From 021e531c992498a2956069a579feca4ac0112833 Mon Sep 17 00:00:00 2001 From: Nicolas Pennequin Date: Mon, 22 Oct 2007 18:56:03 +0200 Subject: [PATCH] Use the callbacks in the audio thread * Hide useful_data(), instead let the user tell the buffering thread which handle it is using with set_base_handle() * Make the audio thread use a callback to know when to add new files * audio_fill_file_buffer() now does what its name says: add tracks until one fails (which means the buffer is full) --- apps/buffering.c | 35 +++++++++++++++++++++++------------ apps/buffering.h | 4 ++-- apps/playback.c | 29 ++++++++++++++++++++--------- 3 files changed, 45 insertions(+), 23 deletions(-) diff --git a/apps/buffering.c b/apps/buffering.c index 60f7ae76d..a39e07151 100644 --- a/apps/buffering.c +++ b/apps/buffering.c @@ -138,6 +138,8 @@ static struct memory_handle *first_handle; static int num_handles; /* number of handles in the list */ +static int base_handle_id; + static struct mutex llist_mutex; /* Handle cache (makes find_handle faster). @@ -156,6 +158,7 @@ enum { offset (the offset has to be set beforehand) */ Q_CLOSE_HANDLE, Q_BUFFERING_FILL_BUFFER_IF_ACTIVE_ATA, + Q_BASE_HANDLE, }; /* Buffering thread */ @@ -519,6 +522,12 @@ void request_buffer_handle(int handle_id) queue_send(&buffering_queue, Q_BUFFER_HANDLE, handle_id); } +void set_base_handle(int handle_id) +{ + LOGFQUEUE("buffering >| buffering Q_BUFFER_HANDLE"); + queue_post(&buffering_queue, Q_BASE_HANDLE, handle_id); +} + /* Reset writing position and data buffer of a handle to its current offset. Use this after having set the new offset to use. Returns 0 for success or -1 if the handle wasn't found. */ @@ -707,19 +716,16 @@ static size_t buffered_data(void) return ret; } -size_t useful_data(int start_handle_id) +static size_t useful_data(void) { - /* use a static var to remember which handle to start with when the caller - doesn't have access to the playback data. */ - static int start_id = 0; - if (start_handle_id > 0) - start_id = start_handle_id; - size_t ret = 0; - struct memory_handle *m = first_handle; + + struct memory_handle *m = find_handle(base_handle_id); + if (!m) + m = first_handle; + while (m) { - if (m->id >= start_id) - ret += m->available - RINGBUF_SUB(m->ridx, m->data); + ret += m->available - RINGBUF_SUB(m->ridx, m->data); m = m->next; } return ret; @@ -1134,6 +1140,11 @@ void buffering_thread(void) queue_reply(&buffering_queue, close_handle((int)ev.data)); break; + case Q_BASE_HANDLE: + LOGFQUEUE("buffering < Q_BASE_HANDLE"); + base_handle_id = (int)ev.data; + break; + #if MEM > 8 case Q_BUFFERING_FILL_BUFFER_IF_ACTIVE_ATA: /* only fill if the disk is still spining */ @@ -1159,7 +1170,7 @@ void buffering_thread(void) break; } - if (first_handle && useful_data(first_handle->id) < conf_watermark) + if (first_handle && useful_data() < conf_watermark) { DEBUGF("buffer is low on useful data, calling the callbacks\n"); call_buffer_low_callbacks(); @@ -1217,5 +1228,5 @@ void buffering_get_debugdata(struct buffering_debug *dbgdata) dbgdata->data_rem = data_rem(); dbgdata->wasted_space = wasted_space(); dbgdata->buffered_data = buffered_data(); - dbgdata->useful_data = useful_data(0); + dbgdata->useful_data = useful_data(); } diff --git a/apps/buffering.h b/apps/buffering.h index 7fb1ffbdb..762a8ad93 100644 --- a/apps/buffering.h +++ b/apps/buffering.h @@ -64,8 +64,6 @@ bool buffering_init(char *filebuf, size_t filebuflen); /* Amount of buffer space used */ size_t bufused(void); -size_t useful_data(int start_handle_id); - /* Reserve space in the buffer for a file */ int bufopen(char *file, size_t offset, enum data_type type); @@ -94,6 +92,8 @@ ssize_t handleoffset(int handle_id); void request_buffer_handle(int handle_id); +void set_base_handle(int handle_id); + void buffering_get_debugdata(struct buffering_debug *dbgdata); #endif diff --git a/apps/playback.c b/apps/playback.c index f558d44ad..bbbab8b21 100644 --- a/apps/playback.c +++ b/apps/playback.c @@ -1512,6 +1512,7 @@ static void codec_advance_buffer_counters(size_t amount) bufadvance(CUR_TI->audio_hid, amount); ci.curpos += amount; +#if 0 /* Start buffer filling as necessary. */ if (!pcmbuf_is_lowdata() && !filling) { @@ -1522,6 +1523,7 @@ static void codec_advance_buffer_counters(size_t amount) queue_post(&audio_queue, Q_AUDIO_FILL_BUFFER, 0); } } +#endif } /* copy up-to size bytes into ptr and return the actual size copied */ @@ -2663,6 +2665,12 @@ static void audio_generate_postbuffer_events(void) } } +static void low_buffer_callback(void) +{ + LOGFQUEUE("buffering > audio Q_AUDIO_FILL_BUFFER"); + queue_post(&audio_queue, Q_AUDIO_FILL_BUFFER, 0); +} + static bool audio_initialize_buffer_fill(bool clear_tracks) { /* Don't initialize if we're already initialized */ @@ -2699,19 +2707,18 @@ static void audio_fill_file_buffer( if (!audio_initialize_buffer_fill(!start_play)) return ; - continue_buffering = audio_load_track(offset, start_play, rebuffer); + do { + continue_buffering = audio_load_track(offset, start_play, rebuffer); + start_play = false; + offset = 0; + } while (continue_buffering); if (!had_next_track && audio_next_track()) track_changed = true; - /* If we're done buffering */ - if (!continue_buffering) - { - //audio_read_next_metadata(); - - audio_generate_postbuffer_events(); - filling = false; - } + audio_generate_postbuffer_events(); + filling = false; + register_buffer_low_callback(low_buffer_callback); } static void audio_rebuffer(void) @@ -2811,6 +2818,8 @@ static int audio_check_new_track(void) track_ridx += ci.new_track; track_ridx &= MAX_TRACK_MASK; + set_base_handle(CUR_TI->audio_hid); + if (automatic_skip) { playlist_end = false; @@ -3221,6 +3230,7 @@ static void audio_thread(void) { queue_wait_w_tmo(&audio_queue, &ev, HZ/2); +#if 0 if (filling) { if (ev.id == SYS_TIMEOUT) @@ -3234,6 +3244,7 @@ static void audio_thread(void) register_ata_idle_func(ata_fillbuffer_callback); #endif } +#endif switch (ev.id) { #if MEM > 8 -- 2.11.4.GIT