diff options
author | Sebastian Dröge <slomo@circular-chaos.org> | 2013-09-19 12:31:13 +0200 |
---|---|---|
committer | Sebastian Dröge <slomo@circular-chaos.org> | 2013-09-19 12:31:13 +0200 |
commit | 63f3a12981d4257915f0c1651ab409a08a1c66f8 (patch) | |
tree | aede32630d47ab14da0fb9ca006a363ae3407dc3 /gst | |
parent | 63f38155df9cb281e4d48dbc14389e66446436f2 (diff) |
Imported Upstream version 1.1.90upstream/1.1.90
Diffstat (limited to 'gst')
-rw-r--r-- | gst/Makefile.in | 2 | ||||
-rw-r--r-- | gst/gst.c | 1 | ||||
-rw-r--r-- | gst/gstbin.c | 98 | ||||
-rw-r--r-- | gst/gstcontext.c | 86 | ||||
-rw-r--r-- | gst/gstcontext.h | 12 | ||||
-rw-r--r-- | gst/gstelement.c | 37 | ||||
-rw-r--r-- | gst/gstelement.h | 5 | ||||
-rw-r--r-- | gst/gstevent.c | 54 | ||||
-rw-r--r-- | gst/gstevent.h | 7 | ||||
-rw-r--r-- | gst/gstinfo.c | 10 | ||||
-rw-r--r-- | gst/gstmessage.c | 115 | ||||
-rw-r--r-- | gst/gstmessage.h | 6 | ||||
-rw-r--r-- | gst/gstmeta.c | 26 | ||||
-rw-r--r-- | gst/gstmeta.h | 12 | ||||
-rw-r--r-- | gst/gstquark.c | 4 | ||||
-rw-r--r-- | gst/gstquark.h | 19 | ||||
-rw-r--r-- | gst/gstquery.c | 125 | ||||
-rw-r--r-- | gst/gstquery.h | 11 | ||||
-rw-r--r-- | gst/parse/Makefile.in | 2 | ||||
-rw-r--r-- | gst/printf/Makefile.in | 2 |
20 files changed, 280 insertions, 354 deletions
diff --git a/gst/Makefile.in b/gst/Makefile.in index ed53fff..9fde22b 100644 --- a/gst/Makefile.in +++ b/gst/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.13.3 from Makefile.am. +# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. @@ -942,6 +942,7 @@ gst_deinit (void) return; } + g_thread_pool_set_max_unused_threads (0); bin_class = GST_BIN_CLASS (g_type_class_peek (gst_bin_get_type ())); if (bin_class->pool != NULL) { g_thread_pool_free (bin_class->pool, FALSE, TRUE); diff --git a/gst/gstbin.c b/gst/gstbin.c index 6da31e8..c03f9e0 100644 --- a/gst/gstbin.c +++ b/gst/gstbin.c @@ -198,6 +198,8 @@ struct _GstBinPrivate gboolean message_forward; gboolean posted_eos; + + GList *contexts; }; typedef struct @@ -530,6 +532,8 @@ gst_bin_dispose (GObject * object) GST_STR_NULL (GST_OBJECT_NAME (object))); } + g_list_free_full (bin->priv->contexts, (GDestroyNotify) gst_context_unref); + G_OBJECT_CLASS (parent_class)->dispose (object); } @@ -1094,6 +1098,7 @@ gst_bin_add_func (GstBin * bin, GstElement * element) gboolean is_sink, is_source, provides_clock, requires_clock; GstMessage *clock_message = NULL, *async_message = NULL; GstStateChangeReturn ret; + GList *l; GST_DEBUG_OBJECT (bin, "element :%s", GST_ELEMENT_NAME (element)); @@ -1165,8 +1170,8 @@ gst_bin_add_func (GstBin * bin, GstElement * element) * a new clock will be selected */ gst_element_set_clock (element, GST_ELEMENT_CLOCK (bin)); - if (GST_ELEMENT_CAST (bin)->context) - gst_element_set_context (element, GST_ELEMENT_CAST (bin)->context); + for (l = bin->priv->contexts; l; l = l->next) + gst_element_set_context (element, l->data); #if 0 /* set the cached index on the children */ @@ -2579,9 +2584,30 @@ gst_bin_change_state_func (GstElement * element, GstStateChange transition) goto activate_failure; break; case GST_STATE_NULL: - if (current == GST_STATE_READY) + if (current == GST_STATE_READY) { + GList *l; + if (!(gst_bin_src_pads_activate (bin, FALSE))) goto activate_failure; + + /* Remove all non-persistent contexts */ + GST_OBJECT_LOCK (bin); + for (l = bin->priv->contexts; l;) { + GstContext *context = l->data; + + if (!gst_context_is_persistent (context)) { + GList *next; + + gst_context_unref (context); + next = l->next; + bin->priv->contexts = g_list_delete_link (bin->priv->contexts, l); + l = next; + } else { + l = l->next; + } + } + GST_OBJECT_UNLOCK (bin); + } break; default: break; @@ -3272,6 +3298,34 @@ bin_do_message_forward (GstBin * bin, GstMessage * message) } } +static void +gst_bin_update_context (GstBin * bin, GstContext * context) +{ + GList *l; + const gchar *context_type; + + GST_OBJECT_LOCK (bin); + context_type = gst_context_get_context_type (context); + for (l = bin->priv->contexts; l; l = l->next) { + GstContext *tmp = l->data; + const gchar *tmp_type = gst_context_get_context_type (tmp); + + /* Always store newest context but never replace + * a persistent one by a non-persistent one */ + if (strcmp (context_type, tmp_type) == 0 && + (gst_context_is_persistent (context) || + !gst_context_is_persistent (tmp))) { + gst_context_replace ((GstContext **) & l->data, context); + break; + } + } + /* Not found? Add */ + if (l != NULL) + bin->priv->contexts = + g_list_prepend (bin->priv->contexts, gst_context_ref (context)); + GST_OBJECT_UNLOCK (bin); +} + /* handle child messages: * * This method is called synchronously when a child posts a message on @@ -3628,6 +3682,42 @@ gst_bin_handle_message_func (GstBin * bin, GstMessage * message) break; } + case GST_MESSAGE_NEED_CONTEXT:{ + const gchar *context_type; + GList *l; + + gst_message_parse_context_type (message, &context_type); + GST_OBJECT_LOCK (bin); + for (l = bin->priv->contexts; l; l = l->next) { + GstContext *tmp = l->data; + const gchar *tmp_type = gst_context_get_context_type (tmp); + + if (strcmp (context_type, tmp_type) == 0) { + gst_element_set_context (GST_ELEMENT (src), l->data); + break; + } + } + GST_OBJECT_UNLOCK (bin); + + /* Forward if we couldn't answer the message */ + if (l == NULL) { + goto forward; + } else { + gst_message_unref (message); + } + + break; + } + case GST_MESSAGE_HAVE_CONTEXT:{ + GstContext *context; + + gst_message_parse_have_context (message, &context); + gst_bin_update_context (bin, context); + gst_context_unref (context); + + goto forward; + break; + } default: goto forward; } @@ -3992,6 +4082,8 @@ gst_bin_set_context (GstElement * element, GstContext * context) bin = GST_BIN (element); + gst_bin_update_context (bin, context); + children = gst_bin_iterate_elements (bin); while (gst_iterator_foreach (children, set_context, context) == GST_ITERATOR_RESYNC); diff --git a/gst/gstcontext.c b/gst/gstcontext.c index 92afb75..d8c7e5c 100644 --- a/gst/gstcontext.c +++ b/gst/gstcontext.c @@ -1,6 +1,7 @@ /* GStreamer * Copyright (C) 2013 Collabora Ltd. * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk> + * Copyright (C) 2013 Sebastian Dröge <slomo@circular-chaos.org> * * gstcontext.h: Header for GstContext subsystem * @@ -38,17 +39,15 @@ * order until one step succeeds: * 1) Check if the element already has a context * 2) Query downstream with GST_QUERY_CONTEXT for the context + * 2) Query upstream with GST_QUERY_CONTEXT for the context * 3) Post a GST_MESSAGE_NEED_CONTEXT message on the bus with the required * context types and afterwards check if a usable context was set now * 4) Create a context by itself and post a GST_MESSAGE_HAVE_CONTEXT message - * and send a GST_EVENT_CONTEXT event downstream, containing the complete - * context information at this time. + * on the bus. * - * Applications should catch the GST_MESSAGE_HAVE_CONTEXT messages and remember - * any content from it unless it has a custom version of a specific context. If - * later an element is posting a GST_MESSAGE_NEED_CONTEXT message for a specific - * context that was created by an element before, the application should pass it - * to the element or the complete pipeline. + * Bins will catch GST_MESSAGE_NEED_CONTEXT messages and will set any previously + * known context on the element that asks for it if possible. Otherwise the + * application should provide one if it can. * * Since: 1.2 */ @@ -62,7 +61,9 @@ struct _GstContext { GstMiniObject mini_object; + gchar *context_type; GstStructure *structure; + gboolean persistent; }; #define GST_CONTEXT_STRUCTURE(c) (((GstContext *)(c))->structure) @@ -98,6 +99,7 @@ _gst_context_free (GstContext * context) gst_structure_set_parent_refcount (structure, NULL); gst_structure_free (structure); } + g_free (context->context_type); g_slice_free1 (sizeof (GstContext), context); } @@ -117,11 +119,15 @@ _gst_context_copy (GstContext * context) gst_context_init (copy); + copy->context_type = g_strdup (context->context_type); + structure = GST_CONTEXT_STRUCTURE (context); GST_CONTEXT_STRUCTURE (copy) = gst_structure_copy (structure); gst_structure_set_parent_refcount (GST_CONTEXT_STRUCTURE (copy), ©->mini_object.refcount); + copy->persistent = context->persistent; + return GST_CONTEXT_CAST (copy); } @@ -135,6 +141,7 @@ gst_context_init (GstContext * context) /** * gst_context_new: + * @persistent: Persistent context * * Create a new context. * @@ -143,11 +150,13 @@ gst_context_init (GstContext * context) * Since: 1.2 */ GstContext * -gst_context_new (void) +gst_context_new (const gchar * context_type, gboolean persistent) { GstContext *context; GstStructure *structure; + g_return_val_if_fail (context_type != NULL, NULL); + context = g_slice_new0 (GstContext); GST_CAT_LOG (GST_CAT_CONTEXT, "creating new context %p", context); @@ -156,12 +165,53 @@ gst_context_new (void) gst_structure_set_parent_refcount (structure, &context->mini_object.refcount); gst_context_init (context); + context->context_type = g_strdup (context_type); GST_CONTEXT_STRUCTURE (context) = structure; + context->persistent = persistent; return context; } /** + * gst_context_get_context_type: + * @context: The #GstContext. + * + * Get the type of @context. + * + * Returns: The type of the context. + * + * Since: 1.2 + */ +const gchar * +gst_context_get_context_type (const GstContext * context) +{ + g_return_val_if_fail (GST_IS_CONTEXT (context), NULL); + + return context->context_type; +} + +/** + * gst_context_has_context_type: + * @context: The #GstContext. + * @context_type: Context type to check. + * + * Checks if @context has @context_type. + * + * Returns: %TRUE if @context has @context_type. + * + * Since: 1.2 + */ +gboolean +gst_context_has_context_type (const GstContext * context, + const gchar * context_type) +{ + g_return_val_if_fail (GST_IS_CONTEXT (context), NULL); + g_return_val_if_fail (context_type != NULL, NULL); + + return strcmp (context->context_type, context_type) == 0; +} + +/** * gst_context_get_structure: * @context: The #GstContext. * @@ -174,7 +224,7 @@ gst_context_new (void) * Since: 1.2 */ const GstStructure * -gst_context_get_structure (GstContext * context) +gst_context_get_structure (const GstContext * context) { g_return_val_if_fail (GST_IS_CONTEXT (context), NULL); @@ -202,3 +252,21 @@ gst_context_writable_structure (GstContext * context) return GST_CONTEXT_STRUCTURE (context); } + +/** + * gst_context_is_persistent: + * @context: The #GstContext. + * + * Check if @context is persistent. + * + * Returns: %TRUE if the context is persistent. + * + * Since: 1.2 + */ +gboolean +gst_context_is_persistent (const GstContext * context) +{ + g_return_val_if_fail (GST_IS_CONTEXT (context), NULL); + + return context->persistent; +} diff --git a/gst/gstcontext.h b/gst/gstcontext.h index 7f4a565..9dd0914 100644 --- a/gst/gstcontext.h +++ b/gst/gstcontext.h @@ -1,6 +1,7 @@ /* GStreamer * Copyright (C) 2013 Collabora Ltd. * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk> + * Copyright (C) 2013 Sebastian Dröge <slomo@circular-chaos.org> * * gstcontext.h: Header for GstContext subsystem * @@ -143,10 +144,15 @@ gst_context_replace (GstContext **old_context, GstContext *new_context) return gst_mini_object_replace ((GstMiniObject **) old_context, (GstMiniObject *) new_context); } -GstContext * gst_context_new (void) G_GNUC_MALLOC; +GstContext * gst_context_new (const gchar * context_type, + gboolean persistent) G_GNUC_MALLOC; -const GstStructure * gst_context_get_structure (GstContext *context); -GstStructure * gst_context_writable_structure (GstContext *context); +const gchar * gst_context_get_context_type (const GstContext * context); +gboolean gst_context_has_context_type (const GstContext * context, const gchar * context_type); +const GstStructure * gst_context_get_structure (const GstContext * context); +GstStructure * gst_context_writable_structure (GstContext * context); + +gboolean gst_context_is_persistent (const GstContext * context); G_END_DECLS diff --git a/gst/gstelement.c b/gst/gstelement.c index 7ee52e3..6af2ca1 100644 --- a/gst/gstelement.c +++ b/gst/gstelement.c @@ -136,8 +136,6 @@ static gboolean gst_element_set_clock_func (GstElement * element, static void gst_element_set_bus_func (GstElement * element, GstBus * bus); static gboolean gst_element_post_message_default (GstElement * element, GstMessage * message); -static void gst_element_set_context_func (GstElement * element, - GstContext * context); static gboolean gst_element_default_send_event (GstElement * element, GstEvent * event); @@ -244,7 +242,6 @@ gst_element_class_init (GstElementClass * klass) klass->send_event = GST_DEBUG_FUNCPTR (gst_element_default_send_event); klass->numpadtemplates = 0; klass->post_message = GST_DEBUG_FUNCPTR (gst_element_post_message_default); - klass->set_context = GST_DEBUG_FUNCPTR (gst_element_set_context_func); klass->elementfactory = NULL; } @@ -2915,7 +2912,6 @@ gst_element_dispose (GObject * object) bus_p = &element->bus; gst_object_replace ((GstObject **) clock_p, NULL); gst_object_replace ((GstObject **) bus_p, NULL); - gst_context_replace (&element->context, NULL); GST_OBJECT_UNLOCK (element); GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "parent class dispose"); @@ -3026,14 +3022,6 @@ gst_element_get_bus (GstElement * element) return result; } -static void -gst_element_set_context_func (GstElement * element, GstContext * context) -{ - GST_OBJECT_LOCK (element); - gst_context_replace (&element->context, context); - GST_OBJECT_UNLOCK (element); -} - /** * gst_element_set_context: * @element: a #GstElement to set the context of. @@ -3059,28 +3047,3 @@ gst_element_set_context (GstElement * element, GstContext * context) if (oclass->set_context) oclass->set_context (element, context); } - -/** - * gst_element_get_context: - * @element: a #GstElement to get the context from. - * - * Gets the current context of the element. - * - * MT safe. - * - * Returns: (transfer full): The current context of the element - */ -GstContext * -gst_element_get_context (GstElement * element) -{ - GstContext *context = NULL; - - g_return_val_if_fail (GST_IS_ELEMENT (element), NULL); - - GST_OBJECT_LOCK (element); - if (element->context) - context = gst_context_ref (element->context); - GST_OBJECT_UNLOCK (element); - - return context ? context : gst_context_new (); -} diff --git a/gst/gstelement.h b/gst/gstelement.h index 15d4c75..73ca545 100644 --- a/gst/gstelement.h +++ b/gst/gstelement.h @@ -568,10 +568,8 @@ struct _GstElement GList *sinkpads; guint32 pads_cookie; - GstContext *context; - /*< private >*/ - gpointer _gst_reserved[GST_PADDING-1]; + gpointer _gst_reserved[GST_PADDING]; }; /** @@ -744,7 +742,6 @@ GstBus * gst_element_get_bus (GstElement * element); /* context */ void gst_element_set_context (GstElement * element, GstContext * context); -GstContext * gst_element_get_context (GstElement * element); /* pad management */ gboolean gst_element_add_pad (GstElement *element, GstPad *pad); diff --git a/gst/gstevent.c b/gst/gstevent.c index f47c928..a26cd9e 100644 --- a/gst/gstevent.c +++ b/gst/gstevent.c @@ -116,7 +116,6 @@ static GstEventQuarks event_quarks[] = { {GST_EVENT_BUFFERSIZE, "buffersize", 0}, {GST_EVENT_SINK_MESSAGE, "sink-message", 0}, {GST_EVENT_EOS, "eos", 0}, - {GST_EVENT_CONTEXT, "context", 0}, {GST_EVENT_SEGMENT_DONE, "segment-done", 0}, {GST_EVENT_GAP, "gap", 0}, {GST_EVENT_QOS, "qos", 0}, @@ -1687,56 +1686,3 @@ gst_event_parse_segment_done (GstEvent * event, GstFormat * format, if (position != NULL) *position = g_value_get_int64 (val); } - -/** - * gst_event_new_context: - * @context: (transfer full): the #GstContext - * - * Create a new context event. The purpose of the context event is - * to pass a pipeline-local context to downstream elements. - * - * Returns: (transfer full): a new #GstEvent - * - * Since: 1.2 - */ -GstEvent * -gst_event_new_context (GstContext * context) -{ - GstEvent *event; - GstStructure *structure; - - g_return_val_if_fail (context != NULL, NULL); - - GST_CAT_INFO (GST_CAT_EVENT, "creating context event"); - - structure = gst_structure_new_id (GST_QUARK (EVENT_SEEK), - GST_QUARK (CONTEXT), GST_TYPE_CONTEXT, context, NULL); - event = gst_event_new_custom (GST_EVENT_CONTEXT, structure); - gst_context_unref (context); - - return event; -} - -/** - * gst_event_parse_context: - * @event: The event to query - * @context: (out) (transfer full): a pointer to store the #GstContext in. - * - * Parse the context event. Unref @context after usage. - * - * Since: 1.2 - */ -void -gst_event_parse_context (GstEvent * event, GstContext ** context) -{ - const GstStructure *structure; - - g_return_if_fail (GST_IS_EVENT (event)); - g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_CONTEXT); - - structure = GST_EVENT_STRUCTURE (event); - if (context) - *context = - GST_CONTEXT (g_value_dup_boxed (gst_structure_id_get_value - (structure, GST_QUARK (CONTEXT)))); -} diff --git a/gst/gstevent.h b/gst/gstevent.h index f4723ec..0d1f58d 100644 --- a/gst/gstevent.h +++ b/gst/gstevent.h @@ -99,8 +99,6 @@ typedef enum { * @GST_EVENT_GAP: Marks a gap in the datastream. * @GST_EVENT_TOC: An event which indicates that a new table of contents (TOC) * was found or updated. - * @GST_EVENT_CONTEXT: An event to communicate a #GstContext to other - * elements (Since 1.2) * @GST_EVENT_QOS: A quality message. Used to indicate to upstream elements * that the downstream elements should adjust their processing * rate. @@ -149,7 +147,6 @@ typedef enum { 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_CONTEXT = GST_EVENT_MAKE_TYPE (130, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY) | FLAG(STICKY_MULTI)), /* non-sticky downstream serialized */ GST_EVENT_SEGMENT_DONE = GST_EVENT_MAKE_TYPE (150, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)), @@ -579,10 +576,6 @@ void gst_event_parse_toc_select (GstEvent *event, gchar **uid); GstEvent* gst_event_new_segment_done (GstFormat format, gint64 position) G_GNUC_MALLOC; void gst_event_parse_segment_done (GstEvent *event, GstFormat *format, gint64 *position); -/* context */ -GstEvent* gst_event_new_context (GstContext * context) G_GNUC_MALLOC; -void gst_event_parse_context (GstEvent *event, GstContext **context); - G_END_DECLS #endif /* __GST_EVENT_H__ */ diff --git a/gst/gstinfo.c b/gst/gstinfo.c index ea2876d..5501217 100644 --- a/gst/gstinfo.c +++ b/gst/gstinfo.c @@ -709,17 +709,15 @@ gst_debug_print_object (gpointer ptr) if (GST_IS_CONTEXT (object)) { GstContext *context = GST_CONTEXT_CAST (object); gchar *s, *ret; + const gchar *type; const GstStructure *structure; + type = gst_context_get_context_type (context); structure = gst_context_get_structure (context); - if (structure) { - s = gst_info_structure_to_string (structure); - } else { - s = g_strdup ("(NULL)"); - } + s = gst_info_structure_to_string (structure); - ret = g_strdup_printf ("context '%s'", s); + ret = g_strdup_printf ("context '%s'='%s'", type, s); g_free (s); return ret; } diff --git a/gst/gstmessage.c b/gst/gstmessage.c index 7ed646b..1e6deff 100644 --- a/gst/gstmessage.c +++ b/gst/gstmessage.c @@ -107,6 +107,8 @@ static GstMessageQuarks message_quarks[] = { {GST_MESSAGE_TOC, "toc", 0}, {GST_MESSAGE_RESET_TIME, "reset-time", 0}, {GST_MESSAGE_STREAM_START, "stream-start", 0}, + {GST_MESSAGE_NEED_CONTEXT, "need-context", 0}, + {GST_MESSAGE_HAVE_CONTEXT, "have-context", 0}, {0, NULL, 0} }; @@ -2226,6 +2228,7 @@ gst_message_parse_group_id (GstMessage * message, guint * group_id) /** * gst_message_new_need_context: * @src: (transfer none): The object originating the message. + * @context_type: The context type that is needed * * This message is posted when an element needs a specific #GstContext. * @@ -2236,133 +2239,47 @@ gst_message_parse_group_id (GstMessage * message, guint * group_id) * Since: 1.2 */ GstMessage * -gst_message_new_need_context (GstObject * src) +gst_message_new_need_context (GstObject * src, const gchar * context_type) { GstMessage *message; GstStructure *structure; - structure = gst_structure_new_id_empty (GST_QUARK (MESSAGE_NEED_CONTEXT)); + g_return_val_if_fail (context_type != NULL, NULL); + + structure = gst_structure_new_id (GST_QUARK (MESSAGE_NEED_CONTEXT), + GST_QUARK (CONTEXT_TYPE), G_TYPE_STRING, context_type, NULL); message = gst_message_new_custom (GST_MESSAGE_NEED_CONTEXT, src, structure); return message; } -static GArray * -ensure_array (GstStructure * s, GQuark quark, gsize element_size, - GDestroyNotify clear_func) -{ - GArray *array; - const GValue *value; - - value = gst_structure_id_get_value (s, quark); - if (value) { - array = (GArray *) g_value_get_boxed (value); - } else { - GValue new_array_val = { 0, }; - - array = g_array_new (FALSE, TRUE, element_size); - if (clear_func) - g_array_set_clear_func (array, clear_func); - - g_value_init (&new_array_val, G_TYPE_ARRAY); - g_value_take_boxed (&new_array_val, array); - - gst_structure_id_take_value (s, quark, &new_array_val); - } - return array; -} - -static void -free_array_string (gpointer ptr) -{ - gchar *str = *(gchar **) ptr; - g_free (str); -} - -/** - * gst_message_add_context_type: - * @message: a GST_MESSAGE_NEED_CONTEXT type message - * @context_type: a context type - * - * Add a new context type to @message. - * - * Since: 1.2 - */ -void -gst_message_add_context_type (GstMessage * message, const gchar * context_type) -{ - GstStructure *structure; - GArray *array; - gchar *copy; - - g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_NEED_CONTEXT); - g_return_if_fail (gst_message_is_writable (message)); - - structure = GST_MESSAGE_STRUCTURE (message); - array = ensure_array (structure, GST_QUARK (CONTEXT_TYPES), - sizeof (gchar *), free_array_string); - - copy = g_strdup (context_type); - g_array_append_val (array, copy); -} - /** - * gst_message_get_n_context_types: - * @message: a GST_MESSAGE_NEED_CONTEXT type message - * - * Retrieve the number of values currently stored in the - * context-types array of the message's structure. - * - * Returns: the context-types array size as a #guint. - * - * Since: 1.2 - */ -guint -gst_message_get_n_context_types (GstMessage * message) -{ - GstStructure *structure; - GArray *array; - - g_return_val_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_NEED_CONTEXT, - 0); - - structure = GST_MESSAGE_STRUCTURE (message); - array = ensure_array (structure, GST_QUARK (CONTEXT_TYPES), - sizeof (gchar *), free_array_string); - - return array->len; -} - -/** - * gst_message_parse_nth_context_type: + * gst_message_parse_context_type: * @message: a GST_MESSAGE_NEED_CONTEXT type message * @context_type: (out) (allow-none): the context type, or NULL * - * Parse a context type from an existing GST_MESSAGE_NEED_CONTEXT message - * from @index. + * Parse a context type from an existing GST_MESSAGE_NEED_CONTEXT message. * * Returns: a #gboolean indicating if the parsing succeeded. * * Since: 1.2 */ gboolean -gst_message_parse_nth_context_type (GstMessage * message, guint index, +gst_message_parse_context_type (GstMessage * message, const gchar ** context_type) { GstStructure *structure; - GArray *array; + const GValue *value; g_return_val_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_NEED_CONTEXT, FALSE); structure = GST_MESSAGE_STRUCTURE (message); - array = ensure_array (structure, GST_QUARK (CONTEXT_TYPES), - sizeof (gchar *), free_array_string); - g_return_val_if_fail (index < array->len, FALSE); - - if (context_type) - *context_type = g_array_index (array, gchar *, index); + if (context_type) { + value = gst_structure_id_get_value (structure, GST_QUARK (CONTEXT_TYPE)); + *context_type = g_value_get_string (value); + } return TRUE; } diff --git a/gst/gstmessage.h b/gst/gstmessage.h index e359187..38e6d7e 100644 --- a/gst/gstmessage.h +++ b/gst/gstmessage.h @@ -565,10 +565,8 @@ void gst_message_set_group_id (GstMessage *message, guint grou gboolean gst_message_parse_group_id (GstMessage *message, guint *group_id); /* NEED_CONTEXT */ -GstMessage * gst_message_new_need_context (GstObject * src) G_GNUC_MALLOC; -void gst_message_add_context_type (GstMessage * message, const gchar * context_type); -guint gst_message_get_n_context_types (GstMessage * message); -gboolean gst_message_parse_nth_context_type (GstMessage * message, guint i, const gchar ** context_type); +GstMessage * gst_message_new_need_context (GstObject * src, const gchar * context_type) G_GNUC_MALLOC; +gboolean gst_message_parse_context_type (GstMessage * message, const gchar ** context_type); /* HAVE_CONTEXT */ GstMessage * gst_message_new_have_context (GstObject * src, GstContext *context) G_GNUC_MALLOC; diff --git a/gst/gstmeta.c b/gst/gstmeta.c index 819c72e..51936a3 100644 --- a/gst/gstmeta.c +++ b/gst/gstmeta.c @@ -98,6 +98,10 @@ gst_meta_api_type_register (const gchar * api, const gchar ** tags) GINT_TO_POINTER (TRUE)); } } + + g_type_set_qdata (type, g_quark_from_string ("tags"), + g_strdupv ((gchar **) tags)); + return type; } @@ -120,6 +124,28 @@ gst_meta_api_type_has_tag (GType api, GQuark tag) } /** + * gst_meta_api_type_get_tags: + * @api: an API + * + * Returns: (transfer none) (array zero-terminated=1) (element-type utf8): an array of tags as strings. + * + * Since: 1.2 + */ +const gchar *const * +gst_meta_api_type_get_tags (GType api) +{ + const gchar **tags; + g_return_val_if_fail (api != 0, FALSE); + + tags = g_type_get_qdata (api, g_quark_from_string ("tags")); + + if (!tags[0]) + return NULL; + + return (const gchar * const *) tags; +} + +/** * gst_meta_register: * @api: the type of the #GstMeta API * @impl: the name of the #GstMeta implementation diff --git a/gst/gstmeta.h b/gst/gstmeta.h index 08411e3..d294126 100644 --- a/gst/gstmeta.h +++ b/gst/gstmeta.h @@ -82,6 +82,14 @@ typedef enum { #define GST_META_FLAG_UNSET(meta,flag) (GST_META_FLAGS (meta) &= ~(flag)) /** + * GST_META_TAG_MEMORY_STR: + * This metadata stays relevant as long as memory layout is unchanged. + * + * Since: 1.2 + */ +#define GST_META_TAG_MEMORY_STR "memory" + +/** * GstMeta: * @flags: extra flags for the metadata * @info: pointer to the #GstMetaInfo @@ -199,6 +207,7 @@ const GstMetaInfo * gst_meta_register (GType api, const gchar *impl, GstMetaFreeFunction free_func, GstMetaTransformFunction transform_func); const GstMetaInfo * gst_meta_get_info (const gchar * impl); +const gchar* const* gst_meta_api_type_get_tags (GType api); /* some default tags */ GST_EXPORT GQuark _gst_meta_tag_memory; @@ -208,6 +217,9 @@ GST_EXPORT GQuark _gst_meta_tag_memory; * * Metadata tagged with this tag depends on the particular memory * or buffer that it is on. + * + * Deprecated: The GQuarks are not exported by any public API, use + * GST_META_TAG_MEMORY_STR instead. */ #define GST_META_TAG_MEMORY (_gst_meta_tag_memory) diff --git a/gst/gstquark.c b/gst/gstquark.c index 2f818d2..5598b99 100644 --- a/gst/gstquark.c +++ b/gst/gstquark.c @@ -66,8 +66,8 @@ static const gchar *_quark_strings[] = { "GstMessageResetTime", "GstMessageToc", "GstEventTocGlobal", "GstEventTocCurrent", "GstEventSegmentDone", - "GstEventStreamStart", "stream-id", "GstEventContext", "GstQueryContext", - "GstMessageNeedContext", "GstMessageHaveContext", "context", "context-types", + "GstEventStreamStart", "stream-id", "GstQueryContext", + "GstMessageNeedContext", "GstMessageHaveContext", "context", "context-type", "GstMessageStreamStart", "group-id", "uri-redirection" }; diff --git a/gst/gstquark.h b/gst/gstquark.h index e8667e7..025f508 100644 --- a/gst/gstquark.h +++ b/gst/gstquark.h @@ -188,16 +188,15 @@ typedef enum _GstQuarkId GST_QUARK_EVENT_SEGMENT_DONE = 159, GST_QUARK_EVENT_STREAM_START = 160, GST_QUARK_STREAM_ID = 161, - GST_QUARK_EVENT_CONTEXT = 162, - GST_QUARK_QUERY_CONTEXT = 163, - GST_QUARK_MESSAGE_NEED_CONTEXT = 164, - GST_QUARK_MESSAGE_HAVE_CONTEXT = 165, - GST_QUARK_CONTEXT = 166, - GST_QUARK_CONTEXT_TYPES = 167, - GST_QUARK_MESSAGE_STREAM_START = 168, - GST_QUARK_GROUP_ID = 169, - GST_QUARK_URI_REDIRECTION = 170, - GST_QUARK_MAX = 171 + GST_QUARK_QUERY_CONTEXT = 162, + GST_QUARK_MESSAGE_NEED_CONTEXT = 163, + GST_QUARK_MESSAGE_HAVE_CONTEXT = 164, + GST_QUARK_CONTEXT = 165, + GST_QUARK_CONTEXT_TYPE = 166, + GST_QUARK_MESSAGE_STREAM_START = 167, + GST_QUARK_GROUP_ID = 168, + GST_QUARK_URI_REDIRECTION = 169, + GST_QUARK_MAX = 170 } GstQuarkId; extern GQuark _priv_gst_quark_table[GST_QUARK_MAX]; diff --git a/gst/gstquery.c b/gst/gstquery.c index 3b9eddc..4466413 100644 --- a/gst/gstquery.c +++ b/gst/gstquery.c @@ -2489,6 +2489,7 @@ gst_query_new_drain (void) /** * gst_query_new_context: + * @context_type: Context type to query * * Constructs a new query object for querying the pipeline-local context. * @@ -2499,12 +2500,15 @@ gst_query_new_drain (void) * Since: 1.2 */ GstQuery * -gst_query_new_context (void) +gst_query_new_context (const gchar * context_type) { GstQuery *query; GstStructure *structure; - structure = gst_structure_new_id_empty (GST_QUARK (QUERY_CONTEXT)); + g_return_val_if_fail (context_type != NULL, NULL); + + structure = gst_structure_new_id (GST_QUARK (QUERY_CONTEXT), + GST_QUARK (CONTEXT_TYPE), G_TYPE_STRING, context_type, NULL); query = gst_query_new_custom (GST_QUERY_CONTEXT, structure); return query; @@ -2523,9 +2527,14 @@ void gst_query_set_context (GstQuery * query, GstContext * context) { GstStructure *s; + const gchar *context_type; g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CONTEXT); + gst_query_parse_context_type (query, &context_type); + g_return_if_fail (strcmp (gst_context_get_context_type (context), + context_type) == 0); + s = GST_QUERY_STRUCTURE (query); gst_structure_id_set (s, @@ -2559,127 +2568,31 @@ gst_query_parse_context (GstQuery * query, GstContext ** context) *context = NULL; } -static void -free_array_string (gpointer ptr) -{ - gchar *str = *(gchar **) ptr; - g_free (str); -} - -/** - * gst_query_add_context_type: - * @query: a GST_QUERY_CONTEXT type query - * @context_type: a context type - * - * Add a new context type to @query. - * - * Since: 1.2 - */ -void -gst_query_add_context_type (GstQuery * query, const gchar * context_type) -{ - GstStructure *structure; - GArray *array; - gchar *copy; - - g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CONTEXT); - g_return_if_fail (gst_query_is_writable (query)); - - structure = GST_QUERY_STRUCTURE (query); - array = ensure_array (structure, GST_QUARK (CONTEXT_TYPES), - sizeof (gchar *), free_array_string); - - copy = g_strdup (context_type); - g_array_append_val (array, copy); -} - -/** - * gst_query_get_n_context_types: - * @query: a GST_QUERY_CONTEXT type query - * - * Retrieve the number of values currently stored in the - * context-types array of the query's structure. - * - * Returns: the context-types array size as a #guint. - * - * Since: 1.2 - */ -guint -gst_query_get_n_context_types (GstQuery * query) -{ - GstStructure *structure; - GArray *array; - - g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CONTEXT, 0); - - structure = GST_QUERY_STRUCTURE (query); - array = ensure_array (structure, GST_QUARK (CONTEXT_TYPES), - sizeof (gchar *), free_array_string); - - return array->len; -} - /** - * gst_query_parse_nth_context_type: + * gst_query_parse_context_type: * @query: a GST_QUERY_CONTEXT type query * @context_type: (out) (transfer none) (allow-none): the context type, or NULL * - * Parse a context type from an existing GST_QUERY_CONTEXT query - * from @index. + * Parse a context type from an existing GST_QUERY_CONTEXT query. * * Returns: a #gboolean indicating if the parsing succeeded. * * Since: 1.2 */ gboolean -gst_query_parse_nth_context_type (GstQuery * query, guint index, - const gchar ** context_type) +gst_query_parse_context_type (GstQuery * query, const gchar ** context_type) { GstStructure *structure; - GArray *array; + const GValue *value; g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CONTEXT, FALSE); structure = GST_QUERY_STRUCTURE (query); - array = ensure_array (structure, GST_QUARK (CONTEXT_TYPES), - sizeof (gchar *), free_array_string); - g_return_val_if_fail (index < array->len, FALSE); - - if (context_type) - *context_type = g_array_index (array, gchar *, index); - - return TRUE; -} - -/** - * gst_query_has_context_type: - * @query: a GST_QUERY_CONTEXT type query - * @context_type: the context type - * - * Check if @query is asking for @context_type. - * - * Returns: %TRUE if @context_type is requested. - * - * Since: 1.2 - */ -gboolean -gst_query_has_context_type (GstQuery * query, const gchar * context_type) -{ - guint i, n; - - g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CONTEXT, FALSE); - g_return_val_if_fail (context_type != NULL, FALSE); - - n = gst_query_get_n_context_types (query); - for (i = 0; i < n; i++) { - const gchar *tmp; - - if (gst_query_parse_nth_context_type (query, i, &tmp) && - strcmp (tmp, context_type) == 0) - return TRUE; + if (context_type) { + value = gst_structure_id_get_value (structure, GST_QUARK (CONTEXT_TYPE)); + *context_type = g_value_get_string (value); } - - return FALSE; + return TRUE; } diff --git a/gst/gstquery.h b/gst/gstquery.h index 7b8d582..8943b86 100644 --- a/gst/gstquery.h +++ b/gst/gstquery.h @@ -103,7 +103,7 @@ typedef enum { * @GST_QUERY_CAPS: the caps query * @GST_QUERY_DRAIN: wait till all serialized data is consumed downstream * @GST_QUERY_CONTEXT: query the pipeline-local context from - * downstream (since 1.2) + * downstream or upstream (since 1.2) * * Standard predefined Query types */ @@ -128,7 +128,7 @@ typedef enum { GST_QUERY_ACCEPT_CAPS = GST_QUERY_MAKE_TYPE (160, FLAG(BOTH)), GST_QUERY_CAPS = GST_QUERY_MAKE_TYPE (170, FLAG(BOTH)), GST_QUERY_DRAIN = GST_QUERY_MAKE_TYPE (180, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)), - GST_QUERY_CONTEXT = GST_QUERY_MAKE_TYPE (190, FLAG(DOWNSTREAM)) + GST_QUERY_CONTEXT = GST_QUERY_MAKE_TYPE (190, FLAG(BOTH)) } GstQueryType; #undef FLAG @@ -486,11 +486,8 @@ void gst_query_parse_caps_result (GstQuery *query, GstCaps **c GstQuery * gst_query_new_drain (void) G_GNUC_MALLOC; /* context query */ -GstQuery * gst_query_new_context (void) G_GNUC_MALLOC; -void gst_query_add_context_type (GstQuery * query, const gchar * context_type); -guint gst_query_get_n_context_types (GstQuery * query); -gboolean gst_query_parse_nth_context_type (GstQuery * query, guint i, const gchar ** context_type); -gboolean gst_query_has_context_type (GstQuery * query, const gchar * context_type); +GstQuery * gst_query_new_context (const gchar * context_type) G_GNUC_MALLOC; +gboolean gst_query_parse_context_type (GstQuery * query, const gchar ** context_type); void gst_query_set_context (GstQuery *query, GstContext *context); void gst_query_parse_context (GstQuery *query, GstContext **context); diff --git a/gst/parse/Makefile.in b/gst/parse/Makefile.in index 82ee195..9e65380 100644 --- a/gst/parse/Makefile.in +++ b/gst/parse/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.13.3 from Makefile.am. +# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. diff --git a/gst/printf/Makefile.in b/gst/printf/Makefile.in index 1295058..5594dec 100644 --- a/gst/printf/Makefile.in +++ b/gst/printf/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.13.3 from Makefile.am. +# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. |