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>
This commit is contained in:
Edward Hervey 2020-03-23 08:06:26 +01:00 committed by Sebastian Dröge
parent 973986f40b
commit 586454bf10

View file

@ -2982,45 +2982,6 @@ gst_structure_is_equal (const GstStructure * structure1,
(gpointer) structure2); (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: * gst_structure_intersect:
* @struct1: a #GstStructure * @struct1: a #GstStructure
@ -3034,7 +2995,8 @@ GstStructure *
gst_structure_intersect (const GstStructure * struct1, gst_structure_intersect (const GstStructure * struct1,
const GstStructure * struct2) const GstStructure * struct2)
{ {
IntersectData data; guint it1, len1, it2, len2;
GstStructure *dest;
g_assert (struct1 != NULL); g_assert (struct1 != NULL);
g_assert (struct2 != NULL); g_assert (struct2 != NULL);
@ -3042,24 +3004,59 @@ gst_structure_intersect (const GstStructure * struct1,
if (G_UNLIKELY (struct1->name != struct2->name)) if (G_UNLIKELY (struct1->name != struct2->name))
return NULL; 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 /* copy fields from struct1 which we have not in struct2 to target
* intersect if we have the field in both */ * intersect if we have the field in both */
data.dest = gst_structure_new_id_empty (struct1->name); for (it1 = 0; it1 < len1; it1++) {
data.intersect = struct2; GstStructureField *field1 = GST_STRUCTURE_FIELD (struct1, it1);
if (G_UNLIKELY (!gst_structure_foreach ((GstStructure *) struct1, gboolean seenother = FALSE;
gst_structure_intersect_field1, &data))) for (it2 = 0; it2 < len2; it2++) {
goto error; 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 */ /* Now iterate over the 2nd struct and copy over everything which
data.intersect = struct1; * isn't present in the 1st struct (we've already taken care of
if (G_UNLIKELY (!gst_structure_foreach ((GstStructure *) struct2, * values being present in both just above) */
gst_structure_intersect_field2, &data))) for (it2 = 0; it2 < len2; it2++) {
goto error; 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: error:
gst_structure_free (data.dest); gst_structure_free (dest);
return NULL; return NULL;
} }