// TODO(eladalon): Consider using packet.recovered() to avoid processing
// recovered packets here.
std::unique_ptr<ForwardErrorCorrection::ReceivedPacket>FlexfecReceiver::AddReceivedPacket(const RtpPacketReceived& packet) {
RTC_DCHECK_RUN_ON(&sequence_checker_);
// RTP packets with a full base header (12 bytes), but without payload,
// could conceivably be useful in the decoding. Therefore we check
// with a non-strict inequality here.
RTC_DCHECK_GE(packet.size(), kRtpHeaderSize);
// Demultiplex based on SSRC, and insert into erasure code decoder.
std::unique_ptr<ForwardErrorCorrection::ReceivedPacket> received_packet(
new ForwardErrorCorrection::ReceivedPacket());
received_packet->seq_num = packet.SequenceNumber();
received_packet->ssrc = packet.Ssrc();
received_packet->extensions = packet.extension_manager();
if (received_packet->ssrc == ssrc_) {
// This is a FlexFEC packet.
if (packet.payload_size() < kMinFlexfecHeaderSize) {
RTC_LOG(LS_WARNING) <<"Truncated FlexFEC packet, discarding.";
returnnullptr;
}
received_packet->is_fec =true;
++packet_counter_.num_fec_packets;
// Insert packet payload into erasure code.
received_packet->pkt = scoped_refptr<ForwardErrorCorrection::Packet>(
new ForwardErrorCorrection::Packet());
received_packet->pkt->data = packet.Buffer().Slice(packet.headers_size(), packet.payload_size());
} else {
// This is a media packet, or a FlexFEC packet belonging to some
// other FlexFEC stream.
if (received_packet->ssrc != protected_media_ssrc_) {
returnnullptr;
}
received_packet->is_fec =false;
// Insert entire packet into erasure code.
// Create a copy and fill with zeros all mutable extensions.
received_packet->pkt = scoped_refptr<ForwardErrorCorrection::Packet>(
new ForwardErrorCorrection::Packet());
RtpPacketReceived packet_copy(packet);
packet_copy.ZeroMutableExtensions();
received_packet->pkt->data = packet_copy.Buffer();
}
++packet_counter_.num_packets;
return received_packet;
}