2 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3 * 2000 Wim Taymans <wtay@chello.be>
5 * gstelementfactory.c: GstElementFactory object, support routines
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.
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.
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.
23 //#define DEBUG_ENABLED
24 #include "gst_private.h"
26 #include "gstelement.h"
27 #include "gstplugin.h"
30 /* global list of registered elementfactories */
31 GList* _gst_elementfactories;
34 _gst_elementfactory_initialize (void)
36 _gst_elementfactories = NULL;
40 * gst_elementfactory_destroy:
41 * @elementfactory: factory to destroy
43 * Removes the elementfactory from the global list.
46 gst_elementfactory_destroy (GstElementFactory *elementfactory)
48 g_return_if_fail (elementfactory != NULL);
50 _gst_elementfactories = g_list_remove (_gst_elementfactories, elementfactory);
52 // we don't free the struct bacause someone might have a handle to it..
56 * gst_elementfactory_find:
57 * @name: name of factory to find
59 * Search for an elementfactory of the given name.
61 * Returns: #GstElementFactory if found, NULL otherwise
64 gst_elementfactory_find (const gchar *name)
67 GstElementFactory *factory;
69 g_return_val_if_fail(name != NULL, NULL);
71 GST_DEBUG (0,"gstelementfactory: find \"%s\"\n", name);
73 walk = _gst_elementfactories;
75 factory = (GstElementFactory *)(walk->data);
76 if (!strcmp(name,factory->name))
78 walk = g_list_next(walk);
85 * gst_elementfactory_get_list:
87 * Get the global list of elementfactories.
89 * Returns: GList of type #GstElementFactory
92 gst_elementfactory_get_list (void)
94 return _gst_elementfactories;
99 * gst_elementfactory_new:
100 * @name: name of new elementfactory
101 * @type: GtkType of new element
102 * @details: #GstElementDetails structure with element details
104 * Create a new elementfactory capable of insantiating objects of the
107 * Returns: new elementfactory
110 gst_elementfactory_new (const gchar *name, GtkType type,
111 GstElementDetails *details)
113 GstElementFactory *factory;
115 g_return_val_if_fail(name != NULL, NULL);
117 factory = g_new0(GstElementFactory, 1);
119 factory->name = g_strdup(name);
120 factory->type = type;
121 factory->details = details;
122 factory->padtemplates = NULL;
123 factory->numpadtemplates = 0;
125 _gst_elementfactories = g_list_prepend (_gst_elementfactories, factory);
131 * gst_elementfactory_create:
132 * @factory: factory to instantiate
133 * @name: name of new element
135 * Create a new element of the type defined by the given elementfactory.
136 * It wll be given the name supplied, since all elements require a name as
137 * their first argument.
139 * Returns: new #GstElement
142 gst_elementfactory_create (GstElementFactory *factory,
146 GstElementClass *oclass;
148 g_return_val_if_fail(factory != NULL, NULL);
149 g_return_val_if_fail(name != NULL, NULL);
151 GST_DEBUG (0,"gstelementfactory: create \"%s\" \"%s\"\n", factory->name, name);
153 // it's not loaded, try to load the plugin
154 if (factory->type == 0) {
155 factory = gst_plugin_load_elementfactory(factory->name);
157 g_return_val_if_fail(factory != NULL, NULL);
158 g_return_val_if_fail(factory->type != 0, NULL);
160 // create an instance of the element
161 element = GST_ELEMENT(gtk_type_new(factory->type));
162 g_assert(element != NULL);
163 gst_object_ref(GST_OBJECT(element));
165 // attempt to set the elemenfactory class pointer if necessary
166 oclass = GST_ELEMENT_CLASS(GTK_OBJECT(element)->klass);
167 if (oclass->elementfactory == NULL) {
168 GST_DEBUG (0,"gstelementfactory: class %s\n", factory->name);
169 oclass->elementfactory = factory;
172 gst_object_set_name (GST_OBJECT (element),name);
178 * gst_elementfactory_make:
179 * @factoryname: a named factory to instantiate
180 * @name: name of new element
182 * Create a new element of the type defined by the given elementfactory.
183 * It wll be given the name supplied, since all elements require a name as
184 * their first argument.
186 * Returns: new #GstElement
189 gst_elementfactory_make (const gchar *factoryname, const gchar *name)
191 GstElementFactory *factory;
194 g_return_val_if_fail(factoryname != NULL, NULL);
195 g_return_val_if_fail(name != NULL, NULL);
197 GST_DEBUG (0,"gstelementfactory: make \"%s\" \"%s\"\n", factoryname, name);
199 //gst_plugin_load_elementfactory(factoryname);
200 factory = gst_elementfactory_find(factoryname);
201 if (factory == NULL) return NULL;
202 element = gst_elementfactory_create(factory,name);
207 * gst_elementfactory_add_padtemplate :
208 * @elementfactory: factory to add the src id to
209 * @templ: the padtemplate to add
211 * Add the given padtemplate to this elementfactory.
214 gst_elementfactory_add_padtemplate (GstElementFactory *factory,
215 GstPadTemplate *templ)
217 g_return_if_fail(factory != NULL);
218 g_return_if_fail(templ != NULL);
220 factory->padtemplates = g_list_append (factory->padtemplates, templ);
221 factory->numpadtemplates++;
225 * gst_elementfactory_can_src_caps_list :
226 * @factory: factory to query
227 * @caps: the caps list to check
229 * Checks if the factory can source the given capability list.
231 * Returns: true if it can src the capabilities
234 gst_elementfactory_can_src_caps_list (GstElementFactory *factory,
239 g_return_val_if_fail(factory != NULL, FALSE);
240 g_return_val_if_fail(caps != NULL, FALSE);
242 templates = factory->padtemplates;
245 GstPadTemplate *template = (GstPadTemplate *)templates->data;
247 if (template->direction == GST_PAD_SRC) {
248 if (gst_caps_list_check_compatibility (template->caps, caps))
251 templates = g_list_next (templates);
258 * gst_elementfactory_can_sink_caps_list :
259 * @factory: factory to query
260 * @caps: the caps list to check
262 * Checks if the factory can sink the given capability list.
264 * Returns: true if it can sink the capabilities
267 gst_elementfactory_can_sink_caps_list (GstElementFactory *factory,
272 g_return_val_if_fail(factory != NULL, FALSE);
273 g_return_val_if_fail(caps != NULL, FALSE);
275 templates = factory->padtemplates;
278 GstPadTemplate *template = (GstPadTemplate *)templates->data;
280 if (template->direction == GST_PAD_SINK) {
281 if (gst_caps_list_check_compatibility (caps, template->caps))
284 templates = g_list_next (templates);
291 * gst_elementfactory_can_src_caps :
292 * @factory: factory to query
293 * @caps: the caps to check
295 * Checks if the factory can src the given capability.
297 * Returns: true if it can sink the capability
300 gst_elementfactory_can_src_caps (GstElementFactory *factory,
306 dummy = g_list_prepend (NULL, caps);
308 ret = gst_elementfactory_can_src_caps_list (factory, dummy);
316 * gst_elementfactory_can_sink_caps :
317 * @factory: factory to query
318 * @caps: the caps to check
320 * Checks if the factory can sink the given capability.
322 * Returns: true if it can sink the capability
325 gst_elementfactory_can_sink_caps (GstElementFactory *factory,
331 dummy = g_list_prepend (NULL, caps);
333 ret = gst_elementfactory_can_sink_caps_list (factory, dummy);
341 * gst_elementfactory_save_thyself:
342 * @factory: factory to save
343 * @parent: the parent xmlNodePtr
345 * Saves the factory into an XML tree.
347 * Returns: the new xmlNodePtr
350 gst_elementfactory_save_thyself (GstElementFactory *factory,
355 g_return_val_if_fail(factory != NULL, NULL);
357 xmlNewChild(parent,NULL,"name",factory->name);
358 xmlNewChild(parent,NULL,"longname", factory->details->longname);
359 xmlNewChild(parent,NULL,"class", factory->details->klass);
360 xmlNewChild(parent,NULL,"description", factory->details->description);
361 xmlNewChild(parent,NULL,"version", factory->details->version);
362 xmlNewChild(parent,NULL,"author", factory->details->author);
363 xmlNewChild(parent,NULL,"copyright", factory->details->copyright);
365 pads = factory->padtemplates;
369 GstPadTemplate *padtemplate = (GstPadTemplate *)pads->data;
371 subtree = xmlNewChild(parent, NULL, "padtemplate", NULL);
372 gst_padtemplate_save_thyself(padtemplate, subtree);
374 pads = g_list_next (pads);
381 * gst_elementfactory_load_thyself:
382 * @parent: the parent xmlNodePtr
384 * Creates a new factory from an xmlNodePtr.
386 * Returns: the new factory
389 gst_elementfactory_load_thyself (xmlNodePtr parent)
391 GstElementFactory *factory = g_new0(GstElementFactory, 1);
392 xmlNodePtr children = parent->xmlChildrenNode;
393 factory->details = g_new0(GstElementDetails, 1);
394 factory->padtemplates = NULL;
397 if (!strcmp(children->name, "name")) {
398 factory->name = xmlNodeGetContent(children);
400 if (!strcmp(children->name, "longname")) {
401 factory->details->longname = xmlNodeGetContent(children);
403 if (!strcmp(children->name, "class")) {
404 factory->details->klass = xmlNodeGetContent(children);
406 if (!strcmp(children->name, "description")) {
407 factory->details->description = xmlNodeGetContent(children);
409 if (!strcmp(children->name, "version")) {
410 factory->details->version = xmlNodeGetContent(children);
412 if (!strcmp(children->name, "author")) {
413 factory->details->author = xmlNodeGetContent(children);
415 if (!strcmp(children->name, "copyright")) {
416 factory->details->copyright = xmlNodeGetContent(children);
418 if (!strcmp(children->name, "padtemplate")) {
419 GstPadTemplate *template;
421 template = gst_padtemplate_load_thyself (children);
423 gst_elementfactory_add_padtemplate (factory, template);
426 children = children->next;
429 _gst_elementfactories = g_list_prepend (_gst_elementfactories, factory);