summaryrefslogtreecommitdiff
path: root/src/xine-engine/load_plugins.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xine-engine/load_plugins.c')
-rw-r--r--src/xine-engine/load_plugins.c659
1 files changed, 345 insertions, 314 deletions
diff --git a/src/xine-engine/load_plugins.c b/src/xine-engine/load_plugins.c
index 71cb19d3b..9eb33f8ed 100644
--- a/src/xine-engine/load_plugins.c
+++ b/src/xine-engine/load_plugins.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2006 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -101,7 +101,7 @@ static const int plugin_iface_versions[] = {
SPU_DECODER_IFACE_VERSION,
AUDIO_OUT_IFACE_VERSION,
VIDEO_OUT_DRIVER_IFACE_VERSION,
- POST_PLUGIN_IFACE_VERSION
+ POST_PLUGIN_IFACE_VERSION
};
static void _build_list_typed_plugins(plugin_catalog_t **catalog, xine_sarray_t *type) {
@@ -112,7 +112,7 @@ static void _build_list_typed_plugins(plugin_catalog_t **catalog, xine_sarray_t
list_size = xine_sarray_size (type);
for (list_id = 0, i = 0; list_id < list_size; list_id++) {
node = xine_sarray_get(type, list_id);
-
+
/* add only unique ids to the list */
for ( j = 0; j < i; j++ ) {
if( !strcmp((*catalog)->ids[j], node->info->id) )
@@ -157,9 +157,9 @@ static int get_decoder_priority(xine_t *this, plugin_node_t *node) {
char key[80];
snprintf(key, sizeof(key), "engine.decoder_priorities.%s", node->info->id);
-
+
entry = this->config->lookup_entry(this->config, key);
-
+
if (entry && entry->num_value)
/* user given priorities should definitely override defaults, so multiply them */
return entry->num_value * 100;
@@ -258,14 +258,14 @@ static plugin_info_t *_get_cached_info (xine_t *this,
node->file->filesize == filesize &&
node->file->filemtime == filemtime &&
!strcmp( node->file->filename, filename )) {
-
+
return node->info;
}
-
+
/* skip previously returned items */
if( node->info == previous_info )
previous_info = NULL;
-
+
}
return NULL;
}
@@ -313,20 +313,19 @@ static void _insert_node (xine_t *this,
const input_info_t *input_old;
uint32_t *types;
char key[80];
- char desc[100];
int i;
_x_assert(list);
_x_assert(info);
if (info->API != api_version) {
- xprintf(this, XINE_VERBOSITY_LOG,
+ xprintf(this, XINE_VERBOSITY_LOG,
_("load_plugins: ignoring plugin %s, wrong iface version %d (should be %d)\n"),
info->id, info->API, api_version);
return;
}
- entry = xine_xmalloc(sizeof(plugin_node_t));
- entry->info = xine_xmalloc(sizeof(plugin_info_t));
+ entry = calloc(1, sizeof(plugin_node_t));
+ entry->info = calloc(1, sizeof(plugin_info_t));
*(entry->info) = *info;
entry->info->id = strdup(info->id);
entry->info->init = info->init;
@@ -339,7 +338,7 @@ static void _insert_node (xine_t *this,
case PLUGIN_VIDEO_OUT:
vo_old = info->special_info;
- vo_new = xine_xmalloc(sizeof(vo_info_t));
+ vo_new = calloc(1, sizeof(vo_info_t));
entry->priority = vo_new->priority = vo_old->priority;
vo_new->visual_type = vo_old->visual_type;
entry->info->special_info = vo_new;
@@ -347,7 +346,7 @@ static void _insert_node (xine_t *this,
case PLUGIN_AUDIO_OUT:
ao_old = info->special_info;
- ao_new = xine_xmalloc(sizeof(ao_info_t));
+ ao_new = calloc(1, sizeof(ao_info_t));
entry->priority = ao_new->priority = ao_old->priority;
entry->info->special_info = ao_new;
break;
@@ -356,7 +355,7 @@ static void _insert_node (xine_t *this,
case PLUGIN_VIDEO_DECODER:
case PLUGIN_SPU_DECODER:
decoder_old = info->special_info;
- decoder_new = xine_xmalloc(sizeof(decoder_info_t));
+ decoder_new = calloc(1, sizeof(decoder_info_t));
if (decoder_old == NULL) {
if (file)
xprintf (this, XINE_VERBOSITY_DEBUG,
@@ -368,22 +367,21 @@ static void _insert_node (xine_t *this,
info->id);
_x_abort();
}
- for (i=0; decoder_old->supported_types[i] != 0; ++i);
- types = xine_xmalloc((i+1)*sizeof(uint32_t));
- for (i=0; decoder_old->supported_types[i] != 0; ++i){
- types[i] = decoder_old->supported_types[i];
+ {
+ size_t supported_types_size;
+ for (supported_types_size=0; decoder_old->supported_types[supported_types_size] != 0; ++supported_types_size);
+ types = calloc((supported_types_size+1), sizeof(uint32_t));
+ memcpy(types, decoder_old->supported_types, supported_types_size*sizeof(uint32_t));
+ decoder_new->supported_types = types;
}
- decoder_new->supported_types = types;
entry->priority = decoder_new->priority = decoder_old->priority;
-
+
snprintf(key, sizeof(key), "engine.decoder_priorities.%s", info->id);
- snprintf(desc, sizeof(desc), _("priority for %s decoder"), info->id);
/* write the description on the heap because the config system
* does not strdup() it, so we have to provide a different pointer
* for each decoder */
for (i = 0; catalog->prio_desc[i]; i++);
- catalog->prio_desc[i] = malloc(strlen(desc) + 1);
- strcpy(catalog->prio_desc[i], desc);
+ asprintf(&catalog->prio_desc[i], _("priority for %s decoder"), info->id);
this->config->register_num (this->config,
key,
0,
@@ -399,23 +397,23 @@ static void _insert_node (xine_t *this,
entry->info->special_info = decoder_new;
break;
-
+
case PLUGIN_POST:
post_old = info->special_info;
- post_new = xine_xmalloc(sizeof(post_info_t));
+ post_new = calloc(1, sizeof(post_info_t));
post_new->type = post_old->type;
entry->info->special_info = post_new;
break;
-
+
case PLUGIN_DEMUX:
demux_old = info->special_info;
- demux_new = xine_xmalloc(sizeof(demuxer_info_t));
-
+ demux_new = calloc(1, sizeof(demuxer_info_t));
+
if (demux_old) {
entry->priority = demux_new->priority = demux_old->priority;
lprintf("demux: %s, priority: %d\n", info->id, entry->priority);
} else {
- xprintf(this, XINE_VERBOSITY_LOG,
+ xprintf(this, XINE_VERBOSITY_LOG,
_("load_plugins: demuxer plugin %s does not provide a priority,"
" xine-lib will use the default priority.\n"),
info->id);
@@ -426,13 +424,13 @@ static void _insert_node (xine_t *this,
case PLUGIN_INPUT:
input_old = info->special_info;
- input_new = xine_xmalloc(sizeof(input_info_t));
-
+ input_new = calloc(1, sizeof(input_info_t));
+
if (input_old) {
entry->priority = input_new->priority = input_old->priority;
lprintf("input: %s, priority: %d\n", info->id, entry->priority);
} else {
- xprintf(this, XINE_VERBOSITY_LOG,
+ xprintf(this, XINE_VERBOSITY_LOG,
_("load_plugins: input plugin %s does not provide a priority,"
" xine-lib will use the default priority.\n"),
info->id);
@@ -463,12 +461,12 @@ static int _plugin_node_comparator(void *a, void *b) {
}
}
-static plugin_catalog_t *_new_catalog(void){
+static plugin_catalog_t *XINE_MALLOC _new_catalog(void){
plugin_catalog_t *catalog;
int i;
- catalog = xine_xmalloc(sizeof(plugin_catalog_t));
+ catalog = calloc(1, sizeof(plugin_catalog_t));
for (i = 0; i < PLUGIN_TYPE_MAX; i++) {
catalog->plugin_lists[i] = xine_sarray_new(0, _plugin_node_comparator);
@@ -487,13 +485,13 @@ static void _register_plugins_internal(xine_t *this, plugin_file_t *file, plugin
while ( info && info->type != PLUGIN_NONE ) {
- if (file)
+ if (file && file->filename)
xine_log (this, XINE_LOG_PLUGIN,
_("load_plugins: plugin %s found\n"), file->filename);
else
xine_log (this, XINE_LOG_PLUGIN,
_("load_plugins: static plugin found\n"));
-
+
if (this->plugin_catalog->plugin_count >= PLUGIN_MAX ||
(this->plugin_catalog->decoder_count >= DECODER_MAX &&
info->type >= PLUGIN_AUDIO_DECODER && info->type <= PLUGIN_SPU_DECODER)) {
@@ -527,7 +525,7 @@ static void _register_plugins_internal(xine_t *this, plugin_file_t *file, plugin
}
this->plugin_catalog->plugin_count++;
}
-
+
/* get next info */
if( file && !file->lib_handle ) {
lprintf("get cached info\n");
@@ -556,25 +554,20 @@ static void collect_plugins(xine_t *this, char *path){
dir = opendir(path);
if (dir) {
struct dirent *pEntry;
- size_t path_len, str_size;
- char *str = NULL;
- path_len = strlen(path);
- str_size = path_len * 2 + 2; /* +2 for '/' and '\0' */
- str = malloc(str_size);
- xine_fast_memcpy(str, path, path_len);
- str[path_len] = '/';
- str[path_len + 1] = '\0';
+ size_t path_len = strlen(path);
+ size_t str_size = path_len * 2 + 2; /* +2 for '/' and '\0' */
+ char *str = malloc(str_size);
+ sprintf(str, "%s/", path);
while ((pEntry = readdir (dir)) != NULL) {
- size_t new_str_size, d_len;
void *lib = NULL;
plugin_info_t *info = NULL;
-
+
struct stat statbuffer;
- d_len = strlen(pEntry->d_name);
- new_str_size = path_len + d_len + 2;
+ size_t d_len = strlen(pEntry->d_name);
+ size_t new_str_size = path_len + d_len + 2;
if (str_size < new_str_size) {
str_size = new_str_size + new_str_size / 2;
str = realloc(str, str_size);
@@ -599,7 +592,7 @@ static void collect_plugins(xine_t *this, char *path){
#if defined(__hpux)
if(!strstr(str, ".sl")
#elif defined(__CYGWIN__) || defined(WIN32)
- if(!strstr(str, ".dll")
+ if(!strstr(str, ".dll") || strstr(str, ".dll.a")
#else
if(!strstr(str, ".so")
#endif
@@ -623,7 +616,7 @@ static void collect_plugins(xine_t *this, char *path){
if(!info && (lib = dlopen (str, RTLD_LAZY | RTLD_GLOBAL)) == NULL) {
const char *error = dlerror();
/* too noisy -- but good to catch unresolved references */
- xprintf(this, XINE_VERBOSITY_LOG,
+ xprintf(this, XINE_VERBOSITY_LOG,
_("load_plugins: cannot open plugin lib %s:\n%s\n"), str, error);
} else {
@@ -666,14 +659,14 @@ static void collect_plugins(xine_t *this, char *path){
* generic 2nd stage plugin loader
*/
-static inline int _plugin_info_equal(const plugin_info_t *a,
+static inline int _plugin_info_equal(const plugin_info_t *a,
const plugin_info_t *b) {
- if (a->type != b->type ||
+ if (a->type != b->type ||
a->API != b->API ||
strcasecmp(a->id, b->id) ||
a->version != b->version)
return 0;
-
+
switch (a->type & PLUGIN_TYPE_MASK) {
case PLUGIN_VIDEO_OUT:
/* FIXME: Could special_info be NULL? */
@@ -682,11 +675,11 @@ static inline int _plugin_info_equal(const plugin_info_t *a,
((vo_info_t*)b->special_info)->visual_type);
}
break;
-
+
default:
break;
}
-
+
return 1;
}
@@ -729,7 +722,7 @@ static int _load_plugin_class(xine_t *this,
info++;
}
lprintf("plugin not found\n");
-
+
} else {
xine_log (this, XINE_LOG_PLUGIN,
_("load_plugins: Yikes! %s doesn't contain plugin info.\n"), filename);
@@ -797,9 +790,9 @@ static void _load_required_plugins(xine_t *this, xine_sarray_t *list) {
list_size = xine_sarray_size(list);
while (list_id < list_size) {
plugin_node_t *node = xine_sarray_get(list, list_id);
-
+
if( (node->info->type & PLUGIN_MUST_PRELOAD) && !node->plugin_class ) {
-
+
lprintf("preload plugin %s from %s\n", node->info->id, node->file->filename);
if (! _load_plugin_class (this, node, NULL)) {
@@ -838,7 +831,7 @@ static void save_plugin_list(FILE *fp, xine_sarray_t *list) {
const vo_info_t *vo_info;
const ao_info_t *ao_info;
const post_info_t *post_info;
-
+
int i;
int list_id = 0;
int list_size;
@@ -855,20 +848,20 @@ static void save_plugin_list(FILE *fp, xine_sarray_t *list) {
fprintf(fp, "api=%d\n", node->info->API );
fprintf(fp, "id=%s\n", node->info->id );
fprintf(fp, "version=%lu\n", (unsigned long) node->info->version );
-
+
switch (node->info->type & PLUGIN_TYPE_MASK){
-
+
case PLUGIN_VIDEO_OUT:
vo_info = node->info->special_info;
fprintf(fp, "visual_type=%d\n", vo_info->visual_type );
fprintf(fp, "vo_priority=%d\n", vo_info->priority );
break;
-
+
case PLUGIN_AUDIO_OUT:
ao_info = node->info->special_info;
fprintf(fp, "ao_priority=%d\n", ao_info->priority );
break;
-
+
case PLUGIN_AUDIO_DECODER:
case PLUGIN_VIDEO_DECODER:
case PLUGIN_SPU_DECODER:
@@ -885,7 +878,7 @@ static void save_plugin_list(FILE *fp, xine_sarray_t *list) {
demuxer_info = node->info->special_info;
fprintf(fp, "demuxer_priority=%d\n", demuxer_info->priority);
break;
-
+
case PLUGIN_INPUT:
input_info = node->info->special_info;
fprintf(fp, "input_priority=%d\n", input_info->priority);
@@ -895,8 +888,8 @@ static void save_plugin_list(FILE *fp, xine_sarray_t *list) {
post_info = node->info->special_info;
fprintf(fp, "post_type=%lu\n", (unsigned long)post_info->type);
break;
- }
-
+ }
+
fprintf(fp, "\n");
list_id++;
}
@@ -921,13 +914,13 @@ static void load_plugin_list(FILE *fp, xine_sarray_t *plugins) {
char line[1024];
char *value;
int version_ok = 0;
-
+
node = NULL;
file = NULL;
while (fgets (line, 1023, fp)) {
if (line[0] == '#')
continue;
-
+
if( (value = strchr(line, '\r')) || (value = strchr(line, '\n')) )
*value = (char) 0; /* eliminate any cr/lf */
@@ -941,11 +934,11 @@ static void load_plugin_list(FILE *fp, xine_sarray_t *plugins) {
if( node ) {
xine_sarray_add (plugins, node);
}
- node = xine_xmalloc(sizeof(plugin_node_t));
- file = xine_xmalloc(sizeof(plugin_file_t));
+ node = calloc(1, sizeof(plugin_node_t));
+ file = calloc(1, sizeof(plugin_file_t));
node->file = file;
file->filename = strdup(line+1);
- node->info = xine_xmalloc(2*sizeof(plugin_info_t));
+ node->info = calloc(2, sizeof(plugin_info_t));
node->info[1].type = PLUGIN_NONE;
decoder_info = NULL;
vo_info = NULL;
@@ -964,7 +957,7 @@ static void load_plugin_list(FILE *fp, xine_sarray_t *plugins) {
if( i == CACHE_CATALOG_VERSION )
version_ok = 1;
else
- return;
+ return;
}
} else if (node) {
if( !strcmp("size",line) ) {
@@ -976,42 +969,42 @@ static void load_plugin_list(FILE *fp, xine_sarray_t *plugins) {
} else if( !strcmp("type",line) ) {
sscanf(value," %d",&i);
node->info->type = i;
-
+
switch (node->info->type & PLUGIN_TYPE_MASK){
-
+
case PLUGIN_VIDEO_OUT:
node->info->special_info = vo_info =
- xine_xmalloc(sizeof(vo_info_t));
+ calloc(1, sizeof(vo_info_t));
break;
-
+
case PLUGIN_AUDIO_OUT:
node->info->special_info = ao_info =
- xine_xmalloc(sizeof(ao_info_t));
+ calloc(1, sizeof(ao_info_t));
break;
-
+
case PLUGIN_DEMUX:
node->info->special_info = demuxer_info =
- xine_xmalloc(sizeof(demuxer_info_t));
+ calloc(1, sizeof(demuxer_info_t));
break;
case PLUGIN_INPUT:
node->info->special_info = input_info =
- xine_xmalloc(sizeof(input_info_t));
+ calloc(1, sizeof(input_info_t));
break;
case PLUGIN_AUDIO_DECODER:
case PLUGIN_VIDEO_DECODER:
case PLUGIN_SPU_DECODER:
node->info->special_info = decoder_info =
- xine_xmalloc(sizeof(decoder_info_t));
+ calloc(1, sizeof(decoder_info_t));
break;
-
+
case PLUGIN_POST:
node->info->special_info = post_info =
- xine_xmalloc(sizeof(post_info_t));
+ calloc(1, sizeof(post_info_t));
break;
- }
-
+ }
+
} else if( !strcmp("api",line) ) {
sscanf(value," %d",&i);
node->info->API = i;
@@ -1025,11 +1018,11 @@ static void load_plugin_list(FILE *fp, xine_sarray_t *plugins) {
vo_info->visual_type = i;
} else if( !strcmp("supported_types",line) && decoder_info ) {
char *s;
-
+
for( s = value, i = 0; s && sscanf(s," %lu",&lu) > 0; i++ ) {
s = strchr(s+1, ' ');
}
- decoder_info->supported_types = xine_xmalloc((i+1)*sizeof(uint32_t));
+ decoder_info->supported_types = calloc((i+1), sizeof(uint32_t));
for( s = value, i = 0; s && sscanf(s," %lu",&lu) > 0; i++ ) {
decoder_info->supported_types[i] = lu;
s = strchr(s+1, ' ');
@@ -1056,7 +1049,7 @@ static void load_plugin_list(FILE *fp, xine_sarray_t *plugins) {
}
}
}
-
+
if( node ) {
xine_sarray_add (plugins, node);
}
@@ -1069,33 +1062,52 @@ static void load_plugin_list(FILE *fp, xine_sarray_t *plugins) {
static void save_catalog (xine_t *this) {
FILE *fp;
- char *cachefile, *dirfile;
+ char *cachefile, *cachefile_new, *dirfile;
const char *relname = CACHE_CATALOG_FILE;
const char *dirname = CACHE_CATALOG_DIR;
-
- cachefile = (char *) xine_xmalloc(strlen(xine_get_homedir()) +
- strlen(relname) + 2);
- sprintf(cachefile, "%s/%s", xine_get_homedir(), relname);
-
+
+ const char *const homedir = xine_get_homedir();
+
+ asprintf(&cachefile, "%s/%s", homedir, relname);
+ asprintf(&cachefile_new, "%s.new", cachefile);
+
/* make sure homedir (~/.xine) exists */
- dirfile = (char *) xine_xmalloc(strlen(xine_get_homedir()) +
- strlen(dirname) + 2);
- sprintf(dirfile, "%s/%s", xine_get_homedir(), dirname);
+ asprintf(&dirfile, "%s/%s", homedir, dirname);
mkdir (dirfile, 0755);
free (dirfile);
- if( (fp = fopen(cachefile,"w")) != NULL ) {
+ if( (fp = fopen(cachefile_new,"w")) != NULL ) {
int i;
-
+
fprintf(fp, "# this file is automatically created by xine, do not edit.\n\n");
fprintf(fp, "cache_catalog_version=%d\n\n", CACHE_CATALOG_VERSION);
for (i = 0; i < PLUGIN_TYPE_MAX; i++) {
save_plugin_list (fp, this->plugin_catalog->plugin_lists[i]);
}
- fclose(fp);
+ if (fclose(fp))
+ {
+ const char *err = strerror (errno);
+ xine_log (this, XINE_LOG_MSG,
+ _("failed to save catalogue cache: %s\n"), err);
+ goto do_unlink;
+ }
+ else if (rename (cachefile_new, cachefile))
+ {
+ const char *err = strerror (errno);
+ xine_log (this, XINE_LOG_MSG,
+ _("failed to replace catalogue cache: %s\n"), err);
+ do_unlink:
+ if (unlink (cachefile_new) && errno != ENOENT)
+ {
+ err = strerror (errno);
+ xine_log (this, XINE_LOG_MSG,
+ _("failed to remove new catalogue cache: %s\n"), err);
+ }
+ }
}
free(cachefile);
+ free(cachefile_new);
}
/*
@@ -1104,13 +1116,11 @@ static void save_catalog (xine_t *this) {
static void load_cached_catalog (xine_t *this) {
FILE *fp;
- char *cachefile;
+ char *cachefile;
const char *relname = CACHE_CATALOG_FILE;
-
- cachefile = (char *) xine_xmalloc(strlen(xine_get_homedir()) +
- strlen(relname) + 2);
- sprintf(cachefile, "%s/%s", xine_get_homedir(), relname);
-
+
+ asprintf(&cachefile, "%s/%s", xine_get_homedir(), relname);
+
if( (fp = fopen(cachefile,"r")) != NULL ) {
load_plugin_list (fp, this->plugin_catalog->cache_list);
fclose(fp);
@@ -1119,15 +1129,25 @@ static void load_cached_catalog (xine_t *this) {
}
+/* helper function for _x_scan_plugins */
+static void push_if_dir (xine_list_t *plugindirs, void *path)
+{
+ struct stat st;
+ if (!stat (path, &st) && S_ISDIR (st.st_mode))
+ xine_list_push_back (plugindirs, path);
+ else
+ free (path);
+}
+
/*
* initialize catalog, load all plugins into new catalog
*/
void _x_scan_plugins (xine_t *this) {
-
- char *homedir, *plugindir, *pluginpath;
- int i,j;
- int lenpluginpath;
-
+
+ char *homedir, *pluginpath;
+ xine_list_t *plugindirs = xine_list_new ();
+ xine_list_iterator_t iter;
+
lprintf("_x_scan_plugins()\n");
if (this == NULL || this->config == NULL) {
@@ -1140,45 +1160,49 @@ void _x_scan_plugins (xine_t *this) {
this->plugin_catalog = _new_catalog();
load_cached_catalog (this);
- if ((pluginpath = getenv("XINE_PLUGIN_PATH")) != NULL) {
- pluginpath = strdup(pluginpath);
+ if ((pluginpath = getenv("XINE_PLUGIN_PATH")) != NULL && *pluginpath) {
+ char *p = pluginpath;
+ while (p && p[0])
+ {
+ size_t len;
+ char *dir, *q;
+
+ q = p;
+ p = strchr (p, XINE_PATH_SEPARATOR_CHAR);
+ if (p) {
+ p++;
+ len = p - q;
+ } else
+ len = strlen(q);
+ if (q[0] == '~' && q[1] == '/')
+ asprintf (&dir, "%s%.*s", homedir, (int)(len - 1), q + 1);
+ else
+ dir = strndup (q, len);
+ push_if_dir (plugindirs, dir); /* store or free it */
+ }
} else {
- const char *str1, *str2;
- int len;
-
- str1 = "~/.xine/plugins";
- str2 = XINE_PLUGINDIR;
- len = strlen(str1) + strlen(str2) + 2;
- pluginpath = xine_xmalloc(len);
- snprintf(pluginpath, len, "%s" XINE_PATH_SEPARATOR_STRING "%s", str1, str2);
- }
- plugindir = xine_xmalloc(strlen(pluginpath)+strlen(homedir)+2);
- j=0;
- lenpluginpath = strlen(pluginpath);
- for (i=0; i <= lenpluginpath; ++i){
- switch (pluginpath[i]){
- case XINE_PATH_SEPARATOR_CHAR:
- case '\0':
- plugindir[j] = '\0';
- collect_plugins(this, plugindir);
- j = 0;
- break;
- case '~':
- if (j == 0){
- strcpy(plugindir, homedir);
- j = strlen(plugindir);
- break;
- }
- default:
- plugindir[j++] = pluginpath[i];
+ char *dir;
+ int i;
+ asprintf (&dir, "%s/.xine/plugins", homedir);
+ push_if_dir (plugindirs, dir);
+ for (i = 0; i <= XINE_LT_AGE; ++i)
+ {
+ asprintf (&dir, "%s.%d", XINE_PLUGINROOT, XINE_LT_AGE - i);
+ push_if_dir (plugindirs, dir);
}
}
- free(plugindir);
- free(pluginpath);
+ for (iter = xine_list_front (plugindirs); iter;
+ iter = xine_list_next (plugindirs, iter))
+ {
+ char *dir = xine_list_get_value (plugindirs, iter);
+ collect_plugins(this, dir);
+ free (dir);
+ }
+ xine_list_delete (plugindirs);
free(homedir);
save_catalog (this);
-
+
load_required_plugins (this);
map_decoders (this);
@@ -1208,7 +1232,7 @@ input_plugin_t *_x_find_input_plugin (xine_stream_t *stream, const char *mrl) {
plugin->node = node;
break;
}
- }
+ }
}
pthread_mutex_unlock (&catalog->lock);
@@ -1229,6 +1253,26 @@ void _x_free_input_plugin (xine_stream_t *stream, input_plugin_t *input) {
}
}
+static int probe_mime_type (xine_t *self, plugin_node_t *node, const char *mime_type)
+{
+ /* catalog->lock is expected to be locked */
+ if (node->plugin_class || _load_plugin_class(self, node, NULL))
+ {
+ const unsigned int mime_type_len = strlen (mime_type);
+ demux_class_t *cls = (demux_class_t *)node->plugin_class;
+ const char *mime = cls->get_mimetypes (cls);
+ while (mime)
+ {
+ while (*mime == ';' || isspace (*mime))
+ ++mime;
+ if (!strncasecmp (mime, mime_type, mime_type_len) &&
+ (!mime[mime_type_len] || mime[mime_type_len] == ':' || mime[mime_type_len] == ';'))
+ return 1;
+ mime = strchr (mime, ';');
+ }
+ }
+ return 0;
+}
static demux_plugin_t *probe_demux (xine_stream_t *stream, int method1, int method2,
input_plugin_t *input) {
@@ -1251,8 +1295,6 @@ static demux_plugin_t *probe_demux (xine_stream_t *stream, int method1, int meth
while (methods[i] != -1 && !plugin) {
int list_id, list_size;
- stream->content_detection_method = methods[i];
-
pthread_mutex_lock (&catalog->lock);
list_size = xine_sarray_size(catalog->plugin_lists[PLUGIN_DEMUX - 1]);
@@ -1264,6 +1306,25 @@ static demux_plugin_t *probe_demux (xine_stream_t *stream, int method1, int meth
xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "load_plugins: probing demux '%s'\n", node->info->id);
if (node->plugin_class || _load_plugin_class(stream->xine, node, NULL)) {
+ const char *mime_type;
+
+ /* If detecting by MRL, try the MIME type first (but not text/plain)... */
+ stream->content_detection_method = METHOD_EXPLICIT;
+ if (methods[i] == METHOD_BY_EXTENSION &&
+ stream->input_plugin->get_optional_data &&
+ stream->input_plugin->get_optional_data (stream->input_plugin, NULL, INPUT_OPTIONAL_DATA_DEMUX_MIME_TYPE) != INPUT_OPTIONAL_UNSUPPORTED &&
+ stream->input_plugin->get_optional_data (stream->input_plugin, &mime_type, INPUT_OPTIONAL_DATA_MIME_TYPE) != INPUT_OPTIONAL_UNSUPPORTED &&
+ mime_type && strcasecmp (mime_type, "text/plain") &&
+ probe_mime_type (stream->xine, node, mime_type) &&
+ (plugin = ((demux_class_t *)node->plugin_class)->open_plugin (node->plugin_class, stream, input)))
+ {
+ inc_node_ref(node);
+ plugin->node = node;
+ break;
+ }
+
+ /* ... then try the extension */
+ stream->content_detection_method = methods[i];
if ((plugin = ((demux_class_t *)node->plugin_class)->open_plugin(node->plugin_class, stream, input))) {
inc_node_ref(node);
plugin->node = node;
@@ -1377,7 +1438,7 @@ demux_plugin_t *_x_find_demux_plugin_last_probe(xine_stream_t *stream, const cha
if (strcasecmp(node->info->id, last_demux_name) == 0) {
last_demux = node;
} else {
- xprintf(stream->xine, XINE_VERBOSITY_DEBUG,
+ xprintf(stream->xine, XINE_VERBOSITY_DEBUG,
"load_plugin: probing '%s' (method %d)...\n", node->info->id, stream->content_detection_method );
if (node->plugin_class || _load_plugin_class(xine, node, NULL)) {
if ((plugin = ((demux_class_t *)node->plugin_class)->open_plugin(node->plugin_class, stream, input))) {
@@ -1485,7 +1546,7 @@ const char *const *xine_get_browsable_input_plugin_ids(xine_t *this) {
for (list_id = 0; list_id < list_size; list_id++) {
input_class_t *ic;
-
+
node = xine_sarray_get(catalog->plugin_lists[PLUGIN_INPUT - 1], list_id);
if (node->plugin_class || _load_plugin_class(this, node, NULL)) {
@@ -1544,7 +1605,7 @@ vo_driver_t *_x_load_video_output_plugin(xine_t *this,
if (id && !strcasecmp(id, "auto"))
id = NULL;
-
+
pthread_mutex_lock (&catalog->lock);
list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_VIDEO_OUT - 1]);
@@ -1592,7 +1653,7 @@ xine_video_port_t *xine_open_video_driver (xine_t *this,
}
port = _x_vo_new_port(this, driver, 0);
-
+
return port;
}
@@ -1631,7 +1692,7 @@ xine_video_port_t *xine_new_framegrab_video_port (xine_t *this) {
}
port = _x_vo_new_port(this, driver, 1);
-
+
return port;
}
@@ -1641,7 +1702,7 @@ xine_video_port_t *xine_new_framegrab_video_port (xine_t *this) {
const char *const *xine_list_audio_output_plugins (xine_t *xine) {
plugin_catalog_t *catalog = xine->plugin_catalog;
-
+
pthread_mutex_lock (&catalog->lock);
_build_list_typed_plugins(&catalog, catalog->plugin_lists[PLUGIN_AUDIO_OUT - 1]);
pthread_mutex_unlock (&catalog->lock);
@@ -1651,7 +1712,7 @@ const char *const *xine_list_audio_output_plugins (xine_t *xine) {
const char *const *xine_list_video_output_plugins (xine_t *xine) {
plugin_catalog_t *catalog = xine->plugin_catalog;
-
+
pthread_mutex_lock (&catalog->lock);
_build_list_typed_plugins(&catalog, catalog->plugin_lists[PLUGIN_VIDEO_OUT - 1]);
pthread_mutex_unlock (&catalog->lock);
@@ -1659,6 +1720,36 @@ const char *const *xine_list_video_output_plugins (xine_t *xine) {
return catalog->ids;
}
+const char *const *xine_list_video_output_plugins_typed(xine_t *xine, uint64_t typemask)
+{
+ plugin_catalog_t *catalog = xine->plugin_catalog;
+ plugin_node_t *node;
+ int list_id, list_size, i;
+
+ pthread_mutex_lock (&catalog->lock);
+
+ list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_VIDEO_OUT - 1]);
+
+ for (list_id = i = 0; list_id < list_size; list_id++)
+ {
+ node = xine_sarray_get (catalog->plugin_lists[PLUGIN_VIDEO_OUT - 1], list_id);
+ if (typemask & (1ULL << ((vo_info_t *)node->info->special_info)->visual_type))
+ {
+ const char *id = node->info->id;
+ int j = i;
+ while (--j >= 0)
+ if (!strcmp (catalog->ids[j], id))
+ goto ignore; /* already listed */
+ catalog->ids[i++] = id;
+ }
+ ignore: ;
+ }
+ catalog->ids[i] = NULL;
+
+ pthread_mutex_unlock (&catalog->lock);
+ return catalog->ids;
+}
+
static ao_driver_t *_load_audio_driver (xine_t *this, plugin_node_t *node,
void *data) {
@@ -1721,7 +1812,7 @@ xine_audio_port_t *xine_open_audio_driver (xine_t *this, const char *id,
if (id && !strcasecmp(id, "auto") )
id = NULL;
-
+
pthread_mutex_lock (&catalog->lock);
driver = NULL;
@@ -1747,13 +1838,13 @@ xine_audio_port_t *xine_open_audio_driver (xine_t *this, const char *id,
}
pthread_mutex_unlock (&catalog->lock);
-
+
if (!driver) {
if (id)
xprintf (this, XINE_VERBOSITY_LOG,
_("load_plugins: failed to load audio output plugin <%s>\n"), id);
else
- xprintf (this, XINE_VERBOSITY_LOG,
+ xprintf (this, XINE_VERBOSITY_LOG,
_("load_plugins: audio output auto-probing didn't find any usable audio driver.\n"));
return NULL;
}
@@ -1811,7 +1902,7 @@ char **xine_get_autoplay_mrls (xine_t *this, const char *plugin_id,
if (node->plugin_class || _load_plugin_class (this, node, NULL)) {
ic = (input_class_t *) node->plugin_class;
-
+
if (!ic->get_autoplay_list)
return NULL;
@@ -1845,7 +1936,7 @@ xine_mrl_t **xine_get_browse_mrls (xine_t *this, const char *plugin_id,
if (node->plugin_class || _load_plugin_class (this, node, NULL)) {
ic = (input_class_t *) node->plugin_class;
-
+
if (!ic->get_dir)
return NULL;
@@ -1877,7 +1968,7 @@ video_decoder_t *_x_get_video_decoder (xine_stream_t *stream, uint8_t stream_typ
if (!node->plugin_class && !_load_plugin_class (stream->xine, node, NULL)) {
/* remove non working plugin from catalog */
- xprintf(stream->xine, XINE_VERBOSITY_DEBUG,
+ xprintf(stream->xine, XINE_VERBOSITY_DEBUG,
"load_plugins: plugin %s failed to init its class.\n", node->info->id);
for (j = i + 1; j < PLUGINS_PER_TYPE; j++)
catalog->video_decoder_map[stream_type][j - 1] =
@@ -1893,9 +1984,9 @@ video_decoder_t *_x_get_video_decoder (xine_stream_t *stream, uint8_t stream_typ
inc_node_ref(node);
vd->node = node;
xprintf(stream->xine, XINE_VERBOSITY_DEBUG,
- "load_plugins: plugin %s will be used for video streamtype %02x.\n",
+ "load_plugins: plugin %s will be used for video streamtype %02x.\n",
node->info->id, stream_type);
-
+
break;
} else {
/* remove non working plugin from catalog */
@@ -1948,7 +2039,7 @@ audio_decoder_t *_x_get_audio_decoder (xine_stream_t *stream, uint8_t stream_typ
if (!node->plugin_class && !_load_plugin_class (stream->xine, node, NULL)) {
/* remove non working plugin from catalog */
- xprintf(stream->xine, XINE_VERBOSITY_DEBUG,
+ xprintf(stream->xine, XINE_VERBOSITY_DEBUG,
"load_plugins: plugin %s failed to init its class.\n", node->info->id);
for (j = i + 1; j < PLUGINS_PER_TYPE; j++)
catalog->audio_decoder_map[stream_type][j - 1] =
@@ -1964,7 +2055,7 @@ audio_decoder_t *_x_get_audio_decoder (xine_stream_t *stream, uint8_t stream_typ
inc_node_ref(node);
ad->node = node;
xprintf(stream->xine, XINE_VERBOSITY_DEBUG,
- "load_plugins: plugin %s will be used for audio streamtype %02x.\n",
+ "load_plugins: plugin %s will be used for audio streamtype %02x.\n",
node->info->id, stream_type);
break;
} else {
@@ -2004,11 +2095,11 @@ int _x_decoder_available (xine_t *xine, uint32_t buftype)
if ( (buftype & 0xFF000000) == BUF_VIDEO_BASE ) {
if( catalog->video_decoder_map[stream_type][0] )
return 1;
- } else
+ } else
if ( (buftype & 0xFF000000) == BUF_AUDIO_BASE ) {
if( catalog->audio_decoder_map[stream_type][0] )
return 1;
- } else
+ } else
if ( (buftype & 0xFF000000) == BUF_SPU_BASE ) {
if( catalog->spu_decoder_map[stream_type][0] )
return 1;
@@ -2035,7 +2126,7 @@ static void _display_file_plugin_list (xine_list_t *list, plugin_file_t *file) {
#endif
static void _unload_unref_plugins(xine_t *this, xine_sarray_t *list) {
-
+
plugin_node_t *node;
int list_id, list_size;
@@ -2073,7 +2164,7 @@ void xine_plugins_garbage_collector(xine_t *self) {
pthread_mutex_lock (&catalog->lock);
for(i = 0; i < PLUGIN_TYPE_MAX; i++) {
_unload_unref_plugins(self, self->plugin_catalog->plugin_lists[i]);
- }
+ }
#if 0
{
@@ -2135,7 +2226,7 @@ spu_decoder_t *_x_get_spu_decoder (xine_stream_t *stream, uint8_t stream_type) {
inc_node_ref(node);
sd->node = node;
xprintf(stream->xine, XINE_VERBOSITY_DEBUG,
- "load_plugins: plugin %s will be used for spu streamtype %02x.\n",
+ "load_plugins: plugin %s will be used for spu streamtype %02x.\n",
node->info->id, stream_type);
break;
} else {
@@ -2169,7 +2260,7 @@ void _x_free_spu_decoder (xine_stream_t *stream, spu_decoder_t *sd) {
const char *const *xine_list_demuxer_plugins(xine_t *xine) {
plugin_catalog_t *catalog = xine->plugin_catalog;
-
+
pthread_mutex_lock (&catalog->lock);
_build_list_typed_plugins(&catalog, catalog->plugin_lists[PLUGIN_DEMUX - 1]);
pthread_mutex_unlock (&catalog->lock);
@@ -2179,7 +2270,7 @@ const char *const *xine_list_demuxer_plugins(xine_t *xine) {
const char *const *xine_list_input_plugins(xine_t *xine) {
plugin_catalog_t *catalog = xine->plugin_catalog;
-
+
pthread_mutex_lock (&catalog->lock);
_build_list_typed_plugins(&catalog, catalog->plugin_lists[PLUGIN_INPUT - 1]);
pthread_mutex_unlock (&catalog->lock);
@@ -2189,7 +2280,7 @@ const char *const *xine_list_input_plugins(xine_t *xine) {
const char *const *xine_list_spu_plugins(xine_t *xine) {
plugin_catalog_t *catalog = xine->plugin_catalog;
-
+
pthread_mutex_lock (&catalog->lock);
_build_list_typed_plugins(&catalog, catalog->plugin_lists[PLUGIN_SPU_DECODER - 1]);
pthread_mutex_unlock (&catalog->lock);
@@ -2199,7 +2290,7 @@ const char *const *xine_list_spu_plugins(xine_t *xine) {
const char *const *xine_list_audio_decoder_plugins(xine_t *xine) {
plugin_catalog_t *catalog = xine->plugin_catalog;
-
+
pthread_mutex_lock (&catalog->lock);
_build_list_typed_plugins(&catalog, catalog->plugin_lists[PLUGIN_AUDIO_DECODER - 1]);
pthread_mutex_unlock (&catalog->lock);
@@ -2209,7 +2300,7 @@ const char *const *xine_list_audio_decoder_plugins(xine_t *xine) {
const char *const *xine_list_video_decoder_plugins(xine_t *xine) {
plugin_catalog_t *catalog = xine->plugin_catalog;
-
+
pthread_mutex_lock (&catalog->lock);
_build_list_typed_plugins(&catalog, catalog->plugin_lists[PLUGIN_VIDEO_DECODER - 1]);
pthread_mutex_unlock (&catalog->lock);
@@ -2219,7 +2310,7 @@ const char *const *xine_list_video_decoder_plugins(xine_t *xine) {
const char *const *xine_list_post_plugins(xine_t *xine) {
plugin_catalog_t *catalog = xine->plugin_catalog;
-
+
pthread_mutex_lock (&catalog->lock);
_build_list_typed_plugins(&catalog, catalog->plugin_lists[PLUGIN_POST - 1]);
pthread_mutex_unlock (&catalog->lock);
@@ -2232,7 +2323,7 @@ const char *const *xine_list_post_plugins_typed(xine_t *xine, int type) {
plugin_node_t *node;
int i;
int list_id, list_size;
-
+
pthread_mutex_lock (&catalog->lock);
i = 0;
@@ -2287,25 +2378,25 @@ xine_post_t *xine_post_init(xine_t *xine, const char *name, int inputs,
plugin_node_t *node;
post_plugin_t *post = NULL;
int list_id, list_size;
-
+
if( !name )
return NULL;
-
+
pthread_mutex_lock(&catalog->lock);
-
+
list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_POST - 1]);
for (list_id = 0; list_id < list_size; list_id++) {
node = xine_sarray_get (catalog->plugin_lists[PLUGIN_POST - 1], list_id);
-
+
if (strcmp(node->info->id, name) == 0) {
-
+
if (!node->plugin_class && !_load_plugin_class(xine, node, NULL)) {
xprintf(xine, XINE_VERBOSITY_DEBUG,
"load_plugins: requested post plugin %s failed to load\n", name);
break;
}
-
+
post = ((post_class_t *)node->plugin_class)->open_plugin(node->plugin_class,
inputs, audio_target, video_target);
@@ -2314,12 +2405,12 @@ xine_post_t *xine_post_init(xine_t *xine, const char *name, int inputs,
xine_post_out_t *output;
xine_list_iterator_t ite;
int i;
-
+
post->running_ticket = xine->port_ticket;
post->xine = xine;
post->node = node;
inc_node_ref(node);
-
+
/* init the lists of announced connections */
i = 0;
ite = xine_list_front(post->input);
@@ -2337,7 +2428,7 @@ xine_post_t *xine_post_init(xine_t *xine, const char *name, int inputs,
ite = xine_list_next (post->input, ite);
}
post->input_ids[i] = NULL;
-
+
i = 0;
ite = xine_list_front (post->output);
while (ite) {
@@ -2354,10 +2445,10 @@ xine_post_t *xine_post_init(xine_t *xine, const char *name, int inputs,
ite = xine_list_next (post->output, ite);
}
post->output_ids[i] = NULL;
-
+
/* copy the post plugin type to the public part */
post->xine_post.type = ((post_info_t *)node->info->special_info)->type;
-
+
break;
} else {
xprintf(xine, XINE_VERBOSITY_DEBUG,
@@ -2366,9 +2457,9 @@ xine_post_t *xine_post_init(xine_t *xine, const char *name, int inputs,
}
}
}
-
+
pthread_mutex_unlock(&catalog->lock);
-
+
if(post)
return &post->xine_post;
else {
@@ -2384,73 +2475,67 @@ void xine_post_dispose(xine_t *xine, xine_post_t *post_gen) {
* their disposal if they are still in use => post.c handles the counting for us */
}
+/**
+ * @brief Concantenates an array of strings into a single
+ * string separated with a given string.
+ *
+ * @param strings Array of strings to concatenate.
+ * @param count Number of elements in the @p strings array.
+ * @param joining String to use to join the various strings together.
+ * @param final_length The pre-calculated final length of the string.
+ */
+static char *_x_concatenate_with_string(char const **strings, size_t count, char *joining, size_t final_length) {
+ size_t i;
+ char *const result = malloc(final_length+1); /* Better be safe */
+ char *str = result;
+
+ for(i = 0; i < count; i++, strings++) {
+ if ( *strings ) {
+ int offset = snprintf(str, final_length, "%s%s", *strings, joining);
+ str += offset;
+ final_length -= offset;
+ }
+ }
+
+ return result;
+}
+
/* get a list of file extensions for file types supported by xine
- * the list is separated by spaces
+ * the list is separated by spaces
*
* the pointer returned can be free()ed when no longer used */
char *xine_get_file_extensions (xine_t *self) {
plugin_catalog_t *catalog = self->plugin_catalog;
- int len, pos;
- plugin_node_t *node;
- char *str;
- int list_id, list_size;
+ int list_id;
pthread_mutex_lock (&catalog->lock);
- /* calc length of output */
+ /* calc length of output string and create an array of strings to
+ concatenate */
+ size_t len = 0;
+ const int list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_DEMUX - 1]);
+ const char **extensions = calloc(list_size, sizeof(char*));
- len = 0;
- list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_DEMUX - 1]);
for (list_id = 0; list_id < list_size; list_id++) {
- demux_class_t *cls;
- const char *exts;
-
- node = xine_sarray_get (catalog->plugin_lists[PLUGIN_DEMUX - 1], list_id);
+ plugin_node_t *const node = xine_sarray_get (catalog->plugin_lists[PLUGIN_DEMUX - 1], list_id);
if (node->plugin_class || _load_plugin_class(self, node, NULL)) {
-
- cls = (demux_class_t *)node->plugin_class;
-
- if((exts = cls->get_extensions(cls)) && *exts)
- len += strlen(exts) + 1;
+ demux_class_t *const cls = (demux_class_t *)node->plugin_class;
+ if( (extensions[list_id] = cls->get_extensions(cls)) != NULL )
+ len += strlen(extensions[list_id]) +1;
}
}
- /* create output */
- str = malloc (len); /* '\0' space is already counted in the previous loop */
- pos = 0;
+ /* create output string */
+ char *const result = _x_concatenate_with_string(extensions, list_size, " ", len);
+ free(extensions);
- list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_DEMUX - 1]);
- for (list_id = 0; list_id < list_size; list_id++) {
- demux_class_t *cls;
- const char *e;
- int l;
-
- node = xine_sarray_get (catalog->plugin_lists[PLUGIN_DEMUX - 1], list_id);
- if (node->plugin_class || _load_plugin_class(self, node, NULL)) {
+ /* Drop the last whitespace */
+ result[len-1] = '\0';
- cls = (demux_class_t *)node->plugin_class;
-
- if((e = cls->get_extensions (cls)) && *e) {
- l = strlen(e);
- memcpy (&str[pos], e, l);
-
- pos += l;
-
- /* Don't add ' ' char at the end of str */
- if((pos + 1) < len) {
- str[pos] = ' ';
- pos++;
- }
- }
- }
- }
-
- str[pos] = 0;
-
pthread_mutex_unlock (&catalog->lock);
- return str;
+ return result;
}
/* get a list of mime types supported by xine
@@ -2459,65 +2544,34 @@ char *xine_get_file_extensions (xine_t *self) {
char *xine_get_mime_types (xine_t *self) {
plugin_catalog_t *catalog = self->plugin_catalog;
- int len, pos;
- plugin_node_t *node;
- char *str;
- int list_id, list_size;
+ int list_id;
pthread_mutex_lock (&catalog->lock);
/* calc length of output */
- len = 0;
- list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_DEMUX - 1]);
+ /* calc length of output string and create an array of strings to
+ concatenate */
+ size_t len = 0;
+ const int list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_DEMUX - 1]);
+ const char **mimetypes = calloc(list_size, sizeof(char*));
for (list_id = 0; list_id < list_size; list_id++) {
- demux_class_t *cls;
- const char *s;
-
- node = xine_sarray_get (catalog->plugin_lists[PLUGIN_DEMUX - 1], list_id);
+ plugin_node_t *const node = xine_sarray_get (catalog->plugin_lists[PLUGIN_DEMUX - 1], list_id);
if (node->plugin_class || _load_plugin_class(self, node, NULL)) {
-
- cls = (demux_class_t *)node->plugin_class;
-
- s = cls->get_mimetypes (cls);
- if (s)
- len += strlen(s);
+ demux_class_t *const cls = (demux_class_t *)node->plugin_class;
+ if( (mimetypes[list_id] = cls->get_mimetypes(cls)) != NULL )
+ len += strlen(mimetypes[list_id]);
}
}
- /* create output */
-
- str = malloc (len+1);
- pos = 0;
-
- list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_DEMUX - 1]);
-
- for (list_id = 0; list_id < list_size; list_id++) {
- demux_class_t *cls;
- const char *s;
- int l;
-
- node = xine_sarray_get (catalog->plugin_lists[PLUGIN_DEMUX - 1], list_id);
- if (node->plugin_class || _load_plugin_class(self, node, NULL)) {
-
- cls = (demux_class_t *)node->plugin_class;
+ /* create output string */
+ char *const result = _x_concatenate_with_string(mimetypes, list_size, "", len);
+ free(mimetypes);
- s = cls->get_mimetypes (cls);
- if (s) {
- l = strlen(s);
- memcpy (&str[pos], s, l);
-
- pos += l;
- }
- }
- }
-
- str[pos] = 0;
-
pthread_mutex_unlock (&catalog->lock);
- return str;
+ return result;
}
@@ -2530,47 +2584,24 @@ char *xine_get_demux_for_mime_type (xine_t *self, const char *mime_type) {
plugin_catalog_t *catalog = self->plugin_catalog;
plugin_node_t *node;
char *id = NULL;
- char *mime_arg, *mime_demux;
- char *s;
- const char *mt;
int list_id, list_size;
- /* create a copy and convert to lower case */
- mime_arg = strdup(mime_type);
- for(s=mime_arg; *s; s++)
- *s = tolower(*s);
-
pthread_mutex_lock (&catalog->lock);
list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_DEMUX - 1]);
for (list_id = 0; (list_id < list_size) && !id; list_id++) {
- demux_class_t *cls;
node = xine_sarray_get (catalog->plugin_lists[PLUGIN_DEMUX - 1], list_id);
- if (node->plugin_class || _load_plugin_class(self, node, NULL)) {
-
- cls = (demux_class_t *)node->plugin_class;
-
- mt = cls->get_mimetypes (cls);
- if (mt) {
- mime_demux = strdup(mt);
-
- for(s=mime_demux; *s; s++)
- *s = tolower(*s);
-
- if( strstr(mime_demux, mime_arg) )
- id = strdup(node->info->id);
-
- free(mime_demux);
- }
+ if (probe_mime_type (self, node, mime_type))
+ {
+ free (id);
+ id = strdup(node->info->id);
}
}
pthread_mutex_unlock (&catalog->lock);
- free(mime_arg);
-
return id;
}
@@ -2582,7 +2613,7 @@ static void dispose_plugin_list (xine_sarray_t *list) {
int list_id, list_size;
if (list) {
-
+
list_size = xine_sarray_size (list);
for (list_id = 0; list_id < list_size; list_id++) {
@@ -2603,12 +2634,12 @@ static void dispose_plugin_list (xine_sarray_t *list) {
decoder_info = (decoder_info_t *)node->info->special_info;
free (decoder_info->supported_types);
-
+
default:
free ((void *)node->info->special_info);
break;
}
-
+
/* free info structure and string copies */
free (node->info->id);
free (node->info);