From 614b4d162727c8c8c955a2489c09756a4b8529a8 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Wed, 21 Apr 2004 03:25:13 +0000 Subject: [PATCH] gst/gstcaps.c: check for ANY caps before appending/unioning Original commit message from CVS: * gst/gstcaps.c: (gst_caps_append), (gst_caps_union): check for ANY caps before appending/unioning * gst/gstcaps.c: (gst_caps_is_subset), (gst_caps_is_equal), (gst_caps_structure_subtract_field), (gst_caps_structure_subtract), (gst_caps_subtract): * gst/gstcaps.h: add gst_caps_is_equal, gst_caps_is_subset and gst_caps_subtract to the API. deprecate gst_caps_is_equal_fixed * gst/gstpad.c: (gst_pad_try_set_caps): * gst/gstqueue.c: (gst_queue_link): s/gst_caps_is_equal_fixed/gst_caps_is_equal/ * gst/gststructure.c: (gst_structure_get_name_id): * gst/gststructure.h: add function gst_structure_get_name_id * gst/gstvalue.c: (gst_value_subtract_int_int_range), (gst_value_create_new_range), (gst_value_subtract_int_range_int), (gst_value_subtract_int_range_int_range), (gst_value_subtract_double_double_range), (gst_value_subtract_double_range_double), (gst_value_subtract_double_range_double_range), (gst_value_subtract_from_list), (gst_value_subtract_list), (gst_value_can_intersect), (gst_value_subtract), (gst_value_can_subtract), (gst_value_register_subtract_func), (_gst_value_initialize): * gst/gstvalue.h: add support for subtracting values from each other. Note that subtracting means subtracting as in set theory. Required for caps stuff above. * testsuite/caps/.cvsignore: * testsuite/caps/Makefile.am: * testsuite/caps/erathostenes.c: (erathostenes), (main): * testsuite/caps/sets.c: (check_caps), (main): * testsuite/caps/subtract.c: (check_caps), (main): add tests for subtraction and equality code. --- ChangeLog | 37 +++ gst/gstcaps.c | 138 +++++++++++- gst/gstcaps.h | 10 +- gst/gstpad.c | 2 +- gst/gstqueue.c | 2 +- gst/gststructure.c | 16 ++ gst/gststructure.h | 1 + gst/gstvalue.c | 387 +++++++++++++++++++++++++++++++- gst/gstvalue.h | 14 ++ plugins/elements/gstqueue.c | 2 +- tests/old/testsuite/caps/.gitignore | 7 +- tests/old/testsuite/caps/Makefile.am | 13 +- tests/old/testsuite/caps/erathostenes.c | 71 ++++++ tests/old/testsuite/caps/sets.c | 91 ++++++++ tests/old/testsuite/caps/subtract.c | 63 ++++++ testsuite/caps/.gitignore | 7 +- testsuite/caps/Makefile.am | 13 +- testsuite/caps/erathostenes.c | 71 ++++++ testsuite/caps/sets.c | 91 ++++++++ testsuite/caps/subtract.c | 63 ++++++ 20 files changed, 1080 insertions(+), 19 deletions(-) create mode 100644 tests/old/testsuite/caps/erathostenes.c create mode 100644 tests/old/testsuite/caps/sets.c create mode 100644 tests/old/testsuite/caps/subtract.c create mode 100644 testsuite/caps/erathostenes.c create mode 100644 testsuite/caps/sets.c create mode 100644 testsuite/caps/subtract.c diff --git a/ChangeLog b/ChangeLog index 0ea88f4..1c7dc48 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,40 @@ +2004-04-21 Benjamin Otte + + * gst/gstcaps.c: (gst_caps_append), (gst_caps_union): + check for ANY caps before appending/unioning + * gst/gstcaps.c: (gst_caps_is_subset), + (gst_caps_is_equal), (gst_caps_structure_subtract_field), + (gst_caps_structure_subtract), (gst_caps_subtract): + * gst/gstcaps.h: + add gst_caps_is_equal, gst_caps_is_subset and gst_caps_subtract to + the API. deprecate gst_caps_is_equal_fixed + * gst/gstpad.c: (gst_pad_try_set_caps): + * gst/gstqueue.c: (gst_queue_link): + s/gst_caps_is_equal_fixed/gst_caps_is_equal/ + * gst/gststructure.c: (gst_structure_get_name_id): + * gst/gststructure.h: + add function gst_structure_get_name_id + * gst/gstvalue.c: (gst_value_subtract_int_int_range), + (gst_value_create_new_range), (gst_value_subtract_int_range_int), + (gst_value_subtract_int_range_int_range), + (gst_value_subtract_double_double_range), + (gst_value_subtract_double_range_double), + (gst_value_subtract_double_range_double_range), + (gst_value_subtract_from_list), (gst_value_subtract_list), + (gst_value_can_intersect), (gst_value_subtract), + (gst_value_can_subtract), (gst_value_register_subtract_func), + (_gst_value_initialize): + * gst/gstvalue.h: + add support for subtracting values from each other. Note that + subtracting means subtracting as in set theory. Required for caps + stuff above. + * testsuite/caps/.cvsignore: + * testsuite/caps/Makefile.am: + * testsuite/caps/erathostenes.c: (erathostenes), (main): + * testsuite/caps/sets.c: (check_caps), (main): + * testsuite/caps/subtract.c: (check_caps), (main): + add tests for subtraction and equality code. + 2004-04-20 David Schleef * gst/autoplug/Makefile.am: Fix some little buglets in last checkin. diff --git a/gst/gstcaps.c b/gst/gstcaps.c index b5cef4a..c1ebb59 100644 --- a/gst/gstcaps.c +++ b/gst/gstcaps.c @@ -295,9 +295,17 @@ gst_caps_append (GstCaps * caps1, GstCaps * caps2) #ifdef USE_POISONING CAPS_POISON (caps2); #endif - for (i = 0; i < caps2->structs->len; i++) { - structure = gst_caps_get_structure (caps2, i); - gst_caps_append_structure (caps1, structure); + if (gst_caps_is_any (caps1) || gst_caps_is_any (caps2)) { + caps1->flags |= GST_CAPS_FLAGS_ANY; + for (i = 0; i < caps2->structs->len; i++) { + structure = gst_caps_get_structure (caps2, i); + gst_structure_remove_all_fields (structure); + } + } else { + for (i = 0; i < caps2->structs->len; i++) { + structure = gst_caps_get_structure (caps2, i); + gst_caps_append_structure (caps1, structure); + } } g_ptr_array_free (caps2->structs, TRUE); #ifdef USE_POISONING @@ -690,6 +698,38 @@ gst_caps_is_always_compatible (const GstCaps * caps1, const GstCaps * caps2) return FALSE; } +gboolean +gst_caps_is_subset (const GstCaps * subset, const GstCaps * superset) +{ + GstCaps *caps; + gboolean ret; + + g_return_val_if_fail (subset != NULL, FALSE); + g_return_val_if_fail (superset != NULL, FALSE); + + if (gst_caps_is_empty (subset) || gst_caps_is_any (superset)) + return TRUE; + if (gst_caps_is_any (subset) || gst_caps_is_empty (superset)) + return FALSE; + + caps = gst_caps_subtract (subset, superset); + ret = gst_caps_is_empty (caps); + gst_caps_free (caps); + return ret; +} + +gboolean +gst_caps_is_equal (const GstCaps * caps1, const GstCaps * caps2) +{ + g_return_val_if_fail (caps1 != NULL, FALSE); + g_return_val_if_fail (caps2 != NULL, FALSE); + + if (gst_caps_is_fixed (caps1) && gst_caps_is_fixed (caps2)) + return gst_caps_is_equal_fixed (caps1, caps2); + + return gst_caps_is_subset (caps1, caps2) && gst_caps_is_subset (caps2, caps1); +} + typedef struct { GstStructure *dest; @@ -849,6 +889,95 @@ gst_caps_intersect (const GstCaps * caps1, const GstCaps * caps2) #endif } +typedef struct +{ + const GstStructure *subtract_from; + GstCaps *put_into; +} +SubtractionEntry; + + +gboolean +gst_caps_structure_subtract_field (GQuark field_id, GValue * value, + gpointer user_data) +{ + SubtractionEntry *e = user_data; + GValue subtraction = { 0, }; + const GValue *other; + GstStructure *structure; + + other = gst_structure_id_get_value (e->subtract_from, field_id); + if (!other) + return TRUE; + if (!gst_value_subtract (&subtraction, other, value)) + return TRUE; + structure = gst_structure_copy (e->subtract_from); + if (gst_value_compare (&subtraction, other) == GST_VALUE_EQUAL) { + gst_caps_append_structure (e->put_into, structure); + return FALSE; + } else { + gst_structure_id_set_value (structure, field_id, &subtraction); + g_value_unset (&subtraction); + gst_caps_append_structure (e->put_into, structure); + return TRUE; + } +} + +static void +gst_caps_structure_subtract (GstCaps * into, const GstStructure * minuend, + const GstStructure * subtrahend) +{ + SubtractionEntry e; + + e.subtract_from = minuend; + e.put_into = into; + + gst_structure_foreach ((GstStructure *) subtrahend, + gst_caps_structure_subtract_field, &e); +} + +GstCaps * +gst_caps_subtract (const GstCaps * minuend, const GstCaps * subtrahend) +{ + int i, j; + GstStructure *min; + GstStructure *sub; + GstCaps *dest = NULL, *src; + + g_return_val_if_fail (minuend != NULL, NULL); + /* what would that be ? */ + g_return_val_if_fail (!gst_caps_is_any (minuend), NULL); + g_return_val_if_fail (subtrahend != NULL, NULL); + + if (gst_caps_is_empty (minuend) || gst_caps_is_any (subtrahend)) { + return gst_caps_new_empty (); + } + if (gst_caps_is_empty (subtrahend)) + return gst_caps_copy (minuend); + + src = gst_caps_copy (minuend); + for (i = 0; i < subtrahend->structs->len; i++) { + sub = gst_caps_get_structure (subtrahend, i); + if (dest) { + gst_caps_free (src); + src = dest; + } + dest = gst_caps_new_empty (); + for (j = 0; j < src->structs->len; j++) { + min = gst_caps_get_structure (src, j); + if (gst_structure_get_name_id (min) == gst_structure_get_name_id (sub)) { + gst_caps_structure_subtract (dest, min, sub); + } else { + gst_caps_append_structure (dest, gst_structure_copy (min)); + } + } + if (gst_caps_is_empty (dest)) + return dest; + } + + return dest; +} + /** * gst_caps_union: * @caps1: a #GstCaps to union @@ -865,6 +994,9 @@ gst_caps_union (const GstCaps * caps1, const GstCaps * caps2) GstCaps *dest1; GstCaps *dest2; + if (gst_caps_is_any (caps1) || gst_caps_is_any (caps2)) + return gst_caps_new_any (); + dest1 = gst_caps_copy (caps1); dest2 = gst_caps_copy (caps2); gst_caps_append (dest1, dest2); diff --git a/gst/gstcaps.h b/gst/gstcaps.h index ef3e94f..d0ad570 100644 --- a/gst/gstcaps.h +++ b/gst/gstcaps.h @@ -106,16 +106,22 @@ gboolean gst_caps_is_any (const G gboolean gst_caps_is_empty (const GstCaps *caps); #ifndef GST_DISABLE_DEPRECATED gboolean gst_caps_is_chained (const GstCaps *caps); -#endif -gboolean gst_caps_is_fixed (const GstCaps *caps); gboolean gst_caps_is_equal_fixed (const GstCaps *caps1, const GstCaps *caps2); +#endif +gboolean gst_caps_is_fixed (const GstCaps *caps); gboolean gst_caps_is_always_compatible (const GstCaps *caps1, const GstCaps *caps2); +gboolean gst_caps_is_subset (const GstCaps *subset, + const GstCaps *superset); +gboolean gst_caps_is_equal (const GstCaps *caps1, + const GstCaps *caps2); /* operations */ GstCaps * gst_caps_intersect (const GstCaps *caps1, const GstCaps *caps2); +GstCaps * gst_caps_subtract (const GstCaps *minuend, + const GstCaps *subtrahend); GstCaps * gst_caps_union (const GstCaps *caps1, const GstCaps *caps2); GstCaps * gst_caps_normalize (const GstCaps *caps); diff --git a/gst/gstpad.c b/gst/gstpad.c index 480a704..a953823 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -1449,7 +1449,7 @@ gst_pad_try_set_caps (GstPad * pad, const GstCaps * caps) g_return_val_if_fail (GST_PAD_LINK_SINK (pad), GST_PAD_LINK_REFUSED); /* if the desired caps are already there, it's trivially ok */ - if (GST_PAD_CAPS (pad) && gst_caps_is_equal_fixed (caps, GST_PAD_CAPS (pad))) { + if (GST_PAD_CAPS (pad) && gst_caps_is_equal (caps, GST_PAD_CAPS (pad))) { return GST_PAD_LINK_OK; } diff --git a/gst/gstqueue.c b/gst/gstqueue.c index b86b517..3b9cb44 100644 --- a/gst/gstqueue.c +++ b/gst/gstqueue.c @@ -340,7 +340,7 @@ gst_queue_link (GstPad * pad, const GstCaps * caps) queue = GST_QUEUE (gst_pad_get_parent (pad)); if (queue->cur_level.bytes > 0) { - if (gst_caps_is_equal_fixed (caps, queue->negotiated_caps)) { + if (gst_caps_is_equal (caps, queue->negotiated_caps)) { return GST_PAD_LINK_OK; } return GST_PAD_LINK_REFUSED; diff --git a/gst/gststructure.c b/gst/gststructure.c index d420e21..8319f5a 100644 --- a/gst/gststructure.c +++ b/gst/gststructure.c @@ -248,6 +248,22 @@ gst_structure_get_name (const GstStructure * structure) } /** + * gst_structure_get_name: + * @structure: a #GstStructure + * + * Accessor fuction. + * + * Returns: the quark representing the name of the structure. + */ +GQuark +gst_structure_get_name_id (const GstStructure * structure) +{ + g_return_val_if_fail (structure != NULL, 0); + + return structure->name; +} + +/** * gst_structure_set_name: * @structure: a #GstStructure * @name: the new name of the structure diff --git a/gst/gststructure.h b/gst/gststructure.h index b2834d0..fcc4f95 100644 --- a/gst/gststructure.h +++ b/gst/gststructure.h @@ -60,6 +60,7 @@ GstStructure * gst_structure_copy (const GstStructure void gst_structure_free (GstStructure *structure); G_CONST_RETURN gchar * gst_structure_get_name (const GstStructure *structure); +GQuark gst_structure_get_name_id (const GstStructure *structure); void gst_structure_set_name (GstStructure *structure, const gchar *name); diff --git a/gst/gstvalue.c b/gst/gstvalue.c index efa108f..25b273f 100644 --- a/gst/gstvalue.c +++ b/gst/gstvalue.c @@ -44,6 +44,15 @@ struct _GstValueIntersectInfo GstValueIntersectFunc func; }; +typedef struct _GstValueSubtractInfo GstValueSubtractInfo; +struct _GstValueSubtractInfo +{ + GType minuend; + GType subtrahend; + GstValueSubtractFunc func; +}; + +GType gst_type_fourcc; GType gst_type_fourcc; GType gst_type_int_range; GType gst_type_double_range; @@ -52,6 +61,7 @@ GType gst_type_list; static GArray *gst_value_table; static GArray *gst_value_union_funcs; static GArray *gst_value_intersect_funcs; +static GArray *gst_value_subtract_funcs; /*************************************/ /* list */ @@ -1235,6 +1245,252 @@ gst_value_intersect_list (GValue * dest, const GValue * value1, return ret; } +/*************************************/ +/* subtraction */ + +static gboolean +gst_value_subtract_int_int_range (GValue * dest, const GValue * minuend, + const GValue * subtrahend) +{ + int min = gst_value_get_int_range_min (subtrahend); + int max = gst_value_get_int_range_max (subtrahend); + int val = g_value_get_int (minuend); + + if (val < min || val > max) { + gst_value_init_and_copy (dest, minuend); + return TRUE; + } + return FALSE; +} + +static gboolean +gst_value_create_new_range (GValue * dest, int min1, int max1, int min2, + int max2) +{ + GValue v1 = { 0, }; + GValue v2 = { 0, }; + GValue *pv1, *pv2; /* yeah, hungarian! */ + + if (min1 <= max1 && min2 <= max2) { + pv1 = &v1; + pv2 = &v2; + } else if (min1 <= max1) { + pv1 = dest; + } else if (min2 <= max2) { + pv2 = dest; + } else { + return FALSE; + } + + if (min1 < max1) { + g_value_init (pv1, GST_TYPE_INT_RANGE); + gst_value_set_int_range (pv1, min1, max1); + } else if (min1 == max1) { + g_value_init (pv1, G_TYPE_INT); + g_value_set_int (pv1, min1); + } + if (min2 < max2) { + g_value_init (pv2, GST_TYPE_INT_RANGE); + gst_value_set_int_range (pv2, min2, max2); + } else if (min2 == max2) { + g_value_init (pv2, G_TYPE_INT); + g_value_set_int (pv2, min2); + } + + if (min1 <= max1 && min2 <= max2) { + gst_value_list_concat (dest, pv1, pv2); + g_value_unset (pv1); + g_value_unset (pv2); + } + return TRUE; +} + +static gboolean +gst_value_subtract_int_range_int (GValue * dest, const GValue * minuend, + const GValue * subtrahend) +{ + int min = gst_value_get_int_range_min (minuend); + int max = gst_value_get_int_range_max (minuend); + int val = g_value_get_int (subtrahend); + + g_return_val_if_fail (min < max, FALSE); + + if (val < min || val > max) { + gst_value_init_and_copy (dest, minuend); + return TRUE; + } else { + if (val == G_MAXINT) { + max--; + val--; + } + if (val == G_MININT) { + min++; + val++; + } + gst_value_create_new_range (dest, min, val - 1, val + 1, max); + } + return TRUE; +} + +static gboolean +gst_value_subtract_int_range_int_range (GValue * dest, const GValue * minuend, + const GValue * subtrahend) +{ + int min1 = gst_value_get_int_range_min (minuend); + int max1 = gst_value_get_int_range_max (minuend); + int min2 = gst_value_get_int_range_min (subtrahend); + int max2 = gst_value_get_int_range_max (subtrahend); + + if (max2 == G_MAXINT) { + max2--; + max1--; + } + if (min2 == G_MININT) { + min2++; + min1++; + } + return gst_value_create_new_range (dest, min1, MIN (min2 - 1, max1), + MAX (max2 + 1, min1), max1); +} + +static gboolean +gst_value_subtract_double_double_range (GValue * dest, const GValue * minuend, + const GValue * subtrahend) +{ + double min = gst_value_get_double_range_min (subtrahend); + double max = gst_value_get_double_range_max (subtrahend); + double val = g_value_get_double (minuend); + + if (val < min || val > max) { + gst_value_init_and_copy (dest, minuend); + return TRUE; + } + return FALSE; +} + +static gboolean +gst_value_subtract_double_range_double (GValue * dest, const GValue * minuend, + const GValue * subtrahend) +{ + /* FIXME! */ + gst_value_init_and_copy (dest, minuend); + return TRUE; +} + +static gboolean +gst_value_subtract_double_range_double_range (GValue * dest, + const GValue * minuend, const GValue * subtrahend) +{ + /* FIXME! */ + /* done like with ints */ + double min1 = gst_value_get_double_range_min (minuend); + double max2 = gst_value_get_double_range_max (minuend); + double max1 = MIN (gst_value_get_double_range_min (subtrahend), max2); + double min2 = MAX (gst_value_get_double_range_max (subtrahend), min1); + GValue v1 = { 0, }; + GValue v2 = { 0, }; + GValue *pv1, *pv2; /* yeah, hungarian! */ + + if (min1 < max1 && min2 < max2) { + pv1 = &v1; + pv2 = &v2; + } else if (min1 < max1) { + pv1 = dest; + } else if (min2 < max2) { + pv2 = dest; + } else { + return FALSE; + } + + if (min1 < max1) { + g_value_init (pv1, GST_TYPE_DOUBLE_RANGE); + gst_value_set_double_range (pv1, min1, max1); + } + if (min2 < max2) { + g_value_init (pv2, GST_TYPE_DOUBLE_RANGE); + gst_value_set_double_range (pv2, min2, max2); + } + + if (min1 < max1 && min2 < max2) { + gst_value_list_concat (dest, pv1, pv2); + g_value_unset (pv1); + g_value_unset (pv2); + } + return TRUE; +} + +static gboolean +gst_value_subtract_from_list (GValue * dest, const GValue * minuend, + const GValue * subtrahend) +{ + guint i, size; + GValue subtraction = { 0, }; + gboolean ret = FALSE; + + g_return_val_if_fail (GST_VALUE_HOLDS_LIST (minuend), FALSE); + + size = gst_value_list_get_size (minuend); + for (i = 0; i < size; i++) { + const GValue *cur = gst_value_list_get_value (minuend, i); + + if (gst_value_subtract (&subtraction, cur, subtrahend)) { + if (!ret) { + gst_value_init_and_copy (dest, &subtraction); + ret = TRUE; + } else if (GST_VALUE_HOLDS_LIST (dest) + && GST_VALUE_HOLDS_LIST (&subtraction)) { + /* unroll */ + GValue unroll = { 0, }; + + gst_value_init_and_copy (&unroll, dest); + g_value_unset (dest); + gst_value_list_concat (dest, &unroll, &subtraction); + } else if (GST_VALUE_HOLDS_LIST (dest)) { + gst_value_list_append_value (dest, &subtraction); + } else { + GValue temp = { 0, }; + + gst_value_init_and_copy (&temp, dest); + g_value_unset (dest); + gst_value_list_concat (dest, &temp, &subtraction); + } + g_value_unset (&subtraction); + } + } + return ret; +} + +static gboolean +gst_value_subtract_list (GValue * dest, const GValue * minuend, + const GValue * subtrahend) +{ + guint i, size; + GValue data[2] = { {0,}, {0,} }; + GValue *subtraction = &data[0], *result = &data[1]; + + g_return_val_if_fail (GST_VALUE_HOLDS_LIST (subtrahend), FALSE); + + gst_value_init_and_copy (result, minuend); + size = gst_value_list_get_size (subtrahend); + for (i = 0; i < size; i++) { + const GValue *cur = gst_value_list_get_value (subtrahend, i); + + if (gst_value_subtract (subtraction, result, cur)) { + GValue *temp = result; + + result = subtraction; + subtraction = temp; + g_value_unset (subtraction); + } else { + g_value_unset (result); + return FALSE; + } + } + gst_value_init_and_copy (dest, result); + g_value_unset (result); + return TRUE; +} + /*************************************/ @@ -1418,7 +1674,9 @@ gst_value_can_intersect (const GValue * value1, const GValue * value2) GstValueIntersectInfo, i); if (intersect_info->type1 == G_VALUE_TYPE (value1) && intersect_info->type2 == G_VALUE_TYPE (value2)) - return TRUE; + if (intersect_info->type2 == G_VALUE_TYPE (value1) && + intersect_info->type1 == G_VALUE_TYPE (value2)) + return TRUE; } return gst_value_can_compare (value1, value2); @@ -1491,6 +1749,118 @@ gst_value_register_intersect_func (GType type1, GType type2, g_array_append_val (gst_value_intersect_funcs, intersect_info); } + +/* subtraction */ + +/** + * gst_value_subtract: + * @dest: the destination value for the result if the subtraction is not empty + * @minuend: the value to subtract from + * @subtrahend: the value to subtract + * + * Subtracts @subtrahend from @minuend and stores the result in @dest. + * Note that this means subtraction as in sets, not as in mathematics. + * + * Returns: TRUE if the subtraction is not empty + */ +gboolean +gst_value_subtract (GValue * dest, const GValue * minuend, + const GValue * subtrahend) +{ + GstValueSubtractInfo *info; + int i; + + /* special cases first */ + if (GST_VALUE_HOLDS_LIST (minuend)) + return gst_value_subtract_from_list (dest, minuend, subtrahend); + if (GST_VALUE_HOLDS_LIST (subtrahend)) + return gst_value_subtract_list (dest, minuend, subtrahend); + + for (i = 0; i < gst_value_subtract_funcs->len; i++) { + info = &g_array_index (gst_value_subtract_funcs, GstValueSubtractInfo, i); + if (info->minuend == G_VALUE_TYPE (minuend) && + info->subtrahend == G_VALUE_TYPE (subtrahend)) { + return info->func (dest, minuend, subtrahend); + } + } + + if (gst_value_compare (minuend, subtrahend) != GST_VALUE_EQUAL) { + gst_value_init_and_copy (dest, minuend); + return TRUE; + } + + return FALSE; +} + +#if 0 +gboolean +gst_value_subtract (GValue * dest, const GValue * minuend, + const GValue * subtrahend) +{ + gboolean ret = gst_value_subtract2 (dest, minuend, subtrahend); + + g_printerr ("\"%s\" - \"%s\" = \"%s\"\n", gst_value_serialize (minuend), + gst_value_serialize (subtrahend), + ret ? gst_value_serialize (dest) : "---"); + return ret; +} +#endif + +/** + * gst_value_can_subtract: + * @minuend: the value to subtract from + * @subtrahend: the value to subtract + * + * Checks if it's possible to subtract @subtrahend from @minuend. + * + * Returns: TRUE if a subtraction is possible + */ +gboolean +gst_value_can_subtract (const GValue * minuend, const GValue * subtrahend) +{ + GstValueSubtractInfo *info; + int i; + + /* special cases */ + if (GST_VALUE_HOLDS_LIST (minuend) || GST_VALUE_HOLDS_LIST (subtrahend)) + return TRUE; + + for (i = 0; i < gst_value_subtract_funcs->len; i++) { + info = &g_array_index (gst_value_subtract_funcs, GstValueSubtractInfo, i); + if (info->minuend == G_VALUE_TYPE (minuend) && + info->subtrahend == G_VALUE_TYPE (subtrahend)) + return TRUE; + } + + return gst_value_can_compare (minuend, subtrahend); +} + +/** + * gst_value_register_subtract_func: + * @minuend_type: type of the minuend + * @subtrahend_type: type of the subtrahend + * @func: function to use + * + * Registers @func as a function capable of subtracting the values of + * @subtrahend_type from values of @minuend_type. + */ +void +gst_value_register_subtract_func (GType minuend_type, GType subtrahend_type, + GstValueSubtractFunc func) +{ + GstValueSubtractInfo info; + + /* one type must be unfixed, other subtractions can be done as comparisons */ + g_return_if_fail (!gst_type_is_fixed (minuend_type) + || !gst_type_is_fixed (subtrahend_type)); + + info.minuend = minuend_type; + info.subtrahend = subtrahend_type; + info.func = func; + + g_array_append_val (gst_value_subtract_funcs, info); +} + /* * gst_value_register: * @table: @@ -1618,6 +1988,8 @@ _gst_value_initialize (void) sizeof (GstValueUnionInfo)); gst_value_intersect_funcs = g_array_new (FALSE, FALSE, sizeof (GstValueIntersectInfo)); + gst_value_subtract_funcs = g_array_new (FALSE, FALSE, + sizeof (GstValueSubtractInfo)); { static const GTypeValueTable value_table = { @@ -1812,6 +2184,19 @@ _gst_value_initialize (void) gst_value_register_intersect_func (GST_TYPE_DOUBLE_RANGE, GST_TYPE_DOUBLE_RANGE, gst_value_intersect_double_range_double_range); + gst_value_register_subtract_func (G_TYPE_INT, GST_TYPE_INT_RANGE, + gst_value_subtract_int_int_range); + gst_value_register_subtract_func (GST_TYPE_INT_RANGE, G_TYPE_INT, + gst_value_subtract_int_range_int); + gst_value_register_subtract_func (GST_TYPE_INT_RANGE, GST_TYPE_INT_RANGE, + gst_value_subtract_int_range_int_range); + gst_value_register_subtract_func (G_TYPE_DOUBLE, GST_TYPE_DOUBLE_RANGE, + gst_value_subtract_double_double_range); + gst_value_register_subtract_func (GST_TYPE_DOUBLE_RANGE, G_TYPE_DOUBLE, + gst_value_subtract_double_range_double); + gst_value_register_subtract_func (GST_TYPE_DOUBLE_RANGE, + GST_TYPE_DOUBLE_RANGE, gst_value_subtract_double_range_double_range); + gst_value_register_union_func (G_TYPE_INT, GST_TYPE_INT_RANGE, gst_value_union_int_int_range); gst_value_register_union_func (GST_TYPE_INT_RANGE, GST_TYPE_INT_RANGE, diff --git a/gst/gstvalue.h b/gst/gstvalue.h index a3b95be..9d67f9e 100644 --- a/gst/gstvalue.h +++ b/gst/gstvalue.h @@ -62,6 +62,9 @@ typedef int (* GstValueUnionFunc) (GValue *dest, typedef int (* GstValueIntersectFunc) (GValue *dest, const GValue *value1, const GValue *value2); +typedef int (* GstValueSubtractFunc) (GValue *dest, + const GValue *minuend, + const GValue *subtrahend); typedef struct _GstValueTable GstValueTable; struct _GstValueTable { @@ -148,6 +151,17 @@ void gst_value_register_intersect_func (GType GType type2, GstValueIntersectFunc func); +/* subtraction */ +gboolean gst_value_subtract (GValue *dest, + const GValue *minuend, + const GValue *subtrahend); +gboolean gst_value_can_subtract (const GValue *minuend, + const GValue *subtrahend); +void gst_value_register_subtract_func (GType minuend_type, + GType dubtrahend_type, + GstValueSubtractFunc func); + +/* fixation */ gboolean gst_type_is_fixed (GType type); /* private */ diff --git a/plugins/elements/gstqueue.c b/plugins/elements/gstqueue.c index b86b517..3b9cb44 100644 --- a/plugins/elements/gstqueue.c +++ b/plugins/elements/gstqueue.c @@ -340,7 +340,7 @@ gst_queue_link (GstPad * pad, const GstCaps * caps) queue = GST_QUEUE (gst_pad_get_parent (pad)); if (queue->cur_level.bytes > 0) { - if (gst_caps_is_equal_fixed (caps, queue->negotiated_caps)) { + if (gst_caps_is_equal (caps, queue->negotiated_caps)) { return GST_PAD_LINK_OK; } return GST_PAD_LINK_REFUSED; diff --git a/tests/old/testsuite/caps/.gitignore b/tests/old/testsuite/caps/.gitignore index 75f6cf7..3ff4a8e 100644 --- a/tests/old/testsuite/caps/.gitignore +++ b/tests/old/testsuite/caps/.gitignore @@ -12,11 +12,14 @@ Makefile.in app_fixate caps compatibility +erathostenes +fixed +intersect2 intersection normalisation union -fixed +sets string-conversions -intersect2 +subtract value_compare value_intersect diff --git a/tests/old/testsuite/caps/Makefile.am b/tests/old/testsuite/caps/Makefile.am index 52949f0..2b7eb47 100644 --- a/tests/old/testsuite/caps/Makefile.am +++ b/tests/old/testsuite/caps/Makefile.am @@ -15,7 +15,10 @@ tests_pass = \ value_intersect \ value_serialize \ audioscale \ - filtercaps + filtercaps \ + erathostenes \ + subtract \ + sets tests_fail = tests_ignore = @@ -38,6 +41,10 @@ intersect2_LDADD = $(GST_LIBS) intersect2_CFLAGS = $(GST_CFLAGS) $(XML_CFLAGS) filtercaps_LDADD = $(GST_LIBS) filtercaps_CFLAGS = $(GST_CFLAGS) $(XML_CFLAGS) - - +erathostenes_LDADD = $(GST_LIBS) +ersthostenes_CFLAGS = $(GST_CFLAGS) $(XML_CFLAGS) +subtract_LDADD = $(GST_LIBS) +subtract_CFLAGS = $(GST_CFLAGS) $(XML_CFLAGS) +sets_LDADD = $(GST_LIBS) +sets_CFLAGS = $(GST_CFLAGS) $(XML_CFLAGS) diff --git a/tests/old/testsuite/caps/erathostenes.c b/tests/old/testsuite/caps/erathostenes.c new file mode 100644 index 0000000..9d9866a --- /dev/null +++ b/tests/old/testsuite/caps/erathostenes.c @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2004 Benjamin Otte + * + * 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 +#include + +#define MAX_SIEVE 20 + +static void +erathostenes (GValue * sieve, gboolean up, int size) +{ + guint i, j; + GValue temp = { 0, }; + GValue list = { 0, }; + + g_value_init (sieve, GST_TYPE_INT_RANGE); + gst_value_set_int_range (sieve, 2, size * size); + for (i = up ? 2 : size; up ? (i <= size) : (i >= 2); i += up ? 1 : -1) { + g_value_init (&list, GST_TYPE_LIST); + for (j = 2 * i; j <= size * size; j += i) { + GValue v = { 0, }; + + g_value_init (&v, G_TYPE_INT); + g_value_set_int (&v, j); + gst_value_list_append_value (&list, &v); + g_value_unset (&v); + } + gst_value_subtract (&temp, sieve, &list); + g_value_unset (sieve); + gst_value_init_and_copy (sieve, &temp); + g_value_unset (&temp); + g_value_unset (&list); + /* g_print ("%2u: %s\n", i, gst_value_serialize (sieve)); */ + } + + g_print ("%s\n", gst_value_serialize (sieve)); +} + +gint +main (gint argc, gchar ** argv) +{ + GValue up = { 0, }; + GValue down = { 0, }; + guint size = MAX_SIEVE; + + gst_init (&argc, &argv); + + if (argc > 1) + size = atol (argv[1]); + + erathostenes (&up, TRUE, size); + erathostenes (&down, FALSE, size); + + g_assert (gst_value_compare (&up, &down) == GST_VALUE_EQUAL); + return 0; +} diff --git a/tests/old/testsuite/caps/sets.c b/tests/old/testsuite/caps/sets.c new file mode 100644 index 0000000..740039f --- /dev/null +++ b/tests/old/testsuite/caps/sets.c @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2004 Benjamin Otte + * + * 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 +#include + +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" +}; + +static void +check_caps (const gchar * eins, const gchar * zwei) +{ + GstCaps *one, *two, *test, *test2, *test3, *test4; + + one = gst_caps_from_string (eins); + two = gst_caps_from_string (zwei); + g_print (" A = %u\n", strlen (eins)); + g_print (" B = %u\n", strlen (zwei)); + + test = gst_caps_intersect (one, two); + if (gst_caps_is_equal (one, two)) { + g_print (" EQUAL\n\n"); + g_assert (gst_caps_is_equal (one, test)); + g_assert (gst_caps_is_equal (two, test)); + } else if (!gst_caps_is_any (one) || gst_caps_is_empty (two)) { + test2 = gst_caps_subtract (one, test); + g_print (" A - B = %u\n", strlen (gst_caps_to_string (test2))); + /* test2 = one - (one A two) = one - two */ + test3 = gst_caps_intersect (test2, two); + g_print (" empty = %s\n", gst_caps_to_string (test3)); + g_assert (gst_caps_is_empty (test3)); + gst_caps_free (test3); + test3 = gst_caps_union (test2, two); + g_print (" A + B = %u\n", strlen (gst_caps_to_string (test3))); + /* test3 = one - two + two = one + two */ + g_print (" A + B = %s\n", gst_caps_to_string (gst_caps_subtract (one, + test3))); + g_assert (gst_caps_is_subset (one, test3)); + test4 = gst_caps_union (one, two); + g_assert (gst_caps_is_equal (test3, test4)); + g_print (" NOT EQUAL\n\n"); + gst_caps_free (test2); + gst_caps_free (test3); + gst_caps_free (test4); + } else { + g_print (" ANY CAPS\n\n"); + } + gst_caps_free (test); + gst_caps_free (two); + gst_caps_free (one); +} + +gint +main (gint argc, gchar ** argv) +{ + guint i, j; + + gst_init (&argc, &argv); + + for (i = 0; i < G_N_ELEMENTS (caps); i++) { + for (j = 0; j < G_N_ELEMENTS (caps); j++) { + g_print ("%u - %u\n", i, j); + check_caps (caps[i], caps[j]); + } + } + + return 0; +} diff --git a/tests/old/testsuite/caps/subtract.c b/tests/old/testsuite/caps/subtract.c new file mode 100644 index 0000000..fe80d44 --- /dev/null +++ b/tests/old/testsuite/caps/subtract.c @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2004 Benjamin Otte + * + * 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 + +static void +check_caps (const gchar * set, const gchar * subset) +{ + GstCaps *one, *two, *test, *test2; + + g_print (" A = %s\n", set); + one = gst_caps_from_string (set); + g_print (" B = %s\n", subset); + two = gst_caps_from_string (subset); + /* basics */ + test = gst_caps_subtract (one, one); + g_assert (gst_caps_is_empty (test)); + gst_caps_free (test); + test = gst_caps_subtract (two, two); + g_assert (gst_caps_is_empty (test)); + gst_caps_free (test); + test = gst_caps_subtract (two, one); + g_assert (gst_caps_is_empty (test)); + gst_caps_free (test); + /* now the nice part */ + test = gst_caps_subtract (one, two); + g_assert (!gst_caps_is_empty (test)); + g_print (" A - B = %s\n", gst_caps_to_string (test)); + test2 = gst_caps_union (test, two); + g_print ("A - B + B = %s\n", gst_caps_to_string (test2)); + gst_caps_free (test); + test = gst_caps_subtract (test2, one); + g_assert (gst_caps_is_empty (test)); + gst_caps_free (test); +} + +gint +main (gint argc, gchar ** argv) +{ + gst_init (&argc, &argv); + + check_caps ("some/mime, _int = [ 1, 2 ], list = { \"A\", \"B\", \"C\" }", + "some/mime, _int = 1, list = \"A\""); + check_caps ("some/mime, _double = (double) 1.0; other/mime, _int = { 1, 2 }", + "some/mime, _double = (double) 1.0"); + + return 0; +} diff --git a/testsuite/caps/.gitignore b/testsuite/caps/.gitignore index 75f6cf7..3ff4a8e 100644 --- a/testsuite/caps/.gitignore +++ b/testsuite/caps/.gitignore @@ -12,11 +12,14 @@ Makefile.in app_fixate caps compatibility +erathostenes +fixed +intersect2 intersection normalisation union -fixed +sets string-conversions -intersect2 +subtract value_compare value_intersect diff --git a/testsuite/caps/Makefile.am b/testsuite/caps/Makefile.am index 52949f0..2b7eb47 100644 --- a/testsuite/caps/Makefile.am +++ b/testsuite/caps/Makefile.am @@ -15,7 +15,10 @@ tests_pass = \ value_intersect \ value_serialize \ audioscale \ - filtercaps + filtercaps \ + erathostenes \ + subtract \ + sets tests_fail = tests_ignore = @@ -38,6 +41,10 @@ intersect2_LDADD = $(GST_LIBS) intersect2_CFLAGS = $(GST_CFLAGS) $(XML_CFLAGS) filtercaps_LDADD = $(GST_LIBS) filtercaps_CFLAGS = $(GST_CFLAGS) $(XML_CFLAGS) - - +erathostenes_LDADD = $(GST_LIBS) +ersthostenes_CFLAGS = $(GST_CFLAGS) $(XML_CFLAGS) +subtract_LDADD = $(GST_LIBS) +subtract_CFLAGS = $(GST_CFLAGS) $(XML_CFLAGS) +sets_LDADD = $(GST_LIBS) +sets_CFLAGS = $(GST_CFLAGS) $(XML_CFLAGS) diff --git a/testsuite/caps/erathostenes.c b/testsuite/caps/erathostenes.c new file mode 100644 index 0000000..9d9866a --- /dev/null +++ b/testsuite/caps/erathostenes.c @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2004 Benjamin Otte + * + * 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 +#include + +#define MAX_SIEVE 20 + +static void +erathostenes (GValue * sieve, gboolean up, int size) +{ + guint i, j; + GValue temp = { 0, }; + GValue list = { 0, }; + + g_value_init (sieve, GST_TYPE_INT_RANGE); + gst_value_set_int_range (sieve, 2, size * size); + for (i = up ? 2 : size; up ? (i <= size) : (i >= 2); i += up ? 1 : -1) { + g_value_init (&list, GST_TYPE_LIST); + for (j = 2 * i; j <= size * size; j += i) { + GValue v = { 0, }; + + g_value_init (&v, G_TYPE_INT); + g_value_set_int (&v, j); + gst_value_list_append_value (&list, &v); + g_value_unset (&v); + } + gst_value_subtract (&temp, sieve, &list); + g_value_unset (sieve); + gst_value_init_and_copy (sieve, &temp); + g_value_unset (&temp); + g_value_unset (&list); + /* g_print ("%2u: %s\n", i, gst_value_serialize (sieve)); */ + } + + g_print ("%s\n", gst_value_serialize (sieve)); +} + +gint +main (gint argc, gchar ** argv) +{ + GValue up = { 0, }; + GValue down = { 0, }; + guint size = MAX_SIEVE; + + gst_init (&argc, &argv); + + if (argc > 1) + size = atol (argv[1]); + + erathostenes (&up, TRUE, size); + erathostenes (&down, FALSE, size); + + g_assert (gst_value_compare (&up, &down) == GST_VALUE_EQUAL); + return 0; +} diff --git a/testsuite/caps/sets.c b/testsuite/caps/sets.c new file mode 100644 index 0000000..740039f --- /dev/null +++ b/testsuite/caps/sets.c @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2004 Benjamin Otte + * + * 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 +#include + +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" +}; + +static void +check_caps (const gchar * eins, const gchar * zwei) +{ + GstCaps *one, *two, *test, *test2, *test3, *test4; + + one = gst_caps_from_string (eins); + two = gst_caps_from_string (zwei); + g_print (" A = %u\n", strlen (eins)); + g_print (" B = %u\n", strlen (zwei)); + + test = gst_caps_intersect (one, two); + if (gst_caps_is_equal (one, two)) { + g_print (" EQUAL\n\n"); + g_assert (gst_caps_is_equal (one, test)); + g_assert (gst_caps_is_equal (two, test)); + } else if (!gst_caps_is_any (one) || gst_caps_is_empty (two)) { + test2 = gst_caps_subtract (one, test); + g_print (" A - B = %u\n", strlen (gst_caps_to_string (test2))); + /* test2 = one - (one A two) = one - two */ + test3 = gst_caps_intersect (test2, two); + g_print (" empty = %s\n", gst_caps_to_string (test3)); + g_assert (gst_caps_is_empty (test3)); + gst_caps_free (test3); + test3 = gst_caps_union (test2, two); + g_print (" A + B = %u\n", strlen (gst_caps_to_string (test3))); + /* test3 = one - two + two = one + two */ + g_print (" A + B = %s\n", gst_caps_to_string (gst_caps_subtract (one, + test3))); + g_assert (gst_caps_is_subset (one, test3)); + test4 = gst_caps_union (one, two); + g_assert (gst_caps_is_equal (test3, test4)); + g_print (" NOT EQUAL\n\n"); + gst_caps_free (test2); + gst_caps_free (test3); + gst_caps_free (test4); + } else { + g_print (" ANY CAPS\n\n"); + } + gst_caps_free (test); + gst_caps_free (two); + gst_caps_free (one); +} + +gint +main (gint argc, gchar ** argv) +{ + guint i, j; + + gst_init (&argc, &argv); + + for (i = 0; i < G_N_ELEMENTS (caps); i++) { + for (j = 0; j < G_N_ELEMENTS (caps); j++) { + g_print ("%u - %u\n", i, j); + check_caps (caps[i], caps[j]); + } + } + + return 0; +} diff --git a/testsuite/caps/subtract.c b/testsuite/caps/subtract.c new file mode 100644 index 0000000..fe80d44 --- /dev/null +++ b/testsuite/caps/subtract.c @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2004 Benjamin Otte + * + * 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 + +static void +check_caps (const gchar * set, const gchar * subset) +{ + GstCaps *one, *two, *test, *test2; + + g_print (" A = %s\n", set); + one = gst_caps_from_string (set); + g_print (" B = %s\n", subset); + two = gst_caps_from_string (subset); + /* basics */ + test = gst_caps_subtract (one, one); + g_assert (gst_caps_is_empty (test)); + gst_caps_free (test); + test = gst_caps_subtract (two, two); + g_assert (gst_caps_is_empty (test)); + gst_caps_free (test); + test = gst_caps_subtract (two, one); + g_assert (gst_caps_is_empty (test)); + gst_caps_free (test); + /* now the nice part */ + test = gst_caps_subtract (one, two); + g_assert (!gst_caps_is_empty (test)); + g_print (" A - B = %s\n", gst_caps_to_string (test)); + test2 = gst_caps_union (test, two); + g_print ("A - B + B = %s\n", gst_caps_to_string (test2)); + gst_caps_free (test); + test = gst_caps_subtract (test2, one); + g_assert (gst_caps_is_empty (test)); + gst_caps_free (test); +} + +gint +main (gint argc, gchar ** argv) +{ + gst_init (&argc, &argv); + + check_caps ("some/mime, _int = [ 1, 2 ], list = { \"A\", \"B\", \"C\" }", + "some/mime, _int = 1, list = \"A\""); + check_caps ("some/mime, _double = (double) 1.0; other/mime, _int = { 1, 2 }", + "some/mime, _double = (double) 1.0"); + + return 0; +} -- 2.7.4