74874a97597ac600426181f64f31f5a4df99960d
[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 #include "gst_private.h"
65 #include "gstinfo.h"
66 #include "gstquery.h"
67 #include "gstvalue.h"
68 #include "gstenumtypes.h"
69 #include "gstquark.h"
70 #include "gsturi.h"
71 #include "gstbufferpool.h"
72
73 GST_DEBUG_CATEGORY_STATIC (gst_query_debug);
74 #define GST_CAT_DEFAULT gst_query_debug
75
76 static GType _gst_query_type = 0;
77
78 typedef struct
79 {
80   GstQuery query;
81
82   GstStructure *structure;
83 } GstQueryImpl;
84
85 #define GST_QUERY_STRUCTURE(q)  (((GstQueryImpl *)(q))->structure)
86
87 static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
88 static GList *_gst_queries = NULL;
89 static GHashTable *_nick_to_query = NULL;
90 static GHashTable *_query_type_to_nick = NULL;
91 static guint32 _n_values = 1;   /* we start from 1 because 0 reserved for NONE */
92
93 static GstQueryTypeDefinition standard_definitions[] = {
94   {GST_QUERY_POSITION, "position", "Current position", 0},
95   {GST_QUERY_DURATION, "duration", "Total duration", 0},
96   {GST_QUERY_LATENCY, "latency", "Latency", 0},
97   {GST_QUERY_JITTER, "jitter", "Jitter", 0},
98   {GST_QUERY_RATE, "rate", "Configured rate 1000000 = 1", 0},
99   {GST_QUERY_SEEKING, "seeking", "Seeking capabilities and parameters", 0},
100   {GST_QUERY_SEGMENT, "segment", "currently configured segment", 0},
101   {GST_QUERY_CONVERT, "convert", "Converting between formats", 0},
102   {GST_QUERY_FORMATS, "formats", "Supported formats for conversion", 0},
103   {GST_QUERY_BUFFERING, "buffering", "Buffering status", 0},
104   {GST_QUERY_CUSTOM, "custom", "Custom query", 0},
105   {GST_QUERY_URI, "uri", "URI of the source or sink", 0},
106   {GST_QUERY_ALLOCATION, "allocation", "Allocation properties", 0},
107   {GST_QUERY_SCHEDULING, "scheduling", "Scheduling properties", 0},
108   {GST_QUERY_NONE, NULL, NULL, 0}
109 };
110
111 GST_DEFINE_MINI_OBJECT (GstQuery, gst_query);
112
113 void
114 _priv_gst_query_initialize (void)
115 {
116   GstQueryTypeDefinition *standards = standard_definitions;
117
118   GST_CAT_INFO (GST_CAT_GST_INIT, "init queries");
119
120   GST_DEBUG_CATEGORY_INIT (gst_query_debug, "query", 0, "query system");
121
122   g_static_mutex_lock (&mutex);
123   if (_nick_to_query == NULL) {
124     _nick_to_query = g_hash_table_new (g_str_hash, g_str_equal);
125     _query_type_to_nick = g_hash_table_new (NULL, NULL);
126   }
127
128   while (standards->nick) {
129     standards->quark = g_quark_from_static_string (standards->nick);
130     g_hash_table_insert (_nick_to_query, (gpointer) standards->nick, standards);
131     g_hash_table_insert (_query_type_to_nick,
132         GINT_TO_POINTER (standards->value), standards);
133
134     _gst_queries = g_list_append (_gst_queries, standards);
135     standards++;
136     _n_values++;
137   }
138   g_static_mutex_unlock (&mutex);
139
140   _gst_query_type = gst_query_get_type ();
141 }
142
143 /**
144  * gst_query_type_get_name:
145  * @query: the query type
146  *
147  * Get a printable name for the given query type. Do not modify or free.
148  *
149  * Returns: a reference to the static name of the query.
150  */
151 const gchar *
152 gst_query_type_get_name (GstQueryType query)
153 {
154   const GstQueryTypeDefinition *def;
155
156   def = gst_query_type_get_details (query);
157   g_return_val_if_fail (def != NULL, NULL);
158
159   return def->nick;
160 }
161
162 /**
163  * gst_query_type_to_quark:
164  * @query: the query type
165  *
166  * Get the unique quark for the given query type.
167  *
168  * Returns: the quark associated with the query type
169  */
170 GQuark
171 gst_query_type_to_quark (GstQueryType query)
172 {
173   const GstQueryTypeDefinition *def;
174
175   def = gst_query_type_get_details (query);
176   g_return_val_if_fail (def != NULL, 0);
177
178   return def->quark;
179 }
180
181 /**
182  * gst_query_type_register:
183  * @nick: The nick of the new query
184  * @description: The description of the new query
185  *
186  * Create a new GstQueryType based on the nick or return an
187  * already registered query with that nick
188  *
189  * Returns: A new GstQueryType or an already registered query
190  * with the same nick.
191  */
192 GstQueryType
193 gst_query_type_register (const gchar * nick, const gchar * description)
194 {
195   GstQueryTypeDefinition *query;
196   GstQueryType lookup;
197
198   g_return_val_if_fail (nick != NULL, GST_QUERY_NONE);
199   g_return_val_if_fail (description != NULL, GST_QUERY_NONE);
200
201   lookup = gst_query_type_get_by_nick (nick);
202   if (lookup != GST_QUERY_NONE)
203     return lookup;
204
205   query = g_slice_new (GstQueryTypeDefinition);
206   query->value = (GstQueryType) _n_values;
207   query->nick = g_strdup (nick);
208   query->description = g_strdup (description);
209   query->quark = g_quark_from_static_string (query->nick);
210
211   g_static_mutex_lock (&mutex);
212   g_hash_table_insert (_nick_to_query, (gpointer) query->nick, query);
213   g_hash_table_insert (_query_type_to_nick, GINT_TO_POINTER (query->value),
214       query);
215   _gst_queries = g_list_append (_gst_queries, query);
216   _n_values++;
217   g_static_mutex_unlock (&mutex);
218
219   return query->value;
220 }
221
222 /**
223  * gst_query_type_get_by_nick:
224  * @nick: The nick of the query
225  *
226  * Get the query type registered with @nick.
227  *
228  * Returns: The query registered with @nick or #GST_QUERY_NONE
229  * if the query was not registered.
230  */
231 GstQueryType
232 gst_query_type_get_by_nick (const gchar * nick)
233 {
234   GstQueryTypeDefinition *query;
235
236   g_return_val_if_fail (nick != NULL, GST_QUERY_NONE);
237
238   g_static_mutex_lock (&mutex);
239   query = g_hash_table_lookup (_nick_to_query, nick);
240   g_static_mutex_unlock (&mutex);
241
242   if (query != NULL)
243     return query->value;
244   else
245     return GST_QUERY_NONE;
246 }
247
248 /**
249  * gst_query_types_contains:
250  * @types: The query array to search
251  * @type: the #GstQueryType to find
252  *
253  * See if the given #GstQueryType is inside the @types query types array.
254  *
255  * Returns: TRUE if the type is found inside the array
256  */
257 gboolean
258 gst_query_types_contains (const GstQueryType * types, GstQueryType type)
259 {
260   if (!types)
261     return FALSE;
262
263   while (*types) {
264     if (*types == type)
265       return TRUE;
266
267     types++;
268   }
269   return FALSE;
270 }
271
272
273 /**
274  * gst_query_type_get_details:
275  * @type: a #GstQueryType
276  *
277  * Get details about the given #GstQueryType.
278  *
279  * Returns: The #GstQueryTypeDefinition for @type or NULL on failure.
280  */
281 const GstQueryTypeDefinition *
282 gst_query_type_get_details (GstQueryType type)
283 {
284   const GstQueryTypeDefinition *result;
285
286   g_static_mutex_lock (&mutex);
287   result = g_hash_table_lookup (_query_type_to_nick, GINT_TO_POINTER (type));
288   g_static_mutex_unlock (&mutex);
289
290   return result;
291 }
292
293 /**
294  * gst_query_type_iterate_definitions:
295  *
296  * Get a #GstIterator of all the registered query types. The definitions
297  * iterated over are read only.
298  *
299  * Free-function: gst_iterator_free
300  *
301  * Returns: (transfer full): a #GstIterator of #GstQueryTypeDefinition.
302  */
303 GstIterator *
304 gst_query_type_iterate_definitions (void)
305 {
306   GstIterator *result;
307
308   g_static_mutex_lock (&mutex);
309   /* FIXME: register a boxed type for GstQueryTypeDefinition */
310   result = gst_iterator_new_list (G_TYPE_POINTER,
311       g_static_mutex_get_mutex (&mutex), &_n_values, &_gst_queries, NULL, NULL);
312   g_static_mutex_unlock (&mutex);
313
314   return result;
315 }
316
317 static void
318 _gst_query_free (GstQuery * query)
319 {
320   GstStructure *s;
321
322   g_return_if_fail (query != NULL);
323
324   s = GST_QUERY_STRUCTURE (query);
325   if (s) {
326     gst_structure_set_parent_refcount (s, NULL);
327     gst_structure_free (s);
328   }
329
330   g_slice_free1 (GST_MINI_OBJECT_SIZE (query), query);
331 }
332
333 static GstQuery *gst_query_new (GstQueryType type, GstStructure * structure);
334
335 static GstQuery *
336 _gst_query_copy (GstQuery * query)
337 {
338   GstQuery *copy;
339
340   copy = gst_query_new (query->type, GST_QUERY_STRUCTURE (query));
341
342   return copy;
343 }
344
345 static GstQuery *
346 gst_query_new (GstQueryType type, GstStructure * structure)
347 {
348   GstQueryImpl *query;
349
350   query = g_slice_new0 (GstQueryImpl);
351
352   gst_mini_object_init (GST_MINI_OBJECT_CAST (query),
353       _gst_query_type, sizeof (GstQueryImpl));
354
355   query->query.mini_object.copy = (GstMiniObjectCopyFunction) _gst_query_copy;
356   query->query.mini_object.free = (GstMiniObjectFreeFunction) _gst_query_free;
357
358   GST_DEBUG ("creating new query %p %d", query, type);
359
360   GST_QUERY_TYPE (query) = type;
361   query->structure = structure;
362
363   if (structure)
364     gst_structure_set_parent_refcount (structure,
365         &query->query.mini_object.refcount);
366
367   return GST_QUERY_CAST (query);
368 }
369
370 /**
371  * gst_query_new_position:
372  * @format: the default #GstFormat for the new query
373  *
374  * Constructs a new query stream position query object. Use gst_query_unref()
375  * when done with it. A position query is used to query the current position
376  * of playback in the streams, in some format.
377  *
378  * Free-function: gst_query_unref
379  *
380  * Returns: (transfer full): a new #GstQuery
381  */
382 GstQuery *
383 gst_query_new_position (GstFormat format)
384 {
385   GstQuery *query;
386   GstStructure *structure;
387
388   structure = gst_structure_id_new (GST_QUARK (QUERY_POSITION),
389       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
390       GST_QUARK (CURRENT), G_TYPE_INT64, G_GINT64_CONSTANT (-1), NULL);
391
392   query = gst_query_new (GST_QUERY_POSITION, structure);
393
394   return query;
395 }
396
397 /**
398  * gst_query_set_position:
399  * @query: a #GstQuery with query type GST_QUERY_POSITION
400  * @format: the requested #GstFormat
401  * @cur: the position to set
402  *
403  * Answer a position query by setting the requested value in the given format.
404  */
405 void
406 gst_query_set_position (GstQuery * query, GstFormat format, gint64 cur)
407 {
408   GstStructure *s;
409
410   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_POSITION);
411
412   s = GST_QUERY_STRUCTURE (query);
413   g_return_if_fail (format == g_value_get_enum (gst_structure_id_get_value (s,
414               GST_QUARK (FORMAT))));
415
416   gst_structure_id_set (s,
417       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
418       GST_QUARK (CURRENT), G_TYPE_INT64, cur, NULL);
419 }
420
421 /**
422  * gst_query_parse_position:
423  * @query: a #GstQuery
424  * @format: (out) (allow-none): the storage for the #GstFormat of the
425  *     position values (may be NULL)
426  * @cur: (out) (allow-none): the storage for the current position (may be NULL)
427  *
428  * Parse a position query, writing the format into @format, and the position
429  * into @cur, if the respective parameters are non-NULL.
430  */
431 void
432 gst_query_parse_position (GstQuery * query, GstFormat * format, gint64 * cur)
433 {
434   GstStructure *structure;
435
436   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_POSITION);
437
438   structure = GST_QUERY_STRUCTURE (query);
439   if (format)
440     *format =
441         (GstFormat) g_value_get_enum (gst_structure_id_get_value (structure,
442             GST_QUARK (FORMAT)));
443   if (cur)
444     *cur = g_value_get_int64 (gst_structure_id_get_value (structure,
445             GST_QUARK (CURRENT)));
446 }
447
448
449 /**
450  * gst_query_new_duration:
451  * @format: the #GstFormat for this duration query
452  *
453  * Constructs a new stream duration query object to query in the given format.
454  * Use gst_query_unref() when done with it. A duration query will give the
455  * total length of the stream.
456  *
457  * Free-function: gst_query_unref
458  *
459  * Returns: (transfer full): a new #GstQuery
460  */
461 GstQuery *
462 gst_query_new_duration (GstFormat format)
463 {
464   GstQuery *query;
465   GstStructure *structure;
466
467   structure = gst_structure_id_new (GST_QUARK (QUERY_DURATION),
468       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
469       GST_QUARK (DURATION), G_TYPE_INT64, G_GINT64_CONSTANT (-1), NULL);
470
471   query = gst_query_new (GST_QUERY_DURATION, structure);
472
473   return query;
474 }
475
476 /**
477  * gst_query_set_duration:
478  * @query: a #GstQuery
479  * @format: the #GstFormat for the duration
480  * @duration: the duration of the stream
481  *
482  * Answer a duration query by setting the requested value in the given format.
483  */
484 void
485 gst_query_set_duration (GstQuery * query, GstFormat format, gint64 duration)
486 {
487   GstStructure *s;
488
489   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_DURATION);
490
491   s = GST_QUERY_STRUCTURE (query);
492   g_return_if_fail (format == g_value_get_enum (gst_structure_id_get_value (s,
493               GST_QUARK (FORMAT))));
494   gst_structure_id_set (s, GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
495       GST_QUARK (DURATION), G_TYPE_INT64, duration, NULL);
496 }
497
498 /**
499  * gst_query_parse_duration:
500  * @query: a #GstQuery
501  * @format: (out) (allow-none): the storage for the #GstFormat of the duration
502  *     value, or NULL.
503  * @duration: (out) (allow-none): the storage for the total duration, or NULL.
504  *
505  * Parse a duration query answer. Write the format of the duration into @format,
506  * and the value into @duration, if the respective variables are non-NULL.
507  */
508 void
509 gst_query_parse_duration (GstQuery * query, GstFormat * format,
510     gint64 * duration)
511 {
512   GstStructure *structure;
513
514   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_DURATION);
515
516   structure = GST_QUERY_STRUCTURE (query);
517   if (format)
518     *format =
519         (GstFormat) g_value_get_enum (gst_structure_id_get_value (structure,
520             GST_QUARK (FORMAT)));
521   if (duration)
522     *duration = g_value_get_int64 (gst_structure_id_get_value (structure,
523             GST_QUARK (DURATION)));
524 }
525
526 /**
527  * gst_query_new_latency:
528  *
529  * Constructs a new latency query object.
530  * Use gst_query_unref() when done with it. A latency query is usually performed
531  * by sinks to compensate for additional latency introduced by elements in the
532  * pipeline.
533  *
534  * Free-function: gst_query_unref
535  *
536  * Returns: (transfer full): a #GstQuery
537  *
538  * Since: 0.10.12
539  */
540 GstQuery *
541 gst_query_new_latency (void)
542 {
543   GstQuery *query;
544   GstStructure *structure;
545
546   structure = gst_structure_id_new (GST_QUARK (QUERY_LATENCY),
547       GST_QUARK (LIVE), G_TYPE_BOOLEAN, FALSE,
548       GST_QUARK (MIN_LATENCY), G_TYPE_UINT64, G_GUINT64_CONSTANT (0),
549       GST_QUARK (MAX_LATENCY), G_TYPE_UINT64, G_GUINT64_CONSTANT (-1), NULL);
550
551   query = gst_query_new (GST_QUERY_LATENCY, structure);
552
553   return query;
554 }
555
556 /**
557  * gst_query_set_latency:
558  * @query: a #GstQuery
559  * @live: if there is a live element upstream
560  * @min_latency: the minimal latency of the live element
561  * @max_latency: the maximal latency of the live element
562  *
563  * Answer a latency query by setting the requested values in the given format.
564  *
565  * Since: 0.10.12
566  */
567 void
568 gst_query_set_latency (GstQuery * query, gboolean live,
569     GstClockTime min_latency, GstClockTime max_latency)
570 {
571   GstStructure *structure;
572
573   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_LATENCY);
574
575   structure = GST_QUERY_STRUCTURE (query);
576   gst_structure_id_set (structure,
577       GST_QUARK (LIVE), G_TYPE_BOOLEAN, live,
578       GST_QUARK (MIN_LATENCY), G_TYPE_UINT64, min_latency,
579       GST_QUARK (MAX_LATENCY), G_TYPE_UINT64, max_latency, NULL);
580 }
581
582 /**
583  * gst_query_parse_latency:
584  * @query: a #GstQuery
585  * @live: (out) (allow-none): storage for live or NULL
586  * @min_latency: (out) (allow-none): the storage for the min latency or NULL
587  * @max_latency: (out) (allow-none): the storage for the max latency or NULL
588  *
589  * Parse a latency query answer.
590  *
591  * Since: 0.10.12
592  */
593 void
594 gst_query_parse_latency (GstQuery * query, gboolean * live,
595     GstClockTime * min_latency, GstClockTime * max_latency)
596 {
597   GstStructure *structure;
598
599   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_LATENCY);
600
601   structure = GST_QUERY_STRUCTURE (query);
602   if (live)
603     *live =
604         g_value_get_boolean (gst_structure_id_get_value (structure,
605             GST_QUARK (LIVE)));
606   if (min_latency)
607     *min_latency = g_value_get_uint64 (gst_structure_id_get_value (structure,
608             GST_QUARK (MIN_LATENCY)));
609   if (max_latency)
610     *max_latency = g_value_get_uint64 (gst_structure_id_get_value (structure,
611             GST_QUARK (MAX_LATENCY)));
612 }
613
614 /**
615  * gst_query_new_convert:
616  * @src_format: the source #GstFormat for the new query
617  * @value: the value to convert
618  * @dest_format: the target #GstFormat
619  *
620  * Constructs a new convert query object. Use gst_query_unref()
621  * when done with it. A convert query is used to ask for a conversion between
622  * one format and another.
623  *
624  * Free-function: gst_query_unref
625  *
626  * Returns: (transfer full): a #GstQuery
627  */
628 GstQuery *
629 gst_query_new_convert (GstFormat src_format, gint64 value,
630     GstFormat dest_format)
631 {
632   GstQuery *query;
633   GstStructure *structure;
634
635   structure = gst_structure_id_new (GST_QUARK (QUERY_CONVERT),
636       GST_QUARK (SRC_FORMAT), GST_TYPE_FORMAT, src_format,
637       GST_QUARK (SRC_VALUE), G_TYPE_INT64, value,
638       GST_QUARK (DEST_FORMAT), GST_TYPE_FORMAT, dest_format,
639       GST_QUARK (DEST_VALUE), G_TYPE_INT64, G_GINT64_CONSTANT (-1), NULL);
640
641   query = gst_query_new (GST_QUERY_CONVERT, structure);
642
643   return query;
644 }
645
646 /**
647  * gst_query_set_convert:
648  * @query: a #GstQuery
649  * @src_format: the source #GstFormat
650  * @src_value: the source value
651  * @dest_format: the destination #GstFormat
652  * @dest_value: the destination value
653  *
654  * Answer a convert query by setting the requested values.
655  */
656 void
657 gst_query_set_convert (GstQuery * query, GstFormat src_format, gint64 src_value,
658     GstFormat dest_format, gint64 dest_value)
659 {
660   GstStructure *structure;
661
662   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CONVERT);
663
664   structure = GST_QUERY_STRUCTURE (query);
665   gst_structure_id_set (structure,
666       GST_QUARK (SRC_FORMAT), GST_TYPE_FORMAT, src_format,
667       GST_QUARK (SRC_VALUE), G_TYPE_INT64, src_value,
668       GST_QUARK (DEST_FORMAT), GST_TYPE_FORMAT, dest_format,
669       GST_QUARK (DEST_VALUE), G_TYPE_INT64, dest_value, NULL);
670 }
671
672 /**
673  * gst_query_parse_convert:
674  * @query: a #GstQuery
675  * @src_format: (out) (allow-none): the storage for the #GstFormat of the
676  *     source value, or NULL
677  * @src_value: (out) (allow-none): the storage for the source value, or NULL
678  * @dest_format: (out) (allow-none): the storage for the #GstFormat of the
679  *     destination value, or NULL
680  * @dest_value: (out) (allow-none): the storage for the destination value,
681  *     or NULL
682  *
683  * Parse a convert query answer. Any of @src_format, @src_value, @dest_format,
684  * and @dest_value may be NULL, in which case that value is omitted.
685  */
686 void
687 gst_query_parse_convert (GstQuery * query, GstFormat * src_format,
688     gint64 * src_value, GstFormat * dest_format, gint64 * dest_value)
689 {
690   GstStructure *structure;
691
692   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CONVERT);
693
694   structure = GST_QUERY_STRUCTURE (query);
695   if (src_format)
696     *src_format =
697         (GstFormat) g_value_get_enum (gst_structure_id_get_value (structure,
698             GST_QUARK (SRC_FORMAT)));
699   if (src_value)
700     *src_value = g_value_get_int64 (gst_structure_id_get_value (structure,
701             GST_QUARK (SRC_VALUE)));
702   if (dest_format)
703     *dest_format =
704         (GstFormat) g_value_get_enum (gst_structure_id_get_value (structure,
705             GST_QUARK (DEST_FORMAT)));
706   if (dest_value)
707     *dest_value = g_value_get_int64 (gst_structure_id_get_value (structure,
708             GST_QUARK (DEST_VALUE)));
709 }
710
711 /**
712  * gst_query_new_segment:
713  * @format: the #GstFormat for the new query
714  *
715  * Constructs a new segment query object. Use gst_query_unref()
716  * when done with it. A segment query is used to discover information about the
717  * currently configured segment for playback.
718  *
719  * Free-function: gst_query_unref
720  *
721  * Returns: (transfer full): a new #GstQuery
722  */
723 GstQuery *
724 gst_query_new_segment (GstFormat format)
725 {
726   GstQuery *query;
727   GstStructure *structure;
728
729   structure = gst_structure_id_new (GST_QUARK (QUERY_SEGMENT),
730       GST_QUARK (RATE), G_TYPE_DOUBLE, (gdouble) 0.0,
731       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
732       GST_QUARK (START_VALUE), G_TYPE_INT64, G_GINT64_CONSTANT (-1),
733       GST_QUARK (STOP_VALUE), G_TYPE_INT64, G_GINT64_CONSTANT (-1), NULL);
734
735   query = gst_query_new (GST_QUERY_SEGMENT, structure);
736
737   return query;
738 }
739
740 /**
741  * gst_query_set_segment:
742  * @query: a #GstQuery
743  * @rate: the rate of the segment
744  * @format: the #GstFormat of the segment values (@start_value and @stop_value)
745  * @start_value: the start value
746  * @stop_value: the stop value
747  *
748  * Answer a segment query by setting the requested values. The normal
749  * playback segment of a pipeline is 0 to duration at the default rate of
750  * 1.0. If a seek was performed on the pipeline to play a different
751  * segment, this query will return the range specified in the last seek.
752  *
753  * @start_value and @stop_value will respectively contain the configured
754  * playback range start and stop values expressed in @format.
755  * The values are always between 0 and the duration of the media and
756  * @start_value <= @stop_value. @rate will contain the playback rate. For
757  * negative rates, playback will actually happen from @stop_value to
758  * @start_value.
759  */
760 void
761 gst_query_set_segment (GstQuery * query, gdouble rate, GstFormat format,
762     gint64 start_value, gint64 stop_value)
763 {
764   GstStructure *structure;
765
766   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SEGMENT);
767
768   structure = GST_QUERY_STRUCTURE (query);
769   gst_structure_id_set (structure,
770       GST_QUARK (RATE), G_TYPE_DOUBLE, rate,
771       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
772       GST_QUARK (START_VALUE), G_TYPE_INT64, start_value,
773       GST_QUARK (STOP_VALUE), G_TYPE_INT64, stop_value, NULL);
774 }
775
776 /**
777  * gst_query_parse_segment:
778  * @query: a #GstQuery
779  * @rate: (out) (allow-none): the storage for the rate of the segment, or NULL
780  * @format: (out) (allow-none): the storage for the #GstFormat of the values,
781  *     or NULL
782  * @start_value: (out) (allow-none): the storage for the start value, or NULL
783  * @stop_value: (out) (allow-none): the storage for the stop value, or NULL
784  *
785  * Parse a segment query answer. Any of @rate, @format, @start_value, and
786  * @stop_value may be NULL, which will cause this value to be omitted.
787  *
788  * See gst_query_set_segment() for an explanation of the function arguments.
789  */
790 void
791 gst_query_parse_segment (GstQuery * query, gdouble * rate, GstFormat * format,
792     gint64 * start_value, gint64 * stop_value)
793 {
794   GstStructure *structure;
795
796   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SEGMENT);
797
798   structure = GST_QUERY_STRUCTURE (query);
799   if (rate)
800     *rate = g_value_get_double (gst_structure_id_get_value (structure,
801             GST_QUARK (RATE)));
802   if (format)
803     *format =
804         (GstFormat) g_value_get_enum (gst_structure_id_get_value (structure,
805             GST_QUARK (FORMAT)));
806   if (start_value)
807     *start_value = g_value_get_int64 (gst_structure_id_get_value (structure,
808             GST_QUARK (START_VALUE)));
809   if (stop_value)
810     *stop_value = g_value_get_int64 (gst_structure_id_get_value (structure,
811             GST_QUARK (STOP_VALUE)));
812 }
813
814 /**
815  * gst_query_new_custom:
816  * @type: the query type
817  * @structure: a structure for the query
818  *
819  * Constructs a new custom query object. Use gst_query_unref()
820  * when done with it.
821  *
822  * Free-function: gst_query_unref
823  *
824  * Returns: (transfer full): a new #GstQuery
825  */
826 GstQuery *
827 gst_query_new_custom (GstQueryType type, GstStructure * structure)
828 {
829   g_return_val_if_fail (gst_query_type_get_details (type) != NULL, NULL);
830   g_return_val_if_fail (structure != NULL, NULL);
831
832   return gst_query_new (type, structure);
833 }
834
835 /**
836  * gst_query_get_structure:
837  * @query: a #GstQuery
838  *
839  * Get the structure of a query.
840  *
841  * Returns: (transfer none): the #GstStructure of the query. The structure is
842  *     still owned by the query and will therefore be freed when the query
843  *     is unreffed.
844  */
845 const GstStructure *
846 gst_query_get_structure (GstQuery * query)
847 {
848   g_return_val_if_fail (GST_IS_QUERY (query), NULL);
849
850   return GST_QUERY_STRUCTURE (query);
851 }
852
853 /**
854  * gst_query_writable_structure:
855  * @query: a #GstQuery
856  *
857  * Get the structure of a query.
858  *
859  * Returns: (transfer none): the #GstStructure of the query. The structure is
860  *     still owned by the query and will therefore be freed when the query
861  *     is unreffed.
862  */
863 GstStructure *
864 gst_query_writable_structure (GstQuery * query)
865 {
866   g_return_val_if_fail (GST_IS_QUERY (query), NULL);
867   g_return_val_if_fail (gst_query_is_writable (query), NULL);
868
869   return GST_QUERY_STRUCTURE (query);
870 }
871
872 /**
873  * gst_query_new_seeking:
874  * @format: the default #GstFormat for the new query
875  *
876  * Constructs a new query object for querying seeking properties of
877  * the stream.
878  *
879  * Free-function: gst_query_unref
880  *
881  * Returns: (transfer full): a new #GstQuery
882  */
883 GstQuery *
884 gst_query_new_seeking (GstFormat format)
885 {
886   GstQuery *query;
887   GstStructure *structure;
888
889   structure = gst_structure_id_new (GST_QUARK (QUERY_SEEKING),
890       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
891       GST_QUARK (SEEKABLE), G_TYPE_BOOLEAN, FALSE,
892       GST_QUARK (SEGMENT_START), G_TYPE_INT64, G_GINT64_CONSTANT (-1),
893       GST_QUARK (SEGMENT_END), G_TYPE_INT64, G_GINT64_CONSTANT (-1), NULL);
894
895   query = gst_query_new (GST_QUERY_SEEKING, structure);
896
897   return query;
898 }
899
900 /**
901  * gst_query_set_seeking:
902  * @query: a #GstQuery
903  * @format: the format to set for the @segment_start and @segment_end values
904  * @seekable: the seekable flag to set
905  * @segment_start: the segment_start to set
906  * @segment_end: the segment_end to set
907  *
908  * Set the seeking query result fields in @query.
909  */
910 void
911 gst_query_set_seeking (GstQuery * query, GstFormat format,
912     gboolean seekable, gint64 segment_start, gint64 segment_end)
913 {
914   GstStructure *structure;
915
916   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SEEKING);
917   g_return_if_fail (gst_query_is_writable (query));
918
919   structure = GST_QUERY_STRUCTURE (query);
920   gst_structure_id_set (structure,
921       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
922       GST_QUARK (SEEKABLE), G_TYPE_BOOLEAN, seekable,
923       GST_QUARK (SEGMENT_START), G_TYPE_INT64, segment_start,
924       GST_QUARK (SEGMENT_END), G_TYPE_INT64, segment_end, NULL);
925 }
926
927 /**
928  * gst_query_parse_seeking:
929  * @query: a GST_QUERY_SEEKING type query #GstQuery
930  * @format: (out) (allow-none): the format to set for the @segment_start
931  *     and @segment_end values, or NULL
932  * @seekable: (out) (allow-none): the seekable flag to set, or NULL
933  * @segment_start: (out) (allow-none): the segment_start to set, or NULL
934  * @segment_end: (out) (allow-none): the segment_end to set, or NULL
935  *
936  * Parse a seeking query, writing the format into @format, and
937  * other results into the passed parameters, if the respective parameters
938  * are non-NULL
939  */
940 void
941 gst_query_parse_seeking (GstQuery * query, GstFormat * format,
942     gboolean * seekable, gint64 * segment_start, gint64 * segment_end)
943 {
944   GstStructure *structure;
945
946   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SEEKING);
947
948   structure = GST_QUERY_STRUCTURE (query);
949   if (format)
950     *format =
951         (GstFormat) g_value_get_enum (gst_structure_id_get_value (structure,
952             GST_QUARK (FORMAT)));
953   if (seekable)
954     *seekable = g_value_get_boolean (gst_structure_id_get_value (structure,
955             GST_QUARK (SEEKABLE)));
956   if (segment_start)
957     *segment_start = g_value_get_int64 (gst_structure_id_get_value (structure,
958             GST_QUARK (SEGMENT_START)));
959   if (segment_end)
960     *segment_end = g_value_get_int64 (gst_structure_id_get_value (structure,
961             GST_QUARK (SEGMENT_END)));
962 }
963
964 /**
965  * gst_query_new_formats:
966  *
967  * Constructs a new query object for querying formats of
968  * the stream.
969  *
970  * Free-function: gst_query_unref
971  *
972  * Returns: (transfer full): a new #GstQuery
973  *
974  * Since: 0.10.4
975  */
976 GstQuery *
977 gst_query_new_formats (void)
978 {
979   GstQuery *query;
980   GstStructure *structure;
981
982   structure = gst_structure_id_empty_new (GST_QUARK (QUERY_FORMATS));
983   query = gst_query_new (GST_QUERY_FORMATS, structure);
984
985   return query;
986 }
987
988 static void
989 gst_query_list_add_format (GValue * list, GstFormat format)
990 {
991   GValue item = { 0, };
992
993   g_value_init (&item, GST_TYPE_FORMAT);
994   g_value_set_enum (&item, format);
995   gst_value_list_append_value (list, &item);
996   g_value_unset (&item);
997 }
998
999 /**
1000  * gst_query_set_formats:
1001  * @query: a #GstQuery
1002  * @n_formats: the number of formats to set.
1003  * @...: A number of @GstFormats equal to @n_formats.
1004  *
1005  * Set the formats query result fields in @query. The number of formats passed
1006  * must be equal to @n_formats.
1007  */
1008 void
1009 gst_query_set_formats (GstQuery * query, gint n_formats, ...)
1010 {
1011   va_list ap;
1012   GValue list = { 0, };
1013   gint i;
1014   GstStructure *structure;
1015
1016   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_FORMATS);
1017   g_return_if_fail (gst_query_is_writable (query));
1018
1019   g_value_init (&list, GST_TYPE_LIST);
1020
1021   va_start (ap, n_formats);
1022   for (i = 0; i < n_formats; i++) {
1023     gst_query_list_add_format (&list, va_arg (ap, GstFormat));
1024   }
1025   va_end (ap);
1026
1027   structure = GST_QUERY_STRUCTURE (query);
1028   gst_structure_set_value (structure, "formats", &list);
1029
1030   g_value_unset (&list);
1031
1032 }
1033
1034 /**
1035  * gst_query_set_formatsv:
1036  * @query: a #GstQuery
1037  * @n_formats: the number of formats to set.
1038  * @formats: (in) (array length=n_formats): an array containing @n_formats
1039  *     @GstFormat values.
1040  *
1041  * Set the formats query result fields in @query. The number of formats passed
1042  * in the @formats array must be equal to @n_formats.
1043  *
1044  * Since: 0.10.4
1045  */
1046 void
1047 gst_query_set_formatsv (GstQuery * query, gint n_formats,
1048     const GstFormat * formats)
1049 {
1050   GValue list = { 0, };
1051   gint i;
1052   GstStructure *structure;
1053
1054   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_FORMATS);
1055   g_return_if_fail (gst_query_is_writable (query));
1056
1057   g_value_init (&list, GST_TYPE_LIST);
1058   for (i = 0; i < n_formats; i++) {
1059     gst_query_list_add_format (&list, formats[i]);
1060   }
1061   structure = GST_QUERY_STRUCTURE (query);
1062   gst_structure_set_value (structure, "formats", &list);
1063
1064   g_value_unset (&list);
1065 }
1066
1067 /**
1068  * gst_query_parse_n_formats:
1069  * @query: a #GstQuery
1070  * @n_formats: (out): the number of formats in this query.
1071  *
1072  * Parse the number of formats in the formats @query.
1073  *
1074  * Since: 0.10.4
1075  */
1076 void
1077 gst_query_parse_n_formats (GstQuery * query, guint * n_formats)
1078 {
1079   GstStructure *structure;
1080
1081   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_FORMATS);
1082
1083   if (n_formats) {
1084     const GValue *list;
1085
1086     structure = GST_QUERY_STRUCTURE (query);
1087     list = gst_structure_get_value (structure, "formats");
1088     if (list == NULL)
1089       *n_formats = 0;
1090     else
1091       *n_formats = gst_value_list_get_size (list);
1092   }
1093 }
1094
1095 /**
1096  * gst_query_parse_nth_format:
1097  * @query: a #GstQuery
1098  * @nth: (out): the nth format to retrieve.
1099  * @format: (out): a pointer to store the nth format
1100  *
1101  * Parse the format query and retrieve the @nth format from it into
1102  * @format. If the list contains less elements than @nth, @format will be
1103  * set to GST_FORMAT_UNDEFINED.
1104  */
1105 void
1106 gst_query_parse_nth_format (GstQuery * query, guint nth, GstFormat * format)
1107 {
1108   GstStructure *structure;
1109
1110   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_FORMATS);
1111
1112   if (format) {
1113     const GValue *list;
1114
1115     structure = GST_QUERY_STRUCTURE (query);
1116     list = gst_structure_get_value (structure, "formats");
1117     if (list == NULL) {
1118       *format = GST_FORMAT_UNDEFINED;
1119     } else {
1120       if (nth < gst_value_list_get_size (list)) {
1121         *format =
1122             (GstFormat) g_value_get_enum (gst_value_list_get_value (list, nth));
1123       } else
1124         *format = GST_FORMAT_UNDEFINED;
1125     }
1126   }
1127 }
1128
1129 /**
1130  * gst_query_new_buffering
1131  * @format: the default #GstFormat for the new query
1132  *
1133  * Constructs a new query object for querying the buffering status of
1134  * a stream.
1135  *
1136  * Free-function: gst_query_unref
1137  *
1138  * Returns: (transfer full): a new #GstQuery
1139  *
1140  * Since: 0.10.20
1141  */
1142 GstQuery *
1143 gst_query_new_buffering (GstFormat format)
1144 {
1145   GstQuery *query;
1146   GstStructure *structure;
1147
1148   /* by default, we configure the answer as no buffering with a 100% buffering
1149    * progress */
1150   structure = gst_structure_id_new (GST_QUARK (QUERY_BUFFERING),
1151       GST_QUARK (BUSY), G_TYPE_BOOLEAN, FALSE,
1152       GST_QUARK (BUFFER_PERCENT), G_TYPE_INT, 100,
1153       GST_QUARK (BUFFERING_MODE), GST_TYPE_BUFFERING_MODE, GST_BUFFERING_STREAM,
1154       GST_QUARK (AVG_IN_RATE), G_TYPE_INT, -1,
1155       GST_QUARK (AVG_OUT_RATE), G_TYPE_INT, -1,
1156       GST_QUARK (BUFFERING_LEFT), G_TYPE_INT64, G_GINT64_CONSTANT (0),
1157       GST_QUARK (ESTIMATED_TOTAL), G_TYPE_INT64, G_GINT64_CONSTANT (-1),
1158       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
1159       GST_QUARK (START_VALUE), G_TYPE_INT64, G_GINT64_CONSTANT (-1),
1160       GST_QUARK (STOP_VALUE), G_TYPE_INT64, G_GINT64_CONSTANT (-1), NULL);
1161
1162   query = gst_query_new (GST_QUERY_BUFFERING, structure);
1163
1164   return query;
1165 }
1166
1167 /**
1168  * gst_query_set_buffering_percent
1169  * @query: A valid #GstQuery of type GST_QUERY_BUFFERING.
1170  * @busy: if buffering is busy
1171  * @percent: a buffering percent
1172  *
1173  * Set the percentage of buffered data. This is a value between 0 and 100.
1174  * The @busy indicator is %TRUE when the buffering is in progress.
1175  *
1176  * Since: 0.10.20
1177  */
1178 void
1179 gst_query_set_buffering_percent (GstQuery * query, gboolean busy, gint percent)
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   g_return_if_fail (percent >= 0 && percent <= 100);
1186
1187   structure = GST_QUERY_STRUCTURE (query);
1188   gst_structure_id_set (structure,
1189       GST_QUARK (BUSY), G_TYPE_BOOLEAN, busy,
1190       GST_QUARK (BUFFER_PERCENT), G_TYPE_INT, percent, NULL);
1191 }
1192
1193 /**
1194  * gst_query_parse_buffering_percent
1195  * @query: A valid #GstQuery of type GST_QUERY_BUFFERING.
1196  * @busy: (out) (allow-none): if buffering is busy, or NULL
1197  * @percent: (out) (allow-none): a buffering percent, or NULL
1198  *
1199  * Get the percentage of buffered data. This is a value between 0 and 100.
1200  * The @busy indicator is %TRUE when the buffering is in progress.
1201  *
1202  * Since: 0.10.20
1203  */
1204 void
1205 gst_query_parse_buffering_percent (GstQuery * query, gboolean * busy,
1206     gint * percent)
1207 {
1208   GstStructure *structure;
1209
1210   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING);
1211
1212   structure = GST_QUERY_STRUCTURE (query);
1213   if (busy)
1214     *busy = g_value_get_boolean (gst_structure_id_get_value (structure,
1215             GST_QUARK (BUSY)));
1216   if (percent)
1217     *percent = g_value_get_int (gst_structure_id_get_value (structure,
1218             GST_QUARK (BUFFER_PERCENT)));
1219 }
1220
1221 /**
1222  * gst_query_set_buffering_stats:
1223  * @query: A valid #GstQuery of type GST_QUERY_BUFFERING.
1224  * @mode: a buffering mode
1225  * @avg_in: the average input rate
1226  * @avg_out: the average output rate
1227  * @buffering_left: amount of buffering time left
1228  *
1229  * Configures the buffering stats values in @query.
1230  *
1231  * Since: 0.10.20
1232  */
1233 void
1234 gst_query_set_buffering_stats (GstQuery * query, GstBufferingMode mode,
1235     gint avg_in, gint avg_out, gint64 buffering_left)
1236 {
1237   GstStructure *structure;
1238
1239   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING);
1240   g_return_if_fail (gst_query_is_writable (query));
1241
1242   structure = GST_QUERY_STRUCTURE (query);
1243   gst_structure_id_set (structure,
1244       GST_QUARK (BUFFERING_MODE), GST_TYPE_BUFFERING_MODE, mode,
1245       GST_QUARK (AVG_IN_RATE), G_TYPE_INT, avg_in,
1246       GST_QUARK (AVG_OUT_RATE), G_TYPE_INT, avg_out,
1247       GST_QUARK (BUFFERING_LEFT), G_TYPE_INT64, buffering_left, NULL);
1248 }
1249
1250 /**
1251  * gst_query_parse_buffering_stats:
1252  * @query: A valid #GstQuery of type GST_QUERY_BUFFERING.
1253  * @mode: (out) (allow-none): a buffering mode, or NULL
1254  * @avg_in: (out) (allow-none): the average input rate, or NULL
1255  * @avg_out: (out) (allow-none): the average output rat, or NULLe
1256  * @buffering_left: (out) (allow-none): amount of buffering time left, or NULL
1257  *
1258  * Extracts the buffering stats values from @query.
1259  *
1260  * Since: 0.10.20
1261  */
1262 void
1263 gst_query_parse_buffering_stats (GstQuery * query,
1264     GstBufferingMode * mode, gint * avg_in, gint * avg_out,
1265     gint64 * buffering_left)
1266 {
1267   GstStructure *structure;
1268
1269   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING);
1270
1271   structure = GST_QUERY_STRUCTURE (query);
1272   if (mode)
1273     *mode = (GstBufferingMode)
1274         g_value_get_enum (gst_structure_id_get_value (structure,
1275             GST_QUARK (BUFFERING_MODE)));
1276   if (avg_in)
1277     *avg_in = g_value_get_int (gst_structure_id_get_value (structure,
1278             GST_QUARK (AVG_IN_RATE)));
1279   if (avg_out)
1280     *avg_out = g_value_get_int (gst_structure_id_get_value (structure,
1281             GST_QUARK (AVG_OUT_RATE)));
1282   if (buffering_left)
1283     *buffering_left =
1284         g_value_get_int64 (gst_structure_id_get_value (structure,
1285             GST_QUARK (BUFFERING_LEFT)));
1286 }
1287
1288
1289 /**
1290  * gst_query_set_buffering_range:
1291  * @query: a #GstQuery
1292  * @format: the format to set for the @start and @stop values
1293  * @start: the start to set
1294  * @stop: the stop to set
1295  * @estimated_total: estimated total amount of download time
1296  *
1297  * Set the available query result fields in @query.
1298  *
1299  * Since: 0.10.20
1300  */
1301 void
1302 gst_query_set_buffering_range (GstQuery * query, GstFormat format,
1303     gint64 start, gint64 stop, gint64 estimated_total)
1304 {
1305   GstStructure *structure;
1306
1307   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING);
1308   g_return_if_fail (gst_query_is_writable (query));
1309
1310   structure = GST_QUERY_STRUCTURE (query);
1311   gst_structure_id_set (structure,
1312       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
1313       GST_QUARK (START_VALUE), G_TYPE_INT64, start,
1314       GST_QUARK (STOP_VALUE), G_TYPE_INT64, stop,
1315       GST_QUARK (ESTIMATED_TOTAL), G_TYPE_INT64, estimated_total, NULL);
1316 }
1317
1318 /**
1319  * gst_query_parse_buffering_range:
1320  * @query: a GST_QUERY_BUFFERING type query #GstQuery
1321  * @format: (out) (allow-none): the format to set for the @segment_start
1322  *     and @segment_end values, or NULL
1323  * @start: (out) (allow-none): the start to set, or NULL
1324  * @stop: (out) (allow-none): the stop to set, or NULL
1325  * @estimated_total: (out) (allow-none): estimated total amount of download
1326  *     time, or NULL
1327  *
1328  * Parse an available query, writing the format into @format, and
1329  * other results into the passed parameters, if the respective parameters
1330  * are non-NULL
1331  *
1332  * Since: 0.10.20
1333  */
1334 void
1335 gst_query_parse_buffering_range (GstQuery * query, GstFormat * format,
1336     gint64 * start, gint64 * stop, gint64 * estimated_total)
1337 {
1338   GstStructure *structure;
1339
1340   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING);
1341
1342   structure = GST_QUERY_STRUCTURE (query);
1343   if (format)
1344     *format =
1345         (GstFormat) g_value_get_enum (gst_structure_id_get_value (structure,
1346             GST_QUARK (FORMAT)));
1347   if (start)
1348     *start = g_value_get_int64 (gst_structure_id_get_value (structure,
1349             GST_QUARK (START_VALUE)));
1350   if (stop)
1351     *stop = g_value_get_int64 (gst_structure_id_get_value (structure,
1352             GST_QUARK (STOP_VALUE)));
1353   if (estimated_total)
1354     *estimated_total =
1355         g_value_get_int64 (gst_structure_id_get_value (structure,
1356             GST_QUARK (ESTIMATED_TOTAL)));
1357 }
1358
1359 /**
1360  * gst_query_add_buffering_range
1361  * @query: a GST_QUERY_BUFFERING type query #GstQuery
1362  * @start: start position of the range
1363  * @stop: stop position of the range
1364  *
1365  * Set the buffering-ranges array field in @query. The current last
1366  * start position of the array should be inferior to @start.
1367  *
1368  * Returns: a #gboolean indicating if the range was added or not.
1369  *
1370  * Since: 0.10.31
1371  */
1372 gboolean
1373 gst_query_add_buffering_range (GstQuery * query, gint64 start, gint64 stop)
1374 {
1375   GValueArray *array;
1376   GValue *last_array_value;
1377   const GValue *value;
1378   GValue range_value = { 0 };
1379   GstStructure *structure;
1380
1381   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING, FALSE);
1382   g_return_val_if_fail (gst_query_is_writable (query), FALSE);
1383
1384   if (G_UNLIKELY (start >= stop))
1385     return FALSE;
1386
1387   structure = GST_QUERY_STRUCTURE (query);
1388   value = gst_structure_id_get_value (structure, GST_QUARK (BUFFERING_RANGES));
1389   if (value) {
1390     array = (GValueArray *) g_value_get_boxed (value);
1391     last_array_value = g_value_array_get_nth (array, array->n_values - 1);
1392     if (G_UNLIKELY (start <= gst_value_get_int64_range_min (last_array_value)))
1393       return FALSE;
1394   } else {
1395     GValue new_array_val = { 0, };
1396
1397     array = g_value_array_new (0);
1398
1399     g_value_init (&new_array_val, G_TYPE_VALUE_ARRAY);
1400     g_value_take_boxed (&new_array_val, array);
1401
1402     /* set the value array only once, so we then modify (append to) the
1403      * existing value array owned by the GstStructure / the field's GValue */
1404     gst_structure_id_take_value (structure, GST_QUARK (BUFFERING_RANGES),
1405         &new_array_val);
1406   }
1407
1408   g_value_init (&range_value, GST_TYPE_INT64_RANGE);
1409   gst_value_set_int64_range (&range_value, start, stop);
1410   g_value_array_append (array, &range_value);
1411   /* skip the g_value_unset(&range_value) here, we know it's not needed */
1412
1413   return TRUE;
1414 }
1415
1416 /**
1417  * gst_query_get_n_buffering_ranges
1418  * @query: a GST_QUERY_BUFFERING type query #GstQuery
1419  *
1420  * Retrieve the number of values currently stored in the
1421  * buffered-ranges array of the query's structure.
1422  *
1423  * Returns: the range array size as a #guint.
1424  *
1425  * Since: 0.10.31
1426  */
1427 guint
1428 gst_query_get_n_buffering_ranges (GstQuery * query)
1429 {
1430   GValueArray *array;
1431   const GValue *value;
1432   guint size = 0;
1433   GstStructure *structure;
1434
1435   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING, 0);
1436
1437   structure = GST_QUERY_STRUCTURE (query);
1438   value = gst_structure_id_get_value (structure, GST_QUARK (BUFFERING_RANGES));
1439   if (value) {
1440     array = (GValueArray *) g_value_get_boxed (value);
1441     size = array->n_values;
1442   }
1443   return size;
1444 }
1445
1446
1447 /**
1448  * gst_query_parse_nth_buffering_range
1449  * @query: a GST_QUERY_BUFFERING type query #GstQuery
1450  * @index: position in the buffered-ranges array to read
1451  * @start: (out) (allow-none): the start position to set, or NULL
1452  * @stop: (out) (allow-none): the stop position to set, or NULL
1453  *
1454  * Parse an available query and get the start and stop values stored
1455  * at the @index of the buffered ranges array.
1456  *
1457  * Returns: a #gboolean indicating if the parsing succeeded.
1458  *
1459  * Since: 0.10.31
1460  */
1461 gboolean
1462 gst_query_parse_nth_buffering_range (GstQuery * query, guint index,
1463     gint64 * start, gint64 * stop)
1464 {
1465   const GValue *value;
1466   GValueArray *ranges;
1467   GValue *range_value;
1468   gboolean ret = FALSE;
1469   GstStructure *structure;
1470
1471   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING, ret);
1472
1473   structure = GST_QUERY_STRUCTURE (query);
1474   value = gst_structure_id_get_value (structure, GST_QUARK (BUFFERING_RANGES));
1475   ranges = (GValueArray *) g_value_get_boxed (value);
1476   range_value = g_value_array_get_nth (ranges, index);
1477   if (range_value) {
1478     if (start)
1479       *start = gst_value_get_int64_range_min (range_value);
1480     if (stop)
1481       *stop = gst_value_get_int64_range_max (range_value);
1482     ret = TRUE;
1483   }
1484
1485   return ret;
1486 }
1487
1488
1489 /**
1490  * gst_query_new_uri:
1491  *
1492  * Constructs a new query URI query object. Use gst_query_unref()
1493  * when done with it. An URI query is used to query the current URI
1494  * that is used by the source or sink.
1495  *
1496  * Free-function: gst_query_unref
1497  *
1498  * Returns: (transfer full): a new #GstQuery
1499  *
1500  * Since: 0.10.22
1501  */
1502 GstQuery *
1503 gst_query_new_uri (void)
1504 {
1505   GstQuery *query;
1506   GstStructure *structure;
1507
1508   structure = gst_structure_id_new (GST_QUARK (QUERY_URI),
1509       GST_QUARK (URI), G_TYPE_STRING, NULL, NULL);
1510
1511   query = gst_query_new (GST_QUERY_URI, structure);
1512
1513   return query;
1514 }
1515
1516 /**
1517  * gst_query_set_uri:
1518  * @query: a #GstQuery with query type GST_QUERY_URI
1519  * @uri: the URI to set
1520  *
1521  * Answer a URI query by setting the requested URI.
1522  *
1523  * Since: 0.10.22
1524  */
1525 void
1526 gst_query_set_uri (GstQuery * query, const gchar * uri)
1527 {
1528   GstStructure *structure;
1529
1530   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_URI);
1531   g_return_if_fail (gst_query_is_writable (query));
1532   g_return_if_fail (gst_uri_is_valid (uri));
1533
1534   structure = GST_QUERY_STRUCTURE (query);
1535   gst_structure_id_set (structure, GST_QUARK (URI), G_TYPE_STRING, uri, NULL);
1536 }
1537
1538 /**
1539  * gst_query_parse_uri:
1540  * @query: a #GstQuery
1541  * @uri: (out callee-allocates) (allow-none): the storage for the current URI
1542  *     (may be NULL)
1543  *
1544  * Parse an URI query, writing the URI into @uri as a newly
1545  * allocated string, if the respective parameters are non-NULL.
1546  * Free the string with g_free() after usage.
1547  *
1548  * Since: 0.10.22
1549  */
1550 void
1551 gst_query_parse_uri (GstQuery * query, gchar ** uri)
1552 {
1553   GstStructure *structure;
1554
1555   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_URI);
1556
1557   structure = GST_QUERY_STRUCTURE (query);
1558   if (uri)
1559     *uri = g_value_dup_string (gst_structure_id_get_value (structure,
1560             GST_QUARK (URI)));
1561 }
1562
1563 /**
1564  * gst_query_new_allocation
1565  * @caps: the negotiated caps
1566  * @need_pool: return a pool
1567  *
1568  * Constructs a new query object for querying the allocation properties.
1569  *
1570  * Free-function: gst_query_unref
1571  *
1572  * Returns: (transfer full): a new #GstQuery
1573  */
1574 GstQuery *
1575 gst_query_new_allocation (GstCaps * caps, gboolean need_pool)
1576 {
1577   GstQuery *query;
1578   GstStructure *structure;
1579
1580   structure = gst_structure_id_new (GST_QUARK (QUERY_ALLOCATION),
1581       GST_QUARK (CAPS), GST_TYPE_CAPS, caps,
1582       GST_QUARK (NEED_POOL), G_TYPE_BOOLEAN, need_pool,
1583       GST_QUARK (SIZE), G_TYPE_UINT, 0,
1584       GST_QUARK (MIN_BUFFERS), G_TYPE_UINT, 0,
1585       GST_QUARK (MAX_BUFFERS), G_TYPE_UINT, 0,
1586       GST_QUARK (PREFIX), G_TYPE_UINT, 0,
1587       GST_QUARK (ALIGN), G_TYPE_UINT, 0,
1588       GST_QUARK (POOL), GST_TYPE_BUFFER_POOL, NULL, NULL);
1589
1590   query = gst_query_new (GST_QUERY_ALLOCATION, structure);
1591
1592   return query;
1593 }
1594
1595 void
1596 gst_query_parse_allocation (GstQuery * query, GstCaps ** caps,
1597     gboolean * need_pool)
1598 {
1599   GstStructure *structure;
1600
1601   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
1602
1603   structure = GST_QUERY_STRUCTURE (query);
1604   gst_structure_id_get (structure,
1605       GST_QUARK (CAPS), GST_TYPE_CAPS, caps,
1606       GST_QUARK (NEED_POOL), G_TYPE_BOOLEAN, need_pool, NULL);
1607 }
1608
1609 /**
1610  * gst_query_set_allocation_params
1611  * @query: A valid #GstQuery of type GST_QUERY_ALLOCATION.
1612  * @size: the size
1613  * @min_buffers: the min buffers
1614  * @max_buffers: the max buffers
1615  * @prefix: the prefix
1616  * @alignment: the alignment
1617  * @pool: the #GstBufferPool
1618  *
1619  * Set the allocation parameters in @query.
1620  */
1621 void
1622 gst_query_set_allocation_params (GstQuery * query, guint size,
1623     guint min_buffers, guint max_buffers, guint prefix,
1624     guint alignment, GstBufferPool * pool)
1625 {
1626   GstStructure *structure;
1627
1628   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
1629   g_return_if_fail (gst_query_is_writable (query));
1630   g_return_if_fail (((alignment + 1) & alignment) == 0);
1631   g_return_if_fail (size != 0 || pool == NULL);
1632
1633   structure = GST_QUERY_STRUCTURE (query);
1634   gst_structure_id_set (structure,
1635       GST_QUARK (SIZE), G_TYPE_UINT, size,
1636       GST_QUARK (MIN_BUFFERS), G_TYPE_UINT, min_buffers,
1637       GST_QUARK (MAX_BUFFERS), G_TYPE_UINT, max_buffers,
1638       GST_QUARK (PREFIX), G_TYPE_UINT, prefix,
1639       GST_QUARK (ALIGN), G_TYPE_UINT, alignment,
1640       GST_QUARK (POOL), GST_TYPE_BUFFER_POOL, pool, NULL);
1641 }
1642
1643 /**
1644  * gst_query_parse_allocation_params
1645  * @query: A valid #GstQuery of type GST_QUERY_ALLOCATION.
1646  * @size: the size
1647  * @min_buffers: the min buffers
1648  * @max_buffers: the max buffers
1649  * @prefix: the prefix
1650  * @alignment: the alignment
1651  * @pool: the #GstBufferPool
1652  *
1653  * Get the allocation parameters in @query.
1654  */
1655 void
1656 gst_query_parse_allocation_params (GstQuery * query, guint * size,
1657     guint * min_buffers, guint * max_buffers, guint * prefix,
1658     guint * alignment, GstBufferPool ** pool)
1659 {
1660   GstStructure *structure;
1661
1662   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
1663
1664   structure = GST_QUERY_STRUCTURE (query);
1665   gst_structure_id_get (structure,
1666       GST_QUARK (SIZE), G_TYPE_UINT, size,
1667       GST_QUARK (MIN_BUFFERS), G_TYPE_UINT, min_buffers,
1668       GST_QUARK (MAX_BUFFERS), G_TYPE_UINT, max_buffers,
1669       GST_QUARK (PREFIX), G_TYPE_UINT, prefix,
1670       GST_QUARK (ALIGN), G_TYPE_UINT, alignment,
1671       GST_QUARK (POOL), GST_TYPE_BUFFER_POOL, pool, NULL);
1672 }
1673
1674 /**
1675  * gst_query_add_allocation_meta
1676  * @query: a GST_QUERY_ALLOCATION type query #GstQuery
1677  * @api: the metadata API
1678  *
1679  * Add @api as aone of the supported metadata API to @query.
1680  */
1681 void
1682 gst_query_add_allocation_meta (GstQuery * query, const gchar * api)
1683 {
1684   GValueArray *array;
1685   const GValue *value;
1686   GValue api_value = { 0 };
1687   GstStructure *structure;
1688
1689   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
1690   g_return_if_fail (api != NULL);
1691   g_return_if_fail (gst_query_is_writable (query));
1692
1693   structure = GST_QUERY_STRUCTURE (query);
1694   value = gst_structure_id_get_value (structure, GST_QUARK (META));
1695   if (value) {
1696     array = (GValueArray *) g_value_get_boxed (value);
1697   } else {
1698     GValue new_array_val = { 0, };
1699
1700     array = g_value_array_new (0);
1701
1702     g_value_init (&new_array_val, G_TYPE_VALUE_ARRAY);
1703     g_value_take_boxed (&new_array_val, array);
1704
1705     gst_structure_id_take_value (structure, GST_QUARK (META), &new_array_val);
1706   }
1707
1708   g_value_init (&api_value, G_TYPE_STRING);
1709   g_value_set_string (&api_value, api);
1710   g_value_array_append (array, &api_value);
1711   g_value_unset (&api_value);
1712 }
1713
1714 /**
1715  * gst_query_get_n_allocation_metas:
1716  * @query: a GST_QUERY_ALLOCATION type query #GstQuery
1717  *
1718  * Retrieve the number of values currently stored in the
1719  * meta API array of the query's structure.
1720  *
1721  * Returns: the metadata API array size as a #guint.
1722  */
1723 guint
1724 gst_query_get_n_allocation_metas (GstQuery * query)
1725 {
1726   GValueArray *array;
1727   const GValue *value;
1728   guint size = 0;
1729   GstStructure *structure;
1730
1731   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, 0);
1732
1733   structure = GST_QUERY_STRUCTURE (query);
1734   value = gst_structure_id_get_value (structure, GST_QUARK (META));
1735   if (value) {
1736     array = (GValueArray *) g_value_get_boxed (value);
1737     size = array->n_values;
1738   }
1739   return size;
1740 }
1741
1742 /**
1743  * gst_query_parse_nth_allocation_meta
1744  * @query: a GST_QUERY_ALLOCATION type query #GstQuery
1745  * @index: position in the metadata API array to read
1746  *
1747  * Parse an available query and get the metadata API
1748  * at @index of the metadata API array.
1749  *
1750  * Returns: a #gchar of the metadata API at @index.
1751  */
1752 const gchar *
1753 gst_query_parse_nth_allocation_meta (GstQuery * query, guint index)
1754 {
1755   const GValue *value;
1756   const gchar *ret = NULL;
1757   GstStructure *structure;
1758
1759   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, NULL);
1760
1761   structure = GST_QUERY_STRUCTURE (query);
1762   value = gst_structure_id_get_value (structure, GST_QUARK (META));
1763   if (value) {
1764     GValueArray *meta;
1765     GValue *api_value;
1766
1767     meta = (GValueArray *) g_value_get_boxed (value);
1768     api_value = g_value_array_get_nth (meta, index);
1769
1770     if (api_value)
1771       ret = g_value_get_string (api_value);
1772   }
1773   return ret;
1774 }
1775
1776 /**
1777  * gst_query_has_allocation_meta
1778  * @query: a GST_QUERY_ALLOCATION type query #GstQuery
1779  * @api: the metadata API
1780  *
1781  * Check if @query has metadata @api set.
1782  *
1783  * Returns: TRUE when @api is in the list of metadata.
1784  */
1785 gboolean
1786 gst_query_has_allocation_meta (GstQuery * query, const gchar * api)
1787 {
1788   const GValue *value;
1789   GstStructure *structure;
1790
1791   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, FALSE);
1792   g_return_val_if_fail (api != NULL, FALSE);
1793
1794   structure = GST_QUERY_STRUCTURE (query);
1795   value = gst_structure_id_get_value (structure, GST_QUARK (META));
1796   if (value) {
1797     GValueArray *array;
1798     GValue *api_value;
1799     guint i;
1800
1801     array = (GValueArray *) g_value_get_boxed (value);
1802     for (i = 0; i < array->n_values; i++) {
1803       api_value = g_value_array_get_nth (array, i);
1804       if (!strcmp (api, g_value_get_string (api_value)))
1805         return TRUE;
1806     }
1807   }
1808   return FALSE;
1809 }
1810
1811 /**
1812  * gst_query_add_allocation_memory
1813  * @query: a GST_QUERY_ALLOCATION type query #GstQuery
1814  * @alloc: the memory allocator
1815  *
1816  * Add @alloc as a supported memory allocator.
1817  */
1818 void
1819 gst_query_add_allocation_memory (GstQuery * query, const gchar * alloc)
1820 {
1821   GValueArray *array;
1822   const GValue *value;
1823   GValue alloc_value = { 0 };
1824   GstStructure *structure;
1825
1826   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
1827   g_return_if_fail (gst_query_is_writable (query));
1828
1829   structure = GST_QUERY_STRUCTURE (query);
1830   value = gst_structure_id_get_value (structure, GST_QUARK (ALLOCATOR));
1831   if (value) {
1832     array = (GValueArray *) g_value_get_boxed (value);
1833   } else {
1834     GValue new_array_val = { 0, };
1835
1836     array = g_value_array_new (0);
1837
1838     g_value_init (&new_array_val, G_TYPE_VALUE_ARRAY);
1839     g_value_take_boxed (&new_array_val, array);
1840
1841     gst_structure_id_take_value (structure, GST_QUARK (ALLOCATOR),
1842         &new_array_val);
1843   }
1844
1845   g_value_init (&alloc_value, G_TYPE_STRING);
1846   g_value_set_string (&alloc_value, alloc);
1847   g_value_array_append (array, &alloc_value);
1848   g_value_unset (&alloc_value);
1849 }
1850
1851 /**
1852  * gst_query_get_n_allocation_memories:
1853  * @query: a GST_QUERY_ALLOCATION type query #GstQuery
1854  *
1855  * Retrieve the number of values currently stored in the
1856  * allocator array of the query's structure.
1857  *
1858  * If no memory allocator is specified, the downstream element can handle
1859  * the default memory allocator.
1860  *
1861  * Returns: the allocator array size as a #guint.
1862  */
1863 guint
1864 gst_query_get_n_allocation_memories (GstQuery * query)
1865 {
1866   GValueArray *array;
1867   const GValue *value;
1868   guint size = 0;
1869   GstStructure *structure;
1870
1871   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, 0);
1872
1873   structure = GST_QUERY_STRUCTURE (query);
1874   value = gst_structure_id_get_value (structure, GST_QUARK (ALLOCATOR));
1875   if (value) {
1876     array = (GValueArray *) g_value_get_boxed (value);
1877     size = array->n_values;
1878   }
1879   return size;
1880 }
1881
1882 /**
1883  * gst_query_parse_nth_allocation_memory
1884  * @query: a GST_QUERY_ALLOCATION type query #GstQuery
1885  * @index: position in the allocator array to read
1886  *
1887  * Parse an available query and get the alloctor
1888  * at @index of the allocator array.
1889  *
1890  * Returns: the name of the allocator at @index.
1891  */
1892 const gchar *
1893 gst_query_parse_nth_allocation_memory (GstQuery * query, guint index)
1894 {
1895   const GValue *value;
1896   const gchar *ret = NULL;
1897   GstStructure *structure;
1898
1899   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, NULL);
1900
1901   structure = GST_QUERY_STRUCTURE (query);
1902   value = gst_structure_id_get_value (structure, GST_QUARK (ALLOCATOR));
1903   if (value) {
1904     GValueArray *memory;
1905     GValue *alloc_value;
1906
1907     memory = (GValueArray *) g_value_get_boxed (value);
1908     alloc_value = g_value_array_get_nth (memory, index);
1909
1910     if (alloc_value)
1911       ret = g_value_get_string (alloc_value);
1912   }
1913   return ret;
1914 }
1915
1916 /**
1917  * gst_query_new_scheduling
1918  *
1919  * Constructs a new query object for querying the scheduling properties.
1920  *
1921  * Free-function: gst_query_unref
1922  *
1923  * Returns: (transfer full): a new #GstQuery
1924  */
1925 GstQuery *
1926 gst_query_new_scheduling (void)
1927 {
1928   GstQuery *query;
1929   GstStructure *structure;
1930
1931   structure = gst_structure_id_new (GST_QUARK (QUERY_SCHEDULING),
1932       GST_QUARK (PULL_MODE), G_TYPE_BOOLEAN, FALSE,
1933       GST_QUARK (RANDOM_ACCESS), G_TYPE_BOOLEAN, FALSE,
1934       GST_QUARK (SEQUENTIAL), G_TYPE_BOOLEAN, TRUE,
1935       GST_QUARK (MINSIZE), G_TYPE_INT, 1,
1936       GST_QUARK (MAXSIZE), G_TYPE_INT, -1,
1937       GST_QUARK (ALIGN), G_TYPE_INT, 1, NULL);
1938   query = gst_query_new (GST_QUERY_SCHEDULING, structure);
1939
1940   return query;
1941 }
1942
1943 /**
1944  * gst_query_set_scheduling
1945  * @query: A valid #GstQuery of type GST_QUERY_SCHEDULING.
1946  * @pull_mode: if pull mode scheduling is supported
1947  * @random_access: if random access is possible
1948  * @sequential: if sequential access is recommended
1949  * @minsize: the suggested minimum size of pull requests
1950  * @maxsize the suggested maximum size of pull requests:
1951  * @align: the suggested alignment of pull requests
1952  *
1953  * Set the scheduling properties.
1954  */
1955 void
1956 gst_query_set_scheduling (GstQuery * query, gboolean pull_mode,
1957     gboolean random_access, gboolean sequential,
1958     gint minsize, gint maxsize, gint align)
1959 {
1960   GstStructure *structure;
1961
1962   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SCHEDULING);
1963   g_return_if_fail (gst_query_is_writable (query));
1964
1965   structure = GST_QUERY_STRUCTURE (query);
1966   gst_structure_id_set (structure,
1967       GST_QUARK (PULL_MODE), G_TYPE_BOOLEAN, pull_mode,
1968       GST_QUARK (RANDOM_ACCESS), G_TYPE_BOOLEAN, random_access,
1969       GST_QUARK (SEQUENTIAL), G_TYPE_BOOLEAN, sequential,
1970       GST_QUARK (MINSIZE), G_TYPE_INT, minsize,
1971       GST_QUARK (MAXSIZE), G_TYPE_INT, maxsize,
1972       GST_QUARK (ALIGN), G_TYPE_INT, align, NULL);
1973 }
1974
1975 /**
1976  * gst_query_parse_scheduling
1977  * @query: A valid #GstQuery of type GST_QUERY_SCHEDULING.
1978  * @pull_mode: if pull mode scheduling is supported
1979  * @random_access: if random access is possible
1980  * @sequential: if sequential access is recommended
1981  * @minsize: the suggested minimum size of pull requests
1982  * @maxsize the suggested maximum size of pull requests:
1983  * @align: the suggested alignment of pull requests
1984  *
1985  * Set the scheduling properties.
1986  */
1987 void
1988 gst_query_parse_scheduling (GstQuery * query, gboolean * pull_mode,
1989     gboolean * random_access, gboolean * sequential,
1990     gint * minsize, gint * maxsize, gint * align)
1991 {
1992   GstStructure *structure;
1993
1994   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SCHEDULING);
1995
1996   structure = GST_QUERY_STRUCTURE (query);
1997   gst_structure_id_get (structure,
1998       GST_QUARK (PULL_MODE), G_TYPE_BOOLEAN, pull_mode,
1999       GST_QUARK (RANDOM_ACCESS), G_TYPE_BOOLEAN, random_access,
2000       GST_QUARK (SEQUENTIAL), G_TYPE_BOOLEAN, sequential,
2001       GST_QUARK (MINSIZE), G_TYPE_INT, minsize,
2002       GST_QUARK (MAXSIZE), G_TYPE_INT, maxsize,
2003       GST_QUARK (ALIGN), G_TYPE_INT, align, NULL);
2004 }