Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(50)

Side by Side Diff: webrtc/video/video_send_stream_tests.cc

Issue 1687303002: Don't send FEC for H.264 with NACK enabled. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: feedback Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 #include <algorithm> // max 10 #include <algorithm> // max
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 return true; 301 return true;
302 } 302 }
303 303
304 RtcpStatistics stats_; 304 RtcpStatistics stats_;
305 }; 305 };
306 306
307 rtc::scoped_ptr<LossyStatistician> lossy_stats_; 307 rtc::scoped_ptr<LossyStatistician> lossy_stats_;
308 StatisticianMap stats_map_; 308 StatisticianMap stats_map_;
309 }; 309 };
310 310
311 class FecObserver : public test::SendTest { 311 class FecObserver : public test::EndToEndTest {
312 public: 312 public:
313 explicit FecObserver(bool header_extensions_enabled) 313 FecObserver(bool header_extensions_enabled,
314 : SendTest(VideoSendStreamTest::kDefaultTimeoutMs), 314 bool use_nack,
315 bool expect_red,
316 const std::string& codec)
317 : EndToEndTest(VideoSendStreamTest::kDefaultTimeoutMs),
318 payload_name_(codec),
319 use_nack_(use_nack),
320 expect_red_(expect_red),
315 send_count_(0), 321 send_count_(0),
316 received_media_(false), 322 received_media_(false),
317 received_fec_(false), 323 received_fec_(false),
318 header_extensions_enabled_(header_extensions_enabled) {} 324 header_extensions_enabled_(header_extensions_enabled) {
325 if (codec == "H264") {
326 encoder_.reset(new test::FakeH264Encoder(Clock::GetRealTimeClock()));
327 } else if (codec == "VP8") {
328 encoder_.reset(VideoEncoder::Create(VideoEncoder::EncoderType::kVp8));
329 } else if (codec == "VP9") {
330 encoder_.reset(VideoEncoder::Create(VideoEncoder::EncoderType::kVp9));
331 } else {
332 RTC_NOTREACHED();
333 }
334 }
319 335
320 private: 336 private:
321 Action OnSendRtp(const uint8_t* packet, size_t length) override { 337 Action OnSendRtp(const uint8_t* packet, size_t length) override {
322 RTPHeader header; 338 RTPHeader header;
323 EXPECT_TRUE(parser_->Parse(packet, length, &header)); 339 EXPECT_TRUE(parser_->Parse(packet, length, &header));
324 340
325 // Send lossy receive reports to trigger FEC enabling. 341 ++send_count_;
326 if (send_count_++ % 2 != 0) {
327 // Receive statistics reporting having lost 50% of the packets.
328 FakeReceiveStatistics lossy_receive_stats(
329 VideoSendStreamTest::kVideoSendSsrcs[0], header.sequenceNumber,
330 send_count_ / 2, 127);
331 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(),
332 &lossy_receive_stats, nullptr, nullptr,
333 transport_adapter_.get());
334
335 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
336 rtcp_sender.SetRemoteSSRC(VideoSendStreamTest::kVideoSendSsrcs[0]);
337
338 RTCPSender::FeedbackState feedback_state;
339
340 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
341 }
342
343 int encapsulated_payload_type = -1; 342 int encapsulated_payload_type = -1;
344 if (header.payloadType == VideoSendStreamTest::kRedPayloadType) { 343 if (header.payloadType == VideoSendStreamTest::kRedPayloadType) {
344 EXPECT_TRUE(expect_red_);
345 encapsulated_payload_type = static_cast<int>(packet[header.headerLength]); 345 encapsulated_payload_type = static_cast<int>(packet[header.headerLength]);
346 if (encapsulated_payload_type != 346 if (encapsulated_payload_type !=
347 VideoSendStreamTest::kFakeVideoSendPayloadType) 347 VideoSendStreamTest::kFakeVideoSendPayloadType) {
348 EXPECT_EQ(VideoSendStreamTest::kUlpfecPayloadType, 348 EXPECT_EQ(VideoSendStreamTest::kUlpfecPayloadType,
349 encapsulated_payload_type); 349 encapsulated_payload_type);
350 }
350 } else { 351 } else {
351 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType, 352 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
352 header.payloadType); 353 header.payloadType);
354 if (static_cast<size_t>(header.headerLength + header.paddingLength) <
355 length) {
356 // Not padding-only, media received outside of RED.
357 EXPECT_FALSE(expect_red_);
358 received_media_ = true;
359 }
353 } 360 }
354 361
355 if (header_extensions_enabled_) { 362 if (header_extensions_enabled_) {
356 EXPECT_TRUE(header.extension.hasAbsoluteSendTime); 363 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
357 uint32_t kHalf24BitsSpace = 0xFFFFFF / 2; 364 uint32_t kHalf24BitsSpace = 0xFFFFFF / 2;
358 if (header.extension.absoluteSendTime <= kHalf24BitsSpace && 365 if (header.extension.absoluteSendTime <= kHalf24BitsSpace &&
359 prev_header_.extension.absoluteSendTime > kHalf24BitsSpace) { 366 prev_header_.extension.absoluteSendTime > kHalf24BitsSpace) {
360 // 24 bits wrap. 367 // 24 bits wrap.
361 EXPECT_GT(prev_header_.extension.absoluteSendTime, 368 EXPECT_GT(prev_header_.extension.absoluteSendTime,
362 header.extension.absoluteSendTime); 369 header.extension.absoluteSendTime);
363 } else { 370 } else {
364 EXPECT_GE(header.extension.absoluteSendTime, 371 EXPECT_GE(header.extension.absoluteSendTime,
365 prev_header_.extension.absoluteSendTime); 372 prev_header_.extension.absoluteSendTime);
366 } 373 }
367 EXPECT_TRUE(header.extension.hasTransportSequenceNumber); 374 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
368 uint16_t seq_num_diff = header.extension.transportSequenceNumber - 375 uint16_t seq_num_diff = header.extension.transportSequenceNumber -
369 prev_header_.extension.transportSequenceNumber; 376 prev_header_.extension.transportSequenceNumber;
370 EXPECT_EQ(1, seq_num_diff); 377 EXPECT_EQ(1, seq_num_diff);
371 } 378 }
372 379
373 if (encapsulated_payload_type != -1) { 380 if (encapsulated_payload_type != -1) {
374 if (encapsulated_payload_type == 381 if (encapsulated_payload_type ==
375 VideoSendStreamTest::kUlpfecPayloadType) { 382 VideoSendStreamTest::kUlpfecPayloadType) {
376 received_fec_ = true; 383 received_fec_ = true;
377 } else { 384 } else {
378 received_media_ = true; 385 received_media_ = true;
379 } 386 }
380 } 387 }
381 388
382 if (received_media_ && received_fec_ && send_count_ > 100) 389 if (send_count_ > 100 && received_media_) {
383 observation_complete_.Set(); 390 if (received_fec_ || !expect_red_)
391 observation_complete_.Set();
392 }
384 393
385 prev_header_ = header; 394 prev_header_ = header;
386 395
387 return SEND_PACKET; 396 return SEND_PACKET;
388 } 397 }
389 398
399 test::PacketTransport* CreateSendTransport(Call* sender_call) override {
400 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
401 // Configure some network delay.
402 const int kNetworkDelayMs = 100;
403 FakeNetworkPipe::Config config;
404 config.loss_percent = 50;
405 config.queue_delay_ms = kNetworkDelayMs;
406 return new test::PacketTransport(sender_call, this,
407 test::PacketTransport::kSender, config);
408 }
409
390 void ModifyVideoConfigs( 410 void ModifyVideoConfigs(
391 VideoSendStream::Config* send_config, 411 VideoSendStream::Config* send_config,
392 std::vector<VideoReceiveStream::Config>* receive_configs, 412 std::vector<VideoReceiveStream::Config>* receive_configs,
393 VideoEncoderConfig* encoder_config) override { 413 VideoEncoderConfig* encoder_config) override {
394 transport_adapter_.reset( 414 transport_adapter_.reset(
395 new internal::TransportAdapter(send_config->send_transport)); 415 new internal::TransportAdapter(send_config->send_transport));
396 transport_adapter_->Enable(); 416 transport_adapter_->Enable();
417 if (use_nack_) {
418 send_config->rtp.nack.rtp_history_ms =
419 (*receive_configs)[0].rtp.nack.rtp_history_ms =
420 VideoSendStreamTest::kNackRtpHistoryMs;
421 }
422 send_config->encoder_settings.encoder = encoder_.get();
423 send_config->encoder_settings.payload_name = payload_name_;
397 send_config->rtp.fec.red_payload_type = 424 send_config->rtp.fec.red_payload_type =
398 VideoSendStreamTest::kRedPayloadType; 425 VideoSendStreamTest::kRedPayloadType;
399 send_config->rtp.fec.ulpfec_payload_type = 426 send_config->rtp.fec.ulpfec_payload_type =
400 VideoSendStreamTest::kUlpfecPayloadType; 427 VideoSendStreamTest::kUlpfecPayloadType;
401 if (header_extensions_enabled_) { 428 if (header_extensions_enabled_) {
402 send_config->rtp.extensions.push_back(RtpExtension( 429 send_config->rtp.extensions.push_back(RtpExtension(
403 RtpExtension::kAbsSendTime, test::kAbsSendTimeExtensionId)); 430 RtpExtension::kAbsSendTime, test::kAbsSendTimeExtensionId));
404 send_config->rtp.extensions.push_back( 431 send_config->rtp.extensions.push_back(
405 RtpExtension(RtpExtension::kTransportSequenceNumber, 432 RtpExtension(RtpExtension::kTransportSequenceNumber,
406 test::kTransportSequenceNumberExtensionId)); 433 test::kTransportSequenceNumberExtensionId));
407 } 434 }
435 (*receive_configs)[0].rtp.fec.red_payload_type =
436 send_config->rtp.fec.red_payload_type;
437 (*receive_configs)[0].rtp.fec.ulpfec_payload_type =
438 send_config->rtp.fec.ulpfec_payload_type;
408 } 439 }
409 440
410 void PerformTest() override { 441 void PerformTest() override {
411 EXPECT_TRUE(Wait()) << "Timed out waiting for FEC and media packets."; 442 EXPECT_TRUE(Wait()) << "Timed out waiting for FEC and media packets.";
412 } 443 }
413 444
414 rtc::scoped_ptr<internal::TransportAdapter> transport_adapter_; 445 rtc::scoped_ptr<internal::TransportAdapter> transport_adapter_;
446 rtc::scoped_ptr<VideoEncoder> encoder_;
447 const std::string payload_name_;
448 const bool use_nack_;
449 const bool expect_red_;
415 int send_count_; 450 int send_count_;
416 bool received_media_; 451 bool received_media_;
417 bool received_fec_; 452 bool received_fec_;
418 bool header_extensions_enabled_; 453 bool header_extensions_enabled_;
419 RTPHeader prev_header_; 454 RTPHeader prev_header_;
420 }; 455 };
421 456
422 TEST_F(VideoSendStreamTest, SupportsFecWithExtensions) { 457 TEST_F(VideoSendStreamTest, SupportsFecWithExtensions) {
423 FecObserver test(true); 458 FecObserver test(true, false, true, "VP8");
424
425 RunBaseTest(&test); 459 RunBaseTest(&test);
426 } 460 }
427 461
428 TEST_F(VideoSendStreamTest, SupportsFecWithoutExtensions) { 462 TEST_F(VideoSendStreamTest, SupportsFecWithoutExtensions) {
429 FecObserver test(false); 463 FecObserver test(false, false, true, "VP8");
430
431 RunBaseTest(&test); 464 RunBaseTest(&test);
432 } 465 }
433 466
467 // The FEC scheme used is not efficient for H264, so we should not use RED/FEC
468 // since we'll still have to re-request FEC packets, effectively wasting
469 // bandwidth since the receiver has to wait for FEC retransmissions to determine
470 // that the received state is actually decodable.
471 TEST_F(VideoSendStreamTest, DoesNotUtilizeRedForH264WithNackEnabled) {
472 FecObserver test(false, true, false, "H264");
473 RunBaseTest(&test);
474 }
475
476 // Without retransmissions FEC for H264 is fine.
477 TEST_F(VideoSendStreamTest, DoesUtilizeRedForH264WithoutNackEnabled) {
478 FecObserver test(false, false, true, "H264");
479 RunBaseTest(&test);
480 }
481
482 TEST_F(VideoSendStreamTest, DoesUtilizeRedForVp8WithNackEnabled) {
483 FecObserver test(false, true, true, "VP8");
484 RunBaseTest(&test);
485 }
486
487 TEST_F(VideoSendStreamTest, DoesUtilizeRedForVp9WithNackEnabled) {
488 FecObserver test(false, true, true, "VP9");
489 RunBaseTest(&test);
490 }
491
434 void VideoSendStreamTest::TestNackRetransmission( 492 void VideoSendStreamTest::TestNackRetransmission(
435 uint32_t retransmit_ssrc, 493 uint32_t retransmit_ssrc,
436 uint8_t retransmit_payload_type) { 494 uint8_t retransmit_payload_type) {
437 class NackObserver : public test::SendTest { 495 class NackObserver : public test::SendTest {
438 public: 496 public:
439 explicit NackObserver(uint32_t retransmit_ssrc, 497 explicit NackObserver(uint32_t retransmit_ssrc,
440 uint8_t retransmit_payload_type) 498 uint8_t retransmit_payload_type)
441 : SendTest(kDefaultTimeoutMs), 499 : SendTest(kDefaultTimeoutMs),
442 send_count_(0), 500 send_count_(0),
443 retransmit_ssrc_(retransmit_ssrc), 501 retransmit_ssrc_(retransmit_ssrc),
(...skipping 1813 matching lines...) Expand 10 before | Expand all | Expand 10 after
2257 observation_complete_.Set(); 2315 observation_complete_.Set();
2258 } 2316 }
2259 } 2317 }
2260 } test; 2318 } test;
2261 2319
2262 RunBaseTest(&test); 2320 RunBaseTest(&test);
2263 } 2321 }
2264 #endif 2322 #endif
2265 2323
2266 } // namespace webrtc 2324 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698