gstbuffer: fix meta removal in gst_buffer_foreach_meta

When updating the linked list, prev->next = next is correct
if prev is actually updated after being set to the head
of the list at the start.

https://bugzilla.gnome.org/show_bug.cgi?id=788617
This commit is contained in:
Mathieu Duponchelle 2017-10-06 21:59:03 +02:00
parent 6617b01af9
commit e838007d09
2 changed files with 56 additions and 0 deletions

View file

@ -2370,12 +2370,16 @@ gst_buffer_foreach_meta (GstBuffer * buffer, GstBufferForeachMetaFunc func,
else
prev->next = next;
prev = next;
/* call free_func if any */
if (info->free_func)
info->free_func (m, buffer);
/* and free the slice */
g_slice_free1 (ITEM_SIZE (info), walk);
} else {
prev = walk;
}
if (!res)
break;

View file

@ -314,6 +314,57 @@ GST_START_TEST (test_meta_locked)
GST_END_TEST;
static gboolean
foreach_meta_remove_one (GstBuffer * buffer, GstMeta ** meta,
gpointer to_remove)
{
if (*meta == to_remove) {
*meta = NULL;
}
return TRUE;
}
static gint
count_buffer_meta (GstBuffer * buffer)
{
gint ret = 0;
gpointer state = NULL;
while (gst_buffer_iterate_meta (buffer, &state))
ret++;
return ret;
}
GST_START_TEST (test_meta_foreach_remove_one)
{
GstBuffer *buffer;
GstMetaTest *meta1, *meta2, *meta3;
buffer = gst_buffer_new_and_alloc (4);
fail_if (buffer == NULL);
/* add some metadata */
meta1 = GST_META_TEST_ADD (buffer);
fail_if (meta1 == NULL);
meta2 = GST_META_TEST_ADD (buffer);
fail_if (meta2 == NULL);
meta3 = GST_META_TEST_ADD (buffer);
fail_if (meta3 == NULL);
fail_unless_equals_int (count_buffer_meta (buffer), 3);
gst_buffer_foreach_meta (buffer, foreach_meta_remove_one, meta1);
fail_unless_equals_int (count_buffer_meta (buffer), 2);
/* clean up */
gst_buffer_unref (buffer);
}
GST_END_TEST;
GST_START_TEST (test_meta_iterate)
{
GstBuffer *buffer;
@ -421,6 +472,7 @@ gst_buffermeta_suite (void)
suite_add_tcase (s, tc_chain);
tcase_add_test (tc_chain, test_meta_test);
tcase_add_test (tc_chain, test_meta_locked);
tcase_add_test (tc_chain, test_meta_foreach_remove_one);
tcase_add_test (tc_chain, test_meta_iterate);
return s;