Merge branch 'move_subdir' into tizen_gst_1.19.2_mono
[platform/upstream/gstreamer.git] / subprojects / gstreamer / gst / gstelementfactory.c
index cd84130..70a183c 100644 (file)
@@ -88,6 +88,11 @@ extern GQuark __gst_elementclass_factory;
 G_DEFINE_TYPE_WITH_CODE (GstElementFactory, gst_element_factory,
     GST_TYPE_PLUGIN_FEATURE, _do_init);
 
+#ifdef TIZEN_PROFILE_TV
+static GMutex pool_mutex;
+static GList *pool = NULL;
+#endif
+
 static void
 gst_element_factory_class_init (GstElementFactoryClass * klass)
 {
@@ -1176,3 +1181,108 @@ gst_element_factory_list_filter (GList * list,
   }
   return results.head;
 }
+
+#ifdef TIZEN_PROFILE_TV
+/**
+ * gst_element_factory_pool_push:
+ *
+ * Pushes the element to the pool. This function increase the refcount of @element.
+ * And the pool will take a reference forever.
+ * MT safe.
+ */
+static gboolean
+gst_element_factory_pool_push (GstElement * element)
+{
+  gboolean ret = FALSE;
+  g_return_val_if_fail (element != NULL, FALSE);
+  g_return_val_if_fail (GST_IS_ELEMENT (element) == TRUE, FALSE);
+  g_return_val_if_fail (GST_IS_BIN (element) == FALSE, FALSE);
+  g_return_val_if_fail (GST_IS_PIPELINE (element) == FALSE, FALSE);
+
+  g_mutex_lock (&pool_mutex);
+  if (!g_list_find (pool, (gconstpointer) element)) {
+    gst_object_ref (element);
+    pool = g_list_prepend (pool, element);
+    ret = TRUE;
+  }
+  //GST_INFO("ret[ %d ], [ %s / %p ] - refcount[ %d ], state[ %d ]", ret, GST_ELEMENT_NAME(element), element, GST_OBJECT_REFCOUNT(element), GST_STATE (element));
+  g_mutex_unlock (&pool_mutex);
+  return ret;
+}
+
+static gint
+is_available_element (gconstpointer data, gconstpointer factory_)
+{
+  GstElement *element = GST_ELEMENT_CAST (data);
+  const GstElementFactory *factory = (const GstElementFactory *) factory_;
+  gboolean found = FALSE;
+  if (gst_element_get_factory (element) == factory
+      && GST_ELEMENT_PARENT (element) == NULL
+      && GST_OBJECT_REFCOUNT (element) == 1
+      && (GST_STATE (element) == GST_STATE_NULL
+          || GST_STATE (element) == GST_STATE_VOID_PENDING)) {
+    found = TRUE;
+  }
+  //GST_DEBUG("PARENT[ %p ], [ %s / %p ] - refcount[ %d ], state[ %d ]", GST_ELEMENT_PARENT(element), GST_ELEMENT_NAME(element), element, GST_OBJECT_REFCOUNT(element), GST_STATE (element));
+
+  if (found)
+    return 0;
+
+  return -1;
+}
+
+/**
+ * gst_element_factory_pool_get:
+ *
+ * Get a element which is created by given @factoryname
+ * You can search any element by this API before you use gst_element_factory_create.
+ * Returns: (transfer full): a pointer to the #GstElement.
+ *         This function guarantee that the refcount of returned #GstElement is 1,
+ *         and it's state is NULL-STATE.
+ *
+ * MT safe.
+ */
+static GstElement *
+gst_element_factory_pool_get (GstElementFactory * factory,
+    const gchar * new_element_name)
+{
+  GstElement *element = NULL;
+  GList *found = NULL;
+  g_return_val_if_fail (factory != NULL, NULL);
+  g_return_val_if_fail (pool != NULL, NULL);
+
+  g_mutex_lock (&pool_mutex);
+  found = g_list_find_custom (pool, factory, is_available_element);
+  if (found) {
+    element = GST_ELEMENT_CAST (found->data);
+    gst_object_ref (element);
+    if (new_element_name)
+      gst_element_set_name (element, new_element_name);
+  }
+  g_mutex_unlock (&pool_mutex);
+  return element;
+}
+
+/* First, Try to get element from pool. */
+GstElement *
+gst_element_factory_get (GstElementFactory * factory, const gchar * name)
+{
+  GstElement *element = NULL;
+  g_return_val_if_fail (factory != NULL, NULL);
+  element = gst_element_factory_pool_get (factory, name);
+  if (!element) {
+    element = gst_element_factory_create (factory, name);
+    if (!element) {
+      GST_ERROR ("[ %s / %p ],  new element name[ %s ]",
+          GST_OBJECT_NAME (factory), factory, name);
+      return NULL;
+    }
+    gst_element_factory_pool_push (element);
+  } else {
+    gst_set_family_id_to_child (element, 0);
+  }
+
+  //GST_INFO("[ %s / %p ] - refcount[ %d ], state[ %d ]", GST_ELEMENT_NAME(element), element, GST_OBJECT_REFCOUNT(element), GST_STATE (element));
+  return element;
+}
+#endif