mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-19 07:00:10 -05:00
param: add more generic port params
Remove port properties and replace them with port params. Move the params from the PortInfo to enum_params. Use the Param ranges to specify possible sizes etc.
This commit is contained in:
parent
12effccb06
commit
d1a6d6e03f
37 changed files with 1044 additions and 755 deletions
|
|
@ -76,6 +76,8 @@ typedef struct {
|
|||
SpaFormat *format;
|
||||
uint32_t n_formats;
|
||||
SpaFormat **formats;
|
||||
uint32_t n_params;
|
||||
SpaParam **params;
|
||||
SpaPortIO *io;
|
||||
|
||||
uint32_t n_buffers;
|
||||
|
|
@ -306,7 +308,8 @@ do_update_port (SpaProxy *this,
|
|||
uint32_t n_possible_formats,
|
||||
const SpaFormat **possible_formats,
|
||||
const SpaFormat *format,
|
||||
const SpaProps *props,
|
||||
uint32_t n_params,
|
||||
const SpaParam **params,
|
||||
const SpaPortInfo *info)
|
||||
{
|
||||
SpaProxyPort *port;
|
||||
|
|
@ -332,20 +335,17 @@ do_update_port (SpaProxy *this,
|
|||
port->format = spa_format_copy (format);
|
||||
}
|
||||
|
||||
if (change_mask & PINOS_MESSAGE_PORT_UPDATE_PROPS) {
|
||||
if (change_mask & PINOS_MESSAGE_PORT_UPDATE_PARAMS) {
|
||||
for (i = 0; i < port->n_params; i++)
|
||||
free (port->params[i]);
|
||||
port->n_params = n_params;
|
||||
port->params = realloc (port->params, port->n_params * sizeof (SpaParam *));
|
||||
for (i = 0; i < port->n_params; i++)
|
||||
port->params[i] = spa_param_copy (params[i]);
|
||||
}
|
||||
|
||||
if (change_mask & PINOS_MESSAGE_PORT_UPDATE_INFO && info) {
|
||||
void *old;
|
||||
for (i = 0; i < port->info.n_params; i++)
|
||||
free (port->info.params[i]);
|
||||
old = port->info.params;
|
||||
if (change_mask & PINOS_MESSAGE_PORT_UPDATE_INFO && info)
|
||||
port->info = *info;
|
||||
port->info.params = realloc (old, port->info.n_params * sizeof (SpaAllocParam *));
|
||||
for (i = 0; i < port->info.n_params; i++)
|
||||
port->info.params[i] = spa_alloc_param_copy (info->params[i]);
|
||||
port->info.extra = NULL;
|
||||
}
|
||||
|
||||
if (!port->valid) {
|
||||
spa_log_info (this->log, "proxy %p: adding port %d", this, port_id);
|
||||
|
|
@ -370,11 +370,12 @@ clear_port (SpaProxy *this,
|
|||
port_id,
|
||||
PINOS_MESSAGE_PORT_UPDATE_POSSIBLE_FORMATS |
|
||||
PINOS_MESSAGE_PORT_UPDATE_FORMAT |
|
||||
PINOS_MESSAGE_PORT_UPDATE_PROPS |
|
||||
PINOS_MESSAGE_PORT_UPDATE_PARAMS |
|
||||
PINOS_MESSAGE_PORT_UPDATE_INFO,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
clear_buffers (this, port);
|
||||
|
|
@ -566,19 +567,37 @@ spa_proxy_node_port_get_info (SpaNode *node,
|
|||
}
|
||||
|
||||
static SpaResult
|
||||
spa_proxy_node_port_get_props (SpaNode *node,
|
||||
SpaDirection direction,
|
||||
uint32_t port_id,
|
||||
SpaProps **props)
|
||||
spa_proxy_node_port_enum_params (SpaNode *node,
|
||||
SpaDirection direction,
|
||||
uint32_t port_id,
|
||||
uint32_t index,
|
||||
SpaParam **param)
|
||||
{
|
||||
return SPA_RESULT_NOT_IMPLEMENTED;
|
||||
SpaProxy *this;
|
||||
SpaProxyPort *port;
|
||||
|
||||
spa_return_val_if_fail (node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
|
||||
spa_return_val_if_fail (param != NULL, SPA_RESULT_INVALID_ARGUMENTS);
|
||||
|
||||
this = SPA_CONTAINER_OF (node, SpaProxy, node);
|
||||
|
||||
spa_return_val_if_fail (CHECK_PORT (this, direction, port_id), SPA_RESULT_INVALID_PORT);
|
||||
|
||||
port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
|
||||
|
||||
if (index >= port->n_params)
|
||||
return SPA_RESULT_ENUM_END;
|
||||
|
||||
*param = port->params[index];
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static SpaResult
|
||||
spa_proxy_node_port_set_props (SpaNode *node,
|
||||
spa_proxy_node_port_set_param (SpaNode *node,
|
||||
SpaDirection direction,
|
||||
uint32_t port_id,
|
||||
const SpaProps *props)
|
||||
const SpaParam *param)
|
||||
{
|
||||
return SPA_RESULT_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
|
@ -726,7 +745,7 @@ static SpaResult
|
|||
spa_proxy_node_port_alloc_buffers (SpaNode *node,
|
||||
SpaDirection direction,
|
||||
uint32_t port_id,
|
||||
SpaAllocParam **params,
|
||||
SpaParam **params,
|
||||
uint32_t n_params,
|
||||
SpaBuffer **buffers,
|
||||
uint32_t *n_buffers)
|
||||
|
|
@ -927,7 +946,8 @@ client_node_port_update (void *object,
|
|||
uint32_t n_possible_formats,
|
||||
const SpaFormat **possible_formats,
|
||||
const SpaFormat *format,
|
||||
const SpaProps *props,
|
||||
uint32_t n_params,
|
||||
const SpaParam **params,
|
||||
const SpaPortInfo *info)
|
||||
{
|
||||
PinosResource *resource = object;
|
||||
|
|
@ -952,7 +972,8 @@ client_node_port_update (void *object,
|
|||
n_possible_formats,
|
||||
possible_formats,
|
||||
format,
|
||||
props,
|
||||
n_params,
|
||||
params,
|
||||
info);
|
||||
}
|
||||
}
|
||||
|
|
@ -1024,8 +1045,8 @@ static const SpaNode proxy_node = {
|
|||
spa_proxy_node_port_set_format,
|
||||
spa_proxy_node_port_get_format,
|
||||
spa_proxy_node_port_get_info,
|
||||
spa_proxy_node_port_get_props,
|
||||
spa_proxy_node_port_set_props,
|
||||
spa_proxy_node_port_enum_params,
|
||||
spa_proxy_node_port_set_param,
|
||||
spa_proxy_node_port_use_buffers,
|
||||
spa_proxy_node_port_alloc_buffers,
|
||||
spa_proxy_node_port_set_io,
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@
|
|||
#include <spa/video/format.h>
|
||||
#include <spa/pod-utils.h>
|
||||
|
||||
#include <spa/lib/props.h>
|
||||
|
||||
#include "pinos/client/pinos.h"
|
||||
#include "pinos/client/interfaces.h"
|
||||
|
||||
|
|
@ -190,33 +192,33 @@ error:
|
|||
}
|
||||
}
|
||||
|
||||
static void *
|
||||
find_param (const SpaPortInfo *info, uint32_t type)
|
||||
static SpaParam *
|
||||
find_param (SpaParam **params, int n_params, uint32_t type)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < info->n_params; i++) {
|
||||
if (spa_pod_is_object_type (&info->params[i]->pod, type))
|
||||
return info->params[i];
|
||||
for (i = 0; i < n_params; i++) {
|
||||
if (spa_pod_is_object_type (¶ms[i]->pod, type))
|
||||
return params[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *
|
||||
find_meta_enable (PinosCore *core, const SpaPortInfo *info, uint32_t type)
|
||||
static SpaParam *
|
||||
find_meta_enable (PinosCore *core, SpaParam **params, int n_params, uint32_t type)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < info->n_params; i++) {
|
||||
if (spa_pod_is_object_type (&info->params[i]->pod, core->type.alloc_param_meta_enable.MetaEnable)) {
|
||||
for (i = 0; i < n_params; i++) {
|
||||
if (spa_pod_is_object_type (¶ms[i]->pod, core->type.param_alloc_meta_enable.MetaEnable)) {
|
||||
uint32_t qtype;
|
||||
|
||||
if (spa_alloc_param_query (info->params[i],
|
||||
core->type.alloc_param_meta_enable.type, SPA_POD_TYPE_ID, &qtype, 0) != 1)
|
||||
if (spa_param_query (params[i],
|
||||
core->type.param_alloc_meta_enable.type, SPA_POD_TYPE_ID, &qtype, 0) != 1)
|
||||
continue;
|
||||
|
||||
if (qtype == type)
|
||||
return info->params[i];
|
||||
return params[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
|
@ -226,7 +228,7 @@ static SpaBuffer **
|
|||
alloc_buffers (PinosLink *this,
|
||||
uint32_t n_buffers,
|
||||
uint32_t n_params,
|
||||
SpaAllocParam **params,
|
||||
SpaParam **params,
|
||||
uint32_t n_datas,
|
||||
size_t *data_sizes,
|
||||
ssize_t *data_strides,
|
||||
|
|
@ -256,17 +258,17 @@ alloc_buffers (PinosLink *this,
|
|||
|
||||
/* collect metadata */
|
||||
for (i = 0; i < n_params; i++) {
|
||||
SpaAllocParam *ap = params[i];
|
||||
|
||||
if (ap->pod.type == this->core->type.alloc_param_meta_enable.MetaEnable) {
|
||||
if (spa_pod_is_object_type (¶ms[i]->pod, this->core->type.param_alloc_meta_enable.MetaEnable)) {
|
||||
uint32_t type, size;
|
||||
|
||||
if (spa_alloc_param_query (ap,
|
||||
this->core->type.alloc_param_meta_enable.type, SPA_POD_TYPE_ID, &type,
|
||||
this->core->type.alloc_param_meta_enable.size, SPA_POD_TYPE_INT, &size,
|
||||
0) != 1)
|
||||
if (spa_param_query (params[i],
|
||||
this->core->type.param_alloc_meta_enable.type, SPA_POD_TYPE_ID, &type,
|
||||
this->core->type.param_alloc_meta_enable.size, SPA_POD_TYPE_INT, &size,
|
||||
0) != 2)
|
||||
continue;
|
||||
|
||||
pinos_log_debug ("link %p: enable meta %d %d", this, type, size);
|
||||
|
||||
metas[n_metas].type = type;
|
||||
metas[n_metas].size = size;
|
||||
meta_size += metas[n_metas].size;
|
||||
|
|
@ -358,6 +360,56 @@ alloc_buffers (PinosLink *this,
|
|||
return buffers;
|
||||
}
|
||||
|
||||
static int
|
||||
spa_node_param_filter (PinosLink *this,
|
||||
SpaNode *in_node,
|
||||
uint32_t in_port,
|
||||
SpaNode *out_node,
|
||||
uint32_t out_port,
|
||||
SpaPODBuilder *result)
|
||||
{
|
||||
SpaResult res;
|
||||
SpaParam *oparam, *iparam;
|
||||
int iidx, oidx, num = 0;
|
||||
|
||||
for (iidx = 0; ; iidx++) {
|
||||
if (spa_node_port_enum_params (in_node, SPA_DIRECTION_INPUT, in_port, iidx, &iparam) < 0)
|
||||
break;
|
||||
|
||||
if (pinos_log_level_enabled (SPA_LOG_LEVEL_DEBUG))
|
||||
spa_debug_param (iparam, this->core->type.map);
|
||||
|
||||
for (oidx = 0; ; oidx++) {
|
||||
SpaPODFrame f;
|
||||
uint32_t offset;
|
||||
|
||||
if (spa_node_port_enum_params (out_node, SPA_DIRECTION_OUTPUT, out_port, oidx, &oparam) < 0)
|
||||
break;
|
||||
|
||||
if (pinos_log_level_enabled (SPA_LOG_LEVEL_DEBUG))
|
||||
spa_debug_param (oparam, this->core->type.map);
|
||||
|
||||
if (iparam->body.body.type != oparam->body.body.type)
|
||||
continue;
|
||||
|
||||
offset = result->offset;
|
||||
spa_pod_builder_push_object (result, &f, 0, iparam->body.body.type);
|
||||
if ((res = spa_props_filter (result,
|
||||
SPA_POD_CONTENTS (SpaParam, iparam),
|
||||
SPA_POD_CONTENTS_SIZE (SpaParam, iparam),
|
||||
SPA_POD_CONTENTS (SpaParam, oparam),
|
||||
SPA_POD_CONTENTS_SIZE (SpaParam, oparam))) < 0) {
|
||||
result->offset = offset;
|
||||
result->stack = NULL;
|
||||
continue;
|
||||
}
|
||||
spa_pod_builder_pop (result, &f);
|
||||
num++;
|
||||
}
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
static SpaResult
|
||||
do_allocation (PinosLink *this, uint32_t in_state, uint32_t out_state)
|
||||
{
|
||||
|
|
@ -437,55 +489,54 @@ do_allocation (PinosLink *this, uint32_t in_state, uint32_t out_state)
|
|||
}
|
||||
|
||||
if (impl->buffers == NULL) {
|
||||
SpaAllocParam *in_alloc, *out_alloc;
|
||||
SpaAllocParam *in_me, *out_me;
|
||||
SpaParam **params, *param;
|
||||
uint8_t buffer[4096];
|
||||
SpaPODBuilder b = SPA_POD_BUILDER_INIT (buffer, sizeof (buffer));
|
||||
int i, offset, n_params;
|
||||
uint32_t max_buffers;
|
||||
size_t minsize = 1024, stride = 0;
|
||||
|
||||
in_me = find_meta_enable (this->core, iinfo, this->core->type.meta.Ringbuffer);
|
||||
out_me = find_meta_enable (this->core, oinfo, this->core->type.meta.Ringbuffer);
|
||||
if (in_me && out_me) {
|
||||
uint32_t ms1, ms2, s1, s2;
|
||||
n_params = spa_node_param_filter (this,
|
||||
this->input->node->node,
|
||||
this->input->port_id,
|
||||
this->output->node->node,
|
||||
this->output->port_id,
|
||||
&b);
|
||||
|
||||
params = alloca (n_params * sizeof (SpaParam *));
|
||||
for (i = 0, offset = 0; i < n_params; i++) {
|
||||
params[i] = SPA_MEMBER (buffer, offset, SpaParam);
|
||||
spa_param_fixate (params[i]);
|
||||
spa_debug_param (params[i], this->core->type.map);
|
||||
offset += SPA_ROUND_UP_N (SPA_POD_SIZE (params[i]), 8);
|
||||
}
|
||||
|
||||
param = find_meta_enable (this->core, params, n_params,
|
||||
this->core->type.meta.Ringbuffer);
|
||||
if (param) {
|
||||
uint32_t ms, s;
|
||||
max_buffers = 1;
|
||||
|
||||
if (spa_alloc_param_query (in_me,
|
||||
this->core->type.alloc_param_meta_enable.ringbufferSize, SPA_POD_TYPE_INT, &ms1,
|
||||
this->core->type.alloc_param_meta_enable.ringbufferStride, SPA_POD_TYPE_INT, &s1, 0) == 2 &&
|
||||
spa_alloc_param_query (in_me,
|
||||
this->core->type.alloc_param_meta_enable.ringbufferSize, SPA_POD_TYPE_INT, &ms2,
|
||||
this->core->type.alloc_param_meta_enable.ringbufferStride, SPA_POD_TYPE_INT, &s2, 0) == 2) {
|
||||
minsize = SPA_MAX (ms1, ms2);
|
||||
stride = SPA_MAX (s1, s2);
|
||||
if (spa_param_query (param,
|
||||
this->core->type.param_alloc_meta_enable.ringbufferSize, SPA_POD_TYPE_INT, &ms,
|
||||
this->core->type.param_alloc_meta_enable.ringbufferStride, SPA_POD_TYPE_INT, &s, 0) == 2) {
|
||||
minsize = ms;
|
||||
stride = s;
|
||||
}
|
||||
} else {
|
||||
max_buffers = MAX_BUFFERS;
|
||||
minsize = stride = 0;
|
||||
in_alloc = find_param (iinfo, this->core->type.alloc_param_buffers.Buffers);
|
||||
if (in_alloc) {
|
||||
param = find_param (params, n_params,
|
||||
this->core->type.param_alloc_buffers.Buffers);
|
||||
if (param) {
|
||||
uint32_t qmax_buffers = max_buffers,
|
||||
qminsize = minsize,
|
||||
qstride = stride;
|
||||
|
||||
spa_alloc_param_query (in_alloc,
|
||||
this->core->type.alloc_param_buffers.size, SPA_POD_TYPE_INT, &qminsize,
|
||||
this->core->type.alloc_param_buffers.stride, SPA_POD_TYPE_INT, &qstride,
|
||||
this->core->type.alloc_param_buffers.buffers, SPA_POD_TYPE_INT, &qmax_buffers,
|
||||
0);
|
||||
|
||||
max_buffers = qmax_buffers == 0 ? max_buffers : SPA_MIN (qmax_buffers, max_buffers);
|
||||
minsize = SPA_MAX (minsize, qminsize);
|
||||
stride = SPA_MAX (stride, qstride);
|
||||
}
|
||||
out_alloc = find_param (oinfo, this->core->type.alloc_param_buffers.Buffers);
|
||||
if (out_alloc) {
|
||||
uint32_t qmax_buffers = max_buffers,
|
||||
qminsize = minsize,
|
||||
qstride = stride;
|
||||
|
||||
spa_alloc_param_query (out_alloc,
|
||||
this->core->type.alloc_param_buffers.size, SPA_POD_TYPE_INT, &qminsize,
|
||||
this->core->type.alloc_param_buffers.stride, SPA_POD_TYPE_INT, &qstride,
|
||||
this->core->type.alloc_param_buffers.buffers, SPA_POD_TYPE_INT, &qmax_buffers,
|
||||
spa_param_query (param,
|
||||
this->core->type.param_alloc_buffers.size, SPA_POD_TYPE_INT, &qminsize,
|
||||
this->core->type.param_alloc_buffers.stride, SPA_POD_TYPE_INT, &qstride,
|
||||
this->core->type.param_alloc_buffers.buffers, SPA_POD_TYPE_INT, &qmax_buffers,
|
||||
0);
|
||||
|
||||
max_buffers = qmax_buffers == 0 ? max_buffers : SPA_MIN (qmax_buffers, max_buffers);
|
||||
|
|
@ -523,8 +574,8 @@ do_allocation (PinosLink *this, uint32_t in_state, uint32_t out_state)
|
|||
impl->n_buffers = max_buffers;
|
||||
impl->buffers = alloc_buffers (this,
|
||||
impl->n_buffers,
|
||||
oinfo->n_params,
|
||||
oinfo->params,
|
||||
n_params,
|
||||
params,
|
||||
1,
|
||||
data_sizes,
|
||||
data_strides,
|
||||
|
|
@ -537,7 +588,7 @@ do_allocation (PinosLink *this, uint32_t in_state, uint32_t out_state)
|
|||
if ((res = spa_node_port_alloc_buffers (this->output->node->node,
|
||||
SPA_DIRECTION_OUTPUT,
|
||||
this->output->port_id,
|
||||
iinfo->params, iinfo->n_params,
|
||||
params, n_params,
|
||||
impl->buffers, &impl->n_buffers)) < 0) {
|
||||
asprintf (&error, "error alloc output buffers: %d", res);
|
||||
goto error;
|
||||
|
|
@ -553,7 +604,7 @@ do_allocation (PinosLink *this, uint32_t in_state, uint32_t out_state)
|
|||
if ((res = spa_node_port_alloc_buffers (this->input->node->node,
|
||||
SPA_DIRECTION_INPUT,
|
||||
this->input->port_id,
|
||||
oinfo->params, oinfo->n_params,
|
||||
params, n_params,
|
||||
impl->buffers, &impl->n_buffers)) < 0) {
|
||||
asprintf (&error, "error alloc input buffers: %d", res);
|
||||
goto error;
|
||||
|
|
|
|||
|
|
@ -829,8 +829,8 @@ client_node_demarshal_port_update (void *object,
|
|||
{
|
||||
PinosResource *resource = object;
|
||||
SpaPODIter it;
|
||||
uint32_t i, direction, port_id, change_mask, n_possible_formats;
|
||||
const SpaProps *props = NULL;
|
||||
uint32_t i, direction, port_id, change_mask, n_possible_formats, n_params;
|
||||
const SpaParam **params = NULL;
|
||||
const SpaFormat **possible_formats = NULL, *format = NULL;
|
||||
SpaPortInfo info, *infop = NULL;
|
||||
SpaPOD *ipod;
|
||||
|
|
@ -852,13 +852,21 @@ client_node_demarshal_port_update (void *object,
|
|||
|
||||
if (!spa_pod_iter_get (&it,
|
||||
-SPA_POD_TYPE_OBJECT, &format,
|
||||
-SPA_POD_TYPE_OBJECT, &props,
|
||||
SPA_POD_TYPE_INT, &n_params,
|
||||
0))
|
||||
return false;
|
||||
|
||||
params = alloca (n_params * sizeof (SpaParam*));
|
||||
for (i = 0; i < n_params; i++)
|
||||
if (!spa_pod_iter_get (&it, SPA_POD_TYPE_OBJECT, ¶ms[i], 0))
|
||||
return false;
|
||||
|
||||
if (!spa_pod_iter_get (&it,
|
||||
-SPA_POD_TYPE_STRUCT, &ipod,
|
||||
0))
|
||||
return false;
|
||||
|
||||
if (ipod) {
|
||||
SpaDict dict;
|
||||
SpaPODIter it2;
|
||||
infop = &info;
|
||||
|
||||
|
|
@ -866,29 +874,8 @@ client_node_demarshal_port_update (void *object,
|
|||
!spa_pod_iter_get (&it2,
|
||||
SPA_POD_TYPE_INT, &info.flags,
|
||||
SPA_POD_TYPE_INT, &info.rate,
|
||||
SPA_POD_TYPE_LONG, &info.maxbuffering,
|
||||
SPA_POD_TYPE_LONG, &info.latency,
|
||||
SPA_POD_TYPE_INT, &info.n_params,
|
||||
0))
|
||||
return false;
|
||||
|
||||
info.params = alloca (info.n_params * sizeof (SpaAllocParam *));
|
||||
for (i = 0; i < info.n_params; i++)
|
||||
if (!spa_pod_iter_get (&it2, SPA_POD_TYPE_OBJECT, &info.params[i], 0))
|
||||
return false;
|
||||
|
||||
if (!spa_pod_iter_get (&it2, SPA_POD_TYPE_INT, &dict.n_items, 0))
|
||||
return false;
|
||||
|
||||
info.extra = &dict;
|
||||
dict.items = alloca (dict.n_items * sizeof (SpaDictItem));
|
||||
for (i = 0; i < dict.n_items; i++) {
|
||||
if (!spa_pod_iter_get (&it2,
|
||||
SPA_POD_TYPE_STRING, &dict.items[i].key,
|
||||
SPA_POD_TYPE_STRING, &dict.items[i].value,
|
||||
0))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
((PinosClientNodeMethods*)resource->implementation)->port_update (resource,
|
||||
|
|
@ -898,7 +885,8 @@ client_node_demarshal_port_update (void *object,
|
|||
n_possible_formats,
|
||||
possible_formats,
|
||||
format,
|
||||
props,
|
||||
n_params,
|
||||
params,
|
||||
infop);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue