diff options
Diffstat (limited to 'apps/codecs/libspeex/jitter.c')
-rw-r--r-- | apps/codecs/libspeex/jitter.c | 753 |
1 files changed, 521 insertions, 232 deletions
diff --git a/apps/codecs/libspeex/jitter.c b/apps/codecs/libspeex/jitter.c index 57bb4c2958..e31a131bba 100644 --- a/apps/codecs/libspeex/jitter.c +++ b/apps/codecs/libspeex/jitter.c | |||
@@ -32,12 +32,27 @@ | |||
32 | 32 | ||
33 | */ | 33 | */ |
34 | 34 | ||
35 | /* | ||
36 | TODO: | ||
37 | - Write generic functions for computing stats and shifting the histogram | ||
38 | - Take into account the delay step when computing the stats and when shifting | ||
39 | - Linked list structure for holding the packets instead of the current fixed-size array | ||
40 | + return memory to a pool | ||
41 | + allow pre-allocation of the pool | ||
42 | + optional max number of elements | ||
43 | - Statistics | ||
44 | + drift | ||
45 | + loss | ||
46 | + late | ||
47 | + jitter | ||
48 | + buffering delay | ||
49 | */ | ||
35 | #ifdef HAVE_CONFIG_H | 50 | #ifdef HAVE_CONFIG_H |
36 | #include "config-speex.h" | 51 | #include "config-speex.h" |
37 | #endif | 52 | #endif |
38 | 53 | ||
39 | 54 | ||
40 | #include "misc.h" | 55 | #include "arch.h" |
41 | #include <speex/speex.h> | 56 | #include <speex/speex.h> |
42 | #include <speex/speex_bits.h> | 57 | #include <speex/speex_bits.h> |
43 | #include <speex/speex_jitter.h> | 58 | #include <speex/speex_jitter.h> |
@@ -52,29 +67,157 @@ | |||
52 | 67 | ||
53 | #define SPEEX_JITTER_MAX_BUFFER_SIZE 200 /**< Maximum number of packets in jitter buffer */ | 68 | #define SPEEX_JITTER_MAX_BUFFER_SIZE 200 /**< Maximum number of packets in jitter buffer */ |
54 | 69 | ||
55 | 70 | #define TSUB(a,b) ((spx_int32_t)((a)-(b))) | |
56 | 71 | ||
57 | #define GT32(a,b) (((spx_int32_t)((a)-(b)))>0) | 72 | #define GT32(a,b) (((spx_int32_t)((a)-(b)))>0) |
58 | #define GE32(a,b) (((spx_int32_t)((a)-(b)))>=0) | 73 | #define GE32(a,b) (((spx_int32_t)((a)-(b)))>=0) |
59 | #define LT32(a,b) (((spx_int32_t)((a)-(b)))<0) | 74 | #define LT32(a,b) (((spx_int32_t)((a)-(b)))<0) |
60 | #define LE32(a,b) (((spx_int32_t)((a)-(b)))<=0) | 75 | #define LE32(a,b) (((spx_int32_t)((a)-(b)))<=0) |
61 | 76 | ||
77 | #define MAX_TIMINGS 20 | ||
78 | #define MAX_BUFFERS 3 | ||
79 | #define TOP_DELAY 25 | ||
80 | #define WINDOW_SIZE 200 | ||
81 | |||
82 | struct TimingBuffer { | ||
83 | int filled; | ||
84 | int curr_count; | ||
85 | spx_int16_t timing[MAX_TIMINGS]; | ||
86 | spx_int16_t counts[MAX_TIMINGS]; | ||
87 | }; | ||
88 | |||
89 | static void tb_init(struct TimingBuffer *tb) | ||
90 | { | ||
91 | tb->filled = 0; | ||
92 | tb->curr_count = 0; | ||
93 | } | ||
94 | |||
95 | static void tb_add(struct TimingBuffer *tb, spx_int16_t timing) | ||
96 | { | ||
97 | int pos; | ||
98 | /*fprintf(stderr, "timing = %d\n", timing);*/ | ||
99 | /*fprintf(stderr, "timing = %d, latest = %d, earliest = %d, filled = %d\n", timing, tb->timing[0], tb->timing[tb->filled-1], tb->filled);*/ | ||
100 | if (tb->filled >= MAX_TIMINGS && timing >= tb->timing[tb->filled-1]) | ||
101 | { | ||
102 | tb->curr_count++; | ||
103 | return; | ||
104 | } | ||
105 | pos = 0; | ||
106 | /* FIXME: Do bisection instead of linear search */ | ||
107 | while (pos<tb->filled && timing >= tb->timing[pos]) | ||
108 | { | ||
109 | pos++; | ||
110 | } | ||
111 | |||
112 | /*fprintf(stderr, "pos = %d filled = %d\n", pos, tb->filled);*/ | ||
113 | speex_assert(pos <= tb->filled && pos < MAX_TIMINGS); | ||
114 | fprintf(stderr, "OK\n"); | ||
115 | if (pos < tb->filled) | ||
116 | { | ||
117 | int move_size = tb->filled-pos; | ||
118 | if (tb->filled == MAX_TIMINGS) | ||
119 | move_size -= 1; | ||
120 | /*fprintf(stderr, "speex_move(%d %d %d)\n", pos+1, pos, move_size);*/ | ||
121 | speex_move(&tb->timing[pos+1], &tb->timing[pos], move_size*sizeof(tb->timing[0])); | ||
122 | speex_move(&tb->counts[pos+1], &tb->counts[pos], move_size*sizeof(tb->counts[0])); | ||
123 | } | ||
124 | /*fprintf(stderr, "moved\n");*/ | ||
125 | tb->timing[pos] = timing; | ||
126 | tb->counts[pos] = tb->curr_count; | ||
127 | /*{ | ||
128 | int i; | ||
129 | for (i=0;i<MAX_TIMINGS;i++) | ||
130 | fprintf(stderr, "%d ", tb->timing[i]); | ||
131 | fprintf(stderr, "\n"); | ||
132 | }*/ | ||
133 | tb->curr_count++; | ||
134 | if (tb->filled<MAX_TIMINGS) | ||
135 | tb->filled++; | ||
136 | /*fprintf(stderr, "added\n");*/ | ||
137 | } | ||
138 | |||
139 | /** Based on available data, this computes the optimal delay for the jitter buffer. | ||
140 | The optimised function is in timestamp units and is: | ||
141 | cost = delay + late_factor*[number of frames that would be late if we used that delay] | ||
142 | @param tb Array of buffers | ||
143 | @param late_factor Equivalent cost of a late frame (in timestamp units) | ||
144 | */ | ||
145 | static spx_int16_t tbs_get_opt_delay(struct TimingBuffer *tb, spx_int32_t late_factor) | ||
146 | { | ||
147 | int i; | ||
148 | spx_int16_t opt=0; | ||
149 | spx_int32_t best_cost=0x7fffffff; | ||
150 | int late = 0; | ||
151 | int pos[MAX_BUFFERS]; | ||
152 | |||
153 | /*fprintf(stderr, "tbs_get_opt_delay\n");*/ | ||
154 | for (i=0;i<MAX_BUFFERS;i++) | ||
155 | pos[i] = 0; | ||
156 | |||
157 | for (i=0;i<TOP_DELAY;i++) | ||
158 | { | ||
159 | int j; | ||
160 | int next=-1; | ||
161 | int latest = 32767; | ||
162 | for (j=0;j<MAX_BUFFERS;j++) | ||
163 | { | ||
164 | if (pos[j] < tb[j].filled && tb[j].timing[pos[j]] < latest) | ||
165 | { | ||
166 | next = j; | ||
167 | latest = tb[j].timing[pos[j]]; | ||
168 | } | ||
169 | } | ||
170 | late++; | ||
171 | if (next != -1) | ||
172 | { | ||
173 | spx_int32_t cost; | ||
174 | pos[next]++; | ||
175 | /* When considering reducing delay, "on-time" frames could twice (this provides hysteresis) */ | ||
176 | if (latest > 0) | ||
177 | late++; | ||
178 | cost = -latest + late_factor*late; | ||
179 | /*fprintf(stderr, "cost %d = -%d + %d * %d\n", cost, latest, late_factor, late);*/ | ||
180 | if (cost < best_cost) | ||
181 | { | ||
182 | best_cost = cost; | ||
183 | opt = latest; | ||
184 | } | ||
185 | } else { | ||
186 | break; | ||
187 | } | ||
188 | } | ||
189 | return opt; | ||
190 | } | ||
191 | |||
62 | /** Jitter buffer structure */ | 192 | /** Jitter buffer structure */ |
63 | struct JitterBuffer_ { | 193 | struct JitterBuffer_ { |
64 | spx_uint32_t pointer_timestamp; /**< Timestamp of what we will *get* next */ | 194 | spx_uint32_t pointer_timestamp; /**< Timestamp of what we will *get* next */ |
65 | spx_uint32_t current_timestamp; /**< Timestamp of the local clock (what we will *play* next) */ | 195 | spx_uint32_t last_returned_timestamp; |
66 | 196 | spx_uint32_t next_stop; | |
67 | char *buf[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Buffer of packets (NULL if slot is free) */ | 197 | |
68 | spx_uint32_t timestamp[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Timestamp of packet */ | 198 | JitterBufferPacket packets[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Packets stored in the buffer */ |
69 | int span[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Timestamp of packet */ | 199 | spx_uint32_t arrival[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Packet arrival time (0 means it was late, even though it's a valid timestamp) */ |
70 | int len[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Number of bytes in packet */ | 200 | |
201 | void (*destroy) (void *); /**< Callback for destroying a packet */ | ||
71 | 202 | ||
72 | int tick_size; /**< Output granularity */ | 203 | int resolution; /**< Time resolution for histogram (timestamp units) */ |
204 | int delay_step; /**< Size of the steps when adjusting buffering (timestamp units) */ | ||
205 | int res_delay_step; /**< Size of the steps when adjusting buffering (resolution units) */ | ||
73 | int reset_state; /**< True if state was just reset */ | 206 | int reset_state; /**< True if state was just reset */ |
74 | int buffer_margin; /**< How many frames we want to keep in the buffer (lower bound) */ | 207 | int buffer_margin; /**< How many frames we want to keep in the buffer (lower bound) */ |
75 | int late_cutoff; /**< How late must a packet be for it not to be considered at all */ | 208 | int late_cutoff; /**< How late must a packet be for it not to be considered at all */ |
76 | int interp_requested; /**< An interpolation is requested by speex_jitter_update_delay() */ | 209 | int interp_requested; /**< An interpolation is requested by speex_jitter_update_delay() */ |
77 | 210 | ||
211 | struct TimingBuffer _tb[MAX_BUFFERS]; /**< Don't use those directly */ | ||
212 | struct TimingBuffer *timeBuffers[MAX_BUFFERS]; /**< Storing arrival time of latest frames so we can compute some stats */ | ||
213 | |||
214 | float late_ratio_short; | ||
215 | float late_ratio_long; | ||
216 | float ontime_ratio_short; | ||
217 | float ontime_ratio_long; | ||
218 | float early_ratio_short; | ||
219 | float early_ratio_long; | ||
220 | |||
78 | int lost_count; /**< Number of consecutive lost packets */ | 221 | int lost_count; /**< Number of consecutive lost packets */ |
79 | float shortterm_margin[MAX_MARGIN]; /**< Short term margin histogram */ | 222 | float shortterm_margin[MAX_MARGIN]; /**< Short term margin histogram */ |
80 | float longterm_margin[MAX_MARGIN]; /**< Long term margin histogram */ | 223 | float longterm_margin[MAX_MARGIN]; /**< Long term margin histogram */ |
@@ -82,17 +225,21 @@ struct JitterBuffer_ { | |||
82 | }; | 225 | }; |
83 | 226 | ||
84 | /** Initialise jitter buffer */ | 227 | /** Initialise jitter buffer */ |
85 | JitterBuffer *jitter_buffer_init(int tick) | 228 | JitterBuffer *jitter_buffer_init(int resolution) |
86 | { | 229 | { |
87 | JitterBuffer *jitter = (JitterBuffer*)speex_alloc(sizeof(JitterBuffer)); | 230 | JitterBuffer *jitter = (JitterBuffer*)speex_alloc(sizeof(JitterBuffer)); |
88 | if (jitter) | 231 | if (jitter) |
89 | { | 232 | { |
90 | int i; | 233 | int i; |
91 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) | 234 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) |
92 | jitter->buf[i]=NULL; | 235 | jitter->packets[i].data=NULL; |
93 | jitter->tick_size = tick; | 236 | jitter->resolution = resolution; |
237 | jitter->delay_step = resolution; | ||
238 | jitter->res_delay_step = 1; | ||
239 | /*FIXME: Should this be 0 or 1?*/ | ||
94 | jitter->buffer_margin = 1; | 240 | jitter->buffer_margin = 1; |
95 | jitter->late_cutoff = 50; | 241 | jitter->late_cutoff = 50; |
242 | jitter->destroy = NULL; | ||
96 | jitter_buffer_reset(jitter); | 243 | jitter_buffer_reset(jitter); |
97 | } | 244 | } |
98 | return jitter; | 245 | return jitter; |
@@ -104,15 +251,18 @@ void jitter_buffer_reset(JitterBuffer *jitter) | |||
104 | int i; | 251 | int i; |
105 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) | 252 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) |
106 | { | 253 | { |
107 | if (jitter->buf[i]) | 254 | if (jitter->packets[i].data) |
108 | { | 255 | { |
109 | speex_free(jitter->buf[i]); | 256 | if (jitter->destroy) |
110 | jitter->buf[i] = NULL; | 257 | jitter->destroy(jitter->packets[i].data); |
258 | else | ||
259 | speex_free(jitter->packets[i].data); | ||
260 | jitter->packets[i].data = NULL; | ||
111 | } | 261 | } |
112 | } | 262 | } |
113 | /* Timestamp is actually undefined at this point */ | 263 | /* Timestamp is actually undefined at this point */ |
114 | jitter->pointer_timestamp = 0; | 264 | jitter->pointer_timestamp = 0; |
115 | jitter->current_timestamp = 0; | 265 | jitter->next_stop = 0; |
116 | jitter->reset_state = 1; | 266 | jitter->reset_state = 1; |
117 | jitter->lost_count = 0; | 267 | jitter->lost_count = 0; |
118 | jitter->loss_rate = 0; | 268 | jitter->loss_rate = 0; |
@@ -121,6 +271,12 @@ void jitter_buffer_reset(JitterBuffer *jitter) | |||
121 | jitter->shortterm_margin[i] = 0; | 271 | jitter->shortterm_margin[i] = 0; |
122 | jitter->longterm_margin[i] = 0; | 272 | jitter->longterm_margin[i] = 0; |
123 | } | 273 | } |
274 | |||
275 | for (i=0;i<MAX_BUFFERS;i++) | ||
276 | { | ||
277 | tb_init(&jitter->_tb[i]); | ||
278 | jitter->timeBuffers[i] = &jitter->_tb[i]; | ||
279 | } | ||
124 | /*fprintf (stderr, "reset\n");*/ | 280 | /*fprintf (stderr, "reset\n");*/ |
125 | } | 281 | } |
126 | 282 | ||
@@ -131,79 +287,45 @@ void jitter_buffer_destroy(JitterBuffer *jitter) | |||
131 | speex_free(jitter); | 287 | speex_free(jitter); |
132 | } | 288 | } |
133 | 289 | ||
134 | /** Put one packet into the jitter buffer */ | 290 | static void update_timings(JitterBuffer *jitter, spx_int32_t timing) |
135 | void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet) | ||
136 | { | 291 | { |
137 | int i,j; | 292 | if (timing < -32767) |
138 | spx_int32_t arrival_margin; | 293 | timing = -32767; |
139 | /*fprintf (stderr, "put packet %d %d\n", timestamp, span);*/ | 294 | if (timing > 32767) |
140 | if (jitter->reset_state) | 295 | timing = 32767; |
141 | { | 296 | if (jitter->timeBuffers[0]->curr_count >= WINDOW_SIZE) |
142 | jitter->reset_state=0; | ||
143 | jitter->pointer_timestamp = packet->timestamp; | ||
144 | jitter->current_timestamp = packet->timestamp; | ||
145 | /*fprintf(stderr, "reset to %d\n", timestamp);*/ | ||
146 | } | ||
147 | |||
148 | /* Cleanup buffer (remove old packets that weren't played) */ | ||
149 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) | ||
150 | { | 297 | { |
151 | /* Make sure we don't discard a "just-late" packet in case we want to play it next (if we interpolate). */ | 298 | int i; |
152 | if (jitter->buf[i] && LE32(jitter->timestamp[i] + jitter->span[i], jitter->pointer_timestamp)) | 299 | /*fprintf(stderr, "Rotate buffer\n");*/ |
153 | { | 300 | struct TimingBuffer *tmp = jitter->timeBuffers[MAX_BUFFERS-1]; |
154 | /*fprintf (stderr, "cleaned (not played)\n");*/ | 301 | for (i=MAX_BUFFERS-1;i>=1;i--) |
155 | speex_free(jitter->buf[i]); | 302 | jitter->timeBuffers[i] = jitter->timeBuffers[i-1]; |
156 | jitter->buf[i] = NULL; | 303 | jitter->timeBuffers[0] = tmp; |
157 | } | 304 | tb_init(jitter->timeBuffers[0]); |
158 | } | 305 | } |
306 | tb_add(jitter->timeBuffers[0], timing); | ||
307 | spx_int16_t opt = tbs_get_opt_delay(jitter->_tb, 2); | ||
308 | /*fprintf(stderr, "opt adjustment is %d\n", opt);*/ | ||
309 | } | ||
159 | 310 | ||
160 | /*Find an empty slot in the buffer*/ | 311 | static void shift_timings(JitterBuffer *jitter, spx_int16_t amount) |
161 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) | 312 | { |
313 | int i, j; | ||
314 | for (i=0;i<MAX_BUFFERS;i++) | ||
162 | { | 315 | { |
163 | if (jitter->buf[i]==NULL) | 316 | for (j=0;j<jitter->timeBuffers[i]->filled;i++) |
164 | break; | 317 | jitter->timeBuffers[i]->timing[j] += amount; |
165 | } | 318 | } |
319 | } | ||
166 | 320 | ||
167 | /*fprintf(stderr, "%d %d %f\n", timestamp, jitter->pointer_timestamp, jitter->drift_average);*/ | 321 | static void update_histogram(JitterBuffer *jitter, spx_int32_t arrival_margin) |
168 | /*No place left in the buffer*/ | 322 | { |
169 | if (i==SPEEX_JITTER_MAX_BUFFER_SIZE) | 323 | int i; |
170 | { | ||
171 | int earliest=jitter->timestamp[0]; | ||
172 | i=0; | ||
173 | for (j=1;j<SPEEX_JITTER_MAX_BUFFER_SIZE;j++) | ||
174 | { | ||
175 | if (!jitter->buf[i] || LT32(jitter->timestamp[j],earliest)) | ||
176 | { | ||
177 | earliest = jitter->timestamp[j]; | ||
178 | i=j; | ||
179 | } | ||
180 | } | ||
181 | speex_free(jitter->buf[i]); | ||
182 | jitter->buf[i]=NULL; | ||
183 | if (jitter->lost_count>20) | ||
184 | { | ||
185 | jitter_buffer_reset(jitter); | ||
186 | } | ||
187 | /*fprintf (stderr, "Buffer is full, discarding earliest frame %d (currently at %d)\n", timestamp, jitter->pointer_timestamp);*/ | ||
188 | } | ||
189 | |||
190 | /* Copy packet in buffer */ | ||
191 | jitter->buf[i]=(char*)speex_alloc(packet->len); | ||
192 | for (j=0;j<(int)packet->len;j++) | ||
193 | jitter->buf[i][j]=packet->data[j]; | ||
194 | jitter->timestamp[i]=packet->timestamp; | ||
195 | jitter->span[i]=packet->span; | ||
196 | jitter->len[i]=packet->len; | ||
197 | |||
198 | /* Adjust the buffer size depending on network conditions. | ||
199 | The arrival margin is how much in advance (or late) the packet it */ | ||
200 | arrival_margin = (((spx_int32_t)packet->timestamp) - ((spx_int32_t)jitter->current_timestamp))/jitter->tick_size - jitter->buffer_margin; | ||
201 | |||
202 | if (arrival_margin >= -jitter->late_cutoff) | 324 | if (arrival_margin >= -jitter->late_cutoff) |
203 | { | 325 | { |
204 | /* Here we compute the histogram based on the time of arrival of the packet. | 326 | /* Here we compute the histogram based on the time of arrival of the packet. |
205 | This is based on a (first-order) recursive average. We keep both a short-term | 327 | This is based on a (first-order) recursive average. We keep both a short-term |
206 | histogram and a long-term histogram */ | 328 | histogram and a long-term histogram */ |
207 | spx_int32_t int_margin; | 329 | spx_int32_t int_margin; |
208 | /* First, apply the "damping" of the recursive average to all bins */ | 330 | /* First, apply the "damping" of the recursive average to all bins */ |
209 | for (i=0;i<MAX_MARGIN;i++) | 331 | for (i=0;i<MAX_MARGIN;i++) |
@@ -228,88 +350,215 @@ void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet) | |||
228 | jitter_buffer_reset(jitter); | 350 | jitter_buffer_reset(jitter); |
229 | } | 351 | } |
230 | } | 352 | } |
231 | #if 0 /* Enable to check how much is being buffered */ | 353 | } |
232 | if (rand()%1000==0) | 354 | |
355 | static void shift_histogram(JitterBuffer *jitter, int amount) | ||
356 | { | ||
357 | int i, c; | ||
358 | if (amount == 0) | ||
359 | return; | ||
360 | if (amount > 0) | ||
233 | { | 361 | { |
234 | int count = 0; | 362 | /* FIXME: This is terribly inefficient */ |
235 | for (j=0;j<SPEEX_JITTER_MAX_BUFFER_SIZE;j++) | 363 | for (c=0;c<amount;c++) |
236 | { | 364 | { |
237 | if (jitter->buf[j]) | 365 | jitter->shortterm_margin[MAX_MARGIN-1] += jitter->shortterm_margin[MAX_MARGIN-2]; |
238 | count++; | 366 | jitter->longterm_margin[MAX_MARGIN-1] += jitter->longterm_margin[MAX_MARGIN-2]; |
367 | for (i=MAX_MARGIN-3;i>=0;i--) | ||
368 | { | ||
369 | jitter->shortterm_margin[i+1] = jitter->shortterm_margin[i]; | ||
370 | jitter->longterm_margin[i+1] = jitter->longterm_margin[i]; | ||
371 | } | ||
372 | jitter->shortterm_margin[0] = 0; | ||
373 | jitter->longterm_margin[0] = 0; | ||
374 | } | ||
375 | } else { | ||
376 | /* FIXME: This is terribly inefficient */ | ||
377 | for (c=0;c<-amount;c++) | ||
378 | { | ||
379 | jitter->shortterm_margin[0] += jitter->shortterm_margin[1]; | ||
380 | jitter->longterm_margin[0] += jitter->longterm_margin[1]; | ||
381 | for (i=1;i<MAX_MARGIN-1;i++) | ||
382 | { | ||
383 | jitter->shortterm_margin[i] = jitter->shortterm_margin[i+1]; | ||
384 | jitter->longterm_margin[i] = jitter->longterm_margin[i+1]; | ||
385 | } | ||
386 | jitter->shortterm_margin[MAX_MARGIN-1] = 0; | ||
387 | jitter->longterm_margin[MAX_MARGIN-1] = 0; | ||
239 | } | 388 | } |
240 | fprintf (stderr, "buffer_size = %d\n", count); | ||
241 | } | 389 | } |
242 | #endif | ||
243 | } | 390 | } |
244 | 391 | ||
245 | /** Get one packet from the jitter buffer */ | 392 | static void compute_statistics(JitterBuffer *jitter) |
246 | int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset) | ||
247 | { | 393 | { |
248 | int i; | 394 | int i; |
249 | unsigned int j; | 395 | jitter->late_ratio_short = 0; |
250 | float late_ratio_short; | 396 | jitter->late_ratio_long = 0; |
251 | float late_ratio_long; | 397 | /* Count the proportion of packets that are late */ |
252 | float ontime_ratio_short; | 398 | for (i=0;i<LATE_BINS;i++) |
253 | float ontime_ratio_long; | ||
254 | float early_ratio_short; | ||
255 | float early_ratio_long; | ||
256 | int chunk_size; | ||
257 | int incomplete = 0; | ||
258 | |||
259 | if (jitter->interp_requested) | ||
260 | { | 399 | { |
261 | jitter->interp_requested = 0; | 400 | jitter->late_ratio_short += jitter->shortterm_margin[i]; |
262 | if (start_offset) | 401 | jitter->late_ratio_long += jitter->longterm_margin[i]; |
263 | *start_offset = 0; | ||
264 | packet->timestamp = jitter->pointer_timestamp; | ||
265 | packet->span = jitter->tick_size; | ||
266 | jitter->pointer_timestamp += jitter->tick_size; | ||
267 | packet->len = 0; | ||
268 | return JITTER_BUFFER_MISSING; | ||
269 | } | 402 | } |
270 | if (LT32(jitter->current_timestamp+jitter->tick_size, jitter->pointer_timestamp)) | 403 | |
404 | /* Count the proportion of packets that are just on time */ | ||
405 | jitter->ontime_ratio_short = 0; | ||
406 | jitter->ontime_ratio_long = 0; | ||
407 | for (;i<LATE_BINS+jitter->res_delay_step;i++) | ||
271 | { | 408 | { |
272 | jitter->current_timestamp = jitter->pointer_timestamp; | 409 | jitter->ontime_ratio_short = jitter->shortterm_margin[i]; |
273 | speex_warning("did you forget to call jitter_buffer_tick() by any chance?"); | 410 | jitter->ontime_ratio_long = jitter->longterm_margin[i]; |
274 | } | 411 | } |
275 | /*fprintf (stderr, "get packet %d %d\n", jitter->pointer_timestamp, jitter->current_timestamp);*/ | 412 | |
413 | jitter->early_ratio_short = 0; | ||
414 | jitter->early_ratio_long = 0; | ||
415 | /* Count the proportion of packets that are early */ | ||
416 | for (;i<MAX_MARGIN;i++) | ||
417 | { | ||
418 | jitter->early_ratio_short += jitter->shortterm_margin[i]; | ||
419 | jitter->early_ratio_long += jitter->longterm_margin[i]; | ||
420 | } | ||
421 | } | ||
276 | 422 | ||
277 | /* FIXME: This should be only what remaining of the current tick */ | 423 | /** Put one packet into the jitter buffer */ |
278 | chunk_size = jitter->tick_size; | 424 | void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet) |
425 | { | ||
426 | int i,j; | ||
427 | int late; | ||
428 | spx_int32_t arrival_margin; | ||
429 | spx_int32_t arrival_time; | ||
430 | /*fprintf (stderr, "put packet %d %d\n", timestamp, span);*/ | ||
279 | 431 | ||
280 | /* Compiling arrival statistics */ | 432 | /* Syncing on the first packet to arrive */ |
433 | if (jitter->reset_state) | ||
434 | { | ||
435 | jitter->reset_state=0; | ||
436 | jitter->pointer_timestamp = packet->timestamp; | ||
437 | jitter->next_stop = packet->timestamp; | ||
438 | /*fprintf(stderr, "reset to %d\n", timestamp);*/ | ||
439 | } | ||
281 | 440 | ||
282 | late_ratio_short = 0; | 441 | /* Cleanup buffer (remove old packets that weren't played) */ |
283 | late_ratio_long = 0; | 442 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) |
284 | /* Count the proportion of packets that are late */ | ||
285 | for (i=0;i<LATE_BINS;i++) | ||
286 | { | 443 | { |
287 | late_ratio_short += jitter->shortterm_margin[i]; | 444 | /* Make sure we don't discard a "just-late" packet in case we want to play it next (if we interpolate). */ |
288 | late_ratio_long += jitter->longterm_margin[i]; | 445 | if (jitter->packets[i].data && LE32(jitter->packets[i].timestamp + jitter->packets[i].span, jitter->pointer_timestamp)) |
446 | { | ||
447 | /*fprintf (stderr, "cleaned (not played)\n");*/ | ||
448 | if (jitter->destroy) | ||
449 | jitter->destroy(jitter->packets[i].data); | ||
450 | else | ||
451 | speex_free(jitter->packets[i].data); | ||
452 | jitter->packets[i].data = NULL; | ||
453 | } | ||
289 | } | 454 | } |
290 | /* Count the proportion of packets that are just on time */ | 455 | |
291 | ontime_ratio_short = jitter->shortterm_margin[LATE_BINS]; | 456 | /*fprintf(stderr, "arrival: %d %d %d\n", packet->timestamp, jitter->next_stop, jitter->pointer_timestamp);*/ |
292 | ontime_ratio_long = jitter->longterm_margin[LATE_BINS]; | 457 | /* Check if packet is late (could still be useful though) */ |
293 | early_ratio_short = early_ratio_long = 0; | 458 | if (LT32(packet->timestamp, jitter->next_stop)) |
294 | /* Count the proportion of packets that are early */ | ||
295 | for (i=LATE_BINS+1;i<MAX_MARGIN;i++) | ||
296 | { | 459 | { |
297 | early_ratio_short += jitter->shortterm_margin[i]; | 460 | /*fprintf(stderr, "late by %d\n", jitter->next_stop - packet->timestamp);*/ |
298 | early_ratio_long += jitter->longterm_margin[i]; | 461 | |
462 | /* The arrival margin is how much in advance (or in this case late) the packet it (in resolution units) */ | ||
463 | arrival_margin = (((spx_int32_t)packet->timestamp) - ((spx_int32_t)jitter->next_stop))/jitter->resolution - jitter->buffer_margin; | ||
464 | |||
465 | /*fprintf(stderr, "put arrival_margin = %d\n", arrival_margin);*/ | ||
466 | /*update_timings(jitter, ((spx_int32_t)packet->timestamp) - ((spx_int32_t)jitter->next_stop));*/ | ||
467 | update_histogram(jitter, arrival_margin); | ||
468 | late = 1; | ||
469 | } else { | ||
470 | late = 0; | ||
299 | } | 471 | } |
300 | if (0&&jitter->pointer_timestamp%1000==0) | 472 | |
473 | /* Only insert the packet if it's not hopelessly late (i.e. totally useless) */ | ||
474 | if (GE32(packet->timestamp+packet->span+jitter->delay_step, jitter->pointer_timestamp)) | ||
301 | { | 475 | { |
302 | /*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);*/ | 476 | |
303 | /*fprintf (stderr, "%f %f\n", early_ratio_short + ontime_ratio_short + late_ratio_short, early_ratio_long + ontime_ratio_long + late_ratio_long);*/ | 477 | /*Find an empty slot in the buffer*/ |
478 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) | ||
479 | { | ||
480 | if (jitter->packets[i].data==NULL) | ||
481 | break; | ||
482 | } | ||
483 | |||
484 | /*No place left in the buffer, need to make room for it by discarding the oldest packet */ | ||
485 | if (i==SPEEX_JITTER_MAX_BUFFER_SIZE) | ||
486 | { | ||
487 | int earliest=jitter->packets[0].timestamp; | ||
488 | i=0; | ||
489 | for (j=1;j<SPEEX_JITTER_MAX_BUFFER_SIZE;j++) | ||
490 | { | ||
491 | if (!jitter->packets[i].data || LT32(jitter->packets[j].timestamp,earliest)) | ||
492 | { | ||
493 | earliest = jitter->packets[j].timestamp; | ||
494 | i=j; | ||
495 | } | ||
496 | } | ||
497 | if (jitter->destroy) | ||
498 | jitter->destroy(jitter->packets[i].data); | ||
499 | else | ||
500 | speex_free(jitter->packets[i].data); | ||
501 | jitter->packets[i].data=NULL; | ||
502 | if (jitter->lost_count>20) | ||
503 | { | ||
504 | jitter_buffer_reset(jitter); | ||
505 | } | ||
506 | /*fprintf (stderr, "Buffer is full, discarding earliest frame %d (currently at %d)\n", timestamp, jitter->pointer_timestamp);*/ | ||
507 | } | ||
508 | |||
509 | /* Copy packet in buffer */ | ||
510 | if (jitter->destroy) | ||
511 | { | ||
512 | jitter->packets[i].data = packet->data; | ||
513 | } else { | ||
514 | jitter->packets[i].data=(char*)speex_alloc(packet->len); | ||
515 | for (j=0;j<packet->len;j++) | ||
516 | jitter->packets[i].data[j]=packet->data[j]; | ||
517 | } | ||
518 | jitter->packets[i].timestamp=packet->timestamp; | ||
519 | jitter->packets[i].span=packet->span; | ||
520 | jitter->packets[i].len=packet->len; | ||
521 | jitter->packets[i].user_data=packet->user_data; | ||
522 | if (late) | ||
523 | jitter->arrival[i] = 0; | ||
524 | else | ||
525 | jitter->arrival[i] = jitter->next_stop; | ||
304 | } | 526 | } |
305 | 527 | ||
306 | 528 | ||
529 | } | ||
530 | |||
531 | /** Get one packet from the jitter buffer */ | ||
532 | int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t desired_span, spx_int32_t *start_offset) | ||
533 | { | ||
534 | int i; | ||
535 | unsigned int j; | ||
536 | int incomplete = 0; | ||
537 | |||
538 | jitter->last_returned_timestamp = jitter->pointer_timestamp; | ||
539 | |||
540 | if (jitter->interp_requested) | ||
541 | { | ||
542 | jitter->interp_requested = 0; | ||
543 | if (start_offset) | ||
544 | *start_offset = 0; | ||
545 | packet->timestamp = jitter->pointer_timestamp; | ||
546 | packet->span = jitter->delay_step; | ||
547 | |||
548 | /* Increment the pointer because it got decremented in the delay update */ | ||
549 | jitter->pointer_timestamp += jitter->delay_step; | ||
550 | packet->len = 0; | ||
551 | /*fprintf (stderr, "Deferred interpolate\n");*/ | ||
552 | |||
553 | return JITTER_BUFFER_MISSING; | ||
554 | } | ||
555 | |||
307 | /* Searching for the packet that fits best */ | 556 | /* Searching for the packet that fits best */ |
308 | 557 | ||
309 | /* Search the buffer for a packet with the right timestamp and spanning the whole current chunk */ | 558 | /* Search the buffer for a packet with the right timestamp and spanning the whole current chunk */ |
310 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) | 559 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) |
311 | { | 560 | { |
312 | if (jitter->buf[i] && jitter->timestamp[i]==jitter->pointer_timestamp && GE32(jitter->timestamp[i]+jitter->span[i],jitter->pointer_timestamp+chunk_size)) | 561 | 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)) |
313 | break; | 562 | break; |
314 | } | 563 | } |
315 | 564 | ||
@@ -318,7 +567,7 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3 | |||
318 | { | 567 | { |
319 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) | 568 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) |
320 | { | 569 | { |
321 | if (jitter->buf[i] && LE32(jitter->timestamp[i], jitter->pointer_timestamp) && GE32(jitter->timestamp[i]+jitter->span[i],jitter->pointer_timestamp+chunk_size)) | 570 | 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)) |
322 | break; | 571 | break; |
323 | } | 572 | } |
324 | } | 573 | } |
@@ -328,7 +577,7 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3 | |||
328 | { | 577 | { |
329 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) | 578 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) |
330 | { | 579 | { |
331 | if (jitter->buf[i] && LE32(jitter->timestamp[i], jitter->pointer_timestamp) && GT32(jitter->timestamp[i]+jitter->span[i],jitter->pointer_timestamp)) | 580 | 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)) |
332 | break; | 581 | break; |
333 | } | 582 | } |
334 | } | 583 | } |
@@ -343,12 +592,12 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3 | |||
343 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) | 592 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) |
344 | { | 593 | { |
345 | /* check if packet starts within current chunk */ | 594 | /* check if packet starts within current chunk */ |
346 | if (jitter->buf[i] && LT32(jitter->timestamp[i],jitter->pointer_timestamp+chunk_size) && GE32(jitter->timestamp[i],jitter->pointer_timestamp)) | 595 | if (jitter->packets[i].data && LT32(jitter->packets[i].timestamp,jitter->pointer_timestamp+desired_span) && GE32(jitter->packets[i].timestamp,jitter->pointer_timestamp)) |
347 | { | 596 | { |
348 | if (!found || LT32(jitter->timestamp[i],best_time) || (jitter->timestamp[i]==best_time && GT32(jitter->span[i],best_span))) | 597 | if (!found || LT32(jitter->packets[i].timestamp,best_time) || (jitter->packets[i].timestamp==best_time && GT32(jitter->packets[i].span,best_span))) |
349 | { | 598 | { |
350 | best_time = jitter->timestamp[i]; | 599 | best_time = jitter->packets[i].timestamp; |
351 | best_span = jitter->span[i]; | 600 | best_span = jitter->packets[i].span; |
352 | besti = i; | 601 | besti = i; |
353 | found = 1; | 602 | found = 1; |
354 | } | 603 | } |
@@ -358,31 +607,62 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3 | |||
358 | { | 607 | { |
359 | i=besti; | 608 | i=besti; |
360 | incomplete = 1; | 609 | incomplete = 1; |
361 | /*fprintf (stderr, "incomplete: %d %d %d %d\n", jitter->timestamp[i], jitter->pointer_timestamp, chunk_size, jitter->span[i]);*/ | 610 | /*fprintf (stderr, "incomplete: %d %d %d %d\n", jitter->packets[i].timestamp, jitter->pointer_timestamp, chunk_size, jitter->packets[i].span);*/ |
362 | } | 611 | } |
363 | } | 612 | } |
364 | 613 | ||
365 | /* If we find something */ | 614 | /* If we find something */ |
366 | if (i!=SPEEX_JITTER_MAX_BUFFER_SIZE) | 615 | if (i!=SPEEX_JITTER_MAX_BUFFER_SIZE) |
367 | { | 616 | { |
617 | |||
618 | |||
368 | /* We (obviously) haven't lost this packet */ | 619 | /* We (obviously) haven't lost this packet */ |
369 | jitter->lost_count = 0; | 620 | jitter->lost_count = 0; |
370 | jitter->loss_rate = .999*jitter->loss_rate; | 621 | jitter->loss_rate = .999*jitter->loss_rate; |
371 | /* Check for potential overflow */ | 622 | |
372 | packet->len = jitter->len[i]; | 623 | /* In this case, 0 isn't as a valid timestamp */ |
624 | if (jitter->arrival[i] != 0) | ||
625 | { | ||
626 | spx_int32_t arrival_margin; | ||
627 | /*fprintf(stderr, "early by %d\n", jitter->packets[i].timestamp - jitter->arrival[i]);*/ | ||
628 | |||
629 | /* The arrival margin is how much in advance (or in this case late) the packet it (in resolution units) */ | ||
630 | arrival_margin = (((spx_int32_t)jitter->packets[i].timestamp) - ((spx_int32_t)jitter->arrival[i]))/jitter->resolution - jitter->buffer_margin; | ||
631 | |||
632 | /*fprintf(stderr, "get arrival_margin = %d\n", arrival_margin);*/ | ||
633 | |||
634 | /*update_timings(jitter, ((spx_int32_t)jitter->packets[i].timestamp) - ((spx_int32_t)jitter->arrival[i]));*/ | ||
635 | |||
636 | update_histogram(jitter, arrival_margin); | ||
637 | |||
638 | } | ||
639 | |||
640 | |||
641 | /* FIXME: Check for potential overflow */ | ||
642 | packet->len = jitter->packets[i].len; | ||
373 | /* Copy packet */ | 643 | /* Copy packet */ |
374 | for (j=0;j<packet->len;j++) | 644 | if (jitter->destroy) |
375 | packet->data[j] = jitter->buf[i][j]; | 645 | { |
376 | /* Remove packet */ | 646 | packet->data = jitter->packets[i].data; |
377 | speex_free(jitter->buf[i]); | 647 | } else { |
378 | jitter->buf[i] = NULL; | 648 | for (j=0;j<packet->len;j++) |
649 | packet->data[j] = jitter->packets[i].data[j]; | ||
650 | /* Remove packet */ | ||
651 | speex_free(jitter->packets[i].data); | ||
652 | } | ||
653 | jitter->packets[i].data = NULL; | ||
379 | /* Set timestamp and span (if requested) */ | 654 | /* Set timestamp and span (if requested) */ |
380 | if (start_offset) | 655 | if (start_offset) |
381 | *start_offset = (spx_int32_t)jitter->timestamp[i]-(spx_int32_t)jitter->pointer_timestamp; | 656 | *start_offset = (spx_int32_t)jitter->packets[i].timestamp-(spx_int32_t)jitter->pointer_timestamp; |
382 | packet->timestamp = jitter->timestamp[i]; | 657 | |
383 | packet->span = jitter->span[i]; | 658 | packet->timestamp = jitter->packets[i].timestamp; |
384 | /* Point at the end of the current packet */ | 659 | jitter->last_returned_timestamp = packet->timestamp; |
385 | jitter->pointer_timestamp = jitter->timestamp[i]+jitter->span[i]; | 660 | |
661 | packet->span = jitter->packets[i].span; | ||
662 | packet->user_data = jitter->packets[i].user_data; | ||
663 | /* Point to the end of the current packet */ | ||
664 | jitter->pointer_timestamp = jitter->packets[i].timestamp+jitter->packets[i].span; | ||
665 | |||
386 | if (incomplete) | 666 | if (incomplete) |
387 | return JITTER_BUFFER_INCOMPLETE; | 667 | return JITTER_BUFFER_INCOMPLETE; |
388 | else | 668 | else |
@@ -391,6 +671,7 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3 | |||
391 | 671 | ||
392 | 672 | ||
393 | /* If we haven't found anything worth returning */ | 673 | /* If we haven't found anything worth returning */ |
674 | |||
394 | /*fprintf (stderr, "not found\n");*/ | 675 | /*fprintf (stderr, "not found\n");*/ |
395 | jitter->lost_count++; | 676 | jitter->lost_count++; |
396 | /*fprintf (stderr, "m");*/ | 677 | /*fprintf (stderr, "m");*/ |
@@ -398,34 +679,71 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3 | |||
398 | jitter->loss_rate = .999*jitter->loss_rate + .001; | 679 | jitter->loss_rate = .999*jitter->loss_rate + .001; |
399 | if (start_offset) | 680 | if (start_offset) |
400 | *start_offset = 0; | 681 | *start_offset = 0; |
401 | packet->timestamp = jitter->pointer_timestamp; | ||
402 | packet->span = jitter->tick_size; | ||
403 | jitter->pointer_timestamp += chunk_size; | ||
404 | packet->len = 0; | ||
405 | 682 | ||
406 | /* Adjusting the buffering bssed on the amount of packets that are early/on time/late */ | 683 | compute_statistics(jitter); |
407 | if (late_ratio_short > .1 || late_ratio_long > .03) | 684 | |
685 | /* Should we force an increase in the buffer or just do normal interpolation? */ | ||
686 | if (jitter->late_ratio_short > .1 || jitter->late_ratio_long > .03) | ||
408 | { | 687 | { |
409 | /* If too many packets are arriving late */ | 688 | /* Increase buffering */ |
410 | jitter->shortterm_margin[MAX_MARGIN-1] += jitter->shortterm_margin[MAX_MARGIN-2]; | 689 | |
411 | jitter->longterm_margin[MAX_MARGIN-1] += jitter->longterm_margin[MAX_MARGIN-2]; | 690 | /* Shift histogram to compensate */ |
412 | for (i=MAX_MARGIN-3;i>=0;i--) | 691 | shift_histogram(jitter, jitter->res_delay_step); |
413 | { | 692 | |
414 | jitter->shortterm_margin[i+1] = jitter->shortterm_margin[i]; | 693 | packet->timestamp = jitter->pointer_timestamp; |
415 | jitter->longterm_margin[i+1] = jitter->longterm_margin[i]; | 694 | packet->span = jitter->delay_step; |
416 | } | 695 | /* Don't move the pointer_timestamp forward */ |
417 | jitter->shortterm_margin[0] = 0; | 696 | packet->len = 0; |
418 | jitter->longterm_margin[0] = 0; | 697 | |
419 | jitter->pointer_timestamp -= jitter->tick_size; | 698 | /*jitter->pointer_timestamp -= jitter->delay_step;*/ |
420 | jitter->current_timestamp -= jitter->tick_size; | 699 | /*fprintf (stderr, "Forced to interpolate\n");*/ |
421 | /*fprintf (stderr, "i");*/ | 700 | } else { |
422 | /*fprintf (stderr, "interpolate (getting some slack)\n");*/ | 701 | /* Normal packet loss */ |
702 | packet->timestamp = jitter->pointer_timestamp; | ||
703 | packet->span = desired_span; | ||
704 | jitter->pointer_timestamp += desired_span; | ||
705 | packet->len = 0; | ||
706 | /*fprintf (stderr, "Normal loss\n");*/ | ||
423 | } | 707 | } |
424 | 708 | ||
425 | return JITTER_BUFFER_MISSING; | 709 | return JITTER_BUFFER_MISSING; |
426 | 710 | ||
427 | } | 711 | } |
428 | 712 | ||
713 | int jitter_buffer_get_another(JitterBuffer *jitter, JitterBufferPacket *packet) | ||
714 | { | ||
715 | int i, j; | ||
716 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) | ||
717 | { | ||
718 | if (jitter->packets[i].data && jitter->packets[i].timestamp==jitter->last_returned_timestamp) | ||
719 | break; | ||
720 | } | ||
721 | if (i!=SPEEX_JITTER_MAX_BUFFER_SIZE) | ||
722 | { | ||
723 | /* Copy packet */ | ||
724 | packet->len = jitter->packets[i].len; | ||
725 | if (jitter->destroy) | ||
726 | { | ||
727 | packet->data = jitter->packets[i].data; | ||
728 | } else { | ||
729 | for (j=0;j<packet->len;j++) | ||
730 | packet->data[j] = jitter->packets[i].data[j]; | ||
731 | /* Remove packet */ | ||
732 | speex_free(jitter->packets[i].data); | ||
733 | } | ||
734 | jitter->packets[i].data = NULL; | ||
735 | packet->timestamp = jitter->packets[i].timestamp; | ||
736 | packet->span = jitter->packets[i].span; | ||
737 | packet->user_data = jitter->packets[i].user_data; | ||
738 | return JITTER_BUFFER_OK; | ||
739 | } else { | ||
740 | packet->data = NULL; | ||
741 | packet->len = 0; | ||
742 | packet->span = 0; | ||
743 | return JITTER_BUFFER_MISSING; | ||
744 | } | ||
745 | } | ||
746 | |||
429 | /** Get pointer timestamp of jitter buffer */ | 747 | /** Get pointer timestamp of jitter buffer */ |
430 | int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter) | 748 | int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter) |
431 | { | 749 | { |
@@ -434,81 +752,39 @@ int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter) | |||
434 | 752 | ||
435 | void jitter_buffer_tick(JitterBuffer *jitter) | 753 | void jitter_buffer_tick(JitterBuffer *jitter) |
436 | { | 754 | { |
437 | jitter->current_timestamp += jitter->tick_size; | 755 | jitter->next_stop = jitter->pointer_timestamp; |
756 | } | ||
757 | |||
758 | void jitter_buffer_remaining_span(JitterBuffer *jitter, spx_uint32_t rem) | ||
759 | { | ||
760 | jitter->next_stop = jitter->pointer_timestamp - rem; | ||
438 | } | 761 | } |
439 | 762 | ||
440 | /* Let the jitter buffer know it's the right time to adjust the buffering delay to the network conditions */ | 763 | /* Let the jitter buffer know it's the right time to adjust the buffering delay to the network conditions */ |
441 | int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset) | 764 | int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset) |
442 | { | 765 | { |
443 | int i; | 766 | int i; |
444 | float late_ratio_short; | ||
445 | float late_ratio_long; | ||
446 | float ontime_ratio_short; | ||
447 | float ontime_ratio_long; | ||
448 | float early_ratio_short; | ||
449 | float early_ratio_long; | ||
450 | 767 | ||
451 | if (LT32(jitter->current_timestamp+jitter->tick_size, jitter->pointer_timestamp)) | 768 | compute_statistics(jitter); |
452 | { | ||
453 | jitter->current_timestamp = jitter->pointer_timestamp; | ||
454 | speex_warning("did you forget to call jitter_buffer_tick() by any chance?"); | ||
455 | } | ||
456 | /*fprintf (stderr, "get packet %d %d\n", jitter->pointer_timestamp, jitter->current_timestamp);*/ | ||
457 | 769 | ||
458 | /* FIXME: This should be only what remaining of the current tick */ | ||
459 | late_ratio_short = 0; | ||
460 | late_ratio_long = 0; | ||
461 | /* Count the proportion of packets that are late */ | ||
462 | for (i=0;i<LATE_BINS;i++) | ||
463 | { | ||
464 | late_ratio_short += jitter->shortterm_margin[i]; | ||
465 | late_ratio_long += jitter->longterm_margin[i]; | ||
466 | } | ||
467 | /* Count the proportion of packets that are just on time */ | ||
468 | ontime_ratio_short = jitter->shortterm_margin[LATE_BINS]; | ||
469 | ontime_ratio_long = jitter->longterm_margin[LATE_BINS]; | ||
470 | early_ratio_short = early_ratio_long = 0; | ||
471 | /* Count the proportion of packets that are early */ | ||
472 | for (i=LATE_BINS+1;i<MAX_MARGIN;i++) | ||
473 | { | ||
474 | early_ratio_short += jitter->shortterm_margin[i]; | ||
475 | early_ratio_long += jitter->longterm_margin[i]; | ||
476 | } | ||
477 | |||
478 | /* Adjusting the buffering bssed on the amount of packets that are early/on time/late */ | 770 | /* Adjusting the buffering bssed on the amount of packets that are early/on time/late */ |
479 | if (late_ratio_short > .1 || late_ratio_long > .03) | 771 | if (jitter->late_ratio_short > .1 || jitter->late_ratio_long > .03) |
480 | { | 772 | { |
481 | /* If too many packets are arriving late */ | 773 | /* If too many packets are arriving late */ |
482 | jitter->shortterm_margin[MAX_MARGIN-1] += jitter->shortterm_margin[MAX_MARGIN-2]; | 774 | shift_histogram(jitter, jitter->res_delay_step); |
483 | jitter->longterm_margin[MAX_MARGIN-1] += jitter->longterm_margin[MAX_MARGIN-2]; | 775 | |
484 | for (i=MAX_MARGIN-3;i>=0;i--) | 776 | jitter->pointer_timestamp -= jitter->delay_step; |
485 | { | ||
486 | jitter->shortterm_margin[i+1] = jitter->shortterm_margin[i]; | ||
487 | jitter->longterm_margin[i+1] = jitter->longterm_margin[i]; | ||
488 | } | ||
489 | jitter->shortterm_margin[0] = 0; | ||
490 | jitter->longterm_margin[0] = 0; | ||
491 | jitter->pointer_timestamp -= jitter->tick_size; | ||
492 | jitter->current_timestamp -= jitter->tick_size; | ||
493 | jitter->interp_requested = 1; | 777 | jitter->interp_requested = 1; |
778 | /*fprintf (stderr, "Decision to interpolate\n");*/ | ||
494 | return JITTER_BUFFER_ADJUST_INTERPOLATE; | 779 | return JITTER_BUFFER_ADJUST_INTERPOLATE; |
495 | 780 | ||
496 | } else if (late_ratio_short + ontime_ratio_short < .005 && late_ratio_long + ontime_ratio_long < .01 && early_ratio_short > .8) | 781 | } else if (jitter->late_ratio_short + jitter->ontime_ratio_short < .005 && jitter->late_ratio_long + jitter->ontime_ratio_long < .01 && jitter->early_ratio_short > .8) |
497 | { | 782 | { |
498 | /* Many frames arriving early */ | 783 | /* Many frames arriving early */ |
499 | jitter->shortterm_margin[0] += jitter->shortterm_margin[1]; | 784 | shift_histogram(jitter, -jitter->res_delay_step); |
500 | jitter->longterm_margin[0] += jitter->longterm_margin[1]; | 785 | |
501 | for (i=1;i<MAX_MARGIN-1;i++) | 786 | jitter->pointer_timestamp += jitter->delay_step; |
502 | { | 787 | /*fprintf (stderr, "Decision to drop\n");*/ |
503 | jitter->shortterm_margin[i] = jitter->shortterm_margin[i+1]; | ||
504 | jitter->longterm_margin[i] = jitter->longterm_margin[i+1]; | ||
505 | } | ||
506 | jitter->shortterm_margin[MAX_MARGIN-1] = 0; | ||
507 | jitter->longterm_margin[MAX_MARGIN-1] = 0; | ||
508 | /*fprintf (stderr, "drop frame\n");*/ | ||
509 | /*fprintf (stderr, "d");*/ | ||
510 | jitter->pointer_timestamp += jitter->tick_size; | ||
511 | jitter->current_timestamp += jitter->tick_size; | ||
512 | return JITTER_BUFFER_ADJUST_DROP; | 788 | return JITTER_BUFFER_ADJUST_DROP; |
513 | } | 789 | } |
514 | 790 | ||
@@ -531,13 +807,26 @@ int jitter_buffer_ctl(JitterBuffer *jitter, int request, void *ptr) | |||
531 | count = 0; | 807 | count = 0; |
532 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) | 808 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) |
533 | { | 809 | { |
534 | if (jitter->buf[i] && LE32(jitter->pointer_timestamp, jitter->timestamp[i])) | 810 | if (jitter->packets[i].data && LE32(jitter->pointer_timestamp, jitter->packets[i].timestamp)) |
535 | { | 811 | { |
536 | count++; | 812 | count++; |
537 | } | 813 | } |
538 | } | 814 | } |
539 | *(spx_int32_t*)ptr = count; | 815 | *(spx_int32_t*)ptr = count; |
540 | break; | 816 | break; |
817 | case JITTER_BUFFER_SET_DESTROY_CALLBACK: | ||
818 | jitter->destroy = (void (*) (void *))ptr; | ||
819 | break; | ||
820 | case JITTER_BUFFER_GET_DESTROY_CALLBACK: | ||
821 | *(void (**) (void *))ptr = jitter->destroy; | ||
822 | break; | ||
823 | case JITTER_BUFFER_SET_DELAY_STEP: | ||
824 | jitter->delay_step = *(spx_int32_t*)ptr; | ||
825 | jitter->res_delay_step = jitter->delay_step/jitter->resolution; | ||
826 | break; | ||
827 | case JITTER_BUFFER_GET_DELAY_STEP: | ||
828 | *(spx_int32_t*)ptr = jitter->delay_step; | ||
829 | break; | ||
541 | default: | 830 | default: |
542 | speex_warning_int("Unknown jitter_buffer_ctl request: ", request); | 831 | speex_warning_int("Unknown jitter_buffer_ctl request: ", request); |
543 | return -1; | 832 | return -1; |