gst/gstformat.c: Fix locking order (must take lock before using n_values).
authorTim-Philipp Müller <tim@centricular.net>
Sun, 17 Sep 2006 19:26:16 +0000 (19:26 +0000)
committerTim-Philipp Müller <tim@centricular.net>
Sun, 17 Sep 2006 19:26:16 +0000 (19:26 +0000)
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.

ChangeLog
gst/gstformat.c
gst/gstvalue.c
tests/check/gst/gstvalue.c

index a2603a3..324da83 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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:
index 3e00061..b047c1c 100644 (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);
index 3142f88..abcb93e 100644 (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;
index b9c38be..fd60b21 100644 (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);