memory: more fixes
authorWim Taymans <wim.taymans@collabora.co.uk>
Mon, 21 Mar 2011 12:07:42 +0000 (13:07 +0100)
committerWim Taymans <wim.taymans@collabora.co.uk>
Mon, 28 Mar 2011 18:08:45 +0000 (20:08 +0200)
Fix span and is_span
Implement buffer memory

gst/gstbuffer.c
gst/gstbuffer.h
gst/gstbufferlist.c
gst/gstbufferpool.c
gst/gstmemory.c
gst/gstmemory.h
gst/gstmeta.c
gst/gstpad.c

index 0b8692b..e0192f2 100644 (file)
@@ -154,16 +154,6 @@ static size_t _gst_buffer_data_alignment = BUFFER_ALIGNMENT;
 #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
@@ -179,58 +169,21 @@ _gst_buffer_initialize (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;
 
@@ -260,16 +213,45 @@ gst_buffer_copy_metadata (GstBuffer * dest, GstBuffer * src,
   }
 
   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;
@@ -291,8 +273,7 @@ _gst_buffer_copy (GstBuffer * buffer)
   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;
 }
@@ -337,7 +318,7 @@ _gst_buffer_free (GstBuffer * buffer)
     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);
@@ -445,6 +426,8 @@ gst_buffer_try_new_and_alloc (guint size)
     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);
@@ -488,7 +471,7 @@ gst_buffer_remove_memory (GstBuffer * buffer, guint idx)
 }
 
 gsize
-gst_buffer_get_memory_size (GstBuffer * buffer)
+gst_buffer_get_size (GstBuffer * buffer)
 {
   GPtrArray *arr = (GPtrArray *) buffer->memory;
   guint i, size, len;
@@ -507,13 +490,39 @@ gpointer
 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;
 }
 
 /**
@@ -614,15 +623,12 @@ gst_buffer_make_metadata_writable (GstBuffer * buf)
     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.
@@ -645,88 +651,25 @@ gst_buffer_make_metadata_writable (GstBuffer * buf)
  *     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;
 }
 
@@ -736,7 +679,7 @@ gst_buffer_create_sub (GstBuffer * buffer, guint offset, guint size)
  * @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.
@@ -746,14 +689,17 @@ gst_buffer_create_sub (GstBuffer * buffer, guint offset, guint size)
 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);
 }
 
 /**
@@ -780,36 +726,27 @@ gst_buffer_is_span_fast (GstBuffer * buf1, GstBuffer * buf2)
  *     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);
@@ -831,6 +768,7 @@ gst_buffer_span (GstBuffer * buf1, guint32 offset, GstBuffer * buf2,
       }
     }
   }
+#endif
 
   return newbuf;
 }
index aa229e9..420c8fb 100644 (file)
@@ -302,7 +302,7 @@ void        gst_buffer_take_memory       (GstBuffer *buffer, GstMemory *mem);
 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,
@@ -406,27 +406,32 @@ gst_buffer_copy (const GstBuffer * buf)
  * 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:
@@ -481,11 +486,11 @@ GstCaps*        gst_buffer_get_caps             (GstBuffer *buffer);
 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>
index 7bcc746..2713803 100644 (file)
@@ -836,9 +836,9 @@ GstBuffer *
 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);
 
@@ -847,7 +847,7 @@ gst_buffer_list_iterator_merge_group (const GstBufferListIterator * it)
   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);
   }
@@ -860,19 +860,26 @@ gst_buffer_list_iterator_merge_group (const GstBufferListIterator * it)
   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;
 }
index 83acd68..6e85495 100644 (file)
@@ -160,22 +160,14 @@ static GstFlowReturn
 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;
 }
index 02bc279..cadea03 100644 (file)
@@ -220,44 +220,14 @@ _default_mem_sub (GstMemoryDefault * mem, gsize offset, gsize size)
 }
 
 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
@@ -301,32 +271,11 @@ _fallback_sub (GstMemory * mem, gsize offset, gsize size)
 }
 
 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)
 {
@@ -350,7 +299,6 @@ 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);
 
@@ -376,8 +324,7 @@ _gst_memory_init (void)
     (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,
@@ -388,7 +335,6 @@ _gst_memory_init (void)
     NULL,
     NULL,
     NULL,
-    NULL,
     NULL
   };
 
@@ -474,21 +420,99 @@ gst_memory_sub (GstMemory * mem, gsize offset, gsize size)
 }
 
 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 *
index 652dd9a..c371821 100644 (file)
@@ -79,9 +79,8 @@ typedef void        (*GstMemoryExtractFunction)   (GstMemory *mem, gsize offset,
                                                    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:
@@ -100,7 +99,6 @@ struct _GstMemoryInfo {
   GstMemoryExtractFunction  extract;
   GstMemorySubFunction      sub;
   GstMemoryIsSpanFunction   is_span;
-  GstMemorySpanFunction     span;
 };
 
 void _gst_memory_init (void);
@@ -120,9 +118,11 @@ void        gst_memory_extract    (GstMemory *mem, gsize offset, gpointer dest,
                                    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,
index 827f9f7..d64b719 100644 (file)
@@ -241,7 +241,7 @@ meta_timing_transform (GstBuffer * transbuf, GstMetaTiming * meta,
     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,
@@ -252,7 +252,7 @@ meta_timing_transform (GstBuffer * transbuf, GstMetaTiming * meta,
     /* 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 {
index 829aaf0..46f0f68 100644 (file)
@@ -2960,7 +2960,8 @@ gst_pad_alloc_buffer_full (GstPad * pad, guint64 offset, gint size,
   }
 
   /* 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;
@@ -2997,7 +2998,7 @@ wrong_size_fallback:
   {
     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);