diff --git a/webrtc/modules/rtp_rtcp/source/forward_error_correction.cc b/webrtc/modules/rtp_rtcp/source/forward_error_correction.cc index f8a2e6f7f7..63c6d688c0 100644 --- a/webrtc/modules/rtp_rtcp/source/forward_error_correction.cc +++ b/webrtc/modules/rtp_rtcp/source/forward_error_correction.cc @@ -138,8 +138,8 @@ int ForwardErrorCorrection::GenerateFec(const PacketList& media_packets, } } - int num_fec_packets = - GetNumberOfFecPackets(num_media_packets, protection_factor); + int num_fec_packets = GetNumberOfFecPackets(num_media_packets, + protection_factor); if (num_fec_packets == 0) { return 0; } @@ -438,51 +438,50 @@ void ForwardErrorCorrection::GenerateFecUlpHeaders( void ForwardErrorCorrection::ResetState( RecoveredPacketList* recovered_packets) { - // Free the memory for any existing recovered packets, if the user hasn't. + // Free the memory for any existing recovered packets, if the caller hasn't. recovered_packets->clear(); received_fec_packets_.clear(); } void ForwardErrorCorrection::InsertMediaPacket( - ReceivedPacket* rx_packet, + ReceivedPacket* received_packet, RecoveredPacketList* recovered_packets) { // Search for duplicate packets. for (const auto& recovered_packet : *recovered_packets) { - if (rx_packet->seq_num == recovered_packet->seq_num) { + if (received_packet->seq_num == recovered_packet->seq_num) { // Duplicate packet, no need to add to list. // Delete duplicate media packet data. - rx_packet->pkt = nullptr; + received_packet->pkt = nullptr; return; } } - std::unique_ptr recovered_packet_to_insert( - new RecoveredPacket()); - // This "recovered packet" was not recovered using parity packets. - recovered_packet_to_insert->was_recovered = false; - // This media packet has already been passed on. - 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; - RecoveredPacket* recovered_packet_to_insert_ptr = - recovered_packet_to_insert.get(); + std::unique_ptr recovered_packet(new RecoveredPacket()); + // This "recovered packet" was not recovered using parity packets. + recovered_packet->was_recovered = false; + // This media packet has already been passed on. + recovered_packet->returned = true; + recovered_packet->seq_num = received_packet->seq_num; + recovered_packet->pkt = received_packet->pkt; + recovered_packet->pkt->length = received_packet->pkt->length; + + RecoveredPacket* recovered_packet_ptr = recovered_packet.get(); // 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_packets->push_back(std::move(recovered_packet_to_insert)); + recovered_packets->push_back(std::move(recovered_packet)); recovered_packets->sort(SortablePacket::LessThan()); - UpdateCoveringFecPackets(recovered_packet_to_insert_ptr); + UpdateCoveringFecPackets(recovered_packet_ptr); } void ForwardErrorCorrection::UpdateCoveringFecPackets(RecoveredPacket* packet) { for (auto& fec_packet : received_fec_packets_) { // Is this FEC packet protecting the media packet |packet|? - auto protected_it = std::lower_bound(fec_packet->protected_pkt_list.begin(), - fec_packet->protected_pkt_list.end(), + auto protected_it = std::lower_bound(fec_packet->protected_packets.begin(), + fec_packet->protected_packets.end(), packet, SortablePacket::LessThan()); - if (protected_it != fec_packet->protected_pkt_list.end() && + if (protected_it != fec_packet->protected_packets.end() && (*protected_it)->seq_num == packet->seq_num) { // Found an FEC packet which is protecting |packet|. (*protected_it)->pkt = packet->pkt; @@ -491,28 +490,30 @@ void ForwardErrorCorrection::UpdateCoveringFecPackets(RecoveredPacket* packet) { } void ForwardErrorCorrection::InsertFecPacket( - ReceivedPacket* rx_packet, + ReceivedPacket* received_packet, const RecoveredPacketList* recovered_packets) { // Check for duplicate. for (const auto& existing_fec_packet : received_fec_packets_) { - if (rx_packet->seq_num == existing_fec_packet->seq_num) { + if (received_packet->seq_num == existing_fec_packet->seq_num) { // Delete duplicate FEC packet data. - rx_packet->pkt = nullptr; + received_packet->pkt = nullptr; return; } } + std::unique_ptr fec_packet(new ReceivedFecPacket()); - fec_packet->pkt = rx_packet->pkt; - fec_packet->seq_num = rx_packet->seq_num; - fec_packet->ssrc = rx_packet->ssrc; + fec_packet->pkt = received_packet->pkt; + fec_packet->seq_num = received_packet->seq_num; + fec_packet->ssrc = received_packet->ssrc; const uint16_t seq_num_base = ByteReader::ReadBigEndian(&fec_packet->pkt->data[2]); - const uint16_t maskSizeBytes = (fec_packet->pkt->data[0] & 0x40) - ? kMaskSizeLBitSet - : kMaskSizeLBitClear; // L bit set? + const uint16_t mask_size_bytes = (fec_packet->pkt->data[0] & 0x40) + ? kMaskSizeLBitSet + : kMaskSizeLBitClear; // L bit set? - for (uint16_t byte_idx = 0; byte_idx < maskSizeBytes; ++byte_idx) { + // Parse erasure code mask from ULP header and represent as protected packets. + for (uint16_t byte_idx = 0; byte_idx < mask_size_bytes; ++byte_idx) { 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))) { @@ -522,13 +523,13 @@ void ForwardErrorCorrection::InsertFecPacket( protected_packet->seq_num = static_cast(seq_num_base + (byte_idx << 3) + bit_idx); protected_packet->pkt = nullptr; - fec_packet->protected_pkt_list.push_back(std::move(protected_packet)); + fec_packet->protected_packets.push_back(std::move(protected_packet)); } } } - if (fec_packet->protected_pkt_list.empty()) { + if (fec_packet->protected_packets.empty()) { // All-zero packet mask; we can discard this FEC packet. - LOG(LS_WARNING) << "FEC packet has an all-zero packet mask."; + LOG(LS_WARNING) << "Received FEC packet has an all-zero packet mask."; } else { AssignRecoveredPackets(fec_packet.get(), recovered_packets); // TODO(holmer): Consider replacing this with a binary search for the right @@ -545,7 +546,7 @@ void ForwardErrorCorrection::InsertFecPacket( void ForwardErrorCorrection::AssignRecoveredPackets( ReceivedFecPacket* fec_packet, const RecoveredPacketList* recovered_packets) { - ProtectedPacketList* protected_packets = &fec_packet->protected_pkt_list; + ProtectedPacketList* protected_packets = &fec_packet->protected_packets; std::vector recovered_protected_packets; // Find intersection between the (sorted) containers |protected_packets| @@ -573,7 +574,7 @@ void ForwardErrorCorrection::InsertPackets( ReceivedPacketList* received_packets, RecoveredPacketList* recovered_packets) { while (!received_packets->empty()) { - ReceivedPacket* rx_packet = received_packets->front().get(); + ReceivedPacket* received_packet = received_packets->front().get(); // Check for discarding oldest FEC packet, to avoid wrong FEC decoding from // sequence number wrap-around. Detection of old FEC packet is based on @@ -584,18 +585,17 @@ void ForwardErrorCorrection::InsertPackets( // thresholding (e.g., to distinguish between wrap-around and reordering). if (!received_fec_packets_.empty()) { uint16_t seq_num_diff = - abs(static_cast(rx_packet->seq_num) - + abs(static_cast(received_packet->seq_num) - static_cast(received_fec_packets_.front()->seq_num)); if (seq_num_diff > 0x3fff) { received_fec_packets_.pop_front(); } } - if (rx_packet->is_fec) { - InsertFecPacket(rx_packet, recovered_packets); + if (received_packet->is_fec) { + InsertFecPacket(received_packet, recovered_packets); } else { - // Insert packet at the end of |recoveredPacketList|. - InsertMediaPacket(rx_packet, recovered_packets); + InsertMediaPacket(received_packet, recovered_packets); } // Delete the received packet "wrapper". received_packets->pop_front(); @@ -606,7 +606,7 @@ void ForwardErrorCorrection::InsertPackets( bool ForwardErrorCorrection::StartPacketRecovery( const ReceivedFecPacket* fec_packet, - RecoveredPacket* recovered) { + RecoveredPacket* recovered_packet) { // This is the first packet which we try to recover with. const uint16_t ulp_header_size = fec_packet->pkt->data[0] & 0x40 ? kUlpHeaderSizeLBitSet @@ -617,74 +617,77 @@ bool ForwardErrorCorrection::StartPacketRecovery( << "Truncated FEC packet doesn't contain room for ULP header."; return false; } - recovered->pkt = new Packet(); - memset(recovered->pkt->data, 0, IP_PACKET_SIZE); - recovered->returned = false; - recovered->was_recovered = true; + recovered_packet->pkt = new Packet(); + memset(recovered_packet->pkt->data, 0, IP_PACKET_SIZE); + recovered_packet->returned = false; + recovered_packet->was_recovered = true; uint16_t protection_length = ByteReader::ReadBigEndian(&fec_packet->pkt->data[10]); if (protection_length > std::min( - sizeof(recovered->pkt->data) - kRtpHeaderSize, + sizeof(recovered_packet->pkt->data) - kRtpHeaderSize, sizeof(fec_packet->pkt->data) - kFecHeaderSize - ulp_header_size)) { LOG(LS_WARNING) << "Incorrect FEC protection length, dropping."; return false; } // Copy FEC payload, skipping the ULP header. - memcpy(&recovered->pkt->data[kRtpHeaderSize], + memcpy(&recovered_packet->pkt->data[kRtpHeaderSize], &fec_packet->pkt->data[kFecHeaderSize + ulp_header_size], protection_length); // Copy the length recovery field. - memcpy(recovered->length_recovery, &fec_packet->pkt->data[8], 2); + memcpy(recovered_packet->length_recovery, &fec_packet->pkt->data[8], 2); // Copy the first 2 bytes of the FEC header. - memcpy(recovered->pkt->data, fec_packet->pkt->data, 2); + memcpy(recovered_packet->pkt->data, fec_packet->pkt->data, 2); // Copy the 5th to 8th bytes of the FEC header. - memcpy(&recovered->pkt->data[4], &fec_packet->pkt->data[4], 4); + memcpy(&recovered_packet->pkt->data[4], &fec_packet->pkt->data[4], 4); // Set the SSRC field. - ByteWriter::WriteBigEndian(&recovered->pkt->data[8], + ByteWriter::WriteBigEndian(&recovered_packet->pkt->data[8], fec_packet->ssrc); return true; } -bool ForwardErrorCorrection::FinishPacketRecovery(RecoveredPacket* recovered) { +bool ForwardErrorCorrection::FinishPacketRecovery( + RecoveredPacket* recovered_packet) { // Set the RTP version to 2. - recovered->pkt->data[0] |= 0x80; // Set the 1st bit. - recovered->pkt->data[0] &= 0xbf; // Clear the 2nd bit. + recovered_packet->pkt->data[0] |= 0x80; // Set the 1st bit. + recovered_packet->pkt->data[0] &= 0xbf; // Clear the 2nd bit. // Set the SN field. - ByteWriter::WriteBigEndian(&recovered->pkt->data[2], - recovered->seq_num); + ByteWriter::WriteBigEndian(&recovered_packet->pkt->data[2], + recovered_packet->seq_num); // Recover the packet length. - recovered->pkt->length = - ByteReader::ReadBigEndian(recovered->length_recovery) + + recovered_packet->pkt->length = + ByteReader::ReadBigEndian(recovered_packet->length_recovery) + kRtpHeaderSize; - if (recovered->pkt->length > sizeof(recovered->pkt->data) - kRtpHeaderSize) + if (recovered_packet->pkt->length > + sizeof(recovered_packet->pkt->data) - kRtpHeaderSize) { return false; + } return true; } -void ForwardErrorCorrection::XorPackets(const Packet* src_packet, - RecoveredPacket* dst_packet) { +void ForwardErrorCorrection::XorPackets(const Packet* src, + RecoveredPacket* dst) { // XOR with the first 2 bytes of the RTP header. for (uint32_t i = 0; i < 2; ++i) { - dst_packet->pkt->data[i] ^= src_packet->data[i]; + dst->pkt->data[i] ^= src->data[i]; } // XOR with the 5th to 8th bytes of the RTP header. for (uint32_t i = 4; i < 8; ++i) { - dst_packet->pkt->data[i] ^= src_packet->data[i]; + dst->pkt->data[i] ^= src->data[i]; } // XOR with the network-ordered payload size. uint8_t media_payload_length[2]; ByteWriter::WriteBigEndian(media_payload_length, - src_packet->length - kRtpHeaderSize); - dst_packet->length_recovery[0] ^= media_payload_length[0]; - dst_packet->length_recovery[1] ^= media_payload_length[1]; + src->length - kRtpHeaderSize); + dst->length_recovery[0] ^= media_payload_length[0]; + dst->length_recovery[1] ^= media_payload_length[1]; // XOR with RTP payload. // TODO(marpan/ajm): Are we doing more XORs than required here? - for (size_t i = kRtpHeaderSize; i < src_packet->length; ++i) { - dst_packet->pkt->data[i] ^= src_packet->data[i]; + for (size_t i = kRtpHeaderSize; i < src->length; ++i) { + dst->pkt->data[i] ^= src->data[i]; } } @@ -693,7 +696,7 @@ bool ForwardErrorCorrection::RecoverPacket( RecoveredPacket* rec_packet_to_insert) { if (!StartPacketRecovery(fec_packet, rec_packet_to_insert)) return false; - for (const auto& protected_packet : fec_packet->protected_pkt_list) { + for (const auto& protected_packet : fec_packet->protected_packets) { if (protected_packet->pkt == nullptr) { // This is the packet we're recovering. rec_packet_to_insert->seq_num = protected_packet->seq_num; @@ -753,7 +756,7 @@ void ForwardErrorCorrection::AttemptRecover( int ForwardErrorCorrection::NumCoveredPacketsMissing( const ReceivedFecPacket* fec_packet) { int packets_missing = 0; - for (const auto& protected_packet : fec_packet->protected_pkt_list) { + for (const auto& protected_packet : fec_packet->protected_packets) { if (protected_packet->pkt == nullptr) { ++packets_missing; if (packets_missing > 1) { diff --git a/webrtc/modules/rtp_rtcp/source/forward_error_correction.h b/webrtc/modules/rtp_rtcp/source/forward_error_correction.h index ecc8151e89..57eec7a01a 100644 --- a/webrtc/modules/rtp_rtcp/source/forward_error_correction.h +++ b/webrtc/modules/rtp_rtcp/source/forward_error_correction.h @@ -70,19 +70,9 @@ class ForwardErrorCorrection { uint16_t seq_num; }; - // 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 - // determine frame completion. If set, we assume a FEC stream, and the - // following assumptions must hold: + // The received list parameter of DecodeFec() references structs of this type. // - // 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. - // 2. All FEC packets have a sequence number base equal to the first media - // packet in the corresponding frame. - // - // The ssrc member is needed to ensure we can restore the SSRC field of + // The ssrc member is needed to ensure that we can restore the SSRC field of // recovered packets. In most situations this could be retrieved from other // media packets, but in the case of an FEC packet protecting a single // missing media packet, we have no other means of obtaining it. @@ -99,7 +89,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() references structs of // this type. // TODO(holmer): Refactor into a proper class. class RecoveredPacket : public SortablePacket { @@ -124,88 +114,85 @@ class ForwardErrorCorrection { ForwardErrorCorrection(); virtual ~ForwardErrorCorrection(); - /** - * Generates a list of FEC packets from supplied media packets. - * - * \param[in] mediaPacketList List of media packets to protect, of type - * #Packet. All packets must belong to the - * same frame and the list must not be empty. - * \param[in] protectionFactor FEC protection overhead in the [0, 255] - * domain. To obtain 100% overhead, or an - * equal number of FEC packets as media - * packets, use 255. - * \param[in] numImportantPackets The number of "important" packets in the - * frame. These packets may receive greater - * protection than the remaining packets. The - * important packets must be located at the - * start of the media packet list. For codecs - * with data partitioning, the important - * packets may correspond to first partition - * packets. - * \param[in] useUnequalProtection Parameter to enable/disable unequal - * protection (UEP) across packets. Enabling - * UEP will allocate more protection to the - * numImportantPackets from the start of the - * mediaPacketList. - * \param[in] fec_mask_type The type of packet mask used in the FEC. - * Random or bursty type may be selected. The - * bursty type is only defined up to 12 media - * packets. If the number of media packets is - * above 12, the packets masks from the - * random table will be selected. - * \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(). - * - * \return 0 on success, -1 on failure. - */ + // + // Generates a list of FEC packets from supplied media packets. + // + // Input: media_packets List of media packets to protect, of type + // Packet. All packets must belong to the + // same frame and the list must not be empty. + // Input: protection_factor FEC protection overhead in the [0, 255] + // domain. To obtain 100% overhead, or an + // equal number of FEC packets as + // media packets, use 255. + // Input: num_important_packets The number of "important" packets in the + // frame. These packets may receive greater + // protection than the remaining packets. + // The important packets must be located at the + // start of the media packet list. For codecs + // with data partitioning, the important + // packets may correspond to first partition + // packets. + // Input: use_unequal_protection Parameter to enable/disable unequal + // protection (UEP) across packets. Enabling + // UEP will allocate more protection to the + // num_important_packets from the start of the + // media_packets. + // Input: fec_mask_type The type of packet mask used in the FEC. + // Random or bursty type may be selected. The + // bursty type is only defined up to 12 media + // packets. If the number of media packets is + // above 12, the packet masks from the random + // table will be selected. + // Output: fec_packets List of pointers to generated 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(). + // + // Returns 0 on success, -1 on failure. + // int GenerateFec(const PacketList& media_packets, uint8_t protection_factor, int num_important_packets, bool use_unequal_protection, FecMaskType fec_mask_type, std::list* fec_packets); - /** - * Decodes a list of media and FEC packets. It will parse the input received - * packet list, storing FEC packets internally and inserting media packets to - * the output recovered packet list. The recovered list will be sorted by - * 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. - * - * 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. - * - * \param[in] receivedPacketList List of new received packets, of type - * #ReceivedPacket, belonging to a single - * frame. At output the list will be empty, - * with packets either stored internally, - * or accessible through the recovered list. - * \param[out] recoveredPacketList List of recovered media packets, of type - * #RecoveredPacket, belonging to a single - * frame. The memory available through the - * list will be valid until the next call to - * DecodeFec(). - * - * \return 0 on success, -1 on failure. - */ + // + // Decodes a list of received media and FEC packets. It will parse the + // |received_packets|, storing FEC packets internally, and move + // media packets to |recovered_packets|. The recovered list will be + // sorted by ascending sequence number and have duplicates removed. + // The function should be called as new packets arrive, and + // |recovered_packets| will be progressively assembled with each call. + // When the function returns, |received_packets| will be empty. + // + // The caller will allocate packets submitted through |received_packets|. + // The function will handle allocation of recovered packets. + // + // Input: received_packets List of new received packets, of type + // ReceivedPacket, belonging to a single + // frame. At output the list will be empty, + // with packets either stored internally, + // or accessible through the recovered list. + // Output: recovered_packets List of recovered media packets, of type + // RecoveredPacket, belonging to a single + // frame. The memory available through the + // list will be valid until the next call to + // DecodeFec(). + // + // Returns 0 on success, -1 on failure. + // int DecodeFec(ReceivedPacketList* received_packets, RecoveredPacketList* recovered_packets); - // Get the number of FEC packets, given the number of media packets and the - // protection factor. + // Get the number of generated FEC packets, given the number of media packets + // and the protection factor. int GetNumberOfFecPackets(int num_media_packets, int protection_factor); // Gets the size in bytes of the FEC/ULP headers, which must be accounted for - // as packet overhead. - // \return Packet overhead in bytes. + // as packet overhead. Returns the packet overhead in bytes. static size_t PacketOverhead(); - // Reset internal states from last frame and clears |recovered_packets|. + // Reset internal states from last frame and clear |recovered_packets|. // Frees all memory allocated by this class. void ResetState(RecoveredPacketList* recovered_packets); @@ -225,7 +212,7 @@ class ForwardErrorCorrection { // TODO(holmer): Refactor into a proper class. class ReceivedFecPacket : public ForwardErrorCorrection::SortablePacket { public: - ProtectedPacketList protected_pkt_list; + ProtectedPacketList protected_packets; uint32_t ssrc; // SSRC of the current frame. rtc::scoped_refptr pkt; }; @@ -271,12 +258,13 @@ class ForwardErrorCorrection { uint8_t* packet_mask, int num_fec_packets, bool l_bit); - // Insert received packets into FEC or recovered list. + // Inserts the |received_packets| into the internal received FEC packet list + // or into |recovered_packets|. void InsertPackets(ReceivedPacketList* received_packets, RecoveredPacketList* recovered_packets); - // Insert media packet into recovered packet list. We delete duplicates. - void InsertMediaPacket(ReceivedPacket* rx_packet, + // Inserts the |received_packet| into |recovered_packets|. Deletes duplicates. + void InsertMediaPacket(ReceivedPacket* received_packet, RecoveredPacketList* recovered_packets); // Assigns pointers to the recovered packet from all FEC packets which cover @@ -286,43 +274,45 @@ class ForwardErrorCorrection { // packets covered by the FEC packet. void UpdateCoveringFecPackets(RecoveredPacket* packet); - // Insert packet into FEC list. We delete duplicates. - void InsertFecPacket(ReceivedPacket* rx_packet, + // Insert |received_packet| into internal FEC list. Deletes duplicates. + void InsertFecPacket(ReceivedPacket* received_packet, const RecoveredPacketList* recovered_packets); - // Assigns pointers to already recovered packets covered by this FEC packet. + // Assigns pointers to already recovered packets covered by |fec_packet|. static void AssignRecoveredPackets( ReceivedFecPacket* fec_packet, const RecoveredPacketList* recovered_packets); - // Insert into recovered list in correct position. + // Insert |rec_packet_to_insert| into |recovered_packets| in correct position. void InsertRecoveredPacket(RecoveredPacket* rec_packet_to_insert, RecoveredPacketList* recovered_packets); - // Attempt to recover missing packets. + // Attempt to recover missing packets, using the internally stored + // received FEC packets. void AttemptRecover(RecoveredPacketList* recovered_packets); - // Initializes the packet recovery using the FEC packet. + // Initializes packet recovery using the received |fec_packet|. static bool StartPacketRecovery(const ReceivedFecPacket* fec_packet, - RecoveredPacket* recovered); + RecoveredPacket* recovered_packet); - // 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); + // Performs XOR between |src| and |dst| and stores the result in |dst|. + static void XorPackets(const Packet* src, RecoveredPacket* dst); // Finish up the recovery of a packet. - static bool FinishPacketRecovery(RecoveredPacket* recovered); + static bool FinishPacketRecovery(RecoveredPacket* recovered_packet); // Recover a missing packet. bool RecoverPacket(const ReceivedFecPacket* fec_packet, RecoveredPacket* rec_packet_to_insert); - // Get the number of missing media packets which are covered by this - // FEC packet. An FEC packet can recover at most one packet, and if zero - // packets are missing the FEC packet can be discarded. - // This function returns 2 when two or more packets are missing. + // Get the number of missing media packets which are covered by |fec_packet|. + // An FEC packet can recover at most one packet, and if zero packets are + // missing the FEC packet can be discarded. This function returns 2 when two + // or more packets are missing. static int NumCoveredPacketsMissing(const ReceivedFecPacket* fec_packet); + // Discards old packets in |recovered_packets|, which are no longer relevant + // for recovering lost packets. static void DiscardOldRecoveredPackets( RecoveredPacketList* recovered_packets); static uint16_t ParseSequenceNumber(uint8_t* packet);