memory improvements
[platform/upstream/gstreamer.git] / gst / gstmemory.c
1 /* GStreamer
2  * Copyright (C) 2011 Wim Taymans <wim.taymans@gmail.be>
3  *
4  * gstmemory.c: memory block handling
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 /**
23  * SECTION:gstmemory
24  * @short_description: refcounted wrapper for memory blocks
25  * @see_also: #GstBuffer
26  *
27  * GstMemory is a lightweight refcounted object that wraps a region of memory.
28  * They are typically used to manage the data of a #GstBuffer.
29  *
30  * A GstMemory object has an allocated region of memory of maxsize. The maximum
31  * size does not change during the lifetime of the memory object. The memory
32  * also has an offset and size property that specifies the valid range of memory
33  * in the allocated region.
34  *
35  * Memory is usually created by allocators with a gst_allocator_alloc()
36  * method call. When NULL is used as the allocator, the default allocator will
37  * be used.
38  *
39  * New allocators can be registered with gst_allocator_register().
40  * Allocators are identified by name and can be retrieved with
41  * gst_allocator_find().
42  *
43  * New memory can be created with gst_memory_new_wrapped() that wraps the memory
44  * allocated elsewhere.
45  *
46  * Refcounting of the memory block is performed with gst_memory_ref() and
47  * gst_memory_unref().
48  *
49  * The size of the memory can be retrieved and changed with
50  * gst_memory_get_sizes() and gst_memory_resize() respectively.
51  *
52  * Getting access to the data of the memory is performed with gst_memory_map().
53  * The call will return a pointer to offset bytes into the region of memory.
54  * After the memory access is completed, gst_memory_unmap() should be called.
55  *
56  * Memory can be copied with gst_memory_copy(), which will returnn a writable
57  * copy. gst_memory_share() will create a new memory block that shares the
58  * memory with an existing memory block at a custom offset and with a custom
59  * size.
60  *
61  * Memory can be efficiently merged when gst_memory_is_span() returns TRUE.
62  *
63  * Last reviewed on 2011-06-08 (0.11.0)
64  */
65
66 #ifdef HAVE_CONFIG_H
67 #include "config.h"
68 #endif
69
70 #include "gst_private.h"
71 #include "gstmemory.h"
72
73 G_DEFINE_BOXED_TYPE (GstMemory, gst_memory, (GBoxedCopyFunc) gst_memory_ref,
74     (GBoxedFreeFunc) gst_memory_unref);
75
76 /**
77  * gst_memory_alignment:
78  *
79  * The default memory alignment in bytes - 1
80  * an alignment of 7 would be the same as what malloc() guarantees.
81  */
82 #if defined(MEMORY_ALIGNMENT_MALLOC)
83 size_t gst_memory_alignment = 7;
84 #elif defined(MEMORY_ALIGNMENT_PAGESIZE)
85 /* we fill this in in the _init method */
86 size_t gst_memory_alignment = 0;
87 #elif defined(MEMORY_ALIGNMENT)
88 size_t gst_memory_alignment = MEMORY_ALIGNMENT - 1;
89 #else
90 #error "No memory alignment configured"
91 size_t gst_memory_alignment = 0;
92 #endif
93
94 struct _GstAllocator
95 {
96   GQuark name;
97
98   GstMemoryInfo info;
99 };
100
101 /* default memory implementation */
102 typedef struct
103 {
104   GstMemory mem;
105   gsize slice_size;
106   guint8 *data;
107   GFreeFunc free_func;
108 } GstMemoryDefault;
109
110 /* the default allocator */
111 static const GstAllocator *_default_allocator;
112
113 /* our predefined allocators */
114 static const GstAllocator *_default_mem_impl;
115
116 /* initialize the fields */
117 static void
118 _default_mem_init (GstMemoryDefault * mem, GstMemoryFlags flags,
119     GstMemory * parent, gsize slice_size, gpointer data,
120     GFreeFunc free_func, gsize maxsize, gsize offset, gsize size)
121 {
122   mem->mem.allocator = _default_mem_impl;
123   mem->mem.flags = flags;
124   mem->mem.refcount = 1;
125   mem->mem.parent = parent ? gst_memory_ref (parent) : NULL;
126   mem->mem.state = (flags & GST_MEMORY_FLAG_READONLY ? 0x5 : 0);
127   mem->mem.maxsize = maxsize;
128   mem->mem.offset = offset;
129   mem->mem.size = size;
130   mem->slice_size = slice_size;
131   mem->data = data;
132   mem->free_func = free_func;
133 }
134
135 /* create a new memory block that manages the given memory */
136 static GstMemoryDefault *
137 _default_mem_new (GstMemoryFlags flags, GstMemory * parent, gpointer data,
138     GFreeFunc free_func, gsize maxsize, gsize offset, gsize size)
139 {
140   GstMemoryDefault *mem;
141   gsize slice_size;
142
143   slice_size = sizeof (GstMemoryDefault);
144
145   mem = g_slice_alloc (slice_size);
146   _default_mem_init (mem, flags, parent, slice_size,
147       data, free_func, maxsize, offset, size);
148
149   return mem;
150 }
151
152 /* allocate the memory and structure in one block */
153 static GstMemoryDefault *
154 _default_mem_new_block (gsize maxsize, gsize align, gsize offset, gsize size)
155 {
156   GstMemoryDefault *mem;
157   gsize aoffset, slice_size;
158   guint8 *data;
159
160   /* ensure configured alignment */
161   align |= gst_memory_alignment;
162   /* allocate more to compensate for alignment */
163   maxsize += align;
164   /* alloc header and data in one block */
165   slice_size = sizeof (GstMemoryDefault) + maxsize;
166
167   mem = g_slice_alloc (slice_size);
168   if (mem == NULL)
169     return NULL;
170
171   data = (guint8 *) mem + sizeof (GstMemoryDefault);
172
173   if ((aoffset = ((guintptr) data & align)))
174     aoffset = (align + 1) - aoffset;
175
176   _default_mem_init (mem, 0, NULL, slice_size, data, NULL, maxsize,
177       aoffset + offset, size);
178
179   return mem;
180 }
181
182 static GstMemory *
183 _default_mem_alloc (const GstAllocator * allocator, gsize maxsize, gsize align)
184 {
185   return (GstMemory *) _default_mem_new_block (maxsize, align, 0, maxsize);
186 }
187
188 static gpointer
189 _default_mem_map (GstMemoryDefault * mem, GstMapFlags flags)
190 {
191   return mem->data;
192 }
193
194 static gboolean
195 _default_mem_unmap (GstMemoryDefault * mem)
196 {
197   return TRUE;
198 }
199
200 static void
201 _default_mem_free (GstMemoryDefault * mem)
202 {
203   if (mem->mem.parent)
204     gst_memory_unref (mem->mem.parent);
205
206   if (mem->free_func)
207     mem->free_func (mem->data);
208
209   g_slice_free1 (mem->slice_size, mem);
210 }
211
212 static GstMemoryDefault *
213 _default_mem_copy (GstMemoryDefault * mem, gssize offset, gsize size)
214 {
215   GstMemoryDefault *copy;
216
217   if (size == -1)
218     size = mem->mem.size > offset ? mem->mem.size - offset : 0;
219
220   copy =
221       _default_mem_new_block (mem->mem.maxsize, 0, mem->mem.offset + offset,
222       size);
223   memcpy (copy->data, mem->data, mem->mem.maxsize);
224
225   return copy;
226 }
227
228 static GstMemoryDefault *
229 _default_mem_share (GstMemoryDefault * mem, gssize offset, gsize size)
230 {
231   GstMemoryDefault *sub;
232   GstMemory *parent;
233
234   /* find the real parent */
235   if ((parent = mem->mem.parent) == NULL)
236     parent = (GstMemory *) mem;
237
238   if (size == -1)
239     size = mem->mem.size - offset;
240
241   sub =
242       _default_mem_new (parent->flags, parent, mem->data, NULL,
243       mem->mem.maxsize, mem->mem.offset + offset, size);
244
245   return sub;
246 }
247
248 static gboolean
249 _default_mem_is_span (GstMemoryDefault * mem1, GstMemoryDefault * mem2,
250     gsize * offset)
251 {
252
253   if (offset) {
254     GstMemoryDefault *parent;
255
256     parent = (GstMemoryDefault *) mem1->mem.parent;
257
258     *offset = mem1->mem.offset - parent->mem.offset;
259   }
260
261   /* and memory is contiguous */
262   return mem1->data + mem1->mem.offset + mem1->mem.size ==
263       mem2->data + mem2->mem.offset;
264 }
265
266 static GstMemory *
267 _fallback_copy (GstMemory * mem, gssize offset, gssize size)
268 {
269   GstMemory *copy;
270   guint8 *data, *dest;
271   gsize msize;
272
273   data = gst_memory_map (mem, &msize, NULL, GST_MAP_READ);
274   if (data == NULL)
275     return NULL;
276   if (size == -1)
277     size = msize > offset ? msize - offset : 0;
278   /* use the same allocator as the memory we copy  */
279   copy = gst_allocator_alloc (mem->allocator, size, mem->align);
280   dest = gst_memory_map (copy, NULL, NULL, GST_MAP_WRITE);
281   memcpy (dest, data + offset, size);
282   gst_memory_unmap (copy);
283   gst_memory_unmap (mem);
284
285   return (GstMemory *) copy;
286 }
287
288 static gboolean
289 _fallback_is_span (GstMemory * mem1, GstMemory * mem2, gsize * offset)
290 {
291   return FALSE;
292 }
293
294 static GRWLock lock;
295 static GHashTable *allocators;
296
297 void
298 _priv_gst_memory_initialize (void)
299 {
300   static const GstMemoryInfo _mem_info = {
301     (GstMemoryAllocFunction) _default_mem_alloc,
302     (GstMemoryMapFunction) _default_mem_map,
303     (GstMemoryUnmapFunction) _default_mem_unmap,
304     (GstMemoryFreeFunction) _default_mem_free,
305     (GstMemoryCopyFunction) _default_mem_copy,
306     (GstMemoryShareFunction) _default_mem_share,
307     (GstMemoryIsSpanFunction) _default_mem_is_span,
308     NULL
309   };
310
311   g_rw_lock_init (&lock);
312   allocators = g_hash_table_new (g_str_hash, g_str_equal);
313
314 #ifdef HAVE_GETPAGESIZE
315 #ifdef MEMORY_ALIGNMENT_PAGESIZE
316   gst_memory_alignment = getpagesize () - 1;
317 #endif
318 #endif
319
320   GST_DEBUG ("memory alignment: %" G_GSIZE_FORMAT, gst_memory_alignment);
321
322   _default_mem_impl = gst_allocator_register (GST_ALLOCATOR_SYSMEM, &_mem_info);
323
324   _default_allocator = _default_mem_impl;
325 }
326
327 /**
328  * gst_memory_new_wrapped:
329  * @flags: #GstMemoryFlags
330  * @data: data to wrap
331  * @free_func: function to free @data
332  * @maxsize: allocated size of @data
333  * @offset: offset in @data
334  * @size: size of valid data
335  *
336  * Allocate a new memory block that wraps the given @data.
337  *
338  * Returns: a new #GstMemory.
339  */
340 GstMemory *
341 gst_memory_new_wrapped (GstMemoryFlags flags, gpointer data,
342     GFreeFunc free_func, gsize maxsize, gsize offset, gsize size)
343 {
344   GstMemoryDefault *mem;
345
346   g_return_val_if_fail (data != NULL, NULL);
347   g_return_val_if_fail (offset + size <= maxsize, NULL);
348
349   mem = _default_mem_new (flags, NULL, data, free_func, maxsize, offset, size);
350
351   return (GstMemory *) mem;
352 }
353
354 /**
355  * gst_memory_ref:
356  * @mem: a #GstMemory
357  *
358  * Increases the refcount of @mem.
359  *
360  * Returns: @mem with increased refcount
361  */
362 GstMemory *
363 gst_memory_ref (GstMemory * mem)
364 {
365   g_return_val_if_fail (mem != NULL, NULL);
366
367   g_atomic_int_inc (&mem->refcount);
368
369   return mem;
370 }
371
372 /**
373  * gst_memory_unref:
374  * @mem: a #GstMemory
375  *
376  * Decreases the refcount of @mem. When the refcount reaches 0, the free
377  * function of @mem will be called.
378  */
379 void
380 gst_memory_unref (GstMemory * mem)
381 {
382   g_return_if_fail (mem != NULL);
383   g_return_if_fail (mem->allocator != NULL);
384
385   if (g_atomic_int_dec_and_test (&mem->refcount))
386     mem->allocator->info.free (mem);
387 }
388
389 /**
390  * gst_memory_get_sizes:
391  * @mem: a #GstMemory
392  * @offset: pointer to offset
393  * @maxsize: pointer to maxsize
394  *
395  * Get the current @size, @offset and @maxsize of @mem.
396  *
397  * Returns: the current sizes of @mem
398  */
399 gsize
400 gst_memory_get_sizes (GstMemory * mem, gsize * offset, gsize * maxsize)
401 {
402   g_return_val_if_fail (mem != NULL, 0);
403
404   if (offset)
405     *offset = mem->offset;
406   if (maxsize)
407     *maxsize = mem->maxsize;
408
409   return mem->size;
410 }
411
412 /**
413  * gst_memory_resize:
414  * @mem: a #GstMemory
415  * @offset: a new offset
416  * @size: a new size
417  *
418  * Resize the memory region. @mem should be writable and offset + size should be
419  * less than the maxsize of @mem.
420  */
421 void
422 gst_memory_resize (GstMemory * mem, gssize offset, gsize size)
423 {
424   g_return_if_fail (mem != NULL);
425   g_return_if_fail (gst_memory_is_writable (mem));
426   g_return_if_fail (offset >= 0 || mem->offset >= -offset);
427   g_return_if_fail (size + mem->offset + offset <= mem->maxsize);
428
429   mem->offset += offset;
430   mem->size = size;
431 }
432
433 /**
434  * gst_memory_is_writable:
435  * @mem: a #GstMemory
436  *
437  * Check if @mem is writable.
438  *
439  * Returns: %TRUE is @mem is writable.
440  */
441 gboolean
442 gst_memory_is_writable (GstMemory * mem)
443 {
444   g_return_val_if_fail (mem != NULL, FALSE);
445
446   return (mem->refcount == 1) &&
447       ((mem->parent == NULL) || (mem->parent->refcount == 1)) &&
448       ((mem->flags & GST_MEMORY_FLAG_READONLY) == 0);
449 }
450
451 static gboolean
452 gst_memory_lock (GstMemory * mem, GstMapFlags flags)
453 {
454   gint access_mode, state, newstate;
455
456   access_mode = flags & 3;
457
458   do {
459     state = g_atomic_int_get (&mem->state);
460     if (state == 0) {
461       /* nothing mapped, set access_mode and refcount */
462       newstate = 4 | access_mode;
463     } else {
464       /* access_mode must match */
465       if ((state & access_mode) != access_mode)
466         goto lock_failed;
467       /* increase refcount */
468       newstate = state + 4;
469     }
470   } while (!g_atomic_int_compare_and_exchange (&mem->state, state, newstate));
471
472   return TRUE;
473
474 lock_failed:
475   {
476     GST_DEBUG ("lock failed %p: state %d, access_mode %d", mem, state,
477         access_mode);
478     return FALSE;
479   }
480 }
481
482 static void
483 gst_memory_unlock (GstMemory * mem)
484 {
485   gint state, newstate;
486
487   do {
488     state = g_atomic_int_get (&mem->state);
489     /* decrease the refcount */
490     newstate = state - 4;
491     /* last refcount, unset access_mode */
492     if (newstate < 4)
493       newstate = 0;
494   } while (!g_atomic_int_compare_and_exchange (&mem->state, state, newstate));
495 }
496
497 /**
498  * gst_memory_map:
499  * @mem: a #GstMemory
500  * @size: (out) (allow-none): pointer for size
501  * @maxsize: (out) (allow-none): pointer for maxsize
502  * @flags: mapping flags
503  *
504  * Get a pointer to the memory of @mem that can be accessed according to @flags.
505  *
506  * @size and @maxsize will contain the size of the memory and the maximum
507  * allocated memory of @mem respectively. They can be set to NULL.
508  *
509  * This function can return NULL for various reasons:
510  * - the memory backed by @mem is not accessible with the given @flags.
511  * - the memory was already mapped with a different mapping.
512  *
513  * @pointer remains valid for as long as @mem is alive and until
514  * gst_memory_unmap() is called.
515  *
516  * For each gst_memory_map() call, a corresponding gst_memory_unmap() call
517  * should be done.
518  *
519  * Returns: (transfer none): a pointer to the memory of @mem.
520  */
521 gpointer
522 gst_memory_map (GstMemory * mem, gsize * size, gsize * maxsize,
523     GstMapFlags flags)
524 {
525   guint8 *res;
526
527   g_return_val_if_fail (mem != NULL, NULL);
528
529   if (!gst_memory_lock (mem, flags))
530     goto lock_failed;
531
532   res = mem->allocator->info.map (mem, mem->maxsize, flags);
533
534   if (G_UNLIKELY (res == NULL))
535     goto error;
536
537   if (size)
538     *size = mem->size;
539   if (maxsize)
540     *maxsize = mem->maxsize - mem->offset;
541
542   return res + mem->offset;
543
544   /* ERRORS */
545 lock_failed:
546   {
547     g_critical ("memory %p: failed to lock memory", mem);
548     return NULL;
549   }
550 error:
551   {
552     /* something went wrong, restore the orginal state again */
553     GST_ERROR ("mem %p: map failed", mem);
554     gst_memory_unlock (mem);
555     return NULL;
556   }
557 }
558
559 /**
560  * gst_memory_unmap:
561  * @mem: a #GstMemory
562  *
563  * Release the memory obtained with gst_memory_map()
564  */
565 void
566 gst_memory_unmap (GstMemory * mem)
567 {
568   g_return_if_fail (mem != NULL);
569   /* there must be a ref */
570   g_return_if_fail (g_atomic_int_get (&mem->state) >= 4);
571
572   mem->allocator->info.unmap (mem);
573   gst_memory_unlock (mem);
574 }
575
576 /**
577  * gst_memory_copy:
578  * @mem: a #GstMemory
579  * @offset: an offset to copy
580  * @size: size to copy or -1 to copy all bytes from offset
581  *
582  * Return a copy of @size bytes from @mem starting from @offset. This copy is
583  * guaranteed to be writable. @size can be set to -1 to return a copy all bytes
584  * from @offset.
585  *
586  * Returns: a new #GstMemory.
587  */
588 GstMemory *
589 gst_memory_copy (GstMemory * mem, gssize offset, gssize size)
590 {
591   GstMemory *copy;
592
593   g_return_val_if_fail (mem != NULL, NULL);
594   g_return_val_if_fail (gst_memory_lock (mem, GST_MAP_READ), NULL);
595
596   copy = mem->allocator->info.copy (mem, offset, size);
597
598   gst_memory_unlock (mem);
599
600   return copy;
601 }
602
603 /**
604  * gst_memory_share:
605  * @mem: a #GstMemory
606  * @offset: an offset to share
607  * @size: size to share or -1 to share bytes from offset
608  *
609  * Return a shared copy of @size bytes from @mem starting from @offset. No
610  * memory copy is performed and the memory region is simply shared. The result
611  * is guaranteed to be not-writable. @size can be set to -1 to return a share
612  * all bytes from @offset.
613  *
614  * Returns: a new #GstMemory.
615  */
616 GstMemory *
617 gst_memory_share (GstMemory * mem, gssize offset, gssize size)
618 {
619   g_return_val_if_fail (mem != NULL, NULL);
620
621   return mem->allocator->info.share (mem, offset, size);
622 }
623
624 /**
625  * gst_memory_is_span:
626  * @mem1: a #GstMemory
627  * @mem2: a #GstMemory
628  * @offset: a pointer to a result offset
629  *
630  * Check if @mem1 and mem2 share the memory with a common parent memory object
631  * and that the memory is contiguous.
632  *
633  * If this is the case, the memory of @mem1 and @mem2 can be merged
634  * efficiently by performing gst_memory_share() on the parent object from
635  * the returned @offset.
636  *
637  * Returns: %TRUE if the memory is contiguous and of a common parent.
638  */
639 gboolean
640 gst_memory_is_span (GstMemory * mem1, GstMemory * mem2, gsize * offset)
641 {
642   g_return_val_if_fail (mem1 != NULL, FALSE);
643   g_return_val_if_fail (mem2 != NULL, FALSE);
644
645   /* need to have the same allocators */
646   if (mem1->allocator != mem2->allocator)
647     return FALSE;
648
649   /* need to have the same parent */
650   if (mem1->parent == NULL || mem1->parent != mem2->parent)
651     return FALSE;
652
653   /* and memory is contiguous */
654   if (!mem1->allocator->info.is_span (mem1, mem2, offset))
655     return FALSE;
656
657   return TRUE;
658 }
659
660 /**
661  * gst_allocator_register:
662  * @name: the name of the allocator
663  * @info: #GstMemoryInfo
664  *
665  * Registers the memory allocator with @name and implementation functions
666  * @info.
667  *
668  * All functions in @info are mandatory exept the copy and is_span
669  * functions, which will have a default implementation when left NULL.
670  *
671  * The user_data field in @info will be passed to all calls of the alloc
672  * function.
673  *
674  * Returns: a new #GstAllocator.
675  */
676 const GstAllocator *
677 gst_allocator_register (const gchar * name, const GstMemoryInfo * info)
678 {
679   GstAllocator *allocator;
680
681 #define INSTALL_FALLBACK(_t) \
682   if (allocator->info._t == NULL) allocator->info._t = _fallback_ ##_t;
683
684   g_return_val_if_fail (name != NULL, NULL);
685   g_return_val_if_fail (info != NULL, NULL);
686   g_return_val_if_fail (info->alloc != NULL, NULL);
687   g_return_val_if_fail (info->map != NULL, NULL);
688   g_return_val_if_fail (info->unmap != NULL, NULL);
689   g_return_val_if_fail (info->free != NULL, NULL);
690   g_return_val_if_fail (info->share != NULL, NULL);
691
692   allocator = g_slice_new (GstAllocator);
693   allocator->name = g_quark_from_string (name);
694   allocator->info = *info;
695   INSTALL_FALLBACK (copy);
696   INSTALL_FALLBACK (is_span);
697 #undef INSTALL_FALLBACK
698
699   GST_DEBUG ("registering allocator \"%s\"", name);
700
701   g_rw_lock_writer_lock (&lock);
702   g_hash_table_insert (allocators, (gpointer) name, (gpointer) allocator);
703   g_rw_lock_writer_unlock (&lock);
704
705   return allocator;
706 }
707
708 /**
709  * gst_allocator_find:
710  * @name: the name of the allocator
711  *
712  * Find a previously registered allocator with @name. When @name is NULL, the
713  * default allocator will be returned.
714  *
715  * Returns: a #GstAllocator or NULL when the allocator with @name was not
716  * registered.
717  */
718 const GstAllocator *
719 gst_allocator_find (const gchar * name)
720 {
721   const GstAllocator *allocator;
722
723   g_rw_lock_reader_lock (&lock);
724   if (name) {
725     allocator = g_hash_table_lookup (allocators, (gconstpointer) name);
726   } else {
727     allocator = _default_allocator;
728   }
729   g_rw_lock_reader_unlock (&lock);
730
731   return allocator;
732 }
733
734 /**
735  * gst_allocator_set_default:
736  * @allocator: a #GstAllocator
737  *
738  * Set the default allocator.
739  */
740 void
741 gst_allocator_set_default (const GstAllocator * allocator)
742 {
743   g_return_if_fail (allocator != NULL);
744
745   g_rw_lock_writer_lock (&lock);
746   _default_allocator = allocator;
747   g_rw_lock_writer_unlock (&lock);
748 }
749
750 /**
751  * gst_allocator_alloc:
752  * @allocator: (transfer none) (allow-none): a #GstAllocator to use
753  * @maxsize: allocated size of @data
754  * @align: alignment for the data
755  *
756  * Use @allocator to allocate a new memory block with memory that is at least
757  * @maxsize big and has the given alignment.
758  *
759  * When @allocator is NULL, the default allocator will be used.
760  *
761  * @align is given as a bitmask so that @align + 1 equals the amount of bytes to
762  * align to. For example, to align to 8 bytes, use an alignment of 7.
763  *
764  * Returns: (transfer full): a new #GstMemory.
765  */
766 GstMemory *
767 gst_allocator_alloc (const GstAllocator * allocator, gsize maxsize, gsize align)
768 {
769   g_return_val_if_fail (((align + 1) & align) == 0, NULL);
770
771   if (allocator == NULL)
772     allocator = _default_allocator;
773
774   return allocator->info.alloc (allocator, maxsize, align,
775       allocator->info.user_data);
776 }