Alexandre Lision | 8af73cb | 2013-12-10 14:11:20 -0500 | [diff] [blame] | 1 | /* Copyright (C) 2002 Jean-Marc Valin |
| 2 | File: speex_jitter.h |
| 3 | |
| 4 | Adaptive jitter buffer for Speex |
| 5 | |
| 6 | Redistribution and use in source and binary forms, with or without |
| 7 | modification, are permitted provided that the following conditions |
| 8 | are met: |
| 9 | |
| 10 | - Redistributions of source code must retain the above copyright |
| 11 | notice, this list of conditions and the following disclaimer. |
| 12 | |
| 13 | - Redistributions in binary form must reproduce the above copyright |
| 14 | notice, this list of conditions and the following disclaimer in the |
| 15 | documentation and/or other materials provided with the distribution. |
| 16 | |
| 17 | - Neither the name of the Xiph.org Foundation nor the names of its |
| 18 | contributors may be used to endorse or promote products derived from |
| 19 | this software without specific prior written permission. |
| 20 | |
| 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 22 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 23 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 24 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR |
| 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| 26 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| 27 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| 28 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
| 29 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| 30 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| 31 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 32 | |
| 33 | */ |
| 34 | |
| 35 | /* |
| 36 | TODO: |
| 37 | - Add short-term estimate |
| 38 | - Defensive programming |
| 39 | + warn when last returned < last desired (begative buffering) |
| 40 | + warn if update_delay not called between get() and tick() or is called twice in a row |
| 41 | - Linked list structure for holding the packets instead of the current fixed-size array |
| 42 | + return memory to a pool |
| 43 | + allow pre-allocation of the pool |
| 44 | + optional max number of elements |
| 45 | - Statistics |
| 46 | + drift |
| 47 | + loss |
| 48 | + late |
| 49 | + jitter |
| 50 | + buffering delay |
| 51 | */ |
| 52 | #ifdef HAVE_CONFIG_H |
| 53 | #include "config.h" |
| 54 | #endif |
| 55 | |
| 56 | |
| 57 | #include "arch.h" |
| 58 | #include <speex/speex.h> |
| 59 | #include <speex/speex_bits.h> |
| 60 | #include <speex/speex_jitter.h> |
| 61 | #include "os_support.h" |
| 62 | |
| 63 | #ifndef NULL |
| 64 | #define NULL 0 |
| 65 | #endif |
| 66 | |
| 67 | #define SPEEX_JITTER_MAX_BUFFER_SIZE 200 /**< Maximum number of packets in jitter buffer */ |
| 68 | |
| 69 | #define TSUB(a,b) ((spx_int32_t)((a)-(b))) |
| 70 | |
| 71 | #define GT32(a,b) (((spx_int32_t)((a)-(b)))>0) |
| 72 | #define GE32(a,b) (((spx_int32_t)((a)-(b)))>=0) |
| 73 | #define LT32(a,b) (((spx_int32_t)((a)-(b)))<0) |
| 74 | #define LE32(a,b) (((spx_int32_t)((a)-(b)))<=0) |
| 75 | |
| 76 | #define ROUND_DOWN(x, step) ((x)<0 ? ((x)-(step)+1)/(step)*(step) : (x)/(step)*(step)) |
| 77 | |
| 78 | #define MAX_TIMINGS 40 |
| 79 | #define MAX_BUFFERS 3 |
| 80 | #define TOP_DELAY 40 |
| 81 | |
| 82 | /** Buffer that keeps the time of arrival of the latest packets */ |
| 83 | struct TimingBuffer { |
| 84 | int filled; /**< Number of entries occupied in "timing" and "counts"*/ |
| 85 | int curr_count; /**< Number of packet timings we got (including those we discarded) */ |
| 86 | spx_int32_t timing[MAX_TIMINGS]; /**< Sorted list of all timings ("latest" packets first) */ |
| 87 | spx_int16_t counts[MAX_TIMINGS]; /**< Order the packets were put in (will be used for short-term estimate) */ |
| 88 | }; |
| 89 | |
| 90 | static void tb_init(struct TimingBuffer *tb) |
| 91 | { |
| 92 | tb->filled = 0; |
| 93 | tb->curr_count = 0; |
| 94 | } |
| 95 | |
| 96 | /* Add the timing of a new packet to the TimingBuffer */ |
| 97 | static void tb_add(struct TimingBuffer *tb, spx_int16_t timing) |
| 98 | { |
| 99 | int pos; |
| 100 | /* Discard packet that won't make it into the list because they're too early */ |
| 101 | if (tb->filled >= MAX_TIMINGS && timing >= tb->timing[tb->filled-1]) |
| 102 | { |
| 103 | tb->curr_count++; |
| 104 | return; |
| 105 | } |
| 106 | |
| 107 | /* Find where the timing info goes in the sorted list */ |
| 108 | pos = 0; |
| 109 | /* FIXME: Do bisection instead of linear search */ |
| 110 | while (pos<tb->filled && timing >= tb->timing[pos]) |
| 111 | { |
| 112 | pos++; |
| 113 | } |
| 114 | |
| 115 | speex_assert(pos <= tb->filled && pos < MAX_TIMINGS); |
| 116 | |
| 117 | /* Shift everything so we can perform the insertion */ |
| 118 | if (pos < tb->filled) |
| 119 | { |
| 120 | int move_size = tb->filled-pos; |
| 121 | if (tb->filled == MAX_TIMINGS) |
| 122 | move_size -= 1; |
| 123 | SPEEX_MOVE(&tb->timing[pos+1], &tb->timing[pos], move_size); |
| 124 | SPEEX_MOVE(&tb->counts[pos+1], &tb->counts[pos], move_size); |
| 125 | } |
| 126 | /* Insert */ |
| 127 | tb->timing[pos] = timing; |
| 128 | tb->counts[pos] = tb->curr_count; |
| 129 | |
| 130 | tb->curr_count++; |
| 131 | if (tb->filled<MAX_TIMINGS) |
| 132 | tb->filled++; |
| 133 | } |
| 134 | |
| 135 | |
| 136 | |
| 137 | /** Jitter buffer structure */ |
| 138 | struct JitterBuffer_ { |
| 139 | spx_uint32_t pointer_timestamp; /**< Timestamp of what we will *get* next */ |
| 140 | spx_uint32_t last_returned_timestamp; /**< Useful for getting the next packet with the same timestamp (for fragmented media) */ |
| 141 | spx_uint32_t next_stop; /**< Estimated time the next get() will be called */ |
| 142 | |
| 143 | spx_int32_t buffered; /**< Amount of data we think is still buffered by the application (timestamp units)*/ |
| 144 | |
| 145 | JitterBufferPacket packets[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Packets stored in the buffer */ |
| 146 | spx_uint32_t arrival[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Packet arrival time (0 means it was late, even though it's a valid timestamp) */ |
| 147 | |
| 148 | void (*destroy) (void *); /**< Callback for destroying a packet */ |
| 149 | |
| 150 | spx_int32_t delay_step; /**< Size of the steps when adjusting buffering (timestamp units) */ |
| 151 | spx_int32_t concealment_size; /**< Size of the packet loss concealment "units" */ |
| 152 | int reset_state; /**< True if state was just reset */ |
| 153 | int buffer_margin; /**< How many frames we want to keep in the buffer (lower bound) */ |
| 154 | int late_cutoff; /**< How late must a packet be for it not to be considered at all */ |
| 155 | int interp_requested; /**< An interpolation is requested by speex_jitter_update_delay() */ |
| 156 | int auto_adjust; /**< Whether to automatically adjust the delay at any time */ |
| 157 | |
| 158 | struct TimingBuffer _tb[MAX_BUFFERS]; /**< Don't use those directly */ |
| 159 | struct TimingBuffer *timeBuffers[MAX_BUFFERS]; /**< Storing arrival time of latest frames so we can compute some stats */ |
| 160 | int window_size; /**< Total window over which the late frames are counted */ |
| 161 | int subwindow_size; /**< Sub-window size for faster computation */ |
| 162 | int max_late_rate; /**< Absolute maximum amount of late packets tolerable (in percent) */ |
| 163 | int latency_tradeoff; /**< Latency equivalent of losing one percent of packets */ |
| 164 | int auto_tradeoff; /**< Latency equivalent of losing one percent of packets (automatic default) */ |
| 165 | |
| 166 | int lost_count; /**< Number of consecutive lost packets */ |
| 167 | }; |
| 168 | |
| 169 | /** Based on available data, this computes the optimal delay for the jitter buffer. |
| 170 | The optimised function is in timestamp units and is: |
| 171 | cost = delay + late_factor*[number of frames that would be late if we used that delay] |
| 172 | @param tb Array of buffers |
| 173 | @param late_factor Equivalent cost of a late frame (in timestamp units) |
| 174 | */ |
| 175 | static spx_int16_t compute_opt_delay(JitterBuffer *jitter) |
| 176 | { |
| 177 | int i; |
| 178 | spx_int16_t opt=0; |
| 179 | spx_int32_t best_cost=0x7fffffff; |
| 180 | int late = 0; |
| 181 | int pos[MAX_BUFFERS]; |
| 182 | int tot_count; |
| 183 | float late_factor; |
| 184 | int penalty_taken = 0; |
| 185 | int best = 0; |
| 186 | int worst = 0; |
| 187 | spx_int32_t deltaT; |
| 188 | struct TimingBuffer *tb; |
| 189 | |
| 190 | tb = jitter->_tb; |
| 191 | |
| 192 | /* Number of packet timings we have received (including those we didn't keep) */ |
| 193 | tot_count = 0; |
| 194 | for (i=0;i<MAX_BUFFERS;i++) |
| 195 | tot_count += tb[i].curr_count; |
| 196 | if (tot_count==0) |
| 197 | return 0; |
| 198 | |
| 199 | /* Compute cost for one lost packet */ |
| 200 | if (jitter->latency_tradeoff != 0) |
| 201 | late_factor = jitter->latency_tradeoff * 100.0f / tot_count; |
| 202 | else |
| 203 | late_factor = jitter->auto_tradeoff * jitter->window_size/tot_count; |
| 204 | |
| 205 | /*fprintf(stderr, "late_factor = %f\n", late_factor);*/ |
| 206 | for (i=0;i<MAX_BUFFERS;i++) |
| 207 | pos[i] = 0; |
| 208 | |
| 209 | /* Pick the TOP_DELAY "latest" packets (doesn't need to actually be late |
| 210 | for the current settings) */ |
| 211 | for (i=0;i<TOP_DELAY;i++) |
| 212 | { |
| 213 | int j; |
| 214 | int next=-1; |
| 215 | int latest = 32767; |
| 216 | /* Pick latest amoung all sub-windows */ |
| 217 | for (j=0;j<MAX_BUFFERS;j++) |
| 218 | { |
| 219 | if (pos[j] < tb[j].filled && tb[j].timing[pos[j]] < latest) |
| 220 | { |
| 221 | next = j; |
| 222 | latest = tb[j].timing[pos[j]]; |
| 223 | } |
| 224 | } |
| 225 | if (next != -1) |
| 226 | { |
| 227 | spx_int32_t cost; |
| 228 | |
| 229 | if (i==0) |
| 230 | worst = latest; |
| 231 | best = latest; |
| 232 | latest = ROUND_DOWN(latest, jitter->delay_step); |
| 233 | pos[next]++; |
| 234 | |
| 235 | /* Actual cost function that tells us how bad using this delay would be */ |
| 236 | cost = -latest + late_factor*late; |
| 237 | /*fprintf(stderr, "cost %d = %d + %f * %d\n", cost, -latest, late_factor, late);*/ |
| 238 | if (cost < best_cost) |
| 239 | { |
| 240 | best_cost = cost; |
| 241 | opt = latest; |
| 242 | } |
| 243 | } else { |
| 244 | break; |
| 245 | } |
| 246 | |
| 247 | /* For the next timing we will consider, there will be one more late packet to count */ |
| 248 | late++; |
| 249 | /* Two-frame penalty if we're going to increase the amount of late frames (hysteresis) */ |
| 250 | if (latest >= 0 && !penalty_taken) |
| 251 | { |
| 252 | penalty_taken = 1; |
| 253 | late+=4; |
| 254 | } |
| 255 | } |
| 256 | |
| 257 | deltaT = best-worst; |
| 258 | /* This is a default "automatic latency tradeoff" when none is provided */ |
| 259 | jitter->auto_tradeoff = 1 + deltaT/TOP_DELAY; |
| 260 | /*fprintf(stderr, "auto_tradeoff = %d (%d %d %d)\n", jitter->auto_tradeoff, best, worst, i);*/ |
| 261 | |
| 262 | /* FIXME: Compute a short-term estimate too and combine with the long-term one */ |
| 263 | |
| 264 | /* Prevents reducing the buffer size when we haven't really had much data */ |
| 265 | if (tot_count < TOP_DELAY && opt > 0) |
| 266 | return 0; |
| 267 | return opt; |
| 268 | } |
| 269 | |
| 270 | |
| 271 | /** Initialise jitter buffer */ |
| 272 | EXPORT JitterBuffer *jitter_buffer_init(int step_size) |
| 273 | { |
| 274 | JitterBuffer *jitter = (JitterBuffer*)speex_alloc(sizeof(JitterBuffer)); |
| 275 | if (jitter) |
| 276 | { |
| 277 | int i; |
| 278 | spx_int32_t tmp; |
| 279 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) |
| 280 | jitter->packets[i].data=NULL; |
| 281 | jitter->delay_step = step_size; |
| 282 | jitter->concealment_size = step_size; |
| 283 | /*FIXME: Should this be 0 or 1?*/ |
| 284 | jitter->buffer_margin = 0; |
| 285 | jitter->late_cutoff = 50; |
| 286 | jitter->destroy = NULL; |
| 287 | jitter->latency_tradeoff = 0; |
| 288 | jitter->auto_adjust = 1; |
| 289 | tmp = 4; |
| 290 | jitter_buffer_ctl(jitter, JITTER_BUFFER_SET_MAX_LATE_RATE, &tmp); |
| 291 | jitter_buffer_reset(jitter); |
| 292 | } |
| 293 | return jitter; |
| 294 | } |
| 295 | |
| 296 | /** Reset jitter buffer */ |
| 297 | EXPORT void jitter_buffer_reset(JitterBuffer *jitter) |
| 298 | { |
| 299 | int i; |
| 300 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) |
| 301 | { |
| 302 | if (jitter->packets[i].data) |
| 303 | { |
| 304 | if (jitter->destroy) |
| 305 | jitter->destroy(jitter->packets[i].data); |
| 306 | else |
| 307 | speex_free(jitter->packets[i].data); |
| 308 | jitter->packets[i].data = NULL; |
| 309 | } |
| 310 | } |
| 311 | /* Timestamp is actually undefined at this point */ |
| 312 | jitter->pointer_timestamp = 0; |
| 313 | jitter->next_stop = 0; |
| 314 | jitter->reset_state = 1; |
| 315 | jitter->lost_count = 0; |
| 316 | jitter->buffered = 0; |
| 317 | jitter->auto_tradeoff = 32000; |
| 318 | |
| 319 | for (i=0;i<MAX_BUFFERS;i++) |
| 320 | { |
| 321 | tb_init(&jitter->_tb[i]); |
| 322 | jitter->timeBuffers[i] = &jitter->_tb[i]; |
| 323 | } |
| 324 | /*fprintf (stderr, "reset\n");*/ |
| 325 | } |
| 326 | |
| 327 | /** Destroy jitter buffer */ |
| 328 | EXPORT void jitter_buffer_destroy(JitterBuffer *jitter) |
| 329 | { |
| 330 | jitter_buffer_reset(jitter); |
| 331 | speex_free(jitter); |
| 332 | } |
| 333 | |
| 334 | /** Take the following timing into consideration for future calculations */ |
| 335 | static void update_timings(JitterBuffer *jitter, spx_int32_t timing) |
| 336 | { |
| 337 | if (timing < -32767) |
| 338 | timing = -32767; |
| 339 | if (timing > 32767) |
| 340 | timing = 32767; |
| 341 | /* If the current sub-window is full, perform a rotation and discard oldest sub-widow */ |
| 342 | if (jitter->timeBuffers[0]->curr_count >= jitter->subwindow_size) |
| 343 | { |
| 344 | int i; |
| 345 | /*fprintf(stderr, "Rotate buffer\n");*/ |
| 346 | struct TimingBuffer *tmp = jitter->timeBuffers[MAX_BUFFERS-1]; |
| 347 | for (i=MAX_BUFFERS-1;i>=1;i--) |
| 348 | jitter->timeBuffers[i] = jitter->timeBuffers[i-1]; |
| 349 | jitter->timeBuffers[0] = tmp; |
| 350 | tb_init(jitter->timeBuffers[0]); |
| 351 | } |
| 352 | tb_add(jitter->timeBuffers[0], timing); |
| 353 | } |
| 354 | |
| 355 | /** Compensate all timings when we do an adjustment of the buffering */ |
| 356 | static void shift_timings(JitterBuffer *jitter, spx_int16_t amount) |
| 357 | { |
| 358 | int i, j; |
| 359 | for (i=0;i<MAX_BUFFERS;i++) |
| 360 | { |
| 361 | for (j=0;j<jitter->timeBuffers[i]->filled;j++) |
| 362 | jitter->timeBuffers[i]->timing[j] += amount; |
| 363 | } |
| 364 | } |
| 365 | |
| 366 | |
| 367 | /** Put one packet into the jitter buffer */ |
| 368 | EXPORT void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet) |
| 369 | { |
| 370 | int i,j; |
| 371 | int late; |
| 372 | /*fprintf (stderr, "put packet %d %d\n", timestamp, span);*/ |
| 373 | |
| 374 | /* Cleanup buffer (remove old packets that weren't played) */ |
| 375 | if (!jitter->reset_state) |
| 376 | { |
| 377 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) |
| 378 | { |
| 379 | /* Make sure we don't discard a "just-late" packet in case we want to play it next (if we interpolate). */ |
| 380 | if (jitter->packets[i].data && LE32(jitter->packets[i].timestamp + jitter->packets[i].span, jitter->pointer_timestamp)) |
| 381 | { |
| 382 | /*fprintf (stderr, "cleaned (not played)\n");*/ |
| 383 | if (jitter->destroy) |
| 384 | jitter->destroy(jitter->packets[i].data); |
| 385 | else |
| 386 | speex_free(jitter->packets[i].data); |
| 387 | jitter->packets[i].data = NULL; |
| 388 | } |
| 389 | } |
| 390 | } |
| 391 | |
| 392 | /*fprintf(stderr, "arrival: %d %d %d\n", packet->timestamp, jitter->next_stop, jitter->pointer_timestamp);*/ |
| 393 | /* Check if packet is late (could still be useful though) */ |
| 394 | if (!jitter->reset_state && LT32(packet->timestamp, jitter->next_stop)) |
| 395 | { |
| 396 | update_timings(jitter, ((spx_int32_t)packet->timestamp) - ((spx_int32_t)jitter->next_stop) - jitter->buffer_margin); |
| 397 | late = 1; |
| 398 | } else { |
| 399 | late = 0; |
| 400 | } |
| 401 | |
| 402 | /* For some reason, the consumer has failed the last 20 fetches. Make sure this packet is |
| 403 | * used to resync. */ |
| 404 | if (jitter->lost_count>20) |
| 405 | { |
| 406 | jitter_buffer_reset(jitter); |
| 407 | } |
| 408 | |
| 409 | /* Only insert the packet if it's not hopelessly late (i.e. totally useless) */ |
| 410 | if (jitter->reset_state || GE32(packet->timestamp+packet->span+jitter->delay_step, jitter->pointer_timestamp)) |
| 411 | { |
| 412 | |
| 413 | /*Find an empty slot in the buffer*/ |
| 414 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) |
| 415 | { |
| 416 | if (jitter->packets[i].data==NULL) |
| 417 | break; |
| 418 | } |
| 419 | |
| 420 | /*No place left in the buffer, need to make room for it by discarding the oldest packet */ |
| 421 | if (i==SPEEX_JITTER_MAX_BUFFER_SIZE) |
| 422 | { |
| 423 | int earliest=jitter->packets[0].timestamp; |
| 424 | i=0; |
| 425 | for (j=1;j<SPEEX_JITTER_MAX_BUFFER_SIZE;j++) |
| 426 | { |
| 427 | if (!jitter->packets[i].data || LT32(jitter->packets[j].timestamp,earliest)) |
| 428 | { |
| 429 | earliest = jitter->packets[j].timestamp; |
| 430 | i=j; |
| 431 | } |
| 432 | } |
| 433 | if (jitter->destroy) |
| 434 | jitter->destroy(jitter->packets[i].data); |
| 435 | else |
| 436 | speex_free(jitter->packets[i].data); |
| 437 | jitter->packets[i].data=NULL; |
| 438 | /*fprintf (stderr, "Buffer is full, discarding earliest frame %d (currently at %d)\n", timestamp, jitter->pointer_timestamp);*/ |
| 439 | } |
| 440 | |
| 441 | /* Copy packet in buffer */ |
| 442 | if (jitter->destroy) |
| 443 | { |
| 444 | jitter->packets[i].data = packet->data; |
| 445 | } else { |
| 446 | jitter->packets[i].data=(char*)speex_alloc(packet->len); |
| 447 | for (j=0;j<packet->len;j++) |
| 448 | jitter->packets[i].data[j]=packet->data[j]; |
| 449 | } |
| 450 | jitter->packets[i].timestamp=packet->timestamp; |
| 451 | jitter->packets[i].span=packet->span; |
| 452 | jitter->packets[i].len=packet->len; |
| 453 | jitter->packets[i].sequence=packet->sequence; |
| 454 | jitter->packets[i].user_data=packet->user_data; |
| 455 | if (jitter->reset_state || late) |
| 456 | jitter->arrival[i] = 0; |
| 457 | else |
| 458 | jitter->arrival[i] = jitter->next_stop; |
| 459 | } |
| 460 | |
| 461 | |
| 462 | } |
| 463 | |
| 464 | /** Get one packet from the jitter buffer */ |
| 465 | EXPORT int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t desired_span, spx_int32_t *start_offset) |
| 466 | { |
| 467 | int i; |
| 468 | unsigned int j; |
| 469 | int incomplete = 0; |
| 470 | spx_int16_t opt; |
| 471 | |
| 472 | if (start_offset != NULL) |
| 473 | *start_offset = 0; |
| 474 | |
| 475 | /* Syncing on the first call */ |
| 476 | if (jitter->reset_state) |
| 477 | { |
| 478 | int found = 0; |
| 479 | /* Find the oldest packet */ |
| 480 | spx_uint32_t oldest=0; |
| 481 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) |
| 482 | { |
| 483 | if (jitter->packets[i].data && (!found || LT32(jitter->packets[i].timestamp,oldest))) |
| 484 | { |
| 485 | oldest = jitter->packets[i].timestamp; |
| 486 | found = 1; |
| 487 | } |
| 488 | } |
| 489 | if (found) |
| 490 | { |
| 491 | jitter->reset_state=0; |
| 492 | jitter->pointer_timestamp = oldest; |
| 493 | jitter->next_stop = oldest; |
| 494 | } else { |
| 495 | packet->timestamp = 0; |
| 496 | packet->span = jitter->interp_requested; |
| 497 | return JITTER_BUFFER_MISSING; |
| 498 | } |
| 499 | } |
| 500 | |
| 501 | |
| 502 | jitter->last_returned_timestamp = jitter->pointer_timestamp; |
| 503 | |
| 504 | if (jitter->interp_requested != 0) |
| 505 | { |
| 506 | packet->timestamp = jitter->pointer_timestamp; |
| 507 | packet->span = jitter->interp_requested; |
| 508 | |
| 509 | /* Increment the pointer because it got decremented in the delay update */ |
| 510 | jitter->pointer_timestamp += jitter->interp_requested; |
| 511 | packet->len = 0; |
| 512 | /*fprintf (stderr, "Deferred interpolate\n");*/ |
| 513 | |
| 514 | jitter->interp_requested = 0; |
| 515 | |
| 516 | jitter->buffered = packet->span - desired_span; |
| 517 | |
| 518 | return JITTER_BUFFER_INSERTION; |
| 519 | } |
| 520 | |
| 521 | /* Searching for the packet that fits best */ |
| 522 | |
| 523 | /* Search the buffer for a packet with the right timestamp and spanning the whole current chunk */ |
| 524 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) |
| 525 | { |
| 526 | 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)) |
| 527 | break; |
| 528 | } |
| 529 | |
| 530 | /* If no match, try for an "older" packet that still spans (fully) the current chunk */ |
| 531 | if (i==SPEEX_JITTER_MAX_BUFFER_SIZE) |
| 532 | { |
| 533 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) |
| 534 | { |
| 535 | 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)) |
| 536 | break; |
| 537 | } |
| 538 | } |
| 539 | |
| 540 | /* If still no match, try for an "older" packet that spans part of the current chunk */ |
| 541 | if (i==SPEEX_JITTER_MAX_BUFFER_SIZE) |
| 542 | { |
| 543 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) |
| 544 | { |
| 545 | 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)) |
| 546 | break; |
| 547 | } |
| 548 | } |
| 549 | |
| 550 | /* If still no match, try for earliest packet possible */ |
| 551 | if (i==SPEEX_JITTER_MAX_BUFFER_SIZE) |
| 552 | { |
| 553 | int found = 0; |
| 554 | spx_uint32_t best_time=0; |
| 555 | int best_span=0; |
| 556 | int besti=0; |
| 557 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) |
| 558 | { |
| 559 | /* check if packet starts within current chunk */ |
| 560 | if (jitter->packets[i].data && LT32(jitter->packets[i].timestamp,jitter->pointer_timestamp+desired_span) && GE32(jitter->packets[i].timestamp,jitter->pointer_timestamp)) |
| 561 | { |
| 562 | if (!found || LT32(jitter->packets[i].timestamp,best_time) || (jitter->packets[i].timestamp==best_time && GT32(jitter->packets[i].span,best_span))) |
| 563 | { |
| 564 | best_time = jitter->packets[i].timestamp; |
| 565 | best_span = jitter->packets[i].span; |
| 566 | besti = i; |
| 567 | found = 1; |
| 568 | } |
| 569 | } |
| 570 | } |
| 571 | if (found) |
| 572 | { |
| 573 | i=besti; |
| 574 | incomplete = 1; |
| 575 | /*fprintf (stderr, "incomplete: %d %d %d %d\n", jitter->packets[i].timestamp, jitter->pointer_timestamp, chunk_size, jitter->packets[i].span);*/ |
| 576 | } |
| 577 | } |
| 578 | |
| 579 | /* If we find something */ |
| 580 | if (i!=SPEEX_JITTER_MAX_BUFFER_SIZE) |
| 581 | { |
| 582 | spx_int32_t offset; |
| 583 | |
| 584 | /* We (obviously) haven't lost this packet */ |
| 585 | jitter->lost_count = 0; |
| 586 | |
| 587 | /* In this case, 0 isn't as a valid timestamp */ |
| 588 | if (jitter->arrival[i] != 0) |
| 589 | { |
| 590 | update_timings(jitter, ((spx_int32_t)jitter->packets[i].timestamp) - ((spx_int32_t)jitter->arrival[i]) - jitter->buffer_margin); |
| 591 | } |
| 592 | |
| 593 | |
| 594 | /* Copy packet */ |
| 595 | if (jitter->destroy) |
| 596 | { |
| 597 | packet->data = jitter->packets[i].data; |
| 598 | packet->len = jitter->packets[i].len; |
| 599 | } else { |
| 600 | if (jitter->packets[i].len > packet->len) |
| 601 | { |
| 602 | speex_warning_int("jitter_buffer_get(): packet too large to fit. Size is", jitter->packets[i].len); |
| 603 | } else { |
| 604 | packet->len = jitter->packets[i].len; |
| 605 | } |
| 606 | for (j=0;j<packet->len;j++) |
| 607 | packet->data[j] = jitter->packets[i].data[j]; |
| 608 | /* Remove packet */ |
| 609 | speex_free(jitter->packets[i].data); |
| 610 | } |
| 611 | jitter->packets[i].data = NULL; |
| 612 | /* Set timestamp and span (if requested) */ |
| 613 | offset = (spx_int32_t)jitter->packets[i].timestamp-(spx_int32_t)jitter->pointer_timestamp; |
| 614 | if (start_offset != NULL) |
| 615 | *start_offset = offset; |
| 616 | else if (offset != 0) |
| 617 | speex_warning_int("jitter_buffer_get() discarding non-zero start_offset", offset); |
| 618 | |
| 619 | packet->timestamp = jitter->packets[i].timestamp; |
| 620 | jitter->last_returned_timestamp = packet->timestamp; |
| 621 | |
| 622 | packet->span = jitter->packets[i].span; |
| 623 | packet->sequence = jitter->packets[i].sequence; |
| 624 | packet->user_data = jitter->packets[i].user_data; |
| 625 | /* Point to the end of the current packet */ |
| 626 | jitter->pointer_timestamp = jitter->packets[i].timestamp+jitter->packets[i].span; |
| 627 | |
| 628 | jitter->buffered = packet->span - desired_span; |
| 629 | |
| 630 | if (start_offset != NULL) |
| 631 | jitter->buffered += *start_offset; |
| 632 | |
| 633 | return JITTER_BUFFER_OK; |
| 634 | } |
| 635 | |
| 636 | |
| 637 | /* If we haven't found anything worth returning */ |
| 638 | |
| 639 | /*fprintf (stderr, "not found\n");*/ |
| 640 | jitter->lost_count++; |
| 641 | /*fprintf (stderr, "m");*/ |
| 642 | /*fprintf (stderr, "lost_count = %d\n", jitter->lost_count);*/ |
| 643 | |
| 644 | opt = compute_opt_delay(jitter); |
| 645 | |
| 646 | /* Should we force an increase in the buffer or just do normal interpolation? */ |
| 647 | if (opt < 0) |
| 648 | { |
| 649 | /* Need to increase buffering */ |
| 650 | |
| 651 | /* Shift histogram to compensate */ |
| 652 | shift_timings(jitter, -opt); |
| 653 | |
| 654 | packet->timestamp = jitter->pointer_timestamp; |
| 655 | packet->span = -opt; |
| 656 | /* Don't move the pointer_timestamp forward */ |
| 657 | packet->len = 0; |
| 658 | |
| 659 | jitter->buffered = packet->span - desired_span; |
| 660 | return JITTER_BUFFER_INSERTION; |
| 661 | /*jitter->pointer_timestamp -= jitter->delay_step;*/ |
| 662 | /*fprintf (stderr, "Forced to interpolate\n");*/ |
| 663 | } else { |
| 664 | /* Normal packet loss */ |
| 665 | packet->timestamp = jitter->pointer_timestamp; |
| 666 | |
| 667 | desired_span = ROUND_DOWN(desired_span, jitter->concealment_size); |
| 668 | packet->span = desired_span; |
| 669 | jitter->pointer_timestamp += desired_span; |
| 670 | packet->len = 0; |
| 671 | |
| 672 | jitter->buffered = packet->span - desired_span; |
| 673 | return JITTER_BUFFER_MISSING; |
| 674 | /*fprintf (stderr, "Normal loss\n");*/ |
| 675 | } |
| 676 | |
| 677 | |
| 678 | } |
| 679 | |
| 680 | EXPORT int jitter_buffer_get_another(JitterBuffer *jitter, JitterBufferPacket *packet) |
| 681 | { |
| 682 | int i, j; |
| 683 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) |
| 684 | { |
| 685 | if (jitter->packets[i].data && jitter->packets[i].timestamp==jitter->last_returned_timestamp) |
| 686 | break; |
| 687 | } |
| 688 | if (i!=SPEEX_JITTER_MAX_BUFFER_SIZE) |
| 689 | { |
| 690 | /* Copy packet */ |
| 691 | packet->len = jitter->packets[i].len; |
| 692 | if (jitter->destroy) |
| 693 | { |
| 694 | packet->data = jitter->packets[i].data; |
| 695 | } else { |
| 696 | for (j=0;j<packet->len;j++) |
| 697 | packet->data[j] = jitter->packets[i].data[j]; |
| 698 | /* Remove packet */ |
| 699 | speex_free(jitter->packets[i].data); |
| 700 | } |
| 701 | jitter->packets[i].data = NULL; |
| 702 | packet->timestamp = jitter->packets[i].timestamp; |
| 703 | packet->span = jitter->packets[i].span; |
| 704 | packet->sequence = jitter->packets[i].sequence; |
| 705 | packet->user_data = jitter->packets[i].user_data; |
| 706 | return JITTER_BUFFER_OK; |
| 707 | } else { |
| 708 | packet->data = NULL; |
| 709 | packet->len = 0; |
| 710 | packet->span = 0; |
| 711 | return JITTER_BUFFER_MISSING; |
| 712 | } |
| 713 | } |
| 714 | |
| 715 | /* Let the jitter buffer know it's the right time to adjust the buffering delay to the network conditions */ |
| 716 | static int _jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset) |
| 717 | { |
| 718 | spx_int16_t opt = compute_opt_delay(jitter); |
| 719 | /*fprintf(stderr, "opt adjustment is %d ", opt);*/ |
| 720 | |
| 721 | if (opt < 0) |
| 722 | { |
| 723 | shift_timings(jitter, -opt); |
| 724 | |
| 725 | jitter->pointer_timestamp += opt; |
| 726 | jitter->interp_requested = -opt; |
| 727 | /*fprintf (stderr, "Decision to interpolate %d samples\n", -opt);*/ |
| 728 | } else if (opt > 0) |
| 729 | { |
| 730 | shift_timings(jitter, -opt); |
| 731 | jitter->pointer_timestamp += opt; |
| 732 | /*fprintf (stderr, "Decision to drop %d samples\n", opt);*/ |
| 733 | } |
| 734 | |
| 735 | return opt; |
| 736 | } |
| 737 | |
| 738 | /* Let the jitter buffer know it's the right time to adjust the buffering delay to the network conditions */ |
| 739 | EXPORT int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset) |
| 740 | { |
| 741 | /* If the programmer calls jitter_buffer_update_delay() directly, |
| 742 | automatically disable auto-adjustment */ |
| 743 | jitter->auto_adjust = 0; |
| 744 | |
| 745 | return _jitter_buffer_update_delay(jitter, packet, start_offset); |
| 746 | } |
| 747 | |
| 748 | /** Get pointer timestamp of jitter buffer */ |
| 749 | EXPORT int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter) |
| 750 | { |
| 751 | return jitter->pointer_timestamp; |
| 752 | } |
| 753 | |
| 754 | EXPORT void jitter_buffer_tick(JitterBuffer *jitter) |
| 755 | { |
| 756 | /* Automatically-adjust the buffering delay if requested */ |
| 757 | if (jitter->auto_adjust) |
| 758 | _jitter_buffer_update_delay(jitter, NULL, NULL); |
| 759 | |
| 760 | if (jitter->buffered >= 0) |
| 761 | { |
| 762 | jitter->next_stop = jitter->pointer_timestamp - jitter->buffered; |
| 763 | } else { |
| 764 | jitter->next_stop = jitter->pointer_timestamp; |
| 765 | speex_warning_int("jitter buffer sees negative buffering, your code might be broken. Value is ", jitter->buffered); |
| 766 | } |
| 767 | jitter->buffered = 0; |
| 768 | } |
| 769 | |
| 770 | EXPORT void jitter_buffer_remaining_span(JitterBuffer *jitter, spx_uint32_t rem) |
| 771 | { |
| 772 | /* Automatically-adjust the buffering delay if requested */ |
| 773 | if (jitter->auto_adjust) |
| 774 | _jitter_buffer_update_delay(jitter, NULL, NULL); |
| 775 | |
| 776 | if (jitter->buffered < 0) |
| 777 | speex_warning_int("jitter buffer sees negative buffering, your code might be broken. Value is ", jitter->buffered); |
| 778 | jitter->next_stop = jitter->pointer_timestamp - rem; |
| 779 | } |
| 780 | |
| 781 | |
| 782 | /* Used like the ioctl function to control the jitter buffer parameters */ |
| 783 | EXPORT int jitter_buffer_ctl(JitterBuffer *jitter, int request, void *ptr) |
| 784 | { |
| 785 | int count, i; |
| 786 | switch(request) |
| 787 | { |
| 788 | case JITTER_BUFFER_SET_MARGIN: |
| 789 | jitter->buffer_margin = *(spx_int32_t*)ptr; |
| 790 | break; |
| 791 | case JITTER_BUFFER_GET_MARGIN: |
| 792 | *(spx_int32_t*)ptr = jitter->buffer_margin; |
| 793 | break; |
| 794 | case JITTER_BUFFER_GET_AVALIABLE_COUNT: |
| 795 | count = 0; |
| 796 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) |
| 797 | { |
| 798 | if (jitter->packets[i].data && LE32(jitter->pointer_timestamp, jitter->packets[i].timestamp)) |
| 799 | { |
| 800 | count++; |
| 801 | } |
| 802 | } |
| 803 | *(spx_int32_t*)ptr = count; |
| 804 | break; |
| 805 | case JITTER_BUFFER_SET_DESTROY_CALLBACK: |
| 806 | jitter->destroy = (void (*) (void *))ptr; |
| 807 | break; |
| 808 | case JITTER_BUFFER_GET_DESTROY_CALLBACK: |
| 809 | *(void (**) (void *))ptr = jitter->destroy; |
| 810 | break; |
| 811 | case JITTER_BUFFER_SET_DELAY_STEP: |
| 812 | jitter->delay_step = *(spx_int32_t*)ptr; |
| 813 | break; |
| 814 | case JITTER_BUFFER_GET_DELAY_STEP: |
| 815 | *(spx_int32_t*)ptr = jitter->delay_step; |
| 816 | break; |
| 817 | case JITTER_BUFFER_SET_CONCEALMENT_SIZE: |
| 818 | jitter->concealment_size = *(spx_int32_t*)ptr; |
| 819 | break; |
| 820 | case JITTER_BUFFER_GET_CONCEALMENT_SIZE: |
| 821 | *(spx_int32_t*)ptr = jitter->concealment_size; |
| 822 | break; |
| 823 | case JITTER_BUFFER_SET_MAX_LATE_RATE: |
| 824 | jitter->max_late_rate = *(spx_int32_t*)ptr; |
| 825 | jitter->window_size = 100*TOP_DELAY/jitter->max_late_rate; |
| 826 | jitter->subwindow_size = jitter->window_size/MAX_BUFFERS; |
| 827 | break; |
| 828 | case JITTER_BUFFER_GET_MAX_LATE_RATE: |
| 829 | *(spx_int32_t*)ptr = jitter->max_late_rate; |
| 830 | break; |
| 831 | case JITTER_BUFFER_SET_LATE_COST: |
| 832 | jitter->latency_tradeoff = *(spx_int32_t*)ptr; |
| 833 | break; |
| 834 | case JITTER_BUFFER_GET_LATE_COST: |
| 835 | *(spx_int32_t*)ptr = jitter->latency_tradeoff; |
| 836 | break; |
| 837 | default: |
| 838 | speex_warning_int("Unknown jitter_buffer_ctl request: ", request); |
| 839 | return -1; |
| 840 | } |
| 841 | return 0; |
| 842 | } |
| 843 | |