First THREADED backport attempt, focusing on adding locks and making sure the API...
[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
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 #include <string.h>
25
26 #include "gst_private.h"
27 #include "gstquery.h"
28
29 static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
30 static GList *_gst_queries = NULL;
31 static GHashTable *_nick_to_query = NULL;
32 static GHashTable *_query_type_to_nick = NULL;
33 static guint32 _n_values = 1;   /* we start from 1 because 0 reserved for NONE */
34
35 static GstQueryTypeDefinition standard_definitions[] = {
36   {GST_QUERY_TOTAL, "total", "Total length"},
37   {GST_QUERY_POSITION, "position", "Current Position"},
38   {GST_QUERY_LATENCY, "latency", "Latency"},
39   {GST_QUERY_JITTER, "jitter", "Jitter"},
40   {GST_QUERY_START, "start", "Start position of stream"},
41   {GST_QUERY_SEGMENT_END, "segment_end", "End position of the stream"},
42   {GST_QUERY_RATE, "rate", "Configured rate 1000000 = 1"},
43   {0, NULL, NULL}
44 };
45
46 void
47 _gst_query_type_initialize (void)
48 {
49   GstQueryTypeDefinition *standards = standard_definitions;
50
51   g_static_mutex_lock (&mutex);
52   if (_nick_to_query == NULL) {
53     _nick_to_query = g_hash_table_new (g_str_hash, g_str_equal);
54     _query_type_to_nick = g_hash_table_new (NULL, NULL);
55   }
56
57   while (standards->nick) {
58     g_hash_table_insert (_nick_to_query, standards->nick, standards);
59     g_hash_table_insert (_query_type_to_nick,
60         GINT_TO_POINTER (standards->value), standards);
61
62     _gst_queries = g_list_append (_gst_queries, standards);
63     standards++;
64     _n_values++;
65   }
66   g_static_mutex_unlock (&mutex);
67 }
68
69 /**
70  * gst_query_type_register:
71  * @nick: The nick of the new query
72  * @description: The description of the new query
73  *
74  * Create a new GstQueryType based on the nick or return an
75  * allrady registered query with that nick
76  *
77  * Returns: A new GstQueryType or an already registered query
78  * with the same nick.
79  */
80 GstQueryType
81 gst_query_type_register (const gchar * nick, const gchar * description)
82 {
83   GstQueryTypeDefinition *query;
84   GstQueryType lookup;
85
86   g_return_val_if_fail (nick != NULL, 0);
87   g_return_val_if_fail (description != NULL, 0);
88
89   lookup = gst_query_type_get_by_nick (nick);
90   if (lookup != GST_QUERY_NONE)
91     return lookup;
92
93   query = g_new0 (GstQueryTypeDefinition, 1);
94   query->value = _n_values;
95   query->nick = g_strdup (nick);
96   query->description = g_strdup (description);
97
98   g_static_mutex_lock (&mutex);
99   g_hash_table_insert (_nick_to_query, query->nick, query);
100   g_hash_table_insert (_query_type_to_nick, GINT_TO_POINTER (query->value),
101       query);
102   _gst_queries = g_list_append (_gst_queries, query);
103   _n_values++;
104   g_static_mutex_unlock (&mutex);
105
106   return query->value;
107 }
108
109 /**
110  * gst_query_type_get_by_nick:
111  * @nick: The nick of the query
112  *
113  * Return the query registered with the given nick. 
114  *
115  * Returns: The query with @nick or GST_QUERY_NONE
116  * if the query was not registered.
117  */
118 GstQueryType
119 gst_query_type_get_by_nick (const gchar * nick)
120 {
121   GstQueryTypeDefinition *query;
122
123   g_return_val_if_fail (nick != NULL, 0);
124
125   g_static_mutex_lock (&mutex);
126   query = g_hash_table_lookup (_nick_to_query, nick);
127   g_static_mutex_unlock (&mutex);
128
129   if (query != NULL)
130     return query->value;
131   else
132     return GST_QUERY_NONE;
133 }
134
135 /**
136  * gst_query_types_contains:
137  * @types: The query array to search
138  * @type: the querytype to find
139  *
140  * See if the given query is inside the query array.
141  *
142  * Returns: TRUE if the query is found inside the array
143  */
144 gboolean
145 gst_query_types_contains (const GstQueryType * types, GstQueryType type)
146 {
147   if (!types)
148     return FALSE;
149
150   while (*types) {
151     if (*types == type)
152       return TRUE;
153
154     types++;
155   }
156   return FALSE;
157 }
158
159
160 /**
161  * gst_query_type_get_details:
162  * @type: The query to get details of
163  *
164  * Get details about the given query.
165  *
166  * Returns: The #GstQueryTypeDefinition for @query or NULL on failure.
167  */
168 const GstQueryTypeDefinition *
169 gst_query_type_get_details (GstQueryType type)
170 {
171   const GstQueryTypeDefinition *result;
172
173   g_static_mutex_lock (&mutex);
174   result = g_hash_table_lookup (_query_type_to_nick, GINT_TO_POINTER (type));
175   g_static_mutex_unlock (&mutex);
176
177   return result;
178 }
179
180 /**
181  * gst_query_type_iterate_definitions:
182  *
183  * Get an Iterator of all the registered query types. The querytype
184  * definition is read only.
185  *
186  * Returns: A #GstIterator of #GstQueryTypeDefinition.
187  */
188 GstIterator *
189 gst_query_type_iterate_definitions (void)
190 {
191   GstIterator *result;
192
193   g_static_mutex_lock (&mutex);
194   result = gst_iterator_new_list (g_static_mutex_get_mutex (&mutex),
195       &_n_values, &_gst_queries, NULL, NULL, NULL);
196   g_static_mutex_unlock (&mutex);
197
198   return result;
199 }