decoder/sndfile: use decoder_read()

.. instead of InputStream::LockRead(). The former is cancellable.
This commit is contained in:
Max Kellermann 2014-07-11 20:50:44 +02:00
parent eb79d83051
commit 0ef843f138
2 changed files with 23 additions and 16 deletions

1
NEWS
View File

@ -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

View File

@ -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);
size_t nbytes = sis.Read((char *)ptr + total_bytes,
count - total_bytes);
if (nbytes == 0)
return -1;
}
break;
}
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;