+ g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_URI);
+ g_return_if_fail (gst_query_is_writable (query));
+
+ structure = GST_QUERY_STRUCTURE (query);
+ gst_structure_id_set (structure, GST_QUARK (URI_REDIRECTION_PERMANENT),
+ G_TYPE_BOOLEAN, permanent, NULL);
+}
+
+/**
+ * gst_query_parse_uri_redirection_permanent:
+ * @query: a #GstQuery
+ * @permanent: (out) (allow-none): if the URI redirection is permanent
+ * (may be %NULL)
+ *
+ * Parse an URI query, and set @permanent to %TRUE if there is a redirection
+ * and it should be considered permanent. If a redirection is permanent,
+ * applications should update their internal storage of the URI, otherwise
+ * they should make all future requests to the original URI.
+ *
+ * Since: 1.4
+ */
+void
+gst_query_parse_uri_redirection_permanent (GstQuery * query,
+ gboolean * permanent)
+{
+ GstStructure *structure;
+
+ g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_URI);
+
+ structure = GST_QUERY_STRUCTURE (query);
+ if (permanent) {
+ if (!gst_structure_id_get (structure, GST_QUARK (URI_REDIRECTION_PERMANENT),
+ G_TYPE_BOOLEAN, permanent, NULL))
+ *permanent = FALSE;
+ }
+}
+
+/**
+ * gst_query_new_allocation:
+ * @caps: the negotiated caps
+ * @need_pool: return a pool
+ *
+ * Constructs a new query object for querying the allocation properties.
+ *
+ * Free-function: gst_query_unref
+ *
+ * Returns: (transfer full): a new #GstQuery
+ */
+GstQuery *
+gst_query_new_allocation (GstCaps * caps, gboolean need_pool)
+{
+ GstQuery *query;
+ GstStructure *structure;
+
+ structure = gst_structure_new_id (GST_QUARK (QUERY_ALLOCATION),
+ GST_QUARK (CAPS), GST_TYPE_CAPS, caps,
+ GST_QUARK (NEED_POOL), G_TYPE_BOOLEAN, need_pool, NULL);
+
+ query = gst_query_new_custom (GST_QUERY_ALLOCATION, structure);
+
+ return query;
+}
+
+/**
+ * gst_query_parse_allocation:
+ * @query: a #GstQuery
+ * @caps: (out) (transfer none) (allow-none): The #GstCaps
+ * @need_pool: (out) (allow-none): Whether a #GstBufferPool is needed
+ *
+ * Parse an allocation query, writing the requested caps in @caps and
+ * whether a pool is needed in @need_pool, if the respective parameters
+ * are non-%NULL.
+ */
+void
+gst_query_parse_allocation (GstQuery * query, GstCaps ** caps,
+ gboolean * need_pool)
+{
+ GstStructure *structure;
+
+ g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
+
+ structure = GST_QUERY_STRUCTURE (query);
+ if (caps) {
+ *caps = g_value_get_boxed (gst_structure_id_get_value (structure,
+ GST_QUARK (CAPS)));
+ }
+ gst_structure_id_get (structure,
+ GST_QUARK (NEED_POOL), G_TYPE_BOOLEAN, need_pool, NULL);
+}
+
+typedef struct
+{
+ GstBufferPool *pool;
+ guint size;
+ guint min_buffers;
+ guint max_buffers;
+} AllocationPool;
+
+static void
+allocation_pool_free (AllocationPool * ap)
+{
+ if (ap->pool)
+ gst_object_unref (ap->pool);
+}
+
+/**
+ * gst_query_add_allocation_pool:
+ * @query: A valid #GstQuery of type GST_QUERY_ALLOCATION.
+ * @pool: the #GstBufferPool
+ * @size: the size
+ * @min_buffers: the min buffers
+ * @max_buffers: the max buffers
+ *
+ * Set the pool parameters in @query.
+ */
+void
+gst_query_add_allocation_pool (GstQuery * query, GstBufferPool * pool,
+ guint size, guint min_buffers, guint max_buffers)
+{
+ GArray *array;
+ GstStructure *structure;
+ AllocationPool ap;
+
+ g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
+ g_return_if_fail (gst_query_is_writable (query));
+ g_return_if_fail (size != 0);
+
+ structure = GST_QUERY_STRUCTURE (query);
+ array = ensure_array (structure, GST_QUARK (POOL),
+ sizeof (AllocationPool), (GDestroyNotify) allocation_pool_free);
+
+ if ((ap.pool = pool))
+ gst_object_ref (pool);
+ ap.size = size;
+ ap.min_buffers = min_buffers;
+ ap.max_buffers = max_buffers;
+
+ g_array_append_val (array, ap);
+}
+
+
+/**
+ * gst_query_get_n_allocation_pools:
+ * @query: a GST_QUERY_ALLOCATION type query #GstQuery
+ *
+ * Retrieve the number of values currently stored in the
+ * pool array of the query's structure.
+ *
+ * Returns: the pool array size as a #guint.
+ */
+guint
+gst_query_get_n_allocation_pools (GstQuery * query)
+{
+ GArray *array;
+ GstStructure *structure;
+
+ g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, 0);
+
+ structure = GST_QUERY_STRUCTURE (query);
+ array = ensure_array (structure, GST_QUARK (POOL),
+ sizeof (AllocationPool), (GDestroyNotify) allocation_pool_free);
+
+ return array->len;
+}
+
+/**
+ * gst_query_parse_nth_allocation_pool:
+ * @query: A valid #GstQuery of type GST_QUERY_ALLOCATION.
+ * @index: index to parse
+ * @pool: (out) (allow-none) (transfer full): the #GstBufferPool
+ * @size: (out) (allow-none): the size
+ * @min_buffers: (out) (allow-none): the min buffers
+ * @max_buffers: (out) (allow-none): the max buffers
+ *
+ * Get the pool parameters in @query.
+ *
+ * Unref @pool with gst_object_unref() when it's not needed any more.
+ */
+void
+gst_query_parse_nth_allocation_pool (GstQuery * query, guint index,
+ GstBufferPool ** pool, guint * size, guint * min_buffers,
+ guint * max_buffers)
+{
+ GArray *array;
+ GstStructure *structure;
+ AllocationPool *ap;
+
+ g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
+
+ structure = GST_QUERY_STRUCTURE (query);
+ array = ensure_array (structure, GST_QUARK (POOL),
+ sizeof (AllocationPool), (GDestroyNotify) allocation_pool_free);
+ g_return_if_fail (index < array->len);
+
+ ap = &g_array_index (array, AllocationPool, index);
+
+ if (pool)
+ if ((*pool = ap->pool))
+ gst_object_ref (*pool);
+ if (size)
+ *size = ap->size;
+ if (min_buffers)
+ *min_buffers = ap->min_buffers;
+ if (max_buffers)
+ *max_buffers = ap->max_buffers;
+}
+
+/**
+ * gst_query_set_nth_allocation_pool:
+ * @index: index to modify
+ * @query: A valid #GstQuery of type GST_QUERY_ALLOCATION.
+ * @pool: the #GstBufferPool
+ * @size: the size
+ * @min_buffers: the min buffers
+ * @max_buffers: the max buffers
+ *
+ * Set the pool parameters in @query.
+ */
+void
+gst_query_set_nth_allocation_pool (GstQuery * query, guint index,
+ GstBufferPool * pool, guint size, guint min_buffers, guint max_buffers)
+{
+ GArray *array;
+ GstStructure *structure;
+ AllocationPool *oldap, ap;
+
+ g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
+
+ structure = GST_QUERY_STRUCTURE (query);
+ array = ensure_array (structure, GST_QUARK (POOL),
+ sizeof (AllocationPool), (GDestroyNotify) allocation_pool_free);
+ g_return_if_fail (index < array->len);
+
+ oldap = &g_array_index (array, AllocationPool, index);
+ allocation_pool_free (oldap);
+
+ if ((ap.pool = pool))
+ gst_object_ref (pool);
+ ap.size = size;
+ ap.min_buffers = min_buffers;
+ ap.max_buffers = max_buffers;
+ g_array_index (array, AllocationPool, index) = ap;
+}
+
+/**
+ * gst_query_remove_nth_allocation_pool:
+ * @query: a GST_QUERY_ALLOCATION type query #GstQuery
+ * @index: position in the allocation pool array to remove
+ *
+ * Remove the allocation pool at @index of the allocation pool array.
+ *
+ * Since: 1.2
+ */
+void
+gst_query_remove_nth_allocation_pool (GstQuery * query, guint index)
+{
+ GArray *array;
+ GstStructure *structure;
+
+ g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
+ g_return_if_fail (gst_query_is_writable (query));
+
+ structure = GST_QUERY_STRUCTURE (query);
+ array =
+ ensure_array (structure, GST_QUARK (POOL), sizeof (AllocationPool),
+ (GDestroyNotify) allocation_pool_free);
+ g_return_if_fail (index < array->len);
+
+ g_array_remove_index (array, index);
+}
+
+typedef struct
+{
+ GType api;
+ GstStructure *params;
+} AllocationMeta;
+
+static void
+allocation_meta_free (AllocationMeta * am)
+{
+ if (am->params)
+ gst_structure_free (am->params);
+}
+
+/**
+ * gst_query_add_allocation_meta:
+ * @query: a GST_QUERY_ALLOCATION type query #GstQuery
+ * @api: the metadata API
+ * @params: (transfer none) (allow-none): API specific parameters
+ *
+ * Add @api with @params as one of the supported metadata API to @query.
+ */
+void
+gst_query_add_allocation_meta (GstQuery * query, GType api,
+ const GstStructure * params)
+{
+ GArray *array;
+ GstStructure *structure;
+ AllocationMeta am;
+
+ g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
+ g_return_if_fail (api != 0);
+ g_return_if_fail (gst_query_is_writable (query));
+
+ structure = GST_QUERY_STRUCTURE (query);
+ array =
+ ensure_array (structure, GST_QUARK (META), sizeof (AllocationMeta),
+ (GDestroyNotify) allocation_meta_free);
+
+ am.api = api;
+ am.params = (params ? gst_structure_copy (params) : NULL);
+
+ g_array_append_val (array, am);
+}
+
+/**
+ * gst_query_get_n_allocation_metas:
+ * @query: a GST_QUERY_ALLOCATION type query #GstQuery
+ *
+ * Retrieve the number of values currently stored in the
+ * meta API array of the query's structure.
+ *
+ * Returns: the metadata API array size as a #guint.
+ */
+guint
+gst_query_get_n_allocation_metas (GstQuery * query)
+{
+ GArray *array;
+ GstStructure *structure;
+
+ g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, 0);
+
+ structure = GST_QUERY_STRUCTURE (query);
+ array =
+ ensure_array (structure, GST_QUARK (META), sizeof (AllocationMeta),
+ (GDestroyNotify) allocation_meta_free);
+
+ return array->len;
+}
+
+/**
+ * gst_query_parse_nth_allocation_meta:
+ * @query: a GST_QUERY_ALLOCATION type query #GstQuery
+ * @index: position in the metadata API array to read
+ * @params: (out) (transfer none) (allow-none): API specific flags
+ *
+ * Parse an available query and get the metadata API
+ * at @index of the metadata API array.
+ *
+ * Returns: a #GType of the metadata API at @index.
+ */
+GType
+gst_query_parse_nth_allocation_meta (GstQuery * query, guint index,
+ const GstStructure ** params)
+{
+ GArray *array;
+ GstStructure *structure;
+ AllocationMeta *am;
+
+ g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, 0);
+
+ structure = GST_QUERY_STRUCTURE (query);
+ array =
+ ensure_array (structure, GST_QUARK (META), sizeof (AllocationMeta),
+ (GDestroyNotify) allocation_meta_free);
+
+ g_return_val_if_fail (index < array->len, 0);
+
+ am = &g_array_index (array, AllocationMeta, index);
+
+ if (params)
+ *params = am->params;
+
+ return am->api;
+}
+
+/**
+ * gst_query_remove_nth_allocation_meta:
+ * @query: a GST_QUERY_ALLOCATION type query #GstQuery
+ * @index: position in the metadata API array to remove
+ *
+ * Remove the metadata API at @index of the metadata API array.
+ */
+void
+gst_query_remove_nth_allocation_meta (GstQuery * query, guint index)
+{
+ GArray *array;
+ GstStructure *structure;
+
+ g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
+ g_return_if_fail (gst_query_is_writable (query));
+
+ structure = GST_QUERY_STRUCTURE (query);
+ array =
+ ensure_array (structure, GST_QUARK (META), sizeof (AllocationMeta),
+ (GDestroyNotify) allocation_meta_free);
+ g_return_if_fail (index < array->len);
+
+ g_array_remove_index (array, index);
+}
+
+/**
+ * gst_query_find_allocation_meta:
+ * @query: a GST_QUERY_ALLOCATION type query #GstQuery
+ * @api: the metadata API
+ * @index: (out) (transfer none) (allow-none): the index
+ *
+ * Check if @query has metadata @api set. When this function returns %TRUE,
+ * @index will contain the index where the requested API and the flags can be
+ * found.
+ *
+ * Returns: %TRUE when @api is in the list of metadata.
+ */
+gboolean
+gst_query_find_allocation_meta (GstQuery * query, GType api, guint * index)
+{
+ GArray *array;
+ GstStructure *structure;
+ guint i, len;
+
+ g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, FALSE);
+ g_return_val_if_fail (api != 0, FALSE);
+
+ structure = GST_QUERY_STRUCTURE (query);
+ array =
+ ensure_array (structure, GST_QUARK (META), sizeof (AllocationMeta),
+ (GDestroyNotify) allocation_meta_free);
+
+ len = array->len;
+ for (i = 0; i < len; i++) {
+ AllocationMeta *am = &g_array_index (array, AllocationMeta, i);
+ if (am->api == api) {
+ if (index)
+ *index = i;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+typedef struct
+{
+ GstAllocator *allocator;
+ GstAllocationParams params;
+} AllocationParam;
+
+static void
+allocation_param_free (AllocationParam * ap)
+{
+ if (ap->allocator)
+ gst_object_unref (ap->allocator);
+}
+
+/**
+ * gst_query_add_allocation_param:
+ * @query: a GST_QUERY_ALLOCATION type query #GstQuery
+ * @allocator: (transfer none) (allow-none): the memory allocator
+ * @params: (transfer none) (allow-none): a #GstAllocationParams
+ *
+ * Add @allocator and its @params as a supported memory allocator.
+ */
+void
+gst_query_add_allocation_param (GstQuery * query, GstAllocator * allocator,
+ const GstAllocationParams * params)
+{
+ GArray *array;
+ GstStructure *structure;
+ AllocationParam ap;
+
+ g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
+ g_return_if_fail (gst_query_is_writable (query));
+ g_return_if_fail (allocator != NULL || params != NULL);
+
+ structure = GST_QUERY_STRUCTURE (query);
+ array = ensure_array (structure, GST_QUARK (ALLOCATOR),
+ sizeof (AllocationParam), (GDestroyNotify) allocation_param_free);
+
+ if ((ap.allocator = allocator))
+ gst_object_ref (allocator);
+ if (params)
+ ap.params = *params;
+ else
+ gst_allocation_params_init (&ap.params);
+
+ g_array_append_val (array, ap);
+}
+
+/**
+ * gst_query_get_n_allocation_params:
+ * @query: a GST_QUERY_ALLOCATION type query #GstQuery
+ *
+ * Retrieve the number of values currently stored in the
+ * allocator params array of the query's structure.
+ *
+ * If no memory allocator is specified, the downstream element can handle
+ * the default memory allocator. The first memory allocator in the query
+ * should be generic and allow mapping to system memory, all following
+ * allocators should be ordered by preference with the preferred one first.
+ *
+ * Returns: the allocator array size as a #guint.
+ */
+guint
+gst_query_get_n_allocation_params (GstQuery * query)
+{
+ GArray *array;
+ GstStructure *structure;
+
+ g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, 0);
+
+ structure = GST_QUERY_STRUCTURE (query);
+ array = ensure_array (structure, GST_QUARK (ALLOCATOR),
+ sizeof (AllocationParam), (GDestroyNotify) allocation_param_free);
+
+ return array->len;
+}
+
+/**
+ * gst_query_parse_nth_allocation_param:
+ * @query: a GST_QUERY_ALLOCATION type query #GstQuery
+ * @index: position in the allocator array to read
+ * @allocator: (out) (transfer full) (allow-none): variable to hold the result
+ * @params: (out) (allow-none): parameters for the allocator
+ *
+ * Parse an available query and get the allocator and its params
+ * at @index of the allocator array.
+ */
+void
+gst_query_parse_nth_allocation_param (GstQuery * query, guint index,
+ GstAllocator ** allocator, GstAllocationParams * params)
+{
+ GArray *array;
+ GstStructure *structure;
+ AllocationParam *ap;
+
+ g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
+
+ structure = GST_QUERY_STRUCTURE (query);
+ array = ensure_array (structure, GST_QUARK (ALLOCATOR),
+ sizeof (AllocationParam), (GDestroyNotify) allocation_param_free);
+ g_return_if_fail (index < array->len);
+
+ ap = &g_array_index (array, AllocationParam, index);
+
+ if (allocator)
+ if ((*allocator = ap->allocator))
+ gst_object_ref (*allocator);
+ if (params)
+ *params = ap->params;
+}
+
+/**
+ * gst_query_set_nth_allocation_param:
+ * @query: a GST_QUERY_ALLOCATION type query #GstQuery
+ * @index: position in the allocator array to set
+ * @allocator: (transfer none) (allow-none): new allocator to set
+ * @params: (transfer none) (allow-none): parameters for the allocator
+ *
+ * Parse an available query and get the allocator and its params
+ * at @index of the allocator array.
+ */
+void
+gst_query_set_nth_allocation_param (GstQuery * query, guint index,
+ GstAllocator * allocator, const GstAllocationParams * params)
+{
+ GArray *array;
+ GstStructure *structure;
+ AllocationParam *old, ap;
+
+ g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
+
+ structure = GST_QUERY_STRUCTURE (query);
+ array = ensure_array (structure, GST_QUARK (ALLOCATOR),
+ sizeof (AllocationParam), (GDestroyNotify) allocation_param_free);
+ g_return_if_fail (index < array->len);
+
+ old = &g_array_index (array, AllocationParam, index);
+ allocation_param_free (old);
+
+ if ((ap.allocator = allocator))
+ gst_object_ref (allocator);
+ if (params)
+ ap.params = *params;
+ else
+ gst_allocation_params_init (&ap.params);
+
+ g_array_index (array, AllocationParam, index) = ap;
+}
+
+/**
+ * gst_query_remove_nth_allocation_param:
+ * @query: a GST_QUERY_ALLOCATION type query #GstQuery
+ * @index: position in the allocation param array to remove
+ *
+ * Remove the allocation param at @index of the allocation param array.
+ *
+ * Since: 1.2
+ */
+void
+gst_query_remove_nth_allocation_param (GstQuery * query, guint index)
+{
+ GArray *array;
+ GstStructure *structure;
+
+ g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
+ g_return_if_fail (gst_query_is_writable (query));
+
+ structure = GST_QUERY_STRUCTURE (query);
+ array =
+ ensure_array (structure, GST_QUARK (ALLOCATOR), sizeof (AllocationParam),
+ (GDestroyNotify) allocation_param_free);
+ g_return_if_fail (index < array->len);
+
+ g_array_remove_index (array, index);
+}
+
+/**
+ * gst_query_new_scheduling:
+ *
+ * Constructs a new query object for querying the scheduling properties.
+ *
+ * Free-function: gst_query_unref
+ *
+ * Returns: (transfer full): a new #GstQuery
+ */
+GstQuery *
+gst_query_new_scheduling (void)
+{
+ GstQuery *query;
+ GstStructure *structure;
+
+ structure = gst_structure_new_id (GST_QUARK (QUERY_SCHEDULING),
+ GST_QUARK (FLAGS), GST_TYPE_SCHEDULING_FLAGS, 0,
+ GST_QUARK (MINSIZE), G_TYPE_INT, 1,
+ GST_QUARK (MAXSIZE), G_TYPE_INT, -1,
+ GST_QUARK (ALIGN), G_TYPE_INT, 0, NULL);
+ query = gst_query_new_custom (GST_QUERY_SCHEDULING, structure);
+
+ return query;
+}
+
+/**
+ * gst_query_set_scheduling:
+ * @query: A valid #GstQuery of type GST_QUERY_SCHEDULING.
+ * @flags: #GstSchedulingFlags
+ * @minsize: the suggested minimum size of pull requests
+ * @maxsize: the suggested maximum size of pull requests
+ * @align: the suggested alignment of pull requests
+ *
+ * Set the scheduling properties.
+ */
+void
+gst_query_set_scheduling (GstQuery * query, GstSchedulingFlags flags,
+ gint minsize, gint maxsize, gint align)
+{
+ GstStructure *structure;
+
+ g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SCHEDULING);
+ g_return_if_fail (gst_query_is_writable (query));
+
+ structure = GST_QUERY_STRUCTURE (query);
+ gst_structure_id_set (structure,
+ GST_QUARK (FLAGS), GST_TYPE_SCHEDULING_FLAGS, flags,
+ GST_QUARK (MINSIZE), G_TYPE_INT, minsize,
+ GST_QUARK (MAXSIZE), G_TYPE_INT, maxsize,
+ GST_QUARK (ALIGN), G_TYPE_INT, align, NULL);
+}
+
+/**
+ * gst_query_parse_scheduling:
+ * @query: A valid #GstQuery of type GST_QUERY_SCHEDULING.
+ * @flags: (out) (allow-none): #GstSchedulingFlags
+ * @minsize: (out) (allow-none): the suggested minimum size of pull requests
+ * @maxsize: (out) (allow-none): the suggested maximum size of pull requests:
+ * @align: (out) (allow-none): the suggested alignment of pull requests
+ *
+ * Set the scheduling properties.
+ */
+void
+gst_query_parse_scheduling (GstQuery * query, GstSchedulingFlags * flags,
+ gint * minsize, gint * maxsize, gint * align)
+{
+ GstStructure *structure;
+
+ g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SCHEDULING);
+
+ structure = GST_QUERY_STRUCTURE (query);
+ gst_structure_id_get (structure,
+ GST_QUARK (FLAGS), GST_TYPE_SCHEDULING_FLAGS, flags,
+ GST_QUARK (MINSIZE), G_TYPE_INT, minsize,
+ GST_QUARK (MAXSIZE), G_TYPE_INT, maxsize,
+ GST_QUARK (ALIGN), G_TYPE_INT, align, NULL);
+}
+
+/**
+ * gst_query_add_scheduling_mode:
+ * @query: a GST_QUERY_SCHEDULING type query #GstQuery
+ * @mode: a #GstPadMode
+ *
+ * Add @mode as one of the supported scheduling modes to @query.
+ */
+void
+gst_query_add_scheduling_mode (GstQuery * query, GstPadMode mode)
+{
+ GstStructure *structure;
+ GArray *array;
+
+ g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SCHEDULING);
+ g_return_if_fail (gst_query_is_writable (query));
+
+ structure = GST_QUERY_STRUCTURE (query);
+ array =
+ ensure_array (structure, GST_QUARK (MODES), sizeof (GstPadMode), NULL);
+
+ g_array_append_val (array, mode);
+}
+
+/**
+ * gst_query_get_n_scheduling_modes:
+ * @query: a GST_QUERY_SCHEDULING type query #GstQuery
+ *
+ * Retrieve the number of values currently stored in the
+ * scheduling mode array of the query's structure.
+ *
+ * Returns: the scheduling mode array size as a #guint.
+ */
+guint
+gst_query_get_n_scheduling_modes (GstQuery * query)
+{
+ GArray *array;
+ GstStructure *structure;
+
+ g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SCHEDULING, 0);
+
+ structure = GST_QUERY_STRUCTURE (query);
+ array =
+ ensure_array (structure, GST_QUARK (MODES), sizeof (GstPadMode), NULL);
+
+ return array->len;
+}
+
+/**
+ * gst_query_parse_nth_scheduling_mode:
+ * @query: a GST_QUERY_SCHEDULING type query #GstQuery
+ * @index: position in the scheduling modes array to read
+ *
+ * Parse an available query and get the scheduling mode
+ * at @index of the scheduling modes array.
+ *
+ * Returns: a #GstPadMode of the scheduling mode at @index.
+ */
+GstPadMode
+gst_query_parse_nth_scheduling_mode (GstQuery * query, guint index)
+{
+ GstStructure *structure;
+ GArray *array;
+
+ g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SCHEDULING,
+ GST_PAD_MODE_NONE);
+
+ structure = GST_QUERY_STRUCTURE (query);
+ array =
+ ensure_array (structure, GST_QUARK (MODES), sizeof (GstPadMode), NULL);
+ g_return_val_if_fail (index < array->len, GST_PAD_MODE_NONE);
+
+ return g_array_index (array, GstPadMode, index);
+}
+
+/**
+ * gst_query_has_scheduling_mode:
+ * @query: a GST_QUERY_SCHEDULING type query #GstQuery
+ * @mode: the scheduling mode
+ *
+ * Check if @query has scheduling mode set.
+ *
+ * <note>
+ * <para>
+ * When checking if upstream supports pull mode, it is usually not
+ * enough to just check for GST_PAD_MODE_PULL with this function, you
+ * also want to check whether the scheduling flags returned by
+ * gst_query_parse_scheduling() have the seeking flag set (meaning
+ * random access is supported, not only sequential pulls).
+ * </para>
+ * </note>
+ *
+ * Returns: %TRUE when @mode is in the list of scheduling modes.
+ */
+gboolean
+gst_query_has_scheduling_mode (GstQuery * query, GstPadMode mode)
+{
+ GstStructure *structure;
+ GArray *array;
+ guint i, len;
+
+ g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SCHEDULING, FALSE);
+
+ structure = GST_QUERY_STRUCTURE (query);
+ array =
+ ensure_array (structure, GST_QUARK (MODES), sizeof (GstPadMode), NULL);
+
+ len = array->len;
+ for (i = 0; i < len; i++) {
+ if (mode == g_array_index (array, GstPadMode, i))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * gst_query_has_scheduling_mode_with_flags:
+ * @query: a GST_QUERY_SCHEDULING type query #GstQuery
+ * @mode: the scheduling mode
+ * @flags: #GstSchedulingFlags
+ *
+ * Check if @query has scheduling mode set and @flags is set in
+ * query scheduling flags.
+ *
+ * Returns: %TRUE when @mode is in the list of scheduling modes
+ * and @flags are compatible with query flags.
+ */
+gboolean
+gst_query_has_scheduling_mode_with_flags (GstQuery * query, GstPadMode mode,
+ GstSchedulingFlags flags)
+{
+ GstSchedulingFlags sched_flags;
+
+ g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SCHEDULING, FALSE);
+
+ gst_query_parse_scheduling (query, &sched_flags, NULL, NULL, NULL);
+
+ return ((flags & sched_flags) == flags) &&
+ gst_query_has_scheduling_mode (query, mode);
+}
+
+/**
+ * gst_query_new_accept_caps:
+ * @caps: a fixed #GstCaps
+ *
+ * Constructs a new query object for querying if @caps are accepted.
+ *
+ * Free-function: gst_query_unref
+ *
+ * Returns: (transfer full): a new #GstQuery
+ */
+GstQuery *
+gst_query_new_accept_caps (GstCaps * caps)
+{
+ GstQuery *query;
+ GstStructure *structure;
+
+ g_return_val_if_fail (gst_caps_is_fixed (caps), NULL);
+
+ structure = gst_structure_new_id (GST_QUARK (QUERY_ACCEPT_CAPS),
+ GST_QUARK (CAPS), GST_TYPE_CAPS, caps,
+ GST_QUARK (RESULT), G_TYPE_BOOLEAN, FALSE, NULL);
+ query = gst_query_new_custom (GST_QUERY_ACCEPT_CAPS, structure);
+
+ return query;
+}
+
+/**
+ * gst_query_parse_accept_caps:
+ * @query: The query to parse
+ * @caps: (out) (transfer none): A pointer to the caps
+ *
+ * Get the caps from @query. The caps remains valid as long as @query remains
+ * valid.
+ */
+void
+gst_query_parse_accept_caps (GstQuery * query, GstCaps ** caps)
+{
+ GstStructure *structure;
+
+ g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ACCEPT_CAPS);
+ g_return_if_fail (caps != NULL);
+
+ structure = GST_QUERY_STRUCTURE (query);
+ *caps = g_value_get_boxed (gst_structure_id_get_value (structure,
+ GST_QUARK (CAPS)));
+}
+
+/**
+ * gst_query_set_accept_caps_result:
+ * @query: a GST_QUERY_ACCEPT_CAPS type query #GstQuery
+ * @result: the result to set
+ *
+ * Set @result as the result for the @query.
+ */
+void
+gst_query_set_accept_caps_result (GstQuery * query, gboolean result)
+{
+ GstStructure *structure;
+
+ g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ACCEPT_CAPS);
+ g_return_if_fail (gst_query_is_writable (query));
+
+ structure = GST_QUERY_STRUCTURE (query);
+ gst_structure_id_set (structure,
+ GST_QUARK (RESULT), G_TYPE_BOOLEAN, result, NULL);
+}
+
+/**
+ * gst_query_parse_accept_caps_result:
+ * @query: a GST_QUERY_ACCEPT_CAPS type query #GstQuery
+ * @result: location for the result
+ *
+ * Parse the result from @query and store in @result.
+ */
+void
+gst_query_parse_accept_caps_result (GstQuery * query, gboolean * result)
+{
+ GstStructure *structure;