From 964ea9eccb66f4bee4d79f980859f00288931220 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 5 Jul 2012 12:53:57 +0200 Subject: [PATCH] docs: update docs --- docs/design/part-buffer.txt | 10 +- docs/design/part-memory.txt | 139 ++++++++------------------ docs/design/part-miniobject.txt | 209 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 258 insertions(+), 100 deletions(-) create mode 100644 docs/design/part-miniobject.txt diff --git a/docs/design/part-buffer.txt b/docs/design/part-buffer.txt index 92582de..2565ab7 100644 --- a/docs/design/part-buffer.txt +++ b/docs/design/part-buffer.txt @@ -15,10 +15,16 @@ Requirements - Must be able to attach artibtrary metadata to buffers - efficient handling of subbuffer, copy, span, trim +Lifecycle +~~~~~~~~~ + +GstMemory extends from GstMiniObject and therefore uses its lifecycle +management (See part-miniobject.txt). + Writability ------------ +~~~~~~~~~~~ -The Buffers is writable when the refcount is 1. This means that: +When a Buffers is writable as returned from gst_buffer_is_writable(): - metadata can be added/removed and the metadata can be changed - GstMemory blocks can be added/removed diff --git a/docs/design/part-memory.txt b/docs/design/part-memory.txt index fc507b4..ea44cf9 100644 --- a/docs/design/part-memory.txt +++ b/docs/design/part-memory.txt @@ -14,6 +14,33 @@ Requirements 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 ~~~~~~~~~~ @@ -40,7 +67,11 @@ Allocators After an allocator is created, new GstMemory can be created with GstMemory * gst_allocator_alloc (const GstAllocator * allocator, - gsize maxsize, gsize align); + 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 (). @@ -57,100 +88,9 @@ Allocators Lifecycle ~~~~~~~~~ -GstMemory objects are refcounted. When the GstMemory object is first created, it -has a refcount of 1. - -Each variable holding a reference to the GstMemory object is responsible for -updating the refcount. - -When the refcount reaches 0, and thus no objects hold a reference anymore, we -can free the memory. The GstMemoryFreeFunction of the allocator will be called -to cleanup the memory. - - -Access management ------------------ - -GstMemory objects can be shared between multiple GstBuffer objects. It is -important that when a thread writes to the shared GstMemory that the other -buffers don't not see the changes. - -We need 2 concepts: - - - count how many objects are sharing this GstMemory (exclusive counter) - - control the READ/WRITE access to the GstMemory (locking) - -* exclusive counter - - Each object that wants to keep a reference to the GstMemory and doesn't want to - see the changes from other owners of the same GstMemory needs to lock the - GstMemory in EXCLUSIVE mode, which will increase the exclusive counter. +GstMemory extends from GstMiniObject and therefore uses its lifecycle +management (See part-miniobject.txt). - The exclusive counter counts the amount of objects that share this GstMemory - object. The counter is initially 0, meaning that the object is not shared with - any object. When a GstBuffer (or other object) receives a ref to a GstMemory, - it will lock in EXCLUSIVE mode. - - When the GstMemory is removed from the buffer, both the ref count and the - exclusive counter will be decreased with gst_object_unref() and - gst_memory_unlock () respectively. - -* locking - - All read and write access must be performed between a gst_memory_lock() and - gst_memory_unlock() pair with the requested access method. - - A gst_memory_lock() can fail when a WRITE lock is requested and the exclusive - counter is > 1. Indeed a GstMemory object with an exclusive counter > 1 is - locked EXCLUSIVELY by at least 2 objects and is therefore not writable. - - Once the memory is locked with a certain access mode, it can be recursively - locked with the same or narrower access mode. For example, first locking the - memory in READWRITE mode allows you to recusively lock the memory in - READWRITE, READ and WRITE mode. Memory locked in READ mode cannot be locked - recursively in WRITE or READWRITE mode. - - Note that multiple threads can READ lock the memory concurrently but cannot - lock the memory in WRITE mode because the exclusive counter must be > 1. - - All calls to gst_memory_lock() need to be paired with one gst_memory_unlock() - call with the same access mode. When the last refcount of the memory is - removed, the should be no more outstanding locks. - -Note that a shared counter of both 0 and 1 leaves the memory writable. The -reason is to make it easy to create and pass ownership of the memory to -another object while keeping it the memory writable. When the memory is -created with a shared count of 0, it is writable. When the memory is then -added to another object, the shared count is incremented to 1 and the memory -remains writable. The 0 share counter has a similar purpose as the floating -reference in GObject. - - -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); Data Access @@ -160,6 +100,9 @@ Data Access 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 @@ -170,10 +113,10 @@ Data Access 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 map multiple times with different 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. + 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 diff --git a/docs/design/part-miniobject.txt b/docs/design/part-miniobject.txt new file mode 100644 index 0000000..8c04780 --- /dev/null +++ b/docs/design/part-miniobject.txt @@ -0,0 +1,209 @@ +GstMiniObject +------------- + +This document describes the design of the miniobject base class. + +The miniobject abstract base class is used to construct lightweight refcounted +and boxed types that are frequently created and destroyed. + +Requirements +~~~~~~~~~~~~ + + - Be lightweight + - Refcounted + - I must be possible to control access to the object, ie. when the object is + readable and writable. + - Subclasses must be able to use their own allocator for the memory. + + +Usage +~~~~~ + +Users of the GstMiniObject infrastructure will need to define a structure that +includes the GstMiniObject structure as the first field. + + struct { + GstMiniObject mini_object; + + /* my fields */ + ... + } MyObject + +The subclass should then implement a constructor method where it allocates the +memory for its structure and initializes the miniobject structure with +gst_mini_object_init(). Copy and Free functions are provided to the +gst_mini_object_init() function. + + MyObject * + my_object_new() + { + MyObject *res = g_slice_new (MyObject); + + gst_mini_object_init (GST_MINI_OBJECT_CAST (res), 0, + MY_TYPE_OBJECT, + (GstMiniObjectCopyFunction) _my_object_copy, + (GstMiniObjectDisposeFunction) NULL, + (GstMiniObjectFreeFunction) _my_object_free); + + /* other init */ + ..... + + return res; + } + +The Free function is responsible for freeing the allocated memory for +the structure. + + static void + _my_object_free (MyObject *obj) + { + /* other cleanup */ + ... + + g_slice_free (MyObject, obj); + } + + +Lifecycle +~~~~~~~~~ + +GstMiniObject is refcounted. When a GstMiniObject is first created, +it has a refcount of 1. + +Each variable holding a reference to a GstMiniObject is responsible for +updating the refcount. This includes incrementing the refcount with +gst_mini_object_ref() when a reference is kept to a miniobject or +gst_mini_object_unref() when a reference is released. + +When the refcount reaches 0, and thus no objects hold a reference to the +miniobject anymore, we can free the miniobject. + +When freeing the miniobject, first the GstMiniObjectDisposeFunction is called. +This function is allowed to revive the object again by incrementing the +refcount, in which case it should return FALSE from the dispose function. The +dispose function is used by GstBuffer to revive the buffer back into the +GstBufferPool when needed. + +When the dispose function returns TRUE, the GstMiniObjectFreeFunction will be +called and the miniobject will be freed. + + +Copy +~~~~ + +A miniobject can be copied with gst_mini_object_copy(). This function will +call the custom copy function that was provided when registering the new +GstMiniObject subclass. + +The copy function should try to preserve as much info from the original object +as possible. + +The new copy should be writable. + + +Access management +~~~~~~~~~~~~~~~~~ + +GstMiniObject can be shared between multiple threads. It is important that when +a thread writes to a GstMiniObject that the other threads don't not see the +changes. + +To avoid exposing changes from one thread to another thread, the miniobjects +are managed in a Copy-On-Write way. A copy is only made when it is known that +the object is shared between multiple objects or threads. + +There are 2 methods implemented for controlling access to the miniobject. + + - A first method relies on the refcount of the object to control writability. + Objects using this method have the LOCKABLE flag unset. + + - A second method relies on a separate counter for controlling + the access to the object. Objects using this method have the LOCKABLE flag + set. + + You can check if an object is writable with gst_mini_object_is_writable() and + you can make any miniobject writable with gst_mini_object_make_writable(). + This will create a writable copy when the object was not writable. + + + non-LOCKABLE GstMiniObjects + --------------------------- + + These GstMiniObjects have the LOCKABLE flag unset. They use the refcount value + to control writability of the object. + + When the refcount of the miniobject is > 1, the objects it referenced by at + least 2 objects and is thus considered unwritable. A copy must be made before a + modification to the object can be done. + + Using the refcount to control writability is problematic for many language + bindings that can keep additional references to the objects. This method is + mainly for historical reasons until all users of the miniobjects are + converted to use the LOCAKBLE flag. + + + LOCKABLE GstMiniObjects + ----------------------- + + These GstMiniObjects have the LOCKABLE flag set. They use a separate counter + for controlling writability and access to the object. + + It consists of 2 components: + + * exclusive counter + + Each object that wants to keep a reference to a GstMiniObject and doesn't want to + see the changes from other owners of the same GstMiniObject needs to lock the + GstMiniObject in EXCLUSIVE mode, which will increase the exclusive counter. + + The exclusive counter counts the amount of objects that share this + GstMiniObject. The counter is initially 0, meaning that the object is not shared with + any object. + + When a reference to a GstMiniObject release, both the ref count and the + exclusive counter will be decreased with gst_mini_object_unref() and + gst_mini_object_unlock () respectively. + + * locking + + All read and write access must be performed between a gst_mini_object_lock() and + gst_mini_object_unlock() pair with the requested access method. + + A gst_mini_object_lock() can fail when a WRITE lock is requested and the exclusive + counter is > 1. Indeed a GstMiniObject object with an exclusive counter > 1 is + locked EXCLUSIVELY by at least 2 objects and is therefore not writable. + + Once the GstMiniObject is locked with a certain access mode, it can be recursively + locked with the same or narrower access mode. For example, first locking the + GstMiniObject in READWRITE mode allows you to recusively lock the + GstMiniObject in + READWRITE, READ and WRITE mode. Memory locked in READ mode cannot be locked + recursively in WRITE or READWRITE mode. + + Note that multiple threads can READ lock the GstMiniObject concurrently but cannot + lock the object in WRITE mode because the exclusive counter must be > 1. + + All calls to gst_mini_object_lock() need to be paired with one + gst_mini_object_unlock() call with the same access mode. When the last refcount + of the object is removed, there should be no more outstanding locks. + + Note that a shared counter of both 0 and 1 leaves the GstMiniObject writable. The + reason is to make it easy to create and pass ownership of the GstMiniObject to + another object while keeping it writable. When the GstMiniObject is + created with a shared count of 0, it is writable. When the GstMiniObject is then + added to another object, the shared count is incremented to 1 and the + GstMiniObject remains writable. The 0 share counter has a similar purpose as the floating + reference in GObject. + + +Weak references +~~~~~~~~~~~~~~~ + +GstMiniObject has support for weak references. A callback will be called when +the object is freed for all registered weak references. + + +QData +~~~~~ + +Extra data can be associated with a GstMiniObject by using the QData API. -- 2.7.4