taglist: add gst_tag_list_is_equal()
authorTim-Philipp Müller <tim.muller@collabora.co.uk>
Sat, 29 Oct 2011 23:44:44 +0000 (00:44 +0100)
committerTim-Philipp Müller <tim.muller@collabora.co.uk>
Sun, 30 Oct 2011 00:44:00 +0000 (01:44 +0100)
API: gst_tag_list_is_equal()

docs/gst/gstreamer-sections.txt
gst/gsttaglist.c
gst/gsttaglist.h
tests/check/gst/gsttag.c
win32/common/libgstreamer.def

index c29ac05..5373972 100644 (file)
@@ -2368,6 +2368,7 @@ gst_tag_list_new_full
 gst_tag_list_new_full_valist
 gst_is_tag_list
 gst_tag_list_is_empty
+gst_tag_list_is_equal
 gst_tag_list_copy
 gst_tag_list_insert
 gst_tag_list_merge
index 385e3b0..b46a962 100644 (file)
@@ -35,6 +35,7 @@
 #endif
 
 #include "gst_private.h"
+#include "math-compat.h"
 #include "gst-i18n-lib.h"
 #include "gsttaglist.h"
 #include "gstinfo.h"
@@ -709,6 +710,77 @@ gst_tag_list_is_empty (const GstTagList * list)
   return (gst_structure_n_fields ((GstStructure *) list) == 0);
 }
 
+static gboolean
+gst_tag_list_fields_equal (const GValue * value1, const GValue * value2)
+{
+  gdouble d1, d2;
+
+  if (gst_value_compare (value1, value2) == GST_VALUE_EQUAL)
+    return TRUE;
+
+  /* fields not equal: add some tolerance for doubles, otherwise bail out */
+  if (!G_VALUE_HOLDS_DOUBLE (value1) || !G_VALUE_HOLDS_DOUBLE (value2))
+    return FALSE;
+
+  d1 = g_value_get_double (value1);
+  d2 = g_value_get_double (value2);
+
+  /* This will only work for 'normal' values and values around 0,
+   * which should be good enough for our purposes here
+   * FIXME: maybe add this to gst_value_compare_double() ? */
+  return (fabs (d1 - d2) < 0.0000001);
+}
+
+/**
+ * gst_tag_list_is_equal:
+ * @list1: a #GstTagList.
+ * @list2: a #GstTagList.
+ *
+ * Checks if the two given taglists are equal.
+ *
+ * Returns: TRUE if the taglists are equal, otherwise FALSE
+ *
+ * Since: 0.10.36
+ */
+gboolean
+gst_tag_list_is_equal (const GstTagList * list1, const GstTagList * list2)
+{
+  const GstStructure *s1, *s2;
+  gint num_fields1, num_fields2, i;
+
+  g_return_val_if_fail (GST_IS_TAG_LIST (list1), FALSE);
+  g_return_val_if_fail (GST_IS_TAG_LIST (list2), FALSE);
+
+  /* we don't just use gst_structure_is_equal() here so we can add some
+   * tolerance for doubles, though maybe we should just add that to
+   * gst_value_compare_double() as well? */
+  s1 = (const GstStructure *) list1;
+  s2 = (const GstStructure *) list2;
+
+  num_fields1 = gst_structure_n_fields (s1);
+  num_fields2 = gst_structure_n_fields (s2);
+
+  if (num_fields1 != num_fields2)
+    return FALSE;
+
+  for (i = 0; i < num_fields1; i++) {
+    const GValue *value1, *value2;
+    const gchar *tag_name;
+
+    tag_name = gst_structure_nth_field_name (s1, i);
+    value1 = gst_structure_get_value (s1, tag_name);
+    value2 = gst_structure_get_value (s2, tag_name);
+
+    if (value2 == NULL)
+      return FALSE;
+
+    if (!gst_tag_list_fields_equal (value1, value2))
+      return FALSE;
+  }
+
+  return TRUE;
+}
+
 /**
  * gst_is_tag_list:
  * @p: Object that might be a taglist
index e40d52a..cc0601f 100644 (file)
@@ -218,6 +218,8 @@ GstTagList * gst_tag_list_new_full_valist   (va_list var_args);
 gboolean     gst_is_tag_list                (gconstpointer p);
 GstTagList * gst_tag_list_copy              (const GstTagList * list);
 gboolean     gst_tag_list_is_empty          (const GstTagList * list);
+gboolean     gst_tag_list_is_equal          (const GstTagList * list1,
+                                             const GstTagList * list2);
 void         gst_tag_list_insert            (GstTagList       * into,
                                              const GstTagList * from,
                                              GstTagMergeMode    mode);
index ecf8223..7efcf2c 100644 (file)
@@ -281,6 +281,7 @@ GST_START_TEST (test_date_tags)
   tag_list2 = gst_structure_from_string (str, NULL);
   fail_if (tag_list2 == NULL);
   fail_if (!gst_tag_list_get_date (tag_list2, GST_TAG_DATE, &date2));
+  fail_unless (gst_tag_list_is_equal (tag_list2, tag_list));
   gst_tag_list_free (tag_list2);
   g_free (str);
 
@@ -452,6 +453,43 @@ GST_START_TEST (test_merge_strings_with_comma)
 
 GST_END_TEST;
 
+GST_START_TEST (test_equal)
+{
+  GstTagList *tags, *tags2;
+
+  tags = gst_tag_list_new ();
+  gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_ARTIST, "Foo", NULL);
+  gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_ARTIST, "Bar", NULL);
+  gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_ARTIST, "Yay", NULL);
+
+  tags2 = gst_tag_list_new ();
+  fail_unless (!gst_tag_list_is_equal (tags2, tags));
+  gst_tag_list_add (tags2, GST_TAG_MERGE_APPEND, GST_TAG_ARTIST, "Yay", NULL);
+  fail_unless (!gst_tag_list_is_equal (tags2, tags));
+  gst_tag_list_add (tags2, GST_TAG_MERGE_APPEND, GST_TAG_ARTIST, "Bar", NULL);
+  fail_unless (!gst_tag_list_is_equal (tags2, tags));
+  gst_tag_list_add (tags2, GST_TAG_MERGE_APPEND, GST_TAG_ARTIST, "Foo", NULL);
+  fail_unless (gst_tag_list_is_equal (tags2, tags));
+
+  gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_REFERENCE_LEVEL,
+      9.87654321, NULL);
+  fail_unless (!gst_tag_list_is_equal (tags2, tags));
+  gst_tag_list_add (tags2, GST_TAG_MERGE_APPEND, GST_TAG_REFERENCE_LEVEL,
+      9.87654320, NULL);
+  /* want these two double values to be equal despite minor differences */
+  fail_unless (gst_tag_list_is_equal (tags2, tags));
+
+  /* want this to be unequal though, difference too large */
+  gst_tag_list_add (tags2, GST_TAG_MERGE_REPLACE, GST_TAG_REFERENCE_LEVEL,
+      9.87654310, NULL);
+  fail_unless (!gst_tag_list_is_equal (tags2, tags));
+
+  gst_tag_list_free (tags);
+  gst_tag_list_free (tags2);
+}
+
+GST_END_TEST;
+
 static Suite *
 gst_tag_suite (void)
 {
@@ -469,6 +507,7 @@ gst_tag_suite (void)
   tcase_add_test (tc_chain, test_buffer_tags);
   tcase_add_test (tc_chain, test_empty_tags);
   tcase_add_test (tc_chain, test_new_full);
+  tcase_add_test (tc_chain, test_equal);
 
   return s;
 }
index a15e0e9..e0f60af 100644 (file)
@@ -1083,6 +1083,7 @@ EXPORTS
        gst_tag_list_get_value_index
        gst_tag_list_insert
        gst_tag_list_is_empty
+       gst_tag_list_is_equal
        gst_tag_list_merge
        gst_tag_list_new
        gst_tag_list_new_full