mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-27 09:38:17 +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 <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,134 @@ no_element:
|
|||
}
|
||||
|
||||
/**
|
||||
* gst_element_factory_make:
|
||||
* @factoryname: a named factory to instantiate
|
||||
* @name: (allow-none): name of new element, or %NULL to automatically create
|
||||
* a unique name
|
||||
* 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 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.
|
||||
* 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 unable to create element
|
||||
* if the element couldn't be created
|
||||
*
|
||||
* Since: 1.20
|
||||
*/
|
||||
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;
|
||||
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 (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_with_properties (factory, n, names,
|
||||
values);
|
||||
if (element == NULL)
|
||||
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
|
||||
__gst_element_factory_add_static_pad_template (GstElementFactory * factory,
|
||||
GstStaticPadTemplate * templ)
|
||||
|
|
|
@ -84,8 +84,26 @@ 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);
|
||||
|
|
Loading…
Reference in a new issue