caps: improve _do_simplify

Make gst_caps_do_simplify() take ownership of the input caps and produce a
simplified output caps. This removes the requirement of having writable input
caps and the method can make the caps writable only when needed.
This commit is contained in:
Wim Taymans 2012-03-12 10:42:23 +01:00
parent 6886be59f5
commit 9cdbffea94
5 changed files with 25 additions and 37 deletions

View file

@ -1498,7 +1498,7 @@ gst_caps_subtract (GstCaps * minuend, GstCaps * subtrahend)
} }
gst_caps_unref (src); gst_caps_unref (src);
gst_caps_do_simplify (dest); dest = gst_caps_do_simplify (dest);
return dest; return dest;
} }
@ -1575,7 +1575,7 @@ gst_caps_union (GstCaps * caps1, GstCaps * caps2)
dest1 = _gst_caps_copy (caps1); dest1 = _gst_caps_copy (caps1);
gst_caps_append (dest1, gst_caps_ref (caps2)); gst_caps_append (dest1, gst_caps_ref (caps2));
gst_caps_do_simplify (dest1); dest1 = gst_caps_do_simplify (dest1);
return dest1; return dest1;
} }
@ -1765,36 +1765,36 @@ gst_caps_switch_structures (GstCaps * caps, GstStructure * old,
/** /**
* gst_caps_do_simplify: * gst_caps_do_simplify:
* @caps: a #GstCaps to simplify * @caps: (transfer full): a #GstCaps to simplify
* *
* Modifies the given @caps inplace into a representation that represents the * Modifies the given @caps inplace into a representation that represents the
* same set of formats, but in a simpler form. Component structures that are * same set of formats, but in a simpler form. Component structures that are
* identical are merged. Component structures that have values that can be * identical are merged. Component structures that have values that can be
* merged are also merged. * merged are also merged.
* *
* Returns: TRUE, if the caps could be simplified * Returns: The simplified caps.
*/ */
gboolean GstCaps *
gst_caps_do_simplify (GstCaps * caps) gst_caps_do_simplify (GstCaps * caps)
{ {
GstStructure *simplify, *compare, *result = NULL; GstStructure *simplify, *compare, *result = NULL;
gint i, j, start; gint i, j, start;
gboolean changed = FALSE;
g_return_val_if_fail (caps != NULL, FALSE); g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
g_return_val_if_fail (IS_WRITABLE (caps), FALSE);
if (gst_caps_get_size (caps) < 2) if (gst_caps_is_fixed (caps))
return FALSE; return caps;
caps = gst_caps_make_writable (caps);
g_ptr_array_sort (GST_CAPS_ARRAY (caps), gst_caps_compare_structures); g_ptr_array_sort (GST_CAPS_ARRAY (caps), gst_caps_compare_structures);
start = GST_CAPS_LEN (caps) - 1; start = GST_CAPS_LEN (caps) - 1;
for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) { for (i = start; i >= 0; i--) {
simplify = gst_caps_get_structure_unchecked (caps, i); simplify = gst_caps_get_structure_unchecked (caps, i);
compare = gst_caps_get_structure_unchecked (caps, start);
if (gst_structure_get_name_id (simplify) != if (gst_structure_get_name_id (simplify) !=
gst_structure_get_name_id (gst_caps_get_structure_unchecked (caps, gst_structure_get_name_id (compare))
start)))
start = i; start = i;
for (j = start; j >= 0; j--) { for (j = start; j >= 0; j--) {
if (j == i) if (j == i)
@ -1813,16 +1813,10 @@ gst_caps_do_simplify (GstCaps * caps)
start--; start--;
break; break;
} }
changed = TRUE;
} }
} }
} }
return caps;
if (!changed)
return FALSE;
/* gst_caps_do_simplify (caps); */
return TRUE;
} }
/** /**

View file

@ -438,7 +438,7 @@ GstCaps * gst_caps_subtract (GstCaps *minuend,
GstCaps * gst_caps_union (GstCaps *caps1, GstCaps * gst_caps_union (GstCaps *caps1,
GstCaps *caps2) G_GNUC_WARN_UNUSED_RESULT; GstCaps *caps2) G_GNUC_WARN_UNUSED_RESULT;
GstCaps * gst_caps_normalize (GstCaps *caps) G_GNUC_WARN_UNUSED_RESULT; GstCaps * gst_caps_normalize (GstCaps *caps) G_GNUC_WARN_UNUSED_RESULT;
gboolean gst_caps_do_simplify (GstCaps *caps); GstCaps * gst_caps_do_simplify (GstCaps *caps) G_GNUC_WARN_UNUSED_RESULT;
GstCaps * gst_caps_fixate (GstCaps *caps) G_GNUC_WARN_UNUSED_RESULT; GstCaps * gst_caps_fixate (GstCaps *caps) G_GNUC_WARN_UNUSED_RESULT;

View file

@ -321,16 +321,13 @@ gst_registry_chunks_save_feature (GList ** list, GstPluginFeature * feature)
} }
/* save caps */ /* save caps */
if (factory->caps) { if (factory->caps) {
/* we copy the caps here so we can simplify them before saving. This GstCaps *fcaps = gst_caps_ref (factory->caps);
* is a lot faster when loading them later on */ /* we simplify the caps before saving. This is a lot faster
if (!gst_caps_is_fixed (factory->caps)) { * when loading them later on */
GstCaps *copy = gst_caps_copy (factory->caps); fcaps = gst_caps_do_simplify (fcaps);
gst_caps_do_simplify (copy); str = gst_caps_to_string (fcaps);
str = gst_caps_to_string (copy); gst_caps_unref (fcaps);
gst_caps_unref (copy);
} else {
str = gst_caps_to_string (factory->caps);
}
gst_registry_chunks_save_string (list, str); gst_registry_chunks_save_string (list, str);
} else { } else {
gst_registry_chunks_save_const_string (list, ""); gst_registry_chunks_save_const_string (list, "");

View file

@ -298,8 +298,7 @@ gst_capsfilter_prepare_buf (GstBaseTransform * trans, GstBuffer * input,
g_return_val_if_fail (out_caps != NULL, GST_FLOW_ERROR); g_return_val_if_fail (out_caps != NULL, GST_FLOW_ERROR);
} }
out_caps = gst_caps_make_writable (out_caps); out_caps = gst_caps_do_simplify (out_caps);
gst_caps_do_simplify (out_caps);
if (gst_caps_is_fixed (out_caps) && !gst_caps_is_empty (out_caps)) { if (gst_caps_is_fixed (out_caps) && !gst_caps_is_empty (out_caps)) {
GST_DEBUG_OBJECT (trans, "Have fixed output caps %" GST_DEBUG_OBJECT (trans, "Have fixed output caps %"

View file

@ -190,16 +190,14 @@ check_string_list (const GValue * format_value)
GST_START_TEST (test_simplify) GST_START_TEST (test_simplify)
{ {
GstStructure *s1; GstStructure *s1;
gboolean did_simplify;
GstCaps *caps; GstCaps *caps;
caps = gst_caps_from_string (non_simple_caps_string); caps = gst_caps_from_string (non_simple_caps_string);
fail_unless (caps != NULL, fail_unless (caps != NULL,
"gst_caps_from_string (non_simple_caps_string) failed"); "gst_caps_from_string (non_simple_caps_string) failed");
did_simplify = gst_caps_do_simplify (caps); caps = gst_caps_do_simplify (caps);
fail_unless (did_simplify == TRUE, fail_unless (caps != NULL, "gst_caps_do_simplify() should have worked");
"gst_caps_do_simplify() should have worked");
/* check simplified caps, should be: /* check simplified caps, should be:
* *