mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-09-01 01:33:52 +00:00
pwg: flesh out allocation docs
Add more examples. Add example for implementing new metadata. Add programs to the docs (again?), it seems to contain useful info.
This commit is contained in:
parent
98dc4a057d
commit
bd0eb629bf
3 changed files with 443 additions and 36 deletions
|
@ -79,7 +79,7 @@ main (int argc, char *argv[])
|
||||||
GError *err = NULL; /* error to show to users */
|
GError *err = NULL; /* error to show to users */
|
||||||
gchar *dbg = NULL; /* additional debug string for developers */
|
gchar *dbg = NULL; /* additional debug string for developers */
|
||||||
|
|
||||||
gst_message_parse_error (msg, &err, &dbg);
|
gst_message_parse_error (msg, &err, &dbg);
|
||||||
if (err) {
|
if (err) {
|
||||||
g_printerr ("ERROR: %s\n", err->message);
|
g_printerr ("ERROR: %s\n", err->message);
|
||||||
g_error_free (err);
|
g_error_free (err);
|
||||||
|
@ -193,6 +193,7 @@ gst-inspect mad
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
|
<![CDATA[
|
||||||
Factory Details:
|
Factory Details:
|
||||||
Rank: secondary (128)
|
Rank: secondary (128)
|
||||||
Long-name: Audio Sink (OSS)
|
Long-name: Audio Sink (OSS)
|
||||||
|
@ -325,6 +326,7 @@ Element Properties:
|
||||||
device : OSS device (usually /dev/dspN)
|
device : OSS device (usually /dev/dspN)
|
||||||
flags: readable, writable
|
flags: readable, writable
|
||||||
String. Default: "/dev/dsp"
|
String. Default: "/dev/dsp"
|
||||||
|
]]>
|
||||||
</screen>
|
</screen>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
|
|
|
@ -50,6 +50,7 @@
|
||||||
<!ENTITY COMPONENTS SYSTEM "highlevel-components.xml">
|
<!ENTITY COMPONENTS SYSTEM "highlevel-components.xml">
|
||||||
|
|
||||||
<!-- Appendices -->
|
<!-- Appendices -->
|
||||||
|
<!ENTITY PROGRAMS SYSTEM "appendix-programs.xml">
|
||||||
<!ENTITY CHECKLIST SYSTEM "appendix-checklist.xml">
|
<!ENTITY CHECKLIST SYSTEM "appendix-checklist.xml">
|
||||||
<!ENTITY PORTING SYSTEM "appendix-porting.xml">
|
<!ENTITY PORTING SYSTEM "appendix-porting.xml">
|
||||||
<!ENTITY INTEGRATION SYSTEM "appendix-integration.xml">
|
<!ENTITY INTEGRATION SYSTEM "appendix-integration.xml">
|
||||||
|
@ -253,6 +254,7 @@
|
||||||
- table please...
|
- table please...
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
&PROGRAMS;
|
||||||
&CHECKLIST;
|
&CHECKLIST;
|
||||||
&PORTING;
|
&PORTING;
|
||||||
&INTEGRATION;
|
&INTEGRATION;
|
||||||
|
|
|
@ -41,20 +41,60 @@
|
||||||
never be changed after the object is created, however, the offset
|
never be changed after the object is created, however, the offset
|
||||||
and size can be changed.
|
and size can be changed.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
|
||||||
Data access to the memory wrapped by the <classname>GstMemory</classname>
|
|
||||||
object is always protected with a <function>gst_memory_map()</function>
|
|
||||||
and <function>gst_memory_unmap()</function> pair. An access mode
|
|
||||||
(read/write) must be given when mapping memory. The map
|
|
||||||
function returns a pointer to the valid memory region that can
|
|
||||||
then be accessed according to the requested access mode.
|
|
||||||
</para>
|
|
||||||
<para>
|
<para>
|
||||||
<classname>GstMemory</classname> objects are created by a
|
<classname>GstMemory</classname> objects are created by a
|
||||||
<classname>GstAllocator</classname> object. To implement support
|
<classname>GstAllocator</classname> object. To implement support
|
||||||
for a new kind of memory type, you must implement a new allocator
|
for a new kind of memory type, you must implement a new allocator
|
||||||
object.
|
object.
|
||||||
</para>
|
</para>
|
||||||
|
<sect2 id="section-allocation-memory-ex" xreflabel="GstMemory-ex">
|
||||||
|
<title>GstMemory API example</title>
|
||||||
|
<para>
|
||||||
|
Data access to the memory wrapped by the <classname>GstMemory</classname>
|
||||||
|
object is always protected with a <function>gst_memory_map()</function>
|
||||||
|
and <function>gst_memory_unmap()</function> pair. An access mode
|
||||||
|
(read/write) must be given when mapping memory. The map
|
||||||
|
function returns a pointer to the valid memory region that can
|
||||||
|
then be accessed according to the requested access mode.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Below is an example of making a <classname>GstMemory</classname>
|
||||||
|
object and using the <function>gst_memory_map()</function> to
|
||||||
|
access the memory region.
|
||||||
|
</para>
|
||||||
|
<programlisting>
|
||||||
|
<![CDATA[
|
||||||
|
[...]
|
||||||
|
|
||||||
|
GstMemory *mem;
|
||||||
|
GstMapInfo info;
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
/* allocate 100 bytes */
|
||||||
|
mem = gst_allocator_alloc (NULL, 100, NULL);
|
||||||
|
|
||||||
|
/* get access to the memory in write mode */
|
||||||
|
gst_memory_map (mem, &info, GST_MAP_WRITE);
|
||||||
|
|
||||||
|
/* fill with pattern */
|
||||||
|
for (i = 0; i < info.size; i++)
|
||||||
|
info.data[i] = i;
|
||||||
|
|
||||||
|
/* release memory */
|
||||||
|
gst_memory_unmap (mem, &info);
|
||||||
|
|
||||||
|
[...]
|
||||||
|
]]>
|
||||||
|
</programlisting>
|
||||||
|
</sect2>
|
||||||
|
|
||||||
|
<sect2 id="section-allocation-allocator" xreflabel="GstAllocator">
|
||||||
|
<title>Implementing a GstAllocator</title>
|
||||||
|
<para>
|
||||||
|
WRITEME
|
||||||
|
</para>
|
||||||
|
</sect2>
|
||||||
|
|
||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
<sect1 id="section-allocation-buffer" xreflabel="GstBuffer">
|
<sect1 id="section-allocation-buffer" xreflabel="GstBuffer">
|
||||||
|
@ -100,14 +140,69 @@
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
<para>
|
|
||||||
A buffer is writable when the refcount of the object is exactly 1, meaning
|
<sect2 id="section-allocation-writability" xreflabel="GstBuffer-write">
|
||||||
that only one object is holding a ref to the buffer. You can only
|
<title>GstBuffer writability</title>
|
||||||
modify anything in the buffer when the buffer is writable. This means
|
<para>
|
||||||
that you need to call <function>gst_buffer_make_writable()</function>
|
A buffer is writable when the refcount of the object is exactly 1, meaning
|
||||||
before changing the timestamps, offsets, metadata or adding and
|
that only one object is holding a ref to the buffer. You can only
|
||||||
removing memory blocks.
|
modify anything in the buffer when the buffer is writable. This means
|
||||||
</para>
|
that you need to call <function>gst_buffer_make_writable()</function>
|
||||||
|
before changing the timestamps, offsets, metadata or adding and
|
||||||
|
removing memory blocks.
|
||||||
|
</para>
|
||||||
|
</sect2>
|
||||||
|
<sect2 id="section-allocation-buffer-ex" xreflabel="GstBuffer-ex">
|
||||||
|
<title>GstBuffer API examples</title>
|
||||||
|
<para>
|
||||||
|
You can create a buffer with <function>gst_buffer_new ()</function>
|
||||||
|
and then add memory objects to it or you can use a convenience function
|
||||||
|
<function>gst_buffer_new_allocate ()</function> which combines the
|
||||||
|
two. It's also possible to wrap existing memory with
|
||||||
|
<function>gst_buffer_new_wrapped_full () </function> where you can
|
||||||
|
give the function to call when the memory should be freed.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
You can access the memory of the buffer by getting and mapping the
|
||||||
|
<classname>GstMemory</classname> objects individually or by using
|
||||||
|
<function>gst_buffer_map ()</function>. The latter merges all the
|
||||||
|
memory into one big block and then gives you a pointer to this block.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Below is an example of how to create a buffer and access its memory.
|
||||||
|
</para>
|
||||||
|
<programlisting>
|
||||||
|
<![CDATA[
|
||||||
|
[...]
|
||||||
|
GstBuffer *buffer;
|
||||||
|
GstMemory *mem;
|
||||||
|
GstMapInfo info;
|
||||||
|
|
||||||
|
/* make empty buffer */
|
||||||
|
buffer = gst_buffer_new ();
|
||||||
|
|
||||||
|
/* make memory holding 100 bytes */
|
||||||
|
mem = gst_allocator_alloc (NULL, 100, NULL);
|
||||||
|
|
||||||
|
/* add the the buffer */
|
||||||
|
gst_buffer_append_memory (buffer, mem);
|
||||||
|
|
||||||
|
[...]
|
||||||
|
|
||||||
|
/* get WRITE access to the memory and fill with 0xff */
|
||||||
|
gst_buffer_map (buffer, &info, GST_MAP_WRITE);
|
||||||
|
memset (info.data, 0xff, info.size);
|
||||||
|
gst_buffer_unmap (buffer, &info);
|
||||||
|
|
||||||
|
[...]
|
||||||
|
|
||||||
|
/* free the buffer */
|
||||||
|
gst_buffer_unref (buffer);
|
||||||
|
|
||||||
|
[...]
|
||||||
|
]]>
|
||||||
|
</programlisting>
|
||||||
|
</sect2>
|
||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
<sect1 id="section-allocation-meta" xreflabel="GstMeta">
|
<sect1 id="section-allocation-meta" xreflabel="GstMeta">
|
||||||
|
@ -122,6 +217,288 @@
|
||||||
backing up the memory of the buffer. This makes it easier for elements
|
backing up the memory of the buffer. This makes it easier for elements
|
||||||
to locate the X image from the buffer.
|
to locate the X image from the buffer.
|
||||||
</para>
|
</para>
|
||||||
|
<para>
|
||||||
|
The metadata system separates API specification (what the metadata
|
||||||
|
and its API look like) and the implementation (how it works). This makes
|
||||||
|
it possible to make different implementations of the same API,
|
||||||
|
for example, depending on the hardware you are running on.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<sect2 id="section-allocation-meta-ex" xreflabel="GstMeta-ex">
|
||||||
|
<title>GstMeta API example</title>
|
||||||
|
<para>
|
||||||
|
After allocating a new buffer, you can add metadata to the buffer
|
||||||
|
with the metadata specific API. This means that you will need to
|
||||||
|
link to the header file where the metadata is defined to use
|
||||||
|
its API.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
By convention, a metadata API with name <classname>FooBar</classname>
|
||||||
|
should provide two methods, a
|
||||||
|
<function>gst_buffer_add_foo_bar_meta ()</function> and a
|
||||||
|
<function>gst_buffer_get_foo_bar_meta ()</function>. Both functions
|
||||||
|
should return a pointer to a <classname>FooBarMeta</classname>
|
||||||
|
structure that contains the metadata fields. Some of the
|
||||||
|
<function>_add_*_meta ()</function> can have extra parameters that
|
||||||
|
will usually be used to configure the metadata structure for you.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Let's have a look at the metadata that is used to specify a cropping
|
||||||
|
region for video frames.
|
||||||
|
</para>
|
||||||
|
<programlisting>
|
||||||
|
<![CDATA[
|
||||||
|
#include <gst/video/gstvideometa.h>
|
||||||
|
|
||||||
|
[...]
|
||||||
|
GstVideoCropMeta *meta;
|
||||||
|
|
||||||
|
/* buffer points to a video frame, add some cropping metadata */
|
||||||
|
meta = gst_buffer_add_video_crop_meta (buffer);
|
||||||
|
|
||||||
|
/* configure the cropping metadata */
|
||||||
|
meta->x = 8;
|
||||||
|
meta->y = 8;
|
||||||
|
meta->width = 120;
|
||||||
|
meta->height = 80;
|
||||||
|
[...]
|
||||||
|
]]>
|
||||||
|
</programlisting>
|
||||||
|
<para>
|
||||||
|
An element can then use the metadata on the buffer when rendering
|
||||||
|
the frame like this:
|
||||||
|
</para>
|
||||||
|
<programlisting>
|
||||||
|
<![CDATA[
|
||||||
|
#include <gst/video/gstvideometa.h>
|
||||||
|
|
||||||
|
[...]
|
||||||
|
GstVideoCropMeta *meta;
|
||||||
|
|
||||||
|
/* buffer points to a video frame, get the cropping metadata */
|
||||||
|
meta = gst_buffer_get_video_crop_meta (buffer);
|
||||||
|
|
||||||
|
if (meta) {
|
||||||
|
/* render frame with cropping */
|
||||||
|
_render_frame_cropped (buffer, meta->x, meta->y, meta->width, meta->height);
|
||||||
|
} else {
|
||||||
|
/* render frame */
|
||||||
|
_render_frame (buffer);
|
||||||
|
}
|
||||||
|
[...]
|
||||||
|
|
||||||
|
]]>
|
||||||
|
</programlisting>
|
||||||
|
</sect2>
|
||||||
|
|
||||||
|
<sect2 id="section-allocation-meta-new" xreflabel="GstMeta-new">
|
||||||
|
<title>Implementing new GstMeta</title>
|
||||||
|
<para>
|
||||||
|
In the next sections we show how you can add new metadata to the
|
||||||
|
system and use it on buffers.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<sect3 id="section-allocation-meta-api" xreflabel="GstMeta-api">
|
||||||
|
<title>Define the metadata API</title>
|
||||||
|
<para>
|
||||||
|
First we need to define what our API will look like and we
|
||||||
|
will have to register this API to the system. This is important
|
||||||
|
because this API definition will be used when elements negotiate
|
||||||
|
what kind of metadata they will exchange. The API definition
|
||||||
|
also contains arbitrary tags that give hints about what the
|
||||||
|
metadata contains. This is important when we see how metadata
|
||||||
|
is preserved when buffers pass through the pipeline.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
If you are making a new implementation of an existing API,
|
||||||
|
you can skip this step and move on to the implementation step.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
First we start with making the
|
||||||
|
<filename>my-example-meta.h</filename> header file that will contain
|
||||||
|
the definition of the API and structure for our metadata.
|
||||||
|
</para>
|
||||||
|
<programlisting>
|
||||||
|
<![CDATA[
|
||||||
|
#include <gst/gst.h>
|
||||||
|
|
||||||
|
typedef struct _MyExampleMeta MyExampleMeta;
|
||||||
|
|
||||||
|
struct _MyExampleMeta {
|
||||||
|
GstMeta meta;
|
||||||
|
|
||||||
|
gint age;
|
||||||
|
gchar *name;
|
||||||
|
};
|
||||||
|
|
||||||
|
GType my_example_meta_api_get_type (void);
|
||||||
|
#define MY_EXAMPLE_META_API_TYPE (my_example_meta_api_get_type())
|
||||||
|
|
||||||
|
#define gst_buffer_get_my_example_meta(b) \
|
||||||
|
((MyExampleMeta*)gst_buffer_get_meta((b),MY_EXAMPLE_META_API_TYPE))
|
||||||
|
]]>
|
||||||
|
</programlisting>
|
||||||
|
<para>
|
||||||
|
The metadata API definition consists of the definition of the
|
||||||
|
structure that holds a gint and a string. The first field in
|
||||||
|
the structure must be <classname>GstMeta</classname>.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
We also define a <function>my_example_meta_api_get_type ()</function>
|
||||||
|
function that will register out metadata API definition. We
|
||||||
|
also define a convenience macro
|
||||||
|
<function>gst_buffer_get_my_example_meta ()</function> that simply
|
||||||
|
finds and returns the metadata with our new API.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Next let's have a look at how the
|
||||||
|
<function>my_example_meta_api_get_type ()</function> function is
|
||||||
|
implemented in the <filename>my-example-meta.c</filename> file.
|
||||||
|
</para>
|
||||||
|
<programlisting>
|
||||||
|
<![CDATA[
|
||||||
|
#include "my-example-meta.h"
|
||||||
|
|
||||||
|
GType
|
||||||
|
my_example_meta_api_get_type (void)
|
||||||
|
{
|
||||||
|
static volatile GType type;
|
||||||
|
static const gchar *tags[] = { "foo", "bar", NULL };
|
||||||
|
|
||||||
|
if (g_once_init_enter (&type)) {
|
||||||
|
GType _type = gst_meta_api_type_register ("MyExampleMetaAPI", tags);
|
||||||
|
g_once_init_leave (&type, _type);
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
]]>
|
||||||
|
</programlisting>
|
||||||
|
<para>
|
||||||
|
As you can see, it simply uses the
|
||||||
|
<function>gst_meta_api_type_register ()</function> function to
|
||||||
|
register a name for the api and some tags. The result is a
|
||||||
|
new pointer GType that defines the newly registered API.
|
||||||
|
</para>
|
||||||
|
</sect3>
|
||||||
|
|
||||||
|
<sect3 id="section-allocation-meta-impl" xreflabel="GstMeta-impl">
|
||||||
|
<title>Implementing a metadata API</title>
|
||||||
|
<para>
|
||||||
|
Next we can make an implementation for a registered metadata
|
||||||
|
API GType. The implementation detail of a metadata API
|
||||||
|
are kept in a <classname>GstMetaInfo</classname> structure
|
||||||
|
that you will make available to the users of your metadata
|
||||||
|
API implementation with a <function>my_example_meta_get_info ()</function>
|
||||||
|
function and a convenience <function>MY_EXAMPLE_META_INFO</function>
|
||||||
|
macro. You will also make a method to add your metadata
|
||||||
|
implementation to a <classname>GstBuffer</classname>.
|
||||||
|
Your <filename>my-example-meta.h</filename> header file will
|
||||||
|
need thse additions:
|
||||||
|
</para>
|
||||||
|
<programlisting>
|
||||||
|
<![CDATA[
|
||||||
|
[...]
|
||||||
|
|
||||||
|
/* implementation */
|
||||||
|
const GstMetaInfo *my_example_meta_get_info (void);
|
||||||
|
#define MY_EXAMPLE_META_INFO (my_example_meta_get_info())
|
||||||
|
|
||||||
|
MyExampleMeta * gst_buffer_add_my_example_meta (GstBuffer *buffer,
|
||||||
|
gint age,
|
||||||
|
const gchar *name);
|
||||||
|
]]>
|
||||||
|
</programlisting>
|
||||||
|
<para>
|
||||||
|
Let's have a look at how these functions are
|
||||||
|
implemented in the <filename>my-example-meta.c</filename> file.
|
||||||
|
</para>
|
||||||
|
<programlisting>
|
||||||
|
<![CDATA[
|
||||||
|
[...]
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
my_example_meta_init (GstMeta * meta, gpointer params, GstBuffer * buffer)
|
||||||
|
{
|
||||||
|
MyExampleMeta *emeta = (MyExampleMeta *) meta;
|
||||||
|
|
||||||
|
emeta->age = 0;
|
||||||
|
emeta->name = NULL;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
my_example_meta_transform (GstBuffer * transbuf, GstMeta * meta,
|
||||||
|
GstBuffer * buffer, GQuark type, gpointer data)
|
||||||
|
{
|
||||||
|
MyExampleMeta *emeta = (MyExampleMeta *) meta;
|
||||||
|
|
||||||
|
/* we always copy no matter what transform */
|
||||||
|
gst_buffer_add_my_example_meta (transbuf, emeta->age, emeta->name);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
my_example_meta_free (GstMeta * meta, GstBuffer * buffer)
|
||||||
|
{
|
||||||
|
MyExampleMeta *emeta = (MyExampleMeta *) meta;
|
||||||
|
|
||||||
|
g_free (emeta->name)
|
||||||
|
emeta->name = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const GstMetaInfo *
|
||||||
|
my_example_meta_get_info (void)
|
||||||
|
{
|
||||||
|
static const GstMetaInfo *meta_info = NULL;
|
||||||
|
|
||||||
|
if (meta_info == NULL) {
|
||||||
|
meta_info = gst_meta_register (MY_EXAMPLE_META_API_TYPE,
|
||||||
|
"MyExampleMeta",
|
||||||
|
sizeof (MyExampleMeta),
|
||||||
|
my_example_meta_init,
|
||||||
|
my_example_meta_free,
|
||||||
|
my_example_meta_transform);
|
||||||
|
}
|
||||||
|
return meta_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
MyExampleMeta *
|
||||||
|
gst_buffer_add_my_example_meta (GstBuffer *buffer,
|
||||||
|
gint age,
|
||||||
|
const gchar *name)
|
||||||
|
{
|
||||||
|
MyExampleMeta *meta;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL);
|
||||||
|
|
||||||
|
meta = (MyExampleMeta *) gst_buffer_add_meta (buffer,
|
||||||
|
MY_EXAMPLE_META_INFO, NULL);
|
||||||
|
|
||||||
|
meta->age = age;
|
||||||
|
meta->name = g_strdup (name);
|
||||||
|
|
||||||
|
return meta;
|
||||||
|
}
|
||||||
|
]]>
|
||||||
|
</programlisting>
|
||||||
|
<para>
|
||||||
|
<function>gst_meta_register ()</function> registers the implementation
|
||||||
|
details, like the API that you implement and the size of the
|
||||||
|
metadata structure along with methods to initialize and free the
|
||||||
|
memory area. You can also implement a transform function that will
|
||||||
|
be called when a certain transformation (identified by the quark and
|
||||||
|
quark specific data) is performed on a buffer.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Lastly, you implement a <function>gst_buffer_add_*_meta()</function>
|
||||||
|
that adds the metadata implementation to a buffer and sets the
|
||||||
|
values of the metadata.
|
||||||
|
</para>
|
||||||
|
</sect3>
|
||||||
|
</sect2>
|
||||||
|
|
||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
<sect1 id="section-allocation-bufferpool" xreflabel="GstBufferPool">
|
<sect1 id="section-allocation-bufferpool" xreflabel="GstBufferPool">
|
||||||
|
@ -141,6 +518,21 @@
|
||||||
to the buffers in the pool or such as enabling specific padding on
|
to the buffers in the pool or such as enabling specific padding on
|
||||||
the memory in the buffers.
|
the memory in the buffers.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<sect2 id="section-allocation-pool-ex" xreflabel="GstBufferPool-ex">
|
||||||
|
<title>GstBufferPool API example</title>
|
||||||
|
<para>
|
||||||
|
WRITEME
|
||||||
|
</para>
|
||||||
|
</sect2>
|
||||||
|
|
||||||
|
<sect2 id="section-allocation-pool-new" xreflabel="GstBufferPool-new">
|
||||||
|
<title>Implementing a new GstBufferPool</title>
|
||||||
|
<para>
|
||||||
|
WRITEME
|
||||||
|
</para>
|
||||||
|
</sect2>
|
||||||
|
|
||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
<sect1 id="section-allocation-query" xreflabel="GST_QUERY_ALLOCATION">
|
<sect1 id="section-allocation-query" xreflabel="GST_QUERY_ALLOCATION">
|
||||||
|
@ -191,24 +583,35 @@
|
||||||
from the available bufferpools, allocators and metadata how it will
|
from the available bufferpools, allocators and metadata how it will
|
||||||
allocate buffers.
|
allocate buffers.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
|
||||||
In many baseclasses you will see the following virtual methods for
|
<sect2 id="section-allocation-query-ex" xreflabel="Allocation-ex">
|
||||||
influencing the allocation strategy:
|
<title>ALLOCATION query example</title>
|
||||||
</para>
|
<para>
|
||||||
<itemizedlist>
|
WRITEME
|
||||||
<listitem>
|
</para>
|
||||||
<para>
|
</sect2>
|
||||||
<function>propose_allocation ()</function> should suggest
|
|
||||||
allocation parameters for the upstream element.
|
<sect2 id="section-allocation-query-base" xreflabel="Allocation-base">
|
||||||
</para>
|
<title>The ALLOCATION query in base classes</title>
|
||||||
</listitem>
|
<para>
|
||||||
<listitem>
|
In many baseclasses you will see the following virtual methods for
|
||||||
<para>
|
influencing the allocation strategy:
|
||||||
<function>decide_allocation ()</function> should decide the
|
</para>
|
||||||
allocation parameters from the suggestions received from
|
<itemizedlist>
|
||||||
downstream.
|
<listitem>
|
||||||
</para>
|
<para>
|
||||||
</listitem>
|
<function>propose_allocation ()</function> should suggest
|
||||||
</itemizedlist>
|
allocation parameters for the upstream element.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<function>decide_allocation ()</function> should decide the
|
||||||
|
allocation parameters from the suggestions received from
|
||||||
|
downstream.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</sect2>
|
||||||
</sect1>
|
</sect1>
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|
Loading…
Reference in a new issue