From 007c0e5fe155abbc3fc0d801c47ba7388cda3f48 Mon Sep 17 00:00:00 2001 From: Thiago Santos Date: Wed, 25 Sep 2013 19:06:55 -0300 Subject: [PATCH] value: fix caps serialization when there are caps inside caps Wrap caps strings so that it can handle serialization and deserialization of caps inside caps. Otherwise the values from the internal caps are parsed as if they were from the upper one https://bugzilla.gnome.org/show_bug.cgi?id=708772 --- gst/gstcaps.c | 12 ++++++++++++ gst/gststructure.c | 12 ++++++++++++ gst/gstvalue.c | 15 ++++++++++++--- tests/check/gst/gstvalue.c | 8 +++++++- 4 files changed, 43 insertions(+), 4 deletions(-) diff --git a/gst/gstcaps.c b/gst/gstcaps.c index 7e10a2a212..fbe9c1813d 100644 --- a/gst/gstcaps.c +++ b/gst/gstcaps.c @@ -56,6 +56,12 @@ * Various methods exist to work with the media types such as subtracting * or intersecting. * + * Be aware that the current #GstCaps / #GstStructure serialization into string + * has limited support for nested #GstCaps / #GstStructure fields. It can only + * support one level of nesting. Using more levels will lead to unexpected + * behavior when using serialization features, such as gst_caps_to_string() or + * gst_value_serialize() and their counterparts. + * * Last reviewed on 2011-03-28 (0.11.3) */ @@ -2129,6 +2135,9 @@ gst_caps_fixate (GstCaps * caps) * ]| * This prints the caps in human readable form. * + * The current implementation of serialization will lead to unexpected results + * when there are nested #GstCaps / #GstStructure deeper than one level. + * * Returns: (transfer full): a newly allocated string representing @caps. */ gchar * @@ -2298,6 +2307,9 @@ gst_caps_from_string_inplace (GstCaps * caps, const gchar * string) * * Converts @caps from a string representation. * + * The current implementation of serialization will lead to unexpected results + * when there are nested #GstCaps / #GstStructure deeper than one level. + * * Returns: (transfer full): a newly allocated #GstCaps */ GstCaps * diff --git a/gst/gststructure.c b/gst/gststructure.c index f164d163df..6f7f6097da 100644 --- a/gst/gststructure.c +++ b/gst/gststructure.c @@ -53,6 +53,12 @@ * Strings in structures must be ASCII or UTF-8 encoded. Other encodings are * not allowed. Strings must not be empty either, but may be NULL. * + * Be aware that the current #GstCaps / #GstStructure serialization into string + * has limited support for nested #GstCaps / #GstStructure fields. It can only + * support one level of nesting. Using more levels will lead to unexpected + * behavior when using serialization features, such as gst_caps_to_string() or + * gst_value_serialize() and their counterparts. + * * Last reviewed on 2012-03-29 (0.11.3) */ @@ -1817,6 +1823,9 @@ priv_gst_structure_append_to_gstring (const GstStructure * structure, * ]| * This prints the structure in human readble form. * + * The current implementation of serialization will lead to unexpected results + * when there are nested #GstCaps / #GstStructure deeper than one level. + * * Free-function: g_free * * Returns: (transfer full): a pointer to string allocated by g_malloc(). @@ -2315,6 +2324,9 @@ priv_gst_structure_parse_fields (gchar * str, gchar ** end, * If end is not NULL, a pointer to the place inside the given string * where parsing ended will be returned. * + * The current implementation of serialization will lead to unexpected results + * when there are nested #GstCaps / #GstStructure deeper than one level. + * * Free-function: gst_structure_free * * Returns: (transfer full): a new #GstStructure or NULL when the string could diff --git a/gst/gstvalue.c b/gst/gstvalue.c index c2885cdee6..9dadb85912 100644 --- a/gst/gstvalue.c +++ b/gst/gstvalue.c @@ -1887,8 +1887,7 @@ static gchar * gst_value_serialize_caps (const GValue * value) { GstCaps *caps = g_value_get_boxed (value); - - return gst_caps_to_string (caps); + return gst_string_take_and_wrap (gst_caps_to_string (caps)); } static gboolean @@ -1896,7 +1895,17 @@ gst_value_deserialize_caps (GValue * dest, const gchar * s) { GstCaps *caps; - caps = gst_caps_from_string (s); + if (*s != '"') { + caps = gst_caps_from_string (s); + } else { + gchar *str = gst_string_unwrap (s); + + if (G_UNLIKELY (!str)) + return FALSE; + + caps = gst_caps_from_string (str); + g_free (str); + } if (caps) { g_value_take_boxed (dest, caps); diff --git a/tests/check/gst/gstvalue.c b/tests/check/gst/gstvalue.c index babe9148ce..fcb7220b7d 100644 --- a/tests/check/gst/gstvalue.c +++ b/tests/check/gst/gstvalue.c @@ -2379,11 +2379,17 @@ GST_START_TEST (test_serialize_deserialize_caps) , value2 = { 0}; GstCaps *caps, *caps2; + GstCaps *incaps; gchar *serialized; + incaps = gst_caps_new_simple ("caps/internal", + "in-field", G_TYPE_INT, 20, "in-field2", + G_TYPE_STRING, "some in ternal field", NULL); caps = gst_caps_new_simple ("test/caps", - "foo", G_TYPE_INT, 10, "bar", G_TYPE_STRING, "test", NULL); + "foo", G_TYPE_INT, 10, "bar", G_TYPE_STRING, "test", + "int-caps", GST_TYPE_CAPS, incaps, NULL); fail_if (GST_CAPS_REFCOUNT_VALUE (caps) != 1); + gst_caps_unref (incaps); /* and assign caps to gvalue */ g_value_init (&value, GST_TYPE_CAPS);