FFmpeg
aeval.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011 Stefano Sabatini
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 /**
22  * @file
23  * eval audio source
24  */
25 
26 #include "libavutil/avassert.h"
27 #include "libavutil/avstring.h"
29 #include "libavutil/eval.h"
30 #include "libavutil/opt.h"
31 #include "libavutil/parseutils.h"
32 #include "avfilter.h"
33 #include "audio.h"
34 #include "internal.h"
35 
36 static const char * const var_names[] = {
37  "ch", ///< the value of the current channel
38  "n", ///< number of frame
39  "nb_in_channels",
40  "nb_out_channels",
41  "t", ///< timestamp expressed in seconds
42  "s", ///< sample rate
43  NULL
44 };
45 
46 enum var_name {
54 };
55 
56 typedef struct EvalContext {
57  const AVClass *class;
60  int64_t chlayout;
61  char *chlayout_str;
62  int nb_channels; ///< number of output channels
63  int nb_in_channels; ///< number of input channels
64  int same_chlayout; ///< set output as input channel layout
65  int64_t pts;
67  char *exprs;
68  int nb_samples; ///< number of samples per requested frame
69  int64_t duration;
70  uint64_t n;
72  double *channel_values;
74 } EvalContext;
75 
76 static double val(void *priv, double ch)
77 {
78  EvalContext *eval = priv;
79  return eval->channel_values[FFMIN((int)ch, eval->nb_in_channels-1)];
80 }
81 
82 static double (* const aeval_func1[])(void *, double) = { val, NULL };
83 static const char * const aeval_func1_names[] = { "val", NULL };
84 
85 #define OFFSET(x) offsetof(EvalContext, x)
86 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
87 
88 static const AVOption aevalsrc_options[]= {
89  { "exprs", "set the '|'-separated list of channels expressions", OFFSET(exprs), AV_OPT_TYPE_STRING, {.str = NULL}, .flags = FLAGS },
90  { "nb_samples", "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64 = 1024}, 0, INT_MAX, FLAGS },
91  { "n", "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64 = 1024}, 0, INT_MAX, FLAGS },
92  { "sample_rate", "set the sample rate", OFFSET(sample_rate_str), AV_OPT_TYPE_STRING, {.str = "44100"}, CHAR_MIN, CHAR_MAX, FLAGS },
93  { "s", "set the sample rate", OFFSET(sample_rate_str), AV_OPT_TYPE_STRING, {.str = "44100"}, CHAR_MIN, CHAR_MAX, FLAGS },
94  { "duration", "set audio duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = -1}, -1, INT64_MAX, FLAGS },
95  { "d", "set audio duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = -1}, -1, INT64_MAX, FLAGS },
96  { "channel_layout", "set channel layout", OFFSET(chlayout_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
97  { "c", "set channel layout", OFFSET(chlayout_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
98  { NULL }
99 };
100 
101 AVFILTER_DEFINE_CLASS(aevalsrc);
102 
104  int expected_nb_channels)
105 {
106  EvalContext *eval = ctx->priv;
107  char *args1 = av_strdup(eval->exprs);
108  char *expr, *last_expr = NULL, *buf;
109  double (* const *func1)(void *, double) = NULL;
110  const char * const *func1_names = NULL;
111  int i, ret = 0;
112 
113  if (!args1)
114  return AVERROR(ENOMEM);
115 
116  if (!eval->exprs) {
117  av_log(ctx, AV_LOG_ERROR, "Channels expressions list is empty\n");
118  return AVERROR(EINVAL);
119  }
120 
121  if (!strcmp(ctx->filter->name, "aeval")) {
122  func1 = aeval_func1;
123  func1_names = aeval_func1_names;
124  }
125 
126 #define ADD_EXPRESSION(expr_) do { \
127  if (!av_dynarray2_add((void **)&eval->expr, &eval->nb_channels, \
128  sizeof(*eval->expr), NULL)) { \
129  ret = AVERROR(ENOMEM); \
130  goto end; \
131  } \
132  eval->expr[eval->nb_channels-1] = NULL; \
133  ret = av_expr_parse(&eval->expr[eval->nb_channels - 1], expr_, \
134  var_names, func1_names, func1, \
135  NULL, NULL, 0, ctx); \
136  if (ret < 0) \
137  goto end; \
138  } while (0)
139 
140  /* reset expressions */
141  for (i = 0; i < eval->nb_channels; i++) {
142  av_expr_free(eval->expr[i]);
143  eval->expr[i] = NULL;
144  }
145  av_freep(&eval->expr);
146  eval->nb_channels = 0;
147 
148  buf = args1;
149  while (expr = av_strtok(buf, "|", &buf)) {
150  ADD_EXPRESSION(expr);
151  last_expr = expr;
152  }
153 
154  if (expected_nb_channels > eval->nb_channels)
155  for (i = eval->nb_channels; i < expected_nb_channels; i++)
156  ADD_EXPRESSION(last_expr);
157 
158  if (expected_nb_channels > 0 && eval->nb_channels != expected_nb_channels) {
159  av_log(ctx, AV_LOG_ERROR,
160  "Mismatch between the specified number of channel expressions '%d' "
161  "and the number of expected output channels '%d' for the specified channel layout\n",
162  eval->nb_channels, expected_nb_channels);
163  ret = AVERROR(EINVAL);
164  goto end;
165  }
166 
167 end:
168  av_free(args1);
169  return ret;
170 }
171 
173 {
174  EvalContext *eval = ctx->priv;
175  int ret = 0;
176 
177  if (eval->chlayout_str) {
178  if (!strcmp(eval->chlayout_str, "same") && !strcmp(ctx->filter->name, "aeval")) {
179  eval->same_chlayout = 1;
180  } else {
181  ret = ff_parse_channel_layout(&eval->chlayout, NULL, eval->chlayout_str, ctx);
182  if (ret < 0)
183  return ret;
184 
186  if (ret < 0)
187  return ret;
188  }
189  } else {
190  /* guess channel layout from nb expressions/channels */
191  if ((ret = parse_channel_expressions(ctx, -1)) < 0)
192  return ret;
193 
195  if (!eval->chlayout && eval->nb_channels <= 0) {
196  av_log(ctx, AV_LOG_ERROR, "Invalid number of channels '%d' provided\n",
197  eval->nb_channels);
198  return AVERROR(EINVAL);
199  }
200  }
201 
202  if (eval->sample_rate_str)
203  if ((ret = ff_parse_sample_rate(&eval->sample_rate, eval->sample_rate_str, ctx)))
204  return ret;
205  eval->n = 0;
206 
207  return ret;
208 }
209 
211 {
212  EvalContext *eval = ctx->priv;
213  int i;
214 
215  for (i = 0; i < eval->nb_channels; i++) {
216  av_expr_free(eval->expr[i]);
217  eval->expr[i] = NULL;
218  }
219  av_freep(&eval->expr);
220  av_freep(&eval->channel_values);
221 }
222 
223 static int config_props(AVFilterLink *outlink)
224 {
225  EvalContext *eval = outlink->src->priv;
226  char buf[128];
227 
228  outlink->time_base = (AVRational){1, eval->sample_rate};
229  outlink->sample_rate = eval->sample_rate;
230 
231  eval->var_values[VAR_S] = eval->sample_rate;
233  eval->var_values[VAR_NB_OUT_CHANNELS] = outlink->channels;
234 
235  av_get_channel_layout_string(buf, sizeof(buf), 0, eval->chlayout);
236 
237  av_log(outlink->src, AV_LOG_VERBOSE,
238  "sample_rate:%d chlayout:%s duration:%"PRId64"\n",
239  eval->sample_rate, buf, eval->duration);
240 
241  return 0;
242 }
243 
245 {
246  EvalContext *eval = ctx->priv;
248  int64_t chlayouts[] = { eval->chlayout ? eval->chlayout : FF_COUNT2LAYOUT(eval->nb_channels) , -1 };
249  int sample_rates[] = { eval->sample_rate, -1 };
252  int ret;
253 
254  formats = ff_make_format_list(sample_fmts);
255  if (!formats)
256  return AVERROR(ENOMEM);
257  ret = ff_set_common_formats (ctx, formats);
258  if (ret < 0)
259  return ret;
260 
261  layouts = avfilter_make_format64_list(chlayouts);
262  if (!layouts)
263  return AVERROR(ENOMEM);
264  ret = ff_set_common_channel_layouts(ctx, layouts);
265  if (ret < 0)
266  return ret;
267 
268  formats = ff_make_format_list(sample_rates);
269  if (!formats)
270  return AVERROR(ENOMEM);
271  return ff_set_common_samplerates(ctx, formats);
272 }
273 
274 static int request_frame(AVFilterLink *outlink)
275 {
276  EvalContext *eval = outlink->src->priv;
277  AVFrame *samplesref;
278  int i, j;
279  int64_t t = av_rescale(eval->n, AV_TIME_BASE, eval->sample_rate);
280  int nb_samples;
281 
282  if (eval->duration >= 0 && t >= eval->duration)
283  return AVERROR_EOF;
284 
285  if (eval->duration >= 0) {
286  nb_samples = FFMIN(eval->nb_samples, av_rescale(eval->duration, eval->sample_rate, AV_TIME_BASE) - eval->pts);
287  if (!nb_samples)
288  return AVERROR_EOF;
289  } else {
290  nb_samples = eval->nb_samples;
291  }
292  samplesref = ff_get_audio_buffer(outlink, nb_samples);
293  if (!samplesref)
294  return AVERROR(ENOMEM);
295 
296  /* evaluate expression for each single sample and for each channel */
297  for (i = 0; i < nb_samples; i++, eval->n++) {
298  eval->var_values[VAR_N] = eval->n;
299  eval->var_values[VAR_T] = eval->var_values[VAR_N] * (double)1/eval->sample_rate;
300 
301  for (j = 0; j < eval->nb_channels; j++) {
302  *((double *) samplesref->extended_data[j] + i) =
303  av_expr_eval(eval->expr[j], eval->var_values, NULL);
304  }
305  }
306 
307  samplesref->pts = eval->pts;
308  samplesref->sample_rate = eval->sample_rate;
309  eval->pts += nb_samples;
310 
311  return ff_filter_frame(outlink, samplesref);
312 }
313 
314 #if CONFIG_AEVALSRC_FILTER
315 static const AVFilterPad aevalsrc_outputs[] = {
316  {
317  .name = "default",
318  .type = AVMEDIA_TYPE_AUDIO,
319  .config_props = config_props,
320  .request_frame = request_frame,
321  },
322  { NULL }
323 };
324 
326  .name = "aevalsrc",
327  .description = NULL_IF_CONFIG_SMALL("Generate an audio signal generated by an expression."),
328  .query_formats = query_formats,
329  .init = init,
330  .uninit = uninit,
331  .priv_size = sizeof(EvalContext),
332  .inputs = NULL,
333  .outputs = aevalsrc_outputs,
334  .priv_class = &aevalsrc_class,
335 };
336 
337 #endif /* CONFIG_AEVALSRC_FILTER */
338 
339 #define OFFSET(x) offsetof(EvalContext, x)
340 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
341 
342 static const AVOption aeval_options[]= {
343  { "exprs", "set the '|'-separated list of channels expressions", OFFSET(exprs), AV_OPT_TYPE_STRING, {.str = NULL}, .flags = FLAGS },
344  { "channel_layout", "set channel layout", OFFSET(chlayout_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
345  { "c", "set channel layout", OFFSET(chlayout_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
346  { NULL }
347 };
348 
349 AVFILTER_DEFINE_CLASS(aeval);
350 
352 {
355  AVFilterLink *inlink = ctx->inputs[0];
356  AVFilterLink *outlink = ctx->outputs[0];
357  EvalContext *eval = ctx->priv;
358  static const enum AVSampleFormat sample_fmts[] = {
360  };
361  int ret;
362 
363  // inlink supports any channel layout
364  layouts = ff_all_channel_counts();
365  if ((ret = ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts)) < 0)
366  return ret;
367 
368  if (eval->same_chlayout) {
369  layouts = ff_all_channel_counts();
370  if ((ret = ff_set_common_channel_layouts(ctx, layouts)) < 0)
371  return ret;
372  } else {
373  // outlink supports only requested output channel layout
374  layouts = NULL;
375  if ((ret = ff_add_channel_layout(&layouts,
376  eval->out_channel_layout ? eval->out_channel_layout :
377  FF_COUNT2LAYOUT(eval->nb_channels))) < 0)
378  return ret;
379  if ((ret = ff_channel_layouts_ref(layouts, &outlink->in_channel_layouts)) < 0)
380  return ret;
381  }
382 
383  formats = ff_make_format_list(sample_fmts);
384  if ((ret = ff_set_common_formats(ctx, formats)) < 0)
385  return ret;
386 
387  formats = ff_all_samplerates();
388  return ff_set_common_samplerates(ctx, formats);
389 }
390 
391 static int aeval_config_output(AVFilterLink *outlink)
392 {
393  AVFilterContext *ctx = outlink->src;
394  EvalContext *eval = ctx->priv;
395  AVFilterLink *inlink = ctx->inputs[0];
396  int ret;
397 
398  if (eval->same_chlayout) {
399  eval->chlayout = inlink->channel_layout;
400 
401  if ((ret = parse_channel_expressions(ctx, inlink->channels)) < 0)
402  return ret;
403  }
404 
405  eval->n = 0;
406  eval->nb_in_channels = eval->var_values[VAR_NB_IN_CHANNELS] = inlink->channels;
407  eval->var_values[VAR_NB_OUT_CHANNELS] = outlink->channels;
408  eval->var_values[VAR_S] = inlink->sample_rate;
409  eval->var_values[VAR_T] = NAN;
410 
412  inlink->channels, sizeof(*eval->channel_values));
413  if (!eval->channel_values)
414  return AVERROR(ENOMEM);
415 
416  return 0;
417 }
418 
419 #define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)*av_q2d(tb))
420 
422 {
423  EvalContext *eval = inlink->dst->priv;
424  AVFilterLink *outlink = inlink->dst->outputs[0];
425  int nb_samples = in->nb_samples;
426  AVFrame *out;
427  double t0;
428  int i, j;
429 
430  out = ff_get_audio_buffer(outlink, nb_samples);
431  if (!out) {
432  av_frame_free(&in);
433  return AVERROR(ENOMEM);
434  }
435  av_frame_copy_props(out, in);
436 
437  t0 = TS2T(in->pts, inlink->time_base);
438 
439  /* evaluate expression for each single sample and for each channel */
440  for (i = 0; i < nb_samples; i++, eval->n++) {
441  eval->var_values[VAR_N] = eval->n;
442  eval->var_values[VAR_T] = t0 + i * (double)1/inlink->sample_rate;
443 
444  for (j = 0; j < inlink->channels; j++)
445  eval->channel_values[j] = *((double *) in->extended_data[j] + i);
446 
447  for (j = 0; j < outlink->channels; j++) {
448  eval->var_values[VAR_CH] = j;
449  *((double *) out->extended_data[j] + i) =
450  av_expr_eval(eval->expr[j], eval->var_values, eval);
451  }
452  }
453 
454  av_frame_free(&in);
455  return ff_filter_frame(outlink, out);
456 }
457 
458 #if CONFIG_AEVAL_FILTER
459 
460 static const AVFilterPad aeval_inputs[] = {
461  {
462  .name = "default",
463  .type = AVMEDIA_TYPE_AUDIO,
464  .filter_frame = filter_frame,
465  },
466  { NULL }
467 };
468 
469 static const AVFilterPad aeval_outputs[] = {
470  {
471  .name = "default",
472  .type = AVMEDIA_TYPE_AUDIO,
473  .config_props = aeval_config_output,
474  },
475  { NULL }
476 };
477 
479  .name = "aeval",
480  .description = NULL_IF_CONFIG_SMALL("Filter audio signal according to a specified expression."),
481  .query_formats = aeval_query_formats,
482  .init = init,
483  .uninit = uninit,
484  .priv_size = sizeof(EvalContext),
485  .inputs = aeval_inputs,
486  .outputs = aeval_outputs,
487  .priv_class = &aeval_class,
488 };
489 
490 #endif /* CONFIG_AEVAL_FILTER */
#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:549
char * exprs
Definition: aeval.c:67
static const char *const func1_names[]
Definition: vf_rotate.c:195
static int aeval_config_output(AVFilterLink *outlink)
Definition: aeval.c:391
#define av_realloc_f(p, o, n)
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
static int aeval_query_formats(AVFilterContext *ctx)
Definition: aeval.c:351
AVOption.
Definition: opt.h:246
Definition: aeval.c:48
Main libavfilter public API header.
int64_t duration
Definition: aeval.c:69
AVExpr ** expr
Definition: aeval.c:66
uint8_t pi<< 24) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_U8,(uint64_t)((*(const uint8_t *) pi-0x80U))<< 56) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16,(*(const int16_t *) pi >>8)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S16,(uint64_t)(*(const int16_t *) pi)<< 48) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16,*(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16,*(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32,(*(const int32_t *) pi >>24)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S32,(uint64_t)(*(const int32_t *) pi)<< 32) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32,*(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32,*(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S64,(*(const int64_t *) pi >>56)+0x80) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S64,*(const int64_t *) pi *(1.0f/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S64,*(const int64_t *) pi *(1.0/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_FLT, llrintf(*(const float *) pi *(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_DBL, llrint(*(const double *) pi *(INT64_C(1)<< 63)))#define FMT_PAIR_FUNC(out, in) static conv_func_type *const fmt_pair_to_conv_functions[AV_SAMPLE_FMT_NB *AV_SAMPLE_FMT_NB]={FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S64),};static void cpy1(uint8_t **dst, const uint8_t **src, int len){memcpy(*dst,*src, len);}static void cpy2(uint8_t **dst, const uint8_t **src, int len){memcpy(*dst,*src, 2 *len);}static void cpy4(uint8_t **dst, const uint8_t **src, int len){memcpy(*dst,*src, 4 *len);}static void cpy8(uint8_t **dst, const uint8_t **src, int len){memcpy(*dst,*src, 8 *len);}AudioConvert *swri_audio_convert_alloc(enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, const int *ch_map, int flags){AudioConvert *ctx;conv_func_type *f=fmt_pair_to_conv_functions[av_get_packed_sample_fmt(out_fmt)+AV_SAMPLE_FMT_NB *av_get_packed_sample_fmt(in_fmt)];if(!f) return NULL;ctx=av_mallocz(sizeof(*ctx));if(!ctx) return NULL;if(channels==1){in_fmt=av_get_planar_sample_fmt(in_fmt);out_fmt=av_get_planar_sample_fmt(out_fmt);}ctx->channels=channels;ctx->conv_f=f;ctx->ch_map=ch_map;if(in_fmt==AV_SAMPLE_FMT_U8||in_fmt==AV_SAMPLE_FMT_U8P) memset(ctx->silence, 0x80, sizeof(ctx->silence));if(out_fmt==in_fmt &&!ch_map){switch(av_get_bytes_per_sample(in_fmt)){case 1:ctx->simd_f=cpy1;break;case 2:ctx->simd_f=cpy2;break;case 4:ctx->simd_f=cpy4;break;case 8:ctx->simd_f=cpy8;break;}}if(HAVE_X86ASM &&1) swri_audio_convert_init_x86(ctx, out_fmt, in_fmt, channels);if(ARCH_ARM) swri_audio_convert_init_arm(ctx, out_fmt, in_fmt, channels);if(ARCH_AARCH64) swri_audio_convert_init_aarch64(ctx, out_fmt, in_fmt, channels);return ctx;}void swri_audio_convert_free(AudioConvert **ctx){av_freep(ctx);}int swri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, int len){int ch;int off=0;const int os=(out->planar?1:out->ch_count)*out->bps;unsigned misaligned=0;av_assert0(ctx->channels==out->ch_count);if(ctx->in_simd_align_mask){int planes=in->planar?in->ch_count:1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) in->ch[ch];misaligned|=m &ctx->in_simd_align_mask;}if(ctx->out_simd_align_mask){int planes=out->planar?out->ch_count:1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) out->ch[ch];misaligned|=m &ctx->out_simd_align_mask;}if(ctx->simd_f &&!ctx->ch_map &&!misaligned){off=len &~15;av_assert1(off >=0);av_assert1(off<=len);av_assert2(ctx->channels==SWR_CH_MAX||!in->ch[ctx->channels]);if(off >0){if(out->planar==in->planar){int planes=out->planar?out->ch_count:1;for(ch=0;ch< planes;ch++){ctx->simd_f(out-> ch ch
Definition: audioconvert.c:56
static const char *const aeval_func1_names[]
Definition: aeval.c:83
static av_cold void uninit(AVFilterContext *ctx)
Definition: aeval.c:210
double, planar
Definition: samplefmt.h:70
double * channel_values
Definition: aeval.c:72
char * chlayout_str
Definition: aeval.c:61
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:283
int av_get_channel_layout_nb_channels(uint64_t channel_layout)
Return the number of channels in the channel layout.
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:435
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1080
int64_t out_channel_layout
Definition: aeval.c:73
#define av_cold
Definition: attributes.h:82
AVOptions.
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
int nb_samples
number of samples per requested frame
Definition: aeval.c:68
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:388
Definition: eval.c:157
int64_t pts
Definition: aeval.c:65
#define t0
Definition: regdef.h:28
static double(*const aeval_func1[])(void *, double)
Definition: aeval.c:82
#define AVERROR_EOF
End of file.
Definition: error.h:55
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:192
static const char *const var_names[]
Definition: aeval.c:36
static const AVOption aeval_options[]
Definition: aeval.c:342
#define av_log(a,...)
A filter pad used for either input or output.
Definition: internal.h:54
#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:568
int ff_add_channel_layout(AVFilterChannelLayouts **l, uint64_t channel_layout)
Definition: formats.c:343
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
Definition: aeval.c:52
static double(*const func1[])(void *, double)
Definition: vf_rotate.c:189
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
void * priv
private data for use by the filter
Definition: avfilter.h:353
int ff_parse_channel_layout(int64_t *ret, int *nret, const char *arg, void *log_ctx)
Parse a channel layout or a corresponding integer representation.
Definition: formats.c:662
uint64_t n
Definition: aeval.c:70
simple assert() macros that are a bit more flexible than ISO C assert().
int64_t chlayout
Definition: aeval.c:60
var_name
Definition: aeval.c:46
audio channel layout utility functions
static int request_frame(AVFilterLink *outlink)
Definition: aeval.c:274
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 NAN
Definition: mathematics.h:64
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:254
#define FFMIN(a, b)
Definition: common.h:96
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: aeval.c:421
AVFormatContext * ctx
Definition: movenc.c:48
Definition: aeval.c:51
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
A list of supported channel layouts.
Definition: formats.h:85
void av_get_channel_layout_string(char *buf, int buf_size, int nb_channels, uint64_t channel_layout)
Return a description of a channel layout.
AVFilter ff_af_aeval
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:251
AVFilterChannelLayouts * avfilter_make_format64_list(const int64_t *fmts)
Definition: formats.c:303
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
Definition: eval.c:334
int same_chlayout
set output as input channel layout
Definition: aeval.c:64
#define FLAGS
Definition: aeval.c:340
static int config_props(AVFilterLink *outlink)
Definition: aeval.c:223
char * sample_rate_str
Definition: aeval.c:58
void * buf
Definition: avisynth_c.h:766
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
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
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
Rational number (pair of numerator and denominator).
Definition: rational.h:58
AVFILTER_DEFINE_CLASS(aevalsrc)
const char * name
Filter name.
Definition: avfilter.h:148
misc parsing utilities
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:350
enum MovChannelLayoutTag * layouts
Definition: mov_chan.c:434
AVFilterFormats * ff_all_samplerates(void)
Definition: formats.c:395
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
int nb_in_channels
number of input channels
Definition: aeval.c:63
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
static const AVOption aevalsrc_options[]
Definition: aeval.c:88
static int query_formats(AVFilterContext *ctx)
Definition: aeval.c:244
sample_rates
int sample_rate
Definition: aeval.c:59
int ff_parse_sample_rate(int *ret, const char *arg, void *log_ctx)
Parse a sample rate.
Definition: formats.c:650
int nb_channels
number of output channels
Definition: aeval.c:62
#define av_free(p)
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
Evaluate a previously parsed expression.
Definition: eval.c:734
#define ADD_EXPRESSION(expr_)
A list of supported formats for one end of a filter link.
Definition: formats.h:64
An instance of a filter.
Definition: avfilter.h:338
int64_t av_get_default_channel_layout(int nb_channels)
Return default channel layout for a given number of channels.
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:701
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
formats
Definition: signature.h:48
static av_cold int init(AVFilterContext *ctx)
Definition: aeval.c:172
static int parse_channel_expressions(AVFilterContext *ctx, int expected_nb_channels)
Definition: aeval.c:103
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
AVFilterChannelLayouts * ff_all_channel_counts(void)
Construct an AVFilterChannelLayouts coding for any channel layout, with known or unknown disposition...
Definition: formats.c:410
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:342
double var_values[VAR_VARS_NB]
Definition: aeval.c:71
static double val(void *priv, double ch)
Definition: aeval.c:76
Definition: aeval.c:47
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:361
const AVFilter * filter
the AVFilter of which this is an instance
Definition: avfilter.h:341
for(j=16;j >0;--j)
int ff_set_common_samplerates(AVFilterContext *ctx, AVFilterFormats *samplerates)
Definition: formats.c:556
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:654
AVFilter ff_asrc_aevalsrc
simple arithmetic expression evaluator
#define TS2T(ts, tb)
Definition: aeval.c:419
#define OFFSET(x)
Definition: aeval.c:339