[tracker] Add an extractor that uses gupnp-dlna for gstreamer based metadata extraction.



commit 1405ee26b152b7a62a64d1584a4c5b2e55c32f79
Author: Mikael Ottela <mikael ottela ixonos com>
Date:   Thu Aug 12 17:12:47 2010 +0300

    Add an extractor that uses gupnp-dlna for gstreamer based metadata extraction.

 configure.ac                                     |   33 +-
 src/tracker-extract/Makefile.am                  |   14 +
 src/tracker-extract/tracker-extract-gupnp-dlna.c |  999 ++++++++++++++++++++++
 3 files changed, 1043 insertions(+), 3 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 72c60ff..39f1ad0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -584,9 +584,17 @@ AM_CONDITIONAL(HAVE_GDKPIXBUF, test "x$have_gdkpixbuf" = "xyes")
 
 AC_ARG_ENABLE(video-extractor,
               AS_HELP_STRING([--enable-video-extractor=ARG],
-                             [enables one of the (gstreamer, xine, external, auto) video extractor backends [[default=auto]]]),,
+                             [enables one of the (gupnp-dlna, gstreamer, xine, external, auto) video extractor backends [[default=auto]]]),,
               [enable_video_extractor=auto])
 
+PKG_CHECK_MODULES(GUPNP_DLNA,
+		  [gupnp-dlna-1.0],
+                  [have_gupnp_dlna=yes],
+                  [have_gupnp_dlna=no])
+
+AC_SUBST(GUPNP_DLNA_CFLAGS)
+AC_SUBST(GUPNP_DLNA_LIBS)
+
 PKG_CHECK_MODULES(GSTREAMER,
                   [gstreamer-0.10 >= 0.10.12 gstreamer-tag-0.10 >= 0.10.12],
                   [have_libgstreamer=yes],
@@ -604,7 +612,10 @@ AC_SUBST(XINE_CFLAGS)
 AC_SUBST(XINE_LIBS)
 
 if test "x$enable_video_extractor" = "xauto"; then
-   if test "$have_libgstreamer" = "yes"; then
+   if test "$have_gupnp_dlna" = "yes"; then
+      have_video_handler_app="GUPnP-DLNA"
+      have_video_handler="yes"
+   elif test "$have_libgstreamer" = "yes"; then
       have_video_handler_app="GStreamer"
       have_video_handler="yes"
    elif test "$have_libxine" = "yes"; then
@@ -614,6 +625,13 @@ if test "x$enable_video_extractor" = "xauto"; then
       have_video_handler="?"
       have_video_handler_app="An external video player will be called"
    fi
+elif test "x$enable_video_extractor" = "xgupnp-dlna"; then
+   if test "$have_gupnp_dlna" = "yes"; then
+      have_video_handler_app="GUPnP-DLNA"
+      have_video_handler="yes"
+   else
+      AC_MSG_ERROR([Couldn't find GUPnP-DLNA])
+   fi
 elif test "x$enable_video_extractor" = "xgstreamer"; then
    if test "$have_libgstreamer" = "yes"; then
       have_video_handler_app="GStreamer"
@@ -633,19 +651,28 @@ else
    have_video_handler_app="An external video player will be called"
 fi
 
-if test "$have_video_handler_app" = "GStreamer"; then
+if test "$have_video_handler_app" = "GUPnP-DLNA"; then
+   AC_DEFINE(HAVE_GUPNP_DLNA, [], [Define if we have GUPnP-DLNA])
+   AM_CONDITIONAL(HAVE_GUPNP_DLNA, true)
+   AM_CONDITIONAL(HAVE_GSTREAMER, false)
+   AM_CONDITIONAL(HAVE_LIBXINE, false)
+   AM_CONDITIONAL(USING_EXTERNAL_VIDEO_PLAYER, false)
+elif test "$have_video_handler_app" = "GStreamer"; then
    AC_DEFINE(HAVE_GSTREAMER, [], [Define if we have GStreamer])
    AM_CONDITIONAL(HAVE_GSTREAMER, true)
+   AM_CONDITIONAL(HAVE_GUPNP_DLNA, false)
    AM_CONDITIONAL(HAVE_LIBXINE, false)
    AM_CONDITIONAL(USING_EXTERNAL_VIDEO_PLAYER, false)
 elif test "$have_video_handler_app" = "Xine"; then
    AC_DEFINE(HAVE_LIBXINE, [], [Define if we have Libxine])
    AM_CONDITIONAL(HAVE_LIBXINE, true)
+   AM_CONDITIONAL(HAVE_GUPNP_DLNA, false)
    AM_CONDITIONAL(HAVE_GSTREAMER, false)
    AM_CONDITIONAL(USING_EXTERNAL_VIDEO_PLAYER, false)
 else
    AC_DEFINE(USING_EXTERNAL_VIDEO_PLAYER, [], [Define that Tracker will try to use external video players])
    AM_CONDITIONAL(USING_EXTERNAL_VIDEO_PLAYER, true)
+   AM_CONDITIONAL(HAVE_GUPNP_DLNA, false)
    AM_CONDITIONAL(HAVE_GSTREAMER, false)
    AM_CONDITIONAL(HAVE_LIBXINE, false)
 fi
diff --git a/src/tracker-extract/Makefile.am b/src/tracker-extract/Makefile.am
index faf5c84..b6b94a7 100644
--- a/src/tracker-extract/Makefile.am
+++ b/src/tracker-extract/Makefile.am
@@ -29,6 +29,7 @@ INCLUDES = 								\
 	$(POPPLER_CFLAGS) 						\
 	$(GSTREAMER_CFLAGS) 						\
 	$(XINE_CFLAGS) 							\
+	$(GUPNP_DLNA_CFLAGS)						\
 	$(TOTEM_PL_PARSER_CFLAGS)
 
 if HAVE_LIBSTREAMANALYZER
@@ -91,6 +92,10 @@ if HAVE_GSTREAMER
 modules_LTLIBRARIES += libextract-gstreamer.la
 endif
 
+if HAVE_GUPNP_DLNA
+modules_LTLIBRARIES += libextract-gupnp-dlna.la
+endif
+
 if HAVE_GSTREAMER_HELIX
 modules_LTLIBRARIES += libextract-gstreamer-helix.la
 endif
@@ -251,6 +256,15 @@ libextract_gstreamer_helix_la_LIBADD = 					\
 	$(GLIB2_LIBS) 							\
 	$(GCOV_LIBS)
 
+# GUPnP DLNA
+libextract_gupnp_dlna_la_SOURCES = tracker-extract-gupnp-dlna.c
+libextract_gupnp_dlna_la_LDFLAGS = $(module_flags) $(albumart_flags)
+libextract_gupnp_dlna_la_LIBADD = 					\
+	$(top_builddir)/src/libtracker-extract/libtracker-extract- TRACKER_API_VERSION@.la \
+	$(GUPNP_DLNA_LIBS) 						\
+	$(GLIB2_LIBS) 							\
+	$(GCOV_LIBS)
+
 # Xine
 libextract_xine_la_SOURCES = tracker-extract-libxine.c
 libextract_xine_la_LDFLAGS = $(module_flags)
diff --git a/src/tracker-extract/tracker-extract-gupnp-dlna.c b/src/tracker-extract/tracker-extract-gupnp-dlna.c
new file mode 100644
index 0000000..481f163
--- /dev/null
+++ b/src/tracker-extract/tracker-extract-gupnp-dlna.c
@@ -0,0 +1,999 @@
+/*
+ * Copyright (C) 2010, Nokia <ivan frade nokia com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+/* I don't know why, but this prototype ain't in my math.h */
+long long int llroundl(long double x);
+
+#include <glib.h>
+#include <glib/gstdio.h>
+
+#define GST_USE_UNSTABLE_API
+#include <libgupnp-dlna/gupnp-dlna-discoverer.h>
+
+#include <gst/tag/tag.h>
+
+#include <libtracker-client/tracker.h>
+
+#include <libtracker-extract/tracker-extract.h>
+
+#include "tracker-albumart.h"
+#include "tracker-dbus.h"
+
+/* An additional tag in gstreamer for the content source. Remove when in upstream */
+#ifndef GST_TAG_CLASSIFICATION
+#define GST_TAG_CLASSIFICATION "classification"
+#endif
+
+/* 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
+
+#ifndef GST_TAG_DEVICE_MODEL
+#define GST_TAG_DEVICE_MODEL "device-model"
+#endif
+
+#ifndef GST_TAG_DEVICE_MANUFACTURER
+#define GST_TAG_DEVICE_MANUFACTURER "device-manufacturer"
+#endif
+
+#ifndef GST_TAG_DEVICE_MAKE
+#define GST_TAG_DEVICE_MAKE "device-make"
+#endif
+
+static void extract_gupnp_dlna_audio (const gchar          *uri,
+                                     TrackerSparqlBuilder *preupdate,
+                                     TrackerSparqlBuilder *metadata);
+static void extract_gupnp_dlna_video (const gchar          *uri,
+                                     TrackerSparqlBuilder *preupdate,
+                                     TrackerSparqlBuilder *metadata);
+static void extract_gupnp_dlna_image (const gchar          *uri,
+                                     TrackerSparqlBuilder *preupdate,
+                                     TrackerSparqlBuilder *metadata);
+static void extract_gupnp_dlna_guess (const gchar          *uri,
+                                     TrackerSparqlBuilder *preupdate,
+                                     TrackerSparqlBuilder *metadata);
+
+static TrackerExtractData data[] = {
+	{ "audio/*", extract_gupnp_dlna_audio },
+	{ "video/*", extract_gupnp_dlna_video },
+	{ "image/*", extract_gupnp_dlna_image },
+	{ "dlna/*",  extract_gupnp_dlna_guess },
+	{ "video/3gpp", extract_gupnp_dlna_guess },
+	{ "video/mp4", extract_gupnp_dlna_guess },
+	{ "video/x-ms-asf", extract_gupnp_dlna_guess },
+	{ NULL, NULL }
+};
+
+typedef enum {
+	CONTENT_NONE,
+	CONTENT_GUESS,
+	CONTENT_VIDEO,
+	CONTENT_AUDIO,
+	CONTENT_IMAGE,
+} ContentType;
+
+typedef struct {
+	ContentType content;
+
+	gboolean    has_image;
+	gboolean    has_audio;
+	gboolean    has_video;
+
+	const gchar *dlna_profile;
+
+	GstTagList *tags;
+
+	guint       width;
+	guint       height;
+	gfloat      frame_rate;
+	gfloat      aspect_ratio;
+
+	guint       sample_rate;
+	guint       bitrate;
+	guint       channels;
+
+	guint       duration;
+
+	gboolean        is_content_encrypted;
+
+	unsigned char  *album_art_data;
+	guint           album_art_size;
+	const gchar    *album_art_mime;
+
+} MetadataExtractor;
+
+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,
+                    GstTagList           *tag_list,
+                    const gchar          *tag)
+{
+	gchar    *s;
+	gboolean  ret;
+
+	s = NULL;
+	ret = gst_tag_list_get_string (tag_list, tag, &s);
+
+	if (s) {
+		if (ret && s[0] != '\0') {
+			tracker_sparql_builder_predicate (metadata, key);
+			tracker_sparql_builder_object_unvalidated (metadata, s);
+		}
+
+		g_free (s);
+	}
+}
+
+static void
+add_uint_gst_tag (TrackerSparqlBuilder   *metadata,
+                  const gchar *uri,
+                  const gchar *key,
+                  GstTagList  *tag_list,
+                  const gchar *tag)
+{
+	gboolean ret;
+	guint    n;
+
+	ret = gst_tag_list_get_uint (tag_list, tag, &n);
+
+	if (ret) {
+		tracker_sparql_builder_predicate (metadata, key);
+		tracker_sparql_builder_object_int64 (metadata, n);
+	}
+}
+
+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,
+                    GstTagList  *tag_list,
+                    const gchar *tag)
+{
+	gboolean ret;
+	gdouble          n;
+
+	ret = gst_tag_list_get_double (tag_list, tag, &n);
+
+	if (ret) {
+		tracker_sparql_builder_predicate (metadata, key);
+		tracker_sparql_builder_object_int64 (metadata, (gint64) 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_y_date_gst_tag (TrackerSparqlBuilder  *metadata,
+                    const gchar *uri,
+                    const gchar *key,
+                    GstTagList  *tag_list,
+                    const gchar *tag)
+{
+	GDate    *date;
+	gboolean  ret;
+
+	date = NULL;
+	ret = gst_tag_list_get_date (tag_list, tag, &date);
+
+	if (ret) {
+		if (date && g_date_valid (date)) {
+			if (date->julian)
+				ret = g_date_valid_julian (date->julian_days);
+			if (date->dmy)
+				ret = g_date_valid_dmy (date->day, date->month, date->year);
+		} else
+			ret = FALSE;
+	}
+
+	if (ret) {
+		gchar buf[25];
+
+		if (g_date_strftime (buf, 25, "%Y-%m-%dT%H:%M:%S%z", date)) {
+			tracker_sparql_builder_predicate (metadata, key);
+			tracker_sparql_builder_object_unvalidated (metadata, buf);
+		}
+	}
+
+	if (date) {
+		g_date_free (date);
+	}
+}
+
+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 = llroundl ((long double) n / (long double) 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)
+{
+	gboolean ret;
+	gchar *str;
+
+	ret = gst_tag_list_get_string (tag_list, GST_TAG_KEYWORDS, &str);
+
+	if (ret) {
+		GStrv keywords;
+		gint i = 0;
+
+		keywords = g_strsplit_set (str, " ,", -1);
+
+		while (keywords[i]) {
+			tracker_sparql_builder_predicate (metadata, "nie:keyword");
+			tracker_sparql_builder_object_unvalidated (metadata, g_strstrip (keywords[i]));
+			i++;
+		}
+
+		g_strfreev (keywords);
+		g_free (str);
+	}
+}
+
+/* static gboolean */
+/* get_embedded_album_art(MetadataExtractor *extractor) */
+/* { */
+/* 	const GValue *value; */
+/* 	guint         lindex; */
+
+/* 	lindex = 0; */
+
+/* 	do { */
+/* 		value = gst_tag_list_get_value_index (extractor->tags, GST_TAG_IMAGE, lindex); */
+
+/* 		if (value) { */
+/* 			GstBuffer    *buffer; */
+/* 			GstCaps      *caps; */
+/* 			GstStructure *caps_struct; */
+/* 			gint          type; */
+
+/* 			buffer = gst_value_get_buffer (value); */
+/* 			caps   = gst_buffer_get_caps (buffer); */
+/* 			caps_struct = gst_caps_get_structure (buffer->caps, 0); */
+
+/* 			gst_structure_get_enum (caps_struct, */
+/* 			                        "image-type", */
+/* 			                        GST_TYPE_TAG_IMAGE_TYPE, */
+/* 			                        &type); */
+
+/* 			if ((type == GST_TAG_IMAGE_TYPE_FRONT_COVER)|| */
+/* 			    ((type == GST_TAG_IMAGE_TYPE_UNDEFINED)&&(extractor->album_art_size == 0))) { */
+/* 				extractor->album_art_data = buffer->data; */
+/* 				extractor->album_art_size = buffer->size; */
+/* 				extractor->album_art_mime = gst_structure_get_name (caps_struct); */
+/* 				gst_caps_unref (caps); */
+/* 				return TRUE; */
+/* 			} */
+
+/* 			gst_caps_unref (caps); */
+
+/* 			lindex++; */
+/* 		} */
+/* 	} while (value); */
+
+/* 	value = gst_tag_list_get_value_index (extractor->tags, GST_TAG_PREVIEW_IMAGE, lindex); */
+
+/* 	if (value) { */
+/* 		GstBuffer    *buffer; */
+/* 		GstStructure *caps_struct; */
+
+/* 		buffer = gst_value_get_buffer (value); */
+/* 		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); */
+
+
+/* 		return TRUE; */
+/* 	} */
+
+/* 	return FALSE; */
+/* } */
+
+static void
+extract_metadata (MetadataExtractor      *extractor,
+		  const gchar            *uri,
+                  TrackerSparqlBuilder   *preupdate,
+                  TrackerSparqlBuilder   *metadata,
+                  gchar                 **artist,
+                  gchar                 **album,
+                  gchar                 **scount)
+{
+	const gchar *temp;
+	gchar *s, *make = NULL, *model = NULL, *manuf = NULL, *make_model = NULL;
+	gboolean ret;
+	gint count;
+	gboolean needs_audio = FALSE;
+
+	g_return_if_fail (metadata != NULL);
+
+	if (extractor->tags) {
+		gchar *artist_uri = NULL;
+		gchar *performer_uri = NULL;
+		gchar *composer_uri = NULL;
+		gchar *album_uri = NULL;
+
+		/* General */
+		if (extractor->content == CONTENT_AUDIO || extractor->content == CONTENT_VIDEO) {
+			gchar *performer = NULL, *artist_local = NULL;
+
+			gst_tag_list_get_string (extractor->tags, GST_TAG_PERFORMER, &performer);
+			gst_tag_list_get_string (extractor->tags, GST_TAG_ARTIST, &artist_local);
+
+			if (artist_local) {
+				artist_uri = tracker_uri_printf_escaped ("urn:artist:%s", artist_local);
+
+				tracker_sparql_builder_insert_open (preupdate, NULL);
+				tracker_sparql_builder_subject_iri (preupdate, artist_uri);
+				tracker_sparql_builder_predicate (preupdate, "a");
+				tracker_sparql_builder_object (preupdate, "nmm:Artist");
+				tracker_sparql_builder_predicate (preupdate, "nmm:artistName");
+				tracker_sparql_builder_object_unvalidated (preupdate, artist_local);
+				tracker_sparql_builder_insert_close (preupdate);
+			}
+
+			temp = tracker_coalesce_strip (2, performer, artist_local);
+
+			if (temp) {
+				performer_uri = tracker_uri_printf_escaped ("urn:artist:%s", temp);
+
+				tracker_sparql_builder_insert_open (preupdate, NULL);
+				tracker_sparql_builder_subject_iri (preupdate, performer_uri);
+				tracker_sparql_builder_predicate (preupdate, "a");
+				tracker_sparql_builder_object (preupdate, "nmm:Artist");
+				tracker_sparql_builder_predicate (preupdate, "nmm:artistName");
+				tracker_sparql_builder_object_unvalidated (preupdate, temp);
+				tracker_sparql_builder_insert_close (preupdate);
+
+				*artist = g_strdup (temp);
+			}
+
+			g_free (performer);
+			g_free (artist_local);
+
+			s = NULL;
+			gst_tag_list_get_string (extractor->tags, GST_TAG_COMPOSER, &s);
+
+			if (s) {
+				composer_uri = tracker_uri_printf_escaped ("urn:artist:%s", s);
+
+				tracker_sparql_builder_insert_open (preupdate, NULL);
+
+				tracker_sparql_builder_subject_iri (preupdate, composer_uri);
+				tracker_sparql_builder_predicate (preupdate, "a");
+				tracker_sparql_builder_object (preupdate, "nmm:Artist");
+
+				tracker_sparql_builder_predicate (preupdate, "nmm:artistName");
+				tracker_sparql_builder_object_unvalidated (preupdate, s);
+
+				tracker_sparql_builder_insert_close (preupdate);
+
+				g_free (s);
+			}
+
+		}
+
+		/* Audio */
+		s = NULL;
+		gst_tag_list_get_string (extractor->tags, GST_TAG_ALBUM, &s);
+		if (s) {
+			gboolean has_it;
+			guint count;
+			gdouble gain;
+
+			needs_audio = TRUE;
+
+			album_uri = tracker_uri_printf_escaped ("urn:album:%s", s);
+
+			tracker_sparql_builder_insert_open (preupdate, NULL);
+
+			tracker_sparql_builder_subject_iri (preupdate, album_uri);
+			tracker_sparql_builder_predicate (preupdate, "a");
+			tracker_sparql_builder_object (preupdate, "nmm:MusicAlbum");
+			tracker_sparql_builder_predicate (preupdate, "nmm:albumTitle");
+			tracker_sparql_builder_object_unvalidated (preupdate, s);
+
+			if (artist_uri) {
+				tracker_sparql_builder_predicate (preupdate, "nmm:albumArtist");
+				tracker_sparql_builder_object_iri (preupdate, artist_uri);
+			}
+
+			tracker_sparql_builder_insert_close (preupdate);
+
+			has_it = gst_tag_list_get_uint (extractor->tags,
+			                                GST_TAG_TRACK_COUNT,
+			                                &count);
+
+			if (has_it) {
+				tracker_sparql_builder_delete_open (preupdate, NULL);
+				tracker_sparql_builder_subject_iri (preupdate, album_uri);
+				tracker_sparql_builder_predicate (preupdate, "nmm:albumTrackCount");
+				tracker_sparql_builder_object_variable (preupdate, "unknown");
+				tracker_sparql_builder_delete_close (preupdate);
+
+				tracker_sparql_builder_where_open (preupdate);
+				tracker_sparql_builder_subject_iri (preupdate, album_uri);
+				tracker_sparql_builder_predicate (preupdate, "nmm:albumTrackCount");
+				tracker_sparql_builder_object_variable (preupdate, "unknown");
+				tracker_sparql_builder_where_close (preupdate);
+
+				tracker_sparql_builder_insert_open (preupdate, NULL);
+
+				tracker_sparql_builder_subject_iri (preupdate, album_uri);
+				tracker_sparql_builder_predicate (preupdate, "nmm:albumTrackCount");
+				tracker_sparql_builder_object_int64 (preupdate, count);
+
+				tracker_sparql_builder_insert_close (preupdate);
+			}
+
+			has_it = gst_tag_list_get_uint (extractor->tags,
+			                                GST_TAG_ALBUM_VOLUME_NUMBER,
+			                                &count);
+
+			if (has_it) {
+				tracker_sparql_builder_delete_open (preupdate, NULL);
+				tracker_sparql_builder_subject_iri (preupdate, album_uri);
+				tracker_sparql_builder_predicate (preupdate, "nmm:setNumber");
+				tracker_sparql_builder_object_variable (preupdate, "unknown");
+				tracker_sparql_builder_delete_close (preupdate);
+
+				tracker_sparql_builder_where_open (preupdate);
+				tracker_sparql_builder_subject_iri (preupdate, album_uri);
+				tracker_sparql_builder_predicate (preupdate, "nmm:setNumber");
+				tracker_sparql_builder_object_variable (preupdate, "unknown");
+				tracker_sparql_builder_where_close (preupdate);
+
+				tracker_sparql_builder_insert_open (preupdate, NULL);
+
+				tracker_sparql_builder_subject_iri (preupdate, album_uri);
+				tracker_sparql_builder_predicate (preupdate, "nmm:setNumber");
+				tracker_sparql_builder_object_int64 (preupdate, count);
+
+				tracker_sparql_builder_insert_close (preupdate);
+			}
+
+			has_it = gst_tag_list_get_double (extractor->tags,
+			                                  GST_TAG_ALBUM_GAIN,
+			                                  &gain);
+
+			if (has_it) {
+				tracker_sparql_builder_delete_open (preupdate, NULL);
+				tracker_sparql_builder_subject_iri (preupdate, album_uri);
+				tracker_sparql_builder_predicate (preupdate, "nmm:albumGain");
+				tracker_sparql_builder_object_variable (preupdate, "unknown");
+				tracker_sparql_builder_delete_close (preupdate);
+
+				tracker_sparql_builder_where_open (preupdate);
+				tracker_sparql_builder_subject_iri (preupdate, album_uri);
+				tracker_sparql_builder_predicate (preupdate, "nmm:albumGain");
+				tracker_sparql_builder_object_variable (preupdate, "unknown");
+				tracker_sparql_builder_where_close (preupdate);
+
+				tracker_sparql_builder_insert_open (preupdate, NULL);
+
+				tracker_sparql_builder_subject_iri (preupdate, album_uri);
+				tracker_sparql_builder_predicate (preupdate, "nmm:albumGain");
+				tracker_sparql_builder_object_double (preupdate, gain);
+
+				tracker_sparql_builder_insert_close (preupdate);
+			}
+
+			has_it = gst_tag_list_get_double (extractor->tags,
+			                                  GST_TAG_ALBUM_PEAK,
+			                                  &gain);
+
+			if (has_it) {
+				tracker_sparql_builder_delete_open (preupdate, NULL);
+				tracker_sparql_builder_subject_iri (preupdate, album_uri);
+				tracker_sparql_builder_predicate (preupdate, "nmm:albumPeakGain");
+				tracker_sparql_builder_object_variable (preupdate, "unknown");
+				tracker_sparql_builder_delete_close (preupdate);
+
+				tracker_sparql_builder_where_open (preupdate);
+				tracker_sparql_builder_subject_iri (preupdate, album_uri);
+				tracker_sparql_builder_predicate (preupdate, "nmm:albumPeakGain");
+				tracker_sparql_builder_object_variable (preupdate, "unknown");
+				tracker_sparql_builder_where_close (preupdate);
+
+				tracker_sparql_builder_insert_open (preupdate, NULL);
+
+				tracker_sparql_builder_subject_iri (preupdate, album_uri);
+				tracker_sparql_builder_predicate (preupdate, "nmm:albumPeakGain");
+				tracker_sparql_builder_object_double (preupdate, gain);
+
+				tracker_sparql_builder_insert_close (preupdate);
+			}
+
+			*album = s;
+
+		}
+
+		if (extractor->content == CONTENT_AUDIO)
+			needs_audio = TRUE;
+
+		tracker_sparql_builder_predicate (metadata, "a");
+
+		if (needs_audio) {
+			tracker_sparql_builder_object (metadata, "nmm:MusicPiece");
+			tracker_sparql_builder_object (metadata, "nfo:Audio");
+		}
+
+		if (extractor->content == CONTENT_VIDEO) {
+			tracker_sparql_builder_object (metadata, "nmm:Video");
+		} else if (!needs_audio) {
+			tracker_sparql_builder_object (metadata, "nfo:Image");
+		}
+
+		s = NULL;
+		gst_tag_list_get_string (extractor->tags, GST_TAG_GENRE, &s);
+		if (s && strcmp (s, "Unknown") != 0) {
+			tracker_sparql_builder_predicate (metadata, "nfo:genre");
+			tracker_sparql_builder_object_unvalidated (metadata, s);
+		}
+		g_free (s);
+
+		add_string_gst_tag (metadata, uri, "nie:title", extractor->tags, GST_TAG_TITLE);
+		add_string_gst_tag (metadata, uri, "nie:copyright", extractor->tags, GST_TAG_COPYRIGHT);
+		add_string_gst_tag (metadata, uri, "nie:license", extractor->tags, GST_TAG_LICENSE);
+		add_string_gst_tag (metadata, uri, "dc:coverage", extractor->tags, GST_TAG_LOCATION);
+		add_y_date_gst_tag (metadata, uri, "nie:contentCreated", extractor->tags, GST_TAG_DATE);
+		add_string_gst_tag (metadata, uri, "nie:comment", extractor->tags, GST_TAG_COMMENT);
+
+		gst_tag_list_get_string (extractor->tags, GST_TAG_DEVICE_MODEL, &model);
+		gst_tag_list_get_string (extractor->tags, GST_TAG_DEVICE_MAKE, &make);
+		gst_tag_list_get_string (extractor->tags, GST_TAG_DEVICE_MANUFACTURER, &manuf);
+
+		if (make && model && manuf) {
+			make_model = tracker_merge_const (" ", 3, manuf, make, model);
+		} else if (make && model) {
+			make_model = tracker_merge_const (" ", 2, make, model);
+		} else if (make && manuf) {
+			make_model = tracker_merge_const (" ", 2, manuf, make);
+		} else if (model && manuf) {
+			make_model = tracker_merge_const (" ", 2, manuf, model);
+		} else if (model) {
+			make_model = g_strdup (model);
+		} else if (make) {
+			make_model = g_strdup (make);
+		} else if (manuf) {
+			make_model = g_strdup (manuf);
+		}
+
+		if (make_model) {
+			tracker_sparql_builder_predicate (metadata, "nfo:device");
+			tracker_sparql_builder_object_unvalidated (metadata, make_model);
+			g_free (make_model);
+		}
+
+		g_free (make);
+		g_free (model);
+		g_free (manuf);
+
+		/* FIXME add this stuff */
+		/* if (extractor->is_content_encrypted) { */
+		/* 	tracker_sparql_builder_predicate (metadata, "nfo:isContentEncrypted"); */
+		/* 	tracker_sparql_builder_object_boolean (metadata, TRUE); */
+		/* } */
+
+		if (extractor->content == CONTENT_VIDEO) {
+			add_string_gst_tag (metadata, uri, "dc:source", extractor->tags, GST_TAG_CLASSIFICATION);
+
+			if (performer_uri) {
+				tracker_sparql_builder_predicate (metadata, "nmm:leadActor");
+				tracker_sparql_builder_object_iri (metadata, performer_uri);
+			}
+
+			if (composer_uri) {
+				tracker_sparql_builder_predicate (metadata, "nmm:director");
+				tracker_sparql_builder_object_iri (metadata, composer_uri);
+			}
+
+			add_keywords_gst_tag (metadata, extractor->tags);
+		}
+
+		if (needs_audio) {
+			/* Audio */
+			ret = gst_tag_list_get_uint (extractor->tags, GST_TAG_TRACK_COUNT, &count);
+			if (ret) {
+				*scount = g_strdup_printf ("%d", count);
+			}
+
+			add_uint_gst_tag   (metadata, uri, "nmm:trackNumber", extractor->tags, GST_TAG_TRACK_NUMBER);
+
+			add_double_gst_tag (metadata, uri, "nfo:gain", extractor->tags, GST_TAG_TRACK_GAIN);
+			add_double_gst_tag (metadata, uri, "nfo:peakGain", extractor->tags, GST_TAG_TRACK_PEAK);
+
+			if (performer_uri) {
+				tracker_sparql_builder_predicate (metadata, "nmm:performer");
+				tracker_sparql_builder_object_iri (metadata, performer_uri);
+			}
+
+			if (composer_uri) {
+				tracker_sparql_builder_predicate (metadata, "nmm:composer");
+				tracker_sparql_builder_object_iri (metadata, composer_uri);
+			}
+
+			if (album_uri) {
+				tracker_sparql_builder_predicate (metadata, "nmm:musicAlbum");
+				tracker_sparql_builder_object_iri (metadata, album_uri);
+			}
+		}
+
+		g_free (artist_uri);
+		g_free (performer_uri);
+		g_free (composer_uri);
+		g_free (album_uri);
+
+		add_string_gst_tag (metadata, uri, "nfo:codec", extractor->tags, GST_TAG_AUDIO_CODEC);
+	} else {
+		if (extractor->content == CONTENT_AUDIO)
+			needs_audio = TRUE;
+
+		tracker_sparql_builder_predicate (metadata, "a");
+
+		if (needs_audio) {
+			tracker_sparql_builder_object (metadata, "nmm:MusicPiece");
+			tracker_sparql_builder_object (metadata, "nfo:Audio");
+		}
+
+		if (extractor->content == CONTENT_VIDEO) {
+			tracker_sparql_builder_object (metadata, "nmm:Video");
+		} else if (extractor->content == CONTENT_IMAGE) {
+			tracker_sparql_builder_object (metadata, "nfo:Image");
+		}
+	}
+
+	if (extractor->content != CONTENT_IMAGE) {
+		if (extractor->channels) {
+			tracker_sparql_builder_predicate (metadata, "nfo.channels");
+			tracker_sparql_builder_object_int64 (metadata, extractor->channels);
+		}
+
+		if (extractor->sample_rate) {
+			tracker_sparql_builder_predicate (metadata, "nfo:sampleRate");
+			tracker_sparql_builder_object_int64 (metadata, extractor->sample_rate);
+		}
+
+		if (extractor->duration) {
+			tracker_sparql_builder_predicate (metadata, "nfo:duration");
+			tracker_sparql_builder_object_int64 (metadata, extractor->duration);
+		}
+	}
+
+	if (extractor->content == CONTENT_VIDEO) {
+		if (extractor->width) {
+			tracker_sparql_builder_predicate (metadata, "nfo:width");
+			tracker_sparql_builder_object_int64 (metadata, extractor->width);
+		}
+
+		if (extractor->height) {
+			tracker_sparql_builder_predicate (metadata, "nfo:height");
+			tracker_sparql_builder_object_int64 (metadata, extractor->height);
+		}
+
+		if (extractor->frame_rate) {
+			tracker_sparql_builder_predicate (metadata, "nfo:frameRate");
+			tracker_sparql_builder_object_double (metadata, extractor->frame_rate);
+		}
+
+		if (extractor->aspect_ratio) {
+			tracker_sparql_builder_predicate (metadata, "nfo:aspectRatio");
+			tracker_sparql_builder_object_double (metadata, extractor->aspect_ratio);
+		}
+	}
+
+	if (extractor->dlna_profile) {
+		tracker_sparql_builder_predicate (metadata, "nmm:dlnaProfile");
+		tracker_sparql_builder_object_string (metadata, extractor->dlna_profile);
+	}
+
+	/* if (extractor->content == CONTENT_AUDIO) { */
+	/* 	get_embedded_album_art (extractor); */
+	/* } */
+}
+
+static void
+extract_gupnp_dlna (const gchar *uri,
+		    TrackerSparqlBuilder  *preupdate,
+		    TrackerSparqlBuilder  *metadata,
+		    ContentType            content)
+{
+	GUPnPDLNADiscoverer  *discoverer = NULL;
+	GUPnPDLNAInformation *dlna_info  = NULL;
+	GError               *error      = NULL;
+	MetadataExtractor    extractor;
+
+	gst_init (NULL, NULL);
+
+	extractor.has_image = FALSE;
+	extractor.has_video = FALSE;
+	extractor.has_audio = FALSE;
+
+	extractor.tags      = NULL;
+
+	extractor.width = 0;
+	extractor.height = 0;
+	extractor.frame_rate = 0;
+	extractor.aspect_ratio = 0;
+
+	extractor.sample_rate = 0;
+	extractor.bitrate = 0;
+	extractor.channels = 0;
+
+	extractor.duration = 0;
+
+	extractor.is_content_encrypted = FALSE;
+
+	extractor.album_art_data = NULL;
+	extractor.album_art_size = 0;
+	extractor.album_art_mime = NULL;
+
+	discoverer = gupnp_dlna_discoverer_new (5*GST_SECOND);
+	dlna_info = gupnp_dlna_discoverer_discover_uri_sync (discoverer,
+							     uri,
+							     &error);
+
+	if (error) {
+		g_warning ("Error in gst-discovery: %s", error->message);
+
+		g_error_free (error);
+		return;
+	}
+
+	if (dlna_info) {
+		GstDiscovererInformation *info     = NULL;
+		GList                    *iter;
+
+		gchar *artist, *album, *scount;
+
+		album  = NULL;
+		scount = NULL;
+		artist = NULL;
+
+		info = gupnp_dlna_information_get_info (dlna_info);
+
+		iter = g_list_first (info->stream_list);
+
+		while (iter != NULL) {
+			GstStreamInformation *stream   = NULL;
+			GstTagList           *tmp      = NULL;
+
+			stream = iter->data;
+
+			if (stream->misc == NULL) {
+				g_debug ("misc NULL");
+			}
+
+			switch (stream->streamtype) {
+			case GST_STREAM_AUDIO:
+				extractor.has_audio = TRUE;
+				extractor.sample_rate = ((GstStreamAudioInformation *)stream)->sample_rate;
+				extractor.bitrate     = ((GstStreamAudioInformation *)stream)->bitrate;
+				extractor.channels    = ((GstStreamAudioInformation *)stream)->channels;
+				break;
+			case GST_STREAM_VIDEO:
+				extractor.has_video    = TRUE;
+				extractor.frame_rate   = (gfloat)gst_value_get_fraction_numerator (&((GstStreamVideoInformation *)stream)->frame_rate)/
+					gst_value_get_fraction_denominator (&((GstStreamVideoInformation *)stream)->frame_rate);
+				extractor.width        = ((GstStreamVideoInformation *)stream)->width;
+				extractor.height       = ((GstStreamVideoInformation *)stream)->height;
+				extractor.aspect_ratio = (gfloat)gst_value_get_fraction_numerator (&((GstStreamVideoInformation *)stream)->pixel_aspect_ratio)/
+					gst_value_get_fraction_denominator (&((GstStreamVideoInformation *)stream)->pixel_aspect_ratio);
+				break;
+			case GST_STREAM_IMAGE:
+				extractor.has_image = TRUE;
+				break;
+			default:
+				break;
+			}
+
+			tmp = gst_tag_list_merge (extractor.tags, stream->tags, GST_TAG_MERGE_APPEND);
+			if (extractor.tags) {
+				gst_tag_list_free (extractor.tags);
+			}
+			extractor.tags = tmp;
+
+			iter = g_list_next (iter);
+		}
+
+		extractor.duration = info->duration / GST_SECOND;
+
+		extractor.dlna_profile = gupnp_dlna_information_get_name (dlna_info);
+
+		if (content != CONTENT_GUESS) {
+			extractor.content = content;
+		} else {
+			if (extractor.has_video) {
+				extractor.content = CONTENT_VIDEO;
+			} else if (extractor.has_audio) {
+				extractor.content = CONTENT_AUDIO;
+			} else if (extractor.has_image) {
+				extractor.content = CONTENT_IMAGE;
+			} else {
+				extractor.content = CONTENT_NONE;
+			}
+		}
+
+		extract_metadata (&extractor, uri, preupdate, metadata, &artist, &album, &scount);
+
+		/* tracker_albumart_process (extractor.album_art_data, */
+		/* 			  extractor.album_art_size, */
+		/* 			  extractor.album_art_mime, */
+		/* 			  artist, */
+		/* 			  album, */
+		/* 			  uri); */
+
+		gst_tag_list_free (extractor.tags);
+		g_free (artist);
+		g_free (album);
+		g_free (scount);
+
+	}
+
+	g_object_unref (discoverer);
+	g_object_unref (dlna_info);
+
+}
+
+static void
+extract_gupnp_dlna_audio (const gchar          *uri,
+			  TrackerSparqlBuilder *preupdate,
+			  TrackerSparqlBuilder *metadata)
+{
+	extract_gupnp_dlna (uri, preupdate, metadata, CONTENT_AUDIO);
+}
+
+static void
+extract_gupnp_dlna_video (const gchar          *uri,
+			  TrackerSparqlBuilder *preupdate,
+			  TrackerSparqlBuilder *metadata)
+{
+	extract_gupnp_dlna (uri, preupdate, metadata, CONTENT_VIDEO);
+}
+
+static void
+extract_gupnp_dlna_image (const gchar          *uri,
+			  TrackerSparqlBuilder *preupdate,
+			  TrackerSparqlBuilder *metadata)
+{
+	extract_gupnp_dlna (uri, preupdate, metadata, CONTENT_IMAGE);
+}
+
+static void
+extract_gupnp_dlna_guess (const gchar          *uri,
+			  TrackerSparqlBuilder *preupdate,
+			  TrackerSparqlBuilder *metadata)
+{
+	extract_gupnp_dlna (uri, preupdate, metadata, CONTENT_GUESS);
+}
+
+
+TrackerExtractData *
+tracker_extract_get_data (void)
+{
+	return data;
+}
+



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