mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-16 11:15:31 +00:00
Externalized the plugin information in /etc/gstreamer/reg.xml
Original commit message from CVS: Externalized the plugin information in /etc/gstreamer/reg.xml - no need to do a plugin_load_all() - plugins are loaded when needed - typedetect functions are loaded when needed (still buggy) - no need to check for the existance of the plugin in the codecs - added gstreamer-register to create the reg.xml file - renamed launch to gstreamer-launch - plugins need to register the typefactory they provide modified the plugins to meet the new design modified the plugins to correctly set their pad types autoplugging can be done without loading the plugins now
This commit is contained in:
parent
a703c01d94
commit
7ccc2cf90b
15 changed files with 502 additions and 46 deletions
|
@ -21,20 +21,21 @@ int main(int argc,char *argv[])
|
|||
}
|
||||
|
||||
gst_init(&argc,&argv);
|
||||
gst_plugin_load_all();
|
||||
g_print("\n");
|
||||
|
||||
/* create a new bin to hold the elements */
|
||||
pipeline = gst_pipeline_new("pipeline");
|
||||
g_assert(pipeline != NULL);
|
||||
|
||||
/* create a disk reader */
|
||||
disksrc = gst_elementfactory_make("disksrc", "disk_source");
|
||||
g_assert(disksrc != NULL);
|
||||
gtk_object_set(GTK_OBJECT(disksrc),"location", argv[1],NULL);
|
||||
gtk_signal_connect(GTK_OBJECT(disksrc),"eos",
|
||||
GTK_SIGNAL_FUNC(eos),NULL);
|
||||
|
||||
/* and an audio sink */
|
||||
audiosink = gst_elementfactory_make("audiosink", "play_audio");
|
||||
g_assert(audiosink != NULL);
|
||||
|
||||
/* add objects to the main pipeline */
|
||||
gst_bin_add(GST_BIN(pipeline), disksrc);
|
||||
|
|
|
@ -32,10 +32,10 @@ extern gint _gst_trace_on;
|
|||
void gst_init(int *argc,char **argv[]) {
|
||||
GstTrace *gst_trace;
|
||||
|
||||
gtk_init(argc,argv);
|
||||
|
||||
if (!g_thread_supported()) g_thread_init (NULL);
|
||||
|
||||
gtk_init(argc,argv);
|
||||
|
||||
_gst_type_initialize();
|
||||
_gst_plugin_initialize();
|
||||
_gst_buffer_initialize();
|
||||
|
@ -48,8 +48,8 @@ void gst_init(int *argc,char **argv[]) {
|
|||
gst_elementfactory_register(gst_elementfactory_new(
|
||||
"thread",gst_thread_get_type(),&gst_thread_details));
|
||||
|
||||
gst_plugin_load("libgsttypes.so");
|
||||
gst_plugin_load("libgstelements.so");
|
||||
//gst_plugin_load_elementfactory("gsttypes");
|
||||
//gst_plugin_load("libgstelements.so");
|
||||
|
||||
_gst_trace_on = 0;
|
||||
if (_gst_trace_on) {
|
||||
|
|
|
@ -199,6 +199,9 @@ GstElement *gst_elementfactory_create(GstElementFactory *factory,
|
|||
// FIXME this name is wrong, probably so is the one above it
|
||||
GstElement *gst_elementfactory_make(gchar *factoryname,gchar *name);
|
||||
|
||||
xmlNodePtr gst_elementfactory_save_thyself(GstElementFactory *factory, xmlNodePtr parent);
|
||||
GstElementFactory *gst_elementfactory_load_thyself(xmlNodePtr parent);
|
||||
|
||||
int gst_element_loopfunc_wrapper(int argc,char **argv);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
|
||||
#include <gst/gstelement.h>
|
||||
#include <gst/gstplugin.h>
|
||||
|
||||
|
||||
/* global list of registered elementfactories */
|
||||
|
@ -113,6 +114,9 @@ GstElement *gst_elementfactory_create(GstElementFactory *factory,
|
|||
GstElementClass *oclass;
|
||||
|
||||
g_return_val_if_fail(factory != NULL, NULL);
|
||||
|
||||
factory = gst_plugin_load_elementfactory(factory->name);
|
||||
|
||||
g_return_val_if_fail(factory->type != 0, NULL);
|
||||
|
||||
// create an instance of the element
|
||||
|
@ -133,6 +137,7 @@ GstElement *gst_elementfactory_make(gchar *factoryname,gchar *name) {
|
|||
GstElementFactory *factory;
|
||||
GstElement *element;
|
||||
|
||||
gst_plugin_load_elementfactory(factoryname);
|
||||
factory = gst_elementfactory_find(factoryname);
|
||||
if (factory == NULL) return NULL;
|
||||
element = gst_elementfactory_create(factory,name);
|
||||
|
@ -151,3 +156,89 @@ void gst_elementfactory_add_sink(GstElementFactory *elementfactory, guint16 id)
|
|||
elementfactory->sink_types = g_list_prepend(elementfactory->sink_types, GUINT_TO_POINTER(type));
|
||||
}
|
||||
|
||||
xmlNodePtr gst_elementfactory_save_thyself(GstElementFactory *factory, xmlNodePtr parent) {
|
||||
GList *types;
|
||||
xmlNodePtr subtree;
|
||||
|
||||
xmlNewChild(parent,NULL,"name",factory->name);
|
||||
xmlNewChild(parent,NULL,"longname", factory->details->longname);
|
||||
xmlNewChild(parent,NULL,"class", factory->details->class);
|
||||
xmlNewChild(parent,NULL,"description", factory->details->description);
|
||||
xmlNewChild(parent,NULL,"version", factory->details->version);
|
||||
xmlNewChild(parent,NULL,"author", factory->details->author);
|
||||
xmlNewChild(parent,NULL,"copyright", factory->details->copyright);
|
||||
|
||||
types = factory->src_types;
|
||||
if (types) {
|
||||
subtree = xmlNewChild(parent,NULL,"sources",NULL);
|
||||
while (types) {
|
||||
guint16 typeid = GPOINTER_TO_UINT(types->data);
|
||||
GstType *type = gst_type_find_by_id(typeid);
|
||||
|
||||
gst_type_save_thyself(type, subtree);
|
||||
|
||||
types = g_list_next(types);
|
||||
}
|
||||
}
|
||||
types = factory->sink_types;
|
||||
if (types) {
|
||||
subtree = xmlNewChild(parent,NULL,"sinks",NULL);
|
||||
while (types) {
|
||||
guint16 typeid = GPOINTER_TO_UINT(types->data);
|
||||
GstType *type = gst_type_find_by_id(typeid);
|
||||
|
||||
gst_type_save_thyself(type, subtree);
|
||||
|
||||
types = g_list_next(types);
|
||||
}
|
||||
}
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
GstElementFactory *gst_elementfactory_load_thyself(xmlNodePtr parent) {
|
||||
GstElementFactory *factory = g_new0(GstElementFactory, 1);
|
||||
xmlNodePtr children = parent->childs;
|
||||
factory->details = g_new0(GstElementDetails, 1);
|
||||
factory->sink_types = NULL;
|
||||
factory->src_types = NULL;
|
||||
|
||||
while (children) {
|
||||
if (!strcmp(children->name, "name")) {
|
||||
factory->name = g_strdup(xmlNodeGetContent(children));
|
||||
}
|
||||
if (!strcmp(children->name, "longname")) {
|
||||
factory->details->longname = g_strdup(xmlNodeGetContent(children));
|
||||
}
|
||||
if (!strcmp(children->name, "class")) {
|
||||
factory->details->class = g_strdup(xmlNodeGetContent(children));
|
||||
}
|
||||
if (!strcmp(children->name, "description")) {
|
||||
factory->details->description = g_strdup(xmlNodeGetContent(children));
|
||||
}
|
||||
if (!strcmp(children->name, "version")) {
|
||||
factory->details->version = g_strdup(xmlNodeGetContent(children));
|
||||
}
|
||||
if (!strcmp(children->name, "author")) {
|
||||
factory->details->author = g_strdup(xmlNodeGetContent(children));
|
||||
}
|
||||
if (!strcmp(children->name, "copyright")) {
|
||||
factory->details->copyright = g_strdup(xmlNodeGetContent(children));
|
||||
}
|
||||
if (!strcmp(children->name, "sources")) {
|
||||
guint16 typeid = gst_type_load_thyself(children);
|
||||
|
||||
gst_type_add_src(typeid, factory);
|
||||
}
|
||||
if (!strcmp(children->name, "sinks")) {
|
||||
guint16 typeid = gst_type_load_thyself(children);
|
||||
|
||||
gst_type_add_sink(typeid, factory);
|
||||
}
|
||||
|
||||
children = children->next;
|
||||
}
|
||||
|
||||
return factory;
|
||||
}
|
||||
|
||||
|
|
240
gst/gstplugin.c
240
gst/gstplugin.c
|
@ -28,6 +28,8 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#undef PLUGINS_USE_SRCDIR
|
||||
|
||||
/* list of loaded modules and its sequence number */
|
||||
GList *_gst_modules;
|
||||
gint _gst_modules_seqno;
|
||||
|
@ -37,34 +39,49 @@ gint _gst_plugins_seqno;
|
|||
/* list of paths to check for plugins */
|
||||
GList *_gst_plugin_paths;
|
||||
|
||||
GList *_gst_libraries;
|
||||
gint _gst_libraries_seqno;
|
||||
|
||||
/* whether or not to spew library load issues */
|
||||
gboolean _gst_plugin_spew = FALSE;
|
||||
|
||||
|
||||
void _gst_plugin_initialize() {
|
||||
xmlDocPtr doc;
|
||||
_gst_modules = NULL;
|
||||
_gst_modules_seqno = 0;
|
||||
_gst_plugins = NULL;
|
||||
_gst_plugins_seqno = 0;
|
||||
_gst_plugin_paths = NULL;
|
||||
_gst_libraries = NULL;
|
||||
_gst_libraries_seqno = 0;
|
||||
|
||||
/* add the main (installed) library path */
|
||||
_gst_plugin_paths = g_list_prepend(_gst_plugin_paths,PLUGINS_DIR);
|
||||
_gst_plugin_paths = g_list_append(_gst_plugin_paths,PLUGINS_DIR);
|
||||
|
||||
/* if this is set, we add build-directory paths to the list */
|
||||
#ifdef PLUGINS_USE_SRCDIR
|
||||
/* the catch-all plugins directory */
|
||||
_gst_plugin_paths = g_list_prepend(_gst_plugin_paths,
|
||||
_gst_plugin_paths = g_list_append(_gst_plugin_paths,
|
||||
PLUGINS_SRCDIR "/plugins");
|
||||
/* the libreary directory */
|
||||
_gst_plugin_paths = g_list_prepend(_gst_plugin_paths,
|
||||
_gst_plugin_paths = g_list_append(_gst_plugin_paths,
|
||||
PLUGINS_SRCDIR "/libs");
|
||||
/* location libgstelements.so */
|
||||
_gst_plugin_paths = g_list_prepend(_gst_plugin_paths,
|
||||
_gst_plugin_paths = g_list_append(_gst_plugin_paths,
|
||||
PLUGINS_SRCDIR "/gst/elements");
|
||||
_gst_plugin_paths = g_list_prepend(_gst_plugin_paths,
|
||||
_gst_plugin_paths = g_list_append(_gst_plugin_paths,
|
||||
PLUGINS_SRCDIR "/gst/types");
|
||||
#endif /* PLUGINS_USE_SRCDIR */
|
||||
|
||||
doc = xmlParseFile("/etc/gstreamer/reg.xml");
|
||||
|
||||
if (!doc || strcmp(doc->root->name, "GST-PluginRegistry")) {
|
||||
g_print("gstplugin: registry needs rebuild\n");
|
||||
gst_plugin_load_all();
|
||||
return;
|
||||
}
|
||||
gst_plugin_load_thyself(doc->root);
|
||||
}
|
||||
|
||||
static gboolean gst_plugin_load_recurse(gchar *directory,gchar *name) {
|
||||
|
@ -128,8 +145,23 @@ void gst_plugin_load_all() {
|
|||
* Returns: whether the library was loaded or not
|
||||
*/
|
||||
gboolean gst_library_load(gchar *name) {
|
||||
gboolean res;
|
||||
GList *libraries = _gst_libraries;
|
||||
|
||||
while (libraries) {
|
||||
if (!strcmp((gchar *)libraries->data, name)) return TRUE;
|
||||
|
||||
libraries = g_list_next(libraries);
|
||||
}
|
||||
|
||||
// for now this is the same
|
||||
return gst_plugin_load(name);
|
||||
res = gst_plugin_load(name);
|
||||
|
||||
if (res) {
|
||||
_gst_libraries = g_list_prepend(_gst_libraries, name);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -145,7 +177,7 @@ gboolean gst_plugin_load(gchar *name) {
|
|||
GList *path;
|
||||
gchar *libspath;
|
||||
|
||||
// g_print("attempting to load plugin '%s'\n",name);
|
||||
//g_print("attempting to load plugin '%s'\n",name);
|
||||
|
||||
path = _gst_plugin_paths;
|
||||
while (path != NULL) {
|
||||
|
@ -177,20 +209,35 @@ gboolean gst_plugin_load_absolute(gchar *name) {
|
|||
GModule *module;
|
||||
GstPluginInitFunc initfunc;
|
||||
GstPlugin *plugin;
|
||||
GList *plugins;
|
||||
|
||||
//g_print("trying to absolute load '%s\n",name);
|
||||
|
||||
if (g_module_supported() == FALSE) {
|
||||
g_print("wow, you built this on a platform without dynamic loading???\n");
|
||||
g_print("gstplugin: wow, you built this on a platform without dynamic loading???\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
plugins = _gst_plugins;
|
||||
|
||||
while (plugins) {
|
||||
plugin = (GstPlugin *)plugins->data;
|
||||
|
||||
if (!strcmp(plugin->filename, name) && plugin->loaded) {
|
||||
_gst_plugins = g_list_append(_gst_plugins,plugin);
|
||||
return TRUE;
|
||||
}
|
||||
plugins = g_list_next(plugins);
|
||||
}
|
||||
//g_print("trying to absolute load '%s\n",name);
|
||||
|
||||
module = g_module_open(name,G_MODULE_BIND_LAZY);
|
||||
if (module != NULL) {
|
||||
if (g_module_symbol(module,"plugin_init",(gpointer *)&initfunc)) {
|
||||
if ((plugin = (initfunc)(module))) {
|
||||
GList *factories;
|
||||
g_print("gstplugin: plugin %s loaded\n", plugin->name);
|
||||
plugin->filename = g_strdup(name);
|
||||
plugin->loaded = TRUE;
|
||||
_gst_modules = g_list_append(_gst_modules,module);
|
||||
_gst_modules_seqno++;
|
||||
_gst_plugins = g_list_append(_gst_plugins,plugin);
|
||||
|
@ -203,7 +250,7 @@ gboolean gst_plugin_load_absolute(gchar *name) {
|
|||
return TRUE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
} else if (_gst_plugin_spew) {
|
||||
// if (strstr(g_module_error(),"No such") == NULL)
|
||||
gst_info("error loading plugin: %s\n",g_module_error());
|
||||
|
@ -227,6 +274,7 @@ GstPlugin *gst_plugin_new(gchar *name) {
|
|||
plugin->longname = NULL;
|
||||
plugin->types = NULL;
|
||||
plugin->elements = NULL;
|
||||
plugin->loaded = FALSE;
|
||||
|
||||
return plugin;
|
||||
}
|
||||
|
@ -253,7 +301,7 @@ void gst_plugin_set_longname(GstPlugin *plugin,gchar *longname) {
|
|||
*
|
||||
* Returns: pointer to the #GstPlugin if found, NULL otherwise
|
||||
*/
|
||||
GstPlugin *gst_plugin_find(gchar *name) {
|
||||
GstPlugin *gst_plugin_find(const gchar *name) {
|
||||
GList *plugins = _gst_plugins;
|
||||
|
||||
g_return_val_if_fail(name != NULL, NULL);
|
||||
|
@ -262,8 +310,9 @@ GstPlugin *gst_plugin_find(gchar *name) {
|
|||
GstPlugin *plugin = (GstPlugin *)plugins->data;
|
||||
// g_print("plugin name is '%s'\n",plugin->name);
|
||||
if (plugin->name) {
|
||||
if (!strcmp(plugin->name,name))
|
||||
if (!strcmp(plugin->name,name)) {
|
||||
return plugin;
|
||||
}
|
||||
}
|
||||
plugins = g_list_next(plugins);
|
||||
}
|
||||
|
@ -289,7 +338,7 @@ GstElementFactory *gst_plugin_find_elementfactory(gchar *name) {
|
|||
factories = ((GstPlugin *)(plugins->data))->elements;
|
||||
while (factories) {
|
||||
factory = (GstElementFactory*)(factories->data);
|
||||
if (!strcmp(gst_element_get_name(GST_ELEMENT(factory)),name))
|
||||
if (!strcmp(factory->name,name))
|
||||
return (GstElementFactory*)(factory);
|
||||
factories = g_list_next(factories);
|
||||
}
|
||||
|
@ -299,6 +348,69 @@ GstElementFactory *gst_plugin_find_elementfactory(gchar *name) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
GstElementFactory *gst_plugin_load_elementfactory(gchar *name) {
|
||||
GList *plugins, *factories;
|
||||
GstElementFactory *factory = NULL;
|
||||
GstPlugin *plugin;
|
||||
|
||||
g_return_val_if_fail(name != NULL, NULL);
|
||||
|
||||
plugins = _gst_plugins;
|
||||
while (plugins) {
|
||||
plugin = (GstPlugin *)plugins->data;
|
||||
factories = plugin->elements;
|
||||
while (factories) {
|
||||
factory = (GstElementFactory*)(factories->data);
|
||||
if (!strcmp(factory->name,name)) {
|
||||
if (!plugin->loaded) {
|
||||
g_print("gstplugin: loading element factory %s from plugin %s\n", name, plugin->name);
|
||||
_gst_plugins = g_list_remove(_gst_plugins, plugin);
|
||||
if (!gst_plugin_load_absolute(plugin->filename)) {
|
||||
g_print("gstplugin: error loading element factory %s from plugin %s\n", name, plugin->name);
|
||||
}
|
||||
factory = gst_plugin_find_elementfactory(factory->name);
|
||||
}
|
||||
return factory;
|
||||
}
|
||||
factories = g_list_next(factories);
|
||||
}
|
||||
plugins = g_list_next(plugins);
|
||||
}
|
||||
|
||||
return factory;
|
||||
}
|
||||
|
||||
void gst_plugin_load_typefactory(gchar *mime) {
|
||||
GList *plugins, *factories;
|
||||
GstTypeFactory *factory;
|
||||
GstPlugin *plugin;
|
||||
|
||||
g_return_if_fail(mime != NULL);
|
||||
|
||||
plugins = _gst_plugins;
|
||||
while (plugins) {
|
||||
plugin = (GstPlugin *)plugins->data;
|
||||
factories = plugin->types;
|
||||
while (factories) {
|
||||
factory = (GstTypeFactory*)(factories->data);
|
||||
if (!strcmp(factory->mime,mime)) {
|
||||
if (!plugin->loaded) {
|
||||
g_print("gstplugin: loading type factory for \"%s\" from plugin %s\n", mime, plugin->name);
|
||||
_gst_plugins = g_list_remove(_gst_plugins, plugin);
|
||||
if (!gst_plugin_load_absolute(plugin->filename)) {
|
||||
g_print("gstplugin: error loading type factory \"%s\" from plugin %s\n", mime, plugin->name);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
factories = g_list_next(factories);
|
||||
}
|
||||
plugins = g_list_next(plugins);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_plugin_add_factory:
|
||||
* @plugin: plugin to add factory to
|
||||
|
@ -314,6 +426,14 @@ void gst_plugin_add_factory(GstPlugin *plugin,GstElementFactory *factory) {
|
|||
plugin->elements = g_list_append(plugin->elements,factory);
|
||||
}
|
||||
|
||||
void gst_plugin_add_type(GstPlugin *plugin,GstTypeFactory *factory) {
|
||||
g_return_if_fail(plugin != NULL);
|
||||
g_return_if_fail(factory != NULL);
|
||||
|
||||
// g_print("adding factory to plugin\n");
|
||||
plugin->types = g_list_append(plugin->types,factory);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_plugin_get_list:
|
||||
*
|
||||
|
@ -324,3 +444,97 @@ void gst_plugin_add_factory(GstPlugin *plugin,GstElementFactory *factory) {
|
|||
GList *gst_plugin_get_list() {
|
||||
return _gst_plugins;
|
||||
}
|
||||
|
||||
xmlNodePtr gst_plugin_save_thyself(xmlNodePtr parent) {
|
||||
xmlNodePtr tree, subtree;
|
||||
GList *plugins = NULL, *elements = NULL, *types = NULL;
|
||||
|
||||
plugins = gst_plugin_get_list();
|
||||
while (plugins) {
|
||||
GstPlugin *plugin = (GstPlugin *)plugins->data;
|
||||
tree = xmlNewChild(parent,NULL,"plugin",NULL);
|
||||
xmlNewChild(tree,NULL,"name",plugin->name);
|
||||
xmlNewChild(tree,NULL,"longname",plugin->longname);
|
||||
xmlNewChild(tree,NULL,"filename",plugin->filename);
|
||||
types = plugin->types;
|
||||
while (types) {
|
||||
GstTypeFactory *factory = (GstTypeFactory *)types->data;
|
||||
subtree = xmlNewChild(tree,NULL,"type",NULL);
|
||||
|
||||
gst_typefactory_save_thyself(factory, subtree);
|
||||
|
||||
types = g_list_next(types);
|
||||
}
|
||||
elements = plugin->elements;
|
||||
while (elements) {
|
||||
GstElementFactory *factory = (GstElementFactory *)elements->data;
|
||||
subtree = xmlNewChild(tree,NULL,"element",NULL);
|
||||
|
||||
gst_elementfactory_save_thyself(factory, subtree);
|
||||
|
||||
elements = g_list_next(elements);
|
||||
}
|
||||
plugins = g_list_next(plugins);
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
|
||||
void gst_plugin_load_thyself(xmlNodePtr parent) {
|
||||
xmlNodePtr kinderen;
|
||||
gint elementcount = 0;
|
||||
gint typecount = 0;
|
||||
|
||||
kinderen = parent->childs; // Dutch invasion :-)
|
||||
while (kinderen) {
|
||||
if (!strcmp(kinderen->name, "plugin")) {
|
||||
xmlNodePtr field = kinderen->childs;
|
||||
GstPlugin *plugin = (GstPlugin *)g_malloc(sizeof(GstPlugin));
|
||||
plugin->elements = NULL;
|
||||
plugin->types = NULL;
|
||||
plugin->loaded = FALSE;
|
||||
|
||||
while (field) {
|
||||
if (!strcmp(field->name, "name")) {
|
||||
if (gst_plugin_find(xmlNodeGetContent(field))) {
|
||||
g_free(plugin);
|
||||
plugin = NULL;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
plugin->name = g_strdup(xmlNodeGetContent(field));
|
||||
}
|
||||
}
|
||||
else if (!strcmp(field->name, "longname")) {
|
||||
plugin->longname = g_strdup(xmlNodeGetContent(field));
|
||||
}
|
||||
else if (!strcmp(field->name, "filename")) {
|
||||
plugin->filename = g_strdup(xmlNodeGetContent(field));
|
||||
}
|
||||
else if (!strcmp(field->name, "element")) {
|
||||
GstElementFactory *factory = gst_elementfactory_load_thyself(field);
|
||||
plugin->elements = g_list_prepend(plugin->elements, factory);
|
||||
elementcount++;
|
||||
}
|
||||
else if (!strcmp(field->name, "type")) {
|
||||
GstTypeFactory *factory = gst_typefactory_load_thyself(field);
|
||||
guint16 typeid = gst_type_find_by_mime(factory->mime);
|
||||
if (!typeid) {
|
||||
typeid = gst_type_register(factory);
|
||||
}
|
||||
plugin->types = g_list_prepend(plugin->types, factory);
|
||||
typecount++;
|
||||
}
|
||||
|
||||
field = field->next;
|
||||
}
|
||||
|
||||
if (plugin) {
|
||||
_gst_plugins = g_list_prepend(_gst_plugins, plugin);
|
||||
}
|
||||
}
|
||||
|
||||
kinderen = kinderen->next;
|
||||
}
|
||||
g_print("gstplugin: added %d registered factories and %d types\n", elementcount, typecount);
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,8 @@ struct _GstPlugin {
|
|||
|
||||
GList *types; /* list of types provided */
|
||||
GList *elements; /* list of elements provided */
|
||||
GList *identifiers; /* list of identifiers */
|
||||
|
||||
gboolean loaded; /* if the plugin is in memory */
|
||||
};
|
||||
|
||||
|
||||
|
@ -53,9 +54,16 @@ gboolean gst_library_load(gchar *name);
|
|||
gboolean gst_plugin_load_absolute(gchar *name);
|
||||
|
||||
void gst_plugin_add_factory(GstPlugin *plugin,GstElementFactory *factory);
|
||||
void gst_plugin_add_type(GstPlugin *plugin,GstTypeFactory *factory);
|
||||
|
||||
GstPlugin *gst_plugin_find(gchar *name);
|
||||
GstPlugin *gst_plugin_find(const gchar *name);
|
||||
GList *gst_plugin_get_list();
|
||||
GstElementFactory *gst_plugin_find_elementfactory(gchar *name);
|
||||
|
||||
GstElementFactory *gst_plugin_load_elementfactory(gchar *name);
|
||||
void gst_plugin_load_typefactory(gchar *mime);
|
||||
|
||||
xmlNodePtr gst_plugin_save_thyself(xmlNodePtr parent);
|
||||
void gst_plugin_load_thyself(xmlNodePtr parent);
|
||||
|
||||
#endif /* __GST_PLUGIN_H__ */
|
||||
|
|
126
gst/gsttype.c
126
gst/gsttype.c
|
@ -43,6 +43,8 @@ struct _gst_type_node
|
|||
};
|
||||
typedef struct _gst_type_node gst_type_node;
|
||||
|
||||
static gboolean gst_type_typefind_dummy(GstBuffer *buffer, gpointer priv);
|
||||
|
||||
/* we keep a (spase) matrix in the hashtable like:
|
||||
*
|
||||
* type_id list of factories hashed by src type_id
|
||||
|
@ -58,6 +60,7 @@ typedef struct _gst_type_node gst_type_node;
|
|||
**/
|
||||
|
||||
void _gst_type_initialize() {
|
||||
|
||||
_gst_types = NULL;
|
||||
_gst_maxtype = 1; /* type 0 is undefined */
|
||||
|
||||
|
@ -70,10 +73,9 @@ guint16 gst_type_register(GstTypeFactory *factory) {
|
|||
|
||||
g_return_val_if_fail(factory != NULL, 0);
|
||||
|
||||
// id = gst_type_find_by_mime(factory->mime);
|
||||
id = 0;
|
||||
id = gst_type_find_by_mime(factory->mime);
|
||||
if (!id) {
|
||||
type = (GstType *)g_malloc(sizeof(GstType));
|
||||
type = g_new0(GstType, 1);
|
||||
|
||||
type->id = _gst_maxtype++;
|
||||
type->mime = factory->mime;
|
||||
|
@ -85,6 +87,7 @@ guint16 gst_type_register(GstTypeFactory *factory) {
|
|||
_gst_types = g_list_prepend(_gst_types,type);
|
||||
|
||||
id = type->id;
|
||||
|
||||
} else {
|
||||
type = gst_type_find_by_id(id);
|
||||
/* now we want to try to merge the types and return the original */
|
||||
|
@ -92,19 +95,22 @@ guint16 gst_type_register(GstTypeFactory *factory) {
|
|||
/* FIXME: do extension merging here, not that easy */
|
||||
|
||||
/* if there is no existing typefind function, try to use new one */
|
||||
if (!type->typefindfunc && factory->typefindfunc)
|
||||
if ((type->typefindfunc == gst_type_typefind_dummy ||
|
||||
type->typefindfunc == NULL) && factory->typefindfunc)
|
||||
type->typefindfunc = factory->typefindfunc;
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
guint16 gst_type_find_by_mime(gchar *mime) {
|
||||
GList *walk = _gst_types;
|
||||
static guint16 gst_type_find_by_mime_func(gchar *mime) {
|
||||
GList *walk;
|
||||
GstType *type;
|
||||
gint typelen,mimelen;
|
||||
gchar *search, *found;
|
||||
|
||||
|
||||
walk = _gst_types;
|
||||
// DEBUG("searching for '%s'\n",mime);
|
||||
mimelen = strlen(mime);
|
||||
while (walk) {
|
||||
|
@ -132,6 +138,18 @@ guint16 gst_type_find_by_mime(gchar *mime) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
guint16 gst_type_find_by_mime(gchar *mime) {
|
||||
guint16 typeid;
|
||||
|
||||
typeid = gst_type_find_by_mime_func(mime);
|
||||
|
||||
if (!typeid) {
|
||||
gst_plugin_load_typefactory(mime);
|
||||
}
|
||||
|
||||
return gst_type_find_by_mime_func(mime);
|
||||
}
|
||||
|
||||
GstType *gst_type_find_by_id(guint16 id) {
|
||||
GList *walk = _gst_types;
|
||||
GstType *type;
|
||||
|
@ -150,7 +168,7 @@ static void gst_type_dump_converter(gpointer key, gpointer value, gpointer data)
|
|||
GList *walk = (GList *)value;
|
||||
GstElementFactory *factory;
|
||||
|
||||
g_print("%u, (", GPOINTER_TO_UINT(key));
|
||||
g_print("gsttype: %u, (", GPOINTER_TO_UINT(key));
|
||||
|
||||
while (walk) {
|
||||
factory = (GstElementFactory *) walk->data;
|
||||
|
@ -304,6 +322,7 @@ static GList *construct_path (gst_type_node *rgnNodes, gint chNode)
|
|||
GstType *type;
|
||||
GList *converters;
|
||||
|
||||
g_print("gsttype: constructed pad ");
|
||||
while (current != MAX_COST)
|
||||
{
|
||||
type = gst_type_find_by_id(current);
|
||||
|
@ -323,6 +342,7 @@ static guint gst_type_find_cost(gint src, gint dest) {
|
|||
|
||||
GList *converters = (GList *)g_hash_table_lookup(type->converters, GUINT_TO_POINTER(dest));
|
||||
|
||||
// FIXME do something very clever here...
|
||||
if (converters) return 1;
|
||||
return MAX_COST;
|
||||
}
|
||||
|
@ -374,3 +394,95 @@ GList *gst_type_get_sink_to_src(guint16 sinkid, guint16 srcid) {
|
|||
GList *gst_type_get_list() {
|
||||
return _gst_types;
|
||||
}
|
||||
|
||||
xmlNodePtr gst_type_save_thyself(GstType *type, xmlNodePtr parent) {
|
||||
xmlNodePtr tree;
|
||||
|
||||
tree = xmlNewChild(parent, NULL, "type", NULL);
|
||||
|
||||
xmlNewChild(tree, NULL, "mime", type->mime);
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
guint16 gst_type_load_thyself(xmlNodePtr parent) {
|
||||
xmlNodePtr children = parent->childs;
|
||||
guint16 typeid = 0;
|
||||
|
||||
while (children) {
|
||||
if (!strcmp(children->name, "type")) {
|
||||
xmlNodePtr field = children->childs;
|
||||
while (field) {
|
||||
if (!strcmp(field->name, "mime")) {
|
||||
typeid = gst_type_find_by_mime(xmlNodeGetContent(field));
|
||||
if (!typeid) {
|
||||
GstTypeFactory *factory = g_new0(GstTypeFactory, 1);
|
||||
|
||||
factory->mime = g_strdup(xmlNodeGetContent(field));
|
||||
typeid = gst_type_register(factory);
|
||||
}
|
||||
return typeid;
|
||||
}
|
||||
field = field->next;
|
||||
}
|
||||
}
|
||||
children = children->next;
|
||||
}
|
||||
|
||||
return typeid;
|
||||
}
|
||||
|
||||
|
||||
xmlNodePtr gst_typefactory_save_thyself(GstTypeFactory *factory, xmlNodePtr parent) {
|
||||
|
||||
xmlNewChild(parent, NULL, "mime", factory->mime);
|
||||
if (factory->exts) {
|
||||
xmlNewChild(parent, NULL, "extensions", factory->exts);
|
||||
}
|
||||
if (factory->typefindfunc) {
|
||||
xmlNewChild(parent, NULL, "typefind", NULL);
|
||||
}
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
static gboolean gst_type_typefind_dummy(GstBuffer *buffer, gpointer priv)
|
||||
{
|
||||
GstType *type = (GstType *)priv;
|
||||
guint16 typeid;
|
||||
g_print("gsttype: need to load typefind function\n");
|
||||
|
||||
type->typefindfunc = NULL;
|
||||
gst_plugin_load_typefactory(type->mime);
|
||||
typeid = gst_type_find_by_mime(type->mime);
|
||||
type = gst_type_find_by_id(typeid);
|
||||
|
||||
if (type->typefindfunc) {
|
||||
return type->typefindfunc(buffer, type);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GstTypeFactory *gst_typefactory_load_thyself(xmlNodePtr parent) {
|
||||
|
||||
GstTypeFactory *factory = g_new0(GstTypeFactory, 1);
|
||||
xmlNodePtr field = parent->childs;
|
||||
factory->typefindfunc = NULL;
|
||||
|
||||
while (field) {
|
||||
if (!strcmp(field->name, "mime")) {
|
||||
factory->mime = g_strdup(xmlNodeGetContent(field));
|
||||
}
|
||||
else if (!strcmp(field->name, "extensions")) {
|
||||
factory->exts = g_strdup(xmlNodeGetContent(field));
|
||||
}
|
||||
else if (!strcmp(field->name, "typefind")) {
|
||||
factory->typefindfunc = gst_type_typefind_dummy;
|
||||
}
|
||||
field = field->next;
|
||||
}
|
||||
|
||||
return factory;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
|
||||
/* type of function used to check a stream for equality with type */
|
||||
typedef gboolean (*GstTypeFindFunc) (GstBuffer *buf,gpointer *priv);
|
||||
typedef gboolean (*GstTypeFindFunc) (GstBuffer *buf,gpointer priv);
|
||||
|
||||
typedef struct _GstType GstType;
|
||||
typedef struct _GstTypeFactory GstTypeFactory;
|
||||
|
@ -81,4 +81,11 @@ GList *gst_type_get_sink_to_src(guint16 sinkid, guint16 srcid);
|
|||
GList *gst_type_get_list();
|
||||
|
||||
void gst_type_dump();
|
||||
|
||||
xmlNodePtr gst_type_save_thyself(GstType *type, xmlNodePtr parent);
|
||||
guint16 gst_type_load_thyself(xmlNodePtr parent);
|
||||
|
||||
xmlNodePtr gst_typefactory_save_thyself(GstTypeFactory *factory, xmlNodePtr parent);
|
||||
GstTypeFactory *gst_typefactory_load_thyself(xmlNodePtr parent);
|
||||
|
||||
#endif /* __GST_TYPE_H__ */
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
|
||||
GstTypeFactory _factories[] = {
|
||||
{ "audio/raw", ".raw", NULL },
|
||||
{ "audio/ac3", ".ac3", NULL },
|
||||
{ "video/raw image/raw", ".raw", NULL },
|
||||
{ NULL, NULL, NULL },
|
||||
};
|
||||
|
@ -42,6 +41,7 @@ GstPlugin *plugin_init(GModule *module) {
|
|||
|
||||
while (_factories[i].mime) {
|
||||
gst_type_register(&_factories[i]);
|
||||
gst_plugin_add_type(plugin, &_factories[i]);
|
||||
// DEBUG("added factory #%d '%s'\n",i,_factories[i].mime);
|
||||
i++;
|
||||
}
|
||||
|
|
|
@ -315,6 +315,7 @@ main (int argc, char *argv[])
|
|||
glade_init();
|
||||
glade_gnome_init();
|
||||
gst_init(&argc,&argv);
|
||||
//gst_plugin_load_all();
|
||||
|
||||
g_print("using %s\n", DATADIR"gstplay.glade");
|
||||
/* load the interface */
|
||||
|
@ -367,13 +368,6 @@ main (int argc, char *argv[])
|
|||
|
||||
glade_xml_signal_autoconnect(xml);
|
||||
|
||||
gst_plugin_load("mpeg1parse");
|
||||
gst_plugin_load("mpeg2parse");
|
||||
gst_plugin_load("mp1videoparse");
|
||||
gst_plugin_load("mp3parse");
|
||||
gst_plugin_load("parsewav");
|
||||
gst_plugin_load("parseavi");
|
||||
|
||||
video_render_queue = gst_elementfactory_make("queue","video_render_queue");
|
||||
gtk_object_set(GTK_OBJECT(video_render_queue),"max_level",BUFFER,NULL);
|
||||
gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(video_render_queue));
|
||||
|
|
|
@ -21,20 +21,21 @@ int main(int argc,char *argv[])
|
|||
}
|
||||
|
||||
gst_init(&argc,&argv);
|
||||
gst_plugin_load_all();
|
||||
g_print("\n");
|
||||
|
||||
/* create a new bin to hold the elements */
|
||||
pipeline = gst_pipeline_new("pipeline");
|
||||
g_assert(pipeline != NULL);
|
||||
|
||||
/* create a disk reader */
|
||||
disksrc = gst_elementfactory_make("disksrc", "disk_source");
|
||||
g_assert(disksrc != NULL);
|
||||
gtk_object_set(GTK_OBJECT(disksrc),"location", argv[1],NULL);
|
||||
gtk_signal_connect(GTK_OBJECT(disksrc),"eos",
|
||||
GTK_SIGNAL_FUNC(eos),NULL);
|
||||
|
||||
/* and an audio sink */
|
||||
audiosink = gst_elementfactory_make("audiosink", "play_audio");
|
||||
g_assert(audiosink != NULL);
|
||||
|
||||
/* add objects to the main pipeline */
|
||||
gst_bin_add(GST_BIN(pipeline), disksrc);
|
||||
|
|
3
tools/.gitignore
vendored
3
tools/.gitignore
vendored
|
@ -6,5 +6,6 @@ Makefile.in
|
|||
.deps
|
||||
.libs
|
||||
|
||||
launch
|
||||
gstreamer-launch
|
||||
gstreamer-register
|
||||
*.xml
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
bin_PROGRAMS = launch
|
||||
bin_PROGRAMS = gstreamer-launch gstreamer-register
|
||||
|
||||
CFLAGS = -Wall -O2
|
||||
|
||||
LDADD = $(GLIB_LIBS) $(GTK_LIBS) $(top_builddir)/gst/libgst.la
|
||||
INCLUDES = $(GLIB_CFLAGS) $(GTK_CFLAGS) -I$(top_srcdir)
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include <glib.h>
|
||||
#include <gst/gst.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct _launch_delayed_pad launch_delayed_pad;
|
||||
struct _launch_delayed_pad {
|
||||
|
@ -17,11 +19,11 @@ void launch_newpad(GstElement *element,GstPad *pad,launch_delayed_pad *peer) {
|
|||
}
|
||||
}
|
||||
|
||||
gint parse(int argc,char *argv[],GstElement *parent,gint offset,gchar endchar) {
|
||||
void parse(int argc,char *argv[],GstElement *parent,gint offset,gchar endchar) {
|
||||
gint i = offset;
|
||||
gchar *plugin;
|
||||
GstElement *element, *prevelement;
|
||||
GstPad *prevpad,*nextpad;
|
||||
GstElement *element = NULL, *prevelement;
|
||||
GstPad *prevpad = NULL,*nextpad;
|
||||
gchar *prevpadname = NULL,*nextpadname = NULL;
|
||||
gchar *ptr;
|
||||
gint len;
|
||||
|
@ -64,7 +66,7 @@ gint parse(int argc,char *argv[],GstElement *parent,gint offset,gchar endchar) {
|
|||
// snag the length in advance;
|
||||
len = strlen(argv[i]);
|
||||
// if it's just a connection, pick the 'src' pad and move on
|
||||
if (ptr = strchr(argv[i],'|')) {
|
||||
if ((ptr = strchr(argv[i],'|')) != 0) {
|
||||
// if there's a previous pad name
|
||||
if (ptr != argv[i]) {
|
||||
ptr[0] = '\0';
|
||||
|
@ -98,7 +100,7 @@ int main(int argc,char *argv[]) {
|
|||
gst_info("\n\n");
|
||||
|
||||
pipeline = gst_elementfactory_make("thread","launch");
|
||||
if (t = atoi(argv[1]))
|
||||
if ((t = atoi(argv[1])))
|
||||
parse(argc,argv,pipeline,2,0);
|
||||
else
|
||||
parse(argc,argv,pipeline,1,0);
|
||||
|
@ -112,4 +114,6 @@ int main(int argc,char *argv[]) {
|
|||
sleep(t);
|
||||
else
|
||||
sleep(5);
|
||||
|
||||
return 1;
|
||||
}
|
18
tools/gstreamer-register.c
Normal file
18
tools/gstreamer-register.c
Normal file
|
@ -0,0 +1,18 @@
|
|||
#include <gst/gst.h>
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
xmlDocPtr doc;
|
||||
|
||||
unlink("/etc/gstreamer/reg.xml");
|
||||
|
||||
gst_init(&argc,&argv);
|
||||
gst_plugin_load_all();
|
||||
|
||||
doc = xmlNewDoc("1.0");
|
||||
doc->root = xmlNewDocNode(doc, NULL, "GST-PluginRegistry", NULL);
|
||||
gst_plugin_save_thyself(doc->root);
|
||||
xmlSaveFile("/etc/gstreamer/reg.xml", doc);
|
||||
exit(0);
|
||||
}
|
||||
|
Loading…
Reference in a new issue