FFmpeg  4.4.4
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 "formats.h"
29 #include "internal.h"
30 #include "video.h"
31 
32 static const char *const var_names[] = {
33  "w", ///< width of the input video
34  "h", ///< height of the input video
35  "val", ///< input value for the pixel
36  "ymin",
37  "umin",
38  "vmin",
39  "amin",
40  "ymax",
41  "umax",
42  "vmax",
43  "amax",
44  NULL
45 };
46 
47 enum var_name {
60 };
61 
62 enum Curves {
70 };
71 
72 enum Presets {
84 };
85 
86 typedef struct Curve {
87  double coef[3][8];
88 } Curve;
89 
90 typedef struct Fill {
91  float fill[4];
92 } Fill;
93 
94 typedef struct Range {
95  int start, end;
96 } Range;
97 
98 typedef struct Preset {
100  const Range *ranges;
101  const Curve *curves;
102  const Fill *fills;
103 } Preset;
104 
105 static const Range full_range = {0, 256};
106 static const Range spec1_range[] = {{0, 16}, {16, 236}, {236, 256}};
107 static const Range spec2_range[] = {{0, 16}, {16, 22}, {22, 226}, {226, 236}, {236, 256}};
108 static const Range shadows_range[] = {{0, 32}, {32, 256}};
109 static const Range highlights_range[] = {{0, 214}, {214, 224}, {224, 256}};
110 
111 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}}};
112 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}}};
113 static const Fill shadows_fills[] = {{{0.8f, 0.4f, .8f, 1.f}}, {{-1.f, -1.f, -1.f, 1.f}}};
114 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}}};
115 
116 static const Curve curves[] =
117 {
118  [MAGMA] = {{
119  {-7.5631093e-16, 7.4289183e-13, -2.8525484e-10, 5.4446085e-08, -5.5596238e-06, 3.0569325e-04, -2.3137421e-03, 1.2152095e-02 },
120  { 1.3217636e-15, -1.2214648e-12, 4.4319712e-10, -8.0197993e-08, 7.6598370e-06, -3.6523704e-04, 8.4836670e-03, -2.5536888e-02 },
121  {-1.1446568e-15, 1.0013446e-12, -3.5651575e-10, 6.6775016e-08, -6.7120346e-06, 2.7346619e-04, 4.7969657e-03, 1.1971441e-02 },
122  }},
123  [INFERNO] = {{
124  {-3.9848859e-18, 9.4821649e-14, -6.7371977e-11, 1.8469937e-08, -2.5359307e-06, 1.7959053e-04, 3.9782564e-04, 2.8845935e-04 },
125  { 6.8408539e-16, -6.5499979e-13, 2.4562526e-10, -4.5989298e-08, 4.5723324e-06, -2.2111913e-04, 5.2023164e-03, -1.1226064e-02 },
126  {-2.9921470e-15, 2.5864165e-12, -8.7403799e-10, 1.4713388e-07, -1.2701505e-05, 4.5159935e-04, 3.1087989e-03, 1.9122831e-02 },
127  }},
128  [PLASMA] = {{
129  { 3.6196089e-16, -3.3623041e-13, 1.2324010e-10, -2.2769060e-08, 2.2297792e-06, -1.2567829e-04, 9.9791629e-03, 5.7247918e-02 },
130  { 5.0262888e-16, -5.3193896e-13, 2.2451715e-10, -4.7529623e-08, 5.1374873e-06, -2.3260136e-04, 3.1502825e-03, 1.5362491e-02 },
131  {-1.7782261e-16, 2.2487839e-13, -1.0610236e-10, 2.4112644e-08, -2.6331623e-06, 8.9499751e-05, 2.1386328e-03, 5.3824268e-01 },
132  }},
133  [VIRIDIS] = {{
134  { 9.4850045e-16, -8.6629383e-13, 3.0310944e-10, -5.1340396e-08, 4.6024275e-06, -2.2744239e-04, 4.5559993e-03, 2.5662350e-01 },
135  { 9.6461041e-17, -6.9209477e-14, 1.7625397e-11, -2.0229773e-09, 1.4900110e-07, -1.9315187e-05, 5.8967339e-03, 3.9544827e-03 },
136  { 5.1785449e-16, -3.6663004e-13, 1.0249990e-10, -1.5431998e-08, 1.5007941e-06, -1.2001502e-04, 7.6951526e-03, 3.2292815e-01 },
137  }},
138  [TURBO] = {{
139  {-4.3683890e-15, 3.7020347e-12, -1.1712592e-09, 1.6401790e-07, -8.6842919e-06, -1.8542465e-06, 8.4485325e-03, 1.6267077e-01 },
140  {-4.0011069e-16, 2.7861423e-13, -6.3388921e-11, 5.8872238e-09, -5.4466522e-07, 1.8037114e-05, 1.0599869e-02, 7.6914696e-02 },
141  {-2.8242609e-15, 2.9234108e-12, -1.1726546e-09, 2.2552115e-07, -2.0059387e-05, 5.0595552e-04, 1.7714932e-02, 2.7271836e-01 },
142  }},
143  [CIVIDIS] = {{
144  {-9.5484131e-16, 9.6988184e-13, -4.0058766e-10, 8.5743924e-08, -9.9644797e-06, 5.9197908e-04, -1.0361579e-02, 3.3164429e-02 },
145  { 1.2731941e-17, -9.4238449e-15, 2.2808841e-12, -1.1548296e-10, -2.3888913e-08, 3.8986680e-06, 2.5879330e-03, 1.2769733e-01 },
146  { 4.6004608e-16, -5.0686849e-13, 2.2753449e-10, -5.3074099e-08, 6.7196096e-06, -4.4120020e-04, 1.3435551e-02, 2.8293355e-01 },
147  }},
148 };
149 
150 static const Preset presets[] =
151 {
152  [PRESET_MAGMA] = { 1, &full_range, &curves[MAGMA], NULL },
153  [PRESET_INFERNO] = { 1, &full_range, &curves[INFERNO], NULL },
154  [PRESET_PLASMA] = { 1, &full_range, &curves[PLASMA], NULL },
155  [PRESET_VIRIDIS] = { 1, &full_range, &curves[VIRIDIS], NULL },
156  [PRESET_TURBO] = { 1, &full_range, &curves[TURBO], NULL },
157  [PRESET_CIVIDIS] = { 1, &full_range, &curves[CIVIDIS], NULL },
162 };
163 
164 typedef struct PseudoColorContext {
165  const AVClass *class;
166  int preset;
167  float opacity;
168  int max;
169  int index;
171  int color;
172  int linesize[4];
173  int width[4], height[4];
175  char *comp_expr_str[4];
177  float lut[4][256*256];
178 
179  void (*filter[4])(int max, int width, int height,
180  const uint8_t *index, const uint8_t *src,
181  uint8_t *dst,
182  ptrdiff_t ilinesize,
183  ptrdiff_t slinesize,
184  ptrdiff_t dlinesize,
185  float *lut,
186  float opacity);
188 
189 #define OFFSET(x) offsetof(PseudoColorContext, x)
190 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
191 
192 static const AVOption pseudocolor_options[] = {
193  { "c0", "set component #0 expression", OFFSET(comp_expr_str[0]), AV_OPT_TYPE_STRING, {.str="val"}, .flags = FLAGS },
194  { "c1", "set component #1 expression", OFFSET(comp_expr_str[1]), AV_OPT_TYPE_STRING, {.str="val"}, .flags = FLAGS },
195  { "c2", "set component #2 expression", OFFSET(comp_expr_str[2]), AV_OPT_TYPE_STRING, {.str="val"}, .flags = FLAGS },
196  { "c3", "set component #3 expression", OFFSET(comp_expr_str[3]), AV_OPT_TYPE_STRING, {.str="val"}, .flags = FLAGS },
197  { "index", "set component as base", OFFSET(index), AV_OPT_TYPE_INT, {.i64=0}, 0, 3, .flags = FLAGS },
198  { "i", "set component as base", OFFSET(index), AV_OPT_TYPE_INT, {.i64=0}, 0, 3, .flags = FLAGS },
199  { "preset", "set preset", OFFSET(preset), AV_OPT_TYPE_INT, {.i64=-1},-1, NB_PRESETS-1, .flags = FLAGS, "preset" },
200  { "p", "set preset", OFFSET(preset), AV_OPT_TYPE_INT, {.i64=-1},-1, NB_PRESETS-1, .flags = FLAGS, "preset" },
201  { "none", NULL, 0, AV_OPT_TYPE_CONST, {.i64=-1}, .flags = FLAGS, "preset" },
202  { "magma", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_MAGMA}, .flags = FLAGS, "preset" },
203  { "inferno", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_INFERNO}, .flags = FLAGS, "preset" },
204  { "plasma", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_PLASMA}, .flags = FLAGS, "preset" },
205  { "viridis", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_VIRIDIS}, .flags = FLAGS, "preset" },
206  { "turbo", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_TURBO}, .flags = FLAGS, "preset" },
207  { "cividis", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_CIVIDIS}, .flags = FLAGS, "preset" },
208  { "range1", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_RANGE1}, .flags = FLAGS, "preset" },
209  { "range2", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_RANGE2}, .flags = FLAGS, "preset" },
210  { "shadows", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_SHADOWS}, .flags = FLAGS, "preset" },
211  { "highlights", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_HIGHLIGHTS},.flags=FLAGS, "preset" },
212  { "opacity", "set pseudocolor opacity",OFFSET(opacity), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 1, .flags = FLAGS },
213  { NULL }
214 };
215 
216 static const enum AVPixelFormat pix_fmts[] = {
243 };
244 
246 {
248  if (!fmts_list)
249  return AVERROR(ENOMEM);
250  return ff_set_common_formats(ctx, fmts_list);
251 }
252 
253 static inline float lerpf(float v0, float v1, float f)
254 {
255  return v0 + (v1 - v0) * f;
256 }
257 
258 #define PCLIP(v, max, dst, src, x) \
259  if (v >= 0 && v <= max) { \
260  dst[x] = lerpf(src[x], v, opacity);\
261  } else { \
262  dst[x] = src[x]; \
263  }
264 
265 static void pseudocolor_filter(int max, int width, int height,
266  const uint8_t *index,
267  const uint8_t *src,
268  uint8_t *dst,
269  ptrdiff_t ilinesize,
270  ptrdiff_t slinesize,
271  ptrdiff_t dlinesize,
272  float *lut,
273  float opacity)
274 {
275  int x, y;
276 
277  for (y = 0; y < height; y++) {
278  for (x = 0; x < width; x++) {
279  int v = lut[index[x]];
280 
281  PCLIP(v, max, dst, src, x);
282  }
283  index += ilinesize;
284  src += slinesize;
285  dst += dlinesize;
286  }
287 }
288 
289 static void pseudocolor_filter_11(int max, int width, int height,
290  const uint8_t *index,
291  const uint8_t *src,
292  uint8_t *dst,
293  ptrdiff_t ilinesize,
294  ptrdiff_t slinesize,
295  ptrdiff_t dlinesize,
296  float *lut,
297  float opacity)
298 {
299  int x, y;
300 
301  for (y = 0; y < height; y++) {
302  for (x = 0; x < width; x++) {
303  int v = lut[index[(y << 1) * ilinesize + (x << 1)]];
304 
305  PCLIP(v, max, dst, src, x);
306  }
307  src += slinesize;
308  dst += dlinesize;
309  }
310 }
311 
312 static void pseudocolor_filter_11d(int max, int width, int height,
313  const uint8_t *index,
314  const uint8_t *src,
315  uint8_t *dst,
316  ptrdiff_t ilinesize,
317  ptrdiff_t slinesize,
318  ptrdiff_t dlinesize,
319  float *lut,
320  float opacity)
321 {
322  int x, y;
323 
324  for (y = 0; y < height; y++) {
325  for (x = 0; x < width; x++) {
326  int v = lut[index[(y >> 1) * ilinesize + (x >> 1)]];
327 
328  PCLIP(v, max, dst, src, x);
329  }
330  src += slinesize;
331  dst += dlinesize;
332  }
333 }
334 
335 static void pseudocolor_filter_10(int max, int width, int height,
336  const uint8_t *index,
337  const uint8_t *src,
338  uint8_t *dst,
339  ptrdiff_t ilinesize,
340  ptrdiff_t slinesize,
341  ptrdiff_t dlinesize,
342  float *lut,
343  float opacity)
344 {
345  int x, y;
346 
347  for (y = 0; y < height; y++) {
348  for (x = 0; x < width; x++) {
349  int v = lut[index[x << 1]];
350 
351  PCLIP(v, max, dst, src, x);
352  }
353  index += ilinesize;
354  src += slinesize;
355  dst += dlinesize;
356  }
357 }
358 
359 static void pseudocolor_filter_10d(int max, int width, int height,
360  const uint8_t *index,
361  const uint8_t *src,
362  uint8_t *dst,
363  ptrdiff_t ilinesize,
364  ptrdiff_t slinesize,
365  ptrdiff_t dlinesize,
366  float *lut,
367  float opacity)
368 {
369  int x, y;
370 
371  for (y = 0; y < height; y++) {
372  for (x = 0; x < width; x++) {
373  int v = lut[index[x >> 1]];
374 
375  PCLIP(v, max, dst, src, x);
376  }
377  index += ilinesize;
378  src += slinesize;
379  dst += dlinesize;
380  }
381 }
382 
383 static void pseudocolor_filter_16(int max, int width, int height,
384  const uint8_t *iindex,
385  const uint8_t *ssrc,
386  uint8_t *ddst,
387  ptrdiff_t ilinesize,
388  ptrdiff_t slinesize,
389  ptrdiff_t dlinesize,
390  float *lut,
391  float opacity)
392 {
393  const uint16_t *index = (const uint16_t *)iindex;
394  const uint16_t *src = (const uint16_t *)ssrc;
395  uint16_t *dst = (uint16_t *)ddst;
396  int x, y;
397 
398  for (y = 0; y < height; y++) {
399  for (x = 0; x < width; x++) {
400  int v = lut[index[x]];
401 
402  PCLIP(v, max, dst, src, x);
403  }
404  index += ilinesize / 2;
405  src += slinesize / 2;
406  dst += dlinesize / 2;
407  }
408 }
409 
410 static void pseudocolor_filter_16_10(int max, int width, int height,
411  const uint8_t *iindex,
412  const uint8_t *ssrc,
413  uint8_t *ddst,
414  ptrdiff_t ilinesize,
415  ptrdiff_t slinesize,
416  ptrdiff_t dlinesize,
417  float *lut,
418  float opacity)
419 {
420  const uint16_t *index = (const uint16_t *)iindex;
421  const uint16_t *src = (const uint16_t *)ssrc;
422  uint16_t *dst = (uint16_t *)ddst;
423  int x, y;
424 
425  for (y = 0; y < height; y++) {
426  for (x = 0; x < width; x++) {
427  int v = lut[index[x << 1]];
428 
429  PCLIP(v, max, dst, src, x);
430  }
431  index += ilinesize / 2;
432  src += slinesize / 2;
433  dst += dlinesize / 2;
434  }
435 }
436 
437 static void pseudocolor_filter_16_10d(int max, int width, int height,
438  const uint8_t *iindex,
439  const uint8_t *ssrc,
440  uint8_t *ddst,
441  ptrdiff_t ilinesize,
442  ptrdiff_t slinesize,
443  ptrdiff_t dlinesize,
444  float *lut,
445  float opacity)
446 {
447  const uint16_t *index = (const uint16_t *)iindex;
448  const uint16_t *src = (const uint16_t *)ssrc;
449  uint16_t *dst = (uint16_t *)ddst;
450  int x, y;
451 
452  for (y = 0; y < height; y++) {
453  for (x = 0; x < width; x++) {
454  int v = lut[index[x >> 1]];
455 
456  PCLIP(v, max, dst, src, x);
457  }
458  index += ilinesize / 2;
459  src += slinesize / 2;
460  dst += dlinesize / 2;
461  }
462 }
463 
464 static void pseudocolor_filter_16_11(int max, int width, int height,
465  const uint8_t *iindex,
466  const uint8_t *ssrc,
467  uint8_t *ddst,
468  ptrdiff_t ilinesize,
469  ptrdiff_t slinesize,
470  ptrdiff_t dlinesize,
471  float *lut,
472  float opacity)
473 {
474  const uint16_t *index = (const uint16_t *)iindex;
475  const uint16_t *src = (const uint16_t *)ssrc;
476  uint16_t *dst = (uint16_t *)ddst;
477  int x, y;
478 
479  ilinesize /= 2;
480  dlinesize /= 2;
481  slinesize /= 2;
482 
483  for (y = 0; y < height; y++) {
484  for (x = 0; x < width; x++) {
485  int v = lut[index[(y << 1) * ilinesize + (x << 1)]];
486 
487  PCLIP(v, max, dst, src, x);
488  }
489  src += slinesize;
490  dst += dlinesize;
491  }
492 }
493 
494 static void pseudocolor_filter_16_11d(int max, int width, int height,
495  const uint8_t *iindex,
496  const uint8_t *ssrc,
497  uint8_t *ddst,
498  ptrdiff_t ilinesize,
499  ptrdiff_t slinesize,
500  ptrdiff_t dlinesize,
501  float *lut,
502  float opacity)
503 {
504  const uint16_t *index = (const uint16_t *)iindex;
505  const uint16_t *src = (const uint16_t *)ssrc;
506  uint16_t *dst = (uint16_t *)ddst;
507  int x, y;
508 
509  ilinesize /= 2;
510  dlinesize /= 2;
511  slinesize /= 2;
512 
513  for (y = 0; y < height; y++) {
514  for (x = 0; x < width; x++) {
515  int v = lut[index[(y >> 1) * ilinesize + (x >> 1)]];
516 
517  PCLIP(v, max, dst, src, x);
518  }
519  src += slinesize;
520  dst += dlinesize;
521  }
522 }
523 
524 #define RGB_TO_Y_BT709(r, g, b) \
525 ((0.21260*219.0/255.0) * (r) + (0.71520*219.0/255.0) * (g) + \
526  (0.07220*219.0/255.0) * (b))
527 
528 #define RGB_TO_U_BT709(r1, g1, b1, max) \
529 (-(0.11457*224.0/255.0) * r1 - (0.38543*224.0/255.0) * g1 + \
530  (0.50000*224.0/255.0) * b1 + max * 0.5)
531 
532 #define RGB_TO_V_BT709(r1, g1, b1, max) \
533 ((0.50000*224.0/255.0) * r1 - (0.45415*224.0/255.0) * g1 - \
534  (0.04585*224.0/255.0) * b1 + max * 0.5)
535 
536 static double poly_eval(const double *const poly, double x)
537 {
538  double res = 0.;
539 
540  for (int i = 0; i < 8; i++) {
541  res += pow(x, i) * poly[7-i];
542  }
543 
544  return av_clipd(res, 0., 1.);
545 }
546 
547 static int config_input(AVFilterLink *inlink)
548 {
549  AVFilterContext *ctx = inlink->dst;
550  PseudoColorContext *s = ctx->priv;
552  int depth, ret, hsub, vsub, color, factor, rgb;
553 
554  rgb = desc->flags & AV_PIX_FMT_FLAG_RGB;
555  depth = desc->comp[0].depth;
556  factor = 1 << (depth - 8);
557  s->max = (1 << depth) - 1;
558  s->nb_planes = av_pix_fmt_count_planes(inlink->format);
559 
560  if (s->index >= s->nb_planes) {
561  av_log(ctx, AV_LOG_ERROR, "index out of allowed range\n");
562  return AVERROR(EINVAL);
563  }
564 
565  if ((ret = av_image_fill_linesizes(s->linesize, inlink->format, inlink->w)) < 0)
566  return ret;
567 
568  hsub = desc->log2_chroma_w;
569  vsub = desc->log2_chroma_h;
570  s->height[1] = s->height[2] = AV_CEIL_RSHIFT(inlink->h, vsub);
571  s->height[0] = s->height[3] = inlink->h;
572  s->width[1] = s->width[2] = AV_CEIL_RSHIFT(inlink->w, hsub);
573  s->width[0] = s->width[3] = inlink->w;
574 
575  s->var_values[VAR_W] = inlink->w;
576  s->var_values[VAR_H] = inlink->h;
577 
578  s->var_values[VAR_YMIN] = 16 * (1 << (depth - 8));
579  s->var_values[VAR_UMIN] = 16 * (1 << (depth - 8));
580  s->var_values[VAR_VMIN] = 16 * (1 << (depth - 8));
581  s->var_values[VAR_AMIN] = 0;
582  s->var_values[VAR_YMAX] = 235 * (1 << (depth - 8));
583  s->var_values[VAR_UMAX] = 240 * (1 << (depth - 8));
584  s->var_values[VAR_VMAX] = 240 * (1 << (depth - 8));
585  s->var_values[VAR_AMAX] = s->max;
586 
587  for (color = 0; color < s->nb_planes && s->preset < 0; color++) {
588  double res;
589  int val;
590 
591  /* create the parsed expression */
592  av_expr_free(s->comp_expr[color]);
593  s->comp_expr[color] = NULL;
594  ret = av_expr_parse(&s->comp_expr[color], s->comp_expr_str[color],
595  var_names, NULL, NULL, NULL, NULL, 0, ctx);
596  if (ret < 0) {
598  "Error when parsing the expression '%s' for the component %d and color %d.\n",
599  s->comp_expr_str[color], color, color);
600  return AVERROR(EINVAL);
601  }
602 
603  /* compute the lut */
604  for (val = 0; val < FF_ARRAY_ELEMS(s->lut[color]); val++) {
605  s->var_values[VAR_VAL] = val;
606 
607  res = av_expr_eval(s->comp_expr[color], s->var_values, s);
608  if (isnan(res)) {
610  "Error when evaluating the expression '%s' for the value %d for the component %d.\n",
611  s->comp_expr_str[color], val, color);
612  return AVERROR(EINVAL);
613  }
614  s->lut[color][val] = res;
615  }
616  }
617 
618  if (s->preset >= 0) {
619  int nb_segments = presets[s->preset].nb_segments;
620 
621  for (int seg = 0; seg < nb_segments; seg++) {
622  int start = presets[s->preset].ranges[seg].start;
623  int end = presets[s->preset].ranges[seg].end;
624 
625  for (int i = start; i < end; i++) {
626  if (!presets[s->preset].curves) {
627  const Fill fill = presets[s->preset].fills[seg];
628 
629  for (int j = 0; j < factor; j++) {
630  double r, g, b, a;
631 
632  g = fill.fill[1];
633  b = fill.fill[2];
634  r = fill.fill[0];
635  a = fill.fill[3];
636 
637  if (g >= 0.f && b >= 0.f && r >= 0.f) {
638  g *= s->max;
639  b *= s->max;
640  r *= s->max;
641 
642  if (!rgb) {
643  double y = RGB_TO_Y_BT709(r, g, b);
644  double u = RGB_TO_U_BT709(r, g, b, s->max);
645  double v = RGB_TO_V_BT709(r, g, b, s->max);
646 
647  r = v;
648  g = y;
649  b = u;
650  }
651  }
652 
653  s->lut[0][i*factor+j] = g;
654  s->lut[1][i*factor+j] = b;
655  s->lut[2][i*factor+j] = r;
656  s->lut[3][i*factor+j] = a * s->max;
657  }
658  } else {
659  const Curve curve = presets[s->preset].curves[seg];
660 
661  for (int j = 0; j < factor; j++) {
662  const double lf = j / (double)factor;
663  double r, g, b;
664 
665  g = poly_eval(curve.coef[1], i + lf) * s->max;
666  b = poly_eval(curve.coef[2], i + lf) * s->max;
667  r = poly_eval(curve.coef[0], i + lf) * s->max;
668 
669  if (!rgb) {
670  double y = RGB_TO_Y_BT709(r, g, b);
671  double u = RGB_TO_U_BT709(r, g, b, s->max);
672  double v = RGB_TO_V_BT709(r, g, b, s->max);
673 
674  r = v;
675  g = y;
676  b = u;
677  }
678 
679  s->lut[0][i*factor+j] = g;
680  s->lut[1][i*factor+j] = b;
681  s->lut[2][i*factor+j] = r;
682  s->lut[3][i*factor+j] = 1.f * s->max;
683  }
684  }
685  }
686  }
687  }
688 
689  switch (inlink->format) {
690  case AV_PIX_FMT_YUV444P:
691  case AV_PIX_FMT_YUVA444P:
692  case AV_PIX_FMT_GBRP:
693  case AV_PIX_FMT_GBRAP:
694  case AV_PIX_FMT_GRAY8:
695  s->filter[0] = s->filter[1] = s->filter[2] = s->filter[3] = pseudocolor_filter;
696  break;
697  case AV_PIX_FMT_YUV420P:
698  case AV_PIX_FMT_YUVA420P:
699  switch (s->index) {
700  case 0:
701  case 3:
702  s->filter[0] = s->filter[3] = pseudocolor_filter;
703  s->filter[1] = s->filter[2] = pseudocolor_filter_11;
704  break;
705  case 1:
706  case 2:
707  s->filter[0] = s->filter[3] = pseudocolor_filter_11d;
708  s->filter[1] = s->filter[2] = pseudocolor_filter;
709  break;
710  }
711  break;
712  case AV_PIX_FMT_YUV422P:
713  case AV_PIX_FMT_YUVA422P:
714  switch (s->index) {
715  case 0:
716  case 3:
717  s->filter[0] = s->filter[3] = pseudocolor_filter;
718  s->filter[1] = s->filter[2] = pseudocolor_filter_10;
719  break;
720  case 1:
721  case 2:
722  s->filter[0] = s->filter[3] = pseudocolor_filter_10d;
723  s->filter[1] = s->filter[2] = pseudocolor_filter;
724  break;
725  }
726  break;
727  case AV_PIX_FMT_YUV444P9:
735  case AV_PIX_FMT_GBRP9:
736  case AV_PIX_FMT_GBRP10:
737  case AV_PIX_FMT_GBRP12:
738  case AV_PIX_FMT_GBRP14:
739  case AV_PIX_FMT_GBRP16:
740  case AV_PIX_FMT_GBRAP10:
741  case AV_PIX_FMT_GBRAP12:
742  case AV_PIX_FMT_GBRAP16:
743  case AV_PIX_FMT_GRAY9:
744  case AV_PIX_FMT_GRAY10:
745  case AV_PIX_FMT_GRAY12:
746  case AV_PIX_FMT_GRAY14:
747  case AV_PIX_FMT_GRAY16:
748  s->filter[0] = s->filter[1] = s->filter[2] = s->filter[3] = pseudocolor_filter_16;
749  break;
750  case AV_PIX_FMT_YUV422P9:
758  switch (s->index) {
759  case 0:
760  case 3:
761  s->filter[0] = s->filter[3] = pseudocolor_filter_16;
762  s->filter[1] = s->filter[2] = pseudocolor_filter_16_10;
763  break;
764  case 1:
765  case 2:
766  s->filter[0] = s->filter[3] = pseudocolor_filter_16_10d;
767  s->filter[1] = s->filter[2] = pseudocolor_filter_16;
768  break;
769  }
770  break;
771  case AV_PIX_FMT_YUV420P9:
779  switch (s->index) {
780  case 0:
781  case 3:
782  s->filter[0] = s->filter[3] = pseudocolor_filter_16;
783  s->filter[1] = s->filter[2] = pseudocolor_filter_16_11;
784  break;
785  case 1:
786  case 2:
787  s->filter[0] = s->filter[3] = pseudocolor_filter_16_11d;
788  s->filter[1] = s->filter[2] = pseudocolor_filter_16;
789  break;
790  }
791  break;
792  }
793 
794  return 0;
795 }
796 
797 typedef struct ThreadData {
798  AVFrame *in, *out;
799 } ThreadData;
800 
801 static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
802 {
803  PseudoColorContext *s = ctx->priv;
804  ThreadData *td = arg;
805  AVFrame *in = td->in;
806  AVFrame *out = td->out;
807 
808  for (int plane = 0; plane < s->nb_planes; plane++) {
809  const int slice_start = (s->height[plane] * jobnr) / nb_jobs;
810  const int slice_end = (s->height[plane] * (jobnr+1)) / nb_jobs;
811  const int islice_start = (s->height[s->index] * jobnr) / nb_jobs;
812  ptrdiff_t ilinesize = in->linesize[s->index];
813  ptrdiff_t slinesize = in->linesize[plane];
814  ptrdiff_t dlinesize = out->linesize[plane];
815  const uint8_t *index = in->data[s->index] + islice_start * ilinesize;
816  const uint8_t *src = in->data[plane] + slice_start * slinesize;
817  uint8_t *dst = out->data[plane] + slice_start * dlinesize;
818 
819  s->filter[plane](s->max, s->width[plane], slice_end - slice_start,
820  index, src, dst, ilinesize, slinesize,
821  dlinesize, s->lut[plane], s->opacity);
822  }
823 
824  return 0;
825 }
826 
827 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
828 {
829  AVFilterContext *ctx = inlink->dst;
830  PseudoColorContext *s = ctx->priv;
831  AVFilterLink *outlink = ctx->outputs[0];
832  ThreadData td;
833  AVFrame *out;
834 
835  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
836  if (!out) {
837  av_frame_free(&in);
838  return AVERROR(ENOMEM);
839  }
841 
842  td.out = out, td.in = in;
843  ctx->internal->execute(ctx, filter_slice, &td, NULL, FFMIN(s->height[1], ff_filter_get_nb_threads(ctx)));
844 
845  av_frame_free(&in);
846  return ff_filter_frame(outlink, out);
847 }
848 
849 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
850  char *res, int res_len, int flags)
851 {
852  int ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags);
853 
854  if (ret < 0)
855  return ret;
856 
857  return config_input(ctx->inputs[0]);
858 }
859 
860 static const AVFilterPad inputs[] = {
861  {
862  .name = "default",
863  .type = AVMEDIA_TYPE_VIDEO,
864  .filter_frame = filter_frame,
865  .config_props = config_input,
866  },
867  { NULL }
868 };
869 
870 static const AVFilterPad outputs[] = {
871  {
872  .name = "default",
873  .type = AVMEDIA_TYPE_VIDEO,
874  },
875  { NULL }
876 };
877 
879 {
880  PseudoColorContext *s = ctx->priv;
881  int i;
882 
883  for (i = 0; i < 4; i++) {
884  av_expr_free(s->comp_expr[i]);
885  s->comp_expr[i] = NULL;
886  }
887 }
888 
890 
892  .name = "pseudocolor",
893  .description = NULL_IF_CONFIG_SMALL("Make pseudocolored video frames."),
894  .priv_size = sizeof(PseudoColorContext),
895  .priv_class = &pseudocolor_class,
896  .uninit = uninit,
898  .inputs = inputs,
899  .outputs = outputs,
902 };
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:561
#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:336
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
Evaluate a previously parsed expression.
Definition: eval.c:766
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:685
simple arithmetic expression evaluator
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:157
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:118
const char * g
Definition: vf_curves.c:117
const char * r
Definition: vf_curves.c:116
preset
Definition: vf_curves.c:46
static void hsub(htype *dst, const htype *src, int bins)
Definition: vf_median.c:75
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