context: restore driver rate when no longer forced

Keep track of when a rate was forced on a driver and restore the
best rate again when no longer forced.

This handles:

- paplay playing a file at 44100Hz
  --> driver openeing the device at 44100
- PIPEWIRE_PROPS='{ node.force-rate=48000 }' jack_simple_client
  --> driver being forced to a new rate of 48000
- Stop jack_simple_client
  --> Driver reverting back to 44100

Previously the driver would stay in 48000Hz until it idles.

This also works with pw-metadata -n settings 0 clock.force-rate 0.

Fixes #2133
This commit is contained in:
Wim Taymans 2023-03-23 11:35:50 +01:00
parent 8ddb6d711f
commit d3cd900d06
2 changed files with 15 additions and 5 deletions

View file

@ -1204,7 +1204,7 @@ 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;
bool force_rate, force_quantum, restore_rate = false;
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;
@ -1276,6 +1276,13 @@ again:
s->moved = false;
}
if (n->forced_rate && !force_rate) {
/* A node that was forced to a rate but is no longer being
* forced can restore its rate */
pw_log_info("(%s-%u) restore rate", n->name, n->info.id);
restore_rate = true;
}
if (force_quantum)
lock_quantum = false;
if (force_rate)
@ -1285,10 +1292,11 @@ again:
running = true;
current_rate = n->current_rate.denom;
if (lock_rate || n->reconfigure || !running ||
(!force_rate &&
(n->info.state > PW_NODE_STATE_IDLE)))
/* when someone wants us to lock the rate of this driver or
if (!restore_rate &&
(lock_rate || n->reconfigure || !running ||
(!force_rate && (n->info.state > PW_NODE_STATE_IDLE))))
/* when we don't need to restore or rate and
* when someone wants us to lock the rate of this driver or
* when we are in the process of reconfiguring the driver or
* when we are not running any followers or
* when the driver is busy and we don't need to force a rate,
@ -1327,6 +1335,7 @@ again:
* current rate in the next iteration of the graph. */
n->current_rate = SPA_FRACTION(1, target_rate);
n->current_pending = true;
n->forced_rate = force_rate;
current_rate = target_rate;
/* we might be suspended now and the links need to be prepared again */
if (do_reconfigure)

View file

@ -702,6 +702,7 @@ struct pw_impl_node {
unsigned int pause_on_idle:1; /**< Pause processing when IDLE */
unsigned int suspend_on_idle:1;
unsigned int reconfigure:1;
unsigned int forced_rate:1;
uint32_t port_user_data_size; /**< extra size for port user data */