static int maxjitterbuffer=1000;
#ifdef NEWJB
static int resyncthreshold=1000;
+static int maxjitterinterps=10;
#endif
static int jittershrinkrate=2;
static int trunkfreq = 20;
tmp->jbid = -1;
jbconf.max_jitterbuf = maxjitterbuffer;
jbconf.resync_threshold = resyncthreshold;
+ jbconf.max_contig_interp = maxjitterinterps;
jb_setconf(tmp->jb,&jbconf);
}
#endif
#ifdef NEWJB
else if (!strcasecmp(v->name, "resyncthreshold"))
resyncthreshold = atoi(v->value);
+ else if (!strcasecmp(v->name, "maxjitterinterps"))
+ maxjitterinterps = atoi(v->value);
#endif
else if (!strcasecmp(v->name, "jittershrinkrate"))
jittershrinkrate = atoi(v->value);
; Resycning can be disabled by setting this parameter to -1.
; [This option presently applies only to the new jitterbuffer implementation]
;
+; maxjitterinterps: the maximum number of interpolation frames the jitterbuffer should
+; return in a row. Since some clients do not send CNG/DTX frames to indicate
+; silence, the jitterbuffer will assume silence has begun after returning this
+; many interpolations. This prevents interpolating throughout a long silence.
+; [This option presently applies only to the new jitterbuffer implementation]
+;
; maxexcessbuffer: If conditions improve after a period of high jitter,
; the jitter buffer can end up bigger than necessary. If it ends up
; more than "maxexcessbuffer" bigger than needed, Asterisk will start
forcejitterbuffer=no
;dropcount=2
;maxjitterbuffer=1000
+;maxjitterinterps=10
;resyncthreshold=1000
;maxexcessbuffer=80
;minexcessbuffer=10
jb->info.next_voice_ts += interpl;
jb->info.last_voice_ms = interpl;
jb->info.last_adjustment = now;
+ jb->info.cnt_contig_interp++;
+ if (jb->info.conf.max_contig_interp && jb->info.cnt_contig_interp >= jb->info.conf.max_contig_interp) {
+ jb->info.silence_begin_ts = jb->info.next_voice_ts - jb->info.current;
+ }
jb_dbg("G");
return JB_INTERP;
}
/* not a voice frame; just return it. */
if (frame && frame->type != JB_TYPE_VOICE) {
- if (frame->type == JB_TYPE_SILENCE)
+ if (frame->type == JB_TYPE_SILENCE) {
jb->info.silence_begin_ts = frame->ts;
+ jb->info.cnt_contig_interp = 0;
+ }
*frameout = *frame;
jb->info.frames_out++;
jb->info.next_voice_ts = frame->ts + jb->info.current + frame->ms;
jb->info.frames_out++;
decrement_losspct(jb);
+ jb->info.cnt_contig_interp = 0;
jb_dbg("v");
return JB_OK;
} else {
(jb->info.last_adjustment + 500 < now))) {
jb->info.last_adjustment = now;
+ jb->info.cnt_contig_interp = 0;
if (frame) {
*frameout = *frame;
increment_losspct(jb);
jb->info.next_voice_ts += interpl;
jb->info.last_voice_ms = interpl;
+ jb->info.cnt_contig_interp++;
+ if (jb->info.conf.max_contig_interp && jb->info.cnt_contig_interp >= jb->info.conf.max_contig_interp) {
+ jb->info.silence_begin_ts = jb->info.next_voice_ts - jb->info.current;
+ }
jb_dbg("L");
return JB_INTERP;
}
*frameout = *frame;
jb->info.next_voice_ts += frame->ms;
jb->info.frames_out++;
+ jb->info.cnt_contig_interp = 0;
decrement_losspct(jb);
jb_dbg("v");
return JB_OK;
jb->info.conf.max_jitterbuf = conf->max_jitterbuf;
jb->info.conf.resync_threshold = conf->resync_threshold;
+ jb->info.conf.max_contig_interp = conf->max_contig_interp;
return JB_OK;
}
/* settings */
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 */
} jb_conf;
typedef struct jb_info {
long last_delay; /* the last now added to history */
long cnt_delay_discont; /* the count of discontinuous delays */
long resync_offset; /* the amount to offset ts to support resyncs */
+ long cnt_contig_interp; /* the number of contiguous interp frames returned */
} jb_info;
typedef struct jb_frame {