diff --git a/src/pipewire/context.c b/src/pipewire/context.c index ab798c20e..384682701 100644 --- a/src/pipewire/context.c +++ b/src/pipewire/context.c @@ -917,7 +917,7 @@ static inline void get_quantums(struct pw_context *context, uint32_t *def, *limit = s->clock_quantum_limit; } -static inline uint32_t *get_rates(struct pw_context *context, uint32_t *def, uint32_t *n_rates, +static inline const uint32_t *get_rates(struct pw_context *context, uint32_t *def, uint32_t *n_rates, bool *force) { struct settings *s = &context->settings; @@ -971,7 +971,7 @@ static int fraction_compare(const struct spa_fraction *a, const struct spa_fract return fa < fb ? -1 : (fa > fb ? 1 : 0); } -static uint32_t find_best_rate(uint32_t *rates, uint32_t n_rates, uint32_t rate, uint32_t best) +static uint32_t find_best_rate(const uint32_t *rates, uint32_t n_rates, uint32_t rate, uint32_t best) { uint32_t i; for (i = 0; i < n_rates; i++) { @@ -1005,9 +1005,10 @@ int pw_context_recalc_graph(struct pw_context *context, const char *reason) struct impl *impl = SPA_CONTAINER_OF(context, struct impl, this); struct settings *settings = &context->settings; struct pw_impl_node *n, *s, *target, *fallback; + const uint32_t *rates; uint32_t max_quantum, min_quantum, def_quantum, lim_quantum, rate_quantum; - uint32_t *rates, n_rates, def_rate; - bool freewheel = false, global_force_rate, force_rate, force_quantum, global_force_quantum; + uint32_t n_rates, def_rate; + bool freewheel = false, global_force_rate, global_force_quantum; struct spa_list collect; pw_log_info("%p: busy:%d reason:%s", context, impl->recalc, reason); @@ -1023,8 +1024,7 @@ again: get_quantums(context, &def_quantum, &min_quantum, &max_quantum, &lim_quantum, &rate_quantum); rates = get_rates(context, &def_rate, &n_rates, &global_force_rate); - force_quantum = global_force_quantum = rate_quantum == 0; - force_rate = global_force_rate; + global_force_quantum = rate_quantum == 0; /* start from all drivers and group all nodes that are linked * to it. Some nodes are not (yet) linked to anything and they @@ -1121,10 +1121,25 @@ again: struct spa_fraction rate = SPA_FRACTION(0, 0); uint32_t quantum, target_rate, current_rate; uint64_t quantum_stamp = 0, rate_stamp = 0; + bool force_rate, force_quantum; + const uint32_t *node_rates; + uint32_t node_n_rates, node_def_rate; + uint32_t node_max_quantum, node_min_quantum, node_def_quantum, node_rate_quantum; if (!n->driving || n->exported) continue; + node_def_quantum = def_quantum; + node_min_quantum = min_quantum; + node_max_quantum = max_quantum; + node_rate_quantum = rate_quantum; + force_quantum = global_force_quantum; + + node_def_rate = def_rate; + node_n_rates = n_rates; + node_rates = rates; + force_rate = global_force_rate; + /* collect quantum and rate */ spa_list_for_each(s, &n->follower_list, follower_link) { @@ -1138,17 +1153,17 @@ again: } if (!global_force_quantum && s->force_quantum > 0 && s->stamp > quantum_stamp) { - def_quantum = min_quantum = max_quantum = s->force_quantum; - rate_quantum = 0; + node_def_quantum = node_min_quantum = node_max_quantum = s->force_quantum; + node_rate_quantum = 0; quantum_stamp = s->stamp; force_quantum = true; } if (!global_force_rate && s->force_rate > 0 && s->stamp > rate_stamp) { - def_rate = s->force_rate; + node_def_rate = s->force_rate; + node_n_rates = 1; + node_rates = &s->force_rate; force_rate = true; - n_rates = 1; - rates = &s->force_rate; rate_stamp = s->stamp; } @@ -1198,9 +1213,9 @@ again: /* Here we are allowed to change the rate of the driver. * Start with the default rate. If the desired rate is * allowed, switch to it */ - target_rate = def_rate; + target_rate = node_def_rate; if (rate.denom != 0 && rate.num == 1) - target_rate = find_best_rate(rates, n_rates, + target_rate = find_best_rate(node_rates, node_n_rates, rate.denom, target_rate); } @@ -1233,24 +1248,24 @@ again: goto again; } - if (rate_quantum != 0 && current_rate != rate_quantum) { + if (node_rate_quantum != 0 && current_rate != node_rate_quantum) { /* the quantum values are scaled with the current rate */ - def_quantum = def_quantum * current_rate / rate_quantum; - min_quantum = min_quantum * current_rate / rate_quantum; - max_quantum = max_quantum * current_rate / rate_quantum; + node_def_quantum = node_def_quantum * current_rate / node_rate_quantum; + node_min_quantum = node_min_quantum * current_rate / node_rate_quantum; + node_max_quantum = node_max_quantum * current_rate / node_rate_quantum; } /* calculate desired quantum */ if (max_latency.denom != 0) { uint32_t tmp = (max_latency.num * current_rate / max_latency.denom); - if (tmp < max_quantum) - max_quantum = tmp; + if (tmp < node_max_quantum) + node_max_quantum = tmp; } - quantum = def_quantum; + quantum = node_def_quantum; if (latency.denom != 0) quantum = (latency.num * current_rate / latency.denom); - quantum = SPA_CLAMP(quantum, min_quantum, max_quantum); + quantum = SPA_CLAMP(quantum, node_min_quantum, node_max_quantum); quantum = SPA_MIN(quantum, lim_quantum); if (settings->clock_power_of_two_quantum)