aboutsummaryrefslogtreecommitdiffstats
path: root/src/decoder_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/decoder_api.c')
-rw-r--r--src/decoder_api.c50
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;