From 407e32588d6ad9defdb6a6ae3f25d63c5f34c331 Mon Sep 17 00:00:00 2001 From: Henry Wilkes Date: Tue, 21 Jan 2020 19:02:48 +0000 Subject: [PATCH] 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 --- gst/gstcaps.c | 14 +++ tests/check/gst/gstcaps.c | 197 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 211 insertions(+) diff --git a/gst/gstcaps.c b/gst/gstcaps.c index 9e6408d574..8ab0073e2f 100644 --- a/gst/gstcaps.c +++ b/gst/gstcaps.c @@ -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; diff --git a/tests/check/gst/gstcaps.c b/tests/check/gst/gstcaps.c index c80d02b6b2..cd755667ea 100644 --- a/tests/check/gst/gstcaps.c +++ b/tests/check/gst/gstcaps.c @@ -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; }