mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 19:51:11 +00:00
caps: Add gst_caps_foreach() and gst_caps_map_in_place()
https://bugzilla.gnome.org/show_bug.cgi?id=739765
This commit is contained in:
parent
f3494d09d4
commit
bc11a1b79d
4 changed files with 218 additions and 0 deletions
|
@ -398,6 +398,9 @@ GST_CAPS_FLAG_IS_SET
|
|||
GST_CAPS_FLAG_SET
|
||||
GST_CAPS_FLAG_UNSET
|
||||
|
||||
GstCapsForeachFunc
|
||||
GstCapsMapFunc
|
||||
|
||||
gst_caps_new_empty
|
||||
gst_caps_new_empty_simple
|
||||
gst_caps_new_any
|
||||
|
@ -424,6 +427,8 @@ gst_caps_set_features
|
|||
gst_caps_set_value
|
||||
gst_caps_set_simple
|
||||
gst_caps_set_simple_valist
|
||||
gst_caps_foreach
|
||||
gst_caps_map_in_place
|
||||
gst_caps_is_any
|
||||
gst_caps_is_empty
|
||||
gst_caps_is_fixed
|
||||
|
|
|
@ -2358,3 +2358,92 @@ gst_caps_transform_to_string (const GValue * src_value, GValue * dest_value)
|
|||
g_value_take_string (dest_value,
|
||||
gst_caps_to_string (gst_value_get_caps (src_value)));
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_caps_foreach:
|
||||
* @caps: a #GstCaps
|
||||
* @func: (scope call): a function to call for each field
|
||||
* @user_data: (closure): private data
|
||||
*
|
||||
* Calls the provided function once for each structure and caps feature in the
|
||||
* #GstCaps. The function must not modify the fields.
|
||||
* Also see gst_caps_map_in_place().
|
||||
*
|
||||
* Returns: %TRUE if the supplied function returns %TRUE for each call,
|
||||
* %FALSE otherwise.
|
||||
*
|
||||
* Since: 1.6
|
||||
*/
|
||||
gboolean
|
||||
gst_caps_foreach (const GstCaps * caps, GstCapsForeachFunc func,
|
||||
gpointer user_data)
|
||||
{
|
||||
guint i, n;
|
||||
GstCapsFeatures *features;
|
||||
GstStructure *structure;
|
||||
gboolean ret;
|
||||
|
||||
g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
|
||||
g_return_val_if_fail (func != NULL, FALSE);
|
||||
|
||||
n = GST_CAPS_LEN (caps);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
features = gst_caps_get_features_unchecked (caps, i);
|
||||
structure = gst_caps_get_structure_unchecked (caps, i);
|
||||
|
||||
ret = func (features, structure, user_data);
|
||||
if (G_UNLIKELY (!ret))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_caps_map_in_place:
|
||||
* @caps: a #GstCaps
|
||||
* @func: (scope call): a function to call for each field
|
||||
* @user_data: (closure): private data
|
||||
*
|
||||
* Calls the provided function once for each structure and caps feature in the
|
||||
* #GstCaps. In contrast to gst_caps_foreach(), the function may modify but not
|
||||
* delete the structures and features. The caps must be mutable.
|
||||
*
|
||||
* Returns: %TRUE if the supplied function returns %TRUE for each call,
|
||||
* %FALSE otherwise.
|
||||
*
|
||||
* Since: 1.6
|
||||
*/
|
||||
gboolean
|
||||
gst_caps_map_in_place (GstCaps * caps, GstCapsMapFunc func, gpointer user_data)
|
||||
{
|
||||
guint i, n;
|
||||
GstCapsFeatures *features;
|
||||
GstStructure *structure;
|
||||
gboolean ret;
|
||||
|
||||
g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
|
||||
g_return_val_if_fail (gst_caps_is_writable (caps), FALSE);
|
||||
g_return_val_if_fail (func != NULL, FALSE);
|
||||
|
||||
n = GST_CAPS_LEN (caps);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
features = gst_caps_get_features_unchecked (caps, i);
|
||||
structure = gst_caps_get_structure_unchecked (caps, i);
|
||||
|
||||
/* Provide sysmem features if there are none yet */
|
||||
if (!features) {
|
||||
features =
|
||||
gst_caps_features_copy (GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY);
|
||||
gst_caps_set_features (caps, i, features);
|
||||
}
|
||||
|
||||
ret = func (features, structure, user_data);
|
||||
if (G_UNLIKELY (!ret))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -363,6 +363,41 @@ struct _GstStaticCaps {
|
|||
gpointer _gst_reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
/**
|
||||
* GstCapsForeachFunc:
|
||||
* @features: the #GstCapsFeatures
|
||||
* @structure: the #GstStructure
|
||||
* @user_data: user data
|
||||
*
|
||||
* A function that will be called in gst_caps_foreach(). The function may
|
||||
* not modify @features or @structure.
|
||||
*
|
||||
* Returns: %TRUE if the foreach operation should continue, %FALSE if
|
||||
* the foreach operation should stop with %FALSE.
|
||||
*
|
||||
* Since: 1.6
|
||||
*/
|
||||
typedef gboolean (*GstCapsForeachFunc) (GstCapsFeatures *features,
|
||||
GstStructure *structure,
|
||||
gpointer user_data);
|
||||
|
||||
/**
|
||||
* GstCapsMapFunc:
|
||||
* @features: the #GstCapsFeatures
|
||||
* @structure: the #GstStructure
|
||||
* @user_data: user data
|
||||
*
|
||||
* A function that will be called in gst_caps_map_in_place(). The function
|
||||
* may modify @features and @structure.
|
||||
*
|
||||
* Returns: %TRUE if the map operation should continue, %FALSE if
|
||||
* the map operation should stop with %FALSE.
|
||||
*/
|
||||
typedef gboolean (*GstCapsMapFunc) (GstCapsFeatures *features,
|
||||
GstStructure *structure,
|
||||
gpointer user_data);
|
||||
|
||||
|
||||
GType gst_caps_get_type (void);
|
||||
|
||||
GstCaps * gst_caps_new_empty (void);
|
||||
|
@ -417,6 +452,14 @@ void gst_caps_set_simple_valist (GstCaps *caps,
|
|||
const char *field,
|
||||
va_list varargs);
|
||||
|
||||
gboolean gst_caps_foreach (const GstCaps *caps,
|
||||
GstCapsForeachFunc func,
|
||||
gpointer user_data);
|
||||
|
||||
gboolean gst_caps_map_in_place (GstCaps *caps,
|
||||
GstCapsMapFunc func,
|
||||
gpointer user_data);
|
||||
|
||||
/* tests */
|
||||
gboolean gst_caps_is_any (const GstCaps *caps);
|
||||
gboolean gst_caps_is_empty (const GstCaps *caps);
|
||||
|
|
|
@ -1161,6 +1161,85 @@ GST_START_TEST (test_special_caps)
|
|||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
static gboolean
|
||||
foreach_append_function (GstCapsFeatures * features, GstStructure * structure,
|
||||
gpointer user_data)
|
||||
{
|
||||
GstCaps *caps = user_data;
|
||||
|
||||
gst_caps_append_structure_full (caps, gst_structure_copy (structure),
|
||||
features ? gst_caps_features_copy (features) : NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GST_START_TEST (test_foreach)
|
||||
{
|
||||
GstCaps *caps, *caps2;
|
||||
|
||||
caps =
|
||||
gst_caps_from_string
|
||||
("video/x-raw, format=I420; video/x-raw(foo:bar); video/x-h264");
|
||||
caps2 = gst_caps_new_empty ();
|
||||
fail_unless (gst_caps_foreach (caps, foreach_append_function, caps2));
|
||||
fail_unless (gst_caps_is_strictly_equal (caps, caps2));
|
||||
gst_caps_unref (caps);
|
||||
gst_caps_unref (caps2);
|
||||
|
||||
caps = gst_caps_new_empty ();
|
||||
caps2 = gst_caps_new_empty ();
|
||||
fail_unless (gst_caps_foreach (caps, foreach_append_function, caps2));
|
||||
fail_unless (gst_caps_is_strictly_equal (caps, caps2));
|
||||
gst_caps_unref (caps);
|
||||
gst_caps_unref (caps2);
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
static gboolean
|
||||
map_function (GstCapsFeatures * features, GstStructure * structure,
|
||||
gpointer user_data)
|
||||
{
|
||||
/* Remove caps features if there are any, otherwise add some dummy */
|
||||
if (gst_caps_features_contains (features, "foo:bar")) {
|
||||
gst_caps_features_remove (features, "foo:bar");
|
||||
} else {
|
||||
gst_caps_features_add (features, "foo:bar");
|
||||
gst_caps_features_remove (features, GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY);
|
||||
}
|
||||
|
||||
/* Set some dummy integer in the structure */
|
||||
gst_structure_set (structure, "foo", G_TYPE_INT, 123, NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GST_START_TEST (test_map_in_place)
|
||||
{
|
||||
GstCaps *caps, *caps2;
|
||||
|
||||
caps =
|
||||
gst_caps_from_string
|
||||
("video/x-raw, format=I420; video/x-raw(foo:bar); video/x-h264");
|
||||
caps2 =
|
||||
gst_caps_from_string
|
||||
("video/x-raw(foo:bar), foo=(int)123, format=I420; video/x-raw, foo=(int)123; video/x-h264(foo:bar), foo=(int)123");
|
||||
fail_unless (gst_caps_map_in_place (caps, map_function, NULL));
|
||||
fail_unless (gst_caps_is_strictly_equal (caps, caps2));
|
||||
gst_caps_unref (caps);
|
||||
gst_caps_unref (caps2);
|
||||
|
||||
caps = gst_caps_new_empty ();
|
||||
caps2 = gst_caps_new_empty ();
|
||||
fail_unless (gst_caps_map_in_place (caps, map_function, NULL));
|
||||
fail_unless (gst_caps_is_strictly_equal (caps, caps2));
|
||||
gst_caps_unref (caps);
|
||||
gst_caps_unref (caps2);
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
static Suite *
|
||||
gst_caps_suite (void)
|
||||
{
|
||||
|
@ -1190,6 +1269,8 @@ gst_caps_suite (void)
|
|||
tcase_add_test (tc_chain, test_broken);
|
||||
tcase_add_test (tc_chain, test_features);
|
||||
tcase_add_test (tc_chain, test_special_caps);
|
||||
tcase_add_test (tc_chain, test_foreach);
|
||||
tcase_add_test (tc_chain, test_map_in_place);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue