FFmpeg
af_aspectralstats.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2021 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 "libavutil/mem.h"
25 #include "libavutil/opt.h"
26 #include "libavutil/tx.h"
27 #include "audio.h"
28 #include "avfilter.h"
29 #include "filters.h"
30 #include "internal.h"
31 #include "window_func.h"
32 
33 #define MEASURE_ALL UINT_MAX
34 #define MEASURE_NONE 0
35 #define MEASURE_MEAN (1 << 0)
36 #define MEASURE_VARIANCE (1 << 1)
37 #define MEASURE_CENTROID (1 << 2)
38 #define MEASURE_SPREAD (1 << 3)
39 #define MEASURE_SKEWNESS (1 << 4)
40 #define MEASURE_KURTOSIS (1 << 5)
41 #define MEASURE_ENTROPY (1 << 6)
42 #define MEASURE_FLATNESS (1 << 7)
43 #define MEASURE_CREST (1 << 8)
44 #define MEASURE_FLUX (1 << 9)
45 #define MEASURE_SLOPE (1 << 10)
46 #define MEASURE_DECREASE (1 << 11)
47 #define MEASURE_ROLLOFF (1 << 12)
48 
49 typedef struct ChannelSpectralStats {
50  float mean;
51  float variance;
52  float centroid;
53  float spread;
54  float skewness;
55  float kurtosis;
56  float entropy;
57  float flatness;
58  float crest;
59  float flux;
60  float slope;
61  float decrease;
62  float rolloff;
64 
65 typedef struct AudioSpectralStatsContext {
66  const AVClass *class;
67  unsigned measure;
68  int win_size;
69  int win_func;
70  float overlap;
72  int hop_size;
79  float **prev_magnitude;
80  float **magnitude;
83 
84 #define OFFSET(x) offsetof(AudioSpectralStatsContext, x)
85 #define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
86 
87 static const AVOption aspectralstats_options[] = {
88  { "win_size", "set the window size", OFFSET(win_size), AV_OPT_TYPE_INT, {.i64=2048}, 32, 65536, A },
89  WIN_FUNC_OPTION("win_func", OFFSET(win_func), A, WFUNC_HANNING),
90  { "overlap", "set window overlap", OFFSET(overlap), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, A },
91  { "measure", "select the parameters which are measured", OFFSET(measure), AV_OPT_TYPE_FLAGS, {.i64=MEASURE_ALL}, 0, UINT_MAX, A, .unit = "measure" },
92  { "none", "", 0, AV_OPT_TYPE_CONST, {.i64=MEASURE_NONE }, 0, 0, A, .unit = "measure" },
93  { "all", "", 0, AV_OPT_TYPE_CONST, {.i64=MEASURE_ALL }, 0, 0, A, .unit = "measure" },
94  { "mean", "", 0, AV_OPT_TYPE_CONST, {.i64=MEASURE_MEAN }, 0, 0, A, .unit = "measure" },
95  { "variance", "", 0, AV_OPT_TYPE_CONST, {.i64=MEASURE_VARIANCE}, 0, 0, A, .unit = "measure" },
96  { "centroid", "", 0, AV_OPT_TYPE_CONST, {.i64=MEASURE_CENTROID}, 0, 0, A, .unit = "measure" },
97  { "spread", "", 0, AV_OPT_TYPE_CONST, {.i64=MEASURE_SPREAD }, 0, 0, A, .unit = "measure" },
98  { "skewness", "", 0, AV_OPT_TYPE_CONST, {.i64=MEASURE_SKEWNESS}, 0, 0, A, .unit = "measure" },
99  { "kurtosis", "", 0, AV_OPT_TYPE_CONST, {.i64=MEASURE_KURTOSIS}, 0, 0, A, .unit = "measure" },
100  { "entropy", "", 0, AV_OPT_TYPE_CONST, {.i64=MEASURE_ENTROPY }, 0, 0, A, .unit = "measure" },
101  { "flatness", "", 0, AV_OPT_TYPE_CONST, {.i64=MEASURE_FLATNESS}, 0, 0, A, .unit = "measure" },
102  { "crest", "", 0, AV_OPT_TYPE_CONST, {.i64=MEASURE_CREST }, 0, 0, A, .unit = "measure" },
103  { "flux", "", 0, AV_OPT_TYPE_CONST, {.i64=MEASURE_FLUX }, 0, 0, A, .unit = "measure" },
104  { "slope", "", 0, AV_OPT_TYPE_CONST, {.i64=MEASURE_SLOPE }, 0, 0, A, .unit = "measure" },
105  { "decrease", "", 0, AV_OPT_TYPE_CONST, {.i64=MEASURE_DECREASE}, 0, 0, A, .unit = "measure" },
106  { "rolloff", "", 0, AV_OPT_TYPE_CONST, {.i64=MEASURE_ROLLOFF }, 0, 0, A, .unit = "measure" },
107  { NULL }
108 };
109 
110 AVFILTER_DEFINE_CLASS(aspectralstats);
111 
112 static int config_output(AVFilterLink *outlink)
113 {
114  AudioSpectralStatsContext *s = outlink->src->priv;
115  float overlap, scale = 1.f;
116  int ret;
117 
118  s->nb_channels = outlink->ch_layout.nb_channels;
119  s->window_func_lut = av_realloc_f(s->window_func_lut, s->win_size,
120  sizeof(*s->window_func_lut));
121  if (!s->window_func_lut)
122  return AVERROR(ENOMEM);
123  generate_window_func(s->window_func_lut, s->win_size, s->win_func, &overlap);
124  if (s->overlap == 1.f)
125  s->overlap = overlap;
126 
127  s->hop_size = s->win_size * (1.f - s->overlap);
128  if (s->hop_size <= 0)
129  return AVERROR(EINVAL);
130 
131  s->stats = av_calloc(s->nb_channels, sizeof(*s->stats));
132  if (!s->stats)
133  return AVERROR(ENOMEM);
134 
135  s->fft = av_calloc(s->nb_channels, sizeof(*s->fft));
136  if (!s->fft)
137  return AVERROR(ENOMEM);
138 
139  s->magnitude = av_calloc(s->nb_channels, sizeof(*s->magnitude));
140  if (!s->magnitude)
141  return AVERROR(ENOMEM);
142 
143  s->prev_magnitude = av_calloc(s->nb_channels, sizeof(*s->prev_magnitude));
144  if (!s->prev_magnitude)
145  return AVERROR(ENOMEM);
146 
147  s->fft_in = av_calloc(s->nb_channels, sizeof(*s->fft_in));
148  if (!s->fft_in)
149  return AVERROR(ENOMEM);
150 
151  s->fft_out = av_calloc(s->nb_channels, sizeof(*s->fft_out));
152  if (!s->fft_out)
153  return AVERROR(ENOMEM);
154 
155  for (int ch = 0; ch < s->nb_channels; ch++) {
156  ret = av_tx_init(&s->fft[ch], &s->tx_fn, AV_TX_FLOAT_FFT, 0, s->win_size, &scale, 0);
157  if (ret < 0)
158  return ret;
159 
160  s->fft_in[ch] = av_calloc(s->win_size, sizeof(**s->fft_in));
161  if (!s->fft_in[ch])
162  return AVERROR(ENOMEM);
163 
164  s->fft_out[ch] = av_calloc(s->win_size, sizeof(**s->fft_out));
165  if (!s->fft_out[ch])
166  return AVERROR(ENOMEM);
167 
168  s->magnitude[ch] = av_calloc(s->win_size, sizeof(**s->magnitude));
169  if (!s->magnitude[ch])
170  return AVERROR(ENOMEM);
171 
172  s->prev_magnitude[ch] = av_calloc(s->win_size, sizeof(**s->prev_magnitude));
173  if (!s->prev_magnitude[ch])
174  return AVERROR(ENOMEM);
175  }
176 
177  s->window = ff_get_audio_buffer(outlink, s->win_size);
178  if (!s->window)
179  return AVERROR(ENOMEM);
180 
181  return 0;
182 }
183 
184 static void set_meta(AVDictionary **metadata, int chan, const char *key,
185  const char *fmt, float val)
186 {
187  uint8_t value[128];
188  uint8_t key2[128];
189 
190  snprintf(value, sizeof(value), fmt, val);
191  if (chan)
192  snprintf(key2, sizeof(key2), "lavfi.aspectralstats.%d.%s", chan, key);
193  else
194  snprintf(key2, sizeof(key2), "lavfi.aspectralstats.%s", key);
195  av_dict_set(metadata, key2, value, 0);
196 }
197 
199 {
200  for (int ch = 0; ch < s->nb_channels; ch++) {
201  ChannelSpectralStats *stats = &s->stats[ch];
202 
203  if (s->measure & MEASURE_MEAN)
204  set_meta(metadata, ch + 1, "mean", "%g", stats->mean);
205  if (s->measure & MEASURE_VARIANCE)
206  set_meta(metadata, ch + 1, "variance", "%g", stats->variance);
207  if (s->measure & MEASURE_CENTROID)
208  set_meta(metadata, ch + 1, "centroid", "%g", stats->centroid);
209  if (s->measure & MEASURE_SPREAD)
210  set_meta(metadata, ch + 1, "spread", "%g", stats->spread);
211  if (s->measure & MEASURE_SKEWNESS)
212  set_meta(metadata, ch + 1, "skewness", "%g", stats->skewness);
213  if (s->measure & MEASURE_KURTOSIS)
214  set_meta(metadata, ch + 1, "kurtosis", "%g", stats->kurtosis);
215  if (s->measure & MEASURE_ENTROPY)
216  set_meta(metadata, ch + 1, "entropy", "%g", stats->entropy);
217  if (s->measure & MEASURE_FLATNESS)
218  set_meta(metadata, ch + 1, "flatness", "%g", stats->flatness);
219  if (s->measure & MEASURE_CREST)
220  set_meta(metadata, ch + 1, "crest", "%g", stats->crest);
221  if (s->measure & MEASURE_FLUX)
222  set_meta(metadata, ch + 1, "flux", "%g", stats->flux);
223  if (s->measure & MEASURE_SLOPE)
224  set_meta(metadata, ch + 1, "slope", "%g", stats->slope);
225  if (s->measure & MEASURE_DECREASE)
226  set_meta(metadata, ch + 1, "decrease", "%g", stats->decrease);
227  if (s->measure & MEASURE_ROLLOFF)
228  set_meta(metadata, ch + 1, "rolloff", "%g", stats->rolloff);
229  }
230 }
231 
232 static float spectral_mean(const float *const spectral, int size, int max_freq)
233 {
234  float sum = 0.f;
235 
236  for (int n = 0; n < size; n++)
237  sum += spectral[n];
238 
239  return sum / size;
240 }
241 
242 static float sqrf(float a)
243 {
244  return a * a;
245 }
246 
247 static float spectral_variance(const float *const spectral, int size, int max_freq, float mean)
248 {
249  float sum = 0.f;
250 
251  for (int n = 0; n < size; n++)
252  sum += sqrf(spectral[n] - mean);
253 
254  return sum / size;
255 }
256 
257 static float spectral_centroid(const float *const spectral, int size, int max_freq)
258 {
259  const float scale = max_freq / (float)size;
260  float num = 0.f, den = 0.f;
261 
262  for (int n = 0; n < size; n++) {
263  num += spectral[n] * n * scale;
264  den += spectral[n];
265  }
266 
267  if (den <= FLT_EPSILON)
268  return 1.f;
269  return num / den;
270 }
271 
272 static float spectral_spread(const float *const spectral, int size, int max_freq, float centroid)
273 {
274  const float scale = max_freq / (float)size;
275  float num = 0.f, den = 0.f;
276 
277  for (int n = 0; n < size; n++) {
278  num += spectral[n] * sqrf(n * scale - centroid);
279  den += spectral[n];
280  }
281 
282  if (den <= FLT_EPSILON)
283  return 1.f;
284  return sqrtf(num / den);
285 }
286 
287 static float cbrf(float a)
288 {
289  return a * a * a;
290 }
291 
292 static float spectral_skewness(const float *const spectral, int size, int max_freq, float centroid, float spread)
293 {
294  const float scale = max_freq / (float)size;
295  float num = 0.f, den = 0.f;
296 
297  for (int n = 0; n < size; n++) {
298  num += spectral[n] * cbrf(n * scale - centroid);
299  den += spectral[n];
300  }
301 
302  den *= cbrf(spread);
303  if (den <= FLT_EPSILON)
304  return 1.f;
305  return num / den;
306 }
307 
308 static float spectral_kurtosis(const float *const spectral, int size, int max_freq, float centroid, float spread)
309 {
310  const float scale = max_freq / (float)size;
311  float num = 0.f, den = 0.f;
312 
313  for (int n = 0; n < size; n++) {
314  num += spectral[n] * sqrf(sqrf(n * scale - centroid));
315  den += spectral[n];
316  }
317 
318  den *= sqrf(sqrf(spread));
319  if (den <= FLT_EPSILON)
320  return 1.f;
321  return num / den;
322 }
323 
324 static float spectral_entropy(const float *const spectral, int size, int max_freq)
325 {
326  float num = 0.f, den = 0.f;
327 
328  for (int n = 0; n < size; n++) {
329  num += spectral[n] * logf(spectral[n] + FLT_EPSILON);
330  }
331 
332  den = logf(size);
333  if (den <= FLT_EPSILON)
334  return 1.f;
335  return -num / den;
336 }
337 
338 static float spectral_flatness(const float *const spectral, int size, int max_freq)
339 {
340  float num = 0.f, den = 0.f;
341 
342  for (int n = 0; n < size; n++) {
343  float v = FLT_EPSILON + spectral[n];
344  num += logf(v);
345  den += v;
346  }
347 
348  num /= size;
349  den /= size;
350  num = expf(num);
351  if (den <= FLT_EPSILON)
352  return 0.f;
353  return num / den;
354 }
355 
356 static float spectral_crest(const float *const spectral, int size, int max_freq)
357 {
358  float max = 0.f, mean = 0.f;
359 
360  for (int n = 0; n < size; n++) {
361  max = fmaxf(max, spectral[n]);
362  mean += spectral[n];
363  }
364 
365  mean /= size;
366  if (mean <= FLT_EPSILON)
367  return 0.f;
368  return max / mean;
369 }
370 
371 static float spectral_flux(const float *const spectral, const float *const prev_spectral,
372  int size, int max_freq)
373 {
374  float sum = 0.f;
375 
376  for (int n = 0; n < size; n++)
377  sum += sqrf(spectral[n] - prev_spectral[n]);
378 
379  return sqrtf(sum);
380 }
381 
382 static float spectral_slope(const float *const spectral, int size, int max_freq)
383 {
384  const float mean_freq = size * 0.5f;
385  float mean_spectral = 0.f, num = 0.f, den = 0.f;
386 
387  for (int n = 0; n < size; n++)
388  mean_spectral += spectral[n];
389  mean_spectral /= size;
390 
391  for (int n = 0; n < size; n++) {
392  num += ((n - mean_freq) / mean_freq) * (spectral[n] - mean_spectral);
393  den += sqrf((n - mean_freq) / mean_freq);
394  }
395 
396  if (fabsf(den) <= FLT_EPSILON)
397  return 0.f;
398  return num / den;
399 }
400 
401 static float spectral_decrease(const float *const spectral, int size, int max_freq)
402 {
403  float num = 0.f, den = 0.f;
404 
405  for (int n = 1; n < size; n++) {
406  num += (spectral[n] - spectral[0]) / n;
407  den += spectral[n];
408  }
409 
410  if (den <= FLT_EPSILON)
411  return 0.f;
412  return num / den;
413 }
414 
415 static float spectral_rolloff(const float *const spectral, int size, int max_freq)
416 {
417  const float scale = max_freq / (float)size;
418  float norm = 0.f, sum = 0.f;
419  int idx = 0.f;
420 
421  for (int n = 0; n < size; n++)
422  norm += spectral[n];
423  norm *= 0.85f;
424 
425  for (int n = 0; n < size; n++) {
426  sum += spectral[n];
427  if (sum >= norm) {
428  idx = n;
429  break;
430  }
431  }
432 
433  return idx * scale;
434 }
435 
436 static int filter_channel(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
437 {
439  const float *window_func_lut = s->window_func_lut;
440  AVFrame *in = arg;
441  const int channels = s->nb_channels;
442  const int start = (channels * jobnr) / nb_jobs;
443  const int end = (channels * (jobnr+1)) / nb_jobs;
444  const int offset = s->win_size - s->hop_size;
445 
446  for (int ch = start; ch < end; ch++) {
447  float *window = (float *)s->window->extended_data[ch];
448  ChannelSpectralStats *stats = &s->stats[ch];
449  AVComplexFloat *fft_out = s->fft_out[ch];
450  AVComplexFloat *fft_in = s->fft_in[ch];
451  float *magnitude = s->magnitude[ch];
452  float *prev_magnitude = s->prev_magnitude[ch];
453  const float scale = 1.f / s->win_size;
454 
455  memmove(window, &window[s->hop_size], offset * sizeof(float));
456  memcpy(&window[offset], in->extended_data[ch], in->nb_samples * sizeof(float));
457  memset(&window[offset + in->nb_samples], 0, (s->hop_size - in->nb_samples) * sizeof(float));
458 
459  for (int n = 0; n < s->win_size; n++) {
460  fft_in[n].re = window[n] * window_func_lut[n];
461  fft_in[n].im = 0;
462  }
463 
464  s->tx_fn(s->fft[ch], fft_out, fft_in, sizeof(*fft_in));
465 
466  for (int n = 0; n < s->win_size / 2; n++) {
467  fft_out[n].re *= scale;
468  fft_out[n].im *= scale;
469  }
470 
471  for (int n = 0; n < s->win_size / 2; n++)
472  magnitude[n] = hypotf(fft_out[n].re, fft_out[n].im);
473 
474  if (s->measure & (MEASURE_MEAN | MEASURE_VARIANCE))
475  stats->mean = spectral_mean(magnitude, s->win_size / 2, in->sample_rate / 2);
476  if (s->measure & MEASURE_VARIANCE)
477  stats->variance = spectral_variance(magnitude, s->win_size / 2, in->sample_rate / 2, stats->mean);
479  stats->centroid = spectral_centroid(magnitude, s->win_size / 2, in->sample_rate / 2);
480  if (s->measure & (MEASURE_SPREAD | MEASURE_KURTOSIS | MEASURE_SKEWNESS))
481  stats->spread = spectral_spread(magnitude, s->win_size / 2, in->sample_rate / 2, stats->centroid);
482  if (s->measure & MEASURE_SKEWNESS)
483  stats->skewness = spectral_skewness(magnitude, s->win_size / 2, in->sample_rate / 2, stats->centroid, stats->spread);
484  if (s->measure & MEASURE_KURTOSIS)
485  stats->kurtosis = spectral_kurtosis(magnitude, s->win_size / 2, in->sample_rate / 2, stats->centroid, stats->spread);
486  if (s->measure & MEASURE_ENTROPY)
487  stats->entropy = spectral_entropy(magnitude, s->win_size / 2, in->sample_rate / 2);
488  if (s->measure & MEASURE_FLATNESS)
489  stats->flatness = spectral_flatness(magnitude, s->win_size / 2, in->sample_rate / 2);
490  if (s->measure & MEASURE_CREST)
491  stats->crest = spectral_crest(magnitude, s->win_size / 2, in->sample_rate / 2);
492  if (s->measure & MEASURE_FLUX)
493  stats->flux = spectral_flux(magnitude, prev_magnitude, s->win_size / 2, in->sample_rate / 2);
494  if (s->measure & MEASURE_SLOPE)
495  stats->slope = spectral_slope(magnitude, s->win_size / 2, in->sample_rate / 2);
496  if (s->measure & MEASURE_DECREASE)
497  stats->decrease = spectral_decrease(magnitude, s->win_size / 2, in->sample_rate / 2);
498  if (s->measure & MEASURE_ROLLOFF)
499  stats->rolloff = spectral_rolloff(magnitude, s->win_size / 2, in->sample_rate / 2);
500 
501  memcpy(prev_magnitude, magnitude, s->win_size * sizeof(float));
502  }
503 
504  return 0;
505 }
506 
508 {
509  AVFilterContext *ctx = inlink->dst;
510  AVFilterLink *outlink = ctx->outputs[0];
512  AVDictionary **metadata;
513  AVFrame *out;
514  int ret;
515 
516  if (av_frame_is_writable(in)) {
517  out = in;
518  } else {
519  out = ff_get_audio_buffer(outlink, in->nb_samples);
520  if (!out) {
521  av_frame_free(&in);
522  return AVERROR(ENOMEM);
523  }
524  ret = av_frame_copy_props(out, in);
525  if (ret < 0)
526  goto fail;
527  ret = av_frame_copy(out, in);
528  if (ret < 0)
529  goto fail;
530  }
531 
532  metadata = &out->metadata;
534  FFMIN(inlink->ch_layout.nb_channels, ff_filter_get_nb_threads(ctx)));
535 
536  set_metadata(s, metadata);
537 
538  if (out != in)
539  av_frame_free(&in);
540  return ff_filter_frame(outlink, out);
541 fail:
542  av_frame_free(&in);
543  av_frame_free(&out);
544  return ret;
545 }
546 
548 {
550  AVFilterLink *outlink = ctx->outputs[0];
551  AVFilterLink *inlink = ctx->inputs[0];
552  AVFrame *in;
553  int ret;
554 
556 
557  ret = ff_inlink_consume_samples(inlink, s->hop_size, s->hop_size, &in);
558  if (ret < 0)
559  return ret;
560  if (ret > 0)
561  ret = filter_frame(inlink, in);
562  if (ret < 0)
563  return ret;
564 
565  if (ff_inlink_queued_samples(inlink) >= s->hop_size) {
567  return 0;
568  }
569 
572 
573  return FFERROR_NOT_READY;
574 }
575 
577 {
579 
580  for (int ch = 0; ch < s->nb_channels; ch++) {
581  if (s->fft)
582  av_tx_uninit(&s->fft[ch]);
583  if (s->fft_in)
584  av_freep(&s->fft_in[ch]);
585  if (s->fft_out)
586  av_freep(&s->fft_out[ch]);
587  if (s->magnitude)
588  av_freep(&s->magnitude[ch]);
589  if (s->prev_magnitude)
590  av_freep(&s->prev_magnitude[ch]);
591  }
592 
593  av_freep(&s->fft);
594  av_freep(&s->magnitude);
595  av_freep(&s->prev_magnitude);
596  av_freep(&s->fft_in);
597  av_freep(&s->fft_out);
598  av_freep(&s->stats);
599 
600  av_freep(&s->window_func_lut);
601  av_frame_free(&s->window);
602 }
603 
605  {
606  .name = "default",
607  .type = AVMEDIA_TYPE_AUDIO,
608  .config_props = config_output,
609  },
610 };
611 
613  .name = "aspectralstats",
614  .description = NULL_IF_CONFIG_SMALL("Show frequency domain statistics about audio frames."),
615  .priv_size = sizeof(AudioSpectralStatsContext),
616  .priv_class = &aspectralstats_class,
617  .uninit = uninit,
618  .activate = activate,
623 };
ff_get_audio_buffer
AVFrame * ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
Request an audio samples buffer with a specific set of permissions.
Definition: audio.c:97
AV_SAMPLE_FMT_FLTP
@ AV_SAMPLE_FMT_FLTP
float, planar
Definition: samplefmt.h:66
MEASURE_KURTOSIS
#define MEASURE_KURTOSIS
Definition: af_aspectralstats.c:40
ChannelSpectralStats::slope
float slope
Definition: af_aspectralstats.c:60
spectral_mean
static float spectral_mean(const float *const spectral, int size, int max_freq)
Definition: af_aspectralstats.c:232
MEASURE_ALL
#define MEASURE_ALL
Definition: af_aspectralstats.c:33
AVERROR
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
opt.h
out
FILE * out
Definition: movenc.c:55
AudioSpectralStatsContext::measure
unsigned measure
Definition: af_aspectralstats.c:67
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1015
MEASURE_ENTROPY
#define MEASURE_ENTROPY
Definition: af_aspectralstats.c:41
FFERROR_NOT_READY
return FFERROR_NOT_READY
Definition: filter_design.txt:204
AudioSpectralStatsContext
Definition: af_aspectralstats.c:65
AVTXContext
Definition: tx_priv.h:235
FILTER_SINGLE_SAMPLEFMT
#define FILTER_SINGLE_SAMPLEFMT(sample_fmt_)
Definition: internal.h:175
inlink
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
Definition: filter_design.txt:212
AudioSpectralStatsContext::prev_magnitude
float ** prev_magnitude
Definition: af_aspectralstats.c:79
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:160
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:374
MEASURE_FLUX
#define MEASURE_FLUX
Definition: af_aspectralstats.c:44
AVOption
AVOption.
Definition: opt.h:346
expf
#define expf(x)
Definition: libm.h:283
float.h
AVComplexFloat
Definition: tx.h:27
WIN_FUNC_OPTION
#define WIN_FUNC_OPTION(win_func_opt_name, win_func_offset, flag, default_window_func)
Definition: window_func.h:37
max
#define max(a, b)
Definition: cuda_runtime.h:33
AVDictionary
Definition: dict.c:34
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:170
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:313
aspectralstats_outputs
static const AVFilterPad aspectralstats_outputs[]
Definition: af_aspectralstats.c:604
FF_FILTER_FORWARD_STATUS_BACK
#define FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink)
Forward the status on an output link to an input link.
Definition: filters.h:199
av_tx_init
av_cold int av_tx_init(AVTXContext **ctx, av_tx_fn *tx, enum AVTXType type, int inv, int len, const void *scale, uint64_t flags)
Initialize a transform context with the given configuration (i)MDCTs with an odd length are currently...
Definition: tx.c:903
spectral_entropy
static float spectral_entropy(const float *const spectral, int size, int max_freq)
Definition: af_aspectralstats.c:324
AudioSpectralStatsContext::fft_out
AVComplexFloat ** fft_out
Definition: af_aspectralstats.c:78
window
static SDL_Window * window
Definition: ffplay.c:361
AVFilterContext::priv
void * priv
private data for use by the filter
Definition: avfilter.h:422
fail
#define fail()
Definition: checkasm.h:179
spectral_variance
static float spectral_variance(const float *const spectral, int size, int max_freq, float mean)
Definition: af_aspectralstats.c:247
AudioSpectralStatsContext::magnitude
float ** magnitude
Definition: af_aspectralstats.c:80
AudioSpectralStatsContext::tx_fn
av_tx_fn tx_fn
Definition: af_aspectralstats.c:75
val
static double val(void *priv, double ch)
Definition: aeval.c:78
fabsf
static __device__ float fabsf(float a)
Definition: cuda_runtime.h:181
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:33
ChannelSpectralStats::decrease
float decrease
Definition: af_aspectralstats.c:61
ff_af_aspectralstats
const AVFilter ff_af_aspectralstats
Definition: af_aspectralstats.c:612
ChannelSpectralStats::kurtosis
float kurtosis
Definition: af_aspectralstats.c:55
spectral_crest
static float spectral_crest(const float *const spectral, int size, int max_freq)
Definition: af_aspectralstats.c:356
av_cold
#define av_cold
Definition: attributes.h:90
filter_channel
static int filter_channel(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: af_aspectralstats.c:436
av_tx_fn
void(* av_tx_fn)(AVTXContext *s, void *out, void *in, ptrdiff_t stride)
Function pointer to a function to perform the transform.
Definition: tx.h:151
spectral_flatness
static float spectral_flatness(const float *const spectral, int size, int max_freq)
Definition: af_aspectralstats.c:338
float
float
Definition: af_crystalizer.c:121
AudioSpectralStatsContext::window
AVFrame * window
Definition: af_aspectralstats.c:81
ChannelSpectralStats::centroid
float centroid
Definition: af_aspectralstats.c:52
s
#define s(width, name)
Definition: cbs_vp9.c:198
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
AudioSpectralStatsContext::win_func
int win_func
Definition: af_aspectralstats.c:69
MEASURE_CREST
#define MEASURE_CREST
Definition: af_aspectralstats.c:43
filters.h
AV_TX_FLOAT_FFT
@ AV_TX_FLOAT_FFT
Standard complex to complex FFT with sample data type of AVComplexFloat, AVComplexDouble or AVComplex...
Definition: tx.h:47
MEASURE_SLOPE
#define MEASURE_SLOPE
Definition: af_aspectralstats.c:45
ctx
AVFormatContext * ctx
Definition: movenc.c:49
channels
channels
Definition: aptx.h:31
ChannelSpectralStats
Definition: af_aspectralstats.c:49
MEASURE_DECREASE
#define MEASURE_DECREASE
Definition: af_aspectralstats.c:46
key
const char * key
Definition: hwcontext_opencl.c:189
AudioSpectralStatsContext::overlap
float overlap
Definition: af_aspectralstats.c:70
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: internal.h:182
arg
const char * arg
Definition: jacosubdec.c:67
AudioSpectralStatsContext::fft
AVTXContext ** fft
Definition: af_aspectralstats.c:76
av_realloc_f
#define av_realloc_f(p, o, n)
Definition: tableprint_vlc.h:32
spectral_slope
static float spectral_slope(const float *const spectral, int size, int max_freq)
Definition: af_aspectralstats.c:382
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
ff_inlink_consume_samples
int ff_inlink_consume_samples(AVFilterLink *link, unsigned min, unsigned max, AVFrame **rframe)
Take samples from the link's FIFO and update the link's stats.
Definition: avfilter.c:1462
NULL
#define NULL
Definition: coverity.c:32
ChannelSpectralStats::spread
float spread
Definition: af_aspectralstats.c:53
av_frame_copy_props
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:709
ChannelSpectralStats::entropy
float entropy
Definition: af_aspectralstats.c:56
ChannelSpectralStats::flatness
float flatness
Definition: af_aspectralstats.c:57
ff_audio_default_filterpad
const AVFilterPad ff_audio_default_filterpad[1]
An AVFilterPad array whose only entry has name "default" and is of type AVMEDIA_TYPE_AUDIO.
Definition: audio.c:33
sqrtf
static __device__ float sqrtf(float a)
Definition: cuda_runtime.h:184
generate_window_func
static void generate_window_func(float *lut, int N, int win_func, float *overlap)
Definition: window_func.h:63
WFUNC_HANNING
@ WFUNC_HANNING
Definition: window_func.h:29
aspectralstats_options
static const AVOption aspectralstats_options[]
Definition: af_aspectralstats.c:87
stats
static void stats(AVPacket *const *in, int n_in, unsigned *_max, unsigned *_sum)
Definition: vp9_superframe.c:34
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:94
ChannelSpectralStats::skewness
float skewness
Definition: af_aspectralstats.c:54
av_frame_copy
int av_frame_copy(AVFrame *dst, const AVFrame *src)
Copy the frame data from src to dst.
Definition: frame.c:999
AVFrame::sample_rate
int sample_rate
Sample rate of the audio data.
Definition: frame.h:573
fmaxf
float fmaxf(float, float)
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: af_aspectralstats.c:507
size
int size
Definition: twinvq_data.h:10344
av_frame_is_writable
int av_frame_is_writable(AVFrame *frame)
Check if the frame data is writable.
Definition: frame.c:645
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
spectral_decrease
static float spectral_decrease(const float *const spectral, int size, int max_freq)
Definition: af_aspectralstats.c:401
MEASURE_VARIANCE
#define MEASURE_VARIANCE
Definition: af_aspectralstats.c:36
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
FF_FILTER_FORWARD_WANTED
FF_FILTER_FORWARD_WANTED(outlink, inlink)
activate
static int activate(AVFilterContext *ctx)
Definition: af_aspectralstats.c:547
spectral_centroid
static float spectral_centroid(const float *const spectral, int size, int max_freq)
Definition: af_aspectralstats.c:257
av_tx_uninit
av_cold void av_tx_uninit(AVTXContext **ctx)
Frees a context and sets *ctx to NULL, does nothing when *ctx == NULL.
Definition: tx.c:295
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: af_aspectralstats.c:576
internal.h
AV_OPT_TYPE_FLOAT
@ AV_OPT_TYPE_FLOAT
Definition: opt.h:238
spectral_rolloff
static float spectral_rolloff(const float *const spectral, int size, int max_freq)
Definition: af_aspectralstats.c:415
MEASURE_FLATNESS
#define MEASURE_FLATNESS
Definition: af_aspectralstats.c:42
AVFrame::nb_samples
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:454
MEASURE_SKEWNESS
#define MEASURE_SKEWNESS
Definition: af_aspectralstats.c:39
AVFrame::extended_data
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:435
ChannelSpectralStats::mean
float mean
Definition: af_aspectralstats.c:50
cbrf
static float cbrf(float a)
Definition: af_aspectralstats.c:287
spectral_flux
static float spectral_flux(const float *const spectral, const float *const prev_spectral, int size, int max_freq)
Definition: af_aspectralstats.c:371
ff_filter_get_nb_threads
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:827
AudioSpectralStatsContext::fft_in
AVComplexFloat ** fft_in
Definition: af_aspectralstats.c:77
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
ChannelSpectralStats::crest
float crest
Definition: af_aspectralstats.c:58
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:39
ff_inlink_queued_samples
int ff_inlink_queued_samples(AVFilterLink *link)
Definition: avfilter.c:1417
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
MEASURE_ROLLOFF
#define MEASURE_ROLLOFF
Definition: af_aspectralstats.c:47
ChannelSpectralStats::flux
float flux
Definition: af_aspectralstats.c:59
ChannelSpectralStats::variance
float variance
Definition: af_aspectralstats.c:51
AVFilter
Filter definition.
Definition: avfilter.h:166
config_output
static int config_output(AVFilterLink *outlink)
Definition: af_aspectralstats.c:112
ret
ret
Definition: filter_design.txt:187
window_func.h
set_meta
static void set_meta(AVDictionary **metadata, int chan, const char *key, const char *fmt, float val)
Definition: af_aspectralstats.c:184
spectral_spread
static float spectral_spread(const float *const spectral, int size, int max_freq, float centroid)
Definition: af_aspectralstats.c:272
AudioSpectralStatsContext::hop_size
int hop_size
Definition: af_aspectralstats.c:72
AudioSpectralStatsContext::nb_channels
int nb_channels
Definition: af_aspectralstats.c:71
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:235
avfilter.h
mean
static float mean(const float *input, int size)
Definition: vf_nnedi.c:863
spectral_skewness
static float spectral_skewness(const float *const spectral, int size, int max_freq, float centroid, float spread)
Definition: af_aspectralstats.c:292
AVFilterContext
An instance of a filter.
Definition: avfilter.h:407
AVFILTER_FLAG_SLICE_THREADS
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Definition: avfilter.h:117
mem.h
audio.h
ChannelSpectralStats::rolloff
float rolloff
Definition: af_aspectralstats.c:62
scale
static void scale(int *out, const int *in, const int w, const int h, const int shift)
Definition: intra.c:291
FF_FILTER_FORWARD_STATUS
FF_FILTER_FORWARD_STATUS(inlink, outlink)
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: internal.h:183
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
av_dict_set
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition: dict.c:88
set_metadata
static void set_metadata(AudioSpectralStatsContext *s, AVDictionary **metadata)
Definition: af_aspectralstats.c:198
sqrf
static float sqrf(float a)
Definition: af_aspectralstats.c:242
AV_OPT_TYPE_FLAGS
@ AV_OPT_TYPE_FLAGS
Definition: opt.h:234
AudioSpectralStatsContext::win_size
int win_size
Definition: af_aspectralstats.c:68
AudioSpectralStatsContext::stats
ChannelSpectralStats * stats
Definition: af_aspectralstats.c:73
A
#define A
Definition: af_aspectralstats.c:85
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(aspectralstats)
MEASURE_NONE
#define MEASURE_NONE
Definition: af_aspectralstats.c:34
MEASURE_CENTROID
#define MEASURE_CENTROID
Definition: af_aspectralstats.c:37
MEASURE_MEAN
#define MEASURE_MEAN
Definition: af_aspectralstats.c:35
AudioSpectralStatsContext::window_func_lut
float * window_func_lut
Definition: af_aspectralstats.c:74
ff_filter_execute
static av_always_inline int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg, int *ret, int nb_jobs)
Definition: internal.h:134
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:244
snprintf
#define snprintf
Definition: snprintf.h:34
spectral_kurtosis
static float spectral_kurtosis(const float *const spectral, int size, int max_freq, float centroid, float spread)
Definition: af_aspectralstats.c:308
MEASURE_SPREAD
#define MEASURE_SPREAD
Definition: af_aspectralstats.c:38
ff_filter_set_ready
void ff_filter_set_ready(AVFilterContext *filter, unsigned priority)
Mark a filter ready and schedule it for activation.
Definition: avfilter.c:235
tx.h
OFFSET
#define OFFSET(x)
Definition: af_aspectralstats.c:84