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>
6 * gstquery.c: GstQueryType registration
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.
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.
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.
25 * @short_description: Dynamically register new query types and parse results
26 * @see_also: #GstPad, #GstElement
28 * GstQuery functions are used to register a new query types to the gstreamer core.
29 * Query types can be used to perform queries on pads and elements.
31 * Query answer can be parsed using gst_query_parse_xxx() helpers.
35 #include "gst_private.h"
37 #include "gstenumtypes.h"
39 GST_DEBUG_CATEGORY_STATIC (gst_query_debug);
40 #define GST_CAT_DEFAULT gst_query_debug
42 static void gst_query_init (GTypeInstance * instance, gpointer g_class);
43 static void gst_query_class_init (gpointer g_class, gpointer class_data);
44 static void gst_query_finalize (GstQuery * query);
45 static GstQuery *_gst_query_copy (GstQuery * query);
48 static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
49 static GList *_gst_queries = NULL;
50 static GHashTable *_nick_to_query = NULL;
51 static GHashTable *_query_type_to_nick = NULL;
52 static guint32 _n_values = 1; /* we start from 1 because 0 reserved for NONE */
54 static GstQueryTypeDefinition standard_definitions[] = {
55 {GST_QUERY_POSITION, "position", "Current Position"},
56 {GST_QUERY_LATENCY, "latency", "Latency"},
57 {GST_QUERY_JITTER, "jitter", "Jitter"},
58 {GST_QUERY_RATE, "rate", "Configured rate 1000000 = 1"},
59 {GST_QUERY_SEEKING, "seeking", "Seeking capabilities and parameters"},
60 {GST_QUERY_CONVERT, "convert", "Converting between formats"},
61 {GST_QUERY_FORMATS, "formats", "Supported formats for conversion"},
66 _gst_query_initialize (void)
68 GstQueryTypeDefinition *standards = standard_definitions;
70 GST_CAT_INFO (GST_CAT_GST_INIT, "init queries");
72 GST_DEBUG_CATEGORY_INIT (gst_query_debug, "query", 0, "query system");
74 g_static_mutex_lock (&mutex);
75 if (_nick_to_query == NULL) {
76 _nick_to_query = g_hash_table_new (g_str_hash, g_str_equal);
77 _query_type_to_nick = g_hash_table_new (NULL, NULL);
80 while (standards->nick) {
81 g_hash_table_insert (_nick_to_query, standards->nick, standards);
82 g_hash_table_insert (_query_type_to_nick,
83 GINT_TO_POINTER (standards->value), standards);
85 _gst_queries = g_list_append (_gst_queries, standards);
89 g_static_mutex_unlock (&mutex);
91 gst_query_get_type ();
95 gst_query_get_type (void)
97 static GType _gst_query_type;
99 if (G_UNLIKELY (_gst_query_type == 0)) {
100 static const GTypeInfo query_info = {
101 sizeof (GstQueryClass),
104 gst_query_class_init,
113 _gst_query_type = g_type_register_static (GST_TYPE_MINI_OBJECT,
114 "GstQuery", &query_info, 0);
116 return _gst_query_type;
120 gst_query_class_init (gpointer g_class, gpointer class_data)
122 GstQueryClass *query_class = GST_QUERY_CLASS (g_class);
124 query_class->mini_object_class.copy =
125 (GstMiniObjectCopyFunction) _gst_query_copy;
126 query_class->mini_object_class.finalize =
127 (GstMiniObjectFinalizeFunction) gst_query_finalize;
132 gst_query_finalize (GstQuery * query)
134 g_return_if_fail (query != NULL);
136 if (query->structure) {
137 gst_structure_set_parent_refcount (query->structure, NULL);
138 gst_structure_free (query->structure);
143 gst_query_init (GTypeInstance * instance, gpointer g_class)
149 _gst_query_copy (GstQuery * query)
153 copy = (GstQuery *) gst_mini_object_new (GST_TYPE_QUERY);
155 copy->type = query->type;
157 if (query->structure) {
158 copy->structure = gst_structure_copy (query->structure);
159 gst_structure_set_parent_refcount (copy->structure,
160 &query->mini_object.refcount);
169 * gst_query_type_register:
170 * @nick: The nick of the new query
171 * @description: The description of the new query
173 * Create a new GstQueryType based on the nick or return an
174 * allrady registered query with that nick
176 * Returns: A new GstQueryType or an already registered query
177 * with the same nick.
180 gst_query_type_register (const gchar * nick, const gchar * description)
182 GstQueryTypeDefinition *query;
185 g_return_val_if_fail (nick != NULL, 0);
186 g_return_val_if_fail (description != NULL, 0);
188 lookup = gst_query_type_get_by_nick (nick);
189 if (lookup != GST_QUERY_NONE)
192 query = g_new0 (GstQueryTypeDefinition, 1);
193 query->value = _n_values;
194 query->nick = g_strdup (nick);
195 query->description = g_strdup (description);
197 g_static_mutex_lock (&mutex);
198 g_hash_table_insert (_nick_to_query, query->nick, query);
199 g_hash_table_insert (_query_type_to_nick, GINT_TO_POINTER (query->value),
201 _gst_queries = g_list_append (_gst_queries, query);
203 g_static_mutex_unlock (&mutex);
209 * gst_query_type_get_by_nick:
210 * @nick: The nick of the query
212 * Return the query registered with the given nick.
214 * Returns: The query with @nick or GST_QUERY_NONE
215 * if the query was not registered.
218 gst_query_type_get_by_nick (const gchar * nick)
220 GstQueryTypeDefinition *query;
222 g_return_val_if_fail (nick != NULL, 0);
224 g_static_mutex_lock (&mutex);
225 query = g_hash_table_lookup (_nick_to_query, nick);
226 g_static_mutex_unlock (&mutex);
231 return GST_QUERY_NONE;
235 * gst_query_types_contains:
236 * @types: The query array to search
237 * @type: the querytype to find
239 * See if the given query is inside the query array.
241 * Returns: TRUE if the query is found inside the array
244 gst_query_types_contains (const GstQueryType * types, GstQueryType type)
260 * gst_query_type_get_details:
261 * @type: The query to get details of
263 * Get details about the given query.
265 * Returns: The #GstQueryTypeDefinition for @query or NULL on failure.
267 const GstQueryTypeDefinition *
268 gst_query_type_get_details (GstQueryType type)
270 const GstQueryTypeDefinition *result;
272 g_static_mutex_lock (&mutex);
273 result = g_hash_table_lookup (_query_type_to_nick, GINT_TO_POINTER (type));
274 g_static_mutex_unlock (&mutex);
280 * gst_query_type_iterate_definitions:
282 * Get an Iterator of all the registered query types. The querytype
283 * definition is read only.
285 * Returns: A #GstIterator of #GstQueryTypeDefinition.
288 gst_query_type_iterate_definitions (void)
292 g_static_mutex_lock (&mutex);
293 result = gst_iterator_new_list (g_static_mutex_get_mutex (&mutex),
294 &_n_values, &_gst_queries, NULL, NULL, NULL);
295 g_static_mutex_unlock (&mutex);
301 gst_query_new (GstQueryType type, GstStructure * structure)
305 query = (GstQuery *) gst_mini_object_new (GST_TYPE_QUERY);
307 GST_DEBUG ("creating new query %p %d", query, type);
312 query->structure = structure;
313 gst_structure_set_parent_refcount (query->structure,
314 &query->mini_object.refcount);
316 query->structure = NULL;
323 * gst_query_new_position:
324 * @format: the default #GstFormat for the new query
326 * Constructs a new query stream position query object. Use gst_query_unref()
329 * Returns: A new #GstQuery
332 gst_query_new_position (GstFormat format)
335 GstStructure *structure;
337 structure = gst_structure_new ("GstQueryPosition",
338 "format", GST_TYPE_FORMAT, format,
339 "cur", G_TYPE_INT64, (gint64) - 1,
340 "end", G_TYPE_INT64, (gint64) - 1, NULL);
341 query = gst_query_new (GST_QUERY_POSITION, structure);
347 * gst_query_set_position:
348 * @query: the query to fill in
349 * @format: the requested #GstFormat
350 * @cur: the current position
351 * @end: the end position
353 * Answer a position query by setting the requested values.
356 gst_query_set_position (GstQuery * query, GstFormat format,
357 gint64 cur, gint64 end)
359 GstStructure *structure;
361 g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_POSITION);
363 structure = gst_query_get_structure (query);
364 gst_structure_set (structure,
365 "format", GST_TYPE_FORMAT, format,
366 "cur", G_TYPE_INT64, cur, "end", G_TYPE_INT64, end, NULL);
370 * gst_query_parse_position:
371 * @query: the query to fill in
372 * @format: the requested #GstFormat or NULL for the default (used when creating
374 * @cur: the storage for the current position
375 * @end: the storage for the end position
377 * Parse a position query answer.
380 gst_query_parse_position (GstQuery * query, GstFormat * format,
381 gint64 * cur, gint64 * end)
383 GstStructure *structure;
385 g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_POSITION);
387 structure = gst_query_get_structure (query);
389 *format = g_value_get_enum (gst_structure_get_value (structure, "format"));
391 *cur = g_value_get_int64 (gst_structure_get_value (structure, "cur"));
393 *end = g_value_get_int64 (gst_structure_get_value (structure, "end"));
397 gst_query_new_convert (GstFormat src_fmt, gint64 value, GstFormat dest_fmt)
400 GstStructure *structure;
402 g_return_val_if_fail (value >= 0, NULL);
404 structure = gst_structure_new ("GstQueryConvert",
405 "src_format", GST_TYPE_FORMAT, src_fmt,
406 "src_value", G_TYPE_INT64, value,
407 "dest_format", GST_TYPE_FORMAT, dest_fmt,
408 "dest_value", G_TYPE_INT64, (gint64) - 1, NULL);
409 query = gst_query_new (GST_QUERY_CONVERT, structure);
415 gst_query_set_convert (GstQuery * query, GstFormat src_format, gint64 src_value,
416 GstFormat dest_format, gint64 dest_value)
418 GstStructure *structure;
420 g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CONVERT);
422 structure = gst_query_get_structure (query);
423 gst_structure_set (structure,
424 "src_format", GST_TYPE_FORMAT, src_format,
425 "src_value", G_TYPE_INT64, src_value,
426 "dest_format", GST_TYPE_FORMAT, dest_format,
427 "dest_value", G_TYPE_INT64, dest_value, NULL);
431 gst_query_parse_convert (GstQuery * query, GstFormat * src_format,
432 gint64 * src_value, GstFormat * dest_format, gint64 * dest_value)
434 GstStructure *structure;
436 g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CONVERT);
438 structure = gst_query_get_structure (query);
441 g_value_get_enum (gst_structure_get_value (structure, "src_format"));
444 g_value_get_int64 (gst_structure_get_value (structure, "src_value"));
447 g_value_get_enum (gst_structure_get_value (structure, "dest_format"));
450 g_value_get_int64 (gst_structure_get_value (structure, "dest_value"));
455 gst_query_new_application (GstQueryType type, GstStructure * structure)
457 g_return_val_if_fail (gst_query_type_get_details (type) != NULL, NULL);
458 g_return_val_if_fail (structure != NULL, NULL);
460 return gst_query_new (type, structure);
464 gst_query_get_structure (GstQuery * query)
466 g_return_val_if_fail (GST_IS_QUERY (query), NULL);
468 return query->structure;