aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2014-08-31 13:58:04 +0200
committerMax Kellermann <max@duempel.org>2014-08-31 14:01:57 +0200
commit2406152576b512c6fedb4eb3b6d3849448d84e6b (patch)
treece0f3ee03f4d58a58e581c5de6fa60454a868136
parentaf260b5a64b038c61d987d9ca7e3a3e96c656cde (diff)
downloadmpd-2406152576b512c6fedb4eb3b6d3849448d84e6b.tar.gz
mpd-2406152576b512c6fedb4eb3b6d3849448d84e6b.tar.xz
mpd-2406152576b512c6fedb4eb3b6d3849448d84e6b.zip
output/alsa: fix endless loop at end of file in dsd_usb mode
-rw-r--r--NEWS2
-rw-r--r--src/output/AlsaOutputPlugin.cxx9
2 files changed, 11 insertions, 0 deletions
diff --git a/NEWS b/NEWS
index 22eda0f14..2736762a4 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,8 @@ ver 0.18.13 (not yet released)
- dsdiff, dsf: fix endless loop on malformed file
- ffmpeg: support ffmpeg/libav version 11
- gme: fix song duration
+* output
+ - alsa: fix endless loop at end of file in dsd_usb mode
* fix state file saver
* fix build failure on Darwin
diff --git a/src/output/AlsaOutputPlugin.cxx b/src/output/AlsaOutputPlugin.cxx
index 76eea5bd6..f8aae13a1 100644
--- a/src/output/AlsaOutputPlugin.cxx
+++ b/src/output/AlsaOutputPlugin.cxx
@@ -815,7 +815,16 @@ alsa_play(struct audio_output *ao, const void *chunk, size_t size,
}
}
+ const size_t original_size = size;
chunk = ad->pcm_export->Export(chunk, size, size);
+ if (size == 0)
+ /* the DoP (DSD over PCM) filter converts two frames
+ at a time and ignores the last odd frame; if there
+ was only one frame (e.g. the last frame in the
+ file), the result is empty; to avoid an endless
+ loop, bail out here, and pretend the one frame has
+ been played */
+ return original_size;
assert(size % ad->out_frame_size == 0);