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);
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;

View file

@ -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)

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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

View file

@ -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