context: add option for soft/hard clock rate changes

Hard rate changes (the default now) makes the graph suspend so that the
driver reopens the device with the new sample rate if possible. This
causes a glitch.

Soft rate changes works as before and just changes the clock rate of
the position area, which makes everything resample things to the new
rate without a glitch.

Sample rate changes can currently still only be triggered by
configuring the settings metadata clock.force-rate
This commit is contained in:
Wim Taymans 2021-07-29 17:13:54 +02:00
parent 65e7402d01
commit 08a1ca403f
2 changed files with 20 additions and 0 deletions

View file

@ -1005,6 +1005,20 @@ static inline void get_rate(struct pw_context *context, uint32_t *def)
*def = s->clock_force_rate == 0 ? s->clock_rate : s->clock_force_rate;
}
static void suspend_driver(struct pw_context *context, struct pw_impl_node *n)
{
struct pw_impl_node *s;
spa_list_for_each(s, &n->follower_list, follower_link) {
if (s == n)
continue;
pw_log_debug(NAME" %p: follower %p: '%s' suspend",
context, s, s->name);
pw_impl_node_set_state(s, PW_NODE_STATE_SUSPENDED);
}
pw_impl_node_set_state(n, PW_NODE_STATE_SUSPENDED);
}
int pw_context_recalc_graph(struct pw_context *context, const char *reason)
{
struct impl *impl = SPA_CONTAINER_OF(context, struct impl, this);
@ -1128,6 +1142,9 @@ again:
n->name, n->info.id,
n->rt.position->clock.rate.denom,
def_rate);
if (context->settings.clock_rate_update_mode == CLOCK_RATE_UPDATE_MODE_HARD)
suspend_driver(context, n);
n->rt.position->clock.rate = SPA_FRACTION(1, def_rate);
}
if (quantum != n->rt.position->clock.duration) {

View file

@ -64,6 +64,9 @@ struct settings {
unsigned int mem_warn_mlock:1;
unsigned int mem_allow_mlock:1;
unsigned int clock_power_of_two_quantum:1;
#define CLOCK_RATE_UPDATE_MODE_HARD 0
#define CLOCK_RATE_UPDATE_MODE_SOFT 1
int clock_rate_update_mode;
uint32_t clock_force_rate;
uint32_t clock_force_quantum;
};