Merge Steven Davie's timestamp improvements

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@3361 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.0
Mark Spencer 22 years ago
parent 7be9c6e469
commit 1f1c915fea

@ -119,7 +119,9 @@ static int ping_time = 20;
static int lagrq_time = 10; static int lagrq_time = 10;
static int maxtrunkcall = TRUNK_CALL_START; static int maxtrunkcall = TRUNK_CALL_START;
static int maxnontrunkcall = 1; static int maxnontrunkcall = 1;
static int maxjitterbuffer=3000; static int maxjitterbuffer=1000;
static int minjitterbuffer=10;
static int jittershrinkrate=2;
static int trunkfreq = 20; static int trunkfreq = 20;
static int authdebug = 1; static int authdebug = 1;
static int iaxcompat = 0; static int iaxcompat = 0;
@ -1595,12 +1597,21 @@ static unsigned int calc_fakestamp(struct chan_iax2_pvt *from, struct chan_iax2_
static int forward_delivery(struct iax_frame *fr) static int forward_delivery(struct iax_frame *fr)
{ {
struct chan_iax2_pvt *p1, *p2; struct chan_iax2_pvt *p1, *p2;
char tmp[80];
p1 = iaxs[fr->callno]; p1 = iaxs[fr->callno];
p2 = iaxs[p1->bridgecallno]; p2 = iaxs[p1->bridgecallno];
if (!p1) if (!p1)
return -1; return -1;
if (!p2) if (!p2)
return -1; return -1;
if (option_debug)
ast_log(LOG_DEBUG, "forward_delivery: Forwarding ts=%d on %d/%d to %d/%d on %s:%d\n",
fr->ts,
p1->callno, p1->peercallno,
p2->callno, p2->peercallno,
ast_inet_ntoa(tmp, sizeof(tmp), p2->addr.sin_addr), ntohs(p2->addr.sin_port));
/* Fix relative timestamp */ /* Fix relative timestamp */
fr->ts = calc_fakestamp(p1, p2, fr->ts); fr->ts = calc_fakestamp(p1, p2, fr->ts);
/* Now just send it send on the 2nd one /* Now just send it send on the 2nd one
@ -1701,7 +1712,7 @@ static int schedule_delivery(struct iax_frame *fr, int reallydeliver, int update
/* If our jitter buffer is too big (by a significant margin), then we slowly /* If our jitter buffer is too big (by a significant margin), then we slowly
shrink it by about 1 ms each time to avoid letting the change be perceived */ shrink it by about 1 ms each time to avoid letting the change be perceived */
if (max < iaxs[fr->callno]->jitterbuffer - max_jitter_buffer) if (max < iaxs[fr->callno]->jitterbuffer - max_jitter_buffer)
iaxs[fr->callno]->jitterbuffer -= 2; iaxs[fr->callno]->jitterbuffer -= jittershrinkrate;
#if 1 #if 1
@ -2590,7 +2601,8 @@ static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms,
long int ms, pred; long int ms, pred;
tpeer->trunkact = *tv; tpeer->trunkact = *tv;
mssincetx = (tv->tv_sec - tpeer->lasttxtime.tv_sec) * 1000 + (tv->tv_usec - tpeer->lasttxtime.tv_usec) / 1000; mssincetx = (tv->tv_sec - tpeer->lasttxtime.tv_sec) * 1000 +
(1000000 + tv->tv_usec - tpeer->lasttxtime.tv_usec) / 1000 - 1000;
if (mssincetx > 5000 || (!tpeer->txtrunktime.tv_sec && !tpeer->txtrunktime.tv_usec)) { if (mssincetx > 5000 || (!tpeer->txtrunktime.tv_sec && !tpeer->txtrunktime.tv_usec)) {
/* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */ /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
tpeer->txtrunktime.tv_sec = tv->tv_sec; tpeer->txtrunktime.tv_sec = tv->tv_sec;
@ -2602,7 +2614,8 @@ static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms,
tpeer->lasttxtime.tv_usec = tv->tv_usec; tpeer->lasttxtime.tv_usec = tv->tv_usec;
/* Calculate ms offset */ /* Calculate ms offset */
ms = (tv->tv_sec - tpeer->txtrunktime.tv_sec) * 1000 + (tv->tv_usec - tpeer->txtrunktime.tv_usec) / 1000; ms = (tv->tv_sec - tpeer->txtrunktime.tv_sec) * 1000 +
(1000000 + tv->tv_usec - tpeer->txtrunktime.tv_usec) / 1000 - 1000;
/* Predict from last value */ /* Predict from last value */
pred = tpeer->lastsent + sampms; pred = tpeer->lastsent + sampms;
if (abs(ms - pred) < MAX_TIMESTAMP_SKEW) if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
@ -2621,12 +2634,12 @@ static unsigned int fix_peerts(struct timeval *tv, int callno, unsigned int ts)
if (!iaxs[callno]->rxcore.tv_sec && !iaxs[callno]->rxcore.tv_usec) { if (!iaxs[callno]->rxcore.tv_sec && !iaxs[callno]->rxcore.tv_usec) {
/* Initialize rxcore time if appropriate */ /* Initialize rxcore time if appropriate */
gettimeofday(&iaxs[callno]->rxcore, NULL); gettimeofday(&iaxs[callno]->rxcore, NULL);
/* Round to nearest 20ms */ /* Round to nearest 20ms so traces look pretty */
iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000; iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
} }
/* Calculate difference between trunk and channel */ /* Calculate difference between trunk and channel */
ms = (tv->tv_sec - iaxs[callno]->rxcore.tv_sec) * 1000 + ms = (tv->tv_sec - iaxs[callno]->rxcore.tv_sec) * 1000 +
(tv->tv_usec - iaxs[callno]->rxcore.tv_usec) / 1000; (1000000 + tv->tv_usec - iaxs[callno]->rxcore.tv_usec) / 1000 - 1000;
/* Return as the sum of trunk time and the difference between trunk and real time */ /* Return as the sum of trunk time and the difference between trunk and real time */
return ms + ts; return ms + ts;
} }
@ -2655,7 +2668,7 @@ static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, str
} }
if (!p->offset.tv_sec && !p->offset.tv_usec) { if (!p->offset.tv_sec && !p->offset.tv_usec) {
gettimeofday(&p->offset, NULL); gettimeofday(&p->offset, NULL);
/* Round to nearest 20ms */ /* Round to nearest 20ms for nice looking traces */
p->offset.tv_usec -= p->offset.tv_usec % 20000; p->offset.tv_usec -= p->offset.tv_usec % 20000;
} }
/* If the timestamp is specified, just send it as is */ /* If the timestamp is specified, just send it as is */
@ -2663,10 +2676,12 @@ static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, str
return ts; return ts;
/* If we have a time that the frame arrived, always use it to make our timestamp */ /* If we have a time that the frame arrived, always use it to make our timestamp */
if (delivery && (delivery->tv_sec || delivery->tv_usec)) { if (delivery && (delivery->tv_sec || delivery->tv_usec)) {
ms = (delivery->tv_sec - p->offset.tv_sec) * 1000 + (delivery->tv_usec - p->offset.tv_usec) / 1000; ms = (delivery->tv_sec - p->offset.tv_sec) * 1000 +
(1000000 + delivery->tv_usec - p->offset.tv_usec) / 1000 - 1000;
} else { } else {
gettimeofday(&tv, NULL); gettimeofday(&tv, NULL);
ms = (tv.tv_sec - p->offset.tv_sec) * 1000 + (tv.tv_usec - p->offset.tv_usec) / 1000; ms = (tv.tv_sec - p->offset.tv_sec) * 1000 +
(1000000 + tv.tv_usec - p->offset.tv_usec) / 1000 - 1000;
if (ms < 0) if (ms < 0)
ms = 0; ms = 0;
if (voice) { if (voice) {
@ -2720,7 +2735,8 @@ static unsigned int calc_fakestamp(struct chan_iax2_pvt *p1, struct chan_iax2_pv
Adding rxcore to it gives us when we would want the packet to be delivered normally. Adding rxcore to it gives us when we would want the packet to be delivered normally.
Subtracting txcore of the outgoing channel gives us what we'd expect */ Subtracting txcore of the outgoing channel gives us what we'd expect */
ms = (p1->rxcore.tv_sec - p2->offset.tv_sec) * 1000 + (p1->rxcore.tv_usec - p2->offset.tv_usec) / 1000; ms = (p1->rxcore.tv_sec - p2->offset.tv_sec) * 1000 +
(1000000 + p1->rxcore.tv_usec - p2->offset.tv_usec) / 1000 - 1000;
fakets += ms; fakets += ms;
if (fakets <= p2->lastsent) if (fakets <= p2->lastsent)
fakets = p2->lastsent + 1; fakets = p2->lastsent + 1;
@ -2739,7 +2755,8 @@ static unsigned int calc_rxstamp(struct chan_iax2_pvt *p)
gettimeofday(&p->rxcore, NULL); gettimeofday(&p->rxcore, NULL);
gettimeofday(&tv, NULL); gettimeofday(&tv, NULL);
ms = (tv.tv_sec - p->rxcore.tv_sec) * 1000 + (tv.tv_usec - p->rxcore.tv_usec) / 1000; ms = (tv.tv_sec - p->rxcore.tv_sec) * 1000 +
(1000000 + tv.tv_usec - p->rxcore.tv_usec) / 1000 - 1000;
return ms; return ms;
} }
@ -3147,16 +3164,26 @@ static int iax2_show_registry(int fd, int argc, char *argv[])
#undef FORMAT2 #undef FORMAT2
} }
static int jitterbufsize(struct chan_iax2_pvt *pvt) {
int min, i;
min = 99999999;
for (i=0; i<MEMORY_SIZE; i++) {
if (pvt->history[i] < min)
min = pvt->history[i];
}
return pvt->jitterbuffer - min;
}
static int iax2_show_channels(int fd, int argc, char *argv[]) static int iax2_show_channels(int fd, int argc, char *argv[])
{ {
#define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %s\n" #define FORMAT2 "%-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n"
#define FORMAT "%-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-6.6s\n" #define FORMAT "%-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s\n"
int x; int x;
int numchans = 0; int numchans = 0;
char iabuf[80]; char iabuf[80];
if (argc != 3) if (argc != 3)
return RESULT_SHOWUSAGE; return RESULT_SHOWUSAGE;
ast_cli(fd, FORMAT2, "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "Format"); ast_cli(fd, FORMAT2, "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format");
for (x=0;x<IAX_MAX_CALLS;x++) { for (x=0;x<IAX_MAX_CALLS;x++) {
ast_mutex_lock(&iaxsl[x]); ast_mutex_lock(&iaxsl[x]);
if (iaxs[x]) { if (iaxs[x]) {
@ -3166,6 +3193,7 @@ static int iax2_show_channels(int fd, int argc, char *argv[])
iaxs[x]->oseqno, iaxs[x]->iseqno, iaxs[x]->oseqno, iaxs[x]->iseqno,
iaxs[x]->lag, iaxs[x]->lag,
iaxs[x]->jitter, iaxs[x]->jitter,
jitterbufsize(iaxs[x]),
ast_getformatname(iaxs[x]->voiceformat) ); ast_getformatname(iaxs[x]->voiceformat) );
numchans++; numchans++;
} }
@ -6380,6 +6408,10 @@ static int set_config(char *config_file, struct sockaddr_in* sin){
ping_time = atoi(v->value); ping_time = atoi(v->value);
else if (!strcasecmp(v->name, "maxjitterbuffer")) else if (!strcasecmp(v->name, "maxjitterbuffer"))
maxjitterbuffer = atoi(v->value); maxjitterbuffer = atoi(v->value);
else if (!strcasecmp(v->name, "minjitterbuffer"))
minjitterbuffer = atoi(v->value);
else if (!strcasecmp(v->name, "jittershrinkrate"))
jittershrinkrate = atoi(v->value);
else if (!strcasecmp(v->name, "maxexcessbuffer")) else if (!strcasecmp(v->name, "maxexcessbuffer"))
max_jitter_buffer = atoi(v->value); max_jitter_buffer = atoi(v->value);
else if (!strcasecmp(v->name, "lagrqtime")) else if (!strcasecmp(v->name, "lagrqtime"))

10
rtp.c

@ -38,6 +38,8 @@
#include <asterisk/lock.h> #include <asterisk/lock.h>
#include <asterisk/utils.h> #include <asterisk/utils.h>
#define MAX_TIMESTAMP_SKEW 640
#define RTP_MTU 1200 #define RTP_MTU 1200
#define TYPE_HIGH 0x0 #define TYPE_HIGH 0x0
@ -380,6 +382,7 @@ static void calc_rxstamp(struct timeval *tv, struct ast_rtp *rtp, unsigned int t
gettimeofday(&rtp->rxcore, NULL); gettimeofday(&rtp->rxcore, NULL);
rtp->rxcore.tv_sec -= timestamp / 8000; rtp->rxcore.tv_sec -= timestamp / 8000;
rtp->rxcore.tv_usec -= (timestamp % 8000) * 125; rtp->rxcore.tv_usec -= (timestamp % 8000) * 125;
/* Round to 20ms for nice, pretty timestamps */
rtp->rxcore.tv_usec -= rtp->rxcore.tv_usec % 20000; rtp->rxcore.tv_usec -= rtp->rxcore.tv_usec % 20000;
if (rtp->rxcore.tv_usec < 0) { if (rtp->rxcore.tv_usec < 0) {
/* Adjust appropriately if necessary */ /* Adjust appropriately if necessary */
@ -919,18 +922,19 @@ static unsigned int calc_txstamp(struct ast_rtp *rtp, struct timeval *delivery)
unsigned int ms; unsigned int ms;
if (!rtp->txcore.tv_sec && !rtp->txcore.tv_usec) { if (!rtp->txcore.tv_sec && !rtp->txcore.tv_usec) {
gettimeofday(&rtp->txcore, NULL); gettimeofday(&rtp->txcore, NULL);
/* Round to 20ms for nice, pretty timestamps */
rtp->txcore.tv_usec -= rtp->txcore.tv_usec % 20000; rtp->txcore.tv_usec -= rtp->txcore.tv_usec % 20000;
} }
if (delivery && (delivery->tv_sec || delivery->tv_usec)) { if (delivery && (delivery->tv_sec || delivery->tv_usec)) {
/* Use previous txcore */ /* Use previous txcore */
ms = (delivery->tv_sec - rtp->txcore.tv_sec) * 1000; ms = (delivery->tv_sec - rtp->txcore.tv_sec) * 1000;
ms += (delivery->tv_usec - rtp->txcore.tv_usec) / 1000; ms += (1000000 + delivery->tv_usec - rtp->txcore.tv_usec) / 1000 - 1000;
rtp->txcore.tv_sec = delivery->tv_sec; rtp->txcore.tv_sec = delivery->tv_sec;
rtp->txcore.tv_usec = delivery->tv_usec; rtp->txcore.tv_usec = delivery->tv_usec;
} else { } else {
gettimeofday(&now, NULL); gettimeofday(&now, NULL);
ms = (now.tv_sec - rtp->txcore.tv_sec) * 1000; ms = (now.tv_sec - rtp->txcore.tv_sec) * 1000;
ms += (now.tv_usec - rtp->txcore.tv_usec) / 1000; ms += (1000000 + now.tv_usec - rtp->txcore.tv_usec) / 1000 - 1000;
/* Use what we just got for next time */ /* Use what we just got for next time */
rtp->txcore.tv_sec = now.tv_sec; rtp->txcore.tv_sec = now.tv_sec;
rtp->txcore.tv_usec = now.tv_usec; rtp->txcore.tv_usec = now.tv_usec;
@ -1058,7 +1062,7 @@ static int ast_rtp_raw_write(struct ast_rtp *rtp, struct ast_frame *f, int codec
if (!f->delivery.tv_sec && !f->delivery.tv_usec) { if (!f->delivery.tv_sec && !f->delivery.tv_usec) {
/* If this isn't an absolute delivery time, Check if it is close to our prediction, /* If this isn't an absolute delivery time, Check if it is close to our prediction,
and if so, go with our prediction */ and if so, go with our prediction */
if (abs(rtp->lastts - pred) < 640) if (abs(rtp->lastts - pred) < MAX_TIMESTAMP_SKEW)
rtp->lastts = pred; rtp->lastts = pred;
else { else {
ast_log(LOG_DEBUG, "Difference is %d, ms is %d\n", abs(rtp->lastts - pred), ms); ast_log(LOG_DEBUG, "Difference is %d, ms is %d\n", abs(rtp->lastts - pred), ms);

Loading…
Cancel
Save