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