From patchwork Fri Aug 4 08:23:55 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marton Balint X-Patchwork-Id: 4621 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.46.211 with SMTP id u202csp1967952vsu; Fri, 4 Aug 2017 01:24:19 -0700 (PDT) X-Received: by 10.28.0.6 with SMTP id 6mr860490wma.37.1501835059241; Fri, 04 Aug 2017 01:24:19 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1501835059; cv=none; d=google.com; s=arc-20160816; b=wTyF0u5DUv8QgZEH13bBuOYH5nkwbpbV2x7I/Ybe0fODF59i7+HWjaFu+PMgOxrFbp E243Ox6LCKHGgVZ+DmURujz+BN1vlfvOdPtWokD530q6WHaqzM/dWvnqJrdSYR5Q/I3O wW45LN7wX7HJPMJb5PRNFwFSWbum7MevEOOfJEFRX8o6L1kwspOHVB5RbwrVXYcOtxfh LqP8sJURcjB2D+f7MkiSnKnsN4vi+yVMleW2pI/3noMXmLaD6DI3ucAz2TBGzvG5yjQf YLaCKmRZ6cZFJyeSp3oehgeMbQzJqtBY4P0zVd+bCMptuMXke0INSGTNuMtsvtHW/e9n AFIw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:message-id:date:to:from:delivered-to :arc-authentication-results; bh=HkMbkd6klyi5ZGRO3cua0tuXFzPZ0MzgQlG7xWwNjac=; b=a4takg3DEVz9YtzLc02LLxW8tamq/DgalnlAon/rNx5dwJ4MwAp5h+a7/dOCDrwja7 A8dGJEWFR+oSHihgCRvjskozNfNUCyCKqfwMp/HLJ8UVvf1eF7YaGxgPQcYLyLTD6ceE X2SJl+m8+2FNnvupNSiVLNHnlHTrUlEnH7yyOQ/wgnqv2TwNj0Hzq4DaZ9pCAsQPtkIl CRSrx0jQmr7PN3pimzpt0w0ZXJTHuPcmY03dqRHBuHkS98ci9FKW0pH4cDT8AEaYDFQk Cqo/jBo439c7SGZs/T11oktWEpU0WA6u2w+GtoMzU6BkCNbfs4uM4eiOo8JKwIUgskjH FL8g== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id j38si3114928wre.394.2017.08.04.01.24.18; Fri, 04 Aug 2017 01:24:19 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 1C754689760; Fri, 4 Aug 2017 11:24:15 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from iq.passwd.hu (unknown [217.27.212.140]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id CA56A680A8F for ; Fri, 4 Aug 2017 11:24:08 +0300 (EEST) Received: from localhost (localhost [127.0.0.1]) by iq.passwd.hu (Postfix) with ESMTP id 313A710182D; Fri, 4 Aug 2017 10:24:03 +0200 (CEST) X-Virus-Scanned: amavisd-new at passwd.hu Received: from iq.passwd.hu ([127.0.0.1]) by localhost (iq.passwd.hu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id j8s848poiwb7; Fri, 4 Aug 2017 10:24:01 +0200 (CEST) Received: from bluegene.passwd.hu (localhost [127.0.0.1]) by iq.passwd.hu (Postfix) with ESMTP id 8323D1017A3; Fri, 4 Aug 2017 10:24:01 +0200 (CEST) From: Marton Balint To: ffmpeg-devel@ffmpeg.org Date: Fri, 4 Aug 2017 10:23:55 +0200 Message-Id: <20170804082355.12557-1-cus@passwd.hu> X-Mailer: git-send-email 2.13.1 Subject: [FFmpeg-devel] [PATCH] avfilter/vf_overlay: fix alpha blending for planar formats with a transparent background 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: Marton Balint MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" When the background had an alpha channel, the old code in blend_plane calculated premultiplied alpha from the destination plane colors instead of the destination alpha. Also the calculation of the output alpha should only happen after the color planes are already finished. Fixes output of: ffplay -f lavfi "testsrc2=alpha=32[a];color=black[b];[b][a]overlay[out0]" Signed-off-by: Marton Balint --- libavfilter/vf_overlay.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c index ad292a61c1..52f09fae1f 100644 --- a/libavfilter/vf_overlay.c +++ b/libavfilter/vf_overlay.c @@ -508,7 +508,7 @@ static av_always_inline void blend_plane(AVFilterContext *ctx, int dst_hp = AV_CEIL_RSHIFT(dst_h, vsub); int yp = y>>vsub; int xp = x>>hsub; - uint8_t *s, *sp, *d, *dp, *a, *ap; + uint8_t *s, *sp, *d, *dp, *dap, *a, *da, *ap; int jmax, j, k, kmax; j = FFMAX(-yp, 0); @@ -517,12 +517,14 @@ static av_always_inline void blend_plane(AVFilterContext *ctx, + (yp+j) * dst->linesize[dst_plane] + dst_offset; ap = src->data[3] + (j<linesize[3]; + dap = dst->data[3] + ((yp+j) << vsub) * dst->linesize[3]; for (jmax = FFMIN(-yp + dst_hp, src_hp); j < jmax; j++) { k = FFMAX(-xp, 0); d = dp + (xp+k) * dst_step; s = sp + k; a = ap + (k<linesize[3]] + - d[1] + d[src->linesize[3]+1]) >> 2; + alpha_d = (da[0] + da[dst->linesize[3]] + + da[1] + da[dst->linesize[3]+1]) >> 2; } else if (hsub || vsub) { alpha_h = hsub && k+1 < src_wp ? - (d[0] + d[1]) >> 1 : d[0]; + (da[0] + da[1]) >> 1 : da[0]; alpha_v = vsub && j+1 < src_hp ? - (d[0] + d[src->linesize[3]]) >> 1 : d[0]; + (da[0] + da[dst->linesize[3]]) >> 1 : da[0]; alpha_d = (alpha_v + alpha_h) >> 1; } else - alpha_d = d[0]; + alpha_d = da[0]; alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d); } *d = FAST_DIV255(*d * (255 - alpha) + *s * alpha); s++; d += dst_step; + da += 1 << hsub; a += 1 << hsub; } dp += dst->linesize[dst_plane]; sp += src->linesize[i]; ap += (1 << vsub) * src->linesize[3]; + dap += (1 << vsub) * dst->linesize[3]; } } @@ -622,15 +626,15 @@ static av_always_inline void blend_image_yuv(AVFilterContext *ctx, const int dst_w = dst->width; const int dst_h = dst->height; - if (main_has_alpha) - alpha_composite(src, dst, src_w, src_h, dst_w, dst_h, x, y); - blend_plane(ctx, dst, src, src_w, src_h, dst_w, dst_h, 0, 0, 0, x, y, main_has_alpha, s->main_desc->comp[0].plane, s->main_desc->comp[0].offset, s->main_desc->comp[0].step); blend_plane(ctx, dst, src, src_w, src_h, dst_w, dst_h, 1, hsub, vsub, x, y, main_has_alpha, s->main_desc->comp[1].plane, s->main_desc->comp[1].offset, s->main_desc->comp[1].step); blend_plane(ctx, dst, src, src_w, src_h, dst_w, dst_h, 2, hsub, vsub, x, y, main_has_alpha, s->main_desc->comp[2].plane, s->main_desc->comp[2].offset, s->main_desc->comp[2].step); + + if (main_has_alpha) + alpha_composite(src, dst, src_w, src_h, dst_w, dst_h, x, y); } static av_always_inline void blend_image_planar_rgb(AVFilterContext *ctx, @@ -645,15 +649,15 @@ static av_always_inline void blend_image_planar_rgb(AVFilterContext *ctx, const int dst_w = dst->width; const int dst_h = dst->height; - if (main_has_alpha) - alpha_composite(src, dst, src_w, src_h, dst_w, dst_h, x, y); - blend_plane(ctx, dst, src, src_w, src_h, dst_w, dst_h, 0, 0, 0, x, y, main_has_alpha, s->main_desc->comp[1].plane, s->main_desc->comp[1].offset, s->main_desc->comp[1].step); blend_plane(ctx, dst, src, src_w, src_h, dst_w, dst_h, 1, hsub, vsub, x, y, main_has_alpha, s->main_desc->comp[2].plane, s->main_desc->comp[2].offset, s->main_desc->comp[2].step); blend_plane(ctx, dst, src, src_w, src_h, dst_w, dst_h, 2, hsub, vsub, x, y, main_has_alpha, s->main_desc->comp[0].plane, s->main_desc->comp[0].offset, s->main_desc->comp[0].step); + + if (main_has_alpha) + alpha_composite(src, dst, src_w, src_h, dst_w, dst_h, x, y); } static void blend_image_yuv420(AVFilterContext *ctx, AVFrame *dst, const AVFrame *src, int x, int y)