OLD | NEW |
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> | 10 #include <algorithm> |
(...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
574 | 574 |
575 uint32_t local_ssrc_; | 575 uint32_t local_ssrc_; |
576 uint32_t remote_ssrc_; | 576 uint32_t remote_ssrc_; |
577 Transport* receive_transport_; | 577 Transport* receive_transport_; |
578 rtc::Optional<uint16_t> sequence_number_to_retransmit_; | 578 rtc::Optional<uint16_t> sequence_number_to_retransmit_; |
579 } test; | 579 } test; |
580 | 580 |
581 RunBaseTest(&test); | 581 RunBaseTest(&test); |
582 } | 582 } |
583 | 583 |
584 TEST_F(EndToEndTest, CanReceiveFec) { | 584 TEST_F(EndToEndTest, CanReceiveUlpfec) { |
585 class FecRenderObserver : public test::EndToEndTest, | 585 class UlpfecRenderObserver : public test::EndToEndTest, |
586 public rtc::VideoSinkInterface<VideoFrame> { | 586 public rtc::VideoSinkInterface<VideoFrame> { |
587 public: | 587 public: |
588 FecRenderObserver() | 588 UlpfecRenderObserver() |
589 : EndToEndTest(kDefaultTimeoutMs), state_(kFirstPacket) {} | 589 : EndToEndTest(kDefaultTimeoutMs), state_(kFirstPacket) {} |
590 | 590 |
591 private: | 591 private: |
592 Action OnSendRtp(const uint8_t* packet, size_t length) override { | 592 Action OnSendRtp(const uint8_t* packet, size_t length) override { |
593 rtc::CritScope lock(&crit_); | 593 rtc::CritScope lock(&crit_); |
594 RTPHeader header; | 594 RTPHeader header; |
595 EXPECT_TRUE(parser_->Parse(packet, length, &header)); | 595 EXPECT_TRUE(parser_->Parse(packet, length, &header)); |
596 | 596 |
597 int encapsulated_payload_type = -1; | 597 int encapsulated_payload_type = -1; |
598 if (header.payloadType == kRedPayloadType) { | 598 if (header.payloadType == kRedPayloadType) { |
599 encapsulated_payload_type = | 599 encapsulated_payload_type = |
600 static_cast<int>(packet[header.headerLength]); | 600 static_cast<int>(packet[header.headerLength]); |
601 if (encapsulated_payload_type != kFakeVideoSendPayloadType) | 601 if (encapsulated_payload_type != kFakeVideoSendPayloadType) |
602 EXPECT_EQ(kUlpfecPayloadType, encapsulated_payload_type); | 602 EXPECT_EQ(kUlpfecPayloadType, encapsulated_payload_type); |
603 } else { | 603 } else { |
604 EXPECT_EQ(kFakeVideoSendPayloadType, header.payloadType); | 604 EXPECT_EQ(kFakeVideoSendPayloadType, header.payloadType); |
605 } | 605 } |
606 | 606 |
607 if (protected_sequence_numbers_.count(header.sequenceNumber) != 0) { | 607 if (protected_sequence_numbers_.count(header.sequenceNumber) != 0) { |
608 // Retransmitted packet, should not count. | 608 // Retransmitted packet, should not count. |
609 protected_sequence_numbers_.erase(header.sequenceNumber); | 609 protected_sequence_numbers_.erase(header.sequenceNumber); |
610 EXPECT_GT(protected_timestamps_.count(header.timestamp), 0u); | 610 EXPECT_GT(protected_timestamps_.count(header.timestamp), 0u); |
611 protected_timestamps_.erase(header.timestamp); | 611 protected_timestamps_.erase(header.timestamp); |
612 return SEND_PACKET; | 612 return SEND_PACKET; |
613 } | 613 } |
614 | 614 |
615 switch (state_) { | 615 switch (state_) { |
616 case kFirstPacket: | 616 case kFirstPacket: |
617 state_ = kDropEveryOtherPacketUntilFec; | 617 state_ = kDropEveryOtherPacketUntilUlpfec; |
618 break; | 618 break; |
619 case kDropEveryOtherPacketUntilFec: | 619 case kDropEveryOtherPacketUntilUlpfec: |
620 if (encapsulated_payload_type == kUlpfecPayloadType) { | 620 if (encapsulated_payload_type == kUlpfecPayloadType) { |
621 state_ = kDropNextMediaPacket; | 621 state_ = kDropNextMediaPacket; |
622 return SEND_PACKET; | 622 return SEND_PACKET; |
623 } | 623 } |
624 if (header.sequenceNumber % 2 == 0) | 624 if (header.sequenceNumber % 2 == 0) |
625 return DROP_PACKET; | 625 return DROP_PACKET; |
626 break; | 626 break; |
627 case kDropNextMediaPacket: | 627 case kDropNextMediaPacket: |
628 if (encapsulated_payload_type == kFakeVideoSendPayloadType) { | 628 if (encapsulated_payload_type == kFakeVideoSendPayloadType) { |
629 protected_sequence_numbers_.insert(header.sequenceNumber); | 629 protected_sequence_numbers_.insert(header.sequenceNumber); |
630 protected_timestamps_.insert(header.timestamp); | 630 protected_timestamps_.insert(header.timestamp); |
631 state_ = kDropEveryOtherPacketUntilFec; | 631 state_ = kDropEveryOtherPacketUntilUlpfec; |
632 return DROP_PACKET; | 632 return DROP_PACKET; |
633 } | 633 } |
634 break; | 634 break; |
635 } | 635 } |
636 | 636 |
637 return SEND_PACKET; | 637 return SEND_PACKET; |
638 } | 638 } |
639 | 639 |
640 void OnFrame(const VideoFrame& video_frame) override { | 640 void OnFrame(const VideoFrame& video_frame) override { |
641 rtc::CritScope lock(&crit_); | 641 rtc::CritScope lock(&crit_); |
642 // Rendering frame with timestamp of packet that was dropped -> FEC | 642 // Rendering frame with timestamp of packet that was dropped -> FEC |
643 // protection worked. | 643 // protection worked. |
644 if (protected_timestamps_.count(video_frame.timestamp()) != 0) | 644 if (protected_timestamps_.count(video_frame.timestamp()) != 0) |
645 observation_complete_.Set(); | 645 observation_complete_.Set(); |
646 } | 646 } |
647 | 647 |
648 enum { | 648 enum { |
649 kFirstPacket, | 649 kFirstPacket, |
650 kDropEveryOtherPacketUntilFec, | 650 kDropEveryOtherPacketUntilUlpfec, |
651 kDropNextMediaPacket, | 651 kDropNextMediaPacket, |
652 } state_; | 652 } state_; |
653 | 653 |
654 void ModifyVideoConfigs( | 654 void ModifyVideoConfigs( |
655 VideoSendStream::Config* send_config, | 655 VideoSendStream::Config* send_config, |
656 std::vector<VideoReceiveStream::Config>* receive_configs, | 656 std::vector<VideoReceiveStream::Config>* receive_configs, |
657 VideoEncoderConfig* encoder_config) override { | 657 VideoEncoderConfig* encoder_config) override { |
658 // TODO(pbos): Run this test with combined NACK/FEC enabled as well. | 658 // TODO(pbos): Run this test with combined NACK/ULPFEC enabled as well. |
659 // int rtp_history_ms = 1000; | 659 // int rtp_history_ms = 1000; |
660 // (*receive_configs)[0].rtp.nack.rtp_history_ms = rtp_history_ms; | 660 // (*receive_configs)[0].rtp.nack.rtp_history_ms = rtp_history_ms; |
661 // send_config->rtp.nack.rtp_history_ms = rtp_history_ms; | 661 // send_config->rtp.nack.rtp_history_ms = rtp_history_ms; |
662 send_config->rtp.ulpfec.red_payload_type = kRedPayloadType; | 662 send_config->rtp.ulpfec.red_payload_type = kRedPayloadType; |
663 send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType; | 663 send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType; |
664 | 664 |
665 (*receive_configs)[0].rtp.ulpfec.red_payload_type = kRedPayloadType; | 665 (*receive_configs)[0].rtp.ulpfec.red_payload_type = kRedPayloadType; |
666 (*receive_configs)[0].rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType; | 666 (*receive_configs)[0].rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType; |
667 (*receive_configs)[0].renderer = this; | 667 (*receive_configs)[0].renderer = this; |
668 } | 668 } |
669 | 669 |
670 void PerformTest() override { | 670 void PerformTest() override { |
671 EXPECT_TRUE(Wait()) | 671 EXPECT_TRUE(Wait()) |
672 << "Timed out waiting for dropped frames frames to be rendered."; | 672 << "Timed out waiting for dropped frames frames to be rendered."; |
673 } | 673 } |
674 | 674 |
675 rtc::CriticalSection crit_; | 675 rtc::CriticalSection crit_; |
676 std::set<uint32_t> protected_sequence_numbers_ GUARDED_BY(crit_); | 676 std::set<uint32_t> protected_sequence_numbers_ GUARDED_BY(crit_); |
677 std::set<uint32_t> protected_timestamps_ GUARDED_BY(crit_); | 677 std::set<uint32_t> protected_timestamps_ GUARDED_BY(crit_); |
678 } test; | 678 } test; |
679 | 679 |
680 RunBaseTest(&test); | 680 RunBaseTest(&test); |
681 } | 681 } |
682 | 682 |
683 TEST_F(EndToEndTest, ReceivedFecPacketsNotNacked) { | 683 TEST_F(EndToEndTest, ReceivedUlpfecPacketsNotNacked) { |
684 class FecNackObserver : public test::EndToEndTest { | 684 class UlpfecNackObserver : public test::EndToEndTest { |
685 public: | 685 public: |
686 FecNackObserver() | 686 UlpfecNackObserver() |
687 : EndToEndTest(kDefaultTimeoutMs), | 687 : EndToEndTest(kDefaultTimeoutMs), |
688 state_(kFirstPacket), | 688 state_(kFirstPacket), |
689 fec_sequence_number_(0), | 689 ulpfec_sequence_number_(0), |
690 has_last_sequence_number_(false), | 690 has_last_sequence_number_(false), |
691 last_sequence_number_(0), | 691 last_sequence_number_(0), |
692 encoder_(VideoEncoder::Create(VideoEncoder::EncoderType::kVp8)), | 692 encoder_(VideoEncoder::Create(VideoEncoder::EncoderType::kVp8)), |
693 decoder_(VP8Decoder::Create()) {} | 693 decoder_(VP8Decoder::Create()) {} |
694 | 694 |
695 private: | 695 private: |
696 Action OnSendRtp(const uint8_t* packet, size_t length) override { | 696 Action OnSendRtp(const uint8_t* packet, size_t length) override { |
697 rtc::CritScope lock_(&crit_); | 697 rtc::CritScope lock_(&crit_); |
698 RTPHeader header; | 698 RTPHeader header; |
699 EXPECT_TRUE(parser_->Parse(packet, length, &header)); | 699 EXPECT_TRUE(parser_->Parse(packet, length, &header)); |
(...skipping 10 matching lines...) Expand all Loading... |
710 | 710 |
711 if (has_last_sequence_number_ && | 711 if (has_last_sequence_number_ && |
712 !IsNewerSequenceNumber(header.sequenceNumber, | 712 !IsNewerSequenceNumber(header.sequenceNumber, |
713 last_sequence_number_)) { | 713 last_sequence_number_)) { |
714 // Drop retransmitted packets. | 714 // Drop retransmitted packets. |
715 return DROP_PACKET; | 715 return DROP_PACKET; |
716 } | 716 } |
717 last_sequence_number_ = header.sequenceNumber; | 717 last_sequence_number_ = header.sequenceNumber; |
718 has_last_sequence_number_ = true; | 718 has_last_sequence_number_ = true; |
719 | 719 |
720 bool fec_packet = encapsulated_payload_type == kUlpfecPayloadType; | 720 bool ulpfec_packet = encapsulated_payload_type == kUlpfecPayloadType; |
721 switch (state_) { | 721 switch (state_) { |
722 case kFirstPacket: | 722 case kFirstPacket: |
723 state_ = kDropEveryOtherPacketUntilFec; | 723 state_ = kDropEveryOtherPacketUntilUlpfec; |
724 break; | 724 break; |
725 case kDropEveryOtherPacketUntilFec: | 725 case kDropEveryOtherPacketUntilUlpfec: |
726 if (fec_packet) { | 726 if (ulpfec_packet) { |
727 state_ = kDropAllMediaPacketsUntilFec; | 727 state_ = kDropAllMediaPacketsUntilUlpfec; |
728 } else if (header.sequenceNumber % 2 == 0) { | 728 } else if (header.sequenceNumber % 2 == 0) { |
729 return DROP_PACKET; | 729 return DROP_PACKET; |
730 } | 730 } |
731 break; | 731 break; |
732 case kDropAllMediaPacketsUntilFec: | 732 case kDropAllMediaPacketsUntilUlpfec: |
733 if (!fec_packet) | 733 if (!ulpfec_packet) |
734 return DROP_PACKET; | 734 return DROP_PACKET; |
735 fec_sequence_number_ = header.sequenceNumber; | 735 ulpfec_sequence_number_ = header.sequenceNumber; |
736 state_ = kDropOneMediaPacket; | 736 state_ = kDropOneMediaPacket; |
737 break; | 737 break; |
738 case kDropOneMediaPacket: | 738 case kDropOneMediaPacket: |
739 if (fec_packet) | 739 if (ulpfec_packet) |
740 return DROP_PACKET; | 740 return DROP_PACKET; |
741 state_ = kPassOneMediaPacket; | 741 state_ = kPassOneMediaPacket; |
742 return DROP_PACKET; | 742 return DROP_PACKET; |
743 break; | 743 break; |
744 case kPassOneMediaPacket: | 744 case kPassOneMediaPacket: |
745 if (fec_packet) | 745 if (ulpfec_packet) |
746 return DROP_PACKET; | 746 return DROP_PACKET; |
747 // Pass one media packet after dropped packet after last FEC, | 747 // Pass one media packet after dropped packet after last FEC, |
748 // otherwise receiver might never see a seq_no after | 748 // otherwise receiver might never see a seq_no after |
749 // |fec_sequence_number_| | 749 // |ulpfec_sequence_number_| |
750 state_ = kVerifyFecPacketNotInNackList; | 750 state_ = kVerifyUlpfecPacketNotInNackList; |
751 break; | 751 break; |
752 case kVerifyFecPacketNotInNackList: | 752 case kVerifyUlpfecPacketNotInNackList: |
753 // Continue to drop packets. Make sure no frame can be decoded. | 753 // Continue to drop packets. Make sure no frame can be decoded. |
754 if (fec_packet || header.sequenceNumber % 2 == 0) | 754 if (ulpfec_packet || header.sequenceNumber % 2 == 0) |
755 return DROP_PACKET; | 755 return DROP_PACKET; |
756 break; | 756 break; |
757 } | 757 } |
758 return SEND_PACKET; | 758 return SEND_PACKET; |
759 } | 759 } |
760 | 760 |
761 Action OnReceiveRtcp(const uint8_t* packet, size_t length) override { | 761 Action OnReceiveRtcp(const uint8_t* packet, size_t length) override { |
762 rtc::CritScope lock_(&crit_); | 762 rtc::CritScope lock_(&crit_); |
763 if (state_ == kVerifyFecPacketNotInNackList) { | 763 if (state_ == kVerifyUlpfecPacketNotInNackList) { |
764 test::RtcpPacketParser rtcp_parser; | 764 test::RtcpPacketParser rtcp_parser; |
765 rtcp_parser.Parse(packet, length); | 765 rtcp_parser.Parse(packet, length); |
766 const std::vector<uint16_t>& nacks = rtcp_parser.nack()->packet_ids(); | 766 const std::vector<uint16_t>& nacks = rtcp_parser.nack()->packet_ids(); |
767 EXPECT_TRUE(std::find(nacks.begin(), nacks.end(), | 767 EXPECT_TRUE(std::find(nacks.begin(), nacks.end(), |
768 fec_sequence_number_) == nacks.end()) | 768 ulpfec_sequence_number_) == nacks.end()) |
769 << "Got nack for FEC packet"; | 769 << "Got nack for ULPFEC packet"; |
770 if (!nacks.empty() && | 770 if (!nacks.empty() && |
771 IsNewerSequenceNumber(nacks.back(), fec_sequence_number_)) { | 771 IsNewerSequenceNumber(nacks.back(), ulpfec_sequence_number_)) { |
772 observation_complete_.Set(); | 772 observation_complete_.Set(); |
773 } | 773 } |
774 } | 774 } |
775 return SEND_PACKET; | 775 return SEND_PACKET; |
776 } | 776 } |
777 | 777 |
778 test::PacketTransport* CreateSendTransport(Call* sender_call) override { | 778 test::PacketTransport* CreateSendTransport(Call* sender_call) override { |
779 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC. | 779 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC. |
780 // Configure some network delay. | 780 // Configure some network delay. |
781 const int kNetworkDelayMs = 50; | 781 const int kNetworkDelayMs = 50; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
819 (*receive_configs)[0].decoders[0].decoder = decoder_.get(); | 819 (*receive_configs)[0].decoders[0].decoder = decoder_.get(); |
820 } | 820 } |
821 | 821 |
822 void PerformTest() override { | 822 void PerformTest() override { |
823 EXPECT_TRUE(Wait()) | 823 EXPECT_TRUE(Wait()) |
824 << "Timed out while waiting for FEC packets to be received."; | 824 << "Timed out while waiting for FEC packets to be received."; |
825 } | 825 } |
826 | 826 |
827 enum { | 827 enum { |
828 kFirstPacket, | 828 kFirstPacket, |
829 kDropEveryOtherPacketUntilFec, | 829 kDropEveryOtherPacketUntilUlpfec, |
830 kDropAllMediaPacketsUntilFec, | 830 kDropAllMediaPacketsUntilUlpfec, |
831 kDropOneMediaPacket, | 831 kDropOneMediaPacket, |
832 kPassOneMediaPacket, | 832 kPassOneMediaPacket, |
833 kVerifyFecPacketNotInNackList, | 833 kVerifyUlpfecPacketNotInNackList, |
834 } state_; | 834 } state_; |
835 | 835 |
836 rtc::CriticalSection crit_; | 836 rtc::CriticalSection crit_; |
837 uint16_t fec_sequence_number_ GUARDED_BY(&crit_); | 837 uint16_t ulpfec_sequence_number_ GUARDED_BY(&crit_); |
838 bool has_last_sequence_number_; | 838 bool has_last_sequence_number_; |
839 uint16_t last_sequence_number_; | 839 uint16_t last_sequence_number_; |
840 std::unique_ptr<webrtc::VideoEncoder> encoder_; | 840 std::unique_ptr<webrtc::VideoEncoder> encoder_; |
841 std::unique_ptr<webrtc::VideoDecoder> decoder_; | 841 std::unique_ptr<webrtc::VideoDecoder> decoder_; |
842 } test; | 842 } test; |
843 | 843 |
844 RunBaseTest(&test); | 844 RunBaseTest(&test); |
845 } | 845 } |
846 | 846 |
847 // This test drops second RTP packet with a marker bit set, makes sure it's | 847 // This test drops second RTP packet with a marker bit set, makes sure it's |
(...skipping 2902 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3750 VerifyNewVideoReceiveStreamsRespectNetworkState(MediaType::AUDIO, &transport); | 3750 VerifyNewVideoReceiveStreamsRespectNetworkState(MediaType::AUDIO, &transport); |
3751 } | 3751 } |
3752 | 3752 |
3753 void VerifyEmptyNackConfig(const NackConfig& config) { | 3753 void VerifyEmptyNackConfig(const NackConfig& config) { |
3754 EXPECT_EQ(0, config.rtp_history_ms) | 3754 EXPECT_EQ(0, config.rtp_history_ms) |
3755 << "Enabling NACK requires rtcp-fb: nack negotiation."; | 3755 << "Enabling NACK requires rtcp-fb: nack negotiation."; |
3756 } | 3756 } |
3757 | 3757 |
3758 void VerifyEmptyUlpfecConfig(const UlpfecConfig& config) { | 3758 void VerifyEmptyUlpfecConfig(const UlpfecConfig& config) { |
3759 EXPECT_EQ(-1, config.ulpfec_payload_type) | 3759 EXPECT_EQ(-1, config.ulpfec_payload_type) |
3760 << "Enabling FEC requires rtpmap: ulpfec negotiation."; | 3760 << "Enabling ULPFEC requires rtpmap: ulpfec negotiation."; |
3761 EXPECT_EQ(-1, config.red_payload_type) | 3761 EXPECT_EQ(-1, config.red_payload_type) |
3762 << "Enabling FEC requires rtpmap: red negotiation."; | 3762 << "Enabling ULPFEC requires rtpmap: red negotiation."; |
3763 EXPECT_EQ(-1, config.red_rtx_payload_type) | 3763 EXPECT_EQ(-1, config.red_rtx_payload_type) |
3764 << "Enabling RTX in FEC requires rtpmap: rtx negotiation."; | 3764 << "Enabling RTX in ULPFEC requires rtpmap: rtx negotiation."; |
3765 } | 3765 } |
3766 | 3766 |
3767 TEST_F(EndToEndTest, VerifyDefaultSendConfigParameters) { | 3767 TEST_F(EndToEndTest, VerifyDefaultSendConfigParameters) { |
3768 VideoSendStream::Config default_send_config(nullptr); | 3768 VideoSendStream::Config default_send_config(nullptr); |
3769 EXPECT_EQ(0, default_send_config.rtp.nack.rtp_history_ms) | 3769 EXPECT_EQ(0, default_send_config.rtp.nack.rtp_history_ms) |
3770 << "Enabling NACK require rtcp-fb: nack negotiation."; | 3770 << "Enabling NACK require rtcp-fb: nack negotiation."; |
3771 EXPECT_TRUE(default_send_config.rtp.rtx.ssrcs.empty()) | 3771 EXPECT_TRUE(default_send_config.rtp.rtx.ssrcs.empty()) |
3772 << "Enabling RTX requires rtpmap: rtx negotiation."; | 3772 << "Enabling RTX requires rtpmap: rtx negotiation."; |
3773 EXPECT_TRUE(default_send_config.rtp.extensions.empty()) | 3773 EXPECT_TRUE(default_send_config.rtp.extensions.empty()) |
3774 << "Enabling RTP extensions require negotiation."; | 3774 << "Enabling RTP extensions require negotiation."; |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3962 std::unique_ptr<VideoEncoder> encoder_; | 3962 std::unique_ptr<VideoEncoder> encoder_; |
3963 std::unique_ptr<VideoDecoder> decoder_; | 3963 std::unique_ptr<VideoDecoder> decoder_; |
3964 rtc::CriticalSection crit_; | 3964 rtc::CriticalSection crit_; |
3965 int recorded_frames_ GUARDED_BY(crit_); | 3965 int recorded_frames_ GUARDED_BY(crit_); |
3966 } test(this); | 3966 } test(this); |
3967 | 3967 |
3968 RunBaseTest(&test); | 3968 RunBaseTest(&test); |
3969 } | 3969 } |
3970 | 3970 |
3971 } // namespace webrtc | 3971 } // namespace webrtc |
OLD | NEW |