FFmpeg
vf_colorlevels.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 "libavutil/imgutils.h"
22 #include "libavutil/opt.h"
23 #include "libavutil/pixdesc.h"
24 #include "avfilter.h"
25 #include "drawutils.h"
26 #include "formats.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 Range {
37  double in_min, in_max;
38  double out_min, out_max;
39 } Range;
40 
41 typedef struct ColorLevelsContext {
42  const AVClass *class;
45 
46  int nb_comp;
47  int bpp;
48  int step;
49  uint8_t rgba_map[4];
50  int linesize;
51 
52  int (*colorlevels_slice[2])(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs);
54 
55 #define OFFSET(x) offsetof(ColorLevelsContext, x)
56 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
57 static const AVOption colorlevels_options[] = {
58  { "rimin", "set input red black point", OFFSET(range[R].in_min), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -1, 1, FLAGS },
59  { "gimin", "set input green black point", OFFSET(range[G].in_min), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -1, 1, FLAGS },
60  { "bimin", "set input blue black point", OFFSET(range[B].in_min), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -1, 1, FLAGS },
61  { "aimin", "set input alpha black point", OFFSET(range[A].in_min), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -1, 1, FLAGS },
62  { "rimax", "set input red white point", OFFSET(range[R].in_max), AV_OPT_TYPE_DOUBLE, {.dbl=1}, -1, 1, FLAGS },
63  { "gimax", "set input green white point", OFFSET(range[G].in_max), AV_OPT_TYPE_DOUBLE, {.dbl=1}, -1, 1, FLAGS },
64  { "bimax", "set input blue white point", OFFSET(range[B].in_max), AV_OPT_TYPE_DOUBLE, {.dbl=1}, -1, 1, FLAGS },
65  { "aimax", "set input alpha white point", OFFSET(range[A].in_max), AV_OPT_TYPE_DOUBLE, {.dbl=1}, -1, 1, FLAGS },
66  { "romin", "set output red black point", OFFSET(range[R].out_min), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 1, FLAGS },
67  { "gomin", "set output green black point", OFFSET(range[G].out_min), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 1, FLAGS },
68  { "bomin", "set output blue black point", OFFSET(range[B].out_min), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 1, FLAGS },
69  { "aomin", "set output alpha black point", OFFSET(range[A].out_min), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 1, FLAGS },
70  { "romax", "set output red white point", OFFSET(range[R].out_max), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS },
71  { "gomax", "set output green white point", OFFSET(range[G].out_max), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS },
72  { "bomax", "set output blue white point", OFFSET(range[B].out_max), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS },
73  { "aomax", "set output alpha white point", OFFSET(range[A].out_max), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS },
74  { "preserve", "set preserve color mode", OFFSET(preserve_color), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_PRESERVE-1, FLAGS, "preserve" },
75  { "none", "disabled", 0, AV_OPT_TYPE_CONST, {.i64=P_NONE}, 0, 0, FLAGS, "preserve" },
76  { "lum", "luminance", 0, AV_OPT_TYPE_CONST, {.i64=P_LUM}, 0, 0, FLAGS, "preserve" },
77  { "max", "max", 0, AV_OPT_TYPE_CONST, {.i64=P_MAX}, 0, 0, FLAGS, "preserve" },
78  { "avg", "average", 0, AV_OPT_TYPE_CONST, {.i64=P_AVG}, 0, 0, FLAGS, "preserve" },
79  { "sum", "sum", 0, AV_OPT_TYPE_CONST, {.i64=P_SUM}, 0, 0, FLAGS, "preserve" },
80  { "nrm", "norm", 0, AV_OPT_TYPE_CONST, {.i64=P_NRM}, 0, 0, FLAGS, "preserve" },
81  { "pwr", "power", 0, AV_OPT_TYPE_CONST, {.i64=P_PWR}, 0, 0, FLAGS, "preserve" },
82  { NULL }
83 };
84 
85 AVFILTER_DEFINE_CLASS(colorlevels);
86 
88 {
89  static const enum AVPixelFormat pix_fmts[] = {
98  };
99 
101 }
102 
103 typedef struct ThreadData {
104  const uint8_t *srcrow;
105  uint8_t *dstrow;
107  int src_linesize;
108 
109  float coeff[4];
110 
111  int h;
112 
113  int imin[4];
114  int omin[4];
115 } ThreadData;
116 
117 #define DO_COMMON(type, clip, preserve) \
118  ColorLevelsContext *s = ctx->priv; \
119  const ThreadData *td = arg; \
120  const int linesize = s->linesize; \
121  const int step = s->step; \
122  const int process_h = td->h; \
123  const int slice_start = (process_h * jobnr ) / nb_jobs; \
124  const int slice_end = (process_h * (jobnr+1)) / nb_jobs; \
125  const int src_linesize = td->src_linesize / sizeof(type); \
126  const int dst_linesize = td->dst_linesize / sizeof(type); \
127  const type *srcrow = (const type *)td->srcrow + src_linesize * slice_start; \
128  type *dstrow = (type *)td->dstrow + dst_linesize * slice_start; \
129  const uint8_t offset_r = s->rgba_map[R]; \
130  const uint8_t offset_g = s->rgba_map[G]; \
131  const uint8_t offset_b = s->rgba_map[B]; \
132  const uint8_t offset_a = s->rgba_map[A]; \
133  const int imin_r = td->imin[R]; \
134  const int imin_g = td->imin[G]; \
135  const int imin_b = td->imin[B]; \
136  const int imin_a = td->imin[A]; \
137  const int omin_r = td->omin[R]; \
138  const int omin_g = td->omin[G]; \
139  const int omin_b = td->omin[B]; \
140  const int omin_a = td->omin[A]; \
141  const float coeff_r = td->coeff[R]; \
142  const float coeff_g = td->coeff[G]; \
143  const float coeff_b = td->coeff[B]; \
144  const float coeff_a = td->coeff[A]; \
145  const type *src_r = srcrow + offset_r; \
146  const type *src_g = srcrow + offset_g; \
147  const type *src_b = srcrow + offset_b; \
148  const type *src_a = srcrow + offset_a; \
149  type *dst_r = dstrow + offset_r; \
150  type *dst_g = dstrow + offset_g; \
151  type *dst_b = dstrow + offset_b; \
152  type *dst_a = dstrow + offset_a; \
153  \
154  for (int y = slice_start; y < slice_end; y++) { \
155  for (int x = 0; x < linesize; x += step) { \
156  int ir, ig, ib, or, og, ob; \
157  ir = src_r[x]; \
158  ig = src_g[x]; \
159  ib = src_b[x]; \
160  if (preserve) { \
161  float ratio, icolor, ocolor, max = (1<<(8*sizeof(type)))-1; \
162  \
163  or = (ir - imin_r) * coeff_r + omin_r; \
164  og = (ig - imin_g) * coeff_g + omin_g; \
165  ob = (ib - imin_b) * coeff_b + omin_b; \
166  \
167  preserve_color(s->preserve_color, ir, ig, ib, or, og, ob, max, \
168  &icolor, &ocolor); \
169  if (ocolor > 0.f) { \
170  ratio = icolor / ocolor; \
171  \
172  or *= ratio; \
173  og *= ratio; \
174  ob *= ratio; \
175  } \
176  \
177  dst_r[x] = clip(or); \
178  dst_g[x] = clip(og); \
179  dst_b[x] = clip(ob); \
180  } else { \
181  dst_r[x] = clip((ir - imin_r) * coeff_r + omin_r); \
182  dst_g[x] = clip((ig - imin_g) * coeff_g + omin_g); \
183  dst_b[x] = clip((ib - imin_b) * coeff_b + omin_b); \
184  } \
185  } \
186  \
187  for (int x = 0; x < linesize && s->nb_comp == 4; x += step) \
188  dst_a[x] = clip((src_a[x] - imin_a) * coeff_a + omin_a); \
189  \
190  src_r += src_linesize; \
191  src_g += src_linesize; \
192  src_b += src_linesize; \
193  src_a += src_linesize; \
194  \
195  dst_r += dst_linesize; \
196  dst_g += dst_linesize; \
197  dst_b += dst_linesize; \
198  dst_a += dst_linesize; \
199  }
200 
201 static int colorlevels_slice_8(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
202 {
203  DO_COMMON(uint8_t, av_clip_uint8, 0)
204 
205  return 0;
206 }
207 
208 static int colorlevels_slice_16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
209 {
210  DO_COMMON(uint16_t, av_clip_uint16, 0)
211 
212  return 0;
213 }
214 
215 static int colorlevels_preserve_slice_8(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
216 {
217  DO_COMMON(uint8_t, av_clip_uint8, 1)
218 
219  return 0;
220 }
221 
222 static int colorlevels_preserve_slice_16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
223 {
224  DO_COMMON(uint16_t, av_clip_uint16, 1)
225 
226  return 0;
227 }
228 
230 {
231  AVFilterContext *ctx = inlink->dst;
232  ColorLevelsContext *s = ctx->priv;
234 
235  s->nb_comp = desc->nb_components;
236  s->bpp = desc->comp[0].depth >> 3;
237  s->step = av_get_padded_bits_per_pixel(desc) >> (3 + (s->bpp == 2));
238  s->linesize = inlink->w * s->step;
239  ff_fill_rgba_map(s->rgba_map, inlink->format);
240 
241  s->colorlevels_slice[0] = colorlevels_slice_8;
242  s->colorlevels_slice[1] = colorlevels_preserve_slice_8;
243  if (s->bpp == 2) {
244  s->colorlevels_slice[0] = colorlevels_slice_16;
245  s->colorlevels_slice[1] = colorlevels_preserve_slice_16;
246  }
247 
248  return 0;
249 }
250 
252 {
253  AVFilterContext *ctx = inlink->dst;
254  ColorLevelsContext *s = ctx->priv;
255  AVFilterLink *outlink = ctx->outputs[0];
256  const int step = s->step;
257  ThreadData td;
258  AVFrame *out;
259 
260  if (av_frame_is_writable(in)) {
261  out = in;
262  } else {
263  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
264  if (!out) {
265  av_frame_free(&in);
266  return AVERROR(ENOMEM);
267  }
269  }
270 
271  td.h = inlink->h;
272  td.dst_linesize = out->linesize[0];
273  td.src_linesize = in->linesize[0];
274  td.srcrow = in->data[0];
275  td.dstrow = out->data[0];
276 
277  switch (s->bpp) {
278  case 1:
279  for (int i = 0; i < s->nb_comp; i++) {
280  Range *r = &s->range[i];
281  const uint8_t offset = s->rgba_map[i];
282  const uint8_t *srcrow = in->data[0];
283  int imin = lrint(r->in_min * UINT8_MAX);
284  int imax = lrint(r->in_max * UINT8_MAX);
285  int omin = lrint(r->out_min * UINT8_MAX);
286  int omax = lrint(r->out_max * UINT8_MAX);
287  float coeff;
288 
289  if (imin < 0) {
290  imin = UINT8_MAX;
291  for (int y = 0; y < inlink->h; y++) {
292  const uint8_t *src = srcrow;
293 
294  for (int x = 0; x < s->linesize; x += step)
295  imin = FFMIN(imin, src[x + offset]);
296  srcrow += in->linesize[0];
297  }
298  }
299  if (imax < 0) {
300  srcrow = in->data[0];
301  imax = 0;
302  for (int y = 0; y < inlink->h; y++) {
303  const uint8_t *src = srcrow;
304 
305  for (int x = 0; x < s->linesize; x += step)
306  imax = FFMAX(imax, src[x + offset]);
307  srcrow += in->linesize[0];
308  }
309  }
310 
311  coeff = (omax - omin) / (double)(imax - imin);
312 
313  td.coeff[i] = coeff;
314  td.imin[i] = imin;
315  td.omin[i] = omin;
316  }
317  break;
318  case 2:
319  for (int i = 0; i < s->nb_comp; i++) {
320  Range *r = &s->range[i];
321  const uint8_t offset = s->rgba_map[i];
322  const uint8_t *srcrow = in->data[0];
323  int imin = lrint(r->in_min * UINT16_MAX);
324  int imax = lrint(r->in_max * UINT16_MAX);
325  int omin = lrint(r->out_min * UINT16_MAX);
326  int omax = lrint(r->out_max * UINT16_MAX);
327  float coeff;
328 
329  if (imin < 0) {
330  imin = UINT16_MAX;
331  for (int y = 0; y < inlink->h; y++) {
332  const uint16_t *src = (const uint16_t *)srcrow;
333 
334  for (int x = 0; x < s->linesize; x += step)
335  imin = FFMIN(imin, src[x + offset]);
336  srcrow += in->linesize[0];
337  }
338  }
339  if (imax < 0) {
340  srcrow = in->data[0];
341  imax = 0;
342  for (int y = 0; y < inlink->h; y++) {
343  const uint16_t *src = (const uint16_t *)srcrow;
344 
345  for (int x = 0; x < s->linesize; x += step)
346  imax = FFMAX(imax, src[x + offset]);
347  srcrow += in->linesize[0];
348  }
349  }
350 
351  coeff = (omax - omin) / (double)(imax - imin);
352 
353  td.coeff[i] = coeff;
354  td.imin[i] = imin;
355  td.omin[i] = omin;
356  }
357  break;
358  }
359 
360  ff_filter_execute(ctx, s->colorlevels_slice[s->preserve_color > 0], &td, NULL,
362 
363  if (in != out)
364  av_frame_free(&in);
365  return ff_filter_frame(outlink, out);
366 }
367 
368 static const AVFilterPad colorlevels_inputs[] = {
369  {
370  .name = "default",
371  .type = AVMEDIA_TYPE_VIDEO,
372  .filter_frame = filter_frame,
373  .config_props = config_input,
374  },
375 };
376 
378  {
379  .name = "default",
380  .type = AVMEDIA_TYPE_VIDEO,
381  },
382 };
383 
385  .name = "colorlevels",
386  .description = NULL_IF_CONFIG_SMALL("Adjust the color levels."),
387  .priv_size = sizeof(ColorLevelsContext),
388  .priv_class = &colorlevels_class,
393  .process_command = ff_filter_process_command,
394 };
ff_get_video_buffer
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:98
td
#define td
Definition: regdef.h:70
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
ThreadData::coeff
float coeff[4]
Definition: vf_colorlevels.c:109
ColorLevelsContext::linesize
int linesize
Definition: vf_colorlevels.c:50
r
const char * r
Definition: vf_curves.c:116
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
preserve_color.h
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:1019
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2564
P_PWR
@ P_PWR
Definition: preserve_color.h:33
colorlevels_preserve_slice_16
static int colorlevels_preserve_slice_16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorlevels.c:222
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: vf_colorlevels.c:251
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
ColorLevelsContext::preserve_color
int preserve_color
Definition: vf_colorlevels.c:44
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:112
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:303
pixdesc.h
colorlevels_inputs
static const AVFilterPad colorlevels_inputs[]
Definition: vf_colorlevels.c:368
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
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:247
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
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:153
video.h
config_input
static int config_input(AVFilterLink *inlink)
Definition: vf_colorlevels.c:229
A
#define A
Definition: vf_colorlevels.c:34
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:317
formats.h
ff_vf_colorlevels
const AVFilter ff_vf_colorlevels
Definition: vf_colorlevels.c:384
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:50
ColorLevelsContext
Definition: vf_colorlevels.c:41
ThreadData::imin
int imin[4]
Definition: vf_colorlevels.c:113
lrint
#define lrint
Definition: tablegen.h:53
ThreadData::srcrow
const uint8_t * srcrow
Definition: vf_colorlevels.c:104
P_AVG
@ P_AVG
Definition: preserve_color.h:30
s
#define s(width, name)
Definition: cbs_vp9.c:257
colorlevels_preserve_slice_8
static int colorlevels_preserve_slice_8(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorlevels.c:215
colorlevels_slice_16
static int colorlevels_slice_16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorlevels.c:208
Range::in_min
double in_min
Definition: vf_colorlevels.c:37
AV_OPT_TYPE_DOUBLE
@ AV_OPT_TYPE_DOUBLE
Definition: opt.h:226
ff_set_common_formats_from_list
int ff_set_common_formats_from_list(AVFilterContext *ctx, const int *fmts)
Equivalent to ff_set_common_formats(ctx, ff_make_format_list(fmts))
Definition: formats.c:698
pix_fmts
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:290
ctx
AVFormatContext * ctx
Definition: movenc.c:48
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: internal.h:152
ThreadData::h
int h
Definition: vf_blend.c:86
P_NONE
@ P_NONE
Definition: preserve_color.h:27
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
query_formats
static int query_formats(AVFilterContext *ctx)
Definition: vf_colorlevels.c:87
ColorLevelsContext::range
Range range[4]
Definition: vf_colorlevels.c:43
AV_PIX_FMT_RGBA64
#define AV_PIX_FMT_RGBA64
Definition: pixfmt.h:381
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
NB_PRESERVE
@ NB_PRESERVE
Definition: preserve_color.h:34
AV_PIX_FMT_BGR48
#define AV_PIX_FMT_BGR48
Definition: pixfmt.h:382
NULL
#define NULL
Definition: coverity.c:32
av_frame_copy_props
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:537
src
#define src
Definition: vp8dsp.c:255
P_LUM
@ P_LUM
Definition: preserve_color.h:28
P_MAX
@ P_MAX
Definition: preserve_color.h:29
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_ABGR
@ AV_PIX_FMT_ABGR
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
Definition: pixfmt.h:94
Range
Definition: vf_colorbalance.c:38
G
#define G
Definition: vf_colorlevels.c:32
OFFSET
#define OFFSET(x)
Definition: vf_colorlevels.c:55
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
ColorLevelsContext::rgba_map
uint8_t rgba_map[4]
Definition: vf_colorlevels.c:49
av_get_padded_bits_per_pixel
int av_get_padded_bits_per_pixel(const AVPixFmtDescriptor *pixdesc)
Return the number of bits per pixel for the pixel format described by pixdesc, including any padding ...
Definition: pixdesc.c:2529
AV_PIX_FMT_RGB48
#define AV_PIX_FMT_RGB48
Definition: pixfmt.h:377
av_frame_is_writable
int av_frame_is_writable(AVFrame *frame)
Check if the frame data is writable.
Definition: frame.c:473
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(colorlevels)
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:883
B
#define B
Definition: vf_colorlevels.c:33
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
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:130
AV_PIX_FMT_ARGB
@ AV_PIX_FMT_ARGB
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:92
colorlevels_slice_8
static int colorlevels_slice_8(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorlevels.c:201
AV_PIX_FMT_BGRA64
#define AV_PIX_FMT_BGRA64
Definition: pixfmt.h:386
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
ThreadData::dstrow
uint8_t * dstrow
Definition: vf_colorlevels.c:105
ColorLevelsContext::bpp
int bpp
Definition: vf_colorlevels.c:47
ff_filter_get_nb_threads
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:804
ThreadData
Used for passing data between threads.
Definition: dsddec.c:67
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:56
ColorLevelsContext::nb_comp
int nb_comp
Definition: vf_colorlevels.c:46
Range::out_min
double out_min
Definition: vf_colorlevels.c:38
P_SUM
@ P_SUM
Definition: preserve_color.h:31
AVFilter
Filter definition.
Definition: avfilter.h:149
AV_PIX_FMT_0BGR
@ AV_PIX_FMT_0BGR
packed BGR 8:8:8, 32bpp, XBGRXBGR... X=unused/undefined
Definition: pixfmt.h:229
colorlevels_outputs
static const AVFilterPad colorlevels_outputs[]
Definition: vf_colorlevels.c:377
ColorLevelsContext::colorlevels_slice
int(* colorlevels_slice[2])(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_colorlevels.c:52
ThreadData::src_linesize
int src_linesize
Definition: vf_bm3d.c:56
colorlevels_options
static const AVOption colorlevels_options[]
Definition: vf_colorlevels.c:57
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:224
avfilter.h
ColorLevelsContext::step
int step
Definition: vf_colorlevels.c:48
av_clip_uint8
#define av_clip_uint8
Definition: common.h:102
AVFilterContext
An instance of a filter.
Definition: avfilter.h:346
av_clip_uint16
#define av_clip_uint16
Definition: common.h:108
FLAGS
#define FLAGS
Definition: vf_colorlevels.c:56
DO_COMMON
#define DO_COMMON(type, clip, preserve)
Definition: vf_colorlevels.c:117
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
ThreadData::dst_linesize
int dst_linesize
Definition: vf_colorlevels.c:106
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
ThreadData::omin
int omin[4]
Definition: vf_colorlevels.c:114
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: internal.h:153
ff_fill_rgba_map
int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt)
Definition: drawutils.c:33
imgutils.h
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:334
AV_PIX_FMT_0RGB
@ AV_PIX_FMT_0RGB
packed RGB 8:8:8, 32bpp, XRGBXRGB... X=unused/undefined
Definition: pixfmt.h:227
coeff
static const double coeff[2][5]
Definition: vf_owdenoise.c:73
P_NRM
@ P_NRM
Definition: preserve_color.h:32
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
int
int
Definition: ffmpeg_filter.c:156
Range::in_max
double in_max
Definition: vf_colorlevels.c:37
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:233
Range::out_max
double out_max
Definition: vf_colorlevels.c:38
R
#define R
Definition: vf_colorlevels.c:31