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 |
11 #include <algorithm> | 11 #include <algorithm> |
12 #include <list> | 12 #include <list> |
13 | 13 |
14 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
15 #include "webrtc/base/random.h" | 15 #include "webrtc/base/random.h" |
16 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" | 16 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" |
17 #include "webrtc/modules/rtp_rtcp/source/forward_error_correction.h" | 17 #include "webrtc/modules/rtp_rtcp/source/forward_error_correction.h" |
18 | 18 |
19 using webrtc::ForwardErrorCorrection; | 19 using webrtc::ForwardErrorCorrection; |
20 | 20 |
21 // Minimum RTP header size in bytes. | 21 // Minimum RTP header size in bytes. |
22 const uint8_t kRtpHeaderSize = 12; | 22 constexpr uint8_t kRtpHeaderSize = 12; |
23 | 23 |
24 // Transport header size in bytes. Assume UDP/IPv4 as a reasonable minimum. | 24 // Transport header size in bytes. Assume UDP/IPv4 as a reasonable minimum. |
25 const uint8_t kTransportOverhead = 28; | 25 constexpr uint8_t kTransportOverhead = 28; |
26 | 26 |
27 // Maximum number of media packets used in the FEC (RFC 5109). | 27 // Maximum number of media packets used in the FEC (RFC 5109). |
28 const uint8_t kMaxNumberMediaPackets = ForwardErrorCorrection::kMaxMediaPackets; | 28 constexpr uint8_t kMaxNumberMediaPackets = |
29 ForwardErrorCorrection::kMaxMediaPackets; | |
29 | 30 |
30 using PacketList = ForwardErrorCorrection::PacketList; | 31 using PacketList = ForwardErrorCorrection::PacketList; |
31 using ReceivedPacketList = ForwardErrorCorrection::ReceivedPacketList; | 32 using ReceivedPacketList = ForwardErrorCorrection::ReceivedPacketList; |
32 using RecoveredPacketList = ForwardErrorCorrection::RecoveredPacketList; | 33 using RecoveredPacketList = ForwardErrorCorrection::RecoveredPacketList; |
33 | 34 |
34 template <typename T> void ClearList(std::list<T*>* my_list) { | 35 template <typename T> void ClearList(std::list<T*>* my_list) { |
35 T* packet = NULL; | 36 T* packet = NULL; |
36 while (!my_list->empty()) { | 37 while (!my_list->empty()) { |
37 packet = my_list->front(); | 38 packet = my_list->front(); |
38 delete packet; | 39 delete packet; |
39 my_list->pop_front(); | 40 my_list->pop_front(); |
40 } | 41 } |
41 } | 42 } |
42 | 43 |
43 class RtpFecTest : public ::testing::Test { | 44 class RtpFecTest : public ::testing::Test { |
44 protected: | 45 protected: |
45 RtpFecTest() | 46 RtpFecTest() |
46 : random_(0xfec133700742), | 47 : random_(0xfec133700742), |
47 fec_(new ForwardErrorCorrection()), | |
48 ssrc_(random_.Rand<uint32_t>()), | 48 ssrc_(random_.Rand<uint32_t>()), |
49 fec_seq_num_(0) {} | 49 fec_seq_num_(0) {} |
50 | 50 |
51 webrtc::Random random_; | 51 // Construct |media_packet_list_|, up to |num_media_packets| packets. |
52 ForwardErrorCorrection* fec_; | |
53 int ssrc_; | |
54 uint16_t fec_seq_num_; | |
55 | |
56 PacketList media_packet_list_; | |
57 PacketList fec_packet_list_; | |
58 ReceivedPacketList received_packet_list_; | |
59 RecoveredPacketList recovered_packet_list_; | |
60 | |
61 // Media packet "i" is lost if media_loss_mask_[i] = 1, | |
62 // received if media_loss_mask_[i] = 0. | |
63 int media_loss_mask_[kMaxNumberMediaPackets]; | |
64 | |
65 // FEC packet "i" is lost if fec_loss_mask_[i] = 1, | |
66 // received if fec_loss_mask_[i] = 0. | |
67 int fec_loss_mask_[kMaxNumberMediaPackets]; | |
68 | |
69 // Construct the media packet list, up to |num_media_packets| packets. | |
70 // Returns the next sequence number after the last media packet. | 52 // Returns the next sequence number after the last media packet. |
71 // (this will be the sequence of the first FEC packet) | 53 // (this will be the sequence of the first FEC packet) |
72 int ConstructMediaPacketsSeqNum(int num_media_packets, int start_seq_num); | 54 int ConstructMediaPacketsSeqNum(int num_media_packets, int start_seq_num); |
73 int ConstructMediaPackets(int num_media_packets); | 55 int ConstructMediaPackets(int num_media_packets); |
74 | 56 |
75 // Construct the received packet list: a subset of the media and FEC packets. | 57 // Construct |received_packet_list_|: a subset of the media and FEC packets. |
76 void NetworkReceivedPackets(); | 58 // |
59 // Media packet "i" is lost if media_loss_mask_[i] = 1, received if | |
60 // media_loss_mask_[i] = 0. | |
61 // FEC packet "i" is lost if fec_loss_mask_[i] = 1, received if | |
62 // fec_loss_mask_[i] = 0. | |
63 void NetworkReceivedPackets(int* media_loss_mask, int* fec_loss_mask); | |
77 | 64 |
78 // Add packet from |packet_list| to list of received packets, using the | 65 // Add packet from |packet_list| to list of received packets, using the |
79 // |loss_mask|. | 66 // |loss_mask|. |
80 // The |packet_list| may be a media packet list (is_fec = false), or a | 67 // The |packet_list| may be a media packet list (is_fec = false), or a |
81 // FEC packet list (is_fec = true). | 68 // FEC packet list (is_fec = true). |
82 void ReceivedPackets(const PacketList& packet_list, int* loss_mask, | 69 void ReceivedPackets(const PacketList& packet_list, int* loss_mask, |
83 bool is_fec); | 70 bool is_fec); |
84 | 71 |
85 // Check for complete recovery after FEC decoding. | 72 // Check for complete recovery after FEC decoding. |
86 bool IsRecoveryComplete(); | 73 bool IsRecoveryComplete(); |
87 | 74 |
88 // Delete the received packets. | 75 // Delete the received packets. |
89 void FreeRecoveredPacketList(); | 76 void FreeRecoveredPacketList(); |
90 | 77 |
91 // Delete the media and FEC packets. | 78 // Delete the media and FEC packets. |
92 void TearDown(); | 79 void TearDown(); |
80 | |
81 webrtc::Random random_; | |
82 ForwardErrorCorrection fec_; | |
83 int ssrc_; | |
84 uint16_t fec_seq_num_; | |
85 | |
86 PacketList media_packet_list_; | |
87 PacketList fec_packet_list_; | |
88 ReceivedPacketList received_packet_list_; | |
89 RecoveredPacketList recovered_packet_list_; | |
90 | |
91 int media_loss_mask_[kMaxNumberMediaPackets]; | |
92 int fec_loss_mask_[kMaxNumberMediaPackets]; | |
93 }; | 93 }; |
94 | 94 |
95 TEST_F(RtpFecTest, FecRecoveryNoLoss) { | 95 TEST_F(RtpFecTest, FecRecoveryNoLoss) { |
96 const int kNumImportantPackets = 0; | 96 constexpr int kNumImportantPackets = 0; |
97 const bool kUseUnequalProtection = false; | 97 constexpr bool kUseUnequalProtection = false; |
98 const int kNumMediaPackets = 4; | 98 constexpr int kNumMediaPackets = 4; |
99 uint8_t kProtectionFactor = 60; | 99 constexpr uint8_t kProtectionFactor = 60; |
100 | 100 |
101 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); | 101 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); |
102 | 102 |
103 EXPECT_EQ(0, fec_->GenerateFec(media_packet_list_, kProtectionFactor, | 103 EXPECT_EQ(0, fec_.GenerateFec(media_packet_list_, kProtectionFactor, |
104 kNumImportantPackets, kUseUnequalProtection, | 104 kNumImportantPackets, kUseUnequalProtection, |
105 webrtc::kFecMaskBursty, &fec_packet_list_)); | 105 webrtc::kFecMaskBursty, &fec_packet_list_)); |
106 | 106 |
107 // Expect 1 FEC packet. | 107 // Expect 1 FEC packet. |
108 EXPECT_EQ(1, static_cast<int>(fec_packet_list_.size())); | 108 EXPECT_EQ(1u, fec_packet_list_.size()); |
109 | 109 |
110 // No packets lost. | 110 // No packets lost. |
111 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 111 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
112 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 112 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
113 NetworkReceivedPackets(); | 113 NetworkReceivedPackets(media_loss_mask_, fec_loss_mask_); |
114 | 114 |
115 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 115 EXPECT_EQ(0, fec_.DecodeFec(&received_packet_list_, |
116 &recovered_packet_list_)); | 116 &recovered_packet_list_)); |
117 | 117 |
118 // No packets lost, expect complete recovery. | 118 // No packets lost, expect complete recovery. |
119 EXPECT_TRUE(IsRecoveryComplete()); | 119 EXPECT_TRUE(IsRecoveryComplete()); |
120 } | 120 } |
121 | 121 |
122 TEST_F(RtpFecTest, FecRecoveryWithLoss) { | 122 TEST_F(RtpFecTest, FecRecoveryWithLoss) { |
123 const int kNumImportantPackets = 0; | 123 constexpr int kNumImportantPackets = 0; |
124 const bool kUseUnequalProtection = false; | 124 constexpr bool kUseUnequalProtection = false; |
125 const int kNumMediaPackets = 4; | 125 constexpr int kNumMediaPackets = 4; |
126 uint8_t kProtectionFactor = 60; | 126 constexpr uint8_t kProtectionFactor = 60; |
127 | 127 |
128 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); | 128 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); |
129 | 129 |
130 EXPECT_EQ(0, fec_->GenerateFec(media_packet_list_, kProtectionFactor, | 130 EXPECT_EQ(0, fec_.GenerateFec(media_packet_list_, kProtectionFactor, |
131 kNumImportantPackets, kUseUnequalProtection, | 131 kNumImportantPackets, kUseUnequalProtection, |
132 webrtc::kFecMaskBursty, &fec_packet_list_)); | 132 webrtc::kFecMaskBursty, &fec_packet_list_)); |
133 | 133 |
134 // Expect 1 FEC packet. | 134 // Expect 1 FEC packet. |
135 EXPECT_EQ(1, static_cast<int>(fec_packet_list_.size())); | 135 EXPECT_EQ(1u, fec_packet_list_.size()); |
136 | 136 |
137 // 1 media packet lost | 137 // 1 media packet lost |
138 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 138 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
139 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 139 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
140 media_loss_mask_[3] = 1; | 140 media_loss_mask_[3] = 1; |
141 NetworkReceivedPackets(); | 141 NetworkReceivedPackets(media_loss_mask_, fec_loss_mask_); |
142 | 142 |
143 EXPECT_EQ(0, | 143 EXPECT_EQ(0, |
144 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); | 144 fec_.DecodeFec(&received_packet_list_, &recovered_packet_list_)); |
145 | 145 |
146 // One packet lost, one FEC packet, expect complete recovery. | 146 // One packet lost, one FEC packet, expect complete recovery. |
147 EXPECT_TRUE(IsRecoveryComplete()); | 147 EXPECT_TRUE(IsRecoveryComplete()); |
148 FreeRecoveredPacketList(); | 148 FreeRecoveredPacketList(); |
149 | 149 |
150 // 2 media packets lost. | 150 // 2 media packets lost. |
151 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 151 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
152 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 152 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
153 media_loss_mask_[1] = 1; | 153 media_loss_mask_[1] = 1; |
154 media_loss_mask_[3] = 1; | 154 media_loss_mask_[3] = 1; |
155 NetworkReceivedPackets(); | 155 NetworkReceivedPackets(media_loss_mask_, fec_loss_mask_); |
156 | 156 |
157 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 157 EXPECT_EQ(0, fec_.DecodeFec(&received_packet_list_, |
158 &recovered_packet_list_)); | 158 &recovered_packet_list_)); |
danilchap
2016/07/22 12:38:21
realign (or just call 'git cl format' since there
brandtr
2016/07/22 12:58:27
Ran 'git cl format'.
| |
159 | 159 |
160 // 2 packets lost, one FEC packet, cannot get complete recovery. | 160 // 2 packets lost, one FEC packet, cannot get complete recovery. |
161 EXPECT_FALSE(IsRecoveryComplete()); | 161 EXPECT_FALSE(IsRecoveryComplete()); |
162 } | 162 } |
163 | 163 |
164 // Verify that we don't use an old FEC packet for FEC decoding. | 164 // Verify that we don't use an old FEC packet for FEC decoding. |
165 TEST_F(RtpFecTest, FecRecoveryWithSeqNumGapTwoFrames) { | 165 TEST_F(RtpFecTest, FecRecoveryWithSeqNumGapTwoFrames) { |
166 const int kNumImportantPackets = 0; | 166 constexpr int kNumImportantPackets = 0; |
167 const bool kUseUnequalProtection = false; | 167 constexpr bool kUseUnequalProtection = false; |
168 uint8_t kProtectionFactor = 20; | 168 constexpr uint8_t kProtectionFactor = 20; |
169 | 169 |
170 // Two frames: first frame (old) with two media packets and 1 FEC packet. | 170 // Two frames: first frame (old) with two media packets and 1 FEC packet. |
171 // Second frame (new) with 3 media packets, and no FEC packets. | 171 // Second frame (new) with 3 media packets, and no FEC packets. |
172 // ---Frame 1---- ----Frame 2------ | 172 // ---Frame 1---- ----Frame 2------ |
173 // #0(media) #1(media) #2(FEC) #65535(media) #0(media) #1(media). | 173 // #0(media) #1(media) #2(FEC) #65535(media) #0(media) #1(media). |
174 // If we lose either packet 0 or 1 of second frame, FEC decoding should not | 174 // If we lose either packet 0 or 1 of second frame, FEC decoding should not |
175 // try to decode using "old" FEC packet #2. | 175 // try to decode using "old" FEC packet #2. |
176 | 176 |
177 // Construct media packets for first frame, starting at sequence number 0. | 177 // Construct media packets for first frame, starting at sequence number 0. |
178 fec_seq_num_ = ConstructMediaPacketsSeqNum(2, 0); | 178 fec_seq_num_ = ConstructMediaPacketsSeqNum(2, 0); |
179 | 179 |
180 EXPECT_EQ(0, fec_->GenerateFec(media_packet_list_, kProtectionFactor, | 180 EXPECT_EQ(0, fec_.GenerateFec(media_packet_list_, kProtectionFactor, |
181 kNumImportantPackets, kUseUnequalProtection, | 181 kNumImportantPackets, kUseUnequalProtection, |
182 webrtc::kFecMaskBursty, &fec_packet_list_)); | 182 webrtc::kFecMaskBursty, &fec_packet_list_)); |
183 // Expect 1 FEC packet. | 183 // Expect 1 FEC packet. |
184 EXPECT_EQ(1, static_cast<int>(fec_packet_list_.size())); | 184 EXPECT_EQ(1u, fec_packet_list_.size()); |
185 // Add FEC packet (seq#2) of this first frame to received list (i.e., assume | 185 // Add FEC packet (seq#2) of this first frame to received list (i.e., assume |
186 // the two media packet were lost). | 186 // the two media packet were lost). |
187 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 187 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
188 ReceivedPackets(fec_packet_list_, fec_loss_mask_, true); | 188 ReceivedPackets(fec_packet_list_, fec_loss_mask_, true); |
189 | 189 |
190 // Construct media packets for second frame, with sequence number wrap. | 190 // Construct media packets for second frame, with sequence number wrap. |
191 ClearList(&media_packet_list_); | 191 ClearList(&media_packet_list_); |
192 fec_seq_num_ = ConstructMediaPacketsSeqNum(3, 65535); | 192 fec_seq_num_ = ConstructMediaPacketsSeqNum(3, 65535); |
193 | 193 |
194 // Expect 3 media packets for this frame. | 194 // Expect 3 media packets for this frame. |
195 EXPECT_EQ(3, static_cast<int>(media_packet_list_.size())); | 195 EXPECT_EQ(3u, media_packet_list_.size()); |
196 | 196 |
197 // Second media packet lost (seq#0). | 197 // Second media packet lost (seq#0). |
198 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 198 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
199 media_loss_mask_[1] = 1; | 199 media_loss_mask_[1] = 1; |
200 // Add packets #65535, and #1 to received list. | 200 // Add packets #65535, and #1 to received list. |
201 ReceivedPackets(media_packet_list_, media_loss_mask_, false); | 201 ReceivedPackets(media_packet_list_, media_loss_mask_, false); |
202 | 202 |
203 EXPECT_EQ(0, | 203 EXPECT_EQ(0, |
204 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); | 204 fec_.DecodeFec(&received_packet_list_, &recovered_packet_list_)); |
205 | 205 |
206 // Expect that no decoding is done to get missing packet (seq#0) of second | 206 // Expect that no decoding is done to get missing packet (seq#0) of second |
207 // frame, using old FEC packet (seq#2) from first (old) frame. So number of | 207 // frame, using old FEC packet (seq#2) from first (old) frame. So number of |
208 // recovered packets is 2, and not equal to number of media packets (=3). | 208 // recovered packets is 2, and not equal to number of media packets (=3). |
209 EXPECT_EQ(2, static_cast<int>(recovered_packet_list_.size())); | 209 EXPECT_EQ(2u, recovered_packet_list_.size()); |
210 EXPECT_TRUE(recovered_packet_list_.size() != media_packet_list_.size()); | 210 EXPECT_TRUE(recovered_packet_list_.size() != media_packet_list_.size()); |
211 FreeRecoveredPacketList(); | 211 FreeRecoveredPacketList(); |
212 } | 212 } |
213 | 213 |
214 // Verify we can still recovery frame if sequence number wrap occurs within | 214 // Verify we can still recover frame if sequence number wrap occurs within |
215 // the frame and FEC packet following wrap is received after media packets. | 215 // the frame and FEC packet following wrap is received after media packets. |
216 TEST_F(RtpFecTest, FecRecoveryWithSeqNumGapOneFrameRecovery) { | 216 TEST_F(RtpFecTest, FecRecoveryWithSeqNumGapOneFrameRecovery) { |
217 const int kNumImportantPackets = 0; | 217 constexpr int kNumImportantPackets = 0; |
218 const bool kUseUnequalProtection = false; | 218 constexpr bool kUseUnequalProtection = false; |
219 uint8_t kProtectionFactor = 20; | 219 constexpr uint8_t kProtectionFactor = 20; |
220 | 220 |
221 // One frame, with sequence number wrap in media packets. | 221 // One frame, with sequence number wrap in media packets. |
222 // -----Frame 1---- | 222 // -----Frame 1---- |
223 // #65534(media) #65535(media) #0(media) #1(FEC). | 223 // #65534(media) #65535(media) #0(media) #1(FEC). |
224 fec_seq_num_ = ConstructMediaPacketsSeqNum(3, 65534); | 224 fec_seq_num_ = ConstructMediaPacketsSeqNum(3, 65534); |
225 | 225 |
226 EXPECT_EQ(0, fec_->GenerateFec(media_packet_list_, kProtectionFactor, | 226 EXPECT_EQ(0, fec_.GenerateFec(media_packet_list_, kProtectionFactor, |
227 kNumImportantPackets, kUseUnequalProtection, | 227 kNumImportantPackets, kUseUnequalProtection, |
228 webrtc::kFecMaskBursty, &fec_packet_list_)); | 228 webrtc::kFecMaskBursty, &fec_packet_list_)); |
229 | 229 |
230 // Expect 1 FEC packet. | 230 // Expect 1 FEC packet. |
231 EXPECT_EQ(1, static_cast<int>(fec_packet_list_.size())); | 231 EXPECT_EQ(1u, fec_packet_list_.size()); |
232 | 232 |
233 // Lose one media packet (seq# 65535). | 233 // Lose one media packet (seq# 65535). |
234 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 234 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
235 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 235 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
236 media_loss_mask_[1] = 1; | 236 media_loss_mask_[1] = 1; |
237 ReceivedPackets(media_packet_list_, media_loss_mask_, false); | 237 ReceivedPackets(media_packet_list_, media_loss_mask_, false); |
238 // Add FEC packet to received list following the media packets. | 238 // Add FEC packet to received list following the media packets. |
239 ReceivedPackets(fec_packet_list_, fec_loss_mask_, true); | 239 ReceivedPackets(fec_packet_list_, fec_loss_mask_, true); |
240 | 240 |
241 EXPECT_EQ(0, | 241 EXPECT_EQ(0, |
242 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); | 242 fec_.DecodeFec(&received_packet_list_, &recovered_packet_list_)); |
243 | 243 |
244 // Expect 3 media packets in recovered list, and complete recovery. | 244 // Expect 3 media packets in recovered list, and complete recovery. |
245 // Wrap-around won't remove FEC packet, as it follows the wrap. | 245 // Wrap-around won't remove FEC packet, as it follows the wrap. |
246 EXPECT_EQ(3, static_cast<int>(recovered_packet_list_.size())); | 246 EXPECT_EQ(3u, recovered_packet_list_.size()); |
247 EXPECT_TRUE(IsRecoveryComplete()); | 247 EXPECT_TRUE(IsRecoveryComplete()); |
248 FreeRecoveredPacketList(); | 248 FreeRecoveredPacketList(); |
249 } | 249 } |
250 | 250 |
251 // Sequence number wrap occurs within the FEC packets for the frame. | 251 // Sequence number wrap occurs within the FEC packets for the frame. |
252 // In this case we will discard FEC packet and full recovery is not expected. | 252 // In this case we will discard FEC packet and full recovery is not expected. |
253 // Same problem will occur if wrap is within media packets but FEC packet is | 253 // Same problem will occur if wrap is within media packets but FEC packet is |
254 // received before the media packets. This may be improved if timing information | 254 // received before the media packets. This may be improved if timing information |
255 // is used to detect old FEC packets. | 255 // is used to detect old FEC packets. |
256 // TODO(marpan): Update test if wrap-around handling changes in FEC decoding. | 256 // TODO(marpan): Update test if wrap-around handling changes in FEC decoding. |
257 TEST_F(RtpFecTest, FecRecoveryWithSeqNumGapOneFrameNoRecovery) { | 257 TEST_F(RtpFecTest, FecRecoveryWithSeqNumGapOneFrameNoRecovery) { |
258 const int kNumImportantPackets = 0; | 258 constexpr int kNumImportantPackets = 0; |
259 const bool kUseUnequalProtection = false; | 259 constexpr bool kUseUnequalProtection = false; |
260 uint8_t kProtectionFactor = 200; | 260 constexpr uint8_t kProtectionFactor = 200; |
261 | 261 |
262 // 1 frame: 3 media packets and 2 FEC packets. | 262 // 1 frame: 3 media packets and 2 FEC packets. |
263 // Sequence number wrap in FEC packets. | 263 // Sequence number wrap in FEC packets. |
264 // -----Frame 1---- | 264 // -----Frame 1---- |
265 // #65532(media) #65533(media) #65534(media) #65535(FEC) #0(FEC). | 265 // #65532(media) #65533(media) #65534(media) #65535(FEC) #0(FEC). |
266 fec_seq_num_ = ConstructMediaPacketsSeqNum(3, 65532); | 266 fec_seq_num_ = ConstructMediaPacketsSeqNum(3, 65532); |
267 | 267 |
268 EXPECT_EQ(0, fec_->GenerateFec(media_packet_list_, kProtectionFactor, | 268 EXPECT_EQ(0, fec_.GenerateFec(media_packet_list_, kProtectionFactor, |
269 kNumImportantPackets, kUseUnequalProtection, | 269 kNumImportantPackets, kUseUnequalProtection, |
270 webrtc::kFecMaskBursty, &fec_packet_list_)); | 270 webrtc::kFecMaskBursty, &fec_packet_list_)); |
271 | 271 |
272 // Expect 2 FEC packets. | 272 // Expect 2 FEC packets. |
273 EXPECT_EQ(2, static_cast<int>(fec_packet_list_.size())); | 273 EXPECT_EQ(2u, fec_packet_list_.size()); |
274 | 274 |
275 // Lose the last two media packets (seq# 65533, 65534). | 275 // Lose the last two media packets (seq# 65533, 65534). |
276 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 276 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
277 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 277 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
278 media_loss_mask_[1] = 1; | 278 media_loss_mask_[1] = 1; |
279 media_loss_mask_[2] = 1; | 279 media_loss_mask_[2] = 1; |
280 ReceivedPackets(media_packet_list_, media_loss_mask_, false); | 280 ReceivedPackets(media_packet_list_, media_loss_mask_, false); |
281 ReceivedPackets(fec_packet_list_, fec_loss_mask_, true); | 281 ReceivedPackets(fec_packet_list_, fec_loss_mask_, true); |
282 | 282 |
283 EXPECT_EQ(0, | 283 EXPECT_EQ(0, |
284 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); | 284 fec_.DecodeFec(&received_packet_list_, &recovered_packet_list_)); |
285 | 285 |
286 // The two FEC packets are received and should allow for complete recovery, | 286 // The two FEC packets are received and should allow for complete recovery, |
287 // but because of the wrap the second FEC packet will be discarded, and only | 287 // but because of the wrap the second FEC packet will be discarded, and only |
288 // one media packet is recoverable. So exepct 2 media packets on recovered | 288 // one media packet is recoverable. So exepct 2 media packets on recovered |
289 // list and no complete recovery. | 289 // list and no complete recovery. |
290 EXPECT_EQ(2, static_cast<int>(recovered_packet_list_.size())); | 290 EXPECT_EQ(2u, recovered_packet_list_.size()); |
291 EXPECT_TRUE(recovered_packet_list_.size() != media_packet_list_.size()); | 291 EXPECT_TRUE(recovered_packet_list_.size() != media_packet_list_.size()); |
292 EXPECT_FALSE(IsRecoveryComplete()); | 292 EXPECT_FALSE(IsRecoveryComplete()); |
293 FreeRecoveredPacketList(); | 293 FreeRecoveredPacketList(); |
294 } | 294 } |
295 | 295 |
296 // Verify we can still recovery frame if FEC is received before media packets. | 296 // Verify we can still recover frame if media packets are reordered. |
297 TEST_F(RtpFecTest, FecRecoveryWithFecOutOfOrder) { | 297 TEST_F(RtpFecTest, FecRecoveryWithMediaOutOfOrder) { |
298 const int kNumImportantPackets = 0; | 298 constexpr int kNumImportantPackets = 0; |
299 const bool kUseUnequalProtection = false; | 299 constexpr bool kUseUnequalProtection = false; |
300 uint8_t kProtectionFactor = 20; | 300 constexpr uint8_t kProtectionFactor = 20; |
301 | 301 |
302 // One frame: 3 media packets, 1 FEC packet. | 302 // One frame: 3 media packets, 1 FEC packet. |
303 // -----Frame 1---- | 303 // -----Frame 1---- |
304 // #0(media) #1(media) #2(media) #3(FEC). | 304 // #0(media) #1(media) #2(media) #3(FEC). |
305 fec_seq_num_ = ConstructMediaPacketsSeqNum(3, 0); | 305 fec_seq_num_ = ConstructMediaPacketsSeqNum(3, 0); |
306 | 306 |
307 EXPECT_EQ(0, fec_->GenerateFec(media_packet_list_, kProtectionFactor, | 307 EXPECT_EQ(0, fec_.GenerateFec(media_packet_list_, kProtectionFactor, |
308 kNumImportantPackets, kUseUnequalProtection, | 308 kNumImportantPackets, kUseUnequalProtection, |
309 webrtc::kFecMaskBursty, &fec_packet_list_)); | 309 webrtc::kFecMaskBursty, &fec_packet_list_)); |
310 | 310 |
311 // Expect 1 FEC packet. | 311 // Expect 1 FEC packet. |
312 EXPECT_EQ(1, static_cast<int>(fec_packet_list_.size())); | 312 EXPECT_EQ(1u, fec_packet_list_.size()); |
313 | 313 |
314 // Lose one media packet (seq# 1). | 314 // Lose one media packet (seq# 1). |
315 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 315 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
316 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | |
317 media_loss_mask_[1] = 1; | |
318 NetworkReceivedPackets(media_loss_mask_, fec_loss_mask_); | |
319 | |
320 // Reorder received media packets. | |
321 auto it0 = received_packet_list_.begin(); | |
322 auto it2 = received_packet_list_.begin(); | |
323 it2++; | |
324 std::swap(*it0, *it2); | |
325 | |
326 EXPECT_EQ(0, | |
327 fec_.DecodeFec(&received_packet_list_, &recovered_packet_list_)); | |
328 | |
329 // Expect 3 media packets in recovered list, and complete recovery. | |
330 EXPECT_EQ(3u, recovered_packet_list_.size()); | |
331 EXPECT_TRUE(IsRecoveryComplete()); | |
332 } | |
333 | |
334 // Verify we can still recover frame if FEC is received before media packets. | |
335 TEST_F(RtpFecTest, FecRecoveryWithFecOutOfOrder) { | |
336 constexpr int kNumImportantPackets = 0; | |
337 constexpr bool kUseUnequalProtection = false; | |
338 constexpr uint8_t kProtectionFactor = 20; | |
339 | |
340 // One frame: 3 media packets, 1 FEC packet. | |
341 // -----Frame 1---- | |
342 // #0(media) #1(media) #2(media) #3(FEC). | |
343 fec_seq_num_ = ConstructMediaPacketsSeqNum(3, 0); | |
344 | |
345 EXPECT_EQ(0, fec_.GenerateFec(media_packet_list_, kProtectionFactor, | |
346 kNumImportantPackets, kUseUnequalProtection, | |
347 webrtc::kFecMaskBursty, &fec_packet_list_)); | |
348 | |
349 // Expect 1 FEC packet. | |
350 EXPECT_EQ(1u, fec_packet_list_.size()); | |
351 | |
352 // Lose one media packet (seq# 1). | |
353 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | |
316 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 354 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
317 media_loss_mask_[1] = 1; | 355 media_loss_mask_[1] = 1; |
318 // Add FEC packet to received list before the media packets. | 356 // Add FEC packet to received list before the media packets. |
319 ReceivedPackets(fec_packet_list_, fec_loss_mask_, true); | 357 ReceivedPackets(fec_packet_list_, fec_loss_mask_, true); |
320 // Add media packets to received list. | 358 // Add media packets to received list. |
321 ReceivedPackets(media_packet_list_, media_loss_mask_, false); | 359 ReceivedPackets(media_packet_list_, media_loss_mask_, false); |
322 | 360 |
323 EXPECT_EQ(0, | 361 EXPECT_EQ(0, |
324 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); | 362 fec_.DecodeFec(&received_packet_list_, &recovered_packet_list_)); |
325 | 363 |
326 // Expect 3 media packets in recovered list, and complete recovery. | 364 // Expect 3 media packets in recovered list, and complete recovery. |
327 EXPECT_EQ(3, static_cast<int>(recovered_packet_list_.size())); | 365 EXPECT_EQ(3u, recovered_packet_list_.size()); |
328 EXPECT_TRUE(IsRecoveryComplete()); | 366 EXPECT_TRUE(IsRecoveryComplete()); |
329 FreeRecoveredPacketList(); | 367 FreeRecoveredPacketList(); |
330 } | 368 } |
331 | 369 |
332 // Test 50% protection with random mask type: Two cases are considered: | 370 // Test 50% protection with random mask type: Two cases are considered: |
333 // a 50% non-consecutive loss which can be fully recovered, and a 50% | 371 // a 50% non-consecutive loss which can be fully recovered, and a 50% |
334 // consecutive loss which cannot be fully recovered. | 372 // consecutive loss which cannot be fully recovered. |
335 TEST_F(RtpFecTest, FecRecoveryWithLoss50percRandomMask) { | 373 TEST_F(RtpFecTest, FecRecoveryWithLoss50percRandomMask) { |
336 const int kNumImportantPackets = 0; | 374 constexpr int kNumImportantPackets = 0; |
337 const bool kUseUnequalProtection = false; | 375 constexpr bool kUseUnequalProtection = false; |
338 const int kNumMediaPackets = 4; | 376 constexpr int kNumMediaPackets = 4; |
339 const uint8_t kProtectionFactor = 255; | 377 constexpr uint8_t kProtectionFactor = 255; |
340 | 378 |
341 // Packet Mask for (4,4,0) code, from random mask table. | 379 // Packet Mask for (4,4,0) code, from random mask table. |
342 // (kNumMediaPackets = 4; num_fec_packets = 4, kNumImportantPackets = 0) | 380 // (kNumMediaPackets = 4; num_fec_packets = 4, kNumImportantPackets = 0) |
343 | 381 |
344 // media#0 media#1 media#2 media#3 | 382 // media#0 media#1 media#2 media#3 |
345 // fec#0: 1 1 0 0 | 383 // fec#0: 1 1 0 0 |
346 // fec#1: 1 0 1 0 | 384 // fec#1: 1 0 1 0 |
347 // fec#2: 0 0 1 1 | 385 // fec#2: 0 0 1 1 |
348 // fec#3: 0 1 0 1 | 386 // fec#3: 0 1 0 1 |
349 // | 387 // |
350 | 388 |
351 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); | 389 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); |
352 | 390 |
353 EXPECT_EQ(0, fec_->GenerateFec(media_packet_list_, kProtectionFactor, | 391 EXPECT_EQ(0, fec_.GenerateFec(media_packet_list_, kProtectionFactor, |
354 kNumImportantPackets, kUseUnequalProtection, | 392 kNumImportantPackets, kUseUnequalProtection, |
355 webrtc::kFecMaskRandom, &fec_packet_list_)); | 393 webrtc::kFecMaskRandom, &fec_packet_list_)); |
356 | 394 |
357 // Expect 4 FEC packets. | 395 // Expect 4 FEC packets. |
358 EXPECT_EQ(4, static_cast<int>(fec_packet_list_.size())); | 396 EXPECT_EQ(4u, fec_packet_list_.size()); |
359 | 397 |
360 // 4 packets lost: 3 media packets (0, 2, 3), and one FEC packet (0) lost. | 398 // 4 packets lost: 3 media packets (0, 2, 3), and one FEC packet (0) lost. |
361 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 399 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
362 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 400 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
363 fec_loss_mask_[0] = 1; | 401 fec_loss_mask_[0] = 1; |
364 media_loss_mask_[0] = 1; | 402 media_loss_mask_[0] = 1; |
365 media_loss_mask_[2] = 1; | 403 media_loss_mask_[2] = 1; |
366 media_loss_mask_[3] = 1; | 404 media_loss_mask_[3] = 1; |
367 NetworkReceivedPackets(); | 405 NetworkReceivedPackets(media_loss_mask_, fec_loss_mask_); |
368 | 406 |
369 EXPECT_EQ(0, | 407 EXPECT_EQ(0, |
370 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); | 408 fec_.DecodeFec(&received_packet_list_, &recovered_packet_list_)); |
371 | 409 |
372 // With media packet#1 and FEC packets #1, #2, #3, expect complete recovery. | 410 // With media packet#1 and FEC packets #1, #2, #3, expect complete recovery. |
373 EXPECT_TRUE(IsRecoveryComplete()); | 411 EXPECT_TRUE(IsRecoveryComplete()); |
374 FreeRecoveredPacketList(); | 412 FreeRecoveredPacketList(); |
375 | 413 |
376 // 4 consecutive packets lost: media packets 0, 1, 2, 3. | 414 // 4 consecutive packets lost: media packets 0, 1, 2, 3. |
377 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 415 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
378 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 416 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
379 media_loss_mask_[0] = 1; | 417 media_loss_mask_[0] = 1; |
380 media_loss_mask_[1] = 1; | 418 media_loss_mask_[1] = 1; |
381 media_loss_mask_[2] = 1; | 419 media_loss_mask_[2] = 1; |
382 media_loss_mask_[3] = 1; | 420 media_loss_mask_[3] = 1; |
383 NetworkReceivedPackets(); | 421 NetworkReceivedPackets(media_loss_mask_, fec_loss_mask_); |
384 | 422 |
385 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 423 EXPECT_EQ(0, fec_.DecodeFec(&received_packet_list_, |
386 &recovered_packet_list_)); | 424 &recovered_packet_list_)); |
387 | 425 |
388 // Cannot get complete recovery for this loss configuration with random mask. | 426 // Cannot get complete recovery for this loss configuration with random mask. |
389 EXPECT_FALSE(IsRecoveryComplete()); | 427 EXPECT_FALSE(IsRecoveryComplete()); |
390 } | 428 } |
391 | 429 |
392 // Test 50% protection with bursty type: Three cases are considered: | 430 // Test 50% protection with bursty type: Three cases are considered: |
393 // two 50% consecutive losses which can be fully recovered, and one | 431 // two 50% consecutive losses which can be fully recovered, and one |
394 // non-consecutive which cannot be fully recovered. | 432 // non-consecutive which cannot be fully recovered. |
395 TEST_F(RtpFecTest, FecRecoveryWithLoss50percBurstyMask) { | 433 TEST_F(RtpFecTest, FecRecoveryWithLoss50percBurstyMask) { |
396 const int kNumImportantPackets = 0; | 434 constexpr int kNumImportantPackets = 0; |
397 const bool kUseUnequalProtection = false; | 435 constexpr bool kUseUnequalProtection = false; |
398 const int kNumMediaPackets = 4; | 436 constexpr int kNumMediaPackets = 4; |
399 const uint8_t kProtectionFactor = 255; | 437 constexpr uint8_t kProtectionFactor = 255; |
400 | 438 |
401 // Packet Mask for (4,4,0) code, from bursty mask table. | 439 // Packet Mask for (4,4,0) code, from bursty mask table. |
402 // (kNumMediaPackets = 4; num_fec_packets = 4, kNumImportantPackets = 0) | 440 // (kNumMediaPackets = 4; num_fec_packets = 4, kNumImportantPackets = 0) |
403 | 441 |
404 // media#0 media#1 media#2 media#3 | 442 // media#0 media#1 media#2 media#3 |
405 // fec#0: 1 0 0 0 | 443 // fec#0: 1 0 0 0 |
406 // fec#1: 1 1 0 0 | 444 // fec#1: 1 1 0 0 |
407 // fec#2: 0 1 1 0 | 445 // fec#2: 0 1 1 0 |
408 // fec#3: 0 0 1 1 | 446 // fec#3: 0 0 1 1 |
409 // | 447 // |
410 | 448 |
411 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); | 449 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); |
412 | 450 |
413 EXPECT_EQ(0, fec_->GenerateFec(media_packet_list_, kProtectionFactor, | 451 EXPECT_EQ(0, fec_.GenerateFec(media_packet_list_, kProtectionFactor, |
414 kNumImportantPackets, kUseUnequalProtection, | 452 kNumImportantPackets, kUseUnequalProtection, |
415 webrtc::kFecMaskBursty, &fec_packet_list_)); | 453 webrtc::kFecMaskBursty, &fec_packet_list_)); |
416 | 454 |
417 // Expect 4 FEC packets. | 455 // Expect 4 FEC packets. |
418 EXPECT_EQ(4, static_cast<int>(fec_packet_list_.size())); | 456 EXPECT_EQ(4u, fec_packet_list_.size()); |
419 | 457 |
420 // 4 consecutive packets lost: media packets 0,1,2,3. | 458 // 4 consecutive packets lost: media packets 0,1,2,3. |
421 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 459 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
422 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 460 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
423 media_loss_mask_[0] = 1; | 461 media_loss_mask_[0] = 1; |
424 media_loss_mask_[1] = 1; | 462 media_loss_mask_[1] = 1; |
425 media_loss_mask_[2] = 1; | 463 media_loss_mask_[2] = 1; |
426 media_loss_mask_[3] = 1; | 464 media_loss_mask_[3] = 1; |
427 NetworkReceivedPackets(); | 465 NetworkReceivedPackets(media_loss_mask_, fec_loss_mask_); |
428 | 466 |
429 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 467 EXPECT_EQ(0, fec_.DecodeFec(&received_packet_list_, |
430 &recovered_packet_list_)); | 468 &recovered_packet_list_)); |
431 | 469 |
432 // Expect complete recovery for consecutive packet loss <= 50%. | 470 // Expect complete recovery for consecutive packet loss <= 50%. |
433 EXPECT_TRUE(IsRecoveryComplete()); | 471 EXPECT_TRUE(IsRecoveryComplete()); |
434 FreeRecoveredPacketList(); | 472 FreeRecoveredPacketList(); |
435 | 473 |
436 // 4 consecutive packets lost: media packets 1,2, 3, and FEC packet 0. | 474 // 4 consecutive packets lost: media packets 1,2, 3, and FEC packet 0. |
437 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 475 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
438 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 476 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
439 fec_loss_mask_[0] = 1; | 477 fec_loss_mask_[0] = 1; |
440 media_loss_mask_[1] = 1; | 478 media_loss_mask_[1] = 1; |
441 media_loss_mask_[2] = 1; | 479 media_loss_mask_[2] = 1; |
442 media_loss_mask_[3] = 1; | 480 media_loss_mask_[3] = 1; |
443 NetworkReceivedPackets(); | 481 NetworkReceivedPackets(media_loss_mask_, fec_loss_mask_); |
444 | 482 |
445 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 483 EXPECT_EQ(0, fec_.DecodeFec(&received_packet_list_, |
446 &recovered_packet_list_)); | 484 &recovered_packet_list_)); |
447 | 485 |
448 // Expect complete recovery for consecutive packet loss <= 50%. | 486 // Expect complete recovery for consecutive packet loss <= 50%. |
449 EXPECT_TRUE(IsRecoveryComplete()); | 487 EXPECT_TRUE(IsRecoveryComplete()); |
450 FreeRecoveredPacketList(); | 488 FreeRecoveredPacketList(); |
451 | 489 |
452 // 4 packets lost (non-consecutive loss): media packets 0, 3, and FEC# 0, 3. | 490 // 4 packets lost (non-consecutive loss): media packets 0, 3, and FEC# 0, 3. |
453 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 491 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
454 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 492 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
455 fec_loss_mask_[0] = 1; | 493 fec_loss_mask_[0] = 1; |
456 fec_loss_mask_[3] = 1; | 494 fec_loss_mask_[3] = 1; |
457 media_loss_mask_[0] = 1; | 495 media_loss_mask_[0] = 1; |
458 media_loss_mask_[3] = 1; | 496 media_loss_mask_[3] = 1; |
459 NetworkReceivedPackets(); | 497 NetworkReceivedPackets(media_loss_mask_, fec_loss_mask_); |
460 | 498 |
461 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 499 EXPECT_EQ(0, fec_.DecodeFec(&received_packet_list_, |
462 &recovered_packet_list_)); | 500 &recovered_packet_list_)); |
463 | 501 |
464 // Cannot get complete recovery for this loss configuration. | 502 // Cannot get complete recovery for this loss configuration. |
465 EXPECT_FALSE(IsRecoveryComplete()); | 503 EXPECT_FALSE(IsRecoveryComplete()); |
466 } | 504 } |
467 | 505 |
468 TEST_F(RtpFecTest, FecRecoveryNoLossUep) { | 506 TEST_F(RtpFecTest, FecRecoveryNoLossUep) { |
469 const int kNumImportantPackets = 2; | 507 constexpr int kNumImportantPackets = 2; |
470 const bool kUseUnequalProtection = true; | 508 constexpr bool kUseUnequalProtection = true; |
471 const int kNumMediaPackets = 4; | 509 constexpr int kNumMediaPackets = 4; |
472 const uint8_t kProtectionFactor = 60; | 510 constexpr uint8_t kProtectionFactor = 60; |
473 | 511 |
474 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); | 512 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); |
475 | 513 |
476 EXPECT_EQ(0, fec_->GenerateFec(media_packet_list_, kProtectionFactor, | 514 EXPECT_EQ(0, fec_.GenerateFec(media_packet_list_, kProtectionFactor, |
477 kNumImportantPackets, kUseUnequalProtection, | 515 kNumImportantPackets, kUseUnequalProtection, |
478 webrtc::kFecMaskBursty, &fec_packet_list_)); | 516 webrtc::kFecMaskBursty, &fec_packet_list_)); |
479 | 517 |
480 // Expect 1 FEC packet. | 518 // Expect 1 FEC packet. |
481 EXPECT_EQ(1, static_cast<int>(fec_packet_list_.size())); | 519 EXPECT_EQ(1u, fec_packet_list_.size()); |
482 | 520 |
483 // No packets lost. | 521 // No packets lost. |
484 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 522 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
485 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 523 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
486 NetworkReceivedPackets(); | 524 NetworkReceivedPackets(media_loss_mask_, fec_loss_mask_); |
487 | 525 |
488 EXPECT_EQ(0, | 526 EXPECT_EQ(0, |
489 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); | 527 fec_.DecodeFec(&received_packet_list_, &recovered_packet_list_)); |
490 | 528 |
491 // No packets lost, expect complete recovery. | 529 // No packets lost, expect complete recovery. |
492 EXPECT_TRUE(IsRecoveryComplete()); | 530 EXPECT_TRUE(IsRecoveryComplete()); |
493 } | 531 } |
494 | 532 |
495 TEST_F(RtpFecTest, FecRecoveryWithLossUep) { | 533 TEST_F(RtpFecTest, FecRecoveryWithLossUep) { |
496 const int kNumImportantPackets = 2; | 534 constexpr int kNumImportantPackets = 2; |
497 const bool kUseUnequalProtection = true; | 535 constexpr bool kUseUnequalProtection = true; |
498 const int kNumMediaPackets = 4; | 536 constexpr int kNumMediaPackets = 4; |
499 const uint8_t kProtectionFactor = 60; | 537 constexpr uint8_t kProtectionFactor = 60; |
500 | 538 |
501 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); | 539 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); |
502 | 540 |
503 EXPECT_EQ(0, fec_->GenerateFec(media_packet_list_, kProtectionFactor, | 541 EXPECT_EQ(0, fec_.GenerateFec(media_packet_list_, kProtectionFactor, |
504 kNumImportantPackets, kUseUnequalProtection, | 542 kNumImportantPackets, kUseUnequalProtection, |
505 webrtc::kFecMaskBursty, &fec_packet_list_)); | 543 webrtc::kFecMaskBursty, &fec_packet_list_)); |
506 | 544 |
507 // Expect 1 FEC packet. | 545 // Expect 1 FEC packet. |
508 EXPECT_EQ(1, static_cast<int>(fec_packet_list_.size())); | 546 EXPECT_EQ(1u, fec_packet_list_.size()); |
509 | 547 |
510 // 1 media packet lost. | 548 // 1 media packet lost. |
511 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 549 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
512 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 550 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
513 media_loss_mask_[3] = 1; | 551 media_loss_mask_[3] = 1; |
514 NetworkReceivedPackets(); | 552 NetworkReceivedPackets(media_loss_mask_, fec_loss_mask_); |
515 | 553 |
516 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 554 EXPECT_EQ(0, fec_.DecodeFec(&received_packet_list_, |
517 &recovered_packet_list_)); | 555 &recovered_packet_list_)); |
518 | 556 |
519 // One packet lost, one FEC packet, expect complete recovery. | 557 // One packet lost, one FEC packet, expect complete recovery. |
520 EXPECT_TRUE(IsRecoveryComplete()); | 558 EXPECT_TRUE(IsRecoveryComplete()); |
521 FreeRecoveredPacketList(); | 559 FreeRecoveredPacketList(); |
522 | 560 |
523 // 2 media packets lost. | 561 // 2 media packets lost. |
524 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 562 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
525 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 563 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
526 media_loss_mask_[1] = 1; | 564 media_loss_mask_[1] = 1; |
527 media_loss_mask_[3] = 1; | 565 media_loss_mask_[3] = 1; |
528 NetworkReceivedPackets(); | 566 NetworkReceivedPackets(media_loss_mask_, fec_loss_mask_); |
529 | 567 |
530 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 568 EXPECT_EQ(0, fec_.DecodeFec(&received_packet_list_, |
531 &recovered_packet_list_)); | 569 &recovered_packet_list_)); |
532 | 570 |
533 // 2 packets lost, one FEC packet, cannot get complete recovery. | 571 // 2 packets lost, one FEC packet, cannot get complete recovery. |
534 EXPECT_FALSE(IsRecoveryComplete()); | 572 EXPECT_FALSE(IsRecoveryComplete()); |
535 } | 573 } |
536 | 574 |
537 // Test 50% protection with random mask type for UEP on. | 575 // Test 50% protection with random mask type for UEP on. |
538 TEST_F(RtpFecTest, FecRecoveryWithLoss50percUepRandomMask) { | 576 TEST_F(RtpFecTest, FecRecoveryWithLoss50percUepRandomMask) { |
539 const int kNumImportantPackets = 1; | 577 constexpr int kNumImportantPackets = 1; |
540 const bool kUseUnequalProtection = true; | 578 constexpr bool kUseUnequalProtection = true; |
541 const int kNumMediaPackets = 4; | 579 constexpr int kNumMediaPackets = 4; |
542 const uint8_t kProtectionFactor = 255; | 580 constexpr uint8_t kProtectionFactor = 255; |
543 | 581 |
544 // Packet Mask for (4,4,1) code, from random mask table. | 582 // Packet Mask for (4,4,1) code, from random mask table. |
545 // (kNumMediaPackets = 4; num_fec_packets = 4, kNumImportantPackets = 1) | 583 // (kNumMediaPackets = 4; num_fec_packets = 4, kNumImportantPackets = 1) |
546 | 584 |
547 // media#0 media#1 media#2 media#3 | 585 // media#0 media#1 media#2 media#3 |
548 // fec#0: 1 0 0 0 | 586 // fec#0: 1 0 0 0 |
549 // fec#1: 1 1 0 0 | 587 // fec#1: 1 1 0 0 |
550 // fec#2: 1 0 1 1 | 588 // fec#2: 1 0 1 1 |
551 // fec#3: 0 1 1 0 | 589 // fec#3: 0 1 1 0 |
552 // | 590 // |
553 | 591 |
554 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); | 592 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); |
555 | 593 |
556 EXPECT_EQ(0, fec_->GenerateFec(media_packet_list_, kProtectionFactor, | 594 EXPECT_EQ(0, fec_.GenerateFec(media_packet_list_, kProtectionFactor, |
557 kNumImportantPackets, kUseUnequalProtection, | 595 kNumImportantPackets, kUseUnequalProtection, |
558 webrtc::kFecMaskRandom, &fec_packet_list_)); | 596 webrtc::kFecMaskRandom, &fec_packet_list_)); |
559 | 597 |
560 // Expect 4 FEC packets. | 598 // Expect 4 FEC packets. |
561 EXPECT_EQ(4, static_cast<int>(fec_packet_list_.size())); | 599 EXPECT_EQ(4u, fec_packet_list_.size()); |
562 | 600 |
563 // 4 packets lost: 3 media packets and FEC packet#1 lost. | 601 // 4 packets lost: 3 media packets and FEC packet#1 lost. |
564 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 602 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
565 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 603 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
566 fec_loss_mask_[1] = 1; | 604 fec_loss_mask_[1] = 1; |
567 media_loss_mask_[0] = 1; | 605 media_loss_mask_[0] = 1; |
568 media_loss_mask_[2] = 1; | 606 media_loss_mask_[2] = 1; |
569 media_loss_mask_[3] = 1; | 607 media_loss_mask_[3] = 1; |
570 NetworkReceivedPackets(); | 608 NetworkReceivedPackets(media_loss_mask_, fec_loss_mask_); |
571 | 609 |
572 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 610 EXPECT_EQ(0, fec_.DecodeFec(&received_packet_list_, |
573 &recovered_packet_list_)); | 611 &recovered_packet_list_)); |
574 | 612 |
575 // With media packet#3 and FEC packets #0, #1, #3, expect complete recovery. | 613 // With media packet#3 and FEC packets #0, #1, #3, expect complete recovery. |
576 EXPECT_TRUE(IsRecoveryComplete()); | 614 EXPECT_TRUE(IsRecoveryComplete()); |
577 FreeRecoveredPacketList(); | 615 FreeRecoveredPacketList(); |
578 | 616 |
579 // 5 packets lost: 4 media packets and one FEC packet#2 lost. | 617 // 5 packets lost: 4 media packets and one FEC packet#2 lost. |
580 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 618 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
581 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 619 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
582 fec_loss_mask_[2] = 1; | 620 fec_loss_mask_[2] = 1; |
583 media_loss_mask_[0] = 1; | 621 media_loss_mask_[0] = 1; |
584 media_loss_mask_[1] = 1; | 622 media_loss_mask_[1] = 1; |
585 media_loss_mask_[2] = 1; | 623 media_loss_mask_[2] = 1; |
586 media_loss_mask_[3] = 1; | 624 media_loss_mask_[3] = 1; |
587 NetworkReceivedPackets(); | 625 NetworkReceivedPackets(media_loss_mask_, fec_loss_mask_); |
588 | 626 |
589 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 627 EXPECT_EQ(0, fec_.DecodeFec(&received_packet_list_, |
590 &recovered_packet_list_)); | 628 &recovered_packet_list_)); |
591 | 629 |
592 // Cannot get complete recovery for this loss configuration. | 630 // Cannot get complete recovery for this loss configuration. |
593 EXPECT_FALSE(IsRecoveryComplete()); | 631 EXPECT_FALSE(IsRecoveryComplete()); |
594 } | 632 } |
595 | 633 |
596 TEST_F(RtpFecTest, FecRecoveryNonConsecutivePackets) { | 634 TEST_F(RtpFecTest, FecRecoveryNonConsecutivePackets) { |
597 const int kNumImportantPackets = 0; | 635 constexpr int kNumImportantPackets = 0; |
598 const bool kUseUnequalProtection = false; | 636 constexpr bool kUseUnequalProtection = false; |
599 const int kNumMediaPackets = 5; | 637 constexpr int kNumMediaPackets = 5; |
600 uint8_t kProtectionFactor = 60; | 638 constexpr uint8_t kProtectionFactor = 60; |
601 | 639 |
602 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); | 640 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); |
603 | 641 |
604 // Create a new temporary packet list for generating FEC packets. | 642 // Create a new temporary packet list for generating FEC packets. |
605 // This list should have every other packet removed. | 643 // This list should have every other packet removed. |
606 PacketList protected_media_packets; | 644 PacketList protected_media_packets; |
607 int i = 0; | 645 int i = 0; |
608 for (auto it = media_packet_list_.begin(); it != media_packet_list_.end(); | 646 for (auto it = media_packet_list_.begin(); it != media_packet_list_.end(); |
609 ++it, ++i) { | 647 ++it, ++i) { |
610 if (i % 2 == 0) protected_media_packets.push_back(*it); | 648 if (i % 2 == 0) protected_media_packets.push_back(*it); |
611 } | 649 } |
612 | 650 |
613 EXPECT_EQ(0, fec_->GenerateFec(protected_media_packets, kProtectionFactor, | 651 EXPECT_EQ(0, fec_.GenerateFec(protected_media_packets, kProtectionFactor, |
614 kNumImportantPackets, kUseUnequalProtection, | 652 kNumImportantPackets, kUseUnequalProtection, |
615 webrtc::kFecMaskBursty, &fec_packet_list_)); | 653 webrtc::kFecMaskBursty, &fec_packet_list_)); |
616 | 654 |
617 // Expect 1 FEC packet. | 655 // Expect 1 FEC packet. |
618 EXPECT_EQ(1, static_cast<int>(fec_packet_list_.size())); | 656 EXPECT_EQ(1u, fec_packet_list_.size()); |
619 | 657 |
620 // 1 protected media packet lost | 658 // 1 protected media packet lost |
621 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 659 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
622 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 660 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
623 media_loss_mask_[2] = 1; | 661 media_loss_mask_[2] = 1; |
624 NetworkReceivedPackets(); | 662 NetworkReceivedPackets(media_loss_mask_, fec_loss_mask_); |
625 | 663 |
626 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 664 EXPECT_EQ(0, fec_.DecodeFec(&received_packet_list_, |
627 &recovered_packet_list_)); | 665 &recovered_packet_list_)); |
628 | 666 |
629 // One packet lost, one FEC packet, expect complete recovery. | 667 // One packet lost, one FEC packet, expect complete recovery. |
630 EXPECT_TRUE(IsRecoveryComplete()); | 668 EXPECT_TRUE(IsRecoveryComplete()); |
631 FreeRecoveredPacketList(); | 669 FreeRecoveredPacketList(); |
632 | 670 |
633 // Unprotected packet lost. | 671 // Unprotected packet lost. |
634 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 672 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
635 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 673 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
636 media_loss_mask_[1] = 1; | 674 media_loss_mask_[1] = 1; |
637 NetworkReceivedPackets(); | 675 NetworkReceivedPackets(media_loss_mask_, fec_loss_mask_); |
638 | 676 |
639 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 677 EXPECT_EQ(0, fec_.DecodeFec(&received_packet_list_, |
640 &recovered_packet_list_)); | 678 &recovered_packet_list_)); |
641 | 679 |
642 // Unprotected packet lost. Recovery not possible. | 680 // Unprotected packet lost. Recovery not possible. |
643 EXPECT_FALSE(IsRecoveryComplete()); | 681 EXPECT_FALSE(IsRecoveryComplete()); |
644 FreeRecoveredPacketList(); | 682 FreeRecoveredPacketList(); |
645 | 683 |
646 // 2 media packets lost. | 684 // 2 media packets lost. |
647 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 685 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
648 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 686 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
649 media_loss_mask_[0] = 1; | 687 media_loss_mask_[0] = 1; |
650 media_loss_mask_[2] = 1; | 688 media_loss_mask_[2] = 1; |
651 NetworkReceivedPackets(); | 689 NetworkReceivedPackets(media_loss_mask_, fec_loss_mask_); |
652 | 690 |
653 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 691 EXPECT_EQ(0, fec_.DecodeFec(&received_packet_list_, |
654 &recovered_packet_list_)); | 692 &recovered_packet_list_)); |
655 | 693 |
656 // 2 protected packets lost, one FEC packet, cannot get complete recovery. | 694 // 2 protected packets lost, one FEC packet, cannot get complete recovery. |
657 EXPECT_FALSE(IsRecoveryComplete()); | 695 EXPECT_FALSE(IsRecoveryComplete()); |
658 } | 696 } |
659 | 697 |
660 TEST_F(RtpFecTest, FecRecoveryNonConsecutivePacketsExtension) { | 698 TEST_F(RtpFecTest, FecRecoveryNonConsecutivePacketsExtension) { |
661 const int kNumImportantPackets = 0; | 699 constexpr int kNumImportantPackets = 0; |
662 const bool kUseUnequalProtection = false; | 700 constexpr bool kUseUnequalProtection = false; |
663 const int kNumMediaPackets = 21; | 701 constexpr int kNumMediaPackets = 21; |
664 uint8_t kProtectionFactor = 127; | 702 uint8_t kProtectionFactor = 127; |
665 | 703 |
666 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); | 704 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); |
667 | 705 |
668 // Create a new temporary packet list for generating FEC packets. | 706 // Create a new temporary packet list for generating FEC packets. |
669 // This list should have every other packet removed. | 707 // This list should have every other packet removed. |
670 PacketList protected_media_packets; | 708 PacketList protected_media_packets; |
671 int i = 0; | 709 int i = 0; |
672 for (auto it = media_packet_list_.begin(); it != media_packet_list_.end(); | 710 for (auto it = media_packet_list_.begin(); it != media_packet_list_.end(); |
673 ++it, ++i) { | 711 ++it, ++i) { |
674 if (i % 2 == 0) protected_media_packets.push_back(*it); | 712 if (i % 2 == 0) protected_media_packets.push_back(*it); |
675 } | 713 } |
676 | 714 |
677 // Zero column insertion will have to extend the size of the packet | 715 // Zero column insertion will have to extend the size of the packet |
678 // mask since the number of actual packets are 21, while the number | 716 // mask since the number of actual packets are 21, while the number |
679 // of protected packets are 11. | 717 // of protected packets are 11. |
680 EXPECT_EQ(0, fec_->GenerateFec(protected_media_packets, kProtectionFactor, | 718 EXPECT_EQ(0, fec_.GenerateFec(protected_media_packets, kProtectionFactor, |
681 kNumImportantPackets, kUseUnequalProtection, | 719 kNumImportantPackets, kUseUnequalProtection, |
682 webrtc::kFecMaskBursty, &fec_packet_list_)); | 720 webrtc::kFecMaskBursty, &fec_packet_list_)); |
683 | 721 |
684 // Expect 5 FEC packet. | 722 // Expect 5 FEC packet. |
685 EXPECT_EQ(5, static_cast<int>(fec_packet_list_.size())); | 723 EXPECT_EQ(5u, fec_packet_list_.size()); |
686 | 724 |
687 // Last protected media packet lost | 725 // Last protected media packet lost |
688 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 726 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
689 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 727 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
690 media_loss_mask_[kNumMediaPackets - 1] = 1; | 728 media_loss_mask_[kNumMediaPackets - 1] = 1; |
691 NetworkReceivedPackets(); | 729 NetworkReceivedPackets(media_loss_mask_, fec_loss_mask_); |
692 | 730 |
693 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 731 EXPECT_EQ(0, fec_.DecodeFec(&received_packet_list_, |
694 &recovered_packet_list_)); | 732 &recovered_packet_list_)); |
695 | 733 |
696 // One packet lost, one FEC packet, expect complete recovery. | 734 // One packet lost, one FEC packet, expect complete recovery. |
697 EXPECT_TRUE(IsRecoveryComplete()); | 735 EXPECT_TRUE(IsRecoveryComplete()); |
698 FreeRecoveredPacketList(); | 736 FreeRecoveredPacketList(); |
699 | 737 |
700 // Last unprotected packet lost. | 738 // Last unprotected packet lost. |
701 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 739 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
702 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 740 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
703 media_loss_mask_[kNumMediaPackets - 2] = 1; | 741 media_loss_mask_[kNumMediaPackets - 2] = 1; |
704 NetworkReceivedPackets(); | 742 NetworkReceivedPackets(media_loss_mask_, fec_loss_mask_); |
705 | 743 |
706 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 744 EXPECT_EQ(0, fec_.DecodeFec(&received_packet_list_, |
707 &recovered_packet_list_)); | 745 &recovered_packet_list_)); |
708 | 746 |
709 // Unprotected packet lost. Recovery not possible. | 747 // Unprotected packet lost. Recovery not possible. |
710 EXPECT_FALSE(IsRecoveryComplete()); | 748 EXPECT_FALSE(IsRecoveryComplete()); |
711 FreeRecoveredPacketList(); | 749 FreeRecoveredPacketList(); |
712 | 750 |
713 // 6 media packets lost. | 751 // 6 media packets lost. |
714 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 752 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
715 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 753 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
716 media_loss_mask_[kNumMediaPackets - 11] = 1; | 754 media_loss_mask_[kNumMediaPackets - 11] = 1; |
717 media_loss_mask_[kNumMediaPackets - 9] = 1; | 755 media_loss_mask_[kNumMediaPackets - 9] = 1; |
718 media_loss_mask_[kNumMediaPackets - 7] = 1; | 756 media_loss_mask_[kNumMediaPackets - 7] = 1; |
719 media_loss_mask_[kNumMediaPackets - 5] = 1; | 757 media_loss_mask_[kNumMediaPackets - 5] = 1; |
720 media_loss_mask_[kNumMediaPackets - 3] = 1; | 758 media_loss_mask_[kNumMediaPackets - 3] = 1; |
721 media_loss_mask_[kNumMediaPackets - 1] = 1; | 759 media_loss_mask_[kNumMediaPackets - 1] = 1; |
722 NetworkReceivedPackets(); | 760 NetworkReceivedPackets(media_loss_mask_, fec_loss_mask_); |
723 | 761 |
724 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 762 EXPECT_EQ(0, fec_.DecodeFec(&received_packet_list_, |
725 &recovered_packet_list_)); | 763 &recovered_packet_list_)); |
726 | 764 |
727 // 5 protected packets lost, one FEC packet, cannot get complete recovery. | 765 // 5 protected packets lost, one FEC packet, cannot get complete recovery. |
728 EXPECT_FALSE(IsRecoveryComplete()); | 766 EXPECT_FALSE(IsRecoveryComplete()); |
729 } | 767 } |
730 | 768 |
731 TEST_F(RtpFecTest, FecRecoveryNonConsecutivePacketsWrap) { | 769 TEST_F(RtpFecTest, FecRecoveryNonConsecutivePacketsWrap) { |
732 const int kNumImportantPackets = 0; | 770 constexpr int kNumImportantPackets = 0; |
733 const bool kUseUnequalProtection = false; | 771 constexpr bool kUseUnequalProtection = false; |
734 const int kNumMediaPackets = 21; | 772 constexpr int kNumMediaPackets = 21; |
735 uint8_t kProtectionFactor = 127; | 773 uint8_t kProtectionFactor = 127; |
736 | 774 |
737 fec_seq_num_ = ConstructMediaPacketsSeqNum(kNumMediaPackets, 0xFFFF - 5); | 775 fec_seq_num_ = ConstructMediaPacketsSeqNum(kNumMediaPackets, 0xFFFF - 5); |
738 | 776 |
739 // Create a new temporary packet list for generating FEC packets. | 777 // Create a new temporary packet list for generating FEC packets. |
740 // This list should have every other packet removed. | 778 // This list should have every other packet removed. |
741 PacketList protected_media_packets; | 779 PacketList protected_media_packets; |
742 int i = 0; | 780 int i = 0; |
743 for (auto it = media_packet_list_.begin(); it != media_packet_list_.end(); | 781 for (auto it = media_packet_list_.begin(); it != media_packet_list_.end(); |
744 ++it, ++i) { | 782 ++it, ++i) { |
745 if (i % 2 == 0) protected_media_packets.push_back(*it); | 783 if (i % 2 == 0) protected_media_packets.push_back(*it); |
746 } | 784 } |
747 | 785 |
748 // Zero column insertion will have to extend the size of the packet | 786 // Zero column insertion will have to extend the size of the packet |
749 // mask since the number of actual packets are 21, while the number | 787 // mask since the number of actual packets are 21, while the number |
750 // of protected packets are 11. | 788 // of protected packets are 11. |
751 EXPECT_EQ(0, fec_->GenerateFec(protected_media_packets, kProtectionFactor, | 789 EXPECT_EQ(0, fec_.GenerateFec(protected_media_packets, kProtectionFactor, |
752 kNumImportantPackets, kUseUnequalProtection, | 790 kNumImportantPackets, kUseUnequalProtection, |
753 webrtc::kFecMaskBursty, &fec_packet_list_)); | 791 webrtc::kFecMaskBursty, &fec_packet_list_)); |
754 | 792 |
755 // Expect 5 FEC packet. | 793 // Expect 5 FEC packet. |
756 EXPECT_EQ(5, static_cast<int>(fec_packet_list_.size())); | 794 EXPECT_EQ(5u, fec_packet_list_.size()); |
757 | 795 |
758 // Last protected media packet lost | 796 // Last protected media packet lost |
759 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 797 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
760 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 798 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
761 media_loss_mask_[kNumMediaPackets - 1] = 1; | 799 media_loss_mask_[kNumMediaPackets - 1] = 1; |
762 NetworkReceivedPackets(); | 800 NetworkReceivedPackets(media_loss_mask_, fec_loss_mask_); |
763 | 801 |
764 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 802 EXPECT_EQ(0, fec_.DecodeFec(&received_packet_list_, |
765 &recovered_packet_list_)); | 803 &recovered_packet_list_)); |
766 | 804 |
767 // One packet lost, one FEC packet, expect complete recovery. | 805 // One packet lost, one FEC packet, expect complete recovery. |
768 EXPECT_TRUE(IsRecoveryComplete()); | 806 EXPECT_TRUE(IsRecoveryComplete()); |
769 FreeRecoveredPacketList(); | 807 FreeRecoveredPacketList(); |
770 | 808 |
771 // Last unprotected packet lost. | 809 // Last unprotected packet lost. |
772 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 810 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
773 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 811 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
774 media_loss_mask_[kNumMediaPackets - 2] = 1; | 812 media_loss_mask_[kNumMediaPackets - 2] = 1; |
775 NetworkReceivedPackets(); | 813 NetworkReceivedPackets(media_loss_mask_, fec_loss_mask_); |
776 | 814 |
777 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 815 EXPECT_EQ(0, fec_.DecodeFec(&received_packet_list_, |
778 &recovered_packet_list_)); | 816 &recovered_packet_list_)); |
779 | 817 |
780 // Unprotected packet lost. Recovery not possible. | 818 // Unprotected packet lost. Recovery not possible. |
781 EXPECT_FALSE(IsRecoveryComplete()); | 819 EXPECT_FALSE(IsRecoveryComplete()); |
782 FreeRecoveredPacketList(); | 820 FreeRecoveredPacketList(); |
783 | 821 |
784 // 6 media packets lost. | 822 // 6 media packets lost. |
785 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 823 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
786 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 824 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
787 media_loss_mask_[kNumMediaPackets - 11] = 1; | 825 media_loss_mask_[kNumMediaPackets - 11] = 1; |
788 media_loss_mask_[kNumMediaPackets - 9] = 1; | 826 media_loss_mask_[kNumMediaPackets - 9] = 1; |
789 media_loss_mask_[kNumMediaPackets - 7] = 1; | 827 media_loss_mask_[kNumMediaPackets - 7] = 1; |
790 media_loss_mask_[kNumMediaPackets - 5] = 1; | 828 media_loss_mask_[kNumMediaPackets - 5] = 1; |
791 media_loss_mask_[kNumMediaPackets - 3] = 1; | 829 media_loss_mask_[kNumMediaPackets - 3] = 1; |
792 media_loss_mask_[kNumMediaPackets - 1] = 1; | 830 media_loss_mask_[kNumMediaPackets - 1] = 1; |
793 NetworkReceivedPackets(); | 831 NetworkReceivedPackets(media_loss_mask_, fec_loss_mask_); |
794 | 832 |
795 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 833 EXPECT_EQ(0, fec_.DecodeFec(&received_packet_list_, |
796 &recovered_packet_list_)); | 834 &recovered_packet_list_)); |
797 | 835 |
798 // 5 protected packets lost, one FEC packet, cannot get complete recovery. | 836 // 5 protected packets lost, one FEC packet, cannot get complete recovery. |
799 EXPECT_FALSE(IsRecoveryComplete()); | 837 EXPECT_FALSE(IsRecoveryComplete()); |
800 } | 838 } |
801 | 839 |
802 void RtpFecTest::TearDown() { | 840 void RtpFecTest::TearDown() { |
803 fec_->ResetState(&recovered_packet_list_); | 841 fec_.ResetState(&recovered_packet_list_); |
804 delete fec_; | |
805 FreeRecoveredPacketList(); | 842 FreeRecoveredPacketList(); |
806 ClearList(&media_packet_list_); | 843 ClearList(&media_packet_list_); |
807 EXPECT_TRUE(media_packet_list_.empty()); | 844 EXPECT_TRUE(media_packet_list_.empty()); |
808 } | 845 } |
809 | 846 |
810 void RtpFecTest::FreeRecoveredPacketList() { | 847 void RtpFecTest::FreeRecoveredPacketList() { |
811 ClearList(&recovered_packet_list_); | 848 ClearList(&recovered_packet_list_); |
812 } | 849 } |
813 | 850 |
814 bool RtpFecTest::IsRecoveryComplete() { | 851 bool RtpFecTest::IsRecoveryComplete() { |
(...skipping 13 matching lines...) Expand all Loading... | |
828 recovered_packet->pkt->data, | 865 recovered_packet->pkt->data, |
829 media_packet->length) != 0) { | 866 media_packet->length) != 0) { |
830 return false; | 867 return false; |
831 } | 868 } |
832 return true; | 869 return true; |
833 }; | 870 }; |
834 return std::equal(media_packet_list_.cbegin(), media_packet_list_.cend(), | 871 return std::equal(media_packet_list_.cbegin(), media_packet_list_.cend(), |
835 recovered_packet_list_.cbegin(), cmp); | 872 recovered_packet_list_.cbegin(), cmp); |
836 } | 873 } |
837 | 874 |
838 void RtpFecTest::NetworkReceivedPackets() { | 875 void RtpFecTest::NetworkReceivedPackets(int* media_loss_mask, |
839 const bool kFecPacket = true; | 876 int* fec_loss_mask) { |
840 ReceivedPackets(media_packet_list_, media_loss_mask_, !kFecPacket); | 877 constexpr bool kFecPacket = true; |
841 ReceivedPackets(fec_packet_list_, fec_loss_mask_, kFecPacket); | 878 ReceivedPackets(media_packet_list_, media_loss_mask, !kFecPacket); |
879 ReceivedPackets(fec_packet_list_, fec_loss_mask, kFecPacket); | |
842 } | 880 } |
843 | 881 |
844 void RtpFecTest::ReceivedPackets(const PacketList& packet_list, int* loss_mask, | 882 void RtpFecTest::ReceivedPackets(const PacketList& packet_list, int* loss_mask, |
845 bool is_fec) { | 883 bool is_fec) { |
846 int seq_num = fec_seq_num_; | 884 int seq_num = fec_seq_num_; |
847 int packet_idx = 0; | 885 int packet_idx = 0; |
848 | 886 |
849 for (const auto* packet : packet_list) { | 887 for (const auto* packet : packet_list) { |
850 if (loss_mask[packet_idx] == 0) { | 888 if (loss_mask[packet_idx] == 0) { |
851 auto received_packet = new ForwardErrorCorrection::ReceivedPacket(); | 889 auto received_packet = new ForwardErrorCorrection::ReceivedPacket(); |
(...skipping 28 matching lines...) Expand all Loading... | |
880 int RtpFecTest::ConstructMediaPacketsSeqNum(int num_media_packets, | 918 int RtpFecTest::ConstructMediaPacketsSeqNum(int num_media_packets, |
881 int start_seq_num) { | 919 int start_seq_num) { |
882 RTC_DCHECK_GT(num_media_packets, 0); | 920 RTC_DCHECK_GT(num_media_packets, 0); |
883 ForwardErrorCorrection::Packet* media_packet = NULL; | 921 ForwardErrorCorrection::Packet* media_packet = NULL; |
884 int sequence_number = start_seq_num; | 922 int sequence_number = start_seq_num; |
885 int time_stamp = random_.Rand<int>(); | 923 int time_stamp = random_.Rand<int>(); |
886 | 924 |
887 for (int i = 0; i < num_media_packets; ++i) { | 925 for (int i = 0; i < num_media_packets; ++i) { |
888 media_packet = new ForwardErrorCorrection::Packet(); | 926 media_packet = new ForwardErrorCorrection::Packet(); |
889 media_packet_list_.push_back(media_packet); | 927 media_packet_list_.push_back(media_packet); |
890 const uint32_t kMinPacketSize = kRtpHeaderSize; | 928 constexpr uint32_t kMinPacketSize = kRtpHeaderSize; |
891 const uint32_t kMaxPacketSize = IP_PACKET_SIZE - kRtpHeaderSize - | 929 const uint32_t kMaxPacketSize = IP_PACKET_SIZE - kRtpHeaderSize - |
892 kTransportOverhead - | 930 kTransportOverhead - |
893 ForwardErrorCorrection::PacketOverhead(); | 931 ForwardErrorCorrection::PacketOverhead(); |
894 media_packet->length = random_.Rand(kMinPacketSize, kMaxPacketSize); | 932 media_packet->length = random_.Rand(kMinPacketSize, kMaxPacketSize); |
895 | 933 |
896 // Generate random values for the first 2 bytes | 934 // Generate random values for the first 2 bytes |
897 media_packet->data[0] = random_.Rand<uint8_t>(); | 935 media_packet->data[0] = random_.Rand<uint8_t>(); |
898 media_packet->data[1] = random_.Rand<uint8_t>(); | 936 media_packet->data[1] = random_.Rand<uint8_t>(); |
899 | 937 |
900 // The first two bits are assumed to be 10 by the FEC encoder. | 938 // The first two bits are assumed to be 10 by the FEC encoder. |
(...skipping 23 matching lines...) Expand all Loading... | |
924 } | 962 } |
925 // Last packet, set marker bit. | 963 // Last packet, set marker bit. |
926 RTC_DCHECK(media_packet); | 964 RTC_DCHECK(media_packet); |
927 media_packet->data[1] |= 0x80; | 965 media_packet->data[1] |= 0x80; |
928 return sequence_number; | 966 return sequence_number; |
929 } | 967 } |
930 | 968 |
931 int RtpFecTest::ConstructMediaPackets(int num_media_packets) { | 969 int RtpFecTest::ConstructMediaPackets(int num_media_packets) { |
932 return ConstructMediaPacketsSeqNum(num_media_packets, random_.Rand<int>()); | 970 return ConstructMediaPacketsSeqNum(num_media_packets, random_.Rand<int>()); |
933 } | 971 } |
OLD | NEW |