2 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3 * 2000 Wim Taymans <wtay@chello.be>
5 * gstplugin.c: Plugin subsystem for loading elements, types, and libs
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 <sys/types.h>
30 #include "gst_private.h"
31 #include "gstplugin.h"
32 #include "gstversion.h"
36 /* list of loaded modules and its sequence number */
38 gint _gst_modules_seqno;
39 /* global list of plugins and its sequence number */
41 gint _gst_plugins_seqno;
42 gint _gst_plugin_elementfactories = 0;
43 gint _gst_plugin_types = 0;
44 /* list of paths to check for plugins */
45 GList *_gst_plugin_paths;
47 GList *_gst_libraries;
48 gint _gst_libraries_seqno;
50 /* whether or not to spew library load issues */
51 gboolean _gst_plugin_spew = FALSE;
53 /* whether or not to warn if registry needs rebuild (gstreamer-register sets
55 gboolean _gst_warn_old_registry = TRUE;
57 static gboolean plugin_times_older_than(time_t regtime);
58 static time_t get_time(const char * path);
61 _gst_plugin_initialize (void)
65 _gst_modules_seqno = 0;
67 _gst_plugins_seqno = 0;
68 _gst_plugin_paths = NULL;
69 _gst_libraries = NULL;
70 _gst_libraries_seqno = 0;
72 /* add the main (installed) library path */
73 _gst_plugin_paths = g_list_prepend (_gst_plugin_paths, PLUGINS_DIR);
75 /* if this is set, we add build-directory paths to the list */
76 #ifdef PLUGINS_USE_SRCDIR
77 /* the catch-all plugins directory */
78 _gst_plugin_paths = g_list_prepend (_gst_plugin_paths,
79 PLUGINS_SRCDIR "/plugins");
80 /* the libreary directory */
81 _gst_plugin_paths = g_list_prepend (_gst_plugin_paths,
82 PLUGINS_SRCDIR "/libs");
83 /* location libgstelements.so */
84 _gst_plugin_paths = g_list_prepend (_gst_plugin_paths,
85 PLUGINS_SRCDIR "/gst/elements");
86 _gst_plugin_paths = g_list_prepend (_gst_plugin_paths,
87 PLUGINS_SRCDIR "/gst/types");
88 _gst_plugin_paths = g_list_prepend (_gst_plugin_paths,
89 PLUGINS_SRCDIR "/gst/autoplug");
90 #endif /* PLUGINS_USE_SRCDIR */
92 doc = xmlParseFile (GST_CONFIG_DIR"/reg.xml");
96 doc->xmlRootNode->name == 0 ||
97 strcmp (doc->xmlRootNode->name, "GST-PluginRegistry") ||
98 !plugin_times_older_than(get_time(GST_CONFIG_DIR"/reg.xml"))) {
99 if (_gst_warn_old_registry)
100 g_warning ("gstplugin: registry needs rebuild: run gstreamer-register\n");
101 gst_plugin_load_all ();
104 gst_plugin_load_thyself (doc->xmlRootNode);
110 * gst_plugin_add_path:
111 * @path: the directory to add to the search path
113 * Add a directory to the path searched for plugins.
116 gst_plugin_add_path (const gchar *path)
118 _gst_plugin_paths = g_list_prepend (_gst_plugin_paths,g_strdup(path));
122 get_time(const char * path)
125 if (stat(path, &statbuf)) return 0;
126 if (statbuf.st_mtime > statbuf.st_ctime) return statbuf.st_mtime;
127 return statbuf.st_ctime;
131 plugin_times_older_than_recurse(gchar *path, time_t regtime)
134 struct dirent *dirent;
137 time_t pathtime = get_time(path);
139 if (pathtime > regtime) {
140 GST_INFO (GST_CAT_PLUGIN_LOADING,
141 "time for %s was %ld; more recent than registry time of %ld\n",
142 path, (long)pathtime, (long)regtime);
148 while ((dirent = readdir(dir))) {
149 /* don't want to recurse in place or backwards */
150 if (strcmp(dirent->d_name,".") && strcmp(dirent->d_name,"..")) {
151 pluginname = g_strjoin("/",path,dirent->d_name,NULL);
152 if (!plugin_times_older_than_recurse(pluginname , regtime)) {
166 plugin_times_older_than(time_t regtime)
168 // return true iff regtime is more recent than the times of all the files
169 // in the plugin dirs.
171 path = _gst_plugin_paths;
172 while (path != NULL) {
173 GST_DEBUG (GST_CAT_PLUGIN_LOADING,
174 "comparing plugin times from %s with %ld\n",
175 (gchar *)path->data, (long) regtime);
176 if(!plugin_times_older_than_recurse(path->data, regtime))
178 path = g_list_next(path);
184 gst_plugin_load_recurse (gchar *directory, gchar *name)
187 struct dirent *dirent;
188 gboolean loaded = FALSE;
191 //g_print("recursive load of '%s' in '%s'\n", name, directory);
192 dir = opendir(directory);
194 while ((dirent = readdir(dir))) {
195 /* don't want to recurse in place or backwards */
196 if (strcmp(dirent->d_name,".") && strcmp(dirent->d_name,"..")) {
197 dirname = g_strjoin("/",directory,dirent->d_name,NULL);
198 loaded = gst_plugin_load_recurse(dirname,name);
200 if (loaded && name) {
208 if (strstr(directory,".so")) {
211 if ((temp = strstr(directory,name)) &&
212 (!strcmp(temp,name))) {
213 loaded = gst_plugin_load_absolute(directory);
215 } else if ((temp = strstr(directory,".so")) &&
216 (!strcmp(temp,".so"))) {
217 loaded = gst_plugin_load_absolute(directory);
225 * gst_plugin_load_all:
227 * Load all plugins in the path.
230 gst_plugin_load_all(void)
234 path = _gst_plugin_paths;
235 while (path != NULL) {
236 GST_INFO (GST_CAT_PLUGIN_LOADING,"loading plugins from %s",(gchar *)path->data);
237 gst_plugin_load_recurse(path->data,NULL);
238 path = g_list_next(path);
240 GST_INFO (GST_CAT_PLUGIN_LOADING,"loaded %d plugins with %d elements and %d types",
241 _gst_plugins_seqno,_gst_plugin_elementfactories,_gst_plugin_types);
246 * @name: name of library to load
248 * Load the named library. Name should be given as
249 * "liblibrary.so".
251 * Returns: whether the library was loaded or not
254 gst_library_load (const gchar *name)
257 GList *libraries = _gst_libraries;
260 if (!strcmp((gchar *)libraries->data, name)) return TRUE;
262 libraries = g_list_next(libraries);
265 // for now this is the same
266 res = gst_plugin_load(name);
269 _gst_libraries = g_list_prepend(_gst_libraries, g_strdup (name));
276 gst_plugin_remove (GstPlugin *plugin)
280 factories = plugin->elements;
282 gst_elementfactory_destroy ((GstElementFactory*)(factories->data));
283 factories = g_list_next(factories);
286 _gst_plugins = g_list_remove(_gst_plugins, plugin);
288 // don't free the stuct because someone can have a handle to it
293 * @name: name of plugin to load
295 * Load the named plugin. Name should be given as
296 * "libplugin.so".
298 * Returns: whether the plugin was loaded or not
301 gst_plugin_load (const gchar *name)
308 //g_print("attempting to load plugin '%s'\n",name);
310 plugin = gst_plugin_find (name);
312 if (plugin && plugin->loaded) return TRUE;
314 path = _gst_plugin_paths;
315 while (path != NULL) {
316 pluginname = g_module_build_path(path->data,name);
317 if (gst_plugin_load_absolute(pluginname)) {
322 libspath = g_strconcat(path->data,"/.libs",NULL);
323 //g_print("trying to load '%s'\n",g_module_build_path(libspath,name));
324 pluginname = g_module_build_path(libspath,name);
326 if (gst_plugin_load_absolute(pluginname)) {
331 //g_print("trying to load '%s' from '%s'\n",name,path->data);
332 pluginname = g_module_build_path("",name);
333 if (gst_plugin_load_recurse(path->data,pluginname)) {
338 path = g_list_next(path);
344 * gst_plugin_load_absolute:
345 * @name: name of plugin to load
347 * Returns: whether or not the plugin loaded
350 gst_plugin_load_absolute (const gchar *name)
355 struct stat file_status;
357 GST_INFO (GST_CAT_PLUGIN_LOADING,"plugin \"%s\" loading", name);
359 if (g_module_supported() == FALSE) {
360 g_warning("gstplugin: wow, you built this on a platform without dynamic loading???\n");
364 if (stat(name,&file_status)) {
365 //g_print("problem opening file %s\n",name);
369 module = g_module_open(name,G_MODULE_BIND_LAZY);
370 if (module != NULL) {
371 if (g_module_symbol(module,"plugin_desc",(gpointer *)&desc)) {
372 GST_INFO (GST_CAT_PLUGIN_LOADING,"loading plugin \"%s\"...", name);
373 plugin = gst_plugin_new(desc->name, desc->major_version, desc->minor_version);
374 if (plugin != NULL) {
375 plugin->filename = g_strdup(name);
376 if (!((desc->plugin_init)(module, plugin))) {
377 GST_INFO (GST_CAT_PLUGIN_LOADING,"plugin \"%s\" failed to initialise",
384 if (plugin != NULL) {
385 GST_INFO (GST_CAT_PLUGIN_LOADING,"plugin \"%s\" loaded: %d elements, %d types",
386 plugin->name,plugin->numelements,plugin->numtypes);
387 plugin->loaded = TRUE;
388 _gst_modules = g_list_prepend(_gst_modules,module);
389 _gst_modules_seqno++;
390 _gst_plugins = g_list_prepend(_gst_plugins,plugin);
391 _gst_plugins_seqno++;
392 _gst_plugin_elementfactories += plugin->numelements;
393 _gst_plugin_types += plugin->numtypes;
398 } else if (_gst_plugin_spew) {
399 // FIXME this should be some standard gst mechanism!!!
400 g_printerr ("error loading plugin %s, reason: %s\n", name, g_module_error());
403 GST_INFO (GST_CAT_PLUGIN_LOADING, "error loading plugin %s, reason: %s\n", name, g_module_error());
411 * @name: name of new plugin
412 * @major: major version number of core that plugin is compatible with
413 * @minor: minor version number of core that plugin is compatible with
415 * Create a new plugin with given name.
417 * Returns: new plugin, or NULL if plugin couldn't be created, due to
418 * incompatible version number, or name already being allocated)
421 gst_plugin_new (const gchar *name, gint major, gint minor)
425 // return NULL if the major and minor version numbers are not compatible
427 if (major != GST_VERSION_MAJOR || minor != GST_VERSION_MINOR) return NULL;
429 // return NULL if the plugin is allready loaded
430 plugin = gst_plugin_find (name);
431 if (plugin) return NULL;
433 plugin = (GstPlugin *)g_malloc(sizeof(GstPlugin));
435 plugin->name = g_strdup(name);
436 plugin->longname = NULL;
437 plugin->elements = NULL;
438 plugin->numelements = 0;
439 plugin->types = NULL;
440 plugin->numtypes = 0;
441 plugin->autopluggers = NULL;
442 plugin->numautopluggers = 0;
443 plugin->loaded = TRUE;
449 * gst_plugin_get_name:
450 * @plugin: plugin to get the name of
452 * Get the short name of the plugin
454 * Returns: the name of the plugin
457 gst_plugin_get_name (GstPlugin *plugin)
459 g_return_val_if_fail (plugin != NULL, NULL);
465 * gst_plugin_set_name:
466 * @plugin: plugin to set name of
469 * Sets the name (should be short) of the plugin.
472 gst_plugin_set_name (GstPlugin *plugin, const gchar *name)
474 g_return_if_fail (plugin != NULL);
477 g_free (plugin->name);
479 plugin->name = g_strdup (name);
483 * gst_plugin_set_longname:
484 * @plugin: plugin to set long name of
485 * @longname: new long name
487 * Sets the long name (should be descriptive) of the plugin.
490 gst_plugin_set_longname (GstPlugin *plugin, const gchar *longname)
492 g_return_if_fail(plugin != NULL);
494 if (plugin->longname)
495 g_free(plugin->longname);
497 plugin->longname = g_strdup(longname);
501 * gst_plugin_get_longname:
502 * @plugin: plugin to get long name of
504 * Get the long descriptive name of the plugin
506 * Returns: the long name of the plugin
509 gst_plugin_get_longname (GstPlugin *plugin)
511 g_return_val_if_fail (plugin != NULL, NULL);
513 return plugin->longname;
517 * gst_plugin_get_filename:
518 * @plugin: plugin to get the filename of
520 * get the filename of the plugin
522 * Returns: the filename of the plugin
525 gst_plugin_get_filename (GstPlugin *plugin)
527 g_return_val_if_fail (plugin != NULL, NULL);
529 return plugin->filename;
533 * gst_plugin_is_loaded:
534 * @plugin: plugin to query
536 * queries if the plugin is loaded into memory
538 * Returns: TRUE is loaded, FALSE otherwise
541 gst_plugin_is_loaded (GstPlugin *plugin)
543 g_return_val_if_fail (plugin != NULL, FALSE);
545 return plugin->loaded;
551 * @name: name of plugin to find
553 * Search the list of registered plugins for one of the given name
555 * Returns: pointer to the #GstPlugin if found, NULL otherwise
558 gst_plugin_find (const gchar *name)
560 GList *plugins = _gst_plugins;
562 g_return_val_if_fail(name != NULL, NULL);
565 GstPlugin *plugin = (GstPlugin *)plugins->data;
566 // g_print("plugin name is '%s'\n",plugin->name);
568 if (!strcmp(plugin->name,name)) {
572 plugins = g_list_next(plugins);
577 static GstElementFactory*
578 gst_plugin_find_elementfactory (const gchar *name)
580 GList *plugins, *factories;
581 GstElementFactory *factory;
583 g_return_val_if_fail(name != NULL, NULL);
585 plugins = _gst_plugins;
587 factories = ((GstPlugin *)(plugins->data))->elements;
589 factory = (GstElementFactory*)(factories->data);
590 if (!strcmp(factory->name, name))
591 return (GstElementFactory*)(factory);
592 factories = g_list_next(factories);
594 plugins = g_list_next(plugins);
601 * gst_plugin_load_elementfactory:
602 * @name: name of elementfactory to load
604 * Load a registered elementfactory by name.
606 * Returns: @GstElementFactory if loaded, NULL if not
609 gst_plugin_load_elementfactory (const gchar *name)
611 GList *plugins, *factories;
612 GstElementFactory *factory = NULL;
615 g_return_val_if_fail(name != NULL, NULL);
617 plugins = _gst_plugins;
619 plugin = (GstPlugin *)plugins->data;
620 factories = plugin->elements;
623 factory = (GstElementFactory*)(factories->data);
625 if (!strcmp(factory->name,name)) {
626 if (!plugin->loaded) {
627 gchar *filename = g_strdup (plugin->filename);
628 gchar *pluginname = g_strdup (plugin->name);
630 GST_INFO (GST_CAT_PLUGIN_LOADING,"loaded elementfactory %s from plugin %s",name,plugin->name);
631 gst_plugin_remove(plugin);
632 if (!gst_plugin_load_absolute(filename)) {
633 GST_DEBUG (0,"gstplugin: error loading element factory %s from plugin %s\n", name, pluginname);
638 factory = gst_plugin_find_elementfactory(name);
641 factories = g_list_next(factories);
643 plugins = g_list_next(plugins);
649 static GstAutoplugFactory*
650 gst_plugin_find_autoplugfactory (const gchar *name)
652 GList *plugins, *factories;
653 GstAutoplugFactory *factory;
655 g_return_val_if_fail(name != NULL, NULL);
657 plugins = _gst_plugins;
659 factories = ((GstPlugin *)(plugins->data))->autopluggers;
661 factory = (GstAutoplugFactory*)(factories->data);
662 if (!strcmp(factory->name, name))
663 return (GstAutoplugFactory*)(factory);
664 factories = g_list_next(factories);
666 plugins = g_list_next(plugins);
672 * gst_plugin_load_autoplugfactory:
673 * @name: name of autoplugfactory to load
675 * Load a registered autoplugfactory by name.
677 * Returns: @GstAutoplugFactory if loaded, NULL if not
680 gst_plugin_load_autoplugfactory (const gchar *name)
682 GList *plugins, *factories;
683 GstAutoplugFactory *factory = NULL;
686 g_return_val_if_fail(name != NULL, NULL);
688 plugins = _gst_plugins;
690 plugin = (GstPlugin *)plugins->data;
691 factories = plugin->autopluggers;
694 factory = (GstAutoplugFactory*)(factories->data);
696 if (!strcmp(factory->name,name)) {
697 if (!plugin->loaded) {
698 gchar *filename = g_strdup (plugin->filename);
699 gchar *pluginname = g_strdup (plugin->name);
701 GST_INFO (GST_CAT_PLUGIN_LOADING,"loaded autoplugfactory %s from plugin %s",name,plugin->name);
702 gst_plugin_remove(plugin);
703 if (!gst_plugin_load_absolute(filename)) {
704 GST_DEBUG (0,"gstplugin: error loading autoplug factory %s from plugin %s\n", name, pluginname);
709 factory = gst_plugin_find_autoplugfactory(name);
712 factories = g_list_next(factories);
714 plugins = g_list_next(plugins);
721 * gst_plugin_load_typefactory:
722 * @mime: name of typefactory to load
724 * Load a registered typefactory by mime type.
727 gst_plugin_load_typefactory (const gchar *mime)
729 GList *plugins, *factories;
730 GstTypeFactory *factory;
733 g_return_if_fail (mime != NULL);
735 plugins = g_list_copy (_gst_plugins);
737 plugin = (GstPlugin *)plugins->data;
738 factories = g_list_copy (plugin->types);
741 factory = (GstTypeFactory*)(factories->data);
743 if (!strcmp(factory->mime,mime)) {
744 if (!plugin->loaded) {
745 gchar *filename = g_strdup (plugin->filename);
746 gchar *pluginname = g_strdup (plugin->name);
748 GST_INFO (GST_CAT_PLUGIN_LOADING,"loading type factory for \"%s\" from plugin %s",mime,plugin->name);
749 plugin->loaded = TRUE;
750 gst_plugin_remove(plugin);
751 if (!gst_plugin_load_absolute(filename)) {
752 GST_DEBUG (0,"gstplugin: error loading type factory \"%s\" from plugin %s\n", mime, pluginname);
759 factories = g_list_next(factories);
762 g_list_free (factories);
763 plugins = g_list_next(plugins);
765 g_list_free (plugins);
771 * gst_plugin_add_factory:
772 * @plugin: plugin to add factory to
773 * @factory: factory to add
775 * Add factory to the list of those provided by the plugin.
778 gst_plugin_add_factory (GstPlugin *plugin, GstElementFactory *factory)
780 g_return_if_fail (plugin != NULL);
781 g_return_if_fail (factory != NULL);
783 // g_print("adding factory to plugin\n");
784 plugin->elements = g_list_prepend (plugin->elements, factory);
785 plugin->numelements++;
789 * gst_plugin_add_type:
790 * @plugin: plugin to add type to
791 * @factory: the typefactory to add
793 * Add a typefactory to the list of those provided by the plugin.
796 gst_plugin_add_type (GstPlugin *plugin, GstTypeFactory *factory)
798 g_return_if_fail (plugin != NULL);
799 g_return_if_fail (factory != NULL);
801 // g_print("adding factory to plugin\n");
802 plugin->types = g_list_prepend (plugin->types, factory);
804 gst_type_register (factory);
808 * gst_plugin_add_autoplugger:
809 * @plugin: plugin to add the autoplugger to
810 * @factory: the autoplugfactory to add
812 * Add an autoplugfactory to the list of those provided by the plugin.
815 gst_plugin_add_autoplugger (GstPlugin *plugin, GstAutoplugFactory *factory)
817 g_return_if_fail (plugin != NULL);
818 g_return_if_fail (factory != NULL);
820 // g_print("adding factory to plugin\n");
821 plugin->autopluggers = g_list_prepend (plugin->autopluggers, factory);
822 plugin->numautopluggers++;
826 * gst_plugin_get_list:
828 * get the currently loaded plugins
830 * Returns; a GList of GstPlugin elements
833 gst_plugin_get_list (void)
835 return g_list_copy (_gst_plugins);
839 * gst_plugin_save_thyself:
840 * @parent: the parent node to save the plugin to
842 * saves the plugin into an XML representation
844 * Returns: the new XML node
847 gst_plugin_save_thyself (xmlNodePtr parent)
849 xmlNodePtr tree, subtree;
850 GList *plugins = NULL, *elements = NULL, *types = NULL, *autopluggers = NULL;
852 plugins = g_list_copy (_gst_plugins);
854 GstPlugin *plugin = (GstPlugin *)plugins->data;
856 tree = xmlNewChild (parent, NULL, "plugin", NULL);
857 xmlNewChild (tree, NULL, "name", plugin->name);
858 xmlNewChild (tree, NULL, "longname", plugin->longname);
859 xmlNewChild (tree, NULL, "filename", plugin->filename);
861 types = plugin->types;
863 GstTypeFactory *factory = (GstTypeFactory *)types->data;
864 subtree = xmlNewChild(tree, NULL, "typefactory", NULL);
866 gst_typefactory_save_thyself (factory, subtree);
868 types = g_list_next (types);
870 elements = plugin->elements;
872 GstElementFactory *factory = (GstElementFactory *)elements->data;
873 subtree = xmlNewChild (tree, NULL, "elementfactory", NULL);
875 gst_elementfactory_save_thyself (factory, subtree);
877 elements = g_list_next (elements);
879 autopluggers = plugin->autopluggers;
880 while (autopluggers) {
881 GstAutoplugFactory *factory = (GstAutoplugFactory *)autopluggers->data;
882 subtree = xmlNewChild (tree, NULL, "autoplugfactory", NULL);
884 gst_autoplugfactory_save_thyself (factory, subtree);
886 autopluggers = g_list_next (autopluggers);
888 plugins = g_list_next (plugins);
890 g_list_free (plugins);
895 * gst_plugin_load_thyself:
896 * @parent: the parent node to load the plugin from
898 * load the plugin from an XML representation
901 gst_plugin_load_thyself (xmlNodePtr parent)
904 gint elementcount = 0;
905 gint autoplugcount = 0;
909 kinderen = parent->xmlChildrenNode; // Dutch invasion :-)
911 if (!strcmp (kinderen->name, "plugin")) {
912 xmlNodePtr field = kinderen->xmlChildrenNode;
913 GstPlugin *plugin = g_new0 (GstPlugin, 1);
915 plugin->elements = NULL;
916 plugin->types = NULL;
917 plugin->loaded = FALSE;
920 if (!strcmp (field->name, "name")) {
921 pluginname = xmlNodeGetContent (field);
922 if (gst_plugin_find (pluginname)) {
928 plugin->name = pluginname;
931 else if (!strcmp (field->name, "longname")) {
932 plugin->longname = xmlNodeGetContent (field);
934 else if (!strcmp (field->name, "filename")) {
935 plugin->filename = xmlNodeGetContent (field);
937 else if (!strcmp (field->name, "elementfactory")) {
938 GstElementFactory *factory = gst_elementfactory_load_thyself (field);
939 gst_plugin_add_factory (plugin, factory);
942 else if (!strcmp (field->name, "autoplugfactory")) {
943 GstAutoplugFactory *factory = gst_autoplugfactory_load_thyself (field);
944 gst_plugin_add_autoplugger (plugin, factory);
947 else if (!strcmp (field->name, "typefactory")) {
948 GstTypeFactory *factory = gst_typefactory_load_thyself (field);
949 gst_plugin_add_type (plugin, factory);
958 _gst_plugins = g_list_prepend (_gst_plugins, plugin);
962 kinderen = kinderen->next;
964 GST_INFO (GST_CAT_PLUGIN_LOADING, "added %d registered factories, %d autopluggers and %d types",
965 elementcount, autoplugcount, typecount);
970 * gst_plugin_get_factory_list:
971 * @plugin: the plugin to get the factories from
973 * get a list of all the factories that this plugin provides
975 * Returns: a GList of factories
978 gst_plugin_get_factory_list (GstPlugin *plugin)
980 g_return_val_if_fail (plugin != NULL, NULL);
982 return plugin->elements;
986 * gst_plugin_get_type_list:
987 * @plugin: the plugin to get the typefactories from
989 * get a list of all the typefactories that this plugin provides
991 * Returns: a GList of factories
994 gst_plugin_get_type_list (GstPlugin *plugin)
996 g_return_val_if_fail (plugin != NULL, NULL);
998 return plugin->types;
1002 * gst_plugin_get_autoplug_list:
1003 * @plugin: the plugin to get the autoplugfactories from
1005 * get a list of all the autoplugfactories that this plugin provides
1007 * Returns: a GList of factories
1010 gst_plugin_get_autoplug_list (GstPlugin *plugin)
1012 g_return_val_if_fail (plugin != NULL, NULL);
1014 return plugin->autopluggers;