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.allow-mlock = true
#mem.mlock-all = false #mem.mlock-all = false
log.level = 0 log.level = 0
#default.clock.quantum-limit = 8192
} }
context.spa-libs = { context.spa-libs = {

View file

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

View file

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

View file

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

View file

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

View file

@ -52,6 +52,7 @@ struct defs {
struct sample_spec sample_spec; struct sample_spec sample_spec;
struct channel_map channel_map; struct channel_map channel_map;
uint32_t max_quantum; uint32_t max_quantum;
uint32_t quantum_limit;
}; };
struct stats { 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, 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; struct settings *s = &context->settings;
*def = s->clock_force_quantum == 0 ? s->clock_quantum : s->clock_force_quantum; if (s->clock_force_quantum != 0) {
*min = s->clock_force_quantum == 0 ? s->clock_min_quantum : s->clock_force_quantum; *def = *min = *max = s->clock_force_quantum;
*max = s->clock_force_quantum == 0 ? s->clock_max_quantum : s->clock_force_quantum; *rate = 0;
*rate = s->clock_force_quantum == 0 ? s->clock_rate : s->clock_force_rate; } 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, 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; struct settings *s = &context->settings;
if (s->clock_force_rate != 0) { if (s->clock_force_rate != 0) {
*force_rate = true; *force = true;
*n_rates = 1; *n_rates = 1;
*def = s->clock_force_rate; *def = s->clock_force_rate;
return &s->clock_force_rate; return &s->clock_force_rate;
} else { } else {
*force_rate = false; *force = false;
*n_rates = s->n_clock_rates; *n_rates = s->n_clock_rates;
*def = s->clock_rate; *def = s->clock_rate;
return s->clock_rates; 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 impl *impl = SPA_CONTAINER_OF(context, struct impl, this);
struct pw_impl_node *n, *s, *target, *fallback; 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; uint32_t *rates, n_rates, def_rate;
bool freewheel = false, force_rate; bool freewheel = false, force_rate;
@ -1067,7 +1073,7 @@ int pw_context_recalc_graph(struct pw_context *context, const char *reason)
again: again:
impl->recalc = true; 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); rates = get_rates(context, &def_rate, &n_rates, &force_rate);
/* start from all drivers and group all nodes that are linked /* start from all drivers and group all nodes that are linked
@ -1221,6 +1227,7 @@ again:
if (rate_quantum != 0 && current_rate != rate_quantum) { if (rate_quantum != 0 && current_rate != rate_quantum) {
def_quantum = def_quantum * current_rate / rate_quantum; def_quantum = def_quantum * current_rate / rate_quantum;
min_quantum = min_quantum * current_rate / rate_quantum; min_quantum = min_quantum * current_rate / rate_quantum;
max_quantum = max_quantum * current_rate / rate_quantum;
} }
/* calculate desired quantum */ /* calculate desired quantum */
@ -1234,6 +1241,7 @@ again:
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, min_quantum, max_quantum);
quantum = SPA_MIN(quantum, lim_quantum);
if (context->settings.clock_power_of_two_quantum) if (context->settings.clock_power_of_two_quantum)
quantum = flp2(quantum); quantum = flp2(quantum);

View file

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

View file

@ -44,6 +44,7 @@
#define DEFAULT_CLOCK_QUANTUM 1024u #define DEFAULT_CLOCK_QUANTUM 1024u
#define DEFAULT_CLOCK_MIN_QUANTUM 32u #define DEFAULT_CLOCK_MIN_QUANTUM 32u
#define DEFAULT_CLOCK_MAX_QUANTUM 8192u #define DEFAULT_CLOCK_MAX_QUANTUM 8192u
#define DEFAULT_CLOCK_QUANTUM_LIMIT 8192u
#define DEFAULT_CLOCK_POWER_OF_TWO_QUANTUM true #define DEFAULT_CLOCK_POWER_OF_TWO_QUANTUM true
#define DEFAULT_VIDEO_WIDTH 640 #define DEFAULT_VIDEO_WIDTH 640
#define DEFAULT_VIDEO_HEIGHT 480 #define DEFAULT_VIDEO_HEIGHT 480
@ -188,7 +189,7 @@ static int metadata_property(void *data, uint32_t subject, const char *key,
recalc = true; recalc = true;
} else if (spa_streq(key, "clock.force-quantum")) { } else if (spa_streq(key, "clock.force-quantum")) {
v = value ? atoi(value) : 0; v = value ? atoi(value) : 0;
s->clock_force_quantum = SPA_MIN(v, 8192u); s->clock_force_quantum = v;
recalc = true; recalc = true;
} }
if (recalc) 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_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_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_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.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_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); 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_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->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); 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, d->clock_min_quantum = SPA_CLAMP(d->clock_min_quantum,
CLOCK_MIN_QUANTUM, d->clock_max_quantum); CLOCK_MIN_QUANTUM, d->clock_max_quantum);
d->clock_quantum = SPA_CLAMP(d->clock_quantum, d->clock_quantum = SPA_CLAMP(d->clock_quantum,