FFmpeg
vf_waveform.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012-2016 Paul B Mahol
3  * Copyright (c) 2013 Marton Balint
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "libavutil/avassert.h"
23 #include "libavutil/opt.h"
24 #include "libavutil/parseutils.h"
25 #include "libavutil/pixdesc.h"
27 #include "avfilter.h"
28 #include "formats.h"
29 #include "internal.h"
30 #include "video.h"
31 
32 typedef struct ThreadData {
33  AVFrame *in;
34  AVFrame *out;
35  int component;
36  int offset_y;
37  int offset_x;
38 } ThreadData;
39 
40 enum FilterType {
50 };
51 
57 };
58 
59 enum ScaleType {
62  IRE,
64 };
65 
72 };
73 
74 typedef struct GraticuleLine {
75  const char *name;
76  uint16_t pos;
78 
79 typedef struct GraticuleLines {
80  struct GraticuleLine line[4];
82 
83 typedef struct WaveformContext {
84  const AVClass *class;
85  int mode;
86  int acomp;
87  int dcomp;
88  int ncomp;
89  int pcomp;
90  uint8_t bg_color[4];
91  float fintensity;
92  int intensity;
93  int mirror;
94  int display;
95  int envelope;
96  int graticule;
97  float opacity;
98  float bgopacity;
99  int estart[4];
100  int eend[4];
101  int *emax[4][4];
102  int *emin[4][4];
103  int *peak;
104  int filter;
105  int flags;
106  int bits;
107  int max;
108  int size;
109  int scale;
110  uint8_t grat_yuva_color[4];
111  int shift_w[4], shift_h[4];
114  int rgb;
115 
116  int (*waveform_slice)(AVFilterContext *ctx, void *arg,
117  int jobnr, int nb_jobs);
118  void (*graticulef)(struct WaveformContext *s, AVFrame *out);
119  void (*blend_line)(uint8_t *dst, int size, int linesize, float o1, float o2,
120  int v, int step);
121  void (*draw_text)(AVFrame *out, int x, int y, int mult,
122  float o1, float o2, const char *txt,
123  const uint8_t color[4]);
127 
128 #define OFFSET(x) offsetof(WaveformContext, x)
129 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
130 
131 static const AVOption waveform_options[] = {
132  { "mode", "set mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS, "mode" },
133  { "m", "set mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS, "mode" },
134  { "row", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "mode" },
135  { "column", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "mode" },
136  { "intensity", "set intensity", OFFSET(fintensity), AV_OPT_TYPE_FLOAT, {.dbl=0.04}, 0, 1, FLAGS },
137  { "i", "set intensity", OFFSET(fintensity), AV_OPT_TYPE_FLOAT, {.dbl=0.04}, 0, 1, FLAGS },
138  { "mirror", "set mirroring", OFFSET(mirror), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGS },
139  { "r", "set mirroring", OFFSET(mirror), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGS },
140  { "display", "set display mode", OFFSET(display), AV_OPT_TYPE_INT, {.i64=STACK}, 0, NB_DISPLAYS-1, FLAGS, "display" },
141  { "d", "set display mode", OFFSET(display), AV_OPT_TYPE_INT, {.i64=STACK}, 0, NB_DISPLAYS-1, FLAGS, "display" },
142  { "overlay", NULL, 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY}, 0, 0, FLAGS, "display" },
143  { "stack", NULL, 0, AV_OPT_TYPE_CONST, {.i64=STACK}, 0, 0, FLAGS, "display" },
144  { "parade", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PARADE}, 0, 0, FLAGS, "display" },
145  { "components", "set components to display", OFFSET(pcomp), AV_OPT_TYPE_INT, {.i64=1}, 1, 15, FLAGS },
146  { "c", "set components to display", OFFSET(pcomp), AV_OPT_TYPE_INT, {.i64=1}, 1, 15, FLAGS },
147  { "envelope", "set envelope to display", OFFSET(envelope), AV_OPT_TYPE_INT, {.i64=0}, 0, 3, FLAGS, "envelope" },
148  { "e", "set envelope to display", OFFSET(envelope), AV_OPT_TYPE_INT, {.i64=0}, 0, 3, FLAGS, "envelope" },
149  { "none", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "envelope" },
150  { "instant", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "envelope" },
151  { "peak", NULL, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, "envelope" },
152  { "peak+instant", NULL, 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, FLAGS, "envelope" },
153  { "filter", "set filter", OFFSET(filter), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_FILTERS-1, FLAGS, "filter" },
154  { "f", "set filter", OFFSET(filter), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_FILTERS-1, FLAGS, "filter" },
155  { "lowpass", NULL, 0, AV_OPT_TYPE_CONST, {.i64=LOWPASS}, 0, 0, FLAGS, "filter" },
156  { "flat" , NULL, 0, AV_OPT_TYPE_CONST, {.i64=FLAT}, 0, 0, FLAGS, "filter" },
157  { "aflat" , NULL, 0, AV_OPT_TYPE_CONST, {.i64=AFLAT}, 0, 0, FLAGS, "filter" },
158  { "chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64=CHROMA}, 0, 0, FLAGS, "filter" },
159  { "color", NULL, 0, AV_OPT_TYPE_CONST, {.i64=COLOR}, 0, 0, FLAGS, "filter" },
160  { "acolor", NULL, 0, AV_OPT_TYPE_CONST, {.i64=ACOLOR}, 0, 0, FLAGS, "filter" },
161  { "xflat", NULL, 0, AV_OPT_TYPE_CONST, {.i64=XFLAT}, 0, 0, FLAGS, "filter" },
162  { "yflat", NULL, 0, AV_OPT_TYPE_CONST, {.i64=YFLAT}, 0, 0, FLAGS, "filter" },
163  { "graticule", "set graticule", OFFSET(graticule), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_GRATICULES-1, FLAGS, "graticule" },
164  { "g", "set graticule", OFFSET(graticule), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_GRATICULES-1, FLAGS, "graticule" },
165  { "none", NULL, 0, AV_OPT_TYPE_CONST, {.i64=GRAT_NONE}, 0, 0, FLAGS, "graticule" },
166  { "green", NULL, 0, AV_OPT_TYPE_CONST, {.i64=GRAT_GREEN}, 0, 0, FLAGS, "graticule" },
167  { "orange", NULL, 0, AV_OPT_TYPE_CONST, {.i64=GRAT_ORANGE}, 0, 0, FLAGS, "graticule" },
168  { "invert", NULL, 0, AV_OPT_TYPE_CONST, {.i64=GRAT_INVERT}, 0, 0, FLAGS, "graticule" },
169  { "opacity", "set graticule opacity", OFFSET(opacity), AV_OPT_TYPE_FLOAT, {.dbl=0.75}, 0, 1, FLAGS },
170  { "o", "set graticule opacity", OFFSET(opacity), AV_OPT_TYPE_FLOAT, {.dbl=0.75}, 0, 1, FLAGS },
171  { "flags", "set graticule flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64=1}, 0, 3, FLAGS, "flags" },
172  { "fl", "set graticule flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64=1}, 0, 3, FLAGS, "flags" },
173  { "numbers", "draw numbers", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "flags" },
174  { "dots", "draw dots instead of lines", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, "flags" },
175  { "scale", "set scale", OFFSET(scale), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_SCALES-1, FLAGS, "scale" },
176  { "s", "set scale", OFFSET(scale), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_SCALES-1, FLAGS, "scale" },
177  { "digital", NULL, 0, AV_OPT_TYPE_CONST, {.i64=DIGITAL}, 0, 0, FLAGS, "scale" },
178  { "millivolts", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MILLIVOLTS}, 0, 0, FLAGS, "scale" },
179  { "ire", NULL, 0, AV_OPT_TYPE_CONST, {.i64=IRE}, 0, 0, FLAGS, "scale" },
180  { "bgopacity", "set background opacity", OFFSET(bgopacity), AV_OPT_TYPE_FLOAT, {.dbl=0.75}, 0, 1, FLAGS },
181  { "b", "set background opacity", OFFSET(bgopacity), AV_OPT_TYPE_FLOAT, {.dbl=0.75}, 0, 1, FLAGS },
182  { NULL }
183 };
184 
185 AVFILTER_DEFINE_CLASS(waveform);
186 
187 static const enum AVPixelFormat in_lowpass_pix_fmts[] = {
203 };
204 
205 static const enum AVPixelFormat in_color_pix_fmts[] = {
220 };
221 
222 static const enum AVPixelFormat in_flat_pix_fmts[] = {
235 };
236 
240 };
241 
245 };
246 
250 };
251 
255 };
256 
260 };
261 
265 };
266 
270 };
271 
275 };
276 
280 };
281 
285 };
286 
290 };
291 
295 };
296 
297 static const enum AVPixelFormat flat_pix_fmts[] = {
302 };
303 
305 {
306  WaveformContext *s = ctx->priv;
307  const enum AVPixelFormat *out_pix_fmts;
308  const enum AVPixelFormat *in_pix_fmts;
309  const AVPixFmtDescriptor *desc, *desc2;
310  AVFilterFormats *avff, *avff2;
311  int depth, depth2, rgb, i, ret, ncomp, ncomp2;
312 
313  if (!ctx->inputs[0]->in_formats ||
314  !ctx->inputs[0]->in_formats->nb_formats) {
315  return AVERROR(EAGAIN);
316  }
317 
318  switch (s->filter) {
319  case LOWPASS: in_pix_fmts = in_lowpass_pix_fmts; break;
320  case CHROMA:
321  case XFLAT:
322  case YFLAT:
323  case AFLAT:
324  case FLAT: in_pix_fmts = in_flat_pix_fmts; break;
325  case ACOLOR:
326  case COLOR: in_pix_fmts = in_color_pix_fmts; break;
327  default: return AVERROR_BUG;
328  }
329 
330  if (!ctx->inputs[0]->out_formats) {
331  if ((ret = ff_formats_ref(ff_make_format_list(in_pix_fmts), &ctx->inputs[0]->out_formats)) < 0)
332  return ret;
333  }
334 
335  avff = ctx->inputs[0]->in_formats;
336  avff2 = ctx->inputs[0]->out_formats;
337  desc = av_pix_fmt_desc_get(avff->formats[0]);
338  desc2 = av_pix_fmt_desc_get(avff2->formats[0]);
339  ncomp = desc->nb_components;
340  ncomp2 = desc2->nb_components;
341  rgb = desc->flags & AV_PIX_FMT_FLAG_RGB;
342  depth = desc->comp[0].depth;
343  depth2 = desc2->comp[0].depth;
344  if (ncomp != ncomp2 || depth != depth2)
345  return AVERROR(EAGAIN);
346  for (i = 1; i < avff->nb_formats; i++) {
347  desc = av_pix_fmt_desc_get(avff->formats[i]);
348  if (rgb != (desc->flags & AV_PIX_FMT_FLAG_RGB) ||
349  depth != desc->comp[0].depth)
350  return AVERROR(EAGAIN);
351  }
352 
353  if (s->filter == LOWPASS && ncomp == 1 && depth == 8)
354  out_pix_fmts = out_gray8_lowpass_pix_fmts;
355  else if (s->filter == LOWPASS && ncomp == 1 && depth == 9)
356  out_pix_fmts = out_gray9_lowpass_pix_fmts;
357  else if (s->filter == LOWPASS && ncomp == 1 && depth == 10)
358  out_pix_fmts = out_gray10_lowpass_pix_fmts;
359  else if (s->filter == LOWPASS && ncomp == 1 && depth == 12)
360  out_pix_fmts = out_gray12_lowpass_pix_fmts;
361  else if (rgb && depth == 8 && ncomp > 2)
362  out_pix_fmts = out_rgb8_lowpass_pix_fmts;
363  else if (rgb && depth == 9 && ncomp > 2)
364  out_pix_fmts = out_rgb9_lowpass_pix_fmts;
365  else if (rgb && depth == 10 && ncomp > 2)
366  out_pix_fmts = out_rgb10_lowpass_pix_fmts;
367  else if (rgb && depth == 12 && ncomp > 2)
368  out_pix_fmts = out_rgb12_lowpass_pix_fmts;
369  else if (depth == 8 && ncomp > 2)
370  out_pix_fmts = out_yuv8_lowpass_pix_fmts;
371  else if (depth == 9 && ncomp > 2)
372  out_pix_fmts = out_yuv9_lowpass_pix_fmts;
373  else if (depth == 10 && ncomp > 2)
374  out_pix_fmts = out_yuv10_lowpass_pix_fmts;
375  else if (depth == 12 && ncomp > 2)
376  out_pix_fmts = out_yuv12_lowpass_pix_fmts;
377  else
378  return AVERROR(EAGAIN);
379  if ((ret = ff_formats_ref(ff_make_format_list(out_pix_fmts), &ctx->outputs[0]->in_formats)) < 0)
380  return ret;
381 
382  return 0;
383 }
384 
386 {
387  const int dst_linesize = out->linesize[component] / 2;
388  const int bg = s->bg_color[component] * (s->max / 256);
389  const int limit = s->max - 1;
390  const int dst_h = s->display == PARADE ? out->height / s->acomp : out->height;
391  const int dst_w = s->display == PARADE ? out->width / s->acomp : out->width;
392  const int start = s->estart[plane];
393  const int end = s->eend[plane];
394  uint16_t *dst;
395  int x, y;
396 
397  if (s->mode) {
398  for (x = offset; x < offset + dst_w; x++) {
399  for (y = start; y < end; y++) {
400  dst = (uint16_t *)out->data[component] + y * dst_linesize + x;
401  if (dst[0] != bg) {
402  dst[0] = limit;
403  break;
404  }
405  }
406  for (y = end - 1; y >= start; y--) {
407  dst = (uint16_t *)out->data[component] + y * dst_linesize + x;
408  if (dst[0] != bg) {
409  dst[0] = limit;
410  break;
411  }
412  }
413  }
414  } else {
415  for (y = offset; y < offset + dst_h; y++) {
416  dst = (uint16_t *)out->data[component] + y * dst_linesize;
417  for (x = start; x < end; x++) {
418  if (dst[x] != bg) {
419  dst[x] = limit;
420  break;
421  }
422  }
423  for (x = end - 1; x >= start; x--) {
424  if (dst[x] != bg) {
425  dst[x] = limit;
426  break;
427  }
428  }
429  }
430  }
431 }
432 
434 {
435  const int dst_linesize = out->linesize[component];
436  const uint8_t bg = s->bg_color[component];
437  const int dst_h = s->display == PARADE ? out->height / s->acomp : out->height;
438  const int dst_w = s->display == PARADE ? out->width / s->acomp : out->width;
439  const int start = s->estart[plane];
440  const int end = s->eend[plane];
441  uint8_t *dst;
442  int x, y;
443 
444  if (s->mode) {
445  for (x = offset; x < offset + dst_w; x++) {
446  for (y = start; y < end; y++) {
447  dst = out->data[component] + y * dst_linesize + x;
448  if (dst[0] != bg) {
449  dst[0] = 255;
450  break;
451  }
452  }
453  for (y = end - 1; y >= start; y--) {
454  dst = out->data[component] + y * dst_linesize + x;
455  if (dst[0] != bg) {
456  dst[0] = 255;
457  break;
458  }
459  }
460  }
461  } else {
462  for (y = offset; y < offset + dst_h; y++) {
463  dst = out->data[component] + y * dst_linesize;
464  for (x = start; x < end; x++) {
465  if (dst[x] != bg) {
466  dst[x] = 255;
467  break;
468  }
469  }
470  for (x = end - 1; x >= start; x--) {
471  if (dst[x] != bg) {
472  dst[x] = 255;
473  break;
474  }
475  }
476  }
477  }
478 }
479 
481 {
482  const int dst_linesize = out->linesize[component] / 2;
483  const int bg = s->bg_color[component] * (s->max / 256);
484  const int limit = s->max - 1;
485  const int dst_h = s->display == PARADE ? out->height / s->acomp : out->height;
486  const int dst_w = s->display == PARADE ? out->width / s->acomp : out->width;
487  const int start = s->estart[plane];
488  const int end = s->eend[plane];
489  int *emax = s->emax[plane][component];
490  int *emin = s->emin[plane][component];
491  uint16_t *dst;
492  int x, y;
493 
494  if (s->mode) {
495  for (x = offset; x < offset + dst_w; x++) {
496  for (y = start; y < end && y < emin[x - offset]; y++) {
497  dst = (uint16_t *)out->data[component] + y * dst_linesize + x;
498  if (dst[0] != bg) {
499  emin[x - offset] = y;
500  break;
501  }
502  }
503  for (y = end - 1; y >= start && y >= emax[x - offset]; y--) {
504  dst = (uint16_t *)out->data[component] + y * dst_linesize + x;
505  if (dst[0] != bg) {
506  emax[x - offset] = y;
507  break;
508  }
509  }
510  }
511 
512  if (s->envelope == 3)
513  envelope_instant16(s, out, plane, component, offset);
514 
515  for (x = offset; x < offset + dst_w; x++) {
516  dst = (uint16_t *)out->data[component] + emin[x - offset] * dst_linesize + x;
517  dst[0] = limit;
518  dst = (uint16_t *)out->data[component] + emax[x - offset] * dst_linesize + x;
519  dst[0] = limit;
520  }
521  } else {
522  for (y = offset; y < offset + dst_h; y++) {
523  dst = (uint16_t *)out->data[component] + y * dst_linesize;
524  for (x = start; x < end && x < emin[y - offset]; x++) {
525  if (dst[x] != bg) {
526  emin[y - offset] = x;
527  break;
528  }
529  }
530  for (x = end - 1; x >= start && x >= emax[y - offset]; x--) {
531  if (dst[x] != bg) {
532  emax[y - offset] = x;
533  break;
534  }
535  }
536  }
537 
538  if (s->envelope == 3)
539  envelope_instant16(s, out, plane, component, offset);
540 
541  for (y = offset; y < offset + dst_h; y++) {
542  dst = (uint16_t *)out->data[component] + y * dst_linesize + emin[y - offset];
543  dst[0] = limit;
544  dst = (uint16_t *)out->data[component] + y * dst_linesize + emax[y - offset];
545  dst[0] = limit;
546  }
547  }
548 }
549 
551 {
552  const int dst_linesize = out->linesize[component];
553  const int bg = s->bg_color[component];
554  const int dst_h = s->display == PARADE ? out->height / s->acomp : out->height;
555  const int dst_w = s->display == PARADE ? out->width / s->acomp : out->width;
556  const int start = s->estart[plane];
557  const int end = s->eend[plane];
558  int *emax = s->emax[plane][component];
559  int *emin = s->emin[plane][component];
560  uint8_t *dst;
561  int x, y;
562 
563  if (s->mode) {
564  for (x = offset; x < offset + dst_w; x++) {
565  for (y = start; y < end && y < emin[x - offset]; y++) {
566  dst = out->data[component] + y * dst_linesize + x;
567  if (dst[0] != bg) {
568  emin[x - offset] = y;
569  break;
570  }
571  }
572  for (y = end - 1; y >= start && y >= emax[x - offset]; y--) {
573  dst = out->data[component] + y * dst_linesize + x;
574  if (dst[0] != bg) {
575  emax[x - offset] = y;
576  break;
577  }
578  }
579  }
580 
581  if (s->envelope == 3)
582  envelope_instant(s, out, plane, component, offset);
583 
584  for (x = offset; x < offset + dst_w; x++) {
585  dst = out->data[component] + emin[x - offset] * dst_linesize + x;
586  dst[0] = 255;
587  dst = out->data[component] + emax[x - offset] * dst_linesize + x;
588  dst[0] = 255;
589  }
590  } else {
591  for (y = offset; y < offset + dst_h; y++) {
592  dst = out->data[component] + y * dst_linesize;
593  for (x = start; x < end && x < emin[y - offset]; x++) {
594  if (dst[x] != bg) {
595  emin[y - offset] = x;
596  break;
597  }
598  }
599  for (x = end - 1; x >= start && x >= emax[y - offset]; x--) {
600  if (dst[x] != bg) {
601  emax[y - offset] = x;
602  break;
603  }
604  }
605  }
606 
607  if (s->envelope == 3)
608  envelope_instant(s, out, plane, component, offset);
609 
610  for (y = offset; y < offset + dst_h; y++) {
611  dst = out->data[component] + y * dst_linesize + emin[y - offset];
612  dst[0] = 255;
613  dst = out->data[component] + y * dst_linesize + emax[y - offset];
614  dst[0] = 255;
615  }
616  }
617 }
618 
619 static void envelope16(WaveformContext *s, AVFrame *out, int plane, int component, int offset)
620 {
621  if (s->envelope == 0) {
622  return;
623  } else if (s->envelope == 1) {
624  envelope_instant16(s, out, plane, component, offset);
625  } else {
626  envelope_peak16(s, out, plane, component, offset);
627  }
628 }
629 
630 static void envelope(WaveformContext *s, AVFrame *out, int plane, int component, int offset)
631 {
632  if (s->envelope == 0) {
633  return;
634  } else if (s->envelope == 1) {
635  envelope_instant(s, out, plane, component, offset);
636  } else {
637  envelope_peak(s, out, plane, component, offset);
638  }
639 }
640 
641 static void update16(uint16_t *target, int max, int intensity, int limit)
642 {
643  if (*target <= max)
644  *target += intensity;
645  else
646  *target = limit;
647 }
648 
649 static void update(uint8_t *target, int max, int intensity)
650 {
651  if (*target <= max)
652  *target += intensity;
653  else
654  *target = 255;
655 }
656 
657 static void update_cr(uint8_t *target, int unused, int intensity)
658 {
659  if (*target - intensity > 0)
660  *target -= intensity;
661  else
662  *target = 0;
663 }
664 
665 static void update16_cr(uint16_t *target, int unused, int intensity, int limit)
666 {
667  if (*target - intensity > 0)
668  *target -= intensity;
669  else
670  *target = 0;
671 }
672 
674  AVFrame *in, AVFrame *out,
675  int component, int intensity,
676  int offset_y, int offset_x,
677  int column, int mirror,
678  int jobnr, int nb_jobs)
679 {
680  const int plane = s->desc->comp[component].plane;
681  const int shift_w = s->shift_w[component];
682  const int shift_h = s->shift_h[component];
683  const int src_linesize = in->linesize[plane] / 2;
684  const int dst_linesize = out->linesize[plane] / 2;
685  const int dst_signed_linesize = dst_linesize * (mirror == 1 ? -1 : 1);
686  const int limit = s->max - 1;
687  const int max = limit - intensity;
688  const int src_h = AV_CEIL_RSHIFT(in->height, shift_h);
689  const int src_w = AV_CEIL_RSHIFT(in->width, shift_w);
690  const int sliceh_start = !column ? (src_h * jobnr) / nb_jobs : 0;
691  const int sliceh_end = !column ? (src_h * (jobnr+1)) / nb_jobs : src_h;
692  const int slicew_start = column ? (src_w * jobnr) / nb_jobs : 0;
693  const int slicew_end = column ? (src_w * (jobnr+1)) / nb_jobs : src_w;
694  const int step = column ? 1 << shift_w : 1 << shift_h;
695  const uint16_t *src_data = (const uint16_t *)in->data[plane] + sliceh_start * src_linesize;
696  uint16_t *dst_data = (uint16_t *)out->data[plane] + (offset_y + sliceh_start * step) * dst_linesize + offset_x;
697  uint16_t * const dst_bottom_line = dst_data + dst_linesize * (s->size - 1);
698  uint16_t * const dst_line = (mirror ? dst_bottom_line : dst_data);
699  const uint16_t *p;
700  int y;
701 
702  if (!column && mirror)
703  dst_data += s->size;
704 
705  for (y = sliceh_start; y < sliceh_end; y++) {
706  const uint16_t *src_data_end = src_data + slicew_end;
707  uint16_t *dst = dst_line + slicew_start * step;
708 
709  for (p = src_data + slicew_start; p < src_data_end; p++) {
710  uint16_t *target;
711  int i = 0, v = FFMIN(*p, limit);
712 
713  if (column) {
714  do {
715  target = dst++ + dst_signed_linesize * v;
716  update16(target, max, intensity, limit);
717  } while (++i < step);
718  } else {
719  uint16_t *row = dst_data;
720  do {
721  if (mirror)
722  target = row - v - 1;
723  else
724  target = row + v;
725  update16(target, max, intensity, limit);
726  row += dst_linesize;
727  } while (++i < step);
728  }
729  }
730  src_data += src_linesize;
731  dst_data += dst_linesize * step;
732  }
733 }
734 
735 #define LOWPASS16_FUNC(name, column, mirror) \
736 static int lowpass16_##name(AVFilterContext *ctx, \
737  void *arg, int jobnr, \
738  int nb_jobs) \
739 { \
740  WaveformContext *s = ctx->priv; \
741  ThreadData *td = arg; \
742  AVFrame *in = td->in; \
743  AVFrame *out = td->out; \
744  int component = td->component; \
745  int offset_y = td->offset_y; \
746  int offset_x = td->offset_x; \
747  \
748  lowpass16(s, in, out, component, s->intensity, \
749  offset_y, offset_x, column, mirror, \
750  jobnr, nb_jobs); \
751  \
752  return 0; \
753 }
754 
755 LOWPASS16_FUNC(column_mirror, 1, 1)
756 LOWPASS16_FUNC(column, 1, 0)
757 LOWPASS16_FUNC(row_mirror, 0, 1)
758 LOWPASS16_FUNC(row, 0, 0)
759 
761  AVFrame *in, AVFrame *out,
762  int component, int intensity,
763  int offset_y, int offset_x,
764  int column, int mirror,
765  int jobnr, int nb_jobs)
766 {
767  const int plane = s->desc->comp[component].plane;
768  const int shift_w = s->shift_w[component];
769  const int shift_h = s->shift_h[component];
770  const int src_linesize = in->linesize[plane];
771  const int dst_linesize = out->linesize[plane];
772  const int dst_signed_linesize = dst_linesize * (mirror == 1 ? -1 : 1);
773  const int max = 255 - intensity;
774  const int src_h = AV_CEIL_RSHIFT(in->height, shift_h);
775  const int src_w = AV_CEIL_RSHIFT(in->width, shift_w);
776  const int sliceh_start = !column ? (src_h * jobnr) / nb_jobs : 0;
777  const int sliceh_end = !column ? (src_h * (jobnr+1)) / nb_jobs : src_h;
778  const int slicew_start = column ? (src_w * jobnr) / nb_jobs : 0;
779  const int slicew_end = column ? (src_w * (jobnr+1)) / nb_jobs : src_w;
780  const int step = column ? 1 << shift_w : 1 << shift_h;
781  const uint8_t *src_data = in->data[plane] + sliceh_start * src_linesize;
782  uint8_t *dst_data = out->data[plane] + (offset_y + sliceh_start * step) * dst_linesize + offset_x;
783  uint8_t * const dst_bottom_line = dst_data + dst_linesize * (s->size - 1);
784  uint8_t * const dst_line = (mirror ? dst_bottom_line : dst_data);
785  const uint8_t *p;
786  int y;
787 
788  if (!column && mirror)
789  dst_data += s->size;
790 
791  for (y = sliceh_start; y < sliceh_end; y++) {
792  const uint8_t *src_data_end = src_data + slicew_end;
793  uint8_t *dst = dst_line + slicew_start * step;
794 
795  for (p = src_data + slicew_start; p < src_data_end; p++) {
796  uint8_t *target;
797  if (column) {
798  target = dst + dst_signed_linesize * *p;
799  dst += step;
800  update(target, max, intensity);
801  } else {
802  uint8_t *row = dst_data;
803  if (mirror)
804  target = row - *p - 1;
805  else
806  target = row + *p;
807  update(target, max, intensity);
808  row += dst_linesize;
809  }
810  }
811  src_data += src_linesize;
812  dst_data += dst_linesize * step;
813  }
814 
815  if (column && step > 1) {
816  const int dst_h = 256;
817  uint8_t *dst;
818  int x, z;
819 
820  dst = out->data[plane] + offset_y * dst_linesize + offset_x;
821  for (y = 0; y < dst_h; y++) {
822  for (x = slicew_start * step; x < slicew_end * step; x+=step) {
823  for (z = 1; z < step; z++) {
824  dst[x + z] = dst[x];
825  }
826  }
827  dst += dst_linesize;
828  }
829  } else if (step > 1) {
830  const int dst_w = 256;
831  uint8_t *dst;
832  int z;
833 
834  dst = out->data[plane] + (offset_y + sliceh_start * step) * dst_linesize + offset_x;
835  for (y = sliceh_start * step; y < sliceh_end * step; y+=step) {
836  for (z = 1; z < step; z++)
837  memcpy(dst + dst_linesize * z, dst, dst_w);
838  dst += dst_linesize * step;
839  }
840  }
841 }
842 
843 #define LOWPASS_FUNC(name, column, mirror) \
844 static int lowpass_##name(AVFilterContext *ctx, \
845  void *arg, int jobnr, \
846  int nb_jobs) \
847 { \
848  WaveformContext *s = ctx->priv; \
849  ThreadData *td = arg; \
850  AVFrame *in = td->in; \
851  AVFrame *out = td->out; \
852  int component = td->component; \
853  int offset_y = td->offset_y; \
854  int offset_x = td->offset_x; \
855  \
856  lowpass(s, in, out, component, s->intensity, \
857  offset_y, offset_x, column, mirror, \
858  jobnr, nb_jobs); \
859  \
860  return 0; \
861 }
862 
863 LOWPASS_FUNC(column_mirror, 1, 1)
864 LOWPASS_FUNC(column, 1, 0)
865 LOWPASS_FUNC(row_mirror, 0, 1)
866 LOWPASS_FUNC(row, 0, 0)
867 
869  AVFrame *in, AVFrame *out,
870  int component, int intensity,
871  int offset_y, int offset_x,
872  int column, int mirror,
873  int jobnr, int nb_jobs)
874 {
875  const int plane = s->desc->comp[component].plane;
876  const int c0_linesize = in->linesize[ plane + 0 ] / 2;
877  const int c1_linesize = in->linesize[(plane + 1) % s->ncomp] / 2;
878  const int c2_linesize = in->linesize[(plane + 2) % s->ncomp] / 2;
879  const int c0_shift_w = s->shift_w[ component + 0 ];
880  const int c1_shift_w = s->shift_w[(component + 1) % s->ncomp];
881  const int c2_shift_w = s->shift_w[(component + 2) % s->ncomp];
882  const int c0_shift_h = s->shift_h[ component + 0 ];
883  const int c1_shift_h = s->shift_h[(component + 1) % s->ncomp];
884  const int c2_shift_h = s->shift_h[(component + 2) % s->ncomp];
885  const int d0_linesize = out->linesize[ plane + 0 ] / 2;
886  const int d1_linesize = out->linesize[(plane + 1) % s->ncomp] / 2;
887  const int limit = s->max - 1;
888  const int max = limit - intensity;
889  const int mid = s->max / 2;
890  const int src_h = in->height;
891  const int src_w = in->width;
892  const int sliceh_start = !column ? (src_h * jobnr) / nb_jobs : 0;
893  const int sliceh_end = !column ? (src_h * (jobnr+1)) / nb_jobs : src_h;
894  const int slicew_start = column ? (src_w * jobnr) / nb_jobs : 0;
895  const int slicew_end = column ? (src_w * (jobnr+1)) / nb_jobs : src_w;
896  int x, y;
897 
898  if (column) {
899  const int d0_signed_linesize = d0_linesize * (mirror == 1 ? -1 : 1);
900  const int d1_signed_linesize = d1_linesize * (mirror == 1 ? -1 : 1);
901 
902  for (x = slicew_start; x < slicew_end; x++) {
903  const uint16_t *c0_data = (uint16_t *)in->data[plane + 0];
904  const uint16_t *c1_data = (uint16_t *)in->data[(plane + 1) % s->ncomp];
905  const uint16_t *c2_data = (uint16_t *)in->data[(plane + 2) % s->ncomp];
906  uint16_t *d0_data = (uint16_t *)(out->data[plane]) + offset_y * d0_linesize + offset_x;
907  uint16_t *d1_data = (uint16_t *)(out->data[(plane + 1) % s->ncomp]) + offset_y * d1_linesize + offset_x;
908  uint16_t * const d0_bottom_line = d0_data + d0_linesize * (s->size - 1);
909  uint16_t * const d0 = (mirror ? d0_bottom_line : d0_data);
910  uint16_t * const d1_bottom_line = d1_data + d1_linesize * (s->size - 1);
911  uint16_t * const d1 = (mirror ? d1_bottom_line : d1_data);
912 
913  for (y = 0; y < src_h; y++) {
914  const int c0 = FFMIN(c0_data[x >> c0_shift_w], limit) + s->max;
915  const int c1 = FFMIN(FFABS(c1_data[x >> c1_shift_w] - mid) + FFABS(c2_data[x >> c2_shift_w] - mid), limit);
916  uint16_t *target;
917 
918  target = d0 + x + d0_signed_linesize * c0;
919  update16(target, max, intensity, limit);
920  target = d1 + x + d1_signed_linesize * (c0 - c1);
921  update16(target, max, intensity, limit);
922  target = d1 + x + d1_signed_linesize * (c0 + c1);
923  update16(target, max, intensity, limit);
924 
925  if (!c0_shift_h || (y & c0_shift_h))
926  c0_data += c0_linesize;
927  if (!c1_shift_h || (y & c1_shift_h))
928  c1_data += c1_linesize;
929  if (!c2_shift_h || (y & c2_shift_h))
930  c2_data += c2_linesize;
931  d0_data += d0_linesize;
932  d1_data += d1_linesize;
933  }
934  }
935  } else {
936  const uint16_t *c0_data = (uint16_t *)(in->data[plane]) + (sliceh_start >> c0_shift_h) * c0_linesize;
937  const uint16_t *c1_data = (uint16_t *)(in->data[(plane + 1) % s->ncomp]) + (sliceh_start >> c1_shift_h) * c1_linesize;
938  const uint16_t *c2_data = (uint16_t *)(in->data[(plane + 2) % s->ncomp]) + (sliceh_start >> c2_shift_h) * c2_linesize;
939  uint16_t *d0_data = (uint16_t *)(out->data[plane]) + (offset_y + sliceh_start) * d0_linesize + offset_x;
940  uint16_t *d1_data = (uint16_t *)(out->data[(plane + 1) % s->ncomp]) + (offset_y + sliceh_start) * d1_linesize + offset_x;
941 
942  if (mirror) {
943  d0_data += s->size - 1;
944  d1_data += s->size - 1;
945  }
946 
947  for (y = sliceh_start; y < sliceh_end; y++) {
948  for (x = 0; x < src_w; x++) {
949  const int c0 = FFMIN(c0_data[x >> c0_shift_w], limit) + s->max;
950  const int c1 = FFMIN(FFABS(c1_data[x >> c1_shift_w] - mid) + FFABS(c2_data[x >> c2_shift_w] - mid), limit);
951  uint16_t *target;
952 
953  if (mirror) {
954  target = d0_data - c0;
955  update16(target, max, intensity, limit);
956  target = d1_data - (c0 - c1);
957  update16(target, max, intensity, limit);
958  target = d1_data - (c0 + c1);
959  update16(target, max, intensity, limit);
960  } else {
961  target = d0_data + c0;
962  update16(target, max, intensity, limit);
963  target = d1_data + (c0 - c1);
964  update16(target, max, intensity, limit);
965  target = d1_data + (c0 + c1);
966  update16(target, max, intensity, limit);
967  }
968  }
969 
970  if (!c0_shift_h || (y & c0_shift_h))
971  c0_data += c0_linesize;
972  if (!c1_shift_h || (y & c1_shift_h))
973  c1_data += c1_linesize;
974  if (!c2_shift_h || (y & c2_shift_h))
975  c2_data += c2_linesize;
976  d0_data += d0_linesize;
977  d1_data += d1_linesize;
978  }
979  }
980 }
981 
982 #define FLAT16_FUNC(name, column, mirror) \
983 static int flat16_##name(AVFilterContext *ctx, \
984  void *arg, int jobnr, \
985  int nb_jobs) \
986 { \
987  WaveformContext *s = ctx->priv; \
988  ThreadData *td = arg; \
989  AVFrame *in = td->in; \
990  AVFrame *out = td->out; \
991  int component = td->component; \
992  int offset_y = td->offset_y; \
993  int offset_x = td->offset_x; \
994  \
995  flat16(s, in, out, component, s->intensity, \
996  offset_y, offset_x, column, mirror, \
997  jobnr, nb_jobs); \
998  \
999  return 0; \
1000 }
1001 
1002 FLAT16_FUNC(column_mirror, 1, 1)
1003 FLAT16_FUNC(column, 1, 0)
1004 FLAT16_FUNC(row_mirror, 0, 1)
1005 FLAT16_FUNC(row, 0, 0)
1006 
1008  AVFrame *in, AVFrame *out,
1009  int component, int intensity,
1010  int offset_y, int offset_x,
1011  int column, int mirror,
1012  int jobnr, int nb_jobs)
1013 {
1014  const int plane = s->desc->comp[component].plane;
1015  const int c0_linesize = in->linesize[ plane + 0 ];
1016  const int c1_linesize = in->linesize[(plane + 1) % s->ncomp];
1017  const int c2_linesize = in->linesize[(plane + 2) % s->ncomp];
1018  const int c0_shift_w = s->shift_w[ component + 0 ];
1019  const int c1_shift_w = s->shift_w[(component + 1) % s->ncomp];
1020  const int c2_shift_w = s->shift_w[(component + 2) % s->ncomp];
1021  const int c0_shift_h = s->shift_h[ component + 0 ];
1022  const int c1_shift_h = s->shift_h[(component + 1) % s->ncomp];
1023  const int c2_shift_h = s->shift_h[(component + 2) % s->ncomp];
1024  const int d0_linesize = out->linesize[ plane + 0 ];
1025  const int d1_linesize = out->linesize[(plane + 1) % s->ncomp];
1026  const int max = 255 - intensity;
1027  const int src_h = in->height;
1028  const int src_w = in->width;
1029  const int sliceh_start = !column ? (src_h * jobnr) / nb_jobs : 0;
1030  const int sliceh_end = !column ? (src_h * (jobnr+1)) / nb_jobs : src_h;
1031  const int slicew_start = column ? (src_w * jobnr) / nb_jobs : 0;
1032  const int slicew_end = column ? (src_w * (jobnr+1)) / nb_jobs : src_w;
1033  int x, y;
1034 
1035  if (column) {
1036  const int d0_signed_linesize = d0_linesize * (mirror == 1 ? -1 : 1);
1037  const int d1_signed_linesize = d1_linesize * (mirror == 1 ? -1 : 1);
1038 
1039  for (x = slicew_start; x < slicew_end; x++) {
1040  const uint8_t *c0_data = in->data[plane + 0];
1041  const uint8_t *c1_data = in->data[(plane + 1) % s->ncomp];
1042  const uint8_t *c2_data = in->data[(plane + 2) % s->ncomp];
1043  uint8_t *d0_data = out->data[plane] + offset_y * d0_linesize + offset_x;
1044  uint8_t *d1_data = out->data[(plane + 1) % s->ncomp] + offset_y * d1_linesize + offset_x;
1045  uint8_t * const d0_bottom_line = d0_data + d0_linesize * (s->size - 1);
1046  uint8_t * const d0 = (mirror ? d0_bottom_line : d0_data);
1047  uint8_t * const d1_bottom_line = d1_data + d1_linesize * (s->size - 1);
1048  uint8_t * const d1 = (mirror ? d1_bottom_line : d1_data);
1049 
1050  for (y = 0; y < src_h; y++) {
1051  const int c0 = c0_data[x >> c0_shift_w] + 256;
1052  const int c1 = FFABS(c1_data[x >> c1_shift_w] - 128) + FFABS(c2_data[x >> c2_shift_w] - 128);
1053  uint8_t *target;
1054 
1055  target = d0 + x + d0_signed_linesize * c0;
1056  update(target, max, intensity);
1057  target = d1 + x + d1_signed_linesize * (c0 - c1);
1058  update(target, max, intensity);
1059  target = d1 + x + d1_signed_linesize * (c0 + c1);
1060  update(target, max, intensity);
1061 
1062  if (!c0_shift_h || (y & c0_shift_h))
1063  c0_data += c0_linesize;
1064  if (!c1_shift_h || (y & c1_shift_h))
1065  c1_data += c1_linesize;
1066  if (!c2_shift_h || (y & c2_shift_h))
1067  c2_data += c2_linesize;
1068  d0_data += d0_linesize;
1069  d1_data += d1_linesize;
1070  }
1071  }
1072  } else {
1073  const uint8_t *c0_data = in->data[plane] + (sliceh_start >> c0_shift_h) * c0_linesize;
1074  const uint8_t *c1_data = in->data[(plane + 1) % s->ncomp] + (sliceh_start >> c1_shift_h) * c1_linesize;
1075  const uint8_t *c2_data = in->data[(plane + 2) % s->ncomp] + (sliceh_start >> c2_shift_h) * c2_linesize;
1076  uint8_t *d0_data = out->data[plane] + (offset_y + sliceh_start) * d0_linesize + offset_x;
1077  uint8_t *d1_data = out->data[(plane + 1) % s->ncomp] + (offset_y + sliceh_start) * d1_linesize + offset_x;
1078 
1079  if (mirror) {
1080  d0_data += s->size - 1;
1081  d1_data += s->size - 1;
1082  }
1083 
1084  for (y = sliceh_start; y < sliceh_end; y++) {
1085  for (x = 0; x < src_w; x++) {
1086  const int c0 = c0_data[x >> c0_shift_w] + 256;
1087  const int c1 = FFABS(c1_data[x >> c1_shift_w] - 128) + FFABS(c2_data[x >> c2_shift_w] - 128);
1088  uint8_t *target;
1089 
1090  if (mirror) {
1091  target = d0_data - c0;
1092  update(target, max, intensity);
1093  target = d1_data - (c0 - c1);
1094  update(target, max, intensity);
1095  target = d1_data - (c0 + c1);
1096  update(target, max, intensity);
1097  } else {
1098  target = d0_data + c0;
1099  update(target, max, intensity);
1100  target = d1_data + (c0 - c1);
1101  update(target, max, intensity);
1102  target = d1_data + (c0 + c1);
1103  update(target, max, intensity);
1104  }
1105  }
1106 
1107  if (!c0_shift_h || (y & c0_shift_h))
1108  c0_data += c0_linesize;
1109  if (!c1_shift_h || (y & c1_shift_h))
1110  c1_data += c1_linesize;
1111  if (!c2_shift_h || (y & c2_shift_h))
1112  c2_data += c2_linesize;
1113  d0_data += d0_linesize;
1114  d1_data += d1_linesize;
1115  }
1116  }
1117 }
1118 
1119 #define FLAT_FUNC(name, column, mirror) \
1120 static int flat_##name(AVFilterContext *ctx, \
1121  void *arg, int jobnr, \
1122  int nb_jobs) \
1123 { \
1124  WaveformContext *s = ctx->priv; \
1125  ThreadData *td = arg; \
1126  AVFrame *in = td->in; \
1127  AVFrame *out = td->out; \
1128  int component = td->component; \
1129  int offset_y = td->offset_y; \
1130  int offset_x = td->offset_x; \
1131  \
1132  flat(s, in, out, component, s->intensity, \
1133  offset_y, offset_x, column, mirror, \
1134  jobnr, nb_jobs); \
1135  \
1136  return 0; \
1137 }
1138 
1139 FLAT_FUNC(column_mirror, 1, 1)
1140 FLAT_FUNC(column, 1, 0)
1141 FLAT_FUNC(row_mirror, 0, 1)
1142 FLAT_FUNC(row, 0, 0)
1143 
1144 #define AFLAT16(name, update_cb, update_cr, column, mirror) \
1145 static int name(AVFilterContext *ctx, \
1146  void *arg, int jobnr, \
1147  int nb_jobs) \
1148 { \
1149  WaveformContext *s = ctx->priv; \
1150  ThreadData *td = arg; \
1151  AVFrame *in = td->in; \
1152  AVFrame *out = td->out; \
1153  int component = td->component; \
1154  int offset_y = td->offset_y; \
1155  int offset_x = td->offset_x; \
1156  const int intensity = s->intensity; \
1157  const int plane = s->desc->comp[component].plane; \
1158  const int c0_linesize = in->linesize[ plane + 0 ] / 2; \
1159  const int c1_linesize = in->linesize[(plane + 1) % s->ncomp] / 2; \
1160  const int c2_linesize = in->linesize[(plane + 2) % s->ncomp] / 2; \
1161  const int c0_shift_w = s->shift_w[ component + 0 ]; \
1162  const int c1_shift_w = s->shift_w[(component + 1) % s->ncomp]; \
1163  const int c2_shift_w = s->shift_w[(component + 2) % s->ncomp]; \
1164  const int c0_shift_h = s->shift_h[ component + 0 ]; \
1165  const int c1_shift_h = s->shift_h[(component + 1) % s->ncomp]; \
1166  const int c2_shift_h = s->shift_h[(component + 2) % s->ncomp]; \
1167  const int d0_linesize = out->linesize[ plane + 0 ] / 2; \
1168  const int d1_linesize = out->linesize[(plane + 1) % s->ncomp] / 2; \
1169  const int d2_linesize = out->linesize[(plane + 2) % s->ncomp] / 2; \
1170  const int limit = s->max - 1; \
1171  const int max = limit - intensity; \
1172  const int mid = s->max / 2; \
1173  const int src_h = in->height; \
1174  const int src_w = in->width; \
1175  const int sliceh_start = !column ? (src_h * jobnr) / nb_jobs : 0; \
1176  const int sliceh_end = !column ? (src_h * (jobnr+1)) / nb_jobs : src_h; \
1177  const int slicew_start = column ? (src_w * jobnr) / nb_jobs : 0; \
1178  const int slicew_end = column ? (src_w * (jobnr+1)) / nb_jobs : src_w; \
1179  int x, y; \
1180  \
1181  if (column) { \
1182  const int d0_signed_linesize = d0_linesize * (mirror == 1 ? -1 : 1); \
1183  const int d1_signed_linesize = d1_linesize * (mirror == 1 ? -1 : 1); \
1184  const int d2_signed_linesize = d2_linesize * (mirror == 1 ? -1 : 1); \
1185  \
1186  for (x = slicew_start; x < slicew_end; x++) { \
1187  const uint16_t *c0_data = (uint16_t *)in->data[plane + 0]; \
1188  const uint16_t *c1_data = (uint16_t *)in->data[(plane + 1) % s->ncomp]; \
1189  const uint16_t *c2_data = (uint16_t *)in->data[(plane + 2) % s->ncomp]; \
1190  uint16_t *d0_data = (uint16_t *)out->data[plane] + offset_y * d0_linesize + offset_x; \
1191  uint16_t *d1_data = (uint16_t *)out->data[(plane + 1) % s->ncomp] + offset_y * d1_linesize + offset_x; \
1192  uint16_t *d2_data = (uint16_t *)out->data[(plane + 2) % s->ncomp] + offset_y * d2_linesize + offset_x; \
1193  uint16_t * const d0_bottom_line = d0_data + d0_linesize * (s->size - 1); \
1194  uint16_t * const d0 = (mirror ? d0_bottom_line : d0_data); \
1195  uint16_t * const d1_bottom_line = d1_data + d1_linesize * (s->size - 1); \
1196  uint16_t * const d1 = (mirror ? d1_bottom_line : d1_data); \
1197  uint16_t * const d2_bottom_line = d2_data + d2_linesize * (s->size - 1); \
1198  uint16_t * const d2 = (mirror ? d2_bottom_line : d2_data); \
1199  \
1200  for (y = 0; y < src_h; y++) { \
1201  const int c0 = FFMIN(c0_data[x >> c0_shift_w], limit) + mid; \
1202  const int c1 = FFMIN(c1_data[x >> c1_shift_w], limit) - mid; \
1203  const int c2 = FFMIN(c2_data[x >> c2_shift_w], limit) - mid; \
1204  uint16_t *target; \
1205  \
1206  target = d0 + x + d0_signed_linesize * c0; \
1207  update16(target, max, intensity, limit); \
1208  \
1209  target = d1 + x + d1_signed_linesize * (c0 + c1); \
1210  update_cb(target, max, intensity, limit); \
1211  \
1212  target = d2 + x + d2_signed_linesize * (c0 + c2); \
1213  update_cr(target, max, intensity, limit); \
1214  \
1215  if (!c0_shift_h || (y & c0_shift_h)) \
1216  c0_data += c0_linesize; \
1217  if (!c1_shift_h || (y & c1_shift_h)) \
1218  c1_data += c1_linesize; \
1219  if (!c2_shift_h || (y & c2_shift_h)) \
1220  c2_data += c2_linesize; \
1221  d0_data += d0_linesize; \
1222  d1_data += d1_linesize; \
1223  d2_data += d2_linesize; \
1224  } \
1225  } \
1226  } else { \
1227  const uint16_t *c0_data = (uint16_t *)in->data[plane] + (sliceh_start >> c0_shift_h) * c0_linesize; \
1228  const uint16_t *c1_data = (uint16_t *)in->data[(plane + 1) % s->ncomp] + (sliceh_start >> c1_shift_h) * c1_linesize; \
1229  const uint16_t *c2_data = (uint16_t *)in->data[(plane + 2) % s->ncomp] + (sliceh_start >> c2_shift_h) * c2_linesize; \
1230  uint16_t *d0_data = (uint16_t *)out->data[plane] + (offset_y + sliceh_start) * d0_linesize + offset_x; \
1231  uint16_t *d1_data = (uint16_t *)out->data[(plane + 1) % s->ncomp] + (offset_y + sliceh_start) * d1_linesize + offset_x; \
1232  uint16_t *d2_data = (uint16_t *)out->data[(plane + 2) % s->ncomp] + (offset_y + sliceh_start) * d2_linesize + offset_x; \
1233  \
1234  if (mirror) { \
1235  d0_data += s->size - 1; \
1236  d1_data += s->size - 1; \
1237  d2_data += s->size - 1; \
1238  } \
1239  \
1240  for (y = sliceh_start; y < sliceh_end; y++) { \
1241  for (x = 0; x < src_w; x++) { \
1242  const int c0 = FFMIN(c0_data[x >> c0_shift_w], limit) + mid; \
1243  const int c1 = FFMIN(c1_data[x >> c1_shift_w], limit) - mid; \
1244  const int c2 = FFMIN(c2_data[x >> c2_shift_w], limit) - mid; \
1245  uint16_t *target; \
1246  \
1247  if (mirror) { \
1248  target = d0_data - c0; \
1249  update16(target, max, intensity, limit); \
1250  target = d1_data - (c0 + c1); \
1251  update_cb(target, max, intensity, limit); \
1252  target = d2_data - (c0 + c2); \
1253  update_cr(target, max, intensity, limit); \
1254  } else { \
1255  target = d0_data + c0; \
1256  update16(target, max, intensity, limit); \
1257  target = d1_data + (c0 + c1); \
1258  update_cb(target, max, intensity, limit); \
1259  target = d2_data + (c0 + c2); \
1260  update_cr(target, max, intensity, limit); \
1261  } \
1262  } \
1263  \
1264  if (!c0_shift_h || (y & c0_shift_h)) \
1265  c0_data += c0_linesize; \
1266  if (!c1_shift_h || (y & c1_shift_h)) \
1267  c1_data += c1_linesize; \
1268  if (!c2_shift_h || (y & c2_shift_h)) \
1269  c2_data += c2_linesize; \
1270  d0_data += d0_linesize; \
1271  d1_data += d1_linesize; \
1272  d2_data += d2_linesize; \
1273  } \
1274  } \
1275  return 0; \
1276 }
1277 
1278 #define AFLAT(name, update_cb, update_cr, column, mirror) \
1279 static int name(AVFilterContext *ctx, \
1280  void *arg, int jobnr, \
1281  int nb_jobs) \
1282 { \
1283  WaveformContext *s = ctx->priv; \
1284  ThreadData *td = arg; \
1285  AVFrame *in = td->in; \
1286  AVFrame *out = td->out; \
1287  int component = td->component; \
1288  int offset_y = td->offset_y; \
1289  int offset_x = td->offset_x; \
1290  const int src_h = in->height; \
1291  const int src_w = in->width; \
1292  const int sliceh_start = !column ? (src_h * jobnr) / nb_jobs : 0; \
1293  const int sliceh_end = !column ? (src_h * (jobnr+1)) / nb_jobs : src_h; \
1294  const int slicew_start = column ? (src_w * jobnr) / nb_jobs : 0; \
1295  const int slicew_end = column ? (src_w * (jobnr+1)) / nb_jobs : src_w; \
1296  const int intensity = s->intensity; \
1297  const int plane = s->desc->comp[component].plane; \
1298  const int c0_linesize = in->linesize[ plane + 0 ]; \
1299  const int c1_linesize = in->linesize[(plane + 1) % s->ncomp]; \
1300  const int c2_linesize = in->linesize[(plane + 2) % s->ncomp]; \
1301  const int c0_shift_w = s->shift_w[ component + 0 ]; \
1302  const int c1_shift_w = s->shift_w[(component + 1) % s->ncomp]; \
1303  const int c2_shift_w = s->shift_w[(component + 2) % s->ncomp]; \
1304  const int c0_shift_h = s->shift_h[ component + 0 ]; \
1305  const int c1_shift_h = s->shift_h[(component + 1) % s->ncomp]; \
1306  const int c2_shift_h = s->shift_h[(component + 2) % s->ncomp]; \
1307  const int d0_linesize = out->linesize[ plane + 0 ]; \
1308  const int d1_linesize = out->linesize[(plane + 1) % s->ncomp]; \
1309  const int d2_linesize = out->linesize[(plane + 2) % s->ncomp]; \
1310  const int max = 255 - intensity; \
1311  int x, y; \
1312  \
1313  if (column) { \
1314  const int d0_signed_linesize = d0_linesize * (mirror == 1 ? -1 : 1); \
1315  const int d1_signed_linesize = d1_linesize * (mirror == 1 ? -1 : 1); \
1316  const int d2_signed_linesize = d2_linesize * (mirror == 1 ? -1 : 1); \
1317  \
1318  for (x = slicew_start; x < slicew_end; x++) { \
1319  const uint8_t *c0_data = in->data[plane + 0]; \
1320  const uint8_t *c1_data = in->data[(plane + 1) % s->ncomp]; \
1321  const uint8_t *c2_data = in->data[(plane + 2) % s->ncomp]; \
1322  uint8_t *d0_data = out->data[plane] + offset_y * d0_linesize + offset_x; \
1323  uint8_t *d1_data = out->data[(plane + 1) % s->ncomp] + offset_y * d1_linesize + offset_x; \
1324  uint8_t *d2_data = out->data[(plane + 2) % s->ncomp] + offset_y * d2_linesize + offset_x; \
1325  uint8_t * const d0_bottom_line = d0_data + d0_linesize * (s->size - 1); \
1326  uint8_t * const d0 = (mirror ? d0_bottom_line : d0_data); \
1327  uint8_t * const d1_bottom_line = d1_data + d1_linesize * (s->size - 1); \
1328  uint8_t * const d1 = (mirror ? d1_bottom_line : d1_data); \
1329  uint8_t * const d2_bottom_line = d2_data + d2_linesize * (s->size - 1); \
1330  uint8_t * const d2 = (mirror ? d2_bottom_line : d2_data); \
1331  \
1332  for (y = 0; y < src_h; y++) { \
1333  const int c0 = c0_data[x >> c0_shift_w] + 128; \
1334  const int c1 = c1_data[x >> c1_shift_w] - 128; \
1335  const int c2 = c2_data[x >> c2_shift_w] - 128; \
1336  uint8_t *target; \
1337  \
1338  target = d0 + x + d0_signed_linesize * c0; \
1339  update(target, max, intensity); \
1340  \
1341  target = d1 + x + d1_signed_linesize * (c0 + c1); \
1342  update_cb(target, max, intensity); \
1343  \
1344  target = d2 + x + d2_signed_linesize * (c0 + c2); \
1345  update_cr(target, max, intensity); \
1346  \
1347  if (!c0_shift_h || (y & c0_shift_h)) \
1348  c0_data += c0_linesize; \
1349  if (!c1_shift_h || (y & c1_shift_h)) \
1350  c1_data += c1_linesize; \
1351  if (!c2_shift_h || (y & c2_shift_h)) \
1352  c2_data += c2_linesize; \
1353  d0_data += d0_linesize; \
1354  d1_data += d1_linesize; \
1355  d2_data += d2_linesize; \
1356  } \
1357  } \
1358  } else { \
1359  const uint8_t *c0_data = in->data[plane] + (sliceh_start >> c0_shift_h) * c0_linesize; \
1360  const uint8_t *c1_data = in->data[(plane + 1) % s->ncomp] + (sliceh_start >> c1_shift_h) * c1_linesize; \
1361  const uint8_t *c2_data = in->data[(plane + 2) % s->ncomp] + (sliceh_start >> c2_shift_h) * c2_linesize; \
1362  uint8_t *d0_data = out->data[plane] + (offset_y + sliceh_start) * d0_linesize + offset_x; \
1363  uint8_t *d1_data = out->data[(plane + 1) % s->ncomp] + (offset_y + sliceh_start) * d1_linesize + offset_x; \
1364  uint8_t *d2_data = out->data[(plane + 2) % s->ncomp] + (offset_y + sliceh_start) * d2_linesize + offset_x; \
1365  \
1366  if (mirror) { \
1367  d0_data += s->size - 1; \
1368  d1_data += s->size - 1; \
1369  d2_data += s->size - 1; \
1370  } \
1371  \
1372  for (y = sliceh_start; y < sliceh_end; y++) { \
1373  for (x = 0; x < src_w; x++) { \
1374  const int c0 = c0_data[x >> c0_shift_w] + 128; \
1375  const int c1 = c1_data[x >> c1_shift_w] - 128; \
1376  const int c2 = c2_data[x >> c2_shift_w] - 128; \
1377  uint8_t *target; \
1378  \
1379  if (mirror) { \
1380  target = d0_data - c0; \
1381  update(target, max, intensity); \
1382  target = d1_data - (c0 + c1); \
1383  update_cb(target, max, intensity); \
1384  target = d2_data - (c0 + c2); \
1385  update_cr(target, max, intensity); \
1386  } else { \
1387  target = d0_data + c0; \
1388  update(target, max, intensity); \
1389  target = d1_data + (c0 + c1); \
1390  update_cb(target, max, intensity); \
1391  target = d2_data + (c0 + c2); \
1392  update_cr(target, max, intensity); \
1393  } \
1394  } \
1395  \
1396  if (!c0_shift_h || (y & c0_shift_h)) \
1397  c0_data += c0_linesize; \
1398  if (!c1_shift_h || (y & c1_shift_h)) \
1399  c1_data += c1_linesize; \
1400  if (!c2_shift_h || (y & c2_shift_h)) \
1401  c2_data += c2_linesize; \
1402  d0_data += d0_linesize; \
1403  d1_data += d1_linesize; \
1404  d2_data += d2_linesize; \
1405  } \
1406  } \
1407  return 0; \
1408 }
1409 
1410 AFLAT16(aflat16_row, update16, update16, 0, 0)
1411 AFLAT16(aflat16_row_mirror, update16, update16, 0, 1)
1412 AFLAT16(aflat16_column, update16, update16, 1, 0)
1413 AFLAT16(aflat16_column_mirror, update16, update16, 1, 1)
1414 AFLAT16(xflat16_row, update16, update16_cr, 0, 0)
1415 AFLAT16(xflat16_row_mirror, update16, update16_cr, 0, 1)
1416 AFLAT16(xflat16_column, update16, update16_cr, 1, 0)
1417 AFLAT16(xflat16_column_mirror, update16, update16_cr, 1, 1)
1418 AFLAT16(yflat16_row, update16_cr, update16_cr, 0, 0)
1419 AFLAT16(yflat16_row_mirror, update16_cr, update16_cr, 0, 1)
1420 AFLAT16(yflat16_column, update16_cr, update16_cr, 1, 0)
1421 AFLAT16(yflat16_column_mirror, update16_cr, update16_cr, 1, 1)
1422 
1423 AFLAT(aflat_row, update, update, 0, 0)
1424 AFLAT(aflat_row_mirror, update, update, 0, 1)
1425 AFLAT(aflat_column, update, update, 1, 0)
1426 AFLAT(aflat_column_mirror, update, update, 1, 1)
1427 AFLAT(xflat_row, update, update_cr, 0, 0)
1428 AFLAT(xflat_row_mirror, update, update_cr, 0, 1)
1429 AFLAT(xflat_column, update, update_cr, 1, 0)
1430 AFLAT(xflat_column_mirror, update, update_cr, 1, 1)
1431 AFLAT(yflat_row, update_cr, update_cr, 0, 0)
1432 AFLAT(yflat_row_mirror, update_cr, update_cr, 0, 1)
1433 AFLAT(yflat_column, update_cr, update_cr, 1, 0)
1434 AFLAT(yflat_column_mirror, update_cr, update_cr, 1, 1)
1435 
1437  AVFrame *in, AVFrame *out,
1438  int component, int intensity,
1439  int offset_y, int offset_x,
1440  int column, int mirror,
1441  int jobnr, int nb_jobs)
1442 {
1443  const int plane = s->desc->comp[component].plane;
1444  const int c0_linesize = in->linesize[(plane + 1) % s->ncomp] / 2;
1445  const int c1_linesize = in->linesize[(plane + 2) % s->ncomp] / 2;
1446  const int dst_linesize = out->linesize[plane] / 2;
1447  const int limit = s->max - 1;
1448  const int max = limit - intensity;
1449  const int mid = s->max / 2;
1450  const int c0_shift_w = s->shift_w[(component + 1) % s->ncomp];
1451  const int c1_shift_w = s->shift_w[(component + 2) % s->ncomp];
1452  const int c0_shift_h = s->shift_h[(component + 1) % s->ncomp];
1453  const int c1_shift_h = s->shift_h[(component + 2) % s->ncomp];
1454  const int src_h = in->height;
1455  const int src_w = in->width;
1456  const int sliceh_start = !column ? (src_h * jobnr) / nb_jobs : 0;
1457  const int sliceh_end = !column ? (src_h * (jobnr+1)) / nb_jobs : src_h;
1458  const int slicew_start = column ? (src_w * jobnr) / nb_jobs : 0;
1459  const int slicew_end = column ? (src_w * (jobnr+1)) / nb_jobs : src_w;
1460  int x, y;
1461 
1462  if (column) {
1463  const int dst_signed_linesize = dst_linesize * (mirror == 1 ? -1 : 1);
1464 
1465  for (x = slicew_start; x < slicew_end; x++) {
1466  const uint16_t *c0_data = (uint16_t *)in->data[(plane + 1) % s->ncomp];
1467  const uint16_t *c1_data = (uint16_t *)in->data[(plane + 2) % s->ncomp];
1468  uint16_t *dst_data = (uint16_t *)out->data[plane] + offset_y * dst_linesize + offset_x;
1469  uint16_t * const dst_bottom_line = dst_data + dst_linesize * (s->size - 1);
1470  uint16_t * const dst_line = (mirror ? dst_bottom_line : dst_data);
1471  uint16_t *dst = dst_line;
1472 
1473  for (y = 0; y < src_h; y++) {
1474  const int sum = FFMIN(FFABS(c0_data[x >> c0_shift_w] - mid) + FFABS(c1_data[x >> c1_shift_w] - mid - 1), limit);
1475  uint16_t *target;
1476 
1477  target = dst + x + dst_signed_linesize * sum;
1478  update16(target, max, intensity, limit);
1479 
1480  if (!c0_shift_h || (y & c0_shift_h))
1481  c0_data += c0_linesize;
1482  if (!c1_shift_h || (y & c1_shift_h))
1483  c1_data += c1_linesize;
1484  dst_data += dst_linesize;
1485  }
1486  }
1487  } else {
1488  const uint16_t *c0_data = (uint16_t *)in->data[(plane + 1) % s->ncomp] + (sliceh_start >> c0_shift_h) * c0_linesize;
1489  const uint16_t *c1_data = (uint16_t *)in->data[(plane + 2) % s->ncomp] + (sliceh_start >> c1_shift_h) * c1_linesize;
1490  uint16_t *dst_data = (uint16_t *)out->data[plane] + (offset_y + sliceh_start) * dst_linesize + offset_x;
1491 
1492  if (mirror)
1493  dst_data += s->size - 1;
1494  for (y = sliceh_start; y < sliceh_end; y++) {
1495  for (x = 0; x < src_w; x++) {
1496  const int sum = FFMIN(FFABS(c0_data[x >> c0_shift_w] - mid) + FFABS(c1_data[x >> c1_shift_w] - mid - 1), limit);
1497  uint16_t *target;
1498 
1499  if (mirror) {
1500  target = dst_data - sum;
1501  update16(target, max, intensity, limit);
1502  } else {
1503  target = dst_data + sum;
1504  update16(target, max, intensity, limit);
1505  }
1506  }
1507 
1508  if (!c0_shift_h || (y & c0_shift_h))
1509  c0_data += c0_linesize;
1510  if (!c1_shift_h || (y & c1_shift_h))
1511  c1_data += c1_linesize;
1512  dst_data += dst_linesize;
1513  }
1514  }
1515 }
1516 
1517 #define CHROMA16_FUNC(name, column, mirror) \
1518 static int chroma16_##name(AVFilterContext *ctx, \
1519  void *arg, int jobnr, \
1520  int nb_jobs) \
1521 { \
1522  WaveformContext *s = ctx->priv; \
1523  ThreadData *td = arg; \
1524  AVFrame *in = td->in; \
1525  AVFrame *out = td->out; \
1526  int component = td->component; \
1527  int offset_y = td->offset_y; \
1528  int offset_x = td->offset_x; \
1529  \
1530  chroma16(s, in, out, component, s->intensity,\
1531  offset_y, offset_x, column, mirror, \
1532  jobnr, nb_jobs); \
1533  \
1534  return 0; \
1535 }
1536 
1537 CHROMA16_FUNC(column_mirror, 1, 1)
1538 CHROMA16_FUNC(column, 1, 0)
1539 CHROMA16_FUNC(row_mirror, 0, 1)
1540 CHROMA16_FUNC(row, 0, 0)
1541 
1543  AVFrame *in, AVFrame *out,
1544  int component, int intensity,
1545  int offset_y, int offset_x,
1546  int column, int mirror,
1547  int jobnr, int nb_jobs)
1548 {
1549  const int plane = s->desc->comp[component].plane;
1550  const int src_h = in->height;
1551  const int src_w = in->width;
1552  const int sliceh_start = !column ? (src_h * jobnr) / nb_jobs : 0;
1553  const int sliceh_end = !column ? (src_h * (jobnr+1)) / nb_jobs : src_h;
1554  const int slicew_start = column ? (src_w * jobnr) / nb_jobs : 0;
1555  const int slicew_end = column ? (src_w * (jobnr+1)) / nb_jobs : src_w;
1556  const int c0_linesize = in->linesize[(plane + 1) % s->ncomp];
1557  const int c1_linesize = in->linesize[(plane + 2) % s->ncomp];
1558  const int dst_linesize = out->linesize[plane];
1559  const int max = 255 - intensity;
1560  const int c0_shift_w = s->shift_w[(component + 1) % s->ncomp];
1561  const int c1_shift_w = s->shift_w[(component + 2) % s->ncomp];
1562  const int c0_shift_h = s->shift_h[(component + 1) % s->ncomp];
1563  const int c1_shift_h = s->shift_h[(component + 2) % s->ncomp];
1564  int x, y;
1565 
1566  if (column) {
1567  const int dst_signed_linesize = dst_linesize * (mirror == 1 ? -1 : 1);
1568 
1569  for (x = slicew_start; x < slicew_end; x++) {
1570  const uint8_t *c0_data = in->data[(plane + 1) % s->ncomp];
1571  const uint8_t *c1_data = in->data[(plane + 2) % s->ncomp];
1572  uint8_t *dst_data = out->data[plane] + offset_y * dst_linesize + offset_x;
1573  uint8_t * const dst_bottom_line = dst_data + dst_linesize * (s->size - 1);
1574  uint8_t * const dst_line = (mirror ? dst_bottom_line : dst_data);
1575  uint8_t *dst = dst_line;
1576 
1577  for (y = 0; y < src_h; y++) {
1578  const int sum = FFABS(c0_data[x >> c0_shift_w] - 128) + FFABS(c1_data[x >> c1_shift_w] - 127);
1579  uint8_t *target;
1580 
1581  target = dst + x + dst_signed_linesize * sum;
1582  update(target, max, intensity);
1583 
1584  if (!c0_shift_h || (y & c0_shift_h))
1585  c0_data += c0_linesize;
1586  if (!c1_shift_h || (y & c1_shift_h))
1587  c1_data += c1_linesize;
1588  dst_data += dst_linesize;
1589  }
1590  }
1591  } else {
1592  const uint8_t *c0_data = in->data[(plane + 1) % s->ncomp] + (sliceh_start >> c0_shift_h) * c0_linesize;
1593  const uint8_t *c1_data = in->data[(plane + 2) % s->ncomp] + (sliceh_start >> c1_shift_h) * c1_linesize;
1594  uint8_t *dst_data = out->data[plane] + (offset_y + sliceh_start) * dst_linesize + offset_x;
1595 
1596  if (mirror)
1597  dst_data += s->size - 1;
1598  for (y = sliceh_start; y < sliceh_end; y++) {
1599  for (x = 0; x < src_w; x++) {
1600  const int sum = FFABS(c0_data[x >> c0_shift_w] - 128) + FFABS(c1_data[x >> c1_shift_w] - 127);
1601  uint8_t *target;
1602 
1603  if (mirror) {
1604  target = dst_data - sum;
1605  update(target, max, intensity);
1606  } else {
1607  target = dst_data + sum;
1608  update(target, max, intensity);
1609  }
1610  }
1611 
1612  if (!c0_shift_h || (y & c0_shift_h))
1613  c0_data += c0_linesize;
1614  if (!c1_shift_h || (y & c1_shift_h))
1615  c1_data += c1_linesize;
1616  dst_data += dst_linesize;
1617  }
1618  }
1619 }
1620 
1621 #define CHROMA_FUNC(name, column, mirror) \
1622 static int chroma_##name(AVFilterContext *ctx, \
1623  void *arg, int jobnr, \
1624  int nb_jobs) \
1625 { \
1626  WaveformContext *s = ctx->priv; \
1627  ThreadData *td = arg; \
1628  AVFrame *in = td->in; \
1629  AVFrame *out = td->out; \
1630  int component = td->component; \
1631  int offset_y = td->offset_y; \
1632  int offset_x = td->offset_x; \
1633  \
1634  chroma(s, in, out, component, s->intensity, \
1635  offset_y, offset_x, column, mirror, \
1636  jobnr, nb_jobs); \
1637  \
1638  return 0; \
1639 }
1640 
1641 CHROMA_FUNC(column_mirror, 1, 1)
1642 CHROMA_FUNC(column, 1, 0)
1643 CHROMA_FUNC(row_mirror, 0, 1)
1644 CHROMA_FUNC(row, 0, 0)
1645 
1647  AVFrame *in, AVFrame *out,
1648  int component, int intensity,
1649  int offset_y, int offset_x,
1650  int column, int mirror,
1651  int jobnr, int nb_jobs)
1652 {
1653  const int plane = s->desc->comp[component].plane;
1654  const int limit = s->max - 1;
1655  const int src_h = in->height;
1656  const int src_w = in->width;
1657  const int sliceh_start = !column ? (src_h * jobnr) / nb_jobs : 0;
1658  const int sliceh_end = !column ? (src_h * (jobnr+1)) / nb_jobs : src_h;
1659  const int slicew_start = column ? (src_w * jobnr) / nb_jobs : 0;
1660  const int slicew_end = column ? (src_w * (jobnr+1)) / nb_jobs : src_w;
1661  const int c0_linesize = in->linesize[ plane + 0 ] / 2;
1662  const int c1_linesize = in->linesize[(plane + 1) % s->ncomp] / 2;
1663  const int c2_linesize = in->linesize[(plane + 2) % s->ncomp] / 2;
1664  const int c0_shift_h = s->shift_h[ component + 0 ];
1665  const int c1_shift_h = s->shift_h[(component + 1) % s->ncomp];
1666  const int c2_shift_h = s->shift_h[(component + 2) % s->ncomp];
1667  const uint16_t *c0_data = (const uint16_t *)in->data[plane + 0] + (sliceh_start >> c0_shift_h) * c0_linesize;
1668  const uint16_t *c1_data = (const uint16_t *)in->data[(plane + 1) % s->ncomp] + (sliceh_start >> c1_shift_h) * c1_linesize;
1669  const uint16_t *c2_data = (const uint16_t *)in->data[(plane + 2) % s->ncomp] + (sliceh_start >> c2_shift_h) * c2_linesize;
1670  const int d0_linesize = out->linesize[ plane + 0 ] / 2;
1671  const int d1_linesize = out->linesize[(plane + 1) % s->ncomp] / 2;
1672  const int d2_linesize = out->linesize[(plane + 2) % s->ncomp] / 2;
1673  const int c0_shift_w = s->shift_w[ component + 0 ];
1674  const int c1_shift_w = s->shift_w[(component + 1) % s->ncomp];
1675  const int c2_shift_w = s->shift_w[(component + 2) % s->ncomp];
1676  int x, y;
1677 
1678  if (column) {
1679  const int d0_signed_linesize = d0_linesize * (mirror == 1 ? -1 : 1);
1680  const int d1_signed_linesize = d1_linesize * (mirror == 1 ? -1 : 1);
1681  const int d2_signed_linesize = d2_linesize * (mirror == 1 ? -1 : 1);
1682  uint16_t *d0_data = (uint16_t *)out->data[plane] + offset_y * d0_linesize + offset_x;
1683  uint16_t *d1_data = (uint16_t *)out->data[(plane + 1) % s->ncomp] + offset_y * d1_linesize + offset_x;
1684  uint16_t *d2_data = (uint16_t *)out->data[(plane + 2) % s->ncomp] + offset_y * d2_linesize + offset_x;
1685  uint16_t * const d0_bottom_line = d0_data + d0_linesize * (s->size - 1);
1686  uint16_t * const d0 = (mirror ? d0_bottom_line : d0_data);
1687  uint16_t * const d1_bottom_line = d1_data + d1_linesize * (s->size - 1);
1688  uint16_t * const d1 = (mirror ? d1_bottom_line : d1_data);
1689  uint16_t * const d2_bottom_line = d2_data + d2_linesize * (s->size - 1);
1690  uint16_t * const d2 = (mirror ? d2_bottom_line : d2_data);
1691 
1692  for (y = 0; y < src_h; y++) {
1693  for (x = slicew_start; x < slicew_end; x++) {
1694  const int c0 = FFMIN(c0_data[x >> c0_shift_w], limit);
1695  const int c1 = c1_data[x >> c1_shift_w];
1696  const int c2 = c2_data[x >> c2_shift_w];
1697 
1698  *(d0 + d0_signed_linesize * c0 + x) = c0;
1699  *(d1 + d1_signed_linesize * c0 + x) = c1;
1700  *(d2 + d2_signed_linesize * c0 + x) = c2;
1701  }
1702 
1703  if (!c0_shift_h || (y & c0_shift_h))
1704  c0_data += c0_linesize;
1705  if (!c1_shift_h || (y & c1_shift_h))
1706  c1_data += c1_linesize;
1707  if (!c2_shift_h || (y & c2_shift_h))
1708  c2_data += c2_linesize;
1709  d0_data += d0_linesize;
1710  d1_data += d1_linesize;
1711  d2_data += d2_linesize;
1712  }
1713  } else {
1714  uint16_t *d0_data = (uint16_t *)out->data[plane] + (offset_y + sliceh_start) * d0_linesize + offset_x;
1715  uint16_t *d1_data = (uint16_t *)out->data[(plane + 1) % s->ncomp] + (offset_y + sliceh_start) * d1_linesize + offset_x;
1716  uint16_t *d2_data = (uint16_t *)out->data[(plane + 2) % s->ncomp] + (offset_y + sliceh_start) * d2_linesize + offset_x;
1717 
1718  if (mirror) {
1719  d0_data += s->size - 1;
1720  d1_data += s->size - 1;
1721  d2_data += s->size - 1;
1722  }
1723 
1724  for (y = sliceh_start; y < sliceh_end; y++) {
1725  for (x = 0; x < src_w; x++) {
1726  const int c0 = FFMIN(c0_data[x >> c0_shift_w], limit);
1727  const int c1 = c1_data[x >> c1_shift_w];
1728  const int c2 = c2_data[x >> c2_shift_w];
1729 
1730  if (mirror) {
1731  *(d0_data - c0) = c0;
1732  *(d1_data - c0) = c1;
1733  *(d2_data - c0) = c2;
1734  } else {
1735  *(d0_data + c0) = c0;
1736  *(d1_data + c0) = c1;
1737  *(d2_data + c0) = c2;
1738  }
1739  }
1740 
1741  if (!c0_shift_h || (y & c0_shift_h))
1742  c0_data += c0_linesize;
1743  if (!c1_shift_h || (y & c1_shift_h))
1744  c1_data += c1_linesize;
1745  if (!c2_shift_h || (y & c2_shift_h))
1746  c2_data += c2_linesize;
1747  d0_data += d0_linesize;
1748  d1_data += d1_linesize;
1749  d2_data += d2_linesize;
1750  }
1751  }
1752 }
1753 
1754 #define COLOR16_FUNC(name, column, mirror) \
1755 static int color16_##name(AVFilterContext *ctx, \
1756  void *arg, int jobnr, \
1757  int nb_jobs) \
1758 { \
1759  WaveformContext *s = ctx->priv; \
1760  ThreadData *td = arg; \
1761  AVFrame *in = td->in; \
1762  AVFrame *out = td->out; \
1763  int component = td->component; \
1764  int offset_y = td->offset_y; \
1765  int offset_x = td->offset_x; \
1766  \
1767  color16(s, in, out, component, s->intensity, \
1768  offset_y, offset_x, column, mirror, \
1769  jobnr, nb_jobs); \
1770  \
1771  return 0; \
1772 }
1773 
1774 COLOR16_FUNC(column_mirror, 1, 1)
1775 COLOR16_FUNC(column, 1, 0)
1776 COLOR16_FUNC(row_mirror, 0, 1)
1777 COLOR16_FUNC(row, 0, 0)
1778 
1780  AVFrame *in, AVFrame *out,
1781  int component, int intensity,
1782  int offset_y, int offset_x,
1783  int column, int mirror,
1784  int jobnr, int nb_jobs)
1785 {
1786  const int plane = s->desc->comp[component].plane;
1787  const int src_h = in->height;
1788  const int src_w = in->width;
1789  const int sliceh_start = !column ? (src_h * jobnr) / nb_jobs : 0;
1790  const int sliceh_end = !column ? (src_h * (jobnr+1)) / nb_jobs : src_h;
1791  const int slicew_start = column ? (src_w * jobnr) / nb_jobs : 0;
1792  const int slicew_end = column ? (src_w * (jobnr+1)) / nb_jobs : src_w;
1793  const int c0_linesize = in->linesize[ plane + 0 ];
1794  const int c1_linesize = in->linesize[(plane + 1) % s->ncomp];
1795  const int c2_linesize = in->linesize[(plane + 2) % s->ncomp];
1796  const int c0_shift_h = s->shift_h[ component + 0 ];
1797  const int c1_shift_h = s->shift_h[(component + 1) % s->ncomp];
1798  const int c2_shift_h = s->shift_h[(component + 2) % s->ncomp];
1799  const uint8_t *c0_data = in->data[plane] + (sliceh_start >> c0_shift_h) * c0_linesize;
1800  const uint8_t *c1_data = in->data[(plane + 1) % s->ncomp] + (sliceh_start >> c1_shift_h) * c1_linesize;
1801  const uint8_t *c2_data = in->data[(plane + 2) % s->ncomp] + (sliceh_start >> c2_shift_h) * c2_linesize;
1802  const int d0_linesize = out->linesize[ plane + 0 ];
1803  const int d1_linesize = out->linesize[(plane + 1) % s->ncomp];
1804  const int d2_linesize = out->linesize[(plane + 2) % s->ncomp];
1805  const int c0_shift_w = s->shift_w[ component + 0 ];
1806  const int c1_shift_w = s->shift_w[(component + 1) % s->ncomp];
1807  const int c2_shift_w = s->shift_w[(component + 2) % s->ncomp];
1808  int x, y;
1809 
1810  if (column) {
1811  const int d0_signed_linesize = d0_linesize * (mirror == 1 ? -1 : 1);
1812  const int d1_signed_linesize = d1_linesize * (mirror == 1 ? -1 : 1);
1813  const int d2_signed_linesize = d2_linesize * (mirror == 1 ? -1 : 1);
1814  uint8_t *d0_data = out->data[plane] + offset_y * d0_linesize + offset_x;
1815  uint8_t *d1_data = out->data[(plane + 1) % s->ncomp] + offset_y * d1_linesize + offset_x;
1816  uint8_t *d2_data = out->data[(plane + 2) % s->ncomp] + offset_y * d2_linesize + offset_x;
1817  uint8_t * const d0_bottom_line = d0_data + d0_linesize * (s->size - 1);
1818  uint8_t * const d0 = (mirror ? d0_bottom_line : d0_data);
1819  uint8_t * const d1_bottom_line = d1_data + d1_linesize * (s->size - 1);
1820  uint8_t * const d1 = (mirror ? d1_bottom_line : d1_data);
1821  uint8_t * const d2_bottom_line = d2_data + d2_linesize * (s->size - 1);
1822  uint8_t * const d2 = (mirror ? d2_bottom_line : d2_data);
1823 
1824  for (y = 0; y < src_h; y++) {
1825  for (x = slicew_start; x < slicew_end; x++) {
1826  const int c0 = c0_data[x >> c0_shift_w];
1827  const int c1 = c1_data[x >> c1_shift_w];
1828  const int c2 = c2_data[x >> c2_shift_w];
1829 
1830  *(d0 + d0_signed_linesize * c0 + x) = c0;
1831  *(d1 + d1_signed_linesize * c0 + x) = c1;
1832  *(d2 + d2_signed_linesize * c0 + x) = c2;
1833  }
1834 
1835  if (!c0_shift_h || (y & c0_shift_h))
1836  c0_data += c0_linesize;
1837  if (!c1_shift_h || (y & c1_shift_h))
1838  c1_data += c1_linesize;
1839  if (!c2_shift_h || (y & c2_shift_h))
1840  c2_data += c2_linesize;
1841  d0_data += d0_linesize;
1842  d1_data += d1_linesize;
1843  d2_data += d2_linesize;
1844  }
1845  } else {
1846  uint8_t *d0_data = out->data[plane] + (offset_y + sliceh_start) * d0_linesize + offset_x;
1847  uint8_t *d1_data = out->data[(plane + 1) % s->ncomp] + (offset_y + sliceh_start) * d1_linesize + offset_x;
1848  uint8_t *d2_data = out->data[(plane + 2) % s->ncomp] + (offset_y + sliceh_start) * d2_linesize + offset_x;
1849 
1850  if (mirror) {
1851  d0_data += s->size - 1;
1852  d1_data += s->size - 1;
1853  d2_data += s->size - 1;
1854  }
1855 
1856  for (y = sliceh_start; y < sliceh_end; y++) {
1857  for (x = 0; x < src_w; x++) {
1858  const int c0 = c0_data[x >> c0_shift_w];
1859  const int c1 = c1_data[x >> c1_shift_w];
1860  const int c2 = c2_data[x >> c2_shift_w];
1861 
1862  if (mirror) {
1863  *(d0_data - c0) = c0;
1864  *(d1_data - c0) = c1;
1865  *(d2_data - c0) = c2;
1866  } else {
1867  *(d0_data + c0) = c0;
1868  *(d1_data + c0) = c1;
1869  *(d2_data + c0) = c2;
1870  }
1871  }
1872 
1873  if (!c0_shift_h || (y & c0_shift_h))
1874  c0_data += c0_linesize;
1875  if (!c1_shift_h || (y & c1_shift_h))
1876  c1_data += c1_linesize;
1877  if (!c2_shift_h || (y & c2_shift_h))
1878  c2_data += c2_linesize;
1879  d0_data += d0_linesize;
1880  d1_data += d1_linesize;
1881  d2_data += d2_linesize;
1882  }
1883  }
1884 }
1885 
1886 #define COLOR_FUNC(name, column, mirror) \
1887 static int color_##name(AVFilterContext *ctx, \
1888  void *arg, int jobnr, \
1889  int nb_jobs) \
1890 { \
1891  WaveformContext *s = ctx->priv; \
1892  ThreadData *td = arg; \
1893  AVFrame *in = td->in; \
1894  AVFrame *out = td->out; \
1895  int component = td->component; \
1896  int offset_y = td->offset_y; \
1897  int offset_x = td->offset_x; \
1898  \
1899  color(s, in, out, component, s->intensity, \
1900  offset_y, offset_x, column, mirror, \
1901  jobnr, nb_jobs); \
1902  \
1903  return 0; \
1904 }
1905 
1906 COLOR_FUNC(column_mirror, 1, 1)
1907 COLOR_FUNC(column, 1, 0)
1908 COLOR_FUNC(row_mirror, 0, 1)
1909 COLOR_FUNC(row, 0, 0)
1910 
1912  AVFrame *in, AVFrame *out,
1913  int component, int intensity,
1914  int offset_y, int offset_x,
1915  int column, int mirror,
1916  int jobnr, int nb_jobs)
1917 {
1918  const int plane = s->desc->comp[component].plane;
1919  const int limit = s->max - 1;
1920  const int max = limit - intensity;
1921  const int src_h = in->height;
1922  const int src_w = in->width;
1923  const int sliceh_start = !column ? (src_h * jobnr) / nb_jobs : 0;
1924  const int sliceh_end = !column ? (src_h * (jobnr+1)) / nb_jobs : src_h;
1925  const int slicew_start = column ? (src_w * jobnr) / nb_jobs : 0;
1926  const int slicew_end = column ? (src_w * (jobnr+1)) / nb_jobs : src_w;
1927  const int c0_shift_h = s->shift_h[ component + 0 ];
1928  const int c1_shift_h = s->shift_h[(component + 1) % s->ncomp];
1929  const int c2_shift_h = s->shift_h[(component + 2) % s->ncomp];
1930  const int c0_linesize = in->linesize[ plane + 0 ] / 2;
1931  const int c1_linesize = in->linesize[(plane + 1) % s->ncomp] / 2;
1932  const int c2_linesize = in->linesize[(plane + 2) % s->ncomp] / 2;
1933  const uint16_t *c0_data = (const uint16_t *)in->data[plane + 0] + (sliceh_start >> c0_shift_h) * c0_linesize;
1934  const uint16_t *c1_data = (const uint16_t *)in->data[(plane + 1) % s->ncomp] + (sliceh_start >> c1_shift_h) * c1_linesize;
1935  const uint16_t *c2_data = (const uint16_t *)in->data[(plane + 2) % s->ncomp] + (sliceh_start >> c2_shift_h) * c2_linesize;
1936  const int d0_linesize = out->linesize[ plane + 0 ] / 2;
1937  const int d1_linesize = out->linesize[(plane + 1) % s->ncomp] / 2;
1938  const int d2_linesize = out->linesize[(plane + 2) % s->ncomp] / 2;
1939  const int c0_shift_w = s->shift_w[ component + 0 ];
1940  const int c1_shift_w = s->shift_w[(component + 1) % s->ncomp];
1941  const int c2_shift_w = s->shift_w[(component + 2) % s->ncomp];
1942  int x, y;
1943 
1944  if (column) {
1945  const int d0_signed_linesize = d0_linesize * (mirror == 1 ? -1 : 1);
1946  const int d1_signed_linesize = d1_linesize * (mirror == 1 ? -1 : 1);
1947  const int d2_signed_linesize = d2_linesize * (mirror == 1 ? -1 : 1);
1948  uint16_t *d0_data = (uint16_t *)out->data[plane] + offset_y * d0_linesize + offset_x;
1949  uint16_t *d1_data = (uint16_t *)out->data[(plane + 1) % s->ncomp] + offset_y * d1_linesize + offset_x;
1950  uint16_t *d2_data = (uint16_t *)out->data[(plane + 2) % s->ncomp] + offset_y * d2_linesize + offset_x;
1951  uint16_t * const d0_bottom_line = d0_data + d0_linesize * (s->size - 1);
1952  uint16_t * const d0 = (mirror ? d0_bottom_line : d0_data);
1953  uint16_t * const d1_bottom_line = d1_data + d1_linesize * (s->size - 1);
1954  uint16_t * const d1 = (mirror ? d1_bottom_line : d1_data);
1955  uint16_t * const d2_bottom_line = d2_data + d2_linesize * (s->size - 1);
1956  uint16_t * const d2 = (mirror ? d2_bottom_line : d2_data);
1957 
1958  for (y = 0; y < src_h; y++) {
1959  for (x = slicew_start; x < slicew_end; x++) {
1960  const int c0 = FFMIN(c0_data[x >> c0_shift_w], limit);
1961  const int c1 = c1_data[x >> c1_shift_w];
1962  const int c2 = c2_data[x >> c2_shift_w];
1963 
1964  update16(d0 + d0_signed_linesize * c0 + x, max, intensity, limit);
1965  *(d1 + d1_signed_linesize * c0 + x) = c1;
1966  *(d2 + d2_signed_linesize * c0 + x) = c2;
1967  }
1968 
1969  if (!c0_shift_h || (y & c0_shift_h))
1970  c0_data += c0_linesize;
1971  if (!c1_shift_h || (y & c1_shift_h))
1972  c1_data += c1_linesize;
1973  if (!c2_shift_h || (y & c2_shift_h))
1974  c2_data += c2_linesize;
1975  d0_data += d0_linesize;
1976  d1_data += d1_linesize;
1977  d2_data += d2_linesize;
1978  }
1979  } else {
1980  uint16_t *d0_data = (uint16_t *)out->data[plane] + (offset_y + sliceh_start) * d0_linesize + offset_x;
1981  uint16_t *d1_data = (uint16_t *)out->data[(plane + 1) % s->ncomp] + (offset_y + sliceh_start) * d1_linesize + offset_x;
1982  uint16_t *d2_data = (uint16_t *)out->data[(plane + 2) % s->ncomp] + (offset_y + sliceh_start) * d2_linesize + offset_x;
1983 
1984  if (mirror) {
1985  d0_data += s->size - 1;
1986  d1_data += s->size - 1;
1987  d2_data += s->size - 1;
1988  }
1989 
1990  for (y = sliceh_start; y < sliceh_end; y++) {
1991  for (x = 0; x < src_w; x++) {
1992  const int c0 = FFMIN(c0_data[x >> c0_shift_w], limit);
1993  const int c1 = c1_data[x >> c1_shift_w];
1994  const int c2 = c2_data[x >> c2_shift_w];
1995 
1996  if (mirror) {
1997  update16(d0_data - c0, max, intensity, limit);
1998  *(d1_data - c0) = c1;
1999  *(d2_data - c0) = c2;
2000  } else {
2001  update16(d0_data + c0, max, intensity, limit);
2002  *(d1_data + c0) = c1;
2003  *(d2_data + c0) = c2;
2004  }
2005  }
2006 
2007  if (!c0_shift_h || (y & c0_shift_h))
2008  c0_data += c0_linesize;
2009  if (!c1_shift_h || (y & c1_shift_h))
2010  c1_data += c1_linesize;
2011  if (!c2_shift_h || (y & c2_shift_h))
2012  c2_data += c2_linesize;
2013  d0_data += d0_linesize;
2014  d1_data += d1_linesize;
2015  d2_data += d2_linesize;
2016  }
2017  }
2018 }
2019 
2020 #define ACOLOR16_FUNC(name, column, mirror) \
2021 static int acolor16_##name(AVFilterContext *ctx, \
2022  void *arg, int jobnr, \
2023  int nb_jobs) \
2024 { \
2025  WaveformContext *s = ctx->priv; \
2026  ThreadData *td = arg; \
2027  AVFrame *in = td->in; \
2028  AVFrame *out = td->out; \
2029  int component = td->component; \
2030  int offset_y = td->offset_y; \
2031  int offset_x = td->offset_x; \
2032  \
2033  acolor16(s, in, out, component, s->intensity,\
2034  offset_y, offset_x, column, mirror, \
2035  jobnr, nb_jobs); \
2036  \
2037  return 0; \
2038 }
2039 
2040 ACOLOR16_FUNC(column_mirror, 1, 1)
2041 ACOLOR16_FUNC(column, 1, 0)
2042 ACOLOR16_FUNC(row_mirror, 0, 1)
2043 ACOLOR16_FUNC(row, 0, 0)
2044 
2046  AVFrame *in, AVFrame *out,
2047  int component, int intensity,
2048  int offset_y, int offset_x,
2049  int column, int mirror,
2050  int jobnr, int nb_jobs)
2051 {
2052  const int plane = s->desc->comp[component].plane;
2053  const int src_h = in->height;
2054  const int src_w = in->width;
2055  const int sliceh_start = !column ? (src_h * jobnr) / nb_jobs : 0;
2056  const int sliceh_end = !column ? (src_h * (jobnr+1)) / nb_jobs : src_h;
2057  const int slicew_start = column ? (src_w * jobnr) / nb_jobs : 0;
2058  const int slicew_end = column ? (src_w * (jobnr+1)) / nb_jobs : src_w;
2059  const int c0_shift_w = s->shift_w[ component + 0 ];
2060  const int c1_shift_w = s->shift_w[(component + 1) % s->ncomp];
2061  const int c2_shift_w = s->shift_w[(component + 2) % s->ncomp];
2062  const int c0_shift_h = s->shift_h[ component + 0 ];
2063  const int c1_shift_h = s->shift_h[(component + 1) % s->ncomp];
2064  const int c2_shift_h = s->shift_h[(component + 2) % s->ncomp];
2065  const int c0_linesize = in->linesize[ plane + 0 ];
2066  const int c1_linesize = in->linesize[(plane + 1) % s->ncomp];
2067  const int c2_linesize = in->linesize[(plane + 2) % s->ncomp];
2068  const uint8_t *c0_data = in->data[plane + 0] + (sliceh_start >> c0_shift_h) * c0_linesize;
2069  const uint8_t *c1_data = in->data[(plane + 1) % s->ncomp] + (sliceh_start >> c1_shift_h) * c1_linesize;
2070  const uint8_t *c2_data = in->data[(plane + 2) % s->ncomp] + (sliceh_start >> c2_shift_h) * c2_linesize;
2071  const int d0_linesize = out->linesize[ plane + 0 ];
2072  const int d1_linesize = out->linesize[(plane + 1) % s->ncomp];
2073  const int d2_linesize = out->linesize[(plane + 2) % s->ncomp];
2074  const int max = 255 - intensity;
2075  int x, y;
2076 
2077  if (column) {
2078  const int d0_signed_linesize = d0_linesize * (mirror == 1 ? -1 : 1);
2079  const int d1_signed_linesize = d1_linesize * (mirror == 1 ? -1 : 1);
2080  const int d2_signed_linesize = d2_linesize * (mirror == 1 ? -1 : 1);
2081  uint8_t *d0_data = out->data[plane] + offset_y * d0_linesize + offset_x;
2082  uint8_t *d1_data = out->data[(plane + 1) % s->ncomp] + offset_y * d1_linesize + offset_x;
2083  uint8_t *d2_data = out->data[(plane + 2) % s->ncomp] + offset_y * d2_linesize + offset_x;
2084  uint8_t * const d0_bottom_line = d0_data + d0_linesize * (s->size - 1);
2085  uint8_t * const d0 = (mirror ? d0_bottom_line : d0_data);
2086  uint8_t * const d1_bottom_line = d1_data + d1_linesize * (s->size - 1);
2087  uint8_t * const d1 = (mirror ? d1_bottom_line : d1_data);
2088  uint8_t * const d2_bottom_line = d2_data + d2_linesize * (s->size - 1);
2089  uint8_t * const d2 = (mirror ? d2_bottom_line : d2_data);
2090 
2091  for (y = 0; y < src_h; y++) {
2092  for (x = slicew_start; x < slicew_end; x++) {
2093  const int c0 = c0_data[x >> c0_shift_w];
2094  const int c1 = c1_data[x >> c1_shift_w];
2095  const int c2 = c2_data[x >> c2_shift_w];
2096 
2097  update(d0 + d0_signed_linesize * c0 + x, max, intensity);
2098  *(d1 + d1_signed_linesize * c0 + x) = c1;
2099  *(d2 + d2_signed_linesize * c0 + x) = c2;
2100  }
2101 
2102  if (!c0_shift_h || (y & c0_shift_h))
2103  c0_data += c0_linesize;
2104  if (!c1_shift_h || (y & c1_shift_h))
2105  c1_data += c1_linesize;
2106  if (!c2_shift_h || (y & c2_shift_h))
2107  c2_data += c2_linesize;
2108  d0_data += d0_linesize;
2109  d1_data += d1_linesize;
2110  d2_data += d2_linesize;
2111  }
2112  } else {
2113  uint8_t *d0_data = out->data[plane] + (offset_y + sliceh_start) * d0_linesize + offset_x;
2114  uint8_t *d1_data = out->data[(plane + 1) % s->ncomp] + (offset_y + sliceh_start) * d1_linesize + offset_x;
2115  uint8_t *d2_data = out->data[(plane + 2) % s->ncomp] + (offset_y + sliceh_start) * d2_linesize + offset_x;
2116 
2117  if (mirror) {
2118  d0_data += s->size - 1;
2119  d1_data += s->size - 1;
2120  d2_data += s->size - 1;
2121  }
2122 
2123  for (y = sliceh_start; y < sliceh_end; y++) {
2124  for (x = 0; x < src_w; x++) {
2125  const int c0 = c0_data[x >> c0_shift_w];
2126  const int c1 = c1_data[x >> c1_shift_w];
2127  const int c2 = c2_data[x >> c2_shift_w];
2128 
2129  if (mirror) {
2130  update(d0_data - c0, max, intensity);
2131  *(d1_data - c0) = c1;
2132  *(d2_data - c0) = c2;
2133  } else {
2134  update(d0_data + c0, max, intensity);
2135  *(d1_data + c0) = c1;
2136  *(d2_data + c0) = c2;
2137  }
2138  }
2139 
2140  if (!c0_shift_h || (y & c0_shift_h))
2141  c0_data += c0_linesize;
2142  if (!c1_shift_h || (y & c1_shift_h))
2143  c1_data += c1_linesize;
2144  if (!c2_shift_h || (y & c2_shift_h))
2145  c2_data += c2_linesize;
2146  d0_data += d0_linesize;
2147  d1_data += d1_linesize;
2148  d2_data += d2_linesize;
2149  }
2150  }
2151 }
2152 
2153 #define ACOLOR_FUNC(name, column, mirror) \
2154 static int acolor_##name(AVFilterContext *ctx, \
2155  void *arg, int jobnr, \
2156  int nb_jobs) \
2157 { \
2158  WaveformContext *s = ctx->priv; \
2159  ThreadData *td = arg; \
2160  AVFrame *in = td->in; \
2161  AVFrame *out = td->out; \
2162  int component = td->component; \
2163  int offset_y = td->offset_y; \
2164  int offset_x = td->offset_x; \
2165  \
2166  acolor(s, in, out, component, s->intensity, \
2167  offset_y, offset_x, column, mirror, \
2168  jobnr, nb_jobs); \
2169  \
2170  return 0; \
2171 }
2172 
2173 ACOLOR_FUNC(column_mirror, 1, 1)
2174 ACOLOR_FUNC(column, 1, 0)
2175 ACOLOR_FUNC(row_mirror, 0, 1)
2176 ACOLOR_FUNC(row, 0, 0)
2177 
2178 static const uint8_t black_yuva_color[4] = { 0, 127, 127, 255 };
2179 static const uint8_t black_gbrp_color[4] = { 0, 0, 0, 255 };
2180 
2181 static const GraticuleLines aflat_digital8[] = {
2182  { { { "16", 16+128 }, { "16", 16+128 }, { "16", 16+128 }, { "0", 0+128 } } },
2183  { { { "128", 128+128 }, { "128", 128+128 }, { "128", 128+128 }, { "128", 128+128 } } },
2184  { { { "235", 235+128 }, { "240", 240+128 }, { "240", 240+128 }, { "255", 255+128 } } },
2185 };
2186 
2187 static const GraticuleLines aflat_digital9[] = {
2188  { { { "32", 32+256 }, { "32", 32+256 }, { "32", 32+256 }, { "0", 0+256 } } },
2189  { { { "256", 256+256 }, { "256", 256+256 }, { "256", 256+256 }, { "256", 256+256 } } },
2190  { { { "470", 470+256 }, { "480", 480+256 }, { "480", 480+256 }, { "511", 511+256 } } },
2191 };
2192 
2194  { { { "64", 64+512 }, { "64", 64+512 }, { "64", 64+512 }, { "0", 0+512 } } },
2195  { { { "512", 512+512 }, { "512", 512+512 }, { "512", 512+512 }, { "512", 512+512 } } },
2196  { { { "940", 940+512 }, { "960", 960+512 }, { "960", 960+512 }, { "1023", 1023+512 } } },
2197 };
2198 
2200  { { { "256", 256+2048 }, { "256", 256+2048 }, { "256", 256+2048 }, { "0", 0+2048 } } },
2201  { { { "2048", 2048+2048 }, { "2048", 2048+2048 }, { "2048", 2048+2048 }, { "2048", 2048+2048 } } },
2202  { { { "3760", 3760+2048 }, { "3840", 3840+2048 }, { "3840", 3840+2048 }, { "4095", 4095+2048 } } },
2203 };
2204 
2206  { { { "0", 16+128 }, { "0", 16+128 }, { "0", 16+128 }, { "0", 0+128 } } },
2207  { { { "175", 71+128 }, { "175", 72+128 }, { "175", 72+128 }, { "175", 64+128 } } },
2208  { { { "350", 126+128 }, { "350", 128+128 }, { "350", 128+128 }, { "350", 128+128 } } },
2209  { { { "525", 180+128 }, { "525", 184+128 }, { "525", 184+128 }, { "525", 192+128 } } },
2210  { { { "700", 235+128 }, { "700", 240+128 }, { "700", 240+128 }, { "700", 255+128 } } },
2211 };
2212 
2214  { { { "0", 32+256 }, { "0", 32+256 }, { "0", 32+256 }, { "0", 0+256 } } },
2215  { { { "175", 142+256 }, { "175", 144+256 }, { "175", 144+256 }, { "175", 128+256 } } },
2216  { { { "350", 251+256 }, { "350", 256+256 }, { "350", 256+256 }, { "350", 256+256 } } },
2217  { { { "525", 361+256 }, { "525", 368+256 }, { "525", 368+256 }, { "525", 384+256 } } },
2218  { { { "700", 470+256 }, { "700", 480+256 }, { "700", 480+256 }, { "700", 511+256 } } },
2219 };
2220 
2222  { { { "0", 64+512 }, { "0", 64+512 }, { "0", 64+512 }, { "0", 0+512 } } },
2223  { { { "175", 283+512 }, { "175", 288+512 }, { "175", 288+512 }, { "175", 256+512 } } },
2224  { { { "350", 502+512 }, { "350", 512+512 }, { "350", 512+512 }, { "350", 512+512 } } },
2225  { { { "525", 721+512 }, { "525", 736+512 }, { "525", 736+512 }, { "525", 768+512 } } },
2226  { { { "700", 940+512 }, { "700", 960+512 }, { "700", 960+512 }, { "700", 1023+512 } } },
2227 };
2228 
2230  { { { "0", 256+2048 }, { "0", 256+2048 }, { "0", 256+2048 }, { "0", 0+2048 } } },
2231  { { { "175", 1132+2048 }, { "175", 1152+2048 }, { "175", 1152+2048 }, { "175", 1024+2048 } } },
2232  { { { "350", 2008+2048 }, { "350", 2048+2048 }, { "350", 2048+2048 }, { "350", 2048+2048 } } },
2233  { { { "525", 2884+2048 }, { "525", 2944+2048 }, { "525", 2944+2048 }, { "525", 3072+2048 } } },
2234  { { { "700", 3760+2048 }, { "700", 3840+2048 }, { "700", 3840+2048 }, { "700", 4095+2048 } } },
2235 };
2236 
2237 static const GraticuleLines aflat_ire8[] = {
2238  { { { "-25", -39+128 }, { "-25", -40+128 }, { "-25", -40+128 }, { "-25", -64+128 } } },
2239  { { { "0", 16+128 }, { "0", 16+128 }, { "0", 16+128 }, { "0", 0+128 } } },
2240  { { { "25", 71+128 }, { "25", 72+128 }, { "25", 72+128 }, { "25", 64+128 } } },
2241  { { { "50", 126+128 }, { "50", 128+128 }, { "50", 128+128 }, { "50", 128+128 } } },
2242  { { { "75", 180+128 }, { "75", 184+128 }, { "75", 184+128 }, { "75", 192+128 } } },
2243  { { { "100", 235+128 }, { "100", 240+128 }, { "100", 240+128 }, { "100", 256+128 } } },
2244  { { { "125", 290+128 }, { "125", 296+128 }, { "125", 296+128 }, { "125", 320+128 } } },
2245 };
2246 
2247 static const GraticuleLines aflat_ire9[] = {
2248  { { { "-25", -78+256 }, { "-25", -80+256 }, { "-25", -80+256 }, { "-25",-128+256 } } },
2249  { { { "0", 32+256 }, { "0", 32+256 }, { "0", 32+256 }, { "0", 0+256 } } },
2250  { { { "25", 142+256 }, { "25", 144+256 }, { "25", 144+256 }, { "25", 128+256 } } },
2251  { { { "50", 251+256 }, { "50", 256+256 }, { "50", 256+256 }, { "50", 256+256 } } },
2252  { { { "75", 361+256 }, { "75", 368+256 }, { "75", 368+256 }, { "75", 384+256 } } },
2253  { { { "100", 470+256 }, { "100", 480+256 }, { "100", 480+256 }, { "100", 512+256 } } },
2254  { { { "125", 580+256 }, { "125", 592+256 }, { "125", 592+256 }, { "125", 640+256 } } },
2255 };
2256 
2257 static const GraticuleLines aflat_ire10[] = {
2258  { { { "-25",-156+512 }, { "-25",-160+512 }, { "-25",-160+512 }, { "-25", -256+512 } } },
2259  { { { "0", 64+512 }, { "0", 64+512 }, { "0", 64+512 }, { "0", 0+512 } } },
2260  { { { "25", 283+512 }, { "25", 288+512 }, { "25", 288+512 }, { "25", 256+512 } } },
2261  { { { "50", 502+512 }, { "50", 512+512 }, { "50", 512+512 }, { "50", 512+512 } } },
2262  { { { "75", 721+512 }, { "75", 736+512 }, { "75", 736+512 }, { "75", 768+512 } } },
2263  { { { "100", 940+512 }, { "100", 960+512 }, { "100", 960+512 }, { "100", 1024+512 } } },
2264  { { { "125",1160+512 }, { "125",1184+512 }, { "125",1184+512 }, { "125", 1280+512 } } },
2265 };
2266 
2267 static const GraticuleLines aflat_ire12[] = {
2268  { { { "-25", -624+2048 }, { "-25", -640+2048 }, { "-25", -640+2048 }, { "-25",-1024+2048 } } },
2269  { { { "0", 256+2048 }, { "0", 256+2048 }, { "0", 256+2048 }, { "0", 0+2048 } } },
2270  { { { "25", 1132+2048 }, { "25", 1152+2048 }, { "25", 1152+2048 }, { "25", 1024+2048 } } },
2271  { { { "50", 2008+2048 }, { "50", 2048+2048 }, { "50", 2048+2048 }, { "50", 2048+2048 } } },
2272  { { { "75", 2884+2048 }, { "75", 2944+2048 }, { "75", 2944+2048 }, { "75", 3072+2048 } } },
2273  { { { "100", 3760+2048 }, { "100", 3840+2048 }, { "100", 3840+2048 }, { "100", 4096+2048 } } },
2274  { { { "125", 4640+2048 }, { "125", 4736+2048 }, { "125", 4736+2048 }, { "125", 5120+2048 } } },
2275 };
2276 
2277 static const GraticuleLines flat_digital8[] = {
2278  { { { "16", 16+256 }, { "16", 16+256 }, { "16", 16+256 }, { "0", 0+256 } } },
2279  { { { "128", 128+256 }, { "128", 128+256 }, { "128", 128+256 }, { "128", 128+256 } } },
2280  { { { "235", 235+256 }, { "240", 240+256 }, { "240", 240+256 }, { "255", 255+256 } } },
2281 };
2282 
2283 static const GraticuleLines flat_digital9[] = {
2284  { { { "32", 32+512 }, { "32", 32+512 }, { "32", 32+512 }, { "0", 0+512 } } },
2285  { { { "256", 256+512 }, { "256", 256+512 }, { "256", 256+512 }, { "256", 256+512 } } },
2286  { { { "470", 470+512 }, { "480", 480+512 }, { "480", 480+512 }, { "511", 511+512 } } },
2287 };
2288 
2289 static const GraticuleLines flat_digital10[] = {
2290  { { { "64", 64+1024 }, { "64", 64+1024 }, { "64", 64+1024 }, { "0", 0+1024 } } },
2291  { { { "512", 512+1024 }, { "512", 512+1024 }, { "512", 512+1024 }, { "512", 512+1024 } } },
2292  { { { "940", 940+1024 }, { "960", 960+1024 }, { "960", 960+1024 }, { "1023", 1023+1024 } } },
2293 };
2294 
2295 static const GraticuleLines flat_digital12[] = {
2296  { { { "256", 256+4096 }, { "256", 256+4096 }, { "256", 256+4096 }, { "0", 0+4096 } } },
2297  { { { "2048", 2048+4096 }, { "2048", 2048+4096 }, { "2048", 2048+4096 }, { "2048", 2048+4096 } } },
2298  { { { "3760", 3760+4096 }, { "3840", 3840+4096 }, { "3840", 3840+4096 }, { "4095", 4095+4096 } } },
2299 };
2300 
2302  { { { "0", 16+256 }, { "0", 16+256 }, { "0", 16+256 }, { "0", 0+256 } } },
2303  { { { "175", 71+256 }, { "175", 72+256 }, { "175", 72+256 }, { "175", 64+256 } } },
2304  { { { "350", 126+256 }, { "350", 128+256 }, { "350", 128+256 }, { "350", 128+256 } } },
2305  { { { "525", 180+256 }, { "525", 184+256 }, { "525", 184+256 }, { "525", 192+256 } } },
2306  { { { "700", 235+256 }, { "700", 240+256 }, { "700", 240+256 }, { "700", 255+256 } } },
2307 };
2308 
2310  { { { "0", 32+512 }, { "0", 32+512 }, { "0", 32+512 }, { "0", 0+512 } } },
2311  { { { "175", 142+512 }, { "175", 144+512 }, { "175", 144+512 }, { "175", 128+512 } } },
2312  { { { "350", 251+512 }, { "350", 256+512 }, { "350", 256+512 }, { "350", 256+512 } } },
2313  { { { "525", 361+512 }, { "525", 368+512 }, { "525", 368+512 }, { "525", 384+512 } } },
2314  { { { "700", 470+512 }, { "700", 480+512 }, { "700", 480+512 }, { "700", 511+512 } } },
2315 };
2316 
2318  { { { "0", 64+1024 }, { "0", 64+1024 }, { "0", 64+1024 }, { "0", 0+1024 } } },
2319  { { { "175", 283+1024 }, { "175", 288+1024 }, { "175", 288+1024 }, { "175", 256+1024 } } },
2320  { { { "350", 502+1024 }, { "350", 512+1024 }, { "350", 512+1024 }, { "350", 512+1024 } } },
2321  { { { "525", 721+1024 }, { "525", 736+1024 }, { "525", 736+1024 }, { "525", 768+1024 } } },
2322  { { { "700", 940+1024 }, { "700", 960+1024 }, { "700", 960+1024 }, { "700", 1023+1024 } } },
2323 };
2324 
2326  { { { "0", 256+4096 }, { "0", 256+4096 }, { "0", 256+4096 }, { "0", 0+4096 } } },
2327  { { { "175", 1132+4096 }, { "175", 1152+4096 }, { "175", 1152+4096 }, { "175", 1024+4096 } } },
2328  { { { "350", 2008+4096 }, { "350", 2048+4096 }, { "350", 2048+4096 }, { "350", 2048+4096 } } },
2329  { { { "525", 2884+4096 }, { "525", 2944+4096 }, { "525", 2944+4096 }, { "525", 3072+4096 } } },
2330  { { { "700", 3760+4096 }, { "700", 3840+4096 }, { "700", 3840+4096 }, { "700", 4095+4096 } } },
2331 };
2332 
2333 static const GraticuleLines flat_ire8[] = {
2334  { { { "-25", -39+256 }, { "-25", -40+256 }, { "-25", -40+256 }, { "-25", -64+256 } } },
2335  { { { "0", 16+256 }, { "0", 16+256 }, { "0", 16+256 }, { "0", 0+256 } } },
2336  { { { "25", 71+256 }, { "25", 72+256 }, { "25", 72+256 }, { "25", 64+256 } } },
2337  { { { "50", 126+256 }, { "50", 128+256 }, { "50", 128+256 }, { "50", 128+256 } } },
2338  { { { "75", 180+256 }, { "75", 184+256 }, { "75", 184+256 }, { "75", 192+256 } } },
2339  { { { "100", 235+256 }, { "100", 240+256 }, { "100", 240+256 }, { "100", 256+256 } } },
2340  { { { "125", 290+256 }, { "125", 296+256 }, { "125", 296+256 }, { "125", 320+256 } } },
2341 };
2342 
2343 static const GraticuleLines flat_ire9[] = {
2344  { { { "-25", -78+512 }, { "-25", -80+512 }, { "-25", -80+512 }, { "-25",-128+512 } } },
2345  { { { "0", 32+512 }, { "0", 32+512 }, { "0", 32+512 }, { "0", 0+512 } } },
2346  { { { "25", 142+512 }, { "25", 144+512 }, { "25", 144+512 }, { "25", 128+512 } } },
2347  { { { "50", 251+512 }, { "50", 256+512 }, { "50", 256+512 }, { "50", 256+512 } } },
2348  { { { "75", 361+512 }, { "75", 368+512 }, { "75", 368+512 }, { "75", 384+512 } } },
2349  { { { "100", 470+512 }, { "100", 480+512 }, { "100", 480+512 }, { "100", 512+512 } } },
2350  { { { "125", 580+512 }, { "125", 592+512 }, { "125", 592+512 }, { "125", 640+512 } } },
2351 };
2352 
2353 static const GraticuleLines flat_ire10[] = {
2354  { { { "-25",-156+1024 }, { "-25",-160+1024 }, { "-25",-160+1024 }, { "-25", -256+1024 } } },
2355  { { { "0", 64+1024 }, { "0", 64+1024 }, { "0", 64+1024 }, { "0", 0+1024 } } },
2356  { { { "25", 283+1024 }, { "25", 288+1024 }, { "25", 288+1024 }, { "25", 256+1024 } } },
2357  { { { "50", 502+1024 }, { "50", 512+1024 }, { "50", 512+1024 }, { "50", 512+1024 } } },
2358  { { { "75", 721+1024 }, { "75", 736+1024 }, { "75", 736+1024 }, { "75", 768+1024 } } },
2359  { { { "100", 940+1024 }, { "100", 960+1024 }, { "100", 960+1024 }, { "100", 1024+1024 } } },
2360  { { { "125",1160+1024 }, { "125",1184+1024 }, { "125",1184+1024 }, { "125", 1280+1024 } } },
2361 };
2362 
2363 static const GraticuleLines flat_ire12[] = {
2364  { { { "-25", -624+4096 }, { "-25", -640+4096 }, { "-25", -640+4096 }, { "-25",-1024+4096 } } },
2365  { { { "0", 256+4096 }, { "0", 256+4096 }, { "0", 256+4096 }, { "0", 0+4096 } } },
2366  { { { "25", 1132+4096 }, { "25", 1152+4096 }, { "25", 1152+4096 }, { "25", 1024+4096 } } },
2367  { { { "50", 2008+4096 }, { "50", 2048+4096 }, { "50", 2048+4096 }, { "50", 2048+4096 } } },
2368  { { { "75", 2884+4096 }, { "75", 2944+4096 }, { "75", 2944+4096 }, { "75", 3072+4096 } } },
2369  { { { "100", 3760+4096 }, { "100", 3840+4096 }, { "100", 3840+4096 }, { "100", 4096+4096 } } },
2370  { { { "125", 4640+4096 }, { "125", 4736+4096 }, { "125", 4736+4096 }, { "125", 5120+4096 } } },
2371 };
2372 
2373 static const GraticuleLines digital8[] = {
2374  { { { "16", 16 }, { "16", 16 }, { "16", 16 }, { "0", 0 } } },
2375  { { { "128", 128 }, { "128", 128 }, { "128", 128 }, { "128", 128 } } },
2376  { { { "235", 235 }, { "240", 240 }, { "240", 240 }, { "255", 255 } } },
2377 };
2378 
2379 static const GraticuleLines digital9[] = {
2380  { { { "32", 32 }, { "32", 32 }, { "32", 32 }, { "0", 0 } } },
2381  { { { "256", 256 }, { "256", 256 }, { "256", 256 }, { "256", 256 } } },
2382  { { { "470", 470 }, { "480", 480 }, { "480", 480 }, { "511", 511 } } },
2383 };
2384 
2385 static const GraticuleLines digital10[] = {
2386  { { { "64", 64 }, { "64", 64 }, { "64", 64 }, { "0", 0 } } },
2387  { { { "512", 512 }, { "512", 512 }, { "512", 512 }, { "512", 512 } } },
2388  { { { "940", 940 }, { "960", 960 }, { "960", 960 }, { "1023", 1023 } } },
2389 };
2390 
2391 static const GraticuleLines digital12[] = {
2392  { { { "256", 256 }, { "256", 256 }, { "256", 256 }, { "0", 0 } } },
2393  { { { "2048", 2048 }, { "2048", 2048 }, { "2048", 2048 }, { "2048", 2048 } } },
2394  { { { "3760", 3760 }, { "3840", 3840 }, { "3840", 3840 }, { "4095", 4095 } } },
2395 };
2396 
2397 static const GraticuleLines millivolts8[] = {
2398  { { { "0", 16 }, { "0", 16 }, { "0", 16 }, { "0", 0 } } },
2399  { { { "175", 71 }, { "175", 72 }, { "175", 72 }, { "175", 64 } } },
2400  { { { "350", 126 }, { "350", 128 }, { "350", 128 }, { "350", 128 } } },
2401  { { { "525", 180 }, { "525", 184 }, { "525", 184 }, { "525", 192 } } },
2402  { { { "700", 235 }, { "700", 240 }, { "700", 240 }, { "700", 255 } } },
2403 };
2404 
2405 static const GraticuleLines millivolts9[] = {
2406  { { { "0", 32 }, { "0", 32 }, { "0", 32 }, { "0", 0 } } },
2407  { { { "175", 142 }, { "175", 144 }, { "175", 144 }, { "175", 128 } } },
2408  { { { "350", 251 }, { "350", 256 }, { "350", 256 }, { "350", 256 } } },
2409  { { { "525", 361 }, { "525", 368 }, { "525", 368 }, { "525", 384 } } },
2410  { { { "700", 470 }, { "700", 480 }, { "700", 480 }, { "700", 511 } } },
2411 };
2412 
2413 static const GraticuleLines millivolts10[] = {
2414  { { { "0", 64 }, { "0", 64 }, { "0", 64 }, { "0", 0 } } },
2415  { { { "175", 283 }, { "175", 288 }, { "175", 288 }, { "175", 256 } } },
2416  { { { "350", 502 }, { "350", 512 }, { "350", 512 }, { "350", 512 } } },
2417  { { { "525", 721 }, { "525", 736 }, { "525", 736 }, { "525", 768 } } },
2418  { { { "700", 940 }, { "700", 960 }, { "700", 960 }, { "700", 1023 } } },
2419 };
2420 
2421 static const GraticuleLines millivolts12[] = {
2422  { { { "0", 256 }, { "0", 256 }, { "0", 256 }, { "0", 0 } } },
2423  { { { "175", 1132 }, { "175", 1152 }, { "175", 1152 }, { "175", 1024 } } },
2424  { { { "350", 2008 }, { "350", 2048 }, { "350", 2048 }, { "350", 2048 } } },
2425  { { { "525", 2884 }, { "525", 2944 }, { "525", 2944 }, { "525", 3072 } } },
2426  { { { "700", 3760 }, { "700", 3840 }, { "700", 3840 }, { "700", 4095 } } },
2427 };
2428 
2429 static const GraticuleLines ire8[] = {
2430  { { { "0", 16 }, { "0", 16 }, { "0", 16 }, { "0", 0 } } },
2431  { { { "25", 71 }, { "25", 72 }, { "25", 72 }, { "25", 64 } } },
2432  { { { "50", 126 }, { "50", 128 }, { "50", 128 }, { "50", 128 } } },
2433  { { { "75", 180 }, { "75", 184 }, { "75", 184 }, { "75", 192 } } },
2434  { { { "100", 235 }, { "100", 240 }, { "100", 240 }, { "100", 255 } } },
2435 };
2436 
2437 static const GraticuleLines ire9[] = {
2438  { { { "0", 32 }, { "0", 32 }, { "0", 32 }, { "0", 0 } } },
2439  { { { "25", 142 }, { "25", 144 }, { "25", 144 }, { "25", 128 } } },
2440  { { { "50", 251 }, { "50", 256 }, { "50", 256 }, { "50", 256 } } },
2441  { { { "75", 361 }, { "75", 368 }, { "75", 368 }, { "75", 384 } } },
2442  { { { "100", 470 }, { "100", 480 }, { "100", 480 }, { "100", 511 } } },
2443 };
2444 
2445 static const GraticuleLines ire10[] = {
2446  { { { "0", 64 }, { "0", 64 }, { "0", 64 }, { "0", 0 } } },
2447  { { { "25", 283 }, { "25", 288 }, { "25", 288 }, { "25", 256 } } },
2448  { { { "50", 502 }, { "50", 512 }, { "50", 512 }, { "50", 512 } } },
2449  { { { "75", 721 }, { "75", 736 }, { "75", 736 }, { "75", 768 } } },
2450  { { { "100", 940 }, { "100", 960 }, { "100", 960 }, { "100", 1023 } } },
2451 };
2452 
2453 static const GraticuleLines ire12[] = {
2454  { { { "0", 256 }, { "0", 256 }, { "0", 256 }, { "0", 0 } } },
2455  { { { "25", 1132 }, { "25", 1152 }, { "25", 1152 }, { "25", 1024 } } },
2456  { { { "50", 2008 }, { "50", 2048 }, { "50", 2048 }, { "50", 2048 } } },
2457  { { { "75", 2884 }, { "75", 2944 }, { "75", 2944 }, { "75", 3072 } } },
2458  { { { "100", 3760 }, { "100", 3840 }, { "100", 3840 }, { "100", 4095 } } },
2459 };
2460 
2462  { { { "50", 50 }, { "50", 50 }, { "50", 50 }, { "50", 50 } } },
2463  { { { "100", 100 }, { "100", 100 }, { "100", 100 }, { "100", 100 } } },
2464  { { { "150", 150 }, { "150", 150 }, { "150", 150 }, { "150", 150 } } },
2465  { { { "200", 200 }, { "200", 200 }, { "200", 200 }, { "200", 200 } } },
2466  { { { "255", 255 }, { "255", 255 }, { "255", 255 }, { "255", 255 } } },
2467 };
2468 
2470  { { { "100", 100 }, { "100", 100 }, { "100", 100 }, { "100", 100 } } },
2471  { { { "200", 200 }, { "200", 200 }, { "200", 200 }, { "200", 200 } } },
2472  { { { "300", 300 }, { "300", 300 }, { "300", 300 }, { "300", 300 } } },
2473  { { { "400", 400 }, { "400", 400 }, { "400", 400 }, { "400", 400 } } },
2474  { { { "500", 500 }, { "500", 500 }, { "500", 500 }, { "500", 500 } } },
2475 };
2476 
2478  { { { "200", 200 }, { "200", 200 }, { "200", 200 }, { "200", 200 } } },
2479  { { { "400", 400 }, { "400", 400 }, { "400", 400 }, { "400", 400 } } },
2480  { { { "600", 600 }, { "600", 600 }, { "600", 600 }, { "600", 600 } } },
2481  { { { "800", 800 }, { "800", 800 }, { "800", 800 }, { "800", 800 } } },
2482  { { {"1000",1000 }, {"1000",1000 }, {"1000",1000 }, {"1000",1000 } } },
2483 };
2484 
2486  { { { "800", 800 }, { "800", 800 }, { "800", 800 }, { "800", 800 } } },
2487  { { { "1600", 1600 }, { "1600", 1600 }, { "1600", 1600 }, { "1600", 1600 } } },
2488  { { { "2400", 2400 }, { "2400", 2400 }, { "2400", 2400 }, { "2400", 2400 } } },
2489  { { { "3200", 3200 }, { "3200", 3200 }, { "3200", 3200 }, { "3200", 3200 } } },
2490  { { { "4000", 4000 }, { "4000", 4000 }, { "4000", 4000 }, { "4000", 4000 } } },
2491 };
2492 
2493 static void blend_vline(uint8_t *dst, int height, int linesize, float o1, float o2, int v, int step)
2494 {
2495  int y;
2496 
2497  for (y = 0; y < height; y += step) {
2498  dst[0] = v * o1 + dst[0] * o2;
2499 
2500  dst += linesize * step;
2501  }
2502 }
2503 
2504 static void blend_vline16(uint8_t *ddst, int height, int linesize, float o1, float o2, int v, int step)
2505 {
2506  uint16_t *dst = (uint16_t *)ddst;
2507  int y;
2508 
2509  for (y = 0; y < height; y += step) {
2510  dst[0] = v * o1 + dst[0] * o2;
2511 
2512  dst += (linesize / 2) * step;
2513  }
2514 }
2515 
2516 static void blend_hline(uint8_t *dst, int width, int unused, float o1, float o2, int v, int step)
2517 {
2518  int x;
2519 
2520  for (x = 0; x < width; x += step) {
2521  dst[x] = v * o1 + dst[x] * o2;
2522  }
2523 }
2524 
2525 static void blend_hline16(uint8_t *ddst, int width, int unused, float o1, float o2, int v, int step)
2526 {
2527  uint16_t *dst = (uint16_t *)ddst;
2528  int x;
2529 
2530  for (x = 0; x < width; x += step) {
2531  dst[x] = v * o1 + dst[x] * o2;
2532  }
2533 }
2534 
2535 static void draw_htext(AVFrame *out, int x, int y, int mult, float o1, float o2, const char *txt, const uint8_t color[4])
2536 {
2537  const uint8_t *font;
2538  int font_height;
2539  int i, plane;
2540 
2541  font = avpriv_cga_font, font_height = 8;
2542 
2543  for (plane = 0; plane < 4 && out->data[plane]; plane++) {
2544  for (i = 0; txt[i]; i++) {
2545  int char_y, mask;
2546  int v = color[plane];
2547 
2548  uint8_t *p = out->data[plane] + y * out->linesize[plane] + (x + i * 8);
2549  for (char_y = 0; char_y < font_height; char_y++) {
2550  for (mask = 0x80; mask; mask >>= 1) {
2551  if (font[txt[i] * font_height + char_y] & mask)
2552  p[0] = p[0] * o2 + v * o1;
2553  p++;
2554  }
2555  p += out->linesize[plane] - 8;
2556  }
2557  }
2558  }
2559 }
2560 
2561 static void draw_htext16(AVFrame *out, int x, int y, int mult, float o1, float o2, const char *txt, const uint8_t color[4])
2562 {
2563  const uint8_t *font;
2564  int font_height;
2565  int i, plane;
2566 
2567  font = avpriv_cga_font, font_height = 8;
2568 
2569  for (plane = 0; plane < 4 && out->data[plane]; plane++) {
2570  for (i = 0; txt[i]; i++) {
2571  int char_y, mask;
2572  int v = color[plane] * mult;
2573 
2574  uint16_t *p = (uint16_t *)(out->data[plane] + y * out->linesize[plane]) + (x + i * 8);
2575  for (char_y = 0; char_y < font_height; char_y++) {
2576  for (mask = 0x80; mask; mask >>= 1) {
2577  if (font[txt[i] * font_height + char_y] & mask)
2578  p[0] = p[0] * o2 + v * o1;
2579  p++;
2580  }
2581  p += out->linesize[plane] / 2 - 8;
2582  }
2583  }
2584  }
2585 }
2586 
2587 static void draw_vtext(AVFrame *out, int x, int y, int mult, float o1, float o2, const char *txt, const uint8_t color[4])
2588 {
2589  const uint8_t *font;
2590  int font_height;
2591  int i, plane;
2592 
2593  font = avpriv_cga_font, font_height = 8;
2594 
2595  for (plane = 0; plane < 4 && out->data[plane]; plane++) {
2596  for (i = 0; txt[i]; i++) {
2597  int char_y, mask;
2598  int v = color[plane];
2599 
2600  for (char_y = font_height - 1; char_y >= 0; char_y--) {
2601  uint8_t *p = out->data[plane] + (y + i * 10) * out->linesize[plane] + x;
2602  for (mask = 0x80; mask; mask >>= 1) {
2603  if (font[txt[i] * font_height + font_height - 1 - char_y] & mask)
2604  p[char_y] = p[char_y] * o2 + v * o1;
2605  p += out->linesize[plane];
2606  }
2607  }
2608  }
2609  }
2610 }
2611 
2612 static void draw_vtext16(AVFrame *out, int x, int y, int mult, float o1, float o2, const char *txt, const uint8_t color[4])
2613 {
2614  const uint8_t *font;
2615  int font_height;
2616  int i, plane;
2617 
2618  font = avpriv_cga_font, font_height = 8;
2619 
2620  for (plane = 0; plane < 4 && out->data[plane]; plane++) {
2621  for (i = 0; txt[i]; i++) {
2622  int char_y, mask;
2623  int v = color[plane] * mult;
2624 
2625  for (char_y = 0; char_y < font_height; char_y++) {
2626  uint16_t *p = (uint16_t *)(out->data[plane] + (y + i * 10) * out->linesize[plane]) + x;
2627  for (mask = 0x80; mask; mask >>= 1) {
2628  if (font[txt[i] * font_height + font_height - 1 - char_y] & mask)
2629  p[char_y] = p[char_y] * o2 + v * o1;
2630  p += out->linesize[plane] / 2;
2631  }
2632  }
2633  }
2634  }
2635 }
2636 
2637 static void iblend_vline(uint8_t *dst, int height, int linesize, float o1, float o2, int v, int step)
2638 {
2639  int y;
2640 
2641  for (y = 0; y < height; y += step) {
2642  dst[0] = (v - dst[0]) * o1 + dst[0] * o2;
2643 
2644  dst += linesize * step;
2645  }
2646 }
2647 
2648 static void iblend_vline16(uint8_t *ddst, int height, int linesize, float o1, float o2, int v, int step)
2649 {
2650  uint16_t *dst = (uint16_t *)ddst;
2651  int y;
2652 
2653  for (y = 0; y < height; y += step) {
2654  dst[0] = (v - dst[0]) * o1 + dst[0] * o2;
2655 
2656  dst += (linesize / 2) * step;
2657  }
2658 }
2659 
2660 static void iblend_hline(uint8_t *dst, int width, int unused, float o1, float o2, int v, int step)
2661 {
2662  int x;
2663 
2664  for (x = 0; x < width; x += step) {
2665  dst[x] = (v - dst[x]) * o1 + dst[x] * o2;
2666  }
2667 }
2668 
2669 static void iblend_hline16(uint8_t *ddst, int width, int unused, float o1, float o2, int v, int step)
2670 {
2671  uint16_t *dst = (uint16_t *)ddst;
2672  int x;
2673 
2674  for (x = 0; x < width; x += step) {
2675  dst[x] = (v - dst[x]) * o1 + dst[x] * o2;
2676  }
2677 }
2678 
2679 static void idraw_htext(AVFrame *out, int x, int y, int mult, float o1, float o2, const char *txt, const uint8_t color[4])
2680 {
2681  const uint8_t *font;
2682  int font_height;
2683  int i, plane;
2684 
2685  font = avpriv_cga_font, font_height = 8;
2686 
2687  for (plane = 0; plane < 4 && out->data[plane]; plane++) {
2688  for (i = 0; txt[i]; i++) {
2689  int char_y, mask;
2690  int v = color[plane];
2691 
2692  uint8_t *p = out->data[plane] + y * out->linesize[plane] + (x + i * 8);
2693  for (char_y = 0; char_y < font_height; char_y++) {
2694  for (mask = 0x80; mask; mask >>= 1) {
2695  if (font[txt[i] * font_height + char_y] & mask)
2696  p[0] = p[0] * o2 + (v - p[0]) * o1;
2697  p++;
2698  }
2699  p += out->linesize[plane] - 8;
2700  }
2701  }
2702  }
2703 }
2704 
2705 static void idraw_htext16(AVFrame *out, int x, int y, int mult, float o1, float o2, const char *txt, const uint8_t color[4])
2706 {
2707  const uint8_t *font;
2708  int font_height;
2709  int i, plane;
2710 
2711  font = avpriv_cga_font, font_height = 8;
2712 
2713  for (plane = 0; plane < 4 && out->data[plane]; plane++) {
2714  for (i = 0; txt[i]; i++) {
2715  int char_y, mask;
2716  int v = color[plane] * mult;
2717 
2718  uint16_t *p = (uint16_t *)(out->data[plane] + y * out->linesize[plane]) + (x + i * 8);
2719  for (char_y = 0; char_y < font_height; char_y++) {
2720  for (mask = 0x80; mask; mask >>= 1) {
2721  if (font[txt[i] * font_height + char_y] & mask)
2722  p[0] = p[0] * o2 + (v - p[0]) * o1;
2723  p++;
2724  }
2725  p += out->linesize[plane] / 2 - 8;
2726  }
2727  }
2728  }
2729 }
2730 
2731 static void idraw_vtext(AVFrame *out, int x, int y, int mult, float o1, float o2, const char *txt, const uint8_t color[4])
2732 {
2733  const uint8_t *font;
2734  int font_height;
2735  int i, plane;
2736 
2737  font = avpriv_cga_font, font_height = 8;
2738 
2739  for (plane = 0; plane < 4 && out->data[plane]; plane++) {
2740  for (i = 0; txt[i]; i++) {
2741  int char_y, mask;
2742  int v = color[plane];
2743 
2744  for (char_y = font_height - 1; char_y >= 0; char_y--) {
2745  uint8_t *p = out->data[plane] + (y + i * 10) * out->linesize[plane] + x;
2746  for (mask = 0x80; mask; mask >>= 1) {
2747  if (font[txt[i] * font_height + font_height - 1 - char_y] & mask)
2748  p[char_y] = p[char_y] * o2 + (v - p[char_y]) * o1;
2749  p += out->linesize[plane];
2750  }
2751  }
2752  }
2753  }
2754 }
2755 
2756 static void idraw_vtext16(AVFrame *out, int x, int y, int mult, float o1, float o2, const char *txt, const uint8_t color[4])
2757 {
2758  const uint8_t *font;
2759  int font_height;
2760  int i, plane;
2761 
2762  font = avpriv_cga_font, font_height = 8;
2763 
2764  for (plane = 0; plane < 4 && out->data[plane]; plane++) {
2765  for (i = 0; txt[i]; i++) {
2766  int char_y, mask;
2767  int v = color[plane] * mult;
2768 
2769  for (char_y = 0; char_y < font_height; char_y++) {
2770  uint16_t *p = (uint16_t *)(out->data[plane] + (y + i * 10) * out->linesize[plane]) + x;
2771  for (mask = 0x80; mask; mask >>= 1) {
2772  if (font[txt[i] * font_height + font_height - 1 - char_y] & mask)
2773  p[char_y] = p[char_y] * o2 + (v - p[char_y]) * o1;
2774  p += out->linesize[plane] / 2;
2775  }
2776  }
2777  }
2778  }
2779 }
2780 
2782 {
2783 }
2784 
2786 {
2787  const int step = (s->flags & 2) + 1;
2788  const float o1 = s->opacity;
2789  const float o2 = 1. - o1;
2790  const int height = s->display == PARADE ? out->height / s->acomp : out->height;
2791  int C, k = 0, c, p, l, offset_x = 0, offset_y = 0;
2792 
2793  for (c = 0; c < s->ncomp; c++) {
2794  if (!((1 << c) & s->pcomp) || (!s->display && k > 0))
2795  continue;
2796 
2797  k++;
2798  C = s->rgb ? 0 : c;
2799  for (p = 0; p < s->ncomp; p++) {
2800  const int v = s->grat_yuva_color[p];
2801  for (l = 0; l < s->nb_glines; l++) {
2802  const uint16_t pos = s->glines[l].line[C].pos;
2803  int x = offset_x + (s->mirror ? s->size - 1 - pos : pos);
2804  uint8_t *dst = out->data[p] + offset_y * out->linesize[p] + x;
2805 
2806  s->blend_line(dst, height, out->linesize[p], o1, o2, v, step);
2807  }
2808  }
2809 
2810  for (l = 0; l < s->nb_glines && (s->flags & 1); l++) {
2811  const char *name = s->glines[l].line[C].name;
2812  const uint16_t pos = s->glines[l].line[C].pos;
2813  int x = offset_x + (s->mirror ? s->size - 1 - pos : pos) - 10;
2814 
2815  if (x < 0)
2816  x = 4;
2817 
2818  s->draw_text(out, x, offset_y + 2, 1, o1, o2, name, s->grat_yuva_color);
2819  }
2820 
2821  offset_x += s->size * (s->display == STACK);
2822  offset_y += height * (s->display == PARADE);
2823  }
2824 }
2825 
2827 {
2828  const int step = (s->flags & 2) + 1;
2829  const float o1 = s->opacity;
2830  const float o2 = 1. - o1;
2831  const int mult = s->max / 256;
2832  const int height = s->display == PARADE ? out->height / s->acomp : out->height;
2833  int C, k = 0, c, p, l, offset_x = 0, offset_y = 0;
2834 
2835  for (c = 0; c < s->ncomp; c++) {
2836  if (!((1 << c) & s->pcomp) || (!s->display && k > 0))
2837  continue;
2838 
2839  k++;
2840  C = s->rgb ? 0 : c;
2841  for (p = 0; p < s->ncomp; p++) {
2842  const int v = s->grat_yuva_color[p] * mult;
2843  for (l = 0; l < s->nb_glines ; l++) {
2844  const uint16_t pos = s->glines[l].line[C].pos;
2845  int x = offset_x + (s->mirror ? s->size - 1 - pos : pos);
2846  uint8_t *dst = (uint8_t *)(out->data[p] + offset_y * out->linesize[p]) + x * 2;
2847 
2848  s->blend_line(dst, height, out->linesize[p], o1, o2, v, step);
2849  }
2850  }
2851 
2852  for (l = 0; l < s->nb_glines && (s->flags & 1); l++) {
2853  const char *name = s->glines[l].line[C].name;
2854  const uint16_t pos = s->glines[l].line[C].pos;
2855  int x = offset_x + (s->mirror ? s->size - 1 - pos : pos) - 10;
2856 
2857  if (x < 0)
2858  x = 4;
2859 
2860  s->draw_text(out, x, offset_y + 2, mult, o1, o2, name, s->grat_yuva_color);
2861  }
2862 
2863  offset_x += s->size * (s->display == STACK);
2864  offset_y += height * (s->display == PARADE);
2865  }
2866 }
2867 
2869 {
2870  const int step = (s->flags & 2) + 1;
2871  const float o1 = s->opacity;
2872  const float o2 = 1. - o1;
2873  const int width = s->display == PARADE ? out->width / s->acomp : out->width;
2874  int C, k = 0, c, p, l, offset_y = 0, offset_x = 0;
2875 
2876  for (c = 0; c < s->ncomp; c++) {
2877  if ((!((1 << c) & s->pcomp) || (!s->display && k > 0)))
2878  continue;
2879 
2880  k++;
2881  C = s->rgb ? 0 : c;
2882  for (p = 0; p < s->ncomp; p++) {
2883  const int v = s->grat_yuva_color[p];
2884  for (l = 0; l < s->nb_glines ; l++) {
2885  const uint16_t pos = s->glines[l].line[C].pos;
2886  int y = offset_y + (s->mirror ? s->size - 1 - pos : pos);
2887  uint8_t *dst = out->data[p] + y * out->linesize[p] + offset_x;
2888 
2889  s->blend_line(dst, width, 1, o1, o2, v, step);
2890  }
2891  }
2892 
2893  for (l = 0; l < s->nb_glines && (s->flags & 1); l++) {
2894  const char *name = s->glines[l].line[C].name;
2895  const uint16_t pos = s->glines[l].line[C].pos;
2896  int y = offset_y + (s->mirror ? s->size - 1 - pos : pos) - 10;
2897 
2898  if (y < 0)
2899  y = 4;
2900 
2901  s->draw_text(out, 2 + offset_x, y, 1, o1, o2, name, s->grat_yuva_color);
2902  }
2903 
2904  offset_y += s->size * (s->display == STACK);
2905  offset_x += width * (s->display == PARADE);
2906  }
2907 }
2908 
2910 {
2911  const int step = (s->flags & 2) + 1;
2912  const float o1 = s->opacity;
2913  const float o2 = 1. - o1;
2914  const int mult = s->max / 256;
2915  const int width = s->display == PARADE ? out->width / s->acomp : out->width;
2916  int C, k = 0, c, p, l, offset_x = 0, offset_y = 0;
2917 
2918  for (c = 0; c < s->ncomp; c++) {
2919  if ((!((1 << c) & s->pcomp) || (!s->display && k > 0)))
2920  continue;
2921 
2922  k++;
2923  C = s->rgb ? 0 : c;
2924  for (p = 0; p < s->ncomp; p++) {
2925  const int v = s->grat_yuva_color[p] * mult;
2926  for (l = 0; l < s->nb_glines ; l++) {
2927  const uint16_t pos = s->glines[l].line[C].pos;
2928  int y = offset_y + (s->mirror ? s->size - 1 - pos : pos);
2929  uint8_t *dst = (uint8_t *)(out->data[p] + y * out->linesize[p]) + offset_x * 2;
2930 
2931  s->blend_line(dst, width, 1, o1, o2, v, step);
2932  }
2933  }
2934 
2935  for (l = 0; l < s->nb_glines && (s->flags & 1); l++) {
2936  const char *name = s->glines[l].line[C].name;
2937  const uint16_t pos = s->glines[l].line[C].pos;
2938  int y = offset_y + (s->mirror ? s->size - 1 - pos: pos) - 10;
2939 
2940  if (y < 0)
2941  y = 4;
2942 
2943  s->draw_text(out, 2 + offset_x, y, mult, o1, o2, name, s->grat_yuva_color);
2944  }
2945 
2946  offset_y += s->size * (s->display == STACK);
2947  offset_x += width * (s->display == PARADE);
2948  }
2949 }
2950 
2952 {
2953  AVFilterContext *ctx = inlink->dst;
2954  WaveformContext *s = ctx->priv;
2955 
2956  s->desc = av_pix_fmt_desc_get(inlink->format);
2957  s->ncomp = s->desc->nb_components;
2958  s->bits = s->desc->comp[0].depth;
2959  s->max = 1 << s->bits;
2960  s->intensity = s->fintensity * (s->max - 1);
2961 
2962  s->shift_w[0] = s->shift_w[3] = 0;
2963  s->shift_h[0] = s->shift_h[3] = 0;
2964  s->shift_w[1] = s->shift_w[2] = s->desc->log2_chroma_w;
2965  s->shift_h[1] = s->shift_h[2] = s->desc->log2_chroma_h;
2966 
2968 
2969  switch (s->filter) {
2970  case XFLAT:
2971  case YFLAT:
2972  case AFLAT: s->size = 256 * 2; break;
2973  case FLAT: s->size = 256 * 3; break;
2974  default: s->size = 256; break;
2975  }
2976 
2977  switch (s->filter | ((s->bits > 8) << 4) |
2978  (s->mode << 8) | (s->mirror << 12)) {
2979  case 0x1100: s->waveform_slice = lowpass_column_mirror; break;
2980  case 0x1000: s->waveform_slice = lowpass_row_mirror; break;
2981  case 0x0100: s->waveform_slice = lowpass_column; break;
2982  case 0x0000: s->waveform_slice = lowpass_row; break;
2983  case 0x1110: s->waveform_slice = lowpass16_column_mirror; break;
2984  case 0x1010: s->waveform_slice = lowpass16_row_mirror; break;
2985  case 0x0110: s->waveform_slice = lowpass16_column; break;
2986  case 0x0010: s->waveform_slice = lowpass16_row; break;
2987  case 0x1101: s->waveform_slice = flat_column_mirror; break;
2988  case 0x1001: s->waveform_slice = flat_row_mirror; break;
2989  case 0x0101: s->waveform_slice = flat_column; break;
2990  case 0x0001: s->waveform_slice = flat_row; break;
2991  case 0x1111: s->waveform_slice = flat16_column_mirror; break;
2992  case 0x1011: s->waveform_slice = flat16_row_mirror; break;
2993  case 0x0111: s->waveform_slice = flat16_column; break;
2994  case 0x0011: s->waveform_slice = flat16_row; break;
2995  case 0x1102: s->waveform_slice = aflat_column_mirror; break;
2996  case 0x1002: s->waveform_slice = aflat_row_mirror; break;
2997  case 0x0102: s->waveform_slice = aflat_column; break;
2998  case 0x0002: s->waveform_slice = aflat_row; break;
2999  case 0x1112: s->waveform_slice = aflat16_column_mirror; break;
3000  case 0x1012: s->waveform_slice = aflat16_row_mirror; break;
3001  case 0x0112: s->waveform_slice = aflat16_column; break;
3002  case 0x0012: s->waveform_slice = aflat16_row; break;
3003  case 0x1103: s->waveform_slice = chroma_column_mirror; break;
3004  case 0x1003: s->waveform_slice = chroma_row_mirror; break;
3005  case 0x0103: s->waveform_slice = chroma_column; break;
3006  case 0x0003: s->waveform_slice = chroma_row; break;
3007  case 0x1113: s->waveform_slice = chroma16_column_mirror; break;
3008  case 0x1013: s->waveform_slice = chroma16_row_mirror; break;
3009  case 0x0113: s->waveform_slice = chroma16_column; break;
3010  case 0x0013: s->waveform_slice = chroma16_row; break;
3011  case 0x1104: s->waveform_slice = color_column_mirror; break;
3012  case 0x1004: s->waveform_slice = color_row_mirror; break;
3013  case 0x0104: s->waveform_slice = color_column; break;
3014  case 0x0004: s->waveform_slice = color_row; break;
3015  case 0x1114: s->waveform_slice = color16_column_mirror; break;
3016  case 0x1014: s->waveform_slice = color16_row_mirror; break;
3017  case 0x0114: s->waveform_slice = color16_column; break;
3018  case 0x0014: s->waveform_slice = color16_row; break;
3019  case 0x1105: s->waveform_slice = acolor_column_mirror; break;
3020  case 0x1005: s->waveform_slice = acolor_row_mirror; break;
3021  case 0x0105: s->waveform_slice = acolor_column; break;
3022  case 0x0005: s->waveform_slice = acolor_row; break;
3023  case 0x1115: s->waveform_slice = acolor16_column_mirror; break;
3024  case 0x1015: s->waveform_slice = acolor16_row_mirror; break;
3025  case 0x0115: s->waveform_slice = acolor16_column; break;
3026  case 0x0015: s->waveform_slice = acolor16_row; break;
3027  case 0x1106: s->waveform_slice = xflat_column_mirror; break;
3028  case 0x1006: s->waveform_slice = xflat_row_mirror; break;
3029  case 0x0106: s->waveform_slice = xflat_column; break;
3030  case 0x0006: s->waveform_slice = xflat_row; break;
3031  case 0x1116: s->waveform_slice = xflat16_column_mirror; break;
3032  case 0x1016: s->waveform_slice = xflat16_row_mirror; break;
3033  case 0x0116: s->waveform_slice = xflat16_column; break;
3034  case 0x0016: s->waveform_slice = xflat16_row; break;
3035  case 0x1107: s->waveform_slice = yflat_column_mirror; break;
3036  case 0x1007: s->waveform_slice = yflat_row_mirror; break;
3037  case 0x0107: s->waveform_slice = yflat_column; break;
3038  case 0x0007: s->waveform_slice = yflat_row; break;
3039  case 0x1117: s->waveform_slice = yflat16_column_mirror; break;
3040  case 0x1017: s->waveform_slice = yflat16_row_mirror; break;
3041  case 0x0117: s->waveform_slice = yflat16_column; break;
3042  case 0x0017: s->waveform_slice = yflat16_row; break;
3043  }
3044 
3045  s->grat_yuva_color[0] = 255;
3046  s->grat_yuva_color[1] = s->graticule == GRAT_INVERT ? 255 : 0;
3047  s->grat_yuva_color[2] = s->graticule == GRAT_ORANGE || s->graticule == GRAT_INVERT ? 255 : 0;
3048  s->grat_yuva_color[3] = 255;
3049 
3050  if (s->mode == 0 && s->graticule != GRAT_INVERT) {
3051  s->blend_line = s->bits <= 8 ? blend_vline : blend_vline16;
3052  s->draw_text = s->bits <= 8 ? draw_vtext : draw_vtext16;
3053  } else if (s->graticule != GRAT_INVERT) {
3054  s->blend_line = s->bits <= 8 ? blend_hline : blend_hline16;
3055  s->draw_text = s->bits <= 8 ? draw_htext : draw_htext16;
3056  } else if (s->mode == 0 && s->graticule == GRAT_INVERT) {
3057  s->blend_line = s->bits <= 8 ? iblend_vline : iblend_vline16;
3058  s->draw_text = s->bits <= 8 ? idraw_vtext : idraw_vtext16;
3059  } else if (s->graticule == GRAT_INVERT) {
3060  s->blend_line = s->bits <= 8 ? iblend_hline : iblend_hline16;
3061  s->draw_text = s->bits <= 8 ? idraw_htext : idraw_htext16;
3062  }
3063 
3064  switch (s->filter) {
3065  case LOWPASS:
3066  case COLOR:
3067  case ACOLOR:
3068  case CHROMA:
3069  case AFLAT:
3070  case XFLAT:
3071  case YFLAT:
3072  case FLAT:
3073  if (s->graticule > GRAT_NONE && s->mode == 1)
3075  else if (s->graticule > GRAT_NONE && s->mode == 0)
3076  s->graticulef = s->bits > 8 ? graticule16_row : graticule_row;
3077  break;
3078  }
3079 
3080  switch (s->filter) {
3081  case COLOR:
3082  case ACOLOR:
3083  case LOWPASS:
3084  switch (s->scale) {
3085  case DIGITAL:
3086  switch (s->bits) {
3087  case 8: s->glines = (GraticuleLines *)digital8; s->nb_glines = FF_ARRAY_ELEMS(digital8); break;
3088  case 9: s->glines = (GraticuleLines *)digital9; s->nb_glines = FF_ARRAY_ELEMS(digital9); break;
3089  case 10: s->glines = (GraticuleLines *)digital10; s->nb_glines = FF_ARRAY_ELEMS(digital10); break;
3090  case 12: s->glines = (GraticuleLines *)digital12; s->nb_glines = FF_ARRAY_ELEMS(digital12); break;
3091  }
3092  break;
3093  case MILLIVOLTS:
3094  switch (s->bits) {
3095  case 8: s->glines = (GraticuleLines *)millivolts8; s->nb_glines = FF_ARRAY_ELEMS(millivolts8); break;
3096  case 9: s->glines = (GraticuleLines *)millivolts9; s->nb_glines = FF_ARRAY_ELEMS(millivolts9); break;
3097  case 10: s->glines = (GraticuleLines *)millivolts10; s->nb_glines = FF_ARRAY_ELEMS(millivolts10); break;
3098  case 12: s->glines = (GraticuleLines *)millivolts12; s->nb_glines = FF_ARRAY_ELEMS(millivolts12); break;
3099  }
3100  break;
3101  case IRE:
3102  switch (s->bits) {
3103  case 8: s->glines = (GraticuleLines *)ire8; s->nb_glines = FF_ARRAY_ELEMS(ire8); break;
3104  case 9: s->glines = (GraticuleLines *)ire9; s->nb_glines = FF_ARRAY_ELEMS(ire9); break;
3105  case 10: s->glines = (GraticuleLines *)ire10; s->nb_glines = FF_ARRAY_ELEMS(ire10); break;
3106  case 12: s->glines = (GraticuleLines *)ire12; s->nb_glines = FF_ARRAY_ELEMS(ire12); break;
3107  }
3108  break;
3109  }
3110  break;
3111  case CHROMA:
3112  switch (s->scale) {
3113  case DIGITAL:
3114  switch (s->bits) {
3115  case 8: s->glines = (GraticuleLines *)chroma_digital8; s->nb_glines = FF_ARRAY_ELEMS(chroma_digital8); break;
3116  case 9: s->glines = (GraticuleLines *)chroma_digital9; s->nb_glines = FF_ARRAY_ELEMS(chroma_digital9); break;
3117  case 10: s->glines = (GraticuleLines *)chroma_digital10; s->nb_glines = FF_ARRAY_ELEMS(chroma_digital10); break;
3118  case 12: s->glines = (GraticuleLines *)chroma_digital12; s->nb_glines = FF_ARRAY_ELEMS(chroma_digital12); break;
3119  }
3120  break;
3121  case MILLIVOLTS:
3122  switch (s->bits) {
3123  case 8: s->glines = (GraticuleLines *)millivolts8; s->nb_glines = FF_ARRAY_ELEMS(millivolts8); break;
3124  case 9: s->glines = (GraticuleLines *)millivolts9; s->nb_glines = FF_ARRAY_ELEMS(millivolts9); break;
3125  case 10: s->glines = (GraticuleLines *)millivolts10; s->nb_glines = FF_ARRAY_ELEMS(millivolts10); break;
3126  case 12: s->glines = (GraticuleLines *)millivolts12; s->nb_glines = FF_ARRAY_ELEMS(millivolts12); break;
3127  }
3128  break;
3129  case IRE:
3130  switch (s->bits) {
3131  case 8: s->glines = (GraticuleLines *)ire8; s->nb_glines = FF_ARRAY_ELEMS(ire8); break;
3132  case 9: s->glines = (GraticuleLines *)ire9; s->nb_glines = FF_ARRAY_ELEMS(ire9); break;
3133  case 10: s->glines = (GraticuleLines *)ire10; s->nb_glines = FF_ARRAY_ELEMS(ire10); break;
3134  case 12: s->glines = (GraticuleLines *)ire12; s->nb_glines = FF_ARRAY_ELEMS(ire12); break;
3135  }
3136  break;
3137  }
3138  break;
3139  case XFLAT:
3140  case YFLAT:
3141  case AFLAT:
3142  switch (s->scale) {
3143  case DIGITAL:
3144  switch (s->bits) {
3145  case 8: s->glines = (GraticuleLines *)aflat_digital8; s->nb_glines = FF_ARRAY_ELEMS(aflat_digital8); break;
3146  case 9: s->glines = (GraticuleLines *)aflat_digital9; s->nb_glines = FF_ARRAY_ELEMS(aflat_digital9); break;
3147  case 10: s->glines = (GraticuleLines *)aflat_digital10; s->nb_glines = FF_ARRAY_ELEMS(aflat_digital10); break;
3148  case 12: s->glines = (GraticuleLines *)aflat_digital12; s->nb_glines = FF_ARRAY_ELEMS(aflat_digital12); break;
3149  }
3150  break;
3151  case MILLIVOLTS:
3152  switch (s->bits) {
3153  case 8: s->glines = (GraticuleLines *)aflat_millivolts8; s->nb_glines = FF_ARRAY_ELEMS(aflat_millivolts8); break;
3154  case 9: s->glines = (GraticuleLines *)aflat_millivolts9; s->nb_glines = FF_ARRAY_ELEMS(aflat_millivolts9); break;
3155  case 10: s->glines = (GraticuleLines *)aflat_millivolts10; s->nb_glines = FF_ARRAY_ELEMS(aflat_millivolts10); break;
3156  case 12: s->glines = (GraticuleLines *)aflat_millivolts12; s->nb_glines = FF_ARRAY_ELEMS(aflat_millivolts12); break;
3157  }
3158  break;
3159  case IRE:
3160  switch (s->bits) {
3161  case 8: s->glines = (GraticuleLines *)aflat_ire8; s->nb_glines = FF_ARRAY_ELEMS(aflat_ire8); break;
3162  case 9: s->glines = (GraticuleLines *)aflat_ire9; s->nb_glines = FF_ARRAY_ELEMS(aflat_ire9); break;
3163  case 10: s->glines = (GraticuleLines *)aflat_ire10; s->nb_glines = FF_ARRAY_ELEMS(aflat_ire10); break;
3164  case 12: s->glines = (GraticuleLines *)aflat_ire12; s->nb_glines = FF_ARRAY_ELEMS(aflat_ire12); break;
3165  }
3166  break;
3167  }
3168  break;
3169  case FLAT:
3170  switch (s->scale) {
3171  case DIGITAL:
3172  switch (s->bits) {
3173  case 8: s->glines = (GraticuleLines *)flat_digital8; s->nb_glines = FF_ARRAY_ELEMS(flat_digital8); break;
3174  case 9: s->glines = (GraticuleLines *)flat_digital9; s->nb_glines = FF_ARRAY_ELEMS(flat_digital9); break;
3175  case 10: s->glines = (GraticuleLines *)flat_digital10; s->nb_glines = FF_ARRAY_ELEMS(flat_digital10); break;
3176  case 12: s->glines = (GraticuleLines *)flat_digital12; s->nb_glines = FF_ARRAY_ELEMS(flat_digital12); break;
3177  }
3178  break;
3179  case MILLIVOLTS:
3180  switch (s->bits) {
3181  case 8: s->glines = (GraticuleLines *)flat_millivolts8; s->nb_glines = FF_ARRAY_ELEMS(flat_millivolts8); break;
3182  case 9: s->glines = (GraticuleLines *)flat_millivolts9; s->nb_glines = FF_ARRAY_ELEMS(flat_millivolts9); break;
3183  case 10: s->glines = (GraticuleLines *)flat_millivolts10; s->nb_glines = FF_ARRAY_ELEMS(flat_millivolts10); break;
3184  case 12: s->glines = (GraticuleLines *)flat_millivolts12; s->nb_glines = FF_ARRAY_ELEMS(flat_millivolts12); break;
3185  }
3186  break;
3187  case IRE:
3188  switch (s->bits) {
3189  case 8: s->glines = (GraticuleLines *)flat_ire8; s->nb_glines = FF_ARRAY_ELEMS(flat_ire8); break;
3190  case 9: s->glines = (GraticuleLines *)flat_ire9; s->nb_glines = FF_ARRAY_ELEMS(flat_ire9); break;
3191  case 10: s->glines = (GraticuleLines *)flat_ire10; s->nb_glines = FF_ARRAY_ELEMS(flat_ire10); break;
3192  case 12: s->glines = (GraticuleLines *)flat_ire12; s->nb_glines = FF_ARRAY_ELEMS(flat_ire12); break;
3193  }
3194  break;
3195  }
3196  break;
3197  }
3198 
3199  s->size = s->size << (s->bits - 8);
3200 
3201  switch (inlink->format) {
3202  case AV_PIX_FMT_GBRAP:
3203  case AV_PIX_FMT_GBRP:
3204  case AV_PIX_FMT_GBRP9:
3205  case AV_PIX_FMT_GBRP10:
3206  case AV_PIX_FMT_GBRP12:
3207  s->rgb = 1;
3208  memcpy(s->bg_color, black_gbrp_color, sizeof(s->bg_color));
3209  break;
3210  default:
3211  memcpy(s->bg_color, black_yuva_color, sizeof(s->bg_color));
3212  }
3213 
3214  s->bg_color[3] *= s->bgopacity;
3215 
3216  return 0;
3217 }
3218 
3219 static int config_output(AVFilterLink *outlink)
3220 {
3221  AVFilterContext *ctx = outlink->src;
3222  AVFilterLink *inlink = ctx->inputs[0];
3223  WaveformContext *s = ctx->priv;
3224  int comp = 0, i, j = 0, k, p, size;
3225 
3226  for (i = 0; i < s->ncomp; i++) {
3227  if ((1 << i) & s->pcomp)
3228  comp++;
3229  }
3230  s->acomp = comp;
3231  if (s->acomp == 0)
3232  return AVERROR(EINVAL);
3233 
3234  s->odesc = av_pix_fmt_desc_get(outlink->format);
3235  s->dcomp = s->odesc->nb_components;
3236 
3237  av_freep(&s->peak);
3238 
3239  if (s->mode) {
3240  outlink->h = s->size * FFMAX(comp * (s->display == STACK), 1);
3241  outlink->w = inlink->w * FFMAX(comp * (s->display == PARADE), 1);
3242  size = inlink->w;
3243  } else {
3244  outlink->w = s->size * FFMAX(comp * (s->display == STACK), 1);
3245  outlink->h = inlink->h * FFMAX(comp * (s->display == PARADE), 1);
3246  size = inlink->h;
3247  }
3248 
3249  s->peak = av_malloc_array(size, 32 * sizeof(*s->peak));
3250  if (!s->peak)
3251  return AVERROR(ENOMEM);
3252 
3253  for (p = 0; p < s->ncomp; p++) {
3254  const int plane = s->desc->comp[p].plane;
3255  int offset;
3256 
3257  if (!((1 << p) & s->pcomp))
3258  continue;
3259 
3260  for (k = 0; k < 4; k++) {
3261  s->emax[plane][k] = s->peak + size * (plane * 4 + k + 0);
3262  s->emin[plane][k] = s->peak + size * (plane * 4 + k + 16);
3263  }
3264 
3265  offset = j++ * s->size * (s->display == STACK);
3266  s->estart[plane] = offset;
3267  s->eend[plane] = (offset + s->size - 1);
3268  for (i = 0; i < size; i++) {
3269  for (k = 0; k < 4; k++) {
3270  s->emax[plane][k][i] = s->estart[plane];
3271  s->emin[plane][k][i] = s->eend[plane];
3272  }
3273  }
3274  }
3275 
3276  outlink->sample_aspect_ratio = (AVRational){1,1};
3277 
3278  return 0;
3279 }
3280 
3282 {
3283  AVFilterContext *ctx = inlink->dst;
3284  WaveformContext *s = ctx->priv;
3285  AVFilterLink *outlink = ctx->outputs[0];
3286  AVFrame *out;
3287  int i, j, k;
3288 
3289  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
3290  if (!out) {
3291  av_frame_free(&in);
3292  return AVERROR(ENOMEM);
3293  }
3294  out->pts = in->pts;
3296 
3297  for (k = 0; k < s->dcomp; k++) {
3298  if (s->bits <= 8) {
3299  for (i = 0; i < outlink->h ; i++)
3300  memset(out->data[s->odesc->comp[k].plane] +
3301  i * out->linesize[s->odesc->comp[k].plane],
3302  s->bg_color[k], outlink->w);
3303  } else {
3304  const int mult = s->max / 256;
3305  uint16_t *dst = (uint16_t *)out->data[s->odesc->comp[k].plane];
3306 
3307  for (i = 0; i < outlink->h ; i++) {
3308  for (j = 0; j < outlink->w; j++)
3309  dst[j] = s->bg_color[k] * mult;
3310  dst += out->linesize[s->odesc->comp[k].plane] / 2;
3311  }
3312  }
3313  }
3314 
3315  for (k = 0, i = 0; k < s->ncomp; k++) {
3316  if ((1 << k) & s->pcomp) {
3317  const int plane = s->desc->comp[k].plane;
3318  ThreadData td;
3319  int offset_y;
3320  int offset_x;
3321 
3322  if (s->display == PARADE) {
3323  offset_x = s->mode ? i++ * inlink->w : 0;
3324  offset_y = s->mode ? 0 : i++ * inlink->h;
3325  } else {
3326  offset_y = s->mode ? i++ * s->size * !!s->display : 0;
3327  offset_x = s->mode ? 0 : i++ * s->size * !!s->display;
3328  }
3329 
3330  td.in = in;
3331  td.out = out;
3332  td.component = k;
3333  td.offset_y = offset_y;
3334  td.offset_x = offset_x;
3335  ctx->internal->execute(ctx, s->waveform_slice, &td, NULL, ff_filter_get_nb_threads(ctx));
3336  switch (s->filter) {
3337  case ACOLOR:
3338  case CHROMA:
3339  case COLOR:
3340  case LOWPASS:
3341  if (s->bits <= 8)
3342  envelope(s, out, plane, plane, s->mode ? offset_x : offset_y);
3343  else
3344  envelope16(s, out, plane, plane, s->mode ? offset_x : offset_y);
3345  break;
3346  case FLAT:
3347  if (s->bits <= 8) {
3348  envelope(s, out, plane, plane, s->mode ? offset_x : offset_y);
3349  envelope(s, out, plane, (plane + 1) % s->ncomp, s->mode ? offset_x : offset_y);
3350  } else {
3351  envelope16(s, out, plane, plane, s->mode ? offset_x : offset_y);
3352  envelope16(s, out, plane, (plane + 1) % s->ncomp, s->mode ? offset_x : offset_y);
3353  }
3354  break;
3355  case AFLAT:
3356  case XFLAT:
3357  case YFLAT:
3358  if (s->bits <= 8) {
3359  envelope(s, out, plane, (plane + 0) % s->ncomp, s->mode ? offset_x : offset_y);
3360  envelope(s, out, plane, (plane + 1) % s->ncomp, s->mode ? offset_x : offset_y);
3361  envelope(s, out, plane, (plane + 2) % s->ncomp, s->mode ? offset_x : offset_y);
3362  } else {
3363  envelope16(s, out, plane, (plane + 0) % s->ncomp, s->mode ? offset_x : offset_y);
3364  envelope16(s, out, plane, (plane + 1) % s->ncomp, s->mode ? offset_x : offset_y);
3365  envelope16(s, out, plane, (plane + 2) % s->ncomp, s->mode ? offset_x : offset_y);
3366  }
3367  break;
3368  }
3369  }
3370  }
3371  s->graticulef(s, out);
3372 
3373  av_frame_free(&in);
3374  return ff_filter_frame(outlink, out);
3375 }
3376 
3378 {
3379  WaveformContext *s = ctx->priv;
3380 
3381  av_freep(&s->peak);
3382 }
3383 
3384 static const AVFilterPad inputs[] = {
3385  {
3386  .name = "default",
3387  .type = AVMEDIA_TYPE_VIDEO,
3388  .filter_frame = filter_frame,
3389  .config_props = config_input,
3390  },
3391  { NULL }
3392 };
3393 
3394 static const AVFilterPad outputs[] = {
3395  {
3396  .name = "default",
3397  .type = AVMEDIA_TYPE_VIDEO,
3398  .config_props = config_output,
3399  },
3400  { NULL }
3401 };
3402 
3404  .name = "waveform",
3405  .description = NULL_IF_CONFIG_SMALL("Video waveform monitor."),
3406  .priv_size = sizeof(WaveformContext),
3407  .priv_class = &waveform_class,
3409  .uninit = uninit,
3410  .inputs = inputs,
3411  .outputs = outputs,
3413 };
int plane
Which of the 4 planes contains the component.
Definition: pixdesc.h:35
static const GraticuleLines aflat_digital10[]
Definition: vf_waveform.c:2193
#define NULL
Definition: coverity.c:32
AVFrame * out
Definition: af_adeclick.c:488
#define AV_PIX_FMT_YUVA422P9
Definition: pixfmt.h:422
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2522
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
AVOption.
Definition: opt.h:246
#define AV_PIX_FMT_YUVA420P10
Definition: pixfmt.h:424
#define CHROMA_FUNC(name, column, mirror)
Definition: vf_waveform.c:1621
static void envelope16(WaveformContext *s, AVFrame *out, int plane, int component, int offset)
Definition: vf_waveform.c:619
#define AV_PIX_FMT_GBRAP10
Definition: pixfmt.h:407
static av_always_inline void acolor16(WaveformContext *s, AVFrame *in, AVFrame *out, int component, int intensity, int offset_y, int offset_x, int column, int mirror, int jobnr, int nb_jobs)
Definition: vf_waveform.c:1911
#define AV_PIX_FMT_YUVA422P10
Definition: pixfmt.h:425
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:71
Main libavfilter public API header.
static const GraticuleLines digital8[]
Definition: vf_waveform.c:2373
static const GraticuleLines aflat_ire9[]
Definition: vf_waveform.c:2247
#define CHROMA16_FUNC(name, column, mirror)
Definition: vf_waveform.c:1517
static int config_input(AVFilterLink *inlink)
Definition: vf_waveform.c:2951
#define FLAT16_FUNC(name, column, mirror)
Definition: vf_waveform.c:982
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:168
#define AV_PIX_FMT_GBRP10
Definition: pixfmt.h:403
static const GraticuleLines flat_millivolts10[]
Definition: vf_waveform.c:2317
static void update(uint8_t *target, int max, int intensity)
Definition: vf_waveform.c:649
static int config_output(AVFilterLink *outlink)
Definition: vf_waveform.c:3219
static enum AVPixelFormat in_color_pix_fmts[]
Definition: vf_waveform.c:205
static enum AVPixelFormat in_lowpass_pix_fmts[]
Definition: vf_waveform.c:187
static const GraticuleLines ire12[]
Definition: vf_waveform.c:2453
static const AVFilterPad inputs[]
Definition: vf_waveform.c:3384
static av_always_inline void acolor(WaveformContext *s, AVFrame *in, AVFrame *out, int component, int intensity, int offset_y, int offset_x, int column, int mirror, int jobnr, int nb_jobs)
Definition: vf_waveform.c:2045
#define AV_PIX_FMT_GRAY9
Definition: pixfmt.h:367
static const GraticuleLines flat_millivolts12[]
Definition: vf_waveform.c:2325
static void blend_line(uint8_t *dst, unsigned src, unsigned alpha, int dx, int w, unsigned hsub, int left, int right)
Definition: drawutils.c:398
#define AV_PIX_FMT_YUV420P12
Definition: pixfmt.h:391
static const GraticuleLines aflat_millivolts9[]
Definition: vf_waveform.c:2213
static const GraticuleLines ire10[]
Definition: vf_waveform.c:2445
GraticuleType
Definition: vf_waveform.c:66
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:99
static const GraticuleLines flat_ire9[]
Definition: vf_waveform.c:2343
static const GraticuleLines chroma_digital8[]
Definition: vf_waveform.c:2461
static enum AVPixelFormat out_yuv9_lowpass_pix_fmts[]
Definition: vf_waveform.c:262
static enum AVPixelFormat in_flat_pix_fmts[]
Definition: vf_waveform.c:222
static void graticule16_row(WaveformContext *s, AVFrame *out)
Definition: vf_waveform.c:2826
#define ACOLOR_FUNC(name, column, mirror)
Definition: vf_waveform.c:2153
static const GraticuleLines flat_ire12[]
Definition: vf_waveform.c:2363
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:92
static const GraticuleLines aflat_digital12[]
Definition: vf_waveform.c:2199
void(* draw_text)(AVFrame *out, int x, int y, int mult, float o1, float o2, const char *txt, const uint8_t color[4])
Definition: vf_waveform.c:121
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:283
#define AV_PIX_FMT_GRAY10
Definition: pixfmt.h:368
static enum AVPixelFormat out_gray9_lowpass_pix_fmts[]
Definition: vf_waveform.c:282
const char * name
Pad name.
Definition: internal.h:60
#define AV_PIX_FMT_GRAY12
Definition: pixfmt.h:369
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:346
#define FLAGS
Definition: vf_waveform.c:129
FilterType
uint8_t grat_yuva_color[4]
Definition: vf_waveform.c:110
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1093
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition: pixfmt.h:101
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:117
uint8_t
static void blend_hline(uint8_t *dst, int width, int unused, float o1, float o2, int v, int step)
Definition: vf_waveform.c:2516
#define av_cold
Definition: attributes.h:82
#define LOWPASS16_FUNC(name, column, mirror)
Definition: vf_waveform.c:735
void(* graticulef)(struct WaveformContext *s, AVFrame *out)
Definition: vf_waveform.c:118
AVOptions.
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
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
static int query_formats(AVFilterContext *ctx)
Definition: vf_waveform.c:304
static const uint8_t black_gbrp_color[4]
Definition: vf_waveform.c:2179
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:388
#define ACOLOR16_FUNC(name, column, mirror)
Definition: vf_waveform.c:2020
static const GraticuleLines aflat_millivolts10[]
Definition: vf_waveform.c:2221
int offset_y
Definition: vf_waveform.c:36
#define AV_PIX_FMT_YUVA420P9
Definition: pixfmt.h:421
#define AV_PIX_FMT_GBRP9
Definition: pixfmt.h:402
static void blend_vline(uint8_t *dst, int height, int linesize, float o1, float o2, int v, int step)
Definition: vf_waveform.c:2493
int height
Definition: vf_avgblur.c:61
static void graticule_row(WaveformContext *s, AVFrame *out)
Definition: vf_waveform.c:2785
static void draw_vtext16(AVFrame *out, int x, int y, int mult, float o1, float o2, const char *txt, const uint8_t color[4])
Definition: vf_waveform.c:2612
#define LOWPASS_FUNC(name, column, mirror)
Definition: vf_waveform.c:843
AVFilter ff_vf_waveform
Definition: vf_waveform.c:3403
AVFrame * dst
Definition: vf_blend.c:55
int plane
Definition: vf_blend.c:57
planar YUV 4:4:0 full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV440P and setting color_range...
Definition: pixfmt.h:100
static void update16(uint16_t *target, int max, int intensity, int limit)
Definition: vf_waveform.c:641
static av_always_inline void lowpass(WaveformContext *s, AVFrame *in, AVFrame *out, int component, int intensity, int offset_y, int offset_x, int column, int mirror, int jobnr, int nb_jobs)
Definition: vf_waveform.c:760
static const uint64_t c1
Definition: murmur3.c:49
planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting col...
Definition: pixfmt.h:79
int linesize
Definition: vf_avgblur.c:64
ptrdiff_t size
Definition: opengl_enc.c:100
static const GraticuleLines chroma_digital10[]
Definition: vf_waveform.c:2477
#define AV_PIX_FMT_YUV422P12
Definition: pixfmt.h:392
static void iblend_vline(uint8_t *dst, int height, int linesize, float o1, float o2, int v, int step)
Definition: vf_waveform.c:2637
A filter pad used for either input or output.
Definition: internal.h:54
static enum AVPixelFormat out_gray8_lowpass_pix_fmts[]
Definition: vf_waveform.c:277
static const GraticuleLines flat_digital9[]
Definition: vf_waveform.c:2283
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
Definition: pixfmt.h:176
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
int width
Definition: frame.h:353
#define td
Definition: regdef.h:70
int step
Definition: vf_remap.c:77
const uint8_t avpriv_cga_font[2048]
Definition: xga_font_data.c:29
static const GraticuleLines aflat_ire10[]
Definition: vf_waveform.c:2257
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:101
static void iblend_hline(uint8_t *dst, int width, int unused, float o1, float o2, int v, int step)
Definition: vf_waveform.c:2660
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce then the filter should push the output frames on the output link immediately As an exception to the previous rule if the input frame is enough to produce several output frames then the filter needs output only at least one per link The additional frames can be left buffered in the filter
DisplayType
Definition: vf_waveform.c:52
static enum AVPixelFormat out_yuv12_lowpass_pix_fmts[]
Definition: vf_waveform.c:272
static void mirror(const float *modifier, float *vec)
Definition: vf_v360.c:2419
struct GraticuleLine line[4]
Definition: vf_waveform.c:80
static void blend_hline16(uint8_t *ddst, int width, int unused, float o1, float o2, int v, int step)
Definition: vf_waveform.c:2525
AVFILTER_DEFINE_CLASS(waveform)
static av_always_inline void chroma(WaveformContext *s, AVFrame *in, AVFrame *out, int component, int intensity, int offset_y, int offset_x, int column, int mirror, int jobnr, int nb_jobs)
Definition: vf_waveform.c:1542
#define AV_PIX_FMT_FLAG_RGB
The pixel format contains RGB-like data (as opposed to YUV/grayscale).
Definition: pixdesc.h:148
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:202
ScaleType
Definition: vf_waveform.c:59
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
static av_always_inline void flat16(WaveformContext *s, AVFrame *in, AVFrame *out, int component, int intensity, int offset_y, int offset_x, int column, int mirror, int jobnr, int nb_jobs)
Definition: vf_waveform.c:868
static const GraticuleLines flat_digital10[]
Definition: vf_waveform.c:2289
void * priv
private data for use by the filter
Definition: avfilter.h:353
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: frame.h:539
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Definition: avfilter.h:116
const char * arg
Definition: jacosubdec.c:66
Definition: graph2dot.c:48
#define AV_PIX_FMT_GBRAP12
Definition: pixfmt.h:408
simple assert() macros that are a bit more flexible than ISO C assert().
static void draw_htext(AVFrame *out, int x, int y, int mult, float o1, float o2, const char *txt, const uint8_t color[4])
Definition: vf_waveform.c:2535
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:390
static enum AVPixelFormat in_pix_fmts[]
Definition: vf_ciescope.c:124
static void graticule_none(WaveformContext *s, AVFrame *out)
Definition: vf_waveform.c:2781
#define FFMAX(a, b)
Definition: common.h:94
static void iblend_vline16(uint8_t *ddst, int height, int linesize, float o1, float o2, int v, int step)
Definition: vf_waveform.c:2648
static const GraticuleLines ire8[]
Definition: vf_waveform.c:2429
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:70
static void envelope_peak16(WaveformContext *s, AVFrame *out, int plane, int component, int offset)
Definition: vf_waveform.c:480
static void idraw_htext16(AVFrame *out, int x, int y, int mult, float o1, float o2, const char *txt, const uint8_t color[4])
Definition: vf_waveform.c:2705
uint64_t flags
Combination of AV_PIX_FMT_FLAG_...
Definition: pixdesc.h:106
#define AV_PIX_FMT_YUV422P9
Definition: pixfmt.h:385
#define OFFSET(x)
Definition: vf_waveform.c:128
uint8_t nb_components
The number of components each pixel has, (1-4)
Definition: pixdesc.h:83
static const GraticuleLines millivolts12[]
Definition: vf_waveform.c:2421
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:802
static int16_t mult(Float11 *f1, Float11 *f2)
Definition: g726.c:55
#define FFMIN(a, b)
Definition: common.h:96
static enum AVPixelFormat out_gray12_lowpass_pix_fmts[]
Definition: vf_waveform.c:292
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
Definition: pixfmt.h:78
int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add *ref as a new reference to formats.
Definition: formats.c:439
typedef void(APIENTRY *FF_PFNGLACTIVETEXTUREPROC)(GLenum texture)
static enum AVPixelFormat flat_pix_fmts[]
Definition: vf_waveform.c:297
static av_always_inline void color16(WaveformContext *s, AVFrame *in, AVFrame *out, int component, int intensity, int offset_y, int offset_x, int column, int mirror, int jobnr, int nb_jobs)
Definition: vf_waveform.c:1646
uint16_t pos
Definition: vf_waveform.c:76
AVFormatContext * ctx
Definition: movenc.c:48
int offset_x
Definition: vf_waveform.c:37
static const GraticuleLines flat_digital8[]
Definition: vf_waveform.c:2277
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:72
static const GraticuleLines aflat_digital9[]
Definition: vf_waveform.c:2187
unsigned nb_formats
number of formats
Definition: formats.h:65
static void envelope_instant(WaveformContext *s, AVFrame *out, int plane, int component, int offset)
Definition: vf_waveform.c:433
#define AV_PIX_FMT_YUVA444P10
Definition: pixfmt.h:426
int * emax[4][4]
Definition: vf_waveform.c:101
#define AV_PIX_FMT_YUV444P9
Definition: pixfmt.h:386
static void idraw_htext(AVFrame *out, int x, int y, int mult, float o1, float o2, const char *txt, const uint8_t color[4])
Definition: vf_waveform.c:2679
#define FF_ARRAY_ELEMS(a)
the normal 2^n-1 "JPEG" YUV ranges
Definition: pixfmt.h:523
static enum AVPixelFormat out_yuv10_lowpass_pix_fmts[]
Definition: vf_waveform.c:267
if(ret)
s EdgeDetect Foobar g libavfilter vf_edgedetect c libavfilter vf_foobar c edit libavfilter and add an entry for foobar following the pattern of the other filters edit libavfilter allfilters and add an entry for foobar following the pattern of the other filters configure make j< whatever > ffmpeg ffmpeg i you should get a foobar png with Lena edge detected That s your new playground is ready Some little details about what s going which in turn will define variables for the build system and the C
const char * name
Definition: vf_waveform.c:75
static void comp(unsigned char *dst, ptrdiff_t dst_stride, unsigned char *src, ptrdiff_t src_stride, int add)
Definition: eamad.c:83
static void update_cr(uint8_t *target, int unused, int intensity)
Definition: vf_waveform.c:657
static const AVOption waveform_options[]
Definition: vf_waveform.c:131
static const GraticuleLines aflat_digital8[]
Definition: vf_waveform.c:2181
static const GraticuleLines flat_ire8[]
Definition: vf_waveform.c:2333
Used for passing data between threads.
Definition: dsddec.c:64
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:326
static void draw_text(FFDrawContext *draw, AVFrame *frame, FFDrawColor *color, int x0, int y0, const uint8_t *text, int vertical)
Definition: vf_datascope.c:79
static const GraticuleLines chroma_digital9[]
Definition: vf_waveform.c:2469
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
Definition: pixfmt.h:177
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
static const AVFilterPad outputs[]
Definition: vf_waveform.c:3394
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_waveform.c:3377
static const GraticuleLines aflat_millivolts12[]
Definition: vf_waveform.c:2229
GraticuleLines * glines
Definition: vf_waveform.c:112
static av_always_inline void chroma16(WaveformContext *s, AVFrame *in, AVFrame *out, int component, int intensity, int offset_y, int offset_x, int column, int mirror, int jobnr, int nb_jobs)
Definition: vf_waveform.c:1436
void(* blend_line)(uint8_t *dst, int size, int linesize, float o1, float o2, int v, int step)
Definition: vf_waveform.c:119
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:50
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:387
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
Definition: pixfmt.h:72
static enum AVPixelFormat out_yuv8_lowpass_pix_fmts[]
Definition: vf_waveform.c:257
static enum AVPixelFormat out_rgb9_lowpass_pix_fmts[]
Definition: vf_waveform.c:242
Describe the class of an AVClass context structure.
Definition: log.h:67
Filter definition.
Definition: avfilter.h:144
AVFrame * mask
static void update16_cr(uint16_t *target, int unused, int intensity, int limit)
Definition: vf_waveform.c:665
Rational number (pair of numerator and denominator).
Definition: rational.h:58
#define FLAT_FUNC(name, column, mirror)
Definition: vf_waveform.c:1119
static void envelope_instant16(WaveformContext *s, AVFrame *out, int plane, int component, int offset)
Definition: vf_waveform.c:385
#define COLOR16_FUNC(name, column, mirror)
Definition: vf_waveform.c:1754
const char * name
Filter name.
Definition: avfilter.h:148
#define AV_PIX_FMT_YUV440P12
Definition: pixfmt.h:393
#define AV_PIX_FMT_YUV420P9
Definition: pixfmt.h:384
static const GraticuleLines flat_digital12[]
Definition: vf_waveform.c:2295
static void idraw_vtext16(AVFrame *out, int x, int y, int mult, float o1, float o2, const char *txt, const uint8_t color[4])
Definition: vf_waveform.c:2756
misc parsing utilities
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:350
int * emin[4][4]
Definition: vf_waveform.c:102
#define AV_PIX_FMT_GBRP12
Definition: pixfmt.h:404
static const GraticuleLines millivolts8[]
Definition: vf_waveform.c:2397
#define flags(name, subs,...)
Definition: cbs_av1.c:561
AVFilterInternal * internal
An opaque struct for libavfilter internal use.
Definition: avfilter.h:378
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:388
#define AV_PIX_FMT_YUV444P12
Definition: pixfmt.h:394
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:309
static const GraticuleLines digital12[]
Definition: vf_waveform.c:2391
uint8_t bg_color[4]
Definition: vf_waveform.c:90
#define AFLAT(name, update_cb, update_cr, column, mirror)
Definition: vf_waveform.c:1278
int
static enum AVPixelFormat out_rgb12_lowpass_pix_fmts[]
Definition: vf_waveform.c:252
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
Y , 8bpp.
Definition: pixfmt.h:74
static av_always_inline void flat(WaveformContext *s, AVFrame *in, AVFrame *out, int component, int intensity, int offset_y, int offset_x, int column, int mirror, int jobnr, int nb_jobs)
Definition: vf_waveform.c:1007
static void idraw_vtext(AVFrame *out, int x, int y, int mult, float o1, float o2, const char *txt, const uint8_t color[4])
Definition: vf_waveform.c:2731
planar GBRA 4:4:4:4 32bpp
Definition: pixfmt.h:215
static const GraticuleLines millivolts10[]
Definition: vf_waveform.c:2413
static const GraticuleLines aflat_ire12[]
Definition: vf_waveform.c:2267
#define AV_PIX_FMT_YUVA444P9
Definition: pixfmt.h:423
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
Definition: pixfmt.h:80
static const GraticuleLines digital9[]
Definition: vf_waveform.c:2379
static void blend_vline16(uint8_t *ddst, int height, int linesize, float o1, float o2, int v, int step)
Definition: vf_waveform.c:2504
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
Definition: pixfmt.h:73
static enum AVPixelFormat out_pix_fmts[]
Definition: vf_ciescope.c:133
static av_always_inline void lowpass16(WaveformContext *s, AVFrame *in, AVFrame *out, int component, int intensity, int offset_y, int offset_x, int column, int mirror, int jobnr, int nb_jobs)
Definition: vf_waveform.c:673
avfilter_execute_func * execute
Definition: internal.h:155
static const GraticuleLines digital10[]
Definition: vf_waveform.c:2385
static const GraticuleLines flat_ire10[]
Definition: vf_waveform.c:2353
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: vf_waveform.c:3281
static void graticule_column(WaveformContext *s, AVFrame *out)
Definition: vf_waveform.c:2868
static const uint8_t black_yuva_color[4]
Definition: vf_waveform.c:2178
static void graticule16_column(WaveformContext *s, AVFrame *out)
Definition: vf_waveform.c:2909
const AVPixFmtDescriptor * odesc
Definition: vf_waveform.c:125
const AVPixFmtDescriptor * desc
Definition: vf_tonemap.c:196
int(* waveform_slice)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_waveform.c:116
static void envelope_peak(WaveformContext *s, AVFrame *out, int plane, int component, int offset)
Definition: vf_waveform.c:550
A list of supported formats for one end of a filter link.
Definition: formats.h:64
#define AFLAT16(name, update_cb, update_cr, column, mirror)
Definition: vf_waveform.c:1144
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) full scale (JPEG), deprecated in favor ...
Definition: pixfmt.h:258
int component
Definition: vf_waveform.c:35
static const GraticuleLines flat_millivolts8[]
Definition: vf_waveform.c:2301
An instance of a filter.
Definition: avfilter.h:338
static void draw_htext16(AVFrame *out, int x, int y, int mult, float o1, float o2, const char *txt, const uint8_t color[4])
Definition: vf_waveform.c:2561
int height
Definition: frame.h:353
#define av_freep(p)
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
Definition: pixfmt.h:99
void INT64 start
Definition: avisynth_c.h:766
#define av_always_inline
Definition: attributes.h:39
#define av_malloc_array(a, b)
AVFrame * in
Definition: af_afftdn.c:1082
static void iblend_hline16(uint8_t *ddst, int width, int unused, float o1, float o2, int v, int step)
Definition: vf_waveform.c:2669
static void envelope(WaveformContext *s, AVFrame *out, int plane, int component, int offset)
Definition: vf_waveform.c:630
static const GraticuleLines ire9[]
Definition: vf_waveform.c:2437
static const GraticuleLines chroma_digital12[]
Definition: vf_waveform.c:2485
static const GraticuleLines flat_millivolts9[]
Definition: vf_waveform.c:2309
AVFilterLink * inlink
Definition: vf_blend.c:56
internal API functions
static enum AVPixelFormat out_gray10_lowpass_pix_fmts[]
Definition: vf_waveform.c:287
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
int depth
Number of bits in the component.
Definition: pixdesc.h:58
static const GraticuleLines aflat_ire8[]
Definition: vf_waveform.c:2237
static enum AVPixelFormat out_rgb8_lowpass_pix_fmts[]
Definition: vf_waveform.c:237
const AVPixFmtDescriptor * desc
Definition: vf_waveform.c:124
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
static void draw_vtext(AVFrame *out, int x, int y, int mult, float o1, float o2, const char *txt, const uint8_t color[4])
Definition: vf_waveform.c:2587
int src_linesize
Definition: vf_bm3d.c:57
mode
Use these values in ebur128_init (or&#39;ed).
Definition: ebur128.h:83
static const GraticuleLines millivolts9[]
Definition: vf_waveform.c:2405
for(j=16;j >0;--j)
#define COLOR_FUNC(name, column, mirror)
Definition: vf_waveform.c:1886
static const GraticuleLines aflat_millivolts8[]
Definition: vf_waveform.c:2205
CGA/EGA/VGA ROM font data.
static enum AVPixelFormat out_rgb10_lowpass_pix_fmts[]
Definition: vf_waveform.c:247
AVFrame * max
Definition: vf_threshold.c:75
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:58
const char * name
Definition: opengl_enc.c:102
int * formats
list of media formats
Definition: formats.h:66