[xiph-commits] r14139 - in trunk/speex: include/speex libspeex

jm at svn.xiph.org jm at svn.xiph.org
Wed Nov 14 18:08:33 PST 2007


Author: jm
Date: 2007-11-14 18:08:32 -0800 (Wed, 14 Nov 2007)
New Revision: 14139

Modified:
   trunk/speex/include/speex/speex_jitter.h
   trunk/speex/libspeex/jitter.c
Log:
jitter buffer: Some tuning to new algo (not enabled yet)


Modified: trunk/speex/include/speex/speex_jitter.h
===================================================================
--- trunk/speex/include/speex/speex_jitter.h	2007-11-15 01:01:54 UTC (rev 14138)
+++ trunk/speex/include/speex/speex_jitter.h	2007-11-15 02:08:32 UTC (rev 14139)
@@ -98,7 +98,16 @@
 /**  */
 #define JITTER_BUFFER_GET_DELAY_STEP 7
 
+#define JITTER_BUFFER_SET_LOSS_SIZE 8
+#define JITTER_BUFFER_GET_LOSS_SIZE 9
 
+#define JITTER_BUFFER_SET_MAX_LATE_RATE 10
+#define JITTER_BUFFER_GET_MAX_LATE_RATE 11
+
+#define JITTER_BUFFER_SET_LATE_COST 12
+#define JITTER_BUFFER_GET_LATE_COST 13
+
+
 #define JITTER_BUFFER_ADJUST_INTERPOLATE -1
 #define JITTER_BUFFER_ADJUST_OK 0
 #define JITTER_BUFFER_ADJUST_DROP 1

Modified: trunk/speex/libspeex/jitter.c
===================================================================
--- trunk/speex/libspeex/jitter.c	2007-11-15 01:01:54 UTC (rev 14138)
+++ trunk/speex/libspeex/jitter.c	2007-11-15 02:08:32 UTC (rev 14139)
@@ -76,8 +76,7 @@
 
 #define MAX_TIMINGS 20
 #define MAX_BUFFERS 3
-#define TOP_DELAY 25
-#define WINDOW_SIZE 200
+#define TOP_DELAY 12
 
 struct TimingBuffer {
    int filled;
@@ -111,7 +110,7 @@
    
    /*fprintf(stderr, "pos = %d filled = %d\n", pos, tb->filled);*/
    speex_assert(pos <= tb->filled && pos < MAX_TIMINGS);
-   fprintf(stderr, "OK\n");
+   /*fprintf(stderr, "OK\n");*/
    if (pos < tb->filled)
    {
       int move_size = tb->filled-pos;
@@ -142,14 +141,24 @@
    @param tb Array of buffers
    @param late_factor Equivalent cost of a late frame (in timestamp units) 
 */
-static spx_int16_t tbs_get_opt_delay(struct TimingBuffer *tb, spx_int32_t late_factor)
+static spx_int16_t tbs_get_opt_delay(struct TimingBuffer *tb, spx_int32_t latency_tradeoff)
 {
    int i;
    spx_int16_t opt=0;
    spx_int32_t best_cost=0x7fffffff;
    int late = 0;
    int pos[MAX_BUFFERS];
+   int tot_count;
+   float late_factor;
+   int penalty_taken = 0;
    
+   tot_count = 0;
+   for (i=0;i<MAX_BUFFERS;i++)
+      tot_count += tb[i].curr_count;
+   if (tot_count==0)
+      return 0;
+   late_factor = latency_tradeoff * 100.0f / tot_count;
+   
    /*fprintf(stderr, "tbs_get_opt_delay\n");*/
    for (i=0;i<MAX_BUFFERS;i++)
       pos[i] = 0;
@@ -167,14 +176,10 @@
             latest = tb[j].timing[pos[j]];
          }
       }
-      late++;
       if (next != -1)
       {
          spx_int32_t cost;
          pos[next]++;
-         /* When considering reducing delay, "on-time" frames could twice (this provides hysteresis) */
-         if (latest > 0)
-            late++;
          cost = -latest + late_factor*late;
          /*fprintf(stderr, "cost %d = -%d + %d * %d\n", cost, latest, late_factor, late);*/
          if (cost < best_cost)
@@ -185,31 +190,43 @@
       } else {
          break;
       }
+      
+      late++;
+      /* Two-frame penalty if we're going to increase the amount of late frames */
+      if (latest >= 0 && !penalty_taken)
+      {
+         penalty_taken = 1;
+         late+=2;
+      }
    }
    return opt;
 }
 
 /** Jitter buffer structure */
 struct JitterBuffer_ {
-   spx_uint32_t pointer_timestamp;                                        /**< Timestamp of what we will *get* next */
+   spx_uint32_t pointer_timestamp;                             /**< Timestamp of what we will *get* next */
    spx_uint32_t last_returned_timestamp;
    spx_uint32_t next_stop;
    
-   JitterBufferPacket packets[SPEEX_JITTER_MAX_BUFFER_SIZE];              /**< Packets stored in the buffer */
-   spx_uint32_t arrival[SPEEX_JITTER_MAX_BUFFER_SIZE];                    /**< Packet arrival time (0 means it was late, even though it's a valid timestamp) */
+   JitterBufferPacket packets[SPEEX_JITTER_MAX_BUFFER_SIZE];   /**< Packets stored in the buffer */
+   spx_uint32_t arrival[SPEEX_JITTER_MAX_BUFFER_SIZE];         /**< Packet arrival time (0 means it was late, even though it's a valid timestamp) */
    
-   void (*destroy) (void *);                                              /**< Callback for destroying a packet */
+   void (*destroy) (void *);                                   /**< Callback for destroying a packet */
 
-   int resolution;                                                        /**< Time resolution for histogram (timestamp units) */
-   int delay_step;                                                        /**< Size of the steps when adjusting buffering (timestamp units) */
-   int res_delay_step;                                                    /**< Size of the steps when adjusting buffering (resolution units) */
-   int reset_state;                                                       /**< True if state was just reset        */
-   int buffer_margin;                                                     /**< How many frames we want to keep in the buffer (lower bound) */
-   int late_cutoff;                                                       /**< How late must a packet be for it not to be considered at all */
-   int interp_requested;                                                  /**< An interpolation is requested by speex_jitter_update_delay() */
+   int resolution;                                             /**< Time resolution for histogram (timestamp units) */
+   int delay_step;                                             /**< Size of the steps when adjusting buffering (timestamp units) */
+   int res_delay_step;                                         /**< Size of the steps when adjusting buffering (resolution units) */
+   int reset_state;                                            /**< True if state was just reset        */
+   int buffer_margin;                                          /**< How many frames we want to keep in the buffer (lower bound) */
+   int late_cutoff;                                            /**< How late must a packet be for it not to be considered at all */
+   int interp_requested;                                       /**< An interpolation is requested by speex_jitter_update_delay() */
 
-   struct TimingBuffer _tb[MAX_BUFFERS];                                  /**< Don't use those directly */
-   struct TimingBuffer *timeBuffers[MAX_BUFFERS];                       /**< Storing arrival time of latest frames so we can compute some stats */
+   struct TimingBuffer _tb[MAX_BUFFERS];                       /**< Don't use those directly */
+   struct TimingBuffer *timeBuffers[MAX_BUFFERS];              /**< Storing arrival time of latest frames so we can compute some stats */
+   int window_size;                                            /**< Total window over which the late frames are counted */
+   int subwindow_size;                                         /**< Sub-window size for faster computation  */
+   int max_late_rate;                                          /**< Absolute maximum amount of late packets tolerable (in percent) */
+   int latency_tradeoff;                                       /**< Latency equivalent of losing one percent of packets */
    
    float late_ratio_short;
    float late_ratio_long;
@@ -218,10 +235,10 @@
    float early_ratio_short;
    float early_ratio_long;
 
-   int lost_count;                                                        /**< Number of consecutive lost packets  */
-   float shortterm_margin[MAX_MARGIN];                                    /**< Short term margin histogram         */
-   float longterm_margin[MAX_MARGIN];                                     /**< Long term margin histogram          */
-   float loss_rate;                                                       /**< Average loss rate                   */
+   int lost_count;                                             /**< Number of consecutive lost packets  */
+   float shortterm_margin[MAX_MARGIN];                         /**< Short term margin histogram         */
+   float longterm_margin[MAX_MARGIN];                          /**< Long term margin histogram          */
+   float loss_rate;                                            /**< Average loss rate                   */
 };
 
 /** Initialise jitter buffer */
@@ -231,15 +248,19 @@
    if (jitter)
    {
       int i;
+      spx_int32_t tmp;
       for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
          jitter->packets[i].data=NULL;
       jitter->resolution = resolution;
       jitter->delay_step = resolution;
       jitter->res_delay_step = 1;
       /*FIXME: Should this be 0 or 1?*/
-      jitter->buffer_margin = 1;
+      jitter->buffer_margin = 0;
       jitter->late_cutoff = 50;
       jitter->destroy = NULL;
+      jitter->latency_tradeoff = 8;
+      tmp = 2;
+      jitter_buffer_ctl(jitter, JITTER_BUFFER_SET_MAX_LATE_RATE, &tmp);
       jitter_buffer_reset(jitter);
    }
    return jitter;
@@ -293,7 +314,7 @@
       timing = -32767;
    if (timing > 32767)
       timing = 32767;
-   if (jitter->timeBuffers[0]->curr_count >= WINDOW_SIZE)
+   if (jitter->timeBuffers[0]->curr_count >= jitter->subwindow_size)
    {
       int i;
       /*fprintf(stderr, "Rotate buffer\n");*/
@@ -304,7 +325,7 @@
       tb_init(jitter->timeBuffers[0]);
    }
    tb_add(jitter->timeBuffers[0], timing);
-   spx_int16_t opt = tbs_get_opt_delay(jitter->_tb, 2);
+   spx_int16_t opt = tbs_get_opt_delay(jitter->_tb, jitter->latency_tradeoff);
    /*fprintf(stderr, "opt adjustment is %d\n", opt);*/
 }
 
@@ -463,7 +484,7 @@
       arrival_margin = (((spx_int32_t)packet->timestamp) - ((spx_int32_t)jitter->next_stop))/jitter->resolution - jitter->buffer_margin;
    
       /*fprintf(stderr, "put arrival_margin = %d\n", arrival_margin);*/
-      /*update_timings(jitter, ((spx_int32_t)packet->timestamp) - ((spx_int32_t)jitter->next_stop));*/
+      update_timings(jitter, ((spx_int32_t)packet->timestamp) - ((spx_int32_t)jitter->next_stop));
       update_histogram(jitter, arrival_margin);
       late = 1;
    } else {
@@ -631,7 +652,7 @@
    
          /*fprintf(stderr, "get arrival_margin = %d\n", arrival_margin);*/
          
-         /*update_timings(jitter, ((spx_int32_t)jitter->packets[i].timestamp) - ((spx_int32_t)jitter->arrival[i]));*/
+         update_timings(jitter, ((spx_int32_t)jitter->packets[i].timestamp) - ((spx_int32_t)jitter->arrival[i]));
 
          update_histogram(jitter, arrival_margin);
 
@@ -827,6 +848,24 @@
       case JITTER_BUFFER_GET_DELAY_STEP:
          *(spx_int32_t*)ptr = jitter->delay_step;
          break;
+      case JITTER_BUFFER_SET_LOSS_SIZE:
+         break;
+      case JITTER_BUFFER_GET_LOSS_SIZE:
+         break;
+      case JITTER_BUFFER_SET_MAX_LATE_RATE:
+         jitter->max_late_rate = *(spx_int32_t*)ptr;
+         jitter->window_size = 100*TOP_DELAY/jitter->max_late_rate;
+         jitter->subwindow_size = jitter->window_size/MAX_BUFFERS;
+         break;
+      case JITTER_BUFFER_GET_MAX_LATE_RATE:
+         *(spx_int32_t*)ptr = jitter->max_late_rate;
+         break;
+      case JITTER_BUFFER_SET_LATE_COST:
+         jitter->latency_tradeoff = *(spx_int32_t*)ptr;
+         break;
+      case JITTER_BUFFER_GET_LATE_COST:
+         *(spx_int32_t*)ptr = jitter->latency_tradeoff;
+         break;
       default:
          speex_warning_int("Unknown jitter_buffer_ctl request: ", request);
          return -1;



More information about the commits mailing list