diff options
| author | Thomas Martitz <kugel@rockbox.org> | 2011-11-17 17:55:02 +0000 |
|---|---|---|
| committer | Thomas Martitz <kugel@rockbox.org> | 2011-11-17 17:55:02 +0000 |
| commit | 2a8eacdbfc5d98b016c480ddaddff100301f721f (patch) | |
| tree | 69c79430463bb43c0e3ce96fbef851de6c35b277 /apps/mpeg.c | |
| parent | 91206954aa0818e0790857f25f46a53d8e737a20 (diff) | |
| download | rockbox-2a8eacdbfc5d98b016c480ddaddff100301f721f.zip rockbox-2a8eacdbfc5d98b016c480ddaddff100301f721f.tar.gz rockbox-2a8eacdbfc5d98b016c480ddaddff100301f721f.tar.bz2 rockbox-2a8eacdbfc5d98b016c480ddaddff100301f721f.tar.xz | |
Buflib: Make shrinking and buflib_available() smarter.
* shrinking now considers freespace just before the alloc-to-be-shrinked,
that means less (or sometimes none at all) is taken from the audio buffer.
* core_available() now searches for the best free space, instead of simply the end,
i.e. it will not return 0 if the audio buffer is allocated and there's free space
before it. It also runs a compaction to ensure maximum contiguous memory.
audio_buffer_available() is also enhanced. It now considers the 256K reserve buffer,
and returns free buflib space instead if the audio buffer is short.
This all fixes the root problem of FS#12344 (Sansa Clip+: PANIC occurred when
dircache is enabled), that alloced from the audio buffer, even if it was very
short and buflib had many more available as free space before it.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@31006 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/mpeg.c')
| -rw-r--r-- | apps/mpeg.c | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/apps/mpeg.c b/apps/mpeg.c index ae33ccc..698695b 100644 --- a/apps/mpeg.c +++ b/apps/mpeg.c @@ -151,7 +151,7 @@ static bool paused; /* playback is paused */ static int audiobuf_handle; /* handle to the audio buffer */ static char* mpeg_audiobuf; /* poiunter to the audio buffer */ static long audiobuflen; /* length of the audio buffer */ - +#define AUDIO_BUFFER_RESERVE (256*1024) #ifdef SIMULATOR static char mpeg_stack[DEFAULT_STACK_SIZE]; static struct mp3entry taginfo; @@ -515,9 +515,16 @@ static void audio_reset_buffer_noalloc(void* buf, size_t bufsize); /* Buffer must not move. */ static int shrink_callback(int handle, unsigned hints, void* start, size_t old_size) { - long offset = audio_current_track()->offset; - bool playing = (audio_status() & AUDIO_STATUS_PLAY) == AUDIO_STATUS_PLAY; + ssize_t extradata_size = old_size - audiobuflen; + /* check what buflib requests */ + size_t wanted_size = (hints & BUFLIB_SHRINK_SIZE_MASK); + ssize_t size = (ssize_t)old_size - wanted_size; + /* keep at least 256K for the buffering */ + if ((size - extradata_size) < AUDIO_BUFFER_RESERVE) + return BUFLIB_CB_CANNOT_SHRINK; /* TODO: Do it without stopping playback, if possible */ + bool playing = (audio_status() & AUDIO_STATUS_PLAY) == AUDIO_STATUS_PLAY; + long offset = audio_current_track()->offset; /* don't call audio_hard_stop() as it frees this handle */ if (thread_self() == audio_thread_id) { /* inline case MPEG_STOP (audio_stop()) response @@ -528,9 +535,6 @@ static int shrink_callback(int handle, unsigned hints, void* start, size_t old_s audio_stop(); talk_buffer_steal(); /* we obtain control over the buffer */ - /* we should be free to change the buffer now */ - size_t wanted_size = (hints & BUFLIB_SHRINK_SIZE_MASK); - ssize_t size = (ssize_t)old_size - wanted_size; switch (hints & BUFLIB_SHRINK_POS_MASK) { case BUFLIB_SHRINK_POS_BACK: @@ -2742,11 +2746,20 @@ void audio_set_recording_options(struct audio_recording_options *options) #endif /* SIMULATOR */ #endif /* CONFIG_CODEC == MAS3587F */ -size_t audio_buffer_available(void) +size_t audio_buffer_size(void) { if (audiobuf_handle > 0) return audiobuflen; - return core_available(); + return 0; +} + +size_t audio_buffer_available(void) +{ + size_t size = 0; + size_t core_size = core_available(); + if (audiobuf_handle > 0) + return audiobuflen - AUDIO_BUFFER_RESERVE - 128; + return MAX(core_size, size); } static void audio_reset_buffer_noalloc(void* buf, size_t bufsize) |