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 
40 };
41 
42 typedef struct VectorscopeContext {
43  const AVClass *class;
44  int mode;
45  int intensity;
46  float fintensity;
47  uint16_t bg_color[4];
48  int planewidth[4];
49  int planeheight[4];
50  int hsub, vsub;
51  int x, y, pd;
52  int is_yuv;
53  int size;
54  int depth;
55  int mult;
56  int envelope;
57  int graticule;
58  float opacity;
59  float bgopacity;
60  float lthreshold;
61  float hthreshold;
62  int tmin;
63  int tmax;
64  int flags;
66  int cs;
69 
70  void (*vectorscope)(struct VectorscopeContext *s,
71  AVFrame *in, AVFrame *out, int pd);
73  int X, int Y, int D, int P);
75 
76 #define OFFSET(x) offsetof(VectorscopeContext, x)
77 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
78 
79 static const AVOption vectorscope_options[] = {
80  { "mode", "set vectorscope mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=0}, 0, MODE_NB-1, FLAGS, "mode"},
81  { "m", "set vectorscope mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=0}, 0, MODE_NB-1, FLAGS, "mode"},
82  { "gray", 0, 0, AV_OPT_TYPE_CONST, {.i64=GRAY}, 0, 0, FLAGS, "mode" },
83  { "color", 0, 0, AV_OPT_TYPE_CONST, {.i64=COLOR}, 0, 0, FLAGS, "mode" },
84  { "color2", 0, 0, AV_OPT_TYPE_CONST, {.i64=COLOR2}, 0, 0, FLAGS, "mode" },
85  { "color3", 0, 0, AV_OPT_TYPE_CONST, {.i64=COLOR3}, 0, 0, FLAGS, "mode" },
86  { "color4", 0, 0, AV_OPT_TYPE_CONST, {.i64=COLOR4}, 0, 0, FLAGS, "mode" },
87  { "color5", 0, 0, AV_OPT_TYPE_CONST, {.i64=COLOR5}, 0, 0, FLAGS, "mode" },
88  { "x", "set color component on X axis", OFFSET(x), AV_OPT_TYPE_INT, {.i64=1}, 0, 2, FLAGS},
89  { "y", "set color component on Y axis", OFFSET(y), AV_OPT_TYPE_INT, {.i64=2}, 0, 2, FLAGS},
90  { "intensity", "set intensity", OFFSET(fintensity), AV_OPT_TYPE_FLOAT, {.dbl=0.004}, 0, 1, FLAGS},
91  { "i", "set intensity", OFFSET(fintensity), AV_OPT_TYPE_FLOAT, {.dbl=0.004}, 0, 1, FLAGS},
92  { "envelope", "set envelope", OFFSET(envelope), AV_OPT_TYPE_INT, {.i64=0}, 0, 3, FLAGS, "envelope"},
93  { "e", "set envelope", OFFSET(envelope), AV_OPT_TYPE_INT, {.i64=0}, 0, 3, FLAGS, "envelope"},
94  { "none", 0, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "envelope" },
95  { "instant", 0, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "envelope" },
96  { "peak", 0, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, "envelope" },
97  { "peak+instant", 0, 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, FLAGS, "envelope" },
98  { "graticule", "set graticule", OFFSET(graticule), AV_OPT_TYPE_INT, {.i64=0}, 0, 2, FLAGS, "graticule"},
99  { "g", "set graticule", OFFSET(graticule), AV_OPT_TYPE_INT, {.i64=0}, 0, 2, FLAGS, "graticule"},
100  { "none", 0, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "graticule" },
101  { "green", 0, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "graticule" },
102  { "color", 0, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, "graticule" },
103  { "opacity", "set graticule opacity", OFFSET(opacity), AV_OPT_TYPE_FLOAT, {.dbl=0.75}, 0, 1, FLAGS},
104  { "o", "set graticule opacity", OFFSET(opacity), AV_OPT_TYPE_FLOAT, {.dbl=0.75}, 0, 1, FLAGS},
105  { "flags", "set graticule flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64=4}, 0, 7, FLAGS, "flags"},
106  { "f", "set graticule flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64=4}, 0, 7, FLAGS, "flags"},
107  { "white", "draw white point", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "flags" },
108  { "black", "draw black point", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, "flags" },
109  { "name", "draw point name", 0, AV_OPT_TYPE_CONST, {.i64=4}, 0, 0, FLAGS, "flags" },
110  { "bgopacity", "set background opacity", OFFSET(bgopacity), AV_OPT_TYPE_FLOAT, {.dbl=0.3}, 0, 1, FLAGS},
111  { "b", "set background opacity", OFFSET(bgopacity), AV_OPT_TYPE_FLOAT, {.dbl=0.3}, 0, 1, FLAGS},
112  { "lthreshold", "set low threshold", OFFSET(lthreshold), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, 1, FLAGS},
113  { "l", "set low threshold", OFFSET(lthreshold), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, 1, FLAGS},
114  { "hthreshold", "set high threshold", OFFSET(hthreshold), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 1, FLAGS},
115  { "h", "set high threshold", OFFSET(hthreshold), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 1, FLAGS},
116  { "colorspace", "set colorspace", OFFSET(colorspace), AV_OPT_TYPE_INT, {.i64=0}, 0, 2, FLAGS, "colorspace"},
117  { "c", "set colorspace", OFFSET(colorspace), AV_OPT_TYPE_INT, {.i64=0}, 0, 2, FLAGS, "colorspace"},
118  { "auto", 0, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "colorspace" },
119  { "601", 0, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "colorspace" },
120  { "709", 0, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, "colorspace" },
121  { NULL }
122 };
123 
125 
126 static const enum AVPixelFormat out_yuv8_pix_fmts[] = {
129 };
130 
131 static const enum AVPixelFormat out_yuv9_pix_fmts[] = {
134 };
135 
136 static const enum AVPixelFormat out_yuv10_pix_fmts[] = {
139 };
140 
141 static const enum AVPixelFormat out_yuv12_pix_fmts[] = {
144 };
145 
146 static const enum AVPixelFormat out_rgb8_pix_fmts[] = {
149 };
150 
151 static const enum AVPixelFormat out_rgb9_pix_fmts[] = {
154 };
155 
156 static const enum AVPixelFormat out_rgb10_pix_fmts[] = {
159 };
160 
161 static const enum AVPixelFormat out_rgb12_pix_fmts[] = {
164 };
165 
166 static const enum AVPixelFormat in1_pix_fmts[] = {
175 };
176 
177 static const enum AVPixelFormat in2_pix_fmts[] = {
192 };
193 
195 {
196  VectorscopeContext *s = ctx->priv;
197  const enum AVPixelFormat *out_pix_fmts;
198  const AVPixFmtDescriptor *desc;
199  AVFilterFormats *avff;
200  int depth, rgb, i, ret;
201 
202  if (!ctx->inputs[0]->in_formats ||
203  !ctx->inputs[0]->in_formats->nb_formats) {
204  return AVERROR(EAGAIN);
205  }
206 
207  if (!ctx->inputs[0]->out_formats) {
208  const enum AVPixelFormat *in_pix_fmts;
209 
210  if ((s->x == 1 && s->y == 2) || (s->x == 2 && s->y == 1))
212  else
214  if ((ret = ff_formats_ref(ff_make_format_list(in_pix_fmts), &ctx->inputs[0]->out_formats)) < 0)
215  return ret;
216  }
217 
218  avff = ctx->inputs[0]->in_formats;
219  desc = av_pix_fmt_desc_get(avff->formats[0]);
220  rgb = desc->flags & AV_PIX_FMT_FLAG_RGB;
221  depth = desc->comp[0].depth;
222  for (i = 1; i < avff->nb_formats; i++) {
223  desc = av_pix_fmt_desc_get(avff->formats[i]);
224  if (rgb != (desc->flags & AV_PIX_FMT_FLAG_RGB) ||
225  depth != desc->comp[0].depth)
226  return AVERROR(EAGAIN);
227  }
228 
229  if (rgb && depth == 8)
231  else if (rgb && depth == 9)
233  else if (rgb && depth == 10)
235  else if (rgb && depth == 12)
237  else if (depth == 8)
239  else if (depth == 9)
241  else if (depth == 10)
243  else if (depth == 12)
245  else
246  return AVERROR(EAGAIN);
247  if ((ret = ff_formats_ref(ff_make_format_list(out_pix_fmts), &ctx->outputs[0]->in_formats)) < 0)
248  return ret;
249 
250  return 0;
251 }
252 
253 static int config_output(AVFilterLink *outlink)
254 {
255  VectorscopeContext *s = outlink->src->priv;
256  int i;
257 
258  s->intensity = s->fintensity * (s->size - 1);
259  outlink->h = outlink->w = s->size;
260  outlink->sample_aspect_ratio = (AVRational){1,1};
261 
262  s->peak_memory = av_calloc(s->size, s->size);
263  if (!s->peak_memory)
264  return AVERROR(ENOMEM);
265 
266  s->peak = av_calloc(s->size, sizeof(*s->peak));
267  if (!s->peak)
268  return AVERROR(ENOMEM);
269 
270  for (i = 0; i < s->size; i++)
271  s->peak[i] = s->peak_memory + s->size * i;
272 
273  return 0;
274 }
275 
277 {
278  const int dlinesize = out->linesize[0] / 2;
279  uint16_t *dpd = s->mode == COLOR || !s->is_yuv ? (uint16_t *)out->data[s->pd] : (uint16_t *)out->data[0];
280  const int max = s->size - 1;
281  int i, j;
282 
283  for (i = 0; i < out->height; i++) {
284  for (j = 0; j < out->width; j++) {
285  const int pos = i * dlinesize + j;
286  const int poa = (i - 1) * dlinesize + j;
287  const int pob = (i + 1) * dlinesize + j;
288 
289  if (dpd[pos] && (((!j || !dpd[pos - 1]) || ((j == (out->width - 1)) || !dpd[pos + 1]))
290  || ((!i || !dpd[poa]) || ((i == (out->height - 1)) || !dpd[pob])))) {
291  dpd[pos] = max;
292  }
293  }
294  }
295 }
296 
298 {
299  const int dlinesize = out->linesize[0] / 2;
300  uint16_t *dpd = s->mode == COLOR || !s->is_yuv ? (uint16_t *)out->data[s->pd] : (uint16_t *)out->data[0];
301  const int max = s->size - 1;
302  int i, j;
303 
304  for (i = 0; i < out->height; i++) {
305  for (j = 0; j < out->width; j++) {
306  const int pos = i * dlinesize + j;
307 
308  if (dpd[pos])
309  s->peak[i][j] = 1;
310  }
311  }
312 
313  if (s->envelope == 3)
315 
316  for (i = 0; i < out->height; i++) {
317  for (j = 0; j < out->width; j++) {
318  const int pos = i * dlinesize + j;
319 
320  if (s->peak[i][j] && (((!j || !s->peak[i][j-1]) || ((j == (out->width - 1)) || !s->peak[i][j + 1]))
321  || ((!i || !s->peak[i-1][j]) || ((i == (out->height - 1)) || !s->peak[i + 1][j])))) {
322  dpd[pos] = max;
323  }
324  }
325  }
326 }
327 
329 {
330  const int dlinesize = out->linesize[0];
331  uint8_t *dpd = s->mode == COLOR || !s->is_yuv ? out->data[s->pd] : out->data[0];
332  int i, j;
333 
334  for (i = 0; i < out->height; i++) {
335  for (j = 0; j < out->width; j++) {
336  const int pos = i * dlinesize + j;
337  const int poa = (i - 1) * dlinesize + j;
338  const int pob = (i + 1) * dlinesize + j;
339 
340  if (dpd[pos] && (((!j || !dpd[pos - 1]) || ((j == (out->width - 1)) || !dpd[pos + 1]))
341  || ((!i || !dpd[poa]) || ((i == (out->height - 1)) || !dpd[pob])))) {
342  dpd[pos] = 255;
343  }
344  }
345  }
346 }
347 
349 {
350  const int dlinesize = out->linesize[0];
351  uint8_t *dpd = s->mode == COLOR || !s->is_yuv ? out->data[s->pd] : out->data[0];
352  int i, j;
353 
354  for (i = 0; i < out->height; i++) {
355  for (j = 0; j < out->width; j++) {
356  const int pos = i * dlinesize + j;
357 
358  if (dpd[pos])
359  s->peak[i][j] = 1;
360  }
361  }
362 
363  if (s->envelope == 3)
365 
366  for (i = 0; i < out->height; i++) {
367  for (j = 0; j < out->width; j++) {
368  const int pos = i * dlinesize + j;
369 
370  if (s->peak[i][j] && (((!j || !s->peak[i][j-1]) || ((j == (out->width - 1)) || !s->peak[i][j + 1]))
371  || ((!i || !s->peak[i-1][j]) || ((i == (out->height - 1)) || !s->peak[i + 1][j])))) {
372  dpd[pos] = 255;
373  }
374  }
375  }
376 }
377 
379 {
380  if (!s->envelope) {
381  return;
382  } else if (s->envelope == 1) {
384  } else {
386  }
387 }
388 
390 {
391  if (!s->envelope) {
392  return;
393  } else if (s->envelope == 1) {
395  } else {
396  envelope_peak(s, out);
397  }
398 }
399 
401 {
402  const uint16_t * const *src = (const uint16_t * const *)in->data;
403  const int slinesizex = in->linesize[s->x] / 2;
404  const int slinesizey = in->linesize[s->y] / 2;
405  const int slinesized = in->linesize[pd] / 2;
406  const int dlinesize = out->linesize[0] / 2;
407  const int intensity = s->intensity;
408  const int px = s->x, py = s->y;
409  const int h = s->planeheight[py];
410  const int w = s->planewidth[px];
411  const uint16_t *spx = src[px];
412  const uint16_t *spy = src[py];
413  const uint16_t *spd = src[pd];
414  const int hsub = s->hsub;
415  const int vsub = s->vsub;
416  uint16_t **dst = (uint16_t **)out->data;
417  uint16_t *dpx = dst[px];
418  uint16_t *dpy = dst[py];
419  uint16_t *dpd = dst[pd];
420  const int max = s->size - 1;
421  const int mid = s->size / 2;
422  const int tmin = s->tmin;
423  const int tmax = s->tmax;
424  int i, j, k;
425 
426  for (k = 0; k < 4 && dst[k]; k++) {
427  for (i = 0; i < out->height ; i++)
428  for (j = 0; j < out->width; j++)
429  AV_WN16(out->data[k] + i * out->linesize[k] + j * 2,
430  (s->mode == COLOR || s->mode == COLOR5) && k == s->pd ? 0 : s->bg_color[k]);
431  }
432 
433  switch (s->mode) {
434  case COLOR:
435  case COLOR5:
436  case GRAY:
437  if (s->is_yuv) {
438  for (i = 0; i < h; i++) {
439  const int iwx = i * slinesizex;
440  const int iwy = i * slinesizey;
441  const int iwd = i * slinesized;
442  for (j = 0; j < w; j++) {
443  const int x = FFMIN(spx[iwx + j], max);
444  const int y = FFMIN(spy[iwy + j], max);
445  const int z = spd[iwd + j];
446  const int pos = y * dlinesize + x;
447 
448  if (z < tmin || z > tmax)
449  continue;
450 
451  dpd[pos] = FFMIN(dpd[pos] + intensity, max);
452  }
453  }
454  } else {
455  for (i = 0; i < h; i++) {
456  const int iwx = i * slinesizex;
457  const int iwy = i * slinesizey;
458  const int iwd = i * slinesized;
459  for (j = 0; j < w; j++) {
460  const int x = FFMIN(spx[iwx + j], max);
461  const int y = FFMIN(spy[iwy + j], max);
462  const int z = spd[iwd + j];
463  const int pos = y * dlinesize + x;
464 
465  if (z < tmin || z > tmax)
466  continue;
467 
468  dst[0][pos] = FFMIN(dst[0][pos] + intensity, max);
469  dst[1][pos] = FFMIN(dst[1][pos] + intensity, max);
470  dst[2][pos] = FFMIN(dst[2][pos] + intensity, max);
471  }
472  }
473  }
474  break;
475  case COLOR2:
476  if (s->is_yuv) {
477  for (i = 0; i < h; i++) {
478  const int iw1 = i * slinesizex;
479  const int iw2 = i * slinesizey;
480  const int iwd = i * slinesized;
481  for (j = 0; j < w; j++) {
482  const int x = FFMIN(spx[iw1 + j], max);
483  const int y = FFMIN(spy[iw2 + j], max);
484  const int z = spd[iwd + j];
485  const int pos = y * dlinesize + x;
486 
487  if (z < tmin || z > tmax)
488  continue;
489 
490  if (!dpd[pos])
491  dpd[pos] = FFABS(mid - x) + FFABS(mid - y);
492  dpx[pos] = x;
493  dpy[pos] = y;
494  }
495  }
496  } else {
497  for (i = 0; i < h; i++) {
498  const int iw1 = i * slinesizex;
499  const int iw2 = i * slinesizey;
500  const int iwd = i * slinesized;
501  for (j = 0; j < w; j++) {
502  const int x = FFMIN(spx[iw1 + j], max);
503  const int y = FFMIN(spy[iw2 + j], max);
504  const int z = spd[iwd + j];
505  const int pos = y * dlinesize + x;
506 
507  if (z < tmin || z > tmax)
508  continue;
509 
510  if (!dpd[pos])
511  dpd[pos] = FFMIN(x + y, max);
512  dpx[pos] = x;
513  dpy[pos] = y;
514  }
515  }
516  }
517  break;
518  case COLOR3:
519  for (i = 0; i < h; i++) {
520  const int iw1 = i * slinesizex;
521  const int iw2 = i * slinesizey;
522  const int iwd = i * slinesized;
523  for (j = 0; j < w; j++) {
524  const int x = FFMIN(spx[iw1 + j], max);
525  const int y = FFMIN(spy[iw2 + j], max);
526  const int z = spd[iwd + j];
527  const int pos = y * dlinesize + x;
528 
529  if (z < tmin || z > tmax)
530  continue;
531 
532  dpd[pos] = FFMIN(max, dpd[pos] + intensity);
533  dpx[pos] = x;
534  dpy[pos] = y;
535  }
536  }
537  break;
538  case COLOR4:
539  for (i = 0; i < in->height; i++) {
540  const int iwx = (i >> vsub) * slinesizex;
541  const int iwy = (i >> vsub) * slinesizey;
542  const int iwd = i * slinesized;
543  for (j = 0; j < in->width; j++) {
544  const int x = FFMIN(spx[iwx + (j >> hsub)], max);
545  const int y = FFMIN(spy[iwy + (j >> hsub)], max);
546  const int z = spd[iwd + j];
547  const int pos = y * dlinesize + x;
548 
549  if (z < tmin || z > tmax)
550  continue;
551 
552  dpd[pos] = FFMAX(z, dpd[pos]);
553  dpx[pos] = x;
554  dpy[pos] = y;
555  }
556  }
557  break;
558  default:
559  av_assert0(0);
560  }
561 
562  envelope16(s, out);
563 
564  if (dst[3]) {
565  for (i = 0; i < out->height; i++) {
566  for (j = 0; j < out->width; j++) {
567  int pos = i * dlinesize + j;
568 
569  if (dpd[pos])
570  dst[3][pos] = max;
571  }
572  }
573  }
574 
575  if (s->mode == COLOR) {
576  for (i = 0; i < out->height; i++) {
577  for (j = 0; j < out->width; j++) {
578  if (!dpd[i * dlinesize + j]) {
579  dpx[i * dlinesize + j] = j;
580  dpy[i * dlinesize + j] = i;
581  dpd[i * dlinesize + j] = mid;
582  }
583  }
584  }
585  } else if (s->mode == COLOR5) {
586  for (i = 0; i < out->height; i++) {
587  for (j = 0; j < out->width; j++) {
588  if (!dpd[i * dlinesize + j]) {
589  dpx[i * dlinesize + j] = j;
590  dpy[i * dlinesize + j] = i;
591  dpd[i * dlinesize + j] = mid * M_SQRT2 - hypot(i - mid, j - mid);
592  }
593  }
594  }
595  }
596 }
597 
599 {
600  const uint8_t * const *src = (const uint8_t * const *)in->data;
601  const int slinesizex = in->linesize[s->x];
602  const int slinesizey = in->linesize[s->y];
603  const int slinesized = in->linesize[pd];
604  const int dlinesize = out->linesize[0];
605  const int intensity = s->intensity;
606  const int px = s->x, py = s->y;
607  const int h = s->planeheight[py];
608  const int w = s->planewidth[px];
609  const uint8_t *spx = src[px];
610  const uint8_t *spy = src[py];
611  const uint8_t *spd = src[pd];
612  const int hsub = s->hsub;
613  const int vsub = s->vsub;
614  uint8_t **dst = out->data;
615  uint8_t *dpx = dst[px];
616  uint8_t *dpy = dst[py];
617  uint8_t *dpd = dst[pd];
618  const int tmin = s->tmin;
619  const int tmax = s->tmax;
620  int i, j, k;
621 
622  for (k = 0; k < 4 && dst[k]; k++)
623  for (i = 0; i < out->height ; i++)
624  memset(dst[k] + i * out->linesize[k],
625  (s->mode == COLOR || s->mode == COLOR5) && k == s->pd ? 0 : s->bg_color[k], out->width);
626 
627  switch (s->mode) {
628  case COLOR5:
629  case COLOR:
630  case GRAY:
631  if (s->is_yuv) {
632  for (i = 0; i < h; i++) {
633  const int iwx = i * slinesizex;
634  const int iwy = i * slinesizey;
635  const int iwd = i * slinesized;
636  for (j = 0; j < w; j++) {
637  const int x = spx[iwx + j];
638  const int y = spy[iwy + j];
639  const int z = spd[iwd + j];
640  const int pos = y * dlinesize + x;
641 
642  if (z < tmin || z > tmax)
643  continue;
644 
645  dpd[pos] = FFMIN(dpd[pos] + intensity, 255);
646  }
647  }
648  } else {
649  for (i = 0; i < h; i++) {
650  const int iwx = i * slinesizex;
651  const int iwy = i * slinesizey;
652  const int iwd = i * slinesized;
653  for (j = 0; j < w; j++) {
654  const int x = spx[iwx + j];
655  const int y = spy[iwy + j];
656  const int z = spd[iwd + j];
657  const int pos = y * dlinesize + x;
658 
659  if (z < tmin || z > tmax)
660  continue;
661 
662  dst[0][pos] = FFMIN(dst[0][pos] + intensity, 255);
663  dst[1][pos] = FFMIN(dst[1][pos] + intensity, 255);
664  dst[2][pos] = FFMIN(dst[2][pos] + intensity, 255);
665  }
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 == COLOR) {
770  for (i = 0; i < out->height; i++) {
771  for (j = 0; j < out->width; j++) {
772  if (!dpd[i * out->linesize[pd] + j]) {
773  dpx[i * out->linesize[px] + j] = j;
774  dpy[i * out->linesize[py] + j] = i;
775  dpd[i * out->linesize[pd] + j] = 128;
776  }
777  }
778  }
779  } else if (s->mode == COLOR5) {
780  for (i = 0; i < out->height; i++) {
781  for (j = 0; j < out->width; j++) {
782  if (!dpd[i * out->linesize[pd] + j]) {
783  dpx[i * out->linesize[px] + j] = j;
784  dpy[i * out->linesize[py] + j] = i;
785  dpd[i * out->linesize[pd] + j] = 128 * M_SQRT2 - hypot(i - 128, j - 128);
786  }
787  }
788  }
789  }
790 }
791 
792 const static char *positions_name[] = {
793  "R", "B", "Cy", "Yl", "G", "Mg",
794 };
795 
796 const static uint16_t positions[][14][3] = {
797  {
798  { 81, 90, 240 }, { 41, 240, 110 }, { 170, 166, 16 },
799  { 210, 16, 146 }, { 145, 54, 34 }, { 106, 202, 222 },
800  { 162, 44, 142 }, { 131, 156, 44 }, { 112, 72, 58 },
801  { 84, 184, 198 }, { 65, 100, 212 }, { 35, 212, 114 },
802  { 235, 128, 128 }, { 16, 128, 128 } },
803  { { 63, 102, 240 }, { 32, 240, 118 }, { 188, 154, 16 },
804  { 219, 16, 138 }, { 173, 42, 26 }, { 78, 214, 230 },
805  { 28, 212, 120 }, { 51, 109, 212 }, { 63, 193, 204 },
806  { 133, 63, 52 }, { 145, 147, 44 }, { 168, 44, 136 },
807  { 235, 128, 128 }, { 16, 128, 128 } },
808  { { 81*2, 90*2, 240*2 }, { 41*2, 240*2, 110*2 }, { 170*2, 166*2, 16*2 },
809  { 210*2, 16*2, 146*2 }, { 145*2, 54*2, 34*2 }, { 106*2, 202*2, 222*2 },
810  { 162*2, 44*2, 142*2 }, { 131*2, 156*2, 44*2 }, { 112*2, 72*2, 58*2 },
811  { 84*2, 184*2, 198*2 }, { 65*2, 100*2, 212*2 }, { 35*2, 212*2, 114*2 },
812  { 470, 256, 256 }, { 32, 256, 256 } },
813  { { 63*2, 102*2, 240*2 }, { 32*2, 240*2, 118*2 }, { 188*2, 154*2, 16*2 },
814  { 219*2, 16*2, 138*2 }, { 173*2, 42*2, 26*2 }, { 78*2, 214*2, 230*2 },
815  { 28*2, 212*2, 120*2 }, { 51*2, 109*2, 212*2 }, { 63*2, 193*2, 204*2 },
816  { 133*2, 63*2, 52*2 }, { 145*2, 147*2, 44*2 }, { 168*2, 44*2, 136*2 },
817  { 470, 256, 256 }, { 32, 256, 256 } },
818  { { 81*4, 90*4, 240*4 }, { 41*4, 240*4, 110*4 }, { 170*4, 166*4, 16*4 },
819  { 210*4, 16*4, 146*4 }, { 145*4, 54*4, 34*4 }, { 106*4, 202*4, 222*4 },
820  { 162*4, 44*4, 142*4 }, { 131*4, 156*4, 44*4 }, { 112*4, 72*4, 58*4 },
821  { 84*4, 184*4, 198*4 }, { 65*4, 100*4, 212*4 }, { 35*4, 212*4, 114*4 },
822  { 940, 512, 512 }, { 64, 512, 512 } },
823  { { 63*4, 102*4, 240*4 }, { 32*4, 240*4, 118*4 }, { 188*4, 154*4, 16*4 },
824  { 219*4, 16*4, 138*4 }, { 173*4, 42*4, 26*4 }, { 78*4, 214*4, 230*4 },
825  { 28*4, 212*4, 120*4 }, { 51*4, 109*4, 212*4 }, { 63*4, 193*4, 204*4 },
826  { 133*4, 63*4, 52*4 }, { 145*4, 147*4, 44*4 }, { 168*4, 44*4, 136*4 },
827  { 940, 512, 512 }, { 64, 512, 512 } },
828  { { 81*8, 90*4, 240*8 }, { 41*8, 240*8, 110*8 }, { 170*8, 166*8, 16*8 },
829  { 210*8, 16*4, 146*8 }, { 145*8, 54*8, 34*8 }, { 106*8, 202*8, 222*8 },
830  { 162*8, 44*4, 142*8 }, { 131*8, 156*8, 44*8 }, { 112*8, 72*8, 58*8 },
831  { 84*8, 184*4, 198*8 }, { 65*8, 100*8, 212*8 }, { 35*8, 212*8, 114*8 },
832  { 1880, 1024, 1024 }, { 128, 1024, 1024 } },
833  { { 63*8, 102*8, 240*8 }, { 32*8, 240*8, 118*8 }, { 188*8, 154*8, 16*8 },
834  { 219*8, 16*8, 138*8 }, { 173*8, 42*8, 26*8 }, { 78*8, 214*8, 230*8 },
835  { 28*8, 212*8, 120*8 }, { 51*8, 109*8, 212*8 }, { 63*8, 193*8, 204*8 },
836  { 133*8, 63*8, 52*8 }, { 145*8, 147*8, 44*8 }, { 168*8, 44*8, 136*8 },
837  { 1880, 1024, 1024 }, { 128, 1024, 1024 } },
838  { { 81*16, 90*16, 240*16 }, { 41*16, 240*16, 110*16 }, { 170*16, 166*16, 16*16 },
839  { 210*16, 16*16, 146*16 }, { 145*16, 54*16, 34*16 }, { 106*16, 202*16, 222*16 },
840  { 162*16, 44*16, 142*16 }, { 131*16, 156*16, 44*16 }, { 112*16, 72*16, 58*16 },
841  { 84*16, 184*16, 198*16 }, { 65*16, 100*16, 212*16 }, { 35*16, 212*16, 114*16 },
842  { 3760, 2048, 2048 }, { 256, 2048, 2048 } },
843  { { 63*16, 102*16, 240*16 }, { 32*16, 240*16, 118*16 }, { 188*16, 154*16, 16*16 },
844  { 219*16, 16*16, 138*16 }, { 173*16, 42*16, 26*16 }, { 78*16, 214*16, 230*16 },
845  { 28*16, 212*16, 120*16 }, { 51*16, 109*16, 212*16 }, { 63*16, 193*16, 204*16 },
846  { 133*16, 63*16, 52*16 }, { 145*16, 147*16, 44*16 }, { 168*16, 44*16, 136*16 },
847  { 3760, 2048, 2048 }, { 256, 2048, 2048 } },
848 };
849 
850 static void draw_dots(uint8_t *dst, int L, int v, float o)
851 {
852  const float f = 1. - o;
853  const float V = o * v;
854  int l = L * 2;
855 
856  dst[ l - 3] = dst[ l - 3] * f + V;
857  dst[ l + 3] = dst[ l + 3] * f + V;
858  dst[-l - 3] = dst[-l - 3] * f + V;
859  dst[-l + 3] = dst[-l + 3] * f + V;
860 
861  l += L;
862 
863  dst[ l - 3] = dst[ l - 3] * f + V;
864  dst[ l + 3] = dst[ l + 3] * f + V;
865  dst[ l - 2] = dst[ l - 2] * f + V;
866  dst[ l + 2] = dst[ l + 2] * f + V;
867  dst[-l - 3] = dst[-l - 3] * f + V;
868  dst[-l + 3] = dst[-l + 3] * f + V;
869  dst[-l - 2] = dst[-l - 2] * f + V;
870  dst[-l + 2] = dst[-l + 2] * f + V;
871 }
872 
873 static void draw_dots16(uint16_t *dst, int L, int v, float o)
874 {
875  const float f = 1. - o;
876  const float V = o * v;
877  int l = L * 2;
878 
879  dst[ l - 3] = dst[ l - 3] * f + V;
880  dst[ l + 3] = dst[ l + 3] * f + V;
881  dst[-l - 3] = dst[-l - 3] * f + V;
882  dst[-l + 3] = dst[-l + 3] * f + V;
883 
884  l += L;
885 
886  dst[ l - 3] = dst[ l - 3] * f + V;
887  dst[ l + 3] = dst[ l + 3] * f + V;
888  dst[ l - 2] = dst[ l - 2] * f + V;
889  dst[ l + 2] = dst[ l + 2] * f + V;
890  dst[-l - 3] = dst[-l - 3] * f + V;
891  dst[-l + 3] = dst[-l + 3] * f + V;
892  dst[-l - 2] = dst[-l - 2] * f + V;
893  dst[-l + 2] = dst[-l + 2] * f + V;
894 }
895 
896 static void none_graticule(VectorscopeContext *s, AVFrame *out, int X, int Y, int D, int P)
897 {
898 }
899 
900 static void draw_htext(AVFrame *out, int x, int y, float o1, float o2, const char *txt, const uint8_t color[4])
901 {
902  const uint8_t *font;
903  int font_height;
904  int i, plane;
905 
906  font = avpriv_cga_font, font_height = 8;
907 
908  for (plane = 0; plane < 4 && out->data[plane]; plane++) {
909  for (i = 0; txt[i]; i++) {
910  int char_y, mask;
911  int v = color[plane];
912 
913  uint8_t *p = out->data[plane] + y * out->linesize[plane] + (x + i * 8);
914  for (char_y = font_height - 1; char_y >= 0; char_y--) {
915  for (mask = 0x80; mask; mask >>= 1) {
916  if (font[txt[i] * font_height + char_y] & mask)
917  p[0] = p[0] * o2 + v * o1;
918  p++;
919  }
920  p += out->linesize[plane] - 8;
921  }
922  }
923  }
924 }
925 
926 static void draw_htext16(AVFrame *out, int x, int y, float o1, float o2, const char *txt, const uint16_t color[4])
927 {
928  const uint8_t *font;
929  int font_height;
930  int i, plane;
931 
932  font = avpriv_cga_font, font_height = 8;
933 
934  for (plane = 0; plane < 4 && out->data[plane]; plane++) {
935  for (i = 0; txt[i]; i++) {
936  int char_y, mask;
937  int v = color[plane];
938 
939  uint16_t *p = (uint16_t *)(out->data[plane] + y * out->linesize[plane]) + (x + i * 8);
940  for (char_y = font_height - 1; char_y >= 0; char_y--) {
941  for (mask = 0x80; mask; mask >>= 1) {
942  if (font[txt[i] * font_height + char_y] & mask)
943  p[0] = p[0] * o2 + v * o1;
944  p++;
945  }
946  p += out->linesize[plane] / 2 - 8;
947  }
948  }
949  }
950 }
951 
952 static void color_graticule16(VectorscopeContext *s, AVFrame *out, int X, int Y, int D, int P)
953 {
954  const int max = s->size - 1;
955  const float o = s->opacity;
956  int i;
957 
958  for (i = 0; i < 12; i++) {
959  int x = positions[P][i][X];
960  int y = positions[P][i][Y];
961  int d = positions[P][i][D];
962 
963  draw_dots16((uint16_t *)(out->data[D] + y * out->linesize[D] + x * 2), out->linesize[D] / 2, d, o);
964  draw_dots16((uint16_t *)(out->data[X] + y * out->linesize[X] + x * 2), out->linesize[X] / 2, x, o);
965  draw_dots16((uint16_t *)(out->data[Y] + y * out->linesize[Y] + x * 2), out->linesize[Y] / 2, y, o);
966  if (out->data[3])
967  draw_dots16((uint16_t *)(out->data[3] + y * out->linesize[3] + x * 2), out->linesize[3] / 2, max, o);
968  }
969 
970  if (s->flags & 1) {
971  int x = positions[P][12][X];
972  int y = positions[P][12][Y];
973  int d = positions[P][12][D];
974 
975  draw_dots16((uint16_t *)(out->data[D] + y * out->linesize[D] + x * 2), out->linesize[D] / 2, d, o);
976  draw_dots16((uint16_t *)(out->data[X] + y * out->linesize[X] + x * 2), out->linesize[X] / 2, x, o);
977  draw_dots16((uint16_t *)(out->data[Y] + y * out->linesize[Y] + x * 2), out->linesize[Y] / 2, y, o);
978  if (out->data[3])
979  draw_dots16((uint16_t *)(out->data[3] + y * out->linesize[3] + x * 2), out->linesize[3] / 2, max, o);
980  }
981 
982  if (s->flags & 2) {
983  int x = positions[P][13][X];
984  int y = positions[P][13][Y];
985  int d = positions[P][13][D];
986 
987  draw_dots16((uint16_t *)(out->data[D] + y * out->linesize[D] + x * 2), out->linesize[D] / 2, d, o);
988  draw_dots16((uint16_t *)(out->data[X] + y * out->linesize[X] + x * 2), out->linesize[X] / 2, x, o);
989  draw_dots16((uint16_t *)(out->data[Y] + y * out->linesize[Y] + x * 2), out->linesize[Y] / 2, y, o);
990  if (out->data[3])
991  draw_dots16((uint16_t *)(out->data[3] + y * out->linesize[3] + x * 2), out->linesize[3] / 2, max, o);
992  }
993 
994  for (i = 0; i < 6 && s->flags & 4; i++) {
995  uint16_t color[4] = { 0, 0, 0, 0 };
996  int x = positions[P][i][X];
997  int y = positions[P][i][Y];
998  int d = positions[P][i][D];
999 
1000  color[D] = d;
1001  color[X] = x;
1002  color[Y] = y;
1003  color[3] = max;
1004 
1005  if (x > max / 2)
1006  x += 8;
1007  else
1008  x -= 14;
1009  if (y > max / 2)
1010  y += 8;
1011  else
1012  y -= 14;
1013 
1014  x = av_clip(x, 0, out->width - 9);
1015  y = av_clip(y, 0, out->height - 9);
1016  draw_htext16(out, x, y, o, 1. - o, positions_name[i], color);
1017  }
1018 }
1019 
1020 static void color_graticule(VectorscopeContext *s, AVFrame *out, int X, int Y, int D, int P)
1021 {
1022  const float o = s->opacity;
1023  int i;
1024 
1025  for (i = 0; i < 12; i++) {
1026  int x = positions[P][i][X];
1027  int y = positions[P][i][Y];
1028  int d = positions[P][i][D];
1029 
1030  draw_dots(out->data[D] + y * out->linesize[D] + x, out->linesize[D], d, o);
1031  draw_dots(out->data[X] + y * out->linesize[X] + x, out->linesize[X], x, o);
1032  draw_dots(out->data[Y] + y * out->linesize[Y] + x, out->linesize[Y], y, o);
1033  if (out->data[3])
1034  draw_dots(out->data[3] + y * out->linesize[3] + x, out->linesize[3], 255, o);
1035  }
1036 
1037  if (s->flags & 1) {
1038  int x = positions[P][12][X];
1039  int y = positions[P][12][Y];
1040  int d = positions[P][12][D];
1041 
1042  draw_dots(out->data[D] + y * out->linesize[D] + x, out->linesize[D], d, o);
1043  draw_dots(out->data[X] + y * out->linesize[X] + x, out->linesize[X], x, o);
1044  draw_dots(out->data[Y] + y * out->linesize[Y] + x, out->linesize[Y], y, o);
1045  if (out->data[3])
1046  draw_dots(out->data[3] + y * out->linesize[3] + x, out->linesize[3], 255, o);
1047  }
1048 
1049  if (s->flags & 2) {
1050  int x = positions[P][13][X];
1051  int y = positions[P][13][Y];
1052  int d = positions[P][12][D];
1053 
1054  draw_dots(out->data[D] + y * out->linesize[D] + x, out->linesize[D], d, o);
1055  draw_dots(out->data[X] + y * out->linesize[X] + x, out->linesize[X], x, o);
1056  draw_dots(out->data[Y] + y * out->linesize[Y] + x, out->linesize[Y], y, o);
1057  if (out->data[3])
1058  draw_dots(out->data[3] + y * out->linesize[3] + x, out->linesize[3], 255, o);
1059  }
1060 
1061  for (i = 0; i < 6 && s->flags & 4; i++) {
1062  uint8_t color[4] = { 0, 0, 0, 255 };
1063  int x = positions[P][i][X];
1064  int y = positions[P][i][Y];
1065  int d = positions[P][i][D];
1066 
1067  color[D] = d;
1068  color[X] = x;
1069  color[Y] = y;
1070 
1071  if (x > 128)
1072  x += 8;
1073  else
1074  x -= 14;
1075  if (y > 128)
1076  y += 8;
1077  else
1078  y -= 14;
1079 
1080  x = av_clip(x, 0, out->width - 9);
1081  y = av_clip(y, 0, out->height - 9);
1082  draw_htext(out, x, y, o, 1. - o, positions_name[i], color);
1083  }
1084 }
1085 
1086 static void green_graticule16(VectorscopeContext *s, AVFrame *out, int X, int Y, int D, int P)
1087 {
1088  const int max = s->size - 1;
1089  const float o = s->opacity;
1090  const int m = s->mult;
1091  int i;
1092 
1093  for (i = 0; i < 12; i++) {
1094  int x = positions[P][i][X];
1095  int y = positions[P][i][Y];
1096 
1097  draw_dots16((uint16_t *)(out->data[0] + y * out->linesize[0] + x * 2), out->linesize[0] / 2, 128 * m, o);
1098  draw_dots16((uint16_t *)(out->data[1] + y * out->linesize[1] + x * 2), out->linesize[1] / 2, 0, o);
1099  draw_dots16((uint16_t *)(out->data[2] + y * out->linesize[2] + x * 2), out->linesize[2] / 2, 0, o);
1100  if (out->data[3])
1101  draw_dots16((uint16_t *)(out->data[3] + y * out->linesize[3] + x * 2), out->linesize[3] / 2, max, o);
1102  }
1103 
1104  if (s->flags & 1) {
1105  int x = positions[P][12][X];
1106  int y = positions[P][12][Y];
1107 
1108  draw_dots16((uint16_t *)(out->data[0] + y * out->linesize[0] + x * 2), out->linesize[0] / 2, 128 * m, o);
1109  draw_dots16((uint16_t *)(out->data[1] + y * out->linesize[1] + x * 2), out->linesize[1] / 2, 0, o);
1110  draw_dots16((uint16_t *)(out->data[2] + y * out->linesize[2] + x * 2), out->linesize[2] / 2, 0, o);
1111  if (out->data[3])
1112  draw_dots16((uint16_t *)(out->data[3] + y * out->linesize[3] + x * 2), out->linesize[3] / 2, max, o);
1113  }
1114 
1115  if (s->flags & 2) {
1116  int x = positions[P][13][X];
1117  int y = positions[P][13][Y];
1118 
1119  draw_dots16((uint16_t *)(out->data[0] + y * out->linesize[0] + x * 2), out->linesize[0] / 2, 128 * m, o);
1120  draw_dots16((uint16_t *)(out->data[1] + y * out->linesize[1] + x * 2), out->linesize[1] / 2, 0, o);
1121  draw_dots16((uint16_t *)(out->data[2] + y * out->linesize[2] + x * 2), out->linesize[2] / 2, 0, o);
1122  if (out->data[3])
1123  draw_dots16((uint16_t *)(out->data[3] + y * out->linesize[3] + x * 2), out->linesize[3] / 2, max, o);
1124  }
1125 
1126  for (i = 0; i < 6 && s->flags & 4; i++) {
1127  const uint16_t color[4] = { 128 * m, 0, 0, max };
1128  int x = positions[P][i][X];
1129  int y = positions[P][i][Y];
1130 
1131  if (x > max / 2)
1132  x += 8;
1133  else
1134  x -= 14;
1135  if (y > max / 2)
1136  y += 8;
1137  else
1138  y -= 14;
1139 
1140  x = av_clip(x, 0, out->width - 9);
1141  y = av_clip(y, 0, out->height - 9);
1142  draw_htext16(out, x, y, o, 1. - o, positions_name[i], color);
1143  }
1144 }
1145 
1146 static void green_graticule(VectorscopeContext *s, AVFrame *out, int X, int Y, int D, int P)
1147 {
1148  const float o = s->opacity;
1149  int i;
1150 
1151  for (i = 0; i < 12; i++) {
1152  int x = positions[P][i][X];
1153  int y = positions[P][i][Y];
1154 
1155  draw_dots(out->data[0] + y * out->linesize[0] + x, out->linesize[0], 128, o);
1156  draw_dots(out->data[1] + y * out->linesize[1] + x, out->linesize[1], 0, o);
1157  draw_dots(out->data[2] + y * out->linesize[2] + x, out->linesize[2], 0, o);
1158  if (out->data[3])
1159  draw_dots(out->data[3] + y * out->linesize[3] + x, out->linesize[3], 255, o);
1160  }
1161 
1162  if (s->flags & 1) {
1163  int x = positions[P][12][X];
1164  int y = positions[P][12][Y];
1165 
1166  draw_dots(out->data[0] + y * out->linesize[0] + x, out->linesize[0], 128, o);
1167  draw_dots(out->data[1] + y * out->linesize[1] + x, out->linesize[1], 0, o);
1168  draw_dots(out->data[2] + y * out->linesize[2] + x, out->linesize[2], 0, o);
1169  if (out->data[3])
1170  draw_dots(out->data[3] + y * out->linesize[3] + x, out->linesize[3], 255, o);
1171  }
1172 
1173  if (s->flags & 2) {
1174  int x = positions[P][13][X];
1175  int y = positions[P][13][Y];
1176 
1177  draw_dots(out->data[0] + y * out->linesize[0] + x, out->linesize[0], 128, o);
1178  draw_dots(out->data[1] + y * out->linesize[1] + x, out->linesize[1], 0, o);
1179  draw_dots(out->data[2] + y * out->linesize[2] + x, out->linesize[2], 0, o);
1180  if (out->data[3])
1181  draw_dots(out->data[3] + y * out->linesize[3] + x, out->linesize[3], 255, o);
1182  }
1183 
1184  for (i = 0; i < 6 && s->flags & 4; i++) {
1185  const uint8_t color[4] = { 128, 0, 0, 255 };
1186  int x = positions[P][i][X];
1187  int y = positions[P][i][Y];
1188 
1189  if (x > 128)
1190  x += 8;
1191  else
1192  x -= 14;
1193  if (y > 128)
1194  y += 8;
1195  else
1196  y -= 14;
1197 
1198  x = av_clip(x, 0, out->width - 9);
1199  y = av_clip(y, 0, out->height - 9);
1200  draw_htext(out, x, y, o, 1. - o, positions_name[i], color);
1201  }
1202 }
1203 
1205 {
1206  AVFilterContext *ctx = inlink->dst;
1207  VectorscopeContext *s = ctx->priv;
1208  AVFilterLink *outlink = ctx->outputs[0];
1209  AVFrame *out;
1210  int plane;
1211 
1212  if (s->colorspace) {
1213  s->cs = (s->depth - 8) * 2 + s->colorspace - 1;
1214  } else {
1215  switch (in->colorspace) {
1216  case AVCOL_SPC_SMPTE170M:
1217  case AVCOL_SPC_BT470BG:
1218  s->cs = (s->depth - 8) * 2 + 0;
1219  break;
1220  case AVCOL_SPC_BT709:
1221  default:
1222  s->cs = (s->depth - 8) * 2 + 1;
1223  }
1224  }
1225 
1226  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
1227  if (!out) {
1228  av_frame_free(&in);
1229  return AVERROR(ENOMEM);
1230  }
1232 
1233  s->vectorscope(s, in, out, s->pd);
1234  s->graticulef(s, out, s->x, s->y, s->pd, s->cs);
1235 
1236  for (plane = 0; plane < 4; plane++) {
1237  if (out->data[plane]) {
1238  out->data[plane] += (s->size - 1) * out->linesize[plane];
1239  out->linesize[plane] = -out->linesize[plane];
1240  }
1241  }
1242 
1243  av_frame_free(&in);
1244  return ff_filter_frame(outlink, out);
1245 }
1246 
1248 {
1250  AVFilterContext *ctx = inlink->dst;
1251  VectorscopeContext *s = ctx->priv;
1252 
1253  s->is_yuv = !(desc->flags & AV_PIX_FMT_FLAG_RGB);
1254  s->size = 1 << desc->comp[0].depth;
1255  s->mult = s->size / 256;
1256  s->depth = desc->comp[0].depth;
1257  s->tmin = s->lthreshold * (s->size - 1);
1258  s->tmax = s->hthreshold * (s->size - 1);
1259 
1260  if (s->tmin > s->tmax) {
1261  av_log(ctx, AV_LOG_ERROR, "low threshold should be less than high threshold\n");
1262  return AVERROR(EINVAL);
1263  }
1264 
1265  if (s->mode == GRAY && s->is_yuv)
1266  s->pd = 0;
1267  else {
1268  if ((s->x == 1 && s->y == 2) || (s->x == 2 && s->y == 1))
1269  s->pd = 0;
1270  else if ((s->x == 0 && s->y == 2) || (s->x == 2 && s->y == 0))
1271  s->pd = 1;
1272  else if ((s->x == 0 && s->y == 1) || (s->x == 1 && s->y == 0))
1273  s->pd = 2;
1274  }
1275 
1276  if (s->size == 256)
1277  s->vectorscope = vectorscope8;
1278  else
1279  s->vectorscope = vectorscope16;
1280 
1281  s->graticulef = none_graticule;
1282 
1283  if (s->is_yuv && s->size == 256) {
1284  if (s->graticule == 1)
1285  s->graticulef = green_graticule;
1286  else if (s->graticule == 2)
1287  s->graticulef = color_graticule;
1288  } else if (s->is_yuv) {
1289  if (s->graticule == 1)
1290  s->graticulef = green_graticule16;
1291  else if (s->graticule == 2)
1292  s->graticulef = color_graticule16;
1293  }
1294 
1295  s->bg_color[3] = s->bgopacity * (s->size - 1);
1296 
1297  switch (inlink->format) {
1298  case AV_PIX_FMT_GBRP12:
1299  case AV_PIX_FMT_GBRP10:
1300  case AV_PIX_FMT_GBRP9:
1301  case AV_PIX_FMT_GBRAP:
1302  case AV_PIX_FMT_GBRP:
1303  s->bg_color[0] = 0;
1304  s->bg_color[1] = 0;
1305  s->bg_color[2] = 0;
1306  break;
1307  default:
1308  s->bg_color[0] = 0;
1309  s->bg_color[1] = s->size / 2 - 1;
1310  s->bg_color[2] = s->size / 2 - 1;
1311  }
1312 
1313  s->hsub = desc->log2_chroma_w;
1314  s->vsub = desc->log2_chroma_h;
1315  s->planeheight[1] = s->planeheight[2] = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h);
1316  s->planeheight[0] = s->planeheight[3] = inlink->h;
1317  s->planewidth[1] = s->planewidth[2] = AV_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w);
1318  s->planewidth[0] = s->planewidth[3] = inlink->w;
1319 
1320  return 0;
1321 }
1322 
1324 {
1325  VectorscopeContext *s = ctx->priv;
1326 
1327  av_freep(&s->peak);
1328  av_freep(&s->peak_memory);
1329 }
1330 
1331 static const AVFilterPad inputs[] = {
1332  {
1333  .name = "default",
1334  .type = AVMEDIA_TYPE_VIDEO,
1335  .filter_frame = filter_frame,
1336  .config_props = config_input,
1337  },
1338  { NULL }
1339 };
1340 
1341 static const AVFilterPad outputs[] = {
1342  {
1343  .name = "default",
1344  .type = AVMEDIA_TYPE_VIDEO,
1345  .config_props = config_output,
1346  },
1347  { NULL }
1348 };
1349 
1351  .name = "vectorscope",
1352  .description = NULL_IF_CONFIG_SMALL("Video vectorscope."),
1353  .priv_size = sizeof(VectorscopeContext),
1354  .priv_class = &vectorscope_class,
1356  .uninit = uninit,
1357  .inputs = inputs,
1358  .outputs = outputs,
1359 };
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:99
VectorscopeMode
VectorscopeMode
Definition: vf_vectorscope.c:32
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
envelope_peak16
static void envelope_peak16(VectorscopeContext *s, AVFrame *out)
Definition: vf_vectorscope.c:297
query_formats
static int query_formats(AVFilterContext *ctx)
Definition: vf_vectorscope.c:194
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:1341
draw_dots16
static void draw_dots16(uint16_t *dst, int L, int v, float o)
Definition: vf_vectorscope.c:873
ff_make_format_list
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:283
VectorscopeContext::depth
int depth
Definition: vf_vectorscope.c:54
out_yuv10_pix_fmts
static enum AVPixelFormat out_yuv10_pix_fmts[]
Definition: vf_vectorscope.c:136
out
FILE * out
Definition: movenc.c:54
color
Definition: vf_paletteuse.c:588
FLAGS
#define FLAGS
Definition: vf_vectorscope.c:77
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1080
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2522
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:65
VectorscopeContext::mode
int mode
Definition: vf_vectorscope.c:44
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:202
AV_PIX_FMT_YUVA422P9
#define AV_PIX_FMT_YUVA422P9
Definition: pixfmt.h:422
VectorscopeContext::cs
int cs
Definition: vf_vectorscope.c:66
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
pixdesc.h
w
uint8_t w
Definition: llviddspenc.c:38
positions_name
const static char * positions_name[]
Definition: vf_vectorscope.c:792
AV_PIX_FMT_YUVA420P10
#define AV_PIX_FMT_YUVA420P10
Definition: pixfmt.h:424
vectorscope_options
static const AVOption vectorscope_options[]
Definition: vf_vectorscope.c:79
AVOption
AVOption.
Definition: opt.h:246
AV_PIX_FMT_YUV420P10
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:387
out_rgb8_pix_fmts
static enum AVPixelFormat out_rgb8_pix_fmts[]
Definition: vf_vectorscope.c:146
VectorscopeContext::y
int y
Definition: vf_vectorscope.c:51
MODE_NB
@ MODE_NB
Definition: vf_vectorscope.c:39
AV_PIX_FMT_YUV440P
@ AV_PIX_FMT_YUV440P
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
Definition: pixfmt.h:99
max
#define max(a, b)
Definition: cuda_runtime.h:33
AVFilterFormats::formats
int * formats
list of media formats
Definition: formats.h:66
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:148
VectorscopeContext::fintensity
float fintensity
Definition: vf_vectorscope.c:46
video.h
AV_PIX_FMT_YUVA422P10
#define AV_PIX_FMT_YUVA422P10
Definition: pixfmt.h:425
inputs
static const AVFilterPad inputs[]
Definition: vf_vectorscope.c:1331
color_graticule
static void color_graticule(VectorscopeContext *s, AVFrame *out, int X, int Y, int D, int P)
Definition: vf_vectorscope.c:1020
D
D(D(float, sse)
Definition: rematrix_init.c:28
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:378
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:502
AV_PIX_FMT_YUVA420P9
#define AV_PIX_FMT_YUVA420P9
Definition: pixfmt.h:421
out_yuv8_pix_fmts
static enum AVPixelFormat out_yuv8_pix_fmts[]
Definition: vf_vectorscope.c:126
positions
const static uint16_t positions[][14][3]
Definition: vf_vectorscope.c:796
AV_PIX_FMT_GBRAP
@ AV_PIX_FMT_GBRAP
planar GBRA 4:4:4:4 32bpp
Definition: pixfmt.h:215
AVFilterContext::priv
void * priv
private data for use by the filter
Definition: avfilter.h:353
AV_PIX_FMT_GBRP10
#define AV_PIX_FMT_GBRP10
Definition: pixfmt.h:403
VectorscopeContext::peak_memory
uint8_t * peak_memory
Definition: vf_vectorscope.c:67
plane
int plane
Definition: avisynth_c.h:384
AV_PIX_FMT_YUV422P9
#define AV_PIX_FMT_YUV422P9
Definition: pixfmt.h:385
VectorscopeContext::bgopacity
float bgopacity
Definition: vf_vectorscope.c:59
COLOR3
@ COLOR3
Definition: vf_vectorscope.c:36
src
#define src
Definition: vp8dsp.c:254
in1_pix_fmts
static enum AVPixelFormat in1_pix_fmts[]
Definition: vf_vectorscope.c:166
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:54
AV_PIX_FMT_YUV444P10
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:390
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:258
VectorscopeContext::pd
int pd
Definition: vf_vectorscope.c:51
in_pix_fmts
static enum AVPixelFormat in_pix_fmts[]
Definition: vf_ciescope.c:121
avassert.h
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: vf_vectorscope.c:1204
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
av_cold
#define av_cold
Definition: attributes.h:84
VectorscopeContext::intensity
int intensity
Definition: vf_vectorscope.c:45
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:79
AV_PIX_FMT_GBRAP10
#define AV_PIX_FMT_GBRAP10
Definition: pixfmt.h:407
VectorscopeContext::tmax
int tmax
Definition: vf_vectorscope.c:63
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:257
AV_PIX_FMT_GBRAP12
#define AV_PIX_FMT_GBRAP12
Definition: pixfmt.h:408
AV_PIX_FMT_YUVA420P
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition: pixfmt.h:101
AV_CEIL_RSHIFT
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:58
AVCOL_SPC_SMPTE170M
@ AVCOL_SPC_SMPTE170M
also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC
Definition: pixfmt.h:503
OFFSET
#define OFFSET(x)
Definition: vf_vectorscope.c:76
ff_formats_ref
int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add *ref as a new reference to formats.
Definition: formats.c:440
vectorscope8
static void vectorscope8(VectorscopeContext *s, AVFrame *in, AVFrame *out, int pd)
Definition: vf_vectorscope.c:598
VectorscopeContext::mult
int mult
Definition: vf_vectorscope.c:55
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
AV_PIX_FMT_YUV420P9
#define AV_PIX_FMT_YUV420P9
Definition: pixfmt.h:384
VectorscopeContext::graticulef
void(* graticulef)(struct VectorscopeContext *s, AVFrame *out, int X, int Y, int D, int P)
Definition: vf_vectorscope.c:72
VectorscopeContext::opacity
float opacity
Definition: vf_vectorscope.c:58
ctx
AVFormatContext * ctx
Definition: movenc.c:48
VectorscopeContext::hsub
int hsub
Definition: vf_vectorscope.c:50
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
f
#define f(width, name)
Definition: cbs_vp9.c:255
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:80
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:348
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:67
NULL
#define NULL
Definition: coverity.c:32
av_frame_copy_props
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:654
VectorscopeContext::vectorscope
void(* vectorscope)(struct VectorscopeContext *s, AVFrame *in, AVFrame *out, int pd)
Definition: vf_vectorscope.c:70
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:78
VectorscopeContext::hthreshold
float hthreshold
Definition: vf_vectorscope.c:61
V
#define V
Definition: avdct.c:30
GRAY
@ GRAY
Definition: vf_vectorscope.c:33
parseutils.h
AVFilterFormats::nb_formats
unsigned nb_formats
number of formats
Definition: formats.h:65
green_graticule
static void green_graticule(VectorscopeContext *s, AVFrame *out, int X, int Y, int D, int P)
Definition: vf_vectorscope.c:1146
AV_PIX_FMT_YUV422P10
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:388
AV_PIX_FMT_GBRP9
#define AV_PIX_FMT_GBRP9
Definition: pixfmt.h:402
COLOR5
@ COLOR5
Definition: vf_vectorscope.c:38
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_vectorscope.c:1323
for
for(j=16;j >0;--j)
Definition: h264pred_template.c:469
desc
const char * desc
Definition: nvenc.c:68
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:188
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:148
P
#define P
FFMAX
#define FFMAX(a, b)
Definition: common.h:94
AV_PIX_FMT_YUV422P12
#define AV_PIX_FMT_YUV422P12
Definition: pixfmt.h:392
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:394
envelope_instant
static void envelope_instant(VectorscopeContext *s, AVFrame *out)
Definition: vf_vectorscope.c:328
out_rgb12_pix_fmts
static enum AVPixelFormat out_rgb12_pix_fmts[]
Definition: vf_vectorscope.c:161
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:926
COLOR4
@ COLOR4
Definition: vf_vectorscope.c:37
VectorscopeContext::is_yuv
int is_yuv
Definition: vf_vectorscope.c:52
FFMIN
#define FFMIN(a, b)
Definition: common.h:96
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:177
AV_PIX_FMT_YUVA444P10
#define AV_PIX_FMT_YUVA444P10
Definition: pixfmt.h:426
xga_font_data.h
out_yuv12_pix_fmts
static enum AVPixelFormat out_yuv12_pix_fmts[]
Definition: vf_vectorscope.c:141
VectorscopeContext::graticule
int graticule
Definition: vf_vectorscope.c:57
in2_pix_fmts
static enum AVPixelFormat in2_pix_fmts[]
Definition: vf_vectorscope.c:177
Y
#define Y
Definition: boxblur.h:38
internal.h
AV_OPT_TYPE_FLOAT
@ AV_OPT_TYPE_FLOAT
Definition: opt.h:226
in
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) #define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac) { } void ff_audio_convert_free(AudioConvert **ac) { if(! *ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);} AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map) { AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method !=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2) { ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc) { av_free(ac);return NULL;} return ac;} in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar) { ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar ? ac->channels :1;} else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;} int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in) { int use_generic=1;int len=in->nb_samples;int p;if(ac->dc) { av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
Definition: audio_convert.c:326
ff_vf_vectorscope
AVFilter ff_vf_vectorscope
Definition: vf_vectorscope.c:1350
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
VectorscopeContext::envelope
int envelope
Definition: vf_vectorscope.c:56
AV_PIX_FMT_GBRP12
#define AV_PIX_FMT_GBRP12
Definition: pixfmt.h:404
out_pix_fmts
static enum AVPixelFormat out_pix_fmts[]
Definition: vf_ciescope.c:130
vectorscope16
static void vectorscope16(VectorscopeContext *s, AVFrame *in, AVFrame *out, int pd)
Definition: vf_vectorscope.c:400
out_rgb9_pix_fmts
static enum AVPixelFormat out_rgb9_pix_fmts[]
Definition: vf_vectorscope.c:151
envelope
static void envelope(VectorscopeContext *s, AVFrame *out)
Definition: vf_vectorscope.c:389
uint8_t
uint8_t
Definition: audio_convert.c:194
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:60
AV_PIX_FMT_YUV444P9
#define AV_PIX_FMT_YUV444P9
Definition: pixfmt.h:386
AVFilter
Filter definition.
Definition: avfilter.h:144
ret
ret
Definition: filter_design.txt:187
VectorscopeContext::lthreshold
float lthreshold
Definition: vf_vectorscope.c:60
green_graticule16
static void green_graticule16(VectorscopeContext *s, AVFrame *out, int X, int Y, int D, int P)
Definition: vf_vectorscope.c:1086
AV_PIX_FMT_YUVA444P9
#define AV_PIX_FMT_YUVA444P9
Definition: pixfmt.h:423
VectorscopeContext::flags
int flags
Definition: vf_vectorscope.c:64
VectorscopeContext::peak
uint8_t ** peak
Definition: vf_vectorscope.c:68
AV_PIX_FMT_YUV420P12
#define AV_PIX_FMT_YUV420P12
Definition: pixfmt.h:391
L
#define L(x)
Definition: vp56_arith.h:36
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
Definition: mem.c:244
mode
mode
Definition: ebur128.h:83
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
VectorscopeContext::vsub
int vsub
Definition: vf_vectorscope.c:50
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:223
avfilter.h
config_output
static int config_output(AVFilterLink *outlink)
Definition: vf_vectorscope.c:253
color_graticule16
static void color_graticule16(VectorscopeContext *s, AVFrame *out, int X, int Y, int D, int P)
Definition: vf_vectorscope.c:952
VectorscopeContext
Definition: vf_vectorscope.c:42
config_input
static int config_input(AVFilterLink *inlink)
Definition: vf_vectorscope.c:1247
AV_PIX_FMT_YUV444P
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:71
AVFilterContext
An instance of a filter.
Definition: avfilter.h:338
AV_PIX_FMT_GBRP
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:168
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
AV_PIX_FMT_YUV422P
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:70
VectorscopeContext::planewidth
int planewidth[4]
Definition: vf_vectorscope.c:48
M_SQRT2
#define M_SQRT2
Definition: mathematics.h:61
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
VectorscopeContext::bg_color
uint16_t bg_color[4]
Definition: vf_vectorscope.c:47
none_graticule
static void none_graticule(VectorscopeContext *s, AVFrame *out, int X, int Y, int D, int P)
Definition: vf_vectorscope.c:896
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:131
COLOR
@ COLOR
Definition: vf_vectorscope.c:34
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:900
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
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:73
VectorscopeContext::x
int x
Definition: vf_vectorscope.c:51
AV_OPT_TYPE_FLAGS
@ AV_OPT_TYPE_FLAGS
Definition: opt.h:222
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:565
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:72
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
VectorscopeContext::size
int size
Definition: vf_vectorscope.c:53
out_rgb10_pix_fmts
static enum AVPixelFormat out_rgb10_pix_fmts[]
Definition: vf_vectorscope.c:156
AV_PIX_FMT_YUV440P12
#define AV_PIX_FMT_YUV440P12
Definition: pixfmt.h:393
h
h
Definition: vp9dsp_template.c:2038
AVCOL_SPC_BT709
@ AVCOL_SPC_BT709
also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B
Definition: pixfmt.h:498
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:232
VectorscopeContext::planeheight
int planeheight[4]
Definition: vf_vectorscope.c:49
draw_dots
static void draw_dots(uint8_t *dst, int L, int v, float o)
Definition: vf_vectorscope.c:850
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:176
VectorscopeContext::tmin
int tmin
Definition: vf_vectorscope.c:62
envelope_instant16
static void envelope_instant16(VectorscopeContext *s, AVFrame *out)
Definition: vf_vectorscope.c:276
COLOR2
@ COLOR2
Definition: vf_vectorscope.c:35
AV_WN16
#define AV_WN16(p, v)
Definition: intreadwrite.h:372