webrtc 中 Rtcp NACK 接收处理流程

webrtc_m74

 

1:

解析 rtcp ,如果是 NACK,那么解析;主要是解析相关的类型,和 获取相关参数;

      case rtcp::Rtpfb::kPacketType:

        switch (rtcp_block.fmt()) {

          case rtcp::Nack::kFeedbackMessageType:

            HandleNack(rtcp_block, packet_information);

 

2:

上面解析 rtcp 后,如果 rtcp 格式有效,那么任何rtcp都会触发相关的函数;

这个函数,封装了相关 rtcp 的处理回调函数;

TriggerCallbacksFromRtcpPacket(packet_information);

 

3:

webrtc 处理 Nack ,主要就是重发 没收到的 rtp 包,从历史记录中查找,发送;

void RTPSender::OnReceivedNack(

    const std::vector<uint16_t>& nack_sequence_numbers,

    int64_t avg_rtt) {

  packet_history_.SetRtt(5 + avg_rtt);

  for (uint16_t seq_no : nack_sequence_numbers) {

    const int32_t bytes_sent = ReSendPacket(seq_no); //再次发送,这函数名称很好;

    if (bytes_sent < 0) {

      // Failed to send one Sequence number. Give up the rest in this nack.

      RTC_LOG(LS_WARNING) << "Failed resending RTP packet " << seq_no

                          << ", Discard rest of packets.";

      break;

    }

  }

}

 

4:

int32_t RTPSender::ReSendPacket(uint16_t packet_id) {

  // Try to find packet in RTP packet history. Also verify RTT here, so that we

  // don't retransmit too often.

//上面注释很好了,从 packet_history_ 找到 Nack 中的 packet ; 

  absl::optional<RtpPacketHistory::PacketState> stored_packet =

      packet_history_.GetPacketState(packet_id);  

  if (!stored_packet) {

    // Packet not found.

    return 0;

  }

 

  const int32_t packet_size = static_cast<int32_t>(stored_packet->packet_size);

 

  // Skip retransmission rate check if not configured.

  if (retransmission_rate_limiter_) {

    // Check if we're overusing retransmission bitrate.

    // TODO(sprang): Add histograms for nack success or failure reasons.

    if (!retransmission_rate_limiter_->TryUseRate(packet_size)) {

      return -1;

    }

  }

 

  if (paced_sender_) {  //一般都有;

    // Convert from TickTime to Clock since capture_time_ms is based on

    // TickTime.

    int64_t corrected_capture_tims_ms =

        stored_packet->capture_time_ms + clock_delta_ms_;

//添加到 paced_sender_ 中,pacer 中 有一定的排序规则,一般 Nack 的 packet 会优先发送;

    paced_sender_->InsertPacket(

        RtpPacketSender::kNormalPriority, stored_packet->ssrc,

        stored_packet->rtp_sequence_number, corrected_capture_tims_ms,

        stored_packet->packet_size, true);

 

    return packet_size; 完成,返回;

  }

 

 

// 如果没有 paced_sender_ ,最后直接 RTPSender::SendPacketToNetwork;

  std::unique_ptr<RtpPacketToSend> packet =

      packet_history_.GetPacketAndSetSendTime(packet_id);

  if (!packet) {

    Packet could theoretically time out between the first check and this one.

    return 0;

  }

 

  const bool rtx = (RtxStatus() & kRtxRetransmitted) > 0;

 

// RTPSender::SendPacketToNetwork; 

if (!PrepareAndSendPacket(std::move(packet), rtx, true, PacedPacketInfo()))

    return -1;

 

  return packet_size;

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(WebRTC)