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 accesible 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 recusively map multiple times with the same or narrower
 access modes. for each of the map calls, an 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 an 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 will do, albeit slower
 than what as 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. 


