aboutsummaryrefslogtreecommitdiff
path: root/src/decoder/decoder_thread.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/decoder/decoder_thread.c')
-rw-r--r--src/decoder/decoder_thread.c496
1 files changed, 248 insertions, 248 deletions
diff --git a/src/decoder/decoder_thread.c b/src/decoder/decoder_thread.c
index 964f1318..59ff26db 100644
--- a/src/decoder/decoder_thread.c
+++ b/src/decoder/decoder_thread.c
@@ -51,11 +51,11 @@
static void
decoder_command_finished_locked(struct decoder_control *dc)
{
- assert(dc->command != DECODE_COMMAND_NONE);
+ assert(dc->command != DECODE_COMMAND_NONE);
- dc->command = DECODE_COMMAND_NONE;
+ dc->command = DECODE_COMMAND_NONE;
- g_cond_signal(dc->client_cond);
+ g_cond_signal(dc->client_cond);
}
/**
@@ -72,108 +72,108 @@ decoder_command_finished_locked(struct decoder_control *dc)
static struct input_stream *
decoder_input_stream_open(struct decoder_control *dc, const char *uri)
{
- GError *error = NULL;
- struct input_stream *is;
+ GError *error = NULL;
+ struct input_stream *is;
- is = input_stream_open(uri, dc->mutex, dc->cond, &error);
- if (is == NULL) {
- if (error != NULL) {
- g_warning("%s", error->message);
- g_error_free(error);
- }
+ is = input_stream_open(uri, dc->mutex, dc->cond, &error);
+ if (is == NULL) {
+ if (error != NULL) {
+ g_warning("%s", error->message);
+ g_error_free(error);
+ }
- return NULL;
- }
+ return NULL;
+ }
- /* wait for the input stream to become ready; its metadata
- will be available then */
+ /* wait for the input stream to become ready; its metadata
+ will be available then */
- decoder_lock(dc);
+ decoder_lock(dc);
- input_stream_update(is);
- while (!is->ready &&
- dc->command != DECODE_COMMAND_STOP) {
- decoder_wait(dc);
+ input_stream_update(is);
+ while (!is->ready &&
+ dc->command != DECODE_COMMAND_STOP) {
+ decoder_wait(dc);
- input_stream_update(is);
- }
+ input_stream_update(is);
+ }
- if (!input_stream_check(is, &error)) {
- decoder_unlock(dc);
+ if (!input_stream_check(is, &error)) {
+ decoder_unlock(dc);
- g_warning("%s", error->message);
- g_error_free(error);
+ g_warning("%s", error->message);
+ g_error_free(error);
- return NULL;
- }
+ return NULL;
+ }
- decoder_unlock(dc);
+ decoder_unlock(dc);
- return is;
+ return is;
}
static bool
decoder_stream_decode(const struct decoder_plugin *plugin,
- struct decoder *decoder,
- struct input_stream *input_stream)
+ struct decoder *decoder,
+ struct input_stream *input_stream)
{
- assert(plugin != NULL);
- assert(plugin->stream_decode != NULL);
- assert(decoder != NULL);
- assert(decoder->stream_tag == NULL);
- assert(decoder->decoder_tag == NULL);
- assert(input_stream != NULL);
- assert(input_stream->ready);
- assert(decoder->dc->state == DECODE_STATE_START);
+ assert(plugin != NULL);
+ assert(plugin->stream_decode != NULL);
+ assert(decoder != NULL);
+ assert(decoder->stream_tag == NULL);
+ assert(decoder->decoder_tag == NULL);
+ assert(input_stream != NULL);
+ assert(input_stream->ready);
+ assert(decoder->dc->state == DECODE_STATE_START);
- g_debug("probing plugin %s", plugin->name);
+ g_debug("probing plugin %s", plugin->name);
- if (decoder->dc->command == DECODE_COMMAND_STOP)
- return true;
+ if (decoder->dc->command == DECODE_COMMAND_STOP)
+ return true;
- /* rewind the stream, so each plugin gets a fresh start */
- input_stream_seek(input_stream, 0, SEEK_SET, NULL);
+ /* rewind the stream, so each plugin gets a fresh start */
+ input_stream_seek(input_stream, 0, SEEK_SET, NULL);
- decoder_unlock(decoder->dc);
+ decoder_unlock(decoder->dc);
- decoder_plugin_stream_decode(plugin, decoder, input_stream);
+ decoder_plugin_stream_decode(plugin, decoder, input_stream);
- decoder_lock(decoder->dc);
+ decoder_lock(decoder->dc);
- assert(decoder->dc->state == DECODE_STATE_START ||
- decoder->dc->state == DECODE_STATE_DECODE);
+ assert(decoder->dc->state == DECODE_STATE_START ||
+ decoder->dc->state == DECODE_STATE_DECODE);
- return decoder->dc->state != DECODE_STATE_START;
+ return decoder->dc->state != DECODE_STATE_START;
}
static bool
decoder_file_decode(const struct decoder_plugin *plugin,
- struct decoder *decoder, const char *path)
+ struct decoder *decoder, const char *path)
{
- assert(plugin != NULL);
- assert(plugin->file_decode != NULL);
- assert(decoder != NULL);
- assert(decoder->stream_tag == NULL);
- assert(decoder->decoder_tag == NULL);
- assert(path != NULL);
- assert(g_path_is_absolute(path));
- assert(decoder->dc->state == DECODE_STATE_START);
+ assert(plugin != NULL);
+ assert(plugin->file_decode != NULL);
+ assert(decoder != NULL);
+ assert(decoder->stream_tag == NULL);
+ assert(decoder->decoder_tag == NULL);
+ assert(path != NULL);
+ assert(g_path_is_absolute(path));
+ assert(decoder->dc->state == DECODE_STATE_START);
- g_debug("probing plugin %s", plugin->name);
+ g_debug("probing plugin %s", plugin->name);
- if (decoder->dc->command == DECODE_COMMAND_STOP)
- return true;
+ if (decoder->dc->command == DECODE_COMMAND_STOP)
+ return true;
- decoder_unlock(decoder->dc);
+ decoder_unlock(decoder->dc);
- decoder_plugin_file_decode(plugin, decoder, path);
+ decoder_plugin_file_decode(plugin, decoder, path);
- decoder_lock(decoder->dc);
+ decoder_lock(decoder->dc);
- assert(decoder->dc->state == DECODE_STATE_START ||
- decoder->dc->state == DECODE_STATE_DECODE);
+ assert(decoder->dc->state == DECODE_STATE_START ||
+ decoder->dc->state == DECODE_STATE_DECODE);
- return decoder->dc->state != DECODE_STATE_START;
+ return decoder->dc->state != DECODE_STATE_START;
}
/**
@@ -182,12 +182,12 @@ decoder_file_decode(const struct decoder_plugin *plugin,
static inline gpointer
deconst_plugin(const struct decoder_plugin *plugin)
{
- union {
- const struct decoder_plugin *in;
- gpointer out;
- } u = { .in = plugin };
+ union {
+ const struct decoder_plugin *in;
+ gpointer out;
+ } u = { .in = plugin };
- return u.out;
+ return u.out;
}
/**
@@ -197,31 +197,31 @@ deconst_plugin(const struct decoder_plugin *plugin)
*/
static bool
decoder_run_stream_mime_type(struct decoder *decoder, struct input_stream *is,
- GSList **tried_r)
+ GSList **tried_r)
{
- assert(tried_r != NULL);
+ assert(tried_r != NULL);
- const struct decoder_plugin *plugin;
- unsigned int next = 0;
+ const struct decoder_plugin *plugin;
+ unsigned int next = 0;
- if (is->mime == NULL)
- return false;
+ if (is->mime == NULL)
+ return false;
- while ((plugin = decoder_plugin_from_mime_type(is->mime, next++))) {
- if (plugin->stream_decode == NULL)
- continue;
+ while ((plugin = decoder_plugin_from_mime_type(is->mime, next++))) {
+ if (plugin->stream_decode == NULL)
+ continue;
- if (g_slist_find(*tried_r, plugin) != NULL)
- /* don't try a plugin twice */
- continue;
+ if (g_slist_find(*tried_r, plugin) != NULL)
+ /* don't try a plugin twice */
+ continue;
- if (decoder_stream_decode(plugin, decoder, is))
- return true;
+ if (decoder_stream_decode(plugin, decoder, is))
+ return true;
- *tried_r = g_slist_prepend(*tried_r, deconst_plugin(plugin));
- }
+ *tried_r = g_slist_prepend(*tried_r, deconst_plugin(plugin));
+ }
- return false;
+ return false;
}
/**
@@ -232,31 +232,31 @@ decoder_run_stream_mime_type(struct decoder *decoder, struct input_stream *is,
*/
static bool
decoder_run_stream_suffix(struct decoder *decoder, struct input_stream *is,
- const char *uri, GSList **tried_r)
+ const char *uri, GSList **tried_r)
{
- assert(tried_r != NULL);
+ assert(tried_r != NULL);
- const char *suffix = uri_get_suffix(uri);
- const struct decoder_plugin *plugin = NULL;
+ const char *suffix = uri_get_suffix(uri);
+ const struct decoder_plugin *plugin = NULL;
- if (suffix == NULL)
- return false;
+ if (suffix == NULL)
+ return false;
- while ((plugin = decoder_plugin_from_suffix(suffix, plugin)) != NULL) {
- if (plugin->stream_decode == NULL)
- continue;
+ while ((plugin = decoder_plugin_from_suffix(suffix, plugin)) != NULL) {
+ if (plugin->stream_decode == NULL)
+ continue;
- if (g_slist_find(*tried_r, plugin) != NULL)
- /* don't try a plugin twice */
- continue;
+ if (g_slist_find(*tried_r, plugin) != NULL)
+ /* don't try a plugin twice */
+ continue;
- if (decoder_stream_decode(plugin, decoder, is))
- return true;
+ if (decoder_stream_decode(plugin, decoder, is))
+ return true;
- *tried_r = g_slist_prepend(*tried_r, deconst_plugin(plugin));
- }
+ *tried_r = g_slist_prepend(*tried_r, deconst_plugin(plugin));
+ }
- return false;
+ return false;
}
/**
@@ -265,11 +265,11 @@ decoder_run_stream_suffix(struct decoder *decoder, struct input_stream *is,
static bool
decoder_run_stream_fallback(struct decoder *decoder, struct input_stream *is)
{
- const struct decoder_plugin *plugin;
+ const struct decoder_plugin *plugin;
- plugin = decoder_plugin_from_name("mad");
- return plugin != NULL && plugin->stream_decode != NULL &&
- decoder_stream_decode(plugin, decoder, is);
+ plugin = decoder_plugin_from_name("mad");
+ return plugin != NULL && plugin->stream_decode != NULL &&
+ decoder_stream_decode(plugin, decoder, is);
}
/**
@@ -278,40 +278,40 @@ decoder_run_stream_fallback(struct decoder *decoder, struct input_stream *is)
static bool
decoder_run_stream(struct decoder *decoder, const char *uri)
{
- struct decoder_control *dc = decoder->dc;
- struct input_stream *input_stream;
- bool success;
+ struct decoder_control *dc = decoder->dc;
+ struct input_stream *input_stream;
+ bool success;
- decoder_unlock(dc);
+ decoder_unlock(dc);
- input_stream = decoder_input_stream_open(dc, uri);
- if (input_stream == NULL) {
- decoder_lock(dc);
- return false;
- }
+ input_stream = decoder_input_stream_open(dc, uri);
+ if (input_stream == NULL) {
+ decoder_lock(dc);
+ return false;
+ }
- decoder_lock(dc);
+ decoder_lock(dc);
- GSList *tried = NULL;
+ GSList *tried = NULL;
- success = dc->command == DECODE_COMMAND_STOP ||
- /* first we try mime types: */
- decoder_run_stream_mime_type(decoder, input_stream, &tried) ||
- /* if that fails, try suffix matching the URL: */
- decoder_run_stream_suffix(decoder, input_stream, uri,
- &tried) ||
- /* fallback to mp3: this is needed for bastard streams
- that don't have a suffix or set the mimeType */
- (tried == NULL &&
- decoder_run_stream_fallback(decoder, input_stream));
+ success = dc->command == DECODE_COMMAND_STOP ||
+ /* first we try mime types: */
+ decoder_run_stream_mime_type(decoder, input_stream, &tried) ||
+ /* if that fails, try suffix matching the URL: */
+ decoder_run_stream_suffix(decoder, input_stream, uri,
+ &tried) ||
+ /* fallback to mp3: this is needed for bastard streams
+ that don't have a suffix or set the mimeType */
+ (tried == NULL &&
+ decoder_run_stream_fallback(decoder, input_stream));
- g_slist_free(tried);
+ g_slist_free(tried);
- decoder_unlock(dc);
- input_stream_close(input_stream);
- decoder_lock(dc);
+ decoder_unlock(dc);
+ input_stream_close(input_stream);
+ decoder_lock(dc);
- return success;
+ return success;
}
/**
@@ -321,9 +321,9 @@ decoder_run_stream(struct decoder *decoder, const char *uri)
static void
decoder_load_replay_gain(struct decoder *decoder, const char *path_fs)
{
- struct replay_gain_info info;
- if (replay_gain_ape_read(path_fs, &info))
- decoder_replay_gain(decoder, &info);
+ struct replay_gain_info info;
+ if (replay_gain_ape_read(path_fs, &info))
+ decoder_replay_gain(decoder, &info);
}
/**
@@ -332,174 +332,174 @@ decoder_load_replay_gain(struct decoder *decoder, const char *path_fs)
static bool
decoder_run_file(struct decoder *decoder, const char *path_fs)
{
- struct decoder_control *dc = decoder->dc;
- const char *suffix = uri_get_suffix(path_fs);
- const struct decoder_plugin *plugin = NULL;
+ struct decoder_control *dc = decoder->dc;
+ const char *suffix = uri_get_suffix(path_fs);
+ const struct decoder_plugin *plugin = NULL;
- if (suffix == NULL)
- return false;
+ if (suffix == NULL)
+ return false;
- decoder_unlock(dc);
+ decoder_unlock(dc);
- decoder_load_replay_gain(decoder, path_fs);
+ decoder_load_replay_gain(decoder, path_fs);
- while ((plugin = decoder_plugin_from_suffix(suffix, plugin)) != NULL) {
- if (plugin->file_decode != NULL) {
- decoder_lock(dc);
+ while ((plugin = decoder_plugin_from_suffix(suffix, plugin)) != NULL) {
+ if (plugin->file_decode != NULL) {
+ decoder_lock(dc);
- if (decoder_file_decode(plugin, decoder, path_fs))
- return true;
+ if (decoder_file_decode(plugin, decoder, path_fs))
+ return true;
- decoder_unlock(dc);
- } else if (plugin->stream_decode != NULL) {
- struct input_stream *input_stream;
- bool success;
+ decoder_unlock(dc);
+ } else if (plugin->stream_decode != NULL) {
+ struct input_stream *input_stream;
+ bool success;
- input_stream = decoder_input_stream_open(dc, path_fs);
- if (input_stream == NULL)
- continue;
+ input_stream = decoder_input_stream_open(dc, path_fs);
+ if (input_stream == NULL)
+ continue;
- decoder_lock(dc);
+ decoder_lock(dc);
- success = decoder_stream_decode(plugin, decoder,
- input_stream);
+ success = decoder_stream_decode(plugin, decoder,
+ input_stream);
- decoder_unlock(dc);
+ decoder_unlock(dc);
- input_stream_close(input_stream);
+ input_stream_close(input_stream);
- if (success) {
- decoder_lock(dc);
- return true;
- }
- }
- }
+ if (success) {
+ decoder_lock(dc);
+ return true;
+ }
+ }
+ }
- decoder_lock(dc);
- return false;
+ decoder_lock(dc);
+ return false;
}
static void
decoder_run_song(struct decoder_control *dc,
- const struct song *song, const char *uri)
+ const struct song *song, const char *uri)
{
- struct decoder decoder = {
- .dc = dc,
- .initial_seek_pending = dc->start_ms > 0,
- .initial_seek_running = false,
- };
- int ret;
+ struct decoder decoder = {
+ .dc = dc,
+ .initial_seek_pending = dc->start_ms > 0,
+ .initial_seek_running = false,
+ };
+ int ret;
- decoder.timestamp = 0.0;
- decoder.seeking = false;
- decoder.song_tag = song->tag != NULL && song_is_file(song)
- ? tag_dup(song->tag) : NULL;
- decoder.stream_tag = NULL;
- decoder.decoder_tag = NULL;
+ decoder.timestamp = 0.0;
+ decoder.seeking = false;
+ decoder.song_tag = song->tag != NULL && song_is_file(song)
+ ? tag_dup(song->tag) : NULL;
+ decoder.stream_tag = NULL;
+ decoder.decoder_tag = NULL;
- dc->state = DECODE_STATE_START;
+ dc->state = DECODE_STATE_START;
- decoder_command_finished_locked(dc);
+ decoder_command_finished_locked(dc);
- pcm_convert_init(&decoder.conv_state);
+ pcm_convert_init(&decoder.conv_state);
- ret = song_is_file(song)
- ? decoder_run_file(&decoder, uri)
- : decoder_run_stream(&decoder, uri);
+ ret = song_is_file(song)
+ ? decoder_run_file(&decoder, uri)
+ : decoder_run_stream(&decoder, uri);
- decoder_unlock(dc);
+ decoder_unlock(dc);
- pcm_convert_deinit(&decoder.conv_state);
+ pcm_convert_deinit(&decoder.conv_state);
- if (decoder.song_tag != NULL)
- tag_free(decoder.song_tag);
+ if (decoder.song_tag != NULL)
+ tag_free(decoder.song_tag);
- if (decoder.stream_tag != NULL)
- tag_free(decoder.stream_tag);
+ if (decoder.stream_tag != NULL)
+ tag_free(decoder.stream_tag);
- if (decoder.decoder_tag != NULL)
- tag_free(decoder.decoder_tag);
+ if (decoder.decoder_tag != NULL)
+ tag_free(decoder.decoder_tag);
- decoder_lock(dc);
+ decoder_lock(dc);
- dc->state = ret ? DECODE_STATE_STOP : DECODE_STATE_ERROR;
+ dc->state = ret ? DECODE_STATE_STOP : DECODE_STATE_ERROR;
}
static void
decoder_run(struct decoder_control *dc)
{
- const struct song *song = dc->song;
- char *uri;
+ const struct song *song = dc->song;
+ char *uri;
- assert(song != NULL);
+ assert(song != NULL);
- if (song_is_file(song))
- uri = map_song_fs(song);
- else
- uri = song_get_uri(song);
+ if (song_is_file(song))
+ uri = map_song_fs(song);
+ else
+ uri = song_get_uri(song);
- if (uri == NULL) {
- dc->state = DECODE_STATE_ERROR;
- decoder_command_finished_locked(dc);
- return;
- }
+ if (uri == NULL) {
+ dc->state = DECODE_STATE_ERROR;
+ decoder_command_finished_locked(dc);
+ return;
+ }
- decoder_run_song(dc, song, uri);
- g_free(uri);
+ decoder_run_song(dc, song, uri);
+ g_free(uri);
}
static gpointer
decoder_task(gpointer arg)
{
- struct decoder_control *dc = arg;
+ struct decoder_control *dc = arg;
- decoder_lock(dc);
+ decoder_lock(dc);
- do {
- assert(dc->state == DECODE_STATE_STOP ||
- dc->state == DECODE_STATE_ERROR);
+ do {
+ assert(dc->state == DECODE_STATE_STOP ||
+ dc->state == DECODE_STATE_ERROR);
- switch (dc->command) {
- case DECODE_COMMAND_START:
- g_debug("clearing mixramp tags");
- dc_mixramp_start(dc, NULL);
- dc_mixramp_prev_end(dc, dc->mixramp_end);
- dc->mixramp_end = NULL; /* Don't free, it's copied above. */
- dc->replay_gain_prev_db = dc->replay_gain_db;
- dc->replay_gain_db = 0;
+ switch (dc->command) {
+ case DECODE_COMMAND_START:
+ g_debug("clearing mixramp tags");
+ dc_mixramp_start(dc, NULL);
+ dc_mixramp_prev_end(dc, dc->mixramp_end);
+ dc->mixramp_end = NULL; /* Don't free, it's copied above. */
+ dc->replay_gain_prev_db = dc->replay_gain_db;
+ dc->replay_gain_db = 0;
/* fall through */
- case DECODE_COMMAND_SEEK:
- decoder_run(dc);
- break;
+ case DECODE_COMMAND_SEEK:
+ decoder_run(dc);
+ break;
- case DECODE_COMMAND_STOP:
- decoder_command_finished_locked(dc);
- break;
+ case DECODE_COMMAND_STOP:
+ decoder_command_finished_locked(dc);
+ break;
- case DECODE_COMMAND_NONE:
- decoder_wait(dc);
- break;
- }
- } while (dc->command != DECODE_COMMAND_NONE || !dc->quit);
+ case DECODE_COMMAND_NONE:
+ decoder_wait(dc);
+ break;
+ }
+ } while (dc->command != DECODE_COMMAND_NONE || !dc->quit);
- decoder_unlock(dc);
+ decoder_unlock(dc);
- return NULL;
+ return NULL;
}
void
decoder_thread_start(struct decoder_control *dc)
{
- GError *e = NULL;
+ GError *e = NULL;
- assert(dc->thread == NULL);
+ assert(dc->thread == NULL);
- dc->quit = false;
+ dc->quit = false;
- dc->thread = g_thread_create(decoder_task, dc, true, &e);
- if (dc->thread == NULL)
- MPD_ERROR("Failed to spawn decoder task: %s", e->message);
+ dc->thread = g_thread_create(decoder_task, dc, true, &e);
+ if (dc->thread == NULL)
+ MPD_ERROR("Failed to spawn decoder task: %s", e->message);
}