[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