美文网首页
WebRTC之RTT计算

WebRTC之RTT计算

作者: stoneliuxs | 来源:发表于2019-02-20 20:06 被阅读0次

    关于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<rtcp::ReportBlock> 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<rtcp::ReportBlock> 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计算

          本文链接:https://www.haomeiwen.com/subject/sqdkyqtx.html