Chromium Code Reviews| 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 |