diff options
Diffstat (limited to '')
-rw-r--r-- | src/player_thread.c | 60 |
1 files changed, 42 insertions, 18 deletions
diff --git a/src/player_thread.c b/src/player_thread.c index 13d1c2ebb..2d8822eb0 100644 --- a/src/player_thread.c +++ b/src/player_thread.c @@ -149,6 +149,32 @@ player_dc_start(struct player *player, struct music_pipe *pipe) } /** + * Is the decoder still busy on the same song as the player? + * + * Note: this function does not check if the decoder is already + * finished. + */ +static bool +player_dc_at_current_song(const struct player *player) +{ + assert(player != NULL); + assert(player->pipe != NULL); + + return player->dc->pipe == player->pipe; +} + +/** + * Returns true if the decoder is decoding the next song (or has begun + * decoding it, or has finished doing it), and the player hasn't + * switched to that song yet. + */ +static bool +player_dc_at_next_song(const struct player *player) +{ + return player->dc->pipe != NULL && !player_dc_at_current_song(player); +} + +/** * Stop the decoder and clears (and frees) its music pipe. * * Player lock is not held. @@ -173,17 +199,6 @@ player_dc_stop(struct player *player) } /** - * Returns true if the decoder is decoding the next song (or has begun - * decoding it, or has finished doing it), and the player hasn't - * switched to that song yet. - */ -static bool -decoding_next_song(const struct player *player) -{ - return player->dc->pipe != NULL && player->dc->pipe != player->pipe; -} - -/** * After the decoder has been started asynchronously, wait for the * "START" command to finish. The decoder may not be initialized yet, * i.e. there is no audio_format information yet. @@ -405,6 +420,14 @@ static bool player_seek_decoder(struct player *player) return false; } } else { + if (!player_dc_at_current_song(player)) { + /* the decoder is already decoding the "next" song, + but it is the same song file; exchange the pipe */ + music_pipe_clear(player->pipe, player_buffer); + music_pipe_free(player->pipe); + player->pipe = dc->pipe; + } + pc.next_song = NULL; player->queued = false; } @@ -473,7 +496,7 @@ static void player_process_command(struct player *player) case PLAYER_COMMAND_QUEUE: assert(pc.next_song != NULL); assert(!player->queued); - assert(dc->pipe == NULL || dc->pipe == player->pipe); + assert(!player_dc_at_next_song(player)); player->queued = true; player_command_finished_locked(); @@ -527,7 +550,7 @@ static void player_process_command(struct player *player) return; } - if (decoding_next_song(player)) { + if (player_dc_at_next_song(player)) { /* the decoder is already decoding the song - stop it and reset the position */ player_unlock(); @@ -635,7 +658,7 @@ play_next_chunk(struct player *player) return true; if (player->xfade == XFADE_ENABLED && - decoding_next_song(player) && + player_dc_at_next_song(player) && (cross_fade_position = music_pipe_size(player->pipe)) <= player->cross_fade_chunks) { /* perform cross fade */ @@ -881,12 +904,13 @@ static void do_play(struct decoder_control *dc) dc->pipe == player.pipe) { /* the decoder has finished the current song; make it decode the next song */ + assert(dc->pipe == NULL || dc->pipe == player.pipe); player_dc_start(&player, music_pipe_new()); } - if (decoding_next_song(&player) && + if (player_dc_at_next_song(&player) && player.xfade == XFADE_UNKNOWN && !decoder_lock_is_starting(dc)) { /* enable cross fading in this song? if yes, @@ -919,7 +943,7 @@ static void do_play(struct decoder_control *dc) if (pc.command == PLAYER_COMMAND_NONE) player_wait(); continue; - } else if (music_pipe_size(player.pipe) > 0) { + } else if (!music_pipe_empty(player.pipe)) { /* at least one music chunk is ready - send it to the audio output */ @@ -931,7 +955,7 @@ static void do_play(struct decoder_control *dc) /* XXX synchronize in a better way */ g_usleep(10000); - } else if (decoding_next_song(&player)) { + } else if (player_dc_at_next_song(&player)) { /* at the beginning of a new song */ if (!player_song_border(&player)) @@ -940,7 +964,7 @@ static void do_play(struct decoder_control *dc) /* check the size of the pipe again, because the decoder thread may have added something since we last checked */ - if (music_pipe_size(player.pipe) == 0) { + if (music_pipe_empty(player.pipe)) { /* wait for the hardware to finish playback */ audio_output_all_drain(); |