context: scale max_quantum and add quantum_limit

Also scale the max_quantum with the selected rate. Add a new
quantum_limit property that is the upper limit of the quantum regardless
of the sample rate, this is usually the allocated buffer size.

See #1931
This commit is contained in:
Wim Taymans 2022-01-12 17:44:45 +01:00
parent dcac58609c
commit 676bed734c
9 changed files with 35 additions and 12 deletions

View file

@ -9,6 +9,8 @@ context.properties = {
#mem.allow-mlock = true
#mem.mlock-all = false
log.level = 0
#default.clock.quantum-limit = 8192
}
context.spa-libs = {

View file

@ -9,6 +9,8 @@ context.properties = {
#mem.allow-mlock = true
#mem.mlock-all = false
log.level = 0
#default.clock.quantum-limit = 8192
}
context.spa-libs = {

View file

@ -9,6 +9,8 @@ context.properties = {
#mem.allow-mlock = true
#mem.mlock-all = false
log.level = 0
#default.clock.quantum-limit = 8192
}
context.spa-libs = {

View file

@ -9,6 +9,8 @@ context.properties = {
#mem.allow-mlock = true
#mem.mlock-all = false
#log.level = 2
#default.clock.quantum-limit = 8192
}
context.spa-libs = {

View file

@ -26,6 +26,7 @@ context.properties = {
#default.clock.quantum = 1024
#default.clock.min-quantum = 32
#default.clock.max-quantum = 8192
#default.clock.quantum-limit = 8192
#default.video.width = 640
#default.video.height = 480
#default.video.rate.num = 25

View file

@ -52,6 +52,7 @@ struct defs {
struct sample_spec sample_spec;
struct channel_map channel_map;
uint32_t max_quantum;
uint32_t quantum_limit;
};
struct stats {

View file

@ -980,26 +980,32 @@ static int collect_nodes(struct pw_context *context, struct pw_impl_node *driver
}
static inline void get_quantums(struct pw_context *context, uint32_t *def,
uint32_t *min, uint32_t *max, uint32_t *rate)
uint32_t *min, uint32_t *max, uint32_t *limit, uint32_t *rate)
{
struct settings *s = &context->settings;
*def = s->clock_force_quantum == 0 ? s->clock_quantum : s->clock_force_quantum;
*min = s->clock_force_quantum == 0 ? s->clock_min_quantum : s->clock_force_quantum;
*max = s->clock_force_quantum == 0 ? s->clock_max_quantum : s->clock_force_quantum;
*rate = s->clock_force_quantum == 0 ? s->clock_rate : s->clock_force_rate;
if (s->clock_force_quantum != 0) {
*def = *min = *max = s->clock_force_quantum;
*rate = 0;
} else {
*def = s->clock_quantum;
*min = s->clock_min_quantum;
*max = s->clock_max_quantum;
*rate = s->clock_rate;
}
*limit = s->clock_quantum_limit;
}
static inline uint32_t *get_rates(struct pw_context *context, uint32_t *def, uint32_t *n_rates,
bool *force_rate)
bool *force)
{
struct settings *s = &context->settings;
if (s->clock_force_rate != 0) {
*force_rate = true;
*force = true;
*n_rates = 1;
*def = s->clock_force_rate;
return &s->clock_force_rate;
} else {
*force_rate = false;
*force = false;
*n_rates = s->n_clock_rates;
*def = s->clock_rate;
return s->clock_rates;
@ -1053,7 +1059,7 @@ int pw_context_recalc_graph(struct pw_context *context, const char *reason)
{
struct impl *impl = SPA_CONTAINER_OF(context, struct impl, this);
struct pw_impl_node *n, *s, *target, *fallback;
uint32_t max_quantum, min_quantum, def_quantum, rate_quantum;
uint32_t max_quantum, min_quantum, def_quantum, lim_quantum, rate_quantum;
uint32_t *rates, n_rates, def_rate;
bool freewheel = false, force_rate;
@ -1067,7 +1073,7 @@ int pw_context_recalc_graph(struct pw_context *context, const char *reason)
again:
impl->recalc = true;
get_quantums(context, &def_quantum, &min_quantum, &max_quantum, &rate_quantum);
get_quantums(context, &def_quantum, &min_quantum, &max_quantum, &lim_quantum, &rate_quantum);
rates = get_rates(context, &def_rate, &n_rates, &force_rate);
/* start from all drivers and group all nodes that are linked
@ -1221,6 +1227,7 @@ again:
if (rate_quantum != 0 && current_rate != rate_quantum) {
def_quantum = def_quantum * current_rate / rate_quantum;
min_quantum = min_quantum * current_rate / rate_quantum;
max_quantum = max_quantum * current_rate / rate_quantum;
}
/* calculate desired quantum */
@ -1234,6 +1241,7 @@ again:
if (latency.denom != 0)
quantum = (latency.num * current_rate / latency.denom);
quantum = SPA_CLAMP(quantum, min_quantum, max_quantum);
quantum = SPA_MIN(quantum, lim_quantum);
if (context->settings.clock_power_of_two_quantum)
quantum = flp2(quantum);

View file

@ -61,6 +61,7 @@ struct settings {
uint32_t clock_quantum; /* default quantum */
uint32_t clock_min_quantum; /* min quantum */
uint32_t clock_max_quantum; /* max quantum */
uint32_t clock_quantum_limit; /* quantum limit */
struct spa_rectangle video_size;
struct spa_fraction video_rate;
uint32_t link_max_buffers;

View file

@ -44,6 +44,7 @@
#define DEFAULT_CLOCK_QUANTUM 1024u
#define DEFAULT_CLOCK_MIN_QUANTUM 32u
#define DEFAULT_CLOCK_MAX_QUANTUM 8192u
#define DEFAULT_CLOCK_QUANTUM_LIMIT 8192u
#define DEFAULT_CLOCK_POWER_OF_TWO_QUANTUM true
#define DEFAULT_VIDEO_WIDTH 640
#define DEFAULT_VIDEO_HEIGHT 480
@ -188,7 +189,7 @@ static int metadata_property(void *data, uint32_t subject, const char *key,
recalc = true;
} else if (spa_streq(key, "clock.force-quantum")) {
v = value ? atoi(value) : 0;
s->clock_force_quantum = SPA_MIN(v, 8192u);
s->clock_force_quantum = v;
recalc = true;
}
if (recalc)
@ -213,6 +214,7 @@ void pw_settings_init(struct pw_context *this)
d->clock_quantum = get_default_int(p, "default.clock.quantum", DEFAULT_CLOCK_QUANTUM);
d->clock_min_quantum = get_default_int(p, "default.clock.min-quantum", DEFAULT_CLOCK_MIN_QUANTUM);
d->clock_max_quantum = get_default_int(p, "default.clock.max-quantum", DEFAULT_CLOCK_MAX_QUANTUM);
d->clock_quantum_limit = get_default_int(p, "default.clock.quantum-limit", DEFAULT_CLOCK_QUANTUM_LIMIT);
d->video_size.width = get_default_int(p, "default.video.width", DEFAULT_VIDEO_WIDTH);
d->video_size.height = get_default_int(p, "default.video.height", DEFAULT_VIDEO_HEIGHT);
d->video_rate.num = get_default_int(p, "default.video.rate.num", DEFAULT_VIDEO_RATE_NUM);
@ -225,8 +227,10 @@ void pw_settings_init(struct pw_context *this)
d->mem_warn_mlock = get_default_bool(p, "mem.warn-mlock", DEFAULT_MEM_WARN_MLOCK);
d->mem_allow_mlock = get_default_bool(p, "mem.allow-mlock", DEFAULT_MEM_ALLOW_MLOCK);
d->clock_max_quantum = SPA_CLAMP(d->clock_max_quantum,
d->clock_quantum_limit = SPA_CLAMP(d->clock_quantum_limit,
CLOCK_MIN_QUANTUM, CLOCK_MAX_QUANTUM);
d->clock_max_quantum = SPA_CLAMP(d->clock_max_quantum,
CLOCK_MIN_QUANTUM, d->clock_quantum_limit);
d->clock_min_quantum = SPA_CLAMP(d->clock_min_quantum,
CLOCK_MIN_QUANTUM, d->clock_max_quantum);
d->clock_quantum = SPA_CLAMP(d->clock_quantum,