diff --git a/src/daemon/client-rt.conf.in b/src/daemon/client-rt.conf.in index e902beafd..fd85a9bce 100644 --- a/src/daemon/client-rt.conf.in +++ b/src/daemon/client-rt.conf.in @@ -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 = { diff --git a/src/daemon/client.conf.in b/src/daemon/client.conf.in index 8910085e4..8f216e364 100644 --- a/src/daemon/client.conf.in +++ b/src/daemon/client.conf.in @@ -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 = { diff --git a/src/daemon/jack.conf.in b/src/daemon/jack.conf.in index efd5ff511..8e648bd37 100644 --- a/src/daemon/jack.conf.in +++ b/src/daemon/jack.conf.in @@ -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 = { diff --git a/src/daemon/pipewire-pulse.conf.in b/src/daemon/pipewire-pulse.conf.in index 23870190e..ccf195713 100644 --- a/src/daemon/pipewire-pulse.conf.in +++ b/src/daemon/pipewire-pulse.conf.in @@ -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 = { diff --git a/src/daemon/pipewire.conf.in b/src/daemon/pipewire.conf.in index 9a749d0c2..77b19b290 100644 --- a/src/daemon/pipewire.conf.in +++ b/src/daemon/pipewire.conf.in @@ -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 diff --git a/src/modules/module-protocol-pulse/internal.h b/src/modules/module-protocol-pulse/internal.h index df222cf01..ebda6fcd6 100644 --- a/src/modules/module-protocol-pulse/internal.h +++ b/src/modules/module-protocol-pulse/internal.h @@ -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 { diff --git a/src/pipewire/context.c b/src/pipewire/context.c index f28369b30..33c6b9216 100644 --- a/src/pipewire/context.c +++ b/src/pipewire/context.c @@ -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); diff --git a/src/pipewire/private.h b/src/pipewire/private.h index 63126261b..2caca67d2 100644 --- a/src/pipewire/private.h +++ b/src/pipewire/private.h @@ -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; diff --git a/src/pipewire/settings.c b/src/pipewire/settings.c index 7aaac103c..6f8a7d5e4 100644 --- a/src/pipewire/settings.c +++ b/src/pipewire/settings.c @@ -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,