diff options
author | Max Kellermann <max@musicpd.org> | 2019-08-03 12:30:10 +0200 |
---|---|---|
committer | Max Kellermann <max@musicpd.org> | 2019-08-03 12:30:10 +0200 |
commit | f2d8fd769de98df13568989b7d6d164474380d19 (patch) | |
tree | f2ba317129ef9e6703b0fba27e54f5a5352ea57f | |
parent | 9661062ae2f5b2bb94f3e4f32ef95baabd8ad63a (diff) |
player/Thread: don't restart unseekable song after failed seek attempt
The check IsSeekableCurrentSong() was added by commit
44b200240f1f4b8394dd2e58fec72da3d3ec448f in version 0.20.19, but it
caused a regression: by doing the branch only if the current song is
seekable, the player would restart the current song if it was not
seekable, and later the initial seek would fail; but we already know
it's not seekable, and so we should fail early.
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | src/decoder/Control.hxx | 5 | ||||
-rw-r--r-- | src/player/Thread.cxx | 13 |
3 files changed, 20 insertions, 0 deletions
@@ -6,6 +6,8 @@ ver 0.21.12 (not yet released) - opus, vorbis: decode the "end of stream" packet * output - jack: fix mono-to-stereo conversion +* player + - don't restart unseekable song after failed seek attempt * Windows - support backslash in relative URIs loaded from playlists diff --git a/src/decoder/Control.hxx b/src/decoder/Control.hxx index 1e272255f..385516a62 100644 --- a/src/decoder/Control.hxx +++ b/src/decoder/Control.hxx @@ -321,6 +321,11 @@ public: bool IsCurrentSong(const DetachedSong &_song) const noexcept; gcc_pure + bool IsUnseekableCurrentSong(const DetachedSong &_song) const noexcept { + return !seekable && IsCurrentSong(_song); + } + + gcc_pure bool IsSeekableCurrentSong(const DetachedSong &_song) const noexcept { return seekable && IsCurrentSong(_song); } diff --git a/src/player/Thread.cxx b/src/player/Thread.cxx index 028842b61..05e691bd1 100644 --- a/src/player/Thread.cxx +++ b/src/player/Thread.cxx @@ -599,6 +599,19 @@ Player::SeekDecoder() noexcept { assert(pc.next_song != nullptr); + if (pc.seek_time > SongTime::zero() && // TODO: allow this only if the song duration is known + dc.IsUnseekableCurrentSong(*pc.next_song)) { + /* seeking into the current song; but we already know + it's not seekable, so let's fail early */ + /* note the seek_time>0 check: if seeking to the + beginning, we can simply restart the decoder */ + pc.next_song.reset(); + pc.SetError(PlayerError::DECODER, + std::make_exception_ptr(std::runtime_error("Not seekable"))); + pc.CommandFinished(); + return true; + } + CancelPendingSeek(); { |