#include "gstbufferpool.h"
#include "gstinfo.h"
#include "gstutils.h"
-#include "gstminiobject.h"
#include "gstversion.h"
GType _gst_buffer_type = 0;
gst_memory_map (mem[i], &sinfo, GST_MAP_READ);
tocopy = MIN (sinfo.size, left);
GST_CAT_DEBUG (GST_CAT_PERFORMANCE,
- "memcpy for merge %p from memory %p", result, mem[i]);
+ "memcpy %" G_GSIZE_FORMAT " bytes for merge %p from memory %p",
+ tocopy, result, mem[i]);
memcpy (ptr, (guint8 *) sinfo.data, tocopy);
left -= tocopy;
ptr += tocopy;
gsize end, i;
end = idx + length;
- GST_LOG ("buffer %p replace %u-%u with memory %p", buffer, idx, end, mem);
+ GST_LOG ("buffer %p replace %u-%" G_GSIZE_FORMAT " with memory %p", buffer,
+ idx, end, mem);
/* unref old memory */
for (i = idx; i < end; i++)
gst_memory_unref (GST_BUFFER_MEM_PTR (buffer, i));
- if (end != len) {
- g_memmove (&GST_BUFFER_MEM_PTR (buffer, idx + 1),
+ if (mem != NULL) {
+ /* replace with single memory */
+ GST_BUFFER_MEM_PTR (buffer, idx) = mem;
+ idx++;
+ length--;
+ }
+
+ if (end < len) {
+ g_memmove (&GST_BUFFER_MEM_PTR (buffer, idx),
&GST_BUFFER_MEM_PTR (buffer, end), (len - end) * sizeof (gpointer));
}
- /* replace with single memory */
- GST_BUFFER_MEM_PTR (buffer, idx) = mem;
- GST_BUFFER_MEM_LEN (buffer) = len - length + 1;
+ GST_BUFFER_MEM_LEN (buffer) = len - length;
}
static inline void
g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL);
len = GST_BUFFER_MEM_LEN (buffer);
- g_return_val_if_fail ((length == -1 && idx < len) ||
- (length > 0 && length + idx <= len), NULL);
+ g_return_val_if_fail ((len == 0 && idx == 0 && length == -1) ||
+ (length == -1 && idx < len) || (length > 0 && length + idx <= len), NULL);
if (length == -1)
length = len - idx;
g_return_if_fail (GST_IS_BUFFER (buffer));
g_return_if_fail (gst_buffer_is_writable (buffer));
len = GST_BUFFER_MEM_LEN (buffer);
- g_return_if_fail ((length == -1 && idx < len) || (length > 0
- && length + idx <= len));
+ g_return_if_fail ((len == 0 && idx == 0 && length == -1) ||
+ (length == -1 && idx < len) || (length > 0 && length + idx <= len));
if (length == -1)
length = len - idx;
void
gst_buffer_remove_memory_range (GstBuffer * buffer, guint idx, gint length)
{
- guint len, i, end;
+ guint len;
g_return_if_fail (GST_IS_BUFFER (buffer));
g_return_if_fail (gst_buffer_is_writable (buffer));
len = GST_BUFFER_MEM_LEN (buffer);
- g_return_if_fail ((length == -1 && idx < len) || length + idx <= len);
+ g_return_if_fail ((len == 0 && idx == 0 && length == -1) ||
+ (length == -1 && idx < len) || length + idx <= len);
if (length == -1)
length = len - idx;
- end = idx + length;
- for (i = idx; i < end; i++)
- gst_memory_unref (GST_BUFFER_MEM_PTR (buffer, i));
+ _replace_memory (buffer, len, idx, length, NULL);
+}
- if (end != len) {
- g_memmove (&GST_BUFFER_MEM_PTR (buffer, idx),
- &GST_BUFFER_MEM_PTR (buffer, end), (len - end) * sizeof (gpointer));
+/**
+ * gst_buffer_find_memory:
+ * @buffer: a #GstBuffer.
+ * @offset: an offset
+ * @size: a size
+ * @idx: (out): pointer to index
+ * @length: (out): pointer to length
+ * @skip: (out): pointer to skip
+ *
+ * Find the memory blocks that span @size bytes starting from @offset
+ * in @buffer.
+ *
+ * When this function returns %TRUE, @idx will contain the index of the first
+ * memory bock where the byte for @offset can be found and @length contains the
+ * number of memory blocks containing the @size remaining bytes. @skip contains
+ * the number of bytes to skip in the memory bock at @idx to get to the byte
+ * for @offset.
+ *
+ * @size can be -1 to get all the memory blocks after @idx.
+ *
+ * Returns: %TRUE when @size bytes starting from @offset could be found in
+ * @buffer and @idx, @length and @skip will be filled.
+ */
+gboolean
+gst_buffer_find_memory (GstBuffer * buffer, gsize offset, gsize size,
+ guint * idx, guint * length, gsize * skip)
+{
+ guint i, len, found;
+
+ g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
+ g_return_val_if_fail (idx != NULL, FALSE);
+ g_return_val_if_fail (length != NULL, FALSE);
+ g_return_val_if_fail (skip != NULL, FALSE);
+
+ len = GST_BUFFER_MEM_LEN (buffer);
+
+ found = 0;
+ for (i = 0; i < len; i++) {
+ GstMemory *mem;
+ gsize s;
+
+ mem = GST_BUFFER_MEM_PTR (buffer, i);
+ s = gst_memory_get_sizes (mem, NULL, NULL);
+
+ if (s <= offset) {
+ /* block before offset, or empty block, skip */
+ offset -= s;
+ } else {
+ /* block after offset */
+ if (found == 0) {
+ /* first block, remember index and offset */
+ *idx = i;
+ *skip = offset;
+ if (size == -1) {
+ /* return remaining blocks */
+ *length = len - i;
+ return TRUE;
+ }
+ s -= offset;
+ offset = 0;
+ }
+ /* count the amount of found bytes */
+ found += s;
+ if (found >= size) {
+ /* we have enough bytes */
+ *length = i - *idx + 1;
+ return TRUE;
+ }
+ }
}
- GST_BUFFER_MEM_LEN (buffer) = len - length;
+ return FALSE;
}
/**
- * gst_buffer_get_sizes:
+ * gst_buffer_get_sizes_range:
* @buffer: a #GstBuffer.
+ * @idx: an index
+ * @length: a length
* @offset: a pointer to the offset
* @maxsize: a pointer to the maxsize
*
- * Get the total size of all memory blocks in @buffer.
+ * Get the total size of @length memory blocks stating from @idx in @buffer.
*
- * When not %NULL, @offset will contain the offset of the data in the first
- * memory block in @buffer and @maxsize will contain the sum of the size
- * and @offset and the amount of extra padding on the last memory block.
- * @offset and @maxsize can be used to resize the buffer with
- * gst_buffer_resize().
+ * When not %NULL, @offset will contain the offset of the data in the
+ * memory block in @buffer at @idx and @maxsize will contain the sum of the size
+ * and @offset and the amount of extra padding on the memory block at @idx +
+ * @length -1.
+ * @offset and @maxsize can be used to resize the buffer memory blocks with
+ * gst_buffer_resize_range().
*
- * Returns: the total size of the memory in @buffer.
+ * Returns: total size @length memory blocks starting at @idx in @buffer.
*/
gsize
-gst_buffer_get_sizes (GstBuffer * buffer, gsize * offset, gsize * maxsize)
+gst_buffer_get_sizes_range (GstBuffer * buffer, guint idx, gint length,
+ gsize * offset, gsize * maxsize)
{
guint len;
gsize size;
GstMemory *mem;
g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
-
len = GST_BUFFER_MEM_LEN (buffer);
+ g_return_val_if_fail ((len == 0 && idx == 0 && length == -1) ||
+ (length == -1 && idx < len) || (length + idx <= len), 0);
+
+ if (length == -1)
+ length = len - idx;
- if (G_LIKELY (len == 1)) {
+ if (G_LIKELY (length == 1)) {
/* common case */
- mem = GST_BUFFER_MEM_PTR (buffer, 0);
+ mem = GST_BUFFER_MEM_PTR (buffer, idx);
size = gst_memory_get_sizes (mem, offset, maxsize);
} else {
- guint i;
+ guint i, end;
gsize extra, offs;
+ end = idx + length;
size = offs = extra = 0;
- for (i = 0; i < len; i++) {
+ for (i = idx; i < end; i++) {
gsize s, o, ms;
mem = GST_BUFFER_MEM_PTR (buffer, i);
}
/**
- * gst_buffer_resize:
+ * gst_buffer_resize_range:
* @buffer: a #GstBuffer.
+ * @idx: an index
+ * @length: a length
* @offset: the offset adjustement
* @size: the new size or -1 to just adjust the offset
*
- * Set the total size of the buffer
+ * Set the total size of the @length memory blocks starting at @idx in
+ * @buffer
*/
void
-gst_buffer_resize (GstBuffer * buffer, gssize offset, gssize size)
+gst_buffer_resize_range (GstBuffer * buffer, guint idx, gint length,
+ gssize offset, gssize size)
{
- guint len;
- guint i;
+ guint i, len, end;
gsize bsize, bufsize, bufoffs, bufmax;
GstMemory *mem;
g_return_if_fail (gst_buffer_is_writable (buffer));
g_return_if_fail (size >= -1);
+ len = GST_BUFFER_MEM_LEN (buffer);
+ g_return_if_fail ((len == 0 && idx == 0 && length == -1) ||
+ (length == -1 && idx < len) || (length + idx <= len));
+
+ if (length == -1)
+ length = len - idx;
- bufsize = gst_buffer_get_sizes (buffer, &bufoffs, &bufmax);
+ bufsize = gst_buffer_get_sizes_range (buffer, idx, length, &bufoffs, &bufmax);
GST_CAT_LOG (GST_CAT_BUFFER, "trim %p %" G_GSSIZE_FORMAT "-%" G_GSSIZE_FORMAT
" size:%" G_GSIZE_FORMAT " offs:%" G_GSIZE_FORMAT " max:%"
if (offset == 0 && size == bufsize)
return;
- len = GST_BUFFER_MEM_LEN (buffer);
-
+ end = idx + length;
/* copy and trim */
- for (i = 0; i < len; i++) {
+ for (i = idx; i < end; i++) {
gsize left, noffs;
mem = GST_BUFFER_MEM_PTR (buffer, i);
noffs = 0;
/* last buffer always gets resized to the remaining size */
- if (i + 1 == len)
+ if (i + 1 == end)
left = size;
/* shrink buffers before the offset */
else if ((gssize) bsize <= offset) {
g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
g_return_val_if_fail (info != NULL, FALSE);
len = GST_BUFFER_MEM_LEN (buffer);
- if (len == 0)
- goto no_memory;
- g_return_val_if_fail ((length == -1 && idx < len) || (length > 0
+ g_return_val_if_fail ((len == 0 && idx == 0 && length == -1) ||
+ (length == -1 && idx < len) || (length > 0
&& length + idx <= len), FALSE);
write = (flags & GST_MAP_WRITE) != 0;
g_return_val_if_fail (buffer != NULL, FALSE);
g_return_val_if_fail (meta != NULL, FALSE);
g_return_val_if_fail (gst_buffer_is_writable (buffer), FALSE);
+ g_return_val_if_fail (!GST_META_FLAG_IS_SET (meta, GST_META_FLAG_LOCKED),
+ FALSE);
/* find the metadata and delete */
prev = GST_BUFFER_META (buffer);
g_type_name (info->type));
g_return_if_fail (gst_buffer_is_writable (buffer));
+ g_return_if_fail (!GST_META_FLAG_IS_SET (m, GST_META_FLAG_LOCKED));
/* remove from list */
if (GST_BUFFER_META (buffer) == walk)