aboutsummaryrefslogtreecommitdiff
path: root/gst
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian.droege@collabora.co.uk>2012-06-08 09:16:25 +0200
committerSebastian Dröge <sebastian.droege@collabora.co.uk>2012-06-08 09:16:25 +0200
commitbed72dff4210fac83b878ac3b0f3ecb78d30d1d2 (patch)
tree9dd932b51f35262b1051648bb79e174f72d275da /gst
parent50f12103f5a136f45bd274ac6a99006a3db5ca4d (diff)
Imported Upstream version 0.11.92upstream/0.11.92
Diffstat (limited to 'gst')
-rw-r--r--gst/Makefile.in9
-rw-r--r--gst/gst.c3
-rw-r--r--gst/gst_private.h47
-rw-r--r--gst/gstbin.c94
-rw-r--r--gst/gstcaps.c2
-rw-r--r--gst/gstcompat.h2
-rw-r--r--gst/gstdebugutils.c2
-rw-r--r--gst/gstelement.c48
-rw-r--r--gst/gstelementfactory.c34
-rw-r--r--gst/gstelementfactory.h41
-rw-r--r--gst/gstevent.c36
-rw-r--r--gst/gstevent.h6
-rw-r--r--gst/gstmessage.c24
-rw-r--r--gst/gstpad.c139
-rw-r--r--gst/gstpad.h20
-rw-r--r--gst/gstpluginfeature.c20
-rw-r--r--gst/gstpluginfeature.h33
-rw-r--r--gst/gstquark.c6
-rw-r--r--gst/gstquark.h14
-rw-r--r--gst/gstquery.c6
-rw-r--r--gst/gstregistry.c2
-rw-r--r--gst/gststructure.c2
-rw-r--r--gst/gsttaglist.c446
-rw-r--r--gst/gsttaglist.h123
-rw-r--r--gst/gsttagsetter.c4
-rw-r--r--gst/gsttoc.c271
-rw-r--r--gst/gsttoc.h10
-rw-r--r--gst/gsturi.c3
-rw-r--r--gst/gstutils.c7
-rw-r--r--gst/parse/Makefile.in9
30 files changed, 914 insertions, 549 deletions
diff --git a/gst/Makefile.in b/gst/Makefile.in
index 008347b..2e6f45d 100644
--- a/gst/Makefile.in
+++ b/gst/Makefile.in
@@ -53,6 +53,7 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
+target_triplet = @target@
@HAVE_INTROSPECTION_TRUE@am__append_1 = $(BUILT_GIRSOURCES) $(typelibs_DATA)
subdir = gst
DIST_COMMON = $(libgstreamer_@GST_API_VERSION@include_HEADERS) \
@@ -412,6 +413,10 @@ GST_VERSION_MICRO = @GST_VERSION_MICRO@
GST_VERSION_MINOR = @GST_VERSION_MINOR@
GST_VERSION_NANO = @GST_VERSION_NANO@
GTKDOC_CHECK = @GTKDOC_CHECK@
+GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
+GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
+GTKDOC_MKPDF = @GTKDOC_MKPDF@
+GTKDOC_REBASE = @GTKDOC_REBASE@
HAVE_DOCBOOK2HTML = @HAVE_DOCBOOK2HTML@
HAVE_DOCBOOK2PS = @HAVE_DOCBOOK2PS@
HAVE_DVIPS = @HAVE_DVIPS@
@@ -564,7 +569,11 @@ sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
+target = @target@
target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
diff --git a/gst/gst.c b/gst/gst.c
index d78e9ce..96c20b5 100644
--- a/gst/gst.c
+++ b/gst/gst.c
@@ -139,7 +139,7 @@ extern gboolean _priv_gst_disable_registry_update;
#endif
#ifndef GST_DISABLE_GST_DEBUG
-extern const gchar *priv_gst_dump_dot_dir;
+const gchar *priv_gst_dump_dot_dir;
#endif
/* defaults */
@@ -746,7 +746,6 @@ init_post (GOptionContext * context, GOptionGroup * group, gpointer data,
g_type_class_ref (gst_param_spec_fraction_get_type ());
_priv_gst_tag_initialize ();
- _priv_gst_toc_initialize ();
gst_parse_context_get_type ();
_priv_gst_plugin_initialize ();
diff --git a/gst/gst_private.h b/gst/gst_private.h
index f44c6f3..c15c8fa 100644
--- a/gst/gst_private.h
+++ b/gst/gst_private.h
@@ -113,7 +113,6 @@ void _priv_gst_sample_initialize (void);
void _priv_gst_tag_initialize (void);
void _priv_gst_value_initialize (void);
void _priv_gst_debug_init (void);
-void _priv_gst_toc_initialize (void);
/* TOC functions */
/* These functions are used to parse TOC messages, events and queries */
@@ -296,6 +295,27 @@ struct _GstPluginClass {
gpointer _gst_reserved[GST_PADDING];
};
+struct _GstPluginFeature {
+ GstObject object;
+
+ /*< private >*/
+ gboolean loaded;
+ guint rank;
+
+ const gchar *plugin_name;
+ GstPlugin *plugin; /* weak ref */
+
+ /*< private >*/
+ gpointer _gst_reserved[GST_PADDING];
+};
+
+struct _GstPluginFeatureClass {
+ GstObjectClass parent_class;
+
+ /*< private >*/
+ gpointer _gst_reserved[GST_PADDING];
+};
+
#include "gsttypefind.h"
struct _GstTypeFindFactory {
@@ -319,6 +339,31 @@ struct _GstTypeFindFactoryClass {
gpointer _gst_reserved[GST_PADDING];
};
+struct _GstElementFactory {
+ GstPluginFeature parent;
+
+ GType type; /* unique GType of element or 0 if not loaded */
+
+ gpointer metadata;
+
+ GList * staticpadtemplates; /* GstStaticPadTemplate list */
+ guint numpadtemplates;
+
+ /* URI interface stuff */
+ GstURIType uri_type;
+ gchar ** uri_protocols;
+
+ GList * interfaces; /* interface type names this element implements */
+
+ /*< private >*/
+ gpointer _gst_reserved[GST_PADDING];
+};
+
+struct _GstElementFactoryClass {
+ GstPluginFeatureClass parent_class;
+
+ gpointer _gst_reserved[GST_PADDING];
+};
G_END_DECLS
#endif /* __GST_PRIVATE_H__ */
diff --git a/gst/gstbin.c b/gst/gstbin.c
index 665259e..d5ce5f6 100644
--- a/gst/gstbin.c
+++ b/gst/gstbin.c
@@ -2152,7 +2152,7 @@ gst_bin_element_set_state (GstBin * bin, GstElement * element,
GstState next)
{
GstStateChangeReturn ret;
- GstState pending, child_current, child_pending;
+ GstState child_current, child_pending;
gboolean locked;
GList *found;
@@ -2182,17 +2182,76 @@ gst_bin_element_set_state (GstBin * bin, GstElement * element,
goto no_preroll;
}
- GST_OBJECT_LOCK (bin);
- pending = GST_STATE_PENDING (bin);
+ GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
+ "current %s pending %s, desired next %s",
+ gst_element_state_get_name (child_current),
+ gst_element_state_get_name (child_pending),
+ gst_element_state_get_name (next));
/* Try not to change the state of elements that are already in the state we're
* going to */
- if (!(next == GST_STATE_PLAYING || child_pending != GST_STATE_VOID_PENDING ||
- (child_pending == GST_STATE_VOID_PENDING &&
- ((pending > child_current && next > child_current) ||
- (pending < child_current && next < child_current)))))
+ if (child_current == next && child_pending == GST_STATE_VOID_PENDING) {
+ /* child is already at the requested state, return previous return. Note that
+ * if the child has a pending state to next, we will still call the
+ * set_state function */
goto unneeded;
+ } else if (next > current) {
+ /* upward state change */
+ if (child_pending == GST_STATE_VOID_PENDING) {
+ /* .. and the child is not busy doing anything */
+ if (child_current > next) {
+ /* .. and is already past the requested state, assume it got there
+ * without error */
+ ret = GST_STATE_CHANGE_SUCCESS;
+ goto unneeded;
+ }
+ } else if (child_pending > child_current) {
+ /* .. and the child is busy going upwards */
+ if (child_current >= next) {
+ /* .. and is already past the requested state, assume it got there
+ * without error */
+ ret = GST_STATE_CHANGE_SUCCESS;
+ goto unneeded;
+ }
+ } else {
+ /* .. and the child is busy going downwards */
+ if (child_current > next) {
+ /* .. and is already past the requested state, assume it got there
+ * without error */
+ ret = GST_STATE_CHANGE_SUCCESS;
+ goto unneeded;
+ }
+ }
+ } else if (next < current) {
+ /* downward state change */
+ if (child_pending == GST_STATE_VOID_PENDING) {
+ /* .. and the child is not busy doing anything */
+ if (child_current < next) {
+ /* .. and is already past the requested state, assume it got there
+ * without error */
+ ret = GST_STATE_CHANGE_SUCCESS;
+ goto unneeded;
+ }
+ } else if (child_pending < child_current) {
+ /* .. and the child is busy going downwards */
+ if (child_current <= next) {
+ /* .. and is already past the requested state, assume it got there
+ * without error */
+ ret = GST_STATE_CHANGE_SUCCESS;
+ goto unneeded;
+ }
+ } else {
+ /* .. and the child is busy going upwards */
+ if (child_current < next) {
+ /* .. and is already past the requested state, assume it got there
+ * without error */
+ ret = GST_STATE_CHANGE_SUCCESS;
+ goto unneeded;
+ }
+ }
+ }
+ GST_OBJECT_LOCK (bin);
/* the element was busy with an upwards async state change, we must wait for
* an ASYNC_DONE message before we attemp to change the state. */
if ((found =
@@ -2234,25 +2293,22 @@ locked:
GST_STATE_UNLOCK (element);
return ret;
}
-was_busy:
- {
- GST_DEBUG_OBJECT (element, "element was busy, delaying state change");
- GST_OBJECT_UNLOCK (bin);
- GST_STATE_UNLOCK (element);
- return GST_STATE_CHANGE_ASYNC;
- }
unneeded:
{
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
- "skipping transition from %s to %s, since bin pending"
- " is %s : last change state return follows",
+ "skipping transition from %s to %s",
gst_element_state_get_name (child_current),
- gst_element_state_get_name (next),
- gst_element_state_get_name (pending));
- GST_OBJECT_UNLOCK (bin);
+ gst_element_state_get_name (next));
GST_STATE_UNLOCK (element);
return ret;
}
+was_busy:
+ {
+ GST_DEBUG_OBJECT (element, "element was busy, delaying state change");
+ GST_OBJECT_UNLOCK (bin);
+ GST_STATE_UNLOCK (element);
+ return GST_STATE_CHANGE_ASYNC;
+ }
}
/* gst_iterator_fold functions for pads_activate
diff --git a/gst/gstcaps.c b/gst/gstcaps.c
index 2f4a341..ec95ed5 100644
--- a/gst/gstcaps.c
+++ b/gst/gstcaps.c
@@ -177,7 +177,7 @@ _gst_caps_free (GstCaps * caps)
g_ptr_array_free (GST_CAPS_ARRAY (caps), TRUE);
#ifdef DEBUG_REFCOUNT
- GST_CAT_LOG (GST_CAT_CAPS, "freeing caps %p", caps);
+ GST_CAT_TRACE (GST_CAT_CAPS, "freeing caps %p", caps);
#endif
g_slice_free1 (GST_MINI_OBJECT_SIZE (caps), caps);
}
diff --git a/gst/gstcompat.h b/gst/gstcompat.h
index a35c6ce..97728f4 100644
--- a/gst/gstcompat.h
+++ b/gst/gstcompat.h
@@ -56,6 +56,8 @@ G_BEGIN_DECLS
#define gst_adapter_prev_timestamp gst_adapter_prev_pts
+#define gst_tag_list_free(taglist) gst_tag_list_unref(taglist)
+
#ifndef GST_DISABLE_DEPRECATED
#endif /* not GST_DISABLE_DEPRECATED */
diff --git a/gst/gstdebugutils.c b/gst/gstdebugutils.c
index 8e31bde..e67a77c 100644
--- a/gst/gstdebugutils.c
+++ b/gst/gstdebugutils.c
@@ -54,7 +54,7 @@
/*** PIPELINE GRAPHS **********************************************************/
-const gchar *priv_gst_dump_dot_dir; /* NULL *//* set from gst.c */
+extern const gchar *priv_gst_dump_dot_dir; /* NULL *//* set from gst.c */
const gchar spaces[] = {
" " /* 32 */
diff --git a/gst/gstelement.c b/gst/gstelement.c
index b3366f4..2962830 100644
--- a/gst/gstelement.c
+++ b/gst/gstelement.c
@@ -325,7 +325,7 @@ gst_element_release_request_pad (GstElement * element, GstPad * pad)
/* if the element implements a custom release function we call that, else we
* simply remove the pad from the element */
if (oclass->release_pad)
- (oclass->release_pad) (element, pad);
+ oclass->release_pad (element, pad);
else
gst_element_remove_pad (element, pad);
}
@@ -1523,9 +1523,10 @@ gst_element_default_send_event (GstElement * element, GstEvent * event)
* This function takes owership of the provided event so you should
* gst_event_ref() it if you want to reuse the event after this call.
*
- * Returns: %TRUE if the event was handled.
- *
* MT safe.
+ *
+ * Returns: %TRUE if the event was handled. Events that trigger a preroll (such
+ * as flushing seeks and steps) will emit %GST_MESSAGE_ASYNC_DONE.
*/
gboolean
gst_element_send_event (GstElement * element, GstEvent * event)
@@ -1564,9 +1565,10 @@ gst_element_send_event (GstElement * element, GstEvent * event)
* the parameters. The seek event is sent to the element using
* gst_element_send_event().
*
- * Returns: %TRUE if the event was handled.
- *
* MT safe.
+ *
+ * Returns: %TRUE if the event was handled. Flushing seeks will trigger a
+ * preroll, which will emit %GST_MESSAGE_ASYNC_DONE.
*/
gboolean
gst_element_seek (GstElement * element, gdouble rate, GstFormat format,
@@ -2826,6 +2828,7 @@ gst_element_dispose (GObject * object)
GstClock **clock_p;
GstBus **bus_p;
GstElementClass *oclass;
+ GList *walk;
oclass = GST_ELEMENT_GET_CLASS (element);
@@ -2834,23 +2837,32 @@ gst_element_dispose (GObject * object)
if (GST_STATE (element) != GST_STATE_NULL)
goto not_null;
- GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
- "removing %d pads", g_list_length (element->pads));
- /* first we break all our links with the outside */
- while (element->pads && element->pads->data) {
- GstPad *pad = GST_PAD_CAST (element->pads->data);
+ /* start by releasing all request pads, this might also remove some dynamic
+ * pads */
+ walk = element->pads;
+ while (walk) {
+ GstPad *pad = GST_PAD_CAST (walk->data);
+
+ walk = walk->next;
- /* don't call _remove_pad with NULL */
if (oclass->release_pad && GST_PAD_PAD_TEMPLATE (pad) &&
GST_PAD_TEMPLATE_PRESENCE (GST_PAD_PAD_TEMPLATE (pad))
- == GST_PAD_REQUEST)
- (oclass->release_pad) (element, GST_PAD_CAST (element->pads->data));
- else
- gst_element_remove_pad (element, GST_PAD_CAST (element->pads->data));
+ == GST_PAD_REQUEST) {
+ GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
+ "removing request pad %s:%s", GST_DEBUG_PAD_NAME (pad));
+ oclass->release_pad (element, pad);
+ }
}
- if (G_UNLIKELY (element->pads != NULL)) {
- g_critical ("could not remove pads from element %s",
- GST_STR_NULL (GST_OBJECT_NAME (object)));
+ /* remove the remaining pads */
+ while (element->pads) {
+ GstPad *pad = GST_PAD_CAST (element->pads->data);
+ GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
+ "removing pad %s:%s", GST_DEBUG_PAD_NAME (pad));
+ if (!gst_element_remove_pad (element, pad)) {
+ /* only happens when someone unparented our pad.. */
+ g_critical ("failed to remove pad %s:%s", GST_DEBUG_PAD_NAME (pad));
+ break;
+ }
}
GST_OBJECT_LOCK (element);
diff --git a/gst/gstelementfactory.c b/gst/gstelementfactory.c
index b11abfc..a8ef9fe 100644
--- a/gst/gstelementfactory.c
+++ b/gst/gstelementfactory.c
@@ -510,6 +510,40 @@ gst_element_factory_get_metadata (GstElementFactory * factory,
}
/**
+ * gst_element_factory_get_metadata_keys:
+ * @factory,: a #GstElementFactory
+ *
+ * Get the available keys for the metadata on @factory.
+ *
+ * Returns: a %NULL-terminated array of key strings, or %NULL when
+ * there is no metadata. Free with g_strfreev() when no longer needd.
+ */
+gchar **
+gst_element_factory_get_metadata_keys (GstElementFactory * factory)
+{
+ GstStructure *metadata;
+ gchar **arr;
+ gint i, num;
+
+ g_return_val_if_fail (GST_IS_ELEMENT_FACTORY (factory), NULL);
+
+ metadata = (GstStructure *) factory->metadata;
+ if (metadata == NULL)
+ return NULL;
+
+ num = gst_structure_n_fields (metadata);
+ if (num == 0)
+ return NULL;
+
+ arr = g_new (gchar *, num + 1);
+ for (i = 0; i < num; ++i) {
+ arr[i] = g_strdup (gst_structure_nth_field_name (metadata, i));
+ }
+ arr[i] = NULL;
+ return arr;
+}
+
+/**
* gst_element_factory_get_num_pad_templates:
* @factory: a #GstElementFactory
*
diff --git a/gst/gstelementfactory.h b/gst/gstelementfactory.h
index b2dff92..601c9d6 100644
--- a/gst/gstelementfactory.h
+++ b/gst/gstelementfactory.h
@@ -24,16 +24,19 @@
#ifndef __GST_ELEMENT_FACTORY_H__
#define __GST_ELEMENT_FACTORY_H__
+/**
+ * GstElementFactory:
+ *
+ * The opaque #GstElementFactory data structure.
+ */
typedef struct _GstElementFactory GstElementFactory;
typedef struct _GstElementFactoryClass GstElementFactoryClass;
#include <gst/gstconfig.h>
#include <gst/gstelement.h>
-#include <gst/gstobject.h>
+#include <gst/gstpad.h>
#include <gst/gstplugin.h>
#include <gst/gstpluginfeature.h>
-#include <gst/gstpadtemplate.h>
-#include <gst/gstiterator.h>
#include <gst/gsturi.h>
G_BEGIN_DECLS
@@ -47,37 +50,6 @@ G_BEGIN_DECLS
#define GST_IS_ELEMENT_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ELEMENT_FACTORY))
#define GST_ELEMENT_FACTORY_CAST(obj) ((GstElementFactory *)(obj))
-/**
- * GstElementFactory:
- *
- * The opaque #GstElementFactory data structure.
- */
-struct _GstElementFactory {
- GstPluginFeature parent;
-
- GType type; /* unique GType of element or 0 if not loaded */
-
- gpointer metadata;
-
- GList * staticpadtemplates; /* GstStaticPadTemplate list */
- guint numpadtemplates;
-
- /* URI interface stuff */
- GstURIType uri_type;
- gchar ** uri_protocols;
-
- GList * interfaces; /* interface type names this element implements */
-
- /*< private >*/
- gpointer _gst_reserved[GST_PADDING];
-};
-
-struct _GstElementFactoryClass {
- GstPluginFeatureClass parent_class;
-
- gpointer _gst_reserved[GST_PADDING];
-};
-
GType gst_element_factory_get_type (void);
GstElementFactory * gst_element_factory_find (const gchar *name);
@@ -85,6 +57,7 @@ GstElementFactory * gst_element_factory_find (const gchar *na
GType gst_element_factory_get_element_type (GstElementFactory *factory);
const gchar * gst_element_factory_get_metadata (GstElementFactory *factory, const gchar *key);
+gchar ** gst_element_factory_get_metadata_keys (GstElementFactory *factory);
guint gst_element_factory_get_num_pad_templates (GstElementFactory *factory);
const GList * gst_element_factory_get_static_pad_templates (GstElementFactory *factory);
diff --git a/gst/gstevent.c b/gst/gstevent.c
index e496f40..3ba388a 100644
--- a/gst/gstevent.c
+++ b/gst/gstevent.c
@@ -992,19 +992,30 @@ gst_event_copy_segment (GstEvent * event, GstSegment * segment)
/**
* gst_event_new_tag:
+ * @name: (transfer none): the name of the event
* @taglist: (transfer full): metadata list. The event will take ownership
* of the taglist.
*
* Generates a metadata tag event from the given @taglist.
*
+ * Since the TAG event has the %GST_EVENT_TYPE_STICKY_MULTI flag set, the
+ * @name will be used to keep track of multiple tag events.
+ *
* Returns: (transfer full): a new #GstEvent
*/
GstEvent *
-gst_event_new_tag (GstTagList * taglist)
+gst_event_new_tag (const gchar * name, GstTagList * taglist)
{
+ GstStructure *s;
+ GValue val = G_VALUE_INIT;
+
g_return_val_if_fail (taglist != NULL, NULL);
- return gst_event_new_custom (GST_EVENT_TAG, (GstStructure *) taglist);
+ s = gst_structure_new_empty (name);
+ g_value_init (&val, GST_TYPE_TAG_LIST);
+ g_value_take_boxed (&val, taglist);
+ gst_structure_id_take_value (s, GST_QUARK (TAGLIST), &val);
+ return gst_event_new_custom (GST_EVENT_TAG, s);
}
/**
@@ -1020,11 +1031,16 @@ gst_event_new_tag (GstTagList * taglist)
void
gst_event_parse_tag (GstEvent * event, GstTagList ** taglist)
{
+ const GValue *val;
+
g_return_if_fail (GST_IS_EVENT (event));
g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_TAG);
+ val = gst_structure_id_get_value (GST_EVENT_STRUCTURE (event),
+ GST_QUARK (TAGLIST));
+
if (taglist)
- *taglist = (GstTagList *) GST_EVENT_STRUCTURE (event);
+ *taglist = (GstTagList *) g_value_get_boxed (val);
}
/* buffersize event */
@@ -1252,13 +1268,13 @@ gst_event_parse_qos (GstEvent * event, GstQOSType * type,
* from the newly configured start position.
*
* For negative rates, playback will start from the newly configured stop
- * position (if any). If the stop position if updated, it must be different from
- * -1 for negative rates.
+ * position (if any). If the stop position is updated, it must be different from
+ * -1 (#GST_CLOCK_TIME_NONE) for negative rates.
*
* It is not possible to seek relative to the current playback position, to do
* this, PAUSE the pipeline, query the current playback position with
* #GST_QUERY_POSITION and update the playback segment current position with a
- * #GST_SEEK_TYPE_SET to the desired position.
+ * #GST_SEEK_TYPE_SET to the desired position.
*
* Returns: (transfer full): a new seek event.
*/
@@ -1539,19 +1555,22 @@ gst_event_new_reconfigure (void)
/**
* gst_event_new_sink_message:
+ * @name: a name for the event
* @msg: (transfer none): the #GstMessage to be posted
*
* Create a new sink-message event. The purpose of the sink-message event is
* to instruct a sink to post the message contained in the event synchronized
* with the stream.
*
+ * @name is used to store multiple sticky events on one pad.
+ *
* Returns: (transfer full): a new #GstEvent
*
* Since: 0.10.26
*/
/* FIXME 0.11: take ownership of msg for consistency? */
GstEvent *
-gst_event_new_sink_message (GstMessage * msg)
+gst_event_new_sink_message (const gchar * name, GstMessage * msg)
{
GstEvent *event;
GstStructure *structure;
@@ -1560,7 +1579,7 @@ gst_event_new_sink_message (GstMessage * msg)
GST_CAT_INFO (GST_CAT_EVENT, "creating sink-message event");
- structure = gst_structure_new_id (GST_QUARK (EVENT_SINK_MESSAGE),
+ structure = gst_structure_new_id (g_quark_from_string (name),
GST_QUARK (MESSAGE), GST_TYPE_MESSAGE, msg, NULL);
event = gst_event_new_custom (GST_EVENT_SINK_MESSAGE, structure);
@@ -1615,6 +1634,7 @@ gst_event_new_stream_start (void)
/**
* gst_event_new_toc:
+ * @name: a name for the event
* @toc: #GstToc structure.
* @updated: whether @toc was updated or not.
*
diff --git a/gst/gstevent.h b/gst/gstevent.h
index b8609e9..35ebba8 100644
--- a/gst/gstevent.h
+++ b/gst/gstevent.h
@@ -152,7 +152,7 @@ typedef enum {
GST_EVENT_BUFFERSIZE = GST_EVENT_MAKE_TYPE (90, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)),
GST_EVENT_SINK_MESSAGE = GST_EVENT_MAKE_TYPE (100, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY) | FLAG(STICKY_MULTI)),
GST_EVENT_EOS = GST_EVENT_MAKE_TYPE (110, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)),
- GST_EVENT_TOC = GST_EVENT_MAKE_TYPE (120, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY) | FLAG(STICKY_MULTI)),
+ GST_EVENT_TOC = GST_EVENT_MAKE_TYPE (120, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)),
/* non-sticky downstream serialized */
GST_EVENT_SEGMENT_DONE = GST_EVENT_MAKE_TYPE (150, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)),
@@ -523,7 +523,7 @@ void gst_event_parse_segment (GstEvent *event, const GstSegme
void gst_event_copy_segment (GstEvent *event, GstSegment *segment);
/* tag event */
-GstEvent* gst_event_new_tag (GstTagList *taglist) G_GNUC_MALLOC;
+GstEvent* gst_event_new_tag (const gchar *name, GstTagList *taglist) G_GNUC_MALLOC;
void gst_event_parse_tag (GstEvent *event, GstTagList **taglist);
/* TOC event */
@@ -538,7 +538,7 @@ void gst_event_parse_buffer_size (GstEvent *event, GstFormat *for
gint64 *maxsize, gboolean *async);
/* sink message */
-GstEvent* gst_event_new_sink_message (GstMessage *msg) G_GNUC_MALLOC;
+GstEvent* gst_event_new_sink_message (const gchar *name, GstMessage *msg) G_GNUC_MALLOC;
void gst_event_parse_sink_message (GstEvent *event, GstMessage **msg);
/* QOS events */
diff --git a/gst/gstmessage.c b/gst/gstmessage.c
index 6b8b2c0..4eef4ac 100644
--- a/gst/gstmessage.c
+++ b/gst/gstmessage.c
@@ -480,13 +480,17 @@ gst_message_new_info (GstObject * src, GError * error, const gchar * debug)
GstMessage *
gst_message_new_tag (GstObject * src, GstTagList * tag_list)
{
+ GstStructure *s;
GstMessage *message;
+ GValue val = G_VALUE_INIT;
- g_return_val_if_fail (GST_IS_STRUCTURE (tag_list), NULL);
-
- message =
- gst_message_new_custom (GST_MESSAGE_TAG, src, (GstStructure *) tag_list);
+ g_return_val_if_fail (GST_IS_TAG_LIST (tag_list), NULL);
+ s = gst_structure_new_id_empty (GST_QUARK (MESSAGE_TAG));
+ g_value_init (&val, GST_TYPE_TAG_LIST);
+ g_value_take_boxed (&val, tag_list);
+ gst_structure_id_take_value (s, GST_QUARK (TAGLIST), &val);
+ message = gst_message_new_custom (GST_MESSAGE_TAG, src, s);
return message;
}
@@ -1004,7 +1008,7 @@ gst_message_has_name (GstMessage * message, const gchar * name)
* gst_message_parse_tag (msg, &amp;tags);
* g_print ("Got tags from element %s\n", GST_OBJECT_NAME (msg->src));
* handle_tags (tags);
- * gst_tag_list_free (tags);
+ * gst_tag_list_unref (tags);
* break;
* }
* ...
@@ -1017,16 +1021,12 @@ gst_message_has_name (GstMessage * message, const gchar * name)
void
gst_message_parse_tag (GstMessage * message, GstTagList ** tag_list)
{
- GstStructure *ret;
-
g_return_if_fail (GST_IS_MESSAGE (message));
g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_TAG);
g_return_if_fail (tag_list != NULL);
- ret = gst_structure_copy (GST_MESSAGE_STRUCTURE (message));
- gst_structure_remove_field (ret, "source-pad");
-
- *tag_list = (GstTagList *) ret;
+ gst_structure_id_get (GST_MESSAGE_STRUCTURE (message),
+ GST_QUARK (TAGLIST), GST_TYPE_TAG_LIST, tag_list, NULL);
}
/**
@@ -2210,7 +2210,7 @@ gst_message_new_toc (GstObject * src, GstToc * toc, gboolean updated)
* @toc: (out): return location for the TOC.
* @updated: (out): return location for the updated flag.
*
- * Extract the TOC from the #GstMessage. The TOC returned in the
+ * Extract thef TOC from the #GstMessage. The TOC returned in the
* output argument is a copy; the caller must free it with
* gst_toc_free() when done.
*
diff --git a/gst/gstpad.c b/gst/gstpad.c
index 0464209..73981f3 100644
--- a/gst/gstpad.c
+++ b/gst/gstpad.c
@@ -2637,12 +2637,6 @@ gst_pad_event_default (GstPad * pad, GstObject * parent, GstEvent * event)
GST_LOG_OBJECT (pad, "default event handler");
switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_EOS:
- {
- GST_DEBUG_OBJECT (pad, "pausing task because of eos");
- gst_pad_pause_task (pad);
- break;
- }
case GST_EVENT_CAPS:
forward = GST_PAD_IS_PROXY_CAPS (pad);
result = TRUE;
@@ -3151,11 +3145,21 @@ done:
GST_OBJECT_UNLOCK (pad);
}
+typedef struct
+{
+ GstFlowReturn ret;
+
+ /* If TRUE and ret is not OK this means
+ * that pushing the EOS event failed
+ */
+ gboolean was_eos;
+} PushStickyData;
+
/* should be called with pad LOCK */
static gboolean
push_sticky (GstPad * pad, PadEvent * ev, gpointer user_data)
{
- GstFlowReturn *data = user_data;
+ PushStickyData *data = user_data;
GstEvent *event = ev->event;
if (ev->received) {
@@ -3164,10 +3168,10 @@ push_sticky (GstPad * pad, PadEvent * ev, gpointer user_data)
return TRUE;
}
- *data = gst_pad_push_event_unchecked (pad, gst_event_ref (event),
+ data->ret = gst_pad_push_event_unchecked (pad, gst_event_ref (event),
GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM);
- switch (*data) {
+ switch (data->ret) {
case GST_FLOW_OK:
ev->received = TRUE;
GST_DEBUG_OBJECT (pad, "event %s marked received",
@@ -3175,16 +3179,21 @@ push_sticky (GstPad * pad, PadEvent * ev, gpointer user_data)
break;
case GST_FLOW_NOT_LINKED:
/* not linked is not a problem, we are sticky so the event will be
- * sent later */
+ * sent later but only for non-EOS events */
GST_DEBUG_OBJECT (pad, "pad was not linked");
- *data = GST_FLOW_OK;
+ if (GST_EVENT_TYPE (event) != GST_EVENT_EOS)
+ data->ret = GST_FLOW_OK;
/* fallthrough */
default:
GST_DEBUG_OBJECT (pad, "mark pending events");
GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_PENDING_EVENTS);
break;
}
- return *data == GST_FLOW_OK;
+
+ if (data->ret != GST_FLOW_OK && GST_EVENT_TYPE (event) == GST_EVENT_EOS)
+ data->was_eos = TRUE;
+
+ return data->ret == GST_FLOW_OK;
}
/* check sticky events and push them when needed. should be called
@@ -3192,15 +3201,31 @@ push_sticky (GstPad * pad, PadEvent * ev, gpointer user_data)
static inline GstFlowReturn
check_sticky (GstPad * pad)
{
- GstFlowReturn ret = GST_FLOW_OK;
+ PushStickyData data = { GST_FLOW_OK, FALSE };
if (G_UNLIKELY (GST_PAD_HAS_PENDING_EVENTS (pad))) {
GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_PENDING_EVENTS);
GST_DEBUG_OBJECT (pad, "pushing all sticky events");
- events_foreach (pad, push_sticky, &ret);
+ events_foreach (pad, push_sticky, &data);
+
+ /* If there's an EOS event we must push it downstream
+ * even if sending a previous sticky event failed.
+ * Otherwise the pipeline might wait forever for EOS.
+ *
+ * Only do this if pushing another event than the EOS
+ * event failed.
+ */
+ if (data.ret != GST_FLOW_OK && !data.was_eos) {
+ PadEvent *ev = find_event_by_type (pad, GST_EVENT_EOS, 0);
+
+ if (ev && !ev->received) {
+ data.ret = gst_pad_push_event_unchecked (pad, gst_event_ref (ev->event),
+ GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM);
+ }
+ }
}
- return ret;
+ return data.ret;
}
@@ -3473,6 +3498,9 @@ gst_pad_chain_data_unchecked (GstPad * pad, GstPadProbeType type, void *data)
if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
goto flushing;
+ if (G_UNLIKELY (GST_PAD_IS_EOS (pad)))
+ goto eos;
+
if (G_UNLIKELY (GST_PAD_MODE (pad) != GST_PAD_MODE_PUSH))
goto wrong_mode;
@@ -3534,6 +3562,14 @@ flushing:
gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
return GST_FLOW_FLUSHING;
}
+eos:
+ {
+ GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "chaining, but pad was EOS");
+ GST_OBJECT_UNLOCK (pad);
+ GST_PAD_STREAM_UNLOCK (pad);
+ gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
+ return GST_FLOW_EOS;
+ }
wrong_mode:
{
g_critical ("chain on pad %s:%s but it was not in push mode",
@@ -3682,6 +3718,9 @@ gst_pad_push_data (GstPad * pad, GstPadProbeType type, void *data)
if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
goto flushing;
+ if (G_UNLIKELY (GST_PAD_IS_EOS (pad)))
+ goto eos;
+
if (G_UNLIKELY (GST_PAD_MODE (pad) != GST_PAD_MODE_PUSH))
goto wrong_mode;
@@ -3727,6 +3766,13 @@ flushing:
gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
return GST_FLOW_FLUSHING;
}
+eos:
+ {
+ GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "pushing, but pad was EOS");
+ GST_OBJECT_UNLOCK (pad);
+ gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
+ return GST_FLOW_EOS;
+ }
wrong_mode:
{
g_critical ("pushing on pad %s:%s but it was not activated in push mode",
@@ -4289,6 +4335,7 @@ gst_pad_push_event_unchecked (GstPad * pad, GstEvent * event,
/* Remove sticky EOS events */
GST_LOG_OBJECT (pad, "Removing pending EOS events");
remove_event_by_type (pad, GST_EVENT_EOS);
+ GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_EOS);
type |= GST_PAD_PROBE_TYPE_EVENT_FLUSH;
break;
@@ -4297,6 +4344,11 @@ gst_pad_push_event_unchecked (GstPad * pad, GstEvent * event,
if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
goto flushed;
+ /* No need to check for EOS here as either the caller (gst_pad_push_event())
+ * checked already or this is called as part of pushing sticky events,
+ * in which case we still want to forward the EOS event downstream.
+ */
+
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_SEGMENT:
/* pass the adjusted segment event on. We need to do this even if
@@ -4378,6 +4430,11 @@ not_linked:
GST_DEBUG_OBJECT (pad, "Dropping event because pad is not linked");
GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_PENDING_EVENTS);
gst_event_unref (event);
+
+ /* unlinked pads should not influence latency configuration */
+ if (event_type == GST_EVENT_LATENCY)
+ return GST_FLOW_OK;
+
return GST_FLOW_NOT_LINKED;
}
idle_probe_stopped:
@@ -4406,7 +4463,7 @@ idle_probe_stopped:
gboolean
gst_pad_push_event (GstPad * pad, GstEvent * event)
{
- gboolean res;
+ gboolean res = FALSE;
GstPadProbeType type;
gboolean sticky, serialized;
@@ -4434,12 +4491,17 @@ gst_pad_push_event (GstPad * pad, GstEvent * event)
if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
goto flushed;
+ if (G_UNLIKELY (GST_PAD_IS_EOS (pad)))
+ goto eos;
+
/* srcpad sticky events are store immediately, the received flag is set
* to FALSE and will be set to TRUE when we can successfully push the
* event to the peer pad */
if (gst_pad_store_sticky_event (pad, event, TRUE)) {
GST_DEBUG_OBJECT (pad, "event %s updated", GST_EVENT_TYPE_NAME (event));
}
+ if (GST_EVENT_TYPE (event) == GST_EVENT_EOS)
+ GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_EOS);
}
if (GST_PAD_IS_SRC (pad) && (serialized || sticky)) {
/* all serialized or sticky events on the srcpad trigger push of
@@ -4450,8 +4512,14 @@ gst_pad_push_event (GstPad * pad, GstEvent * event)
/* other events are pushed right away */
res = (gst_pad_push_event_unchecked (pad, event, type) == GST_FLOW_OK);
} else {
+ /* Errors in sticky event pushing are no problem and ignored here
+ * as they will cause more meaningful errors during data flow.
+ * For EOS events, that are not followed by data flow, we still
+ * return FALSE here though.
+ */
+ if (GST_EVENT_TYPE (event) != GST_EVENT_EOS)
+ res = TRUE;
gst_event_unref (event);
- res = TRUE;
}
GST_OBJECT_UNLOCK (pad);
@@ -4478,13 +4546,20 @@ flushed:
gst_event_unref (event);
return FALSE;
}
+eos:
+ {
+ GST_DEBUG_OBJECT (pad, "We're EOS");
+ GST_OBJECT_UNLOCK (pad);
+ gst_event_unref (event);
+ return FALSE;
+ }
}
/* Check if we can call the event function with the given event */
static GstFlowReturn
pre_eventfunc_check (GstPad * pad, GstEvent * event)
{
- GstCaps *caps, *templ;
+ GstCaps *caps;
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_CAPS:
@@ -4492,12 +4567,8 @@ pre_eventfunc_check (GstPad * pad, GstEvent * event)
/* backwards compatibility mode for caps */
gst_event_parse_caps (event, &caps);
- /* See if pad accepts the caps */
- templ = gst_pad_get_pad_template_caps (pad);
- if (!gst_caps_is_subset (caps, templ))
+ if (!gst_pad_query_accept_caps (pad, caps))
goto not_accepted;
-
- gst_caps_unref (templ);
break;
}
default:
@@ -4508,11 +4579,8 @@ pre_eventfunc_check (GstPad * pad, GstEvent * event)
/* ERRORS */
not_accepted:
{
- gst_caps_unref (templ);
GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
"caps %" GST_PTR_FORMAT " not accepted", caps);
- GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
- "no intersection with template %" GST_PTR_FORMAT, templ);
return GST_FLOW_NOT_NEGOTIATED;
}
}
@@ -4554,6 +4622,7 @@ gst_pad_send_event_unchecked (GstPad * pad, GstEvent * event,
/* Remove pending EOS events */
GST_LOG_OBJECT (pad, "Removing pending EOS events");
remove_event_by_type (pad, GST_EVENT_EOS);
+ GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_EOS);
GST_OBJECT_UNLOCK (pad);
/* grab stream lock */
@@ -4574,6 +4643,9 @@ gst_pad_send_event_unchecked (GstPad * pad, GstEvent * event,
goto flushing;
if (serialized) {
+ if (G_UNLIKELY (GST_PAD_IS_EOS (pad)))
+ goto eos;
+
/* lock order: STREAM_LOCK, LOCK, recheck flushing. */
GST_OBJECT_UNLOCK (pad);
GST_PAD_STREAM_LOCK (pad);
@@ -4581,6 +4653,9 @@ gst_pad_send_event_unchecked (GstPad * pad, GstEvent * event,
GST_OBJECT_LOCK (pad);
if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
goto flushing;
+
+ if (G_UNLIKELY (GST_PAD_IS_EOS (pad)))
+ goto eos;
}
switch (GST_EVENT_TYPE (event)) {
@@ -4635,6 +4710,8 @@ gst_pad_send_event_unchecked (GstPad * pad, GstEvent * event,
/* after the event function accepted the event, we can store the sticky
* event on the pad */
gst_pad_store_sticky_event (pad, event, FALSE);
+ if (event_type == GST_EVENT_EOS)
+ GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_EOS);
}
gst_event_unref (event);
}
@@ -4655,6 +4732,16 @@ flushing:
gst_event_unref (event);
return GST_FLOW_FLUSHING;
}
+eos:
+ {
+ GST_OBJECT_UNLOCK (pad);
+ if (need_unlock)
+ GST_PAD_STREAM_UNLOCK (pad);
+ GST_CAT_INFO_OBJECT (GST_CAT_EVENT, pad,
+ "Received event on EOS pad. Discarding");
+ gst_event_unref (event);
+ return GST_FLOW_EOS;
+ }
probe_stopped:
{
GST_OBJECT_UNLOCK (pad);
diff --git a/gst/gstpad.h b/gst/gstpad.h
index df66794..4e93f07 100644
--- a/gst/gstpad.h
+++ b/gst/gstpad.h
@@ -590,7 +590,8 @@ typedef gboolean (*GstPadStickyEventsForeachFunction) (GstPad *pad, GstEvent **
/**
* GstPadFlags:
* @GST_PAD_FLAG_BLOCKED: is dataflow on a pad blocked
- * @GST_PAD_FLAG_FLUSHING: is pad refusing buffers
+ * @GST_PAD_FLAG_FLUSHING: is pad flushing
+ * @GST_PAD_FLAG_EOS: is pad in EOS state
* @GST_PAD_FLAG_BLOCKING: is pad currently blocking on a buffer or event
* @GST_PAD_FLAG_NEED_PARENT: ensure that there is a parent object before calling
* into the pad callbacks.
@@ -614,13 +615,14 @@ typedef gboolean (*GstPadStickyEventsForeachFunction) (GstPad *pad, GstEvent **
typedef enum {
GST_PAD_FLAG_BLOCKED = (GST_OBJECT_FLAG_LAST << 0),
GST_PAD_FLAG_FLUSHING = (GST_OBJECT_FLAG_LAST << 1),
- GST_PAD_FLAG_BLOCKING = (GST_OBJECT_FLAG_LAST << 2),
- GST_PAD_FLAG_NEED_PARENT = (GST_OBJECT_FLAG_LAST << 3),
- GST_PAD_FLAG_NEED_RECONFIGURE = (GST_OBJECT_FLAG_LAST << 4),
- GST_PAD_FLAG_PENDING_EVENTS = (GST_OBJECT_FLAG_LAST << 5),
- GST_PAD_FLAG_FIXED_CAPS = (GST_OBJECT_FLAG_LAST << 6),
- GST_PAD_FLAG_PROXY_CAPS = (GST_OBJECT_FLAG_LAST << 7),
- GST_PAD_FLAG_PROXY_ALLOCATION = (GST_OBJECT_FLAG_LAST << 8),
+ GST_PAD_FLAG_EOS = (GST_OBJECT_FLAG_LAST << 2),
+ GST_PAD_FLAG_BLOCKING = (GST_OBJECT_FLAG_LAST << 3),
+ GST_PAD_FLAG_NEED_PARENT = (GST_OBJECT_FLAG_LAST << 4),
+ GST_PAD_FLAG_NEED_RECONFIGURE = (GST_OBJECT_FLAG_LAST << 5),
+ GST_PAD_FLAG_PENDING_EVENTS = (GST_OBJECT_FLAG_LAST << 6),
+ GST_PAD_FLAG_FIXED_CAPS = (GST_OBJECT_FLAG_LAST << 7),
+ GST_PAD_FLAG_PROXY_CAPS = (GST_OBJECT_FLAG_LAST << 8),
+ GST_PAD_FLAG_PROXY_ALLOCATION = (GST_OBJECT_FLAG_LAST << 9),
/* padding */
GST_PAD_FLAG_LAST = (GST_OBJECT_FLAG_LAST << 16)
} GstPadFlags;
@@ -755,6 +757,8 @@ struct _GstPadClass {
#define GST_PAD_SET_FLUSHING(pad) (GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_FLUSHING))
#define GST_PAD_UNSET_FLUSHING(pad) (GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_FLUSHING))
+#define GST_PAD_IS_EOS(pad) (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_FLAG_EOS))
+
#define GST_PAD_NEEDS_RECONFIGURE(pad) (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_FLAG_NEED_RECONFIGURE))
#define GST_PAD_HAS_PENDING_EVENTS(pad) (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_FLAG_PENDING_EVENTS))
#define GST_PAD_IS_FIXED_CAPS(pad) (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_FLAG_FIXED_CAPS))
diff --git a/gst/gstpluginfeature.c b/gst/gstpluginfeature.c
index e61fee2..3e1228e 100644
--- a/gst/gstpluginfeature.c
+++ b/gst/gstpluginfeature.c
@@ -180,6 +180,26 @@ gst_plugin_feature_get_rank (GstPluginFeature * feature)
}
/**
+ * gst_plugin_feature_get_plugin:
+ * @feature: a feature
+ *
+ * Get the plugin that provides this feature.
+ *
+ * Returns: (transfer full): the plugin that provides this feature, or %NULL.
+ * Unref with gst_object_unref() when no longer needed.
+ */
+GstPlugin *
+gst_plugin_feature_get_plugin (GstPluginFeature * feature)
+{
+ g_return_val_if_fail (GST_IS_PLUGIN_FEATURE (feature), NULL);
+
+ if (feature->plugin == NULL)
+ return NULL;
+
+ return (GstPlugin *) gst_object_ref (feature->plugin);
+}
+
+/**
* gst_plugin_feature_list_free:
* @list: (transfer full) (element-type Gst.PluginFeature): list
* of #GstPluginFeature
diff --git a/gst/gstpluginfeature.h b/gst/gstpluginfeature.h
index b99d9ee..a372281 100644
--- a/gst/gstpluginfeature.h
+++ b/gst/gstpluginfeature.h
@@ -38,6 +38,11 @@ G_BEGIN_DECLS
#define GST_PLUGIN_FEATURE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_PLUGIN_FEATURE, GstPluginFeatureClass))
#define GST_PLUGIN_FEATURE_CAST(obj) ((GstPluginFeature*)(obj))
+/**
+ * GstPluginFeature:
+ *
+ * Opaque #GstPluginFeature structure.
+ */
typedef struct _GstPluginFeature GstPluginFeature;
typedef struct _GstPluginFeatureClass GstPluginFeatureClass;
@@ -85,32 +90,6 @@ typedef enum {
#define gst_plugin_feature_set_name(feature,name) gst_object_set_name(GST_OBJECT_CAST(feature),name)
/**
- * GstPluginFeature:
- *
- * Opaque #GstPluginFeature structure.
- */
-struct _GstPluginFeature {
- GstObject object;
-
- /*< private >*/
- gboolean loaded;
- guint rank;
-
- const gchar *plugin_name;
- GstPlugin *plugin; /* weak ref */
-
- /*< private >*/
- gpointer _gst_reserved[GST_PADDING];
-};
-
-struct _GstPluginFeatureClass {
- GstObjectClass parent_class;
-
- /*< private >*/
- gpointer _gst_reserved[GST_PADDING];
-};
-
-/**
* GstPluginFeatureFilter:
* @feature: the pluginfeature to check
* @user_data: the user_data that has been passed on e.g.
@@ -133,6 +112,8 @@ GstPluginFeature *
void gst_plugin_feature_set_rank (GstPluginFeature *feature, guint rank);
guint gst_plugin_feature_get_rank (GstPluginFeature *feature);
+GstPlugin * gst_plugin_feature_get_plugin (GstPluginFeature *feature);
+
void gst_plugin_feature_list_free (GList *list);
GList *gst_plugin_feature_list_copy (GList *list) G_GNUC_MALLOC;
void gst_plugin_feature_list_debug (GList *list);
diff --git a/gst/gstquark.c b/gst/gstquark.c
index d7b6b6d..2d55fa3 100644
--- a/gst/gstquark.c
+++ b/gst/gstquark.c
@@ -58,9 +58,11 @@ static const gchar *_quark_strings[] = {
"allocator", "GstEventFlushStop", "options", "GstQueryAcceptCaps",
"result", "GstQueryCaps", "filter", "modes", "GstEventStreamConfig",
"setup-data", "stream-headers", "GstEventGap", "GstQueryDrain", "params",
- "toc-select", "uid", "toc", GST_ELEMENT_METADATA_LONGNAME,
+ "GstEventTocSelect", "uid", "GstQueryToc", GST_ELEMENT_METADATA_LONGNAME,
GST_ELEMENT_METADATA_KLASS, GST_ELEMENT_METADATA_DESCRIPTION,
- GST_ELEMENT_METADATA_AUTHOR
+ GST_ELEMENT_METADATA_AUTHOR, "toc", "toc-entry", "updated", "extend-uid",
+ "uid", "tags", "sub-entries", "info", "info-structure",
+ "time-structure", "GstMessageTag", "GstEventTag"
};
GQuark _priv_gst_quark_table[GST_QUARK_MAX];
diff --git a/gst/gstquark.h b/gst/gstquark.h
index 8f8968f..969ce79 100644
--- a/gst/gstquark.h
+++ b/gst/gstquark.h
@@ -171,7 +171,19 @@ typedef enum _GstQuarkId
GST_QUARK_ELEMENT_METADATA_KLASS = 142,
GST_QUARK_ELEMENT_METADATA_DESCRIPTION = 143,
GST_QUARK_ELEMENT_METADATA_AUTHOR = 144,
- GST_QUARK_MAX = 145
+ GST_QUARK_TOC = 145,
+ GST_QUARK_TOC_ENTRY = 146,
+ GST_QUARK_UPDATED = 147,
+ GST_QUARK_EXTEND_UID = 148,
+ GST_QUARK_TOC_UID = 149,
+ GST_QUARK_TAGS = 150,
+ GST_QUARK_SUB_ENTRIES = 151,
+ GST_QUARK_INFO = 152,
+ GST_QUARK_INFO_STRUCTURE = 153,
+ GST_QUARK_TIME_STRUCTURE = 154,
+ GST_QUARK_MESSAGE_TAG = 155,
+ GST_QUARK_EVENT_TAG = 156,
+ GST_QUARK_MAX = 157
} GstQuarkId;
extern GQuark _priv_gst_quark_table[GST_QUARK_MAX];
diff --git a/gst/gstquery.c b/gst/gstquery.c
index 4aaa17e..5fadc9d 100644
--- a/gst/gstquery.c
+++ b/gst/gstquery.c
@@ -2197,7 +2197,7 @@ gst_query_parse_accept_caps_result (GstQuery * query, gboolean * result)
*
* Constructs a new query object for querying the caps.
*
- * The CAPS query should return the* allowable caps for a pad in the context
+ * The CAPS query should return the allowable caps for a pad in the context
* of the element's state, its link to other elements, and the devices or files
* it has opened. These caps must be a subset of the pad template caps. In the
* NULL state with no links, the CAPS query should ideally return the same caps
@@ -2210,6 +2210,10 @@ gst_query_parse_accept_caps_result (GstQuery * query, gboolean * result)
* the CAPS query should return the most specific caps it reasonably can, since this
* helps with autoplugging.
*
+ * The @filter is used to restrict the result caps, only the caps matching
+ * @filter should be returned from the CAPS query. Specifying a filter might
+ * greatly reduce the amount of processing an element needs to do.
+ *
* Free-function: gst_query_unref
*
* Returns: (transfer full): a new #GstQuery
diff --git a/gst/gstregistry.c b/gst/gstregistry.c
index 0575709..c77cffe 100644
--- a/gst/gstregistry.c
+++ b/gst/gstregistry.c
@@ -1664,7 +1664,7 @@ ensure_current_registry (GError ** error)
registry_file = g_strdup (g_getenv ("GST_REGISTRY"));
if (registry_file == NULL) {
registry_file = g_build_filename (g_get_user_cache_dir (),
- "gstreamer-" GST_API_VERSION, "registry." HOST_CPU ".bin", NULL);
+ "gstreamer-" GST_API_VERSION, "registry." TARGET_CPU ".bin", NULL);
}
if (!_gst_disable_registry_cache) {
diff --git a/gst/gststructure.c b/gst/gststructure.c
index 8065b31..fdc65e1 100644
--- a/gst/gststructure.c
+++ b/gst/gststructure.c
@@ -1828,7 +1828,7 @@ priv_gst_structure_append_to_gstring (const GstStructure * structure,
*
* Free-function: g_free
*
- * Returns: (transfer full)L a pointer to string allocated by g_malloc().
+ * Returns: (transfer full): a pointer to string allocated by g_malloc().
* g_free() after usage.
*/
gchar *
diff --git a/gst/gsttaglist.c b/gst/gsttaglist.c
index c1a2ab0..5658fe7 100644
--- a/gst/gsttaglist.c
+++ b/gst/gsttaglist.c
@@ -47,14 +47,22 @@
#include <gobject/gvaluecollector.h>
#include <string.h>
+/* FIXME: add category for tags */
+#define GST_CAT_TAGS GST_CAT_DEFAULT
+
#define GST_TAG_IS_VALID(tag) (gst_tag_get_info (tag) != NULL)
/* FIXME 0.11: make taglists refcounted maybe? */
/* a tag list is basically a structure, but we don't make this fact public */
-struct _GstTagList
+typedef struct _GstTagListImpl
{
- GstStructure structure;
-};
+ GstTagList taglist;
+
+ GstStructure *structure;
+} GstTagListImpl;
+
+#define GST_TAG_LIST_STRUCTURE(taglist) ((GstTagListImpl*)(taglist))->structure
+
/* FIXME 0.11: use GParamSpecs or something similar for tag registrations,
* possibly even gst_tag_register(). Especially value ranges might be
@@ -64,8 +72,8 @@ typedef struct
{
GType type; /* type the data is in */
- gchar *nick; /* translated name */
- gchar *blurb; /* translated description of type */
+ const gchar *nick; /* translated short description */
+ const gchar *blurb; /* translated long description */
GstTagMergeFunc merge_func; /* functions to merge the values */
GstTagFlag flag; /* type of tag */
@@ -82,298 +90,307 @@ static GMutex __tag_mutex;
/* tags hash table: maps tag name string => GstTagInfo */
static GHashTable *__tags;
-G_DEFINE_BOXED_TYPE (GstTagList, gst_tag_list,
- (GBoxedCopyFunc) gst_tag_list_copy, (GBoxedFreeFunc) gst_tag_list_free);
+GST_DEFINE_MINI_OBJECT_TYPE (GstTagList, gst_tag_list);
+
+static void __gst_tag_list_free (GstTagList * list);
+static GstTagList *__gst_tag_list_copy (const GstTagList * list);
/* FIXME: had code:
* g_value_register_transform_func (_gst_tag_list_type, G_TYPE_STRING,
* _gst_structure_transform_to_string);
*/
-
void
_priv_gst_tag_initialize (void)
{
g_mutex_init (&__tag_mutex);
__tags = g_hash_table_new (g_str_hash, g_str_equal);
- gst_tag_register (GST_TAG_TITLE, GST_TAG_FLAG_META,
+ gst_tag_register_static (GST_TAG_TITLE, GST_TAG_FLAG_META,
G_TYPE_STRING,
_("title"), _("commonly used title"), gst_tag_merge_strings_with_comma);
- gst_tag_register (GST_TAG_TITLE_SORTNAME, GST_TAG_FLAG_META,
+ gst_tag_register_static (GST_TAG_TITLE_SORTNAME, GST_TAG_FLAG_META,
G_TYPE_STRING,
_("title sortname"), _("commonly used title for sorting purposes"), NULL);
- gst_tag_register (GST_TAG_ARTIST, GST_TAG_FLAG_META,
+ gst_tag_register_static (GST_TAG_ARTIST, GST_TAG_FLAG_META,
G_TYPE_STRING,
_("artist"),
_("person(s) responsible for the recording"),
gst_tag_merge_strings_with_comma);
- gst_tag_register (GST_TAG_ARTIST_SORTNAME, GST_TAG_FLAG_META,
+ gst_tag_register_static (GST_TAG_ARTIST_SORTNAME, GST_TAG_FLAG_META,
G_TYPE_STRING,
_("artist sortname"),
_("person(s) responsible for the recording for sorting purposes"), NULL);
- gst_tag_register (GST_TAG_ALBUM, GST_TAG_FLAG_META,
+ gst_tag_register_static (GST_TAG_ALBUM, GST_TAG_FLAG_META,
G_TYPE_STRING,
_("album"),
_("album containing this data"), gst_tag_merge_strings_with_comma);
- gst_tag_register (GST_TAG_ALBUM_SORTNAME, GST_TAG_FLAG_META,
+ gst_tag_register_static (GST_TAG_ALBUM_SORTNAME, GST_TAG_FLAG_META,
G_TYPE_STRING,
_("album sortname"),
_("album containing this data for sorting purposes"), NULL);
- gst_tag_register (GST_TAG_ALBUM_ARTIST, GST_TAG_FLAG_META,
+ gst_tag_register_static (GST_TAG_ALBUM_ARTIST, GST_TAG_FLAG_META,
G_TYPE_STRING,
_("album artist"),
_("The artist of the entire album, as it should be displayed"),
gst_tag_merge_strings_with_comma);
- gst_tag_register (GST_TAG_ALBUM_ARTIST_SORTNAME, GST_TAG_FLAG_META,
+ gst_tag_register_static (GST_TAG_ALBUM_ARTIST_SORTNAME, GST_TAG_FLAG_META,
G_TYPE_STRING,
_("album artist sortname"),
_("The artist of the entire album, as it should be sorted"), NULL);
- gst_tag_register (GST_TAG_DATE, GST_TAG_FLAG_META, G_TYPE_DATE,
+ gst_tag_register_static (GST_TAG_DATE, GST_TAG_FLAG_META, G_TYPE_DATE,
_("date"), _("date the data was created (as a GDate structure)"), NULL);
- gst_tag_register (GST_TAG_DATE_TIME, GST_TAG_FLAG_META, GST_TYPE_DATE_TIME,
- _("datetime"),
+ gst_tag_register_static (GST_TAG_DATE_TIME, GST_TAG_FLAG_META,
+ GST_TYPE_DATE_TIME, _("datetime"),
_("date and time the data was created (as a GstDateTime structure)"),
NULL);
- gst_tag_register (GST_TAG_GENRE, GST_TAG_FLAG_META,
+ gst_tag_register_static (GST_TAG_GENRE, GST_TAG_FLAG_META,
G_TYPE_STRING,
_("genre"),
_("genre this data belongs to"), gst_tag_merge_strings_with_comma);
- gst_tag_register (GST_TAG_COMMENT, GST_TAG_FLAG_META,
+ gst_tag_register_static (GST_TAG_COMMENT, GST_TAG_FLAG_META,
G_TYPE_STRING,
_("comment"),
_("free text commenting the data"), gst_tag_merge_use_first);
- gst_tag_register (GST_TAG_EXTENDED_COMMENT, GST_TAG_FLAG_META,
+ gst_tag_register_static (GST_TAG_EXTENDED_COMMENT, GST_TAG_FLAG_META,
G_TYPE_STRING,
_("extended comment"),
_("free text commenting the data in key=value or key[en]=comment form"),
gst_tag_merge_use_first);
- gst_tag_register (GST_TAG_TRACK_NUMBER, GST_TAG_FLAG_META,
+ gst_tag_register_static (GST_TAG_TRACK_NUMBER, GST_TAG_FLAG_META,
G_TYPE_UINT,
_("track number"),
_("track number inside a collection"), gst_tag_merge_use_first);
- gst_tag_register (GST_TAG_TRACK_COUNT, GST_TAG_FLAG_META,
+ gst_tag_register_static (GST_TAG_TRACK_COUNT, GST_TAG_FLAG_META,
G_TYPE_UINT,
_("track count"),
_("count of tracks inside collection this track belongs to"),
gst_tag_merge_use_first);
- gst_tag_register (GST_TAG_ALBUM_VOLUME_NUMBER, GST_TAG_FLAG_META,
+ gst_tag_register_static (GST_TAG_ALBUM_VOLUME_NUMBER, GST_TAG_FLAG_META,
G_TYPE_UINT,
_("disc number"),
_("disc number inside a collection"), gst_tag_merge_use_first);
- gst_tag_register (GST_TAG_ALBUM_VOLUME_COUNT, GST_TAG_FLAG_META,
+ gst_tag_register_static (GST_TAG_ALBUM_VOLUME_COUNT, GST_TAG_FLAG_META,
G_TYPE_UINT,
_("disc count"),
_("count of discs inside collection this disc belongs to"),
gst_tag_merge_use_first);
- gst_tag_register (GST_TAG_LOCATION, GST_TAG_FLAG_META,
+ gst_tag_register_static (GST_TAG_LOCATION, GST_TAG_FLAG_META,
G_TYPE_STRING,
_("location"), _("Origin of media as a URI (location, where the "
"original of the file or stream is hosted)"),
gst_tag_merge_strings_with_comma);
- gst_tag_register (GST_TAG_HOMEPAGE, GST_TAG_FLAG_META,
+ gst_tag_register_static (GST_TAG_HOMEPAGE, GST_TAG_FLAG_META,
G_TYPE_STRING,
_("homepage"),
_("Homepage for this media (i.e. artist or movie homepage)"),
gst_tag_merge_strings_with_comma);
- gst_tag_register (GST_TAG_DESCRIPTION, GST_TAG_FLAG_META, G_TYPE_STRING,
- _("description"), _("short text describing the content of the data"),
+ gst_tag_register_static (GST_TAG_DESCRIPTION, GST_TAG_FLAG_META,
+ G_TYPE_STRING, _("description"),
+ _("short text describing the content of the data"),
gst_tag_merge_strings_with_comma);
- gst_tag_register (GST_TAG_VERSION, GST_TAG_FLAG_META, G_TYPE_STRING,
+ gst_tag_register_static (GST_TAG_VERSION, GST_TAG_FLAG_META, G_TYPE_STRING,
_("version"), _("version of this data"), NULL);
- gst_tag_register (GST_TAG_ISRC, GST_TAG_FLAG_META, G_TYPE_STRING, _("ISRC"),
+ gst_tag_register_static (GST_TAG_ISRC, GST_TAG_FLAG_META, G_TYPE_STRING,
+ _("ISRC"),
_
("International Standard Recording Code - see http://www.ifpi.org/isrc/"),
NULL);
/* FIXME: organization (fix what? tpm) */
- gst_tag_register (GST_TAG_ORGANIZATION, GST_TAG_FLAG_META, G_TYPE_STRING,
- _("organization"), _("organization"), gst_tag_merge_strings_with_comma);
- gst_tag_register (GST_TAG_COPYRIGHT, GST_TAG_FLAG_META,
+ gst_tag_register_static (GST_TAG_ORGANIZATION, GST_TAG_FLAG_META,
+ G_TYPE_STRING, _("organization"), _("organization"),
+ gst_tag_merge_strings_with_comma);
+ gst_tag_register_static (GST_TAG_COPYRIGHT, GST_TAG_FLAG_META,
G_TYPE_STRING, _("copyright"), _("copyright notice of the data"), NULL);
- gst_tag_register (GST_TAG_COPYRIGHT_URI, GST_TAG_FLAG_META,
+ gst_tag_register_static (GST_TAG_COPYRIGHT_URI, GST_TAG_FLAG_META,
G_TYPE_STRING, _("copyright uri"),
_("URI to the copyright notice of the data"), NULL);
- gst_tag_register (GST_TAG_ENCODED_BY, GST_TAG_FLAG_META, G_TYPE_STRING,
+ gst_tag_register_static (GST_TAG_ENCODED_BY, GST_TAG_FLAG_META, G_TYPE_STRING,
_("encoded by"), _("name of the encoding person or organization"),
gst_tag_merge_strings_with_comma);
- gst_tag_register (GST_TAG_CONTACT, GST_TAG_FLAG_META,
+ gst_tag_register_static (GST_TAG_CONTACT, GST_TAG_FLAG_META,
G_TYPE_STRING,
_("contact"), _("contact information"), gst_tag_merge_strings_with_comma);
- gst_tag_register (GST_TAG_LICENSE, GST_TAG_FLAG_META,
+ gst_tag_register_static (GST_TAG_LICENSE, GST_TAG_FLAG_META,
G_TYPE_STRING, _("license"), _("license of data"), NULL);
- gst_tag_register (GST_TAG_LICENSE_URI, GST_TAG_FLAG_META,
+ gst_tag_register_static (GST_TAG_LICENSE_URI, GST_TAG_FLAG_META,
G_TYPE_STRING, _("license uri"),
_("URI to the license of the data"), NULL);
- gst_tag_register (GST_TAG_PERFORMER, GST_TAG_FLAG_META,
+ gst_tag_register_static (GST_TAG_PERFORMER, GST_TAG_FLAG_META,
G_TYPE_STRING,
_("performer"),
_("person(s) performing"), gst_tag_merge_strings_with_comma);
- gst_tag_register (GST_TAG_COMPOSER, GST_TAG_FLAG_META,
+ gst_tag_register_static (GST_TAG_COMPOSER, GST_TAG_FLAG_META,
G_TYPE_STRING,
_("composer"),
_("person(s) who composed the recording"),
gst_tag_merge_strings_with_comma);
- gst_tag_register (GST_TAG_DURATION, GST_TAG_FLAG_DECODED,
+ gst_tag_register_static (GST_TAG_DURATION, GST_TAG_FLAG_DECODED,
G_TYPE_UINT64,
_("duration"), _("length in GStreamer time units (nanoseconds)"), NULL);
- gst_tag_register (GST_TAG_CODEC, GST_TAG_FLAG_ENCODED,
+ gst_tag_register_static (GST_TAG_CODEC, GST_TAG_FLAG_ENCODED,
G_TYPE_STRING,
_("codec"),
_("codec the data is stored in"), gst_tag_merge_strings_with_comma);
- gst_tag_register (GST_TAG_VIDEO_CODEC, GST_TAG_FLAG_ENCODED,
+ gst_tag_register_static (GST_TAG_VIDEO_CODEC, GST_TAG_FLAG_ENCODED,
G_TYPE_STRING,
_("video codec"), _("codec the video data is stored in"), NULL);
- gst_tag_register (GST_TAG_AUDIO_CODEC, GST_TAG_FLAG_ENCODED,
+ gst_tag_register_static (GST_TAG_AUDIO_CODEC, GST_TAG_FLAG_ENCODED,
G_TYPE_STRING,
_("audio codec"), _("codec the audio data is stored in"), NULL);
- gst_tag_register (GST_TAG_SUBTITLE_CODEC, GST_TAG_FLAG_ENCODED,
+ gst_tag_register_static (GST_TAG_SUBTITLE_CODEC, GST_TAG_FLAG_ENCODED,
G_TYPE_STRING,
_("subtitle codec"), _("codec the subtitle data is stored in"), NULL);
- gst_tag_register (GST_TAG_CONTAINER_FORMAT, GST_TAG_FLAG_ENCODED,
+ gst_tag_register_static (GST_TAG_CONTAINER_FORMAT, GST_TAG_FLAG_ENCODED,
G_TYPE_STRING, _("container format"),
_("container format the data is stored in"), NULL);
- gst_tag_register (GST_TAG_BITRATE, GST_TAG_FLAG_ENCODED,
+ gst_tag_register_static (GST_TAG_BITRATE, GST_TAG_FLAG_ENCODED,
G_TYPE_UINT, _("bitrate"), _("exact or average bitrate in bits/s"), NULL);
- gst_tag_register (GST_TAG_NOMINAL_BITRATE, GST_TAG_FLAG_ENCODED,
+ gst_tag_register_static (GST_TAG_NOMINAL_BITRATE, GST_TAG_FLAG_ENCODED,
G_TYPE_UINT, _("nominal bitrate"), _("nominal bitrate in bits/s"), NULL);
- gst_tag_register (GST_TAG_MINIMUM_BITRATE, GST_TAG_FLAG_ENCODED,
+ gst_tag_register_static (GST_TAG_MINIMUM_BITRATE, GST_TAG_FLAG_ENCODED,
G_TYPE_UINT, _("minimum bitrate"), _("minimum bitrate in bits/s"), NULL);
- gst_tag_register (GST_TAG_MAXIMUM_BITRATE, GST_TAG_FLAG_ENCODED,
+ gst_tag_register_static (GST_TAG_MAXIMUM_BITRATE, GST_TAG_FLAG_ENCODED,
G_TYPE_UINT, _("maximum bitrate"), _("maximum bitrate in bits/s"), NULL);
- gst_tag_register (GST_TAG_ENCODER, GST_TAG_FLAG_ENCODED,
+ gst_tag_register_static (GST_TAG_ENCODER, GST_TAG_FLAG_ENCODED,
G_TYPE_STRING,
_("encoder"), _("encoder used to encode this stream"), NULL);
- gst_tag_register (GST_TAG_ENCODER_VERSION, GST_TAG_FLAG_ENCODED,
+ gst_tag_register_static (GST_TAG_ENCODER_VERSION, GST_TAG_FLAG_ENCODED,
G_TYPE_UINT,
_("encoder version"),
_("version of the encoder used to encode this stream"), NULL);
- gst_tag_register (GST_TAG_SERIAL, GST_TAG_FLAG_ENCODED,
+ gst_tag_register_static (GST_TAG_SERIAL, GST_TAG_FLAG_ENCODED,
G_TYPE_UINT, _("serial"), _("serial number of track"), NULL);
- gst_tag_register (GST_TAG_TRACK_GAIN, GST_TAG_FLAG_META,
+ gst_tag_register_static (GST_TAG_TRACK_GAIN, GST_TAG_FLAG_META,
G_TYPE_DOUBLE, _("replaygain track gain"), _("track gain in db"), NULL);
- gst_tag_register (GST_TAG_TRACK_PEAK, GST_TAG_FLAG_META,
+ gst_tag_register_static (GST_TAG_TRACK_PEAK, GST_TAG_FLAG_META,
G_TYPE_DOUBLE, _("replaygain track peak"), _("peak of the track"), NULL);
- gst_tag_register (GST_TAG_ALBUM_GAIN, GST_TAG_FLAG_META,
+ gst_tag_register_static (GST_TAG_ALBUM_GAIN, GST_TAG_FLAG_META,
G_TYPE_DOUBLE, _("replaygain album gain"), _("album gain in db"), NULL);
- gst_tag_register (GST_TAG_ALBUM_PEAK, GST_TAG_FLAG_META,
+ gst_tag_register_static (GST_TAG_ALBUM_PEAK, GST_TAG_FLAG_META,
G_TYPE_DOUBLE, _("replaygain album peak"), _("peak of the album"), NULL);
- gst_tag_register (GST_TAG_REFERENCE_LEVEL, GST_TAG_FLAG_META,
+ gst_tag_register_static (GST_TAG_REFERENCE_LEVEL, GST_TAG_FLAG_META,
G_TYPE_DOUBLE, _("replaygain reference level"),
_("reference level of track and album gain values"), NULL);
- gst_tag_register (GST_TAG_LANGUAGE_CODE, GST_TAG_FLAG_META, G_TYPE_STRING,
- _("language code"),
+ gst_tag_register_static (GST_TAG_LANGUAGE_CODE, GST_TAG_FLAG_META,
+ G_TYPE_STRING, _("language code"),
_("language code for this stream, conforming to ISO-639-1 or ISO-639-2"),
NULL);
- gst_tag_register (GST_TAG_LANGUAGE_NAME, GST_TAG_FLAG_META, G_TYPE_STRING,
- _("language name"),
+ gst_tag_register_static (GST_TAG_LANGUAGE_NAME, GST_TAG_FLAG_META,
+ G_TYPE_STRING, _("language name"),
_("freeform name of the language this stream is in"), NULL);
- gst_tag_register (GST_TAG_IMAGE, GST_TAG_FLAG_META, GST_TYPE_SAMPLE,
+ gst_tag_register_static (GST_TAG_IMAGE, GST_TAG_FLAG_META, GST_TYPE_SAMPLE,
_("image"), _("image related to this stream"), gst_tag_merge_use_first);
- gst_tag_register (GST_TAG_PREVIEW_IMAGE, GST_TAG_FLAG_META, GST_TYPE_SAMPLE,
+ gst_tag_register_static (GST_TAG_PREVIEW_IMAGE, GST_TAG_FLAG_META,
+ GST_TYPE_SAMPLE,
/* TRANSLATORS: 'preview image' = image that shows a preview of the full image */
_("preview image"), _("preview image related to this stream"), NULL);
- gst_tag_register (GST_TAG_ATTACHMENT, GST_TAG_FLAG_META, GST_TYPE_SAMPLE,
- _("attachment"), _("file attached to this stream"),
+ gst_tag_register_static (GST_TAG_ATTACHMENT, GST_TAG_FLAG_META,
+ GST_TYPE_SAMPLE, _("attachment"), _("file attached to this stream"),
gst_tag_merge_use_first);
- gst_tag_register (GST_TAG_BEATS_PER_MINUTE, GST_TAG_FLAG_META, G_TYPE_DOUBLE,
- _("beats per minute"), _("number of beats per minute in audio"), NULL);
- gst_tag_register (GST_TAG_KEYWORDS, GST_TAG_FLAG_META, G_TYPE_STRING,
+ gst_tag_register_static (GST_TAG_BEATS_PER_MINUTE, GST_TAG_FLAG_META,
+ G_TYPE_DOUBLE, _("beats per minute"),
+ _("number of beats per minute in audio"), NULL);
+ gst_tag_register_static (GST_TAG_KEYWORDS, GST_TAG_FLAG_META, G_TYPE_STRING,
_("keywords"), _("comma separated keywords describing the content"),
gst_tag_merge_strings_with_comma);
- gst_tag_register (GST_TAG_GEO_LOCATION_NAME, GST_TAG_FLAG_META, G_TYPE_STRING,
- _("geo location name"), _("human readable descriptive location of where "
+ gst_tag_register_static (GST_TAG_GEO_LOCATION_NAME, GST_TAG_FLAG_META,
+ G_TYPE_STRING, _("geo location name"),
+ _("human readable descriptive location of where "
"the media has been recorded or produced"), NULL);
- gst_tag_register (GST_TAG_GEO_LOCATION_LATITUDE, GST_TAG_FLAG_META,
+ gst_tag_register_static (GST_TAG_GEO_LOCATION_LATITUDE, GST_TAG_FLAG_META,
G_TYPE_DOUBLE, _("geo location latitude"),
_("geo latitude location of where the media has been recorded or "
"produced in degrees according to WGS84 (zero at the equator, "
"negative values for southern latitudes)"), NULL);
- gst_tag_register (GST_TAG_GEO_LOCATION_LONGITUDE, GST_TAG_FLAG_META,
+ gst_tag_register_static (GST_TAG_GEO_LOCATION_LONGITUDE, GST_TAG_FLAG_META,
G_TYPE_DOUBLE, _("geo location longitude"),
_("geo longitude location of where the media has been recorded or "
"produced in degrees according to WGS84 (zero at the prime meridian "
"in Greenwich/UK, negative values for western longitudes)"), NULL);
- gst_tag_register (GST_TAG_GEO_LOCATION_ELEVATION, GST_TAG_FLAG_META,
+ gst_tag_register_static (GST_TAG_GEO_LOCATION_ELEVATION, GST_TAG_FLAG_META,
G_TYPE_DOUBLE, _("geo location elevation"),
_("geo elevation of where the media has been recorded or produced in "
"meters according to WGS84 (zero is average sea level)"), NULL);
- gst_tag_register (GST_TAG_GEO_LOCATION_COUNTRY, GST_TAG_FLAG_META,
+ gst_tag_register_static (GST_TAG_GEO_LOCATION_COUNTRY, GST_TAG_FLAG_META,
G_TYPE_STRING, _("geo location country"),
_("country (english name) where the media has been recorded "
"or produced"), NULL);
- gst_tag_register (GST_TAG_GEO_LOCATION_CITY, GST_TAG_FLAG_META,
+ gst_tag_register_static (GST_TAG_GEO_LOCATION_CITY, GST_TAG_FLAG_META,
G_TYPE_STRING, _("geo location city"),
_("city (english name) where the media has been recorded "
"or produced"), NULL);
- gst_tag_register (GST_TAG_GEO_LOCATION_SUBLOCATION, GST_TAG_FLAG_META,
+ gst_tag_register_static (GST_TAG_GEO_LOCATION_SUBLOCATION, GST_TAG_FLAG_META,
G_TYPE_STRING, _("geo location sublocation"),
_("a location whithin a city where the media has been produced "
"or created (e.g. the neighborhood)"), NULL);
- gst_tag_register (GST_TAG_GEO_LOCATION_HORIZONTAL_ERROR, GST_TAG_FLAG_META,
- G_TYPE_DOUBLE, _("geo location horizontal error"),
+ gst_tag_register_static (GST_TAG_GEO_LOCATION_HORIZONTAL_ERROR,
+ GST_TAG_FLAG_META, G_TYPE_DOUBLE, _("geo location horizontal error"),
_("expected error of the horizontal positioning measures (in meters)"),
NULL);
- gst_tag_register (GST_TAG_GEO_LOCATION_MOVEMENT_SPEED, GST_TAG_FLAG_META,
- G_TYPE_DOUBLE, _("geo location movement speed"),
+ gst_tag_register_static (GST_TAG_GEO_LOCATION_MOVEMENT_SPEED,
+ GST_TAG_FLAG_META, G_TYPE_DOUBLE, _("geo location movement speed"),
_("movement speed of the capturing device while performing the capture "
"in m/s"), NULL);
- gst_tag_register (GST_TAG_GEO_LOCATION_MOVEMENT_DIRECTION, GST_TAG_FLAG_META,
- G_TYPE_DOUBLE, _("geo location movement direction"),
+ gst_tag_register_static (GST_TAG_GEO_LOCATION_MOVEMENT_DIRECTION,
+ GST_TAG_FLAG_META, G_TYPE_DOUBLE, _("geo location movement direction"),
_("indicates the movement direction of the device performing the capture"
" of a media. It is represented as degrees in floating point "
"representation, 0 means the geographic north, and increases "
"clockwise"), NULL);
- gst_tag_register (GST_TAG_GEO_LOCATION_CAPTURE_DIRECTION, GST_TAG_FLAG_META,
- G_TYPE_DOUBLE, _("geo location capture direction"),
+ gst_tag_register_static (GST_TAG_GEO_LOCATION_CAPTURE_DIRECTION,
+ GST_TAG_FLAG_META, G_TYPE_DOUBLE, _("geo location capture direction"),
_("indicates the direction the device is pointing to when capturing "
" a media. It is represented as degrees in floating point "
" representation, 0 means the geographic north, and increases "
"clockwise"), NULL);
- gst_tag_register (GST_TAG_SHOW_NAME, GST_TAG_FLAG_META, G_TYPE_STRING,
+ gst_tag_register_static (GST_TAG_SHOW_NAME, GST_TAG_FLAG_META, G_TYPE_STRING,
/* TRANSLATORS: 'show name' = 'TV/radio/podcast show name' here */
_("show name"),
_("Name of the tv/podcast/series show the media is from"),
gst_tag_merge_strings_with_comma);
- gst_tag_register (GST_TAG_SHOW_SORTNAME, GST_TAG_FLAG_META, G_TYPE_STRING,
+ gst_tag_register_static (GST_TAG_SHOW_SORTNAME, GST_TAG_FLAG_META,
+ G_TYPE_STRING,
/* TRANSLATORS: 'show sortname' = 'TV/radio/podcast show name as used for sorting purposes' here */
_("show sortname"),
_("Name of the tv/podcast/series show the media is from, for sorting "
"purposes"), NULL);
- gst_tag_register (GST_TAG_SHOW_EPISODE_NUMBER, GST_TAG_FLAG_META, G_TYPE_UINT,
- _("episode number"),
+ gst_tag_register_static (GST_TAG_SHOW_EPISODE_NUMBER, GST_TAG_FLAG_META,
+ G_TYPE_UINT, _("episode number"),
_("The episode number in the season the media is part of"),
gst_tag_merge_use_first);
- gst_tag_register (GST_TAG_SHOW_SEASON_NUMBER, GST_TAG_FLAG_META, G_TYPE_UINT,
- _("season number"),
+ gst_tag_register_static (GST_TAG_SHOW_SEASON_NUMBER, GST_TAG_FLAG_META,
+ G_TYPE_UINT, _("season number"),
_("The season number of the show the media is part of"),
gst_tag_merge_use_first);
- gst_tag_register (GST_TAG_LYRICS, GST_TAG_FLAG_META, G_TYPE_STRING,
+ gst_tag_register_static (GST_TAG_LYRICS, GST_TAG_FLAG_META, G_TYPE_STRING,
_("lyrics"), _("The lyrics of the media, commonly used for songs"),
gst_tag_merge_strings_with_comma);
- gst_tag_register (GST_TAG_COMPOSER_SORTNAME, GST_TAG_FLAG_META, G_TYPE_STRING,
- _("composer sortname"),
+ gst_tag_register_static (GST_TAG_COMPOSER_SORTNAME, GST_TAG_FLAG_META,
+ G_TYPE_STRING, _("composer sortname"),
_("person(s) who composed the recording, for sorting purposes"), NULL);
- gst_tag_register (GST_TAG_GROUPING, GST_TAG_FLAG_META, G_TYPE_STRING,
+ gst_tag_register_static (GST_TAG_GROUPING, GST_TAG_FLAG_META, G_TYPE_STRING,
_("grouping"),
_("Groups related media that spans multiple tracks, like the different "
"pieces of a concerto. It is a higher level than a track, "
"but lower than an album"), NULL);
- gst_tag_register (GST_TAG_USER_RATING, GST_TAG_FLAG_META, G_TYPE_UINT,
+ gst_tag_register_static (GST_TAG_USER_RATING, GST_TAG_FLAG_META, G_TYPE_UINT,
_("user rating"),
_("Rating attributed by a user. The higher the rank, "
"the more the user likes this media"), NULL);
- gst_tag_register (GST_TAG_DEVICE_MANUFACTURER, GST_TAG_FLAG_META,
+ gst_tag_register_static (GST_TAG_DEVICE_MANUFACTURER, GST_TAG_FLAG_META,
G_TYPE_STRING, _("device manufacturer"),
_("Manufacturer of the device used to create this media"), NULL);
- gst_tag_register (GST_TAG_DEVICE_MODEL, GST_TAG_FLAG_META, G_TYPE_STRING,
- _("device model"),
+ gst_tag_register_static (GST_TAG_DEVICE_MODEL, GST_TAG_FLAG_META,
+ G_TYPE_STRING, _("device model"),
_("Model of the device used to create this media"), NULL);
- gst_tag_register (GST_TAG_APPLICATION_NAME, GST_TAG_FLAG_META, G_TYPE_STRING,
- _("application name"), _("Application used to create the media"), NULL);
- gst_tag_register (GST_TAG_APPLICATION_DATA, GST_TAG_FLAG_META,
+ gst_tag_register_static (GST_TAG_APPLICATION_NAME, GST_TAG_FLAG_META,
+ G_TYPE_STRING, _("application name"),
+ _("Application used to create the media"), NULL);
+ gst_tag_register_static (GST_TAG_APPLICATION_DATA, GST_TAG_FLAG_META,
GST_TYPE_BUFFER, _("application data"),
_("Arbitrary application data to be serialized into the media"), NULL);
- gst_tag_register (GST_TAG_IMAGE_ORIENTATION, GST_TAG_FLAG_META, G_TYPE_STRING,
- _("image orientation"),
+ gst_tag_register_static (GST_TAG_IMAGE_ORIENTATION, GST_TAG_FLAG_META,
+ G_TYPE_STRING, _("image orientation"),
_("How the image should be rotated or flipped before display"), NULL);
}
@@ -470,8 +487,36 @@ void
gst_tag_register (const gchar * name, GstTagFlag flag, GType type,
const gchar * nick, const gchar * blurb, GstTagMergeFunc func)
{
+ g_return_if_fail (name != NULL);
+ g_return_if_fail (nick != NULL);
+ g_return_if_fail (blurb != NULL);
+ g_return_if_fail (type != 0 && type != GST_TYPE_LIST);
+
+ return gst_tag_register_static (g_intern_string (name), flag, type,
+ g_intern_string (nick), g_intern_string (blurb), func);
+}
+
+/**
+ * gst_tag_register_static:
+ * @name: the name or identifier string (string constant)
+ * @flag: a flag describing the type of tag info
+ * @type: the type this data is in
+ * @nick: human-readable name or short description (string constant)
+ * @blurb: a human-readable description for this tag (string constant)
+ * @func: function for merging multiple values of this tag, or NULL
+ *
+ * Registers a new tag type for the use with GStreamer's type system.
+ *
+ * Same as gst_tag_register(), but @name, @nick, and @blurb must be
+ * static strings or inlined strings, as they will not be copied. (GStreamer
+ * plugins will be made resident once loaded, so this function can be used
+ * even from dynamically loaded plugins.)
+ */
+void
+gst_tag_register_static (const gchar * name, GstTagFlag flag, GType type,
+ const gchar * nick, const gchar * blurb, GstTagMergeFunc func)
+{
GstTagInfo *info;
- gchar *name_dup;
g_return_if_fail (name != NULL);
g_return_if_fail (nick != NULL);
@@ -488,17 +533,13 @@ gst_tag_register (const gchar * name, GstTagFlag flag, GType type,
info = g_slice_new (GstTagInfo);
info->flag = flag;
info->type = type;
- info->nick = g_strdup (nick);
- info->blurb = g_strdup (blurb);
+ info->name_quark = g_quark_from_static_string (name);
+ info->nick = nick;
+ info->blurb = blurb;
info->merge_func = func;
- /* we make a copy for the hash table anyway, which will stay around, so
- * can use that for the quark table too */
- name_dup = g_strdup (name);
- info->name_quark = g_quark_from_static_string (name_dup);
-
TAG_LOCK;
- g_hash_table_insert (__tags, (gpointer) name_dup, info);
+ g_hash_table_insert (__tags, (gpointer) name, info);
TAG_UNLOCK;
}
@@ -621,19 +662,82 @@ gst_tag_is_fixed (const gchar * tag)
return info->merge_func == NULL;
}
+static void
+gst_tag_list_init (GstTagList * taglist, gsize size)
+{
+ gst_mini_object_init (GST_MINI_OBJECT_CAST (taglist),
+ gst_tag_list_get_type (), size);
+
+ taglist->mini_object.copy = (GstMiniObjectCopyFunction) __gst_tag_list_copy;
+ taglist->mini_object.dispose = NULL;
+ taglist->mini_object.free = (GstMiniObjectFreeFunction) __gst_tag_list_free;
+}
+
+/* takes ownership of the structure */
+static GstTagList *
+gst_tag_list_new_internal (GstStructure * s)
+{
+ GstTagList *tag_list;
+
+ g_assert (s != NULL);
+
+ tag_list = (GstTagList *) g_slice_new (GstTagListImpl);
+
+ gst_tag_list_init (tag_list, sizeof (GstTagListImpl));
+
+ GST_TAG_LIST_STRUCTURE (tag_list) = s;
+
+#ifdef DEBUG_REFCOUNT
+ GST_CAT_TRACE (GST_CAT_TAGS, "created taglist %p", tag_list);
+#endif
+
+ return tag_list;
+}
+
+static void
+__gst_tag_list_free (GstTagList * list)
+{
+ g_return_if_fail (GST_IS_TAG_LIST (list));
+
+#ifdef DEBUG_REFCOUNT
+ GST_CAT_TRACE (GST_CAT_TAGS, "freeing caps %p", list);
+#endif
+
+ gst_structure_free (GST_TAG_LIST_STRUCTURE (list));
+
+ /* why not just pass sizeof (GstTagListImpl) here? */
+ g_slice_free1 (GST_MINI_OBJECT_SIZE (list), list);
+}
+
+static GstTagList *
+__gst_tag_list_copy (const GstTagList * list)
+{
+ const GstStructure *s;
+
+ g_return_val_if_fail (GST_IS_TAG_LIST (list), NULL);
+
+ s = GST_TAG_LIST_STRUCTURE (list);
+ return gst_tag_list_new_internal (gst_structure_copy (s));
+}
+
/**
* gst_tag_list_new_empty:
*
* Creates a new empty GstTagList.
*
- * Free-function: gst_tag_list_free
+ * Free-function: gst_tag_list_unref
*
* Returns: (transfer full): An empty tag list
*/
GstTagList *
gst_tag_list_new_empty (void)
{
- return GST_TAG_LIST (gst_structure_new_id_empty (GST_QUARK (TAGLIST)));
+ GstStructure *s;
+ GstTagList *tag_list;
+
+ s = gst_structure_new_id_empty (GST_QUARK (TAGLIST));
+ tag_list = gst_tag_list_new_internal (s);
+ return tag_list;
}
/**
@@ -649,9 +753,9 @@ gst_tag_list_new_empty (void)
* function. The tag list will make copies of any arguments passed
* (e.g. strings, buffers).
*
- * Free-function: gst_tag_list_free
+ * Free-function: gst_tag_list_unref
*
- * Returns: (transfer full): a new #GstTagList. Free with gst_tag_list_free()
+ * Returns: (transfer full): a new #GstTagList. Free with gst_tag_list_unref()
* when no longer needed.
*
* Since: 0.10.24
@@ -679,9 +783,9 @@ gst_tag_list_new (const gchar * tag, ...)
* Just like gst_tag_list_new(), only that it takes a va_list argument.
* Useful mostly for language bindings.
*
- * Free-function: gst_tag_list_free
+ * Free-function: gst_tag_list_unref
*
- * Returns: (transfer full): a new #GstTagList. Free with gst_tag_list_free()
+ * Returns: (transfer full): a new #GstTagList. Free with gst_tag_list_unref()
* when no longer needed.
*
* Since: 0.10.24
@@ -716,7 +820,7 @@ gst_tag_list_to_string (const GstTagList * list)
{
g_return_val_if_fail (GST_IS_TAG_LIST (list), NULL);
- return gst_structure_to_string (GST_STRUCTURE (list));
+ return gst_structure_to_string (GST_TAG_LIST_STRUCTURE (list));
}
/**
@@ -732,10 +836,13 @@ gst_tag_list_to_string (const GstTagList * list)
GstTagList *
gst_tag_list_new_from_string (const gchar * str)
{
+ GstTagList *tag_list;
+
g_return_val_if_fail (str != NULL, NULL);
g_return_val_if_fail (g_str_has_prefix (str, "taglist"), NULL);
- return GST_TAG_LIST (gst_structure_from_string (str, NULL));
+ tag_list = gst_tag_list_new_internal (gst_structure_from_string (str, NULL));
+ return tag_list;
}
/**
@@ -752,7 +859,7 @@ gst_tag_list_n_tags (const GstTagList * list)
g_return_val_if_fail (list != NULL, 0);
g_return_val_if_fail (GST_IS_TAG_LIST (list), 0);
- return gst_structure_n_fields ((GstStructure *) list);
+ return gst_structure_n_fields (GST_TAG_LIST_STRUCTURE (list));
}
/**
@@ -770,7 +877,7 @@ gst_tag_list_nth_tag_name (const GstTagList * list, guint index)
g_return_val_if_fail (list != NULL, 0);
g_return_val_if_fail (GST_IS_TAG_LIST (list), 0);
- return gst_structure_nth_field_name ((GstStructure *) list, index);
+ return gst_structure_nth_field_name (GST_TAG_LIST_STRUCTURE (list), index);
}
/**
@@ -789,7 +896,7 @@ gst_tag_list_is_empty (const GstTagList * list)
g_return_val_if_fail (list != NULL, FALSE);
g_return_val_if_fail (GST_IS_TAG_LIST (list), FALSE);
- return (gst_structure_n_fields ((GstStructure *) list) == 0);
+ return (gst_structure_n_fields (GST_TAG_LIST_STRUCTURE (list)) == 0);
}
static gboolean
@@ -836,8 +943,8 @@ gst_tag_list_is_equal (const GstTagList * list1, const GstTagList * list2)
/* we don't just use gst_structure_is_equal() here so we can add some
* tolerance for doubles, though maybe we should just add that to
* gst_value_compare_double() as well? */
- s1 = (const GstStructure *) list1;
- s2 = (const GstStructure *) list2;
+ s1 = GST_TAG_LIST_STRUCTURE (list1);
+ s2 = GST_TAG_LIST_STRUCTURE (list2);
num_fields1 = gst_structure_n_fields (s1);
num_fields2 = gst_structure_n_fields (s2);
@@ -863,24 +970,6 @@ gst_tag_list_is_equal (const GstTagList * list1, const GstTagList * list2)
return TRUE;
}
-/**
- * gst_is_tag_list:
- * @p: Object that might be a taglist
- *
- * Checks if the given pointer is a taglist.
- *
- * Returns: TRUE, if the given pointer is a taglist
- */
-gboolean
-gst_is_tag_list (gconstpointer p)
-{
- GstStructure *s = (GstStructure *) p;
-
- g_return_val_if_fail (p != NULL, FALSE);
-
- return (GST_IS_STRUCTURE (s) && s->name == GST_QUARK (TAGLIST));
-}
-
typedef struct
{
GstTagList *list;
@@ -892,7 +981,7 @@ static void
gst_tag_list_add_value_internal (GstTagList * tag_list, GstTagMergeMode mode,
const gchar * tag, const GValue * value, GstTagInfo * info)
{
- GstStructure *list = GST_STRUCTURE (tag_list);
+ GstStructure *list = GST_TAG_LIST_STRUCTURE (tag_list);
const GValue *value2;
GQuark tag_quark;
@@ -981,34 +1070,17 @@ gst_tag_list_insert (GstTagList * into, const GstTagList * from,
GstTagCopyData data;
g_return_if_fail (GST_IS_TAG_LIST (into));
+ g_return_if_fail (gst_tag_list_is_writable (into));
g_return_if_fail (GST_IS_TAG_LIST (from));
g_return_if_fail (GST_TAG_MODE_IS_VALID (mode));
data.list = into;
data.mode = mode;
if (mode == GST_TAG_MERGE_REPLACE_ALL) {
- gst_structure_remove_all_fields (GST_STRUCTURE (data.list));
+ gst_structure_remove_all_fields (GST_TAG_LIST_STRUCTURE (into));
}
- gst_structure_foreach ((GstStructure *) from, gst_tag_list_copy_foreach,
- &data);
-}
-
-/**
- * gst_tag_list_copy:
- * @list: list to copy
- *
- * Copies a given #GstTagList.
- *
- * Free-function: gst_tag_list_free
- *
- * Returns: (transfer full): copy of the given list
- */
-GstTagList *
-gst_tag_list_copy (const GstTagList * list)
-{
- g_return_val_if_fail (GST_IS_TAG_LIST (list), NULL);
-
- return GST_TAG_LIST (gst_structure_copy ((GstStructure *) list));
+ gst_structure_foreach (GST_TAG_LIST_STRUCTURE (from),
+ gst_tag_list_copy_foreach, &data);
}
/**
@@ -1020,7 +1092,7 @@ gst_tag_list_copy (const GstTagList * list)
* Merges the two given lists into a new list. If one of the lists is NULL, a
* copy of the other is returned. If both lists are NULL, NULL is returned.
*
- * Free-function: gst_tag_list_free
+ * Free-function: gst_tag_list_unref
*
* Returns: (transfer full): the new list
*/
@@ -1047,25 +1119,12 @@ gst_tag_list_merge (const GstTagList * list1, const GstTagList * list2,
gst_tag_list_insert (list1_cp, list2_cp, mode);
if (!list2)
- gst_tag_list_free ((GstTagList *) list2_cp);
+ gst_tag_list_unref ((GstTagList *) list2_cp);
return list1_cp;
}
/**
- * gst_tag_list_free:
- * @list: (in) (transfer full): the list to free
- *
- * Frees the given list and all associated values.
- */
-void
-gst_tag_list_free (GstTagList * list)
-{
- g_return_if_fail (GST_IS_TAG_LIST (list));
- gst_structure_free ((GstStructure *) list);
-}
-
-/**
* gst_tag_list_get_tag_size:
* @list: a taglist
* @tag: the tag to query
@@ -1081,7 +1140,7 @@ gst_tag_list_get_tag_size (const GstTagList * list, const gchar * tag)
g_return_val_if_fail (GST_IS_TAG_LIST (list), 0);
- value = gst_structure_get_value ((GstStructure *) list, tag);
+ value = gst_structure_get_value (GST_TAG_LIST_STRUCTURE (list), tag);
if (value == NULL)
return 0;
if (G_VALUE_TYPE (value) != GST_TYPE_LIST)
@@ -1106,6 +1165,7 @@ gst_tag_list_add (GstTagList * list, GstTagMergeMode mode, const gchar * tag,
va_list args;
g_return_if_fail (GST_IS_TAG_LIST (list));
+ g_return_if_fail (gst_tag_list_is_writable (list));
g_return_if_fail (GST_TAG_MODE_IS_VALID (mode));
g_return_if_fail (tag != NULL);
@@ -1130,6 +1190,7 @@ gst_tag_list_add_values (GstTagList * list, GstTagMergeMode mode,
va_list args;
g_return_if_fail (GST_IS_TAG_LIST (list));
+ g_return_if_fail (gst_tag_list_is_writable (list));
g_return_if_fail (GST_TAG_MODE_IS_VALID (mode));
g_return_if_fail (tag != NULL);
@@ -1155,11 +1216,12 @@ gst_tag_list_add_valist (GstTagList * list, GstTagMergeMode mode,
gchar *error = NULL;
g_return_if_fail (GST_IS_TAG_LIST (list));
+ g_return_if_fail (gst_tag_list_is_writable (list));
g_return_if_fail (GST_TAG_MODE_IS_VALID (mode));
g_return_if_fail (tag != NULL);
if (mode == GST_TAG_MERGE_REPLACE_ALL) {
- gst_structure_remove_all_fields (GST_STRUCTURE (list));
+ gst_structure_remove_all_fields (GST_TAG_LIST_STRUCTURE (list));
}
while (tag != NULL) {
@@ -1199,11 +1261,12 @@ gst_tag_list_add_valist_values (GstTagList * list, GstTagMergeMode mode,
const gchar * tag, va_list var_args)
{
g_return_if_fail (GST_IS_TAG_LIST (list));
+ g_return_if_fail (gst_tag_list_is_writable (list));
g_return_if_fail (GST_TAG_MODE_IS_VALID (mode));
g_return_if_fail (tag != NULL);
if (mode == GST_TAG_MERGE_REPLACE_ALL) {
- gst_structure_remove_all_fields (GST_STRUCTURE (list));
+ gst_structure_remove_all_fields (GST_TAG_LIST_STRUCTURE (list));
}
while (tag != NULL) {
@@ -1236,6 +1299,7 @@ gst_tag_list_add_value (GstTagList * list, GstTagMergeMode mode,
const gchar * tag, const GValue * value)
{
g_return_if_fail (GST_IS_TAG_LIST (list));
+ g_return_if_fail (gst_tag_list_is_writable (list));
g_return_if_fail (GST_TAG_MODE_IS_VALID (mode));
g_return_if_fail (tag != NULL);
@@ -1255,7 +1319,7 @@ gst_tag_list_remove_tag (GstTagList * list, const gchar * tag)
g_return_if_fail (GST_IS_TAG_LIST (list));
g_return_if_fail (tag != NULL);
- gst_structure_remove_field ((GstStructure *) list, tag);
+ gst_structure_remove_field (GST_TAG_LIST_STRUCTURE (list), tag);
}
typedef struct
@@ -1297,8 +1361,8 @@ gst_tag_list_foreach (const GstTagList * list, GstTagForeachFunc func,
data.func = func;
data.tag_list = list;
data.data = user_data;
- gst_structure_foreach ((GstStructure *) list, structure_foreach_wrapper,
- &data);
+ gst_structure_foreach (GST_TAG_LIST_STRUCTURE (list),
+ structure_foreach_wrapper, &data);
}
/**
@@ -1322,7 +1386,7 @@ gst_tag_list_get_value_index (const GstTagList * list, const gchar * tag,
g_return_val_if_fail (GST_IS_TAG_LIST (list), NULL);
g_return_val_if_fail (tag != NULL, NULL);
- value = gst_structure_get_value ((GstStructure *) list, tag);
+ value = gst_structure_get_value (GST_TAG_LIST_STRUCTURE (list), tag);
if (value == NULL)
return NULL;
@@ -1362,7 +1426,7 @@ gst_tag_list_copy_value (GValue * dest, const GstTagList * list,
g_return_val_if_fail (dest != NULL, FALSE);
g_return_val_if_fail (G_VALUE_TYPE (dest) == 0, FALSE);
- src = gst_structure_get_value ((GstStructure *) list, tag);
+ src = gst_structure_get_value (GST_TAG_LIST_STRUCTURE (list), tag);
if (!src)
return FALSE;
diff --git a/gst/gsttaglist.h b/gst/gsttaglist.h
index 00a2770..7940a31 100644
--- a/gst/gsttaglist.h
+++ b/gst/gsttaglist.h
@@ -132,6 +132,7 @@ typedef enum {
*
* Extra tag flags used when registering tags.
*/
+/* FIXME: these are not really flags .. */
typedef enum {
GST_TAG_FLAG_UNDEFINED,
GST_TAG_FLAG_META,
@@ -144,14 +145,18 @@ typedef enum {
/**
* GstTagList:
+ * @mini_object: the parent type
*
- * Opaque #GstTagList data structure.
+ * Object describing tags / metadata.
*/
typedef struct _GstTagList GstTagList;
+struct _GstTagList {
+ GstMiniObject mini_object;
+};
#define GST_TAG_LIST(x) ((GstTagList *) (x))
-#define GST_IS_TAG_LIST(x) ((x) != NULL && gst_is_tag_list (GST_TAG_LIST (x)))
#define GST_TYPE_TAG_LIST (gst_tag_list_get_type ())
+#define GST_IS_TAG_LIST(obj) (GST_IS_MINI_OBJECT_TYPE((obj), GST_TYPE_TAG_LIST))
/**
* GstTagForeachFunc:
@@ -186,6 +191,13 @@ void gst_tag_register (const gchar * name,
const gchar * blurb,
GstTagMergeFunc func);
+void gst_tag_register_static (const gchar * name,
+ GstTagFlag flag,
+ GType type,
+ const gchar * nick,
+ const gchar * blurb,
+ GstTagMergeFunc func);
+
/* some default merging functions */
void gst_tag_merge_use_first (GValue * dest, const GValue * src);
void gst_tag_merge_strings_with_comma (GValue * dest, const GValue * src);
@@ -206,8 +218,6 @@ GstTagList * gst_tag_list_new_valist (va_list var_args) G_GNUC_MALLOC;
gchar * gst_tag_list_to_string (const GstTagList * list) G_GNUC_MALLOC;
GstTagList * gst_tag_list_new_from_string (const gchar * str) G_GNUC_MALLOC;
-gboolean gst_is_tag_list (gconstpointer p);
-GstTagList * gst_tag_list_copy (const GstTagList * list) G_GNUC_MALLOC;
gint gst_tag_list_n_tags (const GstTagList * list);
const gchar* gst_tag_list_nth_tag_name (const GstTagList * list, guint index);
gboolean gst_tag_list_is_empty (const GstTagList * list);
@@ -219,7 +229,6 @@ void gst_tag_list_insert (GstTagList * into,
GstTagList * gst_tag_list_merge (const GstTagList * list1,
const GstTagList * list2,
GstTagMergeMode mode) G_GNUC_MALLOC;
-void gst_tag_list_free (GstTagList * list);
guint gst_tag_list_get_tag_size (const GstTagList * list,
const gchar * tag);
void gst_tag_list_add (GstTagList * list,
@@ -346,6 +355,104 @@ gboolean gst_tag_list_get_buffer_index (const GstTagList * list,
guint index,
GstBuffer ** value);
+/* refcounting */
+/**
+ * gst_tag_list_ref:
+ * @taglist: the #GstTagList to reference
+ *
+ * Add a reference to a #GstTagList mini object.
+ *
+ * From this point on, until the caller calls gst_tag_list_unref() or
+ * gst_tag_list_make_writable(), it is guaranteed that the taglist object will
+ * not change. To use a #GstTagList object, you must always have a refcount on
+ * it -- either the one made implicitly by e.g. gst_tag_list_new(), or via
+ * taking one explicitly with this function.
+ *
+ * Returns: the same #GstTagList mini object.
+ */
+#ifdef _FOOL_GTK_DOC_
+G_INLINE_FUNC GstTagList * gst_tag_list_ref (GstTagList * taglist);
+#endif
+
+static inline GstTagList *
+gst_tag_list_ref (GstTagList * taglist)
+{
+ return (GstTagList *) gst_mini_object_ref (GST_MINI_OBJECT_CAST (taglist));
+}
+
+/**
+ * gst_tag_list_unref:
+ * @taglist: a #GstTagList.
+ *
+ * Unref a #GstTagList, and and free all its memory when the refcount reaches 0.
+ */
+#ifdef _FOOL_GTK_DOC_
+G_INLINE_FUNC void gst_tag_list_unref (GstTagList * taglist);
+#endif
+
+static inline void
+gst_tag_list_unref (GstTagList * taglist)
+{
+ gst_mini_object_unref (GST_MINI_OBJECT_CAST (taglist));
+}
+
+/**
+ * gst_tag_list_copy:
+ * @taglist: a #GstTagList.
+ *
+ * Creates a new #GstTagList as a copy of the old @taglist. The new taglist
+ * will have a refcount of 1, owned by the caller, and will be writable as
+ * a result.
+ *
+ * Note that this function is the semantic equivalent of a gst_tag_list_ref()
+ * followed by a gst_tag_list_make_writable(). If you only want to hold on to a
+ * reference to the data, you should use gst_tag_list_ref().
+ *
+ * When you are finished with the taglist, call gst_tag_list_unref() on it.
+ *
+ * Returns: the new #GstTagList
+ */
+#ifdef _FOOL_GTK_DOC_
+G_INLINE_FUNC GstTagList * gst_tag_list_copy (const GstTagList * taglist);
+#endif
+
+static inline GstTagList *
+gst_tag_list_copy (const GstTagList * taglist)
+{
+ return GST_TAG_LIST (gst_mini_object_copy (GST_MINI_OBJECT_CAST (taglist)));
+}
+
+/**
+ * gst_tag_list_is_writable:
+ * @taglist: a #GstTagList
+ *
+ * Tests if you can safely modify @taglist. It is only safe to modify taglist
+ * when there is only one owner of the taglist - ie, the refcount is 1.
+ */
+#define gst_tag_list_is_writable(taglist) gst_mini_object_is_writable (GST_MINI_OBJECT_CAST (taglist))
+
+/**
+ * gst_tag_list_make_writable:
+ * @taglist: (transfer full): a #GstTagList
+ *
+ * Returns a writable copy of @taglist.
+ *
+ * If there is only one reference count on @taglist, the caller must be the
+ * owner, and so this function will return the taglist object unchanged. If on
+ * the other hand there is more than one reference on the object, a new taglist
+ * object will be returned (which will be a copy of @taglist). The caller's
+ * reference on @taglist will be removed, and instead the caller will own a
+ * reference to the returned object.
+ *
+ * In short, this function unrefs the taglist in the argument and refs the
+ * taglist that it returns. Don't access the argument after calling this
+ * function. See also: gst_tag_list_ref().
+ *
+ * Returns: (transfer full): a writable taglist which may or may not be the
+ * same as @taglist
+ */
+#define gst_tag_list_make_writable(taglist) GST_TAG_LIST (gst_mini_object_make_writable (GST_MINI_OBJECT_CAST (taglist)))
+
/* GStreamer core tags */
/**
* GST_TAG_TITLE:
@@ -723,7 +830,7 @@ gboolean gst_tag_list_get_buffer_index (const GstTagList * list,
/**
* GST_TAG_IMAGE:
*
- * image (sample) (sample caps should specify the content type and preferably
+ * image (sample) (sample taglist should specify the content type and preferably
* also set "image-type" field as #GstTagImageType)
*
* Since: 0.10.6
@@ -733,7 +840,7 @@ gboolean gst_tag_list_get_buffer_index (const GstTagList * list,
* GST_TAG_PREVIEW_IMAGE:
*
* image that is meant for preview purposes, e.g. small icon-sized version
- * (sample) (sample caps should specify the content type)
+ * (sample) (sample taglist should specify the content type)
*
* Since: 0.10.7
*/
@@ -742,7 +849,7 @@ gboolean gst_tag_list_get_buffer_index (const GstTagList * list,
/**
* GST_TAG_ATTACHMENT:
*
- * generic file attachment (sample) (sample caps should specify the content
+ * generic file attachment (sample) (sample taglist should specify the content
* type and if possible set "filename" to the file name of the
* attachment)
*
diff --git a/gst/gsttagsetter.c b/gst/gsttagsetter.c
index 2ed099d..b538c59 100644
--- a/gst/gsttagsetter.c
+++ b/gst/gsttagsetter.c
@@ -126,7 +126,7 @@ gst_tag_data_free (gpointer p)
GstTagData *data = (GstTagData *) p;
if (data->list)
- gst_tag_list_free (data->list);
+ gst_tag_list_unref (data->list);
g_mutex_clear (&data->lock);
@@ -181,7 +181,7 @@ gst_tag_setter_reset_tags (GstTagSetter * setter)
GST_TAG_DATA_LOCK (data);
if (data->list) {
- gst_tag_list_free (data->list);
+ gst_tag_list_unref (data->list);
data->list = NULL;
}
GST_TAG_DATA_UNLOCK (data);
diff --git a/gst/gsttoc.c b/gst/gsttoc.c
index 0ea0f33..b79717b 100644
--- a/gst/gsttoc.c
+++ b/gst/gsttoc.c
@@ -70,90 +70,12 @@
#include "gstvalue.h"
#include "gsttoc.h"
#include "gstpad.h"
+#include "gstquark.h"
-#define GST_TOC_TOC_NAME "toc"
-#define GST_TOC_ENTRY_NAME "entry"
-
-#define GST_TOC_TOC_UPDATED_FIELD "updated"
-#define GST_TOC_TOC_EXTENDUID_FIELD "extenduid"
-#define GST_TOC_INFO_FIELD "info"
-
-#define GST_TOC_ENTRY_UID_FIELD "uid"
-#define GST_TOC_ENTRY_TYPE_FIELD "type"
-#define GST_TOC_ENTRY_TAGS_FIELD "tags"
-
-#define GST_TOC_TOC_ENTRIES_FIELD "subentries"
-
-#define GST_TOC_INFO_NAME "info-structure"
-#define GST_TOC_INFO_TIME_FIELD "time"
-
-#define GST_TOC_TIME_NAME "time-structure"
-#define GST_TOC_TIME_START_FIELD "start"
-#define GST_TOC_TIME_STOP_FIELD "stop"
-
-
-enum
-{
- GST_TOC_TOC = 0,
- GST_TOC_ENTRY = 1,
- GST_TOC_UPDATED = 2,
- GST_TOC_EXTENDUID = 3,
- GST_TOC_UID = 4,
- GST_TOC_TYPE = 5,
- GST_TOC_TAGS = 6,
- GST_TOC_SUBENTRIES = 7,
- GST_TOC_INFO = 8,
- GST_TOC_INFONAME = 9,
- GST_TOC_TIME = 10,
- GST_TOC_TIMENAME = 11,
- GST_TOC_TIME_START = 12,
- GST_TOC_TIME_STOP = 13,
- GST_TOC_LAST = 14
-};
-
-static GQuark gst_toc_fields[GST_TOC_LAST] = { 0 };
-
-void
-_priv_gst_toc_initialize (void)
-{
- static gboolean inited = FALSE;
-
- if (G_LIKELY (!inited)) {
- gst_toc_fields[GST_TOC_TOC] = g_quark_from_static_string (GST_TOC_TOC_NAME);
- gst_toc_fields[GST_TOC_ENTRY] =
- g_quark_from_static_string (GST_TOC_ENTRY_NAME);
-
- gst_toc_fields[GST_TOC_UPDATED] =
- g_quark_from_static_string (GST_TOC_TOC_UPDATED_FIELD);
- gst_toc_fields[GST_TOC_EXTENDUID] =
- g_quark_from_static_string (GST_TOC_TOC_EXTENDUID_FIELD);
- gst_toc_fields[GST_TOC_INFO] =
- g_quark_from_static_string (GST_TOC_INFO_FIELD);
-
- gst_toc_fields[GST_TOC_UID] =
- g_quark_from_static_string (GST_TOC_ENTRY_UID_FIELD);
- gst_toc_fields[GST_TOC_TYPE] =
- g_quark_from_static_string (GST_TOC_ENTRY_TYPE_FIELD);
- gst_toc_fields[GST_TOC_TAGS] =
- g_quark_from_static_string (GST_TOC_ENTRY_TAGS_FIELD);
-
- gst_toc_fields[GST_TOC_SUBENTRIES] =
- g_quark_from_static_string (GST_TOC_TOC_ENTRIES_FIELD);
-
- gst_toc_fields[GST_TOC_INFONAME] =
- g_quark_from_static_string (GST_TOC_INFO_NAME);
- gst_toc_fields[GST_TOC_TIME] =
- g_quark_from_static_string (GST_TOC_INFO_TIME_FIELD);
- gst_toc_fields[GST_TOC_TIMENAME] =
- g_quark_from_static_string (GST_TOC_TIME_NAME);
- gst_toc_fields[GST_TOC_TIME_START] =
- g_quark_from_static_string (GST_TOC_TIME_START_FIELD);
- gst_toc_fields[GST_TOC_TIME_STOP] =
- g_quark_from_static_string (GST_TOC_TIME_STOP_FIELD);
-
- inited = TRUE;
- }
-}
+G_DEFINE_BOXED_TYPE (GstToc, gst_toc,
+ (GBoxedCopyFunc) gst_toc_copy, (GBoxedFreeFunc) gst_toc_free);
+G_DEFINE_BOXED_TYPE (GstTocEntry, gst_toc_entry,
+ (GBoxedCopyFunc) gst_toc_entry_copy, (GBoxedFreeFunc) gst_toc_entry_free);
/**
* gst_toc_new:
@@ -171,7 +93,7 @@ gst_toc_new (void)
toc = g_slice_new0 (GstToc);
toc->tags = gst_tag_list_new_empty ();
- toc->info = gst_structure_new_id_empty (gst_toc_fields[GST_TOC_INFONAME]);
+ toc->info = gst_structure_new_id_empty (GST_QUARK (INFO_STRUCTURE));
return toc;
}
@@ -198,7 +120,7 @@ gst_toc_entry_new (GstTocEntryType type, const gchar * uid)
entry->uid = g_strdup (uid);
entry->type = type;
entry->tags = gst_tag_list_new_empty ();
- entry->info = gst_structure_new_id_empty (gst_toc_fields[GST_TOC_INFONAME]);
+ entry->info = gst_structure_new_id_empty (GST_QUARK (INFO_STRUCTURE));
return entry;
}
@@ -218,7 +140,7 @@ gst_toc_entry_new (GstTocEntryType type, const gchar * uid)
*/
GstTocEntry *
gst_toc_entry_new_with_pad (GstTocEntryType type, const gchar * uid,
- gpointer pad)
+ GstPad * pad)
{
GstTocEntry *entry;
@@ -228,7 +150,7 @@ gst_toc_entry_new_with_pad (GstTocEntryType type, const gchar * uid,
entry->uid = g_strdup (uid);
entry->type = type;
entry->tags = gst_tag_list_new_empty ();
- entry->info = gst_structure_new_id_empty (gst_toc_fields[GST_TOC_INFONAME]);
+ entry->info = gst_structure_new_id_empty (GST_QUARK (INFO_STRUCTURE));
if (pad != NULL && GST_IS_PAD (pad))
entry->pads = g_list_append (entry->pads, gst_object_ref (pad));
@@ -253,7 +175,7 @@ gst_toc_free (GstToc * toc)
g_list_free (toc->entries);
if (toc->tags != NULL)
- gst_tag_list_free (toc->tags);
+ gst_tag_list_unref (toc->tags);
if (toc->info != NULL)
gst_structure_free (toc->info);
@@ -284,7 +206,7 @@ gst_toc_entry_free (GstTocEntry * entry)
g_free (entry->uid);
if (entry->tags != NULL)
- gst_tag_list_free (entry->tags);
+ gst_tag_list_unref (entry->tags);
if (entry->info != NULL)
gst_structure_free (entry->info);
@@ -305,22 +227,16 @@ static GstStructure *
gst_toc_structure_new (GstTagList * tags, GstStructure * info)
{
GstStructure *ret;
- GValue val = { 0 };
- ret = gst_structure_new_id_empty (gst_toc_fields[GST_TOC_TOC]);
+ ret = gst_structure_new_id_empty (GST_QUARK (TOC));
if (tags != NULL) {
- g_value_init (&val, GST_TYPE_STRUCTURE);
- gst_value_set_structure (&val, GST_STRUCTURE (tags));
- gst_structure_id_set_value (ret, gst_toc_fields[GST_TOC_TAGS], &val);
- g_value_unset (&val);
+ gst_structure_id_set (ret, GST_QUARK (TAGS), GST_TYPE_TAG_LIST, tags, NULL);
}
if (info != NULL) {
- g_value_init (&val, GST_TYPE_STRUCTURE);
- gst_value_set_structure (&val, info);
- gst_structure_id_set_value (ret, gst_toc_fields[GST_TOC_INFO], &val);
- g_value_unset (&val);
+ gst_structure_id_set (ret, GST_QUARK (INFO), GST_TYPE_STRUCTURE, info,
+ NULL);
}
return ret;
@@ -330,31 +246,21 @@ static GstStructure *
gst_toc_entry_structure_new (GstTocEntryType type, const gchar * uid,
GstTagList * tags, GstStructure * info)
{
- GValue val = { 0 };
GstStructure *ret;
- ret = gst_structure_new_id_empty (gst_toc_fields[GST_TOC_ENTRY]);
+ ret = gst_structure_new_id_empty (GST_QUARK (TOC_ENTRY));
- gst_structure_id_set (ret, gst_toc_fields[GST_TOC_TYPE],
- GST_TYPE_TOC_ENTRY_TYPE, type, NULL);
-
- g_value_init (&val, G_TYPE_STRING);
- g_value_set_string (&val, uid);
- gst_structure_id_set_value (ret, gst_toc_fields[GST_TOC_UID], &val);
- g_value_unset (&val);
+ gst_structure_id_set (ret, GST_QUARK (TYPE), GST_TYPE_TOC_ENTRY_TYPE, type,
+ NULL);
+ gst_structure_id_set (ret, GST_QUARK (UID), G_TYPE_STRING, uid, NULL);
if (tags != NULL) {
- g_value_init (&val, GST_TYPE_STRUCTURE);
- gst_value_set_structure (&val, GST_STRUCTURE (tags));
- gst_structure_id_set_value (ret, gst_toc_fields[GST_TOC_TAGS], &val);
- g_value_unset (&val);
+ gst_structure_id_set (ret, GST_QUARK (TAGS), GST_TYPE_TAG_LIST, tags, NULL);
}
if (info != NULL) {
- g_value_init (&val, GST_TYPE_STRUCTURE);
- gst_value_set_structure (&val, info);
- gst_structure_id_set_value (ret, gst_toc_fields[GST_TOC_INFO], &val);
- g_value_unset (&val);
+ gst_structure_id_set (ret, GST_QUARK (INFO), GST_TYPE_STRUCTURE, info,
+ NULL);
}
return ret;
@@ -364,11 +270,11 @@ static guint
gst_toc_entry_structure_n_subentries (const GstStructure * entry)
{
if (G_UNLIKELY (!gst_structure_id_has_field_typed (entry,
- gst_toc_fields[GST_TOC_SUBENTRIES], GST_TYPE_ARRAY)))
+ GST_QUARK (SUB_ENTRIES), GST_TYPE_ARRAY)))
return 0;
else
return gst_value_array_get_size ((gst_structure_id_get_value (entry,
- gst_toc_fields[GST_TOC_SUBENTRIES])));
+ GST_QUARK (SUB_ENTRIES))));
}
static const GstStructure *
@@ -383,12 +289,12 @@ gst_toc_entry_structure_nth_subentry (const GstStructure * entry, guint nth)
return NULL;
if (G_UNLIKELY (!gst_structure_id_has_field_typed (entry,
- gst_toc_fields[GST_TOC_SUBENTRIES], GST_TYPE_ARRAY)))
+ GST_QUARK (SUB_ENTRIES), GST_TYPE_ARRAY)))
return NULL;
else {
array =
gst_value_array_get_value (gst_structure_id_get_value (entry,
- gst_toc_fields[GST_TOC_SUBENTRIES]), nth);
+ GST_QUARK (SUB_ENTRIES)), nth);
return gst_value_get_structure (array);
}
}
@@ -407,20 +313,20 @@ gst_toc_entry_from_structure (const GstStructure * entry, guint level)
g_return_val_if_fail (entry != NULL, NULL);
g_return_val_if_fail (gst_structure_id_has_field_typed (entry,
- gst_toc_fields[GST_TOC_UID], G_TYPE_STRING), NULL);
+ GST_QUARK (UID), G_TYPE_STRING), NULL);
g_return_val_if_fail (gst_structure_id_has_field_typed (entry,
- gst_toc_fields[GST_TOC_TYPE], GST_TYPE_TOC_ENTRY_TYPE), NULL);
+ GST_QUARK (TYPE), GST_TYPE_TOC_ENTRY_TYPE), NULL);
- val = gst_structure_id_get_value (entry, gst_toc_fields[GST_TOC_UID]);
+ val = gst_structure_id_get_value (entry, GST_QUARK (UID));
uid = g_value_get_string (val);
ret = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_CHAPTER, uid);
- gst_structure_get_enum (entry, GST_TOC_ENTRY_TYPE_FIELD,
+ gst_structure_get_enum (entry, g_quark_to_string (GST_QUARK (TYPE)),
GST_TYPE_TOC_ENTRY_TYPE, (gint *) & (ret->type));
if (gst_structure_id_has_field_typed (entry,
- gst_toc_fields[GST_TOC_SUBENTRIES], GST_TYPE_ARRAY)) {
+ GST_QUARK (SUB_ENTRIES), GST_TYPE_ARRAY)) {
count = gst_toc_entry_structure_n_subentries (entry);
for (i = 0; i < count; ++i) {
@@ -460,20 +366,20 @@ gst_toc_entry_from_structure (const GstStructure * entry, guint level)
ret->subentries = g_list_reverse (ret->subentries);
}
- if (gst_structure_id_has_field_typed (entry,
- gst_toc_fields[GST_TOC_TAGS], GST_TYPE_STRUCTURE)) {
- val = gst_structure_id_get_value (entry, gst_toc_fields[GST_TOC_TAGS]);
+ if (gst_structure_id_has_field_typed (entry, GST_QUARK (TAGS),
+ GST_TYPE_TAG_LIST)) {
+ val = gst_structure_id_get_value (entry, GST_QUARK (TAGS));
- if (G_LIKELY (GST_IS_TAG_LIST (gst_value_get_structure (val)))) {
- list = gst_tag_list_copy (GST_TAG_LIST (gst_value_get_structure (val)));
- gst_tag_list_free (ret->tags);
+ if (G_LIKELY (GST_IS_TAG_LIST (g_value_get_boxed (val)))) {
+ list = gst_tag_list_copy (GST_TAG_LIST (g_value_get_boxed (val)));
+ gst_tag_list_unref (ret->tags);
ret->tags = list;
}
}
if (gst_structure_id_has_field_typed (entry,
- gst_toc_fields[GST_TOC_INFO], GST_TYPE_STRUCTURE)) {
- val = gst_structure_id_get_value (entry, gst_toc_fields[GST_TOC_INFO]);
+ GST_QUARK (INFO), GST_TYPE_STRUCTURE)) {
+ val = gst_structure_id_get_value (entry, GST_QUARK (INFO));
if (G_LIKELY (GST_IS_STRUCTURE (gst_value_get_structure (val)))) {
st = gst_structure_copy (gst_value_get_structure (val));
@@ -502,7 +408,7 @@ __gst_toc_from_structure (const GstStructure * toc)
ret = gst_toc_new ();
if (gst_structure_id_has_field_typed (toc,
- gst_toc_fields[GST_TOC_SUBENTRIES], GST_TYPE_ARRAY)) {
+ GST_QUARK (SUB_ENTRIES), GST_TYPE_ARRAY)) {
count = gst_toc_entry_structure_n_subentries (toc);
for (i = 0; i < count; ++i) {
@@ -544,20 +450,20 @@ __gst_toc_from_structure (const GstStructure * toc)
ret->entries = g_list_reverse (ret->entries);
}
- if (gst_structure_id_has_field_typed (toc,
- gst_toc_fields[GST_TOC_TAGS], GST_TYPE_STRUCTURE)) {
- val = gst_structure_id_get_value (toc, gst_toc_fields[GST_TOC_TAGS]);
+ if (gst_structure_id_has_field_typed (toc, GST_QUARK (TAGS),
+ GST_TYPE_TAG_LIST)) {
+ val = gst_structure_id_get_value (toc, GST_QUARK (TAGS));
- if (G_LIKELY (GST_IS_TAG_LIST (gst_value_get_structure (val)))) {
- list = gst_tag_list_copy (GST_TAG_LIST (gst_value_get_structure (val)));
- gst_tag_list_free (ret->tags);
+ if (G_LIKELY (GST_IS_TAG_LIST (g_value_get_boxed (val)))) {
+ list = gst_tag_list_copy (GST_TAG_LIST (g_value_get_boxed (val)));
+ gst_tag_list_unref (ret->tags);
ret->tags = list;
}
}
if (gst_structure_id_has_field_typed (toc,
- gst_toc_fields[GST_TOC_INFO], GST_TYPE_STRUCTURE)) {
- val = gst_structure_id_get_value (toc, gst_toc_fields[GST_TOC_INFO]);
+ GST_QUARK (INFO), GST_TYPE_STRUCTURE)) {
+ val = gst_structure_id_get_value (toc, GST_QUARK (INFO));
if (G_LIKELY (GST_IS_STRUCTURE (gst_value_get_structure (val)))) {
st = gst_structure_copy (gst_value_get_structure (val));
@@ -647,8 +553,7 @@ gst_toc_entry_to_structure (const GstTocEntry * entry, guint level)
cur = cur->next;
}
- gst_structure_id_set_value (ret, gst_toc_fields[GST_TOC_SUBENTRIES],
- &subentries_val);
+ gst_structure_id_set_value (ret, GST_QUARK (SUB_ENTRIES), &subentries_val);
g_value_unset (&subentries_val);
g_value_unset (&entry_val);
@@ -719,8 +624,7 @@ __gst_toc_to_structure (const GstToc * toc)
cur = cur->next;
}
- gst_structure_id_set_value (ret, gst_toc_fields[GST_TOC_SUBENTRIES],
- &subentries_val);
+ gst_structure_id_set_value (ret, GST_QUARK (SUB_ENTRIES), &subentries_val);
g_value_unset (&val);
g_value_unset (&subentries_val);
@@ -808,7 +712,7 @@ gst_toc_entry_copy (const GstTocEntry * entry)
if (GST_IS_TAG_LIST (entry->tags)) {
list = gst_tag_list_copy (entry->tags);
- gst_tag_list_free (ret->tags);
+ gst_tag_list_unref (ret->tags);
ret->tags = list;
}
@@ -866,7 +770,7 @@ gst_toc_copy (const GstToc * toc)
if (GST_IS_TAG_LIST (toc->tags)) {
list = gst_tag_list_copy (toc->tags);
- gst_tag_list_free (ret->tags);
+ gst_tag_list_unref (ret->tags);
ret->tags = list;
}
@@ -903,21 +807,19 @@ gst_toc_entry_set_start_stop (GstTocEntry * entry, gint64 start, gint64 stop)
g_return_if_fail (entry != NULL);
g_return_if_fail (GST_IS_STRUCTURE (entry->info));
- if (gst_structure_id_has_field_typed (entry->info,
- gst_toc_fields[GST_TOC_TIME], GST_TYPE_STRUCTURE)) {
- val =
- gst_structure_id_get_value (entry->info, gst_toc_fields[GST_TOC_TIME]);
+ if (gst_structure_id_has_field_typed (entry->info, GST_QUARK (TIME),
+ GST_TYPE_STRUCTURE)) {
+ val = gst_structure_id_get_value (entry->info, GST_QUARK (TIME));
structure = gst_structure_copy (gst_value_get_structure (val));
}
if (structure == NULL)
- structure = gst_structure_new_id_empty (gst_toc_fields[GST_TOC_TIMENAME]);
+ structure = gst_structure_new_id_empty (GST_QUARK (TIME_STRUCTURE));
- gst_structure_id_set (structure, gst_toc_fields[GST_TOC_TIME_START],
- G_TYPE_INT64, start, gst_toc_fields[GST_TOC_TIME_STOP], G_TYPE_INT64,
- stop, NULL);
+ gst_structure_id_set (structure, GST_QUARK (START),
+ G_TYPE_INT64, start, GST_QUARK (STOP), G_TYPE_INT64, stop, NULL);
- gst_structure_id_set (entry->info, gst_toc_fields[GST_TOC_TIME],
+ gst_structure_id_set (entry->info, GST_QUARK (TIME),
GST_TYPE_STRUCTURE, structure, NULL);
gst_structure_free (structure);
@@ -948,28 +850,28 @@ gst_toc_entry_get_start_stop (const GstTocEntry * entry, gint64 * start,
g_return_val_if_fail (GST_IS_STRUCTURE (entry->info), FALSE);
if (!gst_structure_id_has_field_typed (entry->info,
- gst_toc_fields[GST_TOC_TIME], GST_TYPE_STRUCTURE))
+ GST_QUARK (TIME), GST_TYPE_STRUCTURE))
return FALSE;
- val = gst_structure_id_get_value (entry->info, gst_toc_fields[GST_TOC_TIME]);
+ val = gst_structure_id_get_value (entry->info, GST_QUARK (TIME));
structure = gst_value_get_structure (val);
if (start != NULL) {
if (gst_structure_id_has_field_typed (structure,
- gst_toc_fields[GST_TOC_TIME_START], G_TYPE_INT64))
+ GST_QUARK (START), G_TYPE_INT64))
*start =
g_value_get_int64 (gst_structure_id_get_value (structure,
- gst_toc_fields[GST_TOC_TIME_START]));
+ GST_QUARK (START)));
else
ret = FALSE;
}
if (stop != NULL) {
if (gst_structure_id_has_field_typed (structure,
- gst_toc_fields[GST_TOC_TIME_STOP], G_TYPE_INT64))
+ GST_QUARK (STOP), G_TYPE_INT64))
*stop =
g_value_get_int64 (gst_structure_id_get_value (structure,
- gst_toc_fields[GST_TOC_TIME_STOP]));
+ GST_QUARK (STOP)));
else
ret = FALSE;
}
@@ -977,6 +879,25 @@ gst_toc_entry_get_start_stop (const GstTocEntry * entry, gint64 * start,
return ret;
}
+/**
+ * gst_toc_entry_type_get_nick:
+ * @type: a #GstTocEntryType.
+ *
+ * Converts @type to a string representation.
+ *
+ * Returns: Returns the human-readable @type. Can be NULL if an error occurred.
+ * Since: 0.11.92
+ */
+const gchar *
+gst_toc_entry_type_get_nick (GstTocEntryType type)
+{
+ const gchar *entry_types[] = { "chapter", "edition" };
+
+ g_return_val_if_fail ((gint) type >= 0
+ && (gint) type < G_N_ELEMENTS (entry_types), NULL);
+ return entry_types[type];
+}
+
gboolean
__gst_toc_structure_get_updated (const GstStructure * toc)
{
@@ -985,8 +906,8 @@ __gst_toc_structure_get_updated (const GstStructure * toc)
g_return_val_if_fail (GST_IS_STRUCTURE (toc), FALSE);
if (G_LIKELY (gst_structure_id_has_field_typed (toc,
- gst_toc_fields[GST_TOC_UPDATED], G_TYPE_BOOLEAN))) {
- val = gst_structure_id_get_value (toc, gst_toc_fields[GST_TOC_UPDATED]);
+ GST_QUARK (UPDATED), G_TYPE_BOOLEAN))) {
+ val = gst_structure_id_get_value (toc, GST_QUARK (UPDATED));
return g_value_get_boolean (val);
}
@@ -996,14 +917,10 @@ __gst_toc_structure_get_updated (const GstStructure * toc)
void
__gst_toc_structure_set_updated (GstStructure * toc, gboolean updated)
{
- GValue val = { 0 };
-
g_return_if_fail (toc != NULL);
- g_value_init (&val, G_TYPE_BOOLEAN);
- g_value_set_boolean (&val, updated);
- gst_structure_id_set_value (toc, gst_toc_fields[GST_TOC_UPDATED], &val);
- g_value_unset (&val);
+ gst_structure_id_set (toc, GST_QUARK (UPDATED), G_TYPE_BOOLEAN, updated,
+ NULL);
}
gchar *
@@ -1014,8 +931,8 @@ __gst_toc_structure_get_extend_uid (const GstStructure * toc)
g_return_val_if_fail (GST_IS_STRUCTURE (toc), NULL);
if (G_LIKELY (gst_structure_id_has_field_typed (toc,
- gst_toc_fields[GST_TOC_EXTENDUID], G_TYPE_STRING))) {
- val = gst_structure_id_get_value (toc, gst_toc_fields[GST_TOC_EXTENDUID]);
+ GST_QUARK (EXTEND_UID), G_TYPE_STRING))) {
+ val = gst_structure_id_get_value (toc, GST_QUARK (EXTEND_UID));
return g_strdup (g_value_get_string (val));
}
@@ -1026,13 +943,9 @@ void
__gst_toc_structure_set_extend_uid (GstStructure * toc,
const gchar * extend_uid)
{
- GValue val = { 0 };
-
g_return_if_fail (toc != NULL);
g_return_if_fail (extend_uid != NULL);
- g_value_init (&val, G_TYPE_STRING);
- g_value_set_string (&val, extend_uid);
- gst_structure_id_set_value (toc, gst_toc_fields[GST_TOC_EXTENDUID], &val);
- g_value_unset (&val);
+ gst_structure_id_set (toc, GST_QUARK (EXTEND_UID), G_TYPE_STRING, extend_uid,
+ NULL);
}
diff --git a/gst/gsttoc.h b/gst/gsttoc.h
index a1a7b8c..d59cf84 100644
--- a/gst/gsttoc.h
+++ b/gst/gsttoc.h
@@ -29,6 +29,9 @@
G_BEGIN_DECLS
+#define GST_TYPE_TOC (gst_toc_get_type ())
+#define GST_TYPE_TOC_ENTRY (gst_toc_entry_get_type ())
+
typedef struct _GstTocEntry GstTocEntry;
typedef struct _GstToc GstToc;
@@ -90,10 +93,14 @@ struct _GstToc {
gpointer _gst_reserved[GST_PADDING];
};
+/* functions to return type structures */
+GType gst_toc_get_type (void);
+GType gst_toc_entry_get_type (void);
+
/* functions to create new structures */
GstToc * gst_toc_new (void);
GstTocEntry * gst_toc_entry_new (GstTocEntryType type, const gchar *uid);
-GstTocEntry * gst_toc_entry_new_with_pad (GstTocEntryType type, const gchar *uid, gpointer pad);
+GstTocEntry * gst_toc_entry_new_with_pad (GstTocEntryType type, const gchar *uid, GstPad * pad);
/* functions to free structures */
void gst_toc_entry_free (GstTocEntry *entry);
@@ -105,6 +112,7 @@ GstToc * gst_toc_copy (const GstToc *toc);
void gst_toc_entry_set_start_stop (GstTocEntry *entry, gint64 start, gint64 stop);
gboolean gst_toc_entry_get_start_stop (const GstTocEntry *entry, gint64 *start, gint64 *stop);
+const gchar * gst_toc_entry_type_get_nick (GstTocEntryType type);
G_END_DECLS
diff --git a/gst/gsturi.c b/gst/gsturi.c
index afe2907..90e7461 100644
--- a/gst/gsturi.c
+++ b/gst/gsturi.c
@@ -578,6 +578,8 @@ gst_element_make_from_uri (const GstURIType type, const gchar * uri,
g_return_val_if_fail (GST_URI_TYPE_IS_VALID (type), NULL);
g_return_val_if_fail (gst_uri_is_valid (uri), NULL);
+ GST_DEBUG ("type:%d, uri:%s, elementname:%s", type, uri, elementname);
+
protocol = gst_uri_get_protocol (uri);
possibilities = get_element_factories_from_uri_protocol (type, protocol);
g_free (protocol);
@@ -598,6 +600,7 @@ gst_element_make_from_uri (const GstURIType type, const gchar * uri,
if (gst_uri_handler_set_uri (handler, uri, NULL))
break;
+ GST_WARNING ("element %s didn't accept the URI", GST_ELEMENT_NAME (ret));
gst_object_unref (ret);
ret = NULL;
}
diff --git a/gst/gstutils.c b/gst/gstutils.c
index 7771862..5c15341 100644
--- a/gst/gstutils.c
+++ b/gst/gstutils.c
@@ -2364,8 +2364,8 @@ gst_element_query_convert (GstElement * element, GstFormat src_format,
* PAUSED. If the element supports seek in READY, it will always return %TRUE when
* it receives the event in the READY state.
*
- * Returns: %TRUE if the seek operation succeeded (the seek might not always be
- * executed instantly though)
+ * Returns: %TRUE if the seek operation succeeded. Flushing seeks will trigger a
+ * preroll, which will emit %GST_MESSAGE_ASYNC_DONE.
*
* Since: 0.10.7
*/
@@ -2931,7 +2931,8 @@ gst_pad_query_accept_caps (GstPad * pad, GstCaps * caps)
g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
- GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "accept caps of %p", caps);
+ GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "accept caps of %"
+ GST_PTR_FORMAT, caps);
query = gst_query_new_accept_caps (caps);
if (gst_pad_query (pad, query)) {
diff --git a/gst/parse/Makefile.in b/gst/parse/Makefile.in
index 5915f4d..17fcfe4 100644
--- a/gst/parse/Makefile.in
+++ b/gst/parse/Makefile.in
@@ -52,6 +52,7 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
+target_triplet = @target@
subdir = gst/parse
DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in
@@ -257,6 +258,10 @@ GST_VERSION_MICRO = @GST_VERSION_MICRO@
GST_VERSION_MINOR = @GST_VERSION_MINOR@
GST_VERSION_NANO = @GST_VERSION_NANO@
GTKDOC_CHECK = @GTKDOC_CHECK@
+GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
+GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
+GTKDOC_MKPDF = @GTKDOC_MKPDF@
+GTKDOC_REBASE = @GTKDOC_REBASE@
HAVE_DOCBOOK2HTML = @HAVE_DOCBOOK2HTML@
HAVE_DOCBOOK2PS = @HAVE_DOCBOOK2PS@
HAVE_DVIPS = @HAVE_DVIPS@
@@ -409,7 +414,11 @@ sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
+target = @target@
target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@