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 explicit FlexfecRenderObserver(bool expect_flexfec_rtcp) |
711 FlexfecRenderObserver() | 711 : test::EndToEndTest(test::CallTest::kDefaultTimeoutMs), |
712 : EndToEndTest(kDefaultTimeoutMs), random_(0xcafef00d1) {} | 712 expect_flexfec_rtcp_(expect_flexfec_rtcp), |
713 received_flexfec_rtcp_(false), | |
714 random_(0xcafef00d1) {} | |
713 | 715 |
714 size_t GetNumFlexfecStreams() const override { return 1; } | 716 size_t GetNumFlexfecStreams() const override { return 1; } |
715 | 717 |
716 private: | 718 static constexpr uint32_t kVideoLocalSsrc = 123; |
danilchap
2017/01/10 13:48:17
constants above constructors
brandtr
2017/01/11 09:55:24
Done.
| |
717 Action OnSendRtp(const uint8_t* packet, size_t length) override { | 719 static constexpr uint32_t kFlexfecLocalSsrc = 456; |
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 | 756 } |
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 | 757 |
738 return SEND_PACKET; | 758 return SEND_PACKET; |
739 } | 759 } |
740 } | |
741 | 760 |
742 // Simulate 5% packet loss. Record what media packets, and corresponding | 761 Action OnReceiveRtcp(const uint8_t* data, size_t length) override { |
brandtr
2017/01/10 11:57:52
This method is new.
| |
743 // timestamps, that were dropped. | 762 if (length < 32U) { |
744 if (random_.Rand(1, 100) <= 5) { | 763 // No report block, or truncated report block. |
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; | 764 return SEND_PACKET; |
754 } | 765 } |
755 | 766 |
756 void OnFrame(const VideoFrame& video_frame) override { | 767 uint32_t rtcp_sender_ssrc = ByteReader<uint32_t>::ReadBigEndian(&data[4]); |
danilchap
2017/01/10 13:48:17
avoid reimplmenting (simplifed) rtcp parser:
in te
brandtr
2017/01/11 09:55:24
Done. See below.
| |
757 rtc::CritScope lock(&crit_); | 768 if (rtcp_sender_ssrc == kFlexfecLocalSsrc) { |
758 // Rendering frame with timestamp of packet that was dropped -> FEC | 769 received_flexfec_rtcp_ = true; |
759 // protection worked. | 770 |
760 auto it = dropped_timestamps_.find(video_frame.timestamp()); | 771 uint8_t payload_type = data[1]; |
761 if (it != dropped_timestamps_.end()) | 772 EXPECT_EQ(201U, payload_type); // RTCP RR. |
773 uint32_t reported_ssrc = ByteReader<uint32_t>::ReadBigEndian(&data[8]); | |
danilchap
2017/01/10 13:48:17
test_parser->receiver_report()->report_blocks().fr
brandtr
2017/01/11 09:55:24
Hmm, OK. I did have a look at that class before wr
| |
774 EXPECT_EQ(test::CallTest::kFlexfecSendSsrc, reported_ssrc); | |
775 } | |
776 return SEND_PACKET; | |
777 } | |
778 | |
779 void OnFrame(const VideoFrame& video_frame) override { | |
780 rtc::CritScope lock(&crit_); | |
781 // Rendering frame with timestamp of packet that was dropped -> FEC | |
782 // protection worked. | |
783 auto it = dropped_timestamps_.find(video_frame.timestamp()); | |
784 if (it != dropped_timestamps_.end()) { | |
785 if (!expect_flexfec_rtcp_ || received_flexfec_rtcp_) { | |
762 observation_complete_.Set(); | 786 observation_complete_.Set(); |
787 } | |
763 } | 788 } |
789 } | |
764 | 790 |
765 void ModifyVideoConfigs( | 791 void ModifyVideoConfigs( |
766 VideoSendStream::Config* send_config, | 792 VideoSendStream::Config* send_config, |
767 std::vector<VideoReceiveStream::Config>* receive_configs, | 793 std::vector<VideoReceiveStream::Config>* receive_configs, |
768 VideoEncoderConfig* encoder_config) override { | 794 VideoEncoderConfig* encoder_config) override { |
769 (*receive_configs)[0].renderer = this; | 795 (*receive_configs)[0].rtp.local_ssrc = kVideoLocalSsrc; |
770 } | 796 (*receive_configs)[0].renderer = this; |
797 } | |
771 | 798 |
772 void PerformTest() override { | 799 void ModifyFlexfecConfigs( |
773 EXPECT_TRUE(Wait()) | 800 std::vector<FlexfecReceiveStream::Config>* receive_configs) override { |
774 << "Timed out waiting for dropped frames to be rendered."; | 801 (*receive_configs)[0].local_ssrc = kFlexfecLocalSsrc; |
775 } | 802 } |
776 | 803 |
777 rtc::CriticalSection crit_; | 804 void PerformTest() override { |
778 std::set<uint32_t> dropped_sequence_numbers_ GUARDED_BY(crit_); | 805 EXPECT_TRUE(Wait()) |
779 // Since several packets can have the same timestamp a multiset is used | 806 << "Timed out waiting for dropped frames to be rendered."; |
780 // instead of a set. | 807 } |
781 std::multiset<uint32_t> dropped_timestamps_ GUARDED_BY(crit_); | |
782 Random random_; | |
783 } test; | |
784 | 808 |
809 rtc::CriticalSection crit_; | |
810 std::set<uint32_t> dropped_sequence_numbers_ GUARDED_BY(crit_); | |
811 // Since several packets can have the same timestamp a multiset is used | |
812 // instead of a set. | |
813 std::multiset<uint32_t> dropped_timestamps_ GUARDED_BY(crit_); | |
814 bool expect_flexfec_rtcp_; | |
815 bool received_flexfec_rtcp_; | |
816 Random random_; | |
817 }; | |
818 | |
819 TEST_P(EndToEndTest, ReceivesFlexfec) { | |
820 FlexfecRenderObserver test(false); | |
785 RunBaseTest(&test); | 821 RunBaseTest(&test); |
786 } | 822 } |
787 | 823 |
824 TEST_P(EndToEndTest, ReceivesFlexfecAndSendsCorrespondingRtcp) { | |
825 FlexfecRenderObserver test(true); | |
826 RunBaseTest(&test); | |
827 } | |
828 | |
788 TEST_P(EndToEndTest, ReceivedUlpfecPacketsNotNacked) { | 829 TEST_P(EndToEndTest, ReceivedUlpfecPacketsNotNacked) { |
789 class UlpfecNackObserver : public test::EndToEndTest { | 830 class UlpfecNackObserver : public test::EndToEndTest { |
790 public: | 831 public: |
791 UlpfecNackObserver() | 832 UlpfecNackObserver() |
792 : EndToEndTest(kDefaultTimeoutMs), | 833 : EndToEndTest(kDefaultTimeoutMs), |
793 state_(kFirstPacket), | 834 state_(kFirstPacket), |
794 ulpfec_sequence_number_(0), | 835 ulpfec_sequence_number_(0), |
795 has_last_sequence_number_(false), | 836 has_last_sequence_number_(false), |
796 last_sequence_number_(0), | 837 last_sequence_number_(0), |
797 encoder_(VP8Encoder::Create()), | 838 encoder_(VP8Encoder::Create()), |
(...skipping 3267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4065 std::unique_ptr<VideoEncoder> encoder_; | 4106 std::unique_ptr<VideoEncoder> encoder_; |
4066 std::unique_ptr<VideoDecoder> decoder_; | 4107 std::unique_ptr<VideoDecoder> decoder_; |
4067 rtc::CriticalSection crit_; | 4108 rtc::CriticalSection crit_; |
4068 int recorded_frames_ GUARDED_BY(crit_); | 4109 int recorded_frames_ GUARDED_BY(crit_); |
4069 } test(this); | 4110 } test(this); |
4070 | 4111 |
4071 RunBaseTest(&test); | 4112 RunBaseTest(&test); |
4072 } | 4113 } |
4073 | 4114 |
4074 } // namespace webrtc | 4115 } // namespace webrtc |
OLD | NEW |