query: also include padding in ALLOCATION query
[platform/upstream/gstreamer.git] / gst / gstquery.c
1 /* GStreamer
2  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3  *                    2000 Wim Taymans <wim.taymans@chello.be>
4  *                    2005 Wim Taymans <wim@fluendo.com>
5  *
6  * gstquery.c: GstQueryType registration and Query parsing/creation
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23
24 /**
25  * SECTION:gstquery
26  * @short_description: Dynamically register new query types. Provide functions
27  *                     to create queries, and to set and parse values in them.
28  * @see_also: #GstPad, #GstElement
29  *
30  * GstQuery functions are used to register new query types to the gstreamer
31  * core and use them.
32  * Queries can be performed on pads (gst_pad_query()) and elements
33  * (gst_element_query()). Please note that some queries might need a running
34  * pipeline to work.
35  *
36  * Queries can be created using the gst_query_new_*() functions.
37  * Query values can be set using gst_query_set_*(), and parsed using
38  * gst_query_parse_*() helpers.
39  *
40  * The following example shows how to query the duration of a pipeline:
41  *
42  * <example>
43  *  <title>Query duration on a pipeline</title>
44  *  <programlisting>
45  *  GstQuery *query;
46  *  gboolean res;
47  *  query = gst_query_new_duration (GST_FORMAT_TIME);
48  *  res = gst_element_query (pipeline, query);
49  *  if (res) {
50  *    gint64 duration;
51  *    gst_query_parse_duration (query, NULL, &amp;duration);
52  *    g_print ("duration = %"GST_TIME_FORMAT, GST_TIME_ARGS (duration));
53  *  }
54  *  else {
55  *    g_print ("duration query failed...");
56  *  }
57  *  gst_query_unref (query);
58  *  </programlisting>
59  * </example>
60  *
61  * Last reviewed on 2006-02-14 (0.10.4)
62  */
63
64
65 /* FIXME 0.11: suppress warnings for deprecated API such as GValueArray
66  * with newer GLib versions (>= 2.31.0) */
67 #define GLIB_DISABLE_DEPRECATION_WARNINGS
68
69 #include "gst_private.h"
70 #include "gstinfo.h"
71 #include "gstquery.h"
72 #include "gstvalue.h"
73 #include "gstenumtypes.h"
74 #include "gstquark.h"
75 #include "gsturi.h"
76 #include "gstbufferpool.h"
77
78 GST_DEBUG_CATEGORY_STATIC (gst_query_debug);
79 #define GST_CAT_DEFAULT gst_query_debug
80
81 static GType _gst_query_type = 0;
82
83 typedef struct
84 {
85   GstQuery query;
86
87   GstStructure *structure;
88 } GstQueryImpl;
89
90 #define GST_QUERY_STRUCTURE(q)  (((GstQueryImpl *)(q))->structure)
91
92 /* GstQueryBufferingRange: internal struct for GArray */
93 typedef struct
94 {
95   gint64 start;
96   gint64 stop;
97 } GstQueryBufferingRange;
98
99 typedef struct
100 {
101   const gint type;
102   const gchar *name;
103   GQuark quark;
104 } GstQueryQuarks;
105
106 static GstQueryQuarks query_quarks[] = {
107   {GST_QUERY_UNKNOWN, "unknown", 0},
108   {GST_QUERY_POSITION, "position", 0},
109   {GST_QUERY_DURATION, "duration", 0},
110   {GST_QUERY_LATENCY, "latency", 0},
111   {GST_QUERY_JITTER, "jitter", 0},
112   {GST_QUERY_RATE, "rate", 0},
113   {GST_QUERY_SEEKING, "seeking", 0},
114   {GST_QUERY_SEGMENT, "segment", 0},
115   {GST_QUERY_CONVERT, "convert", 0},
116   {GST_QUERY_FORMATS, "formats", 0},
117   {GST_QUERY_BUFFERING, "buffering", 0},
118   {GST_QUERY_CUSTOM, "custom", 0},
119   {GST_QUERY_URI, "uri", 0},
120   {GST_QUERY_ALLOCATION, "allocation", 0},
121   {GST_QUERY_SCHEDULING, "scheduling", 0},
122   {GST_QUERY_ACCEPT_CAPS, "accept-caps", 0},
123   {GST_QUERY_CAPS, "caps", 0},
124   {GST_QUERY_DRAIN, "drain", 0},
125
126   {0, NULL, 0}
127 };
128
129 GST_DEFINE_MINI_OBJECT_TYPE (GstQuery, gst_query);
130
131 void
132 _priv_gst_query_initialize (void)
133 {
134   gint i;
135
136   _gst_query_type = gst_query_get_type ();
137
138   GST_DEBUG_CATEGORY_INIT (gst_query_debug, "query", 0, "query system");
139
140   for (i = 0; query_quarks[i].name; i++) {
141     query_quarks[i].quark = g_quark_from_static_string (query_quarks[i].name);
142   }
143 }
144
145 /**
146  * gst_query_type_get_name:
147  * @type: the query type
148  *
149  * Get a printable name for the given query type. Do not modify or free.
150  *
151  * Returns: a reference to the static name of the query.
152  */
153 const gchar *
154 gst_query_type_get_name (GstQueryType type)
155 {
156   gint i;
157
158   for (i = 0; query_quarks[i].name; i++) {
159     if (type == query_quarks[i].type)
160       return query_quarks[i].name;
161   }
162   return "unknown";
163 }
164
165 /**
166  * gst_query_type_to_quark:
167  * @type: the query type
168  *
169  * Get the unique quark for the given query type.
170  *
171  * Returns: the quark associated with the query type
172  */
173 GQuark
174 gst_query_type_to_quark (GstQueryType type)
175 {
176   gint i;
177
178   for (i = 0; query_quarks[i].name; i++) {
179     if (type == query_quarks[i].type)
180       return query_quarks[i].quark;
181   }
182   return 0;
183 }
184
185 /**
186  * gst_query_type_get_flags:
187  * @type: a #GstQueryType
188  *
189  * Gets the #GstQueryTypeFlags associated with @type.
190  *
191  * Returns: a #GstQueryTypeFlags.
192  */
193 GstQueryTypeFlags
194 gst_query_type_get_flags (GstQueryType type)
195 {
196   GstQueryTypeFlags ret;
197
198   ret = type & ((1 << GST_EVENT_NUM_SHIFT) - 1);
199
200   return ret;
201 }
202
203 static void
204 _gst_query_free (GstQuery * query)
205 {
206   GstStructure *s;
207
208   g_return_if_fail (query != NULL);
209
210   s = GST_QUERY_STRUCTURE (query);
211   if (s) {
212     gst_structure_set_parent_refcount (s, NULL);
213     gst_structure_free (s);
214   }
215
216   g_slice_free1 (GST_MINI_OBJECT_SIZE (query), query);
217 }
218
219 static GstQuery *
220 _gst_query_copy (GstQuery * query)
221 {
222   GstQuery *copy;
223
224   copy = gst_query_new_custom (query->type, GST_QUERY_STRUCTURE (query));
225
226   return copy;
227 }
228
229 static void
230 gst_query_init (GstQueryImpl * query, gsize size, GstQueryType type)
231 {
232   gst_mini_object_init (GST_MINI_OBJECT_CAST (query), _gst_query_type, size);
233
234   query->query.mini_object.copy = (GstMiniObjectCopyFunction) _gst_query_copy;
235   query->query.mini_object.free = (GstMiniObjectFreeFunction) _gst_query_free;
236
237   GST_EVENT_TYPE (query) = type;
238 }
239
240 /**
241  * gst_query_new_position:
242  * @format: the default #GstFormat for the new query
243  *
244  * Constructs a new query stream position query object. Use gst_query_unref()
245  * when done with it. A position query is used to query the current position
246  * of playback in the streams, in some format.
247  *
248  * Free-function: gst_query_unref
249  *
250  * Returns: (transfer full): a new #GstQuery
251  */
252 GstQuery *
253 gst_query_new_position (GstFormat format)
254 {
255   GstQuery *query;
256   GstStructure *structure;
257
258   structure = gst_structure_new_id (GST_QUARK (QUERY_POSITION),
259       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
260       GST_QUARK (CURRENT), G_TYPE_INT64, G_GINT64_CONSTANT (-1), NULL);
261
262   query = gst_query_new_custom (GST_QUERY_POSITION, structure);
263
264   return query;
265 }
266
267 /**
268  * gst_query_set_position:
269  * @query: a #GstQuery with query type GST_QUERY_POSITION
270  * @format: the requested #GstFormat
271  * @cur: the position to set
272  *
273  * Answer a position query by setting the requested value in the given format.
274  */
275 void
276 gst_query_set_position (GstQuery * query, GstFormat format, gint64 cur)
277 {
278   GstStructure *s;
279
280   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_POSITION);
281
282   s = GST_QUERY_STRUCTURE (query);
283   g_return_if_fail (format == g_value_get_enum (gst_structure_id_get_value (s,
284               GST_QUARK (FORMAT))));
285
286   gst_structure_id_set (s,
287       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
288       GST_QUARK (CURRENT), G_TYPE_INT64, cur, NULL);
289 }
290
291 /**
292  * gst_query_parse_position:
293  * @query: a #GstQuery
294  * @format: (out) (allow-none): the storage for the #GstFormat of the
295  *     position values (may be NULL)
296  * @cur: (out) (allow-none): the storage for the current position (may be NULL)
297  *
298  * Parse a position query, writing the format into @format, and the position
299  * into @cur, if the respective parameters are non-NULL.
300  */
301 void
302 gst_query_parse_position (GstQuery * query, GstFormat * format, gint64 * cur)
303 {
304   GstStructure *structure;
305
306   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_POSITION);
307
308   structure = GST_QUERY_STRUCTURE (query);
309   if (format)
310     *format =
311         (GstFormat) g_value_get_enum (gst_structure_id_get_value (structure,
312             GST_QUARK (FORMAT)));
313   if (cur)
314     *cur = g_value_get_int64 (gst_structure_id_get_value (structure,
315             GST_QUARK (CURRENT)));
316 }
317
318
319 /**
320  * gst_query_new_duration:
321  * @format: the #GstFormat for this duration query
322  *
323  * Constructs a new stream duration query object to query in the given format.
324  * Use gst_query_unref() when done with it. A duration query will give the
325  * total length of the stream.
326  *
327  * Free-function: gst_query_unref
328  *
329  * Returns: (transfer full): a new #GstQuery
330  */
331 GstQuery *
332 gst_query_new_duration (GstFormat format)
333 {
334   GstQuery *query;
335   GstStructure *structure;
336
337   structure = gst_structure_new_id (GST_QUARK (QUERY_DURATION),
338       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
339       GST_QUARK (DURATION), G_TYPE_INT64, G_GINT64_CONSTANT (-1), NULL);
340
341   query = gst_query_new_custom (GST_QUERY_DURATION, structure);
342
343   return query;
344 }
345
346 /**
347  * gst_query_set_duration:
348  * @query: a #GstQuery
349  * @format: the #GstFormat for the duration
350  * @duration: the duration of the stream
351  *
352  * Answer a duration query by setting the requested value in the given format.
353  */
354 void
355 gst_query_set_duration (GstQuery * query, GstFormat format, gint64 duration)
356 {
357   GstStructure *s;
358
359   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_DURATION);
360
361   s = GST_QUERY_STRUCTURE (query);
362   g_return_if_fail (format == g_value_get_enum (gst_structure_id_get_value (s,
363               GST_QUARK (FORMAT))));
364   gst_structure_id_set (s, GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
365       GST_QUARK (DURATION), G_TYPE_INT64, duration, NULL);
366 }
367
368 /**
369  * gst_query_parse_duration:
370  * @query: a #GstQuery
371  * @format: (out) (allow-none): the storage for the #GstFormat of the duration
372  *     value, or NULL.
373  * @duration: (out) (allow-none): the storage for the total duration, or NULL.
374  *
375  * Parse a duration query answer. Write the format of the duration into @format,
376  * and the value into @duration, if the respective variables are non-NULL.
377  */
378 void
379 gst_query_parse_duration (GstQuery * query, GstFormat * format,
380     gint64 * duration)
381 {
382   GstStructure *structure;
383
384   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_DURATION);
385
386   structure = GST_QUERY_STRUCTURE (query);
387   if (format)
388     *format =
389         (GstFormat) g_value_get_enum (gst_structure_id_get_value (structure,
390             GST_QUARK (FORMAT)));
391   if (duration)
392     *duration = g_value_get_int64 (gst_structure_id_get_value (structure,
393             GST_QUARK (DURATION)));
394 }
395
396 /**
397  * gst_query_new_latency:
398  *
399  * Constructs a new latency query object.
400  * Use gst_query_unref() when done with it. A latency query is usually performed
401  * by sinks to compensate for additional latency introduced by elements in the
402  * pipeline.
403  *
404  * Free-function: gst_query_unref
405  *
406  * Returns: (transfer full): a #GstQuery
407  *
408  * Since: 0.10.12
409  */
410 GstQuery *
411 gst_query_new_latency (void)
412 {
413   GstQuery *query;
414   GstStructure *structure;
415
416   structure = gst_structure_new_id (GST_QUARK (QUERY_LATENCY),
417       GST_QUARK (LIVE), G_TYPE_BOOLEAN, FALSE,
418       GST_QUARK (MIN_LATENCY), G_TYPE_UINT64, G_GUINT64_CONSTANT (0),
419       GST_QUARK (MAX_LATENCY), G_TYPE_UINT64, G_GUINT64_CONSTANT (-1), NULL);
420
421   query = gst_query_new_custom (GST_QUERY_LATENCY, structure);
422
423   return query;
424 }
425
426 /**
427  * gst_query_set_latency:
428  * @query: a #GstQuery
429  * @live: if there is a live element upstream
430  * @min_latency: the minimal latency of the upstream elements
431  * @max_latency: the maximal latency of the upstream elements
432  *
433  * Answer a latency query by setting the requested values in the given format.
434  *
435  * Since: 0.10.12
436  */
437 void
438 gst_query_set_latency (GstQuery * query, gboolean live,
439     GstClockTime min_latency, GstClockTime max_latency)
440 {
441   GstStructure *structure;
442
443   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_LATENCY);
444
445   structure = GST_QUERY_STRUCTURE (query);
446   gst_structure_id_set (structure,
447       GST_QUARK (LIVE), G_TYPE_BOOLEAN, live,
448       GST_QUARK (MIN_LATENCY), G_TYPE_UINT64, min_latency,
449       GST_QUARK (MAX_LATENCY), G_TYPE_UINT64, max_latency, NULL);
450 }
451
452 /**
453  * gst_query_parse_latency:
454  * @query: a #GstQuery
455  * @live: (out) (allow-none): storage for live or NULL
456  * @min_latency: (out) (allow-none): the storage for the min latency or NULL
457  * @max_latency: (out) (allow-none): the storage for the max latency or NULL
458  *
459  * Parse a latency query answer.
460  *
461  * Since: 0.10.12
462  */
463 void
464 gst_query_parse_latency (GstQuery * query, gboolean * live,
465     GstClockTime * min_latency, GstClockTime * max_latency)
466 {
467   GstStructure *structure;
468
469   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_LATENCY);
470
471   structure = GST_QUERY_STRUCTURE (query);
472   if (live)
473     *live =
474         g_value_get_boolean (gst_structure_id_get_value (structure,
475             GST_QUARK (LIVE)));
476   if (min_latency)
477     *min_latency = g_value_get_uint64 (gst_structure_id_get_value (structure,
478             GST_QUARK (MIN_LATENCY)));
479   if (max_latency)
480     *max_latency = g_value_get_uint64 (gst_structure_id_get_value (structure,
481             GST_QUARK (MAX_LATENCY)));
482 }
483
484 /**
485  * gst_query_new_convert:
486  * @src_format: the source #GstFormat for the new query
487  * @value: the value to convert
488  * @dest_format: the target #GstFormat
489  *
490  * Constructs a new convert query object. Use gst_query_unref()
491  * when done with it. A convert query is used to ask for a conversion between
492  * one format and another.
493  *
494  * Free-function: gst_query_unref
495  *
496  * Returns: (transfer full): a #GstQuery
497  */
498 GstQuery *
499 gst_query_new_convert (GstFormat src_format, gint64 value,
500     GstFormat dest_format)
501 {
502   GstQuery *query;
503   GstStructure *structure;
504
505   structure = gst_structure_new_id (GST_QUARK (QUERY_CONVERT),
506       GST_QUARK (SRC_FORMAT), GST_TYPE_FORMAT, src_format,
507       GST_QUARK (SRC_VALUE), G_TYPE_INT64, value,
508       GST_QUARK (DEST_FORMAT), GST_TYPE_FORMAT, dest_format,
509       GST_QUARK (DEST_VALUE), G_TYPE_INT64, G_GINT64_CONSTANT (-1), NULL);
510
511   query = gst_query_new_custom (GST_QUERY_CONVERT, structure);
512
513   return query;
514 }
515
516 /**
517  * gst_query_set_convert:
518  * @query: a #GstQuery
519  * @src_format: the source #GstFormat
520  * @src_value: the source value
521  * @dest_format: the destination #GstFormat
522  * @dest_value: the destination value
523  *
524  * Answer a convert query by setting the requested values.
525  */
526 void
527 gst_query_set_convert (GstQuery * query, GstFormat src_format, gint64 src_value,
528     GstFormat dest_format, gint64 dest_value)
529 {
530   GstStructure *structure;
531
532   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CONVERT);
533
534   structure = GST_QUERY_STRUCTURE (query);
535   gst_structure_id_set (structure,
536       GST_QUARK (SRC_FORMAT), GST_TYPE_FORMAT, src_format,
537       GST_QUARK (SRC_VALUE), G_TYPE_INT64, src_value,
538       GST_QUARK (DEST_FORMAT), GST_TYPE_FORMAT, dest_format,
539       GST_QUARK (DEST_VALUE), G_TYPE_INT64, dest_value, NULL);
540 }
541
542 /**
543  * gst_query_parse_convert:
544  * @query: a #GstQuery
545  * @src_format: (out) (allow-none): the storage for the #GstFormat of the
546  *     source value, or NULL
547  * @src_value: (out) (allow-none): the storage for the source value, or NULL
548  * @dest_format: (out) (allow-none): the storage for the #GstFormat of the
549  *     destination value, or NULL
550  * @dest_value: (out) (allow-none): the storage for the destination value,
551  *     or NULL
552  *
553  * Parse a convert query answer. Any of @src_format, @src_value, @dest_format,
554  * and @dest_value may be NULL, in which case that value is omitted.
555  */
556 void
557 gst_query_parse_convert (GstQuery * query, GstFormat * src_format,
558     gint64 * src_value, GstFormat * dest_format, gint64 * dest_value)
559 {
560   GstStructure *structure;
561
562   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CONVERT);
563
564   structure = GST_QUERY_STRUCTURE (query);
565   if (src_format)
566     *src_format =
567         (GstFormat) g_value_get_enum (gst_structure_id_get_value (structure,
568             GST_QUARK (SRC_FORMAT)));
569   if (src_value)
570     *src_value = g_value_get_int64 (gst_structure_id_get_value (structure,
571             GST_QUARK (SRC_VALUE)));
572   if (dest_format)
573     *dest_format =
574         (GstFormat) g_value_get_enum (gst_structure_id_get_value (structure,
575             GST_QUARK (DEST_FORMAT)));
576   if (dest_value)
577     *dest_value = g_value_get_int64 (gst_structure_id_get_value (structure,
578             GST_QUARK (DEST_VALUE)));
579 }
580
581 /**
582  * gst_query_new_segment:
583  * @format: the #GstFormat for the new query
584  *
585  * Constructs a new segment query object. Use gst_query_unref()
586  * when done with it. A segment query is used to discover information about the
587  * currently configured segment for playback.
588  *
589  * Free-function: gst_query_unref
590  *
591  * Returns: (transfer full): a new #GstQuery
592  */
593 GstQuery *
594 gst_query_new_segment (GstFormat format)
595 {
596   GstQuery *query;
597   GstStructure *structure;
598
599   structure = gst_structure_new_id (GST_QUARK (QUERY_SEGMENT),
600       GST_QUARK (RATE), G_TYPE_DOUBLE, (gdouble) 0.0,
601       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
602       GST_QUARK (START_VALUE), G_TYPE_INT64, G_GINT64_CONSTANT (-1),
603       GST_QUARK (STOP_VALUE), G_TYPE_INT64, G_GINT64_CONSTANT (-1), NULL);
604
605   query = gst_query_new_custom (GST_QUERY_SEGMENT, structure);
606
607   return query;
608 }
609
610 /**
611  * gst_query_set_segment:
612  * @query: a #GstQuery
613  * @rate: the rate of the segment
614  * @format: the #GstFormat of the segment values (@start_value and @stop_value)
615  * @start_value: the start value
616  * @stop_value: the stop value
617  *
618  * Answer a segment query by setting the requested values. The normal
619  * playback segment of a pipeline is 0 to duration at the default rate of
620  * 1.0. If a seek was performed on the pipeline to play a different
621  * segment, this query will return the range specified in the last seek.
622  *
623  * @start_value and @stop_value will respectively contain the configured
624  * playback range start and stop values expressed in @format.
625  * The values are always between 0 and the duration of the media and
626  * @start_value <= @stop_value. @rate will contain the playback rate. For
627  * negative rates, playback will actually happen from @stop_value to
628  * @start_value.
629  */
630 void
631 gst_query_set_segment (GstQuery * query, gdouble rate, GstFormat format,
632     gint64 start_value, gint64 stop_value)
633 {
634   GstStructure *structure;
635
636   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SEGMENT);
637
638   structure = GST_QUERY_STRUCTURE (query);
639   gst_structure_id_set (structure,
640       GST_QUARK (RATE), G_TYPE_DOUBLE, rate,
641       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
642       GST_QUARK (START_VALUE), G_TYPE_INT64, start_value,
643       GST_QUARK (STOP_VALUE), G_TYPE_INT64, stop_value, NULL);
644 }
645
646 /**
647  * gst_query_parse_segment:
648  * @query: a #GstQuery
649  * @rate: (out) (allow-none): the storage for the rate of the segment, or NULL
650  * @format: (out) (allow-none): the storage for the #GstFormat of the values,
651  *     or NULL
652  * @start_value: (out) (allow-none): the storage for the start value, or NULL
653  * @stop_value: (out) (allow-none): the storage for the stop value, or NULL
654  *
655  * Parse a segment query answer. Any of @rate, @format, @start_value, and
656  * @stop_value may be NULL, which will cause this value to be omitted.
657  *
658  * See gst_query_set_segment() for an explanation of the function arguments.
659  */
660 void
661 gst_query_parse_segment (GstQuery * query, gdouble * rate, GstFormat * format,
662     gint64 * start_value, gint64 * stop_value)
663 {
664   GstStructure *structure;
665
666   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SEGMENT);
667
668   structure = GST_QUERY_STRUCTURE (query);
669   if (rate)
670     *rate = g_value_get_double (gst_structure_id_get_value (structure,
671             GST_QUARK (RATE)));
672   if (format)
673     *format =
674         (GstFormat) g_value_get_enum (gst_structure_id_get_value (structure,
675             GST_QUARK (FORMAT)));
676   if (start_value)
677     *start_value = g_value_get_int64 (gst_structure_id_get_value (structure,
678             GST_QUARK (START_VALUE)));
679   if (stop_value)
680     *stop_value = g_value_get_int64 (gst_structure_id_get_value (structure,
681             GST_QUARK (STOP_VALUE)));
682 }
683
684 /**
685  * gst_query_new_custom:
686  * @type: the query type
687  * @structure: a structure for the query
688  *
689  * Constructs a new custom query object. Use gst_query_unref()
690  * when done with it.
691  *
692  * Free-function: gst_query_unref
693  *
694  * Returns: (transfer full): a new #GstQuery
695  */
696 GstQuery *
697 gst_query_new_custom (GstQueryType type, GstStructure * structure)
698 {
699   GstQueryImpl *query;
700
701   query = g_slice_new0 (GstQueryImpl);
702
703   GST_DEBUG ("creating new query %p %s", query, gst_query_type_get_name (type));
704
705   if (structure) {
706     /* structure must not have a parent */
707     if (!gst_structure_set_parent_refcount (structure,
708             &query->query.mini_object.refcount))
709       goto had_parent;
710   }
711   gst_query_init (query, sizeof (GstQueryImpl), type);
712
713   GST_QUERY_STRUCTURE (query) = structure;
714
715   return GST_QUERY_CAST (query);
716
717   /* ERRORS */
718 had_parent:
719   {
720     g_slice_free1 (GST_MINI_OBJECT_SIZE (query), query);
721     g_warning ("structure is already owned by another object");
722     return NULL;
723   }
724 }
725
726 /**
727  * gst_query_get_structure:
728  * @query: a #GstQuery
729  *
730  * Get the structure of a query.
731  *
732  * Returns: (transfer none): the #GstStructure of the query. The structure is
733  *     still owned by the query and will therefore be freed when the query
734  *     is unreffed.
735  */
736 const GstStructure *
737 gst_query_get_structure (GstQuery * query)
738 {
739   g_return_val_if_fail (GST_IS_QUERY (query), NULL);
740
741   return GST_QUERY_STRUCTURE (query);
742 }
743
744 /**
745  * gst_query_writable_structure:
746  * @query: a #GstQuery
747  *
748  * Get the structure of a query. This method should be called with a writable
749  * @query so that the returned structure is guranteed to be writable.
750  *
751  * Returns: (transfer none): the #GstStructure of the query. The structure is
752  *     still owned by the query and will therefore be freed when the query
753  *     is unreffed.
754  */
755 GstStructure *
756 gst_query_writable_structure (GstQuery * query)
757 {
758   g_return_val_if_fail (GST_IS_QUERY (query), NULL);
759   g_return_val_if_fail (gst_query_is_writable (query), NULL);
760
761   return GST_QUERY_STRUCTURE (query);
762 }
763
764 /**
765  * gst_query_new_seeking:
766  * @format: the default #GstFormat for the new query
767  *
768  * Constructs a new query object for querying seeking properties of
769  * the stream.
770  *
771  * Free-function: gst_query_unref
772  *
773  * Returns: (transfer full): a new #GstQuery
774  */
775 GstQuery *
776 gst_query_new_seeking (GstFormat format)
777 {
778   GstQuery *query;
779   GstStructure *structure;
780
781   structure = gst_structure_new_id (GST_QUARK (QUERY_SEEKING),
782       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
783       GST_QUARK (SEEKABLE), G_TYPE_BOOLEAN, FALSE,
784       GST_QUARK (SEGMENT_START), G_TYPE_INT64, G_GINT64_CONSTANT (-1),
785       GST_QUARK (SEGMENT_END), G_TYPE_INT64, G_GINT64_CONSTANT (-1), NULL);
786
787   query = gst_query_new_custom (GST_QUERY_SEEKING, structure);
788
789   return query;
790 }
791
792 /**
793  * gst_query_set_seeking:
794  * @query: a #GstQuery
795  * @format: the format to set for the @segment_start and @segment_end values
796  * @seekable: the seekable flag to set
797  * @segment_start: the segment_start to set
798  * @segment_end: the segment_end to set
799  *
800  * Set the seeking query result fields in @query.
801  */
802 void
803 gst_query_set_seeking (GstQuery * query, GstFormat format,
804     gboolean seekable, gint64 segment_start, gint64 segment_end)
805 {
806   GstStructure *structure;
807
808   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SEEKING);
809   g_return_if_fail (gst_query_is_writable (query));
810
811   structure = GST_QUERY_STRUCTURE (query);
812   gst_structure_id_set (structure,
813       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
814       GST_QUARK (SEEKABLE), G_TYPE_BOOLEAN, seekable,
815       GST_QUARK (SEGMENT_START), G_TYPE_INT64, segment_start,
816       GST_QUARK (SEGMENT_END), G_TYPE_INT64, segment_end, NULL);
817 }
818
819 /**
820  * gst_query_parse_seeking:
821  * @query: a GST_QUERY_SEEKING type query #GstQuery
822  * @format: (out) (allow-none): the format to set for the @segment_start
823  *     and @segment_end values, or NULL
824  * @seekable: (out) (allow-none): the seekable flag to set, or NULL
825  * @segment_start: (out) (allow-none): the segment_start to set, or NULL
826  * @segment_end: (out) (allow-none): the segment_end to set, or NULL
827  *
828  * Parse a seeking query, writing the format into @format, and
829  * other results into the passed parameters, if the respective parameters
830  * are non-NULL
831  */
832 void
833 gst_query_parse_seeking (GstQuery * query, GstFormat * format,
834     gboolean * seekable, gint64 * segment_start, gint64 * segment_end)
835 {
836   GstStructure *structure;
837
838   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SEEKING);
839
840   structure = GST_QUERY_STRUCTURE (query);
841   if (format)
842     *format =
843         (GstFormat) g_value_get_enum (gst_structure_id_get_value (structure,
844             GST_QUARK (FORMAT)));
845   if (seekable)
846     *seekable = g_value_get_boolean (gst_structure_id_get_value (structure,
847             GST_QUARK (SEEKABLE)));
848   if (segment_start)
849     *segment_start = g_value_get_int64 (gst_structure_id_get_value (structure,
850             GST_QUARK (SEGMENT_START)));
851   if (segment_end)
852     *segment_end = g_value_get_int64 (gst_structure_id_get_value (structure,
853             GST_QUARK (SEGMENT_END)));
854 }
855
856 static GArray *
857 ensure_array (GstStructure * s, GQuark quark, gsize element_size,
858     GDestroyNotify clear_func)
859 {
860   GArray *array;
861   const GValue *value;
862
863   value = gst_structure_id_get_value (s, quark);
864   if (value) {
865     array = (GArray *) g_value_get_boxed (value);
866   } else {
867     GValue new_array_val = { 0, };
868
869     array = g_array_new (FALSE, TRUE, element_size);
870     if (clear_func)
871       g_array_set_clear_func (array, clear_func);
872
873     g_value_init (&new_array_val, G_TYPE_ARRAY);
874     g_value_take_boxed (&new_array_val, array);
875
876     gst_structure_id_take_value (s, quark, &new_array_val);
877   }
878   return array;
879 }
880
881 /**
882  * gst_query_new_formats:
883  *
884  * Constructs a new query object for querying formats of
885  * the stream.
886  *
887  * Free-function: gst_query_unref
888  *
889  * Returns: (transfer full): a new #GstQuery
890  *
891  * Since: 0.10.4
892  */
893 GstQuery *
894 gst_query_new_formats (void)
895 {
896   GstQuery *query;
897   GstStructure *structure;
898
899   structure = gst_structure_new_id_empty (GST_QUARK (QUERY_FORMATS));
900   query = gst_query_new_custom (GST_QUERY_FORMATS, structure);
901
902   return query;
903 }
904
905 static void
906 gst_query_list_add_format (GValue * list, GstFormat format)
907 {
908   GValue item = { 0, };
909
910   g_value_init (&item, GST_TYPE_FORMAT);
911   g_value_set_enum (&item, format);
912   gst_value_list_append_value (list, &item);
913   g_value_unset (&item);
914 }
915
916 /**
917  * gst_query_set_formats:
918  * @query: a #GstQuery
919  * @n_formats: the number of formats to set.
920  * @...: A number of @GstFormats equal to @n_formats.
921  *
922  * Set the formats query result fields in @query. The number of formats passed
923  * must be equal to @n_formats.
924  */
925 void
926 gst_query_set_formats (GstQuery * query, gint n_formats, ...)
927 {
928   va_list ap;
929   GValue list = { 0, };
930   gint i;
931   GstStructure *structure;
932
933   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_FORMATS);
934   g_return_if_fail (gst_query_is_writable (query));
935
936   g_value_init (&list, GST_TYPE_LIST);
937
938   va_start (ap, n_formats);
939   for (i = 0; i < n_formats; i++) {
940     gst_query_list_add_format (&list, va_arg (ap, GstFormat));
941   }
942   va_end (ap);
943
944   structure = GST_QUERY_STRUCTURE (query);
945   gst_structure_set_value (structure, "formats", &list);
946
947   g_value_unset (&list);
948
949 }
950
951 /**
952  * gst_query_set_formatsv:
953  * @query: a #GstQuery
954  * @n_formats: the number of formats to set.
955  * @formats: (in) (array length=n_formats): an array containing @n_formats
956  *     @GstFormat values.
957  *
958  * Set the formats query result fields in @query. The number of formats passed
959  * in the @formats array must be equal to @n_formats.
960  *
961  * Since: 0.10.4
962  */
963 void
964 gst_query_set_formatsv (GstQuery * query, gint n_formats,
965     const GstFormat * formats)
966 {
967   GValue list = { 0, };
968   gint i;
969   GstStructure *structure;
970
971   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_FORMATS);
972   g_return_if_fail (gst_query_is_writable (query));
973
974   g_value_init (&list, GST_TYPE_LIST);
975   for (i = 0; i < n_formats; i++) {
976     gst_query_list_add_format (&list, formats[i]);
977   }
978   structure = GST_QUERY_STRUCTURE (query);
979   gst_structure_set_value (structure, "formats", &list);
980
981   g_value_unset (&list);
982 }
983
984 /**
985  * gst_query_parse_n_formats:
986  * @query: a #GstQuery
987  * @n_formats: (out) (allow-none): the number of formats in this query.
988  *
989  * Parse the number of formats in the formats @query.
990  *
991  * Since: 0.10.4
992  */
993 void
994 gst_query_parse_n_formats (GstQuery * query, guint * n_formats)
995 {
996   GstStructure *structure;
997
998   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_FORMATS);
999
1000   if (n_formats) {
1001     const GValue *list;
1002
1003     structure = GST_QUERY_STRUCTURE (query);
1004     list = gst_structure_get_value (structure, "formats");
1005     if (list == NULL)
1006       *n_formats = 0;
1007     else
1008       *n_formats = gst_value_list_get_size (list);
1009   }
1010 }
1011
1012 /**
1013  * gst_query_parse_nth_format:
1014  * @query: a #GstQuery
1015  * @nth: (out): the nth format to retrieve.
1016  * @format: (out) (allow-none): a pointer to store the nth format
1017  *
1018  * Parse the format query and retrieve the @nth format from it into
1019  * @format. If the list contains less elements than @nth, @format will be
1020  * set to GST_FORMAT_UNDEFINED.
1021  */
1022 void
1023 gst_query_parse_nth_format (GstQuery * query, guint nth, GstFormat * format)
1024 {
1025   GstStructure *structure;
1026
1027   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_FORMATS);
1028
1029   if (format) {
1030     const GValue *list;
1031
1032     structure = GST_QUERY_STRUCTURE (query);
1033     list = gst_structure_get_value (structure, "formats");
1034     if (list == NULL) {
1035       *format = GST_FORMAT_UNDEFINED;
1036     } else {
1037       if (nth < gst_value_list_get_size (list)) {
1038         *format =
1039             (GstFormat) g_value_get_enum (gst_value_list_get_value (list, nth));
1040       } else
1041         *format = GST_FORMAT_UNDEFINED;
1042     }
1043   }
1044 }
1045
1046 /**
1047  * gst_query_new_buffering:
1048  * @format: the default #GstFormat for the new query
1049  *
1050  * Constructs a new query object for querying the buffering status of
1051  * a stream.
1052  *
1053  * Free-function: gst_query_unref
1054  *
1055  * Returns: (transfer full): a new #GstQuery
1056  *
1057  * Since: 0.10.20
1058  */
1059 GstQuery *
1060 gst_query_new_buffering (GstFormat format)
1061 {
1062   GstQuery *query;
1063   GstStructure *structure;
1064
1065   /* by default, we configure the answer as no buffering with a 100% buffering
1066    * progress */
1067   structure = gst_structure_new_id (GST_QUARK (QUERY_BUFFERING),
1068       GST_QUARK (BUSY), G_TYPE_BOOLEAN, FALSE,
1069       GST_QUARK (BUFFER_PERCENT), G_TYPE_INT, 100,
1070       GST_QUARK (BUFFERING_MODE), GST_TYPE_BUFFERING_MODE, GST_BUFFERING_STREAM,
1071       GST_QUARK (AVG_IN_RATE), G_TYPE_INT, -1,
1072       GST_QUARK (AVG_OUT_RATE), G_TYPE_INT, -1,
1073       GST_QUARK (BUFFERING_LEFT), G_TYPE_INT64, G_GINT64_CONSTANT (0),
1074       GST_QUARK (ESTIMATED_TOTAL), G_TYPE_INT64, G_GINT64_CONSTANT (-1),
1075       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
1076       GST_QUARK (START_VALUE), G_TYPE_INT64, G_GINT64_CONSTANT (-1),
1077       GST_QUARK (STOP_VALUE), G_TYPE_INT64, G_GINT64_CONSTANT (-1), NULL);
1078
1079   query = gst_query_new_custom (GST_QUERY_BUFFERING, structure);
1080
1081   return query;
1082 }
1083
1084 /**
1085  * gst_query_set_buffering_percent:
1086  * @query: A valid #GstQuery of type GST_QUERY_BUFFERING.
1087  * @busy: if buffering is busy
1088  * @percent: a buffering percent
1089  *
1090  * Set the percentage of buffered data. This is a value between 0 and 100.
1091  * The @busy indicator is %TRUE when the buffering is in progress.
1092  *
1093  * Since: 0.10.20
1094  */
1095 void
1096 gst_query_set_buffering_percent (GstQuery * query, gboolean busy, gint percent)
1097 {
1098   GstStructure *structure;
1099
1100   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING);
1101   g_return_if_fail (gst_query_is_writable (query));
1102   g_return_if_fail (percent >= 0 && percent <= 100);
1103
1104   structure = GST_QUERY_STRUCTURE (query);
1105   gst_structure_id_set (structure,
1106       GST_QUARK (BUSY), G_TYPE_BOOLEAN, busy,
1107       GST_QUARK (BUFFER_PERCENT), G_TYPE_INT, percent, NULL);
1108 }
1109
1110 /**
1111  * gst_query_parse_buffering_percent:
1112  * @query: A valid #GstQuery of type GST_QUERY_BUFFERING.
1113  * @busy: (out) (allow-none): if buffering is busy, or NULL
1114  * @percent: (out) (allow-none): a buffering percent, or NULL
1115  *
1116  * Get the percentage of buffered data. This is a value between 0 and 100.
1117  * The @busy indicator is %TRUE when the buffering is in progress.
1118  *
1119  * Since: 0.10.20
1120  */
1121 void
1122 gst_query_parse_buffering_percent (GstQuery * query, gboolean * busy,
1123     gint * percent)
1124 {
1125   GstStructure *structure;
1126
1127   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING);
1128
1129   structure = GST_QUERY_STRUCTURE (query);
1130   if (busy)
1131     *busy = g_value_get_boolean (gst_structure_id_get_value (structure,
1132             GST_QUARK (BUSY)));
1133   if (percent)
1134     *percent = g_value_get_int (gst_structure_id_get_value (structure,
1135             GST_QUARK (BUFFER_PERCENT)));
1136 }
1137
1138 /**
1139  * gst_query_set_buffering_stats:
1140  * @query: A valid #GstQuery of type GST_QUERY_BUFFERING.
1141  * @mode: a buffering mode
1142  * @avg_in: the average input rate
1143  * @avg_out: the average output rate
1144  * @buffering_left: amount of buffering time left
1145  *
1146  * Configures the buffering stats values in @query.
1147  *
1148  * Since: 0.10.20
1149  */
1150 void
1151 gst_query_set_buffering_stats (GstQuery * query, GstBufferingMode mode,
1152     gint avg_in, gint avg_out, gint64 buffering_left)
1153 {
1154   GstStructure *structure;
1155
1156   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING);
1157   g_return_if_fail (gst_query_is_writable (query));
1158
1159   structure = GST_QUERY_STRUCTURE (query);
1160   gst_structure_id_set (structure,
1161       GST_QUARK (BUFFERING_MODE), GST_TYPE_BUFFERING_MODE, mode,
1162       GST_QUARK (AVG_IN_RATE), G_TYPE_INT, avg_in,
1163       GST_QUARK (AVG_OUT_RATE), G_TYPE_INT, avg_out,
1164       GST_QUARK (BUFFERING_LEFT), G_TYPE_INT64, buffering_left, NULL);
1165 }
1166
1167 /**
1168  * gst_query_parse_buffering_stats:
1169  * @query: A valid #GstQuery of type GST_QUERY_BUFFERING.
1170  * @mode: (out) (allow-none): a buffering mode, or NULL
1171  * @avg_in: (out) (allow-none): the average input rate, or NULL
1172  * @avg_out: (out) (allow-none): the average output rat, or NULLe
1173  * @buffering_left: (out) (allow-none): amount of buffering time left, or NULL
1174  *
1175  * Extracts the buffering stats values from @query.
1176  *
1177  * Since: 0.10.20
1178  */
1179 void
1180 gst_query_parse_buffering_stats (GstQuery * query,
1181     GstBufferingMode * mode, gint * avg_in, gint * avg_out,
1182     gint64 * buffering_left)
1183 {
1184   GstStructure *structure;
1185
1186   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING);
1187
1188   structure = GST_QUERY_STRUCTURE (query);
1189   if (mode)
1190     *mode = (GstBufferingMode)
1191         g_value_get_enum (gst_structure_id_get_value (structure,
1192             GST_QUARK (BUFFERING_MODE)));
1193   if (avg_in)
1194     *avg_in = g_value_get_int (gst_structure_id_get_value (structure,
1195             GST_QUARK (AVG_IN_RATE)));
1196   if (avg_out)
1197     *avg_out = g_value_get_int (gst_structure_id_get_value (structure,
1198             GST_QUARK (AVG_OUT_RATE)));
1199   if (buffering_left)
1200     *buffering_left =
1201         g_value_get_int64 (gst_structure_id_get_value (structure,
1202             GST_QUARK (BUFFERING_LEFT)));
1203 }
1204
1205 /**
1206  * gst_query_set_buffering_range:
1207  * @query: a #GstQuery
1208  * @format: the format to set for the @start and @stop values
1209  * @start: the start to set
1210  * @stop: the stop to set
1211  * @estimated_total: estimated total amount of download time
1212  *
1213  * Set the available query result fields in @query.
1214  *
1215  * Since: 0.10.20
1216  */
1217 void
1218 gst_query_set_buffering_range (GstQuery * query, GstFormat format,
1219     gint64 start, gint64 stop, gint64 estimated_total)
1220 {
1221   GstStructure *structure;
1222
1223   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING);
1224   g_return_if_fail (gst_query_is_writable (query));
1225
1226   structure = GST_QUERY_STRUCTURE (query);
1227   gst_structure_id_set (structure,
1228       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
1229       GST_QUARK (START_VALUE), G_TYPE_INT64, start,
1230       GST_QUARK (STOP_VALUE), G_TYPE_INT64, stop,
1231       GST_QUARK (ESTIMATED_TOTAL), G_TYPE_INT64, estimated_total, NULL);
1232 }
1233
1234 /**
1235  * gst_query_parse_buffering_range:
1236  * @query: a GST_QUERY_BUFFERING type query #GstQuery
1237  * @format: (out) (allow-none): the format to set for the @segment_start
1238  *     and @segment_end values, or NULL
1239  * @start: (out) (allow-none): the start to set, or NULL
1240  * @stop: (out) (allow-none): the stop to set, or NULL
1241  * @estimated_total: (out) (allow-none): estimated total amount of download
1242  *     time, or NULL
1243  *
1244  * Parse an available query, writing the format into @format, and
1245  * other results into the passed parameters, if the respective parameters
1246  * are non-NULL
1247  *
1248  * Since: 0.10.20
1249  */
1250 void
1251 gst_query_parse_buffering_range (GstQuery * query, GstFormat * format,
1252     gint64 * start, gint64 * stop, gint64 * estimated_total)
1253 {
1254   GstStructure *structure;
1255
1256   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING);
1257
1258   structure = GST_QUERY_STRUCTURE (query);
1259   if (format)
1260     *format =
1261         (GstFormat) g_value_get_enum (gst_structure_id_get_value (structure,
1262             GST_QUARK (FORMAT)));
1263   if (start)
1264     *start = g_value_get_int64 (gst_structure_id_get_value (structure,
1265             GST_QUARK (START_VALUE)));
1266   if (stop)
1267     *stop = g_value_get_int64 (gst_structure_id_get_value (structure,
1268             GST_QUARK (STOP_VALUE)));
1269   if (estimated_total)
1270     *estimated_total =
1271         g_value_get_int64 (gst_structure_id_get_value (structure,
1272             GST_QUARK (ESTIMATED_TOTAL)));
1273 }
1274
1275 /**
1276  * gst_query_add_buffering_range:
1277  * @query: a GST_QUERY_BUFFERING type query #GstQuery
1278  * @start: start position of the range
1279  * @stop: stop position of the range
1280  *
1281  * Set the buffering-ranges array field in @query. The current last
1282  * start position of the array should be inferior to @start.
1283  *
1284  * Returns: a #gboolean indicating if the range was added or not.
1285  *
1286  * Since: 0.10.31
1287  */
1288 gboolean
1289 gst_query_add_buffering_range (GstQuery * query, gint64 start, gint64 stop)
1290 {
1291   GstQueryBufferingRange range;
1292   GstStructure *structure;
1293   GArray *array;
1294
1295   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING, FALSE);
1296   g_return_val_if_fail (gst_query_is_writable (query), FALSE);
1297
1298   if (G_UNLIKELY (start >= stop))
1299     return FALSE;
1300
1301   structure = GST_QUERY_STRUCTURE (query);
1302   array = ensure_array (structure, GST_QUARK (BUFFERING_RANGES),
1303       sizeof (GstQueryBufferingRange), NULL);
1304
1305   if (array->len > 1) {
1306     GstQueryBufferingRange *last;
1307
1308     last = &g_array_index (array, GstQueryBufferingRange, array->len - 1);
1309
1310     if (G_UNLIKELY (start <= last->start))
1311       return FALSE;
1312   }
1313
1314   range.start = start;
1315   range.stop = stop;
1316   g_array_append_val (array, range);
1317
1318   return TRUE;
1319 }
1320
1321 /**
1322  * gst_query_get_n_buffering_ranges:
1323  * @query: a GST_QUERY_BUFFERING type query #GstQuery
1324  *
1325  * Retrieve the number of values currently stored in the
1326  * buffered-ranges array of the query's structure.
1327  *
1328  * Returns: the range array size as a #guint.
1329  *
1330  * Since: 0.10.31
1331  */
1332 guint
1333 gst_query_get_n_buffering_ranges (GstQuery * query)
1334 {
1335   GstStructure *structure;
1336   GArray *array;
1337
1338   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING, 0);
1339
1340   structure = GST_QUERY_STRUCTURE (query);
1341   array = ensure_array (structure, GST_QUARK (BUFFERING_RANGES),
1342       sizeof (GstQueryBufferingRange), NULL);
1343
1344   return array->len;
1345 }
1346
1347
1348 /**
1349  * gst_query_parse_nth_buffering_range:
1350  * @query: a GST_QUERY_BUFFERING type query #GstQuery
1351  * @index: position in the buffered-ranges array to read
1352  * @start: (out) (allow-none): the start position to set, or NULL
1353  * @stop: (out) (allow-none): the stop position to set, or NULL
1354  *
1355  * Parse an available query and get the start and stop values stored
1356  * at the @index of the buffered ranges array.
1357  *
1358  * Returns: a #gboolean indicating if the parsing succeeded.
1359  *
1360  * Since: 0.10.31
1361  */
1362 gboolean
1363 gst_query_parse_nth_buffering_range (GstQuery * query, guint index,
1364     gint64 * start, gint64 * stop)
1365 {
1366   GstQueryBufferingRange *range;
1367   GstStructure *structure;
1368   GArray *array;
1369
1370   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING, FALSE);
1371
1372   structure = GST_QUERY_STRUCTURE (query);
1373
1374   array = ensure_array (structure, GST_QUARK (BUFFERING_RANGES),
1375       sizeof (GstQueryBufferingRange), NULL);
1376   g_return_val_if_fail (index < array->len, FALSE);
1377
1378   range = &g_array_index (array, GstQueryBufferingRange, index);
1379
1380   if (start)
1381     *start = range->start;
1382   if (stop)
1383     *stop = range->stop;
1384
1385   return TRUE;
1386 }
1387
1388
1389 /**
1390  * gst_query_new_uri:
1391  *
1392  * Constructs a new query URI query object. Use gst_query_unref()
1393  * when done with it. An URI query is used to query the current URI
1394  * that is used by the source or sink.
1395  *
1396  * Free-function: gst_query_unref
1397  *
1398  * Returns: (transfer full): a new #GstQuery
1399  *
1400  * Since: 0.10.22
1401  */
1402 GstQuery *
1403 gst_query_new_uri (void)
1404 {
1405   GstQuery *query;
1406   GstStructure *structure;
1407
1408   structure = gst_structure_new_id (GST_QUARK (QUERY_URI),
1409       GST_QUARK (URI), G_TYPE_STRING, NULL, NULL);
1410
1411   query = gst_query_new_custom (GST_QUERY_URI, structure);
1412
1413   return query;
1414 }
1415
1416 /**
1417  * gst_query_set_uri:
1418  * @query: a #GstQuery with query type GST_QUERY_URI
1419  * @uri: the URI to set
1420  *
1421  * Answer a URI query by setting the requested URI.
1422  *
1423  * Since: 0.10.22
1424  */
1425 void
1426 gst_query_set_uri (GstQuery * query, const gchar * uri)
1427 {
1428   GstStructure *structure;
1429
1430   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_URI);
1431   g_return_if_fail (gst_query_is_writable (query));
1432   g_return_if_fail (gst_uri_is_valid (uri));
1433
1434   structure = GST_QUERY_STRUCTURE (query);
1435   gst_structure_id_set (structure, GST_QUARK (URI), G_TYPE_STRING, uri, NULL);
1436 }
1437
1438 /**
1439  * gst_query_parse_uri:
1440  * @query: a #GstQuery
1441  * @uri: (out callee-allocates) (allow-none): the storage for the current URI
1442  *     (may be NULL)
1443  *
1444  * Parse an URI query, writing the URI into @uri as a newly
1445  * allocated string, if the respective parameters are non-NULL.
1446  * Free the string with g_free() after usage.
1447  *
1448  * Since: 0.10.22
1449  */
1450 void
1451 gst_query_parse_uri (GstQuery * query, gchar ** uri)
1452 {
1453   GstStructure *structure;
1454
1455   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_URI);
1456
1457   structure = GST_QUERY_STRUCTURE (query);
1458   if (uri)
1459     *uri = g_value_dup_string (gst_structure_id_get_value (structure,
1460             GST_QUARK (URI)));
1461 }
1462
1463 /**
1464  * gst_query_new_allocation:
1465  * @caps: the negotiated caps
1466  * @need_pool: return a pool
1467  *
1468  * Constructs a new query object for querying the allocation properties.
1469  *
1470  * Free-function: gst_query_unref
1471  *
1472  * Returns: (transfer full): a new #GstQuery
1473  */
1474 GstQuery *
1475 gst_query_new_allocation (GstCaps * caps, gboolean need_pool)
1476 {
1477   GstQuery *query;
1478   GstStructure *structure;
1479
1480   structure = gst_structure_new_id (GST_QUARK (QUERY_ALLOCATION),
1481       GST_QUARK (CAPS), GST_TYPE_CAPS, caps,
1482       GST_QUARK (NEED_POOL), G_TYPE_BOOLEAN, need_pool,
1483       GST_QUARK (SIZE), G_TYPE_UINT, 0,
1484       GST_QUARK (MIN_BUFFERS), G_TYPE_UINT, 0,
1485       GST_QUARK (MAX_BUFFERS), G_TYPE_UINT, 0,
1486       GST_QUARK (PREFIX), G_TYPE_UINT, 0,
1487       GST_QUARK (PADDING), G_TYPE_UINT, 0,
1488       GST_QUARK (ALIGN), G_TYPE_UINT, 0,
1489       GST_QUARK (POOL), GST_TYPE_BUFFER_POOL, NULL, NULL);
1490
1491   query = gst_query_new_custom (GST_QUERY_ALLOCATION, structure);
1492
1493   return query;
1494 }
1495
1496 /**
1497  * gst_query_parse_allocation:
1498  * @query: a #GstQuery
1499  * @caps: (out callee-allocates) (allow-none): The #GstCaps
1500  * @need_pool: (out) (allow-none): Whether a #GstBufferPool is needed
1501  *
1502  * Parse an allocation query, writing the requested caps in @caps and
1503  * whether a pool is needed in @need_pool, if the respective parameters
1504  * are non-NULL.
1505  */
1506 void
1507 gst_query_parse_allocation (GstQuery * query, GstCaps ** caps,
1508     gboolean * need_pool)
1509 {
1510   GstStructure *structure;
1511
1512   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
1513
1514   structure = GST_QUERY_STRUCTURE (query);
1515   gst_structure_id_get (structure,
1516       GST_QUARK (CAPS), GST_TYPE_CAPS, caps,
1517       GST_QUARK (NEED_POOL), G_TYPE_BOOLEAN, need_pool, NULL);
1518 }
1519
1520 /**
1521  * gst_query_set_allocation_params:
1522  * @query: A valid #GstQuery of type GST_QUERY_ALLOCATION.
1523  * @size: the size
1524  * @min_buffers: the min buffers
1525  * @max_buffers: the max buffers
1526  * @prefix: the prefix
1527  * @padding: the padding
1528  * @alignment: the alignment
1529  * @pool: the #GstBufferPool
1530  *
1531  * Set the allocation parameters in @query.
1532  */
1533 void
1534 gst_query_set_allocation_params (GstQuery * query, guint size,
1535     guint min_buffers, guint max_buffers, guint prefix, guint padding,
1536     guint alignment, GstBufferPool * pool)
1537 {
1538   GstStructure *structure;
1539
1540   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
1541   g_return_if_fail (gst_query_is_writable (query));
1542   g_return_if_fail (((alignment + 1) & alignment) == 0);
1543   g_return_if_fail (size != 0 || pool == NULL);
1544
1545   structure = GST_QUERY_STRUCTURE (query);
1546   gst_structure_id_set (structure,
1547       GST_QUARK (SIZE), G_TYPE_UINT, size,
1548       GST_QUARK (MIN_BUFFERS), G_TYPE_UINT, min_buffers,
1549       GST_QUARK (MAX_BUFFERS), G_TYPE_UINT, max_buffers,
1550       GST_QUARK (PREFIX), G_TYPE_UINT, prefix,
1551       GST_QUARK (PADDING), G_TYPE_UINT, padding,
1552       GST_QUARK (ALIGN), G_TYPE_UINT, alignment,
1553       GST_QUARK (POOL), GST_TYPE_BUFFER_POOL, pool, NULL);
1554 }
1555
1556 /**
1557  * gst_query_parse_allocation_params:
1558  * @query: A valid #GstQuery of type GST_QUERY_ALLOCATION.
1559  * @size: (out) (allow-none): the size
1560  * @min_buffers: (out) (allow-none): the min buffers
1561  * @max_buffers: (out) (allow-none): the max buffers
1562  * @prefix: (out) (allow-none): the prefix
1563  * @padding: (out) (allow-none): the padding
1564  * @alignment: (out) (allow-none): the alignment
1565  * @pool: (out) (allow-none) (transfer full): the #GstBufferPool
1566  *
1567  * Get the allocation parameters in @query.
1568  */
1569 void
1570 gst_query_parse_allocation_params (GstQuery * query, guint * size,
1571     guint * min_buffers, guint * max_buffers, guint * prefix,
1572     guint * padding, guint * alignment, GstBufferPool ** pool)
1573 {
1574   GstStructure *structure;
1575
1576   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
1577
1578   structure = GST_QUERY_STRUCTURE (query);
1579   gst_structure_id_get (structure,
1580       GST_QUARK (SIZE), G_TYPE_UINT, size,
1581       GST_QUARK (MIN_BUFFERS), G_TYPE_UINT, min_buffers,
1582       GST_QUARK (MAX_BUFFERS), G_TYPE_UINT, max_buffers,
1583       GST_QUARK (PREFIX), G_TYPE_UINT, prefix,
1584       GST_QUARK (PADDING), G_TYPE_UINT, padding,
1585       GST_QUARK (ALIGN), G_TYPE_UINT, alignment,
1586       GST_QUARK (POOL), GST_TYPE_BUFFER_POOL, pool, NULL);
1587 }
1588
1589 /**
1590  * gst_query_add_allocation_meta:
1591  * @query: a GST_QUERY_ALLOCATION type query #GstQuery
1592  * @api: the metadata API
1593  *
1594  * Add @api as aone of the supported metadata API to @query.
1595  */
1596 void
1597 gst_query_add_allocation_meta (GstQuery * query, GType api)
1598 {
1599   GArray *array;
1600   GstStructure *structure;
1601
1602   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
1603   g_return_if_fail (api != 0);
1604   g_return_if_fail (gst_query_is_writable (query));
1605
1606   structure = GST_QUERY_STRUCTURE (query);
1607   array = ensure_array (structure, GST_QUARK (META), sizeof (GType), NULL);
1608
1609   g_array_append_val (array, api);
1610 }
1611
1612 /**
1613  * gst_query_get_n_allocation_metas:
1614  * @query: a GST_QUERY_ALLOCATION type query #GstQuery
1615  *
1616  * Retrieve the number of values currently stored in the
1617  * meta API array of the query's structure.
1618  *
1619  * Returns: the metadata API array size as a #guint.
1620  */
1621 guint
1622 gst_query_get_n_allocation_metas (GstQuery * query)
1623 {
1624   GArray *array;
1625   GstStructure *structure;
1626
1627   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, 0);
1628
1629   structure = GST_QUERY_STRUCTURE (query);
1630   array = ensure_array (structure, GST_QUARK (META), sizeof (GType), NULL);
1631
1632   return array->len;
1633 }
1634
1635 /**
1636  * gst_query_parse_nth_allocation_meta:
1637  * @query: a GST_QUERY_ALLOCATION type query #GstQuery
1638  * @index: position in the metadata API array to read
1639  *
1640  * Parse an available query and get the metadata API
1641  * at @index of the metadata API array.
1642  *
1643  * Returns: a #GType of the metadata API at @index.
1644  */
1645 GType
1646 gst_query_parse_nth_allocation_meta (GstQuery * query, guint index)
1647 {
1648   GArray *array;
1649   GstStructure *structure;
1650
1651   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, 0);
1652
1653   structure = GST_QUERY_STRUCTURE (query);
1654   array = ensure_array (structure, GST_QUARK (META), sizeof (GType), NULL);
1655
1656   g_return_val_if_fail (index < array->len, 0);
1657
1658   return g_array_index (array, GType, index);
1659 }
1660
1661 /**
1662  * gst_query_remove_nth_allocation_meta:
1663  * @query: a GST_QUERY_ALLOCATION type query #GstQuery
1664  * @index: position in the metadata API array to remove
1665  *
1666  * Remove the metadata API at @index of the metadata API array.
1667  */
1668 void
1669 gst_query_remove_nth_allocation_meta (GstQuery * query, guint index)
1670 {
1671   GArray *array;
1672   GstStructure *structure;
1673
1674   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
1675   g_return_if_fail (gst_query_is_writable (query));
1676
1677   structure = GST_QUERY_STRUCTURE (query);
1678   array = ensure_array (structure, GST_QUARK (META), sizeof (GType), NULL);
1679   g_return_if_fail (index < array->len);
1680
1681   g_array_remove_index (array, index);
1682 }
1683
1684 /**
1685  * gst_query_has_allocation_meta:
1686  * @query: a GST_QUERY_ALLOCATION type query #GstQuery
1687  * @api: the metadata API
1688  *
1689  * Check if @query has metadata @api set.
1690  *
1691  * Returns: TRUE when @api is in the list of metadata.
1692  */
1693 gboolean
1694 gst_query_has_allocation_meta (GstQuery * query, GType api)
1695 {
1696   GArray *array;
1697   GstStructure *structure;
1698   guint i, len;
1699
1700   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, FALSE);
1701   g_return_val_if_fail (api != 0, FALSE);
1702
1703   structure = GST_QUERY_STRUCTURE (query);
1704   array = ensure_array (structure, GST_QUARK (META), sizeof (GType), NULL);
1705
1706   len = array->len;
1707   for (i = 0; i < len; i++) {
1708     if (g_array_index (array, GType, i) == api)
1709       return TRUE;
1710   }
1711   return FALSE;
1712 }
1713
1714 /**
1715  * gst_query_add_allocation_memory:
1716  * @query: a GST_QUERY_ALLOCATION type query #GstQuery
1717  * @allocator: the memory allocator
1718  *
1719  * Add @allocator as a supported memory allocator.
1720  */
1721 void
1722 gst_query_add_allocation_memory (GstQuery * query, GstAllocator * allocator)
1723 {
1724   GArray *array;
1725   GstStructure *structure;
1726
1727   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
1728   g_return_if_fail (gst_query_is_writable (query));
1729   g_return_if_fail (allocator != NULL);
1730
1731   structure = GST_QUERY_STRUCTURE (query);
1732   array =
1733       ensure_array (structure, GST_QUARK (ALLOCATOR), sizeof (GstAllocator *),
1734       (GDestroyNotify) gst_allocator_unref);
1735
1736   g_array_append_val (array, allocator);
1737 }
1738
1739 /**
1740  * gst_query_get_n_allocation_memories:
1741  * @query: a GST_QUERY_ALLOCATION type query #GstQuery
1742  *
1743  * Retrieve the number of values currently stored in the
1744  * allocator array of the query's structure.
1745  *
1746  * If no memory allocator is specified, the downstream element can handle
1747  * the default memory allocator.
1748  *
1749  * Returns: the allocator array size as a #guint.
1750  */
1751 guint
1752 gst_query_get_n_allocation_memories (GstQuery * query)
1753 {
1754   GArray *array;
1755   GstStructure *structure;
1756
1757   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, 0);
1758
1759   structure = GST_QUERY_STRUCTURE (query);
1760   array =
1761       ensure_array (structure, GST_QUARK (ALLOCATOR), sizeof (GstAllocator *),
1762       (GDestroyNotify) gst_allocator_unref);
1763
1764   return array->len;
1765 }
1766
1767 /**
1768  * gst_query_parse_nth_allocation_memory:
1769  * @query: a GST_QUERY_ALLOCATION type query #GstQuery
1770  * @index: position in the allocator array to read
1771  *
1772  * Parse an available query and get the alloctor
1773  * at @index of the allocator array.
1774  *
1775  * Returns: (transfer none): the allocator at @index. The allocator remains
1776  * valid for as long as @query is valid.
1777  */
1778 GstAllocator *
1779 gst_query_parse_nth_allocation_memory (GstQuery * query, guint index)
1780 {
1781   GArray *array;
1782   GstStructure *structure;
1783
1784   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, NULL);
1785
1786   structure = GST_QUERY_STRUCTURE (query);
1787   array =
1788       ensure_array (structure, GST_QUARK (ALLOCATOR), sizeof (GstAllocator *),
1789       (GDestroyNotify) gst_allocator_unref);
1790   g_return_val_if_fail (index < array->len, NULL);
1791
1792   return g_array_index (array, GstAllocator *, index);
1793 }
1794
1795 /**
1796  * gst_query_new_scheduling:
1797  *
1798  * Constructs a new query object for querying the scheduling properties.
1799  *
1800  * Free-function: gst_query_unref
1801  *
1802  * Returns: (transfer full): a new #GstQuery
1803  */
1804 GstQuery *
1805 gst_query_new_scheduling (void)
1806 {
1807   GstQuery *query;
1808   GstStructure *structure;
1809
1810   structure = gst_structure_new_id (GST_QUARK (QUERY_SCHEDULING),
1811       GST_QUARK (FLAGS), GST_TYPE_SCHEDULING_FLAGS, 0,
1812       GST_QUARK (MINSIZE), G_TYPE_INT, 1,
1813       GST_QUARK (MAXSIZE), G_TYPE_INT, -1,
1814       GST_QUARK (ALIGN), G_TYPE_INT, 0, NULL);
1815   query = gst_query_new_custom (GST_QUERY_SCHEDULING, structure);
1816
1817   return query;
1818 }
1819
1820 /**
1821  * gst_query_set_scheduling:
1822  * @query: A valid #GstQuery of type GST_QUERY_SCHEDULING.
1823  * @flags: #GstSchedulingFlags
1824  * @minsize: the suggested minimum size of pull requests
1825  * @maxsize: the suggested maximum size of pull requests
1826  * @align: the suggested alignment of pull requests
1827  *
1828  * Set the scheduling properties.
1829  */
1830 void
1831 gst_query_set_scheduling (GstQuery * query, GstSchedulingFlags flags,
1832     gint minsize, gint maxsize, gint align)
1833 {
1834   GstStructure *structure;
1835
1836   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SCHEDULING);
1837   g_return_if_fail (gst_query_is_writable (query));
1838
1839   structure = GST_QUERY_STRUCTURE (query);
1840   gst_structure_id_set (structure,
1841       GST_QUARK (FLAGS), GST_TYPE_SCHEDULING_FLAGS, flags,
1842       GST_QUARK (MINSIZE), G_TYPE_INT, minsize,
1843       GST_QUARK (MAXSIZE), G_TYPE_INT, maxsize,
1844       GST_QUARK (ALIGN), G_TYPE_INT, align, NULL);
1845 }
1846
1847 /**
1848  * gst_query_parse_scheduling:
1849  * @query: A valid #GstQuery of type GST_QUERY_SCHEDULING.
1850  * @flags: (out) (allow-none): #GstSchedulingFlags
1851  * @minsize: (out) (allow-none): the suggested minimum size of pull requests
1852  * @maxsize: (out) (allow-none): the suggested maximum size of pull requests:
1853  * @align: (out) (allow-none): the suggested alignment of pull requests
1854  *
1855  * Set the scheduling properties.
1856  */
1857 void
1858 gst_query_parse_scheduling (GstQuery * query, GstSchedulingFlags * flags,
1859     gint * minsize, gint * maxsize, gint * align)
1860 {
1861   GstStructure *structure;
1862
1863   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SCHEDULING);
1864
1865   structure = GST_QUERY_STRUCTURE (query);
1866   gst_structure_id_get (structure,
1867       GST_QUARK (FLAGS), GST_TYPE_SCHEDULING_FLAGS, flags,
1868       GST_QUARK (MINSIZE), G_TYPE_INT, minsize,
1869       GST_QUARK (MAXSIZE), G_TYPE_INT, maxsize,
1870       GST_QUARK (ALIGN), G_TYPE_INT, align, NULL);
1871 }
1872
1873 /**
1874  * gst_query_add_scheduling_mode:
1875  * @query: a GST_QUERY_SCHEDULING type query #GstQuery
1876  * @mode: a #GstPadMode
1877  *
1878  * Add @mode as aone of the supported scheduling modes to @query.
1879  */
1880 void
1881 gst_query_add_scheduling_mode (GstQuery * query, GstPadMode mode)
1882 {
1883   GstStructure *structure;
1884   GArray *array;
1885
1886   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SCHEDULING);
1887   g_return_if_fail (gst_query_is_writable (query));
1888
1889   structure = GST_QUERY_STRUCTURE (query);
1890   array =
1891       ensure_array (structure, GST_QUARK (MODES), sizeof (GstPadMode), NULL);
1892
1893   g_array_append_val (array, mode);
1894 }
1895
1896 /**
1897  * gst_query_get_n_scheduling_modes:
1898  * @query: a GST_QUERY_SCHEDULING type query #GstQuery
1899  *
1900  * Retrieve the number of values currently stored in the
1901  * scheduling mode array of the query's structure.
1902  *
1903  * Returns: the scheduling mode array size as a #guint.
1904  */
1905 guint
1906 gst_query_get_n_scheduling_modes (GstQuery * query)
1907 {
1908   GArray *array;
1909   GstStructure *structure;
1910
1911   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SCHEDULING, 0);
1912
1913   structure = GST_QUERY_STRUCTURE (query);
1914   array =
1915       ensure_array (structure, GST_QUARK (MODES), sizeof (GstPadMode), NULL);
1916
1917   return array->len;
1918 }
1919
1920 /**
1921  * gst_query_parse_nth_scheduling_mode:
1922  * @query: a GST_QUERY_SCHEDULING type query #GstQuery
1923  * @index: position in the scheduling modes array to read
1924  *
1925  * Parse an available query and get the scheduling mode
1926  * at @index of the scheduling modes array.
1927  *
1928  * Returns: a #GstPadMode of the scheduling mode at @index.
1929  */
1930 GstPadMode
1931 gst_query_parse_nth_scheduling_mode (GstQuery * query, guint index)
1932 {
1933   GstStructure *structure;
1934   GArray *array;
1935
1936   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SCHEDULING,
1937       GST_PAD_MODE_NONE);
1938
1939   structure = GST_QUERY_STRUCTURE (query);
1940   array =
1941       ensure_array (structure, GST_QUARK (MODES), sizeof (GstPadMode), NULL);
1942   g_return_val_if_fail (index < array->len, GST_PAD_MODE_NONE);
1943
1944   return g_array_index (array, GstPadMode, index);
1945 }
1946
1947 /**
1948  * gst_query_has_scheduling_mode:
1949  * @query: a GST_QUERY_SCHEDULING type query #GstQuery
1950  * @mode: the scheduling mode
1951  *
1952  * Check if @query has scheduling mode set.
1953  *
1954  * Returns: TRUE when @mode is in the list of scheduling modes.
1955  */
1956 gboolean
1957 gst_query_has_scheduling_mode (GstQuery * query, GstPadMode mode)
1958 {
1959   GstStructure *structure;
1960   GArray *array;
1961   guint i, len;
1962
1963   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SCHEDULING, FALSE);
1964
1965   structure = GST_QUERY_STRUCTURE (query);
1966   array =
1967       ensure_array (structure, GST_QUARK (MODES), sizeof (GstPadMode), NULL);
1968
1969   len = array->len;
1970   for (i = 0; i < len; i++) {
1971     if (mode == g_array_index (array, GstPadMode, i))
1972       return TRUE;
1973   }
1974   return FALSE;
1975 }
1976
1977 /**
1978  * gst_query_new_accept_caps:
1979  * @caps: a #GstCaps
1980  *
1981  * Constructs a new query object for querying if @caps are accepted.
1982  *
1983  * Free-function: gst_query_unref
1984  *
1985  * Returns: (transfer full): a new #GstQuery
1986  */
1987 GstQuery *
1988 gst_query_new_accept_caps (GstCaps * caps)
1989 {
1990   GstQuery *query;
1991   GstStructure *structure;
1992
1993   structure = gst_structure_new_id (GST_QUARK (QUERY_ACCEPT_CAPS),
1994       GST_QUARK (CAPS), GST_TYPE_CAPS, caps,
1995       GST_QUARK (RESULT), G_TYPE_BOOLEAN, FALSE, NULL);
1996   query = gst_query_new_custom (GST_QUERY_ACCEPT_CAPS, structure);
1997
1998   return query;
1999 }
2000
2001 /**
2002  * gst_query_parse_accept_caps:
2003  * @query: The query to parse
2004  * @caps: (out): A pointer to the caps
2005  *
2006  * Get the caps from @query. The caps remains valid as long as @query remains
2007  * valid.
2008  */
2009 void
2010 gst_query_parse_accept_caps (GstQuery * query, GstCaps ** caps)
2011 {
2012   GstStructure *structure;
2013
2014   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ACCEPT_CAPS);
2015   g_return_if_fail (caps != NULL);
2016
2017   structure = GST_QUERY_STRUCTURE (query);
2018   *caps = g_value_get_boxed (gst_structure_id_get_value (structure,
2019           GST_QUARK (CAPS)));
2020 }
2021
2022 void
2023 gst_query_set_accept_caps_result (GstQuery * query, gboolean result)
2024 {
2025   GstStructure *structure;
2026
2027   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ACCEPT_CAPS);
2028   g_return_if_fail (gst_query_is_writable (query));
2029
2030   structure = GST_QUERY_STRUCTURE (query);
2031   gst_structure_id_set (structure,
2032       GST_QUARK (RESULT), G_TYPE_BOOLEAN, result, NULL);
2033 }
2034
2035 void
2036 gst_query_parse_accept_caps_result (GstQuery * query, gboolean * result)
2037 {
2038   GstStructure *structure;
2039
2040   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ACCEPT_CAPS);
2041
2042   structure = GST_QUERY_STRUCTURE (query);
2043   gst_structure_id_get (structure,
2044       GST_QUARK (RESULT), G_TYPE_BOOLEAN, result, NULL);
2045 }
2046
2047 /**
2048  * gst_query_new_caps:
2049  * @filter: a filter
2050  *
2051  * Constructs a new query object for querying the caps.
2052  *
2053  * The CAPS query should return the* allowable caps for a pad in the context
2054  * of the element's state, its link to other elements, and the devices or files
2055  * it has opened. These caps must be a subset of the pad template caps. In the
2056  * NULL state with no links, the CAPS query should ideally return the same caps
2057  * as the pad template. In rare circumstances, an object property can affect
2058  * the caps returned by the CAPS query, but this is discouraged.
2059  *
2060  * For most filters, the caps returned by CAPS query is directly affected by the
2061  * allowed caps on other pads. For demuxers and decoders, the caps returned by
2062  * the srcpad's getcaps function is directly related to the stream data. Again,
2063  * the CAPS query should return the most specific caps it reasonably can, since this
2064  * helps with autoplugging.
2065  *
2066  * Free-function: gst_query_unref
2067  *
2068  * Returns: (transfer full): a new #GstQuery
2069  */
2070 GstQuery *
2071 gst_query_new_caps (GstCaps * filter)
2072 {
2073   GstQuery *query;
2074   GstStructure *structure;
2075
2076   structure = gst_structure_new_id (GST_QUARK (QUERY_CAPS),
2077       GST_QUARK (FILTER), GST_TYPE_CAPS, filter,
2078       GST_QUARK (CAPS), GST_TYPE_CAPS, NULL, NULL);
2079   query = gst_query_new_custom (GST_QUERY_CAPS, structure);
2080
2081   return query;
2082 }
2083
2084 /**
2085  * gst_query_parse_caps:
2086  * @query: The query to parse
2087  * @filter: (out): A pointer to the caps filter
2088  *
2089  * Get the filter from the caps @query. The caps remains valid as long as
2090  * @query remains valid.
2091  */
2092 void
2093 gst_query_parse_caps (GstQuery * query, GstCaps ** filter)
2094 {
2095   GstStructure *structure;
2096
2097   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CAPS);
2098   g_return_if_fail (filter != NULL);
2099
2100   structure = GST_QUERY_STRUCTURE (query);
2101   *filter = g_value_get_boxed (gst_structure_id_get_value (structure,
2102           GST_QUARK (FILTER)));
2103 }
2104
2105 /**
2106  * gst_query_set_caps_result:
2107  * @query: The query to use
2108  * @caps: (in): A pointer to the caps
2109  *
2110  * Set the @caps result in @query.
2111  */
2112 void
2113 gst_query_set_caps_result (GstQuery * query, GstCaps * caps)
2114 {
2115   GstStructure *structure;
2116
2117   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CAPS);
2118   g_return_if_fail (gst_query_is_writable (query));
2119
2120   structure = GST_QUERY_STRUCTURE (query);
2121   gst_structure_id_set (structure, GST_QUARK (CAPS), GST_TYPE_CAPS, caps, NULL);
2122 }
2123
2124 /**
2125  * gst_query_parse_caps_result:
2126  * @query: The query to parse
2127  * @caps: (out): A pointer to the caps
2128  *
2129  * Get the caps result from @query. The caps remains valid as long as
2130  * @query remains valid.
2131  */
2132 void
2133 gst_query_parse_caps_result (GstQuery * query, GstCaps ** caps)
2134 {
2135   GstStructure *structure;
2136
2137   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CAPS);
2138   g_return_if_fail (caps != NULL);
2139
2140   structure = GST_QUERY_STRUCTURE (query);
2141   *caps = g_value_get_boxed (gst_structure_id_get_value (structure,
2142           GST_QUARK (CAPS)));
2143 }
2144
2145 void
2146 gst_query_intersect_caps_result (GstQuery * query, GstCaps * filter,
2147     GstCapsIntersectMode mode)
2148 {
2149   GstCaps *res, *caps = NULL;
2150
2151   gst_query_parse_caps_result (query, &caps);
2152   res = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
2153   gst_query_set_caps_result (query, res);
2154   gst_caps_unref (res);
2155 }
2156
2157 /**
2158  * gst_query_new_drain:
2159  *
2160  * Constructs a new query object for querying the drain state.
2161  *
2162  * Free-function: gst_query_unref
2163  *
2164  * Returns: (transfer full): a new #GstQuery
2165  */
2166 GstQuery *
2167 gst_query_new_drain (void)
2168 {
2169   GstQuery *query;
2170   GstStructure *structure;
2171
2172   structure = gst_structure_new_id_empty (GST_QUARK (QUERY_DRAIN));
2173   query = gst_query_new_custom (GST_QUERY_DRAIN, structure);
2174
2175   return query;
2176 }