mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
gstbuffer: add gst_buffer_copy_deep
A variant of gst_buffer_copy that forces the underlying memory to be copied. This is added to avoid adding an extra reference to a GstMemory that might belong to a bufferpool that is trying to be drained. The use case is when the buffer copying is done to release the old buffer and all its resources. https://bugzilla.gnome.org/show_bug.cgi?id=745287
This commit is contained in:
parent
d8f572647f
commit
96eaeadc0f
4 changed files with 67 additions and 5 deletions
|
@ -508,7 +508,7 @@ gst_buffer_copy_into (GstBuffer * dest, GstBuffer * src,
|
|||
}
|
||||
|
||||
static GstBuffer *
|
||||
_gst_buffer_copy (GstBuffer * buffer)
|
||||
gst_buffer_copy_with_flags (const GstBuffer * buffer, GstBufferFlags flags)
|
||||
{
|
||||
GstBuffer *copy;
|
||||
|
||||
|
@ -517,8 +517,9 @@ _gst_buffer_copy (GstBuffer * buffer)
|
|||
/* create a fresh new buffer */
|
||||
copy = gst_buffer_new ();
|
||||
|
||||
/* we simply copy everything from our parent */
|
||||
if (!gst_buffer_copy_into (copy, buffer, GST_BUFFER_COPY_ALL, 0, -1))
|
||||
/* copy what the 'flags' want from our parent */
|
||||
/* FIXME why we can't pass const to gst_buffer_copy_into() ? */
|
||||
if (!gst_buffer_copy_into (copy, (GstBuffer *) buffer, flags, 0, -1))
|
||||
gst_buffer_replace (©, NULL);
|
||||
|
||||
if (copy)
|
||||
|
@ -527,6 +528,28 @@ _gst_buffer_copy (GstBuffer * buffer)
|
|||
return copy;
|
||||
}
|
||||
|
||||
static GstBuffer *
|
||||
_gst_buffer_copy (const GstBuffer * buffer)
|
||||
{
|
||||
return gst_buffer_copy_with_flags (buffer, GST_BUFFER_COPY_ALL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_buffer_copy_deep:
|
||||
* @buf: a #GstBuffer.
|
||||
*
|
||||
* Create a copy of the given buffer. This will make a newly allocated
|
||||
* copy of the data the source buffer contains.
|
||||
*
|
||||
* Returns: (transfer full): a new copy of @buf.
|
||||
*/
|
||||
GstBuffer *
|
||||
gst_buffer_copy_deep (const GstBuffer * buffer)
|
||||
{
|
||||
return gst_buffer_copy_with_flags (buffer,
|
||||
GST_BUFFER_COPY_ALL | GST_BUFFER_COPY_DEEP);
|
||||
}
|
||||
|
||||
/* the default dispose function revives the buffer and returns it to the
|
||||
* pool when there is a pool */
|
||||
static gboolean
|
||||
|
|
|
@ -365,8 +365,11 @@ gst_buffer_unref (GstBuffer * buf)
|
|||
* gst_buffer_copy:
|
||||
* @buf: a #GstBuffer.
|
||||
*
|
||||
* Create a copy of the given buffer. This will also make a newly allocated
|
||||
* copy of the data the source buffer contains.
|
||||
* Create a copy of the given buffer. This will only copy the buffer's
|
||||
* data to a newly allocated memory if needed (if the type of memory
|
||||
* requires it), otherwise the underlying data is just referenced.
|
||||
* Check gst_buffer_copy_deep() if you want to force the data
|
||||
* to be copied to newly allocated memory.
|
||||
*
|
||||
* Returns: (transfer full): a new copy of @buf.
|
||||
*/
|
||||
|
@ -380,6 +383,7 @@ gst_buffer_copy (const GstBuffer * buf)
|
|||
return GST_BUFFER (gst_mini_object_copy (GST_MINI_OBJECT_CONST_CAST (buf)));
|
||||
}
|
||||
|
||||
GstBuffer * gst_buffer_copy_deep (const GstBuffer * buf);
|
||||
|
||||
/**
|
||||
* GstBufferCopyFlags:
|
||||
|
|
|
@ -340,6 +340,8 @@ GST_START_TEST (test_copy)
|
|||
|
||||
/* NOTE that data is refcounted */
|
||||
fail_unless (info.size == sinfo.size);
|
||||
/* GstBuffer was copied but the underlying GstMemory should be the same */
|
||||
fail_unless (info.data == sinfo.data);
|
||||
|
||||
gst_buffer_unmap (copy, &sinfo);
|
||||
gst_buffer_unmap (buffer, &info);
|
||||
|
@ -408,6 +410,37 @@ GST_START_TEST (test_copy)
|
|||
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST (test_copy_deep)
|
||||
{
|
||||
GstBuffer *buffer, *copy;
|
||||
GstMapInfo info, sinfo;
|
||||
|
||||
buffer = gst_buffer_new_and_alloc (4);
|
||||
ASSERT_BUFFER_REFCOUNT (buffer, "buffer", 1);
|
||||
|
||||
copy = gst_buffer_copy_deep (buffer);
|
||||
ASSERT_BUFFER_REFCOUNT (buffer, "buffer", 1);
|
||||
ASSERT_BUFFER_REFCOUNT (copy, "copy", 1);
|
||||
/* buffers are copied and must point to different memory */
|
||||
fail_if (buffer == copy);
|
||||
|
||||
fail_unless (gst_buffer_map (buffer, &info, GST_MAP_READ));
|
||||
fail_unless (gst_buffer_map (copy, &sinfo, GST_MAP_READ));
|
||||
|
||||
/* NOTE that data is refcounted */
|
||||
fail_unless (info.size == sinfo.size);
|
||||
/* copy_deep() forces new GstMemory to be used */
|
||||
fail_unless (info.data != sinfo.data);
|
||||
|
||||
gst_buffer_unmap (copy, &sinfo);
|
||||
gst_buffer_unmap (buffer, &info);
|
||||
|
||||
gst_buffer_unref (copy);
|
||||
gst_buffer_unref (buffer);
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST (test_try_new_and_alloc)
|
||||
{
|
||||
GstBuffer *buf;
|
||||
|
@ -871,6 +904,7 @@ gst_buffer_suite (void)
|
|||
tcase_add_test (tc_chain, test_metadata_writable);
|
||||
tcase_add_test (tc_chain, test_memcmp);
|
||||
tcase_add_test (tc_chain, test_copy);
|
||||
tcase_add_test (tc_chain, test_copy_deep);
|
||||
tcase_add_test (tc_chain, test_try_new_and_alloc);
|
||||
tcase_add_test (tc_chain, test_size);
|
||||
tcase_add_test (tc_chain, test_resize);
|
||||
|
|
|
@ -115,6 +115,7 @@ EXPORTS
|
|||
gst_buffer_append
|
||||
gst_buffer_append_memory
|
||||
gst_buffer_append_region
|
||||
gst_buffer_copy_deep
|
||||
gst_buffer_copy_flags_get_type
|
||||
gst_buffer_copy_into
|
||||
gst_buffer_copy_region
|
||||
|
|
Loading…
Reference in a new issue