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;
// Parse control parameters
p = s->options;
while (s->options) {
- LADSPA_PortRangeHint *h;
LADSPA_Data val;
+ int ret;
if (!(arg = av_strtok(p, "|", &saveptr)))
break;
return AVERROR(EINVAL);
}
- if (i < 0 || i >= s->nb_inputcontrols) {
- av_log(ctx, AV_LOG_ERROR,
- "Control c%d is out of range [0 - %lu].\n",
- i, s->nb_inputcontrols);
- return AVERROR(EINVAL);
- }
-
- h = (LADSPA_PortRangeHint *)s->desc->PortRangeHints + s->icmap[i];
- s->ictlv[i] = val;
+ if ((ret = set_control(ctx, i, val)) < 0)
+ return ret;
s->ctl_needs_value[i] = 0;
- if (LADSPA_IS_HINT_BOUNDED_BELOW(h->HintDescriptor) &&
- val < h->LowerBound) {
- av_log(ctx, AV_LOG_ERROR,
- "%s: input control c%d is below lower boundary of %0.4f.\n",
- s->desc->Label, i, h->LowerBound);
- return AVERROR(EINVAL);
- }
- if (LADSPA_IS_HINT_BOUNDED_ABOVE(h->HintDescriptor) &&
- val > h->UpperBound) {
- av_log(ctx, AV_LOG_ERROR,
- "%s: input control c%d is above upper boundary of %0.4f.\n",
- s->desc->Label, i, h->UpperBound);
- return AVERROR(EINVAL);
- }
}
// Check if any controls are not set
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) {
- AVFilterLink *outlink = ctx->outputs[0];
int64_t outlayout = FF_COUNT2LAYOUT(s->nb_outputs);
layouts = NULL;
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",
.init = init,
.uninit = uninit,
.query_formats = query_formats,
+ .process_command = process_command,
.inputs = 0,
.outputs = ladspa_outputs,
.flags = AVFILTER_FLAG_DYNAMIC_INPUTS,