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.
This commit is contained in:
Benjamin Otte 2004-04-21 03:25:13 +00:00
parent bdb8c10b5c
commit 614b4d1627
20 changed files with 1080 additions and 19 deletions

View file

@ -1,3 +1,40 @@
2004-04-21 Benjamin Otte <otte@gnome.org>
* 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@schleef.org>
* gst/autoplug/Makefile.am: Fix some little buglets in last checkin.

View file

@ -295,10 +295,18 @@ gst_caps_append (GstCaps * caps1, GstCaps * caps2)
#ifdef USE_POISONING
CAPS_POISON (caps2);
#endif
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
memset (caps2, 0xff, sizeof (GstCaps));
@ -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);

View file

@ -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);

View file

@ -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;
}

View file

@ -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;

View file

@ -247,6 +247,22 @@ gst_structure_get_name (const GstStructure * structure)
return g_quark_to_string (structure->name);
}
/**
* 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

View file

@ -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);

View file

@ -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,6 +1674,8 @@ 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))
if (intersect_info->type2 == G_VALUE_TYPE (value1) &&
intersect_info->type1 == G_VALUE_TYPE (value2))
return TRUE;
}
@ -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,

View file

@ -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 */

View file

@ -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;

View file

@ -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

View file

@ -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)

View file

@ -0,0 +1,71 @@
/*
* Copyright (C) 2004 Benjamin Otte <in7y118@public.uni-hamburg.de>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <gst/gst.h>
#include <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;
}

View file

@ -0,0 +1,91 @@
/*
* Copyright (C) 2004 Benjamin Otte <in7y118@public.uni-hamburg.de>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <gst/gst.h>
#include <string.h>
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;
}

View file

@ -0,0 +1,63 @@
/*
* Copyright (C) 2004 Benjamin Otte <in7y118@public.uni-hamburg.de>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <gst/gst.h>
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;
}

View file

@ -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

View file

@ -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)

View file

@ -0,0 +1,71 @@
/*
* Copyright (C) 2004 Benjamin Otte <in7y118@public.uni-hamburg.de>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <gst/gst.h>
#include <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;
}

91
testsuite/caps/sets.c Normal file
View file

@ -0,0 +1,91 @@
/*
* Copyright (C) 2004 Benjamin Otte <in7y118@public.uni-hamburg.de>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <gst/gst.h>
#include <string.h>
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;
}

63
testsuite/caps/subtract.c Normal file
View file

@ -0,0 +1,63 @@
/*
* Copyright (C) 2004 Benjamin Otte <in7y118@public.uni-hamburg.de>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <gst/gst.h>
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;
}