Mega update of INFO, DEBUG, and ERROR subsystems, renamed with GST_ prefix.
[platform/upstream/gstreamer.git] / gst / gstcaps.c
1 /* GStreamer
2  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3  *                    2000 Wim Taymans <wtay@chello.be>
4  *
5  * gstcaps.c: Element capabilities subsystem
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 //#define GST_DEBUG_ENABLED
24 #include "gst_private.h"
25
26 #include "gstcaps.h"
27 #include "gsttype.h"
28
29 #include "gstpropsprivate.h"
30
31
32 void 
33 _gst_caps_initialize (void) 
34 {
35 }
36
37 static guint16
38 get_type_for_mime (gchar *mime)
39 {
40   guint16 typeid;
41
42   typeid = gst_type_find_by_mime (mime);
43   if (typeid == 0) {
44      GstTypeFactory *factory = g_new0 (GstTypeFactory, 1);
45
46      factory->mime = g_strdup (mime);
47      factory->exts = NULL;
48      factory->typefindfunc = NULL;
49
50      typeid = gst_type_register (factory);
51   }
52   return typeid;
53 }
54
55 /**
56  * gst_caps_new:
57  * @name: the name of this capability
58  * @mime: the mime type to attach to the capability
59  *
60  * create a new capability with the given mime type
61  *
62  * Returns: a new capability
63  */
64 GstCaps*
65 gst_caps_new (gchar *name, gchar *mime)
66 {
67   GstCaps *caps;
68
69   g_return_val_if_fail (mime != NULL, NULL);
70   
71   caps = g_new0 (GstCaps, 1);
72   caps->name = g_strdup (name);
73   caps->id = get_type_for_mime (mime);
74   caps->properties = NULL;
75   
76   return caps;
77 }
78
79 /**
80  * gst_caps_new_with_props:
81  * @name: the name of this capability
82  * @mime: the mime type to attach to the capability
83  * @props: the properties for this capability
84  *
85  * create a new capability with the given mime type
86  * and the given properties
87  *
88  * Returns: a new capability
89  */
90 GstCaps*
91 gst_caps_new_with_props (gchar *name, gchar *mime, GstProps *props)
92 {
93   GstCaps *caps;
94   
95   caps = gst_caps_new (name, mime);
96   caps->properties = props;
97
98   return caps;
99 }
100
101 /**
102  * gst_caps_register:
103  * @factory: the factory to register
104  *
105  * Register the factory. 
106  *
107  * Returns: The registered capability
108  */
109 GstCaps*
110 gst_caps_register (GstCapsFactory *factory)
111 {
112   guint dummy;
113
114   return gst_caps_register_count (factory, &dummy);
115 }
116
117 /**
118  * gst_caps_register_count:
119  * @factory: the factory to register
120  * @counter: count how many entries were consumed
121  *
122  * Register the factory. 
123  *
124  * Returns: The registered capability
125  */
126 GstCaps*
127 gst_caps_register_count (GstCapsFactory *factory, guint *counter)
128 {
129   GstCapsFactoryEntry tag;
130   gint i = 0;
131   guint16 typeid;
132   gchar *name;
133   GstCaps *caps;
134
135   g_return_val_if_fail (factory != NULL, NULL);
136
137   tag = (*factory)[i++];
138   g_return_val_if_fail (tag != NULL, NULL);
139
140   name = tag;
141
142   tag = (*factory)[i++];
143   g_return_val_if_fail (tag != NULL, NULL);
144   
145   typeid = get_type_for_mime ((gchar *)tag);
146
147   caps = g_new0 (GstCaps, 1);
148   g_return_val_if_fail (caps != NULL, NULL);
149
150   caps->name = g_strdup (name);
151   caps->id = typeid;
152   caps->properties = gst_props_register_count (&(*factory)[i], counter);
153
154   *counter += 2;
155
156   return caps;
157 }
158
159 /**
160  * gst_caps_set_props:
161  * @caps: the caps to attach the properties to
162  * @props: the properties to attach
163  *
164  * set the properties to the given caps
165  *
166  * Returns: The new caps structure
167  */
168 GstCaps*
169 gst_caps_set_props (GstCaps *caps, GstProps *props)
170 {
171   g_return_val_if_fail (caps != NULL, caps);
172   g_return_val_if_fail (props != NULL, caps);
173   g_return_val_if_fail (caps->properties == NULL, caps);
174
175   caps->properties = props;
176   
177   return caps;
178 }
179
180 /**
181  * gst_caps_get_props:
182  * @caps: the caps to get the properties from
183  *
184  * get the properties of the given caps
185  *
186  * Returns: The properties of the caps
187  */
188 GstProps*
189 gst_caps_get_props (GstCaps *caps)
190 {
191   g_return_val_if_fail (caps != NULL, NULL);
192
193   return caps->properties;
194 }
195
196 /**
197  * gst_caps_check_compatibility:
198  * @fromcaps: a capabilty
199  * @tocaps: a capabilty
200  *
201  * Checks whether two capabilities are compatible
202  *
203  * Returns: true if compatible, false otherwise
204  */
205 gboolean
206 gst_caps_check_compatibility (GstCaps *fromcaps, GstCaps *tocaps)
207 {
208   g_return_val_if_fail (fromcaps != NULL, FALSE);
209   g_return_val_if_fail (tocaps != NULL, FALSE);
210         
211   if (fromcaps->id != tocaps->id) {
212     GST_DEBUG (0,"gstcaps: mime types wrong\n");
213     return FALSE;
214   }
215
216   if (tocaps->properties) {
217     if (fromcaps->properties) {
218       return gst_props_check_compatibility (fromcaps->properties, tocaps->properties);
219     }
220     else {
221       GST_DEBUG (0,"gstcaps: no source caps\n");
222       return FALSE;
223     }
224   }
225   else {
226     // assume it accepts everything
227     GST_DEBUG (0,"gstcaps: no caps\n");
228     return TRUE;
229   }
230 }
231
232 /**
233  * gst_caps_list_check_compatibility:
234  * @fromcaps: a capabilty
235  * @tocaps: a capabilty
236  *
237  * Checks whether two capability lists are compatible
238  *
239  * Returns: true if compatible, false otherwise
240  */
241 gboolean
242 gst_caps_list_check_compatibility (GList *fromcaps, GList *tocaps)
243 {
244   while (fromcaps) {
245     GstCaps *fromcap = (GstCaps *)fromcaps->data;
246     GList *destcaps = tocaps;
247
248     while (destcaps) {
249       GstCaps *destcap = (GstCaps *)destcaps->data;
250
251       if (gst_caps_check_compatibility (fromcap, destcap))
252         return TRUE;
253
254       destcaps = g_list_next (destcaps);
255     }
256     fromcaps = g_list_next (fromcaps);
257   }
258   return FALSE;
259 }
260
261 /**
262  * gst_caps_save_thyself:
263  * @caps: a capabilty to save
264  * @parent: the parent XML node pointer
265  *
266  * save the capability into an XML representation
267  *
268  * Returns: a new XML node pointer
269  */
270 xmlNodePtr      
271 gst_caps_save_thyself (GstCaps *caps, xmlNodePtr parent)
272 {
273   xmlNodePtr subtree;
274
275   g_return_val_if_fail (caps != NULL, NULL);
276
277   xmlNewChild (parent, NULL, "name", caps->name);
278   xmlNewChild (parent, NULL, "type", gst_type_find_by_id (caps->id)->mime);
279   if (caps->properties) {
280     subtree = xmlNewChild (parent, NULL, "properties", NULL);
281
282     gst_props_save_thyself (caps->properties, subtree);
283   }
284
285   return parent;
286 }
287
288 /**
289  * gst_caps_load_thyself:
290  * @parent: the parent XML node pointer
291  *
292  * load a new caps from the XML representation
293  *
294  * Returns: a new capability
295  */
296 GstCaps*        
297 gst_caps_load_thyself (xmlNodePtr parent)
298 {
299   GstCaps *caps = g_new0 (GstCaps, 1);
300   xmlNodePtr field = parent->childs;
301
302   while (field) {
303     if (!strcmp (field->name, "name")) {
304       caps->name = g_strdup (xmlNodeGetContent (field));
305     }
306     if (!strcmp (field->name, "type")) {
307       caps->id = get_type_for_mime (xmlNodeGetContent (field));
308     }
309     else if (!strcmp (field->name, "properties")) {
310       caps->properties = gst_props_load_thyself (field);
311     }
312     field = field->next;
313   }
314
315   return caps;
316 }
317
318
319