mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-01 22:58:50 -04:00
impl-node: rework quantum and max_quantum handling
Rework the quantum and max_quantum handling. Work directly with the latency fractions and calculate the final quantum size until we know the samplerate.
This commit is contained in:
parent
7bec96640c
commit
6acf72dc30
3 changed files with 53 additions and 45 deletions
|
|
@ -1019,6 +1019,22 @@ static void suspend_driver(struct pw_context *context, struct pw_impl_node *n)
|
|||
pw_impl_node_set_state(n, PW_NODE_STATE_SUSPENDED);
|
||||
}
|
||||
|
||||
/* find smaller power of 2 */
|
||||
static uint32_t flp2(uint32_t x)
|
||||
{
|
||||
x = x | (x >> 1);
|
||||
x = x | (x >> 2);
|
||||
x = x | (x >> 4);
|
||||
x = x | (x >> 8);
|
||||
x = x | (x >> 16);
|
||||
return x - (x >> 1);
|
||||
}
|
||||
|
||||
static int64_t fraction_compare(const struct spa_fraction *a, const struct spa_fraction *b)
|
||||
{
|
||||
return (int64_t)(a->num * b->denom) - (int64_t)(b->num * a->denom);
|
||||
}
|
||||
|
||||
int pw_context_recalc_graph(struct pw_context *context, const char *reason)
|
||||
{
|
||||
struct impl *impl = SPA_CONTAINER_OF(context, struct impl, this);
|
||||
|
|
@ -1113,7 +1129,9 @@ again:
|
|||
/* assign final quantum and set state for followers and drivers */
|
||||
spa_list_for_each(n, &context->driver_list, driver_link) {
|
||||
bool running = false, lock_quantum = false;
|
||||
uint32_t quantum = 0;
|
||||
struct spa_fraction latency = SPA_FRACTION(0, 0);
|
||||
struct spa_fraction max_latency = SPA_FRACTION(0, 0);
|
||||
uint32_t quantum;
|
||||
|
||||
if (!n->driving || n->exported)
|
||||
continue;
|
||||
|
|
@ -1123,22 +1141,33 @@ again:
|
|||
|
||||
lock_quantum |= s->lock_quantum;
|
||||
|
||||
if (s->quantum_size > 0) {
|
||||
if (quantum == 0 || s->quantum_size < quantum)
|
||||
quantum = s->quantum_size;
|
||||
}
|
||||
if (s->max_quantum_size > 0) {
|
||||
if (s->max_quantum_size < max_quantum)
|
||||
max_quantum = s->max_quantum_size;
|
||||
}
|
||||
if (latency.denom == 0 ||
|
||||
(s->latency.denom > 0 &&
|
||||
fraction_compare(&s->latency, &latency) < 0))
|
||||
latency = s->latency;
|
||||
|
||||
if (max_latency.denom == 0 ||
|
||||
(s->max_latency.denom > 0 &&
|
||||
fraction_compare(&s->max_latency, &max_latency) < 0))
|
||||
max_latency = s->max_latency;
|
||||
|
||||
if (s->active)
|
||||
running = !n->passive;
|
||||
}
|
||||
if (quantum == 0)
|
||||
quantum = def_quantum;
|
||||
if (max_latency.denom != 0) {
|
||||
uint32_t tmp = (max_latency.num * def_rate / max_latency.denom);
|
||||
if (tmp < max_quantum)
|
||||
max_quantum = tmp;
|
||||
}
|
||||
|
||||
quantum = def_quantum;
|
||||
if (latency.denom != 0)
|
||||
quantum = (latency.num * def_rate / latency.denom);
|
||||
quantum = SPA_CLAMP(quantum, min_quantum, max_quantum);
|
||||
|
||||
if (context->settings.clock_power_of_two_quantum)
|
||||
quantum = flp2(quantum);
|
||||
|
||||
if (def_rate != n->rt.position->clock.rate.denom) {
|
||||
pw_log_info("(%s-%u) new rate:%u->%u",
|
||||
n->name, n->info.id,
|
||||
|
|
|
|||
|
|
@ -817,6 +817,7 @@ static void check_properties(struct pw_impl_node *node)
|
|||
struct impl *impl = SPA_CONTAINER_OF(node, struct impl, this);
|
||||
struct pw_context *context = node->context;
|
||||
const char *str, *recalc_reason = NULL;
|
||||
struct spa_fraction frac;
|
||||
bool driver;
|
||||
|
||||
if ((str = pw_properties_get(node->properties, PW_KEY_PRIORITY_DRIVER))) {
|
||||
|
|
@ -873,43 +874,23 @@ static void check_properties(struct pw_impl_node *node)
|
|||
node->want_driver = true;
|
||||
|
||||
if ((str = pw_properties_get(node->properties, PW_KEY_NODE_LATENCY))) {
|
||||
uint32_t num, denom;
|
||||
if (sscanf(str, "%u/%u", &num, &denom) == 2 && denom != 0) {
|
||||
uint32_t quantum_size;
|
||||
|
||||
node->latency = SPA_FRACTION(num, denom);
|
||||
quantum_size = (num * context->settings.clock_rate / denom);
|
||||
if (context->settings.clock_power_of_two_quantum)
|
||||
quantum_size = flp2(quantum_size);
|
||||
|
||||
if (quantum_size != node->quantum_size) {
|
||||
pw_log_debug(NAME" %p: latency '%s' quantum %u/%u",
|
||||
node, str, quantum_size, context->settings.clock_rate);
|
||||
pw_log_info("(%s-%u) latency:%s ->quantum %u/%u", node->name,
|
||||
node->info.id, str, quantum_size,
|
||||
context->settings.clock_rate);
|
||||
node->quantum_size = quantum_size;
|
||||
if (sscanf(str, "%u/%u", &frac.num, &frac.denom) == 2 && frac.denom != 0) {
|
||||
if (node->latency.num != frac.num || node->latency.denom != frac.denom) {
|
||||
pw_log_info("(%s-%u) latency:%u/%u -> %u/%u", node->name,
|
||||
node->info.id, node->latency.num,
|
||||
node->latency.denom, frac.num, frac.denom);
|
||||
node->latency = frac;
|
||||
recalc_reason = "quantum changed";
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((str = pw_properties_get(node->properties, PW_KEY_NODE_MAX_LATENCY))) {
|
||||
uint32_t num, denom;
|
||||
if (sscanf(str, "%u/%u", &num, &denom) == 2 && denom != 0) {
|
||||
uint32_t max_quantum_size;
|
||||
|
||||
node->max_latency = SPA_FRACTION(num, denom);
|
||||
max_quantum_size = (num * context->settings.clock_rate / denom);
|
||||
if (context->settings.clock_power_of_two_quantum)
|
||||
max_quantum_size = flp2(max_quantum_size);
|
||||
|
||||
if (max_quantum_size != node->max_quantum_size) {
|
||||
pw_log_debug(NAME" %p: max latency '%s' quantum %u/%u",
|
||||
node, str, max_quantum_size, context->settings.clock_rate);
|
||||
pw_log_info("(%s-%u) max latency:%s ->quantum %u/%u", node->name,
|
||||
node->info.id, str, max_quantum_size,
|
||||
context->settings.clock_rate);
|
||||
node->max_quantum_size = max_quantum_size;
|
||||
if (sscanf(str, "%u/%u", &frac.num, &frac.denom) == 2 && frac.denom != 0) {
|
||||
if (node->max_latency.num != frac.num || node->max_latency.denom != frac.denom) {
|
||||
pw_log_info("(%s-%u) max-latency:%u/%u -> %u/%u", node->name,
|
||||
node->info.id, node->max_latency.num,
|
||||
node->max_latency.denom, frac.num, frac.denom);
|
||||
node->max_latency = frac;
|
||||
recalc_reason = "max quantum changed";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -701,9 +701,7 @@ struct pw_impl_node {
|
|||
struct pw_loop *data_loop; /**< the data loop for this node */
|
||||
|
||||
struct spa_fraction latency; /**< requested latency */
|
||||
uint32_t quantum_size; /**< desired quantum */
|
||||
struct spa_fraction max_latency; /**< maximum latency */
|
||||
uint32_t max_quantum_size; /**< max supported quantum */
|
||||
struct spa_source source; /**< source to remotely trigger this node */
|
||||
struct pw_memblock *activation;
|
||||
struct {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue