ulpfec_receiver_unittest.cc (22116B)
1 /* 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 * 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 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "modules/rtp_rtcp/source/ulpfec_receiver.h" 12 13 #include <cstdint> 14 #include <cstring> 15 #include <iterator> 16 #include <list> 17 #include <memory> 18 #include <utility> 19 20 #include "api/units/timestamp.h" 21 #include "modules/include/module_fec_types.h" 22 #include "modules/rtp_rtcp/include/recovered_packet_receiver.h" 23 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" 24 #include "modules/rtp_rtcp/mocks/mock_recovered_packet_receiver.h" 25 #include "modules/rtp_rtcp/source/byte_io.h" 26 #include "modules/rtp_rtcp/source/fec_test_helper.h" 27 #include "modules/rtp_rtcp/source/forward_error_correction.h" 28 #include "modules/rtp_rtcp/source/rtp_packet_received.h" 29 #include "system_wrappers/include/clock.h" 30 #include "test/gmock.h" 31 #include "test/gtest.h" 32 33 namespace webrtc { 34 35 namespace { 36 using ::testing::_; 37 using ::testing::Eq; 38 using ::testing::Property; 39 40 using Packet = ForwardErrorCorrection::Packet; 41 using test::fec::UlpfecPacketGenerator; 42 43 constexpr int kFecPayloadType = 96; 44 constexpr uint32_t kMediaSsrc = 835424; 45 46 class NullRecoveredPacketReceiver : public RecoveredPacketReceiver { 47 public: 48 void OnRecoveredPacket(const RtpPacketReceived& /* packet */) override {} 49 }; 50 51 } // namespace 52 53 class UlpfecReceiverTest : public ::testing::Test { 54 protected: 55 UlpfecReceiverTest() 56 : fec_(ForwardErrorCorrection::CreateUlpfec(kMediaSsrc)), 57 receiver_fec_(kMediaSsrc, 58 kFecPayloadType, 59 &recovered_packet_receiver_, 60 Clock::GetRealTimeClock()), 61 packet_generator_(kMediaSsrc) {} 62 63 // Generates `num_fec_packets` FEC packets, given `media_packets`. 64 void EncodeFec(const ForwardErrorCorrection::PacketList& media_packets, 65 size_t num_fec_packets, 66 std::list<ForwardErrorCorrection::Packet*>* fec_packets); 67 68 // Generates `num_media_packets` corresponding to a single frame. 69 void PacketizeFrame(size_t num_media_packets, 70 size_t frame_offset, 71 std::list<RtpPacketReceived>* augmented_packets, 72 ForwardErrorCorrection::PacketList* packets); 73 74 // Build a media packet using `packet_generator_` and add it 75 // to the receiver. 76 void BuildAndAddRedMediaPacket(const RtpPacketReceived& packet, 77 bool is_recovered = false); 78 79 // Build a FEC packet using `packet_generator_` and add it 80 // to the receiver. 81 void BuildAndAddRedFecPacket(Packet* packet); 82 83 // Ensure that `recovered_packet_receiver_` will be called correctly 84 // and that the recovered packet will be identical to the lost packet. 85 void VerifyReconstructedMediaPacket(const RtpPacket& packet, size_t times); 86 87 void InjectGarbagePacketLength(size_t fec_garbage_offset); 88 89 static void SurvivesMaliciousPacket(const uint8_t* data, 90 size_t length, 91 uint8_t ulpfec_payload_type); 92 93 MockRecoveredPacketReceiver recovered_packet_receiver_; 94 std::unique_ptr<ForwardErrorCorrection> fec_; 95 UlpfecReceiver receiver_fec_; 96 UlpfecPacketGenerator packet_generator_; 97 }; 98 99 void UlpfecReceiverTest::EncodeFec( 100 const ForwardErrorCorrection::PacketList& media_packets, 101 size_t num_fec_packets, 102 std::list<ForwardErrorCorrection::Packet*>* fec_packets) { 103 const uint8_t protection_factor = 104 num_fec_packets * 255 / media_packets.size(); 105 // Unequal protection is turned off, and the number of important 106 // packets is thus irrelevant. 107 constexpr int kNumImportantPackets = 0; 108 constexpr bool kUseUnequalProtection = false; 109 constexpr FecMaskType kFecMaskType = kFecMaskBursty; 110 EXPECT_EQ( 111 0, fec_->EncodeFec(media_packets, protection_factor, kNumImportantPackets, 112 kUseUnequalProtection, kFecMaskType, fec_packets)); 113 ASSERT_EQ(num_fec_packets, fec_packets->size()); 114 } 115 116 void UlpfecReceiverTest::PacketizeFrame( 117 size_t num_media_packets, 118 size_t frame_offset, 119 std::list<RtpPacketReceived>* augmented_packets, 120 ForwardErrorCorrection::PacketList* packets) { 121 packet_generator_.NewFrame(num_media_packets); 122 for (size_t i = 0; i < num_media_packets; ++i) { 123 RtpPacketReceived next_packet = 124 packet_generator_.NextPacket<RtpPacketReceived>(frame_offset + i, 125 kRtpHeaderSize + 10); 126 auto packet = std::make_unique<Packet>(); 127 packet->data = next_packet.Buffer(); 128 augmented_packets->push_back(std::move(next_packet)); 129 packets->push_back(std::move(packet)); 130 } 131 } 132 133 void UlpfecReceiverTest::BuildAndAddRedMediaPacket( 134 const RtpPacketReceived& packet, 135 bool is_recovered) { 136 EXPECT_TRUE(receiver_fec_.AddReceivedRedPacket( 137 packet_generator_.BuildMediaRedPacket(packet, is_recovered))); 138 } 139 140 void UlpfecReceiverTest::BuildAndAddRedFecPacket(Packet* packet) { 141 RtpPacketReceived red_packet = 142 packet_generator_.BuildUlpfecRedPacket(*packet); 143 EXPECT_TRUE(receiver_fec_.AddReceivedRedPacket(red_packet)); 144 } 145 146 void UlpfecReceiverTest::VerifyReconstructedMediaPacket(const RtpPacket& packet, 147 size_t times) { 148 // Verify that the content of the reconstructed packet is equal to the 149 // content of `packet`, and that the same content is received `times` number 150 // of times in a row. 151 EXPECT_CALL(recovered_packet_receiver_, 152 OnRecoveredPacket( 153 Property(&RtpPacketReceived::Buffer, Eq(packet.Buffer())))) 154 .Times(times); 155 } 156 157 void UlpfecReceiverTest::InjectGarbagePacketLength(size_t fec_garbage_offset) { 158 EXPECT_CALL(recovered_packet_receiver_, OnRecoveredPacket(_)); 159 160 const size_t kNumFecPackets = 1; 161 std::list<RtpPacketReceived> augmented_media_packets; 162 ForwardErrorCorrection::PacketList media_packets; 163 PacketizeFrame(2, 0, &augmented_media_packets, &media_packets); 164 std::list<ForwardErrorCorrection::Packet*> fec_packets; 165 EncodeFec(media_packets, kNumFecPackets, &fec_packets); 166 ByteWriter<uint16_t>::WriteBigEndian( 167 fec_packets.front()->data.MutableData() + fec_garbage_offset, 0x4711); 168 169 // Inject first media packet, then first FEC packet, skipping the second media 170 // packet to cause a recovery from the FEC packet. 171 BuildAndAddRedMediaPacket(augmented_media_packets.front()); 172 BuildAndAddRedFecPacket(fec_packets.front()); 173 receiver_fec_.ProcessReceivedFec(); 174 175 FecPacketCounter counter = receiver_fec_.GetPacketCounter(); 176 EXPECT_EQ(2U, counter.num_packets); 177 EXPECT_EQ(1U, counter.num_fec_packets); 178 EXPECT_EQ(0U, counter.num_recovered_packets); 179 } 180 181 void UlpfecReceiverTest::SurvivesMaliciousPacket(const uint8_t* data, 182 size_t length, 183 uint8_t ulpfec_payload_type) { 184 NullRecoveredPacketReceiver null_callback; 185 UlpfecReceiver receiver_fec(kMediaSsrc, ulpfec_payload_type, &null_callback, 186 Clock::GetRealTimeClock()); 187 188 RtpPacketReceived rtp_packet; 189 ASSERT_TRUE(rtp_packet.Parse(data, length)); 190 receiver_fec.AddReceivedRedPacket(rtp_packet); 191 } 192 193 TEST_F(UlpfecReceiverTest, TwoMediaOneFec) { 194 constexpr size_t kNumFecPackets = 1u; 195 std::list<RtpPacketReceived> augmented_media_packets; 196 ForwardErrorCorrection::PacketList media_packets; 197 PacketizeFrame(2, 0, &augmented_media_packets, &media_packets); 198 std::list<ForwardErrorCorrection::Packet*> fec_packets; 199 EncodeFec(media_packets, kNumFecPackets, &fec_packets); 200 201 FecPacketCounter counter = receiver_fec_.GetPacketCounter(); 202 EXPECT_EQ(0u, counter.num_packets); 203 EXPECT_EQ(Timestamp::MinusInfinity(), counter.first_packet_time); 204 205 // Recovery 206 auto it = augmented_media_packets.begin(); 207 BuildAndAddRedMediaPacket(*it); 208 VerifyReconstructedMediaPacket(*it, 1); 209 210 receiver_fec_.ProcessReceivedFec(); 211 counter = receiver_fec_.GetPacketCounter(); 212 EXPECT_EQ(1u, counter.num_packets); 213 EXPECT_EQ(0u, counter.num_fec_packets); 214 EXPECT_EQ(0u, counter.num_recovered_packets); 215 const Timestamp first_packet_time = counter.first_packet_time; 216 EXPECT_NE(Timestamp::MinusInfinity(), first_packet_time); 217 218 // Drop one media packet. 219 auto fec_it = fec_packets.begin(); 220 BuildAndAddRedFecPacket(*fec_it); 221 ++it; 222 VerifyReconstructedMediaPacket(*it, 1); 223 receiver_fec_.ProcessReceivedFec(); 224 225 counter = receiver_fec_.GetPacketCounter(); 226 EXPECT_EQ(2u, counter.num_packets); 227 EXPECT_EQ(1u, counter.num_fec_packets); 228 EXPECT_EQ(1u, counter.num_recovered_packets); 229 EXPECT_EQ(first_packet_time, counter.first_packet_time); 230 } 231 232 TEST_F(UlpfecReceiverTest, TwoMediaOneFecNotUsesRecoveredPackets) { 233 constexpr size_t kNumFecPackets = 1u; 234 std::list<RtpPacketReceived> augmented_media_packets; 235 ForwardErrorCorrection::PacketList media_packets; 236 PacketizeFrame(2, 0, &augmented_media_packets, &media_packets); 237 std::list<ForwardErrorCorrection::Packet*> fec_packets; 238 EncodeFec(media_packets, kNumFecPackets, &fec_packets); 239 240 FecPacketCounter counter = receiver_fec_.GetPacketCounter(); 241 EXPECT_EQ(0u, counter.num_packets); 242 EXPECT_EQ(Timestamp::MinusInfinity(), counter.first_packet_time); 243 244 // Recovery 245 auto it = augmented_media_packets.begin(); 246 BuildAndAddRedMediaPacket(*it, /*is_recovered=*/true); 247 VerifyReconstructedMediaPacket(*it, 1); 248 receiver_fec_.ProcessReceivedFec(); 249 counter = receiver_fec_.GetPacketCounter(); 250 EXPECT_EQ(1u, counter.num_packets); 251 EXPECT_EQ(0u, counter.num_fec_packets); 252 EXPECT_EQ(0u, counter.num_recovered_packets); 253 const Timestamp first_packet_time = counter.first_packet_time; 254 EXPECT_NE(Timestamp::MinusInfinity(), first_packet_time); 255 256 // Drop one media packet. 257 auto fec_it = fec_packets.begin(); 258 BuildAndAddRedFecPacket(*fec_it); 259 ++it; 260 receiver_fec_.ProcessReceivedFec(); 261 262 counter = receiver_fec_.GetPacketCounter(); 263 EXPECT_EQ(2u, counter.num_packets); 264 EXPECT_EQ(1u, counter.num_fec_packets); 265 EXPECT_EQ(0u, counter.num_recovered_packets); 266 EXPECT_EQ(first_packet_time, counter.first_packet_time); 267 } 268 269 TEST_F(UlpfecReceiverTest, InjectGarbageFecHeaderLengthRecovery) { 270 // Byte offset 8 is the 'length recovery' field of the FEC header. 271 InjectGarbagePacketLength(8); 272 } 273 274 TEST_F(UlpfecReceiverTest, InjectGarbageFecLevelHeaderProtectionLength) { 275 // Byte offset 10 is the 'protection length' field in the first FEC level 276 // header. 277 InjectGarbagePacketLength(10); 278 } 279 280 TEST_F(UlpfecReceiverTest, TwoMediaTwoFec) { 281 const size_t kNumFecPackets = 2; 282 std::list<RtpPacketReceived> augmented_media_packets; 283 ForwardErrorCorrection::PacketList media_packets; 284 PacketizeFrame(2, 0, &augmented_media_packets, &media_packets); 285 std::list<ForwardErrorCorrection::Packet*> fec_packets; 286 EncodeFec(media_packets, kNumFecPackets, &fec_packets); 287 288 // Recovery 289 // Drop both media packets. 290 auto it = augmented_media_packets.begin(); 291 auto fec_it = fec_packets.begin(); 292 BuildAndAddRedFecPacket(*fec_it); 293 VerifyReconstructedMediaPacket(*it, 1); 294 receiver_fec_.ProcessReceivedFec(); 295 ++fec_it; 296 BuildAndAddRedFecPacket(*fec_it); 297 ++it; 298 VerifyReconstructedMediaPacket(*it, 1); 299 receiver_fec_.ProcessReceivedFec(); 300 } 301 302 TEST_F(UlpfecReceiverTest, TwoFramesOneFec) { 303 const size_t kNumFecPackets = 1; 304 std::list<RtpPacketReceived> augmented_media_packets; 305 ForwardErrorCorrection::PacketList media_packets; 306 PacketizeFrame(1, 0, &augmented_media_packets, &media_packets); 307 PacketizeFrame(1, 1, &augmented_media_packets, &media_packets); 308 std::list<ForwardErrorCorrection::Packet*> fec_packets; 309 EncodeFec(media_packets, kNumFecPackets, &fec_packets); 310 311 // Recovery 312 auto it = augmented_media_packets.begin(); 313 BuildAndAddRedMediaPacket(augmented_media_packets.front()); 314 VerifyReconstructedMediaPacket(*it, 1); 315 receiver_fec_.ProcessReceivedFec(); 316 // Drop one media packet. 317 BuildAndAddRedFecPacket(fec_packets.front()); 318 ++it; 319 VerifyReconstructedMediaPacket(*it, 1); 320 receiver_fec_.ProcessReceivedFec(); 321 } 322 323 TEST_F(UlpfecReceiverTest, OneCompleteOneUnrecoverableFrame) { 324 const size_t kNumFecPackets = 1; 325 std::list<RtpPacketReceived> augmented_media_packets; 326 ForwardErrorCorrection::PacketList media_packets; 327 PacketizeFrame(1, 0, &augmented_media_packets, &media_packets); 328 PacketizeFrame(2, 1, &augmented_media_packets, &media_packets); 329 330 std::list<ForwardErrorCorrection::Packet*> fec_packets; 331 EncodeFec(media_packets, kNumFecPackets, &fec_packets); 332 333 // Recovery 334 auto it = augmented_media_packets.begin(); 335 BuildAndAddRedMediaPacket(*it); // First frame: one packet. 336 VerifyReconstructedMediaPacket(*it, 1); 337 receiver_fec_.ProcessReceivedFec(); 338 ++it; 339 BuildAndAddRedMediaPacket(*it); // First packet of second frame. 340 VerifyReconstructedMediaPacket(*it, 1); 341 receiver_fec_.ProcessReceivedFec(); 342 } 343 344 TEST_F(UlpfecReceiverTest, MaxFramesOneFec) { 345 const size_t kNumFecPackets = 1; 346 const size_t kNumMediaPackets = 48; 347 std::list<RtpPacketReceived> augmented_media_packets; 348 ForwardErrorCorrection::PacketList media_packets; 349 for (size_t i = 0; i < kNumMediaPackets; ++i) { 350 PacketizeFrame(1, i, &augmented_media_packets, &media_packets); 351 } 352 std::list<ForwardErrorCorrection::Packet*> fec_packets; 353 EncodeFec(media_packets, kNumFecPackets, &fec_packets); 354 355 // Recovery 356 auto it = augmented_media_packets.begin(); 357 ++it; // Drop first packet. 358 for (; it != augmented_media_packets.end(); ++it) { 359 BuildAndAddRedMediaPacket(*it); 360 VerifyReconstructedMediaPacket(*it, 1); 361 receiver_fec_.ProcessReceivedFec(); 362 } 363 BuildAndAddRedFecPacket(fec_packets.front()); 364 it = augmented_media_packets.begin(); 365 VerifyReconstructedMediaPacket(*it, 1); 366 receiver_fec_.ProcessReceivedFec(); 367 } 368 369 TEST_F(UlpfecReceiverTest, TooManyFrames) { 370 const size_t kNumFecPackets = 1; 371 const size_t kNumMediaPackets = 49; 372 std::list<RtpPacketReceived> augmented_media_packets; 373 ForwardErrorCorrection::PacketList media_packets; 374 for (size_t i = 0; i < kNumMediaPackets; ++i) { 375 PacketizeFrame(1, i, &augmented_media_packets, &media_packets); 376 } 377 std::list<ForwardErrorCorrection::Packet*> fec_packets; 378 EXPECT_EQ(-1, fec_->EncodeFec(media_packets, 379 kNumFecPackets * 255 / kNumMediaPackets, 0, 380 false, kFecMaskBursty, &fec_packets)); 381 } 382 383 TEST_F(UlpfecReceiverTest, PacketNotDroppedTooEarly) { 384 // 1 frame with 2 media packets and one FEC packet. One media packet missing. 385 // Delay the FEC packet. 386 Packet* delayed_fec = nullptr; 387 const size_t kNumFecPacketsBatch1 = 1; 388 const size_t kNumMediaPacketsBatch1 = 2; 389 std::list<RtpPacketReceived> augmented_media_packets_batch1; 390 ForwardErrorCorrection::PacketList media_packets_batch1; 391 PacketizeFrame(kNumMediaPacketsBatch1, 0, &augmented_media_packets_batch1, 392 &media_packets_batch1); 393 std::list<ForwardErrorCorrection::Packet*> fec_packets; 394 EncodeFec(media_packets_batch1, kNumFecPacketsBatch1, &fec_packets); 395 396 BuildAndAddRedMediaPacket(augmented_media_packets_batch1.front()); 397 EXPECT_CALL(recovered_packet_receiver_, OnRecoveredPacket(_)).Times(1); 398 receiver_fec_.ProcessReceivedFec(); 399 delayed_fec = fec_packets.front(); 400 401 // Fill the FEC decoder. No packets should be dropped. 402 const size_t kNumMediaPacketsBatch2 = 191; 403 std::list<RtpPacketReceived> augmented_media_packets_batch2; 404 ForwardErrorCorrection::PacketList media_packets_batch2; 405 for (size_t i = 0; i < kNumMediaPacketsBatch2; ++i) { 406 PacketizeFrame(1, i, &augmented_media_packets_batch2, 407 &media_packets_batch2); 408 } 409 for (auto it = augmented_media_packets_batch2.begin(); 410 it != augmented_media_packets_batch2.end(); ++it) { 411 BuildAndAddRedMediaPacket(*it); 412 EXPECT_CALL(recovered_packet_receiver_, OnRecoveredPacket(_)).Times(1); 413 receiver_fec_.ProcessReceivedFec(); 414 } 415 416 // Add the delayed FEC packet. One packet should be reconstructed. 417 BuildAndAddRedFecPacket(delayed_fec); 418 EXPECT_CALL(recovered_packet_receiver_, OnRecoveredPacket(_)).Times(1); 419 receiver_fec_.ProcessReceivedFec(); 420 } 421 422 TEST_F(UlpfecReceiverTest, PacketDroppedWhenTooOld) { 423 // 1 frame with 2 media packets and one FEC packet. One media packet missing. 424 // Delay the FEC packet. 425 Packet* delayed_fec = nullptr; 426 const size_t kNumFecPacketsBatch1 = 1; 427 const size_t kNumMediaPacketsBatch1 = 2; 428 std::list<RtpPacketReceived> augmented_media_packets_batch1; 429 ForwardErrorCorrection::PacketList media_packets_batch1; 430 PacketizeFrame(kNumMediaPacketsBatch1, 0, &augmented_media_packets_batch1, 431 &media_packets_batch1); 432 std::list<ForwardErrorCorrection::Packet*> fec_packets; 433 EncodeFec(media_packets_batch1, kNumFecPacketsBatch1, &fec_packets); 434 435 BuildAndAddRedMediaPacket(augmented_media_packets_batch1.front()); 436 EXPECT_CALL(recovered_packet_receiver_, OnRecoveredPacket(_)).Times(1); 437 receiver_fec_.ProcessReceivedFec(); 438 delayed_fec = fec_packets.front(); 439 440 // Fill the FEC decoder and force the last packet to be dropped. 441 const size_t kNumMediaPacketsBatch2 = 192; 442 std::list<RtpPacketReceived> augmented_media_packets_batch2; 443 ForwardErrorCorrection::PacketList media_packets_batch2; 444 for (size_t i = 0; i < kNumMediaPacketsBatch2; ++i) { 445 PacketizeFrame(1, i, &augmented_media_packets_batch2, 446 &media_packets_batch2); 447 } 448 for (auto it = augmented_media_packets_batch2.begin(); 449 it != augmented_media_packets_batch2.end(); ++it) { 450 BuildAndAddRedMediaPacket(*it); 451 EXPECT_CALL(recovered_packet_receiver_, OnRecoveredPacket(_)).Times(1); 452 receiver_fec_.ProcessReceivedFec(); 453 } 454 455 // Add the delayed FEC packet. No packet should be reconstructed since the 456 // first media packet of that frame has been dropped due to being too old. 457 BuildAndAddRedFecPacket(delayed_fec); 458 EXPECT_CALL(recovered_packet_receiver_, OnRecoveredPacket(_)).Times(0); 459 receiver_fec_.ProcessReceivedFec(); 460 } 461 462 TEST_F(UlpfecReceiverTest, OldFecPacketDropped) { 463 // 49 frames with 2 media packets and one FEC packet. All media packets 464 // missing. 465 const size_t kNumMediaPackets = 49 * 2; 466 std::list<RtpPacketReceived> augmented_media_packets; 467 ForwardErrorCorrection::PacketList media_packets; 468 for (size_t i = 0; i < kNumMediaPackets / 2; ++i) { 469 std::list<RtpPacketReceived> frame_augmented_media_packets; 470 ForwardErrorCorrection::PacketList frame_media_packets; 471 std::list<ForwardErrorCorrection::Packet*> fec_packets; 472 PacketizeFrame(2, 0, &frame_augmented_media_packets, &frame_media_packets); 473 EncodeFec(frame_media_packets, 1, &fec_packets); 474 for (auto it = fec_packets.begin(); it != fec_packets.end(); ++it) { 475 // Only FEC packets inserted. No packets recoverable at this time. 476 BuildAndAddRedFecPacket(*it); 477 EXPECT_CALL(recovered_packet_receiver_, OnRecoveredPacket(_)).Times(0); 478 receiver_fec_.ProcessReceivedFec(); 479 } 480 // Move unique_ptr's to media_packets for lifetime management. 481 media_packets.insert(media_packets.end(), 482 std::make_move_iterator(frame_media_packets.begin()), 483 std::make_move_iterator(frame_media_packets.end())); 484 augmented_media_packets.insert(augmented_media_packets.end(), 485 frame_augmented_media_packets.begin(), 486 frame_augmented_media_packets.end()); 487 } 488 // Insert the oldest media packet. The corresponding FEC packet is too old 489 // and should have been dropped. Only the media packet we inserted will be 490 // returned. 491 BuildAndAddRedMediaPacket(augmented_media_packets.front()); 492 EXPECT_CALL(recovered_packet_receiver_, OnRecoveredPacket(_)).Times(1); 493 receiver_fec_.ProcessReceivedFec(); 494 } 495 496 TEST_F(UlpfecReceiverTest, TruncatedPacketWithFBitSet) { 497 const uint8_t kTruncatedPacket[] = {0x80, 0x2a, 0x68, 0x71, 0x29, 0xa1, 0x27, 498 0x3a, 0x29, 0x12, 0x2a, 0x98, 0xe0, 0x29}; 499 500 SurvivesMaliciousPacket(kTruncatedPacket, sizeof(kTruncatedPacket), 100); 501 } 502 503 TEST_F(UlpfecReceiverTest, 504 TruncatedPacketWithFBitSetEndingAfterFirstRedHeader) { 505 const uint8_t kPacket[] = { 506 0x89, 0x27, 0x3a, 0x83, 0x27, 0x3a, 0x3a, 0xf3, 0x67, 0xbe, 0x2a, 507 0xa9, 0x27, 0x54, 0x3a, 0x3a, 0x2a, 0x67, 0x3a, 0xf3, 0x67, 0xbe, 508 0x2a, 0x27, 0xe6, 0xf6, 0x03, 0x3e, 0x29, 0x27, 0x21, 0x27, 0x2a, 509 0x29, 0x21, 0x4b, 0x29, 0x3a, 0x28, 0x29, 0xbf, 0x29, 0x2a, 0x26, 510 0x29, 0xae, 0x27, 0xa6, 0xf6, 0x00, 0x03, 0x3e}; 511 SurvivesMaliciousPacket(kPacket, sizeof(kPacket), 100); 512 } 513 514 TEST_F(UlpfecReceiverTest, TruncatedPacketWithoutDataPastFirstBlock) { 515 const uint8_t kPacket[] = { 516 0x82, 0x38, 0x92, 0x38, 0x92, 0x38, 0xde, 0x2a, 0x11, 0xc8, 0xa3, 0xc4, 517 0x82, 0x38, 0x2a, 0x21, 0x2a, 0x28, 0x92, 0x38, 0x92, 0x00, 0x00, 0x0a, 518 0x3a, 0xc8, 0xa3, 0x3a, 0x27, 0xc4, 0x2a, 0x21, 0x2a, 0x28}; 519 SurvivesMaliciousPacket(kPacket, sizeof(kPacket), 100); 520 } 521 522 TEST_F(UlpfecReceiverTest, MediaWithPadding) { 523 const size_t kNumFecPackets = 1; 524 std::list<RtpPacketReceived> augmented_media_packets; 525 ForwardErrorCorrection::PacketList media_packets; 526 PacketizeFrame(2, 0, &augmented_media_packets, &media_packets); 527 528 augmented_media_packets.front().SetPadding(/*padding_size=*/4); 529 media_packets.front()->data = augmented_media_packets.front().Buffer(); 530 531 std::list<ForwardErrorCorrection::Packet*> fec_packets; 532 EncodeFec(media_packets, kNumFecPackets, &fec_packets); 533 534 auto it = augmented_media_packets.begin(); 535 BuildAndAddRedMediaPacket(augmented_media_packets.front()); 536 537 VerifyReconstructedMediaPacket(*it, 1); 538 receiver_fec_.ProcessReceivedFec(); 539 540 BuildAndAddRedFecPacket(fec_packets.front()); 541 ++it; 542 VerifyReconstructedMediaPacket(*it, 1); 543 receiver_fec_.ProcessReceivedFec(); 544 } 545 546 } // namespace webrtc