FFmpeg  4.4.8
vf_pseudocolor.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 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/attributes.h"
22 #include "libavutil/common.h"
23 #include "libavutil/eval.h"
24 #include "libavutil/imgutils.h"
25 #include "libavutil/opt.h"
26 #include "libavutil/pixdesc.h"
27 #include "avfilter.h"
28 #include "filters.h"
29 #include "formats.h"
30 #include "internal.h"
31 #include "video.h"
32 
33 static const char *const var_names[] = {
34  "w", ///< width of the input video
35  "h", ///< height of the input video
36  "val", ///< input value for the pixel
37  "ymin",
38  "umin",
39  "vmin",
40  "amin",
41  "ymax",
42  "umax",
43  "vmax",
44  "amax",
45  NULL
46 };
47 
48 enum var_name {
61 };
62 
63 enum Curves {
71 };
72 
73 enum Presets {
85 };
86 
87 typedef struct Curve {
88  double coef[3][8];
89 } Curve;
90 
91 typedef struct Fill {
92  float fill[4];
93 } Fill;
94 
95 typedef struct Range {
96  int start, end;
97 } Range;
98 
99 typedef struct Preset {
101  const Range *ranges;
102  const Curve *curves;
103  const Fill *fills;
104 } Preset;
105 
106 static const Range full_range = {0, 256};
107 static const Range spec1_range[] = {{0, 16}, {16, 236}, {236, 256}};
108 static const Range spec2_range[] = {{0, 16}, {16, 22}, {22, 226}, {226, 236}, {236, 256}};
109 static const Range shadows_range[] = {{0, 32}, {32, 256}};
110 static const Range highlights_range[] = {{0, 214}, {214, 224}, {224, 256}};
111 
112 static const Fill spec1_fills[] = {{{0.5f, 0.f, .5f, 1.f}}, {{-1.f, -1.f, -1.f, 1.f}}, {{1.f, 0.f, 0.f, 1.f}}};
113 static const Fill spec2_fills[] = {{{0.5f, 0.f, .5f, 1.f}}, {{0.f, 1.f, 1.f, 1.f}}, {{-1.f, -1.f, -1.f, 1.f}}, {{1.f, 1.f, 0.f, 1.f}}, {{1.f, 0.f, 0.f, 1.f}}};
114 static const Fill shadows_fills[] = {{{0.8f, 0.4f, .8f, 1.f}}, {{-1.f, -1.f, -1.f, 1.f}}};
115 static const Fill highlights_fills[] = {{{-1.f, -1.f, -1.f, 1.f}}, {{1.f, 0.3f, 0.6f, 1.f}}, {{1.f, 0.2f, .5f, 1.f}}};
116 
117 static const Curve curves[] =
118 {
119  [MAGMA] = {{
120  {-7.5631093e-16, 7.4289183e-13, -2.8525484e-10, 5.4446085e-08, -5.5596238e-06, 3.0569325e-04, -2.3137421e-03, 1.2152095e-02 },
121  { 1.3217636e-15, -1.2214648e-12, 4.4319712e-10, -8.0197993e-08, 7.6598370e-06, -3.6523704e-04, 8.4836670e-03, -2.5536888e-02 },
122  {-1.1446568e-15, 1.0013446e-12, -3.5651575e-10, 6.6775016e-08, -6.7120346e-06, 2.7346619e-04, 4.7969657e-03, 1.1971441e-02 },
123  }},
124  [INFERNO] = {{
125  {-3.9848859e-18, 9.4821649e-14, -6.7371977e-11, 1.8469937e-08, -2.5359307e-06, 1.7959053e-04, 3.9782564e-04, 2.8845935e-04 },
126  { 6.8408539e-16, -6.5499979e-13, 2.4562526e-10, -4.5989298e-08, 4.5723324e-06, -2.2111913e-04, 5.2023164e-03, -1.1226064e-02 },
127  {-2.9921470e-15, 2.5864165e-12, -8.7403799e-10, 1.4713388e-07, -1.2701505e-05, 4.5159935e-04, 3.1087989e-03, 1.9122831e-02 },
128  }},
129  [PLASMA] = {{
130  { 3.6196089e-16, -3.3623041e-13, 1.2324010e-10, -2.2769060e-08, 2.2297792e-06, -1.2567829e-04, 9.9791629e-03, 5.7247918e-02 },
131  { 5.0262888e-16, -5.3193896e-13, 2.2451715e-10, -4.7529623e-08, 5.1374873e-06, -2.3260136e-04, 3.1502825e-03, 1.5362491e-02 },
132  {-1.7782261e-16, 2.2487839e-13, -1.0610236e-10, 2.4112644e-08, -2.6331623e-06, 8.9499751e-05, 2.1386328e-03, 5.3824268e-01 },
133  }},
134  [VIRIDIS] = {{
135  { 9.4850045e-16, -8.6629383e-13, 3.0310944e-10, -5.1340396e-08, 4.6024275e-06, -2.2744239e-04, 4.5559993e-03, 2.5662350e-01 },
136  { 9.6461041e-17, -6.9209477e-14, 1.7625397e-11, -2.0229773e-09, 1.4900110e-07, -1.9315187e-05, 5.8967339e-03, 3.9544827e-03 },
137  { 5.1785449e-16, -3.6663004e-13, 1.0249990e-10, -1.5431998e-08, 1.5007941e-06, -1.2001502e-04, 7.6951526e-03, 3.2292815e-01 },
138  }},
139  [TURBO] = {{
140  {-4.3683890e-15, 3.7020347e-12, -1.1712592e-09, 1.6401790e-07, -8.6842919e-06, -1.8542465e-06, 8.4485325e-03, 1.6267077e-01 },
141  {-4.0011069e-16, 2.7861423e-13, -6.3388921e-11, 5.8872238e-09, -5.4466522e-07, 1.8037114e-05, 1.0599869e-02, 7.6914696e-02 },
142  {-2.8242609e-15, 2.9234108e-12, -1.1726546e-09, 2.2552115e-07, -2.0059387e-05, 5.0595552e-04, 1.7714932e-02, 2.7271836e-01 },
143  }},
144  [CIVIDIS] = {{
145  {-9.5484131e-16, 9.6988184e-13, -4.0058766e-10, 8.5743924e-08, -9.9644797e-06, 5.9197908e-04, -1.0361579e-02, 3.3164429e-02 },
146  { 1.2731941e-17, -9.4238449e-15, 2.2808841e-12, -1.1548296e-10, -2.3888913e-08, 3.8986680e-06, 2.5879330e-03, 1.2769733e-01 },
147  { 4.6004608e-16, -5.0686849e-13, 2.2753449e-10, -5.3074099e-08, 6.7196096e-06, -4.4120020e-04, 1.3435551e-02, 2.8293355e-01 },
148  }},
149 };
150 
151 static const Preset presets[] =
152 {
153  [PRESET_MAGMA] = { 1, &full_range, &curves[MAGMA], NULL },
154  [PRESET_INFERNO] = { 1, &full_range, &curves[INFERNO], NULL },
155  [PRESET_PLASMA] = { 1, &full_range, &curves[PLASMA], NULL },
156  [PRESET_VIRIDIS] = { 1, &full_range, &curves[VIRIDIS], NULL },
157  [PRESET_TURBO] = { 1, &full_range, &curves[TURBO], NULL },
158  [PRESET_CIVIDIS] = { 1, &full_range, &curves[CIVIDIS], NULL },
163 };
164 
165 typedef struct PseudoColorContext {
166  const AVClass *class;
167  int preset;
168  float opacity;
169  int max;
170  int index;
172  int color;
173  int linesize[4];
174  int width[4], height[4];
176  char *comp_expr_str[4];
178  float lut[4][256*256];
179 
180  void (*filter[4])(int max, int width, int height,
181  const uint8_t *index, const uint8_t *src,
182  uint8_t *dst,
183  ptrdiff_t ilinesize,
184  ptrdiff_t slinesize,
185  ptrdiff_t dlinesize,
186  float *lut,
187  float opacity);
189 
190 #define OFFSET(x) offsetof(PseudoColorContext, x)
191 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
192 
193 static const AVOption pseudocolor_options[] = {
194  { "c0", "set component #0 expression", OFFSET(comp_expr_str[0]), AV_OPT_TYPE_STRING, {.str="val"}, .flags = FLAGS },
195  { "c1", "set component #1 expression", OFFSET(comp_expr_str[1]), AV_OPT_TYPE_STRING, {.str="val"}, .flags = FLAGS },
196  { "c2", "set component #2 expression", OFFSET(comp_expr_str[2]), AV_OPT_TYPE_STRING, {.str="val"}, .flags = FLAGS },
197  { "c3", "set component #3 expression", OFFSET(comp_expr_str[3]), AV_OPT_TYPE_STRING, {.str="val"}, .flags = FLAGS },
198  { "index", "set component as base", OFFSET(index), AV_OPT_TYPE_INT, {.i64=0}, 0, 3, .flags = FLAGS },
199  { "i", "set component as base", OFFSET(index), AV_OPT_TYPE_INT, {.i64=0}, 0, 3, .flags = FLAGS },
200  { "preset", "set preset", OFFSET(preset), AV_OPT_TYPE_INT, {.i64=-1},-1, NB_PRESETS-1, .flags = FLAGS, "preset" },
201  { "p", "set preset", OFFSET(preset), AV_OPT_TYPE_INT, {.i64=-1},-1, NB_PRESETS-1, .flags = FLAGS, "preset" },
202  { "none", NULL, 0, AV_OPT_TYPE_CONST, {.i64=-1}, .flags = FLAGS, "preset" },
203  { "magma", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_MAGMA}, .flags = FLAGS, "preset" },
204  { "inferno", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_INFERNO}, .flags = FLAGS, "preset" },
205  { "plasma", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_PLASMA}, .flags = FLAGS, "preset" },
206  { "viridis", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_VIRIDIS}, .flags = FLAGS, "preset" },
207  { "turbo", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_TURBO}, .flags = FLAGS, "preset" },
208  { "cividis", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_CIVIDIS}, .flags = FLAGS, "preset" },
209  { "range1", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_RANGE1}, .flags = FLAGS, "preset" },
210  { "range2", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_RANGE2}, .flags = FLAGS, "preset" },
211  { "shadows", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_SHADOWS}, .flags = FLAGS, "preset" },
212  { "highlights", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_HIGHLIGHTS},.flags=FLAGS, "preset" },
213  { "opacity", "set pseudocolor opacity",OFFSET(opacity), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 1, .flags = FLAGS },
214  { NULL }
215 };
216 
217 static const enum AVPixelFormat pix_fmts[] = {
244 };
245 
247 {
249  if (!fmts_list)
250  return AVERROR(ENOMEM);
251  return ff_set_common_formats(ctx, fmts_list);
252 }
253 
254 static inline float lerpf(float v0, float v1, float f)
255 {
256  return v0 + (v1 - v0) * f;
257 }
258 
259 #define PCLIP(v, max, dst, src, x) \
260  if (v >= 0 && v <= max) { \
261  dst[x] = lerpf(src[x], v, opacity);\
262  } else { \
263  dst[x] = src[x]; \
264  }
265 
266 static void pseudocolor_filter(int max, int width, int height,
267  const uint8_t *index,
268  const uint8_t *src,
269  uint8_t *dst,
270  ptrdiff_t ilinesize,
271  ptrdiff_t slinesize,
272  ptrdiff_t dlinesize,
273  float *lut,
274  float opacity)
275 {
276  int x, y;
277 
278  for (y = 0; y < height; y++) {
279  for (x = 0; x < width; x++) {
280  int v = lut[index[x]];
281 
282  PCLIP(v, max, dst, src, x);
283  }
284  index += ilinesize;
285  src += slinesize;
286  dst += dlinesize;
287  }
288 }
289 
290 static void pseudocolor_filter_11(int max, int width, int height,
291  const uint8_t *index,
292  const uint8_t *src,
293  uint8_t *dst,
294  ptrdiff_t ilinesize,
295  ptrdiff_t slinesize,
296  ptrdiff_t dlinesize,
297  float *lut,
298  float opacity)
299 {
300  int x, y;
301 
302  for (y = 0; y < height; y++) {
303  for (x = 0; x < width; x++) {
304  int v = lut[index[(y << 1) * ilinesize + (x << 1)]];
305 
306  PCLIP(v, max, dst, src, x);
307  }
308  src += slinesize;
309  dst += dlinesize;
310  }
311 }
312 
313 static void pseudocolor_filter_11d(int max, int width, int height,
314  const uint8_t *index,
315  const uint8_t *src,
316  uint8_t *dst,
317  ptrdiff_t ilinesize,
318  ptrdiff_t slinesize,
319  ptrdiff_t dlinesize,
320  float *lut,
321  float opacity)
322 {
323  int x, y;
324 
325  for (y = 0; y < height; y++) {
326  for (x = 0; x < width; x++) {
327  int v = lut[index[(y >> 1) * ilinesize + (x >> 1)]];
328 
329  PCLIP(v, max, dst, src, x);
330  }
331  src += slinesize;
332  dst += dlinesize;
333  }
334 }
335 
336 static void pseudocolor_filter_10(int max, int width, int height,
337  const uint8_t *index,
338  const uint8_t *src,
339  uint8_t *dst,
340  ptrdiff_t ilinesize,
341  ptrdiff_t slinesize,
342  ptrdiff_t dlinesize,
343  float *lut,
344  float opacity)
345 {
346  int x, y;
347 
348  for (y = 0; y < height; y++) {
349  for (x = 0; x < width; x++) {
350  int v = lut[index[x << 1]];
351 
352  PCLIP(v, max, dst, src, x);
353  }
354  index += ilinesize;
355  src += slinesize;
356  dst += dlinesize;
357  }
358 }
359 
360 static void pseudocolor_filter_10d(int max, int width, int height,
361  const uint8_t *index,
362  const uint8_t *src,
363  uint8_t *dst,
364  ptrdiff_t ilinesize,
365  ptrdiff_t slinesize,
366  ptrdiff_t dlinesize,
367  float *lut,
368  float opacity)
369 {
370  int x, y;
371 
372  for (y = 0; y < height; y++) {
373  for (x = 0; x < width; x++) {
374  int v = lut[index[x >> 1]];
375 
376  PCLIP(v, max, dst, src, x);
377  }
378  index += ilinesize;
379  src += slinesize;
380  dst += dlinesize;
381  }
382 }
383 
384 static void pseudocolor_filter_16(int max, int width, int height,
385  const uint8_t *iindex,
386  const uint8_t *ssrc,
387  uint8_t *ddst,
388  ptrdiff_t ilinesize,
389  ptrdiff_t slinesize,
390  ptrdiff_t dlinesize,
391  float *lut,
392  float opacity)
393 {
394  const uint16_t *index = (const uint16_t *)iindex;
395  const uint16_t *src = (const uint16_t *)ssrc;
396  uint16_t *dst = (uint16_t *)ddst;
397  int x, y;
398 
399  for (y = 0; y < height; y++) {
400  for (x = 0; x < width; x++) {
401  int v = lut[index[x]];
402 
403  PCLIP(v, max, dst, src, x);
404  }
405  index += ilinesize / 2;
406  src += slinesize / 2;
407  dst += dlinesize / 2;
408  }
409 }
410 
411 static void pseudocolor_filter_16_10(int max, int width, int height,
412  const uint8_t *iindex,
413  const uint8_t *ssrc,
414  uint8_t *ddst,
415  ptrdiff_t ilinesize,
416  ptrdiff_t slinesize,
417  ptrdiff_t dlinesize,
418  float *lut,
419  float opacity)
420 {
421  const uint16_t *index = (const uint16_t *)iindex;
422  const uint16_t *src = (const uint16_t *)ssrc;
423  uint16_t *dst = (uint16_t *)ddst;
424  int x, y;
425 
426  for (y = 0; y < height; y++) {
427  for (x = 0; x < width; x++) {
428  int v = lut[index[x << 1]];
429 
430  PCLIP(v, max, dst, src, x);
431  }
432  index += ilinesize / 2;
433  src += slinesize / 2;
434  dst += dlinesize / 2;
435  }
436 }
437 
438 static void pseudocolor_filter_16_10d(int max, int width, int height,
439  const uint8_t *iindex,
440  const uint8_t *ssrc,
441  uint8_t *ddst,
442  ptrdiff_t ilinesize,
443  ptrdiff_t slinesize,
444  ptrdiff_t dlinesize,
445  float *lut,
446  float opacity)
447 {
448  const uint16_t *index = (const uint16_t *)iindex;
449  const uint16_t *src = (const uint16_t *)ssrc;
450  uint16_t *dst = (uint16_t *)ddst;
451  int x, y;
452 
453  for (y = 0; y < height; y++) {
454  for (x = 0; x < width; x++) {
455  int v = lut[index[x >> 1]];
456 
457  PCLIP(v, max, dst, src, x);
458  }
459  index += ilinesize / 2;
460  src += slinesize / 2;
461  dst += dlinesize / 2;
462  }
463 }
464 
465 static void pseudocolor_filter_16_11(int max, int width, int height,
466  const uint8_t *iindex,
467  const uint8_t *ssrc,
468  uint8_t *ddst,
469  ptrdiff_t ilinesize,
470  ptrdiff_t slinesize,
471  ptrdiff_t dlinesize,
472  float *lut,
473  float opacity)
474 {
475  const uint16_t *index = (const uint16_t *)iindex;
476  const uint16_t *src = (const uint16_t *)ssrc;
477  uint16_t *dst = (uint16_t *)ddst;
478  int x, y;
479 
480  ilinesize /= 2;
481  dlinesize /= 2;
482  slinesize /= 2;
483 
484  for (y = 0; y < height; y++) {
485  for (x = 0; x < width; x++) {
486  int v = lut[index[(y << 1) * ilinesize + (x << 1)]];
487 
488  PCLIP(v, max, dst, src, x);
489  }
490  src += slinesize;
491  dst += dlinesize;
492  }
493 }
494 
495 static void pseudocolor_filter_16_11d(int max, int width, int height,
496  const uint8_t *iindex,
497  const uint8_t *ssrc,
498  uint8_t *ddst,
499  ptrdiff_t ilinesize,
500  ptrdiff_t slinesize,
501  ptrdiff_t dlinesize,
502  float *lut,
503  float opacity)
504 {
505  const uint16_t *index = (const uint16_t *)iindex;
506  const uint16_t *src = (const uint16_t *)ssrc;
507  uint16_t *dst = (uint16_t *)ddst;
508  int x, y;
509 
510  ilinesize /= 2;
511  dlinesize /= 2;
512  slinesize /= 2;
513 
514  for (y = 0; y < height; y++) {
515  for (x = 0; x < width; x++) {
516  int v = lut[index[(y >> 1) * ilinesize + (x >> 1)]];
517 
518  PCLIP(v, max, dst, src, x);
519  }
520  src += slinesize;
521  dst += dlinesize;
522  }
523 }
524 
525 #define RGB_TO_Y_BT709(r, g, b) \
526 ((0.21260*219.0/255.0) * (r) + (0.71520*219.0/255.0) * (g) + \
527  (0.07220*219.0/255.0) * (b))
528 
529 #define RGB_TO_U_BT709(r1, g1, b1, max) \
530 (-(0.11457*224.0/255.0) * r1 - (0.38543*224.0/255.0) * g1 + \
531  (0.50000*224.0/255.0) * b1 + max * 0.5)
532 
533 #define RGB_TO_V_BT709(r1, g1, b1, max) \
534 ((0.50000*224.0/255.0) * r1 - (0.45415*224.0/255.0) * g1 - \
535  (0.04585*224.0/255.0) * b1 + max * 0.5)
536 
537 static double poly_eval(const double *const poly, double x)
538 {
539  double res = 0.;
540 
541  for (int i = 0; i < 8; i++) {
542  res += pow(x, i) * poly[7-i];
543  }
544 
545  return av_clipd(res, 0., 1.);
546 }
547 
548 static int config_input(AVFilterLink *inlink)
549 {
550  AVFilterContext *ctx = inlink->dst;
551  PseudoColorContext *s = ctx->priv;
553  int depth, ret, hsub, vsub, color, factor, rgb;
554 
555  rgb = desc->flags & AV_PIX_FMT_FLAG_RGB;
556  depth = desc->comp[0].depth;
557  factor = 1 << (depth - 8);
558  s->max = (1 << depth) - 1;
559  s->nb_planes = av_pix_fmt_count_planes(inlink->format);
560 
561  if (s->index >= s->nb_planes) {
562  av_log(ctx, AV_LOG_ERROR, "index out of allowed range\n");
563  return AVERROR(EINVAL);
564  }
565 
566  if ((ret = av_image_fill_linesizes(s->linesize, inlink->format, inlink->w)) < 0)
567  return ret;
568 
569  hsub = desc->log2_chroma_w;
570  vsub = desc->log2_chroma_h;
571  s->height[1] = s->height[2] = AV_CEIL_RSHIFT(inlink->h, vsub);
572  s->height[0] = s->height[3] = inlink->h;
573  s->width[1] = s->width[2] = AV_CEIL_RSHIFT(inlink->w, hsub);
574  s->width[0] = s->width[3] = inlink->w;
575 
576  s->var_values[VAR_W] = inlink->w;
577  s->var_values[VAR_H] = inlink->h;
578 
579  s->var_values[VAR_YMIN] = 16 * (1 << (depth - 8));
580  s->var_values[VAR_UMIN] = 16 * (1 << (depth - 8));
581  s->var_values[VAR_VMIN] = 16 * (1 << (depth - 8));
582  s->var_values[VAR_AMIN] = 0;
583  s->var_values[VAR_YMAX] = 235 * (1 << (depth - 8));
584  s->var_values[VAR_UMAX] = 240 * (1 << (depth - 8));
585  s->var_values[VAR_VMAX] = 240 * (1 << (depth - 8));
586  s->var_values[VAR_AMAX] = s->max;
587 
588  for (color = 0; color < s->nb_planes && s->preset < 0; color++) {
589  double res;
590  int val;
591 
592  /* create the parsed expression */
593  av_expr_free(s->comp_expr[color]);
594  s->comp_expr[color] = NULL;
595  ret = av_expr_parse(&s->comp_expr[color], s->comp_expr_str[color],
596  var_names, NULL, NULL, NULL, NULL, 0, ctx);
597  if (ret < 0) {
599  "Error when parsing the expression '%s' for the component %d and color %d.\n",
600  s->comp_expr_str[color], color, color);
601  return AVERROR(EINVAL);
602  }
603 
604  /* compute the lut */
605  for (val = 0; val < FF_ARRAY_ELEMS(s->lut[color]); val++) {
606  s->var_values[VAR_VAL] = val;
607 
608  res = av_expr_eval(s->comp_expr[color], s->var_values, s);
609  if (isnan(res)) {
611  "Error when evaluating the expression '%s' for the value %d for the component %d.\n",
612  s->comp_expr_str[color], val, color);
613  return AVERROR(EINVAL);
614  }
615  s->lut[color][val] = res;
616  }
617  }
618 
619  if (s->preset >= 0) {
620  int nb_segments = presets[s->preset].nb_segments;
621 
622  for (int seg = 0; seg < nb_segments; seg++) {
623  int start = presets[s->preset].ranges[seg].start;
624  int end = presets[s->preset].ranges[seg].end;
625 
626  for (int i = start; i < end; i++) {
627  if (!presets[s->preset].curves) {
628  const Fill fill = presets[s->preset].fills[seg];
629 
630  for (int j = 0; j < factor; j++) {
631  double r, g, b, a;
632 
633  g = fill.fill[1];
634  b = fill.fill[2];
635  r = fill.fill[0];
636  a = fill.fill[3];
637 
638  if (g >= 0.f && b >= 0.f && r >= 0.f) {
639  g *= s->max;
640  b *= s->max;
641  r *= s->max;
642 
643  if (!rgb) {
644  double y = RGB_TO_Y_BT709(r, g, b);
645  double u = RGB_TO_U_BT709(r, g, b, s->max);
646  double v = RGB_TO_V_BT709(r, g, b, s->max);
647 
648  r = v;
649  g = y;
650  b = u;
651  }
652  }
653 
654  s->lut[0][i*factor+j] = g;
655  s->lut[1][i*factor+j] = b;
656  s->lut[2][i*factor+j] = r;
657  s->lut[3][i*factor+j] = a * s->max;
658  }
659  } else {
660  const Curve curve = presets[s->preset].curves[seg];
661 
662  for (int j = 0; j < factor; j++) {
663  const double lf = j / (double)factor;
664  double r, g, b;
665 
666  g = poly_eval(curve.coef[1], i + lf) * s->max;
667  b = poly_eval(curve.coef[2], i + lf) * s->max;
668  r = poly_eval(curve.coef[0], i + lf) * s->max;
669 
670  if (!rgb) {
671  double y = RGB_TO_Y_BT709(r, g, b);
672  double u = RGB_TO_U_BT709(r, g, b, s->max);
673  double v = RGB_TO_V_BT709(r, g, b, s->max);
674 
675  r = v;
676  g = y;
677  b = u;
678  }
679 
680  s->lut[0][i*factor+j] = g;
681  s->lut[1][i*factor+j] = b;
682  s->lut[2][i*factor+j] = r;
683  s->lut[3][i*factor+j] = 1.f * s->max;
684  }
685  }
686  }
687  }
688  }
689 
690  switch (inlink->format) {
691  case AV_PIX_FMT_YUV444P:
692  case AV_PIX_FMT_YUVA444P:
693  case AV_PIX_FMT_GBRP:
694  case AV_PIX_FMT_GBRAP:
695  case AV_PIX_FMT_GRAY8:
696  s->filter[0] = s->filter[1] = s->filter[2] = s->filter[3] = pseudocolor_filter;
697  break;
698  case AV_PIX_FMT_YUV420P:
699  case AV_PIX_FMT_YUVA420P:
700  switch (s->index) {
701  case 0:
702  case 3:
703  s->filter[0] = s->filter[3] = pseudocolor_filter;
704  s->filter[1] = s->filter[2] = pseudocolor_filter_11;
705  break;
706  case 1:
707  case 2:
708  s->filter[0] = s->filter[3] = pseudocolor_filter_11d;
709  s->filter[1] = s->filter[2] = pseudocolor_filter;
710  break;
711  }
712  break;
713  case AV_PIX_FMT_YUV422P:
714  case AV_PIX_FMT_YUVA422P:
715  switch (s->index) {
716  case 0:
717  case 3:
718  s->filter[0] = s->filter[3] = pseudocolor_filter;
719  s->filter[1] = s->filter[2] = pseudocolor_filter_10;
720  break;
721  case 1:
722  case 2:
723  s->filter[0] = s->filter[3] = pseudocolor_filter_10d;
724  s->filter[1] = s->filter[2] = pseudocolor_filter;
725  break;
726  }
727  break;
728  case AV_PIX_FMT_YUV444P9:
736  case AV_PIX_FMT_GBRP9:
737  case AV_PIX_FMT_GBRP10:
738  case AV_PIX_FMT_GBRP12:
739  case AV_PIX_FMT_GBRP14:
740  case AV_PIX_FMT_GBRP16:
741  case AV_PIX_FMT_GBRAP10:
742  case AV_PIX_FMT_GBRAP12:
743  case AV_PIX_FMT_GBRAP16:
744  case AV_PIX_FMT_GRAY9:
745  case AV_PIX_FMT_GRAY10:
746  case AV_PIX_FMT_GRAY12:
747  case AV_PIX_FMT_GRAY14:
748  case AV_PIX_FMT_GRAY16:
749  s->filter[0] = s->filter[1] = s->filter[2] = s->filter[3] = pseudocolor_filter_16;
750  break;
751  case AV_PIX_FMT_YUV422P9:
759  switch (s->index) {
760  case 0:
761  case 3:
762  s->filter[0] = s->filter[3] = pseudocolor_filter_16;
763  s->filter[1] = s->filter[2] = pseudocolor_filter_16_10;
764  break;
765  case 1:
766  case 2:
767  s->filter[0] = s->filter[3] = pseudocolor_filter_16_10d;
768  s->filter[1] = s->filter[2] = pseudocolor_filter_16;
769  break;
770  }
771  break;
772  case AV_PIX_FMT_YUV420P9:
780  switch (s->index) {
781  case 0:
782  case 3:
783  s->filter[0] = s->filter[3] = pseudocolor_filter_16;
784  s->filter[1] = s->filter[2] = pseudocolor_filter_16_11;
785  break;
786  case 1:
787  case 2:
788  s->filter[0] = s->filter[3] = pseudocolor_filter_16_11d;
789  s->filter[1] = s->filter[2] = pseudocolor_filter_16;
790  break;
791  }
792  break;
793  }
794 
795  return 0;
796 }
797 
798 typedef struct ThreadData {
799  AVFrame *in, *out;
800 } ThreadData;
801 
802 static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
803 {
804  PseudoColorContext *s = ctx->priv;
805  ThreadData *td = arg;
806  AVFrame *in = td->in;
807  AVFrame *out = td->out;
808 
809  for (int plane = 0; plane < s->nb_planes; plane++) {
810  const int slice_start = ff_slice_pos(s->height[plane], jobnr, nb_jobs);
811  const int slice_end = ff_slice_pos(s->height[plane], jobnr + 1, nb_jobs);
812  const int islice_start = ff_slice_pos(s->height[s->index], jobnr, nb_jobs);
813  ptrdiff_t ilinesize = in->linesize[s->index];
814  ptrdiff_t slinesize = in->linesize[plane];
815  ptrdiff_t dlinesize = out->linesize[plane];
816  const uint8_t *index = in->data[s->index] + islice_start * ilinesize;
817  const uint8_t *src = in->data[plane] + slice_start * slinesize;
818  uint8_t *dst = out->data[plane] + slice_start * dlinesize;
819 
820  s->filter[plane](s->max, s->width[plane], slice_end - slice_start,
821  index, src, dst, ilinesize, slinesize,
822  dlinesize, s->lut[plane], s->opacity);
823  }
824 
825  return 0;
826 }
827 
828 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
829 {
830  AVFilterContext *ctx = inlink->dst;
831  PseudoColorContext *s = ctx->priv;
832  AVFilterLink *outlink = ctx->outputs[0];
833  ThreadData td;
834  AVFrame *out;
835 
836  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
837  if (!out) {
838  av_frame_free(&in);
839  return AVERROR(ENOMEM);
840  }
842 
843  td.out = out, td.in = in;
844  ctx->internal->execute(ctx, filter_slice, &td, NULL, FFMIN(s->height[1], ff_filter_get_nb_threads(ctx)));
845 
846  av_frame_free(&in);
847  return ff_filter_frame(outlink, out);
848 }
849 
850 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
851  char *res, int res_len, int flags)
852 {
853  int ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags);
854 
855  if (ret < 0)
856  return ret;
857 
858  return config_input(ctx->inputs[0]);
859 }
860 
861 static const AVFilterPad inputs[] = {
862  {
863  .name = "default",
864  .type = AVMEDIA_TYPE_VIDEO,
865  .filter_frame = filter_frame,
866  .config_props = config_input,
867  },
868  { NULL }
869 };
870 
871 static const AVFilterPad outputs[] = {
872  {
873  .name = "default",
874  .type = AVMEDIA_TYPE_VIDEO,
875  },
876  { NULL }
877 };
878 
880 {
881  PseudoColorContext *s = ctx->priv;
882  int i;
883 
884  for (i = 0; i < 4; i++) {
885  av_expr_free(s->comp_expr[i]);
886  s->comp_expr[i] = NULL;
887  }
888 }
889 
891 
893  .name = "pseudocolor",
894  .description = NULL_IF_CONFIG_SMALL("Make pseudocolored video frames."),
895  .priv_size = sizeof(PseudoColorContext),
896  .priv_class = &pseudocolor_class,
897  .uninit = uninit,
899  .inputs = inputs,
900  .outputs = outputs,
903 };
static double val(void *priv, double ch)
Definition: aeval.c:76
Macro definitions for various function/variable attributes.
#define av_cold
Definition: attributes.h:88
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
uint8_t
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1096
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:882
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:802
Main libavfilter public API header.
#define flags(name, subs,...)
Definition: cbs_av1.c:572
#define u(width, name, range_min, range_max)
Definition: cbs_h2645.c:264
#define s(width, name)
Definition: cbs_vp9.c:257
#define f(width, name)
Definition: cbs_vp9.c:255
common internal and external API header
#define FFMIN(a, b)
Definition: common.h:105
#define av_clipd
Definition: common.h:173
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:58
#define NULL
Definition: coverity.c:32
#define max(a, b)
Definition: cuda_runtime.h:33
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
Definition: eval.c:339
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
Evaluate a previously parsed expression.
Definition: eval.c:781
int av_expr_parse(AVExpr **expr, const char *s, const char *const *const_names, const char *const *func1_names, double(*const *funcs1)(void *, double), const char *const *func2_names, double(*const *funcs2)(void *, double, double), int log_offset, void *log_ctx)
Parse an expression.
Definition: eval.c:700
simple arithmetic expression evaluator
static int ff_slice_pos(int total, int jobnr, int nb_jobs)
Compute the boundary index for a slice when work of size total is split into nb_jobs slices.
Definition: filters.h:271
int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
A helper for query_formats() which sets all links to the same list of formats.
Definition: formats.c:587
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:286
@ AV_OPT_TYPE_CONST
Definition: opt.h:234
@ AV_OPT_TYPE_INT
Definition: opt.h:225
@ AV_OPT_TYPE_FLOAT
Definition: opt.h:228
@ AV_OPT_TYPE_STRING
Definition: opt.h:229
#define AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
Some filters support a generic "enable" expression option that can be used to enable or disable a fil...
Definition: avfilter.h:126
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Definition: avfilter.h:117
#define AVERROR(e)
Definition: error.h:43
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:203
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:658
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
int av_image_fill_linesizes(int linesizes[4], enum AVPixelFormat pix_fmt, int width)
Fill plane linesizes for an image with pixel format pix_fmt and width width.
Definition: imgutils.c:89
int index
Definition: gxfenc.c:89
misc image utilities
int i
Definition: input.c:407
const char * arg
Definition: jacosubdec.c:66
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
#define isnan(x)
Definition: libm.h:340
const char * desc
Definition: libsvtav1.c:79
static const uint32_t color[16+AV_CLASS_CATEGORY_NB]
Definition: log.c:92
static int slice_end(AVCodecContext *avctx, AVFrame *pict)
Handle slice ends.
Definition: mpeg12dec.c:2033
AVOptions.
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2613
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2573
#define AV_PIX_FMT_FLAG_RGB
The pixel format contains RGB-like data (as opposed to YUV/grayscale).
Definition: pixdesc.h:148
#define AV_PIX_FMT_GBRAP12
Definition: pixfmt.h:420
#define AV_PIX_FMT_YUV420P16
Definition: pixfmt.h:410
#define AV_PIX_FMT_YUV444P12
Definition: pixfmt.h:406
#define AV_PIX_FMT_YUV444P9
Definition: pixfmt.h:398
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:399
#define AV_PIX_FMT_GRAY9
Definition: pixfmt.h:379
#define AV_PIX_FMT_GBRAP16
Definition: pixfmt.h:421
#define AV_PIX_FMT_GBRP9
Definition: pixfmt.h:414
#define AV_PIX_FMT_YUV422P9
Definition: pixfmt.h:397
#define AV_PIX_FMT_YUVA444P10
Definition: pixfmt.h:438
#define AV_PIX_FMT_YUVA420P16
Definition: pixfmt.h:441
#define AV_PIX_FMT_YUV420P12
Definition: pixfmt.h:403
#define AV_PIX_FMT_YUVA420P10
Definition: pixfmt.h:436
#define AV_PIX_FMT_YUVA422P9
Definition: pixfmt.h:434
#define AV_PIX_FMT_YUV422P12
Definition: pixfmt.h:404
#define AV_PIX_FMT_GBRP10
Definition: pixfmt.h:415
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:400
#define AV_PIX_FMT_GRAY12
Definition: pixfmt.h:381
#define AV_PIX_FMT_GBRP12
Definition: pixfmt.h:416
#define AV_PIX_FMT_YUV420P9
Definition: pixfmt.h:396
#define AV_PIX_FMT_YUVA420P9
Definition: pixfmt.h:433
#define AV_PIX_FMT_YUVA422P10
Definition: pixfmt.h:437
#define AV_PIX_FMT_YUV420P14
Definition: pixfmt.h:407
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:70
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:74
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition: pixfmt.h:101
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:71
@ 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_GBRAP
planar GBRA 4:4:4:4 32bpp
Definition: pixfmt.h:215
@ AV_PIX_FMT_YUVA422P
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
Definition: pixfmt.h:176
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:168
#define AV_PIX_FMT_YUV422P14
Definition: pixfmt.h:408
#define AV_PIX_FMT_GRAY10
Definition: pixfmt.h:380
#define AV_PIX_FMT_GRAY14
Definition: pixfmt.h:382
#define AV_PIX_FMT_YUV422P16
Definition: pixfmt.h:411
#define AV_PIX_FMT_GRAY16
Definition: pixfmt.h:383
#define AV_PIX_FMT_GBRAP10
Definition: pixfmt.h:419
#define AV_PIX_FMT_YUVA444P16
Definition: pixfmt.h:443
#define AV_PIX_FMT_YUVA422P16
Definition: pixfmt.h:442
#define AV_PIX_FMT_GBRP16
Definition: pixfmt.h:418
#define AV_PIX_FMT_YUV444P14
Definition: pixfmt.h:409
#define AV_PIX_FMT_YUVA444P9
Definition: pixfmt.h:435
#define AV_PIX_FMT_GBRP14
Definition: pixfmt.h:417
#define AV_PIX_FMT_YUV444P16
Definition: pixfmt.h:412
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:402
#define v0
Definition: regdef.h:26
#define td
Definition: regdef.h:70
typedef void(RENAME(mix_any_func_type))
var_name
Definition: setts_bsf.c:50
static const SheerTable rgb[2]
#define FF_ARRAY_ELEMS(a)
Describe the class of an AVClass context structure.
Definition: log.h:67
Definition: eval.c:159
An instance of a filter.
Definition: avfilter.h:341
A list of supported formats for one end of a filter link.
Definition: formats.h:65
A filter pad used for either input or output.
Definition: internal.h:54
const char * name
Pad name.
Definition: internal.h:60
Filter definition.
Definition: avfilter.h:145
const char * name
Filter name.
Definition: avfilter.h:149
AVFormatInternal * internal
An opaque field for libavformat internal usage.
Definition: avformat.h:1699
This structure describes decoded (raw) audio or video data.
Definition: frame.h:318
AVOption.
Definition: opt.h:248
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
double coef[3][8]
float fill[4]
int nb_segments
const Fill * fills
const Curve * curves
const Range * ranges
float lut[4][256 *256]
double var_values[VAR_VARS_NB]
void(* filter[4])(int max, int width, int height, const uint8_t *index, const uint8_t *src, uint8_t *dst, ptrdiff_t ilinesize, ptrdiff_t slinesize, ptrdiff_t dlinesize, float *lut, float opacity)
AVExpr * comp_expr[4]
int start
Used for passing data between threads.
Definition: dsddec.c:67
AVFrame * out
Definition: af_adeclick.c:502
AVFrame * in
Definition: af_adenorm.c:223
Definition: rpzaenc.c:58
#define av_log(a,...)
#define src
Definition: vp8dsp.c:255
FILE * out
Definition: movenc.c:54
AVFormatContext * ctx
Definition: movenc.c:48
#define height
#define width
const char * b
Definition: vf_curves.c:119
const char * g
Definition: vf_curves.c:118
const char * r
Definition: vf_curves.c:117
preset
Definition: vf_curves.c:47
static void hsub(htype *dst, const htype *src, int bins)
Definition: vf_median.c:76
static const int factor[16]
Definition: vf_pp7.c:77
@ VAR_H
@ VAR_VMAX
@ VAR_UMIN
@ VAR_YMAX
@ VAR_VAL
@ VAR_YMIN
@ VAR_AMAX
@ VAR_VMIN
@ VAR_W
@ VAR_VARS_NB
@ VAR_AMIN
@ VAR_UMAX
static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static double poly_eval(const double *const poly, double x)
#define PCLIP(v, max, dst, src, x)
static const AVOption pseudocolor_options[]
#define RGB_TO_Y_BT709(r, g, b)
static const Range shadows_range[]
#define RGB_TO_U_BT709(r1, g1, b1, max)
static void pseudocolor_filter_11d(int max, int width, int height, const uint8_t *index, const uint8_t *src, uint8_t *dst, ptrdiff_t ilinesize, ptrdiff_t slinesize, ptrdiff_t dlinesize, float *lut, float opacity)
static void pseudocolor_filter_16_10d(int max, int width, int height, const uint8_t *iindex, const uint8_t *ssrc, uint8_t *ddst, ptrdiff_t ilinesize, ptrdiff_t slinesize, ptrdiff_t dlinesize, float *lut, float opacity)
static void pseudocolor_filter_16_11(int max, int width, int height, const uint8_t *iindex, const uint8_t *ssrc, uint8_t *ddst, ptrdiff_t ilinesize, ptrdiff_t slinesize, ptrdiff_t dlinesize, float *lut, float opacity)
static int query_formats(AVFilterContext *ctx)
static int config_input(AVFilterLink *inlink)
static void pseudocolor_filter_16_10(int max, int width, int height, const uint8_t *iindex, const uint8_t *ssrc, uint8_t *ddst, ptrdiff_t ilinesize, ptrdiff_t slinesize, ptrdiff_t dlinesize, float *lut, float opacity)
#define FLAGS
static const AVFilterPad inputs[]
static const AVFilterPad outputs[]
static void pseudocolor_filter_16_11d(int max, int width, int height, const uint8_t *iindex, const uint8_t *ssrc, uint8_t *ddst, ptrdiff_t ilinesize, ptrdiff_t slinesize, ptrdiff_t dlinesize, float *lut, float opacity)
static const Fill spec2_fills[]
static const Preset presets[]
static const Range highlights_range[]
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
AVFilter ff_vf_pseudocolor
static void pseudocolor_filter(int max, int width, int height, const uint8_t *index, const uint8_t *src, uint8_t *dst, ptrdiff_t ilinesize, ptrdiff_t slinesize, ptrdiff_t dlinesize, float *lut, float opacity)
static const Range full_range
static const Curve curves[]
static enum AVPixelFormat pix_fmts[]
Curves
@ VIRIDIS
@ MAGMA
@ TURBO
@ INFERNO
@ NB_CURVES
@ PLASMA
@ CIVIDIS
static void pseudocolor_filter_11(int max, int width, int height, const uint8_t *index, const uint8_t *src, uint8_t *dst, ptrdiff_t ilinesize, ptrdiff_t slinesize, ptrdiff_t dlinesize, float *lut, float opacity)
static float lerpf(float v0, float v1, float f)
static const char *const var_names[]
static void pseudocolor_filter_16(int max, int width, int height, const uint8_t *iindex, const uint8_t *ssrc, uint8_t *ddst, ptrdiff_t ilinesize, ptrdiff_t slinesize, ptrdiff_t dlinesize, float *lut, float opacity)
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
#define RGB_TO_V_BT709(r1, g1, b1, max)
static av_cold void uninit(AVFilterContext *ctx)
static void pseudocolor_filter_10d(int max, int width, int height, const uint8_t *index, const uint8_t *src, uint8_t *dst, ptrdiff_t ilinesize, ptrdiff_t slinesize, ptrdiff_t dlinesize, float *lut, float opacity)
static const Fill shadows_fills[]
static const Fill spec1_fills[]
#define OFFSET(x)
static const Range spec1_range[]
static const Fill highlights_fills[]
AVFILTER_DEFINE_CLASS(pseudocolor)
Presets
@ PRESET_VIRIDIS
@ PRESET_TURBO
@ PRESET_RANGE1
@ PRESET_CIVIDIS
@ PRESET_PLASMA
@ PRESET_MAGMA
@ PRESET_SHADOWS
@ NB_PRESETS
@ PRESET_HIGHLIGHTS
@ PRESET_RANGE2
@ PRESET_INFERNO
static void pseudocolor_filter_10(int max, int width, int height, const uint8_t *index, const uint8_t *src, uint8_t *dst, ptrdiff_t ilinesize, ptrdiff_t slinesize, ptrdiff_t dlinesize, float *lut, float opacity)
static const Range spec2_range[]
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:104