mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-18 05:16:05 +00:00
caps: keep ANY caps empty internally
Keep the ANY caps empty internally when appending and merging caps/structures. Previously, an ANY caps could end up containing internal structures, which could be fetched by the user, and gave the caps a non-zero length. Also, made sure that `gst_caps_set_features_simple` frees the features if caps is empty.
This commit is contained in:
parent
407e32588d
commit
412e97beb4
2 changed files with 147 additions and 9 deletions
|
@ -510,6 +510,20 @@ gst_caps_remove_and_get_structure (GstCaps * caps, guint idx)
|
|||
return s;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_caps_make_any (GstCaps * caps)
|
||||
{
|
||||
guint i;
|
||||
GstStructure *s;
|
||||
|
||||
/* empty out residual structures */
|
||||
for (i = GST_CAPS_LEN (caps); i; i--) {
|
||||
s = gst_caps_remove_and_get_structure (caps, 0);
|
||||
gst_structure_free (s);
|
||||
}
|
||||
GST_CAPS_FLAGS (caps) |= GST_CAPS_FLAG_ANY;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_caps_steal_structure:
|
||||
* @caps: the #GstCaps to retrieve from
|
||||
|
@ -554,7 +568,7 @@ gst_caps_append (GstCaps * caps1, GstCaps * caps2)
|
|||
g_return_if_fail (IS_WRITABLE (caps1));
|
||||
|
||||
if (G_UNLIKELY (CAPS_IS_ANY (caps1) || CAPS_IS_ANY (caps2))) {
|
||||
GST_CAPS_FLAGS (caps1) |= GST_CAPS_FLAG_ANY;
|
||||
gst_caps_make_any (caps1);
|
||||
gst_caps_unref (caps2);
|
||||
} else {
|
||||
caps2 = gst_caps_make_writable (caps2);
|
||||
|
@ -636,6 +650,13 @@ gst_caps_append_structure (GstCaps * caps, GstStructure * structure)
|
|||
g_return_if_fail (GST_IS_CAPS (caps));
|
||||
g_return_if_fail (IS_WRITABLE (caps));
|
||||
|
||||
if (CAPS_IS_ANY (caps)) {
|
||||
/* ANY caps will stay as ANY caps */
|
||||
if (structure)
|
||||
gst_structure_free (structure);
|
||||
return;
|
||||
}
|
||||
|
||||
if (G_LIKELY (structure)) {
|
||||
gst_caps_append_structure_unchecked (caps, structure, NULL);
|
||||
}
|
||||
|
@ -659,6 +680,15 @@ gst_caps_append_structure_full (GstCaps * caps, GstStructure * structure,
|
|||
g_return_if_fail (GST_IS_CAPS (caps));
|
||||
g_return_if_fail (IS_WRITABLE (caps));
|
||||
|
||||
if (CAPS_IS_ANY (caps)) {
|
||||
/* ANY caps will stay as ANY caps */
|
||||
if (structure)
|
||||
gst_structure_free (structure);
|
||||
if (features)
|
||||
gst_caps_features_free (features);
|
||||
return;
|
||||
}
|
||||
|
||||
if (G_LIKELY (structure)) {
|
||||
gst_caps_append_structure_unchecked (caps, structure, features);
|
||||
}
|
||||
|
@ -707,6 +737,12 @@ gst_caps_merge_structure (GstCaps * caps, GstStructure * structure)
|
|||
if (G_UNLIKELY (structure == NULL))
|
||||
return caps;
|
||||
|
||||
if (CAPS_IS_ANY (caps)) {
|
||||
/* ANY caps will stay as ANY caps */
|
||||
gst_structure_free (structure);
|
||||
return caps;
|
||||
}
|
||||
|
||||
/* check each structure */
|
||||
for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
|
||||
structure1 = gst_caps_get_structure_unchecked (caps, i);
|
||||
|
@ -758,6 +794,14 @@ gst_caps_merge_structure_full (GstCaps * caps, GstStructure * structure,
|
|||
if (G_UNLIKELY (structure == NULL))
|
||||
return caps;
|
||||
|
||||
if (CAPS_IS_ANY (caps)) {
|
||||
/* ANY caps will stay as ANY caps */
|
||||
gst_structure_free (structure);
|
||||
if (features)
|
||||
gst_caps_features_free (features);
|
||||
return caps;
|
||||
}
|
||||
|
||||
/* To make comparisons easier below */
|
||||
features_tmp = features ? features : GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
|
||||
|
||||
|
@ -951,6 +995,13 @@ gst_caps_set_features_simple (GstCaps * caps, GstCapsFeatures * features)
|
|||
|
||||
n = gst_caps_get_size (caps);
|
||||
|
||||
if (n == 0) {
|
||||
/* features will not be set on any structure */
|
||||
if (features)
|
||||
gst_caps_features_free (features);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
GstCapsFeatures *f;
|
||||
|
||||
|
@ -1182,9 +1233,7 @@ 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 */
|
||||
/* double check not ANY, even though ANY caps should have 0 length */
|
||||
if (CAPS_IS_ANY (caps))
|
||||
return FALSE;
|
||||
|
||||
|
@ -1433,9 +1482,7 @@ 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 both are ANY caps, consider them strictly equal */
|
||||
if (CAPS_IS_ANY (caps1))
|
||||
return (CAPS_IS_ANY (caps2));
|
||||
else if (CAPS_IS_ANY (caps2))
|
||||
|
|
|
@ -60,7 +60,7 @@ GST_START_TEST (test_double_append)
|
|||
GstStructure *s1;
|
||||
GstCaps *c1;
|
||||
|
||||
c1 = gst_caps_new_any ();
|
||||
c1 = gst_caps_new_empty ();
|
||||
s1 = gst_structure_from_string ("audio/x-raw,rate=44100", NULL);
|
||||
gst_caps_append_structure (c1, s1);
|
||||
ASSERT_CRITICAL (gst_caps_append_structure (c1, s1));
|
||||
|
@ -76,7 +76,7 @@ GST_START_TEST (test_mutability)
|
|||
GstCaps *c1;
|
||||
gint ret;
|
||||
|
||||
c1 = gst_caps_new_any ();
|
||||
c1 = gst_caps_new_empty ();
|
||||
s1 = gst_structure_from_string ("audio/x-raw,rate=44100", NULL);
|
||||
gst_structure_set (s1, "rate", G_TYPE_INT, 48000, NULL);
|
||||
gst_caps_append_structure (c1, s1);
|
||||
|
@ -1259,6 +1259,18 @@ GST_START_TEST (test_features)
|
|||
fail_unless (gst_caps_features_is_equal (f1, f2));
|
||||
|
||||
gst_caps_unref (c1);
|
||||
|
||||
c1 = gst_caps_new_any ();
|
||||
fail_unless_equals_int (gst_caps_get_size (c1), 0);
|
||||
|
||||
f1 = gst_caps_features_new ("memory:EGLImage", NULL);
|
||||
/* Nothing to set the features on, but method should still take
|
||||
* ownership of the given features */
|
||||
gst_caps_set_features_simple (c1, f1);
|
||||
fail_unless_equals_int (gst_caps_get_size (c1), 0);
|
||||
fail_unless (gst_caps_is_any (c1));
|
||||
|
||||
gst_caps_unref (c1);
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
@ -1425,6 +1437,7 @@ GST_START_TEST (test_equality)
|
|||
G_TYPE_FLOAT, 5.7, NULL);
|
||||
fail_unless (s);
|
||||
gst_caps_append_structure (any2, s);
|
||||
/* should still be ANY after append */
|
||||
|
||||
caps1 = gst_caps_new_simple ("structure", "int", G_TYPE_INT, 4, "float",
|
||||
G_TYPE_FLOAT, 5.7, NULL);
|
||||
|
@ -1603,6 +1616,83 @@ GST_START_TEST (test_equality)
|
|||
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST (test_remains_any)
|
||||
{
|
||||
GstCaps *any, *caps;
|
||||
GstStructure *s;
|
||||
|
||||
/* test append structure to ANY */
|
||||
any = gst_caps_new_any ();
|
||||
fail_unless (gst_caps_is_any (any));
|
||||
fail_if (gst_caps_get_size (any));
|
||||
s = gst_structure_new ("structure", "int", G_TYPE_INT, 4, NULL);
|
||||
fail_unless (s);
|
||||
gst_caps_append_structure (any, s);
|
||||
fail_unless (gst_caps_is_any (any));
|
||||
fail_if (gst_caps_get_size (any));
|
||||
ASSERT_CRITICAL (gst_caps_get_structure (any, 0));
|
||||
|
||||
s = gst_structure_new ("structure", "int", G_TYPE_INT, 4, NULL);
|
||||
fail_unless (s);
|
||||
gst_caps_append_structure_full (any, s, gst_caps_features_new_any ());
|
||||
fail_unless (gst_caps_is_any (any));
|
||||
fail_if (gst_caps_get_size (any));
|
||||
ASSERT_CRITICAL (gst_caps_get_structure (any, 0));
|
||||
|
||||
/* test merge structure with ANY */
|
||||
s = gst_structure_new ("structure", "int", G_TYPE_INT, 4, NULL);
|
||||
fail_unless (s);
|
||||
any = gst_caps_merge_structure (any, s);
|
||||
fail_unless (gst_caps_is_any (any));
|
||||
fail_if (gst_caps_get_size (any));
|
||||
ASSERT_CRITICAL (gst_caps_get_structure (any, 0));
|
||||
|
||||
s = gst_structure_new ("structure", "int", G_TYPE_INT, 4, NULL);
|
||||
fail_unless (s);
|
||||
any = gst_caps_merge_structure_full (any, s, gst_caps_features_new_any ());
|
||||
fail_unless (gst_caps_is_any (any));
|
||||
fail_if (gst_caps_get_size (any));
|
||||
ASSERT_CRITICAL (gst_caps_get_structure (any, 0));
|
||||
|
||||
/* test appending non-ANY to ANY */
|
||||
caps = gst_caps_new_simple ("structure", "int", G_TYPE_INT, 4, NULL);
|
||||
fail_unless (caps);
|
||||
gst_caps_append (any, caps);
|
||||
fail_unless (gst_caps_is_any (any));
|
||||
fail_if (gst_caps_get_size (any));
|
||||
ASSERT_CRITICAL (gst_caps_get_structure (any, 0));
|
||||
|
||||
/* test merging non-ANY with ANY */
|
||||
caps = gst_caps_new_simple ("structure", "int", G_TYPE_INT, 4, NULL);
|
||||
fail_unless (caps);
|
||||
any = gst_caps_merge (any, caps);
|
||||
fail_unless (gst_caps_is_any (any));
|
||||
fail_if (gst_caps_get_size (any));
|
||||
ASSERT_CRITICAL (gst_caps_get_structure (any, 0));
|
||||
|
||||
caps = gst_caps_new_simple ("structure", "int", G_TYPE_INT, 4, NULL);
|
||||
fail_unless (caps);
|
||||
any = gst_caps_merge (caps, any);
|
||||
fail_unless (gst_caps_is_any (any));
|
||||
fail_if (gst_caps_get_size (any));
|
||||
ASSERT_CRITICAL (gst_caps_get_structure (any, 0));
|
||||
|
||||
gst_caps_unref (any);
|
||||
|
||||
/* test appending ANY to non-ANY */
|
||||
caps = gst_caps_new_simple ("structure", "int", G_TYPE_INT, 4, NULL);
|
||||
fail_unless (caps);
|
||||
fail_unless_equals_int (gst_caps_get_size (caps), 1);
|
||||
fail_unless (gst_caps_get_structure (caps, 0));
|
||||
gst_caps_append (caps, gst_caps_new_any ());
|
||||
fail_unless (gst_caps_is_any (caps));
|
||||
fail_if (gst_caps_get_size (caps));
|
||||
ASSERT_CRITICAL (gst_caps_get_structure (caps, 0));
|
||||
|
||||
gst_caps_unref (caps);
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
static Suite *
|
||||
gst_caps_suite (void)
|
||||
|
@ -1639,6 +1729,7 @@ gst_caps_suite (void)
|
|||
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);
|
||||
tcase_add_test (tc_chain, test_remains_any);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue