summaryrefslogtreecommitdiff
path: root/apps/codecs/libspeex/jitter.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/libspeex/jitter.c')
-rw-r--r--apps/codecs/libspeex/jitter.c194
1 files changed, 124 insertions, 70 deletions
diff --git a/apps/codecs/libspeex/jitter.c b/apps/codecs/libspeex/jitter.c
index 710e36272c..61bca75ce8 100644
--- a/apps/codecs/libspeex/jitter.c
+++ b/apps/codecs/libspeex/jitter.c
@@ -120,8 +120,8 @@ static void tb_add(struct TimingBuffer *tb, spx_int16_t timing)
120 int move_size = tb->filled-pos; 120 int move_size = tb->filled-pos;
121 if (tb->filled == MAX_TIMINGS) 121 if (tb->filled == MAX_TIMINGS)
122 move_size -= 1; 122 move_size -= 1;
123 speex_move(&tb->timing[pos+1], &tb->timing[pos], move_size*sizeof(tb->timing[0])); 123 SPEEX_COPY(&tb->timing[pos+1], &tb->timing[pos], move_size);
124 speex_move(&tb->counts[pos+1], &tb->counts[pos], move_size*sizeof(tb->counts[0])); 124 SPEEX_COPY(&tb->counts[pos+1], &tb->counts[pos], move_size);
125 } 125 }
126 /* Insert */ 126 /* Insert */
127 tb->timing[pos] = timing; 127 tb->timing[pos] = timing;
@@ -153,7 +153,8 @@ struct JitterBuffer_ {
153 int buffer_margin; /**< How many frames we want to keep in the buffer (lower bound) */ 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 */ 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() */ 155 int interp_requested; /**< An interpolation is requested by speex_jitter_update_delay() */
156 156 int auto_adjust; /**< Whether to automatically adjust the delay at any time */
157
157 struct TimingBuffer _tb[MAX_BUFFERS]; /**< Don't use those directly */ 158 struct TimingBuffer _tb[MAX_BUFFERS]; /**< Don't use those directly */
158 struct TimingBuffer *timeBuffers[MAX_BUFFERS]; /**< Storing arrival time of latest frames so we can compute some stats */ 159 struct TimingBuffer *timeBuffers[MAX_BUFFERS]; /**< Storing arrival time of latest frames so we can compute some stats */
159 int window_size; /**< Total window over which the late frames are counted */ 160 int window_size; /**< Total window over which the late frames are counted */
@@ -268,7 +269,7 @@ static spx_int16_t compute_opt_delay(JitterBuffer *jitter)
268 269
269 270
270/** Initialise jitter buffer */ 271/** Initialise jitter buffer */
271JitterBuffer *jitter_buffer_init(void) 272JitterBuffer *jitter_buffer_init(int step_size)
272{ 273{
273 JitterBuffer *jitter = (JitterBuffer*)speex_alloc(sizeof(JitterBuffer)); 274 JitterBuffer *jitter = (JitterBuffer*)speex_alloc(sizeof(JitterBuffer));
274 if (jitter) 275 if (jitter)
@@ -277,13 +278,14 @@ JitterBuffer *jitter_buffer_init(void)
277 spx_int32_t tmp; 278 spx_int32_t tmp;
278 for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) 279 for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
279 jitter->packets[i].data=NULL; 280 jitter->packets[i].data=NULL;
280 jitter->delay_step = 1; 281 jitter->delay_step = step_size;
281 jitter->concealment_size = 1; 282 jitter->concealment_size = step_size;
282 /*FIXME: Should this be 0 or 1?*/ 283 /*FIXME: Should this be 0 or 1?*/
283 jitter->buffer_margin = 0; 284 jitter->buffer_margin = 0;
284 jitter->late_cutoff = 50; 285 jitter->late_cutoff = 50;
285 jitter->destroy = NULL; 286 jitter->destroy = NULL;
286 jitter->latency_tradeoff = 0; 287 jitter->latency_tradeoff = 0;
288 jitter->auto_adjust = 1;
287 tmp = 4; 289 tmp = 4;
288 jitter_buffer_ctl(jitter, JITTER_BUFFER_SET_MAX_LATE_RATE, &tmp); 290 jitter_buffer_ctl(jitter, JITTER_BUFFER_SET_MAX_LATE_RATE, &tmp);
289 jitter_buffer_reset(jitter); 291 jitter_buffer_reset(jitter);
@@ -369,33 +371,27 @@ void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet)
369 int late; 371 int late;
370 /*fprintf (stderr, "put packet %d %d\n", timestamp, span);*/ 372 /*fprintf (stderr, "put packet %d %d\n", timestamp, span);*/
371 373
372 /* Syncing on the first packet to arrive */
373 if (jitter->reset_state)
374 {
375 jitter->reset_state=0;
376 jitter->pointer_timestamp = packet->timestamp;
377 jitter->next_stop = packet->timestamp;
378 /*fprintf(stderr, "reset to %d\n", timestamp);*/
379 }
380
381 /* Cleanup buffer (remove old packets that weren't played) */ 374 /* Cleanup buffer (remove old packets that weren't played) */
382 for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) 375 if (!jitter->reset_state)
383 { 376 {
384 /* Make sure we don't discard a "just-late" packet in case we want to play it next (if we interpolate). */ 377 for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
385 if (jitter->packets[i].data && LE32(jitter->packets[i].timestamp + jitter->packets[i].span, jitter->pointer_timestamp))
386 { 378 {
387 /*fprintf (stderr, "cleaned (not played)\n");*/ 379 /* Make sure we don't discard a "just-late" packet in case we want to play it next (if we interpolate). */
388 if (jitter->destroy) 380 if (jitter->packets[i].data && LE32(jitter->packets[i].timestamp + jitter->packets[i].span, jitter->pointer_timestamp))
389 jitter->destroy(jitter->packets[i].data); 381 {
390 else 382 /*fprintf (stderr, "cleaned (not played)\n");*/
391 speex_free(jitter->packets[i].data); 383 if (jitter->destroy)
392 jitter->packets[i].data = NULL; 384 jitter->destroy(jitter->packets[i].data);
385 else
386 speex_free(jitter->packets[i].data);
387 jitter->packets[i].data = NULL;
388 }
393 } 389 }
394 } 390 }
395 391
396 /*fprintf(stderr, "arrival: %d %d %d\n", packet->timestamp, jitter->next_stop, jitter->pointer_timestamp);*/ 392 /*fprintf(stderr, "arrival: %d %d %d\n", packet->timestamp, jitter->next_stop, jitter->pointer_timestamp);*/
397 /* Check if packet is late (could still be useful though) */ 393 /* Check if packet is late (could still be useful though) */
398 if (LT32(packet->timestamp, jitter->next_stop)) 394 if (!jitter->reset_state && LT32(packet->timestamp, jitter->next_stop))
399 { 395 {
400 update_timings(jitter, ((spx_int32_t)packet->timestamp) - ((spx_int32_t)jitter->next_stop) - jitter->buffer_margin); 396 update_timings(jitter, ((spx_int32_t)packet->timestamp) - ((spx_int32_t)jitter->next_stop) - jitter->buffer_margin);
401 late = 1; 397 late = 1;
@@ -404,7 +400,7 @@ void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet)
404 } 400 }
405 401
406 /* Only insert the packet if it's not hopelessly late (i.e. totally useless) */ 402 /* Only insert the packet if it's not hopelessly late (i.e. totally useless) */
407 if (GE32(packet->timestamp+packet->span+jitter->delay_step, jitter->pointer_timestamp)) 403 if (jitter->reset_state || GE32(packet->timestamp+packet->span+jitter->delay_step, jitter->pointer_timestamp))
408 { 404 {
409 405
410 /*Find an empty slot in the buffer*/ 406 /*Find an empty slot in the buffer*/
@@ -451,8 +447,9 @@ void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet)
451 jitter->packets[i].timestamp=packet->timestamp; 447 jitter->packets[i].timestamp=packet->timestamp;
452 jitter->packets[i].span=packet->span; 448 jitter->packets[i].span=packet->span;
453 jitter->packets[i].len=packet->len; 449 jitter->packets[i].len=packet->len;
450 jitter->packets[i].sequence=packet->sequence;
454 jitter->packets[i].user_data=packet->user_data; 451 jitter->packets[i].user_data=packet->user_data;
455 if (late) 452 if (jitter->reset_state || late)
456 jitter->arrival[i] = 0; 453 jitter->arrival[i] = 0;
457 else 454 else
458 jitter->arrival[i] = jitter->next_stop; 455 jitter->arrival[i] = jitter->next_stop;
@@ -469,12 +466,40 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3
469 int incomplete = 0; 466 int incomplete = 0;
470 spx_int16_t opt; 467 spx_int16_t opt;
471 468
469 if (start_offset != NULL)
470 *start_offset = 0;
471
472 /* Syncing on the first call */
473 if (jitter->reset_state)
474 {
475 int found = 0;
476 /* Find the oldest packet */
477 spx_uint32_t oldest=0;
478 for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
479 {
480 if (jitter->packets[i].data && (!found || LT32(jitter->packets[i].timestamp,oldest)))
481 {
482 oldest = jitter->packets[i].timestamp;
483 found = 1;
484 }
485 }
486 if (found)
487 {
488 jitter->reset_state=0;
489 jitter->pointer_timestamp = oldest;
490 jitter->next_stop = oldest;
491 } else {
492 packet->timestamp = 0;
493 packet->span = jitter->interp_requested;
494 return JITTER_BUFFER_MISSING;
495 }
496 }
497
498
472 jitter->last_returned_timestamp = jitter->pointer_timestamp; 499 jitter->last_returned_timestamp = jitter->pointer_timestamp;
473 500
474 if (jitter->interp_requested != 0) 501 if (jitter->interp_requested != 0)
475 { 502 {
476 if (start_offset)
477 *start_offset = 0;
478 packet->timestamp = jitter->pointer_timestamp; 503 packet->timestamp = jitter->pointer_timestamp;
479 packet->span = jitter->interp_requested; 504 packet->span = jitter->interp_requested;
480 505
@@ -487,7 +512,7 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3
487 512
488 jitter->buffered = packet->span - desired_span; 513 jitter->buffered = packet->span - desired_span;
489 514
490 return JITTER_BUFFER_MISSING; 515 return JITTER_BUFFER_INSERTION;
491 } 516 }
492 517
493 /* Searching for the packet that fits best */ 518 /* Searching for the packet that fits best */
@@ -551,7 +576,7 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3
551 /* If we find something */ 576 /* If we find something */
552 if (i!=SPEEX_JITTER_MAX_BUFFER_SIZE) 577 if (i!=SPEEX_JITTER_MAX_BUFFER_SIZE)
553 { 578 {
554 579 spx_int32_t offset;
555 580
556 /* We (obviously) haven't lost this packet */ 581 /* We (obviously) haven't lost this packet */
557 jitter->lost_count = 0; 582 jitter->lost_count = 0;
@@ -563,8 +588,12 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3
563 } 588 }
564 589
565 590
566 /* FIXME: Check for potential overflow */ 591 if (jitter->packets[i].len > packet->len)
567 packet->len = jitter->packets[i].len; 592 {
593 speex_warning_int("jitter_buffer_get(): packet too large to fit. Size is", jitter->packets[i].len);
594 } else {
595 packet->len = jitter->packets[i].len;
596 }
568 /* Copy packet */ 597 /* Copy packet */
569 if (jitter->destroy) 598 if (jitter->destroy)
570 { 599 {
@@ -577,23 +606,27 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3
577 } 606 }
578 jitter->packets[i].data = NULL; 607 jitter->packets[i].data = NULL;
579 /* Set timestamp and span (if requested) */ 608 /* Set timestamp and span (if requested) */
580 if (start_offset) 609 offset = (spx_int32_t)jitter->packets[i].timestamp-(spx_int32_t)jitter->pointer_timestamp;
581 *start_offset = (spx_int32_t)jitter->packets[i].timestamp-(spx_int32_t)jitter->pointer_timestamp; 610 if (start_offset != NULL)
611 *start_offset = offset;
612 else if (offset != 0)
613 speex_warning_int("jitter_buffer_get() discarding non-zero start_offset", offset);
582 614
583 packet->timestamp = jitter->packets[i].timestamp; 615 packet->timestamp = jitter->packets[i].timestamp;
584 jitter->last_returned_timestamp = packet->timestamp; 616 jitter->last_returned_timestamp = packet->timestamp;
585 617
586 packet->span = jitter->packets[i].span; 618 packet->span = jitter->packets[i].span;
619 packet->sequence = jitter->packets[i].sequence;
587 packet->user_data = jitter->packets[i].user_data; 620 packet->user_data = jitter->packets[i].user_data;
588 /* Point to the end of the current packet */ 621 /* Point to the end of the current packet */
589 jitter->pointer_timestamp = jitter->packets[i].timestamp+jitter->packets[i].span; 622 jitter->pointer_timestamp = jitter->packets[i].timestamp+jitter->packets[i].span;
590 623
591 jitter->buffered = *start_offset + packet->span - desired_span; 624 jitter->buffered = packet->span - desired_span;
592 625
593 if (incomplete) 626 if (start_offset != NULL)
594 return JITTER_BUFFER_INCOMPLETE; 627 jitter->buffered += *start_offset;
595 else 628
596 return JITTER_BUFFER_OK; 629 return JITTER_BUFFER_OK;
597 } 630 }
598 631
599 632
@@ -603,8 +636,6 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3
603 jitter->lost_count++; 636 jitter->lost_count++;
604 /*fprintf (stderr, "m");*/ 637 /*fprintf (stderr, "m");*/
605 /*fprintf (stderr, "lost_count = %d\n", jitter->lost_count);*/ 638 /*fprintf (stderr, "lost_count = %d\n", jitter->lost_count);*/
606 if (start_offset)
607 *start_offset = 0;
608 639
609 opt = compute_opt_delay(jitter); 640 opt = compute_opt_delay(jitter);
610 641
@@ -621,6 +652,8 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3
621 /* Don't move the pointer_timestamp forward */ 652 /* Don't move the pointer_timestamp forward */
622 packet->len = 0; 653 packet->len = 0;
623 654
655 jitter->buffered = packet->span - desired_span;
656 return JITTER_BUFFER_INSERTION;
624 /*jitter->pointer_timestamp -= jitter->delay_step;*/ 657 /*jitter->pointer_timestamp -= jitter->delay_step;*/
625 /*fprintf (stderr, "Forced to interpolate\n");*/ 658 /*fprintf (stderr, "Forced to interpolate\n");*/
626 } else { 659 } else {
@@ -631,11 +664,12 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3
631 packet->span = desired_span; 664 packet->span = desired_span;
632 jitter->pointer_timestamp += desired_span; 665 jitter->pointer_timestamp += desired_span;
633 packet->len = 0; 666 packet->len = 0;
667
668 jitter->buffered = packet->span - desired_span;
669 return JITTER_BUFFER_MISSING;
634 /*fprintf (stderr, "Normal loss\n");*/ 670 /*fprintf (stderr, "Normal loss\n");*/
635 } 671 }
636 672
637 jitter->buffered = packet->span - desired_span;
638 return JITTER_BUFFER_MISSING;
639 673
640} 674}
641 675
@@ -663,6 +697,7 @@ int jitter_buffer_get_another(JitterBuffer *jitter, JitterBufferPacket *packet)
663 jitter->packets[i].data = NULL; 697 jitter->packets[i].data = NULL;
664 packet->timestamp = jitter->packets[i].timestamp; 698 packet->timestamp = jitter->packets[i].timestamp;
665 packet->span = jitter->packets[i].span; 699 packet->span = jitter->packets[i].span;
700 packet->sequence = jitter->packets[i].sequence;
666 packet->user_data = jitter->packets[i].user_data; 701 packet->user_data = jitter->packets[i].user_data;
667 return JITTER_BUFFER_OK; 702 return JITTER_BUFFER_OK;
668 } else { 703 } else {
@@ -673,6 +708,39 @@ int jitter_buffer_get_another(JitterBuffer *jitter, JitterBufferPacket *packet)
673 } 708 }
674} 709}
675 710
711/* Let the jitter buffer know it's the right time to adjust the buffering delay to the network conditions */
712static int _jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset)
713{
714 spx_int16_t opt = compute_opt_delay(jitter);
715 /*fprintf(stderr, "opt adjustment is %d ", opt);*/
716
717 if (opt < 0)
718 {
719 shift_timings(jitter, -opt);
720
721 jitter->pointer_timestamp += opt;
722 jitter->interp_requested = -opt;
723 /*fprintf (stderr, "Decision to interpolate %d samples\n", -opt);*/
724 } else if (opt > 0)
725 {
726 shift_timings(jitter, -opt);
727 jitter->pointer_timestamp += opt;
728 /*fprintf (stderr, "Decision to drop %d samples\n", opt);*/
729 }
730
731 return opt;
732}
733
734/* Let the jitter buffer know it's the right time to adjust the buffering delay to the network conditions */
735int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset)
736{
737 /* If the programmer calls jitter_buffer_update_delay() directly,
738 automatically disable auto-adjustment */
739 jitter->auto_adjust = 0;
740
741 return _jitter_buffer_update_delay(jitter, packet, start_offset);
742}
743
676/** Get pointer timestamp of jitter buffer */ 744/** Get pointer timestamp of jitter buffer */
677int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter) 745int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter)
678{ 746{
@@ -681,45 +749,31 @@ int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter)
681 749
682void jitter_buffer_tick(JitterBuffer *jitter) 750void jitter_buffer_tick(JitterBuffer *jitter)
683{ 751{
752 /* Automatically-adjust the buffering delay if requested */
753 if (jitter->auto_adjust)
754 _jitter_buffer_update_delay(jitter, NULL, NULL);
755
684 if (jitter->buffered >= 0) 756 if (jitter->buffered >= 0)
685 { 757 {
686 jitter->next_stop = jitter->pointer_timestamp - jitter->buffered; 758 jitter->next_stop = jitter->pointer_timestamp - jitter->buffered;
687 } else { 759 } else {
688 jitter->next_stop = jitter->pointer_timestamp; 760 jitter->next_stop = jitter->pointer_timestamp;
689 speex_warning_int("jitter buffer sees negative buffering, you code might be broken. Value is ", jitter->buffered); 761 speex_warning_int("jitter buffer sees negative buffering, your code might be broken. Value is ", jitter->buffered);
690 } 762 }
691 jitter->buffered = 0; 763 jitter->buffered = 0;
692} 764}
693 765
694void jitter_buffer_remaining_span(JitterBuffer *jitter, spx_uint32_t rem) 766void jitter_buffer_remaining_span(JitterBuffer *jitter, spx_uint32_t rem)
695{ 767{
768 /* Automatically-adjust the buffering delay if requested */
769 if (jitter->auto_adjust)
770 _jitter_buffer_update_delay(jitter, NULL, NULL);
771
696 if (jitter->buffered < 0) 772 if (jitter->buffered < 0)
697 speex_warning_int("jitter buffer sees negative buffering, you code might be broken. Value is ", jitter->buffered); 773 speex_warning_int("jitter buffer sees negative buffering, your code might be broken. Value is ", jitter->buffered);
698 jitter->next_stop = jitter->pointer_timestamp - rem; 774 jitter->next_stop = jitter->pointer_timestamp - rem;
699} 775}
700 776
701/* Let the jitter buffer know it's the right time to adjust the buffering delay to the network conditions */
702int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset)
703{
704 spx_int16_t opt = compute_opt_delay(jitter);
705 /*fprintf(stderr, "opt adjustment is %d ", opt);*/
706
707 if (opt < 0)
708 {
709 shift_timings(jitter, -opt);
710
711 jitter->pointer_timestamp += opt;
712 jitter->interp_requested = -opt;
713 /*fprintf (stderr, "Decision to interpolate %d samples\n", -opt);*/
714 } else if (opt > 0)
715 {
716 shift_timings(jitter, -opt);
717 jitter->pointer_timestamp += opt;
718 /*fprintf (stderr, "Decision to drop %d samples\n", opt);*/
719 }
720
721 return opt;
722}
723 777
724/* Used like the ioctl function to control the jitter buffer parameters */ 778/* Used like the ioctl function to control the jitter buffer parameters */
725int jitter_buffer_ctl(JitterBuffer *jitter, int request, void *ptr) 779int jitter_buffer_ctl(JitterBuffer *jitter, int request, void *ptr)