mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-03 09:01:54 -05:00
context: keep per node quantum and rate settings
Copy the global quantum and rate limits before applying node specific settings. Otherwise one node settings will propagate to the defaults of the next nodes, which can result in impossible or wrong settings. See #2925
This commit is contained in:
parent
395749fea9
commit
9f3237b74e
1 changed files with 36 additions and 21 deletions
|
|
@ -917,7 +917,7 @@ static inline void get_quantums(struct pw_context *context, uint32_t *def,
|
||||||
*limit = s->clock_quantum_limit;
|
*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)
|
bool *force)
|
||||||
{
|
{
|
||||||
struct settings *s = &context->settings;
|
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);
|
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;
|
uint32_t i;
|
||||||
for (i = 0; i < n_rates; 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 impl *impl = SPA_CONTAINER_OF(context, struct impl, this);
|
||||||
struct settings *settings = &context->settings;
|
struct settings *settings = &context->settings;
|
||||||
struct pw_impl_node *n, *s, *target, *fallback;
|
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 max_quantum, min_quantum, def_quantum, lim_quantum, rate_quantum;
|
||||||
uint32_t *rates, n_rates, def_rate;
|
uint32_t n_rates, def_rate;
|
||||||
bool freewheel = false, global_force_rate, force_rate, force_quantum, global_force_quantum;
|
bool freewheel = false, global_force_rate, global_force_quantum;
|
||||||
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);
|
||||||
|
|
@ -1023,8 +1024,7 @@ again:
|
||||||
get_quantums(context, &def_quantum, &min_quantum, &max_quantum, &lim_quantum, &rate_quantum);
|
get_quantums(context, &def_quantum, &min_quantum, &max_quantum, &lim_quantum, &rate_quantum);
|
||||||
rates = get_rates(context, &def_rate, &n_rates, &global_force_rate);
|
rates = get_rates(context, &def_rate, &n_rates, &global_force_rate);
|
||||||
|
|
||||||
force_quantum = global_force_quantum = rate_quantum == 0;
|
global_force_quantum = rate_quantum == 0;
|
||||||
force_rate = global_force_rate;
|
|
||||||
|
|
||||||
/* start from all drivers and group all nodes that are linked
|
/* start from all drivers and group all nodes that are linked
|
||||||
* to it. Some nodes are not (yet) linked to anything and they
|
* 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);
|
struct spa_fraction rate = SPA_FRACTION(0, 0);
|
||||||
uint32_t quantum, target_rate, current_rate;
|
uint32_t quantum, target_rate, current_rate;
|
||||||
uint64_t quantum_stamp = 0, rate_stamp = 0;
|
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)
|
if (!n->driving || n->exported)
|
||||||
continue;
|
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 */
|
/* collect quantum and rate */
|
||||||
spa_list_for_each(s, &n->follower_list, follower_link) {
|
spa_list_for_each(s, &n->follower_list, follower_link) {
|
||||||
|
|
||||||
|
|
@ -1138,17 +1153,17 @@ again:
|
||||||
}
|
}
|
||||||
if (!global_force_quantum && s->force_quantum > 0 &&
|
if (!global_force_quantum && s->force_quantum > 0 &&
|
||||||
s->stamp > quantum_stamp) {
|
s->stamp > quantum_stamp) {
|
||||||
def_quantum = min_quantum = max_quantum = s->force_quantum;
|
node_def_quantum = node_min_quantum = node_max_quantum = s->force_quantum;
|
||||||
rate_quantum = 0;
|
node_rate_quantum = 0;
|
||||||
quantum_stamp = s->stamp;
|
quantum_stamp = s->stamp;
|
||||||
force_quantum = true;
|
force_quantum = true;
|
||||||
}
|
}
|
||||||
if (!global_force_rate && s->force_rate > 0 &&
|
if (!global_force_rate && s->force_rate > 0 &&
|
||||||
s->stamp > rate_stamp) {
|
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;
|
force_rate = true;
|
||||||
n_rates = 1;
|
|
||||||
rates = &s->force_rate;
|
|
||||||
rate_stamp = s->stamp;
|
rate_stamp = s->stamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1198,9 +1213,9 @@ again:
|
||||||
/* Here we are allowed to change the rate of the driver.
|
/* Here we are allowed to change the rate of the driver.
|
||||||
* Start with the default rate. If the desired rate is
|
* Start with the default rate. If the desired rate is
|
||||||
* allowed, switch to it */
|
* allowed, switch to it */
|
||||||
target_rate = def_rate;
|
target_rate = node_def_rate;
|
||||||
if (rate.denom != 0 && rate.num == 1)
|
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);
|
rate.denom, target_rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1233,24 +1248,24 @@ again:
|
||||||
goto 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 */
|
/* the quantum values are scaled with the current rate */
|
||||||
def_quantum = def_quantum * current_rate / rate_quantum;
|
node_def_quantum = node_def_quantum * current_rate / node_rate_quantum;
|
||||||
min_quantum = min_quantum * current_rate / rate_quantum;
|
node_min_quantum = node_min_quantum * current_rate / node_rate_quantum;
|
||||||
max_quantum = max_quantum * current_rate / rate_quantum;
|
node_max_quantum = node_max_quantum * current_rate / node_rate_quantum;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* calculate desired quantum */
|
/* calculate desired quantum */
|
||||||
if (max_latency.denom != 0) {
|
if (max_latency.denom != 0) {
|
||||||
uint32_t tmp = (max_latency.num * current_rate / max_latency.denom);
|
uint32_t tmp = (max_latency.num * current_rate / max_latency.denom);
|
||||||
if (tmp < max_quantum)
|
if (tmp < node_max_quantum)
|
||||||
max_quantum = tmp;
|
node_max_quantum = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
quantum = def_quantum;
|
quantum = node_def_quantum;
|
||||||
if (latency.denom != 0)
|
if (latency.denom != 0)
|
||||||
quantum = (latency.num * current_rate / latency.denom);
|
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);
|
quantum = SPA_MIN(quantum, lim_quantum);
|
||||||
|
|
||||||
if (settings->clock_power_of_two_quantum)
|
if (settings->clock_power_of_two_quantum)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue