aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2013-10-21 22:14:08 +0200
committerMax Kellermann <max@duempel.org>2013-10-21 22:15:57 +0200
commitf6d67ac260ad12a6465378d93d03d98fea857ec8 (patch)
treeda2c164d8ff8ad609e6fb366c05f6623b9ccf1f8 /src
parent74904b9cf2fe163c0ae1d53fb73b19826b256812 (diff)
downloadmpd-f6d67ac260ad12a6465378d93d03d98fea857ec8.tar.gz
mpd-f6d67ac260ad12a6465378d93d03d98fea857ec8.tar.xz
mpd-f6d67ac260ad12a6465378d93d03d98fea857ec8.zip
DecoderThread: simplify the decoder lookup loop
Merge the two loops into one, and eliminate the GSList.
Diffstat (limited to '')
-rw-r--r--src/DecoderList.hxx11
-rw-r--r--src/DecoderThread.cxx106
2 files changed, 53 insertions, 64 deletions
diff --git a/src/DecoderList.hxx b/src/DecoderList.hxx
index 51aeb1d71..fd4b22c63 100644
--- a/src/DecoderList.hxx
+++ b/src/DecoderList.hxx
@@ -62,6 +62,17 @@ decoder_plugins_find(F f)
}
template<typename F>
+static inline bool
+decoder_plugins_try(F f)
+{
+ for (unsigned i = 0; decoder_plugins[i] != nullptr; ++i)
+ if (decoder_plugins_enabled[i] && f(*decoder_plugins[i]))
+ return true;
+
+ return false;
+}
+
+template<typename F>
static inline void
decoder_plugins_for_each(F f)
{
diff --git a/src/DecoderThread.cxx b/src/DecoderThread.cxx
index f70b7c34f..556ab327e 100644
--- a/src/DecoderThread.cxx
+++ b/src/DecoderThread.cxx
@@ -179,74 +179,58 @@ deconst_plugin(const struct DecoderPlugin *plugin)
return const_cast<struct DecoderPlugin *>(plugin);
}
-/**
- * Try decoding a stream, using plugins matching the stream's MIME type.
- *
- * @param tried_r a list of plugins which were tried
- */
+gcc_pure
static bool
-decoder_run_stream_mime_type(Decoder &decoder, struct input_stream *is,
- GSList **tried_r)
+decoder_check_plugin_mime(const DecoderPlugin &plugin, const input_stream &is)
{
- assert(tried_r != nullptr);
-
- const struct DecoderPlugin *plugin;
- unsigned int next = 0;
-
- if (is->mime.empty())
- return false;
-
- while ((plugin = decoder_plugin_from_mime_type(is->mime.c_str(),
- next++))) {
- if (plugin->stream_decode == nullptr)
- continue;
-
- if (g_slist_find(*tried_r, plugin) != nullptr)
- /* don't try a plugin twice */
- continue;
+ assert(plugin.stream_decode != nullptr);
- if (decoder_stream_decode(*plugin, decoder, is))
- return true;
+ return !is.mime.empty() && plugin.SupportsMimeType(is.mime.c_str());
+}
- *tried_r = g_slist_prepend(*tried_r, deconst_plugin(plugin));
- }
+gcc_pure
+static bool
+decoder_check_plugin_suffix(const DecoderPlugin &plugin, const char *suffix)
+{
+ assert(plugin.stream_decode != nullptr);
- return false;
+ return suffix != nullptr && plugin.SupportsSuffix(suffix);
}
-/**
- * Try decoding a stream, using plugins matching the stream's URI
- * suffix.
- *
- * @param tried_r a list of plugins which were tried
- */
+gcc_pure
static bool
-decoder_run_stream_suffix(Decoder &decoder, struct input_stream *is,
- const char *uri, GSList **tried_r)
+decoder_check_plugin(const DecoderPlugin &plugin, const input_stream &is,
+ const char *suffix)
{
- assert(tried_r != nullptr);
-
- const char *suffix = uri_get_suffix(uri);
- const struct DecoderPlugin *plugin = nullptr;
+ return plugin.stream_decode != nullptr &&
+ (decoder_check_plugin_mime(plugin, is) ||
+ decoder_check_plugin_suffix(plugin, suffix));
+}
- if (suffix == nullptr)
+static bool
+decoder_run_stream_plugin(Decoder &decoder, input_stream &is,
+ const char *suffix,
+ const DecoderPlugin &plugin,
+ bool &tried_r)
+{
+ if (!decoder_check_plugin(plugin, is, suffix))
return false;
- while ((plugin = decoder_plugin_from_suffix(suffix, plugin)) != nullptr) {
- if (plugin->stream_decode == nullptr)
- continue;
-
- if (g_slist_find(*tried_r, plugin) != nullptr)
- /* don't try a plugin twice */
- continue;
-
- if (decoder_stream_decode(*plugin, decoder, is))
- return true;
+ tried_r = true;
+ return decoder_stream_decode(plugin, decoder, &is);
+}
- *tried_r = g_slist_prepend(*tried_r, deconst_plugin(plugin));
- }
+static bool
+decoder_run_stream_locked(Decoder &decoder, input_stream &is,
+ const char *uri, bool &tried_r)
+{
+ const char *const suffix = uri_get_suffix(uri);
- return false;
+ using namespace std::placeholders;
+ const auto f = std::bind(decoder_run_stream_plugin,
+ std::ref(decoder), std::ref(is), suffix,
+ _1, std::ref(tried_r));
+ return decoder_plugins_try(f);
}
/**
@@ -282,21 +266,15 @@ decoder_run_stream(Decoder &decoder, const char *uri)
dc.Lock();
- GSList *tried = nullptr;
-
+ bool tried = false;
success = dc.command == DecoderCommand::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) ||
+ decoder_run_stream_locked(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 == nullptr &&
+ (!tried &&
decoder_run_stream_fallback(decoder, input_stream));
- g_slist_free(tried);
-
dc.Unlock();
input_stream->Close();
dc.Lock();