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 687 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
698 rtc::CriticalSection crit_; | 698 rtc::CriticalSection crit_; |
699 std::set<uint32_t> protected_sequence_numbers_ GUARDED_BY(crit_); | 699 std::set<uint32_t> protected_sequence_numbers_ GUARDED_BY(crit_); |
700 // Since several packets can have the same timestamp a multiset is used | 700 // Since several packets can have the same timestamp a multiset is used |
701 // instead of a set. | 701 // instead of a set. |
702 std::multiset<uint32_t> protected_timestamps_ GUARDED_BY(crit_); | 702 std::multiset<uint32_t> protected_timestamps_ GUARDED_BY(crit_); |
703 } test; | 703 } test; |
704 | 704 |
705 RunBaseTest(&test); | 705 RunBaseTest(&test); |
706 } | 706 } |
707 | 707 |
708 TEST_P(EndToEndTest, CanReceiveFlexfec) { | 708 class FlexfecRenderObserver : public test::EndToEndTest, |
709 class FlexfecRenderObserver : public test::EndToEndTest, | 709 public rtc::VideoSinkInterface<VideoFrame> { |
710 public rtc::VideoSinkInterface<VideoFrame> { | 710 public: |
711 public: | 711 static constexpr uint32_t kVideoLocalSsrc = 123; |
712 FlexfecRenderObserver() | 712 static constexpr uint32_t kFlexfecLocalSsrc = 456; |
713 : EndToEndTest(kDefaultTimeoutMs), random_(0xcafef00d1) {} | |
714 | 713 |
715 size_t GetNumFlexfecStreams() const override { return 1; } | 714 explicit FlexfecRenderObserver(bool expect_flexfec_rtcp) |
| 715 : test::EndToEndTest(test::CallTest::kDefaultTimeoutMs), |
| 716 expect_flexfec_rtcp_(expect_flexfec_rtcp), |
| 717 received_flexfec_rtcp_(false), |
| 718 random_(0xcafef00d1) {} |
716 | 719 |
717 private: | 720 size_t GetNumFlexfecStreams() const override { return 1; } |
718 Action OnSendRtp(const uint8_t* packet, size_t length) override { | |
719 rtc::CritScope lock(&crit_); | |
720 RTPHeader header; | |
721 EXPECT_TRUE(parser_->Parse(packet, length, &header)); | |
722 | 721 |
723 uint8_t payload_type = header.payloadType; | 722 private: |
724 if (payload_type != kFakeVideoSendPayloadType) { | 723 Action OnSendRtp(const uint8_t* packet, size_t length) override { |
725 EXPECT_EQ(kFlexfecPayloadType, payload_type); | 724 rtc::CritScope lock(&crit_); |
| 725 RTPHeader header; |
| 726 EXPECT_TRUE(parser_->Parse(packet, length, &header)); |
| 727 |
| 728 uint8_t payload_type = header.payloadType; |
| 729 if (payload_type != test::CallTest::kFakeVideoSendPayloadType) { |
| 730 EXPECT_EQ(test::CallTest::kFlexfecPayloadType, payload_type); |
| 731 } |
| 732 |
| 733 // Is this a retransmitted media packet? From the perspective of FEC, this |
| 734 // packet is then no longer dropped, so remove it from the list of |
| 735 // dropped packets. |
| 736 if (payload_type == test::CallTest::kFakeVideoSendPayloadType) { |
| 737 auto seq_num_it = dropped_sequence_numbers_.find(header.sequenceNumber); |
| 738 if (seq_num_it != dropped_sequence_numbers_.end()) { |
| 739 dropped_sequence_numbers_.erase(seq_num_it); |
| 740 auto ts_it = dropped_timestamps_.find(header.timestamp); |
| 741 EXPECT_NE(ts_it, dropped_timestamps_.end()); |
| 742 dropped_timestamps_.erase(ts_it); |
| 743 |
| 744 return SEND_PACKET; |
| 745 } |
| 746 } |
| 747 |
| 748 // Simulate 5% packet loss. Record what media packets, and corresponding |
| 749 // timestamps, that were dropped. |
| 750 if (random_.Rand(1, 100) <= 5) { |
| 751 if (payload_type == test::CallTest::kFakeVideoSendPayloadType) { |
| 752 dropped_sequence_numbers_.insert(header.sequenceNumber); |
| 753 dropped_timestamps_.insert(header.timestamp); |
726 } | 754 } |
727 | 755 |
728 // Is this a retransmitted media packet? From the perspective of FEC, this | 756 return DROP_PACKET; |
729 // packet is then no longer dropped, so remove it from the list of | |
730 // dropped packets. | |
731 if (payload_type == kFakeVideoSendPayloadType) { | |
732 auto seq_num_it = dropped_sequence_numbers_.find(header.sequenceNumber); | |
733 if (seq_num_it != dropped_sequence_numbers_.end()) { | |
734 dropped_sequence_numbers_.erase(seq_num_it); | |
735 auto ts_it = dropped_timestamps_.find(header.timestamp); | |
736 EXPECT_NE(ts_it, dropped_timestamps_.end()); | |
737 dropped_timestamps_.erase(ts_it); | |
738 | |
739 return SEND_PACKET; | |
740 } | |
741 } | |
742 | |
743 // Simulate 5% packet loss. Record what media packets, and corresponding | |
744 // timestamps, that were dropped. | |
745 if (random_.Rand(1, 100) <= 5) { | |
746 if (payload_type == kFakeVideoSendPayloadType) { | |
747 dropped_sequence_numbers_.insert(header.sequenceNumber); | |
748 dropped_timestamps_.insert(header.timestamp); | |
749 } | |
750 | |
751 return DROP_PACKET; | |
752 } | |
753 | |
754 return SEND_PACKET; | |
755 } | 757 } |
756 | 758 |
757 void OnFrame(const VideoFrame& video_frame) override { | 759 return SEND_PACKET; |
758 rtc::CritScope lock(&crit_); | 760 } |
759 // Rendering frame with timestamp of packet that was dropped -> FEC | 761 |
760 // protection worked. | 762 Action OnReceiveRtcp(const uint8_t* data, size_t length) override { |
761 auto it = dropped_timestamps_.find(video_frame.timestamp()); | 763 test::RtcpPacketParser parser; |
762 if (it != dropped_timestamps_.end()) | 764 |
763 observation_complete_.Set(); | 765 parser.Parse(data, length); |
| 766 if (parser.sender_ssrc() == kFlexfecLocalSsrc) { |
| 767 EXPECT_EQ(1, parser.receiver_report()->num_packets()); |
| 768 const std::vector<rtcp::ReportBlock>& report_blocks = |
| 769 parser.receiver_report()->report_blocks(); |
| 770 if (!report_blocks.empty()) { |
| 771 EXPECT_EQ(1U, report_blocks.size()); |
| 772 EXPECT_EQ(test::CallTest::kFlexfecSendSsrc, |
| 773 report_blocks[0].source_ssrc()); |
| 774 received_flexfec_rtcp_ = true; |
| 775 } |
764 } | 776 } |
765 | 777 |
766 void ModifyVideoConfigs( | 778 return SEND_PACKET; |
767 VideoSendStream::Config* send_config, | 779 } |
768 std::vector<VideoReceiveStream::Config>* receive_configs, | 780 |
769 VideoEncoderConfig* encoder_config) override { | 781 void OnFrame(const VideoFrame& video_frame) override { |
770 (*receive_configs)[0].renderer = this; | 782 rtc::CritScope lock(&crit_); |
| 783 // Rendering frame with timestamp of packet that was dropped -> FEC |
| 784 // protection worked. |
| 785 auto it = dropped_timestamps_.find(video_frame.timestamp()); |
| 786 if (it != dropped_timestamps_.end()) { |
| 787 if (!expect_flexfec_rtcp_ || received_flexfec_rtcp_) { |
| 788 observation_complete_.Set(); |
| 789 } |
771 } | 790 } |
| 791 } |
772 | 792 |
773 void PerformTest() override { | 793 void ModifyVideoConfigs( |
774 EXPECT_TRUE(Wait()) | 794 VideoSendStream::Config* send_config, |
775 << "Timed out waiting for dropped frames to be rendered."; | 795 std::vector<VideoReceiveStream::Config>* receive_configs, |
776 } | 796 VideoEncoderConfig* encoder_config) override { |
| 797 (*receive_configs)[0].rtp.local_ssrc = kVideoLocalSsrc; |
| 798 (*receive_configs)[0].renderer = this; |
| 799 } |
777 | 800 |
778 rtc::CriticalSection crit_; | 801 void ModifyFlexfecConfigs( |
779 std::set<uint32_t> dropped_sequence_numbers_ GUARDED_BY(crit_); | 802 std::vector<FlexfecReceiveStream::Config>* receive_configs) override { |
780 // Since several packets can have the same timestamp a multiset is used | 803 (*receive_configs)[0].local_ssrc = kFlexfecLocalSsrc; |
781 // instead of a set. | 804 } |
782 std::multiset<uint32_t> dropped_timestamps_ GUARDED_BY(crit_); | |
783 Random random_; | |
784 } test; | |
785 | 805 |
| 806 void PerformTest() override { |
| 807 EXPECT_TRUE(Wait()) |
| 808 << "Timed out waiting for dropped frames to be rendered."; |
| 809 } |
| 810 |
| 811 rtc::CriticalSection crit_; |
| 812 std::set<uint32_t> dropped_sequence_numbers_ GUARDED_BY(crit_); |
| 813 // Since several packets can have the same timestamp a multiset is used |
| 814 // instead of a set. |
| 815 std::multiset<uint32_t> dropped_timestamps_ GUARDED_BY(crit_); |
| 816 bool expect_flexfec_rtcp_; |
| 817 bool received_flexfec_rtcp_; |
| 818 Random random_; |
| 819 }; |
| 820 |
| 821 TEST_P(EndToEndTest, ReceivesFlexfec) { |
| 822 FlexfecRenderObserver test(false); |
786 RunBaseTest(&test); | 823 RunBaseTest(&test); |
787 } | 824 } |
788 | 825 |
| 826 TEST_P(EndToEndTest, ReceivesFlexfecAndSendsCorrespondingRtcp) { |
| 827 FlexfecRenderObserver test(true); |
| 828 RunBaseTest(&test); |
| 829 } |
| 830 |
789 TEST_P(EndToEndTest, ReceivedUlpfecPacketsNotNacked) { | 831 TEST_P(EndToEndTest, ReceivedUlpfecPacketsNotNacked) { |
790 class UlpfecNackObserver : public test::EndToEndTest { | 832 class UlpfecNackObserver : public test::EndToEndTest { |
791 public: | 833 public: |
792 UlpfecNackObserver() | 834 UlpfecNackObserver() |
793 : EndToEndTest(kDefaultTimeoutMs), | 835 : EndToEndTest(kDefaultTimeoutMs), |
794 state_(kFirstPacket), | 836 state_(kFirstPacket), |
795 ulpfec_sequence_number_(0), | 837 ulpfec_sequence_number_(0), |
796 has_last_sequence_number_(false), | 838 has_last_sequence_number_(false), |
797 last_sequence_number_(0), | 839 last_sequence_number_(0), |
798 encoder_(VP8Encoder::Create()), | 840 encoder_(VP8Encoder::Create()), |
(...skipping 3285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4084 std::unique_ptr<VideoEncoder> encoder_; | 4126 std::unique_ptr<VideoEncoder> encoder_; |
4085 std::unique_ptr<VideoDecoder> decoder_; | 4127 std::unique_ptr<VideoDecoder> decoder_; |
4086 rtc::CriticalSection crit_; | 4128 rtc::CriticalSection crit_; |
4087 int recorded_frames_ GUARDED_BY(crit_); | 4129 int recorded_frames_ GUARDED_BY(crit_); |
4088 } test(this); | 4130 } test(this); |
4089 | 4131 |
4090 RunBaseTest(&test); | 4132 RunBaseTest(&test); |
4091 } | 4133 } |
4092 | 4134 |
4093 } // namespace webrtc | 4135 } // namespace webrtc |
OLD | NEW |