summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorMax Kellermann <max@musicpd.org>2019-03-17 23:14:59 +0100
committerMax Kellermann <max@musicpd.org>2019-03-17 23:14:59 +0100
commit6d12c2265372b621d8400e723238631ca9d2ebcf (patch)
tree582d99c283cdb2fd45920c3f1690f61682d035f4 /src/lib
parentb76d78e6aeae5a6e638194fed03bd003d5b9f49d (diff)
decoder/ogg: ignore the BOS packet after seek to the beginning of song
Previously, MPD would skip the current song after attempting to seek to its beginnig, because that was a seek to offset 0. At offset 0, MPD will see the BOS packet again, which results in throwing StopDecoder in MPDOpusDecoder::OnOggEnd(). Closes https://github.com/MusicPlayerDaemon/MPD/issues/470
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/xiph/OggVisitor.cxx9
-rw-r--r--src/lib/xiph/OggVisitor.hxx8
2 files changed, 17 insertions, 0 deletions
diff --git a/src/lib/xiph/OggVisitor.cxx b/src/lib/xiph/OggVisitor.cxx
index 14ac666a0..b975d8d17 100644
--- a/src/lib/xiph/OggVisitor.cxx
+++ b/src/lib/xiph/OggVisitor.cxx
@@ -20,6 +20,7 @@
#include "OggVisitor.hxx"
#include <stdexcept>
+#include <utility>
void
OggVisitor::EndStream()
@@ -51,7 +52,13 @@ OggVisitor::ReadNextPage()
inline void
OggVisitor::HandlePacket(const ogg_packet &packet)
{
+ const bool _post_seek = std::exchange(post_seek, false);
+
if (packet.b_o_s) {
+ if (_post_seek)
+ /* ignore the BOS packet after seeking */
+ return;
+
EndStream();
has_stream = true;
OnOggBeginning(packet);
@@ -97,4 +104,6 @@ OggVisitor::PostSeek()
/* find the next Ogg page and feed it into the stream */
sync.ExpectPageSeekIn(stream);
+
+ post_seek = true;
}
diff --git a/src/lib/xiph/OggVisitor.hxx b/src/lib/xiph/OggVisitor.hxx
index 4c5e3f14e..a7e6eb9b8 100644
--- a/src/lib/xiph/OggVisitor.hxx
+++ b/src/lib/xiph/OggVisitor.hxx
@@ -39,6 +39,14 @@ class OggVisitor {
bool has_stream = false;
+ /**
+ * This is true after seeking; its one-time effect is to
+ * ignore the BOS packet, just in case we have been seeking to
+ * the beginning of the file, because that would disrupt
+ * playback.
+ */
+ bool post_seek = false;
+
public:
explicit OggVisitor(Reader &reader)
:sync(reader), stream(0) {}