node: Add id to set_io

Make it possible to configure multiple io areas on a port by giving
an id to set_io.
Add some types to enumerate the supported ids
Make an area to exchange buffers and one to specify pull ranges.
The idea is to make more area types for controlable properties.
Implement enumeration of IO areas in volume.
This commit is contained in:
Wim Taymans 2017-11-21 19:34:37 +01:00
parent 4288a634f4
commit 8efea3e1ea
40 changed files with 583 additions and 208 deletions

View file

@ -27,6 +27,7 @@
#include <spa/param/format-utils.h>
#include <spa/param/video/format-utils.h>
#include <spa/param/props.h>
#include <spa/node/io.h>
#include <spa/lib/debug.h>
#include <pipewire/pipewire.h>
@ -83,7 +84,7 @@ struct data {
struct spa_node impl_node;
const struct spa_node_callbacks *callbacks;
void *callbacks_data;
struct spa_port_io *io;
struct spa_io_buffers *io;
uint8_t buffer[1024];
@ -214,11 +215,17 @@ static int impl_get_port_ids(struct spa_node *node,
return 0;
}
static int impl_port_set_io(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
struct spa_port_io *io)
static int impl_port_set_io(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t id, void *io)
{
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
d->io = io;
if (id == d->t->io.Buffers)
d->io = io;
else
return -ENOENT;
return 0;
}

View file

@ -26,6 +26,7 @@
#include <spa/param/format-utils.h>
#include <spa/param/audio/format-utils.h>
#include <spa/param/props.h>
#include <spa/node/io.h>
#include <spa/lib/debug.h>
#include <pipewire/pipewire.h>
@ -81,7 +82,7 @@ struct data {
struct spa_node impl_node;
const struct spa_node_callbacks *callbacks;
void *callbacks_data;
struct spa_port_io *io;
struct spa_io_buffers *io;
uint8_t buffer[1024];
@ -131,10 +132,15 @@ static int impl_get_port_ids(struct spa_node *node,
}
static int impl_port_set_io(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
struct spa_port_io *io)
uint32_t id, void *io)
{
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
d->io = io;
if (id == d->t->io.Buffers)
d->io = io;
else
return -ENOENT;
return 0;
}
@ -241,7 +247,7 @@ static int impl_port_enum_params(struct spa_node *node,
param = spa_pod_builder_object(builder,
id, t->param_buffers.Buffers,
":", t->param_buffers.size, "iru", 1024,
":", t->param_buffers.size, "iru", 256,
2, 32, 4096,
":", t->param_buffers.stride, "i", 0,
":", t->param_buffers.buffers, "iru", 1,
@ -362,7 +368,7 @@ static int impl_node_process_output(struct spa_node *node)
struct buffer *b;
int i, c, n_samples, avail;
int16_t *dst;
struct spa_port_io *io = d->io;
struct spa_io_buffers *io = d->io;
uint32_t maxsize, index = 0;
uint32_t filled, offset;
struct spa_data *od;

View file

@ -26,6 +26,7 @@
#include <spa/param/format-utils.h>
#include <spa/param/video/format-utils.h>
#include <spa/param/props.h>
#include <spa/node/io.h>
#include <spa/lib/debug.h>
#include <pipewire/pipewire.h>
@ -79,7 +80,7 @@ struct data {
struct pw_link *link;
struct spa_node impl_node;
struct spa_port_io *io;
struct spa_io_buffers *io;
const struct spa_node_callbacks *callbacks;
void *callbacks_data;
@ -210,10 +211,15 @@ static int impl_get_port_ids(struct spa_node *node,
}
static int impl_port_set_io(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
struct spa_port_io *io)
uint32_t id, void *io)
{
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
d->io = io;
if (id == d->t->io.Buffers)
d->io = io;
else
return -ENOENT;
return 0;
}

View file

@ -56,8 +56,8 @@ struct pw_client_node_area {
*/
struct pw_client_node_transport {
struct pw_client_node_area *area; /**< the transport area */
struct spa_port_io *inputs; /**< array of input port io */
struct spa_port_io *outputs; /**< array of output port io */
struct spa_io_buffers *inputs; /**< array of buffer input io */
struct spa_io_buffers *outputs; /**< array of buffer output io */
void *input_data; /**< input memory for ringbuffer */
struct spa_ringbuffer *input_buffer; /**< ringbuffer for input memory */
void *output_data; /**< output memory for ringbuffer */

View file

@ -80,7 +80,7 @@ struct proxy_port {
bool have_format;
uint32_t n_params;
struct spa_pod **params;
struct spa_port_io *io;
struct spa_io_buffers *io;
uint32_t n_buffers;
struct proxy_buffer buffers[MAX_BUFFERS];
@ -511,21 +511,30 @@ spa_proxy_node_port_set_param(struct spa_node *node,
static int
spa_proxy_node_port_set_io(struct spa_node *node,
enum spa_direction direction, uint32_t port_id, struct spa_port_io *io)
enum spa_direction direction,
uint32_t port_id,
uint32_t id,
void *io)
{
struct proxy *this;
struct proxy_port *port;
struct pw_type *t;
if (node == NULL)
return -EINVAL;
this = SPA_CONTAINER_OF(node, struct proxy, node);
t = this->impl->t;
if (!CHECK_PORT(this, direction, port_id))
return -EINVAL;
port = GET_PORT(this, direction, port_id);
port->io = io;
if (id == t->io.Buffers)
port->io = io;
else
return -ENOENT;
return 0;
}
@ -737,7 +746,7 @@ static int spa_proxy_node_process_input(struct spa_node *node)
}
else {
spa_list_for_each(p, &n->ports[SPA_DIRECTION_INPUT], link) {
struct spa_port_io *io = p->io;
struct spa_io_buffers *io = p->io;
pw_log_trace("set io status to %d %d", io->status, io->buffer_id);
impl->transport->inputs[p->port_id] = *io;
@ -773,7 +782,7 @@ static int spa_proxy_node_process_output(struct spa_node *node)
impl->out_pending = true;
spa_list_for_each(p, &n->ports[SPA_DIRECTION_OUTPUT], link) {
struct spa_port_io *io = p->io;
struct spa_io_buffers *io = p->io;
impl->transport->outputs[p->port_id] = *io;

View file

@ -22,6 +22,7 @@
#include <sys/mman.h>
#include <spa/utils/ringbuffer.h>
#include <spa/node/io.h>
#include <pipewire/log.h>
#include <extensions/client-node.h>
@ -47,8 +48,8 @@ static size_t area_get_size(struct pw_client_node_area *area)
{
size_t size;
size = sizeof(struct pw_client_node_area);
size += area->max_input_ports * sizeof(struct spa_port_io);
size += area->max_output_ports * sizeof(struct spa_port_io);
size += area->max_input_ports * sizeof(struct spa_io_buffers);
size += area->max_output_ports * sizeof(struct spa_io_buffers);
size += sizeof(struct spa_ringbuffer);
size += INPUT_BUFFER_SIZE;
size += sizeof(struct spa_ringbuffer);
@ -61,13 +62,13 @@ static void transport_setup_area(void *p, struct pw_client_node_transport *trans
struct pw_client_node_area *a;
trans->area = a = p;
p = SPA_MEMBER(p, sizeof(struct pw_client_node_area), struct spa_port_io);
p = SPA_MEMBER(p, sizeof(struct pw_client_node_area), struct spa_io_buffers);
trans->inputs = p;
p = SPA_MEMBER(p, a->max_input_ports * sizeof(struct spa_port_io), void);
p = SPA_MEMBER(p, a->max_input_ports * sizeof(struct spa_io_buffers), void);
trans->outputs = p;
p = SPA_MEMBER(p, a->max_output_ports * sizeof(struct spa_port_io), void);
p = SPA_MEMBER(p, a->max_output_ports * sizeof(struct spa_io_buffers), void);
trans->input_buffer = p;
p = SPA_MEMBER(p, sizeof(struct spa_ringbuffer), void);

View file

@ -47,6 +47,7 @@
struct type {
uint32_t format;
struct spa_type_io io;
struct spa_type_param param;
struct spa_type_data data;
struct spa_type_media_type media_type;
@ -59,6 +60,7 @@ struct type {
static inline void init_type(struct type *type, struct spa_type_map *map)
{
type->format = spa_type_map_get_id(map, SPA_TYPE__Format);
spa_type_io_map(map, &type->io);
spa_type_param_map(map, &type->param);
spa_type_data_map(map, &type->data);
spa_type_media_type_map(map, &type->media_type);
@ -106,7 +108,7 @@ struct port_data {
struct spa_port_info info;
struct spa_port_io *io;
struct spa_io_buffers *io;
bool have_buffers;
struct buffer buffers[64];
@ -261,7 +263,7 @@ static int driver_process_output(struct spa_node *node)
struct spa_graph_node *gn = &this->node->rt.node;
struct spa_graph_port *p;
struct port_data *opd = SPA_CONTAINER_OF(this->driver_out, struct port_data, port);
struct spa_port_io *out_io = opd->io;
struct spa_io_buffers *out_io = opd->io;
struct jack_engine_control *ctrl = this->server->engine_control;
struct buffer *out;
int16_t *op;
@ -290,7 +292,7 @@ static int driver_process_output(struct spa_node *node)
spa_list_for_each(p, &gn->ports[SPA_DIRECTION_INPUT], link) {
struct pw_port *port = p->scheduler_data;
struct port_data *ipd = pw_port_get_user_data(port);
struct spa_port_io *in_io = ipd->io;
struct spa_io_buffers *in_io = ipd->io;
struct buffer *in;
int stride = 2;
@ -342,7 +344,7 @@ static int node_process_input(struct spa_node *node)
spa_list_for_each(p, &gn->ports[SPA_DIRECTION_OUTPUT], link) {
struct pw_port *port = p->scheduler_data;
struct port_data *opd = pw_port_get_user_data(port);
struct spa_port_io *out_io = opd->io;
struct spa_io_buffers *out_io = opd->io;
out_io->buffer_id = 0;
out_io->status = SPA_STATUS_HAVE_BUFFER;
pw_log_trace(NAME " %p: port %p: %d %d", nd, p, out_io->buffer_id, out_io->status);
@ -361,7 +363,7 @@ static int node_process_output(struct spa_node *node)
spa_list_for_each(p, &gn->ports[SPA_DIRECTION_INPUT], link) {
struct pw_port *port = p->scheduler_data;
struct port_data *ipd = pw_port_get_user_data(port);
struct spa_port_io *in_io = ipd->io;
struct spa_io_buffers *in_io = ipd->io;
in_io->buffer_id = 0;
in_io->status = SPA_STATUS_NEED_BUFFER;
pw_log_trace(NAME " %p: port %p: %d %d", nd, p, in_io->buffer_id, in_io->status);
@ -370,12 +372,19 @@ static int node_process_output(struct spa_node *node)
}
static int port_set_io(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
struct spa_port_io *io)
static int port_set_io(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t id, void *io)
{
struct node_data *nd = SPA_CONTAINER_OF(node, struct node_data, node_impl);
struct port_data *pd = nd->port_data[direction][port_id];
pd->io = io;
struct type *t = &pd->node->type;
if (id == t->io.Buffers)
pd->io = io;
else
return -ENOENT;
return 0;
}
@ -619,7 +628,7 @@ static int schedule_mix_input(struct spa_node *_node)
struct pw_jack_port *this = &pd->port;
struct spa_graph_node *node = &this->port->rt.mix_node;
struct spa_graph_port *p;
struct spa_port_io *io = this->port->rt.mix_port.io;
struct spa_io_buffers *io = this->port->rt.mix_port.io;
size_t buffer_size = pd->node->node.server->engine_control->buffer_size;
int layer = 0;
@ -655,7 +664,7 @@ static int schedule_mix_output(struct spa_node *_node)
struct pw_jack_port *this = &pd->port;
struct spa_graph_node *node = &this->port->rt.mix_node;
struct spa_graph_port *p;
struct spa_port_io *io = this->port->rt.mix_port.io;
struct spa_io_buffers *io = this->port->rt.mix_port.io;
spa_list_for_each(p, &node->ports[SPA_DIRECTION_INPUT], link)
*p->io = *io;

View file

@ -1177,7 +1177,7 @@ struct pw_link *pw_link_new(struct pw_core *core,
this->info.format = NULL;
this->info.props = this->properties ? &this->properties->dict : NULL;
this->io = SPA_PORT_IO_INIT;
this->io = SPA_IO_BUFFERS_INIT;
spa_graph_port_init(&this->rt.out_port,
PW_DIRECTION_OUTPUT,

View file

@ -49,7 +49,7 @@ static int schedule_tee_input(struct spa_node *data)
struct pw_port *this = &impl->this;
struct spa_graph_node *node = &this->rt.mix_node;
struct spa_graph_port *p;
struct spa_port_io *io = this->rt.mix_port.io;
struct spa_io_buffers *io = this->rt.mix_port.io;
if (!spa_list_is_empty(&node->ports[SPA_DIRECTION_OUTPUT])) {
pw_log_trace("tee input %d %d", io->status, io->buffer_id);
@ -68,7 +68,7 @@ static int schedule_tee_output(struct spa_node *data)
struct pw_port *this = &impl->this;
struct spa_graph_node *node = &this->rt.mix_node;
struct spa_graph_port *p;
struct spa_port_io *io = this->rt.mix_port.io;
struct spa_io_buffers *io = this->rt.mix_port.io;
spa_list_for_each(p, &node->ports[SPA_DIRECTION_OUTPUT], link)
*io = *p->io;
@ -103,7 +103,7 @@ static int schedule_mix_input(struct spa_node *data)
struct pw_port *this = &impl->this;
struct spa_graph_node *node = &this->rt.mix_node;
struct spa_graph_port *p;
struct spa_port_io *io = this->rt.mix_port.io;
struct spa_io_buffers *io = this->rt.mix_port.io;
spa_list_for_each(p, &node->ports[SPA_DIRECTION_INPUT], link) {
pw_log_trace("mix %p: input %p %p->%p %d %d", node,
@ -121,7 +121,7 @@ static int schedule_mix_output(struct spa_node *data)
struct pw_port *this = &impl->this;
struct spa_graph_node *node = &this->rt.mix_node;
struct spa_graph_port *p;
struct spa_port_io *io = this->rt.mix_port.io;
struct spa_io_buffers *io = this->rt.mix_port.io;
spa_list_for_each(p, &node->ports[SPA_DIRECTION_INPUT], link)
*p->io = *io;
@ -177,7 +177,7 @@ struct pw_port *pw_port_new(enum pw_direction direction,
this->port_id = port_id;
this->properties = properties;
this->state = PW_PORT_STATE_INIT;
this->io = SPA_PORT_IO_INIT;
this->io = SPA_IO_BUFFERS_INIT;
if (user_data_size > 0)
this->user_data = SPA_MEMBER(impl, sizeof(struct impl), void);
@ -287,7 +287,9 @@ bool pw_port_add(struct pw_port *port, struct pw_node *node)
node->info.change_mask |= PW_NODE_CHANGE_MASK_OUTPUT_PORTS;
}
spa_node_port_set_io(node->node, port->direction, port_id, port->rt.port.io);
spa_node_port_set_io(node->node,
port->direction, port_id,
node->core->type.io.Buffers, port->rt.port.io);
port->rt.graph = node->rt.graph;
pw_loop_invoke(node->data_loop, do_add_port, SPA_ID_INVALID, NULL, 0, false, port);

View file

@ -185,7 +185,7 @@ struct pw_link {
struct spa_list resource_list; /**< list of bound resources */
struct spa_port_io io; /**< link io area */
struct spa_io_buffers io; /**< link io area */
struct pw_port *output; /**< output port */
struct spa_list output_link; /**< link in output port links */
@ -270,7 +270,7 @@ struct pw_port {
enum pw_port_state state; /**< state of the port */
struct spa_port_io io; /**< io area of the port */
struct spa_io_buffers io; /**< io area of the port */
bool allocated; /**< if buffers are allocated */
struct pw_memblock buffer_mem; /**< allocated buffer memory */

View file

@ -592,7 +592,7 @@ static void client_node_transport(void *object, uint32_t node_id,
for (i = 0; i < data->trans->area->max_input_ports; i++) {
port_init(&data->in_ports[i]);
data->trans->inputs[i] = SPA_PORT_IO_INIT;
data->trans->inputs[i] = SPA_IO_BUFFERS_INIT;
spa_graph_port_init(&data->in_ports[i].input,
SPA_DIRECTION_INPUT,
i,
@ -614,7 +614,7 @@ static void client_node_transport(void *object, uint32_t node_id,
for (i = 0; i < data->trans->area->max_output_ports; i++) {
port_init(&data->out_ports[i]);
data->trans->outputs[i] = SPA_PORT_IO_INIT;
data->trans->outputs[i] = SPA_IO_BUFFERS_INIT;
spa_graph_port_init(&data->out_ports[i].output,
SPA_DIRECTION_OUTPUT,
i,

View file

@ -557,7 +557,7 @@ static void handle_rtnode_message(struct pw_stream *stream, struct pw_client_nod
int i;
for (i = 0; i < impl->trans->area->n_input_ports; i++) {
struct spa_port_io *input = &impl->trans->inputs[i];
struct spa_io_buffers *input = &impl->trans->inputs[i];
struct buffer_id *bid;
uint32_t buffer_id;
@ -590,7 +590,7 @@ static void handle_rtnode_message(struct pw_stream *stream, struct pw_client_nod
int i;
for (i = 0; i < impl->trans->area->n_output_ports; i++) {
struct spa_port_io *output = &impl->trans->outputs[i];
struct spa_io_buffers *output = &impl->trans->outputs[i];
if (output->buffer_id == SPA_ID_INVALID)
continue;
@ -1139,7 +1139,7 @@ bool pw_stream_recycle_buffer(struct pw_stream *stream, uint32_t id)
int i;
for (i = 0; i < impl->trans->area->n_input_ports; i++) {
struct spa_port_io *input = &impl->trans->inputs[i];
struct spa_io_buffers *input = &impl->trans->inputs[i];
input->buffer_id = id;
}
} else {

View file

@ -54,6 +54,7 @@ void pw_type_init(struct pw_type *type)
type->spa_format = spa_type_map_get_id(type->map, SPA_TYPE__Format);
type->spa_props = spa_type_map_get_id(type->map, SPA_TYPE__Props);
spa_type_io_map(type->map, &type->io);
spa_type_param_map(type->map, &type->param);
spa_type_meta_map(type->map, &type->meta);
spa_type_data_map(type->map, &type->data);

View file

@ -30,6 +30,7 @@ extern "C" {
#include <spa/monitor/monitor.h>
#include <spa/param/buffers.h>
#include <spa/param/meta.h>
#include <spa/node/io.h>
#include <pipewire/map.h>
@ -64,6 +65,7 @@ struct pw_type {
uint32_t spa_format;
uint32_t spa_props;
struct spa_type_io io;
struct spa_type_param param;
struct spa_type_meta meta;
struct spa_type_data data;