mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2026-02-20 01:40:28 -05:00
filter-graph: Make a new control_sync function
This function is run for all the nodes with the data loop locked. It can be used to atomically update multiple node controls. We can't use the control_changed function because this one runs without the lock and might do slow things, like what the sofa plugin currently does. See #5019
This commit is contained in:
parent
e7ca02c4d8
commit
7887c365d1
3 changed files with 52 additions and 38 deletions
|
|
@ -69,6 +69,7 @@ struct spa_fga_descriptor {
|
|||
|
||||
void (*connect_port) (void *instance, unsigned long port, void *data);
|
||||
void (*control_changed) (void *instance);
|
||||
void (*control_sync) (void *instance);
|
||||
|
||||
void (*activate) (void *instance);
|
||||
void (*deactivate) (void *instance);
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#include <spa/utils/string.h>
|
||||
#include <spa/utils/json.h>
|
||||
#include <spa/support/cpu.h>
|
||||
#include <spa/support/loop.h>
|
||||
#include <spa/support/plugin-loader.h>
|
||||
#include <spa/param/latency-utils.h>
|
||||
#include <spa/param/tag-utils.h>
|
||||
|
|
@ -221,6 +222,7 @@ struct impl {
|
|||
struct spa_cpu *cpu;
|
||||
struct spa_fga_dsp *dsp;
|
||||
struct spa_plugin_loader *loader;
|
||||
struct spa_loop *data_loop;
|
||||
|
||||
uint64_t info_all;
|
||||
struct spa_filter_graph_info info;
|
||||
|
|
@ -698,21 +700,46 @@ static int impl_reset(void *object)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void node_control_changed(struct node *node)
|
||||
static int
|
||||
do_emit_node_control_sync(struct spa_loop *loop, bool async, uint32_t seq, const void *data,
|
||||
size_t size, void *user_data)
|
||||
{
|
||||
const struct spa_fga_descriptor *d = node->desc->desc;
|
||||
struct impl *impl = user_data;
|
||||
struct graph *graph = &impl->graph;
|
||||
struct node *node;
|
||||
uint32_t i;
|
||||
spa_list_for_each(node, &graph->node_list, link) {
|
||||
const struct spa_fga_descriptor *d = node->desc->desc;
|
||||
if (!node->control_changed || d->control_sync == NULL)
|
||||
continue;
|
||||
for (i = 0; i < node->n_hndl; i++) {
|
||||
if (node->hndl[i] != NULL)
|
||||
d->control_sync(node->hndl[i]);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void emit_node_control_changed(struct impl *impl)
|
||||
{
|
||||
struct graph *graph = &impl->graph;
|
||||
struct node *node;
|
||||
uint32_t i;
|
||||
|
||||
if (!node->control_changed)
|
||||
return;
|
||||
spa_loop_locked(impl->data_loop, do_emit_node_control_sync, 1, NULL, 0, impl);
|
||||
|
||||
for (i = 0; i < node->n_hndl; i++) {
|
||||
if (node->hndl[i] == NULL)
|
||||
spa_list_for_each(node, &graph->node_list, link) {
|
||||
const struct spa_fga_descriptor *d = node->desc->desc;
|
||||
if (!node->control_changed)
|
||||
continue;
|
||||
if (d->control_changed)
|
||||
d->control_changed(node->hndl[i]);
|
||||
if (d->control_changed != NULL) {
|
||||
for (i = 0; i < node->n_hndl; i++) {
|
||||
if (node->hndl[i] != NULL)
|
||||
d->control_changed(node->hndl[i]);
|
||||
}
|
||||
}
|
||||
node->control_changed = false;
|
||||
}
|
||||
node->control_changed = false;
|
||||
}
|
||||
|
||||
static int sync_volume(struct graph *graph, struct volume *vol)
|
||||
|
|
@ -826,11 +853,7 @@ static int impl_set_props(void *object, enum spa_direction direction, const stru
|
|||
spa_pod_dynamic_builder_clean(&b);
|
||||
|
||||
if (changed > 0) {
|
||||
struct node *node;
|
||||
|
||||
spa_list_for_each(node, &graph->node_list, link)
|
||||
node_control_changed(node);
|
||||
|
||||
emit_node_control_changed(impl);
|
||||
spa_filter_graph_emit_props_changed(&impl->hooks, SPA_DIRECTION_INPUT);
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -1695,10 +1718,10 @@ static int impl_activate(void *object, const struct spa_dict *props)
|
|||
for (i = 0; i < node->n_hndl; i++) {
|
||||
if (d->activate)
|
||||
d->activate(node->hndl[i]);
|
||||
if (node->control_changed && d->control_changed)
|
||||
d->control_changed(node->hndl[i]);
|
||||
}
|
||||
}
|
||||
emit_node_control_changed(impl);
|
||||
|
||||
/* calculate latency */
|
||||
sort_reset(graph);
|
||||
while ((node = sort_next_node(graph)) != NULL) {
|
||||
|
|
@ -2346,6 +2369,7 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
spa_log_topic_init(impl->log, &log_topic);
|
||||
|
||||
impl->cpu = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_CPU);
|
||||
impl->data_loop = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_DataLoop);
|
||||
impl->max_align = spa_cpu_get_max_align(impl->cpu);
|
||||
|
||||
impl->dsp = spa_fga_dsp_new(impl->cpu ? spa_cpu_get_flags(impl->cpu) : 0);
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ struct plugin {
|
|||
|
||||
struct spa_fga_dsp *dsp;
|
||||
struct spa_log *log;
|
||||
struct spa_loop *data_loop;
|
||||
};
|
||||
|
||||
struct builtin {
|
||||
|
|
@ -547,11 +546,9 @@ static void bq_run(void *Instance, unsigned long samples)
|
|||
spa_fga_dsp_biquad_run(impl->dsp, bq, 1, 0, &out, (const float **)&in, 1, samples);
|
||||
}
|
||||
|
||||
static int
|
||||
do_bq_control_changed(struct spa_loop *loop, bool async, uint32_t seq, const void *data,
|
||||
size_t size, void *user_data)
|
||||
static void bq_control_sync(void * Instance)
|
||||
{
|
||||
struct builtin *impl = user_data;
|
||||
struct builtin *impl = Instance;
|
||||
if (impl->type == BQ_NONE) {
|
||||
float b0, b1, b2, a0, a1, a2;
|
||||
b0 = impl->port[5][0];
|
||||
|
|
@ -571,13 +568,6 @@ do_bq_control_changed(struct spa_loop *loop, bool async, uint32_t seq, const voi
|
|||
if (impl->freq != freq || impl->Q != Q || impl->gain != gain)
|
||||
bq_freq_update(impl, impl->type, freq, Q, gain);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bq_control_changed(void * Instance)
|
||||
{
|
||||
struct builtin *impl = Instance;
|
||||
spa_loop_locked(impl->plugin->data_loop, do_bq_control_changed, 1, NULL, 0, impl);
|
||||
}
|
||||
|
||||
/** bq_lowpass */
|
||||
|
|
@ -589,7 +579,7 @@ static const struct spa_fga_descriptor bq_lowpass_desc = {
|
|||
|
||||
.instantiate = bq_instantiate,
|
||||
.connect_port = builtin_connect_port,
|
||||
.control_changed = bq_control_changed,
|
||||
.control_sync = bq_control_sync,
|
||||
.activate = bq_activate,
|
||||
.run = bq_run,
|
||||
.cleanup = builtin_cleanup,
|
||||
|
|
@ -604,7 +594,7 @@ static const struct spa_fga_descriptor bq_highpass_desc = {
|
|||
|
||||
.instantiate = bq_instantiate,
|
||||
.connect_port = builtin_connect_port,
|
||||
.control_changed = bq_control_changed,
|
||||
.control_sync = bq_control_sync,
|
||||
.activate = bq_activate,
|
||||
.run = bq_run,
|
||||
.cleanup = builtin_cleanup,
|
||||
|
|
@ -619,7 +609,7 @@ static const struct spa_fga_descriptor bq_bandpass_desc = {
|
|||
|
||||
.instantiate = bq_instantiate,
|
||||
.connect_port = builtin_connect_port,
|
||||
.control_changed = bq_control_changed,
|
||||
.control_sync = bq_control_sync,
|
||||
.activate = bq_activate,
|
||||
.run = bq_run,
|
||||
.cleanup = builtin_cleanup,
|
||||
|
|
@ -634,7 +624,7 @@ static const struct spa_fga_descriptor bq_lowshelf_desc = {
|
|||
|
||||
.instantiate = bq_instantiate,
|
||||
.connect_port = builtin_connect_port,
|
||||
.control_changed = bq_control_changed,
|
||||
.control_sync = bq_control_sync,
|
||||
.activate = bq_activate,
|
||||
.run = bq_run,
|
||||
.cleanup = builtin_cleanup,
|
||||
|
|
@ -649,7 +639,7 @@ static const struct spa_fga_descriptor bq_highshelf_desc = {
|
|||
|
||||
.instantiate = bq_instantiate,
|
||||
.connect_port = builtin_connect_port,
|
||||
.control_changed = bq_control_changed,
|
||||
.control_sync = bq_control_sync,
|
||||
.activate = bq_activate,
|
||||
.run = bq_run,
|
||||
.cleanup = builtin_cleanup,
|
||||
|
|
@ -664,7 +654,7 @@ static const struct spa_fga_descriptor bq_peaking_desc = {
|
|||
|
||||
.instantiate = bq_instantiate,
|
||||
.connect_port = builtin_connect_port,
|
||||
.control_changed = bq_control_changed,
|
||||
.control_sync = bq_control_sync,
|
||||
.activate = bq_activate,
|
||||
.run = bq_run,
|
||||
.cleanup = builtin_cleanup,
|
||||
|
|
@ -679,7 +669,7 @@ static const struct spa_fga_descriptor bq_notch_desc = {
|
|||
|
||||
.instantiate = bq_instantiate,
|
||||
.connect_port = builtin_connect_port,
|
||||
.control_changed = bq_control_changed,
|
||||
.control_sync = bq_control_sync,
|
||||
.activate = bq_activate,
|
||||
.run = bq_run,
|
||||
.cleanup = builtin_cleanup,
|
||||
|
|
@ -695,7 +685,7 @@ static const struct spa_fga_descriptor bq_allpass_desc = {
|
|||
|
||||
.instantiate = bq_instantiate,
|
||||
.connect_port = builtin_connect_port,
|
||||
.control_changed = bq_control_changed,
|
||||
.control_sync = bq_control_sync,
|
||||
.activate = bq_activate,
|
||||
.run = bq_run,
|
||||
.cleanup = builtin_cleanup,
|
||||
|
|
@ -710,7 +700,7 @@ static const struct spa_fga_descriptor bq_raw_desc = {
|
|||
|
||||
.instantiate = bq_instantiate,
|
||||
.connect_port = builtin_connect_port,
|
||||
.control_changed = bq_control_changed,
|
||||
.control_sync = bq_control_sync,
|
||||
.activate = bq_activate,
|
||||
.run = bq_run,
|
||||
.cleanup = builtin_cleanup,
|
||||
|
|
@ -3411,7 +3401,6 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
|
||||
impl->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log);
|
||||
impl->dsp = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_FILTER_GRAPH_AudioDSP);
|
||||
impl->data_loop = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_DataLoop);
|
||||
|
||||
for (uint32_t i = 0; info && i < info->n_items; i++) {
|
||||
const char *k = info->items[i].key;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue