美文网首页
webrtc RTT计算及NTP时间戳

webrtc RTT计算及NTP时间戳

作者: hijiang | 来源:发表于2019-08-02 15:35 被阅读0次

    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);
    }
    

    相关文章

      网友评论

          本文标题:webrtc RTT计算及NTP时间戳

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