Commit 59520f06 authored by Paul B Mahol's avatar Paul B Mahol

avfilter/vf_colorchannelmixer: add float formats support

parent 835446a8
...@@ -21,10 +21,21 @@ ...@@ -21,10 +21,21 @@
#include <float.h> #include <float.h>
#undef pixel #undef pixel
#undef cpixel
#undef ROUND
#if DEPTH == 8 #if DEPTH == 8
#define pixel uint8_t #define pixel uint8_t
#define cpixel int
#define ROUND lrintf
#elif DEPTH == 16 #elif DEPTH == 16
#define pixel uint16_t #define pixel uint16_t
#define cpixel int
#define ROUND lrintf
#else
#define NOP(x) (x)
#define pixel float
#define cpixel float
#define ROUND NOP
#endif #endif
#undef fn #undef fn
...@@ -60,8 +71,22 @@ static av_always_inline int fn(filter_slice_rgba_planar)(AVFilterContext *ctx, v ...@@ -60,8 +71,22 @@ static av_always_inline int fn(filter_slice_rgba_planar)(AVFilterContext *ctx, v
const pixel gin = srcg[j]; const pixel gin = srcg[j];
const pixel bin = srcb[j]; const pixel bin = srcb[j];
const pixel ain = have_alpha ? srca[j] : 0; const pixel ain = have_alpha ? srca[j] : 0;
int rout, gout, bout; cpixel rout, gout, bout;
#if DEPTH == 32
rout = s->rr * rin +
s->rg * gin +
s->rb * bin +
(have_alpha == 1 ? s->ra * ain : 0);
gout = s->gr * rin +
s->gg * gin +
s->gb * bin +
(have_alpha == 1 ? s->ga * ain : 0);
bout = s->br * rin +
s->bg * gin +
s->bb * bin +
(have_alpha == 1 ? s->ba * ain : 0);
#else
rout = s->lut[R][R][rin] + rout = s->lut[R][R][rin] +
s->lut[R][G][gin] + s->lut[R][G][gin] +
s->lut[R][B][bin] + s->lut[R][B][bin] +
...@@ -74,31 +99,52 @@ static av_always_inline int fn(filter_slice_rgba_planar)(AVFilterContext *ctx, v ...@@ -74,31 +99,52 @@ static av_always_inline int fn(filter_slice_rgba_planar)(AVFilterContext *ctx, v
s->lut[B][G][gin] + s->lut[B][G][gin] +
s->lut[B][B][bin] + s->lut[B][B][bin] +
(have_alpha == 1 ? s->lut[B][A][ain] : 0); (have_alpha == 1 ? s->lut[B][A][ain] : 0);
#endif
if (pc) { if (pc) {
float frout = av_clipf(rout, 0.f, max); float frout, fgout, fbout, lin, lout;
float fgout = av_clipf(gout, 0.f, max);
float fbout = av_clipf(bout, 0.f, max); #if DEPTH < 32
float lin, lout; frout = av_clipf(rout, 0.f, max);
fgout = av_clipf(gout, 0.f, max);
fbout = av_clipf(bout, 0.f, max);
#else
frout = rout;
fgout = gout;
fbout = bout;
#endif
preserve_color(s->preserve_color, rin, gin, bin, preserve_color(s->preserve_color, rin, gin, bin,
rout, gout, bout, max, &lin, &lout); rout, gout, bout, max, &lin, &lout);
preservel(&frout, &fgout, &fbout, lin, lout, max); preservel(&frout, &fgout, &fbout, lin, lout, max);
rout = lrintf(lerpf(rout, frout, pa)); rout = ROUND(lerpf(rout, frout, pa));
gout = lrintf(lerpf(gout, fgout, pa)); gout = ROUND(lerpf(gout, fgout, pa));
bout = lrintf(lerpf(bout, fbout, pa)); bout = ROUND(lerpf(bout, fbout, pa));
} }
#if DEPTH < 32
dstr[j] = av_clip_uintp2(rout, depth); dstr[j] = av_clip_uintp2(rout, depth);
dstg[j] = av_clip_uintp2(gout, depth); dstg[j] = av_clip_uintp2(gout, depth);
dstb[j] = av_clip_uintp2(bout, depth); dstb[j] = av_clip_uintp2(bout, depth);
#else
dstr[j] = rout;
dstg[j] = gout;
dstb[j] = bout;
#endif
if (have_alpha == 1) { if (have_alpha == 1) {
#if DEPTH < 32
dsta[j] = av_clip_uintp2(s->lut[A][R][rin] + dsta[j] = av_clip_uintp2(s->lut[A][R][rin] +
s->lut[A][G][gin] + s->lut[A][G][gin] +
s->lut[A][B][bin] + s->lut[A][B][bin] +
s->lut[A][A][ain], depth); s->lut[A][A][ain], depth);
#else
dsta[j] = s->ar * rin +
s->ag * gin +
s->ab * bin +
s->aa * ain;
#endif
} }
} }
...@@ -115,6 +161,8 @@ static av_always_inline int fn(filter_slice_rgba_planar)(AVFilterContext *ctx, v ...@@ -115,6 +161,8 @@ static av_always_inline int fn(filter_slice_rgba_planar)(AVFilterContext *ctx, v
return 0; return 0;
} }
#if DEPTH < 32
static av_always_inline int fn(filter_slice_rgba_packed)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs, static av_always_inline int fn(filter_slice_rgba_packed)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs,
int have_alpha, int step, int pc, int depth) int have_alpha, int step, int pc, int depth)
{ {
...@@ -191,3 +239,5 @@ static av_always_inline int fn(filter_slice_rgba_packed)(AVFilterContext *ctx, v ...@@ -191,3 +239,5 @@ static av_always_inline int fn(filter_slice_rgba_packed)(AVFilterContext *ctx, v
return 0; return 0;
} }
#endif
...@@ -77,6 +77,10 @@ static void preservel(float *r, float *g, float *b, float lin, float lout, float ...@@ -77,6 +77,10 @@ static void preservel(float *r, float *g, float *b, float lin, float lout, float
#define DEPTH 16 #define DEPTH 16
#include "colorchannelmixer_template.c" #include "colorchannelmixer_template.c"
#undef DEPTH
#define DEPTH 32
#include "colorchannelmixer_template.c"
#define OFFSET(x) offsetof(ColorChannelMixerContext, x) #define OFFSET(x) offsetof(ColorChannelMixerContext, x)
#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
...@@ -125,6 +129,7 @@ static const enum AVPixelFormat pix_fmts[] = { ...@@ -125,6 +129,7 @@ static const enum AVPixelFormat pix_fmts[] = {
AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRAP12,
AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP14,
AV_PIX_FMT_GBRP16, AV_PIX_FMT_GBRAP16, AV_PIX_FMT_GBRP16, AV_PIX_FMT_GBRAP16,
AV_PIX_FMT_GBRPF32, AV_PIX_FMT_GBRAPF32,
AV_PIX_FMT_NONE AV_PIX_FMT_NONE
}; };
...@@ -278,6 +283,26 @@ static int filter_slice_rgb0_pl(AVFilterContext *ctx, void *arg, int jobnr, int ...@@ -278,6 +283,26 @@ static int filter_slice_rgb0_pl(AVFilterContext *ctx, void *arg, int jobnr, int
return filter_slice_rgba_packed_8(ctx, arg, jobnr, nb_jobs, -1, 4, 1, 8); return filter_slice_rgba_packed_8(ctx, arg, jobnr, nb_jobs, -1, 4, 1, 8);
} }
static int filter_slice_gbrp32(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
{
return filter_slice_rgba_planar_32(ctx, arg, jobnr, nb_jobs, 0, 1, 0);
}
static int filter_slice_gbrap32(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
{
return filter_slice_rgba_planar_32(ctx, arg, jobnr, nb_jobs, 1, 1, 0);
}
static int filter_slice_gbrp32_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
{
return filter_slice_rgba_planar_32(ctx, arg, jobnr, nb_jobs, 0, 1, 1);
}
static int filter_slice_gbrap32_pl(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
{
return filter_slice_rgba_planar_32(ctx, arg, jobnr, nb_jobs, 1, 1, 1);
}
static int config_output(AVFilterLink *outlink) static int config_output(AVFilterLink *outlink)
{ {
AVFilterContext *ctx = outlink->src; AVFilterContext *ctx = outlink->src;
...@@ -391,6 +416,14 @@ static int config_output(AVFilterLink *outlink) ...@@ -391,6 +416,14 @@ static int config_output(AVFilterLink *outlink)
s->filter_slice[0] = filter_slice_gbrap16; s->filter_slice[0] = filter_slice_gbrap16;
s->filter_slice[1] = filter_slice_gbrap16_pl; s->filter_slice[1] = filter_slice_gbrap16_pl;
break; break;
case AV_PIX_FMT_GBRPF32:
s->filter_slice[0] = filter_slice_gbrp32;
s->filter_slice[1] = filter_slice_gbrp32_pl;
break;
case AV_PIX_FMT_GBRAPF32:
s->filter_slice[0] = filter_slice_gbrap32;
s->filter_slice[1] = filter_slice_gbrap32_pl;
break;
} }
return 0; return 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment