alllocator: no need to store structure size inside the structure
[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(). gst_allocator_set_default() can be used to change the
42  * default allocator.
43  *
44  * New memory can be created with gst_memory_new_wrapped() that wraps the memory
45  * allocated elsewhere.
46  *
47  * Refcounting of the memory block is performed with gst_memory_ref() and
48  * gst_memory_unref().
49  *
50  * The size of the memory can be retrieved and changed with
51  * gst_memory_get_sizes() and gst_memory_resize() respectively.
52  *
53  * Getting access to the data of the memory is performed with gst_memory_map().
54  * The call will return a pointer to offset bytes into the region of memory.
55  * After the memory access is completed, gst_memory_unmap() should be called.
56  *
57  * Memory can be copied with gst_memory_copy(), which will return a writable
58  * copy. gst_memory_share() will create a new memory block that shares the
59  * memory with an existing memory block at a custom offset and with a custom
60  * size.
61  *
62  * Memory can be efficiently merged when gst_memory_is_span() returns TRUE.
63  *
64  * Last reviewed on 2012-03-28 (0.11.3)
65  */
66
67 #ifdef HAVE_CONFIG_H
68 #include "config.h"
69 #endif
70
71 #include "gst_private.h"
72 #include "gstmemory.h"
73
74 GST_DEFINE_MINI_OBJECT_TYPE (GstMemory, gst_memory);
75
76 GST_DEFINE_MINI_OBJECT_TYPE (GstAllocator, gst_allocator);
77
78 G_DEFINE_BOXED_TYPE (GstAllocationParams, gst_allocation_params,
79     (GBoxedCopyFunc) gst_allocation_params_copy,
80     (GBoxedFreeFunc) gst_allocation_params_free);
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   GstMiniObject mini_object;
97
98   GstMemoryInfo info;
99
100   gpointer user_data;
101   GDestroyNotify notify;
102 };
103
104 /* default memory implementation */
105 typedef struct
106 {
107   GstMemory mem;
108   gsize slice_size;
109   guint8 *data;
110   gpointer user_data;
111   GDestroyNotify notify;
112 } GstMemoryDefault;
113
114 /* the default allocator */
115 static GstAllocator *_default_allocator;
116
117 /* our predefined allocators */
118 static GstAllocator *_default_mem_impl;
119
120 static GstMemory *
121 _gst_memory_copy (GstMemory * mem)
122 {
123   return gst_memory_copy (mem, 0, -1);
124 }
125
126 static void
127 _gst_memory_free (GstMemory * mem)
128 {
129   /* there should be no outstanding mappings */
130   g_return_if_fail (g_atomic_int_get (&mem->state) < 4);
131   mem->allocator->info.mem_free (mem);
132 }
133
134 /* initialize the fields */
135 static void
136 _default_mem_init (GstMemoryDefault * mem, GstMemoryFlags flags,
137     GstMemory * parent, gsize slice_size, gpointer data,
138     gsize maxsize, gsize offset, gsize size, gsize align,
139     gpointer user_data, GDestroyNotify notify)
140 {
141   gst_mini_object_init (GST_MINI_OBJECT_CAST (mem), GST_TYPE_MEMORY);
142
143   mem->mem.mini_object.copy = (GstMiniObjectCopyFunction) _gst_memory_copy;
144   mem->mem.mini_object.dispose = NULL;
145   mem->mem.mini_object.free = (GstMiniObjectFreeFunction) _gst_memory_free;
146   mem->mem.mini_object.flags = flags;
147
148   mem->mem.allocator = _default_mem_impl;
149   mem->mem.parent = parent ? gst_memory_ref (parent) : NULL;
150   mem->mem.state = (flags & GST_MEMORY_FLAG_READONLY ? 0x1 : 0);
151   mem->mem.maxsize = maxsize;
152   mem->mem.align = align;
153   mem->mem.offset = offset;
154   mem->mem.size = size;
155   mem->slice_size = slice_size;
156   mem->data = data;
157   mem->user_data = user_data;
158   mem->notify = notify;
159
160   GST_CAT_DEBUG (GST_CAT_MEMORY, "new memory %p, maxsize:%" G_GSIZE_FORMAT
161       " offset:%" G_GSIZE_FORMAT " size:%" G_GSIZE_FORMAT, mem, maxsize,
162       offset, size);
163 }
164
165 /* create a new memory block that manages the given memory */
166 static GstMemoryDefault *
167 _default_mem_new (GstMemoryFlags flags, GstMemory * parent, gpointer data,
168     gsize maxsize, gsize offset, gsize size, gsize align, gpointer user_data,
169     GDestroyNotify notify)
170 {
171   GstMemoryDefault *mem;
172   gsize slice_size;
173
174   slice_size = sizeof (GstMemoryDefault);
175
176   mem = g_slice_alloc (slice_size);
177   _default_mem_init (mem, flags, parent, slice_size,
178       data, maxsize, offset, size, align, user_data, notify);
179
180   return mem;
181 }
182
183 /* allocate the memory and structure in one block */
184 static GstMemoryDefault *
185 _default_mem_new_block (GstMemoryFlags flags, gsize maxsize, gsize align,
186     gsize offset, gsize size)
187 {
188   GstMemoryDefault *mem;
189   gsize aoffset, slice_size, padding;
190   guint8 *data;
191
192   /* ensure configured alignment */
193   align |= gst_memory_alignment;
194   /* allocate more to compensate for alignment */
195   maxsize += align;
196   /* alloc header and data in one block */
197   slice_size = sizeof (GstMemoryDefault) + maxsize;
198
199   mem = g_slice_alloc (slice_size);
200   if (mem == NULL)
201     return NULL;
202
203   data = (guint8 *) mem + sizeof (GstMemoryDefault);
204
205   /* do alignment */
206   if ((aoffset = ((guintptr) data & align))) {
207     aoffset = (align + 1) - aoffset;
208     data += aoffset;
209     maxsize -= aoffset;
210   }
211
212   if (offset && (flags & GST_MEMORY_FLAG_ZERO_PREFIXED))
213     memset (data, 0, offset);
214
215   padding = maxsize - (offset + size);
216   if (padding && (flags & GST_MEMORY_FLAG_ZERO_PADDED))
217     memset (data + offset + size, 0, padding);
218
219   _default_mem_init (mem, flags, NULL, slice_size, data, maxsize,
220       offset, size, align, NULL, NULL);
221
222   return mem;
223 }
224
225 static GstMemory *
226 _default_alloc_alloc (GstAllocator * allocator, gsize size,
227     GstAllocationParams * params, gpointer user_data)
228 {
229   gsize maxsize = size + params->prefix + params->padding;
230
231   return (GstMemory *) _default_mem_new_block (params->flags,
232       maxsize, params->align, params->prefix, size);
233 }
234
235 static gpointer
236 _default_mem_map (GstMemoryDefault * mem, gsize maxsize, GstMapFlags flags)
237 {
238   return mem->data;
239 }
240
241 static gboolean
242 _default_mem_unmap (GstMemoryDefault * mem)
243 {
244   return TRUE;
245 }
246
247 static void
248 _default_mem_free (GstMemoryDefault * mem)
249 {
250   GST_CAT_DEBUG (GST_CAT_MEMORY, "free memory %p", mem);
251
252   if (mem->mem.parent)
253     gst_memory_unref (mem->mem.parent);
254
255   if (mem->notify)
256     mem->notify (mem->user_data);
257
258   g_slice_free1 (mem->slice_size, mem);
259 }
260
261 static GstMemoryDefault *
262 _default_mem_copy (GstMemoryDefault * mem, gssize offset, gsize size)
263 {
264   GstMemoryDefault *copy;
265
266   if (size == -1)
267     size = mem->mem.size > offset ? mem->mem.size - offset : 0;
268
269   copy =
270       _default_mem_new_block (0, mem->mem.maxsize, 0, mem->mem.offset + offset,
271       size);
272   GST_CAT_DEBUG (GST_CAT_PERFORMANCE,
273       "memcpy %" G_GSIZE_FORMAT " memory %p -> %p", mem->mem.maxsize, mem,
274       copy);
275   memcpy (copy->data, mem->data, mem->mem.maxsize);
276
277   return copy;
278 }
279
280 static GstMemoryDefault *
281 _default_mem_share (GstMemoryDefault * mem, gssize offset, gsize size)
282 {
283   GstMemoryDefault *sub;
284   GstMemory *parent;
285
286   /* find the real parent */
287   if ((parent = mem->mem.parent) == NULL)
288     parent = (GstMemory *) mem;
289
290   if (size == -1)
291     size = mem->mem.size - offset;
292
293   sub =
294       _default_mem_new (GST_MINI_OBJECT_FLAGS (parent), parent, mem->data,
295       mem->mem.maxsize, mem->mem.offset + offset, size, mem->mem.align, NULL,
296       NULL);
297
298   return sub;
299 }
300
301 static gboolean
302 _default_mem_is_span (GstMemoryDefault * mem1, GstMemoryDefault * mem2,
303     gsize * offset)
304 {
305
306   if (offset) {
307     GstMemoryDefault *parent;
308
309     parent = (GstMemoryDefault *) mem1->mem.parent;
310
311     *offset = mem1->mem.offset - parent->mem.offset;
312   }
313
314   /* and memory is contiguous */
315   return mem1->data + mem1->mem.offset + mem1->mem.size ==
316       mem2->data + mem2->mem.offset;
317 }
318
319 static GstMemory *
320 _fallback_mem_copy (GstMemory * mem, gssize offset, gssize size)
321 {
322   GstMemory *copy;
323   GstMapInfo sinfo, dinfo;
324   GstAllocationParams params = { 0, 0, 0, mem->align, };
325
326   if (!gst_memory_map (mem, &sinfo, GST_MAP_READ))
327     return NULL;
328
329   if (size == -1)
330     size = sinfo.size > offset ? sinfo.size - offset : 0;
331
332   /* use the same allocator as the memory we copy  */
333   copy = gst_allocator_alloc (mem->allocator, size, &params);
334   if (!gst_memory_map (copy, &dinfo, GST_MAP_WRITE)) {
335     GST_CAT_WARNING (GST_CAT_MEMORY, "could not write map memory %p", copy);
336     gst_memory_unmap (mem, &sinfo);
337     return NULL;
338   }
339
340   GST_CAT_DEBUG (GST_CAT_PERFORMANCE,
341       "memcpy %" G_GSSIZE_FORMAT " memory %p -> %p", size, mem, copy);
342   memcpy (dinfo.data, sinfo.data + offset, size);
343   gst_memory_unmap (copy, &dinfo);
344   gst_memory_unmap (mem, &sinfo);
345
346   return copy;
347 }
348
349 static gboolean
350 _fallback_mem_is_span (GstMemory * mem1, GstMemory * mem2, gsize * offset)
351 {
352   return FALSE;
353 }
354
355 static GRWLock lock;
356 static GHashTable *allocators;
357
358 static void
359 _priv_sysmem_notify (gpointer user_data)
360 {
361   g_warning ("The default memory allocator was freed!");
362 }
363
364 void
365 _priv_gst_memory_initialize (void)
366 {
367   static const GstMemoryInfo _mem_info = {
368     GST_ALLOCATOR_SYSMEM,
369     (GstAllocatorAllocFunction) _default_alloc_alloc,
370     (GstMemoryMapFunction) _default_mem_map,
371     (GstMemoryUnmapFunction) _default_mem_unmap,
372     (GstMemoryFreeFunction) _default_mem_free,
373     (GstMemoryCopyFunction) _default_mem_copy,
374     (GstMemoryShareFunction) _default_mem_share,
375     (GstMemoryIsSpanFunction) _default_mem_is_span,
376   };
377
378   g_rw_lock_init (&lock);
379   allocators = g_hash_table_new (g_str_hash, g_str_equal);
380
381 #ifdef HAVE_GETPAGESIZE
382 #ifdef MEMORY_ALIGNMENT_PAGESIZE
383   gst_memory_alignment = getpagesize () - 1;
384 #endif
385 #endif
386
387   GST_CAT_DEBUG (GST_CAT_MEMORY, "memory alignment: %" G_GSIZE_FORMAT,
388       gst_memory_alignment);
389
390   _default_mem_impl = gst_allocator_new (&_mem_info, NULL, _priv_sysmem_notify);
391
392   _default_allocator = gst_allocator_ref (_default_mem_impl);
393   gst_allocator_register (GST_ALLOCATOR_SYSMEM,
394       gst_allocator_ref (_default_mem_impl));
395 }
396
397 /**
398  * gst_memory_new_wrapped:
399  * @flags: #GstMemoryFlags
400  * @data: data to wrap
401  * @maxsize: allocated size of @data
402  * @offset: offset in @data
403  * @size: size of valid data
404  * @user_data: user_data
405  * @notify: called with @user_data when the memory is freed
406  *
407  * Allocate a new memory block that wraps the given @data.
408  *
409  * The prefix/padding must be filled with 0 if @flags contains
410  * #GST_MEMORY_FLAG_ZERO_PREFIXED and #GST_MEMORY_FLAG_ZERO_PADDED respectively.
411  *
412  * Returns: a new #GstMemory.
413  */
414 GstMemory *
415 gst_memory_new_wrapped (GstMemoryFlags flags, gpointer data,
416     gsize maxsize, gsize offset, gsize size, gpointer user_data,
417     GDestroyNotify notify)
418 {
419   GstMemoryDefault *mem;
420
421   g_return_val_if_fail (data != NULL, NULL);
422   g_return_val_if_fail (offset + size <= maxsize, NULL);
423
424   mem =
425       _default_mem_new (flags, NULL, data, maxsize, offset, size, 0, user_data,
426       notify);
427
428   return (GstMemory *) mem;
429 }
430
431 /**
432  * gst_memory_is_exclusive:
433  * @mem: a #GstMemory
434  *
435  * Check if the current ref to @mem is exclusive, this means that no other
436  * references exist other than @mem.
437  */
438 gboolean
439 gst_memory_is_exclusive (GstMemory * mem)
440 {
441   g_return_val_if_fail (mem != NULL, FALSE);
442
443   return GST_MINI_OBJECT_REFCOUNT_VALUE (mem) == 1;
444 }
445
446 /**
447  * gst_memory_get_sizes:
448  * @mem: a #GstMemory
449  * @offset: pointer to offset
450  * @maxsize: pointer to maxsize
451  *
452  * Get the current @size, @offset and @maxsize of @mem.
453  *
454  * Returns: the current sizes of @mem
455  */
456 gsize
457 gst_memory_get_sizes (GstMemory * mem, gsize * offset, gsize * maxsize)
458 {
459   g_return_val_if_fail (mem != NULL, 0);
460
461   if (offset)
462     *offset = mem->offset;
463   if (maxsize)
464     *maxsize = mem->maxsize;
465
466   return mem->size;
467 }
468
469 /**
470  * gst_memory_resize:
471  * @mem: a #GstMemory
472  * @offset: a new offset
473  * @size: a new size
474  *
475  * Resize the memory region. @mem should be writable and offset + size should be
476  * less than the maxsize of @mem.
477  *
478  * #GST_MEMORY_FLAG_ZERO_PREFIXED and #GST_MEMORY_FLAG_ZERO_PADDED will be
479  * cleared when offset or padding is increased respectively.
480  */
481 void
482 gst_memory_resize (GstMemory * mem, gssize offset, gsize size)
483 {
484   g_return_if_fail (mem != NULL);
485   g_return_if_fail (offset >= 0 || mem->offset >= -offset);
486   g_return_if_fail (size + mem->offset + offset <= mem->maxsize);
487
488   /* if we increase the prefix, we can't guarantee it is still 0 filled */
489   if ((offset > 0) && GST_MEMORY_IS_ZERO_PREFIXED (mem))
490     GST_MEMORY_FLAG_UNSET (mem, GST_MEMORY_FLAG_ZERO_PREFIXED);
491
492   /* if we increase the padding, we can't guarantee it is still 0 filled */
493   if ((offset + size < mem->size) && GST_MEMORY_IS_ZERO_PADDED (mem))
494     GST_MEMORY_FLAG_UNSET (mem, GST_MEMORY_FLAG_ZERO_PADDED);
495
496   mem->offset += offset;
497   mem->size = size;
498 }
499
500 static gboolean
501 gst_memory_lock (GstMemory * mem, GstMapFlags flags)
502 {
503   gint access_mode, state, newstate;
504
505   access_mode = flags & 3;
506
507   do {
508     state = g_atomic_int_get (&mem->state);
509     if (state == 0) {
510       /* nothing mapped, set access_mode and refcount */
511       newstate = 4 | access_mode;
512     } else {
513       /* access_mode must match */
514       if ((state & access_mode) != access_mode)
515         goto lock_failed;
516       /* increase refcount */
517       newstate = state + 4;
518     }
519   } while (!g_atomic_int_compare_and_exchange (&mem->state, state, newstate));
520
521   return TRUE;
522
523 lock_failed:
524   {
525     GST_CAT_DEBUG (GST_CAT_MEMORY, "lock failed %p: state %d, access_mode %d",
526         mem, state, access_mode);
527     return FALSE;
528   }
529 }
530
531 static void
532 gst_memory_unlock (GstMemory * mem)
533 {
534   gint state, newstate;
535
536   do {
537     state = g_atomic_int_get (&mem->state);
538     /* decrease the refcount */
539     newstate = state - 4;
540     /* last refcount, unset access_mode */
541     if (newstate < 4)
542       newstate = 0;
543   } while (!g_atomic_int_compare_and_exchange (&mem->state, state, newstate));
544 }
545
546
547 /**
548  * gst_memory_make_mapped:
549  * @mem: (transfer full): a #GstMemory
550  * @info: (out): pointer for info
551  * @flags: mapping flags
552  *
553  * Create a #GstMemory object that is mapped with @flags. If @mem is mappable
554  * with @flags, this function returns the mapped @mem directly. Otherwise a
555  * mapped copy of @mem is returned.
556  *
557  * This function takes ownership of old @mem and returns a reference to a new
558  * #GstMemory.
559  *
560  * Returns: (transfer full): a #GstMemory object mapped with @flags or NULL when
561  * a mapping is not possible.
562  */
563 GstMemory *
564 gst_memory_make_mapped (GstMemory * mem, GstMapInfo * info, GstMapFlags flags)
565 {
566   GstMemory *result;
567
568   if (gst_memory_map (mem, info, flags)) {
569     result = mem;
570   } else {
571     result = gst_memory_copy (mem, 0, -1);
572     gst_memory_unref (mem);
573
574     if (result == NULL)
575       goto cannot_copy;
576
577     if (!gst_memory_map (result, info, flags))
578       goto cannot_map;
579   }
580   return result;
581
582   /* ERRORS */
583 cannot_copy:
584   {
585     GST_CAT_DEBUG (GST_CAT_MEMORY, "cannot copy memory %p", mem);
586     return NULL;
587   }
588 cannot_map:
589   {
590     GST_CAT_DEBUG (GST_CAT_MEMORY, "cannot map memory %p with flags %d", mem,
591         flags);
592     gst_memory_unref (result);
593     return NULL;
594   }
595 }
596
597 /**
598  * gst_memory_map:
599  * @mem: a #GstMemory
600  * @info: (out): pointer for info
601  * @flags: mapping flags
602  *
603  * Fill @info with the pointer and sizes of the memory in @mem that can be
604  * accessed according to @flags.
605  *
606  * This function can return %FALSE for various reasons:
607  * - the memory backed by @mem is not accessible with the given @flags.
608  * - the memory was already mapped with a different mapping.
609  *
610  * @info and its contents remain valid for as long as @mem is valid and
611  * until gst_memory_unmap() is called.
612  *
613  * For each gst_memory_map() call, a corresponding gst_memory_unmap() call
614  * should be done.
615  *
616  * Returns: %TRUE if the map operation was successful.
617  */
618 gboolean
619 gst_memory_map (GstMemory * mem, GstMapInfo * info, GstMapFlags flags)
620 {
621   g_return_val_if_fail (mem != NULL, FALSE);
622   g_return_val_if_fail (info != NULL, FALSE);
623
624   if (!gst_memory_lock (mem, flags))
625     goto lock_failed;
626
627   info->data = mem->allocator->info.mem_map (mem, mem->maxsize, flags);
628
629   if (G_UNLIKELY (info->data == NULL))
630     goto error;
631
632   info->memory = mem;
633   info->flags = flags;
634   info->size = mem->size;
635   info->maxsize = mem->maxsize - mem->offset;
636   info->data = info->data + mem->offset;
637
638   return TRUE;
639
640   /* ERRORS */
641 lock_failed:
642   {
643     GST_CAT_DEBUG (GST_CAT_MEMORY, "mem %p: lock %d failed", mem, flags);
644     return FALSE;
645   }
646 error:
647   {
648     /* something went wrong, restore the orginal state again */
649     GST_CAT_ERROR (GST_CAT_MEMORY, "mem %p: map failed", mem);
650     gst_memory_unlock (mem);
651     return FALSE;
652   }
653 }
654
655 /**
656  * gst_memory_unmap:
657  * @mem: a #GstMemory
658  * @info: a #GstMapInfo
659  *
660  * Release the memory obtained with gst_memory_map()
661  */
662 void
663 gst_memory_unmap (GstMemory * mem, GstMapInfo * info)
664 {
665   g_return_if_fail (mem != NULL);
666   g_return_if_fail (info != NULL);
667   g_return_if_fail (info->memory == mem);
668   /* there must be a ref */
669   g_return_if_fail (g_atomic_int_get (&mem->state) >= 4);
670
671   mem->allocator->info.mem_unmap (mem);
672   gst_memory_unlock (mem);
673 }
674
675 /**
676  * gst_memory_copy:
677  * @mem: a #GstMemory
678  * @offset: an offset to copy
679  * @size: size to copy or -1 to copy all bytes from offset
680  *
681  * Return a copy of @size bytes from @mem starting from @offset. This copy is
682  * guaranteed to be writable. @size can be set to -1 to return a copy all bytes
683  * from @offset.
684  *
685  * Returns: a new #GstMemory.
686  */
687 GstMemory *
688 gst_memory_copy (GstMemory * mem, gssize offset, gssize size)
689 {
690   GstMemory *copy;
691
692   g_return_val_if_fail (mem != NULL, NULL);
693
694   copy = mem->allocator->info.mem_copy (mem, offset, size);
695
696   return copy;
697 }
698
699 /**
700  * gst_memory_share:
701  * @mem: a #GstMemory
702  * @offset: an offset to share
703  * @size: size to share or -1 to share bytes from offset
704  *
705  * Return a shared copy of @size bytes from @mem starting from @offset. No
706  * memory copy is performed and the memory region is simply shared. The result
707  * is guaranteed to be not-writable. @size can be set to -1 to return a share
708  * all bytes from @offset.
709  *
710  * Returns: a new #GstMemory.
711  */
712 GstMemory *
713 gst_memory_share (GstMemory * mem, gssize offset, gssize size)
714 {
715   GstMemory *shared;
716
717   g_return_val_if_fail (mem != NULL, NULL);
718   g_return_val_if_fail (!GST_MEMORY_FLAG_IS_SET (mem, GST_MEMORY_FLAG_NO_SHARE),
719       NULL);
720
721   shared = mem->allocator->info.mem_share (mem, offset, size);
722
723   return shared;
724 }
725
726 /**
727  * gst_memory_is_span:
728  * @mem1: a #GstMemory
729  * @mem2: a #GstMemory
730  * @offset: a pointer to a result offset
731  *
732  * Check if @mem1 and mem2 share the memory with a common parent memory object
733  * and that the memory is contiguous.
734  *
735  * If this is the case, the memory of @mem1 and @mem2 can be merged
736  * efficiently by performing gst_memory_share() on the parent object from
737  * the returned @offset.
738  *
739  * Returns: %TRUE if the memory is contiguous and of a common parent.
740  */
741 gboolean
742 gst_memory_is_span (GstMemory * mem1, GstMemory * mem2, gsize * offset)
743 {
744   g_return_val_if_fail (mem1 != NULL, FALSE);
745   g_return_val_if_fail (mem2 != NULL, FALSE);
746
747   /* need to have the same allocators */
748   if (mem1->allocator != mem2->allocator)
749     return FALSE;
750
751   /* need to have the same parent */
752   if (mem1->parent == NULL || mem1->parent != mem2->parent)
753     return FALSE;
754
755   /* and memory is contiguous */
756   if (!mem1->allocator->info.mem_is_span (mem1, mem2, offset))
757     return FALSE;
758
759   return TRUE;
760 }
761
762 static void
763 _gst_allocator_free (GstAllocator * allocator)
764 {
765   if (allocator->notify)
766     allocator->notify (allocator->user_data);
767
768   g_slice_free1 (sizeof (GstAllocator), allocator);
769 }
770
771 static GstAllocator *
772 _gst_allocator_copy (GstAllocator * allocator)
773 {
774   return gst_allocator_ref (allocator);
775 }
776
777 /**
778  * gst_allocator_new:
779  * @info: a #GstMemoryInfo
780  * @user_data: user data
781  * @notify: a #GDestroyNotify for @user_data
782  *
783  * Create a new memory allocator with @info and @user_data.
784  *
785  * All functions in @info are mandatory exept the copy and is_span
786  * functions, which will have a default implementation when left NULL.
787  *
788  * The @user_data will be passed to all calls of the alloc function. @notify
789  * will be called with @user_data when the allocator is freed.
790  *
791  * Returns: a new #GstAllocator.
792  */
793 GstAllocator *
794 gst_allocator_new (const GstMemoryInfo * info, gpointer user_data,
795     GDestroyNotify notify)
796 {
797   GstAllocator *allocator;
798
799   g_return_val_if_fail (info != NULL, NULL);
800   g_return_val_if_fail (info->alloc != NULL, NULL);
801   g_return_val_if_fail (info->mem_map != NULL, NULL);
802   g_return_val_if_fail (info->mem_unmap != NULL, NULL);
803   g_return_val_if_fail (info->mem_free != NULL, NULL);
804   g_return_val_if_fail (info->mem_share != NULL, NULL);
805
806   allocator = g_slice_new0 (GstAllocator);
807
808   gst_mini_object_init (GST_MINI_OBJECT_CAST (allocator), GST_TYPE_ALLOCATOR);
809
810   allocator->mini_object.copy = (GstMiniObjectCopyFunction) _gst_allocator_copy;
811   allocator->mini_object.free = (GstMiniObjectFreeFunction) _gst_allocator_free;
812
813   allocator->info = *info;
814   allocator->user_data = user_data;
815   allocator->notify = notify;
816
817 #define INSTALL_FALLBACK(_t) \
818   if (allocator->info._t == NULL) allocator->info._t = _fallback_ ##_t;
819   INSTALL_FALLBACK (mem_copy);
820   INSTALL_FALLBACK (mem_is_span);
821 #undef INSTALL_FALLBACK
822
823   GST_CAT_DEBUG (GST_CAT_MEMORY, "new allocator %p", allocator);
824
825   return allocator;
826 }
827
828 /**
829  * gst_allocator_get_memory_type:
830  * @allocator: a #GstAllocator
831  *
832  * Get the memory type allocated by this allocator
833  *
834  * Returns: the memory type provided by @allocator
835  */
836 const gchar *
837 gst_allocator_get_memory_type (GstAllocator * allocator)
838 {
839   g_return_val_if_fail (allocator != NULL, NULL);
840
841   return allocator->info.mem_type;
842 }
843
844 /**
845  * gst_allocator_register:
846  * @name: the name of the allocator
847  * @allocator: (transfer full): #GstAllocator
848  *
849  * Registers the memory @allocator with @name. This function takes ownership of
850  * @allocator.
851  */
852 void
853 gst_allocator_register (const gchar * name, GstAllocator * allocator)
854 {
855   g_return_if_fail (name != NULL);
856   g_return_if_fail (allocator != NULL);
857
858   GST_CAT_DEBUG (GST_CAT_MEMORY, "registering allocator %p with name \"%s\"",
859       allocator, name);
860
861   g_rw_lock_writer_lock (&lock);
862   g_hash_table_insert (allocators, (gpointer) name, (gpointer) allocator);
863   g_rw_lock_writer_unlock (&lock);
864 }
865
866 /**
867  * gst_allocator_find:
868  * @name: the name of the allocator
869  *
870  * Find a previously registered allocator with @name. When @name is NULL, the
871  * default allocator will be returned.
872  *
873  * Returns: (transfer full): a #GstAllocator or NULL when the allocator with @name was not
874  * registered. Use gst_allocator_unref() to release the allocator after usage.
875  */
876 GstAllocator *
877 gst_allocator_find (const gchar * name)
878 {
879   GstAllocator *allocator;
880
881   g_rw_lock_reader_lock (&lock);
882   if (name) {
883     allocator = g_hash_table_lookup (allocators, (gconstpointer) name);
884   } else {
885     allocator = _default_allocator;
886   }
887   if (allocator)
888     gst_allocator_ref (allocator);
889   g_rw_lock_reader_unlock (&lock);
890
891   return allocator;
892 }
893
894 /**
895  * gst_allocator_set_default:
896  * @allocator: (transfer full): a #GstAllocator
897  *
898  * Set the default allocator. This function takes ownership of @allocator.
899  */
900 void
901 gst_allocator_set_default (GstAllocator * allocator)
902 {
903   GstAllocator *old;
904   g_return_if_fail (allocator != NULL);
905
906   g_rw_lock_writer_lock (&lock);
907   old = _default_allocator;
908   _default_allocator = allocator;
909   g_rw_lock_writer_unlock (&lock);
910
911   if (old)
912     gst_allocator_unref (old);
913 }
914
915 /**
916  * gst_allocation_params_init:
917  * @params: a #GstAllocationParams
918  *
919  * Initialize @params to its default values
920  */
921 void
922 gst_allocation_params_init (GstAllocationParams * params)
923 {
924   g_return_if_fail (params != NULL);
925
926   memset (params, 0, sizeof (GstAllocationParams));
927 }
928
929 /**
930  * gst_allocation_params_copy:
931  * @params: (transfer none): a #GstAllocationParams
932  *
933  * Create a copy of @params.
934  *
935  * Free-function: gst_allocation_params_free
936  *
937  * Returns: (transfer full): a new ##GstAllocationParams, free with
938  * gst_allocation_params_free().
939  */
940 GstAllocationParams *
941 gst_allocation_params_copy (const GstAllocationParams * params)
942 {
943   GstAllocationParams *result = NULL;
944
945   if (params) {
946     result =
947         (GstAllocationParams *) g_slice_copy (sizeof (GstAllocationParams),
948         params);
949   }
950   return result;
951 }
952
953 /**
954  * gst_allocation_params_free:
955  * @params: (in) (transfer full): a #GstAllocationParams
956  *
957  * Free @params
958  */
959 void
960 gst_allocation_params_free (GstAllocationParams * params)
961 {
962   g_slice_free (GstAllocationParams, params);
963 }
964
965 /**
966  * gst_allocator_alloc:
967  * @allocator: (transfer none) (allow-none): a #GstAllocator to use
968  * @size: size of the visible memory area
969  * @params: (transfer none) (allow-none): optional parameters
970  *
971  * Use @allocator to allocate a new memory block with memory that is at least
972  * @size big.
973  *
974  * The optional @params can specify the prefix and padding for the memory. If
975  * NULL is passed, no flags, no extra prefix/padding and a default alignment is
976  * used.
977  *
978  * The prefix/padding will be filled with 0 if flags contains
979  * #GST_MEMORY_FLAG_ZERO_PREFIXED and #GST_MEMORY_FLAG_ZERO_PADDED respectively.
980  *
981  * When @allocator is NULL, the default allocator will be used.
982  *
983  * The alignment in @params is given as a bitmask so that @align + 1 equals
984  * the amount of bytes to align to. For example, to align to 8 bytes,
985  * use an alignment of 7.
986  *
987  * Returns: (transfer full): a new #GstMemory.
988  */
989 GstMemory *
990 gst_allocator_alloc (GstAllocator * allocator, gsize size,
991     GstAllocationParams * params)
992 {
993   GstMemory *mem;
994   static GstAllocationParams defparams = { 0, 0, 0, 0, };
995
996   if (params) {
997     g_return_val_if_fail (((params->align + 1) & params->align) == 0, NULL);
998   } else {
999     params = &defparams;
1000   }
1001
1002   if (allocator == NULL)
1003     allocator = _default_allocator;
1004
1005   mem = allocator->info.alloc (allocator, size, params, allocator->user_data);
1006
1007   return mem;
1008 }