/* GStreamer
 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
 *                    2000 Wim Taymans <wim.taymans@chello.be>
 *                    2005 Wim Taymans <wim@fluendo.com>
 *
 * gstquery.c: GstQueryType registration and Query parsing/creation
 *
 * 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/**
 * SECTION:gstquery
 * @short_description: Provide functions to create queries, and to set and parse
 *                     values in them.
 * @see_also: #GstPad, #GstElement
 *
 * Queries can be performed on pads (gst_pad_query()) and elements
 * (gst_element_query()). Please note that some queries might need a running
 * pipeline to work.
 *
 * Queries can be created using the gst_query_new_*() functions.
 * Query values can be set using gst_query_set_*(), and parsed using
 * gst_query_parse_*() helpers.
 *
 * The following example shows how to query the duration of a pipeline:
 *
 * <example>
 *  <title>Query duration on a pipeline</title>
 *  <programlisting>
 *  GstQuery *query;
 *  gboolean res;
 *  query = gst_query_new_duration (GST_FORMAT_TIME);
 *  res = gst_element_query (pipeline, query);
 *  if (res) {
 *    gint64 duration;
 *    gst_query_parse_duration (query, NULL, &amp;duration);
 *    g_print ("duration = %"GST_TIME_FORMAT, GST_TIME_ARGS (duration));
 *  }
 *  else {
 *    g_print ("duration query failed...");
 *  }
 *  gst_query_unref (query);
 *  </programlisting>
 * </example>
 *
 * Last reviewed on 2012-03-29 (0.11.3)
 */


#include "gst_private.h"
#include "gstinfo.h"
#include "gstquery.h"
#include "gstvalue.h"
#include "gstenumtypes.h"
#include "gstquark.h"
#include "gsturi.h"
#include "gstbufferpool.h"

GST_DEBUG_CATEGORY_STATIC (gst_query_debug);
#define GST_CAT_DEFAULT gst_query_debug

static GType _gst_query_type = 0;

typedef struct
{
  GstQuery query;

  GstStructure *structure;
} GstQueryImpl;

#define GST_QUERY_STRUCTURE(q)  (((GstQueryImpl *)(q))->structure)


typedef struct
{
  const gint type;
  const gchar *name;
  GQuark quark;
} GstQueryQuarks;

static GstQueryQuarks query_quarks[] = {
  {GST_QUERY_UNKNOWN, "unknown", 0},
  {GST_QUERY_POSITION, "position", 0},
  {GST_QUERY_DURATION, "duration", 0},
  {GST_QUERY_LATENCY, "latency", 0},
  {GST_QUERY_JITTER, "jitter", 0},
  {GST_QUERY_RATE, "rate", 0},
  {GST_QUERY_SEEKING, "seeking", 0},
  {GST_QUERY_SEGMENT, "segment", 0},
  {GST_QUERY_CONVERT, "convert", 0},
  {GST_QUERY_FORMATS, "formats", 0},
  {GST_QUERY_BUFFERING, "buffering", 0},
  {GST_QUERY_CUSTOM, "custom", 0},
  {GST_QUERY_URI, "uri", 0},
  {GST_QUERY_ALLOCATION, "allocation", 0},
  {GST_QUERY_SCHEDULING, "scheduling", 0},
  {GST_QUERY_ACCEPT_CAPS, "accept-caps", 0},
  {GST_QUERY_CAPS, "caps", 0},
  {GST_QUERY_DRAIN, "drain", 0},

  {0, NULL, 0}
};

GST_DEFINE_MINI_OBJECT_TYPE (GstQuery, gst_query);

void
_priv_gst_query_initialize (void)
{
  gint i;

  _gst_query_type = gst_query_get_type ();

  GST_DEBUG_CATEGORY_INIT (gst_query_debug, "query", 0, "query system");

  for (i = 0; query_quarks[i].name; i++) {
    query_quarks[i].quark = g_quark_from_static_string (query_quarks[i].name);
  }
}

/**
 * gst_query_type_get_name:
 * @type: the query type
 *
 * Get a printable name for the given query type. Do not modify or free.
 *
 * Returns: a reference to the static name of the query.
 */
const gchar *
gst_query_type_get_name (GstQueryType type)
{
  gint i;

  for (i = 0; query_quarks[i].name; i++) {
    if (type == query_quarks[i].type)
      return query_quarks[i].name;
  }
  return "unknown";
}

/**
 * gst_query_type_to_quark:
 * @type: the query type
 *
 * Get the unique quark for the given query type.
 *
 * Returns: the quark associated with the query type
 */
GQuark
gst_query_type_to_quark (GstQueryType type)
{
  gint i;

  for (i = 0; query_quarks[i].name; i++) {
    if (type == query_quarks[i].type)
      return query_quarks[i].quark;
  }
  return 0;
}

/**
 * gst_query_type_get_flags:
 * @type: a #GstQueryType
 *
 * Gets the #GstQueryTypeFlags associated with @type.
 *
 * Returns: a #GstQueryTypeFlags.
 */
GstQueryTypeFlags
gst_query_type_get_flags (GstQueryType type)
{
  GstQueryTypeFlags ret;

  ret = type & ((1 << GST_QUERY_NUM_SHIFT) - 1);

  return ret;
}

static void
_gst_query_free (GstQuery * query)
{
  GstStructure *s;

  g_return_if_fail (query != NULL);

  s = GST_QUERY_STRUCTURE (query);
  if (s) {
    gst_structure_set_parent_refcount (s, NULL);
    gst_structure_free (s);
  }

  g_slice_free1 (sizeof (GstQueryImpl), query);
}

static GstQuery *
_gst_query_copy (GstQuery * query)
{
  GstQuery *copy;
  GstStructure *s;

  s = GST_QUERY_STRUCTURE (query);
  if (s) {
    s = gst_structure_copy (s);
  }
  copy = gst_query_new_custom (query->type, s);

  return copy;
}

/**
 * gst_query_new_position:
 * @format: the default #GstFormat for the new query
 *
 * Constructs a new query stream position query object. Use gst_query_unref()
 * when done with it. A position query is used to query the current position
 * of playback in the streams, in some format.
 *
 * Free-function: gst_query_unref
 *
 * Returns: (transfer full): a new #GstQuery
 */
GstQuery *
gst_query_new_position (GstFormat format)
{
  GstQuery *query;
  GstStructure *structure;

  structure = gst_structure_new_id (GST_QUARK (QUERY_POSITION),
      GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
      GST_QUARK (CURRENT), G_TYPE_INT64, G_GINT64_CONSTANT (-1), NULL);

  query = gst_query_new_custom (GST_QUERY_POSITION, structure);

  return query;
}

/**
 * gst_query_set_position:
 * @query: a #GstQuery with query type GST_QUERY_POSITION
 * @format: the requested #GstFormat
 * @cur: the position to set
 *
 * Answer a position query by setting the requested value in the given format.
 */
void
gst_query_set_position (GstQuery * query, GstFormat format, gint64 cur)
{
  GstStructure *s;

  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_POSITION);

  s = GST_QUERY_STRUCTURE (query);
  g_return_if_fail (format == g_value_get_enum (gst_structure_id_get_value (s,
              GST_QUARK (FORMAT))));

  gst_structure_id_set (s,
      GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
      GST_QUARK (CURRENT), G_TYPE_INT64, cur, NULL);
}

/**
 * gst_query_parse_position:
 * @query: a #GstQuery
 * @format: (out) (allow-none): the storage for the #GstFormat of the
 *     position values (may be NULL)
 * @cur: (out) (allow-none): the storage for the current position (may be NULL)
 *
 * Parse a position query, writing the format into @format, and the position
 * into @cur, if the respective parameters are non-NULL.
 */
void
gst_query_parse_position (GstQuery * query, GstFormat * format, gint64 * cur)
{
  GstStructure *structure;

  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_POSITION);

  structure = GST_QUERY_STRUCTURE (query);
  if (format)
    *format =
        (GstFormat) g_value_get_enum (gst_structure_id_get_value (structure,
            GST_QUARK (FORMAT)));
  if (cur)
    *cur = g_value_get_int64 (gst_structure_id_get_value (structure,
            GST_QUARK (CURRENT)));
}


/**
 * gst_query_new_duration:
 * @format: the #GstFormat for this duration query
 *
 * Constructs a new stream duration query object to query in the given format.
 * Use gst_query_unref() when done with it. A duration query will give the
 * total length of the stream.
 *
 * Free-function: gst_query_unref
 *
 * Returns: (transfer full): a new #GstQuery
 */
GstQuery *
gst_query_new_duration (GstFormat format)
{
  GstQuery *query;
  GstStructure *structure;

  structure = gst_structure_new_id (GST_QUARK (QUERY_DURATION),
      GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
      GST_QUARK (DURATION), G_TYPE_INT64, G_GINT64_CONSTANT (-1), NULL);

  query = gst_query_new_custom (GST_QUERY_DURATION, structure);

  return query;
}

/**
 * gst_query_set_duration:
 * @query: a #GstQuery
 * @format: the #GstFormat for the duration
 * @duration: the duration of the stream
 *
 * Answer a duration query by setting the requested value in the given format.
 */
void
gst_query_set_duration (GstQuery * query, GstFormat format, gint64 duration)
{
  GstStructure *s;

  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_DURATION);

  s = GST_QUERY_STRUCTURE (query);
  g_return_if_fail (format == g_value_get_enum (gst_structure_id_get_value (s,
              GST_QUARK (FORMAT))));
  gst_structure_id_set (s, GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
      GST_QUARK (DURATION), G_TYPE_INT64, duration, NULL);
}

/**
 * gst_query_parse_duration:
 * @query: a #GstQuery
 * @format: (out) (allow-none): the storage for the #GstFormat of the duration
 *     value, or NULL.
 * @duration: (out) (allow-none): the storage for the total duration, or NULL.
 *
 * Parse a duration query answer. Write the format of the duration into @format,
 * and the value into @duration, if the respective variables are non-NULL.
 */
void
gst_query_parse_duration (GstQuery * query, GstFormat * format,
    gint64 * duration)
{
  GstStructure *structure;

  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_DURATION);

  structure = GST_QUERY_STRUCTURE (query);
  if (format)
    *format =
        (GstFormat) g_value_get_enum (gst_structure_id_get_value (structure,
            GST_QUARK (FORMAT)));
  if (duration)
    *duration = g_value_get_int64 (gst_structure_id_get_value (structure,
            GST_QUARK (DURATION)));
}

/**
 * gst_query_new_latency:
 *
 * Constructs a new latency query object.
 * Use gst_query_unref() when done with it. A latency query is usually performed
 * by sinks to compensate for additional latency introduced by elements in the
 * pipeline.
 *
 * Free-function: gst_query_unref
 *
 * Returns: (transfer full): a #GstQuery
 */
GstQuery *
gst_query_new_latency (void)
{
  GstQuery *query;
  GstStructure *structure;

  structure = gst_structure_new_id (GST_QUARK (QUERY_LATENCY),
      GST_QUARK (LIVE), G_TYPE_BOOLEAN, FALSE,
      GST_QUARK (MIN_LATENCY), G_TYPE_UINT64, G_GUINT64_CONSTANT (0),
      GST_QUARK (MAX_LATENCY), G_TYPE_UINT64, G_GUINT64_CONSTANT (-1), NULL);

  query = gst_query_new_custom (GST_QUERY_LATENCY, structure);

  return query;
}

/**
 * gst_query_set_latency:
 * @query: a #GstQuery
 * @live: if there is a live element upstream
 * @min_latency: the minimal latency of the upstream elements
 * @max_latency: the maximal latency of the upstream elements
 *
 * Answer a latency query by setting the requested values in the given format.
 */
void
gst_query_set_latency (GstQuery * query, gboolean live,
    GstClockTime min_latency, GstClockTime max_latency)
{
  GstStructure *structure;

  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_LATENCY);

  structure = GST_QUERY_STRUCTURE (query);
  gst_structure_id_set (structure,
      GST_QUARK (LIVE), G_TYPE_BOOLEAN, live,
      GST_QUARK (MIN_LATENCY), G_TYPE_UINT64, min_latency,
      GST_QUARK (MAX_LATENCY), G_TYPE_UINT64, max_latency, NULL);
}

/**
 * gst_query_parse_latency:
 * @query: a #GstQuery
 * @live: (out) (allow-none): storage for live or NULL
 * @min_latency: (out) (allow-none): the storage for the min latency or NULL
 * @max_latency: (out) (allow-none): the storage for the max latency or NULL
 *
 * Parse a latency query answer.
 */
void
gst_query_parse_latency (GstQuery * query, gboolean * live,
    GstClockTime * min_latency, GstClockTime * max_latency)
{
  GstStructure *structure;

  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_LATENCY);

  structure = GST_QUERY_STRUCTURE (query);
  if (live)
    *live =
        g_value_get_boolean (gst_structure_id_get_value (structure,
            GST_QUARK (LIVE)));
  if (min_latency)
    *min_latency = g_value_get_uint64 (gst_structure_id_get_value (structure,
            GST_QUARK (MIN_LATENCY)));
  if (max_latency)
    *max_latency = g_value_get_uint64 (gst_structure_id_get_value (structure,
            GST_QUARK (MAX_LATENCY)));
}

/**
 * gst_query_new_convert:
 * @src_format: the source #GstFormat for the new query
 * @value: the value to convert
 * @dest_format: the target #GstFormat
 *
 * Constructs a new convert query object. Use gst_query_unref()
 * when done with it. A convert query is used to ask for a conversion between
 * one format and another.
 *
 * Free-function: gst_query_unref
 *
 * Returns: (transfer full): a #GstQuery
 */
GstQuery *
gst_query_new_convert (GstFormat src_format, gint64 value,
    GstFormat dest_format)
{
  GstQuery *query;
  GstStructure *structure;

  structure = gst_structure_new_id (GST_QUARK (QUERY_CONVERT),
      GST_QUARK (SRC_FORMAT), GST_TYPE_FORMAT, src_format,
      GST_QUARK (SRC_VALUE), G_TYPE_INT64, value,
      GST_QUARK (DEST_FORMAT), GST_TYPE_FORMAT, dest_format,
      GST_QUARK (DEST_VALUE), G_TYPE_INT64, G_GINT64_CONSTANT (-1), NULL);

  query = gst_query_new_custom (GST_QUERY_CONVERT, structure);

  return query;
}

/**
 * gst_query_set_convert:
 * @query: a #GstQuery
 * @src_format: the source #GstFormat
 * @src_value: the source value
 * @dest_format: the destination #GstFormat
 * @dest_value: the destination value
 *
 * Answer a convert query by setting the requested values.
 */
void
gst_query_set_convert (GstQuery * query, GstFormat src_format, gint64 src_value,
    GstFormat dest_format, gint64 dest_value)
{
  GstStructure *structure;

  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CONVERT);

  structure = GST_QUERY_STRUCTURE (query);
  gst_structure_id_set (structure,
      GST_QUARK (SRC_FORMAT), GST_TYPE_FORMAT, src_format,
      GST_QUARK (SRC_VALUE), G_TYPE_INT64, src_value,
      GST_QUARK (DEST_FORMAT), GST_TYPE_FORMAT, dest_format,
      GST_QUARK (DEST_VALUE), G_TYPE_INT64, dest_value, NULL);
}

/**
 * gst_query_parse_convert:
 * @query: a #GstQuery
 * @src_format: (out) (allow-none): the storage for the #GstFormat of the
 *     source value, or NULL
 * @src_value: (out) (allow-none): the storage for the source value, or NULL
 * @dest_format: (out) (allow-none): the storage for the #GstFormat of the
 *     destination value, or NULL
 * @dest_value: (out) (allow-none): the storage for the destination value,
 *     or NULL
 *
 * Parse a convert query answer. Any of @src_format, @src_value, @dest_format,
 * and @dest_value may be NULL, in which case that value is omitted.
 */
void
gst_query_parse_convert (GstQuery * query, GstFormat * src_format,
    gint64 * src_value, GstFormat * dest_format, gint64 * dest_value)
{
  GstStructure *structure;

  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CONVERT);

  structure = GST_QUERY_STRUCTURE (query);
  if (src_format)
    *src_format =
        (GstFormat) g_value_get_enum (gst_structure_id_get_value (structure,
            GST_QUARK (SRC_FORMAT)));
  if (src_value)
    *src_value = g_value_get_int64 (gst_structure_id_get_value (structure,
            GST_QUARK (SRC_VALUE)));
  if (dest_format)
    *dest_format =
        (GstFormat) g_value_get_enum (gst_structure_id_get_value (structure,
            GST_QUARK (DEST_FORMAT)));
  if (dest_value)
    *dest_value = g_value_get_int64 (gst_structure_id_get_value (structure,
            GST_QUARK (DEST_VALUE)));
}

/**
 * gst_query_new_segment:
 * @format: the #GstFormat for the new query
 *
 * Constructs a new segment query object. Use gst_query_unref()
 * when done with it. A segment query is used to discover information about the
 * currently configured segment for playback.
 *
 * Free-function: gst_query_unref
 *
 * Returns: (transfer full): a new #GstQuery
 */
GstQuery *
gst_query_new_segment (GstFormat format)
{
  GstQuery *query;
  GstStructure *structure;

  structure = gst_structure_new_id (GST_QUARK (QUERY_SEGMENT),
      GST_QUARK (RATE), G_TYPE_DOUBLE, (gdouble) 0.0,
      GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
      GST_QUARK (START_VALUE), G_TYPE_INT64, G_GINT64_CONSTANT (-1),
      GST_QUARK (STOP_VALUE), G_TYPE_INT64, G_GINT64_CONSTANT (-1), NULL);

  query = gst_query_new_custom (GST_QUERY_SEGMENT, structure);

  return query;
}

/**
 * gst_query_set_segment:
 * @query: a #GstQuery
 * @rate: the rate of the segment
 * @format: the #GstFormat of the segment values (@start_value and @stop_value)
 * @start_value: the start value
 * @stop_value: the stop value
 *
 * Answer a segment query by setting the requested values. The normal
 * playback segment of a pipeline is 0 to duration at the default rate of
 * 1.0. If a seek was performed on the pipeline to play a different
 * segment, this query will return the range specified in the last seek.
 *
 * @start_value and @stop_value will respectively contain the configured
 * playback range start and stop values expressed in @format.
 * The values are always between 0 and the duration of the media and
 * @start_value <= @stop_value. @rate will contain the playback rate. For
 * negative rates, playback will actually happen from @stop_value to
 * @start_value.
 */
void
gst_query_set_segment (GstQuery * query, gdouble rate, GstFormat format,
    gint64 start_value, gint64 stop_value)
{
  GstStructure *structure;

  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SEGMENT);

  structure = GST_QUERY_STRUCTURE (query);
  gst_structure_id_set (structure,
      GST_QUARK (RATE), G_TYPE_DOUBLE, rate,
      GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
      GST_QUARK (START_VALUE), G_TYPE_INT64, start_value,
      GST_QUARK (STOP_VALUE), G_TYPE_INT64, stop_value, NULL);
}

/**
 * gst_query_parse_segment:
 * @query: a #GstQuery
 * @rate: (out) (allow-none): the storage for the rate of the segment, or NULL
 * @format: (out) (allow-none): the storage for the #GstFormat of the values,
 *     or NULL
 * @start_value: (out) (allow-none): the storage for the start value, or NULL
 * @stop_value: (out) (allow-none): the storage for the stop value, or NULL
 *
 * Parse a segment query answer. Any of @rate, @format, @start_value, and
 * @stop_value may be NULL, which will cause this value to be omitted.
 *
 * See gst_query_set_segment() for an explanation of the function arguments.
 */
void
gst_query_parse_segment (GstQuery * query, gdouble * rate, GstFormat * format,
    gint64 * start_value, gint64 * stop_value)
{
  GstStructure *structure;

  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SEGMENT);

  structure = GST_QUERY_STRUCTURE (query);
  if (rate)
    *rate = g_value_get_double (gst_structure_id_get_value (structure,
            GST_QUARK (RATE)));
  if (format)
    *format =
        (GstFormat) g_value_get_enum (gst_structure_id_get_value (structure,
            GST_QUARK (FORMAT)));
  if (start_value)
    *start_value = g_value_get_int64 (gst_structure_id_get_value (structure,
            GST_QUARK (START_VALUE)));
  if (stop_value)
    *stop_value = g_value_get_int64 (gst_structure_id_get_value (structure,
            GST_QUARK (STOP_VALUE)));
}

/**
 * gst_query_new_custom:
 * @type: the query type
 * @structure: a structure for the query
 *
 * Constructs a new custom query object. Use gst_query_unref()
 * when done with it.
 *
 * Free-function: gst_query_unref
 *
 * Returns: (transfer full): a new #GstQuery
 */
GstQuery *
gst_query_new_custom (GstQueryType type, GstStructure * structure)
{
  GstQueryImpl *query;

  query = g_slice_new0 (GstQueryImpl);

  GST_DEBUG ("creating new query %p %s", query, gst_query_type_get_name (type));

  if (structure) {
    /* structure must not have a parent */
    if (!gst_structure_set_parent_refcount (structure,
            &query->query.mini_object.refcount))
      goto had_parent;
  }

  gst_mini_object_init (GST_MINI_OBJECT_CAST (query), 0, _gst_query_type,
      (GstMiniObjectCopyFunction) _gst_query_copy, NULL,
      (GstMiniObjectFreeFunction) _gst_query_free);

  GST_QUERY_TYPE (query) = type;
  GST_QUERY_STRUCTURE (query) = structure;

  return GST_QUERY_CAST (query);

  /* ERRORS */
had_parent:
  {
    g_slice_free1 (sizeof (GstQueryImpl), query);
    g_warning ("structure is already owned by another object");
    return NULL;
  }
}

/**
 * gst_query_get_structure:
 * @query: a #GstQuery
 *
 * Get the structure of a query.
 *
 * Returns: (transfer none): the #GstStructure of the query. The structure is
 *     still owned by the query and will therefore be freed when the query
 *     is unreffed.
 */
const GstStructure *
gst_query_get_structure (GstQuery * query)
{
  g_return_val_if_fail (GST_IS_QUERY (query), NULL);

  return GST_QUERY_STRUCTURE (query);
}

/**
 * gst_query_writable_structure:
 * @query: a #GstQuery
 *
 * Get the structure of a query. This method should be called with a writable
 * @query so that the returned structure is guranteed to be writable.
 *
 * Returns: (transfer none): the #GstStructure of the query. The structure is
 *     still owned by the query and will therefore be freed when the query
 *     is unreffed.
 */
GstStructure *
gst_query_writable_structure (GstQuery * query)
{
  g_return_val_if_fail (GST_IS_QUERY (query), NULL);
  g_return_val_if_fail (gst_query_is_writable (query), NULL);

  return GST_QUERY_STRUCTURE (query);
}

/**
 * gst_query_new_seeking:
 * @format: the default #GstFormat for the new query
 *
 * Constructs a new query object for querying seeking properties of
 * the stream.
 *
 * Free-function: gst_query_unref
 *
 * Returns: (transfer full): a new #GstQuery
 */
GstQuery *
gst_query_new_seeking (GstFormat format)
{
  GstQuery *query;
  GstStructure *structure;

  structure = gst_structure_new_id (GST_QUARK (QUERY_SEEKING),
      GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
      GST_QUARK (SEEKABLE), G_TYPE_BOOLEAN, FALSE,
      GST_QUARK (SEGMENT_START), G_TYPE_INT64, G_GINT64_CONSTANT (-1),
      GST_QUARK (SEGMENT_END), G_TYPE_INT64, G_GINT64_CONSTANT (-1), NULL);

  query = gst_query_new_custom (GST_QUERY_SEEKING, structure);

  return query;
}

/**
 * gst_query_set_seeking:
 * @query: a #GstQuery
 * @format: the format to set for the @segment_start and @segment_end values
 * @seekable: the seekable flag to set
 * @segment_start: the segment_start to set
 * @segment_end: the segment_end to set
 *
 * Set the seeking query result fields in @query.
 */
void
gst_query_set_seeking (GstQuery * query, GstFormat format,
    gboolean seekable, gint64 segment_start, gint64 segment_end)
{
  GstStructure *structure;

  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SEEKING);
  g_return_if_fail (gst_query_is_writable (query));

  structure = GST_QUERY_STRUCTURE (query);
  gst_structure_id_set (structure,
      GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
      GST_QUARK (SEEKABLE), G_TYPE_BOOLEAN, seekable,
      GST_QUARK (SEGMENT_START), G_TYPE_INT64, segment_start,
      GST_QUARK (SEGMENT_END), G_TYPE_INT64, segment_end, NULL);
}

/**
 * gst_query_parse_seeking:
 * @query: a GST_QUERY_SEEKING type query #GstQuery
 * @format: (out) (allow-none): the format to set for the @segment_start
 *     and @segment_end values, or NULL
 * @seekable: (out) (allow-none): the seekable flag to set, or NULL
 * @segment_start: (out) (allow-none): the segment_start to set, or NULL
 * @segment_end: (out) (allow-none): the segment_end to set, or NULL
 *
 * Parse a seeking query, writing the format into @format, and
 * other results into the passed parameters, if the respective parameters
 * are non-NULL
 */
void
gst_query_parse_seeking (GstQuery * query, GstFormat * format,
    gboolean * seekable, gint64 * segment_start, gint64 * segment_end)
{
  GstStructure *structure;

  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SEEKING);

  structure = GST_QUERY_STRUCTURE (query);
  if (format)
    *format =
        (GstFormat) g_value_get_enum (gst_structure_id_get_value (structure,
            GST_QUARK (FORMAT)));
  if (seekable)
    *seekable = g_value_get_boolean (gst_structure_id_get_value (structure,
            GST_QUARK (SEEKABLE)));
  if (segment_start)
    *segment_start = g_value_get_int64 (gst_structure_id_get_value (structure,
            GST_QUARK (SEGMENT_START)));
  if (segment_end)
    *segment_end = g_value_get_int64 (gst_structure_id_get_value (structure,
            GST_QUARK (SEGMENT_END)));
}

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;
}

/**
 * gst_query_new_formats:
 *
 * Constructs a new query object for querying formats of
 * the stream.
 *
 * Free-function: gst_query_unref
 *
 * Returns: (transfer full): a new #GstQuery
 */
GstQuery *
gst_query_new_formats (void)
{
  GstQuery *query;
  GstStructure *structure;

  structure = gst_structure_new_id_empty (GST_QUARK (QUERY_FORMATS));
  query = gst_query_new_custom (GST_QUERY_FORMATS, structure);

  return query;
}

static void
gst_query_list_add_format (GValue * list, GstFormat format)
{
  GValue item = { 0, };

  g_value_init (&item, GST_TYPE_FORMAT);
  g_value_set_enum (&item, format);
  gst_value_list_append_value (list, &item);
  g_value_unset (&item);
}

/**
 * gst_query_set_formats:
 * @query: a #GstQuery
 * @n_formats: the number of formats to set.
 * @...: A number of @GstFormats equal to @n_formats.
 *
 * Set the formats query result fields in @query. The number of formats passed
 * must be equal to @n_formats.
 */
void
gst_query_set_formats (GstQuery * query, gint n_formats, ...)
{
  va_list ap;
  GValue list = { 0, };
  gint i;
  GstStructure *structure;

  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_FORMATS);
  g_return_if_fail (gst_query_is_writable (query));

  g_value_init (&list, GST_TYPE_LIST);

  va_start (ap, n_formats);
  for (i = 0; i < n_formats; i++) {
    gst_query_list_add_format (&list, va_arg (ap, GstFormat));
  }
  va_end (ap);

  structure = GST_QUERY_STRUCTURE (query);
  gst_structure_set_value (structure, "formats", &list);

  g_value_unset (&list);

}

/**
 * gst_query_set_formatsv:
 * @query: a #GstQuery
 * @n_formats: the number of formats to set.
 * @formats: (in) (array length=n_formats): an array containing @n_formats
 *     @GstFormat values.
 *
 * Set the formats query result fields in @query. The number of formats passed
 * in the @formats array must be equal to @n_formats.
 */
void
gst_query_set_formatsv (GstQuery * query, gint n_formats,
    const GstFormat * formats)
{
  GValue list = { 0, };
  gint i;
  GstStructure *structure;

  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_FORMATS);
  g_return_if_fail (gst_query_is_writable (query));

  g_value_init (&list, GST_TYPE_LIST);
  for (i = 0; i < n_formats; i++) {
    gst_query_list_add_format (&list, formats[i]);
  }
  structure = GST_QUERY_STRUCTURE (query);
  gst_structure_set_value (structure, "formats", &list);

  g_value_unset (&list);
}

/**
 * gst_query_parse_n_formats:
 * @query: a #GstQuery
 * @n_formats: (out) (allow-none): the number of formats in this query.
 *
 * Parse the number of formats in the formats @query.
 */
void
gst_query_parse_n_formats (GstQuery * query, guint * n_formats)
{
  GstStructure *structure;

  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_FORMATS);

  if (n_formats) {
    const GValue *list;

    structure = GST_QUERY_STRUCTURE (query);
    list = gst_structure_get_value (structure, "formats");
    if (list == NULL)
      *n_formats = 0;
    else
      *n_formats = gst_value_list_get_size (list);
  }
}

/**
 * gst_query_parse_nth_format:
 * @query: a #GstQuery
 * @nth: (out): the nth format to retrieve.
 * @format: (out) (allow-none): a pointer to store the nth format
 *
 * Parse the format query and retrieve the @nth format from it into
 * @format. If the list contains less elements than @nth, @format will be
 * set to GST_FORMAT_UNDEFINED.
 */
void
gst_query_parse_nth_format (GstQuery * query, guint nth, GstFormat * format)
{
  GstStructure *structure;

  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_FORMATS);

  if (format) {
    const GValue *list;

    structure = GST_QUERY_STRUCTURE (query);
    list = gst_structure_get_value (structure, "formats");
    if (list == NULL) {
      *format = GST_FORMAT_UNDEFINED;
    } else {
      if (nth < gst_value_list_get_size (list)) {
        *format =
            (GstFormat) g_value_get_enum (gst_value_list_get_value (list, nth));
      } else
        *format = GST_FORMAT_UNDEFINED;
    }
  }
}

/**
 * gst_query_new_buffering:
 * @format: the default #GstFormat for the new query
 *
 * Constructs a new query object for querying the buffering status of
 * a stream.
 *
 * Free-function: gst_query_unref
 *
 * Returns: (transfer full): a new #GstQuery
 */
GstQuery *
gst_query_new_buffering (GstFormat format)
{
  GstQuery *query;
  GstStructure *structure;

  /* by default, we configure the answer as no buffering with a 100% buffering
   * progress */
  structure = gst_structure_new_id (GST_QUARK (QUERY_BUFFERING),
      GST_QUARK (BUSY), G_TYPE_BOOLEAN, FALSE,
      GST_QUARK (BUFFER_PERCENT), G_TYPE_INT, 100,
      GST_QUARK (BUFFERING_MODE), GST_TYPE_BUFFERING_MODE, GST_BUFFERING_STREAM,
      GST_QUARK (AVG_IN_RATE), G_TYPE_INT, -1,
      GST_QUARK (AVG_OUT_RATE), G_TYPE_INT, -1,
      GST_QUARK (BUFFERING_LEFT), G_TYPE_INT64, G_GINT64_CONSTANT (0),
      GST_QUARK (ESTIMATED_TOTAL), G_TYPE_INT64, G_GINT64_CONSTANT (-1),
      GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
      GST_QUARK (START_VALUE), G_TYPE_INT64, G_GINT64_CONSTANT (-1),
      GST_QUARK (STOP_VALUE), G_TYPE_INT64, G_GINT64_CONSTANT (-1), NULL);

  query = gst_query_new_custom (GST_QUERY_BUFFERING, structure);

  return query;
}

/**
 * gst_query_set_buffering_percent:
 * @query: A valid #GstQuery of type GST_QUERY_BUFFERING.
 * @busy: if buffering is busy
 * @percent: a buffering percent
 *
 * Set the percentage of buffered data. This is a value between 0 and 100.
 * The @busy indicator is %TRUE when the buffering is in progress.
 */
void
gst_query_set_buffering_percent (GstQuery * query, gboolean busy, gint percent)
{
  GstStructure *structure;

  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING);
  g_return_if_fail (gst_query_is_writable (query));
  g_return_if_fail (percent >= 0 && percent <= 100);

  structure = GST_QUERY_STRUCTURE (query);
  gst_structure_id_set (structure,
      GST_QUARK (BUSY), G_TYPE_BOOLEAN, busy,
      GST_QUARK (BUFFER_PERCENT), G_TYPE_INT, percent, NULL);
}

/**
 * gst_query_parse_buffering_percent:
 * @query: A valid #GstQuery of type GST_QUERY_BUFFERING.
 * @busy: (out) (allow-none): if buffering is busy, or NULL
 * @percent: (out) (allow-none): a buffering percent, or NULL
 *
 * Get the percentage of buffered data. This is a value between 0 and 100.
 * The @busy indicator is %TRUE when the buffering is in progress.
 */
void
gst_query_parse_buffering_percent (GstQuery * query, gboolean * busy,
    gint * percent)
{
  GstStructure *structure;

  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING);

  structure = GST_QUERY_STRUCTURE (query);
  if (busy)
    *busy = g_value_get_boolean (gst_structure_id_get_value (structure,
            GST_QUARK (BUSY)));
  if (percent)
    *percent = g_value_get_int (gst_structure_id_get_value (structure,
            GST_QUARK (BUFFER_PERCENT)));
}

/**
 * gst_query_set_buffering_stats:
 * @query: A valid #GstQuery of type GST_QUERY_BUFFERING.
 * @mode: a buffering mode
 * @avg_in: the average input rate
 * @avg_out: the average output rate
 * @buffering_left: amount of buffering time left in milliseconds
 *
 * Configures the buffering stats values in @query.
 */
void
gst_query_set_buffering_stats (GstQuery * query, GstBufferingMode mode,
    gint avg_in, gint avg_out, gint64 buffering_left)
{
  GstStructure *structure;

  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING);
  g_return_if_fail (gst_query_is_writable (query));

  structure = GST_QUERY_STRUCTURE (query);
  gst_structure_id_set (structure,
      GST_QUARK (BUFFERING_MODE), GST_TYPE_BUFFERING_MODE, mode,
      GST_QUARK (AVG_IN_RATE), G_TYPE_INT, avg_in,
      GST_QUARK (AVG_OUT_RATE), G_TYPE_INT, avg_out,
      GST_QUARK (BUFFERING_LEFT), G_TYPE_INT64, buffering_left, NULL);
}

/**
 * gst_query_parse_buffering_stats:
 * @query: A valid #GstQuery of type GST_QUERY_BUFFERING.
 * @mode: (out) (allow-none): a buffering mode, or NULL
 * @avg_in: (out) (allow-none): the average input rate, or NULL
 * @avg_out: (out) (allow-none): the average output rat, or NULLe
 * @buffering_left: (out) (allow-none): amount of buffering time left in
 *     milliseconds, or NULL
 *
 * Extracts the buffering stats values from @query.
 */
void
gst_query_parse_buffering_stats (GstQuery * query,
    GstBufferingMode * mode, gint * avg_in, gint * avg_out,
    gint64 * buffering_left)
{
  GstStructure *structure;

  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING);

  structure = GST_QUERY_STRUCTURE (query);
  if (mode)
    *mode = (GstBufferingMode)
        g_value_get_enum (gst_structure_id_get_value (structure,
            GST_QUARK (BUFFERING_MODE)));
  if (avg_in)
    *avg_in = g_value_get_int (gst_structure_id_get_value (structure,
            GST_QUARK (AVG_IN_RATE)));
  if (avg_out)
    *avg_out = g_value_get_int (gst_structure_id_get_value (structure,
            GST_QUARK (AVG_OUT_RATE)));
  if (buffering_left)
    *buffering_left =
        g_value_get_int64 (gst_structure_id_get_value (structure,
            GST_QUARK (BUFFERING_LEFT)));
}

/**
 * gst_query_set_buffering_range:
 * @query: a #GstQuery
 * @format: the format to set for the @start and @stop values
 * @start: the start to set
 * @stop: the stop to set
 * @estimated_total: estimated total amount of download time
 *
 * Set the available query result fields in @query.
 */
void
gst_query_set_buffering_range (GstQuery * query, GstFormat format,
    gint64 start, gint64 stop, gint64 estimated_total)
{
  GstStructure *structure;

  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING);
  g_return_if_fail (gst_query_is_writable (query));

  structure = GST_QUERY_STRUCTURE (query);
  gst_structure_id_set (structure,
      GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
      GST_QUARK (START_VALUE), G_TYPE_INT64, start,
      GST_QUARK (STOP_VALUE), G_TYPE_INT64, stop,
      GST_QUARK (ESTIMATED_TOTAL), G_TYPE_INT64, estimated_total, NULL);
}

/**
 * gst_query_parse_buffering_range:
 * @query: a GST_QUERY_BUFFERING type query #GstQuery
 * @format: (out) (allow-none): the format to set for the @segment_start
 *     and @segment_end values, or NULL
 * @start: (out) (allow-none): the start to set, or NULL
 * @stop: (out) (allow-none): the stop to set, or NULL
 * @estimated_total: (out) (allow-none): estimated total amount of download
 *     time, or NULL
 *
 * Parse an available query, writing the format into @format, and
 * other results into the passed parameters, if the respective parameters
 * are non-NULL
 */
void
gst_query_parse_buffering_range (GstQuery * query, GstFormat * format,
    gint64 * start, gint64 * stop, gint64 * estimated_total)
{
  GstStructure *structure;

  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING);

  structure = GST_QUERY_STRUCTURE (query);
  if (format)
    *format =
        (GstFormat) g_value_get_enum (gst_structure_id_get_value (structure,
            GST_QUARK (FORMAT)));
  if (start)
    *start = g_value_get_int64 (gst_structure_id_get_value (structure,
            GST_QUARK (START_VALUE)));
  if (stop)
    *stop = g_value_get_int64 (gst_structure_id_get_value (structure,
            GST_QUARK (STOP_VALUE)));
  if (estimated_total)
    *estimated_total =
        g_value_get_int64 (gst_structure_id_get_value (structure,
            GST_QUARK (ESTIMATED_TOTAL)));
}

/* GstQueryBufferingRange: internal struct for GArray */
typedef struct
{
  gint64 start;
  gint64 stop;
} GstQueryBufferingRange;

/**
 * gst_query_add_buffering_range:
 * @query: a GST_QUERY_BUFFERING type query #GstQuery
 * @start: start position of the range
 * @stop: stop position of the range
 *
 * Set the buffering-ranges array field in @query. The current last
 * start position of the array should be inferior to @start.
 *
 * Returns: a #gboolean indicating if the range was added or not.
 */
gboolean
gst_query_add_buffering_range (GstQuery * query, gint64 start, gint64 stop)
{
  GstQueryBufferingRange range;
  GstStructure *structure;
  GArray *array;

  g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING, FALSE);
  g_return_val_if_fail (gst_query_is_writable (query), FALSE);

  if (G_UNLIKELY (start >= stop))
    return FALSE;

  structure = GST_QUERY_STRUCTURE (query);
  array = ensure_array (structure, GST_QUARK (BUFFERING_RANGES),
      sizeof (GstQueryBufferingRange), NULL);

  if (array->len > 1) {
    GstQueryBufferingRange *last;

    last = &g_array_index (array, GstQueryBufferingRange, array->len - 1);

    if (G_UNLIKELY (start <= last->start))
      return FALSE;
  }

  range.start = start;
  range.stop = stop;
  g_array_append_val (array, range);

  return TRUE;
}

/**
 * gst_query_get_n_buffering_ranges:
 * @query: a GST_QUERY_BUFFERING type query #GstQuery
 *
 * Retrieve the number of values currently stored in the
 * buffered-ranges array of the query's structure.
 *
 * Returns: the range array size as a #guint.
 */
guint
gst_query_get_n_buffering_ranges (GstQuery * query)
{
  GstStructure *structure;
  GArray *array;

  g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING, 0);

  structure = GST_QUERY_STRUCTURE (query);
  array = ensure_array (structure, GST_QUARK (BUFFERING_RANGES),
      sizeof (GstQueryBufferingRange), NULL);

  return array->len;
}


/**
 * gst_query_parse_nth_buffering_range:
 * @query: a GST_QUERY_BUFFERING type query #GstQuery
 * @index: position in the buffered-ranges array to read
 * @start: (out) (allow-none): the start position to set, or NULL
 * @stop: (out) (allow-none): the stop position to set, or NULL
 *
 * Parse an available query and get the start and stop values stored
 * at the @index of the buffered ranges array.
 *
 * Returns: a #gboolean indicating if the parsing succeeded.
 */
gboolean
gst_query_parse_nth_buffering_range (GstQuery * query, guint index,
    gint64 * start, gint64 * stop)
{
  GstQueryBufferingRange *range;
  GstStructure *structure;
  GArray *array;

  g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING, FALSE);

  structure = GST_QUERY_STRUCTURE (query);

  array = ensure_array (structure, GST_QUARK (BUFFERING_RANGES),
      sizeof (GstQueryBufferingRange), NULL);
  g_return_val_if_fail (index < array->len, FALSE);

  range = &g_array_index (array, GstQueryBufferingRange, index);

  if (start)
    *start = range->start;
  if (stop)
    *stop = range->stop;

  return TRUE;
}


/**
 * gst_query_new_uri:
 *
 * Constructs a new query URI query object. Use gst_query_unref()
 * when done with it. An URI query is used to query the current URI
 * that is used by the source or sink.
 *
 * Free-function: gst_query_unref
 *
 * Returns: (transfer full): a new #GstQuery
 */
GstQuery *
gst_query_new_uri (void)
{
  GstQuery *query;
  GstStructure *structure;

  structure = gst_structure_new_id (GST_QUARK (QUERY_URI),
      GST_QUARK (URI), G_TYPE_STRING, NULL, NULL);

  query = gst_query_new_custom (GST_QUERY_URI, structure);

  return query;
}

/**
 * gst_query_set_uri:
 * @query: a #GstQuery with query type GST_QUERY_URI
 * @uri: the URI to set
 *
 * Answer a URI query by setting the requested URI.
 */
void
gst_query_set_uri (GstQuery * query, const gchar * uri)
{
  GstStructure *structure;

  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_URI);
  g_return_if_fail (gst_query_is_writable (query));
  g_return_if_fail (gst_uri_is_valid (uri));

  structure = GST_QUERY_STRUCTURE (query);
  gst_structure_id_set (structure, GST_QUARK (URI), G_TYPE_STRING, uri, NULL);
}

/**
 * gst_query_parse_uri:
 * @query: a #GstQuery
 * @uri: (out callee-allocates) (allow-none): the storage for the current URI
 *     (may be NULL)
 *
 * Parse an URI query, writing the URI into @uri as a newly
 * allocated string, if the respective parameters are non-NULL.
 * Free the string with g_free() after usage.
 */
void
gst_query_parse_uri (GstQuery * query, gchar ** uri)
{
  GstStructure *structure;

  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_URI);

  structure = GST_QUERY_STRUCTURE (query);
  if (uri)
    *uri = g_value_dup_string (gst_structure_id_get_value (structure,
            GST_QUARK (URI)));
}

/**
 * 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;
}

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) (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) (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.
 *
 * 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 none) (allow-none): variable to hold the result
 * @params: (out) (allow-none): parameters for the allocator
 *
 * Parse an available query and get the alloctor 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 alloctor 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_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 aone 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): 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;

  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ACCEPT_CAPS);

  structure = GST_QUERY_STRUCTURE (query);
  gst_structure_id_get (structure,
      GST_QUARK (RESULT), G_TYPE_BOOLEAN, result, NULL);
}

/**
 * gst_query_new_caps:
 * @filter: a filter
 *
 * Constructs a new query object for querying the caps.
 *
 * The CAPS query should return the allowable caps for a pad in the context
 * of the element's state, its link to other elements, and the devices or files
 * it has opened. These caps must be a subset of the pad template caps. In the
 * NULL state with no links, the CAPS query should ideally return the same caps
 * as the pad template. In rare circumstances, an object property can affect
 * the caps returned by the CAPS query, but this is discouraged.
 *
 * For most filters, the caps returned by CAPS query is directly affected by the
 * allowed caps on other pads. For demuxers and decoders, the caps returned by
 * the srcpad's getcaps function is directly related to the stream data. Again,
 * the CAPS query should return the most specific caps it reasonably can, since this
 * helps with autoplugging.
 *
 * The @filter is used to restrict the result caps, only the caps matching
 * @filter should be returned from the CAPS query. Specifying a filter might
 * greatly reduce the amount of processing an element needs to do.
 *
 * Free-function: gst_query_unref
 *
 * Returns: (transfer full): a new #GstQuery
 */
GstQuery *
gst_query_new_caps (GstCaps * filter)
{
  GstQuery *query;
  GstStructure *structure;

  structure = gst_structure_new_id (GST_QUARK (QUERY_CAPS),
      GST_QUARK (FILTER), GST_TYPE_CAPS, filter,
      GST_QUARK (CAPS), GST_TYPE_CAPS, NULL, NULL);
  query = gst_query_new_custom (GST_QUERY_CAPS, structure);

  return query;
}

/**
 * gst_query_parse_caps:
 * @query: The query to parse
 * @filter: (out): A pointer to the caps filter
 *
 * Get the filter from the caps @query. The caps remains valid as long as
 * @query remains valid.
 */
void
gst_query_parse_caps (GstQuery * query, GstCaps ** filter)
{
  GstStructure *structure;

  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CAPS);
  g_return_if_fail (filter != NULL);

  structure = GST_QUERY_STRUCTURE (query);
  *filter = g_value_get_boxed (gst_structure_id_get_value (structure,
          GST_QUARK (FILTER)));
}

/**
 * gst_query_set_caps_result:
 * @query: The query to use
 * @caps: (in): A pointer to the caps
 *
 * Set the @caps result in @query.
 */
void
gst_query_set_caps_result (GstQuery * query, GstCaps * caps)
{
  GstStructure *structure;

  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CAPS);
  g_return_if_fail (gst_query_is_writable (query));

  structure = GST_QUERY_STRUCTURE (query);
  gst_structure_id_set (structure, GST_QUARK (CAPS), GST_TYPE_CAPS, caps, NULL);
}

/**
 * gst_query_parse_caps_result:
 * @query: The query to parse
 * @caps: (out): A pointer to the caps
 *
 * Get the caps result from @query. The caps remains valid as long as
 * @query remains valid.
 */
void
gst_query_parse_caps_result (GstQuery * query, GstCaps ** caps)
{
  GstStructure *structure;

  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_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)));
}

#if 0
void
gst_query_intersect_caps_result (GstQuery * query, GstCaps * filter,
    GstCapsIntersectMode mode)
{
  GstCaps *res, *caps = NULL;

  gst_query_parse_caps_result (query, &caps);
  res = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
  gst_query_set_caps_result (query, res);
  gst_caps_unref (res);
}
#endif

/**
 * gst_query_new_drain:
 *
 * Constructs a new query object for querying the drain state.
 *
 * Free-function: gst_query_unref
 *
 * Returns: (transfer full): a new #GstQuery
 */
GstQuery *
gst_query_new_drain (void)
{
  GstQuery *query;
  GstStructure *structure;

  structure = gst_structure_new_id_empty (GST_QUARK (QUERY_DRAIN));
  query = gst_query_new_custom (GST_QUERY_DRAIN, structure);

  return query;
}
