summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVivia Nikolaidou <vivia@toolsonair.com>2017-02-23 20:16:17 +0200
committerSebastian Dröge <sebastian@centricular.com>2017-02-23 20:16:17 +0200
commit978df5d0ffb5006da9ae28ca875b0d8a725fd925 (patch)
treee1307d8d5edc5635c10b33458042ec74a5287ed9
parent834fd18dfaa79c99cac460f9597b3bb5f7e240d9 (diff)
paramspecs: Add GstParamSpecArray for GST_TYPE_ARRAY typed properties
These are mostly useful to get our automatic serialization/deserialization from strings and simple usage from gst-launch or similar. https://bugzilla.gnome.org/show_bug.cgi?id=777375
-rw-r--r--gst/gstparamspecs.c155
-rw-r--r--gst/gstparamspecs.h28
-rw-r--r--win32/common/libgstreamer.def2
3 files changed, 185 insertions, 0 deletions
diff --git a/gst/gstparamspecs.c b/gst/gstparamspecs.c
index 14ae79659..8fad46feb 100644
--- a/gst/gstparamspecs.c
+++ b/gst/gstparamspecs.c
@@ -202,3 +202,158 @@ gst_param_spec_fraction (const gchar * name, const gchar * nick,
return pspec;
}
+
+static void
+_gst_param_array_init (GParamSpec * pspec)
+{
+ GstParamSpecArray *aspec = GST_PARAM_SPEC_ARRAY_LIST (pspec);
+
+ aspec->element_spec = NULL;
+}
+
+static void
+_gst_param_array_finalize (GParamSpec * pspec)
+{
+ GstParamSpecArray *aspec = GST_PARAM_SPEC_ARRAY_LIST (pspec);
+ GParamSpecClass *parent_class =
+ g_type_class_peek (g_type_parent (GST_TYPE_PARAM_ARRAY_LIST));
+
+ if (aspec->element_spec) {
+ g_param_spec_unref (aspec->element_spec);
+ aspec->element_spec = NULL;
+ }
+
+ parent_class->finalize (pspec);
+}
+
+static gboolean
+_gst_param_array_validate (GParamSpec * pspec, GValue * value)
+{
+ GstParamSpecArray *aspec = GST_PARAM_SPEC_ARRAY_LIST (pspec);
+
+ /* ensure array values validity against a present element spec */
+ if (aspec->element_spec) {
+ GParamSpec *element_spec = aspec->element_spec;
+ guint i;
+
+ for (i = 0; i < gst_value_array_get_size (value); i++) {
+ GValue *element = (GValue *) gst_value_array_get_value (value, i);
+
+ /* need to fixup value type, or ensure that the array value is initialized at all */
+ if (!g_value_type_compatible (G_VALUE_TYPE (element),
+ G_PARAM_SPEC_VALUE_TYPE (element_spec))) {
+ if (G_VALUE_TYPE (element) != 0)
+ g_value_unset (element);
+ g_value_init (element, G_PARAM_SPEC_VALUE_TYPE (element_spec));
+ g_param_value_set_default (element_spec, element);
+ return FALSE;
+ }
+ /* validate array value against element_spec */
+ if (!g_param_value_validate (element_spec, element))
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+static gint
+_gst_param_array_values_cmp (GParamSpec * pspec, const GValue * value1,
+ const GValue * value2)
+{
+ GstParamSpecArray *aspec = GST_PARAM_SPEC_ARRAY_LIST (pspec);
+ guint size1, size2;
+
+ if (!value1 || !value2)
+ return value2 ? -1 : value1 != value2;
+
+ size1 = gst_value_array_get_size (value1);
+ size2 = gst_value_array_get_size (value2);
+
+ if (size1 != size2)
+ return size1 < size2 ? -1 : 1;
+ else if (!aspec->element_spec) {
+ /* we need an element specification for comparisons, so there's not much
+ * to compare here, try to at least provide stable lesser/greater result
+ */
+ return size1 < size2 ? -1 : size1 > size2;
+ } else { /* size1 == size2 */
+ guint i;
+
+ for (i = 0; i < size1; i++) {
+ const GValue *element1 = gst_value_array_get_value (value1, i);
+ const GValue *element2 = gst_value_array_get_value (value2, i);
+ gint cmp;
+
+ /* need corresponding element types, provide stable result otherwise */
+ if (G_VALUE_TYPE (element1) != G_VALUE_TYPE (element2))
+ return G_VALUE_TYPE (element1) < G_VALUE_TYPE (element2) ? -1 : 1;
+ cmp = g_param_values_cmp (aspec->element_spec, element1, element2);
+ if (cmp)
+ return cmp;
+ }
+ return 0;
+ }
+}
+
+GType
+gst_param_spec_array_get_type (void)
+{
+ static GType type; /* 0 */
+
+ /* register GST_TYPE_PARAM_FRACTION */
+ if (type == 0) {
+ static GParamSpecTypeInfo pspec_info = {
+ sizeof (GstParamSpecArray), /* instance_size */
+ 0, /* n_preallocs */
+ _gst_param_array_init, /* instance_init */
+ G_TYPE_INVALID, /* value_type */
+ _gst_param_array_finalize, /* finalize */
+ NULL, /* value_set_default */
+ _gst_param_array_validate, /* value_validate */
+ _gst_param_array_values_cmp, /* values_cmp */
+ };
+ pspec_info.value_type = GST_TYPE_ARRAY;
+ type = g_param_type_register_static ("GstParamArray", &pspec_info);
+ }
+ return type;
+}
+
+/**
+ * gst_param_spec_array:
+ * @name: canonical name of the property specified
+ * @nick: nick name for the property specified
+ * @blurb: description of the property specified
+ * @element_spec: GParamSpec of the array
+ * @flags: flags for the property specified
+ *
+ * This function creates a GstArray GParamSpec for use by objects/elements
+ * that want to expose properties of GstArray type. This function is
+ * typically * used in connection with g_object_class_install_property() in a
+ * GObjects's instance_init function.
+ *
+ * Returns: (transfer full): a newly created parameter specification
+ */
+
+GParamSpec *
+gst_param_spec_array (const gchar * name,
+ const gchar * nick,
+ const gchar * blurb, GParamSpec * element_spec, GParamFlags flags)
+{
+ GstParamSpecArray *aspec;
+
+ if (element_spec)
+ g_return_val_if_fail (G_IS_PARAM_SPEC (element_spec), NULL);
+
+ aspec = g_param_spec_internal (GST_TYPE_PARAM_ARRAY_LIST,
+ name, nick, blurb, flags);
+ if (aspec == NULL)
+ return NULL;
+
+ if (element_spec) {
+ aspec->element_spec = g_param_spec_ref (element_spec);
+ g_param_spec_sink (element_spec);
+ }
+
+ return G_PARAM_SPEC (aspec);
+}
diff --git a/gst/gstparamspecs.h b/gst/gstparamspecs.h
index 64377dc29..8a326c066 100644
--- a/gst/gstparamspecs.h
+++ b/gst/gstparamspecs.h
@@ -75,14 +75,22 @@ G_BEGIN_DECLS
#define GST_PARAM_SPEC_FRACTION(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), GST_TYPE_PARAM_FRACTION, GstParamSpecFraction))
+#define GST_TYPE_PARAM_ARRAY_LIST (gst_param_spec_array_get_type ())
+#define GST_IS_PARAM_SPEC_ARRAY_LIST(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), GST_TYPE_PARAM_ARRAY_LIST))
+#define GST_PARAM_SPEC_ARRAY_LIST(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), GST_TYPE_PARAM_ARRAY_LIST, GstParamSpecArray))
+
+
/* --- get_type functions --- */
GType gst_param_spec_fraction_get_type (void);
+GType gst_param_spec_array_get_type (void);
+
/* --- typedefs & structures --- */
typedef struct _GstParamSpecFraction GstParamSpecFraction;
+typedef struct _GstParamSpecArray GstParamSpecArray;
/**
* GstParamSpecFraction:
@@ -105,6 +113,20 @@ struct _GstParamSpecFraction {
gint def_num, def_den;
};
+/**
+ * GstParamSpecArray:
+ * @parent_instance: super class
+ * @value_array: the array of values
+ *
+ * A GParamSpec derived structure that contains the meta data for fractional
+ * properties.
+ */
+struct _GstParamSpecArray {
+ GParamSpec parent_instance;
+
+ GParamSpec * element_spec;
+};
+
/* --- GParamSpec prototypes --- */
@@ -116,6 +138,12 @@ GParamSpec * gst_param_spec_fraction (const gchar * name,
gint default_num, gint default_denom,
GParamFlags flags) G_GNUC_MALLOC;
+GParamSpec * gst_param_spec_array (const gchar * name,
+ const gchar * nick,
+ const gchar * blurb,
+ GParamSpec * element_spec,
+ GParamFlags flags) G_GNUC_MALLOC;
+
G_END_DECLS
#endif /* __GST_PARAMSPECS_H__ */
diff --git a/win32/common/libgstreamer.def b/win32/common/libgstreamer.def
index 1f0fe3ff3..0e41531f3 100644
--- a/win32/common/libgstreamer.def
+++ b/win32/common/libgstreamer.def
@@ -966,6 +966,8 @@ EXPORTS
gst_pad_template_pad_created
gst_pad_unlink
gst_pad_use_fixed_caps
+ gst_param_spec_array
+ gst_param_spec_array_get_type
gst_param_spec_fraction
gst_param_spec_fraction_get_type
gst_parent_buffer_meta_api_get_type