From patchwork Thu Jun 11 20:27:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gavin Smith X-Patchwork-Id: 20294 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id D87E144ACBE for ; Thu, 11 Jun 2020 23:29:35 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id AAB7168B2E0; Thu, 11 Jun 2020 23:29:35 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mout.kundenserver.de (mout.kundenserver.de [212.227.126.131]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id C8B8668A370 for ; Thu, 11 Jun 2020 23:29:29 +0300 (EEST) Received: from localhost.localdomain ([81.107.188.148]) by mrelayeu.kundenserver.de (mreue010 [212.227.15.163]) with ESMTPA (Nemesis) id 1N5max-1iqAZm0g5T-017ADx; Thu, 11 Jun 2020 22:29:29 +0200 From: Gavin Smith To: ffmpeg-devel@ffmpeg.org Date: Thu, 11 Jun 2020 21:27:31 +0100 Message-Id: <20200611202731.8672-1-gavin.smith@playerbites.com> X-Mailer: git-send-email 2.17.1 X-Provags-ID: V03:K1:j8fZDfxFsBBUnQagsAH/Ne8gs8Z4oXXv3so0Kkzz1IYg1AD9Gxx 90eaY01AO/78wDQeTmnxUlL+IFxTO7lQpyelo+OOa1aik32xQHWGfMC8yJne6k42Hp7n/oK I8v7A4mnTdHW/Ic0/NbHSJlq/U9TOrpprDk4/BKMFocRTN5KYRby3QBnC7PfBR0ytXDE9sI 5LnWiBnT3cxT2uhmQ58WA== X-Spam-Flag: NO X-UI-Out-Filterresults: notjunk:1;V03:K0:9p24VS4Sp48=:dMJGeZp8eW7AbbaknOj62c 0ftZKqJA4YbaOt95EssgoERJ4s/trmUPS3Oi2kcWeCQp+8d3CR30mcVuQgjCyBtwKZaAn14bF WUpVM/7nsjQtbXAVEz0xwdXGmUC4kyC55abUvnWBvO6lWklC3q6rOMuGuVR74zMlBVhfrTANn mjK/RHd7sEn74HJsnpollxENOPwM5/M8mf+wfV8l9YAuRToU9kVPKuGORXgI6EN3JnX+Kx/HA /kF08lyVwvX9qSO/VecwCdfF3pq8jotIV6Wqfz3C5A6qmJCvFxrRgbjIdh6UIJZAsfW5lz6fP EIDX8ahK7n6kKt119t7cPxdpiwxJosCVYQXEx2ij+42zrKWMVxI43CwD/RUhiBzjHOBnb/bCj ps5+OiJRimzMkRXJgZvpnx2R4D5RVa7ZfZgBfrgpNj6r51cMflBPvFjOWuHyppkMOsyt5nOby iNDRfsrgrTbCMTCEKdz9m7N1xVsP44bDApx+Bn7Upoxnthw2wUCwf/Mn0TseZdnUsn6kwbDGj kx81yyk0l2Qrriqa/LyrMcD4s8okzKVEv5gNOgRww5wkctfP1cf5pZjrbtjglB2pnVwFXEBCm FK159WmtK0rAPYIpXca/P/RWPBgpFlHqP63kmZNB93O7ot8135A6/nhSNyIu+hZUG7/BeW9kQ swH9hTWhlu26u1/VSllAF8+wzxgXwAY5RU7AiHzqrLS4u84SLrqtxpsljdgG4zDmEMshsZhOi dXOZhS4G9FgXbqcCaOmQeXfIGnhIRwWVx82xaMnvVgJDxRu2Ikdqy52X8rpdtDbReHxX31CPY 7xB386e2ldFdG0qleAV9nyeJ3F1dq7KcTNpaPAV7DXuY9OgoDamYyKzNSF73HrMzUYblYy6 Subject: [FFmpeg-devel] [PATCH] avfilter/vf_chromakey: The chromakey filter preserves non-opaque alpha transparency. X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Gavin Smith MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" 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); + } } }