Allow for negative offsets when doing memory copy and share.
Add fast path in the _get_sizes() function.
Fix resize for negative offset and expanding the buffer.
Add some unit tests.
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;
-
- s = gst_memory_get_sizes (GST_BUFFER_MEM_PTR (buffer, i), &o, &ms);
-
- /* add sizes */
- size += s;
+ 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;
+
+ size = offs = extra = 0;
+ for (i = 0; i < len; i++) {
+ gsize s, o, ms;
+
+ mem = GST_BUFFER_MEM_PTR (buffer, i);
+ s = gst_memory_get_sizes (mem, &o, &ms);
+
+ /* 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);
+ }
- /* 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);
+ if (offset)
+ *offset = offs;
+ if (maxsize)
+ *maxsize = offs + size + extra;
}
-
- if (offset)
- *offset = offs;
- if (maxsize)
- *maxsize = offs + size + extra;
-
return 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));
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);
}
static GstMemoryDefault *
-_default_mem_copy (GstMemoryDefault * mem, gsize offset, gsize size)
+_default_mem_copy (GstMemoryDefault * mem, gssize offset, gsize size)
{
GstMemoryDefault *copy;
}
static GstMemoryDefault *
-_default_mem_share (GstMemoryDefault * mem, gsize offset, gsize size)
+_default_mem_share (GstMemoryDefault * mem, gssize offset, gsize size)
{
GstMemoryDefault *sub;
GstMemory *parent;
}
static GstMemory *
-_fallback_copy (GstMemory * mem, gsize offset, gsize size)
+_fallback_copy (GstMemory * mem, gssize offset, gsize size)
{
GstMemory *copy;
guint8 *data, *dest;
* 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);
* 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);
* 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:
*
* 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:
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);
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)
{
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;
}