1
0
Fork 0
forked from len0rd/rockbox

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
This commit is contained in:
Nicolas Pennequin 2007-11-05 21:11:54 +00:00
parent 287f14b8ca
commit 0c7b26d3a7

View file

@ -502,10 +502,11 @@ static bool move_handle(struct memory_handle **h, size_t *delta,
BUFFER SPACE MANAGEMENT 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 yield_codec : Used by buffer_handle to know if it should interrupt buffering
buffer_handle : Buffer data for a handle buffer_handle : Buffer data for a handle
reset_handle : Reset writing position and data buffer of a handle to its reset_handle : Reset write position and data buffer of a handle to its offset
current offset
rebuffer_handle : Seek to a nonbuffered part of a handle by rebuffering the data rebuffer_handle : Seek to a nonbuffered part of a handle by rebuffering the data
shrink_handle : Free buffer space by moving a handle shrink_handle : Free buffer space by moving a handle
fill_buffer : Call buffer_handle for all handles that have data to buffer 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. 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. /* Buffer data for the given handle.
Return whether or not the buffering should continue explicitly. */ Return whether or not the buffering should continue explicitly. */
@ -596,20 +655,10 @@ static bool buffer_handle(int handle_id)
h->available += rc; h->available += rc;
h->filerem -= rc; h->filerem -= rc;
yield(); /* If this is a large file, see if we need to break or give the codec
/* If this is a large file, see if we need to breakor give the codec
* more time */ * more time */
if (h->type==TYPE_PACKET_AUDIO) { if (h->type==TYPE_PACKET_AUDIO && yield_codec())
if (!queue_empty(&buffering_queue))
break; break;
if (pcmbuf_is_lowdata())
{
sleep(2);
trigger_cpu_boost();
if (!queue_empty(&buffering_queue))
break;
}
}
} }
if (h->filerem == 0) { 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 MAIN BUFFERING API CALLS