FFmpeg
Loading...
Searching...
No Matches
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
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 "video.h"
30
31static const char *const var_names[] = {
32 "w", ///< width of the input video
33 "h", ///< height of the input video
34 "val", ///< input value for the pixel
35 "ymin",
36 "umin",
37 "vmin",
38 "amin",
39 "ymax",
40 "umax",
41 "vmax",
42 "amax",
43 NULL
44};
45
60
78
103
104typedef double (*curve_fun)(double x);
105
106typedef struct Curve {
107 double coef[3][8];
108 double offset[3];
110 int yuv;
111} Curve;
112
113typedef struct Fill {
114 float fill[4];
115} Fill;
116
117typedef struct Range {
119} Range;
120
121typedef struct Preset {
123 const Range *ranges;
124 const Curve *curves;
125 const Fill *fills;
126} Preset;
127
128static const Range full_range = {{0, 1}, {1, 1}};
129static const Range nominal_range[] = {{{0, 1}, {4096, 65536}}, {{4096, 65536}, {60161, 65536}}, {{60161, 65536}, {1, 1}}};
130static const Range preferred_range[] = {{{0, 1}, {1280, 65536}}, {{1280, 65536}, {62977, 65536}}, {{62977, 65536}, {1, 1}}};
131static const Range total_range[] = {{{0, 1}, {256, 65536}}, {{256, 65536}, {65280, 65536}}, {{65280, 65536}, {1, 1}}};
132static const Range spec1_range[] = {{{0, 1}, {16, 256}}, {{16, 256}, {236, 256}}, {{236, 256}, {256, 256}}};
133static const Range spec2_range[] = {{{0, 1}, {16, 256}}, {{16, 256}, {22, 256}}, {{22, 256}, {226, 256}}, {{226, 256}, {236, 256}}, {{236, 256}, {256, 256}}};
134static const Range shadows_range[] = {{{0, 1}, {32, 256}}, {{32, 256}, {256, 256}}};
135static const Range highlights_range[] = {{{0,1}, {214,256}}, {{214, 256}, {224, 256}}, {{224, 256}, {256, 256}}};
136
137static 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}}};
138static 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}}};
139static const Fill shadows_fills[] = {{{0.8f, 0.4f, .8f, 1.f}}, {{-1.f, -1.f, -1.f, 1.f}}};
140static 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}}};
141
142static double limit(double x)
143{
144 return av_clipd(x, 0., 1.);
145}
146
147static double solarfun(double x)
148{
149 return 0.5 * sin(x) + 0.5;
150}
151
152static double coolfunu(double x)
153{
154 return 0.25 * sin(2.0 * x * M_PI - M_PI) + 0.5;
155}
156
157static double coolfunv(double x)
158{
159 return 0.25 * sin(2.0 * x * M_PI) + 0.5;
160}
161
162static double heatfunu(double x)
163{
164 return 0.25 * cos(2.0 * x * M_PI + M_PI) + 0.75;
165}
166
167static double heatfunv(double x)
168{
169 return 0.25 * sin(2.0 * x * M_PI) + 0.5;
170}
171
172static double fieryfunu(double x)
173{
174 return 0.75 - 0.25 * cos(2.0 * x * M_PI);
175}
176
177static double fieryfunv(double x)
178{
179 return 0.25 + 0.25 * cos(2.0 * x * M_PI);
180}
181
182static double helixfunu(double x)
183{
184 return 0.5 + 0.15 * sin(5.0 * x * M_PI + M_PI);
185}
186
187static double helixfunv(double x)
188{
189 return 0.5 + 0.15 * cos(6.0 * x * M_PI + M_PI_2);
190}
191
192static const Curve curves[] =
193{
194 [MAGMA] = {{
195 {-7.5631093e-16, 7.4289183e-13, -2.8525484e-10, 5.4446085e-08, -5.5596238e-06, 3.0569325e-04, -2.3137421e-03, 1.2152095e-02 },
196 { 1.3217636e-15, -1.2214648e-12, 4.4319712e-10, -8.0197993e-08, 7.6598370e-06, -3.6523704e-04, 8.4836670e-03, -2.5536888e-02 },
197 {-1.1446568e-15, 1.0013446e-12, -3.5651575e-10, 6.6775016e-08, -6.7120346e-06, 2.7346619e-04, 4.7969657e-03, 1.1971441e-02 },
198 }, .fun = { limit, limit, limit }, },
199 [INFERNO] = {{
200 {-3.9848859e-18, 9.4821649e-14, -6.7371977e-11, 1.8469937e-08, -2.5359307e-06, 1.7959053e-04, 3.9782564e-04, 2.8845935e-04 },
201 { 6.8408539e-16, -6.5499979e-13, 2.4562526e-10, -4.5989298e-08, 4.5723324e-06, -2.2111913e-04, 5.2023164e-03, -1.1226064e-02 },
202 {-2.9921470e-15, 2.5864165e-12, -8.7403799e-10, 1.4713388e-07, -1.2701505e-05, 4.5159935e-04, 3.1087989e-03, 1.9122831e-02 },
203 }, .fun = { limit, limit, limit }, },
204 [PLASMA] = {{
205 { 3.6196089e-16, -3.3623041e-13, 1.2324010e-10, -2.2769060e-08, 2.2297792e-06, -1.2567829e-04, 9.9791629e-03, 5.7247918e-02 },
206 { 5.0262888e-16, -5.3193896e-13, 2.2451715e-10, -4.7529623e-08, 5.1374873e-06, -2.3260136e-04, 3.1502825e-03, 1.5362491e-02 },
207 {-1.7782261e-16, 2.2487839e-13, -1.0610236e-10, 2.4112644e-08, -2.6331623e-06, 8.9499751e-05, 2.1386328e-03, 5.3824268e-01 },
208 }, .fun = { limit, limit, limit }, },
209 [VIRIDIS] = {{
210 { 9.4850045e-16, -8.6629383e-13, 3.0310944e-10, -5.1340396e-08, 4.6024275e-06, -2.2744239e-04, 4.5559993e-03, 2.5662350e-01 },
211 { 9.6461041e-17, -6.9209477e-14, 1.7625397e-11, -2.0229773e-09, 1.4900110e-07, -1.9315187e-05, 5.8967339e-03, 3.9544827e-03 },
212 { 5.1785449e-16, -3.6663004e-13, 1.0249990e-10, -1.5431998e-08, 1.5007941e-06, -1.2001502e-04, 7.6951526e-03, 3.2292815e-01 },
213 }, .fun = { limit, limit, limit }, },
214 [TURBO] = {{
215 {-4.3683890e-15, 3.7020347e-12, -1.1712592e-09, 1.6401790e-07, -8.6842919e-06, -1.8542465e-06, 8.4485325e-03, 1.6267077e-01 },
216 {-4.0011069e-16, 2.7861423e-13, -6.3388921e-11, 5.8872238e-09, -5.4466522e-07, 1.8037114e-05, 1.0599869e-02, 7.6914696e-02 },
217 {-2.8242609e-15, 2.9234108e-12, -1.1726546e-09, 2.2552115e-07, -2.0059387e-05, 5.0595552e-04, 1.7714932e-02, 2.7271836e-01 },
218 }, .fun = { limit, limit, limit }, },
219 [CIVIDIS] = {{
220 {-9.5484131e-16, 9.6988184e-13, -4.0058766e-10, 8.5743924e-08, -9.9644797e-06, 5.9197908e-04, -1.0361579e-02, 3.3164429e-02 },
221 { 1.2731941e-17, -9.4238449e-15, 2.2808841e-12, -1.1548296e-10, -2.3888913e-08, 3.8986680e-06, 2.5879330e-03, 1.2769733e-01 },
222 { 4.6004608e-16, -5.0686849e-13, 2.2753449e-10, -5.3074099e-08, 6.7196096e-06, -4.4120020e-04, 1.3435551e-02, 2.8293355e-01 },
223 }, .fun = { limit, limit, limit }, },
224 [SOLAR] = {{
225 { 0, 0, 0, 0, 0.000001983938313, -0.0007618323, 0.2, -M_PI_2 },
226 { 0, 0, 0, 0, 0.000001983938313, -0.0007618323, 0.2, -M_PI_2 },
227 { 0, 0, 0, 0, 0.000001983938313, -0.0007618323, 0.2, -M_PI_2 },
228 },
229 .offset = { 0., -9., 9. },
230 .fun = { solarfun, solarfun, solarfun }, },
231 [SPECTRAL] = {{
232 { -1.6820e-15, 1.4982e-12, -5.0442e-10, 8.0490e-08, -6.1903e-06, 1.5821e-04, 6.4359e-03, 6.2887e-01 },
233 { 1.2526e-15, -1.2203e-12, 4.7013e-10, -8.9360e-08, 8.3839e-06, -3.6642e-04, 1.4784e-02, -9.8075e-03 },
234 { 1.4755e-15, -1.6765e-12, 7.3188e-10, -1.5522e-07, 1.6406e-05, -7.7883e-04, 1.4502e-02, 2.1597e-01 },
235 }, .fun = { limit, limit, limit }, },
236 [COOL] = {{
237 { 0, 0, 0, 0, 0, 0, 1./256, 0 },
238 { 0, 0, 0, 0, 0, 0, 1./256, 0 },
239 { 0, 0, 0, 0, 0, 0, 1./256, 0 },
240 },
241 .offset = { 0., 0., 0 },
242 .yuv = 1,
243 .fun = { coolfunu, limit, coolfunv }, },
244 [HEAT] = {{
245 { 0, 0, 0, 0, 0, 0, 1./256, 0 },
246 { 0, 0, 0, 0, 0, 0, 1./256, 0 },
247 { 0, 0, 0, 0, 0, 0, 1./256, 0 },
248 },
249 .offset = { 0., 0., 0 },
250 .yuv = 1,
251 .fun = { heatfunu, limit, heatfunv }, },
252 [FIERY] = {{
253 { 0, 0, 0, 0, 0, 0, 1./256, 0 },
254 { 0, 0, 0, 0, 0, 0, 1./256, 0 },
255 { 0, 0, 0, 0, 0, 0, 1./256, 0 },
256 },
257 .offset = { 0., 0., 0 },
258 .yuv = 1,
259 .fun = { fieryfunu, limit, fieryfunv }, },
260 [BLUES] = {{
261 { 0, 0, 0, 0, 0, 0, 1./256, 0 },
262 { 0, 0, 0, 0, 0, 0, 1./256, 0 },
263 { 0, 0, 0, 0, 0, 0, 1./256, 0 },
264 },
265 .offset = { 0., 0., 0 },
266 .yuv = 1,
267 .fun = { fieryfunv, limit, fieryfunu }, },
268 [GREEN] = {{
269 { 0, 0, 0, 0, 0, 0, 1./256, 0 },
270 { 0, 0, 0, 0, 0, 0, 1./256, 0 },
271 { 0, 0, 0, 0, 0, 0, 1./256, 0 },
272 },
273 .offset = { 0., 0., 0 },
274 .yuv = 1,
275 .fun = { fieryfunv, limit, fieryfunv }, },
276 [HELIX] = {{
277 { 0, 0, 0, 0, 0, 0, 1./256, 0 },
278 { 0, 0, 0, 0, 0, 0, 1./256, 0 },
279 { 0, 0, 0, 0, 0, 0, 1./256, 0 },
280 },
281 .offset = { 0., 0., 0 },
282 .yuv = 1,
283 .fun = { helixfunu, limit, helixfunv }, },
284};
285
310
311typedef struct PseudoColorContext {
312 const AVClass *class;
314 float opacity;
315 int max;
316 int index;
318 int color;
319 int linesize[4];
320 int width[4], height[4];
324 float lut[4][256*256];
325
326 void (*filter[4])(int max, int width, int height,
327 const uint8_t *index, const uint8_t *src,
328 uint8_t *dst,
329 ptrdiff_t ilinesize,
330 ptrdiff_t slinesize,
331 ptrdiff_t dlinesize,
332 float *lut,
333 float opacity);
335
336#define OFFSET(x) offsetof(PseudoColorContext, x)
337#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
338
340 { "c0", "set component #0 expression", OFFSET(comp_expr_str[0]), AV_OPT_TYPE_STRING, {.str="val"}, .flags = FLAGS },
341 { "c1", "set component #1 expression", OFFSET(comp_expr_str[1]), AV_OPT_TYPE_STRING, {.str="val"}, .flags = FLAGS },
342 { "c2", "set component #2 expression", OFFSET(comp_expr_str[2]), AV_OPT_TYPE_STRING, {.str="val"}, .flags = FLAGS },
343 { "c3", "set component #3 expression", OFFSET(comp_expr_str[3]), AV_OPT_TYPE_STRING, {.str="val"}, .flags = FLAGS },
344 { "index", "set component as base", OFFSET(index), AV_OPT_TYPE_INT, {.i64=0}, 0, 3, .flags = FLAGS },
345 { "i", "set component as base", OFFSET(index), AV_OPT_TYPE_INT, {.i64=0}, 0, 3, .flags = FLAGS },
346 { "preset", "set preset", OFFSET(preset), AV_OPT_TYPE_INT, {.i64=-1},-1, NB_PRESETS-1, .flags = FLAGS, .unit = "preset" },
347 { "p", "set preset", OFFSET(preset), AV_OPT_TYPE_INT, {.i64=-1},-1, NB_PRESETS-1, .flags = FLAGS, .unit = "preset" },
348 { "none", NULL, 0, AV_OPT_TYPE_CONST, {.i64=-1}, .flags = FLAGS, .unit = "preset" },
349 { "magma", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_MAGMA}, .flags = FLAGS, .unit = "preset" },
350 { "inferno", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_INFERNO}, .flags = FLAGS, .unit = "preset" },
351 { "plasma", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_PLASMA}, .flags = FLAGS, .unit = "preset" },
352 { "viridis", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_VIRIDIS}, .flags = FLAGS, .unit = "preset" },
353 { "turbo", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_TURBO}, .flags = FLAGS, .unit = "preset" },
354 { "cividis", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_CIVIDIS}, .flags = FLAGS, .unit = "preset" },
355 { "range1", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_RANGE1}, .flags = FLAGS, .unit = "preset" },
356 { "range2", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_RANGE2}, .flags = FLAGS, .unit = "preset" },
357 { "shadows", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_SHADOWS}, .flags = FLAGS, .unit = "preset" },
358 { "highlights", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_HIGHLIGHTS},.flags=FLAGS, .unit = "preset" },
359 { "solar", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_SOLAR}, .flags=FLAGS, .unit = "preset" },
360 { "nominal", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_NOMINAL}, .flags=FLAGS, .unit = "preset" },
361 { "preferred", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_PREFERRED},.flags=FLAGS, .unit = "preset" },
362 { "total", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_TOTAL}, .flags=FLAGS, .unit = "preset" },
363 { "spectral", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_SPECTRAL},.flags = FLAGS, .unit = "preset" },
364 { "cool", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_COOL}, .flags = FLAGS, .unit = "preset" },
365 { "heat", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_HEAT}, .flags = FLAGS, .unit = "preset" },
366 { "fiery", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_FIERY}, .flags = FLAGS, .unit = "preset" },
367 { "blues", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_BLUES}, .flags = FLAGS, .unit = "preset" },
368 { "green", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_GREEN}, .flags = FLAGS, .unit = "preset" },
369 { "helix", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_HELIX}, .flags = FLAGS, .unit = "preset" },
370 { "opacity", "set pseudocolor opacity",OFFSET(opacity), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 1, .flags = FLAGS },
371 { NULL }
372};
373
402
403static inline float lerpf(float v0, float v1, float f)
404{
405 return v0 + (v1 - v0) * f;
406}
407
408#define PCLIP(v, max, dst, src, x) \
409 if (v >= 0 && v <= max) { \
410 dst[x] = lerpf(src[x], v, opacity);\
411 } else { \
412 dst[x] = src[x]; \
413 }
414
415static void pseudocolor_filter(int max, int width, int height,
416 const uint8_t *index,
417 const uint8_t *src,
418 uint8_t *dst,
419 ptrdiff_t ilinesize,
420 ptrdiff_t slinesize,
421 ptrdiff_t dlinesize,
422 float *lut,
423 float opacity)
424{
425 int x, y;
426
427 for (y = 0; y < height; y++) {
428 for (x = 0; x < width; x++) {
429 int v = lut[index[x]];
430
431 PCLIP(v, max, dst, src, x);
432 }
433 index += ilinesize;
434 src += slinesize;
435 dst += dlinesize;
436 }
437}
438
439static void pseudocolor_filter_11(int max, int width, int height,
440 const uint8_t *index,
441 const uint8_t *src,
442 uint8_t *dst,
443 ptrdiff_t ilinesize,
444 ptrdiff_t slinesize,
445 ptrdiff_t dlinesize,
446 float *lut,
447 float opacity)
448{
449 int x, y;
450
451 for (y = 0; y < height; y++) {
452 for (x = 0; x < width; x++) {
453 int v = lut[index[(y << 1) * ilinesize + (x << 1)]];
454
455 PCLIP(v, max, dst, src, x);
456 }
457 src += slinesize;
458 dst += dlinesize;
459 }
460}
461
462static void pseudocolor_filter_11d(int max, int width, int height,
463 const uint8_t *index,
464 const uint8_t *src,
465 uint8_t *dst,
466 ptrdiff_t ilinesize,
467 ptrdiff_t slinesize,
468 ptrdiff_t dlinesize,
469 float *lut,
470 float opacity)
471{
472 int x, y;
473
474 for (y = 0; y < height; y++) {
475 for (x = 0; x < width; x++) {
476 int v = lut[index[(y >> 1) * ilinesize + (x >> 1)]];
477
478 PCLIP(v, max, dst, src, x);
479 }
480 src += slinesize;
481 dst += dlinesize;
482 }
483}
484
485static void pseudocolor_filter_10(int max, int width, int height,
486 const uint8_t *index,
487 const uint8_t *src,
488 uint8_t *dst,
489 ptrdiff_t ilinesize,
490 ptrdiff_t slinesize,
491 ptrdiff_t dlinesize,
492 float *lut,
493 float opacity)
494{
495 int x, y;
496
497 for (y = 0; y < height; y++) {
498 for (x = 0; x < width; x++) {
499 int v = lut[index[x << 1]];
500
501 PCLIP(v, max, dst, src, x);
502 }
503 index += ilinesize;
504 src += slinesize;
505 dst += dlinesize;
506 }
507}
508
509static void pseudocolor_filter_10d(int max, int width, int height,
510 const uint8_t *index,
511 const uint8_t *src,
512 uint8_t *dst,
513 ptrdiff_t ilinesize,
514 ptrdiff_t slinesize,
515 ptrdiff_t dlinesize,
516 float *lut,
517 float opacity)
518{
519 int x, y;
520
521 for (y = 0; y < height; y++) {
522 for (x = 0; x < width; x++) {
523 int v = lut[index[x >> 1]];
524
525 PCLIP(v, max, dst, src, x);
526 }
527 index += ilinesize;
528 src += slinesize;
529 dst += dlinesize;
530 }
531}
532
533static void pseudocolor_filter_16(int max, int width, int height,
534 const uint8_t *iindex,
535 const uint8_t *ssrc,
536 uint8_t *ddst,
537 ptrdiff_t ilinesize,
538 ptrdiff_t slinesize,
539 ptrdiff_t dlinesize,
540 float *lut,
541 float opacity)
542{
543 const uint16_t *index = (const uint16_t *)iindex;
544 const uint16_t *src = (const uint16_t *)ssrc;
545 uint16_t *dst = (uint16_t *)ddst;
546 int x, y;
547
548 for (y = 0; y < height; y++) {
549 for (x = 0; x < width; x++) {
550 int v = lut[index[x]];
551
552 PCLIP(v, max, dst, src, x);
553 }
554 index += ilinesize / 2;
555 src += slinesize / 2;
556 dst += dlinesize / 2;
557 }
558}
559
560static void pseudocolor_filter_16_10(int max, int width, int height,
561 const uint8_t *iindex,
562 const uint8_t *ssrc,
563 uint8_t *ddst,
564 ptrdiff_t ilinesize,
565 ptrdiff_t slinesize,
566 ptrdiff_t dlinesize,
567 float *lut,
568 float opacity)
569{
570 const uint16_t *index = (const uint16_t *)iindex;
571 const uint16_t *src = (const uint16_t *)ssrc;
572 uint16_t *dst = (uint16_t *)ddst;
573 int x, y;
574
575 for (y = 0; y < height; y++) {
576 for (x = 0; x < width; x++) {
577 int v = lut[index[x << 1]];
578
579 PCLIP(v, max, dst, src, x);
580 }
581 index += ilinesize / 2;
582 src += slinesize / 2;
583 dst += dlinesize / 2;
584 }
585}
586
587static void pseudocolor_filter_16_10d(int max, int width, int height,
588 const uint8_t *iindex,
589 const uint8_t *ssrc,
590 uint8_t *ddst,
591 ptrdiff_t ilinesize,
592 ptrdiff_t slinesize,
593 ptrdiff_t dlinesize,
594 float *lut,
595 float opacity)
596{
597 const uint16_t *index = (const uint16_t *)iindex;
598 const uint16_t *src = (const uint16_t *)ssrc;
599 uint16_t *dst = (uint16_t *)ddst;
600 int x, y;
601
602 for (y = 0; y < height; y++) {
603 for (x = 0; x < width; x++) {
604 int v = lut[index[x >> 1]];
605
606 PCLIP(v, max, dst, src, x);
607 }
608 index += ilinesize / 2;
609 src += slinesize / 2;
610 dst += dlinesize / 2;
611 }
612}
613
614static void pseudocolor_filter_16_11(int max, int width, int height,
615 const uint8_t *iindex,
616 const uint8_t *ssrc,
617 uint8_t *ddst,
618 ptrdiff_t ilinesize,
619 ptrdiff_t slinesize,
620 ptrdiff_t dlinesize,
621 float *lut,
622 float opacity)
623{
624 const uint16_t *index = (const uint16_t *)iindex;
625 const uint16_t *src = (const uint16_t *)ssrc;
626 uint16_t *dst = (uint16_t *)ddst;
627 int x, y;
628
629 ilinesize /= 2;
630 dlinesize /= 2;
631 slinesize /= 2;
632
633 for (y = 0; y < height; y++) {
634 for (x = 0; x < width; x++) {
635 int v = lut[index[(y << 1) * ilinesize + (x << 1)]];
636
637 PCLIP(v, max, dst, src, x);
638 }
639 src += slinesize;
640 dst += dlinesize;
641 }
642}
643
644static void pseudocolor_filter_16_11d(int max, int width, int height,
645 const uint8_t *iindex,
646 const uint8_t *ssrc,
647 uint8_t *ddst,
648 ptrdiff_t ilinesize,
649 ptrdiff_t slinesize,
650 ptrdiff_t dlinesize,
651 float *lut,
652 float opacity)
653{
654 const uint16_t *index = (const uint16_t *)iindex;
655 const uint16_t *src = (const uint16_t *)ssrc;
656 uint16_t *dst = (uint16_t *)ddst;
657 int x, y;
658
659 ilinesize /= 2;
660 dlinesize /= 2;
661 slinesize /= 2;
662
663 for (y = 0; y < height; y++) {
664 for (x = 0; x < width; x++) {
665 int v = lut[index[(y >> 1) * ilinesize + (x >> 1)]];
666
667 PCLIP(v, max, dst, src, x);
668 }
669 src += slinesize;
670 dst += dlinesize;
671 }
672}
673
674#define RGB_TO_Y_BT709(r, g, b) \
675((0.21260*219.0/255.0) * (r) + (0.71520*219.0/255.0) * (g) + \
676 (0.07220*219.0/255.0) * (b))
677
678#define RGB_TO_U_BT709(r1, g1, b1, max) \
679(-(0.11457*224.0/255.0) * r1 - (0.38543*224.0/255.0) * g1 + \
680 (0.50000*224.0/255.0) * b1 + max * 0.5)
681
682#define RGB_TO_V_BT709(r1, g1, b1, max) \
683((0.50000*224.0/255.0) * r1 - (0.45415*224.0/255.0) * g1 - \
684 (0.04585*224.0/255.0) * b1 + max * 0.5)
685
686#define Wr 0.2126
687#define Wb 0.0722
688#define Wg (1 - Wr - Wb)
689#define Umax 0.436
690#define Vmax 0.615
691
692#define YUV_BT709_TO_R(y, u, v, max) \
693 ((y + v * (1 - Wr) / Vmax) * max)
694#define YUV_BT709_TO_G(y, u, v, max) \
695 ((y - (u * Wb * (1 - Wb) / (Umax * Wg)) - (v * Wr * (1 - Wr) / (Vmax * Wg))) * max)
696#define YUV_BT709_TO_B(y, u, v, max) \
697 ((y + u * (1 - Wb) / Umax) * max)
698
699static double poly_eval(const double *const poly, double x, curve_fun fun)
700{
701 double res = 0.;
702
703 for (int i = 0; i < 8; i++) {
704 res += pow(x, i) * poly[7-i];
705 }
706
707 return fun(res);
708}
709
710static int config_input(AVFilterLink *inlink)
711{
712 AVFilterContext *ctx = inlink->dst;
713 PseudoColorContext *s = ctx->priv;
715 int depth, ret, hsub, vsub, color, rgb;
716
717 rgb = desc->flags & AV_PIX_FMT_FLAG_RGB;
718 depth = desc->comp[0].depth;
719 s->max = (1 << depth) - 1;
720 s->nb_planes = av_pix_fmt_count_planes(inlink->format);
721
722 if (s->index >= s->nb_planes) {
723 av_log(ctx, AV_LOG_ERROR, "index out of allowed range\n");
724 return AVERROR(EINVAL);
725 }
726
727 if ((ret = av_image_fill_linesizes(s->linesize, inlink->format, inlink->w)) < 0)
728 return ret;
729
730 hsub = desc->log2_chroma_w;
731 vsub = desc->log2_chroma_h;
732 s->height[1] = s->height[2] = AV_CEIL_RSHIFT(inlink->h, vsub);
733 s->height[0] = s->height[3] = inlink->h;
734 s->width[1] = s->width[2] = AV_CEIL_RSHIFT(inlink->w, hsub);
735 s->width[0] = s->width[3] = inlink->w;
736
737 s->var_values[VAR_W] = inlink->w;
738 s->var_values[VAR_H] = inlink->h;
739
740 s->var_values[VAR_YMIN] = 16 * (1 << (depth - 8));
741 s->var_values[VAR_UMIN] = 16 * (1 << (depth - 8));
742 s->var_values[VAR_VMIN] = 16 * (1 << (depth - 8));
743 s->var_values[VAR_AMIN] = 0;
744 s->var_values[VAR_YMAX] = 235 * (1 << (depth - 8));
745 s->var_values[VAR_UMAX] = 240 * (1 << (depth - 8));
746 s->var_values[VAR_VMAX] = 240 * (1 << (depth - 8));
747 s->var_values[VAR_AMAX] = s->max;
748
749 for (color = 0; color < s->nb_planes && s->preset < 0; color++) {
750 double res;
751 int val;
752
753 /* create the parsed expression */
754 av_expr_free(s->comp_expr[color]);
755 s->comp_expr[color] = NULL;
756 ret = av_expr_parse(&s->comp_expr[color], s->comp_expr_str[color],
757 var_names, NULL, NULL, NULL, NULL, 0, ctx);
758 if (ret < 0) {
760 "Error when parsing the expression '%s' for the component %d and color %d.\n",
761 s->comp_expr_str[color], color, color);
762 return AVERROR(EINVAL);
763 }
764
765 /* compute the lut */
766 for (val = 0; val < FF_ARRAY_ELEMS(s->lut[color]); val++) {
767 s->var_values[VAR_VAL] = val;
768
769 res = av_expr_eval(s->comp_expr[color], s->var_values, s);
770 if (isnan(res)) {
772 "Error when evaluating the expression '%s' for the value %d for the component %d.\n",
773 s->comp_expr_str[color], val, color);
774 return AVERROR(EINVAL);
775 }
776 s->lut[color][val] = res;
777 }
778 }
779
780 if (s->preset >= 0) {
781 int nb_segments = presets[s->preset].nb_segments;
782
783 for (int seg = 0; seg < nb_segments; seg++) {
784 AVRational rstart = presets[s->preset].ranges[seg].start;
785 AVRational rend = presets[s->preset].ranges[seg].end;
786 int start = av_rescale_rnd(s->max + 1, rstart.num, rstart.den, AV_ROUND_UP);
787 int end = av_rescale_rnd(s->max + 1, rend.num, rend.den, AV_ROUND_UP);
788
789 for (int i = start; i < end; i++) {
790 if (!presets[s->preset].curves) {
791 const Fill fill = presets[s->preset].fills[seg];
792 double r, g, b, a;
793
794 g = fill.fill[1];
795 b = fill.fill[2];
796 r = fill.fill[0];
797 a = fill.fill[3];
798
799 if (g >= 0.f && b >= 0.f && r >= 0.f) {
800 g *= s->max;
801 b *= s->max;
802 r *= s->max;
803
804 if (!rgb) {
805 double y = RGB_TO_Y_BT709(r, g, b);
806 double u = RGB_TO_U_BT709(r, g, b, s->max);
807 double v = RGB_TO_V_BT709(r, g, b, s->max);
808
809 r = v;
810 g = y;
811 b = u;
812 }
813 }
814
815 s->lut[0][i] = g;
816 s->lut[1][i] = b;
817 s->lut[2][i] = r;
818 s->lut[3][i] = a * s->max;
819 } else {
820 const Curve curve = presets[s->preset].curves[seg];
821 const double lf = i / (double)s->max * 256.;
822 double r, g, b;
823
824 g = poly_eval(curve.coef[1], lf + curve.offset[1], curve.fun[1]);
825 b = poly_eval(curve.coef[2], lf + curve.offset[2], curve.fun[2]);
826 r = poly_eval(curve.coef[0], lf + curve.offset[0], curve.fun[0]);
827
828 if (!curve.yuv || !rgb) {
829 g *= s->max;
830 b *= s->max;
831 r *= s->max;
832 }
833
834 if (!rgb && !curve.yuv) {
835 double y = RGB_TO_Y_BT709(r, g, b);
836 double u = RGB_TO_U_BT709(r, g, b, s->max);
837 double v = RGB_TO_V_BT709(r, g, b, s->max);
838
839 r = v;
840 g = y;
841 b = u;
842 } else if (rgb && curve.yuv) {
843 double y = g;
844 double u = b - 0.5;
845 double v = r - 0.5;
846
847 r = av_clipd(YUV_BT709_TO_R(y, u, v, s->max), 0, s->max);
848 g = av_clipd(YUV_BT709_TO_G(y, u, v, s->max), 0, s->max);
849 b = av_clipd(YUV_BT709_TO_B(y, u, v, s->max), 0, s->max);
850 }
851
852 s->lut[0][i] = g;
853 s->lut[1][i] = b;
854 s->lut[2][i] = r;
855 s->lut[3][i] = 1.f * s->max;
856 }
857 }
858 }
859 }
860
861 switch (inlink->format) {
864 case AV_PIX_FMT_GBRP:
865 case AV_PIX_FMT_GBRAP:
866 case AV_PIX_FMT_GRAY8:
867 s->filter[0] = s->filter[1] = s->filter[2] = s->filter[3] = pseudocolor_filter;
868 break;
871 switch (s->index) {
872 case 0:
873 case 3:
874 s->filter[0] = s->filter[3] = pseudocolor_filter;
875 s->filter[1] = s->filter[2] = pseudocolor_filter_11;
876 break;
877 case 1:
878 case 2:
879 s->filter[0] = s->filter[3] = pseudocolor_filter_11d;
880 s->filter[1] = s->filter[2] = pseudocolor_filter;
881 break;
882 }
883 break;
886 switch (s->index) {
887 case 0:
888 case 3:
889 s->filter[0] = s->filter[3] = pseudocolor_filter;
890 s->filter[1] = s->filter[2] = pseudocolor_filter_10;
891 break;
892 case 1:
893 case 2:
894 s->filter[0] = s->filter[3] = pseudocolor_filter_10d;
895 s->filter[1] = s->filter[2] = pseudocolor_filter;
896 break;
897 }
898 break;
908 case AV_PIX_FMT_GBRP9:
917 case AV_PIX_FMT_GRAY9:
922 s->filter[0] = s->filter[1] = s->filter[2] = s->filter[3] = pseudocolor_filter_16;
923 break;
933 switch (s->index) {
934 case 0:
935 case 3:
936 s->filter[0] = s->filter[3] = pseudocolor_filter_16;
937 s->filter[1] = s->filter[2] = pseudocolor_filter_16_10;
938 break;
939 case 1:
940 case 2:
941 s->filter[0] = s->filter[3] = pseudocolor_filter_16_10d;
942 s->filter[1] = s->filter[2] = pseudocolor_filter_16;
943 break;
944 }
945 break;
954 switch (s->index) {
955 case 0:
956 case 3:
957 s->filter[0] = s->filter[3] = pseudocolor_filter_16;
958 s->filter[1] = s->filter[2] = pseudocolor_filter_16_11;
959 break;
960 case 1:
961 case 2:
962 s->filter[0] = s->filter[3] = pseudocolor_filter_16_11d;
963 s->filter[1] = s->filter[2] = pseudocolor_filter_16;
964 break;
965 }
966 break;
967 }
968
969 return 0;
970}
971
972typedef struct ThreadData {
973 AVFrame *in, *out;
974} ThreadData;
975
976static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
977{
978 PseudoColorContext *s = ctx->priv;
979 ThreadData *td = arg;
980 AVFrame *in = td->in;
981 AVFrame *out = td->out;
982
983 for (int plane = 0; plane < s->nb_planes; plane++) {
984 const int slice_start = ff_slice_pos(s->height[plane], jobnr, nb_jobs);
985 const int slice_end = ff_slice_pos(s->height[plane], jobnr + 1, nb_jobs);
986 const int islice_start = ff_slice_pos(s->height[s->index], jobnr, nb_jobs);
987 ptrdiff_t ilinesize = in->linesize[s->index];
988 ptrdiff_t slinesize = in->linesize[plane];
989 ptrdiff_t dlinesize = out->linesize[plane];
990 const uint8_t *index = in->data[s->index] + islice_start * ilinesize;
991 const uint8_t *src = in->data[plane] + slice_start * slinesize;
992 uint8_t *dst = out->data[plane] + slice_start * dlinesize;
993
994 s->filter[plane](s->max, s->width[plane], slice_end - slice_start,
995 index, src, dst, ilinesize, slinesize,
996 dlinesize, s->lut[plane], s->opacity);
997 }
998
999 return 0;
1000}
1001
1002static int filter_frame(AVFilterLink *inlink, AVFrame *in)
1003{
1004 AVFilterContext *ctx = inlink->dst;
1005 PseudoColorContext *s = ctx->priv;
1006 AVFilterLink *outlink = ctx->outputs[0];
1007 ThreadData td;
1008 AVFrame *out;
1009
1010 out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
1011 if (!out) {
1012 av_frame_free(&in);
1013 return AVERROR(ENOMEM);
1014 }
1016
1017 td.out = out, td.in = in;
1019 FFMIN(s->height[1], ff_filter_get_nb_threads(ctx)));
1020
1021 av_frame_free(&in);
1022 return ff_filter_frame(outlink, out);
1023}
1024
1025static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
1026 char *res, int res_len, int flags)
1027{
1028 int ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags);
1029
1030 if (ret < 0)
1031 return ret;
1032
1033 return config_input(ctx->inputs[0]);
1034}
1035
1036static const AVFilterPad inputs[] = {
1037 {
1038 .name = "default",
1039 .type = AVMEDIA_TYPE_VIDEO,
1040 .filter_frame = filter_frame,
1041 .config_props = config_input,
1042 },
1043};
1044
1046{
1047 PseudoColorContext *s = ctx->priv;
1048 int i;
1049
1050 for (i = 0; i < 4; i++) {
1051 av_expr_free(s->comp_expr[i]);
1052 s->comp_expr[i] = NULL;
1053 }
1054}
1055
1057
1059 .p.name = "pseudocolor",
1060 .p.description = NULL_IF_CONFIG_SMALL("Make pseudocolored video frames."),
1061 .p.priv_class = &pseudocolor_class,
1063 .priv_size = sizeof(PseudoColorContext),
1064 .uninit = uninit,
1068 .process_command = process_command,
1069};
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
static double val(void *priv, double ch)
Definition aeval.c:77
static const AVFilterPad inputs[]
Definition af_aap.c:299
static int config_input(AVFilterLink *inlink)
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
@ NB_CURVES
Definition af_afade.c:62
const FFFilter ff_vf_pseudocolor
@ VIRIDIS
@ MAGMA
@ COOL
@ PLASMA
@ CIVIDIS
@ FIERY
@ VAR_H
Definition avfilter.c:565
@ VAR_W
Definition avfilter.c:564
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition avfilter.c:1068
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:906
int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg, int *ret, int nb_jobs)
Definition avfilter.c:1696
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition avfilter.c:846
Main libavfilter public API header.
#define flags(name, subs,...)
Definition cbs_h264.c:74
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define f(width, name)
Definition cbs_vp8.c:236
#define s(width, name)
Definition cbs_vp9.c:198
#define FLAGS
Definition cmdutils.c:598
common internal and external API header
#define av_clipd
Definition common.h:148
#define AV_CEIL_RSHIFT(a, b)
Definition common.h:60
#define NULL
Definition coverity.c:32
#define max(a, b)
static int filter_frame(DBEDecodeContext *s, AVFrame *frame)
Definition dolby_e.c:1067
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
Definition eval.c:368
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
Evaluate a previously parsed expression.
Definition eval.c:824
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:735
simple arithmetic expression evaluator
@ VAR_VAL
Definition f_drawgraph.c:91
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition opt.h:298
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
@ AV_OPT_TYPE_FLOAT
Underlying C type is float.
Definition opt.h:270
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
Definition opt.h:275
#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:196
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Definition avfilter.h:166
#define AVERROR(e)
Definition error.h:45
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition frame.c:64
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition frame.c:599
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd)
Rescale a 64-bit integer with specified rounding.
Definition mathematics.c:58
@ AV_ROUND_UP
Round toward +infinity.
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
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:90
int a
misc image utilities
#define r
Definition input.c:42
#define b
Definition input.c:43
static av_cold void uninit(AVBitStreamFilterContext *ctx)
#define u(width, name, range_min, range_max)
Definition cbs_apv.c:68
const char * arg
Definition jacosubdec.c:65
#define FILTER_INPUTS(array)
Definition filters.h:264
#define FILTER_OUTPUTS(array)
Definition filters.h:265
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:763
#define FILTER_PIXFMTS_ARRAY(array)
Definition filters.h:244
#define AVFILTER_DEFINE_CLASS(fname)
Definition filters.h:478
Macro definitions for various function/variable attributes.
#define av_cold
Definition attributes.h:117
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:88
static enum AVPixelFormat pix_fmts[]
Definition libkvazaar.c:296
#define isnan(x)
Definition libm.h:342
const char * desc
Definition libsvtav1.c:83
#define FFMIN(a, b)
Definition macros.h:49
#define M_PI_2
Definition mathematics.h:73
#define M_PI
Definition mathematics.h:67
static int slice_end(AVCodecContext *avctx, AVFrame *pict, int *got_output)
Handle slice ends.
Definition mpeg12dec.c:1697
var_name
Definition noise.c:46
@ VAR_VARS_NB
Definition noise.c:59
static const char *const var_names[]
Definition noise.c:30
AVOptions.
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3500
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3460
#define AV_PIX_FMT_FLAG_RGB
The pixel format contains RGB-like data (as opposed to YUV/grayscale).
Definition pixdesc.h:136
#define AV_PIX_FMT_GBRAP12
Definition pixfmt.h:569
#define AV_PIX_FMT_YUV420P16
Definition pixfmt.h:556
#define AV_PIX_FMT_YUV444P12
Definition pixfmt.h:552
#define AV_PIX_FMT_YUV444P9
Definition pixfmt.h:544
#define AV_PIX_FMT_YUV420P10
Definition pixfmt.h:545
#define AV_PIX_FMT_GRAY9
Definition pixfmt.h:524
#define AV_PIX_FMT_GBRAP16
Definition pixfmt.h:571
#define AV_PIX_FMT_GBRP9
Definition pixfmt.h:563
#define AV_PIX_FMT_YUV422P9
Definition pixfmt.h:543
#define AV_PIX_FMT_YUVA444P10
Definition pixfmt.h:598
#define AV_PIX_FMT_YUVA420P16
Definition pixfmt.h:601
#define AV_PIX_FMT_YUV420P12
Definition pixfmt.h:549
#define AV_PIX_FMT_YUVA420P10
Definition pixfmt.h:596
#define AV_PIX_FMT_YUVA422P9
Definition pixfmt.h:594
#define AV_PIX_FMT_YUV422P12
Definition pixfmt.h:550
#define AV_PIX_FMT_GBRAP14
Definition pixfmt.h:570
#define AV_PIX_FMT_GBRP10
Definition pixfmt.h:564
#define AV_PIX_FMT_YUV422P10
Definition pixfmt.h:546
#define AV_PIX_FMT_GRAY12
Definition pixfmt.h:526
#define AV_PIX_FMT_GBRP12
Definition pixfmt.h:565
#define AV_PIX_FMT_YUV420P9
Definition pixfmt.h:542
#define AV_PIX_FMT_YUVA420P9
Definition pixfmt.h:593
#define AV_PIX_FMT_YUVA422P10
Definition pixfmt.h:597
#define AV_PIX_FMT_YUV420P14
Definition pixfmt.h:553
AVPixelFormat
Pixel format.
Definition pixfmt.h:71
@ AV_PIX_FMT_NONE
Definition pixfmt.h:72
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition pixfmt.h:73
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition pixfmt.h:77
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition pixfmt.h:81
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition pixfmt.h:108
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition pixfmt.h:78
@ AV_PIX_FMT_YUVA444P
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
Definition pixfmt.h:174
@ AV_PIX_FMT_GBRAP
planar GBRA 4:4:4:4 32bpp
Definition pixfmt.h:212
@ AV_PIX_FMT_YUVA422P
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
Definition pixfmt.h:173
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
Definition pixfmt.h:165
#define AV_PIX_FMT_YUVA422P12
Definition pixfmt.h:599
#define AV_PIX_FMT_YUV422P14
Definition pixfmt.h:554
#define AV_PIX_FMT_GRAY10
Definition pixfmt.h:525
#define AV_PIX_FMT_GRAY14
Definition pixfmt.h:527
#define AV_PIX_FMT_YUV422P16
Definition pixfmt.h:557
#define AV_PIX_FMT_GRAY16
Definition pixfmt.h:528
#define AV_PIX_FMT_GBRAP10
Definition pixfmt.h:568
#define AV_PIX_FMT_YUVA444P16
Definition pixfmt.h:603
#define AV_PIX_FMT_YUVA422P16
Definition pixfmt.h:602
#define AV_PIX_FMT_GBRP16
Definition pixfmt.h:567
#define AV_PIX_FMT_YUV444P14
Definition pixfmt.h:555
#define AV_PIX_FMT_YUVA444P9
Definition pixfmt.h:595
#define AV_PIX_FMT_GBRP14
Definition pixfmt.h:566
#define AV_PIX_FMT_YUVA444P12
Definition pixfmt.h:600
#define AV_PIX_FMT_YUV444P16
Definition pixfmt.h:558
#define AV_PIX_FMT_YUV444P10
Definition pixfmt.h:548
#define FF_ARRAY_ELEMS(a)
Describe the class of an AVClass context structure.
Definition log.h:76
Definition eval.c:171
An instance of a filter.
Definition avfilter.h:273
A filter pad used for either input or output.
Definition filters.h:40
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition frame.h:493
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Definition frame.h:517
AVOption.
Definition opt.h:428
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition pixdesc.h:69
Rational number (pair of numerator and denominator).
Definition rational.h:58
int num
Numerator.
Definition rational.h:59
int den
Denominator.
Definition rational.h:60
double coef[3][8]
curve_fun fun[3]
double offset[3]
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)
AVRational start
AVRational end
Used for passing data between threads.
Definition dsddec.c:71
AVFrame * out
Definition rpzaenc.c:60
#define av_log(a,...)
#define src
Definition vp8dsp.c:248
static FILE * out
Definition movenc.c:55
static AVFormatContext * ctx
Definition movenc.c:49
#define height
Definition dsp.h:89
#define width
Definition dsp.h:89
static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
const char * g
Definition vf_curves.c:128
preset
Definition vf_curves.c:47
@ NB_PRESETS
Definition vf_curves.c:59
#define GREEN
#define BLUES
static void hsub(htype *dst, const htype *src, int bins)
Definition vf_median.c:74
static double coolfunu(double x)
static const Range total_range[]
@ VAR_VMAX
@ VAR_UMIN
@ VAR_YMAX
@ VAR_YMIN
@ VAR_AMAX
@ VAR_VMIN
@ VAR_VARS_NB
@ VAR_AMIN
@ VAR_UMAX
static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
#define PCLIP(v, max, dst, src, x)
static const AVOption pseudocolor_options[]
#define RGB_TO_Y_BT709(r, g, b)
static double heatfunv(double x)
#define YUV_BT709_TO_B(y, u, v, max)
static double poly_eval(const double *const poly, double x, curve_fun fun)
static const Range shadows_range[]
#define RGB_TO_U_BT709(r1, g1, b1, max)
static const Range nominal_range[]
static double helixfunu(double x)
static double helixfunv(double x)
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 const Range preferred_range[]
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)
static double fieryfunv(double x)
static double solarfun(double x)
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 double fieryfunu(double x)
static const Preset presets[]
static const Range highlights_range[]
#define YUV_BT709_TO_R(y, u, v, max)
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
static double limit(double x)
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[]
Curves
@ TURBO
@ INFERNO
@ SOLAR
@ HELIX
@ HEAT
@ SPECTRAL
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 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)
double(* curve_fun)(double x)
#define YUV_BT709_TO_G(y, u, v, max)
static const Range spec1_range[]
static double heatfunu(double x)
static const Fill highlights_fills[]
Presets
@ PRESET_SOLAR
@ PRESET_VIRIDIS
@ PRESET_SPECTRAL
@ PRESET_TURBO
@ PRESET_HELIX
@ PRESET_RANGE1
@ PRESET_COOL
@ PRESET_HEAT
@ PRESET_CIVIDIS
@ PRESET_TOTAL
@ PRESET_PLASMA
@ PRESET_NOMINAL
@ PRESET_MAGMA
@ PRESET_SHADOWS
@ PRESET_HIGHLIGHTS
@ PRESET_RANGE2
@ PRESET_GREEN
@ PRESET_FIERY
@ PRESET_INFERNO
@ PRESET_BLUES
@ PRESET_PREFERRED
static double coolfunv(double x)
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[]
const AVFilterPad ff_video_default_filterpad[1]
An AVFilterPad array whose only entry has name "default" and is of type AVMEDIA_TYPE_VIDEO.
Definition video.c:37
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition video.c:89
static int slice_start(SliceContext *sc, VVCContext *s, VVCFrameContext *fc, const CodedBitstreamUnit *unit, const int is_first_slice)
Definition dec.c:844