tracker r2946 - in trunk: . src/tracker-extract



Author: mottela
Date: Thu Feb 19 12:57:05 2009
New Revision: 2946
URL: http://svn.gnome.org/viewvc/tracker?rev=2946&view=rev

Log:
Switched gstreamer extractor to use decodebin/tagreadbin

Added:
   trunk/src/tracker-extract/tracker-extract-gstreamer-playbin.c   (props changed)
      - copied unchanged from r2945, /trunk/src/tracker-extract/tracker-extract-gstreamer.c
   trunk/src/tracker-extract/tracker-extract-gstreamer.c   (contents, props changed)
      - copied, changed from r2945, /trunk/src/tracker-extract/tracker-extract-gstreamer-tagreadbin.c
Removed:
   trunk/src/tracker-extract/tracker-extract-gstreamer-tagreadbin.c
Modified:
   trunk/ChangeLog

Copied: trunk/src/tracker-extract/tracker-extract-gstreamer.c (from r2945, /trunk/src/tracker-extract/tracker-extract-gstreamer-tagreadbin.c)
==============================================================================
--- /trunk/src/tracker-extract/tracker-extract-gstreamer-tagreadbin.c	(original)
+++ trunk/src/tracker-extract/tracker-extract-gstreamer.c	Thu Feb 19 12:57:05 2009
@@ -1,5 +1,7 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
+ * Copyright (C) 2006, Laurent Aguerreche (laurent aguerreche free fr)
+ * Copyright (C) 2007, Mr Jamie McCracken (jamiemcc gnome org)
  * Copyright (C) 2008, Nokia
  *
  * This program is free software; you can redistribute it and/or
@@ -29,12 +31,20 @@
 #include <stdlib.h>
 
 #include <glib.h>
+#include <glib/gstdio.h>
+
 #include <gst/gst.h>
 #include <gst/tag/tag.h>
-#include <gst/interfaces/tagreader.h>
+
+#include <libtracker-common/tracker-type-utils.h>
 
 #include "tracker-main.h"
-#include "tracker-albumart.h"
+#include "tracker-extract-albumart.h"
+
+/* An additional tag in gstreamer for the content source. Remove when in upstream */
+#ifndef GST_TAG_CLASSIFICATION
+#define GST_TAG_CLASSIFICATION "classification"
+#endif
 
 typedef enum {
 	EXTRACT_MIME_UNDEFINED,
@@ -44,6 +54,7 @@
 } ExtractMime;
 
 typedef struct {
+	/* Pipeline elements */
 	GMainLoop      *loop;
 
 	GstElement     *bin;
@@ -58,11 +69,28 @@
 
 	ExtractMime	mime;
 
+
+	/* Tags and data */
 	GstTagList     *tagcache;
 
+	GstTagList     *audiotags;
+	GstTagList     *videotags;
+
+	gint64          duration;
+	gint		video_height;
+	gint		video_width;
+	gint		video_fps_n;
+	gint		video_fps_d;
+	gint		audio_channels;
+	gint		audio_samplerate;
+
+	unsigned char  *album_art_data;
+	guint           album_art_size;
+
 } MetadataExtractor;
 
-const guint use_dbin  = 0;
+/* 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, GHashTable *metadata);
@@ -70,13 +98,35 @@
 static void extract_gstreamer_image (const gchar *uri, GHashTable *metadata);
 
 static TrackerExtractData data[] = {
-	{ "audiotag/*", extract_gstreamer_audio },
-	{ "videotag/*", extract_gstreamer_video },
-	{ "imagetag/*", extract_gstreamer_image },
+	{ "audio/*", extract_gstreamer_audio },
+	{ "video/*", extract_gstreamer_video },
+	{ "image/*", extract_gstreamer_image },
 	{ NULL, NULL }
 };
 
 static void
+add_int64_info (GHashTable *metadata,
+		gchar	   *key,
+		gint64	    info)
+{
+	gchar *str_info;
+
+	str_info = tracker_escape_metadata_printf ("%" G_GINT64_FORMAT, info);
+	g_hash_table_insert (metadata, key, str_info);
+}
+
+static void
+add_uint_info (GHashTable *metadata,
+	       gchar	  *key,
+	       guint	   info)
+{
+	gchar *str_info;
+
+	str_info = tracker_escape_metadata_printf ("%d", info);
+	g_hash_table_insert (metadata, key, str_info);
+}
+
+static void
 add_string_gst_tag (GHashTable	*metadata,
 		    const gchar *key,
 		    GstTagList	*tag_list,
@@ -169,13 +219,13 @@
 	GstFormat fmt;
 
 	g_return_val_if_fail (extractor, -1);
-	g_return_val_if_fail (extractor->bin, -1);
+	g_return_val_if_fail (extractor->pipeline, -1);
 
 	fmt = GST_FORMAT_TIME;
 
 	duration = -1;
 	
-	if (gst_element_query_duration (extractor->bin,
+	if (gst_element_query_duration (extractor->pipeline,
 					&fmt,
 					&duration) &&
 	    duration >= 0) {
@@ -189,13 +239,10 @@
 extract_metadata (MetadataExtractor *extractor,
 		  GHashTable        *metadata)
 {
-	gint64 duration;
-
 	g_return_if_fail (extractor);
 	g_return_if_fail (metadata);
 
 	if (extractor->tagcache) {
-
 		/* General */
 		add_string_gst_tag (metadata, "File:Copyright", extractor->tagcache, GST_TAG_COPYRIGHT);
 		add_string_gst_tag (metadata, "File:License", extractor->tagcache, GST_TAG_LICENSE);
@@ -226,7 +273,7 @@
 			add_string_gst_tag (metadata, "Video:Title", extractor->tagcache, GST_TAG_TITLE);
 			add_string_gst_tag (metadata, "Video:Comments", extractor->tagcache, GST_TAG_COMMENT);
 			add_string_gst_tag (metadata, "Video:Author", extractor->tagcache, GST_TAG_ARTIST);
-			add_string_gst_tag (metadata, "File:Copyright", extractor->tagcache, GST_TAG_COPYRIGHT);
+			add_string_gst_tag (metadata, "Video:Source", extractor->tagcache, GST_TAG_CLASSIFICATION);
 		} else if (extractor->mime == EXTRACT_MIME_AUDIO) {
 			add_string_gst_tag (metadata, "Audio:Title", extractor->tagcache, GST_TAG_TITLE);
 			add_string_gst_tag (metadata, "Audio:Artist", extractor->tagcache, GST_TAG_ARTIST);
@@ -234,17 +281,65 @@
 		}
  	}
 
-/* 	duration = get_media_duration (extractor); */
+	if (extractor->audio_channels >= 0) {
+		add_uint_info (metadata,
+			       g_strdup ("Audio:Channels"),
+			       extractor->audio_channels);
+	}
+
+	if (extractor->audio_samplerate >= 0) {
+		add_uint_info (metadata,
+			       g_strdup ("Audio:Samplerate"),
+			       extractor->audio_samplerate);
+	}
+
+	if (extractor->video_height >= 0) {
+		if (extractor->mime == EXTRACT_MIME_IMAGE) {
+			add_uint_info (metadata,
+				       g_strdup ("Image:Height"),
+				       extractor->video_height);
+		} else {
+			add_uint_info (metadata,
+				       g_strdup ("Video:Height"),
+				       extractor->video_height);
+		}
+	}
+
+	if (extractor->video_width >= 0) {
+		if (extractor->mime == EXTRACT_MIME_IMAGE) {
+			add_uint_info (metadata,
+				       g_strdup ("Image:Width"),
+				       extractor->video_width);
+		} else {
+			add_uint_info (metadata,
+				       g_strdup ("Video:Width"),
+				       extractor->video_width);
+		}
+	}
 
-/* 	if (extractor->mime == EXTRACT_MIME_VIDEO) { */
-/* 		if (duration >= 0) { */
-/* 			add_int64_info (metadata, g_strdup ("Video:Duration"), duration); */
-/* 		}	 */
-/* 	} else if (extractor->mime == EXTRACT_MIME_AUDIO) { */
-/* 		if (duration >= 0) { */
-/* 			add_int64_info (metadata, g_strdup ("Audio:Duration"), duration); */
-/* 		} */
-/* 	} */
+ 	if (extractor->mime == EXTRACT_MIME_VIDEO) {
+		if (extractor->video_fps_n >= 0 && extractor->video_fps_d >= 0) {
+			add_uint_info (metadata,
+				       g_strdup ("Video:FrameRate"),
+				       ((extractor->video_fps_n + extractor->video_fps_d / 2) / 
+					extractor->video_fps_d));
+		}
+ 		if (extractor->duration >= 0) {
+ 			add_int64_info (metadata, g_strdup ("Video:Duration"), extractor->duration);
+ 		}
+ 	} else if (extractor->mime == EXTRACT_MIME_AUDIO) {
+ 		if (extractor->duration >= 0) {
+ 			add_int64_info (metadata, g_strdup ("Audio:Duration"), extractor->duration);
+ 		}
+ 	}
+
+	if (extractor->audiotags) {
+		add_uint_gst_tag (metadata, "Audio:Bitrate", extractor->audiotags, GST_TAG_BITRATE);
+	}
+
+	if (extractor->videotags) {
+		add_uint_gst_tag (metadata, "Video:Bitrate", extractor->videotags, GST_TAG_BITRATE);
+	}
 }
 
 static void
@@ -258,7 +353,8 @@
 	gst_element_set_state (fsink, GST_STATE_NULL);
 }
 
-void dbin_dpad_cb (GstElement* e, GstPad* pad, gboolean cont, gpointer data)
+static void
+dbin_dpad_cb (GstElement* e, GstPad* pad, gboolean cont, gpointer data)
 {
 	MetadataExtractor *extractor = (MetadataExtractor *)data;
 	GstElement        *fsink;
@@ -270,15 +366,79 @@
 	
 	gst_element_set_state (fsink, GST_STATE_PAUSED);
 	
-	gst_bin_add (GST_BIN_CAST (extractor->pipeline), fsink);
+	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 void
+add_stream_tags (MetadataExtractor *extractor)
+{
+	GstStructure      *s         = NULL;
+	GstCaps	          *caps      = NULL;
+	GstIterator       *iter      = NULL;
+	gboolean           done      = FALSE;
+	gpointer           item;
+
+	iter = gst_element_iterate_src_pads (extractor->bin);
+
+	extractor->duration = get_media_duration(extractor);
+	
+	while (!done) {
+		switch (gst_iterator_next (iter, &item)) {
+		case GST_ITERATOR_OK:
+			if ((caps = gst_pad_get_negotiated_caps (GST_PAD(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;
+						}
+					} else {
+						g_assert_not_reached ();
+					}
+				}
+			}
+			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;
+		}
+	}
+	gst_iterator_free (iter);
+}
+
+static void
 add_tags (GstMessage *msg, MetadataExtractor *extractor)
 {
+	GstPad       *pad;
 	GstTagList   *new_tags;
 	GstTagList   *result;
 
@@ -293,9 +453,38 @@
 	}
 
 	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);
+
+		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;
+		}
+		
+		if (cache) {
+			result = gst_tag_list_merge (*cache,
+						     new_tags,
+						     GST_TAG_MERGE_KEEP);
+			if (*cache) {
+				gst_tag_list_free (*cache);
+			}
+			
+			*cache = result;
+		}
+	}
 	
 	gst_tag_list_free (new_tags);
-
 }
 
 static gboolean
@@ -323,8 +512,10 @@
 			GstElement *sender = (GstElement *) GST_MESSAGE_SRC (msg);
 			if (use_dbin && sender == extractor->pipeline) {
 				GstState newstate;
-				gst_message_parse_state_changed (msg, NULL, &newstate, NULL);
-				if (newstate == GST_STATE_PAUSED) {
+				GstState oldstate;
+				gst_message_parse_state_changed (msg, &oldstate, &newstate, NULL);
+				if ((oldstate == GST_STATE_READY) && (newstate == GST_STATE_PAUSED)) {
+					add_stream_tags(extractor);
 					stop = TRUE;
 				}
 			}
@@ -375,7 +566,16 @@
 	extractor->mime         = type;
 
 	extractor->tagcache     = NULL;
+	
+	extractor->audiotags    = NULL;
+	extractor->videotags    = 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");
@@ -403,14 +603,14 @@
 		extractor->id = g_signal_connect (G_OBJECT (extractor->bin), 
 				       "new-decoded-pad",
 				       G_CALLBACK (dbin_dpad_cb), 
-				       extractor->pipeline);
+				       extractor);
 	} else {
 	        extractor->bin = gst_element_factory_make ("tagreadbin", "tagreadbin");
 		if (!extractor->bin) {
 			g_error ("Failed to create tagreadbin");
 			return;
 		}
-		extractor->id = 0;	
+		extractor->id = 0;
 	}
 	
 	gst_bin_add (GST_BIN (extractor->pipeline), extractor->filesrc);
@@ -424,7 +624,7 @@
 		return;
 		}
 	} else {
-		if (! gst_element_link_many (extractor->filesrc, extractor->bin, NULL)) {
+		if (!gst_element_link_many (extractor->filesrc, extractor->bin, NULL)) {
 			g_error ("Can't link elements\n");
 			/* FIXME Clean up */
 			return;
@@ -439,6 +639,7 @@
 	g_object_set (G_OBJECT (extractor->filesrc), "location", uri, NULL);
 
 	gst_element_set_state (extractor->pipeline, GST_STATE_PAUSED);
+
 	g_main_loop_run (extractor->loop);
 
 	extract_metadata (extractor, metadata);
@@ -447,6 +648,76 @@
 	gst_object_unref (extractor->bus);
 	gst_object_unref (GST_OBJECT (extractor->pipeline));
 	g_slice_free (MetadataExtractor, extractor);
+
+	/* 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,
+					  /* g_hash_table_lookup (metadata, "Audio:Artist") */ NULL,
+					  g_hash_table_lookup (metadata, "Audio:Album"),
+					  g_hash_table_lookup (metadata, "Audio:AlbumTrackCount"),
+					  uri);
+#else
+		tracker_process_albumart (NULL, 0,
+					  /* g_hash_table_lookup (metadata, "Audio:Artist") */ NULL,
+					  g_hash_table_lookup (metadata, "Audio:Album"),
+					  g_hash_table_lookup (metadata, "Audio:AlbumTrackCount"),
+					  uri);
+		
+#endif /* HAVE_GDKPIXBUF */
+	}
+
+	if (type == EXTRACT_MIME_IMAGE) {
+		if (!g_hash_table_lookup (metadata, "Image:Date")) {
+			struct stat st;
+			
+			if (g_lstat (uri, &st) >= 0) {
+				gchar *date;
+				
+				date = tracker_date_to_string (st.st_mtime);
+				
+				g_hash_table_insert (metadata,
+						     g_strdup ("Image:Date"),
+						     tracker_escape_metadata (date));
+				g_free (date);
+			}
+		}
+	} else if (type == EXTRACT_MIME_VIDEO) {
+		if (!g_hash_table_lookup (metadata, "Video: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, "_", ' ');
+			title = g_strstrip (title);
+			
+			g_hash_table_insert (metadata,
+					     g_strdup ("Video:Title"),
+					     tracker_escape_metadata (title));
+			g_free (title);
+		}
+	} else if (type == EXTRACT_MIME_AUDIO) {
+		if (!g_hash_table_lookup (metadata, "Audio: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, "_", ' ');
+			title = g_strstrip (title);
+			
+			g_hash_table_insert (metadata,
+					     g_strdup ("Audio:Title"),
+					     tracker_escape_metadata (title));
+			g_free (title);
+		}
+	}
+
 }
 
 



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