check/gst/gstvalue.c: Added subtract checks.

Original commit message from CVS:
* check/gst/gstvalue.c: (GST_START_TEST), (gst_value_suite):
Added subtract checks.

* docs/design/part-events.txt:
Some more docs about newsegment

* gst/gstbin.c: (gst_bin_change_state), (bin_bus_handler):
Fix FIXME

* gst/gstcaps.c: (gst_caps_to_string):
Add comments, cleanups.

* gst/gstelement.c: (gst_element_save_thyself):
cleanups

* gst/gstvalue.c: (gst_value_collect_int_range),
(gst_string_unwrap), (gst_value_union_int_int_range),
(gst_value_union_int_range_int_range),
(gst_value_intersect_int_int_range),
(gst_value_intersect_int_range_int_range),
(gst_value_intersect_double_double_range),
(gst_value_intersect_double_range_double_range),
(gst_value_intersect_list), (gst_value_subtract_int_int_range),
(gst_value_subtract_int_range_int),
(gst_value_subtract_double_range_double),
(gst_value_subtract_double_range_double_range),
(gst_value_subtract_from_list), (gst_value_subtract_list),
(gst_value_can_compare), (gst_value_compare_fraction):
Cleanups, add comments, remove unneeded asserts.
This commit is contained in:
Wim Taymans 2005-08-16 09:42:50 +00:00
parent b27244a943
commit 01ace6b592
8 changed files with 1078 additions and 64 deletions

View file

@ -1,3 +1,35 @@
2005-08-16 Wim Taymans <wim@fluendo.com>
* check/gst/gstvalue.c: (GST_START_TEST), (gst_value_suite):
Added subtract checks.
* docs/design/part-events.txt:
Some more docs about newsegment
* gst/gstbin.c: (gst_bin_change_state), (bin_bus_handler):
Fix FIXME
* gst/gstcaps.c: (gst_caps_to_string):
Add comments, cleanups.
* gst/gstelement.c: (gst_element_save_thyself):
cleanups
* gst/gstvalue.c: (gst_value_collect_int_range),
(gst_string_unwrap), (gst_value_union_int_int_range),
(gst_value_union_int_range_int_range),
(gst_value_intersect_int_int_range),
(gst_value_intersect_int_range_int_range),
(gst_value_intersect_double_double_range),
(gst_value_intersect_double_range_double_range),
(gst_value_intersect_list), (gst_value_subtract_int_int_range),
(gst_value_subtract_int_range_int),
(gst_value_subtract_double_range_double),
(gst_value_subtract_double_range_double_range),
(gst_value_subtract_from_list), (gst_value_subtract_list),
(gst_value_can_compare), (gst_value_compare_fraction):
Cleanups, add comments, remove unneeded asserts.
2005-08-15 Thomas Vander Stichele <thomas at apestaart dot org> 2005-08-15 Thomas Vander Stichele <thomas at apestaart dot org>
* tools/gst-launch.c: (event_loop): * tools/gst-launch.c: (event_loop):

View file

@ -411,9 +411,9 @@ GST_START_TEST (test_value_intersect)
g_value_init (&src1, G_TYPE_INT); g_value_init (&src1, G_TYPE_INT);
g_value_set_int (&src1, 10); g_value_set_int (&src1, 10);
g_value_init (&src2, G_TYPE_INT); g_value_init (&src2, G_TYPE_INT);
g_value_set_int (&src1, 20); g_value_set_int (&src2, 20);
ret = gst_value_intersect (&dest, &src1, &src2); ret = gst_value_intersect (&dest, &src1, &src2);
fail_unless (ret == 0); fail_unless (ret == FALSE);
g_value_unset (&src1); g_value_unset (&src1);
g_value_unset (&src2); g_value_unset (&src2);
@ -436,6 +436,489 @@ GST_START_TEST (test_value_intersect)
GST_END_TEST; GST_END_TEST;
GST_START_TEST (test_value_subtract_int)
{
GValue dest = { 0 };
GValue src1 = { 0 };
GValue src2 = { 0 };
const GValue *tmp;
gboolean ret;
/* int <-> int
*/
g_value_init (&src1, G_TYPE_INT);
g_value_set_int (&src1, 10);
g_value_init (&src2, G_TYPE_INT);
g_value_set_int (&src2, 20);
/* 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);
/* int <-> int_range
*/
/* would yield an empty set */
g_value_init (&src1, G_TYPE_INT);
g_value_set_int (&src1, 10);
g_value_init (&src2, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src2, 0, 20);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == FALSE);
/* and the other way around, should create a list of two ranges. */
ret = gst_value_subtract (&dest, &src2, &src1);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_LIST (&dest) == TRUE);
tmp = gst_value_list_get_value (&dest, 0);
fail_unless (GST_VALUE_HOLDS_INT_RANGE (tmp) == TRUE);
fail_unless (gst_value_get_int_range_min (tmp) == 0);
fail_unless (gst_value_get_int_range_max (tmp) == 9);
tmp = gst_value_list_get_value (&dest, 1);
fail_unless (GST_VALUE_HOLDS_INT_RANGE (tmp) == TRUE);
fail_unless (gst_value_get_int_range_min (tmp) == 11);
fail_unless (gst_value_get_int_range_max (tmp) == 20);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* border case 1, empty set */
g_value_init (&src1, G_TYPE_INT);
g_value_set_int (&src1, 10);
g_value_init (&src2, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src2, 10, 20);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == FALSE);
/* and the other way around, should create a new range. */
ret = gst_value_subtract (&dest, &src2, &src1);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_INT_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_int_range_min (&dest) == 11);
fail_unless (gst_value_get_int_range_max (&dest) == 20);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* border case 2, empty set */
g_value_init (&src1, G_TYPE_INT);
g_value_set_int (&src1, 20);
g_value_init (&src2, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src2, 10, 20);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == FALSE);
/* and the other way around, should create a new range. */
ret = gst_value_subtract (&dest, &src2, &src1);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_INT_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_int_range_min (&dest) == 10);
fail_unless (gst_value_get_int_range_max (&dest) == 19);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* case 3, valid set */
g_value_init (&src1, G_TYPE_INT);
g_value_set_int (&src1, 0);
g_value_init (&src2, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src2, 10, 20);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == TRUE);
fail_unless (G_VALUE_HOLDS_INT (&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_INT_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_int_range_min (&dest) == 10);
fail_unless (gst_value_get_int_range_max (&dest) == 20);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* int_range <-> int_range
*/
/* same range, empty set */
g_value_init (&src1, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src1, 10, 20);
g_value_init (&src2, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src2, 10, 20);
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_INT_RANGE);
gst_value_set_int_range (&src1, 10, 20);
g_value_init (&src2, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src2, 30, 40);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_INT_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_int_range_min (&dest) == 10);
fail_unless (gst_value_get_int_range_max (&dest) == 20);
g_value_unset (&dest);
/* the other way */
ret = gst_value_subtract (&dest, &src2, &src1);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_INT_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_int_range_min (&dest) == 30);
fail_unless (gst_value_get_int_range_max (&dest) == 40);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* completely overlapping ranges */
g_value_init (&src1, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src1, 10, 20);
g_value_init (&src2, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src2, 10, 30);
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_INT_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_int_range_min (&dest) == 21);
fail_unless (gst_value_get_int_range_max (&dest) == 30);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* partially overlapping ranges */
g_value_init (&src1, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src1, 10, 20);
g_value_init (&src2, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src2, 15, 30);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_INT_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_int_range_min (&dest) == 10);
fail_unless (gst_value_get_int_range_max (&dest) == 14);
g_value_unset (&dest);
/* the other way */
ret = gst_value_subtract (&dest, &src2, &src1);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_INT_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_int_range_min (&dest) == 21);
fail_unless (gst_value_get_int_range_max (&dest) == 30);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* create a hole { int_range, int_range } */
g_value_init (&src1, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src1, 10, 30);
g_value_init (&src2, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src2, 15, 20);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_LIST (&dest) == TRUE);
tmp = gst_value_list_get_value (&dest, 0);
fail_unless (GST_VALUE_HOLDS_INT_RANGE (tmp) == TRUE);
fail_unless (gst_value_get_int_range_min (tmp) == 10);
fail_unless (gst_value_get_int_range_max (tmp) == 14);
tmp = gst_value_list_get_value (&dest, 1);
fail_unless (GST_VALUE_HOLDS_INT_RANGE (tmp) == TRUE);
fail_unless (gst_value_get_int_range_min (tmp) == 21);
fail_unless (gst_value_get_int_range_max (tmp) == 30);
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);
/* create a hole, { int, int } */
g_value_init (&src1, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src1, 10, 30);
g_value_init (&src2, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src2, 11, 29);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_LIST (&dest) == TRUE);
tmp = gst_value_list_get_value (&dest, 0);
fail_unless (G_VALUE_HOLDS_INT (tmp) == TRUE);
fail_unless (g_value_get_int (tmp) == 10);
tmp = gst_value_list_get_value (&dest, 1);
fail_unless (G_VALUE_HOLDS_INT (tmp) == TRUE);
fail_unless (g_value_get_int (tmp) == 30);
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);
/* create a hole, { int, int_range } */
g_value_init (&src1, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src1, 10, 30);
g_value_init (&src2, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src2, 11, 28);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_LIST (&dest) == TRUE);
tmp = gst_value_list_get_value (&dest, 0);
fail_unless (G_VALUE_HOLDS_INT (tmp) == TRUE);
fail_unless (g_value_get_int (tmp) == 10);
tmp = gst_value_list_get_value (&dest, 1);
fail_unless (GST_VALUE_HOLDS_INT_RANGE (tmp) == TRUE);
fail_unless (gst_value_get_int_range_min (tmp) == 29);
fail_unless (gst_value_get_int_range_max (tmp) == 30);
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);
/* create a hole, { int_range, int } */
g_value_init (&src1, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src1, 10, 30);
g_value_init (&src2, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src2, 12, 29);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_LIST (&dest) == TRUE);
tmp = gst_value_list_get_value (&dest, 0);
fail_unless (GST_VALUE_HOLDS_INT_RANGE (tmp) == TRUE);
fail_unless (gst_value_get_int_range_min (tmp) == 10);
fail_unless (gst_value_get_int_range_max (tmp) == 11);
tmp = gst_value_list_get_value (&dest, 1);
fail_unless (G_VALUE_HOLDS_INT (tmp) == TRUE);
fail_unless (g_value_get_int (tmp) == 30);
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);
}
GST_END_TEST;
GST_START_TEST (test_value_subtract_double)
{
GValue dest = { 0 };
GValue src1 = { 0 };
GValue src2 = { 0 };
const GValue *tmp;
gboolean ret;
/* double <-> double
*/
g_value_init (&src1, G_TYPE_DOUBLE);
g_value_set_double (&src1, 10.0);
g_value_init (&src2, G_TYPE_DOUBLE);
g_value_set_double (&src2, 20.0);
/* 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);
/* double <-> double_range
*/
/* would yield an empty set */
g_value_init (&src1, G_TYPE_DOUBLE);
g_value_set_double (&src1, 10.0);
g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
gst_value_set_double_range (&src2, 0.0, 20.0);
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_DOUBLE_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_double_range_min (&dest) == 0.0);
fail_unless (gst_value_get_double_range_max (&dest) == 20.0);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* border case 1, empty set */
g_value_init (&src1, G_TYPE_DOUBLE);
g_value_set_double (&src1, 10.0);
g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
gst_value_set_double_range (&src2, 10.0, 20.0);
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_DOUBLE_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_double_range_min (&dest) == 10.0);
fail_unless (gst_value_get_double_range_max (&dest) == 20.0);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* border case 2, empty set */
g_value_init (&src1, G_TYPE_DOUBLE);
g_value_set_double (&src1, 20.0);
g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
gst_value_set_double_range (&src2, 10.0, 20.0);
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_DOUBLE_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_double_range_min (&dest) == 10.0);
fail_unless (gst_value_get_double_range_max (&dest) == 20.0);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* case 3, valid set */
g_value_init (&src1, G_TYPE_DOUBLE);
g_value_set_double (&src1, 0.0);
g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
gst_value_set_double_range (&src2, 10.0, 20.0);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == TRUE);
fail_unless (G_VALUE_HOLDS_DOUBLE (&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_DOUBLE_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_double_range_min (&dest) == 10.0);
fail_unless (gst_value_get_double_range_max (&dest) == 20.0);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* double_range <-> double_range
*/
/* same range, empty set */
g_value_init (&src1, GST_TYPE_DOUBLE_RANGE);
gst_value_set_double_range (&src1, 10.0, 20.0);
g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
gst_value_set_double_range (&src2, 10.0, 20.0);
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_DOUBLE_RANGE);
gst_value_set_double_range (&src1, 10.0, 20.0);
g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
gst_value_set_double_range (&src2, 30.0, 40.0);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_DOUBLE_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_double_range_min (&dest) == 10.0);
fail_unless (gst_value_get_double_range_max (&dest) == 20.0);
g_value_unset (&dest);
/* the other way */
ret = gst_value_subtract (&dest, &src2, &src1);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_DOUBLE_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_double_range_min (&dest) == 30.0);
fail_unless (gst_value_get_double_range_max (&dest) == 40.0);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* completely overlapping ranges */
g_value_init (&src1, GST_TYPE_DOUBLE_RANGE);
gst_value_set_double_range (&src1, 10.0, 20.0);
g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
gst_value_set_double_range (&src2, 10.0, 30.0);
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_DOUBLE_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_double_range_min (&dest) == 20.0);
fail_unless (gst_value_get_double_range_max (&dest) == 30.0);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* partially overlapping ranges */
g_value_init (&src1, GST_TYPE_DOUBLE_RANGE);
gst_value_set_double_range (&src1, 10.0, 20.0);
g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
gst_value_set_double_range (&src2, 15.0, 30.0);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_DOUBLE_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_double_range_min (&dest) == 10.0);
fail_unless (gst_value_get_double_range_max (&dest) == 15.0);
g_value_unset (&dest);
/* the other way */
ret = gst_value_subtract (&dest, &src2, &src1);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_DOUBLE_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_double_range_min (&dest) == 20.0);
fail_unless (gst_value_get_double_range_max (&dest) == 30.0);
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_DOUBLE_RANGE);
gst_value_set_double_range (&src1, 10.0, 30.0);
g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
gst_value_set_double_range (&src2, 15.0, 20.0);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_LIST (&dest) == TRUE);
tmp = gst_value_list_get_value (&dest, 0);
fail_unless (GST_VALUE_HOLDS_DOUBLE_RANGE (tmp) == TRUE);
fail_unless (gst_value_get_double_range_min (tmp) == 10.0);
fail_unless (gst_value_get_double_range_max (tmp) == 15.0);
tmp = gst_value_list_get_value (&dest, 1);
fail_unless (GST_VALUE_HOLDS_DOUBLE_RANGE (tmp) == TRUE);
fail_unless (gst_value_get_double_range_min (tmp) == 20.0);
fail_unless (gst_value_get_double_range_max (tmp) == 30.0);
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);
}
GST_END_TEST;
Suite * Suite *
gst_value_suite (void) gst_value_suite (void)
{ {
@ -453,6 +936,9 @@ gst_value_suite (void)
tcase_add_test (tc_chain, test_deserialize_string); tcase_add_test (tc_chain, test_deserialize_string);
tcase_add_test (tc_chain, test_value_compare); tcase_add_test (tc_chain, test_value_compare);
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_double);
return s; return s;
} }

View file

@ -122,6 +122,11 @@ Buffers should be clipped within the range indicated by the newsegment event
start and stop values. Sinks are allowed to drop buffers with timestamps out start and stop values. Sinks are allowed to drop buffers with timestamps out
of the indicated newsegment range. of the indicated newsegment range.
If a newsegment arrives at an element not preceeded by a flush event, the
streamtime of the pipeline will not be reset to 0 so any element that syncs
to the clock must use the stop times of the previous newsegment events to
make the buffer timestamps increasing.
SEEK SEEK
---- ----

View file

@ -1175,9 +1175,9 @@ restart:
GST_LOCK (bin); GST_LOCK (bin);
if (G_UNLIKELY (children_cookie != bin->children_cookie)) { if (G_UNLIKELY (children_cookie != bin->children_cookie)) {
/* FIXME: we reffed some children already, are we leaking refcounts
* in that case ? */
GST_INFO_OBJECT (bin, "bin->children_cookie changed, restarting"); GST_INFO_OBJECT (bin, "bin->children_cookie changed, restarting");
/* restart will unref the children in the queues so that we don't
* leak refcounts. */
goto restart; goto restart;
} }
children = g_list_next (children); children = g_list_next (children);
@ -1439,14 +1439,12 @@ gst_bin_send_event (GstElement * element, GstEvent * event)
return res; return res;
} }
/* FIXME, make me threadsafe */
static GstBusSyncReply static GstBusSyncReply
bin_bus_handler (GstBus * bus, GstMessage * message, GstBin * bin) bin_bus_handler (GstBus * bus, GstMessage * message, GstBin * bin)
{ {
GST_DEBUG_OBJECT (bin, "[msg %p] handling child message of type %d", GST_DEBUG_OBJECT (bin, "[msg %p] handling child message of type %d",
message, GST_MESSAGE_TYPE (message)); message, GST_MESSAGE_TYPE (message));
/* we don't want messages from the streaming thread while we're doing the
* state change. We do want them from the state change functions. */
switch (GST_MESSAGE_TYPE (message)) { switch (GST_MESSAGE_TYPE (message)) {
case GST_MESSAGE_EOS:{ case GST_MESSAGE_EOS:{
gchar *name = gst_object_get_name (GST_MESSAGE_SRC (message)); gchar *name = gst_object_get_name (GST_MESSAGE_SRC (message));
@ -1454,10 +1452,12 @@ bin_bus_handler (GstBus * bus, GstMessage * message, GstBin * bin)
GST_DEBUG_OBJECT (bin, "got EOS message from %s", name); GST_DEBUG_OBJECT (bin, "got EOS message from %s", name);
g_free (name); g_free (name);
/* collect all eos messages from the children */
GST_LOCK (bin->child_bus); GST_LOCK (bin->child_bus);
bin->eosed = g_list_prepend (bin->eosed, GST_MESSAGE_SRC (message)); bin->eosed = g_list_prepend (bin->eosed, GST_MESSAGE_SRC (message));
GST_UNLOCK (bin->child_bus); GST_UNLOCK (bin->child_bus);
/* if we are completely EOS, we forward an EOS message */
if (is_eos (bin)) { if (is_eos (bin)) {
GST_DEBUG_OBJECT (bin, "all sinks posted EOS"); GST_DEBUG_OBJECT (bin, "all sinks posted EOS");
gst_element_post_message (GST_ELEMENT (bin), gst_element_post_message (GST_ELEMENT (bin),

View file

@ -1525,9 +1525,7 @@ gchar *
gst_caps_to_string (const GstCaps * caps) gst_caps_to_string (const GstCaps * caps)
{ {
int i; int i;
GstStructure *structure;
GString *s; GString *s;
char *sstr;
/* NOTE: This function is potentially called by the debug system, /* NOTE: This function is potentially called by the debug system,
* so any calls to gst_log() (and GST_DEBUG(), GST_LOG(), etc.) * so any calls to gst_log() (and GST_DEBUG(), GST_LOG(), etc.)
@ -1535,8 +1533,6 @@ gst_caps_to_string (const GstCaps * caps)
* called by gst_caps_to_string. In particular, calls should * called by gst_caps_to_string. In particular, calls should
* not use the GST_PTR_FORMAT extension. */ * not use the GST_PTR_FORMAT extension. */
/* FIXME does this leak? */
if (caps == NULL) { if (caps == NULL) {
return g_strdup ("NULL"); return g_strdup ("NULL");
} }
@ -1546,16 +1542,16 @@ gst_caps_to_string (const GstCaps * caps)
if (gst_caps_is_empty (caps)) { if (gst_caps_is_empty (caps)) {
return g_strdup ("EMPTY"); return g_strdup ("EMPTY");
} }
s = g_string_new (""); s = g_string_new ("");
structure = gst_caps_get_structure (caps, 0); for (i = 0; i < caps->structs->len; i++) {
sstr = gst_structure_to_string (structure); GstStructure *structure;
g_string_append (s, sstr); char *sstr;
g_free (sstr);
if (i > 0)
g_string_append (s, "; ");
for (i = 1; i < caps->structs->len; i++) {
structure = gst_caps_get_structure (caps, i); structure = gst_caps_get_structure (caps, i);
g_string_append (s, "; ");
sstr = gst_structure_to_string (structure); sstr = gst_structure_to_string (structure);
g_string_append (s, sstr); g_string_append (s, sstr);
g_free (sstr); g_free (sstr);

View file

@ -2122,10 +2122,6 @@ gst_element_save_thyself (GstObject * object, xmlNodePtr parent)
(xmlChar *) GST_PLUGIN_FEATURE (factory)->name); (xmlChar *) GST_PLUGIN_FEATURE (factory)->name);
} }
/* FIXME: what is this? */
/* if (element->manager) */
/* xmlNewChild(parent, NULL, "manager", GST_ELEMENT_NAME(element->manager)); */
/* params */ /* params */
specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (object), &nspecs); specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (object), &nspecs);

View file

@ -578,7 +578,6 @@ static gchar *
gst_value_collect_int_range (GValue * value, guint n_collect_values, gst_value_collect_int_range (GValue * value, guint n_collect_values,
GTypeCValue * collect_values, guint collect_flags) GTypeCValue * collect_values, guint collect_flags)
{ {
/* FIXME */
value->data[0].v_int = collect_values[0].v_int; value->data[0].v_int = collect_values[0].v_int;
value->data[1].v_int = collect_values[1].v_int; value->data[1].v_int = collect_values[1].v_int;
@ -1347,8 +1346,17 @@ gst_string_wrap (const char *s)
return d; return d;
} }
/* FIXME: wouldn't it be nice if this function /*
* were documented ? Alphabet spaghetti is easier to digest. * This function takes a string delimited with double quotes (")
* and unescapes any \xxx octal numbers.
*
* If sequences of \y are found where y is not in the range of
* 0->3, y is copied unescaped.
*
* If \xyy is found where x is an octal number but y is not, an
* error is encountered and NULL is returned.
*
* the input string must be \0 terminated.
*/ */
static char * static char *
gst_string_unwrap (const gchar * s) gst_string_unwrap (const gchar * s)
@ -1356,44 +1364,65 @@ gst_string_unwrap (const gchar * s)
gchar *ret; gchar *ret;
gchar *read, *write; gchar *read, *write;
/* NULL string returns NULL */
if (s == NULL) if (s == NULL)
return NULL; return NULL;
/* strings not starting with " are invalid */
if (*s != '"')
return NULL;
/* make copy of original string to hold the result. This
* string will always be smaller than the original */
ret = g_strdup (s); ret = g_strdup (s);
read = ret; read = ret;
write = ret; write = ret;
if (*read++ != '"') /* need to move to the next position as we parsed the " */
goto beach; read++;
while (*read) { while (*read) {
if (GST_ASCII_IS_STRING (*read)) { if (GST_ASCII_IS_STRING (*read)) {
/* normal chars are just copied */
*write++ = *read++; *write++ = *read++;
} else if (*read == '"') { } else if (*read == '"') {
/* quote marks end of string */
break; break;
} else if (*read == '\\') { } else if (*read == '\\') {
/* got an escape char, move to next position to read a tripplet
* of octal numbers */
read++; read++;
if (*read >= '0' && *read <= '7') { /* is the next char a possible first octal number? */
if (*read >= '0' && *read <= '3') {
/* parse other 2 numbers, if one of them is not in the range of
* an octal number, we error. We also catch the case where a zero
* byte is found here. */
if (read[1] < '0' || read[1] > '7' || read[2] < '0' || read[2] > '7') if (read[1] < '0' || read[1] > '7' || read[2] < '0' || read[2] > '7')
goto beach; goto beach;
/* now convert the octal number to a byte again. */
*write++ = ((read[0] - '0') << 6) + *write++ = ((read[0] - '0') << 6) +
((read[1] - '0') << 3) + (read[2] - '0'); ((read[1] - '0') << 3) + (read[2] - '0');
read += 3; read += 3;
} else { } else {
/* if we run into a \0 here, we definately won't get a quote later */ /* if we run into a \0 here, we definately won't get a quote later */
if (*read == 0) if (*read == 0)
goto beach; goto beach;
/* else copy \X sequence */
*write++ = *read++; *write++ = *read++;
} }
} else { } else {
/* weird character, error */
goto beach; goto beach;
} }
} }
/* if the string is not ending in " and zero terminated, we error */
if (*read != '"' || read[1] != '\0') if (*read != '"' || read[1] != '\0')
goto beach; goto beach;
/* null terminate result string and return */
*write++ = '\0'; *write++ = '\0';
return ret; return ret;
@ -1597,15 +1626,11 @@ static gboolean
gst_value_union_int_int_range (GValue * dest, const GValue * src1, gst_value_union_int_int_range (GValue * dest, const GValue * src1,
const GValue * src2) const GValue * src2)
{ {
g_return_val_if_fail (G_VALUE_TYPE (src1) == G_TYPE_INT, FALSE);
g_return_val_if_fail (G_VALUE_TYPE (src2) == GST_TYPE_INT_RANGE, FALSE);
if (src2->data[0].v_int <= src1->data[0].v_int && if (src2->data[0].v_int <= src1->data[0].v_int &&
src2->data[1].v_int >= src1->data[0].v_int) { src2->data[1].v_int >= src1->data[0].v_int) {
gst_value_init_and_copy (dest, src2); gst_value_init_and_copy (dest, src2);
return TRUE; return TRUE;
} }
return FALSE; return FALSE;
} }
@ -1616,9 +1641,6 @@ gst_value_union_int_range_int_range (GValue * dest, const GValue * src1,
int min; int min;
int max; int max;
g_return_val_if_fail (G_VALUE_TYPE (src1) == GST_TYPE_INT_RANGE, FALSE);
g_return_val_if_fail (G_VALUE_TYPE (src2) == GST_TYPE_INT_RANGE, FALSE);
min = MAX (src1->data[0].v_int, src2->data[0].v_int); min = MAX (src1->data[0].v_int, src2->data[0].v_int);
max = MIN (src1->data[1].v_int, src2->data[1].v_int); max = MIN (src1->data[1].v_int, src2->data[1].v_int);
@ -1641,9 +1663,6 @@ static gboolean
gst_value_intersect_int_int_range (GValue * dest, const GValue * src1, gst_value_intersect_int_int_range (GValue * dest, const GValue * src1,
const GValue * src2) const GValue * src2)
{ {
g_return_val_if_fail (G_VALUE_TYPE (src1) == G_TYPE_INT, FALSE);
g_return_val_if_fail (G_VALUE_TYPE (src2) == GST_TYPE_INT_RANGE, FALSE);
if (src2->data[0].v_int <= src1->data[0].v_int && if (src2->data[0].v_int <= src1->data[0].v_int &&
src2->data[1].v_int >= src1->data[0].v_int) { src2->data[1].v_int >= src1->data[0].v_int) {
gst_value_init_and_copy (dest, src1); gst_value_init_and_copy (dest, src1);
@ -1660,9 +1679,6 @@ gst_value_intersect_int_range_int_range (GValue * dest, const GValue * src1,
int min; int min;
int max; int max;
g_return_val_if_fail (G_VALUE_TYPE (src1) == GST_TYPE_INT_RANGE, FALSE);
g_return_val_if_fail (G_VALUE_TYPE (src2) == GST_TYPE_INT_RANGE, FALSE);
min = MAX (src1->data[0].v_int, src2->data[0].v_int); min = MAX (src1->data[0].v_int, src2->data[0].v_int);
max = MIN (src1->data[1].v_int, src2->data[1].v_int); max = MIN (src1->data[1].v_int, src2->data[1].v_int);
@ -1684,9 +1700,6 @@ static gboolean
gst_value_intersect_double_double_range (GValue * dest, const GValue * src1, gst_value_intersect_double_double_range (GValue * dest, const GValue * src1,
const GValue * src2) const GValue * src2)
{ {
g_return_val_if_fail (G_VALUE_TYPE (src1) == G_TYPE_DOUBLE, FALSE);
g_return_val_if_fail (G_VALUE_TYPE (src2) == GST_TYPE_DOUBLE_RANGE, FALSE);
if (src2->data[0].v_double <= src1->data[0].v_double && if (src2->data[0].v_double <= src1->data[0].v_double &&
src2->data[1].v_double >= src1->data[0].v_double) { src2->data[1].v_double >= src1->data[0].v_double) {
gst_value_init_and_copy (dest, src1); gst_value_init_and_copy (dest, src1);
@ -1703,9 +1716,6 @@ gst_value_intersect_double_range_double_range (GValue * dest,
double min; double min;
double max; double max;
g_return_val_if_fail (G_VALUE_TYPE (src1) == GST_TYPE_DOUBLE_RANGE, FALSE);
g_return_val_if_fail (G_VALUE_TYPE (src2) == GST_TYPE_DOUBLE_RANGE, FALSE);
min = MAX (src1->data[0].v_double, src2->data[0].v_double); min = MAX (src1->data[0].v_double, src2->data[0].v_double);
max = MIN (src1->data[1].v_double, src2->data[1].v_double); max = MIN (src1->data[1].v_double, src2->data[1].v_double);
@ -1731,8 +1741,6 @@ gst_value_intersect_list (GValue * dest, const GValue * value1,
GValue intersection = { 0, }; GValue intersection = { 0, };
gboolean ret = FALSE; gboolean ret = FALSE;
g_return_val_if_fail (GST_VALUE_HOLDS_LIST (value1), FALSE);
size = gst_value_list_get_size (value1); size = gst_value_list_get_size (value1);
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
const GValue *cur = gst_value_list_get_value (value1, i); const GValue *cur = gst_value_list_get_value (value1, i);
@ -1797,13 +1805,18 @@ gst_value_subtract_int_int_range (GValue * dest, const GValue * minuend,
int max = gst_value_get_int_range_max (subtrahend); int max = gst_value_get_int_range_max (subtrahend);
int val = g_value_get_int (minuend); int val = g_value_get_int (minuend);
/* subtracting a range from an int only works if the int is not in the
* range */
if (val < min || val > max) { if (val < min || val > max) {
/* and the result is the int */
gst_value_init_and_copy (dest, minuend); gst_value_init_and_copy (dest, minuend);
return TRUE; return TRUE;
} }
return FALSE; return FALSE;
} }
/* creates a new int range based on input values.
*/
static gboolean static gboolean
gst_value_create_new_range (GValue * dest, int min1, int max1, int min2, gst_value_create_new_range (GValue * dest, int min1, int max1, int min2,
int max2) int max2)
@ -1858,14 +1871,17 @@ gst_value_subtract_int_range_int (GValue * dest, const GValue * minuend,
g_return_val_if_fail (min < max, FALSE); g_return_val_if_fail (min < max, FALSE);
/* value is outside of the range, return range unchanged */
if (val < min || val > max) { if (val < min || val > max) {
gst_value_init_and_copy (dest, minuend); gst_value_init_and_copy (dest, minuend);
return TRUE; return TRUE;
} else { } else {
/* max must be MAXINT too as val <= max */
if (val == G_MAXINT) { if (val == G_MAXINT) {
max--; max--;
val--; val--;
} }
/* min must be MININT too as val >= max */
if (val == G_MININT) { if (val == G_MININT) {
min++; min++;
val++; val++;
@ -1915,7 +1931,8 @@ static gboolean
gst_value_subtract_double_range_double (GValue * dest, const GValue * minuend, gst_value_subtract_double_range_double (GValue * dest, const GValue * minuend,
const GValue * subtrahend) const GValue * subtrahend)
{ {
/* FIXME! */ /* since we don't have open ranges, we cannot create a hole in
* a double range. We return the original range */
gst_value_init_and_copy (dest, minuend); gst_value_init_and_copy (dest, minuend);
return TRUE; return TRUE;
} }
@ -1924,7 +1941,7 @@ static gboolean
gst_value_subtract_double_range_double_range (GValue * dest, gst_value_subtract_double_range_double_range (GValue * dest,
const GValue * minuend, const GValue * subtrahend) const GValue * minuend, const GValue * subtrahend)
{ {
/* FIXME! */ /* since we don't have open ranges, we have to approximate */
/* done like with ints */ /* done like with ints */
double min1 = gst_value_get_double_range_min (minuend); double min1 = gst_value_get_double_range_min (minuend);
double max2 = gst_value_get_double_range_max (minuend); double max2 = gst_value_get_double_range_max (minuend);
@ -1972,8 +1989,6 @@ gst_value_subtract_from_list (GValue * dest, const GValue * minuend,
GValue subtraction = { 0, }; GValue subtraction = { 0, };
gboolean ret = FALSE; gboolean ret = FALSE;
g_return_val_if_fail (GST_VALUE_HOLDS_LIST (minuend), FALSE);
size = gst_value_list_get_size (minuend); size = gst_value_list_get_size (minuend);
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
const GValue *cur = gst_value_list_get_value (minuend, i); const GValue *cur = gst_value_list_get_value (minuend, i);
@ -2014,8 +2029,6 @@ gst_value_subtract_list (GValue * dest, const GValue * minuend,
GValue data[2] = { {0,}, {0,} }; GValue data[2] = { {0,}, {0,} };
GValue *subtraction = &data[0], *result = &data[1]; GValue *subtraction = &data[0], *result = &data[1];
g_return_val_if_fail (GST_VALUE_HOLDS_LIST (subtrahend), FALSE);
gst_value_init_and_copy (result, minuend); gst_value_init_and_copy (result, minuend);
size = gst_value_list_get_size (subtrahend); size = gst_value_list_get_size (subtrahend);
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
@ -2059,6 +2072,7 @@ gst_value_can_compare (const GValue * value1, const GValue * value2)
if (G_VALUE_TYPE (value1) != G_VALUE_TYPE (value2)) if (G_VALUE_TYPE (value1) != G_VALUE_TYPE (value2))
return FALSE; return FALSE;
for (i = 0; i < gst_value_table->len; i++) { for (i = 0; i < gst_value_table->len; i++) {
table = &g_array_index (gst_value_table, GstValueTable, i); table = &g_array_index (gst_value_table, GstValueTable, i);
if (g_type_is_a (G_VALUE_TYPE (value1), table->type) && table->compare) if (g_type_is_a (G_VALUE_TYPE (value1), table->type) && table->compare)
@ -2924,14 +2938,11 @@ gst_value_transform_fraction_double (const GValue * src_value,
static int static int
gst_value_compare_fraction (const GValue * value1, const GValue * value2) gst_value_compare_fraction (const GValue * value1, const GValue * value2)
{ {
/* FIXME: maybe we should make this more mathematically correct instead
* of approximating with gdoubles */
gint n1, n2; gint n1, n2;
gint d1, d2; gint d1, d2;
gdouble new_num_1; gint64 new_num_1;
gdouble new_num_2; gint64 new_num_2;
n1 = value1->data[0].v_int; n1 = value1->data[0].v_int;
n2 = value2->data[0].v_int; n2 = value2->data[0].v_int;
@ -2942,12 +2953,14 @@ gst_value_compare_fraction (const GValue * value1, const GValue * value2)
if (n1 == n2 && d1 == d2) if (n1 == n2 && d1 == d2)
return GST_VALUE_EQUAL; return GST_VALUE_EQUAL;
new_num_1 = n1 * d2; /* extend to 64 bits */
new_num_2 = n2 * d1; new_num_1 = ((gint64) n1) * d2;
new_num_2 = ((gint64) n2) * d1;
if (new_num_1 < new_num_2) if (new_num_1 < new_num_2)
return GST_VALUE_LESS_THAN; return GST_VALUE_LESS_THAN;
if (new_num_1 > new_num_2) if (new_num_1 > new_num_2)
return GST_VALUE_GREATER_THAN; return GST_VALUE_GREATER_THAN;
g_assert_not_reached (); g_assert_not_reached ();
return GST_VALUE_UNORDERED; return GST_VALUE_UNORDERED;
} }

View file

@ -411,9 +411,9 @@ GST_START_TEST (test_value_intersect)
g_value_init (&src1, G_TYPE_INT); g_value_init (&src1, G_TYPE_INT);
g_value_set_int (&src1, 10); g_value_set_int (&src1, 10);
g_value_init (&src2, G_TYPE_INT); g_value_init (&src2, G_TYPE_INT);
g_value_set_int (&src1, 20); g_value_set_int (&src2, 20);
ret = gst_value_intersect (&dest, &src1, &src2); ret = gst_value_intersect (&dest, &src1, &src2);
fail_unless (ret == 0); fail_unless (ret == FALSE);
g_value_unset (&src1); g_value_unset (&src1);
g_value_unset (&src2); g_value_unset (&src2);
@ -436,6 +436,489 @@ GST_START_TEST (test_value_intersect)
GST_END_TEST; GST_END_TEST;
GST_START_TEST (test_value_subtract_int)
{
GValue dest = { 0 };
GValue src1 = { 0 };
GValue src2 = { 0 };
const GValue *tmp;
gboolean ret;
/* int <-> int
*/
g_value_init (&src1, G_TYPE_INT);
g_value_set_int (&src1, 10);
g_value_init (&src2, G_TYPE_INT);
g_value_set_int (&src2, 20);
/* 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);
/* int <-> int_range
*/
/* would yield an empty set */
g_value_init (&src1, G_TYPE_INT);
g_value_set_int (&src1, 10);
g_value_init (&src2, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src2, 0, 20);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == FALSE);
/* and the other way around, should create a list of two ranges. */
ret = gst_value_subtract (&dest, &src2, &src1);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_LIST (&dest) == TRUE);
tmp = gst_value_list_get_value (&dest, 0);
fail_unless (GST_VALUE_HOLDS_INT_RANGE (tmp) == TRUE);
fail_unless (gst_value_get_int_range_min (tmp) == 0);
fail_unless (gst_value_get_int_range_max (tmp) == 9);
tmp = gst_value_list_get_value (&dest, 1);
fail_unless (GST_VALUE_HOLDS_INT_RANGE (tmp) == TRUE);
fail_unless (gst_value_get_int_range_min (tmp) == 11);
fail_unless (gst_value_get_int_range_max (tmp) == 20);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* border case 1, empty set */
g_value_init (&src1, G_TYPE_INT);
g_value_set_int (&src1, 10);
g_value_init (&src2, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src2, 10, 20);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == FALSE);
/* and the other way around, should create a new range. */
ret = gst_value_subtract (&dest, &src2, &src1);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_INT_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_int_range_min (&dest) == 11);
fail_unless (gst_value_get_int_range_max (&dest) == 20);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* border case 2, empty set */
g_value_init (&src1, G_TYPE_INT);
g_value_set_int (&src1, 20);
g_value_init (&src2, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src2, 10, 20);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == FALSE);
/* and the other way around, should create a new range. */
ret = gst_value_subtract (&dest, &src2, &src1);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_INT_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_int_range_min (&dest) == 10);
fail_unless (gst_value_get_int_range_max (&dest) == 19);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* case 3, valid set */
g_value_init (&src1, G_TYPE_INT);
g_value_set_int (&src1, 0);
g_value_init (&src2, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src2, 10, 20);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == TRUE);
fail_unless (G_VALUE_HOLDS_INT (&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_INT_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_int_range_min (&dest) == 10);
fail_unless (gst_value_get_int_range_max (&dest) == 20);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* int_range <-> int_range
*/
/* same range, empty set */
g_value_init (&src1, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src1, 10, 20);
g_value_init (&src2, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src2, 10, 20);
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_INT_RANGE);
gst_value_set_int_range (&src1, 10, 20);
g_value_init (&src2, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src2, 30, 40);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_INT_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_int_range_min (&dest) == 10);
fail_unless (gst_value_get_int_range_max (&dest) == 20);
g_value_unset (&dest);
/* the other way */
ret = gst_value_subtract (&dest, &src2, &src1);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_INT_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_int_range_min (&dest) == 30);
fail_unless (gst_value_get_int_range_max (&dest) == 40);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* completely overlapping ranges */
g_value_init (&src1, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src1, 10, 20);
g_value_init (&src2, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src2, 10, 30);
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_INT_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_int_range_min (&dest) == 21);
fail_unless (gst_value_get_int_range_max (&dest) == 30);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* partially overlapping ranges */
g_value_init (&src1, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src1, 10, 20);
g_value_init (&src2, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src2, 15, 30);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_INT_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_int_range_min (&dest) == 10);
fail_unless (gst_value_get_int_range_max (&dest) == 14);
g_value_unset (&dest);
/* the other way */
ret = gst_value_subtract (&dest, &src2, &src1);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_INT_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_int_range_min (&dest) == 21);
fail_unless (gst_value_get_int_range_max (&dest) == 30);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* create a hole { int_range, int_range } */
g_value_init (&src1, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src1, 10, 30);
g_value_init (&src2, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src2, 15, 20);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_LIST (&dest) == TRUE);
tmp = gst_value_list_get_value (&dest, 0);
fail_unless (GST_VALUE_HOLDS_INT_RANGE (tmp) == TRUE);
fail_unless (gst_value_get_int_range_min (tmp) == 10);
fail_unless (gst_value_get_int_range_max (tmp) == 14);
tmp = gst_value_list_get_value (&dest, 1);
fail_unless (GST_VALUE_HOLDS_INT_RANGE (tmp) == TRUE);
fail_unless (gst_value_get_int_range_min (tmp) == 21);
fail_unless (gst_value_get_int_range_max (tmp) == 30);
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);
/* create a hole, { int, int } */
g_value_init (&src1, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src1, 10, 30);
g_value_init (&src2, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src2, 11, 29);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_LIST (&dest) == TRUE);
tmp = gst_value_list_get_value (&dest, 0);
fail_unless (G_VALUE_HOLDS_INT (tmp) == TRUE);
fail_unless (g_value_get_int (tmp) == 10);
tmp = gst_value_list_get_value (&dest, 1);
fail_unless (G_VALUE_HOLDS_INT (tmp) == TRUE);
fail_unless (g_value_get_int (tmp) == 30);
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);
/* create a hole, { int, int_range } */
g_value_init (&src1, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src1, 10, 30);
g_value_init (&src2, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src2, 11, 28);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_LIST (&dest) == TRUE);
tmp = gst_value_list_get_value (&dest, 0);
fail_unless (G_VALUE_HOLDS_INT (tmp) == TRUE);
fail_unless (g_value_get_int (tmp) == 10);
tmp = gst_value_list_get_value (&dest, 1);
fail_unless (GST_VALUE_HOLDS_INT_RANGE (tmp) == TRUE);
fail_unless (gst_value_get_int_range_min (tmp) == 29);
fail_unless (gst_value_get_int_range_max (tmp) == 30);
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);
/* create a hole, { int_range, int } */
g_value_init (&src1, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src1, 10, 30);
g_value_init (&src2, GST_TYPE_INT_RANGE);
gst_value_set_int_range (&src2, 12, 29);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_LIST (&dest) == TRUE);
tmp = gst_value_list_get_value (&dest, 0);
fail_unless (GST_VALUE_HOLDS_INT_RANGE (tmp) == TRUE);
fail_unless (gst_value_get_int_range_min (tmp) == 10);
fail_unless (gst_value_get_int_range_max (tmp) == 11);
tmp = gst_value_list_get_value (&dest, 1);
fail_unless (G_VALUE_HOLDS_INT (tmp) == TRUE);
fail_unless (g_value_get_int (tmp) == 30);
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);
}
GST_END_TEST;
GST_START_TEST (test_value_subtract_double)
{
GValue dest = { 0 };
GValue src1 = { 0 };
GValue src2 = { 0 };
const GValue *tmp;
gboolean ret;
/* double <-> double
*/
g_value_init (&src1, G_TYPE_DOUBLE);
g_value_set_double (&src1, 10.0);
g_value_init (&src2, G_TYPE_DOUBLE);
g_value_set_double (&src2, 20.0);
/* 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);
/* double <-> double_range
*/
/* would yield an empty set */
g_value_init (&src1, G_TYPE_DOUBLE);
g_value_set_double (&src1, 10.0);
g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
gst_value_set_double_range (&src2, 0.0, 20.0);
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_DOUBLE_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_double_range_min (&dest) == 0.0);
fail_unless (gst_value_get_double_range_max (&dest) == 20.0);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* border case 1, empty set */
g_value_init (&src1, G_TYPE_DOUBLE);
g_value_set_double (&src1, 10.0);
g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
gst_value_set_double_range (&src2, 10.0, 20.0);
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_DOUBLE_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_double_range_min (&dest) == 10.0);
fail_unless (gst_value_get_double_range_max (&dest) == 20.0);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* border case 2, empty set */
g_value_init (&src1, G_TYPE_DOUBLE);
g_value_set_double (&src1, 20.0);
g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
gst_value_set_double_range (&src2, 10.0, 20.0);
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_DOUBLE_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_double_range_min (&dest) == 10.0);
fail_unless (gst_value_get_double_range_max (&dest) == 20.0);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* case 3, valid set */
g_value_init (&src1, G_TYPE_DOUBLE);
g_value_set_double (&src1, 0.0);
g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
gst_value_set_double_range (&src2, 10.0, 20.0);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == TRUE);
fail_unless (G_VALUE_HOLDS_DOUBLE (&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_DOUBLE_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_double_range_min (&dest) == 10.0);
fail_unless (gst_value_get_double_range_max (&dest) == 20.0);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* double_range <-> double_range
*/
/* same range, empty set */
g_value_init (&src1, GST_TYPE_DOUBLE_RANGE);
gst_value_set_double_range (&src1, 10.0, 20.0);
g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
gst_value_set_double_range (&src2, 10.0, 20.0);
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_DOUBLE_RANGE);
gst_value_set_double_range (&src1, 10.0, 20.0);
g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
gst_value_set_double_range (&src2, 30.0, 40.0);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_DOUBLE_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_double_range_min (&dest) == 10.0);
fail_unless (gst_value_get_double_range_max (&dest) == 20.0);
g_value_unset (&dest);
/* the other way */
ret = gst_value_subtract (&dest, &src2, &src1);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_DOUBLE_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_double_range_min (&dest) == 30.0);
fail_unless (gst_value_get_double_range_max (&dest) == 40.0);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* completely overlapping ranges */
g_value_init (&src1, GST_TYPE_DOUBLE_RANGE);
gst_value_set_double_range (&src1, 10.0, 20.0);
g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
gst_value_set_double_range (&src2, 10.0, 30.0);
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_DOUBLE_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_double_range_min (&dest) == 20.0);
fail_unless (gst_value_get_double_range_max (&dest) == 30.0);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* partially overlapping ranges */
g_value_init (&src1, GST_TYPE_DOUBLE_RANGE);
gst_value_set_double_range (&src1, 10.0, 20.0);
g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
gst_value_set_double_range (&src2, 15.0, 30.0);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_DOUBLE_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_double_range_min (&dest) == 10.0);
fail_unless (gst_value_get_double_range_max (&dest) == 15.0);
g_value_unset (&dest);
/* the other way */
ret = gst_value_subtract (&dest, &src2, &src1);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_DOUBLE_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_double_range_min (&dest) == 20.0);
fail_unless (gst_value_get_double_range_max (&dest) == 30.0);
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_DOUBLE_RANGE);
gst_value_set_double_range (&src1, 10.0, 30.0);
g_value_init (&src2, GST_TYPE_DOUBLE_RANGE);
gst_value_set_double_range (&src2, 15.0, 20.0);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_LIST (&dest) == TRUE);
tmp = gst_value_list_get_value (&dest, 0);
fail_unless (GST_VALUE_HOLDS_DOUBLE_RANGE (tmp) == TRUE);
fail_unless (gst_value_get_double_range_min (tmp) == 10.0);
fail_unless (gst_value_get_double_range_max (tmp) == 15.0);
tmp = gst_value_list_get_value (&dest, 1);
fail_unless (GST_VALUE_HOLDS_DOUBLE_RANGE (tmp) == TRUE);
fail_unless (gst_value_get_double_range_min (tmp) == 20.0);
fail_unless (gst_value_get_double_range_max (tmp) == 30.0);
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);
}
GST_END_TEST;
Suite * Suite *
gst_value_suite (void) gst_value_suite (void)
{ {
@ -453,6 +936,9 @@ gst_value_suite (void)
tcase_add_test (tc_chain, test_deserialize_string); tcase_add_test (tc_chain, test_deserialize_string);
tcase_add_test (tc_chain, test_value_compare); tcase_add_test (tc_chain, test_value_compare);
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_double);
return s; return s;
} }