From da58834884ab64a183c144de5576eb31db92b265 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20Dr=C3=B6ge?= Date: Fri, 27 May 2011 13:47:11 +0200 Subject: [PATCH] structure: Add gst_structure_is_subset() API: gst_structure_is_subset() --- docs/gst/gstreamer-sections.txt | 1 + gst/gstcaps.c | 62 ++--------------------------------- gst/gststructure.c | 71 +++++++++++++++++++++++++++++++++++++++++ gst/gststructure.h | 2 ++ win32/common/libgstreamer.def | 1 + 5 files changed, 77 insertions(+), 60 deletions(-) diff --git a/docs/gst/gstreamer-sections.txt b/docs/gst/gstreamer-sections.txt index 0999c5e..218ac4f 100644 --- a/docs/gst/gstreamer-sections.txt +++ b/docs/gst/gstreamer-sections.txt @@ -2209,6 +2209,7 @@ gst_structure_n_fields gst_structure_has_field gst_structure_has_field_typed gst_structure_is_equal +gst_structure_is_subset gst_structure_can_intersect gst_structure_intersect gst_structure_id_has_field diff --git a/gst/gstcaps.c b/gst/gstcaps.c index bc89baa..58a4aca 100644 --- a/gst/gstcaps.c +++ b/gst/gstcaps.c @@ -565,64 +565,6 @@ gst_caps_steal_structure (GstCaps * caps, guint index) return gst_caps_remove_and_get_structure (caps, index); } -static gboolean -gst_caps_structure_is_subset_field (GQuark field_id, const GValue * value, - gpointer user_data) -{ - GstStructure *superset = user_data; - GValue subtraction = { 0, }; - const GValue *other; - - if (!(other = gst_structure_id_get_value (superset, field_id))) - /* field is missing in the superset => is subset */ - return TRUE; - - /* equal values are subset */ - if (gst_value_compare (other, value) == GST_VALUE_EQUAL) - return TRUE; - - /* - * 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. - */ - if (gst_value_subtract (&subtraction, other, value)) { - g_value_unset (&subtraction); - /* !empty result, swapping must be empty */ - if (!gst_value_subtract (&subtraction, value, other)) - return TRUE; - - g_value_unset (&subtraction); - } - return FALSE; -} - -static gboolean -gst_caps_structure_is_subset (const GstStructure * superset, - const GstStructure * subset) -{ - if ((superset->name != subset->name) || - (gst_structure_n_fields (superset) > gst_structure_n_fields (subset))) - return FALSE; - - return gst_structure_foreach ((GstStructure *) subset, - gst_caps_structure_is_subset_field, (gpointer) superset); -} - /** * gst_caps_append: * @caps1: the #GstCaps that will be appended to @@ -792,7 +734,7 @@ gst_caps_merge_structure (GstCaps * caps, GstStructure * structure) for (i = caps->structs->len - 1; i >= 0; i--) { structure1 = gst_caps_get_structure_unchecked (caps, i); /* if structure is a subset of structure1, then skip it */ - if (gst_caps_structure_is_subset (structure1, structure)) { + if (gst_structure_is_subset (structure, structure1)) { unique = FALSE; break; } @@ -1147,7 +1089,7 @@ gst_caps_is_subset (const GstCaps * subset, const GstCaps * superset) for (j = superset->structs->len - 1; j >= 0; j--) { s1 = gst_caps_get_structure_unchecked (subset, i); s2 = gst_caps_get_structure_unchecked (superset, j); - if (gst_caps_structure_is_subset (s2, s1)) { + if (gst_structure_is_subset (s1, s2)) { /* If we found a superset, continue with the next * subset structure */ break; diff --git a/gst/gststructure.c b/gst/gststructure.c index 29d91f9..3b2c2e4 100644 --- a/gst/gststructure.c +++ b/gst/gststructure.c @@ -3099,3 +3099,74 @@ gst_structure_can_intersect (const GstStructure * struct1, return TRUE; } + +static gboolean +gst_caps_structure_is_subset_field (GQuark field_id, const GValue * value, + gpointer user_data) +{ + GstStructure *superset = user_data; + GValue subtraction = { 0, }; + const GValue *other; + + if (!(other = gst_structure_id_get_value (superset, field_id))) + /* field is missing in the superset => is subset */ + return TRUE; + + /* equal values are subset */ + if (gst_value_compare (other, value) == GST_VALUE_EQUAL) + return TRUE; + + /* + * 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. + */ + if (gst_value_subtract (&subtraction, other, value)) { + g_value_unset (&subtraction); + /* !empty result, swapping must be empty */ + if (!gst_value_subtract (&subtraction, value, other)) + return TRUE; + + g_value_unset (&subtraction); + } + return FALSE; +} + +/** + * gst_structure_is_subset: + * @subset: a #GstStructure + * @superset: a potentially greater #GstStructure + * + * Checks if @subset is a subset of @superset, i.e. has the same + * structure name and for all fields that are existing in @superset, + * @subset has a value that is a subset of the value in @superset. + * + * Returns: %TRUE if @subset is a subset of @superset + * + * Since: 0.10.35 + */ +gboolean +gst_structure_is_subset (const GstStructure * subset, + const GstStructure * superset) +{ + if ((superset->name != subset->name) || + (gst_structure_n_fields (superset) > gst_structure_n_fields (subset))) + return FALSE; + + return gst_structure_foreach ((GstStructure *) subset, + gst_caps_structure_is_subset_field, (gpointer) superset); +} diff --git a/gst/gststructure.h b/gst/gststructure.h index 89a79f5..3e92a4d 100644 --- a/gst/gststructure.h +++ b/gst/gststructure.h @@ -250,6 +250,8 @@ gboolean gst_structure_fixate_field_nearest_fraction (GstStructu gboolean gst_structure_is_equal(const GstStructure *structure1, const GstStructure *structure2); +gboolean gst_structure_is_subset(const GstStructure *subset, + const GstStructure *superset); gboolean gst_structure_can_intersect(const GstStructure *struct1, const GstStructure *struct2); GstStructure* gst_structure_intersect (const GstStructure *struct1, diff --git a/win32/common/libgstreamer.def b/win32/common/libgstreamer.def index 9f8bc99..904adfc 100644 --- a/win32/common/libgstreamer.def +++ b/win32/common/libgstreamer.def @@ -1010,6 +1010,7 @@ EXPORTS gst_structure_id_take_value gst_structure_intersect gst_structure_is_equal + gst_structure_is_subset gst_structure_map_in_place gst_structure_n_fields gst_structure_new -- 2.7.4