webrtc 代码学习(三十) rtt 计算方法

rtt 计算方法
作者:LanPZzzz

文章目录

          • 1. 请查看 [\[webrtc\] rtcp模块中rtt时间计算](https://blog.csdn.net/dittychen/article/details/70214675)
          • 2. 因为我们查看的是A->B,B->A 的数据互通,所以在rtt 的计算的,不管是A端计算还是B端计算,都应该是一样的
          • 3. 我们在测试的时候
          • 4. BR,RR 包
          • 5. rtt 计算
          • OK,rtt 计算完成

1. 请查看 [webrtc] rtcp模块中rtt时间计算
2. 因为我们查看的是A->B,B->A 的数据互通,所以在rtt 的计算的,不管是A端计算还是B端计算,都应该是一样的
3. 我们在测试的时候
  1. 使用delay,把导到的包延迟发放,rtt没有变,但是按照计算应该是要变的啊
4. BR,RR 包

A (发送BR 包) -> B,BuildSR

std::unique_ptr RTCPSender::BuildSR(const RtcpContext& ctx) {
  。。。

  rtcp::SenderReport* report = new rtcp::SenderReport();
  report->SetSenderSsrc(ssrc_);
  在report 放入 A 端的当前时间
  report->SetNtp(ctx.now_);
  report->SetRtpTimestamp(rtp_timestamp);
  report->SetPacketCount(ctx.feedback_state_.packets_sent);
  report->SetOctetCount(ctx.feedback_state_.media_bytes_sent);
  report->SetReportBlocks(CreateReportBlocks(ctx.feedback_state_));
。。。
}

B (接收到BR 包)

void RTCPReceiver::HandleSenderReport(const CommonHeader& rtcp_block,
                                      PacketInformation* packet_information) {
  rtcp::SenderReport sender_report;
  if (!sender_report.Parse(rtcp_block)) {
    ++num_skipped_packets_;
    return;
  }

  const uint32_t remote_ssrc = sender_report.sender_ssrc();

  packet_information->remote_ssrc = remote_ssrc;

  UpdateTmmbrRemoteIsAlive(remote_ssrc);

  // Have I received RTP packets from this party?
  if (remote_ssrc_ == remote_ssrc) {
    // Only signal that we have received a SR when we accept one.
    packet_information->packet_type_flags |= kRtcpSr;

    接收到BR 包,是远程ssrc 的,保存A 端的ntp 时间
    remote_sender_ntp_time_ = sender_report.ntp();
    remote_sender_rtp_time_ = sender_report.rtp_timestamp();
    last_received_sr_ntp_ = clock_->CurrentNtpTime();
  } else {
    // We will only store the send report from one source, but
    // we will store all the receive blocks.
    packet_information->packet_type_flags |= kRtcpRr;
  }

  RTC_LOG(LS_WARNING) << "LanPZzzz === RTCPReceiver::HandleSenderReport rtp_rtcp_:"
      << (int64_t)rtp_rtcp_;
  for (const rtcp::ReportBlock report_block : sender_report.report_blocks())
    HandleReportBlock(report_block, packet_information, remote_ssrc);
}

B (发送RR 包) -> A,BuildRR
rtcp_sender_.SendRTCP(GetFeedbackState(), kRtcpReport);
-> ModuleRtpRtcpImpl::GetFeedbackState (modules\rtp_rtcp\source\rtp_rtcp_impl.cc 358)
-> ModuleRtpRtcpImpl::LastReceivedNTP (modules\rtp_rtcp\source\rtp_rtcp_impl.cc 853)
-> RTCPReceiver::NTP (modules\rtp_rtcp\source\rtcp_receiver.cc 246)主要是获取received_ntp_secs, received_ntp_frac

bool RTCPReceiver::NTP(uint32_t* received_ntp_secs,
                       uint32_t* received_ntp_frac,
                       uint32_t* rtcp_arrival_time_secs,
                       uint32_t* rtcp_arrival_time_frac,
                       uint32_t* rtcp_timestamp) const {
  rtc::CritScope lock(&rtcp_receiver_lock_);
  if (!last_received_sr_ntp_.Valid())
    return false;

   主要是获取received_ntp_secs, received_ntp_frac
  // NTP from incoming SenderReport.
  if (received_ntp_secs)
    *received_ntp_secs = remote_sender_ntp_time_.seconds();
  if (received_ntp_frac)
    *received_ntp_frac = remote_sender_ntp_time_.fractions();
    。。。。
  *remote_sr =
      ((ntp_secs & 0x0000ffff) << 16) + ((ntp_frac & 0xffff0000) >> 16);
      
  remote_sr 就是feeback 中的remote_sr

build RR

std::unique_ptr RTCPSender::BuildRR(const RtcpContext& ctx) {
  rtcp::ReceiverReport* report = new rtcp::ReceiverReport();
  report->SetSenderSsrc(ssrc_);
  report->SetReportBlocks(CreateReportBlocks(ctx.feedback_state_));
  。。。
std::vector RTCPSender::CreateReportBlocks(
    const FeedbackState& feedback_state) {
  std::vector result;
  if (!receive_statistics_)
    return result;

  // TODO(danilchap): Support sending more than |RTCP_MAX_REPORT_BLOCKS| per
  // compound rtcp packet when single rtcp module is used for multiple media
  // streams.
  result = receive_statistics_->RtcpReportBlocks(RTCP_MAX_REPORT_BLOCKS);

  if (!result.empty() && ((feedback_state.last_rr_ntp_secs != 0) ||
                          (feedback_state.last_rr_ntp_frac != 0))) {
    // Get our NTP as late as possible to avoid a race.
    uint32_t now = CompactNtp(clock_->CurrentNtpTime());

    uint32_t receive_time = feedback_state.last_rr_ntp_secs & 0x0000FFFF;
    receive_time <<= 16;
    receive_time += (feedback_state.last_rr_ntp_frac & 0xffff0000) >> 16;

    uint32_t delay_since_last_sr = now - receive_time;
    // TODO(danilchap): Instead of setting same value on all report blocks,
    // set only when media_ssrc match sender ssrc of the sender report
    // remote times were taken from.
    for (auto& report_block : result) {
      report_block.SetLastSr(feedback_state.remote_sr);  这里设置了 LSR, 就是A 端发送的时间
      report_block.SetDelayLastSr(delay_since_last_sr);
    }
  }
  return result;
}
5. rtt 计算
void RTCPReceiver::HandleReportBlock(const ReportBlock& report_block,
                                     PacketInformation* packet_information,
                                     uint32_t remote_ssrc) {
。。。

  last_received_rb_ms_ = clock_->TimeInMilliseconds();
。。。
  int64_t rtt_ms = 0;
  uint32_t send_time_ntp = report_block.last_sr();
  // RFC3550, section 6.4.1, LSR field discription states:
  // If no SR has been received yet, the field is set to zero.
  // Receiver rtp_rtcp module is not expected to calculate rtt using
  // Sender Reports even if it accidentally can.
  if (!receiver_only_ && send_time_ntp != 0) {
    uint32_t delay_ntp = report_block.delay_since_last_sr();
    // Local NTP time.
    uint32_t receive_time_ntp = CompactNtp(clock_->CurrentNtpTime());

    // RTT in 1/(2^16) seconds.
    这里计算,接收到RR 包,获取ReportBlock 中 LSR,LDSR,公式 rtt = now - LSR - LDSR 
    uint32_t rtt_ntp = receive_time_ntp - delay_ntp - send_time_ntp;
    // Convert to 1/1000 seconds (milliseconds).
    rtt_ms = CompactNtpRttToMs(rtt_ntp);
    if (rtt_ms > report_block_info->max_rtt_ms)
      report_block_info->max_rtt_ms = rtt_ms;

    if (report_block_info->num_rtts == 0 ||
        rtt_ms < report_block_info->min_rtt_ms)
      report_block_info->min_rtt_ms = rtt_ms;

    report_block_info->last_rtt_ms = rtt_ms;
    report_block_info->sum_rtt_ms += rtt_ms;
    ++report_block_info->num_rtts;

    packet_information->rtt_ms = rtt_ms;
  }

  packet_information->report_blocks.push_back(report_block_info->report_block);
}
OK,rtt 计算完成

你可能感兴趣的:(webrtc学习)