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 #include "gst_private.h"
25 #include "gstelement.h"
26 #include "gstregistrypool.h"
29 #define GST_CAT_DEFAULT GST_CAT_ELEMENT_FACTORY
31 static void gst_element_factory_class_init (GstElementFactoryClass *klass);
32 static void gst_element_factory_init (GstElementFactory *factory);
34 static void gst_element_factory_unload_thyself (GstPluginFeature *feature);
36 static GstPluginFeatureClass *parent_class = NULL;
37 /* static guint gst_element_factory_signals[LAST_SIGNAL] = { 0 }; */
40 gst_element_factory_get_type (void)
42 static GType elementfactory_type = 0;
44 if (!elementfactory_type) {
45 static const GTypeInfo elementfactory_info = {
46 sizeof (GstElementFactoryClass),
49 (GClassInitFunc) gst_element_factory_class_init,
52 sizeof(GstElementFactory),
54 (GInstanceInitFunc) gst_element_factory_init,
57 elementfactory_type = g_type_register_static (GST_TYPE_PLUGIN_FEATURE,
58 "GstElementFactory", &elementfactory_info, 0);
60 return elementfactory_type;
64 gst_element_factory_class_init (GstElementFactoryClass *klass)
66 GObjectClass *gobject_class;
67 GstObjectClass *gstobject_class;
68 GstPluginFeatureClass *gstpluginfeature_class;
70 gobject_class = (GObjectClass*)klass;
71 gstobject_class = (GstObjectClass*)klass;
72 gstpluginfeature_class = (GstPluginFeatureClass*) klass;
74 parent_class = g_type_class_ref (GST_TYPE_PLUGIN_FEATURE);
76 gstpluginfeature_class->unload_thyself = GST_DEBUG_FUNCPTR (gst_element_factory_unload_thyself);
81 gst_element_factory_init (GstElementFactory *factory)
83 factory->padtemplates = NULL;
84 factory->numpadtemplates = 0;
88 * gst_element_factory_find:
89 * @name: name of factory to find
91 * Search for an element factory of the given name.
93 * Returns: #GstElementFactory if found, NULL otherwise
96 gst_element_factory_find (const gchar *name)
98 GstPluginFeature *feature;
100 g_return_val_if_fail(name != NULL, NULL);
102 feature = gst_registry_pool_find_feature (name, GST_TYPE_ELEMENT_FACTORY);
104 return GST_ELEMENT_FACTORY (feature);
106 /* this should be an ERROR */
107 GST_DEBUG ("no such elementfactory \"%s\"", name);
112 gst_element_details_free (GstElementDetails *dp)
114 g_free (dp->longname);
116 g_free (dp->license);
117 g_free (dp->description);
118 g_free (dp->version);
120 g_free (dp->copyright);
125 gst_element_factory_cleanup (GstElementFactory *factory)
129 if (factory->details_dynamic) {
130 gst_element_details_free (factory->details);
131 factory->details_dynamic = FALSE;
134 padtemplates = factory->padtemplates;
136 while (padtemplates) {
137 GstPadTemplate *oldtempl = GST_PAD_TEMPLATE (padtemplates->data);
139 gst_object_unref (GST_OBJECT (oldtempl));
141 padtemplates = g_list_next (padtemplates);
143 g_list_free (factory->padtemplates);
145 factory->padtemplates = NULL;
146 factory->numpadtemplates = 0;
148 g_free (GST_PLUGIN_FEATURE (factory)->name);
152 * gst_element_factory_new:
153 * @name: name of new elementfactory
154 * @type: GType of new element
155 * @details: #GstElementDetails structure with element details
157 * Create a new elementfactory capable of insantiating objects of the
160 * Returns: new elementfactory
163 gst_element_factory_new (const gchar *name, GType type,
164 GstElementDetails *details)
166 GstElementFactory *factory;
168 g_return_val_if_fail (name != NULL, NULL);
169 g_return_val_if_fail (type, NULL);
170 g_return_val_if_fail (details, NULL);
171 g_return_val_if_fail (details->longname, NULL);
172 g_return_val_if_fail (details->klass, NULL);
173 g_return_val_if_fail (details->license, NULL);
174 g_return_val_if_fail (details->description, NULL);
175 g_return_val_if_fail (details->version, NULL);
176 g_return_val_if_fail (details->author, NULL);
177 g_return_val_if_fail (details->copyright, NULL);
179 factory = gst_element_factory_find (name);
182 factory = GST_ELEMENT_FACTORY (g_object_new (GST_TYPE_ELEMENT_FACTORY, NULL));
184 gst_element_factory_cleanup (factory);
187 factory->details = details;
188 factory->details_dynamic = FALSE;
191 factory->type = type;
192 else if (factory->type != type)
193 g_critical ("`%s' requested type change (!)", name);
195 GST_PLUGIN_FEATURE (factory)->name = g_strdup (name);
201 * gst_element_factory_create:
202 * @factory: factory to instantiate
203 * @name: name of new element
205 * Create a new element of the type defined by the given elementfactory.
206 * It will be given the name supplied, since all elements require a name as
207 * their first argument.
209 * Returns: new #GstElement
212 gst_element_factory_create (GstElementFactory *factory,
216 GstElementClass *oclass;
218 g_return_val_if_fail (factory != NULL, NULL);
220 if (!gst_plugin_feature_ensure_loaded (GST_PLUGIN_FEATURE (factory))) {
221 GST_INFO ("could not load element factory for element \"%s\"", name);
225 GST_LOG ("creating element from factory \"%s\" (name \"%s\", type %d)",
226 GST_PLUGIN_FEATURE_NAME (factory), GST_STR_NULL (name), (gint) factory->type);
228 if (factory->type == 0) {
229 g_critical ("Factory for `%s' has no type",
230 GST_PLUGIN_FEATURE_NAME (factory));
234 /* attempt to set the elementfactory class pointer if necessary */
235 oclass = GST_ELEMENT_CLASS (g_type_class_ref (factory->type));
236 if (oclass->elementfactory == NULL) {
237 GST_DEBUG ("class %s", GST_PLUGIN_FEATURE_NAME (factory));
238 oclass->elementfactory = factory;
240 /* copy pad template pointers to the element class,
241 * allow for custom padtemplates */
242 oclass->padtemplates = g_list_concat (oclass->padtemplates,
243 g_list_copy (factory->padtemplates));
244 oclass->numpadtemplates += factory->numpadtemplates;
247 /* create an instance of the element */
248 element = GST_ELEMENT (g_object_new (factory->type, NULL));
249 g_assert (element != NULL);
251 g_type_class_unref (oclass);
253 gst_object_set_name (GST_OBJECT (element), name);
259 * gst_element_factory_make:
260 * @factoryname: a named factory to instantiate
261 * @name: name of new element
263 * Create a new element of the type defined by the given element factory.
264 * If name is NULL, then the element will receive a guaranteed unique name,
265 * consisting of the element factory name and a number.
266 * If name is given, it will be given the name supplied.
268 * Returns: new #GstElement (or NULL if unable to create element)
271 gst_element_factory_make (const gchar *factoryname, const gchar *name)
273 GstElementFactory *factory;
276 g_return_val_if_fail (factoryname != NULL, NULL);
278 GST_LOG ("gstelementfactory: make \"%s\" \"%s\"",
279 factoryname, GST_STR_NULL (name));
281 /* gst_plugin_load_element_factory (factoryname); */
282 factory = gst_element_factory_find (factoryname);
283 if (factory == NULL) {
284 GST_INFO ("no such element factory \"%s\"!",
288 element = gst_element_factory_create (factory, name);
289 if (element == NULL) {
290 GST_INFO ("couldn't create instance of element factory \"%s\"!",
299 * gst_element_factory_make_or_warn:
300 * @factoryname: a named factory to instantiate
301 * @name: name of new element
303 * Create a new element of the type defined by the given element factory
304 * using #gst_element_factory_make.
305 * Will use g_warning if the element could not be created.
307 * Returns: new #GstElement (or NULL if unable to create element)
310 gst_element_factory_make_or_warn (const gchar *factoryname, const gchar *name)
314 element = gst_element_factory_make (factoryname, name);
317 g_warning ("Could not create element from factory %s !\n", factoryname);
323 * gst_element_factory_add_pad_template :
324 * @elementfactory: factory to add the src id to
325 * @templ: the padtemplate to add
327 * Add the given padtemplate to this elementfactory.
330 gst_element_factory_add_pad_template (GstElementFactory *factory,
331 GstPadTemplate *templ)
333 g_return_if_fail (factory != NULL);
334 g_return_if_fail (templ != NULL);
336 gst_object_ref (GST_OBJECT (templ));
337 gst_object_sink (GST_OBJECT (templ));
339 factory->padtemplates = g_list_append (factory->padtemplates, templ);
340 factory->numpadtemplates++;
344 * gst_element_factory_can_src_caps :
345 * @factory: factory to query
346 * @caps: the caps to check
348 * Checks if the factory can source the given capability.
350 * Returns: true if it can src the capabilities
353 gst_element_factory_can_src_caps (GstElementFactory *factory,
358 g_return_val_if_fail(factory != NULL, FALSE);
359 g_return_val_if_fail(caps != NULL, FALSE);
361 templates = factory->padtemplates;
364 GstPadTemplate *template = (GstPadTemplate *)templates->data;
366 if (template->direction == GST_PAD_SRC) {
367 if (gst_caps_is_always_compatible (GST_PAD_TEMPLATE_CAPS (template), caps))
370 templates = g_list_next (templates);
377 * gst_element_factory_can_sink_caps :
378 * @factory: factory to query
379 * @caps: the caps to check
381 * Checks if the factory can sink the given capability.
383 * Returns: true if it can sink the capabilities
386 gst_element_factory_can_sink_caps (GstElementFactory *factory,
391 g_return_val_if_fail(factory != NULL, FALSE);
392 g_return_val_if_fail(caps != NULL, FALSE);
394 templates = factory->padtemplates;
397 GstPadTemplate *template = (GstPadTemplate *)templates->data;
399 if (template->direction == GST_PAD_SINK) {
400 if (gst_caps_is_always_compatible (caps, GST_PAD_TEMPLATE_CAPS (template)))
403 templates = g_list_next (templates);
410 * gst_element_factory_set_rank :
411 * @factory: factory to rank
412 * @rank: rank value - higher number means more priority rank
414 * Specifies a rank for the element so that
415 * autoplugging uses the most appropriate elements.
419 gst_element_factory_set_rank (GstElementFactory *factory, guint16 rank)
421 g_return_if_fail (factory != NULL);
422 factory->rank = rank;
426 gst_element_factory_unload_thyself (GstPluginFeature *feature)
428 GstElementFactory *factory;
430 factory = GST_ELEMENT_FACTORY (feature);