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