mirror of https://git.ffmpeg.org/ffmpeg.git
avfilter/vf_lut: >8 bit depth planar yuv support
Signed-off-by: Paul B Mahol <onemda@gmail.com>
This commit is contained in:
parent
daff49ccf3
commit
b74ebd09c7
|
@ -59,12 +59,13 @@ enum var_name {
|
||||||
|
|
||||||
typedef struct LutContext {
|
typedef struct LutContext {
|
||||||
const AVClass *class;
|
const AVClass *class;
|
||||||
uint8_t lut[4][256]; ///< lookup table for each component
|
uint16_t lut[4][256 * 256]; ///< lookup table for each component
|
||||||
char *comp_expr_str[4];
|
char *comp_expr_str[4];
|
||||||
AVExpr *comp_expr[4];
|
AVExpr *comp_expr[4];
|
||||||
int hsub, vsub;
|
int hsub, vsub;
|
||||||
double var_values[VAR_VARS_NB];
|
double var_values[VAR_VARS_NB];
|
||||||
int is_rgb, is_yuv;
|
int is_rgb, is_yuv;
|
||||||
|
int is_16bit;
|
||||||
int step;
|
int step;
|
||||||
int negate_alpha; /* only used by negate */
|
int negate_alpha; /* only used by negate */
|
||||||
} LutContext;
|
} LutContext;
|
||||||
|
@ -112,7 +113,13 @@ static av_cold void uninit(AVFilterContext *ctx)
|
||||||
AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV440P, \
|
AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV440P, \
|
||||||
AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P, \
|
AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P, \
|
||||||
AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ420P, \
|
AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ420P, \
|
||||||
AV_PIX_FMT_YUVJ440P
|
AV_PIX_FMT_YUVJ440P, \
|
||||||
|
AV_PIX_FMT_YUV444P9LE, AV_PIX_FMT_YUV422P9LE, AV_PIX_FMT_YUV420P9, \
|
||||||
|
AV_PIX_FMT_YUV444P10LE, AV_PIX_FMT_YUV422P10LE, AV_PIX_FMT_YUV420P10LE, AV_PIX_FMT_YUV440P10LE, \
|
||||||
|
AV_PIX_FMT_YUV444P12LE, AV_PIX_FMT_YUV422P12LE, AV_PIX_FMT_YUV420P12LE, AV_PIX_FMT_YUV440P12LE, \
|
||||||
|
AV_PIX_FMT_YUV444P14LE, AV_PIX_FMT_YUV422P14LE, AV_PIX_FMT_YUV420P14LE, \
|
||||||
|
AV_PIX_FMT_YUV444P16LE, AV_PIX_FMT_YUV422P16LE, AV_PIX_FMT_YUV420P16LE, \
|
||||||
|
AV_PIX_FMT_YUVA444P16LE, AV_PIX_FMT_YUVA422P16LE, AV_PIX_FMT_YUVA420P16LE
|
||||||
|
|
||||||
#define RGB_FORMATS \
|
#define RGB_FORMATS \
|
||||||
AV_PIX_FMT_ARGB, AV_PIX_FMT_RGBA, \
|
AV_PIX_FMT_ARGB, AV_PIX_FMT_RGBA, \
|
||||||
|
@ -205,6 +212,7 @@ static int config_props(AVFilterLink *inlink)
|
||||||
|
|
||||||
s->var_values[VAR_W] = inlink->w;
|
s->var_values[VAR_W] = inlink->w;
|
||||||
s->var_values[VAR_H] = inlink->h;
|
s->var_values[VAR_H] = inlink->h;
|
||||||
|
s->is_16bit = desc->comp[0].depth_minus1 > 7;
|
||||||
|
|
||||||
switch (inlink->format) {
|
switch (inlink->format) {
|
||||||
case AV_PIX_FMT_YUV410P:
|
case AV_PIX_FMT_YUV410P:
|
||||||
|
@ -216,10 +224,40 @@ static int config_props(AVFilterLink *inlink)
|
||||||
case AV_PIX_FMT_YUVA420P:
|
case AV_PIX_FMT_YUVA420P:
|
||||||
case AV_PIX_FMT_YUVA422P:
|
case AV_PIX_FMT_YUVA422P:
|
||||||
case AV_PIX_FMT_YUVA444P:
|
case AV_PIX_FMT_YUVA444P:
|
||||||
min[Y] = min[U] = min[V] = 16;
|
case AV_PIX_FMT_YUV420P9LE:
|
||||||
max[Y] = 235;
|
case AV_PIX_FMT_YUV422P9LE:
|
||||||
max[U] = max[V] = 240;
|
case AV_PIX_FMT_YUV444P9LE:
|
||||||
min[A] = 0; max[A] = 255;
|
case AV_PIX_FMT_YUVA420P9LE:
|
||||||
|
case AV_PIX_FMT_YUVA422P9LE:
|
||||||
|
case AV_PIX_FMT_YUVA444P9LE:
|
||||||
|
case AV_PIX_FMT_YUV420P10LE:
|
||||||
|
case AV_PIX_FMT_YUV422P10LE:
|
||||||
|
case AV_PIX_FMT_YUV440P10LE:
|
||||||
|
case AV_PIX_FMT_YUV444P10LE:
|
||||||
|
case AV_PIX_FMT_YUVA420P10LE:
|
||||||
|
case AV_PIX_FMT_YUVA422P10LE:
|
||||||
|
case AV_PIX_FMT_YUVA444P10LE:
|
||||||
|
case AV_PIX_FMT_YUV420P12LE:
|
||||||
|
case AV_PIX_FMT_YUV422P12LE:
|
||||||
|
case AV_PIX_FMT_YUV440P12LE:
|
||||||
|
case AV_PIX_FMT_YUV444P12LE:
|
||||||
|
case AV_PIX_FMT_YUV420P14LE:
|
||||||
|
case AV_PIX_FMT_YUV422P14LE:
|
||||||
|
case AV_PIX_FMT_YUV444P14LE:
|
||||||
|
case AV_PIX_FMT_YUV420P16LE:
|
||||||
|
case AV_PIX_FMT_YUV422P16LE:
|
||||||
|
case AV_PIX_FMT_YUV444P16LE:
|
||||||
|
case AV_PIX_FMT_YUVA420P16LE:
|
||||||
|
case AV_PIX_FMT_YUVA422P16LE:
|
||||||
|
case AV_PIX_FMT_YUVA444P16LE:
|
||||||
|
min[Y] = 16 * (1 << (desc->comp[0].depth_minus1 - 7));
|
||||||
|
min[U] = 16 * (1 << (desc->comp[1].depth_minus1 - 7));
|
||||||
|
min[V] = 16 * (1 << (desc->comp[2].depth_minus1 - 7));
|
||||||
|
min[A] = 0;
|
||||||
|
max[Y] = 235 * (1 << (desc->comp[0].depth_minus1 - 7));
|
||||||
|
max[U] = 240 * (1 << (desc->comp[1].depth_minus1 - 7));
|
||||||
|
max[V] = 240 * (1 << (desc->comp[2].depth_minus1 - 7));
|
||||||
|
max[A] = (1 << (desc->comp[3].depth_minus1 + 1)) - 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
min[0] = min[1] = min[2] = min[3] = 0;
|
min[0] = min[1] = min[2] = min[3] = 0;
|
||||||
|
@ -255,7 +293,7 @@ static int config_props(AVFilterLink *inlink)
|
||||||
s->var_values[VAR_MAXVAL] = max[color];
|
s->var_values[VAR_MAXVAL] = max[color];
|
||||||
s->var_values[VAR_MINVAL] = min[color];
|
s->var_values[VAR_MINVAL] = min[color];
|
||||||
|
|
||||||
for (val = 0; val < 256; val++) {
|
for (val = 0; val < (1 << (desc->comp[0].depth_minus1 + 1)); val++) {
|
||||||
s->var_values[VAR_VAL] = val;
|
s->var_values[VAR_VAL] = val;
|
||||||
s->var_values[VAR_CLIPVAL] = av_clip(val, min[color], max[color]);
|
s->var_values[VAR_CLIPVAL] = av_clip(val, min[color], max[color]);
|
||||||
s->var_values[VAR_NEGVAL] =
|
s->var_values[VAR_NEGVAL] =
|
||||||
|
@ -283,7 +321,6 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
|
||||||
LutContext *s = ctx->priv;
|
LutContext *s = ctx->priv;
|
||||||
AVFilterLink *outlink = ctx->outputs[0];
|
AVFilterLink *outlink = ctx->outputs[0];
|
||||||
AVFrame *out;
|
AVFrame *out;
|
||||||
uint8_t *inrow, *outrow, *inrow0, *outrow0;
|
|
||||||
int i, j, plane, direct = 0;
|
int i, j, plane, direct = 0;
|
||||||
|
|
||||||
if (av_frame_is_writable(in)) {
|
if (av_frame_is_writable(in)) {
|
||||||
|
@ -300,9 +337,10 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
|
||||||
|
|
||||||
if (s->is_rgb) {
|
if (s->is_rgb) {
|
||||||
/* packed */
|
/* packed */
|
||||||
|
uint8_t *inrow, *outrow, *inrow0, *outrow0;
|
||||||
const int w = inlink->w;
|
const int w = inlink->w;
|
||||||
const int h = in->height;
|
const int h = in->height;
|
||||||
const uint8_t (*tab)[256] = (const uint8_t (*)[256])s->lut;
|
const uint16_t (*tab)[256*256] = (const uint16_t (*)[256*256])s->lut;
|
||||||
const int in_linesize = in->linesize[0];
|
const int in_linesize = in->linesize[0];
|
||||||
const int out_linesize = out->linesize[0];
|
const int out_linesize = out->linesize[0];
|
||||||
const int step = s->step;
|
const int step = s->step;
|
||||||
|
@ -326,14 +364,44 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
|
||||||
inrow0 += in_linesize;
|
inrow0 += in_linesize;
|
||||||
outrow0 += out_linesize;
|
outrow0 += out_linesize;
|
||||||
}
|
}
|
||||||
} else {
|
} else if (s->is_16bit) {
|
||||||
/* planar */
|
// planar yuv >8 bit depth
|
||||||
|
uint16_t *inrow, *outrow;
|
||||||
|
|
||||||
for (plane = 0; plane < 4 && in->data[plane] && in->linesize[plane]; plane++) {
|
for (plane = 0; plane < 4 && in->data[plane] && in->linesize[plane]; plane++) {
|
||||||
int vsub = plane == 1 || plane == 2 ? s->vsub : 0;
|
int vsub = plane == 1 || plane == 2 ? s->vsub : 0;
|
||||||
int hsub = plane == 1 || plane == 2 ? s->hsub : 0;
|
int hsub = plane == 1 || plane == 2 ? s->hsub : 0;
|
||||||
int h = FF_CEIL_RSHIFT(inlink->h, vsub);
|
int h = FF_CEIL_RSHIFT(inlink->h, vsub);
|
||||||
int w = FF_CEIL_RSHIFT(inlink->w, hsub);
|
int w = FF_CEIL_RSHIFT(inlink->w, hsub);
|
||||||
const uint8_t *tab = s->lut[plane];
|
const uint16_t *tab = s->lut[plane];
|
||||||
|
const int in_linesize = in->linesize[plane] / 2;
|
||||||
|
const int out_linesize = out->linesize[plane] / 2;
|
||||||
|
|
||||||
|
inrow = (uint16_t *)in ->data[plane];
|
||||||
|
outrow = (uint16_t *)out->data[plane];
|
||||||
|
|
||||||
|
for (i = 0; i < h; i++) {
|
||||||
|
for (j = 0; j < w; j++) {
|
||||||
|
#if HAVE_BIGENDIAN
|
||||||
|
outrow[j] = av_bswap16(tab[av_bswap16(inrow[j])]);
|
||||||
|
#else
|
||||||
|
outrow[j] = tab[inrow[j]];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
inrow += in_linesize;
|
||||||
|
outrow += out_linesize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* planar 8bit depth */
|
||||||
|
uint8_t *inrow, *outrow;
|
||||||
|
|
||||||
|
for (plane = 0; plane < 4 && in->data[plane] && in->linesize[plane]; plane++) {
|
||||||
|
int vsub = plane == 1 || plane == 2 ? s->vsub : 0;
|
||||||
|
int hsub = plane == 1 || plane == 2 ? s->hsub : 0;
|
||||||
|
int h = FF_CEIL_RSHIFT(inlink->h, vsub);
|
||||||
|
int w = FF_CEIL_RSHIFT(inlink->w, hsub);
|
||||||
|
const uint16_t *tab = s->lut[plane];
|
||||||
const int in_linesize = in->linesize[plane];
|
const int in_linesize = in->linesize[plane];
|
||||||
const int out_linesize = out->linesize[plane];
|
const int out_linesize = out->linesize[plane];
|
||||||
|
|
||||||
|
|
|
@ -7,12 +7,32 @@ rgba 7bc854c2698b78af3e9159a19c2d9d21
|
||||||
yuv410p 51b39a0e33f108e652457a26667319ea
|
yuv410p 51b39a0e33f108e652457a26667319ea
|
||||||
yuv411p 9204c5af92aef4922a05f58c1f6c095e
|
yuv411p 9204c5af92aef4922a05f58c1f6c095e
|
||||||
yuv420p 7c43bb0cae8dee633375c89295598508
|
yuv420p 7c43bb0cae8dee633375c89295598508
|
||||||
|
yuv420p10le 1352712dd31cce78bd5441294004cf85
|
||||||
|
yuv420p12le c66f82da9fda458ba3abda057c58e591
|
||||||
|
yuv420p14le e45cb5e2a75bf6143da0b55004767f78
|
||||||
|
yuv420p16le eff54782c51770edfd6b84c958ac7120
|
||||||
|
yuv420p9le 62bf40b1cb97660238c991efa6ef2962
|
||||||
yuv422p 67df35da0c35e54882492b2365438254
|
yuv422p 67df35da0c35e54882492b2365438254
|
||||||
|
yuv422p10le 0158371a800294015def7f0ef66c78ea
|
||||||
|
yuv422p12le bc49d3863ffb89658a17bf8c4fe773b0
|
||||||
|
yuv422p14le b55cb791d286b0b3391fe7481785e5b3
|
||||||
|
yuv422p16le fc3b2ba889ffaf1633000fc774307c33
|
||||||
|
yuv422p9le bb6d5a46073ff4aabfcd2f97416ccb59
|
||||||
yuv440p 5e41adcfc27be4369afd217b61b2ffe3
|
yuv440p 5e41adcfc27be4369afd217b61b2ffe3
|
||||||
|
yuv440p10le 8b49714bba268fb4a79b5a84223ad17a
|
||||||
|
yuv440p12le 15ab4f453238bd9c13b18af81e22f060
|
||||||
yuv444p a2b58590aef88db2c1f14a1a3a3b0359
|
yuv444p a2b58590aef88db2c1f14a1a3a3b0359
|
||||||
|
yuv444p10le c076c20fc808f95b34adb88aca442f48
|
||||||
|
yuv444p12le af8d4dd88169d5cffc2f3fce6333a94c
|
||||||
|
yuv444p14le 93367133e25d088d4535199ed1f1ed58
|
||||||
|
yuv444p16le 800940feec14365ccd9b4863e38f6991
|
||||||
|
yuv444p9le 08cab94dfa6d2a688f9a8cbac8c4b61b
|
||||||
yuva420p 518a380bf1af60ef2ecf4754eec088e9
|
yuva420p 518a380bf1af60ef2ecf4754eec088e9
|
||||||
|
yuva420p16le 72ad4fa535b007d122666ce103ef9c8b
|
||||||
yuva422p 7110ac2e37377b05b6fc5ad967dfabb5
|
yuva422p 7110ac2e37377b05b6fc5ad967dfabb5
|
||||||
|
yuva422p16le e2867210660ada5784a60b4339ac52c0
|
||||||
yuva444p 642f3958f141dece9e99407945e2ef43
|
yuva444p 642f3958f141dece9e99407945e2ef43
|
||||||
|
yuva444p16le ab04ba8acbe38085b0df650d82065eb0
|
||||||
yuvj420p 65bc88887c7f06a6221155ca7f9cfca4
|
yuvj420p 65bc88887c7f06a6221155ca7f9cfca4
|
||||||
yuvj422p ff5baffefc8ffe4547653092fd7da200
|
yuvj422p ff5baffefc8ffe4547653092fd7da200
|
||||||
yuvj440p ef3f27270e60ac06582e3ac7c2f3e6fa
|
yuvj440p ef3f27270e60ac06582e3ac7c2f3e6fa
|
||||||
|
|
Loading…
Reference in New Issue