diff --git a/CHANGES b/CHANGES index b940c153bb..70d8188980 100644 --- a/CHANGES +++ b/CHANGES @@ -63,3 +63,5 @@ Changes since Asterisk 1.4-beta was branched: does not count paused queue members as unavailable. * Added maxfiles option to options section of asterisk.conf which allows you to specify what Asterisk should set as the maximum number of open files when it loads. + * Added the jittertargetextra configuration option. + diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index 865319d2ca..1ada3a24d3 100644 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -163,6 +163,7 @@ static int maxnontrunkcall = 1; static int maxjitterbuffer=1000; static int resyncthreshold=1000; static int maxjitterinterps=10; +static int jittertargetextra = 40; /* number of milliseconds the new jitter buffer adds on to its size */ static int trunkfreq = 20; static int authdebug = 1; static int autokill = 0; @@ -1125,6 +1126,7 @@ static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, int lockpeer, cons jbconf.max_jitterbuf = maxjitterbuffer; jbconf.resync_threshold = resyncthreshold; jbconf.max_contig_interp = maxjitterinterps; + jbconf.target_extra = jittertargetextra; jb_setconf(tmp->jb,&jbconf); AST_LIST_HEAD_INIT_NOLOCK(&tmp->dpentries); @@ -8958,6 +8960,8 @@ static int set_config(char *config_file, int reload) resyncthreshold = atoi(v->value); else if (!strcasecmp(v->name, "maxjitterinterps")) maxjitterinterps = atoi(v->value); + else if (!strcasecmp(v->name, "jittertargetextra")) + jittertargetextra = atoi(v->value); else if (!strcasecmp(v->name, "lagrqtime")) lagrq_time = atoi(v->value); else if (!strcasecmp(v->name, "maxregexpire")) diff --git a/configs/iax.conf.sample b/configs/iax.conf.sample index 6ab33321ff..afe25538c9 100644 --- a/configs/iax.conf.sample +++ b/configs/iax.conf.sample @@ -129,6 +129,13 @@ disallow=lpc10 ; Icky sound quality... Mr. Roboto. ; returning this many interpolations. This prevents interpolating throughout ; a long silence. ; +; +; jittertargetextra: number of milliseconds by which the new jitter buffer +; will pad its size. the default is 40, so without modification, the new +; jitter buffer will set its size to the jitter value plus 40 milliseconds. +; increasing this value may help if your network normally has low jitter, +; but occasionally has spikes. +; jitterbuffer=no forcejitterbuffer=no @@ -139,6 +146,7 @@ forcejitterbuffer=no ;maxexcessbuffer=80 ;minexcessbuffer=10 ;jittershrinkrate=1 +;jittertargetextra=40 ;trunkfreq=20 ; How frequently to send trunk msgs (in ms) diff --git a/include/jitterbuf.h b/include/jitterbuf.h index 3213534d02..4809346924 100644 --- a/include/jitterbuf.h +++ b/include/jitterbuf.h @@ -58,6 +58,7 @@ typedef struct jb_conf { long max_jitterbuf; /* defines a hard clamp to use in setting the jitter buffer delay */ long resync_threshold; /* the jb will resync when delay increases to (2 * jitter) + this param */ long max_contig_interp; /* the max interp frames to return in a row */ + long target_extra ; /* amount of additional jitterbuffer adjustment, overrides JB_TARGET_EXTRA */ } jb_conf; typedef struct jb_info { diff --git a/main/jitterbuf.c b/main/jitterbuf.c index a541d67e52..c418b7955e 100644 --- a/main/jitterbuf.c +++ b/main/jitterbuf.c @@ -79,8 +79,8 @@ void jb_reset(jitterbuf *jb) memset(jb, 0, sizeof(*jb)); jb->info.conf = s; - /* initialize length */ - jb->info.current = jb->info.target = JB_TARGET_EXTRA; + /* initialize length, using the default value */ + jb->info.current = jb->info.target = jb->info.conf.target_extra = JB_TARGET_EXTRA; jb->info.silence_begin_ts = -1; } @@ -547,7 +547,7 @@ static enum jb_return_code _jb_get(jitterbuf *jb, jb_frame *frameout, long now, dbg_cnt++; /* target */ - jb->info.target = jb->info.jitter + jb->info.min + JB_TARGET_EXTRA; + jb->info.target = jb->info.jitter + jb->info.min + jb->info.conf.target_extra; /* if a hard clamp was requested, use it */ if ((jb->info.conf.max_jitterbuf) && ((jb->info.target - jb->info.min) > jb->info.conf.max_jitterbuf)) { @@ -633,7 +633,7 @@ static enum jb_return_code _jb_get(jitterbuf *jb, jb_frame *frameout, long now, /* unless we don't have a frame, then shrink 1 frame */ /* every 80ms (though perhaps we can shrink even faster */ /* in this case) */ - if (diff < -JB_TARGET_EXTRA && + if (diff < -jb->info.conf.target_extra && ((!frame && jb->info.last_adjustment + 80 < now) || (jb->info.last_adjustment + 500 < now))) { @@ -711,7 +711,7 @@ static enum jb_return_code _jb_get(jitterbuf *jb, jb_frame *frameout, long now, /* jb->info.silence_begin_ts = 0; */ /* shrink interpl len every 10ms during silence */ - if (diff < -JB_TARGET_EXTRA && + if (diff < -jb->info.conf.target_extra && jb->info.last_adjustment + 10 <= now) { jb->info.current -= interpl; jb->info.last_adjustment = now; @@ -760,7 +760,7 @@ long jb_next(jitterbuf *jb) if (next > 0) { history_get(jb); /* shrink during silence */ - if (jb->info.target - jb->info.current < -JB_TARGET_EXTRA) + if (jb->info.target - jb->info.current < -jb->info.conf.target_extra) return jb->info.last_adjustment + 10; return next + jb->info.target; } @@ -819,6 +819,16 @@ enum jb_return_code jb_setconf(jitterbuf *jb, jb_conf *conf) jb->info.conf.resync_threshold = conf->resync_threshold; jb->info.conf.max_contig_interp = conf->max_contig_interp; + /* -1 indicates use of the default JB_TARGET_EXTRA value */ + jb->info.conf.target_extra = ( conf->target_extra == -1 ) + ? JB_TARGET_EXTRA + : conf->target_extra + ; + + /* update these to match new target_extra setting */ + jb->info.current = jb->info.conf.target_extra; + jb->info.target = jb->info.conf.target_extra; + return JB_OK; }