The ALLOCATION query is used to negotiate
GstMeta
, GstBufferPool
and GstAllocator
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.
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:
An array of possible GstBufferPool
suggestions
with suggested size, minimum and maximum amount of buffers.
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.
An array of supported GstMeta
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.
When the GST_QUERY_ALLOCATION returns, the source pad will select from the available bufferpools, allocators and metadata how it will allocate buffers.
Below is an example of the ALLOCATION query.
#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); [...]
This particular implementation will make a custom
GstVideoBufferPool
object that is specialized
in allocating video buffers. You can also enable the pool to
put GstVideoMeta
metadata on the buffers from
the pool doing
gst_buffer_pool_config_add_option (config,
GST_BUFFER_POOL_OPTION_VIDEO_META)
.
In many baseclasses you will see the following virtual methods for influencing the allocation strategy:
propose_allocation ()
should suggest
allocation parameters for the upstream element.
decide_allocation ()
should decide the
allocation parameters from the suggestions received from
downstream.
Implementors of these methods should modify the given
GstQuery
object by updating the pool options
and allocation options.