summaryrefslogtreecommitdiff
path: root/src/xine-engine
diff options
context:
space:
mode:
Diffstat (limited to 'src/xine-engine')
-rw-r--r--src/xine-engine/load_plugins.c73
-rw-r--r--src/xine-engine/xine.c35
-rw-r--r--src/xine-engine/xine_internal.h3
3 files changed, 77 insertions, 34 deletions
diff --git a/src/xine-engine/load_plugins.c b/src/xine-engine/load_plugins.c
index 107e7d792..a71092761 100644
--- a/src/xine-engine/load_plugins.c
+++ b/src/xine-engine/load_plugins.c
@@ -1224,6 +1224,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) {
@@ -1246,8 +1266,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]);
@@ -1259,6 +1277,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;
@@ -1356,6 +1393,7 @@ demux_plugin_t *_x_find_demux_plugin_last_probe(xine_stream_t *stream, const cha
i = 0;
while (methods[i] != -1 && !plugin) {
int list_id, list_size;
+ const char *mime_type;
stream->content_detection_method = methods[i];
@@ -2519,47 +2557,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;
}
diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c
index 46d3b424f..e4e36527f 100644
--- a/src/xine-engine/xine.c
+++ b/src/xine-engine/xine.c
@@ -1185,6 +1185,27 @@ static int open_internal (xine_stream_t *stream, const char *mrl) {
/* enable buffered input plugin (request optimizer) */
stream->input_plugin = _x_cache_plugin_get_instance(stream, 0);
+ /* Let the plugin request a specific demuxer (if the user hasn't).
+ * This overrides find-by-content & find-by-extension.
+ */
+ if (!stream->demux_plugin)
+ {
+ char *default_demux = NULL;
+ stream->input_plugin->get_optional_data (stream->input_plugin, &default_demux, INPUT_OPTIONAL_DATA_DEMUXER);
+ if (default_demux)
+ {
+ stream->demux_plugin = _x_find_demux_plugin_by_name (stream, default_demux, stream->input_plugin);
+ if (stream->demux_plugin)
+ {
+ lprintf ("demux and input plugin found\n");
+ _x_meta_info_set_utf8 (stream, XINE_META_INFO_SYSTEMLAYER,
+ stream->demux_plugin->demux_class->get_identifier (stream->demux_plugin->demux_class));
+ }
+ else
+ xine_log (stream->xine, XINE_LOG_MSG, _("xine: couldn't load plugin-specified demux %s for >%s<\n"), default_demux, mrl);
+ }
+ }
+
if (!stream->demux_plugin) {
/*
@@ -2229,7 +2250,10 @@ void xine_log (xine_t *this, int buf, const char *format, ...) {
vsnprintf(buffer, SCRATCH_LINE_LEN_MAX, format, argp);
printf("%s", buffer);
va_end (argp);
- }
+ }
+
+ if (this->log_cb)
+ this->log_cb (this->log_cb_user_data, buf);
}
void xine_vlog(xine_t *this, int buf, const char *format,
@@ -2238,6 +2262,9 @@ void xine_vlog(xine_t *this, int buf, const char *format,
check_log_alloc (this, buf);
this->log_buffers[buf]->scratch_printf(this->log_buffers[buf], format, args);
+
+ if (this->log_cb)
+ this->log_cb (this->log_cb_user_data, buf);
}
char *const *xine_get_log (xine_t *this, int buf) {
@@ -2252,12 +2279,10 @@ char *const *xine_get_log (xine_t *this, int buf) {
}
void xine_register_log_cb (xine_t *this, xine_log_cb_t cb, void *user_data) {
-
- printf ("xine: xine_register_log_cb: not implemented yet.\n");
- _x_abort();
+ this->log_cb = cb;
+ this->log_cb_user_data = user_data;
}
-
int xine_get_error (xine_stream_t *stream) {
return stream->err;
}
diff --git a/src/xine-engine/xine_internal.h b/src/xine-engine/xine_internal.h
index 85f3d6489..f97ca0b24 100644
--- a/src/xine-engine/xine_internal.h
+++ b/src/xine-engine/xine_internal.h
@@ -117,6 +117,9 @@ struct xine_s {
#ifdef XINE_ENGINE_INTERNAL
xine_ticket_t *port_ticket;
pthread_mutex_t log_lock;
+
+ xine_log_cb_t log_cb;
+ void *log_cb_user_data;
#endif
};