parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LOOP_BASED,
- g_param_spec_boolean ("loop_based", "loop_based", "loop_based",
+ g_param_spec_boolean ("loop-based", "Loop-based", "Set to TRUE to use loop-based rather than chain-based scheduling",
TRUE, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SLEEP_TIME,
- g_param_spec_uint ("sleep_time", "sleep_time", "sleep_time",
+ g_param_spec_uint ("sleep-time", "Sleep time", "Microseconds to sleep between processing",
0, G_MAXUINT, 0, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DUPLICATE,
g_param_spec_uint ("duplicate", "Duplicate Buffers", "Push the buffers N times",
static void gst_plugin_register_statics (GModule *module);
static GstPlugin* gst_plugin_register_func (GstPluginDesc *desc, GstPlugin *plugin,
GModule *module);
+GQuark
+gst_plugin_error_quark (void)
+{
+ static GQuark quark = 0;
+ if (!quark)
+ quark = g_quark_from_static_string ("gst_plugin_error");
+ return quark;
+}
+
void
_gst_plugin_initialize (void)
{
/**
* gst_plugin_load_plugin:
* @plugin: The plugin to load
+ * @error: Pointer to a NULL-valued GError.
*
* Load the given plugin.
*
- * Returns: whether or not the plugin loaded
+ * Returns: whether or not the plugin loaded. Sets @error as appropriate.
*/
gboolean
-gst_plugin_load_plugin (GstPlugin *plugin)
+gst_plugin_load_plugin (GstPlugin *plugin, GError **error)
{
GModule *module;
GstPluginDesc *desc;
GST_DEBUG (GST_CAT_PLUGIN_LOADING, "attempt to load plugin \"%s\"", filename);
if (g_module_supported () == FALSE) {
- g_warning ("gstplugin: wow, you built this on a platform without dynamic loading???\n");
+ g_set_error (error,
+ GST_PLUGIN_ERROR,
+ GST_PLUGIN_ERROR_MODULE,
+ "Dynamic loading not supported");
return FALSE;
}
if (stat (filename, &file_status)) {
- g_warning ("problem opening file %s (plugin %s)\n", filename, plugin->name);
+ g_set_error (error,
+ GST_PLUGIN_ERROR,
+ GST_PLUGIN_ERROR_MODULE,
+ "Problem opening file %s (plugin %s)\n",
+ filename, plugin->name);
return FALSE;
}
}
}
else {
- GST_DEBUG (GST_CAT_PLUGIN_LOADING, "could not find plugin_desc in \"%s\"", filename);
+ g_set_error (error,
+ GST_PLUGIN_ERROR,
+ GST_PLUGIN_ERROR_MODULE,
+ "Could not find plugin_desc in \"%s\"",
+ filename);
}
return FALSE;
}
else {
- GST_INFO (GST_CAT_PLUGIN_LOADING, "error loading plugin %s, reason: %s\n", filename, g_module_error());
+ g_set_error (error,
+ GST_PLUGIN_ERROR,
+ GST_PLUGIN_ERROR_MODULE,
+ "Error loading plugin %s, reason: %s\n",
+ filename, g_module_error());
}
return FALSE;
plugin = gst_registry_pool_find_plugin (name);
if (plugin)
- return gst_plugin_load_plugin (plugin);
+ return gst_plugin_load_plugin (plugin, NULL);
return FALSE;
}
#include <gst/gstpluginfeature.h>
+GQuark gst_plugin_error_quark (void);
+#define GST_PLUGIN_ERROR gst_plugin_error_quark ()
+
+typedef enum
+{
+ GST_PLUGIN_ERROR_MODULE,
+ GST_PLUGIN_ERROR_DEPENDENCIES
+} GstPluginError;
+
#define GST_PLUGIN(plugin) ((GstPlugin *) (plugin))
typedef struct _GstPlugin GstPlugin;
GList* gst_plugin_get_feature_list (GstPlugin *plugin);
GstPluginFeature* gst_plugin_find_feature (GstPlugin *plugin, const gchar *name, GType type);
-gboolean gst_plugin_load_plugin (GstPlugin *plugin);
+gboolean gst_plugin_load_plugin (GstPlugin *plugin, GError** error);
gboolean gst_plugin_unload_plugin (GstPlugin *plugin);
void gst_plugin_add_feature (GstPlugin *plugin, GstPluginFeature *feature);
#define dirmode \
(S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
-static void gst_xml_registry_get_perms_func (GstXMLRegistry *registry)
+static gboolean
+make_dir (gchar *filename)
{
struct stat dirstat;
- time_t mod_time = 0;
gchar *dirname;
+
+ if (strrchr (filename, '/') == NULL)
+ return FALSE;
+
+ dirname = g_strndup(filename, strrchr(filename, '/') - filename);
+
+ if (stat (dirname, &dirstat) == -1 && errno == ENOENT) {
+ if (mkdir (dirname, dirmode) != 0) {
+ if (make_dir (dirname) != TRUE) {
+ g_free(dirname);
+ return FALSE;
+ } else {
+ if (mkdir (dirname, dirmode) != 0)
+ return FALSE;
+ }
+ }
+ }
+
+ g_free(dirname);
+ return TRUE;
+}
+
+static void
+gst_xml_registry_get_perms_func (GstXMLRegistry *registry)
+{
+ time_t mod_time = 0;
FILE *temp;
/* if the dir does not exist, make it. if that can't be done, flags = 0x0.
if the file can be appended to, it's writable. if it can then be read,
it's readable. */
- dirname = g_strndup(registry->location,
- strrchr(registry->location, '/') - registry->location);
- if (stat(dirname, &dirstat) == -1 && errno == ENOENT) {
- if (mkdir(dirname, dirmode) != 0) {
- /* we can't do anything with it, leave flags as 0x0 */
- g_free(dirname);
- return;
- }
+ if (make_dir (registry->location) != TRUE) {
+ /* we can't do anything with it, leave flags as 0x0 */
+ return;
}
- g_free(dirname);
mod_time = get_time (registry->location);
static GstRegistryReturn
gst_xml_registry_load_plugin (GstRegistry *registry, GstPlugin *plugin)
{
- if (!gst_plugin_load_plugin (plugin)) {
+ /* FIXME: add gerror support */
+ if (!gst_plugin_load_plugin (plugin, NULL)) {
return GST_REGISTRY_PLUGIN_LOAD_ERROR;
}
return TRUE;
}
-static void
+static GList*
gst_xml_registry_rebuild_recurse (GstXMLRegistry *registry, const gchar *directory)
{
GDir *dir;
- gboolean loaded = FALSE;
+ GList *ret = NULL;
dir = g_dir_open (directory, 0, NULL);
}
dirname = g_strjoin ("/", directory, dirent, NULL);
- gst_xml_registry_rebuild_recurse (registry, dirname);
+ ret = g_list_concat (ret, gst_xml_registry_rebuild_recurse (registry, dirname));
g_free(dirname);
}
g_dir_close (dir);
if ((temp = strstr (directory, ".so")) &&
(!strcmp (temp, ".so"))) {
- GstPlugin *plugin = gst_plugin_new (directory);
-
- loaded = gst_plugin_load_plugin (plugin);
- if (!loaded) {
- g_free (plugin->filename);
- g_free (plugin);
- }
- else {
- gst_registry_add_plugin (GST_REGISTRY (registry), plugin);
- }
+ ret = g_list_prepend (ret, gst_plugin_new (directory));
}
}
}
+
+ return ret;
}
static gboolean
gst_xml_registry_rebuild (GstRegistry *registry)
{
- GList *walk = NULL;
+ GList *walk = NULL, *plugins = NULL, *prune = NULL;
+ GError *error = NULL;
+ gint length;
GstXMLRegistry *xmlregistry = GST_XML_REGISTRY (registry);
walk = registry->paths;
GST_INFO (GST_CAT_PLUGIN_LOADING, "Rebuilding registry %p in directory %s...", registry, path);
- gst_xml_registry_rebuild_recurse (xmlregistry, path);
+ plugins = g_list_concat (plugins, gst_xml_registry_rebuild_recurse (xmlregistry, path));
walk = g_list_next (walk);
}
+ plugins = g_list_reverse (plugins);
+
+ do {
+ length = g_list_length (plugins);
+
+ walk = plugins;
+ while (walk) {
+ g_assert (walk->data);
+ if (gst_plugin_load_plugin (GST_PLUGIN (walk->data), NULL)) {
+ prune = g_list_prepend (prune, walk->data);
+ gst_registry_add_plugin (registry, GST_PLUGIN (walk->data));
+ }
+
+ walk = g_list_next (walk);
+ }
+
+ walk = prune;
+ while (walk) {
+ plugins = g_list_remove (plugins, walk->data);
+ walk = g_list_next (walk);
+ }
+ g_list_free (prune);
+ prune = NULL;
+ } while (g_list_length (plugins) != length);
+
+ walk = plugins;
+ while (walk) {
+ /* should return FALSE */
+ gst_plugin_load_plugin (GST_PLUGIN (walk->data), &error);
+ GST_INFO (GST_CAT_PLUGIN_LOADING, "Plugin %s failed to load: %s\n",
+ ((GstPlugin*)walk->data)->filename, error->message);
+
+ g_free (((GstPlugin*)walk->data)->filename);
+ g_free (walk->data);
+ g_error_free (error);
+ error = NULL;
+
+ walk = g_list_next (walk);
+ }
return TRUE;
}
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LOOP_BASED,
- g_param_spec_boolean ("loop_based", "loop_based", "loop_based",
+ g_param_spec_boolean ("loop-based", "Loop-based", "Set to TRUE to use loop-based rather than chain-based scheduling",
TRUE, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SLEEP_TIME,
- g_param_spec_uint ("sleep_time", "sleep_time", "sleep_time",
+ g_param_spec_uint ("sleep-time", "Sleep time", "Microseconds to sleep between processing",
0, G_MAXUINT, 0, G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DUPLICATE,
g_param_spec_uint ("duplicate", "Duplicate Buffers", "Push the buffers N times",