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