diff --git a/webrtc/modules/rtp_rtcp/source/fec_receiver_impl.cc b/webrtc/modules/rtp_rtcp/source/fec_receiver_impl.cc index 83bd2849df..29cde65b12 100644 --- a/webrtc/modules/rtp_rtcp/source/fec_receiver_impl.cc +++ b/webrtc/modules/rtp_rtcp/source/fec_receiver_impl.cc @@ -10,10 +10,9 @@ #include "webrtc/modules/rtp_rtcp/source/fec_receiver_impl.h" -#include - #include +#include "webrtc/base/checks.h" #include "webrtc/base/logging.h" #include "webrtc/modules/rtp_rtcp/source/byte_io.h" #include "webrtc/modules/rtp_rtcp/source/rtp_receiver_video.h" @@ -89,8 +88,8 @@ int32_t FecReceiverImpl::AddReceivedRedPacket( // we remove the RED header std::unique_ptr received_packet( - new ForwardErrorCorrection::ReceivedPacket); - received_packet->pkt = new ForwardErrorCorrection::Packet; + new ForwardErrorCorrection::ReceivedPacket()); + received_packet->pkt = new ForwardErrorCorrection::Packet(); // get payload type from RED header uint8_t payload_type = @@ -159,8 +158,8 @@ int32_t FecReceiverImpl::AddReceivedRedPacket( received_packet->pkt->length = blockLength; - second_received_packet.reset(new ForwardErrorCorrection::ReceivedPacket); - second_received_packet->pkt = new ForwardErrorCorrection::Packet; + second_received_packet.reset(new ForwardErrorCorrection::ReceivedPacket()); + second_received_packet->pkt = new ForwardErrorCorrection::Packet(); second_received_packet->is_fec = true; second_received_packet->seq_num = header.sequenceNumber; @@ -231,19 +230,19 @@ int32_t FecReceiverImpl::ProcessReceivedFec() { } crit_sect_.Enter(); } - if (fec_->DecodeFEC(&received_packet_list_, &recovered_packet_list_) != 0) { + if (fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_) != 0) { crit_sect_.Leave(); return -1; } - assert(received_packet_list_.empty()); + RTC_DCHECK(received_packet_list_.empty()); } // Send any recovered media packets to VCM. - ForwardErrorCorrection::RecoveredPacketList::iterator it = - recovered_packet_list_.begin(); - for (; it != recovered_packet_list_.end(); ++it) { - if ((*it)->returned) // Already sent to the VCM and the jitter buffer. + for(auto* recovered_packet : recovered_packet_list_) { + if (recovered_packet->returned) { + // Already sent to the VCM and the jitter buffer. continue; - ForwardErrorCorrection::Packet* packet = (*it)->pkt; + } + ForwardErrorCorrection::Packet* packet = recovered_packet->pkt; ++packet_counter_.num_recovered_packets; crit_sect_.Leave(); if (!recovered_packet_callback_->OnRecoveredPacket(packet->data, @@ -251,7 +250,7 @@ int32_t FecReceiverImpl::ProcessReceivedFec() { return -1; } crit_sect_.Enter(); - (*it)->returned = true; + recovered_packet->returned = true; } crit_sect_.Leave(); return 0; diff --git a/webrtc/modules/rtp_rtcp/source/fec_receiver_unittest.cc b/webrtc/modules/rtp_rtcp/source/fec_receiver_unittest.cc index cd60d9b094..0c66dc1f52 100644 --- a/webrtc/modules/rtp_rtcp/source/fec_receiver_unittest.cc +++ b/webrtc/modules/rtp_rtcp/source/fec_receiver_unittest.cc @@ -38,11 +38,11 @@ class ReceiverFecTest : public ::testing::Test { generator_.reset(new FrameGenerator()); } - void GenerateFEC(std::list* media_packets, - std::list* fec_packets, + void GenerateFec(ForwardErrorCorrection::PacketList* media_packets, + ForwardErrorCorrection::PacketList* fec_packets, unsigned int num_fec_packets) { uint8_t protection_factor = num_fec_packets * 255 / media_packets->size(); - EXPECT_EQ(0, fec_->GenerateFEC(*media_packets, protection_factor, + EXPECT_EQ(0, fec_->GenerateFec(*media_packets, protection_factor, 0, false, kFecMaskBursty, fec_packets)); ASSERT_EQ(num_fec_packets, fec_packets->size()); } @@ -50,7 +50,7 @@ class ReceiverFecTest : public ::testing::Test { void GenerateFrame(int num_media_packets, int frame_offset, std::list* media_rtp_packets, - std::list* media_packets) { + ForwardErrorCorrection::PacketList* media_packets) { generator_->NewFrame(num_media_packets); for (int i = 0; i < num_media_packets; ++i) { media_rtp_packets->push_back( @@ -97,7 +97,7 @@ class ReceiverFecTest : public ::testing::Test { std::unique_ptr generator_; }; -void DeletePackets(std::list* packets) { +void DeletePackets(ForwardErrorCorrection::PacketList* packets) { while (!packets->empty()) { delete packets->front(); packets->pop_front(); @@ -107,18 +107,18 @@ void DeletePackets(std::list* packets) { TEST_F(ReceiverFecTest, TwoMediaOneFec) { const unsigned int kNumFecPackets = 1u; std::list media_rtp_packets; - std::list media_packets; + ForwardErrorCorrection::PacketList media_packets; GenerateFrame(2, 0, &media_rtp_packets, &media_packets); - std::list fec_packets; - GenerateFEC(&media_packets, &fec_packets, kNumFecPackets); + ForwardErrorCorrection::PacketList fec_packets; + GenerateFec(&media_packets, &fec_packets, kNumFecPackets); // Recovery - std::list::iterator it = media_rtp_packets.begin(); + auto it = media_rtp_packets.begin(); BuildAndAddRedMediaPacket(*it); VerifyReconstructedMediaPacket(*it, 1); EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); // Drop one media packet. - std::list::iterator fec_it = fec_packets.begin(); + auto fec_it = fec_packets.begin(); BuildAndAddRedFecPacket(*fec_it); ++it; VerifyReconstructedMediaPacket(*it, 1); @@ -138,10 +138,10 @@ void ReceiverFecTest::InjectGarbagePacketLength(size_t fec_garbage_offset) { const unsigned int kNumFecPackets = 1u; std::list media_rtp_packets; - std::list media_packets; + ForwardErrorCorrection::PacketList media_packets; GenerateFrame(2, 0, &media_rtp_packets, &media_packets); - std::list fec_packets; - GenerateFEC(&media_packets, &fec_packets, kNumFecPackets); + ForwardErrorCorrection::PacketList fec_packets; + GenerateFec(&media_packets, &fec_packets, kNumFecPackets); ByteWriter::WriteBigEndian( &fec_packets.front()->data[fec_garbage_offset], 0x4711); @@ -173,15 +173,15 @@ TEST_F(ReceiverFecTest, InjectGarbageFecLevelHeaderProtectionLength) { TEST_F(ReceiverFecTest, TwoMediaTwoFec) { const unsigned int kNumFecPackets = 2u; std::list media_rtp_packets; - std::list media_packets; + ForwardErrorCorrection::PacketList media_packets; GenerateFrame(2, 0, &media_rtp_packets, &media_packets); - std::list fec_packets; - GenerateFEC(&media_packets, &fec_packets, kNumFecPackets); + ForwardErrorCorrection::PacketList fec_packets; + GenerateFec(&media_packets, &fec_packets, kNumFecPackets); // Recovery // Drop both media packets. - std::list::iterator it = media_rtp_packets.begin(); - std::list::iterator fec_it = fec_packets.begin(); + auto it = media_rtp_packets.begin(); + auto fec_it = fec_packets.begin(); BuildAndAddRedFecPacket(*fec_it); VerifyReconstructedMediaPacket(*it, 1); EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); @@ -197,14 +197,14 @@ TEST_F(ReceiverFecTest, TwoMediaTwoFec) { TEST_F(ReceiverFecTest, TwoFramesOneFec) { const unsigned int kNumFecPackets = 1u; std::list media_rtp_packets; - std::list media_packets; + ForwardErrorCorrection::PacketList media_packets; GenerateFrame(1, 0, &media_rtp_packets, &media_packets); GenerateFrame(1, 1, &media_rtp_packets, &media_packets); - std::list fec_packets; - GenerateFEC(&media_packets, &fec_packets, kNumFecPackets); + ForwardErrorCorrection::PacketList fec_packets; + GenerateFec(&media_packets, &fec_packets, kNumFecPackets); // Recovery - std::list::iterator it = media_rtp_packets.begin(); + auto it = media_rtp_packets.begin(); BuildAndAddRedMediaPacket(media_rtp_packets.front()); VerifyReconstructedMediaPacket(*it, 1); EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); @@ -220,15 +220,15 @@ TEST_F(ReceiverFecTest, TwoFramesOneFec) { TEST_F(ReceiverFecTest, OneCompleteOneUnrecoverableFrame) { const unsigned int kNumFecPackets = 1u; std::list media_rtp_packets; - std::list media_packets; + ForwardErrorCorrection::PacketList media_packets; GenerateFrame(1, 0, &media_rtp_packets, &media_packets); GenerateFrame(2, 1, &media_rtp_packets, &media_packets); - std::list fec_packets; - GenerateFEC(&media_packets, &fec_packets, kNumFecPackets); + ForwardErrorCorrection::PacketList fec_packets; + GenerateFec(&media_packets, &fec_packets, kNumFecPackets); // Recovery - std::list::iterator it = media_rtp_packets.begin(); + auto it = media_rtp_packets.begin(); BuildAndAddRedMediaPacket(*it); // First frame: one packet. VerifyReconstructedMediaPacket(*it, 1); EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec()); @@ -244,15 +244,15 @@ TEST_F(ReceiverFecTest, MaxFramesOneFec) { const unsigned int kNumFecPackets = 1u; const unsigned int kNumMediaPackets = 48u; std::list media_rtp_packets; - std::list media_packets; + ForwardErrorCorrection::PacketList media_packets; for (unsigned int i = 0; i < kNumMediaPackets; ++i) { GenerateFrame(1, i, &media_rtp_packets, &media_packets); } - std::list fec_packets; - GenerateFEC(&media_packets, &fec_packets, kNumFecPackets); + ForwardErrorCorrection::PacketList fec_packets; + GenerateFec(&media_packets, &fec_packets, kNumFecPackets); // Recovery - std::list::iterator it = media_rtp_packets.begin(); + auto it = media_rtp_packets.begin(); ++it; // Drop first packet. for (; it != media_rtp_packets.end(); ++it) { BuildAndAddRedMediaPacket(*it); @@ -271,12 +271,12 @@ TEST_F(ReceiverFecTest, TooManyFrames) { const unsigned int kNumFecPackets = 1u; const unsigned int kNumMediaPackets = 49u; std::list media_rtp_packets; - std::list media_packets; + ForwardErrorCorrection::PacketList media_packets; for (unsigned int i = 0; i < kNumMediaPackets; ++i) { GenerateFrame(1, i, &media_rtp_packets, &media_packets); } - std::list fec_packets; - EXPECT_EQ(-1, fec_->GenerateFEC(media_packets, + ForwardErrorCorrection::PacketList fec_packets; + EXPECT_EQ(-1, fec_->GenerateFec(media_packets, kNumFecPackets * 255 / kNumMediaPackets, 0, false, kFecMaskBursty, &fec_packets)); @@ -290,11 +290,11 @@ TEST_F(ReceiverFecTest, PacketNotDroppedTooEarly) { const unsigned int kNumFecPacketsBatch1 = 1u; const unsigned int kNumMediaPacketsBatch1 = 2u; std::list media_rtp_packets_batch1; - std::list media_packets_batch1; + ForwardErrorCorrection::PacketList media_packets_batch1; GenerateFrame(kNumMediaPacketsBatch1, 0, &media_rtp_packets_batch1, &media_packets_batch1); - std::list fec_packets; - GenerateFEC(&media_packets_batch1, &fec_packets, kNumFecPacketsBatch1); + ForwardErrorCorrection::PacketList fec_packets; + GenerateFec(&media_packets_batch1, &fec_packets, kNumFecPacketsBatch1); BuildAndAddRedMediaPacket(media_rtp_packets_batch1.front()); EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) @@ -305,12 +305,11 @@ TEST_F(ReceiverFecTest, PacketNotDroppedTooEarly) { // Fill the FEC decoder. No packets should be dropped. const unsigned int kNumMediaPacketsBatch2 = 46u; std::list media_rtp_packets_batch2; - std::list media_packets_batch2; + ForwardErrorCorrection::PacketList media_packets_batch2; for (unsigned int i = 0; i < kNumMediaPacketsBatch2; ++i) { GenerateFrame(1, i, &media_rtp_packets_batch2, &media_packets_batch2); } - for (std::list::iterator it = - media_rtp_packets_batch2.begin(); + for (auto it = media_rtp_packets_batch2.begin(); it != media_rtp_packets_batch2.end(); ++it) { BuildAndAddRedMediaPacket(*it); EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) @@ -335,11 +334,11 @@ TEST_F(ReceiverFecTest, PacketDroppedWhenTooOld) { const unsigned int kNumFecPacketsBatch1 = 1u; const unsigned int kNumMediaPacketsBatch1 = 2u; std::list media_rtp_packets_batch1; - std::list media_packets_batch1; + ForwardErrorCorrection::PacketList media_packets_batch1; GenerateFrame(kNumMediaPacketsBatch1, 0, &media_rtp_packets_batch1, &media_packets_batch1); - std::list fec_packets; - GenerateFEC(&media_packets_batch1, &fec_packets, kNumFecPacketsBatch1); + ForwardErrorCorrection::PacketList fec_packets; + GenerateFec(&media_packets_batch1, &fec_packets, kNumFecPacketsBatch1); BuildAndAddRedMediaPacket(media_rtp_packets_batch1.front()); EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) @@ -350,12 +349,11 @@ TEST_F(ReceiverFecTest, PacketDroppedWhenTooOld) { // Fill the FEC decoder and force the last packet to be dropped. const unsigned int kNumMediaPacketsBatch2 = 48u; std::list media_rtp_packets_batch2; - std::list media_packets_batch2; + ForwardErrorCorrection::PacketList media_packets_batch2; for (unsigned int i = 0; i < kNumMediaPacketsBatch2; ++i) { GenerateFrame(1, i, &media_rtp_packets_batch2, &media_packets_batch2); } - for (std::list::iterator it = - media_rtp_packets_batch2.begin(); + for (auto it = media_rtp_packets_batch2.begin(); it != media_rtp_packets_batch2.end(); ++it) { BuildAndAddRedMediaPacket(*it); EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) @@ -379,15 +377,14 @@ TEST_F(ReceiverFecTest, OldFecPacketDropped) { // missing. const unsigned int kNumMediaPackets = 49 * 2; std::list media_rtp_packets; - std::list media_packets; + ForwardErrorCorrection::PacketList media_packets; for (unsigned int i = 0; i < kNumMediaPackets / 2; ++i) { std::list frame_media_rtp_packets; - std::list frame_media_packets; - std::list fec_packets; + ForwardErrorCorrection::PacketList frame_media_packets; + ForwardErrorCorrection::PacketList fec_packets; GenerateFrame(2, 0, &frame_media_rtp_packets, &frame_media_packets); - GenerateFEC(&frame_media_packets, &fec_packets, 1); - for (std::list::iterator it = fec_packets.begin(); - it != fec_packets.end(); ++it) { + GenerateFec(&frame_media_packets, &fec_packets, 1); + for (auto it = fec_packets.begin(); it != fec_packets.end(); ++it) { // Only FEC packets inserted. No packets recoverable at this time. BuildAndAddRedFecPacket(*it); EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _)) diff --git a/webrtc/modules/rtp_rtcp/source/forward_error_correction.cc b/webrtc/modules/rtp_rtcp/source/forward_error_correction.cc index 623c658a17..ecaa86e5d2 100644 --- a/webrtc/modules/rtp_rtcp/source/forward_error_correction.cc +++ b/webrtc/modules/rtp_rtcp/source/forward_error_correction.cc @@ -10,7 +10,6 @@ #include "webrtc/modules/rtp_rtcp/source/forward_error_correction.h" -#include #include #include @@ -26,18 +25,19 @@ namespace webrtc { // FEC header size in bytes. -const uint8_t kFecHeaderSize = 10; +constexpr size_t kFecHeaderSize = 10; // ULP header size in bytes (L bit is set). -const uint8_t kUlpHeaderSizeLBitSet = (2 + kMaskSizeLBitSet); +constexpr size_t kUlpHeaderSizeLBitSet = (2 + kMaskSizeLBitSet); // ULP header size in bytes (L bit is cleared). -const uint8_t kUlpHeaderSizeLBitClear = (2 + kMaskSizeLBitClear); +constexpr size_t kUlpHeaderSizeLBitClear = (2 + kMaskSizeLBitClear); // Transport header size in bytes. Assume UDP/IPv4 as a reasonable minimum. -const uint8_t kTransportOverhead = 28; +constexpr size_t kTransportOverhead = 28; -enum { kMaxFecPackets = ForwardErrorCorrection::kMaxMediaPackets }; +// Maximum number of FEC packets stored internally. +constexpr size_t kMaxFecPackets = ForwardErrorCorrection::kMaxMediaPackets; int32_t ForwardErrorCorrection::Packet::AddRef() { return ++ref_count_; @@ -85,8 +85,8 @@ ForwardErrorCorrection::RecoveredPacket::RecoveredPacket() {} ForwardErrorCorrection::RecoveredPacket::~RecoveredPacket() {} ForwardErrorCorrection::ForwardErrorCorrection() - : generated_fec_packets_(kMaxMediaPackets), fec_packet_received_(false) {} - + : generated_fec_packets_(kMaxMediaPackets), fec_packet_list_(), + packet_mask_(), tmp_packet_mask_() {} ForwardErrorCorrection::~ForwardErrorCorrection() {} // Input packet @@ -106,18 +106,21 @@ ForwardErrorCorrection::~ForwardErrorCorrection() {} // | FEC Level 0 Payload | // | | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -int32_t ForwardErrorCorrection::GenerateFEC(const PacketList& media_packet_list, - uint8_t protection_factor, - int num_important_packets, - bool use_unequal_protection, - FecMaskType fec_mask_type, - PacketList* fec_packet_list) { +// +// Note that any potential RED headers are added/removed before calling +// GenerateFec() or DecodeFec(). +int ForwardErrorCorrection::GenerateFec(const PacketList& media_packet_list, + uint8_t protection_factor, + int num_important_packets, + bool use_unequal_protection, + FecMaskType fec_mask_type, + PacketList* fec_packet_list) { const uint16_t num_media_packets = media_packet_list.size(); // Sanity check arguments. - assert(num_media_packets > 0); - assert(num_important_packets >= 0 && - num_important_packets <= num_media_packets); - assert(fec_packet_list->empty()); + RTC_DCHECK_GT(num_media_packets, 0); + RTC_DCHECK_GE(num_important_packets, 0); + RTC_DCHECK_LE(num_important_packets, num_media_packets); + RTC_DCHECK(fec_packet_list->empty()); if (num_media_packets > kMaxMediaPackets) { LOG(LS_WARNING) << "Can't protect " << num_media_packets @@ -130,7 +133,7 @@ int32_t ForwardErrorCorrection::GenerateFEC(const PacketList& media_packet_list, // Do some error checking on the media packets. for (Packet* media_packet : media_packet_list) { - assert(media_packet); + RTC_DCHECK(media_packet); if (media_packet->length < kRtpHeaderSize) { LOG(LS_WARNING) << "Media packet " << media_packet->length << " bytes " @@ -163,29 +166,26 @@ int32_t ForwardErrorCorrection::GenerateFEC(const PacketList& media_packet_list, const internal::PacketMaskTable mask_table(fec_mask_type, num_media_packets); // -- Generate packet masks -- - // Always allocate space for a large mask. - std::unique_ptr packet_mask( - new uint8_t[num_fec_packets * kMaskSizeLBitSet]); - memset(packet_mask.get(), 0, num_fec_packets * num_mask_bytes); + memset(packet_mask_, 0, num_fec_packets * num_mask_bytes); internal::GeneratePacketMasks(num_media_packets, num_fec_packets, num_important_packets, use_unequal_protection, - mask_table, packet_mask.get()); + mask_table, packet_mask_); int num_mask_bits = InsertZerosInBitMasks( - media_packet_list, packet_mask.get(), num_mask_bytes, num_fec_packets); + media_packet_list, packet_mask_, num_mask_bytes, num_fec_packets); if (num_mask_bits < 0) { return -1; } - l_bit = (num_mask_bits > 8 * kMaskSizeLBitClear); + l_bit = (static_cast(num_mask_bits) > 8 * kMaskSizeLBitClear); if (l_bit) { num_mask_bytes = kMaskSizeLBitSet; } - GenerateFecBitStrings(media_packet_list, packet_mask.get(), num_fec_packets, - l_bit); - GenerateFecUlpHeaders(media_packet_list, packet_mask.get(), l_bit, - num_fec_packets); + GenerateFecBitStrings(media_packet_list, packet_mask_, + num_fec_packets, l_bit); + GenerateFecUlpHeaders(media_packet_list, packet_mask_, + num_fec_packets, l_bit); return 0; } @@ -198,7 +198,7 @@ int ForwardErrorCorrection::GetNumberOfFecPackets(int num_media_packets, if (protection_factor > 0 && num_fec_packets == 0) { num_fec_packets = 1; } - assert(num_fec_packets <= num_media_packets); + RTC_DCHECK_LE(num_fec_packets, num_media_packets); return num_fec_packets; } @@ -207,9 +207,7 @@ void ForwardErrorCorrection::GenerateFecBitStrings( uint8_t* packet_mask, int num_fec_packets, bool l_bit) { - if (media_packet_list.empty()) { - return; - } + RTC_DCHECK(!media_packet_list.empty()); uint8_t media_payload_length[2]; const int num_mask_bytes = l_bit ? kMaskSizeLBitSet : kMaskSizeLBitClear; const uint16_t ulp_header_size = @@ -219,7 +217,7 @@ void ForwardErrorCorrection::GenerateFecBitStrings( for (int i = 0; i < num_fec_packets; ++i) { Packet* const fec_packet = &generated_fec_packets_[i]; - PacketList::const_iterator media_list_it = media_packet_list.begin(); + auto media_list_it = media_packet_list.cbegin(); uint32_t pkt_mask_idx = i * num_mask_bytes; uint32_t media_pkt_idx = 0; uint16_t fec_packet_length = 0; @@ -237,9 +235,10 @@ void ForwardErrorCorrection::GenerateFecBitStrings( fec_packet_length = media_packet->length + fec_rtp_offset; // On the first protected packet, we don't need to XOR. if (fec_packet->length == 0) { - // Copy the first 2 bytes of the RTP header. - memcpy(fec_packet->data, media_packet->data, 2); - // Copy the 5th to 8th bytes of the RTP header. + // Copy the first 2 bytes of the RTP header. Note that the E and L + // bits are overwritten in GenerateFecUlpHeaders. + memcpy(&fec_packet->data[0], &media_packet->data[0], 2); + // Copy the 5th to 8th bytes of the RTP header (timestamp). memcpy(&fec_packet->data[4], &media_packet->data[4], 4); // Copy network-ordered payload size. memcpy(&fec_packet->data[8], media_payload_length, 2); @@ -291,7 +290,6 @@ int ForwardErrorCorrection::InsertZerosInBitMasks( uint8_t* packet_mask, int num_mask_bytes, int num_fec_packets) { - uint8_t* new_mask = NULL; if (media_packets.size() <= 1) { return media_packets.size(); } @@ -313,15 +311,14 @@ int ForwardErrorCorrection::InsertZerosInBitMasks( if (media_packets.size() + total_missing_seq_nums > 8 * kMaskSizeLBitClear) { new_mask_bytes = kMaskSizeLBitSet; } - new_mask = new uint8_t[num_fec_packets * kMaskSizeLBitSet]; - memset(new_mask, 0, num_fec_packets * kMaskSizeLBitSet); + memset(tmp_packet_mask_, 0, num_fec_packets * kMaskSizeLBitSet); - PacketList::const_iterator it = media_packets.begin(); + auto it = media_packets.cbegin(); uint16_t prev_seq_num = first_seq_num; ++it; // Insert the first column. - CopyColumn(new_mask, new_mask_bytes, packet_mask, num_mask_bytes, + CopyColumn(tmp_packet_mask_, new_mask_bytes, packet_mask, num_mask_bytes, num_fec_packets, 0, 0); int new_bit_index = 1; int old_bit_index = 1; @@ -335,11 +332,11 @@ int ForwardErrorCorrection::InsertZerosInBitMasks( const int zeros_to_insert = static_cast(seq_num - prev_seq_num - 1); if (zeros_to_insert > 0) { - InsertZeroColumns(zeros_to_insert, new_mask, new_mask_bytes, + InsertZeroColumns(zeros_to_insert, tmp_packet_mask_, new_mask_bytes, num_fec_packets, new_bit_index); } new_bit_index += zeros_to_insert; - CopyColumn(new_mask, new_mask_bytes, packet_mask, num_mask_bytes, + CopyColumn(tmp_packet_mask_, new_mask_bytes, packet_mask, num_mask_bytes, num_fec_packets, new_bit_index, old_bit_index); ++new_bit_index; ++old_bit_index; @@ -349,12 +346,11 @@ int ForwardErrorCorrection::InsertZerosInBitMasks( // We didn't fill the last byte. Shift bits to correct position. for (uint16_t row = 0; row < num_fec_packets; ++row) { int new_byte_index = row * new_mask_bytes + new_bit_index / 8; - new_mask[new_byte_index] <<= (7 - (new_bit_index % 8)); + tmp_packet_mask_[new_byte_index] <<= (7 - (new_bit_index % 8)); } } // Replace the old mask with the new. - memcpy(packet_mask, new_mask, kMaskSizeLBitSet * num_fec_packets); - delete[] new_mask; + memcpy(packet_mask, tmp_packet_mask_, kMaskSizeLBitSet * num_fec_packets); return new_bit_index; } @@ -393,8 +389,8 @@ void ForwardErrorCorrection::CopyColumn(uint8_t* new_mask, void ForwardErrorCorrection::GenerateFecUlpHeaders( const PacketList& media_packet_list, uint8_t* packet_mask, - bool l_bit, - int num_fec_packets) { + int num_fec_packets, + bool l_bit) { // -- Generate FEC and ULP headers -- // // FEC Header, 10 bytes @@ -416,13 +412,14 @@ void ForwardErrorCorrection::GenerateFecUlpHeaders( // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // | mask cont. (present only when L = 1) | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - PacketList::const_iterator media_list_it = media_packet_list.begin(); - Packet* media_packet = *media_list_it; - assert(media_packet != NULL); int num_mask_bytes = l_bit ? kMaskSizeLBitSet : kMaskSizeLBitClear; const uint16_t ulp_header_size = l_bit ? kUlpHeaderSizeLBitSet : kUlpHeaderSizeLBitClear; + RTC_DCHECK(!media_packet_list.empty()); + Packet* first_media_packet = media_packet_list.front(); + RTC_DCHECK(first_media_packet); + uint16_t seq_num = ParseSequenceNumber(first_media_packet->data); for (int i = 0; i < num_fec_packets; ++i) { Packet* const fec_packet = &generated_fec_packets_[i]; // -- FEC header -- @@ -432,10 +429,10 @@ void ForwardErrorCorrection::GenerateFecUlpHeaders( } else { fec_packet->data[0] |= 0x40; // Set the L bit. } - // Two byte sequence number from first RTP packet to SN base. + // Sequence number from first media packet used as SN base. // We use the same sequence number base for every FEC packet, // but that's not required in general. - memcpy(&fec_packet->data[2], &media_packet->data[2], 2); + ByteWriter::WriteBigEndian(&fec_packet->data[2], seq_num); // -- ULP header -- // Copy the payload size to the protection length field. @@ -452,72 +449,67 @@ void ForwardErrorCorrection::GenerateFecUlpHeaders( void ForwardErrorCorrection::ResetState( RecoveredPacketList* recovered_packet_list) { - fec_packet_received_ = false; - // Free the memory for any existing recovered packets, if the user hasn't. while (!recovered_packet_list->empty()) { delete recovered_packet_list->front(); recovered_packet_list->pop_front(); } - assert(recovered_packet_list->empty()); + RTC_DCHECK(recovered_packet_list->empty()); // Free the FEC packet list. while (!fec_packet_list_.empty()) { - FecPacketList::iterator fec_packet_list_it = fec_packet_list_.begin(); - FecPacket* fec_packet = *fec_packet_list_it; - ProtectedPacketList::iterator protected_packet_list_it; - protected_packet_list_it = fec_packet->protected_pkt_list.begin(); + FecPacket* fec_packet = fec_packet_list_.front(); + auto protected_packet_list_it = fec_packet->protected_pkt_list.begin(); while (protected_packet_list_it != fec_packet->protected_pkt_list.end()) { delete *protected_packet_list_it; protected_packet_list_it = fec_packet->protected_pkt_list.erase(protected_packet_list_it); } - assert(fec_packet->protected_pkt_list.empty()); + RTC_DCHECK(fec_packet->protected_pkt_list.empty()); delete fec_packet; fec_packet_list_.pop_front(); } - assert(fec_packet_list_.empty()); + RTC_DCHECK(fec_packet_list_.empty()); } void ForwardErrorCorrection::InsertMediaPacket( ReceivedPacket* rx_packet, RecoveredPacketList* recovered_packet_list) { - RecoveredPacketList::iterator recovered_packet_list_it = - recovered_packet_list->begin(); + auto recovered_packet_list_it = recovered_packet_list->cbegin(); // Search for duplicate packets. while (recovered_packet_list_it != recovered_packet_list->end()) { if (rx_packet->seq_num == (*recovered_packet_list_it)->seq_num) { // Duplicate packet, no need to add to list. // Delete duplicate media packet data. - rx_packet->pkt = NULL; + rx_packet->pkt = nullptr; return; } - recovered_packet_list_it++; + ++recovered_packet_list_it; } - RecoveredPacket* recoverd_packet_to_insert = new RecoveredPacket; - recoverd_packet_to_insert->was_recovered = false; + RecoveredPacket* recovered_packet_to_insert = new RecoveredPacket(); + recovered_packet_to_insert->was_recovered = false; // Inserted Media packet is already sent to VCM. - recoverd_packet_to_insert->returned = true; - recoverd_packet_to_insert->seq_num = rx_packet->seq_num; - recoverd_packet_to_insert->pkt = rx_packet->pkt; - recoverd_packet_to_insert->pkt->length = rx_packet->pkt->length; + recovered_packet_to_insert->returned = true; + recovered_packet_to_insert->seq_num = rx_packet->seq_num; + recovered_packet_to_insert->pkt = rx_packet->pkt; + recovered_packet_to_insert->pkt->length = rx_packet->pkt->length; // TODO(holmer): Consider replacing this with a binary search for the right // position, and then just insert the new packet. Would get rid of the sort. - recovered_packet_list->push_back(recoverd_packet_to_insert); + recovered_packet_list->push_back(recovered_packet_to_insert); recovered_packet_list->sort(SortablePacket::LessThan); - UpdateCoveringFECPackets(recoverd_packet_to_insert); + UpdateCoveringFecPackets(recovered_packet_to_insert); } -void ForwardErrorCorrection::UpdateCoveringFECPackets(RecoveredPacket* packet) { - for (FecPacketList::iterator it = fec_packet_list_.begin(); - it != fec_packet_list_.end(); ++it) { +void ForwardErrorCorrection::UpdateCoveringFecPackets(RecoveredPacket* packet) { + for (auto* fec_packet : fec_packet_list_) { // Is this FEC packet protecting the media packet |packet|? - ProtectedPacketList::iterator protected_it = std::lower_bound( - (*it)->protected_pkt_list.begin(), (*it)->protected_pkt_list.end(), - packet, SortablePacket::LessThan); - if (protected_it != (*it)->protected_pkt_list.end() && + auto protected_it = std::lower_bound(fec_packet->protected_pkt_list.begin(), + fec_packet->protected_pkt_list.end(), + packet, + SortablePacket::LessThan); + if (protected_it != fec_packet->protected_pkt_list.end() && (*protected_it)->seq_num == packet->seq_num) { // Found an FEC packet which is protecting |packet|. (*protected_it)->pkt = packet->pkt; @@ -525,22 +517,18 @@ void ForwardErrorCorrection::UpdateCoveringFECPackets(RecoveredPacket* packet) { } } -void ForwardErrorCorrection::InsertFECPacket( +void ForwardErrorCorrection::InsertFecPacket( ReceivedPacket* rx_packet, const RecoveredPacketList* recovered_packet_list) { - fec_packet_received_ = true; - // Check for duplicate. - FecPacketList::iterator fec_packet_list_it = fec_packet_list_.begin(); - while (fec_packet_list_it != fec_packet_list_.end()) { - if (rx_packet->seq_num == (*fec_packet_list_it)->seq_num) { + for (auto* fec_packet : fec_packet_list_) { + if (rx_packet->seq_num == fec_packet->seq_num) { // Delete duplicate FEC packet data. - rx_packet->pkt = NULL; + rx_packet->pkt = nullptr; return; } - fec_packet_list_it++; } - FecPacket* fec_packet = new FecPacket; + FecPacket* fec_packet = new FecPacket(); fec_packet->pkt = rx_packet->pkt; fec_packet->seq_num = rx_packet->seq_num; fec_packet->ssrc = rx_packet->ssrc; @@ -555,12 +543,12 @@ void ForwardErrorCorrection::InsertFECPacket( uint8_t packet_mask = fec_packet->pkt->data[12 + byte_idx]; for (uint16_t bit_idx = 0; bit_idx < 8; ++bit_idx) { if (packet_mask & (1 << (7 - bit_idx))) { - ProtectedPacket* protected_packet = new ProtectedPacket; + ProtectedPacket* protected_packet = new ProtectedPacket(); fec_packet->protected_pkt_list.push_back(protected_packet); // This wraps naturally with the sequence number. protected_packet->seq_num = static_cast(seq_num_base + (byte_idx << 3) + bit_idx); - protected_packet->pkt = NULL; + protected_packet->pkt = nullptr; } } } @@ -575,10 +563,10 @@ void ForwardErrorCorrection::InsertFECPacket( fec_packet_list_.push_back(fec_packet); fec_packet_list_.sort(SortablePacket::LessThan); if (fec_packet_list_.size() > kMaxFecPackets) { - DiscardFECPacket(fec_packet_list_.front()); + DiscardFecPacket(fec_packet_list_.front()); fec_packet_list_.pop_front(); } - assert(fec_packet_list_.size() <= kMaxFecPackets); + RTC_DCHECK_LE(fec_packet_list_.size(), kMaxFecPackets); } } @@ -590,14 +578,14 @@ void ForwardErrorCorrection::AssignRecoveredPackets( ProtectedPacketList* not_recovered = &fec_packet->protected_pkt_list; RecoveredPacketList already_recovered; std::set_intersection( - recovered_packets->begin(), recovered_packets->end(), - not_recovered->begin(), not_recovered->end(), + recovered_packets->cbegin(), recovered_packets->cend(), + not_recovered->cbegin(), not_recovered->cend(), std::inserter(already_recovered, already_recovered.end()), SortablePacket::LessThan); // Set the FEC pointers to all recovered packets so that we don't have to // search for them when we are doing recovery. - ProtectedPacketList::iterator not_recovered_it = not_recovered->begin(); - for (RecoveredPacketList::iterator it = already_recovered.begin(); + auto not_recovered_it = not_recovered->cbegin(); + for (auto it = already_recovered.cbegin(); it != already_recovered.end(); ++it) { // Search for the next recovered packet in |not_recovered|. while ((*not_recovered_it)->seq_num != (*it)->seq_num) @@ -624,13 +612,13 @@ void ForwardErrorCorrection::InsertPackets( abs(static_cast(rx_packet->seq_num) - static_cast(fec_packet_list_.front()->seq_num)); if (seq_num_diff > 0x3fff) { - DiscardFECPacket(fec_packet_list_.front()); + DiscardFecPacket(fec_packet_list_.front()); fec_packet_list_.pop_front(); } } if (rx_packet->is_fec) { - InsertFECPacket(rx_packet, recovered_packet_list); + InsertFecPacket(rx_packet, recovered_packet_list); } else { // Insert packet at the end of |recoveredPacketList|. InsertMediaPacket(rx_packet, recovered_packet_list); @@ -639,12 +627,12 @@ void ForwardErrorCorrection::InsertPackets( delete rx_packet; received_packet_list->pop_front(); } - assert(received_packet_list->empty()); + RTC_DCHECK(received_packet_list->empty()); DiscardOldPackets(recovered_packet_list); } -bool ForwardErrorCorrection::InitRecovery(const FecPacket* fec_packet, - RecoveredPacket* recovered) { +bool ForwardErrorCorrection::StartPacketRecovery(const FecPacket* fec_packet, + RecoveredPacket* recovered) { // This is the first packet which we try to recover with. const uint16_t ulp_header_size = fec_packet->pkt->data[0] & 0x40 ? kUlpHeaderSizeLBitSet @@ -655,7 +643,7 @@ bool ForwardErrorCorrection::InitRecovery(const FecPacket* fec_packet, << "Truncated FEC packet doesn't contain room for ULP header."; return false; } - recovered->pkt = new Packet; + recovered->pkt = new Packet(); memset(recovered->pkt->data, 0, IP_PACKET_SIZE); recovered->returned = false; recovered->was_recovered = true; @@ -684,7 +672,7 @@ bool ForwardErrorCorrection::InitRecovery(const FecPacket* fec_packet, return true; } -bool ForwardErrorCorrection::FinishRecovery(RecoveredPacket* recovered) { +bool ForwardErrorCorrection::FinishPacketRecovery(RecoveredPacket* recovered) { // Set the RTP version to 2. recovered->pkt->data[0] |= 0x80; // Set the 1st bit. recovered->pkt->data[0] &= 0xbf; // Clear the 2nd bit. @@ -729,27 +717,24 @@ void ForwardErrorCorrection::XorPackets(const Packet* src_packet, bool ForwardErrorCorrection::RecoverPacket( const FecPacket* fec_packet, RecoveredPacket* rec_packet_to_insert) { - if (!InitRecovery(fec_packet, rec_packet_to_insert)) + if (!StartPacketRecovery(fec_packet, rec_packet_to_insert)) return false; - ProtectedPacketList::const_iterator protected_it = - fec_packet->protected_pkt_list.begin(); - while (protected_it != fec_packet->protected_pkt_list.end()) { - if ((*protected_it)->pkt == NULL) { + for (const auto* protected_packet : fec_packet->protected_pkt_list) { + if (protected_packet->pkt == nullptr) { // This is the packet we're recovering. - rec_packet_to_insert->seq_num = (*protected_it)->seq_num; + rec_packet_to_insert->seq_num = protected_packet->seq_num; } else { - XorPackets((*protected_it)->pkt, rec_packet_to_insert); + XorPackets(protected_packet->pkt, rec_packet_to_insert); } - ++protected_it; } - if (!FinishRecovery(rec_packet_to_insert)) + if (!FinishPacketRecovery(rec_packet_to_insert)) return false; return true; } void ForwardErrorCorrection::AttemptRecover( RecoveredPacketList* recovered_packet_list) { - FecPacketList::iterator fec_packet_list_it = fec_packet_list_.begin(); + auto fec_packet_list_it = fec_packet_list_.begin(); while (fec_packet_list_it != fec_packet_list_.end()) { // Search for each FEC packet's protected media packets. int packets_missing = NumCoveredPacketsMissing(*fec_packet_list_it); @@ -757,11 +742,11 @@ void ForwardErrorCorrection::AttemptRecover( // We can only recover one packet with an FEC packet. if (packets_missing == 1) { // Recovery possible. - RecoveredPacket* packet_to_insert = new RecoveredPacket; - packet_to_insert->pkt = NULL; + RecoveredPacket* packet_to_insert = new RecoveredPacket(); + packet_to_insert->pkt = nullptr; if (!RecoverPacket(*fec_packet_list_it, packet_to_insert)) { // Can't recover using this packet, drop it. - DiscardFECPacket(*fec_packet_list_it); + DiscardFecPacket(*fec_packet_list_it); fec_packet_list_it = fec_packet_list_.erase(fec_packet_list_it); delete packet_to_insert; continue; @@ -774,9 +759,9 @@ void ForwardErrorCorrection::AttemptRecover( // the sort. recovered_packet_list->push_back(packet_to_insert); recovered_packet_list->sort(SortablePacket::LessThan); - UpdateCoveringFECPackets(packet_to_insert); + UpdateCoveringFecPackets(packet_to_insert); DiscardOldPackets(recovered_packet_list); - DiscardFECPacket(*fec_packet_list_it); + DiscardFecPacket(*fec_packet_list_it); fec_packet_list_it = fec_packet_list_.erase(fec_packet_list_it); // A packet has been recovered. We need to check the FEC list again, as @@ -786,7 +771,7 @@ void ForwardErrorCorrection::AttemptRecover( } else if (packets_missing == 0) { // Either all protected packets arrived or have been recovered. We can // discard this FEC packet. - DiscardFECPacket(*fec_packet_list_it); + DiscardFecPacket(*fec_packet_list_it); fec_packet_list_it = fec_packet_list_.erase(fec_packet_list_it); } else { fec_packet_list_it++; @@ -797,10 +782,8 @@ void ForwardErrorCorrection::AttemptRecover( int ForwardErrorCorrection::NumCoveredPacketsMissing( const FecPacket* fec_packet) { int packets_missing = 0; - ProtectedPacketList::const_iterator it = - fec_packet->protected_pkt_list.begin(); - for (; it != fec_packet->protected_pkt_list.end(); ++it) { - if ((*it)->pkt == NULL) { + for (const auto* protected_packet : fec_packet->protected_pkt_list) { + if (protected_packet->pkt == nullptr) { ++packets_missing; if (packets_missing > 1) { break; // We can't recover more than one packet. @@ -810,12 +793,12 @@ int ForwardErrorCorrection::NumCoveredPacketsMissing( return packets_missing; } -void ForwardErrorCorrection::DiscardFECPacket(FecPacket* fec_packet) { +void ForwardErrorCorrection::DiscardFecPacket(FecPacket* fec_packet) { while (!fec_packet->protected_pkt_list.empty()) { delete fec_packet->protected_pkt_list.front(); fec_packet->protected_pkt_list.pop_front(); } - assert(fec_packet->protected_pkt_list.empty()); + RTC_DCHECK(fec_packet->protected_pkt_list.empty()); delete fec_packet; } @@ -827,14 +810,14 @@ void ForwardErrorCorrection::DiscardOldPackets( delete packet; recovered_packet_list->pop_front(); } - assert(recovered_packet_list->size() <= kMaxMediaPackets); + RTC_DCHECK(recovered_packet_list->size() <= kMaxMediaPackets); } uint16_t ForwardErrorCorrection::ParseSequenceNumber(uint8_t* packet) { return (packet[2] << 8) + packet[3]; } -int32_t ForwardErrorCorrection::DecodeFEC( +int ForwardErrorCorrection::DecodeFec( ReceivedPacketList* received_packet_list, RecoveredPacketList* recovered_packet_list) { // TODO(marpan/ajm): can we check for multiple ULP headers, and return an diff --git a/webrtc/modules/rtp_rtcp/source/forward_error_correction.h b/webrtc/modules/rtp_rtcp/source/forward_error_correction.h index cbeb97e7b1..fb35374ac6 100644 --- a/webrtc/modules/rtp_rtcp/source/forward_error_correction.h +++ b/webrtc/modules/rtp_rtcp/source/forward_error_correction.h @@ -11,12 +11,15 @@ #ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_FORWARD_ERROR_CORRECTION_H_ #define WEBRTC_MODULES_RTP_RTCP_SOURCE_FORWARD_ERROR_CORRECTION_H_ +#include + #include #include #include "webrtc/base/refcount.h" #include "webrtc/base/scoped_ref_ptr.h" #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" +#include "webrtc/modules/rtp_rtcp/source/forward_error_correction_internal.h" #include "webrtc/typedefs.h" namespace webrtc { @@ -31,7 +34,7 @@ class FecPacket; class ForwardErrorCorrection { public: // Maximum number of media packets we can protect - static const unsigned int kMaxMediaPackets = 48u; + static constexpr size_t kMaxMediaPackets = 48u; // TODO(holmer): As a next step all these struct-like packet classes should be // refactored into proper classes, and their members should be made private. @@ -49,7 +52,7 @@ class ForwardErrorCorrection { // reaches zero. virtual int32_t Release(); - size_t length; // Length of packet in bytes. + size_t length; // Length of packet in bytes. uint8_t data[IP_PACKET_SIZE]; // Packet data. private: @@ -66,17 +69,17 @@ class ForwardErrorCorrection { uint16_t seq_num; }; - // The received list parameter of #DecodeFEC() must reference structs of this + // The received list parameter of #DecodeFec() must reference structs of this // type. The last_media_pkt_in_frame is not required to be used for correct - // recovery, but will reduce delay by allowing #DecodeFEC() to pre-emptively + // recovery, but will reduce delay by allowing #DecodeFec() to pre-emptively // determine frame completion. If set, we assume a FEC stream, and the - // following assumptions must hold:\n + // following assumptions must hold: // // 1. The media packets in a frame have contiguous sequence numbers, i.e. the // frame's FEC packets have sequence numbers either lower than the first - // media packet or higher than the last media packet.\n + // media packet or higher than the last media packet. // 2. All FEC packets have a sequence number base equal to the first media - // packet in the corresponding frame.\n + // packet in the corresponding frame. // // The ssrc member is needed to ensure we can restore the SSRC field of // recovered packets. In most situations this could be retrieved from other @@ -95,7 +98,7 @@ class ForwardErrorCorrection { rtc::scoped_refptr pkt; // Pointer to the packet storage. }; - // The recovered list parameter of #DecodeFEC() will reference structs of + // The recovered list parameter of #DecodeFec() will reference structs of // this type. // TODO(holmer): Refactor into a proper class. class RecoveredPacket : public SortablePacket { @@ -118,7 +121,6 @@ class ForwardErrorCorrection { typedef std::list RecoveredPacketList; ForwardErrorCorrection(); - virtual ~ForwardErrorCorrection(); /** @@ -153,14 +155,14 @@ class ForwardErrorCorrection { * \param[out] fecPacketList List of FEC packets, of type #Packet. Must * be empty on entry. The memory available * through the list will be valid until the - * next call to GenerateFEC(). + * next call to GenerateFec(). * * \return 0 on success, -1 on failure. */ - int32_t GenerateFEC(const PacketList& media_packet_list, - uint8_t protection_factor, int num_important_packets, - bool use_unequal_protection, FecMaskType fec_mask_type, - PacketList* fec_packet_list); + int GenerateFec(const PacketList& media_packet_list, + uint8_t protection_factor, int num_important_packets, + bool use_unequal_protection, FecMaskType fec_mask_type, + PacketList* fec_packet_list); /** * Decodes a list of media and FEC packets. It will parse the input received @@ -169,13 +171,13 @@ class ForwardErrorCorrection { * ascending sequence number and have duplicates removed. The function * should be called as new packets arrive, with the recovered list being * progressively assembled with each call. The received packet list will be - * empty at output.\n + * empty at output. * * The user will allocate packets submitted through the received list. The * function will handle allocation of recovered packets and optionally * deleting of all packet memory. The user may delete the recovered list * packets, in which case they must remove deleted packets from the - * recovered list.\n + * recovered list. * * \param[in] receivedPacketList List of new received packets, of type * #ReceivedPacket, belonging to a single @@ -186,12 +188,12 @@ class ForwardErrorCorrection { * #RecoveredPacket, belonging to a single * frame. The memory available through the * list will be valid until the next call to - * DecodeFEC(). + * DecodeFec(). * * \return 0 on success, -1 on failure. */ - int32_t DecodeFEC(ReceivedPacketList* received_packet_list, - RecoveredPacketList* recovered_packet_list); + int DecodeFec(ReceivedPacketList* received_packet_list, + RecoveredPacketList* recovered_packet_list); // Get the number of FEC packets, given the number of media packets and the // protection factor. @@ -209,10 +211,6 @@ class ForwardErrorCorrection { private: typedef std::list FecPacketList; - void GenerateFecUlpHeaders(const PacketList& media_packet_list, - uint8_t* packet_mask, bool l_bit, - int num_fec_packets); - // Analyzes |media_packets| for holes in the sequence and inserts zero columns // into the |packet_mask| where those holes are found. Zero columns means that // those packets will have no protection. @@ -244,6 +242,10 @@ class ForwardErrorCorrection { int num_fec_packets, int new_bit_index, int old_bit_index); + void GenerateFecUlpHeaders(const PacketList& media_packet_list, + uint8_t* packet_mask, int num_fec_packets, + bool l_bit); + void GenerateFecBitStrings(const PacketList& media_packet_list, uint8_t* packet_mask, int num_fec_packets, bool l_bit); @@ -261,10 +263,10 @@ class ForwardErrorCorrection { // Note: This reduces the complexity when we want to try to recover a packet // since we don't have to find the intersection between recovered packets and // packets covered by the FEC packet. - void UpdateCoveringFECPackets(RecoveredPacket* packet); + void UpdateCoveringFecPackets(RecoveredPacket* packet); // Insert packet into FEC list. We delete duplicates. - void InsertFECPacket(ReceivedPacket* rx_packet, + void InsertFecPacket(ReceivedPacket* rx_packet, const RecoveredPacketList* recovered_packet_list); // Assigns pointers to already recovered packets covered by this FEC packet. @@ -279,15 +281,15 @@ class ForwardErrorCorrection { void AttemptRecover(RecoveredPacketList* recovered_packet_list); // Initializes the packet recovery using the FEC packet. - static bool InitRecovery(const FecPacket* fec_packet, - RecoveredPacket* recovered); + static bool StartPacketRecovery(const FecPacket* fec_packet, + RecoveredPacket* recovered); // Performs XOR between |src_packet| and |dst_packet| and stores the result // in |dst_packet|. static void XorPackets(const Packet* src_packet, RecoveredPacket* dst_packet); // Finish up the recovery of a packet. - static bool FinishRecovery(RecoveredPacket* recovered); + static bool FinishPacketRecovery(RecoveredPacket* recovered); // Recover a missing packet. bool RecoverPacket(const FecPacket* fec_packet, @@ -299,13 +301,18 @@ class ForwardErrorCorrection { // This function returns 2 when two or more packets are missing. static int NumCoveredPacketsMissing(const FecPacket* fec_packet); - static void DiscardFECPacket(FecPacket* fec_packet); + static void DiscardFecPacket(FecPacket* fec_packet); static void DiscardOldPackets(RecoveredPacketList* recovered_packet_list); static uint16_t ParseSequenceNumber(uint8_t* packet); std::vector generated_fec_packets_; FecPacketList fec_packet_list_; - bool fec_packet_received_; + + // Arrays used to avoid dynamically allocating memory when generating + // the packet masks in the ULPFEC headers. + // (There are never more than |kMaxMediaPackets| FEC packets generated.) + uint8_t packet_mask_[kMaxMediaPackets * kMaskSizeLBitSet]; + uint8_t tmp_packet_mask_[kMaxMediaPackets * kMaskSizeLBitSet]; }; } // namespace webrtc #endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_FORWARD_ERROR_CORRECTION_H_ diff --git a/webrtc/modules/rtp_rtcp/source/forward_error_correction_internal.h b/webrtc/modules/rtp_rtcp/source/forward_error_correction_internal.h index f82e46d572..48117514ec 100644 --- a/webrtc/modules/rtp_rtcp/source/forward_error_correction_internal.h +++ b/webrtc/modules/rtp_rtcp/source/forward_error_correction_internal.h @@ -11,15 +11,15 @@ #ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_FORWARD_ERROR_CORRECTION_INTERNAL_H_ #define WEBRTC_MODULES_RTP_RTCP_SOURCE_FORWARD_ERROR_CORRECTION_INTERNAL_H_ -#include "webrtc/modules/rtp_rtcp/source/forward_error_correction.h" +#include "webrtc/modules/include/module_common_types.h" #include "webrtc/typedefs.h" namespace webrtc { // Packet mask size in bytes (L bit is set). -static const int kMaskSizeLBitSet = 6; +constexpr size_t kMaskSizeLBitSet = 6; // Packet mask size in bytes (L bit is cleared). -static const int kMaskSizeLBitClear = 2; +constexpr size_t kMaskSizeLBitClear = 2; namespace internal { diff --git a/webrtc/modules/rtp_rtcp/source/producer_fec.cc b/webrtc/modules/rtp_rtcp/source/producer_fec.cc index c7ea19db58..6fe285fed9 100644 --- a/webrtc/modules/rtp_rtcp/source/producer_fec.cc +++ b/webrtc/modules/rtp_rtcp/source/producer_fec.cc @@ -18,11 +18,11 @@ namespace webrtc { enum { kREDForFECHeaderLength = 1 }; // This controls the maximum amount of excess overhead (actual - target) -// allowed in order to trigger GenerateFEC(), before |params_.max_fec_frames| +// allowed in order to trigger GenerateFec(), before |params_.max_fec_frames| // is reached. Overhead here is defined as relative to number of media packets. enum { kMaxExcessOverhead = 50 }; // Q8. // This is the minimum number of media packets required (above some protection -// level) in order to trigger GenerateFEC(), before |params_.max_fec_frames| is +// level) in order to trigger GenerateFec(), before |params_.max_fec_frames| is // reached. enum { kMinimumMediaPackets = 4 }; // Threshold on the received FEC protection level, above which we enforce at @@ -139,7 +139,8 @@ int ProducerFec::AddRtpPacketAndGenerateFec(const uint8_t* data_buffer, const bool marker_bit = (data_buffer[1] & kRtpMarkerBitMask) ? true : false; if (media_packets_fec_.size() < ForwardErrorCorrection::kMaxMediaPackets) { // Generic FEC can only protect up to kMaxMediaPackets packets. - ForwardErrorCorrection::Packet* packet = new ForwardErrorCorrection::Packet; + ForwardErrorCorrection::Packet* packet = + new ForwardErrorCorrection::Packet(); packet->length = payload_length + rtp_header_length; memcpy(packet->data, data_buffer, packet->length); media_packets_fec_.push_back(packet); @@ -159,7 +160,7 @@ int ProducerFec::AddRtpPacketAndGenerateFec(const uint8_t* data_buffer, static_cast(ForwardErrorCorrection::kMaxMediaPackets)); // TODO(pbos): Consider whether unequal protection should be enabled or not, // it is currently always disabled. - int ret = fec_->GenerateFEC(media_packets_fec_, params_.fec_rate, + int ret = fec_->GenerateFec(media_packets_fec_, params_.fec_rate, num_first_partition_, false, params_.fec_mask_type, &fec_packets_); if (fec_packets_.empty()) { diff --git a/webrtc/modules/rtp_rtcp/source/producer_fec.h b/webrtc/modules/rtp_rtcp/source/producer_fec.h index dcd71c8339..063a45fa95 100644 --- a/webrtc/modules/rtp_rtcp/source/producer_fec.h +++ b/webrtc/modules/rtp_rtcp/source/producer_fec.h @@ -11,7 +11,6 @@ #ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_PRODUCER_FEC_H_ #define WEBRTC_MODULES_RTP_RTCP_SOURCE_PRODUCER_FEC_H_ -#include #include #include "webrtc/modules/rtp_rtcp/source/forward_error_correction.h" @@ -72,8 +71,8 @@ class ProducerFec { void DeletePackets(); int Overhead() const; ForwardErrorCorrection* fec_; - std::list media_packets_fec_; - std::list fec_packets_; + ForwardErrorCorrection::PacketList media_packets_fec_; + ForwardErrorCorrection::PacketList fec_packets_; int num_frames_; int num_first_partition_; int minimum_media_packets_fec_; diff --git a/webrtc/modules/rtp_rtcp/source/producer_fec_unittest.cc b/webrtc/modules/rtp_rtcp/source/producer_fec_unittest.cc index ec5228afd5..ea59dc1b4d 100644 --- a/webrtc/modules/rtp_rtcp/source/producer_fec_unittest.cc +++ b/webrtc/modules/rtp_rtcp/source/producer_fec_unittest.cc @@ -44,7 +44,7 @@ class ProducerFecTest : public ::testing::Test { virtual void SetUp() { fec_ = new ForwardErrorCorrection(); producer_ = new ProducerFec(fec_); - generator_ = new FrameGenerator; + generator_ = new FrameGenerator(); } virtual void TearDown() { diff --git a/webrtc/modules/rtp_rtcp/source/rtp_fec_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtp_fec_unittest.cc index 228c19fe4c..198877df26 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_fec_unittest.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_fec_unittest.cc @@ -8,6 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ +#include #include #include "testing/gtest/include/gtest/gtest.h" @@ -99,7 +100,7 @@ TEST_F(RtpFecTest, FecRecoveryNoLoss) { fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); - EXPECT_EQ(0, fec_->GenerateFEC(media_packet_list_, kProtectionFactor, + EXPECT_EQ(0, fec_->GenerateFec(media_packet_list_, kProtectionFactor, kNumImportantPackets, kUseUnequalProtection, webrtc::kFecMaskBursty, &fec_packet_list_)); @@ -111,7 +112,7 @@ TEST_F(RtpFecTest, FecRecoveryNoLoss) { memset(fec_loss_mask_, 0, sizeof(fec_loss_mask_)); NetworkReceivedPackets(); - EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, + EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); // No packets lost, expect complete recovery. @@ -126,7 +127,7 @@ TEST_F(RtpFecTest, FecRecoveryWithLoss) { fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); - EXPECT_EQ(0, fec_->GenerateFEC(media_packet_list_, kProtectionFactor, + EXPECT_EQ(0, fec_->GenerateFec(media_packet_list_, kProtectionFactor, kNumImportantPackets, kUseUnequalProtection, webrtc::kFecMaskBursty, &fec_packet_list_)); @@ -140,7 +141,7 @@ TEST_F(RtpFecTest, FecRecoveryWithLoss) { NetworkReceivedPackets(); EXPECT_EQ(0, - fec_->DecodeFEC(&received_packet_list_, &recovered_packet_list_)); + fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); // One packet lost, one FEC packet, expect complete recovery. EXPECT_TRUE(IsRecoveryComplete()); @@ -153,7 +154,7 @@ TEST_F(RtpFecTest, FecRecoveryWithLoss) { media_loss_mask_[3] = 1; NetworkReceivedPackets(); - EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, + EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); // 2 packets lost, one FEC packet, cannot get complete recovery. @@ -176,7 +177,7 @@ TEST_F(RtpFecTest, FecRecoveryWithSeqNumGapTwoFrames) { // Construct media packets for first frame, starting at sequence number 0. fec_seq_num_ = ConstructMediaPacketsSeqNum(2, 0); - EXPECT_EQ(0, fec_->GenerateFEC(media_packet_list_, kProtectionFactor, + EXPECT_EQ(0, fec_->GenerateFec(media_packet_list_, kProtectionFactor, kNumImportantPackets, kUseUnequalProtection, webrtc::kFecMaskBursty, &fec_packet_list_)); // Expect 1 FEC packet. @@ -200,7 +201,7 @@ TEST_F(RtpFecTest, FecRecoveryWithSeqNumGapTwoFrames) { ReceivedPackets(media_packet_list_, media_loss_mask_, false); EXPECT_EQ(0, - fec_->DecodeFEC(&received_packet_list_, &recovered_packet_list_)); + fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); // Expect that no decoding is done to get missing packet (seq#0) of second // frame, using old FEC packet (seq#2) from first (old) frame. So number of @@ -222,7 +223,7 @@ TEST_F(RtpFecTest, FecRecoveryWithSeqNumGapOneFrameRecovery) { // #65534(media) #65535(media) #0(media) #1(FEC). fec_seq_num_ = ConstructMediaPacketsSeqNum(3, 65534); - EXPECT_EQ(0, fec_->GenerateFEC(media_packet_list_, kProtectionFactor, + EXPECT_EQ(0, fec_->GenerateFec(media_packet_list_, kProtectionFactor, kNumImportantPackets, kUseUnequalProtection, webrtc::kFecMaskBursty, &fec_packet_list_)); @@ -238,7 +239,7 @@ TEST_F(RtpFecTest, FecRecoveryWithSeqNumGapOneFrameRecovery) { ReceivedPackets(fec_packet_list_, fec_loss_mask_, true); EXPECT_EQ(0, - fec_->DecodeFEC(&received_packet_list_, &recovered_packet_list_)); + fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); // Expect 3 media packets in recovered list, and complete recovery. // Wrap-around won't remove FEC packet, as it follows the wrap. @@ -264,7 +265,7 @@ TEST_F(RtpFecTest, FecRecoveryWithSeqNumGapOneFrameNoRecovery) { // #65532(media) #65533(media) #65534(media) #65535(FEC) #0(FEC). fec_seq_num_ = ConstructMediaPacketsSeqNum(3, 65532); - EXPECT_EQ(0, fec_->GenerateFEC(media_packet_list_, kProtectionFactor, + EXPECT_EQ(0, fec_->GenerateFec(media_packet_list_, kProtectionFactor, kNumImportantPackets, kUseUnequalProtection, webrtc::kFecMaskBursty, &fec_packet_list_)); @@ -280,7 +281,7 @@ TEST_F(RtpFecTest, FecRecoveryWithSeqNumGapOneFrameNoRecovery) { ReceivedPackets(fec_packet_list_, fec_loss_mask_, true); EXPECT_EQ(0, - fec_->DecodeFEC(&received_packet_list_, &recovered_packet_list_)); + fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); // The two FEC packets are received and should allow for complete recovery, // but because of the wrap the second FEC packet will be discarded, and only @@ -303,7 +304,7 @@ TEST_F(RtpFecTest, FecRecoveryWithFecOutOfOrder) { // #0(media) #1(media) #2(media) #3(FEC). fec_seq_num_ = ConstructMediaPacketsSeqNum(3, 0); - EXPECT_EQ(0, fec_->GenerateFEC(media_packet_list_, kProtectionFactor, + EXPECT_EQ(0, fec_->GenerateFec(media_packet_list_, kProtectionFactor, kNumImportantPackets, kUseUnequalProtection, webrtc::kFecMaskBursty, &fec_packet_list_)); @@ -320,7 +321,7 @@ TEST_F(RtpFecTest, FecRecoveryWithFecOutOfOrder) { ReceivedPackets(media_packet_list_, media_loss_mask_, false); EXPECT_EQ(0, - fec_->DecodeFEC(&received_packet_list_, &recovered_packet_list_)); + fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); // Expect 3 media packets in recovered list, and complete recovery. EXPECT_EQ(3, static_cast(recovered_packet_list_.size())); @@ -349,7 +350,7 @@ TEST_F(RtpFecTest, FecRecoveryWithLoss50percRandomMask) { fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); - EXPECT_EQ(0, fec_->GenerateFEC(media_packet_list_, kProtectionFactor, + EXPECT_EQ(0, fec_->GenerateFec(media_packet_list_, kProtectionFactor, kNumImportantPackets, kUseUnequalProtection, webrtc::kFecMaskRandom, &fec_packet_list_)); @@ -366,7 +367,7 @@ TEST_F(RtpFecTest, FecRecoveryWithLoss50percRandomMask) { NetworkReceivedPackets(); EXPECT_EQ(0, - fec_->DecodeFEC(&received_packet_list_, &recovered_packet_list_)); + fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); // With media packet#1 and FEC packets #1, #2, #3, expect complete recovery. EXPECT_TRUE(IsRecoveryComplete()); @@ -381,7 +382,7 @@ TEST_F(RtpFecTest, FecRecoveryWithLoss50percRandomMask) { media_loss_mask_[3] = 1; NetworkReceivedPackets(); - EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, + EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); // Cannot get complete recovery for this loss configuration with random mask. @@ -409,7 +410,7 @@ TEST_F(RtpFecTest, FecRecoveryWithLoss50percBurstyMask) { fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); - EXPECT_EQ(0, fec_->GenerateFEC(media_packet_list_, kProtectionFactor, + EXPECT_EQ(0, fec_->GenerateFec(media_packet_list_, kProtectionFactor, kNumImportantPackets, kUseUnequalProtection, webrtc::kFecMaskBursty, &fec_packet_list_)); @@ -425,7 +426,7 @@ TEST_F(RtpFecTest, FecRecoveryWithLoss50percBurstyMask) { media_loss_mask_[3] = 1; NetworkReceivedPackets(); - EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, + EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); // Expect complete recovery for consecutive packet loss <= 50%. @@ -441,7 +442,7 @@ TEST_F(RtpFecTest, FecRecoveryWithLoss50percBurstyMask) { media_loss_mask_[3] = 1; NetworkReceivedPackets(); - EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, + EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); // Expect complete recovery for consecutive packet loss <= 50%. @@ -457,7 +458,7 @@ TEST_F(RtpFecTest, FecRecoveryWithLoss50percBurstyMask) { media_loss_mask_[3] = 1; NetworkReceivedPackets(); - EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, + EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); // Cannot get complete recovery for this loss configuration. @@ -472,7 +473,7 @@ TEST_F(RtpFecTest, FecRecoveryNoLossUep) { fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); - EXPECT_EQ(0, fec_->GenerateFEC(media_packet_list_, kProtectionFactor, + EXPECT_EQ(0, fec_->GenerateFec(media_packet_list_, kProtectionFactor, kNumImportantPackets, kUseUnequalProtection, webrtc::kFecMaskBursty, &fec_packet_list_)); @@ -485,7 +486,7 @@ TEST_F(RtpFecTest, FecRecoveryNoLossUep) { NetworkReceivedPackets(); EXPECT_EQ(0, - fec_->DecodeFEC(&received_packet_list_, &recovered_packet_list_)); + fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); // No packets lost, expect complete recovery. EXPECT_TRUE(IsRecoveryComplete()); @@ -499,7 +500,7 @@ TEST_F(RtpFecTest, FecRecoveryWithLossUep) { fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); - EXPECT_EQ(0, fec_->GenerateFEC(media_packet_list_, kProtectionFactor, + EXPECT_EQ(0, fec_->GenerateFec(media_packet_list_, kProtectionFactor, kNumImportantPackets, kUseUnequalProtection, webrtc::kFecMaskBursty, &fec_packet_list_)); @@ -512,7 +513,7 @@ TEST_F(RtpFecTest, FecRecoveryWithLossUep) { media_loss_mask_[3] = 1; NetworkReceivedPackets(); - EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, + EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); // One packet lost, one FEC packet, expect complete recovery. @@ -526,7 +527,7 @@ TEST_F(RtpFecTest, FecRecoveryWithLossUep) { media_loss_mask_[3] = 1; NetworkReceivedPackets(); - EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, + EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); // 2 packets lost, one FEC packet, cannot get complete recovery. @@ -552,7 +553,7 @@ TEST_F(RtpFecTest, FecRecoveryWithLoss50percUepRandomMask) { fec_seq_num_ = ConstructMediaPackets(kNumMediaPackets); - EXPECT_EQ(0, fec_->GenerateFEC(media_packet_list_, kProtectionFactor, + EXPECT_EQ(0, fec_->GenerateFec(media_packet_list_, kProtectionFactor, kNumImportantPackets, kUseUnequalProtection, webrtc::kFecMaskRandom, &fec_packet_list_)); @@ -568,7 +569,7 @@ TEST_F(RtpFecTest, FecRecoveryWithLoss50percUepRandomMask) { media_loss_mask_[3] = 1; NetworkReceivedPackets(); - EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, + EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); // With media packet#3 and FEC packets #0, #1, #3, expect complete recovery. @@ -585,7 +586,7 @@ TEST_F(RtpFecTest, FecRecoveryWithLoss50percUepRandomMask) { media_loss_mask_[3] = 1; NetworkReceivedPackets(); - EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, + EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); // Cannot get complete recovery for this loss configuration. @@ -604,12 +605,12 @@ TEST_F(RtpFecTest, FecRecoveryNonConsecutivePackets) { // This list should have every other packet removed. PacketList protected_media_packets; int i = 0; - for (PacketList::iterator it = media_packet_list_.begin(); - it != media_packet_list_.end(); ++it, ++i) { + for (auto it = media_packet_list_.begin(); it != media_packet_list_.end(); + ++it, ++i) { if (i % 2 == 0) protected_media_packets.push_back(*it); } - EXPECT_EQ(0, fec_->GenerateFEC(protected_media_packets, kProtectionFactor, + EXPECT_EQ(0, fec_->GenerateFec(protected_media_packets, kProtectionFactor, kNumImportantPackets, kUseUnequalProtection, webrtc::kFecMaskBursty, &fec_packet_list_)); @@ -622,7 +623,7 @@ TEST_F(RtpFecTest, FecRecoveryNonConsecutivePackets) { media_loss_mask_[2] = 1; NetworkReceivedPackets(); - EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, + EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); // One packet lost, one FEC packet, expect complete recovery. @@ -635,7 +636,7 @@ TEST_F(RtpFecTest, FecRecoveryNonConsecutivePackets) { media_loss_mask_[1] = 1; NetworkReceivedPackets(); - EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, + EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); // Unprotected packet lost. Recovery not possible. @@ -649,7 +650,7 @@ TEST_F(RtpFecTest, FecRecoveryNonConsecutivePackets) { media_loss_mask_[2] = 1; NetworkReceivedPackets(); - EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, + EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); // 2 protected packets lost, one FEC packet, cannot get complete recovery. @@ -668,15 +669,15 @@ TEST_F(RtpFecTest, FecRecoveryNonConsecutivePacketsExtension) { // This list should have every other packet removed. PacketList protected_media_packets; int i = 0; - for (PacketList::iterator it = media_packet_list_.begin(); - it != media_packet_list_.end(); ++it, ++i) { + for (auto it = media_packet_list_.begin(); it != media_packet_list_.end(); + ++it, ++i) { if (i % 2 == 0) protected_media_packets.push_back(*it); } // Zero column insertion will have to extend the size of the packet // mask since the number of actual packets are 21, while the number // of protected packets are 11. - EXPECT_EQ(0, fec_->GenerateFEC(protected_media_packets, kProtectionFactor, + EXPECT_EQ(0, fec_->GenerateFec(protected_media_packets, kProtectionFactor, kNumImportantPackets, kUseUnequalProtection, webrtc::kFecMaskBursty, &fec_packet_list_)); @@ -689,7 +690,7 @@ TEST_F(RtpFecTest, FecRecoveryNonConsecutivePacketsExtension) { media_loss_mask_[kNumMediaPackets - 1] = 1; NetworkReceivedPackets(); - EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, + EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); // One packet lost, one FEC packet, expect complete recovery. @@ -702,7 +703,7 @@ TEST_F(RtpFecTest, FecRecoveryNonConsecutivePacketsExtension) { media_loss_mask_[kNumMediaPackets - 2] = 1; NetworkReceivedPackets(); - EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, + EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); // Unprotected packet lost. Recovery not possible. @@ -720,7 +721,7 @@ TEST_F(RtpFecTest, FecRecoveryNonConsecutivePacketsExtension) { media_loss_mask_[kNumMediaPackets - 1] = 1; NetworkReceivedPackets(); - EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, + EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); // 5 protected packets lost, one FEC packet, cannot get complete recovery. @@ -739,15 +740,15 @@ TEST_F(RtpFecTest, FecRecoveryNonConsecutivePacketsWrap) { // This list should have every other packet removed. PacketList protected_media_packets; int i = 0; - for (PacketList::iterator it = media_packet_list_.begin(); - it != media_packet_list_.end(); ++it, ++i) { + for (auto it = media_packet_list_.begin(); it != media_packet_list_.end(); + ++it, ++i) { if (i % 2 == 0) protected_media_packets.push_back(*it); } // Zero column insertion will have to extend the size of the packet // mask since the number of actual packets are 21, while the number // of protected packets are 11. - EXPECT_EQ(0, fec_->GenerateFEC(protected_media_packets, kProtectionFactor, + EXPECT_EQ(0, fec_->GenerateFec(protected_media_packets, kProtectionFactor, kNumImportantPackets, kUseUnequalProtection, webrtc::kFecMaskBursty, &fec_packet_list_)); @@ -760,7 +761,7 @@ TEST_F(RtpFecTest, FecRecoveryNonConsecutivePacketsWrap) { media_loss_mask_[kNumMediaPackets - 1] = 1; NetworkReceivedPackets(); - EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, + EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); // One packet lost, one FEC packet, expect complete recovery. @@ -773,7 +774,7 @@ TEST_F(RtpFecTest, FecRecoveryNonConsecutivePacketsWrap) { media_loss_mask_[kNumMediaPackets - 2] = 1; NetworkReceivedPackets(); - EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, + EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); // Unprotected packet lost. Recovery not possible. @@ -791,7 +792,7 @@ TEST_F(RtpFecTest, FecRecoveryNonConsecutivePacketsWrap) { media_loss_mask_[kNumMediaPackets - 1] = 1; NetworkReceivedPackets(); - EXPECT_EQ(0, fec_->DecodeFEC(&received_packet_list_, + EXPECT_EQ(0, fec_->DecodeFec(&received_packet_list_, &recovered_packet_list_)); // 5 protected packets lost, one FEC packet, cannot get complete recovery. @@ -811,36 +812,27 @@ void RtpFecTest::FreeRecoveredPacketList() { } bool RtpFecTest::IsRecoveryComplete() { - // Check that the number of media and recovered packets are equal. - if (media_packet_list_.size() != recovered_packet_list_.size()) { + // We must have equally many recovered packets as original packets. + if (recovered_packet_list_.size() != media_packet_list_.size()) { return false; } - ForwardErrorCorrection::Packet* media_packet; - ForwardErrorCorrection::RecoveredPacket* recovered_packet; - - bool recovery = true; - - PacketList::iterator media_packet_list_item = media_packet_list_.begin(); - RecoveredPacketList::iterator recovered_packet_list_item = - recovered_packet_list_.begin(); - while (media_packet_list_item != media_packet_list_.end()) { - if (recovered_packet_list_item == recovered_packet_list_.end()) { + // All recovered packets must be identical to the corresponding + // original packets. + auto cmp = [](ForwardErrorCorrection::Packet* media_packet, + ForwardErrorCorrection::RecoveredPacket* recovered_packet) { + if (media_packet->length != recovered_packet->pkt->length) { return false; } - media_packet = *media_packet_list_item; - recovered_packet = *recovered_packet_list_item; - if (recovered_packet->pkt->length != media_packet->length) { - return false; - } - if (memcmp(recovered_packet->pkt->data, media_packet->data, + if (memcmp(media_packet->data, + recovered_packet->pkt->data, media_packet->length) != 0) { return false; } - media_packet_list_item++; - recovered_packet_list_item++; - } - return recovery; + return true; + }; + return std::equal(media_packet_list_.cbegin(), media_packet_list_.cend(), + recovered_packet_list_.cbegin(), cmp); } void RtpFecTest::NetworkReceivedPackets() { @@ -851,18 +843,13 @@ void RtpFecTest::NetworkReceivedPackets() { void RtpFecTest::ReceivedPackets(const PacketList& packet_list, int* loss_mask, bool is_fec) { - ForwardErrorCorrection::Packet* packet; - ForwardErrorCorrection::ReceivedPacket* received_packet; int seq_num = fec_seq_num_; int packet_idx = 0; - PacketList::const_iterator packet_list_item = packet_list.begin(); - - while (packet_list_item != packet_list.end()) { - packet = *packet_list_item; + for (const auto* packet : packet_list) { if (loss_mask[packet_idx] == 0) { - received_packet = new ForwardErrorCorrection::ReceivedPacket; - received_packet->pkt = new ForwardErrorCorrection::Packet; + auto received_packet = new ForwardErrorCorrection::ReceivedPacket(); + received_packet->pkt = new ForwardErrorCorrection::Packet(); received_packet_list_.push_back(received_packet); received_packet->pkt->length = packet->length; memcpy(received_packet->pkt->data, packet->data, packet->length); @@ -884,7 +871,6 @@ void RtpFecTest::ReceivedPackets(const PacketList& packet_list, int* loss_mask, } } packet_idx++; - packet_list_item++; // Sequence number of FEC packets are defined as increment by 1 from // last media packet in frame. if (is_fec) seq_num++; @@ -893,13 +879,13 @@ void RtpFecTest::ReceivedPackets(const PacketList& packet_list, int* loss_mask, int RtpFecTest::ConstructMediaPacketsSeqNum(int num_media_packets, int start_seq_num) { - assert(num_media_packets > 0); + RTC_DCHECK_GT(num_media_packets, 0); ForwardErrorCorrection::Packet* media_packet = NULL; int sequence_number = start_seq_num; int time_stamp = random_.Rand(); for (int i = 0; i < num_media_packets; ++i) { - media_packet = new ForwardErrorCorrection::Packet; + media_packet = new ForwardErrorCorrection::Packet(); media_packet_list_.push_back(media_packet); const uint32_t kMinPacketSize = kRtpHeaderSize; const uint32_t kMaxPacketSize = IP_PACKET_SIZE - kRtpHeaderSize - @@ -937,7 +923,7 @@ int RtpFecTest::ConstructMediaPacketsSeqNum(int num_media_packets, sequence_number++; } // Last packet, set marker bit. - assert(media_packet != NULL); + RTC_DCHECK(media_packet); media_packet->data[1] |= 0x80; return sequence_number; } diff --git a/webrtc/modules/rtp_rtcp/test/testFec/test_fec.cc b/webrtc/modules/rtp_rtcp/test/testFec/test_fec.cc index 0a1ae6272e..3e9a5989d6 100644 --- a/webrtc/modules/rtp_rtcp/test/testFec/test_fec.cc +++ b/webrtc/modules/rtp_rtcp/test/testFec/test_fec.cc @@ -13,9 +13,6 @@ * functions in ForwardErrorCorrection directly. */ -#include -#include -#include #include #include @@ -38,46 +35,45 @@ namespace test { using fec_private_tables::kPacketMaskBurstyTbl; void ReceivePackets( - ForwardErrorCorrection::ReceivedPacketList* toDecodeList, - ForwardErrorCorrection::ReceivedPacketList* receivedPacketList, - size_t numPacketsToDecode, - float reorderRate, - float duplicateRate, + ForwardErrorCorrection::ReceivedPacketList* to_decode_list, + ForwardErrorCorrection::ReceivedPacketList* received_packet_list, + size_t num_packets_to_decode, + float reorder_rate, + float duplicate_rate, Random* random) { - assert(toDecodeList->empty()); - assert(numPacketsToDecode <= receivedPacketList->size()); + RTC_DCHECK(to_decode_list->empty()); + RTC_DCHECK_LE(num_packets_to_decode, received_packet_list->size()); - ForwardErrorCorrection::ReceivedPacketList::iterator it; - for (size_t i = 0; i < numPacketsToDecode; i++) { - it = receivedPacketList->begin(); + for (size_t i = 0; i < num_packets_to_decode; i++) { + auto it = received_packet_list->begin(); // Reorder packets. - float randomVariable = random->Rand(); - while (randomVariable < reorderRate) { + float random_variable = random->Rand(); + while (random_variable < reorder_rate) { ++it; - if (it == receivedPacketList->end()) { + if (it == received_packet_list->end()) { --it; break; } - randomVariable = random->Rand(); + random_variable = random->Rand(); } - ForwardErrorCorrection::ReceivedPacket* receivedPacket = *it; - toDecodeList->push_back(receivedPacket); + ForwardErrorCorrection::ReceivedPacket* received_packet = *it; + to_decode_list->push_back(received_packet); // Duplicate packets. - randomVariable = random->Rand(); - while (randomVariable < duplicateRate) { - ForwardErrorCorrection::ReceivedPacket* duplicatePacket = - new ForwardErrorCorrection::ReceivedPacket; - *duplicatePacket = *receivedPacket; - duplicatePacket->pkt = new ForwardErrorCorrection::Packet; - memcpy(duplicatePacket->pkt->data, receivedPacket->pkt->data, - receivedPacket->pkt->length); - duplicatePacket->pkt->length = receivedPacket->pkt->length; + random_variable = random->Rand(); + while (random_variable < duplicate_rate) { + ForwardErrorCorrection::ReceivedPacket* duplicate_packet = + new ForwardErrorCorrection::ReceivedPacket(); + *duplicate_packet = *received_packet; + duplicate_packet->pkt = new ForwardErrorCorrection::Packet(); + memcpy(duplicate_packet->pkt->data, received_packet->pkt->data, + received_packet->pkt->length); + duplicate_packet->pkt->length = received_packet->pkt->length; - toDecodeList->push_back(duplicatePacket); - randomVariable = random->Rand(); + to_decode_list->push_back(duplicate_packet); + random_variable = random->Rand(); } - receivedPacketList->erase(it); + received_packet_list->erase(it); } } @@ -111,94 +107,100 @@ TEST(FecTest, MAYBE_FecTest) { << "equal to 12."; ForwardErrorCorrection fec; - ForwardErrorCorrection::PacketList mediaPacketList; - ForwardErrorCorrection::PacketList fecPacketList; - ForwardErrorCorrection::ReceivedPacketList toDecodeList; - ForwardErrorCorrection::ReceivedPacketList receivedPacketList; - ForwardErrorCorrection::RecoveredPacketList recoveredPacketList; - std::list fecMaskList; + ForwardErrorCorrection::PacketList media_packet_list; + ForwardErrorCorrection::PacketList fec_packet_list; + ForwardErrorCorrection::ReceivedPacketList to_decode_list; + ForwardErrorCorrection::ReceivedPacketList received_packet_list; + ForwardErrorCorrection::RecoveredPacketList recovered_packet_list; + std::list fec_mask_list; - ForwardErrorCorrection::Packet* mediaPacket = NULL; + ForwardErrorCorrection::Packet* media_packet = nullptr; // Running over only one loss rate to limit execution time. - const float lossRate[] = {0.5f}; - const uint32_t lossRateSize = sizeof(lossRate) / sizeof(*lossRate); - const float reorderRate = 0.1f; - const float duplicateRate = 0.1f; + const float loss_rate[] = {0.5f}; + const uint32_t loss_rate_size = sizeof(loss_rate) / sizeof(*loss_rate); + const float reorder_rate = 0.1f; + const float duplicate_rate = 0.1f; - uint8_t mediaLossMask[kMaxNumberMediaPackets]; - uint8_t fecLossMask[kMaxNumberFecPackets]; - uint8_t fecPacketMasks[kMaxNumberFecPackets][kMaxNumberMediaPackets]; + uint8_t media_loss_mask[kMaxNumberMediaPackets]; + uint8_t fec_loss_mask[kMaxNumberFecPackets]; + uint8_t fec_packet_masks[kMaxNumberFecPackets][kMaxNumberMediaPackets]; // Seed the random number generator, storing the seed to file in order to // reproduce past results. - const unsigned int randomSeed = static_cast(time(NULL)); - Random random(randomSeed); + const unsigned int random_seed = static_cast(time(nullptr)); + Random random(random_seed); std::string filename = webrtc::test::OutputPath() + "randomSeedLog.txt"; - FILE* randomSeedFile = fopen(filename.c_str(), "a"); - fprintf(randomSeedFile, "%u\n", randomSeed); - fclose(randomSeedFile); - randomSeedFile = NULL; + FILE* random_seed_file = fopen(filename.c_str(), "a"); + fprintf(random_seed_file, "%u\n", random_seed); + fclose(random_seed_file); + random_seed_file = nullptr; - uint16_t seqNum = 0; - uint32_t timeStamp = random.Rand(); + uint16_t seq_num = 0; + uint32_t timestamp = random.Rand(); const uint32_t ssrc = random.Rand(1u, 0xfffffffe); // Loop over the mask types: random and bursty. for (int mask_type_idx = 0; mask_type_idx < kNumFecMaskTypes; ++mask_type_idx) { - for (uint32_t lossRateIdx = 0; lossRateIdx < lossRateSize; ++lossRateIdx) { - printf("Loss rate: %.2f, Mask type %d \n", lossRate[lossRateIdx], + for (uint32_t loss_rate_idx = 0; loss_rate_idx < loss_rate_size; + ++loss_rate_idx) { + printf("Loss rate: %.2f, Mask type %d \n", loss_rate[loss_rate_idx], mask_type_idx); - const uint32_t packetMaskMax = kMaxMediaPackets[mask_type_idx]; - uint8_t* packetMask = new uint8_t[packetMaskMax * kNumMaskBytesL1]; + const uint32_t packet_mask_max = kMaxMediaPackets[mask_type_idx]; + std::unique_ptr packet_mask( + new uint8_t[packet_mask_max * kNumMaskBytesL1]); FecMaskType fec_mask_type = kMaskTypes[mask_type_idx]; - for (uint32_t numMediaPackets = 1; numMediaPackets <= packetMaskMax; - numMediaPackets++) { - internal::PacketMaskTable mask_table(fec_mask_type, numMediaPackets); + for (uint32_t num_media_packets = 1; num_media_packets <= packet_mask_max; + num_media_packets++) { + internal::PacketMaskTable mask_table(fec_mask_type, num_media_packets); - for (uint32_t numFecPackets = 1; - numFecPackets <= numMediaPackets && numFecPackets <= packetMaskMax; - numFecPackets++) { - // Loop over numImpPackets: usually <= (0.3*numMediaPackets). - // For this test we check up to ~ (numMediaPackets / 4). - uint32_t maxNumImpPackets = numMediaPackets / 4 + 1; - for (uint32_t numImpPackets = 0; numImpPackets <= maxNumImpPackets && - numImpPackets <= packetMaskMax; - numImpPackets++) { - uint8_t protectionFactor = - static_cast(numFecPackets * 255 / numMediaPackets); + for (uint32_t num_fec_packets = 1; + num_fec_packets <= num_media_packets && + num_fec_packets <= packet_mask_max; + num_fec_packets++) { + // Loop over num_imp_packets: usually <= (0.3*num_media_packets). + // For this test we check up to ~ (num_media_packets / 4). + uint32_t max_num_imp_packets = num_media_packets / 4 + 1; + for (uint32_t num_imp_packets = 0; + num_imp_packets <= max_num_imp_packets && + num_imp_packets <= packet_mask_max; + num_imp_packets++) { + uint8_t protection_factor = + static_cast(num_fec_packets * 255 / num_media_packets); - const uint32_t maskBytesPerFecPacket = - (numMediaPackets > 16) ? kNumMaskBytesL1 : kNumMaskBytesL0; + const uint32_t mask_bytes_per_fec_packet = + (num_media_packets > 16) ? kNumMaskBytesL1 : kNumMaskBytesL0; - memset(packetMask, 0, numMediaPackets * maskBytesPerFecPacket); + memset(packet_mask.get(), 0, + num_media_packets * mask_bytes_per_fec_packet); // Transfer packet masks from bit-mask to byte-mask. - internal::GeneratePacketMasks(numMediaPackets, numFecPackets, - numImpPackets, kUseUnequalProtection, - mask_table, packetMask); + internal::GeneratePacketMasks(num_media_packets, num_fec_packets, + num_imp_packets, + kUseUnequalProtection, + mask_table, packet_mask.get()); #ifdef VERBOSE_OUTPUT printf( - "%u media packets, %u FEC packets, %u numImpPackets, " + "%u media packets, %u FEC packets, %u num_imp_packets, " "loss rate = %.2f \n", - numMediaPackets, numFecPackets, numImpPackets, - lossRate[lossRateIdx]); + num_media_packets, num_fec_packets, num_imp_packets, + loss_rate[loss_rate_idx]); printf("Packet mask matrix \n"); #endif - for (uint32_t i = 0; i < numFecPackets; i++) { - for (uint32_t j = 0; j < numMediaPackets; j++) { - const uint8_t byteMask = - packetMask[i * maskBytesPerFecPacket + j / 8]; - const uint32_t bitPosition = (7 - j % 8); - fecPacketMasks[i][j] = - (byteMask & (1 << bitPosition)) >> bitPosition; + for (uint32_t i = 0; i < num_fec_packets; i++) { + for (uint32_t j = 0; j < num_media_packets; j++) { + const uint8_t byte_mask = + packet_mask[i * mask_bytes_per_fec_packet + j / 8]; + const uint32_t bit_position = (7 - j % 8); + fec_packet_masks[i][j] = + (byte_mask & (1 << bit_position)) >> bit_position; #ifdef VERBOSE_OUTPUT - printf("%u ", fecPacketMasks[i][j]); + printf("%u ", fec_packet_masks[i][j]); #endif } #ifdef VERBOSE_OUTPUT @@ -209,20 +211,20 @@ TEST(FecTest, MAYBE_FecTest) { printf("\n"); #endif // Check for all zero rows or columns: indicates incorrect mask. - uint32_t rowLimit = numMediaPackets; - for (uint32_t i = 0; i < numFecPackets; ++i) { - uint32_t rowSum = 0; - for (uint32_t j = 0; j < rowLimit; ++j) { - rowSum += fecPacketMasks[i][j]; + uint32_t row_limit = num_media_packets; + for (uint32_t i = 0; i < num_fec_packets; ++i) { + uint32_t row_sum = 0; + for (uint32_t j = 0; j < row_limit; ++j) { + row_sum += fec_packet_masks[i][j]; } - ASSERT_NE(0u, rowSum) << "Row is all zero " << i; + ASSERT_NE(0u, row_sum) << "Row is all zero " << i; } - for (uint32_t j = 0; j < rowLimit; ++j) { - uint32_t columnSum = 0; - for (uint32_t i = 0; i < numFecPackets; ++i) { - columnSum += fecPacketMasks[i][j]; + for (uint32_t j = 0; j < row_limit; ++j) { + uint32_t column_sum = 0; + for (uint32_t i = 0; i < num_fec_packets; ++i) { + column_sum += fec_packet_masks[i][j]; } - ASSERT_NE(0u, columnSum) << "Column is all zero " << j; + ASSERT_NE(0u, column_sum) << "Column is all zero " << j; } // Construct media packets. @@ -230,19 +232,20 @@ TEST(FecTest, MAYBE_FecTest) { // below, to avoid sequence number wrap-around. In actual decoding, // old FEC packets in list are dropped if sequence number wrap // around is detected. This case is currently not handled below. - seqNum = 0; - for (uint32_t i = 0; i < numMediaPackets; ++i) { - mediaPacket = new ForwardErrorCorrection::Packet; - mediaPacketList.push_back(mediaPacket); + seq_num = 0; + for (uint32_t i = 0; i < num_media_packets; ++i) { + media_packet = new ForwardErrorCorrection::Packet(); + media_packet_list.push_back(media_packet); const uint32_t kMinPacketSize = 12; const uint32_t kMaxPacketSize = static_cast( IP_PACKET_SIZE - 12 - 28 - ForwardErrorCorrection::PacketOverhead()); - mediaPacket->length = random.Rand(kMinPacketSize, kMaxPacketSize); + media_packet->length = random.Rand(kMinPacketSize, + kMaxPacketSize); // Generate random values for the first 2 bytes. - mediaPacket->data[0] = random.Rand(); - mediaPacket->data[1] = random.Rand(); + media_packet->data[0] = random.Rand(); + media_packet->data[1] = random.Rand(); // The first two bits are assumed to be 10 by the // FEC encoder. In fact the FEC decoder will set the @@ -250,237 +253,217 @@ TEST(FecTest, MAYBE_FecTest) { // actually were. Set the first two bits to 10 // so that a memcmp can be performed for the // whole restored packet. - mediaPacket->data[0] |= 0x80; - mediaPacket->data[0] &= 0xbf; + media_packet->data[0] |= 0x80; + media_packet->data[0] &= 0xbf; // FEC is applied to a whole frame. // A frame is signaled by multiple packets without // the marker bit set followed by the last packet of // the frame for which the marker bit is set. // Only push one (fake) frame to the FEC. - mediaPacket->data[1] &= 0x7f; + media_packet->data[1] &= 0x7f; - ByteWriter::WriteBigEndian(&mediaPacket->data[2], - seqNum); - ByteWriter::WriteBigEndian(&mediaPacket->data[4], - timeStamp); - ByteWriter::WriteBigEndian(&mediaPacket->data[8], ssrc); + ByteWriter::WriteBigEndian(&media_packet->data[2], + seq_num); + ByteWriter::WriteBigEndian(&media_packet->data[4], + timestamp); + ByteWriter::WriteBigEndian(&media_packet->data[8], + ssrc); // Generate random values for payload - for (size_t j = 12; j < mediaPacket->length; ++j) { - mediaPacket->data[j] = random.Rand(); + for (size_t j = 12; j < media_packet->length; ++j) { + media_packet->data[j] = random.Rand(); } - seqNum++; + seq_num++; } - mediaPacket->data[1] |= 0x80; + media_packet->data[1] |= 0x80; - ASSERT_EQ(0, fec.GenerateFEC(mediaPacketList, protectionFactor, - numImpPackets, kUseUnequalProtection, - fec_mask_type, &fecPacketList)) - << "GenerateFEC() failed"; + ASSERT_EQ(0, fec.GenerateFec(media_packet_list, protection_factor, + num_imp_packets, kUseUnequalProtection, + fec_mask_type, &fec_packet_list)) + << "GenerateFec() failed"; - ASSERT_EQ(numFecPackets, fecPacketList.size()) - << "We requested " << numFecPackets << " FEC packets, but " - << "GenerateFEC() produced " << fecPacketList.size(); - memset(mediaLossMask, 0, sizeof(mediaLossMask)); - ForwardErrorCorrection::PacketList::iterator mediaPacketListItem = - mediaPacketList.begin(); - ForwardErrorCorrection::ReceivedPacket* receivedPacket; - uint32_t mediaPacketIdx = 0; + ASSERT_EQ(num_fec_packets, fec_packet_list.size()) + << "We requested " << num_fec_packets << " FEC packets, but " + << "GenerateFec() produced " << fec_packet_list.size(); - while (mediaPacketListItem != mediaPacketList.end()) { - mediaPacket = *mediaPacketListItem; + memset(media_loss_mask, 0, sizeof(media_loss_mask)); + uint32_t media_packet_idx = 0; + for (auto* media_packet : media_packet_list) { // We want a value between 0 and 1. - const float lossRandomVariable = random.Rand(); + const float loss_random_variable = random.Rand(); - if (lossRandomVariable >= lossRate[lossRateIdx]) { - mediaLossMask[mediaPacketIdx] = 1; - receivedPacket = new ForwardErrorCorrection::ReceivedPacket; - receivedPacket->pkt = new ForwardErrorCorrection::Packet; - receivedPacketList.push_back(receivedPacket); + if (loss_random_variable >= loss_rate[loss_rate_idx]) { + media_loss_mask[media_packet_idx] = 1; + auto received_packet = + new ForwardErrorCorrection::ReceivedPacket(); + received_packet->pkt = new ForwardErrorCorrection::Packet(); + received_packet_list.push_back(received_packet); - receivedPacket->pkt->length = mediaPacket->length; - memcpy(receivedPacket->pkt->data, mediaPacket->data, - mediaPacket->length); - receivedPacket->seq_num = - ByteReader::ReadBigEndian(&mediaPacket->data[2]); - receivedPacket->is_fec = false; + received_packet->pkt->length = media_packet->length; + memcpy(received_packet->pkt->data, media_packet->data, + media_packet->length); + received_packet->seq_num = + ByteReader::ReadBigEndian(&media_packet->data[2]); + received_packet->is_fec = false; } - mediaPacketIdx++; - ++mediaPacketListItem; + media_packet_idx++; } - memset(fecLossMask, 0, sizeof(fecLossMask)); - ForwardErrorCorrection::PacketList::iterator fecPacketListItem = - fecPacketList.begin(); - ForwardErrorCorrection::Packet* fecPacket; - uint32_t fecPacketIdx = 0; - while (fecPacketListItem != fecPacketList.end()) { - fecPacket = *fecPacketListItem; - const float lossRandomVariable = random.Rand(); - if (lossRandomVariable >= lossRate[lossRateIdx]) { - fecLossMask[fecPacketIdx] = 1; - receivedPacket = new ForwardErrorCorrection::ReceivedPacket; - receivedPacket->pkt = new ForwardErrorCorrection::Packet; - receivedPacketList.push_back(receivedPacket); + memset(fec_loss_mask, 0, sizeof(fec_loss_mask)); + uint32_t fec_packet_idx = 0; + for (auto* fec_packet : fec_packet_list) { + const float loss_random_variable = random.Rand(); + if (loss_random_variable >= loss_rate[loss_rate_idx]) { + fec_loss_mask[fec_packet_idx] = 1; + auto received_packet = + new ForwardErrorCorrection::ReceivedPacket(); + received_packet->pkt = new ForwardErrorCorrection::Packet(); - receivedPacket->pkt->length = fecPacket->length; - memcpy(receivedPacket->pkt->data, fecPacket->data, - fecPacket->length); + received_packet_list.push_back(received_packet); - receivedPacket->seq_num = seqNum; - receivedPacket->is_fec = true; - receivedPacket->ssrc = ssrc; + received_packet->pkt->length = fec_packet->length; + memcpy(received_packet->pkt->data, fec_packet->data, + fec_packet->length); - fecMaskList.push_back(fecPacketMasks[fecPacketIdx]); + received_packet->seq_num = seq_num; + received_packet->is_fec = true; + received_packet->ssrc = ssrc; + + fec_mask_list.push_back(fec_packet_masks[fec_packet_idx]); } - ++fecPacketIdx; - ++seqNum; - ++fecPacketListItem; + ++fec_packet_idx; + ++seq_num; } #ifdef VERBOSE_OUTPUT printf("Media loss mask:\n"); - for (uint32_t i = 0; i < numMediaPackets; i++) { - printf("%u ", mediaLossMask[i]); + for (uint32_t i = 0; i < num_media_packets; i++) { + printf("%u ", media_loss_mask[i]); } printf("\n\n"); printf("FEC loss mask:\n"); - for (uint32_t i = 0; i < numFecPackets; i++) { - printf("%u ", fecLossMask[i]); + for (uint32_t i = 0; i < num_fec_packets; i++) { + printf("%u ", fec_loss_mask[i]); } printf("\n\n"); #endif - std::list::iterator fecMaskIt = fecMaskList.begin(); - uint8_t* fecMask; - while (fecMaskIt != fecMaskList.end()) { - fecMask = *fecMaskIt; - uint32_t hammingDist = 0; - uint32_t recoveryPosition = 0; - for (uint32_t i = 0; i < numMediaPackets; i++) { - if (mediaLossMask[i] == 0 && fecMask[i] == 1) { - recoveryPosition = i; - ++hammingDist; + auto fec_mask_it = fec_mask_list.begin(); + while (fec_mask_it != fec_mask_list.end()) { + uint32_t hamming_dist = 0; + uint32_t recovery_position = 0; + for (uint32_t i = 0; i < num_media_packets; i++) { + if (media_loss_mask[i] == 0 && (*fec_mask_it)[i] == 1) { + recovery_position = i; + ++hamming_dist; } } - std::list::iterator itemToDelete = fecMaskIt; - ++fecMaskIt; + auto item_to_delete = fec_mask_it; + ++fec_mask_it; - if (hammingDist == 1) { + if (hamming_dist == 1) { // Recovery possible. Restart search. - mediaLossMask[recoveryPosition] = 1; - fecMaskIt = fecMaskList.begin(); - } else if (hammingDist == 0) { + media_loss_mask[recovery_position] = 1; + fec_mask_it = fec_mask_list.begin(); + } else if (hamming_dist == 0) { // FEC packet cannot provide further recovery. - fecMaskList.erase(itemToDelete); + fec_mask_list.erase(item_to_delete); } } #ifdef VERBOSE_OUTPUT printf("Recovery mask:\n"); - for (uint32_t i = 0; i < numMediaPackets; ++i) { - printf("%u ", mediaLossMask[i]); + for (uint32_t i = 0; i < num_media_packets; ++i) { + printf("%u ", media_loss_mask[i]); } printf("\n\n"); #endif // For error-checking frame completion. - bool fecPacketReceived = false; - while (!receivedPacketList.empty()) { - size_t numPacketsToDecode = random.Rand( - 1u, static_cast(receivedPacketList.size())); - ReceivePackets(&toDecodeList, &receivedPacketList, - numPacketsToDecode, reorderRate, duplicateRate, - &random); + bool fec_packet_received = false; + while (!received_packet_list.empty()) { + size_t num_packets_to_decode = random.Rand( + 1u, static_cast(received_packet_list.size())); + ReceivePackets(&to_decode_list, &received_packet_list, + num_packets_to_decode, reorder_rate, + duplicate_rate, &random); - if (fecPacketReceived == false) { - ForwardErrorCorrection::ReceivedPacketList::iterator - toDecodeIt = toDecodeList.begin(); - while (toDecodeIt != toDecodeList.end()) { - receivedPacket = *toDecodeIt; - if (receivedPacket->is_fec) { - fecPacketReceived = true; + if (fec_packet_received == false) { + for (auto* received_packet : to_decode_list) { + if (received_packet->is_fec) { + fec_packet_received = true; } - ++toDecodeIt; } } - ASSERT_EQ(0, fec.DecodeFEC(&toDecodeList, &recoveredPacketList)) - << "DecodeFEC() failed"; - ASSERT_TRUE(toDecodeList.empty()) + ASSERT_EQ(0, fec.DecodeFec(&to_decode_list, + &recovered_packet_list)) + << "DecodeFec() failed"; + ASSERT_TRUE(to_decode_list.empty()) << "Received packet list is not empty."; } - mediaPacketListItem = mediaPacketList.begin(); - mediaPacketIdx = 0; - while (mediaPacketListItem != mediaPacketList.end()) { - if (mediaLossMask[mediaPacketIdx] == 1) { + media_packet_idx = 0; + for (auto* media_packet : media_packet_list) { + if (media_loss_mask[media_packet_idx] == 1) { // Should have recovered this packet. - ForwardErrorCorrection::RecoveredPacketList::iterator - recoveredPacketListItem = recoveredPacketList.begin(); + auto recovered_packet_list_it = recovered_packet_list.cbegin(); - ASSERT_FALSE(recoveredPacketListItem == - recoveredPacketList.end()) + ASSERT_FALSE(recovered_packet_list_it == + recovered_packet_list.end()) << "Insufficient number of recovered packets."; - mediaPacket = *mediaPacketListItem; - ForwardErrorCorrection::RecoveredPacket* recoveredPacket = - *recoveredPacketListItem; + ForwardErrorCorrection::RecoveredPacket* recovered_packet = + *recovered_packet_list_it; - ASSERT_EQ(recoveredPacket->pkt->length, mediaPacket->length) + ASSERT_EQ(recovered_packet->pkt->length, media_packet->length) << "Recovered packet length not identical to original " << "media packet"; - ASSERT_EQ(0, memcmp(recoveredPacket->pkt->data, - mediaPacket->data, mediaPacket->length)) + ASSERT_EQ(0, memcmp(recovered_packet->pkt->data, + media_packet->data, media_packet->length)) << "Recovered packet payload not identical to original " << "media packet"; - delete recoveredPacket; - recoveredPacketList.pop_front(); + delete recovered_packet; + recovered_packet_list.pop_front(); } - ++mediaPacketIdx; - ++mediaPacketListItem; + ++media_packet_idx; } - fec.ResetState(&recoveredPacketList); - ASSERT_TRUE(recoveredPacketList.empty()) + fec.ResetState(&recovered_packet_list); + ASSERT_TRUE(recovered_packet_list.empty()) << "Excessive number of recovered packets.\t size is: " - << recoveredPacketList.size(); + << recovered_packet_list.size(); // -- Teardown -- - mediaPacketListItem = mediaPacketList.begin(); - while (mediaPacketListItem != mediaPacketList.end()) { - delete *mediaPacketListItem; - ++mediaPacketListItem; - mediaPacketList.pop_front(); + auto media_packet_list_it = media_packet_list.begin(); + while (media_packet_list_it != media_packet_list.end()) { + delete *media_packet_list_it; + ++media_packet_list_it; + media_packet_list.pop_front(); } - assert(mediaPacketList.empty()); + RTC_DCHECK(media_packet_list.empty()); - fecPacketListItem = fecPacketList.begin(); - while (fecPacketListItem != fecPacketList.end()) { - ++fecPacketListItem; - fecPacketList.pop_front(); - } + // Clear FEC packet list, so we don't pass in a non-empty + // list in the next call to DecodeFec(). + fec_packet_list.clear(); - // Delete received packets we didn't pass to DecodeFEC(), due to + // Delete received packets we didn't pass to DecodeFec(), due to // early frame completion. - ForwardErrorCorrection::ReceivedPacketList::iterator - receivedPacketIt = receivedPacketList.begin(); - while (receivedPacketIt != receivedPacketList.end()) { - receivedPacket = *receivedPacketIt; - delete receivedPacket; - ++receivedPacketIt; - receivedPacketList.pop_front(); + auto received_packet_it = received_packet_list.cbegin(); + while (received_packet_it != received_packet_list.end()) { + delete *received_packet_it; + ++received_packet_it; + received_packet_list.pop_front(); } - assert(receivedPacketList.empty()); + RTC_DCHECK(received_packet_list.empty()); - while (!fecMaskList.empty()) { - fecMaskList.pop_front(); + while (!fec_mask_list.empty()) { + fec_mask_list.pop_front(); } - timeStamp += 90000 / 30; - } // loop over numImpPackets + timestamp += 90000 / 30; + } // loop over num_imp_packets } // loop over FecPackets - } // loop over numMediaPackets - delete[] packetMask; + } // loop over num_media_packets } // loop over loss rates } // loop over mask types - // Have DecodeFEC free allocated memory. - fec.ResetState(&recoveredPacketList); - ASSERT_TRUE(recoveredPacketList.empty()) + // Have DecodeFec free allocated memory. + fec.ResetState(&recovered_packet_list); + ASSERT_TRUE(recovered_packet_list.empty()) << "Recovered packet list is not empty"; }