summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThiago Santos <thiagoss@osg.samsung.com>2015-03-13 18:35:01 (GMT)
committerThiago Santos <thiagoss@osg.samsung.com>2015-03-13 18:37:04 (GMT)
commit96eaeadc0f3cbad3cf35d26f542b8359d27e316d (patch)
tree1dfe6f7db16eca01c3523ed56ebfa245891cd3e2
parentd8f572647fe1ee56d4e4a0a215626339a40890fa (diff)
downloadgstreamer-96eaeadc0f3cbad3cf35d26f542b8359d27e316d.tar.gz
gstreamer-96eaeadc0f3cbad3cf35d26f542b8359d27e316d.tar.xz
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
-rw-r--r--gst/gstbuffer.c29
-rw-r--r--gst/gstbuffer.h8
-rw-r--r--tests/check/gst/gstbuffer.c34
-rw-r--r--win32/common/libgstreamer.def1
4 files changed, 67 insertions, 5 deletions
diff --git a/gst/gstbuffer.c b/gst/gstbuffer.c
index 06a55b9..f364572 100644
--- a/gst/gstbuffer.c
+++ b/gst/gstbuffer.c
@@ -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 (&copy, 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
diff --git a/gst/gstbuffer.h b/gst/gstbuffer.h
index 643db7d..dd7f237 100644
--- a/gst/gstbuffer.h
+++ b/gst/gstbuffer.h
@@ -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:
diff --git a/tests/check/gst/gstbuffer.c b/tests/check/gst/gstbuffer.c
index e52175f..70cb191 100644
--- a/tests/check/gst/gstbuffer.c
+++ b/tests/check/gst/gstbuffer.c
@@ -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);
diff --git a/win32/common/libgstreamer.def b/win32/common/libgstreamer.def
index 675661d..22acb9d 100644
--- a/win32/common/libgstreamer.def
+++ b/win32/common/libgstreamer.def
@@ -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