FFmpeg
avf_showcqt.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014-2015 Muhammad Faiz <mfcc64@gmail.com>
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 "config.h"
22 #include "libavutil/tx.h"
24 #include "libavutil/opt.h"
26 #include "libavutil/eval.h"
27 #include "libavutil/pixdesc.h"
28 #include "libavutil/time.h"
29 #include "avfilter.h"
30 #include "internal.h"
31 #include "lavfutils.h"
32 #include "lswsutils.h"
33 
34 #if CONFIG_LIBFREETYPE
35 #include <ft2build.h>
36 #include FT_FREETYPE_H
37 #endif
38 
39 #if CONFIG_LIBFONTCONFIG
40 #include <fontconfig/fontconfig.h>
41 #endif
42 
43 #include "avf_showcqt.h"
44 
45 #define BASEFREQ 20.01523126408007475
46 #define ENDFREQ 20495.59681441799654
47 #define TLENGTH "384*tc/(384+tc*f)"
48 #define TLENGTH_MIN 0.001
49 #define VOLUME_MAX 100.0
50 #define FONTCOLOR "st(0, (midi(f)-59.5)/12);" \
51  "st(1, if(between(ld(0),0,1), 0.5-0.5*cos(2*PI*ld(0)), 0));" \
52  "r(1-ld(1)) + b(ld(1))"
53 #define CSCHEME "1|0.5|0|0|0.5|1"
54 #define PTS_STEP 10
55 #define PTS_TOLERANCE 1
56 
57 #define OFFSET(x) offsetof(ShowCQTContext, x)
58 #define FLAGS (AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM)
59 
60 static const AVOption showcqt_options[] = {
61  { "size", "set video size", OFFSET(width), AV_OPT_TYPE_IMAGE_SIZE, { .str = "1920x1080" }, 0, 0, FLAGS },
62  { "s", "set video size", OFFSET(width), AV_OPT_TYPE_IMAGE_SIZE, { .str = "1920x1080" }, 0, 0, FLAGS },
63  { "fps", "set video rate", OFFSET(rate), AV_OPT_TYPE_VIDEO_RATE, { .str = "25" }, 1, 1000, FLAGS },
64  { "rate", "set video rate", OFFSET(rate), AV_OPT_TYPE_VIDEO_RATE, { .str = "25" }, 1, 1000, FLAGS },
65  { "r", "set video rate", OFFSET(rate), AV_OPT_TYPE_VIDEO_RATE, { .str = "25" }, 1, 1000, FLAGS },
66  { "bar_h", "set bargraph height", OFFSET(bar_h), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, FLAGS },
67  { "axis_h", "set axis height", OFFSET(axis_h), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, FLAGS },
68  { "sono_h", "set sonogram height", OFFSET(sono_h), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, FLAGS },
69  { "fullhd", "set fullhd size", OFFSET(fullhd), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, FLAGS },
70  { "sono_v", "set sonogram volume", OFFSET(sono_v), AV_OPT_TYPE_STRING, { .str = "16" }, 0, 0, FLAGS },
71  { "volume", "set sonogram volume", OFFSET(sono_v), AV_OPT_TYPE_STRING, { .str = "16" }, 0, 0, FLAGS },
72  { "bar_v", "set bargraph volume", OFFSET(bar_v), AV_OPT_TYPE_STRING, { .str = "sono_v" }, 0, 0, FLAGS },
73  { "volume2", "set bargraph volume", OFFSET(bar_v), AV_OPT_TYPE_STRING, { .str = "sono_v" }, 0, 0, FLAGS },
74  { "sono_g", "set sonogram gamma", OFFSET(sono_g), AV_OPT_TYPE_FLOAT, { .dbl = 3.0 }, 1.0, 7.0, FLAGS },
75  { "gamma", "set sonogram gamma", OFFSET(sono_g), AV_OPT_TYPE_FLOAT, { .dbl = 3.0 }, 1.0, 7.0, FLAGS },
76  { "bar_g", "set bargraph gamma", OFFSET(bar_g), AV_OPT_TYPE_FLOAT, { .dbl = 1.0 }, 1.0, 7.0, FLAGS },
77  { "gamma2", "set bargraph gamma", OFFSET(bar_g), AV_OPT_TYPE_FLOAT, { .dbl = 1.0 }, 1.0, 7.0, FLAGS },
78  { "bar_t", "set bar transparency", OFFSET(bar_t), AV_OPT_TYPE_FLOAT, { .dbl = 1.0 }, 0.0, 1.0, FLAGS },
79  { "timeclamp", "set timeclamp", OFFSET(timeclamp), AV_OPT_TYPE_DOUBLE, { .dbl = 0.17 }, 0.002, 1.0, FLAGS },
80  { "tc", "set timeclamp", OFFSET(timeclamp), AV_OPT_TYPE_DOUBLE, { .dbl = 0.17 }, 0.002, 1.0, FLAGS },
81  { "attack", "set attack time", OFFSET(attack), AV_OPT_TYPE_DOUBLE, { .dbl = 0 }, 0.0, 1.0, FLAGS },
82  { "basefreq", "set base frequency", OFFSET(basefreq), AV_OPT_TYPE_DOUBLE, { .dbl = BASEFREQ }, 10.0, 100000.0, FLAGS },
83  { "endfreq", "set end frequency", OFFSET(endfreq), AV_OPT_TYPE_DOUBLE, { .dbl = ENDFREQ }, 10.0, 100000.0, FLAGS },
84  { "coeffclamp", "set coeffclamp", OFFSET(coeffclamp), AV_OPT_TYPE_FLOAT, { .dbl = 1.0 }, 0.1, 10.0, FLAGS },
85  { "tlength", "set tlength", OFFSET(tlength), AV_OPT_TYPE_STRING, { .str = TLENGTH }, 0, 0, FLAGS },
86  { "count", "set transform count", OFFSET(count), AV_OPT_TYPE_INT, { .i64 = 6 }, 1, 30, FLAGS },
87  { "fcount", "set frequency count", OFFSET(fcount), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 10, FLAGS },
88  { "fontfile", "set axis font file", OFFSET(fontfile), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, FLAGS },
89  { "font", "set axis font", OFFSET(font), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, FLAGS },
90  { "fontcolor", "set font color", OFFSET(fontcolor), AV_OPT_TYPE_STRING, { .str = FONTCOLOR }, 0, 0, FLAGS },
91  { "axisfile", "set axis image", OFFSET(axisfile), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, FLAGS },
92  { "axis", "draw axis", OFFSET(axis), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, FLAGS },
93  { "text", "draw axis", OFFSET(axis), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, FLAGS },
94  { "csp", "set color space", OFFSET(csp), AV_OPT_TYPE_INT, { .i64 = AVCOL_SPC_UNSPECIFIED }, 0, INT_MAX, FLAGS, "csp" },
95  { "unspecified", "unspecified", 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_SPC_UNSPECIFIED }, 0, 0, FLAGS, "csp" },
96  { "bt709", "bt709", 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_SPC_BT709 }, 0, 0, FLAGS, "csp" },
97  { "fcc", "fcc", 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_SPC_FCC }, 0, 0, FLAGS, "csp" },
98  { "bt470bg", "bt470bg", 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_SPC_BT470BG }, 0, 0, FLAGS, "csp" },
99  { "smpte170m", "smpte170m", 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_SPC_SMPTE170M }, 0, 0, FLAGS, "csp" },
100  { "smpte240m", "smpte240m", 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_SPC_SMPTE240M }, 0, 0, FLAGS, "csp" },
101  { "bt2020ncl", "bt2020ncl", 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_SPC_BT2020_NCL }, 0, 0, FLAGS, "csp" },
102  { "cscheme", "set color scheme", OFFSET(cscheme), AV_OPT_TYPE_STRING, { .str = CSCHEME }, 0, 0, FLAGS },
103  { NULL }
104 };
105 
106 AVFILTER_DEFINE_CLASS(showcqt);
107 
109 {
110  int k;
111  int level = AV_LOG_DEBUG;
112  int64_t plot_time;
113 
114  if (s->fft_time)
115  av_log(s->ctx, level, "fft_time = %16.3f s.\n", s->fft_time * 1e-6);
116  if (s->cqt_time)
117  av_log(s->ctx, level, "cqt_time = %16.3f s.\n", s->cqt_time * 1e-6);
118  if (s->process_cqt_time)
119  av_log(s->ctx, level, "process_cqt_time = %16.3f s.\n", s->process_cqt_time * 1e-6);
120  if (s->update_sono_time)
121  av_log(s->ctx, level, "update_sono_time = %16.3f s.\n", s->update_sono_time * 1e-6);
122  if (s->alloc_time)
123  av_log(s->ctx, level, "alloc_time = %16.3f s.\n", s->alloc_time * 1e-6);
124  if (s->bar_time)
125  av_log(s->ctx, level, "bar_time = %16.3f s.\n", s->bar_time * 1e-6);
126  if (s->axis_time)
127  av_log(s->ctx, level, "axis_time = %16.3f s.\n", s->axis_time * 1e-6);
128  if (s->sono_time)
129  av_log(s->ctx, level, "sono_time = %16.3f s.\n", s->sono_time * 1e-6);
130 
131  plot_time = s->fft_time + s->cqt_time + s->process_cqt_time + s->update_sono_time
132  + s->alloc_time + s->bar_time + s->axis_time + s->sono_time;
133  if (plot_time)
134  av_log(s->ctx, level, "plot_time = %16.3f s.\n", plot_time * 1e-6);
135 
136  s->fft_time = s->cqt_time = s->process_cqt_time = s->update_sono_time
137  = s->alloc_time = s->bar_time = s->axis_time = s->sono_time = 0;
138  /* axis_frame may be non reference counted frame */
139  if (s->axis_frame && !s->axis_frame->buf[0]) {
140  av_freep(s->axis_frame->data);
141  for (k = 0; k < 4; k++)
142  s->axis_frame->data[k] = NULL;
143  }
144 
145  av_frame_free(&s->axis_frame);
146  av_frame_free(&s->sono_frame);
147  av_tx_uninit(&s->fft_ctx);
148  if (s->coeffs)
149  for (k = 0; k < s->cqt_len; k++)
150  av_freep(&s->coeffs[k].val);
151  av_freep(&s->coeffs);
152  av_freep(&s->fft_data);
153  av_freep(&s->fft_input);
154  av_freep(&s->fft_result);
155  av_freep(&s->cqt_result);
156  av_freep(&s->attack_data);
157  av_freep(&s->c_buf);
158  av_freep(&s->h_buf);
159  av_freep(&s->rcp_h_buf);
160  av_freep(&s->freq);
161  av_freep(&s->sono_v_buf);
162  av_freep(&s->bar_v_buf);
163 }
164 
165 static double *create_freq_table(double base, double end, int n)
166 {
167  double log_base, log_end;
168  double rcp_n = 1.0 / n;
169  double *freq;
170  int x;
171 
172  freq = av_malloc_array(n, sizeof(*freq));
173  if (!freq)
174  return NULL;
175 
176  log_base = log(base);
177  log_end = log(end);
178  for (x = 0; x < n; x++) {
179  double log_freq = log_base + (x + 0.5) * (log_end - log_base) * rcp_n;
180  freq[x] = exp(log_freq);
181  }
182  return freq;
183 }
184 
185 static double clip_with_log(void *log_ctx, const char *name,
186  double val, double min, double max,
187  double nan_replace, int idx)
188 {
189  int level = AV_LOG_WARNING;
190  if (isnan(val)) {
191  av_log(log_ctx, level, "[%d] %s is nan, setting it to %g.\n",
192  idx, name, nan_replace);
193  val = nan_replace;
194  } else if (val < min) {
195  av_log(log_ctx, level, "[%d] %s is too low (%g), setting it to %g.\n",
196  idx, name, val, min);
197  val = min;
198  } else if (val > max) {
199  av_log(log_ctx, level, "[%d] %s it too high (%g), setting it to %g.\n",
200  idx, name, val, max);
201  val = max;
202  }
203  return val;
204 }
205 
206 static double a_weighting(void *p, double f)
207 {
208  double ret = 12200.0*12200.0 * (f*f*f*f);
209  ret /= (f*f + 20.6*20.6) * (f*f + 12200.0*12200.0) *
210  sqrt((f*f + 107.7*107.7) * (f*f + 737.9*737.9));
211  return ret;
212 }
213 
214 static double b_weighting(void *p, double f)
215 {
216  double ret = 12200.0*12200.0 * (f*f*f);
217  ret /= (f*f + 20.6*20.6) * (f*f + 12200.0*12200.0) * sqrt(f*f + 158.5*158.5);
218  return ret;
219 }
220 
221 static double c_weighting(void *p, double f)
222 {
223  double ret = 12200.0*12200.0 * (f*f);
224  ret /= (f*f + 20.6*20.6) * (f*f + 12200.0*12200.0);
225  return ret;
226 }
227 
229 {
230  const char *func_names[] = { "a_weighting", "b_weighting", "c_weighting", NULL };
231  const char *sono_names[] = { "timeclamp", "tc", "frequency", "freq", "f", "bar_v", NULL };
232  const char *bar_names[] = { "timeclamp", "tc", "frequency", "freq", "f", "sono_v", NULL };
233  double (*funcs[])(void *, double) = { a_weighting, b_weighting, c_weighting };
234  AVExpr *sono = NULL, *bar = NULL;
235  int x, ret = AVERROR(ENOMEM);
236 
237  s->sono_v_buf = av_malloc_array(s->cqt_len, sizeof(*s->sono_v_buf));
238  s->bar_v_buf = av_malloc_array(s->cqt_len, sizeof(*s->bar_v_buf));
239  if (!s->sono_v_buf || !s->bar_v_buf)
240  goto error;
241 
242  if ((ret = av_expr_parse(&sono, s->sono_v, sono_names, func_names, funcs, NULL, NULL, 0, s->ctx)) < 0)
243  goto error;
244 
245  if ((ret = av_expr_parse(&bar, s->bar_v, bar_names, func_names, funcs, NULL, NULL, 0, s->ctx)) < 0)
246  goto error;
247 
248  for (x = 0; x < s->cqt_len; x++) {
249  double vars[] = { s->timeclamp, s->timeclamp, s->freq[x], s->freq[x], s->freq[x], 0.0 };
250  double vol = clip_with_log(s->ctx, "sono_v", av_expr_eval(sono, vars, NULL), 0.0, VOLUME_MAX, 0.0, x);
251  vars[5] = vol;
252  vol = clip_with_log(s->ctx, "bar_v", av_expr_eval(bar, vars, NULL), 0.0, VOLUME_MAX, 0.0, x);
253  s->bar_v_buf[x] = vol * vol;
254  vars[5] = vol;
255  vol = clip_with_log(s->ctx, "sono_v", av_expr_eval(sono, vars, NULL), 0.0, VOLUME_MAX, 0.0, x);
256  s->sono_v_buf[x] = vol * vol;
257  }
258  av_expr_free(sono);
259  av_expr_free(bar);
260  return 0;
261 
262 error:
263  av_freep(&s->sono_v_buf);
264  av_freep(&s->bar_v_buf);
265  av_expr_free(sono);
266  av_expr_free(bar);
267  return ret;
268 }
269 
270 static void cqt_calc(AVComplexFloat *dst, const AVComplexFloat *src, const Coeffs *coeffs,
271  int len, int fft_len)
272 {
273  int k, x, i, j;
274  for (k = 0; k < len; k++) {
275  AVComplexFloat l, r, a = {0,0}, b = {0,0};
276 
277  for (x = 0; x < coeffs[k].len; x++) {
278  float u = coeffs[k].val[x];
279  i = coeffs[k].start + x;
280  j = fft_len - i;
281  a.re += u * src[i].re;
282  a.im += u * src[i].im;
283  b.re += u * src[j].re;
284  b.im += u * src[j].im;
285  }
286 
287  /* separate left and right, (and multiply by 2.0) */
288  l.re = a.re + b.re;
289  l.im = a.im - b.im;
290  r.re = b.im + a.im;
291  r.im = b.re - a.re;
292  dst[k].re = l.re * l.re + l.im * l.im;
293  dst[k].im = r.re * r.re + r.im * r.im;
294  }
295 }
296 
298 {
299  const char *var_names[] = { "timeclamp", "tc", "frequency", "freq", "f", NULL };
300  AVExpr *expr = NULL;
301  int rate = s->ctx->inputs[0]->sample_rate;
302  int nb_cqt_coeffs = 0;
303  int k, x, ret;
304 
305  if ((ret = av_expr_parse(&expr, s->tlength, var_names, NULL, NULL, NULL, NULL, 0, s->ctx)) < 0)
306  goto error;
307 
308  ret = AVERROR(ENOMEM);
309  if (!(s->coeffs = av_calloc(s->cqt_len, sizeof(*s->coeffs))))
310  goto error;
311 
312  for (k = 0; k < s->cqt_len; k++) {
313  double vars[] = { s->timeclamp, s->timeclamp, s->freq[k], s->freq[k], s->freq[k] };
314  double flen, center, tlength;
315  int start, end, m = k;
316 
317  if (s->freq[k] > 0.5 * rate)
318  continue;
319  tlength = clip_with_log(s->ctx, "tlength", av_expr_eval(expr, vars, NULL),
320  TLENGTH_MIN, s->timeclamp, s->timeclamp, k);
321 
322  flen = 8.0 * s->fft_len / (tlength * rate);
323  center = s->freq[k] * s->fft_len / rate;
324  start = FFMAX(0, ceil(center - 0.5 * flen));
325  end = FFMIN(s->fft_len, floor(center + 0.5 * flen));
326 
327  s->coeffs[m].start = start & ~(s->cqt_align - 1);
328  s->coeffs[m].len = (end | (s->cqt_align - 1)) + 1 - s->coeffs[m].start;
329  nb_cqt_coeffs += s->coeffs[m].len;
330  if (!(s->coeffs[m].val = av_calloc(s->coeffs[m].len, sizeof(*s->coeffs[m].val))))
331  goto error;
332 
333  for (x = start; x <= end; x++) {
334  int sign = (x & 1) ? (-1) : 1;
335  double y = 2.0 * M_PI * (x - center) * (1.0 / flen);
336  /* nuttall window */
337  double w = 0.355768 + 0.487396 * cos(y) + 0.144232 * cos(2*y) + 0.012604 * cos(3*y);
338  w *= sign * (1.0 / s->fft_len);
339  s->coeffs[m].val[x - s->coeffs[m].start] = w;
340  }
341 
342  if (s->permute_coeffs)
343  s->permute_coeffs(s->coeffs[m].val, s->coeffs[m].len);
344  }
345 
346  av_expr_free(expr);
347  av_log(s->ctx, AV_LOG_INFO, "nb_cqt_coeffs = %d.\n", nb_cqt_coeffs);
348  return 0;
349 
350 error:
351  av_expr_free(expr);
352  if (s->coeffs)
353  for (k = 0; k < s->cqt_len; k++)
354  av_freep(&s->coeffs[k].val);
355  av_freep(&s->coeffs);
356  return ret;
357 }
358 
360 {
361  AVFrame *out;
362  out = av_frame_alloc();
363  if (!out)
364  return NULL;
365  out->format = format;
366  out->width = w;
367  out->height = h;
368  if (av_frame_get_buffer(out, 0) < 0) {
369  av_frame_free(&out);
370  return NULL;
371  }
373  memset(out->data[0], 0, out->linesize[0] * h);
374  } else {
375  int hh = (format == AV_PIX_FMT_YUV420P || format == AV_PIX_FMT_YUVA420P) ? h / 2 : h;
376  memset(out->data[0], 16, out->linesize[0] * h);
377  memset(out->data[1], 128, out->linesize[1] * hh);
378  memset(out->data[2], 128, out->linesize[2] * hh);
379  if (out->data[3])
380  memset(out->data[3], 0, out->linesize[3] * h);
381  }
382  return out;
383 }
384 
386 {
387  switch (format) {
388  case AV_PIX_FMT_RGB24: format = AV_PIX_FMT_RGBA; break;
389  case AV_PIX_FMT_YUV444P:
390  case AV_PIX_FMT_YUV422P:
392  }
393  return format;
394 }
395 
397 {
398  if (!(s->axis_frame = alloc_frame_empty(convert_axis_pixel_format(s->format), s->width, s->axis_h)))
399  return AVERROR(ENOMEM);
400  return 0;
401 }
402 
404 {
405  uint8_t *tmp_data[4] = { NULL };
406  int tmp_linesize[4];
407  enum AVPixelFormat tmp_format;
408  int tmp_w, tmp_h, ret;
409 
410  if ((ret = ff_load_image(tmp_data, tmp_linesize, &tmp_w, &tmp_h, &tmp_format,
411  s->axisfile, s->ctx)) < 0)
412  goto error;
413 
414  ret = AVERROR(ENOMEM);
415  if (!(s->axis_frame = av_frame_alloc()))
416  goto error;
417 
418  if ((ret = ff_scale_image(s->axis_frame->data, s->axis_frame->linesize, s->width, s->axis_h,
419  convert_axis_pixel_format(s->format), tmp_data, tmp_linesize, tmp_w, tmp_h,
420  tmp_format, s->ctx)) < 0)
421  goto error;
422 
423  s->axis_frame->width = s->width;
424  s->axis_frame->height = s->axis_h;
425  s->axis_frame->format = convert_axis_pixel_format(s->format);
426  av_freep(tmp_data);
427  return 0;
428 
429 error:
430  av_frame_free(&s->axis_frame);
431  av_freep(tmp_data);
432  return ret;
433 }
434 
435 static double midi(void *p, double f)
436 {
437  return log2(f/440.0) * 12.0 + 69.0;
438 }
439 
440 static double r_func(void *p, double x)
441 {
442  x = av_clipd(x, 0.0, 1.0);
443  return lrint(x*255.0) << 16;
444 }
445 
446 static double g_func(void *p, double x)
447 {
448  x = av_clipd(x, 0.0, 1.0);
449  return lrint(x*255.0) << 8;
450 }
451 
452 static double b_func(void *p, double x)
453 {
454  x = av_clipd(x, 0.0, 1.0);
455  return lrint(x*255.0);
456 }
457 
459 {
460  const char *var_names[] = { "timeclamp", "tc", "frequency", "freq", "f", NULL };
461  const char *func_names[] = { "midi", "r", "g", "b", NULL };
462  double (*funcs[])(void *, double) = { midi, r_func, g_func, b_func };
463  AVExpr *expr = NULL;
464  double *freq = NULL;
465  int x, xs, y, ret;
466  int width = half ? 1920/2 : 1920, height = half ? 16 : 32;
467  int step = half ? 2 : 1;
468 
469  if (s->basefreq != (double) BASEFREQ || s->endfreq != (double) ENDFREQ) {
470  av_log(s->ctx, AV_LOG_WARNING, "font axis rendering is not implemented in non-default frequency range,"
471  " please use axisfile option instead.\n");
472  return AVERROR(EINVAL);
473  }
474 
475  if (s->cqt_len == 1920)
476  freq = s->freq;
477  else if (!(freq = create_freq_table(s->basefreq, s->endfreq, 1920)))
478  return AVERROR(ENOMEM);
479 
480  if ((ret = av_expr_parse(&expr, s->fontcolor, var_names, func_names, funcs, NULL, NULL, 0, s->ctx)) < 0) {
481  if (freq != s->freq)
482  av_freep(&freq);
483  return ret;
484  }
485 
486  for (x = 0, xs = 0; x < width; x++, xs += step) {
487  double vars[] = { s->timeclamp, s->timeclamp, freq[xs], freq[xs], freq[xs] };
488  int color = (int) av_expr_eval(expr, vars, NULL);
489  uint8_t r = (color >> 16) & 0xFF, g = (color >> 8) & 0xFF, b = color & 0xFF;
490  uint8_t *data = tmp->data[0];
491  int linesize = tmp->linesize[0];
492  for (y = 0; y < height; y++) {
493  data[linesize * y + 4 * x] = r;
494  data[linesize * y + 4 * x + 1] = g;
495  data[linesize * y + 4 * x + 2] = b;
496  }
497  }
498 
499  av_expr_free(expr);
500  if (freq != s->freq)
501  av_freep(&freq);
502  return 0;
503 }
504 
505 static int render_freetype(ShowCQTContext *s, AVFrame *tmp, char *fontfile)
506 {
507 #if CONFIG_LIBFREETYPE
508  const char *str = "EF G A BC D ";
509  uint8_t *data = tmp->data[0];
510  int linesize = tmp->linesize[0];
511  FT_Library lib = NULL;
512  FT_Face face = NULL;
513  int font_width = 16, font_height = 32;
514  int font_repeat = font_width * 12;
515  int linear_hori_advance = font_width * 65536;
516  int non_monospace_warning = 0;
517  int x;
518 
519  if (!fontfile)
520  return AVERROR(EINVAL);
521 
522  if (FT_Init_FreeType(&lib))
523  goto fail;
524 
525  if (FT_New_Face(lib, fontfile, 0, &face))
526  goto fail;
527 
528  if (FT_Set_Char_Size(face, 16*64, 0, 0, 0))
529  goto fail;
530 
531  if (FT_Load_Char(face, 'A', FT_LOAD_RENDER))
532  goto fail;
533 
534  if (FT_Set_Char_Size(face, 16*64 * linear_hori_advance / face->glyph->linearHoriAdvance, 0, 0, 0))
535  goto fail;
536 
537  for (x = 0; x < 12; x++) {
538  int sx, sy, rx, bx, by, dx, dy;
539 
540  if (str[x] == ' ')
541  continue;
542 
543  if (FT_Load_Char(face, str[x], FT_LOAD_RENDER))
544  goto fail;
545 
546  if (face->glyph->advance.x != font_width*64 && !non_monospace_warning) {
547  av_log(s->ctx, AV_LOG_WARNING, "font is not monospace.\n");
548  non_monospace_warning = 1;
549  }
550 
551  sy = font_height - 8 - face->glyph->bitmap_top;
552  for (rx = 0; rx < 10; rx++) {
553  sx = rx * font_repeat + x * font_width + face->glyph->bitmap_left;
554  for (by = 0; by < face->glyph->bitmap.rows; by++) {
555  dy = by + sy;
556  if (dy < 0)
557  continue;
558  if (dy >= font_height)
559  break;
560 
561  for (bx = 0; bx < face->glyph->bitmap.width; bx++) {
562  dx = bx + sx;
563  if (dx < 0)
564  continue;
565  if (dx >= 1920)
566  break;
567  data[dy*linesize+4*dx+3] = face->glyph->bitmap.buffer[by*face->glyph->bitmap.width+bx];
568  }
569  }
570  }
571  }
572 
573  FT_Done_Face(face);
574  FT_Done_FreeType(lib);
575  return 0;
576 
577 fail:
578  av_log(s->ctx, AV_LOG_WARNING, "error while loading freetype font.\n");
579  FT_Done_Face(face);
580  FT_Done_FreeType(lib);
581  return AVERROR(EINVAL);
582 #else
583  if (fontfile)
584  av_log(s->ctx, AV_LOG_WARNING, "freetype is not available, ignoring fontfile option.\n");
585  return AVERROR(EINVAL);
586 #endif
587 }
588 
589 static int render_fontconfig(ShowCQTContext *s, AVFrame *tmp, char* font)
590 {
591 #if CONFIG_LIBFONTCONFIG
592  FcConfig *fontconfig;
593  FcPattern *pat, *best;
594  FcResult result = FcResultMatch;
595  char *filename;
596  int i, ret;
597 
598  if (!font)
599  return AVERROR(EINVAL);
600 
601  for (i = 0; font[i]; i++) {
602  if (font[i] == '|')
603  font[i] = ':';
604  }
605 
606  if (!(fontconfig = FcInitLoadConfigAndFonts())) {
607  av_log(s->ctx, AV_LOG_ERROR, "impossible to init fontconfig.\n");
608  return AVERROR_UNKNOWN;
609  }
610 
611  if (!(pat = FcNameParse((uint8_t *)font))) {
612  av_log(s->ctx, AV_LOG_ERROR, "could not parse fontconfig pat.\n");
613  FcConfigDestroy(fontconfig);
614  return AVERROR(EINVAL);
615  }
616 
617  FcDefaultSubstitute(pat);
618 
619  if (!FcConfigSubstitute(fontconfig, pat, FcMatchPattern)) {
620  av_log(s->ctx, AV_LOG_ERROR, "could not substitue fontconfig options.\n");
621  FcPatternDestroy(pat);
622  FcConfigDestroy(fontconfig);
623  return AVERROR(ENOMEM);
624  }
625 
626  best = FcFontMatch(fontconfig, pat, &result);
627  FcPatternDestroy(pat);
628 
629  ret = AVERROR(EINVAL);
630  if (!best || result != FcResultMatch) {
631  av_log(s->ctx, AV_LOG_ERROR, "cannot find a valid font for %s.\n", font);
632  goto fail;
633  }
634 
635  if (FcPatternGetString(best, FC_FILE, 0, (FcChar8 **)&filename) != FcResultMatch) {
636  av_log(s->ctx, AV_LOG_ERROR, "no file path for %s\n", font);
637  goto fail;
638  }
639 
640  ret = render_freetype(s, tmp, filename);
641 
642 fail:
643  FcPatternDestroy(best);
644  FcConfigDestroy(fontconfig);
645  return ret;
646 #else
647  if (font)
648  av_log(s->ctx, AV_LOG_WARNING, "fontconfig is not available, ignoring font option.\n");
649  return AVERROR(EINVAL);
650 #endif
651 }
652 
654 {
655  const char *str = "EF G A BC D ";
656  int x, u, v, mask;
657  uint8_t *data = tmp->data[0];
658  int linesize = tmp->linesize[0];
659  int width = 1920/2, height = 16;
660 
661  for (x = 0; x < width; x += width/10) {
662  uint8_t *startptr = data + 4 * x;
663  for (u = 0; u < 12; u++) {
664  for (v = 0; v < height; v++) {
665  uint8_t *p = startptr + v * linesize + height/2 * 4 * u;
666  for (mask = 0x80; mask; mask >>= 1, p += 4) {
667  if (mask & avpriv_vga16_font[str[u] * 16 + v])
668  p[3] = 255;
669  else
670  p[3] = 0;
671  }
672  }
673  }
674  }
675 
676  return 0;
677 }
678 
680 {
681  AVFrame *tmp = NULL;
682  int ret = AVERROR(ENOMEM);
683  int width = 1920, height = 32;
684  int default_font = 0;
685 
687  goto fail;
688 
689  if (!(s->axis_frame = av_frame_alloc()))
690  goto fail;
691 
692  if (render_freetype(s, tmp, s->fontfile) < 0 &&
693  render_fontconfig(s, tmp, s->font) < 0 &&
694  (default_font = 1, ret = render_default_font(tmp)) < 0)
695  goto fail;
696 
697  if (default_font)
698  width /= 2, height /= 2;
699 
700  if ((ret = init_axis_color(s, tmp, default_font)) < 0)
701  goto fail;
702 
703  if ((ret = ff_scale_image(s->axis_frame->data, s->axis_frame->linesize, s->width, s->axis_h,
704  convert_axis_pixel_format(s->format), tmp->data, tmp->linesize,
705  width, height, AV_PIX_FMT_RGBA, s->ctx)) < 0)
706  goto fail;
707 
708  av_frame_free(&tmp);
709  s->axis_frame->width = s->width;
710  s->axis_frame->height = s->axis_h;
711  s->axis_frame->format = convert_axis_pixel_format(s->format);
712  return 0;
713 
714 fail:
715  av_frame_free(&tmp);
716  av_frame_free(&s->axis_frame);
717  return ret;
718 }
719 
720 static float calculate_gamma(float v, float g)
721 {
722  if (g == 1.0f)
723  return v;
724  if (g == 2.0f)
725  return sqrtf(v);
726  if (g == 3.0f)
727  return cbrtf(v);
728  if (g == 4.0f)
729  return sqrtf(sqrtf(v));
730  return expf(logf(v) / g);
731 }
732 
733 static void rgb_from_cqt(ColorFloat *c, const AVComplexFloat *v, float g, int len, float cscheme[6])
734 {
735  int x;
736  for (x = 0; x < len; x++) {
737  c[x].rgb.r = 255.0f * calculate_gamma(FFMIN(1.0f, cscheme[0] * v[x].re + cscheme[3] * v[x].im), g);
738  c[x].rgb.g = 255.0f * calculate_gamma(FFMIN(1.0f, cscheme[1] * v[x].re + cscheme[4] * v[x].im), g);
739  c[x].rgb.b = 255.0f * calculate_gamma(FFMIN(1.0f, cscheme[2] * v[x].re + cscheme[5] * v[x].im), g);
740  }
741 }
742 
743 static void yuv_from_cqt(ColorFloat *c, const AVComplexFloat *v, float gamma, int len, float cm[3][3], float cscheme[6])
744 {
745  int x;
746  for (x = 0; x < len; x++) {
747  float r, g, b;
748  r = calculate_gamma(FFMIN(1.0f, cscheme[0] * v[x].re + cscheme[3] * v[x].im), gamma);
749  g = calculate_gamma(FFMIN(1.0f, cscheme[1] * v[x].re + cscheme[4] * v[x].im), gamma);
750  b = calculate_gamma(FFMIN(1.0f, cscheme[2] * v[x].re + cscheme[5] * v[x].im), gamma);
751  c[x].yuv.y = cm[0][0] * r + cm[0][1] * g + cm[0][2] * b;
752  c[x].yuv.u = cm[1][0] * r + cm[1][1] * g + cm[1][2] * b;
753  c[x].yuv.v = cm[2][0] * r + cm[2][1] * g + cm[2][2] * b;
754  }
755 }
756 
757 static void draw_bar_rgb(AVFrame *out, const float *h, const float *rcp_h,
758  const ColorFloat *c, int bar_h, float bar_t)
759 {
760  int x, y, w = out->width;
761  float mul, ht, rcp_bar_h = 1.0f / bar_h, rcp_bar_t = 1.0f / bar_t;
762  uint8_t *v = out->data[0], *lp;
763  int ls = out->linesize[0];
764 
765  for (y = 0; y < bar_h; y++) {
766  ht = (bar_h - y) * rcp_bar_h;
767  lp = v + y * ls;
768  for (x = 0; x < w; x++) {
769  if (h[x] <= ht) {
770  *lp++ = 0;
771  *lp++ = 0;
772  *lp++ = 0;
773  } else {
774  mul = (h[x] - ht) * rcp_h[x];
775  mul = (mul < bar_t) ? (mul * rcp_bar_t) : 1.0f;
776  *lp++ = lrintf(mul * c[x].rgb.r);
777  *lp++ = lrintf(mul * c[x].rgb.g);
778  *lp++ = lrintf(mul * c[x].rgb.b);
779  }
780  }
781  }
782 }
783 
784 #define DRAW_BAR_WITH_CHROMA(x) \
785 do { \
786  if (h[x] <= ht) { \
787  *lpy++ = 16; \
788  *lpu++ = 128; \
789  *lpv++ = 128; \
790  } else { \
791  mul = (h[x] - ht) * rcp_h[x]; \
792  mul = (mul < bar_t) ? (mul * rcp_bar_t) : 1.0f; \
793  *lpy++ = lrintf(mul * c[x].yuv.y + 16.0f); \
794  *lpu++ = lrintf(mul * c[x].yuv.u + 128.0f); \
795  *lpv++ = lrintf(mul * c[x].yuv.v + 128.0f); \
796  } \
797 } while (0)
798 
799 #define DRAW_BAR_WITHOUT_CHROMA(x) \
800 do { \
801  if (h[x] <= ht) { \
802  *lpy++ = 16; \
803  } else { \
804  mul = (h[x] - ht) * rcp_h[x]; \
805  mul = (mul < bar_t) ? (mul * rcp_bar_t) : 1.0f; \
806  *lpy++ = lrintf(mul * c[x].yuv.y + 16.0f); \
807  } \
808 } while (0)
809 
810 static void draw_bar_yuv(AVFrame *out, const float *h, const float *rcp_h,
811  const ColorFloat *c, int bar_h, float bar_t)
812 {
813  int x, y, yh, w = out->width;
814  float mul, ht, rcp_bar_h = 1.0f / bar_h, rcp_bar_t = 1.0f / bar_t;
815  uint8_t *vy = out->data[0], *vu = out->data[1], *vv = out->data[2];
816  uint8_t *lpy, *lpu, *lpv;
817  int lsy = out->linesize[0], lsu = out->linesize[1], lsv = out->linesize[2];
818  int fmt = out->format;
819 
820  for (y = 0; y < bar_h; y += 2) {
821  yh = (fmt == AV_PIX_FMT_YUV420P) ? y / 2 : y;
822  ht = (bar_h - y) * rcp_bar_h;
823  lpy = vy + y * lsy;
824  lpu = vu + yh * lsu;
825  lpv = vv + yh * lsv;
826  if (fmt == AV_PIX_FMT_YUV444P) {
827  for (x = 0; x < w; x += 2) {
830  }
831  } else {
832  for (x = 0; x < w; x += 2) {
835  }
836  }
837 
838  ht = (bar_h - (y+1)) * rcp_bar_h;
839  lpy = vy + (y+1) * lsy;
840  lpu = vu + (y+1) * lsu;
841  lpv = vv + (y+1) * lsv;
842  if (fmt == AV_PIX_FMT_YUV444P) {
843  for (x = 0; x < w; x += 2) {
846  }
847  } else if (fmt == AV_PIX_FMT_YUV422P) {
848  for (x = 0; x < w; x += 2) {
851  }
852  } else {
853  for (x = 0; x < w; x += 2) {
856  }
857  }
858  }
859 }
860 
861 static void draw_axis_rgb(AVFrame *out, AVFrame *axis, const ColorFloat *c, int off)
862 {
863  int x, y, w = axis->width, h = axis->height;
864  float a, rcp_255 = 1.0f / 255.0f;
865  uint8_t *lp, *lpa;
866 
867  for (y = 0; y < h; y++) {
868  lp = out->data[0] + (off + y) * out->linesize[0];
869  lpa = axis->data[0] + y * axis->linesize[0];
870  for (x = 0; x < w; x++) {
871  if (!lpa[3]) {
872  *lp++ = lrintf(c[x].rgb.r);
873  *lp++ = lrintf(c[x].rgb.g);
874  *lp++ = lrintf(c[x].rgb.b);
875  } else if (lpa[3] == 255) {
876  *lp++ = lpa[0];
877  *lp++ = lpa[1];
878  *lp++ = lpa[2];
879  } else {
880  a = rcp_255 * lpa[3];
881  *lp++ = lrintf(a * lpa[0] + (1.0f - a) * c[x].rgb.r);
882  *lp++ = lrintf(a * lpa[1] + (1.0f - a) * c[x].rgb.g);
883  *lp++ = lrintf(a * lpa[2] + (1.0f - a) * c[x].rgb.b);
884  }
885  lpa += 4;
886  }
887  }
888 }
889 
890 #define BLEND_WITH_CHROMA(c) \
891 do { \
892  if (!*lpaa) { \
893  *lpy = lrintf(c.yuv.y + 16.0f); \
894  *lpu = lrintf(c.yuv.u + 128.0f); \
895  *lpv = lrintf(c.yuv.v + 128.0f); \
896  } else if (255 == *lpaa) { \
897  *lpy = *lpay; \
898  *lpu = *lpau; \
899  *lpv = *lpav; \
900  } else { \
901  float a = (1.0f/255.0f) * (*lpaa); \
902  *lpy = lrintf(a * (*lpay) + (1.0f - a) * (c.yuv.y + 16.0f)); \
903  *lpu = lrintf(a * (*lpau) + (1.0f - a) * (c.yuv.u + 128.0f)); \
904  *lpv = lrintf(a * (*lpav) + (1.0f - a) * (c.yuv.v + 128.0f)); \
905  } \
906  lpy++; lpu++; lpv++; \
907  lpay++; lpau++; lpav++; lpaa++; \
908 } while (0)
909 
910 #define BLEND_WITHOUT_CHROMA(c, alpha_inc) \
911 do { \
912  if (!*lpaa) { \
913  *lpy = lrintf(c.yuv.y + 16.0f); \
914  } else if (255 == *lpaa) { \
915  *lpy = *lpay; \
916  } else { \
917  float a = (1.0f/255.0f) * (*lpaa); \
918  *lpy = lrintf(a * (*lpay) + (1.0f - a) * (c.yuv.y + 16.0f)); \
919  } \
920  lpy++; \
921  lpay++; lpaa += alpha_inc; \
922 } while (0)
923 
924 #define BLEND_CHROMA2(c) \
925 do { \
926  if (!lpaa[0] && !lpaa[1]) { \
927  *lpu = lrintf(c.yuv.u + 128.0f); \
928  *lpv = lrintf(c.yuv.v + 128.0f); \
929  } else if (255 == lpaa[0] && 255 == lpaa[1]) { \
930  *lpu = *lpau; *lpv = *lpav; \
931  } else { \
932  float a0 = (0.5f/255.0f) * lpaa[0]; \
933  float a1 = (0.5f/255.0f) * lpaa[1]; \
934  float b = 1.0f - a0 - a1; \
935  *lpu = lrintf(a0 * lpau[0] + a1 * lpau[1] + b * (c.yuv.u + 128.0f)); \
936  *lpv = lrintf(a0 * lpav[0] + a1 * lpav[1] + b * (c.yuv.v + 128.0f)); \
937  } \
938  lpau += 2; lpav += 2; lpaa++; lpu++; lpv++; \
939 } while (0)
940 
941 #define BLEND_CHROMA2x2(c) \
942 do { \
943  if (!lpaa[0] && !lpaa[1] && !lpaa[lsaa] && !lpaa[lsaa+1]) { \
944  *lpu = lrintf(c.yuv.u + 128.0f); \
945  *lpv = lrintf(c.yuv.v + 128.0f); \
946  } else if (255 == lpaa[0] && 255 == lpaa[1] && \
947  255 == lpaa[lsaa] && 255 == lpaa[lsaa+1]) { \
948  *lpu = *lpau; *lpv = *lpav; \
949  } else { \
950  float a0 = (0.25f/255.0f) * lpaa[0]; \
951  float a1 = (0.25f/255.0f) * lpaa[1]; \
952  float a2 = (0.25f/255.0f) * lpaa[lsaa]; \
953  float a3 = (0.25f/255.0f) * lpaa[lsaa+1]; \
954  float b = 1.0f - a0 - a1 - a2 - a3; \
955  *lpu = lrintf(a0 * lpau[0] + a1 * lpau[1] + a2 * lpau[lsau] + a3 * lpau[lsau+1] \
956  + b * (c.yuv.u + 128.0f)); \
957  *lpv = lrintf(a0 * lpav[0] + a1 * lpav[1] + a2 * lpav[lsav] + a3 * lpav[lsav+1] \
958  + b * (c.yuv.v + 128.0f)); \
959  } \
960  lpau += 2; lpav += 2; lpaa++; lpu++; lpv++; \
961 } while (0)
962 
963 static void draw_axis_yuv(AVFrame *out, AVFrame *axis, const ColorFloat *c, int off)
964 {
965  int fmt = out->format, x, y, yh, w = axis->width, h = axis->height;
966  int offh = (fmt == AV_PIX_FMT_YUV420P) ? off / 2 : off;
967  uint8_t *vy = out->data[0], *vu = out->data[1], *vv = out->data[2];
968  uint8_t *vay = axis->data[0], *vau = axis->data[1], *vav = axis->data[2], *vaa = axis->data[3];
969  int lsy = out->linesize[0], lsu = out->linesize[1], lsv = out->linesize[2];
970  int lsay = axis->linesize[0], lsau = axis->linesize[1], lsav = axis->linesize[2], lsaa = axis->linesize[3];
971  uint8_t *lpy, *lpu, *lpv, *lpay, *lpau, *lpav, *lpaa;
972 
973  for (y = 0; y < h; y += 2) {
974  yh = (fmt == AV_PIX_FMT_YUV420P) ? y / 2 : y;
975  lpy = vy + (off + y) * lsy;
976  lpu = vu + (offh + yh) * lsu;
977  lpv = vv + (offh + yh) * lsv;
978  lpay = vay + y * lsay;
979  lpau = vau + y * lsau;
980  lpav = vav + y * lsav;
981  lpaa = vaa + y * lsaa;
982  if (fmt == AV_PIX_FMT_YUV444P) {
983  for (x = 0; x < w; x += 2) {
984  BLEND_WITH_CHROMA(c[x]);
985  BLEND_WITH_CHROMA(c[x+1]);
986  }
987  } else if (fmt == AV_PIX_FMT_YUV422P) {
988  for (x = 0; x < w; x += 2) {
989  BLEND_WITHOUT_CHROMA(c[x], 0);
990  BLEND_CHROMA2(c[x]);
991  BLEND_WITHOUT_CHROMA(c[x+1], 1);
992  }
993  } else {
994  for (x = 0; x < w; x += 2) {
995  BLEND_WITHOUT_CHROMA(c[x], 0);
996  BLEND_CHROMA2x2(c[x]);
997  BLEND_WITHOUT_CHROMA(c[x+1], 1);
998  }
999  }
1000 
1001  lpy = vy + (off + y + 1) * lsy;
1002  lpu = vu + (off + y + 1) * lsu;
1003  lpv = vv + (off + y + 1) * lsv;
1004  lpay = vay + (y + 1) * lsay;
1005  lpau = vau + (y + 1) * lsau;
1006  lpav = vav + (y + 1) * lsav;
1007  lpaa = vaa + (y + 1) * lsaa;
1008  if (fmt == AV_PIX_FMT_YUV444P) {
1009  for (x = 0; x < w; x += 2) {
1010  BLEND_WITH_CHROMA(c[x]);
1011  BLEND_WITH_CHROMA(c[x+1]);
1012  }
1013  } else if (fmt == AV_PIX_FMT_YUV422P) {
1014  for (x = 0; x < w; x += 2) {
1015  BLEND_WITHOUT_CHROMA(c[x], 0);
1016  BLEND_CHROMA2(c[x]);
1017  BLEND_WITHOUT_CHROMA(c[x+1], 1);
1018  }
1019  } else {
1020  for (x = 0; x < w; x += 2) {
1021  BLEND_WITHOUT_CHROMA(c[x], 1);
1022  BLEND_WITHOUT_CHROMA(c[x+1], 1);
1023  }
1024  }
1025  }
1026 }
1027 
1028 static void draw_sono(AVFrame *out, AVFrame *sono, int off, int idx)
1029 {
1030  int fmt = out->format, h = sono->height;
1031  int nb_planes = (fmt == AV_PIX_FMT_RGB24) ? 1 : 3;
1032  int offh = (fmt == AV_PIX_FMT_YUV420P) ? off / 2 : off;
1033  int inc = (fmt == AV_PIX_FMT_YUV420P) ? 2 : 1;
1034  ptrdiff_t ls;
1035  int i, y, yh;
1036 
1037  ls = FFABS(FFMIN(out->linesize[0], sono->linesize[0]));
1038  for (y = 0; y < h; y++) {
1039  memcpy(out->data[0] + (off + y) * out->linesize[0],
1040  sono->data[0] + (idx + y) % h * sono->linesize[0], ls);
1041  }
1042 
1043  for (i = 1; i < nb_planes; i++) {
1044  ls = FFABS(FFMIN(out->linesize[i], sono->linesize[i]));
1045  for (y = 0; y < h; y += inc) {
1046  yh = (fmt == AV_PIX_FMT_YUV420P) ? y / 2 : y;
1047  memcpy(out->data[i] + (offh + yh) * out->linesize[i],
1048  sono->data[i] + (idx + y) % h * sono->linesize[i], ls);
1049  }
1050  }
1051 }
1052 
1053 static void update_sono_rgb(AVFrame *sono, const ColorFloat *c, int idx)
1054 {
1055  int x, w = sono->width;
1056  uint8_t *lp = sono->data[0] + idx * sono->linesize[0];
1057 
1058  for (x = 0; x < w; x++) {
1059  *lp++ = lrintf(c[x].rgb.r);
1060  *lp++ = lrintf(c[x].rgb.g);
1061  *lp++ = lrintf(c[x].rgb.b);
1062  }
1063 }
1064 
1065 static void update_sono_yuv(AVFrame *sono, const ColorFloat *c, int idx)
1066 {
1067  int x, fmt = sono->format, w = sono->width;
1068  uint8_t *lpy = sono->data[0] + idx * sono->linesize[0];
1069  uint8_t *lpu = sono->data[1] + idx * sono->linesize[1];
1070  uint8_t *lpv = sono->data[2] + idx * sono->linesize[2];
1071 
1072  for (x = 0; x < w; x += 2) {
1073  *lpy++ = lrintf(c[x].yuv.y + 16.0f);
1074  *lpu++ = lrintf(c[x].yuv.u + 128.0f);
1075  *lpv++ = lrintf(c[x].yuv.v + 128.0f);
1076  *lpy++ = lrintf(c[x+1].yuv.y + 16.0f);
1077  if (fmt == AV_PIX_FMT_YUV444P) {
1078  *lpu++ = lrintf(c[x+1].yuv.u + 128.0f);
1079  *lpv++ = lrintf(c[x+1].yuv.v + 128.0f);
1080  }
1081  }
1082 }
1083 
1085 {
1086  int x, i;
1087  if (!s->sono_count) {
1088  for (x = 0; x < s->cqt_len; x++) {
1089  s->h_buf[x] = s->bar_v_buf[x] * 0.5f * (s->cqt_result[x].re + s->cqt_result[x].im);
1090  }
1091  if (s->fcount > 1) {
1092  float rcp_fcount = 1.0f / s->fcount;
1093  for (x = 0; x < s->width; x++) {
1094  float h = 0.0f;
1095  for (i = 0; i < s->fcount; i++)
1096  h += s->h_buf[s->fcount * x + i];
1097  s->h_buf[x] = rcp_fcount * h;
1098  }
1099  }
1100  for (x = 0; x < s->width; x++) {
1101  s->h_buf[x] = calculate_gamma(s->h_buf[x], s->bar_g);
1102  s->rcp_h_buf[x] = 1.0f / (s->h_buf[x] + 0.0001f);
1103  }
1104  }
1105 
1106  for (x = 0; x < s->cqt_len; x++) {
1107  s->cqt_result[x].re *= s->sono_v_buf[x];
1108  s->cqt_result[x].im *= s->sono_v_buf[x];
1109  }
1110 
1111  if (s->fcount > 1) {
1112  float rcp_fcount = 1.0f / s->fcount;
1113  for (x = 0; x < s->width; x++) {
1114  AVComplexFloat result = {0.0f, 0.0f};
1115  for (i = 0; i < s->fcount; i++) {
1116  result.re += s->cqt_result[s->fcount * x + i].re;
1117  result.im += s->cqt_result[s->fcount * x + i].im;
1118  }
1119  s->cqt_result[x].re = rcp_fcount * result.re;
1120  s->cqt_result[x].im = rcp_fcount * result.im;
1121  }
1122  }
1123 
1124  if (s->format == AV_PIX_FMT_RGB24)
1125  rgb_from_cqt(s->c_buf, s->cqt_result, s->sono_g, s->width, s->cscheme_v);
1126  else
1127  yuv_from_cqt(s->c_buf, s->cqt_result, s->sono_g, s->width, s->cmatrix, s->cscheme_v);
1128 }
1129 
1130 static int plot_cqt(AVFilterContext *ctx, AVFrame **frameout)
1131 {
1132  AVFilterLink *outlink = ctx->outputs[0];
1133  ShowCQTContext *s = ctx->priv;
1134  int64_t last_time, cur_time;
1135 
1136 #define UPDATE_TIME(t) \
1137  cur_time = av_gettime_relative(); \
1138  t += cur_time - last_time; \
1139  last_time = cur_time
1140 
1141  last_time = av_gettime_relative();
1142 
1143  memcpy(s->fft_input, s->fft_data, s->fft_len * sizeof(*s->fft_data));
1144  if (s->attack_data) {
1145  int k;
1146  for (k = 0; k < s->remaining_fill_max; k++) {
1147  s->fft_input[s->fft_len/2+k].re *= s->attack_data[k];
1148  s->fft_input[s->fft_len/2+k].im *= s->attack_data[k];
1149  }
1150  }
1151 
1152  s->tx_fn(s->fft_ctx, s->fft_result, s->fft_input, sizeof(AVComplexFloat));
1153  UPDATE_TIME(s->fft_time);
1154 
1155  s->cqt_calc(s->cqt_result, s->fft_result, s->coeffs, s->cqt_len, s->fft_len);
1156  UPDATE_TIME(s->cqt_time);
1157 
1158  process_cqt(s);
1159  UPDATE_TIME(s->process_cqt_time);
1160 
1161  if (s->sono_h) {
1162  s->update_sono(s->sono_frame, s->c_buf, s->sono_idx);
1163  UPDATE_TIME(s->update_sono_time);
1164  }
1165 
1166  if (!s->sono_count) {
1167  AVFrame *out = *frameout = ff_get_video_buffer(outlink, outlink->w, outlink->h);
1168  if (!out)
1169  return AVERROR(ENOMEM);
1170  out->sample_aspect_ratio = av_make_q(1, 1);
1171  out->color_range = AVCOL_RANGE_MPEG;
1172  out->colorspace = s->csp;
1173  UPDATE_TIME(s->alloc_time);
1174 
1175  if (s->bar_h) {
1176  s->draw_bar(out, s->h_buf, s->rcp_h_buf, s->c_buf, s->bar_h, s->bar_t);
1177  UPDATE_TIME(s->bar_time);
1178  }
1179 
1180  if (s->axis_h) {
1181  s->draw_axis(out, s->axis_frame, s->c_buf, s->bar_h);
1182  UPDATE_TIME(s->axis_time);
1183  }
1184 
1185  if (s->sono_h) {
1186  s->draw_sono(out, s->sono_frame, s->bar_h + s->axis_h, s->sono_idx);
1187  UPDATE_TIME(s->sono_time);
1188  }
1189  out->pts = s->next_pts;
1190  out->duration = PTS_STEP;
1191  s->next_pts += PTS_STEP;
1192  }
1193  s->sono_count = (s->sono_count + 1) % s->count;
1194  if (s->sono_h)
1195  s->sono_idx = (s->sono_idx + s->sono_h - 1) % s->sono_h;
1196  return 0;
1197 }
1198 
1200 {
1201  double kr, kg, kb;
1202 
1203  /* from vf_colorspace.c */
1204  switch (s->csp) {
1205  default:
1206  av_log(s->ctx, AV_LOG_WARNING, "unsupported colorspace, setting it to unspecified.\n");
1207  s->csp = AVCOL_SPC_UNSPECIFIED;
1208  case AVCOL_SPC_UNSPECIFIED:
1209  case AVCOL_SPC_BT470BG:
1210  case AVCOL_SPC_SMPTE170M:
1211  kr = 0.299; kb = 0.114; break;
1212  case AVCOL_SPC_BT709:
1213  kr = 0.2126; kb = 0.0722; break;
1214  case AVCOL_SPC_FCC:
1215  kr = 0.30; kb = 0.11; break;
1216  case AVCOL_SPC_SMPTE240M:
1217  kr = 0.212; kb = 0.087; break;
1218  case AVCOL_SPC_BT2020_NCL:
1219  kr = 0.2627; kb = 0.0593; break;
1220  }
1221 
1222  kg = 1.0 - kr - kb;
1223  s->cmatrix[0][0] = 219.0 * kr;
1224  s->cmatrix[0][1] = 219.0 * kg;
1225  s->cmatrix[0][2] = 219.0 * kb;
1226  s->cmatrix[1][0] = -112.0 * kr / (1.0 - kb);
1227  s->cmatrix[1][1] = -112.0 * kg / (1.0 - kb);
1228  s->cmatrix[1][2] = 112.0;
1229  s->cmatrix[2][0] = 112.0;
1230  s->cmatrix[2][1] = -112.0 * kg / (1.0 - kr);
1231  s->cmatrix[2][2] = -112.0 * kb / (1.0 - kr);
1232 }
1233 
1235 {
1236  char tail[2];
1237  int k;
1238 
1239  if (sscanf(s->cscheme, " %f | %f | %f | %f | %f | %f %1s", &s->cscheme_v[0],
1240  &s->cscheme_v[1], &s->cscheme_v[2], &s->cscheme_v[3], &s->cscheme_v[4],
1241  &s->cscheme_v[5], tail) != 6)
1242  goto fail;
1243 
1244  for (k = 0; k < 6; k++)
1245  if (isnan(s->cscheme_v[k]) || s->cscheme_v[k] < 0.0f || s->cscheme_v[k] > 1.0f)
1246  goto fail;
1247 
1248  return 0;
1249 
1250 fail:
1251  av_log(s->ctx, AV_LOG_ERROR, "invalid cscheme.\n");
1252  return AVERROR(EINVAL);
1253 }
1254 
1255 /* main filter control */
1257 {
1258  ShowCQTContext *s = ctx->priv;
1259  s->ctx = ctx;
1260 
1261  if (!s->fullhd) {
1262  av_log(ctx, AV_LOG_WARNING, "fullhd option is deprecated, use size/s option instead.\n");
1263  if (s->width != 1920 || s->height != 1080) {
1264  av_log(ctx, AV_LOG_ERROR, "fullhd set to 0 but with custom dimension.\n");
1265  return AVERROR(EINVAL);
1266  }
1267  s->width /= 2;
1268  s->height /= 2;
1269  s->fullhd = 1;
1270  }
1271 
1272  if (s->axis_h < 0) {
1273  s->axis_h = s->width / 60;
1274  if (s->axis_h & 1)
1275  s->axis_h++;
1276  if (s->bar_h >= 0 && s->sono_h >= 0)
1277  s->axis_h = s->height - s->bar_h - s->sono_h;
1278  if (s->bar_h >= 0 && s->sono_h < 0)
1279  s->axis_h = FFMIN(s->axis_h, s->height - s->bar_h);
1280  if (s->bar_h < 0 && s->sono_h >= 0)
1281  s->axis_h = FFMIN(s->axis_h, s->height - s->sono_h);
1282  }
1283 
1284  if (s->bar_h < 0) {
1285  s->bar_h = (s->height - s->axis_h) / 2;
1286  if (s->bar_h & 1)
1287  s->bar_h--;
1288  if (s->sono_h >= 0)
1289  s->bar_h = s->height - s->sono_h - s->axis_h;
1290  }
1291 
1292  if (s->sono_h < 0)
1293  s->sono_h = s->height - s->axis_h - s->bar_h;
1294 
1295  if ((s->width & 1) || (s->height & 1) || (s->bar_h & 1) || (s->axis_h & 1) || (s->sono_h & 1) ||
1296  (s->bar_h < 0) || (s->axis_h < 0) || (s->sono_h < 0) || (s->bar_h > s->height) ||
1297  (s->axis_h > s->height) || (s->sono_h > s->height) || (s->bar_h + s->axis_h + s->sono_h != s->height)) {
1298  av_log(ctx, AV_LOG_ERROR, "invalid dimension.\n");
1299  return AVERROR(EINVAL);
1300  }
1301 
1302  if (!s->fcount) {
1303  do {
1304  s->fcount++;
1305  } while(s->fcount * s->width < 1920 && s->fcount < 10);
1306  }
1307 
1309 
1310  return init_cscheme(s);
1311 }
1312 
1314 {
1315  common_uninit(ctx->priv);
1316 }
1317 
1319 {
1322  AVFilterLink *inlink = ctx->inputs[0];
1323  AVFilterLink *outlink = ctx->outputs[0];
1325  static const enum AVPixelFormat pix_fmts[] = {
1328  };
1331  int ret;
1332 
1333  /* set input audio formats */
1335  if ((ret = ff_formats_ref(formats, &inlink->outcfg.formats)) < 0)
1336  return ret;
1337 
1339  if ((ret = ff_channel_layouts_ref(layouts, &inlink->outcfg.channel_layouts)) < 0)
1340  return ret;
1341 
1343  if ((ret = ff_formats_ref(formats, &inlink->outcfg.samplerates)) < 0)
1344  return ret;
1345 
1346  /* set output video format */
1348  if ((ret = ff_formats_ref(formats, &outlink->incfg.formats)) < 0)
1349  return ret;
1350 
1351  return 0;
1352 }
1353 
1354 static int config_output(AVFilterLink *outlink)
1355 {
1356  AVFilterContext *ctx = outlink->src;
1357  AVFilterLink *inlink = ctx->inputs[0];
1358  ShowCQTContext *s = ctx->priv;
1359  float scale = 1.f;
1360  int ret;
1361 
1362  common_uninit(s);
1363 
1364  outlink->w = s->width;
1365  outlink->h = s->height;
1366  s->format = outlink->format;
1367  outlink->sample_aspect_ratio = av_make_q(1, 1);
1368  outlink->frame_rate = s->rate;
1369  outlink->time_base = av_mul_q(av_inv_q(s->rate), av_make_q(1, PTS_STEP));
1370  av_log(ctx, AV_LOG_INFO, "video: %dx%d %s %d/%d fps, bar_h = %d, axis_h = %d, sono_h = %d.\n",
1371  s->width, s->height, av_get_pix_fmt_name(s->format), s->rate.num, s->rate.den,
1372  s->bar_h, s->axis_h, s->sono_h);
1373 
1374  s->cqt_len = s->width * s->fcount;
1375  if (!(s->freq = create_freq_table(s->basefreq, s->endfreq, s->cqt_len)))
1376  return AVERROR(ENOMEM);
1377 
1378  if ((ret = init_volume(s)) < 0)
1379  return ret;
1380 
1381  s->fft_bits = FFMAX(ceil(log2(inlink->sample_rate * s->timeclamp)), 4);
1382  s->fft_len = 1 << s->fft_bits;
1383  av_log(ctx, AV_LOG_INFO, "fft_len = %d, cqt_len = %d.\n", s->fft_len, s->cqt_len);
1384 
1385  ret = av_tx_init(&s->fft_ctx, &s->tx_fn, AV_TX_FLOAT_FFT, 0, s->fft_len, &scale, 0);
1386  s->fft_data = av_calloc(s->fft_len, sizeof(*s->fft_data));
1387  s->fft_input = av_calloc(FFALIGN(s->fft_len + 64, 256), sizeof(*s->fft_input));
1388  s->fft_result = av_calloc(FFALIGN(s->fft_len + 64, 256), sizeof(*s->fft_result));
1389  s->cqt_result = av_malloc_array(s->cqt_len, sizeof(*s->cqt_result));
1390  if (!s->fft_ctx || !s->fft_data || !s->fft_result || !s->cqt_result)
1391  return AVERROR(ENOMEM);
1392 
1393  s->remaining_fill_max = s->fft_len / 2;
1394  if (s->attack > 0.0) {
1395  int k;
1396 
1397  s->remaining_fill_max = FFMIN(s->remaining_fill_max, ceil(inlink->sample_rate * s->attack));
1398  s->attack_data = av_malloc_array(s->remaining_fill_max, sizeof(*s->attack_data));
1399  if (!s->attack_data)
1400  return AVERROR(ENOMEM);
1401 
1402  for (k = 0; k < s->remaining_fill_max; k++) {
1403  double y = M_PI * k / (inlink->sample_rate * s->attack);
1404  s->attack_data[k] = 0.355768 + 0.487396 * cos(y) + 0.144232 * cos(2*y) + 0.012604 * cos(3*y);
1405  }
1406  }
1407 
1408  s->cqt_align = 1;
1409  s->cqt_calc = cqt_calc;
1410  s->permute_coeffs = NULL;
1411  s->draw_sono = draw_sono;
1412  if (s->format == AV_PIX_FMT_RGB24) {
1413  s->draw_bar = draw_bar_rgb;
1414  s->draw_axis = draw_axis_rgb;
1415  s->update_sono = update_sono_rgb;
1416  } else {
1417  s->draw_bar = draw_bar_yuv;
1418  s->draw_axis = draw_axis_yuv;
1419  s->update_sono = update_sono_yuv;
1420  }
1421 
1422 #if ARCH_X86
1424 #endif
1425 
1426  if ((ret = init_cqt(s)) < 0)
1427  return ret;
1428 
1429  if (s->axis_h) {
1430  if (!s->axis) {
1431  if ((ret = init_axis_empty(s)) < 0)
1432  return ret;
1433  } else if (s->axisfile) {
1434  if (init_axis_from_file(s) < 0) {
1435  av_log(ctx, AV_LOG_WARNING, "loading axis image failed, fallback to font rendering.\n");
1436  if (init_axis_from_font(s) < 0) {
1437  av_log(ctx, AV_LOG_WARNING, "loading axis font failed, disable text drawing.\n");
1438  if ((ret = init_axis_empty(s)) < 0)
1439  return ret;
1440  }
1441  }
1442  } else {
1443  if (init_axis_from_font(s) < 0) {
1444  av_log(ctx, AV_LOG_WARNING, "loading axis font failed, disable text drawing.\n");
1445  if ((ret = init_axis_empty(s)) < 0)
1446  return ret;
1447  }
1448  }
1449  }
1450 
1451  if (s->sono_h) {
1452  s->sono_frame = alloc_frame_empty((outlink->format == AV_PIX_FMT_YUV420P) ?
1453  AV_PIX_FMT_YUV422P : outlink->format, s->width, s->sono_h);
1454  if (!s->sono_frame)
1455  return AVERROR(ENOMEM);
1456  }
1457 
1458  s->h_buf = av_malloc_array(s->cqt_len, sizeof (*s->h_buf));
1459  s->rcp_h_buf = av_malloc_array(s->width, sizeof(*s->rcp_h_buf));
1460  s->c_buf = av_malloc_array(s->width, sizeof(*s->c_buf));
1461  if (!s->h_buf || !s->rcp_h_buf || !s->c_buf)
1462  return AVERROR(ENOMEM);
1463 
1464  s->sono_count = 0;
1465  s->next_pts = 0;
1466  s->sono_idx = 0;
1467  s->remaining_fill = s->remaining_fill_max;
1468  s->remaining_frac = 0;
1469  s->step_frac = av_div_q(av_make_q(inlink->sample_rate, s->count) , s->rate);
1470  s->step = (int)(s->step_frac.num / s->step_frac.den);
1471  s->step_frac.num %= s->step_frac.den;
1472  if (s->step_frac.num) {
1473  av_log(ctx, AV_LOG_INFO, "audio: %d Hz, step = %d + %d/%d.\n",
1474  inlink->sample_rate, s->step, s->step_frac.num, s->step_frac.den);
1475  av_log(ctx, AV_LOG_WARNING, "fractional step.\n");
1476  } else {
1477  av_log(ctx, AV_LOG_INFO, "audio: %d Hz, step = %d.\n",
1478  inlink->sample_rate, s->step);
1479  }
1480 
1481  return 0;
1482 }
1483 
1484 
1485 static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
1486 {
1487  AVFilterContext *ctx = inlink->dst;
1488  AVFilterLink *outlink = ctx->outputs[0];
1489  ShowCQTContext *s = ctx->priv;
1490  int remaining, step, ret, x, i, j, m;
1491  float *audio_data;
1492  AVFrame *out = NULL;
1493 
1494  if (!insamples) {
1495  while (s->remaining_fill < s->remaining_fill_max) {
1496  memset(&s->fft_data[s->fft_len/2 + s->remaining_fill_max - s->remaining_fill], 0, sizeof(*s->fft_data) * s->remaining_fill);
1497  ret = plot_cqt(ctx, &out);
1498  if (ret < 0)
1499  return ret;
1500 
1501  step = s->step + (s->step_frac.num + s->remaining_frac) / s->step_frac.den;
1502  s->remaining_frac = (s->step_frac.num + s->remaining_frac) % s->step_frac.den;
1503  for (x = 0; x < (s->fft_len/2 + s->remaining_fill_max - step); x++)
1504  s->fft_data[x] = s->fft_data[x+step];
1505  s->remaining_fill += step;
1506 
1507  if (out)
1508  return ff_filter_frame(outlink, out);
1509  }
1510  return AVERROR_EOF;
1511  }
1512 
1513  remaining = insamples->nb_samples;
1514  audio_data = (float*) insamples->data[0];
1515 
1516  while (remaining) {
1517  i = insamples->nb_samples - remaining;
1518  j = s->fft_len/2 + s->remaining_fill_max - s->remaining_fill;
1519  if (remaining >= s->remaining_fill) {
1520  for (m = 0; m < s->remaining_fill; m++) {
1521  s->fft_data[j+m].re = audio_data[2*(i+m)];
1522  s->fft_data[j+m].im = audio_data[2*(i+m)+1];
1523  }
1524  ret = plot_cqt(ctx, &out);
1525  if (ret < 0) {
1526  av_frame_free(&insamples);
1527  return ret;
1528  }
1529  remaining -= s->remaining_fill;
1530  if (out) {
1531  int64_t pts = av_rescale_q(insamples->pts, inlink->time_base, av_make_q(1, inlink->sample_rate));
1532  pts += insamples->nb_samples - remaining - s->remaining_fill_max;
1533  pts = av_rescale_q(pts, av_make_q(1, inlink->sample_rate), outlink->time_base);
1534  if (FFABS(pts - out->pts) > PTS_TOLERANCE) {
1535  av_log(ctx, AV_LOG_DEBUG, "changing pts from %"PRId64" (%.3f) to %"PRId64" (%.3f).\n",
1536  out->pts, out->pts * av_q2d(outlink->time_base),
1537  pts, pts * av_q2d(outlink->time_base));
1538  out->pts = pts;
1539  s->next_pts = pts + PTS_STEP;
1540  }
1541  ret = ff_filter_frame(outlink, out);
1542  if (ret < 0) {
1543  av_frame_free(&insamples);
1544  return ret;
1545  }
1546  out = NULL;
1547  }
1548  step = s->step + (s->step_frac.num + s->remaining_frac) / s->step_frac.den;
1549  s->remaining_frac = (s->step_frac.num + s->remaining_frac) % s->step_frac.den;
1550  for (m = 0; m < s->fft_len/2 + s->remaining_fill_max - step; m++)
1551  s->fft_data[m] = s->fft_data[m+step];
1552  s->remaining_fill = step;
1553  } else {
1554  for (m = 0; m < remaining; m++) {
1555  s->fft_data[j+m].re = audio_data[2*(i+m)];
1556  s->fft_data[j+m].im = audio_data[2*(i+m)+1];
1557  }
1558  s->remaining_fill -= remaining;
1559  remaining = 0;
1560  }
1561  }
1562  av_frame_free(&insamples);
1563  return 0;
1564 }
1565 
1566 static int request_frame(AVFilterLink *outlink)
1567 {
1568  AVFilterLink *inlink = outlink->src->inputs[0];
1569  int ret;
1570 
1572  if (ret == AVERROR_EOF)
1574  return ret;
1575 }
1576 
1577 static const AVFilterPad showcqt_inputs[] = {
1578  {
1579  .name = "default",
1580  .type = AVMEDIA_TYPE_AUDIO,
1581  .filter_frame = filter_frame,
1582  },
1583 };
1584 
1585 static const AVFilterPad showcqt_outputs[] = {
1586  {
1587  .name = "default",
1588  .type = AVMEDIA_TYPE_VIDEO,
1589  .config_props = config_output,
1590  .request_frame = request_frame,
1591  },
1592 };
1593 
1595  .name = "showcqt",
1596  .description = NULL_IF_CONFIG_SMALL("Convert input audio to a CQT (Constant/Clamped Q Transform) spectrum video output."),
1597  .init = init,
1598  .uninit = uninit,
1599  .priv_size = sizeof(ShowCQTContext),
1603  .priv_class = &showcqt_class,
1604 };
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:31
formats
formats
Definition: signature.h:48
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:101
rgb::b
uint8_t b
Definition: rpzaenc.c:62
av_gettime_relative
int64_t av_gettime_relative(void)
Get the current time in microseconds since some unspecified starting point.
Definition: time.c:56
AVFilterChannelLayouts
A list of supported channel layouts.
Definition: formats.h:85
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
ff_avf_showcqt
const AVFilter ff_avf_showcqt
Definition: avf_showcqt.c:1594
AV_CHANNEL_LAYOUT_STEREO_DOWNMIX
#define AV_CHANNEL_LAYOUT_STEREO_DOWNMIX
Definition: channel_layout.h:397
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
name
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 minimum maximum flags name is the option name
Definition: writing_filters.txt:88
level
uint8_t level
Definition: svq3.c:204
draw_axis_yuv
static void draw_axis_yuv(AVFrame *out, AVFrame *axis, const ColorFloat *c, int off)
Definition: avf_showcqt.c:963
r
const char * r
Definition: vf_curves.c:126
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
draw_bar_yuv
static void draw_bar_yuv(AVFrame *out, const float *h, const float *rcp_h, const ColorFloat *c, int bar_h, float bar_t)
Definition: avf_showcqt.c:810
ff_make_format_list
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:380
out
FILE * out
Definition: movenc.c:54
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:242
AV_CHANNEL_LAYOUT_STEREO
#define AV_CHANNEL_LAYOUT_STEREO
Definition: channel_layout.h:369
color
Definition: vf_paletteuse.c:509
u
#define u(width, name, range_min, range_max)
Definition: cbs_h2645.c:262
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:969
sample_fmts
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:947
ff_channel_layouts_ref
int ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts **ref)
Add *ref as a new reference to f.
Definition: formats.c:591
layouts
enum MovChannelLayoutTag * layouts
Definition: mov_chan.c:326
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
ColorFloat
Definition: avf_showcqt.h:41
AV_OPT_TYPE_VIDEO_RATE
@ AV_OPT_TYPE_VIDEO_RATE
offset must point to AVRational
Definition: opt.h:238
var_names
static const char *const var_names[]
Definition: noise_bsf.c:30
av_div_q
AVRational av_div_q(AVRational b, AVRational c)
Divide one rational by another.
Definition: rational.c:88
init_cscheme
static int init_cscheme(ShowCQTContext *s)
Definition: avf_showcqt.c:1234
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
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:99
im
float im
Definition: fft.c:79
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:330
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
pixdesc.h
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:437
step
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But a word about which is also called distortion Distortion can be quantified by almost any quality measurement one chooses the sum of squared differences is used but more complex methods that consider psychovisual effects can be used as well It makes no difference in this discussion First step
Definition: rate_distortion.txt:58
AVFrame::width
int width
Definition: frame.h:402
w
uint8_t w
Definition: llviddspenc.c:38
AVOption
AVOption.
Definition: opt.h:251
b
#define b
Definition: input.c:41
FILTER_QUERY_FUNC
#define FILTER_QUERY_FUNC(func)
Definition: internal.h:171
data
const char data[16]
Definition: mxf.c:146
expf
#define expf(x)
Definition: libm.h:283
FLAGS
#define FLAGS
Definition: avf_showcqt.c:58
half
static uint8_t half(int a, int b)
Definition: mobiclip.c:541
ff_request_frame
int ff_request_frame(AVFilterLink *link)
Request an input frame from the filter at the other end of the link.
Definition: avfilter.c:415
BLEND_WITH_CHROMA
#define BLEND_WITH_CHROMA(c)
Definition: avf_showcqt.c:890
base
uint8_t base
Definition: vp3data.h:128
c_weighting
static double c_weighting(void *p, double f)
Definition: avf_showcqt.c:221
AVComplexFloat
Definition: tx.h:27
PTS_STEP
#define PTS_STEP
Definition: avf_showcqt.c:54
max
#define max(a, b)
Definition: cuda_runtime.h:33
CSCHEME
#define CSCHEME
Definition: avf_showcqt.c:53
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:165
render_default_font
static int render_default_font(AVFrame *tmp)
Definition: avf_showcqt.c:653
AVERROR_UNKNOWN
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
Definition: error.h:73
draw_axis_rgb
static void draw_axis_rgb(AVFrame *out, AVFrame *axis, const ColorFloat *c, int off)
Definition: avf_showcqt.c:861
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:883
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:351
AVFilterFormats
A list of supported formats for one end of a filter link.
Definition: formats.h:64
av_expr_parse
int av_expr_parse(AVExpr **expr, const char *s, const char *const *const_names, const char *const *func1_names, double(*const *funcs1)(void *, double), const char *const *func2_names, double(*const *funcs2)(void *, double, double), int log_offset, void *log_ctx)
Parse an expression.
Definition: eval.c:685
AVCOL_SPC_BT470BG
@ AVCOL_SPC_BT470BG
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
Definition: pixfmt.h:593
rgb
Definition: rpzaenc.c:59
AVComplexFloat::im
float im
Definition: tx.h:28
a_weighting
static double a_weighting(void *p, double f)
Definition: avf_showcqt.c:206
fail
#define fail()
Definition: checkasm.h:134
val
static double val(void *priv, double ch)
Definition: aeval.c:77
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: avf_showcqt.c:1313
scale
static av_always_inline float scale(float x, float s)
Definition: vf_v360.c:1389
pts
static int64_t pts
Definition: transcode_aac.c:653
av_expr_free
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
Definition: eval.c:336
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:49
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:87
ceil
static __device__ float ceil(float a)
Definition: cuda_runtime.h:176
lrint
#define lrint
Definition: tablegen.h:53
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
mask
static const uint16_t mask[17]
Definition: lzw.c:38
width
#define width
BLEND_WITHOUT_CHROMA
#define BLEND_WITHOUT_CHROMA(c, alpha_inc)
Definition: avf_showcqt.c:910
s
#define s(width, name)
Definition: cbs_vp9.c:256
UPDATE_TIME
#define UPDATE_TIME(t)
DRAW_BAR_WITHOUT_CHROMA
#define DRAW_BAR_WITHOUT_CHROMA(x)
Definition: avf_showcqt.c:799
AV_PIX_FMT_YUVA420P
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition: pixfmt.h:101
init_colormatrix
static void init_colormatrix(ShowCQTContext *s)
Definition: avf_showcqt.c:1199
format
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 format(the sample packing is implied by the sample format) and sample rate. The lists are not just lists
floor
static __device__ float floor(float a)
Definition: cuda_runtime.h:173
g
const char * g
Definition: vf_curves.c:127
AVCOL_SPC_SMPTE170M
@ AVCOL_SPC_SMPTE170M
also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above
Definition: pixfmt.h:594
AV_OPT_TYPE_DOUBLE
@ AV_OPT_TYPE_DOUBLE
Definition: opt.h:227
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
ff_formats_ref
int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add *ref as a new reference to formats.
Definition: formats.c:596
av_q2d
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
pix_fmts
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:296
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:48
av_expr_eval
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
Evaluate a previously parsed expression.
Definition: eval.c:766
BLEND_CHROMA2x2
#define BLEND_CHROMA2x2(c)
Definition: avf_showcqt.c:941
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
AVExpr
Definition: eval.c:157
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
ShowCQTContext
Definition: avf_showcqt.h:46
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: internal.h:194
AV_PIX_FMT_RGBA
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:93
mul
static float mul(float src0, float src1)
Definition: dnn_backend_native_layer_mathbinary.c:39
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:64
if
if(ret)
Definition: filter_design.txt:179
clip_with_log
static double clip_with_log(void *log_ctx, const char *name, double val, double min, double max, double nan_replace, int idx)
Definition: avf_showcqt.c:185
xs
#define xs(width, name, var, subs,...)
Definition: cbs_vp9.c:352
result
and forward the result(frame or status change) to the corresponding input. If nothing is possible
NULL
#define NULL
Definition: coverity.c:32
init
static av_cold int init(AVFilterContext *ctx)
Definition: avf_showcqt.c:1256
vars
static const uint8_t vars[2][12]
Definition: camellia.c:183
render_freetype
static int render_freetype(ShowCQTContext *s, AVFrame *tmp, char *fontfile)
Definition: avf_showcqt.c:505
isnan
#define isnan(x)
Definition: libm.h:340
AV_OPT_TYPE_IMAGE_SIZE
@ AV_OPT_TYPE_IMAGE_SIZE
offset must point to two consecutive integers
Definition: opt.h:235
AVFilterContext::inputs
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:400
sqrtf
static __device__ float sqrtf(float a)
Definition: cuda_runtime.h:184
double
double
Definition: af_crystalizer.c:132
time.h
rgb_from_cqt
static void rgb_from_cqt(ColorFloat *c, const AVComplexFloat *v, float g, int len, float cscheme[6])
Definition: avf_showcqt.c:733
showcqt_inputs
static const AVFilterPad showcqt_inputs[]
Definition: avf_showcqt.c:1577
exp
int8_t exp
Definition: eval.c:72
alloc_frame_empty
static AVFrame * alloc_frame_empty(enum AVPixelFormat format, int w, int h)
Definition: avf_showcqt.c:359
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
init_axis_from_file
static int init_axis_from_file(ShowCQTContext *s)
Definition: avf_showcqt.c:403
eval.h
f
f
Definition: af_crystalizer.c:122
AV_PIX_FMT_RGB24
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:68
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:115
showcqt_outputs
static const AVFilterPad showcqt_outputs[]
Definition: avf_showcqt.c:1585
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition: channel_layout.h:301
process_cqt
static void process_cqt(ShowCQTContext *s)
Definition: avf_showcqt.c:1084
calculate_gamma
static float calculate_gamma(float v, float g)
Definition: avf_showcqt.c:720
init_axis_color
static int init_axis_color(ShowCQTContext *s, AVFrame *tmp, int half)
Definition: avf_showcqt.c:458
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:425
AV_SAMPLE_FMT_NONE
@ AV_SAMPLE_FMT_NONE
Definition: samplefmt.h:56
init_axis_from_font
static int init_axis_from_font(ShowCQTContext *s)
Definition: avf_showcqt.c:679
av_make_q
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition: rational.h:71
AVComplexFloat::re
float re
Definition: tx.h:28
update_sono_rgb
static void update_sono_rgb(AVFrame *sono, const ColorFloat *c, int idx)
Definition: avf_showcqt.c:1053
Coeffs::val
float * val
Definition: avf_showcqt.h:29
query_formats
static int query_formats(AVFilterContext *ctx)
Definition: avf_showcqt.c:1318
ff_load_image
int ff_load_image(uint8_t *data[4], int linesize[4], int *w, int *h, enum AVPixelFormat *pix_fmt, const char *filename, void *log_ctx)
Load image from filename and put the resulting image in data.
Definition: lavfutils.c:34
TLENGTH
#define TLENGTH
Definition: avf_showcqt.c:47
AVFrame::format
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition: frame.h:417
height
#define height
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
rgb::g
uint8_t g
Definition: rpzaenc.c:61
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:167
init_volume
static int init_volume(ShowCQTContext *s)
Definition: avf_showcqt.c:228
xga_font_data.h
ENDFREQ
#define ENDFREQ
Definition: avf_showcqt.c:46
M_PI
#define M_PI
Definition: mathematics.h:52
yuv_from_cqt
static void yuv_from_cqt(ColorFloat *c, const AVComplexFloat *v, float gamma, int len, float cm[3][3], float cscheme[6])
Definition: avf_showcqt.c:743
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:294
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:191
internal.h
AV_OPT_TYPE_FLOAT
@ AV_OPT_TYPE_FLOAT
Definition: opt.h:228
BLEND_CHROMA2
#define BLEND_CHROMA2(c)
Definition: avf_showcqt.c:924
Coeffs::len
int len
Definition: avf_showcqt.h:30
AVCOL_SPC_SMPTE240M
@ AVCOL_SPC_SMPTE240M
derived from 170M primaries and D65 white point, 170M is derived from BT470 System M's primaries
Definition: pixfmt.h:595
convert_axis_pixel_format
static enum AVPixelFormat convert_axis_pixel_format(enum AVPixelFormat format)
Definition: avf_showcqt.c:385
create_freq_table
static double * create_freq_table(double base, double end, int n)
Definition: avf_showcqt.c:165
AVFrame::nb_samples
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:410
b_weighting
static double b_weighting(void *p, double f)
Definition: avf_showcqt.c:214
avpriv_vga16_font
const uint8_t avpriv_vga16_font[4096]
Definition: xga_font_data.c:160
lrintf
#define lrintf(x)
Definition: libm_mips.h:72
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
b_func
static double b_func(void *p, double x)
Definition: avf_showcqt.c:452
r_func
static double r_func(void *p, double x)
Definition: avf_showcqt.c:440
AVCOL_SPC_BT2020_NCL
@ AVCOL_SPC_BT2020_NCL
ITU-R BT2020 non-constant luminance system.
Definition: pixfmt.h:598
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:31
VOLUME_MAX
#define VOLUME_MAX
Definition: avf_showcqt.c:49
AVSampleFormat
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:55
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
cbrtf
static av_always_inline float cbrtf(float x)
Definition: libm.h:61
TLENGTH_MIN
#define TLENGTH_MIN
Definition: avf_showcqt.c:48
rgb::r
uint8_t r
Definition: rpzaenc.c:60
OFFSET
#define OFFSET(x)
Definition: avf_showcqt.c:57
av_inv_q
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition: rational.h:159
len
int len
Definition: vorbis_enc_data.h:426
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:55
draw_bar_rgb
static void draw_bar_rgb(AVFrame *out, const float *h, const float *rcp_h, const ColorFloat *c, int bar_h, float bar_t)
Definition: avf_showcqt.c:757
AVCOL_SPC_UNSPECIFIED
@ AVCOL_SPC_UNSPECIFIED
Definition: pixfmt.h:590
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:644
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:262
Coeffs::start
int start
Definition: avf_showcqt.h:30
log2
#define log2(x)
Definition: libm.h:404
cqt_calc
static void cqt_calc(AVComplexFloat *dst, const AVComplexFloat *src, const Coeffs *coeffs, int len, int fft_len)
Definition: avf_showcqt.c:270
common_uninit
static void common_uninit(ShowCQTContext *s)
Definition: avf_showcqt.c:108
AVFilter
Filter definition.
Definition: avfilter.h:161
PTS_TOLERANCE
#define PTS_TOLERANCE
Definition: avf_showcqt.c:55
plot_cqt
static int plot_cqt(AVFilterContext *ctx, AVFrame **frameout)
Definition: avf_showcqt.c:1130
ret
ret
Definition: filter_design.txt:187
config_output
static int config_output(AVFilterLink *outlink)
Definition: avf_showcqt.c:1354
FONTCOLOR
#define FONTCOLOR
Definition: avf_showcqt.c:50
showcqt_options
static const AVOption showcqt_options[]
Definition: avf_showcqt.c:60
AVFrame::height
int height
Definition: frame.h:402
ff_all_samplerates
AVFilterFormats * ff_all_samplerates(void)
Definition: formats.c:551
Coeffs
Definition: af_atilt.c:28
channel_layout.h
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
AVCOL_SPC_FCC
@ AVCOL_SPC_FCC
FCC Title 47 Code of Federal Regulations 73.682 (a)(20)
Definition: pixfmt.h:592
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:225
avfilter.h
midi
static double midi(void *p, double f)
Definition: avf_showcqt.c:435
avf_showcqt.h
cm
#define cm
Definition: dvbsubdec.c:39
init_cqt
static int init_cqt(ShowCQTContext *s)
Definition: avf_showcqt.c:297
update_sono_yuv
static void update_sono_yuv(AVFrame *sono, const ColorFloat *c, int idx)
Definition: avf_showcqt.c:1065
ff_showcqt_init_x86
void ff_showcqt_init_x86(ShowCQTContext *s)
Definition: avf_showcqt_init.c:47
lavfutils.h
g_func
static double g_func(void *p, double x)
Definition: avf_showcqt.c:446
av_mul_q
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition: rational.c:80
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:71
AVFilterContext
An instance of a filter.
Definition: avfilter.h:392
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *insamples)
Definition: avf_showcqt.c:1485
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
AV_PIX_FMT_YUV422P
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:70
AVFilterFormatsConfig::formats
AVFilterFormats * formats
List of supported formats (pixel or sample).
Definition: avfilter.h:496
BASEFREQ
#define BASEFREQ
Definition: avf_showcqt.c:45
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:244
channel_layouts
static const uint16_t channel_layouts[7]
Definition: dca_lbr.c:111
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: internal.h:195
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
request_frame
static int request_frame(AVFilterLink *outlink)
Definition: avf_showcqt.c:1566
ff_make_channel_layout_list
AVFilterChannelLayouts * ff_make_channel_layout_list(const AVChannelLayout *fmts)
Definition: formats.c:389
convert_header.str
string str
Definition: convert_header.py:20
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Definition: frame.h:375
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
h
h
Definition: vp9dsp_template.c:2038
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(showcqt)
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:229
AVCOL_SPC_BT709
@ AVCOL_SPC_BT709
also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / derived in SMPTE RP 177 Annex B
Definition: pixfmt.h:589
int
int
Definition: ffmpeg_filter.c:156
ff_scale_image
int ff_scale_image(uint8_t *dst_data[4], int dst_linesize[4], int dst_w, int dst_h, enum AVPixelFormat dst_pix_fmt, uint8_t *const src_data[4], int src_linesize[4], int src_w, int src_h, enum AVPixelFormat src_pix_fmt, void *log_ctx)
Scale image using libswscale.
Definition: lswsutils.c:22
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:234
lswsutils.h
AV_SAMPLE_FMT_FLT
@ AV_SAMPLE_FMT_FLT
float
Definition: samplefmt.h:60
draw_sono
static void draw_sono(AVFrame *out, AVFrame *sono, int off, int idx)
Definition: avf_showcqt.c:1028
av_clipd
av_clipd
Definition: af_crystalizer.c:132
DRAW_BAR_WITH_CHROMA
#define DRAW_BAR_WITH_CHROMA(x)
Definition: avf_showcqt.c:784
init_axis_empty
static int init_axis_empty(ShowCQTContext *s)
Definition: avf_showcqt.c:396
av_get_pix_fmt_name
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
Definition: pixdesc.c:2808
tx.h
re
float re
Definition: fft.c:79
funcs
CheckasmFunc * funcs
Definition: checkasm.c:294
min
float min
Definition: vorbis_enc_data.h:429
render_fontconfig
static int render_fontconfig(ShowCQTContext *s, AVFrame *tmp, char *font)
Definition: avf_showcqt.c:589