flexfec_receiver_ProcessReceivedFec
- tags
- webrtc flexfec
总结
- FlexfecReceiver::ProcessReceivedPacket
- 将FlexfecReceiver::AddReceivedPacket适配的ForwardErrorCorrection::ReceivedPacket包和已恢复的包recovered_packets_传进ForwardErrorErroction::DecodeFec尝试恢复。如果恢复成功,则适配为RtpPacketReceived再通过OnRecoveredPacket传递出去。
序列图
细节序列图
代码
// Note that the implementation of this member function and the implementation
// in UlpfecReceiver::ProcessReceivedFec() are slightly different.
// This implementation only returns _recovered_ media packets through the
// callback, whereas the implementation in UlpfecReceiver returns _all inserted_
// media packets through the callback. The latter behaviour makes sense
// for ULPFEC, since the ULPFEC receiver is owned by the RtpVideoStreamReceiver.
// Here, however, the received media pipeline is more decoupled from the
// FlexFEC decoder, and we therefore do not interfere with the reception
// of non-recovered media packets.
void FlexfecReceiver::ProcessReceivedPacket(
const ForwardErrorCorrection::ReceivedPacket& received_packet) {
RTC_DCHECK_RUN_ON(&sequence_checker_);
// Decode.
ForwardErrorCorrection::DecodeFecResult decode_result =
erasure_code_->DecodeFec(received_packet, &recovered_packets_);
if (decode_result.num_recovered_packets == 0) {
return;
}
// Return recovered packets through callback.
for (const auto& recovered_packet : recovered_packets_) {
RTC_CHECK(recovered_packet);
if (recovered_packet->returned) {
continue;
}
++packet_counter_.num_recovered_packets;
// Set this flag first, since OnRecoveredPacket may end up here
// again, with the same packet.
recovered_packet->returned = true;
RTC_CHECK_GE(recovered_packet->pkt->data.size(), kRtpHeaderSize);
RtpPacketReceived parsed_packet(&received_packet.extensions);
if (!parsed_packet.Parse(recovered_packet->pkt->data)) {
continue;
}
parsed_packet.set_recovered(true);
// TODO(brandtr): Update here when we support protecting audio packets too.
parsed_packet.set_payload_type_frequency(kVideoPayloadTypeFrequency);
recovered_packet_receiver_->OnRecoveredPacket(parsed_packet);
// Periodically log the incoming packets at LS_INFO.
Timestamp now = clock_->CurrentTime();
bool should_log_periodically =
now - last_recovered_packet_ > kPacketLogInterval;
if (RTC_LOG_CHECK_LEVEL(LS_VERBOSE) || should_log_periodically) {
LoggingSeverity level = should_log_periodically ? LS_INFO : LS_VERBOSE;
RTC_LOG_V(level) << "Recovered media packet with SSRC: "
<< parsed_packet.Ssrc() << " seq "
<< parsed_packet.SequenceNumber() << " recovered length "
<< recovered_packet->pkt->data.size()
<< " received length "
<< received_packet.pkt->data.size()
<< " from FlexFEC stream with SSRC: " << ssrc_;
if (should_log_periodically) {
last_recovered_packet_ = now;
}
}
}
}