caps: Merge structures when intersecting instead of appending them
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Thu, 5 May 2011 09:28:38 +0000 (11:28 +0200)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Thu, 5 May 2011 13:22:14 +0000 (15:22 +0200)
This prevents adding duplicates over and over again to the resulting
caps if they already describe the new intersection result.

While this changes intersection from O(n*m) to O(n^2*m), it results in
smaller caps, which in the end will decrease further processing times.

For example in an audioconvert ! audioconvert ! audioconvert pipeline,
when forwarding the downstream caps preference in basetransform
(see e26da72de25a91c3eaad9f7c8b2f53ba888a0394) this results in
16 instead of 191 caps structures.

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

index 09724d0..f0cce6d 100644 (file)
@@ -1361,7 +1361,7 @@ gst_caps_intersect_zig_zag (const GstCaps * caps1, const GstCaps * caps2)
 
       istruct = gst_caps_structure_intersect (struct1, struct2);
 
-      gst_caps_append_structure (dest, istruct);
+      gst_caps_merge_structure (dest, istruct);
       /* move down left */
       k++;
       if (G_UNLIKELY (j == 0))
@@ -1420,7 +1420,7 @@ gst_caps_intersect_first (const GstCaps * caps1, const GstCaps * caps2)
       struct2 = gst_caps_get_structure_unchecked (caps2, j);
       istruct = gst_caps_structure_intersect (struct1, struct2);
       if (istruct)
-        gst_caps_append_structure (dest, istruct);
+        gst_caps_merge_structure (dest, istruct);
     }
   }
 
index fa160d9..a22c15f 100644 (file)
@@ -811,6 +811,24 @@ GST_START_TEST (test_intersect_first2)
 
 GST_END_TEST;
 
+GST_START_TEST (test_intersect_duplication)
+{
+  GstCaps *c1, *c2, *test;
+
+  c1 = gst_caps_from_string
+      ("audio/x-raw-int, endianness=(int)1234, signed=(boolean)true, width=(int)16, depth=(int)16, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2 ]");
+  c2 = gst_caps_from_string
+      ("audio/x-raw-int, width=(int)16, depth=(int)16, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2 ], endianness=(int){ 1234, 4321 }, signed=(boolean){ true, false }; audio/x-raw-int, width=(int)16, depth=(int)16, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 11 ], endianness=(int){ 1234, 4321 }, signed=(boolean){ true, false }; audio/x-raw-int, width=(int)16, depth=(int)[ 1, 16 ], rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 11 ], endianness=(int){ 1234, 4321 }, signed=(boolean){ true, false }");
+
+  test = gst_caps_intersect_full (c1, c2, GST_CAPS_INTERSECT_FIRST);
+  fail_unless_equals_int (gst_caps_get_size (test), 1);
+  fail_unless (gst_caps_is_equal (c1, test));
+  gst_caps_unref (c1);
+  gst_caps_unref (c2);
+  gst_caps_unref (test);
+}
+
+GST_END_TEST;
 
 static gboolean
 _caps_is_fixed_foreach (GQuark field_id, const GValue * value, gpointer unused)
@@ -921,6 +939,7 @@ gst_caps_suite (void)
   tcase_add_test (tc_chain, test_intersect_zigzag);
   tcase_add_test (tc_chain, test_intersect_first);
   tcase_add_test (tc_chain, test_intersect_first2);
+  tcase_add_test (tc_chain, test_intersect_duplication);
   tcase_add_test (tc_chain, test_normalize);
   tcase_add_test (tc_chain, test_broken);