FFmpeg
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 
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 
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 
889 AVFILTER_DEFINE_CLASS(pseudocolor);
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 };
process_command
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
Definition: vf_pseudocolor.c:849
PRESET_VIRIDIS
@ PRESET_VIRIDIS
Definition: vf_pseudocolor.c:76
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
AV_PIX_FMT_YUVA422P16
#define AV_PIX_FMT_YUVA422P16
Definition: pixfmt.h:442
AV_PIX_FMT_GBRAP16
#define AV_PIX_FMT_GBRAP16
Definition: pixfmt.h:421
pseudocolor_filter_10
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)
Definition: vf_pseudocolor.c:335
td
#define td
Definition: regdef.h:70
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
PseudoColorContext::width
int width[4]
Definition: vf_pseudocolor.c:173
Preset::nb_segments
int nb_segments
Definition: vf_pseudocolor.c:99
r
const char * r
Definition: vf_curves.c:116
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
ff_make_format_list
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:286
out
FILE * out
Definition: movenc.c:54
curves
static const Curve curves[]
Definition: vf_pseudocolor.c:116
color
Definition: vf_paletteuse.c:583
u
#define u(width, name, range_min, range_max)
Definition: cbs_h2645.c:264
filter_slice
static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_pseudocolor.c:801
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1096
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2573
PseudoColorContext::linesize
int linesize[4]
Definition: vf_pseudocolor.c:172
query_formats
static int query_formats(AVFilterContext *ctx)
Definition: vf_pseudocolor.c:245
PseudoColorContext::color
int color
Definition: vf_pseudocolor.c:171
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
spec2_fills
static const Fill spec2_fills[]
Definition: vf_pseudocolor.c:112
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:203
VAR_AMAX
@ VAR_AMAX
Definition: vf_pseudocolor.c:58
AV_PIX_FMT_YUVA422P9
#define AV_PIX_FMT_YUVA422P9
Definition: pixfmt.h:434
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:318
pixdesc.h
AV_PIX_FMT_YUVA420P16
#define AV_PIX_FMT_YUVA420P16
Definition: pixfmt.h:441
poly_eval
static double poly_eval(const double *const poly, double x)
Definition: vf_pseudocolor.c:536
spec1_range
static const Range spec1_range[]
Definition: vf_pseudocolor.c:106
AV_PIX_FMT_YUVA420P10
#define AV_PIX_FMT_YUVA420P10
Definition: pixfmt.h:436
AVOption
AVOption.
Definition: opt.h:248
b
#define b
Definition: input.c:41
AV_PIX_FMT_YUV420P10
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:399
VAR_UMAX
@ VAR_UMAX
Definition: vf_pseudocolor.c:56
TURBO
@ TURBO
Definition: vf_pseudocolor.c:67
lerpf
static float lerpf(float v0, float v1, float f)
Definition: vf_pseudocolor.c:253
max
#define max(a, b)
Definition: cuda_runtime.h:33
PRESET_RANGE1
@ PRESET_RANGE1
Definition: vf_pseudocolor.c:79
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:149
ThreadData::out
AVFrame * out
Definition: af_adeclick.c:502
video.h
AVFormatContext::internal
AVFormatInternal * internal
An opaque field for libavformat internal usage.
Definition: avformat.h:1699
AV_PIX_FMT_YUVA422P10
#define AV_PIX_FMT_YUVA422P10
Definition: pixfmt.h:437
Preset::curves
const Curve * curves
Definition: vf_pseudocolor.c:101
AV_PIX_FMT_GRAY9
#define AV_PIX_FMT_GRAY9
Definition: pixfmt.h:379
pseudocolor_filter_16_10
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)
Definition: vf_pseudocolor.c:410
hsub
static void hsub(htype *dst, const htype *src, int bins)
Definition: vf_median.c:75
AVFilterFormats
A list of supported formats for one end of a filter link.
Definition: formats.h:65
formats.h
av_expr_parse
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
PRESET_RANGE2
@ PRESET_RANGE2
Definition: vf_pseudocolor.c:80
av_pix_fmt_count_planes
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2613
AV_PIX_FMT_YUVA420P9
#define AV_PIX_FMT_YUVA420P9
Definition: pixfmt.h:433
rgb
Definition: rpzaenc.c:58
PseudoColorContext::comp_expr
AVExpr * comp_expr[4]
Definition: vf_pseudocolor.c:176
AV_PIX_FMT_GBRP14
#define AV_PIX_FMT_GBRP14
Definition: pixfmt.h:417
VIRIDIS
@ VIRIDIS
Definition: vf_pseudocolor.c:66
AV_PIX_FMT_GBRAP
@ AV_PIX_FMT_GBRAP
planar GBRA 4:4:4:4 32bpp
Definition: pixfmt.h:215
highlights_fills
static const Fill highlights_fills[]
Definition: vf_pseudocolor.c:114
v0
#define v0
Definition: regdef.h:26
presets
static const Preset presets[]
Definition: vf_pseudocolor.c:150
AV_PIX_FMT_GBRP10
#define AV_PIX_FMT_GBRP10
Definition: pixfmt.h:415
AV_PIX_FMT_YUVA444P16
#define AV_PIX_FMT_YUVA444P16
Definition: pixfmt.h:443
pseudocolor_filter_16
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)
Definition: vf_pseudocolor.c:383
pseudocolor_filter_16_11d
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)
Definition: vf_pseudocolor.c:494
AV_PIX_FMT_YUV422P9
#define AV_PIX_FMT_YUV422P9
Definition: pixfmt.h:397
PRESET_SHADOWS
@ PRESET_SHADOWS
Definition: vf_pseudocolor.c:81
val
static double val(void *priv, double ch)
Definition: aeval.c:76
AV_PIX_FMT_GRAY16
#define AV_PIX_FMT_GRAY16
Definition: pixfmt.h:383
av_expr_free
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
Definition: eval.c:336
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:402
preset
preset
Definition: vf_curves.c:46
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
av_cold
#define av_cold
Definition: attributes.h:90
var_name
var_name
Definition: setts_bsf.c:50
AV_PIX_FMT_YUV422P16
#define AV_PIX_FMT_YUV422P16
Definition: pixfmt.h:411
ff_set_common_formats
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
PRESET_HIGHLIGHTS
@ PRESET_HIGHLIGHTS
Definition: vf_pseudocolor.c:82
AV_PIX_FMT_GBRAP10
#define AV_PIX_FMT_GBRAP10
Definition: pixfmt.h:419
PLASMA
@ PLASMA
Definition: vf_pseudocolor.c:65
width
#define width
av_image_fill_linesizes
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
RGB_TO_Y_BT709
#define RGB_TO_Y_BT709(r, g, b)
Definition: vf_pseudocolor.c:524
s
#define s(width, name)
Definition: cbs_vp9.c:257
AV_PIX_FMT_GBRAP12
#define AV_PIX_FMT_GBRAP12
Definition: pixfmt.h:420
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_PIX_FMT_YUV444P16
#define AV_PIX_FMT_YUV444P16
Definition: pixfmt.h:412
AV_CEIL_RSHIFT
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:58
g
const char * g
Definition: vf_curves.c:117
RGB_TO_U_BT709
#define RGB_TO_U_BT709(r1, g1, b1, max)
Definition: vf_pseudocolor.c:528
slice_end
static int slice_end(AVCodecContext *avctx, AVFrame *pict)
Handle slice ends.
Definition: mpeg12dec.c:2033
VAR_VMIN
@ VAR_VMIN
Definition: vf_pseudocolor.c:53
shadows_fills
static const Fill shadows_fills[]
Definition: vf_pseudocolor.c:113
AV_PIX_FMT_YUV420P9
#define AV_PIX_FMT_YUV420P9
Definition: pixfmt.h:396
AV_PIX_FMT_YUV420P16
#define AV_PIX_FMT_YUV420P16
Definition: pixfmt.h:410
ctx
AVFormatContext * ctx
Definition: movenc.c:48
av_expr_eval
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
Evaluate a previously parsed expression.
Definition: eval.c:766
AV_PIX_FMT_GRAY14
#define AV_PIX_FMT_GRAY14
Definition: pixfmt.h:382
AVExpr
Definition: eval.c:157
VAR_YMAX
@ VAR_YMAX
Definition: vf_pseudocolor.c:55
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
arg
const char * arg
Definition: jacosubdec.c:66
AV_PIX_FMT_GRAY10
#define AV_PIX_FMT_GRAY10
Definition: pixfmt.h:380
Presets
Presets
Definition: vf_pseudocolor.c:72
pseudocolor_filter_10d
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)
Definition: vf_pseudocolor.c:359
AV_PIX_FMT_GBRP16
#define AV_PIX_FMT_GBRP16
Definition: pixfmt.h:418
shadows_range
static const Range shadows_range[]
Definition: vf_pseudocolor.c:108
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:67
CIVIDIS
@ CIVIDIS
Definition: vf_pseudocolor.c:68
NULL
#define NULL
Definition: coverity.c:32
outputs
static const AVFilterPad outputs[]
Definition: vf_pseudocolor.c:870
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:658
MAGMA
@ MAGMA
Definition: vf_pseudocolor.c:63
pseudocolor_filter_16_10d
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)
Definition: vf_pseudocolor.c:437
VAR_VARS_NB
@ VAR_VARS_NB
Definition: vf_pseudocolor.c:59
spec2_range
static const Range spec2_range[]
Definition: vf_pseudocolor.c:107
isnan
#define isnan(x)
Definition: libm.h:340
NB_PRESETS
@ NB_PRESETS
Definition: vf_pseudocolor.c:83
OFFSET
#define OFFSET(x)
Definition: vf_pseudocolor.c:189
src
#define src
Definition: vp8dsp.c:255
var_names
static const char *const var_names[]
Definition: vf_pseudocolor.c:32
AV_PIX_FMT_YUV422P10
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:400
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:74
VAR_UMIN
@ VAR_UMIN
Definition: vf_pseudocolor.c:52
AV_PIX_FMT_GBRP9
#define AV_PIX_FMT_GBRP9
Definition: pixfmt.h:414
FLAGS
#define FLAGS
Definition: vf_pseudocolor.c:190
Range
Definition: vf_colorbalance.c:38
index
int index
Definition: gxfenc.c:89
VAR_VMAX
@ VAR_VMAX
Definition: vf_pseudocolor.c:57
eval.h
Preset::ranges
const Range * ranges
Definition: vf_pseudocolor.c:100
RGB_TO_V_BT709
#define RGB_TO_V_BT709(r1, g1, b1, max)
Definition: vf_pseudocolor.c:532
pseudocolor_options
static const AVOption pseudocolor_options[]
Definition: vf_pseudocolor.c:192
PseudoColorContext::height
int height[4]
Definition: vf_pseudocolor.c:173
PseudoColorContext::comp_expr_str
char * comp_expr_str[4]
Definition: vf_pseudocolor.c:175
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:117
PseudoColorContext::nb_planes
int nb_planes
Definition: vf_pseudocolor.c:170
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
Curve
Definition: vf_pseudocolor.c:86
av_clipd
#define av_clipd
Definition: common.h:173
AV_PIX_FMT_YUV422P12
#define AV_PIX_FMT_YUV422P12
Definition: pixfmt.h:404
PCLIP
#define PCLIP(v, max, dst, src, x)
Definition: vf_pseudocolor.c:258
PseudoColorContext::index
int index
Definition: vf_pseudocolor.c:169
color
static const uint32_t color[16+AV_CLASS_CATEGORY_NB]
Definition: log.c:92
PRESET_MAGMA
@ PRESET_MAGMA
Definition: vf_pseudocolor.c:73
AV_PIX_FMT_YUV444P12
#define AV_PIX_FMT_YUV444P12
Definition: pixfmt.h:406
ff_filter_process_command
int ff_filter_process_command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
Generic processing of user supplied commands that are set in the same way as the filter options.
Definition: avfilter.c:882
pseudocolor_filter
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)
Definition: vf_pseudocolor.c:265
height
#define height
FFMIN
#define FFMIN(a, b)
Definition: common.h:105
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
Fill
Definition: vf_pseudocolor.c:90
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
VAR_W
@ VAR_W
Definition: vf_pseudocolor.c:48
AV_PIX_FMT_YUVA444P10
#define AV_PIX_FMT_YUVA444P10
Definition: pixfmt.h:438
attributes.h
PseudoColorContext
Definition: vf_pseudocolor.c:164
full_range
static const Range full_range
Definition: vf_pseudocolor.c:105
VAR_H
@ VAR_H
Definition: vf_pseudocolor.c:49
internal.h
AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
#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
AV_OPT_TYPE_FLOAT
@ AV_OPT_TYPE_FLOAT
Definition: opt.h:228
Fill::fill
float fill[4]
Definition: vf_pseudocolor.c:91
PRESET_PLASMA
@ PRESET_PLASMA
Definition: vf_pseudocolor.c:75
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
Curve::coef
double coef[3][8]
Definition: vf_pseudocolor.c:87
i
int i
Definition: input.c:407
PRESET_CIVIDIS
@ PRESET_CIVIDIS
Definition: vf_pseudocolor.c:78
Range::start
int start
Definition: vf_pseudocolor.c:95
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_pseudocolor.c:878
Preset::fills
const Fill * fills
Definition: vf_pseudocolor.c:102
AV_PIX_FMT_GBRP12
#define AV_PIX_FMT_GBRP12
Definition: pixfmt.h:416
common.h
ff_filter_get_nb_threads
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:802
pseudocolor_filter_16_11
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)
Definition: vf_pseudocolor.c:464
ThreadData
Used for passing data between threads.
Definition: dsddec.c:67
pseudocolor_filter_11
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)
Definition: vf_pseudocolor.c:289
uint8_t
uint8_t
Definition: audio_convert.c:194
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:60
pix_fmts
static enum AVPixelFormat pix_fmts[]
Definition: vf_pseudocolor.c:216
inputs
static const AVFilterPad inputs[]
Definition: vf_pseudocolor.c:860
AV_PIX_FMT_YUV444P9
#define AV_PIX_FMT_YUV444P9
Definition: pixfmt.h:398
AVFilter
Filter definition.
Definition: avfilter.h:145
config_input
static int config_input(AVFilterLink *inlink)
Definition: vf_pseudocolor.c:547
ret
ret
Definition: filter_design.txt:187
PseudoColorContext::var_values
double var_values[VAR_VARS_NB]
Definition: vf_pseudocolor.c:174
PRESET_TURBO
@ PRESET_TURBO
Definition: vf_pseudocolor.c:77
Preset
Definition: vf_pseudocolor.c:98
AV_PIX_FMT_YUVA444P9
#define AV_PIX_FMT_YUVA444P9
Definition: pixfmt.h:435
AV_PIX_FMT_YUV420P12
#define AV_PIX_FMT_YUV420P12
Definition: pixfmt.h:403
AV_PIX_FMT_YUV422P14
#define AV_PIX_FMT_YUV422P14
Definition: pixfmt.h:408
VAR_YMIN
@ VAR_YMIN
Definition: vf_pseudocolor.c:51
spec1_fills
static const Fill spec1_fills[]
Definition: vf_pseudocolor.c:111
VAR_VAL
@ VAR_VAL
Definition: vf_pseudocolor.c:50
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
NB_CURVES
@ NB_CURVES
Definition: vf_pseudocolor.c:69
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:225
avfilter.h
VAR_AMIN
@ VAR_AMIN
Definition: vf_pseudocolor.c:54
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:341
factor
static const int factor[16]
Definition: vf_pp7.c:77
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(pseudocolor)
AV_PIX_FMT_GBRP
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:168
AVFILTER_FLAG_SLICE_THREADS
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Definition: avfilter.h:117
desc
const char * desc
Definition: libsvtav1.c:79
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
ThreadData::in
AVFrame * in
Definition: af_adenorm.c:223
INFERNO
@ INFERNO
Definition: vf_pseudocolor.c:64
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
PseudoColorContext::filter
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)
Definition: vf_pseudocolor.c:179
pseudocolor_filter_11d
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)
Definition: vf_pseudocolor.c:312
PRESET_INFERNO
@ PRESET_INFERNO
Definition: vf_pseudocolor.c:74
ff_vf_pseudocolor
AVFilter ff_vf_pseudocolor
Definition: vf_pseudocolor.c:891
imgutils.h
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
rgb
static const SheerTable rgb[2]
Definition: sheervideodata.h:32
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
Curves
Curves
Definition: vf_pseudocolor.c:62
PseudoColorContext::opacity
float opacity
Definition: vf_pseudocolor.c:167
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: vf_pseudocolor.c:827
PseudoColorContext::lut
float lut[4][256 *256]
Definition: vf_pseudocolor.c:177
AV_PIX_FMT_YUV444P14
#define AV_PIX_FMT_YUV444P14
Definition: pixfmt.h:409
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:229
AV_PIX_FMT_GRAY12
#define AV_PIX_FMT_GRAY12
Definition: pixfmt.h:381
highlights_range
static const Range highlights_range[]
Definition: vf_pseudocolor.c:109
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:234
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
AV_PIX_FMT_YUV420P14
#define AV_PIX_FMT_YUV420P14
Definition: pixfmt.h:407
Range::end
int end
Definition: vf_pseudocolor.c:95
PseudoColorContext::preset
int preset
Definition: vf_pseudocolor.c:166
PseudoColorContext::max
int max
Definition: vf_pseudocolor.c:168