adding GstFraction GValue type
authorThomas Vander Stichele <thomas@apestaart.org>
Thu, 15 Jul 2004 20:27:20 +0000 (20:27 +0000)
committerThomas Vander Stichele <thomas@apestaart.org>
Thu, 15 Jul 2004 20:27:20 +0000 (20:27 +0000)
Original commit message from CVS:
adding GstFraction GValue type

17 files changed:
ChangeLog
docs/gst/gstreamer-sections.txt
docs/gst/tmpl/gstelement.sgml
docs/gst/tmpl/gstpad.sgml
docs/gst/tmpl/gsttypes.sgml
docs/gst/tmpl/gstvalue.sgml
gst/gststructure.c
gst/gstvalue.c
gst/gstvalue.h
tests/old/testsuite/caps/Makefile.am
tests/old/testsuite/caps/fraction.c [new file with mode: 0644]
tests/old/testsuite/caps/string-conversions.c
tests/old/testsuite/caps/value_compare.c
testsuite/caps/Makefile.am
testsuite/caps/fraction.c [new file with mode: 0644]
testsuite/caps/string-conversions.c
testsuite/caps/value_compare.c

index 09790e2..ad06827 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,10 +1,40 @@
+2004-07-15  Thomas Vander Stichele  <thomas at apestaart dot org>
+
+       * docs/gst/gstreamer-sections.txt:
+         add new symbols
+       * docs/gst/tmpl/gstelement.sgml:
+       * docs/gst/tmpl/gstpad.sgml:
+       * docs/gst/tmpl/gsttypes.sgml:
+       * docs/gst/tmpl/gstvalue.sgml:
+         update docs
+       * gst/gststructure.c: (gst_structure_set_valist),
+       (gst_structure_from_abbr), (gst_structure_to_abbr):
+       * gst/gstvalue.c: (gst_value_compare_double), (gst_type_is_fixed),
+       (gst_greatest_common_divisor), (gst_value_init_fraction),
+       (gst_value_copy_fraction), (gst_value_collect_fraction),
+       (gst_value_lcopy_fraction), (gst_value_set_fraction),
+       (gst_value_get_fraction_numerator),
+       (gst_value_get_fraction_denominator),
+       (gst_value_fraction_multiply), (gst_value_serialize_fraction),
+       (gst_value_deserialize_fraction),
+       (gst_value_transform_fraction_string),
+       (gst_value_transform_string_fraction),
+       (gst_value_compare_fraction), (_gst_value_initialize):
+       * gst/gstvalue.h:
+         adding GstFraction GValue type, get/set, and multiply
+       * testsuite/caps/Makefile.am:
+       * testsuite/caps/fraction.c: (test), (main):
+       * testsuite/caps/string-conversions.c: (main):
+       * testsuite/caps/value_compare.c: (test1), (main):
+         add regression tests for GstFraction
+
 2004-07-15  Zaheer Abbas Merali  <zaheerabbas at merali dot org>
        
        * docs/manual/init-api.xml: Grammar fix
 
 2004-07-15  Zaheer Abbas Merali  <zaheerabbas at merali dot org>
-                                                                                
-        * docs/manual/states.xml: Fix inconsistent information
+
+       * docs/manual/states.xml: Fix inconsistent information
 
 2004-07-15  Thomas Vander Stichele  <thomas at apestaart dot org>
 
        * testsuite/clock/signedness.c: (main):
          make sure it never will again
 
->>>>>>> 1.669
 2004-07-11  Andy Wingo  <wingo@pobox.com>
 
        * gst/gstbin.c (gst_bin_add_func): If we're adding an element
index 1546fa3..17888c8 100644 (file)
@@ -1686,11 +1686,13 @@ GST_VALUE_HOLDS_DOUBLE_RANGE
 GST_VALUE_HOLDS_LIST
 GST_VALUE_HOLDS_FIXED_LIST
 GST_VALUE_HOLDS_CAPS
+GST_VALUE_HOLDS_FRACTION
 GST_TYPE_FOURCC
 GST_TYPE_INT_RANGE
 GST_TYPE_DOUBLE_RANGE
 GST_TYPE_LIST
 GST_TYPE_FIXED_LIST
+GST_TYPE_FRACTION
 GST_VALUE_LESS_THAN
 GST_VALUE_EQUAL
 GST_VALUE_GREATER_THAN
@@ -1707,6 +1709,7 @@ gst_type_int_range
 gst_type_double_range
 gst_type_list
 gst_type_fixed_list
+gst_type_fraction
 gst_type_is_fixed
 gst_value_register
 gst_value_init_and_copy
@@ -1727,6 +1730,10 @@ gst_value_get_double_range_min
 gst_value_get_double_range_max
 gst_value_get_caps
 gst_value_set_caps
+gst_value_get_fraction_numerator
+gst_value_get_fraction_denominator
+gst_value_set_fraction
+gst_value_fraction_multiply
 gst_value_compare
 gst_value_can_compare
 gst_value_union
index 6263b4e..2a07afc 100644 (file)
@@ -76,8 +76,6 @@ and gst_element_set_clock().  You can wait for the clock to reach a given
 
 </para>
 
-@:
-
 @gstelement: the object which received the signal.
 
 <!-- ##### SIGNAL GstElement::error ##### -->
@@ -85,11 +83,6 @@ and gst_element_set_clock().  You can wait for the clock to reach a given
 
 </para>
 
-@: 
-@: 
-@: 
-@:
-
 @gstelement: the object which received the signal.
 @arg1: 
 @arg2: 
@@ -100,10 +93,6 @@ and gst_element_set_clock().  You can wait for the clock to reach a given
 
 </para>
 
-@: 
-@: 
-@:
-
 @gstelement: the object which received the signal.
 @arg1: 
 @arg2: 
@@ -113,9 +102,6 @@ and gst_element_set_clock().  You can wait for the clock to reach a given
 
 </para>
 
-@: 
-@:
-
 @gstelement: the object which received the signal.
 @arg1: 
 
@@ -124,8 +110,6 @@ and gst_element_set_clock().  You can wait for the clock to reach a given
 
 </para>
 
-@:
-
 @gstelement: the object which received the signal.
 
 <!-- ##### SIGNAL GstElement::pad-removed ##### -->
@@ -133,9 +117,6 @@ and gst_element_set_clock().  You can wait for the clock to reach a given
 
 </para>
 
-@: 
-@:
-
 @gstelement: the object which received the signal.
 @arg1: 
 
@@ -144,10 +125,6 @@ and gst_element_set_clock().  You can wait for the clock to reach a given
 
 </para>
 
-@: 
-@: 
-@:
-
 @gstelement: the object which received the signal.
 @arg1: 
 @arg2: 
index fbd0537..509ad98 100644 (file)
@@ -467,6 +467,7 @@ Flags for the pad.
 
 @GST_PAD_DISABLED: the pad is disabled.
 @GST_PAD_NEGOTIATING: 
+@GST_PAD_DISPATCHING: 
 @GST_PAD_FLAG_LAST: subclasses can use this number to enumerate their flags.
 
 <!-- ##### MACRO GST_PAD_NAME ##### -->
@@ -759,6 +760,14 @@ Checks if the pad is active.
 @pad: 
 
 
+<!-- ##### MACRO GST_PAD_IS_DISPATCHING ##### -->
+<para>
+
+</para>
+
+@pad: 
+
+
 <!-- ##### MACRO GST_PAD_IS_USABLE ##### -->
 <para>
 Checks if a pad is usable. A usable pad is both linked and active.
index dcf6af2..b786243 100644 (file)
@@ -127,58 +127,58 @@ template.
 
 </para>
 
-@gstelement: the object which received the signal.
+@
 
 <!-- ##### SIGNAL GstElement::error ##### -->
 <para>
 
 </para>
 
-@gstelement: the object which received the signal.
-@arg1
-@arg2
-@arg3
+@
+@: 
+@: 
+@: 
 
 <!-- ##### SIGNAL GstElement::found-tag ##### -->
 <para>
 
 </para>
 
-@gstelement: the object which received the signal.
-@arg1
-@arg2
+@
+@: 
+@: 
 
 <!-- ##### SIGNAL GstElement::new-pad ##### -->
 <para>
 
 </para>
 
-@gstelement: the object which received the signal.
-@arg1
+@
+@: 
 
 <!-- ##### SIGNAL GstElement::no-more-pads ##### -->
 <para>
 
 </para>
 
-@gstelement: the object which received the signal.
+@
 
 <!-- ##### SIGNAL GstElement::pad-removed ##### -->
 <para>
 
 </para>
 
-@gstelement: the object which received the signal.
-@arg1
+@
+@: 
 
 <!-- ##### SIGNAL GstElement::state-change ##### -->
 <para>
 
 </para>
 
-@gstelement: the object which received the signal.
-@arg1
-@arg2
+@
+@: 
+@: 
 
 <!-- ##### STRUCT GstElementClass ##### -->
 <para>
index 7d8089b..e5631b5 100644 (file)
@@ -96,6 +96,14 @@ GValue implementations specific to GStreamer
 @x: 
 
 
+<!-- ##### MACRO GST_VALUE_HOLDS_FRACTION ##### -->
+<para>
+
+</para>
+
+@x: 
+
+
 <!-- ##### MACRO GST_TYPE_FOURCC ##### -->
 <para>
 
@@ -131,6 +139,13 @@ GValue implementations specific to GStreamer
 
 
 
+<!-- ##### MACRO GST_TYPE_FRACTION ##### -->
+<para>
+
+</para>
+
+
+
 <!-- ##### MACRO GST_VALUE_LESS_THAN ##### -->
 <para>
 
@@ -262,6 +277,12 @@ GValue implementations specific to GStreamer
 </para>
 
 
+<!-- ##### VARIABLE gst_type_fraction ##### -->
+<para>
+
+</para>
+
+
 <!-- ##### FUNCTION gst_type_is_fixed ##### -->
 <para>
 
@@ -448,6 +469,45 @@ GValue implementations specific to GStreamer
 @calue: 
 
 
+<!-- ##### FUNCTION gst_value_get_fraction_numerator ##### -->
+<para>
+
+</para>
+
+@value: 
+@Returns: 
+
+
+<!-- ##### FUNCTION gst_value_get_fraction_denominator ##### -->
+<para>
+
+</para>
+
+@value: 
+@Returns: 
+
+
+<!-- ##### FUNCTION gst_value_set_fraction ##### -->
+<para>
+
+</para>
+
+@value: 
+@numerator: 
+@denominator: 
+
+
+<!-- ##### FUNCTION gst_value_fraction_multiply ##### -->
+<para>
+
+</para>
+
+@product: 
+@factor1: 
+@factor2: 
+@Returns: 
+
+
 <!-- ##### FUNCTION gst_value_compare ##### -->
 <para>
 
index c6a6802..4456ccf 100644 (file)
@@ -428,6 +428,13 @@ gst_structure_set_valist (GstStructure * structure,
 
           g_value_init (&field.value, GST_TYPE_BUFFER);
           g_value_set_boxed (&field.value, buffer);
+        } else if (type == GST_TYPE_FRACTION) {
+          gint n, d;
+          n = va_arg (varargs, int);
+          d = va_arg (varargs, int);
+
+          g_value_init (&field.value, GST_TYPE_FRACTION);
+          gst_value_set_fraction (&field.value, n, d);
         } else {
           g_critical ("unimplemented vararg field type %d\n", (int) type);
           return;
@@ -988,6 +995,7 @@ static GstStructureAbbreviation gst_structure_abbrs[] = {
 //{ "buffer",   GST_TYPE_BUFFER },
 //{ "fourcc",   GST_TYPE_FOURCC },
 //{ "4",   GST_TYPE_FOURCC },
+//{ "fraction",   GST_TYPE_FRACTION },
   {"boolean", G_TYPE_BOOLEAN},
   {"bool", G_TYPE_BOOLEAN},
   {"b", G_TYPE_BOOLEAN},
@@ -1016,6 +1024,9 @@ gst_structure_from_abbr (const char *type_name)
   if (strcmp (type_name, "buffer") == 0) {
     return GST_TYPE_BUFFER;
   }
+  if (strcmp (type_name, "fraction") == 0) {
+    return GST_TYPE_FRACTION;
+  }
 
   return g_type_from_name (type_name);
 }
@@ -1040,6 +1051,9 @@ gst_structure_to_abbr (GType type)
   if (type == GST_TYPE_BUFFER) {
     return "buffer";
   }
+  if (type == GST_TYPE_FRACTION) {
+    return "fraction";
+  }
 
   return g_type_name (type);
 }
index 23b8066..1ff920d 100644 (file)
@@ -57,6 +57,7 @@ GType gst_type_int_range;
 GType gst_type_double_range;
 GType gst_type_list;
 GType gst_type_fixed_list;
+GType gst_type_fraction;
 
 static GArray *gst_value_table;
 static GArray *gst_value_union_funcs;
@@ -2281,13 +2282,277 @@ gst_type_is_fixed (GType type)
     return TRUE;
   }
   if (type == GST_TYPE_BUFFER || type == GST_TYPE_FOURCC
-      || type == GST_TYPE_FIXED_LIST) {
+      || type == GST_TYPE_FIXED_LIST || type == GST_TYPE_FRACTION) {
     return TRUE;
   }
 
   return FALSE;
 }
 
+/************
+ * fraction *
+ ************/
+
+/* helper functions */
+
+/* Finds the greatest common divisor.
+ * Returns 1 if none other found.
+ * This is Euclid's algorithm. */
+static guint
+gst_greatest_common_divisor (gint64 a, gint64 b)
+{
+  while (b != 0) {
+    int temp = a;
+
+    a = b;
+    b = temp % b;
+  }
+
+  g_return_val_if_fail (a < G_MAXINT, 1);
+  g_return_val_if_fail (a > G_MININT, 1);
+  return ABS ((gint) a);
+}
+
+static void
+gst_value_init_fraction (GValue * value)
+{
+  value->data[0].v_int = 0;
+  value->data[1].v_int = 1;
+}
+
+static void
+gst_value_copy_fraction (const GValue * src_value, GValue * dest_value)
+{
+  dest_value->data[0].v_int = src_value->data[0].v_int;
+  dest_value->data[1].v_int = src_value->data[1].v_int;
+}
+
+static gchar *
+gst_value_collect_fraction (GValue * value, guint n_collect_values,
+    GTypeCValue * collect_values, guint collect_flags)
+{
+  value->data[0].v_int = collect_values[0].v_int;
+  value->data[1].v_int = collect_values[1].v_int;
+
+  return NULL;
+}
+
+static gchar *
+gst_value_lcopy_fraction (const GValue * value, guint n_collect_values,
+    GTypeCValue * collect_values, guint collect_flags)
+{
+  guint32 *numerator = collect_values[0].v_pointer;
+  guint32 *denominator = collect_values[1].v_pointer;
+
+  if (!numerator)
+    return g_strdup_printf ("numerator for `%s' passed as NULL",
+        G_VALUE_TYPE_NAME (value));
+  if (!denominator)
+    return g_strdup_printf ("denominator for `%s' passed as NULL",
+        G_VALUE_TYPE_NAME (value));
+
+  *numerator = value->data[0].v_int;
+  *denominator = value->data[1].v_int;
+
+  return NULL;
+}
+
+/**
+ * gst_value_set_fraction:
+ * @value: a GValue initialized to GST_TYPE_FRACTION
+ * @numerator: the numerator of the fraction
+ * @denominator: the denominator of the fraction
+ *
+ * Sets @value to the fraction specified by @numerator over @denominator.
+ * The fraction gets reduced to the smallest numerator and denominator,
+ * and if necessary the sign is moved to the numerator.
+ */
+void
+gst_value_set_fraction (GValue * value, gint numerator, gint denominator)
+{
+  g_return_if_fail (GST_VALUE_HOLDS_FRACTION (value));
+  g_return_if_fail (denominator != 0);
+  gint gcd = 0;
+
+  /* normalize sign */
+  if (denominator < 0) {
+    numerator = -numerator;
+    denominator = -denominator;
+  }
+
+  /* check for reduction */
+  gcd = gst_greatest_common_divisor (numerator, denominator);
+  if (gcd) {
+    numerator /= gcd;
+    denominator /= gcd;
+  }
+  value->data[0].v_int = numerator;
+  value->data[1].v_int = denominator;
+}
+
+/**
+ * gst_value_get_fraction_numerator:
+ * @value: a GValue initialized to GST_TYPE_FRACTION
+ *
+ * Gets the numerator of the fraction specified by @value.
+ *
+ * Returns: the numerator of the fraction.
+ */
+int
+gst_value_get_fraction_numerator (const GValue * value)
+{
+  g_return_val_if_fail (GST_VALUE_HOLDS_FRACTION (value), 0);
+
+  return value->data[0].v_int;
+}
+
+/**
+ * gst_value_get_fraction_denominator:
+ * @value: a GValue initialized to GST_TYPE_FRACTION
+ *
+ * Gets the denominator of the fraction specified by @value.
+ *
+ * Returns: the denominator of the fraction.
+ */
+int
+gst_value_get_fraction_denominator (const GValue * value)
+{
+  g_return_val_if_fail (GST_VALUE_HOLDS_FRACTION (value), 0);
+
+  return value->data[1].v_int;
+}
+
+/**
+ * gst_value_fraction_multiply:
+ * @product: a GValue initialized to GST_TYPE_FRACTION
+ * @factor1: a GValue initialized to GST_TYPE_FRACTION
+ * @factor2: a GValue initialized to GST_TYPE_FRACTION
+ *
+ * Multiplies the two GValues containing a GstFraction and sets @product
+ * to the product of the two fractions.
+ *
+ * Returns: FALSE in case of an error (like integer overflow), TRUE otherwise.
+ */
+gboolean
+gst_value_fraction_multiply (GValue * product, const GValue * factor1,
+    const GValue * factor2)
+{
+  gint64 n, d;
+  guint gcd;
+
+  gint n1, n2, d1, d2;
+
+  g_return_val_if_fail (GST_VALUE_HOLDS_FRACTION (factor1), FALSE);
+  g_return_val_if_fail (GST_VALUE_HOLDS_FRACTION (factor2), FALSE);
+
+  n1 = factor1->data[0].v_int;
+  n2 = factor2->data[0].v_int;
+  d1 = factor1->data[1].v_int;
+  d2 = factor2->data[1].v_int;
+
+  n = n1 * n2;
+  d = d1 * d2;
+
+  gcd = gst_greatest_common_divisor (n, d);
+  n /= gcd;
+  d /= gcd;
+
+  g_return_val_if_fail (n < G_MAXINT, FALSE);
+  g_return_val_if_fail (n > G_MININT, FALSE);
+  g_return_val_if_fail (d < G_MAXINT, FALSE);
+  g_return_val_if_fail (d > G_MININT, FALSE);
+
+  gst_value_set_fraction (product, n, d);
+
+  return TRUE;
+}
+
+static char *
+gst_value_serialize_fraction (const GValue * value)
+{
+  gint32 numerator = value->data[0].v_int;
+  gint32 denominator = value->data[1].v_int;
+  gboolean positive = TRUE;
+
+  /* get the sign and make components absolute */
+  if (numerator < 0) {
+    numerator = -numerator;
+    positive = !positive;
+  }
+  if (denominator < 0) {
+    denominator = -denominator;
+    positive = !positive;
+  }
+
+  return g_strdup_printf ("%s%d/%d",
+      positive ? "" : "-", numerator, denominator);
+}
+
+static gboolean
+gst_value_deserialize_fraction (GValue * dest, const char *s)
+{
+  gint num, den;
+  char *div;
+  char *tmp;
+
+  div = strstr (s, "/");
+  if (!div)
+    return FALSE;
+  tmp = strndup (s, (size_t) (div - s));
+  num = atoi (tmp);
+  free (tmp);
+  den = atoi (div + 1);
+
+  gst_value_set_fraction (dest, num, den);
+
+  return TRUE;
+}
+
+static void
+gst_value_transform_fraction_string (const GValue * src_value,
+    GValue * dest_value)
+{
+  dest_value->data[0].v_pointer = gst_value_serialize_fraction (src_value);
+}
+
+static void
+gst_value_transform_string_fraction (const GValue * src_value,
+    GValue * dest_value)
+{
+  gst_value_deserialize_fraction (dest_value, src_value->data[0].v_pointer);
+}
+
+static int
+gst_value_compare_fraction (const GValue * value1, const GValue * value2)
+{
+  /* FIXME: maybe we should make this more mathematically correct instead
+   * of approximating with gdoubles */
+
+  gint n1, n2;
+  gint d1, d2;
+
+  gdouble new_num_1;
+  gdouble new_num_2;
+
+  n1 = value1->data[0].v_int;
+  n2 = value2->data[0].v_int;
+  d1 = value1->data[1].v_int;
+  d2 = value2->data[1].v_int;
+
+  /* fractions are reduced when set, so we can quickly see if they're equal */
+  if (n1 == n2 && d1 == d2)
+    return GST_VALUE_EQUAL;
+
+  new_num_1 = n1 * d2;
+  new_num_2 = n2 * d1;
+  if (new_num_1 < new_num_2)
+    return GST_VALUE_LESS_THAN;
+  if (new_num_1 > new_num_2)
+    return GST_VALUE_GREATER_THAN;
+  g_assert_not_reached ();
+  return GST_VALUE_UNORDERED;
+}
+
 void
 _gst_value_initialize (void)
 {
@@ -2473,6 +2738,32 @@ _gst_value_initialize (void)
     gst_value.type = GST_TYPE_BUFFER;
     gst_value_register (&gst_value);
   }
+  {
+    static const GTypeValueTable value_table = {
+      gst_value_init_fraction,
+      NULL,
+      gst_value_copy_fraction,
+      NULL,
+      "ii",
+      gst_value_collect_fraction,
+      "pp",
+      gst_value_lcopy_fraction
+    };
+    static GstValueTable gst_value = {
+      0,
+      gst_value_compare_fraction,
+      gst_value_serialize_fraction,
+      gst_value_deserialize_fraction,
+    };
+
+    info.value_table = &value_table;
+    gst_type_fraction =
+        g_type_register_fundamental (g_type_fundamental_next (), "GstFraction",
+        &info, &finfo, 0);
+    gst_value.type = gst_type_fraction;
+    gst_value_register (&gst_value);
+  }
+
 
   REGISTER_SERIALIZATION (G_TYPE_DOUBLE, double);
   REGISTER_SERIALIZATION (G_TYPE_FLOAT, float);
@@ -2500,6 +2791,10 @@ _gst_value_initialize (void)
       gst_value_transform_list_string);
   g_value_register_transform_func (GST_TYPE_FIXED_LIST, G_TYPE_STRING,
       gst_value_transform_fixed_list_string);
+  g_value_register_transform_func (GST_TYPE_FRACTION, G_TYPE_STRING,
+      gst_value_transform_fraction_string);
+  g_value_register_transform_func (G_TYPE_STRING, GST_TYPE_FRACTION,
+      gst_value_transform_string_fraction);
 
   gst_value_register_intersect_func (G_TYPE_INT, GST_TYPE_INT_RANGE,
       gst_value_intersect_int_int_range);
index 77a5bc0..9f38e8e 100644 (file)
@@ -41,12 +41,14 @@ G_BEGIN_DECLS
 #define GST_VALUE_HOLDS_LIST(x)         (G_VALUE_HOLDS(x, gst_type_list))
 #define GST_VALUE_HOLDS_FIXED_LIST(x)   (G_VALUE_HOLDS(x, gst_type_fixed_list))
 #define GST_VALUE_HOLDS_CAPS(x)                (G_VALUE_HOLDS(x, GST_TYPE_CAPS))
+#define GST_VALUE_HOLDS_FRACTION(x)    (G_VALUE_HOLDS(x, gst_type_fraction))
 
 #define GST_TYPE_FOURCC                  gst_type_fourcc
 #define GST_TYPE_INT_RANGE               gst_type_int_range
 #define GST_TYPE_DOUBLE_RANGE            gst_type_double_range
 #define GST_TYPE_LIST                    gst_type_list
 #define GST_TYPE_FIXED_LIST              gst_type_fixed_list
+#define GST_TYPE_FRACTION                gst_type_fraction
 
 #define GST_VALUE_LESS_THAN              (-1)
 #define GST_VALUE_EQUAL                   0
@@ -83,6 +85,7 @@ extern GType gst_type_int_range;
 extern GType gst_type_double_range;
 extern GType gst_type_list;
 extern GType gst_type_fixed_list;
+extern GType gst_type_fraction;
 
 void           gst_value_register              (const GstValueTable   *table);
 void           gst_value_init_and_copy         (GValue                *dest,
@@ -130,6 +133,16 @@ G_CONST_RETURN GstCaps *
 void           gst_value_set_caps              (GValue         *value,
                                                 const GstCaps  *caps);
 
+/* fraction */
+void           gst_value_set_fraction          (GValue         *value,
+                                                int            numerator,
+                                                int            denominator);
+int            gst_value_get_fraction_numerator (const GValue  *value);
+int            gst_value_get_fraction_denominator(const GValue *value);
+gboolean       gst_value_fraction_multiply     (GValue         *product,
+                                                const GValue   *factor1,
+                                                const GValue   *factor2);
+
 /* compare */
 int            gst_value_compare               (const GValue   *value1,
                                                 const GValue   *value2);
index f9bf989..0a6e7c0 100644 (file)
@@ -10,6 +10,7 @@ tests_pass = \
        union \
        string-conversions \
        fixed \
+       fraction \
        intersect2 \
        caps \
        value_compare \
diff --git a/tests/old/testsuite/caps/fraction.c b/tests/old/testsuite/caps/fraction.c
new file mode 100644 (file)
index 0000000..f10623f
--- /dev/null
@@ -0,0 +1,100 @@
+/* GStreamer
+ *
+ * fraction.c: test for all GstFraction operations
+ *
+ * Copyright (C) <2004> Thomas Vander Stichele <thomas at apestaart dot org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <gst/gst.h>
+#include <glib.h>
+
+void
+test (void)
+{
+  GValue value1 = { 0 };
+  GValue value2 = { 0 };
+  GValue value3 = { 0 };
+
+  //gboolean ret;
+
+  /* comparing 2/3 with 3/4 */
+  g_value_init (&value1, GST_TYPE_FRACTION);
+  gst_value_set_fraction (&value1, 2, 3);
+  g_value_init (&value2, GST_TYPE_FRACTION);
+  gst_value_set_fraction (&value2, 3, 4);
+  g_assert (gst_value_compare (&value1, &value2) == GST_VALUE_LESS_THAN);
+  g_assert (gst_value_compare (&value2, &value1) == GST_VALUE_GREATER_THAN);
+  g_assert (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
+  g_value_unset (&value1);
+  g_value_unset (&value2);
+
+  /* comparing -4/5 with 2/-3 */
+  g_value_init (&value1, GST_TYPE_FRACTION);
+  gst_value_set_fraction (&value1, -4, 5);
+  g_value_init (&value2, GST_TYPE_FRACTION);
+  gst_value_set_fraction (&value2, 2, -3);
+  g_assert (gst_value_compare (&value1, &value2) == GST_VALUE_LESS_THAN);
+  g_assert (gst_value_compare (&value2, &value1) == GST_VALUE_GREATER_THAN);
+  g_assert (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
+  g_value_unset (&value1);
+  g_value_unset (&value2);
+
+  /* comparing 10/100 with 20/2000 */
+  g_value_init (&value1, GST_TYPE_FRACTION);
+  gst_value_set_fraction (&value1, 10, 100);
+  g_value_init (&value2, GST_TYPE_FRACTION);
+  gst_value_set_fraction (&value2, 200, 2000);
+  g_assert (gst_value_compare (&value1, &value2) == GST_VALUE_EQUAL);
+  g_value_unset (&value1);
+  g_value_unset (&value2);
+
+  /* comparing -4/5 with 2/-3 */
+  g_value_init (&value1, GST_TYPE_FRACTION);
+  gst_value_set_fraction (&value1, -4, 5);
+  g_value_init (&value2, GST_TYPE_FRACTION);
+  gst_value_set_fraction (&value2, 2, -3);
+  g_assert (gst_value_compare (&value1, &value2) == GST_VALUE_LESS_THAN);
+  g_assert (gst_value_compare (&value2, &value1) == GST_VALUE_GREATER_THAN);
+  g_assert (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
+  g_value_unset (&value1);
+  g_value_unset (&value2);
+
+  /* multiplying 4/5 with 3/-2 */
+  g_value_init (&value1, GST_TYPE_FRACTION);
+  gst_value_set_fraction (&value1, 4, 5);
+  g_value_init (&value2, GST_TYPE_FRACTION);
+  gst_value_set_fraction (&value2, 3, -2);
+  g_value_init (&value3, GST_TYPE_FRACTION);
+  g_assert (gst_value_fraction_multiply (&value3, &value1, &value2));
+  g_assert (gst_value_get_fraction_nominator (&value3) == -6);
+  g_assert (gst_value_get_fraction_denominator (&value3) == 5);
+  g_value_unset (&value1);
+  g_value_unset (&value2);
+  g_value_unset (&value3);
+}
+
+int
+main (int argc, char *argv[])
+{
+
+  gst_init (&argc, &argv);
+
+  test ();
+
+  return 0;
+}
index 5da8cd2..e28c3bd 100644 (file)
@@ -19,7 +19,8 @@ GstStaticCaps caps6 = GST_STATIC_CAPS ("video/raw, "
     "fourcc=(fourcc){\"YV12\",\"YUYV\"}, " "height=(int)[16,4096]");
 
 GstStaticCaps caps7 = GST_STATIC_CAPS ("video/raw, "
-    "fourcc=(fourcc){\"YVYV\",\"YUY2\"}, " "height=(int)[16,4096]");
+    "fourcc=(fourcc){\"YVYV\",\"YUY2\"}, " "height=(int)[16,4096],"
+    "pixel-aspect-ratio=(fraction)16/15");
 
 GstStaticCaps caps8 = GST_STATIC_CAPS ("video/raw, "
     "format=(fourcc)\"I420\"; " "video/raw, " "format=(fourcc)\"YUYV\"");
@@ -136,6 +137,7 @@ bla:
   test_string ("audio/raw  ,test=(b ) yes");
   test_string ("audio/raw  ,test =( boolean)no");
   test_string ("audio/raw  ,test = < 1, 2, 3 >");
+  test_string ("video/raw  ,test =( fraction)9/8");
 
   /* buffers */
   test_string ("audio/raw  ,test=(buffer)0123456789abcdef");
index 646e333..cdce4bd 100644 (file)
@@ -7,6 +7,7 @@ test1 (void)
 {
   GValue value1 = { 0 };
   GValue value2 = { 0 };
+
   //GValue value3 = { 0 };
   //gboolean ret;
 
@@ -49,6 +50,48 @@ test1 (void)
   g_value_unset (&value1);
   g_value_unset (&value2);
 
+  /* comparing 2/3 with 3/4 */
+  g_value_init (&value1, GST_TYPE_FRACTION);
+  gst_value_set_fraction (&value1, 2, 3);
+  g_value_init (&value2, GST_TYPE_FRACTION);
+  gst_value_set_fraction (&value2, 3, 4);
+  g_assert (gst_value_compare (&value1, &value2) == GST_VALUE_LESS_THAN);
+  g_assert (gst_value_compare (&value2, &value1) == GST_VALUE_GREATER_THAN);
+  g_assert (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
+  g_value_unset (&value1);
+  g_value_unset (&value2);
+
+  /* comparing -4/5 with 2/-3 */
+  g_value_init (&value1, GST_TYPE_FRACTION);
+  gst_value_set_fraction (&value1, -4, 5);
+  g_value_init (&value2, GST_TYPE_FRACTION);
+  gst_value_set_fraction (&value2, 2, -3);
+  g_assert (gst_value_compare (&value1, &value2) == GST_VALUE_LESS_THAN);
+  g_assert (gst_value_compare (&value2, &value1) == GST_VALUE_GREATER_THAN);
+  g_assert (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
+  g_value_unset (&value1);
+  g_value_unset (&value2);
+
+  /* comparing 10/100 with 20/2000 */
+  g_value_init (&value1, GST_TYPE_FRACTION);
+  gst_value_set_fraction (&value1, 10, 100);
+  g_value_init (&value2, GST_TYPE_FRACTION);
+  gst_value_set_fraction (&value2, 200, 2000);
+  g_assert (gst_value_compare (&value1, &value2) == GST_VALUE_EQUAL);
+  g_value_unset (&value1);
+  g_value_unset (&value2);
+
+  /* comparing -4/5 with 2/-3 */
+  g_value_init (&value1, GST_TYPE_FRACTION);
+  gst_value_set_fraction (&value1, -4, 5);
+  g_value_init (&value2, GST_TYPE_FRACTION);
+  gst_value_set_fraction (&value2, 2, -3);
+  g_assert (gst_value_compare (&value1, &value2) == GST_VALUE_LESS_THAN);
+  g_assert (gst_value_compare (&value2, &value1) == GST_VALUE_GREATER_THAN);
+  g_assert (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
+  g_value_unset (&value1);
+  g_value_unset (&value2);
+
 }
 
 int
@@ -60,5 +103,4 @@ main (int argc, char *argv[])
   test1 ();
 
   return 0;
-
 }
index f9bf989..0a6e7c0 100644 (file)
@@ -10,6 +10,7 @@ tests_pass = \
        union \
        string-conversions \
        fixed \
+       fraction \
        intersect2 \
        caps \
        value_compare \
diff --git a/testsuite/caps/fraction.c b/testsuite/caps/fraction.c
new file mode 100644 (file)
index 0000000..f10623f
--- /dev/null
@@ -0,0 +1,100 @@
+/* GStreamer
+ *
+ * fraction.c: test for all GstFraction operations
+ *
+ * Copyright (C) <2004> Thomas Vander Stichele <thomas at apestaart dot org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <gst/gst.h>
+#include <glib.h>
+
+void
+test (void)
+{
+  GValue value1 = { 0 };
+  GValue value2 = { 0 };
+  GValue value3 = { 0 };
+
+  //gboolean ret;
+
+  /* comparing 2/3 with 3/4 */
+  g_value_init (&value1, GST_TYPE_FRACTION);
+  gst_value_set_fraction (&value1, 2, 3);
+  g_value_init (&value2, GST_TYPE_FRACTION);
+  gst_value_set_fraction (&value2, 3, 4);
+  g_assert (gst_value_compare (&value1, &value2) == GST_VALUE_LESS_THAN);
+  g_assert (gst_value_compare (&value2, &value1) == GST_VALUE_GREATER_THAN);
+  g_assert (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
+  g_value_unset (&value1);
+  g_value_unset (&value2);
+
+  /* comparing -4/5 with 2/-3 */
+  g_value_init (&value1, GST_TYPE_FRACTION);
+  gst_value_set_fraction (&value1, -4, 5);
+  g_value_init (&value2, GST_TYPE_FRACTION);
+  gst_value_set_fraction (&value2, 2, -3);
+  g_assert (gst_value_compare (&value1, &value2) == GST_VALUE_LESS_THAN);
+  g_assert (gst_value_compare (&value2, &value1) == GST_VALUE_GREATER_THAN);
+  g_assert (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
+  g_value_unset (&value1);
+  g_value_unset (&value2);
+
+  /* comparing 10/100 with 20/2000 */
+  g_value_init (&value1, GST_TYPE_FRACTION);
+  gst_value_set_fraction (&value1, 10, 100);
+  g_value_init (&value2, GST_TYPE_FRACTION);
+  gst_value_set_fraction (&value2, 200, 2000);
+  g_assert (gst_value_compare (&value1, &value2) == GST_VALUE_EQUAL);
+  g_value_unset (&value1);
+  g_value_unset (&value2);
+
+  /* comparing -4/5 with 2/-3 */
+  g_value_init (&value1, GST_TYPE_FRACTION);
+  gst_value_set_fraction (&value1, -4, 5);
+  g_value_init (&value2, GST_TYPE_FRACTION);
+  gst_value_set_fraction (&value2, 2, -3);
+  g_assert (gst_value_compare (&value1, &value2) == GST_VALUE_LESS_THAN);
+  g_assert (gst_value_compare (&value2, &value1) == GST_VALUE_GREATER_THAN);
+  g_assert (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
+  g_value_unset (&value1);
+  g_value_unset (&value2);
+
+  /* multiplying 4/5 with 3/-2 */
+  g_value_init (&value1, GST_TYPE_FRACTION);
+  gst_value_set_fraction (&value1, 4, 5);
+  g_value_init (&value2, GST_TYPE_FRACTION);
+  gst_value_set_fraction (&value2, 3, -2);
+  g_value_init (&value3, GST_TYPE_FRACTION);
+  g_assert (gst_value_fraction_multiply (&value3, &value1, &value2));
+  g_assert (gst_value_get_fraction_nominator (&value3) == -6);
+  g_assert (gst_value_get_fraction_denominator (&value3) == 5);
+  g_value_unset (&value1);
+  g_value_unset (&value2);
+  g_value_unset (&value3);
+}
+
+int
+main (int argc, char *argv[])
+{
+
+  gst_init (&argc, &argv);
+
+  test ();
+
+  return 0;
+}
index 5da8cd2..e28c3bd 100644 (file)
@@ -19,7 +19,8 @@ GstStaticCaps caps6 = GST_STATIC_CAPS ("video/raw, "
     "fourcc=(fourcc){\"YV12\",\"YUYV\"}, " "height=(int)[16,4096]");
 
 GstStaticCaps caps7 = GST_STATIC_CAPS ("video/raw, "
-    "fourcc=(fourcc){\"YVYV\",\"YUY2\"}, " "height=(int)[16,4096]");
+    "fourcc=(fourcc){\"YVYV\",\"YUY2\"}, " "height=(int)[16,4096],"
+    "pixel-aspect-ratio=(fraction)16/15");
 
 GstStaticCaps caps8 = GST_STATIC_CAPS ("video/raw, "
     "format=(fourcc)\"I420\"; " "video/raw, " "format=(fourcc)\"YUYV\"");
@@ -136,6 +137,7 @@ bla:
   test_string ("audio/raw  ,test=(b ) yes");
   test_string ("audio/raw  ,test =( boolean)no");
   test_string ("audio/raw  ,test = < 1, 2, 3 >");
+  test_string ("video/raw  ,test =( fraction)9/8");
 
   /* buffers */
   test_string ("audio/raw  ,test=(buffer)0123456789abcdef");
index 646e333..cdce4bd 100644 (file)
@@ -7,6 +7,7 @@ test1 (void)
 {
   GValue value1 = { 0 };
   GValue value2 = { 0 };
+
   //GValue value3 = { 0 };
   //gboolean ret;
 
@@ -49,6 +50,48 @@ test1 (void)
   g_value_unset (&value1);
   g_value_unset (&value2);
 
+  /* comparing 2/3 with 3/4 */
+  g_value_init (&value1, GST_TYPE_FRACTION);
+  gst_value_set_fraction (&value1, 2, 3);
+  g_value_init (&value2, GST_TYPE_FRACTION);
+  gst_value_set_fraction (&value2, 3, 4);
+  g_assert (gst_value_compare (&value1, &value2) == GST_VALUE_LESS_THAN);
+  g_assert (gst_value_compare (&value2, &value1) == GST_VALUE_GREATER_THAN);
+  g_assert (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
+  g_value_unset (&value1);
+  g_value_unset (&value2);
+
+  /* comparing -4/5 with 2/-3 */
+  g_value_init (&value1, GST_TYPE_FRACTION);
+  gst_value_set_fraction (&value1, -4, 5);
+  g_value_init (&value2, GST_TYPE_FRACTION);
+  gst_value_set_fraction (&value2, 2, -3);
+  g_assert (gst_value_compare (&value1, &value2) == GST_VALUE_LESS_THAN);
+  g_assert (gst_value_compare (&value2, &value1) == GST_VALUE_GREATER_THAN);
+  g_assert (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
+  g_value_unset (&value1);
+  g_value_unset (&value2);
+
+  /* comparing 10/100 with 20/2000 */
+  g_value_init (&value1, GST_TYPE_FRACTION);
+  gst_value_set_fraction (&value1, 10, 100);
+  g_value_init (&value2, GST_TYPE_FRACTION);
+  gst_value_set_fraction (&value2, 200, 2000);
+  g_assert (gst_value_compare (&value1, &value2) == GST_VALUE_EQUAL);
+  g_value_unset (&value1);
+  g_value_unset (&value2);
+
+  /* comparing -4/5 with 2/-3 */
+  g_value_init (&value1, GST_TYPE_FRACTION);
+  gst_value_set_fraction (&value1, -4, 5);
+  g_value_init (&value2, GST_TYPE_FRACTION);
+  gst_value_set_fraction (&value2, 2, -3);
+  g_assert (gst_value_compare (&value1, &value2) == GST_VALUE_LESS_THAN);
+  g_assert (gst_value_compare (&value2, &value1) == GST_VALUE_GREATER_THAN);
+  g_assert (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
+  g_value_unset (&value1);
+  g_value_unset (&value2);
+
 }
 
 int
@@ -60,5 +103,4 @@ main (int argc, char *argv[])
   test1 ();
 
   return 0;
-
 }