From 6da19ffeb2ce8bf3b27b2f18a3686fce4ddda00b Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 29 Mar 2011 11:07:36 +0200 Subject: [PATCH] buffer: more buffer updates --- gst/gstbuffer.c | 124 +++++++++++----------------------- gst/gstbuffer.h | 96 +++++++++++++------------- gst/gstpad.c | 4 +- plugins/elements/gstfdsrc.c | 2 +- plugins/elements/gstfilesrc.c | 2 +- tests/check/gst/gstbuffer.c | 6 +- win32/common/libgstreamer.def | 4 +- 7 files changed, 94 insertions(+), 144 deletions(-) diff --git a/gst/gstbuffer.c b/gst/gstbuffer.c index 7f92694776..0023f34f94 100644 --- a/gst/gstbuffer.c +++ b/gst/gstbuffer.c @@ -198,12 +198,9 @@ gst_buffer_copy_into (GstBuffer * dest, GstBuffer * src, bufsize = gst_buffer_get_size (src); if (size == -1) size = bufsize - offset; - g_return_if_fail (bufsize >= offset + size); -#if GST_VERSION_NANO == 1 - /* we enable this extra debugging in git versions only for now */ - g_warn_if_fail (gst_buffer_is_writable (dest)); -#endif + g_return_if_fail (bufsize >= offset + size); + g_return_if_fail (gst_buffer_is_writable (dest)); GST_CAT_LOG (GST_CAT_BUFFER, "copy %p to %p, offset %" G_GSIZE_FORMAT "-%" G_GSIZE_FORMAT "/%" G_GSIZE_FORMAT, src, dest, offset, size, @@ -243,33 +240,33 @@ gst_buffer_copy_into (GstBuffer * dest, GstBuffer * src, if (flags & GST_BUFFER_COPY_MEMORY) { GPtrArray *sarr = (GPtrArray *) src->memory; GPtrArray *darr = (GPtrArray *) dest->memory; - guint i, len; + GstMemory *mem; + gsize left, len, i, bsize; len = sarr->len; + left = size; - for (i = 0; i < len; i++) { - GstMemory *mem, *dmem; - gsize msize; - + /* copy and subbuffer */ + for (i = 0; i < len && left > 0; i++) { mem = g_ptr_array_index (sarr, i); - msize = gst_memory_get_sizes (mem, NULL); + bsize = gst_memory_get_sizes (mem, NULL); - if (i + 1 == len) { - /* last chunk */ - dmem = gst_memory_sub (mem, offset, size); - } else if (offset) { - if (msize > offset) { - dmem = gst_memory_sub (mem, offset, msize - offset); - offset = 0; + if (bsize <= offset) { + /* don't copy buffer */ + offset -= bsize; + } else { + gsize tocopy; + + tocopy = MIN (bsize - offset, left); + if (tocopy < bsize) { + /* we need to clip something */ + mem = gst_memory_sub (mem, offset, tocopy); } else { - offset -= msize; - dmem = NULL; + mem = gst_memory_ref (mem); } - } else - dmem = gst_memory_ref (mem); - - if (dmem) - g_ptr_array_add (darr, dmem); + g_ptr_array_add (darr, mem); + left -= tocopy; + } } } @@ -391,43 +388,9 @@ gst_buffer_new (void) * gst_buffer_new_and_alloc: * @size: the size in bytes of the new buffer's data. * - * Creates a newly allocated buffer with data of the given size. - * The buffer memory is not cleared. If the requested amount of - * memory can't be allocated, the program will abort. Use - * gst_buffer_try_new_and_alloc() if you want to handle this case - * gracefully or have gotten the size to allocate from an untrusted - * source such as a media stream. - * - * Note that when @size == 0, the buffer data pointer will be NULL. - * - * MT safe. - * - * Returns: (transfer full): the new #GstBuffer. - */ -GstBuffer * -gst_buffer_new_and_alloc (guint size) -{ - GstBuffer *newbuf; - - newbuf = gst_buffer_new (); - - if (size > 0) { - gst_buffer_take_memory (newbuf, gst_memory_new_alloc (size, - _gst_buffer_data_alignment)); - } - - GST_CAT_LOG (GST_CAT_BUFFER, "new %p of size %d", newbuf, size); - - return newbuf; -} - -/** - * gst_buffer_try_new_and_alloc: - * @size: the size in bytes of the new buffer's data. - * * Tries to create a newly allocated buffer with data of the given size. If * the requested amount of memory can't be allocated, NULL will be returned. - * The buffer memory is not cleared. + * The allocated buffer memory is not cleared. * * Note that when @size == 0, the buffer will not have memory associated with it. * @@ -437,7 +400,7 @@ gst_buffer_new_and_alloc (guint size) * be allocated. */ GstBuffer * -gst_buffer_try_new_and_alloc (guint size) +gst_buffer_new_and_alloc (guint size) { GstBuffer *newbuf; GstMemory *mem; @@ -535,23 +498,28 @@ gst_buffer_peek_memory (GstBuffer * buffer, guint idx) } /** - * gst_buffer_remove_memory: + * gst_buffer_remove_memory_range: * @buffer: a #GstBuffer. * @idx: an index + * @length: a length * - * Remove the memory block in @buffer at @idx. + * Remove @len memory blocks in @buffer starting from @idx. + * + * @length can be -1, in which case all memory starting from @idx is removed. */ void -gst_buffer_remove_memory (GstBuffer * buffer, guint idx) +gst_buffer_remove_memory_range (GstBuffer * buffer, guint idx, guint length) { GPtrArray *arr; g_return_if_fail (GST_IS_BUFFER (buffer)); g_return_if_fail (gst_buffer_is_writable (buffer)); arr = (GPtrArray *) buffer->memory; - g_return_if_fail (idx < arr->len); - - g_ptr_array_remove_index (arr, idx); + if (length == -1) { + g_return_if_fail (idx < arr->len); + length = arr->len - idx; + } + g_ptr_array_remove_range (arr, idx, length); } /** @@ -603,10 +571,9 @@ gst_buffer_trim (GstBuffer * buffer, gsize offset, gsize size) arr = (GPtrArray *) buffer->memory; len = arr->len; - si = di = 0; /* copy and trim */ - while (size > 0) { + for (di = si = 0; si < len && size > 0; si++) { mem = g_ptr_array_index (arr, si); bsize = gst_memory_get_sizes (mem, NULL); @@ -629,28 +596,13 @@ gst_buffer_trim (GstBuffer * buffer, gsize offset, gsize size) mem = tmp; } } - g_ptr_array_index (arr, di) = mem; + g_ptr_array_index (arr, di++) = mem; size -= tocopy; - di++; } - si++; } g_ptr_array_set_size (arr, di); } -/** - * gst_buffer_set_size: - * @buffer: a #GstBuffer. - * @size: the new size - * - * Set the total size of the buffer - */ -void -gst_buffer_set_size (GstBuffer * buffer, gsize size) -{ - gst_buffer_trim (buffer, 0, size); -} - /** * gst_buffer_map: * @buffer: a #GstBuffer. @@ -710,6 +662,7 @@ gst_buffer_map (GstBuffer * buffer, gsize * size, gsize * maxsize, data = gst_memory_map (mem, size, maxsize, flags); } else { + /* FIXME, implement me */ data = NULL; if (size) *size = 0; @@ -752,6 +705,7 @@ gst_buffer_unmap (GstBuffer * buffer, gpointer data, gsize size) result = gst_memory_unmap (mem, data, size); } else { + /* FIXME, implement me */ result = FALSE; } return result; diff --git a/gst/gstbuffer.h b/gst/gstbuffer.h index eaba4469d9..a92f8fe72b 100644 --- a/gst/gstbuffer.h +++ b/gst/gstbuffer.h @@ -276,12 +276,6 @@ struct _GstBuffer { guint64 offset; guint64 offset_end; - /* pointer to data and its size, backwards compatibility */ - guint8 *bw_data; - guint bw_size; - guint8 *bw_malloc_data; - GFreeFunc bw_free_func; - /* pointer to memory blocks */ gpointer memory; @@ -290,48 +284,46 @@ struct _GstBuffer { }; /* allocation */ -GstBuffer * gst_buffer_new (void); -GstBuffer * gst_buffer_new_and_alloc (guint size); -GstBuffer * gst_buffer_try_new_and_alloc (guint size); +GstBuffer * gst_buffer_new (void); +GstBuffer * gst_buffer_new_and_alloc (guint size); /* memory blocks */ -guint gst_buffer_n_memory (GstBuffer *buffer); -void gst_buffer_take_memory (GstBuffer *buffer, GstMemory *mem); -GstMemory * gst_buffer_peek_memory (GstBuffer *buffer, guint idx); -void gst_buffer_remove_memory (GstBuffer *buffer, guint idx); - -void gst_buffer_fill (GstBuffer *buffer, gsize offset, - gconstpointer src, gsize size); -void gst_buffer_extract (GstBuffer *buffer, gsize offset, - gpointer dest, gsize size); - -gsize gst_buffer_get_size (GstBuffer *buffer); -void gst_buffer_set_size (GstBuffer *buffer, gsize size); -void gst_buffer_trim (GstBuffer *buffer, gsize offset, gsize size); - -/* getting memory */ -gpointer gst_buffer_map (GstBuffer *buffer, gsize *size, gsize *maxsize, - GstMapFlags flags); -gboolean gst_buffer_unmap (GstBuffer *buffer, gpointer data, gsize size); +guint gst_buffer_n_memory (GstBuffer *buffer); +void gst_buffer_take_memory (GstBuffer *buffer, GstMemory *mem); +GstMemory * gst_buffer_peek_memory (GstBuffer *buffer, guint idx); +void gst_buffer_remove_memory_range (GstBuffer *buffer, guint idx, guint length); /** - * gst_buffer_set_data: - * @buf: a #GstBuffer - * @data: The data (a #guint8 *) to set on the buffer. - * @size: The size (in bytes, as a #guint) of the data being set. + * gst_buffer_remove_memory: + * @b: a #GstBuffer. + * @i: an index * - * A convenience function to set the data and size on a buffer. - * This will replace any existing data pointer set on this buffer, but will - * not change GST_BUFFER_MALLOCDATA(), if any. Callers should ensure that - * GST_BUFFER_MALLOCDATA() is non-NULL, or should free that and set it to NULL. - * - * No checks are done on the data or size arguments passed. + * Remove the memory block in @b at @i. */ -#define gst_buffer_set_data(buf, data, size) \ -G_STMT_START { \ - GST_BUFFER_DATA (buf) = data; \ - GST_BUFFER_SIZE (buf) = size; \ -} G_STMT_END +#define gst_buffer_remove_memory(b,i) gst_buffer_remove_memory_range ((b), (i), 1) + +void gst_buffer_fill (GstBuffer *buffer, gsize offset, + gconstpointer src, gsize size); +void gst_buffer_extract (GstBuffer *buffer, gsize offset, + gpointer dest, gsize size); + +gsize gst_buffer_get_size (GstBuffer *buffer); +void gst_buffer_trim (GstBuffer *buffer, gsize offset, gsize size); + +/** + * gst_buffer_remove_memory: + * @b: a #GstBuffer. + * @s: a new size + * + * Set the size of @b to @s. This will remove or trim the memory blocks + * in the buffer. + */ +#define gst_buffer_set_size(b,s) gst_buffer_trim ((b), 0, (s)) + +/* getting memory */ +gpointer gst_buffer_map (GstBuffer *buffer, gsize *size, gsize *maxsize, + GstMapFlags flags); +gboolean gst_buffer_unmap (GstBuffer *buffer, gpointer data, gsize size); /* refcounting */ /** @@ -404,20 +396,28 @@ gst_buffer_copy (const GstBuffer * buf) * @GST_BUFFER_COPY_TIMESTAMPS: flag indicating that buffer timestamp, duration, * offset and offset_end should be copied * @GST_BUFFER_COPY_CAPS: flag indicating that buffer caps should be copied + * @GST_BUFFER_COPY_MEMORY: flag indicating that buffer memory should be copied + * and appended to already existing memory + * @GST_BUFFER_COPY_MERGE: flag indicating that buffer memory should be + * merged * - * A set of flags that can be provided to the gst_buffer_copy_metadata() - * function to specify which metadata fields should be copied. - * - * Since: 0.10.13 + * A set of flags that can be provided to the gst_buffer_copy_into() + * function to specify which items should be copied. */ typedef enum { GST_BUFFER_COPY_FLAGS = (1 << 0), GST_BUFFER_COPY_TIMESTAMPS = (1 << 1), GST_BUFFER_COPY_CAPS = (1 << 2), GST_BUFFER_COPY_MEMORY = (1 << 3), - GST_BUFFER_COPY_MEMORY_MERGE = (1 << 4), + GST_BUFFER_COPY_MERGE = (1 << 4) } GstBufferCopyFlags; +/** + * GST_BUFFER_COPY_METADATA: + * + * Combination of all possible metadata fields that can be copied with + * gst_buffer_copy_into(). + */ #define GST_BUFFER_COPY_METADATA (GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_CAPS) /** @@ -425,8 +425,6 @@ typedef enum { * * Combination of all possible fields that can be copied with * gst_buffer_copy_into(). - * - * Since: 0.10.13 */ #define GST_BUFFER_COPY_ALL (GST_BUFFER_COPY_METADATA | GST_BUFFER_COPY_MEMORY) diff --git a/gst/gstpad.c b/gst/gstpad.c index 46f0f682c8..e0643869af 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -2892,7 +2892,7 @@ fallback: /* fallback case, allocate a buffer of our own, add pad caps. */ GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "fallback buffer alloc"); - if ((*buf = gst_buffer_try_new_and_alloc (size))) { + if ((*buf = gst_buffer_new_and_alloc (size))) { GST_BUFFER_OFFSET (*buf) = offset; gst_buffer_set_caps (*buf, caps); return GST_FLOW_OK; @@ -3002,7 +3002,7 @@ wrong_size_fallback: gst_buffer_unref (*buf); - if ((*buf = gst_buffer_try_new_and_alloc (size))) { + if ((*buf = gst_buffer_new_and_alloc (size))) { GST_BUFFER_OFFSET (*buf) = offset; gst_buffer_set_caps (*buf, caps); return GST_FLOW_OK; diff --git a/plugins/elements/gstfdsrc.c b/plugins/elements/gstfdsrc.c index 8180ae5dfd..e36a9cc449 100644 --- a/plugins/elements/gstfdsrc.c +++ b/plugins/elements/gstfdsrc.c @@ -455,7 +455,7 @@ gst_fd_src_create (GstPushSrc * psrc, GstBuffer ** outbuf) blocksize = GST_BASE_SRC (src)->blocksize; /* create the buffer */ - buf = gst_buffer_try_new_and_alloc (blocksize); + buf = gst_buffer_new_and_alloc (blocksize); if (G_UNLIKELY (buf == NULL)) goto alloc_failed; diff --git a/plugins/elements/gstfilesrc.c b/plugins/elements/gstfilesrc.c index 7df201e16e..c5fa9988f3 100644 --- a/plugins/elements/gstfilesrc.c +++ b/plugins/elements/gstfilesrc.c @@ -814,7 +814,7 @@ gst_file_src_create_read (GstFileSrc * src, guint64 offset, guint length, src->read_position = offset; } - buf = gst_buffer_try_new_and_alloc (length); + buf = gst_buffer_new_and_alloc (length); if (G_UNLIKELY (buf == NULL && length > 0)) goto alloc_failed; diff --git a/tests/check/gst/gstbuffer.c b/tests/check/gst/gstbuffer.c index 7c455e83d2..a327380d5a 100644 --- a/tests/check/gst/gstbuffer.c +++ b/tests/check/gst/gstbuffer.c @@ -448,7 +448,7 @@ GST_START_TEST (test_try_new_and_alloc) guint8 *data; /* special case: alloc of 0 bytes results in new buffer with NULL data */ - buf = gst_buffer_try_new_and_alloc (0); + buf = gst_buffer_new_and_alloc (0); fail_unless (buf != NULL); fail_unless (GST_IS_BUFFER (buf)); data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ); @@ -457,7 +457,7 @@ GST_START_TEST (test_try_new_and_alloc) gst_buffer_unref (buf); /* normal alloc should still work */ - buf = gst_buffer_try_new_and_alloc (640 * 480 * 4); + buf = gst_buffer_new_and_alloc (640 * 480 * 4); fail_unless (buf != NULL); fail_unless (GST_IS_BUFFER (buf)); data = gst_buffer_map (buf, &size, NULL, GST_MAP_WRITE); @@ -477,7 +477,7 @@ GST_START_TEST (test_try_new_and_alloc) /* now this better fail (don't run in valgrind, it will abort * or warn when passing silly arguments to malloc) */ if (!RUNNING_ON_VALGRIND) { - buf = gst_buffer_try_new_and_alloc ((guint) - 1); + buf = gst_buffer_new_and_alloc ((guint) - 1); fail_unless (buf == NULL); } #endif diff --git a/win32/common/libgstreamer.def b/win32/common/libgstreamer.def index d6a5baf88a..2d65d42bd6 100644 --- a/win32/common/libgstreamer.def +++ b/win32/common/libgstreamer.def @@ -136,14 +136,12 @@ EXPORTS gst_buffer_pool_release_buffer gst_buffer_pool_set_active gst_buffer_pool_set_config - gst_buffer_remove_memory + gst_buffer_remove_memory_range gst_buffer_remove_meta gst_buffer_set_caps - gst_buffer_set_size gst_buffer_span gst_buffer_take_memory gst_buffer_trim - gst_buffer_try_new_and_alloc gst_buffer_unmap gst_buffering_mode_get_type gst_bus_add_signal_watch