FFmpeg
af_lv2.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Paul B Mahol
3  * Copyright (c) 2007-2016 David Robillard <http://drobilla.net>
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  * LV2 wrapper
25  */
26 
27 #include <lilv/lilv.h>
28 #include <lv2/lv2plug.in/ns/ext/atom/atom.h>
29 #include <lv2/lv2plug.in/ns/ext/buf-size/buf-size.h>
30 
31 #include "libavutil/avassert.h"
32 #include "libavutil/avstring.h"
34 #include "libavutil/opt.h"
35 #include "audio.h"
36 #include "avfilter.h"
37 #include "internal.h"
38 
39 typedef struct URITable {
40  char **uris;
41  size_t n_uris;
42 } URITable;
43 
44 typedef struct LV2Context {
45  const AVClass *class;
46  char *plugin_uri;
47  char *options;
48 
49  unsigned nb_inputs;
50  unsigned nb_inputcontrols;
51  unsigned nb_outputs;
52 
55  int64_t pts;
56  int64_t duration;
57 
58  LilvWorld *world;
59  const LilvPlugin *plugin;
60  uint32_t nb_ports;
61  float *values;
63  LV2_URID_Map map;
64  LV2_Feature map_feature;
65  LV2_URID_Unmap unmap;
66  LV2_Feature unmap_feature;
67  LV2_Atom_Sequence seq_in[2];
68  LV2_Atom_Sequence *seq_out;
69  const LV2_Feature *features[5];
70 
71  float *mins;
72  float *maxes;
73  float *controls;
74 
75  LilvInstance *instance;
76 
77  LilvNode *atom_AtomPort;
78  LilvNode *atom_Sequence;
79  LilvNode *lv2_AudioPort;
80  LilvNode *lv2_CVPort;
81  LilvNode *lv2_ControlPort;
82  LilvNode *lv2_Optional;
83  LilvNode *lv2_InputPort;
84  LilvNode *lv2_OutputPort;
85  LilvNode *urid_map;
87  LilvNode *fixedBlockLength;
88  LilvNode *boundedBlockLength;
89 } LV2Context;
90 
91 #define OFFSET(x) offsetof(LV2Context, x)
92 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_FILTERING_PARAM
93 
94 static const AVOption lv2_options[] = {
95  { "plugin", "set plugin uri", OFFSET(plugin_uri), AV_OPT_TYPE_STRING, .flags = FLAGS },
96  { "p", "set plugin uri", OFFSET(plugin_uri), AV_OPT_TYPE_STRING, .flags = FLAGS },
97  { "controls", "set plugin options", OFFSET(options), AV_OPT_TYPE_STRING, .flags = FLAGS },
98  { "c", "set plugin options", OFFSET(options), AV_OPT_TYPE_STRING, .flags = FLAGS },
99  { "sample_rate", "set sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64=44100}, 1, INT32_MAX, FLAGS },
100  { "s", "set sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64=44100}, 1, INT32_MAX, FLAGS },
101  { "nb_samples", "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64=1024}, 1, INT_MAX, FLAGS },
102  { "n", "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64=1024}, 1, INT_MAX, FLAGS },
103  { "duration", "set audio duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64=-1}, -1, INT64_MAX, FLAGS },
104  { "d", "set audio duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64=-1}, -1, INT64_MAX, FLAGS },
105  { NULL }
106 };
107 
109 
111 {
112  table->uris = NULL;
113  table->n_uris = 0;
114 }
115 
117 {
118  int i;
119 
120  for (i = 0; i < table->n_uris; i++) {
121  av_freep(&table->uris[i]);
122  }
123 
124  av_freep(&table->uris);
125 }
126 
127 static LV2_URID uri_table_map(LV2_URID_Map_Handle handle, const char *uri)
128 {
129  URITable *table = (URITable*)handle;
130  const size_t len = strlen(uri);
131  size_t i;
132  char **tmp;
133 
134  for (i = 0; i < table->n_uris; i++) {
135  if (!strcmp(table->uris[i], uri)) {
136  return i + 1;
137  }
138  }
139 
140  tmp = av_calloc(table->n_uris + 1, sizeof(char*));
141  if (!tmp)
142  return table->n_uris;
143  memcpy(tmp, table->uris, table->n_uris * sizeof(char**));
144 
145  av_free(table->uris);
146  table->uris = tmp;
147  table->uris[table->n_uris] = av_malloc(len + 1);
148  if (!table->uris[table->n_uris])
149  return table->n_uris;
150 
151  memcpy(table->uris[table->n_uris], uri, len + 1);
152  table->n_uris++;
153 
154  return table->n_uris;
155 }
156 
157 static const char *uri_table_unmap(LV2_URID_Map_Handle handle, LV2_URID urid)
158 {
159  URITable *table = (URITable*)handle;
160 
161  if (urid > 0 && urid <= table->n_uris) {
162  return table->uris[urid - 1];
163  }
164 
165  return NULL;
166 }
167 
169 {
170  int ich = 0, och = 0, i;
171 
172  for (i = 0; i < s->nb_ports; i++) {
173  const LilvPort *port = lilv_plugin_get_port_by_index(s->plugin, i);
174 
175  if (lilv_port_is_a(s->plugin, port, s->lv2_AudioPort) ||
176  lilv_port_is_a(s->plugin, port, s->lv2_CVPort)) {
177  if (lilv_port_is_a(s->plugin, port, s->lv2_InputPort)) {
178  lilv_instance_connect_port(s->instance, i, in->extended_data[ich++]);
179  } else if (lilv_port_is_a(s->plugin, port, s->lv2_OutputPort)) {
180  lilv_instance_connect_port(s->instance, i, out->extended_data[och++]);
181  } else {
182  av_log(s, AV_LOG_WARNING, "port %d neither input nor output, skipping\n", i);
183  }
184  } else if (lilv_port_is_a(s->plugin, port, s->atom_AtomPort)) {
185  if (lilv_port_is_a(s->plugin, port, s->lv2_InputPort)) {
186  lilv_instance_connect_port(s->instance, i, &s->seq_in);
187  } else {
188  lilv_instance_connect_port(s->instance, i, s->seq_out);
189  }
190  } else if (lilv_port_is_a(s->plugin, port, s->lv2_ControlPort)) {
191  lilv_instance_connect_port(s->instance, i, &s->controls[i]);
192  }
193  }
194 
195  s->seq_in[0].atom.size = sizeof(LV2_Atom_Sequence_Body);
196  s->seq_in[0].atom.type = uri_table_map(&s->uri_table, LV2_ATOM__Sequence);
197  s->seq_out->atom.size = 9624;
198  s->seq_out->atom.type = uri_table_map(&s->uri_table, LV2_ATOM__Chunk);
199 }
200 
202 {
203  AVFilterContext *ctx = inlink->dst;
204  LV2Context *s = ctx->priv;
205  AVFrame *out;
206 
207  if (!s->nb_outputs ||
208  (av_frame_is_writable(in) && s->nb_inputs == s->nb_outputs)) {
209  out = in;
210  } else {
211  out = ff_get_audio_buffer(ctx->outputs[0], in->nb_samples);
212  if (!out) {
213  av_frame_free(&in);
214  return AVERROR(ENOMEM);
215  }
216  av_frame_copy_props(out, in);
217  }
218 
219  connect_ports(s, in, out);
220 
221  lilv_instance_run(s->instance, in->nb_samples);
222 
223  if (out != in)
224  av_frame_free(&in);
225 
226  return ff_filter_frame(ctx->outputs[0], out);
227 }
228 
229 static int request_frame(AVFilterLink *outlink)
230 {
231  AVFilterContext *ctx = outlink->src;
232  LV2Context *s = ctx->priv;
233  AVFrame *out;
234  int64_t t;
235 
236  if (ctx->nb_inputs)
237  return ff_request_frame(ctx->inputs[0]);
238 
239  t = av_rescale(s->pts, AV_TIME_BASE, s->sample_rate);
240  if (s->duration >= 0 && t >= s->duration)
241  return AVERROR_EOF;
242 
243  out = ff_get_audio_buffer(outlink, s->nb_samples);
244  if (!out)
245  return AVERROR(ENOMEM);
246 
247  connect_ports(s, out, out);
248 
249  lilv_instance_run(s->instance, out->nb_samples);
250 
251  out->sample_rate = s->sample_rate;
252  out->pts = s->pts;
253  s->pts += s->nb_samples;
254 
255  return ff_filter_frame(outlink, out);
256 }
257 
258 static const LV2_Feature buf_size_features[3] = {
259  { LV2_BUF_SIZE__powerOf2BlockLength, NULL },
260  { LV2_BUF_SIZE__fixedBlockLength, NULL },
261  { LV2_BUF_SIZE__boundedBlockLength, NULL },
262 };
263 
264 static int config_output(AVFilterLink *outlink)
265 {
266  AVFilterContext *ctx = outlink->src;
267  LV2Context *s = ctx->priv;
268  char *p, *arg, *saveptr = NULL;
269  int i, sample_rate;
270 
272  s->map.handle = &s->uri_table;
273  s->map.map = uri_table_map;
274  s->map_feature.URI = LV2_URID_MAP_URI;
275  s->map_feature.data = &s->map;
276  s->unmap.handle = &s->uri_table;
277  s->unmap.unmap = uri_table_unmap;
278  s->unmap_feature.URI = LV2_URID_UNMAP_URI;
279  s->unmap_feature.data = &s->unmap;
280  s->features[0] = &s->map_feature;
281  s->features[1] = &s->unmap_feature;
282  s->features[2] = &buf_size_features[0];
283  s->features[3] = &buf_size_features[1];
284  s->features[4] = &buf_size_features[2];
285 
286  if (ctx->nb_inputs) {
287  AVFilterLink *inlink = ctx->inputs[0];
288 
289  outlink->format = inlink->format;
290  outlink->sample_rate = sample_rate = inlink->sample_rate;
291  if (s->nb_inputs == s->nb_outputs) {
292  outlink->channel_layout = inlink->channel_layout;
293  outlink->channels = inlink->channels;
294  }
295 
296  } else {
297  outlink->sample_rate = sample_rate = s->sample_rate;
298  outlink->time_base = (AVRational){1, s->sample_rate};
299  }
300 
301  s->instance = lilv_plugin_instantiate(s->plugin, sample_rate, s->features);
302  if (!s->instance) {
303  av_log(s, AV_LOG_ERROR, "Failed to instantiate <%s>\n", lilv_node_as_uri(lilv_plugin_get_uri(s->plugin)));
304  return AVERROR(EINVAL);
305  }
306 
307  s->mins = av_calloc(s->nb_ports, sizeof(float));
308  s->maxes = av_calloc(s->nb_ports, sizeof(float));
309  s->controls = av_calloc(s->nb_ports, sizeof(float));
310 
311  if (!s->mins || !s->maxes || !s->controls)
312  return AVERROR(ENOMEM);
313 
314  lilv_plugin_get_port_ranges_float(s->plugin, s->mins, s->maxes, s->controls);
315  s->seq_out = av_malloc(sizeof(LV2_Atom_Sequence) + 9624);
316  if (!s->seq_out)
317  return AVERROR(ENOMEM);
318 
319  if (s->options && !strcmp(s->options, "help")) {
320  if (!s->nb_inputcontrols) {
321  av_log(ctx, AV_LOG_INFO,
322  "The '%s' plugin does not have any input controls.\n",
323  s->plugin_uri);
324  } else {
325  av_log(ctx, AV_LOG_INFO,
326  "The '%s' plugin has the following input controls:\n",
327  s->plugin_uri);
328  for (i = 0; i < s->nb_ports; i++) {
329  const LilvPort *port = lilv_plugin_get_port_by_index(s->plugin, i);
330  const LilvNode *symbol = lilv_port_get_symbol(s->plugin, port);
331  LilvNode *name = lilv_port_get_name(s->plugin, port);
332 
333  if (lilv_port_is_a(s->plugin, port, s->lv2_InputPort) &&
334  lilv_port_is_a(s->plugin, port, s->lv2_ControlPort)) {
335  av_log(ctx, AV_LOG_INFO, "%s\t\t<float> (from %f to %f) (default %f)\t\t%s\n",
336  lilv_node_as_string(symbol), s->mins[i], s->maxes[i], s->controls[i],
337  lilv_node_as_string(name));
338  }
339 
340  lilv_node_free(name);
341  }
342  }
343  return AVERROR_EXIT;
344  }
345 
346  p = s->options;
347  while (s->options) {
348  const LilvPort *port;
349  LilvNode *sym;
350  float val;
351  char *str, *vstr;
352  int index;
353 
354  if (!(arg = av_strtok(p, " |", &saveptr)))
355  break;
356  p = NULL;
357 
358  vstr = strstr(arg, "=");
359  if (vstr == NULL) {
360  av_log(ctx, AV_LOG_ERROR, "Invalid syntax.\n");
361  return AVERROR(EINVAL);
362  }
363 
364  vstr[0] = 0;
365  str = arg;
366  val = atof(vstr+1);
367  sym = lilv_new_string(s->world, str);
368  port = lilv_plugin_get_port_by_symbol(s->plugin, sym);
369  lilv_node_free(sym);
370  if (!port) {
371  av_log(s, AV_LOG_WARNING, "Unknown option: <%s>\n", str);
372  } else {
373  index = lilv_port_get_index(s->plugin, port);
374  s->controls[index] = val;
375  }
376  }
377 
378  if (s->nb_inputs &&
379  (lilv_plugin_has_feature(s->plugin, s->powerOf2BlockLength) ||
380  lilv_plugin_has_feature(s->plugin, s->fixedBlockLength) ||
381  lilv_plugin_has_feature(s->plugin, s->boundedBlockLength))) {
382  AVFilterLink *inlink = ctx->inputs[0];
383 
384  inlink->partial_buf_size = inlink->min_samples = inlink->max_samples = 4096;
385  }
386 
387  return 0;
388 }
389 
391 {
392  LV2Context *s = ctx->priv;
393  const LilvPlugins *plugins;
394  const LilvPlugin *plugin;
395  AVFilterPad pad = { NULL };
396  LilvNode *uri;
397  int i;
398 
399  s->world = lilv_world_new();
400  if (!s->world)
401  return AVERROR(ENOMEM);
402 
403  uri = lilv_new_uri(s->world, s->plugin_uri);
404  if (!uri) {
405  av_log(s, AV_LOG_ERROR, "Invalid plugin URI <%s>\n", s->plugin_uri);
406  return AVERROR(EINVAL);
407  }
408 
409  lilv_world_load_all(s->world);
410  plugins = lilv_world_get_all_plugins(s->world);
411  plugin = lilv_plugins_get_by_uri(plugins, uri);
412  lilv_node_free(uri);
413 
414  if (!plugin) {
415  av_log(s, AV_LOG_ERROR, "Plugin <%s> not found\n", s->plugin_uri);
416  return AVERROR(EINVAL);
417  }
418 
419  s->plugin = plugin;
420  s->nb_ports = lilv_plugin_get_num_ports(s->plugin);
421 
422  s->lv2_InputPort = lilv_new_uri(s->world, LV2_CORE__InputPort);
423  s->lv2_OutputPort = lilv_new_uri(s->world, LV2_CORE__OutputPort);
424  s->lv2_AudioPort = lilv_new_uri(s->world, LV2_CORE__AudioPort);
425  s->lv2_ControlPort = lilv_new_uri(s->world, LV2_CORE__ControlPort);
426  s->lv2_Optional = lilv_new_uri(s->world, LV2_CORE__connectionOptional);
427  s->atom_AtomPort = lilv_new_uri(s->world, LV2_ATOM__AtomPort);
428  s->atom_Sequence = lilv_new_uri(s->world, LV2_ATOM__Sequence);
429  s->urid_map = lilv_new_uri(s->world, LV2_URID__map);
430  s->powerOf2BlockLength = lilv_new_uri(s->world, LV2_BUF_SIZE__powerOf2BlockLength);
431  s->fixedBlockLength = lilv_new_uri(s->world, LV2_BUF_SIZE__fixedBlockLength);
432  s->boundedBlockLength = lilv_new_uri(s->world, LV2_BUF_SIZE__boundedBlockLength);
433 
434  for (i = 0; i < s->nb_ports; i++) {
435  const LilvPort *lport = lilv_plugin_get_port_by_index(s->plugin, i);
436  int is_input = 0;
437  int is_optional = 0;
438 
439  is_optional = lilv_port_has_property(s->plugin, lport, s->lv2_Optional);
440 
441  if (lilv_port_is_a(s->plugin, lport, s->lv2_InputPort)) {
442  is_input = 1;
443  } else if (!lilv_port_is_a(s->plugin, lport, s->lv2_OutputPort) && !is_optional) {
444  return AVERROR(EINVAL);
445  }
446 
447  if (lilv_port_is_a(s->plugin, lport, s->lv2_ControlPort)) {
448  if (is_input) {
449  s->nb_inputcontrols++;
450  }
451  } else if (lilv_port_is_a(s->plugin, lport, s->lv2_AudioPort)) {
452  if (is_input) {
453  s->nb_inputs++;
454  } else {
455  s->nb_outputs++;
456  }
457  }
458  }
459 
460  pad.type = AVMEDIA_TYPE_AUDIO;
461 
462  if (s->nb_inputs) {
463  pad.name = av_asprintf("in0:%s:%u", s->plugin_uri, s->nb_inputs);
464  if (!pad.name)
465  return AVERROR(ENOMEM);
466 
468  if (ff_insert_inpad(ctx, ctx->nb_inputs, &pad) < 0) {
469  av_freep(&pad.name);
470  return AVERROR(ENOMEM);
471  }
472  }
473 
474  return 0;
475 }
476 
478 {
479  LV2Context *s = ctx->priv;
482  AVFilterLink *outlink = ctx->outputs[0];
483  static const enum AVSampleFormat sample_fmts[] = {
485  int ret;
486 
487  formats = ff_make_format_list(sample_fmts);
488  if (!formats)
489  return AVERROR(ENOMEM);
490  ret = ff_set_common_formats(ctx, formats);
491  if (ret < 0)
492  return ret;
493 
494  if (s->nb_inputs) {
495  formats = ff_all_samplerates();
496  if (!formats)
497  return AVERROR(ENOMEM);
498 
499  ret = ff_set_common_samplerates(ctx, formats);
500  if (ret < 0)
501  return ret;
502  } else {
503  int sample_rates[] = { s->sample_rate, -1 };
504 
505  ret = ff_set_common_samplerates(ctx, ff_make_format_list(sample_rates));
506  if (ret < 0)
507  return ret;
508  }
509 
510  if (s->nb_inputs == 2 && s->nb_outputs == 2) {
511  layouts = NULL;
513  if (ret < 0)
514  return ret;
515  ret = ff_set_common_channel_layouts(ctx, layouts);
516  if (ret < 0)
517  return ret;
518  } else {
519  if (s->nb_inputs >= 1) {
520  AVFilterLink *inlink = ctx->inputs[0];
521  uint64_t inlayout = FF_COUNT2LAYOUT(s->nb_inputs);
522 
523  layouts = NULL;
524  ret = ff_add_channel_layout(&layouts, inlayout);
525  if (ret < 0)
526  return ret;
527  ret = ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts);
528  if (ret < 0)
529  return ret;
530 
531  if (!s->nb_outputs) {
532  ret = ff_channel_layouts_ref(layouts, &outlink->in_channel_layouts);
533  if (ret < 0)
534  return ret;
535  }
536  }
537 
538  if (s->nb_outputs >= 1) {
539  uint64_t outlayout = FF_COUNT2LAYOUT(s->nb_outputs);
540 
541  layouts = NULL;
542  ret = ff_add_channel_layout(&layouts, outlayout);
543  if (ret < 0)
544  return ret;
545  ret = ff_channel_layouts_ref(layouts, &outlink->in_channel_layouts);
546  if (ret < 0)
547  return ret;
548  }
549  }
550 
551  return 0;
552 }
553 
555 {
556  LV2Context *s = ctx->priv;
557 
558  lilv_node_free(s->powerOf2BlockLength);
559  lilv_node_free(s->fixedBlockLength);
560  lilv_node_free(s->boundedBlockLength);
561  lilv_node_free(s->urid_map);
562  lilv_node_free(s->atom_Sequence);
563  lilv_node_free(s->atom_AtomPort);
564  lilv_node_free(s->lv2_Optional);
565  lilv_node_free(s->lv2_ControlPort);
566  lilv_node_free(s->lv2_AudioPort);
567  lilv_node_free(s->lv2_OutputPort);
568  lilv_node_free(s->lv2_InputPort);
570  lilv_instance_free(s->instance);
571  lilv_world_free(s->world);
572  av_freep(&s->mins);
573  av_freep(&s->maxes);
574  av_freep(&s->controls);
575  av_freep(&s->seq_out);
576 
577  if (ctx->nb_inputs)
578  av_freep(&ctx->input_pads[0].name);
579 }
580 
581 static const AVFilterPad lv2_outputs[] = {
582  {
583  .name = "default",
584  .type = AVMEDIA_TYPE_AUDIO,
585  .config_props = config_output,
586  .request_frame = request_frame,
587  },
588  { NULL }
589 };
590 
592  .name = "lv2",
593  .description = NULL_IF_CONFIG_SMALL("Apply LV2 effect."),
594  .priv_size = sizeof(LV2Context),
595  .priv_class = &lv2_class,
596  .init = init,
597  .uninit = uninit,
599  .inputs = 0,
600  .outputs = lv2_outputs,
602 };
static void connect_ports(LV2Context *s, AVFrame *in, AVFrame *out)
Definition: af_lv2.c:168
float, planar
Definition: samplefmt.h:69
#define NULL
Definition: coverity.c:32
int ff_set_common_channel_layouts(AVFilterContext *ctx, AVFilterChannelLayouts *layouts)
A helper for query_formats() which sets all links to the same list of channel layouts/sample rates...
Definition: formats.c:550
const char const char void * val
Definition: avisynth_c.h:863
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
LilvInstance * instance
Definition: af_lv2.c:75
AVOption.
Definition: opt.h:246
#define OFFSET(x)
Definition: af_lv2.c:91
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
Main libavfilter public API header.
LilvNode * lv2_ControlPort
Definition: af_lv2.c:81
LV2_URID_Unmap unmap
Definition: af_lv2.c:65
#define AVFILTER_FLAG_DYNAMIC_INPUTS
The number of the filter inputs is not determined just by AVFilter.inputs.
Definition: avfilter.h:105
char * options
Definition: af_lv2.c:47
static int query_formats(AVFilterContext *ctx)
Definition: af_lv2.c:477
enum AVMediaType type
AVFilterPad type.
Definition: internal.h:65
unsigned nb_inputs
Definition: af_lv2.c:49
LilvWorld * world
Definition: af_lv2.c:58
#define AV_CH_LAYOUT_STEREO
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
Definition: mem.c:244
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:283
const char * name
Pad name.
Definition: internal.h:60
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:346
int ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts **ref)
Add *ref as a new reference to f.
Definition: formats.c:434
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1093
static const AVOption lv2_options[]
Definition: af_lv2.c:94
#define av_cold
Definition: attributes.h:82
#define av_malloc(s)
AVOptions.
static av_cold void uninit(AVFilterContext *ctx)
Definition: af_lv2.c:554
static const AVFilterPad lv2_outputs[]
Definition: af_lv2.c:581
size_t n_uris
Definition: af_lv2.c:41
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:388
LilvNode * lv2_Optional
Definition: af_lv2.c:82
int64_t duration
Definition: movenc.c:63
const LV2_Feature * features[5]
Definition: af_lv2.c:69
#define AVERROR_EOF
End of file.
Definition: error.h:55
#define av_log(a,...)
static const uint16_t table[]
Definition: prosumer.c:206
LilvNode * lv2_AudioPort
Definition: af_lv2.c:79
#define FLAGS
Definition: af_lv2.c:92
A filter pad used for either input or output.
Definition: internal.h:54
static void uri_table_init(URITable *table)
Definition: af_lv2.c:110
AVFilterPad * input_pads
array of input pads
Definition: avfilter.h:345
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
A helper for query_formats() which sets all links to the same list of formats.
Definition: formats.c:569
int ff_add_channel_layout(AVFilterChannelLayouts **l, uint64_t channel_layout)
Definition: formats.c:342
AVFrame * ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
Request an audio samples buffer with a specific set of permissions.
Definition: audio.c:86
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:202
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
LilvNode * fixedBlockLength
Definition: af_lv2.c:87
void * priv
private data for use by the filter
Definition: avfilter.h:353
const char * arg
Definition: jacosubdec.c:66
simple assert() macros that are a bit more flexible than ISO C assert().
int64_t duration
Definition: af_lv2.c:56
unsigned nb_outputs
Definition: af_lv2.c:51
static int request_frame(AVFilterLink *outlink)
Definition: af_lv2.c:229
char * av_asprintf(const char *fmt,...)
Definition: avstring.c:113
int64_t pts
Definition: af_lv2.c:55
audio channel layout utility functions
unsigned nb_inputs
number of input pads
Definition: avfilter.h:347
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
Definition: mathematics.c:129
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:254
LilvNode * boundedBlockLength
Definition: af_lv2.c:88
AVFormatContext * ctx
Definition: movenc.c:48
LilvNode * lv2_InputPort
Definition: af_lv2.c:83
LV2_URID_Map map
Definition: af_lv2.c:63
#define s(width, name)
Definition: cbs_vp9.c:257
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: af_lv2.c:201
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
Definition: error.h:56
LilvNode * atom_AtomPort
Definition: af_lv2.c:77
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
A list of supported channel layouts.
Definition: formats.h:85
unsigned nb_inputcontrols
Definition: af_lv2.c:50
sample_rate
#define AV_LOG_INFO
Standard information.
Definition: log.h:187
LilvNode * lv2_CVPort
Definition: af_lv2.c:80
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
int av_frame_is_writable(AVFrame *frame)
Check if the frame data is writable.
Definition: frame.c:594
URITable uri_table
Definition: af_lv2.c:62
LV2_Atom_Sequence * seq_out
Definition: af_lv2.c:68
LilvNode * urid_map
Definition: af_lv2.c:85
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several inputs
LilvNode * atom_Sequence
Definition: af_lv2.c:78
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31))))#define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac){}void ff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map){AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);return NULL;}return ac;}in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;}int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){int use_generic=1;int len=in->nb_samples;int p;if(ac->dc){av_log(ac->avr, AV_LOG_TRACE,"%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
static void uri_table_destroy(URITable *table)
Definition: af_lv2.c:116
Describe the class of an AVClass context structure.
Definition: log.h:67
int sample_rate
Sample rate of the audio data.
Definition: frame.h:467
Filter definition.
Definition: avfilter.h:144
int index
Definition: gxfenc.c:89
Rational number (pair of numerator and denominator).
Definition: rational.h:58
char * plugin_uri
Definition: af_lv2.c:46
LV2_Feature map_feature
Definition: af_lv2.c:64
const char * name
Filter name.
Definition: avfilter.h:148
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:350
enum MovChannelLayoutTag * layouts
Definition: mov_chan.c:434
static LV2_URID uri_table_map(LV2_URID_Map_Handle handle, const char *uri)
Definition: af_lv2.c:127
AVFilterFormats * ff_all_samplerates(void)
Definition: formats.c:394
uint32_t nb_ports
Definition: af_lv2.c:60
float * mins
Definition: af_lv2.c:71
#define flags(name, subs,...)
Definition: cbs_av1.c:561
int(* filter_frame)(AVFilterLink *link, AVFrame *frame)
Filtering callback.
Definition: internal.h:93
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
char * av_strtok(char *s, const char *delim, char **saveptr)
Split the string into several tokens which can be accessed by successive calls to av_strtok()...
Definition: avstring.c:184
LV2_Atom_Sequence seq_in[2]
Definition: af_lv2.c:67
const OptionDef options[]
Definition: ffmpeg_opt.c:3374
sample_rates
float * controls
Definition: af_lv2.c:73
static int config_output(AVFilterLink *outlink)
Definition: af_lv2.c:264
AVFilter ff_af_lv2
Definition: af_lv2.c:591
static const LV2_Feature buf_size_features[3]
Definition: af_lv2.c:258
LilvNode * powerOf2BlockLength
Definition: af_lv2.c:86
const LilvPlugin * plugin
Definition: af_lv2.c:59
float * values
Definition: af_lv2.c:61
#define av_free(p)
int len
AVFILTER_DEFINE_CLASS(lv2)
char ** uris
Definition: af_lv2.c:40
A list of supported formats for one end of a filter link.
Definition: formats.h:64
float * maxes
Definition: af_lv2.c:72
LilvNode * lv2_OutputPort
Definition: af_lv2.c:84
int nb_samples
Definition: af_lv2.c:54
An instance of a filter.
Definition: avfilter.h:338
int sample_rate
Definition: af_lv2.c:53
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:701
LV2_Feature unmap_feature
Definition: af_lv2.c:66
FILE * out
Definition: movenc.c:54
#define av_freep(p)
#define FF_COUNT2LAYOUT(c)
Encode a channel count as a channel layout.
Definition: formats.h:102
int ff_request_frame(AVFilterLink *link)
Request an input frame from the filter at the other end of the link.
Definition: avfilter.c:407
formats
Definition: signature.h:48
internal API functions
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:342
static const char * uri_table_unmap(LV2_URID_Map_Handle handle, LV2_URID urid)
Definition: af_lv2.c:157
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:361
int ff_set_common_samplerates(AVFilterContext *ctx, AVFilterFormats *samplerates)
Definition: formats.c:557
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:654
static av_cold int init(AVFilterContext *ctx)
Definition: af_lv2.c:390
const char * name
Definition: opengl_enc.c:102
static int ff_insert_inpad(AVFilterContext *f, unsigned index, AVFilterPad *p)
Insert a new input pad for the filter.
Definition: internal.h:277
static uint8_t tmp[11]
Definition: aes_ctr.c:26