From cf01d23d0d940e74ef77f86df328ce9b6411e97a Mon Sep 17 00:00:00 2001 From: Thomas Martitz Date: Thu, 3 Nov 2011 21:51:46 +0000 Subject: In the playback buflib shrink callback, ensure a minimum buffer remains for audio playback. If it goes below 256K new buflib allocations fail. This prevents buffer underruns as the new buffer size wasn't actually checked at all. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30893 a1c6a512-1295-4272-9138-f99709370657 --- apps/playback.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'apps/playback.c') diff --git a/apps/playback.c b/apps/playback.c index d2150f6a00..9bbce17a0a 100644 --- a/apps/playback.c +++ b/apps/playback.c @@ -828,6 +828,16 @@ bufpanic: /* Buffer must not move. */ static int shrink_callback(int handle, unsigned hints, void* start, size_t old_size) { + /* filebuflen is, at this point, the buffering.c buffer size, + * i.e. the audiobuf except voice, scratch mem, pcm, ... */ + ssize_t extradata_size = old_size - filebuflen; + /* 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) < 256*1024) + return BUFLIB_CB_CANNOT_SHRINK; + long offset = audio_current_track()->offset; int status = audio_status(); /* TODO: Do it without stopping playback, if possible */ @@ -843,10 +853,9 @@ static int shrink_callback(int handle, unsigned hints, void* start, size_t old_s #ifdef PLAYBACK_VOICE voice_stop(); #endif - /* 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; - /* set final buffer size before calling audio_reset_buffer_noalloc() */ + /* we should be free to change the buffer now + * set final buffer size before calling audio_reset_buffer_noalloc() + * (now it's the total size, the call will subtract voice etc) */ filebuflen = size; switch (hints & BUFLIB_SHRINK_POS_MASK) { -- cgit v1.2.3