aboutsummaryrefslogtreecommitdiffstats
path: root/src/decoder_thread.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/decoder_thread.c')
-rw-r--r--src/decoder_thread.c50
1 files changed, 46 insertions, 4 deletions
diff --git a/src/decoder_thread.c b/src/decoder_thread.c
index d6ff058ec..5140f2ec3 100644
--- a/src/decoder_thread.c
+++ b/src/decoder_thread.c
@@ -49,11 +49,15 @@ decoder_stream_decode(const struct decoder_plugin *plugin,
assert(input_stream->ready);
assert(dc.state == DECODE_STATE_START);
+ decoder_unlock();
+
/* rewind the stream, so each plugin gets a fresh start */
input_stream_seek(input_stream, 0, SEEK_SET);
decoder_plugin_stream_decode(plugin, decoder, input_stream);
+ decoder_lock();
+
assert(dc.state == DECODE_STATE_START ||
dc.state == DECODE_STATE_DECODE);
@@ -73,8 +77,12 @@ decoder_file_decode(const struct decoder_plugin *plugin,
assert(path[0] == '/');
assert(dc.state == DECODE_STATE_START);
+ decoder_unlock();
+
decoder_plugin_file_decode(plugin, decoder, path);
+ decoder_lock();
+
assert(dc.state == DECODE_STATE_START ||
dc.state == DECODE_STATE_DECODE);
@@ -103,28 +111,40 @@ static void decoder_run_song(const struct song *song, const char *uri)
dc.state = DECODE_STATE_START;
dc.command = DECODE_COMMAND_NONE;
+
+ decoder_unlock();
notify_signal(&pc.notify);
+ decoder_lock();
/* wait for the input stream to become ready; its metadata
will be available then */
while (!input_stream.ready) {
if (dc.command == DECODE_COMMAND_STOP) {
+ decoder_unlock();
input_stream_close(&input_stream);
+ decoder_lock();
dc.state = DECODE_STATE_STOP;
return;
}
+ decoder_unlock();
ret = input_stream_buffer(&input_stream);
if (ret < 0) {
input_stream_close(&input_stream);
+ decoder_lock();
dc.state = DECODE_STATE_ERROR;
return;
}
+
+ decoder_lock();
}
if (dc.command == DECODE_COMMAND_STOP) {
+ decoder_unlock();
input_stream_close(&input_stream);
+ decoder_lock();
+
dc.state = DECODE_STATE_STOP;
return;
}
@@ -144,7 +164,7 @@ static void decoder_run_song(const struct song *song, const char *uri)
if (ret)
break;
- plugin = NULL;
+ assert(dc.state == DECODE_STATE_START);
}
/* if that fails, try suffix matching the URL: */
@@ -160,7 +180,6 @@ static void decoder_run_song(const struct song *song, const char *uri)
break;
assert(dc.state == DECODE_STATE_START);
- plugin = NULL;
}
}
/* fallback to mp3: */
@@ -179,7 +198,10 @@ static void decoder_run_song(const struct song *song, const char *uri)
const char *s = uri_get_suffix(uri);
while ((plugin = decoder_plugin_from_suffix(s, next++))) {
if (plugin->file_decode != NULL) {
+ decoder_unlock();
input_stream_close(&input_stream);
+ decoder_lock();
+
close_instream = false;
ret = decoder_file_decode(plugin,
&decoder, uri);
@@ -191,7 +213,13 @@ static void decoder_run_song(const struct song *song, const char *uri)
been closed before
decoder_file_decode() -
reopen it */
- if (input_stream_open(&input_stream, uri))
+ bool success;
+
+ decoder_unlock();
+ success = input_stream_open(&input_stream, uri);
+ decoder_lock();
+
+ if (success)
close_instream = true;
else
continue;
@@ -205,6 +233,8 @@ static void decoder_run_song(const struct song *song, const char *uri)
}
}
+ decoder_unlock();
+
pcm_convert_deinit(&decoder.conv_state);
/* flush the last chunk */
@@ -223,6 +253,8 @@ static void decoder_run_song(const struct song *song, const char *uri)
if (decoder.decoder_tag != NULL)
tag_free(decoder.decoder_tag);
+ decoder_lock();
+
dc.state = ret ? DECODE_STATE_STOP : DECODE_STATE_ERROR;
}
@@ -249,6 +281,8 @@ static void decoder_run(void)
static gpointer decoder_task(G_GNUC_UNUSED gpointer arg)
{
+ decoder_lock();
+
do {
assert(dc.state == DECODE_STATE_STOP ||
dc.state == DECODE_STATE_ERROR);
@@ -259,20 +293,28 @@ static gpointer decoder_task(G_GNUC_UNUSED gpointer arg)
decoder_run();
dc.command = DECODE_COMMAND_NONE;
+
+ decoder_unlock();
notify_signal(&pc.notify);
+ decoder_lock();
break;
case DECODE_COMMAND_STOP:
dc.command = DECODE_COMMAND_NONE;
+
+ decoder_unlock();
notify_signal(&pc.notify);
+ decoder_lock();
break;
case DECODE_COMMAND_NONE:
- notify_wait(&dc.notify);
+ decoder_wait();
break;
}
} while (dc.command != DECODE_COMMAND_NONE || !dc.quit);
+ decoder_unlock();
+
return NULL;
}