mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
context: add force-quantum and force-rate property
Add a node.force-quantum and node.force-rate property. When no global quantum or rate is enforce with settings, the last updated node property is used as the quantum. Make jack use the force-quantum property when set_buffersize is used to make sure that the quantum is not just a suggestion but a hard forced one. This makes it possible for ardour or other jack apps to raise the quantum above the max-quantum but also ensure that it will not change by any other application (unless other jack apps). Fixes #2079
This commit is contained in:
parent
54d50b943f
commit
24c97b1c7e
5 changed files with 54 additions and 6 deletions
|
|
@ -3997,6 +3997,7 @@ int jack_set_buffer_size (jack_client_t *client, jack_nframes_t nframes)
|
|||
|
||||
pw_thread_loop_lock(c->context.loop);
|
||||
pw_properties_set(c->props, PW_KEY_NODE_LATENCY, latency);
|
||||
pw_properties_setf(c->props, PW_KEY_NODE_FORCE_QUANTUM, "%u", nframes);
|
||||
|
||||
c->info.change_mask |= SPA_NODE_CHANGE_MASK_PROPS;
|
||||
c->info.props = &c->props->dict;
|
||||
|
|
|
|||
|
|
@ -1066,10 +1066,11 @@ static bool rates_contains(uint32_t *rates, uint32_t n_rates, uint32_t rate)
|
|||
int pw_context_recalc_graph(struct pw_context *context, const char *reason)
|
||||
{
|
||||
struct impl *impl = SPA_CONTAINER_OF(context, struct impl, this);
|
||||
struct settings *settings = &context->settings;
|
||||
struct pw_impl_node *n, *s, *target, *fallback;
|
||||
uint32_t max_quantum, min_quantum, def_quantum, lim_quantum, rate_quantum;
|
||||
uint32_t *rates, n_rates, def_rate;
|
||||
bool freewheel = false, force_rate;
|
||||
bool freewheel = false, global_force_rate, force_rate, global_force_quantum;
|
||||
|
||||
pw_log_info("%p: busy:%d reason:%s", context, impl->recalc, reason);
|
||||
|
||||
|
|
@ -1082,7 +1083,10 @@ again:
|
|||
impl->recalc = true;
|
||||
|
||||
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, &global_force_rate);
|
||||
|
||||
global_force_quantum = rate_quantum == 0;
|
||||
force_rate = global_force_rate;
|
||||
|
||||
/* start from all drivers and group all nodes that are linked
|
||||
* to it. Some nodes are not (yet) linked to anything and they
|
||||
|
|
@ -1164,6 +1168,7 @@ again:
|
|||
struct spa_fraction max_latency = SPA_FRACTION(0, 0);
|
||||
struct spa_fraction rate = SPA_FRACTION(0, 0);
|
||||
uint32_t quantum, target_rate, current_rate;
|
||||
uint64_t quantum_stamp = 0, rate_stamp = 0;
|
||||
|
||||
if (!n->driving || n->exported)
|
||||
continue;
|
||||
|
|
@ -1175,6 +1180,20 @@ again:
|
|||
lock_quantum |= s->lock_quantum;
|
||||
lock_rate |= s->lock_rate;
|
||||
}
|
||||
if (!global_force_quantum && s->force_quantum > 0 &&
|
||||
s->stamp > quantum_stamp) {
|
||||
def_quantum = min_quantum = max_quantum = s->force_quantum;
|
||||
rate_quantum = 0;
|
||||
quantum_stamp = s->stamp;
|
||||
}
|
||||
if (!global_force_rate && s->force_rate > 0 &&
|
||||
s->stamp > rate_stamp) {
|
||||
def_rate = s->force_rate;
|
||||
force_rate = true;
|
||||
n_rates = 1;
|
||||
rates = &s->force_rate;
|
||||
rate_stamp = s->stamp;
|
||||
}
|
||||
|
||||
/* smallest latencies */
|
||||
if (latency.denom == 0 ||
|
||||
|
|
@ -1221,7 +1240,7 @@ again:
|
|||
target_rate);
|
||||
|
||||
if (force_rate) {
|
||||
if (context->settings.clock_rate_update_mode == CLOCK_RATE_UPDATE_MODE_HARD)
|
||||
if (settings->clock_rate_update_mode == CLOCK_RATE_UPDATE_MODE_HARD)
|
||||
suspend_driver(context, n);
|
||||
} else {
|
||||
if (n->info.state >= PW_NODE_STATE_IDLE)
|
||||
|
|
@ -1253,7 +1272,7 @@ again:
|
|||
quantum = SPA_CLAMP(quantum, min_quantum, max_quantum);
|
||||
quantum = SPA_MIN(quantum, lim_quantum);
|
||||
|
||||
if (context->settings.clock_power_of_two_quantum)
|
||||
if (settings->clock_power_of_two_quantum)
|
||||
quantum = flp2(quantum);
|
||||
|
||||
if (running && quantum != n->current_quantum && !lock_quantum) {
|
||||
|
|
|
|||
|
|
@ -857,6 +857,7 @@ static void check_properties(struct pw_impl_node *node)
|
|||
struct pw_context *context = node->context;
|
||||
const char *str, *recalc_reason = NULL;
|
||||
struct spa_fraction frac;
|
||||
uint32_t value;
|
||||
bool driver;
|
||||
|
||||
if ((str = pw_properties_get(node->properties, PW_KEY_PRIORITY_DRIVER))) {
|
||||
|
|
@ -935,6 +936,15 @@ static void check_properties(struct pw_impl_node *node)
|
|||
}
|
||||
node->lock_quantum = pw_properties_get_bool(node->properties, PW_KEY_NODE_LOCK_QUANTUM, false);
|
||||
|
||||
if ((str = pw_properties_get(node->properties, PW_KEY_NODE_FORCE_QUANTUM))) {
|
||||
if (spa_atou32(str, &value, 0) &&
|
||||
node->force_quantum != value) {
|
||||
node->force_quantum = value;
|
||||
node->stamp = ++context->stamp;
|
||||
recalc_reason = "force quantum changed";
|
||||
}
|
||||
}
|
||||
|
||||
if ((str = pw_properties_get(node->properties, PW_KEY_NODE_RATE))) {
|
||||
if (sscanf(str, "%u/%u", &frac.num, &frac.denom) == 2 && frac.denom != 0) {
|
||||
if (node->rate.num != frac.num || node->rate.denom != frac.denom) {
|
||||
|
|
@ -948,6 +958,15 @@ static void check_properties(struct pw_impl_node *node)
|
|||
}
|
||||
node->lock_rate = pw_properties_get_bool(node->properties, PW_KEY_NODE_LOCK_RATE, false);
|
||||
|
||||
if ((str = pw_properties_get(node->properties, PW_KEY_NODE_FORCE_RATE))) {
|
||||
if (spa_atou32(str, &value, 0) &&
|
||||
node->force_rate != value) {
|
||||
node->force_rate = value;
|
||||
node->stamp = ++context->stamp;
|
||||
recalc_reason = "force rate changed";
|
||||
}
|
||||
}
|
||||
|
||||
pw_log_debug("%p: driver:%d recalc:%s active:%d", node, node->driver,
|
||||
recalc_reason, node->active);
|
||||
|
||||
|
|
@ -1787,6 +1806,7 @@ void pw_impl_node_destroy(struct pw_impl_node *node)
|
|||
struct impl *impl = SPA_CONTAINER_OF(node, struct impl, this);
|
||||
struct pw_impl_port *port;
|
||||
struct pw_impl_node *follower;
|
||||
struct pw_context *context = node->context;
|
||||
bool active, had_driver;
|
||||
|
||||
active = node->active;
|
||||
|
|
@ -1836,7 +1856,7 @@ void pw_impl_node_destroy(struct pw_impl_node *node)
|
|||
}
|
||||
|
||||
if (active || had_driver)
|
||||
pw_context_recalc_graph(node->context,
|
||||
pw_context_recalc_graph(context,
|
||||
"active node destroy");
|
||||
|
||||
pw_log_debug("%p: free", node);
|
||||
|
|
@ -1858,7 +1878,7 @@ void pw_impl_node_destroy(struct pw_impl_node *node)
|
|||
|
||||
clear_info(node);
|
||||
|
||||
spa_system_close(node->context->data_system, node->source.fd);
|
||||
spa_system_close(context->data_system, node->source.fd);
|
||||
free(impl);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -161,10 +161,14 @@ extern "C" {
|
|||
* node as a fraction. Ex: 1024/48000 */
|
||||
#define PW_KEY_NODE_LOCK_QUANTUM "node.lock-quantum" /**< don't change quantum when this node
|
||||
* is active */
|
||||
#define PW_KEY_NODE_FORCE_QUANTUM "node.force-quantum" /**< force a quantum while the node is
|
||||
* active */
|
||||
#define PW_KEY_NODE_RATE "node.rate" /**< the requested rate of the graph as
|
||||
* a fraction. Ex: 1/48000 */
|
||||
#define PW_KEY_NODE_LOCK_RATE "node.lock-rate" /**< don't change rate when this node
|
||||
* is active */
|
||||
#define PW_KEY_NODE_FORCE_RATE "node.force-rate" /**< force a rate while the node is
|
||||
* active */
|
||||
|
||||
#define PW_KEY_NODE_DONT_RECONNECT "node.dont-reconnect" /**< don't reconnect this node */
|
||||
#define PW_KEY_NODE_ALWAYS_PROCESS "node.always-process" /**< process even when unlinked */
|
||||
|
|
|
|||
|
|
@ -424,6 +424,7 @@ struct pw_context {
|
|||
|
||||
struct pw_mempool *pool; /**< global memory pool */
|
||||
|
||||
uint64_t stamp;
|
||||
uint64_t serial;
|
||||
struct pw_map globals; /**< map of globals */
|
||||
|
||||
|
|
@ -713,6 +714,9 @@ struct pw_impl_node {
|
|||
struct spa_fraction latency; /**< requested latency */
|
||||
struct spa_fraction max_latency; /**< maximum latency */
|
||||
struct spa_fraction rate; /**< requested rate */
|
||||
uint32_t force_quantum; /**< forced quantum */
|
||||
uint32_t force_rate; /**< forced rate */
|
||||
uint32_t stamp; /**< stamp of last update */
|
||||
struct spa_source source; /**< source to remotely trigger this node */
|
||||
struct pw_memblock *activation;
|
||||
struct {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue