56#define OFFSET(x) offsetof(ColorLevelsContext, x)
57#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
104#define DO_COMMON(type, ptype, clip, preserve, planar) \
105 const ThreadData *td = arg; \
106 const int linesize = s->linesize; \
107 const int step = s->step; \
108 const int process_h = td->h; \
109 const int slice_start = ff_slice_pos(process_h, jobnr, nb_jobs); \
110 const int slice_end = ff_slice_pos(process_h, jobnr + 1, nb_jobs); \
111 const int src_linesize = td->src_linesize / sizeof(type); \
112 const int dst_linesize = td->dst_linesize / sizeof(type); \
113 const type *src_r = (const type *)(td->srcrow[R]) + src_linesize * slice_start; \
114 const type *src_g = (const type *)(td->srcrow[G]) + src_linesize * slice_start; \
115 const type *src_b = (const type *)(td->srcrow[B]) + src_linesize * slice_start; \
116 const type *src_a = (const type *)(td->srcrow[A]) + src_linesize * slice_start; \
117 type *dst_r = (type *)(td->dstrow[R]) + src_linesize * slice_start; \
118 type *dst_g = (type *)(td->dstrow[G]) + src_linesize * slice_start; \
119 type *dst_b = (type *)(td->dstrow[B]) + src_linesize * slice_start; \
120 type *dst_a = (type *)(td->dstrow[A]) + src_linesize * slice_start; \
121 const ptype imin_r = s->depth == 32 ? td->fimin[R] : td->imin[R]; \
122 const ptype imin_g = s->depth == 32 ? td->fimin[G] : td->imin[G]; \
123 const ptype imin_b = s->depth == 32 ? td->fimin[B] : td->imin[B]; \
124 const ptype imin_a = s->depth == 32 ? td->fimin[A] : td->imin[A]; \
125 const ptype omin_r = s->depth == 32 ? td->fomin[R] : td->omin[R]; \
126 const ptype omin_g = s->depth == 32 ? td->fomin[G] : td->omin[G]; \
127 const ptype omin_b = s->depth == 32 ? td->fomin[B] : td->omin[B]; \
128 const ptype omin_a = s->depth == 32 ? td->fomin[A] : td->omin[A]; \
129 const float coeff_r = td->coeff[R]; \
130 const float coeff_g = td->coeff[G]; \
131 const float coeff_b = td->coeff[B]; \
132 const float coeff_a = td->coeff[A]; \
134 for (int y = slice_start; y < slice_end; y++) { \
135 for (int x = 0; x < linesize; x += step) { \
136 ptype ir, ig, ib, or, og, ob; \
141 float ratio, icolor, ocolor, max = s->depth==32 ? 1.f : s->max; \
143 or = (ir - imin_r) * coeff_r + omin_r; \
144 og = (ig - imin_g) * coeff_g + omin_g; \
145 ob = (ib - imin_b) * coeff_b + omin_b; \
147 preserve_color(s->preserve_color, ir, ig, ib, or, og, ob, max, \
149 if (ocolor > 0.f) { \
150 ratio = icolor / ocolor; \
157 dst_r[x] = clip(or, depth); \
158 dst_g[x] = clip(og, depth); \
159 dst_b[x] = clip(ob, depth); \
161 dst_r[x] = clip((ir - imin_r) * coeff_r + omin_r, depth); \
162 dst_g[x] = clip((ig - imin_g) * coeff_g + omin_g, depth); \
163 dst_b[x] = clip((ib - imin_b) * coeff_b + omin_b, depth); \
167 for (int x = 0; x < linesize && s->nb_comp == 4; x += step) \
168 dst_a[x] = clip((src_a[x] - imin_a) * coeff_a + omin_a, depth); \
170 src_r += src_linesize; \
171 src_g += src_linesize; \
172 src_b += src_linesize; \
173 src_a += src_linesize; \
175 dst_r += dst_linesize; \
176 dst_g += dst_linesize; \
177 dst_b += dst_linesize; \
178 dst_a += dst_linesize; \
181#define CLIP8(x, depth) av_clip_uint8(x)
182#define CLIP16(x, depth) av_clip_uint16(x)
183#define NOCLIP(x, depth) (x)
195 DO_COMMON(uint16_t,
int,
CLIP16, 0, 0)
231 const int depth = 10;
239 const int depth = 12;
247 const int depth = 14;
284 const int depth = 10;
292 const int depth = 12;
300 const int depth = 14;
325 s->nb_comp =
desc->nb_components;
327 s->depth =
desc->comp[0].depth;
328 s->max = (1 <<
s->depth) - 1;
329 s->bpp = (
desc->comp[0].depth + 7) >> 3;
331 s->linesize = inlink->
w *
s->step;
382 const int step =
s->step;
422 for (
int i = 0;
i <
s->nb_comp;
i++) {
424 const uint8_t
offset =
s->rgba_map[
i];
425 const uint8_t *srcrow = in->
data[0];
428 int omin =
lrint(
r->out_min * UINT8_MAX);
429 int omax =
lrint(
r->out_max * UINT8_MAX);
434 for (
int y = 0; y < inlink->
h; y++) {
435 const uint8_t *
src = srcrow;
437 for (
int x = 0; x <
s->linesize; x += step)
443 srcrow = in->
data[0];
445 for (
int y = 0; y < inlink->
h; y++) {
446 const uint8_t *
src = srcrow;
448 for (
int x = 0; x <
s->linesize; x += step)
462 for (
int i = 0;
i <
s->nb_comp;
i++) {
464 const uint8_t
offset =
s->rgba_map[
i];
465 const uint8_t *srcrow = in->
data[0];
468 int omin =
lrint(
r->out_min * UINT16_MAX);
469 int omax =
lrint(
r->out_max * UINT16_MAX);
474 for (
int y = 0; y < inlink->
h; y++) {
475 const uint16_t *
src = (
const uint16_t *)srcrow;
477 for (
int x = 0; x <
s->linesize; x += step)
483 srcrow = in->
data[0];
485 for (
int y = 0; y < inlink->
h; y++) {
486 const uint16_t *
src = (
const uint16_t *)srcrow;
488 for (
int x = 0; x <
s->linesize; x += step)
502 for (
int i = 0;
i <
s->nb_comp;
i++) {
504 const uint8_t
offset =
s->rgba_map[
i];
505 const uint8_t *srcrow = in->
data[0];
506 float imin =
r->in_min;
507 float imax =
r->in_max;
508 float omin =
r->out_min;
509 float omax =
r->out_max;
514 for (
int y = 0; y < inlink->
h; y++) {
515 const float *
src = (
const float *)srcrow;
517 for (
int x = 0; x <
s->linesize; x += step)
523 srcrow = in->
data[0];
525 for (
int y = 0; y < inlink->
h; y++) {
526 const float *
src = (
const float *)srcrow;
528 for (
int x = 0; x <
s->linesize; x += step)
561 .p.name =
"colorlevels",
563 .p.priv_class = &colorlevels_class,
static int config_input(AVFilterLink *inlink)
const FFFilter ff_vf_colorlevels
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
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.
int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg, int *ret, int nb_jobs)
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Main libavfilter public API header.
#define i(width, name, range_min, range_max)
float fminf(float, float)
float fmaxf(float, float)
static int filter_frame(DBEDecodeContext *s, AVFrame *frame)
int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt)
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
@ AV_OPT_TYPE_INT
Underlying C type is int.
@ AV_OPT_TYPE_DOUBLE
Underlying C type is double.
#define AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
Some filters support a generic "enable" expression option that can be used to enable or disable a fil...
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
int av_frame_is_writable(AVFrame *frame)
Check if the frame data is writable.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
#define FILTER_INPUTS(array)
#define FILTER_OUTPUTS(array)
#define FILTER_PIXFMTS(...)
#define AVFILTER_DEFINE_CLASS(fname)
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
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 ...
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
#define AV_PIX_FMT_FLAG_PLANAR
At least one pixel component is not in the first data plane.
#define AV_PIX_FMT_GBRAP12
#define AV_PIX_FMT_GBRPF32
#define AV_PIX_FMT_GBRAP16
#define AV_PIX_FMT_GBRP10
#define AV_PIX_FMT_RGBA64
#define AV_PIX_FMT_GBRP12
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
@ AV_PIX_FMT_BGR0
packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined
@ AV_PIX_FMT_ARGB
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
@ AV_PIX_FMT_BGRA
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
@ AV_PIX_FMT_ABGR
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
@ AV_PIX_FMT_0BGR
packed BGR 8:8:8, 32bpp, XBGRXBGR... X=unused/undefined
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
@ AV_PIX_FMT_GBRAP
planar GBRA 4:4:4:4 32bpp
@ AV_PIX_FMT_RGB0
packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
@ AV_PIX_FMT_0RGB
packed RGB 8:8:8, 32bpp, XRGBXRGB... X=unused/undefined
#define AV_PIX_FMT_BGRA64
#define AV_PIX_FMT_GBRAP10
#define AV_PIX_FMT_GBRP16
#define AV_PIX_FMT_GBRP14
#define AV_PIX_FMT_GBRAPF32
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)
Describe the class of an AVClass context structure.
A link between two filters.
int w
agreed upon image width
int h
agreed upon image height
AVFilterContext * dst
dest filter
int format
agreed upon media format
A filter pad used for either input or output.
This structure describes decoded (raw) audio or video data.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
int(* colorlevels_slice[2])(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Used for passing data between threads.
const uint8_t * srcrow[4]
static int imin(const int a, const int b)
static int imax(const int a, const int b)
static AVFormatContext * ctx
#define DO_COMMON(type, ptype, clip, preserve, planar)
static const AVOption colorlevels_options[]
static int colorlevels_preserve_slice_8(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int colorlevels_slice_32_planar(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int colorlevels_preserve_slice_16_planar(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int colorlevels_slice_12_planar(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int colorlevels_slice_8(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int colorlevels_slice_16_planar(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int config_input(AVFilterLink *inlink)
static int colorlevels_slice_10_planar(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int colorlevels_slice_8_planar(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int colorlevels_slice_9_planar(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int colorlevels_slice_14_planar(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
static int colorlevels_preserve_slice_16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int colorlevels_slice_16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int colorlevels_preserve_slice_9_planar(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int colorlevels_preserve_slice_8_planar(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int colorlevels_preserve_slice_12_planar(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int colorlevels_preserve_slice_32_planar(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int colorlevels_preserve_slice_14_planar(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int colorlevels_preserve_slice_10_planar(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static const AVFilterPad colorlevels_inputs[]
static const double coeff[2][5]
const AVFilterPad ff_video_default_filterpad[1]
An AVFilterPad array whose only entry has name "default" and is of type AVMEDIA_TYPE_VIDEO.
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.