X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavfilter%2Fvf_premultiply.c;h=e051cadac0ba0a187d6b56fce99d736a584b21dd;hb=ef6a9e5e311f09fa8032974fa4d0c1e166a959bb;hp=a9404b4eb3b56d1806cbc06903d7022b2ec8981b;hpb=0084eed5bffebd7f3915bc0f9eba7350e8bc0ef7;p=ffmpeg diff --git a/libavfilter/vf_premultiply.c b/libavfilter/vf_premultiply.c index a9404b4eb3b..e051cadac0b 100644 --- a/libavfilter/vf_premultiply.c +++ b/libavfilter/vf_premultiply.c @@ -73,16 +73,16 @@ static int query_formats(AVFilterContext *ctx) AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV444P14, AV_PIX_FMT_YUV444P16, AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, - AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, + AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, AV_PIX_FMT_GBRPF32, AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY14, AV_PIX_FMT_GRAY16, AV_PIX_FMT_NONE }; static const enum AVPixelFormat alpha_pix_fmts[] = { AV_PIX_FMT_YUVA444P, - AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUVA444P16, + AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUVA444P12, AV_PIX_FMT_YUVA444P16, AV_PIX_FMT_GBRAP, - AV_PIX_FMT_GBRAP10, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP16, + AV_PIX_FMT_GBRAP10, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP16, AV_PIX_FMT_GBRAPF32, AV_PIX_FMT_NONE }; @@ -186,7 +186,7 @@ static void premultiply16yuv(const uint8_t *mmsrc, const uint8_t *aasrc, for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { - dst[x] = ((((msrc[x] - half) * (((asrc[x] >> 1) & 1) + asrc[x]))) >> shift) + half; + dst[x] = ((((msrc[x] - half) * (int64_t)(((asrc[x] >> 1) & 1) + asrc[x]))) >> shift) + half; } dst += dlinesize / 2; @@ -209,7 +209,7 @@ static void premultiply16offset(const uint8_t *mmsrc, const uint8_t *aasrc, for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { - dst[x] = ((((msrc[x] - offset) * (((asrc[x] >> 1) & 1) + asrc[x])) + half) >> shift) + offset; + dst[x] = ((((msrc[x] - offset) * (int64_t)(((asrc[x] >> 1) & 1) + asrc[x])) + half) >> shift) + offset; } dst += dlinesize / 2; @@ -218,6 +218,54 @@ static void premultiply16offset(const uint8_t *mmsrc, const uint8_t *aasrc, } } +static void premultiplyf32(const uint8_t *mmsrc, const uint8_t *aasrc, + uint8_t *ddst, + ptrdiff_t mlinesize, ptrdiff_t alinesize, + ptrdiff_t dlinesize, + int w, int h, + int half, int shift, int offset) +{ + const float *msrc = (const float *)mmsrc; + const float *asrc = (const float *)aasrc; + float *dst = (float *)ddst; + int x, y; + + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + dst[x] = msrc[x] * asrc[x]; + } + + dst += dlinesize / 4; + msrc += mlinesize / 4; + asrc += alinesize / 4; + } +} + +static void premultiplyf32offset(const uint8_t *mmsrc, const uint8_t *aasrc, + uint8_t *ddst, + ptrdiff_t mlinesize, ptrdiff_t alinesize, + ptrdiff_t dlinesize, + int w, int h, + int half, int shift, int offset) +{ + const float *msrc = (const float *)mmsrc; + const float *asrc = (const float *)aasrc; + float *dst = (float *)ddst; + int x, y; + + float offsetf = offset / 65535.0f; + + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + dst[x] = ((msrc[x] - offsetf) * asrc[x]) + offsetf; + } + + dst += dlinesize / 4; + msrc += mlinesize / 4; + asrc += alinesize / 4; + } +} + static void unpremultiply8(const uint8_t *msrc, const uint8_t *asrc, uint8_t *dst, ptrdiff_t mlinesize, ptrdiff_t alinesize, @@ -365,6 +413,62 @@ static void unpremultiply16offset(const uint8_t *mmsrc, const uint8_t *aasrc, } } +static void unpremultiplyf32(const uint8_t *mmsrc, const uint8_t *aasrc, + uint8_t *ddst, + ptrdiff_t mlinesize, ptrdiff_t alinesize, + ptrdiff_t dlinesize, + int w, int h, + int half, int max, int offset) +{ + const float *msrc = (const float *)mmsrc; + const float *asrc = (const float *)aasrc; + + float *dst = (float *)ddst; + int x, y; + + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + if (asrc[x] > 0.0f) + dst[x] = msrc[x] / asrc[x]; + else + dst[x] = msrc[x]; + } + + dst += dlinesize / 4; + msrc += mlinesize / 4; + asrc += alinesize / 4; + } +} + +static void unpremultiplyf32offset(const uint8_t *mmsrc, const uint8_t *aasrc, + uint8_t *ddst, + ptrdiff_t mlinesize, ptrdiff_t alinesize, + ptrdiff_t dlinesize, + int w, int h, + int half, int max, int offset) +{ + const float *msrc = (const float *)mmsrc; + const float *asrc = (const float *)aasrc; + + float *dst = (float *)ddst; + int x, y; + + float offsetf = offset / 65535.0f; + + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + if (asrc[x] > 0.0f) + dst[x] = (msrc[x] - offsetf) / asrc[x] + offsetf; + else + dst[x] = msrc[x]; + } + + dst += dlinesize / 4; + msrc += mlinesize / 4; + asrc += alinesize / 4; + } +} + static int premultiply_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { PreMultiplyContext *s = ctx->priv; @@ -442,6 +546,7 @@ static int filter_frame(AVFilterContext *ctx, case AV_PIX_FMT_YUV444P10: case AV_PIX_FMT_YUVA444P10: case AV_PIX_FMT_YUV444P12: + case AV_PIX_FMT_YUVA444P12: case AV_PIX_FMT_YUV444P14: case AV_PIX_FMT_YUV444P16: case AV_PIX_FMT_YUVA444P16: @@ -458,6 +563,10 @@ static int filter_frame(AVFilterContext *ctx, case AV_PIX_FMT_GBRAP16: s->premultiply[0] = s->premultiply[1] = s->premultiply[2] = limited ? unpremultiply16offset : unpremultiply16; break; + case AV_PIX_FMT_GBRPF32: + case AV_PIX_FMT_GBRAPF32: + s->premultiply[0] = s->premultiply[1] = s->premultiply[2] = limited ? unpremultiplyf32offset : unpremultiplyf32; + break; case AV_PIX_FMT_GRAY8: s->premultiply[0] = limited ? unpremultiply8offset : unpremultiply8; break; @@ -489,6 +598,7 @@ static int filter_frame(AVFilterContext *ctx, case AV_PIX_FMT_YUV444P10: case AV_PIX_FMT_YUVA444P10: case AV_PIX_FMT_YUV444P12: + case AV_PIX_FMT_YUVA444P12: case AV_PIX_FMT_YUV444P14: case AV_PIX_FMT_YUV444P16: case AV_PIX_FMT_YUVA444P16: @@ -505,6 +615,10 @@ static int filter_frame(AVFilterContext *ctx, case AV_PIX_FMT_GBRAP16: s->premultiply[0] = s->premultiply[1] = s->premultiply[2] = limited ? premultiply16offset : premultiply16; break; + case AV_PIX_FMT_GBRPF32: + case AV_PIX_FMT_GBRAPF32: + s->premultiply[0] = s->premultiply[1] = s->premultiply[2] = limited ? premultiplyf32offset: premultiplyf32; + break; case AV_PIX_FMT_GRAY8: s->premultiply[0] = limited ? premultiply8offset : premultiply8; break; @@ -567,7 +681,7 @@ static int config_input(AVFilterLink *inlink) s->width[1] = s->width[2] = AV_CEIL_RSHIFT(inlink->w, hsub); s->width[0] = s->width[3] = inlink->w; - s->depth = desc->comp[0].depth; + s->depth = desc->flags & AV_PIX_FMT_FLAG_FLOAT ? 16 : desc->comp[0].depth; s->max = (1 << s->depth) - 1; s->half = (1 << s->depth) / 2; s->offset = 16 << (s->depth - 8); @@ -639,6 +753,8 @@ static int activate(AVFilterContext *ctx) int ret, status; int64_t pts; + FF_FILTER_FORWARD_STATUS_BACK_ALL(ctx->outputs[0], ctx); + if ((ret = ff_inlink_consume_frame(ctx->inputs[0], &frame)) > 0) { ret = filter_frame(ctx, &out, frame, frame); av_frame_free(&frame); @@ -671,27 +787,19 @@ static av_cold int init(AVFilterContext *ctx) s->inverse = 1; pad.type = AVMEDIA_TYPE_VIDEO; - pad.name = av_strdup("main"); + pad.name = "main"; pad.config_props = config_input; - if (!pad.name) - return AVERROR(ENOMEM); - if ((ret = ff_insert_inpad(ctx, 0, &pad)) < 0) { - av_freep(&pad.name); + if ((ret = ff_insert_inpad(ctx, 0, &pad)) < 0) return ret; - } if (!s->inplace) { pad.type = AVMEDIA_TYPE_VIDEO; - pad.name = av_strdup("alpha"); + pad.name = "alpha"; pad.config_props = NULL; - if (!pad.name) - return AVERROR(ENOMEM); - if ((ret = ff_insert_inpad(ctx, 1, &pad)) < 0) { - av_freep(&pad.name); + if ((ret = ff_insert_inpad(ctx, 1, &pad)) < 0) return ret; - } } return 0;