diff options
author | Thom Johansen <thomj@rockbox.org> | 2007-11-24 19:14:29 +0000 |
---|---|---|
committer | Thom Johansen <thomj@rockbox.org> | 2007-11-24 19:14:29 +0000 |
commit | 929443cca52e53696d776661af42d5737a0af10d (patch) | |
tree | fe118429b9c1467b721fe2e1cab5b7ae4a0fa873 /apps/codecs/libspeex/jitter.c | |
parent | d6e22443c4406d94038fdf19955371d38e2ab71f (diff) | |
download | rockbox-929443cca52e53696d776661af42d5737a0af10d.tar.gz rockbox-929443cca52e53696d776661af42d5737a0af10d.zip |
Sync to SVN.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15792 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs/libspeex/jitter.c')
-rw-r--r-- | apps/codecs/libspeex/jitter.c | 194 |
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 */ |
271 | JitterBuffer *jitter_buffer_init(void) | 272 | JitterBuffer *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 */ | ||
712 | static 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 */ | ||
735 | int 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 */ |
677 | int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter) | 745 | int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter) |
678 | { | 746 | { |
@@ -681,45 +749,31 @@ int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter) | |||
681 | 749 | ||
682 | void jitter_buffer_tick(JitterBuffer *jitter) | 750 | void 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 | ||
694 | void jitter_buffer_remaining_span(JitterBuffer *jitter, spx_uint32_t rem) | 766 | void 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 */ | ||
702 | int 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 */ |
725 | int jitter_buffer_ctl(JitterBuffer *jitter, int request, void *ptr) | 779 | int jitter_buffer_ctl(JitterBuffer *jitter, int request, void *ptr) |