Commit f6d67ac2 authored by Max Kellermann's avatar Max Kellermann

DecoderThread: simplify the decoder lookup loop

Merge the two loops into one, and eliminate the GSList.
parent 74904b9c
...@@ -62,6 +62,17 @@ decoder_plugins_find(F f) ...@@ -62,6 +62,17 @@ decoder_plugins_find(F f)
} }
template<typename 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 static inline void
decoder_plugins_for_each(F f) decoder_plugins_for_each(F f)
{ {
......
...@@ -179,74 +179,58 @@ deconst_plugin(const struct DecoderPlugin *plugin) ...@@ -179,74 +179,58 @@ deconst_plugin(const struct DecoderPlugin *plugin)
return const_cast<struct DecoderPlugin *>(plugin); return const_cast<struct DecoderPlugin *>(plugin);
} }
/** gcc_pure
* Try decoding a stream, using plugins matching the stream's MIME type.
*
* @param tried_r a list of plugins which were tried
*/
static bool static bool
decoder_run_stream_mime_type(Decoder &decoder, struct input_stream *is, decoder_check_plugin_mime(const DecoderPlugin &plugin, const input_stream &is)
GSList **tried_r)
{ {
assert(tried_r != nullptr); assert(plugin.stream_decode != 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;
if (decoder_stream_decode(*plugin, decoder, is)) return !is.mime.empty() && plugin.SupportsMimeType(is.mime.c_str());
return true; }
*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);
} }
/** gcc_pure
* Try decoding a stream, using plugins matching the stream's URI
* suffix.
*
* @param tried_r a list of plugins which were tried
*/
static bool static bool
decoder_run_stream_suffix(Decoder &decoder, struct input_stream *is, decoder_check_plugin(const DecoderPlugin &plugin, const input_stream &is,
const char *uri, GSList **tried_r) const char *suffix)
{ {
assert(tried_r != nullptr); return plugin.stream_decode != nullptr &&
(decoder_check_plugin_mime(plugin, is) ||
const char *suffix = uri_get_suffix(uri); decoder_check_plugin_suffix(plugin, suffix));
const struct DecoderPlugin *plugin = nullptr; }
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; return false;
while ((plugin = decoder_plugin_from_suffix(suffix, plugin)) != nullptr) { tried_r = true;
if (plugin->stream_decode == nullptr) return decoder_stream_decode(plugin, decoder, &is);
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 = 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) ...@@ -282,21 +266,15 @@ decoder_run_stream(Decoder &decoder, const char *uri)
dc.Lock(); dc.Lock();
GSList *tried = nullptr; bool tried = false;
success = dc.command == DecoderCommand::STOP || success = dc.command == DecoderCommand::STOP ||
/* first we try mime types: */ decoder_run_stream_locked(decoder, *input_stream, uri,
decoder_run_stream_mime_type(decoder, input_stream, &tried) || 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 /* fallback to mp3: this is needed for bastard streams
that don't have a suffix or set the mimeType */ that don't have a suffix or set the mimeType */
(tried == nullptr && (!tried &&
decoder_run_stream_fallback(decoder, input_stream)); decoder_run_stream_fallback(decoder, input_stream));
g_slist_free(tried);
dc.Unlock(); dc.Unlock();
input_stream->Close(); input_stream->Close();
dc.Lock(); dc.Lock();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment