posts

vnn01

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;
      }
    }
  }
}

Links to this note