Skip to content
Snippets Groups Projects
Commit af65be5a authored by Mark Spencer's avatar Mark Spencer
Browse files

Fix jitter issues with out-of-order audio (bug #4163)

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@5612 65c4cc65-6c06-0410-ace0-fbb531ad65f3
parent 6f76e2b7
Branches
No related tags found
No related merge requests found
...@@ -58,7 +58,7 @@ void jb_reset(jitterbuf *jb) ...@@ -58,7 +58,7 @@ void jb_reset(jitterbuf *jb)
/* initialize length */ /* initialize length */
jb->info.current = jb->info.target = 0; jb->info.current = jb->info.target = 0;
jb->info.silence = 1; jb->info.silence_begin_ts = -1;
} }
jitterbuf * jb_new() jitterbuf * jb_new()
...@@ -405,7 +405,7 @@ static void jb_dbginfo(jitterbuf *jb) ...@@ -405,7 +405,7 @@ static void jb_dbginfo(jitterbuf *jb)
jb->info.frames_in, jb->info.frames_out, jb->info.frames_late, jb->info.frames_lost, jb->info.frames_dropped, jb->info.frames_cur); jb->info.frames_in, jb->info.frames_out, jb->info.frames_late, jb->info.frames_lost, jb->info.frames_dropped, jb->info.frames_cur);
jb_dbg("jitter=%ld current=%ld target=%ld min=%ld sil=%d len=%d len/fcur=%ld\n", jb_dbg("jitter=%ld current=%ld target=%ld min=%ld sil=%d len=%d len/fcur=%ld\n",
jb->info.jitter, jb->info.current, jb->info.target, jb->info.min, jb->info.silence, jb->info.current - jb->info.min, jb->info.jitter, jb->info.current, jb->info.target, jb->info.min, jb->info.silence_begin_ts, jb->info.current - jb->info.min,
jb->info.frames_cur ? (jb->info.current - jb->info.min)/jb->info.frames_cur : -8); jb->info.frames_cur ? (jb->info.current - jb->info.min)/jb->info.frames_cur : -8);
if (jb->info.frames_in > 0) if (jb->info.frames_in > 0)
jb_dbg("jb info: Loss PCT = %ld%%, Late PCT = %ld%%\n", jb_dbg("jb info: Loss PCT = %ld%%, Late PCT = %ld%%\n",
...@@ -506,7 +506,7 @@ static int _jb_get(jitterbuf *jb, jb_frame *frameout, long now) ...@@ -506,7 +506,7 @@ static int _jb_get(jitterbuf *jb, jb_frame *frameout, long now)
jb->info.last_voice_ts += jb->info.last_voice_ms; jb->info.last_voice_ts += jb->info.last_voice_ms;
/* let's work on non-silent case first */ /* let's work on non-silent case first */
if (!jb->info.silence) { if (!jb->info.silence_begin_ts) {
/* we want to grow */ /* we want to grow */
if ((diff > 0) && if ((diff > 0) &&
/* we haven't grown in the delay length */ /* we haven't grown in the delay length */
...@@ -528,7 +528,7 @@ static int _jb_get(jitterbuf *jb, jb_frame *frameout, long now) ...@@ -528,7 +528,7 @@ static int _jb_get(jitterbuf *jb, jb_frame *frameout, long now)
jb->info.last_voice_ts -= jb->info.last_voice_ms; jb->info.last_voice_ts -= jb->info.last_voice_ms;
if (frame->type == JB_TYPE_SILENCE) if (frame->type == JB_TYPE_SILENCE)
jb->info.silence = 1; jb->info.silence_begin_ts = frame->ts;
*frameout = *frame; *frameout = *frame;
jb->info.frames_out++; jb->info.frames_out++;
...@@ -625,31 +625,46 @@ static int _jb_get(jitterbuf *jb, jb_frame *frameout, long now) ...@@ -625,31 +625,46 @@ static int _jb_get(jitterbuf *jb, jb_frame *frameout, long now)
* here, plus handle last_voice_ts a bit differently */ * here, plus handle last_voice_ts a bit differently */
/* to disable silent special case altogether, just uncomment this: */ /* to disable silent special case altogether, just uncomment this: */
/* jb->info.silence = 0; */ /* jb->info.silence_begin_ts = 0; */
frame = queue_get(jb, now - jb->info.current); frame = queue_get(jb, now - jb->info.current);
if (!frame) { if (!frame) {
return JB_NOFRAME; return JB_NOFRAME;
} else if (frame->type != JB_TYPE_VOICE) {
/* normal case; in silent mode, got a non-voice frame */
*frameout = *frame;
return JB_OK;
} }
if (frame && frame->type == JB_TYPE_VOICE) { if (frame->ts < jb->info.silence_begin_ts) {
/* voice frame is late */
*frameout = *frame;
/* rewind last_voice, since we're just dumping */
jb->info.last_voice_ts -= jb->info.last_voice_ms;
jb->info.frames_out++;
decrement_losspct(jb);
jb->info.frames_late++;
jb->info.frames_lost--;
jb_dbg("l");
/*jb_warn("\nlate: wanted=%ld, this=%ld, next=%ld\n", jb->info.last_voice_ts - jb->info.current, frame->ts, queue_next(jb));
jb_warninfo(jb); */
return JB_DROP;
} else {
/* voice frame */
/* try setting current to target right away here */ /* try setting current to target right away here */
jb->info.current = jb->info.target; jb->info.current = jb->info.target;
jb->info.silence = 0; jb->info.silence_begin_ts = 0;
jb->info.last_voice_ts = frame->ts + jb->info.current + frame->ms; jb->info.last_voice_ts = frame->ts + jb->info.current + frame->ms;
jb->info.last_voice_ms = frame->ms; jb->info.last_voice_ms = frame->ms;
*frameout = *frame; *frameout = *frame;
jb_dbg("V"); jb_dbg("V");
return JB_OK; return JB_OK;
} }
/* normal case; in silent mode, got a non-voice frame */
*frameout = *frame;
return JB_OK;
} }
} }
long jb_next(jitterbuf *jb) long jb_next(jitterbuf *jb)
{ {
if (jb->info.silence) { if (jb->info.silence_begin_ts) {
long next = queue_next(jb); long next = queue_next(jb);
if (next > 0) { if (next > 0) {
history_get(jb); history_get(jb);
......
...@@ -65,7 +65,7 @@ typedef struct jb_info { ...@@ -65,7 +65,7 @@ typedef struct jb_info {
long losspct; /* recent lost frame percentage (* 1000) */ long losspct; /* recent lost frame percentage (* 1000) */
long last_voice_ts; /* the last ts that was read from the jb - in receiver's time */ long last_voice_ts; /* the last ts that was read from the jb - in receiver's time */
long last_voice_ms; /* the duration of the last voice frame */ long last_voice_ms; /* the duration of the last voice frame */
long silence; /* we are presently playing out silence */ long silence_begin_ts; /* the time of the last CNG frame, when in silence */
long last_adjustment; /* the time of the last adjustment */ long last_adjustment; /* the time of the last adjustment */
/* settings */ /* settings */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment