GST_DEBUG reorganization containing loads of stuff:
[platform/upstream/gstreamer.git] / gst / gstelementfactory.c
1 /* GStreamer
2  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3  *                    2000 Wim Taymans <wtay@chello.be>
4  *
5  * gstelementfactory.c: GstElementFactory object, support routines
6  *
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.
11  *
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.
16  *
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.
21  */
22
23 #include "gst_private.h"
24
25 #include "gstelement.h"
26 #include "gstregistrypool.h"
27 #include "gstinfo.h"
28
29 static void             gst_element_factory_class_init          (GstElementFactoryClass *klass);
30 static void             gst_element_factory_init                (GstElementFactory *factory);
31
32 static void             gst_element_factory_unload_thyself      (GstPluginFeature *feature);
33
34 static GstPluginFeatureClass *parent_class = NULL;
35 /* static guint gst_element_factory_signals[LAST_SIGNAL] = { 0 }; */
36
37 GType 
38 gst_element_factory_get_type (void) 
39 {
40   static GType elementfactory_type = 0;
41
42   if (!elementfactory_type) {
43     static const GTypeInfo elementfactory_info = {
44       sizeof (GstElementFactoryClass),
45       NULL,
46       NULL,
47       (GClassInitFunc) gst_element_factory_class_init,
48       NULL,
49       NULL,
50       sizeof(GstElementFactory),
51       0,
52       (GInstanceInitFunc) gst_element_factory_init,
53       NULL
54     };
55     elementfactory_type = g_type_register_static (GST_TYPE_PLUGIN_FEATURE, 
56                                                   "GstElementFactory", &elementfactory_info, 0);
57   }
58   return elementfactory_type;
59 }
60
61 static void
62 gst_element_factory_class_init (GstElementFactoryClass *klass)
63 {
64   GObjectClass *gobject_class;
65   GstObjectClass *gstobject_class;
66   GstPluginFeatureClass *gstpluginfeature_class;
67
68   gobject_class = (GObjectClass*)klass;
69   gstobject_class = (GstObjectClass*)klass;
70   gstpluginfeature_class = (GstPluginFeatureClass*) klass;
71
72   parent_class = g_type_class_ref (GST_TYPE_PLUGIN_FEATURE);
73
74   gstpluginfeature_class->unload_thyself =      GST_DEBUG_FUNCPTR (gst_element_factory_unload_thyself);
75
76 }
77
78 static void
79 gst_element_factory_init (GstElementFactory *factory)
80 {
81   factory->padtemplates = NULL;
82   factory->numpadtemplates = 0;
83 }
84
85 /**
86  * gst_element_factory_find:
87  * @name: name of factory to find
88  *
89  * Search for an element factory of the given name.
90  *
91  * Returns: #GstElementFactory if found, NULL otherwise
92  */
93 GstElementFactory*
94 gst_element_factory_find (const gchar *name)
95 {
96   GstPluginFeature *feature;
97
98   g_return_val_if_fail(name != NULL, NULL);
99
100   feature = gst_registry_pool_find_feature (name, GST_TYPE_ELEMENT_FACTORY);
101   if (feature)
102     return GST_ELEMENT_FACTORY (feature);
103
104   /* this should be an ERROR */
105   GST_CAT_DEBUG (GST_CAT_ELEMENT_FACTORY,"no such elementfactory \"%s\"", name);
106   return NULL;
107 }
108
109 static void
110 gst_element_details_free (GstElementDetails *dp)
111 {
112   g_free (dp->longname);
113   g_free (dp->klass);
114   g_free (dp->license);
115   g_free (dp->description);
116   g_free (dp->version);
117   g_free (dp->author);
118   g_free (dp->copyright);
119   g_free (dp);
120 }
121
122 static void
123 gst_element_factory_cleanup (GstElementFactory *factory)
124 {
125   GList *padtemplates;
126
127   if (factory->details_dynamic) {
128     gst_element_details_free (factory->details);
129     factory->details_dynamic = FALSE;
130   }
131
132   padtemplates = factory->padtemplates;
133
134   while (padtemplates) {
135     GstPadTemplate *oldtempl = GST_PAD_TEMPLATE (padtemplates->data);
136      
137     gst_object_unref (GST_OBJECT (oldtempl));
138
139     padtemplates = g_list_next (padtemplates);
140   }
141   g_list_free (factory->padtemplates);
142
143   factory->padtemplates = NULL;
144   factory->numpadtemplates = 0;
145
146   g_free (GST_PLUGIN_FEATURE (factory)->name);
147 }
148
149 /**
150  * gst_element_factory_new:
151  * @name: name of new elementfactory
152  * @type: GType of new element
153  * @details: #GstElementDetails structure with element details
154  *
155  * Create a new elementfactory capable of insantiating objects of the
156  * given type.
157  *
158  * Returns: new elementfactory
159  */
160 GstElementFactory*
161 gst_element_factory_new (const gchar *name, GType type,
162                         GstElementDetails *details)
163 {
164   GstElementFactory *factory;
165
166   g_return_val_if_fail (name != NULL, NULL);
167   g_return_val_if_fail (type, NULL);
168   g_return_val_if_fail (details, NULL);
169
170   factory = gst_element_factory_find (name);
171
172   if (!factory)
173     factory = GST_ELEMENT_FACTORY (g_object_new (GST_TYPE_ELEMENT_FACTORY, NULL));
174   else {
175     gst_element_factory_cleanup (factory);
176   }
177
178   factory->details = details;
179   factory->details_dynamic = FALSE;
180
181   if (!factory->type)
182     factory->type = type;
183   else if (factory->type != type)
184     g_critical ("`%s' requested type change (!)", name);
185
186   GST_PLUGIN_FEATURE (factory)->name = g_strdup (name);
187
188   return factory;
189 }
190
191 /**
192  * gst_element_factory_create:
193  * @factory: factory to instantiate
194  * @name: name of new element
195  *
196  * Create a new element of the type defined by the given elementfactory.
197  * It will be given the name supplied, since all elements require a name as
198  * their first argument.
199  *
200  * Returns: new #GstElement
201  */
202 GstElement*
203 gst_element_factory_create (GstElementFactory *factory,
204                            const gchar *name)
205 {
206   GstElement *element;
207   GstElementClass *oclass;
208
209   g_return_val_if_fail (factory != NULL, NULL);
210
211   if (!gst_plugin_feature_ensure_loaded (GST_PLUGIN_FEATURE (factory)))
212     return NULL;
213
214   GST_CAT_DEBUG (GST_CAT_ELEMENT_FACTORY,
215              "creating element from factory \"%s\" (name \"%s\", type %d)", 
216              GST_PLUGIN_FEATURE_NAME (factory), GST_STR_NULL (name), (gint) factory->type);
217
218   if (factory->type == 0) {
219       g_critical ("Factory for `%s' has no type",
220                   GST_PLUGIN_FEATURE_NAME (factory));
221       return NULL;
222   }
223
224   /* attempt to set the elementfactory class pointer if necessary */
225   oclass = GST_ELEMENT_CLASS (g_type_class_ref (factory->type));
226   if (oclass->elementfactory == NULL) {
227     GST_CAT_DEBUG (GST_CAT_ELEMENT_FACTORY, "class %s", GST_PLUGIN_FEATURE_NAME (factory));
228     oclass->elementfactory = factory;
229
230     /* copy pad template pointers to the element class, 
231      * allow for custom padtemplates */
232     oclass->padtemplates = g_list_concat (oclass->padtemplates, 
233                     g_list_copy (factory->padtemplates));
234     oclass->numpadtemplates += factory->numpadtemplates;
235   }
236
237   /* create an instance of the element */
238   element = GST_ELEMENT (g_object_new (factory->type, NULL));
239   g_assert (element != NULL);
240
241   g_type_class_unref (oclass);
242
243   gst_object_set_name (GST_OBJECT (element), name);
244
245   return element;
246 }
247
248 /**
249  * gst_element_factory_make:
250  * @factoryname: a named factory to instantiate
251  * @name: name of new element
252  *
253  * Create a new element of the type defined by the given element factory.
254  * If name is NULL, then the element will receive a guaranteed unique name,
255  * consisting of the element factory name and a number.
256  * If name is given, it will be given the name supplied.
257  *
258  * Returns: new #GstElement (or NULL if unable to create element)
259  */
260 GstElement*
261 gst_element_factory_make (const gchar *factoryname, const gchar *name)
262 {
263   GstElementFactory *factory;
264   GstElement *element;
265
266   g_return_val_if_fail (factoryname != NULL, NULL);
267
268   GST_CAT_DEBUG (GST_CAT_ELEMENT_FACTORY, "gstelementfactory: make \"%s\" \"%s\"", 
269              factoryname, GST_STR_NULL (name));
270
271   /* gst_plugin_load_element_factory (factoryname); */
272   factory = gst_element_factory_find (factoryname);
273   if (factory == NULL) {
274     GST_CAT_INFO (GST_CAT_ELEMENT_FACTORY,"no such element factory \"%s\"!",
275               factoryname);
276     return NULL;
277   }
278   element = gst_element_factory_create (factory, name);
279   if (element == NULL) {
280     GST_CAT_INFO (GST_CAT_ELEMENT_FACTORY,
281               "couldn't create instance of element factory \"%s\"!",
282               factoryname);
283     return NULL;
284   }
285
286   return element;
287 }
288
289 /**
290  * gst_element_factory_make_or_warn:
291  * @factoryname: a named factory to instantiate
292  * @name: name of new element
293  *
294  * Create a new element of the type defined by the given element factory
295  * using #gst_element_factory_make.
296  * Will use g_warning if the element could not be created.
297  *
298  * Returns: new #GstElement (or NULL if unable to create element)
299  */
300 GstElement*
301 gst_element_factory_make_or_warn (const gchar *factoryname, const gchar *name)
302 {
303   GstElement *element;
304   
305   element = gst_element_factory_make (factoryname, name);
306
307   if (element == NULL) 
308     g_warning ("Could not create element from factory %s !\n", factoryname);
309
310   return element;
311 }
312     
313 /**
314  * gst_element_factory_add_pad_template :
315  * @elementfactory: factory to add the src id to
316  * @templ: the padtemplate to add
317  *
318  * Add the given padtemplate to this elementfactory.
319  */
320 void
321 gst_element_factory_add_pad_template (GstElementFactory *factory,
322                                       GstPadTemplate *templ)
323 {
324   g_return_if_fail (factory != NULL);
325   g_return_if_fail (templ != NULL);
326
327   gst_object_ref (GST_OBJECT (templ));
328   gst_object_sink (GST_OBJECT (templ));
329
330   factory->padtemplates = g_list_append (factory->padtemplates, templ);
331   factory->numpadtemplates++;
332 }
333
334 /**
335  * gst_element_factory_can_src_caps :
336  * @factory: factory to query
337  * @caps: the caps to check
338  *
339  * Checks if the factory can source the given capability.
340  *
341  * Returns: true if it can src the capabilities
342  */
343 gboolean
344 gst_element_factory_can_src_caps (GstElementFactory *factory,
345                                  GstCaps *caps)
346 {
347   GList *templates;
348
349   g_return_val_if_fail(factory != NULL, FALSE);
350   g_return_val_if_fail(caps != NULL, FALSE);
351
352   templates = factory->padtemplates;
353
354   while (templates) {
355     GstPadTemplate *template = (GstPadTemplate *)templates->data;
356
357     if (template->direction == GST_PAD_SRC) {
358       if (gst_caps_is_always_compatible (GST_PAD_TEMPLATE_CAPS (template), caps))
359         return TRUE;
360     }
361     templates = g_list_next (templates);
362   }
363
364   return FALSE;
365 }
366
367 /**
368  * gst_element_factory_can_sink_caps :
369  * @factory: factory to query
370  * @caps: the caps to check
371  *
372  * Checks if the factory can sink the given capability.
373  *
374  * Returns: true if it can sink the capabilities
375  */
376 gboolean
377 gst_element_factory_can_sink_caps (GstElementFactory *factory,
378                                   GstCaps *caps)
379 {
380   GList *templates;
381
382   g_return_val_if_fail(factory != NULL, FALSE);
383   g_return_val_if_fail(caps != NULL, FALSE);
384
385   templates = factory->padtemplates;
386
387   while (templates) {
388     GstPadTemplate *template = (GstPadTemplate *)templates->data;
389
390     if (template->direction == GST_PAD_SINK) {
391       if (gst_caps_is_always_compatible (caps, GST_PAD_TEMPLATE_CAPS (template)))
392         return TRUE;
393     }
394     templates = g_list_next (templates);
395   }
396
397   return FALSE;
398 }
399
400 /**
401  * gst_element_factory_set_rank  :
402  * @factory: factory to rank
403  * @rank: rank value - higher number means more priority rank
404  *
405  * Specifies a rank for the element so that 
406  * autoplugging uses the most appropriate elements.
407  *
408  */
409 void
410 gst_element_factory_set_rank (GstElementFactory *factory, guint16 rank)
411 {
412   g_return_if_fail (factory != NULL);
413   factory->rank = rank;
414 }
415
416 static void
417 gst_element_factory_unload_thyself (GstPluginFeature *feature)
418 {
419   GstElementFactory *factory;
420
421   factory = GST_ELEMENT_FACTORY (feature);
422
423   factory->type = 0;
424 }