修复rtcp rr/sr时间戳转换相关问题,计算rtt

This commit is contained in:
ziyue
2021-07-06 21:48:51 +08:00
parent bf8642d62f
commit 4c296488f1
9 changed files with 72 additions and 33 deletions

View File

@@ -22,14 +22,14 @@ RtcpContext::RtcpContext(bool is_receiver) {
_is_receiver = is_receiver;
}
void RtcpContext::onRtp(uint16_t seq, uint32_t stamp, size_t bytes) {
void RtcpContext::onRtp(uint16_t seq, uint32_t stamp, uint32_t sample_rate, size_t bytes) {
if (_is_receiver) {
//接收者才做复杂的统计运算
auto sys_stamp = getCurrentMillisecond();
if (_last_rtp_sys_stamp) {
//计算时间戳抖动值
double diff = double(
int64_t(sys_stamp) - int64_t(_last_rtp_sys_stamp) - int64_t(stamp) + int64_t(_last_rtp_stamp));
double diff = double((int64_t(sys_stamp) - int64_t(_last_rtp_sys_stamp)) * (sample_rate / double(1000.0))
- (int64_t(stamp) - int64_t(_last_rtp_stamp)));
if (diff < 0) {
diff = -diff;
}
@@ -68,23 +68,49 @@ void RtcpContext::onRtp(uint16_t seq, uint32_t stamp, size_t bytes) {
}
void RtcpContext::onRtcp(RtcpHeader *rtcp) {
if ((RtcpType) rtcp->pt != RtcpType::RTCP_SR) {
return;
switch ((RtcpType) rtcp->pt) {
case RtcpType::RTCP_SR: {
auto rtcp_sr = (RtcpSR *) rtcp;
/**
last SR timestamp (LSR): 32 bits
The middle 32 bits out of 64 in the NTP timestamp (as explained in
Section 4) received as part of the most recent RTCP sender report
(SR) packet from source SSRC_n. If no SR has been received yet,
the field is set to zero.
*/
_last_sr_lsr = ((rtcp_sr->ntpmsw & 0xFFFF) << 16) | ((rtcp_sr->ntplsw >> 16) & 0xFFFF);
_last_sr_ntp_sys = getCurrentMillisecond();
break;
}
case RtcpType::RTCP_RR: {
auto rtcp_rr = (RtcpRR *) rtcp;
for (auto item : rtcp_rr->getItemList()) {
if (!item->last_sr_stamp) {
continue;
}
//rtp接收端收到sr包后回复rr包的延时已转换为毫秒
auto delay_ms = (uint64_t) item->delay_since_last_sr * 1000 / 65536;
//这个rr包对应sr包的ntpmsw和ntplsw
auto ntpmsw = item->last_sr_stamp >> 16;
auto ntplsw = (item->last_sr_stamp & 0xFFFF) << 16;
RtcpSR sr;
//获取当前时间戳
sr.setNtpStamp(getCurrentMillisecond(true));
//当前时间戳与上次发送的sr包直接的ntp时间差
int64_t ntpmsw_inc = (int64_t)(ntohl(sr.ntpmsw) & 0xFFFF) - (int64_t)ntpmsw;
int64_t ntplsw_inc = (int64_t)(ntohl(sr.ntplsw)) - (int64_t)ntplsw;
//转换为毫秒
auto ms_inc = ntpmsw_inc * 1000 + (ntplsw_inc / ((double) (((uint64_t) 1) << 32) * 1.0e-3));
auto rtt = (int) ((ms_inc - delay_ms) / 2);
_rtt[item->ssrc] = rtt;
//InfoL << "ssrc:" << item->ssrc << ",rtt:" << rtt;
}
break;
}
default: break;
}
if (!_is_receiver) {
WarnL << "rtp发送者收到sr包";
return;
}
auto rtcp_sr = (RtcpSR *) (rtcp);
/**
last SR timestamp (LSR): 32 bits
The middle 32 bits out of 64 in the NTP timestamp (as explained in
Section 4) received as part of the most recent RTCP sender report
(SR) packet from source SSRC_n. If no SR has been received yet,
the field is set to zero.
*/
_last_sr_lsr = ((rtcp_sr->ntpmsw & 0xFFFF) << 16) | ((rtcp_sr->ntplsw >> 16) & 0xFFFF);
_last_sr_ntp_sys = getCurrentMillisecond();
}
size_t RtcpContext::getExpectedPackets() const {
@@ -120,14 +146,9 @@ Buffer::Ptr RtcpContext::createRtcpSR(uint32_t rtcp_ssrc) {
throw std::runtime_error("rtp接收者尝试发送sr包");
}
auto rtcp = RtcpSR::create(0);
rtcp->ssrc = htonl(rtcp_ssrc);
struct timeval tv;
gettimeofday(&tv, NULL);
rtcp->setNtpStamp(tv);
//转换成rtp时间戳
rtcp->setNtpStamp(getCurrentMillisecond(true));
rtcp->rtpts = htonl(_last_rtp_stamp);
rtcp->ssrc = htonl(rtcp_ssrc);
rtcp->packet_count = htonl((uint32_t) _packets);
rtcp->octet_count = htonl((uint32_t) _bytes);
return RtcpHeader::toBuffer(std::move(rtcp));