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
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;
153  AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts);
154  if (!fmts_list)
155  return AVERROR(ENOMEM);
156  return ff_set_common_formats(ctx, fmts_list);
157 }
158 
159 /**
160  * Clip value val in the minval - maxval range.
161  */
162 static double clip(void *opaque, double val)
163 {
164  LutContext *s = opaque;
165  double minval = s->var_values[VAR_MINVAL];
166  double maxval = s->var_values[VAR_MAXVAL];
167 
168  return av_clip(val, minval, maxval);
169 }
170 
171 /**
172  * Compute gamma correction for value val, assuming the minval-maxval
173  * range, val is clipped to a value contained in the same interval.
174  */
175 static double compute_gammaval(void *opaque, double gamma)
176 {
177  LutContext *s = opaque;
178  double val = s->var_values[VAR_CLIPVAL];
179  double minval = s->var_values[VAR_MINVAL];
180  double maxval = s->var_values[VAR_MAXVAL];
181 
182  return pow((val-minval)/(maxval-minval), gamma) * (maxval-minval)+minval;
183 }
184 
185 /**
186  * Compute ITU Rec.709 gamma correction of value val.
187  */
188 static double compute_gammaval709(void *opaque, double gamma)
189 {
190  LutContext *s = opaque;
191  double val = s->var_values[VAR_CLIPVAL];
192  double minval = s->var_values[VAR_MINVAL];
193  double maxval = s->var_values[VAR_MAXVAL];
194  double level = (val - minval) / (maxval - minval);
195  level = level < 0.018 ? 4.5 * level
196  : 1.099 * pow(level, 1.0 / gamma) - 0.099;
197  return level * (maxval - minval) + minval;
198 }
199 
200 static double (* const funcs1[])(void *, double) = {
201  clip,
204  NULL
205 };
206 
207 static const char * const funcs1_names[] = {
208  "clip",
209  "gammaval",
210  "gammaval709",
211  NULL
212 };
213 
215 {
216  AVFilterContext *ctx = inlink->dst;
217  LutContext *s = ctx->priv;
219  uint8_t rgba_map[4]; /* component index -> RGBA color index map */
220  int min[4], max[4];
221  int val, color, ret;
222 
223  s->hsub = desc->log2_chroma_w;
224  s->vsub = desc->log2_chroma_h;
225 
226  s->var_values[VAR_W] = inlink->w;
227  s->var_values[VAR_H] = inlink->h;
228  s->is_16bit = desc->comp[0].depth > 8;
229 
230  switch (inlink->format) {
231  case AV_PIX_FMT_YUV410P:
232  case AV_PIX_FMT_YUV411P:
233  case AV_PIX_FMT_YUV420P:
234  case AV_PIX_FMT_YUV422P:
235  case AV_PIX_FMT_YUV440P:
236  case AV_PIX_FMT_YUV444P:
237  case AV_PIX_FMT_YUVA420P:
238  case AV_PIX_FMT_YUVA422P:
239  case AV_PIX_FMT_YUVA444P:
266  min[Y] = 16 * (1 << (desc->comp[0].depth - 8));
267  min[U] = 16 * (1 << (desc->comp[1].depth - 8));
268  min[V] = 16 * (1 << (desc->comp[2].depth - 8));
269  min[A] = 0;
270  max[Y] = 235 * (1 << (desc->comp[0].depth - 8));
271  max[U] = 240 * (1 << (desc->comp[1].depth - 8));
272  max[V] = 240 * (1 << (desc->comp[2].depth - 8));
273  max[A] = (1 << desc->comp[0].depth) - 1;
274  break;
275  case AV_PIX_FMT_RGB48LE:
276  case AV_PIX_FMT_RGBA64LE:
277  min[0] = min[1] = min[2] = min[3] = 0;
278  max[0] = max[1] = max[2] = max[3] = 65535;
279  break;
280  default:
281  min[0] = min[1] = min[2] = min[3] = 0;
282  max[0] = max[1] = max[2] = max[3] = 255 * (1 << (desc->comp[0].depth - 8));
283  }
284 
285  s->is_yuv = s->is_rgb = 0;
287  if (ff_fmt_is_in(inlink->format, yuv_pix_fmts)) s->is_yuv = 1;
288  else if (ff_fmt_is_in(inlink->format, rgb_pix_fmts)) s->is_rgb = 1;
289 
290  if (s->is_rgb) {
291  ff_fill_rgba_map(rgba_map, inlink->format);
292  s->step = av_get_bits_per_pixel(desc) >> 3;
293  if (s->is_16bit) {
294  s->step = s->step >> 1;
295  }
296  }
297 
298  for (color = 0; color < desc->nb_components; color++) {
299  double res;
300  int comp = s->is_rgb ? rgba_map[color] : color;
301 
302  /* create the parsed expression */
303  av_expr_free(s->comp_expr[color]);
304  s->comp_expr[color] = NULL;
305  ret = av_expr_parse(&s->comp_expr[color], s->comp_expr_str[color],
306  var_names, funcs1_names, funcs1, NULL, NULL, 0, ctx);
307  if (ret < 0) {
308  av_log(ctx, AV_LOG_ERROR,
309  "Error when parsing the expression '%s' for the component %d and color %d.\n",
310  s->comp_expr_str[comp], comp, color);
311  return AVERROR(EINVAL);
312  }
313 
314  /* compute the lut */
315  s->var_values[VAR_MAXVAL] = max[color];
316  s->var_values[VAR_MINVAL] = min[color];
317 
318  for (val = 0; val < FF_ARRAY_ELEMS(s->lut[comp]); val++) {
319  s->var_values[VAR_VAL] = val;
320  s->var_values[VAR_CLIPVAL] = av_clip(val, min[color], max[color]);
321  s->var_values[VAR_NEGVAL] =
322  av_clip(min[color] + max[color] - s->var_values[VAR_VAL],
323  min[color], max[color]);
324 
325  res = av_expr_eval(s->comp_expr[color], s->var_values, s);
326  if (isnan(res)) {
327  av_log(ctx, AV_LOG_ERROR,
328  "Error when evaluating the expression '%s' for the value %d for the component %d.\n",
329  s->comp_expr_str[color], val, comp);
330  return AVERROR(EINVAL);
331  }
332  s->lut[comp][val] = av_clip((int)res, 0, max[A]);
333  av_log(ctx, AV_LOG_DEBUG, "val[%d][%d] = %d\n", comp, val, s->lut[comp][val]);
334  }
335  }
336 
337  return 0;
338 }
339 
340 struct thread_data {
343 
344  int w;
345  int h;
346 };
347 
348 #define LOAD_PACKED_COMMON\
349  LutContext *s = ctx->priv;\
350  const struct thread_data *td = arg;\
351 \
352  int i, j;\
353  const int w = td->w;\
354  const int h = td->h;\
355  AVFrame *in = td->in;\
356  AVFrame *out = td->out;\
357  const uint16_t (*tab)[256*256] = (const uint16_t (*)[256*256])s->lut;\
358  const int step = s->step;\
359 \
360  const int slice_start = (h * jobnr ) / nb_jobs;\
361  const int slice_end = (h * (jobnr+1)) / nb_jobs;\
362 
363 /* packed, 16-bit */
364 static int lut_packed_16bits(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
365 {
367 
368  uint16_t *inrow, *outrow, *inrow0, *outrow0;
369  const int in_linesize = in->linesize[0] / 2;
370  const int out_linesize = out->linesize[0] / 2;
371  inrow0 = (uint16_t *)in ->data[0];
372  outrow0 = (uint16_t *)out->data[0];
373 
374  for (i = slice_start; i < slice_end; i++) {
375  inrow = inrow0 + i * in_linesize;
376  outrow = outrow0 + i * out_linesize;
377  for (j = 0; j < w; j++) {
378 
379  switch (step) {
380 #if HAVE_BIGENDIAN
381  case 4: outrow[3] = av_bswap16(tab[3][av_bswap16(inrow[3])]); // Fall-through
382  case 3: outrow[2] = av_bswap16(tab[2][av_bswap16(inrow[2])]); // Fall-through
383  case 2: outrow[1] = av_bswap16(tab[1][av_bswap16(inrow[1])]); // Fall-through
384  default: outrow[0] = av_bswap16(tab[0][av_bswap16(inrow[0])]);
385 #else
386  case 4: outrow[3] = tab[3][inrow[3]]; // Fall-through
387  case 3: outrow[2] = tab[2][inrow[2]]; // Fall-through
388  case 2: outrow[1] = tab[1][inrow[1]]; // Fall-through
389  default: outrow[0] = tab[0][inrow[0]];
390 #endif
391  }
392  outrow += step;
393  inrow += step;
394  }
395  }
396 
397  return 0;
398 }
399 
400 /* packed, 8-bit */
401 static int lut_packed_8bits(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
402 {
404 
405  uint8_t *inrow, *outrow, *inrow0, *outrow0;
406  const int in_linesize = in->linesize[0];
407  const int out_linesize = out->linesize[0];
408  inrow0 = in ->data[0];
409  outrow0 = out->data[0];
410 
411  for (i = slice_start; i < slice_end; i++) {
412  inrow = inrow0 + i * in_linesize;
413  outrow = outrow0 + i * out_linesize;
414  for (j = 0; j < w; j++) {
415  switch (step) {
416  case 4: outrow[3] = tab[3][inrow[3]]; // Fall-through
417  case 3: outrow[2] = tab[2][inrow[2]]; // Fall-through
418  case 2: outrow[1] = tab[1][inrow[1]]; // Fall-through
419  default: outrow[0] = tab[0][inrow[0]];
420  }
421  outrow += step;
422  inrow += step;
423  }
424  }
425 
426  return 0;
427 }
428 
429 #define LOAD_PLANAR_COMMON\
430  LutContext *s = ctx->priv;\
431  const struct thread_data *td = arg;\
432  int i, j, plane;\
433  AVFrame *in = td->in;\
434  AVFrame *out = td->out;\
435 
436 #define PLANAR_COMMON\
437  int vsub = plane == 1 || plane == 2 ? s->vsub : 0;\
438  int hsub = plane == 1 || plane == 2 ? s->hsub : 0;\
439  int h = AV_CEIL_RSHIFT(td->h, vsub);\
440  int w = AV_CEIL_RSHIFT(td->w, hsub);\
441  const uint16_t *tab = s->lut[plane];\
442 \
443  const int slice_start = (h * jobnr ) / nb_jobs;\
444  const int slice_end = (h * (jobnr+1)) / nb_jobs;\
445 
446 /* planar >8 bit depth */
447 static int lut_planar_16bits(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
448 {
450 
451  uint16_t *inrow, *outrow;
452 
453  for (plane = 0; plane < 4 && in->data[plane] && in->linesize[plane]; plane++) {
455 
456  const int in_linesize = in->linesize[plane] / 2;
457  const int out_linesize = out->linesize[plane] / 2;
458 
459  inrow = (uint16_t *)in ->data[plane] + slice_start * in_linesize;
460  outrow = (uint16_t *)out->data[plane] + slice_start * out_linesize;
461 
462  for (i = slice_start; i < slice_end; i++) {
463  for (j = 0; j < w; j++) {
464 #if HAVE_BIGENDIAN
465  outrow[j] = av_bswap16(tab[av_bswap16(inrow[j])]);
466 #else
467  outrow[j] = tab[inrow[j]];
468 #endif
469  }
470  inrow += in_linesize;
471  outrow += out_linesize;
472  }
473  }
474 
475  return 0;
476 }
477 
478 /* planar 8bit depth */
479 static int lut_planar_8bits(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
480 {
482 
483  uint8_t *inrow, *outrow;
484 
485  for (plane = 0; plane < 4 && in->data[plane] && in->linesize[plane]; plane++) {
487 
488  const int in_linesize = in->linesize[plane];
489  const int out_linesize = out->linesize[plane];
490 
491  inrow = in ->data[plane] + slice_start * in_linesize;
492  outrow = out->data[plane] + slice_start * out_linesize;
493 
494  for (i = slice_start; i < slice_end; i++) {
495  for (j = 0; j < w; j++)
496  outrow[j] = tab[inrow[j]];
497  inrow += in_linesize;
498  outrow += out_linesize;
499  }
500  }
501 
502  return 0;
503 }
504 
505 #define PACKED_THREAD_DATA\
506  struct thread_data td = {\
507  .in = in,\
508  .out = out,\
509  .w = inlink->w,\
510  .h = in->height,\
511  };\
512 
513 #define PLANAR_THREAD_DATA\
514  struct thread_data td = {\
515  .in = in,\
516  .out = out,\
517  .w = inlink->w,\
518  .h = inlink->h,\
519  };\
520 
522 {
523  AVFilterContext *ctx = inlink->dst;
524  LutContext *s = ctx->priv;
525  AVFilterLink *outlink = ctx->outputs[0];
526  AVFrame *out;
527  int direct = 0;
528 
529  if (av_frame_is_writable(in)) {
530  direct = 1;
531  out = in;
532  } else {
533  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
534  if (!out) {
535  av_frame_free(&in);
536  return AVERROR(ENOMEM);
537  }
538  av_frame_copy_props(out, in);
539  }
540 
541  if (s->is_rgb && s->is_16bit && !s->is_planar) {
542  /* packed, 16-bit */
544  ctx->internal->execute(ctx, lut_packed_16bits, &td, NULL,
546  } else if (s->is_rgb && !s->is_planar) {
547  /* packed 8 bits */
549  ctx->internal->execute(ctx, lut_packed_8bits, &td, NULL,
551  } else if (s->is_16bit) {
552  /* planar >8 bit depth */
554  ctx->internal->execute(ctx, lut_planar_16bits, &td, NULL,
556  } else {
557  /* planar 8bit depth */
559  ctx->internal->execute(ctx, lut_planar_8bits, &td, NULL,
561  }
562 
563  if (!direct)
564  av_frame_free(&in);
565 
566  return ff_filter_frame(outlink, out);
567 }
568 
569 static const AVFilterPad inputs[] = {
570  { .name = "default",
571  .type = AVMEDIA_TYPE_VIDEO,
572  .filter_frame = filter_frame,
573  .config_props = config_props,
574  },
575  { NULL }
576 };
577 static const AVFilterPad outputs[] = {
578  { .name = "default",
579  .type = AVMEDIA_TYPE_VIDEO,
580  },
581  { NULL }
582 };
583 
584 #define DEFINE_LUT_FILTER(name_, description_) \
585  AVFilter ff_vf_##name_ = { \
586  .name = #name_, \
587  .description = NULL_IF_CONFIG_SMALL(description_), \
588  .priv_size = sizeof(LutContext), \
589  .priv_class = &name_ ## _class, \
590  .init = name_##_init, \
591  .uninit = uninit, \
592  .query_formats = query_formats, \
593  .inputs = inputs, \
594  .outputs = outputs, \
595  .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS, \
596  }
597 
598 #if CONFIG_LUT_FILTER
599 
600 #define lut_options options
602 
603 static int lut_init(AVFilterContext *ctx)
604 {
605  return 0;
606 }
607 
608 DEFINE_LUT_FILTER(lut, "Compute and apply a lookup table to the RGB/YUV input video.");
609 #endif
610 
611 #if CONFIG_LUTYUV_FILTER
612 
613 #define lutyuv_options options
614 AVFILTER_DEFINE_CLASS(lutyuv);
615 
616 static av_cold int lutyuv_init(AVFilterContext *ctx)
617 {
618  LutContext *s = ctx->priv;
619 
620  s->is_yuv = 1;
621 
622  return 0;
623 }
624 
625 DEFINE_LUT_FILTER(lutyuv, "Compute and apply a lookup table to the YUV input video.");
626 #endif
627 
628 #if CONFIG_LUTRGB_FILTER
629 
630 #define lutrgb_options options
631 AVFILTER_DEFINE_CLASS(lutrgb);
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 #endif
644 
645 #if CONFIG_NEGATE_FILTER
646 
647 static const AVOption negate_options[] = {
648  { "negate_alpha", NULL, OFFSET(negate_alpha), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
649  { NULL }
650 };
651 
652 AVFILTER_DEFINE_CLASS(negate);
653 
654 static av_cold int negate_init(AVFilterContext *ctx)
655 {
656  LutContext *s = ctx->priv;
657  int i;
658 
659  av_log(ctx, AV_LOG_DEBUG, "negate_alpha:%d\n", s->negate_alpha);
660 
661  for (i = 0; i < 4; i++) {
662  s->comp_expr_str[i] = av_strdup((i == 3 && !s->negate_alpha) ?
663  "val" : "negval");
664  if (!s->comp_expr_str[i]) {
665  uninit(ctx);
666  return AVERROR(ENOMEM);
667  }
668  }
669 
670  return 0;
671 }
672 
673 DEFINE_LUT_FILTER(negate, "Negate input video.");
674 
675 #endif
int plane
Definition: avisynth_c.h:384
#define NULL
Definition: coverity.c:32
char * comp_expr_str[4]
Definition: vf_lut.c:64
#define PLANAR_COMMON
Definition: vf_lut.c:436
const char const char void * val
Definition: avisynth_c.h:863
planar YUV 4:4:0,20bpp, (1 Cr & Cb sample per 1x2 Y samples), little-endian
Definition: pixfmt.h:275
planar YUV 4:2:0,21bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
Definition: pixfmt.h:245
int is_planar
Definition: vf_lut.c:69
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2522
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
AVOption.
Definition: opt.h:246
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
planar YUV 4:2:2,28bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
Definition: pixfmt.h:249
planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
Definition: pixfmt.h:159
#define G
Definition: vf_lut.c:79
#define A
Definition: vf_lut.c:81
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:71
Main libavfilter public API header.
const char * desc
Definition: nvenc.c:68
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:2474
static int lut_planar_16bits(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_lut.c:447
#define RGB_FORMATS
Definition: vf_lut.c:126
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: vf_lut.c:521
#define GRAY_FORMATS
Definition: vf_lut.c:138
static const AVOption options[]
Definition: vf_lut.c:86
#define av_bswap16
Definition: bswap.h:31
planar YUV 4:4:4 40bpp, (1 Cr & Cb sample per 1x1 Y & A samples, little-endian)
Definition: pixfmt.h:189
static const char *const funcs1_names[]
Definition: vf_lut.c:207
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:679
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
planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
Definition: pixfmt.h:131
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:92
static enum AVPixelFormat yuv_pix_fmts[]
Definition: vf_lut.c:142
static double compute_gammaval709(void *opaque, double gamma)
Compute ITU Rec.709 gamma correction of value val.
Definition: vf_lut.c:188
Macro definitions for various function/variable attributes.
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:283
const char * name
Pad name.
Definition: internal.h:60
planar YUV 4:2:0 22.5bpp, (1 Cr & Cb sample per 2x2 Y & A samples), little-endian ...
Definition: pixfmt.h:179
static const char *const var_names[]
Definition: vf_lut.c:39
#define R
Definition: vf_lut.c:78
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1080
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:82
AVOptions.
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
static const uint32_t color[16+AV_CLASS_CATEGORY_NB]
Definition: log.c:92
planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Definition: pixfmt.h:251
static double(*const funcs1[])(void *, double)
Definition: vf_lut.c:200
Definition: eval.c:157
planar YUV 4:2:0 40bpp, (1 Cr & Cb sample per 2x2 Y & A samples, little-endian)
Definition: pixfmt.h:191
#define PACKED_THREAD_DATA
Definition: vf_lut.c:505
#define max(a, b)
Definition: cuda_runtime.h:33
AVFrame * in
Definition: vf_lut.c:341
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:254
#define LOAD_PACKED_COMMON
Definition: vf_lut.c:348
#define av_log(a,...)
A filter pad used for either input or output.
Definition: internal.h:54
planar YUV 4:2:0, 13.5bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
Definition: pixfmt.h:157
#define YUV_FORMATS
Definition: vf_lut.c:113
int is_16bit
Definition: vf_lut.c:70
static enum AVPixelFormat all_pix_fmts[]
Definition: vf_lut.c:144
planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Definition: pixfmt.h:165
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
Definition: pixfmt.h:176
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
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:568
#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
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:202
static int lut_planar_8bits(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_lut.c:479
void * priv
private data for use by the filter
Definition: avfilter.h:353
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
const char * arg
Definition: jacosubdec.c:66
planar YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
Definition: pixfmt.h:161
uint16_t lut[4][256 *256]
lookup table for each component
Definition: vf_lut.c:63
planar YUV 4:4:4 36bpp, (1 Cr & Cb sample per 1x1 Y & A samples), little-endian
Definition: pixfmt.h:183
static int lut_packed_8bits(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_lut.c:401
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:70
var_name
Definition: aeval.c:46
uint64_t flags
Combination of AV_PIX_FMT_FLAG_...
Definition: pixdesc.h:106
double var_values[VAR_VARS_NB]
Definition: vf_lut.c:67
uint8_t nb_components
The number of components each pixel has, (1-4)
Definition: pixdesc.h:83
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:802
#define FFMIN(a, b)
Definition: common.h:96
int hsub
Definition: vf_lut.c:66
#define OFFSET(x)
Definition: vf_lut.c:83
uint8_t w
Definition: llviddspenc.c:38
AVFormatContext * ctx
Definition: movenc.c:48
#define U
Definition: vf_lut.c:76
#define s(width, name)
Definition: cbs_vp9.c:257
#define LOAD_PLANAR_COMMON
Definition: vf_lut.c:429
planar YUV 4:2:0,18bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
Definition: pixfmt.h:243
#define PLANAR_THREAD_DATA
Definition: vf_lut.c:513
planar YUV 4:2:2, 18bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
Definition: pixfmt.h:167
#define FF_ARRAY_ELEMS(a)
int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt)
Definition: drawutils.c:35
if(ret)
static void comp(unsigned char *dst, ptrdiff_t dst_stride, unsigned char *src, ptrdiff_t src_stride, int add)
Definition: eamad.c:83
Definition: vf_lut.c:53
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:251
misc drawing utilities
int is_rgb
Definition: vf_lut.c:68
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
Definition: eval.c:334
int av_frame_is_writable(AVFrame *frame)
Check if the frame data is writable.
Definition: frame.c:594
static const AVFilterPad outputs[]
Definition: vf_lut.c:577
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
planar YUV 4:4:0,24bpp, (1 Cr & Cb sample per 1x2 Y samples), little-endian
Definition: pixfmt.h:277
static int query_formats(AVFilterContext *ctx)
Definition: vf_lut.c:146
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
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
Definition: pixfmt.h:72
planar YUV 4:2:2 48bpp, (1 Cr & Cb sample per 2x1 Y & A samples, little-endian)
Definition: pixfmt.h:193
Describe the class of an AVClass context structure.
Definition: log.h:67
planar YUV 4:4:4 64bpp, (1 Cr & Cb sample per 1x1 Y & A samples, little-endian)
Definition: pixfmt.h:195
#define isnan(x)
Definition: libm.h:340
Definition: vf_lut.c:51
byte swapping routines
int step
Definition: vf_lut.c:71
AVExpr * comp_expr[4]
Definition: vf_lut.c:65
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:350
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:275
planar YUV 4:2:2 30bpp, (1 Cr & Cb sample per 2x1 Y & A samples, little-endian)
Definition: pixfmt.h:187
AVFilterInternal * internal
An opaque struct for libavfilter internal use.
Definition: avfilter.h:378
#define DEFINE_LUT_FILTER(name_, description_)
Definition: vf_lut.c:584
uint8_t level
Definition: svq3.c:207
planar YUV 4:4:4, 27bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Definition: pixfmt.h:163
planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Definition: pixfmt.h:135
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
static enum AVPixelFormat rgb_pix_fmts[]
Definition: vf_lut.c:143
static int lut_packed_16bits(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_lut.c:364
static const AVFilterPad inputs[]
Definition: vf_lut.c:569
static int config_props(AVFilterLink *inlink)
Definition: vf_lut.c:214
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
planar YUV 4:2:2,24bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
Definition: pixfmt.h:247
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_lut.c:101
#define V
Definition: vf_lut.c:77
common internal and external API header
static double clip(void *opaque, double val)
Clip value val in the minval - maxval range.
Definition: vf_lut.c:162
#define Y
Definition: vf_lut.c:75
planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
Definition: pixfmt.h:133
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
Definition: pixfmt.h:73
avfilter_execute_func * execute
Definition: internal.h:155
planar YUV 4:2:0 25bpp, (1 Cr & Cb sample per 2x2 Y & A samples, little-endian)
Definition: pixfmt.h:185
static int slice_end(AVCodecContext *avctx, AVFrame *pict)
Handle slice ends.
Definition: mpeg12dec.c:2029
planar YUV 4:4:4,42bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Definition: pixfmt.h:253
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
Evaluate a previously parsed expression.
Definition: eval.c:734
#define AVFILTER_DEFINE_CLASS(fname)
Definition: internal.h:334
#define FLAGS
Definition: vf_lut.c:84
A list of supported formats for one end of a filter link.
Definition: formats.h:64
int negate_alpha
Definition: vf_lut.c:72
int vsub
Definition: vf_lut.c:66
static const struct twinvq_data tab
An instance of a filter.
Definition: avfilter.h:338
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:175
int height
Definition: frame.h:353
FILE * out
Definition: movenc.c:54
#define av_freep(p)
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
Definition: pixfmt.h:99
planar YUV 4:2:2 27bpp, (1 Cr & Cb sample per 2x1 Y & A samples), little-endian
Definition: pixfmt.h:181
internal API functions
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
#define B
Definition: vf_lut.c:80
float min
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
int is_yuv
Definition: vf_lut.c:68
#define AV_PIX_FMT_FLAG_PLANAR
At least one pixel component is not in the first data plane.
Definition: pixdesc.h:144
Definition: vf_lut.c:52
for(j=16;j >0;--j)
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:654
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:206
AVFrame * out
Definition: vf_lut.c:342
simple arithmetic expression evaluator