Added API to dynamically create GstCaps and GstProps
[platform/upstream/gstreamer.git] / gst / gstcaps.c
1 /* Gnome-Streamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 //#define DEBUG_ENABLED
21
22 #include "gstdebug.h"
23 #include "gstcaps.h"
24 #include "gsttype.h"
25
26 #include "gstpropsprivate.h"
27 void 
28 _gst_caps_initialize (void) 
29 {
30 }
31
32 static guint16
33 get_type_for_mime (gchar *mime)
34 {
35   guint16 typeid;
36
37   typeid = gst_type_find_by_mime (mime);
38   if (typeid == 0) {
39      GstTypeFactory *factory = g_new0 (GstTypeFactory, 1);
40
41      factory->mime = g_strdup (mime);
42      factory->exts = NULL;
43      factory->typefindfunc = NULL;
44
45      typeid = gst_type_register (factory);
46   }
47   return typeid;
48 }
49
50 /**
51  * gst_caps_new:
52  * @mime: the mime type to attach to the capability
53  *
54  * create a new capability with the given mime type
55  *
56  * Returns: a new capability
57  */
58 GstCaps*
59 gst_caps_new (gchar *mime)
60 {
61   GstCaps *caps;
62
63   g_return_val_if_fail (mime != NULL, NULL);
64   
65   caps = g_new0 (GstCaps, 1);
66   caps->id = get_type_for_mime (mime);
67   caps->properties = NULL;
68   
69   return caps;
70 }
71
72 GstCaps*
73 gst_caps_new_with_props (gchar *mime, GstProps *props)
74 {
75   GstCaps *caps;
76   
77   caps = gst_caps_new (mime);
78   caps->properties = props;
79
80   return caps;
81 }
82
83 /**
84  * gst_caps_register:
85  * @factory: the factory to register
86  *
87  * Register the factory. 
88  *
89  * Returns: The registered capability
90  */
91 GstCaps*
92 gst_caps_register (GstCapsFactory *factory)
93 {
94   GstCapsFactoryEntry tag;
95   gint i = 0;
96   guint16 typeid;
97   GstCaps *caps;
98   
99   g_return_val_if_fail (factory != NULL, NULL);
100
101   tag = (*factory)[i++];
102
103   g_return_val_if_fail (tag != NULL, NULL);
104   
105   typeid = get_type_for_mime ((gchar *)tag);
106
107   caps = g_new0 (GstCaps, 1);
108   g_return_val_if_fail (caps != NULL, NULL);
109
110   caps->id = typeid;
111   caps->properties = gst_props_register (&(*factory)[i]);
112
113   return caps;
114 }
115
116 GstCaps*
117 gst_caps_set_props (GstCaps *caps, GstProps *props)
118 {
119   g_return_val_if_fail (caps != NULL, caps);
120   g_return_val_if_fail (props != NULL, caps);
121   g_return_val_if_fail (caps->properties == NULL, caps);
122
123   caps->properties = props;
124   
125   return caps;
126 }
127
128 GstProps*
129 gst_caps_get_props (GstCaps *caps)
130 {
131   g_return_val_if_fail (caps != NULL, caps);
132
133   return caps->properties;
134 }
135
136 /**
137  * gst_caps_check_compatibility:
138  * @fromcaps: a capabilty
139  * @tocaps: a capabilty
140  *
141  * Checks whether two capabilities are compatible
142  *
143  * Returns: true if compatible, false otherwise
144  */
145 gboolean
146 gst_caps_check_compatibility (GstCaps *fromcaps, GstCaps *tocaps)
147 {
148   g_return_val_if_fail (fromcaps != NULL, FALSE);
149   g_return_val_if_fail (tocaps != NULL, FALSE);
150         
151   if (fromcaps->id != tocaps->id) {
152     DEBUG ("gstcaps: mime types wrong\n");
153     return FALSE;
154   }
155
156   if (tocaps->properties) {
157     if (fromcaps->properties) {
158       return gst_props_check_compatibility (fromcaps->properties, tocaps->properties);
159     }
160     else {
161       DEBUG ("gstcaps: no source caps\n");
162       return FALSE;
163     }
164   }
165   else {
166     // assume it accepts everything
167     DEBUG ("gstcaps: no caps\n");
168     return TRUE;
169   }
170 }
171
172
173 xmlNodePtr      
174 gst_caps_save_thyself (GstCaps *caps, xmlNodePtr parent)
175 {
176   xmlNodePtr subtree;
177
178   g_return_val_if_fail (caps != NULL, NULL);
179
180   xmlNewChild (parent, NULL, "type", gst_type_find_by_id (caps->id)->mime);
181   if (caps->properties) {
182     subtree = xmlNewChild (parent, NULL, "properties", NULL);
183
184     gst_props_save_thyself (caps->properties, subtree);
185   }
186
187   return parent;
188 }
189
190 GstCaps*        
191 gst_caps_load_thyself (xmlNodePtr parent)
192 {
193   GstCaps *caps = g_new0 (GstCaps, 1);
194   xmlNodePtr field = parent->childs;
195
196   while (field) {
197     if (!strcmp (field->name, "type")) {
198       caps->id = get_type_for_mime (xmlNodeGetContent (field));
199     }
200     else if (!strcmp (field->name, "properties")) {
201       caps->properties = gst_props_load_thyself (field);
202     }
203     field = field->next;
204   }
205
206   return caps;
207 }
208
209
210