<chapter id="chapter-allocation" xreflabel="Memory allocation">
  <title>Memory allocation</title>
  <para>
    Memory allocation and management is a very important topic in
    multimedia. High definition video uses many magabytes to store
    one single frame of video. It is important to reuse the memory
    when possible instead of constantly allocating and freeing
    the memory.
  </para>
  <para>
    Multimedia systems usually use special purpose chips, such as
    DSPs or GPUs to perform the heavy lifting (especially for video).
    These special purpose chips have usually strict requirements
    for the memory that they can operate on and how the memory
    is accessed.
  </para>
  <para>
    This chapter talks about the memory management features that
    &GStreamer; plugins can use. We will first talk about the
    lowlevel <classname>GstMemory</classname> object that manages
    access to a piece of memory. We then continue with
    <classname>GstBuffer</classname> that is used to exchange data
    between plugins (and the application) and that uses
    <classname>GstMemory</classname>. We talk about
    <classname>GstMeta</classname> that can be placed on buffers to
    give extra info about the buffer and its memory.
    For efficiently managing buffers of the same size, we take a
    look at <classname>GstBufferPool</classname>. To conclude this
    chapter we take a look at the GST_QUERY_ALLOCATION query that
    is used to negotiate memory management options between elements.
  </para>

  <sect1 id="section-allocation-memory" xreflabel="GstMemory">
    <title>GstMemory</title>
    <para>
      <classname>GstMemory</classname> is an object that manages a region
      of memory. The memory object points to a region of memory of
      <quote>maxsize</quote>. The area in this memory starting at
      <quote>offset</quote> and for <quote>size</quote> bytes is the
      accessible region in the memory. the maxsize of the memory can
      never be changed after the object is created, however, the offset
      and size can be changed.
    </para>
    <para>
      <classname>GstMemory</classname> objects are created by a
      <classname>GstAllocator</classname> object. To implement support
      for a new kind of memory type, you must implement a new allocator
      object.
    </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 id="section-allocation-buffer" xreflabel="GstBuffer">
    <title>GstBuffer</title>
    <para>
      A <classname>GstBuffer</classname> is an lightweight object that
      is passed from an upstream to a downstream element and contains
      memory and metadata. It represents the multimedia content that
      is pushed or pull downstream by elements.
    </para>
    <para>
      The buffer contains one or more <classname>GstMemory</classname>
      objects thet represent the data in the buffer.
    </para>
    <para>
      Metadata in the buffer consists of:
    </para>
    <itemizedlist mark="opencircle">
      <listitem>
        <para>
          DTS and PTS timestamps. These represent the decoding and
          presentation timestamps of the buffer content and is used by
          synchronizing elements to schedule buffers. Both these timestamps
          can be GST_CLOCK_TIME_NONE when unknown/undefined.
        </para>
      </listitem>
      <listitem>
        <para>
          The duration of the buffer contents. This duration can be
          GST_CLOCK_TIME_NONE when unknown/undefined.
        </para>
      </listitem>
      <listitem>
        <para>
          Media specific offsets and offset_end. For video this is the 
          frame number in the stream and for audio the sample number. Other
          definitions for other media exist. 
        </para>
      </listitem>
      <listitem>
        <para>
          Arbitrary structures via <classname>GstMeta</classname>, see below.
        </para>
      </listitem>
    </itemizedlist>

    <sect2 id="section-allocation-writability" xreflabel="GstBuffer-write">
      <title>GstBuffer writability</title>
      <para>
        A buffer is writable when the refcount of the object is exactly 1, meaning
        that only one object is holding a ref to the buffer. You can only
        modify anything in the buffer when the buffer is writable. This means
        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 id="section-allocation-meta" xreflabel="GstMeta">
    <title>GstMeta</title>
    <para>
      With the <classname>GstMeta</classname> system you can add arbitrary
      structures of on buffers. These structures describe extra properties
      of the buffer such as cropping, stride, region of interest etc.
    </para>
    <para>
      Metadata is also used to store, for example, the X image that is
      backing up the memory of the buffer. This makes it easier for elements
      to locate the X image from the buffer.
    </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 (g_once_init_enter (&meta_info)) {
    const GstMetaInfo *mi = gst_meta_register (MY_EXAMPLE_META_API_TYPE,
        "MyExampleMeta",
        sizeof (MyExampleMeta),
        my_example_meta_init,
        my_example_meta_free,
        my_example_meta_transform);
    g_once_init_leave (&meta_info, mi);
  }
  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 id="section-allocation-bufferpool" xreflabel="GstBufferPool">
    <title>GstBufferPool</title>
    <para>
      The <classname>GstBufferPool</classname> object provides a convenient
      base class for managing lists of reusable buffers. Essential for this
      object is that all the buffers have the same properties such as size,
      padding, metadata and alignment.
    </para>
    <para>
      A bufferpool object can be configured to manage a minimum and maximum
      amount of buffers of a specific size. A bufferpool can also be
      configured to use a specific <classname>GstAllocator</classname> for
      the memory of the buffers. There is support in the bufferpool to enable
      bufferpool specific options, such as adding <classname>GstMeta</classname>
      to the buffers in the pool or such as enabling specific padding on
      the memory in the buffers.
    </para>
    <para>
      A Bufferpool can be inactivate and active. In the inactive state,
      you can configure the pool. In the active state, you can't change
      the configuration anymore but you can acquire and release buffers
      from/to the pool.
    </para>
    <para>
      In the following sections we take a look at how you can use
      a bufferpool. 
    </para>

    <sect2 id="section-allocation-pool-ex" xreflabel="GstBufferPool-ex">
      <title>GstBufferPool API example</title>
      <para>
        Many different bufferpool implementations can exist; they are all
        subclasses of the base class <classname>GstBufferPool</classname>.
        For this example, we will assume we somehow have access to a
        bufferpool, either because we created it ourselves or because
        we were given one as a result of the ALLOCATION query as we will
        see below.
      </para>
      <para>
        The bufferpool is initially in the inactive state so that we can
        configure it. Trying to configure a bufferpool that is not in the
        inactive state will fail. Likewise, trying to activate a bufferpool
        that is not configured will fail.
      </para>
      <programlisting>
<![CDATA[
  GstStructure *config;

[...]

  /* get config structure */
  config = gst_buffer_pool_get_config (pool);

  /* set caps, size, minimum and maximum buffers in the pool */
  gst_buffer_pool_config_set_params (config, caps, size, min, max);

  /* configure allocator and parameters */
  gst_buffer_pool_config_set_allocator (config, allocator, &params);

  /* store the updated configuration again */
  gst_buffer_pool_set_config (pool, config);

[...]
]]>
      </programlisting>
      <para>
        The configuration of the bufferpool is maintained in a generic
        <classname>GstStructure</classname> that can be obtained with
        <function>gst_buffer_pool_get_config()</function>. Convenience
        methods exist to get and set the configuration options in this
        structure. After updating the structure, it is set as the current
        configuration in the bufferpool again with
        <function>gst_buffer_pool_set_config()</function>.
      </para>
      <para>
        The following options can be configured on a bufferpool:
      </para>
      <itemizedlist mark="opencircle">
        <listitem>
          <para>
            The caps of the buffers to allocate.
          </para>
        </listitem>
        <listitem>
          <para>
            The size of the buffers. This is the suggested size of the
            buffers in the pool. The pool might decide to allocate larger
            buffers to add padding.
          </para>
        </listitem>
        <listitem>
          <para>
            The minimum and maximum amount of buffers in the pool. When
            minimum is set to > 0, the bufferpool will pre-allocate this
            amount of buffers. When maximum is not 0, the bufferpool
            will allocate up to maximum amount of buffers.
          </para>
        </listitem>
        <listitem>
          <para>
            The allocator and parameters to use. Some bufferpools might
            ignore the allocator and use its internal one.
          </para>
        </listitem>
        <listitem>
          <para>
            Other arbitrary bufferpool options identified with a string.
            a bufferpool lists the supported options with
            <function>gst_buffer_pool_get_options()</function> and you 
            can ask if an option is supported with
            <function>gst_buffer_pool_has_option()</function>. The option
            can be enabled by adding it to the configuration structure
            with <function>gst_buffer_pool_config_add_option ()</function>.
            These options are used to enable things like letting the
            pool set metadata on the buffers or to add extra configuration
            options for padding, for example.
          </para>
        </listitem>
      </itemizedlist>
      <para>
        After the configuration is set on the bufferpool, the pool can
        be activated with
        <function>gst_buffer_pool_set_active (pool, TRUE)</function>. From
        that point on you can use
        <function>gst_buffer_pool_acquire_buffer ()</function> to retrieve
        a buffer from the pool, like this:
      </para>
      <programlisting>
<![CDATA[
  [...]

  GstFlowReturn ret;
  GstBuffer *buffer;

  ret = gst_buffer_pool_acquire_buffer (pool, &buffer, NULL);
  if (G_UNLIKELY (ret != GST_FLOW_OK))
    goto pool_failed;

  [...]
]]>
      </programlisting>
      <para>
        It is important to check the return value of the acquire function
        because it is possible that it fails: When your
        element shuts down, it will deactivate the bufferpool and then
        all calls to acquire will return GST_FLOW_FLUSHNG.
      </para>
      <para>
        All buffers that are acquired from the pool will have their pool
        member set to the original pool. When the last ref is decremented
        on the buffer, &GStreamer; will automatically call
        <function>gst_buffer_pool_release_buffer()</function> to release
        the buffer back to the pool. You (or any other downstream element)
        don't need to know if a buffer came from a pool, you can just
        unref it.
      </para>
    </sect2>

    <sect2 id="section-allocation-pool-impl" xreflabel="GstBufferPool-impl">
      <title>Implementing a new GstBufferPool</title>
      <para>
        WRITEME
      </para>
    </sect2>

  </sect1>

  <sect1 id="section-allocation-query" xreflabel="GST_QUERY_ALLOCATION">
    <title>GST_QUERY_ALLOCATION</title>
    <para>
      The ALLOCATION query is used to negotiate
      <classname>GstMeta</classname>, <classname>GstBufferPool</classname>
      and <classname>GstAllocator</classname> between elements. Negotiation
      of the allocation strategy is always initiated and decided by a srcpad
      after it has negotiated a format and before it decides to push buffers.
      A sinkpad can suggest an allocation strategy but it is ultimately the
      source pad that will decide based on the suggestions of the downstream
      sink pad.
    </para>
    <para>
      The source pad will do a GST_QUERY_ALLOCATION with the negotiated caps
      as a parameter. This is needed so that the downstream element knows
      what media type is being handled. A downstream sink pad can answer the
      allocation query with the following results:
    </para>
    <itemizedlist mark="opencircle">
      <listitem>
        <para>
          An array of possible <classname>GstBufferPool</classname> suggestions
          with suggested size, minimum and maximum amount of buffers.
        </para>
      </listitem>
      <listitem>
        <para>
          An array of GstAllocator objects along with suggested allocation
          parameters such as flags, prefix, alignment and padding. These
          allocators can also be configured in a bufferpool when this is
          supported by the bufferpool.
        </para>
      </listitem>
      <listitem>
        <para>
          An array of supported <classname>GstMeta</classname> implementations
          along with metadata specific parameters.
          It is important that the upstream element knows what kind of
          metadata is supported downstream before it places that metadata
          on buffers.
        </para>
      </listitem>
    </itemizedlist>
    <para>
      When the GST_QUERY_ALLOCATION returns, the source pad will select
      from the available bufferpools, allocators and metadata how it will
      allocate buffers.
    </para>

    <sect2 id="section-allocation-query-ex" xreflabel="Allocation-ex">
      <title>ALLOCATION query example</title>
      <para>
        Below is an example of the ALLOCATION query.
      </para>
      <programlisting>
<![CDATA[
#include <gst/video/video.h>
#include <gst/video/gstvideometa.h>
#include <gst/video/gstvideopool.h>

  GstCaps *caps;
  GstQuery *query;
  GstStructure *structure;
  GstBufferPool *pool;
  GstStructure *config;
  guint size, min, max;

[...]

  /* find a pool for the negotiated caps now */
  query = gst_query_new_allocation (caps, TRUE);

  if (!gst_pad_peer_query (scope->srcpad, query)) {
    /* query failed, not a problem, we use the query defaults */
  }

  if (gst_query_get_n_allocation_pools (query) > 0) {
    /* we got configuration from our peer, parse them */
    gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max);
  } else {
    pool = NULL;
    size = 0;
    min = max = 0;
  }

  if (pool == NULL) {
    /* we did not get a pool, make one ourselves then */
    pool = gst_video_buffer_pool_new ();
  }

  config = gst_buffer_pool_get_config (pool);
  gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META);
  gst_buffer_pool_config_set_params (config, caps, size, min, max);
  gst_buffer_pool_set_config (pool, config);

  /* and activate */
  gst_buffer_pool_set_active (pool, TRUE);

[...]
]]>
      </programlisting>
      <para>
        This particular implementation will make a custom
        <classname>GstVideoBufferPool</classname> object that is specialized
        in allocating video buffers. You can also enable the pool to
        put <classname>GstVideoMeta</classname> metadata on the buffers from
        the pool doing
        <function>gst_buffer_pool_config_add_option (config,
          GST_BUFFER_POOL_OPTION_VIDEO_META)</function>.
      </para>
    </sect2>

    <sect2 id="section-allocation-query-base" xreflabel="Allocation-base">
      <title>The ALLOCATION query in base classes</title>
      <para>
        In many baseclasses you will see the following virtual methods for
        influencing the allocation strategy:
      </para>
      <itemizedlist>
        <listitem>
          <para>
            <function>propose_allocation ()</function> should suggest
            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>
      <para>
        Implementors of these methods should modify the given
        <classname>GstQuery</classname> object by updating the pool options
        and allocation options.
      </para>
    </sect2>
  </sect1>
</chapter>
