2 * Copyright (c) 2013 Paul B Mahol
3 * Copyright (c) 2011 Mina Nagy Zaki
5 * This file is part of FFmpeg.
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.
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.
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
29 #include "libavutil/avstring.h"
30 #include "libavutil/channel_layout.h"
31 #include "libavutil/opt.h"
36 typedef struct LADSPAContext
{
43 unsigned long nb_inputs
;
44 unsigned long *ipmap
; /* map input number to port number */
46 unsigned long nb_inputcontrols
;
47 unsigned long *icmap
; /* map input control number to port number */
48 LADSPA_Data
*ictlv
; /* input controls values */
50 unsigned long nb_outputs
;
51 unsigned long *opmap
; /* map output number to port number */
53 unsigned long nb_outputcontrols
;
54 unsigned long *ocmap
; /* map output control number to port number */
55 LADSPA_Data
*octlv
; /* output controls values */
57 const LADSPA_Descriptor
*desc
;
60 LADSPA_Handle
*handles
;
68 #define OFFSET(x) offsetof(LADSPAContext, x)
69 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_FILTERING_PARAM
70 static const AVOption ladspa_options
[] = {
71 { "file", "set library name or full path", OFFSET(dl_name
), AV_OPT_TYPE_STRING
, .flags
= FLAGS
},
72 { "f", "set library name or full path", OFFSET(dl_name
), AV_OPT_TYPE_STRING
, .flags
= FLAGS
},
73 { "plugin", "set plugin name", OFFSET(plugin
), AV_OPT_TYPE_STRING
, .flags
= FLAGS
},
74 { "p", "set plugin name", OFFSET(plugin
), AV_OPT_TYPE_STRING
, .flags
= FLAGS
},
75 { "controls", "set plugin options", OFFSET(options
), AV_OPT_TYPE_STRING
, .flags
= FLAGS
},
76 { "c", "set plugin options", OFFSET(options
), AV_OPT_TYPE_STRING
, .flags
= FLAGS
},
77 { "sample_rate", "set sample rate", OFFSET(sample_rate
), AV_OPT_TYPE_INT
, {.i64
=44100}, 1, INT32_MAX
, FLAGS
},
78 { "s", "set sample rate", OFFSET(sample_rate
), AV_OPT_TYPE_INT
, {.i64
=44100}, 1, INT32_MAX
, FLAGS
},
79 { "nb_samples", "set the number of samples per requested frame", OFFSET(nb_samples
), AV_OPT_TYPE_INT
, {.i64
=1024}, 1, INT_MAX
, FLAGS
},
80 { "n", "set the number of samples per requested frame", OFFSET(nb_samples
), AV_OPT_TYPE_INT
, {.i64
=1024}, 1, INT_MAX
, FLAGS
},
81 { "duration", "set audio duration", OFFSET(duration
), AV_OPT_TYPE_DURATION
, {.i64
=-1}, -1, INT64_MAX
, FLAGS
},
82 { "d", "set audio duration", OFFSET(duration
), AV_OPT_TYPE_DURATION
, {.i64
=-1}, -1, INT64_MAX
, FLAGS
},
86 AVFILTER_DEFINE_CLASS(ladspa
);
88 static void print_ctl_info(AVFilterContext
*ctx
, int level
,
89 LADSPAContext
*s
, int ctl
, unsigned long *map
,
90 LADSPA_Data
*values
, int print
)
92 const LADSPA_PortRangeHint
*h
= s
->desc
->PortRangeHints
+ map
[ctl
];
94 av_log(ctx
, level
, "c%i: %s [", ctl
, s
->desc
->PortNames
[map
[ctl
]]);
96 if (LADSPA_IS_HINT_TOGGLED(h
->HintDescriptor
)) {
97 av_log(ctx
, level
, "toggled (1 or 0)");
99 if (LADSPA_IS_HINT_HAS_DEFAULT(h
->HintDescriptor
))
100 av_log(ctx
, level
, " (default %i)", (int)values
[ctl
]);
102 if (LADSPA_IS_HINT_INTEGER(h
->HintDescriptor
)) {
103 av_log(ctx
, level
, "<int>");
105 if (LADSPA_IS_HINT_BOUNDED_BELOW(h
->HintDescriptor
))
106 av_log(ctx
, level
, ", min: %i", (int)h
->LowerBound
);
108 if (LADSPA_IS_HINT_BOUNDED_ABOVE(h
->HintDescriptor
))
109 av_log(ctx
, level
, ", max: %i", (int)h
->UpperBound
);
112 av_log(ctx
, level
, " (value %d)", (int)values
[ctl
]);
113 else if (LADSPA_IS_HINT_HAS_DEFAULT(h
->HintDescriptor
))
114 av_log(ctx
, level
, " (default %d)", (int)values
[ctl
]);
116 av_log(ctx
, level
, "<float>");
118 if (LADSPA_IS_HINT_BOUNDED_BELOW(h
->HintDescriptor
))
119 av_log(ctx
, level
, ", min: %f", h
->LowerBound
);
121 if (LADSPA_IS_HINT_BOUNDED_ABOVE(h
->HintDescriptor
))
122 av_log(ctx
, level
, ", max: %f", h
->UpperBound
);
125 av_log(ctx
, level
, " (value %f)", values
[ctl
]);
126 else if (LADSPA_IS_HINT_HAS_DEFAULT(h
->HintDescriptor
))
127 av_log(ctx
, level
, " (default %f)", values
[ctl
]);
130 if (LADSPA_IS_HINT_SAMPLE_RATE(h
->HintDescriptor
))
131 av_log(ctx
, level
, ", multiple of sample rate");
133 if (LADSPA_IS_HINT_LOGARITHMIC(h
->HintDescriptor
))
134 av_log(ctx
, level
, ", logarithmic scale");
137 av_log(ctx
, level
, "]\n");
140 static int filter_frame(AVFilterLink
*inlink
, AVFrame
*in
)
142 AVFilterContext
*ctx
= inlink
->dst
;
143 LADSPAContext
*s
= ctx
->priv
;
147 if (!s
->nb_outputs
||
148 (av_frame_is_writable(in
) && s
->nb_inputs
== s
->nb_outputs
&&
149 !(s
->desc
->Properties
& LADSPA_PROPERTY_INPLACE_BROKEN
))) {
152 out
= ff_get_audio_buffer(ctx
->outputs
[0], in
->nb_samples
);
155 return AVERROR(ENOMEM
);
157 av_frame_copy_props(out
, in
);
160 for (h
= 0; h
< s
->nb_handles
; h
++) {
161 for (i
= 0; i
< s
->nb_inputs
; i
++) {
162 s
->desc
->connect_port(s
->handles
[h
], s
->ipmap
[i
],
163 (LADSPA_Data
*)in
->extended_data
[i
]);
166 for (i
= 0; i
< s
->nb_outputs
; i
++) {
167 s
->desc
->connect_port(s
->handles
[h
], s
->opmap
[i
],
168 (LADSPA_Data
*)out
->extended_data
[i
]);
171 s
->desc
->run(s
->handles
[h
], in
->nb_samples
);
174 for (i
= 0; i
< s
->nb_outputcontrols
; i
++)
175 print_ctl_info(ctx
, AV_LOG_VERBOSE
, s
, i
, s
->ocmap
, s
->octlv
, 1);
180 return ff_filter_frame(ctx
->outputs
[0], out
);
183 static int request_frame(AVFilterLink
*outlink
)
185 AVFilterContext
*ctx
= outlink
->src
;
186 LADSPAContext
*s
= ctx
->priv
;
192 return ff_request_frame(ctx
->inputs
[0]);
194 t
= av_rescale(s
->pts
, AV_TIME_BASE
, s
->sample_rate
);
195 if (s
->duration
>= 0 && t
>= s
->duration
)
198 out
= ff_get_audio_buffer(outlink
, s
->nb_samples
);
200 return AVERROR(ENOMEM
);
202 for (i
= 0; i
< s
->nb_outputs
; i
++)
203 s
->desc
->connect_port(s
->handles
[0], s
->opmap
[i
],
204 (LADSPA_Data
*)out
->extended_data
[i
]);
206 s
->desc
->run(s
->handles
[0], s
->nb_samples
);
208 for (i
= 0; i
< s
->nb_outputcontrols
; i
++)
209 print_ctl_info(ctx
, AV_LOG_INFO
, s
, i
, s
->ocmap
, s
->octlv
, 1);
211 out
->sample_rate
= s
->sample_rate
;
213 s
->pts
+= s
->nb_samples
;
215 return ff_filter_frame(outlink
, out
);
218 static void set_default_ctl_value(LADSPAContext
*s
, int ctl
,
219 unsigned long *map
, LADSPA_Data
*values
)
221 const LADSPA_PortRangeHint
*h
= s
->desc
->PortRangeHints
+ map
[ctl
];
222 const LADSPA_Data lower
= h
->LowerBound
;
223 const LADSPA_Data upper
= h
->UpperBound
;
225 if (LADSPA_IS_HINT_DEFAULT_MINIMUM(h
->HintDescriptor
)) {
227 } else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(h
->HintDescriptor
)) {
229 } else if (LADSPA_IS_HINT_DEFAULT_0(h
->HintDescriptor
)) {
231 } else if (LADSPA_IS_HINT_DEFAULT_1(h
->HintDescriptor
)) {
233 } else if (LADSPA_IS_HINT_DEFAULT_100(h
->HintDescriptor
)) {
235 } else if (LADSPA_IS_HINT_DEFAULT_440(h
->HintDescriptor
)) {
237 } else if (LADSPA_IS_HINT_DEFAULT_LOW(h
->HintDescriptor
)) {
238 if (LADSPA_IS_HINT_LOGARITHMIC(h
->HintDescriptor
))
239 values
[ctl
] = exp(log(lower
) * 0.75 + log(upper
) * 0.25);
241 values
[ctl
] = lower
* 0.75 + upper
* 0.25;
242 } else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(h
->HintDescriptor
)) {
243 if (LADSPA_IS_HINT_LOGARITHMIC(h
->HintDescriptor
))
244 values
[ctl
] = exp(log(lower
) * 0.5 + log(upper
) * 0.5);
246 values
[ctl
] = lower
* 0.5 + upper
* 0.5;
247 } else if (LADSPA_IS_HINT_DEFAULT_HIGH(h
->HintDescriptor
)) {
248 if (LADSPA_IS_HINT_LOGARITHMIC(h
->HintDescriptor
))
249 values
[ctl
] = exp(log(lower
) * 0.25 + log(upper
) * 0.75);
251 values
[ctl
] = lower
* 0.25 + upper
* 0.75;
255 static int connect_ports(AVFilterContext
*ctx
, AVFilterLink
*link
)
257 LADSPAContext
*s
= ctx
->priv
;
260 s
->nb_handles
= s
->nb_inputs
== 1 && s
->nb_outputs
== 1 ? link
->channels
: 1;
261 s
->handles
= av_calloc(s
->nb_handles
, sizeof(*s
->handles
));
263 return AVERROR(ENOMEM
);
265 for (i
= 0; i
< s
->nb_handles
; i
++) {
266 s
->handles
[i
] = s
->desc
->instantiate(s
->desc
, link
->sample_rate
);
267 if (!s
->handles
[i
]) {
268 av_log(ctx
, AV_LOG_ERROR
, "Could not instantiate plugin.\n");
269 return AVERROR_EXTERNAL
;
272 // Connect the input control ports
273 for (j
= 0; j
< s
->nb_inputcontrols
; j
++)
274 s
->desc
->connect_port(s
->handles
[i
], s
->icmap
[j
], s
->ictlv
+ j
);
276 // Connect the output control ports
277 for (j
= 0; j
< s
->nb_outputcontrols
; j
++)
278 s
->desc
->connect_port(s
->handles
[i
], s
->ocmap
[j
], &s
->octlv
[j
]);
280 if (s
->desc
->activate
)
281 s
->desc
->activate(s
->handles
[i
]);
284 av_log(ctx
, AV_LOG_DEBUG
, "handles: %d\n", s
->nb_handles
);
289 static int config_input(AVFilterLink
*inlink
)
291 AVFilterContext
*ctx
= inlink
->dst
;
293 return connect_ports(ctx
, inlink
);
296 static int config_output(AVFilterLink
*outlink
)
298 AVFilterContext
*ctx
= outlink
->src
;
301 if (ctx
->nb_inputs
) {
302 AVFilterLink
*inlink
= ctx
->inputs
[0];
304 outlink
->format
= inlink
->format
;
305 outlink
->sample_rate
= inlink
->sample_rate
;
309 LADSPAContext
*s
= ctx
->priv
;
311 outlink
->sample_rate
= s
->sample_rate
;
312 outlink
->time_base
= (AVRational
){1, s
->sample_rate
};
314 ret
= connect_ports(ctx
, outlink
);
320 static void count_ports(const LADSPA_Descriptor
*desc
,
321 unsigned long *nb_inputs
, unsigned long *nb_outputs
)
323 LADSPA_PortDescriptor pd
;
326 for (i
= 0; i
< desc
->PortCount
; i
++) {
327 pd
= desc
->PortDescriptors
[i
];
329 if (LADSPA_IS_PORT_AUDIO(pd
)) {
330 if (LADSPA_IS_PORT_INPUT(pd
)) {
332 } else if (LADSPA_IS_PORT_OUTPUT(pd
)) {
339 static void *try_load(const char *dir
, const char *soname
)
341 char *path
= av_asprintf("%s/%s.so", dir
, soname
);
345 ret
= dlopen(path
, RTLD_LOCAL
|RTLD_NOW
);
352 static int set_control(AVFilterContext
*ctx
, unsigned long port
, LADSPA_Data value
)
354 LADSPAContext
*s
= ctx
->priv
;
355 const char *label
= s
->desc
->Label
;
356 LADSPA_PortRangeHint
*h
= (LADSPA_PortRangeHint
*)s
->desc
->PortRangeHints
+
359 if (port
>= s
->nb_inputcontrols
) {
360 av_log(ctx
, AV_LOG_ERROR
, "Control c%ld is out of range [0 - %lu].\n",
361 port
, s
->nb_inputcontrols
);
362 return AVERROR(EINVAL
);
365 if (LADSPA_IS_HINT_BOUNDED_BELOW(h
->HintDescriptor
) &&
366 value
< h
->LowerBound
) {
367 av_log(ctx
, AV_LOG_ERROR
,
368 "%s: input control c%ld is below lower boundary of %0.4f.\n",
369 label
, port
, h
->LowerBound
);
370 return AVERROR(EINVAL
);
373 if (LADSPA_IS_HINT_BOUNDED_ABOVE(h
->HintDescriptor
) &&
374 value
> h
->UpperBound
) {
375 av_log(ctx
, AV_LOG_ERROR
,
376 "%s: input control c%ld is above upper boundary of %0.4f.\n",
377 label
, port
, h
->UpperBound
);
378 return AVERROR(EINVAL
);
381 s
->ictlv
[port
] = value
;
386 static av_cold
int init(AVFilterContext
*ctx
)
388 LADSPAContext
*s
= ctx
->priv
;
389 LADSPA_Descriptor_Function descriptor_fn
;
390 const LADSPA_Descriptor
*desc
;
391 LADSPA_PortDescriptor pd
;
392 AVFilterPad pad
= { NULL
};
393 char *p
, *arg
, *saveptr
= NULL
;
394 unsigned long nb_ports
;
398 av_log(ctx
, AV_LOG_ERROR
, "No plugin name provided\n");
399 return AVERROR(EINVAL
);
402 if (s
->dl_name
[0] == '/' || s
->dl_name
[0] == '.') {
403 // argument is a path
404 s
->dl_handle
= dlopen(s
->dl_name
, RTLD_LOCAL
|RTLD_NOW
);
406 // argument is a shared object name
407 char *paths
= av_strdup(getenv("LADSPA_PATH"));
408 const char *separator
= ":";
412 while ((arg
= av_strtok(p
, separator
, &saveptr
)) && !s
->dl_handle
) {
413 s
->dl_handle
= try_load(arg
, s
->dl_name
);
419 if (!s
->dl_handle
&& (paths
= av_asprintf("%s/.ladspa/lib", getenv("HOME")))) {
420 s
->dl_handle
= try_load(paths
, s
->dl_name
);
425 s
->dl_handle
= try_load("/usr/local/lib/ladspa", s
->dl_name
);
428 s
->dl_handle
= try_load("/usr/lib/ladspa", s
->dl_name
);
431 av_log(ctx
, AV_LOG_ERROR
, "Failed to load '%s'\n", s
->dl_name
);
432 return AVERROR(EINVAL
);
435 descriptor_fn
= dlsym(s
->dl_handle
, "ladspa_descriptor");
436 if (!descriptor_fn
) {
437 av_log(ctx
, AV_LOG_ERROR
, "Could not find ladspa_descriptor: %s\n", dlerror());
438 return AVERROR(EINVAL
);
441 // Find the requested plugin, or list plugins
443 av_log(ctx
, AV_LOG_INFO
, "The '%s' library contains the following plugins:\n", s
->dl_name
);
444 av_log(ctx
, AV_LOG_INFO
, "I = Input Channels\n");
445 av_log(ctx
, AV_LOG_INFO
, "O = Output Channels\n");
446 av_log(ctx
, AV_LOG_INFO
, "I:O %-25s %s\n", "Plugin", "Description");
447 av_log(ctx
, AV_LOG_INFO
, "\n");
448 for (i
= 0; desc
= descriptor_fn(i
); i
++) {
449 unsigned long inputs
= 0, outputs
= 0;
451 count_ports(desc
, &inputs
, &outputs
);
452 av_log(ctx
, AV_LOG_INFO
, "%lu:%lu %-25s %s\n", inputs
, outputs
, desc
->Label
,
453 (char *)av_x_if_null(desc
->Name
, "?"));
454 av_log(ctx
, AV_LOG_VERBOSE
, "Maker: %s\n",
455 (char *)av_x_if_null(desc
->Maker
, "?"));
456 av_log(ctx
, AV_LOG_VERBOSE
, "Copyright: %s\n",
457 (char *)av_x_if_null(desc
->Copyright
, "?"));
462 desc
= descriptor_fn(i
);
464 av_log(ctx
, AV_LOG_ERROR
, "Could not find plugin: %s\n", s
->plugin
);
465 return AVERROR(EINVAL
);
468 if (desc
->Label
&& !strcmp(desc
->Label
, s
->plugin
))
474 nb_ports
= desc
->PortCount
;
476 s
->ipmap
= av_calloc(nb_ports
, sizeof(*s
->ipmap
));
477 s
->opmap
= av_calloc(nb_ports
, sizeof(*s
->opmap
));
478 s
->icmap
= av_calloc(nb_ports
, sizeof(*s
->icmap
));
479 s
->ocmap
= av_calloc(nb_ports
, sizeof(*s
->ocmap
));
480 s
->ictlv
= av_calloc(nb_ports
, sizeof(*s
->ictlv
));
481 s
->octlv
= av_calloc(nb_ports
, sizeof(*s
->octlv
));
482 s
->ctl_needs_value
= av_calloc(nb_ports
, sizeof(*s
->ctl_needs_value
));
483 if (!s
->ipmap
|| !s
->opmap
|| !s
->icmap
||
484 !s
->ocmap
|| !s
->ictlv
|| !s
->octlv
|| !s
->ctl_needs_value
)
485 return AVERROR(ENOMEM
);
487 for (i
= 0; i
< nb_ports
; i
++) {
488 pd
= desc
->PortDescriptors
[i
];
490 if (LADSPA_IS_PORT_AUDIO(pd
)) {
491 if (LADSPA_IS_PORT_INPUT(pd
)) {
492 s
->ipmap
[s
->nb_inputs
] = i
;
494 } else if (LADSPA_IS_PORT_OUTPUT(pd
)) {
495 s
->opmap
[s
->nb_outputs
] = i
;
498 } else if (LADSPA_IS_PORT_CONTROL(pd
)) {
499 if (LADSPA_IS_PORT_INPUT(pd
)) {
500 s
->icmap
[s
->nb_inputcontrols
] = i
;
502 if (LADSPA_IS_HINT_HAS_DEFAULT(desc
->PortRangeHints
[i
].HintDescriptor
))
503 set_default_ctl_value(s
, s
->nb_inputcontrols
, s
->icmap
, s
->ictlv
);
505 s
->ctl_needs_value
[s
->nb_inputcontrols
] = 1;
507 s
->nb_inputcontrols
++;
508 } else if (LADSPA_IS_PORT_OUTPUT(pd
)) {
509 s
->ocmap
[s
->nb_outputcontrols
] = i
;
510 s
->nb_outputcontrols
++;
515 // List Control Ports if "help" is specified
516 if (s
->options
&& !strcmp(s
->options
, "help")) {
517 if (!s
->nb_inputcontrols
) {
518 av_log(ctx
, AV_LOG_INFO
,
519 "The '%s' plugin does not have any input controls.\n",
522 av_log(ctx
, AV_LOG_INFO
,
523 "The '%s' plugin has the following input controls:\n",
525 for (i
= 0; i
< s
->nb_inputcontrols
; i
++)
526 print_ctl_info(ctx
, AV_LOG_INFO
, s
, i
, s
->icmap
, s
->ictlv
, 0);
531 // Parse control parameters
537 if (!(arg
= av_strtok(p
, "|", &saveptr
)))
541 if (sscanf(arg
, "c%d=%f", &i
, &val
) != 2) {
542 av_log(ctx
, AV_LOG_ERROR
, "Invalid syntax.\n");
543 return AVERROR(EINVAL
);
546 if ((ret
= set_control(ctx
, i
, val
)) < 0)
548 s
->ctl_needs_value
[i
] = 0;
551 // Check if any controls are not set
552 for (i
= 0; i
< s
->nb_inputcontrols
; i
++) {
553 if (s
->ctl_needs_value
[i
]) {
554 av_log(ctx
, AV_LOG_ERROR
, "Control c%d must be set.\n", i
);
555 print_ctl_info(ctx
, AV_LOG_ERROR
, s
, i
, s
->icmap
, s
->ictlv
, 0);
556 return AVERROR(EINVAL
);
560 pad
.type
= AVMEDIA_TYPE_AUDIO
;
563 pad
.name
= av_asprintf("in0:%s%lu", desc
->Label
, s
->nb_inputs
);
565 return AVERROR(ENOMEM
);
567 pad
.filter_frame
= filter_frame
;
568 pad
.config_props
= config_input
;
569 if (ff_insert_inpad(ctx
, ctx
->nb_inputs
, &pad
) < 0) {
571 return AVERROR(ENOMEM
);
575 av_log(ctx
, AV_LOG_DEBUG
, "ports: %lu\n", nb_ports
);
576 av_log(ctx
, AV_LOG_DEBUG
, "inputs: %lu outputs: %lu\n",
577 s
->nb_inputs
, s
->nb_outputs
);
578 av_log(ctx
, AV_LOG_DEBUG
, "input controls: %lu output controls: %lu\n",
579 s
->nb_inputcontrols
, s
->nb_outputcontrols
);
584 static int query_formats(AVFilterContext
*ctx
)
586 LADSPAContext
*s
= ctx
->priv
;
587 AVFilterFormats
*formats
;
588 AVFilterChannelLayouts
*layouts
;
589 static const enum AVSampleFormat sample_fmts
[] = {
590 AV_SAMPLE_FMT_FLTP
, AV_SAMPLE_FMT_NONE
};
592 formats
= ff_make_format_list(sample_fmts
);
594 return AVERROR(ENOMEM
);
595 ff_set_common_formats(ctx
, formats
);
598 formats
= ff_all_samplerates();
600 return AVERROR(ENOMEM
);
602 ff_set_common_samplerates(ctx
, formats
);
604 int sample_rates
[] = { s
->sample_rate
, -1 };
606 ff_set_common_samplerates(ctx
, ff_make_format_list(sample_rates
));
609 if (s
->nb_inputs
== 1 && s
->nb_outputs
== 1) {
610 // We will instantiate multiple LADSPA_Handle, one over each channel
611 layouts
= ff_all_channel_layouts();
613 return AVERROR(ENOMEM
);
615 ff_set_common_channel_layouts(ctx
, layouts
);
617 AVFilterLink
*outlink
= ctx
->outputs
[0];
619 if (s
->nb_inputs
>= 1) {
620 AVFilterLink
*inlink
= ctx
->inputs
[0];
621 int64_t inlayout
= FF_COUNT2LAYOUT(s
->nb_inputs
);
624 ff_add_channel_layout(&layouts
, inlayout
);
625 ff_channel_layouts_ref(layouts
, &inlink
->out_channel_layouts
);
628 ff_channel_layouts_ref(layouts
, &outlink
->in_channel_layouts
);
631 if (s
->nb_outputs
>= 1) {
632 int64_t outlayout
= FF_COUNT2LAYOUT(s
->nb_outputs
);
635 ff_add_channel_layout(&layouts
, outlayout
);
636 ff_channel_layouts_ref(layouts
, &outlink
->in_channel_layouts
);
643 static av_cold
void uninit(AVFilterContext
*ctx
)
645 LADSPAContext
*s
= ctx
->priv
;
648 for (i
= 0; i
< s
->nb_handles
; i
++) {
649 if (s
->desc
->deactivate
)
650 s
->desc
->deactivate(s
->handles
[i
]);
651 if (s
->desc
->cleanup
)
652 s
->desc
->cleanup(s
->handles
[i
]);
656 dlclose(s
->dl_handle
);
664 av_freep(&s
->handles
);
665 av_freep(&s
->ctl_needs_value
);
668 av_freep(&ctx
->input_pads
[0].name
);
671 static int process_command(AVFilterContext
*ctx
, const char *cmd
, const char *args
,
672 char *res
, int res_len
, int flags
)
677 if (sscanf(cmd
, "c%ld", &port
) + sscanf(args
, "%f", &value
) != 2)
678 return AVERROR(EINVAL
);
680 return set_control(ctx
, port
, value
);
683 static const AVFilterPad ladspa_outputs
[] = {
686 .type
= AVMEDIA_TYPE_AUDIO
,
687 .config_props
= config_output
,
688 .request_frame
= request_frame
,
693 AVFilter ff_af_ladspa
= {
695 .description
= NULL_IF_CONFIG_SMALL("Apply LADSPA effect."),
696 .priv_size
= sizeof(LADSPAContext
),
697 .priv_class
= &ladspa_class
,
700 .query_formats
= query_formats
,
701 .process_command
= process_command
,
703 .outputs
= ladspa_outputs
,
704 .flags
= AVFILTER_FLAG_DYNAMIC_INPUTS
,