FFmpeg
vf_colorchannelmixer.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 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 <float.h>
22 
23 #include "libavutil/opt.h"
24 #include "libavutil/pixdesc.h"
25 #include "avfilter.h"
26 #include "drawutils.h"
27 #include "internal.h"
28 #include "video.h"
29 #include "preserve_color.h"
30 
31 #define R 0
32 #define G 1
33 #define B 2
34 #define A 3
35 
36 typedef struct ThreadData {
37  AVFrame *in, *out;
38 } ThreadData;
39 
40 typedef struct ColorChannelMixerContext {
41  const AVClass *class;
42  double rr, rg, rb, ra;
43  double gr, gg, gb, ga;
44  double br, bg, bb, ba;
45  double ar, ag, ab, aa;
48 
49  int *lut[4][4];
50 
51  int *buffer;
52 
53  uint8_t rgba_map[4];
54 
55  int (*filter_slice[2])(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs);
57 
58 static float lerpf(float v0, float v1, float f)
59 {
60  return v0 + (v1 - v0) * f;
61 }
62 
63 static void preservel(float *r, float *g, float *b, float lin, float lout, float max)
64 {
65  if (lout <= 0.f)
66  lout = 1.f / (max * 2.f);
67  *r *= lin / lout;
68  *g *= lin / lout;
69  *b *= lin / lout;
70 }
71 
72 #define DEPTH 8
74 
75 #undef DEPTH
76 #define DEPTH 16
78 
79 #undef DEPTH
80 #define DEPTH 32
82 
83 #define OFFSET(x) offsetof(ColorChannelMixerContext, x)
84 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
85 
87  { "rr", "set the red gain for the red channel", OFFSET(rr), AV_OPT_TYPE_DOUBLE, {.dbl=1}, -2, 2, FLAGS },
88  { "rg", "set the green gain for the red channel", OFFSET(rg), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -2, 2, FLAGS },
89  { "rb", "set the blue gain for the red channel", OFFSET(rb), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -2, 2, FLAGS },
90  { "ra", "set the alpha gain for the red channel", OFFSET(ra), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -2, 2, FLAGS },
91  { "gr", "set the red gain for the green channel", OFFSET(gr), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -2, 2, FLAGS },
92  { "gg", "set the green gain for the green channel", OFFSET(gg), AV_OPT_TYPE_DOUBLE, {.dbl=1}, -2, 2, FLAGS },
93  { "gb", "set the blue gain for the green channel", OFFSET(gb), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -2, 2, FLAGS },
94  { "ga", "set the alpha gain for the green channel", OFFSET(ga), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -2, 2, FLAGS },
95  { "br", "set the red gain for the blue channel", OFFSET(br), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -2, 2, FLAGS },
96  { "bg", "set the green gain for the blue channel", OFFSET(bg), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -2, 2, FLAGS },
97  { "bb", "set the blue gain for the blue channel", OFFSET(bb), AV_OPT_TYPE_DOUBLE, {.dbl=1}, -2, 2, FLAGS },
98  { "ba", "set the alpha gain for the blue channel", OFFSET(ba), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -2, 2, FLAGS },
99  { "ar", "set the red gain for the alpha channel", OFFSET(ar), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -2, 2, FLAGS },
100  { "ag", "set the green gain for the alpha channel", OFFSET(ag), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -2, 2, FLAGS },
101  { "ab", "set the blue gain for the alpha channel", OFFSET(ab), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -2, 2, FLAGS },
102  { "aa", "set the alpha gain for the alpha channel", OFFSET(aa), AV_OPT_TYPE_DOUBLE, {.dbl=1}, -2, 2, FLAGS },
103  { "pc", "set the preserve color mode", OFFSET(preserve_color), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_PRESERVE-1, FLAGS, .unit = "preserve" },
104  { "none", "disabled", 0, AV_OPT_TYPE_CONST, {.i64=P_NONE}, 0, 0, FLAGS, .unit = "preserve" },
105  { "lum", "luminance", 0, AV_OPT_TYPE_CONST, {.i64=P_LUM}, 0, 0, FLAGS, .unit = "preserve" },
106  { "max", "max", 0, AV_OPT_TYPE_CONST, {.i64=P_MAX}, 0, 0, FLAGS, .unit = "preserve" },
107  { "avg", "average", 0, AV_OPT_TYPE_CONST, {.i64=P_AVG}, 0, 0, FLAGS, .unit = "preserve" },
108  { "sum", "sum", 0, AV_OPT_TYPE_CONST, {.i64=P_SUM}, 0, 0, FLAGS, .unit = "preserve" },
109  { "nrm", "norm", 0, AV_OPT_TYPE_CONST, {.i64=P_NRM}, 0, 0, FLAGS, .unit = "preserve" },
110  { "pwr", "power", 0, AV_OPT_TYPE_CONST, {.i64=P_PWR}, 0, 0, FLAGS, .unit = "preserve" },
111  { "pa", "set the preserve color amount", OFFSET(preserve_amount), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 1, FLAGS },
112  { NULL }
113 };
114 
115 AVFILTER_DEFINE_CLASS(colorchannelmixer);
116 
117 static const enum AVPixelFormat pix_fmts[] = {
133 };
134 
135 static int filter_slice_gbrp(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
136 {
137  return filter_slice_rgba_planar_8(ctx, arg, jobnr, nb_jobs, 0, 8, 0);
138 }
139 
140 static int filter_slice_gbrap(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
141 {
142  return filter_slice_rgba_planar_8(ctx, arg, jobnr, nb_jobs, 1, 8, 0);
143 }
144 
145 static int filter_slice_gbrp_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
146 {
147  return filter_slice_rgba_planar_8(ctx, arg, jobnr, nb_jobs, 0, 8, 1);
148 }
149 
150 static int filter_slice_gbrap_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
151 {
152  return filter_slice_rgba_planar_8(ctx, arg, jobnr, nb_jobs, 1, 8, 1);
153 }
154 
155 static int filter_slice_gbrp9(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
156 {
157  return filter_slice_rgba_planar_16(ctx, arg, jobnr, nb_jobs, 0, 9, 0);
158 }
159 
160 static int filter_slice_gbrp10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
161 {
162  return filter_slice_rgba_planar_16(ctx, arg, jobnr, nb_jobs, 0, 10, 0);
163 }
164 
165 static int filter_slice_gbrap10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
166 {
167  return filter_slice_rgba_planar_16(ctx, arg, jobnr, nb_jobs, 1, 10, 0);
168 }
169 
170 static int filter_slice_gbrp12(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
171 {
172  return filter_slice_rgba_planar_16(ctx, arg, jobnr, nb_jobs, 0, 12, 0);
173 }
174 
175 static int filter_slice_gbrap12(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
176 {
177  return filter_slice_rgba_planar_16(ctx, arg, jobnr, nb_jobs, 1, 12, 0);
178 }
179 
180 static int filter_slice_gbrp14(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
181 {
182  return filter_slice_rgba_planar_16(ctx, arg, jobnr, nb_jobs, 0, 14, 0);
183 }
184 
185 static int filter_slice_gbrp16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
186 {
187  return filter_slice_rgba_planar_16(ctx, arg, jobnr, nb_jobs, 0, 16, 0);
188 }
189 
190 static int filter_slice_gbrap16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
191 {
192  return filter_slice_rgba_planar_16(ctx, arg, jobnr, nb_jobs, 1, 16, 0);
193 }
194 
195 static int filter_slice_gbrp9_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
196 {
197  return filter_slice_rgba_planar_16(ctx, arg, jobnr, nb_jobs, 0, 9, 1);
198 }
199 
200 static int filter_slice_gbrp10_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
201 {
202  return filter_slice_rgba_planar_16(ctx, arg, jobnr, nb_jobs, 0, 10, 1);
203 }
204 
205 static int filter_slice_gbrap10_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
206 {
207  return filter_slice_rgba_planar_16(ctx, arg, jobnr, nb_jobs, 1, 10, 1);
208 }
209 
210 static int filter_slice_gbrp12_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
211 {
212  return filter_slice_rgba_planar_16(ctx, arg, jobnr, nb_jobs, 0, 12, 1);
213 }
214 
215 static int filter_slice_gbrap12_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
216 {
217  return filter_slice_rgba_planar_16(ctx, arg, jobnr, nb_jobs, 1, 12, 1);
218 }
219 
220 static int filter_slice_gbrp14_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
221 {
222  return filter_slice_rgba_planar_16(ctx, arg, jobnr, nb_jobs, 0, 14, 1);
223 }
224 
225 static int filter_slice_gbrp16_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
226 {
227  return filter_slice_rgba_planar_16(ctx, arg, jobnr, nb_jobs, 0, 16, 1);
228 }
229 
230 static int filter_slice_gbrap16_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
231 {
232  return filter_slice_rgba_planar_16(ctx, arg, jobnr, nb_jobs, 1, 16, 1);
233 }
234 
235 static int filter_slice_rgba64(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
236 {
237  return filter_slice_rgba_packed_16(ctx, arg, jobnr, nb_jobs, 1, 4, 0, 16);
238 }
239 
240 static int filter_slice_rgb48(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
241 {
242  return filter_slice_rgba_packed_16(ctx, arg, jobnr, nb_jobs, 0, 3, 0, 16);
243 }
244 
245 static int filter_slice_rgba64_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
246 {
247  return filter_slice_rgba_packed_16(ctx, arg, jobnr, nb_jobs, 1, 4, 1, 16);
248 }
249 
250 static int filter_slice_rgb48_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
251 {
252  return filter_slice_rgba_packed_16(ctx, arg, jobnr, nb_jobs, 0, 3, 1, 16);
253 }
254 
255 static int filter_slice_rgba(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
256 {
257  return filter_slice_rgba_packed_8(ctx, arg, jobnr, nb_jobs, 1, 4, 0, 8);
258 }
259 
260 static int filter_slice_rgb24(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
261 {
262  return filter_slice_rgba_packed_8(ctx, arg, jobnr, nb_jobs, 0, 3, 0, 8);
263 }
264 
265 static int filter_slice_rgb0(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
266 {
267  return filter_slice_rgba_packed_8(ctx, arg, jobnr, nb_jobs, -1, 4, 0, 8);
268 }
269 
270 static int filter_slice_rgba_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
271 {
272  return filter_slice_rgba_packed_8(ctx, arg, jobnr, nb_jobs, 1, 4, 1, 8);
273 }
274 
275 static int filter_slice_rgb24_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
276 {
277  return filter_slice_rgba_packed_8(ctx, arg, jobnr, nb_jobs, 0, 3, 1, 8);
278 }
279 
280 static int filter_slice_rgb0_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
281 {
282  return filter_slice_rgba_packed_8(ctx, arg, jobnr, nb_jobs, -1, 4, 1, 8);
283 }
284 
285 static int filter_slice_gbrp32(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
286 {
287  return filter_slice_rgba_planar_32(ctx, arg, jobnr, nb_jobs, 0, 1, 0);
288 }
289 
290 static int filter_slice_gbrap32(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
291 {
292  return filter_slice_rgba_planar_32(ctx, arg, jobnr, nb_jobs, 1, 1, 0);
293 }
294 
295 static int filter_slice_gbrp32_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
296 {
297  return filter_slice_rgba_planar_32(ctx, arg, jobnr, nb_jobs, 0, 1, 1);
298 }
299 
300 static int filter_slice_gbrap32_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
301 {
302  return filter_slice_rgba_planar_32(ctx, arg, jobnr, nb_jobs, 1, 1, 1);
303 }
304 
305 static int config_output(AVFilterLink *outlink)
306 {
307  AVFilterContext *ctx = outlink->src;
308  ColorChannelMixerContext *s = ctx->priv;
310  const int depth = desc->comp[0].depth;
311  int i, j, size, *buffer = s->buffer;
312 
313  ff_fill_rgba_map(s->rgba_map, outlink->format);
314 
315  size = 1 << depth;
316  if (!s->buffer) {
317  s->buffer = buffer = av_malloc(16 * size * sizeof(*s->buffer));
318  if (!s->buffer)
319  return AVERROR(ENOMEM);
320 
321  for (i = 0; i < 4; i++)
322  for (j = 0; j < 4; j++, buffer += size)
323  s->lut[i][j] = buffer;
324  }
325 
326  for (i = 0; i < size; i++) {
327  s->lut[R][R][i] = lrint(i * s->rr);
328  s->lut[R][G][i] = lrint(i * s->rg);
329  s->lut[R][B][i] = lrint(i * s->rb);
330  s->lut[R][A][i] = lrint(i * s->ra);
331 
332  s->lut[G][R][i] = lrint(i * s->gr);
333  s->lut[G][G][i] = lrint(i * s->gg);
334  s->lut[G][B][i] = lrint(i * s->gb);
335  s->lut[G][A][i] = lrint(i * s->ga);
336 
337  s->lut[B][R][i] = lrint(i * s->br);
338  s->lut[B][G][i] = lrint(i * s->bg);
339  s->lut[B][B][i] = lrint(i * s->bb);
340  s->lut[B][A][i] = lrint(i * s->ba);
341 
342  s->lut[A][R][i] = lrint(i * s->ar);
343  s->lut[A][G][i] = lrint(i * s->ag);
344  s->lut[A][B][i] = lrint(i * s->ab);
345  s->lut[A][A][i] = lrint(i * s->aa);
346  }
347 
348  switch (outlink->format) {
349  case AV_PIX_FMT_BGR24:
350  case AV_PIX_FMT_RGB24:
351  s->filter_slice[0] = filter_slice_rgb24;
352  s->filter_slice[1] = filter_slice_rgb24_pl;
353  break;
354  case AV_PIX_FMT_0BGR:
355  case AV_PIX_FMT_0RGB:
356  case AV_PIX_FMT_BGR0:
357  case AV_PIX_FMT_RGB0:
358  s->filter_slice[0] = filter_slice_rgb0;
359  s->filter_slice[1] = filter_slice_rgb0_pl;
360  break;
361  case AV_PIX_FMT_ABGR:
362  case AV_PIX_FMT_ARGB:
363  case AV_PIX_FMT_BGRA:
364  case AV_PIX_FMT_RGBA:
365  s->filter_slice[0] = filter_slice_rgba;
366  s->filter_slice[1] = filter_slice_rgba_pl;
367  break;
368  case AV_PIX_FMT_BGR48:
369  case AV_PIX_FMT_RGB48:
370  s->filter_slice[0] = filter_slice_rgb48;
371  s->filter_slice[1] = filter_slice_rgb48_pl;
372  break;
373  case AV_PIX_FMT_BGRA64:
374  case AV_PIX_FMT_RGBA64:
375  s->filter_slice[0] = filter_slice_rgba64;
376  s->filter_slice[1] = filter_slice_rgba64_pl;
377  break;
378  case AV_PIX_FMT_GBRP:
379  s->filter_slice[0] = filter_slice_gbrp;
380  s->filter_slice[1] = filter_slice_gbrp_pl;
381  break;
382  case AV_PIX_FMT_GBRAP:
383  s->filter_slice[0] = filter_slice_gbrap;
384  s->filter_slice[1] = filter_slice_gbrap_pl;
385  break;
386  case AV_PIX_FMT_GBRP9:
387  s->filter_slice[0] = filter_slice_gbrp9;
388  s->filter_slice[1] = filter_slice_gbrp9_pl;
389  break;
390  case AV_PIX_FMT_GBRP10:
391  s->filter_slice[0] = filter_slice_gbrp10;
392  s->filter_slice[1] = filter_slice_gbrp10_pl;
393  break;
394  case AV_PIX_FMT_GBRAP10:
395  s->filter_slice[0] = filter_slice_gbrap10;
396  s->filter_slice[1] = filter_slice_gbrap10_pl;
397  break;
398  case AV_PIX_FMT_GBRP12:
399  s->filter_slice[0] = filter_slice_gbrp12;
400  s->filter_slice[1] = filter_slice_gbrp12_pl;
401  break;
402  case AV_PIX_FMT_GBRAP12:
403  s->filter_slice[0] = filter_slice_gbrap12;
404  s->filter_slice[1] = filter_slice_gbrap12_pl;
405  break;
406  case AV_PIX_FMT_GBRP14:
407  s->filter_slice[0] = filter_slice_gbrp14;
408  s->filter_slice[1] = filter_slice_gbrp14_pl;
409  break;
410  case AV_PIX_FMT_GBRP16:
411  s->filter_slice[0] = filter_slice_gbrp16;
412  s->filter_slice[1] = filter_slice_gbrp16_pl;
413  break;
414  case AV_PIX_FMT_GBRAP16:
415  s->filter_slice[0] = filter_slice_gbrap16;
416  s->filter_slice[1] = filter_slice_gbrap16_pl;
417  break;
418  case AV_PIX_FMT_GBRPF32:
419  s->filter_slice[0] = filter_slice_gbrp32;
420  s->filter_slice[1] = filter_slice_gbrp32_pl;
421  break;
422  case AV_PIX_FMT_GBRAPF32:
423  s->filter_slice[0] = filter_slice_gbrap32;
424  s->filter_slice[1] = filter_slice_gbrap32_pl;
425  break;
426  }
427 
428  return 0;
429 }
430 
432 {
433  AVFilterContext *ctx = inlink->dst;
434  ColorChannelMixerContext *s = ctx->priv;
435  AVFilterLink *outlink = ctx->outputs[0];
436  const int pc = s->preserve_color > 0;
437  ThreadData td;
438  AVFrame *out;
439 
440  if (av_frame_is_writable(in)) {
441  out = in;
442  } else {
443  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
444  if (!out) {
445  av_frame_free(&in);
446  return AVERROR(ENOMEM);
447  }
449  }
450 
451  td.in = in;
452  td.out = out;
453  ff_filter_execute(ctx, s->filter_slice[pc], &td, NULL,
454  FFMIN(outlink->h, ff_filter_get_nb_threads(ctx)));
455 
456  if (in != out)
457  av_frame_free(&in);
458  return ff_filter_frame(outlink, out);
459 }
460 
461 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
462  char *res, int res_len, int flags)
463 {
464  int ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags);
465 
466  if (ret < 0)
467  return ret;
468 
469  return config_output(ctx->outputs[0]);
470 }
471 
473 {
474  ColorChannelMixerContext *s = ctx->priv;
475 
476  av_freep(&s->buffer);
477 }
478 
480  {
481  .name = "default",
482  .type = AVMEDIA_TYPE_VIDEO,
483  .filter_frame = filter_frame,
484  },
485 };
486 
488  {
489  .name = "default",
490  .type = AVMEDIA_TYPE_VIDEO,
491  .config_props = config_output,
492  },
493 };
494 
496  .name = "colorchannelmixer",
497  .description = NULL_IF_CONFIG_SMALL("Adjust colors by mixing color channels."),
498  .priv_size = sizeof(ColorChannelMixerContext),
499  .priv_class = &colorchannelmixer_class,
500  .uninit = uninit,
505  .process_command = process_command,
506 };
ColorChannelMixerContext::gg
double gg
Definition: vf_colorchannelmixer.c:43
filter_slice_rgba64
static int filter_slice_rgba64(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorchannelmixer.c:235
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:112
AV_PIX_FMT_GBRAP16
#define AV_PIX_FMT_GBRAP16
Definition: pixfmt.h:501
P_SUM
@ P_SUM
Definition: preserve_color.h:31
td
#define td
Definition: regdef.h:70
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
r
const char * r
Definition: vf_curves.c:126
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
ColorChannelMixerContext::rg
double rg
Definition: vf_colorchannelmixer.c:42
opt.h
preserve_color.h
ColorChannelMixerContext::bb
double bb
Definition: vf_colorchannelmixer.c:44
out
FILE * out
Definition: movenc.c:54
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:2962
filter_slice_gbrp10_pl
static int filter_slice_gbrp10_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorchannelmixer.c:200
FILTER_PIXFMTS_ARRAY
#define FILTER_PIXFMTS_ARRAY(array)
Definition: internal.h:162
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
P_LUM
@ P_LUM
Definition: preserve_color.h:28
colorchannelmixer_options
static const AVOption colorchannelmixer_options[]
Definition: vf_colorchannelmixer.c:86
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:160
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:375
pixdesc.h
preserve_color
static void preserve_color(int preserve_color, float ir, float ig, float ib, float r, float g, float b, float max, float *icolor, float *ocolor)
Definition: preserve_color.h:53
AVOption
AVOption.
Definition: opt.h:346
b
#define b
Definition: input.c:41
filter_slice_gbrp14
static int filter_slice_gbrp14(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorchannelmixer.c:180
R
#define R
Definition: vf_colorchannelmixer.c:31
A
#define A
Definition: vf_colorchannelmixer.c:34
filter_slice_gbrp_pl
static int filter_slice_gbrp_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorchannelmixer.c:145
P_NRM
@ P_NRM
Definition: preserve_color.h:32
float.h
AV_PIX_FMT_BGR24
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:76
AV_PIX_FMT_BGRA
@ AV_PIX_FMT_BGRA
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition: pixfmt.h:102
max
#define max(a, b)
Definition: cuda_runtime.h:33
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:170
filter_slice_rgb0
static int filter_slice_rgb0(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorchannelmixer.c:265
G
#define G
Definition: vf_colorchannelmixer.c:32
ThreadData::out
AVFrame * out
Definition: af_adeclick.c:526
ColorChannelMixerContext::ar
double ar
Definition: vf_colorchannelmixer.c:45
ColorChannelMixerContext::buffer
int * buffer
Definition: vf_colorchannelmixer.c:51
video.h
ThreadData::in
AVFrame * in
Definition: af_adecorrelate.c:153
filter_slice_gbrap
static int filter_slice_gbrap(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorchannelmixer.c:140
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
ra
#define ra
Definition: regdef.h:57
colorchannelmixer_template.c
filter_slice_rgb0_pl
static int filter_slice_rgb0_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorchannelmixer.c:280
ColorChannelMixerContext::preserve_color
int preserve_color
Definition: vf_colorchannelmixer.c:47
filter_slice_gbrap32
static int filter_slice_gbrap32(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorchannelmixer.c:290
ColorChannelMixerContext::gr
double gr
Definition: vf_colorchannelmixer.c:43
ColorChannelMixerContext::filter_slice
int(* filter_slice[2])(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorchannelmixer.c:55
B
#define B
Definition: vf_colorchannelmixer.c:33
filter_slice_gbrap_pl
static int filter_slice_gbrap_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorchannelmixer.c:150
AV_PIX_FMT_GBRP14
#define AV_PIX_FMT_GBRP14
Definition: pixfmt.h:496
AV_PIX_FMT_GBRAP
@ AV_PIX_FMT_GBRAP
planar GBRA 4:4:4:4 32bpp
Definition: pixfmt.h:212
v0
#define v0
Definition: regdef.h:26
filter_slice_rgba
static int filter_slice_rgba(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorchannelmixer.c:255
AV_PIX_FMT_GBRP10
#define AV_PIX_FMT_GBRP10
Definition: pixfmt.h:494
filter_slice_gbrap10_pl
static int filter_slice_gbrap10_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorchannelmixer.c:205
filter_slice_gbrap16
static int filter_slice_gbrap16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorchannelmixer.c:190
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:33
lerpf
static float lerpf(float v0, float v1, float f)
Definition: vf_colorchannelmixer.c:58
ColorChannelMixerContext::preserve_amount
double preserve_amount
Definition: vf_colorchannelmixer.c:46
lrint
#define lrint
Definition: tablegen.h:53
ff_vf_colorchannelmixer
const AVFilter ff_vf_colorchannelmixer
Definition: vf_colorchannelmixer.c:495
av_cold
#define av_cold
Definition: attributes.h:90
ColorChannelMixerContext::rb
double rb
Definition: vf_colorchannelmixer.c:42
AV_PIX_FMT_GBRAP10
#define AV_PIX_FMT_GBRAP10
Definition: pixfmt.h:498
ColorChannelMixerContext::ba
double ba
Definition: vf_colorchannelmixer.c:44
s
#define s(width, name)
Definition: cbs_vp9.c:198
filter_slice_gbrp14_pl
static int filter_slice_gbrp14_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorchannelmixer.c:220
AV_PIX_FMT_GBRAP12
#define AV_PIX_FMT_GBRAP12
Definition: pixfmt.h:499
FLAGS
#define FLAGS
Definition: vf_colorchannelmixer.c:84
g
const char * g
Definition: vf_curves.c:127
filter_slice_rgb48
static int filter_slice_rgb48(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorchannelmixer.c:240
AV_OPT_TYPE_DOUBLE
@ AV_OPT_TYPE_DOUBLE
Definition: opt.h:237
ColorChannelMixerContext::lut
int * lut[4][4]
Definition: vf_colorchannelmixer.c:49
ColorChannelMixerContext::ag
double ag
Definition: vf_colorchannelmixer.c:45
ctx
AVFormatContext * ctx
Definition: movenc.c:48
filter_slice_gbrap32_pl
static int filter_slice_gbrap32_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorchannelmixer.c:300
ColorChannelMixerContext::bg
double bg
Definition: vf_colorchannelmixer.c:44
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: internal.h:182
AV_PIX_FMT_RGBA
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:100
ColorChannelMixerContext
Definition: vf_colorchannelmixer.c:40
arg
const char * arg
Definition: jacosubdec.c:67
colorchannelmixer_outputs
static const AVFilterPad colorchannelmixer_outputs[]
Definition: vf_colorchannelmixer.c:487
AV_PIX_FMT_GBRP16
#define AV_PIX_FMT_GBRP16
Definition: pixfmt.h:497
AV_PIX_FMT_RGBA64
#define AV_PIX_FMT_RGBA64
Definition: pixfmt.h:468
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
AV_PIX_FMT_BGR48
#define AV_PIX_FMT_BGR48
Definition: pixfmt.h:469
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:709
filter_slice_gbrp
static int filter_slice_gbrp(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorchannelmixer.c:135
filter_slice_gbrp9
static int filter_slice_gbrp9(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorchannelmixer.c:155
filter_slice_gbrp10
static int filter_slice_gbrp10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorchannelmixer.c:160
AV_PIX_FMT_BGR0
@ AV_PIX_FMT_BGR0
packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined
Definition: pixfmt.h:265
preservel
static void preservel(float *r, float *g, float *b, float lin, float lout, float max)
Definition: vf_colorchannelmixer.c:63
AV_PIX_FMT_GBRP9
#define AV_PIX_FMT_GBRP9
Definition: pixfmt.h:493
filter_slice_gbrap12_pl
static int filter_slice_gbrap12_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorchannelmixer.c:215
AV_PIX_FMT_ABGR
@ AV_PIX_FMT_ABGR
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
Definition: pixfmt.h:101
P_NONE
@ P_NONE
Definition: preserve_color.h:27
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(colorchannelmixer)
f
f
Definition: af_crystalizer.c:121
AV_PIX_FMT_RGB24
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:75
filter_slice_gbrap10
static int filter_slice_gbrap10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorchannelmixer.c:165
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:106
AV_PIX_FMT_GBRPF32
#define AV_PIX_FMT_GBRPF32
Definition: pixfmt.h:508
filter_slice_gbrap16_pl
static int filter_slice_gbrap16_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorchannelmixer.c:230
AV_PIX_FMT_RGB48
#define AV_PIX_FMT_RGB48
Definition: pixfmt.h:464
size
int size
Definition: twinvq_data.h:10344
av_frame_is_writable
int av_frame_is_writable(AVFrame *frame)
Check if the frame data is writable.
Definition: frame.c:645
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:890
filter_slice_gbrp12_pl
static int filter_slice_gbrp12_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorchannelmixer.c:210
NB_PRESERVE
@ NB_PRESERVE
Definition: preserve_color.h:34
filter_slice_gbrp32
static int filter_slice_gbrp32(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorchannelmixer.c:285
AV_PIX_FMT_RGB0
@ AV_PIX_FMT_RGB0
packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined
Definition: pixfmt.h:263
internal.h
AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
#define AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
Some filters support a generic "enable" expression option that can be used to enable or disable a fil...
Definition: avfilter.h:147
AV_PIX_FMT_ARGB
@ AV_PIX_FMT_ARGB
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:99
AV_PIX_FMT_BGRA64
#define AV_PIX_FMT_BGRA64
Definition: pixfmt.h:473
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: vf_colorchannelmixer.c:431
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
filter_slice_rgba64_pl
static int filter_slice_rgba64_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorchannelmixer.c:245
filter_slice_gbrp16_pl
static int filter_slice_gbrp16_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorchannelmixer.c:225
AV_PIX_FMT_GBRP12
#define AV_PIX_FMT_GBRP12
Definition: pixfmt.h:495
ff_filter_get_nb_threads
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:825
ThreadData
Used for passing data between threads.
Definition: dsddec.c:69
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
P_AVG
@ P_AVG
Definition: preserve_color.h:30
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:39
filter_slice_gbrp12
static int filter_slice_gbrp12(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorchannelmixer.c:170
AVFilter
Filter definition.
Definition: avfilter.h:166
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_colorchannelmixer.c:472
ret
ret
Definition: filter_design.txt:187
filter_slice_rgb24
static int filter_slice_rgb24(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorchannelmixer.c:260
AV_PIX_FMT_0BGR
@ AV_PIX_FMT_0BGR
packed BGR 8:8:8, 32bpp, XBGRXBGR... X=unused/undefined
Definition: pixfmt.h:264
ColorChannelMixerContext::ab
double ab
Definition: vf_colorchannelmixer.c:45
ColorChannelMixerContext::rr
double rr
Definition: vf_colorchannelmixer.c:42
ColorChannelMixerContext::ga
double ga
Definition: vf_colorchannelmixer.c:43
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
ColorChannelMixerContext::gb
double gb
Definition: vf_colorchannelmixer.c:43
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:235
avfilter.h
AV_PIX_FMT_GBRAPF32
#define AV_PIX_FMT_GBRAPF32
Definition: pixfmt.h:509
AVFilterContext
An instance of a filter.
Definition: avfilter.h:407
config_output
static int config_output(AVFilterLink *outlink)
Definition: vf_colorchannelmixer.c:305
AV_PIX_FMT_GBRP
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:165
AVFILTER_FLAG_SLICE_THREADS
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Definition: avfilter.h:117
desc
const char * desc
Definition: libsvtav1.c:75
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
filter_slice_gbrap12
static int filter_slice_gbrap12(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorchannelmixer.c:175
OFFSET
#define OFFSET(x)
Definition: vf_colorchannelmixer.c:83
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
ColorChannelMixerContext::rgba_map
uint8_t rgba_map[4]
Definition: vf_colorchannelmixer.c:53
P_PWR
@ P_PWR
Definition: preserve_color.h:33
ColorChannelMixerContext::br
double br
Definition: vf_colorchannelmixer.c:44
P_MAX
@ P_MAX
Definition: preserve_color.h:29
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: internal.h:183
filter_slice_rgb48_pl
static int filter_slice_rgb48_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorchannelmixer.c:250
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
filter_slice_rgba_pl
static int filter_slice_rgba_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorchannelmixer.c:270
filter_slice_rgb24_pl
static int filter_slice_rgb24_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorchannelmixer.c:275
ff_fill_rgba_map
int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt)
Definition: drawutils.c:35
ColorChannelMixerContext::ra
double ra
Definition: vf_colorchannelmixer.c:42
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:474
AV_PIX_FMT_0RGB
@ AV_PIX_FMT_0RGB
packed RGB 8:8:8, 32bpp, XRGBXRGB... X=unused/undefined
Definition: pixfmt.h:262
filter_slice_gbrp16
static int filter_slice_gbrp16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorchannelmixer.c:185
process_command
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
Definition: vf_colorchannelmixer.c:461
pix_fmts
static enum AVPixelFormat pix_fmts[]
Definition: vf_colorchannelmixer.c:117
drawutils.h
ColorChannelMixerContext::aa
double aa
Definition: vf_colorchannelmixer.c:45
colorchannelmixer_inputs
static const AVFilterPad colorchannelmixer_inputs[]
Definition: vf_colorchannelmixer.c:479
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:134
int
int
Definition: ffmpeg_filter.c:410
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:244
filter_slice_gbrp32_pl
static int filter_slice_gbrp32_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorchannelmixer.c:295
filter_slice_gbrp9_pl
static int filter_slice_gbrp9_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorchannelmixer.c:195