mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -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
|
|
@ -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