diff options
Diffstat (limited to '')
-rw-r--r-- | src/decoder_control.c | 8 | ||||
-rw-r--r-- | src/decoder_control.h | 42 | ||||
-rw-r--r-- | src/decoder_thread.c | 20 | ||||
-rw-r--r-- | src/player_thread.c | 4 |
4 files changed, 44 insertions, 30 deletions
diff --git a/src/decoder_control.c b/src/decoder_control.c index a1719a6f6..efc8ac797 100644 --- a/src/decoder_control.c +++ b/src/decoder_control.c @@ -27,7 +27,6 @@ void dc_init(void) notify_init(&dc.notify); dc.state = DECODE_STATE_STOP; dc.command = DECODE_COMMAND_NONE; - dc.error = DECODE_ERROR_NOERROR; } void dc_deinit(void) @@ -63,7 +62,6 @@ dc_start(struct notify *notify, struct song *song) assert(song != NULL); dc.next_song = song; - dc.error = DECODE_ERROR_NOERROR; dc_command(notify, DECODE_COMMAND_START); } @@ -73,7 +71,6 @@ dc_start_async(struct song *song) assert(song != NULL); dc.next_song = song; - dc.error = DECODE_ERROR_NOERROR; dc_command_async(DECODE_COMMAND_START); } @@ -81,7 +78,7 @@ void dc_stop(struct notify *notify) { if (dc.command == DECODE_COMMAND_START || - dc.state != DECODE_STATE_STOP) + (dc.state != DECODE_STATE_STOP && dc.state != DECODE_STATE_ERROR)) dc_command(notify, DECODE_COMMAND_STOP); } @@ -90,7 +87,8 @@ dc_seek(struct notify *notify, double where) { assert(where >= 0.0); - if (dc.state == DECODE_STATE_STOP || !dc.seekable) + if (dc.state == DECODE_STATE_STOP || + dc.state == DECODE_STATE_ERROR || !dc.seekable) return false; dc.seek_where = where; diff --git a/src/decoder_control.h b/src/decoder_control.h index c710d3038..e9fa449e6 100644 --- a/src/decoder_control.h +++ b/src/decoder_control.h @@ -25,19 +25,23 @@ #include "audio_format.h" #include "notify.h" +#include <assert.h> + #define DECODE_TYPE_FILE 0 #define DECODE_TYPE_URL 1 enum decoder_state { DECODE_STATE_STOP = 0, DECODE_STATE_START, - DECODE_STATE_DECODE -}; - -enum decoder_error { - DECODE_ERROR_NOERROR = 0, - DECODE_ERROR_UNKTYPE, - DECODE_ERROR_FILE, + DECODE_STATE_DECODE, + + /** + * The last "START" command failed, because there was an I/O + * error or because no decoder was able to decode the file. + * This state will only come after START; once the state has + * turned to DECODE, by definition no such error can occur. + */ + DECODE_STATE_ERROR, }; struct decoder_control { @@ -45,7 +49,6 @@ struct decoder_control { volatile enum decoder_state state; volatile enum decoder_command command; - volatile enum decoder_error error; bool seek_error; bool seekable; volatile double seek_where; @@ -69,7 +72,8 @@ void dc_deinit(void); static inline bool decoder_is_idle(void) { - return dc.state == DECODE_STATE_STOP && + return (dc.state == DECODE_STATE_STOP || + dc.state == DECODE_STATE_ERROR) && dc.command != DECODE_COMMAND_START; } @@ -79,14 +83,28 @@ static inline bool decoder_is_starting(void) dc.state == DECODE_STATE_START; } +static inline bool decoder_has_failed(void) +{ + assert(dc.command == DECODE_COMMAND_NONE); + + return dc.state == DECODE_STATE_ERROR; +} + static inline struct song * decoder_current_song(void) { - if (dc.state == DECODE_STATE_STOP || - dc.error != DECODE_ERROR_NOERROR) + switch (dc.state) { + case DECODE_STATE_STOP: + case DECODE_STATE_ERROR: return NULL; - return dc.current_song; + case DECODE_STATE_START: + case DECODE_STATE_DECODE: + return dc.current_song; + } + + assert(false); + return NULL; } void diff --git a/src/decoder_thread.c b/src/decoder_thread.c index 7c870d6e7..23a947d77 100644 --- a/src/decoder_thread.c +++ b/src/decoder_thread.c @@ -61,13 +61,13 @@ static void decoder_run(void) else uri = song_get_url(song, buffer); if (uri == NULL) { - dc.error = DECODE_ERROR_FILE; + dc.state = DECODE_STATE_ERROR; return; } dc.current_song = dc.next_song; /* NEED LOCK */ if (!input_stream_open(&input_stream, uri)) { - dc.error = DECODE_ERROR_FILE; + dc.state = DECODE_STATE_ERROR; return; } @@ -84,19 +84,21 @@ static void decoder_run(void) while (!input_stream.ready) { if (dc.command != DECODE_COMMAND_NONE) { input_stream_close(&input_stream); + dc.state = DECODE_STATE_STOP; return; } ret = input_stream_buffer(&input_stream); if (ret < 0) { input_stream_close(&input_stream); - dc.error = DECODE_ERROR_FILE; + dc.state = DECODE_STATE_ERROR; return; } } if (dc.command == DECODE_COMMAND_STOP) { input_stream_close(&input_stream); + dc.state = DECODE_STATE_STOP; return; } @@ -161,27 +163,23 @@ static void decoder_run(void) music_pipe_flush(); - if (!ret) { - dc.error = plugin == NULL - ? DECODE_ERROR_UNKTYPE - : DECODE_ERROR_FILE; - } - if (close_instream) input_stream_close(&input_stream); + + dc.state = ret ? DECODE_STATE_STOP : DECODE_STATE_ERROR; } static void * decoder_task(mpd_unused void *arg) { while (1) { - assert(dc.state == DECODE_STATE_STOP); + assert(dc.state == DECODE_STATE_STOP || + dc.state == DECODE_STATE_ERROR); switch (dc.command) { case DECODE_COMMAND_START: case DECODE_COMMAND_SEEK: decoder_run(); - dc.state = DECODE_STATE_STOP; dc.command = DECODE_COMMAND_NONE; notify_signal(&pc.notify); break; diff --git a/src/player_thread.c b/src/player_thread.c index 484c8deb7..30f876fe0 100644 --- a/src/player_thread.c +++ b/src/player_thread.c @@ -93,7 +93,7 @@ static int player_wait_for_decoder(struct player *player) { dc_command_wait(&pc.notify); - if (dc.error != DECODE_ERROR_NOERROR) { + if (decoder_has_failed()) { assert(dc.next_song == NULL || dc.next_song->url != NULL); pc.errored_song = dc.next_song; pc.error = PLAYER_ERROR_FILE; @@ -305,7 +305,7 @@ static void do_play(void) } if (player.decoder_starting) { - if (dc.error != DECODE_ERROR_NOERROR) { + if (decoder_has_failed()) { /* the decoder failed */ assert(dc.next_song == NULL || dc.next_song->url != NULL); pc.errored_song = dc.next_song; |