From patchwork Mon Sep 25 18:04:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Rheinhardt X-Patchwork-Id: 43897 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:2a18:b0:15d:8365:d4b8 with SMTP id e24csp1403229pzh; Mon, 25 Sep 2023 11:04:01 -0700 (PDT) X-Google-Smtp-Source: AGHT+IF1/gwuxsgdhSo9feelFNYaSMUBb0QYwSuTS3e4MBjPUKTDclz1Qw/8JSA1jy9P1hmazo6u X-Received: by 2002:adf:fd4a:0:b0:317:7af4:5294 with SMTP id h10-20020adffd4a000000b003177af45294mr6116781wrs.44.1695665041235; Mon, 25 Sep 2023 11:04:01 -0700 (PDT) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id c4-20020a1709060fc400b00988a6f59292si8642945ejk.600.2023.09.25.11.04.00; Mon, 25 Sep 2023 11:04:01 -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; dkim=neutral (body hash did not verify) header.i=@outlook.com header.s=selector1 header.b=N9sOyGiM; arc=fail (body hash mismatch); 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; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=outlook.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 1FC8168C9B8; Mon, 25 Sep 2023 21:03:57 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from EUR05-AM6-obe.outbound.protection.outlook.com (mail-am6eur05olkn2103.outbound.protection.outlook.com [40.92.91.103]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 9084468C620 for ; Mon, 25 Sep 2023 21:03:50 +0300 (EEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=KgHu5yAX2vh9VHZOCl89dZYiU2/x3k2+dVoERSqvp1VueeORtprz3w+jTCsVFNoXAwLbAyTDWzLyyQ67whz9SGNnhWNHgO2y/WlzKo8pc1OdQi6oHZmEtyj6NrxHMploWK7cJDhPUfMtD38DIGg+T9KYouOpP7elx5bJNhz6HBhmefgB3AY+IdQlkhw9MlvVZLDwi03iBCM0rLskJ+u9eHcrY9c5Fd6+ji25dwSpLfksqI9DaDO3XcxaYx4Xz+TA3oRt4ZUigtsVqUOfvf50rMjMEJM/LimQdhr8CeNNsCopJAyayzl5OElvyPzEZZB6582vO18S18LZ4NiiQoiwHg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=YtZzU5TMXCjZ+HbDFIm+LXj3UmC8pDBm+t4iqxkGHXk=; b=XrY2xQIlwoeTbJ6Ex/YvboHo3dOgR4AsTPII9ejw+Z+AdKtf8J/JrgNzcde21u/WSxpR12Sv+3SuT1fsTzUHt/gjCIfe/SAO6ajeP+NF7DyyLXiYFbmKCh6w19pESnj3UOz7FpVIB/Me/0J/sMjSUVK+3+BASNSrbwemAUfG3VX+K4Pn3O9yeJJAePa4xB2SLAkdg3Q28TBSvFUN+7rv1618DJKKAJRCtxToXG/ENrzAdV8wOYBJC1Ovkr4JVz2IxzStcCz6DXJNx8SN7czNEtdgFOzoCOcJ3U8HN+pz+sIA61WBZW6lVFwRG3awwaQGX5UJyWuneGdD1oRNEQPwAw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none; dmarc=none; dkim=none; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=outlook.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=YtZzU5TMXCjZ+HbDFIm+LXj3UmC8pDBm+t4iqxkGHXk=; b=N9sOyGiMt8Uysd9u/isPZsabIaFMs83lqHs2ja0tCSbHxQ2BAvmXhjB4w1+J3chV7w1YLeO4/IfAPIEm0mSAipr6bOVlyjPMvli2x9ixJPw5c4KZfzWAoPtVLgJOogC8CEr6wgE35rerF2gvjdrY84l7TDLdkOcljOu7i4vMOtziBY0sr/IehFVh5z3OUa/E7bgsSeMoivo22BN9xX3EIsBVjNIQoa/+1L4aBb/y40lOM7kz+ayk077bMpQTqeihFVm0dZpBdjd/uEY+U/Ag5LfNqRVjUaV8YmZRj1urDFLWpQCjppVn56m/waXqUal1b5qEiUyF3YRvBu8+eK2+tQ== Received: from AS8P250MB0744.EURP250.PROD.OUTLOOK.COM (2603:10a6:20b:541::14) by PR3P250MB0290.EURP250.PROD.OUTLOOK.COM (2603:10a6:102:17d::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6813.28; Mon, 25 Sep 2023 18:03:48 +0000 Received: from AS8P250MB0744.EURP250.PROD.OUTLOOK.COM ([fe80::5e01:aea5:d3a8:cafa]) by AS8P250MB0744.EURP250.PROD.OUTLOOK.COM ([fe80::5e01:aea5:d3a8:cafa%3]) with mapi id 15.20.6792.026; Mon, 25 Sep 2023 18:03:48 +0000 From: Andreas Rheinhardt To: ffmpeg-devel@ffmpeg.org Date: Mon, 25 Sep 2023 20:04:50 +0200 Message-ID: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: X-TMN: [Hcj7EOifJ4Z8VscCG0kvxz02Va6/SBDa] X-ClientProxiedBy: ZR0P278CA0083.CHEP278.PROD.OUTLOOK.COM (2603:10a6:910:22::16) To AS8P250MB0744.EURP250.PROD.OUTLOOK.COM (2603:10a6:20b:541::14) X-Microsoft-Original-Message-ID: <20230925180457.2060101-1-andreas.rheinhardt@outlook.com> MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: AS8P250MB0744:EE_|PR3P250MB0290:EE_ X-MS-Office365-Filtering-Correlation-Id: a89c1ede-7938-48b2-43dd-08dbbdf1c476 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: pCXUIP3YnnPme+e369kQbN22djf5rBiCPJN53sK2imS8s4B9Md4kaaOBATj4g7Zfyuh6apSsWSq8HNAAtv7ymSIVBAWzeBwIEHp7FOBal4fKc+Xb8Ld++9krTIrFL1IdlS9r39c8aC/0C32WuQrkx2+NdInMQHz5ocklDBQf9Jilg0iJG3bVsHthuU0G/NFKWh76/H3KSSLyrtQEhIlApzKn+ZvkLRZLLRyqCwvCJQ2nWiG5o0WTYrIxG1Ok9f9iXmAOtgbOBOwLt+TKhOm3N2BzcLoooaUpviwN3vAwBAjpY2QtJT7+Q/t04QPdo8zN+fGLKnoGWRP5EX1E3BfJ/wbV5sacoQGKST5LiibS4uqIUuGuI5MyLt+1fIQ7BNjqBsi3FbfGnJ0u80NJDW5eOMRpQOg0CGrz8h5k9NIivk5laH2hSs3z/FUe7VQQMmAS+52Fy793FiQ0C/8IYleEHii4Gi7TntJ4RlQ36Ja5TkJ6R7AM/TLOVjV3IRfCWxmYJLZyRI0T6DHo9zCXsgPhrOseHjraGiLXSFpR6RaxoUXZnElqmdffjk6Ab/vdq6Zlfof6rM60Jxb7nrMIi5bIlvur2AuB4sU7zInnj7mJR7ZgWwXdINmYicPq0nrejx72 X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: dCfu4ZyeyNDhMqwxngD7jjewVgmNZTmh9nnTm8aePjJ+VIAdV1hH0sQuTdau4uqf53VW+GT5MNuYxM3+hAk0GXFD5vKWbNidDfDz/qBkE9byfLISPk7a2ex/XePaNHvQcWBK/gcwWhTrTtV2FNI3bwha2Gxbv7HDBBryhoJbiemwqeO2PXp/LtM88p/7gXMUMWyOTktTUkGdaByrr3iavPpW/kl3/PptV32qIjO5uQRaEAkN1/gL3U8hIpP/LjrUYGDYO0CMx5n9hONWQ+eWLmZbE9FIi2iQ4LY4ULtI6AIouPJGBb3+SVxIZO8XEN5O2EhSVaF1jTosq6SmJbIOo27mrGEK3ZvrE+LR4xbegXhlqcwsOPc2GAjU793B0+pADIGzd4+yz7/6RkImP4csMZzb/Za/4pQsOiN6HoIkdylguiSSa7wsxKRzmlA6UwEg4GTt+fYmAe2KG+GPodfv+48iXZV3f+PxIC14aQRUAvq35lEmZwmaEWJv98JnxT6bwUhwY5m8Fquh+DCOdXSsDr6sLvIbUjnQ0se/rp9++mZLdVzhc4ueeFu9pzlKzOPKH8WNsHE5MR+RF5b7G87h6QIL0G/jd8IDEA3S75LucPrx3HnnOOt1dMrrdNDUg+5D0ylXCYVXoToqb2X9WA/1WcWVwhgr5divr/DOXsJVuVqc4uaHDobUEyynZZoV4Vn5FfPGLcn05BrzLXf0+fvdVdpSr9FjKweUZWSfprKNRPjhMGlm3RbOgJAKVDGhyYvemwzdEPXS4JdD8yR+ZoV2LC2JaXre5grjgBAMRHpU/4O75dRPnvDs7VcxCRYdoUqBqJV7oJE/5JxD7N8QFfPQm/gNuWO6OhSxpf9PG4W+nBty52+BF7wnoN6kp2LMHRoBIhxs08encXL/Px8bIvr7O+PIJFUTssn4BoQMhAs2r/HYaC4oAr96FR2FLqqyP4bXNu/F+ZrwuR2HCDilZsmt0qfTbW7LKvOIhhcsZLp8XKu5sUGBK9RE6MP67T738WrLAnWSJFNGSu+SZFxrLIodmhUDB679ujwME3n/tWoT2S6o3GBpMTadN0/eQ7oalcsA31fgL9acx2GotJ+Y2pr/0SXcCPh6DjpaOi3A6ETQjILGiC+7E3iA3EEN/cjBLNVfJDLINWmhVcd8CXbotqm5A6fUJagvOZulWAOhswFXCDORy9eSXgDlLIem7OAPThdZ8cn0MO8No1GXKm2cj805eSPVWHAsOxjwlhwcgtE88U1+lmMgmTDuIyTok8sw+lmD X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: a89c1ede-7938-48b2-43dd-08dbbdf1c476 X-MS-Exchange-CrossTenant-AuthSource: AS8P250MB0744.EURP250.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 25 Sep 2023 18:03:48.6810 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-CrossTenant-RMS-PersistedConsumerOrg: 00000000-0000-0000-0000-000000000000 X-MS-Exchange-Transport-CrossTenantHeadersStamped: PR3P250MB0290 Subject: [FFmpeg-devel] [PATCH 2/9] avfilter/vf_bwdif: Move DSP code to a new file X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 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: Andreas Rheinhardt Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: q1akszTLHs1x Otherwise checkasm/vf_bwdif.c pulls in vf_bwdif.c and then all of libavfilter. Besides being bad size-wise this also has the downside that it pulls in avpriv_(cga|vga16)_font from libavutil which are marked as being imported from another library when building libavfilter as a DLL and this breaks checkasm because it links both lavfi and lavu statically. Signed-off-by: Andreas Rheinhardt --- libavfilter/Makefile | 2 +- libavfilter/bwdifdsp.c | 251 +++++++++++++++++++++++++++++++++++++++++ libavfilter/vf_bwdif.c | 211 ---------------------------------- 3 files changed, 252 insertions(+), 212 deletions(-) create mode 100644 libavfilter/bwdifdsp.c diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 2fe0033b21..d063dc65fc 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -214,7 +214,7 @@ OBJS-$(CONFIG_BM3D_FILTER) += vf_bm3d.o framesync.o OBJS-$(CONFIG_BOXBLUR_FILTER) += vf_boxblur.o boxblur.o OBJS-$(CONFIG_BOXBLUR_OPENCL_FILTER) += vf_avgblur_opencl.o opencl.o \ opencl/avgblur.o boxblur.o -OBJS-$(CONFIG_BWDIF_FILTER) += vf_bwdif.o yadif_common.o +OBJS-$(CONFIG_BWDIF_FILTER) += vf_bwdif.o bwdifdsp.o yadif_common.o OBJS-$(CONFIG_BWDIF_CUDA_FILTER) += vf_bwdif_cuda.o vf_bwdif_cuda.ptx.o \ yadif_common.o OBJS-$(CONFIG_BWDIF_VULKAN_FILTER) += vf_bwdif_vulkan.o yadif_common.o vulkan.o vulkan_filter.o diff --git a/libavfilter/bwdifdsp.c b/libavfilter/bwdifdsp.c new file mode 100644 index 0000000000..af217481a5 --- /dev/null +++ b/libavfilter/bwdifdsp.c @@ -0,0 +1,251 @@ +/* + * BobWeaver Deinterlacing Filter DSP functions + * Copyright (C) 2016 Thomas Mundt + * + * Based on YADIF (Yet Another Deinterlacing Filter) + * Copyright (C) 2006-2011 Michael Niedermayer + * 2010 James Darnley + * + * With use of Weston 3 Field Deinterlacing Filter algorithm + * Copyright (C) 2012 British Broadcasting Corporation, All Rights Reserved + * Author of de-interlace algorithm: Jim Easterbrook for BBC R&D + * Based on the process described by Martin Weston for BBC R&D + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "config.h" + +#include "bwdifdsp.h" +#include "libavutil/attributes.h" +#include "libavutil/common.h" +#include "libavutil/macros.h" + +/* + * Filter coefficients coef_lf and coef_hf taken from BBC PH-2071 (Weston 3 Field Deinterlacer). + * Used when there is spatial and temporal interpolation. + * Filter coefficients coef_sp are used when there is spatial interpolation only. + * Adjusted for matching visual sharpness impression of spatial and temporal interpolation. + */ +static const uint16_t coef_lf[2] = { 4309, 213 }; +static const uint16_t coef_hf[3] = { 5570, 3801, 1016 }; +static const uint16_t coef_sp[2] = { 5077, 981 }; + + +#define FILTER_INTRA() \ + for (x = 0; x < w; x++) { \ + interpol = (coef_sp[0] * (cur[mrefs] + cur[prefs]) - coef_sp[1] * (cur[mrefs3] + cur[prefs3])) >> 13; \ + dst[0] = av_clip(interpol, 0, clip_max); \ + \ + dst++; \ + cur++; \ + } + +#define FILTER1() \ + for (x = 0; x < w; x++) { \ + int c = cur[mrefs]; \ + int d = (prev2[0] + next2[0]) >> 1; \ + int e = cur[prefs]; \ + int temporal_diff0 = FFABS(prev2[0] - next2[0]); \ + int temporal_diff1 =(FFABS(prev[mrefs] - c) + FFABS(prev[prefs] - e)) >> 1; \ + int temporal_diff2 =(FFABS(next[mrefs] - c) + FFABS(next[prefs] - e)) >> 1; \ + int diff = FFMAX3(temporal_diff0 >> 1, temporal_diff1, temporal_diff2); \ + \ + if (!diff) { \ + dst[0] = d; \ + } else { + +#define SPAT_CHECK() \ + int b = ((prev2[mrefs2] + next2[mrefs2]) >> 1) - c; \ + int f = ((prev2[prefs2] + next2[prefs2]) >> 1) - e; \ + int dc = d - c; \ + int de = d - e; \ + int max = FFMAX3(de, dc, FFMIN(b, f)); \ + int min = FFMIN3(de, dc, FFMAX(b, f)); \ + diff = FFMAX3(diff, min, -max); + +#define FILTER_LINE() \ + SPAT_CHECK() \ + if (FFABS(c - e) > temporal_diff0) { \ + interpol = (((coef_hf[0] * (prev2[0] + next2[0]) \ + - coef_hf[1] * (prev2[mrefs2] + next2[mrefs2] + prev2[prefs2] + next2[prefs2]) \ + + coef_hf[2] * (prev2[mrefs4] + next2[mrefs4] + prev2[prefs4] + next2[prefs4])) >> 2) \ + + coef_lf[0] * (c + e) - coef_lf[1] * (cur[mrefs3] + cur[prefs3])) >> 13; \ + } else { \ + interpol = (coef_sp[0] * (c + e) - coef_sp[1] * (cur[mrefs3] + cur[prefs3])) >> 13; \ + } + +#define FILTER_EDGE() \ + if (spat) { \ + SPAT_CHECK() \ + } \ + interpol = (c + e) >> 1; + +#define FILTER2() \ + if (interpol > d + diff) \ + interpol = d + diff; \ + else if (interpol < d - diff) \ + interpol = d - diff; \ + \ + dst[0] = av_clip(interpol, 0, clip_max); \ + } \ + \ + dst++; \ + cur++; \ + prev++; \ + next++; \ + prev2++; \ + next2++; \ + } + +void ff_bwdif_filter_intra_c(void *dst1, void *cur1, int w, int prefs, int mrefs, + int prefs3, int mrefs3, int parity, int clip_max) +{ + uint8_t *dst = dst1; + uint8_t *cur = cur1; + int interpol, x; + + FILTER_INTRA() +} + +void ff_bwdif_filter_line_c(void *dst1, void *prev1, void *cur1, void *next1, + int w, int prefs, int mrefs, int prefs2, int mrefs2, + int prefs3, int mrefs3, int prefs4, int mrefs4, + int parity, int clip_max) +{ + uint8_t *dst = dst1; + uint8_t *prev = prev1; + uint8_t *cur = cur1; + uint8_t *next = next1; + uint8_t *prev2 = parity ? prev : cur ; + uint8_t *next2 = parity ? cur : next; + int interpol, x; + + FILTER1() + FILTER_LINE() + FILTER2() +} + +#define NEXT_LINE()\ + dst += d_stride; \ + prev += prefs; \ + cur += prefs; \ + next += prefs; + +void ff_bwdif_filter_line3_c(void * dst1, int d_stride, + const void * prev1, const void * cur1, const void * next1, int s_stride, + int w, int parity, int clip_max) +{ + const int prefs = s_stride; + uint8_t * dst = dst1; + const uint8_t * prev = prev1; + const uint8_t * cur = cur1; + const uint8_t * next = next1; + + ff_bwdif_filter_line_c(dst, (void*)prev, (void*)cur, (void*)next, w, + prefs, -prefs, prefs * 2, - prefs * 2, prefs * 3, -prefs * 3, prefs * 4, -prefs * 4, parity, clip_max); + NEXT_LINE(); + memcpy(dst, cur, w); + NEXT_LINE(); + ff_bwdif_filter_line_c(dst, (void*)prev, (void*)cur, (void*)next, w, + prefs, -prefs, prefs * 2, - prefs * 2, prefs * 3, -prefs * 3, prefs * 4, -prefs * 4, parity, clip_max); +} + +void ff_bwdif_filter_edge_c(void *dst1, void *prev1, void *cur1, void *next1, + int w, int prefs, int mrefs, int prefs2, int mrefs2, + int parity, int clip_max, int spat) +{ + uint8_t *dst = dst1; + uint8_t *prev = prev1; + uint8_t *cur = cur1; + uint8_t *next = next1; + uint8_t *prev2 = parity ? prev : cur ; + uint8_t *next2 = parity ? cur : next; + int interpol, x; + + FILTER1() + FILTER_EDGE() + FILTER2() +} + +static void filter_intra_16bit(void *dst1, void *cur1, int w, int prefs, int mrefs, + int prefs3, int mrefs3, int parity, int clip_max) +{ + uint16_t *dst = dst1; + uint16_t *cur = cur1; + int interpol, x; + + FILTER_INTRA() +} + +static void filter_line_c_16bit(void *dst1, void *prev1, void *cur1, void *next1, + int w, int prefs, int mrefs, int prefs2, int mrefs2, + int prefs3, int mrefs3, int prefs4, int mrefs4, + int parity, int clip_max) +{ + uint16_t *dst = dst1; + uint16_t *prev = prev1; + uint16_t *cur = cur1; + uint16_t *next = next1; + uint16_t *prev2 = parity ? prev : cur ; + uint16_t *next2 = parity ? cur : next; + int interpol, x; + + FILTER1() + FILTER_LINE() + FILTER2() +} + +static void filter_edge_16bit(void *dst1, void *prev1, void *cur1, void *next1, + int w, int prefs, int mrefs, int prefs2, int mrefs2, + int parity, int clip_max, int spat) +{ + uint16_t *dst = dst1; + uint16_t *prev = prev1; + uint16_t *cur = cur1; + uint16_t *next = next1; + uint16_t *prev2 = parity ? prev : cur ; + uint16_t *next2 = parity ? cur : next; + int interpol, x; + + FILTER1() + FILTER_EDGE() + FILTER2() +} + +av_cold void ff_bwdif_init_filter_line(BWDIFDSPContext *s, int bit_depth) +{ + s->filter_line3 = 0; + if (bit_depth > 8) { + s->filter_intra = filter_intra_16bit; + s->filter_line = filter_line_c_16bit; + s->filter_edge = filter_edge_16bit; + } else { + s->filter_intra = ff_bwdif_filter_intra_c; + s->filter_line = ff_bwdif_filter_line_c; + s->filter_edge = ff_bwdif_filter_edge_c; + } + +#if ARCH_X86 + ff_bwdif_init_x86(s, bit_depth); +#elif ARCH_AARCH64 + ff_bwdif_init_aarch64(s, bit_depth); +#endif +} diff --git a/libavfilter/vf_bwdif.c b/libavfilter/vf_bwdif.c index 282aef5698..137cd5ef13 100644 --- a/libavfilter/vf_bwdif.c +++ b/libavfilter/vf_bwdif.c @@ -37,16 +37,6 @@ #include "internal.h" #include "yadif.h" -/* - * Filter coefficients coef_lf and coef_hf taken from BBC PH-2071 (Weston 3 Field Deinterlacer). - * Used when there is spatial and temporal interpolation. - * Filter coefficients coef_sp are used when there is spatial interpolation only. - * Adjusted for matching visual sharpness impression of spatial and temporal interpolation. - */ -static const uint16_t coef_lf[2] = { 4309, 213 }; -static const uint16_t coef_hf[3] = { 5570, 3801, 1016 }; -static const uint16_t coef_sp[2] = { 5077, 981 }; - typedef struct BWDIFContext { YADIFContext yadif; BWDIFDSPContext dsp; @@ -60,187 +50,6 @@ typedef struct ThreadData { int tff; } ThreadData; -#define FILTER_INTRA() \ - for (x = 0; x < w; x++) { \ - interpol = (coef_sp[0] * (cur[mrefs] + cur[prefs]) - coef_sp[1] * (cur[mrefs3] + cur[prefs3])) >> 13; \ - dst[0] = av_clip(interpol, 0, clip_max); \ - \ - dst++; \ - cur++; \ - } - -#define FILTER1() \ - for (x = 0; x < w; x++) { \ - int c = cur[mrefs]; \ - int d = (prev2[0] + next2[0]) >> 1; \ - int e = cur[prefs]; \ - int temporal_diff0 = FFABS(prev2[0] - next2[0]); \ - int temporal_diff1 =(FFABS(prev[mrefs] - c) + FFABS(prev[prefs] - e)) >> 1; \ - int temporal_diff2 =(FFABS(next[mrefs] - c) + FFABS(next[prefs] - e)) >> 1; \ - int diff = FFMAX3(temporal_diff0 >> 1, temporal_diff1, temporal_diff2); \ - \ - if (!diff) { \ - dst[0] = d; \ - } else { - -#define SPAT_CHECK() \ - int b = ((prev2[mrefs2] + next2[mrefs2]) >> 1) - c; \ - int f = ((prev2[prefs2] + next2[prefs2]) >> 1) - e; \ - int dc = d - c; \ - int de = d - e; \ - int max = FFMAX3(de, dc, FFMIN(b, f)); \ - int min = FFMIN3(de, dc, FFMAX(b, f)); \ - diff = FFMAX3(diff, min, -max); - -#define FILTER_LINE() \ - SPAT_CHECK() \ - if (FFABS(c - e) > temporal_diff0) { \ - interpol = (((coef_hf[0] * (prev2[0] + next2[0]) \ - - coef_hf[1] * (prev2[mrefs2] + next2[mrefs2] + prev2[prefs2] + next2[prefs2]) \ - + coef_hf[2] * (prev2[mrefs4] + next2[mrefs4] + prev2[prefs4] + next2[prefs4])) >> 2) \ - + coef_lf[0] * (c + e) - coef_lf[1] * (cur[mrefs3] + cur[prefs3])) >> 13; \ - } else { \ - interpol = (coef_sp[0] * (c + e) - coef_sp[1] * (cur[mrefs3] + cur[prefs3])) >> 13; \ - } - -#define FILTER_EDGE() \ - if (spat) { \ - SPAT_CHECK() \ - } \ - interpol = (c + e) >> 1; - -#define FILTER2() \ - if (interpol > d + diff) \ - interpol = d + diff; \ - else if (interpol < d - diff) \ - interpol = d - diff; \ - \ - dst[0] = av_clip(interpol, 0, clip_max); \ - } \ - \ - dst++; \ - cur++; \ - prev++; \ - next++; \ - prev2++; \ - next2++; \ - } - -void ff_bwdif_filter_intra_c(void *dst1, void *cur1, int w, int prefs, int mrefs, - int prefs3, int mrefs3, int parity, int clip_max) -{ - uint8_t *dst = dst1; - uint8_t *cur = cur1; - int interpol, x; - - FILTER_INTRA() -} - -void ff_bwdif_filter_line_c(void *dst1, void *prev1, void *cur1, void *next1, - int w, int prefs, int mrefs, int prefs2, int mrefs2, - int prefs3, int mrefs3, int prefs4, int mrefs4, - int parity, int clip_max) -{ - uint8_t *dst = dst1; - uint8_t *prev = prev1; - uint8_t *cur = cur1; - uint8_t *next = next1; - uint8_t *prev2 = parity ? prev : cur ; - uint8_t *next2 = parity ? cur : next; - int interpol, x; - - FILTER1() - FILTER_LINE() - FILTER2() -} - -#define NEXT_LINE()\ - dst += d_stride; \ - prev += prefs; \ - cur += prefs; \ - next += prefs; - -void ff_bwdif_filter_line3_c(void * dst1, int d_stride, - const void * prev1, const void * cur1, const void * next1, int s_stride, - int w, int parity, int clip_max) -{ - const int prefs = s_stride; - uint8_t * dst = dst1; - const uint8_t * prev = prev1; - const uint8_t * cur = cur1; - const uint8_t * next = next1; - - ff_bwdif_filter_line_c(dst, (void*)prev, (void*)cur, (void*)next, w, - prefs, -prefs, prefs * 2, - prefs * 2, prefs * 3, -prefs * 3, prefs * 4, -prefs * 4, parity, clip_max); - NEXT_LINE(); - memcpy(dst, cur, w); - NEXT_LINE(); - ff_bwdif_filter_line_c(dst, (void*)prev, (void*)cur, (void*)next, w, - prefs, -prefs, prefs * 2, - prefs * 2, prefs * 3, -prefs * 3, prefs * 4, -prefs * 4, parity, clip_max); -} - -void ff_bwdif_filter_edge_c(void *dst1, void *prev1, void *cur1, void *next1, - int w, int prefs, int mrefs, int prefs2, int mrefs2, - int parity, int clip_max, int spat) -{ - uint8_t *dst = dst1; - uint8_t *prev = prev1; - uint8_t *cur = cur1; - uint8_t *next = next1; - uint8_t *prev2 = parity ? prev : cur ; - uint8_t *next2 = parity ? cur : next; - int interpol, x; - - FILTER1() - FILTER_EDGE() - FILTER2() -} - -static void filter_intra_16bit(void *dst1, void *cur1, int w, int prefs, int mrefs, - int prefs3, int mrefs3, int parity, int clip_max) -{ - uint16_t *dst = dst1; - uint16_t *cur = cur1; - int interpol, x; - - FILTER_INTRA() -} - -static void filter_line_c_16bit(void *dst1, void *prev1, void *cur1, void *next1, - int w, int prefs, int mrefs, int prefs2, int mrefs2, - int prefs3, int mrefs3, int prefs4, int mrefs4, - int parity, int clip_max) -{ - uint16_t *dst = dst1; - uint16_t *prev = prev1; - uint16_t *cur = cur1; - uint16_t *next = next1; - uint16_t *prev2 = parity ? prev : cur ; - uint16_t *next2 = parity ? cur : next; - int interpol, x; - - FILTER1() - FILTER_LINE() - FILTER2() -} - -static void filter_edge_16bit(void *dst1, void *prev1, void *cur1, void *next1, - int w, int prefs, int mrefs, int prefs2, int mrefs2, - int parity, int clip_max, int spat) -{ - uint16_t *dst = dst1; - uint16_t *prev = prev1; - uint16_t *cur = cur1; - uint16_t *next = next1; - uint16_t *prev2 = parity ? prev : cur ; - uint16_t *next2 = parity ? cur : next; - int interpol, x; - - FILTER1() - FILTER_EDGE() - FILTER2() -} - // Round job start line down to multiple of 4 so that if filter_line3 exists // and the frame is a multiple of 4 high then filter_line will never be called static inline int job_start(const int jobnr, const int nb_jobs, const int h) @@ -394,26 +203,6 @@ static int config_props(AVFilterLink *link) return 0; } -av_cold void ff_bwdif_init_filter_line(BWDIFDSPContext *s, int bit_depth) -{ - s->filter_line3 = 0; - if (bit_depth > 8) { - s->filter_intra = filter_intra_16bit; - s->filter_line = filter_line_c_16bit; - s->filter_edge = filter_edge_16bit; - } else { - s->filter_intra = ff_bwdif_filter_intra_c; - s->filter_line = ff_bwdif_filter_line_c; - s->filter_edge = ff_bwdif_filter_edge_c; - } - -#if ARCH_X86 - ff_bwdif_init_x86(s, bit_depth); -#elif ARCH_AARCH64 - ff_bwdif_init_aarch64(s, bit_depth); -#endif -} - #define OFFSET(x) offsetof(YADIFContext, x) #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM