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