tracker r2946 - in trunk: . src/tracker-extract
- From: mottela svn gnome org
- To: svn-commits-list gnome org
- Subject: tracker r2946 - in trunk: . src/tracker-extract
- Date: Thu, 19 Feb 2009 12:57:05 +0000 (UTC)
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]