From 37f026a0a67b9014754e4ab1fcc22229e384fee3 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@duempel.org>
Date: Wed, 5 Oct 2011 22:13:13 +0200
Subject: [PATCH] player_thread: handle SEEK while not playing

---
 NEWS                |  3 +++
 src/player_thread.c | 12 ++++++++++--
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/NEWS b/NEWS
index df870fc48..7e7f128c3 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,9 @@ ver 0.16.5 (2010/??/??)
   - ffmpeg: higher precision timestamps
   - ffmpeg: don't require key frame for seeking
   - fix CUE track seeking
+* player:
+  - make seeking to CUE track more reliable
+  - the "seek" command works when MPD is stopped
 * WIN32: close sockets properly
 * install systemd service file if systemd is available
 
diff --git a/src/player_thread.c b/src/player_thread.c
index b63758544..31bb3d50d 100644
--- a/src/player_thread.c
+++ b/src/player_thread.c
@@ -145,8 +145,12 @@ player_dc_start(struct player *player, struct music_pipe *pipe)
 	assert(player->queued || pc.command == PLAYER_COMMAND_SEEK);
 	assert(pc.next_song != NULL);
 
+	unsigned start_ms = pc.next_song->start_ms;
+	if (pc.command == PLAYER_COMMAND_SEEK)
+		start_ms += (unsigned)(pc.seek_where * 1000);
+
 	dc_start(dc, pc.next_song,
-		 pc.next_song->start_ms, pc.next_song->end_ms,
+		 start_ms, pc.next_song->end_ms,
 		 player_buffer, pipe);
 }
 
@@ -835,6 +839,10 @@ static void do_play(struct decoder_control *dc)
 	}
 
 	player_lock();
+
+	if (pc.command == PLAYER_COMMAND_SEEK)
+		player.elapsed_time = pc.seek_where;
+
 	pc.state = PLAYER_STATE_PLAY;
 	player_command_finished_locked();
 
@@ -1013,6 +1021,7 @@ static gpointer player_task(G_GNUC_UNUSED gpointer arg)
 
 	while (1) {
 		switch (pc.command) {
+		case PLAYER_COMMAND_SEEK:
 		case PLAYER_COMMAND_QUEUE:
 			assert(pc.next_song != NULL);
 
@@ -1026,7 +1035,6 @@ static gpointer player_task(G_GNUC_UNUSED gpointer arg)
 
 			/* fall through */
 
-		case PLAYER_COMMAND_SEEK:
 		case PLAYER_COMMAND_PAUSE:
 			pc.next_song = NULL;
 			player_command_finished_locked();