From a5e1ec0edc025d803ca39796ec802ab8aab99733 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 7 Apr 2011 16:02:43 +0200 Subject: [PATCH] memory: add NO_SHARE flag to memory Add a NO_SHARE flag to memory to indicate that it should not be shared between buffers. --- gst/gstbuffer.c | 33 +++++++++++++++++++++++++-------- gst/gstmemory.h | 10 ++++++++-- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/gst/gstbuffer.c b/gst/gstbuffer.c index 53ceed02bc..7fa1db9a7d 100644 --- a/gst/gstbuffer.c +++ b/gst/gstbuffer.c @@ -309,26 +309,32 @@ gst_buffer_copy_into (GstBuffer * dest, GstBuffer * src, if (flags & GST_BUFFER_COPY_MEMORY) { GstMemory *mem; - gsize left, len, i, bsize; + gsize skip, left, len, i, bsize; len = GST_BUFFER_MEM_LEN (src); left = size; + skip = offset; /* copy and make regions of the memory */ for (i = 0; i < len && left > 0; i++) { mem = GST_BUFFER_MEM_PTR (src, i); bsize = gst_memory_get_sizes (mem, NULL); - if (bsize <= offset) { + if (bsize <= skip) { /* don't copy buffer */ - offset -= bsize; + skip -= bsize; } else { gsize tocopy; - tocopy = MIN (bsize - offset, left); - if (tocopy < bsize) { + tocopy = MIN (bsize - skip, left); + if (mem->flags & GST_MEMORY_FLAG_NO_SHARE) { + /* no share, always copy then */ + mem = gst_memory_copy (mem, skip, tocopy); + skip = 0; + } else if (tocopy < bsize) { /* we need to clip something */ - mem = gst_memory_share (mem, offset, tocopy); + mem = gst_memory_share (mem, skip, tocopy); + skip = 0; } else { mem = gst_memory_ref (mem); } @@ -604,6 +610,8 @@ _get_memory (GstBuffer * buffer, guint idx, gboolean write) if (G_UNLIKELY (write && !GST_MEMORY_IS_WRITABLE (mem))) { GstMemory *copy; + GST_CAT_LOG (GST_CAT_BUFFER, + "making writable copy of memory %p in buffer %p", mem, buffer); /* replace with a writable copy */ copy = gst_memory_copy (mem, 0, -1); GST_BUFFER_MEM_PTR (buffer, idx) = copy; @@ -758,10 +766,16 @@ gst_buffer_resize (GstBuffer * buffer, gsize offset, gsize size) gst_memory_resize (mem, offset, tocopy); } else { GstMemory *tmp; - tmp = gst_memory_share (mem, offset, tocopy); + + if (mem->flags & GST_MEMORY_FLAG_NO_SHARE) + tmp = gst_memory_copy (mem, offset, tocopy); + else + tmp = gst_memory_share (mem, offset, tocopy); + gst_memory_unref (mem); mem = tmp; } + offset = 0; } GST_BUFFER_MEM_PTR (buffer, di++) = mem; size -= tocopy; @@ -1137,7 +1151,10 @@ _gst_buffer_arr_span (GstMemory ** mem[], gsize len[], guint n, gsize offset, if (!writable && _gst_buffer_arr_is_span_fast (mem, len, n, &poffset, &parent)) { - span = gst_memory_share (parent, offset + poffset, size); + if (parent->flags & GST_MEMORY_FLAG_NO_SHARE) + span = gst_memory_copy (parent, offset + poffset, size); + else + span = gst_memory_share (parent, offset + poffset, size); } else { gsize count, left; guint8 *dest, *ptr; diff --git a/gst/gstmemory.h b/gst/gstmemory.h index a18812b2bc..2a570f11a6 100644 --- a/gst/gstmemory.h +++ b/gst/gstmemory.h @@ -35,12 +35,18 @@ typedef struct _GstMemoryImpl GstMemoryImpl; /** * GstMemoryFlags: - * @GST_MEMORY_FLAG_READONLY: memory is readonly + * @GST_MEMORY_FLAG_READONLY: memory is readonly. It is not allowed to map the + * memory with #GST_MAP_WRITE. + * @GST_MEMORY_FLAG_NO_SHARE: memory must not be shared. Copies will have to be + * made when this memory needs to be shared between buffers. * * Flags for wrapped memory. */ typedef enum { - GST_MEMORY_FLAG_READONLY = (1 << 0) + GST_MEMORY_FLAG_READONLY = (1 << 0), + GST_MEMORY_FLAG_NO_SHARE = (1 << 1), + + GST_MEMORY_FLAG_LAST = (1 << 24) } GstMemoryFlags; /**