diff --git a/pipewire-jack/src/pipewire-jack.c b/pipewire-jack/src/pipewire-jack.c index 18ffb31c3..985396d47 100644 --- a/pipewire-jack/src/pipewire-jack.c +++ b/pipewire-jack/src/pipewire-jack.c @@ -2796,8 +2796,8 @@ jack_client_t * jack_client_open (const char *client_name, if (client->context.context == NULL) goto no_props; - client->allow_mlock = client->context.context->defaults.mem_allow_mlock; - client->warn_mlock = client->context.context->defaults.mem_warn_mlock; + client->allow_mlock = client->context.context->settings.mem_allow_mlock; + client->warn_mlock = client->context.context->settings.mem_warn_mlock; if ((str = pw_context_get_conf_section(client->context.context, "jack.properties")) != NULL) diff --git a/src/modules/module-client-node/remote-node.c b/src/modules/module-client-node/remote-node.c index f277dda3a..34fc199f0 100644 --- a/src/modules/module-client-node/remote-node.c +++ b/src/modules/module-client-node/remote-node.c @@ -1219,11 +1219,11 @@ static struct pw_proxy *node_export(struct pw_core *core, void *object, bool do_ data->client_node = (struct pw_client_node *)client_node; data->remote_id = SPA_ID_INVALID; - data->allow_mlock = data->context->defaults.mem_allow_mlock; + data->allow_mlock = data->context->settings.mem_allow_mlock; if ((str = pw_properties_get(node->properties, "mem.allow-mlock")) != NULL) data->allow_mlock = pw_properties_parse_bool(str); - data->warn_mlock = data->context->defaults.mem_warn_mlock; + data->warn_mlock = data->context->settings.mem_warn_mlock; if ((str = pw_properties_get(node->properties, "mem.warn-mlock")) != NULL) data->warn_mlock = pw_properties_parse_bool(str); diff --git a/src/pipewire/buffers.c b/src/pipewire/buffers.c index 65e3d7ee4..063d06181 100644 --- a/src/pipewire/buffers.c +++ b/src/pipewire/buffers.c @@ -278,7 +278,7 @@ int pw_buffers_negotiate(struct pw_context *context, uint32_t flags, offset += SPA_ROUND_UP_N(SPA_POD_SIZE(params[i]), 8); } - max_buffers = context->defaults.link_max_buffers; + max_buffers = context->settings.link_max_buffers; if ((str = pw_properties_get(context->properties, PW_KEY_CPU_MAX_ALIGN)) != NULL) align = pw_properties_parse_int(str); diff --git a/src/pipewire/context.c b/src/pipewire/context.c index a84c29014..d3ec90548 100644 --- a/src/pipewire/context.c +++ b/src/pipewire/context.c @@ -47,9 +47,6 @@ #define NAME "context" -#define CLOCK_MIN_QUANTUM 4u -#define CLOCK_MAX_QUANTUM 8192u - #define DEFAULT_CLOCK_RATE 48000u #define DEFAULT_CLOCK_QUANTUM 1024u #define DEFAULT_CLOCK_MIN_QUANTUM 32u @@ -141,26 +138,30 @@ static bool get_default_bool(struct pw_properties *properties, const char *name, static void fill_defaults(struct pw_context *this) { struct pw_properties *p = this->properties; - this->defaults.clock_power_of_two_quantum = get_default_bool(p, "clock.power-of-two-quantum", - DEFAULT_CLOCK_POWER_OF_TWO_QUANTUM); - this->defaults.clock_rate = get_default_int(p, "default.clock.rate", DEFAULT_CLOCK_RATE); - this->defaults.clock_quantum = get_default_int(p, "default.clock.quantum", DEFAULT_CLOCK_QUANTUM); - this->defaults.clock_min_quantum = get_default_int(p, "default.clock.min-quantum", DEFAULT_CLOCK_MIN_QUANTUM); - this->defaults.clock_max_quantum = get_default_int(p, "default.clock.max-quantum", DEFAULT_CLOCK_MAX_QUANTUM); - this->defaults.video_size.width = get_default_int(p, "default.video.width", DEFAULT_VIDEO_WIDTH); - this->defaults.video_size.height = get_default_int(p, "default.video.height", DEFAULT_VIDEO_HEIGHT); - this->defaults.video_rate.num = get_default_int(p, "default.video.rate.num", DEFAULT_VIDEO_RATE_NUM); - this->defaults.video_rate.denom = get_default_int(p, "default.video.rate.denom", DEFAULT_VIDEO_RATE_DENOM); - this->defaults.link_max_buffers = get_default_int(p, "link.max-buffers", DEFAULT_LINK_MAX_BUFFERS); - this->defaults.mem_warn_mlock = get_default_bool(p, "mem.warn-mlock", DEFAULT_MEM_WARN_MLOCK); - this->defaults.mem_allow_mlock = get_default_bool(p, "mem.allow-mlock", DEFAULT_MEM_ALLOW_MLOCK); + struct settings *d = &this->defaults; - this->defaults.clock_max_quantum = SPA_CLAMP(this->defaults.clock_max_quantum, + d->clock_rate = get_default_int(p, "default.clock.rate", DEFAULT_CLOCK_RATE); + 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->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); + d->video_rate.denom = get_default_int(p, "default.video.rate.denom", DEFAULT_VIDEO_RATE_DENOM); + + d->log_level = get_default_int(p, "log.level", pw_log_level); + d->clock_power_of_two_quantum = get_default_bool(p, "clock.power-of-two-quantum", + DEFAULT_CLOCK_POWER_OF_TWO_QUANTUM); + d->link_max_buffers = get_default_int(p, "link.max-buffers", DEFAULT_LINK_MAX_BUFFERS); + 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, CLOCK_MIN_QUANTUM, CLOCK_MAX_QUANTUM); - this->defaults.clock_min_quantum = SPA_CLAMP(this->defaults.clock_min_quantum, - CLOCK_MIN_QUANTUM, this->defaults.clock_max_quantum); - this->defaults.clock_quantum = SPA_CLAMP(this->defaults.clock_quantum, - this->defaults.clock_min_quantum, this->defaults.clock_max_quantum); + 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, + d->clock_min_quantum, d->clock_max_quantum); } static int try_load_conf(struct pw_context *this, const char *conf_prefix, @@ -306,6 +307,7 @@ struct pw_context *pw_context_new(struct pw_loop *main_loop, } fill_defaults(this); + this->settings = this->defaults; pr = pw_properties_copy(properties); if ((str = pw_properties_get(pr, "context.data-loop." PW_KEY_LIBRARY_NAME_SYSTEM))) @@ -953,10 +955,24 @@ static int collect_nodes(struct pw_context *context, struct pw_impl_node *driver return 0; } +static inline void get_quantums(struct pw_context *context, uint32_t *def, uint32_t *min, uint32_t *max) +{ + 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; +} +static inline void get_rate(struct pw_context *context, uint32_t *def) +{ + struct settings *s = &context->settings; + *def = s->clock_force_rate == 0 ? s->clock_rate : s->clock_force_rate; +} + 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, def_rate; pw_log_info(NAME" %p: busy:%d reason:%s", context, impl->recalc, reason); @@ -968,6 +984,9 @@ 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); + get_rate(context, &def_rate); + /* start from all drivers and group all nodes that are linked * to it. Some nodes are not (yet) linked to anything and they * will end up 'unassigned' to a driver. Other nodes are drivers @@ -1036,7 +1055,6 @@ again: /* assign final quantum and set state for followers and drivers */ spa_list_for_each(n, &context->driver_list, driver_link) { bool running = false; - uint32_t max_quantum = context->defaults.clock_max_quantum; uint32_t quantum = 0; if (!n->driving || n->exported) @@ -1057,12 +1075,11 @@ again: running = !n->passive; } if (quantum == 0) - quantum = context->defaults.clock_quantum; + quantum = def_quantum; - quantum = SPA_CLAMP(quantum, - context->defaults.clock_min_quantum, - max_quantum); + quantum = SPA_CLAMP(quantum, min_quantum, max_quantum); + n->rt.position->clock.rate = SPA_FRACTION(1, def_rate); if (n->rt.position && quantum != n->rt.position->clock.duration) { pw_log_info("(%s-%u) new quantum:%"PRIu64"->%u", n->name, n->info.id, diff --git a/src/pipewire/filter.c b/src/pipewire/filter.c index bf6a76667..33f08041c 100644 --- a/src/pipewire/filter.c +++ b/src/pipewire/filter.c @@ -1048,8 +1048,8 @@ filter_new(struct pw_context *context, const char *name, this->state = PW_FILTER_STATE_UNCONNECTED; impl->context = context; - impl->allow_mlock = context->defaults.mem_allow_mlock; - impl->warn_mlock = context->defaults.mem_warn_mlock; + impl->allow_mlock = context->settings.mem_allow_mlock; + impl->warn_mlock = context->settings.mem_warn_mlock; return impl; diff --git a/src/pipewire/impl-node.c b/src/pipewire/impl-node.c index ead2778ac..a732a7213 100644 --- a/src/pipewire/impl-node.c +++ b/src/pipewire/impl-node.c @@ -879,16 +879,16 @@ static void check_properties(struct pw_impl_node *node) uint32_t quantum_size; node->latency = SPA_FRACTION(num, denom); - quantum_size = (num * context->defaults.clock_rate / denom); - if (context->defaults.clock_power_of_two_quantum) + quantum_size = (num * context->settings.clock_rate / denom); + if (context->settings.clock_power_of_two_quantum) quantum_size = flp2(quantum_size); if (quantum_size != node->quantum_size) { pw_log_debug(NAME" %p: latency '%s' quantum %u/%u", - node, str, quantum_size, context->defaults.clock_rate); + node, str, quantum_size, context->settings.clock_rate); pw_log_info("(%s-%u) latency:%s ->quantum %u/%u", node->name, node->info.id, str, quantum_size, - context->defaults.clock_rate); + context->settings.clock_rate); node->quantum_size = quantum_size; recalc_reason = "quantum changed"; } @@ -900,16 +900,16 @@ static void check_properties(struct pw_impl_node *node) uint32_t max_quantum_size; node->max_latency = SPA_FRACTION(num, denom); - max_quantum_size = (num * context->defaults.clock_rate / denom); - if (context->defaults.clock_power_of_two_quantum) + max_quantum_size = (num * context->settings.clock_rate / denom); + if (context->settings.clock_power_of_two_quantum) max_quantum_size = flp2(max_quantum_size); if (max_quantum_size != node->max_quantum_size) { pw_log_debug(NAME" %p: max latency '%s' quantum %u/%u", - node, str, max_quantum_size, context->defaults.clock_rate); + node, str, max_quantum_size, context->settings.clock_rate); pw_log_info("(%s-%u) max latency:%s ->quantum %u/%u", node->name, node->info.id, str, max_quantum_size, - context->defaults.clock_rate); + context->settings.clock_rate); node->max_quantum_size = max_quantum_size; recalc_reason = "max quantum changed"; } @@ -1105,7 +1105,7 @@ static void reset_segment(struct spa_io_segment *seg) static void reset_position(struct pw_impl_node *this, struct spa_io_position *pos) { uint32_t i; - struct defaults *def = &this->context->defaults; + struct settings *def = &this->context->settings; pos->clock.rate = SPA_FRACTION(1, def->clock_rate); pos->clock.duration = def->clock_quantum; diff --git a/src/pipewire/private.h b/src/pipewire/private.h index c61789ff5..c12b989b7 100644 --- a/src/pipewire/private.h +++ b/src/pipewire/private.h @@ -49,7 +49,11 @@ struct ucred { #define spa_debug(...) pw_log_trace(__VA_ARGS__) #endif -struct defaults { +#define CLOCK_MIN_QUANTUM 4u +#define CLOCK_MAX_QUANTUM 8192u + +struct settings { + uint32_t log_level; uint32_t clock_rate; uint32_t clock_quantum; uint32_t clock_min_quantum; @@ -60,6 +64,8 @@ struct defaults { unsigned int mem_warn_mlock:1; unsigned int mem_allow_mlock:1; unsigned int clock_power_of_two_quantum:1; + uint32_t clock_force_rate; + uint32_t clock_force_quantum; }; struct ratelimit { @@ -378,7 +384,8 @@ struct pw_context { struct pw_properties *conf; /**< configuration of the context */ struct pw_properties *properties; /**< properties of the context */ - struct defaults defaults; /**< default parameters */ + struct settings defaults; /**< default parameters */ + struct settings settings; /**< current parameters */ struct pw_mempool *pool; /**< global memory pool */ diff --git a/src/pipewire/stream.c b/src/pipewire/stream.c index 3b9a304d7..2f1c55ae9 100644 --- a/src/pipewire/stream.c +++ b/src/pipewire/stream.c @@ -1295,8 +1295,8 @@ stream_new(struct pw_context *context, const char *name, this->state = PW_STREAM_STATE_UNCONNECTED; impl->context = context; - impl->allow_mlock = context->defaults.mem_allow_mlock; - impl->warn_mlock = context->defaults.mem_warn_mlock; + impl->allow_mlock = context->settings.mem_allow_mlock; + impl->warn_mlock = context->settings.mem_warn_mlock; spa_hook_list_append(&impl->context->driver_listener_list, &impl->context_listener,