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 686 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
697 rtc::CriticalSection crit_; | 697 rtc::CriticalSection crit_; |
698 std::set<uint32_t> protected_sequence_numbers_ GUARDED_BY(crit_); | 698 std::set<uint32_t> protected_sequence_numbers_ GUARDED_BY(crit_); |
699 // Since several packets can have the same timestamp a multiset is used | 699 // Since several packets can have the same timestamp a multiset is used |
700 // instead of a set. | 700 // instead of a set. |
701 std::multiset<uint32_t> protected_timestamps_ GUARDED_BY(crit_); | 701 std::multiset<uint32_t> protected_timestamps_ GUARDED_BY(crit_); |
702 } test; | 702 } test; |
703 | 703 |
704 RunBaseTest(&test); | 704 RunBaseTest(&test); |
705 } | 705 } |
706 | 706 |
707 TEST_P(EndToEndTest, CanReceiveFlexfec) { | 707 class FlexfecRenderObserver : public test::EndToEndTest, |
708 class FlexfecRenderObserver : public test::EndToEndTest, | 708 public rtc::VideoSinkInterface<VideoFrame> { |
709 public rtc::VideoSinkInterface<VideoFrame> { | 709 public: |
710 public: | 710 static constexpr uint32_t kVideoLocalSsrc = 123; |
711 FlexfecRenderObserver() | 711 static constexpr uint32_t kFlexfecLocalSsrc = 456; |
712 : EndToEndTest(kDefaultTimeoutMs), random_(0xcafef00d1) {} | |
713 | 712 |
714 size_t GetNumFlexfecStreams() const override { return 1; } | 713 explicit FlexfecRenderObserver(bool expect_flexfec_rtcp) |
714 : test::EndToEndTest(test::CallTest::kDefaultTimeoutMs), | |
715 expect_flexfec_rtcp_(expect_flexfec_rtcp), | |
716 received_flexfec_rtcp_(false), | |
717 random_(0xcafef00d1) {} | |
715 | 718 |
716 private: | 719 size_t GetNumFlexfecStreams() const override { return 1; } |
717 Action OnSendRtp(const uint8_t* packet, size_t length) override { | |
718 rtc::CritScope lock(&crit_); | |
719 RTPHeader header; | |
720 EXPECT_TRUE(parser_->Parse(packet, length, &header)); | |
721 | 720 |
722 uint8_t payload_type = header.payloadType; | 721 private: |
723 if (payload_type != kFakeVideoSendPayloadType) { | 722 Action OnSendRtp(const uint8_t* packet, size_t length) override { |
724 EXPECT_EQ(kFlexfecPayloadType, payload_type); | 723 rtc::CritScope lock(&crit_); |
724 RTPHeader header; | |
725 EXPECT_TRUE(parser_->Parse(packet, length, &header)); | |
726 | |
727 uint8_t payload_type = header.payloadType; | |
728 if (payload_type != test::CallTest::kFakeVideoSendPayloadType) { | |
729 EXPECT_EQ(test::CallTest::kFlexfecPayloadType, payload_type); | |
730 } | |
731 | |
732 // Is this a retransmitted media packet? From the perspective of FEC, this | |
733 // packet is then no longer dropped, so remove it from the list of | |
734 // dropped packets. | |
735 if (payload_type == test::CallTest::kFakeVideoSendPayloadType) { | |
736 auto seq_num_it = dropped_sequence_numbers_.find(header.sequenceNumber); | |
737 if (seq_num_it != dropped_sequence_numbers_.end()) { | |
738 dropped_sequence_numbers_.erase(seq_num_it); | |
739 auto ts_it = dropped_timestamps_.find(header.timestamp); | |
740 EXPECT_NE(ts_it, dropped_timestamps_.end()); | |
741 dropped_timestamps_.erase(ts_it); | |
742 | |
743 return SEND_PACKET; | |
744 } | |
745 } | |
746 | |
747 // Simulate 5% packet loss. Record what media packets, and corresponding | |
748 // timestamps, that were dropped. | |
749 if (random_.Rand(1, 100) <= 5) { | |
750 if (payload_type == test::CallTest::kFakeVideoSendPayloadType) { | |
751 dropped_sequence_numbers_.insert(header.sequenceNumber); | |
752 dropped_timestamps_.insert(header.timestamp); | |
725 } | 753 } |
726 | 754 |
727 // Is this a retransmitted media packet? From the perspective of FEC, this | 755 return DROP_PACKET; |
728 // packet is then no longer dropped, so remove it from the list of | |
729 // dropped packets. | |
730 if (payload_type == kFakeVideoSendPayloadType) { | |
731 auto seq_num_it = dropped_sequence_numbers_.find(header.sequenceNumber); | |
732 if (seq_num_it != dropped_sequence_numbers_.end()) { | |
733 dropped_sequence_numbers_.erase(seq_num_it); | |
734 auto ts_it = dropped_timestamps_.find(header.timestamp); | |
735 EXPECT_NE(ts_it, dropped_timestamps_.end()); | |
736 dropped_timestamps_.erase(ts_it); | |
737 | |
738 return SEND_PACKET; | |
739 } | |
740 } | |
741 | |
742 // Simulate 5% packet loss. Record what media packets, and corresponding | |
743 // timestamps, that were dropped. | |
744 if (random_.Rand(1, 100) <= 5) { | |
745 if (payload_type == kFakeVideoSendPayloadType) { | |
746 dropped_sequence_numbers_.insert(header.sequenceNumber); | |
747 dropped_timestamps_.insert(header.timestamp); | |
748 } | |
749 | |
750 return DROP_PACKET; | |
751 } | |
752 | |
753 return SEND_PACKET; | |
754 } | 756 } |
755 | 757 |
756 void OnFrame(const VideoFrame& video_frame) override { | 758 return SEND_PACKET; |
757 rtc::CritScope lock(&crit_); | 759 } |
758 // Rendering frame with timestamp of packet that was dropped -> FEC | 760 |
759 // protection worked. | 761 Action OnReceiveRtcp(const uint8_t* data, size_t length) override { |
760 auto it = dropped_timestamps_.find(video_frame.timestamp()); | 762 test::RtcpPacketParser parser; |
761 if (it != dropped_timestamps_.end()) | 763 |
762 observation_complete_.Set(); | 764 parser.Parse(data, length); |
765 if (parser.sender_ssrc() == kFlexfecLocalSsrc) { | |
766 received_flexfec_rtcp_ = true; | |
danilchap
2017/01/11 12:13:07
probably set to true only if (!report_blocks.empty
brandtr
2017/01/11 12:25:36
Yes, this is better, as it requires the EXPECTs be
| |
767 | |
768 EXPECT_EQ(1, parser.receiver_report()->num_packets()); | |
769 const std::vector<rtcp::ReportBlock>& report_blocks = | |
770 parser.receiver_report()->report_blocks(); | |
771 if (!report_blocks.empty()) { | |
brandtr
2017/01/11 10:47:52
This check is needed because the newly created RTP
danilchap
2017/01/11 12:13:07
should be correct, not so sure if reasonable.
quo
brandtr
2017/01/11 12:25:36
Acknowledged.
| |
772 EXPECT_EQ(1U, report_blocks.size()); | |
773 EXPECT_EQ(test::CallTest::kFlexfecSendSsrc, | |
774 report_blocks[0].source_ssrc()); | |
775 } | |
763 } | 776 } |
764 | 777 |
765 void ModifyVideoConfigs( | 778 return SEND_PACKET; |
766 VideoSendStream::Config* send_config, | 779 } |
767 std::vector<VideoReceiveStream::Config>* receive_configs, | 780 |
768 VideoEncoderConfig* encoder_config) override { | 781 void OnFrame(const VideoFrame& video_frame) override { |
769 (*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 } | |
770 } | 790 } |
791 } | |
771 | 792 |
772 void PerformTest() override { | 793 void ModifyVideoConfigs( |
773 EXPECT_TRUE(Wait()) | 794 VideoSendStream::Config* send_config, |
774 << "Timed out waiting for dropped frames to be rendered."; | 795 std::vector<VideoReceiveStream::Config>* receive_configs, |
775 } | 796 VideoEncoderConfig* encoder_config) override { |
797 (*receive_configs)[0].rtp.local_ssrc = kVideoLocalSsrc; | |
798 (*receive_configs)[0].renderer = this; | |
799 } | |
776 | 800 |
777 rtc::CriticalSection crit_; | 801 void ModifyFlexfecConfigs( |
778 std::set<uint32_t> dropped_sequence_numbers_ GUARDED_BY(crit_); | 802 std::vector<FlexfecReceiveStream::Config>* receive_configs) override { |
779 // Since several packets can have the same timestamp a multiset is used | 803 (*receive_configs)[0].local_ssrc = kFlexfecLocalSsrc; |
780 // instead of a set. | 804 } |
781 std::multiset<uint32_t> dropped_timestamps_ GUARDED_BY(crit_); | |
782 Random random_; | |
783 } test; | |
784 | 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); | |
785 RunBaseTest(&test); | 823 RunBaseTest(&test); |
786 } | 824 } |
787 | 825 |
826 TEST_P(EndToEndTest, ReceivesFlexfecAndSendsCorrespondingRtcp) { | |
827 FlexfecRenderObserver test(true); | |
828 RunBaseTest(&test); | |
829 } | |
830 | |
788 TEST_P(EndToEndTest, ReceivedUlpfecPacketsNotNacked) { | 831 TEST_P(EndToEndTest, ReceivedUlpfecPacketsNotNacked) { |
789 class UlpfecNackObserver : public test::EndToEndTest { | 832 class UlpfecNackObserver : public test::EndToEndTest { |
790 public: | 833 public: |
791 UlpfecNackObserver() | 834 UlpfecNackObserver() |
792 : EndToEndTest(kDefaultTimeoutMs), | 835 : EndToEndTest(kDefaultTimeoutMs), |
793 state_(kFirstPacket), | 836 state_(kFirstPacket), |
794 ulpfec_sequence_number_(0), | 837 ulpfec_sequence_number_(0), |
795 has_last_sequence_number_(false), | 838 has_last_sequence_number_(false), |
796 last_sequence_number_(0), | 839 last_sequence_number_(0), |
797 encoder_(VP8Encoder::Create()), | 840 encoder_(VP8Encoder::Create()), |
(...skipping 3267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4065 std::unique_ptr<VideoEncoder> encoder_; | 4108 std::unique_ptr<VideoEncoder> encoder_; |
4066 std::unique_ptr<VideoDecoder> decoder_; | 4109 std::unique_ptr<VideoDecoder> decoder_; |
4067 rtc::CriticalSection crit_; | 4110 rtc::CriticalSection crit_; |
4068 int recorded_frames_ GUARDED_BY(crit_); | 4111 int recorded_frames_ GUARDED_BY(crit_); |
4069 } test(this); | 4112 } test(this); |
4070 | 4113 |
4071 RunBaseTest(&test); | 4114 RunBaseTest(&test); |
4072 } | 4115 } |
4073 | 4116 |
4074 } // namespace webrtc | 4117 } // namespace webrtc |
OLD | NEW |