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 <algorithm> 29 #include <map> 30 #include <vector> 31 32 #include "talk/media/base/testutils.h" 33 #include "talk/media/base/videoengine_unittest.h" 34 #include "talk/media/webrtc/fakewebrtccall.h" 35 #include "talk/media/webrtc/fakewebrtcvideoengine.h" 36 #include "talk/media/webrtc/simulcast.h" 37 #include "talk/media/webrtc/webrtcvideochannelfactory.h" 38 #include "talk/media/webrtc/webrtcvideoengine2.h" 39 #include "talk/media/webrtc/webrtcvoiceengine.h" 40 #include "webrtc/base/arraysize.h" 41 #include "webrtc/base/gunit.h" 42 #include "webrtc/base/stringutils.h" 43 #include "webrtc/test/field_trial.h" 44 #include "webrtc/video_encoder.h" 45 46 namespace { 47 static const int kDefaultQpMax = 56; 48 static const int kDefaultFramerate = 30; 49 50 static const cricket::VideoCodec kVp8Codec720p(100, "VP8", 1280, 720, 30, 0); 51 static const cricket::VideoCodec kVp8Codec360p(100, "VP8", 640, 360, 30, 0); 52 static const cricket::VideoCodec kVp8Codec270p(100, "VP8", 480, 270, 30, 0); 53 54 static const cricket::VideoCodec kVp8Codec(100, "VP8", 640, 400, 30, 0); 55 static const cricket::VideoCodec kVp9Codec(101, "VP9", 640, 400, 30, 0); 56 static const cricket::VideoCodec kH264Codec(102, "H264", 640, 400, 30, 0); 57 58 static const cricket::VideoCodec kRedCodec(116, "red", 0, 0, 0, 0); 59 static const cricket::VideoCodec kUlpfecCodec(117, "ulpfec", 0, 0, 0, 0); 60 61 static const uint8_t kRedRtxPayloadType = 125; 62 63 static const uint32_t kSsrcs1[] = {1}; 64 static const uint32_t kSsrcs3[] = {1, 2, 3}; 65 static const uint32_t kRtxSsrcs1[] = {4}; 66 static const uint32_t kIncomingUnsignalledSsrc = 0xC0FFEE; 67 static const char kUnsupportedExtensionName[] = 68 "urn:ietf:params:rtp-hdrext:unsupported"; 69 70 void VerifyCodecHasDefaultFeedbackParams(const cricket::VideoCodec& codec) { 71 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam( 72 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty))); 73 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam( 74 cricket::kRtcpFbParamNack, cricket::kRtcpFbNackParamPli))); 75 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam( 76 cricket::kRtcpFbParamRemb, cricket::kParamValueEmpty))); 77 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam( 78 cricket::kRtcpFbParamTransportCc, cricket::kParamValueEmpty))); 79 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam( 80 cricket::kRtcpFbParamCcm, cricket::kRtcpFbCcmParamFir))); 81 } 82 83 static void CreateBlackFrame(webrtc::VideoFrame* video_frame, 84 int width, 85 int height) { 86 video_frame->CreateEmptyFrame( 87 width, height, width, (width + 1) / 2, (width + 1) / 2); 88 memset(video_frame->buffer(webrtc::kYPlane), 16, 89 video_frame->allocated_size(webrtc::kYPlane)); 90 memset(video_frame->buffer(webrtc::kUPlane), 128, 91 video_frame->allocated_size(webrtc::kUPlane)); 92 memset(video_frame->buffer(webrtc::kVPlane), 128, 93 video_frame->allocated_size(webrtc::kVPlane)); 94 } 95 96 void VerifySendStreamHasRtxTypes(const webrtc::VideoSendStream::Config& config, 97 const std::map<int, int>& rtx_types) { 98 std::map<int, int>::const_iterator it; 99 it = rtx_types.find(config.encoder_settings.payload_type); 100 EXPECT_TRUE(it != rtx_types.end() && 101 it->second == config.rtp.rtx.payload_type); 102 103 if (config.rtp.fec.red_rtx_payload_type != -1) { 104 it = rtx_types.find(config.rtp.fec.red_payload_type); 105 EXPECT_TRUE(it != rtx_types.end() && 106 it->second == config.rtp.fec.red_rtx_payload_type); 107 } 108 } 109 } // namespace 110 111 namespace cricket { 112 class WebRtcVideoEngine2Test : public ::testing::Test { 113 public: 114 WebRtcVideoEngine2Test() : WebRtcVideoEngine2Test("") {} 115 explicit WebRtcVideoEngine2Test(const char* field_trials) 116 : WebRtcVideoEngine2Test(nullptr, field_trials) {} 117 WebRtcVideoEngine2Test(WebRtcVoiceEngine* voice_engine, 118 const char* field_trials) 119 : override_field_trials_(field_trials), 120 call_(webrtc::Call::Create(webrtc::Call::Config())), 121 engine_() { 122 std::vector<VideoCodec> engine_codecs = engine_.codecs(); 123 RTC_DCHECK(!engine_codecs.empty()); 124 bool codec_set = false; 125 for (size_t i = 0; i < engine_codecs.size(); ++i) { 126 if (engine_codecs[i].name == "red") { 127 default_red_codec_ = engine_codecs[i]; 128 } else if (engine_codecs[i].name == "ulpfec") { 129 default_ulpfec_codec_ = engine_codecs[i]; 130 } else if (engine_codecs[i].name == "rtx") { 131 int associated_payload_type; 132 if (engine_codecs[i].GetParam(kCodecParamAssociatedPayloadType, 133 &associated_payload_type)) { 134 default_apt_rtx_types_[associated_payload_type] = engine_codecs[i].id; 135 } 136 } else if (!codec_set) { 137 default_codec_ = engine_codecs[i]; 138 codec_set = true; 139 } 140 } 141 142 RTC_DCHECK(codec_set); 143 } 144 145 protected: 146 VideoMediaChannel* SetUpForExternalEncoderFactory( 147 cricket::WebRtcVideoEncoderFactory* encoder_factory, 148 const std::vector<VideoCodec>& codecs); 149 150 VideoMediaChannel* SetUpForExternalDecoderFactory( 151 cricket::WebRtcVideoDecoderFactory* decoder_factory, 152 const std::vector<VideoCodec>& codecs); 153 154 webrtc::test::ScopedFieldTrials override_field_trials_; 155 // Used in WebRtcVideoEngine2VoiceTest, but defined here so it's properly 156 // initialized when the constructor is called. 157 rtc::scoped_ptr<webrtc::Call> call_; 158 WebRtcVoiceEngine voice_engine_; 159 WebRtcVideoEngine2 engine_; 160 VideoCodec default_codec_; 161 VideoCodec default_red_codec_; 162 VideoCodec default_ulpfec_codec_; 163 std::map<int, int> default_apt_rtx_types_; 164 }; 165 166 TEST_F(WebRtcVideoEngine2Test, FindCodec) { 167 const std::vector<cricket::VideoCodec>& c = engine_.codecs(); 168 EXPECT_EQ(cricket::DefaultVideoCodecList().size(), c.size()); 169 170 cricket::VideoCodec vp8(104, "VP8", 320, 200, 30, 0); 171 EXPECT_TRUE(engine_.FindCodec(vp8)); 172 173 cricket::VideoCodec vp8_ci(104, "vp8", 320, 200, 30, 0); 174 EXPECT_TRUE(engine_.FindCodec(vp8)); 175 176 cricket::VideoCodec vp8_diff_fr_diff_pref(104, "VP8", 320, 200, 50, 50); 177 EXPECT_TRUE(engine_.FindCodec(vp8_diff_fr_diff_pref)); 178 179 cricket::VideoCodec vp8_diff_id(95, "VP8", 320, 200, 30, 0); 180 EXPECT_FALSE(engine_.FindCodec(vp8_diff_id)); 181 vp8_diff_id.id = 97; 182 EXPECT_TRUE(engine_.FindCodec(vp8_diff_id)); 183 184 // FindCodec ignores the codec size. 185 // Test that FindCodec can accept uncommon codec size. 186 cricket::VideoCodec vp8_diff_res(104, "VP8", 320, 111, 30, 0); 187 EXPECT_TRUE(engine_.FindCodec(vp8_diff_res)); 188 189 // PeerConnection doesn't negotiate the resolution at this point. 190 // Test that FindCodec can handle the case when width/height is 0. 191 cricket::VideoCodec vp8_zero_res(104, "VP8", 0, 0, 30, 0); 192 EXPECT_TRUE(engine_.FindCodec(vp8_zero_res)); 193 194 cricket::VideoCodec red(101, "RED", 0, 0, 30, 0); 195 EXPECT_TRUE(engine_.FindCodec(red)); 196 197 cricket::VideoCodec red_ci(101, "red", 0, 0, 30, 0); 198 EXPECT_TRUE(engine_.FindCodec(red)); 199 200 cricket::VideoCodec fec(102, "ULPFEC", 0, 0, 30, 0); 201 EXPECT_TRUE(engine_.FindCodec(fec)); 202 203 cricket::VideoCodec fec_ci(102, "ulpfec", 0, 0, 30, 0); 204 EXPECT_TRUE(engine_.FindCodec(fec)); 205 206 cricket::VideoCodec rtx(96, "rtx", 0, 0, 30, 0); 207 EXPECT_TRUE(engine_.FindCodec(rtx)); 208 } 209 210 TEST_F(WebRtcVideoEngine2Test, DefaultRtxCodecHasAssociatedPayloadTypeSet) { 211 std::vector<VideoCodec> engine_codecs = engine_.codecs(); 212 for (size_t i = 0; i < engine_codecs.size(); ++i) { 213 if (engine_codecs[i].name != kRtxCodecName) 214 continue; 215 int associated_payload_type; 216 EXPECT_TRUE(engine_codecs[i].GetParam(kCodecParamAssociatedPayloadType, 217 &associated_payload_type)); 218 EXPECT_EQ(default_codec_.id, associated_payload_type); 219 return; 220 } 221 FAIL() << "No RTX codec found among default codecs."; 222 } 223 224 TEST_F(WebRtcVideoEngine2Test, SupportsTimestampOffsetHeaderExtension) { 225 RtpCapabilities capabilities = engine_.GetCapabilities(); 226 ASSERT_FALSE(capabilities.header_extensions.empty()); 227 for (const RtpHeaderExtension& extension : capabilities.header_extensions) { 228 if (extension.uri == kRtpTimestampOffsetHeaderExtension) { 229 EXPECT_EQ(kRtpTimestampOffsetHeaderExtensionDefaultId, extension.id); 230 return; 231 } 232 } 233 FAIL() << "Timestamp offset extension not in header-extension list."; 234 } 235 236 TEST_F(WebRtcVideoEngine2Test, SupportsAbsoluteSenderTimeHeaderExtension) { 237 RtpCapabilities capabilities = engine_.GetCapabilities(); 238 ASSERT_FALSE(capabilities.header_extensions.empty()); 239 for (const RtpHeaderExtension& extension : capabilities.header_extensions) { 240 if (extension.uri == kRtpAbsoluteSenderTimeHeaderExtension) { 241 EXPECT_EQ(kRtpAbsoluteSenderTimeHeaderExtensionDefaultId, extension.id); 242 return; 243 } 244 } 245 FAIL() << "Absolute Sender Time extension not in header-extension list."; 246 } 247 248 class WebRtcVideoEngine2WithSendSideBweTest : public WebRtcVideoEngine2Test { 249 public: 250 WebRtcVideoEngine2WithSendSideBweTest() 251 : WebRtcVideoEngine2Test("WebRTC-SendSideBwe/Enabled/") {} 252 }; 253 254 TEST_F(WebRtcVideoEngine2WithSendSideBweTest, 255 SupportsTransportSequenceNumberHeaderExtension) { 256 RtpCapabilities capabilities = engine_.GetCapabilities(); 257 ASSERT_FALSE(capabilities.header_extensions.empty()); 258 for (const RtpHeaderExtension& extension : capabilities.header_extensions) { 259 if (extension.uri == kRtpTransportSequenceNumberHeaderExtension) { 260 EXPECT_EQ(kRtpTransportSequenceNumberHeaderExtensionDefaultId, 261 extension.id); 262 return; 263 } 264 } 265 FAIL() << "Transport sequence number extension not in header-extension list."; 266 } 267 268 TEST_F(WebRtcVideoEngine2Test, SupportsVideoRotationHeaderExtension) { 269 RtpCapabilities capabilities = engine_.GetCapabilities(); 270 ASSERT_FALSE(capabilities.header_extensions.empty()); 271 for (const RtpHeaderExtension& extension : capabilities.header_extensions) { 272 if (extension.uri == kRtpVideoRotationHeaderExtension) { 273 EXPECT_EQ(kRtpVideoRotationHeaderExtensionDefaultId, extension.id); 274 return; 275 } 276 } 277 FAIL() << "Video Rotation extension not in header-extension list."; 278 } 279 280 TEST_F(WebRtcVideoEngine2Test, CVOSetHeaderExtensionBeforeCapturer) { 281 // Allocate the capturer first to prevent early destruction before channel's 282 // dtor is called. 283 cricket::FakeVideoCapturer capturer; 284 285 cricket::FakeWebRtcVideoEncoderFactory encoder_factory; 286 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8"); 287 cricket::VideoSendParameters parameters; 288 parameters.codecs.push_back(kVp8Codec); 289 290 rtc::scoped_ptr<VideoMediaChannel> channel( 291 SetUpForExternalEncoderFactory(&encoder_factory, parameters.codecs)); 292 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc))); 293 294 // Add CVO extension. 295 const int id = 1; 296 parameters.extensions.push_back( 297 cricket::RtpHeaderExtension(kRtpVideoRotationHeaderExtension, id)); 298 EXPECT_TRUE(channel->SetSendParameters(parameters)); 299 300 // Set capturer. 301 EXPECT_TRUE(channel->SetCapturer(kSsrc, &capturer)); 302 303 // Verify capturer has turned off applying rotation. 304 EXPECT_FALSE(capturer.GetApplyRotation()); 305 306 // Verify removing header extension turns on applying rotation. 307 parameters.extensions.clear(); 308 EXPECT_TRUE(channel->SetSendParameters(parameters)); 309 EXPECT_TRUE(capturer.GetApplyRotation()); 310 } 311 312 TEST_F(WebRtcVideoEngine2Test, CVOSetHeaderExtensionAfterCapturer) { 313 cricket::FakeVideoCapturer capturer; 314 315 cricket::FakeWebRtcVideoEncoderFactory encoder_factory; 316 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8"); 317 cricket::VideoSendParameters parameters; 318 parameters.codecs.push_back(kVp8Codec); 319 320 rtc::scoped_ptr<VideoMediaChannel> channel( 321 SetUpForExternalEncoderFactory(&encoder_factory, parameters.codecs)); 322 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc))); 323 324 // Set capturer. 325 EXPECT_TRUE(channel->SetCapturer(kSsrc, &capturer)); 326 327 // Add CVO extension. 328 const int id = 1; 329 parameters.extensions.push_back( 330 cricket::RtpHeaderExtension(kRtpVideoRotationHeaderExtension, id)); 331 EXPECT_TRUE(channel->SetSendParameters(parameters)); 332 333 // Verify capturer has turned off applying rotation. 334 EXPECT_FALSE(capturer.GetApplyRotation()); 335 336 // Verify removing header extension turns on applying rotation. 337 parameters.extensions.clear(); 338 EXPECT_TRUE(channel->SetSendParameters(parameters)); 339 EXPECT_TRUE(capturer.GetApplyRotation()); 340 } 341 342 TEST_F(WebRtcVideoEngine2Test, SetSendFailsBeforeSettingCodecs) { 343 engine_.Init(); 344 rtc::scoped_ptr<VideoMediaChannel> channel( 345 engine_.CreateChannel(call_.get(), cricket::VideoOptions())); 346 347 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(123))); 348 349 EXPECT_FALSE(channel->SetSend(true)) 350 << "Channel should not start without codecs."; 351 EXPECT_TRUE(channel->SetSend(false)) 352 << "Channel should be stoppable even without set codecs."; 353 } 354 355 TEST_F(WebRtcVideoEngine2Test, GetStatsWithoutSendCodecsSetDoesNotCrash) { 356 engine_.Init(); 357 rtc::scoped_ptr<VideoMediaChannel> channel( 358 engine_.CreateChannel(call_.get(), cricket::VideoOptions())); 359 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(123))); 360 VideoMediaInfo info; 361 channel->GetStats(&info); 362 } 363 364 TEST_F(WebRtcVideoEngine2Test, UseExternalFactoryForVp8WhenSupported) { 365 cricket::FakeWebRtcVideoEncoderFactory encoder_factory; 366 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8"); 367 cricket::VideoSendParameters parameters; 368 parameters.codecs.push_back(kVp8Codec); 369 370 rtc::scoped_ptr<VideoMediaChannel> channel( 371 SetUpForExternalEncoderFactory(&encoder_factory, parameters.codecs)); 372 373 EXPECT_TRUE( 374 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc))); 375 ASSERT_EQ(1u, encoder_factory.encoders().size()); 376 EXPECT_TRUE(channel->SetSend(true)); 377 378 cricket::FakeVideoCapturer capturer; 379 EXPECT_TRUE(channel->SetCapturer(kSsrc, &capturer)); 380 EXPECT_EQ(cricket::CS_RUNNING, 381 capturer.Start(capturer.GetSupportedFormats()->front())); 382 EXPECT_TRUE(capturer.CaptureFrame()); 383 EXPECT_TRUE_WAIT(encoder_factory.encoders()[0]->GetNumEncodedFrames() > 0, 384 kTimeout); 385 386 // Sending one frame will have reallocated the encoder since input size 387 // changes from a small default to the actual frame width/height. 388 int num_created_encoders = encoder_factory.GetNumCreatedEncoders(); 389 EXPECT_EQ(num_created_encoders, 2); 390 391 // Setting codecs of the same type should not reallocate any encoders 392 // (expecting a no-op). 393 EXPECT_TRUE(channel->SetSendParameters(parameters)); 394 EXPECT_EQ(num_created_encoders, encoder_factory.GetNumCreatedEncoders()); 395 396 // Remove stream previously added to free the external encoder instance. 397 EXPECT_TRUE(channel->RemoveSendStream(kSsrc)); 398 EXPECT_EQ(0u, encoder_factory.encoders().size()); 399 } 400 401 TEST_F(WebRtcVideoEngine2Test, CanConstructDecoderForVp9EncoderFactory) { 402 cricket::FakeWebRtcVideoEncoderFactory encoder_factory; 403 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP9, "VP9"); 404 std::vector<cricket::VideoCodec> codecs; 405 codecs.push_back(kVp9Codec); 406 407 rtc::scoped_ptr<VideoMediaChannel> channel( 408 SetUpForExternalEncoderFactory(&encoder_factory, codecs)); 409 410 EXPECT_TRUE( 411 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc))); 412 } 413 414 TEST_F(WebRtcVideoEngine2Test, PropagatesInputFrameTimestamp) { 415 cricket::FakeWebRtcVideoEncoderFactory encoder_factory; 416 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8"); 417 std::vector<cricket::VideoCodec> codecs; 418 codecs.push_back(kVp8Codec); 419 420 FakeCall* fake_call = new FakeCall(webrtc::Call::Config()); 421 call_.reset(fake_call); 422 rtc::scoped_ptr<VideoMediaChannel> channel( 423 SetUpForExternalEncoderFactory(&encoder_factory, codecs)); 424 425 EXPECT_TRUE( 426 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc))); 427 428 FakeVideoCapturer capturer; 429 EXPECT_TRUE(channel->SetCapturer(kSsrc, &capturer)); 430 capturer.Start(cricket::VideoFormat(1280, 720, 431 cricket::VideoFormat::FpsToInterval(60), 432 cricket::FOURCC_I420)); 433 channel->SetSend(true); 434 435 FakeVideoSendStream* stream = fake_call->GetVideoSendStreams()[0]; 436 437 EXPECT_TRUE(capturer.CaptureFrame()); 438 int64_t last_timestamp = stream->GetLastTimestamp(); 439 for (int i = 0; i < 10; i++) { 440 EXPECT_TRUE(capturer.CaptureFrame()); 441 int64_t timestamp = stream->GetLastTimestamp(); 442 int64_t interval = timestamp - last_timestamp; 443 444 // Precision changes from nanosecond to millisecond. 445 // Allow error to be no more than 1. 446 EXPECT_NEAR(cricket::VideoFormat::FpsToInterval(60) / 1E6, interval, 1); 447 448 last_timestamp = timestamp; 449 } 450 451 capturer.Start(cricket::VideoFormat(1280, 720, 452 cricket::VideoFormat::FpsToInterval(30), 453 cricket::FOURCC_I420)); 454 455 EXPECT_TRUE(capturer.CaptureFrame()); 456 last_timestamp = stream->GetLastTimestamp(); 457 for (int i = 0; i < 10; i++) { 458 EXPECT_TRUE(capturer.CaptureFrame()); 459 int64_t timestamp = stream->GetLastTimestamp(); 460 int64_t interval = timestamp - last_timestamp; 461 462 // Precision changes from nanosecond to millisecond. 463 // Allow error to be no more than 1. 464 EXPECT_NEAR(cricket::VideoFormat::FpsToInterval(30) / 1E6, interval, 1); 465 466 last_timestamp = timestamp; 467 } 468 469 // Remove stream previously added to free the external encoder instance. 470 EXPECT_TRUE(channel->RemoveSendStream(kSsrc)); 471 } 472 473 TEST_F(WebRtcVideoEngine2Test, 474 ProducesIncreasingTimestampsWithResetInputSources) { 475 cricket::FakeWebRtcVideoEncoderFactory encoder_factory; 476 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8"); 477 std::vector<cricket::VideoCodec> codecs; 478 codecs.push_back(kVp8Codec); 479 480 FakeCall* fake_call = new FakeCall(webrtc::Call::Config()); 481 call_.reset(fake_call); 482 rtc::scoped_ptr<VideoMediaChannel> channel( 483 SetUpForExternalEncoderFactory(&encoder_factory, codecs)); 484 485 EXPECT_TRUE( 486 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc))); 487 channel->SetSend(true); 488 FakeVideoSendStream* stream = fake_call->GetVideoSendStreams()[0]; 489 490 FakeVideoCapturer capturer1; 491 EXPECT_TRUE(channel->SetCapturer(kSsrc, &capturer1)); 492 493 cricket::CapturedFrame frame; 494 frame.width = 1280; 495 frame.height = 720; 496 frame.fourcc = cricket::FOURCC_I420; 497 frame.data_size = static_cast<uint32_t>( 498 cricket::VideoFrame::SizeOf(frame.width, frame.height)); 499 rtc::scoped_ptr<char[]> data(new char[frame.data_size]); 500 frame.data = data.get(); 501 memset(frame.data, 1, frame.data_size); 502 const int kInitialTimestamp = 123456; 503 frame.time_stamp = kInitialTimestamp; 504 505 // Deliver initial frame. 506 capturer1.SignalCapturedFrame(&frame); 507 // Deliver next frame 1 second later. 508 frame.time_stamp += rtc::kNumNanosecsPerSec; 509 rtc::Thread::Current()->SleepMs(1000); 510 capturer1.SignalCapturedFrame(&frame); 511 512 int64_t capturer1_last_timestamp = stream->GetLastTimestamp(); 513 // Reset input source, should still be continuous even though input-frame 514 // timestamp is less than before. 515 FakeVideoCapturer capturer2; 516 EXPECT_TRUE(channel->SetCapturer(kSsrc, &capturer2)); 517 518 rtc::Thread::Current()->SleepMs(1); 519 // Deliver with a timestamp (10 seconds) before the previous initial one, 520 // these should not be related at all anymore and it should still work fine. 521 frame.time_stamp = kInitialTimestamp - 10000; 522 capturer2.SignalCapturedFrame(&frame); 523 524 // New timestamp should be at least 1ms in the future and not old. 525 EXPECT_GT(stream->GetLastTimestamp(), capturer1_last_timestamp); 526 527 EXPECT_TRUE(channel->RemoveSendStream(kSsrc)); 528 } 529 530 VideoMediaChannel* WebRtcVideoEngine2Test::SetUpForExternalEncoderFactory( 531 cricket::WebRtcVideoEncoderFactory* encoder_factory, 532 const std::vector<VideoCodec>& codecs) { 533 engine_.SetExternalEncoderFactory(encoder_factory); 534 engine_.Init(); 535 536 VideoMediaChannel* channel = 537 engine_.CreateChannel(call_.get(), cricket::VideoOptions()); 538 cricket::VideoSendParameters parameters; 539 parameters.codecs = codecs; 540 EXPECT_TRUE(channel->SetSendParameters(parameters)); 541 542 return channel; 543 } 544 545 VideoMediaChannel* WebRtcVideoEngine2Test::SetUpForExternalDecoderFactory( 546 cricket::WebRtcVideoDecoderFactory* decoder_factory, 547 const std::vector<VideoCodec>& codecs) { 548 engine_.SetExternalDecoderFactory(decoder_factory); 549 engine_.Init(); 550 551 VideoMediaChannel* channel = 552 engine_.CreateChannel(call_.get(), cricket::VideoOptions()); 553 cricket::VideoRecvParameters parameters; 554 parameters.codecs = codecs; 555 EXPECT_TRUE(channel->SetRecvParameters(parameters)); 556 557 return channel; 558 } 559 560 TEST_F(WebRtcVideoEngine2Test, UsesSimulcastAdapterForVp8Factories) { 561 cricket::FakeWebRtcVideoEncoderFactory encoder_factory; 562 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8"); 563 std::vector<cricket::VideoCodec> codecs; 564 codecs.push_back(kVp8Codec); 565 566 rtc::scoped_ptr<VideoMediaChannel> channel( 567 SetUpForExternalEncoderFactory(&encoder_factory, codecs)); 568 569 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3); 570 571 EXPECT_TRUE( 572 channel->AddSendStream(CreateSimStreamParams("cname", ssrcs))); 573 EXPECT_TRUE(channel->SetSend(true)); 574 575 cricket::FakeVideoCapturer capturer; 576 EXPECT_TRUE(channel->SetCapturer(ssrcs.front(), &capturer)); 577 EXPECT_EQ(cricket::CS_RUNNING, 578 capturer.Start(capturer.GetSupportedFormats()->front())); 579 EXPECT_TRUE(capturer.CaptureFrame()); 580 581 EXPECT_GT(encoder_factory.encoders().size(), 1u); 582 583 // Verify that encoders are configured for simulcast through adapter 584 // (increasing resolution and only configured to send one stream each). 585 int prev_width = -1; 586 for (size_t i = 0; i < encoder_factory.encoders().size(); ++i) { 587 webrtc::VideoCodec codec_settings = 588 encoder_factory.encoders()[i]->GetCodecSettings(); 589 EXPECT_EQ(0, codec_settings.numberOfSimulcastStreams); 590 EXPECT_GT(codec_settings.width, prev_width); 591 prev_width = codec_settings.width; 592 } 593 594 EXPECT_TRUE(channel->SetCapturer(ssrcs.front(), NULL)); 595 596 channel.reset(); 597 ASSERT_EQ(0u, encoder_factory.encoders().size()); 598 } 599 600 TEST_F(WebRtcVideoEngine2Test, ChannelWithExternalH264CanChangeToInternalVp8) { 601 cricket::FakeWebRtcVideoEncoderFactory encoder_factory; 602 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264"); 603 std::vector<cricket::VideoCodec> codecs; 604 codecs.push_back(kH264Codec); 605 606 rtc::scoped_ptr<VideoMediaChannel> channel( 607 SetUpForExternalEncoderFactory(&encoder_factory, codecs)); 608 609 EXPECT_TRUE( 610 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc))); 611 ASSERT_EQ(1u, encoder_factory.encoders().size()); 612 613 cricket::VideoSendParameters parameters; 614 parameters.codecs.push_back(kVp8Codec); 615 EXPECT_TRUE(channel->SetSendParameters(parameters)); 616 ASSERT_EQ(0u, encoder_factory.encoders().size()); 617 } 618 619 TEST_F(WebRtcVideoEngine2Test, 620 DontUseExternalEncoderFactoryForUnsupportedCodecs) { 621 cricket::FakeWebRtcVideoEncoderFactory encoder_factory; 622 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264"); 623 std::vector<cricket::VideoCodec> codecs; 624 codecs.push_back(kVp8Codec); 625 626 rtc::scoped_ptr<VideoMediaChannel> channel( 627 SetUpForExternalEncoderFactory(&encoder_factory, codecs)); 628 629 EXPECT_TRUE( 630 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc))); 631 // Make sure DestroyVideoEncoder was called on the factory. 632 ASSERT_EQ(0u, encoder_factory.encoders().size()); 633 } 634 635 TEST_F(WebRtcVideoEngine2Test, 636 UsesSimulcastAdapterForVp8WithCombinedVP8AndH264Factory) { 637 cricket::FakeWebRtcVideoEncoderFactory encoder_factory; 638 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8"); 639 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264"); 640 641 std::vector<cricket::VideoCodec> codecs; 642 codecs.push_back(kVp8Codec); 643 644 rtc::scoped_ptr<VideoMediaChannel> channel( 645 SetUpForExternalEncoderFactory(&encoder_factory, codecs)); 646 647 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3); 648 649 EXPECT_TRUE( 650 channel->AddSendStream(CreateSimStreamParams("cname", ssrcs))); 651 EXPECT_TRUE(channel->SetSend(true)); 652 653 // Send a fake frame, or else the media engine will configure the simulcast 654 // encoder adapter at a low-enough size that it'll only create a single 655 // encoder layer. 656 cricket::FakeVideoCapturer capturer; 657 EXPECT_TRUE(channel->SetCapturer(ssrcs.front(), &capturer)); 658 EXPECT_EQ(cricket::CS_RUNNING, 659 capturer.Start(capturer.GetSupportedFormats()->front())); 660 EXPECT_TRUE(capturer.CaptureFrame()); 661 662 ASSERT_GT(encoder_factory.encoders().size(), 1u); 663 EXPECT_EQ(webrtc::kVideoCodecVP8, 664 encoder_factory.encoders()[0]->GetCodecSettings().codecType); 665 666 channel.reset(); 667 // Make sure DestroyVideoEncoder was called on the factory. 668 EXPECT_EQ(0u, encoder_factory.encoders().size()); 669 } 670 671 TEST_F(WebRtcVideoEngine2Test, 672 DestroysNonSimulcastEncoderFromCombinedVP8AndH264Factory) { 673 cricket::FakeWebRtcVideoEncoderFactory encoder_factory; 674 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8"); 675 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264"); 676 677 std::vector<cricket::VideoCodec> codecs; 678 codecs.push_back(kH264Codec); 679 680 rtc::scoped_ptr<VideoMediaChannel> channel( 681 SetUpForExternalEncoderFactory(&encoder_factory, codecs)); 682 683 EXPECT_TRUE( 684 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc))); 685 ASSERT_EQ(1u, encoder_factory.encoders().size()); 686 EXPECT_EQ(webrtc::kVideoCodecH264, 687 encoder_factory.encoders()[0]->GetCodecSettings().codecType); 688 689 channel.reset(); 690 // Make sure DestroyVideoEncoder was called on the factory. 691 ASSERT_EQ(0u, encoder_factory.encoders().size()); 692 } 693 694 TEST_F(WebRtcVideoEngine2Test, SimulcastDisabledForH264) { 695 cricket::FakeWebRtcVideoEncoderFactory encoder_factory; 696 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264"); 697 std::vector<cricket::VideoCodec> codecs; 698 codecs.push_back(kH264Codec); 699 700 rtc::scoped_ptr<VideoMediaChannel> channel( 701 SetUpForExternalEncoderFactory(&encoder_factory, codecs)); 702 703 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3); 704 EXPECT_TRUE( 705 channel->AddSendStream(cricket::CreateSimStreamParams("cname", ssrcs))); 706 // Set the stream to 720p. This should trigger a "real" encoder 707 // initialization. 708 cricket::VideoFormat format( 709 1280, 720, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420); 710 EXPECT_TRUE(channel->SetSendStreamFormat(ssrcs[0], format)); 711 ASSERT_EQ(1u, encoder_factory.encoders().size()); 712 FakeWebRtcVideoEncoder* encoder = encoder_factory.encoders()[0]; 713 EXPECT_EQ(webrtc::kVideoCodecH264, encoder->GetCodecSettings().codecType); 714 EXPECT_EQ(1u, encoder->GetCodecSettings().numberOfSimulcastStreams); 715 } 716 717 // Test external codec with be added to the end of the supported codec list. 718 TEST_F(WebRtcVideoEngine2Test, ReportSupportedExternalCodecs) { 719 cricket::FakeWebRtcVideoEncoderFactory encoder_factory; 720 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264"); 721 engine_.SetExternalEncoderFactory(&encoder_factory); 722 engine_.Init(); 723 724 std::vector<cricket::VideoCodec> codecs(engine_.codecs()); 725 ASSERT_GE(codecs.size(), 2u); 726 cricket::VideoCodec internal_codec = codecs.front(); 727 cricket::VideoCodec external_codec = codecs.back(); 728 729 // The external codec will appear at last. 730 EXPECT_EQ("VP8", internal_codec.name); 731 EXPECT_EQ("H264", external_codec.name); 732 } 733 734 TEST_F(WebRtcVideoEngine2Test, RegisterExternalDecodersIfSupported) { 735 cricket::FakeWebRtcVideoDecoderFactory decoder_factory; 736 decoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8); 737 cricket::VideoRecvParameters parameters; 738 parameters.codecs.push_back(kVp8Codec); 739 740 rtc::scoped_ptr<VideoMediaChannel> channel( 741 SetUpForExternalDecoderFactory(&decoder_factory, parameters.codecs)); 742 743 EXPECT_TRUE( 744 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc))); 745 ASSERT_EQ(1u, decoder_factory.decoders().size()); 746 747 // Setting codecs of the same type should not reallocate the decoder. 748 EXPECT_TRUE(channel->SetRecvParameters(parameters)); 749 EXPECT_EQ(1, decoder_factory.GetNumCreatedDecoders()); 750 751 // Remove stream previously added to free the external decoder instance. 752 EXPECT_TRUE(channel->RemoveRecvStream(kSsrc)); 753 EXPECT_EQ(0u, decoder_factory.decoders().size()); 754 } 755 756 // Verifies that we can set up decoders that are not internally supported. 757 TEST_F(WebRtcVideoEngine2Test, RegisterExternalH264DecoderIfSupported) { 758 // TODO(pbos): Do not assume that encoder/decoder support is symmetric. We 759 // can't even query the WebRtcVideoDecoderFactory for supported codecs. 760 // For now we add a FakeWebRtcVideoEncoderFactory to add H264 to supported 761 // codecs. 762 cricket::FakeWebRtcVideoEncoderFactory encoder_factory; 763 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264"); 764 engine_.SetExternalEncoderFactory(&encoder_factory); 765 cricket::FakeWebRtcVideoDecoderFactory decoder_factory; 766 decoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264); 767 std::vector<cricket::VideoCodec> codecs; 768 codecs.push_back(kH264Codec); 769 770 rtc::scoped_ptr<VideoMediaChannel> channel( 771 SetUpForExternalDecoderFactory(&decoder_factory, codecs)); 772 773 EXPECT_TRUE( 774 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc))); 775 ASSERT_EQ(1u, decoder_factory.decoders().size()); 776 } 777 778 class WebRtcVideoChannel2BaseTest 779 : public VideoMediaChannelTest<WebRtcVideoEngine2, WebRtcVideoChannel2> { 780 protected: 781 typedef VideoMediaChannelTest<WebRtcVideoEngine2, WebRtcVideoChannel2> Base; 782 783 cricket::VideoCodec DefaultCodec() override { return kVp8Codec; } 784 }; 785 786 #define WEBRTC_BASE_TEST(test) \ 787 TEST_F(WebRtcVideoChannel2BaseTest, test) { Base::test(); } 788 789 #define WEBRTC_DISABLED_BASE_TEST(test) \ 790 TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_##test) { Base::test(); } 791 792 WEBRTC_BASE_TEST(SetSend); 793 WEBRTC_BASE_TEST(SetSendWithoutCodecs); 794 WEBRTC_BASE_TEST(SetSendSetsTransportBufferSizes); 795 796 WEBRTC_BASE_TEST(GetStats); 797 WEBRTC_BASE_TEST(GetStatsMultipleRecvStreams); 798 WEBRTC_BASE_TEST(GetStatsMultipleSendStreams); 799 800 WEBRTC_BASE_TEST(SetSendBandwidth); 801 802 WEBRTC_BASE_TEST(SetSendSsrc); 803 WEBRTC_BASE_TEST(SetSendSsrcAfterSetCodecs); 804 805 WEBRTC_BASE_TEST(SetRenderer); 806 WEBRTC_BASE_TEST(AddRemoveRecvStreams); 807 808 WEBRTC_DISABLED_BASE_TEST(AddRemoveRecvStreamAndRender); 809 810 WEBRTC_BASE_TEST(AddRemoveRecvStreamsNoConference); 811 812 WEBRTC_BASE_TEST(AddRemoveSendStreams); 813 814 WEBRTC_BASE_TEST(SimulateConference); 815 816 WEBRTC_BASE_TEST(AddRemoveCapturer); 817 818 WEBRTC_BASE_TEST(RemoveCapturerWithoutAdd); 819 820 WEBRTC_BASE_TEST(AddRemoveCapturerMultipleSources); 821 822 // TODO(pbos): Figure out why this fails so often. 823 WEBRTC_DISABLED_BASE_TEST(HighAspectHighHeightCapturer); 824 825 WEBRTC_BASE_TEST(RejectEmptyStreamParams); 826 827 WEBRTC_BASE_TEST(AdaptResolution16x10); 828 829 WEBRTC_BASE_TEST(AdaptResolution4x3); 830 831 // TODO(juberti): Restore this test once we support sending 0 fps. 832 WEBRTC_DISABLED_BASE_TEST(AdaptDropAllFrames); 833 // TODO(juberti): Understand why we get decode errors on this test. 834 WEBRTC_DISABLED_BASE_TEST(AdaptFramerate); 835 836 WEBRTC_BASE_TEST(SendsLowerResolutionOnSmallerFrames); 837 838 WEBRTC_BASE_TEST(MuteStream); 839 840 WEBRTC_BASE_TEST(MultipleSendStreams); 841 842 WEBRTC_BASE_TEST(SetSendStreamFormat0x0); 843 844 // TODO(zhurunz): Fix the flakey test. 845 WEBRTC_DISABLED_BASE_TEST(SetSendStreamFormat); 846 847 TEST_F(WebRtcVideoChannel2BaseTest, SendAndReceiveVp8Vga) { 848 SendAndReceive(cricket::VideoCodec(100, "VP8", 640, 400, 30, 0)); 849 } 850 851 TEST_F(WebRtcVideoChannel2BaseTest, SendAndReceiveVp8Qvga) { 852 SendAndReceive(cricket::VideoCodec(100, "VP8", 320, 200, 30, 0)); 853 } 854 855 TEST_F(WebRtcVideoChannel2BaseTest, SendAndReceiveVp8SvcQqvga) { 856 SendAndReceive(cricket::VideoCodec(100, "VP8", 160, 100, 30, 0)); 857 } 858 859 TEST_F(WebRtcVideoChannel2BaseTest, TwoStreamsSendAndReceive) { 860 Base::TwoStreamsSendAndReceive(kVp8Codec); 861 } 862 863 TEST_F(WebRtcVideoChannel2BaseTest, TwoStreamsReUseFirstStream) { 864 Base::TwoStreamsReUseFirstStream(kVp8Codec); 865 } 866 867 //Disabled for TSan: https://bugs.chromium.org/p/webrtc/issues/detail?id=4963 868 #if !defined(THREAD_SANITIZER) 869 WEBRTC_BASE_TEST(SendManyResizeOnce); 870 #endif // THREAD_SANITIZER 871 872 // TODO(pbos): Enable and figure out why this fails (or should work). 873 TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_SendVp8HdAndReceiveAdaptedVp8Vga) { 874 EXPECT_TRUE(channel_->SetCapturer(kSsrc, NULL)); 875 EXPECT_TRUE(channel_->SetRenderer(kDefaultReceiveSsrc, &renderer_)); 876 channel_->UpdateAspectRatio(1280, 720); 877 video_capturer_.reset(new cricket::FakeVideoCapturer); 878 const std::vector<cricket::VideoFormat>* formats = 879 video_capturer_->GetSupportedFormats(); 880 cricket::VideoFormat capture_format_hd = (*formats)[0]; 881 EXPECT_EQ(cricket::CS_RUNNING, video_capturer_->Start(capture_format_hd)); 882 EXPECT_TRUE(channel_->SetCapturer(kSsrc, video_capturer_.get())); 883 884 // Capture format HD -> adapt (OnOutputFormatRequest VGA) -> VGA. 885 cricket::VideoCodec codec = kVp8Codec720p; 886 EXPECT_TRUE(SetOneCodec(codec)); 887 codec.width /= 2; 888 codec.height /= 2; 889 EXPECT_TRUE(SetSend(true)); 890 EXPECT_EQ(0, renderer_.num_rendered_frames()); 891 EXPECT_TRUE(SendFrame()); 892 EXPECT_FRAME_WAIT(1, codec.width, codec.height, kTimeout); 893 } 894 895 class WebRtcVideoChannel2Test : public WebRtcVideoEngine2Test { 896 public: 897 WebRtcVideoChannel2Test() : WebRtcVideoChannel2Test("") {} 898 explicit WebRtcVideoChannel2Test(const char* field_trials) 899 : WebRtcVideoEngine2Test(field_trials), last_ssrc_(0) {} 900 void SetUp() override { 901 fake_call_.reset(new FakeCall(webrtc::Call::Config())); 902 engine_.Init(); 903 channel_.reset( 904 engine_.CreateChannel(fake_call_.get(), cricket::VideoOptions())); 905 last_ssrc_ = 123; 906 send_parameters_.codecs = engine_.codecs(); 907 recv_parameters_.codecs = engine_.codecs(); 908 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_)); 909 } 910 911 protected: 912 FakeVideoSendStream* AddSendStream() { 913 return AddSendStream(StreamParams::CreateLegacy(++last_ssrc_)); 914 } 915 916 FakeVideoSendStream* AddSendStream(const StreamParams& sp) { 917 size_t num_streams = fake_call_->GetVideoSendStreams().size(); 918 EXPECT_TRUE(channel_->AddSendStream(sp)); 919 std::vector<FakeVideoSendStream*> streams = 920 fake_call_->GetVideoSendStreams(); 921 EXPECT_EQ(num_streams + 1, streams.size()); 922 return streams[streams.size() - 1]; 923 } 924 925 std::vector<FakeVideoSendStream*> GetFakeSendStreams() { 926 return fake_call_->GetVideoSendStreams(); 927 } 928 929 FakeVideoReceiveStream* AddRecvStream() { 930 return AddRecvStream(StreamParams::CreateLegacy(++last_ssrc_)); 931 } 932 933 FakeVideoReceiveStream* AddRecvStream(const StreamParams& sp) { 934 size_t num_streams = fake_call_->GetVideoReceiveStreams().size(); 935 EXPECT_TRUE(channel_->AddRecvStream(sp)); 936 std::vector<FakeVideoReceiveStream*> streams = 937 fake_call_->GetVideoReceiveStreams(); 938 EXPECT_EQ(num_streams + 1, streams.size()); 939 return streams[streams.size() - 1]; 940 } 941 942 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps, 943 int expected_min_bitrate_bps, 944 const char* start_bitrate_kbps, 945 int expected_start_bitrate_bps, 946 const char* max_bitrate_kbps, 947 int expected_max_bitrate_bps) { 948 auto& codecs = send_parameters_.codecs; 949 codecs.clear(); 950 codecs.push_back(kVp8Codec); 951 codecs[0].params[kCodecParamMinBitrate] = min_bitrate_kbps; 952 codecs[0].params[kCodecParamStartBitrate] = start_bitrate_kbps; 953 codecs[0].params[kCodecParamMaxBitrate] = max_bitrate_kbps; 954 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_)); 955 956 EXPECT_EQ(expected_min_bitrate_bps, 957 fake_call_->GetConfig().bitrate_config.min_bitrate_bps); 958 EXPECT_EQ(expected_start_bitrate_bps, 959 fake_call_->GetConfig().bitrate_config.start_bitrate_bps); 960 EXPECT_EQ(expected_max_bitrate_bps, 961 fake_call_->GetConfig().bitrate_config.max_bitrate_bps); 962 } 963 964 void TestSetSendRtpHeaderExtensions(const std::string& cricket_ext, 965 const std::string& webrtc_ext) { 966 // Enable extension. 967 const int id = 1; 968 cricket::VideoSendParameters parameters = send_parameters_; 969 parameters.extensions.push_back( 970 cricket::RtpHeaderExtension(cricket_ext, id)); 971 EXPECT_TRUE(channel_->SetSendParameters(parameters)); 972 FakeVideoSendStream* send_stream = 973 AddSendStream(cricket::StreamParams::CreateLegacy(123)); 974 975 // Verify the send extension id. 976 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size()); 977 EXPECT_EQ(id, send_stream->GetConfig().rtp.extensions[0].id); 978 EXPECT_EQ(webrtc_ext, send_stream->GetConfig().rtp.extensions[0].name); 979 // Verify call with same set of extensions returns true. 980 EXPECT_TRUE(channel_->SetSendParameters(parameters)); 981 // Verify that SetSendRtpHeaderExtensions doesn't implicitly add them for 982 // receivers. 983 EXPECT_TRUE(AddRecvStream(cricket::StreamParams::CreateLegacy(123)) 984 ->GetConfig() 985 .rtp.extensions.empty()); 986 987 // Verify that existing RTP header extensions can be removed. 988 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_)); 989 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size()); 990 send_stream = fake_call_->GetVideoSendStreams()[0]; 991 EXPECT_TRUE(send_stream->GetConfig().rtp.extensions.empty()); 992 993 // Verify that adding receive RTP header extensions adds them for existing 994 // streams. 995 EXPECT_TRUE(channel_->SetSendParameters(parameters)); 996 send_stream = fake_call_->GetVideoSendStreams()[0]; 997 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size()); 998 EXPECT_EQ(id, send_stream->GetConfig().rtp.extensions[0].id); 999 EXPECT_EQ(webrtc_ext, send_stream->GetConfig().rtp.extensions[0].name); 1000 } 1001 1002 void TestSetRecvRtpHeaderExtensions(const std::string& cricket_ext, 1003 const std::string& webrtc_ext) { 1004 // Enable extension. 1005 const int id = 1; 1006 cricket::VideoRecvParameters parameters = recv_parameters_; 1007 parameters.extensions.push_back( 1008 cricket::RtpHeaderExtension(cricket_ext, id)); 1009 EXPECT_TRUE(channel_->SetRecvParameters(parameters)); 1010 1011 FakeVideoReceiveStream* recv_stream = 1012 AddRecvStream(cricket::StreamParams::CreateLegacy(123)); 1013 1014 // Verify the recv extension id. 1015 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size()); 1016 EXPECT_EQ(id, recv_stream->GetConfig().rtp.extensions[0].id); 1017 EXPECT_EQ(webrtc_ext, recv_stream->GetConfig().rtp.extensions[0].name); 1018 // Verify call with same set of extensions returns true. 1019 EXPECT_TRUE(channel_->SetRecvParameters(parameters)); 1020 1021 // Verify that SetRecvRtpHeaderExtensions doesn't implicitly add them for 1022 // senders. 1023 EXPECT_TRUE(AddSendStream(cricket::StreamParams::CreateLegacy(123)) 1024 ->GetConfig() 1025 .rtp.extensions.empty()); 1026 1027 // Verify that existing RTP header extensions can be removed. 1028 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_)); 1029 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size()); 1030 recv_stream = fake_call_->GetVideoReceiveStreams()[0]; 1031 EXPECT_TRUE(recv_stream->GetConfig().rtp.extensions.empty()); 1032 1033 // Verify that adding receive RTP header extensions adds them for existing 1034 // streams. 1035 EXPECT_TRUE(channel_->SetRecvParameters(parameters)); 1036 recv_stream = fake_call_->GetVideoReceiveStreams()[0]; 1037 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size()); 1038 EXPECT_EQ(id, recv_stream->GetConfig().rtp.extensions[0].id); 1039 EXPECT_EQ(webrtc_ext, recv_stream->GetConfig().rtp.extensions[0].name); 1040 } 1041 1042 void TestExtensionFilter(const std::vector<std::string>& extensions, 1043 const std::string& expected_extension) { 1044 cricket::VideoSendParameters parameters = send_parameters_; 1045 int expected_id = -1; 1046 int id = 1; 1047 for (const std::string& extension : extensions) { 1048 if (extension == expected_extension) 1049 expected_id = id; 1050 parameters.extensions.push_back( 1051 cricket::RtpHeaderExtension(extension, id++)); 1052 } 1053 EXPECT_TRUE(channel_->SetSendParameters(parameters)); 1054 FakeVideoSendStream* send_stream = 1055 AddSendStream(cricket::StreamParams::CreateLegacy(123)); 1056 1057 // Verify that only one of them has been set, and that it is the one with 1058 // highest priority (transport sequence number). 1059 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size()); 1060 EXPECT_EQ(expected_id, send_stream->GetConfig().rtp.extensions[0].id); 1061 EXPECT_EQ(expected_extension, 1062 send_stream->GetConfig().rtp.extensions[0].name); 1063 } 1064 1065 void TestCpuAdaptation(bool enable_overuse, bool is_screenshare); 1066 void TestReceiverLocalSsrcConfiguration(bool receiver_first); 1067 void TestReceiveUnsignalledSsrcPacket(uint8_t payload_type, 1068 bool expect_created_receive_stream); 1069 1070 FakeVideoSendStream* SetDenoisingOption( 1071 const cricket::VideoSendParameters& parameters, bool enabled) { 1072 cricket::VideoSendParameters params = parameters; 1073 params.options.video_noise_reduction = rtc::Optional<bool>(enabled); 1074 channel_->SetSendParameters(params); 1075 return fake_call_->GetVideoSendStreams().back(); 1076 } 1077 1078 FakeVideoSendStream* SetUpSimulcast(bool enabled, bool with_rtx) { 1079 const int kRtxSsrcOffset = 0xDEADBEEF; 1080 last_ssrc_ += 3; 1081 std::vector<uint32_t> ssrcs; 1082 std::vector<uint32_t> rtx_ssrcs; 1083 uint32_t num_streams = enabled ? 3 : 1; 1084 for (uint32_t i = 0; i < num_streams; ++i) { 1085 uint32_t ssrc = last_ssrc_ + i; 1086 ssrcs.push_back(ssrc); 1087 if (with_rtx) { 1088 rtx_ssrcs.push_back(ssrc + kRtxSsrcOffset); 1089 } 1090 } 1091 if (with_rtx) { 1092 return AddSendStream( 1093 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs)); 1094 } 1095 return AddSendStream(CreateSimStreamParams("cname", ssrcs)); 1096 } 1097 1098 rtc::scoped_ptr<FakeCall> fake_call_; 1099 rtc::scoped_ptr<VideoMediaChannel> channel_; 1100 cricket::VideoSendParameters send_parameters_; 1101 cricket::VideoRecvParameters recv_parameters_; 1102 uint32_t last_ssrc_; 1103 }; 1104 1105 TEST_F(WebRtcVideoChannel2Test, SetsSyncGroupFromSyncLabel) { 1106 const uint32_t kVideoSsrc = 123; 1107 const std::string kSyncLabel = "AvSyncLabel"; 1108 1109 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kVideoSsrc); 1110 sp.sync_label = kSyncLabel; 1111 EXPECT_TRUE(channel_->AddRecvStream(sp)); 1112 1113 EXPECT_EQ(1, fake_call_->GetVideoReceiveStreams().size()); 1114 EXPECT_EQ(kSyncLabel, 1115 fake_call_->GetVideoReceiveStreams()[0]->GetConfig().sync_group) 1116 << "SyncGroup should be set based on sync_label"; 1117 } 1118 1119 TEST_F(WebRtcVideoChannel2Test, RecvStreamWithSimAndRtx) { 1120 cricket::VideoSendParameters parameters; 1121 parameters.codecs = engine_.codecs(); 1122 EXPECT_TRUE(channel_->SetSendParameters(parameters)); 1123 EXPECT_TRUE(channel_->SetSend(true)); 1124 parameters.options.conference_mode = rtc::Optional<bool>(true); 1125 EXPECT_TRUE(channel_->SetSendParameters(parameters)); 1126 1127 // Send side. 1128 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1); 1129 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1); 1130 FakeVideoSendStream* send_stream = AddSendStream( 1131 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs)); 1132 1133 ASSERT_EQ(rtx_ssrcs.size(), send_stream->GetConfig().rtp.rtx.ssrcs.size()); 1134 for (size_t i = 0; i < rtx_ssrcs.size(); ++i) 1135 EXPECT_EQ(rtx_ssrcs[i], send_stream->GetConfig().rtp.rtx.ssrcs[i]); 1136 1137 // Receiver side. 1138 FakeVideoReceiveStream* recv_stream = AddRecvStream( 1139 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs)); 1140 ASSERT_GT(recv_stream->GetConfig().rtp.rtx.size(), 0u) 1141 << "No SSRCs for RTX configured by AddRecvStream."; 1142 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.rtx.size()) 1143 << "This test only works with one receive codec. Please update the test."; 1144 EXPECT_EQ(rtx_ssrcs[0], 1145 recv_stream->GetConfig().rtp.rtx.begin()->second.ssrc); 1146 // TODO(pbos): Make sure we set the RTX for correct payloads etc. 1147 } 1148 1149 TEST_F(WebRtcVideoChannel2Test, RecvStreamWithRtx) { 1150 // Setup one channel with an associated RTX stream. 1151 cricket::StreamParams params = 1152 cricket::StreamParams::CreateLegacy(kSsrcs1[0]); 1153 params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]); 1154 FakeVideoReceiveStream* recv_stream = AddRecvStream(params); 1155 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.rtx.size()); 1156 EXPECT_EQ(kRtxSsrcs1[0], 1157 recv_stream->GetConfig().rtp.rtx.begin()->second.ssrc); 1158 } 1159 1160 TEST_F(WebRtcVideoChannel2Test, RecvStreamNoRtx) { 1161 // Setup one channel without an associated RTX stream. 1162 cricket::StreamParams params = 1163 cricket::StreamParams::CreateLegacy(kSsrcs1[0]); 1164 FakeVideoReceiveStream* recv_stream = AddRecvStream(params); 1165 ASSERT_TRUE(recv_stream->GetConfig().rtp.rtx.empty()); 1166 } 1167 1168 TEST_F(WebRtcVideoChannel2Test, NoHeaderExtesionsByDefault) { 1169 FakeVideoSendStream* send_stream = 1170 AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0])); 1171 ASSERT_TRUE(send_stream->GetConfig().rtp.extensions.empty()); 1172 1173 FakeVideoReceiveStream* recv_stream = 1174 AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0])); 1175 ASSERT_TRUE(recv_stream->GetConfig().rtp.extensions.empty()); 1176 } 1177 1178 // Test support for RTP timestamp offset header extension. 1179 TEST_F(WebRtcVideoChannel2Test, SendRtpTimestampOffsetHeaderExtensions) { 1180 TestSetSendRtpHeaderExtensions(kRtpTimestampOffsetHeaderExtension, 1181 webrtc::RtpExtension::kTOffset); 1182 } 1183 TEST_F(WebRtcVideoChannel2Test, RecvRtpTimestampOffsetHeaderExtensions) { 1184 TestSetRecvRtpHeaderExtensions(kRtpTimestampOffsetHeaderExtension, 1185 webrtc::RtpExtension::kTOffset); 1186 } 1187 1188 // Test support for absolute send time header extension. 1189 TEST_F(WebRtcVideoChannel2Test, SendAbsoluteSendTimeHeaderExtensions) { 1190 TestSetSendRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension, 1191 webrtc::RtpExtension::kAbsSendTime); 1192 } 1193 TEST_F(WebRtcVideoChannel2Test, RecvAbsoluteSendTimeHeaderExtensions) { 1194 TestSetRecvRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension, 1195 webrtc::RtpExtension::kAbsSendTime); 1196 } 1197 1198 TEST_F(WebRtcVideoChannel2Test, FiltersExtensionsPicksTransportSeqNum) { 1199 // Enable three redundant extensions. 1200 std::vector<std::string> extensions; 1201 extensions.push_back(kRtpAbsoluteSenderTimeHeaderExtension); 1202 extensions.push_back(kRtpTimestampOffsetHeaderExtension); 1203 extensions.push_back(kRtpTransportSequenceNumberHeaderExtension); 1204 TestExtensionFilter(extensions, kRtpTransportSequenceNumberHeaderExtension); 1205 } 1206 1207 TEST_F(WebRtcVideoChannel2Test, FiltersExtensionsPicksAbsSendTime) { 1208 // Enable two redundant extensions. 1209 std::vector<std::string> extensions; 1210 extensions.push_back(kRtpAbsoluteSenderTimeHeaderExtension); 1211 extensions.push_back(kRtpTimestampOffsetHeaderExtension); 1212 TestExtensionFilter(extensions, kRtpAbsoluteSenderTimeHeaderExtension); 1213 } 1214 1215 class WebRtcVideoChannel2WithSendSideBweTest : public WebRtcVideoChannel2Test { 1216 public: 1217 WebRtcVideoChannel2WithSendSideBweTest() 1218 : WebRtcVideoChannel2Test("WebRTC-SendSideBwe/Enabled/") {} 1219 }; 1220 1221 // Test support for transport sequence number header extension. 1222 TEST_F(WebRtcVideoChannel2WithSendSideBweTest, 1223 SendTransportSequenceNumberHeaderExtensions) { 1224 TestSetSendRtpHeaderExtensions( 1225 kRtpTransportSequenceNumberHeaderExtension, 1226 webrtc::RtpExtension::kTransportSequenceNumber); 1227 } 1228 TEST_F(WebRtcVideoChannel2WithSendSideBweTest, 1229 RecvTransportSequenceNumberHeaderExtensions) { 1230 TestSetRecvRtpHeaderExtensions( 1231 kRtpTransportSequenceNumberHeaderExtension, 1232 webrtc::RtpExtension::kTransportSequenceNumber); 1233 } 1234 1235 // Test support for video rotation header extension. 1236 TEST_F(WebRtcVideoChannel2Test, SendVideoRotationHeaderExtensions) { 1237 TestSetSendRtpHeaderExtensions(kRtpVideoRotationHeaderExtension, 1238 webrtc::RtpExtension::kVideoRotation); 1239 } 1240 TEST_F(WebRtcVideoChannel2Test, RecvVideoRotationHeaderExtensions) { 1241 TestSetRecvRtpHeaderExtensions(kRtpVideoRotationHeaderExtension, 1242 webrtc::RtpExtension::kVideoRotation); 1243 } 1244 1245 TEST_F(WebRtcVideoChannel2Test, IdenticalSendExtensionsDoesntRecreateStream) { 1246 const int kAbsSendTimeId = 1; 1247 const int kVideoRotationId = 2; 1248 send_parameters_.extensions.push_back(cricket::RtpHeaderExtension( 1249 kRtpAbsoluteSenderTimeHeaderExtension, kAbsSendTimeId)); 1250 send_parameters_.extensions.push_back(cricket::RtpHeaderExtension( 1251 kRtpVideoRotationHeaderExtension, kVideoRotationId)); 1252 1253 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_)); 1254 FakeVideoSendStream* send_stream = 1255 AddSendStream(cricket::StreamParams::CreateLegacy(123)); 1256 1257 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams()); 1258 ASSERT_EQ(2u, send_stream->GetConfig().rtp.extensions.size()); 1259 1260 // Setting the same extensions (even if in different order) shouldn't 1261 // reallocate the stream. 1262 std::reverse(send_parameters_.extensions.begin(), 1263 send_parameters_.extensions.end()); 1264 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_)); 1265 1266 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams()); 1267 1268 // Setting different extensions should recreate the stream. 1269 send_parameters_.extensions.resize(1); 1270 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_)); 1271 1272 EXPECT_EQ(2, fake_call_->GetNumCreatedSendStreams()); 1273 } 1274 1275 TEST_F(WebRtcVideoChannel2Test, IdenticalRecvExtensionsDoesntRecreateStream) { 1276 const int kTOffsetId = 1; 1277 const int kAbsSendTimeId = 2; 1278 const int kVideoRotationId = 3; 1279 recv_parameters_.extensions.push_back(cricket::RtpHeaderExtension( 1280 kRtpAbsoluteSenderTimeHeaderExtension, kAbsSendTimeId)); 1281 recv_parameters_.extensions.push_back(cricket::RtpHeaderExtension( 1282 kRtpTimestampOffsetHeaderExtension, kTOffsetId)); 1283 recv_parameters_.extensions.push_back(cricket::RtpHeaderExtension( 1284 kRtpVideoRotationHeaderExtension, kVideoRotationId)); 1285 1286 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_)); 1287 FakeVideoReceiveStream* recv_stream = 1288 AddRecvStream(cricket::StreamParams::CreateLegacy(123)); 1289 1290 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams()); 1291 ASSERT_EQ(3u, recv_stream->GetConfig().rtp.extensions.size()); 1292 1293 // Setting the same extensions (even if in different order) shouldn't 1294 // reallocate the stream. 1295 std::reverse(recv_parameters_.extensions.begin(), 1296 recv_parameters_.extensions.end()); 1297 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_)); 1298 1299 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams()); 1300 1301 // Setting different extensions should recreate the stream. 1302 recv_parameters_.extensions.resize(1); 1303 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_)); 1304 1305 EXPECT_EQ(2, fake_call_->GetNumCreatedReceiveStreams()); 1306 } 1307 1308 TEST_F(WebRtcVideoChannel2Test, 1309 SetSendRtpHeaderExtensionsExcludeUnsupportedExtensions) { 1310 const int kUnsupportedId = 1; 1311 const int kTOffsetId = 2; 1312 1313 send_parameters_.extensions.push_back( 1314 cricket::RtpHeaderExtension(kUnsupportedExtensionName, kUnsupportedId)); 1315 send_parameters_.extensions.push_back( 1316 cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, kTOffsetId)); 1317 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_)); 1318 FakeVideoSendStream* send_stream = 1319 AddSendStream(cricket::StreamParams::CreateLegacy(123)); 1320 1321 // Only timestamp offset extension is set to send stream, 1322 // unsupported rtp extension is ignored. 1323 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size()); 1324 EXPECT_STREQ(webrtc::RtpExtension::kTOffset, 1325 send_stream->GetConfig().rtp.extensions[0].name.c_str()); 1326 } 1327 1328 TEST_F(WebRtcVideoChannel2Test, 1329 SetRecvRtpHeaderExtensionsExcludeUnsupportedExtensions) { 1330 const int kUnsupportedId = 1; 1331 const int kTOffsetId = 2; 1332 1333 recv_parameters_.extensions.push_back( 1334 cricket::RtpHeaderExtension(kUnsupportedExtensionName, kUnsupportedId)); 1335 recv_parameters_.extensions.push_back( 1336 cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, kTOffsetId)); 1337 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_)); 1338 FakeVideoReceiveStream* recv_stream = 1339 AddRecvStream(cricket::StreamParams::CreateLegacy(123)); 1340 1341 // Only timestamp offset extension is set to receive stream, 1342 // unsupported rtp extension is ignored. 1343 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size()); 1344 EXPECT_STREQ(webrtc::RtpExtension::kTOffset, 1345 recv_stream->GetConfig().rtp.extensions[0].name.c_str()); 1346 } 1347 1348 TEST_F(WebRtcVideoChannel2Test, SetSendRtpHeaderExtensionsRejectsIncorrectIds) { 1349 const int kIncorrectIds[] = {-2, -1, 0, 15, 16}; 1350 for (size_t i = 0; i < arraysize(kIncorrectIds); ++i) { 1351 send_parameters_.extensions.push_back(cricket::RtpHeaderExtension( 1352 webrtc::RtpExtension::kTOffset, kIncorrectIds[i])); 1353 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_)) 1354 << "Bad extension id '" << kIncorrectIds[i] << "' accepted."; 1355 } 1356 } 1357 1358 TEST_F(WebRtcVideoChannel2Test, SetRecvRtpHeaderExtensionsRejectsIncorrectIds) { 1359 const int kIncorrectIds[] = {-2, -1, 0, 15, 16}; 1360 for (size_t i = 0; i < arraysize(kIncorrectIds); ++i) { 1361 recv_parameters_.extensions.push_back(cricket::RtpHeaderExtension( 1362 webrtc::RtpExtension::kTOffset, kIncorrectIds[i])); 1363 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_)) 1364 << "Bad extension id '" << kIncorrectIds[i] << "' accepted."; 1365 } 1366 } 1367 1368 TEST_F(WebRtcVideoChannel2Test, SetSendRtpHeaderExtensionsRejectsDuplicateIds) { 1369 const int id = 1; 1370 send_parameters_.extensions.push_back( 1371 cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, id)); 1372 send_parameters_.extensions.push_back( 1373 cricket::RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension, id)); 1374 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_)); 1375 1376 // Duplicate entries are also not supported. 1377 send_parameters_.extensions.clear(); 1378 send_parameters_.extensions.push_back( 1379 cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, id)); 1380 send_parameters_.extensions.push_back(send_parameters_.extensions.back()); 1381 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_)); 1382 } 1383 1384 TEST_F(WebRtcVideoChannel2Test, SetRecvRtpHeaderExtensionsRejectsDuplicateIds) { 1385 const int id = 1; 1386 recv_parameters_.extensions.push_back( 1387 cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, id)); 1388 recv_parameters_.extensions.push_back( 1389 cricket::RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension, id)); 1390 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_)); 1391 1392 // Duplicate entries are also not supported. 1393 recv_parameters_.extensions.clear(); 1394 recv_parameters_.extensions.push_back( 1395 cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, id)); 1396 recv_parameters_.extensions.push_back(recv_parameters_.extensions.back()); 1397 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_)); 1398 } 1399 1400 TEST_F(WebRtcVideoChannel2Test, DISABLED_LeakyBucketTest) { 1401 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1402 } 1403 1404 TEST_F(WebRtcVideoChannel2Test, DISABLED_BufferedModeLatency) { 1405 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1406 } 1407 1408 TEST_F(WebRtcVideoChannel2Test, DISABLED_AdditiveVideoOptions) { 1409 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1410 } 1411 1412 TEST_F(WebRtcVideoChannel2Test, AddRecvStreamOnlyUsesOneReceiveStream) { 1413 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1))); 1414 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size()); 1415 } 1416 1417 TEST_F(WebRtcVideoChannel2Test, RtcpIsCompoundByDefault) { 1418 FakeVideoReceiveStream* stream = AddRecvStream(); 1419 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream->GetConfig().rtp.rtcp_mode); 1420 } 1421 1422 TEST_F(WebRtcVideoChannel2Test, RembIsEnabledByDefault) { 1423 FakeVideoReceiveStream* stream = AddRecvStream(); 1424 EXPECT_TRUE(stream->GetConfig().rtp.remb); 1425 } 1426 1427 TEST_F(WebRtcVideoChannel2Test, TransportCcIsEnabledByDefault) { 1428 FakeVideoReceiveStream* stream = AddRecvStream(); 1429 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc); 1430 } 1431 1432 TEST_F(WebRtcVideoChannel2Test, RembCanBeEnabledAndDisabled) { 1433 FakeVideoReceiveStream* stream = AddRecvStream(); 1434 EXPECT_TRUE(stream->GetConfig().rtp.remb); 1435 1436 // Verify that REMB is turned off when send(!) codecs without REMB are set. 1437 cricket::VideoSendParameters parameters; 1438 parameters.codecs.push_back(kVp8Codec); 1439 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty()); 1440 EXPECT_TRUE(channel_->SetSendParameters(parameters)); 1441 stream = fake_call_->GetVideoReceiveStreams()[0]; 1442 EXPECT_FALSE(stream->GetConfig().rtp.remb); 1443 1444 // Verify that REMB is turned on when setting default codecs since the 1445 // default codecs have REMB enabled. 1446 parameters.codecs = engine_.codecs(); 1447 EXPECT_TRUE(channel_->SetSendParameters(parameters)); 1448 stream = fake_call_->GetVideoReceiveStreams()[0]; 1449 EXPECT_TRUE(stream->GetConfig().rtp.remb); 1450 } 1451 1452 TEST_F(WebRtcVideoChannel2Test, TransportCcCanBeEnabledAndDisabled) { 1453 FakeVideoReceiveStream* stream = AddRecvStream(); 1454 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc); 1455 1456 // Verify that transport cc feedback is turned off when send(!) codecs without 1457 // transport cc feedback are set. 1458 cricket::VideoSendParameters parameters; 1459 parameters.codecs.push_back(kVp8Codec); 1460 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty()); 1461 EXPECT_TRUE(channel_->SetSendParameters(parameters)); 1462 stream = fake_call_->GetVideoReceiveStreams()[0]; 1463 EXPECT_FALSE(stream->GetConfig().rtp.transport_cc); 1464 1465 // Verify that transport cc feedback is turned on when setting default codecs 1466 // since the default codecs have transport cc feedback enabled. 1467 parameters.codecs = engine_.codecs(); 1468 EXPECT_TRUE(channel_->SetSendParameters(parameters)); 1469 stream = fake_call_->GetVideoReceiveStreams()[0]; 1470 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc); 1471 } 1472 1473 TEST_F(WebRtcVideoChannel2Test, NackIsEnabledByDefault) { 1474 VerifyCodecHasDefaultFeedbackParams(default_codec_); 1475 1476 cricket::VideoSendParameters parameters; 1477 parameters.codecs = engine_.codecs(); 1478 EXPECT_TRUE(channel_->SetSendParameters(parameters)); 1479 EXPECT_TRUE(channel_->SetSend(true)); 1480 1481 // Send side. 1482 FakeVideoSendStream* send_stream = 1483 AddSendStream(cricket::StreamParams::CreateLegacy(1)); 1484 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0); 1485 1486 // Receiver side. 1487 FakeVideoReceiveStream* recv_stream = 1488 AddRecvStream(cricket::StreamParams::CreateLegacy(1)); 1489 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0); 1490 1491 // Nack history size should match between sender and receiver. 1492 EXPECT_EQ(send_stream->GetConfig().rtp.nack.rtp_history_ms, 1493 recv_stream->GetConfig().rtp.nack.rtp_history_ms); 1494 } 1495 1496 TEST_F(WebRtcVideoChannel2Test, NackCanBeEnabledAndDisabled) { 1497 FakeVideoSendStream* send_stream = AddSendStream(); 1498 FakeVideoReceiveStream* recv_stream = AddRecvStream(); 1499 1500 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0); 1501 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0); 1502 1503 // Verify that NACK is turned off when send(!) codecs without NACK are set. 1504 cricket::VideoSendParameters parameters; 1505 parameters.codecs.push_back(kVp8Codec); 1506 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty()); 1507 EXPECT_TRUE(channel_->SetSendParameters(parameters)); 1508 recv_stream = fake_call_->GetVideoReceiveStreams()[0]; 1509 EXPECT_EQ(0, recv_stream->GetConfig().rtp.nack.rtp_history_ms); 1510 send_stream = fake_call_->GetVideoSendStreams()[0]; 1511 EXPECT_EQ(0, send_stream->GetConfig().rtp.nack.rtp_history_ms); 1512 1513 // Verify that NACK is turned on when setting default codecs since the 1514 // default codecs have NACK enabled. 1515 parameters.codecs = engine_.codecs(); 1516 EXPECT_TRUE(channel_->SetSendParameters(parameters)); 1517 recv_stream = fake_call_->GetVideoReceiveStreams()[0]; 1518 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0); 1519 send_stream = fake_call_->GetVideoSendStreams()[0]; 1520 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0); 1521 } 1522 1523 TEST_F(WebRtcVideoChannel2Test, DISABLED_VideoProtectionInterop) { 1524 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1525 } 1526 1527 TEST_F(WebRtcVideoChannel2Test, DISABLED_VideoProtectionInteropReversed) { 1528 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1529 } 1530 1531 TEST_F(WebRtcVideoChannel2Test, DISABLED_HybridNackFecConference) { 1532 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1533 } 1534 1535 TEST_F(WebRtcVideoChannel2Test, DISABLED_AddRemoveRecvStreamConference) { 1536 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1537 } 1538 1539 TEST_F(WebRtcVideoChannel2Test, DISABLED_SetBandwidthAuto) { 1540 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1541 } 1542 1543 TEST_F(WebRtcVideoChannel2Test, DISABLED_SetBandwidthAutoCapped) { 1544 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1545 } 1546 1547 TEST_F(WebRtcVideoChannel2Test, DISABLED_SetBandwidthFixed) { 1548 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1549 } 1550 1551 TEST_F(WebRtcVideoChannel2Test, DISABLED_SetBandwidthInConference) { 1552 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1553 } 1554 1555 TEST_F(WebRtcVideoChannel2Test, UsesCorrectSettingsForScreencast) { 1556 static const int kScreenshareMinBitrateKbps = 800; 1557 cricket::VideoCodec codec = kVp8Codec360p; 1558 cricket::VideoSendParameters parameters; 1559 parameters.codecs.push_back(codec); 1560 parameters.options.screencast_min_bitrate = 1561 rtc::Optional<int>(kScreenshareMinBitrateKbps); 1562 EXPECT_TRUE(channel_->SetSendParameters(parameters)); 1563 1564 AddSendStream(); 1565 1566 cricket::FakeVideoCapturer capturer; 1567 capturer.SetScreencast(false); 1568 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer)); 1569 cricket::VideoFormat capture_format_hd = 1570 capturer.GetSupportedFormats()->front(); 1571 EXPECT_EQ(1280, capture_format_hd.width); 1572 EXPECT_EQ(720, capture_format_hd.height); 1573 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format_hd)); 1574 1575 EXPECT_TRUE(channel_->SetSend(true)); 1576 1577 EXPECT_TRUE(capturer.CaptureFrame()); 1578 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size()); 1579 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front(); 1580 1581 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames()); 1582 1583 // Verify non-screencast settings. 1584 webrtc::VideoEncoderConfig encoder_config = send_stream->GetEncoderConfig(); 1585 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo, 1586 encoder_config.content_type); 1587 EXPECT_EQ(codec.width, encoder_config.streams.front().width); 1588 EXPECT_EQ(codec.height, encoder_config.streams.front().height); 1589 EXPECT_EQ(0, encoder_config.min_transmit_bitrate_bps) 1590 << "Non-screenshare shouldn't use min-transmit bitrate."; 1591 1592 capturer.SetScreencast(true); 1593 EXPECT_TRUE(capturer.CaptureFrame()); 1594 1595 EXPECT_EQ(2, send_stream->GetNumberOfSwappedFrames()); 1596 1597 // Verify screencast settings. 1598 encoder_config = send_stream->GetEncoderConfig(); 1599 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kScreen, 1600 encoder_config.content_type); 1601 EXPECT_EQ(kScreenshareMinBitrateKbps * 1000, 1602 encoder_config.min_transmit_bitrate_bps); 1603 1604 EXPECT_EQ(capture_format_hd.width, encoder_config.streams.front().width); 1605 EXPECT_EQ(capture_format_hd.height, encoder_config.streams.front().height); 1606 EXPECT_TRUE(encoder_config.streams[0].temporal_layer_thresholds_bps.empty()); 1607 1608 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, NULL)); 1609 } 1610 1611 TEST_F(WebRtcVideoChannel2Test, 1612 ConferenceModeScreencastConfiguresTemporalLayer) { 1613 static const int kConferenceScreencastTemporalBitrateBps = 1614 ScreenshareLayerConfig::GetDefault().tl0_bitrate_kbps * 1000; 1615 send_parameters_.options.conference_mode = rtc::Optional<bool>(true); 1616 channel_->SetSendParameters(send_parameters_); 1617 1618 AddSendStream(); 1619 1620 cricket::FakeVideoCapturer capturer; 1621 capturer.SetScreencast(true); 1622 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer)); 1623 cricket::VideoFormat capture_format_hd = 1624 capturer.GetSupportedFormats()->front(); 1625 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format_hd)); 1626 1627 EXPECT_TRUE(channel_->SetSend(true)); 1628 1629 EXPECT_TRUE(capturer.CaptureFrame()); 1630 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size()); 1631 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front(); 1632 1633 webrtc::VideoEncoderConfig encoder_config = send_stream->GetEncoderConfig(); 1634 1635 // Verify screencast settings. 1636 encoder_config = send_stream->GetEncoderConfig(); 1637 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kScreen, 1638 encoder_config.content_type); 1639 ASSERT_EQ(1u, encoder_config.streams.size()); 1640 ASSERT_EQ(1u, encoder_config.streams[0].temporal_layer_thresholds_bps.size()); 1641 EXPECT_EQ(kConferenceScreencastTemporalBitrateBps, 1642 encoder_config.streams[0].temporal_layer_thresholds_bps[0]); 1643 1644 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, NULL)); 1645 } 1646 1647 TEST_F(WebRtcVideoChannel2Test, DISABLED_SetSendSsrcAndCname) { 1648 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1649 } 1650 1651 TEST_F(WebRtcVideoChannel2Test, 1652 DISABLED_SetSendSsrcAfterCreatingReceiveChannel) { 1653 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1654 } 1655 1656 TEST_F(WebRtcVideoChannel2Test, SuspendBelowMinBitrateDisabledByDefault) { 1657 FakeVideoSendStream* stream = AddSendStream(); 1658 EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate); 1659 } 1660 1661 TEST_F(WebRtcVideoChannel2Test, SetOptionsWithSuspendBelowMinBitrate) { 1662 send_parameters_.options.suspend_below_min_bitrate = 1663 rtc::Optional<bool>(true); 1664 channel_->SetSendParameters(send_parameters_); 1665 1666 FakeVideoSendStream* stream = AddSendStream(); 1667 EXPECT_TRUE(stream->GetConfig().suspend_below_min_bitrate); 1668 1669 send_parameters_.options.suspend_below_min_bitrate = 1670 rtc::Optional<bool>(false); 1671 channel_->SetSendParameters(send_parameters_); 1672 1673 stream = fake_call_->GetVideoSendStreams()[0]; 1674 EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate); 1675 } 1676 1677 TEST_F(WebRtcVideoChannel2Test, Vp8DenoisingEnabledByDefault) { 1678 FakeVideoSendStream* stream = AddSendStream(); 1679 webrtc::VideoCodecVP8 vp8_settings; 1680 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set."; 1681 EXPECT_TRUE(vp8_settings.denoisingOn); 1682 } 1683 1684 TEST_F(WebRtcVideoChannel2Test, VerifyVp8SpecificSettings) { 1685 cricket::VideoSendParameters parameters; 1686 parameters.codecs.push_back(kVp8Codec720p); 1687 ASSERT_TRUE(channel_->SetSendParameters(parameters)); 1688 1689 // Single-stream settings should apply with RTX as well (verifies that we 1690 // check number of regular SSRCs and not StreamParams::ssrcs which contains 1691 // both RTX and regular SSRCs). 1692 FakeVideoSendStream* stream = SetUpSimulcast(false, true); 1693 1694 cricket::FakeVideoCapturer capturer; 1695 capturer.SetScreencast(false); 1696 EXPECT_EQ(cricket::CS_RUNNING, 1697 capturer.Start(capturer.GetSupportedFormats()->front())); 1698 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer)); 1699 channel_->SetSend(true); 1700 1701 EXPECT_TRUE(capturer.CaptureFrame()); 1702 1703 webrtc::VideoCodecVP8 vp8_settings; 1704 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set."; 1705 EXPECT_TRUE(vp8_settings.denoisingOn) 1706 << "VP8 denoising should be on by default."; 1707 1708 stream = SetDenoisingOption(parameters, false); 1709 1710 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set."; 1711 EXPECT_FALSE(vp8_settings.denoisingOn); 1712 EXPECT_TRUE(vp8_settings.automaticResizeOn); 1713 EXPECT_TRUE(vp8_settings.frameDroppingOn); 1714 1715 stream = SetDenoisingOption(parameters, true); 1716 1717 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set."; 1718 EXPECT_TRUE(vp8_settings.denoisingOn); 1719 EXPECT_TRUE(vp8_settings.automaticResizeOn); 1720 EXPECT_TRUE(vp8_settings.frameDroppingOn); 1721 1722 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, NULL)); 1723 stream = SetUpSimulcast(true, false); 1724 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer)); 1725 channel_->SetSend(true); 1726 EXPECT_TRUE(capturer.CaptureFrame()); 1727 1728 EXPECT_EQ(3, stream->GetVideoStreams().size()); 1729 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set."; 1730 // Autmatic resize off when using simulcast. 1731 EXPECT_FALSE(vp8_settings.automaticResizeOn); 1732 EXPECT_TRUE(vp8_settings.frameDroppingOn); 1733 1734 // In screen-share mode, denoising is forced off and simulcast disabled. 1735 capturer.SetScreencast(true); 1736 EXPECT_TRUE(capturer.CaptureFrame()); 1737 stream = SetDenoisingOption(parameters, false); 1738 1739 EXPECT_EQ(1, stream->GetVideoStreams().size()); 1740 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set."; 1741 EXPECT_FALSE(vp8_settings.denoisingOn); 1742 // Resizing and frame dropping always off for screen sharing. 1743 EXPECT_FALSE(vp8_settings.automaticResizeOn); 1744 EXPECT_FALSE(vp8_settings.frameDroppingOn); 1745 1746 stream = SetDenoisingOption(parameters, true); 1747 1748 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set."; 1749 EXPECT_FALSE(vp8_settings.denoisingOn); 1750 EXPECT_FALSE(vp8_settings.automaticResizeOn); 1751 EXPECT_FALSE(vp8_settings.frameDroppingOn); 1752 1753 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, NULL)); 1754 } 1755 1756 class Vp9SettingsTest : public WebRtcVideoChannel2Test { 1757 public: 1758 Vp9SettingsTest() : WebRtcVideoChannel2Test() { 1759 encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP9, "VP9"); 1760 } 1761 virtual ~Vp9SettingsTest() {} 1762 1763 protected: 1764 void SetUp() override { 1765 engine_.SetExternalEncoderFactory(&encoder_factory_); 1766 1767 WebRtcVideoChannel2Test::SetUp(); 1768 } 1769 1770 void TearDown() override { 1771 // Remove references to encoder_factory_ since this will be destroyed 1772 // before channel_ and engine_. 1773 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_)); 1774 } 1775 1776 cricket::FakeWebRtcVideoEncoderFactory encoder_factory_; 1777 }; 1778 1779 TEST_F(Vp9SettingsTest, VerifyVp9SpecificSettings) { 1780 cricket::VideoSendParameters parameters; 1781 parameters.codecs.push_back(kVp9Codec); 1782 ASSERT_TRUE(channel_->SetSendParameters(parameters)); 1783 1784 FakeVideoSendStream* stream = SetUpSimulcast(false, false); 1785 1786 cricket::FakeVideoCapturer capturer; 1787 capturer.SetScreencast(false); 1788 EXPECT_EQ(cricket::CS_RUNNING, 1789 capturer.Start(capturer.GetSupportedFormats()->front())); 1790 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer)); 1791 channel_->SetSend(true); 1792 1793 EXPECT_TRUE(capturer.CaptureFrame()); 1794 1795 webrtc::VideoCodecVP9 vp9_settings; 1796 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set."; 1797 EXPECT_FALSE(vp9_settings.denoisingOn) 1798 << "VP9 denoising should be off by default."; 1799 1800 stream = SetDenoisingOption(parameters, false); 1801 1802 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set."; 1803 EXPECT_FALSE(vp9_settings.denoisingOn); 1804 // Frame dropping always on for real time video. 1805 EXPECT_TRUE(vp9_settings.frameDroppingOn); 1806 1807 stream = SetDenoisingOption(parameters, true); 1808 1809 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set."; 1810 EXPECT_TRUE(vp9_settings.denoisingOn); 1811 EXPECT_TRUE(vp9_settings.frameDroppingOn); 1812 1813 // In screen-share mode, denoising is forced off. 1814 capturer.SetScreencast(true); 1815 EXPECT_TRUE(capturer.CaptureFrame()); 1816 stream = SetDenoisingOption(parameters, false); 1817 1818 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set."; 1819 EXPECT_FALSE(vp9_settings.denoisingOn); 1820 // Frame dropping always off for screen sharing. 1821 EXPECT_FALSE(vp9_settings.frameDroppingOn); 1822 1823 stream = SetDenoisingOption(parameters, false); 1824 1825 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set."; 1826 EXPECT_FALSE(vp9_settings.denoisingOn); 1827 EXPECT_FALSE(vp9_settings.frameDroppingOn); 1828 1829 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, NULL)); 1830 } 1831 1832 TEST_F(WebRtcVideoChannel2Test, DISABLED_MultipleSendStreamsWithOneCapturer) { 1833 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1834 } 1835 1836 TEST_F(WebRtcVideoChannel2Test, DISABLED_SendReceiveBitratesStats) { 1837 FAIL() << "Not implemented."; // TODO(pbos): Implement. 1838 } 1839 1840 TEST_F(WebRtcVideoChannel2Test, AdaptsOnOveruse) { 1841 TestCpuAdaptation(true, false); 1842 } 1843 1844 TEST_F(WebRtcVideoChannel2Test, DoesNotAdaptOnOveruseWhenDisabled) { 1845 TestCpuAdaptation(false, false); 1846 } 1847 1848 TEST_F(WebRtcVideoChannel2Test, DoesNotAdaptOnOveruseWhenScreensharing) { 1849 TestCpuAdaptation(true, true); 1850 } 1851 1852 void WebRtcVideoChannel2Test::TestCpuAdaptation(bool enable_overuse, 1853 bool is_screenshare) { 1854 cricket::VideoCodec codec = kVp8Codec720p; 1855 cricket::VideoSendParameters parameters; 1856 parameters.codecs.push_back(codec); 1857 if (!enable_overuse) { 1858 parameters.options.cpu_overuse_detection = rtc::Optional<bool>(false); 1859 } 1860 EXPECT_TRUE(channel_->SetSendParameters(parameters)); 1861 1862 AddSendStream(); 1863 1864 cricket::FakeVideoCapturer capturer; 1865 capturer.SetScreencast(is_screenshare); 1866 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer)); 1867 EXPECT_EQ(cricket::CS_RUNNING, 1868 capturer.Start(capturer.GetSupportedFormats()->front())); 1869 1870 EXPECT_TRUE(channel_->SetSend(true)); 1871 1872 // Trigger overuse. 1873 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size()); 1874 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front(); 1875 webrtc::LoadObserver* overuse_callback = 1876 send_stream->GetConfig().overuse_callback; 1877 ASSERT_TRUE(overuse_callback != NULL); 1878 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kOveruse); 1879 1880 EXPECT_TRUE(capturer.CaptureFrame()); 1881 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames()); 1882 1883 if (enable_overuse && !is_screenshare) { 1884 EXPECT_LT(send_stream->GetLastWidth(), codec.width); 1885 EXPECT_LT(send_stream->GetLastHeight(), codec.height); 1886 } else { 1887 EXPECT_EQ(codec.width, send_stream->GetLastWidth()); 1888 EXPECT_EQ(codec.height, send_stream->GetLastHeight()); 1889 } 1890 1891 // Trigger underuse which should go back to normal resolution. 1892 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kUnderuse); 1893 EXPECT_TRUE(capturer.CaptureFrame()); 1894 1895 EXPECT_EQ(2, send_stream->GetNumberOfSwappedFrames()); 1896 1897 EXPECT_EQ(codec.width, send_stream->GetLastWidth()); 1898 EXPECT_EQ(codec.height, send_stream->GetLastHeight()); 1899 1900 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, NULL)); 1901 } 1902 1903 TEST_F(WebRtcVideoChannel2Test, EstimatesNtpStartTimeCorrectly) { 1904 // Start at last timestamp to verify that wraparounds are estimated correctly. 1905 static const uint32_t kInitialTimestamp = 0xFFFFFFFFu; 1906 static const int64_t kInitialNtpTimeMs = 1247891230; 1907 static const int kFrameOffsetMs = 20; 1908 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_)); 1909 1910 FakeVideoReceiveStream* stream = AddRecvStream(); 1911 cricket::FakeVideoRenderer renderer; 1912 EXPECT_TRUE(channel_->SetRenderer(last_ssrc_, &renderer)); 1913 1914 webrtc::VideoFrame video_frame; 1915 CreateBlackFrame(&video_frame, 4, 4); 1916 video_frame.set_timestamp(kInitialTimestamp); 1917 // Initial NTP time is not available on the first frame, but should still be 1918 // able to be estimated. 1919 stream->InjectFrame(video_frame, 0); 1920 1921 EXPECT_EQ(1, renderer.num_rendered_frames()); 1922 1923 // This timestamp is kInitialTimestamp (-1) + kFrameOffsetMs * 90, which 1924 // triggers a constant-overflow warning, hence we're calculating it explicitly 1925 // here. 1926 video_frame.set_timestamp(kFrameOffsetMs * 90 - 1); 1927 video_frame.set_ntp_time_ms(kInitialNtpTimeMs + kFrameOffsetMs); 1928 stream->InjectFrame(video_frame, 0); 1929 1930 EXPECT_EQ(2, renderer.num_rendered_frames()); 1931 1932 // Verify that NTP time has been correctly deduced. 1933 cricket::VideoMediaInfo info; 1934 ASSERT_TRUE(channel_->GetStats(&info)); 1935 ASSERT_EQ(1u, info.receivers.size()); 1936 EXPECT_EQ(kInitialNtpTimeMs, info.receivers[0].capture_start_ntp_time_ms); 1937 } 1938 1939 TEST_F(WebRtcVideoChannel2Test, SetDefaultSendCodecs) { 1940 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_)); 1941 1942 VideoCodec codec; 1943 EXPECT_TRUE(channel_->GetSendCodec(&codec)); 1944 EXPECT_TRUE(codec.Matches(engine_.codecs()[0])); 1945 1946 // Using a RTX setup to verify that the default RTX payload type is good. 1947 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1); 1948 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1); 1949 FakeVideoSendStream* stream = AddSendStream( 1950 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs)); 1951 webrtc::VideoSendStream::Config config = stream->GetConfig(); 1952 1953 // Make sure NACK and FEC are enabled on the correct payload types. 1954 EXPECT_EQ(1000, config.rtp.nack.rtp_history_ms); 1955 EXPECT_EQ(default_ulpfec_codec_.id, config.rtp.fec.ulpfec_payload_type); 1956 EXPECT_EQ(default_red_codec_.id, config.rtp.fec.red_payload_type); 1957 1958 EXPECT_EQ(1u, config.rtp.rtx.ssrcs.size()); 1959 EXPECT_EQ(kRtxSsrcs1[0], config.rtp.rtx.ssrcs[0]); 1960 VerifySendStreamHasRtxTypes(config, default_apt_rtx_types_); 1961 // TODO(juberti): Check RTCP, PLI, TMMBR. 1962 } 1963 1964 TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithoutFec) { 1965 cricket::VideoSendParameters parameters; 1966 parameters.codecs.push_back(kVp8Codec); 1967 ASSERT_TRUE(channel_->SetSendParameters(parameters)); 1968 1969 FakeVideoSendStream* stream = AddSendStream(); 1970 webrtc::VideoSendStream::Config config = stream->GetConfig(); 1971 1972 EXPECT_EQ(-1, config.rtp.fec.ulpfec_payload_type); 1973 EXPECT_EQ(-1, config.rtp.fec.red_payload_type); 1974 } 1975 1976 TEST_F(WebRtcVideoChannel2Test, 1977 SetSendCodecRejectsRtxWithoutAssociatedPayloadType) { 1978 cricket::VideoSendParameters parameters; 1979 cricket::VideoCodec rtx_codec(96, "rtx", 0, 0, 0, 0); 1980 parameters.codecs.push_back(rtx_codec); 1981 EXPECT_FALSE(channel_->SetSendParameters(parameters)) 1982 << "RTX codec without associated payload type should be rejected."; 1983 } 1984 1985 TEST_F(WebRtcVideoChannel2Test, 1986 SetSendCodecRejectsRtxWithoutMatchingVideoCodec) { 1987 cricket::VideoSendParameters parameters; 1988 cricket::VideoCodec rtx_codec = 1989 cricket::VideoCodec::CreateRtxCodec(96, kVp8Codec.id); 1990 parameters.codecs.push_back(kVp8Codec); 1991 parameters.codecs.push_back(rtx_codec); 1992 ASSERT_TRUE(channel_->SetSendParameters(parameters)); 1993 1994 cricket::VideoCodec rtx_codec2 = 1995 cricket::VideoCodec::CreateRtxCodec(96, kVp8Codec.id + 1); 1996 parameters.codecs.pop_back(); 1997 parameters.codecs.push_back(rtx_codec2); 1998 EXPECT_FALSE(channel_->SetSendParameters(parameters)) 1999 << "RTX without matching video codec should be rejected."; 2000 } 2001 2002 TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithoutFecDisablesFec) { 2003 cricket::VideoSendParameters parameters; 2004 parameters.codecs.push_back(kVp8Codec); 2005 parameters.codecs.push_back(kUlpfecCodec); 2006 ASSERT_TRUE(channel_->SetSendParameters(parameters)); 2007 2008 FakeVideoSendStream* stream = AddSendStream(); 2009 webrtc::VideoSendStream::Config config = stream->GetConfig(); 2010 2011 EXPECT_EQ(kUlpfecCodec.id, config.rtp.fec.ulpfec_payload_type); 2012 2013 parameters.codecs.pop_back(); 2014 ASSERT_TRUE(channel_->SetSendParameters(parameters)); 2015 stream = fake_call_->GetVideoSendStreams()[0]; 2016 ASSERT_TRUE(stream != NULL); 2017 config = stream->GetConfig(); 2018 EXPECT_EQ(-1, config.rtp.fec.ulpfec_payload_type) 2019 << "SetSendCodec without FEC should disable current FEC."; 2020 } 2021 2022 TEST_F(WebRtcVideoChannel2Test, SetSendCodecsChangesExistingStreams) { 2023 cricket::VideoSendParameters parameters; 2024 parameters.codecs.push_back(kVp8Codec720p); 2025 ASSERT_TRUE(channel_->SetSendParameters(parameters)); 2026 channel_->SetSend(true); 2027 2028 FakeVideoSendStream* stream = AddSendStream(); 2029 2030 cricket::FakeVideoCapturer capturer; 2031 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer)); 2032 EXPECT_EQ(cricket::CS_RUNNING, 2033 capturer.Start(capturer.GetSupportedFormats()->front())); 2034 EXPECT_TRUE(capturer.CaptureFrame()); 2035 2036 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams(); 2037 EXPECT_EQ(kVp8Codec720p.width, streams[0].width); 2038 EXPECT_EQ(kVp8Codec720p.height, streams[0].height); 2039 2040 parameters.codecs.clear(); 2041 parameters.codecs.push_back(kVp8Codec360p); 2042 ASSERT_TRUE(channel_->SetSendParameters(parameters)); 2043 streams = fake_call_->GetVideoSendStreams()[0]->GetVideoStreams(); 2044 EXPECT_EQ(kVp8Codec360p.width, streams[0].width); 2045 EXPECT_EQ(kVp8Codec360p.height, streams[0].height); 2046 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, NULL)); 2047 } 2048 2049 TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithBitrates) { 2050 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200", 2051 200000); 2052 } 2053 2054 TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithHighMaxBitrate) { 2055 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000); 2056 std::vector<webrtc::VideoStream> streams = AddSendStream()->GetVideoStreams(); 2057 ASSERT_EQ(1u, streams.size()); 2058 EXPECT_EQ(10000000, streams[0].max_bitrate_bps); 2059 } 2060 2061 TEST_F(WebRtcVideoChannel2Test, 2062 SetSendCodecsWithoutBitratesUsesCorrectDefaults) { 2063 SetSendCodecsShouldWorkForBitrates( 2064 "", 0, "", -1, "", -1); 2065 } 2066 2067 TEST_F(WebRtcVideoChannel2Test, SetSendCodecsCapsMinAndStartBitrate) { 2068 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1); 2069 } 2070 2071 TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectsMaxLessThanMinBitrate) { 2072 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "300"; 2073 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "200"; 2074 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_)); 2075 } 2076 2077 TEST_F(WebRtcVideoChannel2Test, 2078 SetMaxSendBandwidthShouldPreserveOtherBitrates) { 2079 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200", 2080 200000); 2081 send_parameters_.max_bandwidth_bps = 300000; 2082 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_)); 2083 EXPECT_EQ(100000, fake_call_->GetConfig().bitrate_config.min_bitrate_bps) 2084 << "Setting max bitrate should keep previous min bitrate."; 2085 EXPECT_EQ(-1, fake_call_->GetConfig().bitrate_config.start_bitrate_bps) 2086 << "Setting max bitrate should not reset start bitrate."; 2087 EXPECT_EQ(300000, fake_call_->GetConfig().bitrate_config.max_bitrate_bps); 2088 } 2089 2090 TEST_F(WebRtcVideoChannel2Test, SetMaxSendBandwidthShouldBeRemovable) { 2091 send_parameters_.max_bandwidth_bps = 300000; 2092 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_)); 2093 EXPECT_EQ(300000, fake_call_->GetConfig().bitrate_config.max_bitrate_bps); 2094 // <= 0 means disable (infinite) max bitrate. 2095 send_parameters_.max_bandwidth_bps = 0; 2096 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_)); 2097 EXPECT_EQ(-1, fake_call_->GetConfig().bitrate_config.max_bitrate_bps) 2098 << "Setting zero max bitrate did not reset start bitrate."; 2099 } 2100 2101 TEST_F(WebRtcVideoChannel2Test, SetMaxSendBitrateCanIncreaseSenderBitrate) { 2102 cricket::VideoSendParameters parameters; 2103 parameters.codecs.push_back(kVp8Codec720p); 2104 ASSERT_TRUE(channel_->SetSendParameters(parameters)); 2105 channel_->SetSend(true); 2106 2107 FakeVideoSendStream* stream = AddSendStream(); 2108 2109 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams(); 2110 int initial_max_bitrate_bps = streams[0].max_bitrate_bps; 2111 EXPECT_GT(initial_max_bitrate_bps, 0); 2112 2113 parameters.max_bandwidth_bps = initial_max_bitrate_bps * 2; 2114 EXPECT_TRUE(channel_->SetSendParameters(parameters)); 2115 streams = stream->GetVideoStreams(); 2116 EXPECT_EQ(initial_max_bitrate_bps * 2, streams[0].max_bitrate_bps); 2117 } 2118 2119 TEST_F(WebRtcVideoChannel2Test, 2120 SetMaxSendBitrateCanIncreaseSimulcastSenderBitrate) { 2121 cricket::VideoSendParameters parameters; 2122 parameters.codecs.push_back(kVp8Codec720p); 2123 ASSERT_TRUE(channel_->SetSendParameters(parameters)); 2124 channel_->SetSend(true); 2125 2126 FakeVideoSendStream* stream = AddSendStream( 2127 cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs3))); 2128 2129 // Send a frame to make sure this scales up to >1 stream (simulcast). 2130 cricket::FakeVideoCapturer capturer; 2131 EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], &capturer)); 2132 EXPECT_EQ(cricket::CS_RUNNING, 2133 capturer.Start(capturer.GetSupportedFormats()->front())); 2134 EXPECT_TRUE(capturer.CaptureFrame()); 2135 2136 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams(); 2137 ASSERT_GT(streams.size(), 1u) 2138 << "Without simulcast this test doesn't make sense."; 2139 int initial_max_bitrate_bps = GetTotalMaxBitrateBps(streams); 2140 EXPECT_GT(initial_max_bitrate_bps, 0); 2141 2142 parameters.max_bandwidth_bps = initial_max_bitrate_bps * 2; 2143 EXPECT_TRUE(channel_->SetSendParameters(parameters)); 2144 streams = stream->GetVideoStreams(); 2145 int increased_max_bitrate_bps = GetTotalMaxBitrateBps(streams); 2146 EXPECT_EQ(initial_max_bitrate_bps * 2, increased_max_bitrate_bps); 2147 2148 EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], nullptr)); 2149 } 2150 2151 TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithMaxQuantization) { 2152 static const char* kMaxQuantization = "21"; 2153 cricket::VideoSendParameters parameters; 2154 parameters.codecs.push_back(kVp8Codec); 2155 parameters.codecs[0].params[kCodecParamMaxQuantization] = kMaxQuantization; 2156 EXPECT_TRUE(channel_->SetSendParameters(parameters)); 2157 EXPECT_EQ(static_cast<unsigned int>(atoi(kMaxQuantization)), 2158 AddSendStream()->GetVideoStreams().back().max_qp); 2159 2160 VideoCodec codec; 2161 EXPECT_TRUE(channel_->GetSendCodec(&codec)); 2162 EXPECT_EQ(kMaxQuantization, codec.params[kCodecParamMaxQuantization]); 2163 } 2164 2165 TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectBadDimensions) { 2166 cricket::VideoSendParameters parameters; 2167 parameters.codecs.push_back(kVp8Codec); 2168 2169 parameters.codecs[0].width = 0; 2170 EXPECT_FALSE(channel_->SetSendParameters(parameters)) 2171 << "Codec set though codec width is zero."; 2172 2173 parameters.codecs[0].width = kVp8Codec.width; 2174 parameters.codecs[0].height = 0; 2175 EXPECT_FALSE(channel_->SetSendParameters(parameters)) 2176 << "Codec set though codec height is zero."; 2177 } 2178 2179 TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectBadPayloadTypes) { 2180 // TODO(pbos): Should we only allow the dynamic range? 2181 static const int kIncorrectPayloads[] = {-2, -1, 128, 129}; 2182 cricket::VideoSendParameters parameters; 2183 parameters.codecs.push_back(kVp8Codec); 2184 for (size_t i = 0; i < arraysize(kIncorrectPayloads); ++i) { 2185 parameters.codecs[0].id = kIncorrectPayloads[i]; 2186 EXPECT_FALSE(channel_->SetSendParameters(parameters)) 2187 << "Bad payload type '" << kIncorrectPayloads[i] << "' accepted."; 2188 } 2189 } 2190 2191 TEST_F(WebRtcVideoChannel2Test, SetSendCodecsAcceptAllValidPayloadTypes) { 2192 cricket::VideoSendParameters parameters; 2193 parameters.codecs.push_back(kVp8Codec); 2194 for (int payload_type = 0; payload_type <= 127; ++payload_type) { 2195 parameters.codecs[0].id = payload_type; 2196 EXPECT_TRUE(channel_->SetSendParameters(parameters)) 2197 << "Payload type '" << payload_type << "' rejected."; 2198 } 2199 } 2200 2201 TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithOnlyVp8) { 2202 cricket::VideoRecvParameters parameters; 2203 parameters.codecs.push_back(kVp8Codec); 2204 EXPECT_TRUE(channel_->SetRecvParameters(parameters)); 2205 } 2206 2207 // Test that we set our inbound RTX codecs properly. 2208 TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithRtx) { 2209 cricket::VideoRecvParameters parameters; 2210 parameters.codecs.push_back(kVp8Codec); 2211 cricket::VideoCodec rtx_codec(96, "rtx", 0, 0, 0, 0); 2212 parameters.codecs.push_back(rtx_codec); 2213 EXPECT_FALSE(channel_->SetRecvParameters(parameters)) 2214 << "RTX codec without associated payload should be rejected."; 2215 2216 parameters.codecs[1].SetParam("apt", kVp8Codec.id + 1); 2217 EXPECT_FALSE(channel_->SetRecvParameters(parameters)) 2218 << "RTX codec with invalid associated payload type should be rejected."; 2219 2220 parameters.codecs[1].SetParam("apt", kVp8Codec.id); 2221 EXPECT_TRUE(channel_->SetRecvParameters(parameters)); 2222 2223 cricket::VideoCodec rtx_codec2(97, "rtx", 0, 0, 0, 0); 2224 rtx_codec2.SetParam("apt", rtx_codec.id); 2225 parameters.codecs.push_back(rtx_codec2); 2226 2227 EXPECT_FALSE(channel_->SetRecvParameters(parameters)) << 2228 "RTX codec with another RTX as associated payload type should be " 2229 "rejected."; 2230 } 2231 2232 TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsDifferentPayloadType) { 2233 cricket::VideoRecvParameters parameters; 2234 parameters.codecs.push_back(kVp8Codec); 2235 parameters.codecs[0].id = 99; 2236 EXPECT_TRUE(channel_->SetRecvParameters(parameters)); 2237 } 2238 2239 TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsAcceptDefaultCodecs) { 2240 cricket::VideoRecvParameters parameters; 2241 parameters.codecs = engine_.codecs(); 2242 EXPECT_TRUE(channel_->SetRecvParameters(parameters)); 2243 2244 FakeVideoReceiveStream* stream = AddRecvStream(); 2245 webrtc::VideoReceiveStream::Config config = stream->GetConfig(); 2246 EXPECT_EQ(engine_.codecs()[0].name, config.decoders[0].payload_name); 2247 EXPECT_EQ(engine_.codecs()[0].id, config.decoders[0].payload_type); 2248 } 2249 2250 TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsRejectUnsupportedCodec) { 2251 cricket::VideoRecvParameters parameters; 2252 parameters.codecs.push_back(kVp8Codec); 2253 parameters.codecs.push_back(VideoCodec(101, "WTF3", 640, 400, 30, 0)); 2254 EXPECT_FALSE(channel_->SetRecvParameters(parameters)); 2255 } 2256 2257 // TODO(pbos): Enable VP9 through external codec support 2258 TEST_F(WebRtcVideoChannel2Test, 2259 DISABLED_SetRecvCodecsAcceptsMultipleVideoCodecs) { 2260 cricket::VideoRecvParameters parameters; 2261 parameters.codecs.push_back(kVp8Codec); 2262 parameters.codecs.push_back(kVp9Codec); 2263 EXPECT_TRUE(channel_->SetRecvParameters(parameters)); 2264 } 2265 2266 TEST_F(WebRtcVideoChannel2Test, 2267 DISABLED_SetRecvCodecsSetsFecForAllVideoCodecs) { 2268 cricket::VideoRecvParameters parameters; 2269 parameters.codecs.push_back(kVp8Codec); 2270 parameters.codecs.push_back(kVp9Codec); 2271 EXPECT_TRUE(channel_->SetRecvParameters(parameters)); 2272 FAIL(); // TODO(pbos): Verify that the FEC parameters are set for all codecs. 2273 } 2274 2275 TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithoutFecDisablesFec) { 2276 cricket::VideoSendParameters send_parameters; 2277 send_parameters.codecs.push_back(kVp8Codec); 2278 send_parameters.codecs.push_back(kUlpfecCodec); 2279 ASSERT_TRUE(channel_->SetSendParameters(send_parameters)); 2280 2281 FakeVideoReceiveStream* stream = AddRecvStream(); 2282 webrtc::VideoReceiveStream::Config config = stream->GetConfig(); 2283 2284 EXPECT_EQ(kUlpfecCodec.id, config.rtp.fec.ulpfec_payload_type); 2285 2286 cricket::VideoRecvParameters recv_parameters; 2287 recv_parameters.codecs.push_back(kVp8Codec); 2288 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters)); 2289 stream = fake_call_->GetVideoReceiveStreams()[0]; 2290 ASSERT_TRUE(stream != NULL); 2291 config = stream->GetConfig(); 2292 EXPECT_EQ(-1, config.rtp.fec.ulpfec_payload_type) 2293 << "SetSendCodec without FEC should disable current FEC."; 2294 } 2295 2296 TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectDuplicateFecPayloads) { 2297 cricket::VideoRecvParameters parameters; 2298 parameters.codecs.push_back(kVp8Codec); 2299 parameters.codecs.push_back(kRedCodec); 2300 parameters.codecs[1].id = parameters.codecs[0].id; 2301 EXPECT_FALSE(channel_->SetRecvParameters(parameters)); 2302 } 2303 2304 TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsRejectDuplicateCodecPayloads) { 2305 cricket::VideoRecvParameters parameters; 2306 parameters.codecs.push_back(kVp8Codec); 2307 parameters.codecs.push_back(kVp9Codec); 2308 parameters.codecs[1].id = parameters.codecs[0].id; 2309 EXPECT_FALSE(channel_->SetRecvParameters(parameters)); 2310 } 2311 2312 TEST_F(WebRtcVideoChannel2Test, 2313 SetRecvCodecsAcceptSameCodecOnMultiplePayloadTypes) { 2314 cricket::VideoRecvParameters parameters; 2315 parameters.codecs.push_back(kVp8Codec); 2316 parameters.codecs.push_back(kVp8Codec); 2317 parameters.codecs[1].id += 1; 2318 EXPECT_TRUE(channel_->SetRecvParameters(parameters)); 2319 } 2320 2321 // Test that setting the same codecs but with a different order and preference 2322 // doesn't result in the stream being recreated. 2323 TEST_F(WebRtcVideoChannel2Test, 2324 SetRecvCodecsDifferentOrderAndPreferenceDoesntRecreateStream) { 2325 cricket::VideoRecvParameters parameters1; 2326 parameters1.codecs.push_back(kVp8Codec); 2327 parameters1.codecs.push_back(kRedCodec); 2328 EXPECT_TRUE(channel_->SetRecvParameters(parameters1)); 2329 2330 AddRecvStream(cricket::StreamParams::CreateLegacy(123)); 2331 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams()); 2332 2333 cricket::VideoRecvParameters parameters2; 2334 parameters2.codecs.push_back(kRedCodec); 2335 parameters2.codecs.push_back(kVp8Codec); 2336 parameters2.codecs[1].preference += 1; 2337 EXPECT_TRUE(channel_->SetRecvParameters(parameters2)); 2338 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams()); 2339 } 2340 2341 TEST_F(WebRtcVideoChannel2Test, SendStreamNotSendingByDefault) { 2342 EXPECT_FALSE(AddSendStream()->IsSending()); 2343 } 2344 2345 TEST_F(WebRtcVideoChannel2Test, ReceiveStreamReceivingByDefault) { 2346 EXPECT_TRUE(AddRecvStream()->IsReceiving()); 2347 } 2348 2349 TEST_F(WebRtcVideoChannel2Test, SetSend) { 2350 FakeVideoSendStream* stream = AddSendStream(); 2351 EXPECT_FALSE(stream->IsSending()); 2352 2353 // false->true 2354 EXPECT_TRUE(channel_->SetSend(true)); 2355 EXPECT_TRUE(stream->IsSending()); 2356 // true->true 2357 EXPECT_TRUE(channel_->SetSend(true)); 2358 EXPECT_TRUE(stream->IsSending()); 2359 // true->false 2360 EXPECT_TRUE(channel_->SetSend(false)); 2361 EXPECT_FALSE(stream->IsSending()); 2362 // false->false 2363 EXPECT_TRUE(channel_->SetSend(false)); 2364 EXPECT_FALSE(stream->IsSending()); 2365 2366 EXPECT_TRUE(channel_->SetSend(true)); 2367 FakeVideoSendStream* new_stream = AddSendStream(); 2368 EXPECT_TRUE(new_stream->IsSending()) 2369 << "Send stream created after SetSend(true) not sending initially."; 2370 } 2371 2372 // This test verifies DSCP settings are properly applied on video media channel. 2373 TEST_F(WebRtcVideoChannel2Test, TestSetDscpOptions) { 2374 rtc::scoped_ptr<cricket::FakeNetworkInterface> network_interface( 2375 new cricket::FakeNetworkInterface); 2376 channel_->SetInterface(network_interface.get()); 2377 cricket::VideoSendParameters parameters = send_parameters_; 2378 EXPECT_TRUE(channel_->SetSendParameters(parameters)); 2379 EXPECT_EQ(rtc::DSCP_NO_CHANGE, network_interface->dscp()); 2380 parameters.options.dscp = rtc::Optional<bool>(true); 2381 EXPECT_TRUE(channel_->SetSendParameters(parameters)); 2382 EXPECT_EQ(rtc::DSCP_AF41, network_interface->dscp()); 2383 // Verify previous value is not modified if dscp option is not set. 2384 cricket::VideoSendParameters parameters1 = send_parameters_; 2385 EXPECT_TRUE(channel_->SetSendParameters(parameters1)); 2386 EXPECT_EQ(rtc::DSCP_AF41, network_interface->dscp()); 2387 parameters1.options.dscp = rtc::Optional<bool>(false); 2388 EXPECT_TRUE(channel_->SetSendParameters(parameters1)); 2389 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp()); 2390 channel_->SetInterface(NULL); 2391 } 2392 2393 // This test verifies that the RTCP reduced size mode is properly applied to 2394 // send video streams. 2395 TEST_F(WebRtcVideoChannel2Test, TestSetSendRtcpReducedSize) { 2396 // Create stream, expecting that default mode is "compound". 2397 FakeVideoSendStream* stream1 = AddSendStream(); 2398 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream1->GetConfig().rtp.rtcp_mode); 2399 2400 // Now enable reduced size mode. 2401 send_parameters_.rtcp.reduced_size = true; 2402 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_)); 2403 stream1 = fake_call_->GetVideoSendStreams()[0]; 2404 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream1->GetConfig().rtp.rtcp_mode); 2405 2406 // Create a new stream and ensure it picks up the reduced size mode. 2407 FakeVideoSendStream* stream2 = AddSendStream(); 2408 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream2->GetConfig().rtp.rtcp_mode); 2409 } 2410 2411 // This test verifies that the RTCP reduced size mode is properly applied to 2412 // receive video streams. 2413 TEST_F(WebRtcVideoChannel2Test, TestSetRecvRtcpReducedSize) { 2414 // Create stream, expecting that default mode is "compound". 2415 FakeVideoReceiveStream* stream1 = AddRecvStream(); 2416 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream1->GetConfig().rtp.rtcp_mode); 2417 2418 // Now enable reduced size mode. 2419 recv_parameters_.rtcp.reduced_size = true; 2420 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_)); 2421 stream1 = fake_call_->GetVideoReceiveStreams()[0]; 2422 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream1->GetConfig().rtp.rtcp_mode); 2423 2424 // Create a new stream and ensure it picks up the reduced size mode. 2425 FakeVideoReceiveStream* stream2 = AddRecvStream(); 2426 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream2->GetConfig().rtp.rtcp_mode); 2427 } 2428 2429 TEST_F(WebRtcVideoChannel2Test, OnReadyToSendSignalsNetworkState) { 2430 EXPECT_EQ(webrtc::kNetworkUp, fake_call_->GetNetworkState()); 2431 2432 channel_->OnReadyToSend(false); 2433 EXPECT_EQ(webrtc::kNetworkDown, fake_call_->GetNetworkState()); 2434 2435 channel_->OnReadyToSend(true); 2436 EXPECT_EQ(webrtc::kNetworkUp, fake_call_->GetNetworkState()); 2437 } 2438 2439 TEST_F(WebRtcVideoChannel2Test, GetStatsReportsSentCodecName) { 2440 cricket::VideoSendParameters parameters; 2441 parameters.codecs.push_back(kVp8Codec); 2442 EXPECT_TRUE(channel_->SetSendParameters(parameters)); 2443 2444 AddSendStream(); 2445 2446 cricket::VideoMediaInfo info; 2447 ASSERT_TRUE(channel_->GetStats(&info)); 2448 EXPECT_EQ(kVp8Codec.name, info.senders[0].codec_name); 2449 } 2450 2451 TEST_F(WebRtcVideoChannel2Test, GetStatsReportsEncoderImplementationName) { 2452 FakeVideoSendStream* stream = AddSendStream(); 2453 webrtc::VideoSendStream::Stats stats; 2454 stats.encoder_implementation_name = "encoder_implementation_name"; 2455 stream->SetStats(stats); 2456 2457 cricket::VideoMediaInfo info; 2458 ASSERT_TRUE(channel_->GetStats(&info)); 2459 EXPECT_EQ(stats.encoder_implementation_name, 2460 info.senders[0].encoder_implementation_name); 2461 } 2462 2463 TEST_F(WebRtcVideoChannel2Test, GetStatsReportsCpuOveruseMetrics) { 2464 FakeVideoSendStream* stream = AddSendStream(); 2465 webrtc::VideoSendStream::Stats stats; 2466 stats.avg_encode_time_ms = 13; 2467 stats.encode_usage_percent = 42; 2468 stream->SetStats(stats); 2469 2470 cricket::VideoMediaInfo info; 2471 ASSERT_TRUE(channel_->GetStats(&info)); 2472 EXPECT_EQ(stats.avg_encode_time_ms, info.senders[0].avg_encode_ms); 2473 EXPECT_EQ(stats.encode_usage_percent, info.senders[0].encode_usage_percent); 2474 } 2475 2476 TEST_F(WebRtcVideoChannel2Test, GetStatsReportsUpperResolution) { 2477 FakeVideoSendStream* stream = AddSendStream(); 2478 webrtc::VideoSendStream::Stats stats; 2479 stats.substreams[17].width = 123; 2480 stats.substreams[17].height = 40; 2481 stats.substreams[42].width = 80; 2482 stats.substreams[42].height = 31; 2483 stats.substreams[11].width = 20; 2484 stats.substreams[11].height = 90; 2485 stream->SetStats(stats); 2486 2487 cricket::VideoMediaInfo info; 2488 ASSERT_TRUE(channel_->GetStats(&info)); 2489 ASSERT_EQ(1u, info.senders.size()); 2490 EXPECT_EQ(123, info.senders[0].send_frame_width); 2491 EXPECT_EQ(90, info.senders[0].send_frame_height); 2492 } 2493 2494 TEST_F(WebRtcVideoChannel2Test, GetStatsTracksAdaptationStats) { 2495 AddSendStream(cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs3))); 2496 2497 // Capture format VGA. 2498 cricket::FakeVideoCapturer video_capturer_vga; 2499 const std::vector<cricket::VideoFormat>* formats = 2500 video_capturer_vga.GetSupportedFormats(); 2501 cricket::VideoFormat capture_format_vga = (*formats)[1]; 2502 EXPECT_EQ(cricket::CS_RUNNING, video_capturer_vga.Start(capture_format_vga)); 2503 EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], &video_capturer_vga)); 2504 EXPECT_TRUE(video_capturer_vga.CaptureFrame()); 2505 2506 cricket::VideoCodec send_codec(100, "VP8", 640, 480, 30, 0); 2507 cricket::VideoSendParameters parameters; 2508 parameters.codecs.push_back(send_codec); 2509 EXPECT_TRUE(channel_->SetSendParameters(parameters)); 2510 EXPECT_TRUE(channel_->SetSend(true)); 2511 2512 // Verify that the CpuOveruseObserver is registered and trigger downgrade. 2513 parameters.options.cpu_overuse_detection = rtc::Optional<bool>(true); 2514 EXPECT_TRUE(channel_->SetSendParameters(parameters)); 2515 2516 // Trigger overuse. 2517 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size()); 2518 webrtc::LoadObserver* overuse_callback = 2519 fake_call_->GetVideoSendStreams().front()->GetConfig().overuse_callback; 2520 ASSERT_TRUE(overuse_callback != NULL); 2521 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kOveruse); 2522 2523 // Capture format VGA -> adapt (OnCpuResolutionRequest downgrade) -> VGA/2. 2524 EXPECT_TRUE(video_capturer_vga.CaptureFrame()); 2525 cricket::VideoMediaInfo info; 2526 EXPECT_TRUE(channel_->GetStats(&info)); 2527 ASSERT_EQ(1U, info.senders.size()); 2528 EXPECT_EQ(1, info.senders[0].adapt_changes); 2529 EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_CPU, 2530 info.senders[0].adapt_reason); 2531 2532 // Trigger upgrade and verify that we adapt back up to VGA. 2533 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kUnderuse); 2534 EXPECT_TRUE(video_capturer_vga.CaptureFrame()); 2535 info.Clear(); 2536 EXPECT_TRUE(channel_->GetStats(&info)); 2537 ASSERT_EQ(1U, info.senders.size()); 2538 EXPECT_EQ(2, info.senders[0].adapt_changes); 2539 EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_NONE, 2540 info.senders[0].adapt_reason); 2541 2542 // No capturer (no adapter). Adapt changes from old adapter should be kept. 2543 EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], NULL)); 2544 info.Clear(); 2545 EXPECT_TRUE(channel_->GetStats(&info)); 2546 ASSERT_EQ(1U, info.senders.size()); 2547 EXPECT_EQ(2, info.senders[0].adapt_changes); 2548 EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_NONE, 2549 info.senders[0].adapt_reason); 2550 2551 // Set new capturer, capture format HD. 2552 cricket::FakeVideoCapturer video_capturer_hd; 2553 cricket::VideoFormat capture_format_hd = (*formats)[0]; 2554 EXPECT_EQ(cricket::CS_RUNNING, video_capturer_hd.Start(capture_format_hd)); 2555 EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], &video_capturer_hd)); 2556 EXPECT_TRUE(video_capturer_hd.CaptureFrame()); 2557 2558 // Trigger overuse, HD -> adapt (OnCpuResolutionRequest downgrade) -> HD/2. 2559 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kOveruse); 2560 EXPECT_TRUE(video_capturer_hd.CaptureFrame()); 2561 info.Clear(); 2562 EXPECT_TRUE(channel_->GetStats(&info)); 2563 ASSERT_EQ(1U, info.senders.size()); 2564 EXPECT_EQ(3, info.senders[0].adapt_changes); 2565 EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_CPU, 2566 info.senders[0].adapt_reason); 2567 2568 EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], NULL)); 2569 } 2570 2571 TEST_F(WebRtcVideoChannel2Test, GetStatsTracksAdaptationAndBandwidthStats) { 2572 AddSendStream(cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs3))); 2573 2574 // Capture format VGA. 2575 cricket::FakeVideoCapturer video_capturer_vga; 2576 const std::vector<cricket::VideoFormat>* formats = 2577 video_capturer_vga.GetSupportedFormats(); 2578 cricket::VideoFormat capture_format_vga = (*formats)[1]; 2579 EXPECT_EQ(cricket::CS_RUNNING, video_capturer_vga.Start(capture_format_vga)); 2580 EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], &video_capturer_vga)); 2581 EXPECT_TRUE(video_capturer_vga.CaptureFrame()); 2582 2583 cricket::VideoCodec send_codec(100, "VP8", 640, 480, 30, 0); 2584 cricket::VideoSendParameters parameters; 2585 parameters.codecs.push_back(send_codec); 2586 EXPECT_TRUE(channel_->SetSendParameters(parameters)); 2587 EXPECT_TRUE(channel_->SetSend(true)); 2588 2589 // Verify that the CpuOveruseObserver is registered and trigger downgrade. 2590 parameters.options.cpu_overuse_detection = rtc::Optional<bool>(true); 2591 EXPECT_TRUE(channel_->SetSendParameters(parameters)); 2592 2593 // Trigger overuse -> adapt CPU. 2594 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size()); 2595 webrtc::LoadObserver* overuse_callback = 2596 fake_call_->GetVideoSendStreams().front()->GetConfig().overuse_callback; 2597 ASSERT_TRUE(overuse_callback != NULL); 2598 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kOveruse); 2599 EXPECT_TRUE(video_capturer_vga.CaptureFrame()); 2600 cricket::VideoMediaInfo info; 2601 EXPECT_TRUE(channel_->GetStats(&info)); 2602 ASSERT_EQ(1U, info.senders.size()); 2603 EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_CPU, 2604 info.senders[0].adapt_reason); 2605 2606 // Set bandwidth limitation stats for the stream -> adapt CPU + BW. 2607 webrtc::VideoSendStream::Stats stats; 2608 stats.bw_limited_resolution = true; 2609 fake_call_->GetVideoSendStreams().front()->SetStats(stats); 2610 info.Clear(); 2611 EXPECT_TRUE(channel_->GetStats(&info)); 2612 ASSERT_EQ(1U, info.senders.size()); 2613 EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_CPU + 2614 CoordinatedVideoAdapter::ADAPTREASON_BANDWIDTH, 2615 info.senders[0].adapt_reason); 2616 2617 // Trigger upgrade -> adapt BW. 2618 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kUnderuse); 2619 EXPECT_TRUE(video_capturer_vga.CaptureFrame()); 2620 info.Clear(); 2621 EXPECT_TRUE(channel_->GetStats(&info)); 2622 ASSERT_EQ(1U, info.senders.size()); 2623 EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_BANDWIDTH, 2624 info.senders[0].adapt_reason); 2625 2626 // Reset bandwidth limitation state -> adapt NONE. 2627 stats.bw_limited_resolution = false; 2628 fake_call_->GetVideoSendStreams().front()->SetStats(stats); 2629 info.Clear(); 2630 EXPECT_TRUE(channel_->GetStats(&info)); 2631 ASSERT_EQ(1U, info.senders.size()); 2632 EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_NONE, 2633 info.senders[0].adapt_reason); 2634 2635 EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], NULL)); 2636 } 2637 2638 TEST_F(WebRtcVideoChannel2Test, 2639 GetStatsTranslatesBandwidthLimitedResolutionCorrectly) { 2640 FakeVideoSendStream* stream = AddSendStream(); 2641 webrtc::VideoSendStream::Stats stats; 2642 stats.bw_limited_resolution = true; 2643 stream->SetStats(stats); 2644 2645 cricket::VideoMediaInfo info; 2646 EXPECT_TRUE(channel_->GetStats(&info)); 2647 ASSERT_EQ(1U, info.senders.size()); 2648 EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_BANDWIDTH, 2649 info.senders[0].adapt_reason); 2650 } 2651 2652 TEST_F(WebRtcVideoChannel2Test, 2653 GetStatsTranslatesSendRtcpPacketTypesCorrectly) { 2654 FakeVideoSendStream* stream = AddSendStream(); 2655 webrtc::VideoSendStream::Stats stats; 2656 stats.substreams[17].rtcp_packet_type_counts.fir_packets = 2; 2657 stats.substreams[17].rtcp_packet_type_counts.nack_packets = 3; 2658 stats.substreams[17].rtcp_packet_type_counts.pli_packets = 4; 2659 2660 stats.substreams[42].rtcp_packet_type_counts.fir_packets = 5; 2661 stats.substreams[42].rtcp_packet_type_counts.nack_packets = 7; 2662 stats.substreams[42].rtcp_packet_type_counts.pli_packets = 9; 2663 2664 stream->SetStats(stats); 2665 2666 cricket::VideoMediaInfo info; 2667 ASSERT_TRUE(channel_->GetStats(&info)); 2668 EXPECT_EQ(7, info.senders[0].firs_rcvd); 2669 EXPECT_EQ(10, info.senders[0].nacks_rcvd); 2670 EXPECT_EQ(13, info.senders[0].plis_rcvd); 2671 } 2672 2673 TEST_F(WebRtcVideoChannel2Test, 2674 GetStatsTranslatesReceiveRtcpPacketTypesCorrectly) { 2675 FakeVideoReceiveStream* stream = AddRecvStream(); 2676 webrtc::VideoReceiveStream::Stats stats; 2677 stats.rtcp_packet_type_counts.fir_packets = 2; 2678 stats.rtcp_packet_type_counts.nack_packets = 3; 2679 stats.rtcp_packet_type_counts.pli_packets = 4; 2680 stream->SetStats(stats); 2681 2682 cricket::VideoMediaInfo info; 2683 ASSERT_TRUE(channel_->GetStats(&info)); 2684 EXPECT_EQ(stats.rtcp_packet_type_counts.fir_packets, 2685 info.receivers[0].firs_sent); 2686 EXPECT_EQ(stats.rtcp_packet_type_counts.nack_packets, 2687 info.receivers[0].nacks_sent); 2688 EXPECT_EQ(stats.rtcp_packet_type_counts.pli_packets, 2689 info.receivers[0].plis_sent); 2690 } 2691 2692 TEST_F(WebRtcVideoChannel2Test, GetStatsTranslatesDecodeStatsCorrectly) { 2693 FakeVideoReceiveStream* stream = AddRecvStream(); 2694 webrtc::VideoReceiveStream::Stats stats; 2695 stats.decoder_implementation_name = "decoder_implementation_name"; 2696 stats.decode_ms = 2; 2697 stats.max_decode_ms = 3; 2698 stats.current_delay_ms = 4; 2699 stats.target_delay_ms = 5; 2700 stats.jitter_buffer_ms = 6; 2701 stats.min_playout_delay_ms = 7; 2702 stats.render_delay_ms = 8; 2703 stream->SetStats(stats); 2704 2705 cricket::VideoMediaInfo info; 2706 ASSERT_TRUE(channel_->GetStats(&info)); 2707 EXPECT_EQ(stats.decoder_implementation_name, 2708 info.receivers[0].decoder_implementation_name); 2709 EXPECT_EQ(stats.decode_ms, info.receivers[0].decode_ms); 2710 EXPECT_EQ(stats.max_decode_ms, info.receivers[0].max_decode_ms); 2711 EXPECT_EQ(stats.current_delay_ms, info.receivers[0].current_delay_ms); 2712 EXPECT_EQ(stats.target_delay_ms, info.receivers[0].target_delay_ms); 2713 EXPECT_EQ(stats.jitter_buffer_ms, info.receivers[0].jitter_buffer_ms); 2714 EXPECT_EQ(stats.min_playout_delay_ms, info.receivers[0].min_playout_delay_ms); 2715 EXPECT_EQ(stats.render_delay_ms, info.receivers[0].render_delay_ms); 2716 } 2717 2718 TEST_F(WebRtcVideoChannel2Test, GetStatsTranslatesReceivePacketStatsCorrectly) { 2719 FakeVideoReceiveStream* stream = AddRecvStream(); 2720 webrtc::VideoReceiveStream::Stats stats; 2721 stats.rtp_stats.transmitted.payload_bytes = 2; 2722 stats.rtp_stats.transmitted.header_bytes = 3; 2723 stats.rtp_stats.transmitted.padding_bytes = 4; 2724 stats.rtp_stats.transmitted.packets = 5; 2725 stats.rtcp_stats.cumulative_lost = 6; 2726 stats.rtcp_stats.fraction_lost = 7; 2727 stream->SetStats(stats); 2728 2729 cricket::VideoMediaInfo info; 2730 ASSERT_TRUE(channel_->GetStats(&info)); 2731 EXPECT_EQ(stats.rtp_stats.transmitted.payload_bytes + 2732 stats.rtp_stats.transmitted.header_bytes + 2733 stats.rtp_stats.transmitted.padding_bytes, 2734 info.receivers[0].bytes_rcvd); 2735 EXPECT_EQ(stats.rtp_stats.transmitted.packets, 2736 info.receivers[0].packets_rcvd); 2737 EXPECT_EQ(stats.rtcp_stats.cumulative_lost, info.receivers[0].packets_lost); 2738 EXPECT_EQ(static_cast<float>(stats.rtcp_stats.fraction_lost) / (1 << 8), 2739 info.receivers[0].fraction_lost); 2740 } 2741 2742 TEST_F(WebRtcVideoChannel2Test, TranslatesCallStatsCorrectly) { 2743 AddSendStream(); 2744 AddSendStream(); 2745 webrtc::Call::Stats stats; 2746 stats.rtt_ms = 123; 2747 fake_call_->SetStats(stats); 2748 2749 cricket::VideoMediaInfo info; 2750 ASSERT_TRUE(channel_->GetStats(&info)); 2751 ASSERT_EQ(2u, info.senders.size()); 2752 EXPECT_EQ(stats.rtt_ms, info.senders[0].rtt_ms); 2753 EXPECT_EQ(stats.rtt_ms, info.senders[1].rtt_ms); 2754 } 2755 2756 TEST_F(WebRtcVideoChannel2Test, TranslatesSenderBitrateStatsCorrectly) { 2757 FakeVideoSendStream* stream = AddSendStream(); 2758 webrtc::VideoSendStream::Stats stats; 2759 stats.target_media_bitrate_bps = 156; 2760 stats.media_bitrate_bps = 123; 2761 stats.substreams[17].total_bitrate_bps = 1; 2762 stats.substreams[17].retransmit_bitrate_bps = 2; 2763 stats.substreams[42].total_bitrate_bps = 3; 2764 stats.substreams[42].retransmit_bitrate_bps = 4; 2765 stream->SetStats(stats); 2766 2767 FakeVideoSendStream* stream2 = AddSendStream(); 2768 webrtc::VideoSendStream::Stats stats2; 2769 stats2.target_media_bitrate_bps = 200; 2770 stats2.media_bitrate_bps = 321; 2771 stats2.substreams[13].total_bitrate_bps = 5; 2772 stats2.substreams[13].retransmit_bitrate_bps = 6; 2773 stats2.substreams[21].total_bitrate_bps = 7; 2774 stats2.substreams[21].retransmit_bitrate_bps = 8; 2775 stream2->SetStats(stats2); 2776 2777 cricket::VideoMediaInfo info; 2778 ASSERT_TRUE(channel_->GetStats(&info)); 2779 ASSERT_EQ(2u, info.senders.size()); 2780 // Assuming stream and stream2 corresponds to senders[0] and [1] respectively 2781 // is OK as std::maps are sorted and AddSendStream() gives increasing SSRCs. 2782 EXPECT_EQ(stats.media_bitrate_bps, info.senders[0].nominal_bitrate); 2783 EXPECT_EQ(stats2.media_bitrate_bps, info.senders[1].nominal_bitrate); 2784 EXPECT_EQ(stats.target_media_bitrate_bps + stats2.target_media_bitrate_bps, 2785 info.bw_estimations[0].target_enc_bitrate); 2786 EXPECT_EQ(stats.media_bitrate_bps + stats2.media_bitrate_bps, 2787 info.bw_estimations[0].actual_enc_bitrate); 2788 EXPECT_EQ(1 + 3 + 5 + 7, info.bw_estimations[0].transmit_bitrate) 2789 << "Bandwidth stats should take all streams into account."; 2790 EXPECT_EQ(2 + 4 + 6 + 8, info.bw_estimations[0].retransmit_bitrate) 2791 << "Bandwidth stats should take all streams into account."; 2792 } 2793 2794 TEST_F(WebRtcVideoChannel2Test, DefaultReceiveStreamReconfiguresToUseRtx) { 2795 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_)); 2796 2797 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1); 2798 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1); 2799 2800 ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size()); 2801 const size_t kDataLength = 12; 2802 uint8_t data[kDataLength]; 2803 memset(data, 0, sizeof(data)); 2804 rtc::SetBE32(&data[8], ssrcs[0]); 2805 rtc::Buffer packet(data, kDataLength); 2806 rtc::PacketTime packet_time; 2807 channel_->OnPacketReceived(&packet, packet_time); 2808 2809 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size()) 2810 << "No default receive stream created."; 2811 FakeVideoReceiveStream* recv_stream = fake_call_->GetVideoReceiveStreams()[0]; 2812 EXPECT_EQ(0u, recv_stream->GetConfig().rtp.rtx.size()) 2813 << "Default receive stream should not have configured RTX"; 2814 2815 EXPECT_TRUE(channel_->AddRecvStream( 2816 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs))); 2817 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size()) 2818 << "AddRecvStream should've reconfigured, not added a new receiver."; 2819 recv_stream = fake_call_->GetVideoReceiveStreams()[0]; 2820 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.rtx.size()); 2821 EXPECT_EQ(rtx_ssrcs[0], 2822 recv_stream->GetConfig().rtp.rtx.begin()->second.ssrc); 2823 } 2824 2825 TEST_F(WebRtcVideoChannel2Test, RejectsAddingStreamsWithMissingSsrcsForRtx) { 2826 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_)); 2827 2828 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1); 2829 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1); 2830 2831 StreamParams sp = 2832 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs); 2833 sp.ssrcs = ssrcs; // Without RTXs, this is the important part. 2834 2835 EXPECT_FALSE(channel_->AddSendStream(sp)); 2836 EXPECT_FALSE(channel_->AddRecvStream(sp)); 2837 } 2838 2839 TEST_F(WebRtcVideoChannel2Test, RejectsAddingStreamsWithOverlappingRtxSsrcs) { 2840 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_)); 2841 2842 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1); 2843 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1); 2844 2845 StreamParams sp = 2846 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs); 2847 2848 EXPECT_TRUE(channel_->AddSendStream(sp)); 2849 EXPECT_TRUE(channel_->AddRecvStream(sp)); 2850 2851 // The RTX SSRC is already used in previous streams, using it should fail. 2852 sp = cricket::StreamParams::CreateLegacy(rtx_ssrcs[0]); 2853 EXPECT_FALSE(channel_->AddSendStream(sp)); 2854 EXPECT_FALSE(channel_->AddRecvStream(sp)); 2855 2856 // After removing the original stream this should be fine to add (makes sure 2857 // that RTX ssrcs are not forever taken). 2858 EXPECT_TRUE(channel_->RemoveSendStream(ssrcs[0])); 2859 EXPECT_TRUE(channel_->RemoveRecvStream(ssrcs[0])); 2860 EXPECT_TRUE(channel_->AddSendStream(sp)); 2861 EXPECT_TRUE(channel_->AddRecvStream(sp)); 2862 } 2863 2864 TEST_F(WebRtcVideoChannel2Test, 2865 RejectsAddingStreamsWithOverlappingSimulcastSsrcs) { 2866 static const uint32_t kFirstStreamSsrcs[] = {1, 2, 3}; 2867 static const uint32_t kOverlappingStreamSsrcs[] = {4, 3, 5}; 2868 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_)); 2869 2870 StreamParams sp = 2871 cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kFirstStreamSsrcs)); 2872 2873 EXPECT_TRUE(channel_->AddSendStream(sp)); 2874 EXPECT_TRUE(channel_->AddRecvStream(sp)); 2875 2876 // One of the SSRCs is already used in previous streams, using it should fail. 2877 sp = cricket::CreateSimStreamParams("cname", 2878 MAKE_VECTOR(kOverlappingStreamSsrcs)); 2879 EXPECT_FALSE(channel_->AddSendStream(sp)); 2880 EXPECT_FALSE(channel_->AddRecvStream(sp)); 2881 2882 // After removing the original stream this should be fine to add (makes sure 2883 // that RTX ssrcs are not forever taken). 2884 EXPECT_TRUE(channel_->RemoveSendStream(kFirstStreamSsrcs[0])); 2885 EXPECT_TRUE(channel_->RemoveRecvStream(kFirstStreamSsrcs[0])); 2886 EXPECT_TRUE(channel_->AddSendStream(sp)); 2887 EXPECT_TRUE(channel_->AddRecvStream(sp)); 2888 } 2889 2890 TEST_F(WebRtcVideoChannel2Test, ReportsSsrcGroupsInStats) { 2891 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_)); 2892 2893 static const uint32_t kSenderSsrcs[] = {4, 7, 10}; 2894 static const uint32_t kSenderRtxSsrcs[] = {5, 8, 11}; 2895 2896 StreamParams sender_sp = cricket::CreateSimWithRtxStreamParams( 2897 "cname", MAKE_VECTOR(kSenderSsrcs), MAKE_VECTOR(kSenderRtxSsrcs)); 2898 2899 EXPECT_TRUE(channel_->AddSendStream(sender_sp)); 2900 2901 static const uint32_t kReceiverSsrcs[] = {3}; 2902 static const uint32_t kReceiverRtxSsrcs[] = {2}; 2903 2904 StreamParams receiver_sp = cricket::CreateSimWithRtxStreamParams( 2905 "cname", MAKE_VECTOR(kReceiverSsrcs), MAKE_VECTOR(kReceiverRtxSsrcs)); 2906 EXPECT_TRUE(channel_->AddRecvStream(receiver_sp)); 2907 2908 cricket::VideoMediaInfo info; 2909 ASSERT_TRUE(channel_->GetStats(&info)); 2910 2911 ASSERT_EQ(1u, info.senders.size()); 2912 ASSERT_EQ(1u, info.receivers.size()); 2913 2914 EXPECT_NE(sender_sp.ssrc_groups, receiver_sp.ssrc_groups); 2915 EXPECT_EQ(sender_sp.ssrc_groups, info.senders[0].ssrc_groups); 2916 EXPECT_EQ(receiver_sp.ssrc_groups, info.receivers[0].ssrc_groups); 2917 } 2918 2919 TEST_F(WebRtcVideoChannel2Test, MapsReceivedPayloadTypeToCodecName) { 2920 FakeVideoReceiveStream* stream = AddRecvStream(); 2921 webrtc::VideoReceiveStream::Stats stats; 2922 cricket::VideoMediaInfo info; 2923 2924 // Report no codec name before receiving. 2925 stream->SetStats(stats); 2926 ASSERT_TRUE(channel_->GetStats(&info)); 2927 EXPECT_STREQ("", info.receivers[0].codec_name.c_str()); 2928 2929 // Report VP8 if we're receiving it. 2930 stats.current_payload_type = kDefaultVp8PlType; 2931 stream->SetStats(stats); 2932 ASSERT_TRUE(channel_->GetStats(&info)); 2933 EXPECT_STREQ(kVp8CodecName, info.receivers[0].codec_name.c_str()); 2934 2935 // Report no codec name for unknown playload types. 2936 stats.current_payload_type = 3; 2937 stream->SetStats(stats); 2938 ASSERT_TRUE(channel_->GetStats(&info)); 2939 EXPECT_STREQ("", info.receivers[0].codec_name.c_str()); 2940 } 2941 2942 void WebRtcVideoChannel2Test::TestReceiveUnsignalledSsrcPacket( 2943 uint8_t payload_type, 2944 bool expect_created_receive_stream) { 2945 // Add a RED RTX codec. 2946 VideoCodec red_rtx_codec = 2947 VideoCodec::CreateRtxCodec(kRedRtxPayloadType, kDefaultRedPlType); 2948 recv_parameters_.codecs.push_back(red_rtx_codec); 2949 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_)); 2950 2951 ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size()); 2952 const size_t kDataLength = 12; 2953 uint8_t data[kDataLength]; 2954 memset(data, 0, sizeof(data)); 2955 2956 rtc::Set8(data, 1, payload_type); 2957 rtc::SetBE32(&data[8], kIncomingUnsignalledSsrc); 2958 rtc::Buffer packet(data, kDataLength); 2959 rtc::PacketTime packet_time; 2960 channel_->OnPacketReceived(&packet, packet_time); 2961 2962 if (expect_created_receive_stream) { 2963 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size()) 2964 << "Should have created a receive stream for payload type: " 2965 << payload_type; 2966 } else { 2967 EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size()) 2968 << "Shouldn't have created a receive stream for payload type: " 2969 << payload_type; 2970 } 2971 } 2972 2973 TEST_F(WebRtcVideoChannel2Test, Vp8PacketCreatesUnsignalledStream) { 2974 TestReceiveUnsignalledSsrcPacket(kDefaultVp8PlType, true); 2975 } 2976 2977 TEST_F(WebRtcVideoChannel2Test, Vp9PacketCreatesUnsignalledStream) { 2978 TestReceiveUnsignalledSsrcPacket(kDefaultVp9PlType, true); 2979 } 2980 2981 TEST_F(WebRtcVideoChannel2Test, RtxPacketDoesntCreateUnsignalledStream) { 2982 TestReceiveUnsignalledSsrcPacket(kDefaultRtxVp8PlType, false); 2983 } 2984 2985 TEST_F(WebRtcVideoChannel2Test, UlpfecPacketDoesntCreateUnsignalledStream) { 2986 TestReceiveUnsignalledSsrcPacket(kDefaultUlpfecType, false); 2987 } 2988 2989 TEST_F(WebRtcVideoChannel2Test, RedRtxPacketDoesntCreateUnsignalledStream) { 2990 TestReceiveUnsignalledSsrcPacket(kRedRtxPayloadType, false); 2991 } 2992 2993 void WebRtcVideoChannel2Test::TestReceiverLocalSsrcConfiguration( 2994 bool receiver_first) { 2995 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_)); 2996 2997 const uint32_t kSenderSsrc = 0xC0FFEE; 2998 const uint32_t kSecondSenderSsrc = 0xBADCAFE; 2999 const uint32_t kReceiverSsrc = 0x4711; 3000 const uint32_t kExpectedDefaultReceiverSsrc = 1; 3001 3002 if (receiver_first) { 3003 AddRecvStream(StreamParams::CreateLegacy(kReceiverSsrc)); 3004 std::vector<FakeVideoReceiveStream*> receive_streams = 3005 fake_call_->GetVideoReceiveStreams(); 3006 ASSERT_EQ(1u, receive_streams.size()); 3007 // Default local SSRC when we have no sender. 3008 EXPECT_EQ(kExpectedDefaultReceiverSsrc, 3009 receive_streams[0]->GetConfig().rtp.local_ssrc); 3010 } 3011 AddSendStream(StreamParams::CreateLegacy(kSenderSsrc)); 3012 if (!receiver_first) 3013 AddRecvStream(StreamParams::CreateLegacy(kReceiverSsrc)); 3014 std::vector<FakeVideoReceiveStream*> receive_streams = 3015 fake_call_->GetVideoReceiveStreams(); 3016 ASSERT_EQ(1u, receive_streams.size()); 3017 EXPECT_EQ(kSenderSsrc, receive_streams[0]->GetConfig().rtp.local_ssrc); 3018 3019 // Removing first sender should fall back to another (in this case the second) 3020 // local send stream's SSRC. 3021 AddSendStream(StreamParams::CreateLegacy(kSecondSenderSsrc)); 3022 ASSERT_TRUE(channel_->RemoveSendStream(kSenderSsrc)); 3023 receive_streams = 3024 fake_call_->GetVideoReceiveStreams(); 3025 ASSERT_EQ(1u, receive_streams.size()); 3026 EXPECT_EQ(kSecondSenderSsrc, receive_streams[0]->GetConfig().rtp.local_ssrc); 3027 3028 // Removing the last sender should fall back to default local SSRC. 3029 ASSERT_TRUE(channel_->RemoveSendStream(kSecondSenderSsrc)); 3030 receive_streams = 3031 fake_call_->GetVideoReceiveStreams(); 3032 ASSERT_EQ(1u, receive_streams.size()); 3033 EXPECT_EQ(kExpectedDefaultReceiverSsrc, 3034 receive_streams[0]->GetConfig().rtp.local_ssrc); 3035 } 3036 3037 TEST_F(WebRtcVideoChannel2Test, ConfiguresLocalSsrc) { 3038 TestReceiverLocalSsrcConfiguration(false); 3039 } 3040 3041 TEST_F(WebRtcVideoChannel2Test, ConfiguresLocalSsrcOnExistingReceivers) { 3042 TestReceiverLocalSsrcConfiguration(true); 3043 } 3044 3045 class WebRtcVideoEngine2SimulcastTest : public testing::Test {}; 3046 3047 // Test that if we add a stream with RTX SSRC's, SSRC's get set correctly. 3048 TEST_F(WebRtcVideoEngine2SimulcastTest, DISABLED_TestStreamWithRtx) { 3049 // TODO(pbos): Implement. 3050 FAIL() << "Not implemented."; 3051 } 3052 3053 // Test that if we get too few ssrcs are given in AddSendStream(), 3054 // only supported sub-streams will be added. 3055 TEST_F(WebRtcVideoEngine2SimulcastTest, DISABLED_TooFewSimulcastSsrcs) { 3056 // TODO(pbos): Implement. 3057 FAIL() << "Not implemented."; 3058 } 3059 3060 // Test that even more than enough ssrcs are given in AddSendStream(), 3061 // only supported sub-streams will be added. 3062 TEST_F(WebRtcVideoEngine2SimulcastTest, DISABLED_MoreThanEnoughSimulcastSscrs) { 3063 // TODO(pbos): Implement. 3064 FAIL() << "Not implemented."; 3065 } 3066 3067 // Test that SetSendStreamFormat works well with simulcast. 3068 TEST_F(WebRtcVideoEngine2SimulcastTest, 3069 DISABLED_SetSendStreamFormatWithSimulcast) { 3070 // TODO(pbos): Implement. 3071 FAIL() << "Not implemented."; 3072 } 3073 3074 // Test that simulcast send codec is reset on new video frame size. 3075 TEST_F(WebRtcVideoEngine2SimulcastTest, 3076 DISABLED_ResetSimulcastSendCodecOnNewFrameSize) { 3077 // TODO(pbos): Implement. 3078 FAIL() << "Not implemented."; 3079 } 3080 3081 // Test that simulcast send codec is reset on new portait mode video frame. 3082 TEST_F(WebRtcVideoEngine2SimulcastTest, 3083 DISABLED_ResetSimulcastSendCodecOnNewPortaitFrame) { 3084 // TODO(pbos): Implement. 3085 FAIL() << "Not implemented."; 3086 } 3087 3088 TEST_F(WebRtcVideoEngine2SimulcastTest, 3089 DISABLED_SetBandwidthInConferenceWithSimulcast) { 3090 // TODO(pbos): Implement. 3091 FAIL() << "Not implemented."; 3092 } 3093 3094 // Test that sending screencast frames in conference mode changes 3095 // bitrate. 3096 TEST_F(WebRtcVideoEngine2SimulcastTest, 3097 DISABLED_SetBandwidthScreencastInConference) { 3098 // TODO(pbos): Implement. 3099 FAIL() << "Not implemented."; 3100 } 3101 3102 // Test AddSendStream with simulcast rejects bad StreamParams. 3103 TEST_F(WebRtcVideoEngine2SimulcastTest, 3104 DISABLED_AddSendStreamWithBadStreamParams) { 3105 // TODO(pbos): Implement. 3106 FAIL() << "Not implemented."; 3107 } 3108 3109 // Test AddSendStream with simulcast sets ssrc and cname correctly. 3110 TEST_F(WebRtcVideoEngine2SimulcastTest, DISABLED_AddSendStreamWithSimulcast) { 3111 // TODO(pbos): Implement. 3112 FAIL() << "Not implemented."; 3113 } 3114 3115 // Test RemoveSendStream with simulcast. 3116 TEST_F(WebRtcVideoEngine2SimulcastTest, 3117 DISABLED_RemoveSendStreamWithSimulcast) { 3118 // TODO(pbos): Implement. 3119 FAIL() << "Not implemented."; 3120 } 3121 3122 // Test AddSendStream after send codec has already been set will reset 3123 // send codec with simulcast settings. 3124 TEST_F(WebRtcVideoEngine2SimulcastTest, 3125 DISABLED_AddSimulcastStreamAfterSetSendCodec) { 3126 // TODO(pbos): Implement. 3127 FAIL() << "Not implemented."; 3128 } 3129 3130 TEST_F(WebRtcVideoEngine2SimulcastTest, DISABLED_GetStatsWithMultipleSsrcs) { 3131 // TODO(pbos): Implement. 3132 FAIL() << "Not implemented."; 3133 } 3134 3135 // Test receiving channel(s) local ssrc is set to the same as the first 3136 // simulcast sending ssrc. 3137 TEST_F(WebRtcVideoEngine2SimulcastTest, 3138 DISABLED_AddSimulcastStreamAfterCreatingRecvChannels) { 3139 // TODO(pbos): Implement. 3140 FAIL() << "Not implemented."; 3141 } 3142 3143 // Test 1:1 call never turn on simulcast. 3144 TEST_F(WebRtcVideoEngine2SimulcastTest, DISABLED_NoSimulcastWith1on1) { 3145 // TODO(pbos): Implement. 3146 FAIL() << "Not implemented."; 3147 } 3148 3149 // Test SetOptions with OPT_CONFERENCE flag. 3150 TEST_F(WebRtcVideoEngine2SimulcastTest, DISABLED_SetOptionsWithConferenceMode) { 3151 // TODO(pbos): Implement. 3152 FAIL() << "Not implemented."; 3153 } 3154 3155 // Test that two different streams can have different formats. 3156 TEST_F(WebRtcVideoEngine2SimulcastTest, 3157 DISABLED_MultipleSendStreamsDifferentFormats) { 3158 // TODO(pbos): Implement. 3159 FAIL() << "Not implemented."; 3160 } 3161 3162 TEST_F(WebRtcVideoEngine2SimulcastTest, DISABLED_TestAdaptToOutputFormat) { 3163 // TODO(pbos): Implement. 3164 FAIL() << "Not implemented."; 3165 } 3166 3167 TEST_F(WebRtcVideoEngine2SimulcastTest, 3168 DISABLED_TestAdaptWithCpuOveruseObserver) { 3169 // TODO(pbos): Implement. 3170 FAIL() << "Not implemented."; 3171 } 3172 3173 // Test that codec is not reset for every frame sent in non-conference and 3174 // non-screencast mode. 3175 TEST_F(WebRtcVideoEngine2SimulcastTest, DISABLED_DontResetCodecOnSendFrame) { 3176 // TODO(pbos): Implement. 3177 FAIL() << "Not implemented."; 3178 } 3179 3180 TEST_F(WebRtcVideoEngine2SimulcastTest, 3181 DISABLED_UseSimulcastAdapterOnVp8OnlyFactory) { 3182 // TODO(pbos): Implement. 3183 FAIL() << "Not implemented."; 3184 } 3185 3186 TEST_F(WebRtcVideoEngine2SimulcastTest, 3187 DISABLED_DontUseSimulcastAdapterOnNonVp8Factory) { 3188 // TODO(pbos): Implement. 3189 FAIL() << "Not implemented."; 3190 } 3191 3192 class WebRtcVideoChannel2SimulcastTest : public testing::Test { 3193 public: 3194 WebRtcVideoChannel2SimulcastTest() : fake_call_(webrtc::Call::Config()) {} 3195 3196 void SetUp() override { 3197 engine_.Init(); 3198 channel_.reset(engine_.CreateChannel(&fake_call_, VideoOptions())); 3199 last_ssrc_ = 123; 3200 } 3201 3202 protected: 3203 void VerifySimulcastSettings(const VideoCodec& codec, 3204 size_t num_configured_streams, 3205 size_t expected_num_streams) { 3206 cricket::VideoSendParameters parameters; 3207 parameters.codecs.push_back(codec); 3208 ASSERT_TRUE(channel_->SetSendParameters(parameters)); 3209 3210 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3); 3211 RTC_DCHECK(num_configured_streams <= ssrcs.size()); 3212 ssrcs.resize(num_configured_streams); 3213 3214 FakeVideoSendStream* stream = 3215 AddSendStream(CreateSimStreamParams("cname", ssrcs)); 3216 // Send a full-size frame to trigger a stream reconfiguration to use all 3217 // expected simulcast layers. 3218 cricket::FakeVideoCapturer capturer; 3219 EXPECT_TRUE(channel_->SetCapturer(ssrcs.front(), &capturer)); 3220 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(cricket::VideoFormat( 3221 codec.width, codec.height, 3222 cricket::VideoFormat::FpsToInterval(30), 3223 cricket::FOURCC_I420))); 3224 channel_->SetSend(true); 3225 EXPECT_TRUE(capturer.CaptureFrame()); 3226 3227 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams(); 3228 ASSERT_EQ(expected_num_streams, video_streams.size()); 3229 3230 std::vector<webrtc::VideoStream> expected_streams = GetSimulcastConfig( 3231 num_configured_streams, codec.width, codec.height, 0, kDefaultQpMax, 3232 codec.framerate != 0 ? codec.framerate : kDefaultFramerate); 3233 3234 ASSERT_EQ(expected_streams.size(), video_streams.size()); 3235 3236 size_t num_streams = video_streams.size(); 3237 int total_max_bitrate_bps = 0; 3238 for (size_t i = 0; i < num_streams; ++i) { 3239 EXPECT_EQ(expected_streams[i].width, video_streams[i].width); 3240 EXPECT_EQ(expected_streams[i].height, video_streams[i].height); 3241 3242 EXPECT_GT(video_streams[i].max_framerate, 0); 3243 EXPECT_EQ(expected_streams[i].max_framerate, 3244 video_streams[i].max_framerate); 3245 3246 EXPECT_GT(video_streams[i].min_bitrate_bps, 0); 3247 EXPECT_EQ(expected_streams[i].min_bitrate_bps, 3248 video_streams[i].min_bitrate_bps); 3249 3250 EXPECT_GT(video_streams[i].target_bitrate_bps, 0); 3251 EXPECT_EQ(expected_streams[i].target_bitrate_bps, 3252 video_streams[i].target_bitrate_bps); 3253 3254 EXPECT_GT(video_streams[i].max_bitrate_bps, 0); 3255 EXPECT_EQ(expected_streams[i].max_bitrate_bps, 3256 video_streams[i].max_bitrate_bps); 3257 3258 EXPECT_GT(video_streams[i].max_qp, 0); 3259 EXPECT_EQ(expected_streams[i].max_qp, video_streams[i].max_qp); 3260 3261 EXPECT_FALSE(expected_streams[i].temporal_layer_thresholds_bps.empty()); 3262 EXPECT_EQ(expected_streams[i].temporal_layer_thresholds_bps, 3263 video_streams[i].temporal_layer_thresholds_bps); 3264 3265 if (i == num_streams - 1) { 3266 total_max_bitrate_bps += video_streams[i].max_bitrate_bps; 3267 } else { 3268 total_max_bitrate_bps += video_streams[i].target_bitrate_bps; 3269 } 3270 } 3271 cricket::VideoMediaInfo info; 3272 ASSERT_TRUE(channel_->GetStats(&info)); 3273 ASSERT_EQ(1u, info.senders.size()); 3274 EXPECT_EQ(total_max_bitrate_bps, info.senders[0].preferred_bitrate); 3275 3276 EXPECT_TRUE(channel_->SetCapturer(ssrcs.front(), NULL)); 3277 } 3278 3279 FakeVideoSendStream* AddSendStream() { 3280 return AddSendStream(StreamParams::CreateLegacy(last_ssrc_++)); 3281 } 3282 3283 FakeVideoSendStream* AddSendStream(const StreamParams& sp) { 3284 size_t num_streams = 3285 fake_call_.GetVideoSendStreams().size(); 3286 EXPECT_TRUE(channel_->AddSendStream(sp)); 3287 std::vector<FakeVideoSendStream*> streams = 3288 fake_call_.GetVideoSendStreams(); 3289 EXPECT_EQ(num_streams + 1, streams.size()); 3290 return streams[streams.size() - 1]; 3291 } 3292 3293 std::vector<FakeVideoSendStream*> GetFakeSendStreams() { 3294 return fake_call_.GetVideoSendStreams(); 3295 } 3296 3297 FakeVideoReceiveStream* AddRecvStream() { 3298 return AddRecvStream(StreamParams::CreateLegacy(last_ssrc_++)); 3299 } 3300 3301 FakeVideoReceiveStream* AddRecvStream(const StreamParams& sp) { 3302 size_t num_streams = 3303 fake_call_.GetVideoReceiveStreams().size(); 3304 EXPECT_TRUE(channel_->AddRecvStream(sp)); 3305 std::vector<FakeVideoReceiveStream*> streams = 3306 fake_call_.GetVideoReceiveStreams(); 3307 EXPECT_EQ(num_streams + 1, streams.size()); 3308 return streams[streams.size() - 1]; 3309 } 3310 3311 FakeCall fake_call_; 3312 WebRtcVideoEngine2 engine_; 3313 rtc::scoped_ptr<VideoMediaChannel> channel_; 3314 uint32_t last_ssrc_; 3315 }; 3316 3317 TEST_F(WebRtcVideoChannel2SimulcastTest, SetSendCodecsWith2SimulcastStreams) { 3318 VerifySimulcastSettings(kVp8Codec, 2, 2); 3319 } 3320 3321 TEST_F(WebRtcVideoChannel2SimulcastTest, SetSendCodecsWith3SimulcastStreams) { 3322 VerifySimulcastSettings(kVp8Codec720p, 3, 3); 3323 } 3324 3325 // Test that we normalize send codec format size in simulcast. 3326 TEST_F(WebRtcVideoChannel2SimulcastTest, SetSendCodecsWithOddSizeInSimulcast) { 3327 cricket::VideoCodec codec(kVp8Codec270p); 3328 codec.width += 1; 3329 codec.height += 1; 3330 VerifySimulcastSettings(codec, 2, 2); 3331 } 3332 3333 TEST_F(WebRtcVideoChannel2SimulcastTest, DISABLED_SimulcastSend_1280x800) { 3334 // TODO(pbos): Implement. 3335 FAIL() << "Not implemented."; 3336 } 3337 3338 TEST_F(WebRtcVideoChannel2SimulcastTest, DISABLED_SimulcastSend_1280x720) { 3339 // TODO(pbos): Implement. 3340 FAIL() << "Not implemented."; 3341 } 3342 3343 TEST_F(WebRtcVideoChannel2SimulcastTest, DISABLED_SimulcastSend_960x540) { 3344 // TODO(pbos): Implement. 3345 FAIL() << "Not implemented."; 3346 } 3347 3348 TEST_F(WebRtcVideoChannel2SimulcastTest, DISABLED_SimulcastSend_960x600) { 3349 // TODO(pbos): Implement. 3350 FAIL() << "Not implemented."; 3351 } 3352 3353 TEST_F(WebRtcVideoChannel2SimulcastTest, DISABLED_SimulcastSend_640x400) { 3354 // TODO(pbos): Implement. 3355 FAIL() << "Not implemented."; 3356 } 3357 3358 TEST_F(WebRtcVideoChannel2SimulcastTest, DISABLED_SimulcastSend_640x360) { 3359 // TODO(pbos): Implement. 3360 FAIL() << "Not implemented."; 3361 } 3362 3363 TEST_F(WebRtcVideoChannel2SimulcastTest, DISABLED_SimulcastSend_480x300) { 3364 // TODO(pbos): Implement. 3365 FAIL() << "Not implemented."; 3366 } 3367 3368 TEST_F(WebRtcVideoChannel2SimulcastTest, DISABLED_SimulcastSend_480x270) { 3369 // TODO(pbos): Implement. 3370 FAIL() << "Not implemented."; 3371 } 3372 3373 TEST_F(WebRtcVideoChannel2SimulcastTest, DISABLED_SimulcastSend_320x200) { 3374 // TODO(pbos): Implement. 3375 FAIL() << "Not implemented."; 3376 } 3377 3378 TEST_F(WebRtcVideoChannel2SimulcastTest, DISABLED_SimulcastSend_320x180) { 3379 // TODO(pbos): Implement. 3380 FAIL() << "Not implemented."; 3381 } 3382 3383 // Test simulcast streams are decodeable with expected sizes. 3384 TEST_F(WebRtcVideoChannel2SimulcastTest, DISABLED_SimulcastStreams) { 3385 // TODO(pbos): Implement. 3386 FAIL() << "Not implemented."; 3387 } 3388 3389 // Simulcast and resolution resizing should be turned off when screencasting 3390 // but not otherwise. 3391 TEST_F(WebRtcVideoChannel2SimulcastTest, DISABLED_ScreencastRendering) { 3392 // TODO(pbos): Implement. 3393 FAIL() << "Not implemented."; 3394 } 3395 3396 // Ensures that the correct settings are applied to the codec when single 3397 // temporal layer screencasting is enabled, and that the correct simulcast 3398 // settings are reapplied when disabling screencasting. 3399 TEST_F(WebRtcVideoChannel2SimulcastTest, 3400 DISABLED_OneTemporalLayerScreencastSettings) { 3401 // TODO(pbos): Implement. 3402 FAIL() << "Not implemented."; 3403 } 3404 3405 // Ensures that the correct settings are applied to the codec when two temporal 3406 // layer screencasting is enabled, and that the correct simulcast settings are 3407 // reapplied when disabling screencasting. 3408 TEST_F(WebRtcVideoChannel2SimulcastTest, 3409 DISABLED_TwoTemporalLayerScreencastSettings) { 3410 // TODO(pbos): Implement. 3411 FAIL() << "Not implemented."; 3412 } 3413 3414 } // namespace cricket 3415