add factory pool to reuse and preload for reducing loading time 96/87296/8
authorYounghwan <younghwan_.an@samsung.com>
Wed, 7 Sep 2016 08:43:39 +0000 (17:43 +0900)
committerYounghwan <younghwan_.an@samsung.com>
Mon, 12 Sep 2016 01:49:24 +0000 (10:49 +0900)
Change-Id: Idb4551efee8293ff36f73dd051b622b02d470b9b

configure.ac
gst/gstelementfactory.c
gst/gstelementfactory.h
packaging/gstreamer.spec
pkgconfig/gstreamer.pc.in

index 53f2fae..61883dc 100644 (file)
@@ -846,6 +846,18 @@ fi
 AM_CONDITIONAL(USE_DLOG, test "x$USE_DLOG" = "xyes")
 dnl end
 
+dnl Check for tv-profile
+AC_ARG_ENABLE(tv-profile, AC_HELP_STRING([--enable-tv-profile], [using tv-profile]),
+[
+ case "${enableval}" in
+         yes) HAVE_TV_PROFILE="-DTIZEN_PROFILE_TV" ;;
+         no)  HAVE_TV_PROFILE= ;;
+         *)   AC_MSG_ERROR(bad value ${enableval} for --enable-tv-profile) ;;
+ esac
+],[HAVE_TV_PROFILE=])
+AC_SUBST(HAVE_TV_PROFILE)
+dnl end
+
 dnl *** set variables based on configure arguments
 
 dnl set license and copyright notice
index 486b9fe..d9ae798 100644 (file)
@@ -87,6 +87,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)
 {
@@ -875,3 +880,109 @@ 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 (new_element_name != NULL, 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
index 17e55ce..84c6b3a 100644 (file)
@@ -74,6 +74,9 @@ GstElement*             gst_element_factory_make                (const gchar *fa
 
 gboolean                gst_element_register                    (GstPlugin *plugin, const gchar *name,
                                                                  guint rank, GType type);
+#ifdef TIZEN_PROFILE_TV
+GstElement              *gst_element_factory_get                (GstElementFactory * factory, const gchar * name);
+#endif
 
 /* Factory list functions */
 
index 2b2afd3..3790bf3 100644 (file)
@@ -84,6 +84,9 @@ export CFLAGS="%{optflags} \
         --disable-docbook\
         --disable-gtk-doc\
         --enable-dlog\
+%if "%{?profile}" == "tv"
+        --enable-tv-profile\
+%endif
         --disable-examples
 make %{?_smp_mflags}
 
index 381c96d..444ccbf 100644 (file)
@@ -17,4 +17,4 @@ Version: @VERSION@
 Requires: glib-2.0, gobject-2.0
 Requires.private: gmodule-no-export-2.0
 Libs: -L${libdir} -lgstreamer-@GST_API_VERSION@
-Cflags: -I${includedir} -I${libdir}/gstreamer-@GST_API_VERSION@/include
+Cflags: -I${includedir} -I${libdir}/gstreamer-@GST_API_VERSION@/include @HAVE_TV_PROFILE@