bufferpool: add query to request pool and configuration

Add a query to request allocation parameters and optionally a bufferpool as
well. This should allow elements to discover downstream capabilities and also
use the downstream allocators.
This commit is contained in:
Wim Taymans 2011-04-28 15:31:48 +02:00
parent 7c8405fa28
commit 06f6935107
6 changed files with 198 additions and 3 deletions

View file

@ -0,0 +1,51 @@
Allocation
----------
This document outlines the requirements for determining how memory and buffers
will be allocated between to pads.
Overview
~~~~~~~~
After a particular media format has been negotiated between two pads, they must
agree on how to allocate buffers.
The srcpad will always take the initiative to negotiate the allocation
properties. It starts with creating a GST_QUERY_ALLOCATION with the negotiated
caps.
The srcpad can set the need-pool flag to TRUE in the query to optionally make the
peer pad allocate a bufferpool.
It will then inspect the returned results and configure the returned pool or
create a new pool when needed.
Buffers are then allocated by the srcpad from the negotiated pool.
Allocation query
~~~~~~~~~~~~~~~~
(in) "caps", GST_TYPE_CAPS
- the caps that was negotiated
(in) "need-pool", G_TYPE_BOOLEAN
- if a GstBufferPool is requested
(out) "prefix", G_TYPE_UINT
- the prefix of the buffer memory
(out) "align", G_TYPE_UINT
- the aligment of the memory in the buffers, the alignment will be applied
to the prefix.
(out) "size", G_TYPE_UINT
- the total size of the buffer memory
(out) "pool", GST_TYPE_BUFFER_POOL
- a buffer pool when need-pool was TRUE and the peer can provide a pool
(out) "metadata", G_TYPE_VALUE_ARRAY of G_TYPE_STRING
- an array of metadata API strings that can be accepted.

View file

@ -51,7 +51,8 @@ static const gchar *_quark_strings[] = {
"message", "GstMessageQOS", "running-time", "stream-time", "jitter",
"quality", "processed", "dropped", "buffering-ranges", "GstMessageProgress",
"code", "text", "percent", "timeout", "GstBufferPoolConfig", "caps", "size",
"min-buffers", "max-buffers", "prefix", "postfix", "align", "time"
"min-buffers", "max-buffers", "prefix", "postfix", "align", "time",
"GstQueryAllocation", "need-pool", "meta", "pool"
};
GQuark _priv_gst_quark_table[GST_QUARK_MAX];

View file

@ -141,8 +141,12 @@ typedef enum _GstQuarkId
GST_QUARK_POSTFIX = 112,
GST_QUARK_ALIGN = 113,
GST_QUARK_TIME = 114,
GST_QUARK_QUERY_ALLOCATION = 115,
GST_QUARK_NEED_POOL = 116,
GST_QUARK_META = 117,
GST_QUARK_POOL = 118,
GST_QUARK_MAX = 115
GST_QUARK_MAX = 119
} GstQuarkId;
extern GQuark _priv_gst_quark_table[GST_QUARK_MAX];

View file

@ -68,6 +68,7 @@
#include "gstenumtypes.h"
#include "gstquark.h"
#include "gsturi.h"
#include "gstbufferpool.h"
GST_DEBUG_CATEGORY_STATIC (gst_query_debug);
#define GST_CAT_DEFAULT gst_query_debug
@ -1465,3 +1466,119 @@ gst_query_parse_uri (GstQuery * query, gchar ** uri)
*uri = g_value_dup_string (gst_structure_id_get_value (query->structure,
GST_QUARK (URI)));
}
GstQuery *
gst_query_new_alloction (GstCaps * caps, gboolean need_pool)
{
GstQuery *query;
GstStructure *structure;
structure = gst_structure_id_new (GST_QUARK (QUERY_ALLOCATION),
GST_QUARK (CAPS), GST_TYPE_CAPS, caps,
GST_QUARK (NEED_POOL), G_TYPE_BOOLEAN, need_pool,
GST_QUARK (PREFIX), G_TYPE_UINT, 0,
GST_QUARK (ALIGN), G_TYPE_UINT, 1,
GST_QUARK (SIZE), G_TYPE_UINT, 0,
GST_QUARK (POOL), GST_TYPE_BUFFER_POOL, NULL,
GST_QUARK (META), G_TYPE_VALUE_ARRAY, NULL, NULL);
query = gst_query_new (GST_QUERY_ALLOCATION, structure);
return query;
}
void
gst_query_set_allocation (GstQuery * query, guint alignment, guint prefix,
guint size, GstBufferPool * pool)
{
g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
gst_structure_id_set (query->structure,
GST_QUARK (ALIGN), G_TYPE_UINT, alignment,
GST_QUARK (PREFIX), G_TYPE_UINT, prefix,
GST_QUARK (SIZE), G_TYPE_UINT, size,
GST_QUARK (POOL), GST_TYPE_BUFFER_POOL, pool, NULL);
}
void
gst_query_parse_allocation (GstQuery * query, guint * alignment, guint * prefix,
guint * size, GstBufferPool ** pool)
{
g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
gst_structure_id_get (query->structure,
GST_QUARK (ALIGN), G_TYPE_UINT, alignment,
GST_QUARK (PREFIX), G_TYPE_UINT, prefix,
GST_QUARK (SIZE), G_TYPE_UINT, size,
GST_QUARK (POOL), GST_TYPE_BUFFER_POOL, pool, NULL);
}
void
gst_query_add_allocation_meta (GstQuery * query, const gchar * api)
{
GValueArray *array;
const GValue *value;
GValue api_value = { 0 };
g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
value = gst_structure_id_get_value (query->structure, GST_QUARK (META));
if (value) {
array = (GValueArray *) g_value_get_boxed (value);
} else {
GValue new_array_val = { 0, };
array = g_value_array_new (0);
g_value_init (&new_array_val, G_TYPE_VALUE_ARRAY);
g_value_take_boxed (&new_array_val, array);
gst_structure_id_take_value (query->structure, GST_QUARK (META),
&new_array_val);
}
g_value_init (&api_value, G_TYPE_STRING);
g_value_set_string (&api_value, api);
g_value_array_append (array, &api_value);
g_value_unset (&api_value);
}
guint
gst_query_get_n_allocation_meta (GstQuery * query)
{
GValueArray *array;
const GValue *value;
guint size = 0;
g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, 0);
value = gst_structure_id_get_value (query->structure, GST_QUARK (META));
if (value) {
array = (GValueArray *) g_value_get_boxed (value);
size = array->n_values;
}
return size;
}
const gchar *
gst_query_parse_allocation_meta (GstQuery * query, guint index)
{
const GValue *value;
const gchar *ret = NULL;
g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, NULL);
value = gst_structure_id_get_value (query->structure, GST_QUARK (META));
if (value) {
GValueArray *meta;
GValue *api_value;
meta = (GValueArray *) g_value_get_boxed (value);
api_value = g_value_array_get_nth (meta, index);
if (api_value)
ret = g_value_get_string (api_value);
}
return ret;
}

View file

@ -31,6 +31,7 @@
#include <gst/gstminiobject.h>
#include <gst/gststructure.h>
#include <gst/gstformat.h>
#include <gst/gstpad.h>
G_BEGIN_DECLS
@ -51,6 +52,7 @@ G_BEGIN_DECLS
* @GST_QUERY_CUSTOM: a custom application or element defined query. Since
* 0.10.22.
* @GST_QUERY_URI: query the URI of the source or sink. Since 0.10.22.
* @GST_QUERY_TRANSPORT: the buffer allocation properties
*
* Standard predefined Query types
*/
@ -69,7 +71,8 @@ typedef enum {
GST_QUERY_FORMATS,
GST_QUERY_BUFFERING,
GST_QUERY_CUSTOM,
GST_QUERY_URI
GST_QUERY_URI,
GST_QUERY_ALLOCATION
} GstQueryType;
/**
@ -325,6 +328,19 @@ GstQuery * gst_query_new_uri (void);
void gst_query_parse_uri (GstQuery *query, gchar **uri);
void gst_query_set_uri (GstQuery *query, const gchar *uri);
/* allocation query */
GstQuery * gst_query_new_alloction (GstCaps *caps, gboolean need_pool);
void gst_query_set_allocation (GstQuery *query, guint alignment, guint prefix,
guint size, GstBufferPool *pool);
void gst_query_parse_allocation (GstQuery *query, guint *alignment, guint *prefix,
guint *size, GstBufferPool **pool);
void gst_query_add_allocation_meta (GstQuery *query, const gchar *api);
guint gst_query_get_n_allocation_meta (GstQuery *query);
const gchar * gst_query_parse_allocation_meta (GstQuery *query, guint index);
G_END_DECLS
#endif /* __GST_QUERY_H__ */

View file

@ -827,10 +827,13 @@ EXPORTS
gst_progress_type_get_type
gst_proxy_pad_get_type
gst_qos_type_get_type
gst_query_add_allocation_meta
gst_query_add_buffering_range
gst_query_get_n_allocation_meta
gst_query_get_n_buffering_ranges
gst_query_get_structure
gst_query_get_type
gst_query_new_alloction
gst_query_new_application
gst_query_new_buffering
gst_query_new_convert
@ -841,6 +844,8 @@ EXPORTS
gst_query_new_seeking
gst_query_new_segment
gst_query_new_uri
gst_query_parse_allocation
gst_query_parse_allocation_meta
gst_query_parse_buffering_percent
gst_query_parse_buffering_range
gst_query_parse_buffering_stats
@ -854,6 +859,7 @@ EXPORTS
gst_query_parse_seeking
gst_query_parse_segment
gst_query_parse_uri
gst_query_set_allocation
gst_query_set_buffering_percent
gst_query_set_buffering_range
gst_query_set_buffering_stats