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 672 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
683 } test; | 683 } test; |
684 | 684 |
685 RunBaseTest(&test); | 685 RunBaseTest(&test); |
686 } | 686 } |
687 | 687 |
688 TEST_P(EndToEndTest, CanReceiveFlexfec) { | 688 TEST_P(EndToEndTest, CanReceiveFlexfec) { |
689 class FlexfecRenderObserver : public test::EndToEndTest, | 689 class FlexfecRenderObserver : public test::EndToEndTest, |
690 public rtc::VideoSinkInterface<VideoFrame> { | 690 public rtc::VideoSinkInterface<VideoFrame> { |
691 public: | 691 public: |
692 FlexfecRenderObserver() | 692 FlexfecRenderObserver() |
693 : EndToEndTest(kDefaultTimeoutMs), state_(kFirstPacket) {} | 693 : EndToEndTest(kDefaultTimeoutMs), random_(0xcafef00d) {} |
694 | 694 |
695 size_t GetNumFlexfecStreams() const override { return 1; } | 695 size_t GetNumFlexfecStreams() const override { return 1; } |
696 | 696 |
697 private: | 697 private: |
698 Action OnSendRtp(const uint8_t* packet, size_t length) override { | 698 Action OnSendRtp(const uint8_t* packet, size_t length) override { |
699 rtc::CritScope lock(&crit_); | 699 rtc::CritScope lock(&crit_); |
700 RTPHeader header; | 700 RTPHeader header; |
701 EXPECT_TRUE(parser_->Parse(packet, length, &header)); | 701 EXPECT_TRUE(parser_->Parse(packet, length, &header)); |
702 | 702 |
703 uint8_t payload_type = header.payloadType; | 703 uint8_t payload_type = header.payloadType; |
704 if (payload_type != kFakeVideoSendPayloadType) { | 704 if (payload_type != kFakeVideoSendPayloadType) { |
705 EXPECT_EQ(kFlexfecPayloadType, payload_type); | 705 EXPECT_EQ(kFlexfecPayloadType, payload_type); |
706 } | 706 } |
707 | 707 |
708 auto seq_num_it = protected_sequence_numbers_.find(header.sequenceNumber); | 708 // Is this a retransmitted media packet? From the perspective of FEC, this |
709 if (seq_num_it != protected_sequence_numbers_.end()) { | 709 // packet is then no longer dropped, so remove it from the list of |
710 // Retransmitted packet, should not count. | 710 // dropped packets. |
711 protected_sequence_numbers_.erase(seq_num_it); | 711 if (payload_type == kFakeVideoSendPayloadType) { |
712 auto ts_it = protected_timestamps_.find(header.timestamp); | 712 auto seq_num_it = dropped_sequence_numbers_.find(header.sequenceNumber); |
713 EXPECT_NE(ts_it, protected_timestamps_.end()); | 713 if (seq_num_it != dropped_sequence_numbers_.end()) { |
714 protected_timestamps_.erase(ts_it); | 714 dropped_sequence_numbers_.erase(seq_num_it); |
715 return SEND_PACKET; | 715 auto ts_it = dropped_timestamps_.find(header.timestamp); |
716 EXPECT_NE(ts_it, dropped_timestamps_.end()); | |
717 dropped_timestamps_.erase(ts_it); | |
718 | |
719 return SEND_PACKET; | |
720 } | |
716 } | 721 } |
717 | 722 |
718 switch (state_) { | 723 // Simulate 5% packet loss. Record what media packets, and corresponding |
719 case kFirstPacket: | 724 // timestamps, that were dropped. |
720 state_ = kDropEveryOtherPacketUntilFlexfec; | 725 if (random_.Rand(1, 100) <= 5) { |
721 break; | 726 if (payload_type == kFakeVideoSendPayloadType) { |
722 case kDropEveryOtherPacketUntilFlexfec: | 727 dropped_sequence_numbers_.insert(header.sequenceNumber); |
723 if (payload_type == kFlexfecPayloadType) { | 728 dropped_timestamps_.insert(header.timestamp); |
724 state_ = kDropNextMediaPacket; | 729 } |
725 return SEND_PACKET; | 730 |
726 } | 731 return DROP_PACKET; |
727 if (header.sequenceNumber % 2 == 0) | |
728 return DROP_PACKET; | |
729 break; | |
730 case kDropNextMediaPacket: | |
731 if (payload_type == kFakeVideoSendPayloadType) { | |
732 protected_sequence_numbers_.insert(header.sequenceNumber); | |
733 protected_timestamps_.insert(header.timestamp); | |
734 state_ = kDropEveryOtherPacketUntilFlexfec; | |
735 return DROP_PACKET; | |
736 } | |
737 break; | |
738 } | 732 } |
739 | 733 |
740 return SEND_PACKET; | 734 return SEND_PACKET; |
741 } | 735 } |
742 | 736 |
743 void OnFrame(const VideoFrame& video_frame) override { | 737 void OnFrame(const VideoFrame& video_frame) override { |
744 rtc::CritScope lock(&crit_); | 738 rtc::CritScope lock(&crit_); |
745 // Rendering frame with timestamp of packet that was dropped -> FEC | 739 // Rendering frame with timestamp of packet that was dropped -> FEC |
746 // protection worked. | 740 // protection worked. |
747 auto it = protected_timestamps_.find(video_frame.timestamp()); | 741 auto it = dropped_timestamps_.find(video_frame.timestamp()); |
748 if (it != protected_timestamps_.end()) | 742 if (it != dropped_timestamps_.end()) |
749 observation_complete_.Set(); | 743 observation_complete_.Set(); |
750 } | 744 } |
751 | 745 |
752 enum { | |
753 kFirstPacket, | |
754 kDropEveryOtherPacketUntilFlexfec, | |
755 kDropNextMediaPacket, | |
756 } state_; | |
757 | |
758 void ModifyVideoConfigs( | 746 void ModifyVideoConfigs( |
759 VideoSendStream::Config* send_config, | 747 VideoSendStream::Config* send_config, |
760 std::vector<VideoReceiveStream::Config>* receive_configs, | 748 std::vector<VideoReceiveStream::Config>* receive_configs, |
761 VideoEncoderConfig* encoder_config) override { | 749 VideoEncoderConfig* encoder_config) override { |
762 (*receive_configs)[0].renderer = this; | 750 (*receive_configs)[0].renderer = this; |
763 } | 751 } |
764 | 752 |
765 void PerformTest() override { | 753 void PerformTest() override { |
766 EXPECT_TRUE(Wait()) | 754 EXPECT_TRUE(Wait()) |
767 << "Timed out waiting for dropped frames to be rendered."; | 755 << "Timed out waiting for dropped frames to be rendered."; |
768 } | 756 } |
769 | 757 |
770 rtc::CriticalSection crit_; | 758 rtc::CriticalSection crit_; |
771 std::set<uint32_t> protected_sequence_numbers_ GUARDED_BY(crit_); | 759 std::set<uint32_t> dropped_sequence_numbers_ GUARDED_BY(crit_); |
772 // Since several packets can have the same timestamp a multiset is used | 760 // Since several packets can have the same timestamp a multiset is used |
773 // instead of a set. | 761 // instead of a set. |
774 std::multiset<uint32_t> protected_timestamps_ GUARDED_BY(crit_); | 762 std::multiset<uint32_t> dropped_timestamps_ GUARDED_BY(crit_); |
763 Random random_; | |
mflodman
2016/12/08 09:52:26
Add #include "webrtc/base/random.h"
brandtr
2016/12/08 11:27:12
Done.
| |
775 } test; | 764 } test; |
776 | 765 |
777 RunBaseTest(&test); | 766 RunBaseTest(&test); |
778 } | 767 } |
779 | 768 |
780 TEST_P(EndToEndTest, ReceivedUlpfecPacketsNotNacked) { | 769 TEST_P(EndToEndTest, ReceivedUlpfecPacketsNotNacked) { |
781 class UlpfecNackObserver : public test::EndToEndTest { | 770 class UlpfecNackObserver : public test::EndToEndTest { |
782 public: | 771 public: |
783 UlpfecNackObserver() | 772 UlpfecNackObserver() |
784 : EndToEndTest(kDefaultTimeoutMs), | 773 : EndToEndTest(kDefaultTimeoutMs), |
(...skipping 3256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4041 std::unique_ptr<VideoEncoder> encoder_; | 4030 std::unique_ptr<VideoEncoder> encoder_; |
4042 std::unique_ptr<VideoDecoder> decoder_; | 4031 std::unique_ptr<VideoDecoder> decoder_; |
4043 rtc::CriticalSection crit_; | 4032 rtc::CriticalSection crit_; |
4044 int recorded_frames_ GUARDED_BY(crit_); | 4033 int recorded_frames_ GUARDED_BY(crit_); |
4045 } test(this); | 4034 } test(this); |
4046 | 4035 |
4047 RunBaseTest(&test); | 4036 RunBaseTest(&test); |
4048 } | 4037 } |
4049 | 4038 |
4050 } // namespace webrtc | 4039 } // namespace webrtc |
OLD | NEW |