/* Copyright (C) 2002 Jean-Marc Valin 
   File: speex_jitter.h

   Adaptive jitter buffer for Speex

   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions
   are met:
   
   - Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
   
   - Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.
   
   - Neither the name of the Xiph.org Foundation nor the names of its
   contributors may be used to endorse or promote products derived from
   this software without specific prior written permission.
   
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

/*
TODO:
- Add short-term estimate
- Defensive programming
  + warn when last returned < last desired (begative buffering)
  + warn if update_delay not called between get() and tick() or is called twice in a row
- Linked list structure for holding the packets instead of the current fixed-size array
  + return memory to a pool
  + allow pre-allocation of the pool
  + optional max number of elements
- Statistics
  + drift
  + loss
  + late
  + jitter
  + buffering delay
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif


#include "arch.h"
#include <speex/speex.h>
#include <speex/speex_bits.h>
#include <speex/speex_jitter.h>
#include "os_support.h"

#ifndef NULL
#define NULL 0
#endif

#define SPEEX_JITTER_MAX_BUFFER_SIZE 200   /**< Maximum number of packets in jitter buffer */

#define TSUB(a,b) ((spx_int32_t)((a)-(b)))

#define GT32(a,b) (((spx_int32_t)((a)-(b)))>0)
#define GE32(a,b) (((spx_int32_t)((a)-(b)))>=0)
#define LT32(a,b) (((spx_int32_t)((a)-(b)))<0)
#define LE32(a,b) (((spx_int32_t)((a)-(b)))<=0)

#define ROUND_DOWN(x, step) ((x)<0 ? ((x)-(step)+1)/(step)*(step) : (x)/(step)*(step)) 

#define MAX_TIMINGS 40
#define MAX_BUFFERS 3
#define TOP_DELAY 40

/** Buffer that keeps the time of arrival of the latest packets */
struct TimingBuffer {
   int filled;                         /**< Number of entries occupied in "timing" and "counts"*/
   int curr_count;                     /**< Number of packet timings we got (including those we discarded) */
   spx_int32_t timing[MAX_TIMINGS];    /**< Sorted list of all timings ("latest" packets first) */
   spx_int16_t counts[MAX_TIMINGS];    /**< Order the packets were put in (will be used for short-term estimate) */
};

static void tb_init(struct TimingBuffer *tb)
{
   tb->filled = 0;
   tb->curr_count = 0;
}

/* Add the timing of a new packet to the TimingBuffer */
static void tb_add(struct TimingBuffer *tb, spx_int16_t timing)
{
   int pos;
   /* Discard packet that won't make it into the list because they're too early */
   if (tb->filled >= MAX_TIMINGS && timing >= tb->timing[tb->filled-1])
   {
      tb->curr_count++;
      return;
   }
   
   /* Find where the timing info goes in the sorted list */
   pos = 0;
   /* FIXME: Do bisection instead of linear search */
   while (pos<tb->filled && timing >= tb->timing[pos])
   {
      pos++;
   }
   
   speex_assert(pos <= tb->filled && pos < MAX_TIMINGS);
   
   /* Shift everything so we can perform the insertion */
   if (pos < tb->filled)
   {
      int move_size = tb->filled-pos;
      if (tb->filled == MAX_TIMINGS)
         move_size -= 1;
      SPEEX_MOVE(&tb->timing[pos+1], &tb->timing[pos], move_size);
      SPEEX_MOVE(&tb->counts[pos+1], &tb->counts[pos], move_size);
   }
   /* Insert */
   tb->timing[pos] = timing;
   tb->counts[pos] = tb->curr_count;
   
   tb->curr_count++;
   if (tb->filled<MAX_TIMINGS)
      tb->filled++;
}



/** Jitter buffer structure */
struct JitterBuffer_ {
   spx_uint32_t pointer_timestamp;                             /**< Timestamp of what we will *get* next */
   spx_uint32_t last_returned_timestamp;                       /**< Useful for getting the next packet with the same timestamp (for fragmented media) */
   spx_uint32_t next_stop;                                     /**< Estimated time the next get() will be called */
   
   spx_int32_t buffered;                                       /**< Amount of data we think is still buffered by the application (timestamp units)*/
   
   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 */

   spx_int32_t delay_step;                                     /**< Size of the steps when adjusting buffering (timestamp units) */
   spx_int32_t concealment_size;                               /**< Size of the packet loss concealment "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 auto_adjust;                                            /**< Whether to automatically adjust the delay at any time */
   
   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 */
   int auto_tradeoff;                                          /**< Latency equivalent of losing one percent of packets (automatic default) */
   
   int lost_count;                                             /**< Number of consecutive lost packets  */
};

/** Based on available data, this computes the optimal delay for the jitter buffer. 
   The optimised function is in timestamp units and is:
   cost = delay + late_factor*[number of frames that would be late if we used that delay]
   @param tb Array of buffers
   @param late_factor Equivalent cost of a late frame (in timestamp units) 
 */
static spx_int16_t compute_opt_delay(JitterBuffer *jitter)
{
   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;
   int best = 0;
   int worst = 0;
   spx_int32_t deltaT;
   struct TimingBuffer *tb;
   
   tb = jitter->_tb;
   
   /* Number of packet timings we have received (including those we didn't keep) */
   tot_count = 0;
   for (i=0;i<MAX_BUFFERS;i++)
      tot_count += tb[i].curr_count;
   if (tot_count==0)
      return 0;
   
   /* Compute cost for one lost packet */
   if (jitter->latency_tradeoff != 0)
      late_factor = jitter->latency_tradeoff * 100.0f / tot_count;
   else
      late_factor = jitter->auto_tradeoff * jitter->window_size/tot_count;
   
   /*fprintf(stderr, "late_factor = %f\n", late_factor);*/
   for (i=0;i<MAX_BUFFERS;i++)
      pos[i] = 0;
   
   /* Pick the TOP_DELAY "latest" packets (doesn't need to actually be late 
      for the current settings) */
   for (i=0;i<TOP_DELAY;i++)
   {
      int j;
      int next=-1;
      int latest = 32767;
      /* Pick latest amoung all sub-windows */
      for (j=0;j<MAX_BUFFERS;j++)
      {
         if (pos[j] < tb[j].filled && tb[j].timing[pos[j]] < latest)
         {
            next = j;
            latest = tb[j].timing[pos[j]];
         }
      }
      if (next != -1)
      {
         spx_int32_t cost;
         
         if (i==0)
            worst = latest;
         best = latest;
         latest = ROUND_DOWN(latest, jitter->delay_step);
         pos[next]++;
         
         /* Actual cost function that tells us how bad using this delay would be */
         cost = -latest + late_factor*late;
         /*fprintf(stderr, "cost %d = %d + %f * %d\n", cost, -latest, late_factor, late);*/
         if (cost < best_cost)
         {
            best_cost = cost;
            opt = latest;
         }
      } else {
         break;
      }
      
      /* For the next timing we will consider, there will be one more late packet to count */
      late++;
      /* Two-frame penalty if we're going to increase the amount of late frames (hysteresis) */
      if (latest >= 0 && !penalty_taken)
      {
         penalty_taken = 1;
         late+=4;
      }
   }
   
   deltaT = best-worst;
   /* This is a default "automatic latency tradeoff" when none is provided */
   jitter->auto_tradeoff = 1 + deltaT/TOP_DELAY;
   /*fprintf(stderr, "auto_tradeoff = %d (%d %d %d)\n", jitter->auto_tradeoff, best, worst, i);*/
   
   /* FIXME: Compute a short-term estimate too and combine with the long-term one */
   
   /* Prevents reducing the buffer size when we haven't really had much data */
   if (tot_count < TOP_DELAY && opt > 0)
      return 0;
   return opt;
}


/** Initialise jitter buffer */
EXPORT JitterBuffer *jitter_buffer_init(int step_size)
{
   JitterBuffer *jitter = (JitterBuffer*)speex_alloc(sizeof(JitterBuffer));
   if (jitter)
   {
      int i;
      spx_int32_t tmp;
      for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
         jitter->packets[i].data=NULL;
      jitter->delay_step = step_size;
      jitter->concealment_size = step_size;
      /*FIXME: Should this be 0 or 1?*/
      jitter->buffer_margin = 0;
      jitter->late_cutoff = 50;
      jitter->destroy = NULL;
      jitter->latency_tradeoff = 0;
      jitter->auto_adjust = 1;
      tmp = 4;
      jitter_buffer_ctl(jitter, JITTER_BUFFER_SET_MAX_LATE_RATE, &tmp);
      jitter_buffer_reset(jitter);
   }
   return jitter;
}

/** Reset jitter buffer */
EXPORT void jitter_buffer_reset(JitterBuffer *jitter)
{
   int i;
   for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
   {
      if (jitter->packets[i].data)
      {
         if (jitter->destroy)
            jitter->destroy(jitter->packets[i].data);
         else
            speex_free(jitter->packets[i].data);
         jitter->packets[i].data = NULL;
      }
   }
   /* Timestamp is actually undefined at this point */
   jitter->pointer_timestamp = 0;
   jitter->next_stop = 0;
   jitter->reset_state = 1;
   jitter->lost_count = 0;
   jitter->buffered = 0;
   jitter->auto_tradeoff = 32000;
   
   for (i=0;i<MAX_BUFFERS;i++)
   {
      tb_init(&jitter->_tb[i]);
      jitter->timeBuffers[i] = &jitter->_tb[i];
   }
   /*fprintf (stderr, "reset\n");*/
}

/** Destroy jitter buffer */
EXPORT void jitter_buffer_destroy(JitterBuffer *jitter)
{
   jitter_buffer_reset(jitter);
   speex_free(jitter);
}

/** Take the following timing into consideration for future calculations */
static void update_timings(JitterBuffer *jitter, spx_int32_t timing)
{
   if (timing < -32767)
      timing = -32767;
   if (timing > 32767)
      timing = 32767;
   /* If the current sub-window is full, perform a rotation and discard oldest sub-widow */
   if (jitter->timeBuffers[0]->curr_count >= jitter->subwindow_size)
   {
      int i;
      /*fprintf(stderr, "Rotate buffer\n");*/
      struct TimingBuffer *tmp = jitter->timeBuffers[MAX_BUFFERS-1];
      for (i=MAX_BUFFERS-1;i>=1;i--)
         jitter->timeBuffers[i] = jitter->timeBuffers[i-1];
      jitter->timeBuffers[0] = tmp;
      tb_init(jitter->timeBuffers[0]);
   }
   tb_add(jitter->timeBuffers[0], timing);
}

/** Compensate all timings when we do an adjustment of the buffering */
static void shift_timings(JitterBuffer *jitter, spx_int16_t amount)
{
   int i, j;
   for (i=0;i<MAX_BUFFERS;i++)
   {
      for (j=0;j<jitter->timeBuffers[i]->filled;j++)
         jitter->timeBuffers[i]->timing[j] += amount;
   }
}


/** Put one packet into the jitter buffer */
EXPORT void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet)
{
   int i,j;
   int late;
   /*fprintf (stderr, "put packet %d %d\n", timestamp, span);*/
   
   /* Cleanup buffer (remove old packets that weren't played) */
   if (!jitter->reset_state)
   {
      for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
      {
         /* Make sure we don't discard a "just-late" packet in case we want to play it next (if we interpolate). */
         if (jitter->packets[i].data && LE32(jitter->packets[i].timestamp + jitter->packets[i].span, jitter->pointer_timestamp))
         {
            /*fprintf (stderr, "cleaned (not played)\n");*/
            if (jitter->destroy)
               jitter->destroy(jitter->packets[i].data);
            else
               speex_free(jitter->packets[i].data);
            jitter->packets[i].data = NULL;
         }
      }
   }
   
   /*fprintf(stderr, "arrival: %d %d %d\n", packet->timestamp, jitter->next_stop, jitter->pointer_timestamp);*/
   /* Check if packet is late (could still be useful though) */
   if (!jitter->reset_state && LT32(packet->timestamp, jitter->next_stop))
   {
      update_timings(jitter, ((spx_int32_t)packet->timestamp) - ((spx_int32_t)jitter->next_stop) - jitter->buffer_margin);
      late = 1;
   } else {
      late = 0;
   }

   /* For some reason, the consumer has failed the last 20 fetches. Make sure this packet is
    * used to resync. */
   if (jitter->lost_count>20)
   {
      jitter_buffer_reset(jitter);
   }
   
   /* Only insert the packet if it's not hopelessly late (i.e. totally useless) */
   if (jitter->reset_state || GE32(packet->timestamp+packet->span+jitter->delay_step, jitter->pointer_timestamp))
   {

      /*Find an empty slot in the buffer*/
      for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
      {
         if (jitter->packets[i].data==NULL)
            break;
      }
      
      /*No place left in the buffer, need to make room for it by discarding the oldest packet */
      if (i==SPEEX_JITTER_MAX_BUFFER_SIZE)
      {
         int earliest=jitter->packets[0].timestamp;
         i=0;
         for (j=1;j<SPEEX_JITTER_MAX_BUFFER_SIZE;j++)
         {
            if (!jitter->packets[i].data || LT32(jitter->packets[j].timestamp,earliest))
            {
               earliest = jitter->packets[j].timestamp;
               i=j;
            }
         }
         if (jitter->destroy)
            jitter->destroy(jitter->packets[i].data);
         else
            speex_free(jitter->packets[i].data);
         jitter->packets[i].data=NULL;
         /*fprintf (stderr, "Buffer is full, discarding earliest frame %d (currently at %d)\n", timestamp, jitter->pointer_timestamp);*/      
      }
   
      /* Copy packet in buffer */
      if (jitter->destroy)
      {
         jitter->packets[i].data = packet->data;
      } else {
         jitter->packets[i].data=(char*)speex_alloc(packet->len);
         for (j=0;j<packet->len;j++)
            jitter->packets[i].data[j]=packet->data[j];
      }
      jitter->packets[i].timestamp=packet->timestamp;
      jitter->packets[i].span=packet->span;
      jitter->packets[i].len=packet->len;
      jitter->packets[i].sequence=packet->sequence;
      jitter->packets[i].user_data=packet->user_data;
      if (jitter->reset_state || late)
         jitter->arrival[i] = 0;
      else
         jitter->arrival[i] = jitter->next_stop;
   }
   
   
}

/** Get one packet from the jitter buffer */
EXPORT int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t desired_span, spx_int32_t *start_offset)
{
   int i;
   unsigned int j;
   int incomplete = 0;
   spx_int16_t opt;
   
   if (start_offset != NULL)
      *start_offset = 0;

   /* Syncing on the first call */
   if (jitter->reset_state)
   {
      int found = 0;
      /* Find the oldest packet */
      spx_uint32_t oldest=0;
      for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
      {
         if (jitter->packets[i].data && (!found || LT32(jitter->packets[i].timestamp,oldest)))
         {
            oldest = jitter->packets[i].timestamp;
            found = 1;
         }
      }
      if (found)
      {
         jitter->reset_state=0;         
         jitter->pointer_timestamp = oldest;
         jitter->next_stop = oldest;
      } else {
         packet->timestamp = 0;
         packet->span = jitter->interp_requested;
         return JITTER_BUFFER_MISSING;
      }
   }
   

   jitter->last_returned_timestamp = jitter->pointer_timestamp;
         
   if (jitter->interp_requested != 0)
   {
      packet->timestamp = jitter->pointer_timestamp;
      packet->span = jitter->interp_requested;
      
      /* Increment the pointer because it got decremented in the delay update */
      jitter->pointer_timestamp += jitter->interp_requested;
      packet->len = 0;
      /*fprintf (stderr, "Deferred interpolate\n");*/
      
      jitter->interp_requested = 0;
      
      jitter->buffered = packet->span - desired_span;

      return JITTER_BUFFER_INSERTION;
   }
   
   /* Searching for the packet that fits best */
   
   /* Search the buffer for a packet with the right timestamp and spanning the whole current chunk */
   for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
   {
      if (jitter->packets[i].data && jitter->packets[i].timestamp==jitter->pointer_timestamp && GE32(jitter->packets[i].timestamp+jitter->packets[i].span,jitter->pointer_timestamp+desired_span))
         break;
   }
   
   /* If no match, try for an "older" packet that still spans (fully) the current chunk */
   if (i==SPEEX_JITTER_MAX_BUFFER_SIZE)
   {
      for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
      {
         if (jitter->packets[i].data && LE32(jitter->packets[i].timestamp, jitter->pointer_timestamp) && GE32(jitter->packets[i].timestamp+jitter->packets[i].span,jitter->pointer_timestamp+desired_span))
            break;
      }
   }
   
   /* If still no match, try for an "older" packet that spans part of the current chunk */
   if (i==SPEEX_JITTER_MAX_BUFFER_SIZE)
   {
      for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
      {
         if (jitter->packets[i].data && LE32(jitter->packets[i].timestamp, jitter->pointer_timestamp) && GT32(jitter->packets[i].timestamp+jitter->packets[i].span,jitter->pointer_timestamp))
            break;
      }
   }
   
   /* If still no match, try for earliest packet possible */
   if (i==SPEEX_JITTER_MAX_BUFFER_SIZE)
   {
      int found = 0;
      spx_uint32_t best_time=0;
      int best_span=0;
      int besti=0;
      for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
      {
         /* check if packet starts within current chunk */
         if (jitter->packets[i].data && LT32(jitter->packets[i].timestamp,jitter->pointer_timestamp+desired_span) && GE32(jitter->packets[i].timestamp,jitter->pointer_timestamp))
         {
            if (!found || LT32(jitter->packets[i].timestamp,best_time) || (jitter->packets[i].timestamp==best_time && GT32(jitter->packets[i].span,best_span)))
            {
               best_time = jitter->packets[i].timestamp;
               best_span = jitter->packets[i].span;
               besti = i;
               found = 1;
            }
         }
      }
      if (found)
      {
         i=besti;
         incomplete = 1;
         /*fprintf (stderr, "incomplete: %d %d %d %d\n", jitter->packets[i].timestamp, jitter->pointer_timestamp, chunk_size, jitter->packets[i].span);*/
      }
   }

   /* If we find something */
   if (i!=SPEEX_JITTER_MAX_BUFFER_SIZE)
   {
      spx_int32_t offset;
      
      /* We (obviously) haven't lost this packet */
      jitter->lost_count = 0;
      
      /* In this case, 0 isn't as a valid timestamp */
      if (jitter->arrival[i] != 0)
      {
         update_timings(jitter, ((spx_int32_t)jitter->packets[i].timestamp) - ((spx_int32_t)jitter->arrival[i]) - jitter->buffer_margin);
      }
      
      
      /* Copy packet */
      if (jitter->destroy)
      {
         packet->data = jitter->packets[i].data;
         packet->len = jitter->packets[i].len;
      } else {
         if (jitter->packets[i].len > packet->len)
         {
            speex_warning_int("jitter_buffer_get(): packet too large to fit. Size is", jitter->packets[i].len);
         } else {
            packet->len = jitter->packets[i].len;
         }
         for (j=0;j<packet->len;j++)
            packet->data[j] = jitter->packets[i].data[j];
         /* Remove packet */
         speex_free(jitter->packets[i].data);
      }
      jitter->packets[i].data = NULL;
      /* Set timestamp and span (if requested) */
      offset = (spx_int32_t)jitter->packets[i].timestamp-(spx_int32_t)jitter->pointer_timestamp;
      if (start_offset != NULL)
         *start_offset = offset;
      else if (offset != 0)
         speex_warning_int("jitter_buffer_get() discarding non-zero start_offset", offset);
      
      packet->timestamp = jitter->packets[i].timestamp;
      jitter->last_returned_timestamp = packet->timestamp;
      
      packet->span = jitter->packets[i].span;
      packet->sequence = jitter->packets[i].sequence;
      packet->user_data = jitter->packets[i].user_data;
      /* Point to the end of the current packet */
      jitter->pointer_timestamp = jitter->packets[i].timestamp+jitter->packets[i].span;

      jitter->buffered = packet->span - desired_span;
      
      if (start_offset != NULL)
         jitter->buffered += *start_offset;
      
      return JITTER_BUFFER_OK;
   }
   
   
   /* If we haven't found anything worth returning */
   
   /*fprintf (stderr, "not found\n");*/
   jitter->lost_count++;
   /*fprintf (stderr, "m");*/
   /*fprintf (stderr, "lost_count = %d\n", jitter->lost_count);*/
   
   opt = compute_opt_delay(jitter);
   
   /* Should we force an increase in the buffer or just do normal interpolation? */   
   if (opt < 0)
   {
      /* Need to increase buffering */
      
      /* Shift histogram to compensate */
      shift_timings(jitter, -opt);
      
      packet->timestamp = jitter->pointer_timestamp;
      packet->span = -opt;
      /* Don't move the pointer_timestamp forward */
      packet->len = 0;
      
      jitter->buffered = packet->span - desired_span;
      return JITTER_BUFFER_INSERTION;
      /*jitter->pointer_timestamp -= jitter->delay_step;*/
      /*fprintf (stderr, "Forced to interpolate\n");*/
   } else {
      /* Normal packet loss */
      packet->timestamp = jitter->pointer_timestamp;
      
      desired_span = ROUND_DOWN(desired_span, jitter->concealment_size);
      packet->span = desired_span;
      jitter->pointer_timestamp += desired_span;
      packet->len = 0;
      
      jitter->buffered = packet->span - desired_span;
      return JITTER_BUFFER_MISSING;
      /*fprintf (stderr, "Normal loss\n");*/
   }


}

EXPORT int jitter_buffer_get_another(JitterBuffer *jitter, JitterBufferPacket *packet)
{
   int i, j;
   for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
   {
      if (jitter->packets[i].data && jitter->packets[i].timestamp==jitter->last_returned_timestamp)
         break;
   }
   if (i!=SPEEX_JITTER_MAX_BUFFER_SIZE)
   {
      /* Copy packet */
      packet->len = jitter->packets[i].len;
      if (jitter->destroy)
      {
         packet->data = jitter->packets[i].data;
      } else {
         for (j=0;j<packet->len;j++)
            packet->data[j] = jitter->packets[i].data[j];
         /* Remove packet */
         speex_free(jitter->packets[i].data);
      }
      jitter->packets[i].data = NULL;
      packet->timestamp = jitter->packets[i].timestamp;
      packet->span = jitter->packets[i].span;
      packet->sequence = jitter->packets[i].sequence;
      packet->user_data = jitter->packets[i].user_data;
      return JITTER_BUFFER_OK;
   } else {
      packet->data = NULL;
      packet->len = 0;
      packet->span = 0;
      return JITTER_BUFFER_MISSING;
   }
}

/* Let the jitter buffer know it's the right time to adjust the buffering delay to the network conditions */
static int _jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset)
{
   spx_int16_t opt = compute_opt_delay(jitter);
   /*fprintf(stderr, "opt adjustment is %d ", opt);*/
   
   if (opt < 0)
   {
      shift_timings(jitter, -opt);
      
      jitter->pointer_timestamp += opt;
      jitter->interp_requested = -opt;
      /*fprintf (stderr, "Decision to interpolate %d samples\n", -opt);*/
   } else if (opt > 0)
   {
      shift_timings(jitter, -opt);
      jitter->pointer_timestamp += opt;
      /*fprintf (stderr, "Decision to drop %d samples\n", opt);*/
   }
   
   return opt;
}

/* Let the jitter buffer know it's the right time to adjust the buffering delay to the network conditions */
EXPORT int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset)
{
   /* If the programmer calls jitter_buffer_update_delay() directly, 
      automatically disable auto-adjustment */
   jitter->auto_adjust = 0;

   return _jitter_buffer_update_delay(jitter, packet, start_offset);
}

/** Get pointer timestamp of jitter buffer */
EXPORT int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter)
{
   return jitter->pointer_timestamp;
}

EXPORT void jitter_buffer_tick(JitterBuffer *jitter)
{
   /* Automatically-adjust the buffering delay if requested */
   if (jitter->auto_adjust)
      _jitter_buffer_update_delay(jitter, NULL, NULL);
   
   if (jitter->buffered >= 0)
   {
      jitter->next_stop = jitter->pointer_timestamp - jitter->buffered;
   } else {
      jitter->next_stop = jitter->pointer_timestamp;
      speex_warning_int("jitter buffer sees negative buffering, your code might be broken. Value is ", jitter->buffered);
   }
   jitter->buffered = 0;
}

EXPORT void jitter_buffer_remaining_span(JitterBuffer *jitter, spx_uint32_t rem)
{
   /* Automatically-adjust the buffering delay if requested */
   if (jitter->auto_adjust)
      _jitter_buffer_update_delay(jitter, NULL, NULL);
   
   if (jitter->buffered < 0)
      speex_warning_int("jitter buffer sees negative buffering, your code might be broken. Value is ", jitter->buffered);
   jitter->next_stop = jitter->pointer_timestamp - rem;
}


/* Used like the ioctl function to control the jitter buffer parameters */
EXPORT int jitter_buffer_ctl(JitterBuffer *jitter, int request, void *ptr)
{
   int count, i;
   switch(request)
   {
      case JITTER_BUFFER_SET_MARGIN:
         jitter->buffer_margin = *(spx_int32_t*)ptr;
         break;
      case JITTER_BUFFER_GET_MARGIN:
         *(spx_int32_t*)ptr = jitter->buffer_margin;
         break;
      case JITTER_BUFFER_GET_AVALIABLE_COUNT:
         count = 0;
         for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
         {
            if (jitter->packets[i].data && LE32(jitter->pointer_timestamp, jitter->packets[i].timestamp))
            {
               count++;
            }
         }
         *(spx_int32_t*)ptr = count;
         break;
      case JITTER_BUFFER_SET_DESTROY_CALLBACK:
         jitter->destroy = (void (*) (void *))ptr;
         break;
      case JITTER_BUFFER_GET_DESTROY_CALLBACK:
         *(void (**) (void *))ptr = jitter->destroy;
         break;
      case JITTER_BUFFER_SET_DELAY_STEP:
         jitter->delay_step = *(spx_int32_t*)ptr;
         break;
      case JITTER_BUFFER_GET_DELAY_STEP:
         *(spx_int32_t*)ptr = jitter->delay_step;
         break;
      case JITTER_BUFFER_SET_CONCEALMENT_SIZE:
         jitter->concealment_size = *(spx_int32_t*)ptr;
         break;
      case JITTER_BUFFER_GET_CONCEALMENT_SIZE:
         *(spx_int32_t*)ptr = jitter->concealment_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;
   }
   return 0;
}

