Update of /usr/cvsroot/asterisk
In directory mongoose.digium.com:/tmp/cvs-serv18412

Modified Files:
        jitterbuf.c jitterbuf.h 
Log Message:
fixes for the new jitter buffer (bug #4249)


Index: jitterbuf.c
===================================================================
RCS file: /usr/cvsroot/asterisk/jitterbuf.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- jitterbuf.c 9 May 2005 14:24:58 -0000       1.8
+++ jitterbuf.c 12 May 2005 19:01:03 -0000      1.9
@@ -359,7 +359,7 @@
 
        /*jb_warn("queue_get: ASK %ld FIRST %ld\n", ts, frame->ts); */
 
-       if (all || ts > frame->ts) {
+       if (all || ts >= frame->ts) {
                /* remove this frame */
                frame->prev->next = frame->next;
                frame->next->prev = frame->prev;
@@ -414,7 +414,7 @@
        jb_dbg("jb info: queue %d -> %d.  last_ts %d (queue len: %d) last_ms 
%d\n",
                queue_next(jb), 
                queue_last(jb),
-               jb->info.last_voice_ts, 
+               jb->info.next_voice_ts, 
                queue_last(jb) - queue_next(jb),
                jb->info.last_voice_ms);
 }
@@ -478,7 +478,7 @@
 }
 
 
-static int _jb_get(jitterbuf *jb, jb_frame *frameout, long now) 
+static int _jb_get(jitterbuf *jb, jb_frame *frameout, long now, long interpl) 
 {
        jb_frame *frame;
        long diff;
@@ -494,7 +494,7 @@
        /* if a hard clamp was requested, use it */
        if ((jb->info.max_jitterbuf) && ((jb->info.target - jb->info.min) > 
jb->info.max_jitterbuf)) {
                jb_dbg("clamping target from %d to %d\n", (jb->info.target - 
jb->info.min), jb->info.max_jitterbuf);
-                       jb->info.target = jb->info.min + jb->info.max_jitterbuf;
+               jb->info.target = jb->info.min + jb->info.max_jitterbuf;
        }
 
        diff = jb->info.target - jb->info.current;
@@ -502,9 +502,6 @@
        /* jb_warn("diff = %d lms=%d last = %d now = %d\n", diff,  */
        /*      jb->info.last_voice_ms, jb->info.last_adjustment, now); */
 
-       /* move up last_voice_ts; it is now the expected voice ts */
-       jb->info.last_voice_ts += jb->info.last_voice_ms;
-
        /* let's work on non-silent case first */
        if (!jb->info.silence_begin_ts) { 
                /* we want to grow */
@@ -513,20 +510,19 @@
                        (((jb->info.last_adjustment + JB_ADJUST_DELAY) < now) 
|| 
                        /* we need to grow more than the "length" we have left 
*/
                        (diff > queue_last(jb)  - queue_next(jb)) ) ) {
-                       
-                       jb->info.current += jb->info.last_voice_ms;
+                       /* grow by interp frame length */
+                       jb->info.current += interpl;
+                       jb->info.next_voice_ts += interpl;
+                       jb->info.last_voice_ms = interpl;
                        jb->info.last_adjustment = now;
                        jb_dbg("G");
                        return JB_INTERP;
                }
 
-               frame = queue_get(jb, jb->info.last_voice_ts - 
jb->info.current);
+               frame = queue_get(jb, jb->info.next_voice_ts - 
jb->info.current);
 
                /* not a voice frame; just return it. */
                if (frame && frame->type != JB_TYPE_VOICE) {
-                       /* rewind last_voice_ts, since this isn't voice */
-                       jb->info.last_voice_ts -= jb->info.last_voice_ms;
-
                        if (frame->type == JB_TYPE_SILENCE) 
                                jb->info.silence_begin_ts = frame->ts;
 
@@ -537,19 +533,30 @@
                }
 
 
-               /* voice frame is late */
-               if (frame && frame->ts + jb->info.current < 
jb->info.last_voice_ts - jb->info.last_voice_ms ) {
-                       *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;
+               /* voice frame is later than expected */
+               if (frame && frame->ts + jb->info.current < 
jb->info.next_voice_ts) {
+                       if (frame->ts + jb->info.current > 
jb->info.next_voice_ts - jb->info.last_voice_ms) {
+                               /* either we interpolated past this frame in 
the last jb_get */
+                               /* or the frame is still in order, but came a 
little too quick */ 
+                               *frameout = *frame;
+                               /* reset expectation for next frame */
+                               jb->info.next_voice_ts = frame->ts + 
jb->info.current + frame->ms;
+                               jb->info.frames_out++;
+                               decrement_losspct(jb);
+                               jb_dbg("v");
+                               return JB_OK;
+                       } else {
+                               /* voice frame is late */
+                               *frameout = *frame;
+                               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.next_voice_ts - jb->info.current, frame->ts, 
queue_next(jb));
+                               jb_warninfo(jb); */
+                               return JB_DROP;
+                       }
                }
 
                /* keep track of frame sizes, to allow for variable 
sized-frames */
@@ -562,22 +569,24 @@
                /* every 80ms (though perhaps we can shrink even faster */
                /* in this case) */
                if (diff < -JB_TARGET_EXTRA && 
-               ((!frame && jb->info.last_adjustment + 80 < now) || 
+                       ((!frame && jb->info.last_adjustment + 80 < now) || 
                        (jb->info.last_adjustment + 500 < now))) {
 
-                       /* don't increment last_ts ?? */
-                       jb->info.last_voice_ts -= jb->info.last_voice_ms;
-                       jb->info.current -= jb->info.last_voice_ms;
                        jb->info.last_adjustment = now;
 
                        if (frame) {
                                *frameout = *frame;
+                               /* shrink by frame size we're throwing out */
+                               jb->info.current -= frame->ms;
                                jb->info.frames_out++;
                                decrement_losspct(jb);
                                jb->info.frames_dropped++;
                                jb_dbg("s");
                                return JB_DROP;
                        } else {
+                               /* shrink by last_voice_ms */
+                               jb->info.current -= jb->info.last_voice_ms;
+                               jb->info.frames_lost++;
                                increment_losspct(jb);
                                jb_dbg("S");
                                return JB_NOFRAME;
@@ -609,12 +618,15 @@
                        } */
                        jb->info.frames_lost++;
                        increment_losspct(jb);
+                       jb->info.next_voice_ts += interpl;
+                       jb->info.last_voice_ms = interpl;
                        jb_dbg("L");
                        return JB_INTERP;
                }
 
                /* normal case; return the frame, increment stuff */
                *frameout = *frame;
+               jb->info.next_voice_ts += frame->ms;
                jb->info.frames_out++;
                decrement_losspct(jb);
                jb_dbg("v");
@@ -622,30 +634,36 @@
        } else {     
                /* TODO: after we get the non-silent case down, we'll make the
                 * silent case -- basically, we'll just grow and shrink faster
-                * here, plus handle last_voice_ts a bit differently */
+                * here, plus handle next_voice_ts a bit differently */
       
                /* to disable silent special case altogether, just uncomment 
this: */
                /* jb->info.silence_begin_ts = 0; */
 
+               /* shrink interpl len every 10ms during silence */
+               if (diff < -JB_TARGET_EXTRA &&
+                       jb->info.last_adjustment + 10 <= now) {
+                       jb->info.current -= interpl;
+                       jb->info.last_adjustment = now;
+               }
+
                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;
+                       jb->info.frames_out++;
                        return JB_OK;
                }
                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_warn("\nlate: wanted=%ld, this=%ld, next=%ld\n", 
jb->info.next_voice_ts - jb->info.current, frame->ts, queue_next(jb));
                        jb_warninfo(jb); */
                        return JB_DROP;
                } else {
@@ -653,8 +671,10 @@
                        /* try setting current to target right away here */
                        jb->info.current = jb->info.target;
                        jb->info.silence_begin_ts = 0;
-                       jb->info.last_voice_ts = frame->ts + jb->info.current + 
frame->ms;
+                       jb->info.next_voice_ts = frame->ts + jb->info.current + 
frame->ms;
                        jb->info.last_voice_ms = frame->ms;
+                       jb->info.frames_out++;
+                       decrement_losspct(jb);
                        *frameout = *frame;
                        jb_dbg("V");
                        return JB_OK;
@@ -668,18 +688,21 @@
                long next = queue_next(jb);
                if (next > 0) { 
                        history_get(jb);
+                       /* shrink during silence */
+                       if (jb->info.target - jb->info.current < 
-JB_TARGET_EXTRA)
+                               return jb->info.last_adjustment + 10;
                        return next + jb->info.target;
                }
                else 
                        return JB_LONGMAX;
        } else {
-               return jb->info.last_voice_ts + jb->info.last_voice_ms;
+               return jb->info.next_voice_ts;
        }
 }
 
-int jb_get(jitterbuf *jb, jb_frame *frameout, long now) 
+int jb_get(jitterbuf *jb, jb_frame *frameout, long now, long interpl) 
 {
-       int ret = _jb_get(jb,frameout,now);
+       int ret = _jb_get(jb,frameout,now,interpl);
 #if 0
        static int lastts=0;
        int thists = ((ret == JB_OK) || (ret == JB_DROP)) ? frameout->ts : 0;

Index: jitterbuf.h
===================================================================
RCS file: /usr/cvsroot/asterisk/jitterbuf.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- jitterbuf.h 9 May 2005 14:24:58 -0000       1.3
+++ jitterbuf.h 12 May 2005 19:01:03 -0000      1.4
@@ -63,7 +63,7 @@
        long current;           /* the present jitterbuffer adjustment */
        long target;            /* the target jitterbuffer adjustment */
        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 next_voice_ts;     /* the ts of the next frame to be read from the 
jb - in receiver's time */
        long last_voice_ms;     /* the duration of the last voice frame */
        long silence_begin_ts;  /* the time of the last CNG frame, when in 
silence */
        long last_adjustment;   /* the time of the last adjustment */
@@ -115,10 +115,10 @@
  * JB_OK:  You've got frame!
  * JB_DROP: Here's an audio frame you should just drop.  Ask me again for this 
time..
  * JB_NOFRAME: There's no frame scheduled for this time.
- * JB_INTERP: Please interpolate an audio frame for this time (either we need 
to grow, or there was a lost frame 
+ * JB_INTERP: Please interpolate an interpl-length frame for this time (either 
we need to grow, or there was a lost frame) 
  * JB_EMPTY: The jb is empty.
  */
-int                    jb_get(jitterbuf *jb, jb_frame *frame, long now);
+int                    jb_get(jitterbuf *jb, jb_frame *frame, long now, long 
interpl);
 
 /* unconditionally get frames from jitterbuf until empty */
 int jb_getall(jitterbuf *jb, jb_frame *frameout);

_______________________________________________
Asterisk-Cvs mailing list
[email protected]
http://lists.digium.com/mailman/listinfo/asterisk-cvs

Reply via email to