Fix jitter issues with out-of-order audio (bug #4163)
authorMark Spencer <markster@digium.com>
Mon, 9 May 2005 14:24:58 +0000 (14:24 +0000)
committerMark Spencer <markster@digium.com>
Mon, 9 May 2005 14:24:58 +0000 (14:24 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@5612 65c4cc65-6c06-0410-ace0-fbb531ad65f3

jitterbuf.c
jitterbuf.h

index e319776..2c31007 100755 (executable)
@@ -58,7 +58,7 @@ void jb_reset(jitterbuf *jb)
 
        /* initialize length */
        jb->info.current = jb->info.target = 0; 
-       jb->info.silence = 1; 
+       jb->info.silence_begin_ts = -1; 
 }
 
 jitterbuf * jb_new() 
@@ -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_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);
        if (jb->info.frames_in > 0) 
                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)
        jb->info.last_voice_ts += jb->info.last_voice_ms;
 
        /* let's work on non-silent case first */
-       if (!jb->info.silence) { 
+       if (!jb->info.silence_begin_ts) { 
                /* we want to grow */
                if ((diff > 0) && 
                        /* we haven't grown in the delay length */
@@ -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;
 
                        if (frame->type == JB_TYPE_SILENCE) 
-                               jb->info.silence = 1;
+                               jb->info.silence_begin_ts = frame->ts;
 
                        *frameout = *frame;
                        jb->info.frames_out++;
@@ -625,31 +625,46 @@ static int _jb_get(jitterbuf *jb, jb_frame *frameout, long now)
                 * here, plus handle last_voice_ts a bit differently */
       
                /* 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);
                if (!frame) {
                        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 */
                        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_ms = frame->ms;
                        *frameout = *frame;
                        jb_dbg("V");
                        return JB_OK;
                }
-               /* normal case; in silent mode, got a non-voice frame */
-               *frameout = *frame;
-               return JB_OK;
        }
 }
 
 long jb_next(jitterbuf *jb) 
 {
-       if (jb->info.silence) {
+       if (jb->info.silence_begin_ts) {
                long next = queue_next(jb);
                if (next > 0) { 
                        history_get(jb);
index aa73e80..2247516 100755 (executable)
@@ -65,7 +65,7 @@ typedef struct jb_info {
        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_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 */
 
        /* settings */