gst: Add new GstContext miniobject for sharing contexts in a pipeline
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Thu, 28 Mar 2013 14:35:13 +0000 (15:35 +0100)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Fri, 29 Mar 2013 15:40:21 +0000 (16:40 +0100)
21 files changed:
docs/gst/gstreamer-docs.sgml
docs/gst/gstreamer-sections.txt
gst/Makefile.am
gst/gst.c
gst/gst_private.h
gst/gstbin.c
gst/gstcontext.c [new file with mode: 0644]
gst/gstcontext.h [new file with mode: 0644]
gst/gstelement.c
gst/gstelement.h
gst/gstevent.c
gst/gstevent.h
gst/gstinfo.c
gst/gstmessage.c
gst/gstmessage.h
gst/gstquark.c
gst/gstquark.h
gst/gstquery.c
gst/gstquery.h
win32/common/libgstbase.def
win32/common/libgstreamer.def

index d4388c2..1cfbe34 100644 (file)
@@ -69,6 +69,7 @@ Windows.  It is released under the GNU Library General Public License
     <xi:include href="xml/gstchildproxy.xml" />
     <xi:include href="xml/gstclock.xml" />
     <xi:include href="xml/gstconfig.xml" />
+    <xi:include href="xml/gstcontext.xml" />
     <xi:include href="xml/gstcontrolbinding.xml" />
     <xi:include href="xml/gstcontrolsource.xml" />
     <xi:include href="xml/gstdatetime.xml" />
index e6ccf1b..a96434c 100644 (file)
@@ -621,6 +621,26 @@ GST_PADDING_INIT
 GST_USING_PRINTF_EXTENSION
 </SECTION>
 
+<SECTION>
+<FILE>gstcontext</FILE>
+<TITLE>GstContext</TITLE>
+GstContext
+gst_context_new
+gst_context_ref
+gst_context_unref
+gst_context_copy
+gst_context_get_structure
+gst_context_make_writable
+gst_context_is_writable
+gst_context_replace
+<SUBSECTION Standard>
+GST_CONTEXT
+GST_CONTEXT_CAST
+GST_IS_CONTEXT
+GST_TYPE_CONTEXT
+<SUBSECTION Private>
+gst_context_get_type
+</SECTION>
 
 <SECTION>
 <FILE>gstcontrolbinding</FILE>
@@ -753,6 +773,7 @@ gst_element_set_start_time
 gst_element_get_start_time
 gst_element_set_bus
 gst_element_get_bus
+gst_element_set_context
 gst_element_get_factory
 gst_element_set_name
 gst_element_get_name
@@ -1025,6 +1046,9 @@ gst_event_parse_toc_select
 
 gst_event_new_segment_done
 gst_event_parse_segment_done
+
+gst_event_new_context
+gst_event_parse_context
 <SUBSECTION Standard>
 GstEventClass
 GST_EVENT
@@ -1469,6 +1493,13 @@ GstProgressType
 gst_message_new_progress
 gst_message_parse_progress
 
+gst_message_new_need_context
+gst_message_add_context_type
+gst_message_get_n_context_types
+gst_message_parse_nth_context_type
+gst_message_new_have_context
+gst_message_parse_have_context
+
 <SUBSECTION Standard>
 GstMessageClass
 GST_MESSAGE
@@ -2286,6 +2317,13 @@ gst_query_has_scheduling_mode
 gst_query_has_scheduling_mode_with_flags
 
 gst_query_new_drain
+
+gst_query_new_context
+gst_query_set_context
+gst_query_parse_context
+gst_query_add_context_type
+gst_query_get_n_context_types
+gst_query_parse_nth_context_type
 <SUBSECTION Standard>
 GstQueryClass
 GST_QUERY
index c1bdf0c..87db055 100644 (file)
@@ -57,6 +57,7 @@ libgstreamer_@GST_API_VERSION@_la_SOURCES = \
        gstcaps.c               \
        gstchildproxy.c         \
        gstclock.c              \
+       gstcontext.c \
        gstcontrolbinding.c \
        gstcontrolsource.c \
        gstdatetime.c           \
@@ -153,6 +154,7 @@ gst_headers =                       \
        gstchildproxy.h         \
        gstclock.h              \
        gstcompat.h             \
+       gstcontext.h \
        gstcontrolbinding.h \
        gstcontrolsource.h \
        gstdatetime.h           \
index 9274726..6a7219e 100644 (file)
--- a/gst/gst.c
+++ b/gst/gst.c
@@ -661,6 +661,7 @@ init_post (GOptionContext * context, GOptionGroup * group, gpointer data,
   _priv_gst_buffer_list_initialize ();
   _priv_gst_sample_initialize ();
   _priv_gst_value_initialize ();
+  _priv_gst_context_initialize ();
 
   g_type_class_ref (gst_param_spec_fraction_get_type ());
   _priv_gst_tag_initialize ();
index 99877c4..d42b48f 100644 (file)
@@ -116,6 +116,7 @@ G_GNUC_INTERNAL  void  _priv_gst_sample_initialize (void);
 G_GNUC_INTERNAL  void  _priv_gst_tag_initialize (void);
 G_GNUC_INTERNAL  void  _priv_gst_value_initialize (void);
 G_GNUC_INTERNAL  void  _priv_gst_debug_init (void);
+G_GNUC_INTERNAL  void  _priv_gst_context_initialize (void);
 
 /* Private registry functions */
 G_GNUC_INTERNAL
@@ -220,6 +221,7 @@ GST_EXPORT GstDebugCategory *GST_CAT_REGISTRY;
 GST_EXPORT GstDebugCategory *GST_CAT_QOS;
 GST_EXPORT GstDebugCategory *GST_CAT_META;
 GST_EXPORT GstDebugCategory *GST_CAT_LOCKING;
+GST_EXPORT GstDebugCategory *GST_CAT_CONTEXT;
 
 /* Categories that should be completely private to
  * libgstreamer should be done like this: */
@@ -262,6 +264,7 @@ extern GstDebugCategory *_priv_GST_CAT_POLL;
 #define GST_CAT_POLL             NULL
 #define GST_CAT_META             NULL
 #define GST_CAT_LOCKING          NULL
+#define GST_CAT_CONTEXT          NULL
 
 #endif
 
index c28f2d7..b182618 100644 (file)
@@ -189,6 +189,8 @@ struct _GstBinPrivate
 
   guint32 structure_cookie;
 
+  GstContext *context;
+
 #if 0
   /* cached index */
   GstIndex *index;
@@ -242,6 +244,7 @@ static gboolean gst_bin_send_event (GstElement * element, GstEvent * event);
 static GstBusSyncReply bin_bus_handler (GstBus * bus,
     GstMessage * message, GstBin * bin);
 static gboolean gst_bin_query (GstElement * element, GstQuery * query);
+static void gst_bin_set_context (GstElement * element, GstContext * context);
 
 static gboolean gst_bin_do_latency_func (GstBin * bin);
 
@@ -461,6 +464,7 @@ gst_bin_class_init (GstBinClass * klass)
 
   gstelement_class->send_event = GST_DEBUG_FUNCPTR (gst_bin_send_event);
   gstelement_class->query = GST_DEBUG_FUNCPTR (gst_bin_query);
+  gstelement_class->set_context = GST_DEBUG_FUNCPTR (gst_bin_set_context);
 
   klass->add_element = GST_DEBUG_FUNCPTR (gst_bin_add_func);
   klass->remove_element = GST_DEBUG_FUNCPTR (gst_bin_remove_func);
@@ -1140,6 +1144,9 @@ gst_bin_add_func (GstBin * bin, GstElement * element)
    * a new clock will be selected */
   gst_element_set_clock (element, GST_ELEMENT_CLOCK (bin));
 
+  if (bin->priv->context)
+    gst_element_set_context (element, bin->priv->context);
+
 #if 0
   /* set the cached index on the children */
   if (bin->priv->index)
@@ -3937,6 +3944,33 @@ gst_bin_query (GstElement * element, GstQuery * query)
   return res;
 }
 
+static void
+set_context (const GValue * item, gpointer user_data)
+{
+  GstElement *element = g_value_get_object (item);
+
+  gst_element_set_context (element, user_data);
+}
+
+static void
+gst_bin_set_context (GstElement * element, GstContext * context)
+{
+  GstBin *bin;
+  GstIterator *children;
+
+  g_return_if_fail (GST_IS_BIN (element));
+
+  bin = GST_BIN (element);
+
+  children = gst_bin_iterate_elements (bin);
+  while (gst_iterator_foreach (children, set_context,
+          context) == GST_ITERATOR_RESYNC);
+  gst_iterator_free (children);
+  GST_OBJECT_LOCK (bin);
+  gst_context_replace (&bin->priv->context, context);
+  GST_OBJECT_UNLOCK (bin);
+}
+
 static gint
 compare_name (const GValue * velement, const gchar * name)
 {
diff --git a/gst/gstcontext.c b/gst/gstcontext.c
new file mode 100644 (file)
index 0000000..6c6c38e
--- /dev/null
@@ -0,0 +1,180 @@
+/* GStreamer
+ * Copyright (C) 2013 Collabora Ltd.
+ *   Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
+ *
+ * gstcontext.h: Header for GstContext subsystem
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * SECTION:gstcontext
+ * @short_description: Lightweight objects to represent element contexts
+ * @see_also: #GstMiniObject, #GstElement
+ *
+ * #GstContext is a container object used to store contexts like a device
+ * context, a display server connection and similar concepts that should
+ * be shared between multiple elements.
+ *
+ * Applications can set a context on a complete pipeline by using
+ * gst_element_set_context(), which will then be propagated to all
+ * child elements. Elements can handle these in GstElement::set_context()
+ * and merge them with the context information they already have.
+ *
+ * When an element needs a context it will do the following actions in this
+ * order until one step succeeds:
+ * 1) Check if the element already has a context
+ * 2) Query downstream 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.
+ *
+ * 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 complete pipeline.
+ */
+
+#include "gst_private.h"
+#include <string.h>
+#include "gstcontext.h"
+#include "gstquark.h"
+
+struct _GstContext
+{
+  GstMiniObject mini_object;
+
+  GstStructure *structure;
+};
+
+#define GST_CONTEXT_STRUCTURE(c)  (((GstContext *)(c))->structure)
+
+static GType _gst_context_type = 0;
+GST_DEFINE_MINI_OBJECT_TYPE (GstContext, gst_context);
+
+void
+_priv_gst_context_initialize (void)
+{
+  GST_CAT_INFO (GST_CAT_GST_INIT, "init contexts");
+
+  /* the GstMiniObject types need to be class_ref'd once before it can be
+   * done from multiple threads;
+   * see http://bugzilla.gnome.org/show_bug.cgi?id=304551 */
+  gst_context_get_type ();
+
+  _gst_context_type = gst_context_get_type ();
+}
+
+static void
+_gst_context_free (GstContext * context)
+{
+  GstStructure *structure;
+
+  g_return_if_fail (context != NULL);
+
+  GST_CAT_LOG (GST_CAT_CONTEXT, "finalize context %p: %" GST_PTR_FORMAT,
+      context, GST_CONTEXT_STRUCTURE (context));
+
+  structure = GST_CONTEXT_STRUCTURE (context);
+  if (structure) {
+    gst_structure_set_parent_refcount (structure, NULL);
+    gst_structure_free (structure);
+  }
+
+  g_slice_free1 (sizeof (GstContext), context);
+}
+
+static void gst_context_init (GstContext * context);
+
+static GstContext *
+_gst_context_copy (GstContext * context)
+{
+  GstContext *copy;
+  GstStructure *structure;
+
+  GST_CAT_LOG (GST_CAT_CONTEXT, "copy context %p: %" GST_PTR_FORMAT, context,
+      GST_CONTEXT_STRUCTURE (context));
+
+  copy = g_slice_new0 (GstContext);
+
+  gst_context_init (copy);
+
+  structure = GST_CONTEXT_STRUCTURE (context);
+  GST_CONTEXT_STRUCTURE (copy) = gst_structure_copy (structure);
+  gst_structure_set_parent_refcount (GST_CONTEXT_STRUCTURE (copy),
+      &copy->mini_object.refcount);
+
+  return GST_CONTEXT_CAST (copy);
+}
+
+static void
+gst_context_init (GstContext * context)
+{
+  gst_mini_object_init (GST_MINI_OBJECT_CAST (context), 0, _gst_context_type,
+      (GstMiniObjectCopyFunction) _gst_context_copy, NULL,
+      (GstMiniObjectFreeFunction) _gst_context_free);
+}
+
+/**
+ * gst_context_new:
+ *
+ * Create a new context.
+ *
+ * Returns: (transfer full): The new context.
+ *
+ * MT safe.
+ */
+GstContext *
+gst_context_new (void)
+{
+  GstContext *context;
+  GstStructure *structure;
+
+  context = g_slice_new0 (GstContext);
+
+  GST_CAT_LOG (GST_CAT_CONTEXT, "creating new context %p", context);
+
+  structure = gst_structure_new_id_empty (GST_QUARK (CONTEXT));
+  gst_structure_set_parent_refcount (structure, &context->mini_object.refcount);
+  gst_context_init (context);
+
+  GST_CONTEXT_STRUCTURE (context) = structure;
+
+  return context;
+}
+
+/**
+ * gst_context_get_structure:
+ * @context: The #GstContext.
+ *
+ * Access the structure of the context.
+ *
+ * Returns: (transfer none): The structure of the context. The structure is
+ * still owned by the context, which means that you should not modify it,
+ * free it and that the pointer becomes invalid when you free the context.
+ *
+ * MT safe.
+ */
+const GstStructure *
+gst_context_get_structure (GstContext * context)
+{
+  g_return_val_if_fail (GST_IS_CONTEXT (context), NULL);
+
+  return GST_CONTEXT_STRUCTURE (context);
+}
diff --git a/gst/gstcontext.h b/gst/gstcontext.h
new file mode 100644 (file)
index 0000000..61e9180
--- /dev/null
@@ -0,0 +1,153 @@
+/* GStreamer
+ * Copyright (C) 2013 Collabora Ltd.
+ *   Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
+ *
+ * gstcontext.h: Header for GstContext subsystem
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_CONTEXT_H__
+#define __GST_CONTEXT_H__
+
+G_BEGIN_DECLS
+
+typedef struct _GstContext GstContext;
+
+#include <gst/gstminiobject.h>
+#include <gst/gststructure.h>
+
+#define GST_TYPE_CONTEXT                         (gst_context_get_type())
+#define GST_IS_CONTEXT(obj)                      (GST_IS_MINI_OBJECT_TYPE (obj, GST_TYPE_CONTEXT))
+#define GST_CONTEXT_CAST(obj)                    ((GstContext*)(obj))
+#define GST_CONTEXT(obj)                         (GST_CONTEXT_CAST(obj))
+
+
+
+GType           gst_context_get_type            (void);
+
+
+/* refcounting */
+/**
+ * gst_context_ref:
+ * @context: the context to ref
+ *
+ * Convenience macro to increase the reference count of the context.
+ *
+ * Returns: @context (for convenience when doing assignments)
+ */
+#ifdef _FOOL_GTK_DOC_
+G_INLINE_FUNC GstContext * gst_context_ref (GstContext * context);
+#endif
+
+static inline GstContext *
+gst_context_ref (GstContext * context)
+{
+  return (GstContext *) gst_mini_object_ref (GST_MINI_OBJECT_CAST (context));
+}
+
+/**
+ * gst_context_unref:
+ * @context: the context to unref
+ *
+ * Convenience macro to decrease the reference count of the context, possibly
+ * freeing it.
+ */
+#ifdef _FOOL_GTK_DOC_
+G_INLINE_FUNC void gst_context_unref (GstContext * context);
+#endif
+
+static inline void
+gst_context_unref (GstContext * context)
+{
+  gst_mini_object_unref (GST_MINI_OBJECT_CAST (context));
+}
+
+/* copy context */
+/**
+ * gst_context_copy:
+ * @context: the context to copy
+ *
+ * Creates a copy of the context. Returns a copy of the context.
+ *
+ * Returns: (transfer full): a new copy of @context.
+ *
+ * MT safe
+ */
+#ifdef _FOOL_GTK_DOC_
+G_INLINE_FUNC GstContext * gst_context_copy (const GstContext * context);
+#endif
+
+static inline GstContext *
+gst_context_copy (const GstContext * context)
+{
+  return GST_CONTEXT_CAST (gst_mini_object_copy (GST_MINI_OBJECT_CONST_CAST (context)));
+}
+
+/**
+ * gst_context_is_writable:
+ * @context: a #GstContext
+ *
+ * Tests if you can safely write into a context's structure or validly
+ * modify the seqnum and timestamp fields.
+ */
+#define         gst_context_is_writable(context)     gst_mini_object_is_writable (GST_MINI_OBJECT_CAST (context))
+/**
+ * gst_context_make_writable:
+ * @context: (transfer full): the context to make writable
+ *
+ * Checks if a context is writable. If not, a writable copy is made and
+ * returned.
+ *
+ * Returns: (transfer full): a context (possibly a duplicate) that is writable.
+ *
+ * MT safe
+ */
+#define         gst_context_make_writable(context)  GST_CONTEXT_CAST (gst_mini_object_make_writable (GST_MINI_OBJECT_CAST (context)))
+/**
+ * gst_context_replace:
+ * @old_context: (inout) (transfer full): pointer to a pointer to a #GstContext
+ *     to be replaced.
+ * @new_context: (allow-none) (transfer none): pointer to a #GstContext that will
+ *     replace the context pointed to by @old_context.
+ *
+ * Modifies a pointer to a #GstContext to point to a different #GstContext. The
+ * modification is done atomically (so this is useful for ensuring thread safety
+ * in some cases), and the reference counts are updated appropriately (the old
+ * context is unreffed, the new one is reffed).
+ *
+ * Either @new_context or the #GstContext pointed to by @old_context may be NULL.
+ *
+ * Returns: TRUE if @new_context was different from @old_context
+ */
+#ifdef _FOOL_GTK_DOC_
+G_INLINE_FUNC gboolean gst_context_replace (GstContext **old_context, GstContext *new_context);
+#endif
+
+static inline gboolean
+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;
+
+const GstStructure *
+                gst_context_get_structure       (GstContext *context);
+
+G_END_DECLS
+
+#endif /* __GST_CONTEXT_H__ */
index 7a7133f..b41fa26 100644 (file)
@@ -3011,3 +3011,29 @@ gst_element_get_bus (GstElement * element)
 
   return result;
 }
+
+/**
+ * gst_element_set_context:
+ * @element: a #GstElement to set the bus of.
+ * @context: (transfer none): the #GstContext to set.
+ *
+ * Sets the context of the element. Increases the refcount of the context.
+ *
+ * MT safe.
+ */
+void
+gst_element_set_context (GstElement * element, GstContext * context)
+{
+  GstElementClass *oclass;
+
+  g_return_if_fail (GST_IS_ELEMENT (element));
+
+  oclass = GST_ELEMENT_GET_CLASS (element);
+
+  GST_CAT_DEBUG_OBJECT (GST_CAT_CONTEXT, element,
+      "set context %p %" GST_PTR_FORMAT, context,
+      gst_context_get_structure (context));
+
+  if (oclass->set_context)
+    oclass->set_context (element, context);
+}
index c4c6dfa..afcb9c6 100644 (file)
@@ -593,6 +593,7 @@ struct _GstElement
  * @state_changed: called immediately after a new state was set.
  * @post_message: called when a message is posted on the element. Chain up to
  *                the parent class' handler to have it posted on the bus.
+ * @set_context: set a #GstContext on the element
  *
  * GStreamer element class. Override the vmethods to implement the element
  * functionality.
@@ -649,8 +650,10 @@ struct _GstElementClass
 
   gboolean              (*post_message)         (GstElement *element, GstMessage *message);
 
+  void                  (*set_context)          (GstElement *element, GstContext *context);
+
   /*< private >*/
-  gpointer _gst_reserved[GST_PADDING_LARGE-1];
+  gpointer _gst_reserved[GST_PADDING_LARGE-2];
 };
 
 /* element class pad templates */
@@ -737,6 +740,9 @@ GstClockTime            gst_element_get_start_time      (GstElement *element);
 void                    gst_element_set_bus             (GstElement * element, GstBus * bus);
 GstBus *                gst_element_get_bus             (GstElement * element);
 
+/* context */
+void                    gst_element_set_context         (GstElement * element, GstContext * context);
+
 /* pad management */
 gboolean                gst_element_add_pad             (GstElement *element, GstPad *pad);
 gboolean                gst_element_remove_pad          (GstElement *element, GstPad *pad);
index bb97363..1993ece 100644 (file)
@@ -116,6 +116,7 @@ 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},
@@ -1597,3 +1598,52 @@ gst_event_parse_segment_done (GstEvent * event, GstFormat * format,
   if (position != NULL)
     *position = g_value_get_int64 (val);
 }
+
+/**
+ * gst_event_new_context:
+ * @msg: (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
+ */
+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.
+ */
+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))));
+}
index 8656484..f0de0ad 100644 (file)
@@ -147,6 +147,7 @@ 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)),
@@ -180,6 +181,7 @@ typedef enum {
 #include <gst/gstsegment.h>
 #include <gst/gstsegment.h>
 #include <gst/gstmessage.h>
+#include <gst/gstcontext.h>
 
 G_BEGIN_DECLS
 
@@ -545,6 +547,10 @@ 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__ */
index 3cc9b13..21d53d8 100644 (file)
@@ -174,6 +174,7 @@ GstDebugCategory *GST_CAT_QOS = NULL;
 GstDebugCategory *_priv_GST_CAT_POLL = NULL;
 GstDebugCategory *GST_CAT_META = NULL;
 GstDebugCategory *GST_CAT_LOCKING = NULL;
+GstDebugCategory *GST_CAT_CONTEXT = NULL;
 
 
 #endif /* !defined(GST_DISABLE_GST_DEBUG) || !defined(GST_REMOVE_DISABLED) */
@@ -413,7 +414,7 @@ _priv_gst_debug_init (void)
   _priv_GST_CAT_POLL = _gst_debug_category_new ("GST_POLL", 0, "poll");
   GST_CAT_META = _gst_debug_category_new ("GST_META", 0, "meta");
   GST_CAT_LOCKING = _gst_debug_category_new ("GST_LOCKING", 0, "locking");
-
+  GST_CAT_CONTEXT = _gst_debug_category_new ("GST_CONTEXT", 0, NULL);
 
   /* print out the valgrind message if we're in valgrind */
   _priv_gst_in_valgrind ();
@@ -718,6 +719,23 @@ gst_debug_print_object (gpointer ptr)
     g_free (s);
     return ret;
   }
+  if (GST_IS_CONTEXT (object)) {
+    GstContext *context = GST_CONTEXT_CAST (object);
+    gchar *s, *ret;
+    const GstStructure *structure;
+
+    structure = gst_context_get_structure (context);
+
+    if (structure) {
+      s = gst_info_structure_to_string (structure);
+    } else {
+      s = g_strdup ("(NULL)");
+    }
+
+    ret = g_strdup_printf ("context '%s'", s);
+    g_free (s);
+    return ret;
+  }
 
   return g_strdup_printf ("%p", ptr);
 }
index d7982bf..2b231c4 100644 (file)
@@ -2150,3 +2150,184 @@ gst_message_new_stream_start (GstObject * src)
 
   return message;
 }
+
+/**
+ * gst_message_new_need_context:
+ * @src: (transfer none): The object originating the message.
+ *
+ * This message is posted when an element needs a specific #GstContext.
+ *
+ * Returns: (transfer full): The new need-context message.
+ *
+ * MT safe.
+ */
+GstMessage *
+gst_message_new_need_context (GstObject * src)
+{
+  GstMessage *message;
+  GstStructure *structure;
+
+  structure = gst_structure_new_id_empty (GST_QUARK (MESSAGE_NEED_CONTEXT));
+  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.
+ */
+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.
+ */
+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:
+ * @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.
+ *
+ * Returns: a #gboolean indicating if the parsing succeeded.
+ */
+gboolean
+gst_message_parse_nth_context_type (GstMessage * message, guint index,
+    const gchar ** context_type)
+{
+  GstStructure *structure;
+  GArray *array;
+
+  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);
+
+  return TRUE;
+}
+
+/**
+ * gst_message_new_have_context:
+ * @src: (transfer none): The object originating the message.
+ * @context: (transfer full): the context
+ *
+ * This message is posted when an element has a new local #GstContext.
+ *
+ * Returns: (transfer full): The new have-context message.
+ *
+ * MT safe.
+ */
+GstMessage *
+gst_message_new_have_context (GstObject * src, GstContext * context)
+{
+  GstMessage *message;
+  GstStructure *structure;
+
+  structure = gst_structure_new_id (GST_QUARK (MESSAGE_HAVE_CONTEXT),
+      GST_QUARK (CONTEXT), GST_TYPE_CONTEXT, context, NULL);
+  message = gst_message_new_custom (GST_MESSAGE_HAVE_CONTEXT, src, structure);
+  gst_context_unref (context);
+
+  return message;
+}
+
+/**
+ * gst_message_parse_have_context:
+ * @message: A valid #GstMessage of type GST_MESSAGE_HAVE_CONTEXT.
+ * @context: (out) (transfer full): Result location for the context or NULL
+ *
+ * Extract the context from the HAVE_CONTEXT message.
+ *
+ * MT safe.
+ */
+void
+gst_message_parse_have_context (GstMessage * message, GstContext ** context)
+{
+  g_return_if_fail (GST_IS_MESSAGE (message));
+  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_HAVE_CONTEXT);
+
+  if (context)
+    gst_structure_id_get (GST_MESSAGE_STRUCTURE (message),
+        GST_QUARK (CONTEXT), GST_TYPE_CONTEXT, context, NULL);
+}
index 614f5cc..802ee17 100644 (file)
@@ -136,6 +136,8 @@ typedef enum
   GST_MESSAGE_TOC               = (1 << 26),
   GST_MESSAGE_RESET_TIME        = (1 << 27),
   GST_MESSAGE_STREAM_START      = (1 << 28),
+  GST_MESSAGE_NEED_CONTEXT      = (1 << 29),
+  GST_MESSAGE_HAVE_CONTEXT      = (1 << 30),
   GST_MESSAGE_ANY               = ~0
 } GstMessageType;
 
@@ -557,6 +559,16 @@ void            gst_message_parse_reset_time    (GstMessage *message, GstClockTi
 /* STREAM_START */
 GstMessage *    gst_message_new_stream_start    (GstObject * src) G_GNUC_MALLOC;
 
+/* 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);
+
+/* HAVE_CONTEXT */
+GstMessage *    gst_message_new_have_context    (GstObject * src, GstContext *context) G_GNUC_MALLOC;
+void            gst_message_parse_have_context  (GstMessage *message, GstContext **context);
+
 G_END_DECLS
 
 #endif /* __GST_MESSAGE_H__ */
index f57810d..6343726 100644 (file)
@@ -66,7 +66,8 @@ static const gchar *_quark_strings[] = {
   "GstMessageResetTime",
   "GstMessageToc", "GstEventTocGlobal", "GstEventTocCurrent",
   "GstEventSegmentDone",
-  "GstEventStreamStart", "stream-id"
+  "GstEventStreamStart", "stream-id", "GstEventContext", "GstQueryContext",
+  "GstMessageNeedContext", "GstMessageHaveContext", "context", "context-types"
 };
 
 GQuark _priv_gst_quark_table[GST_QUARK_MAX];
index c632a18..1abc2ee 100644 (file)
@@ -188,7 +188,13 @@ typedef enum _GstQuarkId
   GST_QUARK_EVENT_SEGMENT_DONE = 159,
   GST_QUARK_EVENT_STREAM_START = 160,
   GST_QUARK_STREAM_ID = 161,
-  GST_QUARK_MAX = 162
+  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_MAX = 168
 } GstQuarkId;
 
 extern GQuark _priv_gst_quark_table[GST_QUARK_MAX];
index c62b021..d5f2962 100644 (file)
@@ -110,6 +110,7 @@ static GstQueryQuarks query_quarks[] = {
   {GST_QUERY_ACCEPT_CAPS, "accept-caps", 0},
   {GST_QUERY_CAPS, "caps", 0},
   {GST_QUERY_DRAIN, "drain", 0},
+  {GST_QUERY_CONTEXT, "context", 0},
 
   {0, NULL, 0}
 };
@@ -2430,3 +2431,152 @@ gst_query_new_drain (void)
 
   return query;
 }
+
+/**
+ * gst_query_new_context:
+ *
+ * Constructs a new query object for querying the pipeline-local context.
+ *
+ * Free-function: gst_query_unref
+ *
+ * Returns: (transfer full): a new #GstQuery
+ */
+GstQuery *
+gst_query_new_context (void)
+{
+  GstQuery *query;
+  GstStructure *structure;
+
+  structure = gst_structure_new_id_empty (GST_QUARK (QUERY_CONTEXT));
+  query = gst_query_new_custom (GST_QUERY_CONTEXT, structure);
+
+  return query;
+}
+
+/**
+ * gst_query_set_context:
+ * @query: a #GstQuery with query type GST_QUERY_CONTEXT
+ * @context: the requested #GstContext
+ *
+ * Answer a context query by setting the requested context.
+ */
+void
+gst_query_set_context (GstQuery * query, GstContext * context)
+{
+  GstStructure *s;
+
+  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CONTEXT);
+
+  s = GST_QUERY_STRUCTURE (query);
+
+  gst_structure_id_set (s,
+      GST_QUARK (CONTEXT), GST_TYPE_CONTEXT, context, NULL);
+}
+
+/**
+ * gst_query_parse_context:
+ * @query: The query to parse
+ * @context: (out): A pointer to store the #GstContext
+ *
+ * Get the context from the context @query. The context remains valid as long as
+ * @query remains valid.
+ */
+void
+gst_query_parse_context (GstQuery * query, GstContext ** context)
+{
+  GstStructure *structure;
+
+  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CONTEXT);
+  g_return_if_fail (context != NULL);
+
+  structure = GST_QUERY_STRUCTURE (query);
+  *context = g_value_get_boxed (gst_structure_id_get_value (structure,
+          GST_QUARK (CONTEXT)));
+}
+
+static void
+free_array_string (gpointer ptr)
+{
+  gchar *str = *(gchar **) ptr;
+  g_free (str);
+}
+
+/**
+ * gst_query_add_context_type:
+ * @query: a GST_QUERY_NEED_CONTEXT type query
+ * @context_type: a context type
+ *
+ * Add a new context type to @query.
+ */
+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_NEED_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.
+ */
+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:
+ * @query: a GST_QUERY_NEED_CONTEXT type query
+ * @context_type: (out) (allow-none): the context type, or NULL
+ *
+ * Parse a context type from an existing GST_QUERY_NEED_CONTEXT query
+ * from @index.
+ *
+ * Returns: a #gboolean indicating if the parsing succeeded.
+ */
+gboolean
+gst_query_parse_nth_context_type (GstQuery * query, guint index,
+    const gchar ** context_type)
+{
+  GstStructure *structure;
+  GArray *array;
+
+  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;
+}
index 1f16e30..c8eb6f9 100644 (file)
@@ -35,6 +35,7 @@
 #include <gst/gstpad.h>
 #include <gst/gstallocator.h>
 #include <gst/gsttoc.h>
+#include <gst/gstcontext.h>
 
 G_BEGIN_DECLS
 
@@ -101,6 +102,7 @@ typedef enum {
  * @GST_QUERY_ACCEPT_CAPS: the accept caps query
  * @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
  *
  * Standard predefined Query types
  */
@@ -124,7 +126,8 @@ typedef enum {
   GST_QUERY_SCHEDULING   = GST_QUERY_MAKE_TYPE (150, FLAG(UPSTREAM)),
   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_DRAIN        = GST_QUERY_MAKE_TYPE (180, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)),
+  GST_QUERY_CONTEXT      = GST_QUERY_MAKE_TYPE (190, FLAG(DOWNSTREAM))
 } GstQueryType;
 #undef FLAG
 
@@ -477,6 +480,14 @@ void            gst_query_parse_caps_result        (GstQuery *query, GstCaps **c
 /* drain query */
 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);
+void            gst_query_set_context              (GstQuery *query, GstContext *context);
+void            gst_query_parse_context            (GstQuery *query, GstContext **context);
+
 G_END_DECLS
 
 #endif /* __GST_QUERY_H__ */
index a36aac1..50d43f4 100644 (file)
@@ -31,6 +31,7 @@ EXPORTS
        gst_base_parse_set_duration
        gst_base_parse_set_frame_rate
        gst_base_parse_set_has_timing_info
+       gst_base_parse_set_infer_ts
        gst_base_parse_set_latency
        gst_base_parse_set_min_frame_size
        gst_base_parse_set_passthrough
index ba81ed2..0dcdce0 100644 (file)
@@ -5,6 +5,7 @@ EXPORTS
        GST_CAT_CALL_TRACE DATA
        GST_CAT_CAPS DATA
        GST_CAT_CLOCK DATA
+       GST_CAT_CONTEXT DATA
        GST_CAT_DEFAULT DATA
        GST_CAT_ELEMENT_PADS DATA
        GST_CAT_ERROR_SYSTEM DATA
@@ -269,6 +270,9 @@ EXPORTS
        gst_clock_single_shot_id_reinit
        gst_clock_type_get_type
        gst_clock_unadjust_unlocked
+       gst_context_get_structure
+       gst_context_get_type
+       gst_context_new
        gst_control_binding_get_g_value_array
        gst_control_binding_get_type
        gst_control_binding_get_value
@@ -419,6 +423,7 @@ EXPORTS
        gst_element_set_base_time
        gst_element_set_bus
        gst_element_set_clock
+       gst_element_set_context
        gst_element_set_locked_state
        gst_element_set_start_time
        gst_element_set_state
@@ -436,6 +441,7 @@ EXPORTS
        gst_event_has_name
        gst_event_new_buffer_size
        gst_event_new_caps
+       gst_event_new_context
        gst_event_new_custom
        gst_event_new_eos
        gst_event_new_flush_start
@@ -456,6 +462,7 @@ EXPORTS
        gst_event_new_toc_select
        gst_event_parse_buffer_size
        gst_event_parse_caps
+       gst_event_parse_context
        gst_event_parse_flush_stop
        gst_event_parse_gap
        gst_event_parse_latency
@@ -540,6 +547,8 @@ EXPORTS
        gst_memory_resize
        gst_memory_share
        gst_memory_unmap
+       gst_message_add_context_type
+       gst_message_get_n_context_types
        gst_message_get_seqnum
        gst_message_get_stream_status_object
        gst_message_get_structure
@@ -556,8 +565,10 @@ EXPORTS
        gst_message_new_element
        gst_message_new_eos
        gst_message_new_error
+       gst_message_new_have_context
        gst_message_new_info
        gst_message_new_latency
+       gst_message_new_need_context
        gst_message_new_new_clock
        gst_message_new_progress
        gst_message_new_qos
@@ -581,8 +592,10 @@ EXPORTS
        gst_message_parse_clock_lost
        gst_message_parse_clock_provide
        gst_message_parse_error
+       gst_message_parse_have_context
        gst_message_parse_info
        gst_message_parse_new_clock
+       gst_message_parse_nth_context_type
        gst_message_parse_progress
        gst_message_parse_qos
        gst_message_parse_qos_stats
@@ -860,12 +873,14 @@ EXPORTS
        gst_query_add_allocation_param
        gst_query_add_allocation_pool
        gst_query_add_buffering_range
+       gst_query_add_context_type
        gst_query_add_scheduling_mode
        gst_query_find_allocation_meta
        gst_query_get_n_allocation_metas
        gst_query_get_n_allocation_params
        gst_query_get_n_allocation_pools
        gst_query_get_n_buffering_ranges
+       gst_query_get_n_context_types
        gst_query_get_n_scheduling_modes
        gst_query_get_structure
        gst_query_get_type
@@ -875,6 +890,7 @@ EXPORTS
        gst_query_new_allocation
        gst_query_new_buffering
        gst_query_new_caps
+       gst_query_new_context
        gst_query_new_convert
        gst_query_new_custom
        gst_query_new_drain
@@ -894,6 +910,7 @@ EXPORTS
        gst_query_parse_buffering_stats
        gst_query_parse_caps
        gst_query_parse_caps_result
+       gst_query_parse_context
        gst_query_parse_convert
        gst_query_parse_duration
        gst_query_parse_latency
@@ -902,6 +919,7 @@ EXPORTS
        gst_query_parse_nth_allocation_param
        gst_query_parse_nth_allocation_pool
        gst_query_parse_nth_buffering_range
+       gst_query_parse_nth_context_type
        gst_query_parse_nth_format
        gst_query_parse_nth_scheduling_mode
        gst_query_parse_position
@@ -917,6 +935,7 @@ EXPORTS
        gst_query_set_buffering_range
        gst_query_set_buffering_stats
        gst_query_set_caps_result
+       gst_query_set_context
        gst_query_set_convert
        gst_query_set_duration
        gst_query_set_formats