Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(35)

Side by Side Diff: webrtc/modules/rtp_rtcp/test/testFec/test_fec.cc

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

Powered by Google App Engine
This is Rietveld 408576698