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.c457
1 files changed, 244 insertions, 213 deletions
diff --git a/src/xine-engine/load_plugins.c b/src/xine-engine/load_plugins.c
index 71cb19d3b..5128644da 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.
*
@@ -313,7 +313,6 @@ 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);
@@ -325,8 +324,8 @@ static void _insert_node (xine_t *this,
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,
@@ -402,14 +400,14 @@ static void _insert_node (xine_t *this,
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;
@@ -426,7 +424,7 @@ 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;
@@ -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,7 +485,7 @@ 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
@@ -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
@@ -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;
@@ -981,34 +974,34 @@ static void load_plugin_list(FILE *fp, xine_sarray_t *plugins) {
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;
}
@@ -1029,7 +1022,7 @@ static void load_plugin_list(FILE *fp, xine_sarray_t *plugins) {
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, ' ');
@@ -1069,22 +1062,21 @@ 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;
+
+ const char *const homedir = xine_get_homedir();
- cachefile = (char *) xine_xmalloc(strlen(xine_get_homedir()) +
- strlen(relname) + 2);
- sprintf(cachefile, "%s/%s", xine_get_homedir(), relname);
+ 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");
@@ -1093,9 +1085,29 @@ static void save_catalog (xine_t *this) {
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);
}
/*
@@ -1107,9 +1119,7 @@ static void load_cached_catalog (xine_t *this) {
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);
@@ -1119,14 +1129,24 @@ 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");
@@ -1140,41 +1160,45 @@ 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);
@@ -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;
@@ -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) {
@@ -2384,6 +2475,31 @@ 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
*
@@ -2391,66 +2507,35 @@ void xine_post_dispose(xine_t *xine, xine_post_t *post_gen) {
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 */
-
- 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);
- 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;
- }
- }
-
- /* create output */
- str = malloc (len); /* '\0' space is already counted in the previous loop */
- pos = 0;
+ /* 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*));
- 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);
+ 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((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++;
- }
- }
+ 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;
}
}
- str[pos] = 0;
+ /* create output string */
+ char *const result = _x_concatenate_with_string(extensions, list_size, " ", len);
+ free(extensions);
+ /* Drop the last whitespace */
+ result[len-1] = '\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)) {
+ /* create output string */
+ char *const result = _x_concatenate_with_string(mimetypes, list_size, "", len);
+ free(mimetypes);
- cls = (demux_class_t *)node->plugin_class;
-
- 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;
}