Migrate the buffering code to the new events system.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16950 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
81efd6c36d
commit
33f522de8b
3 changed files with 44 additions and 111 deletions
|
@ -49,6 +49,7 @@
|
|||
#include "pcmbuf.h"
|
||||
#include "buffer.h"
|
||||
#include "bmp.h"
|
||||
#include "events.h"
|
||||
|
||||
#ifdef SIMULATOR
|
||||
#define ata_disk_is_active() 1
|
||||
|
@ -153,9 +154,6 @@ static struct mutex llist_mutex;
|
|||
This is global so that move_handle and rm_handle can invalidate it. */
|
||||
static struct memory_handle *cached_handle = NULL;
|
||||
|
||||
static buffering_callback buffering_callback_funcs[MAX_BUF_CALLBACKS];
|
||||
static int buffer_callback_count = 0;
|
||||
|
||||
static struct {
|
||||
size_t remaining; /* Amount of data needing to be buffered */
|
||||
size_t wasted; /* Amount of space available for freeing */
|
||||
|
@ -190,8 +188,6 @@ static struct event_queue buffering_queue;
|
|||
static struct queue_sender_list buffering_queue_sender_list;
|
||||
|
||||
|
||||
static void call_buffering_callbacks(enum callback_event ev, int value);
|
||||
|
||||
|
||||
/*
|
||||
LINKED LIST MANAGEMENT
|
||||
|
@ -659,7 +655,7 @@ static bool buffer_handle(int handle_id)
|
|||
/* finished buffering the file */
|
||||
close(h->fd);
|
||||
h->fd = -1;
|
||||
call_buffering_callbacks(EVENT_HANDLE_FINISHED, h->id);
|
||||
send_event(EVENT_HANDLE_FINISHED, &h->id);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -715,7 +711,7 @@ static void rebuffer_handle(int handle_id, size_t newpos)
|
|||
/* There isn't enough space to rebuffer all of the track from its new
|
||||
offset, so we ask the user to free some */
|
||||
DEBUGF("rebuffer_handle: space is needed\n");
|
||||
call_buffering_callbacks(EVENT_HANDLE_REBUFFER, handle_id);
|
||||
send_event(EVENT_HANDLE_REBUFFER, &handle_id);
|
||||
}
|
||||
|
||||
/* Now we ask for a rebuffer */
|
||||
|
@ -1269,52 +1265,6 @@ void buf_set_watermark(size_t bytes)
|
|||
queue_post(&buffering_queue, Q_SET_WATERMARK, bytes);
|
||||
}
|
||||
|
||||
bool register_buffering_callback(buffering_callback func)
|
||||
{
|
||||
int i;
|
||||
if (buffer_callback_count >= MAX_BUF_CALLBACKS)
|
||||
return false;
|
||||
for (i = 0; i < MAX_BUF_CALLBACKS; i++)
|
||||
{
|
||||
if (buffering_callback_funcs[i] == NULL)
|
||||
{
|
||||
buffering_callback_funcs[i] = func;
|
||||
buffer_callback_count++;
|
||||
return true;
|
||||
}
|
||||
else if (buffering_callback_funcs[i] == func)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void unregister_buffering_callback(buffering_callback func)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < MAX_BUF_CALLBACKS; i++)
|
||||
{
|
||||
if (buffering_callback_funcs[i] == func)
|
||||
{
|
||||
buffering_callback_funcs[i] = NULL;
|
||||
buffer_callback_count--;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void call_buffering_callbacks(enum callback_event ev, int value)
|
||||
{
|
||||
logf("call_buffering_callbacks()");
|
||||
int i;
|
||||
for (i = 0; i < MAX_BUF_CALLBACKS; i++)
|
||||
{
|
||||
if (buffering_callback_funcs[i])
|
||||
{
|
||||
buffering_callback_funcs[i](ev, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void shrink_buffer_inner(struct memory_handle *h)
|
||||
{
|
||||
if (h == NULL)
|
||||
|
@ -1350,7 +1300,7 @@ void buffering_thread(void)
|
|||
LOGFQUEUE("buffering < Q_START_FILL");
|
||||
/* Call buffer callbacks here because this is one of two ways
|
||||
* to begin a full buffer fill */
|
||||
call_buffering_callbacks(EVENT_BUFFER_LOW, 0);
|
||||
send_event(EVENT_BUFFER_LOW, 0);
|
||||
shrink_buffer();
|
||||
queue_reply(&buffering_queue, 1);
|
||||
filling |= buffer_handle((int)ev.data);
|
||||
|
@ -1412,7 +1362,7 @@ void buffering_thread(void)
|
|||
|
||||
/* If the buffer is low, call the callbacks to get new data */
|
||||
if (num_handles > 0 && data_counters.useful <= conf_watermark)
|
||||
call_buffering_callbacks(EVENT_BUFFER_LOW, 0);
|
||||
send_event(EVENT_BUFFER_LOW, 0);
|
||||
|
||||
#if 0
|
||||
/* TODO: This needs to be fixed to use the idle callback, disable it
|
||||
|
@ -1422,7 +1372,7 @@ void buffering_thread(void)
|
|||
else if (ata_disk_is_active() && queue_empty(&buffering_queue))
|
||||
{
|
||||
if (num_handles > 0 && data_counters.useful <= high_watermark)
|
||||
call_buffering_callbacks(EVENT_BUFFER_LOW, 0);
|
||||
send_event(EVENT_BUFFER_LOW, 0);
|
||||
|
||||
if (data_counters.remaining > 0 && BUF_USED <= high_watermark)
|
||||
{
|
||||
|
@ -1492,9 +1442,6 @@ bool buffering_reset(char *buf, size_t buflen)
|
|||
num_handles = 0;
|
||||
base_handle_id = -1;
|
||||
|
||||
buffer_callback_count = 0;
|
||||
memset(buffering_callback_funcs, 0, sizeof(buffering_callback_funcs));
|
||||
|
||||
/* Set the high watermark as 75% full...or 25% empty :) */
|
||||
#if MEM > 8
|
||||
high_watermark = 3*buflen / 4;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include <sys/types.h>
|
||||
#include <stdbool.h>
|
||||
#include "events.h"
|
||||
|
||||
|
||||
enum data_type {
|
||||
|
@ -36,8 +37,7 @@ enum data_type {
|
|||
};
|
||||
|
||||
enum callback_event {
|
||||
EVENT_DEFAULT,
|
||||
EVENT_BUFFER_LOW,
|
||||
EVENT_BUFFER_LOW = (EVENT_CLASS_BUFFERING|1),
|
||||
EVENT_HANDLE_REBUFFER,
|
||||
EVENT_HANDLE_CLOSED,
|
||||
EVENT_HANDLE_MOVED,
|
||||
|
@ -109,23 +109,6 @@ void buf_set_base_handle(int handle_id);
|
|||
size_t buf_used(void);
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* CALLBACK UTILITIES
|
||||
* ==================
|
||||
*
|
||||
* register_buffering_callback, unregister_buffering_callback:
|
||||
*
|
||||
* Register/Unregister callback functions that will get executed when the buffer
|
||||
* goes below the low watermark. They are executed once, then forgotten.
|
||||
*
|
||||
* NOTE: The callbacks are called from the buffering thread, so don't make them
|
||||
* do too much. Ideally they should just post an event to a queue and return.
|
||||
****************************************************************************/
|
||||
|
||||
#define MAX_BUF_CALLBACKS 4
|
||||
typedef void (*buffering_callback)(enum callback_event ev, int value);
|
||||
bool register_buffering_callback(buffering_callback func);
|
||||
void unregister_buffering_callback(buffering_callback func);
|
||||
|
||||
/* Settings */
|
||||
enum {
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "codecs.h"
|
||||
#include "audio.h"
|
||||
#include "buffering.h"
|
||||
#include "events.h"
|
||||
#include "voice_thread.h"
|
||||
#include "mp3_playback.h"
|
||||
#include "usb.h"
|
||||
|
@ -1386,6 +1387,34 @@ static void codec_thread(void)
|
|||
}
|
||||
|
||||
|
||||
/* --- Buffering callbacks --- */
|
||||
|
||||
static void buffering_low_buffer_callback(void *data)
|
||||
{
|
||||
(void)data;
|
||||
logf("low buffer callback");
|
||||
|
||||
if (filling == STATE_FULL) {
|
||||
/* force a refill */
|
||||
LOGFQUEUE("buffering > audio Q_AUDIO_FILL_BUFFER");
|
||||
queue_post(&audio_queue, Q_AUDIO_FILL_BUFFER, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void buffering_handle_rebuffer_callback(void *data)
|
||||
{
|
||||
(void)data;
|
||||
LOGFQUEUE("audio >| audio Q_AUDIO_FLUSH");
|
||||
queue_post(&audio_queue, Q_AUDIO_FLUSH, 0);
|
||||
}
|
||||
|
||||
static void buffering_handle_finished_callback(int *data)
|
||||
{
|
||||
logf("handle %d finished buffering", *data);
|
||||
strip_tags(*data);
|
||||
}
|
||||
|
||||
|
||||
/* --- Audio thread --- */
|
||||
|
||||
static bool audio_have_tracks(void)
|
||||
|
@ -1433,36 +1462,6 @@ static void audio_update_trackinfo(void)
|
|||
ci.taginfo_ready = &CUR_TI->taginfo_ready;
|
||||
}
|
||||
|
||||
static void buffering_audio_callback(enum callback_event ev, int value)
|
||||
{
|
||||
(void)value;
|
||||
logf("buffering_audio_callback");
|
||||
|
||||
switch (ev)
|
||||
{
|
||||
case EVENT_BUFFER_LOW:
|
||||
if (filling == STATE_FULL) {
|
||||
/* force a refill */
|
||||
LOGFQUEUE("buffering > audio Q_AUDIO_FILL_BUFFER");
|
||||
queue_post(&audio_queue, Q_AUDIO_FILL_BUFFER, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case EVENT_HANDLE_REBUFFER:
|
||||
LOGFQUEUE("audio >| audio Q_AUDIO_FLUSH");
|
||||
queue_post(&audio_queue, Q_AUDIO_FLUSH, 0);
|
||||
break;
|
||||
|
||||
case EVENT_HANDLE_FINISHED:
|
||||
logf("handle %d finished buffering", value);
|
||||
strip_tags(value);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear tracks between write and read, non inclusive */
|
||||
static void audio_clear_track_entries(void)
|
||||
{
|
||||
|
@ -2062,6 +2061,8 @@ static void audio_stop_playback(void)
|
|||
/* TODO: Create auto bookmark too? */
|
||||
|
||||
prev_track_elapsed = curtrack_id3.elapsed;
|
||||
|
||||
remove_event(EVENT_BUFFER_LOW, buffering_low_buffer_callback);
|
||||
}
|
||||
|
||||
paused = false;
|
||||
|
@ -2076,8 +2077,6 @@ static void audio_stop_playback(void)
|
|||
/* Close all tracks */
|
||||
audio_release_tracks();
|
||||
|
||||
unregister_buffering_callback(buffering_audio_callback);
|
||||
|
||||
memset(&curtrack_id3, 0, sizeof(struct mp3entry));
|
||||
}
|
||||
|
||||
|
@ -2121,7 +2120,8 @@ static void audio_play_start(size_t offset)
|
|||
#endif
|
||||
|
||||
audio_fill_file_buffer(true, offset);
|
||||
register_buffering_callback(buffering_audio_callback);
|
||||
|
||||
add_event(EVENT_BUFFER_LOW, false, buffering_low_buffer_callback);
|
||||
|
||||
LOGFQUEUE("audio > audio Q_AUDIO_TRACK_CHANGED");
|
||||
queue_post(&audio_queue, Q_AUDIO_TRACK_CHANGED, 0);
|
||||
|
@ -2512,6 +2512,9 @@ void audio_init(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
add_event(EVENT_HANDLE_REBUFFER, false, buffering_handle_rebuffer_callback);
|
||||
add_event(EVENT_HANDLE_FINISHED, false, buffering_handle_finished_callback);
|
||||
|
||||
/* Probably safe to say */
|
||||
audio_is_initialized = true;
|
||||
|
||||
|
|
Loading…
Reference in a new issue