FFmpeg
vf_lut.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011 Stefano Sabatini
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 /**
22  * @file
23  * Compute a look-up table for binding the input value to the output
24  * value, and apply it to input video.
25  */
26 
27 #include "libavutil/attributes.h"
28 #include "libavutil/bswap.h"
29 #include "libavutil/common.h"
30 #include "libavutil/eval.h"
31 #include "libavutil/opt.h"
32 #include "libavutil/pixdesc.h"
33 #include "avfilter.h"
34 #include "drawutils.h"
35 #include "formats.h"
36 #include "internal.h"
37 #include "video.h"
38 
39 static const char *const var_names[] = {
40  "w", ///< width of the input video
41  "h", ///< height of the input video
42  "val", ///< input value for the pixel
43  "maxval", ///< max value for the pixel
44  "minval", ///< min value for the pixel
45  "negval", ///< negated value
46  "clipval",
47  NULL
48 };
49 
50 enum var_name {
59 };
60 
61 typedef struct LutContext {
62  const AVClass *class;
63  uint16_t lut[4][256 * 256]; ///< lookup table for each component
64  char *comp_expr_str[4];
66  int hsub, vsub;
68  int is_rgb, is_yuv;
69  int is_planar;
70  int is_16bit;
71  int step;
72  int negate_alpha; /* only used by negate */
73 } LutContext;
74 
75 #define Y 0
76 #define U 1
77 #define V 2
78 #define R 0
79 #define G 1
80 #define B 2
81 #define A 3
82 
83 #define OFFSET(x) offsetof(LutContext, x)
84 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
85 
86 static const AVOption options[] = {
87  { "c0", "set component #0 expression", OFFSET(comp_expr_str[0]), AV_OPT_TYPE_STRING, { .str = "clipval" }, .flags = FLAGS },
88  { "c1", "set component #1 expression", OFFSET(comp_expr_str[1]), AV_OPT_TYPE_STRING, { .str = "clipval" }, .flags = FLAGS },
89  { "c2", "set component #2 expression", OFFSET(comp_expr_str[2]), AV_OPT_TYPE_STRING, { .str = "clipval" }, .flags = FLAGS },
90  { "c3", "set component #3 expression", OFFSET(comp_expr_str[3]), AV_OPT_TYPE_STRING, { .str = "clipval" }, .flags = FLAGS },
91  { "y", "set Y expression", OFFSET(comp_expr_str[Y]), AV_OPT_TYPE_STRING, { .str = "clipval" }, .flags = FLAGS },
92  { "u", "set U expression", OFFSET(comp_expr_str[U]), AV_OPT_TYPE_STRING, { .str = "clipval" }, .flags = FLAGS },
93  { "v", "set V expression", OFFSET(comp_expr_str[V]), AV_OPT_TYPE_STRING, { .str = "clipval" }, .flags = FLAGS },
94  { "r", "set R expression", OFFSET(comp_expr_str[R]), AV_OPT_TYPE_STRING, { .str = "clipval" }, .flags = FLAGS },
95  { "g", "set G expression", OFFSET(comp_expr_str[G]), AV_OPT_TYPE_STRING, { .str = "clipval" }, .flags = FLAGS },
96  { "b", "set B expression", OFFSET(comp_expr_str[B]), AV_OPT_TYPE_STRING, { .str = "clipval" }, .flags = FLAGS },
97  { "a", "set A expression", OFFSET(comp_expr_str[A]), AV_OPT_TYPE_STRING, { .str = "clipval" }, .flags = FLAGS },
98  { NULL }
99 };
100 
102 {
103  LutContext *s = ctx->priv;
104  int i;
105 
106  for (i = 0; i < 4; i++) {
107  av_expr_free(s->comp_expr[i]);
108  s->comp_expr[i] = NULL;
109  av_freep(&s->comp_expr_str[i]);
110  }
111 }
112 
113 #define YUV_FORMATS \
114  AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P, \
115  AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV440P, \
116  AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P, \
117  AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ420P, \
118  AV_PIX_FMT_YUVJ440P, \
119  AV_PIX_FMT_YUV444P9LE, AV_PIX_FMT_YUV422P9LE, AV_PIX_FMT_YUV420P9LE, \
120  AV_PIX_FMT_YUV444P10LE, AV_PIX_FMT_YUV422P10LE, AV_PIX_FMT_YUV420P10LE, AV_PIX_FMT_YUV440P10LE, \
121  AV_PIX_FMT_YUV444P12LE, AV_PIX_FMT_YUV422P12LE, AV_PIX_FMT_YUV420P12LE, AV_PIX_FMT_YUV440P12LE, \
122  AV_PIX_FMT_YUV444P14LE, AV_PIX_FMT_YUV422P14LE, AV_PIX_FMT_YUV420P14LE, \
123  AV_PIX_FMT_YUV444P16LE, AV_PIX_FMT_YUV422P16LE, AV_PIX_FMT_YUV420P16LE, \
124  AV_PIX_FMT_YUVA444P16LE, AV_PIX_FMT_YUVA422P16LE, AV_PIX_FMT_YUVA420P16LE
125 
126 #define RGB_FORMATS \
127  AV_PIX_FMT_ARGB, AV_PIX_FMT_RGBA, \
128  AV_PIX_FMT_ABGR, AV_PIX_FMT_BGRA, \
129  AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24, \
130  AV_PIX_FMT_RGB48LE, AV_PIX_FMT_RGBA64LE, \
131  AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP, \
132  AV_PIX_FMT_GBRP9LE, AV_PIX_FMT_GBRP10LE, \
133  AV_PIX_FMT_GBRAP10LE, \
134  AV_PIX_FMT_GBRP12LE, AV_PIX_FMT_GBRP14LE, \
135  AV_PIX_FMT_GBRP16LE, AV_PIX_FMT_GBRAP12LE, \
136  AV_PIX_FMT_GBRAP16LE
137 
138 #define GRAY_FORMATS \
139  AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9LE, AV_PIX_FMT_GRAY10LE, \
140  AV_PIX_FMT_GRAY12LE, AV_PIX_FMT_GRAY14LE, AV_PIX_FMT_GRAY16LE
141 
145 
147 {
148  LutContext *s = ctx->priv;
149 
150  const enum AVPixelFormat *pix_fmts = s->is_rgb ? rgb_pix_fmts :
151  s->is_yuv ? yuv_pix_fmts :
152  all_pix_fmts;
154 }
155 
156 /**
157  * Clip value val in the minval - maxval range.
158  */
159 static double clip(void *opaque, double val)
160 {
161  LutContext *s = opaque;
162  double minval = s->var_values[VAR_MINVAL];
163  double maxval = s->var_values[VAR_MAXVAL];
164 
165  return av_clip(val, minval, maxval);
166 }
167 
168 /**
169  * Compute gamma correction for value val, assuming the minval-maxval
170  * range, val is clipped to a value contained in the same interval.
171  */
172 static double compute_gammaval(void *opaque, double gamma)
173 {
174  LutContext *s = opaque;
175  double val = s->var_values[VAR_CLIPVAL];
176  double minval = s->var_values[VAR_MINVAL];
177  double maxval = s->var_values[VAR_MAXVAL];
178 
179  return pow((val-minval)/(maxval-minval), gamma) * (maxval-minval)+minval;
180 }
181 
182 /**
183  * Compute ITU Rec.709 gamma correction of value val.
184  */
185 static double compute_gammaval709(void *opaque, double gamma)
186 {
187  LutContext *s = opaque;
188  double val = s->var_values[VAR_CLIPVAL];
189  double minval = s->var_values[VAR_MINVAL];
190  double maxval = s->var_values[VAR_MAXVAL];
191  double level = (val - minval) / (maxval - minval);
192  level = level < 0.018 ? 4.5 * level
193  : 1.099 * pow(level, 1.0 / gamma) - 0.099;
194  return level * (maxval - minval) + minval;
195 }
196 
197 static double (* const funcs1[])(void *, double) = {
198  clip,
201  NULL
202 };
203 
204 static const char * const funcs1_names[] = {
205  "clip",
206  "gammaval",
207  "gammaval709",
208  NULL
209 };
210 
212 {
213  AVFilterContext *ctx = inlink->dst;
214  LutContext *s = ctx->priv;
216  uint8_t rgba_map[4]; /* component index -> RGBA color index map */
217  int min[4], max[4];
218  int val, color, ret;
219 
220  s->hsub = desc->log2_chroma_w;
221  s->vsub = desc->log2_chroma_h;
222 
223  s->var_values[VAR_W] = inlink->w;
224  s->var_values[VAR_H] = inlink->h;
225  s->is_16bit = desc->comp[0].depth > 8;
226 
227  switch (inlink->format) {
228  case AV_PIX_FMT_YUV410P:
229  case AV_PIX_FMT_YUV411P:
230  case AV_PIX_FMT_YUV420P:
231  case AV_PIX_FMT_YUV422P:
232  case AV_PIX_FMT_YUV440P:
233  case AV_PIX_FMT_YUV444P:
234  case AV_PIX_FMT_YUVA420P:
235  case AV_PIX_FMT_YUVA422P:
236  case AV_PIX_FMT_YUVA444P:
263  min[Y] = 16 * (1 << (desc->comp[0].depth - 8));
264  min[U] = 16 * (1 << (desc->comp[1].depth - 8));
265  min[V] = 16 * (1 << (desc->comp[2].depth - 8));
266  min[A] = 0;
267  max[Y] = 235 * (1 << (desc->comp[0].depth - 8));
268  max[U] = 240 * (1 << (desc->comp[1].depth - 8));
269  max[V] = 240 * (1 << (desc->comp[2].depth - 8));
270  max[A] = (1 << desc->comp[0].depth) - 1;
271  break;
272  case AV_PIX_FMT_RGB48LE:
273  case AV_PIX_FMT_RGBA64LE:
274  min[0] = min[1] = min[2] = min[3] = 0;
275  max[0] = max[1] = max[2] = max[3] = 65535;
276  break;
277  default:
278  min[0] = min[1] = min[2] = min[3] = 0;
279  max[0] = max[1] = max[2] = max[3] = 255 * (1 << (desc->comp[0].depth - 8));
280  }
281 
282  s->is_yuv = s->is_rgb = 0;
283  s->is_planar = desc->flags & AV_PIX_FMT_FLAG_PLANAR;
284  if (ff_fmt_is_in(inlink->format, yuv_pix_fmts)) s->is_yuv = 1;
285  else if (ff_fmt_is_in(inlink->format, rgb_pix_fmts)) s->is_rgb = 1;
286 
287  if (s->is_rgb) {
288  ff_fill_rgba_map(rgba_map, inlink->format);
289  s->step = av_get_bits_per_pixel(desc) >> 3;
290  if (s->is_16bit) {
291  s->step = s->step >> 1;
292  }
293  }
294 
295  for (color = 0; color < desc->nb_components; color++) {
296  double res;
297  int comp = s->is_rgb ? rgba_map[color] : color;
298 
299  /* create the parsed expression */
300  av_expr_free(s->comp_expr[color]);
301  s->comp_expr[color] = NULL;
302  ret = av_expr_parse(&s->comp_expr[color], s->comp_expr_str[color],
304  if (ret < 0) {
306  "Error when parsing the expression '%s' for the component %d and color %d.\n",
307  s->comp_expr_str[comp], comp, color);
308  return AVERROR(EINVAL);
309  }
310 
311  /* compute the lut */
312  s->var_values[VAR_MAXVAL] = max[color];
313  s->var_values[VAR_MINVAL] = min[color];
314 
315  for (val = 0; val < FF_ARRAY_ELEMS(s->lut[comp]); val++) {
316  s->var_values[VAR_VAL] = val;
317  s->var_values[VAR_CLIPVAL] = av_clip(val, min[color], max[color]);
318  s->var_values[VAR_NEGVAL] =
319  av_clip(min[color] + max[color] - s->var_values[VAR_VAL],
320  min[color], max[color]);
321 
322  res = av_expr_eval(s->comp_expr[color], s->var_values, s);
323  if (isnan(res)) {
325  "Error when evaluating the expression '%s' for the value %d for the component %d.\n",
326  s->comp_expr_str[color], val, comp);
327  return AVERROR(EINVAL);
328  }
329  s->lut[comp][val] = av_clip((int)res, 0, max[A]);
330  av_log(ctx, AV_LOG_DEBUG, "val[%d][%d] = %d\n", comp, val, s->lut[comp][val]);
331  }
332  }
333 
334  return 0;
335 }
336 
337 struct thread_data {
340 
341  int w;
342  int h;
343 };
344 
345 #define LOAD_PACKED_COMMON\
346  LutContext *s = ctx->priv;\
347  const struct thread_data *td = arg;\
348 \
349  int i, j;\
350  const int w = td->w;\
351  const int h = td->h;\
352  AVFrame *in = td->in;\
353  AVFrame *out = td->out;\
354  const uint16_t (*tab)[256*256] = (const uint16_t (*)[256*256])s->lut;\
355  const int step = s->step;\
356 \
357  const int slice_start = (h * jobnr ) / nb_jobs;\
358  const int slice_end = (h * (jobnr+1)) / nb_jobs;\
359 
360 /* packed, 16-bit */
361 static int lut_packed_16bits(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
362 {
364 
365  uint16_t *inrow, *outrow, *inrow0, *outrow0;
366  const int in_linesize = in->linesize[0] / 2;
367  const int out_linesize = out->linesize[0] / 2;
368  inrow0 = (uint16_t *)in ->data[0];
369  outrow0 = (uint16_t *)out->data[0];
370 
371  for (i = slice_start; i < slice_end; i++) {
372  inrow = inrow0 + i * in_linesize;
373  outrow = outrow0 + i * out_linesize;
374  for (j = 0; j < w; j++) {
375 
376  switch (step) {
377 #if HAVE_BIGENDIAN
378  case 4: outrow[3] = av_bswap16(tab[3][av_bswap16(inrow[3])]); // Fall-through
379  case 3: outrow[2] = av_bswap16(tab[2][av_bswap16(inrow[2])]); // Fall-through
380  case 2: outrow[1] = av_bswap16(tab[1][av_bswap16(inrow[1])]); // Fall-through
381  default: outrow[0] = av_bswap16(tab[0][av_bswap16(inrow[0])]);
382 #else
383  case 4: outrow[3] = tab[3][inrow[3]]; // Fall-through
384  case 3: outrow[2] = tab[2][inrow[2]]; // Fall-through
385  case 2: outrow[1] = tab[1][inrow[1]]; // Fall-through
386  default: outrow[0] = tab[0][inrow[0]];
387 #endif
388  }
389  outrow += step;
390  inrow += step;
391  }
392  }
393 
394  return 0;
395 }
396 
397 /* packed, 8-bit */
398 static int lut_packed_8bits(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
399 {
401 
402  uint8_t *inrow, *outrow, *inrow0, *outrow0;
403  const int in_linesize = in->linesize[0];
404  const int out_linesize = out->linesize[0];
405  inrow0 = in ->data[0];
406  outrow0 = out->data[0];
407 
408  for (i = slice_start; i < slice_end; i++) {
409  inrow = inrow0 + i * in_linesize;
410  outrow = outrow0 + i * out_linesize;
411  for (j = 0; j < w; j++) {
412  switch (step) {
413  case 4: outrow[3] = tab[3][inrow[3]]; // Fall-through
414  case 3: outrow[2] = tab[2][inrow[2]]; // Fall-through
415  case 2: outrow[1] = tab[1][inrow[1]]; // Fall-through
416  default: outrow[0] = tab[0][inrow[0]];
417  }
418  outrow += step;
419  inrow += step;
420  }
421  }
422 
423  return 0;
424 }
425 
426 #define LOAD_PLANAR_COMMON\
427  LutContext *s = ctx->priv;\
428  const struct thread_data *td = arg;\
429  int i, j, plane;\
430  AVFrame *in = td->in;\
431  AVFrame *out = td->out;\
432 
433 #define PLANAR_COMMON\
434  int vsub = plane == 1 || plane == 2 ? s->vsub : 0;\
435  int hsub = plane == 1 || plane == 2 ? s->hsub : 0;\
436  int h = AV_CEIL_RSHIFT(td->h, vsub);\
437  int w = AV_CEIL_RSHIFT(td->w, hsub);\
438  const uint16_t *tab = s->lut[plane];\
439 \
440  const int slice_start = (h * jobnr ) / nb_jobs;\
441  const int slice_end = (h * (jobnr+1)) / nb_jobs;\
442 
443 /* planar >8 bit depth */
444 static int lut_planar_16bits(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
445 {
447 
448  uint16_t *inrow, *outrow;
449 
450  for (plane = 0; plane < 4 && in->data[plane] && in->linesize[plane]; plane++) {
452 
453  const int in_linesize = in->linesize[plane] / 2;
454  const int out_linesize = out->linesize[plane] / 2;
455 
456  inrow = (uint16_t *)in ->data[plane] + slice_start * in_linesize;
457  outrow = (uint16_t *)out->data[plane] + slice_start * out_linesize;
458 
459  for (i = slice_start; i < slice_end; i++) {
460  for (j = 0; j < w; j++) {
461 #if HAVE_BIGENDIAN
462  outrow[j] = av_bswap16(tab[av_bswap16(inrow[j])]);
463 #else
464  outrow[j] = tab[inrow[j]];
465 #endif
466  }
467  inrow += in_linesize;
468  outrow += out_linesize;
469  }
470  }
471 
472  return 0;
473 }
474 
475 /* planar 8bit depth */
476 static int lut_planar_8bits(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
477 {
479 
480  uint8_t *inrow, *outrow;
481 
482  for (plane = 0; plane < 4 && in->data[plane] && in->linesize[plane]; plane++) {
484 
485  const int in_linesize = in->linesize[plane];
486  const int out_linesize = out->linesize[plane];
487 
488  inrow = in ->data[plane] + slice_start * in_linesize;
489  outrow = out->data[plane] + slice_start * out_linesize;
490 
491  for (i = slice_start; i < slice_end; i++) {
492  for (j = 0; j < w; j++)
493  outrow[j] = tab[inrow[j]];
494  inrow += in_linesize;
495  outrow += out_linesize;
496  }
497  }
498 
499  return 0;
500 }
501 
502 #define PACKED_THREAD_DATA\
503  struct thread_data td = {\
504  .in = in,\
505  .out = out,\
506  .w = inlink->w,\
507  .h = in->height,\
508  };\
509 
510 #define PLANAR_THREAD_DATA\
511  struct thread_data td = {\
512  .in = in,\
513  .out = out,\
514  .w = inlink->w,\
515  .h = inlink->h,\
516  };\
517 
519 {
520  AVFilterContext *ctx = inlink->dst;
521  LutContext *s = ctx->priv;
522  AVFilterLink *outlink = ctx->outputs[0];
523  AVFrame *out;
524  int direct = 0;
525 
526  if (av_frame_is_writable(in)) {
527  direct = 1;
528  out = in;
529  } else {
530  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
531  if (!out) {
532  av_frame_free(&in);
533  return AVERROR(ENOMEM);
534  }
536  }
537 
538  if (s->is_rgb && s->is_16bit && !s->is_planar) {
539  /* packed, 16-bit */
543  } else if (s->is_rgb && !s->is_planar) {
544  /* packed 8 bits */
548  } else if (s->is_16bit) {
549  /* planar >8 bit depth */
553  } else {
554  /* planar 8bit depth */
558  }
559 
560  if (!direct)
561  av_frame_free(&in);
562 
563  return ff_filter_frame(outlink, out);
564 }
565 
566 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
567  char *res, int res_len, int flags)
568 {
569  int ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags);
570 
571  if (ret < 0)
572  return ret;
573 
574  return config_props(ctx->inputs[0]);
575 }
576 
577 static const AVFilterPad inputs[] = {
578  { .name = "default",
579  .type = AVMEDIA_TYPE_VIDEO,
580  .filter_frame = filter_frame,
581  .config_props = config_props,
582  },
583 };
584 static const AVFilterPad outputs[] = {
585  { .name = "default",
586  .type = AVMEDIA_TYPE_VIDEO,
587  },
588 };
589 
590 #define DEFINE_LUT_FILTER(name_, description_, priv_class_) \
591  const AVFilter ff_vf_##name_ = { \
592  .name = #name_, \
593  .description = NULL_IF_CONFIG_SMALL(description_), \
594  .priv_class = &priv_class_ ## _class, \
595  .priv_size = sizeof(LutContext), \
596  .init = name_##_init, \
597  .uninit = uninit, \
598  FILTER_INPUTS(inputs), \
599  FILTER_OUTPUTS(outputs), \
600  FILTER_QUERY_FUNC(query_formats), \
601  .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | \
602  AVFILTER_FLAG_SLICE_THREADS, \
603  .process_command = process_command, \
604  }
605 
606 AVFILTER_DEFINE_CLASS_EXT(lut, "lut/lutyuv/lutrgb", options);
607 
608 #if CONFIG_LUT_FILTER
609 
610 #define lut_init NULL
611 DEFINE_LUT_FILTER(lut, "Compute and apply a lookup table to the RGB/YUV input video.",
612  lut);
613 #undef lut_init
614 #endif
615 
616 #if CONFIG_LUTYUV_FILTER
617 
618 static av_cold int lutyuv_init(AVFilterContext *ctx)
619 {
620  LutContext *s = ctx->priv;
621 
622  s->is_yuv = 1;
623 
624  return 0;
625 }
626 
627 DEFINE_LUT_FILTER(lutyuv, "Compute and apply a lookup table to the YUV input video.",
628  lut);
629 #endif
630 
631 #if CONFIG_LUTRGB_FILTER
632 
633 static av_cold int lutrgb_init(AVFilterContext *ctx)
634 {
635  LutContext *s = ctx->priv;
636 
637  s->is_rgb = 1;
638 
639  return 0;
640 }
641 
642 DEFINE_LUT_FILTER(lutrgb, "Compute and apply a lookup table to the RGB input video.",
643  lut);
644 #endif
645 
646 #if CONFIG_NEGATE_FILTER
647 
648 static const AVOption negate_options[] = {
649  { "negate_alpha", NULL, OFFSET(negate_alpha), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
650  { NULL }
651 };
652 
653 AVFILTER_DEFINE_CLASS(negate);
654 
655 static av_cold int negate_init(AVFilterContext *ctx)
656 {
657  LutContext *s = ctx->priv;
658 
659  for (int i = 0; i < 4; i++) {
660  s->comp_expr_str[i] = av_strdup((i == 3 && !s->negate_alpha) ?
661  "val" : "negval");
662  if (!s->comp_expr_str[i])
663  return AVERROR(ENOMEM);
664  }
665 
666  return 0;
667 }
668 
669 DEFINE_LUT_FILTER(negate, "Negate input video.", negate);
670 
671 #endif
AVFILTER_DEFINE_CLASS_EXT
AVFILTER_DEFINE_CLASS_EXT(lut, "lut/lutyuv/lutrgb", options)
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:98
AV_PIX_FMT_YUV420P9LE
@ AV_PIX_FMT_YUV420P9LE
planar YUV 4:2:0, 13.5bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
Definition: pixfmt.h:147
A
#define A
Definition: vf_lut.c:81
direct
static void direct(const float *in, const FFTComplex *ir, int len, float *out)
Definition: af_afir.c:61
td
#define td
Definition: regdef.h:70
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
level
uint8_t level
Definition: svq3.c:204
av_clip
#define av_clip
Definition: common.h:96
G
#define G
Definition: vf_lut.c:79
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
LutContext::is_yuv
int is_yuv
Definition: vf_lut.c:68
compute_gammaval709
static double compute_gammaval709(void *opaque, double gamma)
Compute ITU Rec.709 gamma correction of value val.
Definition: vf_lut.c:185
GRAY_FORMATS
#define GRAY_FORMATS
Definition: vf_lut.c:138
PLANAR_COMMON
#define PLANAR_COMMON
Definition: vf_lut.c:433
out
FILE * out
Definition: movenc.c:54
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: vf_lut.c:518
color
Definition: vf_paletteuse.c:599
comp
static void comp(unsigned char *dst, ptrdiff_t dst_stride, unsigned char *src, ptrdiff_t src_stride, int add)
Definition: eamad.c:85
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1018
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2564
AV_PIX_FMT_YUV422P14LE
@ AV_PIX_FMT_YUV422P14LE
planar YUV 4:2:2,28bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
Definition: pixfmt.h:239
options
static const AVOption options[]
Definition: vf_lut.c:86
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
VAR_W
@ VAR_W
Definition: vf_lut.c:51
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:112
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:303
pixdesc.h
step
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But a word about which is also called distortion Distortion can be quantified by almost any quality measurement one chooses the sum of squared differences is used but more complex methods that consider psychovisual effects can be used as well It makes no difference in this discussion First step
Definition: rate_distortion.txt:58
w
uint8_t w
Definition: llviddspenc.c:38
AVOption
AVOption.
Definition: opt.h:247
B
#define B
Definition: vf_lut.c:80
data
const char data[16]
Definition: mxf.c:143
LutContext::comp_expr_str
char * comp_expr_str[4]
Definition: vf_lut.c:64
AV_PIX_FMT_YUV420P16LE
@ AV_PIX_FMT_YUV420P16LE
planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
Definition: pixfmt.h:121
av_get_bits_per_pixel
int av_get_bits_per_pixel(const AVPixFmtDescriptor *pixdesc)
Return the number of bits per pixel used by the pixel format described by pixdesc.
Definition: pixdesc.c:2516
AV_PIX_FMT_YUV440P
@ AV_PIX_FMT_YUV440P
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
Definition: pixfmt.h:99
max
#define max(a, b)
Definition: cuda_runtime.h:33
thread_data::w
int w
Definition: vf_lut.c:341
video.h
AV_PIX_FMT_YUV444P16LE
@ AV_PIX_FMT_YUV444P16LE
planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Definition: pixfmt.h:125
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
yuv_pix_fmts
static enum AVPixelFormat yuv_pix_fmts[]
Definition: vf_lut.c:142
VAR_H
@ VAR_H
Definition: vf_lut.c:52
LutContext::is_16bit
int is_16bit
Definition: vf_lut.c:70
AV_PIX_FMT_YUV420P12LE
@ AV_PIX_FMT_YUV420P12LE
planar YUV 4:2:0,18bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
Definition: pixfmt.h:233
var_names
static const char *const var_names[]
Definition: vf_lut.c:39
tab
static const struct twinvq_data tab
Definition: twinvq_data.h:10345
PACKED_THREAD_DATA
#define PACKED_THREAD_DATA
Definition: vf_lut.c:502
val
static double val(void *priv, double ch)
Definition: aeval.c:76
LOAD_PACKED_COMMON
#define LOAD_PACKED_COMMON
Definition: vf_lut.c:345
av_expr_free
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
Definition: eval.c:336
funcs1_names
static const char *const funcs1_names[]
Definition: vf_lut.c:204
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:50
AV_PIX_FMT_YUV420P10LE
@ AV_PIX_FMT_YUV420P10LE
planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
Definition: pixfmt.h:149
LutContext::lut
uint16_t lut[4][256 *256]
lookup table for each component
Definition: vf_lut.c:63
AV_PIX_FMT_YUV444P12LE
@ AV_PIX_FMT_YUV444P12LE
planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Definition: pixfmt.h:241
AV_PIX_FMT_YUV444P14LE
@ AV_PIX_FMT_YUV444P14LE
planar YUV 4:4:4,42bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Definition: pixfmt.h:243
LutContext
Definition: vf_lut.c:61
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
av_cold
#define av_cold
Definition: attributes.h:90
thread_data
Definition: vf_lut.c:337
funcs1
static double(*const funcs1[])(void *, double)
Definition: vf_lut.c:197
s
#define s(width, name)
Definition: cbs_vp9.c:257
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
R
#define R
Definition: vf_lut.c:78
slice_end
static int slice_end(AVCodecContext *avctx, AVFrame *pict)
Handle slice ends.
Definition: mpeg12dec.c:2041
ff_set_common_formats_from_list
int ff_set_common_formats_from_list(AVFilterContext *ctx, const int *fmts)
Equivalent to ff_set_common_formats(ctx, ff_make_format_list(fmts))
Definition: formats.c:705
pix_fmts
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:290
var_name
var_name
Definition: noise_bsf.c:47
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
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
all_pix_fmts
static enum AVPixelFormat all_pix_fmts[]
Definition: vf_lut.c:144
AVExpr
Definition: eval.c:157
YUV_FORMATS
#define YUV_FORMATS
Definition: vf_lut.c:113
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
PLANAR_THREAD_DATA
#define PLANAR_THREAD_DATA
Definition: vf_lut.c:510
AV_PIX_FMT_YUV444P10LE
@ AV_PIX_FMT_YUV444P10LE
planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Definition: pixfmt.h:155
U
#define U
Definition: vf_lut.c:76
arg
const char * arg
Definition: jacosubdec.c:67
AV_PIX_FMT_YUVA422P10LE
@ AV_PIX_FMT_YUVA422P10LE
planar YUV 4:2:2 30bpp, (1 Cr & Cb sample per 2x1 Y & A samples, little-endian)
Definition: pixfmt.h:177
if
if(ret)
Definition: filter_design.txt:179
AV_PIX_FMT_YUV422P16LE
@ AV_PIX_FMT_YUV422P16LE
planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
Definition: pixfmt.h:123
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
NULL
#define NULL
Definition: coverity.c:32
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:537
isnan
#define isnan(x)
Definition: libm.h:340
AV_PIX_FMT_RGB48LE
@ AV_PIX_FMT_RGB48LE
packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as lit...
Definition: pixfmt.h:103
AV_PIX_FMT_RGBA64LE
@ AV_PIX_FMT_RGBA64LE
packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, the 2-byte value for each R/G/B/A component is st...
Definition: pixfmt.h:196
AV_PIX_FMT_YUVA444P9LE
@ AV_PIX_FMT_YUVA444P9LE
planar YUV 4:4:4 36bpp, (1 Cr & Cb sample per 1x1 Y & A samples), little-endian
Definition: pixfmt.h:173
ff_fmt_is_in
int ff_fmt_is_in(int fmt, const int *fmts)
Tell if an integer is contained in the provided -1-terminated list of integers.
Definition: formats.c:352
AV_PIX_FMT_YUVA420P16LE
@ AV_PIX_FMT_YUVA420P16LE
planar YUV 4:2:0 40bpp, (1 Cr & Cb sample per 2x2 Y & A samples, little-endian)
Definition: pixfmt.h:181
AV_PIX_FMT_YUV440P10LE
@ AV_PIX_FMT_YUV440P10LE
planar YUV 4:4:0,20bpp, (1 Cr & Cb sample per 1x2 Y samples), little-endian
Definition: pixfmt.h:265
AV_PIX_FMT_YUVA420P9LE
@ AV_PIX_FMT_YUVA420P9LE
planar YUV 4:2:0 22.5bpp, (1 Cr & Cb sample per 2x2 Y & A samples), little-endian
Definition: pixfmt.h:169
lut_packed_8bits
static int lut_packed_8bits(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_lut.c:398
AV_PIX_FMT_YUV420P14LE
@ AV_PIX_FMT_YUV420P14LE
planar YUV 4:2:0,21bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
Definition: pixfmt.h:235
for
for(j=16;j >0;--j)
Definition: h264pred_template.c:469
thread_data::h
int h
Definition: vf_lut.c:342
eval.h
process_command
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
Definition: vf_lut.c:566
AV_PIX_FMT_YUV440P12LE
@ AV_PIX_FMT_YUV440P12LE
planar YUV 4:4:0,24bpp, (1 Cr & Cb sample per 1x2 Y samples), little-endian
Definition: pixfmt.h:267
OFFSET
#define OFFSET(x)
Definition: vf_lut.c:83
lut_planar_8bits
static int lut_planar_8bits(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_lut.c:476
LutContext::var_values
double var_values[VAR_VARS_NB]
Definition: vf_lut.c:67
AV_PIX_FMT_YUV422P10LE
@ AV_PIX_FMT_YUV422P10LE
planar YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
Definition: pixfmt.h:151
LutContext::hsub
int hsub
Definition: vf_lut.c:66
color
static const uint32_t color[16+AV_CLASS_CATEGORY_NB]
Definition: log.c:92
VAR_MAXVAL
@ VAR_MAXVAL
Definition: vf_lut.c:54
VAR_VAL
@ VAR_VAL
Definition: vf_lut.c:53
av_frame_is_writable
int av_frame_is_writable(AVFrame *frame)
Check if the frame data is writable.
Definition: frame.c:473
LutContext::comp_expr
AVExpr * comp_expr[4]
Definition: vf_lut.c:65
LutContext::step
int step
Definition: vf_lut.c:71
LOAD_PLANAR_COMMON
#define LOAD_PLANAR_COMMON
Definition: vf_lut.c:426
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
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:167
lut_packed_16bits
static int lut_packed_16bits(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_lut.c:361
av_bswap16
#define av_bswap16
Definition: bswap.h:31
attributes.h
rgb_pix_fmts
static enum AVPixelFormat rgb_pix_fmts[]
Definition: vf_lut.c:143
AV_PIX_FMT_YUVA420P10LE
@ AV_PIX_FMT_YUVA420P10LE
planar YUV 4:2:0 25bpp, (1 Cr & Cb sample per 2x2 Y & A samples, little-endian)
Definition: pixfmt.h:175
internal.h
AVFILTER_DEFINE_CLASS
#define AVFILTER_DEFINE_CLASS(fname)
Definition: internal.h:326
VAR_CLIPVAL
@ VAR_CLIPVAL
Definition: vf_lut.c:57
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
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:803
outputs
static const AVFilterPad outputs[]
Definition: vf_lut.c:584
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:56
inputs
static const AVFilterPad inputs[]
Definition: vf_lut.c:577
ret
ret
Definition: filter_design.txt:187
bswap.h
LutContext::is_rgb
int is_rgb
Definition: vf_lut.c:68
VAR_NEGVAL
@ VAR_NEGVAL
Definition: vf_lut.c:56
AVFrame::height
int height
Definition: frame.h:361
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
LutContext::vsub
int vsub
Definition: vf_lut.c:66
avfilter.h
AV_PIX_FMT_YUV444P9LE
@ AV_PIX_FMT_YUV444P9LE
planar YUV 4:4:4, 27bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Definition: pixfmt.h:153
AV_PIX_FMT_FLAG_PLANAR
#define AV_PIX_FMT_FLAG_PLANAR
At least one pixel component is not in the first data plane.
Definition: pixdesc.h:132
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
query_formats
static int query_formats(AVFilterContext *ctx)
Definition: vf_lut.c:146
AVFilterContext
An instance of a filter.
Definition: avfilter.h:386
V
#define V
Definition: vf_lut.c:77
av_strdup
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:279
desc
const char * desc
Definition: libsvtav1.c:79
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
VAR_MINVAL
@ VAR_MINVAL
Definition: vf_lut.c:55
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
AV_PIX_FMT_YUVA444P10LE
@ AV_PIX_FMT_YUVA444P10LE
planar YUV 4:4:4 40bpp, (1 Cr & Cb sample per 1x1 Y & A samples, little-endian)
Definition: pixfmt.h:179
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:241
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
AV_PIX_FMT_YUV411P
@ AV_PIX_FMT_YUV411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
Definition: pixfmt.h:73
ff_fill_rgba_map
int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt)
Definition: drawutils.c:33
LutContext::is_planar
int is_planar
Definition: vf_lut.c:69
thread_data::in
AVFrame * in
Definition: vf_lut.c:338
AV_PIX_FMT_YUV422P9LE
@ AV_PIX_FMT_YUV422P9LE
planar YUV 4:2:2, 18bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
Definition: pixfmt.h:157
AV_PIX_FMT_YUVA422P16LE
@ AV_PIX_FMT_YUVA422P16LE
planar YUV 4:2:2 48bpp, (1 Cr & Cb sample per 2x1 Y & A samples, little-endian)
Definition: pixfmt.h:183
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
thread_data::out
AVFrame * out
Definition: vf_lut.c:339
AV_PIX_FMT_YUV410P
@ AV_PIX_FMT_YUV410P
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
Definition: pixfmt.h:72
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
config_props
static int config_props(AVFilterLink *inlink)
Definition: vf_lut.c:211
AV_PIX_FMT_YUVA444P16LE
@ AV_PIX_FMT_YUVA444P16LE
planar YUV 4:4:4 64bpp, (1 Cr & Cb sample per 1x1 Y & A samples, little-endian)
Definition: pixfmt.h:185
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:228
drawutils.h
ff_filter_execute
static av_always_inline int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg, int *ret, int nb_jobs)
Definition: internal.h:143
lut_planar_16bits
static int lut_planar_16bits(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_lut.c:444
RGB_FORMATS
#define RGB_FORMATS
Definition: vf_lut.c:126
AV_PIX_FMT_YUV422P12LE
@ AV_PIX_FMT_YUV422P12LE
planar YUV 4:2:2,24bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
Definition: pixfmt.h:237
FLAGS
#define FLAGS
Definition: vf_lut.c:84
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_lut.c:101
clip
static double clip(void *opaque, double val)
Clip value val in the minval - maxval range.
Definition: vf_lut.c:159
LutContext::negate_alpha
int negate_alpha
Definition: vf_lut.c:72
compute_gammaval
static double compute_gammaval(void *opaque, double gamma)
Compute gamma correction for value val, assuming the minval-maxval range, val is clipped to a value c...
Definition: vf_lut.c:172
DEFINE_LUT_FILTER
#define DEFINE_LUT_FILTER(name_, description_, priv_class_)
Definition: vf_lut.c:590
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:166
VAR_VARS_NB
@ VAR_VARS_NB
Definition: vf_lut.c:58
Y
#define Y
Definition: vf_lut.c:75
min
float min
Definition: vorbis_enc_data.h:429
AV_PIX_FMT_YUVA422P9LE
@ AV_PIX_FMT_YUVA422P9LE
planar YUV 4:2:2 27bpp, (1 Cr & Cb sample per 2x1 Y & A samples), little-endian
Definition: pixfmt.h:171