1. 概述
WebRTC使用SR/RR
包來計算rtt的
SR
報文格式:
RR
報文格式:
2. 相關代碼
RTCPSender::BuildSR
RTCPSender::BuildRR
RTCPSender::SendCompoundRTCP
RTCPReceiver::HandleReceiverReport
RTCPReceiver::HandleReportBlock
3. 探測流程
主要流程如下圖所示:
名詞解釋:
- LSR: 最近一次SR包的NTP時間戳(remote_sender_ntp_time_);LSR由NTP秒(second)低16位和毫秒(fraction)高16位組合而成;
- DLSR: 最近一次收到SR包到打包Report Block包的間隔.
探測流程:
- 發送端構造和發送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.
4. 更新流程
由上一步得到的rtt值會被傳遞到CallStats
中進行定時更新操作(CallStats::Process
), 時間間隔為1s(kUpdateIntervalMs
).
一次處理流程CallStats::Process
為:
RemoveOldReports
移除1.5s之前的舊的rtt數據;- 計算最近1.5s之內的rtt平均值和最大值;
- 如果最大值和平均值都是非負數,那么便認為rtt合法;
- 以平均rtt值和之前的舊的值做一個加權(3:7)作為最終的rtt計算值,通知所有觀察者.