gst: Fix up a bunch of GIR annotations
[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., 51 Franklin St, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  */
23
24 /**
25  * SECTION:gstquery
26  * @title: GstQuery
27  * @short_description: Provide functions to create queries, and to set and parse
28  *                     values in them.
29  * @see_also: #GstPad, #GstElement
30  *
31  * Queries can be performed on pads (gst_pad_query()) and elements
32  * (gst_element_query()). Please note that some queries might need a running
33  * pipeline to work.
34  *
35  * Queries can be created using the gst_query_new_*() functions.
36  * Query values can be set using gst_query_set_*(), and parsed using
37  * gst_query_parse_*() helpers.
38  *
39  * The following example shows how to query the duration of a pipeline:
40  * |[<!-- language="C" -->
41  *   GstQuery *query;
42  *   gboolean res;
43  *   query = gst_query_new_duration (GST_FORMAT_TIME);
44  *   res = gst_element_query (pipeline, query);
45  *   if (res) {
46  *     gint64 duration;
47  *     gst_query_parse_duration (query, NULL, &amp;duration);
48  *     g_print ("duration = %"GST_TIME_FORMAT, GST_TIME_ARGS (duration));
49  *   } else {
50  *     g_print ("duration query failed...");
51  *   }
52  *   gst_query_unref (query);
53  * ]|
54  */
55
56
57 #include "gst_private.h"
58 #include "gstinfo.h"
59 #include "gstquery.h"
60 #include "gstvalue.h"
61 #include "gstenumtypes.h"
62 #include "gstquark.h"
63 #include "gsturi.h"
64 #include "gstbufferpool.h"
65
66 GST_DEBUG_CATEGORY_STATIC (gst_query_debug);
67 #define GST_CAT_DEFAULT gst_query_debug
68
69 GType _gst_query_type = 0;
70
71 typedef struct
72 {
73   GstQuery query;
74
75   GstStructure *structure;
76 } GstQueryImpl;
77
78 #define GST_QUERY_STRUCTURE(q)  (((GstQueryImpl *)(q))->structure)
79
80
81 typedef struct
82 {
83   const gint type;
84   const gchar *name;
85   GQuark quark;
86 } GstQueryQuarks;
87
88 static GstQueryQuarks query_quarks[] = {
89   {GST_QUERY_UNKNOWN, "unknown", 0},
90   {GST_QUERY_POSITION, "position", 0},
91   {GST_QUERY_DURATION, "duration", 0},
92   {GST_QUERY_LATENCY, "latency", 0},
93   {GST_QUERY_JITTER, "jitter", 0},
94   {GST_QUERY_RATE, "rate", 0},
95   {GST_QUERY_SEEKING, "seeking", 0},
96   {GST_QUERY_SEGMENT, "segment", 0},
97   {GST_QUERY_CONVERT, "convert", 0},
98   {GST_QUERY_FORMATS, "formats", 0},
99   {GST_QUERY_BUFFERING, "buffering", 0},
100   {GST_QUERY_CUSTOM, "custom", 0},
101   {GST_QUERY_URI, "uri", 0},
102   {GST_QUERY_ALLOCATION, "allocation", 0},
103   {GST_QUERY_SCHEDULING, "scheduling", 0},
104   {GST_QUERY_ACCEPT_CAPS, "accept-caps", 0},
105   {GST_QUERY_CAPS, "caps", 0},
106   {GST_QUERY_DRAIN, "drain", 0},
107   {GST_QUERY_CONTEXT, "context", 0},
108
109   {0, NULL, 0}
110 };
111
112 GST_DEFINE_MINI_OBJECT_TYPE (GstQuery, gst_query);
113
114 void
115 _priv_gst_query_initialize (void)
116 {
117   gint i;
118
119   _gst_query_type = gst_query_get_type ();
120
121   GST_DEBUG_CATEGORY_INIT (gst_query_debug, "query", 0, "query system");
122
123   for (i = 0; query_quarks[i].name; i++) {
124     query_quarks[i].quark = g_quark_from_static_string (query_quarks[i].name);
125   }
126 }
127
128 /**
129  * gst_query_type_get_name:
130  * @type: the query type
131  *
132  * Get a printable name for the given query type. Do not modify or free.
133  *
134  * Returns: a reference to the static name of the query.
135  */
136 const gchar *
137 gst_query_type_get_name (GstQueryType type)
138 {
139   gint i;
140
141   for (i = 0; query_quarks[i].name; i++) {
142     if (type == query_quarks[i].type)
143       return query_quarks[i].name;
144   }
145   return "unknown";
146 }
147
148 /**
149  * gst_query_type_to_quark:
150  * @type: the query type
151  *
152  * Get the unique quark for the given query type.
153  *
154  * Returns: the quark associated with the query type
155  */
156 GQuark
157 gst_query_type_to_quark (GstQueryType type)
158 {
159   gint i;
160
161   for (i = 0; query_quarks[i].name; i++) {
162     if (type == query_quarks[i].type)
163       return query_quarks[i].quark;
164   }
165   return 0;
166 }
167
168 /**
169  * gst_query_type_get_flags:
170  * @type: a #GstQueryType
171  *
172  * Gets the #GstQueryTypeFlags associated with @type.
173  *
174  * Returns: a #GstQueryTypeFlags.
175  */
176 GstQueryTypeFlags
177 gst_query_type_get_flags (GstQueryType type)
178 {
179   GstQueryTypeFlags ret;
180
181   ret = type & ((1 << GST_QUERY_NUM_SHIFT) - 1);
182
183   return ret;
184 }
185
186 static void
187 _gst_query_free (GstQuery * query)
188 {
189   GstStructure *s;
190
191   g_return_if_fail (query != NULL);
192
193   s = GST_QUERY_STRUCTURE (query);
194   if (s) {
195     gst_structure_set_parent_refcount (s, NULL);
196     gst_structure_free (s);
197   }
198
199   g_slice_free1 (sizeof (GstQueryImpl), query);
200 }
201
202 static GstQuery *
203 _gst_query_copy (GstQuery * query)
204 {
205   GstQuery *copy;
206   GstStructure *s;
207
208   s = GST_QUERY_STRUCTURE (query);
209   if (s) {
210     s = gst_structure_copy (s);
211   }
212   copy = gst_query_new_custom (query->type, s);
213
214   return copy;
215 }
216
217 /**
218  * gst_query_new_position:
219  * @format: the default #GstFormat for the new query
220  *
221  * Constructs a new query stream position query object. Use gst_query_unref()
222  * when done with it. A position query is used to query the current position
223  * of playback in the streams, in some format.
224  *
225  * Free-function: gst_query_unref()
226  *
227  * Returns: (transfer full): a new #GstQuery
228  */
229 GstQuery *
230 gst_query_new_position (GstFormat format)
231 {
232   GstQuery *query;
233   GstStructure *structure;
234
235   structure = gst_structure_new_id (GST_QUARK (QUERY_POSITION),
236       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
237       GST_QUARK (CURRENT), G_TYPE_INT64, G_GINT64_CONSTANT (-1), NULL);
238
239   query = gst_query_new_custom (GST_QUERY_POSITION, structure);
240
241   return query;
242 }
243
244 /**
245  * gst_query_set_position:
246  * @query: a #GstQuery with query type GST_QUERY_POSITION
247  * @format: the requested #GstFormat
248  * @cur: the position to set
249  *
250  * Answer a position query by setting the requested value in the given format.
251  */
252 void
253 gst_query_set_position (GstQuery * query, GstFormat format, gint64 cur)
254 {
255   GstStructure *s;
256
257   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_POSITION);
258
259   s = GST_QUERY_STRUCTURE (query);
260   g_return_if_fail (format == g_value_get_enum (gst_structure_id_get_value (s,
261               GST_QUARK (FORMAT))));
262
263   gst_structure_id_set (s,
264       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
265       GST_QUARK (CURRENT), G_TYPE_INT64, cur, NULL);
266 }
267
268 /**
269  * gst_query_parse_position:
270  * @query: a #GstQuery
271  * @format: (out) (allow-none): the storage for the #GstFormat of the
272  *     position values (may be %NULL)
273  * @cur: (out) (allow-none): the storage for the current position (may be %NULL)
274  *
275  * Parse a position query, writing the format into @format, and the position
276  * into @cur, if the respective parameters are non-%NULL.
277  */
278 void
279 gst_query_parse_position (GstQuery * query, GstFormat * format, gint64 * cur)
280 {
281   GstStructure *structure;
282
283   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_POSITION);
284
285   structure = GST_QUERY_STRUCTURE (query);
286   if (format)
287     *format =
288         (GstFormat) g_value_get_enum (gst_structure_id_get_value (structure,
289             GST_QUARK (FORMAT)));
290   if (cur)
291     *cur = g_value_get_int64 (gst_structure_id_get_value (structure,
292             GST_QUARK (CURRENT)));
293 }
294
295
296 /**
297  * gst_query_new_duration:
298  * @format: the #GstFormat for this duration query
299  *
300  * Constructs a new stream duration query object to query in the given format.
301  * Use gst_query_unref() when done with it. A duration query will give the
302  * total length of the stream.
303  *
304  * Free-function: gst_query_unref()
305  *
306  * Returns: (transfer full): a new #GstQuery
307  */
308 GstQuery *
309 gst_query_new_duration (GstFormat format)
310 {
311   GstQuery *query;
312   GstStructure *structure;
313
314   structure = gst_structure_new_id (GST_QUARK (QUERY_DURATION),
315       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
316       GST_QUARK (DURATION), G_TYPE_INT64, G_GINT64_CONSTANT (-1), NULL);
317
318   query = gst_query_new_custom (GST_QUERY_DURATION, structure);
319
320   return query;
321 }
322
323 /**
324  * gst_query_set_duration:
325  * @query: a #GstQuery
326  * @format: the #GstFormat for the duration
327  * @duration: the duration of the stream
328  *
329  * Answer a duration query by setting the requested value in the given format.
330  */
331 void
332 gst_query_set_duration (GstQuery * query, GstFormat format, gint64 duration)
333 {
334   GstStructure *s;
335
336   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_DURATION);
337
338   s = GST_QUERY_STRUCTURE (query);
339   g_return_if_fail (format == g_value_get_enum (gst_structure_id_get_value (s,
340               GST_QUARK (FORMAT))));
341   gst_structure_id_set (s, GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
342       GST_QUARK (DURATION), G_TYPE_INT64, duration, NULL);
343 }
344
345 /**
346  * gst_query_parse_duration:
347  * @query: a #GstQuery
348  * @format: (out) (allow-none): the storage for the #GstFormat of the duration
349  *     value, or %NULL.
350  * @duration: (out) (allow-none): the storage for the total duration, or %NULL.
351  *
352  * Parse a duration query answer. Write the format of the duration into @format,
353  * and the value into @duration, if the respective variables are non-%NULL.
354  */
355 void
356 gst_query_parse_duration (GstQuery * query, GstFormat * format,
357     gint64 * duration)
358 {
359   GstStructure *structure;
360
361   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_DURATION);
362
363   structure = GST_QUERY_STRUCTURE (query);
364   if (format)
365     *format =
366         (GstFormat) g_value_get_enum (gst_structure_id_get_value (structure,
367             GST_QUARK (FORMAT)));
368   if (duration)
369     *duration = g_value_get_int64 (gst_structure_id_get_value (structure,
370             GST_QUARK (DURATION)));
371 }
372
373 /**
374  * gst_query_new_latency:
375  *
376  * Constructs a new latency query object.
377  * Use gst_query_unref() when done with it. A latency query is usually performed
378  * by sinks to compensate for additional latency introduced by elements in the
379  * pipeline.
380  *
381  * Free-function: gst_query_unref()
382  *
383  * Returns: (transfer full): a #GstQuery
384  */
385 GstQuery *
386 gst_query_new_latency (void)
387 {
388   GstQuery *query;
389   GstStructure *structure;
390
391   structure = gst_structure_new_id (GST_QUARK (QUERY_LATENCY),
392       GST_QUARK (LIVE), G_TYPE_BOOLEAN, FALSE,
393       GST_QUARK (MIN_LATENCY), G_TYPE_UINT64, G_GUINT64_CONSTANT (0),
394       GST_QUARK (MAX_LATENCY), G_TYPE_UINT64, GST_CLOCK_TIME_NONE, NULL);
395
396   query = gst_query_new_custom (GST_QUERY_LATENCY, structure);
397
398   return query;
399 }
400
401 /**
402  * gst_query_set_latency:
403  * @query: a #GstQuery
404  * @live: if there is a live element upstream
405  * @min_latency: the minimal latency of the upstream elements
406  * @max_latency: the maximal latency of the upstream elements
407  *
408  * Answer a latency query by setting the requested values in the given format.
409  */
410 void
411 gst_query_set_latency (GstQuery * query, gboolean live,
412     GstClockTime min_latency, GstClockTime max_latency)
413 {
414   GstStructure *structure;
415
416   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_LATENCY);
417   g_return_if_fail (GST_CLOCK_TIME_IS_VALID (min_latency));
418
419   structure = GST_QUERY_STRUCTURE (query);
420   gst_structure_id_set (structure,
421       GST_QUARK (LIVE), G_TYPE_BOOLEAN, live,
422       GST_QUARK (MIN_LATENCY), G_TYPE_UINT64, min_latency,
423       GST_QUARK (MAX_LATENCY), G_TYPE_UINT64, max_latency, NULL);
424 }
425
426 /**
427  * gst_query_parse_latency:
428  * @query: a #GstQuery
429  * @live: (out) (allow-none): storage for live or %NULL
430  * @min_latency: (out) (allow-none): the storage for the min latency or %NULL
431  * @max_latency: (out) (allow-none): the storage for the max latency or %NULL
432  *
433  * Parse a latency query answer.
434  */
435 void
436 gst_query_parse_latency (GstQuery * query, gboolean * live,
437     GstClockTime * min_latency, GstClockTime * max_latency)
438 {
439   GstStructure *structure;
440
441   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_LATENCY);
442
443   structure = GST_QUERY_STRUCTURE (query);
444   if (live)
445     *live =
446         g_value_get_boolean (gst_structure_id_get_value (structure,
447             GST_QUARK (LIVE)));
448   if (min_latency)
449     *min_latency = g_value_get_uint64 (gst_structure_id_get_value (structure,
450             GST_QUARK (MIN_LATENCY)));
451   if (max_latency)
452     *max_latency = g_value_get_uint64 (gst_structure_id_get_value (structure,
453             GST_QUARK (MAX_LATENCY)));
454 }
455
456 /**
457  * gst_query_new_convert:
458  * @src_format: the source #GstFormat for the new query
459  * @value: the value to convert
460  * @dest_format: the target #GstFormat
461  *
462  * Constructs a new convert query object. Use gst_query_unref()
463  * when done with it. A convert query is used to ask for a conversion between
464  * one format and another.
465  *
466  * Free-function: gst_query_unref()
467  *
468  * Returns: (transfer full): a #GstQuery
469  */
470 GstQuery *
471 gst_query_new_convert (GstFormat src_format, gint64 value,
472     GstFormat dest_format)
473 {
474   GstQuery *query;
475   GstStructure *structure;
476
477   structure = gst_structure_new_id (GST_QUARK (QUERY_CONVERT),
478       GST_QUARK (SRC_FORMAT), GST_TYPE_FORMAT, src_format,
479       GST_QUARK (SRC_VALUE), G_TYPE_INT64, value,
480       GST_QUARK (DEST_FORMAT), GST_TYPE_FORMAT, dest_format,
481       GST_QUARK (DEST_VALUE), G_TYPE_INT64, G_GINT64_CONSTANT (-1), NULL);
482
483   query = gst_query_new_custom (GST_QUERY_CONVERT, structure);
484
485   return query;
486 }
487
488 /**
489  * gst_query_set_convert:
490  * @query: a #GstQuery
491  * @src_format: the source #GstFormat
492  * @src_value: the source value
493  * @dest_format: the destination #GstFormat
494  * @dest_value: the destination value
495  *
496  * Answer a convert query by setting the requested values.
497  */
498 void
499 gst_query_set_convert (GstQuery * query, GstFormat src_format, gint64 src_value,
500     GstFormat dest_format, gint64 dest_value)
501 {
502   GstStructure *structure;
503
504   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CONVERT);
505
506   structure = GST_QUERY_STRUCTURE (query);
507   gst_structure_id_set (structure,
508       GST_QUARK (SRC_FORMAT), GST_TYPE_FORMAT, src_format,
509       GST_QUARK (SRC_VALUE), G_TYPE_INT64, src_value,
510       GST_QUARK (DEST_FORMAT), GST_TYPE_FORMAT, dest_format,
511       GST_QUARK (DEST_VALUE), G_TYPE_INT64, dest_value, NULL);
512 }
513
514 /**
515  * gst_query_parse_convert:
516  * @query: a #GstQuery
517  * @src_format: (out) (allow-none): the storage for the #GstFormat of the
518  *     source value, or %NULL
519  * @src_value: (out) (allow-none): the storage for the source value, or %NULL
520  * @dest_format: (out) (allow-none): the storage for the #GstFormat of the
521  *     destination value, or %NULL
522  * @dest_value: (out) (allow-none): the storage for the destination value,
523  *     or %NULL
524  *
525  * Parse a convert query answer. Any of @src_format, @src_value, @dest_format,
526  * and @dest_value may be %NULL, in which case that value is omitted.
527  */
528 void
529 gst_query_parse_convert (GstQuery * query, GstFormat * src_format,
530     gint64 * src_value, GstFormat * dest_format, gint64 * dest_value)
531 {
532   GstStructure *structure;
533
534   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CONVERT);
535
536   structure = GST_QUERY_STRUCTURE (query);
537   if (src_format)
538     *src_format =
539         (GstFormat) g_value_get_enum (gst_structure_id_get_value (structure,
540             GST_QUARK (SRC_FORMAT)));
541   if (src_value)
542     *src_value = g_value_get_int64 (gst_structure_id_get_value (structure,
543             GST_QUARK (SRC_VALUE)));
544   if (dest_format)
545     *dest_format =
546         (GstFormat) g_value_get_enum (gst_structure_id_get_value (structure,
547             GST_QUARK (DEST_FORMAT)));
548   if (dest_value)
549     *dest_value = g_value_get_int64 (gst_structure_id_get_value (structure,
550             GST_QUARK (DEST_VALUE)));
551 }
552
553 /**
554  * gst_query_new_segment:
555  * @format: the #GstFormat for the new query
556  *
557  * Constructs a new segment query object. Use gst_query_unref()
558  * when done with it. A segment query is used to discover information about the
559  * currently configured segment for playback.
560  *
561  * Free-function: gst_query_unref()
562  *
563  * Returns: (transfer full): a new #GstQuery
564  */
565 GstQuery *
566 gst_query_new_segment (GstFormat format)
567 {
568   GstQuery *query;
569   GstStructure *structure;
570
571   structure = gst_structure_new_id (GST_QUARK (QUERY_SEGMENT),
572       GST_QUARK (RATE), G_TYPE_DOUBLE, (gdouble) 0.0,
573       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
574       GST_QUARK (START_VALUE), G_TYPE_INT64, G_GINT64_CONSTANT (-1),
575       GST_QUARK (STOP_VALUE), G_TYPE_INT64, G_GINT64_CONSTANT (-1), NULL);
576
577   query = gst_query_new_custom (GST_QUERY_SEGMENT, structure);
578
579   return query;
580 }
581
582 /**
583  * gst_query_set_segment:
584  * @query: a #GstQuery
585  * @rate: the rate of the segment
586  * @format: the #GstFormat of the segment values (@start_value and @stop_value)
587  * @start_value: the start value
588  * @stop_value: the stop value
589  *
590  * Answer a segment query by setting the requested values. The normal
591  * playback segment of a pipeline is 0 to duration at the default rate of
592  * 1.0. If a seek was performed on the pipeline to play a different
593  * segment, this query will return the range specified in the last seek.
594  *
595  * @start_value and @stop_value will respectively contain the configured
596  * playback range start and stop values expressed in @format.
597  * The values are always between 0 and the duration of the media and
598  * @start_value <= @stop_value. @rate will contain the playback rate. For
599  * negative rates, playback will actually happen from @stop_value to
600  * @start_value.
601  */
602 void
603 gst_query_set_segment (GstQuery * query, gdouble rate, GstFormat format,
604     gint64 start_value, gint64 stop_value)
605 {
606   GstStructure *structure;
607
608   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SEGMENT);
609
610   structure = GST_QUERY_STRUCTURE (query);
611   gst_structure_id_set (structure,
612       GST_QUARK (RATE), G_TYPE_DOUBLE, rate,
613       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
614       GST_QUARK (START_VALUE), G_TYPE_INT64, start_value,
615       GST_QUARK (STOP_VALUE), G_TYPE_INT64, stop_value, NULL);
616 }
617
618 /**
619  * gst_query_parse_segment:
620  * @query: a #GstQuery
621  * @rate: (out) (allow-none): the storage for the rate of the segment, or %NULL
622  * @format: (out) (allow-none): the storage for the #GstFormat of the values,
623  *     or %NULL
624  * @start_value: (out) (allow-none): the storage for the start value, or %NULL
625  * @stop_value: (out) (allow-none): the storage for the stop value, or %NULL
626  *
627  * Parse a segment query answer. Any of @rate, @format, @start_value, and
628  * @stop_value may be %NULL, which will cause this value to be omitted.
629  *
630  * See gst_query_set_segment() for an explanation of the function arguments.
631  */
632 void
633 gst_query_parse_segment (GstQuery * query, gdouble * rate, GstFormat * format,
634     gint64 * start_value, gint64 * stop_value)
635 {
636   GstStructure *structure;
637
638   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SEGMENT);
639
640   structure = GST_QUERY_STRUCTURE (query);
641   if (rate)
642     *rate = g_value_get_double (gst_structure_id_get_value (structure,
643             GST_QUARK (RATE)));
644   if (format)
645     *format =
646         (GstFormat) g_value_get_enum (gst_structure_id_get_value (structure,
647             GST_QUARK (FORMAT)));
648   if (start_value)
649     *start_value = g_value_get_int64 (gst_structure_id_get_value (structure,
650             GST_QUARK (START_VALUE)));
651   if (stop_value)
652     *stop_value = g_value_get_int64 (gst_structure_id_get_value (structure,
653             GST_QUARK (STOP_VALUE)));
654 }
655
656 /**
657  * gst_query_new_custom:
658  * @type: the query type
659  * @structure: (allow-none) (transfer full): a structure for the query
660  *
661  * Constructs a new custom query object. Use gst_query_unref()
662  * when done with it.
663  *
664  * Free-function: gst_query_unref()
665  *
666  * Returns: (transfer full) (nullable): a new #GstQuery
667  */
668 GstQuery *
669 gst_query_new_custom (GstQueryType type, GstStructure * structure)
670 {
671   GstQueryImpl *query;
672
673   query = g_slice_new0 (GstQueryImpl);
674
675   GST_DEBUG ("creating new query %p %s", query, gst_query_type_get_name (type));
676
677   if (structure) {
678     /* structure must not have a parent */
679     if (!gst_structure_set_parent_refcount (structure,
680             &query->query.mini_object.refcount))
681       goto had_parent;
682   }
683
684   gst_mini_object_init (GST_MINI_OBJECT_CAST (query), 0, _gst_query_type,
685       (GstMiniObjectCopyFunction) _gst_query_copy, NULL,
686       (GstMiniObjectFreeFunction) _gst_query_free);
687
688   GST_QUERY_TYPE (query) = type;
689   GST_QUERY_STRUCTURE (query) = structure;
690
691   return GST_QUERY_CAST (query);
692
693   /* ERRORS */
694 had_parent:
695   {
696     g_slice_free1 (sizeof (GstQueryImpl), query);
697     g_warning ("structure is already owned by another object");
698     return NULL;
699   }
700 }
701
702 /**
703  * gst_query_get_structure:
704  * @query: a #GstQuery
705  *
706  * Get the structure of a query.
707  *
708  * Returns: (transfer none) (nullable): the #GstStructure of the query. The
709  *     structure is still owned by the query and will therefore be freed when the
710  *     query is unreffed.
711  */
712 const GstStructure *
713 gst_query_get_structure (GstQuery * query)
714 {
715   g_return_val_if_fail (GST_IS_QUERY (query), NULL);
716
717   return GST_QUERY_STRUCTURE (query);
718 }
719
720 /**
721  * gst_query_writable_structure:
722  * @query: a #GstQuery
723  *
724  * Get the structure of a query. This method should be called with a writable
725  * @query so that the returned structure is guaranteed to be writable.
726  *
727  * Returns: (transfer none): the #GstStructure of the query. The structure is
728  *     still owned by the query and will therefore be freed when the query
729  *     is unreffed.
730  */
731 GstStructure *
732 gst_query_writable_structure (GstQuery * query)
733 {
734   GstStructure *structure;
735
736   g_return_val_if_fail (GST_IS_QUERY (query), NULL);
737   g_return_val_if_fail (gst_query_is_writable (query), NULL);
738
739   structure = GST_QUERY_STRUCTURE (query);
740
741   if (structure == NULL) {
742     structure =
743         gst_structure_new_id_empty (gst_query_type_to_quark (GST_QUERY_TYPE
744             (query)));
745     gst_structure_set_parent_refcount (structure, &query->mini_object.refcount);
746     GST_QUERY_STRUCTURE (query) = structure;
747   }
748   return structure;
749 }
750
751 /**
752  * gst_query_new_seeking:
753  * @format: the default #GstFormat for the new query
754  *
755  * Constructs a new query object for querying seeking properties of
756  * the stream.
757  *
758  * Free-function: gst_query_unref()
759  *
760  * Returns: (transfer full): a new #GstQuery
761  */
762 GstQuery *
763 gst_query_new_seeking (GstFormat format)
764 {
765   GstQuery *query;
766   GstStructure *structure;
767
768   structure = gst_structure_new_id (GST_QUARK (QUERY_SEEKING),
769       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
770       GST_QUARK (SEEKABLE), G_TYPE_BOOLEAN, FALSE,
771       GST_QUARK (SEGMENT_START), G_TYPE_INT64, G_GINT64_CONSTANT (-1),
772       GST_QUARK (SEGMENT_END), G_TYPE_INT64, G_GINT64_CONSTANT (-1), NULL);
773
774   query = gst_query_new_custom (GST_QUERY_SEEKING, structure);
775
776   return query;
777 }
778
779 /**
780  * gst_query_set_seeking:
781  * @query: a #GstQuery
782  * @format: the format to set for the @segment_start and @segment_end values
783  * @seekable: the seekable flag to set
784  * @segment_start: the segment_start to set
785  * @segment_end: the segment_end to set
786  *
787  * Set the seeking query result fields in @query.
788  */
789 void
790 gst_query_set_seeking (GstQuery * query, GstFormat format,
791     gboolean seekable, gint64 segment_start, gint64 segment_end)
792 {
793   GstStructure *structure;
794
795   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SEEKING);
796   g_return_if_fail (gst_query_is_writable (query));
797
798   structure = GST_QUERY_STRUCTURE (query);
799   gst_structure_id_set (structure,
800       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
801       GST_QUARK (SEEKABLE), G_TYPE_BOOLEAN, seekable,
802       GST_QUARK (SEGMENT_START), G_TYPE_INT64, segment_start,
803       GST_QUARK (SEGMENT_END), G_TYPE_INT64, segment_end, NULL);
804 }
805
806 /**
807  * gst_query_parse_seeking:
808  * @query: a GST_QUERY_SEEKING type query #GstQuery
809  * @format: (out) (allow-none): the format to set for the @segment_start
810  *     and @segment_end values, or %NULL
811  * @seekable: (out) (allow-none): the seekable flag to set, or %NULL
812  * @segment_start: (out) (allow-none): the segment_start to set, or %NULL
813  * @segment_end: (out) (allow-none): the segment_end to set, or %NULL
814  *
815  * Parse a seeking query, writing the format into @format, and
816  * other results into the passed parameters, if the respective parameters
817  * are non-%NULL
818  */
819 void
820 gst_query_parse_seeking (GstQuery * query, GstFormat * format,
821     gboolean * seekable, gint64 * segment_start, gint64 * segment_end)
822 {
823   GstStructure *structure;
824
825   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SEEKING);
826
827   structure = GST_QUERY_STRUCTURE (query);
828   if (format)
829     *format =
830         (GstFormat) g_value_get_enum (gst_structure_id_get_value (structure,
831             GST_QUARK (FORMAT)));
832   if (seekable)
833     *seekable = g_value_get_boolean (gst_structure_id_get_value (structure,
834             GST_QUARK (SEEKABLE)));
835   if (segment_start)
836     *segment_start = g_value_get_int64 (gst_structure_id_get_value (structure,
837             GST_QUARK (SEGMENT_START)));
838   if (segment_end)
839     *segment_end = g_value_get_int64 (gst_structure_id_get_value (structure,
840             GST_QUARK (SEGMENT_END)));
841 }
842
843 static GArray *
844 ensure_array (GstStructure * s, GQuark quark, gsize element_size,
845     GDestroyNotify clear_func)
846 {
847   GArray *array;
848   const GValue *value;
849
850   value = gst_structure_id_get_value (s, quark);
851   if (value) {
852     array = (GArray *) g_value_get_boxed (value);
853   } else {
854     GValue new_array_val = { 0, };
855
856     array = g_array_new (FALSE, TRUE, element_size);
857     if (clear_func)
858       g_array_set_clear_func (array, clear_func);
859
860     g_value_init (&new_array_val, G_TYPE_ARRAY);
861     g_value_take_boxed (&new_array_val, array);
862
863     gst_structure_id_take_value (s, quark, &new_array_val);
864   }
865   return array;
866 }
867
868 /**
869  * gst_query_new_formats:
870  *
871  * Constructs a new query object for querying formats of
872  * the stream.
873  *
874  * Free-function: gst_query_unref()
875  *
876  * Returns: (transfer full): a new #GstQuery
877  */
878 GstQuery *
879 gst_query_new_formats (void)
880 {
881   GstQuery *query;
882   GstStructure *structure;
883
884   structure = gst_structure_new_id_empty (GST_QUARK (QUERY_FORMATS));
885   query = gst_query_new_custom (GST_QUERY_FORMATS, structure);
886
887   return query;
888 }
889
890 static void
891 gst_query_list_add_format (GValue * list, GstFormat format)
892 {
893   GValue item = { 0, };
894
895   g_value_init (&item, GST_TYPE_FORMAT);
896   g_value_set_enum (&item, format);
897   gst_value_list_append_value (list, &item);
898   g_value_unset (&item);
899 }
900
901 /**
902  * gst_query_set_formats:
903  * @query: a #GstQuery
904  * @n_formats: the number of formats to set.
905  * @...: A number of @GstFormats equal to @n_formats.
906  *
907  * Set the formats query result fields in @query. The number of formats passed
908  * must be equal to @n_formats.
909  */
910 void
911 gst_query_set_formats (GstQuery * query, gint n_formats, ...)
912 {
913   va_list ap;
914   GValue list = { 0, };
915   gint i;
916   GstStructure *structure;
917
918   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_FORMATS);
919   g_return_if_fail (gst_query_is_writable (query));
920
921   g_value_init (&list, GST_TYPE_LIST);
922
923   va_start (ap, n_formats);
924   for (i = 0; i < n_formats; i++) {
925     gst_query_list_add_format (&list, va_arg (ap, GstFormat));
926   }
927   va_end (ap);
928
929   structure = GST_QUERY_STRUCTURE (query);
930   gst_structure_set_value (structure, "formats", &list);
931
932   g_value_unset (&list);
933
934 }
935
936 /**
937  * gst_query_set_formatsv:
938  * @query: a #GstQuery
939  * @n_formats: the number of formats to set.
940  * @formats: (in) (array length=n_formats): an array containing @n_formats
941  *     @GstFormat values.
942  *
943  * Set the formats query result fields in @query. The number of formats passed
944  * in the @formats array must be equal to @n_formats.
945  */
946 void
947 gst_query_set_formatsv (GstQuery * query, gint n_formats,
948     const GstFormat * formats)
949 {
950   GValue list = { 0, };
951   gint i;
952   GstStructure *structure;
953
954   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_FORMATS);
955   g_return_if_fail (gst_query_is_writable (query));
956
957   g_value_init (&list, GST_TYPE_LIST);
958   for (i = 0; i < n_formats; i++) {
959     gst_query_list_add_format (&list, formats[i]);
960   }
961   structure = GST_QUERY_STRUCTURE (query);
962   gst_structure_set_value (structure, "formats", &list);
963
964   g_value_unset (&list);
965 }
966
967 /**
968  * gst_query_parse_n_formats:
969  * @query: a #GstQuery
970  * @n_formats: (out) (allow-none): the number of formats in this query.
971  *
972  * Parse the number of formats in the formats @query.
973  */
974 void
975 gst_query_parse_n_formats (GstQuery * query, guint * n_formats)
976 {
977   GstStructure *structure;
978
979   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_FORMATS);
980
981   if (n_formats) {
982     const GValue *list;
983
984     structure = GST_QUERY_STRUCTURE (query);
985     list = gst_structure_get_value (structure, "formats");
986     if (list == NULL)
987       *n_formats = 0;
988     else
989       *n_formats = gst_value_list_get_size (list);
990   }
991 }
992
993 /**
994  * gst_query_parse_nth_format:
995  * @query: a #GstQuery
996  * @nth: (out): the nth format to retrieve.
997  * @format: (out) (allow-none): a pointer to store the nth format
998  *
999  * Parse the format query and retrieve the @nth format from it into
1000  * @format. If the list contains less elements than @nth, @format will be
1001  * set to GST_FORMAT_UNDEFINED.
1002  */
1003 void
1004 gst_query_parse_nth_format (GstQuery * query, guint nth, GstFormat * format)
1005 {
1006   GstStructure *structure;
1007
1008   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_FORMATS);
1009
1010   if (format) {
1011     const GValue *list;
1012
1013     structure = GST_QUERY_STRUCTURE (query);
1014     list = gst_structure_get_value (structure, "formats");
1015     if (list == NULL) {
1016       *format = GST_FORMAT_UNDEFINED;
1017     } else {
1018       if (nth < gst_value_list_get_size (list)) {
1019         *format =
1020             (GstFormat) g_value_get_enum (gst_value_list_get_value (list, nth));
1021       } else
1022         *format = GST_FORMAT_UNDEFINED;
1023     }
1024   }
1025 }
1026
1027 /**
1028  * gst_query_new_buffering:
1029  * @format: the default #GstFormat for the new query
1030  *
1031  * Constructs a new query object for querying the buffering status of
1032  * a stream.
1033  *
1034  * Free-function: gst_query_unref()
1035  *
1036  * Returns: (transfer full): a new #GstQuery
1037  */
1038 GstQuery *
1039 gst_query_new_buffering (GstFormat format)
1040 {
1041   GstQuery *query;
1042   GstStructure *structure;
1043
1044   /* by default, we configure the answer as no buffering with a 100% buffering
1045    * progress */
1046   structure = gst_structure_new_id (GST_QUARK (QUERY_BUFFERING),
1047       GST_QUARK (BUSY), G_TYPE_BOOLEAN, FALSE,
1048       GST_QUARK (BUFFER_PERCENT), G_TYPE_INT, 100,
1049       GST_QUARK (BUFFERING_MODE), GST_TYPE_BUFFERING_MODE, GST_BUFFERING_STREAM,
1050       GST_QUARK (AVG_IN_RATE), G_TYPE_INT, -1,
1051       GST_QUARK (AVG_OUT_RATE), G_TYPE_INT, -1,
1052       GST_QUARK (BUFFERING_LEFT), G_TYPE_INT64, G_GINT64_CONSTANT (0),
1053       GST_QUARK (ESTIMATED_TOTAL), G_TYPE_INT64, G_GINT64_CONSTANT (-1),
1054       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
1055       GST_QUARK (START_VALUE), G_TYPE_INT64, G_GINT64_CONSTANT (-1),
1056       GST_QUARK (STOP_VALUE), G_TYPE_INT64, G_GINT64_CONSTANT (-1), NULL);
1057
1058   query = gst_query_new_custom (GST_QUERY_BUFFERING, structure);
1059
1060   return query;
1061 }
1062
1063 /**
1064  * gst_query_set_buffering_percent:
1065  * @query: A valid #GstQuery of type GST_QUERY_BUFFERING.
1066  * @busy: if buffering is busy
1067  * @percent: a buffering percent
1068  *
1069  * Set the percentage of buffered data. This is a value between 0 and 100.
1070  * The @busy indicator is %TRUE when the buffering is in progress.
1071  */
1072 void
1073 gst_query_set_buffering_percent (GstQuery * query, gboolean busy, gint percent)
1074 {
1075   GstStructure *structure;
1076
1077   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING);
1078   g_return_if_fail (gst_query_is_writable (query));
1079   g_return_if_fail (percent >= 0 && percent <= 100);
1080
1081   structure = GST_QUERY_STRUCTURE (query);
1082   gst_structure_id_set (structure,
1083       GST_QUARK (BUSY), G_TYPE_BOOLEAN, busy,
1084       GST_QUARK (BUFFER_PERCENT), G_TYPE_INT, percent, NULL);
1085 }
1086
1087 /**
1088  * gst_query_parse_buffering_percent:
1089  * @query: A valid #GstQuery of type GST_QUERY_BUFFERING.
1090  * @busy: (out) (allow-none): if buffering is busy, or %NULL
1091  * @percent: (out) (allow-none): a buffering percent, or %NULL
1092  *
1093  * Get the percentage of buffered data. This is a value between 0 and 100.
1094  * The @busy indicator is %TRUE when the buffering is in progress.
1095  */
1096 void
1097 gst_query_parse_buffering_percent (GstQuery * query, gboolean * busy,
1098     gint * percent)
1099 {
1100   GstStructure *structure;
1101
1102   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING);
1103
1104   structure = GST_QUERY_STRUCTURE (query);
1105   if (busy)
1106     *busy = g_value_get_boolean (gst_structure_id_get_value (structure,
1107             GST_QUARK (BUSY)));
1108   if (percent)
1109     *percent = g_value_get_int (gst_structure_id_get_value (structure,
1110             GST_QUARK (BUFFER_PERCENT)));
1111 }
1112
1113 /**
1114  * gst_query_set_buffering_stats:
1115  * @query: A valid #GstQuery of type GST_QUERY_BUFFERING.
1116  * @mode: a buffering mode
1117  * @avg_in: the average input rate
1118  * @avg_out: the average output rate
1119  * @buffering_left: amount of buffering time left in milliseconds
1120  *
1121  * Configures the buffering stats values in @query.
1122  */
1123 void
1124 gst_query_set_buffering_stats (GstQuery * query, GstBufferingMode mode,
1125     gint avg_in, gint avg_out, gint64 buffering_left)
1126 {
1127   GstStructure *structure;
1128
1129   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING);
1130   g_return_if_fail (gst_query_is_writable (query));
1131
1132   structure = GST_QUERY_STRUCTURE (query);
1133   gst_structure_id_set (structure,
1134       GST_QUARK (BUFFERING_MODE), GST_TYPE_BUFFERING_MODE, mode,
1135       GST_QUARK (AVG_IN_RATE), G_TYPE_INT, avg_in,
1136       GST_QUARK (AVG_OUT_RATE), G_TYPE_INT, avg_out,
1137       GST_QUARK (BUFFERING_LEFT), G_TYPE_INT64, buffering_left, NULL);
1138 }
1139
1140 /**
1141  * gst_query_parse_buffering_stats:
1142  * @query: A valid #GstQuery of type GST_QUERY_BUFFERING.
1143  * @mode: (out) (allow-none): a buffering mode, or %NULL
1144  * @avg_in: (out) (allow-none): the average input rate, or %NULL
1145  * @avg_out: (out) (allow-none): the average output rat, or %NULL
1146  * @buffering_left: (out) (allow-none): amount of buffering time left in
1147  *     milliseconds, or %NULL
1148  *
1149  * Extracts the buffering stats values from @query.
1150  */
1151 void
1152 gst_query_parse_buffering_stats (GstQuery * query,
1153     GstBufferingMode * mode, gint * avg_in, gint * avg_out,
1154     gint64 * buffering_left)
1155 {
1156   GstStructure *structure;
1157
1158   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING);
1159
1160   structure = GST_QUERY_STRUCTURE (query);
1161   if (mode)
1162     *mode = (GstBufferingMode)
1163         g_value_get_enum (gst_structure_id_get_value (structure,
1164             GST_QUARK (BUFFERING_MODE)));
1165   if (avg_in)
1166     *avg_in = g_value_get_int (gst_structure_id_get_value (structure,
1167             GST_QUARK (AVG_IN_RATE)));
1168   if (avg_out)
1169     *avg_out = g_value_get_int (gst_structure_id_get_value (structure,
1170             GST_QUARK (AVG_OUT_RATE)));
1171   if (buffering_left)
1172     *buffering_left =
1173         g_value_get_int64 (gst_structure_id_get_value (structure,
1174             GST_QUARK (BUFFERING_LEFT)));
1175 }
1176
1177 /**
1178  * gst_query_set_buffering_range:
1179  * @query: a #GstQuery
1180  * @format: the format to set for the @start and @stop values
1181  * @start: the start to set
1182  * @stop: the stop to set
1183  * @estimated_total: estimated total amount of download time remaining in
1184  *     milliseconds
1185  *
1186  * Set the available query result fields in @query.
1187  */
1188 void
1189 gst_query_set_buffering_range (GstQuery * query, GstFormat format,
1190     gint64 start, gint64 stop, gint64 estimated_total)
1191 {
1192   GstStructure *structure;
1193
1194   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING);
1195   g_return_if_fail (gst_query_is_writable (query));
1196
1197   structure = GST_QUERY_STRUCTURE (query);
1198   gst_structure_id_set (structure,
1199       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
1200       GST_QUARK (START_VALUE), G_TYPE_INT64, start,
1201       GST_QUARK (STOP_VALUE), G_TYPE_INT64, stop,
1202       GST_QUARK (ESTIMATED_TOTAL), G_TYPE_INT64, estimated_total, NULL);
1203 }
1204
1205 /**
1206  * gst_query_parse_buffering_range:
1207  * @query: a GST_QUERY_BUFFERING type query #GstQuery
1208  * @format: (out) (allow-none): the format to set for the @segment_start
1209  *     and @segment_end values, or %NULL
1210  * @start: (out) (allow-none): the start to set, or %NULL
1211  * @stop: (out) (allow-none): the stop to set, or %NULL
1212  * @estimated_total: (out) (allow-none): estimated total amount of download
1213  *     time remaining in milliseconds, or %NULL
1214  *
1215  * Parse an available query, writing the format into @format, and
1216  * other results into the passed parameters, if the respective parameters
1217  * are non-%NULL
1218  */
1219 void
1220 gst_query_parse_buffering_range (GstQuery * query, GstFormat * format,
1221     gint64 * start, gint64 * stop, gint64 * estimated_total)
1222 {
1223   GstStructure *structure;
1224
1225   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING);
1226
1227   structure = GST_QUERY_STRUCTURE (query);
1228   if (format)
1229     *format =
1230         (GstFormat) g_value_get_enum (gst_structure_id_get_value (structure,
1231             GST_QUARK (FORMAT)));
1232   if (start)
1233     *start = g_value_get_int64 (gst_structure_id_get_value (structure,
1234             GST_QUARK (START_VALUE)));
1235   if (stop)
1236     *stop = g_value_get_int64 (gst_structure_id_get_value (structure,
1237             GST_QUARK (STOP_VALUE)));
1238   if (estimated_total)
1239     *estimated_total =
1240         g_value_get_int64 (gst_structure_id_get_value (structure,
1241             GST_QUARK (ESTIMATED_TOTAL)));
1242 }
1243
1244 /* GstQueryBufferingRange: internal struct for GArray */
1245 typedef struct
1246 {
1247   gint64 start;
1248   gint64 stop;
1249 } GstQueryBufferingRange;
1250
1251 /**
1252  * gst_query_add_buffering_range:
1253  * @query: a GST_QUERY_BUFFERING type query #GstQuery
1254  * @start: start position of the range
1255  * @stop: stop position of the range
1256  *
1257  * Set the buffering-ranges array field in @query. The current last
1258  * start position of the array should be inferior to @start.
1259  *
1260  * Returns: a #gboolean indicating if the range was added or not.
1261  */
1262 gboolean
1263 gst_query_add_buffering_range (GstQuery * query, gint64 start, gint64 stop)
1264 {
1265   GstQueryBufferingRange range;
1266   GstStructure *structure;
1267   GArray *array;
1268
1269   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING, FALSE);
1270   g_return_val_if_fail (gst_query_is_writable (query), FALSE);
1271
1272   if (G_UNLIKELY (start >= stop))
1273     return FALSE;
1274
1275   structure = GST_QUERY_STRUCTURE (query);
1276   array = ensure_array (structure, GST_QUARK (BUFFERING_RANGES),
1277       sizeof (GstQueryBufferingRange), NULL);
1278
1279   if (array->len > 1) {
1280     GstQueryBufferingRange *last;
1281
1282     last = &g_array_index (array, GstQueryBufferingRange, array->len - 1);
1283
1284     if (G_UNLIKELY (start <= last->start))
1285       return FALSE;
1286   }
1287
1288   range.start = start;
1289   range.stop = stop;
1290   g_array_append_val (array, range);
1291
1292   return TRUE;
1293 }
1294
1295 /**
1296  * gst_query_get_n_buffering_ranges:
1297  * @query: a GST_QUERY_BUFFERING type query #GstQuery
1298  *
1299  * Retrieve the number of values currently stored in the
1300  * buffered-ranges array of the query's structure.
1301  *
1302  * Returns: the range array size as a #guint.
1303  */
1304 guint
1305 gst_query_get_n_buffering_ranges (GstQuery * query)
1306 {
1307   GstStructure *structure;
1308   GArray *array;
1309
1310   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING, 0);
1311
1312   structure = GST_QUERY_STRUCTURE (query);
1313   array = ensure_array (structure, GST_QUARK (BUFFERING_RANGES),
1314       sizeof (GstQueryBufferingRange), NULL);
1315
1316   return array->len;
1317 }
1318
1319
1320 /**
1321  * gst_query_parse_nth_buffering_range:
1322  * @query: a GST_QUERY_BUFFERING type query #GstQuery
1323  * @index: position in the buffered-ranges array to read
1324  * @start: (out) (allow-none): the start position to set, or %NULL
1325  * @stop: (out) (allow-none): the stop position to set, or %NULL
1326  *
1327  * Parse an available query and get the start and stop values stored
1328  * at the @index of the buffered ranges array.
1329  *
1330  * Returns: a #gboolean indicating if the parsing succeeded.
1331  */
1332 gboolean
1333 gst_query_parse_nth_buffering_range (GstQuery * query, guint index,
1334     gint64 * start, gint64 * stop)
1335 {
1336   GstQueryBufferingRange *range;
1337   GstStructure *structure;
1338   GArray *array;
1339
1340   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING, FALSE);
1341
1342   structure = GST_QUERY_STRUCTURE (query);
1343
1344   array = ensure_array (structure, GST_QUARK (BUFFERING_RANGES),
1345       sizeof (GstQueryBufferingRange), NULL);
1346   g_return_val_if_fail (index < array->len, FALSE);
1347
1348   range = &g_array_index (array, GstQueryBufferingRange, index);
1349
1350   if (start)
1351     *start = range->start;
1352   if (stop)
1353     *stop = range->stop;
1354
1355   return TRUE;
1356 }
1357
1358
1359 /**
1360  * gst_query_new_uri:
1361  *
1362  * Constructs a new query URI query object. Use gst_query_unref()
1363  * when done with it. An URI query is used to query the current URI
1364  * that is used by the source or sink.
1365  *
1366  * Free-function: gst_query_unref()
1367  *
1368  * Returns: (transfer full): a new #GstQuery
1369  */
1370 GstQuery *
1371 gst_query_new_uri (void)
1372 {
1373   GstQuery *query;
1374   GstStructure *structure;
1375
1376   structure = gst_structure_new_id (GST_QUARK (QUERY_URI),
1377       GST_QUARK (URI), G_TYPE_STRING, NULL, NULL);
1378
1379   query = gst_query_new_custom (GST_QUERY_URI, structure);
1380
1381   return query;
1382 }
1383
1384 /**
1385  * gst_query_set_uri:
1386  * @query: a #GstQuery with query type GST_QUERY_URI
1387  * @uri: the URI to set
1388  *
1389  * Answer a URI query by setting the requested URI.
1390  */
1391 void
1392 gst_query_set_uri (GstQuery * query, const gchar * uri)
1393 {
1394   GstStructure *structure;
1395
1396   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_URI);
1397   g_return_if_fail (gst_query_is_writable (query));
1398   g_return_if_fail (gst_uri_is_valid (uri));
1399
1400   structure = GST_QUERY_STRUCTURE (query);
1401   gst_structure_id_set (structure, GST_QUARK (URI), G_TYPE_STRING, uri, NULL);
1402 }
1403
1404 /**
1405  * gst_query_parse_uri:
1406  * @query: a #GstQuery
1407  * @uri: (out) (transfer full) (allow-none): the storage for the current URI
1408  *     (may be %NULL)
1409  *
1410  * Parse an URI query, writing the URI into @uri as a newly
1411  * allocated string, if the respective parameters are non-%NULL.
1412  * Free the string with g_free() after usage.
1413  */
1414 void
1415 gst_query_parse_uri (GstQuery * query, gchar ** uri)
1416 {
1417   GstStructure *structure;
1418
1419   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_URI);
1420
1421   structure = GST_QUERY_STRUCTURE (query);
1422   if (uri)
1423     *uri = g_value_dup_string (gst_structure_id_get_value (structure,
1424             GST_QUARK (URI)));
1425 }
1426
1427 /**
1428  * gst_query_set_uri_redirection:
1429  * @query: a #GstQuery with query type GST_QUERY_URI
1430  * @uri: the URI to set
1431  *
1432  * Answer a URI query by setting the requested URI redirection.
1433  *
1434  * Since: 1.2
1435  */
1436 void
1437 gst_query_set_uri_redirection (GstQuery * query, const gchar * uri)
1438 {
1439   GstStructure *structure;
1440
1441   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_URI);
1442   g_return_if_fail (gst_query_is_writable (query));
1443   g_return_if_fail (gst_uri_is_valid (uri));
1444
1445   structure = GST_QUERY_STRUCTURE (query);
1446   gst_structure_id_set (structure, GST_QUARK (URI_REDIRECTION),
1447       G_TYPE_STRING, uri, NULL);
1448 }
1449
1450 /**
1451  * gst_query_parse_uri_redirection:
1452  * @query: a #GstQuery
1453  * @uri: (out) (transfer full) (allow-none): the storage for the redirect URI
1454  *     (may be %NULL)
1455  *
1456  * Parse an URI query, writing the URI into @uri as a newly
1457  * allocated string, if the respective parameters are non-%NULL.
1458  * Free the string with g_free() after usage.
1459  *
1460  * Since: 1.2
1461  */
1462 void
1463 gst_query_parse_uri_redirection (GstQuery * query, gchar ** uri)
1464 {
1465   GstStructure *structure;
1466
1467   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_URI);
1468
1469   structure = GST_QUERY_STRUCTURE (query);
1470   if (uri) {
1471     if (!gst_structure_id_get (structure, GST_QUARK (URI_REDIRECTION),
1472             G_TYPE_STRING, uri, NULL))
1473       *uri = NULL;
1474   }
1475 }
1476
1477 /**
1478  * gst_query_set_uri_redirection_permanent:
1479  * @query: a #GstQuery with query type %GST_QUERY_URI
1480  * @permanent: whether the redirect is permanent or not
1481  *
1482  * Answer a URI query by setting the requested URI redirection
1483  * to permanent or not.
1484  *
1485  * Since: 1.4
1486  */
1487 void
1488 gst_query_set_uri_redirection_permanent (GstQuery * query, gboolean permanent)
1489 {
1490   GstStructure *structure;
1491
1492   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_URI);
1493   g_return_if_fail (gst_query_is_writable (query));
1494
1495   structure = GST_QUERY_STRUCTURE (query);
1496   gst_structure_id_set (structure, GST_QUARK (URI_REDIRECTION_PERMANENT),
1497       G_TYPE_BOOLEAN, permanent, NULL);
1498 }
1499
1500 /**
1501  * gst_query_parse_uri_redirection_permanent:
1502  * @query: a #GstQuery
1503  * @permanent: (out) (allow-none): if the URI redirection is permanent
1504  *     (may be %NULL)
1505  *
1506  * Parse an URI query, and set @permanent to %TRUE if there is a redirection
1507  * and it should be considered permanent. If a redirection is permanent,
1508  * applications should update their internal storage of the URI, otherwise
1509  * they should make all future requests to the original URI.
1510  *
1511  * Since: 1.4
1512  */
1513 void
1514 gst_query_parse_uri_redirection_permanent (GstQuery * query,
1515     gboolean * permanent)
1516 {
1517   GstStructure *structure;
1518
1519   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_URI);
1520
1521   structure = GST_QUERY_STRUCTURE (query);
1522   if (permanent) {
1523     if (!gst_structure_id_get (structure, GST_QUARK (URI_REDIRECTION_PERMANENT),
1524             G_TYPE_BOOLEAN, permanent, NULL))
1525       *permanent = FALSE;
1526   }
1527 }
1528
1529 /**
1530  * gst_query_new_allocation:
1531  * @caps: the negotiated caps
1532  * @need_pool: return a pool
1533  *
1534  * Constructs a new query object for querying the allocation properties.
1535  *
1536  * Free-function: gst_query_unref()
1537  *
1538  * Returns: (transfer full): a new #GstQuery
1539  */
1540 GstQuery *
1541 gst_query_new_allocation (GstCaps * caps, gboolean need_pool)
1542 {
1543   GstQuery *query;
1544   GstStructure *structure;
1545
1546   structure = gst_structure_new_id (GST_QUARK (QUERY_ALLOCATION),
1547       GST_QUARK (CAPS), GST_TYPE_CAPS, caps,
1548       GST_QUARK (NEED_POOL), G_TYPE_BOOLEAN, need_pool, NULL);
1549
1550   query = gst_query_new_custom (GST_QUERY_ALLOCATION, structure);
1551
1552   return query;
1553 }
1554
1555 /**
1556  * gst_query_parse_allocation:
1557  * @query: a #GstQuery
1558  * @caps: (out) (transfer none) (allow-none): The #GstCaps
1559  * @need_pool: (out) (allow-none): Whether a #GstBufferPool is needed
1560  *
1561  * Parse an allocation query, writing the requested caps in @caps and
1562  * whether a pool is needed in @need_pool, if the respective parameters
1563  * are non-%NULL.
1564  *
1565  * Pool details can be retrieved using gst_query_get_n_allocation_pools() and
1566  * gst_query_parse_nth_allocation_pool().
1567  */
1568 void
1569 gst_query_parse_allocation (GstQuery * query, GstCaps ** caps,
1570     gboolean * need_pool)
1571 {
1572   GstStructure *structure;
1573
1574   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
1575
1576   structure = GST_QUERY_STRUCTURE (query);
1577   if (caps) {
1578     *caps = g_value_get_boxed (gst_structure_id_get_value (structure,
1579             GST_QUARK (CAPS)));
1580   }
1581   gst_structure_id_get (structure,
1582       GST_QUARK (NEED_POOL), G_TYPE_BOOLEAN, need_pool, NULL);
1583 }
1584
1585 typedef struct
1586 {
1587   GstBufferPool *pool;
1588   guint size;
1589   guint min_buffers;
1590   guint max_buffers;
1591 } AllocationPool;
1592
1593 static void
1594 allocation_pool_free (AllocationPool * ap)
1595 {
1596   if (ap->pool)
1597     gst_object_unref (ap->pool);
1598 }
1599
1600 /**
1601  * gst_query_add_allocation_pool:
1602  * @query: A valid #GstQuery of type GST_QUERY_ALLOCATION.
1603  * @pool: (transfer none) (allow-none): the #GstBufferPool
1604  * @size: the buffer size
1605  * @min_buffers: the min buffers
1606  * @max_buffers: the max buffers
1607  *
1608  * Set the pool parameters in @query.
1609  */
1610 void
1611 gst_query_add_allocation_pool (GstQuery * query, GstBufferPool * pool,
1612     guint size, guint min_buffers, guint max_buffers)
1613 {
1614   GArray *array;
1615   GstStructure *structure;
1616   AllocationPool ap;
1617
1618   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
1619   g_return_if_fail (gst_query_is_writable (query));
1620
1621   structure = GST_QUERY_STRUCTURE (query);
1622   array = ensure_array (structure, GST_QUARK (POOL),
1623       sizeof (AllocationPool), (GDestroyNotify) allocation_pool_free);
1624
1625   if ((ap.pool = pool))
1626     gst_object_ref (pool);
1627   ap.size = size;
1628   ap.min_buffers = min_buffers;
1629   ap.max_buffers = max_buffers;
1630
1631   g_array_append_val (array, ap);
1632 }
1633
1634 /**
1635  * gst_query_get_n_allocation_pools:
1636  * @query: a GST_QUERY_ALLOCATION type query #GstQuery
1637  *
1638  * Retrieve the number of values currently stored in the
1639  * pool array of the query's structure.
1640  *
1641  * Returns: the pool array size as a #guint.
1642  */
1643 guint
1644 gst_query_get_n_allocation_pools (GstQuery * query)
1645 {
1646   GArray *array;
1647   GstStructure *structure;
1648
1649   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, 0);
1650
1651   structure = GST_QUERY_STRUCTURE (query);
1652   array = ensure_array (structure, GST_QUARK (POOL),
1653       sizeof (AllocationPool), (GDestroyNotify) allocation_pool_free);
1654
1655   return array->len;
1656 }
1657
1658 /**
1659  * gst_query_parse_nth_allocation_pool:
1660  * @query: A valid #GstQuery of type GST_QUERY_ALLOCATION.
1661  * @index: index to parse
1662  * @pool: (out) (allow-none) (transfer full): the #GstBufferPool
1663  * @size: (out) (allow-none): the buffer size
1664  * @min_buffers: (out) (allow-none): the min buffers
1665  * @max_buffers: (out) (allow-none): the max buffers
1666  *
1667  * Get the pool parameters in @query.
1668  *
1669  * Unref @pool with gst_object_unref() when it's not needed any more.
1670  */
1671 void
1672 gst_query_parse_nth_allocation_pool (GstQuery * query, guint index,
1673     GstBufferPool ** pool, guint * size, guint * min_buffers,
1674     guint * max_buffers)
1675 {
1676   GArray *array;
1677   GstStructure *structure;
1678   AllocationPool *ap;
1679
1680   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
1681
1682   structure = GST_QUERY_STRUCTURE (query);
1683   array = ensure_array (structure, GST_QUARK (POOL),
1684       sizeof (AllocationPool), (GDestroyNotify) allocation_pool_free);
1685   g_return_if_fail (index < array->len);
1686
1687   ap = &g_array_index (array, AllocationPool, index);
1688
1689   if (pool)
1690     if ((*pool = ap->pool))
1691       gst_object_ref (*pool);
1692   if (size)
1693     *size = ap->size;
1694   if (min_buffers)
1695     *min_buffers = ap->min_buffers;
1696   if (max_buffers)
1697     *max_buffers = ap->max_buffers;
1698 }
1699
1700 /**
1701  * gst_query_set_nth_allocation_pool:
1702  * @index: index to modify
1703  * @query: A valid #GstQuery of type GST_QUERY_ALLOCATION.
1704  * @pool: (transfer none) (allow-none): the #GstBufferPool
1705  * @size: the buffer size
1706  * @min_buffers: the min buffers
1707  * @max_buffers: the max buffers
1708  *
1709  * Set the pool parameters in @query.
1710  */
1711 void
1712 gst_query_set_nth_allocation_pool (GstQuery * query, guint index,
1713     GstBufferPool * pool, guint size, guint min_buffers, guint max_buffers)
1714 {
1715   GArray *array;
1716   GstStructure *structure;
1717   AllocationPool *oldap, ap;
1718
1719   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
1720
1721   structure = GST_QUERY_STRUCTURE (query);
1722   array = ensure_array (structure, GST_QUARK (POOL),
1723       sizeof (AllocationPool), (GDestroyNotify) allocation_pool_free);
1724   g_return_if_fail (index < array->len);
1725
1726   oldap = &g_array_index (array, AllocationPool, index);
1727   allocation_pool_free (oldap);
1728
1729   if ((ap.pool = pool))
1730     gst_object_ref (pool);
1731   ap.size = size;
1732   ap.min_buffers = min_buffers;
1733   ap.max_buffers = max_buffers;
1734   g_array_index (array, AllocationPool, index) = ap;
1735 }
1736
1737 /**
1738  * gst_query_remove_nth_allocation_pool:
1739  * @query: a GST_QUERY_ALLOCATION type query #GstQuery
1740  * @index: position in the allocation pool array to remove
1741  *
1742  * Remove the allocation pool at @index of the allocation pool array.
1743  *
1744  * Since: 1.2
1745  */
1746 void
1747 gst_query_remove_nth_allocation_pool (GstQuery * query, guint index)
1748 {
1749   GArray *array;
1750   GstStructure *structure;
1751
1752   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
1753   g_return_if_fail (gst_query_is_writable (query));
1754
1755   structure = GST_QUERY_STRUCTURE (query);
1756   array =
1757       ensure_array (structure, GST_QUARK (POOL), sizeof (AllocationPool),
1758       (GDestroyNotify) allocation_pool_free);
1759   g_return_if_fail (index < array->len);
1760
1761   g_array_remove_index (array, index);
1762 }
1763
1764 typedef struct
1765 {
1766   GType api;
1767   GstStructure *params;
1768 } AllocationMeta;
1769
1770 static void
1771 allocation_meta_free (AllocationMeta * am)
1772 {
1773   if (am->params)
1774     gst_structure_free (am->params);
1775 }
1776
1777 /**
1778  * gst_query_add_allocation_meta:
1779  * @query: a GST_QUERY_ALLOCATION type query #GstQuery
1780  * @api: the metadata API
1781  * @params: (transfer none) (allow-none): API specific parameters
1782  *
1783  * Add @api with @params as one of the supported metadata API to @query.
1784  */
1785 void
1786 gst_query_add_allocation_meta (GstQuery * query, GType api,
1787     const GstStructure * params)
1788 {
1789   GArray *array;
1790   GstStructure *structure;
1791   AllocationMeta am;
1792
1793   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
1794   g_return_if_fail (api != 0);
1795   g_return_if_fail (gst_query_is_writable (query));
1796
1797   structure = GST_QUERY_STRUCTURE (query);
1798   array =
1799       ensure_array (structure, GST_QUARK (META), sizeof (AllocationMeta),
1800       (GDestroyNotify) allocation_meta_free);
1801
1802   am.api = api;
1803   am.params = (params ? gst_structure_copy (params) : NULL);
1804
1805   g_array_append_val (array, am);
1806 }
1807
1808 /**
1809  * gst_query_get_n_allocation_metas:
1810  * @query: a GST_QUERY_ALLOCATION type query #GstQuery
1811  *
1812  * Retrieve the number of values currently stored in the
1813  * meta API array of the query's structure.
1814  *
1815  * Returns: the metadata API array size as a #guint.
1816  */
1817 guint
1818 gst_query_get_n_allocation_metas (GstQuery * query)
1819 {
1820   GArray *array;
1821   GstStructure *structure;
1822
1823   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, 0);
1824
1825   structure = GST_QUERY_STRUCTURE (query);
1826   array =
1827       ensure_array (structure, GST_QUARK (META), sizeof (AllocationMeta),
1828       (GDestroyNotify) allocation_meta_free);
1829
1830   return array->len;
1831 }
1832
1833 /**
1834  * gst_query_parse_nth_allocation_meta:
1835  * @query: a GST_QUERY_ALLOCATION type query #GstQuery
1836  * @index: position in the metadata API array to read
1837  * @params: (out) (transfer none) (allow-none): API specific parameters
1838  *
1839  * Parse an available query and get the metadata API
1840  * at @index of the metadata API array.
1841  *
1842  * Returns: a #GType of the metadata API at @index.
1843  */
1844 GType
1845 gst_query_parse_nth_allocation_meta (GstQuery * query, guint index,
1846     const GstStructure ** params)
1847 {
1848   GArray *array;
1849   GstStructure *structure;
1850   AllocationMeta *am;
1851
1852   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, 0);
1853
1854   structure = GST_QUERY_STRUCTURE (query);
1855   array =
1856       ensure_array (structure, GST_QUARK (META), sizeof (AllocationMeta),
1857       (GDestroyNotify) allocation_meta_free);
1858
1859   g_return_val_if_fail (index < array->len, 0);
1860
1861   am = &g_array_index (array, AllocationMeta, index);
1862
1863   if (params)
1864     *params = am->params;
1865
1866   return am->api;
1867 }
1868
1869 /**
1870  * gst_query_remove_nth_allocation_meta:
1871  * @query: a GST_QUERY_ALLOCATION type query #GstQuery
1872  * @index: position in the metadata API array to remove
1873  *
1874  * Remove the metadata API at @index of the metadata API array.
1875  */
1876 void
1877 gst_query_remove_nth_allocation_meta (GstQuery * query, guint index)
1878 {
1879   GArray *array;
1880   GstStructure *structure;
1881
1882   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
1883   g_return_if_fail (gst_query_is_writable (query));
1884
1885   structure = GST_QUERY_STRUCTURE (query);
1886   array =
1887       ensure_array (structure, GST_QUARK (META), sizeof (AllocationMeta),
1888       (GDestroyNotify) allocation_meta_free);
1889   g_return_if_fail (index < array->len);
1890
1891   g_array_remove_index (array, index);
1892 }
1893
1894 /**
1895  * gst_query_find_allocation_meta:
1896  * @query: a GST_QUERY_ALLOCATION type query #GstQuery
1897  * @api: the metadata API
1898  * @index: (out) (transfer none) (allow-none): the index
1899  *
1900  * Check if @query has metadata @api set. When this function returns %TRUE,
1901  * @index will contain the index where the requested API and the parameters
1902  * can be found.
1903  *
1904  * Returns: %TRUE when @api is in the list of metadata.
1905  */
1906 gboolean
1907 gst_query_find_allocation_meta (GstQuery * query, GType api, guint * index)
1908 {
1909   GArray *array;
1910   GstStructure *structure;
1911   guint i, len;
1912
1913   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, FALSE);
1914   g_return_val_if_fail (api != 0, FALSE);
1915
1916   structure = GST_QUERY_STRUCTURE (query);
1917   array =
1918       ensure_array (structure, GST_QUARK (META), sizeof (AllocationMeta),
1919       (GDestroyNotify) allocation_meta_free);
1920
1921   len = array->len;
1922   for (i = 0; i < len; i++) {
1923     AllocationMeta *am = &g_array_index (array, AllocationMeta, i);
1924     if (am->api == api) {
1925       if (index)
1926         *index = i;
1927       return TRUE;
1928     }
1929   }
1930   return FALSE;
1931 }
1932
1933 typedef struct
1934 {
1935   GstAllocator *allocator;
1936   GstAllocationParams params;
1937 } AllocationParam;
1938
1939 static void
1940 allocation_param_free (AllocationParam * ap)
1941 {
1942   if (ap->allocator)
1943     gst_object_unref (ap->allocator);
1944 }
1945
1946 /**
1947  * gst_query_add_allocation_param:
1948  * @query: a GST_QUERY_ALLOCATION type query #GstQuery
1949  * @allocator: (transfer none) (allow-none): the memory allocator
1950  * @params: (transfer none) (allow-none): a #GstAllocationParams
1951  *
1952  * Add @allocator and its @params as a supported memory allocator.
1953  */
1954 void
1955 gst_query_add_allocation_param (GstQuery * query, GstAllocator * allocator,
1956     const GstAllocationParams * params)
1957 {
1958   GArray *array;
1959   GstStructure *structure;
1960   AllocationParam ap;
1961
1962   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
1963   g_return_if_fail (gst_query_is_writable (query));
1964   g_return_if_fail (allocator != NULL || params != NULL);
1965
1966   structure = GST_QUERY_STRUCTURE (query);
1967   array = ensure_array (structure, GST_QUARK (ALLOCATOR),
1968       sizeof (AllocationParam), (GDestroyNotify) allocation_param_free);
1969
1970   if ((ap.allocator = allocator))
1971     gst_object_ref (allocator);
1972   if (params)
1973     ap.params = *params;
1974   else
1975     gst_allocation_params_init (&ap.params);
1976
1977   g_array_append_val (array, ap);
1978 }
1979
1980 /**
1981  * gst_query_get_n_allocation_params:
1982  * @query: a GST_QUERY_ALLOCATION type query #GstQuery
1983  *
1984  * Retrieve the number of values currently stored in the
1985  * allocator params array of the query's structure.
1986  *
1987  * If no memory allocator is specified, the downstream element can handle
1988  * the default memory allocator. The first memory allocator in the query
1989  * should be generic and allow mapping to system memory, all following
1990  * allocators should be ordered by preference with the preferred one first.
1991  *
1992  * Returns: the allocator array size as a #guint.
1993  */
1994 guint
1995 gst_query_get_n_allocation_params (GstQuery * query)
1996 {
1997   GArray *array;
1998   GstStructure *structure;
1999
2000   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, 0);
2001
2002   structure = GST_QUERY_STRUCTURE (query);
2003   array = ensure_array (structure, GST_QUARK (ALLOCATOR),
2004       sizeof (AllocationParam), (GDestroyNotify) allocation_param_free);
2005
2006   return array->len;
2007 }
2008
2009 /**
2010  * gst_query_parse_nth_allocation_param:
2011  * @query: a GST_QUERY_ALLOCATION type query #GstQuery
2012  * @index: position in the allocator array to read
2013  * @allocator: (out) (transfer full) (allow-none): variable to hold the result
2014  * @params: (out) (allow-none): parameters for the allocator
2015  *
2016  * Parse an available query and get the allocator and its params
2017  * at @index of the allocator array.
2018  */
2019 void
2020 gst_query_parse_nth_allocation_param (GstQuery * query, guint index,
2021     GstAllocator ** allocator, GstAllocationParams * params)
2022 {
2023   GArray *array;
2024   GstStructure *structure;
2025   AllocationParam *ap;
2026
2027   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
2028
2029   structure = GST_QUERY_STRUCTURE (query);
2030   array = ensure_array (structure, GST_QUARK (ALLOCATOR),
2031       sizeof (AllocationParam), (GDestroyNotify) allocation_param_free);
2032   g_return_if_fail (index < array->len);
2033
2034   ap = &g_array_index (array, AllocationParam, index);
2035
2036   if (allocator)
2037     if ((*allocator = ap->allocator))
2038       gst_object_ref (*allocator);
2039   if (params)
2040     *params = ap->params;
2041 }
2042
2043 /**
2044  * gst_query_set_nth_allocation_param:
2045  * @query: a GST_QUERY_ALLOCATION type query #GstQuery
2046  * @index: position in the allocator array to set
2047  * @allocator: (transfer none) (allow-none): new allocator to set
2048  * @params: (transfer none) (allow-none): parameters for the allocator
2049  *
2050  * Parse an available query and get the allocator and its params
2051  * at @index of the allocator array.
2052  */
2053 void
2054 gst_query_set_nth_allocation_param (GstQuery * query, guint index,
2055     GstAllocator * allocator, const GstAllocationParams * params)
2056 {
2057   GArray *array;
2058   GstStructure *structure;
2059   AllocationParam *old, ap;
2060
2061   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
2062
2063   structure = GST_QUERY_STRUCTURE (query);
2064   array = ensure_array (structure, GST_QUARK (ALLOCATOR),
2065       sizeof (AllocationParam), (GDestroyNotify) allocation_param_free);
2066   g_return_if_fail (index < array->len);
2067
2068   old = &g_array_index (array, AllocationParam, index);
2069   allocation_param_free (old);
2070
2071   if ((ap.allocator = allocator))
2072     gst_object_ref (allocator);
2073   if (params)
2074     ap.params = *params;
2075   else
2076     gst_allocation_params_init (&ap.params);
2077
2078   g_array_index (array, AllocationParam, index) = ap;
2079 }
2080
2081 /**
2082  * gst_query_remove_nth_allocation_param:
2083  * @query: a GST_QUERY_ALLOCATION type query #GstQuery
2084  * @index: position in the allocation param array to remove
2085  *
2086  * Remove the allocation param at @index of the allocation param array.
2087  *
2088  * Since: 1.2
2089  */
2090 void
2091 gst_query_remove_nth_allocation_param (GstQuery * query, guint index)
2092 {
2093   GArray *array;
2094   GstStructure *structure;
2095
2096   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
2097   g_return_if_fail (gst_query_is_writable (query));
2098
2099   structure = GST_QUERY_STRUCTURE (query);
2100   array =
2101       ensure_array (structure, GST_QUARK (ALLOCATOR), sizeof (AllocationParam),
2102       (GDestroyNotify) allocation_param_free);
2103   g_return_if_fail (index < array->len);
2104
2105   g_array_remove_index (array, index);
2106 }
2107
2108 /**
2109  * gst_query_new_scheduling:
2110  *
2111  * Constructs a new query object for querying the scheduling properties.
2112  *
2113  * Free-function: gst_query_unref()
2114  *
2115  * Returns: (transfer full): a new #GstQuery
2116  */
2117 GstQuery *
2118 gst_query_new_scheduling (void)
2119 {
2120   GstQuery *query;
2121   GstStructure *structure;
2122
2123   structure = gst_structure_new_id (GST_QUARK (QUERY_SCHEDULING),
2124       GST_QUARK (FLAGS), GST_TYPE_SCHEDULING_FLAGS, 0,
2125       GST_QUARK (MINSIZE), G_TYPE_INT, 1,
2126       GST_QUARK (MAXSIZE), G_TYPE_INT, -1,
2127       GST_QUARK (ALIGN), G_TYPE_INT, 0, NULL);
2128   query = gst_query_new_custom (GST_QUERY_SCHEDULING, structure);
2129
2130   return query;
2131 }
2132
2133 /**
2134  * gst_query_set_scheduling:
2135  * @query: A valid #GstQuery of type GST_QUERY_SCHEDULING.
2136  * @flags: #GstSchedulingFlags
2137  * @minsize: the suggested minimum size of pull requests
2138  * @maxsize: the suggested maximum size of pull requests
2139  * @align: the suggested alignment of pull requests
2140  *
2141  * Set the scheduling properties.
2142  */
2143 void
2144 gst_query_set_scheduling (GstQuery * query, GstSchedulingFlags flags,
2145     gint minsize, gint maxsize, gint align)
2146 {
2147   GstStructure *structure;
2148
2149   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SCHEDULING);
2150   g_return_if_fail (gst_query_is_writable (query));
2151
2152   structure = GST_QUERY_STRUCTURE (query);
2153   gst_structure_id_set (structure,
2154       GST_QUARK (FLAGS), GST_TYPE_SCHEDULING_FLAGS, flags,
2155       GST_QUARK (MINSIZE), G_TYPE_INT, minsize,
2156       GST_QUARK (MAXSIZE), G_TYPE_INT, maxsize,
2157       GST_QUARK (ALIGN), G_TYPE_INT, align, NULL);
2158 }
2159
2160 /**
2161  * gst_query_parse_scheduling:
2162  * @query: A valid #GstQuery of type GST_QUERY_SCHEDULING.
2163  * @flags: (out) (allow-none): #GstSchedulingFlags
2164  * @minsize: (out) (allow-none): the suggested minimum size of pull requests
2165  * @maxsize: (out) (allow-none): the suggested maximum size of pull requests:
2166  * @align: (out) (allow-none): the suggested alignment of pull requests
2167  *
2168  * Set the scheduling properties.
2169  */
2170 void
2171 gst_query_parse_scheduling (GstQuery * query, GstSchedulingFlags * flags,
2172     gint * minsize, gint * maxsize, gint * align)
2173 {
2174   GstStructure *structure;
2175
2176   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SCHEDULING);
2177
2178   structure = GST_QUERY_STRUCTURE (query);
2179   gst_structure_id_get (structure,
2180       GST_QUARK (FLAGS), GST_TYPE_SCHEDULING_FLAGS, flags,
2181       GST_QUARK (MINSIZE), G_TYPE_INT, minsize,
2182       GST_QUARK (MAXSIZE), G_TYPE_INT, maxsize,
2183       GST_QUARK (ALIGN), G_TYPE_INT, align, NULL);
2184 }
2185
2186 /**
2187  * gst_query_add_scheduling_mode:
2188  * @query: a GST_QUERY_SCHEDULING type query #GstQuery
2189  * @mode: a #GstPadMode
2190  *
2191  * Add @mode as one of the supported scheduling modes to @query.
2192  */
2193 void
2194 gst_query_add_scheduling_mode (GstQuery * query, GstPadMode mode)
2195 {
2196   GstStructure *structure;
2197   GArray *array;
2198
2199   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SCHEDULING);
2200   g_return_if_fail (gst_query_is_writable (query));
2201
2202   structure = GST_QUERY_STRUCTURE (query);
2203   array =
2204       ensure_array (structure, GST_QUARK (MODES), sizeof (GstPadMode), NULL);
2205
2206   g_array_append_val (array, mode);
2207 }
2208
2209 /**
2210  * gst_query_get_n_scheduling_modes:
2211  * @query: a GST_QUERY_SCHEDULING type query #GstQuery
2212  *
2213  * Retrieve the number of values currently stored in the
2214  * scheduling mode array of the query's structure.
2215  *
2216  * Returns: the scheduling mode array size as a #guint.
2217  */
2218 guint
2219 gst_query_get_n_scheduling_modes (GstQuery * query)
2220 {
2221   GArray *array;
2222   GstStructure *structure;
2223
2224   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SCHEDULING, 0);
2225
2226   structure = GST_QUERY_STRUCTURE (query);
2227   array =
2228       ensure_array (structure, GST_QUARK (MODES), sizeof (GstPadMode), NULL);
2229
2230   return array->len;
2231 }
2232
2233 /**
2234  * gst_query_parse_nth_scheduling_mode:
2235  * @query: a GST_QUERY_SCHEDULING type query #GstQuery
2236  * @index: position in the scheduling modes array to read
2237  *
2238  * Parse an available query and get the scheduling mode
2239  * at @index of the scheduling modes array.
2240  *
2241  * Returns: a #GstPadMode of the scheduling mode at @index.
2242  */
2243 GstPadMode
2244 gst_query_parse_nth_scheduling_mode (GstQuery * query, guint index)
2245 {
2246   GstStructure *structure;
2247   GArray *array;
2248
2249   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SCHEDULING,
2250       GST_PAD_MODE_NONE);
2251
2252   structure = GST_QUERY_STRUCTURE (query);
2253   array =
2254       ensure_array (structure, GST_QUARK (MODES), sizeof (GstPadMode), NULL);
2255   g_return_val_if_fail (index < array->len, GST_PAD_MODE_NONE);
2256
2257   return g_array_index (array, GstPadMode, index);
2258 }
2259
2260 /**
2261  * gst_query_has_scheduling_mode:
2262  * @query: a GST_QUERY_SCHEDULING type query #GstQuery
2263  * @mode: the scheduling mode
2264  *
2265  * Check if @query has scheduling mode set.
2266  *
2267  * > When checking if upstream supports pull mode, it is usually not
2268  * > enough to just check for GST_PAD_MODE_PULL with this function, you
2269  * > also want to check whether the scheduling flags returned by
2270  * > gst_query_parse_scheduling() have the seeking flag set (meaning
2271  * > random access is supported, not only sequential pulls).
2272  *
2273  * Returns: %TRUE when @mode is in the list of scheduling modes.
2274  */
2275 gboolean
2276 gst_query_has_scheduling_mode (GstQuery * query, GstPadMode mode)
2277 {
2278   GstStructure *structure;
2279   GArray *array;
2280   guint i, len;
2281
2282   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SCHEDULING, FALSE);
2283
2284   structure = GST_QUERY_STRUCTURE (query);
2285   array =
2286       ensure_array (structure, GST_QUARK (MODES), sizeof (GstPadMode), NULL);
2287
2288   len = array->len;
2289   for (i = 0; i < len; i++) {
2290     if (mode == g_array_index (array, GstPadMode, i))
2291       return TRUE;
2292   }
2293   return FALSE;
2294 }
2295
2296 /**
2297  * gst_query_has_scheduling_mode_with_flags:
2298  * @query: a GST_QUERY_SCHEDULING type query #GstQuery
2299  * @mode: the scheduling mode
2300  * @flags: #GstSchedulingFlags
2301  *
2302  * Check if @query has scheduling mode set and @flags is set in
2303  * query scheduling flags.
2304  *
2305  * Returns: %TRUE when @mode is in the list of scheduling modes
2306  *    and @flags are compatible with query flags.
2307  */
2308 gboolean
2309 gst_query_has_scheduling_mode_with_flags (GstQuery * query, GstPadMode mode,
2310     GstSchedulingFlags flags)
2311 {
2312   GstSchedulingFlags sched_flags;
2313
2314   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SCHEDULING, FALSE);
2315
2316   gst_query_parse_scheduling (query, &sched_flags, NULL, NULL, NULL);
2317
2318   return ((flags & sched_flags) == flags) &&
2319       gst_query_has_scheduling_mode (query, mode);
2320 }
2321
2322 /**
2323  * gst_query_new_accept_caps:
2324  * @caps: a fixed #GstCaps
2325  *
2326  * Constructs a new query object for querying if @caps are accepted.
2327  *
2328  * Free-function: gst_query_unref()
2329  *
2330  * Returns: (transfer full): a new #GstQuery
2331  */
2332 GstQuery *
2333 gst_query_new_accept_caps (GstCaps * caps)
2334 {
2335   GstQuery *query;
2336   GstStructure *structure;
2337
2338   g_return_val_if_fail (gst_caps_is_fixed (caps), NULL);
2339
2340   structure = gst_structure_new_id (GST_QUARK (QUERY_ACCEPT_CAPS),
2341       GST_QUARK (CAPS), GST_TYPE_CAPS, caps,
2342       GST_QUARK (RESULT), G_TYPE_BOOLEAN, FALSE, NULL);
2343   query = gst_query_new_custom (GST_QUERY_ACCEPT_CAPS, structure);
2344
2345   return query;
2346 }
2347
2348 /**
2349  * gst_query_parse_accept_caps:
2350  * @query: The query to parse
2351  * @caps: (out) (transfer none): A pointer to the caps
2352  *
2353  * Get the caps from @query. The caps remains valid as long as @query remains
2354  * valid.
2355  */
2356 void
2357 gst_query_parse_accept_caps (GstQuery * query, GstCaps ** caps)
2358 {
2359   GstStructure *structure;
2360
2361   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ACCEPT_CAPS);
2362   g_return_if_fail (caps != NULL);
2363
2364   structure = GST_QUERY_STRUCTURE (query);
2365   *caps = g_value_get_boxed (gst_structure_id_get_value (structure,
2366           GST_QUARK (CAPS)));
2367 }
2368
2369 /**
2370  * gst_query_set_accept_caps_result:
2371  * @query: a GST_QUERY_ACCEPT_CAPS type query #GstQuery
2372  * @result: the result to set
2373  *
2374  * Set @result as the result for the @query.
2375  */
2376 void
2377 gst_query_set_accept_caps_result (GstQuery * query, gboolean result)
2378 {
2379   GstStructure *structure;
2380
2381   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ACCEPT_CAPS);
2382   g_return_if_fail (gst_query_is_writable (query));
2383
2384   structure = GST_QUERY_STRUCTURE (query);
2385   gst_structure_id_set (structure,
2386       GST_QUARK (RESULT), G_TYPE_BOOLEAN, result, NULL);
2387 }
2388
2389 /**
2390  * gst_query_parse_accept_caps_result:
2391  * @query: a GST_QUERY_ACCEPT_CAPS type query #GstQuery
2392  * @result: location for the result
2393  *
2394  * Parse the result from @query and store in @result.
2395  */
2396 void
2397 gst_query_parse_accept_caps_result (GstQuery * query, gboolean * result)
2398 {
2399   GstStructure *structure;
2400
2401   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ACCEPT_CAPS);
2402
2403   structure = GST_QUERY_STRUCTURE (query);
2404   gst_structure_id_get (structure,
2405       GST_QUARK (RESULT), G_TYPE_BOOLEAN, result, NULL);
2406 }
2407
2408 /**
2409  * gst_query_new_caps:
2410  * @filter: a filter
2411  *
2412  * Constructs a new query object for querying the caps.
2413  *
2414  * The CAPS query should return the allowable caps for a pad in the context
2415  * of the element's state, its link to other elements, and the devices or files
2416  * it has opened. These caps must be a subset of the pad template caps. In the
2417  * NULL state with no links, the CAPS query should ideally return the same caps
2418  * as the pad template. In rare circumstances, an object property can affect
2419  * the caps returned by the CAPS query, but this is discouraged.
2420  *
2421  * For most filters, the caps returned by CAPS query is directly affected by the
2422  * allowed caps on other pads. For demuxers and decoders, the caps returned by
2423  * the srcpad's getcaps function is directly related to the stream data. Again,
2424  * the CAPS query should return the most specific caps it reasonably can, since this
2425  * helps with autoplugging.
2426  *
2427  * The @filter is used to restrict the result caps, only the caps matching
2428  * @filter should be returned from the CAPS query. Specifying a filter might
2429  * greatly reduce the amount of processing an element needs to do.
2430  *
2431  * Free-function: gst_query_unref()
2432  *
2433  * Returns: (transfer full): a new #GstQuery
2434  */
2435 GstQuery *
2436 gst_query_new_caps (GstCaps * filter)
2437 {
2438   GstQuery *query;
2439   GstStructure *structure;
2440
2441   structure = gst_structure_new_id (GST_QUARK (QUERY_CAPS),
2442       GST_QUARK (FILTER), GST_TYPE_CAPS, filter,
2443       GST_QUARK (CAPS), GST_TYPE_CAPS, NULL, NULL);
2444   query = gst_query_new_custom (GST_QUERY_CAPS, structure);
2445
2446   return query;
2447 }
2448
2449 /**
2450  * gst_query_parse_caps:
2451  * @query: The query to parse
2452  * @filter: (out) (transfer none): A pointer to the caps filter
2453  *
2454  * Get the filter from the caps @query. The caps remains valid as long as
2455  * @query remains valid.
2456  */
2457 void
2458 gst_query_parse_caps (GstQuery * query, GstCaps ** filter)
2459 {
2460   GstStructure *structure;
2461
2462   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CAPS);
2463   g_return_if_fail (filter != NULL);
2464
2465   structure = GST_QUERY_STRUCTURE (query);
2466   *filter = g_value_get_boxed (gst_structure_id_get_value (structure,
2467           GST_QUARK (FILTER)));
2468 }
2469
2470 /**
2471  * gst_query_set_caps_result:
2472  * @query: The query to use
2473  * @caps: (in): A pointer to the caps
2474  *
2475  * Set the @caps result in @query.
2476  */
2477 void
2478 gst_query_set_caps_result (GstQuery * query, GstCaps * caps)
2479 {
2480   GstStructure *structure;
2481
2482   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CAPS);
2483   g_return_if_fail (gst_query_is_writable (query));
2484
2485   structure = GST_QUERY_STRUCTURE (query);
2486   gst_structure_id_set (structure, GST_QUARK (CAPS), GST_TYPE_CAPS, caps, NULL);
2487 }
2488
2489 /**
2490  * gst_query_parse_caps_result:
2491  * @query: The query to parse
2492  * @caps: (out) (transfer none): A pointer to the caps
2493  *
2494  * Get the caps result from @query. The caps remains valid as long as
2495  * @query remains valid.
2496  */
2497 void
2498 gst_query_parse_caps_result (GstQuery * query, GstCaps ** caps)
2499 {
2500   GstStructure *structure;
2501
2502   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CAPS);
2503   g_return_if_fail (caps != NULL);
2504
2505   structure = GST_QUERY_STRUCTURE (query);
2506   *caps = g_value_get_boxed (gst_structure_id_get_value (structure,
2507           GST_QUARK (CAPS)));
2508 }
2509
2510 #if 0
2511 void
2512 gst_query_intersect_caps_result (GstQuery * query, GstCaps * filter,
2513     GstCapsIntersectMode mode)
2514 {
2515   GstCaps *res, *caps = NULL;
2516
2517   gst_query_parse_caps_result (query, &caps);
2518   res = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
2519   gst_query_set_caps_result (query, res);
2520   gst_caps_unref (res);
2521 }
2522 #endif
2523
2524 /**
2525  * gst_query_new_drain:
2526  *
2527  * Constructs a new query object for querying the drain state.
2528  *
2529  * Free-function: gst_query_unref()
2530  *
2531  * Returns: (transfer full): a new #GstQuery
2532  */
2533 GstQuery *
2534 gst_query_new_drain (void)
2535 {
2536   GstQuery *query;
2537   GstStructure *structure;
2538
2539   structure = gst_structure_new_id_empty (GST_QUARK (QUERY_DRAIN));
2540   query = gst_query_new_custom (GST_QUERY_DRAIN, structure);
2541
2542   return query;
2543 }
2544
2545 /**
2546  * gst_query_new_context:
2547  * @context_type: Context type to query
2548  *
2549  * Constructs a new query object for querying the pipeline-local context.
2550  *
2551  * Free-function: gst_query_unref()
2552  *
2553  * Returns: (transfer full): a new #GstQuery
2554  *
2555  * Since: 1.2
2556  */
2557 GstQuery *
2558 gst_query_new_context (const gchar * context_type)
2559 {
2560   GstQuery *query;
2561   GstStructure *structure;
2562
2563   g_return_val_if_fail (context_type != NULL, NULL);
2564
2565   structure = gst_structure_new_id (GST_QUARK (QUERY_CONTEXT),
2566       GST_QUARK (CONTEXT_TYPE), G_TYPE_STRING, context_type, NULL);
2567   query = gst_query_new_custom (GST_QUERY_CONTEXT, structure);
2568
2569   return query;
2570 }
2571
2572 /**
2573  * gst_query_set_context:
2574  * @query: a #GstQuery with query type GST_QUERY_CONTEXT
2575  * @context: the requested #GstContext
2576  *
2577  * Answer a context query by setting the requested context.
2578  *
2579  * Since: 1.2
2580  */
2581 void
2582 gst_query_set_context (GstQuery * query, GstContext * context)
2583 {
2584   GstStructure *s;
2585   const gchar *context_type;
2586
2587   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CONTEXT);
2588
2589   gst_query_parse_context_type (query, &context_type);
2590   g_return_if_fail (strcmp (gst_context_get_context_type (context),
2591           context_type) == 0);
2592
2593   s = GST_QUERY_STRUCTURE (query);
2594
2595   gst_structure_id_set (s,
2596       GST_QUARK (CONTEXT), GST_TYPE_CONTEXT, context, NULL);
2597 }
2598
2599 /**
2600  * gst_query_parse_context:
2601  * @query: The query to parse
2602  * @context: (out) (transfer none): A pointer to store the #GstContext
2603  *
2604  * Get the context from the context @query. The context remains valid as long as
2605  * @query remains valid.
2606  *
2607  * Since: 1.2
2608  */
2609 void
2610 gst_query_parse_context (GstQuery * query, GstContext ** context)
2611 {
2612   GstStructure *structure;
2613   const GValue *v;
2614
2615   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CONTEXT);
2616   g_return_if_fail (context != NULL);
2617
2618   structure = GST_QUERY_STRUCTURE (query);
2619   v = gst_structure_id_get_value (structure, GST_QUARK (CONTEXT));
2620   if (v)
2621     *context = g_value_get_boxed (v);
2622   else
2623     *context = NULL;
2624 }
2625
2626 /**
2627  * gst_query_parse_context_type:
2628  * @query: a GST_QUERY_CONTEXT type query
2629  * @context_type: (out) (transfer none) (allow-none): the context type, or %NULL
2630  *
2631  * Parse a context type from an existing GST_QUERY_CONTEXT query.
2632  *
2633  * Returns: a #gboolean indicating if the parsing succeeded.
2634  *
2635  * Since: 1.2
2636  */
2637 gboolean
2638 gst_query_parse_context_type (GstQuery * query, const gchar ** context_type)
2639 {
2640   GstStructure *structure;
2641   const GValue *value;
2642
2643   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CONTEXT, FALSE);
2644
2645   structure = GST_QUERY_STRUCTURE (query);
2646
2647   if (context_type) {
2648     value = gst_structure_id_get_value (structure, GST_QUARK (CONTEXT_TYPE));
2649     *context_type = g_value_get_string (value);
2650   }
2651
2652   return TRUE;
2653 }