mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-07-02 20:55:55 +00:00
buffer: clean up _span and add more g_return_if..
This commit is contained in:
parent
d9becdcd27
commit
4e32ac8463
186
gst/gstbuffer.c
186
gst/gstbuffer.c
|
@ -131,6 +131,9 @@
|
|||
|
||||
GType _gst_buffer_type = 0;
|
||||
|
||||
static GstMemory *_gst_buffer_arr_span (GstMemory ** mem[], gsize len[],
|
||||
guint n, gsize offset, gsize size);
|
||||
|
||||
typedef struct _GstMetaItem GstMetaItem;
|
||||
|
||||
struct _GstMetaItem
|
||||
|
@ -157,12 +160,38 @@ typedef struct
|
|||
GstMetaItem *item;
|
||||
} GstBufferImpl;
|
||||
|
||||
static void
|
||||
_span_memory (GstBuffer * buffer, gsize offset, gsize size)
|
||||
{
|
||||
GstMemory *span, **mem[1];
|
||||
gsize len[1], i;
|
||||
|
||||
/* not enough room, span buffers */
|
||||
mem[0] = GST_BUFFER_MEM_ARRAY (buffer);
|
||||
len[0] = GST_BUFFER_MEM_LEN (buffer);
|
||||
span = _gst_buffer_arr_span (mem, len, 1, offset, size);
|
||||
|
||||
/* unref old buffers */
|
||||
for (i = 0; i < len[0]; i++)
|
||||
gst_memory_unref (mem[0][i]);
|
||||
|
||||
/* replace with single spanned buffer */
|
||||
GST_BUFFER_MEM_PTR (buffer, 0) = span;
|
||||
GST_BUFFER_MEM_LEN (buffer) = 1;
|
||||
}
|
||||
|
||||
static inline void
|
||||
_memory_add (GstBuffer * buffer, GstMemory * mem)
|
||||
{
|
||||
guint len = GST_BUFFER_MEM_LEN (buffer);
|
||||
/* FIXME, span buffers when we run out of places */
|
||||
g_return_if_fail (len < GST_BUFFER_MEM_MAX);
|
||||
|
||||
if (G_UNLIKELY (len >= GST_BUFFER_MEM_MAX)) {
|
||||
gsize size = gst_buffer_get_size (buffer);
|
||||
/* to many buffer, span them */
|
||||
_span_memory (buffer, 0, size);
|
||||
/* we now have 1 single spanned buffer */
|
||||
len = 1;
|
||||
}
|
||||
GST_BUFFER_MEM_PTR (buffer, len) = mem;
|
||||
GST_BUFFER_MEM_LEN (buffer) = len + 1;
|
||||
}
|
||||
|
@ -223,12 +252,13 @@ gst_buffer_copy_into (GstBuffer * dest, GstBuffer * src,
|
|||
if (G_UNLIKELY (dest == src))
|
||||
return;
|
||||
|
||||
g_return_if_fail (gst_buffer_is_writable (dest));
|
||||
|
||||
bufsize = gst_buffer_get_size (src);
|
||||
g_return_if_fail (bufsize >= offset);
|
||||
if (size == -1)
|
||||
size = bufsize - offset;
|
||||
|
||||
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,
|
||||
|
@ -646,7 +676,7 @@ gst_buffer_trim (GstBuffer * buffer, gsize offset, gsize size)
|
|||
{
|
||||
guint len;
|
||||
guint si, di;
|
||||
gsize bsize;
|
||||
gsize bsize, bufsize;
|
||||
GstMemory *mem;
|
||||
|
||||
GST_CAT_LOG (GST_CAT_BUFFER, "trim %p %" G_GSIZE_FORMAT "-%" G_GSIZE_FORMAT,
|
||||
|
@ -654,6 +684,12 @@ gst_buffer_trim (GstBuffer * buffer, gsize offset, gsize size)
|
|||
|
||||
g_return_if_fail (gst_buffer_is_writable (buffer));
|
||||
|
||||
bufsize = gst_buffer_get_size (buffer);
|
||||
g_return_if_fail (bufsize >= offset);
|
||||
if (size == -1)
|
||||
size = bufsize - offset;
|
||||
g_return_if_fail (bufsize >= offset + size);
|
||||
|
||||
len = GST_BUFFER_MEM_LEN (buffer);
|
||||
|
||||
/* copy and trim */
|
||||
|
@ -963,8 +999,10 @@ gst_buffer_create_sub (GstBuffer * buffer, gsize offset, gsize size)
|
|||
|
||||
g_return_val_if_fail (buffer != NULL, NULL);
|
||||
g_return_val_if_fail (buffer->mini_object.refcount > 0, NULL);
|
||||
|
||||
bufsize = gst_buffer_get_size (buffer);
|
||||
g_return_val_if_fail (bufsize >= offset, NULL);
|
||||
if (size == -1)
|
||||
size = bufsize - offset;
|
||||
g_return_val_if_fail (bufsize >= offset + size, NULL);
|
||||
|
||||
/* create the new buffer */
|
||||
|
@ -978,6 +1016,92 @@ gst_buffer_create_sub (GstBuffer * buffer, gsize offset, gsize size)
|
|||
return subbuffer;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_gst_buffer_arr_is_span_fast (GstMemory ** mem[], gsize len[], guint n,
|
||||
gsize * offset, GstMemory ** parent)
|
||||
{
|
||||
GstMemory *mcur, *mprv;
|
||||
gboolean have_offset = FALSE;
|
||||
guint count, i;
|
||||
|
||||
mcur = mprv = NULL;
|
||||
for (count = 0; count < n; count++) {
|
||||
gsize offs, clen;
|
||||
GstMemory **cmem;
|
||||
|
||||
cmem = mem[count];
|
||||
clen = len[count];
|
||||
|
||||
for (i = 0; i < clen; i++) {
|
||||
if (mcur)
|
||||
mprv = mcur;
|
||||
mcur = cmem[i];
|
||||
|
||||
if (mprv && mcur) {
|
||||
/* check is memory is contiguous */
|
||||
if (!gst_memory_is_span (mprv, mcur, &offs))
|
||||
return FALSE;
|
||||
|
||||
if (!have_offset) {
|
||||
if (offset)
|
||||
*offset = offs;
|
||||
if (parent)
|
||||
*parent = mprv->parent;
|
||||
|
||||
have_offset = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return have_offset;
|
||||
}
|
||||
|
||||
static GstMemory *
|
||||
_gst_buffer_arr_span (GstMemory ** mem[], gsize len[], guint n, gsize offset,
|
||||
gsize size)
|
||||
{
|
||||
GstMemory *span, *parent;
|
||||
gsize poffset;
|
||||
|
||||
if (_gst_buffer_arr_is_span_fast (mem, len, n, &poffset, &parent)) {
|
||||
span = gst_memory_sub (parent, offset + poffset, size);
|
||||
} else {
|
||||
gsize count, left;
|
||||
guint8 *dest, *ptr;
|
||||
|
||||
span = gst_memory_new_alloc (size, 0);
|
||||
dest = gst_memory_map (span, NULL, NULL, GST_MAP_WRITE);
|
||||
|
||||
ptr = dest;
|
||||
left = size;
|
||||
|
||||
for (count = 0; count < n; count++) {
|
||||
gsize i, tocopy, clen, ssize;
|
||||
guint8 *src;
|
||||
GstMemory **cmem;
|
||||
|
||||
cmem = mem[count];
|
||||
clen = len[count];
|
||||
|
||||
for (i = 0; i < clen && left > 0; i++) {
|
||||
src = gst_memory_map (cmem[i], &ssize, NULL, GST_MAP_READ);
|
||||
tocopy = MIN (ssize, left);
|
||||
if (tocopy > offset) {
|
||||
memcpy (ptr, src + offset, tocopy - offset);
|
||||
left -= tocopy;
|
||||
ptr += tocopy;
|
||||
offset = 0;
|
||||
} else {
|
||||
offset -= tocopy;
|
||||
}
|
||||
gst_memory_unmap (cmem[i], src, ssize);
|
||||
}
|
||||
}
|
||||
gst_memory_unmap (span, dest, size);
|
||||
}
|
||||
return span;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_buffer_is_span_fast:
|
||||
* @buf1: the first #GstBuffer.
|
||||
|
@ -994,20 +1118,20 @@ gst_buffer_create_sub (GstBuffer * buffer, gsize offset, gsize size)
|
|||
gboolean
|
||||
gst_buffer_is_span_fast (GstBuffer * buf1, GstBuffer * buf2)
|
||||
{
|
||||
GstMemory **arr1, **arr2;
|
||||
gsize len1, len2;
|
||||
GstMemory **mem[2];
|
||||
gsize len[2];
|
||||
|
||||
g_return_val_if_fail (GST_IS_BUFFER (buf1), FALSE);
|
||||
g_return_val_if_fail (GST_IS_BUFFER (buf2), FALSE);
|
||||
g_return_val_if_fail (buf1->mini_object.refcount > 0, FALSE);
|
||||
g_return_val_if_fail (buf2->mini_object.refcount > 0, FALSE);
|
||||
|
||||
arr1 = GST_BUFFER_MEM_ARRAY (buf1);
|
||||
len1 = GST_BUFFER_MEM_LEN (buf1);
|
||||
arr2 = GST_BUFFER_MEM_ARRAY (buf2);
|
||||
len2 = GST_BUFFER_MEM_LEN (buf2);
|
||||
mem[0] = GST_BUFFER_MEM_ARRAY (buf1);
|
||||
len[0] = GST_BUFFER_MEM_LEN (buf1);
|
||||
mem[1] = GST_BUFFER_MEM_ARRAY (buf2);
|
||||
len[1] = GST_BUFFER_MEM_LEN (buf2);
|
||||
|
||||
return gst_memory_is_span (arr1, len1, arr2, len2, NULL, NULL);
|
||||
return _gst_buffer_arr_is_span_fast (mem, len, 2, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1016,7 +1140,7 @@ gst_buffer_is_span_fast (GstBuffer * buf1, GstBuffer * buf2)
|
|||
* @offset: the offset in the first buffer from where the new
|
||||
* buffer should start.
|
||||
* @buf2: the second source #GstBuffer to merge.
|
||||
* @len: the total length of the new buffer.
|
||||
* @size: the total size of the new buffer.
|
||||
*
|
||||
* Creates a new buffer that consists of part of buf1 and buf2.
|
||||
* Logically, buf1 and buf2 are concatenated into a single larger
|
||||
|
@ -1034,30 +1158,34 @@ gst_buffer_is_span_fast (GstBuffer * buf1, GstBuffer * buf2)
|
|||
* buffers, or NULL if the arguments are invalid.
|
||||
*/
|
||||
GstBuffer *
|
||||
gst_buffer_span (GstBuffer * buf1, gsize offset, GstBuffer * buf2, gsize len)
|
||||
gst_buffer_span (GstBuffer * buf1, gsize offset, GstBuffer * buf2, gsize size)
|
||||
{
|
||||
GstBuffer *newbuf;
|
||||
GstMemory **arr1, **arr2;
|
||||
gsize len1, len2;
|
||||
GstMemory *mem;
|
||||
GstMemory *span;
|
||||
GstMemory **mem[2];
|
||||
gsize len[2], len1, len2;
|
||||
|
||||
g_return_val_if_fail (GST_IS_BUFFER (buf1), NULL);
|
||||
g_return_val_if_fail (GST_IS_BUFFER (buf2), NULL);
|
||||
g_return_val_if_fail (buf1->mini_object.refcount > 0, NULL);
|
||||
g_return_val_if_fail (buf2->mini_object.refcount > 0, NULL);
|
||||
g_return_val_if_fail (len > 0, NULL);
|
||||
g_return_val_if_fail (len <= gst_buffer_get_size (buf1) +
|
||||
gst_buffer_get_size (buf2) - offset, NULL);
|
||||
len1 = gst_buffer_get_size (buf1);
|
||||
len2 = gst_buffer_get_size (buf2);
|
||||
g_return_val_if_fail (len1 + len2 > offset, NULL);
|
||||
if (size == -1)
|
||||
size = len1 + len2 - offset;
|
||||
else
|
||||
g_return_val_if_fail (size <= len1 + len2 - offset, NULL);
|
||||
|
||||
mem[0] = GST_BUFFER_MEM_ARRAY (buf1);
|
||||
len[0] = GST_BUFFER_MEM_LEN (buf1);
|
||||
mem[1] = GST_BUFFER_MEM_ARRAY (buf2);
|
||||
len[1] = GST_BUFFER_MEM_LEN (buf2);
|
||||
|
||||
span = _gst_buffer_arr_span (mem, len, 2, offset, size);
|
||||
|
||||
newbuf = gst_buffer_new ();
|
||||
|
||||
arr1 = GST_BUFFER_MEM_ARRAY (buf1);
|
||||
len1 = GST_BUFFER_MEM_LEN (buf1);
|
||||
arr2 = GST_BUFFER_MEM_ARRAY (buf2);
|
||||
len2 = GST_BUFFER_MEM_LEN (buf2);
|
||||
|
||||
mem = gst_memory_span (arr1, len1, offset, arr2, len2, len);
|
||||
_memory_add (newbuf, mem);
|
||||
_memory_add (newbuf, span);
|
||||
|
||||
#if 0
|
||||
/* if the offset is 0, the new buffer has the same timestamp as buf1 */
|
||||
|
|
100
gst/gstmemory.c
100
gst/gstmemory.c
|
@ -213,6 +213,9 @@ _default_mem_sub (GstMemoryDefault * mem, gsize offset, gsize size)
|
|||
if ((parent = mem->mem.parent) == NULL)
|
||||
parent = (GstMemory *) mem;
|
||||
|
||||
if (size == -1)
|
||||
size = mem->size - offset;
|
||||
|
||||
sub = _default_mem_new (parent->flags, parent, mem->data, NULL, mem->maxsize,
|
||||
mem->offset + offset, size);
|
||||
|
||||
|
@ -478,101 +481,22 @@ gst_memory_sub (GstMemory * mem, gsize offset, gsize size)
|
|||
}
|
||||
|
||||
gboolean
|
||||
gst_memory_is_span (GstMemory ** mem1, gsize len1, GstMemory ** mem2,
|
||||
gsize len2, GstMemory ** parent, gsize * offset)
|
||||
gst_memory_is_span (GstMemory * mem1, GstMemory * mem2, gsize * offset)
|
||||
{
|
||||
GstMemory *m1, *m2, **arr;
|
||||
gsize len, i;
|
||||
guint count;
|
||||
gboolean have_offset = FALSE;
|
||||
|
||||
g_return_val_if_fail (mem1 != NULL, FALSE);
|
||||
g_return_val_if_fail (mem2 != NULL, FALSE);
|
||||
|
||||
arr = mem1;
|
||||
len = len1;
|
||||
m1 = m2 = NULL;
|
||||
/* need to have the same implementation */
|
||||
if (mem1->impl != mem2->impl)
|
||||
return FALSE;
|
||||
|
||||
for (count = 0; count < 2; count++) {
|
||||
gsize offs;
|
||||
/* need to have the same parent */
|
||||
if (mem1->parent == NULL || mem1->parent != mem2->parent)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (m2)
|
||||
m1 = m2;
|
||||
m2 = arr[i];
|
||||
|
||||
if (m1 && m2) {
|
||||
/* need to have the same implementation */
|
||||
if (m1->impl != m2->impl)
|
||||
return FALSE;
|
||||
|
||||
/* need to have the same parent */
|
||||
if (m1->parent == NULL || m1->parent != m2->parent)
|
||||
return FALSE;
|
||||
|
||||
/* and memory is contiguous */
|
||||
if (!m1->impl->info.is_span (m1, m2, &offs))
|
||||
return FALSE;
|
||||
|
||||
if (!have_offset) {
|
||||
if (offset)
|
||||
*offset = offs;
|
||||
if (parent)
|
||||
*parent = m1->parent;
|
||||
|
||||
have_offset = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
arr = mem2;
|
||||
len = len2;
|
||||
}
|
||||
if (!have_offset)
|
||||
/* and memory is contiguous */
|
||||
if (!mem1->impl->info.is_span (mem1, mem2, offset))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GstMemory *
|
||||
gst_memory_span (GstMemory ** mem1, gsize len1, gsize offset, GstMemory ** mem2,
|
||||
gsize len2, gsize size)
|
||||
{
|
||||
GstMemory *span, **mem, *parent;
|
||||
guint8 *data, *dest;
|
||||
gsize count, ssize, tocopy, len, poffset, i;
|
||||
|
||||
g_return_val_if_fail (mem1 != NULL, NULL);
|
||||
g_return_val_if_fail (mem2 != NULL, NULL);
|
||||
|
||||
if (gst_memory_is_span (mem1, len1, mem2, len2, &parent, &poffset)) {
|
||||
span = gst_memory_sub (parent, offset + poffset, size);
|
||||
} else {
|
||||
GstMemoryDefault *tspan;
|
||||
|
||||
tspan = _default_mem_new_block (size, 0, 0, size);
|
||||
dest = tspan->data;
|
||||
|
||||
mem = mem1;
|
||||
len = len1;
|
||||
|
||||
for (count = 0; count < 2; count++) {
|
||||
for (i = 0; i < len && size > 0; i++) {
|
||||
data = gst_memory_map (mem[i], &ssize, NULL, GST_MAP_READ);
|
||||
tocopy = MIN (ssize, size);
|
||||
if (tocopy > offset) {
|
||||
memcpy (dest, data + offset, tocopy - offset);
|
||||
size -= tocopy;
|
||||
dest += tocopy;
|
||||
offset = 0;
|
||||
} else {
|
||||
offset -= tocopy;
|
||||
}
|
||||
gst_memory_unmap (mem[i], data, ssize);
|
||||
}
|
||||
mem = mem2;
|
||||
len = len2;
|
||||
}
|
||||
span = (GstMemory *) tspan;
|
||||
}
|
||||
return span;
|
||||
}
|
||||
|
|
|
@ -135,9 +135,7 @@ GstMemory * gst_memory_copy (GstMemory *mem, gsize offset, gsize size);
|
|||
GstMemory * gst_memory_sub (GstMemory *mem, gsize offset, gsize size);
|
||||
|
||||
/* memory arrays */
|
||||
gboolean gst_memory_is_span (GstMemory **mem1, gsize len1,
|
||||
GstMemory **mem2, gsize len2,
|
||||
GstMemory **parent, gsize *offset);
|
||||
gboolean gst_memory_is_span (GstMemory *mem1, GstMemory *mem2, gsize *offset);
|
||||
GstMemory * gst_memory_span (GstMemory **mem1, gsize len1, gsize offset,
|
||||
GstMemory **mem2, gsize len2, gsize size);
|
||||
|
||||
|
|
|
@ -541,7 +541,6 @@ EXPORTS
|
|||
gst_memory_new_wrapped
|
||||
gst_memory_ref
|
||||
gst_memory_register
|
||||
gst_memory_span
|
||||
gst_memory_sub
|
||||
gst_memory_trim
|
||||
gst_memory_unmap
|
||||
|
|
Loading…
Reference in a new issue