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