mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-07 07:58:51 +00:00
docs: update docs and defs
This commit is contained in:
parent
9a3f158c73
commit
0969106993
3 changed files with 90 additions and 84 deletions
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue