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

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: add log warning 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 (*receive_configs)[0].rtp.fec.red_payload_type =
426 VideoSendStreamTest::kRedPayloadType;
399 send_config->rtp.fec.ulpfec_payload_type = 427 send_config->rtp.fec.ulpfec_payload_type =
400 VideoSendStreamTest::kUlpfecPayloadType; 428 (*receive_configs)[0].rtp.fec.ulpfec_payload_type =
429 VideoSendStreamTest::kUlpfecPayloadType;
stefan-webrtc 2016/02/12 10:46:27 I personally prefer to configure the sender first
pbos-webrtc 2016/02/12 12:00:27 Done.
401 if (header_extensions_enabled_) { 430 if (header_extensions_enabled_) {
402 send_config->rtp.extensions.push_back(RtpExtension( 431 send_config->rtp.extensions.push_back(RtpExtension(
403 RtpExtension::kAbsSendTime, test::kAbsSendTimeExtensionId)); 432 RtpExtension::kAbsSendTime, test::kAbsSendTimeExtensionId));
404 send_config->rtp.extensions.push_back( 433 send_config->rtp.extensions.push_back(
405 RtpExtension(RtpExtension::kTransportSequenceNumber, 434 RtpExtension(RtpExtension::kTransportSequenceNumber,
406 test::kTransportSequenceNumberExtensionId)); 435 test::kTransportSequenceNumberExtensionId));
407 } 436 }
408 } 437 }
409 438
410 void PerformTest() override { 439 void PerformTest() override {
411 EXPECT_TRUE(Wait()) << "Timed out waiting for FEC and media packets."; 440 EXPECT_TRUE(Wait()) << "Timed out waiting for FEC and media packets.";
412 } 441 }
413 442
414 rtc::scoped_ptr<internal::TransportAdapter> transport_adapter_; 443 rtc::scoped_ptr<internal::TransportAdapter> transport_adapter_;
444 rtc::scoped_ptr<VideoEncoder> encoder_;
445 const std::string payload_name_;
446 const bool use_nack_;
447 const bool expect_red_;
415 int send_count_; 448 int send_count_;
416 bool received_media_; 449 bool received_media_;
417 bool received_fec_; 450 bool received_fec_;
418 bool header_extensions_enabled_; 451 bool header_extensions_enabled_;
419 RTPHeader prev_header_; 452 RTPHeader prev_header_;
420 }; 453 };
421 454
422 TEST_F(VideoSendStreamTest, SupportsFecWithExtensions) { 455 TEST_F(VideoSendStreamTest, SupportsFecWithExtensions) {
423 FecObserver test(true); 456 FecObserver test(true, false, true, "VP8");
424
425 RunBaseTest(&test); 457 RunBaseTest(&test);
426 } 458 }
427 459
428 TEST_F(VideoSendStreamTest, SupportsFecWithoutExtensions) { 460 TEST_F(VideoSendStreamTest, SupportsFecWithoutExtensions) {
429 FecObserver test(false); 461 FecObserver test(false, false, true, "VP8");
430
431 RunBaseTest(&test); 462 RunBaseTest(&test);
432 } 463 }
433 464
465 // The FEC scheme used is not efficient for H264, so we should not use RED/FEC
466 // since we'll still have to re-request FEC packets, efficiently wasting
stefan-webrtc 2016/02/12 10:46:27 "effectively wasting"?
pbos-webrtc 2016/02/12 12:00:27 Done.
467 // bandwidth. Also FEC packets are not stored on the sender, so retransmission
468 // requests for FEC packets are dropped.
stefan-webrtc 2016/02/12 10:46:27 I think the main issue is that we have to wait for
pbos-webrtc 2016/02/12 12:00:27 Done.
469 TEST_F(VideoSendStreamTest, DoesNotUtilizeRedForH264WithNackEnabled) {
470 FecObserver test(false, true, false, "H264");
471 RunBaseTest(&test);
472 }
473
474 // Without retransmissions FEC for H264 is fine.
475 TEST_F(VideoSendStreamTest, DoesUtilizeRedForH264WithoutNackEnabled) {
476 FecObserver test(false, false, true, "H264");
477 RunBaseTest(&test);
478 }
479
480 TEST_F(VideoSendStreamTest, DoesUtilizeRedForVp8WithNackEnabled) {
481 FecObserver test(false, true, true, "VP8");
482 RunBaseTest(&test);
483 }
484
485 TEST_F(VideoSendStreamTest, DoesUtilizeRedForVp9WithNackEnabled) {
486 FecObserver test(false, true, true, "VP9");
487 RunBaseTest(&test);
488 }
489
434 void VideoSendStreamTest::TestNackRetransmission( 490 void VideoSendStreamTest::TestNackRetransmission(
435 uint32_t retransmit_ssrc, 491 uint32_t retransmit_ssrc,
436 uint8_t retransmit_payload_type) { 492 uint8_t retransmit_payload_type) {
437 class NackObserver : public test::SendTest { 493 class NackObserver : public test::SendTest {
438 public: 494 public:
439 explicit NackObserver(uint32_t retransmit_ssrc, 495 explicit NackObserver(uint32_t retransmit_ssrc,
440 uint8_t retransmit_payload_type) 496 uint8_t retransmit_payload_type)
441 : SendTest(kDefaultTimeoutMs), 497 : SendTest(kDefaultTimeoutMs),
442 send_count_(0), 498 send_count_(0),
443 retransmit_ssrc_(retransmit_ssrc), 499 retransmit_ssrc_(retransmit_ssrc),
(...skipping 1813 matching lines...) Expand 10 before | Expand all | Expand 10 after
2257 observation_complete_.Set(); 2313 observation_complete_.Set();
2258 } 2314 }
2259 } 2315 }
2260 } test; 2316 } test;
2261 2317
2262 RunBaseTest(&test); 2318 RunBaseTest(&test);
2263 } 2319 }
2264 #endif 2320 #endif
2265 2321
2266 } // namespace webrtc 2322 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698