diff options
Diffstat (limited to 'src/decoder_api.c')
-rw-r--r-- | src/decoder_api.c | 50 |
1 files changed, 30 insertions, 20 deletions
diff --git a/src/decoder_api.c b/src/decoder_api.c index 2ece3bb98..070151a67 100644 --- a/src/decoder_api.c +++ b/src/decoder_api.c @@ -57,8 +57,11 @@ void decoder_initialized(G_GNUC_UNUSED struct decoder * decoder, dc.seekable = seekable; dc.total_time = total_time; + decoder_lock(); dc.state = DECODE_STATE_DECODE; - notify_signal(&pc.notify); + decoder_unlock(); + + player_lock_signal(); g_debug("audio_format=%u:%u:%u, seekable=%s", dc.in_audio_format.sample_rate, dc.in_audio_format.bits, @@ -88,6 +91,8 @@ enum decoder_command decoder_get_command(G_GNUC_UNUSED struct decoder * decoder) void decoder_command_finished(G_GNUC_UNUSED struct decoder * decoder) { + decoder_lock(); + assert(dc.command != DECODE_COMMAND_NONE); assert(dc.command != DECODE_COMMAND_SEEK || dc.seek_error || decoder->seeking); @@ -105,7 +110,9 @@ void decoder_command_finished(G_GNUC_UNUSED struct decoder * decoder) } dc.command = DECODE_COMMAND_NONE; - notify_signal(&pc.notify); + decoder_unlock(); + + player_lock_signal(); } double decoder_seek_where(G_GNUC_UNUSED struct decoder * decoder) @@ -177,7 +184,7 @@ do_send_tag(struct decoder *decoder, struct input_stream *is, /* there is a partial chunk - flush it, we want the tag in a new chunk */ decoder_flush_chunk(decoder); - notify_signal(&pc.notify); + player_lock_signal(); } assert(decoder->chunk == NULL); @@ -225,21 +232,24 @@ decoder_data(struct decoder *decoder, struct replay_gain_info *replay_gain_info) { const char *data = _data; + GError *error = NULL; + enum decoder_command cmd; assert(dc.state == DECODE_STATE_DECODE); assert(dc.pipe != NULL); assert(length % audio_format_frame_size(&dc.in_audio_format) == 0); - if (dc.command == DECODE_COMMAND_STOP || - dc.command == DECODE_COMMAND_SEEK || + decoder_lock(); + cmd = dc.command; + decoder_unlock(); + + if (cmd == DECODE_COMMAND_STOP || cmd == DECODE_COMMAND_SEEK || length == 0) - return dc.command; + return cmd; /* send stream tags */ if (update_stream_tag(decoder, is)) { - enum decoder_command cmd; - if (decoder->decoder_tag != NULL) { /* merge with tag from decoder plugin */ struct tag *tag; @@ -259,14 +269,15 @@ decoder_data(struct decoder *decoder, if (!audio_format_equals(&dc.in_audio_format, &dc.out_audio_format)) { data = pcm_convert(&decoder->conv_state, &dc.in_audio_format, data, length, - &dc.out_audio_format, &length); - - /* under certain circumstances, pcm_convert() may - return an empty buffer - this condition should be - investigated further, but for now, do this check as - a workaround: */ - if (data == NULL) - return DECODE_COMMAND_NONE; + &dc.out_audio_format, &length, + &error); + if (data == NULL) { + /* the PCM conversion has failed - stop + playback, since we have no better way to + bail out */ + g_warning("%s", error->message); + return DECODE_COMMAND_STOP; + } } while (length > 0) { @@ -286,7 +297,7 @@ decoder_data(struct decoder *decoder, if (dest == NULL) { /* the chunk is full, flush it */ decoder_flush_chunk(decoder); - notify_signal(&pc.notify); + player_lock_signal(); continue; } @@ -301,8 +312,7 @@ decoder_data(struct decoder *decoder, /* apply replay gain or normalization */ - if (replay_gain_info != NULL && - replay_gain_mode != REPLAY_GAIN_OFF) + if (replay_gain_mode != REPLAY_GAIN_OFF) replay_gain_apply(replay_gain_info, dest, nbytes, &dc.out_audio_format); else if (normalizationEnabled) @@ -314,7 +324,7 @@ decoder_data(struct decoder *decoder, if (full) { /* the chunk is full, flush it */ decoder_flush_chunk(decoder); - notify_signal(&pc.notify); + player_lock_signal(); } data += nbytes; |