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