summaryrefslogtreecommitdiff
path: root/gst/gststructure.c
diff options
context:
space:
mode:
authorEdward Hervey <edward@centricular.com>2020-03-23 08:06:26 +0100
committerSebastian Dröge <slomo@coaxion.net>2020-05-05 10:17:49 +0000
commit586454bf10e823ca40be754f4a64983d1e5d7313 (patch)
tree3d0800bcf20799ea6563ccc2aecc8041d7be6592 /gst/gststructure.c
parent973986f40bf922583d4f65def18d1e8c829c9ce0 (diff)
downloadgstreamer-586454bf10e823ca40be754f4a64983d1e5d7313.tar.gz
gststructure: Inline gst_structure_intersect()
Having direct access to the iteration allows tighter code and also being able to stop earlier. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/453>
Diffstat (limited to 'gst/gststructure.c')
-rw-r--r--gst/gststructure.c101
1 files changed, 49 insertions, 52 deletions
diff --git a/gst/gststructure.c b/gst/gststructure.c
index d5dc4f62fe..8df6c121e3 100644
--- a/gst/gststructure.c
+++ b/gst/gststructure.c
@@ -2982,45 +2982,6 @@ gst_structure_is_equal (const GstStructure * structure1,
(gpointer) structure2);
}
-
-typedef struct
-{
- GstStructure *dest;
- const GstStructure *intersect;
-}
-IntersectData;
-
-static gboolean
-gst_structure_intersect_field1 (GQuark id, const GValue * val1, gpointer data)
-{
- IntersectData *idata = (IntersectData *) data;
- const GValue *val2 = gst_structure_id_get_value (idata->intersect, id);
-
- if (G_UNLIKELY (val2 == NULL)) {
- gst_structure_id_set_value (idata->dest, id, val1);
- } else {
- GValue dest_value = { 0 };
- if (gst_value_intersect (&dest_value, val1, val2)) {
- gst_structure_id_take_value (idata->dest, id, &dest_value);
- } else {
- return FALSE;
- }
- }
- return TRUE;
-}
-
-static gboolean
-gst_structure_intersect_field2 (GQuark id, const GValue * val1, gpointer data)
-{
- IntersectData *idata = (IntersectData *) data;
- const GValue *val2 = gst_structure_id_get_value (idata->intersect, id);
-
- if (G_UNLIKELY (val2 == NULL)) {
- gst_structure_id_set_value (idata->dest, id, val1);
- }
- return TRUE;
-}
-
/**
* gst_structure_intersect:
* @struct1: a #GstStructure
@@ -3034,7 +2995,8 @@ GstStructure *
gst_structure_intersect (const GstStructure * struct1,
const GstStructure * struct2)
{
- IntersectData data;
+ guint it1, len1, it2, len2;
+ GstStructure *dest;
g_assert (struct1 != NULL);
g_assert (struct2 != NULL);
@@ -3042,24 +3004,59 @@ gst_structure_intersect (const GstStructure * struct1,
if (G_UNLIKELY (struct1->name != struct2->name))
return NULL;
+ len1 = GST_STRUCTURE_LEN (struct1);
+ len2 = GST_STRUCTURE_LEN (struct2);
+
+ /* Resulting structure will be at most the size of the smallest structure */
+ dest = gst_structure_new_id_empty_with_size (struct1->name, MIN (len1, len2));
+
/* copy fields from struct1 which we have not in struct2 to target
* intersect if we have the field in both */
- data.dest = gst_structure_new_id_empty (struct1->name);
- data.intersect = struct2;
- if (G_UNLIKELY (!gst_structure_foreach ((GstStructure *) struct1,
- gst_structure_intersect_field1, &data)))
- goto error;
+ for (it1 = 0; it1 < len1; it1++) {
+ GstStructureField *field1 = GST_STRUCTURE_FIELD (struct1, it1);
+ gboolean seenother = FALSE;
+ for (it2 = 0; it2 < len2; it2++) {
+ GstStructureField *field2 = GST_STRUCTURE_FIELD (struct2, it2);
+ if (field1->name == field2->name) {
+ GValue dest_value = { 0 };
+ seenother = TRUE;
+ /* Get the intersection if any */
+ if (gst_value_intersect (&dest_value, &field1->value, &field2->value)) {
+ gst_structure_id_take_value (dest, field1->name, &dest_value);
+ break;
+ } else {
+ /* No intersection, return nothing */
+ goto error;
+ }
+ }
+ }
+ /* Field1 was only present in struct1, copy it over */
+ if (!seenother)
+ gst_structure_id_set_value (dest, field1->name, &field1->value);
+ }
- /* copy fields from struct2 which we have not in struct1 to target */
- data.intersect = struct1;
- if (G_UNLIKELY (!gst_structure_foreach ((GstStructure *) struct2,
- gst_structure_intersect_field2, &data)))
- goto error;
+ /* Now iterate over the 2nd struct and copy over everything which
+ * isn't present in the 1st struct (we've already taken care of
+ * values being present in both just above) */
+ for (it2 = 0; it2 < len2; it2++) {
+ GstStructureField *field2 = GST_STRUCTURE_FIELD (struct2, it2);
+ gboolean seenother = FALSE;
+ for (it1 = 0; it1 < len1; it1++) {
+ GstStructureField *field1 = GST_STRUCTURE_FIELD (struct1, it1);
+ if (field1->name == field2->name) {
+ seenother = TRUE;
+ break;
+ }
+ }
+ if (!seenother)
+ gst_structure_id_set_value (dest, field2->name, &field2->value);
+
+ }
- return data.dest;
+ return dest;
error:
- gst_structure_free (data.dest);
+ gst_structure_free (dest);
return NULL;
}