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 },
158  [PRESET_RANGE1] = { 3, spec1_range, NULL, spec1_fills },
159  [PRESET_RANGE2] = { 5, spec2_range, NULL, spec2_fills },
160  [PRESET_SHADOWS] = { 2, shadows_range, NULL, shadows_fills },
161  [PRESET_HIGHLIGHTS] = { 3, highlights_range, NULL, highlights_fills },
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];
174  double var_values[VAR_VARS_NB];
175  char *comp_expr_str[4];
176  AVExpr *comp_expr[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;
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) {
597  av_log(ctx, AV_LOG_ERROR,
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)) {
609  av_log(ctx, AV_LOG_ERROR,
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  }
840  av_frame_copy_props(out, in);
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 };
#define RGB_TO_Y_BT709(r, g, b)
static const Range highlights_range[]
#define NULL
Definition: coverity.c:32
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)
#define AV_PIX_FMT_YUVA422P16
Definition: pixfmt.h:442
AVFrame * out
Definition: af_adeclick.c:502
#define AV_PIX_FMT_YUVA422P9
Definition: pixfmt.h:434
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2573
#define OFFSET(x)
This structure describes decoded (raw) audio or video data.
Definition: frame.h:318
static const AVFilterPad outputs[]
AVOption.
Definition: opt.h:248
#define AV_PIX_FMT_YUVA420P10
Definition: pixfmt.h:436
#define AV_PIX_FMT_YUV444P14
Definition: pixfmt.h:409
static void pseudocolor_filter_16_10(int max, int width, int height, const uint8_t *iindex, const uint8_t *ssrc, uint8_t *ddst, ptrdiff_t ilinesize, ptrdiff_t slinesize, ptrdiff_t dlinesize, float *lut, float opacity)
#define AV_PIX_FMT_GBRAP10
Definition: pixfmt.h:419
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)
#define AV_PIX_FMT_YUVA422P10
Definition: pixfmt.h:437
const char * desc
Definition: libsvtav1.c:79
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:71
misc image utilities
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2613
Main libavfilter public API header.
static const Range full_range
const char * g
Definition: vf_curves.c:117
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:168
#define FLAGS
#define AV_PIX_FMT_GBRP10
Definition: pixfmt.h:415
#define RGB_TO_V_BT709(r1, g1, b1, max)
#define RGB_TO_U_BT709(r1, g1, b1, max)
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:36
#define AV_PIX_FMT_GRAY9
Definition: pixfmt.h:379
#define AV_PIX_FMT_YUV420P12
Definition: pixfmt.h:403
#define FF_ARRAY_ELEMS(a)
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
GLfloat v0
Definition: opengl_enc.c:106
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
fg index
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:92
static const Preset presets[]
Macro definitions for various function/variable attributes.
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:287
#define AV_PIX_FMT_GRAY10
Definition: pixfmt.h:380
#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
const char * name
Pad name.
Definition: internal.h:60
#define AV_PIX_FMT_GRAY12
Definition: pixfmt.h:381
static const Fill highlights_fills[]
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:349
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1094
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition: pixfmt.h:101
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:117
uint8_t
#define av_cold
Definition: attributes.h:88
AVOptions.
static const uint32_t color[16+AV_CLASS_CATEGORY_NB]
Definition: log.c:92
#define f(width, name)
Definition: cbs_vp9.c:255
float lut[4][256 *256]
static const Curve curves[]
Definition: eval.c:157
#define u(width, name, range_min, range_max)
Definition: cbs_h2645.c:264
#define AV_PIX_FMT_YUVA420P9
Definition: pixfmt.h:433
#define AV_PIX_FMT_GBRP9
Definition: pixfmt.h:414
#define height
#define AV_PIX_FMT_YUV444P16
Definition: pixfmt.h:412
#define max(a, b)
Definition: cuda_runtime.h:33
#define AV_PIX_FMT_YUV422P12
Definition: pixfmt.h:404
#define AV_PIX_FMT_YUVA420P16
Definition: pixfmt.h:441
static const Range spec1_range[]
#define av_log(a,...)
A filter pad used for either input or output.
Definition: internal.h:54
#define src
Definition: vp8dsp.c:255
#define PCLIP(v, max, dst, src, x)
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
Definition: pixfmt.h:176
static const Fill spec1_fills[]
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
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:588
#define td
Definition: regdef.h:70
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:101
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce then the filter should push the output frames on the output link immediately As an exception to the previous rule if the input frame is enough to produce several output frames then the filter needs output only at least one per link The additional frames can be left buffered in the filter
#define AV_PIX_FMT_FLAG_RGB
The pixel format contains RGB-like data (as opposed to YUV/grayscale).
Definition: pixdesc.h:148
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:204
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:117
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
const char * r
Definition: vf_curves.c:116
void * priv
private data for use by the filter
Definition: avfilter.h:356
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Definition: avfilter.h:117
#define AV_PIX_FMT_YUVA444P16
Definition: pixfmt.h:443
const char * arg
Definition: jacosubdec.c:66
#define AV_PIX_FMT_GBRAP12
Definition: pixfmt.h:420
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:402
AVExpr * comp_expr[4]
static const Fill spec2_fills[]
#define AV_PIX_FMT_GBRAP16
Definition: pixfmt.h:421
static double poly_eval(const double *const poly, double x)
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:70
static const char *const var_names[]
uint64_t flags
Combination of AV_PIX_FMT_FLAG_...
Definition: pixdesc.h:106
#define AV_PIX_FMT_YUV422P9
Definition: pixfmt.h:397
int start
#define b
Definition: input.c:41
const Curve * curves
#define AV_PIX_FMT_GBRP16
Definition: pixfmt.h:418
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:802
#define AV_PIX_FMT_GRAY16
Definition: pixfmt.h:383
#define FFMIN(a, b)
Definition: common.h:105
#define width
typedef void(APIENTRY *FF_PFNGLACTIVETEXTUREPROC)(GLenum texture)
AVFormatContext * ctx
Definition: movenc.c:48
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)
#define s(width, name)
Definition: cbs_vp9.c:257
#define AV_PIX_FMT_YUVA444P10
Definition: pixfmt.h:438
Presets
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)
#define AV_PIX_FMT_YUV444P9
Definition: pixfmt.h:398
static const Fill shadows_fills[]
#define AV_PIX_FMT_GBRP14
Definition: pixfmt.h:417
const Fill * fills
#define AV_PIX_FMT_YUV420P16
Definition: pixfmt.h:410
#define AV_PIX_FMT_YUV420P14
Definition: pixfmt.h:407
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)
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
Definition: eval.c:336
static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Used for passing data between threads.
Definition: dsddec.c:67
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:349
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)
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
Definition: pixfmt.h:177
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
#define AV_PIX_FMT_GRAY14
Definition: pixfmt.h:382
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
const Range * ranges
AVFilter ff_vf_pseudocolor
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
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:399
Describe the class of an AVClass context structure.
Definition: log.h:67
Filter definition.
Definition: avfilter.h:145
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
#define isnan(x)
Definition: libm.h:340
static const SheerTable rgb[2]
static const int factor[16]
Definition: vf_pp7.c:77
const char * name
Filter name.
Definition: avfilter.h:149
#define AV_PIX_FMT_YUV420P9
Definition: pixfmt.h:396
static av_cold void uninit(AVFilterContext *ctx)
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:353
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)
#define AV_PIX_FMT_YUV422P14
Definition: pixfmt.h:408
#define AV_PIX_FMT_GBRP12
Definition: pixfmt.h:416
#define flags(name, subs,...)
Definition: cbs_av1.c:561
AVFilterInternal * internal
An opaque struct for libavfilter internal use.
Definition: avfilter.h:381
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:400
static float lerpf(float v0, float v1, float f)
#define AV_PIX_FMT_YUV444P12
Definition: pixfmt.h:406
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:332
static const AVOption pseudocolor_options[]
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
preset
Definition: vf_curves.c:46
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
static int config_input(AVFilterLink *inlink)
Y , 8bpp.
Definition: pixfmt.h:74
common internal and external API header
float fill[4]
planar GBRA 4:4:4:4 32bpp
Definition: pixfmt.h:215
#define av_clipd
Definition: common.h:173
#define AV_PIX_FMT_YUVA444P9
Definition: pixfmt.h:435
static const Range shadows_range[]
avfilter_execute_func * execute
Definition: internal.h:136
static int query_formats(AVFilterContext *ctx)
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 slice_end(AVCodecContext *avctx, AVFrame *pict)
Handle slice ends.
Definition: mpeg12dec.c:2032
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[]
static enum AVPixelFormat pix_fmts[]
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
Evaluate a previously parsed expression.
Definition: eval.c:766
AVFILTER_DEFINE_CLASS(pseudocolor)
A list of supported formats for one end of a filter link.
Definition: formats.h:65
An instance of a filter.
Definition: avfilter.h:341
FILE * out
Definition: movenc.c:54
double var_values[VAR_VARS_NB]
AVFrame * in
Definition: af_adenorm.c:223
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 const AVFilterPad inputs[]
internal API functions
int nb_segments
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
int depth
Number of bits in the component.
Definition: pixdesc.h:58
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
static double val(void *priv, double ch)
Definition: aeval.c:76
static void hsub(htype *dst, const htype *src, int bins)
Definition: vf_median.c:75
#define AV_PIX_FMT_YUV422P16
Definition: pixfmt.h:411
Curves
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:659
int i
Definition: input.c:407
double coef[3][8]
var_name
Definition: setts_bsf.c:50
simple arithmetic expression evaluator
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:58