diff options
-rw-r--r-- | gst/gststructure.c | 73 | ||||
-rw-r--r-- | gst/gstvalue.c | 726 | ||||
-rw-r--r-- | gst/gstvalue.h | 13 | ||||
-rw-r--r-- | win32/common/libgstreamer.def | 6 |
4 files changed, 673 insertions, 145 deletions
diff --git a/gst/gststructure.c b/gst/gststructure.c index a484c0d3ac..531009222f 100644 --- a/gst/gststructure.c +++ b/gst/gststructure.c @@ -1900,8 +1900,9 @@ gst_structure_parse_range (gchar * s, gchar ** after, GValue * value, { GValue value1 = { 0 }; GValue value2 = { 0 }; + GValue value3 = { 0 }; GType range_type; - gboolean ret; + gboolean ret, have_step = FALSE; if (*s != '[') return FALSE; @@ -1928,12 +1929,34 @@ gst_structure_parse_range (gchar * s, gchar ** after, GValue * value, while (g_ascii_isspace (*s)) s++; + /* optional step for int and int64 */ + if (G_VALUE_TYPE (&value1) == G_TYPE_INT + || G_VALUE_TYPE (&value1) == G_TYPE_INT64) { + if (*s == ',') { + s++; + + while (g_ascii_isspace (*s)) + s++; + + ret = gst_structure_parse_value (s, &s, &value3, type); + if (ret == FALSE) + return FALSE; + + while (g_ascii_isspace (*s)) + s++; + + have_step = TRUE; + } + } + if (*s != ']') return FALSE; s++; if (G_VALUE_TYPE (&value1) != G_VALUE_TYPE (&value2)) return FALSE; + if (have_step && G_VALUE_TYPE (&value1) != G_VALUE_TYPE (&value3)) + return FALSE; if (G_VALUE_TYPE (&value1) == G_TYPE_DOUBLE) { range_type = GST_TYPE_DOUBLE_RANGE; @@ -1944,13 +1967,26 @@ gst_structure_parse_range (gchar * s, gchar ** after, GValue * value, } else if (G_VALUE_TYPE (&value1) == G_TYPE_INT) { range_type = GST_TYPE_INT_RANGE; g_value_init (value, range_type); - gst_value_set_int_range (value, gst_g_value_get_int_unchecked (&value1), - gst_g_value_get_int_unchecked (&value2)); + if (have_step) + gst_value_set_int_range_step (value, + gst_g_value_get_int_unchecked (&value1), + gst_g_value_get_int_unchecked (&value2), + gst_g_value_get_int_unchecked (&value3)); + else + gst_value_set_int_range (value, gst_g_value_get_int_unchecked (&value1), + gst_g_value_get_int_unchecked (&value2)); } else if (G_VALUE_TYPE (&value1) == G_TYPE_INT64) { range_type = GST_TYPE_INT64_RANGE; g_value_init (value, range_type); - gst_value_set_int64_range (value, gst_g_value_get_int64_unchecked (&value1), - gst_g_value_get_int64_unchecked (&value2)); + if (have_step) + gst_value_set_int64_range_step (value, + gst_g_value_get_int64_unchecked (&value1), + gst_g_value_get_int64_unchecked (&value2), + gst_g_value_get_int64_unchecked (&value3)); + else + gst_value_set_int64_range (value, + gst_g_value_get_int64_unchecked (&value1), + gst_g_value_get_int64_unchecked (&value2)); } else if (G_VALUE_TYPE (&value1) == GST_TYPE_FRACTION) { range_type = GST_TYPE_FRACTION_RANGE; g_value_init (value, range_type); @@ -3132,32 +3168,7 @@ gst_caps_structure_is_subset_field (GQuark field_id, const GValue * value, if (comparison != GST_VALUE_UNORDERED) return FALSE; - /* - * 1 - [1,2] = empty - * -> !subset - * - * [1,2] - 1 = 2 - * -> 1 - [1,2] = empty - * -> subset - * - * [1,3] - [1,2] = 3 - * -> [1,2] - [1,3] = empty - * -> subset - * - * {1,2} - {1,3} = 2 - * -> {1,3} - {1,2} = 3 - * -> !subset - * - * First caps subtraction needs to return a non-empty set, second - * subtractions needs to give en empty set. - * Both substractions are switched below, as it's faster that way. - */ - if (!gst_value_subtract (NULL, value, other)) { - if (gst_value_subtract (NULL, other, value)) { - return TRUE; - } - } - return FALSE; + return gst_value_is_subset (value, other); } /** diff --git a/gst/gstvalue.c b/gst/gstvalue.c index ef99e922dd..75a53624be 100644 --- a/gst/gstvalue.c +++ b/gst/gstvalue.c @@ -778,26 +778,56 @@ gst_value_deserialize_array (GValue * dest, const gchar * s) /************* * int range * + * + * Values in the range are defined as any value greater or equal + * to min*step, AND lesser or equal to max*step. + * For step == 1, this falls back to the traditional range semantics. *************/ +#define INT_RANGE_MIN(v) (((gint *)((v)->data[0].v_pointer))[0]) +#define INT_RANGE_MAX(v) (((gint *)((v)->data[0].v_pointer))[1]) +#define INT_RANGE_STEP(v) (((gint *)((v)->data[0].v_pointer))[2]) + static void gst_value_init_int_range (GValue * value) { - value->data[0].v_int = 0; - value->data[1].v_int = 0; + gint *vals = g_slice_alloc0 (3 * sizeof (gint)); + value->data[0].v_pointer = vals; + INT_RANGE_MIN (value) = 0; + INT_RANGE_MAX (value) = 0; + INT_RANGE_STEP (value) = 1; +} + +static void +gst_value_free_int_range (GValue * value) +{ + g_return_if_fail (GST_VALUE_HOLDS_INT_RANGE (value)); + g_slice_free1 (3 * sizeof (gint), value->data[0].v_pointer); + value->data[0].v_pointer = NULL; } static void gst_value_copy_int_range (const GValue * src_value, GValue * dest_value) { - dest_value->data[0].v_int = src_value->data[0].v_int; - dest_value->data[1].v_int = src_value->data[1].v_int; + gint *vals = (gint *) dest_value->data[0].v_pointer; + gint *src_vals = (gint *) src_value->data[0].v_pointer; + + if (vals == NULL) { + gst_value_init_int_range (dest_value); + } + if (src_vals != NULL) { + INT_RANGE_MIN (dest_value) = INT_RANGE_MIN (src_value); + INT_RANGE_MAX (dest_value) = INT_RANGE_MAX (src_value); + INT_RANGE_STEP (dest_value) = INT_RANGE_STEP (src_value); + } } static gchar * gst_value_collect_int_range (GValue * value, guint n_collect_values, GTypeCValue * collect_values, guint collect_flags) { + gint *vals = value->data[0].v_pointer; + if (n_collect_values != 2) return g_strdup_printf ("not enough value locations for `%s' passed", G_VALUE_TYPE_NAME (value)); @@ -805,8 +835,12 @@ gst_value_collect_int_range (GValue * value, guint n_collect_values, return g_strdup_printf ("range start is not smaller than end for `%s'", G_VALUE_TYPE_NAME (value)); - value->data[0].v_int = collect_values[0].v_int; - value->data[1].v_int = collect_values[1].v_int; + if (vals == NULL) { + gst_value_init_int_range (value); + } + + gst_value_set_int_range_step (value, collect_values[0].v_int, + collect_values[1].v_int, 1); return NULL; } @@ -817,6 +851,8 @@ gst_value_lcopy_int_range (const GValue * value, guint n_collect_values, { guint32 *int_range_start = collect_values[0].v_pointer; guint32 *int_range_end = collect_values[1].v_pointer; + guint32 *int_range_step = collect_values[2].v_pointer; + gint *vals = (gint *) value->data[0].v_pointer; if (!int_range_start) return g_strdup_printf ("start value location for `%s' passed as NULL", @@ -824,29 +860,57 @@ gst_value_lcopy_int_range (const GValue * value, guint n_collect_values, if (!int_range_end) return g_strdup_printf ("end value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value)); + if (!int_range_step) + return g_strdup_printf ("step value location for `%s' passed as NULL", + G_VALUE_TYPE_NAME (value)); + + if (G_UNLIKELY (vals == NULL)) { + return g_strdup_printf ("Uninitialised `%s' passed", + G_VALUE_TYPE_NAME (value)); + } - *int_range_start = value->data[0].v_int; - *int_range_end = value->data[1].v_int; + *int_range_start = INT_RANGE_MIN (value); + *int_range_end = INT_RANGE_MAX (value); + *int_range_step = INT_RANGE_STEP (value); return NULL; } /** - * gst_value_set_int_range: + * gst_value_set_int_range_step: * @value: a GValue initialized to GST_TYPE_INT_RANGE * @start: the start of the range * @end: the end of the range + * @step: the step of the range * - * Sets @value to the range specified by @start and @end. + * Sets @value to the range specified by @start, @end and @step. */ void -gst_value_set_int_range (GValue * value, gint start, gint end) +gst_value_set_int_range_step (GValue * value, gint start, gint end, gint step) { g_return_if_fail (GST_VALUE_HOLDS_INT_RANGE (value)); g_return_if_fail (start < end); + g_return_if_fail (step > 0); + g_return_if_fail (start % step == 0); + g_return_if_fail (end % step == 0); + + INT_RANGE_MIN (value) = start / step; + INT_RANGE_MAX (value) = end / step; + INT_RANGE_STEP (value) = step; +} - value->data[0].v_int = start; - value->data[1].v_int = end; +/** + * gst_value_set_int_range: + * @value: a GValue initialized to GST_TYPE_INT_RANGE + * @start: the start of the range + * @end: the end of the range + * + * Sets @value to the range specified by @start and @end. + */ +void +gst_value_set_int_range (GValue * value, gint start, gint end) +{ + gst_value_set_int_range_step (value, start, end, 1); } /** @@ -862,7 +926,7 @@ gst_value_get_int_range_min (const GValue * value) { g_return_val_if_fail (GST_VALUE_HOLDS_INT_RANGE (value), 0); - return value->data[0].v_int; + return INT_RANGE_MIN (value) * INT_RANGE_STEP (value); } /** @@ -878,31 +942,81 @@ gst_value_get_int_range_max (const GValue * value) { g_return_val_if_fail (GST_VALUE_HOLDS_INT_RANGE (value), 0); - return value->data[1].v_int; + return INT_RANGE_MAX (value) * INT_RANGE_STEP (value); +} + +/** + * gst_value_get_int_range_step: + * @value: a GValue initialized to GST_TYPE_INT_RANGE + * + * Gets the step of the range specified by @value. + * + * Returns: the step of the range + */ +gint +gst_value_get_int_range_step (const GValue * value) +{ + g_return_val_if_fail (GST_VALUE_HOLDS_INT_RANGE (value), 0); + + return INT_RANGE_STEP (value); } static void gst_value_transform_int_range_string (const GValue * src_value, GValue * dest_value) { - dest_value->data[0].v_pointer = g_strdup_printf ("[%d,%d]", - (int) src_value->data[0].v_int, (int) src_value->data[1].v_int); + if (INT_RANGE_STEP (src_value) == 1) + dest_value->data[0].v_pointer = g_strdup_printf ("[%d,%d]", + INT_RANGE_MIN (src_value), INT_RANGE_MAX (src_value)); + else + dest_value->data[0].v_pointer = g_strdup_printf ("[%d,%d,%d]", + INT_RANGE_MIN (src_value) * INT_RANGE_STEP (src_value), + INT_RANGE_MAX (src_value) * INT_RANGE_STEP (src_value), + INT_RANGE_STEP (src_value)); } static gint gst_value_compare_int_range (const GValue * value1, const GValue * value2) { - if (value2->data[0].v_int == value1->data[0].v_int && - value2->data[1].v_int == value1->data[1].v_int) + /* calculate the number of values in each range */ + gint n1 = INT_RANGE_MAX (value1) - INT_RANGE_MIN (value1) + 1; + gint n2 = INT_RANGE_MAX (value2) - INT_RANGE_MIN (value2) + 1; + + /* they must be equal */ + if (n1 != n2) + return GST_VALUE_UNORDERED; + + /* if empty, equal */ + if (n1 == 0) return GST_VALUE_EQUAL; - return GST_VALUE_UNORDERED; + + /* if more than one value, then it is only equal if the step is equal + and bounds lie on the same value */ + if (n1 > 1) { + if (INT_RANGE_STEP (value1) == INT_RANGE_STEP (value2) && + INT_RANGE_STEP (value1) == INT_RANGE_STEP (value2) && + INT_RANGE_STEP (value1) == INT_RANGE_STEP (value2)) { + return GST_VALUE_EQUAL; + } + return GST_VALUE_UNORDERED; + } else { + /* if just one, only if the value is equal */ + if (INT_RANGE_MIN (value1) == INT_RANGE_MIN (value2)) + return GST_VALUE_EQUAL; + return GST_VALUE_UNORDERED; + } } static gchar * gst_value_serialize_int_range (const GValue * value) { - return g_strdup_printf ("[ %d, %d ]", value->data[0].v_int, - value->data[1].v_int); + if (INT_RANGE_STEP (value) == 1) + return g_strdup_printf ("[ %d, %d ]", INT_RANGE_MIN (value), + INT_RANGE_MAX (value)); + else + return g_strdup_printf ("[ %d, %d, %d ]", + INT_RANGE_MIN (value) * INT_RANGE_STEP (value), + INT_RANGE_MAX (value) * INT_RANGE_STEP (value), INT_RANGE_STEP (value)); } static gboolean @@ -914,26 +1028,57 @@ gst_value_deserialize_int_range (GValue * dest, const gchar * s) /*************** * int64 range * + * + * Values in the range are defined as any value greater or equal + * to min*step, AND lesser or equal to max*step. + * For step == 1, this falls back to the traditional range semantics. ***************/ +#define INT64_RANGE_MIN(v) (((gint64 *)((v)->data[0].v_pointer))[0]) +#define INT64_RANGE_MAX(v) (((gint64 *)((v)->data[0].v_pointer))[1]) +#define INT64_RANGE_STEP(v) (((gint64 *)((v)->data[0].v_pointer))[2]) + static void gst_value_init_int64_range (GValue * value) { - value->data[0].v_int64 = 0; - value->data[1].v_int64 = 0; + gint64 *vals = g_slice_alloc0 (3 * sizeof (gint64)); + value->data[0].v_pointer = vals; + INT64_RANGE_MIN (value) = 0; + INT64_RANGE_MAX (value) = 0; + INT64_RANGE_STEP (value) = 1; +} + +static void +gst_value_free_int64_range (GValue * value) +{ + g_return_if_fail (GST_VALUE_HOLDS_INT64_RANGE (value)); + g_slice_free1 (3 * sizeof (gint64), value->data[0].v_pointer); + value->data[0].v_pointer = NULL; } static void gst_value_copy_int64_range (const GValue * src_value, GValue * dest_value) { - dest_value->data[0].v_int64 = src_value->data[0].v_int64; - dest_value->data[1].v_int64 = src_value->data[1].v_int64; + gint64 *vals = (gint64 *) dest_value->data[0].v_pointer; + gint64 *src_vals = (gint64 *) src_value->data[0].v_pointer; + + if (vals == NULL) { + gst_value_init_int64_range (dest_value); + vals = (gint64 *) dest_value->data[0].v_pointer; + } + if (src_vals != NULL) { + INT64_RANGE_MIN (dest_value) = INT64_RANGE_MIN (src_value); + INT64_RANGE_MAX (dest_value) = INT64_RANGE_MAX (src_value); + INT64_RANGE_STEP (dest_value) = INT64_RANGE_STEP (src_value); + } } static gchar * gst_value_collect_int64_range (GValue * value, guint n_collect_values, GTypeCValue * collect_values, guint collect_flags) { + gint64 *vals = value->data[0].v_pointer; + if (n_collect_values != 2) return g_strdup_printf ("not enough value locations for `%s' passed", G_VALUE_TYPE_NAME (value)); @@ -941,8 +1086,12 @@ gst_value_collect_int64_range (GValue * value, guint n_collect_values, return g_strdup_printf ("range start is not smaller than end for `%s'", G_VALUE_TYPE_NAME (value)); - value->data[0].v_int64 = collect_values[0].v_int64; - value->data[1].v_int64 = collect_values[1].v_int64; + if (vals == NULL) { + gst_value_init_int64_range (value); + } + + gst_value_set_int64_range_step (value, collect_values[0].v_int64, + collect_values[1].v_int64, 1); return NULL; } @@ -953,6 +1102,8 @@ gst_value_lcopy_int64_range (const GValue * value, guint n_collect_values, { guint64 *int_range_start = collect_values[0].v_pointer; guint64 *int_range_end = collect_values[1].v_pointer; + guint64 *int_range_step = collect_values[2].v_pointer; + gint64 *vals = (gint64 *) value->data[0].v_pointer; if (!int_range_start) return g_strdup_printf ("start value location for `%s' passed as NULL", @@ -960,14 +1111,49 @@ gst_value_lcopy_int64_range (const GValue * value, guint n_collect_values, if (!int_range_end) return g_strdup_printf ("end value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value)); + if (!int_range_step) + return g_strdup_printf ("step value location for `%s' passed as NULL", + G_VALUE_TYPE_NAME (value)); - *int_range_start = value->data[0].v_int64; - *int_range_end = value->data[1].v_int64; + if (G_UNLIKELY (vals == NULL)) { + return g_strdup_printf ("Uninitialised `%s' passed", + G_VALUE_TYPE_NAME (value)); + } + + *int_range_start = INT64_RANGE_MIN (value); + *int_range_end = INT64_RANGE_MAX (value); + *int_range_step = INT64_RANGE_STEP (value); return NULL; } /** + * gst_value_set_int64_range_step: + * @value: a GValue initialized to GST_TYPE_INT64_RANGE + * @start: the start of the range + * @end: the end of the range + * @step: the step of the range + * + * Sets @value to the range specified by @start, @end and @step. + * + * Since: 0.11.0 + */ +void +gst_value_set_int64_range_step (GValue * value, gint64 start, gint64 end, + gint64 step) +{ + g_return_if_fail (GST_VALUE_HOLDS_INT64_RANGE (value)); + g_return_if_fail (start < end); + g_return_if_fail (step > 0); + g_return_if_fail (start % step == 0); + g_return_if_fail (end % step == 0); + + INT64_RANGE_MIN (value) = start / step; + INT64_RANGE_MAX (value) = end / step; + INT64_RANGE_STEP (value) = step; +} + +/** * gst_value_set_int64_range: * @value: a GValue initialized to GST_TYPE_INT64_RANGE * @start: the start of the range @@ -980,11 +1166,7 @@ gst_value_lcopy_int64_range (const GValue * value, guint n_collect_values, void gst_value_set_int64_range (GValue * value, gint64 start, gint64 end) { - g_return_if_fail (GST_VALUE_HOLDS_INT64_RANGE (value)); - g_return_if_fail (start < end); - - value->data[0].v_int64 = start; - value->data[1].v_int64 = end; + gst_value_set_int64_range_step (value, start, end, 1); } /** @@ -1002,7 +1184,7 @@ gst_value_get_int64_range_min (const GValue * value) { g_return_val_if_fail (GST_VALUE_HOLDS_INT64_RANGE (value), 0); - return value->data[0].v_int64; + return INT64_RANGE_MIN (value) * INT64_RANGE_STEP (value); } /** @@ -1020,32 +1202,88 @@ gst_value_get_int64_range_max (const GValue * value) { g_return_val_if_fail (GST_VALUE_HOLDS_INT64_RANGE (value), 0); - return value->data[1].v_int64; + return INT64_RANGE_MAX (value) * INT64_RANGE_STEP (value); +} + +/** + * gst_value_get_int64_range_step: + * @value: a GValue initialized to GST_TYPE_INT64_RANGE + * + * Gets the step of the range specified by @value. + * + * Returns: the step of the range + * + * Since: 0.11.0 + */ +gint64 +gst_value_get_int64_range_step (const GValue * value) +{ + g_return_val_if_fail (GST_VALUE_HOLDS_INT64_RANGE (value), 0); + + return INT64_RANGE_STEP (value); } static void gst_value_transform_int64_range_string (const GValue * src_value, GValue * dest_value) { - dest_value->data[0].v_pointer = - g_strdup_printf ("(gint64)[%" G_GINT64_FORMAT ",%" G_GINT64_FORMAT "]", - src_value->data[0].v_int64, src_value->data[1].v_int64); + if (INT64_RANGE_STEP (src_value) == 1) + dest_value->data[0].v_pointer = + g_strdup_printf ("(gint64)[%" G_GINT64_FORMAT ",%" G_GINT64_FORMAT "]", + INT64_RANGE_MIN (src_value), INT64_RANGE_MAX (src_value)); + else + dest_value->data[0].v_pointer = + g_strdup_printf ("(gint64)[%" G_GINT64_FORMAT ",%" G_GINT64_FORMAT + ",%" G_GINT64_FORMAT "]", + INT64_RANGE_MIN (src_value) * INT64_RANGE_STEP (src_value), + INT64_RANGE_MAX (src_value) * INT64_RANGE_STEP (src_value), + INT64_RANGE_STEP (src_value)); } static gint gst_value_compare_int64_range (const GValue * value1, const GValue * value2) { - if (value2->data[0].v_int64 == value1->data[0].v_int64 && - value2->data[1].v_int64 == value1->data[1].v_int64) + /* calculate the number of values in each range */ + gint64 n1 = INT64_RANGE_MAX (value1) - INT64_RANGE_MIN (value1) + 1; + gint64 n2 = INT64_RANGE_MAX (value2) - INT64_RANGE_MIN (value2) + 1; + + /* they must be equal */ + if (n1 != n2) + return GST_VALUE_UNORDERED; + + /* if empty, equal */ + if (n1 == 0) return GST_VALUE_EQUAL; - return GST_VALUE_UNORDERED; + + /* if more than one value, then it is only equal if the step is equal + and bounds lie on the same value */ + if (n1 > 1) { + if (INT64_RANGE_STEP (value1) == INT64_RANGE_STEP (value2) && + INT64_RANGE_STEP (value1) == INT64_RANGE_STEP (value2) && + INT64_RANGE_STEP (value1) == INT64_RANGE_STEP (value2)) { + return GST_VALUE_EQUAL; + } + return GST_VALUE_UNORDERED; + } else { + /* if just one, only if the value is equal */ + if (INT64_RANGE_MIN (value1) == INT64_RANGE_MIN (value2)) + return GST_VALUE_EQUAL; + return GST_VALUE_UNORDERED; + } } static gchar * gst_value_serialize_int64_range (const GValue * value) { - return g_strdup_printf ("[ %" G_GINT64_FORMAT ", %" G_GINT64_FORMAT " ]", - value->data[0].v_int64, value->data[1].v_int64); + if (INT64_RANGE_STEP (value) == 1) + return g_strdup_printf ("[ %" G_GINT64_FORMAT ", %" G_GINT64_FORMAT " ]", + INT64_RANGE_MIN (value), INT64_RANGE_MAX (value)); + else + return g_strdup_printf ("[ %" G_GINT64_FORMAT ", %" G_GINT64_FORMAT ", %" + G_GINT64_FORMAT " ]", + INT64_RANGE_MIN (value) * INT64_RANGE_STEP (value), + INT64_RANGE_MAX (value) * INT64_RANGE_STEP (value), + INT64_RANGE_STEP (value)); } static gboolean @@ -2491,6 +2729,114 @@ gst_value_deserialize_flags (GValue * dest, const gchar * s) return TRUE; } +/**************** + * subset * + ****************/ + +static gboolean +gst_value_is_subset_int_range_int_range (const GValue * value1, + const GValue * value2) +{ + gint gcd; + + g_return_val_if_fail (GST_VALUE_HOLDS_INT_RANGE (value1), FALSE); + g_return_val_if_fail (GST_VALUE_HOLDS_INT_RANGE (value2), FALSE); + + if (INT_RANGE_MIN (value1) * INT_RANGE_STEP (value1) < + INT_RANGE_MIN (value2) * INT_RANGE_STEP (value2)) + return FALSE; + if (INT_RANGE_MAX (value1) * INT_RANGE_STEP (value1) > + INT_RANGE_MAX (value2) * INT_RANGE_STEP (value2)) + return FALSE; + + if (INT_RANGE_MIN (value2) == INT_RANGE_MAX (value2)) { + if ((INT_RANGE_MIN (value2) * INT_RANGE_STEP (value2)) % + INT_RANGE_STEP (value1)) + return FALSE; + return TRUE; + } + + gcd = + gst_util_greatest_common_divisor (INT_RANGE_STEP (value1), + INT_RANGE_STEP (value2)); + if (gcd != MIN (INT_RANGE_STEP (value1), INT_RANGE_STEP (value2))) + return FALSE; + + return TRUE; +} + +static gboolean +gst_value_is_subset_int64_range_int64_range (const GValue * value1, + const GValue * value2) +{ + gint64 gcd; + + g_return_val_if_fail (GST_VALUE_HOLDS_INT64_RANGE (value1), FALSE); + g_return_val_if_fail (GST_VALUE_HOLDS_INT64_RANGE (value2), FALSE); + + if (INT64_RANGE_MIN (value1) < INT64_RANGE_MIN (value2)) + return FALSE; + if (INT64_RANGE_MAX (value1) > INT64_RANGE_MAX (value2)) + return FALSE; + + if (INT64_RANGE_MIN (value2) == INT64_RANGE_MAX (value2)) { + if ((INT64_RANGE_MIN (value2) * INT64_RANGE_STEP (value2)) % + INT64_RANGE_STEP (value1)) + return FALSE; + return TRUE; + } + + gcd = + gst_util_greatest_common_divisor_int64 (INT64_RANGE_STEP (value1), + INT64_RANGE_STEP (value2)); + if (gcd != MIN (INT64_RANGE_STEP (value1), INT64_RANGE_STEP (value2))) + return FALSE; + + return TRUE; +} + +gboolean +gst_value_is_subset (const GValue * value1, const GValue * value2) +{ + /* special case for int/int64 ranges, since we cannot compute + the difference for those when they have different steps, + and it's actually a lot simpler to compute whether a range + is a subset of another. */ + if (GST_VALUE_HOLDS_INT_RANGE (value1) && GST_VALUE_HOLDS_INT_RANGE (value2)) { + return gst_value_is_subset_int_range_int_range (value1, value2); + } else if (GST_VALUE_HOLDS_INT64_RANGE (value1) + && GST_VALUE_HOLDS_INT64_RANGE (value2)) { + return gst_value_is_subset_int64_range_int64_range (value1, value2); + } + + /* + * 1 - [1,2] = empty + * -> !subset + * + * [1,2] - 1 = 2 + * -> 1 - [1,2] = empty + * -> subset + * + * [1,3] - [1,2] = 3 + * -> [1,2] - [1,3] = empty + * -> subset + * + * {1,2} - {1,3} = 2 + * -> {1,3} - {1,2} = 3 + * -> !subset + * + * First caps subtraction needs to return a non-empty set, second + * subtractions needs to give en empty set. + * Both substractions are switched below, as it's faster that way. + */ + if (!gst_value_subtract (NULL, value1, value2)) { + if (gst_value_subtract (NULL, value2, value1)) { + return TRUE; + } + } + return FALSE; +} + /********* * union * *********/ @@ -2499,11 +2845,33 @@ static gboolean gst_value_union_int_int_range (GValue * dest, const GValue * src1, const GValue * src2) { - if (src2->data[0].v_int <= src1->data[0].v_int && - src2->data[1].v_int >= src1->data[0].v_int) { - gst_value_init_and_copy (dest, src2); + gint v = src1->data[0].v_int; + + /* check if it's already in the range */ + if (INT_RANGE_MIN (src2) * INT_RANGE_STEP (src2) <= v && + INT_RANGE_MAX (src2) * INT_RANGE_STEP (src2) >= v && + v % INT_RANGE_STEP (src2) == 0) { + if (dest) + gst_value_init_and_copy (dest, src2); return TRUE; } + + /* check if it extends the range */ + if (v == (INT_RANGE_MIN (src2) - 1) * INT_RANGE_STEP (src2)) { + if (dest) { + gst_value_init_and_copy (dest, src2); + --INT_RANGE_MIN (src2); + } + return TRUE; + } + if (v == (INT_RANGE_MAX (src2) + 1) * INT_RANGE_STEP (src2)) { + if (dest) { + gst_value_init_and_copy (dest, src2); + ++INT_RANGE_MAX (src2); + } + return TRUE; + } + return FALSE; } @@ -2511,20 +2879,77 @@ static gboolean gst_value_union_int_range_int_range (GValue * dest, const GValue * src1, const GValue * src2) { - gint min; - gint max; + /* We can union in several special cases: + 1 - one is a subset of another + 2 - same step and not disjoint + 3 - different step, at least one with one value which matches a 'next' or 'previous' + - anything else ? + */ - min = MAX (src1->data[0].v_int, src2->data[0].v_int); - max = MIN (src1->data[1].v_int, src2->data[1].v_int); - - if (min <= max) { - g_value_init (dest, GST_TYPE_INT_RANGE); - gst_value_set_int_range (dest, - MIN (src1->data[0].v_int, src2->data[0].v_int), - MAX (src1->data[1].v_int, src2->data[1].v_int)); + /* 1 - subset */ + if (gst_value_is_subset_int_range_int_range (src1, src2)) { + if (dest) + gst_value_init_and_copy (dest, src2); + return TRUE; + } + if (gst_value_is_subset_int_range_int_range (src2, src1)) { + if (dest) + gst_value_init_and_copy (dest, src1); return TRUE; } + /* 2 - same step and not disjoint */ + if (INT_RANGE_STEP (src1) == INT_RANGE_STEP (src2)) { + if ((INT_RANGE_MIN (src1) <= INT_RANGE_MAX (src2) + 1 && + INT_RANGE_MAX (src1) >= INT_RANGE_MIN (src2) - 1) || + (INT_RANGE_MIN (src2) <= INT_RANGE_MAX (src1) + 1 && + INT_RANGE_MAX (src2) >= INT_RANGE_MIN (src1) - 1)) { + if (dest) { + gint step = INT_RANGE_STEP (src1); + gint min = step * MIN (INT_RANGE_MIN (src1), INT_RANGE_MIN (src2)); + gint max = step * MAX (INT_RANGE_MAX (src1), INT_RANGE_MAX (src2)); + g_value_init (dest, GST_TYPE_INT_RANGE); + gst_value_set_int_range_step (dest, min, max, step); + } + return TRUE; + } + } + + /* 3 - single value matches next or previous */ + if (INT_RANGE_STEP (src1) != INT_RANGE_STEP (src2)) { + gint n1 = INT_RANGE_MAX (src1) - INT_RANGE_MIN (src1) + 1; + gint n2 = INT_RANGE_MAX (src2) - INT_RANGE_MIN (src2) + 1; + if (n1 == 1 || n2 == 1) { + const GValue *range_value = NULL; + gint scalar = 0; + if (n1 == 1) { + range_value = src2; + scalar = INT_RANGE_MIN (src1) * INT_RANGE_STEP (src1); + } else if (n2 == 1) { + range_value = src1; + scalar = INT_RANGE_MIN (src2) * INT_RANGE_STEP (src2); + } + + if (scalar == + (INT_RANGE_MIN (range_value) - 1) * INT_RANGE_STEP (range_value)) { + if (dest) { + gst_value_init_and_copy (dest, range_value); + --INT_RANGE_MIN (range_value); + } + return TRUE; + } else if (scalar == + (INT_RANGE_MAX (range_value) + 1) * INT_RANGE_STEP (range_value)) { + if (dest) { + gst_value_init_and_copy (dest, range_value); + ++INT_RANGE_MIN (range_value); + } + return TRUE; + } + } + } + + /* If we get there, we did not find a way to make a union that can be + represented with our simplistic model. */ return FALSE; } @@ -2536,8 +2961,9 @@ static gboolean gst_value_intersect_int_int_range (GValue * dest, const GValue * src1, const GValue * src2) { - if (src2->data[0].v_int <= src1->data[0].v_int && - src2->data[1].v_int >= src1->data[0].v_int) { + if (INT_RANGE_MIN (src2) * INT_RANGE_STEP (src2) <= src1->data[0].v_int && + INT_RANGE_MAX (src2) * INT_RANGE_STEP (src2) >= src1->data[0].v_int && + src1->data[0].v_int % INT_RANGE_STEP (src2) == 0) { if (dest) gst_value_init_and_copy (dest, src1); return TRUE; @@ -2552,14 +2978,29 @@ gst_value_intersect_int_range_int_range (GValue * dest, const GValue * src1, { gint min; gint max; + gint step; - min = MAX (src1->data[0].v_int, src2->data[0].v_int); - max = MIN (src1->data[1].v_int, src2->data[1].v_int); + step = + INT_RANGE_STEP (src1) / + gst_util_greatest_common_divisor (INT_RANGE_STEP (src1), + INT_RANGE_STEP (src2)); + if (G_MAXINT32 / INT_RANGE_STEP (src2) < step) + return FALSE; + step *= INT_RANGE_STEP (src2); + + min = + MAX (INT_RANGE_MIN (src1) * INT_RANGE_STEP (src1), + INT_RANGE_MIN (src2) * INT_RANGE_STEP (src2)); + min = (min + step - 1) / step * step; + max = + MIN (INT_RANGE_MAX (src1) * INT_RANGE_STEP (src1), + INT_RANGE_MAX (src2) * INT_RANGE_STEP (src2)); + max = max / step * step; if (min < max) { if (dest) { g_value_init (dest, GST_TYPE_INT_RANGE); - gst_value_set_int_range (dest, min, max); + gst_value_set_int_range_step (dest, min, max, step); } return TRUE; } @@ -2578,8 +3019,9 @@ static gboolean gst_value_intersect_int64_int64_range (GValue * dest, const GValue * src1, const GValue * src2) { - if (src2->data[0].v_int64 <= src1->data[0].v_int64 && - src2->data[1].v_int64 >= src1->data[0].v_int64) { + if (INT64_RANGE_MIN (src2) * INT64_RANGE_STEP (src2) <= src1->data[0].v_int && + INT64_RANGE_MAX (src2) * INT64_RANGE_STEP (src2) >= src1->data[0].v_int && + src1->data[0].v_int % INT64_RANGE_STEP (src2) == 0) { if (dest) gst_value_init_and_copy (dest, src1); return TRUE; @@ -2594,14 +3036,29 @@ gst_value_intersect_int64_range_int64_range (GValue * dest, const GValue * src1, { gint64 min; gint64 max; + gint64 step; + + step = + INT64_RANGE_STEP (src1) / + gst_util_greatest_common_divisor_int64 (INT64_RANGE_STEP (src1), + INT64_RANGE_STEP (src2)); + if (G_MAXINT64 / INT64_RANGE_STEP (src2) < step) + return FALSE; + step *= INT64_RANGE_STEP (src2); - min = MAX (src1->data[0].v_int64, src2->data[0].v_int64); - max = MIN (src1->data[1].v_int64, src2->data[1].v_int64); + min = + MAX (INT64_RANGE_MIN (src1) * INT64_RANGE_STEP (src1), + INT64_RANGE_MIN (src2) * INT64_RANGE_STEP (src2)); + min = (min + step - 1) / step * step; + max = + MIN (INT64_RANGE_MAX (src1) * INT64_RANGE_STEP (src1), + INT64_RANGE_MAX (src2) * INT64_RANGE_STEP (src2)); + max = max / step * step; if (min < max) { if (dest) { g_value_init (dest, GST_TYPE_INT64_RANGE); - gst_value_set_int64_range (dest, min, max); + gst_value_set_int64_range_step (dest, min, max, step); } return TRUE; } @@ -2830,11 +3287,12 @@ gst_value_subtract_int_int_range (GValue * dest, const GValue * minuend, { gint min = gst_value_get_int_range_min (subtrahend); gint max = gst_value_get_int_range_max (subtrahend); + gint step = gst_value_get_int_range_step (subtrahend); gint val = g_value_get_int (minuend); /* subtracting a range from an int only works if the int is not in the * range */ - if (val < min || val > max) { + if (val < min || val > max || val % step) { /* and the result is the int */ if (dest) gst_value_init_and_copy (dest, minuend); @@ -2847,12 +3305,18 @@ gst_value_subtract_int_int_range (GValue * dest, const GValue * minuend, */ static gboolean gst_value_create_new_range (GValue * dest, gint min1, gint max1, gint min2, - gint max2) + gint max2, gint step) { GValue v1 = { 0, }; GValue v2 = { 0, }; GValue *pv1, *pv2; /* yeah, hungarian! */ + g_return_val_if_fail (step > 0, FALSE); + g_return_val_if_fail (min1 % step == 0, FALSE); + g_return_val_if_fail (max1 % step == 0, FALSE); + g_return_val_if_fail (min2 % step == 0, FALSE); + g_return_val_if_fail (max2 % step == 0, FALSE); + if (min1 <= max1 && min2 <= max2) { pv1 = &v1; pv2 = &v2; @@ -2871,14 +3335,14 @@ gst_value_create_new_range (GValue * dest, gint min1, gint max1, gint min2, if (min1 < max1) { g_value_init (pv1, GST_TYPE_INT_RANGE); - gst_value_set_int_range (pv1, min1, max1); + gst_value_set_int_range_step (pv1, min1, max1, step); } else if (min1 == max1) { g_value_init (pv1, G_TYPE_INT); g_value_set_int (pv1, min1); } if (min2 < max2) { g_value_init (pv2, GST_TYPE_INT_RANGE); - gst_value_set_int_range (pv2, min2, max2); + gst_value_set_int_range_step (pv2, min2, max2, step); } else if (min2 == max2) { g_value_init (pv2, G_TYPE_INT); g_value_set_int (pv2, min2); @@ -2898,28 +3362,29 @@ gst_value_subtract_int_range_int (GValue * dest, const GValue * minuend, { gint min = gst_value_get_int_range_min (minuend); gint max = gst_value_get_int_range_max (minuend); + gint step = gst_value_get_int_range_step (minuend); gint val = g_value_get_int (subtrahend); g_return_val_if_fail (min < max, FALSE); /* value is outside of the range, return range unchanged */ - if (val < min || val > max) { + if (val < min || val > max || val % step) { if (dest) gst_value_init_and_copy (dest, minuend); return TRUE; } else { /* max must be MAXINT too as val <= max */ - if (val == G_MAXINT) { - max--; - val--; + if (val >= G_MAXINT - step + 1) { + max -= step; + val -= step; } /* min must be MININT too as val >= max */ - if (val == G_MININT) { - min++; - val++; + if (val <= G_MININT + step - 1) { + min += step; + val += step; } if (dest) - gst_value_create_new_range (dest, min, val - 1, val + 1, max); + gst_value_create_new_range (dest, min, val - step, val + step, max, step); } return TRUE; } @@ -2930,18 +3395,30 @@ gst_value_subtract_int_range_int_range (GValue * dest, const GValue * minuend, { gint min1 = gst_value_get_int_range_min (minuend); gint max1 = gst_value_get_int_range_max (minuend); + gint step1 = gst_value_get_int_range_step (minuend); gint min2 = gst_value_get_int_range_min (subtrahend); gint max2 = gst_value_get_int_range_max (subtrahend); + gint step2 = gst_value_get_int_range_step (subtrahend); + gint step; - if (max2 == G_MAXINT && min2 == G_MININT) { + if (step1 != step2) { + /* ENOIMPL */ + g_assert (FALSE); return FALSE; - } else if (max2 == G_MAXINT) { - return gst_value_create_new_range (dest, min1, MIN (min2 - 1, max1), 1, 0); - } else if (min2 == G_MININT) { - return gst_value_create_new_range (dest, MAX (max2 + 1, min1), max1, 1, 0); + } + step = step1; + + if (max2 >= max1 && min2 <= min1) { + return FALSE; + } else if (max2 >= max1) { + return gst_value_create_new_range (dest, min1, MIN (min2 - step, max1), + step, 0, step); + } else if (min2 <= min1) { + return gst_value_create_new_range (dest, MAX (max2 + step, min1), max1, + step, 0, step); } else { - return gst_value_create_new_range (dest, min1, MIN (min2 - 1, max1), - MAX (max2 + 1, min1), max1); + return gst_value_create_new_range (dest, min1, MIN (min2 - step, max1), + MAX (max2 + step, min1), max1, step); } } @@ -2951,11 +3428,12 @@ gst_value_subtract_int64_int64_range (GValue * dest, const GValue * minuend, { gint64 min = gst_value_get_int64_range_min (subtrahend); gint64 max = gst_value_get_int64_range_max (subtrahend); + gint64 step = gst_value_get_int64_range_step (subtrahend); gint64 val = g_value_get_int64 (minuend); /* subtracting a range from an int64 only works if the int64 is not in the * range */ - if (val < min || val > max) { + if (val < min || val > max || val % step) { /* and the result is the int64 */ if (dest) gst_value_init_and_copy (dest, minuend); @@ -2968,12 +3446,18 @@ gst_value_subtract_int64_int64_range (GValue * dest, const GValue * minuend, */ static gboolean gst_value_create_new_int64_range (GValue * dest, gint64 min1, gint64 max1, - gint64 min2, gint64 max2) + gint64 min2, gint64 max2, gint64 step) { GValue v1 = { 0, }; GValue v2 = { 0, }; GValue *pv1, *pv2; /* yeah, hungarian! */ + g_return_val_if_fail (step > 0, FALSE); + g_return_val_if_fail (min1 % step == 0, FALSE); + g_return_val_if_fail (max1 % step == 0, FALSE); + g_return_val_if_fail (min2 % step == 0, FALSE); + g_return_val_if_fail (max2 % step == 0, FALSE); + if (min1 <= max1 && min2 <= max2) { pv1 = &v1; pv2 = &v2; @@ -2992,14 +3476,14 @@ gst_value_create_new_int64_range (GValue * dest, gint64 min1, gint64 max1, if (min1 < max1) { g_value_init (pv1, GST_TYPE_INT64_RANGE); - gst_value_set_int64_range (pv1, min1, max1); + gst_value_set_int64_range_step (pv1, min1, max1, step); } else if (min1 == max1) { g_value_init (pv1, G_TYPE_INT64); g_value_set_int64 (pv1, min1); } if (min2 < max2) { g_value_init (pv2, GST_TYPE_INT64_RANGE); - gst_value_set_int64_range (pv2, min2, max2); + gst_value_set_int64_range_step (pv2, min2, max2, step); } else if (min2 == max2) { g_value_init (pv2, G_TYPE_INT64); g_value_set_int64 (pv2, min2); @@ -3019,28 +3503,30 @@ gst_value_subtract_int64_range_int64 (GValue * dest, const GValue * minuend, { gint64 min = gst_value_get_int64_range_min (minuend); gint64 max = gst_value_get_int64_range_max (minuend); + gint64 step = gst_value_get_int64_range_step (minuend); gint64 val = g_value_get_int64 (subtrahend); g_return_val_if_fail (min < max, FALSE); /* value is outside of the range, return range unchanged */ - if (val < min || val > max) { + if (val < min || val > max || val % step) { if (dest) gst_value_init_and_copy (dest, minuend); return TRUE; } else { /* max must be MAXINT64 too as val <= max */ - if (val == G_MAXINT64) { - max--; - val--; + if (val >= G_MAXINT64 - step + 1) { + max -= step; + val -= step; } /* min must be MININT64 too as val >= max */ - if (val == G_MININT64) { - min++; - val++; + if (val <= G_MININT64 + step - 1) { + min += step; + val += step; } if (dest) - gst_value_create_new_int64_range (dest, min, val - 1, val + 1, max); + gst_value_create_new_int64_range (dest, min, val - step, val + step, max, + step); } return TRUE; } @@ -3051,20 +3537,30 @@ gst_value_subtract_int64_range_int64_range (GValue * dest, { gint64 min1 = gst_value_get_int64_range_min (minuend); gint64 max1 = gst_value_get_int64_range_max (minuend); + gint64 step1 = gst_value_get_int64_range_step (minuend); gint64 min2 = gst_value_get_int64_range_min (subtrahend); gint64 max2 = gst_value_get_int64_range_max (subtrahend); + gint64 step2 = gst_value_get_int64_range_step (subtrahend); + gint64 step; - if (max2 == G_MAXINT64 && min2 == G_MININT64) { + if (step1 != step2) { + /* ENOIMPL */ + g_assert (FALSE); return FALSE; - } else if (max2 == G_MAXINT64) { - return gst_value_create_new_int64_range (dest, min1, MIN (min2 - 1, max1), - 1, 0); - } else if (min2 == G_MININT64) { - return gst_value_create_new_int64_range (dest, MAX (max2 + 1, min1), max1, - 1, 0); + } + step = step1; + + if (max2 >= max1 && min2 <= min1) { + return FALSE; + } else if (max2 >= max1) { + return gst_value_create_new_int64_range (dest, min1, MIN (min2 - step, + max1), step, 0, step); + } else if (min2 <= min1) { + return gst_value_create_new_int64_range (dest, MAX (max2 + step, min1), + max1, step, 0, step); } else { - return gst_value_create_new_int64_range (dest, min1, MIN (min2 - 1, max1), - MAX (max2 + 1, min1), max1); + return gst_value_create_new_int64_range (dest, min1, MIN (min2 - step, + max1), MAX (max2 + step, min1), max1, step); } } @@ -3407,14 +3903,15 @@ gst_value_list_equals_range (const GValue * list, const GValue * value) if (CHECK_TYPES (INT, G)) { const gint rmin = gst_value_get_int_range_min (value); const gint rmax = gst_value_get_int_range_max (value); + const gint rstep = gst_value_get_int_range_step (value); /* note: this will overflow for min 0 and max INT_MAX, but this would only be equal to a list of INT_MAX elements, which seems very unlikely */ - if (list_size != rmax - rmin + 1) + if (list_size != rmax / rstep - rmin / rstep + 1) return FALSE; for (n = 0; n < list_size; ++n) { gint v = g_value_get_int (VALUE_LIST_GET_VALUE (list, n)); - if (v < rmin || v > rmax) { + if (v < rmin || v > rmax || v % rstep) { return FALSE; } } @@ -3422,12 +3919,13 @@ gst_value_list_equals_range (const GValue * list, const GValue * value) } else if (CHECK_TYPES (INT64, G)) { const gint64 rmin = gst_value_get_int64_range_min (value); const gint64 rmax = gst_value_get_int64_range_max (value); + const gint64 rstep = gst_value_get_int64_range_step (value); GST_DEBUG ("List/range of int64s"); - if (list_size != rmax - rmin + 1) + if (list_size != rmax / rstep - rmin / rstep + 1) return FALSE; for (n = 0; n < list_size; ++n) { gint64 v = g_value_get_int64 (VALUE_LIST_GET_VALUE (list, n)); - if (v < rmin || v > rmax) + if (v < rmin || v > rmax || v % rstep) return FALSE; } return TRUE; @@ -4919,7 +5417,7 @@ GType gst_ ## type ## _get_type (void) \ static const GTypeValueTable _gst_int_range_value_table = { gst_value_init_int_range, - NULL, + gst_value_free_int_range, gst_value_copy_int_range, NULL, (char *) "ii", @@ -4932,7 +5430,7 @@ FUNC_VALUE_GET_TYPE (int_range, "GstIntRange"); static const GTypeValueTable _gst_int64_range_value_table = { gst_value_init_int64_range, - NULL, + gst_value_free_int64_range, gst_value_copy_int64_range, NULL, (char *) "qq", diff --git a/gst/gstvalue.h b/gst/gstvalue.h index dcf9e24787..1fe64c4666 100644 --- a/gst/gstvalue.h +++ b/gst/gstvalue.h @@ -476,15 +476,25 @@ const GValue * gst_value_array_get_value (const GValue *value, void gst_value_set_int_range (GValue *value, gint start, gint end); +void gst_value_set_int_range_step (GValue *value, + gint start, + gint end, + gint step); gint gst_value_get_int_range_min (const GValue *value); gint gst_value_get_int_range_max (const GValue *value); +gint gst_value_get_int_range_step (const GValue *value); /* int64 range */ void gst_value_set_int64_range (GValue *value, gint64 start, gint64 end); +void gst_value_set_int64_range_step (GValue *value, + gint64 start, + gint64 end, + gint64 step); gint64 gst_value_get_int64_range_min (const GValue *value); gint64 gst_value_get_int64_range_max (const GValue *value); +gint64 gst_value_get_int64_range_step (const GValue *value); /* double range */ void gst_value_set_double_range (GValue *value, @@ -539,6 +549,9 @@ gint gst_value_compare (const GValue *value1, const GValue *value2); gboolean gst_value_can_compare (const GValue *value1, const GValue *value2); +gboolean gst_value_is_subset (const GValue *value1, + const GValue *value2); + /* union */ gboolean gst_value_union (GValue *dest, const GValue *value1, diff --git a/win32/common/libgstreamer.def b/win32/common/libgstreamer.def index 6127ff32f8..e2ae9028e2 100644 --- a/win32/common/libgstreamer.def +++ b/win32/common/libgstreamer.def @@ -1155,6 +1155,7 @@ EXPORTS gst_util_gdouble_to_guint64 gst_util_get_timestamp gst_util_greatest_common_divisor + gst_util_greatest_common_divisor_int64 gst_util_guint64_to_gdouble gst_util_seqnum_compare gst_util_seqnum_next @@ -1190,12 +1191,15 @@ EXPORTS gst_value_get_fraction_range_min gst_value_get_int64_range_max gst_value_get_int64_range_min + gst_value_get_int64_range_step gst_value_get_int_range_max gst_value_get_int_range_min + gst_value_get_int_range_step gst_value_get_structure gst_value_init_and_copy gst_value_intersect gst_value_is_fixed + gst_value_is_subset gst_value_list_append_value gst_value_list_concat gst_value_list_get_size @@ -1215,7 +1219,9 @@ EXPORTS gst_value_set_fraction_range gst_value_set_fraction_range_full gst_value_set_int64_range + gst_value_set_int64_range_step gst_value_set_int_range + gst_value_set_int_range_step gst_value_set_structure gst_value_subtract gst_value_union |