query: add new drain 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 (ALIGN), G_TYPE_UINT, 0,
1488       GST_QUARK (POOL), GST_TYPE_BUFFER_POOL, NULL, NULL);
1489
1490   query = gst_query_new_custom (GST_QUERY_ALLOCATION, structure);
1491
1492   return query;
1493 }
1494
1495 /**
1496  * gst_query_parse_allocation:
1497  * @query: a #GstQuery
1498  * @caps: (out callee-allocates) (allow-none): The #GstCaps
1499  * @need_pool: (out) (allow-none): Whether a #GstBufferPool is needed
1500  *
1501  * Parse an allocation query, writing the requested caps in @caps and
1502  * whether a pool is needed in @need_pool, if the respective parameters
1503  * are non-NULL.
1504  */
1505 void
1506 gst_query_parse_allocation (GstQuery * query, GstCaps ** caps,
1507     gboolean * need_pool)
1508 {
1509   GstStructure *structure;
1510
1511   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
1512
1513   structure = GST_QUERY_STRUCTURE (query);
1514   gst_structure_id_get (structure,
1515       GST_QUARK (CAPS), GST_TYPE_CAPS, caps,
1516       GST_QUARK (NEED_POOL), G_TYPE_BOOLEAN, need_pool, NULL);
1517 }
1518
1519 /**
1520  * gst_query_set_allocation_params:
1521  * @query: A valid #GstQuery of type GST_QUERY_ALLOCATION.
1522  * @size: the size
1523  * @min_buffers: the min buffers
1524  * @max_buffers: the max buffers
1525  * @prefix: the prefix
1526  * @alignment: the alignment
1527  * @pool: the #GstBufferPool
1528  *
1529  * Set the allocation parameters in @query.
1530  */
1531 void
1532 gst_query_set_allocation_params (GstQuery * query, guint size,
1533     guint min_buffers, guint max_buffers, guint prefix,
1534     guint alignment, GstBufferPool * pool)
1535 {
1536   GstStructure *structure;
1537
1538   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
1539   g_return_if_fail (gst_query_is_writable (query));
1540   g_return_if_fail (((alignment + 1) & alignment) == 0);
1541   g_return_if_fail (size != 0 || pool == NULL);
1542
1543   structure = GST_QUERY_STRUCTURE (query);
1544   gst_structure_id_set (structure,
1545       GST_QUARK (SIZE), G_TYPE_UINT, size,
1546       GST_QUARK (MIN_BUFFERS), G_TYPE_UINT, min_buffers,
1547       GST_QUARK (MAX_BUFFERS), G_TYPE_UINT, max_buffers,
1548       GST_QUARK (PREFIX), G_TYPE_UINT, prefix,
1549       GST_QUARK (ALIGN), G_TYPE_UINT, alignment,
1550       GST_QUARK (POOL), GST_TYPE_BUFFER_POOL, pool, NULL);
1551 }
1552
1553 /**
1554  * gst_query_parse_allocation_params:
1555  * @query: A valid #GstQuery of type GST_QUERY_ALLOCATION.
1556  * @size: (out) (allow-none): the size
1557  * @min_buffers: (out) (allow-none): the min buffers
1558  * @max_buffers: (out) (allow-none): the max buffers
1559  * @prefix: (out) (allow-none): the prefix
1560  * @alignment: (out) (allow-none): the alignment
1561  * @pool: (out) (allow-none) (transfer full): the #GstBufferPool
1562  *
1563  * Get the allocation parameters in @query.
1564  */
1565 void
1566 gst_query_parse_allocation_params (GstQuery * query, guint * size,
1567     guint * min_buffers, guint * max_buffers, guint * prefix,
1568     guint * alignment, GstBufferPool ** pool)
1569 {
1570   GstStructure *structure;
1571
1572   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
1573
1574   structure = GST_QUERY_STRUCTURE (query);
1575   gst_structure_id_get (structure,
1576       GST_QUARK (SIZE), G_TYPE_UINT, size,
1577       GST_QUARK (MIN_BUFFERS), G_TYPE_UINT, min_buffers,
1578       GST_QUARK (MAX_BUFFERS), G_TYPE_UINT, max_buffers,
1579       GST_QUARK (PREFIX), G_TYPE_UINT, prefix,
1580       GST_QUARK (ALIGN), G_TYPE_UINT, alignment,
1581       GST_QUARK (POOL), GST_TYPE_BUFFER_POOL, pool, NULL);
1582 }
1583
1584 /**
1585  * gst_query_add_allocation_meta:
1586  * @query: a GST_QUERY_ALLOCATION type query #GstQuery
1587  * @api: the metadata API
1588  *
1589  * Add @api as aone of the supported metadata API to @query.
1590  */
1591 void
1592 gst_query_add_allocation_meta (GstQuery * query, GType api)
1593 {
1594   GArray *array;
1595   GstStructure *structure;
1596
1597   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
1598   g_return_if_fail (api != 0);
1599   g_return_if_fail (gst_query_is_writable (query));
1600
1601   structure = GST_QUERY_STRUCTURE (query);
1602   array = ensure_array (structure, GST_QUARK (META), sizeof (GType), NULL);
1603
1604   g_array_append_val (array, api);
1605 }
1606
1607 /**
1608  * gst_query_get_n_allocation_metas:
1609  * @query: a GST_QUERY_ALLOCATION type query #GstQuery
1610  *
1611  * Retrieve the number of values currently stored in the
1612  * meta API array of the query's structure.
1613  *
1614  * Returns: the metadata API array size as a #guint.
1615  */
1616 guint
1617 gst_query_get_n_allocation_metas (GstQuery * query)
1618 {
1619   GArray *array;
1620   GstStructure *structure;
1621
1622   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, 0);
1623
1624   structure = GST_QUERY_STRUCTURE (query);
1625   array = ensure_array (structure, GST_QUARK (META), sizeof (GType), NULL);
1626
1627   return array->len;
1628 }
1629
1630 /**
1631  * gst_query_parse_nth_allocation_meta:
1632  * @query: a GST_QUERY_ALLOCATION type query #GstQuery
1633  * @index: position in the metadata API array to read
1634  *
1635  * Parse an available query and get the metadata API
1636  * at @index of the metadata API array.
1637  *
1638  * Returns: a #GType of the metadata API at @index.
1639  */
1640 GType
1641 gst_query_parse_nth_allocation_meta (GstQuery * query, guint index)
1642 {
1643   GArray *array;
1644   GstStructure *structure;
1645
1646   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, 0);
1647
1648   structure = GST_QUERY_STRUCTURE (query);
1649   array = ensure_array (structure, GST_QUARK (META), sizeof (GType), NULL);
1650
1651   g_return_val_if_fail (index < array->len, 0);
1652
1653   return g_array_index (array, GType, index);
1654 }
1655
1656 /**
1657  * gst_query_remove_nth_allocation_meta:
1658  * @query: a GST_QUERY_ALLOCATION type query #GstQuery
1659  * @index: position in the metadata API array to remove
1660  *
1661  * Remove the metadata API at @index of the metadata API array.
1662  */
1663 void
1664 gst_query_remove_nth_allocation_meta (GstQuery * query, guint index)
1665 {
1666   GArray *array;
1667   GstStructure *structure;
1668
1669   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
1670   g_return_if_fail (gst_query_is_writable (query));
1671
1672   structure = GST_QUERY_STRUCTURE (query);
1673   array = ensure_array (structure, GST_QUARK (META), sizeof (GType), NULL);
1674   g_return_if_fail (index < array->len);
1675
1676   g_array_remove_index (array, index);
1677 }
1678
1679 /**
1680  * gst_query_has_allocation_meta:
1681  * @query: a GST_QUERY_ALLOCATION type query #GstQuery
1682  * @api: the metadata API
1683  *
1684  * Check if @query has metadata @api set.
1685  *
1686  * Returns: TRUE when @api is in the list of metadata.
1687  */
1688 gboolean
1689 gst_query_has_allocation_meta (GstQuery * query, GType api)
1690 {
1691   GArray *array;
1692   GstStructure *structure;
1693   guint i, len;
1694
1695   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, FALSE);
1696   g_return_val_if_fail (api != 0, FALSE);
1697
1698   structure = GST_QUERY_STRUCTURE (query);
1699   array = ensure_array (structure, GST_QUARK (META), sizeof (GType), NULL);
1700
1701   len = array->len;
1702   for (i = 0; i < len; i++) {
1703     if (g_array_index (array, GType, i) == api)
1704       return TRUE;
1705   }
1706   return FALSE;
1707 }
1708
1709 /**
1710  * gst_query_add_allocation_memory:
1711  * @query: a GST_QUERY_ALLOCATION type query #GstQuery
1712  * @allocator: the memory allocator
1713  *
1714  * Add @allocator as a supported memory allocator.
1715  */
1716 void
1717 gst_query_add_allocation_memory (GstQuery * query, GstAllocator * allocator)
1718 {
1719   GArray *array;
1720   GstStructure *structure;
1721
1722   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
1723   g_return_if_fail (gst_query_is_writable (query));
1724   g_return_if_fail (allocator != NULL);
1725
1726   structure = GST_QUERY_STRUCTURE (query);
1727   array =
1728       ensure_array (structure, GST_QUARK (ALLOCATOR), sizeof (GstAllocator *),
1729       (GDestroyNotify) gst_allocator_unref);
1730
1731   g_array_append_val (array, allocator);
1732 }
1733
1734 /**
1735  * gst_query_get_n_allocation_memories:
1736  * @query: a GST_QUERY_ALLOCATION type query #GstQuery
1737  *
1738  * Retrieve the number of values currently stored in the
1739  * allocator array of the query's structure.
1740  *
1741  * If no memory allocator is specified, the downstream element can handle
1742  * the default memory allocator.
1743  *
1744  * Returns: the allocator array size as a #guint.
1745  */
1746 guint
1747 gst_query_get_n_allocation_memories (GstQuery * query)
1748 {
1749   GArray *array;
1750   GstStructure *structure;
1751
1752   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, 0);
1753
1754   structure = GST_QUERY_STRUCTURE (query);
1755   array =
1756       ensure_array (structure, GST_QUARK (ALLOCATOR), sizeof (GstAllocator *),
1757       (GDestroyNotify) gst_allocator_unref);
1758
1759   return array->len;
1760 }
1761
1762 /**
1763  * gst_query_parse_nth_allocation_memory:
1764  * @query: a GST_QUERY_ALLOCATION type query #GstQuery
1765  * @index: position in the allocator array to read
1766  *
1767  * Parse an available query and get the alloctor
1768  * at @index of the allocator array.
1769  *
1770  * Returns: (transfer none): the allocator at @index. The allocator remains
1771  * valid for as long as @query is valid.
1772  */
1773 GstAllocator *
1774 gst_query_parse_nth_allocation_memory (GstQuery * query, guint index)
1775 {
1776   GArray *array;
1777   GstStructure *structure;
1778
1779   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, NULL);
1780
1781   structure = GST_QUERY_STRUCTURE (query);
1782   array =
1783       ensure_array (structure, GST_QUARK (ALLOCATOR), sizeof (GstAllocator *),
1784       (GDestroyNotify) gst_allocator_unref);
1785   g_return_val_if_fail (index < array->len, NULL);
1786
1787   return g_array_index (array, GstAllocator *, index);
1788 }
1789
1790 /**
1791  * gst_query_new_scheduling:
1792  *
1793  * Constructs a new query object for querying the scheduling properties.
1794  *
1795  * Free-function: gst_query_unref
1796  *
1797  * Returns: (transfer full): a new #GstQuery
1798  */
1799 GstQuery *
1800 gst_query_new_scheduling (void)
1801 {
1802   GstQuery *query;
1803   GstStructure *structure;
1804
1805   structure = gst_structure_new_id (GST_QUARK (QUERY_SCHEDULING),
1806       GST_QUARK (FLAGS), GST_TYPE_SCHEDULING_FLAGS, 0,
1807       GST_QUARK (MINSIZE), G_TYPE_INT, 1,
1808       GST_QUARK (MAXSIZE), G_TYPE_INT, -1,
1809       GST_QUARK (ALIGN), G_TYPE_INT, 0, NULL);
1810   query = gst_query_new_custom (GST_QUERY_SCHEDULING, structure);
1811
1812   return query;
1813 }
1814
1815 /**
1816  * gst_query_set_scheduling:
1817  * @query: A valid #GstQuery of type GST_QUERY_SCHEDULING.
1818  * @flags: #GstSchedulingFlags
1819  * @minsize: the suggested minimum size of pull requests
1820  * @maxsize: the suggested maximum size of pull requests
1821  * @align: the suggested alignment of pull requests
1822  *
1823  * Set the scheduling properties.
1824  */
1825 void
1826 gst_query_set_scheduling (GstQuery * query, GstSchedulingFlags flags,
1827     gint minsize, gint maxsize, gint align)
1828 {
1829   GstStructure *structure;
1830
1831   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SCHEDULING);
1832   g_return_if_fail (gst_query_is_writable (query));
1833
1834   structure = GST_QUERY_STRUCTURE (query);
1835   gst_structure_id_set (structure,
1836       GST_QUARK (FLAGS), GST_TYPE_SCHEDULING_FLAGS, flags,
1837       GST_QUARK (MINSIZE), G_TYPE_INT, minsize,
1838       GST_QUARK (MAXSIZE), G_TYPE_INT, maxsize,
1839       GST_QUARK (ALIGN), G_TYPE_INT, align, NULL);
1840 }
1841
1842 /**
1843  * gst_query_parse_scheduling:
1844  * @query: A valid #GstQuery of type GST_QUERY_SCHEDULING.
1845  * @flags: (out) (allow-none): #GstSchedulingFlags
1846  * @minsize: (out) (allow-none): the suggested minimum size of pull requests
1847  * @maxsize: (out) (allow-none): the suggested maximum size of pull requests:
1848  * @align: (out) (allow-none): the suggested alignment of pull requests
1849  *
1850  * Set the scheduling properties.
1851  */
1852 void
1853 gst_query_parse_scheduling (GstQuery * query, GstSchedulingFlags * flags,
1854     gint * minsize, gint * maxsize, gint * align)
1855 {
1856   GstStructure *structure;
1857
1858   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SCHEDULING);
1859
1860   structure = GST_QUERY_STRUCTURE (query);
1861   gst_structure_id_get (structure,
1862       GST_QUARK (FLAGS), GST_TYPE_SCHEDULING_FLAGS, flags,
1863       GST_QUARK (MINSIZE), G_TYPE_INT, minsize,
1864       GST_QUARK (MAXSIZE), G_TYPE_INT, maxsize,
1865       GST_QUARK (ALIGN), G_TYPE_INT, align, NULL);
1866 }
1867
1868 /**
1869  * gst_query_add_scheduling_mode:
1870  * @query: a GST_QUERY_SCHEDULING type query #GstQuery
1871  * @mode: a #GstPadMode
1872  *
1873  * Add @mode as aone of the supported scheduling modes to @query.
1874  */
1875 void
1876 gst_query_add_scheduling_mode (GstQuery * query, GstPadMode mode)
1877 {
1878   GstStructure *structure;
1879   GArray *array;
1880
1881   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SCHEDULING);
1882   g_return_if_fail (gst_query_is_writable (query));
1883
1884   structure = GST_QUERY_STRUCTURE (query);
1885   array =
1886       ensure_array (structure, GST_QUARK (MODES), sizeof (GstPadMode), NULL);
1887
1888   g_array_append_val (array, mode);
1889 }
1890
1891 /**
1892  * gst_query_get_n_scheduling_modes:
1893  * @query: a GST_QUERY_SCHEDULING type query #GstQuery
1894  *
1895  * Retrieve the number of values currently stored in the
1896  * scheduling mode array of the query's structure.
1897  *
1898  * Returns: the scheduling mode array size as a #guint.
1899  */
1900 guint
1901 gst_query_get_n_scheduling_modes (GstQuery * query)
1902 {
1903   GArray *array;
1904   GstStructure *structure;
1905
1906   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SCHEDULING, 0);
1907
1908   structure = GST_QUERY_STRUCTURE (query);
1909   array =
1910       ensure_array (structure, GST_QUARK (MODES), sizeof (GstPadMode), NULL);
1911
1912   return array->len;
1913 }
1914
1915 /**
1916  * gst_query_parse_nth_scheduling_mode:
1917  * @query: a GST_QUERY_SCHEDULING type query #GstQuery
1918  * @index: position in the scheduling modes array to read
1919  *
1920  * Parse an available query and get the scheduling mode
1921  * at @index of the scheduling modes array.
1922  *
1923  * Returns: a #GstPadMode of the scheduling mode at @index.
1924  */
1925 GstPadMode
1926 gst_query_parse_nth_scheduling_mode (GstQuery * query, guint index)
1927 {
1928   GstStructure *structure;
1929   GArray *array;
1930
1931   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SCHEDULING,
1932       GST_PAD_MODE_NONE);
1933
1934   structure = GST_QUERY_STRUCTURE (query);
1935   array =
1936       ensure_array (structure, GST_QUARK (MODES), sizeof (GstPadMode), NULL);
1937   g_return_val_if_fail (index < array->len, GST_PAD_MODE_NONE);
1938
1939   return g_array_index (array, GstPadMode, index);
1940 }
1941
1942 /**
1943  * gst_query_has_scheduling_mode:
1944  * @query: a GST_QUERY_SCHEDULING type query #GstQuery
1945  * @mode: the scheduling mode
1946  *
1947  * Check if @query has scheduling mode set.
1948  *
1949  * Returns: TRUE when @mode is in the list of scheduling modes.
1950  */
1951 gboolean
1952 gst_query_has_scheduling_mode (GstQuery * query, GstPadMode mode)
1953 {
1954   GstStructure *structure;
1955   GArray *array;
1956   guint i, len;
1957
1958   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SCHEDULING, FALSE);
1959
1960   structure = GST_QUERY_STRUCTURE (query);
1961   array =
1962       ensure_array (structure, GST_QUARK (MODES), sizeof (GstPadMode), NULL);
1963
1964   len = array->len;
1965   for (i = 0; i < len; i++) {
1966     if (mode == g_array_index (array, GstPadMode, i))
1967       return TRUE;
1968   }
1969   return FALSE;
1970 }
1971
1972 /**
1973  * gst_query_new_accept_caps:
1974  * @caps: a #GstCaps
1975  *
1976  * Constructs a new query object for querying if @caps are accepted.
1977  *
1978  * Free-function: gst_query_unref
1979  *
1980  * Returns: (transfer full): a new #GstQuery
1981  */
1982 GstQuery *
1983 gst_query_new_accept_caps (GstCaps * caps)
1984 {
1985   GstQuery *query;
1986   GstStructure *structure;
1987
1988   structure = gst_structure_new_id (GST_QUARK (QUERY_ACCEPT_CAPS),
1989       GST_QUARK (CAPS), GST_TYPE_CAPS, caps,
1990       GST_QUARK (RESULT), G_TYPE_BOOLEAN, FALSE, NULL);
1991   query = gst_query_new_custom (GST_QUERY_ACCEPT_CAPS, structure);
1992
1993   return query;
1994 }
1995
1996 /**
1997  * gst_query_parse_accept_caps:
1998  * @query: The query to parse
1999  * @caps: (out): A pointer to the caps
2000  *
2001  * Get the caps from @query. The caps remains valid as long as @query remains
2002  * valid.
2003  */
2004 void
2005 gst_query_parse_accept_caps (GstQuery * query, GstCaps ** caps)
2006 {
2007   GstStructure *structure;
2008
2009   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ACCEPT_CAPS);
2010   g_return_if_fail (caps != NULL);
2011
2012   structure = GST_QUERY_STRUCTURE (query);
2013   *caps = g_value_get_boxed (gst_structure_id_get_value (structure,
2014           GST_QUARK (CAPS)));
2015 }
2016
2017 void
2018 gst_query_set_accept_caps_result (GstQuery * query, gboolean result)
2019 {
2020   GstStructure *structure;
2021
2022   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ACCEPT_CAPS);
2023   g_return_if_fail (gst_query_is_writable (query));
2024
2025   structure = GST_QUERY_STRUCTURE (query);
2026   gst_structure_id_set (structure,
2027       GST_QUARK (RESULT), G_TYPE_BOOLEAN, result, NULL);
2028 }
2029
2030 void
2031 gst_query_parse_accept_caps_result (GstQuery * query, gboolean * result)
2032 {
2033   GstStructure *structure;
2034
2035   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ACCEPT_CAPS);
2036
2037   structure = GST_QUERY_STRUCTURE (query);
2038   gst_structure_id_get (structure,
2039       GST_QUARK (RESULT), G_TYPE_BOOLEAN, result, NULL);
2040 }
2041
2042 /**
2043  * gst_query_new_caps:
2044  * @filter: a filter
2045  *
2046  * Constructs a new query object for querying the caps.
2047  *
2048  * The CAPS query should return the* allowable caps for a pad in the context
2049  * of the element's state, its link to other elements, and the devices or files
2050  * it has opened. These caps must be a subset of the pad template caps. In the
2051  * NULL state with no links, the CAPS query should ideally return the same caps
2052  * as the pad template. In rare circumstances, an object property can affect
2053  * the caps returned by the CAPS query, but this is discouraged.
2054  *
2055  * For most filters, the caps returned by CAPS query is directly affected by the
2056  * allowed caps on other pads. For demuxers and decoders, the caps returned by
2057  * the srcpad's getcaps function is directly related to the stream data. Again,
2058  * the CAPS query should return the most specific caps it reasonably can, since this
2059  * helps with autoplugging.
2060  *
2061  * Free-function: gst_query_unref
2062  *
2063  * Returns: (transfer full): a new #GstQuery
2064  */
2065 GstQuery *
2066 gst_query_new_caps (GstCaps * filter)
2067 {
2068   GstQuery *query;
2069   GstStructure *structure;
2070
2071   structure = gst_structure_new_id (GST_QUARK (QUERY_CAPS),
2072       GST_QUARK (FILTER), GST_TYPE_CAPS, filter,
2073       GST_QUARK (CAPS), GST_TYPE_CAPS, NULL, NULL);
2074   query = gst_query_new_custom (GST_QUERY_CAPS, structure);
2075
2076   return query;
2077 }
2078
2079 /**
2080  * gst_query_parse_caps:
2081  * @query: The query to parse
2082  * @filter: (out): A pointer to the caps filter
2083  *
2084  * Get the filter from the caps @query. The caps remains valid as long as
2085  * @query remains valid.
2086  */
2087 void
2088 gst_query_parse_caps (GstQuery * query, GstCaps ** filter)
2089 {
2090   GstStructure *structure;
2091
2092   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CAPS);
2093   g_return_if_fail (filter != NULL);
2094
2095   structure = GST_QUERY_STRUCTURE (query);
2096   *filter = g_value_get_boxed (gst_structure_id_get_value (structure,
2097           GST_QUARK (FILTER)));
2098 }
2099
2100 /**
2101  * gst_query_set_caps_result:
2102  * @query: The query to use
2103  * @caps: (in): A pointer to the caps
2104  *
2105  * Set the @caps result in @query.
2106  */
2107 void
2108 gst_query_set_caps_result (GstQuery * query, GstCaps * caps)
2109 {
2110   GstStructure *structure;
2111
2112   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CAPS);
2113   g_return_if_fail (gst_query_is_writable (query));
2114
2115   structure = GST_QUERY_STRUCTURE (query);
2116   gst_structure_id_set (structure, GST_QUARK (CAPS), GST_TYPE_CAPS, caps, NULL);
2117 }
2118
2119 /**
2120  * gst_query_parse_caps_result:
2121  * @query: The query to parse
2122  * @caps: (out): A pointer to the caps
2123  *
2124  * Get the caps result from @query. The caps remains valid as long as
2125  * @query remains valid.
2126  */
2127 void
2128 gst_query_parse_caps_result (GstQuery * query, GstCaps ** caps)
2129 {
2130   GstStructure *structure;
2131
2132   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CAPS);
2133   g_return_if_fail (caps != NULL);
2134
2135   structure = GST_QUERY_STRUCTURE (query);
2136   *caps = g_value_get_boxed (gst_structure_id_get_value (structure,
2137           GST_QUARK (CAPS)));
2138 }
2139
2140 void
2141 gst_query_intersect_caps_result (GstQuery * query, GstCaps * filter,
2142     GstCapsIntersectMode mode)
2143 {
2144   GstCaps *res, *caps = NULL;
2145
2146   gst_query_parse_caps_result (query, &caps);
2147   res = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
2148   gst_query_set_caps_result (query, res);
2149   gst_caps_unref (res);
2150 }
2151
2152 /**
2153  * gst_query_new_drain:
2154  *
2155  * Constructs a new query object for querying the drain state.
2156  *
2157  * Free-function: gst_query_unref
2158  *
2159  * Returns: (transfer full): a new #GstQuery
2160  */
2161 GstQuery *
2162 gst_query_new_drain (void)
2163 {
2164   GstQuery *query;
2165   GstStructure *structure;
2166
2167   structure = gst_structure_new_id_empty (GST_QUARK (QUERY_DRAIN));
2168   query = gst_query_new_custom (GST_QUERY_DRAIN, structure);
2169
2170   return query;
2171 }