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

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: Feedback response. 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 ForwardErrorCorrection::ReceivedPacket* received_packet =
62 to_decode_list->back().get();
61 63
62 // Duplicate packets. 64 // Duplicate packets.
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 (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(new ForwardErrorCorrection::ReceivedPacket() );
299 received_packet->pkt = new ForwardErrorCorrection::Packet(); 300 received_packet->pkt = new ForwardErrorCorrection::Packet();
300 received_packet_list.push_back(received_packet);
301
302 received_packet->pkt->length = media_packet->length; 301 received_packet->pkt->length = media_packet->length;
303 memcpy(received_packet->pkt->data, media_packet->data, 302 memcpy(received_packet->pkt->data, media_packet->data,
304 media_packet->length); 303 media_packet->length);
305 received_packet->seq_num = 304 received_packet->seq_num =
306 ByteReader<uint16_t>::ReadBigEndian(&media_packet->data[2]); 305 ByteReader<uint16_t>::ReadBigEndian(&media_packet->data[2]);
307 received_packet->is_fec = false; 306 received_packet->is_fec = false;
307 received_packet_list.push_back(std::move(received_packet));
308 } 308 }
309 media_packet_idx++; 309 media_packet_idx++;
310 } 310 }
311 311
312 memset(fec_loss_mask, 0, sizeof(fec_loss_mask)); 312 memset(fec_loss_mask, 0, sizeof(fec_loss_mask));
313 uint32_t fec_packet_idx = 0; 313 uint32_t fec_packet_idx = 0;
314 for (auto* fec_packet : fec_packet_list) { 314 for (auto* fec_packet : fec_packet_list) {
315 const float loss_random_variable = random.Rand<float>(); 315 const float loss_random_variable = random.Rand<float>();
316 if (loss_random_variable >= loss_rate[loss_rate_idx]) { 316 if (loss_random_variable >= loss_rate[loss_rate_idx]) {
317 fec_loss_mask[fec_packet_idx] = 1; 317 fec_loss_mask[fec_packet_idx] = 1;
318 auto received_packet = 318 std::unique_ptr<ForwardErrorCorrection::ReceivedPacket>
319 new ForwardErrorCorrection::ReceivedPacket(); 319 received_packet(new ForwardErrorCorrection::ReceivedPacket() );
320 received_packet->pkt = new ForwardErrorCorrection::Packet(); 320 received_packet->pkt = new ForwardErrorCorrection::Packet();
321
322 received_packet_list.push_back(received_packet);
323
324 received_packet->pkt->length = fec_packet->length; 321 received_packet->pkt->length = fec_packet->length;
325 memcpy(received_packet->pkt->data, fec_packet->data, 322 memcpy(received_packet->pkt->data, fec_packet->data,
326 fec_packet->length); 323 fec_packet->length);
327
328 received_packet->seq_num = seq_num; 324 received_packet->seq_num = seq_num;
329 received_packet->is_fec = true; 325 received_packet->is_fec = true;
330 received_packet->ssrc = ssrc; 326 received_packet->ssrc = ssrc;
327 received_packet_list.push_back(std::move(received_packet));
331 328
332 fec_mask_list.push_back(fec_packet_masks[fec_packet_idx]); 329 fec_mask_list.push_back(fec_packet_masks[fec_packet_idx]);
333 } 330 }
334 ++fec_packet_idx; 331 ++fec_packet_idx;
335 ++seq_num; 332 ++seq_num;
336 } 333 }
337 334
338 #ifdef VERBOSE_OUTPUT 335 #ifdef VERBOSE_OUTPUT
339 printf("Media loss mask:\n"); 336 printf("Media loss mask:\n");
340 for (uint32_t i = 0; i < num_media_packets; i++) { 337 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. 378 // For error-checking frame completion.
382 bool fec_packet_received = false; 379 bool fec_packet_received = false;
383 while (!received_packet_list.empty()) { 380 while (!received_packet_list.empty()) {
384 size_t num_packets_to_decode = random.Rand( 381 size_t num_packets_to_decode = random.Rand(
385 1u, static_cast<uint32_t>(received_packet_list.size())); 382 1u, static_cast<uint32_t>(received_packet_list.size()));
386 ReceivePackets(&to_decode_list, &received_packet_list, 383 ReceivePackets(&to_decode_list, &received_packet_list,
387 num_packets_to_decode, reorder_rate, 384 num_packets_to_decode, reorder_rate,
388 duplicate_rate, &random); 385 duplicate_rate, &random);
389 386
390 if (fec_packet_received == false) { 387 if (fec_packet_received == false) {
391 for (auto* received_packet : to_decode_list) { 388 for (auto& received_packet : to_decode_list) {
392 if (received_packet->is_fec) { 389 if (received_packet->is_fec) {
393 fec_packet_received = true; 390 fec_packet_received = true;
394 } 391 }
395 } 392 }
396 } 393 }
397 ASSERT_EQ(0, fec.DecodeFec(&to_decode_list, 394 ASSERT_EQ(0, fec.DecodeFec(&to_decode_list,
398 &recovered_packet_list)) 395 &recovered_packet_list))
399 << "DecodeFec() failed"; 396 << "DecodeFec() failed";
400 ASSERT_TRUE(to_decode_list.empty()) 397 ASSERT_TRUE(to_decode_list.empty())
401 << "Received packet list is not empty."; 398 << "Received packet list is not empty.";
402 } 399 }
403 media_packet_idx = 0; 400 media_packet_idx = 0;
404 for (auto* media_packet : media_packet_list) { 401 for (auto& media_packet : media_packet_list) {
405 if (media_loss_mask[media_packet_idx] == 1) { 402 if (media_loss_mask[media_packet_idx] == 1) {
406 // Should have recovered this packet. 403 // Should have recovered this packet.
407 auto recovered_packet_list_it = recovered_packet_list.cbegin(); 404 auto recovered_packet_list_it = recovered_packet_list.cbegin();
408 405
409 ASSERT_FALSE(recovered_packet_list_it == 406 ASSERT_FALSE(recovered_packet_list_it ==
410 recovered_packet_list.end()) 407 recovered_packet_list.end())
411 << "Insufficient number of recovered packets."; 408 << "Insufficient number of recovered packets.";
412 ForwardErrorCorrection::RecoveredPacket* recovered_packet = 409 ForwardErrorCorrection::RecoveredPacket* recovered_packet =
413 *recovered_packet_list_it; 410 recovered_packet_list_it->get();
414 411
415 ASSERT_EQ(recovered_packet->pkt->length, media_packet->length) 412 ASSERT_EQ(recovered_packet->pkt->length, media_packet->length)
416 << "Recovered packet length not identical to original " 413 << "Recovered packet length not identical to original "
417 << "media packet"; 414 << "media packet";
418 ASSERT_EQ(0, memcmp(recovered_packet->pkt->data, 415 ASSERT_EQ(0, memcmp(recovered_packet->pkt->data,
419 media_packet->data, media_packet->length)) 416 media_packet->data, media_packet->length))
420 << "Recovered packet payload not identical to original " 417 << "Recovered packet payload not identical to original "
421 << "media packet"; 418 << "media packet";
422 delete recovered_packet;
423 recovered_packet_list.pop_front(); 419 recovered_packet_list.pop_front();
424 } 420 }
425 ++media_packet_idx; 421 ++media_packet_idx;
426 } 422 }
427 fec.ResetState(&recovered_packet_list); 423 fec.ResetState(&recovered_packet_list);
428 ASSERT_TRUE(recovered_packet_list.empty()) 424 ASSERT_TRUE(recovered_packet_list.empty())
429 << "Excessive number of recovered packets.\t size is: " 425 << "Excessive number of recovered packets.\t size is: "
430 << recovered_packet_list.size(); 426 << recovered_packet_list.size();
431 // -- Teardown -- 427 // -- Teardown --
432 auto media_packet_list_it = media_packet_list.begin(); 428 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()); 429 RTC_DCHECK(media_packet_list.empty());
danilchap 2016/06/30 19:58:37 this DCHECK looks pointless after the simplificati
brandtr 2016/07/01 10:45:34 Removed.
439 430
440 // Clear FEC packet list, so we don't pass in a non-empty 431 // Clear FEC packet list, so we don't pass in a non-empty
441 // list in the next call to DecodeFec(). 432 // list in the next call to DecodeFec().
442 fec_packet_list.clear(); 433 fec_packet_list.clear();
443 434
444 // Delete received packets we didn't pass to DecodeFec(), due to 435 // Delete received packets we didn't pass to DecodeFec(), due to
445 // early frame completion. 436 // early frame completion.
446 auto received_packet_it = received_packet_list.cbegin(); 437 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()); 438 RTC_DCHECK(received_packet_list.empty());
danilchap 2016/06/30 19:58:37 Same here
brandtr 2016/07/01 10:45:34 Done.
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