gstreamer_core/gst/gstelementfactory.c
branchRCL_3
changeset 30 7e817e7e631c
parent 29 567bb019e3e3
--- a/gstreamer_core/gst/gstelementfactory.c	Tue Aug 31 15:30:33 2010 +0300
+++ b/gstreamer_core/gst/gstelementfactory.c	Wed Sep 01 12:16:41 2010 +0100
@@ -40,16 +40,13 @@
  * <title>Using an element factory</title>
  * <programlisting language="c">
  *   #include &lt;gst/gst.h&gt;
- *   
  *   GstElement *src;
  *   GstElementFactory *srcfactory;
- *   
- *   gst_init (&amp;argc, &amp;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(&amp;argc,&amp;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);
  *   ...
  * </programlisting>
  * </example>
@@ -72,33 +69,54 @@
 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
 
-/* this is defined in gstelement.c */
-extern GQuark _gst_elementclass_factory;
+
+GType
+gst_element_factory_get_type (void)
+{
+  static GType elementfactory_type = 0;
 
-#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"); \
+  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
+    };
+
+    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 = (GObjectClass *) klass;
+  GObjectClass *gobject_class;
+  GstObjectClass *gstobject_class;
+  GstPluginFeatureClass *gstpluginfeature_class;
+
+  gobject_class = (GObjectClass *) klass;
+  gstobject_class = (GstObjectClass *) klass;
+  gstpluginfeature_class = (GstPluginFeatureClass *) klass;
 
   parent_class = g_type_class_peek_parent (klass);
 
@@ -180,12 +198,11 @@
         __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)
@@ -215,7 +232,8 @@
 
   __gst_element_details_clear (&factory->details);
   if (factory->type) {
-    factory->type = G_TYPE_INVALID;
+    g_type_class_unref (g_type_class_peek (factory->type));
+    factory->type = 0;
   }
 
   for (item = factory->staticpadtemplates; item; item = item->next) {
@@ -274,8 +292,6 @@
 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;
@@ -285,27 +301,8 @@
   g_return_val_if_fail (name != NULL, FALSE);
   g_return_val_if_fail (g_type_is_a (type, GST_TYPE_ELEMENT), FALSE);
 
-  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);
+  factory = GST_ELEMENT_FACTORY (g_object_new (GST_TYPE_ELEMENT_FACTORY, NULL));
+  gst_plugin_feature_set_name (GST_PLUGIN_FEATURE (factory), name);
   GST_LOG_OBJECT (factory, "Created new elementfactory for type %s",
       g_type_name (type));
 
@@ -329,7 +326,7 @@
         g_list_append (factory->staticpadtemplates, newt);
   }
   factory->numpadtemplates = klass->numpadtemplates;
-  g_type_set_qdata (type, _gst_elementclass_factory, factory);
+  klass->elementfactory = factory;
 
   /* special stuff for URI handling */
   if (g_type_is_a (type, GST_TYPE_URI_HANDLER)) {
@@ -360,14 +357,15 @@
   g_free (interfaces);
 
   if (plugin && plugin->desc.name) {
-    GST_PLUGIN_FEATURE_CAST (factory)->plugin_name = plugin->desc.name;
+    GST_PLUGIN_FEATURE (factory)->plugin_name = plugin->desc.name;
   } else {
-    GST_PLUGIN_FEATURE_CAST (factory)->plugin_name = "NULL";
+    GST_PLUGIN_FEATURE (factory)->plugin_name = "NULL";
   }
-  gst_plugin_feature_set_rank (GST_PLUGIN_FEATURE_CAST (factory), rank);
-  GST_PLUGIN_FEATURE_CAST (factory)->loaded = TRUE;
+  gst_plugin_feature_set_rank (GST_PLUGIN_FEATURE (factory), rank);
+  GST_PLUGIN_FEATURE (factory)->loaded = TRUE;
 
-  gst_registry_add_feature (registry, GST_PLUGIN_FEATURE_CAST (factory));
+  gst_registry_add_feature (gst_registry_get_default (),
+      GST_PLUGIN_FEATURE (factory));
 
   return TRUE;
 
@@ -437,16 +435,16 @@
 
   /* fill in the pointer to the factory in the element class. The
    * class will not be unreffed currently. 
-   * Be thread safe as there might be 2 threads creating the first instance of
-   * an element at the same moment
-   */
+   * 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 */
   oclass = GST_ELEMENT_GET_CLASS (element);
-  if (!g_atomic_pointer_compare_and_exchange (
-          (gpointer) & oclass->elementfactory, NULL, factory))
+  if (G_UNLIKELY (oclass->elementfactory == NULL))
+    oclass->elementfactory = factory;
+  else
     gst_object_unref (factory);
 
   if (name)
-    gst_object_set_name (GST_OBJECT_CAST (element), name);
+    gst_object_set_name (GST_OBJECT (element), name);
 
   GST_DEBUG ("created element \"%s\"", GST_PLUGIN_FEATURE_NAME (factory));
 
@@ -455,8 +453,7 @@
   /* ERRORS */
 load_failed:
   {
-    GST_WARNING_OBJECT (factory,
-        "loading plugin containing feature %s returned NULL!", name);
+    GST_WARNING_OBJECT (factory, "loading plugin returned NULL!");
     return NULL;
   }
 no_type:
@@ -506,10 +503,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 */
@@ -521,7 +518,6 @@
 create_failed:
   {
     GST_INFO_OBJECT (factory, "couldn't create instance!");
-    gst_object_unref (factory);
     return NULL;
   }
 }
@@ -713,7 +709,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
  */