impl-port: swap io areas instead of doing cycle math

Instead of doing (cycle+1) & 1 for output ports, simply swap the io
areas depending on the port direction (0 = input, 1 = output) and
just to cycle&1 for all ports.
This commit is contained in:
Wim Taymans 2024-05-08 10:43:41 +02:00
parent 03d62dc756
commit fac0d47c23
4 changed files with 14 additions and 15 deletions

View file

@ -578,8 +578,8 @@ do_mix_set_io(struct spa_loop *loop, bool async, uint32_t seq,
info->mix->io_data = info->data; info->mix->io_data = info->data;
if (info->mix->io_data) { if (info->mix->io_data) {
if (info->size >= sizeof(struct spa_io_async_buffers)) { if (info->size >= sizeof(struct spa_io_async_buffers)) {
info->mix->io[0] = &info->mix->io_data[0]; info->mix->io[0] = &info->mix->io_data[port->direction];
info->mix->io[1] = &info->mix->io_data[1]; info->mix->io[1] = &info->mix->io_data[port->direction^1];
} else if (info->size >= sizeof(struct spa_io_buffers)) { } else if (info->size >= sizeof(struct spa_io_buffers)) {
info->mix->io[0] = &info->mix->io_data[0]; info->mix->io[0] = &info->mix->io_data[0];
info->mix->io[1] = &info->mix->io_data[0]; info->mix->io[1] = &info->mix->io_data[0];
@ -1512,7 +1512,7 @@ static inline void *get_buffer_output(struct port *p, uint32_t frames, uint32_t
struct buffer *b; struct buffer *b;
struct spa_data *d; struct spa_data *d;
struct spa_io_buffers *io; struct spa_io_buffers *io;
uint32_t cycle = (p->client->rt.position->clock.cycle + 1) & 1; uint32_t cycle = p->client->rt.position->clock.cycle & 1;
if (frames == 0 || !p->valid) if (frames == 0 || !p->valid)
return NULL; return NULL;
@ -1596,11 +1596,10 @@ static inline void process_empty(struct port *p, uint32_t frames)
} }
} }
static void prepare_output(struct port *p, uint32_t frames) static void prepare_output(struct port *p, uint32_t frames, uint32_t cycle)
{ {
struct mix *mix; struct mix *mix;
struct spa_io_buffers *io; struct spa_io_buffers *io;
uint32_t cycle = (p->client->rt.position->clock.cycle + 1) & 1;
if (SPA_UNLIKELY(p->empty_out || p->tied)) if (SPA_UNLIKELY(p->empty_out || p->tied))
process_empty(p, frames); process_empty(p, frames);
@ -1619,7 +1618,7 @@ static void complete_process(struct client *c, uint32_t frames)
struct port *p; struct port *p;
struct mix *mix; struct mix *mix;
union pw_map_item *item; union pw_map_item *item;
uint32_t cycle = (c->rt.position->clock.cycle + 1) & 1; uint32_t cycle = c->rt.position->clock.cycle & 1;
pw_array_for_each(item, &c->ports[SPA_DIRECTION_OUTPUT].items) { pw_array_for_each(item, &c->ports[SPA_DIRECTION_OUTPUT].items) {
if (pw_map_item_is_free(item)) if (pw_map_item_is_free(item))
@ -1627,7 +1626,7 @@ static void complete_process(struct client *c, uint32_t frames)
p = item->data; p = item->data;
if (!p->valid) if (!p->valid)
continue; continue;
prepare_output(p, frames); prepare_output(p, frames, cycle);
p->io[cycle].status = SPA_STATUS_NEED_DATA; p->io[cycle].status = SPA_STATUS_NEED_DATA;
} }
pw_array_for_each(item, &c->ports[SPA_DIRECTION_INPUT].items) { pw_array_for_each(item, &c->ports[SPA_DIRECTION_INPUT].items) {
@ -5250,7 +5249,7 @@ static struct buffer *get_mix_buffer(struct client *c, struct mix *mix, jack_nfr
uint32_t cycle = c->rt.position->clock.cycle & 1; uint32_t cycle = c->rt.position->clock.cycle & 1;
if (mix->peer_port != NULL) if (mix->peer_port != NULL)
prepare_output(mix->peer_port, frames); prepare_output(mix->peer_port, frames, cycle);
io = mix->io[cycle]; io = mix->io[cycle];
if (io == NULL || if (io == NULL ||

View file

@ -726,8 +726,8 @@ static int do_port_set_io(struct spa_loop *loop, bool async, uint32_t seq,
struct io_info *info = user_data; struct io_info *info = user_data;
if (info->size >= sizeof(struct spa_io_async_buffers)) { if (info->size >= sizeof(struct spa_io_async_buffers)) {
struct spa_io_async_buffers *ab = info->data; struct spa_io_async_buffers *ab = info->data;
info->port->io[0] = &ab->buffers[0]; info->port->io[0] = &ab->buffers[info->port->direction];
info->port->io[1] = &ab->buffers[1]; info->port->io[1] = &ab->buffers[info->port->direction^1];
} else if (info->size >= sizeof(struct spa_io_buffers)) { } else if (info->size >= sizeof(struct spa_io_buffers)) {
info->port->io[0] = info->data; info->port->io[0] = info->data;
info->port->io[1] = info->data; info->port->io[1] = info->data;

View file

@ -661,8 +661,8 @@ static int do_port_set_io(struct spa_loop *loop, bool async, uint32_t seq,
struct io_info *info = user_data; struct io_info *info = user_data;
if (info->size >= sizeof(struct spa_io_async_buffers)) { if (info->size >= sizeof(struct spa_io_async_buffers)) {
struct spa_io_async_buffers *ab = info->data; struct spa_io_async_buffers *ab = info->data;
info->port->io[0] = &ab->buffers[0]; info->port->io[0] = &ab->buffers[info->port->direction];
info->port->io[1] = &ab->buffers[1]; info->port->io[1] = &ab->buffers[info->port->direction^1];
} else if (info->size >= sizeof(struct spa_io_buffers)) { } else if (info->size >= sizeof(struct spa_io_buffers)) {
info->port->io[0] = info->data; info->port->io[0] = info->data;
info->port->io[1] = info->data; info->port->io[1] = info->data;

View file

@ -261,8 +261,8 @@ static int port_set_io(void *object,
if (size >= sizeof(struct spa_io_async_buffers)) { if (size >= sizeof(struct spa_io_async_buffers)) {
struct spa_io_async_buffers *ab = data; struct spa_io_async_buffers *ab = data;
mix->io_data = data; mix->io_data = data;
mix->io[0] = &ab->buffers[0]; mix->io[0] = &ab->buffers[this->direction];
mix->io[1] = &ab->buffers[1]; mix->io[1] = &ab->buffers[this->direction^1];
} else { } else {
mix->io_data = mix->io[0] = mix->io[1] = data; mix->io_data = mix->io[0] = mix->io[1] = data;
} }
@ -279,7 +279,7 @@ static int tee_process(void *object)
struct pw_impl_port *this = &impl->this; struct pw_impl_port *this = &impl->this;
struct pw_impl_port_mix *mix; struct pw_impl_port_mix *mix;
struct spa_io_buffers *io = &this->rt.io; struct spa_io_buffers *io = &this->rt.io;
uint32_t cycle = (this->node->rt.position->clock.cycle + 1) & 1; uint32_t cycle = this->node->rt.position->clock.cycle & 1;
pw_log_trace_fp("%p: tee input status:%d id:%d cycle:%d", this, io->status, io->buffer_id, cycle); pw_log_trace_fp("%p: tee input status:%d id:%d cycle:%d", this, io->status, io->buffer_id, cycle);
spa_list_for_each(mix, &impl->rt.mix_list, rt.link) { spa_list_for_each(mix, &impl->rt.mix_list, rt.link) {