summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS1
-rw-r--r--src/decoder/SndfileDecoderPlugin.cxx26
2 files changed, 21 insertions, 6 deletions
diff --git a/NEWS b/NEWS
index 3ab9a5b67..0c30b5eda 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,7 @@ ver 0.18.10 (not yet released)
- ffmpeg: fix seeking bug
- ffmpeg: handle unknown stream start time
- gme: fix memory leak
+ - sndfile: work around libsndfile bug on partial read
* don't interrupt playback when current song gets deleted
ver 0.18.9 (2014/03/02)
diff --git a/src/decoder/SndfileDecoderPlugin.cxx b/src/decoder/SndfileDecoderPlugin.cxx
index 3360cd1bf..77b132962 100644
--- a/src/decoder/SndfileDecoderPlugin.cxx
+++ b/src/decoder/SndfileDecoderPlugin.cxx
@@ -55,14 +55,28 @@ sndfile_vio_read(void *ptr, sf_count_t count, void *user_data)
{
InputStream &is = *(InputStream *)user_data;
+ sf_count_t total_bytes = 0;
Error error;
- size_t nbytes = is.LockRead(ptr, count, error);
- if (nbytes == 0 && error.IsDefined()) {
- LogError(error);
- return -1;
- }
- return nbytes;
+ /* this loop is necessary because libsndfile chokes on partial
+ reads */
+
+ do {
+ size_t nbytes = is.LockRead((char *)ptr + total_bytes,
+ count - total_bytes, error);
+ if (nbytes == 0) {
+ if (error.IsDefined()) {
+ LogError(error);
+ return -1;
+ }
+
+ break;
+ }
+
+ total_bytes += nbytes;
+ } while (total_bytes < count);
+
+ return total_bytes;
}
static sf_count_t