From 0c7b26d3a75dbfa1f04c31a5750d81692e23b387 Mon Sep 17 00:00:00 2001 From: Nicolas Pennequin Date: Mon, 5 Nov 2007 21:11:54 +0000 Subject: 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 --- apps/buffering.c | 110 ++++++++++++++++++++++++++++++++----------------------- 1 file 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, 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 -- cgit v1.2.3