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