/*
 * Copyright (c) 2013 Paul B Mahol
 * Copyright (c) 2011 Mina Nagy Zaki
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
 * @file
 * LADSPA wrapper
 */

#include <dlfcn.h>
#include <ladspa.h>
#include "libavutil/avstring.h"
#include "libavutil/channel_layout.h"
#include "libavutil/opt.h"
#include "audio.h"
#include "avfilter.h"
#include "internal.h"

typedef struct LADSPAContext {
    const AVClass *class;
    char *dl_name;
    char *plugin;
    char *options;
    void *dl_handle;

    unsigned long nb_inputs;
    unsigned long *ipmap;      /* map input number to port number */

    unsigned long nb_inputcontrols;
    unsigned long *icmap;      /* map input control number to port number */
    LADSPA_Data *ictlv;        /* input controls values */

    unsigned long nb_outputs;
    unsigned long *opmap;      /* map output number to port number */

    unsigned long nb_outputcontrols;
    unsigned long *ocmap;      /* map output control number to port number */
    LADSPA_Data *octlv;        /* output controls values */

    const LADSPA_Descriptor *desc;
    int *ctl_needs_value;
    int nb_handles;
    LADSPA_Handle *handles;

    int sample_rate;
    int nb_samples;
    int64_t pts;
    int64_t duration;
} LADSPAContext;

#define OFFSET(x) offsetof(LADSPAContext, x)
#define FLAGS AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_FILTERING_PARAM
static const AVOption ladspa_options[] = {
    { "file", "set library name or full path", OFFSET(dl_name), AV_OPT_TYPE_STRING, .flags = FLAGS },
    { "f",    "set library name or full path", OFFSET(dl_name), AV_OPT_TYPE_STRING, .flags = FLAGS },
    { "plugin", "set plugin name", OFFSET(plugin), AV_OPT_TYPE_STRING, .flags = FLAGS },
    { "p",      "set plugin name", OFFSET(plugin), AV_OPT_TYPE_STRING, .flags = FLAGS },
    { "controls", "set plugin options", OFFSET(options), AV_OPT_TYPE_STRING, .flags = FLAGS },
    { "c",        "set plugin options", OFFSET(options), AV_OPT_TYPE_STRING, .flags = FLAGS },
    { "sample_rate", "set sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64=44100}, 1, INT32_MAX, FLAGS },
    { "s",           "set sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64=44100}, 1, INT32_MAX, FLAGS },
    { "nb_samples", "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64=1024}, 1, INT_MAX, FLAGS },
    { "n",          "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64=1024}, 1, INT_MAX, FLAGS },
    { "duration", "set audio duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64=-1}, -1, INT64_MAX, FLAGS },
    { "d",        "set audio duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64=-1}, -1, INT64_MAX, FLAGS },
    { NULL }
};

AVFILTER_DEFINE_CLASS(ladspa);

static void print_ctl_info(AVFilterContext *ctx, int level,
                           LADSPAContext *s, int ctl, unsigned long *map,
                           LADSPA_Data *values, int print)
{
    const LADSPA_PortRangeHint *h = s->desc->PortRangeHints + map[ctl];

    av_log(ctx, level, "c%i: %s [", ctl, s->desc->PortNames[map[ctl]]);

    if (LADSPA_IS_HINT_TOGGLED(h->HintDescriptor)) {
        av_log(ctx, level, "toggled (1 or 0)");

        if (LADSPA_IS_HINT_HAS_DEFAULT(h->HintDescriptor))
            av_log(ctx, level, " (default %i)", (int)values[ctl]);
    } else {
        if (LADSPA_IS_HINT_INTEGER(h->HintDescriptor)) {
            av_log(ctx, level, "<int>");

            if (LADSPA_IS_HINT_BOUNDED_BELOW(h->HintDescriptor))
                av_log(ctx, level, ", min: %i", (int)h->LowerBound);

            if (LADSPA_IS_HINT_BOUNDED_ABOVE(h->HintDescriptor))
                av_log(ctx, level, ", max: %i", (int)h->UpperBound);

            if (print)
                av_log(ctx, level, " (value %d)", (int)values[ctl]);
            else if (LADSPA_IS_HINT_HAS_DEFAULT(h->HintDescriptor))
                av_log(ctx, level, " (default %d)", (int)values[ctl]);
        } else {
            av_log(ctx, level, "<float>");

            if (LADSPA_IS_HINT_BOUNDED_BELOW(h->HintDescriptor))
                av_log(ctx, level, ", min: %f", h->LowerBound);

            if (LADSPA_IS_HINT_BOUNDED_ABOVE(h->HintDescriptor))
                av_log(ctx, level, ", max: %f", h->UpperBound);

            if (print)
                av_log(ctx, level, " (value %f)", values[ctl]);
            else if (LADSPA_IS_HINT_HAS_DEFAULT(h->HintDescriptor))
                av_log(ctx, level, " (default %f)", values[ctl]);
        }

        if (LADSPA_IS_HINT_SAMPLE_RATE(h->HintDescriptor))
            av_log(ctx, level, ", multiple of sample rate");

        if (LADSPA_IS_HINT_LOGARITHMIC(h->HintDescriptor))
            av_log(ctx, level, ", logarithmic scale");
    }

    av_log(ctx, level, "]\n");
}

static int filter_frame(AVFilterLink *inlink, AVFrame *in)
{
    AVFilterContext *ctx = inlink->dst;
    LADSPAContext *s = ctx->priv;
    AVFrame *out;
    int i, h;

    if (!s->nb_outputs ||
        (av_frame_is_writable(in) && s->nb_inputs == s->nb_outputs &&
        !(s->desc->Properties & LADSPA_PROPERTY_INPLACE_BROKEN))) {
        out = in;
    } else {
        out = ff_get_audio_buffer(ctx->outputs[0], in->nb_samples);
        if (!out) {
            av_frame_free(&in);
            return AVERROR(ENOMEM);
        }
        av_frame_copy_props(out, in);
    }

    for (h = 0; h < s->nb_handles; h++) {
        for (i = 0; i < s->nb_inputs; i++) {
            s->desc->connect_port(s->handles[h], s->ipmap[i],
                                  (LADSPA_Data*)in->extended_data[i]);
        }

        for (i = 0; i < s->nb_outputs; i++) {
            s->desc->connect_port(s->handles[h], s->opmap[i],
                                  (LADSPA_Data*)out->extended_data[i]);
        }

        s->desc->run(s->handles[h], in->nb_samples);
    }

    for (i = 0; i < s->nb_outputcontrols; i++)
        print_ctl_info(ctx, AV_LOG_VERBOSE, s, i, s->ocmap, s->octlv, 1);

    if (out != in)
        av_frame_free(&in);

    return ff_filter_frame(ctx->outputs[0], out);
}

static int request_frame(AVFilterLink *outlink)
{
    AVFilterContext *ctx = outlink->src;
    LADSPAContext *s = ctx->priv;
    AVFrame *out;
    int64_t t;
    int i;

    if (ctx->nb_inputs)
        return ff_request_frame(ctx->inputs[0]);

    t = av_rescale(s->pts, AV_TIME_BASE, s->sample_rate);
    if (s->duration >= 0 && t >= s->duration)
        return AVERROR_EOF;

    out = ff_get_audio_buffer(outlink, s->nb_samples);
    if (!out)
        return AVERROR(ENOMEM);

    for (i = 0; i < s->nb_outputs; i++)
        s->desc->connect_port(s->handles[0], s->opmap[i],
                (LADSPA_Data*)out->extended_data[i]);

    s->desc->run(s->handles[0], s->nb_samples);

    for (i = 0; i < s->nb_outputcontrols; i++)
        print_ctl_info(ctx, AV_LOG_INFO, s, i, s->ocmap, s->octlv, 1);

    out->sample_rate = s->sample_rate;
    out->pts         = s->pts;
    s->pts          += s->nb_samples;

    return ff_filter_frame(outlink, out);
}

static void set_default_ctl_value(LADSPAContext *s, int ctl,
                                  unsigned long *map, LADSPA_Data *values)
{
    const LADSPA_PortRangeHint *h = s->desc->PortRangeHints + map[ctl];
    const LADSPA_Data lower = h->LowerBound;
    const LADSPA_Data upper = h->UpperBound;

    if (LADSPA_IS_HINT_DEFAULT_MINIMUM(h->HintDescriptor)) {
        values[ctl] = lower;
    } else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(h->HintDescriptor)) {
        values[ctl] = upper;
    } else if (LADSPA_IS_HINT_DEFAULT_0(h->HintDescriptor)) {
        values[ctl] = 0.0;
    } else if (LADSPA_IS_HINT_DEFAULT_1(h->HintDescriptor)) {
        values[ctl] = 1.0;
    } else if (LADSPA_IS_HINT_DEFAULT_100(h->HintDescriptor)) {
        values[ctl] = 100.0;
    } else if (LADSPA_IS_HINT_DEFAULT_440(h->HintDescriptor)) {
        values[ctl] = 440.0;
    } else if (LADSPA_IS_HINT_DEFAULT_LOW(h->HintDescriptor)) {
        if (LADSPA_IS_HINT_LOGARITHMIC(h->HintDescriptor))
            values[ctl] = exp(log(lower) * 0.75 + log(upper) * 0.25);
        else
            values[ctl] = lower * 0.75 + upper * 0.25;
    } else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(h->HintDescriptor)) {
        if (LADSPA_IS_HINT_LOGARITHMIC(h->HintDescriptor))
            values[ctl] = exp(log(lower) * 0.5 + log(upper) * 0.5);
        else
            values[ctl] = lower * 0.5 + upper * 0.5;
    } else if (LADSPA_IS_HINT_DEFAULT_HIGH(h->HintDescriptor)) {
        if (LADSPA_IS_HINT_LOGARITHMIC(h->HintDescriptor))
            values[ctl] = exp(log(lower) * 0.25 + log(upper) * 0.75);
        else
            values[ctl] = lower * 0.25 + upper * 0.75;
    }
}

static int connect_ports(AVFilterContext *ctx, AVFilterLink *link)
{
    LADSPAContext *s = ctx->priv;
    int i, j;

    s->nb_handles = s->nb_inputs == 1 && s->nb_outputs == 1 ? link->channels : 1;
    s->handles    = av_calloc(s->nb_handles, sizeof(*s->handles));
    if (!s->handles)
        return AVERROR(ENOMEM);

    for (i = 0; i < s->nb_handles; i++) {
        s->handles[i] = s->desc->instantiate(s->desc, link->sample_rate);
        if (!s->handles[i]) {
            av_log(ctx, AV_LOG_ERROR, "Could not instantiate plugin.\n");
            return AVERROR_EXTERNAL;
        }

        // Connect the input control ports
        for (j = 0; j < s->nb_inputcontrols; j++)
            s->desc->connect_port(s->handles[i], s->icmap[j], s->ictlv + j);

        // Connect the output control ports
        for (j = 0; j < s->nb_outputcontrols; j++)
            s->desc->connect_port(s->handles[i], s->ocmap[j], &s->octlv[j]);

        if (s->desc->activate)
            s->desc->activate(s->handles[i]);
    }

    av_log(ctx, AV_LOG_DEBUG, "handles: %d\n", s->nb_handles);

    return 0;
}

static int config_input(AVFilterLink *inlink)
{
    AVFilterContext *ctx = inlink->dst;

    return connect_ports(ctx, inlink);
}

static int config_output(AVFilterLink *outlink)
{
    AVFilterContext *ctx = outlink->src;
    int ret;

    if (ctx->nb_inputs) {
        AVFilterLink *inlink = ctx->inputs[0];

        outlink->format      = inlink->format;
        outlink->sample_rate = inlink->sample_rate;

        ret = 0;
    } else {
        LADSPAContext *s = ctx->priv;

        outlink->sample_rate = s->sample_rate;
        outlink->time_base   = (AVRational){1, s->sample_rate};

        ret = connect_ports(ctx, outlink);
    }

    return ret;
}

static void count_ports(const LADSPA_Descriptor *desc,
                        unsigned long *nb_inputs, unsigned long *nb_outputs)
{
    LADSPA_PortDescriptor pd;
    int i;

    for (i = 0; i < desc->PortCount; i++) {
        pd = desc->PortDescriptors[i];

        if (LADSPA_IS_PORT_AUDIO(pd)) {
            if (LADSPA_IS_PORT_INPUT(pd)) {
                (*nb_inputs)++;
            } else if (LADSPA_IS_PORT_OUTPUT(pd)) {
                (*nb_outputs)++;
            }
        }
    }
}

static void *try_load(const char *dir, const char *soname)
{
    char *path = av_asprintf("%s/%s.so", dir, soname);
    void *ret = NULL;

    if (path) {
        ret = dlopen(path, RTLD_LOCAL|RTLD_NOW);
        av_free(path);
    }

    return ret;
}

static int set_control(AVFilterContext *ctx, unsigned long port, LADSPA_Data value)
{
    LADSPAContext *s = ctx->priv;
    const char *label = s->desc->Label;
    LADSPA_PortRangeHint *h = (LADSPA_PortRangeHint *)s->desc->PortRangeHints +
                              s->icmap[port];

    if (port >= s->nb_inputcontrols) {
        av_log(ctx, AV_LOG_ERROR, "Control c%ld is out of range [0 - %lu].\n",
               port, s->nb_inputcontrols);
        return AVERROR(EINVAL);
    }

    if (LADSPA_IS_HINT_BOUNDED_BELOW(h->HintDescriptor) &&
            value < h->LowerBound) {
        av_log(ctx, AV_LOG_ERROR,
                "%s: input control c%ld is below lower boundary of %0.4f.\n",
                label, port, h->LowerBound);
        return AVERROR(EINVAL);
    }

    if (LADSPA_IS_HINT_BOUNDED_ABOVE(h->HintDescriptor) &&
            value > h->UpperBound) {
        av_log(ctx, AV_LOG_ERROR,
                "%s: input control c%ld is above upper boundary of %0.4f.\n",
                label, port, h->UpperBound);
        return AVERROR(EINVAL);
    }

    s->ictlv[port] = value;

    return 0;
}

static av_cold int init(AVFilterContext *ctx)
{
    LADSPAContext *s = ctx->priv;
    LADSPA_Descriptor_Function descriptor_fn;
    const LADSPA_Descriptor *desc;
    LADSPA_PortDescriptor pd;
    AVFilterPad pad = { NULL };
    char *p, *arg, *saveptr = NULL;
    unsigned long nb_ports;
    int i;

    if (!s->dl_name) {
        av_log(ctx, AV_LOG_ERROR, "No plugin name provided\n");
        return AVERROR(EINVAL);
    }

    if (s->dl_name[0] == '/' || s->dl_name[0] == '.') {
        // argument is a path
        s->dl_handle = dlopen(s->dl_name, RTLD_LOCAL|RTLD_NOW);
    } else {
        // argument is a shared object name
        char *paths = av_strdup(getenv("LADSPA_PATH"));
        const char *separator = ":";

        if (paths) {
            p = paths;
            while ((arg = av_strtok(p, separator, &saveptr)) && !s->dl_handle) {
                s->dl_handle = try_load(arg, s->dl_name);
                p = NULL;
            }
        }

        av_free(paths);
        if (!s->dl_handle && (paths = av_asprintf("%s/.ladspa/lib", getenv("HOME")))) {
            s->dl_handle = try_load(paths, s->dl_name);
            av_free(paths);
        }

        if (!s->dl_handle)
            s->dl_handle = try_load("/usr/local/lib/ladspa", s->dl_name);

        if (!s->dl_handle)
            s->dl_handle = try_load("/usr/lib/ladspa", s->dl_name);
    }
    if (!s->dl_handle) {
        av_log(ctx, AV_LOG_ERROR, "Failed to load '%s'\n", s->dl_name);
        return AVERROR(EINVAL);
    }

    descriptor_fn = dlsym(s->dl_handle, "ladspa_descriptor");
    if (!descriptor_fn) {
        av_log(ctx, AV_LOG_ERROR, "Could not find ladspa_descriptor: %s\n", dlerror());
        return AVERROR(EINVAL);
    }

    // Find the requested plugin, or list plugins
    if (!s->plugin) {
        av_log(ctx, AV_LOG_INFO, "The '%s' library contains the following plugins:\n", s->dl_name);
        av_log(ctx, AV_LOG_INFO, "I = Input Channels\n");
        av_log(ctx, AV_LOG_INFO, "O = Output Channels\n");
        av_log(ctx, AV_LOG_INFO, "I:O %-25s %s\n", "Plugin", "Description");
        av_log(ctx, AV_LOG_INFO, "\n");
        for (i = 0; desc = descriptor_fn(i); i++) {
            unsigned long inputs = 0, outputs = 0;

            count_ports(desc, &inputs, &outputs);
            av_log(ctx, AV_LOG_INFO, "%lu:%lu %-25s %s\n", inputs, outputs, desc->Label,
                   (char *)av_x_if_null(desc->Name, "?"));
            av_log(ctx, AV_LOG_VERBOSE, "Maker: %s\n",
                   (char *)av_x_if_null(desc->Maker, "?"));
            av_log(ctx, AV_LOG_VERBOSE, "Copyright: %s\n",
                   (char *)av_x_if_null(desc->Copyright, "?"));
        }
        return AVERROR_EXIT;
    } else {
        for (i = 0;; i++) {
            desc = descriptor_fn(i);
            if (!desc) {
                av_log(ctx, AV_LOG_ERROR, "Could not find plugin: %s\n", s->plugin);
                return AVERROR(EINVAL);
            }

            if (desc->Label && !strcmp(desc->Label, s->plugin))
                break;
        }
    }

    s->desc  = desc;
    nb_ports = desc->PortCount;

    s->ipmap = av_calloc(nb_ports, sizeof(*s->ipmap));
    s->opmap = av_calloc(nb_ports, sizeof(*s->opmap));
    s->icmap = av_calloc(nb_ports, sizeof(*s->icmap));
    s->ocmap = av_calloc(nb_ports, sizeof(*s->ocmap));
    s->ictlv = av_calloc(nb_ports, sizeof(*s->ictlv));
    s->octlv = av_calloc(nb_ports, sizeof(*s->octlv));
    s->ctl_needs_value = av_calloc(nb_ports, sizeof(*s->ctl_needs_value));
    if (!s->ipmap || !s->opmap || !s->icmap ||
        !s->ocmap || !s->ictlv || !s->octlv || !s->ctl_needs_value)
        return AVERROR(ENOMEM);

    for (i = 0; i < nb_ports; i++) {
        pd = desc->PortDescriptors[i];

        if (LADSPA_IS_PORT_AUDIO(pd)) {
            if (LADSPA_IS_PORT_INPUT(pd)) {
                s->ipmap[s->nb_inputs] = i;
                s->nb_inputs++;
            } else if (LADSPA_IS_PORT_OUTPUT(pd)) {
                s->opmap[s->nb_outputs] = i;
                s->nb_outputs++;
            }
        } else if (LADSPA_IS_PORT_CONTROL(pd)) {
            if (LADSPA_IS_PORT_INPUT(pd)) {
                s->icmap[s->nb_inputcontrols] = i;

                if (LADSPA_IS_HINT_HAS_DEFAULT(desc->PortRangeHints[i].HintDescriptor))
                    set_default_ctl_value(s, s->nb_inputcontrols, s->icmap, s->ictlv);
                else
                    s->ctl_needs_value[s->nb_inputcontrols] = 1;

                s->nb_inputcontrols++;
            } else if (LADSPA_IS_PORT_OUTPUT(pd)) {
                s->ocmap[s->nb_outputcontrols] = i;
                s->nb_outputcontrols++;
            }
        }
    }

    // List Control Ports if "help" is specified
    if (s->options && !strcmp(s->options, "help")) {
        if (!s->nb_inputcontrols) {
            av_log(ctx, AV_LOG_INFO,
                   "The '%s' plugin does not have any input controls.\n",
                   desc->Label);
        } else {
            av_log(ctx, AV_LOG_INFO,
                   "The '%s' plugin has the following input controls:\n",
                   desc->Label);
            for (i = 0; i < s->nb_inputcontrols; i++)
                print_ctl_info(ctx, AV_LOG_INFO, s, i, s->icmap, s->ictlv, 0);
        }
        return AVERROR_EXIT;
    }

    // Parse control parameters
    p = s->options;
    while (s->options) {
        LADSPA_Data val;
        int ret;

        if (!(arg = av_strtok(p, "|", &saveptr)))
            break;
        p = NULL;

        if (sscanf(arg, "c%d=%f", &i, &val) != 2) {
            av_log(ctx, AV_LOG_ERROR, "Invalid syntax.\n");
            return AVERROR(EINVAL);
        }

        if ((ret = set_control(ctx, i, val)) < 0)
            return ret;
        s->ctl_needs_value[i] = 0;
    }

    // Check if any controls are not set
    for (i = 0; i < s->nb_inputcontrols; i++) {
        if (s->ctl_needs_value[i]) {
            av_log(ctx, AV_LOG_ERROR, "Control c%d must be set.\n", i);
            print_ctl_info(ctx, AV_LOG_ERROR, s, i, s->icmap, s->ictlv, 0);
            return AVERROR(EINVAL);
        }
    }

    pad.type = AVMEDIA_TYPE_AUDIO;

    if (s->nb_inputs) {
        pad.name = av_asprintf("in0:%s%lu", desc->Label, s->nb_inputs);
        if (!pad.name)
            return AVERROR(ENOMEM);

        pad.filter_frame = filter_frame;
        pad.config_props = config_input;
        if (ff_insert_inpad(ctx, ctx->nb_inputs, &pad) < 0) {
            av_freep(&pad.name);
            return AVERROR(ENOMEM);
        }
    }

    av_log(ctx, AV_LOG_DEBUG, "ports: %lu\n", nb_ports);
    av_log(ctx, AV_LOG_DEBUG, "inputs: %lu outputs: %lu\n",
                              s->nb_inputs, s->nb_outputs);
    av_log(ctx, AV_LOG_DEBUG, "input controls: %lu output controls: %lu\n",
                              s->nb_inputcontrols, s->nb_outputcontrols);

    return 0;
}

static int query_formats(AVFilterContext *ctx)
{
    LADSPAContext *s = ctx->priv;
    AVFilterFormats *formats;
    AVFilterChannelLayouts *layouts;
    static const enum AVSampleFormat sample_fmts[] = {
        AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE };

    formats = ff_make_format_list(sample_fmts);
    if (!formats)
        return AVERROR(ENOMEM);
    ff_set_common_formats(ctx, formats);

    if (s->nb_inputs) {
        formats = ff_all_samplerates();
        if (!formats)
            return AVERROR(ENOMEM);

        ff_set_common_samplerates(ctx, formats);
    } else {
        int sample_rates[] = { s->sample_rate, -1 };

        ff_set_common_samplerates(ctx, ff_make_format_list(sample_rates));
    }

    if (s->nb_inputs == 1 && s->nb_outputs == 1) {
        // We will instantiate multiple LADSPA_Handle, one over each channel
        layouts = ff_all_channel_layouts();
        if (!layouts)
            return AVERROR(ENOMEM);

        ff_set_common_channel_layouts(ctx, layouts);
    } else {
        AVFilterLink *outlink = ctx->outputs[0];

        if (s->nb_inputs >= 1) {
            AVFilterLink *inlink = ctx->inputs[0];
            int64_t inlayout = FF_COUNT2LAYOUT(s->nb_inputs);

            layouts = NULL;
            ff_add_channel_layout(&layouts, inlayout);
            ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts);

            if (!s->nb_outputs)
                ff_channel_layouts_ref(layouts, &outlink->in_channel_layouts);
        }

        if (s->nb_outputs >= 1) {
            int64_t outlayout = FF_COUNT2LAYOUT(s->nb_outputs);

            layouts = NULL;
            ff_add_channel_layout(&layouts, outlayout);
            ff_channel_layouts_ref(layouts, &outlink->in_channel_layouts);
        }
    }

    return 0;
}

static av_cold void uninit(AVFilterContext *ctx)
{
    LADSPAContext *s = ctx->priv;
    int i;

    for (i = 0; i < s->nb_handles; i++) {
        if (s->desc->deactivate)
            s->desc->deactivate(s->handles[i]);
        if (s->desc->cleanup)
            s->desc->cleanup(s->handles[i]);
    }

    if (s->dl_handle)
        dlclose(s->dl_handle);

    av_freep(&s->ipmap);
    av_freep(&s->opmap);
    av_freep(&s->icmap);
    av_freep(&s->ocmap);
    av_freep(&s->ictlv);
    av_freep(&s->octlv);
    av_freep(&s->handles);
    av_freep(&s->ctl_needs_value);

    if (ctx->nb_inputs)
        av_freep(&ctx->input_pads[0].name);
}

static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
                           char *res, int res_len, int flags)
{
    LADSPA_Data value;
    unsigned long port;

    if (sscanf(cmd, "c%ld", &port) + sscanf(args, "%f", &value) != 2)
        return AVERROR(EINVAL);

    return set_control(ctx, port, value);
}

static const AVFilterPad ladspa_outputs[] = {
    {
        .name          = "default",
        .type          = AVMEDIA_TYPE_AUDIO,
        .config_props  = config_output,
        .request_frame = request_frame,
    },
    { NULL }
};

AVFilter ff_af_ladspa = {
    .name          = "ladspa",
    .description   = NULL_IF_CONFIG_SMALL("Apply LADSPA effect."),
    .priv_size     = sizeof(LADSPAContext),
    .priv_class    = &ladspa_class,
    .init          = init,
    .uninit        = uninit,
    .query_formats = query_formats,
    .process_command = process_command,
    .inputs        = 0,
    .outputs       = ladspa_outputs,
    .flags         = AVFILTER_FLAG_DYNAMIC_INPUTS,
};
