OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 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 | 10 |
(...skipping 29 matching lines...) Expand all Loading... |
40 dst->emplace_back(new ForwardErrorCorrection::Packet(*packet)); | 40 dst->emplace_back(new ForwardErrorCorrection::Packet(*packet)); |
41 } | 41 } |
42 ++i; | 42 ++i; |
43 } | 43 } |
44 } | 44 } |
45 | 45 |
46 } // namespace | 46 } // namespace |
47 | 47 |
48 using ::testing::Types; | 48 using ::testing::Types; |
49 | 49 |
50 // Subclass ForwardErrorCorrection to use gTest typed tests. | |
51 class UlpfecForwardErrorCorrection : public ForwardErrorCorrection { | |
52 public: | |
53 UlpfecForwardErrorCorrection() | |
54 : ForwardErrorCorrection( | |
55 std::unique_ptr<FecHeaderReader>(new UlpfecHeaderReader()), | |
56 std::unique_ptr<FecHeaderWriter>(new UlpfecHeaderWriter())) {} | |
57 }; | |
58 | |
59 template <typename ForwardErrorCorrectionType> | 50 template <typename ForwardErrorCorrectionType> |
60 class RtpFecTest : public ::testing::Test { | 51 class RtpFecTest : public ::testing::Test { |
61 protected: | 52 protected: |
62 RtpFecTest() | 53 RtpFecTest() |
63 : random_(0xabcdef123456), | 54 : random_(0xabcdef123456), |
64 media_packet_generator_( | 55 media_packet_generator_( |
65 kRtpHeaderSize, // Minimum packet size. | 56 kRtpHeaderSize, // Minimum packet size. |
66 IP_PACKET_SIZE - kRtpHeaderSize - kTransportOverhead - | 57 IP_PACKET_SIZE - kRtpHeaderSize - kTransportOverhead - |
67 fec_.MaxPacketOverhead(), // Maximum packet size. | 58 fec_.MaxPacketOverhead(), // Maximum packet size. |
68 kMediaSsrc, | 59 kMediaSsrc, |
(...skipping 24 matching lines...) Expand all Loading... |
93 | 84 |
94 ForwardErrorCorrection::PacketList media_packets_; | 85 ForwardErrorCorrection::PacketList media_packets_; |
95 std::list<ForwardErrorCorrection::Packet*> generated_fec_packets_; | 86 std::list<ForwardErrorCorrection::Packet*> generated_fec_packets_; |
96 ForwardErrorCorrection::ReceivedPacketList received_packets_; | 87 ForwardErrorCorrection::ReceivedPacketList received_packets_; |
97 ForwardErrorCorrection::RecoveredPacketList recovered_packets_; | 88 ForwardErrorCorrection::RecoveredPacketList recovered_packets_; |
98 | 89 |
99 int media_loss_mask_[kUlpfecMaxMediaPackets]; | 90 int media_loss_mask_[kUlpfecMaxMediaPackets]; |
100 int fec_loss_mask_[kUlpfecMaxMediaPackets]; | 91 int fec_loss_mask_[kUlpfecMaxMediaPackets]; |
101 }; | 92 }; |
102 | 93 |
| 94 template <typename ForwardErrorCorrectionType> |
| 95 void RtpFecTest<ForwardErrorCorrectionType>::NetworkReceivedPackets( |
| 96 int* media_loss_mask, |
| 97 int* fec_loss_mask) { |
| 98 constexpr bool kFecPacket = true; |
| 99 ReceivedPackets(media_packets_, media_loss_mask, !kFecPacket); |
| 100 ReceivedPackets(generated_fec_packets_, fec_loss_mask, kFecPacket); |
| 101 } |
| 102 |
| 103 template <typename ForwardErrorCorrectionType> |
| 104 template <typename PacketListType> |
| 105 void RtpFecTest<ForwardErrorCorrectionType>::ReceivedPackets( |
| 106 const PacketListType& packet_list, |
| 107 int* loss_mask, |
| 108 bool is_fec) { |
| 109 uint16_t fec_seq_num = media_packet_generator_.GetFecSeqNum(); |
| 110 int packet_idx = 0; |
| 111 |
| 112 for (const auto& packet : packet_list) { |
| 113 if (loss_mask[packet_idx] == 0) { |
| 114 std::unique_ptr<ForwardErrorCorrection::ReceivedPacket> received_packet( |
| 115 new ForwardErrorCorrection::ReceivedPacket()); |
| 116 received_packet->pkt = new ForwardErrorCorrection::Packet(); |
| 117 received_packet->pkt->length = packet->length; |
| 118 memcpy(received_packet->pkt->data, packet->data, packet->length); |
| 119 received_packet->is_fec = is_fec; |
| 120 if (!is_fec) { |
| 121 // For media packets, the sequence number and marker bit is |
| 122 // obtained from RTP header. These were set in ConstructMediaPackets(). |
| 123 received_packet->seq_num = |
| 124 ByteReader<uint16_t>::ReadBigEndian(&packet->data[2]); |
| 125 } else { |
| 126 // The sequence number, marker bit, and ssrc number are defined in the |
| 127 // RTP header of the FEC packet, which is not constructed in this test. |
| 128 // So we set these values below based on the values generated in |
| 129 // ConstructMediaPackets(). |
| 130 received_packet->seq_num = fec_seq_num; |
| 131 // The ssrc value for FEC packets is set to the one used for the |
| 132 // media packets in ConstructMediaPackets(). |
| 133 received_packet->ssrc = kMediaSsrc; |
| 134 } |
| 135 received_packets_.push_back(std::move(received_packet)); |
| 136 } |
| 137 packet_idx++; |
| 138 // Sequence number of FEC packets are defined as increment by 1 from |
| 139 // last media packet in frame. |
| 140 if (is_fec) |
| 141 fec_seq_num++; |
| 142 } |
| 143 } |
| 144 |
| 145 template <typename ForwardErrorCorrectionType> |
| 146 bool RtpFecTest<ForwardErrorCorrectionType>::IsRecoveryComplete() { |
| 147 // We must have equally many recovered packets as original packets. |
| 148 if (recovered_packets_.size() != media_packets_.size()) { |
| 149 return false; |
| 150 } |
| 151 |
| 152 // All recovered packets must be identical to the corresponding |
| 153 // original packets. |
| 154 using PacketPtr = std::unique_ptr<ForwardErrorCorrection::Packet>; |
| 155 using RecoveredPacketPtr = |
| 156 std::unique_ptr<ForwardErrorCorrection::RecoveredPacket>; |
| 157 auto cmp = [](const PacketPtr& media_packet, |
| 158 const RecoveredPacketPtr& recovered_packet) { |
| 159 if (media_packet->length != recovered_packet->pkt->length) { |
| 160 return false; |
| 161 } |
| 162 if (memcmp(media_packet->data, |
| 163 recovered_packet->pkt->data, |
| 164 media_packet->length) != 0) { |
| 165 return false; |
| 166 } |
| 167 return true; |
| 168 }; |
| 169 return std::equal(media_packets_.cbegin(), media_packets_.cend(), |
| 170 recovered_packets_.cbegin(), cmp); |
| 171 } |
| 172 |
103 // Define gTest typed test to loop over both ULPFEC and FlexFEC. | 173 // Define gTest typed test to loop over both ULPFEC and FlexFEC. |
104 // Since the tests now are parameterized, we need to access | 174 // Since the tests now are parameterized, we need to access |
105 // member variables using |this|, thereby enforcing runtime | 175 // member variables using |this|, thereby enforcing runtime |
106 // resolution. | 176 // resolution. |
| 177 |
| 178 class UlpfecForwardErrorCorrection : public ForwardErrorCorrection { |
| 179 public: |
| 180 UlpfecForwardErrorCorrection() |
| 181 : ForwardErrorCorrection( |
| 182 std::unique_ptr<FecHeaderReader>(new UlpfecHeaderReader()), |
| 183 std::unique_ptr<FecHeaderWriter>(new UlpfecHeaderWriter())) {} |
| 184 }; |
| 185 |
107 using FecTypes = Types<UlpfecForwardErrorCorrection>; | 186 using FecTypes = Types<UlpfecForwardErrorCorrection>; |
108 TYPED_TEST_CASE(RtpFecTest, FecTypes); | 187 TYPED_TEST_CASE(RtpFecTest, FecTypes); |
109 | 188 |
110 TYPED_TEST(RtpFecTest, FecRecoveryNoLoss) { | 189 TYPED_TEST(RtpFecTest, FecRecoveryNoLoss) { |
111 constexpr int kNumImportantPackets = 0; | 190 constexpr int kNumImportantPackets = 0; |
112 constexpr bool kUseUnequalProtection = false; | 191 constexpr bool kUseUnequalProtection = false; |
113 constexpr int kNumMediaPackets = 4; | 192 constexpr int kNumMediaPackets = 4; |
114 constexpr uint8_t kProtectionFactor = 60; | 193 constexpr uint8_t kProtectionFactor = 60; |
115 | 194 |
116 this->media_packets_ = | 195 this->media_packets_ = |
(...skipping 746 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
863 this->media_loss_mask_[kNumMediaPackets - 1] = 1; | 942 this->media_loss_mask_[kNumMediaPackets - 1] = 1; |
864 this->NetworkReceivedPackets(this->media_loss_mask_, this->fec_loss_mask_); | 943 this->NetworkReceivedPackets(this->media_loss_mask_, this->fec_loss_mask_); |
865 | 944 |
866 EXPECT_EQ(0, this->fec_.DecodeFec(&this->received_packets_, | 945 EXPECT_EQ(0, this->fec_.DecodeFec(&this->received_packets_, |
867 &this->recovered_packets_)); | 946 &this->recovered_packets_)); |
868 | 947 |
869 // 5 protected packets lost, one FEC packet, cannot get complete recovery. | 948 // 5 protected packets lost, one FEC packet, cannot get complete recovery. |
870 EXPECT_FALSE(this->IsRecoveryComplete()); | 949 EXPECT_FALSE(this->IsRecoveryComplete()); |
871 } | 950 } |
872 | 951 |
873 template <typename ForwardErrorCorrectionType> | |
874 bool RtpFecTest<ForwardErrorCorrectionType>::IsRecoveryComplete() { | |
875 // We must have equally many recovered packets as original packets. | |
876 if (recovered_packets_.size() != media_packets_.size()) { | |
877 return false; | |
878 } | |
879 | |
880 // All recovered packets must be identical to the corresponding | |
881 // original packets. | |
882 using PacketPtr = std::unique_ptr<ForwardErrorCorrection::Packet>; | |
883 using RecoveredPacketPtr = | |
884 std::unique_ptr<ForwardErrorCorrection::RecoveredPacket>; | |
885 auto cmp = [](const PacketPtr& media_packet, | |
886 const RecoveredPacketPtr& recovered_packet) { | |
887 if (media_packet->length != recovered_packet->pkt->length) { | |
888 return false; | |
889 } | |
890 if (memcmp(media_packet->data, | |
891 recovered_packet->pkt->data, | |
892 media_packet->length) != 0) { | |
893 return false; | |
894 } | |
895 return true; | |
896 }; | |
897 return std::equal(media_packets_.cbegin(), media_packets_.cend(), | |
898 recovered_packets_.cbegin(), cmp); | |
899 } | |
900 | |
901 template <typename ForwardErrorCorrectionType> | |
902 void RtpFecTest<ForwardErrorCorrectionType>::NetworkReceivedPackets( | |
903 int* media_loss_mask, | |
904 int* fec_loss_mask) { | |
905 constexpr bool kFecPacket = true; | |
906 ReceivedPackets(media_packets_, media_loss_mask, !kFecPacket); | |
907 ReceivedPackets(generated_fec_packets_, fec_loss_mask, kFecPacket); | |
908 } | |
909 | |
910 template <typename ForwardErrorCorrectionType> | |
911 template <typename PacketListType> | |
912 void RtpFecTest<ForwardErrorCorrectionType>::ReceivedPackets( | |
913 const PacketListType& packet_list, | |
914 int* loss_mask, | |
915 bool is_fec) { | |
916 uint16_t fec_seq_num = media_packet_generator_.GetFecSeqNum(); | |
917 int packet_idx = 0; | |
918 | |
919 for (const auto& packet : packet_list) { | |
920 if (loss_mask[packet_idx] == 0) { | |
921 std::unique_ptr<ForwardErrorCorrection::ReceivedPacket> received_packet( | |
922 new ForwardErrorCorrection::ReceivedPacket()); | |
923 received_packet->pkt = new ForwardErrorCorrection::Packet(); | |
924 received_packet->pkt->length = packet->length; | |
925 memcpy(received_packet->pkt->data, packet->data, packet->length); | |
926 received_packet->is_fec = is_fec; | |
927 if (!is_fec) { | |
928 // For media packets, the sequence number and marker bit is | |
929 // obtained from RTP header. These were set in ConstructMediaPackets(). | |
930 received_packet->seq_num = | |
931 ByteReader<uint16_t>::ReadBigEndian(&packet->data[2]); | |
932 } else { | |
933 // The sequence number, marker bit, and ssrc number are defined in the | |
934 // RTP header of the FEC packet, which is not constructed in this test. | |
935 // So we set these values below based on the values generated in | |
936 // ConstructMediaPackets(). | |
937 received_packet->seq_num = fec_seq_num; | |
938 // The ssrc value for FEC packets is set to the one used for the | |
939 // media packets in ConstructMediaPackets(). | |
940 received_packet->ssrc = kMediaSsrc; | |
941 } | |
942 received_packets_.push_back(std::move(received_packet)); | |
943 } | |
944 packet_idx++; | |
945 // Sequence number of FEC packets are defined as increment by 1 from | |
946 // last media packet in frame. | |
947 if (is_fec) | |
948 fec_seq_num++; | |
949 } | |
950 } | |
951 | |
952 } // namespace webrtc | 952 } // namespace webrtc |
OLD | NEW |