buffers: add support for multiple data blocks

Support multiple data blocks in a buffer.
This commit is contained in:
Wim Taymans 2020-06-04 12:31:17 +02:00
parent 704d504a44
commit f1e7e86bee

View file

@ -39,6 +39,7 @@
#define NAME "buffers" #define NAME "buffers"
#define MAX_ALIGN 32 #define MAX_ALIGN 32
#define MAX_BLOCKS 4
struct port { struct port {
struct spa_node *node; struct spa_node *node;
@ -240,12 +241,12 @@ int pw_buffers_negotiate(struct pw_context *context, uint32_t flags,
uint8_t buffer[4096]; uint8_t buffer[4096];
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer)); struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
uint32_t i, offset, n_params; uint32_t i, offset, n_params;
uint32_t max_buffers; uint32_t max_buffers, blocks;
size_t minsize, stride, align; size_t minsize, stride, align;
uint32_t data_sizes[1]; uint32_t *data_sizes;
int32_t data_strides[1]; int32_t *data_strides;
uint32_t data_aligns[1]; uint32_t *data_aligns;
uint32_t types, data_types[1]; uint32_t types, *data_types;
struct port output = { outnode, SPA_DIRECTION_OUTPUT, out_port_id }; struct port output = { outnode, SPA_DIRECTION_OUTPUT, out_port_id };
struct port input = { innode, SPA_DIRECTION_INPUT, in_port_id }; struct port input = { innode, SPA_DIRECTION_INPUT, in_port_id };
const char *str; const char *str;
@ -283,16 +284,18 @@ int pw_buffers_negotiate(struct pw_context *context, uint32_t flags,
minsize = stride = 0; minsize = stride = 0;
types = SPA_ID_INVALID; /* bitmask of allowed types */ types = SPA_ID_INVALID; /* bitmask of allowed types */
blocks = 1;
param = find_param(params, n_params, SPA_TYPE_OBJECT_ParamBuffers); param = find_param(params, n_params, SPA_TYPE_OBJECT_ParamBuffers);
if (param) { if (param) {
uint32_t qmax_buffers = max_buffers, uint32_t qmax_buffers = max_buffers,
qminsize = minsize, qstride = stride, qalign = align; qminsize = minsize, qstride = stride, qalign = align;
uint32_t qtypes = types; uint32_t qtypes = types, qblocks = blocks;
spa_pod_parse_object(param, spa_pod_parse_object(param,
SPA_TYPE_OBJECT_ParamBuffers, NULL, SPA_TYPE_OBJECT_ParamBuffers, NULL,
SPA_PARAM_BUFFERS_buffers, SPA_POD_OPT_Int(&qmax_buffers), SPA_PARAM_BUFFERS_buffers, SPA_POD_OPT_Int(&qmax_buffers),
SPA_PARAM_BUFFERS_blocks, SPA_POD_OPT_Int(&qblocks),
SPA_PARAM_BUFFERS_size, SPA_POD_OPT_Int(&qminsize), SPA_PARAM_BUFFERS_size, SPA_POD_OPT_Int(&qminsize),
SPA_PARAM_BUFFERS_stride, SPA_POD_OPT_Int(&qstride), SPA_PARAM_BUFFERS_stride, SPA_POD_OPT_Int(&qstride),
SPA_PARAM_BUFFERS_align, SPA_POD_OPT_Int(&qalign), SPA_PARAM_BUFFERS_align, SPA_POD_OPT_Int(&qalign),
@ -301,14 +304,15 @@ int pw_buffers_negotiate(struct pw_context *context, uint32_t flags,
max_buffers = max_buffers =
qmax_buffers == 0 ? max_buffers : SPA_MIN(qmax_buffers, qmax_buffers == 0 ? max_buffers : SPA_MIN(qmax_buffers,
max_buffers); max_buffers);
blocks = SPA_CLAMP(qblocks, blocks, MAX_BLOCKS);
minsize = SPA_MAX(minsize, qminsize); minsize = SPA_MAX(minsize, qminsize);
stride = SPA_MAX(stride, qstride); stride = SPA_MAX(stride, qstride);
align = SPA_MAX(align, qalign); align = SPA_MAX(align, qalign);
types = qtypes; types = qtypes;
pw_log_debug(NAME" %p: %d %d %d %d %d -> %zd %zd %d %zd %d", result, pw_log_debug(NAME" %p: %d %d %d %d %d %d -> %d %zd %zd %d %zd %d", result,
qminsize, qstride, qmax_buffers, qalign, qtypes, qblocks, qminsize, qstride, qmax_buffers, qalign, qtypes,
minsize, stride, max_buffers, align, types); blocks, minsize, stride, max_buffers, align, types);
} else { } else {
pw_log_warn(NAME" %p: no buffers param", result); pw_log_warn(NAME" %p: no buffers param", result);
minsize = 8192; minsize = 8192;
@ -318,16 +322,23 @@ int pw_buffers_negotiate(struct pw_context *context, uint32_t flags,
if (SPA_FLAG_IS_SET(flags, PW_BUFFERS_FLAG_NO_MEM)) if (SPA_FLAG_IS_SET(flags, PW_BUFFERS_FLAG_NO_MEM))
minsize = 0; minsize = 0;
data_sizes[0] = minsize; data_sizes = alloca(sizeof(uint32_t) * blocks);
data_strides[0] = stride; data_strides = alloca(sizeof(int32_t) * blocks);
data_aligns[0] = align; data_aligns = alloca(sizeof(uint32_t) * blocks);
data_types[0] = types; data_types = alloca(sizeof(uint32_t) * blocks);
for (i = 0; i < blocks; i++) {
data_sizes[i] = minsize;
data_strides[i] = stride;
data_aligns[i] = align;
data_types[i] = types;
}
if ((res = alloc_buffers(context->pool, if ((res = alloc_buffers(context->pool,
max_buffers, max_buffers,
n_params, n_params,
params, params,
1, blocks,
data_sizes, data_strides, data_sizes, data_strides,
data_aligns, data_types, data_aligns, data_types,
flags, flags,