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 13 matching lines...) Expand all Loading... |
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 const 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 const uint8_t kMaxNumberMediaPackets = ForwardErrorCorrection::kMaxMediaPackets; |
29 | 29 |
30 using PacketList = ForwardErrorCorrection::PacketList; | 30 using PacketList = ForwardErrorCorrection::PacketList; |
31 using ReceivedPacketList = ForwardErrorCorrection::ReceivedPacketList; | 31 using ReceivedPacketList = ForwardErrorCorrection::ReceivedPacketList; |
32 using RecoveredPacketList = ForwardErrorCorrection::RecoveredPacketList; | 32 using RecoveredPacketList = ForwardErrorCorrection::RecoveredPacketList; |
33 | 33 |
34 template <typename T> void ClearList(std::list<T*>* my_list) { | |
35 T* packet = NULL; | |
36 while (!my_list->empty()) { | |
37 packet = my_list->front(); | |
38 delete packet; | |
39 my_list->pop_front(); | |
40 } | |
41 } | |
42 | |
43 class RtpFecTest : public ::testing::Test { | 34 class RtpFecTest : public ::testing::Test { |
44 protected: | 35 protected: |
45 RtpFecTest() | 36 RtpFecTest() |
46 : random_(0xfec133700742), | 37 : random_(0xfec133700742), |
47 fec_(new ForwardErrorCorrection()), | 38 fec_(new ForwardErrorCorrection()), |
48 ssrc_(random_.Rand<uint32_t>()), | 39 ssrc_(random_.Rand<uint32_t>()), |
49 fec_seq_num_(0) {} | 40 fec_seq_num_(0) {} |
50 | 41 |
51 webrtc::Random random_; | 42 webrtc::Random random_; |
52 ForwardErrorCorrection* fec_; | 43 ForwardErrorCorrection* fec_; |
53 int ssrc_; | 44 int ssrc_; |
54 uint16_t fec_seq_num_; | 45 uint16_t fec_seq_num_; |
55 | 46 |
56 PacketList media_packet_list_; | 47 PacketList media_packet_list_; |
57 PacketList fec_packet_list_; | 48 std::list<ForwardErrorCorrection::Packet*> fec_packet_list_; |
58 ReceivedPacketList received_packet_list_; | 49 ReceivedPacketList received_packet_list_; |
59 RecoveredPacketList recovered_packet_list_; | 50 RecoveredPacketList recovered_packet_list_; |
60 | 51 |
61 // Media packet "i" is lost if media_loss_mask_[i] = 1, | 52 // Media packet "i" is lost if media_loss_mask_[i] = 1, |
62 // received if media_loss_mask_[i] = 0. | 53 // received if media_loss_mask_[i] = 0. |
63 int media_loss_mask_[kMaxNumberMediaPackets]; | 54 int media_loss_mask_[kMaxNumberMediaPackets]; |
64 | 55 |
65 // FEC packet "i" is lost if fec_loss_mask_[i] = 1, | 56 // FEC packet "i" is lost if fec_loss_mask_[i] = 1, |
66 // received if fec_loss_mask_[i] = 0. | 57 // received if fec_loss_mask_[i] = 0. |
67 int fec_loss_mask_[kMaxNumberMediaPackets]; | 58 int fec_loss_mask_[kMaxNumberMediaPackets]; |
68 | 59 |
69 // Construct the media packet list, up to |num_media_packets| packets. | 60 // Construct the media packet list, up to |num_media_packets| packets. |
70 // Returns the next sequence number after the last media packet. | 61 // Returns the next sequence number after the last media packet. |
71 // (this will be the sequence of the first FEC packet) | 62 // (this will be the sequence of the first FEC packet) |
72 int ConstructMediaPacketsSeqNum(int num_media_packets, int start_seq_num); | 63 int ConstructMediaPacketsSeqNum(int num_media_packets, int start_seq_num); |
73 int ConstructMediaPackets(int num_media_packets); | 64 int ConstructMediaPackets(int num_media_packets); |
74 | 65 |
| 66 // Deep copies |src| to |dst|, but only keeps every Nth packet. |
| 67 void DeepCopyEveryNthPacket(const PacketList& src, PacketList* dst, int N); |
| 68 |
75 // Construct the received packet list: a subset of the media and FEC packets. | 69 // Construct the received packet list: a subset of the media and FEC packets. |
76 void NetworkReceivedPackets(); | 70 void NetworkReceivedPackets(); |
77 | 71 |
78 // Add packet from |packet_list| to list of received packets, using the | 72 // Add packet from |packet_list| to list of received packets, using the |
79 // |loss_mask|. | 73 // |loss_mask|. |
80 // The |packet_list| may be a media packet list (is_fec = false), or a | 74 // The |packet_list| may be a media packet list (is_fec = false), or a |
81 // FEC packet list (is_fec = true). | 75 // FEC packet list (is_fec = true). |
82 void ReceivedPackets(const PacketList& packet_list, int* loss_mask, | 76 template <typename T> |
83 bool is_fec); | 77 void ReceivedPackets(const T& packet_list, int* loss_mask, bool is_fec); |
84 | 78 |
85 // Check for complete recovery after FEC decoding. | 79 // Check for complete recovery after FEC decoding. |
86 bool IsRecoveryComplete(); | 80 bool IsRecoveryComplete(); |
87 | 81 |
88 // Delete the received packets. | |
89 void FreeRecoveredPacketList(); | |
90 | |
91 // Delete the media and FEC packets. | 82 // Delete the media and FEC packets. |
92 void TearDown(); | 83 void TearDown(); |
93 }; | 84 }; |
94 | 85 |
95 TEST_F(RtpFecTest, FecRecoveryNoLoss) { | 86 TEST_F(RtpFecTest, FecRecoveryNoLoss) { |
96 const int kNumImportantPackets = 0; | 87 const int kNumImportantPackets = 0; |
97 const bool kUseUnequalProtection = false; | 88 const bool kUseUnequalProtection = false; |
98 const int kNumMediaPackets = 4; | 89 const int kNumMediaPackets = 4; |
99 uint8_t kProtectionFactor = 60; | 90 uint8_t kProtectionFactor = 60; |
100 | 91 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
138 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 129 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
139 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 130 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
140 media_loss_mask_[3] = 1; | 131 media_loss_mask_[3] = 1; |
141 NetworkReceivedPackets(); | 132 NetworkReceivedPackets(); |
142 | 133 |
143 EXPECT_EQ(0, | 134 EXPECT_EQ(0, |
144 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); | 135 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); |
145 | 136 |
146 // One packet lost, one FEC packet, expect complete recovery. | 137 // One packet lost, one FEC packet, expect complete recovery. |
147 EXPECT_TRUE(IsRecoveryComplete()); | 138 EXPECT_TRUE(IsRecoveryComplete()); |
148 FreeRecoveredPacketList(); | 139 recovered_packet_list_.clear(); |
149 | 140 |
150 // 2 media packets lost. | 141 // 2 media packets lost. |
151 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 142 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
152 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 143 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
153 media_loss_mask_[1] = 1; | 144 media_loss_mask_[1] = 1; |
154 media_loss_mask_[3] = 1; | 145 media_loss_mask_[3] = 1; |
155 NetworkReceivedPackets(); | 146 NetworkReceivedPackets(); |
156 | 147 |
157 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 148 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
158 &recovered_packet_list_)); | 149 &recovered_packet_list_)); |
(...skipping 22 matching lines...) Expand all Loading... |
181 kNumImportantPackets, kUseUnequalProtection, | 172 kNumImportantPackets, kUseUnequalProtection, |
182 webrtc::kFecMaskBursty, &fec_packet_list_)); | 173 webrtc::kFecMaskBursty, &fec_packet_list_)); |
183 // Expect 1 FEC packet. | 174 // Expect 1 FEC packet. |
184 EXPECT_EQ(1, static_cast<int>(fec_packet_list_.size())); | 175 EXPECT_EQ(1, static_cast<int>(fec_packet_list_.size())); |
185 // Add FEC packet (seq#2) of this first frame to received list (i.e., assume | 176 // Add FEC packet (seq#2) of this first frame to received list (i.e., assume |
186 // the two media packet were lost). | 177 // the two media packet were lost). |
187 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 178 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
188 ReceivedPackets(fec_packet_list_, fec_loss_mask_, true); | 179 ReceivedPackets(fec_packet_list_, fec_loss_mask_, true); |
189 | 180 |
190 // Construct media packets for second frame, with sequence number wrap. | 181 // Construct media packets for second frame, with sequence number wrap. |
191 ClearList(&media_packet_list_); | 182 media_packet_list_.clear(); |
192 fec_seq_num_ = ConstructMediaPacketsSeqNum(3, 65535); | 183 fec_seq_num_ = ConstructMediaPacketsSeqNum(3, 65535); |
193 | 184 |
194 // Expect 3 media packets for this frame. | 185 // Expect 3 media packets for this frame. |
195 EXPECT_EQ(3, static_cast<int>(media_packet_list_.size())); | 186 EXPECT_EQ(3, static_cast<int>(media_packet_list_.size())); |
196 | 187 |
197 // Second media packet lost (seq#0). | 188 // Second media packet lost (seq#0). |
198 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 189 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
199 media_loss_mask_[1] = 1; | 190 media_loss_mask_[1] = 1; |
200 // Add packets #65535, and #1 to received list. | 191 // Add packets #65535, and #1 to received list. |
201 ReceivedPackets(media_packet_list_, media_loss_mask_, false); | 192 ReceivedPackets(media_packet_list_, media_loss_mask_, false); |
202 | 193 |
203 EXPECT_EQ(0, | 194 EXPECT_EQ(0, |
204 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); | 195 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); |
205 | 196 |
206 // Expect that no decoding is done to get missing packet (seq#0) of second | 197 // 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 | 198 // 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). | 199 // recovered packets is 2, and not equal to number of media packets (=3). |
209 EXPECT_EQ(2, static_cast<int>(recovered_packet_list_.size())); | 200 EXPECT_EQ(2, static_cast<int>(recovered_packet_list_.size())); |
210 EXPECT_TRUE(recovered_packet_list_.size() != media_packet_list_.size()); | 201 EXPECT_TRUE(recovered_packet_list_.size() != media_packet_list_.size()); |
211 FreeRecoveredPacketList(); | |
212 } | 202 } |
213 | 203 |
214 // Verify we can still recovery frame if sequence number wrap occurs within | 204 // Verify we can still recovery frame if sequence number wrap occurs within |
215 // the frame and FEC packet following wrap is received after media packets. | 205 // the frame and FEC packet following wrap is received after media packets. |
216 TEST_F(RtpFecTest, FecRecoveryWithSeqNumGapOneFrameRecovery) { | 206 TEST_F(RtpFecTest, FecRecoveryWithSeqNumGapOneFrameRecovery) { |
217 const int kNumImportantPackets = 0; | 207 const int kNumImportantPackets = 0; |
218 const bool kUseUnequalProtection = false; | 208 const bool kUseUnequalProtection = false; |
219 uint8_t kProtectionFactor = 20; | 209 uint8_t kProtectionFactor = 20; |
220 | 210 |
221 // One frame, with sequence number wrap in media packets. | 211 // One frame, with sequence number wrap in media packets. |
(...skipping 16 matching lines...) Expand all Loading... |
238 // Add FEC packet to received list following the media packets. | 228 // Add FEC packet to received list following the media packets. |
239 ReceivedPackets(fec_packet_list_, fec_loss_mask_, true); | 229 ReceivedPackets(fec_packet_list_, fec_loss_mask_, true); |
240 | 230 |
241 EXPECT_EQ(0, | 231 EXPECT_EQ(0, |
242 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); | 232 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); |
243 | 233 |
244 // Expect 3 media packets in recovered list, and complete recovery. | 234 // Expect 3 media packets in recovered list, and complete recovery. |
245 // Wrap-around won't remove FEC packet, as it follows the wrap. | 235 // Wrap-around won't remove FEC packet, as it follows the wrap. |
246 EXPECT_EQ(3, static_cast<int>(recovered_packet_list_.size())); | 236 EXPECT_EQ(3, static_cast<int>(recovered_packet_list_.size())); |
247 EXPECT_TRUE(IsRecoveryComplete()); | 237 EXPECT_TRUE(IsRecoveryComplete()); |
248 FreeRecoveredPacketList(); | |
249 } | 238 } |
250 | 239 |
251 // Sequence number wrap occurs within the FEC packets for the frame. | 240 // 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. | 241 // 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 | 242 // 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 | 243 // received before the media packets. This may be improved if timing information |
255 // is used to detect old FEC packets. | 244 // is used to detect old FEC packets. |
256 // TODO(marpan): Update test if wrap-around handling changes in FEC decoding. | 245 // TODO(marpan): Update test if wrap-around handling changes in FEC decoding. |
257 TEST_F(RtpFecTest, FecRecoveryWithSeqNumGapOneFrameNoRecovery) { | 246 TEST_F(RtpFecTest, FecRecoveryWithSeqNumGapOneFrameNoRecovery) { |
258 const int kNumImportantPackets = 0; | 247 const int kNumImportantPackets = 0; |
(...skipping 24 matching lines...) Expand all Loading... |
283 EXPECT_EQ(0, | 272 EXPECT_EQ(0, |
284 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); | 273 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); |
285 | 274 |
286 // The two FEC packets are received and should allow for complete recovery, | 275 // 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 | 276 // 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 | 277 // one media packet is recoverable. So exepct 2 media packets on recovered |
289 // list and no complete recovery. | 278 // list and no complete recovery. |
290 EXPECT_EQ(2, static_cast<int>(recovered_packet_list_.size())); | 279 EXPECT_EQ(2, static_cast<int>(recovered_packet_list_.size())); |
291 EXPECT_TRUE(recovered_packet_list_.size() != media_packet_list_.size()); | 280 EXPECT_TRUE(recovered_packet_list_.size() != media_packet_list_.size()); |
292 EXPECT_FALSE(IsRecoveryComplete()); | 281 EXPECT_FALSE(IsRecoveryComplete()); |
293 FreeRecoveredPacketList(); | |
294 } | 282 } |
295 | 283 |
296 // Verify we can still recovery frame if FEC is received before media packets. | 284 // Verify we can still recovery frame if FEC is received before media packets. |
297 TEST_F(RtpFecTest, FecRecoveryWithFecOutOfOrder) { | 285 TEST_F(RtpFecTest, FecRecoveryWithFecOutOfOrder) { |
298 const int kNumImportantPackets = 0; | 286 const int kNumImportantPackets = 0; |
299 const bool kUseUnequalProtection = false; | 287 const bool kUseUnequalProtection = false; |
300 uint8_t kProtectionFactor = 20; | 288 uint8_t kProtectionFactor = 20; |
301 | 289 |
302 // One frame: 3 media packets, 1 FEC packet. | 290 // One frame: 3 media packets, 1 FEC packet. |
303 // -----Frame 1---- | 291 // -----Frame 1---- |
(...skipping 15 matching lines...) Expand all Loading... |
319 ReceivedPackets(fec_packet_list_, fec_loss_mask_, true); | 307 ReceivedPackets(fec_packet_list_, fec_loss_mask_, true); |
320 // Add media packets to received list. | 308 // Add media packets to received list. |
321 ReceivedPackets(media_packet_list_, media_loss_mask_, false); | 309 ReceivedPackets(media_packet_list_, media_loss_mask_, false); |
322 | 310 |
323 EXPECT_EQ(0, | 311 EXPECT_EQ(0, |
324 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); | 312 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); |
325 | 313 |
326 // Expect 3 media packets in recovered list, and complete recovery. | 314 // Expect 3 media packets in recovered list, and complete recovery. |
327 EXPECT_EQ(3, static_cast<int>(recovered_packet_list_.size())); | 315 EXPECT_EQ(3, static_cast<int>(recovered_packet_list_.size())); |
328 EXPECT_TRUE(IsRecoveryComplete()); | 316 EXPECT_TRUE(IsRecoveryComplete()); |
329 FreeRecoveredPacketList(); | |
330 } | 317 } |
331 | 318 |
332 // Test 50% protection with random mask type: Two cases are considered: | 319 // 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% | 320 // a 50% non-consecutive loss which can be fully recovered, and a 50% |
334 // consecutive loss which cannot be fully recovered. | 321 // consecutive loss which cannot be fully recovered. |
335 TEST_F(RtpFecTest, FecRecoveryWithLoss50percRandomMask) { | 322 TEST_F(RtpFecTest, FecRecoveryWithLoss50percRandomMask) { |
336 const int kNumImportantPackets = 0; | 323 const int kNumImportantPackets = 0; |
337 const bool kUseUnequalProtection = false; | 324 const bool kUseUnequalProtection = false; |
338 const int kNumMediaPackets = 4; | 325 const int kNumMediaPackets = 4; |
339 const uint8_t kProtectionFactor = 255; | 326 const uint8_t kProtectionFactor = 255; |
(...skipping 24 matching lines...) Expand all Loading... |
364 media_loss_mask_[0] = 1; | 351 media_loss_mask_[0] = 1; |
365 media_loss_mask_[2] = 1; | 352 media_loss_mask_[2] = 1; |
366 media_loss_mask_[3] = 1; | 353 media_loss_mask_[3] = 1; |
367 NetworkReceivedPackets(); | 354 NetworkReceivedPackets(); |
368 | 355 |
369 EXPECT_EQ(0, | 356 EXPECT_EQ(0, |
370 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); | 357 fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); |
371 | 358 |
372 // With media packet#1 and FEC packets #1, #2, #3, expect complete recovery. | 359 // With media packet#1 and FEC packets #1, #2, #3, expect complete recovery. |
373 EXPECT_TRUE(IsRecoveryComplete()); | 360 EXPECT_TRUE(IsRecoveryComplete()); |
374 FreeRecoveredPacketList(); | 361 recovered_packet_list_.clear(); |
375 | 362 |
376 // 4 consecutive packets lost: media packets 0, 1, 2, 3. | 363 // 4 consecutive packets lost: media packets 0, 1, 2, 3. |
377 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 364 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
378 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 365 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
379 media_loss_mask_[0] = 1; | 366 media_loss_mask_[0] = 1; |
380 media_loss_mask_[1] = 1; | 367 media_loss_mask_[1] = 1; |
381 media_loss_mask_[2] = 1; | 368 media_loss_mask_[2] = 1; |
382 media_loss_mask_[3] = 1; | 369 media_loss_mask_[3] = 1; |
383 NetworkReceivedPackets(); | 370 NetworkReceivedPackets(); |
384 | 371 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
424 media_loss_mask_[1] = 1; | 411 media_loss_mask_[1] = 1; |
425 media_loss_mask_[2] = 1; | 412 media_loss_mask_[2] = 1; |
426 media_loss_mask_[3] = 1; | 413 media_loss_mask_[3] = 1; |
427 NetworkReceivedPackets(); | 414 NetworkReceivedPackets(); |
428 | 415 |
429 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 416 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
430 &recovered_packet_list_)); | 417 &recovered_packet_list_)); |
431 | 418 |
432 // Expect complete recovery for consecutive packet loss <= 50%. | 419 // Expect complete recovery for consecutive packet loss <= 50%. |
433 EXPECT_TRUE(IsRecoveryComplete()); | 420 EXPECT_TRUE(IsRecoveryComplete()); |
434 FreeRecoveredPacketList(); | 421 recovered_packet_list_.clear(); |
435 | 422 |
436 // 4 consecutive packets lost: media packets 1,2, 3, and FEC packet 0. | 423 // 4 consecutive packets lost: media packets 1,2, 3, and FEC packet 0. |
437 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 424 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
438 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 425 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
439 fec_loss_mask_[0] = 1; | 426 fec_loss_mask_[0] = 1; |
440 media_loss_mask_[1] = 1; | 427 media_loss_mask_[1] = 1; |
441 media_loss_mask_[2] = 1; | 428 media_loss_mask_[2] = 1; |
442 media_loss_mask_[3] = 1; | 429 media_loss_mask_[3] = 1; |
443 NetworkReceivedPackets(); | 430 NetworkReceivedPackets(); |
444 | 431 |
445 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 432 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
446 &recovered_packet_list_)); | 433 &recovered_packet_list_)); |
447 | 434 |
448 // Expect complete recovery for consecutive packet loss <= 50%. | 435 // Expect complete recovery for consecutive packet loss <= 50%. |
449 EXPECT_TRUE(IsRecoveryComplete()); | 436 EXPECT_TRUE(IsRecoveryComplete()); |
450 FreeRecoveredPacketList(); | 437 recovered_packet_list_.clear(); |
451 | 438 |
452 // 4 packets lost (non-consecutive loss): media packets 0, 3, and FEC# 0, 3. | 439 // 4 packets lost (non-consecutive loss): media packets 0, 3, and FEC# 0, 3. |
453 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 440 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
454 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 441 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
455 fec_loss_mask_[0] = 1; | 442 fec_loss_mask_[0] = 1; |
456 fec_loss_mask_[3] = 1; | 443 fec_loss_mask_[3] = 1; |
457 media_loss_mask_[0] = 1; | 444 media_loss_mask_[0] = 1; |
458 media_loss_mask_[3] = 1; | 445 media_loss_mask_[3] = 1; |
459 NetworkReceivedPackets(); | 446 NetworkReceivedPackets(); |
460 | 447 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 498 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
512 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 499 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
513 media_loss_mask_[3] = 1; | 500 media_loss_mask_[3] = 1; |
514 NetworkReceivedPackets(); | 501 NetworkReceivedPackets(); |
515 | 502 |
516 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 503 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
517 &recovered_packet_list_)); | 504 &recovered_packet_list_)); |
518 | 505 |
519 // One packet lost, one FEC packet, expect complete recovery. | 506 // One packet lost, one FEC packet, expect complete recovery. |
520 EXPECT_TRUE(IsRecoveryComplete()); | 507 EXPECT_TRUE(IsRecoveryComplete()); |
521 FreeRecoveredPacketList(); | 508 recovered_packet_list_.clear(); |
522 | 509 |
523 // 2 media packets lost. | 510 // 2 media packets lost. |
524 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 511 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
525 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 512 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
526 media_loss_mask_[1] = 1; | 513 media_loss_mask_[1] = 1; |
527 media_loss_mask_[3] = 1; | 514 media_loss_mask_[3] = 1; |
528 NetworkReceivedPackets(); | 515 NetworkReceivedPackets(); |
529 | 516 |
530 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 517 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
531 &recovered_packet_list_)); | 518 &recovered_packet_list_)); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
567 media_loss_mask_[0] = 1; | 554 media_loss_mask_[0] = 1; |
568 media_loss_mask_[2] = 1; | 555 media_loss_mask_[2] = 1; |
569 media_loss_mask_[3] = 1; | 556 media_loss_mask_[3] = 1; |
570 NetworkReceivedPackets(); | 557 NetworkReceivedPackets(); |
571 | 558 |
572 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 559 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
573 &recovered_packet_list_)); | 560 &recovered_packet_list_)); |
574 | 561 |
575 // With media packet#3 and FEC packets #0, #1, #3, expect complete recovery. | 562 // With media packet#3 and FEC packets #0, #1, #3, expect complete recovery. |
576 EXPECT_TRUE(IsRecoveryComplete()); | 563 EXPECT_TRUE(IsRecoveryComplete()); |
577 FreeRecoveredPacketList(); | 564 recovered_packet_list_.clear(); |
578 | 565 |
579 // 5 packets lost: 4 media packets and one FEC packet#2 lost. | 566 // 5 packets lost: 4 media packets and one FEC packet#2 lost. |
580 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 567 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
581 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 568 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
582 fec_loss_mask_[2] = 1; | 569 fec_loss_mask_[2] = 1; |
583 media_loss_mask_[0] = 1; | 570 media_loss_mask_[0] = 1; |
584 media_loss_mask_[1] = 1; | 571 media_loss_mask_[1] = 1; |
585 media_loss_mask_[2] = 1; | 572 media_loss_mask_[2] = 1; |
586 media_loss_mask_[3] = 1; | 573 media_loss_mask_[3] = 1; |
587 NetworkReceivedPackets(); | 574 NetworkReceivedPackets(); |
588 | 575 |
589 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 576 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
590 &recovered_packet_list_)); | 577 &recovered_packet_list_)); |
591 | 578 |
592 // Cannot get complete recovery for this loss configuration. | 579 // Cannot get complete recovery for this loss configuration. |
593 EXPECT_FALSE(IsRecoveryComplete()); | 580 EXPECT_FALSE(IsRecoveryComplete()); |
594 } | 581 } |
595 | 582 |
596 TEST_F(RtpFecTest, FecRecoveryNonConsecutivePackets) { | 583 TEST_F(RtpFecTest, FecRecoveryNonConsecutivePackets) { |
597 const int kNumImportantPackets = 0; | 584 const int kNumImportantPackets = 0; |
598 const bool kUseUnequalProtection = false; | 585 const bool kUseUnequalProtection = false; |
599 const int kNumMediaPackets = 5; | 586 const int kNumMediaPackets = 5; |
600 uint8_t kProtectionFactor = 60; | 587 uint8_t kProtectionFactor = 60; |
601 | 588 |
602 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); | 589 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); |
603 | 590 |
604 // Create a new temporary packet list for generating FEC packets. | 591 // Create a new temporary packet list for generating FEC packets. |
605 // This list should have every other packet removed. | 592 // This list should have every other packet removed. |
606 PacketList protected_media_packets; | 593 PacketList protected_media_packets; |
607 int i = 0; | 594 DeepCopyEveryNthPacket(media_packet_list_, &protected_media_packets, 2); |
608 for (auto it = media_packet_list_.begin(); it != media_packet_list_.end(); | |
609 ++it, ++i) { | |
610 if (i % 2 == 0) protected_media_packets.push_back(*it); | |
611 } | |
612 | 595 |
613 EXPECT_EQ(0, fec_->GenerateFec(protected_media_packets, kProtectionFactor, | 596 EXPECT_EQ(0, fec_->GenerateFec(protected_media_packets, kProtectionFactor, |
614 kNumImportantPackets, kUseUnequalProtection, | 597 kNumImportantPackets, kUseUnequalProtection, |
615 webrtc::kFecMaskBursty, &fec_packet_list_)); | 598 webrtc::kFecMaskBursty, &fec_packet_list_)); |
616 | 599 |
617 // Expect 1 FEC packet. | 600 // Expect 1 FEC packet. |
618 EXPECT_EQ(1, static_cast<int>(fec_packet_list_.size())); | 601 EXPECT_EQ(1, static_cast<int>(fec_packet_list_.size())); |
619 | 602 |
620 // 1 protected media packet lost | 603 // 1 protected media packet lost |
621 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 604 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
622 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 605 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
623 media_loss_mask_[2] = 1; | 606 media_loss_mask_[2] = 1; |
624 NetworkReceivedPackets(); | 607 NetworkReceivedPackets(); |
625 | 608 |
626 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 609 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
627 &recovered_packet_list_)); | 610 &recovered_packet_list_)); |
628 | 611 |
629 // One packet lost, one FEC packet, expect complete recovery. | 612 // One packet lost, one FEC packet, expect complete recovery. |
630 EXPECT_TRUE(IsRecoveryComplete()); | 613 EXPECT_TRUE(IsRecoveryComplete()); |
631 FreeRecoveredPacketList(); | 614 recovered_packet_list_.clear(); |
632 | 615 |
633 // Unprotected packet lost. | 616 // Unprotected packet lost. |
634 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 617 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
635 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 618 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
636 media_loss_mask_[1] = 1; | 619 media_loss_mask_[1] = 1; |
637 NetworkReceivedPackets(); | 620 NetworkReceivedPackets(); |
638 | 621 |
639 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 622 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
640 &recovered_packet_list_)); | 623 &recovered_packet_list_)); |
641 | 624 |
642 // Unprotected packet lost. Recovery not possible. | 625 // Unprotected packet lost. Recovery not possible. |
643 EXPECT_FALSE(IsRecoveryComplete()); | 626 EXPECT_FALSE(IsRecoveryComplete()); |
644 FreeRecoveredPacketList(); | 627 recovered_packet_list_.clear(); |
645 | 628 |
646 // 2 media packets lost. | 629 // 2 media packets lost. |
647 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 630 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
648 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 631 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
649 media_loss_mask_[0] = 1; | 632 media_loss_mask_[0] = 1; |
650 media_loss_mask_[2] = 1; | 633 media_loss_mask_[2] = 1; |
651 NetworkReceivedPackets(); | 634 NetworkReceivedPackets(); |
652 | 635 |
653 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 636 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
654 &recovered_packet_list_)); | 637 &recovered_packet_list_)); |
655 | 638 |
656 // 2 protected packets lost, one FEC packet, cannot get complete recovery. | 639 // 2 protected packets lost, one FEC packet, cannot get complete recovery. |
657 EXPECT_FALSE(IsRecoveryComplete()); | 640 EXPECT_FALSE(IsRecoveryComplete()); |
658 } | 641 } |
659 | 642 |
660 TEST_F(RtpFecTest, FecRecoveryNonConsecutivePacketsExtension) { | 643 TEST_F(RtpFecTest, FecRecoveryNonConsecutivePacketsExtension) { |
661 const int kNumImportantPackets = 0; | 644 const int kNumImportantPackets = 0; |
662 const bool kUseUnequalProtection = false; | 645 const bool kUseUnequalProtection = false; |
663 const int kNumMediaPackets = 21; | 646 const int kNumMediaPackets = 21; |
664 uint8_t kProtectionFactor = 127; | 647 uint8_t kProtectionFactor = 127; |
665 | 648 |
666 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); | 649 fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); |
667 | 650 |
668 // Create a new temporary packet list for generating FEC packets. | 651 // Create a new temporary packet list for generating FEC packets. |
669 // This list should have every other packet removed. | 652 // This list should have every other packet removed. |
670 PacketList protected_media_packets; | 653 PacketList protected_media_packets; |
671 int i = 0; | 654 DeepCopyEveryNthPacket(media_packet_list_, &protected_media_packets, 2); |
672 for (auto it = media_packet_list_.begin(); it != media_packet_list_.end(); | |
673 ++it, ++i) { | |
674 if (i % 2 == 0) protected_media_packets.push_back(*it); | |
675 } | |
676 | 655 |
677 // Zero column insertion will have to extend the size of the packet | 656 // 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 | 657 // mask since the number of actual packets are 21, while the number |
679 // of protected packets are 11. | 658 // of protected packets are 11. |
680 EXPECT_EQ(0, fec_->GenerateFec(protected_media_packets, kProtectionFactor, | 659 EXPECT_EQ(0, fec_->GenerateFec(protected_media_packets, kProtectionFactor, |
681 kNumImportantPackets, kUseUnequalProtection, | 660 kNumImportantPackets, kUseUnequalProtection, |
682 webrtc::kFecMaskBursty, &fec_packet_list_)); | 661 webrtc::kFecMaskBursty, &fec_packet_list_)); |
683 | 662 |
684 // Expect 5 FEC packet. | 663 // Expect 5 FEC packet. |
685 EXPECT_EQ(5, static_cast<int>(fec_packet_list_.size())); | 664 EXPECT_EQ(5, static_cast<int>(fec_packet_list_.size())); |
686 | 665 |
687 // Last protected media packet lost | 666 // Last protected media packet lost |
688 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 667 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
689 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 668 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
690 media_loss_mask_[kNumMediaPackets - 1] = 1; | 669 media_loss_mask_[kNumMediaPackets - 1] = 1; |
691 NetworkReceivedPackets(); | 670 NetworkReceivedPackets(); |
692 | 671 |
693 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 672 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
694 &recovered_packet_list_)); | 673 &recovered_packet_list_)); |
695 | 674 |
696 // One packet lost, one FEC packet, expect complete recovery. | 675 // One packet lost, one FEC packet, expect complete recovery. |
697 EXPECT_TRUE(IsRecoveryComplete()); | 676 EXPECT_TRUE(IsRecoveryComplete()); |
698 FreeRecoveredPacketList(); | 677 recovered_packet_list_.clear(); |
699 | 678 |
700 // Last unprotected packet lost. | 679 // Last unprotected packet lost. |
701 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 680 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
702 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 681 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
703 media_loss_mask_[kNumMediaPackets - 2] = 1; | 682 media_loss_mask_[kNumMediaPackets - 2] = 1; |
704 NetworkReceivedPackets(); | 683 NetworkReceivedPackets(); |
705 | 684 |
706 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 685 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
707 &recovered_packet_list_)); | 686 &recovered_packet_list_)); |
708 | 687 |
709 // Unprotected packet lost. Recovery not possible. | 688 // Unprotected packet lost. Recovery not possible. |
710 EXPECT_FALSE(IsRecoveryComplete()); | 689 EXPECT_FALSE(IsRecoveryComplete()); |
711 FreeRecoveredPacketList(); | 690 recovered_packet_list_.clear(); |
712 | 691 |
713 // 6 media packets lost. | 692 // 6 media packets lost. |
714 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 693 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
715 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 694 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
716 media_loss_mask_[kNumMediaPackets - 11] = 1; | 695 media_loss_mask_[kNumMediaPackets - 11] = 1; |
717 media_loss_mask_[kNumMediaPackets - 9] = 1; | 696 media_loss_mask_[kNumMediaPackets - 9] = 1; |
718 media_loss_mask_[kNumMediaPackets - 7] = 1; | 697 media_loss_mask_[kNumMediaPackets - 7] = 1; |
719 media_loss_mask_[kNumMediaPackets - 5] = 1; | 698 media_loss_mask_[kNumMediaPackets - 5] = 1; |
720 media_loss_mask_[kNumMediaPackets - 3] = 1; | 699 media_loss_mask_[kNumMediaPackets - 3] = 1; |
721 media_loss_mask_[kNumMediaPackets - 1] = 1; | 700 media_loss_mask_[kNumMediaPackets - 1] = 1; |
(...skipping 10 matching lines...) Expand all Loading... |
732 const int kNumImportantPackets = 0; | 711 const int kNumImportantPackets = 0; |
733 const bool kUseUnequalProtection = false; | 712 const bool kUseUnequalProtection = false; |
734 const int kNumMediaPackets = 21; | 713 const int kNumMediaPackets = 21; |
735 uint8_t kProtectionFactor = 127; | 714 uint8_t kProtectionFactor = 127; |
736 | 715 |
737 fec_seq_num_ = ConstructMediaPacketsSeqNum(kNumMediaPackets, 0xFFFF - 5); | 716 fec_seq_num_ = ConstructMediaPacketsSeqNum(kNumMediaPackets, 0xFFFF - 5); |
738 | 717 |
739 // Create a new temporary packet list for generating FEC packets. | 718 // Create a new temporary packet list for generating FEC packets. |
740 // This list should have every other packet removed. | 719 // This list should have every other packet removed. |
741 PacketList protected_media_packets; | 720 PacketList protected_media_packets; |
742 int i = 0; | 721 DeepCopyEveryNthPacket(media_packet_list_, &protected_media_packets, 2); |
743 for (auto it = media_packet_list_.begin(); it != media_packet_list_.end(); | |
744 ++it, ++i) { | |
745 if (i % 2 == 0) protected_media_packets.push_back(*it); | |
746 } | |
747 | 722 |
748 // Zero column insertion will have to extend the size of the packet | 723 // 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 | 724 // mask since the number of actual packets are 21, while the number |
750 // of protected packets are 11. | 725 // of protected packets are 11. |
751 EXPECT_EQ(0, fec_->GenerateFec(protected_media_packets, kProtectionFactor, | 726 EXPECT_EQ(0, fec_->GenerateFec(protected_media_packets, kProtectionFactor, |
752 kNumImportantPackets, kUseUnequalProtection, | 727 kNumImportantPackets, kUseUnequalProtection, |
753 webrtc::kFecMaskBursty, &fec_packet_list_)); | 728 webrtc::kFecMaskBursty, &fec_packet_list_)); |
754 | 729 |
755 // Expect 5 FEC packet. | 730 // Expect 5 FEC packet. |
756 EXPECT_EQ(5, static_cast<int>(fec_packet_list_.size())); | 731 EXPECT_EQ(5, static_cast<int>(fec_packet_list_.size())); |
757 | 732 |
758 // Last protected media packet lost | 733 // Last protected media packet lost |
759 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 734 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
760 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 735 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
761 media_loss_mask_[kNumMediaPackets - 1] = 1; | 736 media_loss_mask_[kNumMediaPackets - 1] = 1; |
762 NetworkReceivedPackets(); | 737 NetworkReceivedPackets(); |
763 | 738 |
764 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 739 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
765 &recovered_packet_list_)); | 740 &recovered_packet_list_)); |
766 | 741 |
767 // One packet lost, one FEC packet, expect complete recovery. | 742 // One packet lost, one FEC packet, expect complete recovery. |
768 EXPECT_TRUE(IsRecoveryComplete()); | 743 EXPECT_TRUE(IsRecoveryComplete()); |
769 FreeRecoveredPacketList(); | 744 recovered_packet_list_.clear(); |
770 | 745 |
771 // Last unprotected packet lost. | 746 // Last unprotected packet lost. |
772 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 747 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
773 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 748 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
774 media_loss_mask_[kNumMediaPackets - 2] = 1; | 749 media_loss_mask_[kNumMediaPackets - 2] = 1; |
775 NetworkReceivedPackets(); | 750 NetworkReceivedPackets(); |
776 | 751 |
777 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 752 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
778 &recovered_packet_list_)); | 753 &recovered_packet_list_)); |
779 | 754 |
780 // Unprotected packet lost. Recovery not possible. | 755 // Unprotected packet lost. Recovery not possible. |
781 EXPECT_FALSE(IsRecoveryComplete()); | 756 EXPECT_FALSE(IsRecoveryComplete()); |
782 FreeRecoveredPacketList(); | 757 recovered_packet_list_.clear(); |
783 | 758 |
784 // 6 media packets lost. | 759 // 6 media packets lost. |
785 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); | 760 memset(media_loss_mask_, 0, sizeof(media_loss_mask_)); |
786 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); | 761 memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); |
787 media_loss_mask_[kNumMediaPackets - 11] = 1; | 762 media_loss_mask_[kNumMediaPackets - 11] = 1; |
788 media_loss_mask_[kNumMediaPackets - 9] = 1; | 763 media_loss_mask_[kNumMediaPackets - 9] = 1; |
789 media_loss_mask_[kNumMediaPackets - 7] = 1; | 764 media_loss_mask_[kNumMediaPackets - 7] = 1; |
790 media_loss_mask_[kNumMediaPackets - 5] = 1; | 765 media_loss_mask_[kNumMediaPackets - 5] = 1; |
791 media_loss_mask_[kNumMediaPackets - 3] = 1; | 766 media_loss_mask_[kNumMediaPackets - 3] = 1; |
792 media_loss_mask_[kNumMediaPackets - 1] = 1; | 767 media_loss_mask_[kNumMediaPackets - 1] = 1; |
793 NetworkReceivedPackets(); | 768 NetworkReceivedPackets(); |
794 | 769 |
795 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, | 770 EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, |
796 &recovered_packet_list_)); | 771 &recovered_packet_list_)); |
797 | 772 |
798 // 5 protected packets lost, one FEC packet, cannot get complete recovery. | 773 // 5 protected packets lost, one FEC packet, cannot get complete recovery. |
799 EXPECT_FALSE(IsRecoveryComplete()); | 774 EXPECT_FALSE(IsRecoveryComplete()); |
800 } | 775 } |
801 | 776 |
802 void RtpFecTest::TearDown() { | 777 void RtpFecTest::TearDown() { |
803 fec_->ResetState(&recovered_packet_list_); | 778 fec_->ResetState(&recovered_packet_list_); |
804 delete fec_; | 779 delete fec_; |
805 FreeRecoveredPacketList(); | 780 recovered_packet_list_.clear(); |
806 ClearList(&media_packet_list_); | 781 media_packet_list_.clear(); |
807 EXPECT_TRUE(media_packet_list_.empty()); | 782 EXPECT_TRUE(media_packet_list_.empty()); |
808 } | 783 } |
809 | 784 |
810 void RtpFecTest::FreeRecoveredPacketList() { | |
811 ClearList(&recovered_packet_list_); | |
812 } | |
813 | |
814 bool RtpFecTest::IsRecoveryComplete() { | 785 bool RtpFecTest::IsRecoveryComplete() { |
815 // We must have equally many recovered packets as original packets. | 786 // We must have equally many recovered packets as original packets. |
816 if (recovered_packet_list_.size() != media_packet_list_.size()) { | 787 if (recovered_packet_list_.size() != media_packet_list_.size()) { |
817 return false; | 788 return false; |
818 } | 789 } |
819 | 790 |
820 // All recovered packets must be identical to the corresponding | 791 // All recovered packets must be identical to the corresponding |
821 // original packets. | 792 // original packets. |
822 auto cmp = [](ForwardErrorCorrection::Packet* media_packet, | 793 using PacketRef = |
823 ForwardErrorCorrection::RecoveredPacket* recovered_packet) { | 794 const std::unique_ptr<ForwardErrorCorrection::Packet>&; |
| 795 using RecoveredPacketRef = |
| 796 const std::unique_ptr<ForwardErrorCorrection::RecoveredPacket>&; |
| 797 auto cmp = [](PacketRef media_packet, RecoveredPacketRef recovered_packet) { |
824 if (media_packet->length != recovered_packet->pkt->length) { | 798 if (media_packet->length != recovered_packet->pkt->length) { |
825 return false; | 799 return false; |
826 } | 800 } |
827 if (memcmp(media_packet->data, | 801 if (memcmp(media_packet->data, |
828 recovered_packet->pkt->data, | 802 recovered_packet->pkt->data, |
829 media_packet->length) != 0) { | 803 media_packet->length) != 0) { |
830 return false; | 804 return false; |
831 } | 805 } |
832 return true; | 806 return true; |
833 }; | 807 }; |
834 return std::equal(media_packet_list_.cbegin(), media_packet_list_.cend(), | 808 return std::equal(media_packet_list_.cbegin(), media_packet_list_.cend(), |
835 recovered_packet_list_.cbegin(), cmp); | 809 recovered_packet_list_.cbegin(), cmp); |
836 } | 810 } |
837 | 811 |
838 void RtpFecTest::NetworkReceivedPackets() { | 812 void RtpFecTest::NetworkReceivedPackets() { |
839 const bool kFecPacket = true; | 813 const bool kFecPacket = true; |
840 ReceivedPackets(media_packet_list_, media_loss_mask_, !kFecPacket); | 814 ReceivedPackets(media_packet_list_, media_loss_mask_, !kFecPacket); |
841 ReceivedPackets(fec_packet_list_, fec_loss_mask_, kFecPacket); | 815 ReceivedPackets(fec_packet_list_, fec_loss_mask_, kFecPacket); |
842 } | 816 } |
843 | 817 |
844 void RtpFecTest::ReceivedPackets(const PacketList& packet_list, int* loss_mask, | 818 template <typename T> |
| 819 void RtpFecTest::ReceivedPackets(const T& packet_list, int* loss_mask, |
845 bool is_fec) { | 820 bool is_fec) { |
846 int seq_num = fec_seq_num_; | 821 int seq_num = fec_seq_num_; |
847 int packet_idx = 0; | 822 int packet_idx = 0; |
848 | 823 |
849 for (const auto* packet : packet_list) { | 824 for (const auto& packet : packet_list) { |
850 if (loss_mask[packet_idx] == 0) { | 825 if (loss_mask[packet_idx] == 0) { |
851 auto received_packet = new ForwardErrorCorrection::ReceivedPacket(); | 826 std::unique_ptr<ForwardErrorCorrection::ReceivedPacket> received_packet( |
| 827 new ForwardErrorCorrection::ReceivedPacket()); |
852 received_packet->pkt = new ForwardErrorCorrection::Packet(); | 828 received_packet->pkt = new ForwardErrorCorrection::Packet(); |
853 received_packet_list_.push_back(received_packet); | |
854 received_packet->pkt->length = packet->length; | 829 received_packet->pkt->length = packet->length; |
855 memcpy(received_packet->pkt->data, packet->data, packet->length); | 830 memcpy(received_packet->pkt->data, packet->data, packet->length); |
856 received_packet->is_fec = is_fec; | 831 received_packet->is_fec = is_fec; |
857 if (!is_fec) { | 832 if (!is_fec) { |
858 // For media packets, the sequence number and marker bit is | 833 // For media packets, the sequence number and marker bit is |
859 // obtained from RTP header. These were set in ConstructMediaPackets(). | 834 // obtained from RTP header. These were set in ConstructMediaPackets(). |
860 received_packet->seq_num = | 835 received_packet->seq_num = |
861 webrtc::ByteReader<uint16_t>::ReadBigEndian(&packet->data[2]); | 836 webrtc::ByteReader<uint16_t>::ReadBigEndian(&packet->data[2]); |
862 } else { | 837 } else { |
863 // The sequence number, marker bit, and ssrc number are defined in the | 838 // The sequence number, marker bit, and ssrc number are defined in the |
864 // RTP header of the FEC packet, which is not constructed in this test. | 839 // RTP header of the FEC packet, which is not constructed in this test. |
865 // So we set these values below based on the values generated in | 840 // So we set these values below based on the values generated in |
866 // ConstructMediaPackets(). | 841 // ConstructMediaPackets(). |
867 received_packet->seq_num = seq_num; | 842 received_packet->seq_num = seq_num; |
868 // The ssrc value for FEC packets is set to the one used for the | 843 // The ssrc value for FEC packets is set to the one used for the |
869 // media packets in ConstructMediaPackets(). | 844 // media packets in ConstructMediaPackets(). |
870 received_packet->ssrc = ssrc_; | 845 received_packet->ssrc = ssrc_; |
871 } | 846 } |
| 847 received_packet_list_.push_back(std::move(received_packet)); |
872 } | 848 } |
873 packet_idx++; | 849 packet_idx++; |
874 // Sequence number of FEC packets are defined as increment by 1 from | 850 // Sequence number of FEC packets are defined as increment by 1 from |
875 // last media packet in frame. | 851 // last media packet in frame. |
876 if (is_fec) seq_num++; | 852 if (is_fec) seq_num++; |
877 } | 853 } |
878 } | 854 } |
879 | 855 |
880 int RtpFecTest::ConstructMediaPacketsSeqNum(int num_media_packets, | 856 int RtpFecTest::ConstructMediaPacketsSeqNum(int num_media_packets, |
881 int start_seq_num) { | 857 int start_seq_num) { |
882 RTC_DCHECK_GT(num_media_packets, 0); | 858 RTC_DCHECK_GT(num_media_packets, 0); |
883 ForwardErrorCorrection::Packet* media_packet = NULL; | |
884 int sequence_number = start_seq_num; | 859 int sequence_number = start_seq_num; |
885 int time_stamp = random_.Rand<int>(); | 860 int time_stamp = random_.Rand<int>(); |
886 | 861 |
887 for (int i = 0; i < num_media_packets; ++i) { | 862 for (int i = 0; i < num_media_packets; ++i) { |
888 media_packet = new ForwardErrorCorrection::Packet(); | 863 std::unique_ptr<ForwardErrorCorrection::Packet> media_packet( |
889 media_packet_list_.push_back(media_packet); | 864 new ForwardErrorCorrection::Packet()); |
890 const uint32_t kMinPacketSize = kRtpHeaderSize; | 865 const uint32_t kMinPacketSize = kRtpHeaderSize; |
891 const uint32_t kMaxPacketSize = IP_PACKET_SIZE - kRtpHeaderSize - | 866 const uint32_t kMaxPacketSize = IP_PACKET_SIZE - kRtpHeaderSize - |
892 kTransportOverhead - | 867 kTransportOverhead - |
893 ForwardErrorCorrection::PacketOverhead(); | 868 ForwardErrorCorrection::PacketOverhead(); |
894 media_packet->length = random_.Rand(kMinPacketSize, kMaxPacketSize); | 869 media_packet->length = random_.Rand(kMinPacketSize, kMaxPacketSize); |
895 | 870 |
896 // Generate random values for the first 2 bytes | 871 // Generate random values for the first 2 bytes |
897 media_packet->data[0] = random_.Rand<uint8_t>(); | 872 media_packet->data[0] = random_.Rand<uint8_t>(); |
898 media_packet->data[1] = random_.Rand<uint8_t>(); | 873 media_packet->data[1] = random_.Rand<uint8_t>(); |
899 | 874 |
(...skipping 14 matching lines...) Expand all Loading... |
914 sequence_number); | 889 sequence_number); |
915 webrtc::ByteWriter<uint32_t>::WriteBigEndian(&media_packet->data[4], | 890 webrtc::ByteWriter<uint32_t>::WriteBigEndian(&media_packet->data[4], |
916 time_stamp); | 891 time_stamp); |
917 webrtc::ByteWriter<uint32_t>::WriteBigEndian(&media_packet->data[8], ssrc_); | 892 webrtc::ByteWriter<uint32_t>::WriteBigEndian(&media_packet->data[8], ssrc_); |
918 | 893 |
919 // Generate random values for payload. | 894 // Generate random values for payload. |
920 for (size_t j = 12; j < media_packet->length; ++j) { | 895 for (size_t j = 12; j < media_packet->length; ++j) { |
921 media_packet->data[j] = random_.Rand<uint8_t>(); | 896 media_packet->data[j] = random_.Rand<uint8_t>(); |
922 } | 897 } |
923 sequence_number++; | 898 sequence_number++; |
| 899 media_packet_list_.push_back(std::move(media_packet)); |
924 } | 900 } |
925 // Last packet, set marker bit. | 901 // Last packet, set marker bit. |
| 902 ForwardErrorCorrection::Packet* media_packet = |
| 903 media_packet_list_.back().get(); |
926 RTC_DCHECK(media_packet); | 904 RTC_DCHECK(media_packet); |
927 media_packet->data[1] |= 0x80; | 905 media_packet->data[1] |= 0x80; |
928 return sequence_number; | 906 return sequence_number; |
929 } | 907 } |
930 | 908 |
931 int RtpFecTest::ConstructMediaPackets(int num_media_packets) { | 909 int RtpFecTest::ConstructMediaPackets(int num_media_packets) { |
932 return ConstructMediaPacketsSeqNum(num_media_packets, random_.Rand<int>()); | 910 return ConstructMediaPacketsSeqNum(num_media_packets, random_.Rand<int>()); |
933 } | 911 } |
| 912 |
| 913 void RtpFecTest::DeepCopyEveryNthPacket(const PacketList& src, |
| 914 PacketList* dst, int N) { |
| 915 RTC_DCHECK_GT(N, 0); |
| 916 int i = 0; |
| 917 for (auto& packet : src) { |
| 918 if (i % N == 0) { |
| 919 dst->emplace_back(new ForwardErrorCorrection::Packet(*packet)); |
| 920 } |
| 921 ++i; |
| 922 } |
| 923 } |
OLD | NEW |