Implemented riff parsing as a library. The avi parser can play simple PCM encoded...
[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   /* the libreary directory */
59   _gst_plugin_paths = g_list_prepend(_gst_plugin_paths,
60                                      PLUGINS_SRCDIR "/libs");
61   /* location libgstelements.so */
62   _gst_plugin_paths = g_list_prepend(_gst_plugin_paths,
63                                      PLUGINS_SRCDIR "/gst/elements");
64   _gst_plugin_paths = g_list_prepend(_gst_plugin_paths,
65                                      PLUGINS_SRCDIR "/gst/types");
66 #endif /* PLUGINS_USE_SRCDIR */
67 }
68
69 static gboolean gst_plugin_load_recurse(gchar *directory,gchar *name) {
70   DIR *dir;
71   struct dirent *dirent;
72   gboolean loaded = FALSE;
73
74         //g_print("recursive load of '%s' in '%s'\n", name, directory);
75   dir = opendir(directory);
76   if (dir) {
77     while ((dirent = readdir(dir))) {
78       /* don't want to recurse in place or backwards */
79       if (strcmp(dirent->d_name,".") && strcmp(dirent->d_name,"..")) {
80         loaded = gst_plugin_load_recurse(g_strjoin("/",directory,dirent->d_name,
81                                               NULL),name);
82                                 if (loaded && name) return TRUE;
83       }
84     }
85     closedir(dir);
86   } else {
87     if (strstr(directory,".so")) {
88       gchar *temp;
89       if (name) {
90         if ((temp = strstr(directory,name)) && 
91             (!strcmp(temp,name))) {
92           loaded = gst_plugin_load_absolute(directory);
93           return loaded;
94         }
95       } else if ((temp = strstr(directory,".so")) &&
96                  (!strcmp(temp,".so"))) {
97         loaded = gst_plugin_load_absolute(directory);
98         //return loaded;
99       }
100     }
101   }
102   return loaded;
103 }
104
105 /**
106  * gst_plugin_load_all:
107  *
108  * Load all plugins in the path.
109  */
110 void gst_plugin_load_all() {
111   GList *path;
112
113   path = _gst_plugin_paths;
114   while (path != NULL) {
115     gst_plugin_load_recurse(path->data,NULL);
116     path = g_list_next(path);
117   }
118 }
119
120 /**
121  * gst_library_load:
122  * @name: name of liabrary to load
123  *
124  * Load the named liabrary.  Name should be given as
125  * &quot;libliabrary.so&quot;.
126  *
127  * Returns: whether the liabrary was loaded or not
128  */
129 gboolean gst_library_load(gchar *name) {
130         // for now this is the same
131   return gst_plugin_load(name);
132 }
133 /**
134  * gst_plugin_load:
135  * @name: name of plugin to load
136  *
137  * Load the named plugin.  Name should be given as
138  * &quot;libplugin.so&quot;.
139  *
140  * Returns: whether the plugin was loaded or not
141  */
142 gboolean gst_plugin_load(gchar *name) {
143   GList *path;
144   gchar *libspath;
145
146 //  g_print("attempting to load plugin '%s'\n",name);
147
148   path = _gst_plugin_paths;
149   while (path != NULL) {
150     if (gst_plugin_load_absolute(g_module_build_path(path->data,name)))
151       return TRUE;
152     libspath = g_strconcat(path->data,"/.libs",NULL);
153     //g_print("trying to load '%s'\n",g_module_build_path(libspath,name));
154     if (gst_plugin_load_absolute(g_module_build_path(libspath,name))) {
155       g_free(libspath);
156       return TRUE;
157     }
158     g_free(libspath);
159     //g_print("trying to load '%s' from '%s'\n",name,path->data);
160     if (gst_plugin_load_recurse(path->data,g_module_build_path("",name))) {
161       return TRUE;
162     }
163     path = g_list_next(path);
164   }
165   return FALSE;
166 }
167
168 /**
169  * gst_plugin_load_absolute:
170  * @name: name of plugin to load
171  *
172  * Returns: whether or not the plugin loaded
173  */
174 gboolean gst_plugin_load_absolute(gchar *name) {
175   GModule *module;
176   GstPluginInitFunc initfunc;
177   GstPlugin *plugin;
178
179   //g_print("trying to absolute load '%s\n",name);
180
181   if (g_module_supported() == FALSE) {
182     g_print("wow, you built this on a platform without dynamic loading???\n");
183     return FALSE;
184   }
185
186   module = g_module_open(name,G_MODULE_BIND_LAZY);
187   if (module != NULL) {
188     if (g_module_symbol(module,"plugin_init",(gpointer *)&initfunc)) {
189       if ((plugin = (initfunc)(module))) {
190         GList *factories;
191         plugin->filename = g_strdup(name);
192         _gst_modules = g_list_append(_gst_modules,module);
193         _gst_modules_seqno++;
194         _gst_plugins = g_list_append(_gst_plugins,plugin);
195         _gst_plugins_seqno++;
196         factories = plugin->elements;
197         while (factories) {
198           gst_elementfactory_register((GstElementFactory*)(factories->data));
199           factories = g_list_next(factories);
200         }
201         return TRUE;
202       }
203     }
204                 return TRUE;
205   } else if (_gst_plugin_spew) {
206 //    if (strstr(g_module_error(),"No such") == NULL)
207       gst_info("error loading plugin: %s\n",g_module_error());
208   }
209
210   return FALSE;
211 }
212
213 /**
214  * gst_plugin_new:
215  * @name: name of new plugin
216  *
217  * Create a new plugin with given name.
218  *
219  * Returns: new plugin
220  */
221 GstPlugin *gst_plugin_new(gchar *name) {
222   GstPlugin *plugin = (GstPlugin *)g_malloc(sizeof(GstPlugin));
223
224   plugin->name = g_strdup(name);
225   plugin->longname = NULL;
226   plugin->types = NULL;
227   plugin->elements = NULL;
228
229   return plugin;
230 }
231
232 /**
233  * gst_plugin_set_longname:
234  * @plugin: plugin to set long name of
235  * @longname: new long name
236  *
237  * Sets the long name (should be descriptive) of the plugin.
238  */
239 void gst_plugin_set_longname(GstPlugin *plugin,gchar *longname) {
240   g_return_if_fail(plugin != NULL);
241
242   if (plugin->longname) g_free(plugin->longname);
243   plugin->longname = g_strdup(longname);
244 }
245
246 /**
247  * gst_plugin_find:
248  * @name: name of plugin to find
249  *
250  * Search the list of registered plugins for one of the given name
251  *
252  * Returns: pointer to the #GstPlugin if found, NULL otherwise
253  */
254 GstPlugin *gst_plugin_find(gchar *name) {
255   GList *plugins = _gst_plugins;
256
257   g_return_val_if_fail(name != NULL, NULL);
258
259   while (plugins) {
260     GstPlugin *plugin = (GstPlugin *)plugins->data;
261 //    g_print("plugin name is '%s'\n",plugin->name);
262     if (plugin->name) {
263       if (!strcmp(plugin->name,name))
264         return plugin;
265     }
266     plugins = g_list_next(plugins);
267   }
268   return NULL;
269 }
270
271 /** 
272  * gst_plugin_find_elementfactory:
273  * @name: name of elementfactory to find
274  *
275  * Find a registered elementfactory by name.
276  *
277  * Returns: @GstElementFactory if found, NULL if not
278  */
279 GstElementFactory *gst_plugin_find_elementfactory(gchar *name) {
280   GList *plugins, *factories;
281   GstElementFactory *factory;
282
283   g_return_val_if_fail(name != NULL, NULL);
284
285   plugins = _gst_plugins;
286   while (plugins) {
287     factories = ((GstPlugin *)(plugins->data))->elements;
288     while (factories) {
289       factory = (GstElementFactory*)(factories->data);
290       if (!strcmp(gst_element_get_name(GST_ELEMENT(factory)),name))
291         return (GstElementFactory*)(factory);
292       factories = g_list_next(factories);
293     }
294     plugins = g_list_next(plugins);
295   }
296
297   return NULL;
298 }
299
300 /**
301  * gst_plugin_add_factory:
302  * @plugin: plugin to add factory to
303  * @factory: factory to add
304  *
305  * Add factory to the list of those provided by the element.
306  */
307 void gst_plugin_add_factory(GstPlugin *plugin,GstElementFactory *factory) {
308   g_return_if_fail(plugin != NULL);
309   g_return_if_fail(factory != NULL);
310
311 //  g_print("adding factory to plugin\n");
312   plugin->elements = g_list_append(plugin->elements,factory);
313 }
314
315 GList *gst_plugin_get_list() {
316   return _gst_plugins;
317 }