webrtc RTT计算及NTP时间戳
2019-08-02 本文已影响0人
hijiang
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);
}