diff options
author | Max Kellermann <max@duempel.org> | 2009-10-08 22:09:25 +0200 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2009-10-08 22:09:25 +0200 |
commit | 448aefaace840ccd8b8c1fb82ff72ef986b84f12 (patch) | |
tree | 2433cdab57c247e96c5f2576b02bb9d6ac0cc022 | |
parent | 47b5e73a151f1ccc506f454eaafc5c65885ff0a3 (diff) | |
download | mpd-448aefaace840ccd8b8c1fb82ff72ef986b84f12.tar.gz mpd-448aefaace840ccd8b8c1fb82ff72ef986b84f12.tar.xz mpd-448aefaace840ccd8b8c1fb82ff72ef986b84f12.zip |
player_thread: get "elapsed" from audio outputs
Tracking the "elapsed" time from the chunks which we have sent to the
output pipe is very imprecise: since we have implemented the music
pipe, we're sending large number of chunks at once, giving the
"elapsed" time stamp a resolution of usually more than a second.
This patch changes the source of this information to the outputs. If
a chunk has been played by all outputs, the "elapsed" time stamp is
updated.
The new command PLAYER_COMMAND_REFRESH makes the player thread update
its status information: it tells the outputs to update the chunk time
stamp. After that, player_control.elapsed_time is current.
Diffstat (limited to '')
-rw-r--r-- | src/output_all.c | 14 | ||||
-rw-r--r-- | src/output_all.h | 7 | ||||
-rw-r--r-- | src/player_control.c | 2 | ||||
-rw-r--r-- | src/player_control.h | 6 | ||||
-rw-r--r-- | src/player_thread.c | 17 |
5 files changed, 42 insertions, 4 deletions
diff --git a/src/output_all.c b/src/output_all.c index 4b5ba3a6f..b7a42a6a3 100644 --- a/src/output_all.c +++ b/src/output_all.c @@ -52,6 +52,11 @@ static struct music_buffer *g_music_buffer; */ static struct music_pipe *g_mp; +/** + * The "elapsed_time" stamp of the most recently finished chunk. + */ +static float audio_output_all_elapsed_time; + unsigned int audio_output_count(void) { return num_audio_outputs; @@ -385,6 +390,8 @@ audio_output_all_check(void) this chunk */ return music_pipe_size(g_mp); + audio_output_all_elapsed_time = chunk->times; + is_tail = chunk->next == NULL; if (is_tail) /* this is the tail of the pipe - clear the @@ -468,9 +475,16 @@ audio_output_all_close(void) music_pipe_clear(g_mp, g_music_buffer); music_pipe_free(g_mp); g_mp = NULL; + audio_output_all_elapsed_time = 0.0; } g_music_buffer = NULL; audio_format_clear(&input_audio_format); } + +float +audio_output_all_get_elapsed_time(void) +{ + return audio_output_all_elapsed_time; +} diff --git a/src/output_all.h b/src/output_all.h index 2a09514b2..e124d3150 100644 --- a/src/output_all.h +++ b/src/output_all.h @@ -128,4 +128,11 @@ audio_output_all_pause(void); void audio_output_all_cancel(void); +/** + * Returns the "elapsed_time" stamp of the most recently finished + * chunk. + */ +float +audio_output_all_get_elapsed_time(void); + #endif diff --git a/src/player_control.c b/src/player_control.c index 38d960031..25a0320c5 100644 --- a/src/player_control.c +++ b/src/player_control.c @@ -142,6 +142,8 @@ pc_set_pause(bool pause_flag) void pc_get_status(struct player_status *status) { + player_command(PLAYER_COMMAND_REFRESH); + status->state = pc.state; if (pc.state != PLAYER_STATE_STOP) { diff --git a/src/player_control.h b/src/player_control.h index 1acdb5686..e9a43e844 100644 --- a/src/player_control.h +++ b/src/player_control.h @@ -48,6 +48,12 @@ enum player_command { * stop */ PLAYER_COMMAND_CANCEL, + + /** + * Refresh status information in the #player_control struct, + * e.g. elapsed_time. + */ + PLAYER_COMMAND_REFRESH, }; enum player_error { diff --git a/src/player_thread.c b/src/player_thread.c index 7368b4d4b..6777d5d61 100644 --- a/src/player_thread.c +++ b/src/player_thread.c @@ -151,7 +151,6 @@ player_wait_for_decoder(struct player *player) player->song = pc.next_song; pc.next_song = NULL; - pc.elapsed_time = 0; player->queued = false; /* set the "starting" flag, which will be cleared by @@ -330,7 +329,6 @@ static bool player_seek_decoder(struct player *player) return false; } - pc.elapsed_time = where; player_command_finished(); player->xfade = XFADE_UNKNOWN; @@ -409,6 +407,14 @@ static void player_process_command(struct player *player) player->queued = false; player_command_finished(); break; + + case PLAYER_COMMAND_REFRESH: + if (audio_format_defined(&player->play_audio_format)) + audio_output_all_check(); + + pc.elapsed_time = audio_output_all_get_elapsed_time(); + player_command_finished(); + break; } } @@ -456,7 +462,6 @@ play_chunk(struct song *song, struct music_chunk *chunk, return true; } - pc.elapsed_time = chunk->times; pc.bit_rate = chunk->bit_rate; /* send the chunk to the audio outputs */ @@ -630,7 +635,6 @@ static void do_play(void) return; } - pc.elapsed_time = 0; pc.state = PLAYER_STATE_PLAY; player_command_finished(); @@ -813,6 +817,11 @@ static gpointer player_task(G_GNUC_UNUSED gpointer arg) player_command_finished(); break; + case PLAYER_COMMAND_REFRESH: + /* no-op when not playing */ + player_command_finished(); + break; + case PLAYER_COMMAND_NONE: notify_wait(&pc.notify); break; |