FFmpeg  4.2.1
avf_showspatial.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019 Paul B Mahol
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 #include <float.h>
22 #include <math.h>
23 
24 #include "libavcodec/avfft.h"
25 #include "libavutil/audio_fifo.h"
26 #include "libavutil/avassert.h"
28 #include "libavutil/opt.h"
29 #include "libavutil/parseutils.h"
30 #include "audio.h"
31 #include "video.h"
32 #include "avfilter.h"
33 #include "filters.h"
34 #include "internal.h"
35 #include "window_func.h"
36 
37 typedef struct ShowSpatialContext {
38  const AVClass *class;
39  int w, h;
41  FFTContext *fft[2]; ///< Fast Fourier Transform context
42  FFTContext *ifft[2]; ///< Inverse Fast Fourier Transform context
43  int fft_bits; ///< number of bits (FFT window size = 1<<fft_bits)
44  FFTComplex *fft_data[2]; ///< bins holder for each (displayed) channels
45  float *window_func_lut; ///< Window function LUT
46  int win_func;
47  int win_size;
48  int buf_size;
49  float overlap;
50  int consumed;
51  int hop_size;
53  int64_t pts;
55 
56 #define OFFSET(x) offsetof(ShowSpatialContext, x)
57 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
58 
59 static const AVOption showspatial_options[] = {
60  { "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "512x512"}, 0, 0, FLAGS },
61  { "s", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "512x512"}, 0, 0, FLAGS },
62  { "win_size", "set window size", OFFSET(win_size), AV_OPT_TYPE_INT, {.i64 = 4096}, 1024, 65536, FLAGS },
63  { "win_func", "set window function", OFFSET(win_func), AV_OPT_TYPE_INT, {.i64 = WFUNC_HANNING}, 0, NB_WFUNC-1, FLAGS, "win_func" },
64  { "rect", "Rectangular", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_RECT}, 0, 0, FLAGS, "win_func" },
65  { "bartlett", "Bartlett", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BARTLETT}, 0, 0, FLAGS, "win_func" },
66  { "hann", "Hann", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_HANNING}, 0, 0, FLAGS, "win_func" },
67  { "hanning", "Hanning", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_HANNING}, 0, 0, FLAGS, "win_func" },
68  { "hamming", "Hamming", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_HAMMING}, 0, 0, FLAGS, "win_func" },
69  { "blackman", "Blackman", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BLACKMAN}, 0, 0, FLAGS, "win_func" },
70  { "welch", "Welch", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_WELCH}, 0, 0, FLAGS, "win_func" },
71  { "flattop", "Flat-top", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_FLATTOP}, 0, 0, FLAGS, "win_func" },
72  { "bharris", "Blackman-Harris", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BHARRIS}, 0, 0, FLAGS, "win_func" },
73  { "bnuttall", "Blackman-Nuttall", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BNUTTALL}, 0, 0, FLAGS, "win_func" },
74  { "bhann", "Bartlett-Hann", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BHANN}, 0, 0, FLAGS, "win_func" },
75  { "sine", "Sine", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_SINE}, 0, 0, FLAGS, "win_func" },
76  { "nuttall", "Nuttall", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_NUTTALL}, 0, 0, FLAGS, "win_func" },
77  { "lanczos", "Lanczos", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_LANCZOS}, 0, 0, FLAGS, "win_func" },
78  { "gauss", "Gauss", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_GAUSS}, 0, 0, FLAGS, "win_func" },
79  { "tukey", "Tukey", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_TUKEY}, 0, 0, FLAGS, "win_func" },
80  { "dolph", "Dolph-Chebyshev", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_DOLPH}, 0, 0, FLAGS, "win_func" },
81  { "cauchy", "Cauchy", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_CAUCHY}, 0, 0, FLAGS, "win_func" },
82  { "parzen", "Parzen", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_PARZEN}, 0, 0, FLAGS, "win_func" },
83  { "poisson", "Poisson", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_POISSON}, 0, 0, FLAGS, "win_func" },
84  { "bohman", "Bohman", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BOHMAN}, 0, 0, FLAGS, "win_func" },
85  { "overlap", "set window overlap", OFFSET(overlap), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGS },
86  { NULL }
87 };
88 
89 AVFILTER_DEFINE_CLASS(showspatial);
90 
92 {
93  ShowSpatialContext *s = ctx->priv;
94  int i;
95 
96  for (i = 0; i < 2; i++)
97  av_fft_end(s->fft[i]);
98  for (i = 0; i < 2; i++)
99  av_fft_end(s->ifft[i]);
100  for (i = 0; i < 2; i++)
101  av_freep(&s->fft_data[i]);
104 }
105 
107 {
110  AVFilterLink *inlink = ctx->inputs[0];
111  AVFilterLink *outlink = ctx->outputs[0];
113  static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_GBRP, AV_PIX_FMT_NONE };
114  int ret;
115 
116  formats = ff_make_format_list(sample_fmts);
117  if ((ret = ff_formats_ref (formats, &inlink->out_formats )) < 0 ||
118  (ret = ff_add_channel_layout (&layout, AV_CH_LAYOUT_STEREO )) < 0 ||
119  (ret = ff_channel_layouts_ref (layout , &inlink->out_channel_layouts)) < 0)
120  return ret;
121 
122  formats = ff_all_samplerates();
123  if ((ret = ff_formats_ref(formats, &inlink->out_samplerates)) < 0)
124  return ret;
125 
126  formats = ff_make_format_list(pix_fmts);
127  if ((ret = ff_formats_ref(formats, &outlink->in_formats)) < 0)
128  return ret;
129 
130  return 0;
131 }
132 
133 static int run_channel_fft(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
134 {
135  ShowSpatialContext *s = ctx->priv;
136  const float *window_func_lut = s->window_func_lut;
137  AVFrame *fin = arg;
138  const int ch = jobnr;
139  const float *p = (float *)fin->extended_data[ch];
140 
141  for (int n = 0; n < fin->nb_samples; n++) {
142  s->fft_data[ch][n].re = p[n] * window_func_lut[n];
143  s->fft_data[ch][n].im = 0;
144  }
145 
146  av_fft_permute(s->fft[ch], s->fft_data[ch]);
147  av_fft_calc(s->fft[ch], s->fft_data[ch]);
148 
149  return 0;
150 }
151 
152 static int config_output(AVFilterLink *outlink)
153 {
154  AVFilterContext *ctx = outlink->src;
155  AVFilterLink *inlink = ctx->inputs[0];
156  ShowSpatialContext *s = ctx->priv;
157  int i, fft_bits;
158  float overlap;
159 
160  outlink->w = s->w;
161  outlink->h = s->h;
162  outlink->sample_aspect_ratio = (AVRational){1,1};
163 
164  s->buf_size = 1 << av_log2(s->win_size);
165  s->win_size = s->buf_size;
166  fft_bits = av_log2(s->win_size);
167 
168  /* (re-)configuration if the video output changed (or first init) */
169  if (fft_bits != s->fft_bits) {
170  s->fft_bits = fft_bits;
171 
172  /* FFT buffers: x2 for each channel buffer.
173  * Note: we use free and malloc instead of a realloc-like function to
174  * make sure the buffer is aligned in memory for the FFT functions. */
175  for (i = 0; i < 2; i++) {
176  av_fft_end(s->fft[i]);
177  av_freep(&s->fft_data[i]);
178  }
179  for (i = 0; i < 2; i++) {
180  s->fft[i] = av_fft_init(fft_bits, 0);
181  if (!s->fft[i]) {
182  av_log(ctx, AV_LOG_ERROR, "Unable to create FFT context. "
183  "The window size might be too high.\n");
184  return AVERROR(EINVAL);
185  }
186  }
187 
188  for (i = 0; i < 2; i++) {
189  s->fft_data[i] = av_calloc(s->buf_size, sizeof(**s->fft_data));
190  if (!s->fft_data[i])
191  return AVERROR(ENOMEM);
192  }
193 
194  /* pre-calc windowing function */
195  s->window_func_lut =
197  sizeof(*s->window_func_lut));
198  if (!s->window_func_lut)
199  return AVERROR(ENOMEM);
201  if (s->overlap == 1)
202  s->overlap = overlap;
203 
204  s->hop_size = (1.f - s->overlap) * s->win_size;
205  if (s->hop_size < 1) {
206  av_log(ctx, AV_LOG_ERROR, "overlap %f too big\n", s->overlap);
207  return AVERROR(EINVAL);
208  }
209  }
210 
211  outlink->time_base = av_inv_q(outlink->frame_rate);
212 
214  s->fifo = av_audio_fifo_alloc(inlink->format, inlink->channels, s->win_size);
215  if (!s->fifo)
216  return AVERROR(ENOMEM);
217  return 0;
218 }
219 
220 #define RE(y, ch) s->fft_data[ch][y].re
221 #define IM(y, ch) s->fft_data[ch][y].im
222 
223 static void draw_dot(uint8_t *dst, int linesize, int value)
224 {
225  dst[0] = value;
226  dst[1] = value;
227  dst[-1] = value;
228  dst[linesize] = value;
229  dst[-linesize] = value;
230 }
231 
232 static int draw_spatial(AVFilterLink *inlink, AVFrame *insamples)
233 {
234  AVFilterContext *ctx = inlink->dst;
235  AVFilterLink *outlink = ctx->outputs[0];
236  ShowSpatialContext *s = ctx->priv;
237  AVFrame *outpicref;
238  int h = s->h - 2;
239  int w = s->w - 2;
240  int z = s->win_size / 2;
241 
242  outpicref = ff_get_video_buffer(outlink, outlink->w, outlink->h);
243  if (!outpicref)
244  return AVERROR(ENOMEM);
245 
246  outpicref->sample_aspect_ratio = (AVRational){1,1};
247  for (int i = 0; i < outlink->h; i++) {
248  memset(outpicref->data[0] + i * outpicref->linesize[0], 0, outlink->w);
249  memset(outpicref->data[1] + i * outpicref->linesize[1], 0, outlink->w);
250  memset(outpicref->data[2] + i * outpicref->linesize[2], 0, outlink->w);
251  }
252 
253  for (int j = 0; j < z; j++) {
254  const int idx = z - 1 - j;
255  float l = hypotf(RE(idx, 0), IM(idx, 0));
256  float r = hypotf(RE(idx, 1), IM(idx, 1));
257  float sum = l + r;
258  float lp = atan2f(IM(idx, 0), RE(idx, 0));
259  float rp = atan2f(IM(idx, 1), RE(idx, 1));
260  float diffp = ((rp - lp) / (2.f * M_PI) + 1.f) * 0.5f;
261  float diff = (sum < 0.000001f ? 0.f : (r - l) / sum) * 0.5f + 0.5f;
262  float cr = av_clipf(cbrtf(l / sum), 0, 1) * 255.f;
263  float cb = av_clipf(cbrtf(r / sum), 0, 1) * 255.f;
264  float cg;
265  int x, y;
266 
267  cg = diffp * 255.f;
268  x = av_clip(w * diff, 0, w - 2) + 1;
269  y = av_clip(h * diffp, 0, h - 2) + 1;
270 
271  draw_dot(outpicref->data[0] + outpicref->linesize[0] * y + x, outpicref->linesize[0], cg);
272  draw_dot(outpicref->data[1] + outpicref->linesize[1] * y + x, outpicref->linesize[1], cb);
273  draw_dot(outpicref->data[2] + outpicref->linesize[2] * y + x, outpicref->linesize[2], cr);
274  }
275 
276  outpicref->pts = av_rescale_q(insamples->pts, inlink->time_base, outlink->time_base);
277 
278  return ff_filter_frame(outlink, outpicref);
279 }
280 
282 {
283  AVFilterLink *inlink = ctx->inputs[0];
284  AVFilterLink *outlink = ctx->outputs[0];
285  ShowSpatialContext *s = ctx->priv;
286  int ret;
287 
288  FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink);
289 
290  if (av_audio_fifo_size(s->fifo) < s->win_size) {
291  AVFrame *frame = NULL;
292 
293  ret = ff_inlink_consume_frame(inlink, &frame);
294  if (ret < 0)
295  return ret;
296  if (ret > 0) {
297  s->pts = frame->pts;
298  s->consumed = 0;
299 
300  av_audio_fifo_write(s->fifo, (void **)frame->extended_data, frame->nb_samples);
301  av_frame_free(&frame);
302  }
303  }
304 
305  if (av_audio_fifo_size(s->fifo) >= s->win_size) {
306  AVFrame *fin = ff_get_audio_buffer(inlink, s->win_size);
307  if (!fin)
308  return AVERROR(ENOMEM);
309 
310  fin->pts = s->pts + s->consumed;
311  s->consumed += s->hop_size;
312  ret = av_audio_fifo_peek(s->fifo, (void **)fin->extended_data,
314  if (ret < 0) {
315  av_frame_free(&fin);
316  return ret;
317  }
318 
319  av_assert0(fin->nb_samples == s->win_size);
320 
321  ctx->internal->execute(ctx, run_channel_fft, fin, NULL, 2);
322 
323  ret = draw_spatial(inlink, fin);
324 
325  av_frame_free(&fin);
327  if (ret <= 0)
328  return ret;
329  }
330 
331  FF_FILTER_FORWARD_STATUS(inlink, outlink);
332  if (ff_outlink_frame_wanted(outlink) && av_audio_fifo_size(s->fifo) < s->win_size) {
333  ff_inlink_request_frame(inlink);
334  return 0;
335  }
336 
337  if (av_audio_fifo_size(s->fifo) >= s->win_size) {
338  ff_filter_set_ready(ctx, 10);
339  return 0;
340  }
341  return FFERROR_NOT_READY;
342 }
343 
344 static const AVFilterPad showspatial_inputs[] = {
345  {
346  .name = "default",
347  .type = AVMEDIA_TYPE_AUDIO,
348  },
349  { NULL }
350 };
351 
353  {
354  .name = "default",
355  .type = AVMEDIA_TYPE_VIDEO,
356  .config_props = config_output,
357  },
358  { NULL }
359 };
360 
362  .name = "showspatial",
363  .description = NULL_IF_CONFIG_SMALL("Convert input audio to a spatial video output."),
364  .uninit = uninit,
365  .query_formats = query_formats,
366  .priv_size = sizeof(ShowSpatialContext),
367  .inputs = showspatial_inputs,
368  .outputs = showspatial_outputs,
370  .priv_class = &showspatial_class,
372 };
float, planar
Definition: samplefmt.h:69
int ff_inlink_consume_frame(AVFilterLink *link, AVFrame **rframe)
Take a frame from the link&#39;s FIFO and update the link&#39;s stats.
Definition: avfilter.c:1481
#define NULL
Definition: coverity.c:32
AVFILTER_DEFINE_CLASS(showspatial)
#define OFFSET(x)
AVAudioFifo * av_audio_fifo_alloc(enum AVSampleFormat sample_fmt, int channels, int nb_samples)
Allocate an AVAudioFifo.
Definition: audio_fifo.c:59
#define av_realloc_f(p, o, n)
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
AVOption.
Definition: opt.h:246
av_cold void av_fft_end(FFTContext *s)
Definition: avfft.c:48
Main libavfilter public API header.
int fft_bits
number of bits (FFT window size = 1<<fft_bits)
void av_audio_fifo_free(AVAudioFifo *af)
Free an AVAudioFifo.
Definition: audio_fifo.c:45
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:168
static int draw_spatial(AVFilterLink *inlink, AVFrame *insamples)
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 &&HAVE_MMX) 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
FFTContext * ifft[2]
Inverse Fast Fourier Transform context.
#define FFERROR_NOT_READY
Filters implementation helper functions.
Definition: filters.h:34
FFTSample re
Definition: avfft.h:38
void av_fft_permute(FFTContext *s, FFTComplex *z)
Do the permutation needed BEFORE calling ff_fft_calc().
Definition: avfft.c:38
static void generate_window_func(float *lut, int N, int win_func, float *overlap)
Definition: window_func.h:36
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:99
#define AV_CH_LAYOUT_STEREO
void ff_inlink_request_frame(AVFilterLink *link)
Mark that a frame is wanted on the link.
Definition: avfilter.c:1607
static int ff_outlink_frame_wanted(AVFilterLink *link)
Test if a frame is wanted on an output link.
Definition: filters.h:172
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
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
int ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts **ref)
Add *ref as a new reference to f.
Definition: formats.c:435
static double cb(void *priv, double x, double y)
Definition: vf_geq.c:112
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1080
uint8_t
#define av_cold
Definition: attributes.h:82
AVOptions.
#define f(width, name)
Definition: cbs_vp9.c:255
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:388
static AVFrame * frame
static int spatial_activate(AVFilterContext *ctx)
#define atan2f(y, x)
Definition: libm.h:45
static av_cold void uninit(AVFilterContext *ctx)
#define av_log(a,...)
#define FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink)
Forward the status on an output link to an input link.
Definition: filters.h:199
A filter pad used for either input or output.
Definition: internal.h:54
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
#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
static const AVFilterPad showspatial_outputs[]
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
#define AVERROR(e)
Definition: error.h:43
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
const char * r
Definition: vf_curves.c:114
void * priv
private data for use by the filter
Definition: avfilter.h:353
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Definition: avfilter.h:116
const char * arg
Definition: jacosubdec.c:66
simple assert() macros that are a bit more flexible than ISO C assert().
FFTContext * av_fft_init(int nbits, int inverse)
Set up a complex FFT.
Definition: avfft.c:28
FFTComplex * fft_data[2]
bins holder for each (displayed) channels
static int config_output(AVFilterLink *outlink)
Context for an Audio FIFO Buffer.
Definition: audio_fifo.c:34
int av_audio_fifo_size(AVAudioFifo *af)
Get the current number of samples in the AVAudioFifo available for reading.
Definition: audio_fifo.c:228
Definition: fft.h:88
audio channel layout utility functions
#define FFMIN(a, b)
Definition: common.h:96
int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add *ref as a new reference to formats.
Definition: formats.c:440
AVFormatContext * ctx
Definition: movenc.c:48
static int activate(AVFilterContext *ctx)
Definition: af_adeclick.c:609
#define s(width, name)
Definition: cbs_vp9.c:257
float * window_func_lut
Window function LUT.
int n
Definition: avisynth_c.h:760
static const AVFilterPad inputs[]
Definition: af_acontrast.c:193
if(ret< 0)
Definition: vf_mcdeint.c:279
#define RE(y, ch)
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
#define av_log2
Definition: intmath.h:83
A list of supported channel layouts.
Definition: formats.h:85
#define FLAGS
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
AVAudioFifo * fifo
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:326
FFT functions.
AVRational sample_aspect_ratio
Sample aspect ratio for the video frame, 0/1 if unknown/unspecified.
Definition: frame.h:383
static const AVFilterPad showspatial_inputs[]
static void draw_dot(uint8_t *dst, int linesize, int value)
static av_always_inline float cbrtf(float x)
Definition: libm.h:61
double value
Definition: eval.c:98
Describe the class of an AVClass context structure.
Definition: log.h:67
Filter definition.
Definition: avfilter.h:144
static int run_channel_fft(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Rational number (pair of numerator and denominator).
Definition: rational.h:58
const char * name
Filter name.
Definition: avfilter.h:148
offset must point to two consecutive integers
Definition: opt.h:233
misc parsing utilities
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:350
AVFilter ff_avf_showspatial
#define FF_FILTER_FORWARD_STATUS(inlink, outlink)
Acknowledge the status on an input link and forward it to an output link.
Definition: filters.h:226
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:275
AVFilterFormats * ff_all_samplerates(void)
Definition: formats.c:395
#define flags(name, subs,...)
Definition: cbs_av1.c:561
AVFilterInternal * internal
An opaque struct for libavfilter internal use.
Definition: avfilter.h:378
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:309
int av_audio_fifo_write(AVAudioFifo *af, void **data, int nb_samples)
Write data to an AVAudioFifo.
Definition: audio_fifo.c:112
int av_audio_fifo_drain(AVAudioFifo *af, int nb_samples)
Drain data from an AVAudioFifo.
Definition: audio_fifo.c:201
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition: rational.h:159
FFTSample im
Definition: avfft.h:38
#define IM(y, ch)
static const AVOption showspatial_options[]
void ff_filter_set_ready(AVFilterContext *filter, unsigned priority)
Mark a filter ready and schedule it for activation.
Definition: avfilter.c:193
avfilter_execute_func * execute
Definition: internal.h:155
static av_always_inline int diff(const uint32_t a, const uint32_t b)
Audio FIFO Buffer.
static int query_formats(AVFilterContext *ctx)
A list of supported formats for one end of a filter link.
Definition: formats.h:64
int av_audio_fifo_peek(AVAudioFifo *af, void **data, int nb_samples)
Peek data from an AVAudioFifo.
Definition: audio_fifo.c:138
uint64_t layout
An instance of a filter.
Definition: avfilter.h:338
FFTContext * fft[2]
Fast Fourier Transform context.
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:701
#define av_freep(p)
#define M_PI
Definition: mathematics.h:52
formats
Definition: signature.h:48
internal API functions
static double cr(void *priv, double x, double y)
Definition: vf_geq.c:113
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:342
void av_fft_calc(FFTContext *s, FFTComplex *z)
Do a complex FFT with the parameters defined in av_fft_init().
Definition: avfft.c:43
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:361
for(j=16;j >0;--j)