node: use new node.transport property to start/stop transport

Instead of modifying the driver activation to start/stop the transport,
use a property on the node and let the server handle the change.
This commit is contained in:
Wim Taymans 2024-02-29 17:45:28 +01:00
parent ccf899a709
commit d063ab7322
5 changed files with 40 additions and 9 deletions

View file

@ -6798,12 +6798,24 @@ int jack_transport_reposition (jack_client_t *client,
return 0; return 0;
} }
static void update_command(struct client *c, uint32_t command) static int transport_update(struct client* c, int active)
{ {
struct pw_node_activation *a = c->rt.driver_activation; pw_log_info("%p: transport %d", c, active);
if (!a)
return; pw_thread_loop_lock(c->context.loop);
SPA_ATOMIC_STORE(a->command, command); pw_properties_set(c->props, PW_KEY_NODE_TRANSPORT,
active ? "true" : "false");
c->info.change_mask |= SPA_NODE_CHANGE_MASK_PROPS;
c->info.props = &c->props->dict;
pw_client_node_update(c->node,
PW_CLIENT_NODE_UPDATE_INFO,
0, NULL, &c->info);
c->info.change_mask = 0;
pw_thread_loop_unlock(c->context.loop);
return 0;
} }
SPA_EXPORT SPA_EXPORT
@ -6811,7 +6823,7 @@ void jack_transport_start (jack_client_t *client)
{ {
struct client *c = (struct client *) client; struct client *c = (struct client *) client;
return_if_fail(c != NULL); return_if_fail(c != NULL);
update_command(c, PW_NODE_ACTIVATION_COMMAND_START); transport_update(c, true);
} }
SPA_EXPORT SPA_EXPORT
@ -6819,7 +6831,7 @@ void jack_transport_stop (jack_client_t *client)
{ {
struct client *c = (struct client *) client; struct client *c = (struct client *) client;
return_if_fail(c != NULL); return_if_fail(c != NULL);
update_command(c, PW_NODE_ACTIVATION_COMMAND_STOP); transport_update(c, false);
} }
SPA_EXPORT SPA_EXPORT

View file

@ -1221,7 +1221,7 @@ int pw_context_recalc_graph(struct pw_context *context, const char *reason)
const uint32_t *rates; const uint32_t *rates;
uint32_t max_quantum, min_quantum, def_quantum, lim_quantum, rate_quantum; uint32_t max_quantum, min_quantum, def_quantum, lim_quantum, rate_quantum;
uint32_t n_rates, def_rate; uint32_t n_rates, def_rate;
bool freewheel = false, global_force_rate, global_force_quantum; bool freewheel, global_force_rate, global_force_quantum, transport_start;
struct spa_list collect; struct spa_list collect;
pw_log_info("%p: busy:%d reason:%s", context, impl->recalc, reason); pw_log_info("%p: busy:%d reason:%s", context, impl->recalc, reason);
@ -1233,6 +1233,8 @@ int pw_context_recalc_graph(struct pw_context *context, const char *reason)
again: again:
impl->recalc = true; impl->recalc = true;
freewheel = false;
transport_start = false;
/* clean up the flags first */ /* clean up the flags first */
spa_list_for_each(n, &context->node_list, link) { spa_list_for_each(n, &context->node_list, link) {
@ -1574,12 +1576,20 @@ again:
/* first change the node states of the followers to the new target */ /* first change the node states of the followers to the new target */
spa_list_for_each(s, &n->follower_list, follower_link) { spa_list_for_each(s, &n->follower_list, follower_link) {
if (s->transport)
transport_start = true;
if (s == n) if (s == n)
continue; continue;
pw_log_debug("%p: follower %p: active:%d '%s'", pw_log_debug("%p: follower %p: active:%d '%s'",
context, s, s->active, s->name); context, s, s->active, s->name);
ensure_state(s, running); ensure_state(s, running);
} }
SPA_ATOMIC_STORE(n->rt.target.activation->command,
transport_start ?
PW_NODE_ACTIVATION_COMMAND_START :
PW_NODE_ACTIVATION_COMMAND_STOP);
/* now that all the followers are ready, start the driver */ /* now that all the followers are ready, start the driver */
ensure_state(n, running); ensure_state(n, running);
} }

View file

@ -938,7 +938,7 @@ static void check_properties(struct pw_impl_node *node)
const char *str, *recalc_reason = NULL; const char *str, *recalc_reason = NULL;
struct spa_fraction frac; struct spa_fraction frac;
uint32_t value; uint32_t value;
bool driver, trigger; bool driver, trigger, transport;
struct match match; struct match match;
match = MATCH_INIT(node); match = MATCH_INIT(node);
@ -1021,6 +1021,13 @@ static void check_properties(struct pw_impl_node *node)
recalc_reason = "link group changed"; recalc_reason = "link group changed";
} }
transport = pw_properties_get_bool(node->properties, PW_KEY_NODE_TRANSPORT, false);
if (transport != node->transport) {
pw_log_info("%p: transport %d -> %d", node, node->transport, transport);
node->transport = transport;
recalc_reason = "transport changed";
}
if ((str = pw_properties_get(node->properties, PW_KEY_MEDIA_CLASS)) != NULL && if ((str = pw_properties_get(node->properties, PW_KEY_MEDIA_CLASS)) != NULL &&
(strstr(str, "/Sink") != NULL || strstr(str, "/Source") != NULL)) { (strstr(str, "/Sink") != NULL || strstr(str, "/Source") != NULL)) {
node->can_suspend = true; node->can_suspend = true;

View file

@ -139,6 +139,7 @@ extern "C" {
* in the same group are always scheduled * in the same group are always scheduled
* with the same driver. Can be an array of * with the same driver. Can be an array of
* group names. */ * group names. */
#define PW_KEY_NODE_TRANSPORT "node.transport" /**< if the transport is active or not */
#define PW_KEY_NODE_EXCLUSIVE "node.exclusive" /**< node wants exclusive access to resources */ #define PW_KEY_NODE_EXCLUSIVE "node.exclusive" /**< node wants exclusive access to resources */
#define PW_KEY_NODE_AUTOCONNECT "node.autoconnect" /**< node wants to be automatically connected #define PW_KEY_NODE_AUTOCONNECT "node.autoconnect" /**< node wants to be automatically connected
* to a compatible node */ * to a compatible node */

View file

@ -683,6 +683,7 @@ struct pw_impl_node {
* trigger to start processing. */ * trigger to start processing. */
unsigned int can_suspend:1; unsigned int can_suspend:1;
unsigned int checked; /**< for sorting */ unsigned int checked; /**< for sorting */
unsigned int transport:1; /**< the transport is active */
uint32_t port_user_data_size; /**< extra size for port user data */ uint32_t port_user_data_size; /**< extra size for port user data */