[gnac] Used GstDiscoverer to retrieve metadata
- From: BenoÃt Dupasquier <bdupasqu src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnac] Used GstDiscoverer to retrieve metadata
- Date: Tue, 31 Jan 2012 02:08:54 +0000 (UTC)
commit 61951dd631d563ea077672aac74c56785da044b1
Author: BenoÃt Dupasquier <bdupasqu src gnome org>
Date: Tue Jan 31 02:08:40 2012 +0000
Used GstDiscoverer to retrieve metadata
libgnac/libgnac-metadata-tags.h | 100 ++++---
libgnac/libgnac-metadata.c | 597 +++++++++++++--------------------------
src/gnac-properties.c | 4 +-
3 files changed, 263 insertions(+), 438 deletions(-)
---
diff --git a/libgnac/libgnac-metadata-tags.h b/libgnac/libgnac-metadata-tags.h
index 342193d..890f69b 100644
--- a/libgnac/libgnac-metadata-tags.h
+++ b/libgnac/libgnac-metadata-tags.h
@@ -33,17 +33,21 @@ G_BEGIN_DECLS
typedef GHashTable LibgnacTags;
/* Non official GStreamer tags */
-#define GNAC_TAG_CHANNELS "channels"
-#define GNAC_TAG_FILENAME "filename"
-#define GNAC_TAG_FILE_SIZE "file-size"
-#define GNAC_TAG_FRAMERATE "framerate"
-#define GNAC_TAG_HAS_AUDIO "has-audio"
-#define GNAC_TAG_HAS_VIDEO "has-video"
-#define GNAC_TAG_HEIGHT "height"
-#define GNAC_TAG_MODE "mode"
-#define GNAC_TAG_RATE "rate"
-#define GNAC_TAG_VBR "vbr"
-#define GNAC_TAG_WIDTH "width"
+#define GNAC_TAG_CHANNELS "channels"
+#define GNAC_TAG_AUDIO_DEPTH "audio-depth"
+#define GNAC_TAG_FILENAME "filename"
+#define GNAC_TAG_FILE_SIZE "file-size"
+#define GNAC_TAG_FRAMERATE "framerate"
+#define GNAC_TAG_HAS_AUDIO "has-audio"
+#define GNAC_TAG_HAS_VIDEO "has-video"
+#define GNAC_TAG_HEIGHT "height"
+#define GNAC_TAG_INTERLACED "interlaced"
+#define GNAC_TAG_MODE "channel-mode"
+#define GNAC_TAG_PAR "par"
+#define GNAC_TAG_RATE "rate"
+#define GNAC_TAG_VBR "vbr"
+#define GNAC_TAG_VIDEO_DEPTH "video-depth"
+#define GNAC_TAG_WIDTH "width"
#define LIBGNAC_METADATA_TAG_IS_ALBUM(tag) \
(g_str_equal((tag), GST_TAG_ALBUM))
@@ -55,6 +59,8 @@ typedef GHashTable LibgnacTags;
(g_str_equal((tag), GST_TAG_ARTIST))
#define LIBGNAC_METADATA_TAG_IS_AUDIO_CODEC(tag) \
(g_str_equal((tag), GST_TAG_AUDIO_CODEC))
+#define LIBGNAC_METADATA_TAG_IS_AUDIO_DEPTH(tag) \
+ (g_str_equal((tag), GST_TAG_AUDIO_DEPTH))
#define LIBGNAC_METADATA_TAG_IS_BITRATE(tag) \
(g_str_equal((tag), GST_TAG_BITRATE))
#define LIBGNAC_METADATA_TAG_IS_CHANNELS(tag) \
@@ -85,6 +91,8 @@ typedef GHashTable LibgnacTags;
(g_str_equal((tag), GNAC_TAG_HEIGHT))
#define LIBGNAC_METADATA_TAG_IS_IMAGE(tag) \
(g_str_equal((tag), GST_TAG_IMAGE))
+#define LIBGNAC_METADATA_TAG_IS_INTERLACED(tag) \
+ (g_str_equal((tag), GNAC_TAG_INTERLACED))
#define LIBGNAC_METADATA_TAG_IS_LOCATION(tag) \
(g_str_equal((tag), GST_TAG_LOCATION))
#define LIBGNAC_METADATA_TAG_IS_MODE(tag) \
@@ -105,71 +113,79 @@ typedef GHashTable LibgnacTags;
(g_str_equal((tag), GNAC_TAG_VBR))
#define LIBGNAC_METADATA_TAG_IS_VIDEO_CODEC(tag) \
(g_str_equal((tag), GST_TAG_VIDEO_CODEC))
+#define LIBGNAC_METADATA_TAG_IS_VIDEO_DEPTH(tag) \
+ (g_str_equal((tag), GST_TAG_VIDEO_DEPTH))
#define LIBGNAC_METADATA_TAG_IS_WIDTH(tag) \
(g_str_equal((tag), GNAC_TAG_WIDTH))
#define LIBGNAC_METADATA_TAG_ALBUM(tags) \
- (g_hash_table_lookup((GHashTable*)(tags), GST_TAG_ALBUM))
+ (g_hash_table_lookup((GHashTable *) (tags), GST_TAG_ALBUM))
#define LIBGNAC_METADATA_TAG_ALBUM_VOLUME_COUNT(tags) \
- (g_hash_table_lookup((GHashTable*)(tags), GST_TAG_ALBUM_VOLUME_COUNT))
+ (g_hash_table_lookup((GHashTable *) (tags), GST_TAG_ALBUM_VOLUME_COUNT))
#define LIBGNAC_METADATA_TAG_ALBUM_VOLUME_NUMBER(tags) \
- (g_hash_table_lookup((GHashTable*)(tags), GST_TAG_ALBUM_VOLUME_NUMBER))
+ (g_hash_table_lookup((GHashTable *) (tags), GST_TAG_ALBUM_VOLUME_NUMBER))
#define LIBGNAC_METADATA_TAG_ARTIST(tags) \
- (g_hash_table_lookup((GHashTable*)(tags), GST_TAG_ARTIST))
+ (g_hash_table_lookup((GHashTable *) (tags), GST_TAG_ARTIST))
#define LIBGNAC_METADATA_TAG_AUDIO_CODEC(tags) \
- (g_hash_table_lookup((GHashTable*)(tags), GST_TAG_AUDIO_CODEC))
+ (g_hash_table_lookup((GHashTable *) (tags), GST_TAG_AUDIO_CODEC))
+#define LIBGNAC_METADATA_TAG_AUDIO_DEPTH(tags) \
+ (g_hash_table_lookup((GHashTable *) (tags), GST_TAG_AUDIO_DEPTH))
#define LIBGNAC_METADATA_TAG_BITRATE(tags) \
- (g_hash_table_lookup((GHashTable*)(tags), GST_TAG_BITRATE))
+ (g_hash_table_lookup((GHashTable *) (tags), GST_TAG_BITRATE))
#define LIBGNAC_METADATA_TAG_CHANNELS(tags) \
- (g_hash_table_lookup((GHashTable*)(tags), GNAC_TAG_CHANNELS))
+ (g_hash_table_lookup((GHashTable *) (tags), GNAC_TAG_CHANNELS))
#define LIBGNAC_METADATA_TAG_COMMENT(tags) \
- (g_hash_table_lookup((GHashTable*)(tags), GST_TAG_COMMENT))
+ (g_hash_table_lookup((GHashTable *) (tags), GST_TAG_COMMENT))
#define LIBGNAC_METADATA_TAG_CONTAINER_FORMAT(tags) \
- (g_hash_table_lookup((GHashTable*)(tags), GST_TAG_CONTAINER_FORMAT))
+ (g_hash_table_lookup((GHashTable *) (tags), GST_TAG_CONTAINER_FORMAT))
#define LIBGNAC_METADATA_TAG_DATE(tags) \
- (g_hash_table_lookup((GHashTable*)(tags), GST_TAG_DATE))
+ (g_hash_table_lookup((GHashTable *) (tags), GST_TAG_DATE))
#define LIBGNAC_METADATA_TAG_DURATION(tags) \
- (g_hash_table_lookup((GHashTable*)(tags), GST_TAG_DURATION))
+ (g_hash_table_lookup((GHashTable *) (tags), GST_TAG_DURATION))
#define LIBGNAC_METADATA_TAG_ENCODER(tags) \
- (g_hash_table_lookup((GHashTable*)(tags), GST_TAG_ENCODER))
+ (g_hash_table_lookup((GHashTable *) (tags), GST_TAG_ENCODER))
#define LIBGNAC_METADATA_TAG_FILE_SIZE(tags) \
- (g_hash_table_lookup((GHashTable*)(tags), GNAC_TAG_FILE_SIZE))
+ (g_hash_table_lookup((GHashTable *) (tags), GNAC_TAG_FILE_SIZE))
#define LIBGNAC_METADATA_TAG_FILENAME(tags) \
- (g_hash_table_lookup((GHashTable*)(tags), GNAC_TAG_FILENAME))
+ (g_hash_table_lookup((GHashTable *) (tags), GNAC_TAG_FILENAME))
#define LIBGNAC_METADATA_TAG_FRAMERATE(tags) \
- (g_hash_table_lookup((GHashTable*)(tags), GNAC_TAG_FRAMERATE))
+ (g_hash_table_lookup((GHashTable *) (tags), GNAC_TAG_FRAMERATE))
#define LIBGNAC_METADATA_TAG_GENRE(tags) \
- (g_hash_table_lookup((GHashTable*)(tags), GST_TAG_GENRE))
+ (g_hash_table_lookup((GHashTable *) (tags), GST_TAG_GENRE))
#define LIBGNAC_METADATA_TAG_HAS_AUDIO(tags) \
- (g_hash_table_lookup((GHashTable*)(tags), GNAC_TAG_HAS_AUDIO))
+ (g_hash_table_lookup((GHashTable *) (tags), GNAC_TAG_HAS_AUDIO))
#define LIBGNAC_METADATA_TAG_HAS_VIDEO(tags) \
- (g_hash_table_lookup((GHashTable*)(tags), GNAC_TAG_HAS_VIDEO))
+ (g_hash_table_lookup((GHashTable *) (tags), GNAC_TAG_HAS_VIDEO))
#define LIBGNAC_METADATA_TAG_HEIGHT(tags) \
- (g_hash_table_lookup((GHashTable*)(tags), GNAC_TAG_HEIGHT))
+ (g_hash_table_lookup((GHashTable *) (tags), GNAC_TAG_HEIGHT))
#define LIBGNAC_METADATA_TAG_IMAGE(tags) \
- (g_hash_table_lookup((GHashTable*)(tags), GST_TAG_IMAGE))
+ (g_hash_table_lookup((GHashTable *) (tags), GST_TAG_IMAGE))
+#define LIBGNAC_METADATA_TAG_INTERLACED(tags) \
+ (g_hash_table_lookup((GHashTable *) (tags), GNAC_TAG_INTERLACED))
#define LIBGNAC_METADATA_TAG_LOCATION(tags) \
- (g_hash_table_lookup((GHashTable*)(tags), GST_TAG_LOCATION))
+ (g_hash_table_lookup((GHashTable *) (tags), GST_TAG_LOCATION))
#define LIBGNAC_METADATA_TAG_MODE(tags) \
- (g_hash_table_lookup((GHashTable*)(tags), GNAC_TAG_MODE))
+ (g_hash_table_lookup((GHashTable *) (tags), GNAC_TAG_MODE))
#define LIBGNAC_METADATA_TAG_RATE(tags) \
- (g_hash_table_lookup((GHashTable*)(tags), GNAC_TAG_RATE))
+ (g_hash_table_lookup((GHashTable *) (tags), GNAC_TAG_RATE))
#define LIBGNAC_METADATA_TAG_TITLE(tags) \
- (g_hash_table_lookup((GHashTable*)(tags), GST_TAG_TITLE))
+ (g_hash_table_lookup((GHashTable *) (tags), GST_TAG_TITLE))
#define LIBGNAC_METADATA_TAG_TRACK_COUNT(tags) \
- (g_hash_table_lookup((GHashTable*)(tags), GST_TAG_TRACK_COUNT))
+ (g_hash_table_lookup((GHashTable *) (tags), GST_TAG_TRACK_COUNT))
#define LIBGNAC_METADATA_TAG_TRACK_GAIN(tag) \
- (g_hash_table_lookup((GHashTable*)(tags), GST_TAG_TRACK_GAIN))
+ (g_hash_table_lookup((GHashTable *) (tags), GST_TAG_TRACK_GAIN))
#define LIBGNAC_METADATA_TAG_TRACK_NUMBER(tags) \
- (g_hash_table_lookup((GHashTable*)(tags), GST_TAG_TRACK_NUMBER))
+ (g_hash_table_lookup((GHashTable *) (tags), GST_TAG_TRACK_NUMBER))
#define LIBGNAC_METADATA_TAG_TRACK_PEAK(tag) \
- (g_hash_table_lookup((GHashTable*)(tags), GST_TAG_TRACK_PEAK))
+ (g_hash_table_lookup((GHashTable *) (tags), GST_TAG_TRACK_PEAK))
#define LIBGNAC_METADATA_TAG_VBR(tags) \
- (g_hash_table_lookup((GHashTable*)(tags), GNAC_TAG_VBR))
+ (g_hash_table_lookup((GHashTable *) (tags), GNAC_TAG_VBR))
#define LIBGNAC_METADATA_TAG_VIDEO_CODEC(tags) \
- (g_hash_table_lookup((GHashTable*)(tags), GST_TAG_VIDEO_CODEC))
+ (g_hash_table_lookup((GHashTable *) (tags), GST_TAG_VIDEO_CODEC))
+#define LIBGNAC_METADATA_TAG_VIDEO_DEPTH(tags) \
+ (g_hash_table_lookup((GHashTable *) (tags), GST_TAG_VIDEO_DEPTH))
#define LIBGNAC_METADATA_TAG_WIDTH(tags) \
- (g_hash_table_lookup((GHashTable*)(tags), GNAC_TAG_WIDTH))
+ (g_hash_table_lookup((GHashTable *) (tags), GNAC_TAG_WIDTH))
G_END_DECLS
diff --git a/libgnac/libgnac-metadata.c b/libgnac/libgnac-metadata.c
index 8b420a5..b063d4d 100644
--- a/libgnac/libgnac-metadata.c
+++ b/libgnac/libgnac-metadata.c
@@ -30,6 +30,7 @@
#include <gdk/gdk.h>
#include <glib/gi18n.h>
#include <gst/gst.h>
+#include <gst/pbutils/pbutils.h>
#include <gst/tag/tag.h>
#include <stdarg.h>
@@ -38,22 +39,12 @@
#include "libgnac-gst-utils.h"
#include "libgnac-metadata.h"
-static LibgnacTags *dummy_tags;
struct LibgnacMetadataPrivate
{
- GFile *uri;
-
- GstElement *pipeline;
- GstElement *sink;
-
- GHashTable *tags_table;
-
- LibgnacTags *metadata;
-
- gboolean eos;
-
- GError *error;
+ GHashTable *tags_table;
+ GstDiscovererInfo *info;
+ LibgnacTags *metadata;
};
G_DEFINE_TYPE(LibgnacMetadata, libgnac_metadata, G_TYPE_OBJECT);
@@ -63,33 +54,13 @@ G_DEFINE_TYPE(LibgnacMetadata, libgnac_metadata, G_TYPE_OBJECT);
static void
-libgnac_metadata_destroy_pipeline(LibgnacMetadata *md)
-{
- if (!md->priv->pipeline) return;
-
- GstBus *bus = gst_element_get_bus(md->priv->pipeline);
- gst_element_set_state(md->priv->pipeline, GST_STATE_NULL);
- gst_bus_set_sync_handler(bus, NULL, NULL);
- gst_object_unref(GST_OBJECT(bus));
- gst_object_unref(GST_OBJECT(md->priv->pipeline));
- md->priv->pipeline = NULL;
-}
-
-
-static void
libgnac_metadata_reset(LibgnacMetadata *md)
{
- if (md->priv->uri) {
- g_object_unref(md->priv->uri);
- md->priv->uri = NULL;
- }
- md->priv->eos = FALSE;
- md->priv->error = NULL;
- libgnac_metadata_destroy_pipeline(md);
/* must be freed by the user */
if (md->priv->metadata) {
md->priv->metadata = NULL;
}
+ md->priv->info = NULL;
}
@@ -158,6 +129,75 @@ libgnac_metadata_free_gvalue(GValue *value)
static void
+libgnac_metadata_add_boolean_value(LibgnacMetadata *md,
+ gchar *tag_name,
+ gboolean value)
+{
+ GValue *val = g_new0(GValue, 1);
+ g_value_init(val, G_TYPE_BOOLEAN);
+ g_value_set_boolean(val, value);
+ g_hash_table_insert(md->priv->metadata, tag_name, val);
+}
+
+
+static void
+libgnac_metadata_add_fraction_value(LibgnacMetadata *md,
+ gchar *tag_name,
+ guint numerator,
+ guint denominator)
+{
+ if (numerator == 0 || denominator == 0) return;
+
+ GValue *value = g_new0(GValue, 1);
+ g_value_init(value, G_TYPE_FLOAT);
+ g_value_set_float(value, (gfloat) numerator / denominator);
+ g_hash_table_insert(md->priv->metadata, tag_name, value);
+}
+
+
+static void
+libgnac_metadata_add_object_value(LibgnacMetadata *md,
+ gchar *tag_name,
+ GObject *value)
+{
+ if (!value) return;
+
+ GValue *val = g_new0(GValue, 1);
+ g_value_init(val, G_TYPE_OBJECT);
+ g_value_set_object(val, value);
+ g_hash_table_insert(md->priv->metadata, tag_name, val);
+}
+
+
+static void
+libgnac_metadata_add_string_value(LibgnacMetadata *md,
+ gchar *tag_name,
+ const gchar *value)
+{
+ if (!value) return;
+
+ GValue *val = g_new0(GValue, 1);
+ g_value_init(val, G_TYPE_STRING);
+ g_value_set_string(val, value);
+ g_hash_table_insert(md->priv->metadata, tag_name, val);
+}
+
+
+static void
+libgnac_metadata_add_uint_value(LibgnacMetadata *md,
+ gchar *tag_name,
+ guint value)
+{
+ if (value == 0) return;
+
+ GValue *val = g_new0(GValue, 1);
+ g_value_init(val, G_TYPE_UINT);
+ g_value_set_uint(val, value);
+ g_hash_table_insert(md->priv->metadata, tag_name, val);
+}
+
+
+static void
libgnac_metadata_size_prepared_cb(GdkPixbufLoader *loader,
gint width,
gint height,
@@ -224,59 +264,17 @@ libgnac_metadata_process_tag_image(const GstTagList *taglist,
}
GdkPixbuf *pixbuf = gdk_pixbuf_loader_get_pixbuf(loader);
- g_return_if_fail(pixbuf);
-
- GValue *newval = g_new0(GValue, 1);
- g_value_init(newval, G_TYPE_OBJECT);
- g_value_set_object(newval, pixbuf);
+ libgnac_metadata_add_object_value(md, GST_TAG_IMAGE, G_OBJECT(pixbuf));
g_object_unref(G_OBJECT(loader));
- loader = NULL;
-
- g_hash_table_insert(md->priv->metadata, GST_TAG_IMAGE, newval);
}
}
}
static void
-libgnac_metadata_process_tag_value(GstStructure *structure,
- gchar *tag_name,
- LibgnacMetadata *md)
-{
- const GValue *val = gst_structure_get_value(structure, tag_name);
- if (!val) return;
-
- if (GST_VALUE_HOLDS_FRACTION(val)) {
- gint numerator = gst_value_get_fraction_numerator(val);
- gint denominator = gst_value_get_fraction_denominator(val);
-
- GValue *newval = g_new0(GValue, 1);
- g_value_init(newval, G_TYPE_FLOAT);
- g_value_set_float(newval, (gfloat) numerator / denominator);
- g_hash_table_insert(md->priv->metadata, tag_name, newval);
- }
-}
-
-
-static void
-libgnac_metadata_process_tag_int(GstStructure *structure,
- gchar *tag_name,
- LibgnacMetadata *md)
-{
- gint int_val;
- if (gst_structure_get_int(structure, tag_name, &int_val)) {
- GValue *val = g_new0(GValue, 1);
- g_value_init(val, G_TYPE_INT);
- g_value_set_int(val, int_val);
- g_hash_table_insert(md->priv->metadata, tag_name, val);
- }
-}
-
-
-static void
-libgnac_metadata_process_tag(const GstTagList *taglist,
- const gchar *tag_name,
+libgnac_metadata_process_tag(const GstTagList *taglist,
+ gchar *tag_name,
LibgnacMetadata *md)
{
gint count = gst_tag_list_get_tag_size(taglist, tag_name);
@@ -290,6 +288,7 @@ libgnac_metadata_process_tag(const GstTagList *taglist,
}
const GValue *val = gst_tag_list_get_value_index(taglist, tag_name, 0);
+
GType type = gst_tag_get_type(tag_name);
GValue *newval = g_new0(GValue, 1);
g_value_init(newval, type);
@@ -310,29 +309,7 @@ libgnac_metadata_process_tag(const GstTagList *taglist,
g_value_take_string(newval, str);
}
- if (g_str_equal(tag_name, GST_TAG_BITRATE))
- {
- guint32 bitrate = g_value_get_uint(newval);
- g_value_set_uint(newval, bitrate);
- if (libgnac_metadata_tag_exists(md->priv->metadata, tag_name)) {
- guint32 old_bitrate = g_value_get_uint(
- LIBGNAC_METADATA_TAG_BITRATE(md->priv->metadata));
- if (bitrate != old_bitrate) {
- GValue *vbr = g_new0(GValue, 1);
- g_value_init(vbr, G_TYPE_UINT);
- g_value_set_uint(vbr, bitrate);
- g_hash_table_insert(md->priv->metadata, GNAC_TAG_VBR, vbr);
- }
- }
- }
- else if (g_str_equal(tag_name, GST_TAG_DURATION))
- {
- guint64 duration = g_value_get_uint64(newval);
- /* convert the duration from ns to seconds */
- g_value_set_uint64(newval, duration / GST_SECOND);
- }
- else if (g_str_equal(tag_name, GST_TAG_DATE))
- {
+ if (g_str_equal(tag_name, GST_TAG_DATE)) {
g_return_if_fail(GST_VALUE_HOLDS_DATE(newval));
const GDate *date = gst_value_get_date(newval);
if (!date) return;
@@ -342,222 +319,120 @@ libgnac_metadata_process_tag(const GstTagList *taglist,
g_value_set_uint(newval, year);
}
- g_hash_table_insert(md->priv->metadata, (gpointer) tag_name, newval);
-}
-
-
-static void
-libgnac_metadata_on_message_application(GstBus *bus,
- GstMessage *message,
- LibgnacMetadata *md)
-{
- libgnac_metadata_destroy_pipeline(md);
- md->priv->eos = TRUE;
+ g_hash_table_insert(md->priv->metadata, tag_name, newval);
}
static void
-libgnac_metadata_on_message_eos(GstBus *bus,
- GstMessage *message,
- LibgnacMetadata *md)
-{
- md->priv->eos = TRUE;
-}
-
-
-static void
-libgnac_metadata_on_message_error(GstBus *bus,
- GstMessage *message,
- LibgnacMetadata *md)
+libgnac_metadata_get_file_info(GFile *uri, LibgnacMetadata *md)
{
GError *error = NULL;
- gchar *debug;
- gst_message_parse_error(message, &error, &debug);
- libgnac_debug("Error on metadata reading: %s (%s)", error->message, debug);
- md->priv->eos = TRUE;
- g_free(debug);
- g_clear_error(&error);
-}
+ GFileInfo *info = g_file_query_info(uri,
+ G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME ","
+ G_FILE_ATTRIBUTE_STANDARD_ICON ","
+ G_FILE_ATTRIBUTE_STANDARD_SIZE ","
+ G_FILE_ATTRIBUTE_THUMBNAIL_PATH,
+ G_FILE_QUERY_INFO_NONE, NULL, &error);
-static void
-libgnac_metadata_on_message_tag(GstBus *bus,
- GstMessage *message,
- LibgnacMetadata *md)
-{
- GstTagList *taglist;
- gst_message_parse_tag(message, &taglist);
- if (GST_IS_TAG_LIST(taglist)) {
- gst_tag_list_foreach(taglist,
- (GstTagForeachFunc) libgnac_metadata_process_tag, md);
- gst_tag_list_free(taglist);
+ if (error) {
+ g_clear_error(&error);
+ return;
}
-}
-
-static gboolean
-libgnac_metadata_bus_handler(GstBus *bus,
- GstMessage *message,
- LibgnacMetadata *md)
-{
- g_return_val_if_fail(md, FALSE);
+ /* file size */
+ GValue *file_size_value = g_new0(GValue, 1);
+ g_value_init(file_size_value, G_TYPE_INT64);
+ g_value_set_int64(file_size_value, g_file_info_get_size(info));
+ g_hash_table_insert(md->priv->metadata, GNAC_TAG_FILE_SIZE, file_size_value);
- switch (GST_MESSAGE_TYPE(message))
- {
- case GST_MESSAGE_EOS:
- libgnac_metadata_on_message_eos(bus, message, md);
- break;
- case GST_MESSAGE_ERROR:
- libgnac_metadata_on_message_error(bus, message, md);
- break;
- case GST_MESSAGE_TAG:
- libgnac_metadata_on_message_tag(bus, message, md);
- break;
- case GST_MESSAGE_APPLICATION:
- libgnac_metadata_on_message_application(bus, message, md);
- break;
- default:
- break;
- }
+ /* location */
+ gchar *path = g_file_get_path(uri);
+ libgnac_metadata_add_string_value(md, GST_TAG_LOCATION, path);
+ g_free(path);
- return FALSE;
-}
+ /* filename */
+ const gchar *filename = g_file_info_get_display_name(info);
+ libgnac_metadata_add_string_value(md, GNAC_TAG_FILENAME, filename);
+ /* image */
+ if (!libgnac_metadata_tag_exists(md->priv->metadata, GST_TAG_IMAGE)) {
+ const gchar *thumbnail_path = g_file_info_get_attribute_byte_string(info,
+ G_FILE_ATTRIBUTE_THUMBNAIL_PATH);
+ if (thumbnail_path) {
+ GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(thumbnail_path, NULL);
+ libgnac_metadata_add_object_value(md, GST_TAG_IMAGE, G_OBJECT(pixbuf));
+ }
+ }
-static GstBusSyncReply
-libgnac_metadata_bus_sync_handler(GstBus *bus,
- GstMessage *message,
- LibgnacMetadata *md)
-{
- libgnac_metadata_bus_handler(bus, message, md);
- gst_message_unref(message);
- return GST_BUS_DROP;
+ g_object_unref(info);
}
static void
-libgnac_metadata_new_decoded_pad_cb(GstElement *decodebin,
- GstPad *pad,
- LibgnacMetadata *md)
+libgnac_metadata_process_audio_info(LibgnacMetadata *md)
{
- GstPad *sink_pad = gst_element_get_pad(md->priv->sink, "sink");
- if (GST_PAD_IS_LINKED(sink_pad)) {
- g_object_unref(sink_pad);
- return;
- }
+ GList *audio_info = gst_discoverer_info_get_audio_streams(md->priv->info);
+ if (!audio_info) return;
- g_return_if_fail(
- libgnac_gstu_pad_link(pad, sink_pad, NULL) == GST_PAD_LINK_OK);
+ libgnac_metadata_add_boolean_value(md, GNAC_TAG_HAS_AUDIO, TRUE);
- GstCaps *caps = gst_pad_get_caps(pad);
- if (gst_caps_is_empty(caps) || gst_caps_is_any(caps)) {
- gst_caps_unref(caps);
- g_object_unref(sink_pad);
- return;
- }
+ GList *first = g_list_first(audio_info);
+ GstDiscovererAudioInfo *audio = (GstDiscovererAudioInfo *) first->data;
- GstStructure *structure = gst_caps_get_structure(caps, 0);
- const gchar *mimetype = gst_structure_get_name(structure);
+ guint channels = gst_discoverer_audio_info_get_channels(audio);
+ libgnac_metadata_add_uint_value(md, GNAC_TAG_CHANNELS, channels);
- if (g_str_has_prefix(mimetype, "video"))
- {
- GValue *val = g_new0(GValue, 1);
- g_value_init(val, G_TYPE_BOOLEAN);
- g_value_set_boolean(val, TRUE);
- g_hash_table_insert(md->priv->metadata, GNAC_TAG_HAS_VIDEO, val);
- }
- else if (g_str_has_prefix(mimetype, "audio"))
- {
- GValue *val = g_new0(GValue, 1);
- g_value_init(val, G_TYPE_BOOLEAN);
- g_value_set_boolean(val, TRUE);
- g_hash_table_insert(md->priv->metadata, GNAC_TAG_HAS_AUDIO, val);
- }
- else
- {
- libgnac_debug("Got a non audio or video pad: %s", mimetype);
- }
+ guint sample_rate = gst_discoverer_audio_info_get_sample_rate(audio);
+ libgnac_metadata_add_uint_value(md, GNAC_TAG_RATE, sample_rate);
- gst_caps_unref(caps);
- gst_object_unref(sink_pad);
-}
+ guint depth = gst_discoverer_audio_info_get_depth(audio);
+ libgnac_metadata_add_uint_value(md, GNAC_TAG_AUDIO_DEPTH, depth);
+ //guint bitrate = gst_discoverer_audio_info_get_bitrate(audio);
+ //if (gst_discoverer_audio_info_is_vbr(audio)) {
+ //if (audio->is_vbr) { // XXX not implemented yet
+ // libgnac_metadata_add_uint_value(md, GNAC_TAG_VBR, bitrate);
+ //}
-static gboolean
-libgnac_metadata_autoplug_continue_cb(GstElement *decodebin,
- GstPad *pad,
- GstCaps *caps,
- LibgnacMetadata *md)
-{
- g_return_val_if_fail(LIBGNAC_IS_METADATA(md), TRUE);
-
- if (!gst_caps_is_fixed(caps)) return TRUE;
-
- GstStructure *structure = gst_caps_get_structure(caps, 0);
- const gchar *mimetype = gst_structure_get_name(structure);
-
- libgnac_metadata_process_tag_int(structure, GNAC_TAG_RATE, md);
- libgnac_metadata_process_tag_int(structure, GNAC_TAG_CHANNELS, md);
-
- if (g_str_has_prefix(mimetype, "video")) {
- libgnac_metadata_process_tag_int(structure, GNAC_TAG_HEIGHT, md);
- libgnac_metadata_process_tag_int(structure, GNAC_TAG_WIDTH, md);
- libgnac_metadata_process_tag_value(structure, GNAC_TAG_FRAMERATE, md);
- }
-
- return TRUE;
+ gst_discoverer_stream_info_list_free(audio_info);
}
static void
-libgnac_metadata_get_file_info(GFile *uri, LibgnacMetadata *md)
+libgnac_metadata_process_video_info(LibgnacMetadata *md)
{
- GError *error = NULL;
+ GList *video_info = gst_discoverer_info_get_video_streams(md->priv->info);
+ if (!video_info) return;
- GFileInfo *info = g_file_query_info(uri,
- G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME ","
- G_FILE_ATTRIBUTE_STANDARD_ICON ","
- G_FILE_ATTRIBUTE_STANDARD_SIZE ","
- G_FILE_ATTRIBUTE_THUMBNAIL_PATH,
- G_FILE_QUERY_INFO_NONE, NULL, &error);
+ libgnac_metadata_add_boolean_value(md, GNAC_TAG_HAS_VIDEO, TRUE);
- if (error) {
- g_clear_error(&error);
- return;
- }
+ GList *first = g_list_first(video_info);
+ GstDiscovererVideoInfo *video = (GstDiscovererVideoInfo *) first->data;
- /* file size */
- GValue *file_size_value = g_new0(GValue, 1);
- g_value_init(file_size_value, G_TYPE_INT64);
- g_value_set_int64(file_size_value, g_file_info_get_size(info));
- g_hash_table_insert(md->priv->metadata, GNAC_TAG_FILE_SIZE, file_size_value);
+ guint height = gst_discoverer_video_info_get_height(video);
+ libgnac_metadata_add_uint_value(md, GNAC_TAG_HEIGHT, height);
- /* location */
- gchar *path = g_file_get_path(uri);
- GValue *location_value = g_new0(GValue, 1);
- g_value_init(location_value, G_TYPE_STRING);
- g_value_set_string(location_value, path);
- g_free(path);
- g_hash_table_insert(md->priv->metadata, GST_TAG_LOCATION, location_value);
+ guint width = gst_discoverer_video_info_get_width(video);
+ libgnac_metadata_add_uint_value(md, GNAC_TAG_WIDTH, width);
- /* filename */
- GValue *filename_value = g_new0(GValue, 1);
- g_value_init(filename_value, G_TYPE_STRING);
- g_value_set_string(filename_value, g_file_info_get_display_name(info));
- g_hash_table_insert(md->priv->metadata, GNAC_TAG_FILENAME, filename_value);
+ guint depth = gst_discoverer_video_info_get_depth(video);
+ libgnac_metadata_add_uint_value(md, GNAC_TAG_VIDEO_DEPTH, depth);
- /* image */
- const gchar *thumbnail_path = g_file_info_get_attribute_byte_string(info,
- G_FILE_ATTRIBUTE_THUMBNAIL_PATH);
- if (thumbnail_path) {
- GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(thumbnail_path, NULL);
- GValue *value = g_new0(GValue, 1);
- g_value_init(value, G_TYPE_OBJECT);
- g_value_set_object(value, pixbuf);
- g_hash_table_insert(md->priv->metadata, GST_TAG_IMAGE, value);
+ guint rate_num = gst_discoverer_video_info_get_framerate_num(video);
+ guint rate_denom = gst_discoverer_video_info_get_framerate_denom(video);
+ libgnac_metadata_add_fraction_value(md, GNAC_TAG_FRAMERATE,
+ rate_num, rate_denom);
+
+ if (gst_discoverer_video_info_is_interlaced(video)) {
+ libgnac_metadata_add_boolean_value(md, GNAC_TAG_INTERLACED, TRUE);
}
- g_object_unref(info);
+ guint par_num = gst_discoverer_video_info_get_par_num(video);
+ guint par_denom = gst_discoverer_video_info_get_par_denom(video);
+ libgnac_metadata_add_fraction_value(md, GNAC_TAG_PAR, par_num, par_denom);
+
+ gst_discoverer_stream_info_list_free(video_info);
}
@@ -576,103 +451,46 @@ libgnac_metadata_extract(LibgnacMetadata *md,
/* make sure we start with a clean base */
libgnac_metadata_reset(md);
- md->priv->uri = g_file_dup(uri);
-
md->priv->metadata = g_hash_table_new_full(g_str_hash, g_str_equal,
NULL, (GDestroyNotify) libgnac_metadata_free_gvalue);
/* store file-size, location and filename */
libgnac_metadata_get_file_info(uri, md);
- GError *metadata_error = NULL;
-
- GstElement *pipeline = libgnac_gstu_pipeline_new(&metadata_error);
- if (metadata_error) {
- g_propagate_error(error, metadata_error);
+ GError *err = NULL;
+ GstDiscoverer *discoverer = gst_discoverer_new(GST_SECOND, &err);
+ if (!discoverer) {
+ libgnac_debug("Failed to create discoverer: %s", err->message);
+ g_propagate_error(error, err);
return NULL;
}
- GstElement *source = libgnac_gstu_make_pipeline_element(pipeline,
- "giosrc", NULL, &metadata_error);
- if (metadata_error) {
- libgnac_debug("source creation failed");
- g_propagate_error(error, metadata_error);
+ GstDiscovererInfo *info = gst_discoverer_discover_uri(discoverer,
+ string_uri, &err);
+ if (!info) {
+ libgnac_debug("Failed to discover: %s", err->message);
+ g_propagate_error(error, err);
return NULL;
}
- g_object_set(G_OBJECT(source), "file", md->priv->uri, NULL);
-
- GstElement *decodebin = libgnac_gstu_make_pipeline_element(pipeline,
- "decodebin2", NULL, &metadata_error);
- if (metadata_error) {
- g_propagate_error(error, metadata_error);
- return NULL;
- }
+ md->priv->info = info;
- md->priv->sink = libgnac_gstu_make_pipeline_element(pipeline,
- "fakesink", NULL, &metadata_error);
- if (metadata_error) {
- g_propagate_error(error, metadata_error);
- return NULL;
+ const GstTagList *taglist = gst_discoverer_info_get_tags(info);
+ if (taglist) {
+ gst_tag_list_foreach(taglist,
+ (GstTagForeachFunc) libgnac_metadata_process_tag, md);
}
- g_signal_connect(decodebin, "autoplug-continue",
- G_CALLBACK(libgnac_metadata_autoplug_continue_cb), md);
- g_signal_connect(decodebin, "pad-added",
- G_CALLBACK(libgnac_metadata_new_decoded_pad_cb), md);
-
- g_return_val_if_fail(
- libgnac_gstu_element_link(source, decodebin, error),
- FALSE);
- md->priv->pipeline = pipeline;
-
- GstBus *bus = gst_element_get_bus(GST_ELEMENT(pipeline));
- gst_bus_set_sync_handler(bus,
- (GstBusSyncHandler) libgnac_metadata_bus_sync_handler, md);
- gst_object_unref(bus);
-
- GstStateChangeReturn state_return = gst_element_set_state(
- md->priv->pipeline, GST_STATE_PAUSED);
+ GstClockTime duration = gst_discoverer_info_get_duration(info);
+ GValue *val = g_new0(GValue, 1);
+ g_value_init(val, G_TYPE_UINT64);
+ /* convert the duration from ns to seconds */
+ g_value_set_uint64(val, duration / GST_SECOND);
+ g_hash_table_insert(md->priv->metadata, GST_TAG_DURATION, val);
- gint timeout_cycle;
- for (timeout_cycle = 0; timeout_cycle < 5; timeout_cycle++) {
- if (state_return != GST_STATE_CHANGE_ASYNC || md->priv->eos) {
- break;
- }
- state_return = gst_element_get_state(md->priv->pipeline,
- NULL, NULL, GST_SECOND);
- }
+ libgnac_metadata_process_audio_info(md);
+ libgnac_metadata_process_video_info(md);
- if ((state_return == GST_STATE_CHANGE_FAILURE) ||
- (state_return == GST_STATE_CHANGE_ASYNC && !md->priv->eos))
- {
- libgnac_debug("An error occured while extracting metadata from file %s",
- string_uri);
- }
- else if (state_return == GST_STATE_CHANGE_SUCCESS) {
- if (!g_hash_table_lookup(md->priv->metadata, GST_TAG_DURATION)) {
- GstFormat format = GST_FORMAT_TIME;
- gint64 length;
- if (gst_element_query_duration(md->priv->sink, &format, &length)) {
- g_assert(format == GST_FORMAT_TIME);
- GValue *newval = g_new0(GValue, 1);
- g_value_init(newval, G_TYPE_UINT64);
- g_value_set_uint64(newval, length/GST_SECOND);
- g_hash_table_insert(md->priv->metadata, GST_TAG_DURATION, newval);
- }
- }
- }
- else if (state_return != GST_STATE_CHANGE_FAILURE) {
- GstBus *message_bus = gst_element_get_bus(md->priv->pipeline);
- if (message_bus) {
- gst_bus_post(message_bus, gst_message_new_application(
- GST_OBJECT(md->priv->pipeline), NULL));
- gst_object_unref(message_bus);
- }
- while (!md->priv->eos);
- }
-
- libgnac_metadata_destroy_pipeline(md);
g_hash_table_insert(md->priv->tags_table, g_strdup(string_uri),
md->priv->metadata);
tags = md->priv->metadata;
@@ -725,45 +543,36 @@ libgnac_metadata_tags_exist(LibgnacTags *tags, ...)
LibgnacTags *
libgnac_metadata_get_dummy_tags(void)
{
+ static LibgnacTags *dummy_tags = NULL;
+
if (!dummy_tags) {
dummy_tags = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
(GDestroyNotify) libgnac_metadata_tags_free);
- GValue *filename = g_new0(GValue, 1);
- g_value_init(filename, G_TYPE_STRING);
- /* Translators: example filename used in the preview label (do not remove the extension) */
- g_value_set_static_string(filename, _("filename.oga"));
- g_hash_table_insert(dummy_tags, GNAC_TAG_FILENAME, filename);
-
- GValue *album = g_new0(GValue, 1);
- g_value_init(album, G_TYPE_STRING);
- g_value_set_static_string(album, "Today!");
- g_hash_table_insert(dummy_tags, GST_TAG_ALBUM, album);
-
- GValue *artist = g_new0(GValue, 1);
- g_value_init(artist, G_TYPE_STRING);
- g_value_set_static_string(artist, "The Beach Boys");
- g_hash_table_insert(dummy_tags, GST_TAG_ARTIST, artist);
-
- GValue *title = g_new0(GValue, 1);
- g_value_init(title, G_TYPE_STRING);
- g_value_set_static_string(title, "Do You Wanna Dance?");
- g_hash_table_insert(dummy_tags, GST_TAG_TITLE, title);
-
- GValue *genre = g_new0(GValue, 1);
- g_value_init(genre, G_TYPE_STRING);
- g_value_set_static_string(genre, "Rock");
- g_hash_table_insert(dummy_tags, GST_TAG_GENRE, genre);
-
- GValue *comment = g_new0(GValue, 1);
- g_value_init(comment, G_TYPE_STRING);
- g_value_set_static_string(comment, _("Converted by Gnac"));
- g_hash_table_insert(dummy_tags, GST_TAG_COMMENT, comment);
-
- GValue *date = g_new0(GValue, 1);
- g_value_init(date, G_TYPE_UINT);
- g_value_set_uint(date, 1965);
- g_hash_table_insert(dummy_tags, GST_TAG_DATE, date);
+ gchar *string_tags[][2] = {
+ { GST_TAG_ALBUM , "Today!" },
+ { GST_TAG_ARTIST , "The Beach Boys" },
+ /* Translators: example filename used in the preview label (do not remove the extension) */
+ { GST_TAG_COMMENT , _("Converted by Gnac") },
+ { GNAC_TAG_FILENAME, _("filename.oga") },
+ { GST_TAG_GENRE , "Rock" },
+ { GST_TAG_TITLE , "Do You Wanna Dance?" },
+ { NULL, NULL }
+ };
+
+ gint i;
+ for (i = 0; string_tags[i][0]; i++) {
+ g_print("%d\n", i);
+ GValue *value = g_new0(GValue, 1);
+ g_value_init(value, G_TYPE_STRING);
+ g_value_set_static_string(value, string_tags[i][1]);
+ g_hash_table_insert(dummy_tags, string_tags[i][0], value);
+ }
+
+ GValue *value = g_new0(GValue, 1);
+ g_value_init(value, G_TYPE_UINT);
+ g_value_set_uint(value, 1965);
+ g_hash_table_insert(dummy_tags, GST_TAG_DATE, value);
GValue *track_count = g_new0(GValue, 1);
g_value_init(track_count, G_TYPE_UINT);
diff --git a/src/gnac-properties.c b/src/gnac-properties.c
index f15a10f..81ea6a1 100644
--- a/src/gnac-properties.c
+++ b/src/gnac-properties.c
@@ -437,7 +437,7 @@ gnac_properties_dup_bitrate(const GValue *value)
static gchar *
gnac_properties_dup_rate(const GValue *value)
{
- gint val = g_value_get_int(value);
+ guint val = g_value_get_uint(value);
if (val == 0) return NULL;
/* Translators: rate */
@@ -459,7 +459,7 @@ gnac_properties_dup_framerate(const GValue *value)
static gchar *
gnac_properties_dup_channels(const GValue *value)
{
- gint val = g_value_get_int(value);
+ guint val = g_value_get_uint(value);
if (val == 0) return NULL;
/* Translators: channels */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]