gst/gstcaps.c: fix bug when converting from empty string.
authorBenjamin Otte <otte@gnome.org>
Thu, 22 Apr 2004 02:35:13 +0000 (02:35 +0000)
committerBenjamin Otte <otte@gnome.org>
Thu, 22 Apr 2004 02:35:13 +0000 (02:35 +0000)
Original commit message from CVS:
* gst/gstcaps.c: (gst_caps_from_string_inplace):
fix bug when converting from empty string.
* gst/gstcaps.c: (gst_caps_new_any), (gst_caps_new_simple),
(gst_caps_new_full_valist), (gst_caps_copy), (gst_caps_copy_1):
use gst_caps_new_empty to allocate a new caps. Only that function
allocates memory for caps now.
* gst/gstcaps.c: (gst_caps_remove_and_get_structure),
(gst_caps_remove_structure):
add ability to remove one structure (but not to header yet)
* gst/gstcaps.c: (gst_caps_compare_structures),
(gst_caps_simplify), (gst_caps_structure_figure_out_union),
(gst_caps_structure_simplify), (gst_caps_do_simplify),
* gst/gstcaps.h:
add gst_caps_do_simplify that tries to simplify a caps in place.
Deprecate old gst_caps_simplify function.
* testsuite/caps/caps.h:
add caps.h containing a common set of caps to test against.
* testsuite/caps/sets.c: (check_caps), (main):
use it.
* testsuite/caps/.cvsignore:
* testsuite/caps/Makefile.am:
* testsuite/caps/simplify.c: (check_caps), (main):
add test to check correctness and efficency of caps simplification.

13 files changed:
ChangeLog
gst/gstcaps.c
gst/gstcaps.h
tests/old/testsuite/caps/.gitignore
tests/old/testsuite/caps/Makefile.am
tests/old/testsuite/caps/caps.h [new file with mode: 0644]
tests/old/testsuite/caps/sets.c
tests/old/testsuite/caps/simplify.c [new file with mode: 0644]
testsuite/caps/.gitignore
testsuite/caps/Makefile.am
testsuite/caps/caps.h [new file with mode: 0644]
testsuite/caps/sets.c
testsuite/caps/simplify.c [new file with mode: 0644]

index f1e907f0de1309d106581c885009690f302b0498..7a52adb982ce42fd955aa78e053b3850ba82bfba 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,29 @@
+2004-04-22  Benjamin Otte  <otte@gnome.org>
+
+       * gst/gstcaps.c: (gst_caps_from_string_inplace):
+         fix bug when converting from empty string.
+       * gst/gstcaps.c: (gst_caps_new_any), (gst_caps_new_simple),
+       (gst_caps_new_full_valist), (gst_caps_copy), (gst_caps_copy_1):
+         use gst_caps_new_empty to allocate a new caps. Only that function
+         allocates memory for caps now.
+       * gst/gstcaps.c: (gst_caps_remove_and_get_structure),
+       (gst_caps_remove_structure):
+         add ability to remove one structure (but not to header yet)
+       * gst/gstcaps.c: (gst_caps_compare_structures),
+       (gst_caps_simplify), (gst_caps_structure_figure_out_union),
+       (gst_caps_structure_simplify), (gst_caps_do_simplify),
+       * gst/gstcaps.h:
+         add gst_caps_do_simplify that tries to simplify a caps in place.
+         Deprecate old gst_caps_simplify function.
+       * testsuite/caps/caps.h:
+         add caps.h containing a common set of caps to test against.
+       * testsuite/caps/sets.c: (check_caps), (main):
+         use it.
+       * testsuite/caps/.cvsignore:
+       * testsuite/caps/Makefile.am:
+       * testsuite/caps/simplify.c: (check_caps), (main):
+         add test to check correctness and efficency of caps simplification.
+
 2004-04-22  Sebastien Cote <sc5@hermes.usherb.ca>
 
        reviewed by Benjamin Otte  <otte@gnome.org>
index c1ebb5948e0d34d99a91dda73e1854823ae200d8..a8f057f44ba2d9ebb2eb4dfe618017459b0a6c49 100644 (file)
@@ -85,7 +85,7 @@ gst_caps_new_empty (void)
 }
 
 /**
- * gst_caps_new_empty:
+ * gst_caps_new_any:
  *
  * Creates a new #GstCaps that indicates that it is compatible with
  * any media format.
@@ -95,10 +95,8 @@ gst_caps_new_empty (void)
 GstCaps *
 gst_caps_new_any (void)
 {
-  GstCaps *caps = g_new0 (GstCaps, 1);
+  GstCaps *caps = gst_caps_new_empty ();
 
-  caps->type = GST_TYPE_CAPS;
-  caps->structs = g_ptr_array_new ();
   caps->flags = GST_CAPS_FLAGS_ANY;
 
   return caps;
@@ -123,9 +121,7 @@ gst_caps_new_simple (const char *media_type, const char *fieldname, ...)
   GstStructure *structure;
   va_list var_args;
 
-  caps = g_new0 (GstCaps, 1);
-  caps->type = GST_TYPE_CAPS;
-  caps->structs = g_ptr_array_new ();
+  caps = gst_caps_new_empty ();
 
   va_start (var_args, fieldname);
   structure = gst_structure_new_valist (media_type, fieldname, var_args);
@@ -176,9 +172,7 @@ gst_caps_new_full_valist (GstStructure * structure, va_list var_args)
 {
   GstCaps *caps;
 
-  caps = g_new0 (GstCaps, 1);
-  caps->type = GST_TYPE_CAPS;
-  caps->structs = g_ptr_array_new ();
+  caps = gst_caps_new_empty ();
 
   while (structure) {
     gst_caps_append_structure (caps, structure);
@@ -206,10 +200,8 @@ gst_caps_copy (const GstCaps * caps)
 
   g_return_val_if_fail (caps != NULL, NULL);
 
-  newcaps = g_new0 (GstCaps, 1);
-  newcaps->type = GST_TYPE_CAPS;
+  newcaps = gst_caps_new_empty ();
   newcaps->flags = caps->flags;
-  newcaps->structs = g_ptr_array_new ();
 
   for (i = 0; i < caps->structs->len; i++) {
     structure = gst_caps_get_structure (caps, i);
@@ -337,6 +329,33 @@ gst_caps_append_structure (GstCaps * caps, GstStructure * structure)
   }
 }
 
+static GstStructure *
+gst_caps_remove_and_get_structure (GstCaps * caps, guint idx)
+{
+  /* don't use index_fast, gst_caps_simplify relies on the order */
+  return g_ptr_array_remove_index (caps->structs, idx);
+}
+
+/*
+ * gst_caps_remove_structure:
+ * @caps: the #GstCaps to remove from
+ * @idx: Index of the structure to remove
+ *
+ * removes the stucture with the given index from the list of structures 
+ * contained in @caps.
+ */
+void
+gst_caps_remove_structure (GstCaps * caps, guint idx)
+{
+  GstStructure *structure;
+
+  g_return_if_fail (caps != NULL);
+  g_return_if_fail (idx <= gst_caps_get_size (caps));
+
+  structure = gst_caps_remove_and_get_structure (caps, idx);
+  gst_structure_free (structure);
+}
+
 /**
  * gst_caps_split_one:
  * @caps: 
@@ -412,10 +431,8 @@ gst_caps_copy_1 (const GstCaps * caps)
 
   g_return_val_if_fail (caps != NULL, NULL);
 
-  newcaps = g_new0 (GstCaps, 1);
-  newcaps->type = GST_TYPE_CAPS;
+  newcaps = gst_caps_new_empty ();
   newcaps->flags = caps->flags;
-  newcaps->structs = g_ptr_array_new ();
 
   if (caps->structs->len > 0) {
     structure = gst_caps_get_structure (caps, 0);
@@ -1070,33 +1087,21 @@ gst_caps_normalize (const GstCaps * caps)
   return newcaps;
 }
 
-static gboolean
-simplify_foreach (GQuark field_id, GValue * value, gpointer user_data)
+static gint
+gst_caps_compare_structures (gconstpointer one, gconstpointer two)
 {
-  GstStructure *s2 = (GstStructure *) user_data;
-  const GValue *v2;
-
-  v2 = gst_structure_id_get_value (s2, field_id);
-  if (v2 == NULL)
-    return FALSE;
-
-  if (gst_value_compare (value, v2) == GST_VALUE_EQUAL)
-    return TRUE;
-  return FALSE;
-}
-
-static gboolean
-gst_caps_structure_simplify (GstStructure * struct1,
-    const GstStructure * struct2)
-{
-  /* FIXME this is just a simple compare.  Better would be to merge
-   * the two structures */
-  if (struct1->name != struct2->name)
-    return FALSE;
-  if (struct1->fields->len != struct2->fields->len)
-    return FALSE;
-
-  return gst_structure_foreach (struct1, simplify_foreach, (void *) struct2);
+  gint ret;
+  const GstStructure *struct1 = *((const GstStructure **) one);
+  const GstStructure *struct2 = *((const GstStructure **) two);
+
+  /* FIXME: this orders aphabetically, but ordering the quarks might be faster 
+     So what's the best way? */
+  ret = strcmp (gst_structure_get_name (struct1),
+      gst_structure_get_name (struct2));
+  if (ret)
+    return ret;
+
+  return gst_structure_n_fields (struct2) - gst_structure_n_fields (struct1);
 }
 
 /**
@@ -1113,33 +1118,121 @@ gst_caps_structure_simplify (GstStructure * struct1,
 GstCaps *
 gst_caps_simplify (const GstCaps * caps)
 {
-  int i;
-  int j;
-  GstCaps *newcaps;
-  GstStructure *structure;
-  GstStructure *struct2;
+  GstCaps *ret;
+
+  g_return_val_if_fail (caps != NULL, NULL);
+
+  ret = gst_caps_copy (caps);
+  gst_caps_do_simplify (ret);
+
+  return ret;
+}
+
+/* need this here */
+typedef struct
+{
+  GQuark name;
+  GValue value;
+  GstStructure *compare;
+}
+UnionField;
+
+static G_GNUC_UNUSED gboolean
+gst_caps_structure_figure_out_union (GQuark field_id, GValue * value,
+    gpointer user_data)
+{
+  UnionField *u = user_data;
+  const GValue *val = gst_structure_id_get_value (u->compare, field_id);
+
+  if (!val)
+    return TRUE;
+  if (gst_value_compare (val, value) == GST_VALUE_EQUAL)
+    return TRUE;
+  if (u->name) {
+    g_value_unset (&u->value);
+    return FALSE;
+  }
+  u->name = field_id;
+  gst_value_union (&u->value, val, value);
+  return TRUE;
+}
 
-  if (gst_caps_get_size (caps) < 2) {
-    return gst_caps_copy (caps);
+static GstStructure *
+gst_caps_structure_simplify (const GstStructure * simplify,
+    GstStructure * compare)
+{
+  GstCaps *caps = gst_caps_new_empty ();
+  GstStructure *ret;
+  UnionField field = { 0, {0,}, NULL };
+
+  /* try to subtract to get a real subset */
+  gst_caps_structure_subtract (caps, simplify, compare);
+  switch (gst_caps_get_size (caps)) {
+    case 0:
+      gst_caps_free (caps);
+      return NULL;
+    case 1:
+      ret = gst_structure_copy (gst_caps_get_structure (caps, 0));
+      break;
+    default:
+      ret = gst_structure_copy (simplify);
+      break;
   }
+  gst_caps_free (caps);
 
-  newcaps = gst_caps_new_empty ();
+  /* try to union both structs */
+  field.compare = compare;
+  if (gst_structure_foreach (ret, gst_caps_structure_figure_out_union, &field)) {
+    g_assert (field.name != 0);
+    gst_structure_id_set_value (compare, field.name, &field.value);
+    gst_structure_free (ret);
+    return NULL;
+  }
 
-  for (i = 0; i < gst_caps_get_size (caps); i++) {
-    structure = gst_caps_get_structure (caps, i);
+  return ret;
+}
 
-    for (j = 0; j < gst_caps_get_size (newcaps); j++) {
-      struct2 = gst_caps_get_structure (caps, i);
-      if (gst_caps_structure_simplify (struct2, structure)) {
+void
+gst_caps_do_simplify (GstCaps * caps)
+{
+  GstStructure *simplify, *compare, *result;
+  gint i, j, start;
+
+  g_return_if_fail (caps != NULL);
+
+  if (gst_caps_get_size (caps) < 2)
+    return;
+
+  g_ptr_array_sort (caps->structs, gst_caps_compare_structures);
+
+  start = caps->structs->len - 1;
+  for (i = caps->structs->len - 1; i >= 0; i--) {
+    simplify = gst_caps_get_structure (caps, i);
+    for (j = start; j >= 0; j--) {
+      compare = gst_caps_get_structure (caps, j);
+      if (j == i)
+        continue;
+      if (gst_structure_get_name_id (simplify) !=
+          gst_structure_get_name_id (compare)) {
+        start = j;
         break;
       }
-    }
-    if (j == gst_caps_get_size (newcaps)) {
-      gst_caps_append_structure (newcaps, gst_structure_copy (structure));
+      result = gst_caps_structure_simplify (simplify, compare);
+      /*g_print ("%s  -  %s  =  %s\n", 
+         gst_structure_to_string (simplify),
+         gst_structure_to_string (compare),
+         result ? gst_structure_to_string (result) : "---");
+       */
+      if (result) {
+        gst_structure_free (simplify);
+        g_ptr_array_index (caps->structs, i) = result;
+        simplify = result;
+      } else {
+        gst_caps_remove_structure (caps, i);
+        start--;
+      }
     }
   }
-
-  return newcaps;
 }
 
 #ifndef GST_DISABLE_LOADSAVE
@@ -1262,7 +1355,7 @@ gst_caps_from_string_inplace (GstCaps * caps, const gchar * string)
     caps->flags = GST_CAPS_FLAGS_ANY;
     return TRUE;
   }
-  if (strcmp ("NONE", string) == 0) {
+  if (strcmp ("EMPTY", string) == 0) {
     return TRUE;
   }
 
index d0ad570c71cc81eacc30040f3a0f473c8bbacbbe..525ce8d771893b0414504f57d13830ff2c09d102 100644 (file)
@@ -88,11 +88,11 @@ void                     gst_caps_append                                (GstCaps
                                                                         GstCaps       *caps2);
 void                     gst_caps_append_structure                      (GstCaps       *caps,
                                                                         GstStructure  *structure);
-GstCaps *                gst_caps_split_one                             (GstCaps       *caps);
 int                      gst_caps_get_size                              (const GstCaps *caps);
 GstStructure *           gst_caps_get_structure                         (const GstCaps *caps,
                                                                         int            index);
 #ifndef GST_DISABLE_DEPRECATED
+GstCaps *                gst_caps_split_one                             (GstCaps       *caps);
 GstCaps *                gst_caps_copy_1                                (const GstCaps *caps);
 #endif
 void                     gst_caps_set_simple                            (GstCaps       *caps,
@@ -125,7 +125,10 @@ GstCaps *                gst_caps_subtract                         (const GstCaps *minuend,
 GstCaps *                gst_caps_union                                 (const GstCaps *caps1,
                                                                         const GstCaps *caps2);
 GstCaps *                gst_caps_normalize                             (const GstCaps *caps);
+#ifndef GST_DISABLE_DEPRECATED
 GstCaps *                gst_caps_simplify                              (const GstCaps *caps);
+#endif
+void                    gst_caps_do_simplify                           (GstCaps *caps);
 
 #ifndef GST_DISABLE_LOADSAVE
 xmlNodePtr               gst_caps_save_thyself                          (const GstCaps *caps,
index 3ff4a8ee4c4252be64cec9a4cfdec03a3b185702..897998f66f2ca30c1ad5ba5033536665b1cad59c 100644 (file)
@@ -18,6 +18,7 @@ intersect2
 intersection
 normalisation
 union
+simplify
 sets
 string-conversions
 subtract
index 2b7eb477f38775b894a334806e901c54b238c60f..e444dcf22cbae5f0326cb251c058bbf41eaf0de3 100644 (file)
@@ -18,7 +18,11 @@ tests_pass = \
        filtercaps \
        erathostenes \
        subtract \
-       sets
+       sets \
+       simplify
+
+noinst_HEADERS = \
+       caps.h
 
 tests_fail =
 tests_ignore =
@@ -47,4 +51,6 @@ subtract_LDADD = $(GST_LIBS)
 subtract_CFLAGS = $(GST_CFLAGS) $(XML_CFLAGS)
 sets_LDADD = $(GST_LIBS) 
 sets_CFLAGS = $(GST_CFLAGS) $(XML_CFLAGS)
+simplify_LDADD = $(GST_LIBS) 
+simplify_CFLAGS = $(GST_CFLAGS) $(XML_CFLAGS)
 
diff --git a/tests/old/testsuite/caps/caps.h b/tests/old/testsuite/caps/caps.h
new file mode 100644 (file)
index 0000000..39e5c2f
--- /dev/null
@@ -0,0 +1,17 @@
+#include <glib.h>
+
+/* defines an array of strings named caps_list, that contains a list of caps for
+   general tests. So if you don't know what caps to use to write a test, just
+   include this file */
+
+static const gchar *caps_list[] = {
+  "video/x-raw-yuv, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], format=(fourcc)I420; video/x-raw-yuv, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], format=(fourcc)YUY2; video/x-raw-rgb, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], bpp=(int)24, depth=(int)24, red_mask=(int)16711680, green_mask=(int)65280, blue_mask=(int)255, endianness=(int)4321; video/x-raw-rgb, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], bpp=(int)24, depth=(int)24, red_mask=(int)255, green_mask=(int)65280, blue_mask=(int)16711680, endianness=(int)4321; video/x-raw-yuv, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], format=(fourcc)Y42B; video/x-raw-rgb, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], bpp=(int)32, depth=(int)24, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, endianness=(int)4321; video/x-raw-yuv, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], format=(fourcc)YUV9; video/x-raw-yuv, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], format=(fourcc)Y41B; video/x-raw-rgb, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], bpp=(int)16, depth=(int)16, red_mask=(int)63488, green_mask=(int)2016, blue_mask=(int)31, endianness=(int)1234; video/x-raw-rgb, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], bpp=(int)16, depth=(int)15, red_mask=(int)31744, green_mask=(int)992, blue_mask=(int)31, endianness=(int)1234",
+  "video/x-raw-yuv, format=(fourcc){ YUY2, I420 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-jpeg, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-divx, divxversion=(int)[ 3, 5 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-xvid, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-3ivx, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-msmpeg, msmpegversion=(int)[ 41, 43 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/mpeg, mpegversion=(int)1, systemstream=(boolean)false, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-h263, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-dv, systemstream=(boolean)false, width=(int)720, height=(int){ 576, 480 }; video/x-huffyuv, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]",
+  "video/x-raw-yuv, format=(fourcc){ YUY2, I420 }, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; image/jpeg, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-divx, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], divxversion=(int)[ 3, 5 ]; video/x-xvid, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-3ivx, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-msmpeg, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], msmpegversion=(int)[ 41, 43 ]; video/mpeg, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], mpegversion=(int)1, systemstream=(boolean)false; video/x-h263, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-dv, width=(int)720, height=(int){ 576, 480 }, systemstream=(boolean)false; video/x-huffyuv, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]",
+  "video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ]; video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)-16777216, green_mask=(int)16711680, blue_mask=(int)65280, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ]",
+  "video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ]",
+  "video/x-raw-yuv, format=(fourcc){ I420 }, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]",
+  "ANY",
+  "EMPTY"
+};
+
index 740039f1bf67cf386902b678958d30d4b6c654a9..676d194e0d501103d1ce1f5bfd831a823ac557cb 100644 (file)
 
 #include <gst/gst.h>
 #include <string.h>
-
-static const gchar *caps[] = {
-  "video/x-raw-yuv, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], format=(fourcc)I420; video/x-raw-yuv, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], format=(fourcc)YUY2; video/x-raw-rgb, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], bpp=(int)24, depth=(int)24, red_mask=(int)16711680, green_mask=(int)65280, blue_mask=(int)255, endianness=(int)4321; video/x-raw-rgb, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], bpp=(int)24, depth=(int)24, red_mask=(int)255, green_mask=(int)65280, blue_mask=(int)16711680, endianness=(int)4321; video/x-raw-yuv, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], format=(fourcc)Y42B; video/x-raw-rgb, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], bpp=(int)32, depth=(int)24, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, endianness=(int)4321; video/x-raw-yuv, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], format=(fourcc)YUV9; video/x-raw-yuv, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], format=(fourcc)Y41B; video/x-raw-rgb, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], bpp=(int)16, depth=(int)16, red_mask=(int)63488, green_mask=(int)2016, blue_mask=(int)31, endianness=(int)1234; video/x-raw-rgb, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], bpp=(int)16, depth=(int)15, red_mask=(int)31744, green_mask=(int)992, blue_mask=(int)31, endianness=(int)1234",
-  "video/x-raw-yuv, format=(fourcc){ YUY2, I420 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-jpeg, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-divx, divxversion=(int)[ 3, 5 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-xvid, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-3ivx, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-msmpeg, msmpegversion=(int)[ 41, 43 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/mpeg, mpegversion=(int)1, systemstream=(boolean)false, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-h263, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-dv, systemstream=(boolean)false, width=(int)720, height=(int){ 576, 480 }; video/x-huffyuv, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]",
-  "video/x-raw-yuv, format=(fourcc){ YUY2, I420 }, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; image/jpeg, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-divx, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], divxversion=(int)[ 3, 5 ]; video/x-xvid, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-3ivx, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-msmpeg, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], msmpegversion=(int)[ 41, 43 ]; video/mpeg, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], mpegversion=(int)1, systemstream=(boolean)false; video/x-h263, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-dv, width=(int)720, height=(int){ 576, 480 }, systemstream=(boolean)false; video/x-huffyuv, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]",
-  "video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ]; video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)-16777216, green_mask=(int)16711680, blue_mask=(int)65280, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ]",
-  "video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ]",
-  "video/x-raw-yuv, format=(fourcc){ I420 }, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]",
-  "ANY",
-  "EMPTY"
-};
+#include "caps.h"
 
 static void
 check_caps (const gchar * eins, const gchar * zwei)
@@ -80,10 +70,10 @@ main (gint argc, gchar ** argv)
 
   gst_init (&argc, &argv);
 
-  for (i = 0; i < G_N_ELEMENTS (caps); i++) {
-    for (j = 0; j < G_N_ELEMENTS (caps); j++) {
+  for (i = 0; i < G_N_ELEMENTS (caps_list); i++) {
+    for (j = 0; j < G_N_ELEMENTS (caps_list); j++) {
       g_print ("%u - %u\n", i, j);
-      check_caps (caps[i], caps[j]);
+      check_caps (caps_list[i], caps_list[j]);
     }
   }
 
diff --git a/tests/old/testsuite/caps/simplify.c b/tests/old/testsuite/caps/simplify.c
new file mode 100644 (file)
index 0000000..ca70ca5
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2004 Benjamin Otte <in7y118@public.uni-hamburg.de>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <gst/gst.h>
+#include <string.h>
+#include "caps.h"
+
+/* statistics junkie!!! */
+static guint size_before = 0, size_after = 0;
+static guint length_before = 0, length_after = 0;
+static guint impossible = 0, success = 0, failure = 0;
+
+static void
+check_caps (GstCaps * caps)
+{
+  gchar *before, *after;
+  GstCaps *old;
+
+  before = gst_caps_to_string (caps);
+  old = gst_caps_copy (caps);
+  gst_caps_do_simplify (caps);
+  after = gst_caps_to_string (caps);
+  g_assert (gst_caps_get_size (caps) <= gst_caps_get_size (old));
+  if (gst_caps_get_size (caps) == gst_caps_get_size (old))
+    g_assert (strlen (after) <= strlen (before));
+  g_assert (gst_caps_is_equal (caps, old));
+  g_print ("%s %2u/%-4u => %2u/%-4u\n",
+      gst_caps_get_size (caps) < gst_caps_get_size (old) ||
+      strlen (after) < strlen (before) ? "REDUCED" :
+      (gst_caps_get_size (old) < 2 ? "  ---  " : "       "),
+      gst_caps_get_size (old), strlen (before),
+      gst_caps_get_size (caps), strlen (after));
+
+  size_before += gst_caps_get_size (old);
+  size_after += gst_caps_get_size (caps);
+  length_before += strlen (before);
+  length_after += strlen (after);
+  if (gst_caps_get_size (old) < 2) {
+    impossible++;
+  } else if (gst_caps_get_size (caps) < gst_caps_get_size (old) ||
+      strlen (after) < strlen (before)) {
+    success++;
+  } else {
+    failure++;
+  }
+
+  g_free (before);
+  g_free (after);
+  gst_caps_free (old);
+}
+
+gint
+main (gint argc, gchar ** argv)
+{
+  guint i, j;
+
+  gst_init (&argc, &argv);
+
+  for (i = 0; i < G_N_ELEMENTS (caps_list); i++) {
+    GstCaps *caps = gst_caps_from_string (caps_list[i]);
+
+    g_print ("     %2u ", i);
+    check_caps (caps);
+    if (!gst_caps_is_any (caps)) {
+      for (j = 0; j < G_N_ELEMENTS (caps_list); j++) {
+        GstCaps *caps2 = gst_caps_from_string (caps_list[j]);
+
+        /* subtraction */
+        GstCaps *temp = gst_caps_subtract (caps, caps2);
+
+        g_print ("%2u - %2u ", i, j);
+        check_caps (temp);
+        gst_caps_free (temp);
+        /* union */
+        temp = gst_caps_union (caps, caps2);
+        g_print ("%2u + %2u ", i, j);
+        check_caps (temp);
+        if (i == j)
+          g_assert (gst_caps_get_size (caps) == gst_caps_get_size (temp));
+        gst_caps_free (temp);
+        gst_caps_free (caps2);
+      }
+    }
+    gst_caps_free (caps);
+  }
+  g_print ("\n\nSTATISTICS:\n");
+  g_print ("\nOf all caps tried\n");
+  g_print ("%3u (%02.4g%%) caps were already at minimum size.\n", impossible,
+      100.0 * ((double) impossible) / (impossible + success + failure));
+  g_print ("%3u (%02.4g%%) caps were successfully reduced.\n", success,
+      100.0 * ((double) success) / (impossible + success + failure));
+  g_print ("%3u (%02.4g%%) caps could not be reduced.\n", failure,
+      100.0 * ((double) failure) / (impossible + success + failure));
+  g_print ("\nOf all caps that could possibly be reduced\n");
+  g_print ("%02.4g%% were reduced\n",
+      100.0 * ((double) success) / (success + failure));
+  g_print ("%02.4g%% average reduction in caps structure amount\n",
+      100.0 * (1.0 - ((double) size_after) / size_before));
+  g_print ("%02.4g%% average reduction in caps serialization length\n",
+      100.0 * (1.0 - ((double) length_after) / length_before));
+
+  return 0;
+}
index 3ff4a8ee4c4252be64cec9a4cfdec03a3b185702..897998f66f2ca30c1ad5ba5033536665b1cad59c 100644 (file)
@@ -18,6 +18,7 @@ intersect2
 intersection
 normalisation
 union
+simplify
 sets
 string-conversions
 subtract
index 2b7eb477f38775b894a334806e901c54b238c60f..e444dcf22cbae5f0326cb251c058bbf41eaf0de3 100644 (file)
@@ -18,7 +18,11 @@ tests_pass = \
        filtercaps \
        erathostenes \
        subtract \
-       sets
+       sets \
+       simplify
+
+noinst_HEADERS = \
+       caps.h
 
 tests_fail =
 tests_ignore =
@@ -47,4 +51,6 @@ subtract_LDADD = $(GST_LIBS)
 subtract_CFLAGS = $(GST_CFLAGS) $(XML_CFLAGS)
 sets_LDADD = $(GST_LIBS) 
 sets_CFLAGS = $(GST_CFLAGS) $(XML_CFLAGS)
+simplify_LDADD = $(GST_LIBS) 
+simplify_CFLAGS = $(GST_CFLAGS) $(XML_CFLAGS)
 
diff --git a/testsuite/caps/caps.h b/testsuite/caps/caps.h
new file mode 100644 (file)
index 0000000..39e5c2f
--- /dev/null
@@ -0,0 +1,17 @@
+#include <glib.h>
+
+/* defines an array of strings named caps_list, that contains a list of caps for
+   general tests. So if you don't know what caps to use to write a test, just
+   include this file */
+
+static const gchar *caps_list[] = {
+  "video/x-raw-yuv, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], format=(fourcc)I420; video/x-raw-yuv, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], format=(fourcc)YUY2; video/x-raw-rgb, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], bpp=(int)24, depth=(int)24, red_mask=(int)16711680, green_mask=(int)65280, blue_mask=(int)255, endianness=(int)4321; video/x-raw-rgb, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], bpp=(int)24, depth=(int)24, red_mask=(int)255, green_mask=(int)65280, blue_mask=(int)16711680, endianness=(int)4321; video/x-raw-yuv, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], format=(fourcc)Y42B; video/x-raw-rgb, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], bpp=(int)32, depth=(int)24, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, endianness=(int)4321; video/x-raw-yuv, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], format=(fourcc)YUV9; video/x-raw-yuv, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], format=(fourcc)Y41B; video/x-raw-rgb, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], bpp=(int)16, depth=(int)16, red_mask=(int)63488, green_mask=(int)2016, blue_mask=(int)31, endianness=(int)1234; video/x-raw-rgb, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], bpp=(int)16, depth=(int)15, red_mask=(int)31744, green_mask=(int)992, blue_mask=(int)31, endianness=(int)1234",
+  "video/x-raw-yuv, format=(fourcc){ YUY2, I420 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-jpeg, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-divx, divxversion=(int)[ 3, 5 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-xvid, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-3ivx, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-msmpeg, msmpegversion=(int)[ 41, 43 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/mpeg, mpegversion=(int)1, systemstream=(boolean)false, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-h263, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-dv, systemstream=(boolean)false, width=(int)720, height=(int){ 576, 480 }; video/x-huffyuv, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]",
+  "video/x-raw-yuv, format=(fourcc){ YUY2, I420 }, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; image/jpeg, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-divx, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], divxversion=(int)[ 3, 5 ]; video/x-xvid, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-3ivx, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-msmpeg, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], msmpegversion=(int)[ 41, 43 ]; video/mpeg, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], mpegversion=(int)1, systemstream=(boolean)false; video/x-h263, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-dv, width=(int)720, height=(int){ 576, 480 }, systemstream=(boolean)false; video/x-huffyuv, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]",
+  "video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ]; video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)-16777216, green_mask=(int)16711680, blue_mask=(int)65280, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ]",
+  "video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ]",
+  "video/x-raw-yuv, format=(fourcc){ I420 }, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]",
+  "ANY",
+  "EMPTY"
+};
+
index 740039f1bf67cf386902b678958d30d4b6c654a9..676d194e0d501103d1ce1f5bfd831a823ac557cb 100644 (file)
 
 #include <gst/gst.h>
 #include <string.h>
-
-static const gchar *caps[] = {
-  "video/x-raw-yuv, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], format=(fourcc)I420; video/x-raw-yuv, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], format=(fourcc)YUY2; video/x-raw-rgb, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], bpp=(int)24, depth=(int)24, red_mask=(int)16711680, green_mask=(int)65280, blue_mask=(int)255, endianness=(int)4321; video/x-raw-rgb, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], bpp=(int)24, depth=(int)24, red_mask=(int)255, green_mask=(int)65280, blue_mask=(int)16711680, endianness=(int)4321; video/x-raw-yuv, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], format=(fourcc)Y42B; video/x-raw-rgb, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], bpp=(int)32, depth=(int)24, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, endianness=(int)4321; video/x-raw-yuv, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], format=(fourcc)YUV9; video/x-raw-yuv, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], format=(fourcc)Y41B; video/x-raw-rgb, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], bpp=(int)16, depth=(int)16, red_mask=(int)63488, green_mask=(int)2016, blue_mask=(int)31, endianness=(int)1234; video/x-raw-rgb, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ], bpp=(int)16, depth=(int)15, red_mask=(int)31744, green_mask=(int)992, blue_mask=(int)31, endianness=(int)1234",
-  "video/x-raw-yuv, format=(fourcc){ YUY2, I420 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-jpeg, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-divx, divxversion=(int)[ 3, 5 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-xvid, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-3ivx, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-msmpeg, msmpegversion=(int)[ 41, 43 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/mpeg, mpegversion=(int)1, systemstream=(boolean)false, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-h263, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-dv, systemstream=(boolean)false, width=(int)720, height=(int){ 576, 480 }; video/x-huffyuv, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]",
-  "video/x-raw-yuv, format=(fourcc){ YUY2, I420 }, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; image/jpeg, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-divx, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], divxversion=(int)[ 3, 5 ]; video/x-xvid, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-3ivx, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-msmpeg, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], msmpegversion=(int)[ 41, 43 ]; video/mpeg, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], mpegversion=(int)1, systemstream=(boolean)false; video/x-h263, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-dv, width=(int)720, height=(int){ 576, 480 }, systemstream=(boolean)false; video/x-huffyuv, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]",
-  "video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ]; video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)-16777216, green_mask=(int)16711680, blue_mask=(int)65280, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ]",
-  "video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(double)[ 0, 1.7976931348623157e+308 ]",
-  "video/x-raw-yuv, format=(fourcc){ I420 }, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]",
-  "ANY",
-  "EMPTY"
-};
+#include "caps.h"
 
 static void
 check_caps (const gchar * eins, const gchar * zwei)
@@ -80,10 +70,10 @@ main (gint argc, gchar ** argv)
 
   gst_init (&argc, &argv);
 
-  for (i = 0; i < G_N_ELEMENTS (caps); i++) {
-    for (j = 0; j < G_N_ELEMENTS (caps); j++) {
+  for (i = 0; i < G_N_ELEMENTS (caps_list); i++) {
+    for (j = 0; j < G_N_ELEMENTS (caps_list); j++) {
       g_print ("%u - %u\n", i, j);
-      check_caps (caps[i], caps[j]);
+      check_caps (caps_list[i], caps_list[j]);
     }
   }
 
diff --git a/testsuite/caps/simplify.c b/testsuite/caps/simplify.c
new file mode 100644 (file)
index 0000000..ca70ca5
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2004 Benjamin Otte <in7y118@public.uni-hamburg.de>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <gst/gst.h>
+#include <string.h>
+#include "caps.h"
+
+/* statistics junkie!!! */
+static guint size_before = 0, size_after = 0;
+static guint length_before = 0, length_after = 0;
+static guint impossible = 0, success = 0, failure = 0;
+
+static void
+check_caps (GstCaps * caps)
+{
+  gchar *before, *after;
+  GstCaps *old;
+
+  before = gst_caps_to_string (caps);
+  old = gst_caps_copy (caps);
+  gst_caps_do_simplify (caps);
+  after = gst_caps_to_string (caps);
+  g_assert (gst_caps_get_size (caps) <= gst_caps_get_size (old));
+  if (gst_caps_get_size (caps) == gst_caps_get_size (old))
+    g_assert (strlen (after) <= strlen (before));
+  g_assert (gst_caps_is_equal (caps, old));
+  g_print ("%s %2u/%-4u => %2u/%-4u\n",
+      gst_caps_get_size (caps) < gst_caps_get_size (old) ||
+      strlen (after) < strlen (before) ? "REDUCED" :
+      (gst_caps_get_size (old) < 2 ? "  ---  " : "       "),
+      gst_caps_get_size (old), strlen (before),
+      gst_caps_get_size (caps), strlen (after));
+
+  size_before += gst_caps_get_size (old);
+  size_after += gst_caps_get_size (caps);
+  length_before += strlen (before);
+  length_after += strlen (after);
+  if (gst_caps_get_size (old) < 2) {
+    impossible++;
+  } else if (gst_caps_get_size (caps) < gst_caps_get_size (old) ||
+      strlen (after) < strlen (before)) {
+    success++;
+  } else {
+    failure++;
+  }
+
+  g_free (before);
+  g_free (after);
+  gst_caps_free (old);
+}
+
+gint
+main (gint argc, gchar ** argv)
+{
+  guint i, j;
+
+  gst_init (&argc, &argv);
+
+  for (i = 0; i < G_N_ELEMENTS (caps_list); i++) {
+    GstCaps *caps = gst_caps_from_string (caps_list[i]);
+
+    g_print ("     %2u ", i);
+    check_caps (caps);
+    if (!gst_caps_is_any (caps)) {
+      for (j = 0; j < G_N_ELEMENTS (caps_list); j++) {
+        GstCaps *caps2 = gst_caps_from_string (caps_list[j]);
+
+        /* subtraction */
+        GstCaps *temp = gst_caps_subtract (caps, caps2);
+
+        g_print ("%2u - %2u ", i, j);
+        check_caps (temp);
+        gst_caps_free (temp);
+        /* union */
+        temp = gst_caps_union (caps, caps2);
+        g_print ("%2u + %2u ", i, j);
+        check_caps (temp);
+        if (i == j)
+          g_assert (gst_caps_get_size (caps) == gst_caps_get_size (temp));
+        gst_caps_free (temp);
+        gst_caps_free (caps2);
+      }
+    }
+    gst_caps_free (caps);
+  }
+  g_print ("\n\nSTATISTICS:\n");
+  g_print ("\nOf all caps tried\n");
+  g_print ("%3u (%02.4g%%) caps were already at minimum size.\n", impossible,
+      100.0 * ((double) impossible) / (impossible + success + failure));
+  g_print ("%3u (%02.4g%%) caps were successfully reduced.\n", success,
+      100.0 * ((double) success) / (impossible + success + failure));
+  g_print ("%3u (%02.4g%%) caps could not be reduced.\n", failure,
+      100.0 * ((double) failure) / (impossible + success + failure));
+  g_print ("\nOf all caps that could possibly be reduced\n");
+  g_print ("%02.4g%% were reduced\n",
+      100.0 * ((double) success) / (success + failure));
+  g_print ("%02.4g%% average reduction in caps structure amount\n",
+      100.0 * (1.0 - ((double) size_after) / size_before));
+  g_print ("%02.4g%% average reduction in caps serialization length\n",
+      100.0 * (1.0 - ((double) length_after) / length_before));
+
+  return 0;
+}