docs: update docs and defs

This commit is contained in:
Wim Taymans 2011-02-27 12:21:32 +01:00
parent 9a3f158c73
commit 0969106993
3 changed files with 90 additions and 84 deletions

View file

@ -34,10 +34,7 @@ Requirements
or ABI. or ABI.
- It plays nice with subbuffers. When a subbuffer is created, the various - It plays nice with subbuffers. When a subbuffer is created, the various
buffer metadata should be copied/updated correctly. buffer metadata should be copied/updated correctly.
- We should be able to pass metadata in pad_alloc() and get_range() functions - We should be able to negotiate metadata between elements
to specify extra allocation parameters.
- We should be able to attach statically allocated metadata to a buffer. This
is for metadata that does not change much.
Use cases Use cases
--------- ---------
@ -67,8 +64,10 @@ struct _GstMiniObject {
/* refcounting */ /* refcounting */
gint refcount; gint refcount;
guint flags; guint flags;
gsize size;
GstMiniObjectCopyFunction copy; GstMiniObjectCopyFunction copy;
GstMiniObjectDisposeFunction dispose;
GstMiniObjectFreeFunction free; GstMiniObjectFreeFunction free;
} }
@ -99,8 +98,6 @@ regular C structure.
struct _GstBuffer { struct _GstBuffer {
GstMiniObject mini_object; GstMiniObject mini_object;
gsize free_size;
GstCaps *caps; GstCaps *caps;
GstBuffer *parent; GstBuffer *parent;
@ -139,21 +136,21 @@ is assumed that more specialized elements can deal with the different memory
metadata structures in order to optimize access to the memory. metadata structures in order to optimize access to the memory.
GstBufferMeta GstMeta
~~~~~~~~~~~~~ ~~~~~~~
A GstBufferMeta is a structure as follows: A GstMeta is a structure as follows:
struct _GstBufferMeta { struct _GstMeta {
GstBufferMetaInfo *info; /* tag and info for the meta item */ GstMetaInfo *info; /* tag and info for the meta item */
}; };
The purpose of the this structure is to serve as a common header for all metadata The purpose of the this structure is to serve as a common header for all metadata
information that we can attach to a buffer. Specific metadata, such as timing metadata, information that we can attach to a buffer. Specific metadata, such as timing metadata,
will have this structure as the first field. For example: will have this structure as the first field. For example:
struct _GstBufferMetaTiming { struct _GstMetaTiming {
GstBufferMeta meta; /* common meta header */ GstMeta meta; /* common meta header */
GstClockTime dts; /* decoding timestamp */ GstClockTime dts; /* decoding timestamp */
GstClockTime pts; /* presentation timestamp */ GstClockTime pts; /* presentation timestamp */
@ -161,12 +158,30 @@ will have this structure as the first field. For example:
GstClockTime clock_rate; /* clock rate for the above values */ GstClockTime clock_rate; /* clock rate for the above values */
}; };
Or another example for the buffer memory region Or another example for the buffer memory region that consists of some methods
only.
struct _GstBufferMetaMemory { struct _GstMetaMemory {
GstBufferMeta meta; GstMeta meta;
GstMetaMemoryMap mmap_func;
GstMetaMemoryUnmap munmap_func;
};
gpointer gst_meta_memory_map (GstMetaMemory *, guint offset, guint *size, GstBufferMapFlags);
gboolean gst_meta_memory_unmap (GstMetaMemory *, gpointer data, guint size);
GstMeta derived structures define the API of the metadata. The API can consist of
fields and/or methods. It is possible to have different implementations for the
same GstMeta structure.
The implementation of the GstMeta api would typically add more fields to the
public structure that allow it to implement the API. For example:
struct _GstMetaMemoryImpl {
GstMetaMemory memory;
/* pointer to data and its size */
gpointer *data; gpointer *data;
guint size; guint size;
gpointer *data_orig; gpointer *data_orig;
@ -174,13 +189,13 @@ Or another example for the buffer memory region
gpointer data_user; gpointer data_user;
}; };
GstBufferMetaInfo will point to more information about the metadata and looks like this:
struct _GstBufferMetaInfo { GstMetaInfo will point to more information about the metadata and looks like this:
struct _GstMetaInfo {
GQuark api; /* api name */ GQuark api; /* api name */
GQuark impl; /* implementation name */ GQuark impl; /* implementation name */
gsize size; /* size of the structure */ gsize size; /* size of the structure */
GstBufferMetaInfo *parent /* parent info */
GstMetaInitFunction init_func; GstMetaInitFunction init_func;
GstMetaFreeFunction free_func; GstMetaFreeFunction free_func;
@ -191,14 +206,17 @@ GstBufferMetaInfo will point to more information about the metadata and looks li
GstMetaConvFunction conv_func; GstMetaConvFunction conv_func;
}; };
Tag will contain a GQuark of the metadata name. We will be able to refer to specific api will contain a GQuark of the metadata api. A repository of registered MetaInfo
metadata by name or by its (cached) GQuark. A repository of registered MetaInfo
will be maintained by the core. We will register some common metadata structures will be maintained by the core. We will register some common metadata structures
in core and some media specific info for audio/video/text in -base. Plugins can in core and some media specific info for audio/video/text in -base. Plugins can
register additional custom metadata. register additional custom metadata.
For each implementation of api, there will thus be a unique GstMetaInfo. In the
case of metadata with a well defined API, the implementation specific init
function will setup the methods in the metadata structure.
Along with the metadata description we will have functions to initialize/free (and/or refcount) Along with the metadata description we will have functions to initialize/free (and/or refcount)
a specific GstBufferMeta instance. We also have the possibility to add a custom subbuffer a specific GstMeta instance. We also have the possibility to add a custom subbuffer
function that can be used to modify the metadata when a subbuffer is taken. function that can be used to modify the metadata when a subbuffer is taken.
We also add serialize and deserialize function for the metadata in case we need special We also add serialize and deserialize function for the metadata in case we need special
@ -220,25 +238,26 @@ The complete buffer with metadata would then look as follows:
+-------------------------------------+ +-------------------------------------+
GstMiniObject | GType (GstBuffer) | GstMiniObject | GType (GstBuffer) |
| refcount, flags, copy/free | | refcount, flags, copy/disp/free |
+-------------------------------------+ +-------------------------------------+
GstBuffer | caps, parent, subfunc | GstBuffer | caps, parent |
+.....................................+ +.....................................+
| next ---+ | next ---+
| parent ------> NULL +- | info ------> GstMetaInfo
+- | info ------> GstBufferMetaInfo GstMetaTiming | | | |
GstBufferMetaTiming | | | |
| | dts | | | | dts | |
| | pts | | | | pts | |
| | duration | | | | duration | |
+- | clock_rate | | +- | clock_rate | |
+ . . . . . . . . . . . . . . . . . . + | + . . . . . . . . . . . . . . . . . . + |
| next <--+ | next <--+
| parent ------> NULL GstMetaMemory +- +- | info ------> GstMetaInfo
GstBufferMetaMemory +- | info ------> GstBufferMetaInfo | | | | |
| | | | | | | mmap | |
| | | munmap | |
+- | | | |
| | data | | | | data | |
| | size | | GstMetaMemoryImpl | | size | |
| | mallocdata | | | | mallocdata | |
| | data_free | | | | data_free | |
+- | data_user | | +- | data_user | |
@ -251,65 +270,62 @@ API examples
Buffers are created using the normal gst_buffer_new functions. The standard fields Buffers are created using the normal gst_buffer_new functions. The standard fields
are initialized as usual. A memory area that is bigger than the structure size are initialized as usual. A memory area that is bigger than the structure size
is allocated for the buffer metadata. The remaining free area is stored in the is allocated for the buffer metadata.
free_size field.
gst_buffer_new (); gst_buffer_new ();
After creating a buffer, the application can set caps. and add other metadata After creating a buffer, the application can set caps and add metadata
information. information.
In order to modify metadata, a reference to the MetaInfo should be obtained. To add or retrieve metadata, a handle to a GstMetaInfo structure needs to be
This can be done like this: obtained. This defines the implementation and API of the metadata. Usually, a
handle to this info structure can be obtained by callnig a public _get_info()
method from a shared library (for shared metadata).
GstBufferMetaInfo *info; The following defines can usually be found in the shared .h file.
info = gst_buffer_meta_get_info (GQuark tag); GstMetaInfo * gst_meta_timing_get_info();
#define GST_META_TIMING_INFO (gst_meta_timing_get_info())
Usually the info will be obtained only once in order to avoid lock contention on Retrieving and/or creating the metadata on a buffer can be done with the
the global pool of meta info. The core will also provide convenience functions gst_buffer_meta_get() method. This function retrieves an existing metadata
for the core metainfo. conforming to the API spcified in the given info. When no such metadata exists
and the last gboolean argument is true, a new metadata item will be created from
the info and added to the buffer.
GstMetaTiming *timing;
timing = gst_buffer_get_meta (buffer, GST_META_TIMING_INFO, TRUE);
Once a reference to the info has been obtained, the associated metadata can be Once a reference to the info has been obtained, the associated metadata can be
added or modified on a buffer. added or modified on a buffer.
For example, to modify the timing info on a buffer, one could use the following
sequence:
GstBufferMetaInfo *info;
GstBufferMetaTiming *timing;
info = gst_buffer_meta_get_info (GST_META_TIMING_QUARK);
timing = gst_buffer_get_meta (buffer, info, TRUE); /* TRUE = create if absent */
timing->timestamp = 0; timing->timestamp = 0;
timing->duration = 20 * GST_MSECOND; timing->duration = 20 * GST_MSECOND;
The _get_meta() function returns a pointer to the metadata structure associated Other convenience macros can be made to simplify the above code:
with the GST_META_TIMING_QUARK info.
For the core meta info, we will provide convenience code that uses the cached #define gst_buffer_get_meta_timing(b,c) \
GstBufferMetaInfo, making the above code a little more simple. ((GstMetaTiming *) gst_buffer_get_meta ((b), GST_META_TIMING_INFO, (c))
GstBufferMetaTiming *timing; This makes the code look like this:
GstMetaTiming *timing;
timing = gst_buffer_get_meta_timing (buffer, TRUE); /* TRUE = create if absent */ timing = gst_buffer_get_meta_timing (buffer, TRUE); /* TRUE = create if absent */
timing->timestamp = 0; timing->timestamp = 0;
timing->duration = 20 * GST_MSECOND; timing->duration = 20 * GST_MSECOND;
Note that for each of the metadata that we will add to buffers, we need a struct
definition and a registered MetaInfo.
We will also provide an API to iterate the different metainfo structures. A We will also provide an API to iterate the different metainfo structures. A
possible simple API would look like this: possible simple API would look like this:
GstBufferMeta *current = NULL; GstMeta *current = NULL;
/* passing NULL gives the first entry */ /* passing NULL gives the first entry */
current = gst_buffer_meta_get_next (buffer, current); current = gst_buffer_meta_get_next (buffer, current);
/* passing a GstBufferMeta returns the next */ /* passing a GstMeta returns the next */
current = gst_buffer_meta_get_next (buffer, current); current = gst_buffer_meta_get_next (buffer, current);
@ -320,8 +336,7 @@ Memory management
* allocation * allocation
We will initially allocate a reasonable sized GstBuffer structure (say 512 We will initially allocate a reasonable sized GstBuffer structure (say 512
bytes) and we will set the free_size to the maximum amount of metadata we can bytes).
store.
Since the complete buffer structure, including a large area for metadata, is Since the complete buffer structure, including a large area for metadata, is
allocated in one go, we can reduce the number of memory allocations while still allocated in one go, we can reduce the number of memory allocations while still
@ -339,7 +354,7 @@ Memory management
structure. This can be useful when a structure is shared between buffers. structure. This can be useful when a structure is shared between buffers.
When the free_size of the GstBuffer is exhausted, we will allocate new memory When the free_size of the GstBuffer is exhausted, we will allocate new memory
for each newly added BufferMeta and use the next pointers to point to this. It for each newly added Meta and use the next pointers to point to this. It
is expected that this does not occur often and we might be able to optimize is expected that this does not occur often and we might be able to optimize
this transparently in the future. this transparently in the future.
@ -409,14 +424,14 @@ so on).
Other use cases Other use cases
~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~
Making the GstBufferMetaMemory (for making the buffer point to the associated Making the GstMetaMemory (for making the buffer point to the associated
memory region) as metadata on a GstBuffer, as opposed to making it an integral memory region) as metadata on a GstBuffer, as opposed to making it an integral
part of GstBuffer, allows for some more interesting ways to transfer data. part of GstBuffer, allows for some more interesting ways to transfer data.
We could for example make a new GstBufferMetaIOVec metadata structure like this: We could for example make a new GstMetaIOVec metadata structure like this:
struct _GstBufferMetaIOVec { struct _GstMetaIOVec {
GstBufferMeta meta; GstMeta meta;
/* pointer to data and its size */ /* pointer to data and its size */
GFreeFunc data_free; GFreeFunc data_free;
@ -460,19 +475,11 @@ We need to make sure that elements exchange metadata that they both understand,
This is particulary important when the metadata describes the data layout in This is particulary important when the metadata describes the data layout in
memory (such as strides). memory (such as strides).
Currently the only way to communicate buffer formats between elements is by We would like to use the bufferpool negotiation system to negotiate the possible
using caps. We would like to use the caps system to negotiate the metadata that metadata that can be exchanged between elements.
will be put on buffers.
We would like to add to the caps on the buffer (and pad) an array of metadata When deciding the allocation properties, we will also negotiate the buffer
structures (as strings) that is on the buffer. This way, an element can metadata structures that we can exchange.
quickly know what metadata to look for.
In order to remain compatibility with older plugins we need to convert buffers
that use metadata to specify a non-standard data layout to the old format. We
need to do this before handing buffers to old elements. We will require elements
that are metadata aware to set a flag on their pads; any buffer passed on that
pad will be converted to the old layout when the flag is not set.
Notes Notes
@ -508,7 +515,7 @@ Video Buffers
}; };
struct GstBufferVideoMeta { struct GstBufferVideoMeta {
GstBufferMeta meta GstMeta meta
GstBufferVideoFlags flags GstBufferVideoFlags flags

View file

@ -153,8 +153,8 @@ typedef enum
* Base class for refcounted lightweight objects. * Base class for refcounted lightweight objects.
* Ref Func: gst_mini_object_ref * Ref Func: gst_mini_object_ref
* Unref Func: gst_mini_object_unref * Unref Func: gst_mini_object_unref
* Set Value Func: gst_value_set_mini_object * Set Value Func: g_value_set_boxed
* Get Value Func: gst_value_get_mini_object * Get Value Func: g_value_get_boxed
*/ */
struct _GstMiniObject { struct _GstMiniObject {
GType type; GType type;

View file

@ -95,7 +95,6 @@ EXPORTS
gst_buffer_flag_get_type gst_buffer_flag_get_type
gst_buffer_get_caps gst_buffer_get_caps
gst_buffer_get_meta gst_buffer_get_meta
gst_buffer_get_meta_by_api
gst_buffer_is_metadata_writable gst_buffer_is_metadata_writable
gst_buffer_is_span_fast gst_buffer_is_span_fast
gst_buffer_iterate_meta gst_buffer_iterate_meta