| 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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 memcpy(duplicate_packet->pkt->data, received_packet->pkt->data, | 71 memcpy(duplicate_packet->pkt->data, received_packet->pkt->data, |
| 72 received_packet->pkt->length); | 72 received_packet->pkt->length); |
| 73 duplicate_packet->pkt->length = received_packet->pkt->length; | 73 duplicate_packet->pkt->length = received_packet->pkt->length; |
| 74 | 74 |
| 75 to_decode_list->push_back(std::move(duplicate_packet)); | 75 to_decode_list->push_back(std::move(duplicate_packet)); |
| 76 random_variable = random->Rand<float>(); | 76 random_variable = random->Rand<float>(); |
| 77 } | 77 } |
| 78 } | 78 } |
| 79 } | 79 } |
| 80 | 80 |
| 81 // Too slow to finish before timeout on iOS. See webrtc:4755. | 81 void RunTest(bool use_flexfec) { |
| 82 #if defined(WEBRTC_IOS) | |
| 83 #define MAYBE_FecTest DISABLED_FecTest | |
| 84 #else | |
| 85 #define MAYBE_FecTest FecTest | |
| 86 #endif | |
| 87 TEST(FecTest, MAYBE_FecTest) { | |
| 88 // TODO(marpan): Split this function into subroutines/helper functions. | 82 // TODO(marpan): Split this function into subroutines/helper functions. |
| 89 enum { kMaxNumberMediaPackets = 48 }; | 83 enum { kMaxNumberMediaPackets = 48 }; |
| 90 enum { kMaxNumberFecPackets = 48 }; | 84 enum { kMaxNumberFecPackets = 48 }; |
| 91 | 85 |
| 92 const uint32_t kNumMaskBytesL0 = 2; | 86 const uint32_t kNumMaskBytesL0 = 2; |
| 93 const uint32_t kNumMaskBytesL1 = 6; | 87 const uint32_t kNumMaskBytesL1 = 6; |
| 94 | 88 |
| 95 // FOR UEP | 89 // FOR UEP |
| 96 const bool kUseUnequalProtection = true; | 90 const bool kUseUnequalProtection = true; |
| 97 | 91 |
| 98 // FEC mask types. | 92 // FEC mask types. |
| 99 const FecMaskType kMaskTypes[] = {kFecMaskRandom, kFecMaskBursty}; | 93 const FecMaskType kMaskTypes[] = {kFecMaskRandom, kFecMaskBursty}; |
| 100 const int kNumFecMaskTypes = sizeof(kMaskTypes) / sizeof(*kMaskTypes); | 94 const int kNumFecMaskTypes = sizeof(kMaskTypes) / sizeof(*kMaskTypes); |
| 101 | 95 |
| 102 // Maximum number of media packets allowed for the mask type. | 96 // Maximum number of media packets allowed for the mask type. |
| 103 const uint16_t kMaxMediaPackets[] = { | 97 const uint16_t kMaxMediaPackets[] = { |
| 104 kMaxNumberMediaPackets, | 98 kMaxNumberMediaPackets, |
| 105 sizeof(kPacketMaskBurstyTbl) / sizeof(*kPacketMaskBurstyTbl)}; | 99 sizeof(kPacketMaskBurstyTbl) / sizeof(*kPacketMaskBurstyTbl)}; |
| 106 | 100 |
| 107 ASSERT_EQ(12, kMaxMediaPackets[1]) << "Max media packets for bursty mode not " | 101 ASSERT_EQ(12, kMaxMediaPackets[1]) << "Max media packets for bursty mode not " |
| 108 << "equal to 12."; | 102 << "equal to 12."; |
| 109 | 103 |
| 110 std::unique_ptr<ForwardErrorCorrection> fec = | |
| 111 ForwardErrorCorrection::CreateUlpfec(); | |
| 112 ForwardErrorCorrection::PacketList media_packet_list; | 104 ForwardErrorCorrection::PacketList media_packet_list; |
| 113 std::list<ForwardErrorCorrection::Packet*> fec_packet_list; | 105 std::list<ForwardErrorCorrection::Packet*> fec_packet_list; |
| 114 ForwardErrorCorrection::ReceivedPacketList to_decode_list; | 106 ForwardErrorCorrection::ReceivedPacketList to_decode_list; |
| 115 ForwardErrorCorrection::ReceivedPacketList received_packet_list; | 107 ForwardErrorCorrection::ReceivedPacketList received_packet_list; |
| 116 ForwardErrorCorrection::RecoveredPacketList recovered_packet_list; | 108 ForwardErrorCorrection::RecoveredPacketList recovered_packet_list; |
| 117 std::list<uint8_t*> fec_mask_list; | 109 std::list<uint8_t*> fec_mask_list; |
| 118 | 110 |
| 119 // Running over only one loss rate to limit execution time. | 111 // Running over only one loss rate to limit execution time. |
| 120 const float loss_rate[] = {0.5f}; | 112 const float loss_rate[] = {0.5f}; |
| 121 const uint32_t loss_rate_size = sizeof(loss_rate) / sizeof(*loss_rate); | 113 const uint32_t loss_rate_size = sizeof(loss_rate) / sizeof(*loss_rate); |
| 122 const float reorder_rate = 0.1f; | 114 const float reorder_rate = 0.1f; |
| 123 const float duplicate_rate = 0.1f; | 115 const float duplicate_rate = 0.1f; |
| 124 | 116 |
| 125 uint8_t media_loss_mask[kMaxNumberMediaPackets]; | 117 uint8_t media_loss_mask[kMaxNumberMediaPackets]; |
| 126 uint8_t fec_loss_mask[kMaxNumberFecPackets]; | 118 uint8_t fec_loss_mask[kMaxNumberFecPackets]; |
| 127 uint8_t fec_packet_masks[kMaxNumberFecPackets][kMaxNumberMediaPackets]; | 119 uint8_t fec_packet_masks[kMaxNumberFecPackets][kMaxNumberMediaPackets]; |
| 128 | 120 |
| 129 // Seed the random number generator, storing the seed to file in order to | 121 // Seed the random number generator, storing the seed to file in order to |
| 130 // reproduce past results. | 122 // reproduce past results. |
| 131 const unsigned int random_seed = static_cast<unsigned int>(time(nullptr)); | 123 const unsigned int random_seed = static_cast<unsigned int>(time(nullptr)); |
| 132 Random random(random_seed); | 124 Random random(random_seed); |
| 133 std::string filename = webrtc::test::OutputPath() + "randomSeedLog.txt"; | 125 std::string filename = webrtc::test::OutputPath() + "randomSeedLog.txt"; |
| 134 FILE* random_seed_file = fopen(filename.c_str(), "a"); | 126 FILE* random_seed_file = fopen(filename.c_str(), "a"); |
| 135 fprintf(random_seed_file, "%u\n", random_seed); | 127 fprintf(random_seed_file, "%u\n", random_seed); |
| 136 fclose(random_seed_file); | 128 fclose(random_seed_file); |
| 137 random_seed_file = nullptr; | 129 random_seed_file = nullptr; |
| 138 | 130 |
| 139 uint16_t seq_num = 0; | 131 uint16_t seq_num = 0; |
| 140 uint32_t timestamp = random.Rand<uint32_t>(); | 132 uint32_t timestamp = random.Rand<uint32_t>(); |
| 141 const uint32_t ssrc = random.Rand(1u, 0xfffffffe); | 133 const uint32_t media_ssrc = random.Rand(1u, 0xfffffffe); |
| 134 uint32_t fec_ssrc; |
| 135 uint16_t fec_seq_num_offset; |
| 136 if (use_flexfec) { |
| 137 fec_ssrc = random.Rand(1u, 0xfffffffe); |
| 138 fec_seq_num_offset = random.Rand<uint16_t>(); |
| 139 } else { |
| 140 fec_ssrc = media_ssrc; |
| 141 fec_seq_num_offset = 0; |
| 142 } |
| 143 |
| 144 std::unique_ptr<ForwardErrorCorrection> fec; |
| 145 if (use_flexfec) { |
| 146 fec = ForwardErrorCorrection::CreateFlexfec(fec_ssrc, media_ssrc); |
| 147 } else { |
| 148 RTC_DCHECK_EQ(media_ssrc, fec_ssrc); |
| 149 fec = ForwardErrorCorrection::CreateUlpfec(fec_ssrc); |
| 150 } |
| 142 | 151 |
| 143 // Loop over the mask types: random and bursty. | 152 // Loop over the mask types: random and bursty. |
| 144 for (int mask_type_idx = 0; mask_type_idx < kNumFecMaskTypes; | 153 for (int mask_type_idx = 0; mask_type_idx < kNumFecMaskTypes; |
| 145 ++mask_type_idx) { | 154 ++mask_type_idx) { |
| 146 for (uint32_t loss_rate_idx = 0; loss_rate_idx < loss_rate_size; | 155 for (uint32_t loss_rate_idx = 0; loss_rate_idx < loss_rate_size; |
| 147 ++loss_rate_idx) { | 156 ++loss_rate_idx) { |
| 148 printf("Loss rate: %.2f, Mask type %d \n", loss_rate[loss_rate_idx], | 157 printf("Loss rate: %.2f, Mask type %d \n", loss_rate[loss_rate_idx], |
| 149 mask_type_idx); | 158 mask_type_idx); |
| 150 | 159 |
| 151 const uint32_t packet_mask_max = kMaxMediaPackets[mask_type_idx]; | 160 const uint32_t packet_mask_max = kMaxMediaPackets[mask_type_idx]; |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 261 // the marker bit set followed by the last packet of | 270 // the marker bit set followed by the last packet of |
| 262 // the frame for which the marker bit is set. | 271 // the frame for which the marker bit is set. |
| 263 // Only push one (fake) frame to the FEC. | 272 // Only push one (fake) frame to the FEC. |
| 264 media_packet->data[1] &= 0x7f; | 273 media_packet->data[1] &= 0x7f; |
| 265 | 274 |
| 266 ByteWriter<uint16_t>::WriteBigEndian(&media_packet->data[2], | 275 ByteWriter<uint16_t>::WriteBigEndian(&media_packet->data[2], |
| 267 seq_num); | 276 seq_num); |
| 268 ByteWriter<uint32_t>::WriteBigEndian(&media_packet->data[4], | 277 ByteWriter<uint32_t>::WriteBigEndian(&media_packet->data[4], |
| 269 timestamp); | 278 timestamp); |
| 270 ByteWriter<uint32_t>::WriteBigEndian(&media_packet->data[8], | 279 ByteWriter<uint32_t>::WriteBigEndian(&media_packet->data[8], |
| 271 ssrc); | 280 media_ssrc); |
| 272 // Generate random values for payload | 281 // Generate random values for payload |
| 273 for (size_t j = 12; j < media_packet->length; ++j) { | 282 for (size_t j = 12; j < media_packet->length; ++j) { |
| 274 media_packet->data[j] = random.Rand<uint8_t>(); | 283 media_packet->data[j] = random.Rand<uint8_t>(); |
| 275 } | 284 } |
| 276 media_packet_list.push_back(std::move(media_packet)); | 285 media_packet_list.push_back(std::move(media_packet)); |
| 277 seq_num++; | 286 seq_num++; |
| 278 } | 287 } |
| 279 media_packet_list.back()->data[1] |= 0x80; | 288 media_packet_list.back()->data[1] |= 0x80; |
| 280 | 289 |
| 281 ASSERT_EQ(0, fec->EncodeFec(media_packet_list, protection_factor, | 290 ASSERT_EQ(0, fec->EncodeFec(media_packet_list, protection_factor, |
| (...skipping 13 matching lines...) Expand all Loading... |
| 295 | 304 |
| 296 if (loss_random_variable >= loss_rate[loss_rate_idx]) { | 305 if (loss_random_variable >= loss_rate[loss_rate_idx]) { |
| 297 media_loss_mask[media_packet_idx] = 1; | 306 media_loss_mask[media_packet_idx] = 1; |
| 298 std::unique_ptr<ForwardErrorCorrection::ReceivedPacket> | 307 std::unique_ptr<ForwardErrorCorrection::ReceivedPacket> |
| 299 received_packet( | 308 received_packet( |
| 300 new ForwardErrorCorrection::ReceivedPacket()); | 309 new ForwardErrorCorrection::ReceivedPacket()); |
| 301 received_packet->pkt = new ForwardErrorCorrection::Packet(); | 310 received_packet->pkt = new ForwardErrorCorrection::Packet(); |
| 302 received_packet->pkt->length = media_packet->length; | 311 received_packet->pkt->length = media_packet->length; |
| 303 memcpy(received_packet->pkt->data, media_packet->data, | 312 memcpy(received_packet->pkt->data, media_packet->data, |
| 304 media_packet->length); | 313 media_packet->length); |
| 314 received_packet->ssrc = media_ssrc; |
| 305 received_packet->seq_num = | 315 received_packet->seq_num = |
| 306 ByteReader<uint16_t>::ReadBigEndian(&media_packet->data[2]); | 316 ByteReader<uint16_t>::ReadBigEndian(&media_packet->data[2]); |
| 307 received_packet->is_fec = false; | 317 received_packet->is_fec = false; |
| 308 received_packet_list.push_back(std::move(received_packet)); | 318 received_packet_list.push_back(std::move(received_packet)); |
| 309 } | 319 } |
| 310 media_packet_idx++; | 320 media_packet_idx++; |
| 311 } | 321 } |
| 312 | 322 |
| 313 memset(fec_loss_mask, 0, sizeof(fec_loss_mask)); | 323 memset(fec_loss_mask, 0, sizeof(fec_loss_mask)); |
| 314 uint32_t fec_packet_idx = 0; | 324 uint32_t fec_packet_idx = 0; |
| 315 for (auto* fec_packet : fec_packet_list) { | 325 for (auto* fec_packet : fec_packet_list) { |
| 316 const float loss_random_variable = random.Rand<float>(); | 326 const float loss_random_variable = random.Rand<float>(); |
| 317 if (loss_random_variable >= loss_rate[loss_rate_idx]) { | 327 if (loss_random_variable >= loss_rate[loss_rate_idx]) { |
| 318 fec_loss_mask[fec_packet_idx] = 1; | 328 fec_loss_mask[fec_packet_idx] = 1; |
| 319 std::unique_ptr<ForwardErrorCorrection::ReceivedPacket> | 329 std::unique_ptr<ForwardErrorCorrection::ReceivedPacket> |
| 320 received_packet( | 330 received_packet( |
| 321 new ForwardErrorCorrection::ReceivedPacket()); | 331 new ForwardErrorCorrection::ReceivedPacket()); |
| 322 received_packet->pkt = new ForwardErrorCorrection::Packet(); | 332 received_packet->pkt = new ForwardErrorCorrection::Packet(); |
| 323 received_packet->pkt->length = fec_packet->length; | 333 received_packet->pkt->length = fec_packet->length; |
| 324 memcpy(received_packet->pkt->data, fec_packet->data, | 334 memcpy(received_packet->pkt->data, fec_packet->data, |
| 325 fec_packet->length); | 335 fec_packet->length); |
| 326 received_packet->seq_num = seq_num; | 336 received_packet->seq_num = fec_seq_num_offset + seq_num; |
| 327 received_packet->is_fec = true; | 337 received_packet->is_fec = true; |
| 328 received_packet->ssrc = ssrc; | 338 received_packet->ssrc = fec_ssrc; |
| 329 received_packet_list.push_back(std::move(received_packet)); | 339 received_packet_list.push_back(std::move(received_packet)); |
| 330 | 340 |
| 331 fec_mask_list.push_back(fec_packet_masks[fec_packet_idx]); | 341 fec_mask_list.push_back(fec_packet_masks[fec_packet_idx]); |
| 332 } | 342 } |
| 333 ++fec_packet_idx; | 343 ++fec_packet_idx; |
| 334 ++seq_num; | 344 ++seq_num; |
| 335 } | 345 } |
| 336 | 346 |
| 337 #ifdef VERBOSE_OUTPUT | 347 #ifdef VERBOSE_OUTPUT |
| 338 printf("Media loss mask:\n"); | 348 printf("Media loss mask:\n"); |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 446 } // loop over num_media_packets | 456 } // loop over num_media_packets |
| 447 } // loop over loss rates | 457 } // loop over loss rates |
| 448 } // loop over mask types | 458 } // loop over mask types |
| 449 | 459 |
| 450 // Have DecodeFec clear the recovered packet list. | 460 // Have DecodeFec clear the recovered packet list. |
| 451 fec->ResetState(&recovered_packet_list); | 461 fec->ResetState(&recovered_packet_list); |
| 452 ASSERT_TRUE(recovered_packet_list.empty()) | 462 ASSERT_TRUE(recovered_packet_list.empty()) |
| 453 << "Recovered packet list is not empty"; | 463 << "Recovered packet list is not empty"; |
| 454 } | 464 } |
| 455 | 465 |
| 466 // Too slow to finish before timeout on iOS. See webrtc:4755. |
| 467 #if defined(WEBRTC_IOS) |
| 468 #define MAYBE_UlpecTest DISABLED_UlpecTest |
| 469 #define MAYBE_FlexfecTest DISABLED_FlexfecTest |
| 470 #else |
| 471 #define MAYBE_UlpecTest UlpecTest |
| 472 #define MAYBE_FlexfecTest FlexfecTest |
| 473 #endif |
| 474 TEST(FecTest, MAYBE_UlpecTest) { |
| 475 RunTest(false); |
| 476 } |
| 477 |
| 478 TEST(FecTest, MAYBE_FlexfecTest) { |
| 479 RunTest(true); |
| 480 } |
| 481 |
| 456 } // namespace test | 482 } // namespace test |
| 457 } // namespace webrtc | 483 } // namespace webrtc |
| OLD | NEW |