From 986de92521cf5533c77a7041b9e938ec35fc9b45 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 2 Apr 2024 12:05:12 +0200 Subject: [PATCH] buffers: add support for mandatory metadata Add a SPA_PARAM_BUFFERS_metaType in the Buffers object. This contains a bitmask of the mandatory metadata items that should be included on a buffer when using this Buffers param. Make the buffer allocation logic skip over the Buffers params that require unavailable metadata. This can be used to, for example, enforce specific metadata to describe extra buffer memory (such as the meaning of generic file descriptors). One such use is the explicit sync, where an extra buffer data is needed for the sync fd along with metadata that contains the sync_point. --- spa/include/spa/param/buffers-types.h | 1 + spa/include/spa/param/buffers.h | 3 ++- src/pipewire/buffers.c | 12 +++++++++--- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/spa/include/spa/param/buffers-types.h b/spa/include/spa/param/buffers-types.h index 90983a905..4ca45cb02 100644 --- a/spa/include/spa/param/buffers-types.h +++ b/spa/include/spa/param/buffers-types.h @@ -56,6 +56,7 @@ static const struct spa_type_info spa_type_param_buffers[] = { { SPA_PARAM_BUFFERS_stride, SPA_TYPE_Int, SPA_TYPE_INFO_PARAM_BLOCK_INFO_BASE "stride", NULL }, { SPA_PARAM_BUFFERS_align, SPA_TYPE_Int, SPA_TYPE_INFO_PARAM_BLOCK_INFO_BASE "align", NULL }, { SPA_PARAM_BUFFERS_dataType, SPA_TYPE_Int, SPA_TYPE_INFO_PARAM_BLOCK_INFO_BASE "dataType", NULL }, + { SPA_PARAM_BUFFERS_metaType, SPA_TYPE_Int, SPA_TYPE_INFO_PARAM_BLOCK_INFO_BASE "metaType", NULL }, { 0, 0, NULL, NULL }, }; diff --git a/spa/include/spa/param/buffers.h b/spa/include/spa/param/buffers.h index 399d3a5f0..87b531dd8 100644 --- a/spa/include/spa/param/buffers.h +++ b/spa/include/spa/param/buffers.h @@ -24,7 +24,8 @@ enum spa_param_buffers { SPA_PARAM_BUFFERS_size, /**< size of a data block memory (Int)*/ SPA_PARAM_BUFFERS_stride, /**< stride of data block memory (Int) */ SPA_PARAM_BUFFERS_align, /**< alignment of data block memory (Int) */ - SPA_PARAM_BUFFERS_dataType, /**< possible memory types (Int, mask of enum spa_data_type) */ + SPA_PARAM_BUFFERS_dataType, /**< possible memory types (flags choice Int, mask of enum spa_data_type) */ + SPA_PARAM_BUFFERS_metaType, /**< required meta data types (Int, mask of enum spa_meta_type) */ }; /** properties for SPA_TYPE_OBJECT_ParamMeta */ diff --git a/src/pipewire/buffers.c b/src/pipewire/buffers.c index c2f06bb4a..96531b9b9 100644 --- a/src/pipewire/buffers.c +++ b/src/pipewire/buffers.c @@ -187,7 +187,7 @@ int pw_buffers_negotiate(struct pw_context *context, uint32_t flags, struct spa_pod **params; uint8_t buffer[4096]; struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer)); - uint32_t i, offset, n_params, n_metas; + uint32_t i, j, offset, n_params, n_metas; struct spa_meta *metas; uint32_t max_buffers, blocks; size_t minsize, stride, align; @@ -264,10 +264,11 @@ int pw_buffers_negotiate(struct pw_context *context, uint32_t flags, for (i = 0; i < n_params; i++) { uint32_t qmax_buffers = max_buffers, qminsize = minsize, qstride = stride, qalign = align; - uint32_t qtypes = types, qblocks = blocks; + uint32_t qtypes = types, qblocks = blocks, qmetas = 0; if (!spa_pod_is_object_type (params[i], SPA_TYPE_OBJECT_ParamBuffers)) continue; + if (spa_pod_parse_object(params[i], SPA_TYPE_OBJECT_ParamBuffers, NULL, SPA_PARAM_BUFFERS_buffers, SPA_POD_OPT_Int(&qmax_buffers), @@ -275,10 +276,15 @@ int pw_buffers_negotiate(struct pw_context *context, uint32_t flags, SPA_PARAM_BUFFERS_size, SPA_POD_OPT_Int(&qminsize), SPA_PARAM_BUFFERS_stride, SPA_POD_OPT_Int(&qstride), SPA_PARAM_BUFFERS_align, SPA_POD_OPT_Int(&qalign), - SPA_PARAM_BUFFERS_dataType, SPA_POD_OPT_Int(&qtypes)) < 0) { + SPA_PARAM_BUFFERS_dataType, SPA_POD_OPT_Int(&qtypes), + SPA_PARAM_BUFFERS_metaType, SPA_POD_OPT_Int(&qmetas)) < 0) { pw_log_warn("%p: invalid Buffers param", result); continue; } + for (j = 0; qmetas != 0 && j < n_metas; j++) + SPA_FLAG_CLEAR(qmetas, 1<