mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-03 04:52:28 +00:00
tags: don't produce duplicated entries when merging same value twice
Add a variant of gst_value_list_concat() that skips duplicates and use that when merging taglists. API: gst_value_list_merge()
This commit is contained in:
parent
655451db54
commit
373be6f14e
5 changed files with 99 additions and 2 deletions
|
@ -2717,6 +2717,7 @@ GST_TYPE_ARRAY
|
|||
gst_value_list_append_value
|
||||
gst_value_list_prepend_value
|
||||
gst_value_list_concat
|
||||
gst_value_list_merge
|
||||
gst_value_list_get_size
|
||||
gst_value_list_get_value
|
||||
|
||||
|
|
|
@ -755,12 +755,12 @@ gst_tag_list_add_value_internal (GstStructure * list, GstTagMergeMode mode,
|
|||
gst_structure_id_set_value (list, tag, value);
|
||||
break;
|
||||
case GST_TAG_MERGE_PREPEND:
|
||||
gst_value_list_concat (&dest, value, value2);
|
||||
gst_value_list_merge (&dest, value, value2);
|
||||
gst_structure_id_set_value (list, tag, &dest);
|
||||
g_value_unset (&dest);
|
||||
break;
|
||||
case GST_TAG_MERGE_APPEND:
|
||||
gst_value_list_concat (&dest, value2, value);
|
||||
gst_value_list_merge (&dest, value2, value);
|
||||
gst_structure_id_set_value (list, tag, &dest);
|
||||
g_value_unset (&dest);
|
||||
break;
|
||||
|
|
|
@ -384,6 +384,98 @@ gst_value_list_concat (GValue * dest, const GValue * value1,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_value_list_merge:
|
||||
* @dest: (out caller-allocates): an uninitialized #GValue to take the result
|
||||
* @value1: a #GValue
|
||||
* @value2: a #GValue
|
||||
*
|
||||
* Merges copies of @value1 and @value2 into a list. Values that are not
|
||||
* of type #GST_TYPE_LIST are treated as if they were lists of length 1.
|
||||
* @dest will be initialized to the type #GST_TYPE_LIST.
|
||||
*
|
||||
* The resulting list won't have duplicated values.
|
||||
*/
|
||||
void
|
||||
gst_value_list_merge (GValue * dest, const GValue * value1,
|
||||
const GValue * value2)
|
||||
{
|
||||
guint i, j, k, value1_length, value2_length, skipped;
|
||||
const GValue *src;
|
||||
gboolean skip;
|
||||
GArray *array;
|
||||
|
||||
g_return_if_fail (dest != NULL);
|
||||
g_return_if_fail (G_VALUE_TYPE (dest) == 0);
|
||||
g_return_if_fail (G_IS_VALUE (value1));
|
||||
g_return_if_fail (G_IS_VALUE (value2));
|
||||
|
||||
value1_length =
|
||||
(GST_VALUE_HOLDS_LIST (value1) ? VALUE_LIST_SIZE (value1) : 1);
|
||||
value2_length =
|
||||
(GST_VALUE_HOLDS_LIST (value2) ? VALUE_LIST_SIZE (value2) : 1);
|
||||
g_value_init (dest, GST_TYPE_LIST);
|
||||
array = (GArray *) dest->data[0].v_pointer;
|
||||
g_array_set_size (array, value1_length + value2_length);
|
||||
|
||||
if (GST_VALUE_HOLDS_LIST (value1)) {
|
||||
for (i = 0; i < value1_length; i++) {
|
||||
gst_value_init_and_copy (&g_array_index (array, GValue, i),
|
||||
VALUE_LIST_GET_VALUE (value1, i));
|
||||
}
|
||||
} else {
|
||||
gst_value_init_and_copy (&g_array_index (array, GValue, 0), value1);
|
||||
}
|
||||
|
||||
j = value1_length;
|
||||
skipped = 0;
|
||||
if (GST_VALUE_HOLDS_LIST (value2)) {
|
||||
for (i = 0; i < value2_length; i++) {
|
||||
skip = FALSE;
|
||||
src = VALUE_LIST_GET_VALUE (value2, i);
|
||||
for (k = 0; k < value1_length; k++) {
|
||||
if (gst_value_compare (&g_array_index (array, GValue, k),
|
||||
src) == GST_VALUE_EQUAL) {
|
||||
skip = TRUE;
|
||||
skipped++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!skip) {
|
||||
gst_value_init_and_copy (&g_array_index (array, GValue, j), src);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
skip = FALSE;
|
||||
for (k = 0; k < value1_length; k++) {
|
||||
if (gst_value_compare (&g_array_index (array, GValue, k),
|
||||
value2) == GST_VALUE_EQUAL) {
|
||||
skip = TRUE;
|
||||
skipped++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!skip) {
|
||||
gst_value_init_and_copy (&g_array_index (array, GValue, j), value2);
|
||||
}
|
||||
}
|
||||
if (skipped) {
|
||||
guint new_size = value1_length + (value2_length - skipped);
|
||||
|
||||
if (new_size > 1) {
|
||||
/* shrink list */
|
||||
g_array_set_size (array, new_size);
|
||||
} else {
|
||||
GValue *tmp = dest;
|
||||
|
||||
/* turn into single value */
|
||||
gst_value_init_and_copy (dest, &g_array_index (array, GValue, 0));
|
||||
g_value_unset (tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_value_list_get_size:
|
||||
* @value: a #GValue of type #GST_TYPE_LIST
|
||||
|
|
|
@ -466,6 +466,9 @@ void gst_value_list_prepend_value (GValue *value,
|
|||
void gst_value_list_concat (GValue *dest,
|
||||
const GValue *value1,
|
||||
const GValue *value2);
|
||||
void gst_value_list_merge (GValue *dest,
|
||||
const GValue *value1,
|
||||
const GValue *value2);
|
||||
guint gst_value_list_get_size (const GValue *value);
|
||||
G_CONST_RETURN GValue *
|
||||
gst_value_list_get_value (const GValue *value,
|
||||
|
|
|
@ -1164,6 +1164,7 @@ EXPORTS
|
|||
gst_value_list_get_size
|
||||
gst_value_list_get_type
|
||||
gst_value_list_get_value
|
||||
gst_value_list_merge
|
||||
gst_value_list_prepend_value
|
||||
gst_value_register
|
||||
gst_value_register_intersect_func
|
||||
|
|
Loading…
Reference in a new issue