summaryrefslogtreecommitdiff
path: root/apps/buffering.c
diff options
context:
space:
mode:
authorNicolas Pennequin <nicolas.pennequin@free.fr>2007-11-05 21:11:54 +0000
committerNicolas Pennequin <nicolas.pennequin@free.fr>2007-11-05 21:11:54 +0000
commit0c7b26d3a75dbfa1f04c31a5750d81692e23b387 (patch)
tree3cc76b784bd7857a4e3630879db8202ee6c81cdc /apps/buffering.c
parent287f14b8cabf08174d8dfbf8fae658107ac17f56 (diff)
downloadrockbox-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
Diffstat (limited to 'apps/buffering.c')
-rw-r--r--apps/buffering.c110
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,
502BUFFER SPACE MANAGEMENT 502BUFFER SPACE MANAGEMENT
503======================= 503=======================
504 504
505update_data_counters: Updates the values in data_counters
506buffer_is_low : Returns true if the amount of useful data in the buffer is low
505yield_codec : Used by buffer_handle to know if it should interrupt buffering 507yield_codec : Used by buffer_handle to know if it should interrupt buffering
506buffer_handle : Buffer data for a handle 508buffer_handle : Buffer data for a handle
507reset_handle : Reset writing position and data buffer of a handle to its 509reset_handle : Reset write position and data buffer of a handle to its offset
508 current offset
509rebuffer_handle : Seek to a nonbuffered part of a handle by rebuffering the data 510rebuffer_handle : Seek to a nonbuffered part of a handle by rebuffering the data
510shrink_handle : Free buffer space by moving a handle 511shrink_handle : Free buffer space by moving a handle
511fill_buffer : Call buffer_handle for all handles that have data to buffer 512fill_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
513These functions are used by the buffering thread to manage buffer space. 514These functions are used by the buffering thread to manage buffer space.
514*/ 515*/
515 516
517static 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
548static 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 */
557static 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
768void 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/*
801MAIN BUFFERING API CALLS 819MAIN BUFFERING API CALLS