diff -r 9b2c3c7a1a9c -r 567bb019e3e3 gstreamer_core/gst/gstelementfactory.c
--- a/gstreamer_core/gst/gstelementfactory.c Wed Mar 31 22:03:18 2010 +0300
+++ b/gstreamer_core/gst/gstelementfactory.c Tue Aug 31 15:30:33 2010 +0300
@@ -40,13 +40,16 @@
*
Using an element factory
*
* #include <gst/gst.h>
+ *
* GstElement *src;
* GstElementFactory *srcfactory;
- * gst_init(&argc,&argv);
- * srcfactory = gst_element_factory_find("filesrc");
- * g_return_if_fail(srcfactory != NULL);
- * src = gst_element_factory_create(srcfactory,"src");
- * g_return_if_fail(src != NULL);
+ *
+ * gst_init (&argc, &argv);
+ *
+ * srcfactory = gst_element_factory_find ("filesrc");
+ * g_return_if_fail (srcfactory != NULL);
+ * src = gst_element_factory_create (srcfactory, "src");
+ * g_return_if_fail (src != NULL);
* ...
*
*
@@ -69,54 +72,33 @@
static void gst_element_factory_class_init (GstElementFactoryClass * klass);
static void gst_element_factory_init (GstElementFactory * factory);
static void gst_element_factory_finalize (GObject * object);
+#ifdef __SYMBIAN32__
+IMPORT_C
+#endif
void __gst_element_details_clear (GstElementDetails * dp);
static void gst_element_factory_cleanup (GstElementFactory * factory);
static GstPluginFeatureClass *parent_class = NULL;
/* static guint gst_element_factory_signals[LAST_SIGNAL] = { 0 }; */
-#ifdef __SYMBIAN32__
-EXPORT_C
-#endif
-
-GType
-gst_element_factory_get_type (void)
-{
- static GType elementfactory_type = 0;
+/* this is defined in gstelement.c */
+extern GQuark _gst_elementclass_factory;
- if (G_UNLIKELY (elementfactory_type == 0)) {
- static const GTypeInfo elementfactory_info = {
- sizeof (GstElementFactoryClass),
- NULL,
- NULL,
- (GClassInitFunc) gst_element_factory_class_init,
- NULL,
- NULL,
- sizeof (GstElementFactory),
- 0,
- (GInstanceInitFunc) gst_element_factory_init,
- NULL
- };
+#define _do_init \
+{ \
+ GST_DEBUG_CATEGORY_INIT (element_factory_debug, "GST_ELEMENT_FACTORY", \
+ GST_DEBUG_BOLD | GST_DEBUG_FG_WHITE | GST_DEBUG_BG_RED, \
+ "element factories keep information about installed elements"); \
+}
- elementfactory_type = g_type_register_static (GST_TYPE_PLUGIN_FEATURE,
- "GstElementFactory", &elementfactory_info, 0);
- GST_DEBUG_CATEGORY_INIT (element_factory_debug, "GST_ELEMENT_FACTORY",
- GST_DEBUG_BOLD | GST_DEBUG_FG_WHITE | GST_DEBUG_BG_RED,
- "element factories keep information about installed elements");
- }
- return elementfactory_type;
-}
+G_DEFINE_TYPE_WITH_CODE (GstElementFactory, gst_element_factory,
+ GST_TYPE_PLUGIN_FEATURE, _do_init);
+
static void
gst_element_factory_class_init (GstElementFactoryClass * klass)
{
- GObjectClass *gobject_class;
- GstObjectClass *gstobject_class;
- GstPluginFeatureClass *gstpluginfeature_class;
-
- gobject_class = (GObjectClass *) klass;
- gstobject_class = (GstObjectClass *) klass;
- gstpluginfeature_class = (GstPluginFeatureClass *) klass;
+ GObjectClass *gobject_class = (GObjectClass *) klass;
parent_class = g_type_class_peek_parent (klass);
@@ -198,11 +180,12 @@
__src->__entry); \
__dest->__entry = g_strdup ("[ERROR: invalid UTF-8]"); \
} \
-} G_STMT_END
-
+}G_STMT_END
#ifdef __SYMBIAN32__
EXPORT_C
#endif
+
+
void
__gst_element_details_set (GstElementDetails * dest,
const GstElementDetails * src)
@@ -232,8 +215,7 @@
__gst_element_details_clear (&factory->details);
if (factory->type) {
- g_type_class_unref (g_type_class_peek (factory->type));
- factory->type = 0;
+ factory->type = G_TYPE_INVALID;
}
for (item = factory->staticpadtemplates; item; item = item->next) {
@@ -292,6 +274,8 @@
gst_element_register (GstPlugin * plugin, const gchar * name, guint rank,
GType type)
{
+ GstPluginFeature *existing_feature;
+ GstRegistry *registry;
GstElementFactory *factory;
GType *interfaces;
guint n_interfaces, i;
@@ -301,8 +285,27 @@
g_return_val_if_fail (name != NULL, FALSE);
g_return_val_if_fail (g_type_is_a (type, GST_TYPE_ELEMENT), FALSE);
- factory = GST_ELEMENT_FACTORY (g_object_new (GST_TYPE_ELEMENT_FACTORY, NULL));
- gst_plugin_feature_set_name (GST_PLUGIN_FEATURE (factory), name);
+ registry = gst_registry_get_default ();
+
+ /* check if feature already exists, if it exists there is no need to update it
+ * when the registry is getting updated, outdated plugins and all there
+ * feature are removed and readded.
+ */
+ existing_feature = gst_registry_lookup_feature (registry, name);
+ if (existing_feature) {
+ GST_DEBUG_OBJECT (registry, "update existing feature %p (%s)",
+ existing_feature, name);
+ factory = GST_ELEMENT_FACTORY_CAST (existing_feature);
+ factory->type = type;
+ existing_feature->loaded = TRUE;
+ g_type_set_qdata (type, _gst_elementclass_factory, factory);
+ gst_object_unref (existing_feature);
+ return TRUE;
+ }
+
+ factory =
+ GST_ELEMENT_FACTORY_CAST (g_object_new (GST_TYPE_ELEMENT_FACTORY, NULL));
+ gst_plugin_feature_set_name (GST_PLUGIN_FEATURE_CAST (factory), name);
GST_LOG_OBJECT (factory, "Created new elementfactory for type %s",
g_type_name (type));
@@ -326,7 +329,7 @@
g_list_append (factory->staticpadtemplates, newt);
}
factory->numpadtemplates = klass->numpadtemplates;
- klass->elementfactory = factory;
+ g_type_set_qdata (type, _gst_elementclass_factory, factory);
/* special stuff for URI handling */
if (g_type_is_a (type, GST_TYPE_URI_HANDLER)) {
@@ -357,15 +360,14 @@
g_free (interfaces);
if (plugin && plugin->desc.name) {
- GST_PLUGIN_FEATURE (factory)->plugin_name = plugin->desc.name;
+ GST_PLUGIN_FEATURE_CAST (factory)->plugin_name = plugin->desc.name;
} else {
- GST_PLUGIN_FEATURE (factory)->plugin_name = "NULL";
+ GST_PLUGIN_FEATURE_CAST (factory)->plugin_name = "NULL";
}
- gst_plugin_feature_set_rank (GST_PLUGIN_FEATURE (factory), rank);
- GST_PLUGIN_FEATURE (factory)->loaded = TRUE;
+ gst_plugin_feature_set_rank (GST_PLUGIN_FEATURE_CAST (factory), rank);
+ GST_PLUGIN_FEATURE_CAST (factory)->loaded = TRUE;
- gst_registry_add_feature (gst_registry_get_default (),
- GST_PLUGIN_FEATURE (factory));
+ gst_registry_add_feature (registry, GST_PLUGIN_FEATURE_CAST (factory));
return TRUE;
@@ -435,16 +437,16 @@
/* fill in the pointer to the factory in the element class. The
* class will not be unreffed currently.
- * FIXME: This isn't safe and may leak a refcount on the factory if 2 threads
- * create the first instance of an element at the same moment */
+ * Be thread safe as there might be 2 threads creating the first instance of
+ * an element at the same moment
+ */
oclass = GST_ELEMENT_GET_CLASS (element);
- if (G_UNLIKELY (oclass->elementfactory == NULL))
- oclass->elementfactory = factory;
- else
+ if (!g_atomic_pointer_compare_and_exchange (
+ (gpointer) & oclass->elementfactory, NULL, factory))
gst_object_unref (factory);
if (name)
- gst_object_set_name (GST_OBJECT (element), name);
+ gst_object_set_name (GST_OBJECT_CAST (element), name);
GST_DEBUG ("created element \"%s\"", GST_PLUGIN_FEATURE_NAME (factory));
@@ -453,7 +455,8 @@
/* ERRORS */
load_failed:
{
- GST_WARNING_OBJECT (factory, "loading plugin returned NULL!");
+ GST_WARNING_OBJECT (factory,
+ "loading plugin containing feature %s returned NULL!", name);
return NULL;
}
no_type:
@@ -503,10 +506,10 @@
GST_LOG_OBJECT (factory, "found factory %p", factory);
element = gst_element_factory_create (factory, name);
- gst_object_unref (factory);
if (element == NULL)
goto create_failed;
+ gst_object_unref (factory);
return element;
/* ERRORS */
@@ -518,6 +521,7 @@
create_failed:
{
GST_INFO_OBJECT (factory, "couldn't create instance!");
+ gst_object_unref (factory);
return NULL;
}
}
@@ -709,7 +713,7 @@
* gst_element_factory_get_uri_type:
* @factory: a #GstElementFactory
*
- * Gets the type of URIs the element supports or GST_URI_UNKNOWN if none.
+ * Gets the type of URIs the element supports or #GST_URI_UNKNOWN if none.
*
* Returns: type of URIs this element supports
*/