[FFmpeg-devel] [PATCH] avfilter/vf_chromakey: The chromakey filter preserves non-opaque alpha transparency.
Gavin Smith
gavin.smith at playerbites.com
Thu Jun 11 23:27:31 EEST 2020
This is to address trac ticket #8724. The filter did not preserve alpha transparency. Items that were transparent in the input would appear black on the output or pixels that were semi-tranparent would appear opaque.
---
libavfilter/vf_chromakey.c | 43 ++++++++++++++++++++++----------------
1 file changed, 25 insertions(+), 18 deletions(-)
diff --git a/libavfilter/vf_chromakey.c b/libavfilter/vf_chromakey.c
index 4b1669d084..7206f44441 100644
--- a/libavfilter/vf_chromakey.c
+++ b/libavfilter/vf_chromakey.c
@@ -47,7 +47,7 @@ typedef struct ChromakeyContext {
int jobnr, int nb_jobs);
} ChromakeyContext;
-static uint8_t do_chromakey_pixel(ChromakeyContext *ctx, uint8_t u[9], uint8_t v[9])
+static uint8_t do_chromakey_pixel(ChromakeyContext *ctx, uint8_t a, uint8_t u[9], uint8_t v[9])
{
double diff = 0.0;
int du, dv, i;
@@ -62,13 +62,13 @@ static uint8_t do_chromakey_pixel(ChromakeyContext *ctx, uint8_t u[9], uint8_t v
diff /= 9.0;
if (ctx->blend > 0.0001) {
- return av_clipd((diff - ctx->similarity) / ctx->blend, 0.0, 1.0) * 255.0;
+ return av_clipd((diff - ctx->similarity) / ctx->blend, 0.0, 1.0) * (float)a;
} else {
- return (diff > ctx->similarity) ? 255 : 0;
+ return (diff > ctx->similarity) ? a : 0;
}
}
-static uint16_t do_chromakey_pixel16(ChromakeyContext *ctx, uint16_t u[9], uint16_t v[9])
+static uint16_t do_chromakey_pixel16(ChromakeyContext *ctx, uint16_t a, uint16_t u[9], uint16_t v[9])
{
double max = ctx->max;
double diff = 0.0;
@@ -84,9 +84,9 @@ static uint16_t do_chromakey_pixel16(ChromakeyContext *ctx, uint16_t u[9], uint1
diff /= 9.0;
if (ctx->blend > 0.0001) {
- return av_clipd((diff - ctx->similarity) / ctx->blend, 0.0, 1.0) * max;
+ return av_clipd((diff - ctx->similarity) / ctx->blend, 0.0, 1.0) * (float)a;
} else {
- return (diff > ctx->similarity) ? max : 0;
+ return (diff > ctx->similarity) ? a : 0;
}
}
@@ -131,13 +131,17 @@ static int do_chromakey_slice(AVFilterContext *avctx, void *arg, int jobnr, int
for (y = slice_start; y < slice_end; ++y) {
for (x = 0; x < frame->width; ++x) {
- for (yo = 0; yo < 3; ++yo) {
- for (xo = 0; xo < 3; ++xo) {
- get_pixel_uv(frame, ctx->hsub_log2, ctx->vsub_log2, x + xo - 1, y + yo - 1, &u[yo * 3 + xo], &v[yo * 3 + xo]);
+ uint8_t *a = frame->data[3] + frame->linesize[3] * y;
+ const uint8_t ao = a[x];
+
+ if (ao != 0) {
+ for (yo = 0; yo < 3; ++yo) {
+ for (xo = 0; xo < 3; ++xo) {
+ get_pixel_uv(frame, ctx->hsub_log2, ctx->vsub_log2, x + xo - 1, y + yo - 1, &u[yo * 3 + xo], &v[yo * 3 + xo]);
+ }
}
+ a[x] = do_chromakey_pixel(ctx, ao, u, v);
}
-
- frame->data[3][frame->linesize[3] * y + x] = do_chromakey_pixel(ctx, u, v);
}
}
@@ -163,15 +167,18 @@ static int do_chromakey16_slice(AVFilterContext *avctx, void *arg, int jobnr, in
for (y = slice_start; y < slice_end; ++y) {
for (x = 0; x < frame->width; ++x) {
- uint16_t *dst = (uint16_t *)(frame->data[3] + frame->linesize[3] * y);
-
- for (yo = 0; yo < 3; ++yo) {
- for (xo = 0; xo < 3; ++xo) {
- get_pixel16_uv(frame, ctx->hsub_log2, ctx->vsub_log2, x + xo - 1, y + yo - 1, &u[yo * 3 + xo], &v[yo * 3 + xo]);
+ uint16_t *a = (uint16_t *)(frame->data[3] + frame->linesize[3] * y);
+ const uint16_t ao = a[x];
+
+ if (ao != 0) {
+ for (yo = 0; yo < 3; ++yo) {
+ for (xo = 0; xo < 3; ++xo) {
+ get_pixel16_uv(frame, ctx->hsub_log2, ctx->vsub_log2, x + xo - 1, y + yo - 1, &u[yo * 3 + xo], &v[yo * 3 + xo]);
+ }
}
- }
- dst[x] = do_chromakey_pixel16(ctx, u, v);
+ a[x] = do_chromakey_pixel16(ctx, ao, u, v);
+ }
}
}
--
2.17.1
More information about the ffmpeg-devel
mailing list