From: Benjamin O. <co...@pd...> - 2004-04-21 03:25:28
|
CVS Root: /home/cvs/gstreamer Module: gstreamer Changes by: company Date: Tue Apr 20 2004 20:25:26 PDT Log message: * 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. Modified files: . : ChangeLog gst : gstcaps.c gstcaps.h gstpad.c gstqueue.c gststructure.c gststructure.h gstvalue.c gstvalue.h testsuite/caps : .cvsignore Makefile.am Added files: testsuite/caps : erathostenes.c sets.c subtract.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/ChangeLog.diff?r1=1.461&r2=1.462 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstcaps.c.diff?r1=1.105&r2=1.106 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstcaps.h.diff?r1=1.76&r2=1.77 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstpad.c.diff?r1=1.315&r2=1.316 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstqueue.c.diff?r1=1.101&r2=1.102 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gststructure.c.diff?r1=1.26&r2=1.27 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gststructure.h.diff?r1=1.15&r2=1.16 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstvalue.c.diff?r1=1.24&r2=1.25 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/gst/gstvalue.h.diff?r1=1.20&r2=1.21 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/testsuite/caps/.cvsignore.diff?r1=1.4&r2=1.5 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/testsuite/caps/Makefile.am.diff?r1=1.16&r2=1.17 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/testsuite/caps/erathostenes.c?rev=1.1&content-type=text/vnd.viewcvs-markup http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/testsuite/caps/sets.c?rev=1.1&content-type=text/vnd.viewcvs-markup http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gstreamer/testsuite/caps/subtract.c?rev=1.1&content-type=text/vnd.viewcvs-markup ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /home/cvs/gstreamer/gstreamer/ChangeLog,v retrieving revision 1.461 retrieving revision 1.462 diff -u -d -r1.461 -r1.462 --- a/ChangeLog 21 Apr 2004 02:43:54 -0000 1.461 +++ b/ChangeLog 21 Apr 2004 03:25:13 -0000 1.462 @@ -1,3 +1,40 @@ +2004-04-21 Benjamin Otte <ot...@gn...> + + * 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 <ds...@sc...> * gst/autoplug/Makefile.am: Fix some little buglets in last checkin. Index: gstcaps.c RCS file: /home/cvs/gstreamer/gstreamer/gst/gstcaps.c,v retrieving revision 1.105 retrieving revision 1.106 diff -u -d -r1.105 -r1.106 --- a/gstcaps.c 17 Apr 2004 02:21:54 -0000 1.105 +++ b/gstcaps.c 21 Apr 2004 03:25:13 -0000 1.106 @@ -295,9 +295,17 @@ #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 { + gst_caps_append_structure (caps1, structure); } g_ptr_array_free (caps2->structs, TRUE); @@ -690,6 +698,38 @@ 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; +} +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 @@ +typedef struct + const GstStructure *subtract_from; + GstCaps *put_into; +SubtractionEntry; +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) + if (!gst_value_subtract (&subtraction, other, value)) + structure = gst_structure_copy (e->subtract_from); + if (gst_value_compare (&subtraction, other) == GST_VALUE_EQUAL) { + gst_caps_append_structure (e->put_into, structure); + gst_structure_id_set_value (structure, field_id, &subtraction); + g_value_unset (&subtraction); + } +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 @@ 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); Index: gstcaps.h RCS file: /home/cvs/gstreamer/gstreamer/gst/gstcaps.h,v retrieving revision 1.76 retrieving revision 1.77 diff -u -d -r1.76 -r1.77 --- a/gstcaps.h 30 Mar 2004 07:36:18 -0000 1.76 +++ b/gstcaps.h 21 Apr 2004 03:25:13 -0000 1.77 @@ -106,16 +106,22 @@ 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, +GstCaps * gst_caps_subtract (const GstCaps *minuend, + const GstCaps *subtrahend); GstCaps * gst_caps_union (const GstCaps *caps1, GstCaps * gst_caps_normalize (const GstCaps *caps); Index: gstpad.c RCS file: /home/cvs/gstreamer/gstreamer/gst/gstpad.c,v retrieving revision 1.315 retrieving revision 1.316 diff -u -d -r1.315 -r1.316 --- a/gstpad.c 20 Apr 2004 09:43:34 -0000 1.315 +++ b/gstpad.c 21 Apr 2004 03:25:13 -0000 1.316 @@ -1449,7 +1449,7 @@ 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; Index: gstqueue.c RCS file: /home/cvs/gstreamer/gstreamer/gst/gstqueue.c,v retrieving revision 1.101 retrieving revision 1.102 diff -u -d -r1.101 -r1.102 --- a/gstqueue.c 9 Apr 2004 19:05:03 -0000 1.101 +++ b/gstqueue.c 21 Apr 2004 03:25:13 -0000 1.102 @@ -340,7 +340,7 @@ 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; Index: gststructure.c RCS file: /home/cvs/gstreamer/gstreamer/gst/gststructure.c,v retrieving revision 1.26 retrieving revision 1.27 diff -u -d -r1.26 -r1.27 --- a/gststructure.c 13 Apr 2004 02:22:02 -0000 1.26 +++ b/gststructure.c 21 Apr 2004 03:25:13 -0000 1.27 @@ -248,6 +248,22 @@ + * 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 Index: gststructure.h RCS file: /home/cvs/gstreamer/gstreamer/gst/gststructure.h,v retrieving revision 1.15 retrieving revision 1.16 diff -u -d -r1.15 -r1.16 --- a/gststructure.h 15 Mar 2004 23:11:36 -0000 1.15 +++ b/gststructure.h 21 Apr 2004 03:25:13 -0000 1.16 @@ -60,6 +60,7 @@ 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); Index: gstvalue.c RCS file: /home/cvs/gstreamer/gstreamer/gst/gstvalue.c,v retrieving revision 1.24 retrieving revision 1.25 diff -u -d -r1.24 -r1.25 --- a/gstvalue.c 17 Apr 2004 02:21:54 -0000 1.24 +++ b/gstvalue.c 21 Apr 2004 03:25:13 -0000 1.25 @@ -44,6 +44,15 @@ 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 @@ 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 @@ 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 FALSE; +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; + 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); + gst_value_list_concat (dest, pv1, pv2); + g_value_unset (pv1); + g_value_unset (pv2); + return TRUE; +gst_value_subtract_int_range_int (GValue * dest, const GValue * minuend, + 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 == G_MAXINT) { + max--; + val--; + if (val == G_MININT) { + min++; + val++; + gst_value_create_new_range (dest, min, val - 1, val + 1, max); +gst_value_subtract_int_range_int_range (GValue * dest, const GValue * minuend, + 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); +gst_value_subtract_double_double_range (GValue * dest, const GValue * minuend, + 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); +gst_value_subtract_double_range_double (GValue * dest, const GValue * minuend, + /* FIXME! */ + gst_value_init_and_copy (dest, minuend); +gst_value_subtract_double_range_double_range (GValue * dest, + const GValue * minuend, const GValue * subtrahend) + /* 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); + if (min1 < max1 && min2 < max2) { + } else if (min1 < max1) { + } else if (min2 < max2) { + g_value_init (pv1, GST_TYPE_DOUBLE_RANGE); + gst_value_set_double_range (pv1, min1, max1); + g_value_init (pv2, GST_TYPE_DOUBLE_RANGE); + gst_value_set_double_range (pv2, min2, max2); +gst_value_subtract_from_list (GValue * dest, const GValue * minuend, + guint i, size; + 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); + GValue temp = { 0, }; + gst_value_init_and_copy (&temp, dest); + gst_value_list_concat (dest, &temp, &subtraction); + g_value_unset (&subtraction); +gst_value_subtract_list (GValue * dest, const GValue * minuend, + 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); + 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); @@ -1418,7 +1674,9 @@ 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 @@ g_array_append_val (gst_value_intersect_funcs, intersect_info); + * 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 +gst_value_subtract (GValue * dest, const GValue * minuend, + 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) { +#if 0 + 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) : "---"); + * gst_value_can_subtract: + * Checks if it's possible to subtract @subtrahend from @minuend. + * Returns: TRUE if a subtraction is possible +gst_value_can_subtract (const GValue * minuend, const GValue * subtrahend) + /* special cases */ + if (GST_VALUE_HOLDS_LIST (minuend) || GST_VALUE_HOLDS_LIST (subtrahend)) + 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 @@ 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_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, Index: gstvalue.h RCS file: /home/cvs/gstreamer/gstreamer/gst/gstvalue.h,v retrieving revision 1.20 retrieving revision 1.21 diff -u -d -r1.20 -r1.21 --- a/gstvalue.h 17 Apr 2004 02:21:54 -0000 1.20 +++ b/gstvalue.h 21 Apr 2004 03:25:13 -0000 1.21 @@ -62,6 +62,9 @@ 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 @@ GType type2, GstValueIntersectFunc func); +gboolean gst_value_subtract (GValue *dest, + const GValue *minuend, + const GValue *subtrahend); +gboolean gst_value_can_subtract (const GValue *minuend, +void gst_value_register_subtract_func (GType minuend_type, + GType dubtrahend_type, + GstValueSubtractFunc func); +/* fixation */ gboolean gst_type_is_fixed (GType type); /* private */ Index: .cvsignore RCS file: /home/cvs/gstreamer/gstreamer/testsuite/caps/.cvsignore,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- a/.cvsignore 12 Jan 2004 16:53:23 -0000 1.4 +++ b/.cvsignore 21 Apr 2004 03:25:13 -0000 1.5 @@ -12,11 +12,14 @@ app_fixate caps compatibility +erathostenes +fixed +intersect2 intersection normalisation union -fixed +sets string-conversions -intersect2 +subtract value_compare value_intersect Index: Makefile.am RCS file: /home/cvs/gstreamer/gstreamer/testsuite/caps/Makefile.am,v retrieving revision 1.17 diff -u -d -r1.16 -r1.17 --- a/Makefile.am 20 Apr 2004 02:43:35 -0000 1.16 +++ b/Makefile.am 21 Apr 2004 03:25:13 -0000 1.17 @@ -15,7 +15,10 @@ value_intersect \ value_serialize \ audioscale \ - filtercaps + filtercaps \ + erathostenes \ + subtract \ + sets tests_fail = tests_ignore = @@ -38,6 +41,10 @@ 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) --- NEW FILE: erathostenes.c --- /* * Copyright (C) 2004 Benjamin Otte <in...@pu...> * * 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 <stdlib.h> #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; --- NEW FILE: sets.c --- #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" }; 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 (test4); } else { g_print (" ANY CAPS\n\n"); gst_caps_free (test); gst_caps_free (two); gst_caps_free (one); 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]); --- NEW FILE: subtract.c --- 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)); test = gst_caps_subtract (two, two); test = gst_caps_subtract (two, one); /* 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)); test = gst_caps_subtract (test2, one); 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"); |