diff --git a/spa/include/spa/graph/graph.h b/spa/include/spa/graph/graph.h index 2efccff85..30d8531ca 100644 --- a/spa/include/spa/graph/graph.h +++ b/spa/include/spa/graph/graph.h @@ -27,6 +27,7 @@ extern "C" { #include #include #include +#include #ifndef spa_debug #define spa_debug(...) @@ -74,7 +75,7 @@ struct spa_graph_port { enum spa_direction direction; /**< port direction */ uint32_t port_id; /**< port id */ uint32_t flags; /**< port flags */ - struct spa_port_io *io; /**< io area of the port */ + struct spa_io_buffers *io; /**< io area of the port */ struct spa_graph_port *peer; /**< peer */ void *scheduler_data; /**< scheduler private data */ }; @@ -127,7 +128,7 @@ spa_graph_port_init(struct spa_graph_port *port, enum spa_direction direction, uint32_t port_id, uint32_t flags, - struct spa_port_io *io) + struct spa_io_buffers *io) { spa_debug("port %p init type %d id %d", port, direction, port_id); port->direction = direction; diff --git a/spa/include/spa/meson.build b/spa/include/spa/meson.build index eaa0eb85b..6187a4aa4 100644 --- a/spa/include/spa/meson.build +++ b/spa/include/spa/meson.build @@ -31,6 +31,7 @@ spa_node_headers = [ 'node/command.h', 'node/event.h', 'node/node.h', + 'node/io.h', ] install_headers(spa_node_headers, @@ -41,6 +42,7 @@ spa_param_headers = [ 'param/props.h', 'param/buffers.h', 'param/meta.h', + 'param/io.h', 'param/format.h', 'param/format-utils.h', ] diff --git a/spa/include/spa/node/io.h b/spa/include/spa/node/io.h new file mode 100644 index 000000000..0d173bc7c --- /dev/null +++ b/spa/include/spa/node/io.h @@ -0,0 +1,89 @@ +/* Simple Plugin API + * Copyright (C) 2016 Wim Taymans + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __SPA_IO_H__ +#define __SPA_IO_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** Base for IO structures to interface with node ports */ +#define SPA_TYPE__IO SPA_TYPE_POINTER_BASE "IO" +#define SPA_TYPE_IO_BASE SPA_TYPE__IO ":" + +/** Base for control structures */ +#define SPA_TYPE_IO__Control SPA_TYPE_IO_BASE "Control" +#define SPA_TYPE_IO_CONTROL_BASE SPA_TYPE_IO__Control ":" + +/** 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" + +/** Buffers IO area + * + * IO information for a port on a node. This is allocated + * by the host and configured on all ports for which IO is requested. + */ +struct spa_io_buffers { +#define SPA_STATUS_OK 0 +#define SPA_STATUS_NEED_BUFFER 1 +#define SPA_STATUS_HAVE_BUFFER 2 +#define SPA_STATUS_FORMAT_CHANGED 3 +#define SPA_STATUS_PORTS_CHANGED 4 +#define SPA_STATUS_PARAM_CHANGED 5 + int32_t status; /**< the status code */ + uint32_t buffer_id; /**< a buffer id */ +}; + +#define SPA_IO_BUFFERS_INIT (struct spa_io_buffers) { SPA_STATUS_OK, SPA_ID_INVALID, } + +/** Information about requested range */ +#define SPA_TYPE_IO_CONTROL__Range SPA_TYPE_IO_CONTROL_BASE "Range" + +/** A range, suitable for input ports that can suggest a range to output ports */ +struct spa_io_control_range { + uint64_t offset; /**< offset in range */ + uint32_t min_size; /**< minimum size of data */ + uint32_t max_size; /**< maximum size of data */ +}; + +struct spa_type_io { + uint32_t Buffers; + uint32_t ControlRange; +}; + +static inline void spa_type_io_map(struct spa_type_map *map, struct spa_type_io *type) +{ + 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); + } +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* __SPA_IO_H__ */ diff --git a/spa/include/spa/node/node.h b/spa/include/spa/node/node.h index eb0fe3e9b..d4c46aae0 100644 --- a/spa/include/spa/node/node.h +++ b/spa/include/spa/node/node.h @@ -38,32 +38,6 @@ struct spa_node; #include #include -/** A range */ -struct spa_range { - uint64_t offset; /**< offset in range */ - uint32_t min_size; /**< minimum size of data */ - uint32_t max_size; /**< maximum size of data */ -}; - -/** Port IO area - * - * IO information for a port on a node. This is allocated - * by the host and configured on all ports for which IO is requested. - */ -struct spa_port_io { -#define SPA_STATUS_OK 0 -#define SPA_STATUS_NEED_BUFFER 1 -#define SPA_STATUS_HAVE_BUFFER 2 -#define SPA_STATUS_FORMAT_CHANGED 3 -#define SPA_STATUS_PORTS_CHANGED 4 -#define SPA_STATUS_PARAM_CHANGED 5 - int32_t status; /**< the status code */ - uint32_t buffer_id; /**< a buffer id */ - struct spa_range range; /**< the requested range */ -}; - -#define SPA_PORT_IO_INIT (struct spa_port_io) { SPA_STATUS_OK, SPA_ID_INVALID, } - /** * Port information structure * @@ -350,6 +324,7 @@ struct spa_node { * \param node a #struct spa_node * \param direction a #enum spa_direction * \param port_id the port to configure + * \param id the parameter id to set * \param flags optional flags * \param param a #struct spa_pod with the parameter to set * \return 0 on success @@ -372,16 +347,19 @@ struct spa_node { /** * Tell the port to use the given buffers * + * The port should also have a spa_io_buffers io area configured to exchange + * the buffers with the port. + * * For an input port, all the buffers will remain dequeued. Once a buffer * has been pushed on a port with port_push_input, it should not be reused * until the reuse_buffer event is notified or when the buffer has been - * returned in the spa_port_io of the port. + * returned in the spa_io_buffers of the port. * * For output ports, all buffers will be queued in the port. When process_input * or process_output return SPA_STATUS_HAVE_BUFFER, buffers are available in - * one or more of the spa_port_io areas. + * one or more of the spa_io_buffers areas. * When a buffer can be reused, port_reuse_buffer() should be called or the - * buffer_id should be placed in the spa_port_io area before calling + * buffer_id should be placed in the spa_io_buffers area before calling * process_output. * * Passing NULL as \a buffers will remove the reference that the port has @@ -404,6 +382,9 @@ struct spa_node { /** * Tell the port to allocate memory for \a buffers. * + * The port should also have a spa_io_buffers io area configured to exchange + * the buffers with the port. + * * \a buffers should contain an array of pointers to buffers. The data * in the buffers should point to an array of at least 1 data entry * with a 0 type that will be filled by this function. @@ -439,23 +420,28 @@ struct spa_node { uint32_t *n_buffers); /** - * Configure the given io structure on \a port_id. This - * structure is allocated by the host and is used to query the state - * of the port and exchange buffers with the port. + * Configure the given memory area with \a id on \a port_id. This + * structure is allocated by the host and is used to exchange + * data and parameters with the port. * - * Setting an \a io of NULL will disable the port. + * Setting an \a io of NULL will disable the port io. * * This function must be called from the main thread. * * \param direction a spa_direction * \param port_id a port id - * \param io a spa_port_io + * \param id the id of the io area, the available ids can be + * enumerated with the port parameters. + * \param io a io area memory * \return 0 on success + * -EINVAL when node is NULL the port is not valid + * -ENOENT when \id is unknown */ int (*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); /** * Tell an output port to reuse a buffer. diff --git a/spa/include/spa/param/io.h b/spa/include/spa/param/io.h new file mode 100644 index 000000000..62191c09e --- /dev/null +++ b/spa/include/spa/param/io.h @@ -0,0 +1,61 @@ +/* Simple Plugin API + * Copyright (C) 2016 Wim Taymans + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __SPA_PARAM_IO_H__ +#define __SPA_PARAM_IO_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +#define SPA_TYPE_PARAM__IO SPA_TYPE_PARAM_BASE "IO" +#define SPA_TYPE_PARAM_IO_BASE SPA_TYPE_PARAM__IO ":" + +#define SPA_TYPE_PARAM_IO__id SPA_TYPE_PARAM_IO_BASE "id" +#define SPA_TYPE_PARAM_IO__size SPA_TYPE_PARAM_IO_BASE "size" +#define SPA_TYPE_PARAM_IO__propId SPA_TYPE_PARAM_IO_BASE "propId" + +struct spa_type_param_io { + uint32_t IO; + uint32_t id; + uint32_t size; + uint32_t propId; +}; + +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); + 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); + } +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* __SPA_PARAM_IO_H__ */ diff --git a/spa/include/spa/param/param.h b/spa/include/spa/param/param.h index 9e8448b37..2f7be7676 100644 --- a/spa/include/spa/param/param.h +++ b/spa/include/spa/param/param.h @@ -59,6 +59,9 @@ extern "C" { /** The supported metadata */ #define SPA_TYPE_PARAM_ID__Meta SPA_TYPE_PARAM_ID_BASE "Meta" +/** The supported io types */ +#define SPA_TYPE_PARAM_ID__IO SPA_TYPE_PARAM_ID_BASE "IO" + struct spa_type_param { uint32_t idList; /**< id of the list param */ uint32_t List; /**< list object type */ @@ -68,6 +71,7 @@ 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 @@ -83,6 +87,7 @@ 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); } } diff --git a/spa/plugins/alsa/alsa-sink.c b/spa/plugins/alsa/alsa-sink.c index 97412a1a1..643e62de6 100644 --- a/spa/plugins/alsa/alsa-sink.c +++ b/spa/plugins/alsa/alsa-sink.c @@ -517,17 +517,28 @@ impl_node_port_alloc_buffers(struct spa_node *node, } static int -impl_node_port_set_io(struct spa_node *node, enum spa_direction direction, uint32_t port_id, struct spa_port_io *io) +impl_node_port_set_io(struct spa_node *node, + enum spa_direction direction, + uint32_t port_id, + uint32_t id, + void *io) { struct state *this; + struct type *t; spa_return_val_if_fail(node != NULL, -EINVAL); this = SPA_CONTAINER_OF(node, struct state, node); + t = &this->type; spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL); - this->io = io; + if (id == t->io.Buffers) + this->io = io; + else if (id == t->io.ControlRange) + this->range = io; + else + return -ENOENT; return 0; } @@ -563,7 +574,7 @@ impl_node_port_send_command(struct spa_node *node, static int impl_node_process_input(struct spa_node *node) { struct state *this; - struct spa_port_io *input; + struct spa_io_buffers *input; spa_return_val_if_fail(node != NULL, -EINVAL); diff --git a/spa/plugins/alsa/alsa-source.c b/spa/plugins/alsa/alsa-source.c index ef6cea770..257dd987f 100644 --- a/spa/plugins/alsa/alsa-source.c +++ b/spa/plugins/alsa/alsa-source.c @@ -552,17 +552,26 @@ impl_node_port_alloc_buffers(struct spa_node *node, } static int -impl_node_port_set_io(struct spa_node *node, enum spa_direction direction, uint32_t port_id, struct spa_port_io *io) +impl_node_port_set_io(struct spa_node *node, + enum spa_direction direction, + uint32_t port_id, + uint32_t id, + void *io) { struct state *this; + struct type *t; spa_return_val_if_fail(node != NULL, -EINVAL); this = SPA_CONTAINER_OF(node, struct state, node); + t = &this->type; spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL); - this->io = io; + if (id == t->io.Buffers) + this->io = io; + else + return -ENOENT; return 0; } @@ -619,7 +628,7 @@ static int impl_node_process_input(struct spa_node *node) static int impl_node_process_output(struct spa_node *node) { struct state *this; - struct spa_port_io *io; + struct spa_io_buffers *io; spa_return_val_if_fail(node != NULL, -EINVAL); diff --git a/spa/plugins/alsa/alsa-utils.c b/spa/plugins/alsa/alsa-utils.c index 1544bbffc..49b1a7f63 100644 --- a/spa/plugins/alsa/alsa-utils.c +++ b/spa/plugins/alsa/alsa-utils.c @@ -334,15 +334,17 @@ static inline void calc_timeout(size_t target, size_t current, static inline void try_pull(struct state *state, snd_pcm_uframes_t frames, snd_pcm_uframes_t written, bool do_pull) { - struct spa_port_io *io = state->io; + struct spa_io_buffers *io = state->io; if (spa_list_is_empty(&state->ready) && do_pull) { spa_log_trace(state->log, "alsa-util %p: %d %lu", state, io->status, state->filled + written); io->status = SPA_STATUS_NEED_BUFFER; - io->range.offset = state->sample_count * state->frame_size; - io->range.min_size = state->threshold * state->frame_size; - io->range.max_size = frames * state->frame_size; + if (state->range) { + state->range->offset = state->sample_count * state->frame_size; + state->range->min_size = state->threshold * state->frame_size; + state->range->max_size = frames * state->frame_size; + } state->callbacks->need_input(state->callbacks_data); } } @@ -428,7 +430,7 @@ push_frames(struct state *state, snd_pcm_uframes_t frames) { snd_pcm_uframes_t total_frames = 0; - struct spa_port_io *io = state->io; + struct spa_io_buffers *io = state->io; if (spa_list_is_empty(&state->free)) { spa_log_trace(state->log, "no more buffers"); diff --git a/spa/plugins/alsa/alsa-utils.h b/spa/plugins/alsa/alsa-utils.h index 8f1f53212..5ba57bc57 100644 --- a/spa/plugins/alsa/alsa-utils.h +++ b/spa/plugins/alsa/alsa-utils.h @@ -35,6 +35,7 @@ extern "C" { #include #include +#include #include #include #include @@ -66,6 +67,7 @@ struct type { uint32_t prop_card_name; uint32_t prop_min_latency; uint32_t prop_max_latency; + struct spa_type_io io; struct spa_type_param param; struct spa_type_meta meta; struct spa_type_data data; @@ -92,6 +94,7 @@ static inline void init_type(struct type *type, struct spa_type_map *map) type->prop_min_latency = spa_type_map_get_id(map, SPA_TYPE_PROPS__minLatency); type->prop_max_latency = spa_type_map_get_id(map, SPA_TYPE_PROPS__maxLatency); + spa_type_io_map(map, &type->io); spa_type_param_map(map, &type->param); spa_type_meta_map(map, &type->meta); spa_type_data_map(map, &type->data); @@ -141,7 +144,8 @@ struct state { size_t frame_size; struct spa_port_info info; - struct spa_port_io *io; + struct spa_io_buffers *io; + struct spa_io_control_range *range; struct buffer buffers[MAX_BUFFERS]; unsigned int n_buffers; diff --git a/spa/plugins/audiomixer/audiomixer.c b/spa/plugins/audiomixer/audiomixer.c index 4b53ca42a..94ba6111f 100644 --- a/spa/plugins/audiomixer/audiomixer.c +++ b/spa/plugins/audiomixer/audiomixer.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -50,7 +51,8 @@ struct buffer { struct port { bool valid; - struct spa_port_io *io; + struct spa_io_buffers *io; + struct spa_io_control_range *range; struct spa_port_info info; @@ -66,6 +68,7 @@ struct port { struct type { uint32_t node; uint32_t format; + struct spa_type_io io; struct spa_type_param param; struct spa_type_media_type media_type; struct spa_type_media_subtype media_subtype; @@ -82,6 +85,7 @@ static inline void init_type(struct type *type, struct spa_type_map *map) { type->node = spa_type_map_get_id(map, SPA_TYPE__Node); 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_media_type_map(map, &type->media_type); spa_type_media_subtype_map(map, &type->media_subtype); @@ -625,21 +629,28 @@ impl_node_port_alloc_buffers(struct spa_node *node, static int impl_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 impl *this; struct port *port; + struct type *t; spa_return_val_if_fail(node != NULL, -EINVAL); this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL); port = GET_PORT(this, direction, port_id); - port->io = io; + + if (id == t->io.Buffers) + port->io = io; + else if (id == t->io.ControlRange) + port->range = io; + else + return -ENOENT; return 0; } @@ -730,7 +741,7 @@ static int mix_output(struct impl *this, size_t n_bytes) struct buffer *outbuf; int i, layer; struct port *outport; - struct spa_port_io *outio; + struct spa_io_buffers *outio; struct spa_data *od; uint32_t avail, index, maxsize, len1, len2, offset; @@ -793,7 +804,7 @@ static int impl_node_process_input(struct spa_node *node) uint32_t i; struct port *outport; size_t min_queued = SIZE_MAX; - struct spa_port_io *outio; + struct spa_io_buffers *outio; spa_return_val_if_fail(node != NULL, -EINVAL); @@ -808,7 +819,7 @@ static int impl_node_process_input(struct spa_node *node) for (i = 0; i < this->last_port; i++) { struct port *inport = GET_IN_PORT(this, i); - struct spa_port_io *inio; + struct spa_io_buffers *inio; if ((inio = inport->io) == NULL) continue; @@ -852,7 +863,7 @@ static int impl_node_process_output(struct spa_node *node) { struct impl *this; struct port *outport; - struct spa_port_io *outio; + struct spa_io_buffers *outio; int i; size_t min_queued = SIZE_MAX; @@ -888,19 +899,20 @@ static int impl_node_process_output(struct spa_node *node) /* take requested output range and apply to input */ for (i = 0; i < this->last_port; i++) { struct port *inport = GET_IN_PORT(this, i); - struct spa_port_io *inio; + struct spa_io_buffers *inio; if ((inio = inport->io) == NULL || inport->n_buffers == 0) continue; if (inport->queued_bytes == 0) { - inio->range = outio->range; + if (inport->range && outport->range) + *inport->range = *outport->range; inio->status = SPA_STATUS_NEED_BUFFER; } else { inio->status = SPA_STATUS_OK; } - spa_log_trace(this->log, NAME " %p: port %d %d queued %zd, res %d", this, - i, outio->range.min_size, inport->queued_bytes, inio->status); + spa_log_trace(this->log, NAME " %p: port %d queued %zd, res %d", this, + i, inport->queued_bytes, inio->status); } } return outio->status; diff --git a/spa/plugins/audiotestsrc/audiotestsrc.c b/spa/plugins/audiotestsrc/audiotestsrc.c index bc031bd76..5fc9eadfa 100644 --- a/spa/plugins/audiotestsrc/audiotestsrc.c +++ b/spa/plugins/audiotestsrc/audiotestsrc.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -53,6 +54,7 @@ struct type { uint32_t prop_volume; uint32_t wave_sine; uint32_t wave_square; + struct spa_type_io io; struct spa_type_param param; struct spa_type_meta meta; struct spa_type_data data; @@ -78,6 +80,7 @@ static inline void init_type(struct type *type, struct spa_type_map *map) type->prop_volume = spa_type_map_get_id(map, SPA_TYPE_PROPS__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); spa_type_param_map(map, &type->param); spa_type_meta_map(map, &type->meta); spa_type_data_map(map, &type->data); @@ -132,7 +135,8 @@ struct impl { struct itimerspec timerspec; struct spa_port_info info; - struct spa_port_io *io; + struct spa_io_buffers *io; + struct spa_io_control_range *range; bool have_format; struct spa_audio_info current_format; @@ -295,7 +299,8 @@ static void read_timer(struct impl *this) static int make_buffer(struct impl *this) { struct buffer *b; - struct spa_port_io *io = this->io; + struct spa_io_buffers *io = this->io; + struct spa_io_control_range *range = this->range; int n_bytes, n_samples; uint32_t maxsize; void *data; @@ -319,10 +324,10 @@ static int make_buffer(struct impl *this) data = d[0].data; n_bytes = maxsize; - if (io->range.min_size != 0) { - n_bytes = SPA_MIN(n_bytes, io->range.min_size); - if (io->range.max_size < n_bytes) - n_bytes = io->range.max_size; + if (range && range->min_size != 0) { + n_bytes = SPA_MIN(n_bytes, range->min_size); + if (range->max_size < n_bytes) + n_bytes = range->max_size; } spa_log_trace(this->log, NAME " %p: dequeue buffer %d %d %d", this, b->outbuf->id, @@ -808,17 +813,25 @@ static int impl_node_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 impl *this; + struct type *t; spa_return_val_if_fail(node != NULL, -EINVAL); this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL); - this->io = io; + if (id == t->io.Buffers) + this->io = io; + else if (id == t->io.ControlRange) + this->range = io; + else + return -ENOENT; return 0; } @@ -870,7 +883,7 @@ static int impl_node_process_input(struct spa_node *node) static int impl_node_process_output(struct spa_node *node) { struct impl *this; - struct spa_port_io *io; + struct spa_io_buffers *io; spa_return_val_if_fail(node != NULL, -EINVAL); diff --git a/spa/plugins/ffmpeg/ffmpeg-dec.c b/spa/plugins/ffmpeg/ffmpeg-dec.c index 06658c2b0..099fa41a0 100644 --- a/spa/plugins/ffmpeg/ffmpeg-dec.c +++ b/spa/plugins/ffmpeg/ffmpeg-dec.c @@ -26,11 +26,16 @@ #include #include #include +#include #include #include -#define IS_VALID_PORT(this,d,id) ((id) == 0) +#define IS_VALID_PORT(this,d,id) ((id) == 0) +#define GET_IN_PORT(this,p) (&this->in_ports[p]) +#define GET_OUT_PORT(this,p) (&this->out_ports[p]) +#define GET_PORT(this,d,p) (d == SPA_DIRECTION_INPUT ? GET_IN_PORT(this,p) : GET_OUT_PORT(this,p)) + #define MAX_BUFFERS 32 struct buffer { @@ -45,11 +50,12 @@ struct port { bool have_buffers; struct buffer buffers[MAX_BUFFERS]; struct spa_port_info info; - struct spa_port_io *io; + struct spa_io_buffers *io; }; struct type { uint32_t node; + struct spa_type_io io; struct spa_type_param param; struct spa_type_media_type media_type; struct spa_type_media_subtype media_subtype; @@ -60,6 +66,7 @@ struct type { static inline void init_type(struct type *type, struct spa_type_map *map) { type->node = spa_type_map_get_id(map, SPA_TYPE__Node); + spa_type_io_map(map, &type->io); spa_type_param_map(map, &type->param); spa_type_media_type_map(map, &type->media_type); spa_type_media_subtype_map(map, &type->media_subtype); @@ -209,8 +216,8 @@ spa_ffmpeg_dec_node_port_get_info(struct spa_node *node, if (!IS_VALID_PORT(this, direction, port_id)) return -EINVAL; - port = - direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id]; + port = GET_PORT(this, direction, port_id); + *info = &port->info; return 0; @@ -253,8 +260,7 @@ static int port_get_format(struct spa_node *node, struct impl *this = SPA_CONTAINER_OF(node, struct impl, node); struct port *port; - port = - direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id]; + port = GET_PORT(this, direction, port_id); if (!port->have_format) return -EIO; @@ -330,8 +336,7 @@ static int port_set_format(struct spa_node *node, if (!IS_VALID_PORT(this, direction, port_id)) return -EINVAL; - port = - direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id]; + port = GET_PORT(this, direction, port_id); if (format == NULL) { port->have_format = false; @@ -406,22 +411,28 @@ static int spa_ffmpeg_dec_node_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 impl *this; struct port *port; + struct type *t; if (node == NULL) return -EINVAL; this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; if (!IS_VALID_PORT(this, direction, port_id)) return -EINVAL; - port = - direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id]; - port->io = io; + port = GET_PORT(this, direction, port_id); + + if (id == t->io.Buffers) + port->io = io; + else + return -ENOENT; return 0; } @@ -435,7 +446,7 @@ static int spa_ffmpeg_dec_node_process_output(struct spa_node *node) { struct impl *this; struct port *port; - struct spa_port_io *output; + struct spa_io_buffers *output; if (node == NULL) return -EINVAL; diff --git a/spa/plugins/ffmpeg/ffmpeg-enc.c b/spa/plugins/ffmpeg/ffmpeg-enc.c index 30b23b480..ea5d7ddd0 100644 --- a/spa/plugins/ffmpeg/ffmpeg-enc.c +++ b/spa/plugins/ffmpeg/ffmpeg-enc.c @@ -26,11 +26,16 @@ #include #include #include +#include #include #include -#define IS_VALID_PORT(this,d,id) ((id) == 0) +#define IS_VALID_PORT(this,d,id) ((id) == 0) +#define GET_IN_PORT(this,p) (&this->in_ports[p]) +#define GET_OUT_PORT(this,p) (&this->out_ports[p]) +#define GET_PORT(this,d,p) (d == SPA_DIRECTION_INPUT ? GET_IN_PORT(this,p) : GET_OUT_PORT(this,p)) + #define MAX_BUFFERS 32 struct buffer { @@ -49,11 +54,12 @@ struct port { bool have_buffers; struct buffer buffers[MAX_BUFFERS]; struct spa_port_info info; - struct spa_port_io *io; + struct spa_io_buffers *io; }; struct type { uint32_t node; + struct spa_type_io io; struct spa_type_param param; struct spa_type_media_type media_type; struct spa_type_media_subtype media_subtype; @@ -64,6 +70,7 @@ struct type { static inline void init_type(struct type *type, struct spa_type_map *map) { type->node = spa_type_map_get_id(map, SPA_TYPE__Node); + spa_type_io_map(map, &type->io); spa_type_param_map(map, &type->param); spa_type_media_type_map(map, &type->media_type); spa_type_media_subtype_map(map, &type->media_subtype); @@ -210,8 +217,7 @@ spa_ffmpeg_enc_node_port_get_info(struct spa_node *node, if (!IS_VALID_PORT(this, direction, port_id)) return -EINVAL; - port = - direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id]; + port = GET_PORT(this, direction, port_id); *info = &port->info; return 0; @@ -227,7 +233,7 @@ static int port_enum_formats(struct spa_node *node, //struct impl *this = SPA_CONTAINER_OF (node, struct impl, node); //struct port *port; - //port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id]; + //port = GET_PORT(this, direction, port_id); switch (*index) { case 0: @@ -249,8 +255,7 @@ static int port_get_format(struct spa_node *node, struct impl *this = SPA_CONTAINER_OF(node, struct impl, node); struct port *port; - port = - direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id]; + port = GET_PORT(this, direction, port_id); if (!port->have_format) return -EIO; @@ -317,8 +322,7 @@ static int port_set_format(struct spa_node *node, struct impl *this = SPA_CONTAINER_OF(node, struct impl, node); struct port *port; - port = - direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id]; + port = GET_PORT(this, direction, port_id); if (format == NULL) { port->have_format = false; @@ -391,22 +395,29 @@ spa_ffmpeg_enc_node_port_alloc_buffers(struct spa_node *node, static int spa_ffmpeg_enc_node_port_set_io(struct spa_node *node, enum spa_direction direction, - uint32_t port_id, struct spa_port_io *io) + uint32_t port_id, + uint32_t id, + void *io) { struct impl *this; struct port *port; + struct type *t; if (node == NULL) return -EINVAL; this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; if (!IS_VALID_PORT(this, direction, port_id)) return -EINVAL; - port = - direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id]; - port->io = io; + port = GET_PORT(this, direction, port_id); + + if (id == t->io.Buffers) + port->io = io; + else + return -ENOENT; return 0; } @@ -440,7 +451,7 @@ static int spa_ffmpeg_enc_node_process_output(struct spa_node *node) { struct impl *this; struct port *port; - struct spa_port_io *output; + struct spa_io_buffers *output; if (node == NULL) return -EINVAL; diff --git a/spa/plugins/test/fakesink.c b/spa/plugins/test/fakesink.c index cdbdf8925..926b5d2e1 100644 --- a/spa/plugins/test/fakesink.c +++ b/spa/plugins/test/fakesink.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -45,6 +46,7 @@ struct type { uint32_t format; uint32_t props; uint32_t prop_live; + struct spa_type_io io; struct spa_type_param param; struct spa_type_meta meta; struct spa_type_data data; @@ -61,6 +63,7 @@ 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_live = spa_type_map_get_id(map, SPA_TYPE_PROPS__live); + spa_type_io_map(map, &type->io); spa_type_param_map(map, &type->param); spa_type_meta_map(map, &type->meta); spa_type_data_map(map, &type->data); @@ -103,7 +106,7 @@ struct impl { struct itimerspec timerspec; struct spa_port_info info; - struct spa_port_io *io; + struct spa_io_buffers *io; bool have_format; uint8_t format_buffer[1024]; @@ -243,7 +246,7 @@ static void render_buffer(struct impl *this, struct buffer *b) static int consume_buffer(struct impl *this) { struct buffer *b; - struct spa_port_io *io = this->io; + struct spa_io_buffers *io = this->io; int n_bytes; read_timer(this); @@ -665,17 +668,23 @@ static int impl_node_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 impl *this; + struct type *t; spa_return_val_if_fail(node != NULL, -EINVAL); this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL); - this->io = io; + if (id == t->io.Buffers) + this->io = io; + else + return -ENOENT; return 0; } @@ -697,7 +706,7 @@ impl_node_port_send_command(struct spa_node *node, static int impl_node_process_input(struct spa_node *node) { struct impl *this; - struct spa_port_io *input; + struct spa_io_buffers *input; spa_return_val_if_fail(node != NULL, -EINVAL); diff --git a/spa/plugins/test/fakesrc.c b/spa/plugins/test/fakesrc.c index fe6e5bc23..15d9fcf7d 100644 --- a/spa/plugins/test/fakesrc.c +++ b/spa/plugins/test/fakesrc.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -46,6 +47,7 @@ struct type { uint32_t props; uint32_t prop_live; uint32_t prop_pattern; + struct spa_type_io io; struct spa_type_param param; struct spa_type_meta meta; struct spa_type_data data; @@ -63,6 +65,7 @@ static inline void init_type(struct type *type, struct spa_type_map *map) type->props = spa_type_map_get_id(map, SPA_TYPE__Props); type->prop_live = spa_type_map_get_id(map, SPA_TYPE_PROPS__live); type->prop_pattern = spa_type_map_get_id(map, SPA_TYPE_PROPS__patternType); + spa_type_io_map(map, &type->io); spa_type_param_map(map, &type->param); spa_type_meta_map(map, &type->meta); spa_type_data_map(map, &type->data); @@ -106,7 +109,7 @@ struct impl { struct itimerspec timerspec; struct spa_port_info info; - struct spa_port_io *io; + struct spa_io_buffers *io; bool have_format; uint8_t format_buffer[1024]; @@ -258,7 +261,7 @@ static inline void read_timer(struct impl *this) static int make_buffer(struct impl *this) { struct buffer *b; - struct spa_port_io *io = this->io; + struct spa_io_buffers *io = this->io; int n_bytes; read_timer(this); @@ -682,17 +685,23 @@ static int impl_node_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 impl *this; + struct type *t; spa_return_val_if_fail(node != NULL, -EINVAL); this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL); - this->io = io; + if (id == t->io.Buffers) + this->io = io; + else + return -ENOENT; return 0; } @@ -746,7 +755,7 @@ static int impl_node_process_input(struct spa_node *node) static int impl_node_process_output(struct spa_node *node) { struct impl *this; - struct spa_port_io *io; + struct spa_io_buffers *io; spa_return_val_if_fail(node != NULL, -EINVAL); diff --git a/spa/plugins/v4l2/v4l2-source.c b/spa/plugins/v4l2/v4l2-source.c index e74a4cb8d..855bc149a 100644 --- a/spa/plugins/v4l2/v4l2-source.c +++ b/spa/plugins/v4l2/v4l2-source.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -70,6 +71,7 @@ struct type { uint32_t prop_device; uint32_t prop_device_name; uint32_t prop_device_fd; + struct spa_type_io io; struct spa_type_param param; struct spa_type_media_type media_type; struct spa_type_media_subtype media_subtype; @@ -93,6 +95,7 @@ static inline void init_type(struct type *type, struct spa_type_map *map) type->prop_device = spa_type_map_get_id(map, SPA_TYPE_PROPS__device); type->prop_device_name = spa_type_map_get_id(map, SPA_TYPE_PROPS__deviceName); type->prop_device_fd = spa_type_map_get_id(map, SPA_TYPE_PROPS__deviceFd); + spa_type_io_map(map, &type->io); spa_type_param_map(map, &type->param); spa_type_media_type_map(map, &type->media_type); spa_type_media_subtype_map(map, &type->media_subtype); @@ -138,7 +141,7 @@ struct port { struct spa_source source; struct spa_port_info info; - struct spa_port_io *io; + struct spa_io_buffers *io; int64_t last_ticks; int64_t last_monotonic; @@ -759,17 +762,23 @@ impl_node_port_alloc_buffers(struct spa_node *node, static int impl_node_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 impl *this; + struct type *t; spa_return_val_if_fail(node != NULL, -EINVAL); this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL); - this->out_ports[port_id].io = io; + if (id == t->io.Buffers) + this->out_ports[port_id].io = io; + else + return -ENOENT; return 0; } @@ -828,7 +837,7 @@ static int impl_node_process_output(struct spa_node *node) { struct impl *this; int res = SPA_STATUS_OK; - struct spa_port_io *io; + struct spa_io_buffers *io; struct port *port; spa_return_val_if_fail(node != NULL, -EINVAL); diff --git a/spa/plugins/v4l2/v4l2-utils.c b/spa/plugins/v4l2/v4l2-utils.c index ed32e7d09..1ef20f9fd 100644 --- a/spa/plugins/v4l2/v4l2-utils.c +++ b/spa/plugins/v4l2/v4l2-utils.c @@ -902,7 +902,7 @@ static int mmap_read(struct impl *this) struct buffer *b; struct spa_data *d; int64_t pts; - struct spa_port_io *io = port->io; + struct spa_io_buffers *io = port->io; spa_zero(buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; diff --git a/spa/plugins/videotestsrc/videotestsrc.c b/spa/plugins/videotestsrc/videotestsrc.c index 124fd76c7..3bbdcd94c 100644 --- a/spa/plugins/videotestsrc/videotestsrc.c +++ b/spa/plugins/videotestsrc/videotestsrc.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -51,6 +52,7 @@ struct type { uint32_t prop_pattern; uint32_t pattern_smpte_snow; uint32_t pattern_snow; + struct spa_type_io io; struct spa_type_param param; struct spa_type_meta meta; struct spa_type_data data; @@ -74,6 +76,7 @@ static inline void init_type(struct type *type, struct spa_type_map *map) type->prop_pattern = spa_type_map_get_id(map, SPA_TYPE_PROPS__patternType); type->pattern_smpte_snow = spa_type_map_get_id(map, SPA_TYPE_PROPS__patternType ":smpte-snow"); type->pattern_snow = spa_type_map_get_id(map, SPA_TYPE_PROPS__patternType ":snow"); + spa_type_io_map(map, &type->io); spa_type_param_map(map, &type->param); spa_type_meta_map(map, &type->meta); spa_type_data_map(map, &type->data); @@ -122,7 +125,7 @@ struct impl { struct itimerspec timerspec; struct spa_port_info info; - struct spa_port_io *io; + struct spa_io_buffers *io; bool have_format; struct spa_video_info current_format; @@ -274,7 +277,7 @@ static void read_timer(struct impl *this) static int make_buffer(struct impl *this) { struct buffer *b; - struct spa_port_io *io = this->io; + struct spa_io_buffers *io = this->io; uint32_t n_bytes; read_timer(this); @@ -753,17 +756,23 @@ static int impl_node_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 impl *this; + struct type *t; spa_return_val_if_fail(node != NULL, -EINVAL); this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL); - this->io = io; + if (id == t->io.Buffers) + this->io = io; + else + return -ENOENT; return 0; } @@ -815,7 +824,7 @@ static int impl_node_process_input(struct spa_node *node) static int impl_node_process_output(struct spa_node *node) { struct impl *this; - struct spa_port_io *io; + struct spa_io_buffers *io; spa_return_val_if_fail(node != NULL, -EINVAL); diff --git a/spa/plugins/volume/volume.c b/spa/plugins/volume/volume.c index fab25fcd0..9a010b73e 100644 --- a/spa/plugins/volume/volume.c +++ b/spa/plugins/volume/volume.c @@ -25,9 +25,11 @@ #include #include #include +#include #include #include #include +#include #include @@ -56,7 +58,8 @@ struct port { struct buffer buffers[MAX_BUFFERS]; uint32_t n_buffers; - struct spa_port_io *io; + struct spa_io_buffers *io; + struct spa_io_control_range *range; struct spa_list empty; }; @@ -67,6 +70,7 @@ struct type { uint32_t props; uint32_t prop_volume; uint32_t prop_mute; + struct spa_type_io io; struct spa_type_param param; struct spa_type_meta meta; struct spa_type_data data; @@ -78,6 +82,7 @@ struct type { struct spa_type_command_node command_node; struct spa_type_param_buffers param_buffers; struct spa_type_param_meta param_meta; + struct spa_type_param_io param_io; }; static inline void init_type(struct type *type, struct spa_type_map *map) @@ -87,6 +92,7 @@ static inline void init_type(struct type *type, struct spa_type_map *map) 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->prop_mute = spa_type_map_get_id(map, SPA_TYPE_PROPS__mute); + spa_type_io_map(map, &type->io); spa_type_param_map(map, &type->param); spa_type_meta_map(map, &type->meta); spa_type_data_map(map, &type->data); @@ -98,6 +104,7 @@ static inline void init_type(struct type *type, struct spa_type_map *map) spa_type_command_node_map(map, &type->command_node); spa_type_param_buffers_map(map, &type->param_buffers); spa_type_param_meta_map(map, &type->param_meta); + spa_type_param_io_map(map, &type->param_io); } struct impl { @@ -417,7 +424,8 @@ impl_node_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.idIO }; if (*index < SPA_N_ELEMENTS(list)) param = spa_pod_builder_object(&b, id, t->param.List, @@ -461,6 +469,24 @@ impl_node_port_enum_params(struct spa_node *node, return 0; } } + else if (id == t->param.idIO) { + 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; + default: + return 0; + } + } else return -ENOENT; @@ -607,19 +633,28 @@ static int impl_node_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 impl *this; struct port *port; + struct type *t; spa_return_val_if_fail(node != NULL, -EINVAL); this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL); port = GET_PORT(this, direction, port_id); - port->io = io; + + if (id == t->io.Buffers) + port->io = io; + else if (id == t->io.ControlRange) + port->range = io; + else + return -ENOENT; return 0; } @@ -733,8 +768,7 @@ static void do_volume(struct impl *this, struct spa_buffer *dbuf, struct spa_buf static int impl_node_process_input(struct spa_node *node) { struct impl *this; - struct spa_port_io *input; - struct spa_port_io *output; + struct spa_io_buffers *input, *output; struct port *in_port, *out_port; struct spa_buffer *dbuf, *sbuf; @@ -780,7 +814,7 @@ static int impl_node_process_output(struct spa_node *node) { struct impl *this; struct port *in_port, *out_port; - struct spa_port_io *input, *output; + struct spa_io_buffers *input, *output; spa_return_val_if_fail(node != NULL, -EINVAL); @@ -803,7 +837,8 @@ static int impl_node_process_output(struct spa_node *node) input = in_port->io; spa_return_val_if_fail(input != NULL, -EIO); - input->range = output->range; + if (in_port->range && out_port->range) + *in_port->range = *out_port->range; input->status = SPA_STATUS_NEED_BUFFER; return SPA_STATUS_NEED_BUFFER; diff --git a/spa/tests/test-graph.c b/spa/tests/test-graph.c index 54159cd36..f6a537c21 100644 --- a/spa/tests/test-graph.c +++ b/spa/tests/test-graph.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -54,6 +55,7 @@ struct type { uint32_t props_volume; uint32_t props_min_latency; uint32_t props_live; + struct spa_type_io io; struct spa_type_param param; struct spa_type_meta meta; struct spa_type_data data; @@ -75,6 +77,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); + spa_type_io_map(map, &type->io); spa_type_param_map(map, &type->param); spa_type_meta_map(map, &type->meta); spa_type_data_map(map, &type->data); @@ -114,14 +117,14 @@ struct data { struct spa_graph_node sink_node; struct spa_node *sink; - struct spa_port_io volume_sink_io[1]; + struct spa_io_buffers volume_sink_io[1]; struct spa_node *volume; struct spa_buffer *volume_buffers[1]; struct buffer volume_buffer[1]; struct spa_node *source; - struct spa_port_io source_volume_io[1]; + struct spa_io_buffers source_volume_io[1]; struct spa_buffer *source_buffers[1]; struct buffer source_buffer[1]; @@ -330,13 +333,21 @@ static int make_nodes(struct data *data, const char *device) if ((res = spa_node_set_param(data->source, data->type.param.idProps, 0, props)) < 0) printf("got set_props error %d\n", res); - data->source_volume_io[0] = SPA_PORT_IO_INIT; - data->volume_sink_io[0] = SPA_PORT_IO_INIT; + data->source_volume_io[0] = SPA_IO_BUFFERS_INIT; + data->volume_sink_io[0] = SPA_IO_BUFFERS_INIT; - spa_node_port_set_io(data->source, SPA_DIRECTION_OUTPUT, 0, &data->source_volume_io[0]); - spa_node_port_set_io(data->volume, SPA_DIRECTION_INPUT, 0, &data->source_volume_io[0]); - spa_node_port_set_io(data->volume, SPA_DIRECTION_OUTPUT, 0, &data->volume_sink_io[0]); - spa_node_port_set_io(data->sink, SPA_DIRECTION_INPUT, 0, &data->volume_sink_io[0]); + spa_node_port_set_io(data->source, + SPA_DIRECTION_OUTPUT, 0, + data->type.io.Buffers, &data->source_volume_io[0]); + spa_node_port_set_io(data->volume, + SPA_DIRECTION_INPUT, 0, + data->type.io.Buffers, &data->source_volume_io[0]); + spa_node_port_set_io(data->volume, + SPA_DIRECTION_OUTPUT, 0, + data->type.io.Buffers, &data->volume_sink_io[0]); + spa_node_port_set_io(data->sink, + SPA_DIRECTION_INPUT, 0, + data->type.io.Buffers, &data->volume_sink_io[0]); spa_graph_node_init(&data->source_node); spa_graph_node_set_implementation(&data->source_node, data->source); diff --git a/spa/tests/test-mixer.c b/spa/tests/test-mixer.c index 35195df91..b558b33c0 100644 --- a/spa/tests/test-mixer.c +++ b/spa/tests/test-mixer.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -56,6 +57,7 @@ struct type { uint32_t props_volume; uint32_t props_min_latency; uint32_t props_live; + struct spa_type_io io; struct spa_type_param param; struct spa_type_meta meta; struct spa_type_data data; @@ -77,6 +79,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); + spa_type_io_map(map, &type->io); spa_type_param_map(map, &type->param); spa_type_meta_map(map, &type->meta); spa_type_data_map(map, &type->data); @@ -118,7 +121,7 @@ struct data { struct spa_graph_node sink_node; struct spa_node *sink; - struct spa_port_io mix_sink_io[1]; + struct spa_io_buffers mix_sink_io[1]; struct spa_node *mix; uint32_t mix_ports[2]; @@ -126,12 +129,12 @@ struct data { struct buffer mix_buffer[1]; struct spa_node *source1; - struct spa_port_io source1_mix_io[1]; + struct spa_io_buffers source1_mix_io[1]; struct spa_buffer *source1_buffers[2]; struct buffer source1_buffer[2]; struct spa_node *source2; - struct spa_port_io source2_mix_io[1]; + struct spa_io_buffers source2_mix_io[1]; struct spa_buffer *source2_buffers[2]; struct buffer source2_buffer[2]; @@ -398,16 +401,28 @@ static int make_nodes(struct data *data, const char *device) if ((res = spa_node_add_port(data->mix, SPA_DIRECTION_INPUT, 1)) < 0) return res; - data->source1_mix_io[0] = SPA_PORT_IO_INIT; - data->source2_mix_io[0] = SPA_PORT_IO_INIT; - data->mix_sink_io[0] = SPA_PORT_IO_INIT; + data->source1_mix_io[0] = SPA_IO_BUFFERS_INIT; + data->source2_mix_io[0] = SPA_IO_BUFFERS_INIT; + data->mix_sink_io[0] = SPA_IO_BUFFERS_INIT; - spa_node_port_set_io(data->source1, SPA_DIRECTION_OUTPUT, 0, &data->source1_mix_io[0]); - spa_node_port_set_io(data->source2, SPA_DIRECTION_OUTPUT, 0, &data->source2_mix_io[0]); - spa_node_port_set_io(data->mix, SPA_DIRECTION_INPUT, 0, &data->source1_mix_io[0]); - spa_node_port_set_io(data->mix, SPA_DIRECTION_INPUT, 1, &data->source2_mix_io[0]); - spa_node_port_set_io(data->mix, SPA_DIRECTION_OUTPUT, 0, &data->mix_sink_io[0]); - spa_node_port_set_io(data->sink, SPA_DIRECTION_INPUT, 0, &data->mix_sink_io[0]); + spa_node_port_set_io(data->source1, + SPA_DIRECTION_OUTPUT, 0, + data->type.io.Buffers, &data->source1_mix_io[0]); + spa_node_port_set_io(data->source2, + SPA_DIRECTION_OUTPUT, 0, + data->type.io.Buffers, &data->source2_mix_io[0]); + spa_node_port_set_io(data->mix, + SPA_DIRECTION_INPUT, 0, + data->type.io.Buffers, &data->source1_mix_io[0]); + spa_node_port_set_io(data->mix, + SPA_DIRECTION_INPUT, 1, + data->type.io.Buffers, &data->source2_mix_io[0]); + spa_node_port_set_io(data->mix, + SPA_DIRECTION_OUTPUT, 0, + data->type.io.Buffers, &data->mix_sink_io[0]); + spa_node_port_set_io(data->sink, + SPA_DIRECTION_INPUT, 0, + data->type.io.Buffers, &data->mix_sink_io[0]); #ifdef USE_GRAPH spa_graph_node_init(&data->source1_node); diff --git a/spa/tests/test-perf.c b/spa/tests/test-perf.c index 324b616c9..ce77cfc89 100644 --- a/spa/tests/test-perf.c +++ b/spa/tests/test-perf.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -56,6 +57,7 @@ struct type { uint32_t props_volume; uint32_t props_min_latency; uint32_t props_live; + struct spa_type_io io; struct spa_type_param param; struct spa_type_meta meta; struct spa_type_data data; @@ -75,6 +77,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); + spa_type_io_map(map, &type->io); spa_type_param_map(map, &type->param); spa_type_meta_map(map, &type->meta); spa_type_data_map(map, &type->data); @@ -113,7 +116,7 @@ struct data { struct spa_graph_node sink_node; struct spa_node *sink; - struct spa_port_io source_sink_io[1]; + struct spa_io_buffers source_sink_io[1]; struct spa_node *source; struct spa_buffer *source_buffers[1]; @@ -358,11 +361,15 @@ static int make_nodes(struct data *data) if (data->mode & MODE_ASYNC_PUSH) spa_node_set_callbacks(data->source, &source_callbacks, data); - data->source_sink_io[0] = SPA_PORT_IO_INIT; + data->source_sink_io[0] = SPA_IO_BUFFERS_INIT; data->source_sink_io[0].status = SPA_STATUS_NEED_BUFFER; - spa_node_port_set_io(data->source, SPA_DIRECTION_OUTPUT, 0, &data->source_sink_io[0]); - spa_node_port_set_io(data->sink, SPA_DIRECTION_INPUT, 0, &data->source_sink_io[0]); + spa_node_port_set_io(data->source, + SPA_DIRECTION_OUTPUT, 0, + data->type.io.Buffers, &data->source_sink_io[0]); + spa_node_port_set_io(data->sink, + SPA_DIRECTION_INPUT, 0, + data->type.io.Buffers, &data->source_sink_io[0]); spa_graph_node_init(&data->source_node); spa_graph_node_set_implementation(&data->source_node, data->source); diff --git a/spa/tests/test-ringbuffer.c b/spa/tests/test-ringbuffer.c index 4cf6bfd29..fab838dfc 100644 --- a/spa/tests/test-ringbuffer.c +++ b/spa/tests/test-ringbuffer.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -49,6 +50,7 @@ struct type { uint32_t props_volume; uint32_t props_min_latency; uint32_t props_live; + struct spa_type_io io; struct spa_type_param param; struct spa_type_meta meta; struct spa_type_data data; @@ -70,6 +72,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); + spa_type_io_map(map, &type->io); spa_type_param_map(map, &type->param); spa_type_meta_map(map, &type->meta); spa_type_data_map(map, &type->data); @@ -99,7 +102,7 @@ struct data { uint32_t n_support; struct spa_node *sink; - struct spa_port_io source_sink_io[1]; + struct spa_io_buffers source_sink_io[1]; struct spa_node *source; struct spa_buffer *source_buffers[1]; @@ -339,10 +342,14 @@ static int negotiate_formats(struct data *data) format)) < 0) return res; - data->source_sink_io[0] = SPA_PORT_IO_INIT; + data->source_sink_io[0] = SPA_IO_BUFFERS_INIT; - spa_node_port_set_io(data->source, SPA_DIRECTION_OUTPUT, 0, &data->source_sink_io[0]); - spa_node_port_set_io(data->sink, SPA_DIRECTION_INPUT, 0, &data->source_sink_io[0]); + spa_node_port_set_io(data->source, + SPA_DIRECTION_OUTPUT, 0, + data->type.io.Buffers, &data->source_sink_io[0]); + spa_node_port_set_io(data->sink, + SPA_DIRECTION_INPUT, 0, + data->type.io.Buffers, &data->source_sink_io[0]); if ((res = spa_node_port_set_param(data->source, SPA_DIRECTION_OUTPUT, 0, diff --git a/spa/tests/test-v4l2.c b/spa/tests/test-v4l2.c index 76357835c..584cd641f 100644 --- a/spa/tests/test-v4l2.c +++ b/spa/tests/test-v4l2.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -49,6 +50,7 @@ struct type { uint32_t format; uint32_t props_device; uint32_t SDL_Texture; + struct spa_type_io io; struct spa_type_param param; struct spa_type_meta meta; struct spa_type_data data; @@ -67,6 +69,7 @@ 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_device = spa_type_map_get_id(map, SPA_TYPE_PROPS__device); type->SDL_Texture = spa_type_map_get_id(map, SPA_TYPE_POINTER_BASE "SDL_Texture"); + spa_type_io_map(map, &type->io); spa_type_param_map(map, &type->param); spa_type_meta_map(map, &type->meta); spa_type_data_map(map, &type->data); @@ -100,7 +103,7 @@ struct data { uint32_t n_support; struct spa_node *source; - struct spa_port_io source_output[1]; + struct spa_io_buffers source_output[1]; SDL_Renderer *renderer; SDL_Window *window; @@ -205,7 +208,7 @@ static void on_source_have_output(void *_data) int i; uint8_t *src, *dst; struct spa_data *datas; - struct spa_port_io *io = &data->source_output[0]; + struct spa_io_buffers *io = &data->source_output[0]; handle_events(data); @@ -419,11 +422,12 @@ static int negotiate_formats(struct data *data) uint8_t buffer[256]; struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer)); - data->source_output[0] = SPA_PORT_IO_INIT; + data->source_output[0] = SPA_IO_BUFFERS_INIT; if ((res = - spa_node_port_set_io(data->source, SPA_DIRECTION_OUTPUT, 0, - &data->source_output[0])) < 0) + spa_node_port_set_io(data->source, + SPA_DIRECTION_OUTPUT, 0, + data->type.io.Buffers, &data->source_output[0])) < 0) return res; format = spa_pod_builder_object(&b, diff --git a/spa/tools/spa-inspect.c b/spa/tools/spa-inspect.c index 2f8eadbb9..83fe09c1b 100644 --- a/spa/tools/spa-inspect.c +++ b/spa/tools/spa-inspect.c @@ -249,7 +249,7 @@ static void do_remove_source(struct spa_source *source) int main(int argc, char *argv[]) { - struct data data; + struct data data = { 0 }; int res; void *handle; spa_handle_factory_enum_func_t enum_func; diff --git a/src/examples/export-sink.c b/src/examples/export-sink.c index 939447cbc..42cdea150 100644 --- a/src/examples/export-sink.c +++ b/src/examples/export-sink.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -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; } diff --git a/src/examples/export-source.c b/src/examples/export-source.c index df6ac5040..6055c864d 100644 --- a/src/examples/export-source.c +++ b/src/examples/export-source.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -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; diff --git a/src/examples/local-v4l2.c b/src/examples/local-v4l2.c index dc3e8f677..8e3fd191f 100644 --- a/src/examples/local-v4l2.c +++ b/src/examples/local-v4l2.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -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; } diff --git a/src/extensions/client-node.h b/src/extensions/client-node.h index d90f83ca3..068c3620a 100644 --- a/src/extensions/client-node.h +++ b/src/extensions/client-node.h @@ -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 */ diff --git a/src/modules/module-client-node/client-node.c b/src/modules/module-client-node/client-node.c index 2d880c9ca..a348d2aee 100644 --- a/src/modules/module-client-node/client-node.c +++ b/src/modules/module-client-node/client-node.c @@ -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; diff --git a/src/modules/module-client-node/transport.c b/src/modules/module-client-node/transport.c index e26f155d2..27c2cf1cb 100644 --- a/src/modules/module-client-node/transport.c +++ b/src/modules/module-client-node/transport.c @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -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); diff --git a/src/modules/module-jack/jack-node.c b/src/modules/module-jack/jack-node.c index 2d07836fe..c5d4a18f9 100644 --- a/src/modules/module-jack/jack-node.c +++ b/src/modules/module-jack/jack-node.c @@ -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; diff --git a/src/pipewire/link.c b/src/pipewire/link.c index c7cffedf3..1f7b78026 100644 --- a/src/pipewire/link.c +++ b/src/pipewire/link.c @@ -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, diff --git a/src/pipewire/port.c b/src/pipewire/port.c index d6f5b1acb..4e2036731 100644 --- a/src/pipewire/port.c +++ b/src/pipewire/port.c @@ -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); diff --git a/src/pipewire/private.h b/src/pipewire/private.h index c0e5dd839..9e0d6c82e 100644 --- a/src/pipewire/private.h +++ b/src/pipewire/private.h @@ -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 */ diff --git a/src/pipewire/remote.c b/src/pipewire/remote.c index 112f88d6f..11a11a147 100644 --- a/src/pipewire/remote.c +++ b/src/pipewire/remote.c @@ -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, diff --git a/src/pipewire/stream.c b/src/pipewire/stream.c index d4b72d52a..1b8f2ccdc 100644 --- a/src/pipewire/stream.c +++ b/src/pipewire/stream.c @@ -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 { diff --git a/src/pipewire/type.c b/src/pipewire/type.c index 3619290d4..ab0daa3ad 100644 --- a/src/pipewire/type.c +++ b/src/pipewire/type.c @@ -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); diff --git a/src/pipewire/type.h b/src/pipewire/type.h index 6452e1d49..caf810a8c 100644 --- a/src/pipewire/type.h +++ b/src/pipewire/type.h @@ -30,6 +30,7 @@ extern "C" { #include #include #include +#include #include @@ -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;