[tracker/gstreamer-with-dlna: 7/7] tracker-extract, gstreamer: don't compile both tagreadbin and decodebin2



commit 56aac39b60788115084c9480097dbe356d0d485d
Author: Aleksander Morgado <aleksander lanedo com>
Date:   Tue Jul 12 18:07:58 2011 +0200

    tracker-extract,gstreamer: don't compile both tagreadbin and decodebin2
    
    ... and prepare for the Discoverer API based implementation

 src/tracker-extract/tracker-extract-gstreamer.c |  767 +++++++++++++----------
 1 files changed, 421 insertions(+), 346 deletions(-)
---
diff --git a/src/tracker-extract/tracker-extract-gstreamer.c b/src/tracker-extract/tracker-extract-gstreamer.c
index 9ef72b1..02d7560 100644
--- a/src/tracker-extract/tracker-extract-gstreamer.c
+++ b/src/tracker-extract/tracker-extract-gstreamer.c
@@ -31,6 +31,7 @@
 
 #include <gst/gst.h>
 #include <gst/tag/tag.h>
+
 #include <libtracker-common/tracker-common.h>
 #include <libtracker-extract/tracker-extract.h>
 
@@ -81,7 +82,6 @@
 #define GST_TAG_DEVICE_MAKE "device-make"
 #endif
 
-
 typedef enum {
 	EXTRACT_MIME_AUDIO,
 	EXTRACT_MIME_VIDEO,
@@ -91,19 +91,21 @@ typedef enum {
 } ExtractMime;
 
 typedef struct {
+	ExtractMime     mime;
+
+#if defined(GSTREAMER_BACKEND_TAGREADBIN) || defined(GSTREAMER_BACKEND_DECODEBIN2)
 	/* Common pipeline elements */
 	GstElement     *pipeline;
-
 	GstBus         *bus;
+#endif
 
-	ExtractMime     mime;
-
-
+#if defined(GSTREAMER_BACKEND_DECODEBIN2)
 	/* Decodebin elements and properties*/
 	GstElement     *bin;
 	GList          *fsinks;
-
 	gint64          duration;
+#endif
+
 	gint            video_height;
 	gint            video_width;
 	gint            video_fps_n;
@@ -123,34 +125,17 @@ typedef struct {
 
 } MetadataExtractor;
 
-/* Not using define directly since we might want to make this dynamic */
-#ifdef TRACKER_EXTRACT_GSTREAMER_USE_TAGREADBIN
-const gboolean use_tagreadbin = TRUE;
-#else
-const gboolean use_tagreadbin = FALSE;
+#if defined(GSTREAMER_BACKEND_TAGREADBIN)
+static void tagreadbin_extract_stream_metadata (MetadataExtractor    *extractor,
+                                                const gchar          *uri,
+                                                TrackerSparqlBuilder *metadata);
+#elif defined(GSTREAMER_BACKEND_DECODEBIN2)
+static void decodebin2_extract_stream_metadata (MetadataExtractor    *extractor,
+                                                const gchar          *uri,
+                                                TrackerSparqlBuilder *metadata);
 #endif
 
 static void
-add_int64_info (TrackerSparqlBuilder *metadata,
-                const gchar          *uri,
-                const gchar          *key,
-                gint64                info)
-{
-	tracker_sparql_builder_predicate (metadata, key);
-	tracker_sparql_builder_object_int64 (metadata, info);
-}
-
-static void
-add_uint_info (TrackerSparqlBuilder *metadata,
-               const gchar          *uri,
-               const gchar          *key,
-               guint                 info)
-{
-	tracker_sparql_builder_predicate (metadata, key);
-	tracker_sparql_builder_object_int64 (metadata, info);
-}
-
-static void
 add_string_gst_tag (TrackerSparqlBuilder *metadata,
                     const gchar          *uri,
                     const gchar          *key,
@@ -192,24 +177,6 @@ add_uint_gst_tag (TrackerSparqlBuilder  *metadata,
 }
 
 static void
-add_int_gst_tag (TrackerSparqlBuilder  *metadata,
-                 const gchar           *uri,
-                 const gchar           *key,
-                 GstTagList            *tag_list,
-                 const gchar           *tag)
-{
-	gboolean ret;
-	gint     n;
-
-	ret = gst_tag_list_get_int (tag_list, tag, &n);
-
-	if (ret) {
-		tracker_sparql_builder_predicate (metadata, key);
-		tracker_sparql_builder_object_int64 (metadata, n);
-	}
-}
-
-static void
 add_double_gst_tag (TrackerSparqlBuilder  *metadata,
                     const gchar           *uri,
                     const gchar           *key,
@@ -228,30 +195,6 @@ add_double_gst_tag (TrackerSparqlBuilder  *metadata,
 }
 
 static void
-add_fraction_gst_tag (TrackerSparqlBuilder  *metadata,
-                      const gchar           *uri,
-                      const gchar           *key,
-                      GstTagList            *tag_list,
-                      const gchar           *tag)
-{
-	gboolean ret;
-	GValue   n = {0,};
-	gfloat   f;
-
-	ret = gst_tag_list_copy_value (&n, tag_list, tag);
-
-	if (ret) {
-		f = (gfloat)gst_value_get_fraction_numerator (&n)/
-		gst_value_get_fraction_denominator (&n);
-
-		tracker_sparql_builder_predicate (metadata, key);
-		tracker_sparql_builder_object_double (metadata, (gdouble) f);
-
-		g_value_unset (&n);
-	}
-}
-
-static void
 add_date_time_gst_tag (TrackerSparqlBuilder  *metadata,
                        const gchar           *uri,
                        const gchar           *key,
@@ -307,28 +250,6 @@ add_date_time_gst_tag (TrackerSparqlBuilder  *metadata,
 }
 
 static void
-add_time_gst_tag (TrackerSparqlBuilder   *metadata,
-                  const gchar *uri,
-                  const gchar *key,
-                  GstTagList  *tag_list,
-                  const gchar *tag)
-{
-	gboolean ret;
-	guint64          n;
-
-	ret = gst_tag_list_get_uint64 (tag_list, tag, &n);
-
-	if (ret) {
-		gint64 duration;
-
-		duration = (n + (GST_SECOND / 2)) / GST_SECOND;
-
-		tracker_sparql_builder_predicate (metadata, key);
-		tracker_sparql_builder_object_int64 (metadata, duration);
-	}
-}
-
-static void
 add_keywords_gst_tag (TrackerSparqlBuilder *metadata,
                       GstTagList           *tag_list)
 {
@@ -355,7 +276,7 @@ add_keywords_gst_tag (TrackerSparqlBuilder *metadata,
 }
 
 static gboolean
-get_embedded_album_art(MetadataExtractor *extractor)
+get_embedded_album_art (MetadataExtractor *extractor)
 {
 	const GValue *value;
 	guint         lindex;
@@ -416,71 +337,6 @@ get_embedded_album_art(MetadataExtractor *extractor)
 }
 
 static void
-extract_stream_metadata_tagreadbin (MetadataExtractor     *extractor,
-                                    const gchar           *uri,
-                                    TrackerSparqlBuilder  *metadata)
-{
-	if (extractor->mime != EXTRACT_MIME_IMAGE && extractor->mime != EXTRACT_MIME_SVG) {
-		add_int_gst_tag (metadata, uri, "nfo:channels", extractor->tagcache, GST_TAG_CHANNEL);
-		add_int_gst_tag (metadata, uri, "nfo:sampleRate", extractor->tagcache, GST_TAG_RATE);
-		add_time_gst_tag (metadata, uri, "nfo:duration", extractor->tagcache, GST_TAG_DURATION);
-	}
-
-	if (extractor->mime == EXTRACT_MIME_IMAGE || extractor->mime == EXTRACT_MIME_SVG || extractor->mime == EXTRACT_MIME_VIDEO) {
-		add_fraction_gst_tag (metadata, uri, "nfo:aspectRatio", extractor->tagcache, GST_TAG_PIXEL_RATIO);
-	}
-
-	add_int_gst_tag (metadata, uri, "nfo:height", extractor->tagcache, GST_TAG_HEIGHT);
-	add_int_gst_tag (metadata, uri, "nfo:width", extractor->tagcache, GST_TAG_WIDTH);
-
-	if (extractor->mime == EXTRACT_MIME_VIDEO) {
-		add_fraction_gst_tag (metadata, uri, "nfo:frameRate", extractor->tagcache, GST_TAG_FRAMERATE);
-	}
-}
-
-static void
-extract_stream_metadata_decodebin (MetadataExtractor *extractor,
-                                   const gchar       *uri,
-                                   TrackerSparqlBuilder         *metadata)
-{
-	if (extractor->mime != EXTRACT_MIME_IMAGE && extractor->mime != EXTRACT_MIME_SVG) {
-
-		if (extractor->audio_channels >= 0) {
-			add_uint_info (metadata, uri, "nfo:channels", extractor->audio_channels);
-		}
-
-		if (extractor->audio_samplerate >= 0) {
-			add_uint_info (metadata, uri, "nfo:sampleRate", extractor->audio_samplerate);
-		}
-
-		if (extractor->duration >= 0) {
-			add_int64_info (metadata, uri, "nfo:duration", extractor->duration);
-		}
-	} else {
-		if (extractor->aspect_ratio >= 0) {
-			add_uint_info (metadata, uri, "nfo:aspectRatio", extractor->aspect_ratio);
-		}
-	}
-
-	if (extractor->video_height >= 0) {
-		add_uint_info (metadata, uri, "nfo:height", extractor->video_height);
-	}
-
-	if (extractor->video_width >= 0) {
-		add_uint_info (metadata, uri, "nfo:width", extractor->video_width);
-	}
-
-	if (extractor->mime == EXTRACT_MIME_VIDEO) {
-		if (extractor->video_fps_n >= 0 && extractor->video_fps_d >= 0) {
-			add_uint_info (metadata,
-			               uri, "nfo:frameRate",
-			               ((extractor->video_fps_n + extractor->video_fps_d / 2) /
-			                extractor->video_fps_d));
-		}
-	}
-}
-
-static void
 extract_metadata (MetadataExtractor      *extractor,
                   const gchar            *uri,
                   TrackerSparqlBuilder   *preupdate,
@@ -907,128 +763,28 @@ extract_metadata (MetadataExtractor      *extractor,
 		tracker_sparql_builder_object_boolean (metadata, TRUE);
 	}
 
-	if (use_tagreadbin) {
-		extract_stream_metadata_tagreadbin (extractor, uri, metadata);
-	} else {
-		extract_stream_metadata_decodebin (extractor, uri, metadata);
-	}
+#if defined(GSTREAMER_BACKEND_TAGREADBIN)
+	tagreadbin_extract_stream_metadata (extractor, uri, metadata);
+#elif defined(GSTREAMER_BACKEND_DECODEBIN2)
+	decodebin2_extract_stream_metadata (extractor, uri, metadata);
+#elif defined(GSTREAMER_BACKEND_DISCOVERER)
+	#warning TODO
+#else
+#error Not a valid GStreamer backend defined
+#endif
 
 	if (extractor->mime == EXTRACT_MIME_AUDIO) {
 		get_embedded_album_art (extractor);
 	}
 }
 
-static void
-unlink_fsink (void *obj, void *data_)
-{
-	MetadataExtractor *extractor = (MetadataExtractor *)data_;
-	GstElement        *fsink     = (GstElement *) obj;
-
-	gst_element_unlink (extractor->bin, fsink);
-	gst_bin_remove (GST_BIN (extractor->pipeline), fsink);
-	gst_element_set_state (fsink, GST_STATE_NULL);
-}
-
-static void
-dbin_dpad_cb (GstElement* e, GstPad* pad, gboolean cont, gpointer data_)
-{
-	MetadataExtractor *extractor = (MetadataExtractor *)data_;
-	GstElement        *fsink;
-	GstPad            *fsinkpad;
-	GValue             val = {0, };
-
-	fsink = gst_element_factory_make ("fakesink", NULL);
-
-	/* We increase the preroll buffer so we get duration (one frame not enough)*/
-	g_value_init (&val, G_TYPE_INT);
-	g_value_set_int (&val, 51);
-	g_object_set_property (G_OBJECT (fsink), "preroll-queue-len", &val);
-	g_value_unset (&val);
-
-	extractor->fsinks = g_list_append (extractor->fsinks, fsink);
-	gst_element_set_state (fsink, GST_STATE_PAUSED);
-
-	gst_bin_add (GST_BIN (extractor->pipeline), fsink);
-	fsinkpad = gst_element_get_static_pad (fsink, "sink");
-	gst_pad_link (pad, fsinkpad);
-	gst_object_unref (fsinkpad);
-}
-
-static guint64
-get_media_duration (MetadataExtractor *extractor)
-{
-	gint64    duration;
-	GstFormat fmt;
-
-	g_return_val_if_fail (extractor, -1);
-	g_return_val_if_fail (extractor->pipeline, -1);
-
-	fmt = GST_FORMAT_TIME;
-
-	duration = -1;
-
-	if (gst_element_query_duration (extractor->pipeline,
-	                                &fmt,
-	                                &duration) &&
-	    duration >= 0) {
-		return duration / GST_SECOND;
-	} else {
-		return -1;
-	}
-}
-
-static void
-add_stream_tag (void *obj, void *data_)
-{
-	MetadataExtractor *extractor = (MetadataExtractor *)data_;
-	GstElement        *fsink     = (GstElement *) obj;
-
-	GstStructure      *s         = NULL;
-	GstCaps                   *caps      = NULL;
-
-	if ((caps = GST_PAD_CAPS (fsink))) {
-		s = gst_caps_get_structure (caps, 0);
-
-		if (s) {
-			if (g_strrstr (gst_structure_get_name (s), "audio")) {
-				if ( ( (extractor->audio_channels != -1) &&
-				       (extractor->audio_samplerate != -1) ) ||
-				     !( (gst_structure_get_int (s,
-				                                "channels",
-				                                &extractor->audio_channels) ) &&
-				        (gst_structure_get_int (s,
-				                                "rate",
-				                                &extractor->audio_samplerate)) ) ) {
-					return;
-				}
-			} else if (g_strrstr (gst_structure_get_name (s), "video")) {
-				if ( ( (extractor->video_fps_n != -1) &&
-				       (extractor->video_fps_d != -1) &&
-				       (extractor->video_width != -1) &&
-				       (extractor->video_height != -1) ) ||
-				     !( (gst_structure_get_fraction (s,
-				                                     "framerate",
-				                                     &extractor->video_fps_n,
-				                                     &extractor->video_fps_d) ) &&
-				        (gst_structure_get_int (s, "width", &extractor->video_width)) &&
-				        (gst_structure_get_int (s, "height", &extractor->video_height)) &&
-				        (gst_structure_get_int (s, "pixel-aspect-ratio", &extractor->aspect_ratio)))) {
-					return;
-				}
-			}
-		}
-	}
-}
+/* --------------- Common Tagreadbin and Decodebin2 implementation ---------- */
 
-static void
-add_stream_tags (MetadataExtractor *extractor)
-{
-	extractor->duration = get_media_duration (extractor);
-	g_list_foreach (extractor->fsinks, add_stream_tag, extractor);
-}
+#if defined(GSTREAMER_BACKEND_TAGREADBIN) || defined(GSTREAMER_BACKEND_DECODEBIN2)
 
 static void
-add_tags (GstTagList *new_tags, MetadataExtractor *extractor)
+add_tags (GstTagList        *new_tags,
+          MetadataExtractor *extractor)
 {
 	GstTagList   *result;
 
@@ -1043,12 +799,21 @@ add_tags (GstTagList *new_tags, MetadataExtractor *extractor)
 	extractor->tagcache = result;
 }
 
+static void
+pipeline_shutdown (MetadataExtractor *extractor)
+{
+	gst_element_set_state (extractor->pipeline, GST_STATE_NULL);
+	gst_element_get_state (extractor->pipeline, NULL, NULL, TRACKER_EXTRACT_GUARD_TIMEOUT* GST_SECOND);
+	gst_object_unref (extractor->bus);
+
+	gst_object_unref (GST_OBJECT (extractor->pipeline));
+}
 
 static gboolean
-poll_for_ready (MetadataExtractor *extractor,
-                GstState           state,
-                gboolean           ready_with_state,
-                gboolean           ready_with_eos)
+pipeline_poll_for_ready (MetadataExtractor *extractor,
+                         GstState           state,
+                         gboolean           ready_with_state,
+                         gboolean           ready_with_eos)
 {
 	gint64              timeout   = 5 * GST_SECOND;
 	GstBus             *bus       = extractor->bus;
@@ -1154,12 +919,192 @@ poll_for_ready (MetadataExtractor *extractor,
 	return FALSE;
 }
 
-static GstElement *
-create_decodebin_pipeline (MetadataExtractor *extractor,
-                           const gchar *uri)
+#endif /* defined(GSTREAMER_BACKEND_TAGREADBIN) || defined(GSTREAMER_BACKEND_DECODEBIN2) */
+
+/* ----------------------- Decodebin2 specific implementation --------------- */
+
+#if defined(GSTREAMER_BACKEND_DECODEBIN2)
+
+static void
+add_int64_info (TrackerSparqlBuilder *metadata,
+                const gchar          *uri,
+                const gchar          *key,
+                gint64                info)
 {
-	GstElement *pipeline = NULL;
+	tracker_sparql_builder_predicate (metadata, key);
+	tracker_sparql_builder_object_int64 (metadata, info);
+}
+
+static void
+add_uint_info (TrackerSparqlBuilder *metadata,
+               const gchar          *uri,
+               const gchar          *key,
+               guint                 info)
+{
+	tracker_sparql_builder_predicate (metadata, key);
+	tracker_sparql_builder_object_int64 (metadata, info);
+}
+
+static void
+decodebin2_extract_stream_metadata (MetadataExtractor    *extractor,
+                                    const gchar          *uri,
+                                    TrackerSparqlBuilder *metadata)
+{
+	if (extractor->mime != EXTRACT_MIME_IMAGE &&
+	    extractor->mime != EXTRACT_MIME_SVG) {
+		if (extractor->audio_channels >= 0) {
+			add_uint_info (metadata, uri, "nfo:channels", extractor->audio_channels);
+		}
+
+		if (extractor->audio_samplerate >= 0) {
+			add_uint_info (metadata, uri, "nfo:sampleRate", extractor->audio_samplerate);
+		}
+
+		if (extractor->duration >= 0) {
+			add_int64_info (metadata, uri, "nfo:duration", extractor->duration);
+		}
+	} else {
+		if (extractor->aspect_ratio >= 0) {
+			add_uint_info (metadata, uri, "nfo:aspectRatio", extractor->aspect_ratio);
+		}
+	}
+
+	if (extractor->video_height >= 0) {
+		add_uint_info (metadata, uri, "nfo:height", extractor->video_height);
+	}
+
+	if (extractor->video_width >= 0) {
+		add_uint_info (metadata, uri, "nfo:width", extractor->video_width);
+	}
+
+	if (extractor->mime == EXTRACT_MIME_VIDEO) {
+		if (extractor->video_fps_n >= 0 && extractor->video_fps_d >= 0) {
+			add_uint_info (metadata,
+			               uri, "nfo:frameRate",
+			               ((extractor->video_fps_n + extractor->video_fps_d / 2) /
+			                extractor->video_fps_d));
+		}
+	}
+}
+
+static void
+decodebin2_unlink_fsink (void *obj,
+                         void *data)
+{
+	MetadataExtractor *extractor = (MetadataExtractor *)data;
+	GstElement        *fsink     = (GstElement *) obj;
+
+	gst_element_unlink (extractor->bin, fsink);
+	gst_bin_remove (GST_BIN (extractor->pipeline), fsink);
+	gst_element_set_state (fsink, GST_STATE_NULL);
+}
+
+static void
+decodebin2_dpad_cb (GstElement *e,
+                    GstPad     *pad,
+                    gboolean    cont,
+                    gpointer    data)
+{
+	MetadataExtractor *extractor = (MetadataExtractor *)data;
+	GstElement        *fsink;
+	GstPad            *fsinkpad;
+	GValue             val = { 0, };
+
+	fsink = gst_element_factory_make ("fakesink", NULL);
+
+	/* We increase the preroll buffer so we get duration (one frame not enough)*/
+	g_value_init (&val, G_TYPE_INT);
+	g_value_set_int (&val, 51);
+	g_object_set_property (G_OBJECT (fsink), "preroll-queue-len", &val);
+	g_value_unset (&val);
+
+	extractor->fsinks = g_list_append (extractor->fsinks, fsink);
+	gst_element_set_state (fsink, GST_STATE_PAUSED);
+
+	gst_bin_add (GST_BIN (extractor->pipeline), fsink);
+	fsinkpad = gst_element_get_static_pad (fsink, "sink");
+	gst_pad_link (pad, fsinkpad);
+	gst_object_unref (fsinkpad);
+}
+
+static guint64
+decodebin2_get_media_duration (MetadataExtractor *extractor)
+{
+	gint64    duration;
+	GstFormat fmt;
+
+	g_return_val_if_fail (extractor, -1);
+	g_return_val_if_fail (extractor->pipeline, -1);
+
+	fmt = GST_FORMAT_TIME;
+
+	duration = -1;
+
+	if (gst_element_query_duration (extractor->pipeline,
+	                                &fmt,
+	                                &duration) &&
+	    duration >= 0) {
+		return duration / GST_SECOND;
+	} else {
+		return -1;
+	}
+}
+
+static void
+decodebin2_add_stream_tag (void *obj, void *data)
+{
+	MetadataExtractor *extractor = (MetadataExtractor *)data;
+	GstElement        *fsink     = (GstElement *) obj;
+
+	GstStructure      *s         = NULL;
+	GstCaps           *caps      = NULL;
+
+	if ((caps = GST_PAD_CAPS (fsink))) {
+		s = gst_caps_get_structure (caps, 0);
+
+		if (s) {
+			if (g_strrstr (gst_structure_get_name (s), "audio")) {
+				if ( ( (extractor->audio_channels != -1) &&
+				       (extractor->audio_samplerate != -1) ) ||
+				     !( (gst_structure_get_int (s,
+				                                "channels",
+				                                &extractor->audio_channels) ) &&
+				        (gst_structure_get_int (s,
+				                                "rate",
+				                                &extractor->audio_samplerate)) ) ) {
+					return;
+				}
+			} else if (g_strrstr (gst_structure_get_name (s), "video")) {
+				if ( ( (extractor->video_fps_n != -1) &&
+				       (extractor->video_fps_d != -1) &&
+				       (extractor->video_width != -1) &&
+				       (extractor->video_height != -1) ) ||
+				     !( (gst_structure_get_fraction (s,
+				                                     "framerate",
+				                                     &extractor->video_fps_n,
+				                                     &extractor->video_fps_d) ) &&
+				        (gst_structure_get_int (s, "width", &extractor->video_width)) &&
+				        (gst_structure_get_int (s, "height", &extractor->video_height)) &&
+				        (gst_structure_get_int (s, "pixel-aspect-ratio", &extractor->aspect_ratio)))) {
+					return;
+				}
+			}
+		}
+	}
+}
+
+static void
+decodebin2_add_stream_tags (MetadataExtractor *extractor)
+{
+	extractor->duration = decodebin2_get_media_duration (extractor);
+	g_list_foreach (extractor->fsinks, decodebin2_add_stream_tag, extractor);
+}
 
+static GstElement *
+decodebin2_create_pipeline (MetadataExtractor *extractor,
+                            const gchar       *uri)
+{
+	GstElement *pipeline = NULL;
 	GstElement *filesrc  = NULL;
 	GstElement *bin      = NULL;
 
@@ -1186,7 +1131,7 @@ create_decodebin_pipeline (MetadataExtractor *extractor,
 
 	g_signal_connect (G_OBJECT (bin),
 	                  "new-decoded-pad",
-	                  G_CALLBACK (dbin_dpad_cb),
+	                  G_CALLBACK (decodebin2_dpad_cb),
 	                  extractor);
 
 	gst_bin_add (GST_BIN (pipeline), filesrc);
@@ -1205,9 +1150,148 @@ create_decodebin_pipeline (MetadataExtractor *extractor,
 	return pipeline;
 }
 
+static gboolean
+decodebin2_setup_and_run (MetadataExtractor *extractor,
+                          const gchar       *uri)
+{
+	extractor->bus = NULL;
+	extractor->bin = NULL;
+	extractor->fsinks = NULL;
+	extractor->duration = -1;
+
+	extractor->pipeline = decodebin2_create_pipeline (extractor, uri);
+	if (!extractor->pipeline) {
+		g_warning ("No valid pipeline for uri %s", uri);
+
+		g_list_free (extractor->fsinks);
+		g_slice_free (MetadataExtractor, extractor);
+		return FALSE;
+	}
+
+	/* Get bus */
+	extractor->bus = gst_pipeline_get_bus (GST_PIPELINE (extractor->pipeline));
+
+	/* Run! */
+	if (!pipeline_poll_for_ready (extractor, GST_STATE_PAUSED, TRUE, FALSE)) {
+		g_warning ("Error running decodebin");
+		gst_element_set_state (extractor->pipeline, GST_STATE_NULL);
+		gst_object_unref (GST_OBJECT (extractor->pipeline));
+		gst_object_unref (extractor->bus);
+		g_slice_free (MetadataExtractor, extractor);
+		return FALSE;
+	}
+
+	decodebin2_add_stream_tags (extractor);
+
+	gst_element_set_state (extractor->pipeline, GST_STATE_READY);
+	gst_element_get_state (extractor->pipeline, NULL, NULL, 5 * GST_SECOND);
+	g_list_foreach (extractor->fsinks, decodebin2_unlink_fsink, extractor);
+	g_list_free (extractor->fsinks);
+	extractor->fsinks = NULL;
+
+	return TRUE;
+}
+
+#endif /* defined(GSTREAMER_BACKEND_DECODEBIN2) */
+
+
+/* ----------------------- Tagreadbin specific implementation --------------- */
+
+#if defined(GSTREAMER_BACKEND_TAGREADBIN)
+
+static void
+add_int_gst_tag (TrackerSparqlBuilder  *metadata,
+                 const gchar           *uri,
+                 const gchar           *key,
+                 GstTagList            *tag_list,
+                 const gchar           *tag)
+{
+	gboolean ret;
+	gint     n;
+
+	ret = gst_tag_list_get_int (tag_list, tag, &n);
+
+	if (ret) {
+		tracker_sparql_builder_predicate (metadata, key);
+		tracker_sparql_builder_object_int64 (metadata, n);
+	}
+}
+
+static void
+add_fraction_gst_tag (TrackerSparqlBuilder  *metadata,
+                      const gchar           *uri,
+                      const gchar           *key,
+                      GstTagList            *tag_list,
+                      const gchar           *tag)
+{
+	gboolean ret;
+	GValue   n = {0,};
+	gfloat   f;
+
+	ret = gst_tag_list_copy_value (&n, tag_list, tag);
+
+	if (ret) {
+		f = (gfloat)gst_value_get_fraction_numerator (&n)/
+		gst_value_get_fraction_denominator (&n);
+
+		tracker_sparql_builder_predicate (metadata, key);
+		tracker_sparql_builder_object_double (metadata, (gdouble) f);
+
+		g_value_unset (&n);
+	}
+}
+
+static void
+add_time_gst_tag (TrackerSparqlBuilder *metadata,
+                  const gchar          *uri,
+                  const gchar          *key,
+                  GstTagList           *tag_list,
+                  const gchar          *tag)
+{
+	gboolean ret;
+	guint64          n;
+
+	ret = gst_tag_list_get_uint64 (tag_list, tag, &n);
+
+	if (ret) {
+		gint64 duration;
+
+		duration = (n + (GST_SECOND / 2)) / GST_SECOND;
+
+		tracker_sparql_builder_predicate (metadata, key);
+		tracker_sparql_builder_object_int64 (metadata, duration);
+	}
+}
+
+static void
+tagreadbin_extract_stream_metadata (MetadataExtractor    *extractor,
+                                    const gchar          *uri,
+                                    TrackerSparqlBuilder *metadata)
+{
+	if (extractor->mime != EXTRACT_MIME_IMAGE &&
+	    extractor->mime != EXTRACT_MIME_SVG) {
+		add_int_gst_tag (metadata, uri, "nfo:channels", extractor->tagcache, GST_TAG_CHANNEL);
+		add_int_gst_tag (metadata, uri, "nfo:sampleRate", extractor->tagcache, GST_TAG_RATE);
+		add_time_gst_tag (metadata, uri, "nfo:duration", extractor->tagcache, GST_TAG_DURATION);
+	}
+
+	if (extractor->mime == EXTRACT_MIME_IMAGE ||
+	    extractor->mime == EXTRACT_MIME_SVG ||
+	    extractor->mime == EXTRACT_MIME_VIDEO) {
+		add_fraction_gst_tag (metadata, uri, "nfo:aspectRatio", extractor->tagcache, GST_TAG_PIXEL_RATIO);
+	}
+
+	add_int_gst_tag (metadata, uri, "nfo:height", extractor->tagcache, GST_TAG_HEIGHT);
+	add_int_gst_tag (metadata, uri, "nfo:width", extractor->tagcache, GST_TAG_WIDTH);
+
+	if (extractor->mime == EXTRACT_MIME_VIDEO) {
+		add_fraction_gst_tag (metadata, uri, "nfo:frameRate", extractor->tagcache, GST_TAG_FRAMERATE);
+	}
+}
+
 static GstElement *
-create_tagreadbin_pipeline (MetadataExtractor *extractor,
-                            const gchar *uri)
+tagreadbin_create_pipeline (MetadataExtractor *extractor,
+                            const gchar       *uri)
 {
 	GstElement *pipeline = NULL;
 
@@ -1221,12 +1305,44 @@ create_tagreadbin_pipeline (MetadataExtractor *extractor,
 	return pipeline;
 }
 
+static gboolean
+tagreadbin_setup_and_run (MetadataExtractor *extractor,
+                          const gchar       *uri)
+{
+	extractor->bus = NULL;
+
+	/* Create pipeline */
+	extractor->pipeline = tagreadbin_create_pipeline (extractor, uri);
+	if (!extractor->pipeline) {
+		g_warning ("No valid pipeline for uri %s", uri);
+
+		g_slice_free (MetadataExtractor, extractor);
+		return FALSE;
+	}
+
+	/* Get bus */
+	extractor->bus = gst_pipeline_get_bus (GST_PIPELINE (extractor->pipeline));
+
+	/* Run */
+	if (!pipeline_poll_for_ready (extractor, GST_STATE_PLAYING, FALSE, TRUE)) {
+		g_warning ("Error running tagreadbin");
+		gst_element_set_state (extractor->pipeline, GST_STATE_NULL);
+		gst_object_unref (GST_OBJECT (extractor->pipeline));
+		gst_object_unref (extractor->bus);
+		g_slice_free (MetadataExtractor, extractor);
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+#endif /* defined(GSTREAMER_BACKEND_TAGREADBIN) */
 
 static void
-tracker_extract_gstreamer (const gchar *uri,
-                           TrackerSparqlBuilder  *preupdate,
-                           TrackerSparqlBuilder  *metadata,
-                           ExtractMime  type)
+tracker_extract_gstreamer (const gchar          *uri,
+                           TrackerSparqlBuilder *preupdate,
+                           TrackerSparqlBuilder *metadata,
+                           ExtractMime           type)
 {
 	MetadataExtractor *extractor;
 	gchar *artist, *album, *scount;
@@ -1240,9 +1356,6 @@ tracker_extract_gstreamer (const gchar *uri,
 	gst_init (NULL, NULL);
 
 	extractor               = g_slice_new0 (MetadataExtractor);
-
-	extractor->pipeline     = NULL;
-	extractor->bus          = NULL;
 	extractor->mime         = type;
 
 	extractor->tagcache     = NULL;
@@ -1251,58 +1364,21 @@ tracker_extract_gstreamer (const gchar *uri,
 	extractor->album_art_size = 0;
 	extractor->album_art_mime = NULL;
 
-	extractor->bin          = NULL;
-	extractor->fsinks       = NULL;
-
-	extractor->duration = -1;
 	extractor->video_fps_n = extractor->video_fps_d = -1;
 	extractor->video_height = extractor->video_width = -1;
 	extractor->audio_channels = -1;
 	extractor->aspect_ratio = -1;
 	extractor->audio_samplerate = -1;
 
-	if (use_tagreadbin) {
-		extractor->pipeline = create_tagreadbin_pipeline (extractor, uri);
-	} else {
-		extractor->pipeline = create_decodebin_pipeline (extractor, uri);
-	}
-
-	if (!extractor->pipeline) {
-		g_warning ("No valid pipeline for uri %s", uri);
-
-		g_list_free (extractor->fsinks);
-		g_slice_free (MetadataExtractor, extractor);
+#if defined(GSTREAMER_BACKEND_TAGREADBIN)
+	if (!tagreadbin_setup_and_run (extractor, uri))
 		return;
-	}
-
-	extractor->bus = gst_pipeline_get_bus (GST_PIPELINE (extractor->pipeline));
-
-	if (use_tagreadbin) {
-		if (!poll_for_ready (extractor, GST_STATE_PLAYING, FALSE, TRUE)) {
-			g_warning ("Error running tagreadbin");
-			gst_element_set_state (extractor->pipeline, GST_STATE_NULL);
-			gst_object_unref (GST_OBJECT (extractor->pipeline));
-			gst_object_unref (extractor->bus);
-			g_slice_free (MetadataExtractor, extractor);
-			return;
-		}
-	} else {
-		if (!poll_for_ready (extractor, GST_STATE_PAUSED, TRUE, FALSE)) {
-			g_warning ("Error running decodebin");
-			gst_element_set_state (extractor->pipeline, GST_STATE_NULL);
-			gst_object_unref (GST_OBJECT (extractor->pipeline));
-			gst_object_unref (extractor->bus);
-			g_slice_free (MetadataExtractor, extractor);
-			return;
-		}
-
-		add_stream_tags (extractor);
-		gst_element_set_state (extractor->pipeline, GST_STATE_READY);
-		gst_element_get_state (extractor->pipeline, NULL, NULL, 5 * GST_SECOND);
-		g_list_foreach (extractor->fsinks, unlink_fsink, extractor);
-		g_list_free (extractor->fsinks);
-		extractor->fsinks = NULL;
-	}
+#elif defined(GSTREAMER_BACKEND_DECODEBIN2)
+	if (!decodebin2_setup_and_run (extractor, uri))
+		return;
+#else /* defined(GSTREAMER_BACKEND_DISCOVERER) */
+	#warning TODO
+#endif
 
 	album = NULL;
 	scount = NULL;
@@ -1321,24 +1397,23 @@ tracker_extract_gstreamer (const gchar *uri,
 	g_free (album);
 	g_free (artist);
 
-	gst_element_set_state (extractor->pipeline, GST_STATE_NULL);
-	gst_element_get_state (extractor->pipeline, NULL, NULL, TRACKER_EXTRACT_GUARD_TIMEOUT* GST_SECOND);
-	gst_object_unref (extractor->bus);
-
 	if (extractor->tagcache) {
 		gst_tag_list_free (extractor->tagcache);
 	}
 
-	gst_object_unref (GST_OBJECT (extractor->pipeline));
+#if defined(GSTREAMER_BACKEND_TAGREADBIN) || defined(GSTREAMER_BACKEND_DECODEBIN2)
+	pipeline_shutdown (extractor);
+#endif
+
 	g_slice_free (MetadataExtractor, extractor);
 }
 
 G_MODULE_EXPORT gboolean
 tracker_extract_get_metadata (const gchar          *uri,
-			      const gchar          *mimetype,
-			      TrackerSparqlBuilder *preupdate,
-			      TrackerSparqlBuilder *metadata,
-			      GString              *where)
+                              const gchar          *mimetype,
+                              TrackerSparqlBuilder *preupdate,
+                              TrackerSparqlBuilder *metadata,
+                              GString              *where)
 {
 	if (strcmp (mimetype, "image/svg+xml") == 0) {
 		tracker_extract_gstreamer (uri, preupdate, metadata, EXTRACT_MIME_SVG);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]