decoder_thread: don't try a plugin twice (MIME type & suffix)
Manage a linked list of plugins which were already tried.
This commit is contained in:
parent
006f4be71c
commit
8ac776c58b
1
NEWS
1
NEWS
|
@ -19,6 +19,7 @@ ver 0.16 (20??/??/??)
|
|||
- added tags "ArtistSort", "AlbumArtistSort"
|
||||
- id3: revised "performer" tag support
|
||||
* decoders:
|
||||
- don't try a plugin twice (MIME type & suffix)
|
||||
- ffmpeg: support multiple tags
|
||||
- ffmpeg: convert metadata to generic format
|
||||
- sndfile: new decoder plugin based on libsndfile
|
||||
|
|
|
@ -156,45 +156,86 @@ decoder_file_decode(const struct decoder_plugin *plugin,
|
|||
return decoder->dc->state != DECODE_STATE_START;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hack to allow tracking const decoder plugins in a GSList.
|
||||
*/
|
||||
static inline gpointer
|
||||
deconst_plugin(const struct decoder_plugin *plugin)
|
||||
{
|
||||
union {
|
||||
const struct decoder_plugin *in;
|
||||
gpointer out;
|
||||
} u = { .in = plugin };
|
||||
|
||||
return u.out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try decoding a stream, using plugins matching the stream's MIME type.
|
||||
*
|
||||
* @param tried_r a list of plugins which were tried
|
||||
*/
|
||||
static bool
|
||||
decoder_run_stream_mime_type(struct decoder *decoder, struct input_stream *is)
|
||||
decoder_run_stream_mime_type(struct decoder *decoder, struct input_stream *is,
|
||||
GSList **tried_r)
|
||||
{
|
||||
assert(tried_r != NULL);
|
||||
|
||||
const struct decoder_plugin *plugin;
|
||||
unsigned int next = 0;
|
||||
|
||||
if (is->mime == NULL)
|
||||
return false;
|
||||
|
||||
while ((plugin = decoder_plugin_from_mime_type(is->mime, next++)))
|
||||
if (plugin->stream_decode != NULL &&
|
||||
decoder_stream_decode(plugin, decoder, is))
|
||||
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 (decoder_stream_decode(plugin, decoder, is))
|
||||
return true;
|
||||
|
||||
*tried_r = g_slist_prepend(*tried_r, deconst_plugin(plugin));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try decoding a stream, using plugins matching the stream's URI
|
||||
* suffix.
|
||||
*
|
||||
* @param tried_r a list of plugins which were tried
|
||||
*/
|
||||
static bool
|
||||
decoder_run_stream_suffix(struct decoder *decoder, struct input_stream *is,
|
||||
const char *uri)
|
||||
const char *uri, GSList **tried_r)
|
||||
{
|
||||
assert(tried_r != NULL);
|
||||
|
||||
const char *suffix = uri_get_suffix(uri);
|
||||
const struct decoder_plugin *plugin = NULL;
|
||||
|
||||
if (suffix == NULL)
|
||||
return false;
|
||||
|
||||
while ((plugin = decoder_plugin_from_suffix(suffix, plugin)) != NULL)
|
||||
if (plugin->stream_decode != NULL &&
|
||||
decoder_stream_decode(plugin, decoder, is))
|
||||
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 (decoder_stream_decode(plugin, decoder, is))
|
||||
return true;
|
||||
|
||||
*tried_r = g_slist_prepend(*tried_r, deconst_plugin(plugin));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -231,15 +272,20 @@ decoder_run_stream(struct decoder *decoder, const char *uri)
|
|||
|
||||
decoder_lock(dc);
|
||||
|
||||
GSList *tried = NULL;
|
||||
|
||||
success = dc->command == DECODE_COMMAND_STOP ||
|
||||
/* first we try mime types: */
|
||||
decoder_run_stream_mime_type(decoder, input_stream) ||
|
||||
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) ||
|
||||
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 */
|
||||
decoder_run_stream_fallback(decoder, input_stream);
|
||||
|
||||
g_slist_free(tried);
|
||||
|
||||
decoder_unlock(dc);
|
||||
input_stream_close(input_stream);
|
||||
decoder_lock(dc);
|
||||
|
|
Loading…
Reference in New Issue