node: add suport for quantum updates

When the node latency property is changed, trigger a graph recalc
to set the new quantum if needed.

Also update the driver quantum when unassigned nodes are assigned
to a driver.
This commit is contained in:
Wim Taymans 2019-08-30 17:00:26 +02:00
parent 001c0a5217
commit 0f9594e119
4 changed files with 34 additions and 18 deletions

@ -1 +1 @@
Subproject commit 58c68f3260abcef9e9782c72963a08c9a7b7a7df
Subproject commit 926b500ceb030348a97adf33f391075cafaf6616

View file

@ -1091,10 +1091,7 @@ static int collect_nodes(struct pw_node *driver)
}
}
}
quantum = SPA_MAX(quantum, MIN_QUANTUM);
if (driver->rt.position && quantum != driver->rt.position->clock.duration)
driver->rt.position->clock.duration = quantum;
driver->quantum_current = SPA_MAX(quantum, MIN_QUANTUM);
return 0;
}
@ -1146,23 +1143,33 @@ int pw_core_recalc_graph(struct pw_core *core)
if (!n->visited) {
pw_log_info(NAME" %p: unassigned node %p: '%s' %d", core,
n, n->name, n->active);
if (!n->want_driver)
if (!n->want_driver || target == NULL) {
pw_node_set_driver(n, NULL);
else {
pw_node_set_state(n, PW_NODE_STATE_IDLE);
} else {
if (n->quantum_size > 0 && n->quantum_size < target->quantum_current)
target->quantum_current = SPA_MAX(MIN_QUANTUM, n->quantum_size);
pw_node_set_driver(n, target);
pw_node_set_state(n, target && n->active ?
pw_node_set_state(n, n->active ?
PW_NODE_STATE_RUNNING : PW_NODE_STATE_IDLE);
}
}
n->visited = false;
}
/* debug only here to list all masters and their slaves */
/* assign final quantum and debug masters and slaves */
spa_list_for_each(n, &core->driver_list, driver_link) {
if (!n->master)
continue;
pw_log_info(NAME" %p: master %p quantum:%"PRIu64" '%s'", core, n,
n->rt.position ? n->rt.position->clock.duration : 0, n->name);
if (n->rt.position && n->quantum_current != n->rt.position->clock.duration)
n->rt.position->clock.duration = n->quantum_current;
pw_log_info(NAME" %p: master %p quantum:%u '%s'", core, n,
n->quantum_current, n->name);
spa_list_for_each(s, &n->slave_list, slave_link)
pw_log_info(NAME" %p: slave %p: active:%d '%s'",
core, s, s->active, s->name);

View file

@ -699,7 +699,7 @@ static void check_properties(struct pw_node *node)
{
struct impl *impl = SPA_CONTAINER_OF(node, struct impl, this);
const char *str;
bool driver;
bool driver, do_recalc = false;
if ((str = pw_properties_get(node->properties, PW_KEY_NODE_NAME))) {
free(node->name);
@ -737,13 +737,21 @@ static void check_properties(struct pw_node *node)
uint32_t num, denom;
pw_log_info(NAME" %p: latency '%s'", node, str);
if (sscanf(str, "%u/%u", &num, &denom) == 2 && denom != 0) {
node->quantum_size = flp2((num * 48000 / denom));
pw_log_info(NAME" %p: quantum %d", node, node->quantum_size);
}
} else
node->quantum_size = DEFAULT_QUANTUM;
uint32_t quantum_size;
pw_log_debug(NAME" %p: driver:%d", node, node->driver);
quantum_size = flp2((num * 48000 / denom));
pw_log_info(NAME" %p: quantum %d", node, quantum_size);
if (quantum_size != node->quantum_size) {
node->quantum_size = quantum_size;
do_recalc |= node->active;
}
}
}
pw_log_debug(NAME" %p: driver:%d recalc:%d", node, node->driver, do_recalc);
if (do_recalc)
pw_core_recalc_graph(node->core);
}
static void dump_states(struct pw_node *driver)

View file

@ -490,6 +490,7 @@ struct pw_node {
struct pw_loop *data_loop; /**< the data loop for this node */
uint32_t quantum_size; /**< desired quantum */
uint32_t quantum_current; /**< current quantum for driver */
struct spa_source source; /**< source to remotely trigger this node */
struct pw_memblock *activation;
struct {