diff --git a/pipewire-jack/src/pipewire-jack.c b/pipewire-jack/src/pipewire-jack.c index 95dd26f2e..a06217423 100644 --- a/pipewire-jack/src/pipewire-jack.c +++ b/pipewire-jack/src/pipewire-jack.c @@ -364,6 +364,7 @@ struct client { unsigned int merge_monitor:1; unsigned int short_name:1; unsigned int filter_name:1; + unsigned int freewheeling:1; int self_connect_mode; jack_position_t jack_position; @@ -1393,8 +1394,17 @@ do_update_driver_activation(struct spa_loop *loop, static int update_driver_activation(struct client *c) { struct link *link; + bool freewheeling; + pw_log_debug(NAME" %p: driver %d", c, c->driver_id); + freewheeling = SPA_FLAG_IS_SET(c->position->clock.flags, SPA_IO_CLOCK_FLAG_FREEWHEEL); + if (c->freewheeling != freewheeling) { + c->freewheeling = freewheeling; + if (c->freewheel_callback) + c->freewheel_callback(freewheeling, c->freewheel_arg); + } + link = find_activation(&c->links, c->driver_id); c->driver_activation = link ? link->activation : NULL; pw_data_loop_invoke(c->loop, diff --git a/spa/include/spa/node/io.h b/spa/include/spa/node/io.h index 2f2a084d8..1da22adff 100644 --- a/spa/include/spa/node/io.h +++ b/spa/include/spa/node/io.h @@ -125,6 +125,7 @@ struct spa_io_range { * since the provider was last started. */ struct spa_io_clock { +#define SPA_IO_CLOCK_FLAG_FREEWHEEL (1u<<0) uint32_t flags; /**< clock flags */ uint32_t id; /**< unique clock id, set by application */ char name[64]; /**< clock name prefixed with API, set by node. The clock name diff --git a/spa/plugins/alsa/alsa-pcm-sink.c b/spa/plugins/alsa/alsa-pcm-sink.c index 76302a62f..8df1a54dd 100644 --- a/spa/plugins/alsa/alsa-pcm-sink.c +++ b/spa/plugins/alsa/alsa-pcm-sink.c @@ -640,8 +640,9 @@ static int impl_node_process(void *object) spa_log_trace_fp(this->log, NAME " %p: process %d %d/%d", this, input->status, input->buffer_id, this->n_buffers); - - if (input->status == SPA_STATUS_HAVE_DATA && + if (this->position && this->position->clock.flags & SPA_IO_CLOCK_FLAG_FREEWHEEL) { + input->status = SPA_STATUS_NEED_DATA; + } else if (input->status == SPA_STATUS_HAVE_DATA && input->buffer_id < this->n_buffers) { struct buffer *b = &this->buffers[input->buffer_id]; diff --git a/spa/plugins/alsa/alsa-pcm-source.c b/spa/plugins/alsa/alsa-pcm-source.c index a33450d7a..dd9c8ecd4 100644 --- a/spa/plugins/alsa/alsa-pcm-source.c +++ b/spa/plugins/alsa/alsa-pcm-source.c @@ -666,6 +666,12 @@ static int impl_node_process(void *object) spa_alsa_recycle_buffer(this, io->buffer_id); io->buffer_id = SPA_ID_INVALID; } + if (this->position && this->position->clock.flags & SPA_IO_CLOCK_FLAG_FREEWHEEL) { + spa_log_info(this->log, NAME " %p:freewheel", this); + io->status = SPA_STATUS_HAVE_DATA; + io->buffer_id = 0; + return SPA_STATUS_HAVE_DATA; + } if (spa_list_is_empty(&this->ready) && this->following) spa_alsa_read(this, 0); diff --git a/src/pipewire/impl-node.c b/src/pipewire/impl-node.c index f9e4fffc4..b1af8e7ee 100644 --- a/src/pipewire/impl-node.c +++ b/src/pipewire/impl-node.c @@ -864,6 +864,7 @@ static void check_properties(struct pw_impl_node *node) if (strcmp(str, node->group) != 0) { pw_log_info(NAME" %p: group '%s'->'%s'", node, node->group, str); snprintf(node->group, sizeof(node->group), "%s", str); + node->freewheel = strcmp(node->group, "pipewire.freewheel") == 0; recalc_reason = "group changed"; } diff --git a/src/pipewire/private.h b/src/pipewire/private.h index c5a774901..51da74eac 100644 --- a/src/pipewire/private.h +++ b/src/pipewire/private.h @@ -636,6 +636,7 @@ struct pw_impl_node { unsigned int visited:1; /**< for sorting */ unsigned int want_driver:1; /**< this node wants to be assigned to a driver */ unsigned int passive:1; /**< driver graph only has passive links */ + unsigned int freewheel:1; /**< if this is the freewheel driver */ uint32_t port_user_data_size; /**< extra size for port user data */