| Index: modules/rtp_rtcp/source/forward_error_correction.cc
|
| diff --git a/modules/rtp_rtcp/source/forward_error_correction.cc b/modules/rtp_rtcp/source/forward_error_correction.cc
|
| index fe348b5e3366f9f5cc93dfc73c23e42573d14d00..3c1b1b4154ef4f65687f8f41a7bb89c59687b7e2 100644
|
| --- a/modules/rtp_rtcp/source/forward_error_correction.cc
|
| +++ b/modules/rtp_rtcp/source/forward_error_correction.cc
|
| @@ -342,16 +342,14 @@ void ForwardErrorCorrection::ResetState(
|
|
|
| void ForwardErrorCorrection::InsertMediaPacket(
|
| RecoveredPacketList* recovered_packets,
|
| - ReceivedPacket* received_packet) {
|
| - RTC_DCHECK_EQ(received_packet->ssrc, protected_media_ssrc_);
|
| + const ReceivedPacket& received_packet) {
|
| + RTC_DCHECK_EQ(received_packet.ssrc, protected_media_ssrc_);
|
|
|
| // Search for duplicate packets.
|
| for (const auto& recovered_packet : *recovered_packets) {
|
| - RTC_DCHECK_EQ(recovered_packet->ssrc, received_packet->ssrc);
|
| - if (recovered_packet->seq_num == received_packet->seq_num) {
|
| + RTC_DCHECK_EQ(recovered_packet->ssrc, received_packet.ssrc);
|
| + if (recovered_packet->seq_num == received_packet.seq_num) {
|
| // Duplicate packet, no need to add to list.
|
| - // Delete duplicate media packet data.
|
| - received_packet->pkt = nullptr;
|
| return;
|
| }
|
| }
|
| @@ -361,10 +359,10 @@ void ForwardErrorCorrection::InsertMediaPacket(
|
| recovered_packet->was_recovered = false;
|
| // This media packet has already been passed on.
|
| recovered_packet->returned = true;
|
| - recovered_packet->ssrc = received_packet->ssrc;
|
| - recovered_packet->seq_num = received_packet->seq_num;
|
| - recovered_packet->pkt = received_packet->pkt;
|
| - recovered_packet->pkt->length = received_packet->pkt->length;
|
| + recovered_packet->ssrc = received_packet.ssrc;
|
| + recovered_packet->seq_num = received_packet.seq_num;
|
| + recovered_packet->pkt = received_packet.pkt;
|
| + recovered_packet->pkt->length = received_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.
|
| RecoveredPacket* recovered_packet_ptr = recovered_packet.get();
|
| @@ -390,23 +388,22 @@ void ForwardErrorCorrection::UpdateCoveringFecPackets(
|
|
|
| void ForwardErrorCorrection::InsertFecPacket(
|
| const RecoveredPacketList& recovered_packets,
|
| - ReceivedPacket* received_packet) {
|
| - RTC_DCHECK_EQ(received_packet->ssrc, ssrc_);
|
| + const ReceivedPacket& received_packet) {
|
| + RTC_DCHECK_EQ(received_packet.ssrc, ssrc_);
|
|
|
| // Check for duplicate.
|
| for (const auto& existing_fec_packet : received_fec_packets_) {
|
| - RTC_DCHECK_EQ(existing_fec_packet->ssrc, received_packet->ssrc);
|
| - if (existing_fec_packet->seq_num == received_packet->seq_num) {
|
| - // Delete duplicate FEC packet data.
|
| - received_packet->pkt = nullptr;
|
| + RTC_DCHECK_EQ(existing_fec_packet->ssrc, received_packet.ssrc);
|
| + if (existing_fec_packet->seq_num == received_packet.seq_num) {
|
| + // Drop duplicate FEC packet data.
|
| return;
|
| }
|
| }
|
|
|
| std::unique_ptr<ReceivedFecPacket> fec_packet(new ReceivedFecPacket());
|
| - fec_packet->pkt = received_packet->pkt;
|
| - fec_packet->ssrc = received_packet->ssrc;
|
| - fec_packet->seq_num = received_packet->seq_num;
|
| + fec_packet->pkt = received_packet.pkt;
|
| + fec_packet->ssrc = received_packet.ssrc;
|
| + fec_packet->seq_num = received_packet.seq_num;
|
| // Parse ULPFEC/FlexFEC header specific info.
|
| bool ret = fec_header_reader_->ReadFecHeader(fec_packet.get());
|
| if (!ret) {
|
| @@ -483,49 +480,46 @@ void ForwardErrorCorrection::AssignRecoveredPackets(
|
| }
|
| }
|
|
|
| -void ForwardErrorCorrection::InsertPackets(
|
| - ReceivedPacketList* received_packets,
|
| +void ForwardErrorCorrection::InsertPacket(
|
| + const ReceivedPacket& received_packet,
|
| RecoveredPacketList* recovered_packets) {
|
| - while (!received_packets->empty()) {
|
| - ReceivedPacket* received_packet = received_packets->front().get();
|
| -
|
| - // Discard old FEC packets such that the sequence numbers in
|
| - // |received_fec_packets_| span at most 1/2 of the sequence number space.
|
| - // This is important for keeping |received_fec_packets_| sorted, and may
|
| - // also reduce the possibility of incorrect decoding due to sequence number
|
| - // wrap-around.
|
| - // TODO(marpan/holmer): We should be able to improve detection/discarding of
|
| - // old FEC packets based on timestamp information or better sequence number
|
| - // thresholding (e.g., to distinguish between wrap-around and reordering).
|
| - if (!received_fec_packets_.empty() &&
|
| - received_packet->ssrc == received_fec_packets_.front()->ssrc) {
|
| - // It only makes sense to detect wrap-around when |received_packet|
|
| - // and |front_received_fec_packet| belong to the same sequence number
|
| - // space, i.e., the same SSRC. This happens when |received_packet|
|
| - // is a FEC packet, or if |received_packet| is a media packet and
|
| - // RED+ULPFEC is used.
|
| - auto it = received_fec_packets_.begin();
|
| - while (it != received_fec_packets_.end()) {
|
| - uint16_t seq_num_diff = abs(static_cast<int>(received_packet->seq_num) -
|
| - static_cast<int>((*it)->seq_num));
|
| - if (seq_num_diff > 0x3fff) {
|
| - it = received_fec_packets_.erase(it);
|
| - } else {
|
| - // No need to keep iterating, since |received_fec_packets_| is sorted.
|
| - break;
|
| - }
|
| + // Discard old FEC packets such that the sequence numbers in
|
| + // |received_fec_packets_| span at most 1/2 of the sequence number space.
|
| + // This is important for keeping |received_fec_packets_| sorted, and may
|
| + // also reduce the possibility of incorrect decoding due to sequence number
|
| + // wrap-around.
|
| + // TODO(marpan/holmer): We should be able to improve detection/discarding of
|
| + // old FEC packets based on timestamp information or better sequence number
|
| + // thresholding (e.g., to distinguish between wrap-around and reordering).
|
| + if (!received_fec_packets_.empty() &&
|
| + received_packet.ssrc == received_fec_packets_.front()->ssrc) {
|
| + // It only makes sense to detect wrap-around when |received_packet|
|
| + // and |front_received_fec_packet| belong to the same sequence number
|
| + // space, i.e., the same SSRC. This happens when |received_packet|
|
| + // is a FEC packet, or if |received_packet| is a media packet and
|
| + // RED+ULPFEC is used.
|
| + auto it = received_fec_packets_.begin();
|
| + while (it != received_fec_packets_.end()) {
|
| + // TODO(nisse): This handling of wraparound appears broken, should be
|
| + // static_cast<int16_t>(
|
| + // received_packet.seq_num - back_recovered_packet->seq_num)
|
| + uint16_t seq_num_diff = abs(static_cast<int>(received_packet.seq_num) -
|
| + static_cast<int>((*it)->seq_num));
|
| + if (seq_num_diff > 0x3fff) {
|
| + it = received_fec_packets_.erase(it);
|
| + } else {
|
| + // No need to keep iterating, since |received_fec_packets_| is sorted.
|
| + break;
|
| }
|
| }
|
| + }
|
|
|
| - if (received_packet->is_fec) {
|
| - InsertFecPacket(*recovered_packets, received_packet);
|
| - } else {
|
| - InsertMediaPacket(recovered_packets, received_packet);
|
| - }
|
| - // Delete the received packet "wrapper".
|
| - received_packets->pop_front();
|
| + if (received_packet.is_fec) {
|
| + InsertFecPacket(*recovered_packets, received_packet);
|
| + } else {
|
| + InsertMediaPacket(recovered_packets, received_packet);
|
| }
|
| - RTC_DCHECK(received_packets->empty());
|
| +
|
| DiscardOldRecoveredPackets(recovered_packets);
|
| }
|
|
|
| @@ -716,38 +710,35 @@ uint32_t ForwardErrorCorrection::ParseSsrc(uint8_t* packet) {
|
| return (packet[8] << 24) + (packet[9] << 16) + (packet[10] << 8) + packet[11];
|
| }
|
|
|
| -int ForwardErrorCorrection::DecodeFec(
|
| - ReceivedPacketList* received_packets,
|
| - RecoveredPacketList* recovered_packets) {
|
| - RTC_DCHECK(received_packets);
|
| +void ForwardErrorCorrection::DecodeFec(const ReceivedPacket& received_packet,
|
| + RecoveredPacketList* recovered_packets) {
|
| RTC_DCHECK(recovered_packets);
|
|
|
| const size_t max_media_packets = fec_header_reader_->MaxMediaPackets();
|
| if (recovered_packets->size() == max_media_packets) {
|
| const RecoveredPacket* back_recovered_packet =
|
| recovered_packets->back().get();
|
| - for (const auto& received_packet : *received_packets) {
|
| - if (received_packet->ssrc == back_recovered_packet->ssrc) {
|
| - const unsigned int seq_num_diff =
|
| - abs(static_cast<int>(received_packet->seq_num) -
|
| - static_cast<int>(back_recovered_packet->seq_num));
|
| - if (seq_num_diff > max_media_packets) {
|
| - // A big gap in sequence numbers. The old recovered packets
|
| - // are now useless, so it's safe to do a reset.
|
| - LOG(LS_INFO) << "Big gap in media/ULPFEC sequence numbers. No need "
|
| - "to keep the old packets in the FEC buffers, thus "
|
| - "resetting them.";
|
| - ResetState(recovered_packets);
|
| - break;
|
| - }
|
| +
|
| + if (received_packet.ssrc == back_recovered_packet->ssrc) {
|
| + // TODO(nisse): This handling of wraparound appears broken, should be
|
| + // static_cast<int16_t>(
|
| + // received_packet.seq_num - back_recovered_packet->seq_num)
|
| + const unsigned int seq_num_diff =
|
| + abs(static_cast<int>(received_packet.seq_num) -
|
| + static_cast<int>(back_recovered_packet->seq_num));
|
| + if (seq_num_diff > max_media_packets) {
|
| + // A big gap in sequence numbers. The old recovered packets
|
| + // are now useless, so it's safe to do a reset.
|
| + LOG(LS_INFO) << "Big gap in media/ULPFEC sequence numbers. No need "
|
| + "to keep the old packets in the FEC buffers, thus "
|
| + "resetting them.";
|
| + ResetState(recovered_packets);
|
| }
|
| }
|
| }
|
|
|
| - InsertPackets(received_packets, recovered_packets);
|
| + InsertPacket(received_packet, recovered_packets);
|
| AttemptRecovery(recovered_packets);
|
| -
|
| - return 0;
|
| }
|
|
|
| size_t ForwardErrorCorrection::MaxPacketOverhead() const {
|
|
|