| GstMemory |
| --------- |
| |
| This document describes the design of the memory objects. |
| |
| GstMemory objects are usually added to GstBuffer objects and contain the |
| multimedia data passed around in the pipeline. |
| |
| Requirements |
| ~~~~~~~~~~~~ |
| |
| - It must be possible to have different memory allocators |
| - It must be possible to efficiently share memory objects, copy, span |
| and trim. |
| |
| |
| Memory layout |
| ~~~~~~~~~~~~~ |
| |
| GstMemory manages a memory region. The accessible part of the managed region is |
| defined by an offset relative to the start of the region and a size. This |
| means that the managed region can be larger than what is visible to the user of |
| GstMemory API. |
| |
| Schematically, GstMemory has a pointer to a memory region of _maxsize_. The area |
| starting from _offset_ and _size_ is accessible. |
| |
| memory |
| GstMemory ->*----------------------------------------------------* |
| ^----------------------------------------------------^ |
| maxsize |
| ^--------------------------------------^ |
| offset size |
| |
| The current properties of the accessible memory can be retrieved with: |
| |
| gsize gst_memory_get_sizes (GstMemory *mem, gsize *offset, gsize *maxsize); |
| |
| The offset and size can be changed with: |
| |
| void gst_memory_resize (GstMemory *mem, gssize offset, gsize size); |
| |
| |
| Allocators |
| ~~~~~~~~~~ |
| |
| GstMemory objects are created by allocators. Allocators are a subclass |
| of GstObject and can be subclassed to make custom allocators. |
| |
| struct _GstAllocator { |
| GstObject object; |
| |
| const gchar *mem_type; |
| |
| GstMemoryMapFunction mem_map; |
| GstMemoryUnmapFunction mem_unmap; |
| |
| GstMemoryCopyFunction mem_copy; |
| GstMemoryShareFunction mem_share; |
| GstMemoryIsSpanFunction mem_is_span; |
| }; |
| |
| The allocator class has 2 virtual methods. One to create a GstMemory, |
| another to free it again. |
| |
| struct _GstAllocatorClass { |
| GstObjectClass object_class; |
| |
| GstMemory * (*alloc) (GstAllocator *allocator, gsize size, |
| GstAllocationParams *params); |
| void (*free) (GstAllocator *allocator, GstMemory *memory); |
| }; |
| |
| |
| Allocators are refcounted. It is also possible to register the allocator to the |
| GStreamer system. This way, the allocator can be retrieved by name. |
| |
| After an allocator is created, new GstMemory can be created with |
| |
| GstMemory * gst_allocator_alloc (const GstAllocator * allocator, |
| gsize size, |
| GstAllocationParams *params); |
| |
| GstAllocationParams contain extra info such as flags, alignment, prefix and |
| padding. |
| |
| The GstMemory object is a refcounted object that must be freed with |
| gst_memory_unref (). |
| |
| The GstMemory keeps a ref to the allocator that allocated it. Inside the |
| allocator are the most common GstMemory operations listed. Custom |
| GstAllocator implementations must implement the various operations on |
| the memory they allocate. |
| |
| It is also possible to create a new GstMemory object that wraps existing |
| memory with: |
| |
| GstMemory * gst_memory_new_wrapped (GstMemoryFlags flags, |
| gpointer data, gsize maxsize, |
| gsize offset, gsize size, |
| gpointer user_data, |
| GDestroyNotify notify); |
| |
| Lifecycle |
| ~~~~~~~~~ |
| |
| GstMemory extends from GstMiniObject and therefore uses its lifecycle |
| management (See part-miniobject.txt). |
| |
| |
| |
| Data Access |
| ~~~~~~~~~~~ |
| |
| Access to the memory region is always controlled with a map and unmap method |
| call. This allows the implementation to monitor the access patterns or set up |
| the required memory mappings when needed. |
| |
| The access of the memory object is controlled with the locking mechanism on |
| GstMiniObject (See part-miniobject.txt). |
| |
| Mapping a memory region requires the caller to specify the access method: READ |
| and/or WRITE. Mapping a memory region will first try to get a lock on the |
| memory in the requested access mode. This means that the map operation can |
| fail when WRITE access is requested on a non-writable memory object (it has |
| an exclusive counter > 1, the memory is already locked in an incompatible |
| access mode or the memory is marked readonly). |
| |
| After the data has been accessed in the object, the unmap call must be |
| performed, which will unlock the memory again. |
| |
| It is allowed to recursively map multiple times with the same or narrower |
| access modes. For each of the map calls, a corresponding unmap call needs to |
| be made. WRITE-only memory cannot be mapped in READ mode and READ-only memory |
| cannot be mapped in WRITE mode. |
| |
| The memory pointer returned from the map call is guaranteed to remain valid in |
| the requested mapping mode until the corresponding unmap call is performed on |
| the pointer. |
| |
| When multiple map operations are nested and return the same pointer, the pointer |
| is valid until the last unmap call is done. |
| |
| When the final reference on a memory object is dropped, all outstanding |
| mappings should have been unmapped. |
| |
| Resizing a GstMemory does not influence any current mappings in any way. |
| |
| Copy |
| ~~~~ |
| |
| A GstMemory copy can be made with the gst_memory_copy() call. Normally, |
| allocators will implement a custom version of this function to make a copy of |
| the same kind of memory as the original one. |
| |
| This is what the fallback version of the copy function does, albeit slower |
| than what a custom implementation could do. |
| |
| The copy operation is only required to copy the visible range of the memory |
| block. |
| |
| |
| Share |
| ~~~~~ |
| |
| A memory region can be shared between GstMemory object with the |
| gst_memory_share() operation. |
| |
| |