關於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