summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/gst/gstreamer-sections.txt6
-rw-r--r--gst/gstcaps.c63
-rw-r--r--gst/gstcaps.h21
-rw-r--r--gst/gststructure.c48
-rw-r--r--gst/gststructure.h21
-rw-r--r--tests/check/gst/gstcaps.c47
-rw-r--r--tests/check/gst/gststructure.c28
-rw-r--r--win32/common/libgstreamer.def4
8 files changed, 233 insertions, 5 deletions
diff --git a/docs/gst/gstreamer-sections.txt b/docs/gst/gstreamer-sections.txt
index f5863bb8f..4d36c26db 100644
--- a/docs/gst/gstreamer-sections.txt
+++ b/docs/gst/gstreamer-sections.txt
@@ -400,6 +400,7 @@ GST_CAPS_FLAG_UNSET
GstCapsForeachFunc
GstCapsMapFunc
+GstCapsFilterMapFunc
gst_caps_new_empty
gst_caps_new_empty_simple
@@ -429,6 +430,7 @@ gst_caps_set_simple
gst_caps_set_simple_valist
gst_caps_foreach
gst_caps_map_in_place
+gst_caps_filter_and_map_in_place
gst_caps_is_any
gst_caps_is_empty
gst_caps_is_fixed
@@ -2525,6 +2527,7 @@ gst_segment_flags_get_type
GstStructure
GstStructureForeachFunc
GstStructureMapFunc
+GstStructureFilterMapFunc
gst_structure_new_empty
gst_structure_new_id_empty
gst_structure_new
@@ -2556,7 +2559,6 @@ gst_structure_remove_fields
gst_structure_remove_fields_valist
gst_structure_remove_all_fields
gst_structure_get_field_type
-gst_structure_foreach
gst_structure_n_fields
gst_structure_has_field
gst_structure_has_field_typed
@@ -2578,7 +2580,9 @@ gst_structure_get_date_time
gst_structure_get_clock_time
gst_structure_get_enum
gst_structure_get_fraction
+gst_structure_foreach
gst_structure_map_in_place
+gst_structure_filter_and_map_in_place
gst_structure_nth_field_name
gst_structure_set_parent_refcount
gst_structure_to_string
diff --git a/gst/gstcaps.c b/gst/gstcaps.c
index c9b72df71..147b32c9c 100644
--- a/gst/gstcaps.c
+++ b/gst/gstcaps.c
@@ -484,8 +484,6 @@ gst_caps_remove_and_get_structure (GstCaps * caps, guint idx)
return s;
}
-
-
/**
* gst_caps_steal_structure:
* @caps: the #GstCaps to retrieve from
@@ -2367,7 +2365,7 @@ gst_caps_transform_to_string (const GValue * src_value, GValue * dest_value)
*
* 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().
+ * Also see gst_caps_map_in_place() and gst_caps_filter_and_map_in_place().
*
* Returns: %TRUE if the supplied function returns %TRUE for each call,
* %FALSE otherwise.
@@ -2447,3 +2445,62 @@ gst_caps_map_in_place (GstCaps * caps, GstCapsMapFunc func, gpointer user_data)
return TRUE;
}
+
+/**
+ * gst_caps_filter_and_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 the
+ * structure and features. In contrast to gst_caps_filter_and_map_in_place(),
+ * the structure and features are removed from the caps if %FALSE is returned
+ * from the function.
+ * The caps must be mutable.
+ *
+ * Since: 1.6
+ */
+void
+gst_caps_filter_and_map_in_place (GstCaps * caps, GstCapsFilterMapFunc func,
+ gpointer user_data)
+{
+ guint i, n;
+ GstCapsFeatures *features;
+ GstStructure *structure;
+ gboolean ret;
+
+ g_return_if_fail (GST_IS_CAPS (caps));
+ g_return_if_fail (gst_caps_is_writable (caps));
+ g_return_if_fail (func != NULL);
+
+ n = GST_CAPS_LEN (caps);
+
+ for (i = 0; i < n;) {
+ 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 (!ret) {
+ GST_CAPS_ARRAY (caps) = g_array_remove_index (GST_CAPS_ARRAY (caps), i);
+
+ gst_structure_set_parent_refcount (structure, NULL);
+ gst_structure_free (structure);
+ if (features) {
+ gst_caps_features_set_parent_refcount (features, NULL);
+ gst_caps_features_free (features);
+ }
+
+ n = GST_CAPS_LEN (caps);
+ } else {
+ i++;
+ }
+ }
+}
diff --git a/gst/gstcaps.h b/gst/gstcaps.h
index 4102f277a..5cd1b781e 100644
--- a/gst/gstcaps.h
+++ b/gst/gstcaps.h
@@ -397,6 +397,23 @@ typedef gboolean (*GstCapsMapFunc) (GstCapsFeatures *features,
GstStructure *structure,
gpointer user_data);
+/**
+ * GstCapsFilterMapFunc:
+ * @features: the #GstCapsFeatures
+ * @structure: the #GstStructure
+ * @user_data: user data
+ *
+ * A function that will be called in gst_caps_filter_and_map_in_place().
+ * The function may modify @features and @structure, and both will be
+ * removed from the caps if %FALSE is returned.
+ *
+ * Returns: %TRUE if the features and structure should be preserved,
+ * %FALSE if it should be removed.
+ */
+typedef gboolean (*GstCapsFilterMapFunc) (GstCapsFeatures *features,
+ GstStructure *structure,
+ gpointer user_data);
+
GType gst_caps_get_type (void);
@@ -460,6 +477,10 @@ gboolean gst_caps_map_in_place (GstCaps *caps,
GstCapsMapFunc func,
gpointer user_data);
+void gst_caps_filter_and_map_in_place (GstCaps *caps,
+ GstCapsFilterMapFunc func,
+ gpointer user_data);
+
/* tests */
gboolean gst_caps_is_any (const GstCaps *caps);
gboolean gst_caps_is_empty (const GstCaps *caps);
diff --git a/gst/gststructure.c b/gst/gststructure.c
index 378161534..8b0b54b92 100644
--- a/gst/gststructure.c
+++ b/gst/gststructure.c
@@ -1100,7 +1100,8 @@ gst_structure_nth_field_name (const GstStructure * structure, guint index)
* @user_data: (closure): private data
*
* Calls the provided function once for each field in the #GstStructure. The
- * function must not modify the fields. Also see gst_structure_map_in_place().
+ * function must not modify the fields. Also see gst_structure_map_in_place()
+ * and gst_structure_filter_and_map_in_place().
*
* Returns: %TRUE if the supplied function returns %TRUE For each of the fields,
* %FALSE otherwise.
@@ -1167,6 +1168,51 @@ gst_structure_map_in_place (GstStructure * structure,
}
/**
+ * gst_structure_filter_and_map_in_place:
+ * @structure: a #GstStructure
+ * @func: (scope call): a function to call for each field
+ * @user_data: (closure): private data
+ *
+ * Calls the provided function once for each field in the #GstStructure. In
+ * contrast to gst_structure_foreach(), the function may modify the fields.
+ * In contrast to gst_structure_map_in_place(), the field is removed from
+ * the structure if %FALSE is returned from the function.
+ * The structure must be mutable.
+ *
+ * Since: 1.6
+ */
+void
+gst_structure_filter_and_map_in_place (GstStructure * structure,
+ GstStructureFilterMapFunc func, gpointer user_data)
+{
+ guint i, len;
+ GstStructureField *field;
+ gboolean ret;
+
+ g_return_if_fail (structure != NULL);
+ g_return_if_fail (IS_MUTABLE (structure));
+ g_return_if_fail (func != NULL);
+ len = GST_STRUCTURE_FIELDS (structure)->len;
+
+ for (i = 0; i < len;) {
+ field = GST_STRUCTURE_FIELD (structure, i);
+
+ ret = func (field->name, &field->value, user_data);
+
+ if (!ret) {
+ if (G_IS_VALUE (&field->value)) {
+ g_value_unset (&field->value);
+ }
+ GST_STRUCTURE_FIELDS (structure) =
+ g_array_remove_index (GST_STRUCTURE_FIELDS (structure), i);
+ len = GST_STRUCTURE_FIELDS (structure)->len;
+ } else {
+ i++;
+ }
+ }
+}
+
+/**
* gst_structure_id_has_field:
* @structure: a #GstStructure
* @field: #GQuark of the field name
diff --git a/gst/gststructure.h b/gst/gststructure.h
index 6687970d8..014ef37e5 100644
--- a/gst/gststructure.h
+++ b/gst/gststructure.h
@@ -71,6 +71,23 @@ typedef gboolean (*GstStructureMapFunc) (GQuark field_id,
gpointer user_data);
/**
+ * GstStructureFilterMapFunc:
+ * @field_id: the #GQuark of the field name
+ * @value: the #GValue of the field
+ * @user_data: user data
+ *
+ * A function that will be called in gst_structure_filter_and_map_in_place().
+ * The function may modify @value, and the value will be removed from
+ * the structure if %FALSE is returned.
+ *
+ * Returns: %TRUE if the field should be preserved, %FALSE if it
+ * should be removed.
+ */
+typedef gboolean (*GstStructureFilterMapFunc) (GQuark field_id,
+ GValue * value,
+ gpointer user_data);
+
+/**
* GstStructure:
* @type: the GType of a structure
*
@@ -198,6 +215,10 @@ gboolean gst_structure_map_in_place (GstStructure *
GstStructureMapFunc func,
gpointer user_data);
+void gst_structure_filter_and_map_in_place (GstStructure * structure,
+ GstStructureFilterMapFunc func,
+ gpointer user_data);
+
gint gst_structure_n_fields (const GstStructure * structure);
const gchar * gst_structure_nth_field_name (const GstStructure * structure,
diff --git a/tests/check/gst/gstcaps.c b/tests/check/gst/gstcaps.c
index cb6128b53..66453610e 100644
--- a/tests/check/gst/gstcaps.c
+++ b/tests/check/gst/gstcaps.c
@@ -1240,6 +1240,52 @@ GST_START_TEST (test_map_in_place)
GST_END_TEST;
+static gboolean
+filter_map_function (GstCapsFeatures * features, GstStructure * structure,
+ gpointer user_data)
+{
+ if (!gst_structure_has_name (structure, "video/x-raw"))
+ return FALSE;
+
+ if (!gst_caps_features_contains (features, "foo:bar"))
+ return FALSE;
+
+ /* Set some dummy integer in the structure */
+ gst_structure_set (structure, "foo", G_TYPE_INT, 123, NULL);
+
+ return TRUE;
+}
+
+GST_START_TEST (test_filter_and_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");
+ gst_caps_filter_and_map_in_place (caps, filter_map_function, NULL);
+ fail_unless (gst_caps_is_strictly_equal (caps, caps2));
+ gst_caps_unref (caps);
+ gst_caps_unref (caps2);
+
+ caps = gst_caps_from_string ("video/x-raw, format=I420; video/x-h264");
+ caps2 = gst_caps_new_empty ();
+ gst_caps_filter_and_map_in_place (caps, filter_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 ();
+ gst_caps_filter_and_map_in_place (caps, filter_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)
{
@@ -1271,6 +1317,7 @@ gst_caps_suite (void)
tcase_add_test (tc_chain, test_special_caps);
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);
return s;
}
diff --git a/tests/check/gst/gststructure.c b/tests/check/gst/gststructure.c
index a73db33fb..18c58f6fa 100644
--- a/tests/check/gst/gststructure.c
+++ b/tests/check/gst/gststructure.c
@@ -722,6 +722,33 @@ GST_START_TEST (test_map_in_place)
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;
+
static Suite *
gst_structure_suite (void)
{
@@ -746,6 +773,7 @@ gst_structure_suite (void)
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);
return s;
}
diff --git a/win32/common/libgstreamer.def b/win32/common/libgstreamer.def
index 5908d4290..98cb12dd6 100644
--- a/win32/common/libgstreamer.def
+++ b/win32/common/libgstreamer.def
@@ -241,8 +241,10 @@ EXPORTS
gst_caps_features_remove_id
gst_caps_features_set_parent_refcount
gst_caps_features_to_string
+ gst_caps_filter_and_map_in_place
gst_caps_fixate
gst_caps_flags_get_type
+ gst_caps_foreach
gst_caps_from_string
gst_caps_get_features
gst_caps_get_size
@@ -261,6 +263,7 @@ EXPORTS
gst_caps_is_subset
gst_caps_is_subset_structure
gst_caps_is_subset_structure_full
+ gst_caps_map_in_place
gst_caps_merge
gst_caps_merge_structure
gst_caps_merge_structure_full
@@ -1139,6 +1142,7 @@ EXPORTS
gst_structure_can_intersect
gst_structure_change_type_get_type
gst_structure_copy
+ gst_structure_filter_and_map_in_place
gst_structure_fixate
gst_structure_fixate_field
gst_structure_fixate_field_boolean