mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-04 13:32:29 +00:00
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:
parent
f641e8a9fe
commit
506aa94ce2
11 changed files with 1406 additions and 42 deletions
33
ChangeLog
33
ChangeLog
|
@ -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>
|
2005-11-21 Andy Wingo <wingo@pobox.com>
|
||||||
|
|
||||||
* gst/gsttaglist.h:
|
* gst/gsttaglist.h:
|
||||||
|
|
|
@ -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) 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, depth = (int) 24, endianness = (int) BIG_ENDIAN, red_mask = (int) 0xFF000000, framerate = (double) [ 0, max ]",
|
||||||
"video/x-raw-rgb,\\ bpp=(int)32",
|
"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",
|
"ANY",
|
||||||
"EMPTY"
|
"EMPTY"
|
||||||
};
|
};
|
||||||
|
|
|
@ -128,14 +128,14 @@ GST_START_TEST (test_static_caps)
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
|
||||||
static const gchar non_simple_caps_string[] =
|
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, "
|
"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, "
|
"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, "
|
"height=(int)[ 16, 4096 ]; video/x-raw-yuv, "
|
||||||
"format=(fourcc){ I420, YUY2, YV12 }, width=(int)[ 16, 4096 ], "
|
"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
|
static gboolean
|
||||||
check_fourcc_list (const GValue * format_value)
|
check_fourcc_list (const GValue * format_value)
|
||||||
|
@ -193,11 +193,11 @@ GST_START_TEST (test_simplify)
|
||||||
/* check simplified caps, should be:
|
/* check simplified caps, should be:
|
||||||
*
|
*
|
||||||
* video/x-raw-rgb, bpp=(int)8, depth=(int)8, endianness=(int)1234,
|
* 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 ];
|
* height=(int)[ 16, 4096 ];
|
||||||
* video/x-raw-yuv, format=(fourcc){ YV12, YUY2, I420 },
|
* video/x-raw-yuv, format=(fourcc){ YV12, YUY2, I420 },
|
||||||
* width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ],
|
* 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);
|
fail_unless (gst_caps_get_size (caps) == 2);
|
||||||
s1 = gst_caps_get_structure (caps, 0);
|
s1 = gst_caps_get_structure (caps, 0);
|
||||||
|
@ -218,7 +218,8 @@ GST_START_TEST (test_simplify)
|
||||||
const GValue *framerate_value;
|
const GValue *framerate_value;
|
||||||
const GValue *width_value;
|
const GValue *width_value;
|
||||||
const GValue *height_value;
|
const GValue *height_value;
|
||||||
gdouble min_fps, max_fps;
|
const GValue *val_fps;
|
||||||
|
GValue test_fps = { 0, };
|
||||||
gint bpp, depth, endianness;
|
gint bpp, depth, endianness;
|
||||||
gint min_width, max_width;
|
gint min_width, max_width;
|
||||||
gint min_height, max_height;
|
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 (gst_structure_get_int (s1, "endianness", &endianness));
|
||||||
fail_unless (endianness == G_LITTLE_ENDIAN);
|
fail_unless (endianness == G_LITTLE_ENDIAN);
|
||||||
|
|
||||||
|
g_value_init (&test_fps, GST_TYPE_FRACTION);
|
||||||
framerate_value = gst_structure_get_value (s1, "framerate");
|
framerate_value = gst_structure_get_value (s1, "framerate");
|
||||||
fail_unless (framerate_value != NULL);
|
fail_unless (framerate_value != NULL);
|
||||||
fail_unless (GST_VALUE_HOLDS_DOUBLE_RANGE (framerate_value));
|
fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (framerate_value));
|
||||||
min_fps = gst_value_get_double_range_min (framerate_value);
|
|
||||||
max_fps = gst_value_get_double_range_max (framerate_value);
|
val_fps = gst_value_get_fraction_range_min (framerate_value);
|
||||||
fail_unless (min_fps == 1.0 && max_fps == 100.0);
|
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");
|
width_value = gst_structure_get_value (s1, "width");
|
||||||
fail_unless (width_value != NULL);
|
fail_unless (width_value != NULL);
|
||||||
|
@ -260,7 +269,8 @@ GST_START_TEST (test_simplify)
|
||||||
const GValue *format_value;
|
const GValue *format_value;
|
||||||
const GValue *width_value;
|
const GValue *width_value;
|
||||||
const GValue *height_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_width, max_width;
|
||||||
gint min_height, max_height;
|
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 (gst_value_list_get_size (format_value) == 3);
|
||||||
fail_unless (check_fourcc_list (format_value) == TRUE);
|
fail_unless (check_fourcc_list (format_value) == TRUE);
|
||||||
|
|
||||||
|
g_value_init (&test_fps, GST_TYPE_FRACTION);
|
||||||
framerate_value = gst_structure_get_value (s2, "framerate");
|
framerate_value = gst_structure_get_value (s2, "framerate");
|
||||||
fail_unless (framerate_value != NULL);
|
fail_unless (framerate_value != NULL);
|
||||||
fail_unless (GST_VALUE_HOLDS_DOUBLE_RANGE (framerate_value));
|
fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (framerate_value));
|
||||||
min_fps = gst_value_get_double_range_min (framerate_value);
|
|
||||||
max_fps = gst_value_get_double_range_max (framerate_value);
|
val_fps = gst_value_get_fraction_range_min (framerate_value);
|
||||||
fail_unless (min_fps == 1.0 && max_fps == 100.0);
|
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");
|
width_value = gst_structure_get_value (s2, "width");
|
||||||
fail_unless (width_value != NULL);
|
fail_unless (width_value != NULL);
|
||||||
|
|
|
@ -435,6 +435,7 @@ GST_START_TEST (test_value_compare)
|
||||||
fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
|
fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
|
||||||
g_value_unset (&value1);
|
g_value_unset (&value1);
|
||||||
g_value_unset (&value2);
|
g_value_unset (&value2);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
@ -958,6 +959,280 @@ GST_START_TEST (test_value_subtract_double)
|
||||||
|
|
||||||
GST_END_TEST;
|
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)
|
GST_START_TEST (test_date)
|
||||||
{
|
{
|
||||||
GstStructure *s;
|
GstStructure *s;
|
||||||
|
@ -1017,6 +1292,59 @@ GST_START_TEST (test_date)
|
||||||
|
|
||||||
GST_END_TEST;
|
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 *
|
Suite *
|
||||||
gst_value_suite (void)
|
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_intersect);
|
||||||
tcase_add_test (tc_chain, test_value_subtract_int);
|
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_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_date);
|
||||||
|
tcase_add_test (tc_chain, test_fraction_range);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1427,19 +1427,20 @@ gst_structure_parse_range (gchar * s, gchar ** after, GValue * value,
|
||||||
|
|
||||||
if (G_VALUE_TYPE (&value1) == G_TYPE_DOUBLE) {
|
if (G_VALUE_TYPE (&value1) == G_TYPE_DOUBLE) {
|
||||||
range_type = GST_TYPE_DOUBLE_RANGE;
|
range_type = GST_TYPE_DOUBLE_RANGE;
|
||||||
} else if (G_VALUE_TYPE (&value1) == G_TYPE_INT) {
|
g_value_init (value, range_type);
|
||||||
range_type = GST_TYPE_INT_RANGE;
|
|
||||||
} else {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_value_init (value, range_type);
|
|
||||||
if (range_type == GST_TYPE_DOUBLE_RANGE) {
|
|
||||||
gst_value_set_double_range (value, g_value_get_double (&value1),
|
gst_value_set_double_range (value, g_value_get_double (&value1),
|
||||||
g_value_get_double (&value2));
|
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),
|
gst_value_set_int_range (value, g_value_get_int (&value1),
|
||||||
g_value_get_int (&value2));
|
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;
|
*after = s;
|
||||||
|
@ -1927,3 +1928,80 @@ gst_structure_fixate_field_boolean (GstStructure * structure,
|
||||||
|
|
||||||
return FALSE;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -189,7 +189,9 @@ gboolean gst_structure_fixate_field_nearest_double (GstStructure
|
||||||
gboolean gst_structure_fixate_field_boolean (GstStructure *structure,
|
gboolean gst_structure_fixate_field_boolean (GstStructure *structure,
|
||||||
const char *field_name,
|
const char *field_name,
|
||||||
gboolean target);
|
gboolean target);
|
||||||
|
gboolean gst_structure_fixate_field_nearest_fraction (GstStructure *structure,
|
||||||
|
const char *field_name,
|
||||||
|
const GValue *target);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
512
gst/gstvalue.c
512
gst/gstvalue.c
|
@ -61,6 +61,7 @@ struct _GstValueSubtractInfo
|
||||||
};
|
};
|
||||||
|
|
||||||
GType gst_type_double_range;
|
GType gst_type_double_range;
|
||||||
|
GType gst_type_fraction_range;
|
||||||
GType gst_type_list;
|
GType gst_type_list;
|
||||||
GType gst_type_array;
|
GType gst_type_array;
|
||||||
GType gst_type_fraction;
|
GType gst_type_fraction;
|
||||||
|
@ -71,6 +72,10 @@ static GArray *gst_value_union_funcs;
|
||||||
static GArray *gst_value_intersect_funcs;
|
static GArray *gst_value_intersect_funcs;
|
||||||
static GArray *gst_value_subtract_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 *
|
* list *
|
||||||
********/
|
********/
|
||||||
|
@ -896,6 +901,254 @@ gst_value_deserialize_double_range (GValue * dest, const char *s)
|
||||||
return FALSE;
|
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 *
|
* GstCaps *
|
||||||
***********/
|
***********/
|
||||||
|
@ -1869,6 +2122,76 @@ gst_value_intersect_array (GValue * dest, const GValue * src1,
|
||||||
return TRUE;
|
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 *
|
* subtraction *
|
||||||
***************/
|
***************/
|
||||||
|
@ -2126,6 +2449,94 @@ gst_value_subtract_list (GValue * dest, const GValue * minuend,
|
||||||
return TRUE;
|
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 *
|
* comparison *
|
||||||
|
@ -2857,6 +3268,55 @@ gst_value_fraction_multiply (GValue * product, const GValue * factor1,
|
||||||
return TRUE;
|
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 *
|
static char *
|
||||||
gst_value_serialize_fraction (const GValue * value)
|
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);
|
gst_value_set_fraction (dest, num, den);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
if (s && sscanf (s, "%d", &num) == 1) {
|
||||||
|
gst_value_set_fraction (dest, num, 1);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -3221,6 +3685,19 @@ static const GTypeValueTable _gst_double_range_value_table = {
|
||||||
|
|
||||||
FUNC_VALUE_GET_TYPE (double_range, "GstDoubleRange");
|
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 = {
|
static const GTypeValueTable _gst_value_list_value_table = {
|
||||||
gst_value_init_list_or_array,
|
gst_value_init_list_or_array,
|
||||||
gst_value_free_list_or_array,
|
gst_value_free_list_or_array,
|
||||||
|
@ -3328,6 +3805,18 @@ _gst_value_initialize (void)
|
||||||
gst_value_register (&gst_value);
|
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 = {
|
static GstValueTable gst_value = {
|
||||||
0,
|
0,
|
||||||
|
@ -3433,6 +3922,8 @@ _gst_value_initialize (void)
|
||||||
gst_value_transform_int_range_string);
|
gst_value_transform_int_range_string);
|
||||||
g_value_register_transform_func (GST_TYPE_DOUBLE_RANGE, G_TYPE_STRING,
|
g_value_register_transform_func (GST_TYPE_DOUBLE_RANGE, G_TYPE_STRING,
|
||||||
gst_value_transform_double_range_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,
|
g_value_register_transform_func (GST_TYPE_LIST, G_TYPE_STRING,
|
||||||
gst_value_transform_list_string);
|
gst_value_transform_list_string);
|
||||||
g_value_register_transform_func (GST_TYPE_ARRAY, G_TYPE_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_TYPE_DOUBLE_RANGE, gst_value_intersect_double_range_double_range);
|
||||||
gst_value_register_intersect_func (GST_TYPE_ARRAY,
|
gst_value_register_intersect_func (GST_TYPE_ARRAY,
|
||||||
GST_TYPE_ARRAY, gst_value_intersect_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_register_subtract_func (G_TYPE_INT, GST_TYPE_INT_RANGE,
|
||||||
gst_value_subtract_int_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_value_register_subtract_func (GST_TYPE_DOUBLE_RANGE,
|
||||||
GST_TYPE_DOUBLE_RANGE, gst_value_subtract_double_range_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)
|
#if GLIB_CHECK_VERSION(2,8,0)
|
||||||
/* see bug #317246, #64994, #65041 */
|
/* see bug #317246, #64994, #65041 */
|
||||||
{
|
{
|
||||||
|
@ -3487,4 +3991,12 @@ _gst_value_initialize (void)
|
||||||
gst_value_union_int_int_range);
|
gst_value_union_int_int_range);
|
||||||
gst_value_register_union_func (GST_TYPE_INT_RANGE, GST_TYPE_INT_RANGE,
|
gst_value_register_union_func (GST_TYPE_INT_RANGE, GST_TYPE_INT_RANGE,
|
||||||
gst_value_union_int_range_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
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,6 +108,14 @@ G_BEGIN_DECLS
|
||||||
*/
|
*/
|
||||||
#define GST_VALUE_HOLDS_DOUBLE_RANGE(x) (G_VALUE_HOLDS(x, gst_double_range_get_type ()))
|
#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:
|
* GST_VALUE_HOLDS_LIST:
|
||||||
* @x: the #GValue to check
|
* @x: the #GValue to check
|
||||||
|
@ -183,6 +191,15 @@ G_BEGIN_DECLS
|
||||||
*/
|
*/
|
||||||
#define GST_TYPE_DOUBLE_RANGE gst_double_range_get_type ()
|
#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:
|
* GST_TYPE_LIST:
|
||||||
*
|
*
|
||||||
|
@ -362,6 +379,7 @@ struct _GstValueTable {
|
||||||
|
|
||||||
GType gst_int_range_get_type (void);
|
GType gst_int_range_get_type (void);
|
||||||
GType gst_double_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_fourcc_get_type (void);
|
||||||
GType gst_fraction_get_type (void);
|
GType gst_fraction_get_type (void);
|
||||||
GType gst_value_list_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,
|
gboolean gst_value_fraction_multiply (GValue *product,
|
||||||
const GValue *factor1,
|
const GValue *factor1,
|
||||||
const GValue *factor2);
|
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 */
|
/* date */
|
||||||
G_CONST_RETURN GDate *
|
G_CONST_RETURN GDate *
|
||||||
|
|
|
@ -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) 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, depth = (int) 24, endianness = (int) BIG_ENDIAN, red_mask = (int) 0xFF000000, framerate = (double) [ 0, max ]",
|
||||||
"video/x-raw-rgb,\\ bpp=(int)32",
|
"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",
|
"ANY",
|
||||||
"EMPTY"
|
"EMPTY"
|
||||||
};
|
};
|
||||||
|
|
|
@ -128,14 +128,14 @@ GST_START_TEST (test_static_caps)
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
|
||||||
static const gchar non_simple_caps_string[] =
|
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, "
|
"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, "
|
"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, "
|
"height=(int)[ 16, 4096 ]; video/x-raw-yuv, "
|
||||||
"format=(fourcc){ I420, YUY2, YV12 }, width=(int)[ 16, 4096 ], "
|
"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
|
static gboolean
|
||||||
check_fourcc_list (const GValue * format_value)
|
check_fourcc_list (const GValue * format_value)
|
||||||
|
@ -193,11 +193,11 @@ GST_START_TEST (test_simplify)
|
||||||
/* check simplified caps, should be:
|
/* check simplified caps, should be:
|
||||||
*
|
*
|
||||||
* video/x-raw-rgb, bpp=(int)8, depth=(int)8, endianness=(int)1234,
|
* 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 ];
|
* height=(int)[ 16, 4096 ];
|
||||||
* video/x-raw-yuv, format=(fourcc){ YV12, YUY2, I420 },
|
* video/x-raw-yuv, format=(fourcc){ YV12, YUY2, I420 },
|
||||||
* width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ],
|
* 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);
|
fail_unless (gst_caps_get_size (caps) == 2);
|
||||||
s1 = gst_caps_get_structure (caps, 0);
|
s1 = gst_caps_get_structure (caps, 0);
|
||||||
|
@ -218,7 +218,8 @@ GST_START_TEST (test_simplify)
|
||||||
const GValue *framerate_value;
|
const GValue *framerate_value;
|
||||||
const GValue *width_value;
|
const GValue *width_value;
|
||||||
const GValue *height_value;
|
const GValue *height_value;
|
||||||
gdouble min_fps, max_fps;
|
const GValue *val_fps;
|
||||||
|
GValue test_fps = { 0, };
|
||||||
gint bpp, depth, endianness;
|
gint bpp, depth, endianness;
|
||||||
gint min_width, max_width;
|
gint min_width, max_width;
|
||||||
gint min_height, max_height;
|
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 (gst_structure_get_int (s1, "endianness", &endianness));
|
||||||
fail_unless (endianness == G_LITTLE_ENDIAN);
|
fail_unless (endianness == G_LITTLE_ENDIAN);
|
||||||
|
|
||||||
|
g_value_init (&test_fps, GST_TYPE_FRACTION);
|
||||||
framerate_value = gst_structure_get_value (s1, "framerate");
|
framerate_value = gst_structure_get_value (s1, "framerate");
|
||||||
fail_unless (framerate_value != NULL);
|
fail_unless (framerate_value != NULL);
|
||||||
fail_unless (GST_VALUE_HOLDS_DOUBLE_RANGE (framerate_value));
|
fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (framerate_value));
|
||||||
min_fps = gst_value_get_double_range_min (framerate_value);
|
|
||||||
max_fps = gst_value_get_double_range_max (framerate_value);
|
val_fps = gst_value_get_fraction_range_min (framerate_value);
|
||||||
fail_unless (min_fps == 1.0 && max_fps == 100.0);
|
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");
|
width_value = gst_structure_get_value (s1, "width");
|
||||||
fail_unless (width_value != NULL);
|
fail_unless (width_value != NULL);
|
||||||
|
@ -260,7 +269,8 @@ GST_START_TEST (test_simplify)
|
||||||
const GValue *format_value;
|
const GValue *format_value;
|
||||||
const GValue *width_value;
|
const GValue *width_value;
|
||||||
const GValue *height_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_width, max_width;
|
||||||
gint min_height, max_height;
|
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 (gst_value_list_get_size (format_value) == 3);
|
||||||
fail_unless (check_fourcc_list (format_value) == TRUE);
|
fail_unless (check_fourcc_list (format_value) == TRUE);
|
||||||
|
|
||||||
|
g_value_init (&test_fps, GST_TYPE_FRACTION);
|
||||||
framerate_value = gst_structure_get_value (s2, "framerate");
|
framerate_value = gst_structure_get_value (s2, "framerate");
|
||||||
fail_unless (framerate_value != NULL);
|
fail_unless (framerate_value != NULL);
|
||||||
fail_unless (GST_VALUE_HOLDS_DOUBLE_RANGE (framerate_value));
|
fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (framerate_value));
|
||||||
min_fps = gst_value_get_double_range_min (framerate_value);
|
|
||||||
max_fps = gst_value_get_double_range_max (framerate_value);
|
val_fps = gst_value_get_fraction_range_min (framerate_value);
|
||||||
fail_unless (min_fps == 1.0 && max_fps == 100.0);
|
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");
|
width_value = gst_structure_get_value (s2, "width");
|
||||||
fail_unless (width_value != NULL);
|
fail_unless (width_value != NULL);
|
||||||
|
|
|
@ -435,6 +435,7 @@ GST_START_TEST (test_value_compare)
|
||||||
fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
|
fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
|
||||||
g_value_unset (&value1);
|
g_value_unset (&value1);
|
||||||
g_value_unset (&value2);
|
g_value_unset (&value2);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
@ -958,6 +959,280 @@ GST_START_TEST (test_value_subtract_double)
|
||||||
|
|
||||||
GST_END_TEST;
|
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)
|
GST_START_TEST (test_date)
|
||||||
{
|
{
|
||||||
GstStructure *s;
|
GstStructure *s;
|
||||||
|
@ -1017,6 +1292,59 @@ GST_START_TEST (test_date)
|
||||||
|
|
||||||
GST_END_TEST;
|
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 *
|
Suite *
|
||||||
gst_value_suite (void)
|
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_intersect);
|
||||||
tcase_add_test (tc_chain, test_value_subtract_int);
|
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_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_date);
|
||||||
|
tcase_add_test (tc_chain, test_fraction_range);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue