gst/gstformat.c: Fix locking order (must take lock before using n_values).

Original commit message from CVS:
* gst/gstformat.c: (gst_format_register):
Fix locking order (must take lock before using n_values).
* gst/gstvalue.c: (gst_value_serialize_enum),
(gst_value_deserialize_enum_iter_cmp),
(gst_value_deserialize_enum):
Fix serialisation/deserialisation of custom registered GstFormats.
* tests/check/gst/gstvalue.c: (GST_START_TEST), (gst_value_suite):
Unit test for custom format serialisation/deserialisation.
This commit is contained in:
Tim-Philipp Müller 2006-09-17 19:26:16 +00:00
parent 139e6f8be4
commit f3c07d5d20
4 changed files with 91 additions and 1 deletions

View file

@ -1,3 +1,16 @@
2006-09-17 Tim-Philipp Müller <tim at centricular dot net>
* gst/gstformat.c: (gst_format_register):
Fix locking order (must take lock before using n_values).
* gst/gstvalue.c: (gst_value_serialize_enum),
(gst_value_deserialize_enum_iter_cmp),
(gst_value_deserialize_enum):
Fix serialisation/deserialisation of custom registered GstFormats.
* tests/check/gst/gstvalue.c: (GST_START_TEST), (gst_value_suite):
Unit test for custom format serialisation/deserialisation.
2006-09-17 Stefan Kost <ensonic@users.sf.net>
* docs/pwg/building-boiler.xml:

View file

@ -150,13 +150,13 @@ gst_format_register (const gchar * nick, const gchar * description)
if (query != GST_FORMAT_UNDEFINED)
return query;
g_static_mutex_lock (&mutex);
format = g_new0 (GstFormatDefinition, 1);
format->value = _n_values;
format->nick = g_strdup (nick);
format->description = g_strdup (description);
format->quark = g_quark_from_static_string (format->nick);
g_static_mutex_lock (&mutex);
g_hash_table_insert (_nick_to_format, format->nick, format);
g_hash_table_insert (_format_to_nick, GINT_TO_POINTER (format->value),
format);

View file

@ -1911,10 +1911,30 @@ gst_value_serialize_enum (const GValue * value)
g_return_val_if_fail (klass, NULL);
en = g_enum_get_value (klass, g_value_get_enum (value));
g_type_class_unref (klass);
/* might be one of the custom formats registered later */
if (G_UNLIKELY (en == NULL && G_VALUE_TYPE (value) == GST_TYPE_FORMAT)) {
const GstFormatDefinition *format_def;
format_def = gst_format_get_details (g_value_get_enum (value));
g_return_val_if_fail (format_def != NULL, NULL);
return g_strdup (format_def->description);
}
g_return_val_if_fail (en, NULL);
return g_strdup (en->value_name);
}
static gint
gst_value_deserialize_enum_iter_cmp (const GstFormatDefinition * format_def,
const gchar * s)
{
if (g_ascii_strcasecmp (s, format_def->nick) == 0)
return 0;
return g_ascii_strcasecmp (s, format_def->description);
}
static gboolean
gst_value_deserialize_enum (GValue * dest, const gchar * s)
{
@ -1933,6 +1953,23 @@ gst_value_deserialize_enum (GValue * dest, const gchar * s)
}
}
g_type_class_unref (klass);
/* might be one of the custom formats registered later */
if (G_UNLIKELY (en == NULL && G_VALUE_TYPE (dest) == GST_TYPE_FORMAT)) {
const GstFormatDefinition *format_def;
GstIterator *iter;
iter = gst_format_iterate_definitions ();
format_def = gst_iterator_find_custom (iter,
(GCompareFunc) gst_value_deserialize_enum_iter_cmp, (gpointer) s);
g_return_val_if_fail (format_def != NULL, FALSE);
g_value_set_enum (dest, (gint) format_def->value);
gst_iterator_free (iter);
return TRUE;
}
g_return_val_if_fail (en, FALSE);
g_value_set_enum (dest, en->value);
return TRUE;

View file

@ -1579,6 +1579,45 @@ GST_START_TEST (test_fraction_range)
GST_END_TEST;
GST_START_TEST (test_serialize_deserialize_format_enum)
{
GstStructure *s, *s2;
GstFormat foobar_fmt;
gchar *str, *str2, *end = NULL;
/* make sure custom formats are serialised properly as well */
foobar_fmt = gst_format_register ("foobar", "GST_FORMAT_FOOBAR");
fail_unless (foobar_fmt != GST_FORMAT_UNDEFINED);
s = gst_structure_new ("foo/bar", "format1", GST_TYPE_FORMAT,
GST_FORMAT_BYTES, "format2", GST_TYPE_FORMAT, GST_FORMAT_TIME,
"format3", GST_TYPE_FORMAT, GST_FORMAT_DEFAULT, "format4",
GST_TYPE_FORMAT, foobar_fmt, NULL);
str = gst_structure_to_string (s);
GST_LOG ("Got structure string '%s'", GST_STR_NULL (str));
fail_unless (str != NULL);
fail_unless (strstr (str, "TIME") != NULL);
fail_unless (strstr (str, "BYTE") != NULL);
fail_unless (strstr (str, "DEFAULT") != NULL);
fail_unless (strstr (str, "FOOBAR") != NULL);
s2 = gst_structure_from_string (str, &end);
fail_unless (s2 != NULL);
str2 = gst_structure_to_string (s2);
fail_unless (str2 != NULL);
fail_unless (g_str_equal (str, str2));
g_free (str);
g_free (str2);
gst_structure_free (s);
gst_structure_free (s2);
}
GST_END_TEST;
Suite *
gst_value_suite (void)
{
@ -1596,6 +1635,7 @@ gst_value_suite (void)
tcase_add_test (tc_chain, test_deserialize_gstfraction);
tcase_add_test (tc_chain, test_serialize_flags);
tcase_add_test (tc_chain, test_deserialize_flags);
tcase_add_test (tc_chain, test_serialize_deserialize_format_enum);
tcase_add_test (tc_chain, test_string);
tcase_add_test (tc_chain, test_deserialize_string);
tcase_add_test (tc_chain, test_value_compare);