mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-19 08:11:16 +00:00
1335110409
We won't be able to do ASSERT_CRITICAL, but the main body of the tests are still valid, and given we ship GStreamer with this configuration, it is important to be able to run some tests against it.
924 lines
28 KiB
C
924 lines
28 KiB
C
/* GStreamer
|
|
* Copyright (C) <2005> Thomas Vander Stichele <thomas at apestaart dot org>
|
|
*
|
|
* gststructure.c: Unit tests for GstStructure
|
|
*
|
|
* 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.
|
|
*/
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
#include <gst/gststructure.h>
|
|
#include <gst/check/gstcheck.h>
|
|
|
|
|
|
GST_START_TEST (test_from_string_int)
|
|
{
|
|
const char *strings[] = {
|
|
"video/x-raw, width = (int) 123456",
|
|
"video/x-raw, stride = (int) -123456",
|
|
"video/x-raw, red_mask = (int) 0xFFFF",
|
|
"video/x-raw, red_mask = (int) 0x0000FFFF",
|
|
"video/x-raw, red_mask = (int) 0x7FFFFFFF",
|
|
"video/x-raw, red_mask = (int) 0x80000000",
|
|
"video/x-raw, red_mask = (int) 0xFF000000",
|
|
/* result from
|
|
* gst-launch ... ! "video/x-raw, red_mask=(int)0xFF000000" ! ... */
|
|
"video/x-raw,\\ red_mask=(int)0xFF000000",
|
|
};
|
|
gint results[] = {
|
|
123456,
|
|
-123456,
|
|
0xFFFF,
|
|
0xFFFF,
|
|
0x7FFFFFFF,
|
|
(gint) 0x80000000,
|
|
(gint) 0xFF000000,
|
|
(gint) 0xFF000000,
|
|
};
|
|
GstStructure *structure;
|
|
int i;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
|
|
const char *s;
|
|
const gchar *name;
|
|
gint value;
|
|
|
|
s = strings[i];
|
|
|
|
structure = gst_structure_from_string (s, NULL);
|
|
fail_if (structure == NULL, "Could not get structure from string %s", s);
|
|
name = gst_structure_nth_field_name (structure, 0);
|
|
fail_unless (gst_structure_get_int (structure, name, &value));
|
|
fail_unless (value == results[i],
|
|
"Value %d is not the expected result %d for string %s",
|
|
value, results[i], s);
|
|
|
|
/* cleanup */
|
|
gst_structure_free (structure);
|
|
}
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_from_string_uint)
|
|
{
|
|
const char *strings[] = {
|
|
"taglist, bar = (uint) 123456",
|
|
"taglist, bar = (uint) 0xFFFF",
|
|
"taglist, bar = (uint) 0x0000FFFF",
|
|
"taglist, bar = (uint) 0x7FFFFFFF",
|
|
"taglist, bar = (uint) 0x80000000",
|
|
"taglist, bar = (uint) 0xFF000000"
|
|
};
|
|
guint results[] = {
|
|
123456,
|
|
0xFFFF,
|
|
0xFFFF,
|
|
0x7FFFFFFF,
|
|
0x80000000,
|
|
0xFF000000,
|
|
};
|
|
GstStructure *structure;
|
|
int i;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
|
|
const char *s;
|
|
const gchar *name;
|
|
guint value;
|
|
|
|
s = strings[i];
|
|
|
|
structure = gst_structure_from_string (s, NULL);
|
|
fail_if (structure == NULL, "Could not get structure from string %s", s);
|
|
name = gst_structure_nth_field_name (structure, 0);
|
|
fail_unless (gst_structure_get_uint (structure, name, &value));
|
|
fail_unless (value == results[i],
|
|
"Value %u is not the expected result %u for string %s",
|
|
value, results[i], s);
|
|
|
|
/* cleanup */
|
|
gst_structure_free (structure);
|
|
}
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
/* Test type conversions from string */
|
|
GST_START_TEST (test_from_string)
|
|
{
|
|
GstStructure *structure;
|
|
const gchar *s;
|
|
const GValue *val;
|
|
|
|
s = "test-string,value=1";
|
|
structure = gst_structure_from_string (s, NULL);
|
|
fail_if (structure == NULL, "Could not get structure from string %s", s);
|
|
fail_unless ((val = gst_structure_get_value (structure, "value")) != NULL);
|
|
fail_unless (G_VALUE_HOLDS_INT (val));
|
|
gst_structure_free (structure);
|
|
|
|
s = "test-string,value=1.0";
|
|
structure = gst_structure_from_string (s, NULL);
|
|
fail_if (structure == NULL, "Could not get structure from string %s", s);
|
|
fail_unless ((val = gst_structure_get_value (structure, "value")) != NULL);
|
|
fail_unless (G_VALUE_HOLDS_DOUBLE (val));
|
|
gst_structure_free (structure);
|
|
|
|
s = "test-string,value=1/1";
|
|
structure = gst_structure_from_string (s, NULL);
|
|
fail_if (structure == NULL, "Could not get structure from string %s", s);
|
|
fail_unless ((val = gst_structure_get_value (structure, "value")) != NULL);
|
|
fail_unless (GST_VALUE_HOLDS_FRACTION (val));
|
|
gst_structure_free (structure);
|
|
|
|
s = "test-string,value=bar";
|
|
structure = gst_structure_from_string (s, NULL);
|
|
fail_if (structure == NULL, "Could not get structure from string %s", s);
|
|
fail_unless ((val = gst_structure_get_value (structure, "value")) != NULL);
|
|
fail_unless (G_VALUE_HOLDS_STRING (val));
|
|
gst_structure_free (structure);
|
|
|
|
s = "test-string,value=true";
|
|
structure = gst_structure_from_string (s, NULL);
|
|
fail_if (structure == NULL, "Could not get structure from string %s", s);
|
|
fail_unless ((val = gst_structure_get_value (structure, "value")) != NULL);
|
|
fail_unless (G_VALUE_HOLDS_BOOLEAN (val));
|
|
fail_unless_equals_int (g_value_get_boolean (val), TRUE);
|
|
gst_structure_free (structure);
|
|
|
|
/* Tests for flagset deserialisation */
|
|
s = "foobar,value=0010:ffff";
|
|
structure = gst_structure_from_string (s, NULL);
|
|
fail_if (structure == NULL, "Could not get structure from string %s", s);
|
|
fail_unless ((val = gst_structure_get_value (structure, "value")) != NULL);
|
|
fail_unless (GST_VALUE_HOLDS_FLAG_SET (val));
|
|
gst_structure_free (structure);
|
|
|
|
/* In the presence of the hex values, the strings don't matter as long as they
|
|
* have the right form */
|
|
s = "foobar,value=0010:ffff:+random+other/not-the-other";
|
|
structure = gst_structure_from_string (s, NULL);
|
|
fail_if (structure == NULL, "Could not get structure from string %s", s);
|
|
fail_unless ((val = gst_structure_get_value (structure, "value")) != NULL);
|
|
fail_unless (GST_VALUE_HOLDS_FLAG_SET (val));
|
|
gst_structure_free (structure);
|
|
|
|
/* Test that a timecode string is deserialised as a string, not a flagset:
|
|
* https://bugzilla.gnome.org/show_bug.cgi?id=779755 */
|
|
s = "foobar,timecode=00:01:00:00";
|
|
structure = gst_structure_from_string (s, NULL);
|
|
fail_if (structure == NULL, "Could not get structure from string %s", s);
|
|
fail_unless ((val = gst_structure_get_value (structure, "timecode")) != NULL);
|
|
fail_unless (G_VALUE_HOLDS_STRING (val));
|
|
gst_structure_free (structure);
|
|
|
|
s = "0.10:decoder-video/mpeg, abc=(boolean)false";
|
|
structure = NULL;
|
|
ASSERT_CRITICAL (structure = gst_structure_from_string (s, NULL));
|
|
fail_unless (structure == NULL, "Could not get structure from string %s", s);
|
|
|
|
/* make sure we bail out correctly in case of an error or if parsing fails */
|
|
s = "***foo***, abc=(boolean)false";
|
|
structure = gst_structure_from_string (s, NULL);
|
|
fail_unless (structure == NULL);
|
|
|
|
/* assert that we get a warning if the structure wasn't entirely consumed, but
|
|
* we didn't provide an end pointer */
|
|
s = "foo/bar; other random data";
|
|
ASSERT_WARNING (structure = gst_structure_from_string (s, NULL));
|
|
fail_if (structure == NULL, "Could not get structure from string %s", s);
|
|
gst_structure_free (structure);
|
|
|
|
/* make sure we handle \ as last character in various things, run with valgrind */
|
|
s = "foo,test=\"foobar\\";
|
|
structure = gst_structure_from_string (s, NULL);
|
|
fail_unless (structure == NULL);
|
|
s = "\\";
|
|
structure = gst_structure_from_string (s, NULL);
|
|
fail_unless (structure == NULL);
|
|
s = "foobar,test\\";
|
|
structure = gst_structure_from_string (s, NULL);
|
|
fail_unless (structure == NULL);
|
|
s = "foobar,test=(string)foo\\";
|
|
structure = gst_structure_from_string (s, NULL);
|
|
fail_unless (structure == NULL);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
|
|
GST_START_TEST (test_to_string)
|
|
{
|
|
GstStructure *st1 = NULL;
|
|
|
|
ASSERT_CRITICAL (st1 = gst_structure_new_empty ("Foo\nwith-newline"));
|
|
fail_unless (st1 == NULL);
|
|
|
|
ASSERT_CRITICAL (st1 = gst_structure_new_empty ("Foo with whitespace"));
|
|
fail_unless (st1 == NULL);
|
|
ASSERT_CRITICAL (st1 = gst_structure_new_empty ("1st"));
|
|
fail_unless (st1 == NULL);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
|
|
GST_START_TEST (test_to_from_string)
|
|
{
|
|
GstStructure *st1, *st2;
|
|
gchar *str;
|
|
|
|
/* test escaping/unescaping */
|
|
st1 = gst_structure_new ("FooBar-123/0_1", "num", G_TYPE_INT, 9173,
|
|
"string", G_TYPE_STRING, "Something Like Face/Off", NULL);
|
|
str = gst_structure_to_string (st1);
|
|
st2 = gst_structure_from_string (str, NULL);
|
|
g_free (str);
|
|
|
|
fail_unless (st2 != NULL);
|
|
fail_unless (gst_structure_is_equal (st1, st2),
|
|
"Structures did not match:\n\tStructure 1: %" GST_PTR_FORMAT
|
|
"\n\tStructure 2: %" GST_PTR_FORMAT "\n", st1, st2);
|
|
|
|
gst_structure_free (st1);
|
|
gst_structure_free (st2);
|
|
|
|
/* Test NULL strings */
|
|
st1 = gst_structure_new ("test", "mynullstr", G_TYPE_STRING, NULL, NULL);
|
|
fail_unless (st1 != NULL);
|
|
str = gst_structure_to_string (st1);
|
|
fail_unless (strcmp (str, "test, mynullstr=(string)NULL;") == 0,
|
|
"Failed to serialize to right string: %s", str);
|
|
|
|
st2 = gst_structure_from_string (str, NULL);
|
|
fail_unless (st2 != NULL);
|
|
g_free (str);
|
|
|
|
fail_unless (gst_structure_is_equal (st1, st2),
|
|
"Structures did not match:\n\tStructure 1: %" GST_PTR_FORMAT
|
|
"\n\tStructure 2: %" GST_PTR_FORMAT "\n", st1, st2);
|
|
|
|
gst_structure_free (st1);
|
|
gst_structure_free (st2);
|
|
|
|
/* pointers are serialized but not deserialized */
|
|
st1 = gst_structure_new ("test", "ptr", G_TYPE_POINTER, 0xdeadbeef, NULL);
|
|
str = gst_structure_to_string (st1);
|
|
/* The way pointers are serialized may be plateform specific so just check
|
|
* if it contains the address */
|
|
fail_unless (g_strrstr (str, "deadbeef") || g_strrstr (str, "DEADBEEF"),
|
|
"Failed to serialize to right string: %s", str);
|
|
|
|
st2 = gst_structure_from_string (str, NULL);
|
|
fail_unless (!st2);
|
|
|
|
gst_structure_free (st1);
|
|
g_free (str);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
/* Added to make sure taglists are properly serialized/deserialized after bug
|
|
* https://bugzilla.gnome.org/show_bug.cgi?id=733131 */
|
|
GST_START_TEST (test_to_from_string_tag_event)
|
|
{
|
|
GstEvent *tagevent;
|
|
GstTagList *taglist;
|
|
GstStructure *st1, *st2;
|
|
gchar *str;
|
|
|
|
/* empty taglist */
|
|
taglist = gst_tag_list_new_empty ();
|
|
tagevent = gst_event_new_tag (taglist);
|
|
|
|
st1 = (GstStructure *) gst_event_get_structure (tagevent);
|
|
str = gst_structure_to_string (st1);
|
|
fail_unless (str != NULL);
|
|
|
|
st2 = gst_structure_new_from_string (str);
|
|
fail_unless (st2 != NULL);
|
|
fail_unless (gst_structure_is_equal (st1, st2));
|
|
gst_event_unref (tagevent);
|
|
gst_structure_free (st2);
|
|
g_free (str);
|
|
|
|
/* taglist with data */
|
|
taglist = gst_tag_list_new ("title", "TEST TITLE", NULL);
|
|
tagevent = gst_event_new_tag (taglist);
|
|
|
|
st1 = (GstStructure *) gst_event_get_structure (tagevent);
|
|
str = gst_structure_to_string (st1);
|
|
fail_unless (str != NULL);
|
|
|
|
st2 = gst_structure_new_from_string (str);
|
|
fail_unless (st2 != NULL);
|
|
fail_unless (gst_structure_is_equal (st1, st2));
|
|
gst_event_unref (tagevent);
|
|
gst_structure_free (st2);
|
|
g_free (str);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_complete_structure)
|
|
{
|
|
GstStructure *structure;
|
|
const gchar *s;
|
|
|
|
s = "GstEventSeek, rate=(double)1, format=(GstFormat)GST_FORMAT_TIME, flags=(GstSeekFlags)GST_SEEK_FLAG_NONE, start_type=(GstSeekType)GST_SEEK_TYPE_SET, start=(gint64)1000000000, stop_type=(GstSeekType)GST_SEEK_TYPE_NONE, stop=(gint64)0";
|
|
structure = gst_structure_from_string (s, NULL);
|
|
fail_if (structure == NULL, "Could not get structure from string %s", s);
|
|
/* FIXME: TODO: add checks for correct serialization of members ? */
|
|
gst_structure_free (structure);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_string_properties)
|
|
{
|
|
GstStructure *st1, *st2;
|
|
gchar *str;
|
|
|
|
/* test escaping/unescaping */
|
|
st1 = gst_structure_new ("RandomStructure", "prop1", G_TYPE_STRING, "foo",
|
|
"prop2", G_TYPE_STRING, "", "prop3", G_TYPE_STRING, NULL,
|
|
"prop4", G_TYPE_STRING, "NULL", NULL);
|
|
str = gst_structure_to_string (st1);
|
|
st2 = gst_structure_from_string (str, NULL);
|
|
g_free (str);
|
|
|
|
fail_unless (st2 != NULL);
|
|
fail_unless (gst_structure_is_equal (st1, st2),
|
|
"Structures did not match:\n\tStructure 1: %" GST_PTR_FORMAT
|
|
"\n\tStructure 2: %" GST_PTR_FORMAT "\n", st1, st2);
|
|
|
|
gst_structure_free (st1);
|
|
gst_structure_free (st2);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_structure_new)
|
|
{
|
|
GstStructure *s;
|
|
GError *e;
|
|
GQuark domain;
|
|
gboolean bool;
|
|
gint num, den;
|
|
GstClockTime clocktime;
|
|
guint64 uint64;
|
|
|
|
s = gst_structure_new ("name",
|
|
"key", G_TYPE_STRING, "value",
|
|
"bool", G_TYPE_BOOLEAN, TRUE,
|
|
"fraction", GST_TYPE_FRACTION, 1, 5,
|
|
"clocktime", GST_TYPE_CLOCK_TIME, GST_CLOCK_TIME_NONE,
|
|
"uint64", G_TYPE_UINT64, (guint64) 1234, NULL);
|
|
|
|
fail_unless (gst_structure_get_field_type (s, "unknown") == G_TYPE_INVALID);
|
|
/* test setting a different name */
|
|
gst_structure_set_name (s, "newname");
|
|
fail_unless (strcmp (gst_structure_get_string (s, "key"), "value") == 0);
|
|
fail_unless (gst_structure_has_field (s, "key"));
|
|
fail_unless_equals_int (gst_structure_n_fields (s), 5);
|
|
/* test removing a field */
|
|
gst_structure_remove_field (s, "key");
|
|
fail_if (gst_structure_get_string (s, "key"));
|
|
fail_if (gst_structure_has_field (s, "key"));
|
|
fail_unless_equals_int (gst_structure_n_fields (s), 4);
|
|
|
|
fail_unless (gst_structure_get_boolean (s, "bool", &bool));
|
|
fail_unless (bool);
|
|
|
|
fail_unless (gst_structure_get_fraction (s, "fraction", &num, &den));
|
|
fail_unless_equals_int (num, 1);
|
|
fail_unless_equals_int (den, 5);
|
|
|
|
fail_unless (gst_structure_get_clock_time (s, "clocktime", &clocktime));
|
|
fail_unless_equals_uint64 (clocktime, GST_CLOCK_TIME_NONE);
|
|
|
|
fail_unless (gst_structure_get_uint64 (s, "uint64", &uint64));
|
|
fail_unless_equals_uint64 (uint64, 1234);
|
|
|
|
gst_structure_free (s);
|
|
|
|
domain = g_quark_from_static_string ("test");
|
|
e = g_error_new (domain, 0, "a test error");
|
|
s = gst_structure_new ("name", "key", G_TYPE_ERROR, e, NULL);
|
|
g_error_free (e);
|
|
gst_structure_free (s);
|
|
|
|
ASSERT_CRITICAL (gst_structure_free (gst_structure_new_empty
|
|
("0.10:decoder-video/mpeg")));
|
|
|
|
/* make sure we bail out correctly in case of an error or if parsing fails */
|
|
s = NULL;
|
|
ASSERT_CRITICAL (s = gst_structure_new ("^joo\nba\ndoo^",
|
|
"abc", G_TYPE_BOOLEAN, FALSE, NULL));
|
|
fail_unless (s == NULL);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_fixate)
|
|
{
|
|
GstStructure *s;
|
|
|
|
s = gst_structure_new ("name",
|
|
"int", G_TYPE_INT, 5,
|
|
"intrange", GST_TYPE_INT_RANGE, 5, 10,
|
|
"intrange2", GST_TYPE_INT_RANGE, 5, 10, NULL);
|
|
|
|
fail_if (gst_structure_fixate_field_nearest_int (s, "int", 5));
|
|
fail_unless (gst_structure_fixate_field_nearest_int (s, "intrange", 5));
|
|
fail_if (gst_structure_fixate_field_nearest_int (s, "intrange", 5));
|
|
fail_unless (gst_structure_fixate_field_nearest_int (s, "intrange2", 15));
|
|
fail_if (gst_structure_fixate_field_nearest_int (s, "intrange2", 15));
|
|
gst_structure_free (s);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_fixate_frac_list)
|
|
{
|
|
GstStructure *s, *s2;
|
|
GValue list = { 0 };
|
|
GValue frac = { 0 };
|
|
gchar *str;
|
|
gint num, denom;
|
|
|
|
g_value_init (&list, GST_TYPE_LIST);
|
|
g_value_init (&frac, GST_TYPE_FRACTION);
|
|
|
|
gst_value_set_fraction (&frac, 30, 1);
|
|
gst_value_list_append_value (&list, &frac);
|
|
gst_value_set_fraction (&frac, 15, 1);
|
|
gst_value_list_append_value (&list, &frac);
|
|
gst_value_set_fraction (&frac, 10, 1);
|
|
gst_value_list_append_value (&list, &frac);
|
|
|
|
s = gst_structure_new_empty ("name");
|
|
gst_structure_set_value (s, "frac", &list);
|
|
g_value_unset (&frac);
|
|
g_value_unset (&list);
|
|
|
|
str = gst_structure_to_string (s);
|
|
GST_DEBUG ("list %s", str);
|
|
g_free (str);
|
|
|
|
/* take copy */
|
|
s2 = gst_structure_copy (s);
|
|
|
|
/* fixate to the nearest fraction, this should give 15/1 */
|
|
fail_unless (gst_structure_fixate_field_nearest_fraction (s, "frac", 14, 1));
|
|
|
|
fail_unless (gst_structure_get_fraction (s, "frac", &num, &denom));
|
|
fail_unless (num == 15);
|
|
fail_unless (denom == 1);
|
|
|
|
gst_structure_free (s);
|
|
s = s2;
|
|
|
|
/* fixate to the nearest fraction, this should give 30/1 */
|
|
fail_unless (gst_structure_fixate_field_nearest_fraction (s, "frac", G_MAXINT,
|
|
1));
|
|
|
|
fail_unless (gst_structure_get_fraction (s, "frac", &num, &denom));
|
|
fail_unless (num == 30);
|
|
fail_unless (denom == 1);
|
|
gst_structure_free (s);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_is_subset_equal_array_list)
|
|
{
|
|
GstStructure *s1, *s2;
|
|
|
|
s1 = gst_structure_from_string ("test/test, channels=(int){ 1, 2 }", NULL);
|
|
fail_if (s1 == NULL);
|
|
s2 = gst_structure_from_string ("test/test, channels=(int)[ 1, 2 ]", NULL);
|
|
fail_if (s2 == NULL);
|
|
|
|
fail_unless (gst_structure_is_subset (s1, s2));
|
|
|
|
gst_structure_free (s1);
|
|
gst_structure_free (s2);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_is_subset_different_name)
|
|
{
|
|
GstStructure *s1, *s2;
|
|
|
|
s1 = gst_structure_from_string ("test/test, channels=(int)1", NULL);
|
|
fail_if (s1 == NULL);
|
|
s2 = gst_structure_from_string ("test/baz, channels=(int)1", NULL);
|
|
fail_if (s2 == NULL);
|
|
|
|
fail_unless (!gst_structure_is_subset (s1, s2));
|
|
|
|
gst_structure_free (s1);
|
|
gst_structure_free (s2);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_is_subset_superset_missing_fields)
|
|
{
|
|
GstStructure *s1, *s2;
|
|
|
|
/* a missing field is equivalent to any value */
|
|
s1 = gst_structure_from_string ("test/test, channels=(int)1, rate=(int)1",
|
|
NULL);
|
|
fail_if (s1 == NULL);
|
|
s2 = gst_structure_from_string ("test/test, channels=(int)1", NULL);
|
|
fail_if (s2 == NULL);
|
|
|
|
fail_unless (gst_structure_is_subset (s1, s2));
|
|
|
|
gst_structure_free (s1);
|
|
gst_structure_free (s2);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_is_subset_superset_extra_fields)
|
|
{
|
|
GstStructure *s1, *s2;
|
|
|
|
/* a missing field is equivalent to any value */
|
|
s1 = gst_structure_from_string ("test/test, channels=(int)1", NULL);
|
|
fail_if (s1 == NULL);
|
|
s2 = gst_structure_from_string ("test/test, channels=(int)1, rate=(int)1",
|
|
NULL);
|
|
fail_if (s2 == NULL);
|
|
|
|
fail_unless (!gst_structure_is_subset (s1, s2));
|
|
|
|
gst_structure_free (s1);
|
|
gst_structure_free (s2);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_is_subset_superset_extra_values)
|
|
{
|
|
GstStructure *s1, *s2;
|
|
|
|
s1 = gst_structure_from_string ("test/test, channels=(int)1", NULL);
|
|
fail_if (s1 == NULL);
|
|
s2 = gst_structure_from_string ("test/test, channels=(int)[ 1, 2 ]", NULL);
|
|
fail_if (s2 == NULL);
|
|
|
|
fail_unless (gst_structure_is_subset (s1, s2));
|
|
|
|
gst_structure_free (s1);
|
|
gst_structure_free (s2);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
|
|
GST_START_TEST (test_structure_nested)
|
|
{
|
|
GstStructure *sp, *sc1, *sc2;
|
|
gchar *str;
|
|
|
|
sc1 = gst_structure_new ("Camera",
|
|
"XResolution", G_TYPE_INT, 72, "YResolution", G_TYPE_INT, 73, NULL);
|
|
fail_unless (sc1 != NULL);
|
|
|
|
sc2 = gst_structure_new ("Image-Data",
|
|
"Orientation", G_TYPE_STRING, "top-left",
|
|
"Comment", G_TYPE_STRING, "super photo", NULL);
|
|
fail_unless (sc2 != NULL);
|
|
|
|
sp = gst_structure_new ("Exif", "Camera", GST_TYPE_STRUCTURE, sc1,
|
|
"Image Data", GST_TYPE_STRUCTURE, sc2, NULL);
|
|
fail_unless (sp != NULL);
|
|
|
|
fail_unless (gst_structure_n_fields (sp) == 2);
|
|
|
|
fail_unless (gst_structure_has_field_typed (sp, "Camera",
|
|
GST_TYPE_STRUCTURE));
|
|
|
|
str = gst_structure_to_string (sp);
|
|
fail_unless (str != NULL);
|
|
|
|
GST_DEBUG ("serialized to '%s'", str);
|
|
|
|
fail_unless (g_str_equal (str,
|
|
"Exif"
|
|
", Camera=(structure)\"Camera\\,\\ XResolution\\=\\(int\\)72\\,\\ YResolution\\=\\(int\\)73\\;\""
|
|
", Image Data=(structure)\"Image-Data\\,\\ Orientation\\=\\(string\\)top-left\\,\\ Comment\\=\\(string\\)\\\"super\\\\\\ photo\\\"\\;\";"));
|
|
|
|
g_free (str);
|
|
str = NULL;
|
|
|
|
gst_structure_free (sc1);
|
|
gst_structure_free (sc2);
|
|
gst_structure_free (sp);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_structure_nested_from_and_to_string)
|
|
{
|
|
GstStructure *s;
|
|
const gchar *str1;
|
|
gchar *str2, *end = NULL;
|
|
|
|
str1 = "main"
|
|
", main-sub1=(structure)\"type-b\\,\\ machine-type\\=\\(int\\)0\\;\""
|
|
", main-sub2=(structure)\"type-a\\,\\ plugin-filename\\=\\(string\\)\\\"/home/user/lib/lib\\\\\\ with\\\\\\ spaces.dll\\\"\\,\\ machine-type\\=\\(int\\)1\\;\""
|
|
", main-sub3=(structure)\"type-b\\,\\ plugin-filename\\=\\(string\\)/home/user/lib/lib_no_spaces.so\\,\\ machine-type\\=\\(int\\)1\\;\""
|
|
";";
|
|
|
|
s = gst_structure_from_string (str1, &end);
|
|
fail_unless (s != NULL);
|
|
|
|
GST_DEBUG ("not parsed part : %s", end);
|
|
fail_unless (*end == '\0');
|
|
|
|
fail_unless (gst_structure_n_fields (s) == 3);
|
|
|
|
fail_unless (gst_structure_has_field_typed (s, "main-sub1",
|
|
GST_TYPE_STRUCTURE));
|
|
|
|
str2 = gst_structure_to_string (s);
|
|
fail_unless (str2 != NULL);
|
|
|
|
fail_unless (g_str_equal (str1, str2));
|
|
|
|
g_free (str2);
|
|
|
|
gst_structure_free (s);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_vararg_getters)
|
|
{
|
|
GstStructure *s;
|
|
GstBuffer *buf, *buf2;
|
|
gboolean ret;
|
|
GstCaps *caps, *caps2;
|
|
GstMapInfo info;
|
|
gdouble d;
|
|
gint64 i64;
|
|
gchar *c;
|
|
gint i, num, denom;
|
|
guint8 *data;
|
|
|
|
buf = gst_buffer_new_and_alloc (3);
|
|
|
|
fail_unless (gst_buffer_map (buf, &info, GST_MAP_WRITE));
|
|
data = info.data;
|
|
data[0] = 0xf0;
|
|
data[1] = 0x66;
|
|
data[2] = 0x0d;
|
|
gst_buffer_unmap (buf, &info);
|
|
|
|
caps = gst_caps_new_empty_simple ("video/x-foo");
|
|
|
|
s = gst_structure_new ("test", "int", G_TYPE_INT, 12345678, "string",
|
|
G_TYPE_STRING, "Hello World!", "buf", GST_TYPE_BUFFER, buf, "caps",
|
|
GST_TYPE_CAPS, caps, "int64", G_TYPE_INT64, G_GINT64_CONSTANT (-99),
|
|
"double", G_TYPE_DOUBLE, G_MAXDOUBLE, "frag", GST_TYPE_FRACTION, 39, 14,
|
|
NULL);
|
|
|
|
/* first the plain one */
|
|
ret = gst_structure_get (s, "double", G_TYPE_DOUBLE, &d, "string",
|
|
G_TYPE_STRING, &c, "caps", GST_TYPE_CAPS, &caps2, "buf",
|
|
GST_TYPE_BUFFER, &buf2, "frag", GST_TYPE_FRACTION, &num, &denom, "int",
|
|
G_TYPE_INT, &i, "int64", G_TYPE_INT64, &i64, NULL);
|
|
|
|
fail_unless (ret);
|
|
fail_unless_equals_string (c, "Hello World!");
|
|
fail_unless_equals_int (i, 12345678);
|
|
fail_unless_equals_float (d, G_MAXDOUBLE);
|
|
fail_unless_equals_int (num, 39);
|
|
fail_unless_equals_int (denom, 14);
|
|
fail_unless (i64 == -99);
|
|
fail_unless (caps == caps2);
|
|
fail_unless (buf == buf2);
|
|
|
|
/* expected failures */
|
|
ASSERT_CRITICAL (gst_structure_get (s, NULL, G_TYPE_INT, &i, NULL));
|
|
fail_if (gst_structure_get (s, "int", G_TYPE_INT, &i, "double",
|
|
G_TYPE_FLOAT, &d, NULL));
|
|
fail_if (gst_structure_get (s, "int", G_TYPE_INT, &i, "dooble",
|
|
G_TYPE_DOUBLE, &d, NULL));
|
|
|
|
g_free (c);
|
|
c = NULL;
|
|
gst_caps_unref (caps2);
|
|
caps2 = NULL;
|
|
gst_buffer_unref (buf2);
|
|
buf2 = NULL;
|
|
|
|
/* and now the _id variant */
|
|
ret = gst_structure_id_get (s, g_quark_from_static_string ("double"),
|
|
G_TYPE_DOUBLE, &d, g_quark_from_static_string ("string"), G_TYPE_STRING,
|
|
&c, g_quark_from_static_string ("caps"), GST_TYPE_CAPS, &caps2,
|
|
g_quark_from_static_string ("buf"), GST_TYPE_BUFFER, &buf2,
|
|
g_quark_from_static_string ("int"), G_TYPE_INT, &i,
|
|
g_quark_from_static_string ("int64"), G_TYPE_INT64, &i64, NULL);
|
|
|
|
fail_unless (ret);
|
|
fail_unless_equals_string (c, "Hello World!");
|
|
fail_unless_equals_int (i, 12345678);
|
|
fail_unless_equals_float (d, G_MAXDOUBLE);
|
|
fail_unless (i64 == -99);
|
|
fail_unless (caps == caps2);
|
|
fail_unless (buf == buf2);
|
|
|
|
/* expected failures */
|
|
ASSERT_CRITICAL (gst_structure_get (s, 0, G_TYPE_INT, &i, NULL));
|
|
fail_if (gst_structure_id_get (s, g_quark_from_static_string ("int"),
|
|
G_TYPE_INT, &i, g_quark_from_static_string ("double"), G_TYPE_FLOAT,
|
|
&d, NULL));
|
|
fail_if (gst_structure_id_get (s, g_quark_from_static_string ("int"),
|
|
G_TYPE_INT, &i, g_quark_from_static_string ("dooble"), G_TYPE_DOUBLE,
|
|
&d, NULL));
|
|
|
|
g_free (c);
|
|
gst_caps_unref (caps2);
|
|
gst_buffer_unref (buf2);
|
|
|
|
/* finally make sure NULL as return location is handled gracefully */
|
|
ret = gst_structure_get (s, "double", G_TYPE_DOUBLE, NULL, "string",
|
|
G_TYPE_STRING, NULL, "caps", GST_TYPE_CAPS, NULL, "buf",
|
|
GST_TYPE_BUFFER, NULL, "int", G_TYPE_INT, &i, "frag", GST_TYPE_FRACTION,
|
|
NULL, NULL, "int64", G_TYPE_INT64, &i64, NULL);
|
|
|
|
ASSERT_WARNING (gst_structure_get (s, "frag", GST_TYPE_FRACTION, NULL,
|
|
&denom, NULL));
|
|
ASSERT_WARNING (gst_structure_get (s, "frag", GST_TYPE_FRACTION, &num,
|
|
NULL, NULL));
|
|
|
|
/* clean up */
|
|
gst_caps_unref (caps);
|
|
gst_buffer_unref (buf);
|
|
gst_structure_free (s);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
static gboolean
|
|
foreach_func (GQuark field_id, const GValue * value, gpointer user_data)
|
|
{
|
|
gint *sum = user_data;
|
|
gint v = 0;
|
|
|
|
if (G_VALUE_HOLDS_INT (value))
|
|
v = g_value_get_int (value);
|
|
*sum += v;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
GST_START_TEST (test_foreach)
|
|
{
|
|
GstStructure *s;
|
|
gint sum = 0;
|
|
|
|
s = gst_structure_new ("foo/bar", "baz", G_TYPE_INT, 1, "bla", G_TYPE_INT, 3,
|
|
NULL);
|
|
fail_unless (gst_structure_foreach (s, foreach_func, &sum));
|
|
fail_unless_equals_int (sum, 4);
|
|
gst_structure_free (s);
|
|
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
static gboolean
|
|
map_func (GQuark field_id, GValue * value, gpointer user_data)
|
|
{
|
|
if (G_VALUE_HOLDS_INT (value))
|
|
g_value_set_int (value, 123);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
GST_START_TEST (test_map_in_place)
|
|
{
|
|
GstStructure *s, *s2;
|
|
|
|
s = gst_structure_new ("foo/bar", "baz", G_TYPE_INT, 1, "bla", G_TYPE_INT, 3,
|
|
NULL);
|
|
s2 = gst_structure_new ("foo/bar", "baz", G_TYPE_INT, 123, "bla", G_TYPE_INT,
|
|
123, NULL);
|
|
fail_unless (gst_structure_map_in_place (s, map_func, NULL));
|
|
fail_unless (gst_structure_is_equal (s, s2));
|
|
gst_structure_free (s);
|
|
gst_structure_free (s2);
|
|
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
static gboolean
|
|
filter_map_func (GQuark field_id, GValue * value, gpointer user_data)
|
|
{
|
|
if (strcmp (g_quark_to_string (field_id), "bla") == 0)
|
|
return FALSE;
|
|
|
|
if (G_VALUE_HOLDS_INT (value))
|
|
g_value_set_int (value, 2);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
GST_START_TEST (test_filter_and_map_in_place)
|
|
{
|
|
GstStructure *s, *s2;
|
|
|
|
s = gst_structure_new ("foo/bar", "baz", G_TYPE_INT, 1, "bla", G_TYPE_INT, 3,
|
|
NULL);
|
|
s2 = gst_structure_new ("foo/bar", "baz", G_TYPE_INT, 2, NULL);
|
|
gst_structure_filter_and_map_in_place (s, filter_map_func, NULL);
|
|
fail_unless (gst_structure_is_equal (s, s2));
|
|
gst_structure_free (s);
|
|
gst_structure_free (s2);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
GST_START_TEST (test_flagset)
|
|
{
|
|
GstStructure *s;
|
|
GType test_flagset_type;
|
|
guint test_flags =
|
|
GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_SKIP | GST_SEEK_FLAG_SNAP_AFTER;
|
|
guint test_mask = GST_FLAG_SET_MASK_EXACT;
|
|
guint out_flags, out_mask;
|
|
|
|
test_flagset_type = gst_flagset_register (GST_TYPE_SEEK_FLAGS);
|
|
fail_unless (g_type_is_a (test_flagset_type, GST_TYPE_FLAG_SET));
|
|
|
|
/* Check that we can retrieve a non-standard flagset from the structure */
|
|
s = gst_structure_new ("test-struct", "test-flagset", test_flagset_type,
|
|
test_flags, test_mask, NULL);
|
|
fail_unless (gst_structure_get_flagset (s, "test-flagset", &out_flags,
|
|
&out_mask));
|
|
|
|
fail_unless (out_flags == test_flags);
|
|
fail_unless (out_mask == test_mask);
|
|
gst_structure_free (s);
|
|
}
|
|
|
|
GST_END_TEST;
|
|
|
|
static Suite *
|
|
gst_structure_suite (void)
|
|
{
|
|
Suite *s = suite_create ("GstStructure");
|
|
TCase *tc_chain = tcase_create ("general");
|
|
|
|
suite_add_tcase (s, tc_chain);
|
|
tcase_add_test (tc_chain, test_from_string_int);
|
|
tcase_add_test (tc_chain, test_from_string_uint);
|
|
tcase_add_test (tc_chain, test_from_string);
|
|
tcase_add_test (tc_chain, test_to_string);
|
|
tcase_add_test (tc_chain, test_to_from_string);
|
|
tcase_add_test (tc_chain, test_to_from_string_tag_event);
|
|
tcase_add_test (tc_chain, test_string_properties);
|
|
tcase_add_test (tc_chain, test_complete_structure);
|
|
tcase_add_test (tc_chain, test_structure_new);
|
|
tcase_add_test (tc_chain, test_fixate);
|
|
tcase_add_test (tc_chain, test_fixate_frac_list);
|
|
tcase_add_test (tc_chain, test_is_subset_equal_array_list);
|
|
tcase_add_test (tc_chain, test_is_subset_different_name);
|
|
tcase_add_test (tc_chain, test_is_subset_superset_missing_fields);
|
|
tcase_add_test (tc_chain, test_is_subset_superset_extra_fields);
|
|
tcase_add_test (tc_chain, test_is_subset_superset_extra_values);
|
|
tcase_add_test (tc_chain, test_structure_nested);
|
|
tcase_add_test (tc_chain, test_structure_nested_from_and_to_string);
|
|
tcase_add_test (tc_chain, test_vararg_getters);
|
|
tcase_add_test (tc_chain, test_foreach);
|
|
tcase_add_test (tc_chain, test_map_in_place);
|
|
tcase_add_test (tc_chain, test_filter_and_map_in_place);
|
|
tcase_add_test (tc_chain, test_flagset);
|
|
return s;
|
|
}
|
|
|
|
GST_CHECK_MAIN (gst_structure);
|