1
0
Fork 0
forked from len0rd/rockbox

Misc. buffering related playback tweaks

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15435 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Brandon Low 2007-11-03 17:55:29 +00:00
parent a7905da890
commit 86919f4609
3 changed files with 41 additions and 40 deletions

View file

@ -224,19 +224,15 @@ static int codec_load_ram(int size, struct codec_api *api)
return status; return status;
} }
int codec_load_buf(unsigned int hid, int size, struct codec_api *api) { int codec_load_buf(unsigned int hid, struct codec_api *api) {
int rc; int rc;
rc = bufread(hid, size, codecbuf); rc = bufread(hid, CODEC_SIZE, codecbuf);
if (rc < 0) { if (rc < 0) {
logf("error loading codec"); logf("error loading codec");
return CODEC_ERROR; return CODEC_ERROR;
} }
if (rc < size) {
logf("codec ended %d early",size - rc);
return CODEC_ERROR;
}
api->discard_codec(); api->discard_codec();
return codec_load_ram(size, api); return codec_load_ram(rc, api);
} }
int codec_load_file(const char *plugin, struct codec_api *api) int codec_load_file(const char *plugin, struct codec_api *api)

View file

@ -284,7 +284,7 @@ extern unsigned char plugin_end_addr[];
void codec_get_full_path(char *path, const char *codec_root_fn); void codec_get_full_path(char *path, const char *codec_root_fn);
/* defined by the codec loader (codec.c) */ /* defined by the codec loader (codec.c) */
int codec_load_buf(unsigned int hid, int size, struct codec_api *api); int codec_load_buf(unsigned int hid, struct codec_api *api);
int codec_load_file(const char* codec, struct codec_api *api); int codec_load_file(const char* codec, struct codec_api *api);
/* defined by the codec */ /* defined by the codec */

View file

@ -215,9 +215,9 @@ struct track_info {
int id3_hid; /* The ID for the track's metadata handle */ int id3_hid; /* The ID for the track's metadata handle */
int codec_hid; /* The ID for the track's codec handle */ int codec_hid; /* The ID for the track's codec handle */
size_t codecsize; /* Codec length in bytes */
size_t filesize; /* File total length */ size_t filesize; /* File total length */
bool has_codec; /* Codec length in bytes */
bool taginfo_ready; /* Is metadata read */ bool taginfo_ready; /* Is metadata read */
bool event_sent; /* Was this track's buffered event sent */ bool event_sent; /* Was this track's buffered event sent */
@ -1686,7 +1686,7 @@ static void codec_discard_codec_callback(void)
{ {
bufclose(CUR_TI->codec_hid); bufclose(CUR_TI->codec_hid);
CUR_TI->codec_hid = 0; CUR_TI->codec_hid = 0;
CUR_TI->codecsize = 0; CUR_TI->has_codec = false;
} }
} }
@ -1875,8 +1875,7 @@ static void codec_thread(void)
#endif #endif
set_current_codec(CODEC_IDX_AUDIO); set_current_codec(CODEC_IDX_AUDIO);
ci.stop_codec = false; ci.stop_codec = false;
status = status = codec_load_buf(CUR_TI->codec_hid, &ci);
codec_load_buf(CUR_TI->codec_hid, CUR_TI->codecsize, &ci);
#ifdef PLAYBACK_VOICE #ifdef PLAYBACK_VOICE
semaphore_release(&sem_codecthread); semaphore_release(&sem_codecthread);
#endif #endif
@ -2066,12 +2065,22 @@ static void audio_update_trackinfo(void)
ci.taginfo_ready = &CUR_TI->taginfo_ready; ci.taginfo_ready = &CUR_TI->taginfo_ready;
} }
static void low_buffer_callback(void)
{
LOGFQUEUE("buffering > audio Q_AUDIO_FILL_BUFFER");
queue_post(&audio_queue, Q_AUDIO_FILL_BUFFER, 0);
}
static void audio_clear_track_entries(bool clear_unbuffered) static void audio_clear_track_entries(bool clear_unbuffered)
{ {
int cur_idx = track_widx; int cur_idx = track_widx;
logf("Clearing tracks:%d/%d, %d", track_ridx, track_widx, clear_unbuffered); logf("Clearing tracks:%d/%d, %d", track_ridx, track_widx, clear_unbuffered);
/* This function is always called in association with a stop or a rebuffer,
* we will reregister the callback at the end of a rebuffer if needed */
unregister_buffer_low_callback(low_buffer_callback);
/* Loop over all tracks from write-to-read */ /* Loop over all tracks from write-to-read */
while (1) while (1)
{ {
@ -2115,7 +2124,6 @@ static bool audio_release_tracks(void)
static bool audio_loadcodec(bool start_play) static bool audio_loadcodec(bool start_play)
{ {
int fd;
int prev_track; int prev_track;
char codec_path[MAX_PATH]; /* Full path to codec */ char codec_path[MAX_PATH]; /* Full path to codec */
@ -2128,7 +2136,7 @@ static bool audio_loadcodec(bool start_play)
if (codec_fn == NULL) if (codec_fn == NULL)
return false; return false;
tracks[track_widx].codec_hid = 0; tracks[track_widx].codec_hid = false;
if (start_play) if (start_play)
{ {
@ -2165,24 +2173,24 @@ static bool audio_loadcodec(bool start_play)
codec_get_full_path(codec_path, codec_fn); codec_get_full_path(codec_path, codec_fn);
fd = open(codec_path, O_RDONLY); /* Found a codec filename */
if (fd < 0) tracks[track_widx].has_codec = true;
{
logf("Codec doesn't exist!");
return false;
}
tracks[track_widx].codecsize = filesize(fd);
tracks[track_widx].codec_hid = bufopen(codec_path, 0, TYPE_CODEC); tracks[track_widx].codec_hid = bufopen(codec_path, 0, TYPE_CODEC);
if (tracks[track_widx].codec_hid < 0) if (tracks[track_widx].codec_hid < 0)
{
if (tracks[track_widx].codec_hid == ERR_FILE_ERROR)
{
logf("Codec file error");
tracks[track_widx].has_codec = false;
}
else
{ {
logf("Not enough space"); logf("Not enough space");
close(fd); }
return false; return false;
} }
close(fd);
logf("Loaded codec"); logf("Loaded codec");
return true; return true;
@ -2368,10 +2376,10 @@ static bool audio_load_track(int offset, bool start_play)
/* Load the codec. */ /* Load the codec. */
if (!audio_loadcodec(start_play)) if (!audio_loadcodec(start_play))
{ {
if (tracks[track_widx].codecsize) if (tracks[track_widx].has_codec)
{ {
/* No space for codec on buffer, not an error */ /* No space for codec on buffer, not an error */
tracks[track_widx].codecsize = 0; tracks[track_widx].has_codec = false;
return false; return false;
} }
@ -2486,12 +2494,6 @@ 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 void audio_fill_file_buffer(bool start_play, size_t offset) static void audio_fill_file_buffer(bool start_play, size_t offset)
{ {
struct queue_event ev; struct queue_event ev;
@ -2533,6 +2535,9 @@ static void audio_fill_file_buffer(bool start_play, size_t offset)
track_changed = true; track_changed = true;
audio_generate_postbuffer_events(); audio_generate_postbuffer_events();
if (!continue_buffering)
register_buffer_low_callback(low_buffer_callback);
} }
static void audio_rebuffer(void) static void audio_rebuffer(void)
@ -2545,9 +2550,6 @@ static void audio_rebuffer(void)
track_widx = track_ridx; track_widx = track_ridx;
audio_clear_track_entries(true); audio_clear_track_entries(true);
/* Just to make sure none were forgotten */
audio_release_tracks();
/* Fill the buffer */ /* Fill the buffer */
last_peek_offset = -1; last_peek_offset = -1;
ci.curpos = 0; ci.curpos = 0;
@ -2772,12 +2774,12 @@ static void audio_stop_playback(void)
audio_stop_codec_flush(); audio_stop_codec_flush();
playing = false; playing = false;
/* Close all tracks */
audio_release_tracks();
/* Mark all entries null. */ /* Mark all entries null. */
audio_clear_track_entries(false); audio_clear_track_entries(false);
/* Close all tracks */
audio_release_tracks();
memset(&curtrack_id3, 0, sizeof(struct mp3entry)); memset(&curtrack_id3, 0, sizeof(struct mp3entry));
memset(&nexttrack_id3, 0, sizeof(struct mp3entry)); memset(&nexttrack_id3, 0, sizeof(struct mp3entry));
} }
@ -3040,7 +3042,6 @@ static void audio_thread(void)
if (!playing || playlist_end || ci.stop_codec) if (!playing || playlist_end || ci.stop_codec)
break; break;
audio_fill_file_buffer(false, 0); audio_fill_file_buffer(false, 0);
register_buffer_low_callback(low_buffer_callback);
break; break;
case Q_AUDIO_PLAY: case Q_AUDIO_PLAY:
@ -3133,6 +3134,10 @@ static void audio_thread(void)
#endif #endif
usb_acknowledge(SYS_USB_CONNECTED_ACK); usb_acknowledge(SYS_USB_CONNECTED_ACK);
usb_wait_for_disconnect(&audio_queue); usb_wait_for_disconnect(&audio_queue);
/* Mark all entries null. */
audio_clear_track_entries(false);
/* release tracks to make sure all handles are closed */ /* release tracks to make sure all handles are closed */
audio_release_tracks(); audio_release_tracks();
break; break;