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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
46 // Reorder packets. | 46 // Reorder packets. |
47 float random_variable = random->Rand<float>(); | 47 float random_variable = random->Rand<float>(); |
48 while (random_variable < reorder_rate) { | 48 while (random_variable < reorder_rate) { |
49 ++it; | 49 ++it; |
50 if (it == received_packet_list->end()) { | 50 if (it == received_packet_list->end()) { |
51 --it; | 51 --it; |
52 break; | 52 break; |
53 } | 53 } |
54 random_variable = random->Rand<float>(); | 54 random_variable = random->Rand<float>(); |
55 } | 55 } |
56 ForwardErrorCorrection::ReceivedPacket* received_packet = *it; | 56 to_decode_list->push_back(std::move(*it)); |
57 to_decode_list->push_back(received_packet); | 57 received_packet_list->erase(it); |
58 ForwardErrorCorrection::ReceivedPacket* received_packet = | |
59 to_decode_list->back().get(); | |
58 | 60 |
59 // Duplicate packets. | 61 // Duplicate packets. |
60 random_variable = random->Rand<float>(); | 62 random_variable = random->Rand<float>(); |
61 while (random_variable < duplicate_rate) { | 63 while (random_variable < duplicate_rate) { |
62 ForwardErrorCorrection::ReceivedPacket* duplicate_packet = | 64 std::unique_ptr<ForwardErrorCorrection::ReceivedPacket> duplicate_packet( |
63 new ForwardErrorCorrection::ReceivedPacket; | 65 new ForwardErrorCorrection::ReceivedPacket); |
stefan-webrtc
2016/06/29 19:36:18
()
brandtr
2016/06/30 14:05:55
Done.
| |
64 *duplicate_packet = *received_packet; | 66 *duplicate_packet = *received_packet; |
65 duplicate_packet->pkt = new ForwardErrorCorrection::Packet; | 67 duplicate_packet->pkt = new ForwardErrorCorrection::Packet; |
66 memcpy(duplicate_packet->pkt->data, received_packet->pkt->data, | 68 memcpy(duplicate_packet->pkt->data, received_packet->pkt->data, |
67 received_packet->pkt->length); | 69 received_packet->pkt->length); |
68 duplicate_packet->pkt->length = received_packet->pkt->length; | 70 duplicate_packet->pkt->length = received_packet->pkt->length; |
69 | 71 |
70 to_decode_list->push_back(duplicate_packet); | 72 to_decode_list->push_back(std::move(duplicate_packet)); |
71 random_variable = random->Rand<float>(); | 73 random_variable = random->Rand<float>(); |
72 } | 74 } |
73 received_packet_list->erase(it); | |
74 } | 75 } |
75 } | 76 } |
76 | 77 |
77 // Too slow to finish before timeout on iOS. See webrtc:4755. | 78 // Too slow to finish before timeout on iOS. See webrtc:4755. |
78 #if defined(WEBRTC_IOS) | 79 #if defined(WEBRTC_IOS) |
79 #define MAYBE_FecTest DISABLED_FecTest | 80 #define MAYBE_FecTest DISABLED_FecTest |
80 #else | 81 #else |
81 #define MAYBE_FecTest FecTest | 82 #define MAYBE_FecTest FecTest |
82 #endif | 83 #endif |
83 TEST(FecTest, MAYBE_FecTest) { | 84 TEST(FecTest, MAYBE_FecTest) { |
(...skipping 14 matching lines...) Expand all Loading... | |
98 // Maximum number of media packets allowed for the mask type. | 99 // Maximum number of media packets allowed for the mask type. |
99 const uint16_t kMaxMediaPackets[] = { | 100 const uint16_t kMaxMediaPackets[] = { |
100 kMaxNumberMediaPackets, | 101 kMaxNumberMediaPackets, |
101 sizeof(kPacketMaskBurstyTbl) / sizeof(*kPacketMaskBurstyTbl)}; | 102 sizeof(kPacketMaskBurstyTbl) / sizeof(*kPacketMaskBurstyTbl)}; |
102 | 103 |
103 ASSERT_EQ(12, kMaxMediaPackets[1]) << "Max media packets for bursty mode not " | 104 ASSERT_EQ(12, kMaxMediaPackets[1]) << "Max media packets for bursty mode not " |
104 << "equal to 12."; | 105 << "equal to 12."; |
105 | 106 |
106 ForwardErrorCorrection fec; | 107 ForwardErrorCorrection fec; |
107 ForwardErrorCorrection::PacketList media_packet_list; | 108 ForwardErrorCorrection::PacketList media_packet_list; |
108 ForwardErrorCorrection::PacketList fec_packet_list; | 109 std::list<ForwardErrorCorrection::Packet*> fec_packet_list; |
109 ForwardErrorCorrection::ReceivedPacketList to_decode_list; | 110 ForwardErrorCorrection::ReceivedPacketList to_decode_list; |
110 ForwardErrorCorrection::ReceivedPacketList received_packet_list; | 111 ForwardErrorCorrection::ReceivedPacketList received_packet_list; |
111 ForwardErrorCorrection::RecoveredPacketList recovered_packet_list; | 112 ForwardErrorCorrection::RecoveredPacketList recovered_packet_list; |
112 std::list<uint8_t*> fec_mask_list; | 113 std::list<uint8_t*> fec_mask_list; |
113 | 114 |
114 ForwardErrorCorrection::Packet* media_packet = nullptr; | |
115 // Running over only one loss rate to limit execution time. | 115 // Running over only one loss rate to limit execution time. |
116 const float loss_rate[] = {0.5f}; | 116 const float loss_rate[] = {0.5f}; |
117 const uint32_t loss_rate_size = sizeof(loss_rate) / sizeof(*loss_rate); | 117 const uint32_t loss_rate_size = sizeof(loss_rate) / sizeof(*loss_rate); |
118 const float reorder_rate = 0.1f; | 118 const float reorder_rate = 0.1f; |
119 const float duplicate_rate = 0.1f; | 119 const float duplicate_rate = 0.1f; |
120 | 120 |
121 uint8_t media_loss_mask[kMaxNumberMediaPackets]; | 121 uint8_t media_loss_mask[kMaxNumberMediaPackets]; |
122 uint8_t fec_loss_mask[kMaxNumberFecPackets]; | 122 uint8_t fec_loss_mask[kMaxNumberFecPackets]; |
123 uint8_t fec_packet_masks[kMaxNumberFecPackets][kMaxNumberMediaPackets]; | 123 uint8_t fec_packet_masks[kMaxNumberFecPackets][kMaxNumberMediaPackets]; |
124 | 124 |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
223 ASSERT_NE(0u, column_sum) << "Column is all zero " << j; | 223 ASSERT_NE(0u, column_sum) << "Column is all zero " << j; |
224 } | 224 } |
225 | 225 |
226 // Construct media packets. | 226 // Construct media packets. |
227 // Reset the sequence number here for each FEC code/mask tested | 227 // Reset the sequence number here for each FEC code/mask tested |
228 // below, to avoid sequence number wrap-around. In actual decoding, | 228 // below, to avoid sequence number wrap-around. In actual decoding, |
229 // old FEC packets in list are dropped if sequence number wrap | 229 // old FEC packets in list are dropped if sequence number wrap |
230 // around is detected. This case is currently not handled below. | 230 // around is detected. This case is currently not handled below. |
231 seq_num = 0; | 231 seq_num = 0; |
232 for (uint32_t i = 0; i < num_media_packets; ++i) { | 232 for (uint32_t i = 0; i < num_media_packets; ++i) { |
233 media_packet = new ForwardErrorCorrection::Packet; | 233 std::unique_ptr<ForwardErrorCorrection::Packet> media_packet( |
234 media_packet_list.push_back(media_packet); | 234 new ForwardErrorCorrection::Packet); |
235 const uint32_t kMinPacketSize = 12; | 235 const uint32_t kMinPacketSize = 12; |
236 const uint32_t kMaxPacketSize = static_cast<uint32_t>( | 236 const uint32_t kMaxPacketSize = static_cast<uint32_t>( |
237 IP_PACKET_SIZE - 12 - 28 - | 237 IP_PACKET_SIZE - 12 - 28 - |
238 ForwardErrorCorrection::PacketOverhead()); | 238 ForwardErrorCorrection::PacketOverhead()); |
239 media_packet->length = random.Rand(kMinPacketSize, | 239 media_packet->length = random.Rand(kMinPacketSize, |
240 kMaxPacketSize); | 240 kMaxPacketSize); |
241 | 241 |
242 // Generate random values for the first 2 bytes. | 242 // Generate random values for the first 2 bytes. |
243 media_packet->data[0] = random.Rand<uint8_t>(); | 243 media_packet->data[0] = random.Rand<uint8_t>(); |
244 media_packet->data[1] = random.Rand<uint8_t>(); | 244 media_packet->data[1] = random.Rand<uint8_t>(); |
(...skipping 17 matching lines...) Expand all Loading... | |
262 ByteWriter<uint16_t>::WriteBigEndian(&media_packet->data[2], | 262 ByteWriter<uint16_t>::WriteBigEndian(&media_packet->data[2], |
263 seq_num); | 263 seq_num); |
264 ByteWriter<uint32_t>::WriteBigEndian(&media_packet->data[4], | 264 ByteWriter<uint32_t>::WriteBigEndian(&media_packet->data[4], |
265 timestamp); | 265 timestamp); |
266 ByteWriter<uint32_t>::WriteBigEndian(&media_packet->data[8], | 266 ByteWriter<uint32_t>::WriteBigEndian(&media_packet->data[8], |
267 ssrc); | 267 ssrc); |
268 // Generate random values for payload | 268 // Generate random values for payload |
269 for (size_t j = 12; j < media_packet->length; ++j) { | 269 for (size_t j = 12; j < media_packet->length; ++j) { |
270 media_packet->data[j] = random.Rand<uint8_t>(); | 270 media_packet->data[j] = random.Rand<uint8_t>(); |
271 } | 271 } |
272 media_packet_list.push_back(std::move(media_packet)); | |
272 seq_num++; | 273 seq_num++; |
273 } | 274 } |
274 media_packet->data[1] |= 0x80; | 275 media_packet_list.back()->data[1] |= 0x80; |
275 | 276 |
276 ASSERT_EQ(0, fec.GenerateFEC(media_packet_list, protection_factor, | 277 ASSERT_EQ(0, fec.GenerateFEC(media_packet_list, protection_factor, |
277 num_imp_packets, kUseUnequalProtection, | 278 num_imp_packets, kUseUnequalProtection, |
278 fec_mask_type, &fec_packet_list)) | 279 fec_mask_type, &fec_packet_list)) |
279 << "GenerateFEC() failed"; | 280 << "GenerateFEC() failed"; |
280 | 281 |
281 ASSERT_EQ(num_fec_packets, fec_packet_list.size()) | 282 ASSERT_EQ(num_fec_packets, fec_packet_list.size()) |
282 << "We requested " << num_fec_packets << " FEC packets, but " | 283 << "We requested " << num_fec_packets << " FEC packets, but " |
283 << "GenerateFEC() produced " << fec_packet_list.size(); | 284 << "GenerateFEC() produced " << fec_packet_list.size(); |
284 | 285 |
285 memset(media_loss_mask, 0, sizeof(media_loss_mask)); | 286 memset(media_loss_mask, 0, sizeof(media_loss_mask)); |
286 uint32_t media_packet_idx = 0; | 287 uint32_t media_packet_idx = 0; |
287 for (auto* media_packet : media_packet_list) { | 288 for (auto& media_packet : media_packet_list) { |
288 // We want a value between 0 and 1. | 289 // We want a value between 0 and 1. |
289 const float loss_random_variable = random.Rand<float>(); | 290 const float loss_random_variable = random.Rand<float>(); |
290 | 291 |
291 if (loss_random_variable >= loss_rate[loss_rate_idx]) { | 292 if (loss_random_variable >= loss_rate[loss_rate_idx]) { |
292 media_loss_mask[media_packet_idx] = 1; | 293 media_loss_mask[media_packet_idx] = 1; |
293 auto received_packet = | 294 std::unique_ptr<ForwardErrorCorrection::ReceivedPacket> |
294 new ForwardErrorCorrection::ReceivedPacket; | 295 received_packet(new ForwardErrorCorrection::ReceivedPacket); |
295 received_packet->pkt = new ForwardErrorCorrection::Packet; | 296 received_packet->pkt = new ForwardErrorCorrection::Packet; |
296 received_packet_list.push_back(received_packet); | |
297 | |
298 received_packet->pkt->length = media_packet->length; | 297 received_packet->pkt->length = media_packet->length; |
299 memcpy(received_packet->pkt->data, media_packet->data, | 298 memcpy(received_packet->pkt->data, media_packet->data, |
300 media_packet->length); | 299 media_packet->length); |
301 received_packet->seq_num = | 300 received_packet->seq_num = |
302 ByteReader<uint16_t>::ReadBigEndian(&media_packet->data[2]); | 301 ByteReader<uint16_t>::ReadBigEndian(&media_packet->data[2]); |
303 received_packet->is_fec = false; | 302 received_packet->is_fec = false; |
303 received_packet_list.push_back(std::move(received_packet)); | |
304 } | 304 } |
305 media_packet_idx++; | 305 media_packet_idx++; |
306 } | 306 } |
307 | 307 |
308 memset(fec_loss_mask, 0, sizeof(fec_loss_mask)); | 308 memset(fec_loss_mask, 0, sizeof(fec_loss_mask)); |
309 uint32_t fec_packet_idx = 0; | 309 uint32_t fec_packet_idx = 0; |
310 for (auto* fec_packet : fec_packet_list) { | 310 for (auto* fec_packet : fec_packet_list) { |
311 const float loss_random_variable = random.Rand<float>(); | 311 const float loss_random_variable = random.Rand<float>(); |
312 if (loss_random_variable >= loss_rate[loss_rate_idx]) { | 312 if (loss_random_variable >= loss_rate[loss_rate_idx]) { |
313 fec_loss_mask[fec_packet_idx] = 1; | 313 fec_loss_mask[fec_packet_idx] = 1; |
314 auto received_packet = | 314 std::unique_ptr<ForwardErrorCorrection::ReceivedPacket> |
315 new ForwardErrorCorrection::ReceivedPacket; | 315 received_packet(new ForwardErrorCorrection::ReceivedPacket); |
316 received_packet->pkt = new ForwardErrorCorrection::Packet; | 316 received_packet->pkt = new ForwardErrorCorrection::Packet; |
317 | |
318 received_packet_list.push_back(received_packet); | |
319 | |
320 received_packet->pkt->length = fec_packet->length; | 317 received_packet->pkt->length = fec_packet->length; |
321 memcpy(received_packet->pkt->data, fec_packet->data, | 318 memcpy(received_packet->pkt->data, fec_packet->data, |
322 fec_packet->length); | 319 fec_packet->length); |
323 | |
324 received_packet->seq_num = seq_num; | 320 received_packet->seq_num = seq_num; |
325 received_packet->is_fec = true; | 321 received_packet->is_fec = true; |
326 received_packet->ssrc = ssrc; | 322 received_packet->ssrc = ssrc; |
323 received_packet_list.push_back(std::move(received_packet)); | |
327 | 324 |
328 fec_mask_list.push_back(fec_packet_masks[fec_packet_idx]); | 325 fec_mask_list.push_back(fec_packet_masks[fec_packet_idx]); |
329 } | 326 } |
330 ++fec_packet_idx; | 327 ++fec_packet_idx; |
331 ++seq_num; | 328 ++seq_num; |
332 } | 329 } |
333 | 330 |
334 #ifdef VERBOSE_OUTPUT | 331 #ifdef VERBOSE_OUTPUT |
335 printf("Media loss mask:\n"); | 332 printf("Media loss mask:\n"); |
336 for (uint32_t i = 0; i < num_media_packets; i++) { | 333 for (uint32_t i = 0; i < num_media_packets; i++) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
377 // For error-checking frame completion. | 374 // For error-checking frame completion. |
378 bool fec_packet_received = false; | 375 bool fec_packet_received = false; |
379 while (!received_packet_list.empty()) { | 376 while (!received_packet_list.empty()) { |
380 size_t num_packets_to_decode = random.Rand( | 377 size_t num_packets_to_decode = random.Rand( |
381 1u, static_cast<uint32_t>(received_packet_list.size())); | 378 1u, static_cast<uint32_t>(received_packet_list.size())); |
382 ReceivePackets(&to_decode_list, &received_packet_list, | 379 ReceivePackets(&to_decode_list, &received_packet_list, |
383 num_packets_to_decode, reorder_rate, | 380 num_packets_to_decode, reorder_rate, |
384 duplicate_rate, &random); | 381 duplicate_rate, &random); |
385 | 382 |
386 if (fec_packet_received == false) { | 383 if (fec_packet_received == false) { |
387 for (auto* received_packet : to_decode_list) { | 384 for (auto& received_packet : to_decode_list) { |
388 if (received_packet->is_fec) { | 385 if (received_packet->is_fec) { |
389 fec_packet_received = true; | 386 fec_packet_received = true; |
390 } | 387 } |
391 } | 388 } |
392 } | 389 } |
393 ASSERT_EQ(0, fec.DecodeFEC(&to_decode_list, | 390 ASSERT_EQ(0, fec.DecodeFEC(&to_decode_list, |
394 &recovered_packet_list)) | 391 &recovered_packet_list)) |
395 << "DecodeFEC() failed"; | 392 << "DecodeFEC() failed"; |
396 ASSERT_TRUE(to_decode_list.empty()) | 393 ASSERT_TRUE(to_decode_list.empty()) |
397 << "Received packet list is not empty."; | 394 << "Received packet list is not empty."; |
398 } | 395 } |
399 media_packet_idx = 0; | 396 media_packet_idx = 0; |
400 for (auto* media_packet : media_packet_list) { | 397 for (auto& media_packet : media_packet_list) { |
401 if (media_loss_mask[media_packet_idx] == 1) { | 398 if (media_loss_mask[media_packet_idx] == 1) { |
402 // Should have recovered this packet. | 399 // Should have recovered this packet. |
403 auto recovered_packet_list_it = recovered_packet_list.cbegin(); | 400 auto recovered_packet_list_it = recovered_packet_list.cbegin(); |
404 | 401 |
405 ASSERT_FALSE(recovered_packet_list_it == | 402 ASSERT_FALSE(recovered_packet_list_it == |
406 recovered_packet_list.end()) | 403 recovered_packet_list.end()) |
407 << "Insufficient number of recovered packets."; | 404 << "Insufficient number of recovered packets."; |
408 ForwardErrorCorrection::RecoveredPacket* recovered_packet = | 405 ForwardErrorCorrection::RecoveredPacket* recovered_packet = |
409 *recovered_packet_list_it; | 406 recovered_packet_list_it->get(); |
410 | 407 |
411 ASSERT_EQ(recovered_packet->pkt->length, media_packet->length) | 408 ASSERT_EQ(recovered_packet->pkt->length, media_packet->length) |
412 << "Recovered packet length not identical to original " | 409 << "Recovered packet length not identical to original " |
413 << "media packet"; | 410 << "media packet"; |
414 ASSERT_EQ(0, memcmp(recovered_packet->pkt->data, | 411 ASSERT_EQ(0, memcmp(recovered_packet->pkt->data, |
415 media_packet->data, media_packet->length)) | 412 media_packet->data, media_packet->length)) |
416 << "Recovered packet payload not identical to original " | 413 << "Recovered packet payload not identical to original " |
417 << "media packet"; | 414 << "media packet"; |
418 delete recovered_packet; | |
419 recovered_packet_list.pop_front(); | 415 recovered_packet_list.pop_front(); |
420 } | 416 } |
421 ++media_packet_idx; | 417 ++media_packet_idx; |
422 } | 418 } |
423 fec.ResetState(&recovered_packet_list); | 419 fec.ResetState(&recovered_packet_list); |
424 ASSERT_TRUE(recovered_packet_list.empty()) | 420 ASSERT_TRUE(recovered_packet_list.empty()) |
425 << "Excessive number of recovered packets.\t size is: " | 421 << "Excessive number of recovered packets.\t size is: " |
426 << recovered_packet_list.size(); | 422 << recovered_packet_list.size(); |
427 // -- Teardown -- | 423 // -- Teardown -- |
428 auto media_packet_list_it = media_packet_list.begin(); | 424 media_packet_list.clear(); |
429 while (media_packet_list_it != media_packet_list.end()) { | |
430 delete *media_packet_list_it; | |
431 ++media_packet_list_it; | |
432 media_packet_list.pop_front(); | |
433 } | |
434 RTC_DCHECK(media_packet_list.empty()); | 425 RTC_DCHECK(media_packet_list.empty()); |
435 | 426 |
436 // Clear FEC packet list, so we don't pass in a non-empty | 427 // Clear FEC packet list, so we don't pass in a non-empty |
437 // list in the next call to DecodeFEC(). | 428 // list in the next call to DecodeFEC(). |
438 fec_packet_list.clear(); | 429 fec_packet_list.clear(); |
439 | 430 |
440 // Delete received packets we didn't pass to DecodeFEC(), due to | 431 // Delete received packets we didn't pass to DecodeFEC(), due to |
441 // early frame completion. | 432 // early frame completion. |
442 auto received_packet_it = received_packet_list.cbegin(); | 433 received_packet_list.clear(); |
443 while (received_packet_it != received_packet_list.end()) { | |
444 delete *received_packet_it; | |
445 ++received_packet_it; | |
446 received_packet_list.pop_front(); | |
447 } | |
448 RTC_DCHECK(received_packet_list.empty()); | 434 RTC_DCHECK(received_packet_list.empty()); |
449 | 435 |
450 while (!fec_mask_list.empty()) { | 436 while (!fec_mask_list.empty()) { |
451 fec_mask_list.pop_front(); | 437 fec_mask_list.pop_front(); |
452 } | 438 } |
453 timestamp += 90000 / 30; | 439 timestamp += 90000 / 30; |
454 } // loop over num_imp_packets | 440 } // loop over num_imp_packets |
455 } // loop over FecPackets | 441 } // loop over FecPackets |
456 } // loop over num_media_packets | 442 } // loop over num_media_packets |
457 delete[] packet_mask; | 443 delete[] packet_mask; |
458 } // loop over loss rates | 444 } // loop over loss rates |
459 } // loop over mask types | 445 } // loop over mask types |
460 | 446 |
461 // Have DecodeFEC free allocated memory. | 447 // Have DecodeFEC clear the recovered packet list. |
462 fec.ResetState(&recovered_packet_list); | 448 fec.ResetState(&recovered_packet_list); |
463 ASSERT_TRUE(recovered_packet_list.empty()) | 449 ASSERT_TRUE(recovered_packet_list.empty()) |
464 << "Recovered packet list is not empty"; | 450 << "Recovered packet list is not empty"; |
465 } | 451 } |
466 | 452 |
467 } // namespace test | 453 } // namespace test |
468 } // namespace webrtc | 454 } // namespace webrtc |
OLD | NEW |