diff --git a/gst/gstbuffer.c b/gst/gstbuffer.c index b190112212..2bcfe732ff 100644 --- a/gst/gstbuffer.c +++ b/gst/gstbuffer.c @@ -761,36 +761,46 @@ gst_buffer_remove_memory_range (GstBuffer * buffer, guint idx, guint length) gsize gst_buffer_get_sizes (GstBuffer * buffer, gsize * offset, gsize * maxsize) { - guint i, len; - gsize extra, size, offs; + guint len; + gsize size; + GstMemory *mem; g_return_val_if_fail (GST_IS_BUFFER (buffer), 0); len = GST_BUFFER_MEM_LEN (buffer); - size = offs = extra = 0; - for (i = 0; i < len; i++) { - gsize s, o, ms; + if (G_LIKELY (len == 1)) { + /* common case */ + mem = GST_BUFFER_MEM_PTR (buffer, 0); + size = gst_memory_get_sizes (mem, offset, maxsize); + } else { + guint i; + gsize extra, offs; - s = gst_memory_get_sizes (GST_BUFFER_MEM_PTR (buffer, i), &o, &ms); + size = offs = extra = 0; + for (i = 0; i < len; i++) { + gsize s, o, ms; - /* add sizes */ - size += s; + mem = GST_BUFFER_MEM_PTR (buffer, i); + s = gst_memory_get_sizes (mem, &o, &ms); - /* keep offset of first memory block */ - if (i == 0) - offs = o; - /* this is the amount of extra bytes in this block, we only keep this for - * the last block */ - else if (i + 1 == len) - extra = ms - (o + s); + /* add sizes */ + size += s; + + /* keep offset of first memory block */ + if (i == 0) + offs = o; + /* this is the amount of extra bytes in this block, we only keep this for + * the last block */ + if (i + 1 == len) + extra = ms - (o + s); + } + + if (offset) + *offset = offs; + if (maxsize) + *maxsize = offs + size + extra; } - - if (offset) - *offset = offs; - if (maxsize) - *maxsize = offs + size + extra; - return size; } @@ -810,7 +820,7 @@ gst_buffer_resize (GstBuffer * buffer, gssize offset, gsize size) gsize bsize, bufsize, bufoffs, bufmax; GstMemory *mem; - GST_CAT_LOG (GST_CAT_BUFFER, "trim %p %" G_GSIZE_FORMAT "-%" G_GSIZE_FORMAT, + GST_CAT_LOG (GST_CAT_BUFFER, "trim %p %" G_GSSIZE_FORMAT "-%" G_GSIZE_FORMAT, buffer, offset, size); g_return_if_fail (gst_buffer_is_writable (buffer)); @@ -834,15 +844,20 @@ gst_buffer_resize (GstBuffer * buffer, gssize offset, gsize size) mem = GST_BUFFER_MEM_PTR (buffer, si); bsize = gst_memory_get_sizes (mem, NULL, NULL); - if (bsize <= offset) { + if ((gssize) bsize <= offset) { /* remove buffer */ gst_memory_unref (mem); offset -= bsize; } else { gsize left; - left = MIN (bsize - offset, size); - if (left < bsize) { + /* last buffer always gets resized to the remaining size */ + if (si + 1 == len) + left = size; + else + left = MIN (bsize - offset, size); + + if (left) { /* we need to clip something */ if (GST_MEMORY_IS_WRITABLE (mem)) { gst_memory_resize (mem, offset, left); diff --git a/gst/gstmemory.c b/gst/gstmemory.c index f30d3c944a..dfb3697645 100644 --- a/gst/gstmemory.c +++ b/gst/gstmemory.c @@ -228,7 +228,7 @@ _default_mem_free (GstMemoryDefault * mem) } static GstMemoryDefault * -_default_mem_copy (GstMemoryDefault * mem, gsize offset, gsize size) +_default_mem_copy (GstMemoryDefault * mem, gssize offset, gsize size) { GstMemoryDefault *copy; @@ -242,7 +242,7 @@ _default_mem_copy (GstMemoryDefault * mem, gsize offset, gsize size) } static GstMemoryDefault * -_default_mem_share (GstMemoryDefault * mem, gsize offset, gsize size) +_default_mem_share (GstMemoryDefault * mem, gssize offset, gsize size) { GstMemoryDefault *sub; GstMemory *parent; @@ -278,7 +278,7 @@ _default_mem_is_span (GstMemoryDefault * mem1, GstMemoryDefault * mem2, } static GstMemory * -_fallback_copy (GstMemory * mem, gsize offset, gsize size) +_fallback_copy (GstMemory * mem, gssize offset, gsize size) { GstMemory *copy; guint8 *data, *dest; @@ -492,7 +492,7 @@ gst_memory_unmap (GstMemory * mem, gpointer data, gsize size) * Returns: a new #GstMemory. */ GstMemory * -gst_memory_copy (GstMemory * mem, gsize offset, gsize size) +gst_memory_copy (GstMemory * mem, gssize offset, gsize size) { g_return_val_if_fail (mem != NULL, NULL); @@ -513,7 +513,7 @@ gst_memory_copy (GstMemory * mem, gsize offset, gsize size) * Returns: a new #GstMemory. */ GstMemory * -gst_memory_share (GstMemory * mem, gsize offset, gsize size) +gst_memory_share (GstMemory * mem, gssize offset, gsize size) { g_return_val_if_fail (mem != NULL, NULL); diff --git a/gst/gstmemory.h b/gst/gstmemory.h index 9bf338ef25..a4f411290a 100644 --- a/gst/gstmemory.h +++ b/gst/gstmemory.h @@ -204,7 +204,7 @@ typedef void (*GstMemoryFreeFunction) (GstMemory *mem); * Returns: a new #GstMemory object wrapping a copy of the requested region in * @mem. */ -typedef GstMemory * (*GstMemoryCopyFunction) (GstMemory *mem, gsize offset, gsize size); +typedef GstMemory * (*GstMemoryCopyFunction) (GstMemory *mem, gssize offset, gsize size); /** * GstMemoryShareFunction: @@ -218,7 +218,7 @@ typedef GstMemory * (*GstMemoryCopyFunction) (GstMemory *mem, gsize offset, * * Returns: a new #GstMemory object sharing the requested region in @mem. */ -typedef GstMemory * (*GstMemoryShareFunction) (GstMemory *mem, gsize offset, gsize size); +typedef GstMemory * (*GstMemoryShareFunction) (GstMemory *mem, gssize offset, gsize size); /** * GstMemoryIsSpanFunction: @@ -293,8 +293,8 @@ gpointer gst_memory_map (GstMemory *mem, gsize *size, gsize *maxsize, gboolean gst_memory_unmap (GstMemory *mem, gpointer data, gsize size); /* copy and subregions */ -GstMemory * gst_memory_copy (GstMemory *mem, gsize offset, gsize size); -GstMemory * gst_memory_share (GstMemory *mem, gsize offset, gsize size); +GstMemory * gst_memory_copy (GstMemory *mem, gssize offset, gsize size); +GstMemory * gst_memory_share (GstMemory *mem, gssize offset, gsize size); /* span memory */ gboolean gst_memory_is_span (GstMemory *mem1, GstMemory *mem2, gsize *offset); diff --git a/tests/check/gst/gstbuffer.c b/tests/check/gst/gstbuffer.c index b37d943a58..22cbef7bd9 100644 --- a/tests/check/gst/gstbuffer.c +++ b/tests/check/gst/gstbuffer.c @@ -441,6 +441,85 @@ GST_START_TEST (test_try_new_and_alloc) GST_END_TEST; +GST_START_TEST (test_resize) +{ + GstBuffer *buf; + gsize maxalloc; + gsize size, maxsize, offset; + + /* one memory block */ + buf = gst_buffer_new_allocate (NULL, 100, 0); + + size = gst_buffer_get_sizes (buf, &offset, &maxalloc); + fail_unless (size == 100); + fail_unless (offset == 0); + fail_unless (maxalloc >= 100); + + ASSERT_CRITICAL (gst_buffer_resize (buf, 200, 50)); + ASSERT_CRITICAL (gst_buffer_resize (buf, 0, 150)); + ASSERT_CRITICAL (gst_buffer_resize (buf, 1, maxalloc)); + ASSERT_CRITICAL (gst_buffer_resize (buf, maxalloc, 1)); + + /* this does nothing */ + gst_buffer_resize (buf, 0, 100); + + /* nothing should have changed */ + size = gst_buffer_get_sizes (buf, &offset, &maxsize); + fail_unless (size == 100); + fail_unless (offset == 0); + fail_unless (maxsize == maxalloc); + + gst_buffer_resize (buf, 0, 50); + size = gst_buffer_get_sizes (buf, &offset, &maxsize); + fail_unless (size == 50); + fail_unless (offset == 0); + fail_unless (maxsize == maxalloc); + + gst_buffer_resize (buf, 0, 100); + size = gst_buffer_get_sizes (buf, &offset, &maxsize); + fail_unless (size == 100); + fail_unless (offset == 0); + fail_unless (maxsize == maxalloc); + + gst_buffer_resize (buf, 1, 99); + size = gst_buffer_get_sizes (buf, &offset, &maxsize); + fail_unless (size == 99); + fail_unless (offset == 1); + fail_unless (maxsize == maxalloc); + + ASSERT_CRITICAL (gst_buffer_resize (buf, 1, maxalloc - 1)); + + gst_buffer_resize (buf, 0, 99); + size = gst_buffer_get_sizes (buf, &offset, &maxsize); + fail_unless (size == 99); + fail_unless (offset == 1); + fail_unless (maxsize == maxalloc); + + gst_buffer_resize (buf, -1, 100); + size = gst_buffer_get_sizes (buf, &offset, &maxsize); + fail_unless (size == 100); + fail_unless (offset == 0); + fail_unless (maxsize == maxalloc); + + ASSERT_CRITICAL (gst_buffer_resize (buf, -1, 100)); + + gst_buffer_resize (buf, 50, 40); + size = gst_buffer_get_sizes (buf, &offset, &maxsize); + fail_unless (size == 40); + fail_unless (offset == 50); + fail_unless (maxsize == maxalloc); + + gst_buffer_resize (buf, -50, 100); + size = gst_buffer_get_sizes (buf, &offset, &maxsize); + fail_unless (size == 100); + fail_unless (offset == 0); + fail_unless (maxsize == maxalloc); + + gst_buffer_unref (buf); +} + +GST_END_TEST; + static Suite * gst_buffer_suite (void) { @@ -456,6 +535,7 @@ gst_buffer_suite (void) tcase_add_test (tc_chain, test_metadata_writable); tcase_add_test (tc_chain, test_copy); tcase_add_test (tc_chain, test_try_new_and_alloc); + tcase_add_test (tc_chain, test_resize); return s; }