aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2014-07-11 20:50:44 +0200
committerMax Kellermann <max@duempel.org>2014-07-11 21:18:44 +0200
commit0ef843f138c3eef1119e393287ca484bf32f8738 (patch)
tree56388610e6544083b247c154b83c17770d602fd0
parenteb79d830517e9668fa31c5615083296ebdff04fe (diff)
downloadmpd-0ef843f138c3eef1119e393287ca484bf32f8738.tar.gz
mpd-0ef843f138c3eef1119e393287ca484bf32f8738.tar.xz
mpd-0ef843f138c3eef1119e393287ca484bf32f8738.zip
decoder/sndfile: use decoder_read()
.. instead of InputStream::LockRead(). The former is cancellable.
-rw-r--r--NEWS1
-rw-r--r--src/decoder/SndfileDecoderPlugin.cxx38
2 files changed, 23 insertions, 16 deletions
diff --git a/NEWS b/NEWS
index 198ada6a9..1deecbe56 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,7 @@ ver 0.18.12 (not yet released)
- audiofile: improve responsiveness
- audiofile: fix WAV stream playback
- dsdiff, dsf: fix stream playback
+ - sndfile: improve responsiveness
* randomize next song when enabling "random" mode while not playing
* randomize next song when adding to single-song queue
diff --git a/src/decoder/SndfileDecoderPlugin.cxx b/src/decoder/SndfileDecoderPlugin.cxx
index 4082f3e0f..5b2913c13 100644
--- a/src/decoder/SndfileDecoderPlugin.cxx
+++ b/src/decoder/SndfileDecoderPlugin.cxx
@@ -31,10 +31,20 @@
static constexpr Domain sndfile_domain("sndfile");
+struct SndfileInputStream {
+ Decoder *const decoder;
+ InputStream &is;
+
+ size_t Read(void *buffer, size_t size) {
+ return decoder_read(decoder, is, buffer, size);
+ }
+};
+
static sf_count_t
sndfile_vio_get_filelen(void *user_data)
{
- const InputStream &is = *(const InputStream *)user_data;
+ SndfileInputStream &sis = *(SndfileInputStream *)user_data;
+ const InputStream &is = sis.is;
return is.GetSize();
}
@@ -42,7 +52,8 @@ sndfile_vio_get_filelen(void *user_data)
static sf_count_t
sndfile_vio_seek(sf_count_t offset, int whence, void *user_data)
{
- InputStream &is = *(InputStream *)user_data;
+ SndfileInputStream &sis = *(SndfileInputStream *)user_data;
+ InputStream &is = sis.is;
Error error;
if (!is.LockSeek(offset, whence, error)) {
@@ -56,25 +67,18 @@ sndfile_vio_seek(sf_count_t offset, int whence, void *user_data)
static sf_count_t
sndfile_vio_read(void *ptr, sf_count_t count, void *user_data)
{
- InputStream &is = *(InputStream *)user_data;
+ SndfileInputStream &sis = *(SndfileInputStream *)user_data;
sf_count_t total_bytes = 0;
- Error error;
/* 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;
- }
+ size_t nbytes = sis.Read((char *)ptr + total_bytes,
+ count - total_bytes);
+ if (nbytes == 0)
+ return -1;
total_bytes += nbytes;
} while (total_bytes < count);
@@ -94,7 +98,8 @@ sndfile_vio_write(gcc_unused const void *ptr,
static sf_count_t
sndfile_vio_tell(void *user_data)
{
- const InputStream &is = *(const InputStream *)user_data;
+ SndfileInputStream &sis = *(SndfileInputStream *)user_data;
+ const InputStream &is = sis.is;
return is.GetOffset();
}
@@ -140,7 +145,8 @@ sndfile_stream_decode(Decoder &decoder, InputStream &is)
info.format = 0;
- sf = sf_open_virtual(&vio, SFM_READ, &info, &is);
+ SndfileInputStream sis{&decoder, is};
+ sf = sf_open_virtual(&vio, SFM_READ, &info, &sis);
if (sf == nullptr) {
LogWarning(sndfile_domain, "sf_open_virtual() failed");
return;