caps: Merge structures when intersecting instead of appending them

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.
This commit is contained in:
Sebastian Dröge 2011-05-05 11:28:38 +02:00
parent aebe4a3c13
commit dc63e38219
2 changed files with 21 additions and 2 deletions

View 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);
}
}

View 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);