mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-10 17:35:59 +00:00
gst/gstpreset.*: Change _get_preset_names API to return a strv with copies. Add _get_property_names to allow implemen...
Original commit message from CVS: * gst/gstpreset.c: * gst/gstpreset.h: Change _get_preset_names API to return a strv with copies. Add _get_property_names to allow implementations to filter and provide good default implementation.
This commit is contained in:
parent
cc4e849e99
commit
51d83b8dfb
3 changed files with 120 additions and 63 deletions
|
@ -1,3 +1,11 @@
|
||||||
|
2007-11-20 Stefan Kost <ensonic@users.sf.net>
|
||||||
|
|
||||||
|
* gst/gstpreset.c:
|
||||||
|
* gst/gstpreset.h:
|
||||||
|
Change _get_preset_names API to return a strv with copies. Add
|
||||||
|
_get_property_names to allow implementations to filter and provide
|
||||||
|
good default implementation.
|
||||||
|
|
||||||
2007-11-20 Julien MOUTTE <julien@moutte.net>
|
2007-11-20 Julien MOUTTE <julien@moutte.net>
|
||||||
|
|
||||||
* docs/faq/gst-uninstalled: Add another library to the uninstalled
|
* docs/faq/gst-uninstalled: Add another library to the uninstalled
|
||||||
|
|
169
gst/gstpreset.c
169
gst/gstpreset.c
|
@ -29,9 +29,15 @@
|
||||||
* All instances of one type will share the list of presets. The list is created
|
* All instances of one type will share the list of presets. The list is created
|
||||||
* on demand, if presets are not used, the list is not created.
|
* on demand, if presets are not used, the list is not created.
|
||||||
*
|
*
|
||||||
|
* The interface comes with a default implementation that servers most plugins.
|
||||||
|
* Wrapper plugins will override most methods to implement support for the
|
||||||
|
* native preset format of those wrapped plugins.
|
||||||
|
* One method that is useful to be overridde is gst_preset_get_property_names().
|
||||||
|
* With that one can control which properties are saved and in which order.
|
||||||
*/
|
*/
|
||||||
/* @todo:
|
/* @todo:
|
||||||
* - we need locks to avoid two instances manipulating the preset list -> flock
|
* - we need locks to avoid two instances manipulating the preset list -> flock
|
||||||
|
* better save the new file to a tempfile and then rename
|
||||||
* - need to add support for GstChildProxy
|
* - need to add support for GstChildProxy
|
||||||
* - how can we support both Preferences and Presets,
|
* - how can we support both Preferences and Presets,
|
||||||
* - preferences = static settings, configurations (non controlable)
|
* - preferences = static settings, configurations (non controlable)
|
||||||
|
@ -68,6 +74,8 @@ static GQuark preset_data_quark = 0;
|
||||||
static GQuark preset_meta_quark = 0;
|
static GQuark preset_meta_quark = 0;
|
||||||
static GQuark instance_list_quark = 0;
|
static GQuark instance_list_quark = 0;
|
||||||
|
|
||||||
|
/*static GQuark property_list_quark = 0;*/
|
||||||
|
|
||||||
/* default iface implementation */
|
/* default iface implementation */
|
||||||
|
|
||||||
/* max character per line */
|
/* max character per line */
|
||||||
|
@ -100,7 +108,7 @@ preset_get_storage (GstPreset * self, GList ** presets,
|
||||||
GST_DEBUG ("new data hash");
|
GST_DEBUG ("new data hash");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GST_INFO ("%ld:%s: presets: %p, %p, %p", type, G_OBJECT_TYPE_NAME (self),
|
GST_INFO ("%s: presets: %p, %p, %p", G_OBJECT_TYPE_NAME (self),
|
||||||
*presets, (preset_meta ? *preset_meta : 0),
|
*presets, (preset_meta ? *preset_meta : 0),
|
||||||
(preset_data ? *preset_data : 0));
|
(preset_data ? *preset_data : 0));
|
||||||
return (res);
|
return (res);
|
||||||
|
@ -162,11 +170,7 @@ preset_get_path (GstPreset * self)
|
||||||
static gboolean
|
static gboolean
|
||||||
preset_skip_property (GParamSpec * property)
|
preset_skip_property (GParamSpec * property)
|
||||||
{
|
{
|
||||||
/* @todo: currently we skip non-controlable parameters and thus only create
|
if (!(property->flags & (G_PARAM_READABLE | G_PARAM_WRITABLE)) ||
|
||||||
* presets, skipping the controlable one would create a config/preference
|
|
||||||
*/
|
|
||||||
if (!(property->flags & GST_PARAM_CONTROLLABLE) ||
|
|
||||||
!(property->flags & G_PARAM_READABLE) ||
|
|
||||||
(property->flags & G_PARAM_CONSTRUCT_ONLY))
|
(property->flags & G_PARAM_CONSTRUCT_ONLY))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -187,7 +191,7 @@ preset_cleanup (gpointer user_data, GObject * self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static GList *
|
static gchar **
|
||||||
gst_preset_default_get_preset_names (GstPreset * self)
|
gst_preset_default_get_preset_names (GstPreset * self)
|
||||||
{
|
{
|
||||||
GType type = G_TYPE_FROM_INSTANCE (self);
|
GType type = G_TYPE_FROM_INSTANCE (self);
|
||||||
|
@ -329,8 +333,48 @@ gst_preset_default_get_preset_names (GstPreset * self)
|
||||||
instances = g_list_prepend (instances, self);
|
instances = g_list_prepend (instances, self);
|
||||||
g_type_set_qdata (type, instance_list_quark, (gpointer) instances);
|
g_type_set_qdata (type, instance_list_quark, (gpointer) instances);
|
||||||
}
|
}
|
||||||
/* @todo: copy strings to avoid races? transform into a strv? */
|
/* copy strings to avoid races */
|
||||||
return (presets);
|
if (presets) {
|
||||||
|
gchar **preset_names = g_new (gchar *, g_list_length (presets) + 1);
|
||||||
|
GList *node;
|
||||||
|
guint i = 0;
|
||||||
|
|
||||||
|
for (node = presets; node; node = g_list_next (node)) {
|
||||||
|
preset_names[i++] = g_strdup (node->data);
|
||||||
|
}
|
||||||
|
preset_names[i] = NULL;
|
||||||
|
return (preset_names);
|
||||||
|
}
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GList *
|
||||||
|
gst_preset_default_get_property_names (GstPreset * self)
|
||||||
|
{
|
||||||
|
GParamSpec **properties, *property;
|
||||||
|
GList *names = NULL;
|
||||||
|
guint i, number_of_properties;
|
||||||
|
|
||||||
|
if ((properties = g_object_class_list_properties (G_OBJECT_CLASS
|
||||||
|
(GST_ELEMENT_GET_CLASS (self)), &number_of_properties))) {
|
||||||
|
for (i = 0; i < number_of_properties; i++) {
|
||||||
|
property = properties[i];
|
||||||
|
if (preset_skip_property (property) ||
|
||||||
|
(property->flags & GST_PARAM_CONTROLLABLE))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
names = g_list_prepend (names, property->name);
|
||||||
|
}
|
||||||
|
for (i = 0; i < number_of_properties; i++) {
|
||||||
|
property = properties[i];
|
||||||
|
if (preset_skip_property (property) ||
|
||||||
|
!(property->flags & GST_PARAM_CONTROLLABLE))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
names = g_list_prepend (names, property->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -345,22 +389,21 @@ gst_preset_default_load_preset (GstPreset * self, const gchar * name)
|
||||||
|
|
||||||
if ((node = g_list_find_custom (presets, name, (GCompareFunc) strcmp))) {
|
if ((node = g_list_find_custom (presets, name, (GCompareFunc) strcmp))) {
|
||||||
GHashTable *data = g_hash_table_lookup (preset_data, node->data);
|
GHashTable *data = g_hash_table_lookup (preset_data, node->data);
|
||||||
GParamSpec **properties, *property;
|
GList *properties;
|
||||||
GType base, parent;
|
GType base, parent;
|
||||||
guint i, number_of_properties;
|
|
||||||
gchar *val = NULL;
|
gchar *val = NULL;
|
||||||
|
|
||||||
GST_DEBUG ("loading preset : '%s', data : %p (size=%d)", name, data,
|
GST_DEBUG ("loading preset : '%s', data : %p (size=%d)", name, data,
|
||||||
g_hash_table_size (data));
|
g_hash_table_size (data));
|
||||||
|
|
||||||
/* preset found, now set values */
|
/* preset found, now set values */
|
||||||
if ((properties =
|
if ((properties = gst_preset_get_property_names (self))) {
|
||||||
g_object_class_list_properties (G_OBJECT_CLASS
|
GParamSpec *property;
|
||||||
(GST_ELEMENT_GET_CLASS (self)), &number_of_properties))) {
|
GList *node;
|
||||||
for (i = 0; i < number_of_properties; i++) {
|
|
||||||
property = properties[i];
|
for (node = properties; node; node = g_list_next (node)) {
|
||||||
if (preset_skip_property (property))
|
property = g_object_class_find_property (G_OBJECT_CLASS
|
||||||
continue;
|
(GST_ELEMENT_GET_CLASS (self)), node->data);
|
||||||
|
|
||||||
/* check if we have a settings for this property */
|
/* check if we have a settings for this property */
|
||||||
if ((val = (gchar *) g_hash_table_lookup (data, property->name))) {
|
if ((val = (gchar *) g_hash_table_lookup (data, property->name))) {
|
||||||
|
@ -404,7 +447,10 @@ gst_preset_default_load_preset (GstPreset * self, const gchar * name)
|
||||||
GST_INFO ("parameter '%s' not in preset", property->name);
|
GST_INFO ("parameter '%s' not in preset", property->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
g_list_free (properties);
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
|
} else {
|
||||||
|
GST_INFO ("no properties");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -516,9 +562,8 @@ gst_preset_default_save_preset (GstPreset * self, const gchar * name)
|
||||||
GList *presets;
|
GList *presets;
|
||||||
GHashTable *preset_meta, *preset_data;
|
GHashTable *preset_meta, *preset_data;
|
||||||
GHashTable *meta, *data;
|
GHashTable *meta, *data;
|
||||||
GParamSpec **properties, *property;
|
GList *properties;
|
||||||
GType base, parent;
|
GType base, parent;
|
||||||
guint i, number_of_properties;
|
|
||||||
gchar *str = NULL, buffer[30 + 1];
|
gchar *str = NULL, buffer[30 + 1];
|
||||||
|
|
||||||
/*guint flags; */
|
/*guint flags; */
|
||||||
|
@ -532,16 +577,13 @@ gst_preset_default_save_preset (GstPreset * self, const gchar * name)
|
||||||
meta = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
|
meta = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
|
||||||
|
|
||||||
/* take copies of current gobject properties from self */
|
/* take copies of current gobject properties from self */
|
||||||
if ((properties =
|
if ((properties = gst_preset_get_property_names (self))) {
|
||||||
g_object_class_list_properties (G_OBJECT_CLASS (GST_ELEMENT_GET_CLASS
|
GParamSpec *property;
|
||||||
(self)), &number_of_properties))) {
|
GList *node;
|
||||||
for (i = 0; i < number_of_properties; i++) {
|
|
||||||
property = properties[i];
|
|
||||||
/*flags=GPOINTER_TO_INT(g_param_spec_get_qdata(property,gst_property_meta_quark_flags)); */
|
|
||||||
|
|
||||||
/* skip non-controlable */
|
for (node = properties; node; node = g_list_next (node)) {
|
||||||
if (preset_skip_property (property))
|
property = g_object_class_find_property (G_OBJECT_CLASS
|
||||||
continue;
|
(GST_ELEMENT_GET_CLASS (self)), node->data);
|
||||||
|
|
||||||
/* get base type */
|
/* get base type */
|
||||||
base = property->value_type;
|
base = property->value_type;
|
||||||
|
@ -611,14 +653,16 @@ gst_preset_default_save_preset (GstPreset * self, const gchar * name)
|
||||||
g_hash_table_insert (data, (gpointer) property->name, (gpointer) str);
|
g_hash_table_insert (data, (gpointer) property->name, (gpointer) str);
|
||||||
str = NULL;
|
str = NULL;
|
||||||
}
|
}
|
||||||
|
g_list_free (properties);
|
||||||
}
|
}
|
||||||
/* @todo: handle childproxy properties as well */
|
/* @todo: handle childproxy properties as well */
|
||||||
GST_INFO (" saved");
|
GST_INFO (" saved");
|
||||||
|
} else {
|
||||||
|
GST_INFO ("no properties");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* flock(fileno())
|
* @todo: flock(fileno())
|
||||||
* http://www.ecst.csuchico.edu/~beej/guide/ipc/flock.html
|
* http://www.ecst.csuchico.edu/~beej/guide/ipc/flock.html
|
||||||
*/
|
*/
|
||||||
g_hash_table_insert (preset_data, (gpointer) name, (gpointer) data);
|
g_hash_table_insert (preset_data, (gpointer) name, (gpointer) data);
|
||||||
|
@ -784,33 +828,17 @@ gst_preset_default_get_meta (GstPreset * self, const gchar * name,
|
||||||
static void
|
static void
|
||||||
gst_preset_default_create_preset (GstPreset * self)
|
gst_preset_default_create_preset (GstPreset * self)
|
||||||
{
|
{
|
||||||
GParamSpec **properties, *property;
|
GList *properties;
|
||||||
guint i, number_of_properties;
|
|
||||||
GType base, parent;
|
GType base, parent;
|
||||||
|
|
||||||
if ((properties =
|
if ((properties = gst_preset_get_property_names (self))) {
|
||||||
g_object_class_list_properties (G_OBJECT_CLASS (GST_OBJECT_GET_CLASS
|
GParamSpec *property;
|
||||||
(self)), &number_of_properties))) {
|
GList *node;
|
||||||
gdouble rnd;
|
gdouble rnd;
|
||||||
|
|
||||||
GST_INFO ("nr of values : %d", number_of_properties);
|
for (node = properties; node; node = g_list_next (node)) {
|
||||||
for (i = 0; i < number_of_properties; i++) {
|
property = g_object_class_find_property (G_OBJECT_CLASS
|
||||||
property = properties[i];
|
(GST_ELEMENT_GET_CLASS (self)), node->data);
|
||||||
|
|
||||||
/* skip non-controlable, and non persistent params */
|
|
||||||
if (preset_skip_property (property))
|
|
||||||
continue;
|
|
||||||
/* we do not want to create a setting for trigger properties, buzztard
|
|
||||||
has more flags attached to g_param_specs
|
|
||||||
else {
|
|
||||||
guint flags=0;
|
|
||||||
|
|
||||||
if(BT_IS_PROPERTY_META(self)) {
|
|
||||||
flags=GPOINTER_TO_INT(g_param_spec_get_qdata(property,bt_property_meta_quark_flags));
|
|
||||||
}
|
|
||||||
if(!(flags&BT_PROPERTY_META_STATE)) continue;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
rnd = ((gdouble) rand ()) / (RAND_MAX + 1.0);
|
rnd = ((gdouble) rand ()) / (RAND_MAX + 1.0);
|
||||||
|
|
||||||
|
@ -871,11 +899,12 @@ gst_preset_default_create_preset (GstPreset * self)
|
||||||
* gst_preset_get_preset_names:
|
* gst_preset_get_preset_names:
|
||||||
* @self: a #GObject that implements #GstPreset
|
* @self: a #GObject that implements #GstPreset
|
||||||
*
|
*
|
||||||
* Get a copy of the preset name list. Free list when done.
|
* Get a copy of preset names as a NULL terminated string array. Free with
|
||||||
|
* g_strfreev() wen done.
|
||||||
*
|
*
|
||||||
* Returns: list with names
|
* Returns: list with names
|
||||||
*/
|
*/
|
||||||
GList *
|
gchar **
|
||||||
gst_preset_get_preset_names (GstPreset * self)
|
gst_preset_get_preset_names (GstPreset * self)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (GST_IS_PRESET (self), NULL);
|
g_return_val_if_fail (GST_IS_PRESET (self), NULL);
|
||||||
|
@ -883,6 +912,22 @@ gst_preset_get_preset_names (GstPreset * self)
|
||||||
return (GST_PRESET_GET_INTERFACE (self)->get_preset_names (self));
|
return (GST_PRESET_GET_INTERFACE (self)->get_preset_names (self));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_preset_get_property_names:
|
||||||
|
* @self: a #GObject that implements #GstPreset
|
||||||
|
*
|
||||||
|
* Get a the gobject property names to use for presets.
|
||||||
|
*
|
||||||
|
* Returns: list with names
|
||||||
|
*/
|
||||||
|
GList *
|
||||||
|
gst_preset_get_property_names (GstPreset * self)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GST_IS_PRESET (self), NULL);
|
||||||
|
|
||||||
|
return (GST_PRESET_GET_INTERFACE (self)->get_property_names (self));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_preset_load_preset:
|
* gst_preset_load_preset:
|
||||||
* @self: a #GObject that implements #GstPreset
|
* @self: a #GObject that implements #GstPreset
|
||||||
|
@ -1031,6 +1076,7 @@ static void
|
||||||
gst_preset_class_init (GstPresetInterface * iface)
|
gst_preset_class_init (GstPresetInterface * iface)
|
||||||
{
|
{
|
||||||
iface->get_preset_names = gst_preset_default_get_preset_names;
|
iface->get_preset_names = gst_preset_default_get_preset_names;
|
||||||
|
iface->get_property_names = gst_preset_default_get_property_names;
|
||||||
|
|
||||||
iface->load_preset = gst_preset_default_load_preset;
|
iface->load_preset = gst_preset_default_load_preset;
|
||||||
iface->save_preset = gst_preset_default_save_preset;
|
iface->save_preset = gst_preset_default_save_preset;
|
||||||
|
@ -1054,11 +1100,12 @@ gst_preset_base_init (gpointer g_class)
|
||||||
GST_DEBUG_FG_WHITE | GST_DEBUG_BG_BLACK, "preset interface");
|
GST_DEBUG_FG_WHITE | GST_DEBUG_BG_BLACK, "preset interface");
|
||||||
|
|
||||||
/* create quarks for use with g_type_{g,s}et_qdata() */
|
/* create quarks for use with g_type_{g,s}et_qdata() */
|
||||||
preset_list_quark = g_quark_from_string ("GstPreset::presets");
|
preset_list_quark = g_quark_from_static_string ("GstPreset::presets");
|
||||||
preset_path_quark = g_quark_from_string ("GstPreset::path");
|
preset_path_quark = g_quark_from_static_string ("GstPreset::path");
|
||||||
preset_data_quark = g_quark_from_string ("GstPreset::data");
|
preset_data_quark = g_quark_from_static_string ("GstPreset::data");
|
||||||
preset_meta_quark = g_quark_from_string ("GstPreset::meta");
|
preset_meta_quark = g_quark_from_static_string ("GstPreset::meta");
|
||||||
instance_list_quark = g_quark_from_string ("GstPreset::instances");
|
instance_list_quark = g_quark_from_static_string ("GstPreset::instances");
|
||||||
|
/*property_list_quark = g_quark_from_static_string ("GstPreset::properties"); */
|
||||||
|
|
||||||
initialized = TRUE;
|
initialized = TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,8 @@ struct _GstPresetInterface
|
||||||
{
|
{
|
||||||
GTypeInterface parent;
|
GTypeInterface parent;
|
||||||
|
|
||||||
GList* (*get_preset_names) (GstPreset *self);
|
gchar** (*get_preset_names) (GstPreset *self);
|
||||||
|
GList* (*get_property_names) (GstPreset * self);
|
||||||
|
|
||||||
gboolean (*load_preset) (GstPreset *self, const gchar *name);
|
gboolean (*load_preset) (GstPreset *self, const gchar *name);
|
||||||
gboolean (*save_preset) (GstPreset *self, const gchar *name);
|
gboolean (*save_preset) (GstPreset *self, const gchar *name);
|
||||||
|
@ -68,7 +69,8 @@ struct _GstPresetInterface
|
||||||
|
|
||||||
GType gst_preset_get_type(void);
|
GType gst_preset_get_type(void);
|
||||||
|
|
||||||
GList* gst_preset_get_preset_names (GstPreset *self);
|
gchar** gst_preset_get_preset_names (GstPreset *self);
|
||||||
|
GList *gst_preset_get_property_names (GstPreset * self);
|
||||||
|
|
||||||
gboolean gst_preset_load_preset (GstPreset *self, const gchar *name);
|
gboolean gst_preset_load_preset (GstPreset *self, const gchar *name);
|
||||||
gboolean gst_preset_save_preset (GstPreset *self, const gchar *name);
|
gboolean gst_preset_save_preset (GstPreset *self, const gchar *name);
|
||||||
|
|
Loading…
Reference in a new issue