mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	filter-chain: improve lv2 support
Add support for Worker. Add Options feature. Pass support in plugin load.
This commit is contained in:
		
							parent
							
								
									c04580a256
								
							
						
					
					
						commit
						8416d66ab3
					
				
					 5 changed files with 183 additions and 46 deletions
				
			
		| 
						 | 
				
			
			@ -39,7 +39,6 @@
 | 
			
		|||
#include <spa/utils/string.h>
 | 
			
		||||
#include <spa/utils/json.h>
 | 
			
		||||
#include <spa/param/profiler.h>
 | 
			
		||||
#include <spa/support/cpu.h>
 | 
			
		||||
#include <spa/debug/pod.h>
 | 
			
		||||
 | 
			
		||||
#include <pipewire/utils.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -739,6 +738,8 @@ static struct plugin *plugin_load(struct impl *impl, const char *type, const cha
 | 
			
		|||
	struct fc_plugin *pl = NULL;
 | 
			
		||||
	struct plugin *hndl;
 | 
			
		||||
	int res = 0;
 | 
			
		||||
	const struct spa_support *support;
 | 
			
		||||
	uint32_t n_support;
 | 
			
		||||
 | 
			
		||||
	spa_list_for_each(hndl, &impl->plugin_list, link) {
 | 
			
		||||
		if (spa_streq(hndl->type, type) &&
 | 
			
		||||
| 
						 | 
				
			
			@ -747,16 +748,17 @@ static struct plugin *plugin_load(struct impl *impl, const char *type, const cha
 | 
			
		|||
			return hndl;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	support = pw_context_get_support(impl->context, &n_support);
 | 
			
		||||
 | 
			
		||||
	if (spa_streq(type, "builtin")) {
 | 
			
		||||
		pl = load_builtin_plugin(path, NULL);
 | 
			
		||||
		pl = load_builtin_plugin(support, n_support, path, NULL);
 | 
			
		||||
	}
 | 
			
		||||
	else if (spa_streq(type, "ladspa")) {
 | 
			
		||||
		pl = load_ladspa_plugin(path, NULL);
 | 
			
		||||
		pl = load_ladspa_plugin(support, n_support, path, NULL);
 | 
			
		||||
	}
 | 
			
		||||
#ifdef HAVE_LILV
 | 
			
		||||
	else if (spa_streq(type, "lv2")) {
 | 
			
		||||
		pl = load_lv2_plugin(path, NULL);
 | 
			
		||||
		pl = load_lv2_plugin(support, n_support, path, NULL);
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
	if (pl == NULL)
 | 
			
		||||
| 
						 | 
				
			
			@ -1280,6 +1282,7 @@ static int setup_graph(struct graph *graph, struct spa_json *inputs, struct spa_
 | 
			
		|||
			sd = dd = NULL;
 | 
			
		||||
 | 
			
		||||
		for (i = 0; i < n_hndl; i++) {
 | 
			
		||||
			pw_log_info("instantiate %s %d", d->name, i);
 | 
			
		||||
			if ((node->hndl[i] = d->instantiate(d, &impl->rate, i, node->config)) == NULL) {
 | 
			
		||||
				pw_log_error("cannot create plugin instance");
 | 
			
		||||
				res = -ENOMEM;
 | 
			
		||||
| 
						 | 
				
			
			@ -1650,9 +1653,6 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
 | 
			
		|||
	struct impl *impl;
 | 
			
		||||
	uint32_t id = pw_global_get_id(pw_impl_module_get_global(module));
 | 
			
		||||
	const char *str;
 | 
			
		||||
	const struct spa_support *support;
 | 
			
		||||
	uint32_t n_support;
 | 
			
		||||
	struct spa_cpu *cpu_iface;
 | 
			
		||||
	int res;
 | 
			
		||||
 | 
			
		||||
	PW_LOG_TOPIC_INIT(mod_topic);
 | 
			
		||||
| 
						 | 
				
			
			@ -1663,10 +1663,6 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
 | 
			
		|||
 | 
			
		||||
	pw_log_debug("module %p: new %s", impl, args);
 | 
			
		||||
 | 
			
		||||
	support = pw_context_get_support(context, &n_support);
 | 
			
		||||
	cpu_iface = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_CPU);
 | 
			
		||||
	init_builtin_plugin(cpu_iface ? spa_cpu_get_flags(cpu_iface) : 0);
 | 
			
		||||
 | 
			
		||||
	if (args)
 | 
			
		||||
		props = pw_properties_new_string(args);
 | 
			
		||||
	else
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,6 +30,8 @@
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
#include <spa/utils/json.h>
 | 
			
		||||
#include <spa/support/cpu.h>
 | 
			
		||||
 | 
			
		||||
#include <pipewire/log.h>
 | 
			
		||||
 | 
			
		||||
#include "plugin.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -771,12 +773,11 @@ static struct fc_plugin builtin_plugin = {
 | 
			
		|||
	.make_desc = builtin_make_desc
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct fc_plugin *load_builtin_plugin(const char *plugin, const char *config)
 | 
			
		||||
struct fc_plugin *load_builtin_plugin(const struct spa_support *support, uint32_t n_support,
 | 
			
		||||
		const char *plugin, const char *config)
 | 
			
		||||
{
 | 
			
		||||
	struct spa_cpu *cpu_iface;
 | 
			
		||||
	cpu_iface = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_CPU);
 | 
			
		||||
	pffft_select_cpu(cpu_iface ? spa_cpu_get_flags(cpu_iface) : 0);
 | 
			
		||||
	return &builtin_plugin;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void init_builtin_plugin(uint32_t cpu_flags)
 | 
			
		||||
{
 | 
			
		||||
	pffft_select_cpu(cpu_flags);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -226,7 +226,8 @@ exit:
 | 
			
		|||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct fc_plugin *load_ladspa_plugin(const char *plugin, const char *config)
 | 
			
		||||
struct fc_plugin *load_ladspa_plugin(const struct spa_support *support, uint32_t n_support,
 | 
			
		||||
		const char *plugin, const char *config)
 | 
			
		||||
{
 | 
			
		||||
	struct fc_plugin *pl = NULL;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,6 +28,7 @@
 | 
			
		|||
#include <spa/utils/defs.h>
 | 
			
		||||
#include <spa/utils/list.h>
 | 
			
		||||
#include <spa/utils/string.h>
 | 
			
		||||
#include <spa/support/loop.h>
 | 
			
		||||
 | 
			
		||||
#include <pipewire/log.h>
 | 
			
		||||
#include <pipewire/utils.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -36,6 +37,9 @@
 | 
			
		|||
#include <lilv/lilv.h>
 | 
			
		||||
#include <lv2/lv2plug.in/ns/ext/atom/atom.h>
 | 
			
		||||
#include <lv2/lv2plug.in/ns/ext/buf-size/buf-size.h>
 | 
			
		||||
#include "lv2/lv2plug.in/ns/ext/worker/worker.h"
 | 
			
		||||
#include "lv2/lv2plug.in/ns/ext/options/options.h"
 | 
			
		||||
#include "lv2/lv2plug.in/ns/ext/parameters/parameters.h"
 | 
			
		||||
 | 
			
		||||
#include "plugin.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -61,17 +65,18 @@ static void uri_table_destroy(URITable *table)
 | 
			
		|||
static LV2_URID uri_table_map(LV2_URID_Map_Handle handle, const char *uri)
 | 
			
		||||
{
 | 
			
		||||
	URITable *table = (URITable*)handle;
 | 
			
		||||
	char *p;
 | 
			
		||||
	char **p;
 | 
			
		||||
	size_t i = 0;
 | 
			
		||||
 | 
			
		||||
	pw_array_for_each(p, &table->array) {
 | 
			
		||||
		if (spa_streq(p, uri))
 | 
			
		||||
			return i + 1;
 | 
			
		||||
		i++;
 | 
			
		||||
		if (spa_streq(*p, uri))
 | 
			
		||||
			goto done;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pw_array_add_ptr(&table->array, strdup(uri));
 | 
			
		||||
	return pw_array_get_len(&table->array, char*);
 | 
			
		||||
	i =  pw_array_get_len(&table->array, char*);
 | 
			
		||||
done:
 | 
			
		||||
	return i;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char *uri_table_unmap(LV2_URID_Map_Handle handle, LV2_URID urid)
 | 
			
		||||
| 
						 | 
				
			
			@ -87,6 +92,9 @@ struct context {
 | 
			
		|||
	int ref;
 | 
			
		||||
	LilvWorld *world;
 | 
			
		||||
 | 
			
		||||
	struct spa_loop *data_loop;
 | 
			
		||||
	struct spa_loop *main_loop;
 | 
			
		||||
 | 
			
		||||
	LilvNode *lv2_InputPort;
 | 
			
		||||
	LilvNode *lv2_OutputPort;
 | 
			
		||||
	LilvNode *lv2_AudioPort;
 | 
			
		||||
| 
						 | 
				
			
			@ -98,18 +106,25 @@ struct context {
 | 
			
		|||
	LilvNode *powerOf2BlockLength;
 | 
			
		||||
	LilvNode *fixedBlockLength;
 | 
			
		||||
	LilvNode *boundedBlockLength;
 | 
			
		||||
	LilvNode* worker_schedule;
 | 
			
		||||
	LilvNode* worker_iface;
 | 
			
		||||
 | 
			
		||||
	URITable uri_table;
 | 
			
		||||
	LV2_URID_Map map;
 | 
			
		||||
	LV2_URID_Unmap unmap;
 | 
			
		||||
	LV2_Feature map_feature;
 | 
			
		||||
	LV2_URID_Unmap unmap;
 | 
			
		||||
	LV2_Feature unmap_feature;
 | 
			
		||||
	const LV2_Feature *features[5];
 | 
			
		||||
 | 
			
		||||
	LV2_URID atom_Int;
 | 
			
		||||
	LV2_URID atom_Float;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define context_map(c,uri) ((c)->map.map((c)->map.handle,(uri)))
 | 
			
		||||
 | 
			
		||||
static void context_free(struct context *c)
 | 
			
		||||
{
 | 
			
		||||
	if (c->world) {
 | 
			
		||||
		lilv_node_free(c->worker_schedule);
 | 
			
		||||
		lilv_node_free(c->powerOf2BlockLength);
 | 
			
		||||
		lilv_node_free(c->fixedBlockLength);
 | 
			
		||||
		lilv_node_free(c->boundedBlockLength);
 | 
			
		||||
| 
						 | 
				
			
			@ -133,7 +148,7 @@ static const LV2_Feature buf_size_features[3] = {
 | 
			
		|||
	{ LV2_BUF_SIZE__boundedBlockLength,  NULL },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static struct context *context_new(void)
 | 
			
		||||
static struct context *context_new(const struct spa_support *support, uint32_t n_support)
 | 
			
		||||
{
 | 
			
		||||
	struct context *c;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -159,6 +174,8 @@ static struct context *context_new(void)
 | 
			
		|||
	c->powerOf2BlockLength = lilv_new_uri(c->world, LV2_BUF_SIZE__powerOf2BlockLength);
 | 
			
		||||
	c->fixedBlockLength = lilv_new_uri(c->world, LV2_BUF_SIZE__fixedBlockLength);
 | 
			
		||||
	c->boundedBlockLength = lilv_new_uri(c->world, LV2_BUF_SIZE__boundedBlockLength);
 | 
			
		||||
        c->worker_schedule = lilv_new_uri(c->world, LV2_WORKER__schedule);
 | 
			
		||||
	c->worker_iface = lilv_new_uri(c->world, LV2_WORKER__interface);
 | 
			
		||||
 | 
			
		||||
	c->map.handle = &c->uri_table;
 | 
			
		||||
	c->map.map = uri_table_map;
 | 
			
		||||
| 
						 | 
				
			
			@ -168,11 +185,12 @@ static struct context *context_new(void)
 | 
			
		|||
	c->unmap.unmap  = uri_table_unmap;
 | 
			
		||||
	c->unmap_feature.URI = LV2_URID_UNMAP_URI;
 | 
			
		||||
	c->unmap_feature.data = &c->unmap;
 | 
			
		||||
	c->features[0] = &c->map_feature;
 | 
			
		||||
	c->features[1] = &c->unmap_feature;
 | 
			
		||||
	c->features[2] = &buf_size_features[0];
 | 
			
		||||
	c->features[3] = &buf_size_features[1];
 | 
			
		||||
	c->features[4] = &buf_size_features[2];
 | 
			
		||||
 | 
			
		||||
	c->atom_Int = context_map(c, LV2_ATOM__Int);
 | 
			
		||||
	c->atom_Float = context_map(c, LV2_ATOM__Float);
 | 
			
		||||
 | 
			
		||||
	c->data_loop = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_DataLoop);
 | 
			
		||||
	c->main_loop = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Loop);
 | 
			
		||||
 | 
			
		||||
	return c;
 | 
			
		||||
error:
 | 
			
		||||
| 
						 | 
				
			
			@ -180,10 +198,10 @@ error:
 | 
			
		|||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct context *context_ref(void)
 | 
			
		||||
static struct context *context_ref(const struct spa_support *support, uint32_t n_support)
 | 
			
		||||
{
 | 
			
		||||
	if (_context == NULL) {
 | 
			
		||||
		_context = context_new();
 | 
			
		||||
		_context = context_new(support, n_support);
 | 
			
		||||
		if (_context == NULL)
 | 
			
		||||
			return NULL;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -210,38 +228,156 @@ struct descriptor {
 | 
			
		|||
	struct plugin *p;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct instance {
 | 
			
		||||
	struct descriptor *desc;
 | 
			
		||||
	LilvInstance *instance;
 | 
			
		||||
	LV2_Worker_Schedule work_schedule;
 | 
			
		||||
	LV2_Feature work_schedule_feature;
 | 
			
		||||
	LV2_Options_Option options[6];
 | 
			
		||||
	LV2_Feature options_feature;
 | 
			
		||||
 | 
			
		||||
	const LV2_Feature *features[7];
 | 
			
		||||
 | 
			
		||||
	const LV2_Worker_Interface *work_iface;
 | 
			
		||||
 | 
			
		||||
	int32_t block_length;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
do_respond(struct spa_loop *loop, bool async, uint32_t seq, const void *data,
 | 
			
		||||
		size_t size, void *user_data)
 | 
			
		||||
{
 | 
			
		||||
	struct instance *i = (struct instance*)user_data;
 | 
			
		||||
	i->work_iface->work_response(i->instance->lv2_handle, size, data);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Called by the plugin to respond to non-RT work. */
 | 
			
		||||
static LV2_Worker_Status
 | 
			
		||||
work_respond(LV2_Worker_Respond_Handle handle, uint32_t size, const void *data)
 | 
			
		||||
{
 | 
			
		||||
	struct instance *i = (struct instance*)handle;
 | 
			
		||||
	struct context *c = i->desc->p->c;
 | 
			
		||||
	spa_loop_invoke(c->data_loop, do_respond, 1, data, size, false, i);
 | 
			
		||||
	return LV2_WORKER_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
do_schedule(struct spa_loop *loop, bool async, uint32_t seq, const void *data,
 | 
			
		||||
		size_t size, void *user_data)
 | 
			
		||||
{
 | 
			
		||||
	struct instance *i = (struct instance*)user_data;
 | 
			
		||||
	i->work_iface->work(i->instance->lv2_handle, work_respond, i, size, data);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Called by the plugin to schedule non-RT work. */
 | 
			
		||||
static LV2_Worker_Status
 | 
			
		||||
work_schedule(LV2_Worker_Schedule_Handle handle, uint32_t size, const void *data)
 | 
			
		||||
{
 | 
			
		||||
	struct instance *i = (struct instance*)handle;
 | 
			
		||||
	struct context *c = i->desc->p->c;
 | 
			
		||||
	spa_loop_invoke(c->main_loop, do_schedule, 1, data, size, false, i);
 | 
			
		||||
	return LV2_WORKER_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void *lv2_instantiate(const struct fc_descriptor *desc,
 | 
			
		||||
                        unsigned long *SampleRate, int index, const char *config)
 | 
			
		||||
{
 | 
			
		||||
	struct descriptor *d = (struct descriptor*)desc;
 | 
			
		||||
	struct plugin *p = d->p;
 | 
			
		||||
	struct context *c = p->c;
 | 
			
		||||
	return lilv_plugin_instantiate(p->p, *SampleRate, c->features);
 | 
			
		||||
	struct instance *i;
 | 
			
		||||
	uint32_t n_features = 0;
 | 
			
		||||
	static const int32_t min_block_length = 1;
 | 
			
		||||
	static const int32_t max_block_length = 8192;
 | 
			
		||||
	static const int32_t seq_size = 32768;
 | 
			
		||||
	float fsample_rate = *SampleRate;
 | 
			
		||||
 | 
			
		||||
	i = calloc(1, sizeof(*i));
 | 
			
		||||
	if (i == NULL)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	i->block_length = 1024;
 | 
			
		||||
	i->desc = d;
 | 
			
		||||
	i->features[n_features++] = &c->map_feature;
 | 
			
		||||
	i->features[n_features++] = &c->unmap_feature;
 | 
			
		||||
	i->features[n_features++] = &buf_size_features[0];
 | 
			
		||||
	i->features[n_features++] = &buf_size_features[1];
 | 
			
		||||
	i->features[n_features++] = &buf_size_features[2];
 | 
			
		||||
	if (lilv_plugin_has_feature(p->p, c->worker_schedule)) {
 | 
			
		||||
		i->work_schedule.handle = i;
 | 
			
		||||
		i->work_schedule.schedule_work = work_schedule;
 | 
			
		||||
		i->work_schedule_feature.URI = LV2_WORKER__schedule;
 | 
			
		||||
		i->work_schedule_feature.data = &i->work_schedule;
 | 
			
		||||
		i->features[n_features++] = &i->work_schedule_feature;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	i->options[0] = (LV2_Options_Option) { LV2_OPTIONS_INSTANCE, 0,
 | 
			
		||||
		context_map(c, LV2_BUF_SIZE__minBlockLength), sizeof(int32_t),
 | 
			
		||||
		c->atom_Int, &min_block_length };
 | 
			
		||||
	i->options[1] = (LV2_Options_Option) { LV2_OPTIONS_INSTANCE, 0,
 | 
			
		||||
		context_map(c, LV2_BUF_SIZE__maxBlockLength), sizeof(int32_t),
 | 
			
		||||
		c->atom_Int, &max_block_length };
 | 
			
		||||
	i->options[2] = (LV2_Options_Option) { LV2_OPTIONS_INSTANCE, 0,
 | 
			
		||||
		context_map(c, LV2_BUF_SIZE__sequenceSize), sizeof(int32_t),
 | 
			
		||||
		c->atom_Int, &seq_size };
 | 
			
		||||
	i->options[3] = (LV2_Options_Option) { LV2_OPTIONS_INSTANCE, 0,
 | 
			
		||||
		context_map(c, "http://lv2plug.in/ns/ext/buf-size#nominalBlockLength"), sizeof(int32_t),
 | 
			
		||||
		c->atom_Int, &i->block_length },
 | 
			
		||||
	i->options[4] = (LV2_Options_Option) { LV2_OPTIONS_INSTANCE, 0,
 | 
			
		||||
		context_map(c, LV2_PARAMETERS__sampleRate), sizeof(float),
 | 
			
		||||
		c->atom_Float, &fsample_rate };
 | 
			
		||||
	i->options[5] = (LV2_Options_Option) { LV2_OPTIONS_INSTANCE, 0, 0, 0, 0, NULL };
 | 
			
		||||
 | 
			
		||||
        i->options_feature.URI = LV2_OPTIONS__options;
 | 
			
		||||
        i->options_feature.data = i->options;
 | 
			
		||||
        i->features[n_features++] = &i->options_feature;
 | 
			
		||||
 | 
			
		||||
	i->instance = lilv_plugin_instantiate(p->p, *SampleRate, i->features);
 | 
			
		||||
	if (i->instance == NULL) {
 | 
			
		||||
		free(i);
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
	if (lilv_plugin_has_extension_data(p->p, c->worker_iface)) {
 | 
			
		||||
                i->work_iface = (const LV2_Worker_Interface*)
 | 
			
		||||
			lilv_instance_get_extension_data(i->instance, LV2_WORKER__interface);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
	return i;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void lv2_cleanup(void *instance)
 | 
			
		||||
{
 | 
			
		||||
	lilv_instance_free(instance);
 | 
			
		||||
	struct instance *i = instance;
 | 
			
		||||
	lilv_instance_free(i->instance);
 | 
			
		||||
	free(i);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void lv2_connect_port(void *instance, unsigned long port, float *data)
 | 
			
		||||
{
 | 
			
		||||
	lilv_instance_connect_port(instance, port, data);
 | 
			
		||||
	struct instance *i = instance;
 | 
			
		||||
	lilv_instance_connect_port(i->instance, port, data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void lv2_activate(void *instance)
 | 
			
		||||
{
 | 
			
		||||
	lilv_instance_activate(instance);
 | 
			
		||||
	struct instance *i = instance;
 | 
			
		||||
	lilv_instance_activate(i->instance);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void lv2_deactivate(void *instance)
 | 
			
		||||
{
 | 
			
		||||
	lilv_instance_deactivate(instance);
 | 
			
		||||
	struct instance *i = instance;
 | 
			
		||||
	lilv_instance_deactivate(i->instance);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void lv2_run(void *instance, unsigned long SampleCount)
 | 
			
		||||
{
 | 
			
		||||
	lilv_instance_run(instance, SampleCount);
 | 
			
		||||
	struct instance *i = instance;
 | 
			
		||||
	lilv_instance_run(i->instance, SampleCount);
 | 
			
		||||
	if (i->work_iface != NULL && i->work_iface->end_run != NULL)
 | 
			
		||||
		i->work_iface->end_run(i->instance);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void lv2_free(struct fc_descriptor *desc)
 | 
			
		||||
| 
						 | 
				
			
			@ -319,7 +455,8 @@ static void lv2_unload(struct fc_plugin *plugin)
 | 
			
		|||
	free(p);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct fc_plugin *load_lv2_plugin(const char *plugin_uri, const char *config)
 | 
			
		||||
struct fc_plugin *load_lv2_plugin(const struct spa_support *support, uint32_t n_support,
 | 
			
		||||
		const char *plugin_uri, const char *config)
 | 
			
		||||
{
 | 
			
		||||
	struct context *c;
 | 
			
		||||
	const LilvPlugins *plugins;
 | 
			
		||||
| 
						 | 
				
			
			@ -328,7 +465,7 @@ struct fc_plugin *load_lv2_plugin(const char *plugin_uri, const char *config)
 | 
			
		|||
	int res;
 | 
			
		||||
	struct plugin *p;
 | 
			
		||||
 | 
			
		||||
	c = context_ref();
 | 
			
		||||
	c = context_ref(support, n_support);
 | 
			
		||||
	if (c == NULL)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,6 +28,7 @@
 | 
			
		|||
#include <stdio.h>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
 | 
			
		||||
#include <spa/support/plugin.h>
 | 
			
		||||
#include <spa/utils/defs.h>
 | 
			
		||||
#include <spa/utils/list.h>
 | 
			
		||||
#include <spa/utils/string.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -93,8 +94,9 @@ static inline void fc_descriptor_free(struct fc_descriptor *desc)
 | 
			
		|||
		desc->free(desc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct fc_plugin *load_ladspa_plugin(const char *path, const char *config);
 | 
			
		||||
struct fc_plugin *load_lv2_plugin(const char *path, const char *config);
 | 
			
		||||
struct fc_plugin *load_builtin_plugin(const char *path, const char *config);
 | 
			
		||||
 | 
			
		||||
void init_builtin_plugin(uint32_t cpu_flags);
 | 
			
		||||
struct fc_plugin *load_ladspa_plugin(const struct spa_support *support, uint32_t n_support,
 | 
			
		||||
		const char *path, const char *config);
 | 
			
		||||
struct fc_plugin *load_lv2_plugin(const struct spa_support *support, uint32_t n_support,
 | 
			
		||||
		const char *path, const char *config);
 | 
			
		||||
struct fc_plugin *load_builtin_plugin(const struct spa_support *support, uint32_t n_support,
 | 
			
		||||
		const char *path, const char *config);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue