Implement fraction ranges and extend GstFraction to support arithmetic subtraction, as well as deserialization from i...

Original commit message from CVS:
* check/gst/capslist.h:
* check/gst/gstcaps.c: (GST_START_TEST):
* check/gst/gstvalue.c: (GST_START_TEST), (gst_value_suite):
* gst/gststructure.c: (gst_structure_parse_range),
(gst_structure_fixate_field_nearest_fraction):
* gst/gststructure.h:
* gst/gstvalue.c: (gst_value_init_fraction_range),
(gst_value_free_fraction_range), (gst_value_copy_fraction_range),
(gst_value_collect_fraction_range),
(gst_value_lcopy_fraction_range), (gst_value_set_fraction_range),
(gst_value_set_fraction_range_full),
(gst_value_get_fraction_range_min),
(gst_value_get_fraction_range_max),
(gst_value_serialize_fraction_range),
(gst_value_transform_fraction_range_string),
(gst_value_compare_fraction_range),
(gst_value_deserialize_fraction_range),
(gst_value_intersect_fraction_fraction_range),
(gst_value_intersect_fraction_range_fraction_range),
(gst_value_subtract_fraction_fraction_range),
(gst_value_subtract_fraction_range_fraction),
(gst_value_subtract_fraction_range_fraction_range),
(gst_value_collect_fraction), (gst_value_fraction_multiply),
(gst_value_fraction_subtract), (gst_value_deserialize_fraction),
(gst_value_transform_string_fraction), (_gst_value_initialize):
* gst/gstvalue.h:
Implement fraction ranges and extend GstFraction to support
arithmetic subtraction, as well as deserialization from integer
strings such as "100"
Add a testsuite as for int and double range set operations
This commit is contained in:
Jan Schmidt 2005-11-21 23:54:59 +00:00
parent f641e8a9fe
commit 506aa94ce2
11 changed files with 1406 additions and 42 deletions

View file

@ -1,3 +1,36 @@
2005-11-22 Jan Schmidt <thaytan@mad.scientist.com>
* check/gst/capslist.h:
* check/gst/gstcaps.c: (GST_START_TEST):
* check/gst/gstvalue.c: (GST_START_TEST), (gst_value_suite):
* gst/gststructure.c: (gst_structure_parse_range),
(gst_structure_fixate_field_nearest_fraction):
* gst/gststructure.h:
* gst/gstvalue.c: (gst_value_init_fraction_range),
(gst_value_free_fraction_range), (gst_value_copy_fraction_range),
(gst_value_collect_fraction_range),
(gst_value_lcopy_fraction_range), (gst_value_set_fraction_range),
(gst_value_set_fraction_range_full),
(gst_value_get_fraction_range_min),
(gst_value_get_fraction_range_max),
(gst_value_serialize_fraction_range),
(gst_value_transform_fraction_range_string),
(gst_value_compare_fraction_range),
(gst_value_deserialize_fraction_range),
(gst_value_intersect_fraction_fraction_range),
(gst_value_intersect_fraction_range_fraction_range),
(gst_value_subtract_fraction_fraction_range),
(gst_value_subtract_fraction_range_fraction),
(gst_value_subtract_fraction_range_fraction_range),
(gst_value_collect_fraction), (gst_value_fraction_multiply),
(gst_value_fraction_subtract), (gst_value_deserialize_fraction),
(gst_value_transform_string_fraction), (_gst_value_initialize):
* gst/gstvalue.h:
Implement fraction ranges and extend GstFraction to support
arithmetic subtraction, as well as deserialization from integer
strings such as "100"
Add a testsuite as for int and double range set operations
2005-11-21 Andy Wingo <wingo@pobox.com>
* gst/gsttaglist.h:

View file

@ -15,6 +15,10 @@ static const gchar *caps_list[] = {
"video/x-raw-rgb, bpp = (int) 32, depth = (int) 24, endianness = (int) BIG_ENDIAN, red_mask = (int) 0x000000FF, framerate = (double) [ 0, max ]",
"video/x-raw-rgb, bpp = (int) 32, depth = (int) 24, endianness = (int) BIG_ENDIAN, red_mask = (int) 0xFF000000, framerate = (double) [ 0, max ]",
"video/x-raw-rgb,\\ bpp=(int)32",
"test/gst-fraction, fraction = (fraction) 1/8",
"test/gst-fraction-range, fraction = (fraction) [ 1/3, 1/4 ]",
"test/gst-fraction-range, fraction = (fraction) { [ 1/3, 1/4 ], 1/8 }",
"test/gst-fraction-range, fraction = (fraction) { [ 1/3, 1/4 ], [ 1/8, 2/8 ] }",
"ANY",
"EMPTY"
};

View file

@ -128,14 +128,14 @@ GST_START_TEST (test_static_caps)
GST_END_TEST;
static const gchar non_simple_caps_string[] =
"video/x-raw-yuv, format=(fourcc)I420, framerate=(double)[ 1, 100 ], "
"video/x-raw-yuv, format=(fourcc)I420, framerate=(fraction)[ 1/100, 100 ], "
"width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-raw-yuv, "
"format=(fourcc)YUY2, framerate=(double)[ 1, 100 ], width=(int)[ 16, 4096 ], "
"format=(fourcc)YUY2, framerate=(fraction)[ 1/100, 100 ], width=(int)[ 16, 4096 ], "
"height=(int)[ 16, 4096 ]; video/x-raw-rgb, bpp=(int)8, depth=(int)8, "
"endianness=(int)1234, framerate=(double)[ 1, 100 ], width=(int)[ 16, 4096 ], "
"endianness=(int)1234, framerate=(fraction)[ 1/100, 100 ], width=(int)[ 16, 4096 ], "
"height=(int)[ 16, 4096 ]; video/x-raw-yuv, "
"format=(fourcc){ I420, YUY2, YV12 }, width=(int)[ 16, 4096 ], "
"height=(int)[ 16, 4096 ], framerate=(double)[ 1, 100 ]";
"height=(int)[ 16, 4096 ], framerate=(fraction)[ 1/100, 100 ]";
static gboolean
check_fourcc_list (const GValue * format_value)
@ -193,11 +193,11 @@ GST_START_TEST (test_simplify)
/* check simplified caps, should be:
*
* video/x-raw-rgb, bpp=(int)8, depth=(int)8, endianness=(int)1234,
* framerate=(double)[ 1, 100 ], width=(int)[ 16, 4096 ],
* framerate=(fraction)[ 1/100, 100 ], width=(int)[ 16, 4096 ],
* height=(int)[ 16, 4096 ];
* video/x-raw-yuv, format=(fourcc){ YV12, YUY2, I420 },
* width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ],
* framerate=(double)[ 1, 100 ]
* framerate=(fraction)[ 1/100, 100 ]
*/
fail_unless (gst_caps_get_size (caps) == 2);
s1 = gst_caps_get_structure (caps, 0);
@ -218,7 +218,8 @@ GST_START_TEST (test_simplify)
const GValue *framerate_value;
const GValue *width_value;
const GValue *height_value;
gdouble min_fps, max_fps;
const GValue *val_fps;
GValue test_fps = { 0, };
gint bpp, depth, endianness;
gint min_width, max_width;
gint min_height, max_height;
@ -232,12 +233,20 @@ GST_START_TEST (test_simplify)
fail_unless (gst_structure_get_int (s1, "endianness", &endianness));
fail_unless (endianness == G_LITTLE_ENDIAN);
g_value_init (&test_fps, GST_TYPE_FRACTION);
framerate_value = gst_structure_get_value (s1, "framerate");
fail_unless (framerate_value != NULL);
fail_unless (GST_VALUE_HOLDS_DOUBLE_RANGE (framerate_value));
min_fps = gst_value_get_double_range_min (framerate_value);
max_fps = gst_value_get_double_range_max (framerate_value);
fail_unless (min_fps == 1.0 && max_fps == 100.0);
fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (framerate_value));
val_fps = gst_value_get_fraction_range_min (framerate_value);
gst_value_set_fraction (&test_fps, 1, 100);
fail_unless (gst_value_compare (&test_fps, val_fps) == GST_VALUE_EQUAL);
val_fps = gst_value_get_fraction_range_max (framerate_value);
gst_value_set_fraction (&test_fps, 100, 1);
fail_unless (gst_value_compare (&test_fps, val_fps) == GST_VALUE_EQUAL);
g_value_unset (&test_fps);
width_value = gst_structure_get_value (s1, "width");
fail_unless (width_value != NULL);
@ -260,7 +269,8 @@ GST_START_TEST (test_simplify)
const GValue *format_value;
const GValue *width_value;
const GValue *height_value;
gdouble min_fps, max_fps;
const GValue *val_fps;
GValue test_fps = { 0, };
gint min_width, max_width;
gint min_height, max_height;
@ -270,12 +280,20 @@ GST_START_TEST (test_simplify)
fail_unless (gst_value_list_get_size (format_value) == 3);
fail_unless (check_fourcc_list (format_value) == TRUE);
g_value_init (&test_fps, GST_TYPE_FRACTION);
framerate_value = gst_structure_get_value (s2, "framerate");
fail_unless (framerate_value != NULL);
fail_unless (GST_VALUE_HOLDS_DOUBLE_RANGE (framerate_value));
min_fps = gst_value_get_double_range_min (framerate_value);
max_fps = gst_value_get_double_range_max (framerate_value);
fail_unless (min_fps == 1.0 && max_fps == 100.0);
fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (framerate_value));
val_fps = gst_value_get_fraction_range_min (framerate_value);
gst_value_set_fraction (&test_fps, 1, 100);
fail_unless (gst_value_compare (&test_fps, val_fps) == GST_VALUE_EQUAL);
val_fps = gst_value_get_fraction_range_max (framerate_value);
gst_value_set_fraction (&test_fps, 100, 1);
fail_unless (gst_value_compare (&test_fps, val_fps) == GST_VALUE_EQUAL);
g_value_unset (&test_fps);
width_value = gst_structure_get_value (s2, "width");
fail_unless (width_value != NULL);

View file

@ -435,6 +435,7 @@ GST_START_TEST (test_value_compare)
fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
g_value_unset (&value1);
g_value_unset (&value2);
}
GST_END_TEST;
@ -958,6 +959,280 @@ GST_START_TEST (test_value_subtract_double)
GST_END_TEST;
/* Test arithmetic subtraction of fractions */
GST_START_TEST (test_value_subtract_fraction)
{
GValue result = { 0 };
GValue src1 = { 0 };
GValue src2 = { 0 };
/* Subtract 1/4 from 1/2 */
g_value_init (&src1, GST_TYPE_FRACTION);
g_value_init (&src2, GST_TYPE_FRACTION);
g_value_init (&result, GST_TYPE_FRACTION);
gst_value_set_fraction (&src1, 1, 2);
gst_value_set_fraction (&src2, 1, 4);
fail_unless (gst_value_fraction_subtract (&result, &src1, &src2) == TRUE);
fail_unless (gst_value_get_fraction_numerator (&result) == 1);
fail_unless (gst_value_get_fraction_denominator (&result) == 4);
g_value_unset (&src1);
g_value_unset (&src2);
g_value_unset (&result);
/* Subtract 1/12 from 7/8 */
g_value_init (&src1, GST_TYPE_FRACTION);
g_value_init (&src2, GST_TYPE_FRACTION);
g_value_init (&result, GST_TYPE_FRACTION);
gst_value_set_fraction (&src1, 7, 8);
gst_value_set_fraction (&src2, 1, 12);
fail_unless (gst_value_fraction_subtract (&result, &src1, &src2) == TRUE);
fail_unless (gst_value_get_fraction_numerator (&result) == 19);
fail_unless (gst_value_get_fraction_denominator (&result) == 24);
g_value_unset (&src1);
g_value_unset (&src2);
g_value_unset (&result);
}
GST_END_TEST;
/* Test set subtraction operations on fraction ranges */
GST_START_TEST (test_value_subtract_fraction_range)
{
GValue dest = { 0 };
GValue src1 = { 0 };
GValue src2 = { 0 };
GValue cmp = { 0 };
const GValue *tmp;
gboolean ret;
/* Value for tests */
g_value_init (&cmp, GST_TYPE_FRACTION);
/* fraction <-> fraction
*/
g_value_init (&src1, GST_TYPE_FRACTION);
gst_value_set_fraction (&src1, 10, 1);
g_value_init (&src2, GST_TYPE_FRACTION);
gst_value_set_fraction (&src2, 20, 1);
gst_value_set_fraction (&src1, 10, 1);
/* subtract as in sets, result is 10 */
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == TRUE);
fail_unless (gst_value_compare (&dest, &src1) == GST_VALUE_EQUAL);
g_value_unset (&dest);
/* same values, yields empty set */
ret = gst_value_subtract (&dest, &src1, &src1);
fail_unless (ret == FALSE);
g_value_unset (&src1);
g_value_unset (&src2);
/* fraction <-> fraction_range
*/
/* would yield an empty set */
g_value_init (&src1, GST_TYPE_FRACTION);
gst_value_set_fraction (&src1, 10, 1);
g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
gst_value_set_fraction_range_full (&src2, 0, 1, 20, 1);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == FALSE);
/* and the other way around, we cannot create open ranges
* so the result is the range again */
ret = gst_value_subtract (&dest, &src2, &src1);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (&dest) == TRUE);
gst_value_set_fraction (&cmp, 0, 1);
fail_unless (gst_value_compare (gst_value_get_fraction_range_min (&dest),
&cmp) == GST_VALUE_EQUAL);
gst_value_set_fraction (&cmp, 20, 1);
fail_unless (gst_value_compare (gst_value_get_fraction_range_max (&dest),
&cmp) == GST_VALUE_EQUAL);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* border case 1, empty set */
g_value_init (&src1, GST_TYPE_FRACTION);
gst_value_set_fraction (&src1, 10, 1);
g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
gst_value_set_fraction_range_full (&src2, 10, 1, 20, 1);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == FALSE);
/* and the other way around, should keep same range as
* we don't have open ranges. */
ret = gst_value_subtract (&dest, &src2, &src1);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (&dest) == TRUE);
gst_value_set_fraction (&cmp, 10, 1);
fail_unless (gst_value_compare (gst_value_get_fraction_range_min (&dest),
&cmp) == GST_VALUE_EQUAL);
gst_value_set_fraction (&cmp, 20, 1);
fail_unless (gst_value_compare (gst_value_get_fraction_range_max (&dest),
&cmp) == GST_VALUE_EQUAL);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* case 2, valid set */
g_value_init (&src1, GST_TYPE_FRACTION);
gst_value_set_fraction (&src1, 0, 1);
g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
gst_value_set_fraction_range_full (&src2, 10, 1, 20, 1);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_FRACTION (&dest) == TRUE);
fail_unless (gst_value_compare (&dest, &src1) == GST_VALUE_EQUAL);
g_value_unset (&dest);
/* and the other way around, should keep the range. */
ret = gst_value_subtract (&dest, &src2, &src1);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (&dest) == TRUE);
fail_unless (gst_value_compare (&dest, &src2) == GST_VALUE_EQUAL);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* fraction_range <-> fraction_range
*/
/* same range, empty set */
g_value_init (&src1, GST_TYPE_FRACTION_RANGE);
gst_value_set_fraction_range_full (&src1, 10, 2, 20, 2);
g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
gst_value_set_fraction_range_full (&src2, 10, 2, 20, 2);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == FALSE);
ret = gst_value_subtract (&dest, &src2, &src1);
fail_unless (ret == FALSE);
g_value_unset (&src1);
g_value_unset (&src2);
/* non overlapping ranges */
g_value_init (&src1, GST_TYPE_FRACTION_RANGE);
gst_value_set_fraction_range_full (&src1, 10, 2, 10, 1);
g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
gst_value_set_fraction_range_full (&src2, 30, 2, 40, 2);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (&dest) == TRUE);
gst_value_set_fraction (&cmp, 5, 1);
fail_unless (gst_value_compare (gst_value_get_fraction_range_min (&dest),
&cmp) == GST_VALUE_EQUAL);
gst_value_set_fraction (&cmp, 10, 1);
fail_unless (gst_value_compare (gst_value_get_fraction_range_max (&dest),
&cmp) == GST_VALUE_EQUAL);
g_value_unset (&dest);
/* the other way */
ret = gst_value_subtract (&dest, &src2, &src1);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (&dest) == TRUE);
gst_value_set_fraction (&cmp, 15, 1);
fail_unless (gst_value_compare (gst_value_get_fraction_range_min (&dest),
&cmp) == GST_VALUE_EQUAL);
gst_value_set_fraction (&cmp, 20, 1);
fail_unless (gst_value_compare (gst_value_get_fraction_range_max (&dest),
&cmp) == GST_VALUE_EQUAL);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* completely overlapping ranges */
g_value_init (&src1, GST_TYPE_FRACTION_RANGE);
gst_value_set_fraction_range_full (&src1, 10, 1, 20, 1);
g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
gst_value_set_fraction_range_full (&src2, 10, 1, 30, 1);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == FALSE);
/* the other way */
ret = gst_value_subtract (&dest, &src2, &src1);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (&dest) == TRUE);
gst_value_set_fraction (&cmp, 20, 1);
fail_unless (gst_value_compare (gst_value_get_fraction_range_min (&dest),
&cmp) == GST_VALUE_EQUAL);
gst_value_set_fraction (&cmp, 30, 1);
fail_unless (gst_value_compare (gst_value_get_fraction_range_max (&dest),
&cmp) == GST_VALUE_EQUAL);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* partially overlapping ranges */
g_value_init (&src1, GST_TYPE_FRACTION_RANGE);
gst_value_set_fraction_range_full (&src1, 10, 1, 20, 1);
g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
gst_value_set_fraction_range_full (&src2, 15, 1, 30, 1);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (&dest) == TRUE);
gst_value_set_fraction (&cmp, 10, 1);
fail_unless (gst_value_compare (gst_value_get_fraction_range_min (&dest),
&cmp) == GST_VALUE_EQUAL);
gst_value_set_fraction (&cmp, 15, 1);
fail_unless (gst_value_compare (gst_value_get_fraction_range_max (&dest),
&cmp) == GST_VALUE_EQUAL);
g_value_unset (&dest);
/* the other way */
ret = gst_value_subtract (&dest, &src2, &src1);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (&dest) == TRUE);
gst_value_set_fraction (&cmp, 20, 1);
fail_unless (gst_value_compare (gst_value_get_fraction_range_min (&dest),
&cmp) == GST_VALUE_EQUAL);
gst_value_set_fraction (&cmp, 30, 1);
fail_unless (gst_value_compare (gst_value_get_fraction_range_max (&dest),
&cmp) == GST_VALUE_EQUAL);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* create a hole { double_range, double_range } */
g_value_init (&src1, GST_TYPE_FRACTION_RANGE);
gst_value_set_fraction_range_full (&src1, 10, 1, 30, 1);
g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
gst_value_set_fraction_range_full (&src2, 15, 1, 20, 1);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_LIST (&dest) == TRUE);
/* 1st list entry */
tmp = gst_value_list_get_value (&dest, 0);
fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (tmp) == TRUE);
gst_value_set_fraction (&cmp, 10, 1);
fail_unless (gst_value_compare (gst_value_get_fraction_range_min (tmp),
&cmp) == GST_VALUE_EQUAL);
gst_value_set_fraction (&cmp, 15, 1);
fail_unless (gst_value_compare (gst_value_get_fraction_range_max (tmp),
&cmp) == GST_VALUE_EQUAL);
/* 2nd list entry */
tmp = gst_value_list_get_value (&dest, 1);
fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (tmp) == TRUE);
gst_value_set_fraction (&cmp, 20, 1);
fail_unless (gst_value_compare (gst_value_get_fraction_range_min (tmp),
&cmp) == GST_VALUE_EQUAL);
gst_value_set_fraction (&cmp, 30, 1);
fail_unless (gst_value_compare (gst_value_get_fraction_range_max (tmp),
&cmp) == GST_VALUE_EQUAL);
g_value_unset (&dest);
/* the other way */
ret = gst_value_subtract (&dest, &src2, &src1);
fail_unless (ret == FALSE);
g_value_unset (&src1);
g_value_unset (&src2);
g_value_unset (&cmp);
}
GST_END_TEST;
GST_START_TEST (test_date)
{
GstStructure *s;
@ -1017,6 +1292,59 @@ GST_START_TEST (test_date)
GST_END_TEST;
GST_START_TEST (test_fraction_range)
{
GValue range = { 0, };
GValue start = { 0, }, end = {
0,};
GValue src = { 0, }, dest = {
0,};
GValue range2 = { 0, };
g_value_init (&range, GST_TYPE_FRACTION_RANGE);
g_value_init (&range2, GST_TYPE_FRACTION_RANGE);
g_value_init (&start, GST_TYPE_FRACTION);
g_value_init (&end, GST_TYPE_FRACTION);
g_value_init (&src, GST_TYPE_FRACTION);
gst_value_set_fraction (&src, 1, 2);
/* Check that a intersection of fraction & range = fraction */
gst_value_set_fraction (&start, 1, 4);
gst_value_set_fraction (&end, 2, 3);
gst_value_set_fraction_range (&range, &start, &end);
fail_unless (gst_value_intersect (&dest, &src, &range) == TRUE);
fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_FRACTION);
fail_unless (gst_value_compare (&dest, &src) == GST_VALUE_EQUAL);
/* Check that a intersection selects the overlapping range */
gst_value_set_fraction (&start, 1, 3);
gst_value_set_fraction (&end, 2, 3);
gst_value_set_fraction_range (&range2, &start, &end);
g_value_unset (&dest);
fail_unless (gst_value_intersect (&dest, &range, &range2) == TRUE);
fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_FRACTION_RANGE);
gst_value_set_fraction_range (&range2, &start, &end);
fail_unless (gst_value_compare (&dest, &range2) == GST_VALUE_EQUAL);
/* Check that non intersection ranges don't intersect */
gst_value_set_fraction (&start, 4, 2);
gst_value_set_fraction (&end, 5, 2);
gst_value_set_fraction_range (&range2, &start, &end);
g_value_unset (&dest);
fail_unless (gst_value_intersect (&dest, &range, &range2) == FALSE);
g_value_unset (&start);
g_value_unset (&end);
g_value_unset (&range);
g_value_unset (&range2);
g_value_unset (&src);
}
GST_END_TEST;
Suite *
gst_value_suite (void)
{
@ -1037,7 +1365,10 @@ gst_value_suite (void)
tcase_add_test (tc_chain, test_value_intersect);
tcase_add_test (tc_chain, test_value_subtract_int);
tcase_add_test (tc_chain, test_value_subtract_double);
tcase_add_test (tc_chain, test_value_subtract_fraction);
tcase_add_test (tc_chain, test_value_subtract_fraction_range);
tcase_add_test (tc_chain, test_date);
tcase_add_test (tc_chain, test_fraction_range);
return s;
}

View file

@ -1427,19 +1427,20 @@ gst_structure_parse_range (gchar * s, gchar ** after, GValue * value,
if (G_VALUE_TYPE (&value1) == G_TYPE_DOUBLE) {
range_type = GST_TYPE_DOUBLE_RANGE;
} else if (G_VALUE_TYPE (&value1) == G_TYPE_INT) {
range_type = GST_TYPE_INT_RANGE;
} else {
return FALSE;
}
g_value_init (value, range_type);
if (range_type == GST_TYPE_DOUBLE_RANGE) {
g_value_init (value, range_type);
gst_value_set_double_range (value, g_value_get_double (&value1),
g_value_get_double (&value2));
} else {
} else if (G_VALUE_TYPE (&value1) == G_TYPE_INT) {
range_type = GST_TYPE_INT_RANGE;
g_value_init (value, range_type);
gst_value_set_int_range (value, g_value_get_int (&value1),
g_value_get_int (&value2));
} else if (G_VALUE_TYPE (&value1) == GST_TYPE_FRACTION) {
range_type = GST_TYPE_FRACTION_RANGE;
g_value_init (value, range_type);
gst_value_set_fraction_range (value, &value1, &value2);
} else {
return FALSE;
}
*after = s;
@ -1927,3 +1928,80 @@ gst_structure_fixate_field_boolean (GstStructure * structure,
return FALSE;
}
/**
* gst_structure_fixate_field_nearest_fraction:
* @structure: a #GstStructure
* @field_name: a field in @structure
* @target: A GValue of GST_TYPE_FRACTION with the target value of the fixation
*
* Fixates a #GstStructure by changing the given field to the nearest
* integer to @target that is a subset of the existing field.
*
* Returns: TRUE if the structure could be fixated
*/
gboolean
gst_structure_fixate_field_nearest_fraction (GstStructure * structure,
const char *field_name, const GValue * target)
{
const GValue *value;
g_return_val_if_fail (gst_structure_has_field (structure, field_name), FALSE);
g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
g_return_val_if_fail (G_VALUE_TYPE (target) == GST_TYPE_FRACTION, FALSE);
value = gst_structure_get_value (structure, field_name);
if (G_VALUE_TYPE (value) == GST_TYPE_FRACTION) {
/* already fixed */
return FALSE;
} else if (G_VALUE_TYPE (value) == GST_TYPE_FRACTION_RANGE) {
const GValue *x;
x = gst_value_get_fraction_range_min (value);
if (gst_value_compare (target, x) == GST_VALUE_LESS_THAN)
target = x;
x = gst_value_get_fraction_range_max (value);
if (gst_value_compare (target, x) == GST_VALUE_GREATER_THAN)
target = x;
gst_structure_set_value (structure, field_name, target);
return TRUE;
} else if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
const GValue *list_value;
int i, n;
const GValue *best = NULL;
GValue best_diff;
GValue cur_diff;
g_value_init (&best_diff, GST_TYPE_FRACTION);
g_value_init (&cur_diff, GST_TYPE_FRACTION);
n = gst_value_list_get_size (value);
for (i = 0; i < n; i++) {
list_value = gst_value_list_get_value (value, i);
if (G_VALUE_TYPE (list_value) == GST_TYPE_FRACTION) {
if (best == NULL) {
best = list_value;
gst_value_set_fraction (&best_diff, 0, 1);
} else {
if (gst_value_compare (list_value, target) == GST_VALUE_LESS_THAN)
gst_value_fraction_subtract (&cur_diff, target, list_value);
else
gst_value_fraction_subtract (&cur_diff, list_value, target);
if (gst_value_compare (&cur_diff, &best_diff) == GST_VALUE_LESS_THAN) {
best = list_value;
g_value_copy (&cur_diff, &best_diff);
}
}
}
}
if (best != NULL) {
gst_structure_set_value (structure, field_name, best);
return TRUE;
}
return FALSE;
}
return FALSE;
}

View file

@ -189,7 +189,9 @@ gboolean gst_structure_fixate_field_nearest_double (GstStructure
gboolean gst_structure_fixate_field_boolean (GstStructure *structure,
const char *field_name,
gboolean target);
gboolean gst_structure_fixate_field_nearest_fraction (GstStructure *structure,
const char *field_name,
const GValue *target);
G_END_DECLS

View file

@ -61,6 +61,7 @@ struct _GstValueSubtractInfo
};
GType gst_type_double_range;
GType gst_type_fraction_range;
GType gst_type_list;
GType gst_type_array;
GType gst_type_fraction;
@ -71,6 +72,10 @@ static GArray *gst_value_union_funcs;
static GArray *gst_value_intersect_funcs;
static GArray *gst_value_subtract_funcs;
/* Forward declarations */
static gint gst_greatest_common_divisor (gint a, gint b);
static char *gst_value_serialize_fraction (const GValue * value);
/********
* list *
********/
@ -896,6 +901,254 @@ gst_value_deserialize_double_range (GValue * dest, const char *s)
return FALSE;
}
/****************
* fraction range *
****************/
static void
gst_value_init_fraction_range (GValue * value)
{
GValue *vals;
value->data[0].v_pointer = vals = g_new0 (GValue, 2);
g_value_init (&vals[0], GST_TYPE_FRACTION);
g_value_init (&vals[1], GST_TYPE_FRACTION);
}
static void
gst_value_free_fraction_range (GValue * value)
{
GValue *vals = (GValue *) value->data[0].v_pointer;
if (vals != NULL) {
g_value_unset (&vals[0]);
g_value_unset (&vals[1]);
g_free (vals);
value->data[0].v_pointer = NULL;
}
}
static void
gst_value_copy_fraction_range (const GValue * src_value, GValue * dest_value)
{
GValue *vals = (GValue *) dest_value->data[0].v_pointer;
GValue *src_vals = (GValue *) src_value->data[0].v_pointer;
if (vals == NULL) {
dest_value->data[0].v_pointer = vals = g_new0 (GValue, 2);
g_return_if_fail (vals != NULL);
g_value_init (&vals[0], GST_TYPE_FRACTION);
g_value_init (&vals[1], GST_TYPE_FRACTION);
}
if (src_vals != NULL) {
g_value_copy (&src_vals[0], &vals[0]);
g_value_copy (&src_vals[1], &vals[1]);
}
}
static gchar *
gst_value_collect_fraction_range (GValue * value, guint n_collect_values,
GTypeCValue * collect_values, guint collect_flags)
{
GValue *vals = (GValue *) value->data[0].v_pointer;
if (n_collect_values != 4)
return g_strdup_printf ("not enough value locations for `%s' passed",
G_VALUE_TYPE_NAME (value));
if (vals == NULL)
return g_strdup_printf ("Uninitialised `%s' passed",
G_VALUE_TYPE_NAME (value));
gst_value_set_fraction (&vals[0], collect_values[0].v_int,
collect_values[1].v_int);
gst_value_set_fraction (&vals[1], collect_values[2].v_int,
collect_values[3].v_int);
return NULL;
}
static gchar *
gst_value_lcopy_fraction_range (const GValue * value, guint n_collect_values,
GTypeCValue * collect_values, guint collect_flags)
{
int i;
int *dest_values[4];
GValue *vals = (GValue *) value->data[0].v_pointer;
if (n_collect_values != 4)
return g_strdup_printf ("not enough value locations for `%s' passed",
G_VALUE_TYPE_NAME (value));
for (i = 0; i < 4; i++) {
if (collect_values[i].v_pointer == NULL) {
return g_strdup_printf ("value location for `%s' passed as NULL",
G_VALUE_TYPE_NAME (value));
}
dest_values[i] = collect_values[i].v_pointer;
}
if (vals == NULL) {
return g_strdup_printf ("Uninitialised `%s' passed",
G_VALUE_TYPE_NAME (value));
}
dest_values[0][0] = gst_value_get_fraction_numerator (&vals[0]);
dest_values[1][0] = gst_value_get_fraction_denominator (&vals[0]);
dest_values[2][0] = gst_value_get_fraction_denominator (&vals[1]);
dest_values[3][0] = gst_value_get_fraction_denominator (&vals[1]);
return NULL;
}
/**
* gst_value_set_fraction_range:
* @value: a GValue initialized to GST_TYPE_FRACTION_RANGE
* @start: the start of the range (a GST_TYPE_FRACTION GValue)
* @end: the end of the range (a GST_TYPE_FRACTION GValue)
*
* Sets @value to the range specified by @start and @end.
*/
void
gst_value_set_fraction_range (GValue * value, const GValue * start,
const GValue * end)
{
GValue *vals;
g_return_if_fail (GST_VALUE_HOLDS_FRACTION_RANGE (value));
vals = (GValue *) value->data[0].v_pointer;
if (vals == NULL) {
value->data[0].v_pointer = vals = g_new0 (GValue, 2);
g_value_init (&vals[0], GST_TYPE_FRACTION);
g_value_init (&vals[1], GST_TYPE_FRACTION);
}
g_value_copy (start, &vals[0]);
g_value_copy (end, &vals[1]);
}
void
gst_value_set_fraction_range_full (GValue * value,
int numerator_start, int denominator_start,
int numerator_end, int denominator_end)
{
GValue start = { 0 };
GValue end = { 0 };
g_value_init (&start, GST_TYPE_FRACTION);
g_value_init (&end, GST_TYPE_FRACTION);
gst_value_set_fraction (&start, numerator_start, denominator_start);
gst_value_set_fraction (&end, numerator_end, denominator_end);
gst_value_set_fraction_range (value, &start, &end);
g_value_unset (&start);
g_value_unset (&end);
}
/**
* gst_value_get_fraction_range_min:
* @value: a GValue initialized to GST_TYPE_FRACTION_RANGE
*
* Gets the minimum of the range specified by @value.
*
* Returns: the minumum of the range
*/
const GValue *
gst_value_get_fraction_range_min (const GValue * value)
{
GValue *vals;
g_return_val_if_fail (GST_VALUE_HOLDS_FRACTION_RANGE (value), FALSE);
vals = (GValue *) value->data[0].v_pointer;
if (vals != NULL) {
return &vals[0];
}
return NULL;
}
/**
* gst_value_get_fraction_range_max:
* @value: a GValue initialized to GST_TYPE_FRACTION_RANGE
*
* Gets the maximum of the range specified by @value.
*
* Returns: the maximum of the range
*/
const GValue *
gst_value_get_fraction_range_max (const GValue * value)
{
GValue *vals;
g_return_val_if_fail (GST_VALUE_HOLDS_FRACTION_RANGE (value), FALSE);
vals = (GValue *) value->data[0].v_pointer;
if (vals != NULL) {
return &vals[1];
}
return NULL;
}
static char *
gst_value_serialize_fraction_range (const GValue * value)
{
GValue *vals = (GValue *) value->data[0].v_pointer;
gchar *retval;
if (vals == NULL) {
retval = g_strdup ("[ 0/1, 0/1 ]");
} else {
gchar *start, *end;
start = gst_value_serialize_fraction (&vals[0]);
end = gst_value_serialize_fraction (&vals[1]);
retval = g_strdup_printf ("[ %s, %s ]", start, end);
g_free (start);
g_free (end);
}
return retval;
}
static void
gst_value_transform_fraction_range_string (const GValue * src_value,
GValue * dest_value)
{
dest_value->data[0].v_pointer =
gst_value_serialize_fraction_range (src_value);
}
static int
gst_value_compare_fraction_range (const GValue * value1, const GValue * value2)
{
GValue *vals1, *vals2;
if (value2->data[0].v_pointer == value1->data[0].v_pointer)
return GST_VALUE_EQUAL; /* Only possible if both are NULL */
if (value2->data[0].v_pointer == NULL || value1->data[0].v_pointer == NULL)
return GST_VALUE_UNORDERED;
vals1 = (GValue *) value1->data[0].v_pointer;
vals2 = (GValue *) value2->data[0].v_pointer;
if (gst_value_compare (&vals1[0], &vals2[0]) == GST_VALUE_EQUAL &&
gst_value_compare (&vals1[1], &vals2[1]) == GST_VALUE_EQUAL)
return GST_VALUE_EQUAL;
return GST_VALUE_UNORDERED;
}
static gboolean
gst_value_deserialize_fraction_range (GValue * dest, const char *s)
{
g_warning ("unimplemented");
return FALSE;
}
/***********
* GstCaps *
***********/
@ -1869,6 +2122,76 @@ gst_value_intersect_array (GValue * dest, const GValue * src1,
return TRUE;
}
static gboolean
gst_value_intersect_fraction_fraction_range (GValue * dest, const GValue * src1,
const GValue * src2)
{
int res1, res2;
GValue *vals;
vals = src2->data[0].v_pointer;
if (vals == NULL)
return FALSE;
res1 = gst_value_compare (&vals[0], src1);
res2 = gst_value_compare (&vals[1], src1);
if ((res1 == GST_VALUE_EQUAL || res1 == GST_VALUE_LESS_THAN) &&
(res2 == GST_VALUE_EQUAL || res2 == GST_VALUE_GREATER_THAN)) {
gst_value_init_and_copy (dest, src1);
return TRUE;
}
return FALSE;
}
static gboolean
gst_value_intersect_fraction_range_fraction_range
(GValue * dest, const GValue * src1, const GValue * src2)
{
GValue *min;
GValue *max;
int res;
GValue *vals1, *vals2;
vals1 = src1->data[0].v_pointer;
vals2 = src2->data[0].v_pointer;
g_return_val_if_fail (vals1 != NULL && vals2 != NULL, FALSE);
/* min = MAX (src1.start, src2.start) */
res = gst_value_compare (&vals1[0], &vals2[0]);
g_return_val_if_fail (res != GST_VALUE_UNORDERED, FALSE);
if (res == GST_VALUE_LESS_THAN)
min = &vals2[0]; /* Take the max of the 2 */
else
min = &vals1[0];
/* max = MIN (src1.end, src2.end) */
res = gst_value_compare (&vals1[1], &vals2[1]);
g_return_val_if_fail (res != GST_VALUE_UNORDERED, FALSE);
if (res == GST_VALUE_GREATER_THAN)
max = &vals2[1]; /* Take the min of the 2 */
else
max = &vals1[1];
res = gst_value_compare (min, max);
g_return_val_if_fail (res != GST_VALUE_UNORDERED, FALSE);
if (res == GST_VALUE_LESS_THAN) {
g_value_init (dest, GST_TYPE_FRACTION_RANGE);
vals1 = dest->data[0].v_pointer;
g_value_copy (min, &vals1[0]);
g_value_copy (max, &vals1[1]);
return TRUE;
}
if (res == GST_VALUE_EQUAL) {
gst_value_init_and_copy (dest, min);
return TRUE;
}
return FALSE;
}
/***************
* subtraction *
***************/
@ -2126,6 +2449,94 @@ gst_value_subtract_list (GValue * dest, const GValue * minuend,
return TRUE;
}
static gboolean
gst_value_subtract_fraction_fraction_range (GValue * dest,
const GValue * minuend, const GValue * subtrahend)
{
const GValue *min = gst_value_get_fraction_range_min (subtrahend);
const GValue *max = gst_value_get_fraction_range_max (subtrahend);
/* subtracting a range from an fraction only works if the fraction
* is not in the range */
if (gst_value_compare (minuend, min) == GST_VALUE_LESS_THAN ||
gst_value_compare (minuend, max) == GST_VALUE_GREATER_THAN) {
/* and the result is the value */
gst_value_init_and_copy (dest, minuend);
return TRUE;
}
return FALSE;
}
static gboolean
gst_value_subtract_fraction_range_fraction (GValue * dest,
const GValue * minuend, const GValue * subtrahend)
{
/* since we don't have open ranges, we cannot create a hole in
* a range. We return the original range */
gst_value_init_and_copy (dest, minuend);
return TRUE;
}
static gboolean
gst_value_subtract_fraction_range_fraction_range (GValue * dest,
const GValue * minuend, const GValue * subtrahend)
{
/* since we don't have open ranges, we have to approximate */
/* done like with ints and doubles. Creates a list of 2 fraction ranges */
const GValue *min1 = gst_value_get_fraction_range_min (minuend);
const GValue *max2 = gst_value_get_fraction_range_max (minuend);
const GValue *max1 = gst_value_get_fraction_range_min (subtrahend);
const GValue *min2 = gst_value_get_fraction_range_max (subtrahend);
int cmp1, cmp2;
GValue v1 = { 0, };
GValue v2 = { 0, };
GValue *pv1, *pv2; /* yeah, hungarian! */
g_return_val_if_fail (min1 != NULL && max1 != NULL, FALSE);
g_return_val_if_fail (min2 != NULL && max2 != NULL, FALSE);
cmp1 = gst_value_compare (max2, max1);
g_return_val_if_fail (cmp1 != GST_VALUE_UNORDERED, FALSE);
if (cmp1 == GST_VALUE_LESS_THAN)
max1 = max2;
cmp1 = gst_value_compare (min1, min2);
g_return_val_if_fail (cmp1 != GST_VALUE_UNORDERED, FALSE);
if (cmp1 == GST_VALUE_GREATER_THAN)
min2 = min1;
cmp1 = gst_value_compare (min1, max1);
cmp2 = gst_value_compare (min2, max2);
if (cmp1 == GST_VALUE_LESS_THAN && cmp2 == GST_VALUE_LESS_THAN) {
pv1 = &v1;
pv2 = &v2;
} else if (cmp1 == GST_VALUE_LESS_THAN) {
pv1 = dest;
pv2 = NULL;
} else if (cmp2 == GST_VALUE_LESS_THAN) {
pv1 = NULL;
pv2 = dest;
} else {
return FALSE;
}
if (cmp1 == GST_VALUE_LESS_THAN) {
g_value_init (pv1, GST_TYPE_FRACTION_RANGE);
gst_value_set_fraction_range (pv1, min1, max1);
}
if (cmp2 == GST_VALUE_LESS_THAN) {
g_value_init (pv2, GST_TYPE_FRACTION_RANGE);
gst_value_set_fraction_range (pv2, min2, max2);
}
if (cmp1 == GST_VALUE_LESS_THAN && cmp2 == GST_VALUE_LESS_THAN) {
gst_value_list_concat (dest, pv1, pv2);
g_value_unset (pv1);
g_value_unset (pv2);
}
return TRUE;
}
/**************
* comparison *
@ -2857,6 +3268,55 @@ gst_value_fraction_multiply (GValue * product, const GValue * factor1,
return TRUE;
}
/**
* gst_value_fraction_subtract:
* @dest: a GValue initialized to #GST_TYPE_FRACTION
* @minued: a GValue initialized to #GST_TYPE_FRACTION
* @subtrahend: a GValue initialized to #GST_TYPE_FRACTION
*
* Subtracts the @subtrahend from the @minuend and sets @dest to the result.
*
* Returns: FALSE in case of an error (like integer overflow), TRUE otherwise.
*/
gboolean
gst_value_fraction_subtract (GValue * dest,
const GValue * minuend, const GValue * subtrahend)
{
gint gcd, n1, n2, d1, d2;
g_return_val_if_fail (GST_VALUE_HOLDS_FRACTION (minuend), FALSE);
g_return_val_if_fail (GST_VALUE_HOLDS_FRACTION (subtrahend), FALSE);
n1 = minuend->data[0].v_int;
n2 = subtrahend->data[0].v_int;
d1 = minuend->data[1].v_int;
d2 = subtrahend->data[1].v_int;
if (n1 == 0) {
gst_value_set_fraction (dest, -n2, d2);
return TRUE;
}
if (n2 == 0) {
gst_value_set_fraction (dest, n1, d1);
return TRUE;
}
gcd = gst_greatest_common_divisor (n1, d2);
n1 /= gcd;
d2 /= gcd;
gcd = gst_greatest_common_divisor (n2, d1);
n2 /= gcd;
d1 /= gcd;
g_return_val_if_fail (n1 == 0 || G_MAXINT / ABS (n1) >= ABS (d2), FALSE);
g_return_val_if_fail (G_MAXINT / ABS (d1) >= ABS (n2), FALSE);
g_return_val_if_fail (G_MAXINT / ABS (d1) >= ABS (d2), FALSE);
gst_value_set_fraction (dest, (n1 * d2) - (n2 * d1), d1 * d2);
return TRUE;
}
static char *
gst_value_serialize_fraction (const GValue * value)
{
@ -2887,6 +3347,10 @@ gst_value_deserialize_fraction (GValue * dest, const char *s)
gst_value_set_fraction (dest, num, den);
return TRUE;
}
if (s && sscanf (s, "%d", &num) == 1) {
gst_value_set_fraction (dest, num, 1);
return TRUE;
}
return FALSE;
}
@ -3221,6 +3685,19 @@ static const GTypeValueTable _gst_double_range_value_table = {
FUNC_VALUE_GET_TYPE (double_range, "GstDoubleRange");
static const GTypeValueTable _gst_fraction_range_value_table = {
gst_value_init_fraction_range,
gst_value_free_fraction_range,
gst_value_copy_fraction_range,
NULL,
"iiii",
gst_value_collect_fraction_range,
"pppp",
gst_value_lcopy_fraction_range
};
FUNC_VALUE_GET_TYPE (fraction_range, "GstFractionRange");
static const GTypeValueTable _gst_value_list_value_table = {
gst_value_init_list_or_array,
gst_value_free_list_or_array,
@ -3328,6 +3805,18 @@ _gst_value_initialize (void)
gst_value_register (&gst_value);
}
{
static GstValueTable gst_value = {
0,
gst_value_compare_fraction_range,
gst_value_serialize_fraction_range,
gst_value_deserialize_fraction_range,
};
gst_value.type = gst_fraction_range_get_type ();
gst_value_register (&gst_value);
}
{
static GstValueTable gst_value = {
0,
@ -3433,6 +3922,8 @@ _gst_value_initialize (void)
gst_value_transform_int_range_string);
g_value_register_transform_func (GST_TYPE_DOUBLE_RANGE, G_TYPE_STRING,
gst_value_transform_double_range_string);
g_value_register_transform_func (GST_TYPE_FRACTION_RANGE, G_TYPE_STRING,
gst_value_transform_fraction_range_string);
g_value_register_transform_func (GST_TYPE_LIST, G_TYPE_STRING,
gst_value_transform_list_string);
g_value_register_transform_func (GST_TYPE_ARRAY, G_TYPE_STRING,
@ -3460,6 +3951,11 @@ _gst_value_initialize (void)
GST_TYPE_DOUBLE_RANGE, gst_value_intersect_double_range_double_range);
gst_value_register_intersect_func (GST_TYPE_ARRAY,
GST_TYPE_ARRAY, gst_value_intersect_array);
gst_value_register_intersect_func (GST_TYPE_FRACTION, GST_TYPE_FRACTION_RANGE,
gst_value_intersect_fraction_fraction_range);
gst_value_register_intersect_func (GST_TYPE_FRACTION_RANGE,
GST_TYPE_FRACTION_RANGE,
gst_value_intersect_fraction_range_fraction_range);
gst_value_register_subtract_func (G_TYPE_INT, GST_TYPE_INT_RANGE,
gst_value_subtract_int_int_range);
@ -3474,6 +3970,14 @@ _gst_value_initialize (void)
gst_value_register_subtract_func (GST_TYPE_DOUBLE_RANGE,
GST_TYPE_DOUBLE_RANGE, gst_value_subtract_double_range_double_range);
gst_value_register_subtract_func (GST_TYPE_FRACTION, GST_TYPE_FRACTION_RANGE,
gst_value_subtract_fraction_fraction_range);
gst_value_register_subtract_func (GST_TYPE_FRACTION_RANGE, GST_TYPE_FRACTION,
gst_value_subtract_fraction_range_fraction);
gst_value_register_subtract_func (GST_TYPE_FRACTION_RANGE,
GST_TYPE_FRACTION_RANGE,
gst_value_subtract_fraction_range_fraction_range);
#if GLIB_CHECK_VERSION(2,8,0)
/* see bug #317246, #64994, #65041 */
{
@ -3487,4 +3991,12 @@ _gst_value_initialize (void)
gst_value_union_int_int_range);
gst_value_register_union_func (GST_TYPE_INT_RANGE, GST_TYPE_INT_RANGE,
gst_value_union_int_range_int_range);
#if 0
/* Implement these if needed */
gst_value_register_union_func (GST_TYPE_FRACTION, GST_TYPE_FRACTION_RANGE,
gst_value_union_fraction_fraction_range);
gst_value_register_union_func (GST_TYPE_FRACTION_RANGE,
GST_TYPE_FRACTION_RANGE, gst_value_union_fraction_range_fraction_range);
#endif
}

View file

@ -108,6 +108,14 @@ G_BEGIN_DECLS
*/
#define GST_VALUE_HOLDS_DOUBLE_RANGE(x) (G_VALUE_HOLDS(x, gst_double_range_get_type ()))
/**
* GST_VALUE_HOLDS_FRACTION_RANGE:
* @x: the #GValue to check
*
* Checks if the given #GValue contains a #GST_TYPE_FRACTION_RANGE value.
*/
#define GST_VALUE_HOLDS_FRACTION_RANGE(x) (G_VALUE_HOLDS(x, gst_fraction_range_get_type ()))
/**
* GST_VALUE_HOLDS_LIST:
* @x: the #GValue to check
@ -183,6 +191,15 @@ G_BEGIN_DECLS
*/
#define GST_TYPE_DOUBLE_RANGE gst_double_range_get_type ()
/**
* GST_TYPE_FRACTION_RANGE:
*
* a #GValue type that represents a GstFraction range
*
* Returns: the #GType of GstFractionRange
*/
#define GST_TYPE_FRACTION_RANGE gst_fraction_range_get_type ()
/**
* GST_TYPE_LIST:
*
@ -362,6 +379,7 @@ struct _GstValueTable {
GType gst_int_range_get_type (void);
GType gst_double_range_get_type (void);
GType gst_fraction_range_get_type (void);
GType gst_fourcc_get_type (void);
GType gst_fraction_get_type (void);
GType gst_value_list_get_type (void);
@ -434,6 +452,21 @@ int gst_value_get_fraction_denominator(const GValue *value);
gboolean gst_value_fraction_multiply (GValue *product,
const GValue *factor1,
const GValue *factor2);
gboolean gst_value_fraction_subtract (GValue * dest,
const GValue * minuend,
const GValue * subtrahend);
/* fraction range */
void gst_value_set_fraction_range (GValue *value,
const GValue *start,
const GValue *end);
void gst_value_set_fraction_range_full (GValue *value,
int numerator_start,
int denominator_start,
int numerator_end,
int denominator_end);
const GValue *gst_value_get_fraction_range_min (const GValue *value);
const GValue *gst_value_get_fraction_range_max (const GValue *value);
/* date */
G_CONST_RETURN GDate *

View file

@ -15,6 +15,10 @@ static const gchar *caps_list[] = {
"video/x-raw-rgb, bpp = (int) 32, depth = (int) 24, endianness = (int) BIG_ENDIAN, red_mask = (int) 0x000000FF, framerate = (double) [ 0, max ]",
"video/x-raw-rgb, bpp = (int) 32, depth = (int) 24, endianness = (int) BIG_ENDIAN, red_mask = (int) 0xFF000000, framerate = (double) [ 0, max ]",
"video/x-raw-rgb,\\ bpp=(int)32",
"test/gst-fraction, fraction = (fraction) 1/8",
"test/gst-fraction-range, fraction = (fraction) [ 1/3, 1/4 ]",
"test/gst-fraction-range, fraction = (fraction) { [ 1/3, 1/4 ], 1/8 }",
"test/gst-fraction-range, fraction = (fraction) { [ 1/3, 1/4 ], [ 1/8, 2/8 ] }",
"ANY",
"EMPTY"
};

View file

@ -128,14 +128,14 @@ GST_START_TEST (test_static_caps)
GST_END_TEST;
static const gchar non_simple_caps_string[] =
"video/x-raw-yuv, format=(fourcc)I420, framerate=(double)[ 1, 100 ], "
"video/x-raw-yuv, format=(fourcc)I420, framerate=(fraction)[ 1/100, 100 ], "
"width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-raw-yuv, "
"format=(fourcc)YUY2, framerate=(double)[ 1, 100 ], width=(int)[ 16, 4096 ], "
"format=(fourcc)YUY2, framerate=(fraction)[ 1/100, 100 ], width=(int)[ 16, 4096 ], "
"height=(int)[ 16, 4096 ]; video/x-raw-rgb, bpp=(int)8, depth=(int)8, "
"endianness=(int)1234, framerate=(double)[ 1, 100 ], width=(int)[ 16, 4096 ], "
"endianness=(int)1234, framerate=(fraction)[ 1/100, 100 ], width=(int)[ 16, 4096 ], "
"height=(int)[ 16, 4096 ]; video/x-raw-yuv, "
"format=(fourcc){ I420, YUY2, YV12 }, width=(int)[ 16, 4096 ], "
"height=(int)[ 16, 4096 ], framerate=(double)[ 1, 100 ]";
"height=(int)[ 16, 4096 ], framerate=(fraction)[ 1/100, 100 ]";
static gboolean
check_fourcc_list (const GValue * format_value)
@ -193,11 +193,11 @@ GST_START_TEST (test_simplify)
/* check simplified caps, should be:
*
* video/x-raw-rgb, bpp=(int)8, depth=(int)8, endianness=(int)1234,
* framerate=(double)[ 1, 100 ], width=(int)[ 16, 4096 ],
* framerate=(fraction)[ 1/100, 100 ], width=(int)[ 16, 4096 ],
* height=(int)[ 16, 4096 ];
* video/x-raw-yuv, format=(fourcc){ YV12, YUY2, I420 },
* width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ],
* framerate=(double)[ 1, 100 ]
* framerate=(fraction)[ 1/100, 100 ]
*/
fail_unless (gst_caps_get_size (caps) == 2);
s1 = gst_caps_get_structure (caps, 0);
@ -218,7 +218,8 @@ GST_START_TEST (test_simplify)
const GValue *framerate_value;
const GValue *width_value;
const GValue *height_value;
gdouble min_fps, max_fps;
const GValue *val_fps;
GValue test_fps = { 0, };
gint bpp, depth, endianness;
gint min_width, max_width;
gint min_height, max_height;
@ -232,12 +233,20 @@ GST_START_TEST (test_simplify)
fail_unless (gst_structure_get_int (s1, "endianness", &endianness));
fail_unless (endianness == G_LITTLE_ENDIAN);
g_value_init (&test_fps, GST_TYPE_FRACTION);
framerate_value = gst_structure_get_value (s1, "framerate");
fail_unless (framerate_value != NULL);
fail_unless (GST_VALUE_HOLDS_DOUBLE_RANGE (framerate_value));
min_fps = gst_value_get_double_range_min (framerate_value);
max_fps = gst_value_get_double_range_max (framerate_value);
fail_unless (min_fps == 1.0 && max_fps == 100.0);
fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (framerate_value));
val_fps = gst_value_get_fraction_range_min (framerate_value);
gst_value_set_fraction (&test_fps, 1, 100);
fail_unless (gst_value_compare (&test_fps, val_fps) == GST_VALUE_EQUAL);
val_fps = gst_value_get_fraction_range_max (framerate_value);
gst_value_set_fraction (&test_fps, 100, 1);
fail_unless (gst_value_compare (&test_fps, val_fps) == GST_VALUE_EQUAL);
g_value_unset (&test_fps);
width_value = gst_structure_get_value (s1, "width");
fail_unless (width_value != NULL);
@ -260,7 +269,8 @@ GST_START_TEST (test_simplify)
const GValue *format_value;
const GValue *width_value;
const GValue *height_value;
gdouble min_fps, max_fps;
const GValue *val_fps;
GValue test_fps = { 0, };
gint min_width, max_width;
gint min_height, max_height;
@ -270,12 +280,20 @@ GST_START_TEST (test_simplify)
fail_unless (gst_value_list_get_size (format_value) == 3);
fail_unless (check_fourcc_list (format_value) == TRUE);
g_value_init (&test_fps, GST_TYPE_FRACTION);
framerate_value = gst_structure_get_value (s2, "framerate");
fail_unless (framerate_value != NULL);
fail_unless (GST_VALUE_HOLDS_DOUBLE_RANGE (framerate_value));
min_fps = gst_value_get_double_range_min (framerate_value);
max_fps = gst_value_get_double_range_max (framerate_value);
fail_unless (min_fps == 1.0 && max_fps == 100.0);
fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (framerate_value));
val_fps = gst_value_get_fraction_range_min (framerate_value);
gst_value_set_fraction (&test_fps, 1, 100);
fail_unless (gst_value_compare (&test_fps, val_fps) == GST_VALUE_EQUAL);
val_fps = gst_value_get_fraction_range_max (framerate_value);
gst_value_set_fraction (&test_fps, 100, 1);
fail_unless (gst_value_compare (&test_fps, val_fps) == GST_VALUE_EQUAL);
g_value_unset (&test_fps);
width_value = gst_structure_get_value (s2, "width");
fail_unless (width_value != NULL);

View file

@ -435,6 +435,7 @@ GST_START_TEST (test_value_compare)
fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
g_value_unset (&value1);
g_value_unset (&value2);
}
GST_END_TEST;
@ -958,6 +959,280 @@ GST_START_TEST (test_value_subtract_double)
GST_END_TEST;
/* Test arithmetic subtraction of fractions */
GST_START_TEST (test_value_subtract_fraction)
{
GValue result = { 0 };
GValue src1 = { 0 };
GValue src2 = { 0 };
/* Subtract 1/4 from 1/2 */
g_value_init (&src1, GST_TYPE_FRACTION);
g_value_init (&src2, GST_TYPE_FRACTION);
g_value_init (&result, GST_TYPE_FRACTION);
gst_value_set_fraction (&src1, 1, 2);
gst_value_set_fraction (&src2, 1, 4);
fail_unless (gst_value_fraction_subtract (&result, &src1, &src2) == TRUE);
fail_unless (gst_value_get_fraction_numerator (&result) == 1);
fail_unless (gst_value_get_fraction_denominator (&result) == 4);
g_value_unset (&src1);
g_value_unset (&src2);
g_value_unset (&result);
/* Subtract 1/12 from 7/8 */
g_value_init (&src1, GST_TYPE_FRACTION);
g_value_init (&src2, GST_TYPE_FRACTION);
g_value_init (&result, GST_TYPE_FRACTION);
gst_value_set_fraction (&src1, 7, 8);
gst_value_set_fraction (&src2, 1, 12);
fail_unless (gst_value_fraction_subtract (&result, &src1, &src2) == TRUE);
fail_unless (gst_value_get_fraction_numerator (&result) == 19);
fail_unless (gst_value_get_fraction_denominator (&result) == 24);
g_value_unset (&src1);
g_value_unset (&src2);
g_value_unset (&result);
}
GST_END_TEST;
/* Test set subtraction operations on fraction ranges */
GST_START_TEST (test_value_subtract_fraction_range)
{
GValue dest = { 0 };
GValue src1 = { 0 };
GValue src2 = { 0 };
GValue cmp = { 0 };
const GValue *tmp;
gboolean ret;
/* Value for tests */
g_value_init (&cmp, GST_TYPE_FRACTION);
/* fraction <-> fraction
*/
g_value_init (&src1, GST_TYPE_FRACTION);
gst_value_set_fraction (&src1, 10, 1);
g_value_init (&src2, GST_TYPE_FRACTION);
gst_value_set_fraction (&src2, 20, 1);
gst_value_set_fraction (&src1, 10, 1);
/* subtract as in sets, result is 10 */
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == TRUE);
fail_unless (gst_value_compare (&dest, &src1) == GST_VALUE_EQUAL);
g_value_unset (&dest);
/* same values, yields empty set */
ret = gst_value_subtract (&dest, &src1, &src1);
fail_unless (ret == FALSE);
g_value_unset (&src1);
g_value_unset (&src2);
/* fraction <-> fraction_range
*/
/* would yield an empty set */
g_value_init (&src1, GST_TYPE_FRACTION);
gst_value_set_fraction (&src1, 10, 1);
g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
gst_value_set_fraction_range_full (&src2, 0, 1, 20, 1);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == FALSE);
/* and the other way around, we cannot create open ranges
* so the result is the range again */
ret = gst_value_subtract (&dest, &src2, &src1);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (&dest) == TRUE);
gst_value_set_fraction (&cmp, 0, 1);
fail_unless (gst_value_compare (gst_value_get_fraction_range_min (&dest),
&cmp) == GST_VALUE_EQUAL);
gst_value_set_fraction (&cmp, 20, 1);
fail_unless (gst_value_compare (gst_value_get_fraction_range_max (&dest),
&cmp) == GST_VALUE_EQUAL);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* border case 1, empty set */
g_value_init (&src1, GST_TYPE_FRACTION);
gst_value_set_fraction (&src1, 10, 1);
g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
gst_value_set_fraction_range_full (&src2, 10, 1, 20, 1);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == FALSE);
/* and the other way around, should keep same range as
* we don't have open ranges. */
ret = gst_value_subtract (&dest, &src2, &src1);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (&dest) == TRUE);
gst_value_set_fraction (&cmp, 10, 1);
fail_unless (gst_value_compare (gst_value_get_fraction_range_min (&dest),
&cmp) == GST_VALUE_EQUAL);
gst_value_set_fraction (&cmp, 20, 1);
fail_unless (gst_value_compare (gst_value_get_fraction_range_max (&dest),
&cmp) == GST_VALUE_EQUAL);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* case 2, valid set */
g_value_init (&src1, GST_TYPE_FRACTION);
gst_value_set_fraction (&src1, 0, 1);
g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
gst_value_set_fraction_range_full (&src2, 10, 1, 20, 1);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_FRACTION (&dest) == TRUE);
fail_unless (gst_value_compare (&dest, &src1) == GST_VALUE_EQUAL);
g_value_unset (&dest);
/* and the other way around, should keep the range. */
ret = gst_value_subtract (&dest, &src2, &src1);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (&dest) == TRUE);
fail_unless (gst_value_compare (&dest, &src2) == GST_VALUE_EQUAL);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* fraction_range <-> fraction_range
*/
/* same range, empty set */
g_value_init (&src1, GST_TYPE_FRACTION_RANGE);
gst_value_set_fraction_range_full (&src1, 10, 2, 20, 2);
g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
gst_value_set_fraction_range_full (&src2, 10, 2, 20, 2);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == FALSE);
ret = gst_value_subtract (&dest, &src2, &src1);
fail_unless (ret == FALSE);
g_value_unset (&src1);
g_value_unset (&src2);
/* non overlapping ranges */
g_value_init (&src1, GST_TYPE_FRACTION_RANGE);
gst_value_set_fraction_range_full (&src1, 10, 2, 10, 1);
g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
gst_value_set_fraction_range_full (&src2, 30, 2, 40, 2);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (&dest) == TRUE);
gst_value_set_fraction (&cmp, 5, 1);
fail_unless (gst_value_compare (gst_value_get_fraction_range_min (&dest),
&cmp) == GST_VALUE_EQUAL);
gst_value_set_fraction (&cmp, 10, 1);
fail_unless (gst_value_compare (gst_value_get_fraction_range_max (&dest),
&cmp) == GST_VALUE_EQUAL);
g_value_unset (&dest);
/* the other way */
ret = gst_value_subtract (&dest, &src2, &src1);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (&dest) == TRUE);
gst_value_set_fraction (&cmp, 15, 1);
fail_unless (gst_value_compare (gst_value_get_fraction_range_min (&dest),
&cmp) == GST_VALUE_EQUAL);
gst_value_set_fraction (&cmp, 20, 1);
fail_unless (gst_value_compare (gst_value_get_fraction_range_max (&dest),
&cmp) == GST_VALUE_EQUAL);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* completely overlapping ranges */
g_value_init (&src1, GST_TYPE_FRACTION_RANGE);
gst_value_set_fraction_range_full (&src1, 10, 1, 20, 1);
g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
gst_value_set_fraction_range_full (&src2, 10, 1, 30, 1);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == FALSE);
/* the other way */
ret = gst_value_subtract (&dest, &src2, &src1);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (&dest) == TRUE);
gst_value_set_fraction (&cmp, 20, 1);
fail_unless (gst_value_compare (gst_value_get_fraction_range_min (&dest),
&cmp) == GST_VALUE_EQUAL);
gst_value_set_fraction (&cmp, 30, 1);
fail_unless (gst_value_compare (gst_value_get_fraction_range_max (&dest),
&cmp) == GST_VALUE_EQUAL);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* partially overlapping ranges */
g_value_init (&src1, GST_TYPE_FRACTION_RANGE);
gst_value_set_fraction_range_full (&src1, 10, 1, 20, 1);
g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
gst_value_set_fraction_range_full (&src2, 15, 1, 30, 1);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (&dest) == TRUE);
gst_value_set_fraction (&cmp, 10, 1);
fail_unless (gst_value_compare (gst_value_get_fraction_range_min (&dest),
&cmp) == GST_VALUE_EQUAL);
gst_value_set_fraction (&cmp, 15, 1);
fail_unless (gst_value_compare (gst_value_get_fraction_range_max (&dest),
&cmp) == GST_VALUE_EQUAL);
g_value_unset (&dest);
/* the other way */
ret = gst_value_subtract (&dest, &src2, &src1);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (&dest) == TRUE);
gst_value_set_fraction (&cmp, 20, 1);
fail_unless (gst_value_compare (gst_value_get_fraction_range_min (&dest),
&cmp) == GST_VALUE_EQUAL);
gst_value_set_fraction (&cmp, 30, 1);
fail_unless (gst_value_compare (gst_value_get_fraction_range_max (&dest),
&cmp) == GST_VALUE_EQUAL);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* create a hole { double_range, double_range } */
g_value_init (&src1, GST_TYPE_FRACTION_RANGE);
gst_value_set_fraction_range_full (&src1, 10, 1, 30, 1);
g_value_init (&src2, GST_TYPE_FRACTION_RANGE);
gst_value_set_fraction_range_full (&src2, 15, 1, 20, 1);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_LIST (&dest) == TRUE);
/* 1st list entry */
tmp = gst_value_list_get_value (&dest, 0);
fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (tmp) == TRUE);
gst_value_set_fraction (&cmp, 10, 1);
fail_unless (gst_value_compare (gst_value_get_fraction_range_min (tmp),
&cmp) == GST_VALUE_EQUAL);
gst_value_set_fraction (&cmp, 15, 1);
fail_unless (gst_value_compare (gst_value_get_fraction_range_max (tmp),
&cmp) == GST_VALUE_EQUAL);
/* 2nd list entry */
tmp = gst_value_list_get_value (&dest, 1);
fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (tmp) == TRUE);
gst_value_set_fraction (&cmp, 20, 1);
fail_unless (gst_value_compare (gst_value_get_fraction_range_min (tmp),
&cmp) == GST_VALUE_EQUAL);
gst_value_set_fraction (&cmp, 30, 1);
fail_unless (gst_value_compare (gst_value_get_fraction_range_max (tmp),
&cmp) == GST_VALUE_EQUAL);
g_value_unset (&dest);
/* the other way */
ret = gst_value_subtract (&dest, &src2, &src1);
fail_unless (ret == FALSE);
g_value_unset (&src1);
g_value_unset (&src2);
g_value_unset (&cmp);
}
GST_END_TEST;
GST_START_TEST (test_date)
{
GstStructure *s;
@ -1017,6 +1292,59 @@ GST_START_TEST (test_date)
GST_END_TEST;
GST_START_TEST (test_fraction_range)
{
GValue range = { 0, };
GValue start = { 0, }, end = {
0,};
GValue src = { 0, }, dest = {
0,};
GValue range2 = { 0, };
g_value_init (&range, GST_TYPE_FRACTION_RANGE);
g_value_init (&range2, GST_TYPE_FRACTION_RANGE);
g_value_init (&start, GST_TYPE_FRACTION);
g_value_init (&end, GST_TYPE_FRACTION);
g_value_init (&src, GST_TYPE_FRACTION);
gst_value_set_fraction (&src, 1, 2);
/* Check that a intersection of fraction & range = fraction */
gst_value_set_fraction (&start, 1, 4);
gst_value_set_fraction (&end, 2, 3);
gst_value_set_fraction_range (&range, &start, &end);
fail_unless (gst_value_intersect (&dest, &src, &range) == TRUE);
fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_FRACTION);
fail_unless (gst_value_compare (&dest, &src) == GST_VALUE_EQUAL);
/* Check that a intersection selects the overlapping range */
gst_value_set_fraction (&start, 1, 3);
gst_value_set_fraction (&end, 2, 3);
gst_value_set_fraction_range (&range2, &start, &end);
g_value_unset (&dest);
fail_unless (gst_value_intersect (&dest, &range, &range2) == TRUE);
fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_FRACTION_RANGE);
gst_value_set_fraction_range (&range2, &start, &end);
fail_unless (gst_value_compare (&dest, &range2) == GST_VALUE_EQUAL);
/* Check that non intersection ranges don't intersect */
gst_value_set_fraction (&start, 4, 2);
gst_value_set_fraction (&end, 5, 2);
gst_value_set_fraction_range (&range2, &start, &end);
g_value_unset (&dest);
fail_unless (gst_value_intersect (&dest, &range, &range2) == FALSE);
g_value_unset (&start);
g_value_unset (&end);
g_value_unset (&range);
g_value_unset (&range2);
g_value_unset (&src);
}
GST_END_TEST;
Suite *
gst_value_suite (void)
{
@ -1037,7 +1365,10 @@ gst_value_suite (void)
tcase_add_test (tc_chain, test_value_intersect);
tcase_add_test (tc_chain, test_value_subtract_int);
tcase_add_test (tc_chain, test_value_subtract_double);
tcase_add_test (tc_chain, test_value_subtract_fraction);
tcase_add_test (tc_chain, test_value_subtract_fraction_range);
tcase_add_test (tc_chain, test_date);
tcase_add_test (tc_chain, test_fraction_range);
return s;
}