summaryrefslogtreecommitdiff
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
parent287f14b8cabf08174d8dfbf8fae658107ac17f56 (diff)
downloadrockbox-0c7b26d3a75dbfa1f04c31a5750d81692e23b387.zip
rockbox-0c7b26d3a75dbfa1f04c31a5750d81692e23b387.tar.gz
rockbox-0c7b26d3a75dbfa1f04c31a5750d81692e23b387.tar.bz2
rockbox-0c7b26d3a75dbfa1f04c31a5750d81692e23b387.tar.xz
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.c110
1 files changed, 64 insertions, 46 deletions
diff --git a/apps/buffering.c b/apps/buffering.c
index dcc753e..349dc9b 100644
--- a/apps/buffering.c
+++ b/apps/buffering.c
@@ -502,10 +502,11 @@ static bool move_handle(struct memory_handle **h, size_t *delta,
BUFFER SPACE MANAGEMENT
=======================
+update_data_counters: Updates the values in data_counters
+buffer_is_low : Returns true if the amount of useful data in the buffer is low
yield_codec : Used by buffer_handle to know if it should interrupt buffering
buffer_handle : Buffer data for a handle
-reset_handle : Reset writing position and data buffer of a handle to its
- current offset
+reset_handle : Reset write position and data buffer of a handle to its offset
rebuffer_handle : Seek to a nonbuffered part of a handle by rebuffering the data
shrink_handle : Free buffer space by moving a handle
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
These functions are used by the buffering thread to manage buffer space.
*/
+static void update_data_counters(void)
+{
+ struct memory_handle *m = find_handle(base_handle_id);
+ bool is_useful = m==NULL;
+
+ size_t buffered = 0;
+ size_t wasted = 0;
+ size_t remaining = 0;
+ size_t useful = 0;
+
+ m = first_handle;
+ while (m) {
+ buffered += m->available;
+ wasted += RINGBUF_SUB(m->ridx, m->data);
+ remaining += m->filerem;
+
+ if (m->id == base_handle_id)
+ is_useful = true;
+
+ if (is_useful)
+ useful += RINGBUF_SUB(m->widx, m->ridx);
+
+ m = m->next;
+ }
+
+ data_counters.buffered = buffered;
+ data_counters.wasted = wasted;
+ data_counters.remaining = remaining;
+ data_counters.useful = useful;
+}
+
+static inline bool buffer_is_low(void)
+{
+ update_data_counters();
+ return data_counters.useful < BUFFERING_CRITICAL_LEVEL;
+}
+
+/* Yield to the codec thread for as long as possible if it is in need of data.
+ Return true if the caller should break to let the buffering thread process
+ new queue events */
+static bool yield_codec(void)
+{
+ yield();
+
+ if (!queue_empty(&buffering_queue))
+ return true;
+
+ while (pcmbuf_is_lowdata() && !buffer_is_low())
+ {
+ sleep(2);
+ trigger_cpu_boost();
+
+ if (!queue_empty(&buffering_queue))
+ return true;
+ }
+
+ return false;
+}
/* Buffer data for the given handle.
Return whether or not the buffering should continue explicitly. */
@@ -596,20 +655,10 @@ static bool buffer_handle(int handle_id)
h->available += rc;
h->filerem -= rc;
- yield();
- /* If this is a large file, see if we need to breakor give the codec
+ /* If this is a large file, see if we need to break or give the codec
* more time */
- if (h->type==TYPE_PACKET_AUDIO) {
- if (!queue_empty(&buffering_queue))
- break;
- if (pcmbuf_is_lowdata())
- {
- sleep(2);
- trigger_cpu_boost();
- if (!queue_empty(&buffering_queue))
- break;
- }
- }
+ if (h->type==TYPE_PACKET_AUDIO && yield_codec())
+ break;
}
if (h->filerem == 0) {
@@ -765,37 +814,6 @@ static bool fill_buffer(void)
}
}
-void update_data_counters(void)
-{
- struct memory_handle *m = find_handle(base_handle_id);
- bool is_useful = m==NULL;
-
- size_t buffered = 0;
- size_t wasted = 0;
- size_t remaining = 0;
- size_t useful = 0;
-
- m = first_handle;
- while (m) {
- buffered += m->available;
- wasted += RINGBUF_SUB(m->ridx, m->data);
- remaining += m->filerem;
-
- if (m->id == base_handle_id)
- is_useful = true;
-
- if (is_useful)
- useful += RINGBUF_SUB(m->widx, m->ridx);
-
- m = m->next;
- }
-
- data_counters.buffered = buffered;
- data_counters.wasted = wasted;
- data_counters.remaining = remaining;
- data_counters.useful = useful;
-}
-
/*
MAIN BUFFERING API CALLS