Commit ef72fa74c0 for ffmpeg
commit ef72fa74c0beca2ad82fae04e002857db6270e49
Author: Ramiro Polla <ramiro.polla@gmail.com>
Date: Thu Oct 8 16:25:03 2026 +0200
avfilter/af_lv2: support plugins built with DPF
Plugins built with DPF require the LV2 options feature to be passed to
lilv_plugin_instantiate(), otherwise they fail to instantiate with the
error:
Options feature missing, cannot continue!
Only the maxBlockLength option seems to be necessary.
Tested with all plugins from dpf-plugins-lv2 from Debian 13.
Fixes #24272.
Reported-by: hellocatfood <hellocatfoodsocial@gmail.com>
diff --git a/libavfilter/af_lv2.c b/libavfilter/af_lv2.c
index e9375b2881..749cc517f7 100644
--- a/libavfilter/af_lv2.c
+++ b/libavfilter/af_lv2.c
@@ -27,6 +27,7 @@
#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/options/options.h>
#include "libavutil/avstring.h"
#include "libavutil/channel_layout.h"
@@ -65,9 +66,12 @@ typedef struct LV2Context {
LV2_Feature map_feature;
LV2_URID_Unmap unmap;
LV2_Feature unmap_feature;
+ int32_t max_block_length;
+ LV2_Options_Option host_options[2];
+ LV2_Feature options_feature;
LV2_Atom_Sequence seq_in[2];
LV2_Atom_Sequence *seq_out;
- const LV2_Feature *features[6];
+ const LV2_Feature *features[7];
float *mins;
float *maxes;
@@ -285,7 +289,8 @@ static int config_output(AVFilterLink *outlink)
s->features[2] = &buf_size_features[0];
s->features[3] = &buf_size_features[1];
s->features[4] = &buf_size_features[2];
- s->features[5] = NULL;
+ s->features[5] = &s->options_feature;
+ s->features[6] = NULL;
if (ctx->nb_inputs) {
AVFilterLink *inlink = ctx->inputs[0];
@@ -304,12 +309,30 @@ static int config_output(AVFilterLink *outlink)
FilterLink *inl = ff_filter_link(inlink);
inl->min_samples = inl->max_samples = 4096;
+ s->max_block_length = inl->max_samples;
}
} else {
outlink->sample_rate = sample_rate = s->sample_rate;
outlink->time_base = (AVRational){1, s->sample_rate};
+ s->max_block_length = s->nb_samples;
}
+ int nb_options = 0;
+ if (s->max_block_length) {
+ s->host_options[nb_options++] = (LV2_Options_Option) {
+ LV2_OPTIONS_INSTANCE, 0,
+ uri_table_map(&s->uri_table, LV2_BUF_SIZE__maxBlockLength),
+ sizeof(s->max_block_length),
+ uri_table_map(&s->uri_table, LV2_ATOM__Int),
+ &s->max_block_length
+ };
+ }
+ s->host_options[nb_options] = (LV2_Options_Option) {
+ LV2_OPTIONS_INSTANCE, 0, 0, 0, 0, NULL
+ };
+ s->options_feature.URI = LV2_OPTIONS__options;
+ s->options_feature.data = s->host_options;
+
s->instance = lilv_plugin_instantiate(s->plugin, sample_rate, s->features);
if (!s->instance) {
av_log(ctx, AV_LOG_ERROR, "Failed to instantiate <%s>\n", lilv_node_as_uri(lilv_plugin_get_uri(s->plugin)));