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 = g_new0(GstElementFactory, 1);
115 g_return_val_if_fail(name != NULL, NULL);
117 factory->name = g_strdup(name);
118 factory->type = type;
119 factory->details = details;
120 factory->padtemplates = NULL;
121 factory->numpadtemplates = 0;
123 _gst_elementfactories = g_list_prepend (_gst_elementfactories, factory);
129 * gst_elementfactory_create:
130 * @factory: factory to instantiate
131 * @name: name of new element
133 * Create a new element of the type defined by the given elementfactory.
134 * It wll be given the name supplied, since all elements require a name as
135 * their first argument.
137 * Returns: new #GstElement
140 gst_elementfactory_create (GstElementFactory *factory,
144 GstElementClass *oclass;
146 g_return_val_if_fail(factory != NULL, NULL);
147 g_return_val_if_fail(name != NULL, NULL);
149 GST_DEBUG (0,"gstelementfactory: create \"%s\" \"%s\"\n", factory->name, name);
151 // it's not loaded, try to load the plugin
152 if (factory->type == 0) {
153 factory = gst_plugin_load_elementfactory(factory->name);
155 g_return_val_if_fail(factory != NULL, NULL);
156 g_return_val_if_fail(factory->type != 0, NULL);
158 // create an instance of the element
159 element = GST_ELEMENT(gtk_type_new(factory->type));
160 g_assert(element != NULL);
161 gst_object_ref(GST_OBJECT(element));
163 // attempt to set the elemenfactory class pointer if necessary
164 oclass = GST_ELEMENT_CLASS(GTK_OBJECT(element)->klass);
165 if (oclass->elementfactory == NULL) {
166 GST_DEBUG (0,"gstelementfactory: class %s\n", factory->name);
167 oclass->elementfactory = factory;
170 gst_element_set_name(GST_ELEMENT(element),name);
176 * gst_elementfactory_make:
177 * @factoryname: a named factory to instantiate
178 * @name: name of new element
180 * Create a new element of the type defined by the given elementfactory.
181 * It wll be given the name supplied, since all elements require a name as
182 * their first argument.
184 * Returns: new #GstElement
187 gst_elementfactory_make (const gchar *factoryname, const gchar *name)
189 GstElementFactory *factory;
192 g_return_val_if_fail(factoryname != NULL, NULL);
193 g_return_val_if_fail(name != NULL, NULL);
195 GST_DEBUG (0,"gstelementfactory: make \"%s\" \"%s\"\n", factoryname, name);
197 //gst_plugin_load_elementfactory(factoryname);
198 factory = gst_elementfactory_find(factoryname);
199 if (factory == NULL) return NULL;
200 element = gst_elementfactory_create(factory,name);
205 * gst_elementfactory_add_padtemplate :
206 * @elementfactory: factory to add the src id to
207 * @temp: the padtemplate to add
209 * Add the given padtemplate to this elementfactory.
212 gst_elementfactory_add_padtemplate (GstElementFactory *factory,
213 GstPadTemplate *temp)
215 g_return_if_fail(factory != NULL);
216 g_return_if_fail(temp != NULL);
218 factory->padtemplates = g_list_append (factory->padtemplates, temp);
219 factory->numpadtemplates++;
223 * gst_elementfactory_can_src_caps_list :
224 * @factory: factory to query
225 * @caps: the caps list to check
227 * Checks if the factory can source the given capability list.
229 * Returns: true if it can src the capabilities
232 gst_elementfactory_can_src_caps_list (GstElementFactory *factory,
237 g_return_val_if_fail(factory != NULL, FALSE);
238 g_return_val_if_fail(caps != NULL, FALSE);
240 templates = factory->padtemplates;
243 GstPadTemplate *template = (GstPadTemplate *)templates->data;
245 if (template->direction == GST_PAD_SRC) {
246 if (gst_caps_list_check_compatibility (template->caps, caps))
249 templates = g_list_next (templates);
256 * gst_elementfactory_can_sink_caps_list :
257 * @factory: factory to query
258 * @caps: the caps list to check
260 * Checks if the factory can sink the given capability list.
262 * Returns: true if it can sink the capabilities
265 gst_elementfactory_can_sink_caps_list (GstElementFactory *factory,
270 g_return_val_if_fail(factory != NULL, FALSE);
271 g_return_val_if_fail(caps != NULL, FALSE);
273 templates = factory->padtemplates;
276 GstPadTemplate *template = (GstPadTemplate *)templates->data;
278 if (template->direction == GST_PAD_SINK) {
279 if (gst_caps_list_check_compatibility (caps, template->caps))
282 templates = g_list_next (templates);
289 * gst_elementfactory_can_src_caps :
290 * @factory: factory to query
291 * @caps: the caps to check
293 * Checks if the factory can src the given capability.
295 * Returns: true if it can sink the capability
298 gst_elementfactory_can_src_caps (GstElementFactory *factory,
304 dummy = g_list_prepend (NULL, caps);
306 ret = gst_elementfactory_can_src_caps_list (factory, dummy);
314 * gst_elementfactory_can_sink_caps :
315 * @factory: factory to query
316 * @caps: the caps to check
318 * Checks if the factory can sink the given capability.
320 * Returns: true if it can sink the capability
323 gst_elementfactory_can_sink_caps (GstElementFactory *factory,
329 dummy = g_list_prepend (NULL, caps);
331 ret = gst_elementfactory_can_sink_caps_list (factory, dummy);
339 * gst_elementfactory_save_thyself:
340 * @factory: factory to save
341 * @parent: the parent xmlNodePtr
343 * Saves the factory into an XML tree.
345 * Returns: the new xmlNodePtr
348 gst_elementfactory_save_thyself (GstElementFactory *factory,
353 g_return_val_if_fail(factory != NULL, NULL);
355 xmlNewChild(parent,NULL,"name",factory->name);
356 xmlNewChild(parent,NULL,"longname", factory->details->longname);
357 xmlNewChild(parent,NULL,"class", factory->details->klass);
358 xmlNewChild(parent,NULL,"description", factory->details->description);
359 xmlNewChild(parent,NULL,"version", factory->details->version);
360 xmlNewChild(parent,NULL,"author", factory->details->author);
361 xmlNewChild(parent,NULL,"copyright", factory->details->copyright);
363 pads = factory->padtemplates;
367 GstPadTemplate *padtemplate = (GstPadTemplate *)pads->data;
369 subtree = xmlNewChild(parent, NULL, "padtemplate", NULL);
370 gst_padtemplate_save_thyself(padtemplate, subtree);
372 pads = g_list_next (pads);
379 * gst_elementfactory_load_thyself:
380 * @parent: the parent xmlNodePtr
382 * Creates a new factory from an xmlNodePtr.
384 * Returns: the new factory
387 gst_elementfactory_load_thyself (xmlNodePtr parent)
389 GstElementFactory *factory = g_new0(GstElementFactory, 1);
390 xmlNodePtr children = parent->childs;
391 factory->details = g_new0(GstElementDetails, 1);
392 factory->padtemplates = NULL;
395 if (!strcmp(children->name, "name")) {
396 factory->name = g_strdup(xmlNodeGetContent(children));
398 if (!strcmp(children->name, "longname")) {
399 factory->details->longname = g_strdup(xmlNodeGetContent(children));
401 if (!strcmp(children->name, "class")) {
402 factory->details->klass = g_strdup(xmlNodeGetContent(children));
404 if (!strcmp(children->name, "description")) {
405 factory->details->description = g_strdup(xmlNodeGetContent(children));
407 if (!strcmp(children->name, "version")) {
408 factory->details->version = g_strdup(xmlNodeGetContent(children));
410 if (!strcmp(children->name, "author")) {
411 factory->details->author = g_strdup(xmlNodeGetContent(children));
413 if (!strcmp(children->name, "copyright")) {
414 factory->details->copyright = g_strdup(xmlNodeGetContent(children));
416 if (!strcmp(children->name, "padtemplate")) {
417 GstPadTemplate *template;
419 template = gst_padtemplate_load_thyself (children);
421 gst_elementfactory_add_padtemplate (factory, template);
424 children = children->next;
427 _gst_elementfactories = g_list_prepend (_gst_elementfactories, factory);