mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-09-30 07:42:32 +00:00
elementfactory: enable construct only property passing
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/736>
This commit is contained in:
parent
a4a1782872
commit
aadf84837b
2 changed files with 336 additions and 33 deletions
|
@ -65,6 +65,8 @@
|
||||||
|
|
||||||
#include "glib-compat-private.h"
|
#include "glib-compat-private.h"
|
||||||
|
|
||||||
|
#include <gobject/gvaluecollector.h>
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_STATIC (element_factory_debug);
|
GST_DEBUG_CATEGORY_STATIC (element_factory_debug);
|
||||||
#define GST_CAT_DEFAULT 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
|
* @factory: factory to instantiate
|
||||||
* @name: (allow-none): name of new element, or %NULL to automatically create
|
* @n: count of properties
|
||||||
* a unique name
|
* @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.
|
* 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
|
* The supplied list of properties, will be passed at object construction.
|
||||||
* their first argument.
|
|
||||||
*
|
*
|
||||||
* Returns: (transfer floating) (nullable): new #GstElement or %NULL
|
* Returns: (transfer floating) (nullable): new #GstElement or %NULL
|
||||||
* if the element couldn't be created
|
* if the element couldn't be created
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
*/
|
*/
|
||||||
GstElement *
|
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;
|
GstElement *element;
|
||||||
GstElementClass *oclass;
|
GstElementClass *oclass;
|
||||||
|
@ -356,22 +431,14 @@ gst_element_factory_create (GstElementFactory * factory, const gchar * name)
|
||||||
|
|
||||||
factory = newfactory;
|
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)
|
if (factory->type == 0)
|
||||||
goto no_type;
|
goto no_type;
|
||||||
|
|
||||||
/* create an instance of the element, cast so we don't assert on NULL
|
element = (GstElement *) g_object_new_with_properties (factory->type, n,
|
||||||
* also set name as early as we can
|
names, values);
|
||||||
*/
|
|
||||||
if (name)
|
|
||||||
element = g_object_new (factory->type, "name", name, NULL);
|
|
||||||
else
|
|
||||||
element = g_object_new (factory->type, NULL);
|
|
||||||
if (G_UNLIKELY (element == NULL))
|
if (G_UNLIKELY (element == NULL))
|
||||||
goto no_element;
|
goto no_element;
|
||||||
|
|
||||||
|
@ -404,8 +471,7 @@ gst_element_factory_create (GstElementFactory * factory, const gchar * name)
|
||||||
/* ERRORS */
|
/* ERRORS */
|
||||||
load_failed:
|
load_failed:
|
||||||
{
|
{
|
||||||
GST_WARNING_OBJECT (factory,
|
GST_WARNING_OBJECT (factory, "loading plugin returned NULL!");
|
||||||
"loading plugin containing feature %s returned NULL!", name);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
no_type:
|
no_type:
|
||||||
|
@ -423,21 +489,134 @@ no_element:
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_element_factory_make:
|
* gst_element_factory_create_valist:
|
||||||
* @factoryname: a named factory to instantiate
|
* @factory: factory to instantiate
|
||||||
* @name: (allow-none): name of new element, or %NULL to automatically create
|
* @first: (nullable): name of the first property
|
||||||
* a unique name
|
* @properties: (nullable): list of properties
|
||||||
*
|
*
|
||||||
* Create a new element of the type defined by the given element factory.
|
* Create a new element of the type defined by the given elementfactory.
|
||||||
* If name is %NULL, then the element will receive a guaranteed unique name,
|
* The supplied list of properties, will be passed at object construction.
|
||||||
* 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
|
* Returns: (transfer floating) (nullable): new #GstElement or %NULL
|
||||||
* if unable to create element
|
* if the element couldn't be created
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
*/
|
*/
|
||||||
GstElement *
|
GstElement *
|
||||||
gst_element_factory_make (const gchar * factoryname, const gchar * name)
|
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;
|
GstElementFactory *factory;
|
||||||
GstElement *element;
|
GstElement *element;
|
||||||
|
@ -445,15 +624,15 @@ gst_element_factory_make (const gchar * factoryname, const gchar * name)
|
||||||
g_return_val_if_fail (factoryname != NULL, NULL);
|
g_return_val_if_fail (factoryname != NULL, NULL);
|
||||||
g_return_val_if_fail (gst_is_initialized (), NULL);
|
g_return_val_if_fail (gst_is_initialized (), NULL);
|
||||||
|
|
||||||
GST_LOG ("gstelementfactory: make \"%s\" \"%s\"",
|
GST_LOG ("gstelementfactory: make \"%s\"", factoryname);
|
||||||
factoryname, GST_STR_NULL (name));
|
|
||||||
|
|
||||||
factory = gst_element_factory_find (factoryname);
|
factory = gst_element_factory_find (factoryname);
|
||||||
if (factory == NULL)
|
if (factory == NULL)
|
||||||
goto no_factory;
|
goto no_factory;
|
||||||
|
|
||||||
GST_LOG_OBJECT (factory, "found factory %p", factory);
|
GST_LOG_OBJECT (factory, "found factory %p", factory);
|
||||||
element = gst_element_factory_create (factory, name);
|
element = gst_element_factory_create_with_properties (factory, n, names,
|
||||||
|
values);
|
||||||
if (element == NULL)
|
if (element == NULL)
|
||||||
goto create_failed;
|
goto create_failed;
|
||||||
|
|
||||||
|
@ -475,6 +654,112 @@ create_failed:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
* 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_valist (const gchar * factoryname,
|
||||||
|
const gchar * first, va_list properties)
|
||||||
|
{
|
||||||
|
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_valist (factory, first, properties);
|
||||||
|
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_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
|
void
|
||||||
__gst_element_factory_add_static_pad_template (GstElementFactory * factory,
|
__gst_element_factory_add_static_pad_template (GstElementFactory * factory,
|
||||||
GstStaticPadTemplate * templ)
|
GstStaticPadTemplate * templ)
|
||||||
|
|
|
@ -84,8 +84,26 @@ GST_API
|
||||||
GstElement* gst_element_factory_create (GstElementFactory *factory,
|
GstElement* gst_element_factory_create (GstElementFactory *factory,
|
||||||
const gchar *name) G_GNUC_MALLOC;
|
const gchar *name) G_GNUC_MALLOC;
|
||||||
GST_API
|
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;
|
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
|
GST_API
|
||||||
gboolean gst_element_register (GstPlugin *plugin, const gchar *name,
|
gboolean gst_element_register (GstPlugin *plugin, const gchar *name,
|
||||||
guint rank, GType type);
|
guint rank, GType type);
|
||||||
|
|
Loading…
Reference in a new issue