WebRTC之RTT计算

关于Report Block详情可以阅读6.4.1 SR: Sender Report RTCP Packet

        0                   1                   2                   3
        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
header |V=2|P|    RC   |   PT=SR=200   |             length            |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                         SSRC of sender                        |
       +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
sender |              NTP timestamp, most significant word             |
info   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |             NTP timestamp, least significant word             |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                         RTP timestamp                         |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                     sender's packet count                     |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                      sender's octet count                     |
       +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
report |                 SSRC_1 (SSRC of first source)                 |
block  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  1    | fraction lost |       cumulative number of packets lost       |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |           extended highest sequence number received           |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                      interarrival jitter                      |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                         last SR (LSR)                         |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                   delay since last SR (DLSR)                  |
       +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+

  • LSR,最近一次SR包的NTP时间戳(remote_sender_ntp_time_);LSR由NTP秒(second)低16位和毫秒(fraction)高16位组合而成,代码如下:
# 相关代码片段
bool RTCPReceiver::NTP(uint32_t* received_ntp_secs, uint32_t* received_ntp_frac ...) const {
  ...
  // 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();
  ...
  return true;
}

bool ModuleRtpRtcpImpl::LastReceivedNTP(...) const {
  // Remote SR: NTP inside the last received (mid 16 bits from sec and frac).
  uint32_t ntp_secs = 0;
  uint32_t ntp_frac = 0;
  if (!rtcp_receiver_.NTP(&ntp_secs, &ntp_frac,  rtcp_arrival_time_secs, rtcp_arrival_time_frac, NULL)) {
    return false;
  }
  *remote_sr = ((ntp_secs & 0x0000ffff) << 16) + ((ntp_frac & 0xffff0000) >> 16);
  return true;
}

std::vector RTCPSender::CreateReportBlocks(const FeedbackState& feedback_state) {
  ...
  report_block.SetLastSr(feedback_state.remote_sr);  
  ...
}
  • DLSR,最近一次收到SR包到打包Report Block包的间隔
void RTCPReceiver::HandleSenderReport(..) {
   ...
  if (remote_ssrc_ == remote_ssrc) {
    last_received_sr_ntp_ = clock_->CurrentNtpTime();
  }
   ...
}

bool RTCPReceiver::NTP(... uint32_t* rtcp_arrival_time_secs, uint32_t* rtcp_arrival_time_frac ...) const {
  ...
  // Local NTP time when we received a RTCP packet with a send block.
  if (rtcp_arrival_time_secs)
    *rtcp_arrival_time_secs = last_received_sr_ntp_.seconds();
  if (rtcp_arrival_time_frac)
    *rtcp_arrival_time_frac = last_received_sr_ntp_.fractions();
}

std::vector RTCPSender::CreateReportBlocks(...) {
  ...
  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;
  ...
  report_block.SetDelayLastSr(delay_since_last_sr);
}

相关代码片段如下

# rtcp_receiver.cc +479
int64_t rtt_ms = 0;
uint32_t send_time_ntp = report_block.last_sr();
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.
    uint32_t rtt_ntp = receive_time_ntp - delay_ntp - send_time_ntp;
    // Convert to 1/1000 seconds (milliseconds).
    rtt_ms = CompactNtpRttToMs(rtt_ntp);
    ...
}

RTT计算说明

A -(sr)> B -(rr/sr)> A
  • A是数据发送方,所以会发送SR包给到B
  • B收到A发送的SR包,记录收到此SR包的时间last_received_sr_ntp_
  • B经过一段时间的统计之后(或者发送NACK请求)向A发送RR包(如果B也向A发送媒体数据则是SR包),RR包里面需要包含ReportBlock,ReportBlock包中会把最近一次A的SR的NTP时间(NTP timestamp, most significant word和NTP timestamp, least significant word)压缩为一个32位LSR和距离收到最近一个SR包的间隔DLSR发送给A
  • A收到B发送的RR包之后记录收到时间receive_time_ntp,用收到时间减去发送时间也Delay时间就得到RTT了:receive_time_ntp - delay_ntp - send_time_ntp

你可能感兴趣的:(WebRTC之RTT计算)