| 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 |