43 double gr, gg, gb, ga;
44 double br, bg, bb, ba;
45 double ar, ag, ab, aa;
58 #define OFFSET(x) offsetof(ColorChannelMixerContext, x) 59 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM 111 return v0 + (v1 -
v0) * f;
114 static void preservel(
float *
r,
float *
g,
float *
b,
float lin,
float lout)
122 int have_alpha,
int pl)
129 const float sr = s->
sr;
130 const float sg = s->
sg;
131 const float sb = s->
sb;
132 const int slice_start = (out->
height * jobnr) / nb_jobs;
144 for (i = slice_start; i <
slice_end; i++) {
145 for (j = 0; j < out->
width; j++) {
149 const uint8_t ain = have_alpha ? srca[j] : 0;
150 int rout, gout, bout;
156 rout = s->
lut[
R][
R][rin] +
159 (have_alpha == 1 ? s->
lut[
R][
A][ain] : 0);
160 gout = s->
lut[
G][
R][rin] +
163 (have_alpha == 1 ? s->
lut[
G][
A][ain] : 0);
164 bout = s->
lut[
B][
R][rin] +
167 (have_alpha == 1 ? s->
lut[
B][
A][ain] : 0);
170 float frout = rout / sr;
171 float fgout = gout / sg;
172 float fbout = bout / sb;
173 float lout =
FFMAX3(frout, fgout, fbout) +
FFMIN3(frout, fgout, fbout);
175 preservel(&frout, &fgout, &fbout, lin, lout);
182 dstr[j] = av_clip_uint8(rout);
183 dstg[j] = av_clip_uint8(gout);
184 dstb[j] = av_clip_uint8(bout);
186 if (have_alpha == 1) {
187 dsta[j] = av_clip_uint8(s->
lut[
A][
R][rin] +
208 int have_alpha,
int depth,
int pl)
215 const float sr = s->
sr;
216 const float sg = s->
sg;
217 const float sb = s->
sb;
218 const int slice_start = (out->
height * jobnr) / nb_jobs;
220 const uint16_t *srcg = (
const uint16_t *)(in->
data[0] + slice_start * in->
linesize[0]);
221 const uint16_t *srcb = (
const uint16_t *)(in->
data[1] + slice_start * in->
linesize[1]);
222 const uint16_t *srcr = (
const uint16_t *)(in->
data[2] + slice_start * in->
linesize[2]);
223 const uint16_t *srca = (
const uint16_t *)(in->
data[3] + slice_start * in->
linesize[3]);
224 uint16_t *dstg = (uint16_t *)(out->
data[0] + slice_start * out->
linesize[0]);
225 uint16_t *dstb = (uint16_t *)(out->
data[1] + slice_start * out->
linesize[1]);
226 uint16_t *dstr = (uint16_t *)(out->
data[2] + slice_start * out->
linesize[2]);
227 uint16_t *dsta = (uint16_t *)(out->
data[3] + slice_start * out->
linesize[3]);
230 for (i = slice_start; i <
slice_end; i++) {
231 for (j = 0; j < out->
width; j++) {
232 const uint16_t rin = srcr[j];
233 const uint16_t gin = srcg[j];
234 const uint16_t bin = srcb[j];
235 const uint16_t ain = have_alpha ? srca[j] : 0;
236 int rout, gout, bout;
242 rout = s->
lut[
R][
R][rin] +
245 (have_alpha == 1 ? s->
lut[
R][
A][ain] : 0);
246 gout = s->
lut[
G][
R][rin] +
249 (have_alpha == 1 ? s->
lut[
G][
A][ain] : 0);
250 bout = s->
lut[
B][
R][rin] +
253 (have_alpha == 1 ? s->
lut[
B][
A][ain] : 0);
256 float frout = rout / sr;
257 float fgout = gout / sg;
258 float fbout = bout / sb;
259 float lout =
FFMAX3(frout, fgout, fbout) +
FFMIN3(frout, fgout, fbout);
261 preservel(&frout, &fgout, &fbout, lin, lout);
268 dstr[j] = av_clip_uintp2(rout, depth);
269 dstg[j] = av_clip_uintp2(gout, depth);
270 dstb[j] = av_clip_uintp2(bout, depth);
272 if (have_alpha == 1) {
273 dsta[j] = av_clip_uintp2(s->
lut[
A][
R][rin] +
276 s->
lut[
A][
A][ain], depth);
394 int have_alpha,
int step,
int pl)
401 const float sr = s->
sr;
402 const float sg = s->
sg;
403 const float sb = s->
sb;
404 const int slice_start = (out->
height * jobnr) / nb_jobs;
414 for (i = slice_start; i <
slice_end; i++) {
419 const uint8_t rin = src[j + roffset];
420 const uint8_t gin = src[j + goffset];
421 const uint8_t bin = src[j + boffset];
422 const uint8_t ain = src[j + aoffset];
423 int rout, gout, bout;
429 rout = s->
lut[
R][
R][rin] +
432 (have_alpha == 1 ? s->
lut[
R][
A][ain] : 0);
433 gout = s->
lut[
G][
R][rin] +
436 (have_alpha == 1 ? s->
lut[
G][
A][ain] : 0);
437 bout = s->
lut[
B][
R][rin] +
440 (have_alpha == 1 ? s->
lut[
B][
A][ain] : 0);
443 float frout = rout / sr;
444 float fgout = gout / sg;
445 float fbout = bout / sb;
446 float lout =
FFMAX3(frout, fgout, fbout) +
FFMIN3(frout, fgout, fbout);
448 preservel(&frout, &fgout, &fbout, lin, lout);
455 dst[j + roffset] = av_clip_uint8(rout);
456 dst[j + goffset] = av_clip_uint8(gout);
457 dst[j + boffset] = av_clip_uint8(bout);
459 if (have_alpha == 1) {
460 dst[j + aoffset] = av_clip_uint8(s->
lut[
A][
R][rin] +
464 }
else if (have_alpha == -1 && in != out)
465 dst[j + aoffset] = 0;
476 int have_alpha,
int step,
int pl)
483 const float sr = s->
sr;
484 const float sg = s->
sg;
485 const float sb = s->
sb;
486 const int slice_start = (out->
height * jobnr) / nb_jobs;
496 for (i = slice_start; i <
slice_end; i++) {
497 const uint16_t *
src = (
const uint16_t *)srcrow;
498 uint16_t *
dst = (uint16_t *)dstrow;
501 const uint16_t rin = src[j + roffset];
502 const uint16_t gin = src[j + goffset];
503 const uint16_t bin = src[j + boffset];
504 const uint16_t ain = src[j + aoffset];
505 int rout, gout, bout;
511 rout = s->
lut[
R][
R][rin] +
514 (have_alpha == 1 ? s->
lut[
R][
A][ain] : 0);
515 gout = s->
lut[
G][
R][rin] +
518 (have_alpha == 1 ? s->
lut[
G][
A][ain] : 0);
519 bout = s->
lut[
B][
R][rin] +
522 (have_alpha == 1 ? s->
lut[
B][
A][ain] : 0);
525 float frout = rout / sr;
526 float fgout = gout / sg;
527 float fbout = bout / sb;
528 float lout =
FFMAX3(frout, fgout, fbout) +
FFMIN3(frout, fgout, fbout);
530 preservel(&frout, &fgout, &fbout, lin, lout);
537 dst[j + roffset] = av_clip_uint16(rout);
538 dst[j + goffset] = av_clip_uint16(gout);
539 dst[j + boffset] = av_clip_uint16(bout);
541 if (have_alpha == 1) {
542 dst[j + aoffset] = av_clip_uint16(s->
lut[
A][
R][rin] +
622 for (i = 0; i < 4; i++)
623 for (j = 0; j < 4; j++, buffer +=
size)
624 s->
lut[i][j] = buffer;
631 if (
fabs(s->
sr) <= DBL_EPSILON)
634 if (
fabs(s->
sg) <= DBL_EPSILON)
637 if (
fabs(s->
sb) <= DBL_EPSILON)
640 for (i = 0; i <
size; i++) {
662 switch (outlink->
format) {
767 char *res,
int res_len,
int flags)
803 .
name =
"colorchannelmixer",
806 .priv_class = &colorchannelmixer_class,
809 .
inputs = colorchannelmixer_inputs,
810 .
outputs = colorchannelmixer_outputs,
AVFILTER_DEFINE_CLASS(colorchannelmixer)
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
This structure describes decoded (raw) audio or video data.
static av_always_inline int filter_slice_rgba_planar(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs, int have_alpha, int pl)
static int query_formats(AVFilterContext *ctx)
#define AV_PIX_FMT_GBRAP10
Main libavfilter public API header.
packed RGB 8:8:8, 24bpp, RGBRGB...
#define AV_PIX_FMT_RGBA64
int h
agreed upon image height
static int filter_slice_rgba(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
#define AV_PIX_FMT_GBRP10
static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
#define AV_PIX_FMT_BGRA64
static int filter_slice_gbrap10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int filter_slice_gbrap10_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
packed BGR 8:8:8, 32bpp, XBGRXBGR... X=unused/undefined
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
static int filter_slice_rgb48_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int filter_slice_rgb0(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static float lerpf(float v0, float v1, float f)
#define AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
Some filters support a generic "enable" expression option that can be used to enable or disable a fil...
static int filter_slice_gbrp12(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
const char * name
Pad name.
static int filter_slice_gbrp9(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
double preserve_lightness
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
int(* filter_slice[2])(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined
static int filter_slice_rgb24_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int filter_slice_gbrap12(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static const AVFilterPad colorchannelmixer_inputs[]
static int filter_slice_rgba64_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
static int filter_slice_gbrp14(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int filter_slice_gbrp14_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int filter_slice_gbrap16_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static av_always_inline int filter_slice_rgba16_planar(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs, int have_alpha, int depth, int pl)
static int filter_slice_gbrap(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
A filter pad used for either input or output.
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
A link between two filters.
static void preservel(float *r, float *g, float *b, float lin, float lout)
static int filter_slice_rgba_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static __device__ float fabs(float a)
static const AVOption colorchannelmixer_options[]
static int filter_slice_gbrp9_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
static int filter_slice_gbrp16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
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...
void * priv
private data for use by the filter
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
static int filter_slice_gbrp(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
#define AV_PIX_FMT_GBRAP12
static int filter_slice_rgb48(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
#define AV_PIX_FMT_GBRAP16
static av_cold void uninit(AVFilterContext *ctx)
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
static int filter_slice_gbrap12_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
int w
agreed upon image width
static const AVFilterPad colorchannelmixer_outputs[]
#define AV_PIX_FMT_GBRP16
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
static int filter_slice_gbrp10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int filter_slice_gbrp_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int filter_slice_gbrap_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int config_output(AVFilterLink *outlink)
packed RGB 8:8:8, 24bpp, BGRBGR...
AVFilterContext * src
source filter
static int filter_slice_gbrp12_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
#define AV_PIX_FMT_GBRP14
static const AVFilterPad outputs[]
int format
agreed upon media format
int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt)
static int filter_slice_rgb24(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
int av_frame_is_writable(AVFrame *frame)
Check if the frame data is writable.
Used for passing data between threads.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
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 inputs
Describe the class of an AVClass context structure.
packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined
const char * name
Filter name.
AVFilterLink ** outputs
array of pointers to output links
static enum AVPixelFormat pix_fmts[]
#define AV_PIX_FMT_GBRP12
#define flags(name, subs,...)
AVFilterInternal * internal
An opaque struct for libavfilter internal use.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
static int filter_slice_gbrap16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
AVFilter ff_vf_colorchannelmixer
planar GBRA 4:4:4:4 32bpp
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
avfilter_execute_func * execute
static int slice_end(AVCodecContext *avctx, AVFrame *pict)
Handle slice ends.
AVFilterContext * dst
dest filter
const AVPixFmtDescriptor * desc
static int filter_slice_gbrp10_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int filter_slice_gbrp16_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static av_always_inline int filter_slice_rgba16_packed(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs, int have_alpha, int step, int pl)
static av_always_inline int filter_slice_rgba_packed(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs, int have_alpha, int step, int pl)
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
int depth
Number of bits in the component.
static int filter_slice_rgb0_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
packed RGB 8:8:8, 32bpp, XRGBXRGB... X=unused/undefined
AVPixelFormat
Pixel format.
static int filter_slice_rgba64(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.