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