diff options
author | Max Kellermann <max@musicpd.org> | 2019-03-17 23:14:59 +0100 |
---|---|---|
committer | Max Kellermann <max@musicpd.org> | 2019-03-17 23:14:59 +0100 |
commit | 6d12c2265372b621d8400e723238631ca9d2ebcf (patch) | |
tree | 582d99c283cdb2fd45920c3f1690f61682d035f4 /src/lib | |
parent | b76d78e6aeae5a6e638194fed03bd003d5b9f49d (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.cxx | 9 | ||||
-rw-r--r-- | src/lib/xiph/OggVisitor.hxx | 8 |
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) {} |