#else
#error "No buffer alignment configured"
#endif
-
-static inline gboolean
-aligned_malloc (gpointer * memptr, guint size)
-{
- gint res;
-
- res = posix_memalign (memptr, _gst_buffer_data_alignment, size);
- return (res == 0);
-}
-
#endif /* HAVE_POSIX_MEMALIGN */
void
}
}
-void
-gst_buffer_copy_memory (GstBuffer * dest, GstBuffer * src,
- gsize offset, gsize size, gboolean merge)
-{
- GPtrArray *sarr = (GPtrArray *) src->memory;
- GPtrArray *darr = (GPtrArray *) dest->memory;
- guint i, len;
-
- len = sarr->len;
-
- for (i = 0; i < len; i++) {
- GstMemory *mem = g_ptr_array_index (sarr, i);
- g_ptr_array_add (darr, gst_memory_copy (mem));
- }
-}
-
-void
-gst_buffer_share_memory (GstBuffer * dest, GstBuffer * src)
-{
- GPtrArray *sarr = (GPtrArray *) src->memory;
- GPtrArray *darr = (GPtrArray *) dest->memory;
- guint i, len;
-
- len = sarr->len;
-
- for (i = 0; i < len; i++) {
- GstMemory *mem = g_ptr_array_index (sarr, i);
- g_ptr_array_add (darr, gst_memory_ref (mem));
- }
-}
-
-
/**
- * gst_buffer_copy_metadata:
+ * gst_buffer_copy_into:
* @dest: a destination #GstBuffer
* @src: a source #GstBuffer
* @flags: flags indicating what metadata fields should be copied.
+ * @offset: offset to copy from
+ * @trim: bytes to trim from end
*
- * Copies the metadata from @src into @dest. The data, size and mallocdata
- * fields are not copied.
- *
- * @flags indicate which fields will be copied. Use #GST_BUFFER_COPY_ALL to copy
- * all the metadata fields.
- *
- * This function is typically called from a custom buffer copy function after
- * creating @dest and setting the data, size, mallocdata.
+ * Copies the information from @src into @dest.
*
- * Since: 0.10.13
+ * @flags indicate which fields will be copied.
*/
void
-gst_buffer_copy_metadata (GstBuffer * dest, GstBuffer * src,
- GstBufferCopyFlags flags)
+gst_buffer_copy_into (GstBuffer * dest, GstBuffer * src,
+ GstBufferCopyFlags flags, gsize offset, gsize trim)
{
GstMetaItem *walk;
}
if (flags & GST_BUFFER_COPY_TIMESTAMPS) {
- GST_BUFFER_TIMESTAMP (dest) = GST_BUFFER_TIMESTAMP (src);
- GST_BUFFER_DURATION (dest) = GST_BUFFER_DURATION (src);
- GST_BUFFER_OFFSET (dest) = GST_BUFFER_OFFSET (src);
- GST_BUFFER_OFFSET_END (dest) = GST_BUFFER_OFFSET_END (src);
+ if (offset == 0) {
+ GST_BUFFER_TIMESTAMP (dest) = GST_BUFFER_TIMESTAMP (src);
+ GST_BUFFER_OFFSET (dest) = GST_BUFFER_OFFSET (src);
+ if (trim == 0) {
+ GST_BUFFER_DURATION (dest) = GST_BUFFER_DURATION (src);
+ GST_BUFFER_OFFSET_END (dest) = GST_BUFFER_OFFSET_END (src);
+ }
+ } else {
+ GST_BUFFER_TIMESTAMP (dest) = GST_CLOCK_TIME_NONE;
+ GST_BUFFER_DURATION (dest) = GST_CLOCK_TIME_NONE;
+ GST_BUFFER_OFFSET (dest) = GST_BUFFER_OFFSET_NONE;
+ GST_BUFFER_OFFSET_END (dest) = GST_BUFFER_OFFSET_NONE;
+ }
}
if (flags & GST_BUFFER_COPY_CAPS) {
gst_caps_replace (&GST_BUFFER_CAPS (dest), GST_BUFFER_CAPS (src));
}
+ if (flags & GST_BUFFER_COPY_MEMORY) {
+ GPtrArray *sarr = (GPtrArray *) src->memory;
+ GPtrArray *darr = (GPtrArray *) dest->memory;
+ guint i, len;
+
+ len = sarr->len;
+
+ if (flags & GST_BUFFER_COPY_MEMORY_SHARE) {
+ for (i = 0; i < len; i++) {
+ GstMemory *mem = g_ptr_array_index (sarr, i);
+ g_ptr_array_add (darr, gst_memory_ref (mem));
+ }
+ } else {
+ for (i = 0; i < len; i++) {
+ GstMemory *mem = g_ptr_array_index (sarr, i);
+ g_ptr_array_add (darr, gst_memory_copy (mem));
+ }
+ }
+ }
+
for (walk = src->priv; walk; walk = walk->next) {
GstMeta *meta = &walk->meta;
const GstMetaInfo *info = meta->info;
copy = gst_buffer_new ();
/* we simply copy everything from our parent */
- gst_buffer_copy_memory (copy, buffer, 0, 0, FALSE);
- gst_buffer_copy_metadata (copy, buffer, GST_BUFFER_COPY_ALL);
+ gst_buffer_copy_into (copy, buffer, GST_BUFFER_COPY_ALL, 0, 0);
return copy;
}
g_slice_free (GstMetaItem, walk);
}
- /* free our data */
+ /* free our data, unrefs the memory too */
g_ptr_array_free (buffer->memory, TRUE);
g_slice_free1 (GST_MINI_OBJECT_SIZE (buffer), buffer);
GST_CAT_WARNING (GST_CAT_BUFFER, "failed to allocate %d bytes", size);
return NULL;
}
+
+ newbuf = gst_buffer_new ();
gst_buffer_take_memory (newbuf, mem);
GST_CAT_LOG (GST_CAT_BUFFER, "new %p of size %d", newbuf, size);
}
gsize
-gst_buffer_get_memory_size (GstBuffer * buffer)
+gst_buffer_get_size (GstBuffer * buffer)
{
GPtrArray *arr = (GPtrArray *) buffer->memory;
guint i, size, len;
gst_buffer_map (GstBuffer * buffer, gsize * size, gsize * maxsize,
GstMapFlags flags)
{
- return NULL;
+ GPtrArray *arr = (GPtrArray *) buffer->memory;
+ guint len;
+ gpointer data;
+
+ len = arr->len;
+
+ if (G_LIKELY (len == 1)) {
+ GstMemory *mem = g_ptr_array_index (arr, 0);
+
+ data = gst_memory_map (mem, size, maxsize, flags);
+ } else {
+ data = NULL;
+ }
+ return data;
}
gboolean
gst_buffer_unmap (GstBuffer * buffer, gpointer data, gsize size)
{
- return FALSE;
+ GPtrArray *arr = (GPtrArray *) buffer->memory;
+ gboolean result;
+ guint len;
+
+ len = arr->len;
+
+ if (G_LIKELY (len == 1)) {
+ GstMemory *mem = g_ptr_array_index (arr, 0);
+
+ result = gst_memory_unmap (mem, data, size);
+ } else {
+ result = FALSE;
+ }
+ return result;
}
/**
ret = gst_buffer_new ();
/* we simply copy everything from our parent */
- gst_buffer_share_memory (ret, buf);
- gst_buffer_copy_metadata (ret, buf, GST_BUFFER_COPY_ALL);
+ gst_buffer_copy_into (ret, buf, GST_BUFFER_SHARE_ALL, 0, 0);
gst_buffer_unref (buf);
}
return ret;
}
-#define GST_IS_SUBBUFFER(obj) (GST_BUFFER_CAST(obj)->parent != NULL)
-
/**
* gst_buffer_create_sub:
* @parent: a #GstBuffer.
* invalid.
*/
GstBuffer *
-gst_buffer_create_sub (GstBuffer * buffer, guint offset, guint size)
+gst_buffer_create_sub (GstBuffer * buffer, gsize offset, gsize size)
{
GstBuffer *subbuffer;
- GstBuffer *parent;
- gboolean complete;
- GstMetaItem *walk;
+ gsize bufsize;
g_return_val_if_fail (buffer != NULL, NULL);
g_return_val_if_fail (buffer->mini_object.refcount > 0, NULL);
- g_return_val_if_fail (buffer->size >= offset + size, NULL);
- /* find real parent */
- if (GST_IS_SUBBUFFER (buffer)) {
- parent = buffer->parent;
- } else {
- parent = buffer;
- }
- gst_buffer_ref (parent);
+ bufsize = gst_buffer_get_size (buffer);
+ g_return_val_if_fail (bufsize >= offset + size, NULL);
/* create the new buffer */
subbuffer = gst_buffer_new ();
- subbuffer->parent = parent;
- GST_BUFFER_FLAG_SET (subbuffer, GST_BUFFER_FLAG_READONLY);
-
- GST_CAT_LOG (GST_CAT_BUFFER, "new subbuffer %p (parent %p)", subbuffer,
- parent);
-
- /* set the right values in the child */
- GST_BUFFER_DATA (subbuffer) = buffer->data + offset;
- GST_BUFFER_SIZE (subbuffer) = size;
-
- if ((offset == 0) && (size == GST_BUFFER_SIZE (buffer))) {
- /* copy all the flags except IN_CAPS */
- GST_BUFFER_FLAG_SET (subbuffer, GST_BUFFER_FLAGS (buffer));
- GST_BUFFER_FLAG_UNSET (subbuffer, GST_BUFFER_FLAG_IN_CAPS);
- } else {
- /* copy only PREROLL & GAP flags */
- GST_BUFFER_FLAG_SET (subbuffer, (GST_BUFFER_FLAGS (buffer) &
- (GST_BUFFER_FLAG_PREROLL | GST_BUFFER_FLAG_GAP)));
- }
-
- /* we can copy the timestamp and offset if the new buffer starts at
- * offset 0 */
- if (offset == 0) {
- GST_BUFFER_TIMESTAMP (subbuffer) = GST_BUFFER_TIMESTAMP (buffer);
- GST_BUFFER_OFFSET (subbuffer) = GST_BUFFER_OFFSET (buffer);
- complete = (buffer->size == size);
- } else {
- GST_BUFFER_TIMESTAMP (subbuffer) = GST_CLOCK_TIME_NONE;
- GST_BUFFER_OFFSET (subbuffer) = GST_BUFFER_OFFSET_NONE;
- complete = FALSE;
- }
- if (complete) {
- GstCaps *caps;
-
- /* if we copied the complete buffer we can copy the duration,
- * offset_end and caps as well */
- GST_BUFFER_DURATION (subbuffer) = GST_BUFFER_DURATION (buffer);
- GST_BUFFER_OFFSET_END (subbuffer) = GST_BUFFER_OFFSET_END (buffer);
- if ((caps = GST_BUFFER_CAPS (buffer)))
- gst_caps_ref (caps);
- GST_BUFFER_CAPS (subbuffer) = caps;
- } else {
- GST_BUFFER_DURATION (subbuffer) = GST_CLOCK_TIME_NONE;
- GST_BUFFER_OFFSET_END (subbuffer) = GST_BUFFER_OFFSET_NONE;
- GST_BUFFER_CAPS (subbuffer) = NULL;
- }
- /* call subbuffer functions for metadata */
- for (walk = buffer->priv; walk; walk = walk->next) {
- GstMeta *meta = &walk->meta;
- const GstMetaInfo *info = meta->info;
- GstMetaTransformSubbuffer subdata;
+ GST_CAT_LOG (GST_CAT_BUFFER, "new subbuffer %p of %p", subbuffer, buffer);
- subdata.data.type = GST_META_TRANSFORM_TRIM;
- subdata.offset = offset;
- subdata.size = size;
+ gst_buffer_copy_into (subbuffer, buffer, GST_BUFFER_SHARE_ALL, offset,
+ bufsize - (size + offset));
- if (info->transform_func)
- info->transform_func (subbuffer, meta, buffer,
- (GstMetaTransformData *) & subdata);
- }
return subbuffer;
}
* @buf2: the second #GstBuffer.
*
* Determines whether a gst_buffer_span() can be done without copying
- * the contents, that is, whether the data areas are contiguous sub-buffers of
+ * the contents, that is, whether the data areas are contiguous sub-buffers of
* the same buffer.
*
* MT safe.
gboolean
gst_buffer_is_span_fast (GstBuffer * buf1, GstBuffer * buf2)
{
+ GPtrArray *arr1, *arr2;
+
g_return_val_if_fail (buf1 != NULL && buf2 != NULL, FALSE);
g_return_val_if_fail (buf1->mini_object.refcount > 0, FALSE);
g_return_val_if_fail (buf2->mini_object.refcount > 0, FALSE);
- /* it's only fast if we have subbuffers of the same parent */
- return (GST_IS_SUBBUFFER (buf1) &&
- GST_IS_SUBBUFFER (buf2) && (buf1->parent == buf2->parent)
- && ((buf1->data + buf1->size) == buf2->data));
+ arr1 = (GPtrArray *) buf1->memory;
+ arr2 = (GPtrArray *) buf2->memory;
+
+ return gst_memory_is_span ((GstMemory **) arr1->pdata, arr1->len,
+ (GstMemory **) arr2->pdata, arr2->len, NULL, NULL);
}
/**
* buffers, or NULL if the arguments are invalid.
*/
GstBuffer *
-gst_buffer_span (GstBuffer * buf1, guint32 offset, GstBuffer * buf2,
- guint32 len)
+gst_buffer_span (GstBuffer * buf1, gsize offset, GstBuffer * buf2, gsize len)
{
GstBuffer *newbuf;
+ GPtrArray *arr1, *arr2;
+ GstMemory *mem;
g_return_val_if_fail (buf1 != NULL && buf2 != NULL, 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 <= buf1->size + buf2->size - offset, NULL);
- /* if the two buffers have the same parent and are adjacent */
- if (gst_buffer_is_span_fast (buf1, buf2)) {
- GstBuffer *parent = buf1->parent;
+ newbuf = gst_buffer_new ();
- /* we simply create a subbuffer of the common parent */
- newbuf = gst_buffer_create_sub (parent,
- buf1->data - parent->data + offset, len);
- } else {
- GST_CAT_DEBUG (GST_CAT_BUFFER,
- "slow path taken while spanning buffers %p and %p", buf1, buf2);
- /* otherwise we simply have to brute-force copy the buffers */
- newbuf = gst_buffer_new_and_alloc (len);
-
- /* copy the first buffer's data across */
- memcpy (newbuf->data, buf1->data + offset, buf1->size - offset);
- /* copy the second buffer's data across */
- memcpy (newbuf->data + (buf1->size - offset), buf2->data,
- len - (buf1->size - offset));
- }
+ arr1 = (GPtrArray *) buf1->memory;
+ arr2 = (GPtrArray *) buf2->memory;
+
+ mem = gst_memory_span ((GstMemory **) arr1->pdata, arr1->len, offset,
+ (GstMemory **) arr2->pdata, arr2->len, len);
+ gst_buffer_take_memory (newbuf, mem);
+
+#if 0
/* if the offset is 0, the new buffer has the same timestamp as buf1 */
if (offset == 0) {
GST_BUFFER_OFFSET (newbuf) = GST_BUFFER_OFFSET (buf1);
}
}
}
+#endif
return newbuf;
}
GstMemory * gst_buffer_peek_memory (GstBuffer *buffer, guint idx);
void gst_buffer_remove_memory (GstBuffer *buffer, guint idx);
-gsize gst_buffer_get_memory_size (GstBuffer *buffer);
+gsize gst_buffer_get_size (GstBuffer *buffer);
/* getting memory */
gpointer gst_buffer_map (GstBuffer *buffer, gsize *size, gsize *maxsize,
* Since: 0.10.13
*/
typedef enum {
- GST_BUFFER_COPY_FLAGS = (1 << 0),
- GST_BUFFER_COPY_TIMESTAMPS = (1 << 1),
- GST_BUFFER_COPY_CAPS = (1 << 2)
+ 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_MEMORY_SHARE = (1 << 5),
} GstBufferCopyFlags;
+#define GST_BUFFER_COPY_METADATA (GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_CAPS)
+
/**
* GST_BUFFER_COPY_ALL:
*
* Combination of all possible fields that can be copied with
- * gst_buffer_copy_metadata().
+ * gst_buffer_copy_into().
*
* Since: 0.10.13
*/
-#define GST_BUFFER_COPY_ALL (GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_CAPS)
+#define GST_BUFFER_COPY_ALL (GST_BUFFER_COPY_METADATA | GST_BUFFER_COPY_MEMORY)
+
+#define GST_BUFFER_SHARE_ALL (GST_BUFFER_COPY_METADATA | GST_BUFFER_COPY_MEMORY | GST_BUFFER_COPY_MEMORY_SHARE)
/* copies memory or metadata into newly allocated buffer */
-void gst_buffer_copy_memory (GstBuffer *dest, GstBuffer *src,
- gsize offset, gsize size, gboolean merge);
-void gst_buffer_share_memory (GstBuffer *dest, GstBuffer *src);
-void gst_buffer_copy_metadata (GstBuffer *dest, GstBuffer *src,
- GstBufferCopyFlags flags);
+void gst_buffer_copy_into (GstBuffer *dest, GstBuffer *src,
+ GstBufferCopyFlags flags,
+ gsize offset, gsize trim);
/**
* gst_buffer_is_writable:
void gst_buffer_set_caps (GstBuffer *buffer, GstCaps *caps);
/* creating a subbuffer */
-GstBuffer* gst_buffer_create_sub (GstBuffer *parent, guint offset, guint size);
+GstBuffer* gst_buffer_create_sub (GstBuffer *parent, gsize offset, gsize size);
/* span, two buffers, intelligently */
gboolean gst_buffer_is_span_fast (GstBuffer *buf1, GstBuffer *buf2);
-GstBuffer* gst_buffer_span (GstBuffer *buf1, guint32 offset, GstBuffer *buf2, guint32 len);
+GstBuffer* gst_buffer_span (GstBuffer *buf1, gsize offset, GstBuffer *buf2, gsize len);
/* metadata */
#include <gst/gstmeta.h>
gst_buffer_list_iterator_merge_group (const GstBufferListIterator * it)
{
GList *tmp;
- guint size;
+ gsize size, bsize;
GstBuffer *buf;
- guint8 *ptr;
+ guint8 *dest, *ptr, *bdata;
g_return_val_if_fail (it != NULL, NULL);
tmp = it->next;
while (tmp && tmp->data != GROUP_START) {
if (tmp->data != STOLEN) {
- size += GST_BUFFER_SIZE (tmp->data);
+ size += gst_buffer_get_size (tmp->data);
}
tmp = g_list_next (tmp);
}
buf = gst_buffer_new_and_alloc (size);
/* copy metadata from the next buffer after the implicit cursor */
- gst_buffer_copy_metadata (buf, GST_BUFFER_CAST (it->next->data),
- GST_BUFFER_COPY_ALL);
+ gst_buffer_copy_into (buf, GST_BUFFER_CAST (it->next->data),
+ GST_BUFFER_COPY_METADATA, 0, 0);
/* copy data of all buffers before the next group start into the new buffer */
- ptr = GST_BUFFER_DATA (buf);
+ dest = ptr = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
tmp = it->next;
do {
if (tmp->data != STOLEN) {
- memcpy (ptr, GST_BUFFER_DATA (tmp->data), GST_BUFFER_SIZE (tmp->data));
- ptr += GST_BUFFER_SIZE (tmp->data);
+
+ bdata =
+ gst_buffer_map (GST_BUFFER_CAST (tmp->data), &bsize, NULL,
+ GST_MAP_READ);
+ memcpy (ptr, bdata, bsize);
+ gst_buffer_unmap (GST_BUFFER_CAST (tmp->data), bdata, bsize);
+ ptr += bsize;
}
tmp = g_list_next (tmp);
} while (tmp && tmp->data != GROUP_START);
+ gst_buffer_unmap (buf, dest, size);
+
return buf;
}
default_alloc_buffer (GstBufferPool * pool, GstBuffer ** buffer,
GstBufferPoolParams * params)
{
- guint size, align;
+ guint align;
GstBufferPoolPrivate *priv = pool->priv;
*buffer = gst_buffer_new ();
align = priv->align - 1;
- size = priv->prefix + priv->postfix + priv->size + align;
- if (size > 0) {
- guint8 *memptr;
-
- memptr = g_malloc (size);
- GST_BUFFER_MALLOCDATA (*buffer) = memptr;
- memptr = (guint8 *) ((guintptr) (memptr + align) & ~align);
- GST_BUFFER_DATA (*buffer) = memptr + priv->prefix;
- GST_BUFFER_SIZE (*buffer) = priv->size;
- }
+
+ gst_buffer_take_memory (*buffer, gst_memory_new_alloc (priv->size, align));
return GST_FLOW_OK;
}
}
static gboolean
-_default_mem_is_span (GstMemoryDefault * mem1, GstMemoryDefault * mem2)
+_default_mem_is_span (GstMemoryDefault * mem1, GstMemoryDefault * mem2,
+ gsize * offset)
{
- /* need to have the same implementation */
- if (mem1->mem.impl != mem2->mem.impl)
- return FALSE;
-
- /* need to have the same parent */
- if (mem1->mem.parent == NULL || mem1->mem.parent != mem2->mem.parent)
- return FALSE;
+ if (offset)
+ *offset = mem1->offset;
/* and memory is contiguous */
- if (mem1->data + mem1->offset + mem1->size != mem2->data + mem2->offset)
- return FALSE;
-
- return TRUE;
-}
-
-static GstMemoryDefault *
-_default_mem_span (GstMemoryDefault * mem1, gsize offset,
- GstMemoryDefault * mem2, gsize size)
-{
- GstMemoryDefault *span;
-
- if (_default_mem_is_span (mem1, mem2)) {
- GstMemoryDefault *parent = (GstMemoryDefault *) mem1->mem.parent;
-
- span =
- _default_mem_sub (parent, mem1->offset - parent->offset + offset, size);
- } else {
- gsize len1;
-
- len1 = mem1->size - offset;
-
- span = _default_mem_new_block (size, 0, 0, size);
- memcpy (span->data, mem1->data + mem1->offset + offset, len1);
- memcpy (span->data + len1, mem2->data + mem2->offset, size - len1);
- }
- return span;
+ return mem1->data + mem1->offset + mem1->size == mem2->data + mem2->offset;
}
static void
}
static gboolean
-_fallback_is_span (GstMemory * mem1, GstMemory * mem2)
+_fallback_is_span (GstMemory * mem1, GstMemory * mem2, gsize * offset)
{
return FALSE;
}
-static GstMemory *
-_fallback_span (GstMemory * mem1, gsize offset, GstMemory * mem2, gsize size)
-{
- GstMemoryDefault *span;
- guint8 *data;
- gsize ssize, len1;
-
- span = _default_mem_new_block (size, 0, 0, size);
-
- data = gst_memory_map (mem1, &ssize, NULL, GST_MAP_READ);
- len1 = ssize - offset;
- memcpy (span->data, data + offset, len1);
- gst_memory_unmap (mem1, data, size);
-
- data = gst_memory_map (mem2, &ssize, NULL, GST_MAP_READ);
- memcpy (span->data + len1, data, ssize - len1);
- gst_memory_unmap (mem2, data, size);
-
- return (GstMemory *) span;
-}
-
const GstMemoryImpl *
gst_memory_register (const gchar * name, const GstMemoryInfo * info)
{
INSTALL_FALLBACK (extract);
INSTALL_FALLBACK (sub);
INSTALL_FALLBACK (is_span);
- INSTALL_FALLBACK (span);
GST_DEBUG ("register \"%s\" of size %" G_GSIZE_FORMAT, name);
(GstMemoryCopyFunction) _default_mem_copy,
(GstMemoryExtractFunction) _default_mem_extract,
(GstMemorySubFunction) _default_mem_sub,
- (GstMemoryIsSpanFunction) _default_mem_is_span,
- (GstMemorySpanFunction) _default_mem_span
+ (GstMemoryIsSpanFunction) _default_mem_is_span
};
static const GstMemoryInfo _sub_info = {
(GstMemoryGetSizesFunction) _default_mem_get_sizes,
NULL,
NULL,
NULL,
- NULL,
NULL
};
}
gboolean
-gst_memory_is_span (GstMemory * mem1, GstMemory * mem2)
+gst_memory_is_span (GstMemory ** mem1, gsize len1, GstMemory ** mem2,
+ gsize len2, GstMemory ** parent, 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);
- return mem1->impl->info.is_span (mem1, mem2);
+ arr = mem1;
+ len = len1;
+ m1 = m2 = NULL;
+
+ for (count = 0; count < 2; count++) {
+ gsize offs;
+
+ 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) {
+ *offset = offs;
+ have_offset = TRUE;
+ }
+ }
+ }
+ arr = mem2;
+ len = len2;
+ }
+ if (!have_offset)
+ return FALSE;
+
+ return TRUE;
}
GstMemory *
-gst_memory_span (GstMemory * mem1, gsize offset, GstMemory * mem2, gsize size)
+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);
- return mem1->impl->info.span (mem1, offset, mem2, size);
+ 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;
}
GstMemory *
gpointer dest, gsize size);
typedef void (*GstMemoryTrimFunction) (GstMemory *mem, gsize offset, gsize size);
typedef GstMemory * (*GstMemorySubFunction) (GstMemory *mem, gsize offset, gsize size);
-typedef gboolean (*GstMemoryIsSpanFunction) (GstMemory *mem1, GstMemory *mem2);
-typedef GstMemory * (*GstMemorySpanFunction) (GstMemory *mem1, gsize offset,
- GstMemory *mem2, gsize size);
+typedef gboolean (*GstMemoryIsSpanFunction) (GstMemory *mem1, GstMemory *mem2,
+ gsize *offset);
/**
* GstMemoryInfo:
GstMemoryExtractFunction extract;
GstMemorySubFunction sub;
GstMemoryIsSpanFunction is_span;
- GstMemorySpanFunction span;
};
void _gst_memory_init (void);
gsize size);
GstMemory * gst_memory_sub (GstMemory *mem, gsize offset, gsize size);
-gboolean gst_memory_is_span (GstMemory *mem1, GstMemory *mem2);
-GstMemory * gst_memory_span (GstMemory *mem1, gsize offset,
- GstMemory *mem2, gsize size);
+gboolean gst_memory_is_span (GstMemory **mem1, gsize len1,
+ GstMemory **mem2, gsize len2,
+ GstMemory **parent, gsize *offset);
+GstMemory * gst_memory_span (GstMemory **mem1, gsize len1, gsize offset,
+ GstMemory **mem2, gsize len2, gsize size);
GstMemory * gst_memory_new_wrapped (gpointer data, GFreeFunc free_func,
size = subdata->size;
} else {
offset = 0;
- size = GST_BUFFER_SIZE (buffer);
+ size = gst_buffer_get_size (buffer);
}
GST_DEBUG ("trans called from buffer %p to %p, meta %p, %u-%u", buffer,
/* same offset, copy timestamps */
timing->pts = meta->pts;
timing->dts = meta->dts;
- if (size == GST_BUFFER_SIZE (buffer)) {
+ if (size == gst_buffer_get_size (buffer)) {
/* same size, copy duration */
timing->duration = meta->duration;
} else {
}
/* sanity check (only if caps are the same) */
- if (G_LIKELY (newcaps == caps) && G_UNLIKELY (GST_BUFFER_SIZE (*buf) < size))
+ if (G_LIKELY (newcaps == caps)
+ && G_UNLIKELY (gst_buffer_get_size (*buf) < size))
goto wrong_size_fallback;
return ret;
{
GST_CAT_ERROR_OBJECT (GST_CAT_PADS, pad, "buffer returned by alloc "
"function is too small (%u < %d), doing fallback buffer alloc",
- GST_BUFFER_SIZE (*buf), size);
+ gst_buffer_get_size (*buf), size);
gst_buffer_unref (*buf);