summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Kellermann <max@musicpd.org>2019-08-03 12:30:10 +0200
committerMax Kellermann <max@musicpd.org>2019-08-03 12:30:10 +0200
commitf2d8fd769de98df13568989b7d6d164474380d19 (patch)
treef2ba317129ef9e6703b0fba27e54f5a5352ea57f
parent9661062ae2f5b2bb94f3e4f32ef95baabd8ad63a (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--NEWS2
-rw-r--r--src/decoder/Control.hxx5
-rw-r--r--src/player/Thread.cxx13
3 files changed, 20 insertions, 0 deletions
diff --git a/NEWS b/NEWS
index 1f40838f0..a4cade59e 100644
--- a/NEWS
+++ b/NEWS
@@ -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();
{