mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-09 11:28:25 +00:00
Fix the calculation of the RTT for RTCP. The previous code would result in
oscillating and incorrect data. Additionally, the RTT would sometimes report negative values due to incorrect calculations. (issue #9601, patch from davetroy) git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@65842 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
56
main/rtp.c
56
main/rtp.c
@@ -831,10 +831,10 @@ struct ast_frame *ast_rtcp_read(struct ast_rtp *rtp)
|
|||||||
struct timeval now;
|
struct timeval now;
|
||||||
unsigned int length;
|
unsigned int length;
|
||||||
int rc;
|
int rc;
|
||||||
double rtt = 0;
|
double rttsec;
|
||||||
double a;
|
uint64_t rtt;
|
||||||
double dlsr;
|
unsigned int dlsr;
|
||||||
double lsr;
|
unsigned int lsr;
|
||||||
unsigned int msw;
|
unsigned int msw;
|
||||||
unsigned int lsw;
|
unsigned int lsw;
|
||||||
unsigned int comp;
|
unsigned int comp;
|
||||||
@@ -914,26 +914,44 @@ struct ast_frame *ast_rtcp_read(struct ast_rtp *rtp)
|
|||||||
break;
|
break;
|
||||||
/* Intentional fall through */
|
/* Intentional fall through */
|
||||||
case RTCP_PT_RR:
|
case RTCP_PT_RR:
|
||||||
/* This is the place to calculate RTT */
|
|
||||||
/* Don't handle multiple reception reports (rc > 1) yet */
|
/* Don't handle multiple reception reports (rc > 1) yet */
|
||||||
|
/* Calculate RTT per RFC */
|
||||||
gettimeofday(&now, NULL);
|
gettimeofday(&now, NULL);
|
||||||
timeval2ntp(now, &msw, &lsw);
|
timeval2ntp(now, &msw, &lsw);
|
||||||
/* Use the one we sent them in our SR instead, rtcp->txlsr could have been rewritten if the dlsr is large */
|
if (ntohl(rtcpheader[i + 4]) && ntohl(rtcpheader[i + 5])) { /* We must have the LSR && DLSR */
|
||||||
if (ntohl(rtcpheader[i + 4])) { /* We must have the LSR */
|
|
||||||
comp = ((msw & 0xffff) << 16) | ((lsw & 0xffff0000) >> 16);
|
comp = ((msw & 0xffff) << 16) | ((lsw & 0xffff0000) >> 16);
|
||||||
a = (double)((comp & 0xffff0000) >> 16) + (double)((double)(comp & 0xffff)/1000000.);
|
lsr = ntohl(rtcpheader[i + 4]);
|
||||||
lsr = (double)((ntohl(rtcpheader[i + 4]) & 0xffff0000) >> 16) + (double)((double)(ntohl(rtcpheader[i + 4]) & 0xffff) / 1000000.);
|
dlsr = ntohl(rtcpheader[i + 5]);
|
||||||
dlsr = (double)(ntohl(rtcpheader[i + 5])/65536.);
|
rtt = comp - lsr - dlsr;
|
||||||
rtt = a - dlsr - lsr;
|
|
||||||
if (rtt >= 0) {
|
/* Convert end to end delay to usec (keeping the calculation in 64bit space)
|
||||||
rtp->rtcp->accumulated_transit += rtt;
|
sess->ee_delay = (eedelay * 1000) / 65536; */
|
||||||
rtp->rtcp->rtt = rtt;
|
if (rtt < 4294) {
|
||||||
if (rtp->rtcp->maxrtt < rtt)
|
rtt = (rtt * 1000000) >> 16;
|
||||||
rtp->rtcp->maxrtt = rtt;
|
} else {
|
||||||
if (rtp->rtcp->minrtt > rtt)
|
rtt = (rtt * 1000) >> 16;
|
||||||
rtp->rtcp->minrtt = rtt;
|
rtt *= 1000;
|
||||||
|
}
|
||||||
|
rtt = rtt / 1000.;
|
||||||
|
rttsec = rtt / 1000.;
|
||||||
|
|
||||||
|
if (comp - dlsr >= lsr) {
|
||||||
|
rtp->rtcp->accumulated_transit += rttsec;
|
||||||
|
rtp->rtcp->rtt = rttsec;
|
||||||
|
if (rtp->rtcp->maxrtt<rttsec)
|
||||||
|
rtp->rtcp->maxrtt = rttsec;
|
||||||
|
if (rtp->rtcp->minrtt>rttsec)
|
||||||
|
rtp->rtcp->minrtt = rttsec;
|
||||||
|
} else {
|
||||||
|
ast_verbose("Internal RTCP NTP clock skew detected: "
|
||||||
|
"lsr=%u, now=%u, dlsr=%u (%d:%03dms), "
|
||||||
|
"diff=%d",
|
||||||
|
lsr, comp, dlsr, dlsr / 65536,
|
||||||
|
(dlsr % 65536) * 1000 / 65536,
|
||||||
|
dlsr - (comp - lsr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rtp->rtcp->reported_jitter = ntohl(rtcpheader[i + 3]);
|
rtp->rtcp->reported_jitter = ntohl(rtcpheader[i + 3]);
|
||||||
rtp->rtcp->reported_lost = ntohl(rtcpheader[i + 1]) & 0xffffff;
|
rtp->rtcp->reported_lost = ntohl(rtcpheader[i + 1]) & 0xffffff;
|
||||||
if (rtcp_debug_test_addr(&sin)) {
|
if (rtcp_debug_test_addr(&sin)) {
|
||||||
@@ -945,7 +963,7 @@ struct ast_frame *ast_rtcp_read(struct ast_rtp *rtp)
|
|||||||
ast_verbose(" Last SR(our NTP): %lu.%010lu\n",(unsigned long) ntohl(rtcpheader[i + 4]) >> 16,((unsigned long) ntohl(rtcpheader[i + 4]) << 16) * 4096);
|
ast_verbose(" Last SR(our NTP): %lu.%010lu\n",(unsigned long) ntohl(rtcpheader[i + 4]) >> 16,((unsigned long) ntohl(rtcpheader[i + 4]) << 16) * 4096);
|
||||||
ast_verbose(" DLSR: %4.4f (sec)\n",ntohl(rtcpheader[i + 5])/65536.0);
|
ast_verbose(" DLSR: %4.4f (sec)\n",ntohl(rtcpheader[i + 5])/65536.0);
|
||||||
if (rtt)
|
if (rtt)
|
||||||
ast_verbose(" RTT: %f(sec)\n", rtt);
|
ast_verbose(" RTT: %lu(sec)\n", rtt);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RTCP_PT_FUR:
|
case RTCP_PT_FUR:
|
||||||
|
|||||||
Reference in New Issue
Block a user