diff options
author | Nicolas Pennequin <nicolas.pennequin@free.fr> | 2007-11-05 21:11:54 +0000 |
---|---|---|
committer | Nicolas Pennequin <nicolas.pennequin@free.fr> | 2007-11-05 21:11:54 +0000 |
commit | 0c7b26d3a75dbfa1f04c31a5750d81692e23b387 (patch) | |
tree | 3cc76b784bd7857a4e3630879db8202ee6c81cdc | |
parent | 287f14b8cabf08174d8dfbf8fae658107ac17f56 (diff) | |
download | rockbox-0c7b26d3a75dbfa1f04c31a5750d81692e23b387.tar.gz rockbox-0c7b26d3a75dbfa1f04c31a5750d81692e23b387.zip |
Readd yield_codec, making it check for useful data through buffer_is_low. Fixes the PCM buffer underruns.
Also move update_data_counters and make it static.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15487 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | apps/buffering.c | 110 |
1 files changed, 64 insertions, 46 deletions
diff --git a/apps/buffering.c b/apps/buffering.c index dcc753ea9e..349dc9bbb9 100644 --- a/apps/buffering.c +++ b/apps/buffering.c | |||
@@ -502,10 +502,11 @@ static bool move_handle(struct memory_handle **h, size_t *delta, | |||
502 | BUFFER SPACE MANAGEMENT | 502 | BUFFER SPACE MANAGEMENT |
503 | ======================= | 503 | ======================= |
504 | 504 | ||
505 | update_data_counters: Updates the values in data_counters | ||
506 | buffer_is_low : Returns true if the amount of useful data in the buffer is low | ||
505 | yield_codec : Used by buffer_handle to know if it should interrupt buffering | 507 | yield_codec : Used by buffer_handle to know if it should interrupt buffering |
506 | buffer_handle : Buffer data for a handle | 508 | buffer_handle : Buffer data for a handle |
507 | reset_handle : Reset writing position and data buffer of a handle to its | 509 | reset_handle : Reset write position and data buffer of a handle to its offset |
508 | current offset | ||
509 | rebuffer_handle : Seek to a nonbuffered part of a handle by rebuffering the data | 510 | rebuffer_handle : Seek to a nonbuffered part of a handle by rebuffering the data |
510 | shrink_handle : Free buffer space by moving a handle | 511 | shrink_handle : Free buffer space by moving a handle |
511 | fill_buffer : Call buffer_handle for all handles that have data to buffer | 512 | fill_buffer : Call buffer_handle for all handles that have data to buffer |
@@ -513,6 +514,64 @@ fill_buffer : Call buffer_handle for all handles that have data to buffer | |||
513 | These functions are used by the buffering thread to manage buffer space. | 514 | These functions are used by the buffering thread to manage buffer space. |
514 | */ | 515 | */ |
515 | 516 | ||
517 | static void update_data_counters(void) | ||
518 | { | ||
519 | struct memory_handle *m = find_handle(base_handle_id); | ||
520 | bool is_useful = m==NULL; | ||
521 | |||
522 | size_t buffered = 0; | ||
523 | size_t wasted = 0; | ||
524 | size_t remaining = 0; | ||
525 | size_t useful = 0; | ||
526 | |||
527 | m = first_handle; | ||
528 | while (m) { | ||
529 | buffered += m->available; | ||
530 | wasted += RINGBUF_SUB(m->ridx, m->data); | ||
531 | remaining += m->filerem; | ||
532 | |||
533 | if (m->id == base_handle_id) | ||
534 | is_useful = true; | ||
535 | |||
536 | if (is_useful) | ||
537 | useful += RINGBUF_SUB(m->widx, m->ridx); | ||
538 | |||
539 | m = m->next; | ||
540 | } | ||
541 | |||
542 | data_counters.buffered = buffered; | ||
543 | data_counters.wasted = wasted; | ||
544 | data_counters.remaining = remaining; | ||
545 | data_counters.useful = useful; | ||
546 | } | ||
547 | |||
548 | static inline bool buffer_is_low(void) | ||
549 | { | ||
550 | update_data_counters(); | ||
551 | return data_counters.useful < BUFFERING_CRITICAL_LEVEL; | ||
552 | } | ||
553 | |||
554 | /* Yield to the codec thread for as long as possible if it is in need of data. | ||
555 | Return true if the caller should break to let the buffering thread process | ||
556 | new queue events */ | ||
557 | static bool yield_codec(void) | ||
558 | { | ||
559 | yield(); | ||
560 | |||
561 | if (!queue_empty(&buffering_queue)) | ||
562 | return true; | ||
563 | |||
564 | while (pcmbuf_is_lowdata() && !buffer_is_low()) | ||
565 | { | ||
566 | sleep(2); | ||
567 | trigger_cpu_boost(); | ||
568 | |||
569 | if (!queue_empty(&buffering_queue)) | ||
570 | return true; | ||
571 | } | ||
572 | |||
573 | return false; | ||
574 | } | ||
516 | 575 | ||
517 | /* Buffer data for the given handle. | 576 | /* Buffer data for the given handle. |
518 | Return whether or not the buffering should continue explicitly. */ | 577 | Return whether or not the buffering should continue explicitly. */ |
@@ -596,20 +655,10 @@ static bool buffer_handle(int handle_id) | |||
596 | h->available += rc; | 655 | h->available += rc; |
597 | h->filerem -= rc; | 656 | h->filerem -= rc; |
598 | 657 | ||
599 | yield(); | 658 | /* If this is a large file, see if we need to break or give the codec |
600 | /* If this is a large file, see if we need to breakor give the codec | ||
601 | * more time */ | 659 | * more time */ |
602 | if (h->type==TYPE_PACKET_AUDIO) { | 660 | if (h->type==TYPE_PACKET_AUDIO && yield_codec()) |
603 | if (!queue_empty(&buffering_queue)) | 661 | break; |
604 | break; | ||
605 | if (pcmbuf_is_lowdata()) | ||
606 | { | ||
607 | sleep(2); | ||
608 | trigger_cpu_boost(); | ||
609 | if (!queue_empty(&buffering_queue)) | ||
610 | break; | ||
611 | } | ||
612 | } | ||
613 | } | 662 | } |
614 | 663 | ||
615 | if (h->filerem == 0) { | 664 | if (h->filerem == 0) { |
@@ -765,37 +814,6 @@ static bool fill_buffer(void) | |||
765 | } | 814 | } |
766 | } | 815 | } |
767 | 816 | ||
768 | void update_data_counters(void) | ||
769 | { | ||
770 | struct memory_handle *m = find_handle(base_handle_id); | ||
771 | bool is_useful = m==NULL; | ||
772 | |||
773 | size_t buffered = 0; | ||
774 | size_t wasted = 0; | ||
775 | size_t remaining = 0; | ||
776 | size_t useful = 0; | ||
777 | |||
778 | m = first_handle; | ||
779 | while (m) { | ||
780 | buffered += m->available; | ||
781 | wasted += RINGBUF_SUB(m->ridx, m->data); | ||
782 | remaining += m->filerem; | ||
783 | |||
784 | if (m->id == base_handle_id) | ||
785 | is_useful = true; | ||
786 | |||
787 | if (is_useful) | ||
788 | useful += RINGBUF_SUB(m->widx, m->ridx); | ||
789 | |||
790 | m = m->next; | ||
791 | } | ||
792 | |||
793 | data_counters.buffered = buffered; | ||
794 | data_counters.wasted = wasted; | ||
795 | data_counters.remaining = remaining; | ||
796 | data_counters.useful = useful; | ||
797 | } | ||
798 | |||
799 | 817 | ||
800 | /* | 818 | /* |
801 | MAIN BUFFERING API CALLS | 819 | MAIN BUFFERING API CALLS |