Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/GStreamer/gstreamer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThéo MAILLART <tmaillart@gmail.com>2021-01-29 22:36:51 +0300
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>2021-08-20 04:41:30 +0300
commitaadf84837b2c0397b02ffb39f704ef4649482a44 (patch)
tree1bf59a9099305cf7b25530b56df43ade20f3b7c0
parenta4a17828728cd900769c9016376820a9c3bb0c59 (diff)
elementfactory: enable construct only property passing
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/736>
-rw-r--r--gst/gstelementfactory.c345
-rw-r--r--gst/gstelementfactory.h18
2 files changed, 333 insertions, 30 deletions
diff --git a/gst/gstelementfactory.c b/gst/gstelementfactory.c
index f7b71bb7c3..cd84130268 100644
--- a/gst/gstelementfactory.c
+++ b/gst/gstelementfactory.c
@@ -65,6 +65,8 @@
#include "glib-compat-private.h"
+#include <gobject/gvaluecollector.h>
+
GST_DEBUG_CATEGORY_STATIC (element_factory_debug);
#define GST_CAT_DEFAULT element_factory_debug
@@ -325,21 +327,94 @@ detailserror:
}
}
+static gboolean
+gst_element_factory_property_valist_to_array (const gchar * first,
+ va_list properties, GType object_type, guint * n, const gchar ** names[],
+ GValue ** values)
+{
+ GObjectClass *class;
+ const gchar *name;
+ guint n_params = 0;
+ guint n_params_alloc = 16;
+ GValue *values_array;
+ const gchar **names_array;
+
+ if (!first)
+ return FALSE;
+
+ g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type), FALSE);
+
+ class = g_type_class_ref (object_type);
+ if (!class)
+ return FALSE;
+
+ name = first;
+ names_array = g_new0 (const gchar *, n_params_alloc);
+ values_array = g_new0 (GValue, n_params_alloc);
+
+ do {
+ gchar *error = NULL;
+ GParamSpec *pspec;
+
+ pspec = g_object_class_find_property (class, name);
+ if (!pspec)
+ goto cleanup;
+
+ if (G_UNLIKELY (n_params == n_params_alloc)) {
+ n_params_alloc *= 2u;
+ names_array =
+ g_realloc (names_array, sizeof (const gchar *) * n_params_alloc);
+ values_array = g_realloc (values_array, sizeof (GValue) * n_params_alloc);
+ memset (&values_array[n_params], 0,
+ sizeof (GValue) * (n_params_alloc - n_params));
+ }
+
+ names_array[n_params] = name;
+
+ G_VALUE_COLLECT_INIT (&values_array[n_params], pspec->value_type,
+ properties, 0, &error);
+
+ if (error) {
+ g_critical ("%s", error);
+ g_free (error);
+ goto cleanup;
+ }
+
+ ++n_params;
+ name = va_arg (properties, const gchar *);
+ } while (name);
+
+ *n = n_params;
+ *names = names_array;
+ *values = values_array;
+ g_type_class_unref (class);
+ return TRUE;
+
+cleanup:
+ g_free (names_array);
+ g_free (values_array);
+ g_type_class_unref (class);
+ return FALSE;
+}
+
/**
- * gst_element_factory_create:
+ * gst_element_factory_create_with_properties:
* @factory: factory to instantiate
- * @name: (allow-none): name of new element, or %NULL to automatically create
- * a unique name
+ * @n: count of properties
+ * @names: (nullable): array of properties names
+ * @values: (nullable): array of associated properties values
*
* Create a new element of the type defined by the given elementfactory.
- * It will be given the name supplied, since all elements require a name as
- * their first argument.
+ * The supplied list of properties, will be passed at object construction.
*
* Returns: (transfer floating) (nullable): new #GstElement or %NULL
* if the element couldn't be created
+ *
+ * Since: 1.20
*/
GstElement *
-gst_element_factory_create (GstElementFactory * factory, const gchar * name)
+gst_element_factory_create_with_properties (GstElementFactory * factory,
+ guint n, const gchar * names[], const GValue values[])
{
GstElement *element;
GstElementClass *oclass;
@@ -356,22 +431,14 @@ gst_element_factory_create (GstElementFactory * factory, const gchar * name)
factory = newfactory;
- if (name)
- GST_INFO ("creating element \"%s\" named \"%s\"",
- GST_OBJECT_NAME (factory), GST_STR_NULL (name));
- else
- GST_INFO ("creating element \"%s\"", GST_OBJECT_NAME (factory));
+ GST_INFO ("creating element \"%s\"", GST_OBJECT_NAME (factory));
if (factory->type == 0)
goto no_type;
- /* create an instance of the element, cast so we don't assert on NULL
- * also set name as early as we can
- */
- if (name)
- element = g_object_new (factory->type, "name", name, NULL);
- else
- element = g_object_new (factory->type, NULL);
+ element = (GstElement *) g_object_new_with_properties (factory->type, n,
+ names, values);
+
if (G_UNLIKELY (element == NULL))
goto no_element;
@@ -404,8 +471,7 @@ gst_element_factory_create (GstElementFactory * factory, const gchar * name)
/* 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:
@@ -423,21 +489,188 @@ no_element:
}
/**
- * gst_element_factory_make:
- * @factoryname: a named factory to instantiate
- * @name: (allow-none): name of new element, or %NULL to automatically create
+ * gst_element_factory_create_valist:
+ * @factory: factory to instantiate
+ * @first: (nullable): name of the first property
+ * @properties: (nullable): list of properties
+ *
+ * Create a new element of the type defined by the given elementfactory.
+ * The supplied list of properties, will be passed at object construction.
+ *
+ * Returns: (transfer floating) (nullable): new #GstElement or %NULL
+ * if the element couldn't be created
+ *
+ * Since: 1.20
+ */
+GstElement *
+gst_element_factory_create_valist (GstElementFactory * factory,
+ const gchar * first, va_list properties)
+{
+ GstElementFactory *newfactory;
+ GstElement *element;
+ const gchar **names = NULL;
+ GValue *values = NULL;
+ guint n = 0;
+
+ g_return_val_if_fail (factory != NULL, NULL);
+
+ newfactory =
+ GST_ELEMENT_FACTORY (gst_plugin_feature_load (GST_PLUGIN_FEATURE
+ (factory)));
+
+ g_return_val_if_fail (newfactory != NULL, NULL);
+ g_return_val_if_fail (newfactory->type != 0, NULL);
+
+ factory = newfactory;
+
+ if (!first) {
+ element =
+ gst_element_factory_create_with_properties (factory, 0, NULL, NULL);
+ goto out;
+ }
+
+ if (!gst_element_factory_property_valist_to_array (first, properties,
+ factory->type, &n, &names, &values)) {
+ GST_ERROR_OBJECT (factory, "property parsing failed");
+ element = NULL;
+ goto out;
+ }
+
+ element = gst_element_factory_create_with_properties (factory, n, names,
+ values);
+
+ g_free (names);
+ while (n--)
+ g_value_unset (&values[n]);
+ g_free (values);
+
+out:
+ gst_object_unref (factory);
+ return element;
+}
+
+/**
+ * gst_element_factory_create_full:
+ * @factory: factory to instantiate
+ * @first: (nullable): name of the first property
+ * @...: (nullable): %NULL terminated list of properties
+ *
+ * Create a new element of the type defined by the given elementfactory.
+ * The supplied list of properties, will be passed at object construction.
+ *
+ * Returns: (transfer floating) (nullable): new #GstElement or %NULL
+ * if the element couldn't be created
+ *
+ * Since: 1.20
+ */
+GstElement *
+gst_element_factory_create_full (GstElementFactory * factory,
+ const gchar * first, ...)
+{
+ GstElement *element;
+ va_list properties;
+
+ va_start (properties, first);
+ element = gst_element_factory_create_valist (factory, first, properties);
+ va_end (properties);
+
+ return element;
+}
+
+/**
+ * gst_element_factory_create:
+ * @factory: factory to instantiate
+ * @name: (nullable): name of new element, or %NULL to automatically create
* a unique name
*
+ * Create a new element of the type defined by the given elementfactory.
+ * It will be given the name supplied, since all elements require a name as
+ * their first argument.
+ *
+ * Returns: (transfer floating) (nullable): new #GstElement or %NULL
+ * if the element couldn't be created
+ */
+GstElement *
+gst_element_factory_create (GstElementFactory * factory, const gchar * name)
+{
+ if (name)
+ return gst_element_factory_create_full (factory, "name", name, NULL);
+ else
+ return gst_element_factory_create_with_properties (factory, 0, NULL, NULL);
+}
+
+/**
+ * gst_element_factory_make_with_properties:
+ * @factoryname: a named factory to instantiate
+ * @n: count of properties
+ * @names: (nullable): array of properties names
+ * @values: (nullable): array of associated properties values
+ *
+ * Create a new element of the type defined by the given elementfactory.
+ * The supplied list of properties, will be passed at object construction.
+ *
+ * Returns: (transfer floating) (nullable): new #GstElement or %NULL
+ * if the element couldn't be created
+ *
+ * Since: 1.20
+ */
+GstElement *
+gst_element_factory_make_with_properties (const gchar * factoryname,
+ guint n, const gchar * names[], const GValue values[])
+{
+ GstElementFactory *factory;
+ GstElement *element;
+
+ g_return_val_if_fail (factoryname != NULL, NULL);
+ g_return_val_if_fail (gst_is_initialized (), NULL);
+
+ GST_LOG ("gstelementfactory: make \"%s\"", factoryname);
+
+ factory = gst_element_factory_find (factoryname);
+ if (factory == NULL)
+ goto no_factory;
+
+ GST_LOG_OBJECT (factory, "found factory %p", factory);
+ element = gst_element_factory_create_with_properties (factory, n, names,
+ values);
+ if (element == NULL)
+ goto create_failed;
+
+ gst_object_unref (factory);
+
+ return element;
+
+ /* ERRORS */
+no_factory:
+ {
+ GST_WARNING ("no such element factory \"%s\"!", factoryname);
+ return NULL;
+ }
+create_failed:
+ {
+ GST_INFO_OBJECT (factory, "couldn't create instance!");
+ gst_object_unref (factory);
+ return NULL;
+ }
+}
+
+/**
+ * gst_element_factory_make_valist:
+ * @factoryname: a named factory to instantiate
+ * @first: (nullable): name of first property
+ * @properties: (nullable): list of properties
+ *
* Create a new element of the type defined by the given element factory.
- * If name is %NULL, then the element will receive a guaranteed unique name,
- * consisting of the element factory name and a number.
- * If name is given, it will be given the name supplied.
+ * The supplied list of properties, will be passed at object construction.
*
* Returns: (transfer floating) (nullable): new #GstElement or %NULL
* if unable to create element
+ *
+ * Since: 1.20
*/
GstElement *
-gst_element_factory_make (const gchar * factoryname, const gchar * name)
+gst_element_factory_make_valist (const gchar * factoryname,
+ const gchar * first, va_list properties)
{
GstElementFactory *factory;
GstElement *element;
@@ -445,15 +678,14 @@ gst_element_factory_make (const gchar * factoryname, const gchar * name)
g_return_val_if_fail (factoryname != NULL, NULL);
g_return_val_if_fail (gst_is_initialized (), NULL);
- GST_LOG ("gstelementfactory: make \"%s\" \"%s\"",
- factoryname, GST_STR_NULL (name));
+ GST_LOG ("gstelementfactory: make \"%s\"", factoryname);
factory = gst_element_factory_find (factoryname);
if (factory == NULL)
goto no_factory;
GST_LOG_OBJECT (factory, "found factory %p", factory);
- element = gst_element_factory_create (factory, name);
+ element = gst_element_factory_create_valist (factory, first, properties);
if (element == NULL)
goto create_failed;
@@ -475,6 +707,59 @@ create_failed:
}
}
+/**
+ * gst_element_factory_make_full:
+ * @factoryname: a named factory to instantiate
+ * @first: (nullable): name of first property
+ * @...: (nullable): %NULL terminated list of properties
+ *
+ * Create a new element of the type defined by the given element factory.
+ * The supplied list of properties, will be passed at object construction.
+ *
+ * Returns: (transfer floating) (nullable): new #GstElement or %NULL
+ * if unable to create element
+ *
+ * Since: 1.20
+ */
+GstElement *
+gst_element_factory_make_full (const gchar * factoryname,
+ const gchar * first, ...)
+{
+ GstElement *element;
+ va_list properties;
+
+ va_start (properties, first);
+
+ element = gst_element_factory_make_valist (factoryname, first, properties);
+
+ va_end (properties);
+ return element;
+}
+
+/**
+ * gst_element_factory_make:
+ * @factoryname: a named factory to instantiate
+ * @name: (nullable): name of new element, or %NULL to automatically create
+ * a unique name
+ *
+ * Create a new element of the type defined by the given element factory.
+ * If name is %NULL, then the element will receive a guaranteed unique name,
+ * consisting of the element factory name and a number.
+ * If name is given, it will be given the name supplied.
+ *
+ * Returns: (transfer floating) (nullable): new #GstElement or %NULL
+ * if unable to create element
+ */
+GstElement *
+gst_element_factory_make (const gchar * factoryname, const gchar * name)
+{
+ if (name)
+ return gst_element_factory_make_full (factoryname, "name", name, NULL);
+ else
+ return gst_element_factory_make_with_properties (factoryname, 0, NULL,
+ NULL);
+}
+
void
__gst_element_factory_add_static_pad_template (GstElementFactory * factory,
GstStaticPadTemplate * templ)
diff --git a/gst/gstelementfactory.h b/gst/gstelementfactory.h
index cffb123429..518bb9bec5 100644
--- a/gst/gstelementfactory.h
+++ b/gst/gstelementfactory.h
@@ -84,9 +84,27 @@ GST_API
GstElement* gst_element_factory_create (GstElementFactory *factory,
const gchar *name) G_GNUC_MALLOC;
GST_API
+GstElement* gst_element_factory_create_full (GstElementFactory * factory,
+ const gchar * first, ...) G_GNUC_MALLOC;
+GST_API
+GstElement * gst_element_factory_create_valist (GstElementFactory * factory,
+ const gchar * first, va_list properties) G_GNUC_MALLOC;
+GST_API
+GstElement * gst_element_factory_create_with_properties (GstElementFactory * factory,
+ guint n, const gchar *names[], const GValue values[]) G_GNUC_MALLOC;
+GST_API
GstElement* gst_element_factory_make (const gchar *factoryname, const gchar *name) G_GNUC_MALLOC;
GST_API
+GstElement* gst_element_factory_make_full (const gchar *factoryname,
+ const gchar *first, ...) G_GNUC_MALLOC;
+GST_API
+GstElement* gst_element_factory_make_valist (const gchar *factoryname,
+ const gchar *first, va_list properties) G_GNUC_MALLOC;
+GST_API
+GstElement* gst_element_factory_make_with_properties (const gchar *factoryname,
+ guint n, const gchar *names[], const GValue values[]) G_GNUC_MALLOC;
+GST_API
gboolean gst_element_register (GstPlugin *plugin, const gchar *name,
guint rank, GType type);