diff --git a/docs/gst/gstreamer-sections.txt b/docs/gst/gstreamer-sections.txt index 8c0ec6f43b..e9b63450c7 100644 --- a/docs/gst/gstreamer-sections.txt +++ b/docs/gst/gstreamer-sections.txt @@ -393,6 +393,7 @@ gst_buffer_list_make_writable GstBufferListFunc gst_buffer_list_foreach gst_buffer_list_get +gst_buffer_list_get_writable GST_BUFFER_LIST diff --git a/gst/gstbufferlist.c b/gst/gstbufferlist.c index ec926457bc..1e97c79eba 100644 --- a/gst/gstbufferlist.c +++ b/gst/gstbufferlist.c @@ -273,6 +273,9 @@ gst_buffer_list_foreach (GstBufferList * list, GstBufferListFunc func, * * Get the buffer at @idx. * + * You must make sure that @idx does not exceed the number of + * buffers available. + * * Returns: (transfer none) (nullable): the buffer at @idx in @group * or %NULL when there is no buffer. The buffer remains valid as * long as @list is valid and buffer is not removed from the list. @@ -286,6 +289,35 @@ gst_buffer_list_get (GstBufferList * list, guint idx) return list->buffers[idx]; } +/** + * gst_buffer_list_get_writable: + * @list: a (writable) #GstBufferList + * @idx: the index + * + * Gets the buffer at @idx, ensuring it is a writable buffer. + * + * You must make sure that @idx does not exceed the number of + * buffers available. + * + * Returns: (transfer none) (nullable): the buffer at @idx in @group. + * The returned buffer remains valid as long as @list is valid and + * the buffer is not removed from the list. + * + * Since: 1.14 + */ +GstBuffer * +gst_buffer_list_get_writable (GstBufferList * list, guint idx) +{ + GstBuffer **p_buf; + + g_return_val_if_fail (GST_IS_BUFFER_LIST (list), NULL); + g_return_val_if_fail (gst_buffer_list_is_writable (list), NULL); + g_return_val_if_fail (idx < list->n_buffers, NULL); + + p_buf = &list->buffers[idx]; + return (*p_buf = gst_buffer_make_writable (*p_buf)); +} + /** * gst_buffer_list_add: * @l: a #GstBufferList diff --git a/gst/gstbufferlist.h b/gst/gstbufferlist.h index b5dcdbaa56..72eb43e3b3 100644 --- a/gst/gstbufferlist.h +++ b/gst/gstbufferlist.h @@ -148,6 +148,9 @@ guint gst_buffer_list_length (GstBufferList *l GST_EXPORT GstBuffer * gst_buffer_list_get (GstBufferList *list, guint idx); +GST_EXPORT +GstBuffer * gst_buffer_list_get_writable (GstBufferList *list, guint idx); + GST_EXPORT void gst_buffer_list_insert (GstBufferList *list, gint idx, GstBuffer *buffer); diff --git a/tests/check/gst/gstbufferlist.c b/tests/check/gst/gstbufferlist.c index 6220d02867..e5c9f56124 100644 --- a/tests/check/gst/gstbufferlist.c +++ b/tests/check/gst/gstbufferlist.c @@ -427,6 +427,39 @@ GST_START_TEST (test_expand_and_remove) GST_END_TEST; +GST_START_TEST (test_get_writable) +{ + GstBuffer *buf, *writable_buf; + + /* buffer list is initially empty */ + fail_unless (gst_buffer_list_length (list) == 0); + + /* Add 2 buffers */ + buf = gst_buffer_new (); + ASSERT_BUFFER_REFCOUNT (buf, "buf", 1); + gst_buffer_list_add (list, buf); + ASSERT_BUFFER_REFCOUNT (buf, "buf", 1); /* list takes ownership */ + fail_unless (gst_buffer_list_length (list) == 1); + fail_unless (buf == gst_buffer_list_get_writable (list, 0)); + fail_unless (buf == gst_buffer_list_get (list, 0)); + + /* extra ref to make buffer no longer writable */ + gst_buffer_ref (buf); + ASSERT_BUFFER_REFCOUNT (buf, "buf", 2); + fail_unless (buf == gst_buffer_list_get (list, 0)); + ASSERT_BUFFER_REFCOUNT (buf, "buf", 2); + + /* should make a copy to make it writable */ + writable_buf = gst_buffer_list_get_writable (list, 0); + fail_if (buf == writable_buf); + ASSERT_BUFFER_REFCOUNT (buf, "buf", 1); + ASSERT_BUFFER_REFCOUNT (writable_buf, "writable_buf", 1); + + gst_buffer_unref (buf); +} + +GST_END_TEST; + static Suite * gst_buffer_list_suite (void) { @@ -442,6 +475,7 @@ gst_buffer_list_suite (void) tcase_add_test (tc_chain, test_copy_deep); tcase_add_test (tc_chain, test_foreach); tcase_add_test (tc_chain, test_expand_and_remove); + tcase_add_test (tc_chain, test_get_writable); return s; } diff --git a/win32/common/libgstreamer.def b/win32/common/libgstreamer.def index db6f55a472..caea3484e7 100644 --- a/win32/common/libgstreamer.def +++ b/win32/common/libgstreamer.def @@ -150,6 +150,7 @@ EXPORTS gst_buffer_list_foreach gst_buffer_list_get gst_buffer_list_get_type + gst_buffer_list_get_writable gst_buffer_list_insert gst_buffer_list_length gst_buffer_list_new