4 This draft document describes a possible design for arbitrary per-buffer
7 The proposed changes in this document are not ABI/API compatible with the 0.10
8 version of GStreamer and should thus only be considered for upcomming unstable
11 Buffer metadata typically includes properties that give more information about
12 the buffer contents. These properties are usually not negotiated and are thus
15 Some examples of metadata:
19 - interlacing information
20 - video alignment, cropping, panning information
21 - extra container information such as granulepos, ...
22 - extra global buffer properties
29 * allocation, free, low fragmentation
30 * access to the metadata fields, preferably not much slower than directly
31 accessing a C structure field
32 - It must be extensible. Elements should be able to add new arbitrary metadata
33 without requiring much effort. Also new metadata fields should not break API
35 - It plays nice with subbuffers. When a subbuffer is created, the various
36 buffer metadata should be copied/updated correctly.
37 - We should be able to pass metadata in pad_alloc() and get_range() functions
38 to specify extra allocation parameters.
39 - We should be able to attach statically allocated metadata to a buffer. This
40 is for metadata that does not change much.
46 We make GstMiniObject a simple refcounted C structure and also a GLib boxed
47 type. The following fields will be in the structure:
49 struct _GstMiniObject {
52 /*< public >*/ /* with COW */
57 GstMiniObjectCopyFunction copy;
58 GstMiniObjectFreeFunction free;
61 We will use the regular GSlice allocator or custom object pooling for allocating
62 instances of the mini object.
64 We use the well known refcounting mechanisms to manage the lifetime of the
68 GstEvent, GstCaps, GstQuery, GstMessage
69 ---------------------------------------
71 Have the new GstMiniObject be the first field in these objects. They will probably
72 also replace the copy and free functions with their own implementations.
74 Allocation of the objects will use the regular gst_*_new() functions that will
75 allocate and initialize a parent GstMiniObject of the required size and setting up
82 A GstMiniObject will be the parent instance of the GstBuffer object, which is a
86 GstMiniObject mini_object;
93 gpointer _gst_padding[10];
96 The Buffer object will contain a pointer to the parent buffer to allow for subbuffers
97 as a first class feature of a GstBuffer.
99 Allocation of the GstBuffer structure will result in the allocation of a memory region
100 of a customizable size (512 bytes). Only the first sizeof (GstBuffer) bytes of this
101 region will initially be used. The remaining bytes will be part of the free metadata
102 region of the buffer. The size of the free region is kept in the free_size field.
104 Buffers point to a GstCaps structure that contains the caps of the buffer data.
110 A GstBufferMeta is a structure as follows:
112 struct _GstBufferMeta {
113 GstBufferMetaInfo *info; /* tag and info for the meta item */
114 GstBufferMeta *next; /* pointer to the next item */
117 The purpose of the this structure is to serve as a common header for all metadata
118 information that we can attach to a buffer. Specific metadata, such as timing metadata,
119 will have this structure as the first field. For example:
121 struct _GstBufferMetaTiming {
122 GstBufferMeta meta; /* common meta header */
124 GstClockTime dts; /* decoding timestamp */
125 GstClockTime pts; /* presentation timestamp */
126 GstClockTime duration; /* duration of the data */
127 GstClockTime clock_rate; /* clock rate for the above values */
130 Or another example for the buffer memory region
132 struct _GstBufferMetaMemory {
135 /* pointer to data and its size */
143 GstBufferMetaInfo will point to more information about the metadata and looks like this:
145 struct _GstBufferMetaInfo {
146 GQuark tag; /* tag name */
147 gsize size; /* size of the structure */
149 GstMetaInitFunction init_func;
150 GstMetaFreeFunction free_func;
151 GstMetaSubFunction sub_func;
152 GstMetaSerializeFunction serialize_func
153 GstMetaDeserializeFunction deserialize_func
156 Tag will contain a GQuark of the metadata name. We will be able to refer to specific
157 metadata by name or by its (cached) GQuark. A repository of registered MetaInfo
158 will be maintained by the core. We will register some common metadata structures
159 in core and some media specific info for audio/video/text in -base. Plugins can
160 register additional custom metadata.
162 Along with the metadata description we will have functions to initialize/free (and/or refcount)
163 a specific GstBufferMeta instance. We also have the possibility to add a custom subbuffer
164 function that can be used to modify the metadata when a subbuffer is taken.
166 We also add serialize and deserialize function for the metadata in case we need special
167 logic for reading and writing the metadata. This is needed for GDP payloading of the
170 The purpose of the separate MetaInfo is to not have to carry the free/init functions in
171 each buffer instance but to define them globally. We still want quick access to the info
172 so we need to make the buffer metadata point to the info.
174 Technically we could also specify the field and types in the MetaInfo and
175 provide a generic API to retrieve the metadata fields without the need for a
176 header file. We will not do this yet.
178 The complete buffer with metadata would then look as follows:
180 +-------------------------------------+
181 GstMiniObject | GType (GstBuffer) |
182 | refcount, flags, copy/free |
183 +-------------------------------------+
184 GstBuffer | caps, parent, subfunc |
185 +.....................................+
186 +- | info ------> GstBufferMetaInfo
187 GstBufferMetaTiming | | next ---+
193 + . . . . . . . . . . . . . . . . . . + |
194 +- | info <--+ -> GstBufferMetaInfo
195 GstBufferMetaMemory | | next ---+
202 + . . . . . . . . . . . . . . . . . . + .
208 Buffers are created using the normal gst_buffer_new functions. The standard fields
209 are initialized as usual. A memory area that is bigger than the structure size
210 is allocated for the buffer metadata. The remaining free area is stored in the
215 After creating a buffer, the application can set caps. and add other metadata
218 In order to modify metadata, a reference to the MetaInfo should be obtained.
219 This can be done like this:
221 GstBufferMetaInfo *info;
223 info = gst_buffer_meta_get_info (GQuark tag);
225 Usually the info will be obtained only once in order to avoid lock contention on
226 the global pool of meta info. The core will also provide convenience functions
227 for the core metainfo.
229 Once a reference to the info has been obtained, the associated metadata can be
230 added or modified on a buffer.
232 For example, to modify the timing info on a buffer, one could use the following
235 GstBufferMetaInfo *info;
236 GstBufferMetaTiming *timing;
238 info = gst_buffer_meta_get_info (GST_META_TIMING_QUARK);
240 timing = gst_buffer_get_meta (buffer, info, TRUE); /* TRUE = create if absent */
241 timing->timestamp = 0;
242 timing->duration = 20 * GST_MSECOND;
244 The _get_meta() function returns a pointer to the metadata structure associated
245 with the GST_META_TIMING_QUARK info.
247 For the core meta info, we will provide convenience code that uses the cached
248 GstBufferMetaInfo, making the above code a little more simple.
250 GstBufferMetaTiming *timing;
252 timing = gst_buffer_get_meta_timing (buffer, TRUE); /* TRUE = create if absent */
253 timing->timestamp = 0;
254 timing->duration = 20 * GST_MSECOND;
256 Note that for each of the metadata that we will add to buffers, we need a struct
257 definition and a registered MetaInfo.
260 We will also provide an API to iterate the different metainfo structures. A
261 possible simple API would look like this:
263 GstBufferMeta *current = NULL;
265 /* passing NULL gives the first entry */
266 current = gst_buffer_meta_get_next (buffer, current);
268 /* passing a GstBufferMeta returns the next */
269 current = gst_buffer_meta_get_next (buffer, current);
278 We will initially allocate a reasonable sized GstBuffer structure (say 512
279 bytes) and we will set the free_size to the maximum amount of metadata we can
282 Since the complete buffer structure, including a large area for metadata, is
283 allocated in one go, we can reduce the number of memory allocations while still
284 providing dynamic metadata.
286 When adding metadata, we need to call the init function of the associated
287 metadata info structure. Since adding the metadata requires the caller to pass
288 a handle to the info, this operation does not require table lookups.
290 Per-metadata memory initialisation is needed because not all metadata is
291 initialized in the same way. We need to, for example, set the timestamps to
292 NONE in the MetaTiming structures.
294 The init/free functions can also be used to implement refcounting for a metadata
295 structure. This can be useful when a structure is shared between buffers.
297 When the free_size of the GstBuffer is exhausted, we will allocate new memory
298 for each newly added BufferMeta and use the next pointers to point to this. It
299 is expected that this does not occur often and we might be able to optimize
300 this transparently in the future.
304 When a GstBuffer is freed, we potentially might have to call a custom free
305 function on the metadata info. In the case of the Memory metadata, we need to
306 call the associated free function to free the memory.
308 When freeing a GstBuffer, the custom buffer free function will iterate all of
309 the metadata in the buffer and call the associated free functions in the
310 MetaInfo associated with the entries. Usually, this function will be NULL.
316 Subbuffers are a first class feature of the GstBuffer.
318 Creating a subbuffer from a GstBuffer will allocate a new GstBuffer and ref the
319 parent buffer. It will then iterate all of the metadata entries for the parent
320 buffer and call the associated sub_func in the MetaInfo.
322 This allows each metadata structure to implement the actions needed to update
323 the metadata of the subbuffer.
325 A pointer to the old and new memory location of the metadata is passed to the
326 sub_func. The default implementation will simply copy the metadata. Custom
327 implementations can adjust the values. For example, when making a subbuffer, the
328 timing metadata needs to be reset to NONE when the start offset is different.
334 When buffer should be sent over the wire or be serialized in GDP, we need a way
335 to perform custom serialization and deserialization on the metadata.
337 For this we add the serialize and deserialize functions to the metadata info.
338 Possible use cases are to make sure we write out the fields with a specific size
345 Making the GstBufferMetaMemory (for making the buffer point to the associated
346 memory region) as metadata on a GstBuffer, as opposed to making it an integral
347 part of GstBuffer, allows for some more interesting ways to transfer data.
349 We could for example make a new GstBufferMetaIOVec metadata structure like this:
351 struct _GstBufferMetaIOVec {
354 /* pointer to data and its size */
361 This would allow us to transfer data in a scatter/gather array. Since the fields
362 in the buffer metadata are now explicit, elements that don't support this kind
363 of metadata can gracefully degrade.
365 Another use case for not having the Memory metadata in the buffers would be for
366 _pad_alloc() and get_range(). We can pass a GstBuffer with the requested
367 metadata fields to those functions and have the _get_range() or pad_alloc()
368 implementations add (or use, in the case of a file reader) the memory metadata.
371 Relationship with GstCaps
372 -------------------------
374 The difference between GstCaps, used in negotiation, and the metadata is not
377 We would like to think of the GstCaps containing the information needed to
378 functionally negotiate the format between two elements. The Metadata should then
379 only contain variables that can change between each buffer.