[gnac] Merged the video part of gnac and gnac-video (libgnac only).
- From: Benoît Dupasquier <bdupasqu src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnac] Merged the video part of gnac and gnac-video (libgnac only).
- Date: Sun, 13 Sep 2009 18:27:02 +0000 (UTC)
commit 1ac2539150e9fb21d3daa099b3e75fb214122d8a
Author: Benoît Dupasquier <bdupasqu src gnome org>
Date: Sun Sep 13 20:26:44 2009 +0200
Merged the video part of gnac and gnac-video (libgnac only).
libgnac/libgnac-converter.c | 66 +++++++++++-
libgnac/libgnac-converter.h | 2 +
libgnac/libgnac-gst.c | 212 +++++++++++++++++++++++++++++++++++----
libgnac/libgnac-gst.h | 7 ++
libgnac/libgnac-metadata-tags.h | 20 ++++
libgnac/libgnac-metadata.c | 88 ++++++++++++----
6 files changed, 347 insertions(+), 48 deletions(-)
---
diff --git a/libgnac/libgnac-converter.c b/libgnac/libgnac-converter.c
index 92eef91..64bc878 100644
--- a/libgnac/libgnac-converter.c
+++ b/libgnac/libgnac-converter.c
@@ -57,7 +57,9 @@ enum
enum
{
PROP_0,
- PROP_PIPELINE_DESC,
+ PROP_AUDIO_PIPELINE_DESC,
+ PROP_MUXER_PIPELINE_DESC,
+ PROP_VIDEO_PIPELINE_DESC,
PROP_STRIP_SPECIAL,
PROP_RENAME_PATTERN,
PROP_FOLDER_HIERARCHY,
@@ -82,6 +84,8 @@ struct LibgnacConverterPrivate
gboolean strip_special;
gchar *audio_description;
+ gchar *muxer_description;
+ gchar *video_description;
gchar *rename_pattern;
gint folder_type;
gchar *folder_hierarchy;
@@ -187,10 +191,18 @@ libgnac_converter_get_property(GObject *object,
switch (property_id)
{
- case PROP_PIPELINE_DESC:
+ case PROP_AUDIO_PIPELINE_DESC:
g_value_set_string(value, self->priv->audio_description);
break;
+ case PROP_MUXER_PIPELINE_DESC:
+ g_value_set_string(value, self->priv->muxer_description);
+ break;
+
+ case PROP_VIDEO_PIPELINE_DESC:
+ g_value_set_string(value, self->priv->video_description);
+ break;
+
case PROP_STRIP_SPECIAL:
g_value_set_boolean(value, self->priv->strip_special);
break;
@@ -237,12 +249,24 @@ libgnac_converter_set_property(GObject *object,
switch (property_id)
{
- case PROP_PIPELINE_DESC:
+ case PROP_AUDIO_PIPELINE_DESC:
g_free(self->priv->audio_description);
self->priv->audio_description = NULL;
self->priv->audio_description = g_value_dup_string(value);
break;
+ case PROP_MUXER_PIPELINE_DESC:
+ g_free(self->priv->muxer_description);
+ self->priv->muxer_description = NULL;
+ self->priv->muxer_description = g_value_dup_string(value);
+ break;
+
+ case PROP_VIDEO_PIPELINE_DESC:
+ g_free(self->priv->video_description);
+ self->priv->video_description = NULL;
+ self->priv->video_description = g_value_dup_string(value);
+ break;
+
case PROP_STRIP_SPECIAL:
self->priv->strip_special = g_value_get_boolean(value);
break;
@@ -308,7 +332,7 @@ libgnac_converter_class_init(LibgnacConverterClass *klass)
gobject_class->set_property = libgnac_converter_set_property;
gobject_class->get_property = libgnac_converter_get_property;
- /* Pipeline desc */
+ /* Audio pipeline desc */
pspec = g_param_spec_string("audio-description",
"Audio pipeline description",
"Audio pipeline description",
@@ -316,7 +340,29 @@ libgnac_converter_class_init(LibgnacConverterClass *klass)
G_PARAM_READWRITE);
g_object_class_install_property(gobject_class,
- PROP_PIPELINE_DESC,
+ PROP_AUDIO_PIPELINE_DESC,
+ pspec);
+
+ /* Muxer pipeline desc */
+ pspec = g_param_spec_string("muxer-description",
+ "Muxer pipeline description",
+ "Muxer pipeline description",
+ NULL,
+ G_PARAM_READWRITE);
+
+ g_object_class_install_property(gobject_class,
+ PROP_MUXER_PIPELINE_DESC,
+ pspec);
+
+ /* Video pipeline desc */
+ pspec = g_param_spec_string("video-description",
+ "Video pipeline description",
+ "Video pipeline description",
+ NULL,
+ G_PARAM_READWRITE);
+
+ g_object_class_install_property(gobject_class,
+ PROP_VIDEO_PIPELINE_DESC,
pspec);
/* Folder hierarchy */
@@ -810,11 +856,19 @@ void
libgnac_converter_item_build(LibgnacConverterItem *item,
GError **error)
{
+ gboolean has_video = FALSE;
GError *err = NULL;
+ LibgnacTags *tags;
+
g_return_if_fail(error == NULL || *error == NULL);
+ /* is it a video file? */
+ tags = libgnac_metadata_extract(metadata, item->source, NULL);
+ if (tags && libgnac_metadata_tag_exists(tags, GNAC_TAG_HAS_VIDEO)) {
+ has_video = TRUE;
+ }
- libgnac_gst_build_pipeline(item, &err);
+ libgnac_gst_build_pipeline(item, has_video, &err);
if (err) {
libgnac_debug("Unable to build pipeline");
libgnac_gst_clean_pipeline(item);
diff --git a/libgnac/libgnac-converter.h b/libgnac/libgnac-converter.h
index e8e6e84..d2f488c 100644
--- a/libgnac/libgnac-converter.h
+++ b/libgnac/libgnac-converter.h
@@ -93,6 +93,8 @@ typedef struct
GFile *destination;
GstElement *pipeline;
GstElement *audio_encoder;
+ GstElement *muxer;
+ GstElement *video_encoder;
GstBus *bus;
guint timeout_id;
gint64 pos;
diff --git a/libgnac/libgnac-gst.c b/libgnac/libgnac-gst.c
index 3d6fe45..a2b6753 100644
--- a/libgnac/libgnac-gst.c
+++ b/libgnac/libgnac-gst.c
@@ -75,10 +75,12 @@ libgnac_gst_stop(LibgnacConverterItem *item,
GstElement *
libgnac_gst_make_pipeline_element(GstElement *bin,
const gchar *element,
+ const gchar *name,
GError **error)
{
GstElement *elem;
- elem = gst_element_factory_make(element, NULL);
+
+ elem = gst_element_factory_make(element, name);
if (!elem) {
libgnac_debug("Failed to create %s element", element);
g_set_error(error,
@@ -89,7 +91,16 @@ libgnac_gst_make_pipeline_element(GstElement *bin,
return NULL;
}
- gst_bin_add(GST_BIN(bin), elem);
+ if (!gst_bin_add(GST_BIN(bin), elem)) {
+ libgnac_debug("Failed to add %s element to the bin", element);
+ g_set_error(error,
+ LIBGNAC_ERROR,
+ LIBGNAC_ERROR_PIPELINE_CREATION,
+ _("Failed to add %s element"),
+ element);
+ return NULL;
+ }
+
return elem;
}
@@ -113,6 +124,29 @@ libgnac_gst_pipeline_new(GError **error)
gboolean
+libgnac_gst_bin_add(GstElement *bin,
+ GstElement *elem,
+ GError **error)
+{
+ gchar *name;
+
+ name = gst_element_get_name(elem);
+
+ if (!gst_bin_add(GST_BIN(bin), elem)) {
+ libgnac_debug("Failed to add %s element to the bin", name);
+ g_set_error(error,
+ LIBGNAC_ERROR,
+ LIBGNAC_ERROR_PIPELINE_CREATION,
+ _("Failed to add %s element"),
+ name);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+gboolean
libgnac_gst_element_link(GstElement *src,
GstElement *dst,
GError **error)
@@ -206,13 +240,14 @@ libgnac_gst_get_audio_bin(LibgnacConverterItem *item,
g_object_get(G_OBJECT(item->converter), "audio-description", &descr, NULL);
- conv = libgnac_gst_make_pipeline_element(bin, "audioconvert", error);
+ conv = libgnac_gst_make_pipeline_element(bin, "audioconvert", NULL, error);
g_return_val_if_fail(conv, NULL);
- resample = libgnac_gst_make_pipeline_element(bin, "audioresample", error);
+ resample = libgnac_gst_make_pipeline_element(bin, "audioresample",
+ NULL, error);
g_return_val_if_fail(resample, NULL);
- rate = libgnac_gst_make_pipeline_element(bin, "audiorate", error);
+ rate = libgnac_gst_make_pipeline_element(bin, "audiorate", NULL, error);
g_return_val_if_fail(rate, NULL);
enc = gst_parse_bin_from_description(descr, TRUE, error);
@@ -236,8 +271,52 @@ libgnac_gst_get_audio_bin(LibgnacConverterItem *item,
}
+static GstElement *
+libgnac_gst_get_video_bin(LibgnacConverterItem *item,
+ GError **error)
+{
+ gchar *descr;
+ GstElement *bin;
+ GstElement *conv;
+ GstElement *enc;
+ GstElement *rate;
+ GstPad *pad;
+
+ bin = gst_bin_new("video_bin");
+
+ g_object_get(G_OBJECT(item->converter), "video-description", &descr, NULL);
+
+ conv = libgnac_gst_make_pipeline_element(bin, "ffmpegcolorspace",
+ NULL, error);
+ g_return_val_if_fail(conv, NULL);
+
+ rate = libgnac_gst_make_pipeline_element(bin, "videorate", NULL, error);
+ g_return_val_if_fail(rate, NULL);
+
+ enc = gst_parse_bin_from_description(descr, TRUE, error);
+ g_free(descr);
+ g_return_val_if_fail(enc && gst_bin_add(GST_BIN(bin), enc), NULL);
+
+ g_return_val_if_fail(
+ gst_element_link_many(conv, rate, enc, NULL),
+ NULL);
+
+ /* ghost pads */
+ pad = gst_element_get_static_pad(conv, "sink");
+ libgnac_gst_element_add_ghost_pad(bin, pad, "video_sink");
+ gst_object_unref(pad);
+
+ pad = gst_element_get_static_pad(enc, "src");
+ libgnac_gst_element_add_ghost_pad(bin, pad, "src");
+ gst_object_unref(pad);
+
+ return bin;
+}
+
+
void
-libgnac_gst_build_pipeline(LibgnacConverterItem *item,
+libgnac_gst_build_pipeline(LibgnacConverterItem *item,
+ gboolean has_video,
GError **error)
{
gboolean linked;
@@ -249,12 +328,14 @@ libgnac_gst_build_pipeline(LibgnacConverterItem *item,
g_return_if_fail(!error || !*error);
+ /* pipeline */
item->pipeline = libgnac_gst_pipeline_new(&encoder_error);
if (encoder_error) {
g_propagate_error(error, encoder_error);
return;
}
+ /* output */
libgnac_output_build_output(item, &encoder_error);
if (encoder_error) {
libgnac_debug("Output creation failed");
@@ -262,10 +343,12 @@ libgnac_gst_build_pipeline(LibgnacConverterItem *item,
return;
}
+ /* bus */
item->bus = gst_element_get_bus(GST_ELEMENT(item->pipeline));
gst_bus_add_signal_watch(item->bus);
- source = libgnac_gst_make_pipeline_element(item->pipeline, "giosrc",
+ /* source */
+ source = libgnac_gst_make_pipeline_element(item->pipeline, "giosrc", NULL,
&encoder_error);
if (encoder_error) {
g_propagate_error(error, encoder_error);
@@ -273,13 +356,22 @@ libgnac_gst_build_pipeline(LibgnacConverterItem *item,
}
g_object_set(G_OBJECT(source), "file", item->source, NULL);
+ /* decodebin */
decodebin = libgnac_gst_make_pipeline_element(item->pipeline, "decodebin",
- &encoder_error);
+ NULL, &encoder_error);
if (encoder_error) {
g_propagate_error(error, encoder_error);
return;
}
+ linked = libgnac_gst_element_link(source, decodebin, &encoder_error);
+ if (encoder_error) {
+ libgnac_debug("link source->decodebin failed");
+ g_propagate_error(error, encoder_error);
+ return;
+ }
+
+ /* audio_bin */
audio_bin = libgnac_gst_get_audio_bin(item, &encoder_error);
if (encoder_error) {
libgnac_debug("audio_bin creation failed");
@@ -288,28 +380,104 @@ libgnac_gst_build_pipeline(LibgnacConverterItem *item,
}
item->audio_encoder = audio_bin;
- gst_bin_add(GST_BIN(item->pipeline), audio_bin);
- sink = libgnac_gst_make_pipeline_element(item->pipeline, "giosink",
- &encoder_error);
+ libgnac_gst_bin_add(item->pipeline, audio_bin, &encoder_error);
if (encoder_error) {
g_propagate_error(error, encoder_error);
return;
}
- g_object_set(G_OBJECT(sink), "file", item->destination, NULL);
- linked = libgnac_gst_element_link(source, decodebin, &encoder_error);
+ /* sink */
+ sink = libgnac_gst_make_pipeline_element(item->pipeline, "giosink", NULL,
+ &encoder_error);
if (encoder_error) {
- libgnac_debug("link source->decodebin failed");
g_propagate_error(error, encoder_error);
return;
}
+ g_object_set(G_OBJECT(sink), "file", item->destination, NULL);
- linked = libgnac_gst_element_link(audio_bin, sink, &encoder_error);
- if (encoder_error) {
- libgnac_debug("link encoder->sink failed");
- g_propagate_error(error, encoder_error);
- return;
+ if (has_video)
+ {
+ gchar *muxer_descr;
+ GstElement *audio_queue;
+ GstElement *mux;
+ GstElement *video_bin;
+ GstElement *video_queue;
+
+ /* muxer */
+ g_object_get(G_OBJECT(item->converter), "muxer-description",
+ &muxer_descr, NULL);
+ mux = libgnac_gst_make_pipeline_element(item->pipeline, muxer_descr,
+ NULL, &encoder_error);
+ g_free(muxer_descr);
+ if (encoder_error) {
+ g_propagate_error(error, encoder_error);
+ return;
+ }
+ item->muxer = mux;
+
+ linked = libgnac_gst_element_link(mux, sink, &encoder_error);
+ if (encoder_error) {
+ libgnac_debug("link encoder->sink failed");
+ g_propagate_error(error, encoder_error);
+ return;
+ }
+
+ /* audio */
+ audio_queue = libgnac_gst_make_pipeline_element(item->pipeline, "queue",
+ "audio_queue", &encoder_error);
+ if (encoder_error) {
+ g_propagate_error(error, encoder_error);
+ return;
+ }
+ item->audio_encoder = audio_queue;
+
+ if (!gst_element_link_many(audio_queue, audio_bin, mux, NULL)) {
+ g_set_error(error,
+ LIBGNAC_ERROR,
+ LIBGNAC_ERROR_PIPELINE_CREATION,
+ _("Failed to link many audio elements"));
+ return;
+ }
+
+ /* video */
+ video_queue = libgnac_gst_make_pipeline_element(item->pipeline, "queue",
+ "video_queue", &encoder_error);
+ if (encoder_error) {
+ g_propagate_error(error, encoder_error);
+ return;
+ }
+ item->video_encoder = video_queue;
+
+ video_bin = libgnac_gst_get_video_bin(item, &encoder_error);
+ if (encoder_error) {
+ libgnac_debug("video_bin creation failed");
+ g_propagate_error(error, encoder_error);
+ return;
+ }
+
+ libgnac_gst_bin_add(item->pipeline, video_bin, &encoder_error);
+ if (encoder_error) {
+ g_propagate_error(error, encoder_error);
+ return;
+ }
+
+ if (!gst_element_link_many(video_queue, video_bin, mux, NULL)) {
+ g_set_error(error,
+ LIBGNAC_ERROR,
+ LIBGNAC_ERROR_PIPELINE_CREATION,
+ _("Failed to link many video elements"));
+ return;
+ }
+ }
+ else /* audio file */
+ {
+ linked = libgnac_gst_element_link(audio_bin, sink, &encoder_error);
+ if (encoder_error) {
+ libgnac_debug("link encoder->sink failed");
+ g_propagate_error(error, encoder_error);
+ return;
+ }
}
/* Connect callbacks */
@@ -382,7 +550,11 @@ libgnac_gst_newpad_cb(GstElement *decodebin,
return;
}
} else if (g_str_has_prefix(mimetype, "video/")) {
- /* contains video data */
+ if (!libgnac_gst_get_compatible_pad(item->video_encoder, pad,
+ caps, "video"))
+ {
+ return;
+ }
} else {
/* unhandled mimetype */
}
diff --git a/libgnac/libgnac-gst.h b/libgnac/libgnac-gst.h
index df99b03..48ff54e 100644
--- a/libgnac/libgnac-gst.h
+++ b/libgnac/libgnac-gst.h
@@ -53,6 +53,7 @@ libgnac_gst_pause(LibgnacConverterItem *item,
void
libgnac_gst_build_pipeline(LibgnacConverterItem *item,
+ gboolean has_video,
GError **error);
void
@@ -61,6 +62,7 @@ libgnac_gst_clean_pipeline(LibgnacConverterItem *item);
GstElement *
libgnac_gst_make_pipeline_element(GstElement *bin,
const gchar *element,
+ const gchar *name,
GError **error);
GstPadLinkReturn
@@ -72,6 +74,11 @@ GstElement *
libgnac_gst_pipeline_new(GError **error);
gboolean
+libgnac_gst_bin_add(GstElement *bin,
+ GstElement *elem,
+ GError **error);
+
+gboolean
libgnac_gst_element_link(GstElement *src,
GstElement *dst,
GError **error);
diff --git a/libgnac/libgnac-metadata-tags.h b/libgnac/libgnac-metadata-tags.h
index 9cc8bc9..9d70d2d 100644
--- a/libgnac/libgnac-metadata-tags.h
+++ b/libgnac/libgnac-metadata-tags.h
@@ -38,8 +38,12 @@ typedef GHashTable LibgnacTags;
#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_VIDEO "has-video"
+#define GNAC_TAG_HEIGHT "height"
#define GNAC_TAG_MODE "mode"
#define GNAC_TAG_RATE "rate"
+#define GNAC_TAG_WIDTH "width"
#define LIBGNAC_METADATA_TAG_IS_ALBUM(tag) \
(g_str_equal((tag), GST_TAG_ALBUM))
@@ -65,8 +69,14 @@ typedef GHashTable LibgnacTags;
(g_str_equal((tag), GNAC_TAG_FILE_SIZE))
#define LIBGNAC_METADATA_TAG_IS_FILENAME(tag) \
(g_str_equal((tag), GNAC_TAG_FILENAME))
+#define LIBGNAC_METADATA_TAG_IS_FRAMERATE(tag) \
+ (g_str_equal((tag), GNAC_TAG_FRAMERATE))
#define LIBGNAC_METADATA_TAG_IS_GENRE(tag) \
(g_str_equal((tag), GST_TAG_GENRE))
+#define LIBGNAC_METADATA_TAG_IS_HAS_VIDEO(tag) \
+ (g_str_equal((tag), GNAC_TAG_HAS_VIDEO))
+#define LIBGNAC_METADATA_TAG_IS_HEIGHT(tag) \
+ (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_LOCATION(tag) \
@@ -85,6 +95,8 @@ typedef GHashTable LibgnacTags;
(g_str_equal((tag), GST_TAG_TRACK_GAIN))
#define LIBGNAC_METADATA_TAG_IS_TRACK_PEAK(tag) \
(g_str_equal((tag), GST_TAG_TRACK_PEAK))
+#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))
@@ -110,8 +122,14 @@ typedef GHashTable LibgnacTags;
(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))
+#define LIBGNAC_METADATA_TAG_FRAMERATE(tags) \
+ (g_hash_table_lookup((GHashTable*)(tags), GNAC_TAG_FRAMERATE))
#define LIBGNAC_METADATA_TAG_GENRE(tags) \
(g_hash_table_lookup((GHashTable*)(tags), GST_TAG_GENRE))
+#define LIBGNAC_METADATA_TAG_HAS_VIDEO(tags) \
+ (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))
#define LIBGNAC_METADATA_TAG_IMAGE(tags) \
(g_hash_table_lookup((GHashTable*)(tags), GST_TAG_IMAGE))
#define LIBGNAC_METADATA_TAG_LOCATION(tags) \
@@ -126,6 +144,8 @@ typedef GHashTable LibgnacTags;
(g_hash_table_lookup((GHashTable*)(tags), GST_TAG_TRACK_COUNT))
#define LIBGNAC_METADATA_TAG_TRACK_NUMBER(tags) \
(g_hash_table_lookup((GHashTable*)(tags), GST_TAG_TRACK_NUMBER))
+#define LIBGNAC_METADATA_TAG_WIDTH(tags) \
+ (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 cd5af07..48076b5 100644
--- a/libgnac/libgnac-metadata.c
+++ b/libgnac/libgnac-metadata.c
@@ -54,6 +54,7 @@ struct LibgnacMetadataPrivate
LibgnacTags *metadata;
gboolean eos;
+
GError *error;
};
@@ -255,6 +256,50 @@ libgnac_metadata_process_tag_image(const GstTagList *taglist,
static void
+libgnac_metadata_process_tag_value(GstStructure *structure,
+ gchar *tag_name,
+ LibgnacMetadata *md)
+{
+ const GValue *val;
+ val = gst_structure_get_value(structure, tag_name);
+ if (val)
+ {
+ if (GST_VALUE_HOLDS_FRACTION(val))
+ {
+ GValue *newval;
+ gint numerator;
+ gint denominator;
+
+ numerator = gst_value_get_fraction_numerator(val);
+ denominator = gst_value_get_fraction_denominator(val);
+
+ 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;
+ 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,
LibgnacMetadata *md)
@@ -446,11 +491,17 @@ libgnac_metadata_new_decoded_pad_cb(GstElement *element,
structure = gst_caps_get_structure(caps, 0);
mimetype = gst_structure_get_name(structure);
- if (!g_strrstr(mimetype, "audio"))
+ if (g_str_has_prefix(mimetype, "video"))
{
- gst_caps_unref(caps);
- gst_object_unref(sink_pad);
- return;
+ GValue *val;
+ 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"))
+ {
+ libgnac_debug("Got a non audio or video pad: %s", mimetype);
}
gst_caps_unref(caps);
@@ -464,8 +515,7 @@ libgnac_metadata_autoplug_continue_cb(GstElement *decodebin,
GstCaps *caps,
LibgnacMetadata *md)
{
- gint rate, channels;
- GValue *rate_value, *channels_value;
+ const gchar *mimetype;
GstStructure *structure;
g_return_val_if_fail(LIBGNAC_IS_METADATA(md), TRUE);
@@ -473,21 +523,15 @@ libgnac_metadata_autoplug_continue_cb(GstElement *decodebin,
if (!gst_caps_is_fixed(caps)) return TRUE;
structure = gst_caps_get_structure(caps, 0);
+ mimetype = gst_structure_get_name(structure);
- /* sample rate */
- if (gst_structure_get_int(structure, GNAC_TAG_RATE, &rate)) {
- rate_value = g_new0(GValue, 1);
- g_value_init(rate_value, G_TYPE_INT);
- g_value_set_int(rate_value, rate);
- g_hash_table_insert(md->priv->metadata, GNAC_TAG_RATE, rate_value);
- }
+ libgnac_metadata_process_tag_int(structure, GNAC_TAG_RATE, md);
+ libgnac_metadata_process_tag_int(structure, GNAC_TAG_CHANNELS, md);
- /* channels */
- if (gst_structure_get_int(structure, GNAC_TAG_CHANNELS, &channels)) {
- channels_value = g_new0(GValue, 1);
- g_value_init(channels_value, G_TYPE_INT);
- g_value_set_int(channels_value, channels);
- g_hash_table_insert(md->priv->metadata, GNAC_TAG_CHANNELS, channels_value);
+ 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;
@@ -578,7 +622,7 @@ libgnac_metadata_extract(LibgnacMetadata *md,
}
source = libgnac_gst_make_pipeline_element(pipeline, "giosrc",
- &metadata_error);
+ NULL, &metadata_error);
if (metadata_error) {
libgnac_debug("source creation failed");
g_propagate_error(error, metadata_error);
@@ -587,14 +631,14 @@ libgnac_metadata_extract(LibgnacMetadata *md,
g_object_set(G_OBJECT(source), "file", md->priv->uri, NULL);
decodebin = libgnac_gst_make_pipeline_element(pipeline, "decodebin2",
- &metadata_error);
+ NULL, &metadata_error);
if (metadata_error) {
g_propagate_error(error, metadata_error);
return NULL;
}
md->priv->sink = libgnac_gst_make_pipeline_element(pipeline, "fakesink",
- &metadata_error);
+ NULL, &metadata_error);
if (metadata_error) {
g_propagate_error(error, metadata_error);
return NULL;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]