Definitions

  • RTT(Round-Trip Time): 往返时延。在计算机网络中它是一个重要的性能指标,表示从发送端发送数据开始,到发送端收到来自接收端的确认(接收端收到数据后便立即发送确认),总共经历的时延。

  • 一般认为单向时延=传输时延t1+传播时延t2+排队时延t3 t1是数据从进入节点到传输媒体所需要的时间,通常等于数据块长度/信道带宽 t2是信号在信道中需要传播一定距离而花费的时间,等于信道长度/传播速率(光纤中电磁波的传播速率约为210^5 km/s,铜缆中2.310^5 km/s) t3可笼统归纳为随机噪声,由途径的每一跳设备及收发两端负荷情况及吞吐排队情况决定(包含互联网设备和传输设备时延) 综上:时延并无标准值只有经验值。某运营商规定网内路由器间时延1000公里之内<=40ms,2000公里之内<=60ms,3000公里之内<=80ms

RTT Calculation

大写S代表发送时间,R代表接收时间,D代表延时 S(a0) A------------------------------------------------------ > B R( b0)

S(a0) D(b0) A<--------------------------------------------------------B D(b0) = S(b0) - R(b0)

1,A先发一个数据包,在本地记录下发送时间 S(a0),并把 S(a0)放在数据包中发给B 2,B收到数据包,在本地记录下数据接收时间R( b0),并把数据包发回A,发送时把本地处理延时时间 D(b0)也记录到数据包中,D(b0) = S(b0) - R(b0) 3,A收到B的回应后,记录到数据接收时间R(a0) 4, rtt = R(a0) - S(a0) - D0

WebRtc RTT Calculation

1.名词解释

  • LSR: 最近一次SR包的NTP时间戳(remote_sender_ntp_time_);LSR由NTP秒(second)低16位和毫秒(fraction)高16位组合而成;

  • DLSR: 最近一次收到SR包到打包Report Block包的间隔.

    SR报文格式:

            0                   1                   2                   30 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)                  |+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
    ​
    ​

    RR报文格式:

            0                   1                   2                   30 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=RR=201   |             length            |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|                     SSRC of packet sender                     |+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
    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)                  |+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
    report |                 SSRC_2 (SSRC of second source)                |
    block  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+2    :                               ...                             :+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+|                  profile-specific extensions                  |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

2. 探测流程

探测流程:

  • 发送端构造和发送SR包,携带发送时间戳LSR;

  • 接收端接收到最新的SR之后,使用last_received_sr_ntp_字段记录当前ntp时间戳;

  • 接收端构造RR包,设置DLSR字段为当前ntp时间戳 - last_received_sr_ntp_,之后发出RR包;

  • 发送端在接收到RR包之后,记录RR包到达时间now_ntp;

  • 计算rtt: now_ntp - LSR - DLSR

SR和RR包的数量并不需要完全相同,它们之间并不是一一对应的关系,而是相互独立发送的,各自按照自己的发送节奏发送数据. 即使SR或者RR丢失了一部分,只要发送端接收到过RR,它总能计算出rtt,因为发送端只需要一次RR包中的LSR和DLSR字段就能够算出一次rtt.

3. 更新流程

由上一步得到的rtt值会被传递到CallStats中进行定时更新操作(CallStats::Process), 时间间隔为1s(kUpdateIntervalMs). 一次处理流程CallStats::Process为:

  • RemoveOldReports移除1.5s之前的旧的rtt数据;

  • 计算最近1.5s之内的rtt平均值和最大值;

  • 如果最大值和平均值都是非负数,那么便认为rtt合法;

  • 以平均rtt值和之前的旧的值做一个加权(3:7)作为最终的rtt计算值,通知所有观察者.

4. 相关代码

`RTCPSender::BuildSR`
`RTCPSender::BuildRR`
`RTCPSender::SendCompoundRTCP`
`RTCPReceiver::HandleReceiverReport`
`RTCPReceiver::HandleReportBlock

获取LSR

bool ModuleRtpRtcpImpl::LastReceivedNTP(uint32_t* rtcp_arrival_time_secs,  // When we got the last report.uint32_t* rtcp_arrival_time_frac,uint32_t* remote_sr) 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 就是 last SR (LSR)  LSR由NTP秒(second)低16位和毫秒(fraction)高16位组合而成;*remote_sr =((ntp_secs & 0x0000ffff) << 16) + ((ntp_frac & 0xffff0000) >> 16);return true;
}

计算DLSR

bool RTCPSender::AddReportBlock(const FeedbackState& feedback_state,uint32_t ssrc,StreamStatistician* statistician) {
​.........// Delay since last received report.if ((feedback_state.last_rr_ntp_secs != 0) ||(feedback_state.last_rr_ntp_frac != 0)) {// Get the 16 lowest bits of seconds and the 16 highest bits of fractions.uint32_t now = CompactNtp(ntp);
​//接收到sr的的时间 last_rr_ntp_secs  last_rr_ntp_fracuint32_t receiveTime = feedback_state.last_rr_ntp_secs & 0x0000FFFF;receiveTime <<= 16;receiveTime += (feedback_state.last_rr_ntp_frac & 0xffff0000) >> 16;
​block->SetDelayLastSr(now - receiveTime);}return true;
}

计算RTT

void RTCPReceiver::HandleReportBlock(const ReportBlock& report_block,PacketInformation* packet_information,uint32_t remote_ssrc) {.........int64_t rtt_ms = 0;//LSRuint32_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) {//DLSRuint32_t delay_ntp = report_block.delay_since_last_sr();// Local NTP time.uint32_t receive_time_ntp = CompactNtp(clock_->CurrentNtpTime());
​//计算RTT// 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);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;}.........
}

更新回调

void CallStats::Process() {RTC_DCHECK_RUN_ON(&process_thread_checker_);int64_t now = clock_->TimeInMilliseconds();last_process_time_ = now;
​// |avg_rtt_ms_| is allowed to be read on the process thread since that's the// only thread that modifies the value.int64_t avg_rtt_ms = avg_rtt_ms_;RemoveOldReports(now, &reports_);max_rtt_ms_ = GetMaxRttMs(reports_);avg_rtt_ms = GetNewAvgRttMs(reports_, avg_rtt_ms);{rtc::CritScope lock(&avg_rtt_ms_lock_);avg_rtt_ms_ = avg_rtt_ms;}
​// If there is a valid rtt, update all observers with the max rtt.if (max_rtt_ms_ >= 0) {RTC_DCHECK_GE(avg_rtt_ms, 0);for (CallStatsObserver* observer : observers_)observer->OnRttUpdate(avg_rtt_ms, max_rtt_ms_);// Sum for Histogram of average RTT reported over the entire call.sum_avg_rtt_ms_ += avg_rtt_ms;++num_avg_rtt_;}
}
int64_t GetNewAvgRttMs(const std::list<CallStats::RttTime>& reports,int64_t prev_avg_rtt) {if (reports.empty())return -1;  // Reset (invalid average).
​int64_t cur_rtt_ms = GetAvgRttMs(reports);if (prev_avg_rtt == -1)return cur_rtt_ms;  // New initial average value.
​// Weight factor to apply to the average rtt.// We weigh the old average at 70% against the new average (30%).constexpr const float kWeightFactor = 0.3f;return prev_avg_rtt * (1.0f - kWeightFactor) + cur_rtt_ms * kWeightFactor;
}

References

[http://www.voidcn.com/article/p-dkzjvoaj-bpd.html]  http://www.voidcn.com/article/p-dkzjvoaj-bpd.html

[https://www.cnblogs.com/xl2432/p/13424448.html]  https://www.cnblogs.com/xl2432/p/13424448.html

webrtc rtt 计算相关推荐

  1. mips平台下使用jiffies_to_msecs差值计算rtt不准确问题

    我们业务模块实现了rtt计算机制,通过发送探测request时,使用jiffies_to_msecs(jiffies)记录下发送时间值.收到探测reply时,再使用jiffies_to_msecs(j ...

  2. WebRTC系列<四> 全面了解客户端-服务器网页游戏的WebRTC

    转载:https://blog.brkho.com/2017/03/15/dive-into-client-server-web-games-webrtc/ 多人游戏很有趣.对于他们在单人沉浸感方面所 ...

  3. 5位音视频技术专家热议WebRTC、Qos、AI、4K

    9月15日,由即构科技ZEGO主办的2018音视频技术嘉年华在来到上海.这次,我们邀请到了即构科技.TutorABC.咪咕视讯.触宝科技.Intel的5位音视频技术专家,就音视频圈热议的WebRTC. ...

  4. 流媒体学习之路(WebRTC)——GCC分析(1)

    流媒体学习之路(WebRTC)--GCC整体分析(1) 文章目录 流媒体学习之路(WebRTC)--GCC整体分析(1) 一.简介 二.类分析 2.1 RtpTransportControllerSe ...

  5. [通俗易懂]深入理解TCP协议(下):RTT、滑动窗口、拥塞处理

    转自即时通讯网:http://www.52im.net/ 前言 此文为系列文章的下篇,如果你对TCP不熟悉的话,请先看看上篇<[通俗易懂]深入理解TCP协议(上):理论基础> . 上篇中, ...

  6. webrtc 渲染_webRTC 中 timing 信息的使用

    作者:付明旺.唐桥科技资深架构师.负责实时通信软件的技术创新与研发.曾就职于中兴通讯.诺基亚,在4G和IMS-webRTC等电信通信产品担任软件工程师.系统架构师等角色,具有丰富的无线/互联网通信.实 ...

  7. TCP RTT与TCP RTO关系详解

    本文目录 1,TCP的RTT和TCP的RTO的定义 1.1,什么是TCP的RTT 1.2,什么是TCP的RTO 2,TCP的当前RTT和RTO的计算 2.1,开始讲RTT计算算法前,我们先理解一下TC ...

  8. WebRTC GCC 拥塞控制算法(REMB-GCC)

    目录 一. 前言 二. REMB-GCC算法原理 1. 接收端基于延时梯度的带宽预估 (1)Arrival-time filter (2)Overuse Detector (3)Adaptive th ...

  9. 音视频技术开发周刊 | 145

    每周一期,纵览音视频技术领域的干货和新闻投稿:contribute@livevideostack.com. 架构 伊隆·马斯克(Elon Musk):视频会议应用"肯定"会出现在特 ...

  10. ZEGO 2018上海音视频技术嘉年华 活动回顾

    9月15日,由即构科技ZEGO主办的2018音视频技术嘉年华在来到上海.这次,我们邀请到了即构科技.TutorABC.咪咕视讯.触宝科技.Intel的5位音视频技术专家,就音视频圈热议的WebRTC. ...

最新文章

  1. MongoDb数据库面试整理
  2. (转)Thread的中断机制(interrupt)
  3. 注入(二):修改导入表(c++)
  4. 好书推荐 -《国富论》-15-09
  5. OJ1078: a+b(多实例测试1)(C语言数组解题)
  6. C#LeetCode刷题,走进Google,走近人生
  7. WEB站点服务器安全配置
  8. 利用Linux的强大移植性和兼容性将操作系统轻松安装到硬盘
  9. Could not load driverClass ${jdbc.driver}
  10. python游戏编程入门下载-Python游戏编程入门 中文pdf扫描版|网盘下载内附地址提取码|...
  11. 在场景中添加光线——在反光表面添加镜面高光
  12. pytorch版crnn网络框架
  13. 从零开始学Java——基础篇
  14. java贪吃蛇碰撞判定分析_java贪吃蛇碰撞检测
  15. IDEA 开发工具安装教程及破解步骤(激活至2099年)
  16. Oracle使用ancestor incarnation完成基于时间点的不完全恢复
  17. 一个严谨的STM32串口DMA发送接收(1.5Mbps波特率)机制
  18. 我30岁自学编程,当上高级工程师,几度精疲力尽想放弃
  19. 公众号如何获得关注粉丝openid?
  20. 2天,我把MySQL索引、事务、分库分表、锁、性能优化撸完了!

热门文章

  1. 摄像机成像原理(模型)与标定
  2. java毕业设计——基于java+JDBC+sqlserver的固定资产管理系统设计与实现(毕业论文+程序源码)——固定资产管理系统
  3. Scrapy对接Selenium(说明在哪里进行对接为什么在这里):小猪短租网实战分析
  4. 中小企业如何选择合适的存储解决方案?
  5. VOA 2011-2-10
  6. java aspose 导出word_使用Aspose.word导出word报告
  7. 互联网诞生记: 浪成于微澜之间
  8. WorldFirst澳元收款账户上线,人民币提现当天到账!
  9. 萨达萨达发神鼎飞丹砂
  10. Android 11 usb调试默认打开