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 "gstregistry.h"
30 static void gst_element_factory_class_init (GstElementFactoryClass *klass);
31 static void gst_element_factory_init (GstElementFactory *factory);
33 static void gst_element_factory_unload_thyself (GstPluginFeature *feature);
35 static GstPluginFeatureClass *parent_class = NULL;
36 /* static guint gst_element_factory_signals[LAST_SIGNAL] = { 0 }; */
39 gst_element_factory_get_type (void)
41 static GType elementfactory_type = 0;
43 if (!elementfactory_type) {
44 static const GTypeInfo elementfactory_info = {
45 sizeof (GstElementFactoryClass),
48 (GClassInitFunc) gst_element_factory_class_init,
51 sizeof(GstElementFactory),
53 (GInstanceInitFunc) gst_element_factory_init,
56 elementfactory_type = g_type_register_static (GST_TYPE_PLUGIN_FEATURE,
57 "GstElementFactory", &elementfactory_info, 0);
59 return elementfactory_type;
63 gst_element_factory_class_init (GstElementFactoryClass *klass)
65 GObjectClass *gobject_class;
66 GstObjectClass *gstobject_class;
67 GstPluginFeatureClass *gstpluginfeature_class;
69 gobject_class = (GObjectClass*)klass;
70 gstobject_class = (GstObjectClass*)klass;
71 gstpluginfeature_class = (GstPluginFeatureClass*) klass;
73 parent_class = g_type_class_ref (GST_TYPE_PLUGIN_FEATURE);
75 gstpluginfeature_class->unload_thyself = GST_DEBUG_FUNCPTR (gst_element_factory_unload_thyself);
80 gst_element_factory_init (GstElementFactory *factory)
82 factory->padtemplates = NULL;
83 factory->numpadtemplates = 0;
87 * gst_element_factory_find:
88 * @name: name of factory to find
90 * Search for an element factory of the given name.
92 * Returns: #GstElementFactory if found, NULL otherwise
95 gst_element_factory_find (const gchar *name)
97 GstPluginFeature *feature;
99 g_return_val_if_fail(name != NULL, NULL);
101 feature = gst_registry_pool_find_feature (name, GST_TYPE_ELEMENT_FACTORY);
103 return GST_ELEMENT_FACTORY (feature);
105 /* this should be an ERROR */
106 GST_DEBUG (GST_CAT_ELEMENT_FACTORY,"no such elementfactory \"%s\"", name);
111 gst_element_details_free (GstElementDetails *dp)
113 g_return_if_fail (dp);
116 g_free (dp->longname);
120 g_free (dp->description);
122 g_free (dp->version);
126 g_free (dp->copyright);
131 * gst_element_factory_new:
132 * @name: name of new elementfactory
133 * @type: GType of new element
134 * @details: #GstElementDetails structure with element details
136 * Create a new elementfactory capable of insantiating objects of the
139 * Returns: new elementfactory
142 gst_element_factory_new (const gchar *name, GType type,
143 GstElementDetails *details)
145 GstElementFactory *factory;
147 g_return_val_if_fail (name != NULL, NULL);
148 g_return_val_if_fail (type, NULL);
149 g_return_val_if_fail (details, NULL);
151 factory = gst_element_factory_find (name);
154 factory = GST_ELEMENT_FACTORY (g_object_new (GST_TYPE_ELEMENT_FACTORY, NULL));
156 if (factory->details_dynamic) {
157 gst_element_details_free (factory->details);
158 factory->details_dynamic = FALSE;
161 factory->details = details;
164 factory->type = type;
165 else if (factory->type != type)
166 g_critical ("`%s' requested type change (!)", name);
168 GST_PLUGIN_FEATURE (factory)->name = g_strdup (name);
174 * gst_element_factory_create:
175 * @factory: factory to instantiate
176 * @name: name of new element
178 * Create a new element of the type defined by the given elementfactory.
179 * It will be given the name supplied, since all elements require a name as
180 * their first argument.
182 * Returns: new #GstElement
185 gst_element_factory_create (GstElementFactory *factory,
189 GstElementClass *oclass;
191 g_return_val_if_fail (factory != NULL, NULL);
193 if (!gst_plugin_feature_ensure_loaded (GST_PLUGIN_FEATURE (factory)))
196 GST_DEBUG (GST_CAT_ELEMENT_FACTORY,
197 "creating element from factory \"%s\" (name \"%s\", type %d)",
198 GST_OBJECT_NAME (factory), name, (gint) factory->type);
200 if (factory->type == 0) {
201 g_critical ("Factory for `%s' has no type",
202 GST_PLUGIN_FEATURE_NAME (factory));
206 /* create an instance of the element */
207 element = GST_ELEMENT (g_object_new (factory->type, NULL));
208 g_assert (element != NULL);
210 /* attempt to set the elemenfactory class pointer if necessary */
211 oclass = GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS (element));
212 if (oclass->elementfactory == NULL) {
213 GST_DEBUG (GST_CAT_ELEMENT_FACTORY, "class %s", GST_OBJECT_NAME (factory));
214 oclass->elementfactory = factory;
216 /* copy pad template pointers to the element class,
217 * allow for custom padtemplates */
218 oclass->padtemplates = g_list_concat (oclass->padtemplates,
219 g_list_copy (factory->padtemplates));
220 oclass->numpadtemplates += factory->numpadtemplates;
223 gst_object_set_name (GST_OBJECT (element), name);
229 * gst_element_factory_make:
230 * @factoryname: a named factory to instantiate
231 * @name: name of new element
233 * Create a new element of the type defined by the given element factory.
234 * If name is NULL, then the element will receive a guaranteed unique name,
235 * consisting of the element factory name and a number.
236 * If name is given, it will be given the name supplied.
238 * Returns: new #GstElement (or NULL if unable to create element)
241 gst_element_factory_make (const gchar *factoryname, const gchar *name)
243 GstElementFactory *factory;
246 g_return_val_if_fail (factoryname != NULL, NULL);
248 GST_DEBUG (GST_CAT_ELEMENT_FACTORY, "gstelementfactory: make \"%s\" \"%s\"",
251 /* gst_plugin_load_element_factory (factoryname); */
252 factory = gst_element_factory_find (factoryname);
253 if (factory == NULL) {
254 GST_INFO (GST_CAT_ELEMENT_FACTORY,"no such element factory \"%s\"!",
258 element = gst_element_factory_create (factory, name);
259 if (element == NULL) {
260 GST_INFO (GST_CAT_ELEMENT_FACTORY,
261 "couldn't create instance of element factory \"%s\"!",
270 * gst_element_factory_make_or_warn:
271 * @factoryname: a named factory to instantiate
272 * @name: name of new element
274 * Create a new element of the type defined by the given element factory
275 * using #gst_element_factory_make.
276 * Will use g_warning if the element could not be created.
278 * Returns: new #GstElement (or NULL if unable to create element)
281 gst_element_factory_make_or_warn (const gchar *factoryname, const gchar *name)
283 GstElement *element = gst_element_factory_make (factoryname, name);
286 g_warning ("Could not create element from factory %s !\n", factoryname);
292 * gst_element_factory_add_pad_template :
293 * @elementfactory: factory to add the src id to
294 * @templ: the padtemplate to add
296 * Add the given padtemplate to this elementfactory.
299 gst_element_factory_add_pad_template (GstElementFactory *factory,
300 GstPadTemplate *templ)
304 g_return_if_fail(factory != NULL);
305 g_return_if_fail(templ != NULL);
307 padtemplates = factory->padtemplates;
309 gst_object_ref (GST_OBJECT (templ));
311 while (padtemplates) {
312 GstPadTemplate *oldtempl = GST_PAD_TEMPLATE (padtemplates->data);
314 if (!strcmp (oldtempl->name_template, templ->name_template)) {
315 gst_object_unref (GST_OBJECT (oldtempl));
316 padtemplates->data = templ;
320 padtemplates = g_list_next (padtemplates);
322 factory->padtemplates = g_list_append (factory->padtemplates, templ);
323 factory->numpadtemplates++;
327 * gst_element_factory_can_src_caps :
328 * @factory: factory to query
329 * @caps: the caps to check
331 * Checks if the factory can source the given capability.
333 * Returns: true if it can src the capabilities
336 gst_element_factory_can_src_caps (GstElementFactory *factory,
341 g_return_val_if_fail(factory != NULL, FALSE);
342 g_return_val_if_fail(caps != NULL, FALSE);
344 templates = factory->padtemplates;
347 GstPadTemplate *template = (GstPadTemplate *)templates->data;
349 if (template->direction == GST_PAD_SRC) {
350 if (gst_caps_check_compatibility (GST_PAD_TEMPLATE_CAPS (template), caps))
353 templates = g_list_next (templates);
360 * gst_element_factory_can_sink_caps :
361 * @factory: factory to query
362 * @caps: the caps to check
364 * Checks if the factory can sink the given capability.
366 * Returns: true if it can sink the capabilities
369 gst_element_factory_can_sink_caps (GstElementFactory *factory,
374 g_return_val_if_fail(factory != NULL, FALSE);
375 g_return_val_if_fail(caps != NULL, FALSE);
377 templates = factory->padtemplates;
380 GstPadTemplate *template = (GstPadTemplate *)templates->data;
382 if (template->direction == GST_PAD_SINK) {
383 if (gst_caps_check_compatibility (caps, GST_PAD_TEMPLATE_CAPS (template)))
386 templates = g_list_next (templates);
393 * gst_element_factory_set_rank :
394 * @factory: factory to rank
395 * @rank: rank value - higher number means more priority rank
397 * Specifies a rank for the element so that
398 * autoplugging uses the most appropriate elements.
402 gst_element_factory_set_rank (GstElementFactory *factory, guint16 rank)
404 g_return_if_fail(factory != NULL);
405 factory->rank = rank;
409 gst_element_factory_unload_thyself (GstPluginFeature *feature)
411 GstElementFactory *factory;
413 factory = GST_ELEMENT_FACTORY (feature);