buffer: more buffer updates

This commit is contained in:
Wim Taymans 2011-03-29 11:07:36 +02:00
parent 3ff26235cb
commit 6da19ffeb2
7 changed files with 94 additions and 144 deletions

View file

@ -198,12 +198,9 @@ gst_buffer_copy_into (GstBuffer * dest, GstBuffer * src,
bufsize = gst_buffer_get_size (src); bufsize = gst_buffer_get_size (src);
if (size == -1) if (size == -1)
size = bufsize - offset; size = bufsize - offset;
g_return_if_fail (bufsize >= offset + size);
#if GST_VERSION_NANO == 1 g_return_if_fail (bufsize >= offset + size);
/* we enable this extra debugging in git versions only for now */ g_return_if_fail (gst_buffer_is_writable (dest));
g_warn_if_fail (gst_buffer_is_writable (dest));
#endif
GST_CAT_LOG (GST_CAT_BUFFER, "copy %p to %p, offset %" G_GSIZE_FORMAT GST_CAT_LOG (GST_CAT_BUFFER, "copy %p to %p, offset %" G_GSIZE_FORMAT
"-%" G_GSIZE_FORMAT "/%" G_GSIZE_FORMAT, src, dest, offset, size, "-%" 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) { if (flags & GST_BUFFER_COPY_MEMORY) {
GPtrArray *sarr = (GPtrArray *) src->memory; GPtrArray *sarr = (GPtrArray *) src->memory;
GPtrArray *darr = (GPtrArray *) dest->memory; GPtrArray *darr = (GPtrArray *) dest->memory;
guint i, len; GstMemory *mem;
gsize left, len, i, bsize;
len = sarr->len; len = sarr->len;
left = size;
for (i = 0; i < len; i++) { /* copy and subbuffer */
GstMemory *mem, *dmem; for (i = 0; i < len && left > 0; i++) {
gsize msize;
mem = g_ptr_array_index (sarr, 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) { if (bsize <= offset) {
/* last chunk */ /* don't copy buffer */
dmem = gst_memory_sub (mem, offset, size); offset -= bsize;
} else if (offset) { } else {
if (msize > offset) { gsize tocopy;
dmem = gst_memory_sub (mem, offset, msize - offset);
offset = 0; tocopy = MIN (bsize - offset, left);
if (tocopy < bsize) {
/* we need to clip something */
mem = gst_memory_sub (mem, offset, tocopy);
} else { } else {
offset -= msize; mem = gst_memory_ref (mem);
dmem = NULL;
} }
} else g_ptr_array_add (darr, mem);
dmem = gst_memory_ref (mem); left -= tocopy;
}
if (dmem)
g_ptr_array_add (darr, dmem);
} }
} }
@ -391,43 +388,9 @@ gst_buffer_new (void)
* gst_buffer_new_and_alloc: * gst_buffer_new_and_alloc:
* @size: the size in bytes of the new buffer's data. * @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 * 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 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. * 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. * be allocated.
*/ */
GstBuffer * GstBuffer *
gst_buffer_try_new_and_alloc (guint size) gst_buffer_new_and_alloc (guint size)
{ {
GstBuffer *newbuf; GstBuffer *newbuf;
GstMemory *mem; 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. * @buffer: a #GstBuffer.
* @idx: an index * @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 void
gst_buffer_remove_memory (GstBuffer * buffer, guint idx) gst_buffer_remove_memory_range (GstBuffer * buffer, guint idx, guint length)
{ {
GPtrArray *arr; GPtrArray *arr;
g_return_if_fail (GST_IS_BUFFER (buffer)); g_return_if_fail (GST_IS_BUFFER (buffer));
g_return_if_fail (gst_buffer_is_writable (buffer)); g_return_if_fail (gst_buffer_is_writable (buffer));
arr = (GPtrArray *) buffer->memory; arr = (GPtrArray *) buffer->memory;
g_return_if_fail (idx < arr->len); if (length == -1) {
g_return_if_fail (idx < arr->len);
g_ptr_array_remove_index (arr, idx); 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; arr = (GPtrArray *) buffer->memory;
len = arr->len; len = arr->len;
si = di = 0;
/* copy and trim */ /* copy and trim */
while (size > 0) { for (di = si = 0; si < len && size > 0; si++) {
mem = g_ptr_array_index (arr, si); mem = g_ptr_array_index (arr, si);
bsize = gst_memory_get_sizes (mem, NULL); bsize = gst_memory_get_sizes (mem, NULL);
@ -629,28 +596,13 @@ gst_buffer_trim (GstBuffer * buffer, gsize offset, gsize size)
mem = tmp; mem = tmp;
} }
} }
g_ptr_array_index (arr, di) = mem; g_ptr_array_index (arr, di++) = mem;
size -= tocopy; size -= tocopy;
di++;
} }
si++;
} }
g_ptr_array_set_size (arr, di); 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: * gst_buffer_map:
* @buffer: a #GstBuffer. * @buffer: a #GstBuffer.
@ -710,6 +662,7 @@ gst_buffer_map (GstBuffer * buffer, gsize * size, gsize * maxsize,
data = gst_memory_map (mem, size, maxsize, flags); data = gst_memory_map (mem, size, maxsize, flags);
} else { } else {
/* FIXME, implement me */
data = NULL; data = NULL;
if (size) if (size)
*size = 0; *size = 0;
@ -752,6 +705,7 @@ gst_buffer_unmap (GstBuffer * buffer, gpointer data, gsize size)
result = gst_memory_unmap (mem, data, size); result = gst_memory_unmap (mem, data, size);
} else { } else {
/* FIXME, implement me */
result = FALSE; result = FALSE;
} }
return result; return result;

View file

@ -276,12 +276,6 @@ struct _GstBuffer {
guint64 offset; guint64 offset;
guint64 offset_end; 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 */ /* pointer to memory blocks */
gpointer memory; gpointer memory;
@ -290,48 +284,46 @@ struct _GstBuffer {
}; };
/* allocation */ /* allocation */
GstBuffer * gst_buffer_new (void); GstBuffer * gst_buffer_new (void);
GstBuffer * gst_buffer_new_and_alloc (guint size); GstBuffer * gst_buffer_new_and_alloc (guint size);
GstBuffer * gst_buffer_try_new_and_alloc (guint size);
/* memory blocks */ /* memory blocks */
guint gst_buffer_n_memory (GstBuffer *buffer); guint gst_buffer_n_memory (GstBuffer *buffer);
void gst_buffer_take_memory (GstBuffer *buffer, GstMemory *mem); void gst_buffer_take_memory (GstBuffer *buffer, GstMemory *mem);
GstMemory * gst_buffer_peek_memory (GstBuffer *buffer, guint idx); GstMemory * gst_buffer_peek_memory (GstBuffer *buffer, guint idx);
void gst_buffer_remove_memory (GstBuffer *buffer, guint idx); void gst_buffer_remove_memory_range (GstBuffer *buffer, guint idx, guint length);
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);
/** /**
* gst_buffer_set_data: * gst_buffer_remove_memory:
* @buf: a #GstBuffer * @b: a #GstBuffer.
* @data: The data (a #guint8 *) to set on the buffer. * @i: an index
* @size: The size (in bytes, as a #guint) of the data being set.
* *
* A convenience function to set the data and size on a buffer. * Remove the memory block in @b at @i.
* 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.
*/ */
#define gst_buffer_set_data(buf, data, size) \ #define gst_buffer_remove_memory(b,i) gst_buffer_remove_memory_range ((b), (i), 1)
G_STMT_START { \
GST_BUFFER_DATA (buf) = data; \ void gst_buffer_fill (GstBuffer *buffer, gsize offset,
GST_BUFFER_SIZE (buf) = size; \ gconstpointer src, gsize size);
} G_STMT_END 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 */ /* refcounting */
/** /**
@ -404,20 +396,28 @@ gst_buffer_copy (const GstBuffer * buf)
* @GST_BUFFER_COPY_TIMESTAMPS: flag indicating that buffer timestamp, duration, * @GST_BUFFER_COPY_TIMESTAMPS: flag indicating that buffer timestamp, duration,
* offset and offset_end should be copied * offset and offset_end should be copied
* @GST_BUFFER_COPY_CAPS: flag indicating that buffer caps 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() * A set of flags that can be provided to the gst_buffer_copy_into()
* function to specify which metadata fields should be copied. * function to specify which items should be copied.
*
* Since: 0.10.13
*/ */
typedef enum { typedef enum {
GST_BUFFER_COPY_FLAGS = (1 << 0), GST_BUFFER_COPY_FLAGS = (1 << 0),
GST_BUFFER_COPY_TIMESTAMPS = (1 << 1), GST_BUFFER_COPY_TIMESTAMPS = (1 << 1),
GST_BUFFER_COPY_CAPS = (1 << 2), GST_BUFFER_COPY_CAPS = (1 << 2),
GST_BUFFER_COPY_MEMORY = (1 << 3), GST_BUFFER_COPY_MEMORY = (1 << 3),
GST_BUFFER_COPY_MEMORY_MERGE = (1 << 4), GST_BUFFER_COPY_MERGE = (1 << 4)
} GstBufferCopyFlags; } 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) #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 * Combination of all possible fields that can be copied with
* gst_buffer_copy_into(). * gst_buffer_copy_into().
*
* Since: 0.10.13
*/ */
#define GST_BUFFER_COPY_ALL (GST_BUFFER_COPY_METADATA | GST_BUFFER_COPY_MEMORY) #define GST_BUFFER_COPY_ALL (GST_BUFFER_COPY_METADATA | GST_BUFFER_COPY_MEMORY)

View file

@ -2892,7 +2892,7 @@ fallback:
/* fallback case, allocate a buffer of our own, add pad caps. */ /* fallback case, allocate a buffer of our own, add pad caps. */
GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "fallback buffer alloc"); 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_OFFSET (*buf) = offset;
gst_buffer_set_caps (*buf, caps); gst_buffer_set_caps (*buf, caps);
return GST_FLOW_OK; return GST_FLOW_OK;
@ -3002,7 +3002,7 @@ wrong_size_fallback:
gst_buffer_unref (*buf); 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_OFFSET (*buf) = offset;
gst_buffer_set_caps (*buf, caps); gst_buffer_set_caps (*buf, caps);
return GST_FLOW_OK; return GST_FLOW_OK;

View file

@ -455,7 +455,7 @@ gst_fd_src_create (GstPushSrc * psrc, GstBuffer ** outbuf)
blocksize = GST_BASE_SRC (src)->blocksize; blocksize = GST_BASE_SRC (src)->blocksize;
/* create the buffer */ /* create the buffer */
buf = gst_buffer_try_new_and_alloc (blocksize); buf = gst_buffer_new_and_alloc (blocksize);
if (G_UNLIKELY (buf == NULL)) if (G_UNLIKELY (buf == NULL))
goto alloc_failed; goto alloc_failed;

View file

@ -814,7 +814,7 @@ gst_file_src_create_read (GstFileSrc * src, guint64 offset, guint length,
src->read_position = offset; 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)) if (G_UNLIKELY (buf == NULL && length > 0))
goto alloc_failed; goto alloc_failed;

View file

@ -448,7 +448,7 @@ GST_START_TEST (test_try_new_and_alloc)
guint8 *data; guint8 *data;
/* special case: alloc of 0 bytes results in new buffer with NULL 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 (buf != NULL);
fail_unless (GST_IS_BUFFER (buf)); fail_unless (GST_IS_BUFFER (buf));
data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ); 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); gst_buffer_unref (buf);
/* normal alloc should still work */ /* 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 (buf != NULL);
fail_unless (GST_IS_BUFFER (buf)); fail_unless (GST_IS_BUFFER (buf));
data = gst_buffer_map (buf, &size, NULL, GST_MAP_WRITE); 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 /* now this better fail (don't run in valgrind, it will abort
* or warn when passing silly arguments to malloc) */ * or warn when passing silly arguments to malloc) */
if (!RUNNING_ON_VALGRIND) { 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); fail_unless (buf == NULL);
} }
#endif #endif

View file

@ -136,14 +136,12 @@ EXPORTS
gst_buffer_pool_release_buffer gst_buffer_pool_release_buffer
gst_buffer_pool_set_active gst_buffer_pool_set_active
gst_buffer_pool_set_config gst_buffer_pool_set_config
gst_buffer_remove_memory gst_buffer_remove_memory_range
gst_buffer_remove_meta gst_buffer_remove_meta
gst_buffer_set_caps gst_buffer_set_caps
gst_buffer_set_size
gst_buffer_span gst_buffer_span
gst_buffer_take_memory gst_buffer_take_memory
gst_buffer_trim gst_buffer_trim
gst_buffer_try_new_and_alloc
gst_buffer_unmap gst_buffer_unmap
gst_buffering_mode_get_type gst_buffering_mode_get_type
gst_bus_add_signal_watch gst_bus_add_signal_watch