control maximum number of interpolation frames generated during silence by jitterbuffer (bug #4295)

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@5951 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.2-netsec
Kevin P. Fleming 21 years ago
parent 767f019264
commit 54e74ff81b

@ -136,6 +136,7 @@ static int maxnontrunkcall = 1;
static int maxjitterbuffer=1000; static int maxjitterbuffer=1000;
#ifdef NEWJB #ifdef NEWJB
static int resyncthreshold=1000; static int resyncthreshold=1000;
static int maxjitterinterps=10;
#endif #endif
static int jittershrinkrate=2; static int jittershrinkrate=2;
static int trunkfreq = 20; static int trunkfreq = 20;
@ -870,6 +871,7 @@ static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, int lockpeer, cons
tmp->jbid = -1; tmp->jbid = -1;
jbconf.max_jitterbuf = maxjitterbuffer; jbconf.max_jitterbuf = maxjitterbuffer;
jbconf.resync_threshold = resyncthreshold; jbconf.resync_threshold = resyncthreshold;
jbconf.max_contig_interp = maxjitterinterps;
jb_setconf(tmp->jb,&jbconf); jb_setconf(tmp->jb,&jbconf);
} }
#endif #endif
@ -8343,6 +8345,8 @@ static int set_config(char *config_file, int reload)
#ifdef NEWJB #ifdef NEWJB
else if (!strcasecmp(v->name, "resyncthreshold")) else if (!strcasecmp(v->name, "resyncthreshold"))
resyncthreshold = atoi(v->value); resyncthreshold = atoi(v->value);
else if (!strcasecmp(v->name, "maxjitterinterps"))
maxjitterinterps = atoi(v->value);
#endif #endif
else if (!strcasecmp(v->name, "jittershrinkrate")) else if (!strcasecmp(v->name, "jittershrinkrate"))
jittershrinkrate = atoi(v->value); jittershrinkrate = atoi(v->value);

@ -110,6 +110,12 @@ disallow=lpc10 ; Icky sound quality... Mr. Roboto.
; Resycning can be disabled by setting this parameter to -1. ; Resycning can be disabled by setting this parameter to -1.
; [This option presently applies only to the new jitterbuffer implementation] ; [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, ; maxexcessbuffer: If conditions improve after a period of high jitter,
; the jitter buffer can end up bigger than necessary. If it ends up ; the jitter buffer can end up bigger than necessary. If it ends up
; more than "maxexcessbuffer" bigger than needed, Asterisk will start ; more than "maxexcessbuffer" bigger than needed, Asterisk will start
@ -132,6 +138,7 @@ jitterbuffer=no
forcejitterbuffer=no forcejitterbuffer=no
;dropcount=2 ;dropcount=2
;maxjitterbuffer=1000 ;maxjitterbuffer=1000
;maxjitterinterps=10
;resyncthreshold=1000 ;resyncthreshold=1000
;maxexcessbuffer=80 ;maxexcessbuffer=80
;minexcessbuffer=10 ;minexcessbuffer=10

@ -564,6 +564,10 @@ static int _jb_get(jitterbuf *jb, jb_frame *frameout, long now, long interpl)
jb->info.next_voice_ts += interpl; jb->info.next_voice_ts += interpl;
jb->info.last_voice_ms = interpl; jb->info.last_voice_ms = interpl;
jb->info.last_adjustment = now; 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"); jb_dbg("G");
return JB_INTERP; return JB_INTERP;
} }
@ -572,8 +576,10 @@ static int _jb_get(jitterbuf *jb, jb_frame *frameout, long now, long interpl)
/* not a voice frame; just return it. */ /* not a voice frame; just return it. */
if (frame && frame->type != JB_TYPE_VOICE) { 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.silence_begin_ts = frame->ts;
jb->info.cnt_contig_interp = 0;
}
*frameout = *frame; *frameout = *frame;
jb->info.frames_out++; jb->info.frames_out++;
@ -592,6 +598,7 @@ static int _jb_get(jitterbuf *jb, jb_frame *frameout, long now, long interpl)
jb->info.next_voice_ts = frame->ts + jb->info.current + frame->ms; jb->info.next_voice_ts = frame->ts + jb->info.current + frame->ms;
jb->info.frames_out++; jb->info.frames_out++;
decrement_losspct(jb); decrement_losspct(jb);
jb->info.cnt_contig_interp = 0;
jb_dbg("v"); jb_dbg("v");
return JB_OK; return JB_OK;
} else { } else {
@ -622,6 +629,7 @@ static int _jb_get(jitterbuf *jb, jb_frame *frameout, long now, long interpl)
(jb->info.last_adjustment + 500 < now))) { (jb->info.last_adjustment + 500 < now))) {
jb->info.last_adjustment = now; jb->info.last_adjustment = now;
jb->info.cnt_contig_interp = 0;
if (frame) { if (frame) {
*frameout = *frame; *frameout = *frame;
@ -669,6 +677,10 @@ static int _jb_get(jitterbuf *jb, jb_frame *frameout, long now, long interpl)
increment_losspct(jb); increment_losspct(jb);
jb->info.next_voice_ts += interpl; jb->info.next_voice_ts += interpl;
jb->info.last_voice_ms = 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"); jb_dbg("L");
return JB_INTERP; return JB_INTERP;
} }
@ -677,6 +689,7 @@ static int _jb_get(jitterbuf *jb, jb_frame *frameout, long now, long interpl)
*frameout = *frame; *frameout = *frame;
jb->info.next_voice_ts += frame->ms; jb->info.next_voice_ts += frame->ms;
jb->info.frames_out++; jb->info.frames_out++;
jb->info.cnt_contig_interp = 0;
decrement_losspct(jb); decrement_losspct(jb);
jb_dbg("v"); jb_dbg("v");
return JB_OK; return JB_OK;
@ -795,6 +808,7 @@ int jb_setconf(jitterbuf *jb, jb_conf *conf)
jb->info.conf.max_jitterbuf = conf->max_jitterbuf; jb->info.conf.max_jitterbuf = conf->max_jitterbuf;
jb->info.conf.resync_threshold = conf->resync_threshold; jb->info.conf.resync_threshold = conf->resync_threshold;
jb->info.conf.max_contig_interp = conf->max_contig_interp;
return JB_OK; return JB_OK;
} }

@ -55,6 +55,7 @@ typedef struct jb_conf {
/* settings */ /* settings */
long max_jitterbuf; /* defines a hard clamp to use in setting the jitter buffer delay */ 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 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; } jb_conf;
typedef struct jb_info { typedef struct jb_info {
@ -80,6 +81,7 @@ typedef struct jb_info {
long last_delay; /* the last now added to history */ long last_delay; /* the last now added to history */
long cnt_delay_discont; /* the count of discontinuous delays */ long cnt_delay_discont; /* the count of discontinuous delays */
long resync_offset; /* the amount to offset ts to support resyncs */ long resync_offset; /* the amount to offset ts to support resyncs */
long cnt_contig_interp; /* the number of contiguous interp frames returned */
} jb_info; } jb_info;
typedef struct jb_frame { typedef struct jb_frame {

Loading…
Cancel
Save