summaryrefslogtreecommitdiffstats
path: root/apps/playback.c
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2011-11-03 21:51:46 +0000
committerThomas Martitz <kugel@rockbox.org>2011-11-03 21:51:46 +0000
commitcf01d23d0d940e74ef77f86df328ce9b6411e97a (patch)
tree480e147a775b05be5745fd4a7f5df970b64b4dd9 /apps/playback.c
parent00c536878e62c85db5556fbd29cb05292f70e94f (diff)
downloadrockbox-cf01d23d0d940e74ef77f86df328ce9b6411e97a.tar.gz
rockbox-cf01d23d0d940e74ef77f86df328ce9b6411e97a.tar.bz2
rockbox-cf01d23d0d940e74ef77f86df328ce9b6411e97a.zip
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
Diffstat (limited to 'apps/playback.c')
-rw-r--r--apps/playback.c17
1 files changed, 13 insertions, 4 deletions
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)
{