• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013 Paul B Mahol
3  * Copyright (c) 2011 Mina Nagy Zaki
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 /**
23  * @file
24  * LADSPA wrapper
25  */
26 
27 #include <dlfcn.h>
28 #include <ladspa.h>
29 #include "libavutil/avassert.h"
30 #include "libavutil/avstring.h"
31 #include "libavutil/channel_layout.h"
32 #include "libavutil/fifo.h"
33 #include "libavutil/opt.h"
34 #include "audio.h"
35 #include "avfilter.h"
36 #include "internal.h"
37 
38 typedef struct MetaItem {
39     int64_t pts;
40     int nb_samples;
41 } MetaItem;
42 
43 typedef struct LADSPAContext {
44     const AVClass *class;
45     char *dl_name;
46     char *plugin;
47     char *options;
48     void *dl_handle;
49 
50     unsigned long nb_inputs;
51     unsigned long *ipmap;      /* map input number to port number */
52 
53     unsigned long nb_inputcontrols;
54     unsigned long *icmap;      /* map input control number to port number */
55     LADSPA_Data *ictlv;        /* input controls values */
56 
57     unsigned long nb_outputs;
58     unsigned long *opmap;      /* map output number to port number */
59 
60     unsigned long nb_outputcontrols;
61     unsigned long *ocmap;      /* map output control number to port number */
62     LADSPA_Data *octlv;        /* output controls values */
63 
64     const LADSPA_Descriptor *desc;
65     int *ctl_needs_value;
66     int nb_handles;
67     LADSPA_Handle *handles;
68 
69     int sample_rate;
70     int nb_samples;
71     int64_t next_in_pts;
72     int64_t next_out_pts;
73     int64_t pts;
74     int64_t duration;
75     int in_trim;
76     int out_pad;
77     int latency;
78 
79     AVFifo *fifo;
80 } LADSPAContext;
81 
82 #define OFFSET(x) offsetof(LADSPAContext, x)
83 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_FILTERING_PARAM
84 static const AVOption ladspa_options[] = {
85     { "file", "set library name or full path", OFFSET(dl_name), AV_OPT_TYPE_STRING, .flags = FLAGS },
86     { "f",    "set library name or full path", OFFSET(dl_name), AV_OPT_TYPE_STRING, .flags = FLAGS },
87     { "plugin", "set plugin name", OFFSET(plugin), AV_OPT_TYPE_STRING, .flags = FLAGS },
88     { "p",      "set plugin name", OFFSET(plugin), AV_OPT_TYPE_STRING, .flags = FLAGS },
89     { "controls", "set plugin options", OFFSET(options), AV_OPT_TYPE_STRING, .flags = FLAGS },
90     { "c",        "set plugin options", OFFSET(options), AV_OPT_TYPE_STRING, .flags = FLAGS },
91     { "sample_rate", "set sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64=44100}, 1, INT32_MAX, FLAGS },
92     { "s",           "set sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64=44100}, 1, INT32_MAX, FLAGS },
93     { "nb_samples", "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64=1024}, 1, INT_MAX, FLAGS },
94     { "n",          "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64=1024}, 1, INT_MAX, FLAGS },
95     { "duration", "set audio duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64=-1}, -1, INT64_MAX, FLAGS },
96     { "d",        "set audio duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64=-1}, -1, INT64_MAX, FLAGS },
97     { "latency", "enable latency compensation", OFFSET(latency), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS },
98     { "l",       "enable latency compensation", OFFSET(latency), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS },
99     { NULL }
100 };
101 
102 AVFILTER_DEFINE_CLASS(ladspa);
103 
find_latency(AVFilterContext * ctx,LADSPAContext * s)104 static int find_latency(AVFilterContext *ctx, LADSPAContext *s)
105 {
106     int latency = 0;
107 
108     for (int ctl = 0; ctl < s->nb_outputcontrols; ctl++) {
109         if (av_strcasecmp("latency", s->desc->PortNames[s->ocmap[ctl]]))
110             continue;
111 
112         latency = lrintf(s->octlv[ctl]);
113         break;
114     }
115 
116     return latency;
117 }
118 
print_ctl_info(AVFilterContext * ctx,int level,LADSPAContext * s,int ctl,unsigned long * map,LADSPA_Data * values,int print)119 static void print_ctl_info(AVFilterContext *ctx, int level,
120                            LADSPAContext *s, int ctl, unsigned long *map,
121                            LADSPA_Data *values, int print)
122 {
123     const LADSPA_PortRangeHint *h = s->desc->PortRangeHints + map[ctl];
124 
125     av_log(ctx, level, "c%i: %s [", ctl, s->desc->PortNames[map[ctl]]);
126 
127     if (LADSPA_IS_HINT_TOGGLED(h->HintDescriptor)) {
128         av_log(ctx, level, "toggled (1 or 0)");
129 
130         if (LADSPA_IS_HINT_HAS_DEFAULT(h->HintDescriptor))
131             av_log(ctx, level, " (default %i)", (int)values[ctl]);
132     } else {
133         if (LADSPA_IS_HINT_INTEGER(h->HintDescriptor)) {
134             av_log(ctx, level, "<int>");
135 
136             if (LADSPA_IS_HINT_BOUNDED_BELOW(h->HintDescriptor))
137                 av_log(ctx, level, ", min: %i", (int)h->LowerBound);
138 
139             if (LADSPA_IS_HINT_BOUNDED_ABOVE(h->HintDescriptor))
140                 av_log(ctx, level, ", max: %i", (int)h->UpperBound);
141 
142             if (print)
143                 av_log(ctx, level, " (value %d)", (int)values[ctl]);
144             else if (LADSPA_IS_HINT_HAS_DEFAULT(h->HintDescriptor))
145                 av_log(ctx, level, " (default %d)", (int)values[ctl]);
146         } else {
147             av_log(ctx, level, "<float>");
148 
149             if (LADSPA_IS_HINT_BOUNDED_BELOW(h->HintDescriptor))
150                 av_log(ctx, level, ", min: %f", h->LowerBound);
151 
152             if (LADSPA_IS_HINT_BOUNDED_ABOVE(h->HintDescriptor))
153                 av_log(ctx, level, ", max: %f", h->UpperBound);
154 
155             if (print)
156                 av_log(ctx, level, " (value %f)", values[ctl]);
157             else if (LADSPA_IS_HINT_HAS_DEFAULT(h->HintDescriptor))
158                 av_log(ctx, level, " (default %f)", values[ctl]);
159         }
160 
161         if (LADSPA_IS_HINT_SAMPLE_RATE(h->HintDescriptor))
162             av_log(ctx, level, ", multiple of sample rate");
163 
164         if (LADSPA_IS_HINT_LOGARITHMIC(h->HintDescriptor))
165             av_log(ctx, level, ", logarithmic scale");
166     }
167 
168     av_log(ctx, level, "]\n");
169 }
170 
filter_frame(AVFilterLink * inlink,AVFrame * in)171 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
172 {
173     AVFilterContext *ctx = inlink->dst;
174     LADSPAContext *s = ctx->priv;
175     AVFrame *out;
176     int i, h, p, new_out_samples;
177     int64_t out_duration;
178     int64_t in_duration;
179     int64_t in_pts;
180     MetaItem meta;
181 
182     av_assert0(in->ch_layout.nb_channels == (s->nb_inputs * s->nb_handles));
183 
184     if (!s->nb_outputs ||
185         (av_frame_is_writable(in) && s->nb_inputs == s->nb_outputs &&
186          s->in_trim == 0 && s->out_pad == 0 &&
187         !(s->desc->Properties & LADSPA_PROPERTY_INPLACE_BROKEN))) {
188         out = in;
189     } else {
190         out = ff_get_audio_buffer(ctx->outputs[0], in->nb_samples);
191         if (!out) {
192             av_frame_free(&in);
193             return AVERROR(ENOMEM);
194         }
195         av_frame_copy_props(out, in);
196     }
197 
198     av_assert0(!s->nb_outputs || out->ch_layout.nb_channels == (s->nb_outputs * s->nb_handles));
199 
200     for (h = 0; h < s->nb_handles; h++) {
201         for (i = 0; i < s->nb_inputs; i++) {
202             p = s->nb_handles > 1 ? h : i;
203             s->desc->connect_port(s->handles[h], s->ipmap[i],
204                                   (LADSPA_Data*)in->extended_data[p]);
205         }
206 
207         for (i = 0; i < s->nb_outputs; i++) {
208             p = s->nb_handles > 1 ? h : i;
209             s->desc->connect_port(s->handles[h], s->opmap[i],
210                                   (LADSPA_Data*)out->extended_data[p]);
211         }
212 
213         s->desc->run(s->handles[h], in->nb_samples);
214         if (s->latency)
215             s->in_trim = s->out_pad = find_latency(ctx, s);
216         s->latency = 0;
217     }
218 
219     for (i = 0; i < s->nb_outputcontrols; i++)
220         print_ctl_info(ctx, AV_LOG_VERBOSE, s, i, s->ocmap, s->octlv, 1);
221 
222     meta = (MetaItem){ in->pts, in->nb_samples };
223     av_fifo_write(s->fifo, &meta, 1);
224 
225     if (out != in)
226         av_frame_free(&in);
227 
228     new_out_samples = out->nb_samples;
229     if (s->in_trim > 0) {
230         int trim = FFMIN(new_out_samples, s->in_trim);
231 
232         new_out_samples -= trim;
233         s->in_trim -= trim;
234     }
235 
236     if (new_out_samples <= 0) {
237         av_frame_free(&out);
238         return 0;
239     } else if (new_out_samples < out->nb_samples) {
240         int offset = out->nb_samples - new_out_samples;
241         for (int ch = 0; ch < out->ch_layout.nb_channels; ch++)
242             memmove(out->extended_data[ch], out->extended_data[ch] + sizeof(float) * offset,
243                     sizeof(float) * new_out_samples);
244         out->nb_samples = new_out_samples;
245     }
246 
247     av_fifo_read(s->fifo, &meta, 1);
248 
249     out_duration = av_rescale_q(out->nb_samples, inlink->time_base, av_make_q(1, out->sample_rate));
250     in_duration  = av_rescale_q(meta.nb_samples, inlink->time_base, av_make_q(1, out->sample_rate));
251     in_pts       = meta.pts;
252 
253     if (s->next_out_pts != AV_NOPTS_VALUE && out->pts != s->next_out_pts &&
254         s->next_in_pts  != AV_NOPTS_VALUE && in_pts   == s->next_in_pts) {
255         out->pts = s->next_out_pts;
256     } else {
257         out->pts = in_pts;
258     }
259     s->next_in_pts  = in_pts   + in_duration;
260     s->next_out_pts = out->pts + out_duration;
261 
262     return ff_filter_frame(ctx->outputs[0], out);
263 }
264 
request_frame(AVFilterLink * outlink)265 static int request_frame(AVFilterLink *outlink)
266 {
267     AVFilterContext *ctx = outlink->src;
268     LADSPAContext *s = ctx->priv;
269     AVFrame *out;
270     int64_t t;
271     int i;
272 
273     if (ctx->nb_inputs) {
274         int ret = ff_request_frame(ctx->inputs[0]);
275 
276         if (ret == AVERROR_EOF && s->out_pad > 0) {
277             AVFrame *frame = ff_get_audio_buffer(outlink, FFMIN(2048, s->out_pad));
278             if (!frame)
279                 return AVERROR(ENOMEM);
280 
281             s->out_pad -= frame->nb_samples;
282             frame->pts = s->next_in_pts;
283             return filter_frame(ctx->inputs[0], frame);
284         }
285         return ret;
286     }
287 
288     t = av_rescale(s->pts, AV_TIME_BASE, s->sample_rate);
289     if (s->duration >= 0 && t >= s->duration)
290         return AVERROR_EOF;
291 
292     out = ff_get_audio_buffer(outlink, s->nb_samples);
293     if (!out)
294         return AVERROR(ENOMEM);
295 
296     for (i = 0; i < s->nb_outputs; i++)
297         s->desc->connect_port(s->handles[0], s->opmap[i],
298                 (LADSPA_Data*)out->extended_data[i]);
299 
300     s->desc->run(s->handles[0], s->nb_samples);
301 
302     for (i = 0; i < s->nb_outputcontrols; i++)
303         print_ctl_info(ctx, AV_LOG_INFO, s, i, s->ocmap, s->octlv, 1);
304 
305     out->sample_rate = s->sample_rate;
306     out->pts         = s->pts;
307     s->pts          += s->nb_samples;
308 
309     return ff_filter_frame(outlink, out);
310 }
311 
set_default_ctl_value(LADSPAContext * s,int ctl,unsigned long * map,LADSPA_Data * values)312 static void set_default_ctl_value(LADSPAContext *s, int ctl,
313                                   unsigned long *map, LADSPA_Data *values)
314 {
315     const LADSPA_PortRangeHint *h = s->desc->PortRangeHints + map[ctl];
316     const LADSPA_Data lower = h->LowerBound;
317     const LADSPA_Data upper = h->UpperBound;
318 
319     if (LADSPA_IS_HINT_DEFAULT_MINIMUM(h->HintDescriptor)) {
320         values[ctl] = lower;
321     } else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(h->HintDescriptor)) {
322         values[ctl] = upper;
323     } else if (LADSPA_IS_HINT_DEFAULT_0(h->HintDescriptor)) {
324         values[ctl] = 0.0;
325     } else if (LADSPA_IS_HINT_DEFAULT_1(h->HintDescriptor)) {
326         values[ctl] = 1.0;
327     } else if (LADSPA_IS_HINT_DEFAULT_100(h->HintDescriptor)) {
328         values[ctl] = 100.0;
329     } else if (LADSPA_IS_HINT_DEFAULT_440(h->HintDescriptor)) {
330         values[ctl] = 440.0;
331     } else if (LADSPA_IS_HINT_DEFAULT_LOW(h->HintDescriptor)) {
332         if (LADSPA_IS_HINT_LOGARITHMIC(h->HintDescriptor))
333             values[ctl] = exp(log(lower) * 0.75 + log(upper) * 0.25);
334         else
335             values[ctl] = lower * 0.75 + upper * 0.25;
336     } else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(h->HintDescriptor)) {
337         if (LADSPA_IS_HINT_LOGARITHMIC(h->HintDescriptor))
338             values[ctl] = exp(log(lower) * 0.5 + log(upper) * 0.5);
339         else
340             values[ctl] = lower * 0.5 + upper * 0.5;
341     } else if (LADSPA_IS_HINT_DEFAULT_HIGH(h->HintDescriptor)) {
342         if (LADSPA_IS_HINT_LOGARITHMIC(h->HintDescriptor))
343             values[ctl] = exp(log(lower) * 0.25 + log(upper) * 0.75);
344         else
345             values[ctl] = lower * 0.25 + upper * 0.75;
346     }
347 }
348 
connect_ports(AVFilterContext * ctx,AVFilterLink * link)349 static int connect_ports(AVFilterContext *ctx, AVFilterLink *link)
350 {
351     LADSPAContext *s = ctx->priv;
352     int i, j;
353 
354     s->nb_handles = s->nb_inputs == 1 && s->nb_outputs == 1 ? link->ch_layout.nb_channels : 1;
355     s->handles    = av_calloc(s->nb_handles, sizeof(*s->handles));
356     if (!s->handles)
357         return AVERROR(ENOMEM);
358 
359     for (i = 0; i < s->nb_handles; i++) {
360         s->handles[i] = s->desc->instantiate(s->desc, link->sample_rate);
361         if (!s->handles[i]) {
362             av_log(ctx, AV_LOG_ERROR, "Could not instantiate plugin.\n");
363             return AVERROR_EXTERNAL;
364         }
365 
366         // Connect the input control ports
367         for (j = 0; j < s->nb_inputcontrols; j++)
368             s->desc->connect_port(s->handles[i], s->icmap[j], s->ictlv + j);
369 
370         // Connect the output control ports
371         for (j = 0; j < s->nb_outputcontrols; j++)
372             s->desc->connect_port(s->handles[i], s->ocmap[j], &s->octlv[j]);
373 
374         if (s->desc->activate)
375             s->desc->activate(s->handles[i]);
376     }
377 
378     av_log(ctx, AV_LOG_DEBUG, "handles: %d\n", s->nb_handles);
379 
380     return 0;
381 }
382 
config_input(AVFilterLink * inlink)383 static int config_input(AVFilterLink *inlink)
384 {
385     AVFilterContext *ctx = inlink->dst;
386 
387     return connect_ports(ctx, inlink);
388 }
389 
config_output(AVFilterLink * outlink)390 static int config_output(AVFilterLink *outlink)
391 {
392     AVFilterContext *ctx = outlink->src;
393     LADSPAContext *s = ctx->priv;
394     int ret;
395 
396     if (ctx->nb_inputs) {
397         AVFilterLink *inlink = ctx->inputs[0];
398 
399         outlink->format      = inlink->format;
400         outlink->sample_rate = inlink->sample_rate;
401         if (s->nb_inputs == s->nb_outputs) {
402             if ((ret = av_channel_layout_copy(&outlink->ch_layout, &inlink->ch_layout)) < 0)
403                 return ret;
404 #if FF_API_OLD_CHANNEL_LAYOUT
405 FF_DISABLE_DEPRECATION_WARNINGS
406             outlink->channel_layout = inlink->channel_layout;
407 FF_ENABLE_DEPRECATION_WARNINGS
408 #endif
409         }
410 
411         ret = 0;
412     } else {
413         outlink->sample_rate = s->sample_rate;
414         outlink->time_base   = (AVRational){1, s->sample_rate};
415 
416         ret = connect_ports(ctx, outlink);
417     }
418 
419     return ret;
420 }
421 
count_ports(const LADSPA_Descriptor * desc,unsigned long * nb_inputs,unsigned long * nb_outputs)422 static void count_ports(const LADSPA_Descriptor *desc,
423                         unsigned long *nb_inputs, unsigned long *nb_outputs)
424 {
425     LADSPA_PortDescriptor pd;
426     int i;
427 
428     for (i = 0; i < desc->PortCount; i++) {
429         pd = desc->PortDescriptors[i];
430 
431         if (LADSPA_IS_PORT_AUDIO(pd)) {
432             if (LADSPA_IS_PORT_INPUT(pd)) {
433                 (*nb_inputs)++;
434             } else if (LADSPA_IS_PORT_OUTPUT(pd)) {
435                 (*nb_outputs)++;
436             }
437         }
438     }
439 }
440 
try_load(const char * dir,const char * soname)441 static void *try_load(const char *dir, const char *soname)
442 {
443     char *path = av_asprintf("%s/%s.so", dir, soname);
444     void *ret = NULL;
445 
446     if (path) {
447         ret = dlopen(path, RTLD_LOCAL|RTLD_NOW);
448         av_free(path);
449     }
450 
451     return ret;
452 }
453 
set_control(AVFilterContext * ctx,unsigned long port,LADSPA_Data value)454 static int set_control(AVFilterContext *ctx, unsigned long port, LADSPA_Data value)
455 {
456     LADSPAContext *s = ctx->priv;
457     const char *label = s->desc->Label;
458     LADSPA_PortRangeHint *h = (LADSPA_PortRangeHint *)s->desc->PortRangeHints +
459                               s->icmap[port];
460 
461     if (port >= s->nb_inputcontrols) {
462         av_log(ctx, AV_LOG_ERROR, "Control c%ld is out of range [0 - %lu].\n",
463                port, s->nb_inputcontrols);
464         return AVERROR(EINVAL);
465     }
466 
467     if (LADSPA_IS_HINT_BOUNDED_BELOW(h->HintDescriptor) &&
468             value < h->LowerBound) {
469         av_log(ctx, AV_LOG_ERROR,
470                 "%s: input control c%ld is below lower boundary of %0.4f.\n",
471                 label, port, h->LowerBound);
472         return AVERROR(EINVAL);
473     }
474 
475     if (LADSPA_IS_HINT_BOUNDED_ABOVE(h->HintDescriptor) &&
476             value > h->UpperBound) {
477         av_log(ctx, AV_LOG_ERROR,
478                 "%s: input control c%ld is above upper boundary of %0.4f.\n",
479                 label, port, h->UpperBound);
480         return AVERROR(EINVAL);
481     }
482 
483     s->ictlv[port] = value;
484 
485     return 0;
486 }
487 
init(AVFilterContext * ctx)488 static av_cold int init(AVFilterContext *ctx)
489 {
490     LADSPAContext *s = ctx->priv;
491     LADSPA_Descriptor_Function descriptor_fn;
492     const LADSPA_Descriptor *desc;
493     LADSPA_PortDescriptor pd;
494     AVFilterPad pad = { NULL };
495     char *p, *arg, *saveptr = NULL;
496     unsigned long nb_ports;
497     int i, j = 0, ret;
498 
499     if (!s->dl_name) {
500         av_log(ctx, AV_LOG_ERROR, "No plugin name provided\n");
501         return AVERROR(EINVAL);
502     }
503 
504     if (s->dl_name[0] == '/' || s->dl_name[0] == '.') {
505         // argument is a path
506         s->dl_handle = dlopen(s->dl_name, RTLD_LOCAL|RTLD_NOW);
507     } else {
508         // argument is a shared object name
509         char *paths = av_strdup(getenv("LADSPA_PATH"));
510         const char *home_path = getenv("HOME");
511         const char *separator = ":";
512 
513         if (paths) {
514             p = paths;
515             while ((arg = av_strtok(p, separator, &saveptr)) && !s->dl_handle) {
516                 s->dl_handle = try_load(arg, s->dl_name);
517                 p = NULL;
518             }
519         }
520 
521         av_free(paths);
522         if (!s->dl_handle && home_path && (paths = av_asprintf("%s/.ladspa", home_path))) {
523             s->dl_handle = try_load(paths, s->dl_name);
524             av_free(paths);
525         }
526 
527         if (!s->dl_handle && home_path && (paths = av_asprintf("%s/.ladspa/lib", home_path))) {
528             s->dl_handle = try_load(paths, s->dl_name);
529             av_free(paths);
530         }
531 
532         if (!s->dl_handle)
533             s->dl_handle = try_load("/usr/local/lib/ladspa", s->dl_name);
534 
535         if (!s->dl_handle)
536             s->dl_handle = try_load("/usr/lib/ladspa", s->dl_name);
537     }
538     if (!s->dl_handle) {
539         av_log(ctx, AV_LOG_ERROR, "Failed to load '%s'\n", s->dl_name);
540         return AVERROR(EINVAL);
541     }
542 
543     descriptor_fn = dlsym(s->dl_handle, "ladspa_descriptor");
544     if (!descriptor_fn) {
545         av_log(ctx, AV_LOG_ERROR, "Could not find ladspa_descriptor: %s\n", dlerror());
546         return AVERROR(EINVAL);
547     }
548 
549     // Find the requested plugin, or list plugins
550     if (!s->plugin) {
551         av_log(ctx, AV_LOG_INFO, "The '%s' library contains the following plugins:\n", s->dl_name);
552         av_log(ctx, AV_LOG_INFO, "I = Input Channels\n");
553         av_log(ctx, AV_LOG_INFO, "O = Output Channels\n");
554         av_log(ctx, AV_LOG_INFO, "I:O %-25s %s\n", "Plugin", "Description");
555         av_log(ctx, AV_LOG_INFO, "\n");
556         for (i = 0; desc = descriptor_fn(i); i++) {
557             unsigned long inputs = 0, outputs = 0;
558 
559             count_ports(desc, &inputs, &outputs);
560             av_log(ctx, AV_LOG_INFO, "%lu:%lu %-25s %s\n", inputs, outputs, desc->Label,
561                    (char *)av_x_if_null(desc->Name, "?"));
562             av_log(ctx, AV_LOG_VERBOSE, "Maker: %s\n",
563                    (char *)av_x_if_null(desc->Maker, "?"));
564             av_log(ctx, AV_LOG_VERBOSE, "Copyright: %s\n",
565                    (char *)av_x_if_null(desc->Copyright, "?"));
566         }
567         return AVERROR_EXIT;
568     } else {
569         for (i = 0;; i++) {
570             desc = descriptor_fn(i);
571             if (!desc) {
572                 av_log(ctx, AV_LOG_ERROR, "Could not find plugin: %s\n", s->plugin);
573                 return AVERROR(EINVAL);
574             }
575 
576             if (desc->Label && !strcmp(desc->Label, s->plugin))
577                 break;
578         }
579     }
580 
581     s->desc  = desc;
582     nb_ports = desc->PortCount;
583 
584     s->ipmap = av_calloc(nb_ports, sizeof(*s->ipmap));
585     s->opmap = av_calloc(nb_ports, sizeof(*s->opmap));
586     s->icmap = av_calloc(nb_ports, sizeof(*s->icmap));
587     s->ocmap = av_calloc(nb_ports, sizeof(*s->ocmap));
588     s->ictlv = av_calloc(nb_ports, sizeof(*s->ictlv));
589     s->octlv = av_calloc(nb_ports, sizeof(*s->octlv));
590     s->ctl_needs_value = av_calloc(nb_ports, sizeof(*s->ctl_needs_value));
591     if (!s->ipmap || !s->opmap || !s->icmap ||
592         !s->ocmap || !s->ictlv || !s->octlv || !s->ctl_needs_value)
593         return AVERROR(ENOMEM);
594 
595     for (i = 0; i < nb_ports; i++) {
596         pd = desc->PortDescriptors[i];
597 
598         if (LADSPA_IS_PORT_AUDIO(pd)) {
599             if (LADSPA_IS_PORT_INPUT(pd)) {
600                 s->ipmap[s->nb_inputs] = i;
601                 s->nb_inputs++;
602             } else if (LADSPA_IS_PORT_OUTPUT(pd)) {
603                 s->opmap[s->nb_outputs] = i;
604                 s->nb_outputs++;
605             }
606         } else if (LADSPA_IS_PORT_CONTROL(pd)) {
607             if (LADSPA_IS_PORT_INPUT(pd)) {
608                 s->icmap[s->nb_inputcontrols] = i;
609 
610                 if (LADSPA_IS_HINT_HAS_DEFAULT(desc->PortRangeHints[i].HintDescriptor))
611                     set_default_ctl_value(s, s->nb_inputcontrols, s->icmap, s->ictlv);
612                 else
613                     s->ctl_needs_value[s->nb_inputcontrols] = 1;
614 
615                 s->nb_inputcontrols++;
616             } else if (LADSPA_IS_PORT_OUTPUT(pd)) {
617                 s->ocmap[s->nb_outputcontrols] = i;
618                 s->nb_outputcontrols++;
619             }
620         }
621     }
622 
623     // List Control Ports if "help" is specified
624     if (s->options && !strcmp(s->options, "help")) {
625         if (!s->nb_inputcontrols) {
626             av_log(ctx, AV_LOG_INFO,
627                    "The '%s' plugin does not have any input controls.\n",
628                    desc->Label);
629         } else {
630             av_log(ctx, AV_LOG_INFO,
631                    "The '%s' plugin has the following input controls:\n",
632                    desc->Label);
633             for (i = 0; i < s->nb_inputcontrols; i++)
634                 print_ctl_info(ctx, AV_LOG_INFO, s, i, s->icmap, s->ictlv, 0);
635         }
636         return AVERROR_EXIT;
637     }
638 
639     // Parse control parameters
640     p = s->options;
641     while (s->options) {
642         LADSPA_Data val;
643         int ret;
644 
645         if (!(arg = av_strtok(p, " |", &saveptr)))
646             break;
647         p = NULL;
648 
649         if (av_sscanf(arg, "c%d=%f", &i, &val) != 2) {
650             if (av_sscanf(arg, "%f", &val) != 1) {
651                 av_log(ctx, AV_LOG_ERROR, "Invalid syntax.\n");
652                 return AVERROR(EINVAL);
653             }
654             i = j++;
655         }
656 
657         if ((ret = set_control(ctx, i, val)) < 0)
658             return ret;
659         s->ctl_needs_value[i] = 0;
660     }
661 
662     // Check if any controls are not set
663     for (i = 0; i < s->nb_inputcontrols; i++) {
664         if (s->ctl_needs_value[i]) {
665             av_log(ctx, AV_LOG_ERROR, "Control c%d must be set.\n", i);
666             print_ctl_info(ctx, AV_LOG_ERROR, s, i, s->icmap, s->ictlv, 0);
667             return AVERROR(EINVAL);
668         }
669     }
670 
671     pad.type = AVMEDIA_TYPE_AUDIO;
672 
673     if (s->nb_inputs) {
674         pad.name = av_asprintf("in0:%s%lu", desc->Label, s->nb_inputs);
675         if (!pad.name)
676             return AVERROR(ENOMEM);
677 
678         pad.filter_frame = filter_frame;
679         pad.config_props = config_input;
680         if ((ret = ff_append_inpad_free_name(ctx, &pad)) < 0)
681             return ret;
682     }
683 
684     av_log(ctx, AV_LOG_DEBUG, "ports: %lu\n", nb_ports);
685     av_log(ctx, AV_LOG_DEBUG, "inputs: %lu outputs: %lu\n",
686                               s->nb_inputs, s->nb_outputs);
687     av_log(ctx, AV_LOG_DEBUG, "input controls: %lu output controls: %lu\n",
688                               s->nb_inputcontrols, s->nb_outputcontrols);
689 
690     s->next_out_pts = AV_NOPTS_VALUE;
691     s->next_in_pts  = AV_NOPTS_VALUE;
692 
693     s->fifo = av_fifo_alloc2(8, sizeof(MetaItem), AV_FIFO_FLAG_AUTO_GROW);
694     if (!s->fifo)
695         return AVERROR(ENOMEM);
696 
697     return 0;
698 }
699 
query_formats(AVFilterContext * ctx)700 static int query_formats(AVFilterContext *ctx)
701 {
702     LADSPAContext *s = ctx->priv;
703     AVFilterChannelLayouts *layouts;
704     static const enum AVSampleFormat sample_fmts[] = {
705         AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE };
706     int ret = ff_set_common_formats_from_list(ctx, sample_fmts);
707     if (ret < 0)
708         return ret;
709 
710     if (s->nb_inputs) {
711         ret = ff_set_common_all_samplerates(ctx);
712         if (ret < 0)
713             return ret;
714     } else {
715         int sample_rates[] = { s->sample_rate, -1 };
716 
717         ret = ff_set_common_samplerates_from_list(ctx, sample_rates);
718         if (ret < 0)
719             return ret;
720     }
721 
722     if (s->nb_inputs == 1 && s->nb_outputs == 1) {
723         // We will instantiate multiple LADSPA_Handle, one over each channel
724         ret = ff_set_common_all_channel_counts(ctx);
725         if (ret < 0)
726             return ret;
727     } else if (s->nb_inputs == 2 && s->nb_outputs == 2) {
728         layouts = NULL;
729         ret = ff_add_channel_layout(&layouts, &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO);
730         if (ret < 0)
731             return ret;
732         ret = ff_set_common_channel_layouts(ctx, layouts);
733         if (ret < 0)
734             return ret;
735     } else {
736         AVFilterLink *outlink = ctx->outputs[0];
737 
738         if (s->nb_inputs >= 1) {
739             AVFilterLink *inlink = ctx->inputs[0];
740             AVChannelLayout inlayout = FF_COUNT2LAYOUT(s->nb_inputs);
741 
742             layouts = NULL;
743             ret = ff_add_channel_layout(&layouts, &inlayout);
744             if (ret < 0)
745                 return ret;
746             ret = ff_channel_layouts_ref(layouts, &inlink->outcfg.channel_layouts);
747             if (ret < 0)
748                 return ret;
749 
750             if (!s->nb_outputs) {
751                 ret = ff_channel_layouts_ref(layouts, &outlink->incfg.channel_layouts);
752                 if (ret < 0)
753                     return ret;
754             }
755         }
756 
757         if (s->nb_outputs >= 1) {
758             AVChannelLayout outlayout = FF_COUNT2LAYOUT(s->nb_outputs);
759 
760             layouts = NULL;
761             ret = ff_add_channel_layout(&layouts, &outlayout);
762             if (ret < 0)
763                 return ret;
764             ret = ff_channel_layouts_ref(layouts, &outlink->incfg.channel_layouts);
765             if (ret < 0)
766                 return ret;
767         }
768     }
769 
770     return 0;
771 }
772 
uninit(AVFilterContext * ctx)773 static av_cold void uninit(AVFilterContext *ctx)
774 {
775     LADSPAContext *s = ctx->priv;
776     int i;
777 
778     for (i = 0; i < s->nb_handles; i++) {
779         if (s->desc->deactivate)
780             s->desc->deactivate(s->handles[i]);
781         if (s->desc->cleanup)
782             s->desc->cleanup(s->handles[i]);
783     }
784 
785     if (s->dl_handle)
786         dlclose(s->dl_handle);
787 
788     av_freep(&s->ipmap);
789     av_freep(&s->opmap);
790     av_freep(&s->icmap);
791     av_freep(&s->ocmap);
792     av_freep(&s->ictlv);
793     av_freep(&s->octlv);
794     av_freep(&s->handles);
795     av_freep(&s->ctl_needs_value);
796 
797     av_fifo_freep2(&s->fifo);
798 }
799 
process_command(AVFilterContext * ctx,const char * cmd,const char * args,char * res,int res_len,int flags)800 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
801                            char *res, int res_len, int flags)
802 {
803     LADSPA_Data value;
804     unsigned long port;
805 
806     if (av_sscanf(cmd, "c%ld", &port) + av_sscanf(args, "%f", &value) != 2)
807         return AVERROR(EINVAL);
808 
809     return set_control(ctx, port, value);
810 }
811 
812 static const AVFilterPad ladspa_outputs[] = {
813     {
814         .name          = "default",
815         .type          = AVMEDIA_TYPE_AUDIO,
816         .config_props  = config_output,
817         .request_frame = request_frame,
818     },
819 };
820 
821 const AVFilter ff_af_ladspa = {
822     .name          = "ladspa",
823     .description   = NULL_IF_CONFIG_SMALL("Apply LADSPA effect."),
824     .priv_size     = sizeof(LADSPAContext),
825     .priv_class    = &ladspa_class,
826     .init          = init,
827     .uninit        = uninit,
828     .process_command = process_command,
829     .inputs        = 0,
830     FILTER_OUTPUTS(ladspa_outputs),
831     FILTER_QUERY_FUNC(query_formats),
832     .flags         = AVFILTER_FLAG_DYNAMIC_INPUTS,
833 };
834