caps: fix is_strictly_equal

Fixed gst_caps_is_strictly_equal() to take into account whether either of
the caps are ANY caps. Previously, two ANY caps could be considered not
strictly equal if one of them still contained some remnant *internal*
structure (this can happen if an ANY caps has emerged from an append or
merge operation). Also, an ANY caps with no remnant internal structures
was considered strictly equal to an EMPTY caps. Similarly, a non-ANY caps
was considered strictly equal to an ANY caps if its remnant internal
structures happened to match.

Also changed gst_caps_is_fixed to take into account that an ANY caps
should not be considered fixed even if it contains a single remnant
internal fixed structure. This affects gst_caps_is_equal(), which uses a
separate method if both caps are fixed. Previously, this meant that a
non-ANY fixed caps was considered equal to an ANY caps if it contained a
single matching remnant internal structure.

Added some tests for these two equality methods, which covers the above
examples, as well as asserts existing behaviour.

Fixes #496
This commit is contained in:
Henry Wilkes 2020-01-21 19:02:48 +00:00 committed by Jan Schmidt
parent 6ab1cdf51d
commit 407e32588d
2 changed files with 211 additions and 0 deletions

View file

@ -1182,6 +1182,12 @@ gst_caps_is_fixed (const GstCaps * caps)
if (GST_CAPS_LEN (caps) != 1)
return FALSE;
/* an ANY caps can have length 1 (rather than the usual 0) if it
* has had a structure appended, or if it was created from a merge
* or append of caps */
if (CAPS_IS_ANY (caps))
return FALSE;
features = gst_caps_get_features_unchecked (caps, 0);
if (features && gst_caps_features_is_any (features))
return FALSE;
@ -1427,6 +1433,14 @@ gst_caps_is_strictly_equal (const GstCaps * caps1, const GstCaps * caps2)
if (G_UNLIKELY (caps1 == caps2))
return TRUE;
/* if both are ANY caps, consider them strictly equal, even if
* internally they contain differing structures from
* gst_caps_append, gst_caps_merge or gst_caps_append_structure */
if (CAPS_IS_ANY (caps1))
return (CAPS_IS_ANY (caps2));
else if (CAPS_IS_ANY (caps2))
return FALSE;
if (GST_CAPS_LEN (caps1) != GST_CAPS_LEN (caps2))
return FALSE;

View file

@ -1408,6 +1408,202 @@ GST_START_TEST (test_filter_and_map_in_place)
GST_END_TEST;
GST_START_TEST (test_equality)
{
GstCaps *empty1, *empty2, *any1, *any2, *caps1, *caps2, *caps3, *caps4,
*caps5, *caps6, *caps7, *caps8, *caps9;
GstStructure *s;
empty1 = gst_caps_new_empty ();
empty2 = gst_caps_new_empty ();
any1 = gst_caps_new_any ();
any2 = gst_caps_new_any ();
s = gst_structure_new ("structure", "int", G_TYPE_INT, 4, "float",
G_TYPE_FLOAT, 5.7, NULL);
fail_unless (s);
gst_caps_append_structure (any2, s);
caps1 = gst_caps_new_simple ("structure", "int", G_TYPE_INT, 4, "float",
G_TYPE_FLOAT, 5.7, NULL);
fail_unless (caps1);
caps2 = gst_caps_new_simple ("structure", "int", G_TYPE_INT, 4, "float",
G_TYPE_FLOAT, 5.7, NULL);
fail_unless (caps2);
/* append an identical structure */
s = gst_structure_new ("structure", "int", G_TYPE_INT, 4, "float",
G_TYPE_FLOAT, 5.7, NULL);
fail_unless (s);
gst_caps_append_structure (caps2, s);
/* change field name */
caps3 = gst_caps_new_simple ("structure", "intX", G_TYPE_INT, 4, "float",
G_TYPE_FLOAT, 5.7, NULL);
fail_unless (caps3);
/* change field type */
caps4 = gst_caps_new_simple ("structure", "int", G_TYPE_UINT, 4, "float",
G_TYPE_FLOAT, 5.7, NULL);
fail_unless (caps4);
/* change structure name */
caps5 = gst_caps_new_simple ("structureX", "int", G_TYPE_INT, 4, "float",
G_TYPE_FLOAT, 5.7, NULL);
fail_unless (caps5);
/* change field value */
caps6 = gst_caps_new_simple ("structure", "int", G_TYPE_INT, 3, "float",
G_TYPE_FLOAT, 5.7, NULL);
fail_unless (caps6);
/* change caps features */
caps7 = gst_caps_new_simple ("structure", "int", G_TYPE_INT, 4, "float",
G_TYPE_FLOAT, 5.7, NULL);
fail_unless (caps6);
gst_caps_set_features (caps7, 0, gst_caps_features_new_any ());
/* add structure */
caps8 = gst_caps_new_simple ("structure", "int", G_TYPE_INT, 4, "float",
G_TYPE_FLOAT, 5.7, NULL);
fail_unless (caps8);
s = gst_structure_new ("structure2", "string", G_TYPE_STRING, "val", NULL);
fail_unless (s);
gst_caps_append_structure (caps8, s);
/* reverse the order of the structures */
caps9 = gst_caps_new_simple ("structure2", "string", G_TYPE_STRING, "val",
NULL);
fail_unless (caps9);
s = gst_structure_new ("structure", "int", G_TYPE_INT, 4, "float",
G_TYPE_FLOAT, 5.7, NULL);
fail_unless (s);
gst_caps_append_structure (caps9, s);
fail_unless (gst_caps_is_equal (empty1, empty2) == TRUE);
fail_unless (gst_caps_is_strictly_equal (empty1, empty2) == TRUE);
fail_unless (gst_caps_is_equal (empty1, any1) == FALSE);
fail_unless (gst_caps_is_strictly_equal (empty1, any1) == FALSE);
fail_unless (gst_caps_is_equal (empty1, any2) == FALSE);
fail_unless (gst_caps_is_strictly_equal (empty1, any2) == FALSE);
fail_unless (gst_caps_is_equal (empty1, caps1) == FALSE);
fail_unless (gst_caps_is_strictly_equal (empty1, caps1) == FALSE);
fail_unless (gst_caps_is_equal (empty1, caps2) == FALSE);
fail_unless (gst_caps_is_strictly_equal (empty1, caps2) == FALSE);
fail_unless (gst_caps_is_equal (empty1, caps3) == FALSE);
fail_unless (gst_caps_is_strictly_equal (empty1, caps3) == FALSE);
fail_unless (gst_caps_is_equal (empty1, caps4) == FALSE);
fail_unless (gst_caps_is_strictly_equal (empty1, caps4) == FALSE);
fail_unless (gst_caps_is_equal (empty1, caps5) == FALSE);
fail_unless (gst_caps_is_strictly_equal (empty1, caps5) == FALSE);
fail_unless (gst_caps_is_equal (empty1, caps6) == FALSE);
fail_unless (gst_caps_is_strictly_equal (empty1, caps6) == FALSE);
fail_unless (gst_caps_is_equal (empty1, caps7) == FALSE);
fail_unless (gst_caps_is_strictly_equal (empty1, caps7) == FALSE);
fail_unless (gst_caps_is_equal (empty1, caps8) == FALSE);
fail_unless (gst_caps_is_strictly_equal (empty1, caps8) == FALSE);
fail_unless (gst_caps_is_equal (empty1, caps9) == FALSE);
fail_unless (gst_caps_is_strictly_equal (empty1, caps9) == FALSE);
fail_unless (gst_caps_is_equal (any1, any2) == TRUE);
fail_unless (gst_caps_is_strictly_equal (any1, any2) == TRUE);
fail_unless (gst_caps_is_equal (any1, caps1) == FALSE);
fail_unless (gst_caps_is_strictly_equal (any1, caps1) == FALSE);
fail_unless (gst_caps_is_equal (any1, caps2) == FALSE);
fail_unless (gst_caps_is_strictly_equal (any1, caps2) == FALSE);
fail_unless (gst_caps_is_equal (any1, caps3) == FALSE);
fail_unless (gst_caps_is_strictly_equal (any1, caps3) == FALSE);
fail_unless (gst_caps_is_equal (any1, caps4) == FALSE);
fail_unless (gst_caps_is_strictly_equal (any1, caps4) == FALSE);
fail_unless (gst_caps_is_equal (any1, caps5) == FALSE);
fail_unless (gst_caps_is_strictly_equal (any1, caps5) == FALSE);
fail_unless (gst_caps_is_equal (any1, caps6) == FALSE);
fail_unless (gst_caps_is_strictly_equal (any1, caps6) == FALSE);
fail_unless (gst_caps_is_equal (any1, caps7) == FALSE);
fail_unless (gst_caps_is_strictly_equal (any1, caps7) == FALSE);
fail_unless (gst_caps_is_equal (any1, caps8) == FALSE);
fail_unless (gst_caps_is_strictly_equal (any1, caps8) == FALSE);
fail_unless (gst_caps_is_equal (any1, caps9) == FALSE);
fail_unless (gst_caps_is_strictly_equal (any1, caps9) == FALSE);
fail_unless (gst_caps_is_equal (any2, caps1) == FALSE);
fail_unless (gst_caps_is_strictly_equal (any2, caps1) == FALSE);
fail_unless (gst_caps_is_equal (any2, caps2) == FALSE);
fail_unless (gst_caps_is_strictly_equal (any2, caps2) == FALSE);
fail_unless (gst_caps_is_equal (any2, caps3) == FALSE);
fail_unless (gst_caps_is_strictly_equal (any2, caps3) == FALSE);
fail_unless (gst_caps_is_equal (any2, caps4) == FALSE);
fail_unless (gst_caps_is_strictly_equal (any2, caps4) == FALSE);
fail_unless (gst_caps_is_equal (any2, caps5) == FALSE);
fail_unless (gst_caps_is_strictly_equal (any2, caps5) == FALSE);
fail_unless (gst_caps_is_equal (any2, caps6) == FALSE);
fail_unless (gst_caps_is_strictly_equal (any2, caps6) == FALSE);
fail_unless (gst_caps_is_equal (any2, caps7) == FALSE);
fail_unless (gst_caps_is_strictly_equal (any2, caps7) == FALSE);
fail_unless (gst_caps_is_equal (any2, caps8) == FALSE);
fail_unless (gst_caps_is_strictly_equal (any2, caps8) == FALSE);
fail_unless (gst_caps_is_equal (any2, caps9) == FALSE);
fail_unless (gst_caps_is_strictly_equal (any2, caps9) == FALSE);
/* caps1 and caps2 are equal, but not strictly equal because one has
* two copies of the same structure */
fail_unless (gst_caps_is_equal (caps1, caps2) == TRUE);
fail_unless (gst_caps_is_strictly_equal (caps1, caps2) == FALSE);
fail_unless (gst_caps_is_equal (caps1, caps3) == FALSE);
fail_unless (gst_caps_is_strictly_equal (caps1, caps3) == FALSE);
fail_unless (gst_caps_is_equal (caps1, caps4) == FALSE);
fail_unless (gst_caps_is_strictly_equal (caps1, caps4) == FALSE);
fail_unless (gst_caps_is_equal (caps1, caps5) == FALSE);
fail_unless (gst_caps_is_strictly_equal (caps1, caps5) == FALSE);
fail_unless (gst_caps_is_equal (caps1, caps6) == FALSE);
fail_unless (gst_caps_is_strictly_equal (caps1, caps6) == FALSE);
fail_unless (gst_caps_is_equal (caps1, caps7) == FALSE);
fail_unless (gst_caps_is_strictly_equal (caps1, caps7) == FALSE);
fail_unless (gst_caps_is_equal (caps1, caps8) == FALSE);
fail_unless (gst_caps_is_strictly_equal (caps1, caps8) == FALSE);
fail_unless (gst_caps_is_equal (caps1, caps9) == FALSE);
fail_unless (gst_caps_is_strictly_equal (caps1, caps9) == FALSE);
fail_unless (gst_caps_is_equal (caps2, caps3) == FALSE);
fail_unless (gst_caps_is_strictly_equal (caps2, caps3) == FALSE);
fail_unless (gst_caps_is_equal (caps2, caps4) == FALSE);
fail_unless (gst_caps_is_strictly_equal (caps2, caps4) == FALSE);
fail_unless (gst_caps_is_equal (caps2, caps5) == FALSE);
fail_unless (gst_caps_is_strictly_equal (caps2, caps5) == FALSE);
fail_unless (gst_caps_is_equal (caps2, caps6) == FALSE);
fail_unless (gst_caps_is_strictly_equal (caps2, caps6) == FALSE);
fail_unless (gst_caps_is_equal (caps2, caps7) == FALSE);
fail_unless (gst_caps_is_strictly_equal (caps2, caps7) == FALSE);
fail_unless (gst_caps_is_equal (caps2, caps8) == FALSE);
fail_unless (gst_caps_is_strictly_equal (caps2, caps8) == FALSE);
fail_unless (gst_caps_is_equal (caps2, caps9) == FALSE);
fail_unless (gst_caps_is_strictly_equal (caps2, caps9) == FALSE);
/* caps8 and caps9 are equal, but not strictly equal because their
* order of structures is different */
fail_unless (gst_caps_is_equal (caps8, caps9) == TRUE);
fail_unless (gst_caps_is_strictly_equal (caps8, caps9) == FALSE);
gst_caps_unref (empty1);
gst_caps_unref (empty2);
gst_caps_unref (any1);
gst_caps_unref (any2);
gst_caps_unref (caps1);
gst_caps_unref (caps2);
gst_caps_unref (caps3);
gst_caps_unref (caps4);
gst_caps_unref (caps5);
gst_caps_unref (caps6);
gst_caps_unref (caps7);
gst_caps_unref (caps8);
gst_caps_unref (caps9);
}
GST_END_TEST;
static Suite *
gst_caps_suite (void)
{
@ -1442,6 +1638,7 @@ gst_caps_suite (void)
tcase_add_test (tc_chain, test_foreach);
tcase_add_test (tc_chain, test_map_in_place);
tcase_add_test (tc_chain, test_filter_and_map_in_place);
tcase_add_test (tc_chain, test_equality);
return s;
}