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