mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-12-15 08:56:38 -05:00
param-io: work on IO parameters
Reorganize the io parameter ids and objects. Make separate enumerations for buffer, control, input and output properties. Add a volume output property to export-source. This is still unused but will eventually be routed to a PropsIn io area where it can control the volume of a mixer, for example.
This commit is contained in:
parent
ada3698355
commit
425073afd8
12 changed files with 240 additions and 124 deletions
|
|
@ -34,13 +34,9 @@ extern "C" {
|
|||
#define SPA_TYPE_IO__Control SPA_TYPE_IO_BASE "Control"
|
||||
#define SPA_TYPE_IO_CONTROL_BASE SPA_TYPE_IO__Control ":"
|
||||
|
||||
/** Base for controlable input properties */
|
||||
#define SPA_TYPE_IO__InputProp SPA_TYPE_IO_BASE "InputProp"
|
||||
#define SPA_TYPE_IO_INPUT_PROP_BASE SPA_TYPE_IO__InputProp ":"
|
||||
|
||||
/** Base for controlable output properties */
|
||||
#define SPA_TYPE_IO__OutputProp SPA_TYPE_IO_BASE "OutputProp"
|
||||
#define SPA_TYPE_IO_OUTPUT_PROP_BASE SPA_TYPE_IO__OutputProp ":"
|
||||
/** Base for controlable properties */
|
||||
#define SPA_TYPE_IO__Prop SPA_TYPE_IO_BASE "Prop"
|
||||
#define SPA_TYPE_IO_PROP_BASE SPA_TYPE_IO__Prop ":"
|
||||
|
||||
/** An io area to exchange buffers with a port */
|
||||
#define SPA_TYPE_IO__Buffers SPA_TYPE_IO_BASE "Buffers"
|
||||
|
|
@ -76,8 +72,7 @@ struct spa_io_control_range {
|
|||
struct spa_type_io {
|
||||
uint32_t Buffers;
|
||||
uint32_t ControlRange;
|
||||
uint32_t InputProp;
|
||||
uint32_t OutputProp;
|
||||
uint32_t Prop;
|
||||
};
|
||||
|
||||
static inline void spa_type_io_map(struct spa_type_map *map, struct spa_type_io *type)
|
||||
|
|
@ -85,8 +80,7 @@ static inline void spa_type_io_map(struct spa_type_map *map, struct spa_type_io
|
|||
if (type->Buffers == 0) {
|
||||
type->Buffers = spa_type_map_get_id(map, SPA_TYPE_IO__Buffers);
|
||||
type->ControlRange = spa_type_map_get_id(map, SPA_TYPE_IO_CONTROL__Range);
|
||||
type->InputProp = spa_type_map_get_id(map, SPA_TYPE_IO__InputProp);
|
||||
type->OutputProp = spa_type_map_get_id(map, SPA_TYPE_IO__OutputProp);
|
||||
type->Prop = spa_type_map_get_id(map, SPA_TYPE_IO__Prop);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,11 +48,11 @@ struct spa_port_info {
|
|||
#define SPA_PORT_INFO_FLAG_OPTIONAL (1<<1) /**< processing on port is optional */
|
||||
#define SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS (1<<2) /**< the port can allocate buffer data */
|
||||
#define SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS (1<<3) /**< the port can use a provided buffer */
|
||||
#define SPA_PORT_INFO_FLAG_IN_PLACE (1<<4) /**< the port can process data in-place and will need
|
||||
* a writable input buffer */
|
||||
#define SPA_PORT_INFO_FLAG_IN_PLACE (1<<4) /**< the port can process data in-place and
|
||||
* will need a writable input buffer */
|
||||
#define SPA_PORT_INFO_FLAG_NO_REF (1<<5) /**< the port does not keep a ref on the buffer */
|
||||
#define SPA_PORT_INFO_FLAG_LIVE (1<<6) /**< output buffers from this port are timestamped against
|
||||
* a live clock. */
|
||||
#define SPA_PORT_INFO_FLAG_LIVE (1<<6) /**< output buffers from this port are
|
||||
* timestamped against a live clock. */
|
||||
uint32_t flags; /**< port flags */
|
||||
uint32_t rate; /**< rate of sequence numbers on port */
|
||||
const struct spa_dict *props; /**< extra port properties */
|
||||
|
|
|
|||
|
|
@ -28,36 +28,69 @@ extern "C" {
|
|||
#include <spa/param/param.h>
|
||||
#include <spa/support/type-map.h>
|
||||
|
||||
#define SPA_TYPE_PARAM__IO SPA_TYPE_PARAM_BASE "IO"
|
||||
#define SPA_TYPE_PARAM_IO_BASE SPA_TYPE_PARAM__IO ":"
|
||||
|
||||
/** type ID of property, uniquely identifies the io area for a port */
|
||||
#define SPA_TYPE_PARAM_IO__id SPA_TYPE_PARAM_IO_BASE "id"
|
||||
/** size of the io area for a port */
|
||||
#define SPA_TYPE_PARAM_IO__size SPA_TYPE_PARAM_IO_BASE "size"
|
||||
|
||||
/** enumerate buffer io areas */
|
||||
#define SPA_TYPE_PARAM_ID_IO__Buffers SPA_TYPE_PARAM_ID_IO_BASE "Buffers"
|
||||
/* an io area to exchange buffers */
|
||||
#define SPA_TYPE_PARAM_IO__Buffers SPA_TYPE_PARAM_IO_BASE "Buffers"
|
||||
|
||||
/** enumerate Control io areas */
|
||||
#define SPA_TYPE_PARAM_ID_IO__Control SPA_TYPE_PARAM_ID_IO_BASE "Control"
|
||||
/* an io area to exchange control information */
|
||||
#define SPA_TYPE_PARAM_IO__Control SPA_TYPE_PARAM_IO_BASE "Control"
|
||||
|
||||
/** enumerate input or output properties */
|
||||
#define SPA_TYPE_PARAM_ID_IO__Props SPA_TYPE_PARAM_ID_IO_BASE "Props"
|
||||
#define SPA_TYPE_PARAM_ID_IO_PROPS_BASE SPA_TYPE_PARAM_ID_IO__Props ":"
|
||||
/** enumerate input property io areas */
|
||||
#define SPA_TYPE_PARAM_ID_IO_PROPS__In SPA_TYPE_PARAM_ID_IO_PROPS_BASE "In"
|
||||
/** enumerate output property io areas */
|
||||
#define SPA_TYPE_PARAM_ID_IO_PROPS__Out SPA_TYPE_PARAM_ID_IO_PROPS_BASE "Out"
|
||||
|
||||
/* an io area to exchange properties */
|
||||
#define SPA_TYPE_PARAM_IO__Prop SPA_TYPE_PARAM_IO_BASE "Prop"
|
||||
#define SPA_TYPE_PARAM_IO_PROP_BASE SPA_TYPE_PARAM_IO__Prop ":"
|
||||
|
||||
/** associated property if any */
|
||||
#define SPA_TYPE_PARAM_IO__propId SPA_TYPE_PARAM_IO_BASE "propId"
|
||||
#define SPA_TYPE_PARAM_IO_PROP__id SPA_TYPE_PARAM_IO_PROP_BASE "id"
|
||||
/** associated type of property if any */
|
||||
#define SPA_TYPE_PARAM_IO__propType SPA_TYPE_PARAM_IO_BASE "propType"
|
||||
#define SPA_TYPE_PARAM_IO_PROP__type SPA_TYPE_PARAM_IO_PROP_BASE "type"
|
||||
|
||||
|
||||
struct spa_type_param_io {
|
||||
uint32_t IO;
|
||||
uint32_t id;
|
||||
uint32_t size;
|
||||
uint32_t propId;
|
||||
uint32_t propType;
|
||||
uint32_t id; /**< id to configure the io area */
|
||||
uint32_t size; /**< size of io area */
|
||||
uint32_t idBuffers; /**< id to enumerate buffer io */
|
||||
uint32_t Buffers; /**< object type of buffer io area */
|
||||
uint32_t idControl; /**< id to enumerate control io */
|
||||
uint32_t Control; /**< object type of Control area */
|
||||
uint32_t idPropsIn; /**< id to enumerate input properties io */
|
||||
uint32_t idPropsOut; /**< id to enumerate output properties io */
|
||||
uint32_t Prop; /**< object type of property area */
|
||||
uint32_t propId; /**< property id */
|
||||
uint32_t propType; /**< property type */
|
||||
};
|
||||
|
||||
static inline void
|
||||
spa_type_param_io_map(struct spa_type_map *map,
|
||||
struct spa_type_param_io *type)
|
||||
{
|
||||
if (type->IO == 0) {
|
||||
type->IO = spa_type_map_get_id(map, SPA_TYPE_PARAM__IO);
|
||||
if (type->id == 0) {
|
||||
type->id = spa_type_map_get_id(map, SPA_TYPE_PARAM_IO__id);
|
||||
type->size = spa_type_map_get_id(map, SPA_TYPE_PARAM_IO__size);
|
||||
type->propId = spa_type_map_get_id(map, SPA_TYPE_PARAM_IO__propId);
|
||||
type->propType = spa_type_map_get_id(map, SPA_TYPE_PARAM_IO__propType);
|
||||
type->idBuffers = spa_type_map_get_id(map, SPA_TYPE_PARAM_ID_IO__Buffers);
|
||||
type->Buffers = spa_type_map_get_id(map, SPA_TYPE_PARAM_IO__Buffers);
|
||||
type->idControl = spa_type_map_get_id(map, SPA_TYPE_PARAM_ID_IO__Control);
|
||||
type->Control = spa_type_map_get_id(map, SPA_TYPE_PARAM_IO__Control);
|
||||
type->idPropsIn = spa_type_map_get_id(map, SPA_TYPE_PARAM_ID_IO_PROPS__In);
|
||||
type->idPropsOut = spa_type_map_get_id(map, SPA_TYPE_PARAM_ID_IO_PROPS__Out);
|
||||
type->Prop = spa_type_map_get_id(map, SPA_TYPE_PARAM_IO__Prop);
|
||||
type->propId = spa_type_map_get_id(map, SPA_TYPE_PARAM_IO_PROP__id);
|
||||
type->propType = spa_type_map_get_id(map, SPA_TYPE_PARAM_IO_PROP__type);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -59,8 +59,15 @@ extern "C" {
|
|||
/** The supported metadata */
|
||||
#define SPA_TYPE_PARAM_ID__Meta SPA_TYPE_PARAM_ID_BASE "Meta"
|
||||
|
||||
/** The supported io types */
|
||||
/** The supported io areas */
|
||||
#define SPA_TYPE_PARAM_ID__IO SPA_TYPE_PARAM_ID_BASE "IO"
|
||||
#define SPA_TYPE_PARAM_ID_IO_BASE SPA_TYPE_PARAM_ID__IO ":"
|
||||
|
||||
/** Base for parameters that describe IO areas to exchange data,
|
||||
* control and properties with a node.
|
||||
*/
|
||||
#define SPA_TYPE_PARAM__IO SPA_TYPE_PARAM_BASE "IO"
|
||||
#define SPA_TYPE_PARAM_IO_BASE SPA_TYPE_PARAM__IO ":"
|
||||
|
||||
struct spa_type_param {
|
||||
uint32_t idList; /**< id of the list param */
|
||||
|
|
@ -71,7 +78,6 @@ struct spa_type_param {
|
|||
uint32_t idFormat; /**< id to get/set format parameter */
|
||||
uint32_t idBuffers; /**< id to enumerate buffer requirements */
|
||||
uint32_t idMeta; /**< id to enumerate supported metadata */
|
||||
uint32_t idIO; /**< id to enumerate supported io types */
|
||||
};
|
||||
|
||||
static inline void
|
||||
|
|
@ -87,7 +93,6 @@ spa_type_param_map(struct spa_type_map *map,
|
|||
type->idFormat = spa_type_map_get_id(map, SPA_TYPE_PARAM_ID__Format);
|
||||
type->idBuffers = spa_type_map_get_id(map, SPA_TYPE_PARAM_ID__Buffers);
|
||||
type->idMeta = spa_type_map_get_id(map, SPA_TYPE_PARAM_ID__Meta);
|
||||
type->idIO = spa_type_map_get_id(map, SPA_TYPE_PARAM_ID__IO);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -111,8 +111,8 @@ static inline void init_type(struct type *type, struct spa_type_map *map)
|
|||
type->format = spa_type_map_get_id(map, SPA_TYPE__Format);
|
||||
type->prop_volume = spa_type_map_get_id(map, SPA_TYPE_PROPS__volume);
|
||||
type->prop_mute = spa_type_map_get_id(map, SPA_TYPE_PROPS__mute);
|
||||
type->io_prop_volume = spa_type_map_get_id(map, SPA_TYPE_IO_INPUT_PROP_BASE "volume");
|
||||
type->io_prop_mute = spa_type_map_get_id(map, SPA_TYPE_IO_INPUT_PROP_BASE "mute");
|
||||
type->io_prop_volume = spa_type_map_get_id(map, SPA_TYPE_IO_PROP_BASE "volume");
|
||||
type->io_prop_mute = spa_type_map_get_id(map, SPA_TYPE_IO_PROP_BASE "mute");
|
||||
spa_type_io_map(map, &type->io);
|
||||
spa_type_param_map(map, &type->param);
|
||||
spa_type_media_type_map(map, &type->media_type);
|
||||
|
|
@ -449,7 +449,9 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
t->param.idFormat,
|
||||
t->param.idBuffers,
|
||||
t->param.idMeta,
|
||||
t->param.idIO };
|
||||
t->param_io.idBuffers,
|
||||
t->param_io.idControl,
|
||||
t->param_io.idPropsIn };
|
||||
|
||||
if (*index < SPA_N_ELEMENTS(list))
|
||||
param = spa_pod_builder_object(&b, id, t->param.List,
|
||||
|
|
@ -496,39 +498,48 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
else if (id == t->param.idIO) {
|
||||
else if (id == t->param_io.idBuffers) {
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_io.Buffers,
|
||||
":", t->param_io.id, "I", t->io.Buffers,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_io_buffers));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (id == t->param_io.idControl) {
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_io.Control,
|
||||
":", t->param_io.id, "I", t->io.ControlRange,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_io_control_range));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (id == t->param_io.idPropsIn) {
|
||||
struct port_props *p = &port->props;
|
||||
|
||||
if (direction == SPA_DIRECTION_OUTPUT)
|
||||
return 0;
|
||||
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_io.IO,
|
||||
":", t->param_io.id, "I", t->io.Buffers,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_io_buffers));
|
||||
break;
|
||||
case 1:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_io.IO,
|
||||
":", t->param_io.id, "I", t->io.ControlRange,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_io_control_range));
|
||||
break;
|
||||
case 2:
|
||||
if (direction == SPA_DIRECTION_OUTPUT)
|
||||
return 0;
|
||||
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_io.IO,
|
||||
id, t->param_io.Prop,
|
||||
":", t->param_io.id, "I", t->io_prop_volume,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_pod_double),
|
||||
":", t->param_io.propId, "I", t->prop_volume,
|
||||
":", t->param_io.propType, "dr", p->volume, 2, 0.0, 10.0);
|
||||
break;
|
||||
case 3:
|
||||
if (direction == SPA_DIRECTION_OUTPUT)
|
||||
return 0;
|
||||
|
||||
case 1:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_io.IO,
|
||||
id, t->param_io.Prop,
|
||||
":", t->param_io.id, "I", t->io_prop_mute,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_pod_bool),
|
||||
":", t->param_io.propId, "I", t->prop_mute,
|
||||
|
|
|
|||
|
|
@ -83,9 +83,9 @@ static inline void init_type(struct type *type, struct spa_type_map *map)
|
|||
type->prop_wave = spa_type_map_get_id(map, SPA_TYPE_PROPS__waveType);
|
||||
type->prop_freq = spa_type_map_get_id(map, SPA_TYPE_PROPS__frequency);
|
||||
type->prop_volume = spa_type_map_get_id(map, SPA_TYPE_PROPS__volume);
|
||||
type->io_prop_wave = spa_type_map_get_id(map, SPA_TYPE_IO_INPUT_PROP_BASE "waveType");
|
||||
type->io_prop_freq = spa_type_map_get_id(map, SPA_TYPE_IO_INPUT_PROP_BASE "frequency");
|
||||
type->io_prop_volume = spa_type_map_get_id(map, SPA_TYPE_IO_INPUT_PROP_BASE "volume");
|
||||
type->io_prop_wave = spa_type_map_get_id(map, SPA_TYPE_IO_PROP_BASE "waveType");
|
||||
type->io_prop_freq = spa_type_map_get_id(map, SPA_TYPE_IO_PROP_BASE "frequency");
|
||||
type->io_prop_volume = spa_type_map_get_id(map, SPA_TYPE_IO_PROP_BASE "volume");
|
||||
type->wave_sine = spa_type_map_get_id(map, SPA_TYPE_PROPS__waveType ":sine");
|
||||
type->wave_square = spa_type_map_get_id(map, SPA_TYPE_PROPS__waveType ":square");
|
||||
spa_type_io_map(map, &type->io);
|
||||
|
|
@ -613,7 +613,9 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
t->param.idFormat,
|
||||
t->param.idBuffers,
|
||||
t->param.idMeta,
|
||||
t->param.idIO };
|
||||
t->param_io.idBuffers,
|
||||
t->param_io.idControl,
|
||||
t->param_io.idPropsIn };
|
||||
|
||||
if (*index < SPA_N_ELEMENTS(list))
|
||||
param = spa_pod_builder_object(&b, id, t->param.List,
|
||||
|
|
@ -660,25 +662,37 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
else if (id == t->param.idIO) {
|
||||
else if (id == t->param_io.idBuffers) {
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_io.Buffers,
|
||||
":", t->param_io.id, "I", t->io.Buffers,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_io_buffers));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (id == t->param_io.idControl) {
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_io.Control,
|
||||
":", t->param_io.id, "I", t->io.ControlRange,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_io_control_range));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (id == t->param_io.idPropsIn) {
|
||||
struct props *p = &this->props;
|
||||
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_io.IO,
|
||||
":", t->param_io.id, "I", t->io.Buffers,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_io_buffers));
|
||||
break;
|
||||
case 1:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_io.IO,
|
||||
":", t->param_io.id, "I", t->io.ControlRange,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_io_control_range));
|
||||
break;
|
||||
case 2:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_io.IO,
|
||||
id, t->param_io.Prop,
|
||||
":", t->param_io.id, "I", t->io_prop_wave,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_pod_id),
|
||||
":", t->param_io.propId, "I", t->prop_wave,
|
||||
|
|
@ -686,17 +700,17 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
2, t->wave_sine,
|
||||
t->wave_square);
|
||||
break;
|
||||
case 3:
|
||||
case 1:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_io.IO,
|
||||
id, t->param_io.Prop,
|
||||
":", t->param_io.id, "I", t->io_prop_freq,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_pod_double),
|
||||
":", t->param_io.propId, "I", t->prop_freq,
|
||||
":", t->param_io.propType, "dr", p->freq, 2, 0.0, 50000000.0);
|
||||
break;
|
||||
case 4:
|
||||
case 2:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_io.IO,
|
||||
id, t->param_io.Prop,
|
||||
":", t->param_io.id, "I", t->io_prop_volume,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_pod_double),
|
||||
":", t->param_io.propId, "I", t->prop_volume,
|
||||
|
|
|
|||
|
|
@ -425,7 +425,8 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
t->param.idFormat,
|
||||
t->param.idBuffers,
|
||||
t->param.idMeta,
|
||||
t->param.idIO };
|
||||
t->param_io.idBuffers,
|
||||
t->param_io.idControl };
|
||||
|
||||
if (*index < SPA_N_ELEMENTS(list))
|
||||
param = spa_pod_builder_object(&b, id, t->param.List,
|
||||
|
|
@ -469,17 +470,23 @@ impl_node_port_enum_params(struct spa_node *node,
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
else if (id == t->param.idIO) {
|
||||
else if (id == t->param_io.idBuffers) {
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_io.IO,
|
||||
id, t->param_io.Buffers,
|
||||
":", t->param_io.id, "I", t->io.Buffers,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_io_buffers));
|
||||
break;
|
||||
case 1:
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (id == t->param_io.idControl) {
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(&b,
|
||||
id, t->param_io.IO,
|
||||
id, t->param_io.Control,
|
||||
":", t->param_io.id, "I", t->io.ControlRange,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_io_control_range));
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -357,7 +357,7 @@ static int make_nodes(struct data *data, const char *device)
|
|||
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
if ((res = spa_node_port_enum_params(data->source, SPA_DIRECTION_OUTPUT, 0,
|
||||
data->type.param.idIO, &idx, NULL, ¶m, &b)) < 1) {
|
||||
data->type.param_io.idPropsIn, &idx, NULL, ¶m, &b)) < 1) {
|
||||
if (res < 0)
|
||||
error(0, -res, "port_enum_params");
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ static inline void init_type(struct type *type, struct spa_type_map *map)
|
|||
type->props_volume = spa_type_map_get_id(map, SPA_TYPE_PROPS__volume);
|
||||
type->props_min_latency = spa_type_map_get_id(map, SPA_TYPE_PROPS__minLatency);
|
||||
type->props_live = spa_type_map_get_id(map, SPA_TYPE_PROPS__live);
|
||||
type->io_inprop_volume = spa_type_map_get_id(map, SPA_TYPE_IO_INPUT_PROP_BASE "volume");
|
||||
type->io_inprop_volume = spa_type_map_get_id(map, SPA_TYPE_IO_PROP_BASE "volume");
|
||||
spa_type_io_map(map, &type->io);
|
||||
spa_type_param_map(map, &type->param);
|
||||
spa_type_meta_map(map, &type->meta);
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
struct type {
|
||||
uint32_t format;
|
||||
uint32_t props;
|
||||
uint32_t prop_volume;
|
||||
uint32_t io_prop_volume;
|
||||
struct spa_type_meta meta;
|
||||
struct spa_type_data data;
|
||||
struct spa_type_media_type media_type;
|
||||
|
|
@ -48,6 +50,8 @@ static inline void init_type(struct type *type, struct spa_type_map *map)
|
|||
{
|
||||
type->format = spa_type_map_get_id(map, SPA_TYPE__Format);
|
||||
type->props = spa_type_map_get_id(map, SPA_TYPE__Props);
|
||||
type->prop_volume = spa_type_map_get_id(map, SPA_TYPE_PROPS__volume);
|
||||
type->io_prop_volume = spa_type_map_get_id(map, SPA_TYPE_IO_PROP_BASE "volume");
|
||||
spa_type_meta_map(map, &type->meta);
|
||||
spa_type_data_map(map, &type->data);
|
||||
spa_type_media_type_map(map, &type->media_type);
|
||||
|
|
@ -56,6 +60,17 @@ static inline void init_type(struct type *type, struct spa_type_map *map)
|
|||
spa_type_audio_format_map(map, &type->audio_format);
|
||||
}
|
||||
|
||||
#define DEFAULT_VOLUME 1.0
|
||||
|
||||
struct props {
|
||||
double volume;
|
||||
};
|
||||
|
||||
static void reset_props(struct props *props)
|
||||
{
|
||||
props->volume = DEFAULT_VOLUME;
|
||||
}
|
||||
|
||||
struct buffer {
|
||||
struct spa_buffer *buffer;
|
||||
struct spa_list link;
|
||||
|
|
@ -66,6 +81,8 @@ struct buffer {
|
|||
struct data {
|
||||
struct type type;
|
||||
|
||||
struct props props;
|
||||
|
||||
const char *path;
|
||||
|
||||
struct pw_main_loop *loop;
|
||||
|
|
@ -84,6 +101,8 @@ struct data {
|
|||
void *callbacks_data;
|
||||
struct spa_io_buffers *io;
|
||||
|
||||
double *io_volume;
|
||||
|
||||
uint8_t buffer[1024];
|
||||
|
||||
struct spa_audio_info_raw format;
|
||||
|
|
@ -138,6 +157,12 @@ static int impl_port_set_io(struct spa_node *node, enum spa_direction direction,
|
|||
|
||||
if (id == d->t->io.Buffers)
|
||||
d->io = data;
|
||||
else if (id == d->type.io_prop_volume) {
|
||||
if (SPA_POD_TYPE(data) == SPA_POD_TYPE_ID)
|
||||
d->io_volume = &SPA_POD_VALUE(struct spa_pod_double, data);
|
||||
else
|
||||
return -EINVAL;
|
||||
}
|
||||
else
|
||||
return -ENOENT;
|
||||
|
||||
|
|
@ -226,7 +251,9 @@ static int impl_port_enum_params(struct spa_node *node,
|
|||
uint32_t list[] = { t->param.idEnumFormat,
|
||||
t->param.idFormat,
|
||||
t->param.idBuffers,
|
||||
t->param.idMeta };
|
||||
t->param.idMeta,
|
||||
t->param_io.idBuffers,
|
||||
t->param_io.idPropsOut };
|
||||
|
||||
if (*index < SPA_N_ELEMENTS(list))
|
||||
param = spa_pod_builder_object(builder,
|
||||
|
|
@ -266,6 +293,34 @@ static int impl_port_enum_params(struct spa_node *node,
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
else if (id == t->param_io.idBuffers) {
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(builder,
|
||||
id, t->param_io.Buffers,
|
||||
":", t->param_io.id, "I", t->io.Buffers,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_io_buffers));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (id == t->param_io.idPropsOut) {
|
||||
struct props *p = &d->props;
|
||||
|
||||
switch (*index) {
|
||||
case 0:
|
||||
param = spa_pod_builder_object(builder,
|
||||
id, t->param_io.Prop,
|
||||
":", t->param_io.id, "I", d->type.io_prop_volume,
|
||||
":", t->param_io.size, "i", sizeof(struct spa_pod_double),
|
||||
":", t->param_io.propId, "I", d->type.prop_volume,
|
||||
":", t->param_io.propType, "dr", p->volume, 2, 0.0, 10.0);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
return -ENOENT;
|
||||
|
||||
|
|
@ -495,6 +550,8 @@ int main(int argc, char *argv[])
|
|||
|
||||
spa_list_init(&data.empty);
|
||||
init_type(&data.type, data.t->map);
|
||||
reset_props(&data.props);
|
||||
data.io_volume = &data.props.volume;
|
||||
spa_debug_set_type_map(data.t->map);
|
||||
|
||||
pw_remote_add_listener(data.remote, &data.remote_listener, &remote_events, &data);
|
||||
|
|
|
|||
|
|
@ -771,7 +771,8 @@ static int spa_proxy_node_process_input(struct spa_node *node)
|
|||
|
||||
/* explicitly recycle buffers when the client is not going to do it */
|
||||
if (!client_reuse && (pp = p->peer))
|
||||
spa_node_port_reuse_buffer(pp->node->implementation, pp->port_id, io->buffer_id);
|
||||
spa_node_port_reuse_buffer(pp->node->implementation,
|
||||
pp->port_id, io->buffer_id);
|
||||
}
|
||||
pw_client_node_transport_add_message(impl->transport,
|
||||
&PW_CLIENT_NODE_MESSAGE_INIT(PW_CLIENT_NODE_MESSAGE_PROCESS_INPUT));
|
||||
|
|
|
|||
|
|
@ -219,54 +219,48 @@ static int update_port_ids(struct pw_node *node)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int collect_params(struct pw_port *port, uint32_t param_id, struct spa_pod ***result)
|
||||
{
|
||||
int res;
|
||||
uint8_t buffer[4096];
|
||||
struct spa_pod_builder b = { 0 };
|
||||
uint32_t state = 0;
|
||||
|
||||
for (res = 0;; res++) {
|
||||
struct spa_pod *fmt;
|
||||
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
if (spa_node_port_enum_params(port->node->node,
|
||||
port->direction, port->port_id,
|
||||
param_id, &state,
|
||||
NULL, &fmt, &b) <= 0)
|
||||
break;
|
||||
|
||||
*result = realloc(*result, sizeof(struct spa_pod *) * (res + 1));
|
||||
(*result)[res] = pw_spa_pod_copy(fmt);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
update_info(struct pw_node *this)
|
||||
{
|
||||
uint8_t buffer[4096];
|
||||
struct spa_pod_builder b = { 0 };
|
||||
struct pw_type *t = &this->core->type;
|
||||
|
||||
this->info.input_params = NULL;
|
||||
if (!spa_list_is_empty(&this->input_ports)) {
|
||||
struct pw_port *port = spa_list_first(&this->input_ports, struct pw_port, link);
|
||||
uint32_t state = 0;
|
||||
|
||||
for (this->info.n_input_params = 0;; this->info.n_input_params++) {
|
||||
struct spa_pod *fmt;
|
||||
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
if (spa_node_port_enum_params(port->node->node,
|
||||
port->direction, port->port_id,
|
||||
this->core->type.param.idEnumFormat, &state,
|
||||
NULL, &fmt, &b) <= 0)
|
||||
break;
|
||||
|
||||
this->info.input_params =
|
||||
realloc(this->info.input_params,
|
||||
sizeof(struct spa_pod *) * (this->info.n_input_params + 1));
|
||||
this->info.input_params[this->info.n_input_params] = pw_spa_pod_copy(fmt);
|
||||
}
|
||||
this->info.n_input_params = collect_params(port,
|
||||
t->param.idEnumFormat,
|
||||
&this->info.input_params);
|
||||
}
|
||||
|
||||
this->info.output_params = NULL;
|
||||
if (!spa_list_is_empty(&this->output_ports)) {
|
||||
struct pw_port *port = spa_list_first(&this->output_ports, struct pw_port, link);
|
||||
uint32_t state = 0;
|
||||
|
||||
for (this->info.n_output_params = 0;; this->info.n_output_params++) {
|
||||
struct spa_pod *fmt;
|
||||
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
if (spa_node_port_enum_params(port->node->node,
|
||||
port->direction, port->port_id,
|
||||
this->core->type.param.idEnumFormat, &state,
|
||||
NULL, &fmt, &b) <= 0)
|
||||
break;
|
||||
|
||||
this->info.output_params =
|
||||
realloc(this->info.output_params,
|
||||
sizeof(struct spa_pod *) * (this->info.n_output_params + 1));
|
||||
this->info.output_params[this->info.n_output_params] = pw_spa_pod_copy(fmt);
|
||||
}
|
||||
this->info.n_output_params = collect_params(port,
|
||||
t->param.idEnumFormat,
|
||||
&this->info.output_params);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue