caps: Fix subset check for equivalent lists and scalar values
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Mon, 30 May 2011 05:36:58 +0000 (07:36 +0200)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Mon, 30 May 2011 05:38:40 +0000 (07:38 +0200)
For example "{ 1 }" and "1" are not strictly equal but
both are a subset of each other. Also add a unit test
for this.

gst/gststructure.c
tests/check/gst/gstcaps.c

index 3b2c2e4..1f3a462 100644 (file)
@@ -3107,11 +3107,48 @@ gst_caps_structure_is_subset_field (GQuark field_id, const GValue * value,
   GstStructure *superset = user_data;
   GValue subtraction = { 0, };
   const GValue *other;
+  GType ltype;
 
   if (!(other = gst_structure_id_get_value (superset, field_id)))
     /* field is missing in the superset => is subset */
     return TRUE;
 
+  /* Special case: lists and scalar values 
+   * "{ 1 }" and "1" subsets of each other
+   * but not strictly equal */
+  ltype = gst_value_list_get_type ();
+  if (G_VALUE_HOLDS (other, ltype) && !G_VALUE_HOLDS (value, ltype)) {
+    const GValue *elt;
+    gint i, n;
+    gboolean all_equal = TRUE;
+
+    n = gst_value_list_get_size (other);
+    for (i = 0; i < n; i++) {
+      elt = gst_value_list_get_value (other, 0);
+      if (gst_value_compare (elt, value) != GST_VALUE_EQUAL) {
+        all_equal = FALSE;
+        break;
+      }
+    }
+    if (all_equal)
+      return TRUE;
+  } else if (G_VALUE_HOLDS (value, ltype) && !G_VALUE_HOLDS (other, ltype)) {
+    const GValue *elt;
+    gint i, n;
+    gboolean all_equal = TRUE;
+
+    n = gst_value_list_get_size (value);
+    for (i = 0; i < n; i++) {
+      elt = gst_value_list_get_value (value, 0);
+      if (gst_value_compare (elt, other) != GST_VALUE_EQUAL) {
+        all_equal = FALSE;
+        break;
+      }
+    }
+    if (all_equal)
+      return TRUE;
+  }
+
   /* equal values are subset */
   if (gst_value_compare (other, value) == GST_VALUE_EQUAL)
     return TRUE;
index 235e588..cd8b9d0 100644 (file)
@@ -367,6 +367,23 @@ GST_START_TEST (test_subset)
   fail_if (gst_caps_is_subset (c1, c2));
   gst_caps_unref (c1);
   gst_caps_unref (c2);
+
+  c1 = gst_caps_from_string ("audio/x-raw-int, channels=(int) {1}");
+  c2 = gst_caps_from_string ("audio/x-raw-int, channels=(int)1");
+  fail_unless (gst_caps_is_subset (c2, c1));
+  fail_unless (gst_caps_is_subset (c1, c2));
+  fail_unless (gst_caps_is_equal (c1, c2));
+  gst_caps_unref (c1);
+  gst_caps_unref (c2);
+
+  c1 = gst_caps_from_string
+      ("audio/x-raw-int, rate=(int)44100, channels=(int)3, endianness=(int)1234, width=(int)16, depth=(int)16, signed=(boolean)false");
+  c2 = gst_caps_from_string
+      ("audio/x-raw-int, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ], endianness=(int){ 1234, 4321 }, width=(int)16, depth=(int)[ 1, 16 ], signed=(boolean){ true, false }");
+  fail_unless (gst_caps_is_subset (c1, c2));
+  fail_if (gst_caps_is_subset (c2, c1));
+  gst_caps_unref (c1);
+  gst_caps_unref (c2);
 }
 
 GST_END_TEST;