428f084d228e8a3bd6754b095de23ac029400750
[platform/upstream/gstreamer.git] / gst / gstplugin.c
1 /* Gnome-Streamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  * 
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 #include <dirent.h>
24 #include <unistd.h>
25 #include <string.h>
26
27 #include <gst/gstplugin.h>
28
29
30 /* list of loaded modules and its sequence number */
31 GList *_gst_modules;
32 gint _gst_modules_seqno;
33 /* global list of plugins and its sequence number */
34 GList *_gst_plugins;
35 gint _gst_plugins_seqno;
36 /* list of paths to check for plugins */
37 GList *_gst_plugin_paths;
38
39 /* whether or not to spew library load issues */
40 gboolean _gst_plugin_spew = FALSE;
41
42
43 void _gst_plugin_initialize() {
44   _gst_modules = NULL;
45   _gst_modules_seqno = 0;
46   _gst_plugins = NULL;
47   _gst_plugins_seqno = 0;
48   _gst_plugin_paths = NULL;
49
50   /* add the main (installed) library path */
51   _gst_plugin_paths = g_list_prepend(_gst_plugin_paths,PLUGINS_DIR);
52
53   /* if this is set, we add build-directory paths to the list */
54 #ifdef PLUGINS_USE_SRCDIR
55   /* the catch-all plugins directory */
56   _gst_plugin_paths = g_list_prepend(_gst_plugin_paths,
57                                      PLUGINS_SRCDIR "/plugins");
58   /* location libgstelements.so */
59   _gst_plugin_paths = g_list_prepend(_gst_plugin_paths,
60                                      PLUGINS_SRCDIR "/gst/elements");
61   _gst_plugin_paths = g_list_prepend(_gst_plugin_paths,
62                                      PLUGINS_SRCDIR "/gst/types");
63 #endif /* PLUGINS_USE_SRCDIR */
64 }
65
66 static gboolean gst_plugin_load_recurse(gchar *directory,gchar *name) {
67   DIR *dir;
68   struct dirent *dirent;
69   gboolean loaded = FALSE;
70
71   dir = opendir(directory);
72   if (dir) {
73     while (dirent = readdir(dir)) {
74       /* don't want to recurse in place or backwards */
75       if (strcmp(dirent->d_name,".") && strcmp(dirent->d_name,"..")) {
76         gst_plugin_load_recurse(g_strjoin("/",directory,dirent->d_name,
77                                               NULL),name);
78       }
79     }
80     closedir(dir);
81   } else {
82     if (strstr(directory,".so")) {
83       gchar *temp;
84       if (name) {
85         if ((temp = strstr(directory,name)) && 
86             (!strcmp(temp,name))) {
87           gst_plugin_load_absolute(directory);
88           return TRUE;
89         }
90       } else if ((temp = strstr(directory,".so")) &&
91                  (!strcmp(temp,".so"))) {
92         gst_plugin_load_absolute(directory);
93         loaded = TRUE;
94       }
95     }
96   }
97   return loaded;
98 }
99
100 /**
101  * gst_plugin_load_all:
102  *
103  * Load all plugins in the path.
104  */
105 void gst_plugin_load_all() {
106   GList *path;
107
108   path = _gst_plugin_paths;
109   while (path != NULL) {
110     gst_plugin_load_recurse(path->data,NULL);
111     path = g_list_next(path);
112   }
113 }
114
115 /**
116  * gst_plugin_load:
117  * @name: name of plugin to load
118  *
119  * Load the named plugin.  Name should be given as
120  * &quot;libplugin.so&quot;.
121  *
122  * Returns: whether the plugin was loaded or not
123  */
124 gboolean gst_plugin_load(gchar *name) {
125   GList *path;
126   gchar *libspath;
127
128 //  g_print("attempting to load plugin '%s'\n",name);
129
130   path = _gst_plugin_paths;
131   while (path != NULL) {
132     if (gst_plugin_load_absolute(g_module_build_path(path->data,name)))
133       return TRUE;
134     libspath = g_strconcat(path->data,"/.libs",NULL);
135 //    g_print("trying to load '%s'\n",g_module_build_path(libspath,name));
136     if (gst_plugin_load_absolute(g_module_build_path(libspath,name))) {
137       g_free(libspath);
138       return TRUE;
139     }
140     g_free(libspath);
141 //    g_print("trying to load '%s' from '%s'\n",name,path->data);
142     if (gst_plugin_load_recurse(path->data,name)) {
143       return TRUE;
144     }
145     path = g_list_next(path);
146   }
147   return FALSE;
148 }
149
150 /**
151  * gst_plugin_load_absolute:
152  * @name: name of plugin to load
153  *
154  * Returns: whether or not the plugin loaded
155  */
156 gboolean gst_plugin_load_absolute(gchar *name) {
157   GModule *module;
158   GstPluginInitFunc initfunc;
159   GstPlugin *plugin;
160
161 //  g_print("trying to load '%s\n",name);
162
163   if (g_module_supported() == FALSE) {
164     g_print("wow, you built this on a platform without dynamic loading???\n");
165     return;
166   }
167
168   module = g_module_open(name,0);
169   if (module != NULL) {
170     if (g_module_symbol(module,"plugin_init",(gpointer *)&initfunc)) {
171       if (plugin = (initfunc)(module)) {
172         GList *factories;
173         plugin->filename = g_strdup(name);
174         _gst_modules = g_list_append(_gst_modules,module);
175         _gst_modules_seqno++;
176         _gst_plugins = g_list_append(_gst_plugins,plugin);
177         _gst_plugins_seqno++;
178         factories = plugin->elements;
179         while (factories) {
180           gst_elementfactory_register((GstElementFactory*)(factories->data));
181           factories = g_list_next(factories);
182         }
183         return TRUE;
184       }
185     }
186   } else if (_gst_plugin_spew) {
187 //    if (strstr(g_module_error(),"No such") == NULL)
188       gst_info("error loading plugin: %s\n",g_module_error());
189   }
190
191   return FALSE;
192 }
193
194 /**
195  * gst_plugin_new:
196  * @name: name of new plugin
197  *
198  * Create a new plugin with given name.
199  *
200  * Returns: new plugin
201  */
202 GstPlugin *gst_plugin_new(gchar *name) {
203   GstPlugin *plugin = (GstPlugin *)malloc(sizeof(GstPlugin));
204
205   plugin->name = g_strdup(name);
206   plugin->longname = NULL;
207   plugin->types = NULL;
208   plugin->elements = NULL;
209
210   return plugin;
211 }
212
213 /**
214  * gst_plugin_set_longname:
215  * @plugin: plugin to set long name of
216  * @longname: new long name
217  *
218  * Sets the long name (should be descriptive) of the plugin.
219  */
220 void gst_plugin_set_longname(GstPlugin *plugin,gchar *longname) {
221   g_return_if_fail(plugin != NULL);
222
223   if (plugin->longname) g_free(plugin->longname);
224   plugin->longname = g_strdup(longname);
225 }
226
227 /**
228  * gst_plugin_find:
229  * @name: name of plugin to find
230  *
231  * Search the list of registered plugins for one of the given name
232  *
233  * Returns: pointer to the #GstPlugin if found, NULL otherwise
234  */
235 GstPlugin *gst_plugin_find(gchar *name) {
236   GList *plugins = _gst_plugins;
237
238   g_return_if_fail(name != NULL);
239
240   while (plugins) {
241     GstPlugin *plugin = (GstPlugin *)plugins->data;
242 //    g_print("plugin name is '%s'\n",plugin->name);
243     if (plugin->name) {
244       if (!strcmp(plugin->name,name))
245         return plugin;
246     }
247     plugins = g_list_next(plugins);
248   }
249   return NULL;
250 }
251
252 /** 
253  * gst_plugin_find_elementfactory:
254  * @name: name of elementfactory to find
255  *
256  * Find a registered elementfactory by name.
257  *
258  * Returns: @GstElementFactory if found, NULL if not
259  */
260 GstElementFactory *gst_plugin_find_elementfactory(gchar *name) {
261   GList *plugins, *factories;
262   GstElementFactory *factory;
263
264   g_return_if_fail(name != NULL);
265
266   plugins = _gst_plugins;
267   while (plugins) {
268     factories = ((GstPlugin *)(plugins->data))->elements;
269     while (factories) {
270       factory = (GstElementFactory*)(factories->data);
271       if (!strcmp(gst_element_get_name(GST_ELEMENT(factory)),name))
272         return (GstElementFactory*)(factory);
273       factories = g_list_next(factories);
274     }
275     plugins = g_list_next(plugins);
276   }
277
278   return NULL;
279 }
280
281 /**
282  * gst_plugin_add_factory:
283  * @plugin: plugin to add factory to
284  * @factory: factory to add
285  *
286  * Add factory to the list of those provided by the element.
287  */
288 void gst_plugin_add_factory(GstPlugin *plugin,GstElementFactory *factory) {
289   g_return_if_fail(plugin != NULL);
290   g_return_if_fail(factory != NULL);
291
292 //  g_print("adding factory to plugin\n");
293   plugin->elements = g_list_append(plugin->elements,factory);
294 }
295
296 GList *gst_plugin_get_list() {
297   return _gst_plugins;
298 }