diff options
author | Max Kellermann <max@duempel.org> | 2011-10-06 22:45:02 +0200 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2011-10-06 22:45:02 +0200 |
commit | 5c0576ca5519d525c6c383cd138da917b67a2810 (patch) | |
tree | 08a6f4b78ec2769265bb210e408a46b36f78be61 /src/decoder | |
parent | 4e909f94113360933b77cf9e67ec54649d48665f (diff) | |
parent | 039b3544902fe479fa2ce31f06de2c08377e0fc5 (diff) | |
download | mpd-5c0576ca5519d525c6c383cd138da917b67a2810.tar.gz mpd-5c0576ca5519d525c6c383cd138da917b67a2810.tar.xz mpd-5c0576ca5519d525c6c383cd138da917b67a2810.zip |
Merge branch 'v0.16.x'
Conflicts:
configure.ac
src/player_control.c
src/player_thread.c
src/playlist_song.c
Diffstat (limited to '')
-rw-r--r-- | src/decoder_api.c | 61 | ||||
-rw-r--r-- | src/decoder_control.c | 3 | ||||
-rw-r--r-- | src/decoder_control.h | 20 | ||||
-rw-r--r-- | src/decoder_thread.c | 2 |
4 files changed, 70 insertions, 16 deletions
diff --git a/src/decoder_api.c b/src/decoder_api.c index a34e19b1a..311f1f31b 100644 --- a/src/decoder_api.c +++ b/src/decoder_api.c @@ -77,30 +77,54 @@ decoder_initialized(struct decoder *decoder, } /** - * Returns the current decoder command. May return a "virtual" - * synthesized command, e.g. to seek to the beginning of the CUE - * track. + * Checks if we need an "initial seek". If so, then the initial seek + * is prepared, and the function returns true. */ G_GNUC_PURE -static enum decoder_command -decoder_get_virtual_command(struct decoder *decoder) +static bool +decoder_prepare_initial_seek(struct decoder *decoder) { const struct decoder_control *dc = decoder->dc; assert(dc->pipe != NULL); if (decoder->initial_seek_running) - return DECODE_COMMAND_SEEK; + /* initial seek has already begun - override any other + command */ + return true; if (decoder->initial_seek_pending) { if (dc->command == DECODE_COMMAND_NONE) { + /* begin initial seek */ + decoder->initial_seek_pending = false; decoder->initial_seek_running = true; - return DECODE_COMMAND_SEEK; + return true; } + /* skip initial seek when there's another command + (e.g. STOP) */ + decoder->initial_seek_pending = false; } + return false; +} + +/** + * Returns the current decoder command. May return a "virtual" + * synthesized command, e.g. to seek to the beginning of the CUE + * track. + */ +G_GNUC_PURE +static enum decoder_command +decoder_get_virtual_command(struct decoder *decoder) +{ + const struct decoder_control *dc = decoder->dc; + assert(dc->pipe != NULL); + + if (decoder_prepare_initial_seek(decoder)) + return DECODE_COMMAND_SEEK; + return dc->command; } @@ -130,7 +154,7 @@ decoder_command_finished(struct decoder *decoder) assert(music_pipe_empty(dc->pipe)); decoder->initial_seek_running = false; - decoder->timestamp = dc->song->start_ms / 1000.; + decoder->timestamp = dc->start_ms / 1000.; decoder_unlock(dc); return; } @@ -162,7 +186,7 @@ double decoder_seek_where(G_GNUC_UNUSED struct decoder * decoder) assert(dc->pipe != NULL); if (decoder->initial_seek_running) - return dc->song->start_ms / 1000.; + return dc->start_ms / 1000.; assert(dc->command == DECODE_COMMAND_SEEK); @@ -177,10 +201,12 @@ void decoder_seek_error(struct decoder * decoder) assert(dc->pipe != NULL); - if (decoder->initial_seek_running) + if (decoder->initial_seek_running) { /* d'oh, we can't seek to the sub-song start position, what now? - no idea, ignoring the problem for now. */ + decoder->initial_seek_running = false; return; + } assert(dc->command == DECODE_COMMAND_SEEK); @@ -424,8 +450,8 @@ decoder_data(struct decoder *decoder, decoder->timestamp += (double)nbytes / audio_format_time_to_size(&dc->out_audio_format); - if (dc->song->end_ms > 0 && - decoder->timestamp >= dc->song->end_ms / 1000.0) + if (dc->end_ms > 0 && + decoder->timestamp >= dc->end_ms / 1000.0) /* the end of this range has been reached: stop decoding */ return DECODE_COMMAND_STOP; @@ -455,6 +481,14 @@ decoder_tag(G_GNUC_UNUSED struct decoder *decoder, struct input_stream *is, update_stream_tag(decoder, is); + /* check if we're seeking */ + + if (decoder_prepare_initial_seek(decoder)) + /* during initial seek, no music chunk must be created + until seeking is finished; skip the rest of the + function here */ + return DECODE_COMMAND_SEEK; + /* send tag to music pipe */ if (decoder->stream_tag != NULL) { @@ -468,9 +502,6 @@ decoder_tag(G_GNUC_UNUSED struct decoder *decoder, struct input_stream *is, /* send only the decoder tag */ cmd = do_send_tag(decoder, tag); - if (cmd == DECODE_COMMAND_NONE) - cmd = decoder_get_virtual_command(decoder); - return cmd; } diff --git a/src/decoder_control.c b/src/decoder_control.c index 685db6c22..70f34b331 100644 --- a/src/decoder_control.c +++ b/src/decoder_control.c @@ -96,6 +96,7 @@ dc_command_async(struct decoder_control *dc, enum decoder_command cmd) void dc_start(struct decoder_control *dc, struct song *song, + unsigned start_ms, unsigned end_ms, struct music_buffer *buffer, struct music_pipe *pipe) { assert(song != NULL); @@ -104,6 +105,8 @@ dc_start(struct decoder_control *dc, struct song *song, assert(music_pipe_empty(pipe)); dc->song = song; + dc->start_ms = start_ms; + dc->end_ms = end_ms; dc->buffer = buffer; dc->pipe = pipe; dc_command(dc, DECODE_COMMAND_START); diff --git a/src/decoder_control.h b/src/decoder_control.h index e1a718a59..566b153ee 100644 --- a/src/decoder_control.h +++ b/src/decoder_control.h @@ -85,6 +85,23 @@ struct decoder_control { */ const struct song *song; + /** + * The initial seek position (in milliseconds), e.g. to the + * start of a sub-track described by a CUE file. + * + * This attribute is set by dc_start(). + */ + unsigned start_ms; + + /** + * The decoder will stop when it reaches this position (in + * milliseconds). 0 means don't stop before the end of the + * file. + * + * This attribute is set by dc_start(). + */ + unsigned end_ms; + float total_time; /** the #music_chunk allocator */ @@ -229,11 +246,14 @@ decoder_current_song(const struct decoder_control *dc) * * @param the decoder * @param song the song to be decoded + * @param start_ms see #decoder_control + * @param end_ms see #decoder_control * @param pipe the pipe which receives the decoded chunks (owned by * the caller) */ void dc_start(struct decoder_control *dc, struct song *song, + unsigned start_ms, unsigned end_ms, struct music_buffer *buffer, struct music_pipe *pipe); void diff --git a/src/decoder_thread.c b/src/decoder_thread.c index dbead655d..c2bb655ea 100644 --- a/src/decoder_thread.c +++ b/src/decoder_thread.c @@ -380,7 +380,7 @@ decoder_run_song(struct decoder_control *dc, { struct decoder decoder = { .dc = dc, - .initial_seek_pending = song->start_ms > 0, + .initial_seek_pending = dc->start_ms > 0, .initial_seek_running = false, }; int ret; |