diff options
author | Mathieu Duponchelle <mathieu@centricular.com> | 2017-10-06 21:59:03 +0200 |
---|---|---|
committer | Mathieu Duponchelle <mathieu@centricular.com> | 2017-10-11 20:13:21 +0200 |
commit | 82fb85403c070a0abcf726fe3df88954b87fda7d (patch) | |
tree | c086418ab8c313d8cbb2bc47b23d30e6aeb98945 | |
parent | a2b6dac456eb8db90e1bb2e038bd5f033079358a (diff) |
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
-rw-r--r-- | gst/gstbuffer.c | 4 | ||||
-rw-r--r-- | tests/check/gst/gstmeta.c | 52 |
2 files changed, 56 insertions, 0 deletions
diff --git a/gst/gstbuffer.c b/gst/gstbuffer.c index 7d51c6d2e..e34286cf5 100644 --- a/gst/gstbuffer.c +++ b/gst/gstbuffer.c @@ -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; diff --git a/tests/check/gst/gstmeta.c b/tests/check/gst/gstmeta.c index 9e88eb735..65cf835e0 100644 --- a/tests/check/gst/gstmeta.c +++ b/tests/check/gst/gstmeta.c @@ -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; |