gstreamer/tests/check/gst/gstvalue.c
Thiago Santos 007c0e5fe1 value: fix caps serialization when there are caps inside caps
Wrap caps strings so that it can handle serialization and deserialization
of caps inside caps. Otherwise the values from the internal caps are parsed
as if they were from the upper one

https://bugzilla.gnome.org/show_bug.cgi?id=708772
2013-09-30 16:20:48 -03:00

2861 lines
94 KiB
C

/* GStreamer
* Copyright (C) <2004> David Schleef <david at schleef dot org>
* Copyright (C) <2005> Thomas Vander Stichele <thomas at apestaart dot org>
*
* gstvalue.c: Unit tests for GstValue
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <gst/check/gstcheck.h>
GST_START_TEST (test_deserialize_buffer)
{
GValue value = { 0 };
GstBuffer *buf;
g_value_init (&value, GST_TYPE_BUFFER);
fail_unless (gst_value_deserialize (&value, "1234567890abcdef"));
/* does not increase the refcount */
buf = GST_BUFFER (g_value_get_boxed (&value));
ASSERT_MINI_OBJECT_REFCOUNT (buf, "buffer", 1);
/* does not increase the refcount */
buf = gst_value_get_buffer (&value);
ASSERT_MINI_OBJECT_REFCOUNT (buf, "buffer", 1);
/* cleanup */
g_value_unset (&value);
}
GST_END_TEST;
/* create and serialize a buffer */
GST_START_TEST (test_serialize_buffer)
{
GValue value = { 0 };
GstBuffer *buf;
gchar *serialized;
static const char *buf_data = "1234567890abcdef";
gint len;
len = strlen (buf_data);
buf = gst_buffer_new_and_alloc (len);
gst_buffer_fill (buf, 0, buf_data, len);
ASSERT_MINI_OBJECT_REFCOUNT (buf, "buffer", 1);
/* and assign buffer to mini object */
g_value_init (&value, GST_TYPE_BUFFER);
gst_value_take_buffer (&value, buf);
ASSERT_MINI_OBJECT_REFCOUNT (buf, "buffer", 1);
/* now serialize it */
serialized = gst_value_serialize (&value);
GST_DEBUG ("serialized buffer to %s", serialized);
fail_unless (serialized != NULL);
/* refcount should not change */
ASSERT_MINI_OBJECT_REFCOUNT (buf, "buffer", 1);
/* cleanup */
g_free (serialized);
g_value_unset (&value);
/* take NULL buffer */
g_value_init (&value, GST_TYPE_BUFFER);
GST_DEBUG ("setting NULL buffer");
gst_value_take_buffer (&value, NULL);
/* now serialize it */
GST_DEBUG ("serializing NULL buffer");
serialized = gst_value_serialize (&value);
/* should return NULL */
fail_unless (serialized == NULL);
g_free (serialized);
g_value_unset (&value);
}
GST_END_TEST;
GST_START_TEST (test_deserialize_gint64)
{
GValue value = { 0 };
const char *strings[] = {
"12345678901",
"-12345678901",
"1152921504606846976",
"-1152921504606846976",
};
gint64 results[] = {
12345678901LL,
-12345678901LL,
1152921504606846976LL,
-1152921504606846976LL,
};
int i;
g_value_init (&value, G_TYPE_INT64);
for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
fail_unless (gst_value_deserialize (&value, strings[i]),
"could not deserialize %s (%d)", strings[i], i);
fail_unless (g_value_get_int64 (&value) == results[i],
"resulting value is %" G_GINT64_FORMAT ", not %" G_GINT64_FORMAT
", for string %s (%d)", g_value_get_int64 (&value),
results[i], strings[i], i);
}
}
GST_END_TEST;
GST_START_TEST (test_deserialize_guint64)
{
GValue value = { 0 };
const char *strings[] = {
"0xffffffffffffffff",
"9223372036854775810",
"-9223372036854775810",
"-1",
"1",
"-0",
};
guint64 results[] = {
0xffffffffffffffffULL,
9223372036854775810ULL,
9223372036854775806ULL,
(guint64) - 1,
1,
0,
};
int i;
g_value_init (&value, G_TYPE_UINT64);
for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
fail_unless (gst_value_deserialize (&value, strings[i]),
"could not deserialize %s (%d)", strings[i], i);
fail_unless (g_value_get_uint64 (&value) == results[i],
"resulting value is %" G_GUINT64_FORMAT ", not %" G_GUINT64_FORMAT
", for string %s (%d)", g_value_get_uint64 (&value),
results[i], strings[i], i);
}
}
GST_END_TEST;
GST_START_TEST (test_deserialize_guchar)
{
GValue value = { 0 };
const char *strings[] = {
"0xff",
"255",
"-1",
"1",
"-0",
};
guchar results[] = {
0xff,
255,
(guchar) - 1,
1,
0,
};
int i;
g_value_init (&value, G_TYPE_UCHAR);
for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
fail_unless (gst_value_deserialize (&value, strings[i]),
"could not deserialize %s (%d)", strings[i], i);
fail_unless (g_value_get_uchar (&value) == results[i],
"resulting value is %u not %u, for string %s (%d)",
g_value_get_uchar (&value), results[i], strings[i], i);
}
/* test serialisation as well while we're at it */
{
gchar *str;
GValue value = { 0 };
g_value_init (&value, G_TYPE_UCHAR);
g_value_set_uchar (&value, 255);
str = gst_value_serialize (&value);
fail_unless_equals_string (str, "255");
g_free (str);
}
}
GST_END_TEST;
GST_START_TEST (test_deserialize_gstfraction)
{
GValue value = { 0 };
const char *strings[] = {
"4/5",
"-8/9"
};
gint64 result_numers[] = {
4,
-8
};
gint64 result_denoms[] = {
5,
9
};
int i;
g_value_init (&value, GST_TYPE_FRACTION);
for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
fail_unless (gst_value_deserialize (&value, strings[i]),
"could not deserialize %s (%d)", strings[i], i);
fail_unless (gst_value_get_fraction_numerator (&value) == result_numers[i],
"resulting numerator value is %d, not %d"
", for string %s (%d)", gst_value_get_fraction_numerator (&value),
result_numers[i], strings[i], i);
fail_unless (gst_value_get_fraction_denominator (&value) ==
result_denoms[i], "resulting denominator value is %d, not %d"
", for string %s (%d)", gst_value_get_fraction_denominator (&value),
result_denoms[i], strings[i], i);
}
}
GST_END_TEST;
GST_START_TEST (test_deserialize_gint)
{
GValue value = { 0 };
const char *strings[] = {
"123456",
"-123456",
"0xFFFF",
"0x0000FFFF",
/* a positive long long, serializing to highest possible positive sint */
"0x7FFFFFFF",
/* a positive long long, serializing to lowest possible negative sint */
"0x80000000",
/* a negative long long, serializing to lowest possible negative sint */
"0xFFFFFFFF80000000",
"0xFF000000",
/* a positive long long serializing to -1 */
"0xFFFFFFFF",
"0xFFFFFFFF",
/* a negative long long serializing to -1 */
"0xFFFFFFFFFFFFFFFF",
"0xFFFFFFFFFFFFFFFF",
"0xEFFFFFFF",
};
/* some casts need to be explicit because of unsigned -> signed */
gint results[] = {
123456,
-123456,
0xFFFF,
0xFFFF,
0x7FFFFFFF,
(gint) 0x80000000,
(gint) 0x80000000,
(gint) 0xFF000000,
-1,
(gint) 0xFFFFFFFF,
-1,
(gint) 0xFFFFFFFFFFFFFFFFLL,
(gint) 0xEFFFFFFF,
};
int i;
g_value_init (&value, G_TYPE_INT);
for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
fail_unless (gst_value_deserialize (&value, strings[i]),
"could not deserialize %s (%d)", strings[i], i);
fail_unless (g_value_get_int (&value) == results[i],
"resulting value is %d, not %d, for string %s (%d)",
g_value_get_int (&value), results[i], strings[i], i);
}
}
GST_END_TEST;
GST_START_TEST (test_deserialize_gint_failures)
{
GValue value = { 0 };
const char *strings[] = {
"-", /* not a complete number */
"- TEST", /* not a complete number */
"0x0000000100000000", /* lowest long long that cannot fit in 32 bits */
"0xF000000000000000",
"0xFFFFFFF000000000",
"0xFFFFFFFF00000000",
"0x10000000000000000", /* first number too long to fit into a long long */
/* invent a new processor first before trying to make this one pass */
"0x10000000000000000000000000000000000000000000",
};
int i;
g_value_init (&value, G_TYPE_INT);
for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
fail_if (gst_value_deserialize (&value, strings[i]),
"deserialized %s (%d), while it should have failed", strings[i], i);
}
}
GST_END_TEST;
GST_START_TEST (test_deserialize_guint)
{
GValue value = { 0 };
const char *strings[] = {
"123456",
"-123456",
"0xFFFF",
"0x0000FFFF",
/* a positive long long, serializing to highest possible positive sint */
"0x7FFFFFFF",
/* a positive long long, serializing to lowest possible negative sint */
"0x80000000",
"2147483648",
/* a negative long long, serializing to lowest possible negative sint */
"0xFFFFFFFF80000000",
/* a value typically used for rgb masks */
"0xFF000000",
/* a positive long long serializing to highest possible positive uint */
"0xFFFFFFFF",
"0xFFFFFFFF",
/* a negative long long serializing to highest possible positive uint */
"0xFFFFFFFFFFFFFFFF",
"0xEFFFFFFF",
};
guint results[] = {
123456,
(guint) - 123456,
0xFFFF,
0xFFFF,
0x7FFFFFFF,
0x80000000,
(guint) 2147483648LL,
0x80000000,
0xFF000000,
0xFFFFFFFF,
G_MAXUINT,
(guint) 0xFFFFFFFFFFFFFFFFLL,
0xEFFFFFFF,
};
int i;
g_value_init (&value, G_TYPE_UINT);
for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
fail_unless (gst_value_deserialize (&value, strings[i]),
"could not deserialize %s (%d)", strings[i], i);
fail_unless (g_value_get_uint (&value) == results[i],
"resulting value is %d, not %d, for string %s (%d)",
g_value_get_uint (&value), results[i], strings[i], i);
}
}
GST_END_TEST;
GST_START_TEST (test_deserialize_guint_failures)
{
GValue value = { 0 };
const char *strings[] = {
"-", /* not a complete number */
"- TEST", /* not a complete number */
#if 0
/* FIXME: these values should not be deserializable, since they overflow
* the target format */
"0x0000000100000000", /* lowest long long that cannot fit in 32 bits */
"0xF000000000000000",
"0xFFFFFFF000000000",
"0xFFFFFFFF00000000",
"0x10000000000000000", /* first number too long to fit into a long long */
/* invent a new processor first before trying to make this one pass */
"0x10000000000000000000000000000000000000000000",
#endif
};
int i;
g_value_init (&value, G_TYPE_UINT);
for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
fail_if (gst_value_deserialize (&value, strings[i]),
"deserialized %s (%d), while it should have failed", strings[i], i);
}
}
GST_END_TEST;
GST_START_TEST (test_serialize_flags)
{
GValue value = { 0 };
gchar *string;
GstSeekFlags flags[] = {
0,
GST_SEEK_FLAG_NONE,
GST_SEEK_FLAG_FLUSH,
GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE,
};
const char *results[] = {
"GST_SEEK_FLAG_NONE",
"GST_SEEK_FLAG_NONE",
"GST_SEEK_FLAG_FLUSH",
"GST_SEEK_FLAG_FLUSH+GST_SEEK_FLAG_ACCURATE",
};
int i;
g_value_init (&value, GST_TYPE_SEEK_FLAGS);
for (i = 0; i < G_N_ELEMENTS (flags); ++i) {
g_value_set_flags (&value, flags[i]);
string = gst_value_serialize (&value);
fail_if (string == NULL, "could not serialize flags %d", i);
fail_unless (strcmp (string, results[i]) == 0,
"resulting value is %s, not %s, for flags #%d", string, results[i], i);
g_free (string);
}
}
GST_END_TEST;
GST_START_TEST (test_deserialize_flags)
{
GValue value = { 0 };
const char *strings[] = {
"",
"0",
"GST_SEEK_FLAG_NONE",
"GST_SEEK_FLAG_FLUSH",
"GST_SEEK_FLAG_FLUSH+GST_SEEK_FLAG_ACCURATE",
};
GstSeekFlags results[] = {
GST_SEEK_FLAG_NONE,
GST_SEEK_FLAG_NONE,
GST_SEEK_FLAG_NONE,
GST_SEEK_FLAG_FLUSH,
GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE,
};
int i;
g_value_init (&value, GST_TYPE_SEEK_FLAGS);
for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
fail_unless (gst_value_deserialize (&value, strings[i]),
"could not deserialize %s (%d)", strings[i], i);
fail_unless (g_value_get_flags (&value) == results[i],
"resulting value is %d, not %d, for string %s (%d)",
g_value_get_flags (&value), results[i], strings[i], i);
}
}
GST_END_TEST;
GST_START_TEST (test_deserialize_bitmask)
{
GValue value = { 0 };
const char *strings[] = {
"0xffffffffffffffff",
"0x1234567890ABCDEF",
};
guint64 results[] = {
0xffffffffffffffffULL,
0x1234567890ABCDEFULL,
};
int i;
g_value_init (&value, GST_TYPE_BITMASK);
for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
fail_unless (gst_value_deserialize (&value, strings[i]),
"could not deserialize %s (%d)", strings[i], i);
fail_unless (gst_value_get_bitmask (&value) == results[i],
"resulting value is 0x%016" G_GINT64_MODIFIER "x, not 0x%016"
G_GINT64_MODIFIER "x, for string %s (%d)",
gst_value_get_bitmask (&value), results[i], strings[i], i);
}
}
GST_END_TEST;
GST_START_TEST (test_string)
{
const gchar *try[] = {
"Dude",
"Hi, I'm a string",
"tüüüt!",
"\"\"" /* Empty string */
};
gchar *tmp;
GValue v = { 0, };
guint i;
g_value_init (&v, G_TYPE_STRING);
for (i = 0; i < G_N_ELEMENTS (try); i++) {
g_value_set_string (&v, try[i]);
tmp = gst_value_serialize (&v);
fail_if (tmp == NULL, "couldn't serialize: %s\n", try[i]);
fail_unless (gst_value_deserialize (&v, tmp),
"couldn't deserialize: %s\n", tmp);
g_free (tmp);
fail_unless (g_str_equal (g_value_get_string (&v), try[i]),
"\nserialized : %s\ndeserialized: %s", try[i],
g_value_get_string (&v));
}
/* NULL strings should not be serializable */
g_value_set_string (&v, NULL);
fail_unless (gst_value_serialize (&v) == NULL);
g_value_unset (&v);
}
GST_END_TEST;
GST_START_TEST (test_deserialize_string)
{
struct
{
const gchar *from;
const gchar *to;
} tests[] = {
{
"", ""}, /* empty strings */
{
"\"\"", ""}, /* quoted empty string -> empty string */
/* Expected FAILURES: */
{
"\"", NULL}, /* missing second quote */
{
"\"Hello\\ World", NULL}, /* missing second quote */
{
"\"\\", NULL}, /* quote at end, missing second quote */
{
"\"\\0", NULL}, /* missing second quote */
{
"\"\\0\"", NULL}, /* unfinished escaped character */
{
"\" \"", NULL}, /* spaces must be escaped */
#if 0
/* FIXME 0.9: this test should fail, but it doesn't */
{
"tüüt", NULL} /* string with special chars must be escaped */
#endif
};
guint i;
GValue v = { 0, };
g_value_init (&v, G_TYPE_STRING);
for (i = 0; i < G_N_ELEMENTS (tests); i++) {
if (gst_value_deserialize (&v, tests[i].from)) {
fail_if (tests[i].to == NULL,
"I got %s instead of a failure", g_value_get_string (&v));
fail_unless (g_str_equal (g_value_get_string (&v), tests[i].to),
"\nwanted: %s\ngot : %s", tests[i].to, g_value_get_string (&v));
} else {
fail_if (tests[i].to != NULL, "failed, but wanted: %s", tests[i].to);
}
}
g_value_unset (&v);
}
GST_END_TEST;
GST_START_TEST (test_value_compare)
{
GValue value1 = { 0 };
GValue value2 = { 0 };
GValue tmp = { 0 };
g_value_init (&value1, G_TYPE_INT);
g_value_set_int (&value1, 10);
g_value_init (&value2, G_TYPE_INT);
g_value_set_int (&value2, 20);
fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_LESS_THAN);
fail_unless (gst_value_compare (&value2, &value1) == GST_VALUE_GREATER_THAN);
fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
g_value_unset (&value1);
g_value_unset (&value2);
g_value_init (&value1, G_TYPE_DOUBLE);
g_value_set_double (&value1, 10);
g_value_init (&value2, G_TYPE_DOUBLE);
g_value_set_double (&value2, 20);
fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_LESS_THAN);
fail_unless (gst_value_compare (&value2, &value1) == GST_VALUE_GREATER_THAN);
fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
g_value_unset (&value1);
g_value_unset (&value2);
g_value_init (&value1, G_TYPE_STRING);
g_value_set_string (&value1, "a");
g_value_init (&value2, G_TYPE_STRING);
g_value_set_string (&value2, "b");
fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_LESS_THAN);
fail_unless (gst_value_compare (&value2, &value1) == GST_VALUE_GREATER_THAN);
fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
/* Test some NULL string comparisons */
g_value_set_string (&value2, NULL);
fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_UNORDERED);
fail_unless (gst_value_compare (&value2, &value1) == GST_VALUE_UNORDERED);
fail_unless (gst_value_compare (&value2, &value2) == GST_VALUE_EQUAL);
g_value_unset (&value1);
g_value_unset (&value2);
/* comparing 2/3 with 3/4 */
g_value_init (&value1, GST_TYPE_FRACTION);
gst_value_set_fraction (&value1, 2, 3);
g_value_init (&value2, GST_TYPE_FRACTION);
gst_value_set_fraction (&value2, 3, 4);
fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_LESS_THAN);
fail_unless (gst_value_compare (&value2, &value1) == GST_VALUE_GREATER_THAN);
fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
g_value_unset (&value1);
g_value_unset (&value2);
/* comparing -4/5 with 2/-3 */
g_value_init (&value1, GST_TYPE_FRACTION);
gst_value_set_fraction (&value1, -4, 5);
g_value_init (&value2, GST_TYPE_FRACTION);
gst_value_set_fraction (&value2, 2, -3);
fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_LESS_THAN);
fail_unless (gst_value_compare (&value2, &value1) == GST_VALUE_GREATER_THAN);
fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
g_value_unset (&value1);
g_value_unset (&value2);
/* comparing 10/100 with 200/2000 */
g_value_init (&value1, GST_TYPE_FRACTION);
gst_value_set_fraction (&value1, 10, 100);
g_value_init (&value2, GST_TYPE_FRACTION);
gst_value_set_fraction (&value2, 200, 2000);
fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_EQUAL);
g_value_unset (&value1);
g_value_unset (&value2);
/* comparing -4/5 with 2/-3 */
g_value_init (&value1, GST_TYPE_FRACTION);
gst_value_set_fraction (&value1, -4, 5);
g_value_init (&value2, GST_TYPE_FRACTION);
gst_value_set_fraction (&value2, 2, -3);
fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_LESS_THAN);
fail_unless (gst_value_compare (&value2, &value1) == GST_VALUE_GREATER_THAN);
fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
g_value_unset (&value1);
g_value_unset (&value2);
/* Check that lists are equal regardless of order */
g_value_init (&value1, GST_TYPE_LIST);
g_value_init (&tmp, G_TYPE_INT);
g_value_set_int (&tmp, 1);
gst_value_list_append_value (&value1, &tmp);
g_value_set_int (&tmp, 2);
gst_value_list_append_value (&value1, &tmp);
g_value_set_int (&tmp, 3);
gst_value_list_append_value (&value1, &tmp);
g_value_set_int (&tmp, 4);
gst_value_list_append_value (&value1, &tmp);
g_value_init (&value2, GST_TYPE_LIST);
g_value_set_int (&tmp, 4);
gst_value_list_append_value (&value2, &tmp);
g_value_set_int (&tmp, 3);
gst_value_list_append_value (&value2, &tmp);
g_value_set_int (&tmp, 2);
gst_value_list_append_value (&value2, &tmp);
g_value_set_int (&tmp, 1);
gst_value_list_append_value (&value2, &tmp);
fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_EQUAL,
"value lists with different order were not equal when they should be");
fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL,
"value lists with same order were not equal when they should be");
fail_unless (gst_value_compare (&value2, &value2) == GST_VALUE_EQUAL,
"value lists with same order were not equal when they should be");
/* Carry over the lists to this next check: */
/* Lists with different sizes are unequal */
g_value_set_int (&tmp, 1);
gst_value_list_append_value (&value2, &tmp);
fail_if (gst_value_compare (&value1, &value2) == GST_VALUE_EQUAL,
"Value lists with different size were equal when they shouldn't be");
/* Carry over the lists to this next check: */
/* Lists with same size but list1 contains one more element not in list2 */
g_value_set_int (&tmp, 5);
gst_value_list_append_value (&value1, &tmp);
fail_if (gst_value_compare (&value1, &value2) == GST_VALUE_EQUAL,
"Value lists with different elements were equal when they shouldn't be");
fail_if (gst_value_compare (&value2, &value1) == GST_VALUE_EQUAL,
"Value lists with different elements were equal when they shouldn't be");
g_value_unset (&value1);
g_value_unset (&value2);
g_value_unset (&tmp);
/* Arrays are only equal when in the same order */
g_value_init (&value1, GST_TYPE_ARRAY);
g_value_init (&tmp, G_TYPE_INT);
g_value_set_int (&tmp, 1);
gst_value_array_append_value (&value1, &tmp);
g_value_set_int (&tmp, 2);
gst_value_array_append_value (&value1, &tmp);
g_value_set_int (&tmp, 3);
gst_value_array_append_value (&value1, &tmp);
g_value_set_int (&tmp, 4);
gst_value_array_append_value (&value1, &tmp);
g_value_init (&value2, GST_TYPE_ARRAY);
g_value_set_int (&tmp, 4);
gst_value_array_append_value (&value2, &tmp);
g_value_set_int (&tmp, 3);
gst_value_array_append_value (&value2, &tmp);
g_value_set_int (&tmp, 2);
gst_value_array_append_value (&value2, &tmp);
g_value_set_int (&tmp, 1);
gst_value_array_append_value (&value2, &tmp);
fail_if (gst_value_compare (&value1, &value2) == GST_VALUE_EQUAL,
"Value arrays with different order were equal when they shouldn't be");
fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL,
"Identical value arrays were not equal when they should be");
fail_unless (gst_value_compare (&value2, &value2) == GST_VALUE_EQUAL,
"Identical value arrays were not equal when they should be");
/* Carry over the arrays to this next check: */
/* Arrays with different sizes are unequal */
g_value_unset (&value2);
g_value_init (&value2, GST_TYPE_ARRAY);
g_value_copy (&value1, &value2);
g_value_set_int (&tmp, 1);
gst_value_array_append_value (&value2, &tmp);
fail_if (gst_value_compare (&value1, &value2) == GST_VALUE_EQUAL,
"Value arrays with different size were equal when they shouldn't be");
/* order should not matter */
fail_if (gst_value_compare (&value2, &value1) == GST_VALUE_EQUAL,
"Value arrays with different size were equal when they shouldn't be");
g_value_unset (&value1);
g_value_unset (&value2);
g_value_unset (&tmp);
g_value_init (&value1, GST_TYPE_BITMASK);
gst_value_set_bitmask (&value1, 0x123);
g_value_init (&value2, GST_TYPE_BITMASK);
gst_value_set_bitmask (&value2, 0x321);
fail_unless (gst_value_compare (&value1, &value2) == GST_VALUE_UNORDERED);
fail_unless (gst_value_compare (&value2, &value1) == GST_VALUE_UNORDERED);
fail_unless (gst_value_compare (&value1, &value1) == GST_VALUE_EQUAL);
g_value_unset (&value1);
g_value_unset (&value2);
}
GST_END_TEST;
GST_START_TEST (test_value_intersect)
{
GValue dest = { 0 };
GValue src1 = { 0 };
GValue src2 = { 0 };
GValue item = { 0 };
gboolean ret;
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);
ret = gst_value_intersect (&dest, &src1, &src2);
fail_unless (ret == FALSE);
g_value_unset (&src1);
g_value_unset (&src2);
g_value_init (&src1, G_TYPE_STRING);
g_value_set_static_string (&src1, "YUY2");
g_value_init (&src2, GST_TYPE_LIST);
g_value_init (&item, G_TYPE_STRING);
g_value_set_static_string (&item, "YUY2");
gst_value_list_append_value (&src2, &item);
g_value_set_static_string (&item, "I420");
gst_value_list_append_value (&src2, &item);
g_value_set_static_string (&item, "ABCD");
gst_value_list_append_value (&src2, &item);
fail_unless (gst_value_intersect (&dest, &src1, &src2));
fail_unless (G_VALUE_HOLDS_STRING (&dest));
fail_unless (g_str_equal (g_value_get_string (&dest), "YUY2"));
g_value_unset (&src1);
g_value_unset (&src2);
g_value_unset (&dest);
}
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_int64)
{
GValue dest = { 0 };
GValue src1 = { 0 };
GValue src2 = { 0 };
const GValue *tmp;
gboolean ret;
/* int64 <-> int64
*/
g_value_init (&src1, G_TYPE_INT64);
g_value_set_int64 (&src1, 10);
g_value_init (&src2, G_TYPE_INT64);
g_value_set_int64 (&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);
/* int64 <-> int64_range
*/
/* would yield an empty set */
g_value_init (&src1, G_TYPE_INT64);
g_value_set_int64 (&src1, 10);
g_value_init (&src2, GST_TYPE_INT64_RANGE);
gst_value_set_int64_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_INT64_RANGE (tmp) == TRUE);
fail_unless (gst_value_get_int64_range_min (tmp) == 0);
fail_unless (gst_value_get_int64_range_max (tmp) == 9);
tmp = gst_value_list_get_value (&dest, 1);
fail_unless (GST_VALUE_HOLDS_INT64_RANGE (tmp) == TRUE);
fail_unless (gst_value_get_int64_range_min (tmp) == 11);
fail_unless (gst_value_get_int64_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_INT64);
g_value_set_int64 (&src1, 10);
g_value_init (&src2, GST_TYPE_INT64_RANGE);
gst_value_set_int64_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_INT64_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_int64_range_min (&dest) == 11);
fail_unless (gst_value_get_int64_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_INT64);
g_value_set_int64 (&src1, 20);
g_value_init (&src2, GST_TYPE_INT64_RANGE);
gst_value_set_int64_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_INT64_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_int64_range_min (&dest) == 10);
fail_unless (gst_value_get_int64_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_INT64);
g_value_set_int64 (&src1, 0);
g_value_init (&src2, GST_TYPE_INT64_RANGE);
gst_value_set_int64_range (&src2, 10, 20);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == TRUE);
fail_unless (G_VALUE_HOLDS_INT64 (&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_INT64_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_int64_range_min (&dest) == 10);
fail_unless (gst_value_get_int64_range_max (&dest) == 20);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* int64_range <-> int64_range
*/
/* same range, empty set */
g_value_init (&src1, GST_TYPE_INT64_RANGE);
gst_value_set_int64_range (&src1, 10, 20);
g_value_init (&src2, GST_TYPE_INT64_RANGE);
gst_value_set_int64_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_INT64_RANGE);
gst_value_set_int64_range (&src1, 10, 20);
g_value_init (&src2, GST_TYPE_INT64_RANGE);
gst_value_set_int64_range (&src2, 30, 40);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_INT64_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_int64_range_min (&dest) == 10);
fail_unless (gst_value_get_int64_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_INT64_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_int64_range_min (&dest) == 30);
fail_unless (gst_value_get_int64_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_INT64_RANGE);
gst_value_set_int64_range (&src1, 10, 20);
g_value_init (&src2, GST_TYPE_INT64_RANGE);
gst_value_set_int64_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_INT64_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_int64_range_min (&dest) == 21);
fail_unless (gst_value_get_int64_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_INT64_RANGE);
gst_value_set_int64_range (&src1, 10, 20);
g_value_init (&src2, GST_TYPE_INT64_RANGE);
gst_value_set_int64_range (&src2, 15, 30);
ret = gst_value_subtract (&dest, &src1, &src2);
fail_unless (ret == TRUE);
fail_unless (GST_VALUE_HOLDS_INT64_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_int64_range_min (&dest) == 10);
fail_unless (gst_value_get_int64_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_INT64_RANGE (&dest) == TRUE);
fail_unless (gst_value_get_int64_range_min (&dest) == 21);
fail_unless (gst_value_get_int64_range_max (&dest) == 30);
g_value_unset (&dest);
g_value_unset (&src1);
g_value_unset (&src2);
/* create a hole { int64_range, int64_range } */
g_value_init (&src1, GST_TYPE_INT64_RANGE);
gst_value_set_int64_range (&src1, 10, 30);
g_value_init (&src2, GST_TYPE_INT64_RANGE);
gst_value_set_int64_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_INT64_RANGE (tmp) == TRUE);
fail_unless (gst_value_get_int64_range_min (tmp) == 10);
fail_unless (gst_value_get_int64_range_max (tmp) == 14);
tmp = gst_value_list_get_value (&dest, 1);
fail_unless (GST_VALUE_HOLDS_INT64_RANGE (tmp) == TRUE);
fail_unless (gst_value_get_int64_range_min (tmp) == 21);
fail_unless (gst_value_get_int64_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, { int64, int64 } */
g_value_init (&src1, GST_TYPE_INT64_RANGE);
gst_value_set_int64_range (&src1, 10, 30);
g_value_init (&src2, GST_TYPE_INT64_RANGE);
gst_value_set_int64_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_INT64 (tmp) == TRUE);
fail_unless (g_value_get_int64 (tmp) == 10);
tmp = gst_value_list_get_value (&dest, 1);
fail_unless (G_VALUE_HOLDS_INT64 (tmp) == TRUE);
fail_unless (g_value_get_int64 (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, { int64, int64_range } */
g_value_init (&src1, GST_TYPE_INT64_RANGE);
gst_value_set_int64_range (&src1, 10, 30);
g_value_init (&src2, GST_TYPE_INT64_RANGE);
gst_value_set_int64_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_INT64 (tmp) == TRUE);
fail_unless (g_value_get_int64 (tmp) == 10);
tmp = gst_value_list_get_value (&dest, 1);
fail_unless (GST_VALUE_HOLDS_INT64_RANGE (tmp) == TRUE);
fail_unless (gst_value_get_int64_range_min (tmp) == 29);
fail_unless (gst_value_get_int64_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, { int64_range, int64 } */
g_value_init (&src1, GST_TYPE_INT64_RANGE);
gst_value_set_int64_range (&src1, 10, 30);
g_value_init (&src2, GST_TYPE_INT64_RANGE);
gst_value_set_int64_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_INT64_RANGE (tmp) == TRUE);
fail_unless (gst_value_get_int64_range_min (tmp) == 10);
fail_unless (gst_value_get_int64_range_max (tmp) == 11);
tmp = gst_value_list_get_value (&dest, 1);
fail_unless (G_VALUE_HOLDS_INT64 (tmp) == TRUE);
fail_unless (g_value_get_int64 (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;
/* 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);
/* Subtract 12/13 from 4/3 */
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, 4, 3);
gst_value_set_fraction (&src2, 12, 13);
fail_unless (gst_value_fraction_subtract (&result, &src1, &src2) == TRUE);
fail_unless (gst_value_get_fraction_numerator (&result) == 16);
fail_unless (gst_value_get_fraction_denominator (&result) == 39);
g_value_unset (&src1);
g_value_unset (&src2);
g_value_unset (&result);
/* Subtract 1/12 from 7/8 */
}
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;
/* Test set subtraction operations on fraction lists */
GST_START_TEST (test_value_subtract_fraction_list)
{
GValue list1 = { 0 };
GValue list2 = { 0 };
GValue val1 = { 0 };
GValue val2 = { 0 };
GValue tmp = { 0 };
gboolean ret;
g_value_init (&list1, GST_TYPE_LIST);
g_value_init (&val1, GST_TYPE_FRACTION);
gst_value_set_fraction (&val1, 15, 2);
gst_value_list_append_value (&list1, &val1);
g_value_init (&tmp, GST_TYPE_FRACTION);
gst_value_set_fraction (&tmp, 5, 1);
gst_value_list_append_value (&list1, &tmp);
g_value_unset (&tmp);
g_value_init (&list2, GST_TYPE_LIST);
g_value_init (&val2, GST_TYPE_FRACTION);
gst_value_set_fraction (&val2, 15, 1);
gst_value_list_append_value (&list2, &val2);
g_value_init (&tmp, GST_TYPE_FRACTION);
gst_value_set_fraction (&tmp, 5, 1);
gst_value_list_append_value (&list2, &tmp);
g_value_unset (&tmp);
/* should subtract all common elements */
ret = gst_value_subtract (&tmp, &list1, &list2);
fail_unless (ret == TRUE);
fail_unless (gst_value_compare (&tmp, &val1) == GST_VALUE_EQUAL);
g_value_unset (&val1);
g_value_unset (&tmp);
ret = gst_value_subtract (&tmp, &list2, &list1);
fail_unless (ret == TRUE);
fail_unless (gst_value_compare (&tmp, &val2) == GST_VALUE_EQUAL);
g_value_unset (&val2);
g_value_unset (&tmp);
g_value_unset (&list1);
g_value_unset (&list2);
}
GST_END_TEST;
GST_START_TEST (test_date)
{
GstStructure *s;
GDate *date, *date2;
gchar *str;
date = g_date_new_dmy (22, 9, 2005);
s = gst_structure_new ("media/x-type", "SOME_DATE_TAG", G_TYPE_DATE,
date, NULL);
fail_unless (gst_structure_has_field_typed (s, "SOME_DATE_TAG", G_TYPE_DATE));
fail_unless (gst_structure_get_date (s, "SOME_DATE_TAG", &date2));
fail_unless (date2 != NULL);
fail_unless (g_date_valid (date2));
fail_unless (g_date_compare (date, date2) == 0);
g_date_free (date);
g_date_free (date2);
date = NULL;
date2 = NULL;
str = gst_structure_to_string (s);
gst_structure_free (s);
s = NULL;
fail_unless (g_str_equal (str,
"media/x-type, SOME_DATE_TAG=(date)2005-09-22;"));
s = gst_structure_from_string (str, NULL);
g_free (str);
str = NULL;
fail_unless (s != NULL);
fail_unless (gst_structure_has_name (s, "media/x-type"));
fail_unless (gst_structure_has_field_typed (s, "SOME_DATE_TAG", G_TYPE_DATE));
fail_unless (gst_structure_get_date (s, "SOME_DATE_TAG", &date));
fail_unless (date != NULL);
fail_unless (g_date_valid (date));
fail_unless (g_date_get_day (date) == 22);
fail_unless (g_date_get_month (date) == 9);
fail_unless (g_date_get_year (date) == 2005);
g_date_free (date);
date = NULL;
str = gst_structure_to_string (s);
gst_structure_free (s);
s = NULL;
fail_unless (g_str_equal (str,
"media/x-type, SOME_DATE_TAG=(date)2005-09-22;"));
g_free (str);
str = NULL;
}
GST_END_TEST;
static gboolean
date_time_equal (GstDateTime * a, GstDateTime * b)
{
if (gst_date_time_get_year (a) != gst_date_time_get_year (b) ||
gst_date_time_get_month (a) != gst_date_time_get_month (b) ||
gst_date_time_get_day (a) != gst_date_time_get_day (b))
return FALSE;
if (gst_date_time_get_hour (a) != gst_date_time_get_hour (b) ||
gst_date_time_get_minute (a) != gst_date_time_get_minute (b) ||
gst_date_time_get_second (a) != gst_date_time_get_second (b) ||
gst_date_time_get_microsecond (a) != gst_date_time_get_microsecond (b))
return FALSE;
if (gst_date_time_get_time_zone_offset (a) !=
gst_date_time_get_time_zone_offset (b))
return FALSE;
return TRUE;
}
GST_START_TEST (test_date_time)
{
GstStructure *s;
GstDateTime *datetime, *datetime2;
GValue val = { 0, };
gchar *str;
/* utc timezone */
datetime = gst_date_time_new (0, 2010, 6, 23, 7, 40, 10);
s = gst_structure_new ("media/x-type", "SOME_DATE_TIME_TAG",
GST_TYPE_DATE_TIME, datetime, NULL);
fail_unless (gst_structure_has_field_typed (s, "SOME_DATE_TIME_TAG",
GST_TYPE_DATE_TIME));
fail_unless (gst_structure_get_date_time (s, "SOME_DATE_TIME_TAG",
&datetime2));
fail_unless (datetime2 != NULL);
fail_unless (date_time_equal (datetime, datetime2));
gst_date_time_unref (datetime);
gst_date_time_unref (datetime2);
datetime = NULL;
datetime2 = NULL;
str = gst_structure_to_string (s);
gst_structure_free (s);
s = NULL;
fail_unless_equals_string (str,
"media/x-type, SOME_DATE_TIME_TAG=(datetime)2010-06-23T07:40:10Z;");
s = gst_structure_from_string (str, NULL);
g_free (str);
str = NULL;
fail_unless (s != NULL);
fail_unless (gst_structure_has_name (s, "media/x-type"));
fail_unless (gst_structure_has_field_typed (s, "SOME_DATE_TIME_TAG",
GST_TYPE_DATE_TIME));
fail_unless (gst_structure_get_date_time (s, "SOME_DATE_TIME_TAG",
&datetime));
fail_unless (datetime != NULL);
fail_unless (gst_date_time_get_year (datetime) == 2010);
fail_unless (gst_date_time_get_month (datetime) == 6);
fail_unless (gst_date_time_get_day (datetime) == 23);
fail_unless (gst_date_time_get_hour (datetime) == 7);
fail_unless (gst_date_time_get_minute (datetime) == 40);
fail_unless (gst_date_time_get_second (datetime) == 10);
fail_unless (gst_date_time_get_microsecond (datetime) == 0);
fail_unless (gst_date_time_get_time_zone_offset (datetime) == 0);
gst_date_time_unref (datetime);
datetime = NULL;
str = gst_structure_to_string (s);
gst_structure_free (s);
s = NULL;
fail_unless_equals_string (str,
"media/x-type, SOME_DATE_TIME_TAG=(datetime)2010-06-23T07:40:10Z;");
g_free (str);
str = NULL;
/* with timezone */
datetime = gst_date_time_new (-3.0, 2010, 6, 23, 7, 40, 10.000001);
s = gst_structure_new ("media/x-type", "SOME_DATE_TIME_TAG",
GST_TYPE_DATE_TIME, datetime, NULL);
fail_unless (gst_structure_has_field_typed (s, "SOME_DATE_TIME_TAG",
GST_TYPE_DATE_TIME));
fail_unless (gst_structure_get_date_time (s, "SOME_DATE_TIME_TAG",
&datetime2));
fail_unless (datetime2 != NULL);
fail_unless (date_time_equal (datetime, datetime2));
gst_date_time_unref (datetime);
gst_date_time_unref (datetime2);
datetime = NULL;
datetime2 = NULL;
str = gst_structure_to_string (s);
gst_structure_free (s);
s = NULL;
fail_unless_equals_string (str,
"media/x-type, SOME_DATE_TIME_TAG=(datetime)2010-06-23T07:40:10.000001-0300;");
s = gst_structure_from_string (str, NULL);
g_free (str);
str = NULL;
fail_unless (s != NULL);
fail_unless (gst_structure_has_name (s, "media/x-type"));
fail_unless (gst_structure_has_field_typed (s, "SOME_DATE_TIME_TAG",
GST_TYPE_DATE_TIME));
fail_unless (gst_structure_get_date_time (s, "SOME_DATE_TIME_TAG",
&datetime));
fail_unless (datetime != NULL);
fail_unless (gst_date_time_get_year (datetime) == 2010);
fail_unless (gst_date_time_get_month (datetime) == 6);
fail_unless (gst_date_time_get_day (datetime) == 23);
fail_unless (gst_date_time_get_hour (datetime) == 7);
fail_unless (gst_date_time_get_minute (datetime) == 40);
fail_unless (gst_date_time_get_second (datetime) == 10);
fail_unless (gst_date_time_get_microsecond (datetime) == 1);
fail_unless (gst_date_time_get_time_zone_offset (datetime) == -3);
gst_date_time_unref (datetime);
datetime = NULL;
str = gst_structure_to_string (s);
gst_structure_free (s);
s = NULL;
fail_unless_equals_string (str,
"media/x-type, SOME_DATE_TIME_TAG=(datetime)2010-06-23T07:40:10.000001-0300;");
g_free (str);
str = NULL;
/* with positive timezone */
datetime = gst_date_time_new (2.0, 2010, 6, 23, 7, 40, 10.000001);
s = gst_structure_new ("media/x-type", "SOME_DATE_TIME_TAG",
GST_TYPE_DATE_TIME, datetime, NULL);
fail_unless (gst_structure_has_field_typed (s, "SOME_DATE_TIME_TAG",
GST_TYPE_DATE_TIME));
fail_unless (gst_structure_get_date_time (s, "SOME_DATE_TIME_TAG",
&datetime2));
fail_unless (datetime2 != NULL);
fail_unless (date_time_equal (datetime, datetime2));
gst_date_time_unref (datetime);
gst_date_time_unref (datetime2);
datetime = NULL;
datetime2 = NULL;
str = gst_structure_to_string (s);
gst_structure_free (s);
s = NULL;
fail_unless_equals_string (str,
"media/x-type, SOME_DATE_TIME_TAG=(datetime)2010-06-23T07:40:10.000001+0200;");
s = gst_structure_from_string (str, NULL);
g_free (str);
str = NULL;
fail_unless (s != NULL);
fail_unless (gst_structure_has_name (s, "media/x-type"));
fail_unless (gst_structure_has_field_typed (s, "SOME_DATE_TIME_TAG",
GST_TYPE_DATE_TIME));
fail_unless (gst_structure_get_date_time (s, "SOME_DATE_TIME_TAG",
&datetime));
fail_unless (datetime != NULL);
fail_unless (gst_date_time_get_year (datetime) == 2010);
fail_unless (gst_date_time_get_month (datetime) == 6);
fail_unless (gst_date_time_get_day (datetime) == 23);
fail_unless (gst_date_time_get_hour (datetime) == 7);
fail_unless (gst_date_time_get_minute (datetime) == 40);
fail_unless (gst_date_time_get_second (datetime) == 10);
fail_unless (gst_date_time_get_microsecond (datetime) == 1);
fail_unless (gst_date_time_get_time_zone_offset (datetime) == 2);
gst_date_time_unref (datetime);
datetime = NULL;
str = gst_structure_to_string (s);
gst_structure_free (s);
s = NULL;
fail_unless_equals_string (str,
"media/x-type, SOME_DATE_TIME_TAG=(datetime)2010-06-23T07:40:10.000001+0200;");
g_free (str);
str = NULL;
/* test partial dates */
datetime = gst_date_time_new (0.0, 2010, -1, -1, -1, -1, -1.0);
g_value_init (&val, GST_TYPE_DATE_TIME);
g_value_take_boxed (&val, datetime);
str = gst_value_serialize (&val);
g_value_reset (&val);
fail_unless_equals_string (str, "2010");
fail_unless (gst_value_deserialize (&val, str));
datetime = g_value_get_boxed (&val);
fail_if (!gst_date_time_has_year (datetime));
fail_if (gst_date_time_has_month (datetime));
fail_if (gst_date_time_has_day (datetime));
fail_if (gst_date_time_has_time (datetime));
g_value_unset (&val);
g_free (str);
datetime = gst_date_time_new (0.0, 2010, 9, -1, -1, -1, -1.0);
g_value_init (&val, GST_TYPE_DATE_TIME);
g_value_take_boxed (&val, datetime);
str = gst_value_serialize (&val);
g_value_reset (&val);
fail_unless_equals_string (str, "2010-09");
fail_unless (gst_value_deserialize (&val, str));
datetime = g_value_get_boxed (&val);
fail_if (!gst_date_time_has_year (datetime));
fail_if (!gst_date_time_has_month (datetime));
fail_if (gst_date_time_has_day (datetime));
fail_if (gst_date_time_has_time (datetime));
g_value_unset (&val);
g_free (str);
datetime = gst_date_time_new (0.0, 1983, 11, 30, -1, -1, -1.0);
g_value_init (&val, GST_TYPE_DATE_TIME);
g_value_take_boxed (&val, datetime);
str = gst_value_serialize (&val);
g_value_reset (&val);
fail_unless_equals_string (str, "1983-11-30");
fail_unless (gst_value_deserialize (&val, str));
datetime = g_value_get_boxed (&val);
fail_if (!gst_date_time_has_year (datetime));
fail_if (!gst_date_time_has_month (datetime));
fail_if (!gst_date_time_has_day (datetime));
fail_if (gst_date_time_has_time (datetime));
g_value_unset (&val);
g_free (str);
datetime = gst_date_time_new (0.0, 1983, 11, 30, 3, 52, -1.0);
g_value_init (&val, GST_TYPE_DATE_TIME);
g_value_take_boxed (&val, datetime);
str = gst_value_serialize (&val);
g_value_reset (&val);
fail_unless_equals_string (str, "1983-11-30T03:52Z");
fail_unless (gst_value_deserialize (&val, str));
datetime = g_value_get_boxed (&val);
fail_if (!gst_date_time_has_year (datetime));
fail_if (!gst_date_time_has_month (datetime));
fail_if (!gst_date_time_has_day (datetime));
fail_if (!gst_date_time_has_time (datetime));
fail_if (gst_date_time_has_second (datetime));
fail_unless_equals_float (gst_date_time_get_time_zone_offset (datetime), 0.0);
g_value_unset (&val);
g_free (str);
datetime = gst_date_time_new (-4.5, 1983, 11, 30, 3, 52, -1.0);
g_value_init (&val, GST_TYPE_DATE_TIME);
g_value_take_boxed (&val, datetime);
str = gst_value_serialize (&val);
g_value_reset (&val);
fail_unless_equals_string (str, "1983-11-30T03:52-0430");
fail_unless (gst_value_deserialize (&val, str));
datetime = g_value_get_boxed (&val);
fail_if (!gst_date_time_has_year (datetime));
fail_if (!gst_date_time_has_month (datetime));
fail_if (!gst_date_time_has_day (datetime));
fail_if (!gst_date_time_has_time (datetime));
fail_if (gst_date_time_has_second (datetime));
fail_unless_equals_float (gst_date_time_get_time_zone_offset (datetime),
-4.5);
g_value_unset (&val);
g_free (str);
datetime = gst_date_time_new (4.5, 1983, 11, 30, 14, 52, 9);
g_value_init (&val, GST_TYPE_DATE_TIME);
g_value_take_boxed (&val, datetime);
str = gst_value_serialize (&val);
g_value_reset (&val);
fail_unless_equals_string (str, "1983-11-30T14:52:09+0430");
fail_unless (gst_value_deserialize (&val, str));
datetime = g_value_get_boxed (&val);
fail_if (!gst_date_time_has_year (datetime));
fail_if (!gst_date_time_has_month (datetime));
fail_if (!gst_date_time_has_day (datetime));
fail_if (!gst_date_time_has_time (datetime));
fail_if (!gst_date_time_has_second (datetime));
fail_unless_equals_float (gst_date_time_get_time_zone_offset (datetime), 4.5);
g_value_unset (&val);
g_free (str);
datetime = gst_date_time_new (-4.5, 1983, 11, 30, 14, 52, 9.702);
g_value_init (&val, GST_TYPE_DATE_TIME);
g_value_take_boxed (&val, datetime);
str = gst_value_serialize (&val);
g_value_reset (&val);
fail_unless_equals_string (str, "1983-11-30T14:52:09.702-0430");
fail_unless (gst_value_deserialize (&val, str));
datetime = g_value_get_boxed (&val);
fail_if (!gst_date_time_has_year (datetime));
fail_if (!gst_date_time_has_month (datetime));
fail_if (!gst_date_time_has_day (datetime));
fail_if (!gst_date_time_has_time (datetime));
fail_if (!gst_date_time_has_second (datetime));
fail_unless_equals_float (gst_date_time_get_time_zone_offset (datetime),
-4.5);
g_value_unset (&val);
g_free (str);
}
GST_END_TEST;
GST_START_TEST (test_fraction_range)
{
GValue range = { 0, };
GValue start = { 0, };
GValue end = { 0, };
GValue src = { 0, };
GValue 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;
GST_START_TEST (test_serialize_deserialize_format_enum)
{
GstStructure *s, *s2;
GstFormat foobar_fmt;
gchar *str, *str2, *end = NULL;
/* make sure custom formats are serialised properly as well */
foobar_fmt = gst_format_register ("foobar", "GST_FORMAT_FOOBAR");
fail_unless (foobar_fmt != GST_FORMAT_UNDEFINED);
s = gst_structure_new ("foo/bar", "format1", GST_TYPE_FORMAT,
GST_FORMAT_BYTES, "format2", GST_TYPE_FORMAT, GST_FORMAT_TIME,
"format3", GST_TYPE_FORMAT, GST_FORMAT_DEFAULT, "format4",
GST_TYPE_FORMAT, foobar_fmt, NULL);
str = gst_structure_to_string (s);
GST_LOG ("Got structure string '%s'", GST_STR_NULL (str));
fail_unless (str != NULL);
fail_unless (strstr (str, "TIME") != NULL);
fail_unless (strstr (str, "BYTE") != NULL);
fail_unless (strstr (str, "DEFAULT") != NULL);
fail_unless (strstr (str, "FOOBAR") != NULL);
s2 = gst_structure_from_string (str, &end);
fail_unless (s2 != NULL);
str2 = gst_structure_to_string (s2);
fail_unless (str2 != NULL);
fail_unless (g_str_equal (str, str2));
g_free (str);
g_free (str2);
gst_structure_free (s);
gst_structure_free (s2);
}
GST_END_TEST;
GST_START_TEST (test_serialize_deserialize_caps)
{
GValue value = { 0 }
, value2 = {
0};
GstCaps *caps, *caps2;
GstCaps *incaps;
gchar *serialized;
incaps = gst_caps_new_simple ("caps/internal",
"in-field", G_TYPE_INT, 20, "in-field2",
G_TYPE_STRING, "some in ternal field", NULL);
caps = gst_caps_new_simple ("test/caps",
"foo", G_TYPE_INT, 10, "bar", G_TYPE_STRING, "test",
"int-caps", GST_TYPE_CAPS, incaps, NULL);
fail_if (GST_CAPS_REFCOUNT_VALUE (caps) != 1);
gst_caps_unref (incaps);
/* and assign caps to gvalue */
g_value_init (&value, GST_TYPE_CAPS);
g_value_take_boxed (&value, caps);
fail_if (GST_CAPS_REFCOUNT_VALUE (caps) != 1);
/* now serialize it */
serialized = gst_value_serialize (&value);
GST_DEBUG ("serialized caps to %s", serialized);
fail_unless (serialized != NULL);
/* refcount should not change */
fail_if (GST_CAPS_REFCOUNT_VALUE (caps) != 1);
/* now deserialize again */
g_value_init (&value2, GST_TYPE_CAPS);
gst_value_deserialize (&value2, serialized);
caps2 = g_value_get_boxed (&value2);
fail_if (GST_CAPS_REFCOUNT_VALUE (caps2) != 1);
/* they should be equal */
fail_unless (gst_caps_is_equal (caps, caps2));
/* cleanup */
g_value_unset (&value);
g_value_unset (&value2);
g_free (serialized);
}
GST_END_TEST;
GST_START_TEST (test_int_range)
{
GValue range = { 0, };
GValue start = { 0, };
GValue end = { 0, };
GValue src = { 0, };
GValue dest = { 0, };
GValue range2 = { 0, };
g_value_init (&range, GST_TYPE_INT_RANGE);
g_value_init (&range2, GST_TYPE_INT_RANGE);
g_value_init (&start, G_TYPE_INT);
g_value_init (&end, G_TYPE_INT);
g_value_init (&src, G_TYPE_INT);
g_value_set_int (&src, 2);
/* Check that a intersection of int & range = int */
gst_value_set_int_range (&range, 1, 5);
fail_unless (gst_value_intersect (&dest, &src, &range) == TRUE);
fail_unless (G_VALUE_TYPE (&dest) == G_TYPE_INT);
fail_unless (gst_value_compare (&dest, &src) == GST_VALUE_EQUAL);
/* Check that a intersection selects the overlapping range */
gst_value_set_int_range (&range2, 2, 3);
g_value_unset (&dest);
fail_unless (gst_value_intersect (&dest, &range, &range2) == TRUE);
fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT_RANGE);
fail_unless (gst_value_compare (&dest, &range2) == GST_VALUE_EQUAL);
/* Check that non intersection ranges don't intersect */
gst_value_set_int_range (&range2, 6, 7);
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;
GST_START_TEST (test_int64_range)
{
GValue range = { 0, };
GValue start = { 0, };
GValue end = { 0, };
GValue src = { 0, };
GValue dest = { 0, };
GValue range2 = { 0, };
g_value_init (&range, GST_TYPE_INT64_RANGE);
g_value_init (&range2, GST_TYPE_INT64_RANGE);
g_value_init (&start, G_TYPE_INT64);
g_value_init (&end, G_TYPE_INT64);
g_value_init (&src, G_TYPE_INT64);
g_value_set_int64 (&src, 2);
/* Check that a intersection of int64 & range = int64 */
gst_value_set_int64_range (&range, 1, 5);
fail_unless (gst_value_intersect (&dest, &src, &range) == TRUE);
fail_unless (G_VALUE_TYPE (&dest) == G_TYPE_INT64);
fail_unless (gst_value_compare (&dest, &src) == GST_VALUE_EQUAL);
/* Check that a intersection selects the overlapping range */
gst_value_set_int64_range (&range2, 2, 3);
g_value_unset (&dest);
fail_unless (gst_value_intersect (&dest, &range, &range2) == TRUE);
fail_unless (G_VALUE_TYPE (&dest) == GST_TYPE_INT64_RANGE);
fail_unless (gst_value_compare (&dest, &range2) == GST_VALUE_EQUAL);
/* Check that non intersection ranges don't intersect */
gst_value_set_int64_range (&range2, 6, 7);
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;
GST_START_TEST (test_serialize_int64_range)
{
int i = 0;
gint64 int64_ranges[] = {
0, 5,
0, G_MAXINT,
5, G_MAXINT32,
5, G_MAXINT64,
};
gint int64_ranges_size = sizeof (int64_ranges) / sizeof (int64_ranges[0]) / 2;
gchar *int64_range_strings[] = {
g_strdup ("[ 0, 5 ]"),
g_strdup_printf ("[ 0, %" G_GINT64_FORMAT " ]", (gint64) G_MAXINT),
g_strdup_printf ("[ 5, %" G_GINT64_FORMAT " ]", (gint64) G_MAXINT32),
g_strdup_printf ("[ 5, %" G_GINT64_FORMAT " ]", G_MAXINT64),
};
gint int64_range_strings_size =
sizeof (int64_range_strings) / sizeof (int64_range_strings[0]);
fail_unless (int64_ranges_size == int64_range_strings_size);
while (i + 1 < (int64_ranges_size * 2)) {
if ((i + 1) % 2) {
gchar *str;
gchar *str2;
GValue value = { 0 };
const GValue *deserialized_value;
int idx = i / 2;
GstStructure *s;
g_value_init (&value, GST_TYPE_INT64_RANGE);
/* check serialization */
gst_value_set_int64_range (&value, int64_ranges[i], int64_ranges[i + 1]);
str = gst_value_serialize (&value);
fail_unless (strcmp (str, int64_range_strings[idx]) == 0);
g_free (int64_range_strings[idx]);
g_value_unset (&value);
/* now deserialize again to an int64 range */
s = gst_structure_new ("foo/bar", "range", GST_TYPE_INT64_RANGE,
int64_ranges[i], int64_ranges[i + 1], NULL);
deserialized_value = gst_structure_get_value (s, "range");
fail_unless (GST_VALUE_HOLDS_INT64_RANGE (deserialized_value) == TRUE);
str2 = gst_value_serialize (deserialized_value);
fail_unless (gst_value_get_int64_range_min (deserialized_value) ==
int64_ranges[i]);
fail_unless (gst_value_get_int64_range_max (deserialized_value) ==
int64_ranges[i + 1]);
gst_structure_free (s);
g_free (str);
g_free (str2);
}
i++;
}
}
GST_END_TEST;
GST_START_TEST (test_deserialize_int_range)
{
GstStructure *s;
gchar *str, *str2;
gchar *end = NULL;
const GValue *deserialized_value;
/* check a valid int_range deserialization */
str = g_strdup_printf ("foo/bar, range=[ 1, %d ];", G_MAXINT);
s = gst_structure_from_string (str, &end);
fail_unless (*end == '\0');
deserialized_value = gst_structure_get_value (s, "range");
fail_unless (GST_VALUE_HOLDS_INT_RANGE (deserialized_value) == TRUE);
fail_unless (gst_value_get_int_range_min (deserialized_value) == 1);
fail_unless (gst_value_get_int_range_max (deserialized_value) == G_MAXINT);
gst_structure_free (s);
end = NULL;
g_free (str);
/* check invalid int_range deserialization */
str =
g_strdup_printf ("foo/bar, range=[ 1, %" G_GINT64_FORMAT " ];",
(gint64) G_MAXINT + 1);
ASSERT_CRITICAL (s = gst_structure_from_string (str, &end));
g_free (str);
gst_structure_free (s);
str =
g_strdup_printf ("foo/bar, range=[ %" G_GINT64_FORMAT ", %"
G_GINT64_FORMAT " ];", (gint64) G_MAXINT, (gint64) G_MAXINT + 1);
ASSERT_CRITICAL (s = gst_structure_from_string (str, NULL));
end = NULL;
g_free (str);
gst_structure_free (s);
/* check a valid int64_range deserialization. Those ranges need to
* be explicit about their storage type. */
str = g_strdup_printf ("foo/bar, range=(gint64)[ 1, %d ];", G_MAXINT);
s = gst_structure_from_string (str, &end);
fail_unless (*end == '\0');
deserialized_value = gst_structure_get_value (s, "range");
fail_unless (GST_VALUE_HOLDS_INT64_RANGE (deserialized_value) == TRUE);
fail_unless (gst_value_get_int64_range_min (deserialized_value) == 1);
fail_unless (gst_value_get_int64_range_max (deserialized_value) == G_MAXINT);
str2 = gst_structure_to_string (s);
fail_unless (strcmp (str, str2) == 0);
gst_structure_free (s);
end = NULL;
g_free (str);
g_free (str2);
/* check invalid int64_range (starting with a gint) deserialization */
str =
g_strdup_printf ("foo/bar, range=(gint64)[ 1, %" G_GUINT64_FORMAT " ];",
(guint64) G_MAXINT64 + 1);
ASSERT_CRITICAL (s = gst_structure_from_string (str, &end));
fail_unless (*end == '\0');
gst_structure_free (s);
end = NULL;
g_free (str);
/* check invalid int64_range deserialization into a int64_range */
str =
g_strdup_printf ("foo/bar, range=(gint64)[ %" G_GINT64_FORMAT ", %"
G_GUINT64_FORMAT " ];", (gint64) G_MAXINT, (guint64) G_MAXINT64 + 1);
ASSERT_CRITICAL (s = gst_structure_from_string (str, NULL));
g_free (str);
gst_structure_free (s);
/* check invalid int64_range deserialization into a int_range */
str =
g_strdup_printf ("foo/bar, range=[ %" G_GINT64_FORMAT ", %"
G_GUINT64_FORMAT " ];", (gint64) G_MAXINT, (guint64) G_MAXINT64 + 1);
s = gst_structure_from_string (str, &end);
fail_unless (s == NULL);
fail_unless (end == NULL);
g_free (str);
}
GST_END_TEST;
GST_START_TEST (test_stepped_range_collection)
{
GstStructure *s;
const GValue *v;
s = gst_structure_new ("foo/bar", "range", GST_TYPE_INT_RANGE, 8, 12, NULL);
fail_unless (s != NULL);
v = gst_structure_get_value (s, "range");
fail_unless (v != NULL);
fail_unless (gst_value_get_int_range_min (v) == 8);
fail_unless (gst_value_get_int_range_max (v) == 12);
fail_unless (gst_value_get_int_range_step (v) == 1);
gst_structure_free (s);
s = gst_structure_new ("foo/bar", "range", GST_TYPE_INT64_RANGE, (gint64) 8,
(gint64) 12, NULL);
fail_unless (s != NULL);
v = gst_structure_get_value (s, "range");
fail_unless (v != NULL);
fail_unless (gst_value_get_int64_range_min (v) == 8);
fail_unless (gst_value_get_int64_range_max (v) == 12);
fail_unless (gst_value_get_int64_range_step (v) == 1);
gst_structure_free (s);
}
GST_END_TEST;
GST_START_TEST (test_stepped_int_range_parsing)
{
gchar *str;
guint n;
gchar *end = NULL;
GstStructure *s;
static const gchar *good_ranges[] = {
"[0, 1, 1]",
"[-2, 2, 2]",
"[16, 4096, 16]",
};
static const gchar *bad_ranges[] = {
"[0, 1, -1]",
"[1, 2, 2]",
"[2, 3, 2]",
"[0, 0, 0]",
};
/* check we can parse good ranges */
for (n = 0; n < G_N_ELEMENTS (good_ranges); ++n) {
str = g_strdup_printf ("foo/bar, range=%s", good_ranges[n]);
s = gst_structure_from_string (str, &end);
fail_unless (s != NULL);
fail_unless (*end == '\0');
gst_structure_free (s);
g_free (str);
}
/* check we cannot parse bad ranges */
for (n = 0; n < G_N_ELEMENTS (bad_ranges); ++n) {
str = g_strdup_printf ("foo/bar, range=%s", bad_ranges[n]);
ASSERT_CRITICAL (s = gst_structure_from_string (str, &end));
gst_structure_free (s);
g_free (str);
}
}
GST_END_TEST;
GST_START_TEST (test_stepped_int_range_ops)
{
gchar *str1, *str2, *str3;
guint n;
GstStructure *s1, *s2, *s3;
const GValue *v1, *v2, *v3;
static const struct
{
const gchar *set1;
const gchar *op;
const gchar *set2;
const gchar *result;
} ranges[] = {
{
"[16, 4096, 16]", "inter", "[100, 200, 10]", "160"}, {
"[16, 4096, 16]", "inter", "[100, 200, 100]", NULL}, {
"[16, 4096, 16]", "inter", "[0, 512, 256]", "[256, 512, 256]"}, {
"[16, 32, 16]", "union", "[32, 96, 16]", "[16, 96, 16]"}, {
"[16, 32, 16]", "union", "[48, 96, 16]", "[16, 96, 16]"}, {
"[112, 192, 16]", "union", "[48, 96, 16]", "[48, 192, 16]"}, {
"[16, 32, 16]", "union", "[64, 96, 16]", NULL}, {
"[112, 192, 16]", "union", "[48, 96, 8]", NULL},};
for (n = 0; n < G_N_ELEMENTS (ranges); ++n) {
gchar *end = NULL;
GValue dest = { 0 };
gboolean ret;
str1 = g_strdup_printf ("foo/bar, range=%s", ranges[n].set1);
s1 = gst_structure_from_string (str1, &end);
fail_unless (s1 != NULL);
fail_unless (*end == '\0');
v1 = gst_structure_get_value (s1, "range");
fail_unless (v1 != NULL);
str2 = g_strdup_printf ("foo/bar, range=%s", ranges[n].set2);
s2 = gst_structure_from_string (str2, &end);
fail_unless (s2 != NULL);
fail_unless (*end == '\0');
v2 = gst_structure_get_value (s2, "range");
fail_unless (v2 != NULL);
if (!strcmp (ranges[n].op, "inter")) {
ret = gst_value_intersect (&dest, v1, v2);
} else if (!strcmp (ranges[n].op, "union")) {
ret = gst_value_union (&dest, v1, v2);
} else {
fail_unless (FALSE);
ret = FALSE;
}
if (ranges[n].result) {
fail_unless (ret);
} else {
fail_unless (!ret);
}
if (ret) {
str3 = g_strdup_printf ("foo/bar, range=%s", ranges[n].result);
s3 = gst_structure_from_string (str3, &end);
fail_unless (s3 != NULL);
fail_unless (*end == '\0');
v3 = gst_structure_get_value (s3, "range");
fail_unless (v3 != NULL);
if (gst_value_compare (&dest, v3) != GST_VALUE_EQUAL) {
GST_ERROR ("%s %s %s yielded %s, expected %s", str1, ranges[n].op, str2,
gst_value_serialize (&dest), gst_value_serialize (v3));
fail_unless (FALSE);
}
gst_structure_free (s3);
g_free (str3);
g_value_unset (&dest);
}
gst_structure_free (s2);
g_free (str2);
gst_structure_free (s1);
g_free (str1);
}
}
GST_END_TEST;
static Suite *
gst_value_suite (void)
{
Suite *s = suite_create ("GstValue");
TCase *tc_chain = tcase_create ("general");
suite_add_tcase (s, tc_chain);
tcase_add_test (tc_chain, test_deserialize_buffer);
tcase_add_test (tc_chain, test_serialize_buffer);
tcase_add_test (tc_chain, test_deserialize_gint);
tcase_add_test (tc_chain, test_deserialize_gint_failures);
tcase_add_test (tc_chain, test_deserialize_guint);
tcase_add_test (tc_chain, test_deserialize_guint_failures);
tcase_add_test (tc_chain, test_deserialize_gint64);
tcase_add_test (tc_chain, test_deserialize_guint64);
tcase_add_test (tc_chain, test_deserialize_guchar);
tcase_add_test (tc_chain, test_deserialize_gstfraction);
tcase_add_test (tc_chain, test_deserialize_bitmask);
tcase_add_test (tc_chain, test_serialize_flags);
tcase_add_test (tc_chain, test_deserialize_flags);
tcase_add_test (tc_chain, test_serialize_deserialize_format_enum);
tcase_add_test (tc_chain, test_string);
tcase_add_test (tc_chain, test_deserialize_string);
tcase_add_test (tc_chain, test_value_compare);
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_int64);
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_value_subtract_fraction_list);
tcase_add_test (tc_chain, test_date);
tcase_add_test (tc_chain, test_date_time);
tcase_add_test (tc_chain, test_fraction_range);
tcase_add_test (tc_chain, test_serialize_deserialize_caps);
tcase_add_test (tc_chain, test_int_range);
tcase_add_test (tc_chain, test_int64_range);
tcase_add_test (tc_chain, test_serialize_int64_range);
tcase_add_test (tc_chain, test_deserialize_int_range);
tcase_add_test (tc_chain, test_stepped_range_collection);
tcase_add_test (tc_chain, test_stepped_int_range_parsing);
tcase_add_test (tc_chain, test_stepped_int_range_ops);
return s;
}
GST_CHECK_MAIN (gst_value);