FFmpeg
vf_colorcontrast.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2021 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/imgutils.h"
25 #include "avfilter.h"
26 #include "drawutils.h"
27 #include "formats.h"
28 #include "internal.h"
29 #include "video.h"
30 
31 #define R 0
32 #define G 1
33 #define B 2
34 
35 typedef struct ColorContrastContext {
36  const AVClass *class;
37 
38  float rc, gm, by;
39  float rcw, gmw, byw;
40  float preserve;
41 
42  int step;
43  int depth;
44  uint8_t rgba_map[4];
45 
47  int jobnr, int nb_jobs);
49 
50 static inline float lerpf(float v0, float v1, float f)
51 {
52  return v0 + (v1 - v0) * f;
53 }
54 
55 #define PROCESS(max) \
56  br = (b + r) * 0.5f; \
57  gb = (g + b) * 0.5f; \
58  rg = (r + g) * 0.5f; \
59  \
60  gd = g - br; \
61  bd = b - rg; \
62  rd = r - gb; \
63  \
64  g0 = g + gd * gm; \
65  b0 = b - gd * gm; \
66  r0 = r - gd * gm; \
67  \
68  g1 = g - bd * by; \
69  b1 = b + bd * by; \
70  r1 = r - bd * by; \
71  \
72  g2 = g - rd * rc; \
73  b2 = b - rd * rc; \
74  r2 = r + rd * rc; \
75  \
76  ng = av_clipf((g0 * gmw + g1 * byw + g2 * rcw) * scale, 0.f, max); \
77  nb = av_clipf((b0 * gmw + b1 * byw + b2 * rcw) * scale, 0.f, max); \
78  nr = av_clipf((r0 * gmw + r1 * byw + r2 * rcw) * scale, 0.f, max); \
79  \
80  li = FFMAX3(r, g, b) + FFMIN3(r, g, b); \
81  lo = FFMAX3(nr, ng, nb) + FFMIN3(nr, ng, nb) + FLT_EPSILON; \
82  lf = li / lo; \
83  \
84  r = nr * lf; \
85  g = ng * lf; \
86  b = nb * lf; \
87  \
88  nr = lerpf(nr, r, preserve); \
89  ng = lerpf(ng, g, preserve); \
90  nb = lerpf(nb, b, preserve);
91 
92 static int colorcontrast_slice8(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
93 {
94  ColorContrastContext *s = ctx->priv;
95  AVFrame *frame = arg;
96  const int width = frame->width;
97  const int height = frame->height;
98  const int slice_start = (height * jobnr) / nb_jobs;
99  const int slice_end = (height * (jobnr + 1)) / nb_jobs;
100  const int glinesize = frame->linesize[0];
101  const int blinesize = frame->linesize[1];
102  const int rlinesize = frame->linesize[2];
103  uint8_t *gptr = frame->data[0] + slice_start * glinesize;
104  uint8_t *bptr = frame->data[1] + slice_start * blinesize;
105  uint8_t *rptr = frame->data[2] + slice_start * rlinesize;
106  const float preserve = s->preserve;
107  const float gm = s->gm * 0.5f;
108  const float by = s->by * 0.5f;
109  const float rc = s->rc * 0.5f;
110  const float gmw = s->gmw;
111  const float byw = s->byw;
112  const float rcw = s->rcw;
113  const float sum = gmw + byw + rcw;
114  const float scale = 1.f / sum;
115 
116  for (int y = slice_start; y < slice_end && sum > FLT_EPSILON; y++) {
117  for (int x = 0; x < width; x++) {
118  float g = gptr[x];
119  float b = bptr[x];
120  float r = rptr[x];
121  float g0, g1, g2;
122  float b0, b1, b2;
123  float r0, r1, r2;
124  float gd, bd, rd;
125  float gb, br, rg;
126  float nr, ng, nb;
127  float li, lo, lf;
128 
129  PROCESS(255.f);
130 
131  gptr[x] = av_clip_uint8(ng);
132  bptr[x] = av_clip_uint8(nb);
133  rptr[x] = av_clip_uint8(nr);
134  }
135 
136  gptr += glinesize;
137  bptr += blinesize;
138  rptr += rlinesize;
139  }
140 
141  return 0;
142 }
143 
144 static int colorcontrast_slice16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
145 {
146  ColorContrastContext *s = ctx->priv;
147  AVFrame *frame = arg;
148  const int depth = s->depth;
149  const float max = (1 << depth) - 1;
150  const int width = frame->width;
151  const int height = frame->height;
152  const int slice_start = (height * jobnr) / nb_jobs;
153  const int slice_end = (height * (jobnr + 1)) / nb_jobs;
154  const int glinesize = frame->linesize[0] / 2;
155  const int blinesize = frame->linesize[1] / 2;
156  const int rlinesize = frame->linesize[2] / 2;
157  uint16_t *gptr = (uint16_t *)frame->data[0] + slice_start * glinesize;
158  uint16_t *bptr = (uint16_t *)frame->data[1] + slice_start * blinesize;
159  uint16_t *rptr = (uint16_t *)frame->data[2] + slice_start * rlinesize;
160  const float preserve = s->preserve;
161  const float gm = s->gm * 0.5f;
162  const float by = s->by * 0.5f;
163  const float rc = s->rc * 0.5f;
164  const float gmw = s->gmw;
165  const float byw = s->byw;
166  const float rcw = s->rcw;
167  const float sum = gmw + byw + rcw;
168  const float scale = 1.f / sum;
169 
170  for (int y = slice_start; y < slice_end && sum > FLT_EPSILON; y++) {
171  for (int x = 0; x < width; x++) {
172  float g = gptr[x];
173  float b = bptr[x];
174  float r = rptr[x];
175  float g0, g1, g2;
176  float b0, b1, b2;
177  float r0, r1, r2;
178  float gd, bd, rd;
179  float gb, br, rg;
180  float nr, ng, nb;
181  float li, lo, lf;
182 
183  PROCESS(max);
184 
185  gptr[x] = av_clip_uintp2_c(ng, depth);
186  bptr[x] = av_clip_uintp2_c(nb, depth);
187  rptr[x] = av_clip_uintp2_c(nr, depth);
188  }
189 
190  gptr += glinesize;
191  bptr += blinesize;
192  rptr += rlinesize;
193  }
194 
195  return 0;
196 }
197 
198 static int colorcontrast_slice8p(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
199 {
200  ColorContrastContext *s = ctx->priv;
201  AVFrame *frame = arg;
202  const int step = s->step;
203  const int width = frame->width;
204  const int height = frame->height;
205  const int slice_start = (height * jobnr) / nb_jobs;
206  const int slice_end = (height * (jobnr + 1)) / nb_jobs;
207  const int linesize = frame->linesize[0];
208  const uint8_t roffset = s->rgba_map[R];
209  const uint8_t goffset = s->rgba_map[G];
210  const uint8_t boffset = s->rgba_map[B];
211  uint8_t *ptr = frame->data[0] + slice_start * linesize;
212  const float preserve = s->preserve;
213  const float gm = s->gm * 0.5f;
214  const float by = s->by * 0.5f;
215  const float rc = s->rc * 0.5f;
216  const float gmw = s->gmw;
217  const float byw = s->byw;
218  const float rcw = s->rcw;
219  const float sum = gmw + byw + rcw;
220  const float scale = 1.f / sum;
221 
222  for (int y = slice_start; y < slice_end && sum > FLT_EPSILON; y++) {
223  for (int x = 0; x < width; x++) {
224  float g = ptr[x * step + goffset];
225  float b = ptr[x * step + boffset];
226  float r = ptr[x * step + roffset];
227  float g0, g1, g2;
228  float b0, b1, b2;
229  float r0, r1, r2;
230  float gd, bd, rd;
231  float gb, br, rg;
232  float nr, ng, nb;
233  float li, lo, lf;
234 
235  PROCESS(255.f);
236 
237  ptr[x * step + goffset] = av_clip_uint8(ng);
238  ptr[x * step + boffset] = av_clip_uint8(nb);
239  ptr[x * step + roffset] = av_clip_uint8(nr);
240  }
241 
242  ptr += linesize;
243  }
244 
245  return 0;
246 }
247 
248 static int colorcontrast_slice16p(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
249 {
250  ColorContrastContext *s = ctx->priv;
251  AVFrame *frame = arg;
252  const int step = s->step;
253  const int depth = s->depth;
254  const float max = (1 << depth) - 1;
255  const int width = frame->width;
256  const int height = frame->height;
257  const int slice_start = (height * jobnr) / nb_jobs;
258  const int slice_end = (height * (jobnr + 1)) / nb_jobs;
259  const int linesize = frame->linesize[0] / 2;
260  const uint8_t roffset = s->rgba_map[R];
261  const uint8_t goffset = s->rgba_map[G];
262  const uint8_t boffset = s->rgba_map[B];
263  uint16_t *ptr = (uint16_t *)frame->data[0] + slice_start * linesize;
264  const float preserve = s->preserve;
265  const float gm = s->gm * 0.5f;
266  const float by = s->by * 0.5f;
267  const float rc = s->rc * 0.5f;
268  const float gmw = s->gmw;
269  const float byw = s->byw;
270  const float rcw = s->rcw;
271  const float sum = gmw + byw + rcw;
272  const float scale = 1.f / sum;
273 
274  for (int y = slice_start; y < slice_end && sum > FLT_EPSILON; y++) {
275  for (int x = 0; x < width; x++) {
276  float g = ptr[x * step + goffset];
277  float b = ptr[x * step + boffset];
278  float r = ptr[x * step + roffset];
279  float g0, g1, g2;
280  float b0, b1, b2;
281  float r0, r1, r2;
282  float gd, bd, rd;
283  float gb, br, rg;
284  float nr, ng, nb;
285  float li, lo, lf;
286 
287  PROCESS(max);
288 
289  ptr[x * step + goffset] = av_clip_uintp2_c(ng, depth);
290  ptr[x * step + boffset] = av_clip_uintp2_c(nb, depth);
291  ptr[x * step + roffset] = av_clip_uintp2_c(nr, depth);
292  }
293 
294  ptr += linesize;
295  }
296 
297  return 0;
298 }
299 
301 {
302  AVFilterContext *ctx = link->dst;
303  ColorContrastContext *s = ctx->priv;
304  int res;
305 
306  if (res = ff_filter_execute(ctx, s->do_slice, frame, NULL,
308  return res;
309 
310  return ff_filter_frame(ctx->outputs[0], frame);
311 }
312 
313 static const enum AVPixelFormat pixel_fmts[] = {
326 };
327 
329 {
330  AVFilterContext *ctx = inlink->dst;
331  ColorContrastContext *s = ctx->priv;
333  int planar = desc->flags & AV_PIX_FMT_FLAG_PLANAR;
334 
335  s->step = desc->nb_components;
336  if (inlink->format == AV_PIX_FMT_RGB0 ||
337  inlink->format == AV_PIX_FMT_0RGB ||
338  inlink->format == AV_PIX_FMT_BGR0 ||
339  inlink->format == AV_PIX_FMT_0BGR)
340  s->step = 4;
341 
342  s->depth = desc->comp[0].depth;
343  s->do_slice = s->depth <= 8 ? colorcontrast_slice8 : colorcontrast_slice16;
344  if (!planar)
345  s->do_slice = s->depth <= 8 ? colorcontrast_slice8p : colorcontrast_slice16p;
346 
347  ff_fill_rgba_map(s->rgba_map, inlink->format);
348 
349  return 0;
350 }
351 
353  {
354  .name = "default",
355  .type = AVMEDIA_TYPE_VIDEO,
357  .filter_frame = filter_frame,
358  .config_props = config_input,
359  },
360 };
361 
363  {
364  .name = "default",
365  .type = AVMEDIA_TYPE_VIDEO,
366  },
367 };
368 
369 #define OFFSET(x) offsetof(ColorContrastContext, x)
370 #define VF AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
371 
372 static const AVOption colorcontrast_options[] = {
373  { "rc", "set the red-cyan contrast", OFFSET(rc), AV_OPT_TYPE_FLOAT, {.dbl=0}, -1, 1, VF },
374  { "gm", "set the green-magenta contrast", OFFSET(gm), AV_OPT_TYPE_FLOAT, {.dbl=0}, -1, 1, VF },
375  { "by", "set the blue-yellow contrast", OFFSET(by), AV_OPT_TYPE_FLOAT, {.dbl=0}, -1, 1, VF },
376  { "rcw", "set the red-cyan weight", OFFSET(rcw), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, 1, VF },
377  { "gmw", "set the green-magenta weight", OFFSET(gmw), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, 1, VF },
378  { "byw", "set the blue-yellow weight", OFFSET(byw), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, 1, VF },
379  { "pl", "set the amount of preserving lightness", OFFSET(preserve), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, 1, VF },
380  { NULL }
381 };
382 
383 AVFILTER_DEFINE_CLASS(colorcontrast);
384 
386  .name = "colorcontrast",
387  .description = NULL_IF_CONFIG_SMALL("Adjust color contrast between RGB components."),
388  .priv_size = sizeof(ColorContrastContext),
389  .priv_class = &colorcontrast_class,
394  .process_command = ff_filter_process_command,
395 };
AV_PIX_FMT_GBRAP16
#define AV_PIX_FMT_GBRAP16
Definition: pixfmt.h:426
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
ColorContrastContext::depth
int depth
Definition: vf_colorcontrast.c:43
colorcontrast_slice8
static int colorcontrast_slice8(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorcontrast.c:92
ColorContrastContext::preserve
float preserve
Definition: vf_colorcontrast.c:40
r
const char * r
Definition: vf_curves.c:116
opt.h
VF
#define VF
Definition: vf_colorcontrast.c:370
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:2660
ColorContrastContext::rcw
float rcw
Definition: vf_colorcontrast.c:39
FILTER_PIXFMTS_ARRAY
#define FILTER_PIXFMTS_ARRAY(array)
Definition: internal.h:171
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
colorcontrast_slice16
static int colorcontrast_slice16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorcontrast.c:144
ColorContrastContext::step
int step
Definition: vf_colorcontrast.c:42
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:317
av_clip_uintp2_c
static av_always_inline av_const unsigned av_clip_uintp2_c(int a, int p)
Clip a signed integer to an unsigned power of two range.
Definition: common.h:276
step
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But a word about which is also called distortion Distortion can be quantified by almost any quality measurement one chooses the sum of squared differences is used but more complex methods that consider psychovisual effects can be used as well It makes no difference in this discussion First step
Definition: rate_distortion.txt:58
PROCESS
#define PROCESS(max)
Definition: vf_colorcontrast.c:55
AVOption
AVOption.
Definition: opt.h:247
b
#define b
Definition: input.c:40
ff_vf_colorcontrast
const AVFilter ff_vf_colorcontrast
Definition: vf_colorcontrast.c:385
float.h
ColorContrastContext::byw
float byw
Definition: vf_colorcontrast.c:39
AV_PIX_FMT_BGR24
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:69
AV_PIX_FMT_BGRA
@ AV_PIX_FMT_BGRA
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition: pixfmt.h:95
max
#define max(a, b)
Definition: cuda_runtime.h:33
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:169
video.h
ColorContrastContext::do_slice
int(* do_slice)(AVFilterContext *s, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorcontrast.c:46
formats.h
OFFSET
#define OFFSET(x)
Definition: vf_colorcontrast.c:369
AV_PIX_FMT_GBRP14
#define AV_PIX_FMT_GBRP14
Definition: pixfmt.h:422
b1
static double b1(void *priv, double x, double y)
Definition: vf_xfade.c:1703
AV_PIX_FMT_GBRAP
@ AV_PIX_FMT_GBRAP
planar GBRA 4:4:4:4 32bpp
Definition: pixfmt.h:205
v0
#define v0
Definition: regdef.h:26
AV_PIX_FMT_GBRP10
#define AV_PIX_FMT_GBRP10
Definition: pixfmt.h:420
ColorContrastContext
Definition: vf_colorcontrast.c:35
scale
static av_always_inline float scale(float x, float s)
Definition: vf_v360.c:1388
ColorContrastContext::gmw
float gmw
Definition: vf_colorcontrast.c:39
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:50
av_cold
#define av_cold
Definition: attributes.h:90
AV_PIX_FMT_GBRAP10
#define AV_PIX_FMT_GBRAP10
Definition: pixfmt.h:424
width
#define width
s
#define s(width, name)
Definition: cbs_vp9.c:257
AV_PIX_FMT_GBRAP12
#define AV_PIX_FMT_GBRAP12
Definition: pixfmt.h:425
g
const char * g
Definition: vf_curves.c:117
slice_end
static int slice_end(AVCodecContext *avctx, AVFrame *pict)
Handle slice ends.
Definition: mpeg12dec.c:2042
ColorContrastContext::rc
float rc
Definition: vf_colorcontrast.c:38
ctx
AVFormatContext * ctx
Definition: movenc.c:48
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(colorcontrast)
f
#define f(width, name)
Definition: cbs_vp9.c:255
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: internal.h:191
link
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 link
Definition: filter_design.txt:23
AV_PIX_FMT_RGBA
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:93
arg
const char * arg
Definition: jacosubdec.c:67
AV_PIX_FMT_GBRP16
#define AV_PIX_FMT_GBRP16
Definition: pixfmt.h:423
AV_PIX_FMT_RGBA64
#define AV_PIX_FMT_RGBA64
Definition: pixfmt.h:394
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:395
NULL
#define NULL
Definition: coverity.c:32
AV_PIX_FMT_BGR0
@ AV_PIX_FMT_BGR0
packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined
Definition: pixfmt.h:230
AV_PIX_FMT_GBRP9
#define AV_PIX_FMT_GBRP9
Definition: pixfmt.h:419
AV_PIX_FMT_ABGR
@ AV_PIX_FMT_ABGR
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
Definition: pixfmt.h:94
for
for(j=16;j >0;--j)
Definition: h264pred_template.c:469
AV_PIX_FMT_RGB24
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:68
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:117
ColorContrastContext::rgba_map
uint8_t rgba_map[4]
Definition: vf_colorcontrast.c:44
AV_PIX_FMT_RGB48
#define AV_PIX_FMT_RGB48
Definition: pixfmt.h:390
ff_filter_process_command
int ff_filter_process_command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
Generic processing of user supplied commands that are set in the same way as the filter options.
Definition: avfilter.c:882
height
#define height
b2
static double b2(void *priv, double x, double y)
Definition: vf_xfade.c:1704
ColorContrastContext::gm
float gm
Definition: vf_colorcontrast.c:38
AV_PIX_FMT_RGB0
@ AV_PIX_FMT_RGB0
packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined
Definition: pixfmt.h:228
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:146
AV_PIX_FMT_ARGB
@ AV_PIX_FMT_ARGB
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:92
AV_OPT_TYPE_FLOAT
@ AV_OPT_TYPE_FLOAT
Definition: opt.h:227
AV_PIX_FMT_BGRA64
#define AV_PIX_FMT_BGRA64
Definition: pixfmt.h:399
AV_PIX_FMT_GBRP12
#define AV_PIX_FMT_GBRP12
Definition: pixfmt.h:421
ff_filter_get_nb_threads
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:803
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
filter_frame
static int filter_frame(AVFilterLink *link, AVFrame *frame)
Definition: vf_colorcontrast.c:300
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:56
colorcontrast_slice16p
static int colorcontrast_slice16p(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorcontrast.c:248
R
#define R
Definition: vf_colorcontrast.c:31
AVFilter
Filter definition.
Definition: avfilter.h:165
colorcontrast_options
static const AVOption colorcontrast_options[]
Definition: vf_colorcontrast.c:372
lerpf
static float lerpf(float v0, float v1, float f)
Definition: vf_colorcontrast.c:50
AV_PIX_FMT_0BGR
@ AV_PIX_FMT_0BGR
packed BGR 8:8:8, 32bpp, XBGRXBGR... X=unused/undefined
Definition: pixfmt.h:229
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
colorcontrast_outputs
static const AVFilterPad colorcontrast_outputs[]
Definition: vf_colorcontrast.c:362
pixel_fmts
static enum AVPixelFormat pixel_fmts[]
Definition: vf_colorcontrast.c:313
colorcontrast_slice8p
static int colorcontrast_slice8p(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorcontrast.c:198
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
colorcontrast_inputs
static const AVFilterPad colorcontrast_inputs[]
Definition: vf_colorcontrast.c:352
avfilter.h
AV_PIX_FMT_FLAG_PLANAR
#define AV_PIX_FMT_FLAG_PLANAR
At least one pixel component is not in the first data plane.
Definition: pixdesc.h:132
av_clip_uint8
#define av_clip_uint8
Definition: common.h:102
AVFilterContext
An instance of a filter.
Definition: avfilter.h:402
G
#define G
Definition: vf_colorcontrast.c:32
AV_PIX_FMT_GBRP
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:158
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:121
desc
const char * desc
Definition: libsvtav1.c:79
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: internal.h:192
ff_fill_rgba_map
int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt)
Definition: drawutils.c:34
imgutils.h
AV_PIX_FMT_0RGB
@ AV_PIX_FMT_0RGB
packed RGB 8:8:8, 32bpp, XRGBXRGB... X=unused/undefined
Definition: pixfmt.h:227
B
#define B
Definition: vf_colorcontrast.c:33
b0
static double b0(void *priv, double x, double y)
Definition: vf_xfade.c:1702
ColorContrastContext::by
float by
Definition: vf_colorcontrast.c:38
drawutils.h
ff_filter_execute
static av_always_inline int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg, int *ret, int nb_jobs)
Definition: internal.h:143
planar
uint8_t pi<< 24) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_U8,(uint64_t)((*(const uint8_t *) pi - 0x80U))<< 56) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16,(*(const int16_t *) pi >>8)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S16, *(const int16_t *) pi *(1<< 16)) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S16,(uint64_t)(*(const int16_t *) pi)<< 48) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32,(*(const int32_t *) pi >>24)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S32,(uint64_t)(*(const int32_t *) pi)<< 32) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S64,(*(const int64_t *) pi >>56)+0x80) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S64, *(const int64_t *) pi *(1.0f/(UINT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S64, *(const int64_t *) pi *(1.0/(UINT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_FLT, llrintf(*(const float *) pi *(UINT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_DBL, llrint(*(const double *) pi *(UINT64_C(1)<< 63))) #define FMT_PAIR_FUNC(out, in) static conv_func_type *const fmt_pair_to_conv_functions[AV_SAMPLE_FMT_NB *AV_SAMPLE_FMT_NB]={ FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S64), };static void cpy1(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, len);} static void cpy2(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 2 *len);} static void cpy4(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 4 *len);} static void cpy8(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 8 *len);} AudioConvert *swri_audio_convert_alloc(enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, const int *ch_map, int flags) { AudioConvert *ctx;conv_func_type *f=fmt_pair_to_conv_functions[av_get_packed_sample_fmt(out_fmt)+AV_SAMPLE_FMT_NB *av_get_packed_sample_fmt(in_fmt)];if(!f) return NULL;ctx=av_mallocz(sizeof(*ctx));if(!ctx) return NULL;if(channels==1){ in_fmt=av_get_planar_sample_fmt(in_fmt);out_fmt=av_get_planar_sample_fmt(out_fmt);} ctx->channels=channels;ctx->conv_f=f;ctx->ch_map=ch_map;if(in_fmt==AV_SAMPLE_FMT_U8||in_fmt==AV_SAMPLE_FMT_U8P) memset(ctx->silence, 0x80, sizeof(ctx->silence));if(out_fmt==in_fmt &&!ch_map) { switch(av_get_bytes_per_sample(in_fmt)){ case 1:ctx->simd_f=cpy1;break;case 2:ctx->simd_f=cpy2;break;case 4:ctx->simd_f=cpy4;break;case 8:ctx->simd_f=cpy8;break;} } if(HAVE_X86ASM &&1) swri_audio_convert_init_x86(ctx, out_fmt, in_fmt, channels);if(ARCH_ARM) swri_audio_convert_init_arm(ctx, out_fmt, in_fmt, channels);if(ARCH_AARCH64) swri_audio_convert_init_aarch64(ctx, out_fmt, in_fmt, channels);return ctx;} void swri_audio_convert_free(AudioConvert **ctx) { av_freep(ctx);} int swri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, int len) { int ch;int off=0;const int os=(out->planar ? 1 :out->ch_count) *out->bps;unsigned misaligned=0;av_assert0(ctx->channels==out->ch_count);if(ctx->in_simd_align_mask) { int planes=in->planar ? in->ch_count :1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) in->ch[ch];misaligned|=m &ctx->in_simd_align_mask;} if(ctx->out_simd_align_mask) { int planes=out->planar ? out->ch_count :1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) out->ch[ch];misaligned|=m &ctx->out_simd_align_mask;} if(ctx->simd_f &&!ctx->ch_map &&!misaligned){ off=len &~15;av_assert1(off >=0);av_assert1(off<=len);av_assert2(ctx->channels==SWR_CH_MAX||!in->ch[ctx->channels]);if(off >0){ if(out->planar==in->planar){ int planes=out->planar ? out->ch_count :1;for(ch=0;ch< planes;ch++){ ctx->simd_f(out->ch+ch,(const uint8_t **) in->ch+ch, off *(out-> planar
Definition: audioconvert.c:56
int
int
Definition: ffmpeg_filter.c:153
config_input
static av_cold int config_input(AVFilterLink *inlink)
Definition: vf_colorcontrast.c:328
AVFILTERPAD_FLAG_NEEDS_WRITABLE
#define AVFILTERPAD_FLAG_NEEDS_WRITABLE
The filter expects writable frames from its input link, duplicating data buffers if needed.
Definition: internal.h:69