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
This commit is contained in:
Thomas Martitz 2011-11-03 21:51:46 +00:00
parent 00c536878e
commit cf01d23d0d

View file

@ -828,6 +828,16 @@ bufpanic:
/* Buffer must not move. */ /* Buffer must not move. */
static int shrink_callback(int handle, unsigned hints, void* start, size_t old_size) 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; long offset = audio_current_track()->offset;
int status = audio_status(); int status = audio_status();
/* TODO: Do it without stopping playback, if possible */ /* 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 #ifdef PLAYBACK_VOICE
voice_stop(); voice_stop();
#endif #endif
/* we should be free to change the buffer now */ /* we should be free to change the buffer now
size_t wanted_size = (hints & BUFLIB_SHRINK_SIZE_MASK); * set final buffer size before calling audio_reset_buffer_noalloc()
ssize_t size = (ssize_t)old_size - wanted_size; * (now it's the total size, the call will subtract voice etc) */
/* set final buffer size before calling audio_reset_buffer_noalloc() */
filebuflen = size; filebuflen = size;
switch (hints & BUFLIB_SHRINK_POS_MASK) switch (hints & BUFLIB_SHRINK_POS_MASK)
{ {