PR #24947 opened by Ramiro Polla (ramiro)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24947
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24947.patch

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 <[email protected]>



>From 20d970397d35053e9a459ec94d4967bd831fafce Mon Sep 17 00:00:00 2001
From: Ramiro Polla <[email protected]>
Date: Thu, 8 Oct 2026 14:45:26 +0200
Subject: [PATCH 1/3] avfilter/af_lv2: NULL-terminate array of features the
 host supports

The documentation for lilv_plugin_instantiate() specifies that the array
of features the host supports should be NULL-terminated.
---
 libavfilter/af_lv2.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libavfilter/af_lv2.c b/libavfilter/af_lv2.c
index c34f6eb30c..cd30e7ac28 100644
--- a/libavfilter/af_lv2.c
+++ b/libavfilter/af_lv2.c
@@ -67,7 +67,7 @@ typedef struct LV2Context {
     LV2_Feature        unmap_feature;
     LV2_Atom_Sequence  seq_in[2];
     LV2_Atom_Sequence *seq_out;
-    const LV2_Feature *features[5];
+    const LV2_Feature *features[6];
 
     float *mins;
     float *maxes;
@@ -285,6 +285,7 @@ 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;
 
     if (ctx->nb_inputs) {
         AVFilterLink *inlink = ctx->inputs[0];
-- 
2.52.0


>From 8e4a6bf2c1acbe3d5233734894612f64dc6378c3 Mon Sep 17 00:00:00 2001
From: Ramiro Polla <[email protected]>
Date: Thu, 8 Oct 2026 16:25:03 +0200
Subject: [PATCH 2/3] avfilter/af_lv2: move the bounded block check earlier in
 config_output()

This will simplify the following commit.
---
 libavfilter/af_lv2.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/libavfilter/af_lv2.c b/libavfilter/af_lv2.c
index cd30e7ac28..e9375b2881 100644
--- a/libavfilter/af_lv2.c
+++ b/libavfilter/af_lv2.c
@@ -298,6 +298,13 @@ static int config_output(AVFilterLink *outlink)
                 return ret;
         }
 
+        if (lilv_plugin_has_feature(s->plugin, s->powerOf2BlockLength) ||
+            lilv_plugin_has_feature(s->plugin, s->fixedBlockLength) ||
+            lilv_plugin_has_feature(s->plugin, s->boundedBlockLength)) {
+            FilterLink *inl = ff_filter_link(inlink);
+
+            inl->min_samples = inl->max_samples = 4096;
+        }
     } else {
         outlink->sample_rate = sample_rate = s->sample_rate;
         outlink->time_base   = (AVRational){1, s->sample_rate};
@@ -380,15 +387,6 @@ static int config_output(AVFilterLink *outlink)
         }
     }
 
-    if (s->nb_inputs &&
-        (lilv_plugin_has_feature(s->plugin, s->powerOf2BlockLength) ||
-         lilv_plugin_has_feature(s->plugin, s->fixedBlockLength) ||
-         lilv_plugin_has_feature(s->plugin, s->boundedBlockLength))) {
-        FilterLink *inlink = ff_filter_link(ctx->inputs[0]);
-
-        inlink->min_samples = inlink->max_samples = 4096;
-    }
-
     lilv_instance_activate(s->instance);
     s->instance_activated = 1;
 
-- 
2.52.0


>From d4a3ea11ebdbbdf31b3ab8b16ea0ee9e3aa8a611 Mon Sep 17 00:00:00 2001
From: Ramiro Polla <[email protected]>
Date: Thu, 8 Oct 2026 16:25:03 +0200
Subject: [PATCH 3/3] 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 <[email protected]>
---
 libavfilter/af_lv2.c | 27 +++++++++++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)

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)));
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to