一、概述
WebRTC中有两种方式计算RTT:
基于媒体流发送端的计算。通过Sender Report(SR)和Receiver Report(RR)携带的信息计算。
基于媒体流接收端的计算。通过RTCP Extended ReportsRTCP(XR)携带Receiver Reference Time Report Block和DLRR Report Block的信息。
两种方式计算RTT的原理一样。引入XR计算方式,因为在一些场景,两个端点间一个只发媒体数据,一个只接收,这种场景下接收端不会发送SR,导致无法计算RTT。于是扩展了RTCP XR在接收端计算这种方式。
WebRTC是在RTCPReceiver::OnPeriodicRttUpdate获取RTT延时参数的。当该侧客户端在发送数据的时候,获取根据基于媒体流发送端计算的值。当该客户端仅接收媒体数据,才获取基于媒体流接收端计算的值。
二、基于媒体流发送端的计算
发送端需要打包Sender Report(SR),解析处理Receiver Report(RR)协议。
1、Sender Report(SR)协议
NTP timestamp:64bits。记录着发送该SR的NTP时间戳。
wireshark示例如下:
这里发送端发送的SR报文中NTP时间是:0xe9f144e7 0x0d601cd3
RTCPSender::BuildSR代码实现如下:
2、Receiver Report(RR)协议
last SR(LSR): 32 bits。64位NTP时间戳中间的32bit(NTP时间戳指绝对时间,相对1900年1月1日00:00:00经历的时间,单位为秒。完整NTP时间戳用64bits表示,左半32bits表示整数,右半32bits表示小数,一般为了紧凑,取中间32bits表示即可,这时整数与小数分别16bits表示)。记录着上次源SSRC_n发送SR的NTP时间,从收到的SR记录的NTP时间戳获取。如果没有收到SR,值为0。
如上面发送端发送的SR报文中NTP时间是:0xe9f144e7 0x0d601cd3,那么接收端发送的RR报文的last SR就应该是0x44e70d60
delay since last SR (DLSR): 32 bits。以1/65536(2^16)秒为单位。记录着上次接收到源SSRC_n发送的SR到当前发送RR的间隔时间。如果没有收到SR,值为0。
wireshark示例如下:
- 媒体接收端封装RR报文
PlatformThread::StartThread(void * param)
->PlatformThread::Run()
->ProcessThreadImpl2::Run(void * obj)
->ProcessThreadImpl2::Process()
->ModuleRtpRtcpImpl2::Process() //配置周期发送RTCP的RR报文TimeToSendRTCPReport&SendRTCP
->RTCPSender::SendRTCP
->RTCPSender::ComputeCompoundRTCPPacket
->RTCPSender::BuildRR
->RTCPSender::CreateReportBlocks
接收端发送RTCP的RR报文,是周期发送。 last SR为接收端收到的最后一次RTCP SR报文的NTP时间戳。
- 媒体发送端解析计算RTT值
ModuleRtpRtcpImpl2::IncomingRtcpPacket
->RTCPReceiver::IncomingPacket
->RTCPReceiver::IncomingPacket
->RTCPReceiver::ParseCompoundPacket
->RTCPReceiver::HandleReceiverReport
->RTCPReceiver::HandleReportBlock
RTCPReceiver::HandleReportBlock函数获取发送端的当前NTP时间,然后再从RR报文中提取出last_sr、delay_since_last_sr就可以计算出RTT延时时间。
三、基于媒体流接收端的计算
1、Receiver Reference Time Report Block
wireshark示例:
2、DLRR Report Block
wireshark示例:
接收端在RTCPReceiver::HandleXrDlrrReportBlock函数计算RTT延时。