[tracker] Ported tagreadbin based GStreamer extractor from tracker-0.6



commit e490717008a26ad4e96828981b968dc84445e891
Author: Philip Van Hoof <philip codeminded be>
Date:   Fri Jun 5 16:10:08 2009 +0200

    Ported tagreadbin based GStreamer extractor from tracker-0.6
---
 configure.ac                                    |   17 +-
 src/libtracker-common/tracker-statement-list.c  |   14 +
 src/libtracker-common/tracker-statement-list.h  |    5 +-
 src/tracker-extract/tracker-extract-gstreamer.c | 1022 +++++++++++------------
 4 files changed, 522 insertions(+), 536 deletions(-)

diff --git a/configure.ac b/configure.ac
index cbc05e9..5f4901c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -340,6 +340,21 @@ fi
 
 AM_CONDITIONAL(HAVE_UNIT_TESTS, test "x$have_unit_tests" = "xyes")
 
+####################################################################
+# Use tagreadbin in gstreamer extraction?
+####################################################################
+
+AC_ARG_ENABLE(gstreamer-tagreadbin,
+             AS_HELP_STRING([--enable-gstreamer-tagreadbin],
+                            [enable tagreadbin in gstreamer [[default=no]]]),
+                            [enable_tagreadbin=yes],
+                            [enable_tagreadbin=no])
+
+if test "x$enable_tagreadbin" != "xno"; then
+  AC_DEFINE(TRACKER_EXTRACT_GSTREAMER_USE_TAGREADBIN, 1, [Use tagreadbin in gstreamer extraction])
+fi
+
+
 ##################################################################
 # Check for HAL
 ##################################################################
@@ -1436,7 +1451,7 @@ Metadata Extractors:
 	Support MS & Open Office:	        $have_libgsf
 	Support XML / HTML:		        $have_libxml2
 	Support embedded / sidecar XMP:		$have_exempi
-	Support video formats:			$have_video_handler ($have_video_handler_app)
+	Support video formats:			$have_video_handler ($have_video_handler_app) (tagreadbin: $enable_tagreadbin)
 	Support helix formats (RPM/RM/etc):     $have_gstreamer_helix
 	Support MP3 album art (w/ GdkPixbuf):	$have_gdkpixbuf
 	Support playlists (w/ Totem):           $have_playlist
diff --git a/src/libtracker-common/tracker-statement-list.c b/src/libtracker-common/tracker-statement-list.c
index 7b7ce30..77f3f0b 100644
--- a/src/libtracker-common/tracker-statement-list.c
+++ b/src/libtracker-common/tracker-statement-list.c
@@ -114,6 +114,20 @@ tracker_statement_list_insert_with_double  (GPtrArray   *statements,
 	g_free (value_str);
 }
 
+
+void
+tracker_statement_list_insert_with_float  (GPtrArray   *statements,
+                                       const gchar *subject,
+                                       const gchar *predicate,
+                                       gfloat      value)
+{
+	gchar *value_str;
+
+	value_str = g_strdup_printf ("%f", value);
+	tracker_statement_list_insert (statements, subject, predicate, value_str);
+	g_free (value_str);
+}
+
 void
 tracker_statement_list_insert_with_int (GPtrArray   *statements,
                                    const gchar *subject,
diff --git a/src/libtracker-common/tracker-statement-list.h b/src/libtracker-common/tracker-statement-list.h
index a3fa4ff..6a18a33 100644
--- a/src/libtracker-common/tracker-statement-list.h
+++ b/src/libtracker-common/tracker-statement-list.h
@@ -43,12 +43,15 @@ void   tracker_statement_list_insert_with_double (GPtrArray   *statements,
                                              const gchar *subject,
                                              const gchar *predicate,
                                              gdouble      value);
+void   tracker_statement_list_insert_with_float  (GPtrArray   *statements,
+                                             const gchar *subject,
+                                             const gchar *predicate,
+                                             gfloat      value);
 const gchar* tracker_statement_list_find         (GPtrArray *statements, 
                                              const gchar *subj, 
                                              const gchar *pred);
 
 
-
 G_END_DECLS
 
 #endif /* __TRACKER_ESCAPE_H__ */
diff --git a/src/tracker-extract/tracker-extract-gstreamer.c b/src/tracker-extract/tracker-extract-gstreamer.c
index 4e7963c..5ba0a53 100644
--- a/src/tracker-extract/tracker-extract-gstreamer.c
+++ b/src/tracker-extract/tracker-extract-gstreamer.c
@@ -25,6 +25,7 @@
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <math.h>
 
 #include <glib.h>
 #include <glib/gstdio.h>
@@ -33,7 +34,7 @@
 #include <gst/tag/tag.h>
 
 #include <libtracker-common/tracker-type-utils.h>
-#include <libtracker-common/tracker-statement-list.h>
+#include <libtracker-common/tracker-file-utils.h>
 #include <libtracker-common/tracker-ontology.h>
 #include <libtracker-common/tracker-utils.h>
 
@@ -53,10 +54,34 @@
 #define NIE_PREFIX TRACKER_NIE_PREFIX
 #define DC_PREFIX TRACKER_DC_PREFIX
 #define NCO_PREFIX TRACKER_NCO_PREFIX
-
 #define RDF_PREFIX TRACKER_RDF_PREFIX
 #define RDF_TYPE RDF_PREFIX "type"
 
+/* Some additional tagreadbin tags (FIXME until they are defined upstream)*/
+#ifndef GST_TAG_CHANNEL
+#define GST_TAG_CHANNEL "channels"
+#endif
+
+#ifndef GST_TAG_RATE
+#define GST_TAG_RATE "rate"
+#endif
+
+#ifndef GST_TAG_WIDTH
+#define GST_TAG_WIDTH "width"
+#endif
+
+#ifndef GST_TAG_HEIGHT
+#define GST_TAG_HEIGHT "height"
+#endif
+
+#ifndef GST_TAG_PIXEL_RATIO
+#define GST_TAG_PIXEL_RATIO "pixel-aspect-ratio"
+#endif
+
+#ifndef GST_TAG_FRAMERATE
+#define GST_TAG_FRAMERATE "framerate"
+#endif
+
 typedef enum {
 	EXTRACT_MIME_UNDEFINED,
 	EXTRACT_MIME_AUDIO,
@@ -65,27 +90,17 @@ typedef enum {
 } ExtractMime;
 
 typedef struct {
-	/* Pipeline elements */
-	GMainLoop      *loop;
-
-	GstElement     *bin;
-	GstElement     *filesrc;
-	GstElement     *cache;
+	/* Common pipeline elements */
 	GstElement     *pipeline;
 
 	GstBus         *bus;
-	guint           id;
-
-	GList          *fsinks;
 
 	ExtractMime	mime;
 
 
-	/* Tags and data */
-	GstTagList     *tagcache;
-
-	GstTagList     *audiotags;
-	GstTagList     *videotags;
+	/* Decodebin elements and properties*/
+	GstElement     *bin;	
+	GList          *fsinks;
 
 	gint64          duration;
 	gint		video_height;
@@ -95,31 +110,37 @@ typedef struct {
 	gint		audio_channels;
 	gint		audio_samplerate;
 
+	/* Tags and data */
+	GstTagList     *tagcache;
+
 	unsigned char  *album_art_data;
 	guint           album_art_size;
 	const gchar    *album_art_mime;
 
 } MetadataExtractor;
 
-/* FIXME Make these definable/dynamic at some point */
-const guint use_dbin  = 1;
-const guint use_cache = 0;
-
 static void extract_gstreamer_audio (const gchar *uri, GPtrArray *metadata);
 static void extract_gstreamer_video (const gchar *uri, GPtrArray *metadata);
 static void extract_gstreamer_image (const gchar *uri, GPtrArray *metadata);
 
-static TrackerExtractData gstreamer_data[] = {
+static TrackerExtractData data[] = {
 	{ "audio/*", extract_gstreamer_audio },
 	{ "video/*", extract_gstreamer_video },
 	{ "image/*", extract_gstreamer_image },
 	{ NULL, NULL }
 };
 
+/* 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;
+#endif
+
 static void
 add_int64_info (GPtrArray *metadata,
 		const gchar *uri,
-		const gchar	   *key,
+		const gchar *key,
 		gint64	    info)
 {
 	tracker_statement_list_insert_with_int64 (metadata, uri, key, info);
@@ -128,7 +149,7 @@ add_int64_info (GPtrArray *metadata,
 static void
 add_uint_info (GPtrArray *metadata,
 	       const gchar *uri,
-	       const gchar	  *key,
+	       const gchar *key,
 	       guint	   info)
 {
 	tracker_statement_list_insert_with_int (metadata, uri, key, info);
@@ -157,8 +178,8 @@ add_string_gst_tag (GPtrArray	*metadata,
 }
 
 static void
-add_uint_gst_tag (GPtrArray  *metadata,
-		const gchar *uri,
+add_uint_gst_tag (GPtrArray   *metadata,
+		  const gchar *uri,
 		  const gchar *key,
 		  GstTagList  *tag_list,
 		  const gchar *tag)
@@ -174,8 +195,25 @@ add_uint_gst_tag (GPtrArray  *metadata,
 }
 
 static void
+add_int_gst_tag (GPtrArray   *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_statement_list_insert_with_int (metadata, uri, key, n);	
+	}
+}
+
+static void
 add_double_gst_tag (GPtrArray	*metadata,
-		const gchar *uri,
+		    const gchar *uri,
 		    const gchar *key,
 		    GstTagList	*tag_list,
 		    const gchar *tag)
@@ -191,11 +229,32 @@ add_double_gst_tag (GPtrArray	*metadata,
 }
 
 static void
+add_fraction_gst_tag (GPtrArray         *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);
+
+	f = (gfloat)gst_value_get_fraction_numerator (&n)/
+		gst_value_get_fraction_denominator (&n);
+
+	if (ret) {
+		tracker_statement_list_insert_with_float (metadata, uri, key, f);
+	}
+}
+
+static void
 add_y_date_gst_tag (GPtrArray  *metadata,
-		const gchar *uri,
-			   const gchar *key,
-			   GstTagList  *tag_list,
-			   const gchar *tag)
+		    const gchar *uri,
+		    const gchar *key,
+		    GstTagList  *tag_list,
+		    const gchar *tag)
 {
 	GDate	 *date;
 	gboolean  ret;
@@ -208,7 +267,7 @@ add_y_date_gst_tag (GPtrArray  *metadata,
 
 		if (g_date_strftime (buf, 10, "%Y", date)) {
 			tracker_statement_list_insert (metadata, uri,
-						  key, buf);
+						       key, buf);
 		}
 	}
 
@@ -217,30 +276,26 @@ add_y_date_gst_tag (GPtrArray  *metadata,
 	}
 }
 
-static gint64
-get_media_duration (MetadataExtractor *extractor)
+static void
+add_time_gst_tag (GPtrArray   *metadata,
+		  const gchar *uri,
+		  const gchar *key,
+		  GstTagList  *tag_list,
+		  const gchar *tag)
 {
-	gint64	  duration;
-	GstFormat fmt;
-
-	g_return_val_if_fail (extractor, -1);
-	g_return_val_if_fail (extractor->pipeline, -1);
+	gboolean ret;
+	guint64	 n;
 
-	fmt = GST_FORMAT_TIME;
+	ret = gst_tag_list_get_uint64 (tag_list, tag, &n);
 
-	duration = -1;
-	
-	if (gst_element_query_duration (extractor->pipeline,
-					&fmt,
-					&duration) &&
-	    duration >= 0) {
-		return duration / GST_SECOND;
-	} else {
-		return -1;
+	if (ret) {
+		gchar *str = g_strdup_printf ("%lld", llroundl ((long double)n/(long double)GST_SECOND));
+		tracker_statement_list_insert (metadata, uri, key, str);
+		g_free (str);
 	}
 }
 
-static void
+static gboolean
 get_embedded_album_art(MetadataExtractor *extractor)
 {
 	const GValue *value;
@@ -271,8 +326,8 @@ get_embedded_album_art(MetadataExtractor *extractor)
 				extractor->album_art_data = buffer->data;
 				extractor->album_art_size = buffer->size;
 				extractor->album_art_mime = gst_structure_get_name (caps_struct);
-				g_debug ("Mime was %s", extractor->album_art_mime);
-				return;
+				gst_object_unref (caps);
+				return TRUE;
 			}
 
 			gst_object_unref (caps);
@@ -280,30 +335,135 @@ get_embedded_album_art(MetadataExtractor *extractor)
 			lindex++;
 		}
 	} while (value);
+
+	value = gst_tag_list_get_value_index (extractor->tagcache, GST_TAG_PREVIEW_IMAGE, lindex);
+
+	if (value) {
+		GstBuffer    *buffer;
+		GstCaps      *caps;
+		GstStructure *caps_struct;
+
+		buffer = gst_value_get_buffer (value);
+		caps   = gst_buffer_get_caps (buffer);
+		caps_struct = gst_caps_get_structure (buffer->caps, 0);
+
+		extractor->album_art_data = buffer->data;
+		extractor->album_art_size = buffer->size;
+		extractor->album_art_mime = gst_structure_get_name (caps_struct);		
+
+		gst_object_unref (caps);
+
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+static void
+extract_stream_metadata_tagreadbin (MetadataExtractor *extractor,
+				    const gchar       *uri,
+				    GPtrArray         *metadata)
+{
+
+	add_uint_gst_tag (metadata, uri, NFO_PREFIX "channels", extractor->tagcache, GST_TAG_CHANNEL);
+	add_uint_gst_tag (metadata, uri, NFO_PREFIX "sampleRate", extractor->tagcache, GST_TAG_RATE);
+
+	add_int_gst_tag (metadata, uri, NFO_PREFIX "height", extractor->tagcache, GST_TAG_HEIGHT);
+	add_int_gst_tag (metadata, uri, NFO_PREFIX "width", extractor->tagcache, GST_TAG_WIDTH);
+	add_time_gst_tag (metadata, uri, NFO_PREFIX "duration", extractor->tagcache, GST_TAG_DURATION); 
+
+	if (extractor->mime == EXTRACT_MIME_VIDEO) {
+		add_fraction_gst_tag   (metadata, uri, NFO_PREFIX "frameRate", extractor->tagcache, GST_TAG_FRAMERATE);	
+	}
+}
+
+static void
+extract_stream_metadata_decodebin (MetadataExtractor *extractor,
+				   const gchar       *uri,
+				   GPtrArray         *metadata)
+{
+	if (extractor->audio_channels >= 0) {
+		add_uint_info (metadata,
+			       uri, NFO_PREFIX "channels",
+			       extractor->audio_channels);
+	}
+
+	if (extractor->audio_samplerate >= 0) {
+		add_uint_info (metadata,
+			       uri, NFO_PREFIX "sampleRate",
+			       extractor->audio_samplerate);
+	}
+
+	if (extractor->video_height >= 0) {
+		add_uint_info (metadata,
+			       uri, NFO_PREFIX "height",
+			       extractor->video_height);
+	}
+
+	if (extractor->video_width >= 0) {
+		add_uint_info (metadata,
+			       uri, NFO_PREFIX "width",
+			       extractor->video_width);
+	}
+
+	if (extractor->duration >= 0) {
+		add_int64_info (metadata, uri, NFO_PREFIX "duration", extractor->duration);
+	}
+
+	if (extractor->mime == EXTRACT_MIME_VIDEO) {
+		if (extractor->video_fps_n >= 0 && extractor->video_fps_d >= 0) {
+			add_uint_info (metadata,
+				       uri, NFO_PREFIX "frameRate",
+				       ((extractor->video_fps_n + extractor->video_fps_d / 2) / 
+					extractor->video_fps_d));
+		}
+	}
 }
 
 static void
 extract_metadata (MetadataExtractor *extractor,
 		  const gchar       *uri,
 		  GPtrArray         *metadata,
-		  gchar            **artist,
-		  gchar            **album,
-		  gchar            **scount)
+		  gchar **album, gchar **scount)
 {
-	gchar *s = NULL;
-	gint   n;
+	gchar *s;
+	gboolean ret;
+	gint count;
 
-	g_return_if_fail (extractor);
-	g_return_if_fail (metadata);
+	g_return_if_fail (extractor != NULL);
+	g_return_if_fail (metadata != NULL);
 
 	if (extractor->tagcache) {
 		/* General */
+
+		add_string_gst_tag (metadata, uri, NIE_PREFIX "title", extractor->tagcache, GST_TAG_TITLE);
 		add_string_gst_tag (metadata, uri, NIE_PREFIX "copyright", extractor->tagcache, GST_TAG_COPYRIGHT);
 		add_string_gst_tag (metadata, uri, NIE_PREFIX "license", extractor->tagcache, GST_TAG_LICENSE);
+
 		add_string_gst_tag (metadata, uri, DC_PREFIX "coverage", extractor->tagcache, GST_TAG_LOCATION);
 
 		/* Audio */
 		s = NULL;
+		gst_tag_list_get_string (extractor->tagcache, GST_TAG_ALBUM, &s);
+		if (s) {
+			gchar *canonical_uri = tracker_uri_printf_escaped ("urn:album:%s", s);
+			tracker_statement_list_insert (metadata, canonical_uri, RDF_TYPE, NMM_PREFIX "MusicAlbum");
+			tracker_statement_list_insert (metadata, canonical_uri, NMM_PREFIX "albumTitle", s);
+			tracker_statement_list_insert (metadata, uri, NMM_PREFIX "musicAlbum", canonical_uri);
+			g_free (canonical_uri);
+			*album = s;
+		}
+
+		ret = gst_tag_list_get_uint (extractor->tagcache, GST_TAG_TRACK_COUNT, &count);
+		if (ret) {
+			*scount = g_strdup_printf ("%d", count);
+		}
+
+		add_uint_gst_tag   (metadata, uri, NMM_PREFIX "albumTrackCount", extractor->tagcache, GST_TAG_TRACK_COUNT);
+		add_uint_gst_tag   (metadata, uri, NMM_PREFIX "trackNumber", extractor->tagcache, GST_TAG_TRACK_NUMBER);
+		add_uint_gst_tag   (metadata, uri, NMM_PREFIX "setNumber", extractor->tagcache, GST_TAG_ALBUM_VOLUME_NUMBER);
+
+		s = NULL;
 		gst_tag_list_get_string (extractor->tagcache, GST_TAG_PERFORMER, &s);
 		if (s) {
 			gchar *canonical_uri = tracker_uri_printf_escaped ("urn:artist:%s", s);
@@ -313,185 +473,58 @@ extract_metadata (MetadataExtractor *extractor,
 			g_free (canonical_uri);
 			g_free (s);
 		}
-	
-		add_double_gst_tag (metadata, uri, NFO_PREFIX "gain", extractor->tagcache, GST_TAG_TRACK_GAIN);
 
+		/* Warn, same predicate as above. Is this an err in our onto? */
+		s = NULL;
+		gst_tag_list_get_string (extractor->tagcache, GST_TAG_ARTIST, &s);
+		if (s) {
+			gchar *canonical_uri = tracker_uri_printf_escaped ("urn:artist:%s", s);
+			tracker_statement_list_insert (metadata, canonical_uri, RDF_TYPE, NMM_PREFIX "Artist");
+			tracker_statement_list_insert (metadata, canonical_uri, NMM_PREFIX "artistName", s);
+			tracker_statement_list_insert (metadata, uri, NMM_PREFIX "performer", canonical_uri);
+			g_free (canonical_uri);
+			g_free (s);
+		}
+
+		add_double_gst_tag (metadata, uri, NFO_PREFIX "gain", extractor->tagcache, GST_TAG_TRACK_GAIN);
 		add_double_gst_tag (metadata, uri, NFO_PREFIX "peakGain", extractor->tagcache, GST_TAG_TRACK_PEAK);
+		add_double_gst_tag (metadata, uri, NFO_PREFIX "albumGain", extractor->tagcache, GST_TAG_ALBUM_GAIN);
+		add_double_gst_tag (metadata, uri, NFO_PREFIX "albumPeakGain", extractor->tagcache, GST_TAG_ALBUM_PEAK);
 
-		add_double_gst_tag (metadata, uri, NMM_PREFIX "albumGain", extractor->tagcache, GST_TAG_ALBUM_GAIN);
-		add_double_gst_tag (metadata, uri, NMM_PREFIX "albumPeakGain", extractor->tagcache, GST_TAG_ALBUM_PEAK);
-		
-		
 		add_y_date_gst_tag (metadata, uri, NIE_PREFIX "contentCreated", extractor->tagcache, GST_TAG_DATE);
-		add_string_gst_tag (metadata, uri, NFO_PREFIX "genre", extractor->tagcache, GST_TAG_GENRE);
-		add_string_gst_tag (metadata, uri, NFO_PREFIX "codec", extractor->tagcache, GST_TAG_AUDIO_CODEC);
-
-		/* Video */
-		add_string_gst_tag (metadata, uri, NFO_PREFIX "codec", extractor->tagcache, GST_TAG_VIDEO_CODEC);
-
-		if (extractor->mime == EXTRACT_MIME_IMAGE) {
-			add_string_gst_tag (metadata, uri, NIE_PREFIX "title", extractor->tagcache, GST_TAG_TITLE);
-			add_string_gst_tag (metadata, uri, NIE_PREFIX "comment", extractor->tagcache, GST_TAG_COMMENT);
-
-			s = NULL;
-			gst_tag_list_get_string (extractor->tagcache, GST_TAG_ARTIST, &s);
-			if (s) {
-				gchar *canonical_uri = tracker_uri_printf_escaped ("urn:contact:%s", s);
-				tracker_statement_list_insert (metadata, canonical_uri, RDF_TYPE, NCO_PREFIX "Contact");
-				tracker_statement_list_insert (metadata, canonical_uri, NCO_PREFIX "fullName", s);
-				tracker_statement_list_insert (metadata, uri, NCO_PREFIX "creator", canonical_uri);
-				g_free (canonical_uri);
-				g_free (s);
-			}
-
-		} else if (extractor->mime == EXTRACT_MIME_VIDEO) {
-			add_string_gst_tag (metadata, uri, NIE_PREFIX "title", extractor->tagcache, GST_TAG_TITLE);
-			add_string_gst_tag (metadata, uri, NIE_PREFIX "comment", extractor->tagcache, GST_TAG_COMMENT);
-
-			s = NULL;
-			gst_tag_list_get_string (extractor->tagcache, GST_TAG_ARTIST, &s);
-			if (s) {
-				gchar *canonical_uri = tracker_uri_printf_escaped ("urn:artist:%s", s);
-				tracker_statement_list_insert (metadata, canonical_uri, RDF_TYPE, NMM_PREFIX "Artist");
-				tracker_statement_list_insert (metadata, canonical_uri, NMM_PREFIX "artistName", s);
-				tracker_statement_list_insert (metadata, uri, NMM_PREFIX "director", canonical_uri);
-				g_free (canonical_uri);
-				g_free (s);
-			}
-			
-			add_string_gst_tag (metadata, uri, DC_PREFIX "source", extractor->tagcache, GST_TAG_CLASSIFICATION);
-		} else if (extractor->mime == EXTRACT_MIME_AUDIO) {
-			add_string_gst_tag (metadata, uri, NIE_PREFIX "title", extractor->tagcache, GST_TAG_TITLE);
-
-			s = NULL;
-			gst_tag_list_get_string (extractor->tagcache, GST_TAG_ALBUM, &s);
-
-			if (s) {
-				gchar *canonical_uri = tracker_uri_printf_escaped ("urn:album:%s", s);
-				tracker_statement_list_insert (metadata, canonical_uri, RDF_TYPE, NMM_PREFIX "MusicAlbum");
-				tracker_statement_list_insert (metadata, canonical_uri, NMM_PREFIX "albumTitle", s);
-				tracker_statement_list_insert (metadata, uri, NMM_PREFIX "musicAlbum", canonical_uri);
-				g_free (canonical_uri);
-				*album = s;
-			}
-			
-			add_uint_gst_tag   (metadata, uri, NMM_PREFIX "albumTrackCount", extractor->tagcache, GST_TAG_TRACK_COUNT);
-			
-			
-			if (gst_tag_list_get_uint (extractor->tagcache, GST_TAG_TRACK_COUNT, &n)) {
-				*scount = g_strdup_printf ("%d", n);
-			}
-			
-			add_uint_gst_tag   (metadata, uri, NMM_PREFIX "trackNumber", extractor->tagcache, GST_TAG_TRACK_NUMBER);
-			
-			add_uint_gst_tag   (metadata, uri, NMM_PREFIX "setNumber", extractor->tagcache, GST_TAG_ALBUM_VOLUME_NUMBER);
-			
-			s = NULL;
-			gst_tag_list_get_string (extractor->tagcache, GST_TAG_ARTIST, &s);
-			if (s) {
-				gchar *canonical_uri = tracker_uri_printf_escaped ("urn:artist:%s", s);
-				tracker_statement_list_insert (metadata, canonical_uri, RDF_TYPE, NMM_PREFIX "Artist");
-				tracker_statement_list_insert (metadata, canonical_uri, NMM_PREFIX "artistName", s);
-				tracker_statement_list_insert (metadata, uri, NMM_PREFIX "performer", canonical_uri);
-				g_free (canonical_uri);
-				g_free (s);
-			}
 
-			s = NULL;
-			if (gst_tag_list_get_string (extractor->tagcache, GST_TAG_ARTIST, &s)) {
-				*artist = s;
-			}
+		s = NULL;
+		gst_tag_list_get_string (extractor->tagcache, GST_TAG_GENRE, &s);
 
-			add_string_gst_tag (metadata, uri, NIE_PREFIX "comment", extractor->tagcache, GST_TAG_COMMENT);
+		if (g_strcmp0 (s, "Unknown") != 0) {
+			tracker_statement_list_insert (metadata, uri, NFO_PREFIX "genre", s);
+			g_free (s);
 		}
- 	}
 
-	if (extractor->audio_channels >= 0) {
-		add_uint_info (metadata, uri,
-			       NFO_PREFIX "channels",
-			       (guint) extractor->audio_channels);
-	}
-
-	if (extractor->audio_samplerate >= 0) {
-		add_uint_info (metadata, uri,
-			       NFO_PREFIX "sampleRate",
-			       (guint) extractor->audio_samplerate);
-	}
+		add_string_gst_tag (metadata, uri, NFO_PREFIX "codec", extractor->tagcache, GST_TAG_AUDIO_CODEC);
 
-	if (extractor->video_height >= 0) {
-		if (extractor->mime == EXTRACT_MIME_IMAGE) {
-			add_uint_info (metadata, uri,
-				       NFO_PREFIX "height",
-				       (guint) extractor->video_height);
-		} else {
-			add_uint_info (metadata, uri,
-				       NFO_PREFIX "height",
-				      (guint)  extractor->video_height);
-		}
-	}
+		add_string_gst_tag (metadata, uri, NIE_PREFIX "comment", extractor->tagcache, GST_TAG_COMMENT);
 
-	if (extractor->video_width >= 0) {
-		if (extractor->mime == EXTRACT_MIME_IMAGE) {
-			add_uint_info (metadata, uri,
-				       NFO_PREFIX "width",
-				       (guint) extractor->video_width);
-		} else {
-			add_uint_info (metadata, uri,
-				       NFO_PREFIX "width",
-				       (guint) extractor->video_width);
+		if (extractor->mime == EXTRACT_MIME_VIDEO) {
+			add_string_gst_tag (metadata, uri, DC_PREFIX "source", extractor->tagcache, GST_TAG_CLASSIFICATION);
 		}
 	}
 
- 	if (extractor->mime == EXTRACT_MIME_VIDEO) {
- 
-		tracker_statement_list_insert (metadata, uri, 
-		                          RDF_TYPE, 
-		                          NMM_PREFIX "Video");
-
-		if (extractor->video_fps_n >= 0 && extractor->video_fps_d >= 0) {
-			add_uint_info (metadata, uri,
-				       NFO_PREFIX "frameRate",
-				       ((extractor->video_fps_n + extractor->video_fps_d / 2) / 
-					extractor->video_fps_d));
-		}
- 		if (extractor->duration >= 0) {
- 			add_int64_info (metadata, uri, NFO_PREFIX "duration", extractor->duration);
- 		}
- 	} else if (extractor->mime == EXTRACT_MIME_AUDIO) {
-
-		tracker_statement_list_insert (metadata, uri, 
-		                          RDF_TYPE, 
-		                          NMM_PREFIX "MusicPiece");
-
- 		if (extractor->duration >= 0) {
- 			add_int64_info (metadata, uri, NMM_PREFIX "length", extractor->duration);
- 		}
-
-		get_embedded_album_art (extractor);
- 	} else if (extractor->mime == EXTRACT_MIME_IMAGE) {
-		tracker_statement_list_insert (metadata, uri, 
-		                          RDF_TYPE, 
-		                          NFO_PREFIX "Image");
+	if (use_tagreadbin) {
+		extract_stream_metadata_tagreadbin (extractor, uri, metadata);
 	} else {
-		tracker_statement_list_insert (metadata, uri, 
-		                          RDF_TYPE, 
-		                          NFO_PREFIX "FileDataObject");
-	}
-
-	if (extractor->audiotags) {
-		add_uint_gst_tag (metadata, uri, NFO_PREFIX "averageBitrate", extractor->audiotags, GST_TAG_BITRATE);
+		extract_stream_metadata_decodebin (extractor, uri, metadata);
 	}
 
-	if (extractor->videotags) {
-		add_uint_gst_tag (metadata, uri, NFO_PREFIX "averageBitrate", extractor->videotags, GST_TAG_BITRATE);
+	if (extractor->mime == EXTRACT_MIME_AUDIO) {
+		get_embedded_album_art (extractor);
 	}
-
 }
 
 static void
-unlink_fsink (void *obj, void *data)
+unlink_fsink (void *obj, void *data_)
 {
-	MetadataExtractor *extractor = (MetadataExtractor *)data;
+	MetadataExtractor *extractor = (MetadataExtractor *)data_;
 	GstElement        *fsink     = (GstElement *) obj;
 
 	gst_element_unlink (extractor->bin, fsink);
@@ -500,24 +533,22 @@ unlink_fsink (void *obj, void *data)
 }
 
 static void
-dbin_dpad_cb (GstElement* e, GstPad* pad, gboolean cont, gpointer data)
+dbin_dpad_cb (GstElement* e, GstPad* pad, gboolean cont, gpointer data_)
 {
-	MetadataExtractor *extractor = (MetadataExtractor *)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, 50);
-
+	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);
@@ -526,104 +557,33 @@ dbin_dpad_cb (GstElement* e, GstPad* pad, gboolean cont, gpointer data)
 	gst_object_unref (fsinkpad);
 }
 
-
-
-static void
-add_stream_tags_tagreadbin_for_element (MetadataExtractor *extractor, GstElement *elem)
+static guint64
+get_media_duration (MetadataExtractor *extractor)
 {
-	GstStructure      *s         = NULL;
-	GstCaps	          *caps      = NULL;
-	GstIterator       *iter      = NULL;
-	gboolean           done      = FALSE;
-	gpointer           item;
-
-	iter = gst_element_iterate_sink_pads (elem);
-
-	while (!done) {
-		switch (gst_iterator_next (iter, &item)) {
-		case GST_ITERATOR_OK:
-			
-			if ((caps = GST_PAD_CAPS (item))) {
-				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)))) {
-							return;
-						}
-					}
-				}
-			}
-			gst_object_unref (item);
-			break;
-		case GST_ITERATOR_RESYNC:
-			gst_iterator_resync (iter);
-			break;
-		case GST_ITERATOR_ERROR:
-		case GST_ITERATOR_DONE:
-			done = TRUE;
-			break;
-		default:
-			break;
-		}
-	}
-	gst_iterator_free (iter);
-}
+	gint64	  duration;
+	GstFormat fmt;
 
-/* FIXME This is a temporary solution while tagreadbin does not support pad signals */
+	g_return_val_if_fail (extractor, -1);
+	g_return_val_if_fail (extractor->pipeline, -1);
 
-static void
-add_stream_tags_tagreadbin (MetadataExtractor *extractor)
-{
-	GstIterator       *iter      = NULL;
-	gboolean           done      = FALSE;
-	gpointer           item;
+	fmt = GST_FORMAT_TIME;
 
-	iter = gst_bin_iterate_elements (GST_BIN(extractor->bin));
+	duration = -1;
 	
-	while (!done) {
-		switch (gst_iterator_next (iter, &item)) {
-		case GST_ITERATOR_OK:
-			add_stream_tags_tagreadbin_for_element (extractor, item);
-			g_object_unref (item);
-			break;
-		case GST_ITERATOR_RESYNC:
-			gst_iterator_resync (iter);
-			break;
-		case GST_ITERATOR_ERROR:
-		case GST_ITERATOR_DONE:
-			done = TRUE;
-			break;
-		}
+	if (gst_element_query_duration (extractor->pipeline,
+					&fmt,
+					&duration) &&
+	    duration >= 0) {
+		return duration / GST_SECOND;
+	} else {
+		return -1;
 	}
-
-	gst_iterator_free (iter);
 }
 
 static void
-add_stream_tag (void *obj, void *data)
+add_stream_tag (void *obj, void *data_)
 {
-	MetadataExtractor *extractor = (MetadataExtractor *)data;
+	MetadataExtractor *extractor = (MetadataExtractor *)data_;
 	GstElement        *fsink     = (GstElement *) obj;
 
 	GstStructure      *s         = NULL;
@@ -666,23 +626,14 @@ static void
 add_stream_tags (MetadataExtractor *extractor)
 {
 	extractor->duration = get_media_duration (extractor);
-
-	if (use_dbin) {
-		g_list_foreach (extractor->fsinks, add_stream_tag, extractor);
-	} else {
-		add_stream_tags_tagreadbin (extractor);
-	}
+	g_list_foreach (extractor->fsinks, add_stream_tag, extractor);
 }
 
 static void
-add_tags (GstMessage *msg, MetadataExtractor *extractor)
+add_tags (GstTagList *new_tags, MetadataExtractor *extractor)
 {
-	GstPad       *pad;
-	GstTagList   *new_tags;
 	GstTagList   *result;
 
-	gst_message_parse_tag (msg, &new_tags);
-
 	result = gst_tag_list_merge (extractor->tagcache,
 				     new_tags,
 				     GST_TAG_MERGE_KEEP);
@@ -692,229 +643,249 @@ add_tags (GstMessage *msg, MetadataExtractor *extractor)
 	}
 
 	extractor->tagcache = result;
+}
 
-	/* media-type-specific tags */
-	if (GST_IS_ELEMENT (msg->src) &&
-	    (pad = gst_element_get_static_pad (GST_ELEMENT (msg->src), "sink"))) {
-		GstTagList  **cache;
-		const GstStructure *s;
-		GstCaps *caps;
 
-		cache = NULL;
-		
-		caps = gst_pad_get_caps (pad);
-		s = gst_caps_get_structure (caps, 0);
+static gboolean
+poll_for_ready (MetadataExtractor *extractor,
+		GstState state,
+		gboolean ready_with_state,
+		gboolean ready_with_eos)
+{
+	gint64              timeout   = 5 * GST_SECOND;
+	GstBus             *bus       = extractor->bus;
+	GstTagList         *new_tags;
+
+	gst_element_set_state (extractor->pipeline, state);
 
-		if (g_strrstr (gst_structure_get_name(s), "audio")) {
-			cache = &extractor->audiotags;
-		} else if (g_strrstr (gst_structure_get_name(s), "video")) {
-			cache = &extractor->videotags;
+	while (TRUE) {
+		GstMessage *message;
+		GstElement *src;
+		
+		message = gst_bus_timed_pop (bus, timeout);
+		
+		if (!message) {
+			g_warning ("Pipeline timed out");
+			return FALSE;
 		}
 		
-		if (cache) {
-			result = gst_tag_list_merge (*cache,
-						     new_tags,
-						     GST_TAG_MERGE_KEEP);
-			if (*cache) {
-				gst_tag_list_free (*cache);
+		src = (GstElement*)GST_MESSAGE_SRC (message);
+		
+		switch (GST_MESSAGE_TYPE (message)) {
+		case GST_MESSAGE_STATE_CHANGED: {
+			if (ready_with_state) {
+				GstState old, new, pending;
+				
+				if (src == extractor->pipeline) {
+					gst_message_parse_state_changed (message, &old, &new, &pending);
+					if (new == state) {
+						gst_message_unref (message);
+						return TRUE;
+					}
+				}
 			}
-			
-			*cache = result;
+			break;
 		}
+		case GST_MESSAGE_ERROR: {
+			GError *lerror = NULL;
+			gchar  *error_message;
+
+			gst_message_parse_error (message, &lerror, &error_message);
+			gst_message_unref (message);
+			g_warning ("Got error :%s", error_message);
+			g_free (error_message);
+			g_error_free (lerror);
 
-		gst_caps_unref (caps);
+			return FALSE;
+			break;
+		}
+		case GST_MESSAGE_EOS: {
+			gst_message_unref (message);
+
+			if (ready_with_eos) {
+				return TRUE;
+			} else {
+				g_warning ("Reached end-of-file without proper content");
+				return FALSE;
+			}
+			break;
+		}
+		case GST_MESSAGE_TAG: {
+			gst_message_parse_tag (message, &new_tags);
+			add_tags (new_tags, extractor);
+			gst_tag_list_free (new_tags);
+			break;
+		}
+		default:
+			/* Nothing to do here */
+			break;
+		}
+		
+		gst_message_unref (message);
 	}
 	
-	gst_tag_list_free (new_tags);
+	g_assert_not_reached ();
+	
+	return FALSE;
 }
 
-static gboolean
-metadata_bus_async_cb (GstBus *bus, GstMessage *msg, gpointer data)
+static GstElement *
+create_decodebin_pipeline (MetadataExtractor *extractor, const gchar *uri)
 {
-	MetadataExtractor *extractor = (MetadataExtractor *)data;
-	GError            *error     = NULL;
-	gboolean           stop      = FALSE;
+	GstElement *pipeline = NULL;
 	
-	switch (GST_MESSAGE_TYPE (msg)) {
-        case GST_MESSAGE_ERROR:
-		gst_message_parse_error (msg, &error, NULL);
-		printf ("ERROR: %s\n", error->message);
-		g_error_free (error);
-		stop = TRUE;
-		break;
-        case GST_MESSAGE_TAG:
-		add_tags (msg, extractor);
-		break;
-        case GST_MESSAGE_EOS:
-		stop = TRUE;
-		break;
-        case GST_MESSAGE_STATE_CHANGED:
-		{
-			GstElement *sender = (GstElement *) GST_MESSAGE_SRC (msg);
-			if (sender == extractor->pipeline) {
-				GstState newstate;
-				GstState oldstate;
-				gst_message_parse_state_changed (msg, &oldstate, &newstate, NULL);
-				if ((oldstate == GST_STATE_READY) && (newstate == GST_STATE_PAUSED)) {
-					stop = TRUE;
-				}
-			}
-		}
-		break;
-	case GST_MESSAGE_DURATION:
-		/* The reasoning here is that if we already got duration we should have also
-		   all the other data we need since getting the duration should take the longest */
-		stop = TRUE;
-		break;
-        default:
-		break;
+	GstElement *filesrc  = NULL;
+	GstElement *bin      = NULL;
+
+	guint       id;
+
+	pipeline = gst_element_factory_make ("pipeline", NULL);
+	if (!pipeline) {
+		g_warning ("Failed to create GStreamer pipeline");
+		return FALSE;
 	}
-	
-	if (stop) {
-		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;
-		g_main_loop_quit (extractor->loop);
+
+	filesrc = gst_element_factory_make ("filesrc", NULL);
+	if (!filesrc) {
+		g_warning ("Failed to create GStreamer filesrc");
+		return FALSE;
 	}
+
+	bin = gst_element_factory_make ("decodebin2", "decodebin2");
+	if (!bin) {
+		g_warning ("Failed to create GStreamer decodebin");
+		return FALSE;
+	}
+
+	id = g_signal_connect (G_OBJECT (bin), 
+			       "new-decoded-pad",
+			       G_CALLBACK (dbin_dpad_cb), 
+			       extractor);
 	
-	return TRUE;
+	gst_bin_add (GST_BIN (pipeline), filesrc);
+	gst_bin_add (GST_BIN (pipeline), bin);
+
+	if (!gst_element_link_many (filesrc, bin, NULL)) {
+		g_warning ("Could not link GStreamer elements");
+		return FALSE;
+	}
+
+	g_object_set (G_OBJECT (filesrc), "location", uri, NULL);
+
+	extractor->bin = bin;
+
+	return pipeline;
 }
 
+static GstElement *
+create_tagreadbin_pipeline (MetadataExtractor *extractor, const gchar *uri)
+{
+	GstElement *pipeline = NULL;
+	gchar      *complete_uri = NULL;
+
+	pipeline = gst_element_factory_make ("tagreadbin", "tagreadbin");
+	if (!pipeline) {
+		g_warning ("Failed to create GStreamer tagreadbin");
+		return NULL;
+	}
+
+	complete_uri = g_filename_to_uri (uri, NULL, NULL);
+	if (!complete_uri) {
+		g_warning ("Failed to convert filename to uri");
+		return NULL;
+	}
+
+	g_object_set (G_OBJECT (pipeline), "uri", complete_uri, NULL);
+	g_free (complete_uri);
+	return pipeline;
+}
+
+
 static void
 tracker_extract_gstreamer (const gchar *uri,
-			   GPtrArray   *metadata,
+			   GPtrArray  *metadata,
 			   ExtractMime	type)
 {
 	MetadataExtractor *extractor;
-	gchar		  *album = NULL, *artist = NULL, *scount = NULL;
-	gchar *path;
-	GFile *file;
+	gchar *album, *scount;
 
 	g_return_if_fail (uri);
 	g_return_if_fail (metadata);
-	
+
+	/* These must be moved to main() */
 	g_type_init ();
 
 	gst_init (NULL, NULL);
 
 	extractor               = g_slice_new0 (MetadataExtractor);
-	extractor->loop         = NULL;
-	extractor->bin          = NULL;
-	extractor->filesrc      = NULL;
-	extractor->cache        = NULL;
-	extractor->pipeline     = NULL;
 
+	extractor->pipeline     = NULL;
 	extractor->bus          = NULL;
-	extractor->id           = 0;
-
-	extractor->fsinks       = NULL;
-
 	extractor->mime         = type;
 
 	extractor->tagcache     = NULL;
 	
-	extractor->audiotags    = NULL;
-	extractor->videotags    = NULL;	
-
 	extractor->album_art_data = NULL;
 	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->audio_samplerate = -1;
-	
-	extractor->pipeline = gst_element_factory_make ("pipeline", NULL);
-	if (!extractor->pipeline) {
-		g_error ("Failed to create pipeline");
-		return;
-	}
-	extractor->filesrc  = gst_element_factory_make ("filesrc",  NULL);
-	if (!extractor->filesrc) {
-		g_error ("Failed to create filesrc");
-		return;
-	}
-	if (use_cache) {
-		extractor->cache    = gst_element_factory_make ("cache",    NULL);
-		if (!extractor->cache) {
-			g_error ("Failed to create cache");
-			return;
-		}
-	}
 
-	if (use_dbin) {
-		extractor->bin = gst_element_factory_make ("decodebin2", "decodebin2");
-		if (!extractor->bin) {
-			g_error ("Failed to create decodebin");
-			return;
-		}
-		extractor->id = g_signal_connect (G_OBJECT (extractor->bin), 
-				       "new-decoded-pad",
-				       G_CALLBACK (dbin_dpad_cb), 
-				       extractor);
+	if (use_tagreadbin) {
+		extractor->pipeline = create_tagreadbin_pipeline (extractor, uri);
 	} else {
-	        extractor->bin = gst_element_factory_make ("tagreadbin", "tagreadbin");
-		if (!extractor->bin) {
-			g_error ("Failed to create tagreadbin");
-			return;
-		}
-		extractor->id = 0;
+		extractor->pipeline = create_decodebin_pipeline (extractor, uri);
 	}
-	
-	gst_bin_add (GST_BIN (extractor->pipeline), extractor->filesrc);
-	gst_bin_add (GST_BIN (extractor->pipeline), extractor->bin);
-
-	if (use_cache) {
-		gst_bin_add (GST_BIN (extractor->pipeline), extractor->cache);
-		if (! gst_element_link_many (extractor->filesrc, extractor->cache, extractor->bin, NULL)) {
-		g_error ("Can't link elements\n");
-		/* FIXME Clean up */
-		return;
-		}
-	} else {
-		if (!gst_element_link_many (extractor->filesrc, extractor->bin, NULL)) {
-			g_error ("Can't link elements\n");
-			/* FIXME Clean up */
-			return;
-		}
+
+	if (!extractor->pipeline) {
+		g_warning ("No valid pipeline for uri %s", uri);
+		goto fail;
 	}
 
-	extractor->loop = g_main_loop_new (NULL, FALSE);
 	extractor->bus = gst_pipeline_get_bus (GST_PIPELINE (extractor->pipeline));
-	gst_bus_add_watch (extractor->bus, metadata_bus_async_cb, extractor);
 
-	file = g_file_new_for_uri (uri);
-	path = g_file_get_path (file);
-	
-	g_object_set (G_OBJECT (extractor->filesrc), "location", path, NULL);
-	
-	
-	gst_element_set_state (extractor->pipeline, GST_STATE_PAUSED);
+	if (use_tagreadbin) {
+		if (!poll_for_ready (extractor, GST_STATE_PLAYING, FALSE, TRUE)) {
+			g_warning ("Error running tagreadbin");
+			goto fail;
+		}			
+	} else {
+		if (!poll_for_ready (extractor, GST_STATE_PAUSED, TRUE, FALSE)) {
+			g_warning ("Error running decodebin");
+			goto fail;
+		}
 
-	g_main_loop_run (extractor->loop);
+		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;
+	}
 
-	extract_metadata (extractor, uri, metadata, 
-			  &artist, &album, &scount);
+	album = NULL;
+	scount = NULL;
 
-	g_free (path);
-	g_object_unref (file);
+	extract_metadata (extractor, uri, metadata, &album, &scount);
 
 	/* Save embedded art */
 	if (extractor->album_art_data && extractor->album_art_size) {
 #ifdef HAVE_GDKPIXBUF
 		tracker_process_albumart (extractor->album_art_data, extractor->album_art_size, extractor->album_art_mime,
-					  /* artist */ NULL,
+					  /* g_hash_table_lookup (metadata, "Audio:Artist") */ NULL,
 					  album,
 					  scount,
 					  uri);
 #else
 		tracker_process_albumart (NULL, 0, NULL,
-					  /* artist */ NULL,
+					  /* g_hash_table_lookup (metadata, "Audio:Artist") */ NULL,
 					  album,
 					  scount,
 					  uri);
@@ -922,10 +893,6 @@ tracker_extract_gstreamer (const gchar *uri,
 #endif /* HAVE_GDKPIXBUF */
 	}
 
-	g_free (album);
-	g_free (artist);
-	g_free (scount);
-
 	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);
@@ -934,94 +901,81 @@ tracker_extract_gstreamer (const gchar *uri,
 		gst_tag_list_free (extractor->tagcache);
 	}
 
-	if (extractor->audiotags) {
-		gst_tag_list_free (extractor->audiotags);
-	}
-
-	if (extractor->videotags) {
-		gst_tag_list_free (extractor->videotags);
-	}
-
 	gst_object_unref (GST_OBJECT (extractor->pipeline));
-	g_main_loop_unref (extractor->loop);
 	g_slice_free (MetadataExtractor, extractor);
 
+fail:
 	if (type == EXTRACT_MIME_IMAGE) {
+		/* We fallback to the file's modified time for the
+		 * "Image:Date" metadata if it doesn't exist.
+		 *
+		 * FIXME: This shouldn't be necessary.
+		 */
 		if (!tracker_statement_list_find (metadata, uri, NIE_PREFIX "contentCreated")) {
-			struct stat st;
+			gchar *date;
+			guint64 mtime;
 			
-			if (g_lstat (uri, &st) >= 0) {
-				gchar *date;
-
-				date = tracker_date_to_string (st.st_mtime);
-
-				tracker_statement_list_insert (metadata, uri,
-							       NIE_PREFIX "contentCreated", 
-							       date);
-
-				g_free (date);
-			}
-		}
-	} else if (type == EXTRACT_MIME_VIDEO) {
-		if (!tracker_statement_list_find (metadata, uri, NIE_PREFIX "title")) {
-			gchar  *basename = g_filename_display_basename (uri);
-			gchar **parts    = g_strsplit (basename, ".", -1);
-			gchar  *title    = g_strdup (parts[0]);
-			
-			g_strfreev (parts);
-			g_free (basename);
-
-			title = g_strdelimit (title, "_", ' ');
+			mtime = tracker_file_get_mtime (uri);
+			date = tracker_date_to_string ((time_t) mtime);
 
 			tracker_statement_list_insert (metadata, uri, 
-						  NIE_PREFIX "title", 
-						  title);
-
-			g_free (title);
+						       NIE_PREFIX "contentCreated",
+						       date);
+			g_free (date);
 		}
-	} else if (type == EXTRACT_MIME_AUDIO) {
-		if (!tracker_statement_list_find (metadata, uri, NIE_PREFIX "title")) {
-			gchar  *basename = g_filename_display_basename (uri);
-			gchar **parts    = g_strsplit (basename, ".", -1);
-			gchar  *title    = g_strdup (parts[0]);
-			
-			g_strfreev (parts);
-			g_free (basename);
-			
-			title = g_strdelimit (title, "_", ' ');
+	}
+ 
+	if (!tracker_statement_list_find (metadata, uri, NIE_PREFIX "title")) {
+		gchar  *basename = g_filename_display_basename (uri);
+		gchar **parts    = g_strsplit (basename, ".", -1);
+		gchar  *title    = g_strdup (parts[0]);
+		
+		g_strfreev (parts);
+		g_free (basename);
 
-			tracker_statement_list_insert (metadata, uri, 
-						  NIE_PREFIX "title", 
-						  title);
+		title = g_strdelimit (title, "_", ' ');
 
-			g_free (title);
-		}
+		tracker_statement_list_insert (metadata, uri, 
+					       NIE_PREFIX "title",
+					       title);
+		g_free (title);
 	}
-
 }
 
 
 static void
 extract_gstreamer_audio (const gchar *uri, GPtrArray *metadata)
 {
+	tracker_statement_list_insert (metadata, uri, 
+				       RDF_TYPE, 
+				       NMM_PREFIX "MusicPiece");
+
 	tracker_extract_gstreamer (uri, metadata, EXTRACT_MIME_AUDIO);
 }
 
 static void
 extract_gstreamer_video (const gchar *uri, GPtrArray *metadata)
 {
+	tracker_statement_list_insert (metadata, uri, 
+				       RDF_TYPE, 
+				       NMM_PREFIX "Video");
+
 	tracker_extract_gstreamer (uri, metadata, EXTRACT_MIME_VIDEO);
 }
 
 static void
 extract_gstreamer_image (const gchar *uri, GPtrArray *metadata)
 {
+	tracker_statement_list_insert (metadata, uri, 
+				       RDF_TYPE, 
+				       NFO_PREFIX "Image");
+
 	tracker_extract_gstreamer (uri, metadata, EXTRACT_MIME_IMAGE);
 }
 
 TrackerExtractData *
 tracker_get_extract_data (void)
 {
-	return gstreamer_data;
+	return data;
 }
 



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