FFmpeg
vf_vectorscope.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Paul B Mahol
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include "libavutil/avassert.h"
22 #include "libavutil/intreadwrite.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 
38 };
39 
48 };
49 
50 typedef struct VectorscopeContext {
51  const AVClass *class;
52  int mode;
53  int intensity;
54  float fintensity;
55  uint16_t bg_color[4];
56  float ftint[2];
57  int planewidth[4];
58  int planeheight[4];
59  int hsub, vsub;
60  int x, y, pd;
61  int is_yuv;
62  int size;
63  int depth;
64  int mult;
65  int envelope;
66  int graticule;
67  float opacity;
68  float bgopacity;
69  float lthreshold;
70  float hthreshold;
71  int tint[2];
72  int tmin;
73  int tmax;
74  int flags;
76  int cs;
77  uint8_t *peak_memory;
78  uint8_t **peak;
79 
80  void (*vectorscope)(struct VectorscopeContext *s,
81  AVFrame *in, AVFrame *out, int pd);
83  int X, int Y, int D, int P);
85 
86 #define OFFSET(x) offsetof(VectorscopeContext, x)
87 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
88 #define TFLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
89 
90 static const AVOption vectorscope_options[] = {
91  { "mode", "set vectorscope mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=0}, 0, MODE_NB-1, FLAGS, .unit = "mode"},
92  { "m", "set vectorscope mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=0}, 0, MODE_NB-1, FLAGS, .unit = "mode"},
93  { "gray", 0, 0, AV_OPT_TYPE_CONST, {.i64=TINT}, 0, 0, FLAGS, .unit = "mode" },
94  { "tint", 0, 0, AV_OPT_TYPE_CONST, {.i64=TINT}, 0, 0, FLAGS, .unit = "mode" },
95  { "color", 0, 0, AV_OPT_TYPE_CONST, {.i64=COLOR}, 0, 0, FLAGS, .unit = "mode" },
96  { "color2", 0, 0, AV_OPT_TYPE_CONST, {.i64=COLOR2}, 0, 0, FLAGS, .unit = "mode" },
97  { "color3", 0, 0, AV_OPT_TYPE_CONST, {.i64=COLOR3}, 0, 0, FLAGS, .unit = "mode" },
98  { "color4", 0, 0, AV_OPT_TYPE_CONST, {.i64=COLOR4}, 0, 0, FLAGS, .unit = "mode" },
99  { "color5", 0, 0, AV_OPT_TYPE_CONST, {.i64=COLOR5}, 0, 0, FLAGS, .unit = "mode" },
100  { "x", "set color component on X axis", OFFSET(x), AV_OPT_TYPE_INT, {.i64=1}, 0, 2, FLAGS},
101  { "y", "set color component on Y axis", OFFSET(y), AV_OPT_TYPE_INT, {.i64=2}, 0, 2, FLAGS},
102  { "intensity", "set intensity", OFFSET(fintensity), AV_OPT_TYPE_FLOAT, {.dbl=0.004}, 0, 1, TFLAGS},
103  { "i", "set intensity", OFFSET(fintensity), AV_OPT_TYPE_FLOAT, {.dbl=0.004}, 0, 1, TFLAGS},
104  { "envelope", "set envelope", OFFSET(envelope), AV_OPT_TYPE_INT, {.i64=0}, 0, 3, TFLAGS, .unit = "envelope"},
105  { "e", "set envelope", OFFSET(envelope), AV_OPT_TYPE_INT, {.i64=0}, 0, 3, TFLAGS, .unit = "envelope"},
106  { "none", 0, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, TFLAGS, .unit = "envelope" },
107  { "instant", 0, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, TFLAGS, .unit = "envelope" },
108  { "peak", 0, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, TFLAGS, .unit = "envelope" },
109  { "peak+instant", 0, 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, TFLAGS, .unit = "envelope" },
110  { "graticule", "set graticule", OFFSET(graticule), AV_OPT_TYPE_INT, {.i64=GRAT_NONE}, 0, NB_GRATICULES-1, FLAGS, .unit = "graticule"},
111  { "g", "set graticule", OFFSET(graticule), AV_OPT_TYPE_INT, {.i64=GRAT_NONE}, 0, NB_GRATICULES-1, FLAGS, .unit = "graticule"},
112  { "none", 0, 0, AV_OPT_TYPE_CONST, {.i64=GRAT_NONE}, 0, 0, FLAGS, .unit = "graticule" },
113  { "green", 0, 0, AV_OPT_TYPE_CONST, {.i64=GRAT_GREEN}, 0, 0, FLAGS, .unit = "graticule" },
114  { "color", 0, 0, AV_OPT_TYPE_CONST, {.i64=GRAT_COLOR}, 0, 0, FLAGS, .unit = "graticule" },
115  { "invert", 0, 0, AV_OPT_TYPE_CONST, {.i64=GRAT_INVERT},0, 0, FLAGS, .unit = "graticule" },
116  { "opacity", "set graticule opacity", OFFSET(opacity), AV_OPT_TYPE_FLOAT, {.dbl=0.75}, 0, 1, TFLAGS},
117  { "o", "set graticule opacity", OFFSET(opacity), AV_OPT_TYPE_FLOAT, {.dbl=0.75}, 0, 1, TFLAGS},
118  { "flags", "set graticule flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64=4}, 0, 7, TFLAGS, .unit = "flags"},
119  { "f", "set graticule flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64=4}, 0, 7, TFLAGS, .unit = "flags"},
120  { "white", "draw white point", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, TFLAGS, .unit = "flags" },
121  { "black", "draw black point", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, TFLAGS, .unit = "flags" },
122  { "name", "draw point name", 0, AV_OPT_TYPE_CONST, {.i64=4}, 0, 0, TFLAGS, .unit = "flags" },
123  { "bgopacity", "set background opacity", OFFSET(bgopacity), AV_OPT_TYPE_FLOAT, {.dbl=0.3}, 0, 1, TFLAGS},
124  { "b", "set background opacity", OFFSET(bgopacity), AV_OPT_TYPE_FLOAT, {.dbl=0.3}, 0, 1, TFLAGS},
125  { "lthreshold", "set low threshold", OFFSET(lthreshold), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, 1, FLAGS},
126  { "l", "set low threshold", OFFSET(lthreshold), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, 1, FLAGS},
127  { "hthreshold", "set high threshold", OFFSET(hthreshold), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 1, FLAGS},
128  { "h", "set high threshold", OFFSET(hthreshold), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 1, FLAGS},
129  { "colorspace", "set colorspace", OFFSET(colorspace), AV_OPT_TYPE_INT, {.i64=0}, 0, 2, FLAGS, .unit = "colorspace"},
130  { "c", "set colorspace", OFFSET(colorspace), AV_OPT_TYPE_INT, {.i64=0}, 0, 2, FLAGS, .unit = "colorspace"},
131  { "auto", 0, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, .unit = "colorspace" },
132  { "601", 0, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, .unit = "colorspace" },
133  { "709", 0, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, .unit = "colorspace" },
134  { "tint0", "set 1st tint", OFFSET(ftint[0]), AV_OPT_TYPE_FLOAT, {.dbl=0}, -1, 1, TFLAGS},
135  { "t0", "set 1st tint", OFFSET(ftint[0]), AV_OPT_TYPE_FLOAT, {.dbl=0}, -1, 1, TFLAGS},
136  { "tint1", "set 2nd tint", OFFSET(ftint[1]), AV_OPT_TYPE_FLOAT, {.dbl=0}, -1, 1, TFLAGS},
137  { "t1", "set 2nd tint", OFFSET(ftint[1]), AV_OPT_TYPE_FLOAT, {.dbl=0}, -1, 1, TFLAGS},
138  { NULL }
139 };
140 
142 
143 static const enum AVPixelFormat out_yuv8_pix_fmts[] = {
146 };
147 
148 static const enum AVPixelFormat out_yuv9_pix_fmts[] = {
151 };
152 
153 static const enum AVPixelFormat out_yuv10_pix_fmts[] = {
156 };
157 
158 static const enum AVPixelFormat out_yuv12_pix_fmts[] = {
161 };
162 
163 static const enum AVPixelFormat out_rgb8_pix_fmts[] = {
166 };
167 
168 static const enum AVPixelFormat out_rgb9_pix_fmts[] = {
171 };
172 
173 static const enum AVPixelFormat out_rgb10_pix_fmts[] = {
176 };
177 
178 static const enum AVPixelFormat out_rgb12_pix_fmts[] = {
181 };
182 
183 static const enum AVPixelFormat in1_pix_fmts[] = {
192 };
193 
194 static const enum AVPixelFormat in2_pix_fmts[] = {
210 };
211 
213 {
214  VectorscopeContext *s = ctx->priv;
215  const enum AVPixelFormat *out_pix_fmts;
216  const AVPixFmtDescriptor *desc;
217  AVFilterFormats *avff;
218  int depth, rgb, i, ret;
219 
220  if (!ctx->inputs[0]->incfg.formats ||
221  !ctx->inputs[0]->incfg.formats->nb_formats) {
222  return AVERROR(EAGAIN);
223  }
224 
225  if (!ctx->inputs[0]->outcfg.formats) {
226  const enum AVPixelFormat *in_pix_fmts;
227 
228  if ((s->x == 1 && s->y == 2) || (s->x == 2 && s->y == 1))
230  else
232  if ((ret = ff_formats_ref(ff_make_format_list(in_pix_fmts), &ctx->inputs[0]->outcfg.formats)) < 0)
233  return ret;
234  }
235 
236  avff = ctx->inputs[0]->incfg.formats;
237  desc = av_pix_fmt_desc_get(avff->formats[0]);
238  rgb = desc->flags & AV_PIX_FMT_FLAG_RGB;
239  depth = desc->comp[0].depth;
240  for (i = 1; i < avff->nb_formats; i++) {
241  desc = av_pix_fmt_desc_get(avff->formats[i]);
242  if (rgb != (desc->flags & AV_PIX_FMT_FLAG_RGB) ||
243  depth != desc->comp[0].depth)
244  return AVERROR(EAGAIN);
245  }
246 
247  if (rgb && depth == 8)
249  else if (rgb && depth == 9)
251  else if (rgb && depth == 10)
253  else if (rgb && depth == 12)
255  else if (depth == 8)
257  else if (depth == 9)
259  else if (depth == 10)
261  else if (depth == 12)
263  else
264  return AVERROR(EAGAIN);
265  if ((ret = ff_formats_ref(ff_make_format_list(out_pix_fmts), &ctx->outputs[0]->incfg.formats)) < 0)
266  return ret;
267 
268  return 0;
269 }
270 
271 static int config_output(AVFilterLink *outlink)
272 {
273  VectorscopeContext *s = outlink->src->priv;
274  int i;
275 
276  outlink->h = outlink->w = s->size;
277  outlink->sample_aspect_ratio = (AVRational){1,1};
278 
279  s->peak_memory = av_calloc(s->size, s->size);
280  if (!s->peak_memory)
281  return AVERROR(ENOMEM);
282 
283  s->peak = av_calloc(s->size, sizeof(*s->peak));
284  if (!s->peak)
285  return AVERROR(ENOMEM);
286 
287  for (i = 0; i < s->size; i++)
288  s->peak[i] = s->peak_memory + s->size * i;
289 
290  return 0;
291 }
292 
294 {
295  const int dlinesize = out->linesize[0] / 2;
296  uint16_t *dpd = s->mode == COLOR || !s->is_yuv ? (uint16_t *)out->data[s->pd] : (uint16_t *)out->data[0];
297  const int max = s->size - 1;
298  int i, j;
299 
300  for (i = 0; i < out->height; i++) {
301  for (j = 0; j < out->width; j++) {
302  const int pos = i * dlinesize + j;
303  const int poa = (i - 1) * dlinesize + j;
304  const int pob = (i + 1) * dlinesize + j;
305 
306  if (dpd[pos] && (((!j || !dpd[pos - 1]) || ((j == (out->width - 1)) || !dpd[pos + 1]))
307  || ((!i || !dpd[poa]) || ((i == (out->height - 1)) || !dpd[pob])))) {
308  dpd[pos] = max;
309  }
310  }
311  }
312 }
313 
315 {
316  const int dlinesize = out->linesize[0] / 2;
317  uint16_t *dpd = s->mode == COLOR || !s->is_yuv ? (uint16_t *)out->data[s->pd] : (uint16_t *)out->data[0];
318  const int max = s->size - 1;
319  int i, j;
320 
321  for (i = 0; i < out->height; i++) {
322  for (j = 0; j < out->width; j++) {
323  const int pos = i * dlinesize + j;
324 
325  if (dpd[pos])
326  s->peak[i][j] = 1;
327  }
328  }
329 
330  if (s->envelope == 3)
332 
333  for (i = 0; i < out->height; i++) {
334  for (j = 0; j < out->width; j++) {
335  const int pos = i * dlinesize + j;
336 
337  if (s->peak[i][j] && (((!j || !s->peak[i][j-1]) || ((j == (out->width - 1)) || !s->peak[i][j + 1]))
338  || ((!i || !s->peak[i-1][j]) || ((i == (out->height - 1)) || !s->peak[i + 1][j])))) {
339  dpd[pos] = max;
340  }
341  }
342  }
343 }
344 
346 {
347  const int dlinesize = out->linesize[0];
348  uint8_t *dpd = s->mode == COLOR || !s->is_yuv ? out->data[s->pd] : out->data[0];
349  int i, j;
350 
351  for (i = 0; i < out->height; i++) {
352  for (j = 0; j < out->width; j++) {
353  const int pos = i * dlinesize + j;
354  const int poa = (i - 1) * dlinesize + j;
355  const int pob = (i + 1) * dlinesize + j;
356 
357  if (dpd[pos] && (((!j || !dpd[pos - 1]) || ((j == (out->width - 1)) || !dpd[pos + 1]))
358  || ((!i || !dpd[poa]) || ((i == (out->height - 1)) || !dpd[pob])))) {
359  dpd[pos] = 255;
360  }
361  }
362  }
363 }
364 
366 {
367  const int dlinesize = out->linesize[0];
368  uint8_t *dpd = s->mode == COLOR || !s->is_yuv ? out->data[s->pd] : out->data[0];
369  int i, j;
370 
371  for (i = 0; i < out->height; i++) {
372  for (j = 0; j < out->width; j++) {
373  const int pos = i * dlinesize + j;
374 
375  if (dpd[pos])
376  s->peak[i][j] = 1;
377  }
378  }
379 
380  if (s->envelope == 3)
382 
383  for (i = 0; i < out->height; i++) {
384  for (j = 0; j < out->width; j++) {
385  const int pos = i * dlinesize + j;
386 
387  if (s->peak[i][j] && (((!j || !s->peak[i][j-1]) || ((j == (out->width - 1)) || !s->peak[i][j + 1]))
388  || ((!i || !s->peak[i-1][j]) || ((i == (out->height - 1)) || !s->peak[i + 1][j])))) {
389  dpd[pos] = 255;
390  }
391  }
392  }
393 }
394 
396 {
397  if (!s->envelope) {
398  return;
399  } else if (s->envelope == 1) {
401  } else {
403  }
404 }
405 
407 {
408  if (!s->envelope) {
409  return;
410  } else if (s->envelope == 1) {
412  } else {
413  envelope_peak(s, out);
414  }
415 }
416 
418 {
419  const uint16_t * const *src = (const uint16_t * const *)in->data;
420  const int slinesizex = in->linesize[s->x] / 2;
421  const int slinesizey = in->linesize[s->y] / 2;
422  const int slinesized = in->linesize[pd] / 2;
423  const int dlinesize = out->linesize[0] / 2;
424  const int intensity = s->intensity;
425  const int px = s->x, py = s->y;
426  const int h = s->planeheight[py];
427  const int w = s->planewidth[px];
428  const uint16_t *spx = src[px];
429  const uint16_t *spy = src[py];
430  const uint16_t *spd = src[pd];
431  const int hsub = s->hsub;
432  const int vsub = s->vsub;
433  uint16_t **dst = (uint16_t **)out->data;
434  uint16_t *dpx = dst[px];
435  uint16_t *dpy = dst[py];
436  uint16_t *dpd = dst[pd];
437  uint16_t *dp1 = dst[1];
438  uint16_t *dp2 = dst[2];
439  const int max = s->size - 1;
440  const int mid = s->size / 2;
441  const int tmin = s->tmin;
442  const int tmax = s->tmax;
443  int i, j, k;
444 
445  for (k = 0; k < 4 && dst[k]; k++) {
446  for (i = 0; i < out->height ; i++)
447  for (j = 0; j < out->width; j++)
448  AV_WN16(out->data[k] + i * out->linesize[k] + j * 2,
449  (s->mode == COLOR || s->mode == COLOR5) && k == s->pd ? 0 : s->bg_color[k]);
450  }
451 
452  switch (s->mode) {
453  case COLOR:
454  case COLOR5:
455  case TINT:
456  for (i = 0; i < h; i++) {
457  const int iwx = i * slinesizex;
458  const int iwy = i * slinesizey;
459  const int iwd = i * slinesized;
460  for (j = 0; j < w; j++) {
461  const int x = FFMIN(spx[iwx + j], max);
462  const int y = FFMIN(spy[iwy + j], max);
463  const int z = spd[iwd + j];
464  const int pos = y * dlinesize + x;
465 
466  if (z < tmin || z > tmax)
467  continue;
468 
469  dpd[pos] = FFMIN(dpd[pos] + intensity, max);
470  }
471  }
472  break;
473  case COLOR2:
474  if (s->is_yuv) {
475  for (i = 0; i < h; i++) {
476  const int iw1 = i * slinesizex;
477  const int iw2 = i * slinesizey;
478  const int iwd = i * slinesized;
479  for (j = 0; j < w; j++) {
480  const int x = FFMIN(spx[iw1 + j], max);
481  const int y = FFMIN(spy[iw2 + j], max);
482  const int z = spd[iwd + j];
483  const int pos = y * dlinesize + x;
484 
485  if (z < tmin || z > tmax)
486  continue;
487 
488  if (!dpd[pos])
489  dpd[pos] = FFABS(mid - x) + FFABS(mid - y);
490  dpx[pos] = x;
491  dpy[pos] = y;
492  }
493  }
494  } else {
495  for (i = 0; i < h; i++) {
496  const int iw1 = i * slinesizex;
497  const int iw2 = i * slinesizey;
498  const int iwd = i * slinesized;
499  for (j = 0; j < w; j++) {
500  const int x = FFMIN(spx[iw1 + j], max);
501  const int y = FFMIN(spy[iw2 + j], max);
502  const int z = spd[iwd + j];
503  const int pos = y * dlinesize + x;
504 
505  if (z < tmin || z > tmax)
506  continue;
507 
508  if (!dpd[pos])
509  dpd[pos] = FFMIN(x + y, max);
510  dpx[pos] = x;
511  dpy[pos] = y;
512  }
513  }
514  }
515  break;
516  case COLOR3:
517  for (i = 0; i < h; i++) {
518  const int iw1 = i * slinesizex;
519  const int iw2 = i * slinesizey;
520  const int iwd = i * slinesized;
521  for (j = 0; j < w; j++) {
522  const int x = FFMIN(spx[iw1 + j], max);
523  const int y = FFMIN(spy[iw2 + j], max);
524  const int z = spd[iwd + j];
525  const int pos = y * dlinesize + x;
526 
527  if (z < tmin || z > tmax)
528  continue;
529 
530  dpd[pos] = FFMIN(max, dpd[pos] + intensity);
531  dpx[pos] = x;
532  dpy[pos] = y;
533  }
534  }
535  break;
536  case COLOR4:
537  for (i = 0; i < in->height; i++) {
538  const int iwx = (i >> vsub) * slinesizex;
539  const int iwy = (i >> vsub) * slinesizey;
540  const int iwd = i * slinesized;
541  for (j = 0; j < in->width; j++) {
542  const int x = FFMIN(spx[iwx + (j >> hsub)], max);
543  const int y = FFMIN(spy[iwy + (j >> hsub)], max);
544  const int z = spd[iwd + j];
545  const int pos = y * dlinesize + x;
546 
547  if (z < tmin || z > tmax)
548  continue;
549 
550  dpd[pos] = FFMAX(z, dpd[pos]);
551  dpx[pos] = x;
552  dpy[pos] = y;
553  }
554  }
555  break;
556  default:
557  av_assert0(0);
558  }
559 
560  envelope16(s, out);
561 
562  if (dst[3]) {
563  for (i = 0; i < out->height; i++) {
564  for (j = 0; j < out->width; j++) {
565  int pos = i * dlinesize + j;
566 
567  if (dpd[pos])
568  dst[3][pos] = max;
569  }
570  }
571  }
572 
573  if (s->mode == TINT && s->is_yuv &&
574  (s->tint[0] != mid || s->tint[1] != mid)) {
575  for (i = 0; i < out->height; i++) {
576  for (j = 0; j < out->width; j++) {
577  const int pos = i * dlinesize + j;
578  if (dpd[pos]) {
579  dp1[pos] = s->tint[0];
580  dp2[pos] = s->tint[1];
581  }
582  }
583  }
584  } else if (s->mode == TINT && !s->is_yuv) {
585  for (i = 0; i < out->height; i++) {
586  for (j = 0; j < out->width; j++) {
587  const int pos = i * dlinesize + j;
588  if (dpd[pos]) {
589  dpx[pos] = av_clip(dpd[pos] + dpd[pos] * s->ftint[0], 0, max);
590  dpy[pos] = av_clip(dpd[pos] + dpd[pos] * s->ftint[1], 0, max);
591  }
592  }
593  }
594  } else if (s->mode == COLOR) {
595  for (i = 0; i < out->height; i++) {
596  for (j = 0; j < out->width; j++) {
597  if (!dpd[i * dlinesize + j]) {
598  dpx[i * dlinesize + j] = j;
599  dpy[i * dlinesize + j] = i;
600  dpd[i * dlinesize + j] = mid;
601  }
602  }
603  }
604  } else if (s->mode == COLOR5) {
605  for (i = 0; i < out->height; i++) {
606  for (j = 0; j < out->width; j++) {
607  if (!dpd[i * dlinesize + j]) {
608  dpx[i * dlinesize + j] = j;
609  dpy[i * dlinesize + j] = i;
610  dpd[i * dlinesize + j] = mid * M_SQRT2 - hypot(i - mid, j - mid);
611  }
612  }
613  }
614  }
615 }
616 
618 {
619  const uint8_t * const *src = (const uint8_t * const *)in->data;
620  const int slinesizex = in->linesize[s->x];
621  const int slinesizey = in->linesize[s->y];
622  const int slinesized = in->linesize[pd];
623  const int dlinesize = out->linesize[0];
624  const int intensity = s->intensity;
625  const int px = s->x, py = s->y;
626  const int h = s->planeheight[py];
627  const int w = s->planewidth[px];
628  const uint8_t *spx = src[px];
629  const uint8_t *spy = src[py];
630  const uint8_t *spd = src[pd];
631  const int hsub = s->hsub;
632  const int vsub = s->vsub;
633  uint8_t **dst = out->data;
634  uint8_t *dpx = dst[px];
635  uint8_t *dpy = dst[py];
636  uint8_t *dpd = dst[pd];
637  uint8_t *dp1 = dst[1];
638  uint8_t *dp2 = dst[2];
639  const int tmin = s->tmin;
640  const int tmax = s->tmax;
641  int i, j, k;
642 
643  for (k = 0; k < 4 && dst[k]; k++)
644  for (i = 0; i < out->height ; i++)
645  memset(dst[k] + i * out->linesize[k],
646  (s->mode == COLOR || s->mode == COLOR5) && k == s->pd ? 0 : s->bg_color[k], out->width);
647 
648  switch (s->mode) {
649  case COLOR5:
650  case COLOR:
651  case TINT:
652  for (i = 0; i < h; i++) {
653  const int iwx = i * slinesizex;
654  const int iwy = i * slinesizey;
655  const int iwd = i * slinesized;
656  for (j = 0; j < w; j++) {
657  const int x = spx[iwx + j];
658  const int y = spy[iwy + j];
659  const int z = spd[iwd + j];
660  const int pos = y * dlinesize + x;
661 
662  if (z < tmin || z > tmax)
663  continue;
664 
665  dpd[pos] = FFMIN(dpd[pos] + intensity, 255);
666  }
667  }
668  break;
669  case COLOR2:
670  if (s->is_yuv) {
671  for (i = 0; i < h; i++) {
672  const int iw1 = i * slinesizex;
673  const int iw2 = i * slinesizey;
674  const int iwd = i * slinesized;
675  for (j = 0; j < w; j++) {
676  const int x = spx[iw1 + j];
677  const int y = spy[iw2 + j];
678  const int z = spd[iwd + j];
679  const int pos = y * dlinesize + x;
680 
681  if (z < tmin || z > tmax)
682  continue;
683 
684  if (!dpd[pos])
685  dpd[pos] = FFABS(128 - x) + FFABS(128 - y);
686  dpx[pos] = x;
687  dpy[pos] = y;
688  }
689  }
690  } else {
691  for (i = 0; i < h; i++) {
692  const int iw1 = i * slinesizex;
693  const int iw2 = i * slinesizey;
694  const int iwd = i * slinesized;
695  for (j = 0; j < w; j++) {
696  const int x = spx[iw1 + j];
697  const int y = spy[iw2 + j];
698  const int z = spd[iwd + j];
699  const int pos = y * dlinesize + x;
700 
701  if (z < tmin || z > tmax)
702  continue;
703 
704  if (!dpd[pos])
705  dpd[pos] = FFMIN(x + y, 255);
706  dpx[pos] = x;
707  dpy[pos] = y;
708  }
709  }
710  }
711  break;
712  case COLOR3:
713  for (i = 0; i < h; i++) {
714  const int iw1 = i * slinesizex;
715  const int iw2 = i * slinesizey;
716  const int iwd = i * slinesized;
717  for (j = 0; j < w; j++) {
718  const int x = spx[iw1 + j];
719  const int y = spy[iw2 + j];
720  const int z = spd[iwd + j];
721  const int pos = y * dlinesize + x;
722 
723  if (z < tmin || z > tmax)
724  continue;
725 
726  dpd[pos] = FFMIN(255, dpd[pos] + intensity);
727  dpx[pos] = x;
728  dpy[pos] = y;
729  }
730  }
731  break;
732  case COLOR4:
733  for (i = 0; i < in->height; i++) {
734  const int iwx = (i >> vsub) * slinesizex;
735  const int iwy = (i >> vsub) * slinesizey;
736  const int iwd = i * slinesized;
737  for (j = 0; j < in->width; j++) {
738  const int x = spx[iwx + (j >> hsub)];
739  const int y = spy[iwy + (j >> hsub)];
740  const int z = spd[iwd + j];
741  const int pos = y * dlinesize + x;
742 
743  if (z < tmin || z > tmax)
744  continue;
745 
746  dpd[pos] = FFMAX(z, dpd[pos]);
747  dpx[pos] = x;
748  dpy[pos] = y;
749  }
750  }
751  break;
752  default:
753  av_assert0(0);
754  }
755 
756  envelope(s, out);
757 
758  if (dst[3]) {
759  for (i = 0; i < out->height; i++) {
760  for (j = 0; j < out->width; j++) {
761  int pos = i * dlinesize + j;
762 
763  if (dpd[pos])
764  dst[3][pos] = 255;
765  }
766  }
767  }
768 
769  if (s->mode == TINT && s->is_yuv &&
770  (s->tint[0] != 128 || s->tint[1] != 128)) {
771  for (i = 0; i < out->height; i++) {
772  for (j = 0; j < out->width; j++) {
773  const int pos = i * dlinesize + j;
774  if (dpd[pos]) {
775  dp1[pos] = s->tint[0];
776  dp2[pos] = s->tint[1];
777  }
778  }
779  }
780  } else if (s->mode == TINT && !s->is_yuv) {
781  for (i = 0; i < out->height; i++) {
782  for (j = 0; j < out->width; j++) {
783  const int pos = i * dlinesize + j;
784  if (dpd[pos]) {
785  dpx[pos] = av_clip_uint8(dpd[pos] + dpd[pos] * s->ftint[0]);
786  dpy[pos] = av_clip_uint8(dpd[pos] + dpd[pos] * s->ftint[1]);
787  }
788  }
789  }
790  } else if (s->mode == COLOR) {
791  for (i = 0; i < out->height; i++) {
792  for (j = 0; j < out->width; j++) {
793  if (!dpd[i * out->linesize[pd] + j]) {
794  dpx[i * out->linesize[px] + j] = j;
795  dpy[i * out->linesize[py] + j] = i;
796  dpd[i * out->linesize[pd] + j] = 128;
797  }
798  }
799  }
800  } else if (s->mode == COLOR5) {
801  for (i = 0; i < out->height; i++) {
802  for (j = 0; j < out->width; j++) {
803  if (!dpd[i * out->linesize[pd] + j]) {
804  dpx[i * out->linesize[px] + j] = j;
805  dpy[i * out->linesize[py] + j] = i;
806  dpd[i * out->linesize[pd] + j] = 128 * M_SQRT2 - hypot(i - 128, j - 128);
807  }
808  }
809  }
810  }
811 }
812 
813 const static char *positions_name[] = {
814  "R", "B", "Cy", "Yl", "G", "Mg",
815 };
816 
817 const static uint16_t positions[][14][3] = {
818  {
819  { 81, 90, 240 }, { 41, 240, 110 }, { 170, 166, 16 },
820  { 210, 16, 146 }, { 145, 54, 34 }, { 106, 202, 222 },
821  { 162, 44, 142 }, { 131, 156, 44 }, { 112, 72, 58 },
822  { 84, 184, 198 }, { 65, 100, 212 }, { 35, 212, 114 },
823  { 235, 128, 128 }, { 16, 128, 128 } },
824  { { 63, 102, 240 }, { 32, 240, 118 }, { 188, 154, 16 },
825  { 219, 16, 138 }, { 173, 42, 26 }, { 78, 214, 230 },
826  { 28, 212, 120 }, { 51, 109, 212 }, { 63, 193, 204 },
827  { 133, 63, 52 }, { 145, 147, 44 }, { 168, 44, 136 },
828  { 235, 128, 128 }, { 16, 128, 128 } },
829  { { 81*2, 90*2, 240*2 }, { 41*2, 240*2, 110*2 }, { 170*2, 166*2, 16*2 },
830  { 210*2, 16*2, 146*2 }, { 145*2, 54*2, 34*2 }, { 106*2, 202*2, 222*2 },
831  { 162*2, 44*2, 142*2 }, { 131*2, 156*2, 44*2 }, { 112*2, 72*2, 58*2 },
832  { 84*2, 184*2, 198*2 }, { 65*2, 100*2, 212*2 }, { 35*2, 212*2, 114*2 },
833  { 470, 256, 256 }, { 32, 256, 256 } },
834  { { 63*2, 102*2, 240*2 }, { 32*2, 240*2, 118*2 }, { 188*2, 154*2, 16*2 },
835  { 219*2, 16*2, 138*2 }, { 173*2, 42*2, 26*2 }, { 78*2, 214*2, 230*2 },
836  { 28*2, 212*2, 120*2 }, { 51*2, 109*2, 212*2 }, { 63*2, 193*2, 204*2 },
837  { 133*2, 63*2, 52*2 }, { 145*2, 147*2, 44*2 }, { 168*2, 44*2, 136*2 },
838  { 470, 256, 256 }, { 32, 256, 256 } },
839  { { 81*4, 90*4, 240*4 }, { 41*4, 240*4, 110*4 }, { 170*4, 166*4, 16*4 },
840  { 210*4, 16*4, 146*4 }, { 145*4, 54*4, 34*4 }, { 106*4, 202*4, 222*4 },
841  { 162*4, 44*4, 142*4 }, { 131*4, 156*4, 44*4 }, { 112*4, 72*4, 58*4 },
842  { 84*4, 184*4, 198*4 }, { 65*4, 100*4, 212*4 }, { 35*4, 212*4, 114*4 },
843  { 940, 512, 512 }, { 64, 512, 512 } },
844  { { 63*4, 102*4, 240*4 }, { 32*4, 240*4, 118*4 }, { 188*4, 154*4, 16*4 },
845  { 219*4, 16*4, 138*4 }, { 173*4, 42*4, 26*4 }, { 78*4, 214*4, 230*4 },
846  { 28*4, 212*4, 120*4 }, { 51*4, 109*4, 212*4 }, { 63*4, 193*4, 204*4 },
847  { 133*4, 63*4, 52*4 }, { 145*4, 147*4, 44*4 }, { 168*4, 44*4, 136*4 },
848  { 940, 512, 512 }, { 64, 512, 512 } },
849  { { 81*8, 90*4, 240*8 }, { 41*8, 240*8, 110*8 }, { 170*8, 166*8, 16*8 },
850  { 210*8, 16*4, 146*8 }, { 145*8, 54*8, 34*8 }, { 106*8, 202*8, 222*8 },
851  { 162*8, 44*4, 142*8 }, { 131*8, 156*8, 44*8 }, { 112*8, 72*8, 58*8 },
852  { 84*8, 184*4, 198*8 }, { 65*8, 100*8, 212*8 }, { 35*8, 212*8, 114*8 },
853  { 1880, 1024, 1024 }, { 128, 1024, 1024 } },
854  { { 63*8, 102*8, 240*8 }, { 32*8, 240*8, 118*8 }, { 188*8, 154*8, 16*8 },
855  { 219*8, 16*8, 138*8 }, { 173*8, 42*8, 26*8 }, { 78*8, 214*8, 230*8 },
856  { 28*8, 212*8, 120*8 }, { 51*8, 109*8, 212*8 }, { 63*8, 193*8, 204*8 },
857  { 133*8, 63*8, 52*8 }, { 145*8, 147*8, 44*8 }, { 168*8, 44*8, 136*8 },
858  { 1880, 1024, 1024 }, { 128, 1024, 1024 } },
859  { { 81*16, 90*16, 240*16 }, { 41*16, 240*16, 110*16 }, { 170*16, 166*16, 16*16 },
860  { 210*16, 16*16, 146*16 }, { 145*16, 54*16, 34*16 }, { 106*16, 202*16, 222*16 },
861  { 162*16, 44*16, 142*16 }, { 131*16, 156*16, 44*16 }, { 112*16, 72*16, 58*16 },
862  { 84*16, 184*16, 198*16 }, { 65*16, 100*16, 212*16 }, { 35*16, 212*16, 114*16 },
863  { 3760, 2048, 2048 }, { 256, 2048, 2048 } },
864  { { 63*16, 102*16, 240*16 }, { 32*16, 240*16, 118*16 }, { 188*16, 154*16, 16*16 },
865  { 219*16, 16*16, 138*16 }, { 173*16, 42*16, 26*16 }, { 78*16, 214*16, 230*16 },
866  { 28*16, 212*16, 120*16 }, { 51*16, 109*16, 212*16 }, { 63*16, 193*16, 204*16 },
867  { 133*16, 63*16, 52*16 }, { 145*16, 147*16, 44*16 }, { 168*16, 44*16, 136*16 },
868  { 3760, 2048, 2048 }, { 256, 2048, 2048 } },
869 };
870 
871 static void draw_dots(uint8_t *dst, int L, int v, float o)
872 {
873  const float f = 1. - o;
874  const float V = o * v;
875  int l = L * 2;
876 
877  dst[ l - 3] = dst[ l - 3] * f + V;
878  dst[ l + 3] = dst[ l + 3] * f + V;
879  dst[-l - 3] = dst[-l - 3] * f + V;
880  dst[-l + 3] = dst[-l + 3] * f + V;
881 
882  l += L;
883 
884  dst[ l - 3] = dst[ l - 3] * f + V;
885  dst[ l + 3] = dst[ l + 3] * f + V;
886  dst[ l - 2] = dst[ l - 2] * f + V;
887  dst[ l + 2] = dst[ l + 2] * f + V;
888  dst[-l - 3] = dst[-l - 3] * f + V;
889  dst[-l + 3] = dst[-l + 3] * f + V;
890  dst[-l - 2] = dst[-l - 2] * f + V;
891  dst[-l + 2] = dst[-l + 2] * f + V;
892 }
893 
894 static void draw_idots(uint8_t *dst, int L, float o)
895 {
896  const float f = 1. - o;
897  int l = L * 2;
898 
899  dst[ l - 3] = dst[ l - 3] * f + (255 - dst[ l - 3]) * o;
900  dst[ l + 3] = dst[ l + 3] * f + (255 - dst[ l + 3]) * o;
901  dst[-l - 3] = dst[-l - 3] * f + (255 - dst[-l - 3]) * o;
902  dst[-l + 3] = dst[-l + 3] * f + (255 - dst[-l + 3]) * o;
903 
904  l += L;
905 
906  dst[ l - 3] = dst[ l - 3] * f + (255 - dst[ l - 3]) * o;
907  dst[ l + 3] = dst[ l + 3] * f + (255 - dst[ l + 3]) * o;
908  dst[ l - 2] = dst[ l - 2] * f + (255 - dst[ l - 2]) * o;
909  dst[ l + 2] = dst[ l + 2] * f + (255 - dst[ l + 2]) * o;
910  dst[-l - 3] = dst[-l - 3] * f + (255 - dst[-l - 3]) * o;
911  dst[-l + 3] = dst[-l + 3] * f + (255 - dst[-l + 3]) * o;
912  dst[-l - 2] = dst[-l - 2] * f + (255 - dst[-l - 2]) * o;
913  dst[-l + 2] = dst[-l + 2] * f + (255 - dst[-l + 2]) * o;
914 }
915 
916 static void draw_dots16(uint16_t *dst, int L, int v, float o)
917 {
918  const float f = 1. - o;
919  const float V = o * v;
920  int l = L * 2;
921 
922  dst[ l - 3] = dst[ l - 3] * f + V;
923  dst[ l + 3] = dst[ l + 3] * f + V;
924  dst[-l - 3] = dst[-l - 3] * f + V;
925  dst[-l + 3] = dst[-l + 3] * f + V;
926 
927  l += L;
928 
929  dst[ l - 3] = dst[ l - 3] * f + V;
930  dst[ l + 3] = dst[ l + 3] * f + V;
931  dst[ l - 2] = dst[ l - 2] * f + V;
932  dst[ l + 2] = dst[ l + 2] * f + V;
933  dst[-l - 3] = dst[-l - 3] * f + V;
934  dst[-l + 3] = dst[-l + 3] * f + V;
935  dst[-l - 2] = dst[-l - 2] * f + V;
936  dst[-l + 2] = dst[-l + 2] * f + V;
937 }
938 
939 static void draw_idots16(uint16_t *dst, int L, int v, float o)
940 {
941  const float f = 1. - o;
942  int l = L * 2;
943 
944  dst[ l - 3] = dst[ l - 3] * f + (v - dst[ l - 3]) * o;
945  dst[ l + 3] = dst[ l + 3] * f + (v - dst[ l + 3]) * o;
946  dst[-l - 3] = dst[-l - 3] * f + (v - dst[-l - 3]) * o;
947  dst[-l + 3] = dst[-l + 3] * f + (v - dst[-l + 3]) * o;
948 
949  l += L;
950 
951  dst[ l - 3] = dst[ l - 3] * f + (v - dst[ l - 3]) * o;
952  dst[ l + 3] = dst[ l + 3] * f + (v - dst[ l + 3]) * o;
953  dst[ l - 2] = dst[ l - 2] * f + (v - dst[ l - 2]) * o;
954  dst[ l + 2] = dst[ l + 2] * f + (v - dst[ l + 2]) * o;
955  dst[-l - 3] = dst[-l - 3] * f + (v - dst[-l - 3]) * o;
956  dst[-l + 3] = dst[-l + 3] * f + (v - dst[-l + 3]) * o;
957  dst[-l - 2] = dst[-l - 2] * f + (v - dst[-l - 2]) * o;
958  dst[-l + 2] = dst[-l + 2] * f + (v - dst[-l + 2]) * o;
959 }
960 
961 static void none_graticule(VectorscopeContext *s, AVFrame *out, int X, int Y, int D, int P)
962 {
963 }
964 
965 static void draw_ihtext(AVFrame *out, int x, int y, float o1, float o2, const char *txt, const uint8_t color[4])
966 {
967  const uint8_t *font;
968  int font_height;
969  int i, plane;
970 
971  font = avpriv_cga_font, font_height = 8;
972 
973  for (plane = 0; plane < 4 && out->data[plane]; plane++) {
974  for (i = 0; txt[i]; i++) {
975  int char_y, mask;
976 
977  uint8_t *p = out->data[plane] + y * out->linesize[plane] + (x + i * 8);
978  for (char_y = font_height - 1; char_y >= 0; char_y--) {
979  for (mask = 0x80; mask; mask >>= 1) {
980  if (font[txt[i] * font_height + char_y] & mask)
981  p[0] = p[0] * o2 + (255 - p[0]) * o1;
982  p++;
983  }
984  p += out->linesize[plane] - 8;
985  }
986  }
987  }
988 }
989 
990 static void draw_ihtext16(AVFrame *out, int x, int y, float o1, float o2, const char *txt, const uint16_t color[4])
991 {
992  const uint8_t *font;
993  int font_height;
994  int i, plane;
995 
996  font = avpriv_cga_font, font_height = 8;
997 
998  for (plane = 0; plane < 4 && out->data[plane]; plane++) {
999  for (i = 0; txt[i]; i++) {
1000  int char_y, mask;
1001  int v = color[plane];
1002 
1003  uint16_t *p = (uint16_t *)(out->data[plane] + y * out->linesize[plane]) + (x + i * 8);
1004  for (char_y = font_height - 1; char_y >= 0; char_y--) {
1005  for (mask = 0x80; mask; mask >>= 1) {
1006  if (font[txt[i] * font_height + char_y] & mask)
1007  p[0] = p[0] * o2 + (v - p[0]) * o1;
1008  p++;
1009  }
1010  p += out->linesize[plane] / 2 - 8;
1011  }
1012  }
1013  }
1014 }
1015 
1016 static void draw_htext(AVFrame *out, int x, int y, float o1, float o2, const char *txt, const uint8_t color[4])
1017 {
1018  const uint8_t *font;
1019  int font_height;
1020  int i, plane;
1021 
1022  font = avpriv_cga_font, font_height = 8;
1023 
1024  for (plane = 0; plane < 4 && out->data[plane]; plane++) {
1025  for (i = 0; txt[i]; i++) {
1026  int char_y, mask;
1027  int v = color[plane];
1028 
1029  uint8_t *p = out->data[plane] + y * out->linesize[plane] + (x + i * 8);
1030  for (char_y = font_height - 1; char_y >= 0; char_y--) {
1031  for (mask = 0x80; mask; mask >>= 1) {
1032  if (font[txt[i] * font_height + char_y] & mask)
1033  p[0] = p[0] * o2 + v * o1;
1034  p++;
1035  }
1036  p += out->linesize[plane] - 8;
1037  }
1038  }
1039  }
1040 }
1041 
1042 static void draw_htext16(AVFrame *out, int x, int y, float o1, float o2, const char *txt, const uint16_t color[4])
1043 {
1044  const uint8_t *font;
1045  int font_height;
1046  int i, plane;
1047 
1048  font = avpriv_cga_font, font_height = 8;
1049 
1050  for (plane = 0; plane < 4 && out->data[plane]; plane++) {
1051  for (i = 0; txt[i]; i++) {
1052  int char_y, mask;
1053  int v = color[plane];
1054 
1055  uint16_t *p = (uint16_t *)(out->data[plane] + y * out->linesize[plane]) + (x + i * 8);
1056  for (char_y = font_height - 1; char_y >= 0; char_y--) {
1057  for (mask = 0x80; mask; mask >>= 1) {
1058  if (font[txt[i] * font_height + char_y] & mask)
1059  p[0] = p[0] * o2 + v * o1;
1060  p++;
1061  }
1062  p += out->linesize[plane] / 2 - 8;
1063  }
1064  }
1065  }
1066 }
1067 
1068 static void color_graticule16(VectorscopeContext *s, AVFrame *out, int X, int Y, int D, int P)
1069 {
1070  const int max = s->size - 1;
1071  const float o = s->opacity;
1072  int i;
1073 
1074  for (i = 0; i < 12; i++) {
1075  int x = positions[P][i][X];
1076  int y = positions[P][i][Y];
1077  int d = positions[P][i][D];
1078 
1079  draw_dots16((uint16_t *)(out->data[D] + y * out->linesize[D] + x * 2), out->linesize[D] / 2, d, o);
1080  draw_dots16((uint16_t *)(out->data[X] + y * out->linesize[X] + x * 2), out->linesize[X] / 2, x, o);
1081  draw_dots16((uint16_t *)(out->data[Y] + y * out->linesize[Y] + x * 2), out->linesize[Y] / 2, y, o);
1082  if (out->data[3])
1083  draw_dots16((uint16_t *)(out->data[3] + y * out->linesize[3] + x * 2), out->linesize[3] / 2, max, o);
1084  }
1085 
1086  if (s->flags & 1) {
1087  int x = positions[P][12][X];
1088  int y = positions[P][12][Y];
1089  int d = positions[P][12][D];
1090 
1091  draw_dots16((uint16_t *)(out->data[D] + y * out->linesize[D] + x * 2), out->linesize[D] / 2, d, o);
1092  draw_dots16((uint16_t *)(out->data[X] + y * out->linesize[X] + x * 2), out->linesize[X] / 2, x, o);
1093  draw_dots16((uint16_t *)(out->data[Y] + y * out->linesize[Y] + x * 2), out->linesize[Y] / 2, y, o);
1094  if (out->data[3])
1095  draw_dots16((uint16_t *)(out->data[3] + y * out->linesize[3] + x * 2), out->linesize[3] / 2, max, o);
1096  }
1097 
1098  if (s->flags & 2) {
1099  int x = positions[P][13][X];
1100  int y = positions[P][13][Y];
1101  int d = positions[P][13][D];
1102 
1103  draw_dots16((uint16_t *)(out->data[D] + y * out->linesize[D] + x * 2), out->linesize[D] / 2, d, o);
1104  draw_dots16((uint16_t *)(out->data[X] + y * out->linesize[X] + x * 2), out->linesize[X] / 2, x, o);
1105  draw_dots16((uint16_t *)(out->data[Y] + y * out->linesize[Y] + x * 2), out->linesize[Y] / 2, y, o);
1106  if (out->data[3])
1107  draw_dots16((uint16_t *)(out->data[3] + y * out->linesize[3] + x * 2), out->linesize[3] / 2, max, o);
1108  }
1109 
1110  for (i = 0; i < 6 && s->flags & 4; i++) {
1111  uint16_t color[4] = { 0, 0, 0, 0 };
1112  int x = positions[P][i][X];
1113  int y = positions[P][i][Y];
1114  int d = positions[P][i][D];
1115 
1116  color[D] = d;
1117  color[X] = x;
1118  color[Y] = y;
1119  color[3] = max;
1120 
1121  if (x > max / 2)
1122  x += 8;
1123  else
1124  x -= 14;
1125  if (y > max / 2)
1126  y += 8;
1127  else
1128  y -= 14;
1129 
1130  x = av_clip(x, 0, out->width - 9);
1131  y = av_clip(y, 0, out->height - 9);
1132  draw_htext16(out, x, y, o, 1. - o, positions_name[i], color);
1133  }
1134 }
1135 
1136 static void color_graticule(VectorscopeContext *s, AVFrame *out, int X, int Y, int D, int P)
1137 {
1138  const float o = s->opacity;
1139  int i;
1140 
1141  for (i = 0; i < 12; i++) {
1142  int x = positions[P][i][X];
1143  int y = positions[P][i][Y];
1144  int d = positions[P][i][D];
1145 
1146  draw_dots(out->data[D] + y * out->linesize[D] + x, out->linesize[D], d, o);
1147  draw_dots(out->data[X] + y * out->linesize[X] + x, out->linesize[X], x, o);
1148  draw_dots(out->data[Y] + y * out->linesize[Y] + x, out->linesize[Y], y, o);
1149  if (out->data[3])
1150  draw_dots(out->data[3] + y * out->linesize[3] + x, out->linesize[3], 255, o);
1151  }
1152 
1153  if (s->flags & 1) {
1154  int x = positions[P][12][X];
1155  int y = positions[P][12][Y];
1156  int d = positions[P][12][D];
1157 
1158  draw_dots(out->data[D] + y * out->linesize[D] + x, out->linesize[D], d, o);
1159  draw_dots(out->data[X] + y * out->linesize[X] + x, out->linesize[X], x, o);
1160  draw_dots(out->data[Y] + y * out->linesize[Y] + x, out->linesize[Y], y, o);
1161  if (out->data[3])
1162  draw_dots(out->data[3] + y * out->linesize[3] + x, out->linesize[3], 255, o);
1163  }
1164 
1165  if (s->flags & 2) {
1166  int x = positions[P][13][X];
1167  int y = positions[P][13][Y];
1168  int d = positions[P][12][D];
1169 
1170  draw_dots(out->data[D] + y * out->linesize[D] + x, out->linesize[D], d, o);
1171  draw_dots(out->data[X] + y * out->linesize[X] + x, out->linesize[X], x, o);
1172  draw_dots(out->data[Y] + y * out->linesize[Y] + x, out->linesize[Y], y, o);
1173  if (out->data[3])
1174  draw_dots(out->data[3] + y * out->linesize[3] + x, out->linesize[3], 255, o);
1175  }
1176 
1177  for (i = 0; i < 6 && s->flags & 4; i++) {
1178  uint8_t color[4] = { 0, 0, 0, 255 };
1179  int x = positions[P][i][X];
1180  int y = positions[P][i][Y];
1181  int d = positions[P][i][D];
1182 
1183  color[D] = d;
1184  color[X] = x;
1185  color[Y] = y;
1186 
1187  if (x > 128)
1188  x += 8;
1189  else
1190  x -= 14;
1191  if (y > 128)
1192  y += 8;
1193  else
1194  y -= 14;
1195 
1196  x = av_clip(x, 0, out->width - 9);
1197  y = av_clip(y, 0, out->height - 9);
1198  draw_htext(out, x, y, o, 1. - o, positions_name[i], color);
1199  }
1200 }
1201 
1202 static void green_graticule16(VectorscopeContext *s, AVFrame *out, int X, int Y, int D, int P)
1203 {
1204  const int max = s->size - 1;
1205  const float o = s->opacity;
1206  const int m = s->mult;
1207  int i;
1208 
1209  for (i = 0; i < 12; i++) {
1210  int x = positions[P][i][X];
1211  int y = positions[P][i][Y];
1212 
1213  draw_dots16((uint16_t *)(out->data[0] + y * out->linesize[0] + x * 2), out->linesize[0] / 2, 128 * m, o);
1214  draw_dots16((uint16_t *)(out->data[1] + y * out->linesize[1] + x * 2), out->linesize[1] / 2, 0, o);
1215  draw_dots16((uint16_t *)(out->data[2] + y * out->linesize[2] + x * 2), out->linesize[2] / 2, 0, o);
1216  if (out->data[3])
1217  draw_dots16((uint16_t *)(out->data[3] + y * out->linesize[3] + x * 2), out->linesize[3] / 2, max, o);
1218  }
1219 
1220  if (s->flags & 1) {
1221  int x = positions[P][12][X];
1222  int y = positions[P][12][Y];
1223 
1224  draw_dots16((uint16_t *)(out->data[0] + y * out->linesize[0] + x * 2), out->linesize[0] / 2, 128 * m, o);
1225  draw_dots16((uint16_t *)(out->data[1] + y * out->linesize[1] + x * 2), out->linesize[1] / 2, 0, o);
1226  draw_dots16((uint16_t *)(out->data[2] + y * out->linesize[2] + x * 2), out->linesize[2] / 2, 0, o);
1227  if (out->data[3])
1228  draw_dots16((uint16_t *)(out->data[3] + y * out->linesize[3] + x * 2), out->linesize[3] / 2, max, o);
1229  }
1230 
1231  if (s->flags & 2) {
1232  int x = positions[P][13][X];
1233  int y = positions[P][13][Y];
1234 
1235  draw_dots16((uint16_t *)(out->data[0] + y * out->linesize[0] + x * 2), out->linesize[0] / 2, 128 * m, o);
1236  draw_dots16((uint16_t *)(out->data[1] + y * out->linesize[1] + x * 2), out->linesize[1] / 2, 0, o);
1237  draw_dots16((uint16_t *)(out->data[2] + y * out->linesize[2] + x * 2), out->linesize[2] / 2, 0, o);
1238  if (out->data[3])
1239  draw_dots16((uint16_t *)(out->data[3] + y * out->linesize[3] + x * 2), out->linesize[3] / 2, max, o);
1240  }
1241 
1242  for (i = 0; i < 6 && s->flags & 4; i++) {
1243  const uint16_t color[4] = { 128 * m, 0, 0, max };
1244  int x = positions[P][i][X];
1245  int y = positions[P][i][Y];
1246 
1247  if (x > max / 2)
1248  x += 8;
1249  else
1250  x -= 14;
1251  if (y > max / 2)
1252  y += 8;
1253  else
1254  y -= 14;
1255 
1256  x = av_clip(x, 0, out->width - 9);
1257  y = av_clip(y, 0, out->height - 9);
1258  draw_htext16(out, x, y, o, 1. - o, positions_name[i], color);
1259  }
1260 }
1261 
1262 static void green_graticule(VectorscopeContext *s, AVFrame *out, int X, int Y, int D, int P)
1263 {
1264  const float o = s->opacity;
1265  int i;
1266 
1267  for (i = 0; i < 12; i++) {
1268  int x = positions[P][i][X];
1269  int y = positions[P][i][Y];
1270 
1271  draw_dots(out->data[0] + y * out->linesize[0] + x, out->linesize[0], 128, o);
1272  draw_dots(out->data[1] + y * out->linesize[1] + x, out->linesize[1], 0, o);
1273  draw_dots(out->data[2] + y * out->linesize[2] + x, out->linesize[2], 0, o);
1274  if (out->data[3])
1275  draw_dots(out->data[3] + y * out->linesize[3] + x, out->linesize[3], 255, o);
1276  }
1277 
1278  if (s->flags & 1) {
1279  int x = positions[P][12][X];
1280  int y = positions[P][12][Y];
1281 
1282  draw_dots(out->data[0] + y * out->linesize[0] + x, out->linesize[0], 128, o);
1283  draw_dots(out->data[1] + y * out->linesize[1] + x, out->linesize[1], 0, o);
1284  draw_dots(out->data[2] + y * out->linesize[2] + x, out->linesize[2], 0, o);
1285  if (out->data[3])
1286  draw_dots(out->data[3] + y * out->linesize[3] + x, out->linesize[3], 255, o);
1287  }
1288 
1289  if (s->flags & 2) {
1290  int x = positions[P][13][X];
1291  int y = positions[P][13][Y];
1292 
1293  draw_dots(out->data[0] + y * out->linesize[0] + x, out->linesize[0], 128, o);
1294  draw_dots(out->data[1] + y * out->linesize[1] + x, out->linesize[1], 0, o);
1295  draw_dots(out->data[2] + y * out->linesize[2] + x, out->linesize[2], 0, o);
1296  if (out->data[3])
1297  draw_dots(out->data[3] + y * out->linesize[3] + x, out->linesize[3], 255, o);
1298  }
1299 
1300  for (i = 0; i < 6 && s->flags & 4; i++) {
1301  const uint8_t color[4] = { 128, 0, 0, 255 };
1302  int x = positions[P][i][X];
1303  int y = positions[P][i][Y];
1304 
1305  if (x > 128)
1306  x += 8;
1307  else
1308  x -= 14;
1309  if (y > 128)
1310  y += 8;
1311  else
1312  y -= 14;
1313 
1314  x = av_clip(x, 0, out->width - 9);
1315  y = av_clip(y, 0, out->height - 9);
1316  draw_htext(out, x, y, o, 1. - o, positions_name[i], color);
1317  }
1318 }
1319 
1320 static void invert_graticule16(VectorscopeContext *s, AVFrame *out, int X, int Y, int D, int P)
1321 {
1322  const int max = s->size - 1;
1323  const float o = s->opacity;
1324  int i;
1325 
1326  for (i = 0; i < 12; i++) {
1327  int x = positions[P][i][X];
1328  int y = positions[P][i][Y];
1329 
1330  draw_idots16((uint16_t *)(out->data[D] + y * out->linesize[D] + x * 2), out->linesize[D] / 2, max, o);
1331  draw_idots16((uint16_t *)(out->data[X] + y * out->linesize[X] + x * 2), out->linesize[X] / 2, max, o);
1332  draw_idots16((uint16_t *)(out->data[Y] + y * out->linesize[Y] + x * 2), out->linesize[Y] / 2, max, o);
1333  if (out->data[3])
1334  draw_dots16((uint16_t *)(out->data[3] + y * out->linesize[3] + x * 2), out->linesize[3] / 2, max, o);
1335  }
1336 
1337  if (s->flags & 1) {
1338  int x = positions[P][12][X];
1339  int y = positions[P][12][Y];
1340 
1341  draw_idots16((uint16_t *)(out->data[D] + y * out->linesize[D] + x * 2), out->linesize[D] / 2, max, o);
1342  draw_idots16((uint16_t *)(out->data[X] + y * out->linesize[X] + x * 2), out->linesize[X] / 2, max, o);
1343  draw_idots16((uint16_t *)(out->data[Y] + y * out->linesize[Y] + x * 2), out->linesize[Y] / 2, max, o);
1344  if (out->data[3])
1345  draw_dots16((uint16_t *)(out->data[3] + y * out->linesize[3] + x * 2), out->linesize[3] / 2, max, o);
1346  }
1347 
1348  if (s->flags & 2) {
1349  int x = positions[P][13][X];
1350  int y = positions[P][13][Y];
1351 
1352  draw_idots16((uint16_t *)(out->data[D] + y * out->linesize[D] + x * 2), out->linesize[D] / 2, max, o);
1353  draw_idots16((uint16_t *)(out->data[X] + y * out->linesize[X] + x * 2), out->linesize[X] / 2, max, o);
1354  draw_idots16((uint16_t *)(out->data[Y] + y * out->linesize[Y] + x * 2), out->linesize[Y] / 2, max, o);
1355  if (out->data[3])
1356  draw_dots16((uint16_t *)(out->data[3] + y * out->linesize[3] + x * 2), out->linesize[3] / 2, max, o);
1357  }
1358 
1359  for (i = 0; i < 6 && s->flags & 4; i++) {
1360  uint16_t color[4] = { max, max, max, max };
1361  int x = positions[P][i][X];
1362  int y = positions[P][i][Y];
1363 
1364  if (x > max / 2)
1365  x += 8;
1366  else
1367  x -= 14;
1368  if (y > max / 2)
1369  y += 8;
1370  else
1371  y -= 14;
1372 
1373  x = av_clip(x, 0, out->width - 9);
1374  y = av_clip(y, 0, out->height - 9);
1375  draw_ihtext16(out, x, y, o, 1. - o, positions_name[i], color);
1376  }
1377 }
1378 
1379 static void invert_graticule(VectorscopeContext *s, AVFrame *out, int X, int Y, int D, int P)
1380 {
1381  const float o = s->opacity;
1382  int i;
1383 
1384  for (i = 0; i < 12; i++) {
1385  int x = positions[P][i][X];
1386  int y = positions[P][i][Y];
1387 
1388  draw_idots(out->data[D] + y * out->linesize[D] + x, out->linesize[D], o);
1389  draw_idots(out->data[X] + y * out->linesize[X] + x, out->linesize[X], o);
1390  draw_idots(out->data[Y] + y * out->linesize[Y] + x, out->linesize[Y], o);
1391  if (out->data[3])
1392  draw_idots(out->data[3] + y * out->linesize[3] + x, out->linesize[3], o);
1393  }
1394 
1395  if (s->flags & 1) {
1396  int x = positions[P][12][X];
1397  int y = positions[P][12][Y];
1398 
1399  draw_idots(out->data[D] + y * out->linesize[D] + x, out->linesize[D], o);
1400  draw_idots(out->data[X] + y * out->linesize[X] + x, out->linesize[X], o);
1401  draw_idots(out->data[Y] + y * out->linesize[Y] + x, out->linesize[Y], o);
1402  if (out->data[3])
1403  draw_idots(out->data[3] + y * out->linesize[3] + x, out->linesize[3], o);
1404  }
1405 
1406  if (s->flags & 2) {
1407  int x = positions[P][13][X];
1408  int y = positions[P][13][Y];
1409 
1410  draw_idots(out->data[D] + y * out->linesize[D] + x, out->linesize[D], o);
1411  draw_idots(out->data[X] + y * out->linesize[X] + x, out->linesize[X], o);
1412  draw_idots(out->data[Y] + y * out->linesize[Y] + x, out->linesize[Y], o);
1413  if (out->data[3])
1414  draw_idots(out->data[3] + y * out->linesize[3] + x, out->linesize[3], o);
1415  }
1416 
1417  for (i = 0; i < 6 && s->flags & 4; i++) {
1418  uint8_t color[4] = { 255, 255, 255, 255 };
1419  int x = positions[P][i][X];
1420  int y = positions[P][i][Y];
1421 
1422  if (x > 128)
1423  x += 8;
1424  else
1425  x -= 14;
1426  if (y > 128)
1427  y += 8;
1428  else
1429  y -= 14;
1430 
1431  x = av_clip(x, 0, out->width - 9);
1432  y = av_clip(y, 0, out->height - 9);
1433  draw_ihtext(out, x, y, o, 1. - o, positions_name[i], color);
1434  }
1435 }
1436 
1438 {
1439  AVFilterContext *ctx = inlink->dst;
1440  VectorscopeContext *s = ctx->priv;
1441  AVFilterLink *outlink = ctx->outputs[0];
1442  AVFrame *out;
1443  int plane;
1444 
1445  s->bg_color[3] = s->bgopacity * (s->size - 1);
1446 
1447  s->tint[0] = .5f * (s->ftint[0] + 1.f) * (s->size - 1);
1448  s->tint[1] = .5f * (s->ftint[1] + 1.f) * (s->size - 1);
1449 
1450  s->intensity = s->fintensity * (s->size - 1);
1451 
1452  if (s->colorspace) {
1453  s->cs = (s->depth - 8) * 2 + s->colorspace - 1;
1454  } else {
1455  switch (in->colorspace) {
1456  case AVCOL_SPC_SMPTE170M:
1457  case AVCOL_SPC_BT470BG:
1458  s->cs = (s->depth - 8) * 2 + 0;
1459  break;
1460  case AVCOL_SPC_BT709:
1461  default:
1462  s->cs = (s->depth - 8) * 2 + 1;
1463  }
1464  }
1465 
1466  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
1467  if (!out) {
1468  av_frame_free(&in);
1469  return AVERROR(ENOMEM);
1470  }
1471  av_frame_copy_props(out, in);
1472 
1473  s->vectorscope(s, in, out, s->pd);
1474  s->graticulef(s, out, s->x, s->y, s->pd, s->cs);
1475 
1476  for (plane = 0; plane < 4; plane++) {
1477  if (out->data[plane]) {
1478  out->data[plane] += (s->size - 1) * out->linesize[plane];
1479  out->linesize[plane] = -out->linesize[plane];
1480  }
1481  }
1482 
1483  av_frame_free(&in);
1484  return ff_filter_frame(outlink, out);
1485 }
1486 
1488 {
1490  AVFilterContext *ctx = inlink->dst;
1491  VectorscopeContext *s = ctx->priv;
1492 
1493  s->is_yuv = !(desc->flags & AV_PIX_FMT_FLAG_RGB);
1494  s->size = 1 << desc->comp[0].depth;
1495  s->mult = s->size / 256;
1496  s->depth = desc->comp[0].depth;
1497  s->tmin = s->lthreshold * (s->size - 1);
1498  s->tmax = s->hthreshold * (s->size - 1);
1499 
1500  if (s->tmin > s->tmax) {
1501  av_log(ctx, AV_LOG_ERROR, "low threshold should be less than high threshold\n");
1502  return AVERROR(EINVAL);
1503  }
1504 
1505  if (s->mode == TINT && s->is_yuv) {
1506  s->pd = 0;
1507  } else {
1508  if ((s->x == 1 && s->y == 2) || (s->x == 2 && s->y == 1))
1509  s->pd = 0;
1510  else if ((s->x == 0 && s->y == 2) || (s->x == 2 && s->y == 0))
1511  s->pd = 1;
1512  else if ((s->x == 0 && s->y == 1) || (s->x == 1 && s->y == 0))
1513  s->pd = 2;
1514  }
1515 
1516  if (s->size == 256)
1517  s->vectorscope = vectorscope8;
1518  else
1519  s->vectorscope = vectorscope16;
1520 
1521  s->graticulef = none_graticule;
1522 
1523  if (s->is_yuv && s->size == 256) {
1524  if (s->graticule == GRAT_GREEN)
1525  s->graticulef = green_graticule;
1526  else if (s->graticule == GRAT_COLOR)
1527  s->graticulef = color_graticule;
1528  else if (s->graticule == GRAT_INVERT)
1529  s->graticulef = invert_graticule;
1530  } else if (s->is_yuv) {
1531  if (s->graticule == GRAT_GREEN)
1532  s->graticulef = green_graticule16;
1533  else if (s->graticule == GRAT_COLOR)
1534  s->graticulef = color_graticule16;
1535  else if (s->graticule == GRAT_INVERT)
1536  s->graticulef = invert_graticule16;
1537  }
1538 
1539  switch (inlink->format) {
1540  case AV_PIX_FMT_GBRP12:
1541  case AV_PIX_FMT_GBRP10:
1542  case AV_PIX_FMT_GBRP9:
1543  case AV_PIX_FMT_GBRAP:
1544  case AV_PIX_FMT_GBRP:
1545  s->bg_color[0] = 0;
1546  s->bg_color[1] = 0;
1547  s->bg_color[2] = 0;
1548  break;
1549  default:
1550  s->bg_color[0] = 0;
1551  s->bg_color[1] = s->size / 2;
1552  s->bg_color[2] = s->size / 2;
1553  }
1554 
1555  s->hsub = desc->log2_chroma_w;
1556  s->vsub = desc->log2_chroma_h;
1557  s->planeheight[1] = s->planeheight[2] = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h);
1558  s->planeheight[0] = s->planeheight[3] = inlink->h;
1559  s->planewidth[1] = s->planewidth[2] = AV_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w);
1560  s->planewidth[0] = s->planewidth[3] = inlink->w;
1561 
1562  return 0;
1563 }
1564 
1566 {
1567  VectorscopeContext *s = ctx->priv;
1568 
1569  av_freep(&s->peak);
1570  av_freep(&s->peak_memory);
1571 }
1572 
1573 static const AVFilterPad inputs[] = {
1574  {
1575  .name = "default",
1576  .type = AVMEDIA_TYPE_VIDEO,
1577  .filter_frame = filter_frame,
1578  .config_props = config_input,
1579  },
1580 };
1581 
1582 static const AVFilterPad outputs[] = {
1583  {
1584  .name = "default",
1585  .type = AVMEDIA_TYPE_VIDEO,
1586  .config_props = config_output,
1587  },
1588 };
1589 
1591  .name = "vectorscope",
1592  .description = NULL_IF_CONFIG_SMALL("Video vectorscope."),
1593  .priv_size = sizeof(VectorscopeContext),
1594  .priv_class = &vectorscope_class,
1595  .uninit = uninit,
1599  .process_command = ff_filter_process_command,
1600 };
ff_get_video_buffer
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:112
invert_graticule
static void invert_graticule(VectorscopeContext *s, AVFrame *out, int X, int Y, int D, int P)
Definition: vf_vectorscope.c:1379
VectorscopeMode
VectorscopeMode
Definition: vf_vectorscope.c:40
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
av_clip
#define av_clip
Definition: common.h:98
envelope_peak16
static void envelope_peak16(VectorscopeContext *s, AVFrame *out)
Definition: vf_vectorscope.c:314
query_formats
static int query_formats(AVFilterContext *ctx)
Definition: vf_vectorscope.c:212
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
outputs
static const AVFilterPad outputs[]
Definition: vf_vectorscope.c:1582
draw_dots16
static void draw_dots16(uint16_t *dst, int L, int v, float o)
Definition: vf_vectorscope.c:916
ff_make_format_list
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:435
VectorscopeContext::depth
int depth
Definition: vf_vectorscope.c:63
out_yuv10_pix_fmts
static enum AVPixelFormat out_yuv10_pix_fmts[]
Definition: vf_vectorscope.c:153
out
FILE * out
Definition: movenc.c:54
color
Definition: vf_paletteuse.c:511
FLAGS
#define FLAGS
Definition: vf_vectorscope.c:87
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1018
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2962
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(vectorscope)
inlink
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
Definition: filter_design.txt:212
VectorscopeContext::colorspace
int colorspace
Definition: vf_vectorscope.c:75
VectorscopeContext::mode
int mode
Definition: vf_vectorscope.c:52
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:160
AV_PIX_FMT_YUVA422P9
#define AV_PIX_FMT_YUVA422P9
Definition: pixfmt.h:514
AVFrame::colorspace
enum AVColorSpace colorspace
YUV colorspace type.
Definition: frame.h:665
VectorscopeContext::cs
int cs
Definition: vf_vectorscope.c:76
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:375
pixdesc.h
GRAT_NONE
@ GRAT_NONE
Definition: vf_vectorscope.c:33
AVFrame::width
int width
Definition: frame.h:447
w
uint8_t w
Definition: llviddspenc.c:38
positions_name
const static char * positions_name[]
Definition: vf_vectorscope.c:813
AV_PIX_FMT_YUVA420P10
#define AV_PIX_FMT_YUVA420P10
Definition: pixfmt.h:516
vectorscope_options
static const AVOption vectorscope_options[]
Definition: vf_vectorscope.c:90
AVOption
AVOption.
Definition: opt.h:346
FILTER_QUERY_FUNC
#define FILTER_QUERY_FUNC(func)
Definition: internal.h:159
AV_PIX_FMT_YUV420P10
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:478
out_rgb8_pix_fmts
static enum AVPixelFormat out_rgb8_pix_fmts[]
Definition: vf_vectorscope.c:163
VectorscopeContext::y
int y
Definition: vf_vectorscope.c:60
MODE_NB
@ MODE_NB
Definition: vf_vectorscope.c:47
AV_PIX_FMT_YUV440P
@ AV_PIX_FMT_YUV440P
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
Definition: pixfmt.h:106
max
#define max(a, b)
Definition: cuda_runtime.h:33
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
AVFilterFormats::formats
int * formats
list of media formats
Definition: formats.h:66
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:170
VectorscopeContext::fintensity
float fintensity
Definition: vf_vectorscope.c:54
video.h
AV_PIX_FMT_YUVA422P10
#define AV_PIX_FMT_YUVA422P10
Definition: pixfmt.h:517
draw_idots
static void draw_idots(uint8_t *dst, int L, float o)
Definition: vf_vectorscope.c:894
inputs
static const AVFilterPad inputs[]
Definition: vf_vectorscope.c:1573
color_graticule
static void color_graticule(VectorscopeContext *s, AVFrame *out, int X, int Y, int D, int P)
Definition: vf_vectorscope.c:1136
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:396
D
D(D(float, sse)
Definition: rematrix_init.c:29
hsub
static void hsub(htype *dst, const htype *src, int bins)
Definition: vf_median.c:73
AVFilterFormats
A list of supported formats for one end of a filter link.
Definition: formats.h:64
formats.h
envelope16
static void envelope16(VectorscopeContext *s, AVFrame *out)
Definition: vf_vectorscope.c:395
AVCOL_SPC_BT470BG
@ AVCOL_SPC_BT470BG
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
Definition: pixfmt.h:615
AV_PIX_FMT_YUVA420P9
#define AV_PIX_FMT_YUVA420P9
Definition: pixfmt.h:513
rgb
Definition: rpzaenc.c:60
out_yuv8_pix_fmts
static enum AVPixelFormat out_yuv8_pix_fmts[]
Definition: vf_vectorscope.c:143
positions
const static uint16_t positions[][14][3]
Definition: vf_vectorscope.c:817
AV_PIX_FMT_GBRAP
@ AV_PIX_FMT_GBRAP
planar GBRA 4:4:4:4 32bpp
Definition: pixfmt.h:212
AVFilterContext::priv
void * priv
private data for use by the filter
Definition: avfilter.h:422
AV_PIX_FMT_GBRP10
#define AV_PIX_FMT_GBRP10
Definition: pixfmt.h:494
VectorscopeContext::peak_memory
uint8_t * peak_memory
Definition: vf_vectorscope.c:77
AV_PIX_FMT_YUV422P9
#define AV_PIX_FMT_YUV422P9
Definition: pixfmt.h:476
NB_GRATICULES
@ NB_GRATICULES
Definition: vf_vectorscope.c:37
VectorscopeContext::bgopacity
float bgopacity
Definition: vf_vectorscope.c:68
COLOR3
@ COLOR3
Definition: vf_vectorscope.c:44
in1_pix_fmts
static enum AVPixelFormat in1_pix_fmts[]
Definition: vf_vectorscope.c:183
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:33
TINT
@ TINT
Definition: vf_vectorscope.c:41
AV_PIX_FMT_YUV444P10
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:481
AV_PIX_FMT_YUVJ411P
@ AV_PIX_FMT_YUVJ411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) full scale (JPEG), deprecated in favor ...
Definition: pixfmt.h:283
VectorscopeContext::pd
int pd
Definition: vf_vectorscope.c:60
in_pix_fmts
static enum AVPixelFormat in_pix_fmts[]
Definition: vf_ciescope.c:128
avassert.h
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: vf_vectorscope.c:1437
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
av_cold
#define av_cold
Definition: attributes.h:90
VectorscopeContext::intensity
int intensity
Definition: vf_vectorscope.c:53
mask
static const uint16_t mask[17]
Definition: lzw.c:38
AV_PIX_FMT_YUVJ422P
@ AV_PIX_FMT_YUVJ422P
planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting col...
Definition: pixfmt.h:86
AV_PIX_FMT_GBRAP10
#define AV_PIX_FMT_GBRAP10
Definition: pixfmt.h:498
VectorscopeContext::tmax
int tmax
Definition: vf_vectorscope.c:73
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:198
AV_PIX_FMT_GBRAP12
#define AV_PIX_FMT_GBRAP12
Definition: pixfmt.h:499
GRAT_INVERT
@ GRAT_INVERT
Definition: vf_vectorscope.c:36
AV_PIX_FMT_YUVA420P
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition: pixfmt.h:108
AV_CEIL_RSHIFT
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:58
X
@ X
Definition: vf_addroi.c:27
AVCOL_SPC_SMPTE170M
@ AVCOL_SPC_SMPTE170M
also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above
Definition: pixfmt.h:616
OFFSET
#define OFFSET(x)
Definition: vf_vectorscope.c:86
ff_formats_ref
int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add *ref as a new reference to formats.
Definition: formats.c:678
vectorscope8
static void vectorscope8(VectorscopeContext *s, AVFrame *in, AVFrame *out, int pd)
Definition: vf_vectorscope.c:617
VectorscopeContext::mult
int mult
Definition: vf_vectorscope.c:64
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
AV_PIX_FMT_YUVA444P12
#define AV_PIX_FMT_YUVA444P12
Definition: pixfmt.h:520
AV_PIX_FMT_YUV420P9
#define AV_PIX_FMT_YUV420P9
Definition: pixfmt.h:475
VectorscopeContext::graticulef
void(* graticulef)(struct VectorscopeContext *s, AVFrame *out, int X, int Y, int D, int P)
Definition: vf_vectorscope.c:82
VectorscopeContext::opacity
float opacity
Definition: vf_vectorscope.c:67
ctx
AVFormatContext * ctx
Definition: movenc.c:48
VectorscopeContext::hsub
int hsub
Definition: vf_vectorscope.c:59
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:73
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: internal.h:182
AV_PIX_FMT_YUVJ444P
@ AV_PIX_FMT_YUVJ444P
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
Definition: pixfmt.h:87
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:72
envelope_peak
static void envelope_peak(VectorscopeContext *s, AVFrame *out)
Definition: vf_vectorscope.c:365
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
NULL
#define NULL
Definition: coverity.c:32
draw_ihtext
static void draw_ihtext(AVFrame *out, int x, int y, float o1, float o2, const char *txt, const uint8_t color[4])
Definition: vf_vectorscope.c:965
av_frame_copy_props
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:709
VectorscopeContext::vectorscope
void(* vectorscope)(struct VectorscopeContext *s, AVFrame *in, AVFrame *out, int pd)
Definition: vf_vectorscope.c:80
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
AV_PIX_FMT_YUVJ420P
@ AV_PIX_FMT_YUVJ420P
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
Definition: pixfmt.h:85
VectorscopeContext::hthreshold
float hthreshold
Definition: vf_vectorscope.c:70
V
#define V
Definition: avdct.c:30
parseutils.h
AVFilterFormats::nb_formats
unsigned nb_formats
number of formats
Definition: formats.h:65
GRAT_GREEN
@ GRAT_GREEN
Definition: vf_vectorscope.c:34
green_graticule
static void green_graticule(VectorscopeContext *s, AVFrame *out, int X, int Y, int D, int P)
Definition: vf_vectorscope.c:1262
draw_idots16
static void draw_idots16(uint16_t *dst, int L, int v, float o)
Definition: vf_vectorscope.c:939
AV_PIX_FMT_YUV422P10
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:479
AV_PIX_FMT_GBRP9
#define AV_PIX_FMT_GBRP9
Definition: pixfmt.h:493
COLOR5
@ COLOR5
Definition: vf_vectorscope.c:46
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_vectorscope.c:1565
f
f
Definition: af_crystalizer.c:121
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:106
AV_PIX_FMT_FLAG_RGB
#define AV_PIX_FMT_FLAG_RGB
The pixel format contains RGB-like data (as opposed to YUV/grayscale).
Definition: pixdesc.h:136
P
#define P
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:425
AV_PIX_FMT_YUV422P12
#define AV_PIX_FMT_YUV422P12
Definition: pixfmt.h:483
hypot
static av_const double hypot(double x, double y)
Definition: libm.h:366
AV_PIX_FMT_YUV444P12
#define AV_PIX_FMT_YUV444P12
Definition: pixfmt.h:485
envelope_instant
static void envelope_instant(VectorscopeContext *s, AVFrame *out)
Definition: vf_vectorscope.c:345
out_rgb12_pix_fmts
static enum AVPixelFormat out_rgb12_pix_fmts[]
Definition: vf_vectorscope.c:178
draw_htext16
static void draw_htext16(AVFrame *out, int x, int y, float o1, float o2, const char *txt, const uint16_t color[4])
Definition: vf_vectorscope.c:1042
COLOR4
@ COLOR4
Definition: vf_vectorscope.c:45
VectorscopeContext::is_yuv
int is_yuv
Definition: vf_vectorscope.c:61
ff_filter_process_command
int ff_filter_process_command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
Generic processing of user supplied commands that are set in the same way as the filter options.
Definition: avfilter.c:890
AV_PIX_FMT_YUVA444P
@ AV_PIX_FMT_YUVA444P
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
Definition: pixfmt.h:174
AV_PIX_FMT_YUVA444P10
#define AV_PIX_FMT_YUVA444P10
Definition: pixfmt.h:518
xga_font_data.h
out_yuv12_pix_fmts
static enum AVPixelFormat out_yuv12_pix_fmts[]
Definition: vf_vectorscope.c:158
VectorscopeContext::graticule
int graticule
Definition: vf_vectorscope.c:66
in2_pix_fmts
static enum AVPixelFormat in2_pix_fmts[]
Definition: vf_vectorscope.c:194
Y
#define Y
Definition: boxblur.h:37
internal.h
ff_vf_vectorscope
const AVFilter ff_vf_vectorscope
Definition: vf_vectorscope.c:1590
AV_OPT_TYPE_FLOAT
@ AV_OPT_TYPE_FLOAT
Definition: opt.h:238
TFLAGS
#define TFLAGS
Definition: vf_vectorscope.c:88
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
VectorscopeContext::envelope
int envelope
Definition: vf_vectorscope.c:65
draw_ihtext16
static void draw_ihtext16(AVFrame *out, int x, int y, float o1, float o2, const char *txt, const uint16_t color[4])
Definition: vf_vectorscope.c:990
AV_PIX_FMT_GBRP12
#define AV_PIX_FMT_GBRP12
Definition: pixfmt.h:495
out_pix_fmts
static enum AVPixelFormat out_pix_fmts[]
Definition: vf_ciescope.c:137
vectorscope16
static void vectorscope16(VectorscopeContext *s, AVFrame *in, AVFrame *out, int pd)
Definition: vf_vectorscope.c:417
out_rgb9_pix_fmts
static enum AVPixelFormat out_rgb9_pix_fmts[]
Definition: vf_vectorscope.c:168
envelope
static void envelope(VectorscopeContext *s, AVFrame *out)
Definition: vf_vectorscope.c:406
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:39
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:262
AV_PIX_FMT_YUV444P9
#define AV_PIX_FMT_YUV444P9
Definition: pixfmt.h:477
AVFilter
Filter definition.
Definition: avfilter.h:166
ret
ret
Definition: filter_design.txt:187
GraticuleType
GraticuleType
Definition: vf_vectorscope.c:32
VectorscopeContext::lthreshold
float lthreshold
Definition: vf_vectorscope.c:69
green_graticule16
static void green_graticule16(VectorscopeContext *s, AVFrame *out, int X, int Y, int D, int P)
Definition: vf_vectorscope.c:1202
AV_PIX_FMT_YUVA444P9
#define AV_PIX_FMT_YUVA444P9
Definition: pixfmt.h:515
pos
unsigned int pos
Definition: spdifenc.c:413
VectorscopeContext::flags
int flags
Definition: vf_vectorscope.c:74
VectorscopeContext::peak
uint8_t ** peak
Definition: vf_vectorscope.c:78
AV_PIX_FMT_YUV420P12
#define AV_PIX_FMT_YUV420P12
Definition: pixfmt.h:482
AVFrame::height
int height
Definition: frame.h:447
mode
mode
Definition: ebur128.h:83
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
AV_PIX_FMT_YUVA422P12
#define AV_PIX_FMT_YUVA422P12
Definition: pixfmt.h:519
VectorscopeContext::vsub
int vsub
Definition: vf_vectorscope.c:59
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:235
avfilter.h
config_output
static int config_output(AVFilterLink *outlink)
Definition: vf_vectorscope.c:271
color_graticule16
static void color_graticule16(VectorscopeContext *s, AVFrame *out, int X, int Y, int D, int P)
Definition: vf_vectorscope.c:1068
L
#define L(x)
Definition: vpx_arith.h:36
VectorscopeContext
Definition: vf_vectorscope.c:50
config_input
static int config_input(AVFilterLink *inlink)
Definition: vf_vectorscope.c:1487
av_clip_uint8
#define av_clip_uint8
Definition: common.h:104
AV_PIX_FMT_YUV444P
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:78
AVFilterContext
An instance of a filter.
Definition: avfilter.h:407
VectorscopeContext::ftint
float ftint[2]
Definition: vf_vectorscope.c:56
AV_PIX_FMT_GBRP
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:165
desc
const char * desc
Definition: libsvtav1.c:75
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
AV_PIX_FMT_YUV422P
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:77
VectorscopeContext::tint
int tint[2]
Definition: vf_vectorscope.c:71
VectorscopeContext::planewidth
int planewidth[4]
Definition: vf_vectorscope.c:57
M_SQRT2
#define M_SQRT2
Definition: mathematics.h:109
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
VectorscopeContext::bg_color
uint16_t bg_color[4]
Definition: vf_vectorscope.c:55
none_graticule
static void none_graticule(VectorscopeContext *s, AVFrame *out, int X, int Y, int D, int P)
Definition: vf_vectorscope.c:961
avpriv_cga_font
const uint8_t avpriv_cga_font[2048]
Definition: xga_font_data.c:29
out_yuv9_pix_fmts
static enum AVPixelFormat out_yuv9_pix_fmts[]
Definition: vf_vectorscope.c:148
COLOR
@ COLOR
Definition: vf_vectorscope.c:42
draw_htext
static void draw_htext(AVFrame *out, int x, int y, float o1, float o2, const char *txt, const uint8_t color[4])
Definition: vf_vectorscope.c:1016
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: internal.h:183
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
AV_PIX_FMT_YUV411P
@ AV_PIX_FMT_YUV411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
Definition: pixfmt.h:80
VectorscopeContext::x
int x
Definition: vf_vectorscope.c:60
d
d
Definition: ffmpeg_filter.c:410
AV_OPT_TYPE_FLAGS
@ AV_OPT_TYPE_FLAGS
Definition: opt.h:234
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:474
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Definition: frame.h:420
rgb
static const SheerTable rgb[2]
Definition: sheervideodata.h:32
AV_PIX_FMT_YUV410P
@ AV_PIX_FMT_YUV410P
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
Definition: pixfmt.h:79
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
VectorscopeContext::size
int size
Definition: vf_vectorscope.c:62
out_rgb10_pix_fmts
static enum AVPixelFormat out_rgb10_pix_fmts[]
Definition: vf_vectorscope.c:173
AV_PIX_FMT_YUV440P12
#define AV_PIX_FMT_YUV440P12
Definition: pixfmt.h:484
h
h
Definition: vp9dsp_template.c:2038
invert_graticule16
static void invert_graticule16(VectorscopeContext *s, AVFrame *out, int X, int Y, int D, int P)
Definition: vf_vectorscope.c:1320
AVCOL_SPC_BT709
@ AVCOL_SPC_BT709
also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / derived in SMPTE RP 177 Annex B
Definition: pixfmt.h:611
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:244
VectorscopeContext::planeheight
int planeheight[4]
Definition: vf_vectorscope.c:58
draw_dots
static void draw_dots(uint8_t *dst, int L, int v, float o)
Definition: vf_vectorscope.c:871
AV_PIX_FMT_YUVA422P
@ AV_PIX_FMT_YUVA422P
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
Definition: pixfmt.h:173
VectorscopeContext::tmin
int tmin
Definition: vf_vectorscope.c:72
envelope_instant16
static void envelope_instant16(VectorscopeContext *s, AVFrame *out)
Definition: vf_vectorscope.c:293
GRAT_COLOR
@ GRAT_COLOR
Definition: vf_vectorscope.c:35
COLOR2
@ COLOR2
Definition: vf_vectorscope.c:43
AV_WN16
#define AV_WN16(p, v)
Definition: intreadwrite.h:370