[rhythmbox] metadata: ignore non-media files better
- From: Jonathan Matthew <jmatthew src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [rhythmbox] metadata: ignore non-media files better
- Date: Thu, 1 Mar 2012 11:38:37 +0000 (UTC)
commit bdf8dfaef826256d0419d3098a30e5e54232e27e
Author: Jonathan Matthew <jonathan d14n org>
Date: Thu Mar 1 09:03:36 2012 +1000
metadata: ignore non-media files better
When GstDiscoverer doesn't give us any stream information, run
a simple typefinding pipeline to get the media type. Its result
isn't always GST_DISCOVERER_MISSING_PLUGINS when there is missing
plugin information, so don't rely on it.
lib/rb-gst-media-types.c | 5 ++
metadata/rb-metadata-dbus-service.c | 1 +
metadata/rb-metadata-gst.c | 117 +++++++++++++++++++++++++++-------
3 files changed, 99 insertions(+), 24 deletions(-)
---
diff --git a/lib/rb-gst-media-types.c b/lib/rb-gst-media-types.c
index 65ea345..c691a18 100644
--- a/lib/rb-gst-media-types.c
+++ b/lib/rb-gst-media-types.c
@@ -60,6 +60,11 @@ rb_gst_get_missing_plugin_type (const GstStructure *structure)
const GValue *val;
int i;
+ if (structure == NULL) {
+ rb_debug ("no missing plugin details");
+ return MEDIA_TYPE_NONE;
+ }
+
missing_type = gst_structure_get_string (structure, "type");
if (missing_type == NULL || strcmp (missing_type, "decoder") != 0) {
rb_debug ("missing plugin is not a decoder");
diff --git a/metadata/rb-metadata-dbus-service.c b/metadata/rb-metadata-dbus-service.c
index 084a43a..cb29d33 100644
--- a/metadata/rb-metadata-dbus-service.c
+++ b/metadata/rb-metadata-dbus-service.c
@@ -284,6 +284,7 @@ test_load (const char *uri)
if (error) {
g_print ("Error loading metadata from %s: %s\n", uri, error->message);
g_clear_error (&error);
+ g_print ("media type: %s\n", rb_metadata_get_media_type (md));
rv = -1;
} else {
int i;
diff --git a/metadata/rb-metadata-gst.c b/metadata/rb-metadata-gst.c
index cdfcae2..52548da 100644
--- a/metadata/rb-metadata-gst.c
+++ b/metadata/rb-metadata-gst.c
@@ -90,6 +90,72 @@ rb_metadata_reset (RBMetaData *md)
md->priv->has_video = FALSE;
}
+static void
+have_type_cb (GstElement *element, guint probability, GstCaps *caps, RBMetaData *md)
+{
+ md->priv->mediatype = rb_gst_caps_to_media_type (caps);
+ rb_debug ("got type %s", md->priv->mediatype);
+}
+
+static void
+run_typefind (RBMetaData *md, const char *uri)
+{
+ GstElement *src;
+
+ src = gst_element_make_from_uri (GST_URI_SRC, uri, NULL);
+ if (src != NULL) {
+ GstElement *pipeline = gst_pipeline_new (NULL);
+ GstElement *sink = gst_element_factory_make ("fakesink", NULL);
+ GstElement *typefind = gst_element_factory_make ("typefind", NULL);
+
+ gst_bin_add_many (GST_BIN (pipeline), src, typefind, sink, NULL);
+ if (gst_element_link_many (src, typefind, sink, NULL)) {
+ GstBus *bus;
+ GstMessage *message;
+ gboolean done;
+
+ g_signal_connect (typefind, "have-type", G_CALLBACK (have_type_cb), md);
+
+ bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
+ gst_element_set_state (pipeline, GST_STATE_PAUSED);
+ done = FALSE;
+
+ while (done == FALSE && md->priv->mediatype == NULL) {
+ message = gst_bus_timed_pop (bus, 5 * GST_SECOND);
+ if (message == NULL) {
+ rb_debug ("typefind pass timed out");
+ break;
+ }
+
+ switch (GST_MESSAGE_TYPE (message)) {
+ case GST_MESSAGE_ERROR:
+ rb_debug ("typefind pass got an error");
+ done = TRUE;
+ break;
+
+ case GST_MESSAGE_STATE_CHANGED:
+ if (GST_MESSAGE_SRC (message) == GST_OBJECT (pipeline)) {
+ GstState old, new, pending;
+ gst_message_parse_state_changed (message, &old, &new, &pending);
+ if (new == GST_STATE_PAUSED && pending == GST_STATE_VOID_PENDING) {
+ rb_debug ("typefind pipeline reached PAUSED");
+ done = TRUE;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
+ }
+
+ g_object_unref (pipeline);
+ }
+}
+
void
rb_metadata_load (RBMetaData *md, const char *uri, GError **error)
{
@@ -153,41 +219,44 @@ rb_metadata_load (RBMetaData *md, const char *uri, GError **error)
}
gst_discoverer_stream_info_list_free (streams);
+ /* if we don't have a media type, use typefind to get one */
+ if (md->priv->mediatype == NULL) {
+ run_typefind (md, uri);
+ }
+
/* look at missing plugin information too */
- if (rb_metadata_has_missing_plugins (md)) {
- switch (rb_gst_get_missing_plugin_type (gst_discoverer_info_get_misc (md->priv->info))) {
- case MEDIA_TYPE_NONE:
- break;
- case MEDIA_TYPE_CONTAINER:
- /* hm, maybe we need a way to say 'we don't even know what's in here'.
- * but for now, the things we actually identify as containers are mostly
- * used for audio, so pretending they actually are is good enough.
- */
- case MEDIA_TYPE_AUDIO:
- md->priv->has_audio = TRUE;
- break;
- case MEDIA_TYPE_VIDEO:
- md->priv->has_video = TRUE;
- break;
- case MEDIA_TYPE_OTHER:
- md->priv->has_non_audio = TRUE;
- break;
- default:
- g_assert_not_reached ();
- }
+ switch (rb_gst_get_missing_plugin_type (gst_discoverer_info_get_misc (md->priv->info))) {
+ case MEDIA_TYPE_NONE:
+ break;
+ case MEDIA_TYPE_CONTAINER:
+ /* hm, maybe we need a way to say 'we don't even know what's in here'.
+ * but for now, the things we actually identify as containers are mostly
+ * used for audio, so pretending they actually are is good enough.
+ */
+ case MEDIA_TYPE_AUDIO:
+ md->priv->has_audio = TRUE;
+ break;
+ case MEDIA_TYPE_VIDEO:
+ md->priv->has_video = TRUE;
+ break;
+ case MEDIA_TYPE_OTHER:
+ md->priv->has_non_audio = TRUE;
+ break;
+ default:
+ g_assert_not_reached ();
}
}
gboolean
rb_metadata_has_missing_plugins (RBMetaData *md)
{
- GstDiscovererResult result;
+ const GstStructure *s;
if (md->priv->info == NULL) {
return FALSE;
}
- result = gst_discoverer_info_get_result (md->priv->info);
- return ((result & GST_DISCOVERER_MISSING_PLUGINS) != 0);
+ s = gst_discoverer_info_get_misc (md->priv->info);
+ return (rb_gst_get_missing_plugin_type (s) != MEDIA_TYPE_NONE);
}
gboolean
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]