mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2026-07-01 07:22:23 +08:00
修复rtcp rr/sr时间戳转换相关问题,计算rtt
This commit is contained in:
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user