FFmpeg
avf_showcwt.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2022 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/tx.h"
27 #include "libavutil/float_dsp.h"
28 #include "libavutil/cpu.h"
29 #include "libavutil/opt.h"
30 #include "libavutil/parseutils.h"
31 #include "audio.h"
32 #include "formats.h"
33 #include "video.h"
34 #include "avfilter.h"
35 #include "filters.h"
36 
48 };
49 
57 };
58 
65 };
66 
67 enum SlideMode {
72 };
73 
74 typedef struct ShowCWTContext {
75  const AVClass *class;
76  int w, h;
77  int mode;
78  char *rate_str;
84  int pos;
90  unsigned *index;
106  int pps;
107  int eof;
108  int slide;
121  float deviation;
122  float bar_ratio;
123  int bar_size;
125  float rotation;
126 
129 
130 #define OFFSET(x) offsetof(ShowCWTContext, x)
131 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
132 
133 static const AVOption showcwt_options[] = {
134  { "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "640x512"}, 0, 0, FLAGS },
135  { "s", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "640x512"}, 0, 0, FLAGS },
136  { "rate", "set video rate", OFFSET(rate_str), AV_OPT_TYPE_STRING, {.str = "25"}, 0, 0, FLAGS },
137  { "r", "set video rate", OFFSET(rate_str), AV_OPT_TYPE_STRING, {.str = "25"}, 0, 0, FLAGS },
138  { "scale", "set frequency scale", OFFSET(frequency_scale), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_FSCALE-1, FLAGS, .unit = "scale" },
139  { "linear", "linear", 0, AV_OPT_TYPE_CONST,{.i64=FSCALE_LINEAR}, 0, 0, FLAGS, .unit = "scale" },
140  { "log", "logarithmic", 0, AV_OPT_TYPE_CONST,{.i64=FSCALE_LOG}, 0, 0, FLAGS, .unit = "scale" },
141  { "bark", "bark", 0, AV_OPT_TYPE_CONST,{.i64=FSCALE_BARK}, 0, 0, FLAGS, .unit = "scale" },
142  { "mel", "mel", 0, AV_OPT_TYPE_CONST,{.i64=FSCALE_MEL}, 0, 0, FLAGS, .unit = "scale" },
143  { "erbs", "erbs", 0, AV_OPT_TYPE_CONST,{.i64=FSCALE_ERBS}, 0, 0, FLAGS, .unit = "scale" },
144  { "sqrt", "sqrt", 0, AV_OPT_TYPE_CONST,{.i64=FSCALE_SQRT}, 0, 0, FLAGS, .unit = "scale" },
145  { "cbrt", "cbrt", 0, AV_OPT_TYPE_CONST,{.i64=FSCALE_CBRT}, 0, 0, FLAGS, .unit = "scale" },
146  { "qdrt", "qdrt", 0, AV_OPT_TYPE_CONST,{.i64=FSCALE_QDRT}, 0, 0, FLAGS, .unit = "scale" },
147  { "fm", "fm", 0, AV_OPT_TYPE_CONST,{.i64=FSCALE_FM}, 0, 0, FLAGS, .unit = "scale" },
148  { "iscale", "set intensity scale", OFFSET(intensity_scale),AV_OPT_TYPE_INT, {.i64=0}, 0, NB_ISCALE-1, FLAGS, .unit = "iscale" },
149  { "linear", "linear", 0, AV_OPT_TYPE_CONST,{.i64=ISCALE_LINEAR}, 0, 0, FLAGS, .unit = "iscale" },
150  { "log", "logarithmic", 0, AV_OPT_TYPE_CONST,{.i64=ISCALE_LOG}, 0, 0, FLAGS, .unit = "iscale" },
151  { "sqrt", "sqrt", 0, AV_OPT_TYPE_CONST,{.i64=ISCALE_SQRT}, 0, 0, FLAGS, .unit = "iscale" },
152  { "cbrt", "cbrt", 0, AV_OPT_TYPE_CONST,{.i64=ISCALE_CBRT}, 0, 0, FLAGS, .unit = "iscale" },
153  { "qdrt", "qdrt", 0, AV_OPT_TYPE_CONST,{.i64=ISCALE_QDRT}, 0, 0, FLAGS, .unit = "iscale" },
154  { "min", "set minimum frequency", OFFSET(minimum_frequency), AV_OPT_TYPE_FLOAT, {.dbl = 20.}, 1, 192000, FLAGS },
155  { "max", "set maximum frequency", OFFSET(maximum_frequency), AV_OPT_TYPE_FLOAT, {.dbl = 20000.}, 1, 192000, FLAGS },
156  { "imin", "set minimum intensity", OFFSET(minimum_intensity), AV_OPT_TYPE_FLOAT, {.dbl = 0.}, 0, 1, FLAGS },
157  { "imax", "set maximum intensity", OFFSET(maximum_intensity), AV_OPT_TYPE_FLOAT, {.dbl = 1.}, 0, 1, FLAGS },
158  { "logb", "set logarithmic basis", OFFSET(logarithmic_basis), AV_OPT_TYPE_FLOAT, {.dbl = 0.0001}, 0, 1, FLAGS },
159  { "deviation", "set frequency deviation", OFFSET(deviation), AV_OPT_TYPE_FLOAT, {.dbl = 1.}, 0, 100, FLAGS },
160  { "pps", "set pixels per second", OFFSET(pps), AV_OPT_TYPE_INT, {.i64 = 64}, 1, 1024, FLAGS },
161  { "mode", "set output mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=0}, 0, 4, FLAGS, .unit = "mode" },
162  { "magnitude", "magnitude", 0, AV_OPT_TYPE_CONST,{.i64=0}, 0, 0, FLAGS, .unit = "mode" },
163  { "phase", "phase", 0, AV_OPT_TYPE_CONST,{.i64=1}, 0, 0, FLAGS, .unit = "mode" },
164  { "magphase", "magnitude+phase", 0, AV_OPT_TYPE_CONST,{.i64=2}, 0, 0, FLAGS, .unit = "mode" },
165  { "channel", "color per channel", 0, AV_OPT_TYPE_CONST,{.i64=3}, 0, 0, FLAGS, .unit = "mode" },
166  { "stereo", "stereo difference", 0, AV_OPT_TYPE_CONST,{.i64=4}, 0, 0, FLAGS, .unit = "mode" },
167  { "slide", "set slide mode", OFFSET(slide), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_SLIDE-1, FLAGS, .unit = "slide" },
168  { "replace", "replace", 0, AV_OPT_TYPE_CONST,{.i64=SLIDE_REPLACE},0, 0, FLAGS, .unit = "slide" },
169  { "scroll", "scroll", 0, AV_OPT_TYPE_CONST,{.i64=SLIDE_SCROLL}, 0, 0, FLAGS, .unit = "slide" },
170  { "frame", "frame", 0, AV_OPT_TYPE_CONST,{.i64=SLIDE_FRAME}, 0, 0, FLAGS, .unit = "slide" },
171  { "direction", "set direction mode", OFFSET(direction), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_DIRECTION-1, FLAGS, .unit = "direction" },
172  { "lr", "left to right", 0, AV_OPT_TYPE_CONST,{.i64=DIRECTION_LR}, 0, 0, FLAGS, .unit = "direction" },
173  { "rl", "right to left", 0, AV_OPT_TYPE_CONST,{.i64=DIRECTION_RL}, 0, 0, FLAGS, .unit = "direction" },
174  { "ud", "up to down", 0, AV_OPT_TYPE_CONST,{.i64=DIRECTION_UD}, 0, 0, FLAGS, .unit = "direction" },
175  { "du", "down to up", 0, AV_OPT_TYPE_CONST,{.i64=DIRECTION_DU}, 0, 0, FLAGS, .unit = "direction" },
176  { "bar", "set bargraph ratio", OFFSET(bar_ratio), AV_OPT_TYPE_FLOAT, {.dbl = 0.}, 0, 1, FLAGS },
177  { "rotation", "set color rotation", OFFSET(rotation), AV_OPT_TYPE_FLOAT, {.dbl = 0}, -1, 1, FLAGS },
178  { NULL }
179 };
180 
181 AVFILTER_DEFINE_CLASS(showcwt);
182 
184 {
185  ShowCWTContext *s = ctx->priv;
186 
187  av_freep(&s->frequency_band);
188  av_freep(&s->kernel_start);
189  av_freep(&s->kernel_stop);
190  av_freep(&s->index);
191 
192  av_frame_free(&s->cache);
193  av_frame_free(&s->outpicref);
194  av_frame_free(&s->fft_in);
195  av_frame_free(&s->fft_out);
196  av_frame_free(&s->dst_x);
197  av_frame_free(&s->src_x);
198  av_frame_free(&s->ifft_in);
199  av_frame_free(&s->ifft_out);
200  av_frame_free(&s->ch_out);
201  av_frame_free(&s->over);
202  av_frame_free(&s->bh_out);
203 
204  if (s->fft) {
205  for (int n = 0; n < s->nb_threads; n++)
206  av_tx_uninit(&s->fft[n]);
207  av_freep(&s->fft);
208  }
209 
210  if (s->ifft) {
211  for (int n = 0; n < s->nb_threads; n++)
212  av_tx_uninit(&s->ifft[n]);
213  av_freep(&s->ifft);
214  }
215 
216  if (s->kernel) {
217  for (int n = 0; n < s->frequency_band_count; n++)
218  av_freep(&s->kernel[n]);
219  }
220  av_freep(&s->kernel);
221 
222  av_freep(&s->fdsp);
223 }
224 
226 {
229  AVFilterLink *inlink = ctx->inputs[0];
230  AVFilterLink *outlink = ctx->outputs[0];
233  int ret;
234 
236  if ((ret = ff_formats_ref(formats, &inlink->outcfg.formats)) < 0)
237  return ret;
238 
240  if ((ret = ff_channel_layouts_ref(layouts, &inlink->outcfg.channel_layouts)) < 0)
241  return ret;
242 
244  if ((ret = ff_formats_ref(formats, &inlink->outcfg.samplerates)) < 0)
245  return ret;
246 
248  if ((ret = ff_formats_ref(formats, &outlink->incfg.formats)) < 0)
249  return ret;
250 
251  return 0;
252 }
253 
254 static float frequency_band(float *frequency_band,
255  int frequency_band_count,
256  float frequency_range,
257  float frequency_offset,
258  int frequency_scale, float deviation)
259 {
260  float ret = 0.f;
261 
262  deviation = sqrtf(deviation / (4.f * M_PI)); // Heisenberg Gabor Limit
263  for (int y = 0; y < frequency_band_count; y++) {
264  float frequency = frequency_range * (1.f - (float)y / frequency_band_count) + frequency_offset;
265  float frequency_derivative = frequency_range / frequency_band_count;
266 
267  switch (frequency_scale) {
268  case FSCALE_LOG:
269  frequency = powf(2.f, frequency);
270  frequency_derivative *= logf(2.f) * frequency;
271  break;
272  case FSCALE_BARK:
273  frequency = 600.f * sinhf(frequency / 6.f);
274  frequency_derivative *= sqrtf(frequency * frequency + 360000.f) / 6.f;
275  break;
276  case FSCALE_MEL:
277  frequency = 700.f * (powf(10.f, frequency / 2595.f) - 1.f);
278  frequency_derivative *= (frequency + 700.f) * logf(10.f) / 2595.f;
279  break;
280  case FSCALE_ERBS:
281  frequency = 676170.4f / (47.06538f - expf(frequency * 0.08950404f)) - 14678.49f;
282  frequency_derivative *= (frequency * frequency + 14990.4f * frequency + 4577850.f) / 160514.f;
283  break;
284  case FSCALE_SQRT:
285  frequency = frequency * frequency;
286  frequency_derivative *= 2.f * sqrtf(frequency);
287  break;
288  case FSCALE_CBRT:
289  frequency = frequency * frequency * frequency;
290  frequency_derivative *= 3.f * powf(frequency, 2.f / 3.f);
291  break;
292  case FSCALE_QDRT:
293  frequency = frequency * frequency * frequency * frequency;
294  frequency_derivative *= 4.f * powf(frequency, 3.f / 4.f);
295  break;
296  case FSCALE_FM:
297  frequency = 2.f * powf(frequency, 3.f / 2.f) / 3.f;
298  frequency_derivative *= sqrtf(frequency);
299  break;
300  }
301 
302  frequency_band[y*2 ] = frequency;
303  frequency_band[y*2+1] = frequency_derivative * deviation;
304 
305  ret = 1.f / (frequency_derivative * deviation);
306  }
307 
308  return ret;
309 }
310 
311 static float remap_log(ShowCWTContext *s, float value, int iscale, float log_factor)
312 {
313  const float max = s->maximum_intensity;
314  const float min = s->minimum_intensity;
315  float ret;
316 
317  value += min;
318 
319  switch (iscale) {
320  case ISCALE_LINEAR:
321  ret = max - expf(value / log_factor);
322  break;
323  case ISCALE_LOG:
324  value = logf(value) * log_factor;
325  ret = max - av_clipf(value, 0.f, 1.f);
326  break;
327  case ISCALE_SQRT:
328  value = max - expf(value / log_factor);
329  ret = sqrtf(value);
330  break;
331  case ISCALE_CBRT:
332  value = max - expf(value / log_factor);
333  ret = cbrtf(value);
334  break;
335  case ISCALE_QDRT:
336  value = max - expf(value / log_factor);
337  ret = powf(value, 0.25f);
338  break;
339  }
340 
341  return av_clipf(ret, 0.f, 1.f);
342 }
343 
344 static int run_channel_cwt_prepare(AVFilterContext *ctx, void *arg, int jobnr, int ch)
345 {
346  ShowCWTContext *s = ctx->priv;
347  const int hop_size = s->hop_size;
348  AVFrame *fin = arg;
349  float *cache = (float *)s->cache->extended_data[ch];
350  AVComplexFloat *src = (AVComplexFloat *)s->fft_in->extended_data[ch];
351  AVComplexFloat *dst = (AVComplexFloat *)s->fft_out->extended_data[ch];
352  const int offset = (s->input_padding_size - hop_size) >> 1;
353 
354  if (fin) {
355  const float *input = (const float *)fin->extended_data[ch];
356  const int offset = s->hop_size - fin->nb_samples;
357 
358  memmove(cache, &cache[fin->nb_samples], offset * sizeof(float));
359  memcpy(&cache[offset], input, fin->nb_samples * sizeof(float));
360  }
361 
362  if (fin && s->hop_index + fin->nb_samples < hop_size)
363  return 0;
364 
365  memset(src, 0, sizeof(float) * s->fft_size);
366  for (int n = 0; n < hop_size; n++)
367  src[n+offset].re = cache[n];
368 
369  s->tx_fn(s->fft[jobnr], dst, src, sizeof(*src));
370 
371  return 0;
372 }
373 
374 #define DRAW_BAR_COLOR(x) \
375 do { \
376  if (Y <= ht) { \
377  dstY[x] = 0; \
378  dstU[x] = 128; \
379  dstV[x] = 128; \
380  } else { \
381  float mul = (Y - ht) * bh[0]; \
382  dstY[x] = av_clip_uint8(lrintf(Y * mul * 255.f)); \
383  dstU[x] = av_clip_uint8(lrintf((U-0.5f) * 128.f + 128)); \
384  dstV[x] = av_clip_uint8(lrintf((V-0.5f) * 128.f + 128)); \
385  } \
386 } while (0)
387 
388 static void draw_bar(ShowCWTContext *s, int y,
389  float Y, float U, float V)
390 {
391  float *bh = ((float *)s->bh_out->extended_data[0]) + y;
392  const ptrdiff_t ylinesize = s->outpicref->linesize[0];
393  const ptrdiff_t ulinesize = s->outpicref->linesize[1];
394  const ptrdiff_t vlinesize = s->outpicref->linesize[2];
395  const int direction = s->direction;
396  const int sono_size = s->sono_size;
397  const int bar_size = s->bar_size;
398  const float rcp_bar_h = 1.f / bar_size;
399  uint8_t *dstY, *dstU, *dstV;
400  const int w = s->w;
401 
402  bh[0] = 1.f / (Y + 0.0001f);
403  switch (direction) {
404  case DIRECTION_LR:
405  dstY = s->outpicref->data[0] + y * ylinesize;
406  dstU = s->outpicref->data[1] + y * ulinesize;
407  dstV = s->outpicref->data[2] + y * vlinesize;
408  for (int x = 0; x < bar_size; x++) {
409  float ht = (bar_size - x) * rcp_bar_h;
410  DRAW_BAR_COLOR(x);
411  }
412  break;
413  case DIRECTION_RL:
414  dstY = s->outpicref->data[0] + y * ylinesize;
415  dstU = s->outpicref->data[1] + y * ulinesize;
416  dstV = s->outpicref->data[2] + y * vlinesize;
417  for (int x = 0; x < bar_size; x++) {
418  float ht = x * rcp_bar_h;
419  DRAW_BAR_COLOR(w - bar_size + x);
420  }
421  break;
422  case DIRECTION_UD:
423  dstY = s->outpicref->data[0] + w - 1 - y;
424  dstU = s->outpicref->data[1] + w - 1 - y;
425  dstV = s->outpicref->data[2] + w - 1 - y;
426  for (int x = 0; x < bar_size; x++) {
427  float ht = (bar_size - x) * rcp_bar_h;
428  DRAW_BAR_COLOR(0);
429  dstY += ylinesize;
430  dstU += ulinesize;
431  dstV += vlinesize;
432  }
433  break;
434  case DIRECTION_DU:
435  dstY = s->outpicref->data[0] + w - 1 - y + ylinesize * sono_size;
436  dstU = s->outpicref->data[1] + w - 1 - y + ulinesize * sono_size;
437  dstV = s->outpicref->data[2] + w - 1 - y + vlinesize * sono_size;
438  for (int x = 0; x < bar_size; x++) {
439  float ht = x * rcp_bar_h;
440  DRAW_BAR_COLOR(0);
441  dstY += ylinesize;
442  dstU += ulinesize;
443  dstV += vlinesize;
444  }
445  break;
446  }
447 }
448 
449 static int draw(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
450 {
451  ShowCWTContext *s = ctx->priv;
452  const ptrdiff_t ylinesize = s->outpicref->linesize[0];
453  const ptrdiff_t ulinesize = s->outpicref->linesize[1];
454  const ptrdiff_t vlinesize = s->outpicref->linesize[2];
455  const ptrdiff_t alinesize = s->outpicref->linesize[3];
456  const float log_factor = 1.f/logf(s->logarithmic_basis);
457  const int count = s->frequency_band_count;
458  const int start = (count * jobnr) / nb_jobs;
459  const int end = (count * (jobnr+1)) / nb_jobs;
460  const int nb_channels = s->nb_channels;
461  const int iscale = s->intensity_scale;
462  const int ihop_index = s->ihop_index;
463  const int ihop_size = s->ihop_size;
464  const float rotation = s->rotation;
465  const int direction = s->direction;
466  uint8_t *dstY, *dstU, *dstV, *dstA;
467  const int sono_size = s->sono_size;
468  const int bar_size = s->bar_size;
469  const int mode = s->mode;
470  const int w_1 = s->w - 1;
471  const int x = s->pos;
472  float Y, U, V;
473 
474  for (int y = start; y < end; y++) {
475  const AVComplexFloat *src = ((const AVComplexFloat *)s->ch_out->extended_data[y]) +
476  0 * ihop_size + ihop_index;
477 
478  if (sono_size <= 0)
479  goto skip;
480 
481  switch (direction) {
482  case DIRECTION_LR:
483  case DIRECTION_RL:
484  dstY = s->outpicref->data[0] + y * ylinesize;
485  dstU = s->outpicref->data[1] + y * ulinesize;
486  dstV = s->outpicref->data[2] + y * vlinesize;
487  dstA = s->outpicref->data[3] ? s->outpicref->data[3] + y * alinesize : NULL;
488  break;
489  case DIRECTION_UD:
490  case DIRECTION_DU:
491  dstY = s->outpicref->data[0] + x * ylinesize + w_1 - y;
492  dstU = s->outpicref->data[1] + x * ulinesize + w_1 - y;
493  dstV = s->outpicref->data[2] + x * vlinesize + w_1 - y;
494  dstA = s->outpicref->data[3] ? s->outpicref->data[3] + x * alinesize + w_1 - y : NULL;
495  break;
496  }
497 
498  switch (s->slide) {
499  case SLIDE_REPLACE:
500  case SLIDE_FRAME:
501  /* nothing to do here */
502  break;
503  case SLIDE_SCROLL:
504  switch (s->direction) {
505  case DIRECTION_RL:
506  memmove(dstY, dstY + 1, w_1);
507  memmove(dstU, dstU + 1, w_1);
508  memmove(dstV, dstV + 1, w_1);
509  if (dstA != NULL)
510  memmove(dstA, dstA + 1, w_1);
511  break;
512  case DIRECTION_LR:
513  memmove(dstY + 1, dstY, w_1);
514  memmove(dstU + 1, dstU, w_1);
515  memmove(dstV + 1, dstV, w_1);
516  if (dstA != NULL)
517  memmove(dstA + 1, dstA, w_1);
518  break;
519  }
520  break;
521  }
522 
523  if (direction == DIRECTION_RL ||
524  direction == DIRECTION_LR) {
525  dstY += x;
526  dstU += x;
527  dstV += x;
528  if (dstA != NULL)
529  dstA += x;
530  }
531 skip:
532 
533  switch (mode) {
534  case 4:
535  {
536  const AVComplexFloat *src2 = (nb_channels > 1) ? src + ihop_size: src;
537  float z, u, v;
538 
539  z = hypotf(src[0].re + src2[0].re, src[0].im + src2[0].im);
540  u = hypotf(src[0].re, src[0].im);
541  v = hypotf(src2[0].re, src2[0].im);
542 
543  z = remap_log(s, z, iscale, log_factor);
544  u = remap_log(s, u, iscale, log_factor);
545  v = remap_log(s, v, iscale, log_factor);
546 
547  Y = z;
548  U = sinf((v - u) * M_PI_2);
549  V = sinf((u - v) * M_PI_2);
550 
551  u = U * cosf(rotation * M_PI) - V * sinf(rotation * M_PI);
552  v = U * sinf(rotation * M_PI) + V * cosf(rotation * M_PI);
553 
554  U = 0.5f + 0.5f * z * u;
555  V = 0.5f + 0.5f * z * v;
556 
557  if (sono_size > 0) {
558  dstY[0] = av_clip_uint8(lrintf(Y * 255.f));
559  dstU[0] = av_clip_uint8(lrintf(U * 255.f));
560  dstV[0] = av_clip_uint8(lrintf(V * 255.f));
561  if (dstA)
562  dstA[0] = dstY[0];
563  }
564 
565  if (bar_size > 0)
566  draw_bar(s, y, Y, U, V);
567  }
568  break;
569  case 3:
570  {
571  const int nb_channels = s->nb_channels;
572  const float yf = 1.f / nb_channels;
573 
574  Y = 0.f;
575  U = V = 0.5f;
576  for (int ch = 0; ch < nb_channels; ch++) {
577  const AVComplexFloat *srcn = src + ihop_size * ch;
578  float z;
579 
580  z = hypotf(srcn[0].re, srcn[0].im);
581  z = remap_log(s, z, iscale, log_factor);
582 
583  Y += z * yf;
584  U += z * yf * sinf(2.f * M_PI * (ch * yf + rotation));
585  V += z * yf * cosf(2.f * M_PI * (ch * yf + rotation));
586  }
587 
588  if (sono_size > 0) {
589  dstY[0] = av_clip_uint8(lrintf(Y * 255.f));
590  dstU[0] = av_clip_uint8(lrintf(U * 255.f));
591  dstV[0] = av_clip_uint8(lrintf(V * 255.f));
592  if (dstA)
593  dstA[0] = dstY[0];
594  }
595 
596  if (bar_size > 0)
597  draw_bar(s, y, Y, U, V);
598  }
599  break;
600  case 2:
601  Y = hypotf(src[0].re, src[0].im);
602  Y = remap_log(s, Y, iscale, log_factor);
603  U = atan2f(src[0].im, src[0].re);
604  U = 0.5f + 0.5f * U * Y / M_PI;
605  V = 1.f - U;
606 
607  if (sono_size > 0) {
608  dstY[0] = av_clip_uint8(lrintf(Y * 255.f));
609  dstU[0] = av_clip_uint8(lrintf(U * 255.f));
610  dstV[0] = av_clip_uint8(lrintf(V * 255.f));
611  if (dstA)
612  dstA[0] = dstY[0];
613  }
614 
615  if (bar_size > 0)
616  draw_bar(s, y, Y, U, V);
617  break;
618  case 1:
619  Y = atan2f(src[0].im, src[0].re);
620  Y = 0.5f + 0.5f * Y / M_PI;
621 
622  if (sono_size > 0) {
623  dstY[0] = av_clip_uint8(lrintf(Y * 255.f));
624  if (dstA)
625  dstA[0] = dstY[0];
626  }
627 
628  if (bar_size > 0)
629  draw_bar(s, y, Y, 0.5f, 0.5f);
630  break;
631  case 0:
632  Y = hypotf(src[0].re, src[0].im);
633  Y = remap_log(s, Y, iscale, log_factor);
634 
635  if (sono_size > 0) {
636  dstY[0] = av_clip_uint8(lrintf(Y * 255.f));
637  if (dstA)
638  dstA[0] = dstY[0];
639  }
640 
641  if (bar_size > 0)
642  draw_bar(s, y, Y, 0.5f, 0.5f);
643  break;
644  }
645  }
646 
647  return 0;
648 }
649 
650 static int run_channel_cwt(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
651 {
652  ShowCWTContext *s = ctx->priv;
653  const int ch = *(int *)arg;
654  const AVComplexFloat *fft_out = (const AVComplexFloat *)s->fft_out->extended_data[ch];
655  AVComplexFloat *isrc = (AVComplexFloat *)s->ifft_in->extended_data[jobnr];
656  AVComplexFloat *idst = (AVComplexFloat *)s->ifft_out->extended_data[jobnr];
657  const int output_padding_size = s->output_padding_size;
658  const int input_padding_size = s->input_padding_size;
659  const float scale = 1.f / input_padding_size;
660  const int ihop_size = s->ihop_size;
661  const int count = s->frequency_band_count;
662  const int start = (count * jobnr) / nb_jobs;
663  const int end = (count * (jobnr+1)) / nb_jobs;
664 
665  for (int y = start; y < end; y++) {
666  AVComplexFloat *chout = ((AVComplexFloat *)s->ch_out->extended_data[y]) + ch * ihop_size;
667  AVComplexFloat *over = ((AVComplexFloat *)s->over->extended_data[ch]) + y * ihop_size;
668  AVComplexFloat *dstx = (AVComplexFloat *)s->dst_x->extended_data[jobnr];
669  AVComplexFloat *srcx = (AVComplexFloat *)s->src_x->extended_data[jobnr];
670  const AVComplexFloat *kernel = s->kernel[y];
671  const unsigned *index = (const unsigned *)s->index;
672  const int kernel_start = s->kernel_start[y];
673  const int kernel_stop = s->kernel_stop[y];
674  const int kernel_range = kernel_stop - kernel_start + 1;
675  int offset;
676 
677  if (kernel_start >= 0) {
678  offset = 0;
679  memcpy(srcx, fft_out + kernel_start, sizeof(*fft_out) * kernel_range);
680  } else {
681  offset = -kernel_start;
682  memcpy(srcx+offset, fft_out, sizeof(*fft_out) * (kernel_range-offset));
683  memcpy(srcx, fft_out+input_padding_size-offset, sizeof(*fft_out)*offset);
684  }
685 
686  s->fdsp->vector_fmul_scalar((float *)srcx, (const float *)srcx, scale, FFALIGN(kernel_range * 2, 4));
687  s->fdsp->vector_fmul((float *)dstx, (const float *)srcx,
688  (const float *)kernel, FFALIGN(kernel_range * 2, 16));
689 
690  memset(isrc, 0, sizeof(*isrc) * output_padding_size);
691  if (offset == 0) {
692  const unsigned *kindex = index + kernel_start;
693  for (int i = 0; i < kernel_range; i++) {
694  const unsigned n = kindex[i];
695 
696  isrc[n].re += dstx[i].re;
697  isrc[n].im += dstx[i].im;
698  }
699  } else {
700  for (int i = 0; i < kernel_range; i++) {
701  const unsigned n = (i-kernel_start) & (output_padding_size-1);
702 
703  isrc[n].re += dstx[i].re;
704  isrc[n].im += dstx[i].im;
705  }
706  }
707 
708  s->itx_fn(s->ifft[jobnr], idst, isrc, sizeof(*isrc));
709 
710  memcpy(chout, idst, sizeof(*chout) * ihop_size);
711  for (int n = 0; n < ihop_size; n++) {
712  chout[n].re += over[n].re;
713  chout[n].im += over[n].im;
714  }
715  memcpy(over, idst + ihop_size, sizeof(*over) * ihop_size);
716  }
717 
718  return 0;
719 }
720 
722 {
723  ShowCWTContext *s = ctx->priv;
724  const int size = s->input_padding_size;
725  const int output_sample_count = s->output_sample_count;
726  const int fsize = s->frequency_band_count;
727  int *kernel_start = s->kernel_start;
728  int *kernel_stop = s->kernel_stop;
729  unsigned *index = s->index;
730  int range_min = INT_MAX;
731  int range_max = 0, ret = 0;
732  float *tkernel;
733 
734  tkernel = av_malloc_array(size, sizeof(*tkernel));
735  if (!tkernel)
736  return AVERROR(ENOMEM);
737 
738  for (int y = 0; y < fsize; y++) {
739  AVComplexFloat *kernel = s->kernel[y];
740  int start = INT_MIN, stop = INT_MAX;
741  const float frequency = s->frequency_band[y*2];
742  const float deviation = 1.f / (s->frequency_band[y*2+1] *
743  output_sample_count);
744  const int a = FFMAX(frequency-12.f*sqrtf(1.f/deviation)-0.5f, -size);
745  const int b = FFMIN(frequency+12.f*sqrtf(1.f/deviation)-0.5f, size+a);
746  const int range = -a;
747 
748  memset(tkernel, 0, size * sizeof(*tkernel));
749  for (int n = a; n < b; n++) {
750  float ff, f = n+0.5f-frequency;
751 
752  ff = expf(-f*f*deviation);
753  tkernel[n+range] = ff;
754  }
755 
756  for (int n = a; n < b; n++) {
757  if (tkernel[n+range] != 0.f) {
758  if (tkernel[n+range] > FLT_MIN)
759  av_log(ctx, AV_LOG_DEBUG, "out of range kernel %g\n", tkernel[n+range]);
760  start = n;
761  break;
762  }
763  }
764 
765  for (int n = b; n >= a; n--) {
766  if (tkernel[n+range] != 0.f) {
767  if (tkernel[n+range] > FLT_MIN)
768  av_log(ctx, AV_LOG_DEBUG, "out of range kernel %g\n", tkernel[n+range]);
769  stop = n;
770  break;
771  }
772  }
773 
774  if (start == INT_MIN || stop == INT_MAX) {
775  ret = AVERROR(EINVAL);
776  break;
777  }
778 
779  kernel_start[y] = start;
780  kernel_stop[y] = stop;
781 
782  kernel = av_calloc(FFALIGN(stop-start+1, 16), sizeof(*kernel));
783  if (!kernel) {
784  ret = AVERROR(ENOMEM);
785  break;
786  }
787 
788  for (int n = 0; n <= stop - start; n++) {
789  kernel[n].re = tkernel[n+range+start];
790  kernel[n].im = tkernel[n+range+start];
791  }
792 
793  range_min = FFMIN(range_min, stop+1-start);
794  range_max = FFMAX(range_max, stop+1-start);
795 
796  s->kernel[y] = kernel;
797  }
798 
799  for (int n = 0; n < size; n++)
800  index[n] = n & (s->output_padding_size - 1);
801 
802  av_log(ctx, AV_LOG_DEBUG, "range_min: %d\n", range_min);
803  av_log(ctx, AV_LOG_DEBUG, "range_max: %d\n", range_max);
804 
805  av_freep(&tkernel);
806 
807  return ret;
808 }
809 
810 static int config_output(AVFilterLink *outlink)
811 {
812  FilterLink *l = ff_filter_link(outlink);
813  AVFilterContext *ctx = outlink->src;
814  AVFilterLink *inlink = ctx->inputs[0];
815  ShowCWTContext *s = ctx->priv;
816  const float limit_frequency = inlink->sample_rate * 0.5f;
817  float maximum_frequency = fminf(s->maximum_frequency, limit_frequency);
818  float minimum_frequency = s->minimum_frequency;
819  float scale = 1.f, factor;
820  int ret;
821 
822  if (minimum_frequency >= maximum_frequency) {
823  av_log(ctx, AV_LOG_ERROR, "min frequency (%f) >= (%f) max frequency\n",
824  minimum_frequency, maximum_frequency);
825  return AVERROR(EINVAL);
826  }
827 
828  uninit(ctx);
829 
830  s->fdsp = avpriv_float_dsp_alloc(0);
831  if (!s->fdsp)
832  return AVERROR(ENOMEM);
833 
834  switch (s->direction) {
835  case DIRECTION_LR:
836  case DIRECTION_RL:
837  s->bar_size = s->w * s->bar_ratio;
838  s->sono_size = s->w - s->bar_size;
839  s->frequency_band_count = s->h;
840  break;
841  case DIRECTION_UD:
842  case DIRECTION_DU:
843  s->bar_size = s->h * s->bar_ratio;
844  s->sono_size = s->h - s->bar_size;
845  s->frequency_band_count = s->w;
846  break;
847  }
848 
849  switch (s->frequency_scale) {
850  case FSCALE_LOG:
851  minimum_frequency = logf(minimum_frequency) / logf(2.f);
852  maximum_frequency = logf(maximum_frequency) / logf(2.f);
853  break;
854  case FSCALE_BARK:
855  minimum_frequency = 6.f * asinhf(minimum_frequency / 600.f);
856  maximum_frequency = 6.f * asinhf(maximum_frequency / 600.f);
857  break;
858  case FSCALE_MEL:
859  minimum_frequency = 2595.f * log10f(1.f + minimum_frequency / 700.f);
860  maximum_frequency = 2595.f * log10f(1.f + maximum_frequency / 700.f);
861  break;
862  case FSCALE_ERBS:
863  minimum_frequency = 11.17268f * logf(1.f + (46.06538f * minimum_frequency) / (minimum_frequency + 14678.49f));
864  maximum_frequency = 11.17268f * logf(1.f + (46.06538f * maximum_frequency) / (maximum_frequency + 14678.49f));
865  break;
866  case FSCALE_SQRT:
867  minimum_frequency = sqrtf(minimum_frequency);
868  maximum_frequency = sqrtf(maximum_frequency);
869  break;
870  case FSCALE_CBRT:
871  minimum_frequency = cbrtf(minimum_frequency);
872  maximum_frequency = cbrtf(maximum_frequency);
873  break;
874  case FSCALE_QDRT:
875  minimum_frequency = powf(minimum_frequency, 0.25f);
876  maximum_frequency = powf(maximum_frequency, 0.25f);
877  break;
878  case FSCALE_FM:
879  minimum_frequency = powf(9.f * (minimum_frequency * minimum_frequency) / 4.f, 1.f / 3.f);
880  maximum_frequency = powf(9.f * (maximum_frequency * maximum_frequency) / 4.f, 1.f / 3.f);
881  break;
882  }
883 
884  s->frequency_band = av_calloc(s->frequency_band_count,
885  sizeof(*s->frequency_band) * 2);
886  if (!s->frequency_band)
887  return AVERROR(ENOMEM);
888 
889  s->nb_consumed_samples = inlink->sample_rate *
890  frequency_band(s->frequency_band,
891  s->frequency_band_count, maximum_frequency - minimum_frequency,
892  minimum_frequency, s->frequency_scale, s->deviation);
893  s->nb_consumed_samples = FFMIN(s->nb_consumed_samples, 65536);
894 
895  s->nb_threads = FFMIN(s->frequency_band_count, ff_filter_get_nb_threads(ctx));
896  s->nb_channels = inlink->ch_layout.nb_channels;
897  s->old_pts = AV_NOPTS_VALUE;
898  s->eof_pts = AV_NOPTS_VALUE;
899 
900  s->input_sample_count = 1 << (32 - ff_clz(s->nb_consumed_samples));
901  s->input_padding_size = 1 << (32 - ff_clz(s->input_sample_count));
902  s->output_sample_count = FFMAX(1, av_rescale(s->input_sample_count, s->pps, inlink->sample_rate));
903  s->output_padding_size = 1 << (32 - ff_clz(s->output_sample_count));
904 
905  s->hop_size = s->input_sample_count;
906  s->ihop_size = s->output_padding_size >> 1;
907 
908  outlink->w = s->w;
909  outlink->h = s->h;
910  outlink->sample_aspect_ratio = (AVRational){1,1};
911 
912  s->fft_size = FFALIGN(s->input_padding_size, av_cpu_max_align());
913  s->ifft_size = FFALIGN(s->output_padding_size, av_cpu_max_align());
914 
915  s->fft = av_calloc(s->nb_threads, sizeof(*s->fft));
916  if (!s->fft)
917  return AVERROR(ENOMEM);
918 
919  for (int n = 0; n < s->nb_threads; n++) {
920  ret = av_tx_init(&s->fft[n], &s->tx_fn, AV_TX_FLOAT_FFT, 0, s->input_padding_size, &scale, 0);
921  if (ret < 0)
922  return ret;
923  }
924 
925  s->ifft = av_calloc(s->nb_threads, sizeof(*s->ifft));
926  if (!s->ifft)
927  return AVERROR(ENOMEM);
928 
929  for (int n = 0; n < s->nb_threads; n++) {
930  ret = av_tx_init(&s->ifft[n], &s->itx_fn, AV_TX_FLOAT_FFT, 1, s->output_padding_size, &scale, 0);
931  if (ret < 0)
932  return ret;
933  }
934 
935  s->outpicref = ff_get_video_buffer(outlink, outlink->w, outlink->h);
936  s->fft_in = ff_get_audio_buffer(inlink, s->fft_size * 2);
937  s->fft_out = ff_get_audio_buffer(inlink, s->fft_size * 2);
938  s->dst_x = av_frame_alloc();
939  s->src_x = av_frame_alloc();
940  s->kernel = av_calloc(s->frequency_band_count, sizeof(*s->kernel));
941  s->cache = ff_get_audio_buffer(inlink, s->hop_size);
942  s->over = ff_get_audio_buffer(inlink, s->frequency_band_count * 2 * s->ihop_size);
943  s->bh_out = ff_get_audio_buffer(inlink, s->frequency_band_count);
944  s->ifft_in = av_frame_alloc();
945  s->ifft_out = av_frame_alloc();
946  s->ch_out = av_frame_alloc();
947  s->index = av_calloc(s->input_padding_size, sizeof(*s->index));
948  s->kernel_start = av_calloc(s->frequency_band_count, sizeof(*s->kernel_start));
949  s->kernel_stop = av_calloc(s->frequency_band_count, sizeof(*s->kernel_stop));
950  if (!s->outpicref || !s->fft_in || !s->fft_out || !s->src_x || !s->dst_x || !s->over ||
951  !s->ifft_in || !s->ifft_out || !s->kernel_start || !s->kernel_stop || !s->ch_out ||
952  !s->cache || !s->index || !s->bh_out || !s->kernel)
953  return AVERROR(ENOMEM);
954 
955  s->ch_out->format = inlink->format;
956  s->ch_out->nb_samples = 2 * s->ihop_size * inlink->ch_layout.nb_channels;
957  s->ch_out->ch_layout.nb_channels = s->frequency_band_count;
958  ret = av_frame_get_buffer(s->ch_out, 0);
959  if (ret < 0)
960  return ret;
961 
962  s->ifft_in->format = inlink->format;
963  s->ifft_in->nb_samples = s->ifft_size * 2;
964  s->ifft_in->ch_layout.nb_channels = s->nb_threads;
965  ret = av_frame_get_buffer(s->ifft_in, 0);
966  if (ret < 0)
967  return ret;
968 
969  s->ifft_out->format = inlink->format;
970  s->ifft_out->nb_samples = s->ifft_size * 2;
971  s->ifft_out->ch_layout.nb_channels = s->nb_threads;
972  ret = av_frame_get_buffer(s->ifft_out, 0);
973  if (ret < 0)
974  return ret;
975 
976  s->src_x->format = inlink->format;
977  s->src_x->nb_samples = s->fft_size * 2;
978  s->src_x->ch_layout.nb_channels = s->nb_threads;
979  ret = av_frame_get_buffer(s->src_x, 0);
980  if (ret < 0)
981  return ret;
982 
983  s->dst_x->format = inlink->format;
984  s->dst_x->nb_samples = s->fft_size * 2;
985  s->dst_x->ch_layout.nb_channels = s->nb_threads;
986  ret = av_frame_get_buffer(s->dst_x, 0);
987  if (ret < 0)
988  return ret;
989 
990  s->outpicref->sample_aspect_ratio = (AVRational){1,1};
991 
992  for (int y = 0; y < outlink->h; y++) {
993  memset(s->outpicref->data[0] + y * s->outpicref->linesize[0], 0, outlink->w);
994  memset(s->outpicref->data[1] + y * s->outpicref->linesize[1], 128, outlink->w);
995  memset(s->outpicref->data[2] + y * s->outpicref->linesize[2], 128, outlink->w);
996  if (s->outpicref->data[3])
997  memset(s->outpicref->data[3] + y * s->outpicref->linesize[3], 0, outlink->w);
998  }
999 
1000  s->outpicref->color_range = AVCOL_RANGE_JPEG;
1001 
1002  factor = s->input_padding_size / (float)inlink->sample_rate;
1003  for (int n = 0; n < s->frequency_band_count; n++) {
1004  s->frequency_band[2*n ] *= factor;
1005  s->frequency_band[2*n+1] *= factor;
1006  }
1007 
1008  av_log(ctx, AV_LOG_DEBUG, "factor: %f\n", factor);
1009  av_log(ctx, AV_LOG_DEBUG, "nb_consumed_samples: %d\n", s->nb_consumed_samples);
1010  av_log(ctx, AV_LOG_DEBUG, "hop_size: %d\n", s->hop_size);
1011  av_log(ctx, AV_LOG_DEBUG, "ihop_size: %d\n", s->ihop_size);
1012  av_log(ctx, AV_LOG_DEBUG, "input_sample_count: %d\n", s->input_sample_count);
1013  av_log(ctx, AV_LOG_DEBUG, "input_padding_size: %d\n", s->input_padding_size);
1014  av_log(ctx, AV_LOG_DEBUG, "output_sample_count: %d\n", s->output_sample_count);
1015  av_log(ctx, AV_LOG_DEBUG, "output_padding_size: %d\n", s->output_padding_size);
1016 
1017  switch (s->direction) {
1018  case DIRECTION_LR:
1019  case DIRECTION_UD:
1020  s->pos = s->bar_size;
1021  break;
1022  case DIRECTION_RL:
1023  case DIRECTION_DU:
1024  s->pos = s->sono_size;
1025  break;
1026  }
1027 
1028  s->auto_frame_rate = av_make_q(inlink->sample_rate, s->hop_size);
1029  if (strcmp(s->rate_str, "auto")) {
1030  ret = av_parse_video_rate(&s->frame_rate, s->rate_str);
1031  if (ret < 0)
1032  return ret;
1033  } else {
1034  s->frame_rate = s->auto_frame_rate;
1035  }
1036  l->frame_rate = s->frame_rate;
1037  outlink->time_base = av_inv_q(l->frame_rate);
1038 
1039  ret = compute_kernel(ctx);
1040  if (ret < 0)
1041  return ret;
1042 
1043  return 0;
1044 }
1045 
1047 {
1048  AVFilterLink *outlink = ctx->outputs[0];
1049  AVFilterLink *inlink = ctx->inputs[0];
1050  ShowCWTContext *s = ctx->priv;
1051  const int nb_planes = 3 + (s->outpicref->data[3] != NULL);
1052  int ret;
1053 
1054  switch (s->slide) {
1055  case SLIDE_SCROLL:
1056  switch (s->direction) {
1057  case DIRECTION_UD:
1058  for (int p = 0; p < nb_planes; p++) {
1059  ptrdiff_t linesize = s->outpicref->linesize[p];
1060 
1061  for (int y = s->h - 1; y > s->bar_size; y--) {
1062  uint8_t *dst = s->outpicref->data[p] + y * linesize;
1063 
1064  memmove(dst, dst - linesize, s->w);
1065  }
1066  }
1067  break;
1068  case DIRECTION_DU:
1069  for (int p = 0; p < nb_planes; p++) {
1070  ptrdiff_t linesize = s->outpicref->linesize[p];
1071 
1072  for (int y = 0; y < s->sono_size; y++) {
1073  uint8_t *dst = s->outpicref->data[p] + y * linesize;
1074 
1075  memmove(dst, dst + linesize, s->w);
1076  }
1077  }
1078  break;
1079  }
1080  break;
1081  }
1082 
1083  ff_filter_execute(ctx, draw, NULL, NULL, s->nb_threads);
1084 
1085  switch (s->slide) {
1086  case SLIDE_REPLACE:
1087  case SLIDE_FRAME:
1088  switch (s->direction) {
1089  case DIRECTION_LR:
1090  s->pos++;
1091  if (s->pos >= s->w) {
1092  s->pos = s->bar_size;
1093  s->new_frame = 1;
1094  }
1095  break;
1096  case DIRECTION_RL:
1097  s->pos--;
1098  if (s->pos < 0) {
1099  s->pos = s->sono_size;
1100  s->new_frame = 1;
1101  }
1102  break;
1103  case DIRECTION_UD:
1104  s->pos++;
1105  if (s->pos >= s->h) {
1106  s->pos = s->bar_size;
1107  s->new_frame = 1;
1108  }
1109  break;
1110  case DIRECTION_DU:
1111  s->pos--;
1112  if (s->pos < 0) {
1113  s->pos = s->sono_size;
1114  s->new_frame = 1;
1115  }
1116  break;
1117  }
1118  break;
1119  case SLIDE_SCROLL:
1120  switch (s->direction) {
1121  case DIRECTION_UD:
1122  case DIRECTION_LR:
1123  s->pos = s->bar_size;
1124  break;
1125  case DIRECTION_RL:
1126  case DIRECTION_DU:
1127  s->pos = s->sono_size;
1128  break;
1129  }
1130  break;
1131  }
1132 
1133  if (s->slide == SLIDE_FRAME && s->eof) {
1134  switch (s->direction) {
1135  case DIRECTION_LR:
1136  for (int p = 0; p < nb_planes; p++) {
1137  ptrdiff_t linesize = s->outpicref->linesize[p];
1138  const int size = s->w - s->pos;
1139  const int fill = p > 0 && p < 3 ? 128 : 0;
1140  const int x = s->pos;
1141 
1142  for (int y = 0; y < s->h; y++) {
1143  uint8_t *dst = s->outpicref->data[p] + y * linesize + x;
1144 
1145  memset(dst, fill, size);
1146  }
1147  }
1148  break;
1149  case DIRECTION_RL:
1150  for (int p = 0; p < nb_planes; p++) {
1151  ptrdiff_t linesize = s->outpicref->linesize[p];
1152  const int size = s->w - s->pos;
1153  const int fill = p > 0 && p < 3 ? 128 : 0;
1154 
1155  for (int y = 0; y < s->h; y++) {
1156  uint8_t *dst = s->outpicref->data[p] + y * linesize;
1157 
1158  memset(dst, fill, size);
1159  }
1160  }
1161  break;
1162  case DIRECTION_UD:
1163  for (int p = 0; p < nb_planes; p++) {
1164  ptrdiff_t linesize = s->outpicref->linesize[p];
1165  const int fill = p > 0 && p < 3 ? 128 : 0;
1166 
1167  for (int y = s->pos; y < s->h; y++) {
1168  uint8_t *dst = s->outpicref->data[p] + y * linesize;
1169 
1170  memset(dst, fill, s->w);
1171  }
1172  }
1173  break;
1174  case DIRECTION_DU:
1175  for (int p = 0; p < nb_planes; p++) {
1176  ptrdiff_t linesize = s->outpicref->linesize[p];
1177  const int fill = p > 0 && p < 3 ? 128 : 0;
1178 
1179  for (int y = s->h - s->pos; y >= 0; y--) {
1180  uint8_t *dst = s->outpicref->data[p] + y * linesize;
1181 
1182  memset(dst, fill, s->w);
1183  }
1184  }
1185  break;
1186  }
1187  }
1188 
1189  s->new_frame = s->slide == SLIDE_FRAME && (s->new_frame || s->eof);
1190 
1191  if (s->slide != SLIDE_FRAME || s->new_frame == 1) {
1192  int64_t pts_offset = s->new_frame ? 0LL : av_rescale(s->ihop_index, s->hop_size, s->ihop_size);
1193  const int offset = (s->input_padding_size - s->hop_size) >> 1;
1194 
1195  pts_offset = av_rescale_q(pts_offset - offset, av_make_q(1, inlink->sample_rate), inlink->time_base);
1196  s->outpicref->pts = av_rescale_q(s->in_pts + pts_offset, inlink->time_base, outlink->time_base);
1197  s->outpicref->duration = 1;
1198  }
1199 
1200  s->ihop_index++;
1201  if (s->ihop_index >= s->ihop_size)
1202  s->ihop_index = s->hop_index = 0;
1203 
1204  if (s->slide == SLIDE_FRAME && s->new_frame == 0)
1205  return 1;
1206 
1207  if (s->old_pts < s->outpicref->pts) {
1208  AVFrame *out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
1209  if (!out)
1210  return AVERROR(ENOMEM);
1211  ret = av_frame_copy_props(out, s->outpicref);
1212  if (ret < 0)
1213  goto fail;
1214  ret = av_frame_copy(out, s->outpicref);
1215  if (ret < 0)
1216  goto fail;
1217  s->old_pts = s->outpicref->pts;
1218  s->new_frame = 0;
1219  ret = ff_filter_frame(outlink, out);
1220  if (ret <= 0)
1221  return ret;
1222 fail:
1223  av_frame_free(&out);
1224  return ret;
1225  }
1226 
1227  return 1;
1228 }
1229 
1230 static int run_channels_cwt_prepare(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
1231 {
1232  ShowCWTContext *s = ctx->priv;
1233  const int count = s->nb_channels;
1234  const int start = (count * jobnr) / nb_jobs;
1235  const int end = (count * (jobnr+1)) / nb_jobs;
1236 
1237  for (int ch = start; ch < end; ch++)
1238  run_channel_cwt_prepare(ctx, arg, jobnr, ch);
1239 
1240  return 0;
1241 }
1242 
1244 {
1245  AVFilterLink *inlink = ctx->inputs[0];
1246  AVFilterLink *outlink = ctx->outputs[0];
1247  ShowCWTContext *s = ctx->priv;
1248  int ret = 0, status;
1249  int64_t pts;
1250 
1252 
1253  if (s->outpicref) {
1254  AVFrame *fin = NULL;
1255 
1256  if (s->hop_index < s->hop_size) {
1257  if (!s->eof) {
1258  ret = ff_inlink_consume_samples(inlink, 1, s->hop_size - s->hop_index, &fin);
1259  if (ret < 0)
1260  return ret;
1261  }
1262 
1263  if (ret > 0 || s->eof) {
1265  FFMIN(s->nb_threads, s->nb_channels));
1266  if (fin) {
1267  if (s->hop_index == 0) {
1268  s->in_pts = fin->pts;
1269  if (s->old_pts == AV_NOPTS_VALUE)
1270  s->old_pts = av_rescale_q(s->in_pts, inlink->time_base, outlink->time_base) - 1;
1271  }
1272  s->hop_index += fin->nb_samples;
1273  av_frame_free(&fin);
1274  } else {
1275  s->hop_index = s->hop_size;
1276  }
1277  }
1278  }
1279 
1280  if (s->hop_index >= s->hop_size || s->ihop_index > 0) {
1281  for (int ch = 0; ch < s->nb_channels && s->ihop_index == 0; ch++) {
1282  ff_filter_execute(ctx, run_channel_cwt, (void *)&ch, NULL,
1283  s->nb_threads);
1284  }
1285 
1286  ret = output_frame(ctx);
1287  if (ret != 1)
1288  return ret;
1289  }
1290  }
1291 
1292  if (s->eof) {
1293  if (s->slide == SLIDE_FRAME)
1294  ret = output_frame(ctx);
1295  ff_outlink_set_status(outlink, AVERROR_EOF, s->eof_pts);
1296  return ret;
1297  }
1298 
1299  if (!s->eof && ff_inlink_acknowledge_status(inlink, &status, &pts)) {
1300  if (status == AVERROR_EOF) {
1301  s->eof = 1;
1302  ff_filter_set_ready(ctx, 10);
1303  s->eof_pts = av_rescale_q(pts, inlink->time_base, outlink->time_base);
1304  return 0;
1305  }
1306  }
1307 
1308  if (ff_inlink_queued_samples(inlink) > 0 || s->ihop_index ||
1309  s->hop_index >= s->hop_size || s->eof) {
1310  ff_filter_set_ready(ctx, 10);
1311  return 0;
1312  }
1313 
1314  if (ff_outlink_frame_wanted(outlink)) {
1316  return 0;
1317  }
1318 
1319  return FFERROR_NOT_READY;
1320 }
1321 
1322 static const AVFilterPad showcwt_outputs[] = {
1323  {
1324  .name = "default",
1325  .type = AVMEDIA_TYPE_VIDEO,
1326  .config_props = config_output,
1327  },
1328 };
1329 
1331  .name = "showcwt",
1332  .description = NULL_IF_CONFIG_SMALL("Convert input audio to a CWT (Continuous Wavelet Transform) spectrum video output."),
1333  .uninit = uninit,
1334  .priv_size = sizeof(ShowCWTContext),
1338  .activate = activate,
1339  .priv_class = &showcwt_class,
1340  .flags = AVFILTER_FLAG_SLICE_THREADS,
1341 };
ShowCWTContext::dst_x
AVFrame * dst_x
Definition: avf_showcwt.c:96
formats
formats
Definition: signature.h:47
ff_get_video_buffer
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:116
FSCALE_LINEAR
@ FSCALE_LINEAR
Definition: avf_showcwt.c:38
ISCALE_LINEAR
@ ISCALE_LINEAR
Definition: avf_showcwt.c:52
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:98
IntensityScale
IntensityScale
Definition: avf_showcwt.c:50
AV_SAMPLE_FMT_FLTP
@ AV_SAMPLE_FMT_FLTP
float, planar
Definition: samplefmt.h:66
AVFilterChannelLayouts
A list of supported channel layouts.
Definition: formats.h:85
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
ShowCWTContext::frequency_scale
int frequency_scale
Definition: avf_showcwt.c:118
FSCALE_FM
@ FSCALE_FM
Definition: avf_showcwt.c:46
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
ff_make_format_list
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:435
DIRECTION_LR
@ DIRECTION_LR
Definition: avf_showcwt.c:60
out
FILE * out
Definition: movenc.c:55
run_channels_cwt_prepare
static int run_channels_cwt_prepare(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: avf_showcwt.c:1230
av_frame_get_buffer
int av_frame_get_buffer(AVFrame *frame, int align)
Allocate new buffer(s) for audio or video data.
Definition: frame.c:290
u
#define u(width, name, range_min, range_max)
Definition: cbs_h2645.c:251
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1023
sample_fmts
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:948
ff_channel_layouts_ref
int ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts **ref)
Add *ref as a new reference to f.
Definition: formats.c:673
layouts
enum MovChannelLayoutTag * layouts
Definition: mov_chan.c:335
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
FSCALE_ERBS
@ FSCALE_ERBS
Definition: avf_showcwt.c:42
FFERROR_NOT_READY
return FFERROR_NOT_READY
Definition: filter_design.txt:204
AVTXContext
Definition: tx_priv.h:235
atan2f
#define atan2f(y, x)
Definition: libm.h:45
ShowCWTContext::input_sample_count
int input_sample_count
Definition: avf_showcwt.c:114
int64_t
long long int64_t
Definition: coverity.c:34
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
ShowCWTContext::rate_str
char * rate_str
Definition: avf_showcwt.c:78
ShowCWTContext::itx_fn
av_tx_fn itx_fn
Definition: avf_showcwt.c:82
ShowCWTContext::bar_size
int bar_size
Definition: avf_showcwt.c:123
ff_clz
#define ff_clz
Definition: intmath.h:143
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
ff_all_channel_counts
AVFilterChannelLayouts * ff_all_channel_counts(void)
Construct an AVFilterChannelLayouts coding for any channel layout, with known or unknown disposition.
Definition: formats.c:621
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: filters.h:262
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:374
FSCALE_SQRT
@ FSCALE_SQRT
Definition: avf_showcwt.c:43
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:486
w
uint8_t w
Definition: llviddspenc.c:38
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:686
FSCALE_LOG
@ FSCALE_LOG
Definition: avf_showcwt.c:39
M_PI_2
#define M_PI_2
Definition: mathematics.h:73
ISCALE_LOG
@ ISCALE_LOG
Definition: avf_showcwt.c:51
ShowCWTContext::bh_out
AVFrame * bh_out
Definition: avf_showcwt.c:102
AVOption
AVOption.
Definition: opt.h:429
ShowCWTContext::slide
int slide
Definition: avf_showcwt.c:108
b
#define b
Definition: input.c:41
showcwt_options
static const AVOption showcwt_options[]
Definition: avf_showcwt.c:133
ShowCWTContext::nb_threads
int nb_threads
Definition: avf_showcwt.c:103
expf
#define expf(x)
Definition: libm.h:283
FLAGS
#define FLAGS
Definition: avf_showcwt.c:131
float.h
AVComplexFloat
Definition: tx.h:27
max
#define max(a, b)
Definition: cuda_runtime.h:33
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:205
output_frame
static int output_frame(AVFilterContext *ctx)
Definition: avf_showcwt.c:1046
video.h
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:434
ShowCWTContext::index
unsigned * index
Definition: avf_showcwt.c:90
ShowCWTContext::ifft_size
int ifft_size
Definition: avf_showcwt.c:83
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
DIRECTION_RL
@ DIRECTION_RL
Definition: avf_showcwt.c:61
AVFilterFormats
A list of supported formats for one end of a filter link.
Definition: formats.h:64
formats.h
SLIDE_REPLACE
@ SLIDE_REPLACE
Definition: avf_showcwt.c:68
AVComplexFloat::im
float im
Definition: tx.h:28
ISCALE_QDRT
@ ISCALE_QDRT
Definition: avf_showcwt.c:55
ff_avf_showcwt
const AVFilter ff_avf_showcwt
Definition: avf_showcwt.c:1330
cosf
#define cosf(x)
Definition: libm.h:78
fail
#define fail()
Definition: checkasm.h:188
log10f
#define log10f(x)
Definition: libm.h:414
NB_FSCALE
@ NB_FSCALE
Definition: avf_showcwt.c:47
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: avf_showcwt.c:183
pts
static int64_t pts
Definition: transcode_aac.c:644
ShowCWTContext::kernel_start
int * kernel_start
Definition: avf_showcwt.c:91
ShowCWTContext::output_sample_count
int output_sample_count
Definition: avf_showcwt.c:114
FSCALE_CBRT
@ FSCALE_CBRT
Definition: avf_showcwt.c:44
AVFilterPad
A filter pad used for either input or output.
Definition: filters.h:38
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:148
ShowCWTContext::frequency_band
float * frequency_band
Definition: avf_showcwt.c:88
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
av_cold
#define av_cold
Definition: attributes.h:90
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
float
float
Definition: af_crystalizer.c:122
ff_outlink_set_status
static void ff_outlink_set_status(AVFilterLink *link, int status, int64_t pts)
Set the status field of a link from the source filter.
Definition: filters.h:424
ff_inlink_request_frame
void ff_inlink_request_frame(AVFilterLink *link)
Mark that a frame is wanted on the link.
Definition: avfilter.c:1578
s
#define s(width, name)
Definition: cbs_vp9.c:198
ShowCWTContext::logarithmic_basis
float logarithmic_basis
Definition: avf_showcwt.c:116
ShowCWTContext::eof_pts
int64_t eof_pts
Definition: avf_showcwt.c:87
ShowCWTContext::frequency_band_count
int frequency_band_count
Definition: avf_showcwt.c:115
ff_formats_ref
int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add *ref as a new reference to formats.
Definition: formats.c:678
ShowCWTContext::nb_channels
int nb_channels
Definition: avf_showcwt.c:104
fminf
float fminf(float, float)
filters.h
pix_fmts
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:304
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
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
ctx
AVFormatContext * ctx
Definition: movenc.c:49
ShowCWTContext::maximum_frequency
float maximum_frequency
Definition: avf_showcwt.c:119
av_rescale_q
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
ShowCWTContext::direction
int direction
Definition: avf_showcwt.c:110
ShowCWTContext
Definition: avf_showcwt.c:74
ShowCWTContext::fft_in
AVFrame * fft_in
Definition: avf_showcwt.c:94
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: filters.h:263
fsize
static int64_t fsize(FILE *f)
Definition: audiomatch.c:29
ShowCWTContext::ifft_out
AVFrame * ifft_out
Definition: avf_showcwt.c:99
AV_PIX_FMT_YUVJ444P
@ AV_PIX_FMT_YUVJ444P
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
Definition: pixfmt.h:87
ShowCWTContext::fft
AVTXContext ** fft
Definition: avf_showcwt.c:81
arg
const char * arg
Definition: jacosubdec.c:67
ShowCWTContext::deviation
float deviation
Definition: avf_showcwt.c:121
if
if(ret)
Definition: filter_design.txt:179
ShowCWTContext::ch_out
AVFrame * ch_out
Definition: avf_showcwt.c:100
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:1471
NULL
#define NULL
Definition: coverity.c:32
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:711
ShowCWTContext::rotation
float rotation
Definition: avf_showcwt.c:125
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
ShowCWTContext::bar_ratio
float bar_ratio
Definition: avf_showcwt.c:122
AV_OPT_TYPE_IMAGE_SIZE
@ AV_OPT_TYPE_IMAGE_SIZE
Underlying C type is two consecutive integers.
Definition: opt.h:303
ShowCWTContext::ihop_size
int ihop_size
Definition: avf_showcwt.c:111
V
#define V
Definition: avdct.c:31
ShowCWTContext::outpicref
AVFrame * outpicref
Definition: avf_showcwt.c:93
parseutils.h
ShowCWTContext::ihop_index
int ihop_index
Definition: avf_showcwt.c:112
ShowCWTContext::cache
AVFrame * cache
Definition: avf_showcwt.c:92
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:34
sqrtf
static __device__ float sqrtf(float a)
Definition: cuda_runtime.h:184
av_cpu_max_align
size_t av_cpu_max_align(void)
Get the maximum data alignment that may be required by FFmpeg.
Definition: cpu.c:272
ShowCWTContext::kernel
AVComplexFloat ** kernel
Definition: avf_showcwt.c:89
ShowCWTContext::h
int h
Definition: avf_showcwt.c:76
sinf
#define sinf(x)
Definition: libm.h:419
av_clipf
av_clipf
Definition: af_crystalizer.c:122
DIRECTION_DU
@ DIRECTION_DU
Definition: avf_showcwt.c:63
compute_kernel
static int compute_kernel(AVFilterContext *ctx)
Definition: avf_showcwt.c:721
ISCALE_CBRT
@ ISCALE_CBRT
Definition: avf_showcwt.c:54
ff_inlink_acknowledge_status
int ff_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts)
Test and acknowledge the change of status on the link.
Definition: avfilter.c:1398
index
int index
Definition: gxfenc.c:90
ff_filter_link
static FilterLink * ff_filter_link(AVFilterLink *link)
Definition: filters.h:197
float_dsp.h
ShowCWTContext::fft_out
AVFrame * fft_out
Definition: avf_showcwt.c:95
ShowCWTContext::over
AVFrame * over
Definition: avf_showcwt.c:101
f
f
Definition: af_crystalizer.c:122
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
powf
#define powf(x, y)
Definition: libm.h:50
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:83
av_frame_copy
int av_frame_copy(AVFrame *dst, const AVFrame *src)
Copy the frame data from src to dst.
Definition: frame.c:1001
cpu.h
ISCALE_SQRT
@ ISCALE_SQRT
Definition: avf_showcwt.c:53
ShowCWTContext::src_x
AVFrame * src_x
Definition: avf_showcwt.c:97
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:425
run_channel_cwt
static int run_channel_cwt(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: avf_showcwt.c:650
AV_SAMPLE_FMT_NONE
@ AV_SAMPLE_FMT_NONE
Definition: samplefmt.h:56
size
int size
Definition: twinvq_data.h:10344
av_make_q
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition: rational.h:71
ShowCWTContext::in_pts
int64_t in_pts
Definition: avf_showcwt.c:85
AVComplexFloat::re
float re
Definition: tx.h:28
ShowCWTContext::maximum_intensity
float maximum_intensity
Definition: avf_showcwt.c:120
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
ShowCWTContext::intensity_scale
int intensity_scale
Definition: avf_showcwt.c:117
DIRECTION_UD
@ DIRECTION_UD
Definition: avf_showcwt.c:62
AVFloatDSPContext
Definition: float_dsp.h:24
range
enum AVColorRange range
Definition: mediacodec_wrapper.c:2464
ShowCWTContext::mode
int mode
Definition: avf_showcwt.c:77
query_formats
static int query_formats(AVFilterContext *ctx)
Definition: avf_showcwt.c:225
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
FrequencyScale
FrequencyScale
Definition: avf_showcwt.c:37
AV_PIX_FMT_YUVA444P
@ AV_PIX_FMT_YUVA444P
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
Definition: pixfmt.h:174
ShowCWTContext::minimum_intensity
float minimum_intensity
Definition: avf_showcwt.c:120
draw_bar
static void draw_bar(ShowCWTContext *s, int y, float Y, float U, float V)
Definition: avf_showcwt.c:388
frequency_band
static float frequency_band(float *frequency_band, int frequency_band_count, float frequency_range, float frequency_offset, int frequency_scale, float deviation)
Definition: avf_showcwt.c:254
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
ShowCWTContext::ifft
AVTXContext ** ifft
Definition: avf_showcwt.c:81
input
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
Definition: filter_design.txt:172
M_PI
#define M_PI
Definition: mathematics.h:67
Y
#define Y
Definition: boxblur.h:37
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
NB_DIRECTION
@ NB_DIRECTION
Definition: avf_showcwt.c:64
draw
static int draw(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: avf_showcwt.c:449
AV_OPT_TYPE_FLOAT
@ AV_OPT_TYPE_FLOAT
Underlying C type is float.
Definition: opt.h:271
ShowCWTContext::nb_consumed_samples
int nb_consumed_samples
Definition: avf_showcwt.c:105
av_parse_video_rate
int av_parse_video_rate(AVRational *rate, const char *arg)
Parse str and store the detected values in *rate.
Definition: parseutils.c:181
ShowCWTContext::output_padding_size
int output_padding_size
Definition: avf_showcwt.c:113
AVFrame::nb_samples
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:454
lrintf
#define lrintf(x)
Definition: libm_mips.h:72
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
ShowCWTContext::kernel_stop
int * kernel_stop
Definition: avf_showcwt.c:91
run_channel_cwt_prepare
static int run_channel_cwt_prepare(AVFilterContext *ctx, void *arg, int jobnr, int ch)
Definition: avf_showcwt.c:344
AVFrame::extended_data
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:435
DirectionMode
DirectionMode
Definition: avf_showcwt.c:59
src2
const pixel * src2
Definition: h264pred_template.c:422
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:31
NB_SLIDE
@ NB_SLIDE
Definition: avf_showcwt.c:71
ff_filter_get_nb_threads
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:834
AVSampleFormat
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:55
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
cbrtf
static av_always_inline float cbrtf(float x)
Definition: libm.h:61
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(showcwt)
av_inv_q
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition: rational.h:159
ShowCWTContext::tx_fn
av_tx_fn tx_fn
Definition: avf_showcwt.c:82
ShowCWTContext::sono_size
int sono_size
Definition: avf_showcwt.c:124
OFFSET
#define OFFSET(x)
Definition: avf_showcwt.c:130
AVFilterPad::name
const char * name
Pad name.
Definition: filters.h:44
ff_inlink_queued_samples
int ff_inlink_queued_samples(AVFilterLink *link)
Definition: avfilter.c:1426
av_rescale
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
ShowCWTContext::minimum_frequency
float minimum_frequency
Definition: avf_showcwt.c:119
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
activate
static int activate(AVFilterContext *ctx)
Definition: avf_showcwt.c:1243
ShowCWTContext::auto_frame_rate
AVRational auto_frame_rate
Definition: avf_showcwt.c:79
ShowCWTContext::hop_index
int hop_index
Definition: avf_showcwt.c:112
AVFilter
Filter definition.
Definition: avfilter.h:201
ret
ret
Definition: filter_design.txt:187
ShowCWTContext::frame_rate
AVRational frame_rate
Definition: avf_showcwt.c:80
NB_ISCALE
@ NB_ISCALE
Definition: avf_showcwt.c:56
ShowCWTContext::fdsp
AVFloatDSPContext * fdsp
Definition: avf_showcwt.c:127
ShowCWTContext::pos
int pos
Definition: avf_showcwt.c:84
config_output
static int config_output(AVFilterLink *outlink)
Definition: avf_showcwt.c:810
U
#define U(x)
Definition: vpx_arith.h:37
FSCALE_QDRT
@ FSCALE_QDRT
Definition: avf_showcwt.c:45
SLIDE_SCROLL
@ SLIDE_SCROLL
Definition: avf_showcwt.c:69
ShowCWTContext::fft_size
int fft_size
Definition: avf_showcwt.c:83
ShowCWTContext::pps
int pps
Definition: avf_showcwt.c:106
ff_all_samplerates
AVFilterFormats * ff_all_samplerates(void)
Definition: formats.c:606
status
ov_status_e status
Definition: dnn_backend_openvino.c:100
channel_layout.h
ff_filter_execute
int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg, int *ret, int nb_jobs)
Definition: avfilter.c:1651
mode
mode
Definition: ebur128.h:83
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
avfilter.h
DRAW_BAR_COLOR
#define DRAW_BAR_COLOR(x)
Definition: avf_showcwt.c:374
pps
uint64_t pps
Definition: dovi_rpuenc.c:35
av_clip_uint8
#define av_clip_uint8
Definition: common.h:106
AV_PIX_FMT_YUV444P
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:78
AVFilterContext
An instance of a filter.
Definition: avfilter.h:457
factor
static const int factor[16]
Definition: vf_pp7.c:80
ShowCWTContext::old_pts
int64_t old_pts
Definition: avf_showcwt.c:86
ShowCWTContext::hop_size
int hop_size
Definition: avf_showcwt.c:111
ShowCWTContext::eof
int eof
Definition: avf_showcwt.c:107
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:152
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
mem.h
audio.h
AVFilterFormatsConfig::formats
AVFilterFormats * formats
List of supported formats (pixel or sample).
Definition: avfilter.h:116
ShowCWTContext::w
int w
Definition: avf_showcwt.c:76
FSCALE_BARK
@ FSCALE_BARK
Definition: avf_showcwt.c:40
scale
static void scale(int *out, const int *in, const int w, const int h, const int shift)
Definition: intra.c:291
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
avpriv_float_dsp_alloc
av_cold AVFloatDSPContext * avpriv_float_dsp_alloc(int bit_exact)
Allocate a float DSP context.
Definition: float_dsp.c:146
ShowCWTContext::new_frame
int new_frame
Definition: avf_showcwt.c:109
ShowCWTContext::input_padding_size
int input_padding_size
Definition: avf_showcwt.c:113
ShowCWTContext::ifft_in
AVFrame * ifft_in
Definition: avf_showcwt.c:98
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
h
h
Definition: vp9dsp_template.c:2070
ff_outlink_frame_wanted
the definition of that something depends on the semantic of the filter The callback must examine the status of the filter s links and proceed accordingly The status of output links is stored in the status_in and status_out fields and tested by the ff_outlink_frame_wanted() function. If this function returns true
FSCALE_MEL
@ FSCALE_MEL
Definition: avf_showcwt.c:41
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
Definition: opt.h:276
showcwt_outputs
static const AVFilterPad showcwt_outputs[]
Definition: avf_showcwt.c:1322
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:299
remap_log
static float remap_log(ShowCWTContext *s, float value, int iscale, float log_factor)
Definition: avf_showcwt.c:311
FILTER_QUERY_FUNC
#define FILTER_QUERY_FUNC(func)
Definition: filters.h:236
skip
static void BS_FUNC() skip(BSCTX *bc, unsigned int n)
Skip n bits in the buffer.
Definition: bitstream_template.h:375
src
#define src
Definition: vp8dsp.c:248
SlideMode
SlideMode
Definition: avf_ahistogram.c:31
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:237
tx.h
min
float min
Definition: vorbis_enc_data.h:429
SLIDE_FRAME
@ SLIDE_FRAME
Definition: avf_showcwt.c:70