diff options
author | Max Kellermann <max@duempel.org> | 2011-10-06 20:30:46 +0200 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2011-10-06 21:22:48 +0200 |
commit | b2f03e76ffd3af918d8eda0968f54c0b81bbff54 (patch) | |
tree | a504e4ef529b087f27c3ff862088fb27cf18afc0 | |
parent | 63b33b6ec584a6730174c45a119a27b4add76777 (diff) | |
download | mpd-b2f03e76ffd3af918d8eda0968f54c0b81bbff54.tar.gz mpd-b2f03e76ffd3af918d8eda0968f54c0b81bbff54.tar.xz mpd-b2f03e76ffd3af918d8eda0968f54c0b81bbff54.zip |
player_thread: add flag "output_open", fixes assertion failure
Previously, the condition "defined(play_audio_format)" was used to see
if an output device has been opened, but if the device had failed on
startup, an assertion failure could occur. This patch adds a separate
flag.
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | src/player_thread.c | 22 |
2 files changed, 18 insertions, 5 deletions
@@ -14,6 +14,7 @@ ver 0.16.5 (2010/??/??) - make seeking to CUE track more reliable - the "seek" command works when MPD is stopped - restore song position from state file (bug fix) + - fix crash that sometimes occurred when audio device fails on startup * 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 9a7c917f4..52788e518 100644 --- a/src/player_thread.c +++ b/src/player_thread.c @@ -74,6 +74,14 @@ struct player { bool queued; /** + * Was any audio output opened successfully? It might have + * failed meanwhile, but was not explicitly closed by the + * player thread. When this flag is unset, some output + * methods must not be called. + */ + bool output_open; + + /** * the song currently being played */ struct song *song; @@ -290,6 +298,7 @@ player_open_output(struct player *player) pc.state == PLAYER_STATE_PAUSE); if (audio_output_all_open(&player->play_audio_format, player_buffer)) { + player->output_open = true; player->paused = false; player_lock(); @@ -298,6 +307,8 @@ player_open_output(struct player *player) return true; } else { + player->output_open = false; + /* pause: the user may resume playback as soon as an audio output becomes available */ player->paused = true; @@ -342,7 +353,7 @@ player_check_decoder_startup(struct player *player) decoder_unlock(dc); - if (audio_format_defined(&player->play_audio_format) && + if (player->output_open && !audio_output_all_wait(1)) /* the output devices havn't finished playing all chunks yet - wait for that */ @@ -386,6 +397,7 @@ player_check_decoder_startup(struct player *player) static bool player_send_silence(struct player *player) { + assert(player->output_open); assert(audio_format_defined(&player->play_audio_format)); struct music_chunk *chunk = music_buffer_allocate(player_buffer); @@ -579,8 +591,7 @@ static void player_process_command(struct player *player) break; case PLAYER_COMMAND_REFRESH: - if (audio_format_defined(&player->play_audio_format) && - !player->paused) { + if (player->output_open && !player->paused) { player_unlock(); audio_output_all_check(); player_lock(); @@ -831,6 +842,7 @@ static void do_play(struct decoder_control *dc) .decoder_starting = false, .paused = false, .queued = true, + .output_open = false, .song = NULL, .xfade = XFADE_UNKNOWN, .cross_fading = false, @@ -883,7 +895,7 @@ static void do_play(struct decoder_control *dc) /* not enough decoded buffer space yet */ if (!player.paused && - audio_format_defined(&player.play_audio_format) && + player.output_open && audio_output_all_check() < 4 && !player_send_silence(&player)) break; @@ -988,7 +1000,7 @@ static void do_play(struct decoder_control *dc) audio_output_all_drain(); break; } - } else { + } else if (player.output_open) { /* the decoder is too busy and hasn't provided new PCM data in time: send silence (if the output pipe is empty) */ |