Index: chan_iax2.c =================================================================== RCS file: /usr/cvsroot/asterisk/channels/chan_iax2.c,v retrieving revision 1.142 diff -u -r1.142 chan_iax2.c --- chan_iax2.c 8 May 2004 14:38:48 -0000 1.142 +++ chan_iax2.c 14 May 2004 19:25:09 -0000 @@ -82,7 +82,7 @@ #define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a)) #define DEFAULT_RETRY_TIME 1000 -#define MEMORY_SIZE 100 +#define MAX_JITTERWINDOW 4096 #define DEFAULT_DROP 3 /* Flag to use with trunk calls, keeping these calls high up. It halves our effective use but keeps the division between trunked and non-trunked better. */ @@ -120,6 +120,9 @@ static int trunkfreq = 20; static int authdebug = 1; static int iaxcompat = 0; +static int jitterwindow = 100; /* window for looking at historical jitter */ +static int jittershrinkrate = 2; /* how many ms we drop per frame when + shrinking jitter buffer */ static int iaxdefaultdpcache=10 * 60; /* Cache dialplan entries for 10 minutes by default */ @@ -359,7 +362,7 @@ /* timeval that we base our delivery on */ struct timeval rxcore; /* Historical delivery time */ - int history[MEMORY_SIZE]; + int history[MAX_JITTERWINDOW]; /* Current base jitterbuffer */ int jitterbuffer; /* Current jitter measure */ @@ -1595,7 +1598,7 @@ static int schedule_delivery(struct iax_frame *fr, int reallydeliver, int updatehistory) { int ms,x; - int drops[MEMORY_SIZE]; + int drops[MAX_JITTERWINDOW]; int min, max=0, maxone=0,y,z, match; /* ms is a measure of the "lateness" of the packet relative to the first packet we received, which always has a lateness of 1. Called by @@ -1617,6 +1620,10 @@ fr->ts -= 65536; } + if(option_debug) + ast_log(LOG_DEBUG, "scheduling frame for call %d ts=%d rxstamp=%d lateness=%d\n", fr->callno, fr->ts, + iaxs[fr->callno]->rxcore.tv_sec * 1000 + iaxs[fr->callno]->rxcore.tv_sec / 1000, ms); + fr->af.delivery.tv_sec = iaxs[fr->callno]->rxcore.tv_sec; fr->af.delivery.tv_usec = iaxs[fr->callno]->rxcore.tv_usec; fr->af.delivery.tv_sec += fr->ts / 1000; @@ -1630,7 +1637,7 @@ /* Rotate our history queue of "lateness". Don't worry about those initial zeros because the first entry will always be zero */ if (updatehistory) { - for (x=0;xcallno]->history[x] = iaxs[fr->callno]->history[x+1]; /* Add a history entry for this one */ iaxs[fr->callno]->history[x] = ms; @@ -1642,7 +1649,7 @@ for (z=0;z < iax2_dropcount + 1;z++) { /* Start very optimistic ;-) */ max=-999999999; - for (x=0;xcallno]->history[x]) { /* We have a candidate new maximum value. Make sure it's not in our drop list */ @@ -1682,7 +1689,7 @@ /* 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 */ if (max < iaxs[fr->callno]->jitterbuffer - max_jitter_buffer) - iaxs[fr->callno]->jitterbuffer -= 2; + iaxs[fr->callno]->jitterbuffer -= jittershrinkrate; #if 1 @@ -2630,26 +2637,25 @@ ms = 0; if (voice) { /* On a voice frame, use predicted values if appropriate */ - if (abs(ms - p->nextpred) <= 640) { + if (abs(ms - p->nextpred) <= 240) { if (!p->nextpred) p->nextpred = f->samples / 8; ms = p->nextpred; - } else - p->nextpred = ms; + } } else { /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinkign) if appropriate unless it's a genuine frame */ if (genuine) { if (ms <= p->lastsent) ms = p->lastsent + 3; - } else if (abs(ms - p->lastsent) <= 640) { + } else if (abs(ms - p->lastsent) <= 240) { ms = p->lastsent + 3; } } } p->lastsent = ms; if (voice) - p->nextpred = p->nextpred + f->samples / 8; + p->nextpred = ms + f->samples / 8; #if 0 printf("TS: %s - %dms\n", voice ? "Audio" : "Control", ms); #endif @@ -6255,6 +6261,16 @@ maxjitterbuffer = atoi(v->value); else if (!strcasecmp(v->name, "maxexcessbuffer")) max_jitter_buffer = atoi(v->value); + else if (!strcasecmp(v->name, "jitterwindow")) { + jitterwindow = atoi(v->value); + if(jitterwindow > MAX_JITTERWINDOW) + jitterwindow = MAX_JITTERWINDOW; + } + else if (!strcasecmp(v->name, "jittershrinkrate")) { + jittershrinkrate = atoi(v->value); + if(jittershrinkrate > 2) + jittershrinkrate = 2; + } else if (!strcasecmp(v->name, "lagrqtime")) lagrq_time = atoi(v->value); else if (!strcasecmp(v->name, "dropcount"))