webrtc RTT计算及NTP时间戳

2019-08-02  本文已影响0人  hijiang

RTT:round-trip time(往返时延),是指从数据包发送开始,到接收端确认接收,然后发送确认给发送端总共经历的延时,注意:不包括接收端处理需要的耗时。

Sender:s(t0)---------------------------------------------------------------->Receiver:r(t1)
Sender:r(t3)<-----------------------------------------------------------------Receiver:s(t2)

rtt时间=t1-t0+t3-t2=t3-t0-(t2-t1)=t3-t0-d d(接收端处理耗时)

1、sender发送一个数据包,记录本地发送的时间s(t0),并将s(t0)带在发送的包中;
2、recevier收到包时,记录接收包的时间r(t1);
3、receiver在t2时刻将包发回给sender,在回包中带上处理耗时d=t2-t1,及sender传来的s(t0);
4、sender收到receiver发回的包记录时刻t3;
5、rtt=r(t3)-s(t0)-d 即路上的耗时为:t3-t0-处理耗时

下面来看下webrtc中rtt计算:
webrtc中所有rtcp包都丢到RTCPReceiver中处理:

void RTCPReceiver::IncomingPacket(const uint8_t* packet, size_t packet_size) {
  if (packet_size == 0) {
    RTC_LOG(LS_WARNING) << "Incoming empty RTCP packet";
    return;
  }

  PacketInformation packet_information;
  if (!ParseCompoundPacket(packet, packet + packet_size, &packet_information))//这里扫描,并处理对应的包
    return;
  TriggerCallbacksFromRtcpPacket(packet_information);
}
bool RTCPReceiver::ParseCompoundPacket(const uint8_t* packet_begin,
                                       const uint8_t* packet_end,
                                       PacketInformation* packet_information) {
  ...
    switch (rtcp_block.type()) {

      case rtcp::SenderReport::kPacketType:
        HandleSenderReport(rtcp_block, packet_information);
        break;

      case rtcp::ReceiverReport::kPacketType:
        HandleReceiverReport(rtcp_block, packet_information);
        break;
  ...
  return true;
}

最终在HandleReportBlock中计算rtt

void RTCPReceiver::HandleReportBlock(const ReportBlock& report_block,
                                     PacketInformation* packet_information,
                                     uint32_t remote_ssrc) {
  // This will be called once per report block in the RTCP packet.
  // We filter out all report blocks that are not for us.
  // Each packet has max 31 RR blocks.
  //
  // We can calc RTT if we send a send report and get a report block back.

  // |report_block.source_ssrc()| is the SSRC identifier of the source to
  // which the information in this reception report block pertains.

  // Filter out all report blocks that are not for us.
  if (registered_ssrcs_.count(report_block.source_ssrc()) == 0) {
    return;
  }
  
  last_received_rb_ms_ = clock_->TimeInMilliseconds();

  ReportBlockWithRtt* report_block_info = &received_report_blocks_[report_block.source_ssrc()][remote_ssrc];
  report_block_info->report_block.sender_ssrc = remote_ssrc;
  report_block_info->report_block.source_ssrc = report_block.source_ssrc();
  report_block_info->report_block.fraction_lost = report_block.fraction_lost();
  report_block_info->report_block.packets_lost = report_block.cumulative_lost_signed();

  if (report_block.extended_high_seq_num() > report_block_info->report_block.extended_highest_sequence_number) {
    // We have successfully delivered new RTP packets to the remote side after
    // the last RR was sent from the remote side.
    last_increased_sequence_number_ms_ = clock_->TimeInMilliseconds();
  }

  report_block_info->report_block.extended_highest_sequence_number = report_block.extended_high_seq_num();
  report_block_info->report_block.jitter = report_block.jitter();
  report_block_info->report_block.delay_since_last_sender_report = report_block.delay_since_last_sr();
  report_block_info->report_block.last_sender_report_timestamp = report_block.last_sr();

  int64_t rtt_ms = 0;
  //获取这个包对应的sr包的发送NTP时间
  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) {
    //获取接收端的处理延时即d
    uint32_t delay_ntp = report_block.delay_since_last_sr();
    // Local NTP time.
    //获取接收到这个rr包的NTP时间
    uint32_t receive_time_ntp = CompactNtp(clock_->CurrentNtpTime());

    // RTT in 1/(2^16) seconds.
    // 得到RTT,单位是2^16分之1秒
    uint32_t rtt_ntp = receive_time_ntp - delay_ntp - send_time_ntp;
    // Convert to 1/1000 seconds (milliseconds).
    // 转换为ms
    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);
}
上一篇下一篇

猜你喜欢

热点阅读