Due to popular demand :-), I added a vorbis decoder.
[platform/upstream/gstreamer.git] / gst / gstelementfactory.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 #include <gst/gstelement.h>
21 #include <gst/gstplugin.h>
22
23
24 /* global list of registered elementfactories */
25 GList* _gst_elementfactories;
26
27 void _gst_elementfactory_initialize() {
28   _gst_elementfactories = NULL;
29 }
30
31 /**
32  * gst_elementfactory_register:
33  * @elementfactory: factory to register
34  *
35  * Adds the elementfactory to the global list, so it can be retrieved by
36  * name.
37  */
38 void gst_elementfactory_register(GstElementFactory *elementfactory) {
39   g_return_if_fail(elementfactory != NULL);
40
41   _gst_elementfactories = g_list_prepend(_gst_elementfactories,elementfactory);
42 }
43
44 /**
45  * gst_elementfactory_find:
46  * @name: name of factory to find
47  *
48  * Search for an elementfactory of the given name.
49  *
50  * Returns: #GstElementFactory if found, NULL otherwise
51  */
52 GstElementFactory *gst_elementfactory_find(gchar *name) {
53   GList *walk = _gst_elementfactories;
54   GstElementFactory *factory;
55
56   while (walk) {
57     factory = (GstElementFactory *)(walk->data);
58     if (!strcmp(name,factory->name))
59       return factory;
60     walk = g_list_next(walk);
61   }
62
63   return NULL;
64 }
65
66 /**
67  * gst_elementfactory_get_list:
68  *
69  * Get the global list of elementfactories.
70  *
71  * Returns: <type>GList</type> of type #GstElementFactory
72  */
73 GList *gst_elementfactory_get_list() {
74   return _gst_elementfactories;
75 }
76
77
78 /**
79  * gst_elementfactory_new:
80  * @name: name of new elementfactory
81  * @type: GtkType of new element
82  * @details: #GstElementDetails structure with element details
83  *
84  * Create a new elementfactory capable of insantiating objects of the
85  * given type.
86  *
87  * Returns: new elementfactory
88  */
89 GstElementFactory *gst_elementfactory_new(gchar *name,GtkType type,
90                                           GstElementDetails *details) {
91   GstElementFactory *factory = g_new0(GstElementFactory, 1);
92   factory->name = g_strdup(name);
93   factory->type = type;
94   factory->details = details;
95   factory->src_types = NULL;
96   factory->sink_types = NULL;
97   return factory;
98 }
99
100 /**
101  * gst_elementfactory_create:
102  * @factory: factory to instantiate
103  * @name: name of new element
104  *
105  * Create a new element of the type defined by the given elementfactory.
106  * It wll be given the name supplied, since all elements require a name as
107  * their first argument.
108  *
109  * Returns: new #GstElement
110  */
111 GstElement *gst_elementfactory_create(GstElementFactory *factory,
112                                       gchar *name) {
113   GstElement *element;
114   GstElementClass *oclass;
115
116   g_return_val_if_fail(factory != NULL, NULL);
117
118   factory = gst_plugin_load_elementfactory(factory->name);
119
120   g_return_val_if_fail(factory->type != 0, NULL);
121
122   // create an instance of the element
123   element = GST_ELEMENT(gtk_type_new(factory->type));
124   g_assert(element != NULL);
125   gst_object_ref(GST_OBJECT(element));
126
127   // attempt to set the elemenfactory class pointer if necessary
128   oclass = GST_ELEMENT_CLASS(GTK_OBJECT(element)->klass);
129   if (oclass->elementfactory == NULL)
130     oclass->elementfactory = factory;
131
132   gst_element_set_name(GST_ELEMENT(element),name);
133
134   return element;
135 }
136
137 /**
138  * gst_elementfactory_make:
139  * @factoryname: a named factory to instantiate
140  * @name: name of new element
141  *
142  * Create a new element of the type defined by the given elementfactory.
143  * It wll be given the name supplied, since all elements require a name as
144  * their first argument.
145  *
146  * Returns: new #GstElement
147  */
148 GstElement *gst_elementfactory_make(gchar *factoryname,gchar *name) {
149   GstElementFactory *factory;
150   GstElement *element;
151
152   gst_plugin_load_elementfactory(factoryname);
153   factory = gst_elementfactory_find(factoryname);
154   if (factory == NULL) return NULL;
155   element = gst_elementfactory_create(factory,name);
156   return element;
157 }
158
159 /**
160  * gst_elementfactory_add_src:
161  * @elementfactory: factory to add the src id to
162  * @id: the mime id of the src 
163  *
164  * Use this function to indicate that this factory can src
165  * the given type id.
166  */
167 void gst_elementfactory_add_src(GstElementFactory *elementfactory, guint16 id) {
168   guint type = id;
169
170   elementfactory->src_types = g_list_prepend(elementfactory->src_types, GUINT_TO_POINTER(type));
171 }
172
173 /**
174  * gst_elementfactory_add_sink:
175  * @elementfactory: factory to add the sink id to
176  * @id: the type id of the sink 
177  *
178  * Use this function to indicate that this factory can sink
179  * the given type id.
180  */
181 void gst_elementfactory_add_sink(GstElementFactory *elementfactory, guint16 id) {
182   guint type = id;
183
184   elementfactory->sink_types = g_list_prepend(elementfactory->sink_types, GUINT_TO_POINTER(type));
185 }
186
187 /**
188  * gst_elementfactory_save_thyself:
189  * @factory: factory to save
190  * @parent: the parent xmlNodePtr 
191  *
192  * Saves the factory into an XML tree
193  * 
194  * Returns: the new xmlNodePtr
195  */
196 xmlNodePtr gst_elementfactory_save_thyself(GstElementFactory *factory, xmlNodePtr parent) {
197   GList *types;
198   xmlNodePtr subtree;
199
200   xmlNewChild(parent,NULL,"name",factory->name);
201   xmlNewChild(parent,NULL,"longname", factory->details->longname);
202   xmlNewChild(parent,NULL,"class", factory->details->class);
203   xmlNewChild(parent,NULL,"description", factory->details->description);
204   xmlNewChild(parent,NULL,"version", factory->details->version);
205   xmlNewChild(parent,NULL,"author", factory->details->author);
206   xmlNewChild(parent,NULL,"copyright", factory->details->copyright);
207
208   types = factory->src_types;
209   if (types) {
210     subtree = xmlNewChild(parent,NULL,"sources",NULL);
211     while (types) {
212       guint16 typeid = GPOINTER_TO_UINT(types->data);
213       GstType *type = gst_type_find_by_id(typeid);
214
215       gst_type_save_thyself(type, subtree);
216
217       types = g_list_next(types);
218     }
219   }
220   types = factory->sink_types;
221   if (types) {
222     subtree = xmlNewChild(parent,NULL,"sinks",NULL);
223     while (types) {
224       guint16 typeid = GPOINTER_TO_UINT(types->data);
225       GstType *type = gst_type_find_by_id(typeid);
226
227       gst_type_save_thyself(type, subtree);
228
229       types = g_list_next(types);
230     }
231   }
232
233   return parent;
234 }
235
236 /**
237  * gst_elementfactory_load_thyself:
238  * @parent: the parent xmlNodePtr 
239  *
240  * Creates a new factory from an xmlNodePtr
241  * 
242  * Returns: the new factory
243  */
244 GstElementFactory *gst_elementfactory_load_thyself(xmlNodePtr parent) {
245   GstElementFactory *factory = g_new0(GstElementFactory, 1);
246   xmlNodePtr children = parent->childs;
247   factory->details = g_new0(GstElementDetails, 1);
248   factory->sink_types = NULL;
249   factory->src_types = NULL;
250
251   while (children) {
252     if (!strcmp(children->name, "name")) {
253       factory->name = g_strdup(xmlNodeGetContent(children));
254     }
255     if (!strcmp(children->name, "longname")) {
256       factory->details->longname = g_strdup(xmlNodeGetContent(children));
257     }
258     if (!strcmp(children->name, "class")) {
259       factory->details->class = g_strdup(xmlNodeGetContent(children));
260     }
261     if (!strcmp(children->name, "description")) {
262       factory->details->description = g_strdup(xmlNodeGetContent(children));
263     }
264     if (!strcmp(children->name, "version")) {
265       factory->details->version = g_strdup(xmlNodeGetContent(children));
266     }
267     if (!strcmp(children->name, "author")) {
268       factory->details->author = g_strdup(xmlNodeGetContent(children));
269     }
270     if (!strcmp(children->name, "copyright")) {
271       factory->details->copyright = g_strdup(xmlNodeGetContent(children));
272     }
273     if (!strcmp(children->name, "sources")) {
274       guint16 typeid = gst_type_load_thyself(children);
275
276       gst_type_add_src(typeid, factory);
277     }
278     if (!strcmp(children->name, "sinks")) {
279       guint16 typeid = gst_type_load_thyself(children);
280
281       gst_type_add_sink(typeid, factory);
282     }
283
284     children = children->next;
285   }
286
287   return factory;
288 }
289