From ffbba4406ae907ecb7f791411f4969471104f438 Mon Sep 17 00:00:00 2001 From: Stefan Sauer Date: Fri, 17 Aug 2012 12:23:50 +0200 Subject: [PATCH] preset: implement child_proxy support Elements such as the GstIirEqualizerNBands would so far not store the properties of their children. Now we also grab the properties of child elements and try to restore them. --- gst/gstpreset.c | 153 ++++++++++++++++++++++++++++++++------------------------ 1 file changed, 88 insertions(+), 65 deletions(-) diff --git a/gst/gstpreset.c b/gst/gstpreset.c index fb20fe8..404f34a 100644 --- a/gst/gstpreset.c +++ b/gst/gstpreset.c @@ -55,10 +55,6 @@ * wide * - can we use a lock inside a names shared memory segment? * - * - need to add support for GstChildProxy - * we can do this in a next iteration, the format is flexible enough - * http://www.buzztard.org/index.php/Preset_handling_interface - * * - should there be a 'preset-list' property to get the preset list * (and to connect a notify:: to to listen for changes) * we could use gnome_vfs_monitor_add() to monitor the user preset_file. @@ -66,33 +62,14 @@ * - should there be a 'preset-name' property so that we can set a preset via * gst-launch, or should we handle this with special syntax in gst-launch: * gst-launch element preset: property=value ... - * - this would alloow to hanve preset-bundles too (a preset on bins that + * - this would allow to have preset-bundles too (a preset on bins that * specifies presets for children - * - * - GstChildProxy suport - * - if we stick with GParamSpec **_list_properties() - * we need to use g_param_spec_set_qdata() to specify the instance on each GParamSpec - * OBJECT_LOCK(obj); // ChildProxy needs GstIterator support - * num=gst_child_proxy_get_children_count(obj); - * for(i=0;i 1) { guint64 version; @@ -486,42 +463,66 @@ static gchar ** gst_preset_default_get_property_names (GstPreset * preset) { GParamSpec **props; - guint i, j, n_props; + guint i, j = 0, n_props; GObjectClass *gclass; - gchar **result; + gboolean is_child_proxy; + gchar **result = NULL; gclass = G_OBJECT_CLASS (GST_ELEMENT_GET_CLASS (preset)); + is_child_proxy = GST_IS_CHILD_PROXY (preset); - /* get a list of normal properties. - * FIXME, change this for childproxy support. */ + /* get a list of object properties */ props = g_object_class_list_properties (gclass, &n_props); - if (!props) - goto no_properties; - - /* allocate array big enough to hold the worst case, including a terminating - * NULL pointer. */ - result = g_new (gchar *, n_props + 1); - - /* now filter out the properties that we can use for presets */ - GST_DEBUG_OBJECT (preset, " filtering properties: %u", n_props); - for (i = j = 0; i < n_props; i++) { - if (preset_skip_property (props[i])) - continue; - - /* copy and increment out pointer */ - result[j++] = g_strdup (props[i]->name); + if (props) { + /* allocate array big enough to hold the worst case, including a terminating + * NULL pointer. */ + result = g_new (gchar *, n_props + 1); + + /* now filter out the properties that we can use for presets */ + GST_DEBUG_OBJECT (preset, " filtering properties: %u", n_props); + for (i = 0; i < n_props; i++) { + if (preset_skip_property (props[i])) + continue; + GST_DEBUG_OBJECT (preset, " using: %s", props[i]->name); + result[j++] = g_strdup (props[i]->name); + } + g_free (props); } - result[j] = NULL; - g_free (props); - - return result; - /* ERRORS */ -no_properties: - { + if (is_child_proxy) { + guint c, n_children; + GObject *child; + + n_children = gst_child_proxy_get_children_count ((GstChildProxy *) preset); + for (c = 0; c < n_children; c++) { + child = gst_child_proxy_get_child_by_index ((GstChildProxy *) preset, c); + gclass = G_OBJECT_CLASS (GST_ELEMENT_GET_CLASS (child)); + + props = g_object_class_list_properties (gclass, &n_props); + if (props) { + /* resize property name array */ + result = g_renew (gchar *, result, j + n_props + 1); + + /* now filter out the properties that we can use for presets */ + GST_DEBUG_OBJECT (preset, " filtering properties: %u", n_props); + for (i = 0; i < n_props; i++) { + if (preset_skip_property (props[i])) + continue; + GST_DEBUG_OBJECT (preset, " using: %s::%s", + GST_OBJECT_NAME (child), props[i]->name); + result[j++] = g_strdup_printf ("%s::%s", GST_OBJECT_NAME (child), + props[i]->name); + } + g_free (props); + } + } + } + if (!result) { GST_INFO_OBJECT (preset, "object has no properties"); - return NULL; + } else { + result[j] = NULL; } + return result; } /* load the presets of @name for the instance @preset. Returns %FALSE if something @@ -533,6 +534,7 @@ gst_preset_default_load_preset (GstPreset * preset, const gchar * name) gchar **props; guint i; GObjectClass *gclass; + gboolean is_child_proxy; /* get the presets from the type */ if (!(presets = preset_get_keyfile (preset))) @@ -549,13 +551,14 @@ gst_preset_default_load_preset (GstPreset * preset, const gchar * name) goto no_properties; gclass = G_OBJECT_CLASS (GST_ELEMENT_GET_CLASS (preset)); + is_child_proxy = GST_IS_CHILD_PROXY (preset); /* for each of the property names, find the preset parameter and try to * configure the property with its value */ for (i = 0; props[i]; i++) { gchar *str; GValue gvalue = { 0, }; - GParamSpec *property; + GParamSpec *property = NULL; /* check if we have a settings for this element property */ if (!(str = g_key_file_get_value (presets, name, props[i], NULL))) { @@ -567,8 +570,13 @@ gst_preset_default_load_preset (GstPreset * preset, const gchar * name) GST_DEBUG_OBJECT (preset, "setting value '%s' for property '%s'", str, props[i]); - /* FIXME, change for childproxy to get the property and element. */ - if (!(property = g_object_class_find_property (gclass, props[i]))) { + if (is_child_proxy) { + gst_child_proxy_lookup ((GstChildProxy *) preset, props[i], NULL, + &property); + } else { + property = g_object_class_find_property (gclass, props[i]); + } + if (!property) { /* the parameter was in the keyfile, the element said it supported it but * then the property was not found in the element. This should not happen. */ GST_WARNING_OBJECT (preset, "property '%s' not in object", props[i]); @@ -580,8 +588,12 @@ gst_preset_default_load_preset (GstPreset * preset, const gchar * name) * the object property */ g_value_init (&gvalue, property->value_type); if (gst_value_deserialize (&gvalue, str)) { - /* FIXME, change for childproxy support */ - g_object_set_property (G_OBJECT (preset), props[i], &gvalue); + if (is_child_proxy) { + gst_child_proxy_set_property ((GstChildProxy *) preset, props[i], + &gvalue); + } else { + g_object_set_property ((GObject *) preset, props[i], &gvalue); + } } else { GST_WARNING_OBJECT (preset, "deserialization of value '%s' for property '%s' failed", str, @@ -701,6 +713,7 @@ gst_preset_default_save_preset (GstPreset * preset, const gchar * name) gchar **props; guint i; GObjectClass *gclass; + gboolean is_child_proxy; GST_INFO_OBJECT (preset, "saving new preset: %s", name); @@ -713,16 +726,22 @@ gst_preset_default_save_preset (GstPreset * preset, const gchar * name) goto no_properties; gclass = G_OBJECT_CLASS (GST_ELEMENT_GET_CLASS (preset)); + is_child_proxy = GST_IS_CHILD_PROXY (preset); /* loop over the object properties and store the property value in the * keyfile */ for (i = 0; props[i]; i++) { GValue gvalue = { 0, }; gchar *str; - GParamSpec *property; + GParamSpec *property = NULL; - /* FIXME, change for childproxy to get the property and element. */ - if (!(property = g_object_class_find_property (gclass, props[i]))) { + if (is_child_proxy) { + gst_child_proxy_lookup ((GstChildProxy *) preset, props[i], NULL, + &property); + } else { + property = g_object_class_find_property (gclass, props[i]); + } + if (!property) { /* the element said it supported the property but then it does not have * that property. This should not happen. */ GST_WARNING_OBJECT (preset, "property '%s' not in object", props[i]); @@ -730,8 +749,12 @@ gst_preset_default_save_preset (GstPreset * preset, const gchar * name) } g_value_init (&gvalue, property->value_type); - /* FIXME, change for childproxy */ - g_object_get_property (G_OBJECT (preset), props[i], &gvalue); + if (is_child_proxy) { + gst_child_proxy_get_property ((GstChildProxy *) preset, props[i], + &gvalue); + } else { + g_object_get_property ((GObject *) preset, props[i], &gvalue); + } if ((str = gst_value_serialize (&gvalue))) { g_key_file_set_string (presets, name, props[i], (gpointer) str); -- 2.7.4