Implemented the old (speex-dependent) jitter buffer using the new (general)
authorjm <jm@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Wed, 22 Mar 2006 07:31:43 +0000 (07:31 +0000)
committerjm <jm@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Wed, 22 Mar 2006 07:31:43 +0000 (07:31 +0000)
one. Probably broke things in the process.

git-svn-id: http://svn.xiph.org/trunk/speex@11048 0101bb08-14d6-0310-b084-bc0e0c8e3800

include/speex/speex_jitter.h
libspeex/jitter.c

index 2162ccc..3f4f48a 100644 (file)
@@ -71,6 +71,9 @@ int jitter_buffer_get(JitterBuffer *jitter, char *out, int *length, int *current
 /** Get pointer timestamp of jitter buffer */
 int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter);
 
+/** Advance by one tick */
+void jitter_buffer_tick(JitterBuffer *jitter);
+
 
 #define SPEEX_JITTER_MAX_PACKET_SIZE 1500 /**< Maximum number of bytes per packet         */
 #define SPEEX_JITTER_MAX_BUFFER_SIZE 20   /**< Maximum number of packets in jitter buffer */
@@ -79,25 +82,11 @@ int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter);
 
 /** Speex jitter-buffer state. */
 typedef struct SpeexJitter {
-   int buffer_size;                                                       /**< Buffer size                         */
-   int pointer_timestamp;                                                 /**< Pointer timestamp                   */
-
    SpeexBits current_packet;                                              /**< Current Speex packet                */
    int valid_bits;                                                        /**< True if Speex bits are valid        */
-
-   char buf[SPEEX_JITTER_MAX_BUFFER_SIZE][SPEEX_JITTER_MAX_PACKET_SIZE];  /**< Buffer of packets                   */
-   int timestamp[SPEEX_JITTER_MAX_BUFFER_SIZE];                           /**< Timestamp of packet                 */
-   int len[SPEEX_JITTER_MAX_BUFFER_SIZE];                                 /**< Number of bytes in packet           */
-
+   JitterBuffer *packets;
    void *dec;                                                             /**< Pointer to Speex decoder            */
    int frame_size;                                                        /**< Frame size of Speex decoder         */
-   int frame_time;                                                        /**< Frame time in [ms] of Speex decoder */
-   int reset_state;                                                       /**< True if Speex state was reset       */
-   
-   int lost_count;                                                        /**< Number of lost packets              */
-   float shortterm_margin[MAX_MARGIN];                                    /**< Short term margins                  */
-   float longterm_margin[MAX_MARGIN];                                     /**< Long term margins                   */
-   float loss_rate;                                                       /**< Loss rate                           */
 } SpeexJitter;
 
 /** Initialise jitter buffer */
index e55677d..7b9a59f 100644 (file)
@@ -303,54 +303,8 @@ int jitter_buffer_get(JitterBuffer *jitter, char *out, int *length, int *current
    if (current_timestamp)
       *current_timestamp = jitter->pointer_timestamp;
    *length = 0;
-   return;
+   return 1;
 
-#if 0
-   if (i==SPEEX_JITTER_MAX_BUFFER_SIZE)
-   {
-      /* No packet found */
-      if (jitter->valid_bits)
-      {
-         /* Try decoding last received packet */
-         ret = speex_decode_int(jitter->dec, &jitter->current_packet, out);
-         if (ret == 0)
-         {
-            jitter->lost_count = 0;
-            return;
-         } else {
-            jitter->valid_bits = 0;
-         }
-      }
-
-      /*fprintf (stderr, "lost/late frame %d\n", jitter->pointer_timestamp);*/
-      /*Packet is late or lost*/
-      speex_decode_int(jitter->dec, NULL, out);
-      jitter->lost_count++;
-      if (jitter->lost_count>=25)
-      {
-         jitter->lost_count = 0;
-         jitter->reset_state = 1;
-         speex_decoder_ctl(jitter->dec, SPEEX_RESET_STATE, NULL);
-      }
-      jitter->loss_rate = .999*jitter->loss_rate + .001;
-   } else {
-      jitter->lost_count = 0;
-      /* Found the right packet */
-      speex_bits_read_from(&jitter->current_packet, jitter->buf[i], jitter->len[i]);
-      jitter->len[i]=-1;
-      /* Decode packet */
-      ret = speex_decode_int(jitter->dec, &jitter->current_packet, out);
-      if (ret == 0)
-      {
-         jitter->valid_bits = 1;
-      } else {
-         /* Error while decoding */
-         for (i=0;i<jitter->frame_size;i++)
-            out[i]=0;
-      }
-      jitter->loss_rate = .999*jitter->loss_rate;
-   }
-#endif
 }
 
 /** Get pointer timestamp of jitter buffer */
@@ -359,7 +313,10 @@ int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter)
    return jitter->pointer_timestamp;
 }
 
-
+void jitter_buffer_tick(JitterBuffer *jitter)
+{
+   jitter->pointer_timestamp += jitter->tick_size;
+}
 
 
 
@@ -368,249 +325,60 @@ int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter)
 void speex_jitter_init(SpeexJitter *jitter, void *decoder, int sampling_rate)
 {
    int i;
-   for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
-   {
-      jitter->len[i]=-1;
-      jitter->timestamp[i]=-1;
-   }
-
+   
    jitter->dec = decoder;
    speex_decoder_ctl(decoder, SPEEX_GET_FRAME_SIZE, &jitter->frame_size);
-   jitter->frame_time = jitter->frame_size;
+
+   jitter->packets = jitter_buffer_init(jitter->frame_size);
 
    speex_bits_init(&jitter->current_packet);
    jitter->valid_bits = 0;
 
-   jitter->buffer_size = 4;
-
-   jitter->pointer_timestamp = -jitter->frame_time * jitter->buffer_size;
-   jitter->reset_state = 1;
-   jitter->lost_count = 0;
-   jitter->loss_rate = 0;
 }
 
 void speex_jitter_destroy(SpeexJitter *jitter)
 {
+   jitter_buffer_destroy(jitter->packets);
    speex_bits_destroy(&jitter->current_packet);
 }
 
 
 void speex_jitter_put(SpeexJitter *jitter, char *packet, int len, int timestamp)
 {
-   int i,j;
-   int arrival_margin;
-
-   if (jitter->reset_state)
-   {
-      jitter->reset_state=0;
-      jitter->pointer_timestamp = timestamp-jitter->frame_time * jitter->buffer_size;
-      for (i=0;i<MAX_MARGIN;i++)
-      {
-         jitter->shortterm_margin[i] = 0;
-         jitter->longterm_margin[i] = 0;
-      }
-      for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
-      {
-         jitter->len[i]=-1;
-         jitter->timestamp[i]=-1;
-      }
-      fprintf(stderr, "reset to %d\n", timestamp);
-   }
-   
-   /* Cleanup buffer (remove old packets that weren't played) */
-   for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
-   {
-      if (jitter->timestamp[i]<jitter->pointer_timestamp)
-      {
-         jitter->len[i]=-1;
-         /*if (jitter->timestamp[i] != -1)
-            fprintf (stderr, "discarding %d %d\n", jitter->timestamp[i], jitter->pointer_timestamp);*/
-      }
-   }
-
-   /*Find an empty slot in the buffer*/
-   for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
-   {
-      if (jitter->len[i]==-1)
-         break;
-   }
-
-   /*fprintf(stderr, "%d %d %f\n", timestamp, jitter->pointer_timestamp, jitter->drift_average);*/
-   if (i==SPEEX_JITTER_MAX_BUFFER_SIZE)
-   {
-      int earliest=jitter->timestamp[0];
-      i=0;
-      for (j=1;j<SPEEX_JITTER_MAX_BUFFER_SIZE;j++)
-      {
-         if (jitter->timestamp[j]<earliest)
-         {
-            earliest = jitter->timestamp[j];
-            i=j;
-         }
-      }
-      /*fprintf (stderr, "Buffer is full, discarding earliest frame %d (currently at %d)\n", timestamp, jitter->pointer_timestamp);*/
-      /*No place left in the buffer*/
-      
-      /*skip some frame(s) */
-      /*return;*/
-   }
-   
-   /* Copy packet in buffer */
-   if (len>SPEEX_JITTER_MAX_PACKET_SIZE)
-      len=SPEEX_JITTER_MAX_PACKET_SIZE;
-   for (j=0;j<len/BYTES_PER_CHAR;j++)
-      jitter->buf[i][j]=packet[j];
-   jitter->timestamp[i]=timestamp;
-   jitter->len[i]=len;
-   
-   /* Don't count late packets when adjusting the synchro (we're taking care of them elsewhere) */
-   /*if (timestamp <= jitter->pointer_timestamp)
-   {
-      fprintf (stderr, "frame for timestamp %d arrived too late (at time %d)\n", timestamp, jitter->pointer_timestamp);
-   }*/
-
-   /* Adjust the buffer size depending on network conditions */
-   arrival_margin = (timestamp - jitter->pointer_timestamp - jitter->frame_time);
-   
-   if (arrival_margin >= -LATE_BINS*jitter->frame_time)
-   {
-      int int_margin;
-      for (i=0;i<MAX_MARGIN;i++)
-      {
-         jitter->shortterm_margin[i] *= .98;
-         jitter->longterm_margin[i] *= .995;
-      }
-      int_margin = (arrival_margin + LATE_BINS*jitter->frame_time)/jitter->frame_time;
-      if (int_margin>MAX_MARGIN-1)
-         int_margin = MAX_MARGIN-1;
-      if (int_margin>=0)
-      {
-         jitter->shortterm_margin[int_margin] += .02;
-         jitter->longterm_margin[int_margin] += .005;
-      }
-   }
-   
-   /*fprintf (stderr, "margin : %d %d %f %f %f %f\n", arrival_margin, jitter->buffer_size, 100*jitter->loss_rate, 100*jitter->late_ratio, 100*jitter->ontime_ratio, 100*jitter->early_ratio);*/
+   jitter_buffer_put(jitter->packets, packet, len, timestamp, jitter->frame_size);
 }
 
 void speex_jitter_get(SpeexJitter *jitter, short *out, int *current_timestamp)
 {
    int i;
    int ret;
-   float late_ratio_short;
-   float late_ratio_long;
-   float ontime_ratio_short;
-   float ontime_ratio_long;
-   float early_ratio_short;
-   float early_ratio_long;
-   
-   late_ratio_short = 0;
-   late_ratio_long = 0;
-   for (i=0;i<LATE_BINS;i++)
-   {
-      late_ratio_short += jitter->shortterm_margin[i];
-      late_ratio_long += jitter->longterm_margin[i];
-   }
-   ontime_ratio_short = jitter->shortterm_margin[LATE_BINS];
-   ontime_ratio_long = jitter->longterm_margin[LATE_BINS];
-   early_ratio_short = early_ratio_long = 0;
-   for (i=LATE_BINS+1;i<MAX_MARGIN;i++)
-   {
-      early_ratio_short += jitter->shortterm_margin[i];
-      early_ratio_long += jitter->longterm_margin[i];
-   }
-   if (0&&jitter->pointer_timestamp%1000==0)
-   {
-      fprintf (stderr, "%f %f %f %f %f %f\n", early_ratio_short, early_ratio_long, ontime_ratio_short, ontime_ratio_long, late_ratio_short, late_ratio_long);
-      /*fprintf (stderr, "%f %f\n", early_ratio_short + ontime_ratio_short + late_ratio_short, early_ratio_long + ontime_ratio_long + late_ratio_long);*/
-   }
+   char packet[2048];
+   int length = 2048;
    
-   if (late_ratio_short > .1 || late_ratio_long > .03)
+   if (jitter->valid_bits)
    {
-      jitter->shortterm_margin[MAX_MARGIN-1] += jitter->shortterm_margin[MAX_MARGIN-2];
-      jitter->longterm_margin[MAX_MARGIN-1] += jitter->longterm_margin[MAX_MARGIN-2];
-      for (i=MAX_MARGIN-3;i>=0;i--)
-      {
-         jitter->shortterm_margin[i+1] = jitter->shortterm_margin[i];
-         jitter->longterm_margin[i+1] = jitter->longterm_margin[i];         
-      }
-      jitter->shortterm_margin[0] = 0;
-      jitter->longterm_margin[0] = 0;            
-      /*fprintf (stderr, "interpolate frame\n");*/
-      speex_decode_int(jitter->dec, NULL, out);
-      if (current_timestamp)
-         *current_timestamp = jitter->pointer_timestamp;
-      return;
-   }
-   
-   /* Increment timestamp */
-   jitter->pointer_timestamp += jitter->frame_time;
-   
-   if (late_ratio_short + ontime_ratio_short < .005 && late_ratio_long + ontime_ratio_long < .01 && early_ratio_short > .8)
-   {
-      jitter->shortterm_margin[0] += jitter->shortterm_margin[1];
-      jitter->longterm_margin[0] += jitter->longterm_margin[1];
-      for (i=1;i<MAX_MARGIN-1;i++)
+      /* Try decoding last received packet */
+      ret = speex_decode_int(jitter->dec, &jitter->current_packet, out);
+      if (ret == 0)
       {
-         jitter->shortterm_margin[i] = jitter->shortterm_margin[i+1];
-         jitter->longterm_margin[i] = jitter->longterm_margin[i+1];         
+         jitter_buffer_tick(jitter->packets);
+         return;
+      } else {
+         jitter->valid_bits = 0;
       }
-      jitter->shortterm_margin[MAX_MARGIN-1] = 0;
-      jitter->longterm_margin[MAX_MARGIN-1] = 0;      
-      /*fprintf (stderr, "drop frame\n");*/
-      jitter->pointer_timestamp += jitter->frame_time;
    }
 
-   if (current_timestamp)
-      *current_timestamp = jitter->pointer_timestamp;
-
-   /* Send zeros while we fill in the buffer */
-   if (jitter->pointer_timestamp<0)
-   {
-      for (i=0;i<jitter->frame_size;i++)
-         out[i]=0;
-      return;
-   }
+   ret = jitter_buffer_get(jitter->packets, packet, &length, current_timestamp);
    
-   /* Search the buffer for a packet with the right timestamp */
-   for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
-   {
-      if (jitter->len[i]!=-1 && jitter->timestamp[i]==jitter->pointer_timestamp)
-         break;
-   }
-   
-   if (i==SPEEX_JITTER_MAX_BUFFER_SIZE)
+   if (ret != 0)
    {
       /* No packet found */
-      if (jitter->valid_bits)
-      {
-         /* Try decoding last received packet */
-         ret = speex_decode_int(jitter->dec, &jitter->current_packet, out);
-         if (ret == 0)
-         {
-            jitter->lost_count = 0;
-            return;
-         } else {
-            jitter->valid_bits = 0;
-         }
-      }
 
       /*fprintf (stderr, "lost/late frame %d\n", jitter->pointer_timestamp);*/
       /*Packet is late or lost*/
       speex_decode_int(jitter->dec, NULL, out);
-      jitter->lost_count++;
-      if (jitter->lost_count>=25)
-      {
-         jitter->lost_count = 0;
-         jitter->reset_state = 1;
-         speex_decoder_ctl(jitter->dec, SPEEX_RESET_STATE, NULL);
-      }
-      jitter->loss_rate = .999*jitter->loss_rate + .001;
    } else {
-      jitter->lost_count = 0;
-      /* Found the right packet */
-      speex_bits_read_from(&jitter->current_packet, jitter->buf[i], jitter->len[i]);
-      jitter->len[i]=-1;
+      speex_bits_read_from(&jitter->current_packet, packet, length);
       /* Decode packet */
       ret = speex_decode_int(jitter->dec, &jitter->current_packet, out);
       if (ret == 0)
@@ -621,13 +389,10 @@ void speex_jitter_get(SpeexJitter *jitter, short *out, int *current_timestamp)
          for (i=0;i<jitter->frame_size;i++)
             out[i]=0;
       }
-      jitter->loss_rate = .999*jitter->loss_rate;
    }
-
-
 }
 
 int speex_jitter_get_pointer_timestamp(SpeexJitter *jitter)
 {
-   return jitter->pointer_timestamp;
+   return jitter_buffer_get_pointer_timestamp(jitter->packets);
 }