From patchwork Tue May 3 06:37:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andreas Rheinhardt X-Patchwork-Id: 35558 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:a885:b0:7f:4be2:bd17 with SMTP id ca5csp257736pzb; Mon, 2 May 2022 23:40:02 -0700 (PDT) X-Google-Smtp-Source: ABdhPJw4HPyhTcwqDWOAJ5fhuH/b2LUU/aOE1Rd1/02qzUXg2Jt2iLVf/5tet84MKU3D26wW5Lqi X-Received: by 2002:a17:906:9754:b0:6da:7d72:1353 with SMTP id o20-20020a170906975400b006da7d721353mr14209947ejy.273.1651560002320; Mon, 02 May 2022 23:40:02 -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 v6-20020a056402174600b00425bfc70c1bsi13212304edx.341.2022.05.02.23.40.01; Mon, 02 May 2022 23:40:02 -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=tP9KaI4S; 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 646A368B3D5; Tue, 3 May 2022 09:39:47 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from EUR04-VI1-obe.outbound.protection.outlook.com (mail-oln040092075040.outbound.protection.outlook.com [40.92.75.40]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id D8CF168B2A1 for ; Tue, 3 May 2022 09:39:40 +0300 (EEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=gyti/NwMJqfiQxDQO+2MKGgfrUgYCAQX+Rgtx7LeEZfssC69yVAH42AMHB9AFF5A6ho+2JNKQrMI5tif4/mGVGhkk7mGmPfiOm+wjP0fcOfygED2qtZyM9Q64Scz0liK9kuC2wRQlJvqtS33g0hh4G1N+JpjDFLGJCxkG1Tsd9/VKrtwMfYhL/XHORyE3ZxVYhAO9PxE/g3u0IZqkQGqKLGaJ0KMiF7AGTeJzLvLlk5BKHUO8wbZzLollTPNh1J1KTIVnfCRVuqbPG995jTD3jTgPZ9eZUuIcMFGmhBUlgm6V/Oqi6ucXjO+PprH/7iMjbM3cj/OgAVGRUV+WuJP2g== 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=Gfei3EYUM13Te4JqUjwrYQM3r8Asr92MCyOkb7f8SKo=; b=Va1npGwR++w+CxsFL+u2buoBMDinhEjgWq5wrwmXvUxaDcVSMZJDL0k/nyPmbieiOoM8roBzqPJULzyPQD/oc0HADF/MJ9zHfoI7NJWhiG2RXBTMl+TCEKNw8Q0WHNC9NX5/janeSTj0nz+b+4NgzMzbUkk3m12/6y10mt0lOPltANxBIYJ36mSYrXGPDaN74MYswG1AsqHl7kgHbEwVYp03iZ27ds9hz2eCOLofAOr3rg31v8SAABMMWznfhpN/FJSF7eg1YALggv9TahhHe7MVDgWiJ0kQbVB2jAGsSG4k65MeFYTI1a3CU/bXuiTBUUt5sQieuKufBMtwOxsf8w== 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=Gfei3EYUM13Te4JqUjwrYQM3r8Asr92MCyOkb7f8SKo=; b=tP9KaI4SeTD82LhPaRR9CLMkB9peZZ5rtPyQLwiwzL1NkcF49Mbe8MijvVCRD2biR4IA/0G+tSkEgEmYvOR1ZMPCNTWHahaqg84O25eFK8Y+DnCv5WyZFjrSFPP+IE8XXAVacuBkIeVklVvxLqsct24KEVvdTQghoAjBgjU4yd0HqFnVVRgcjiLrqXSJyS0qHqJFcxgL3Ba9uVo6Q8YyG4XnaTWcnKyOFxJNZhGLgs9eYOZW65/SIrRcWClp5oD5EVemInZBfjduOPP/7d9tplYkVtiSBwKMk5irmmYAJ3a/MS0eEYnwQwz+OvzAz2G0RrC+6t9Rc6AisfFWGbvpoQ== Received: from AS8PR01MB7944.eurprd01.prod.exchangelabs.com (2603:10a6:20b:373::5) by VI1PR0102MB3230.eurprd01.prod.exchangelabs.com (2603:10a6:803:8::26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5206.24; Tue, 3 May 2022 06:39:19 +0000 Received: from AS8PR01MB7944.eurprd01.prod.exchangelabs.com ([fe80::1854:2c30:7ba1:c431]) by AS8PR01MB7944.eurprd01.prod.exchangelabs.com ([fe80::1854:2c30:7ba1:c431%6]) with mapi id 15.20.5206.024; Tue, 3 May 2022 06:39:19 +0000 From: Andreas Rheinhardt To: ffmpeg-devel@ffmpeg.org Date: Tue, 3 May 2022 08:37:48 +0200 Message-ID: X-Mailer: git-send-email 2.32.0 In-Reply-To: References: X-TMN: [gkCQEtTA+DtP+uAqT0sGrV2fZLLVzdD4] X-ClientProxiedBy: ZR0P278CA0014.CHEP278.PROD.OUTLOOK.COM (2603:10a6:910:16::24) To AS8PR01MB7944.eurprd01.prod.exchangelabs.com (2603:10a6:20b:373::5) X-Microsoft-Original-Message-ID: <20220503063751.2261222-6-andreas.rheinhardt@outlook.com> MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 9a94bbb8-76b8-4292-2b0a-08da2ccfa65e X-MS-Exchange-SLBlob-MailProps: +LiGfBxqLEshfmgJKOBnMup7aFnPglP1MOoFnNBA7MFo8n5bAykiG8nHjgPtjPg1Zw5jH2MZ4VJ29nZN/veTa24eMGEVbZclOEITxu4wE0J6UgUzdXOsYA+kjVqjUa/ELAgKfVp/GQI6XCyhadGAWWLZC+OmTOcoFadcQCfeVUzFtmK4DMGld3WwbCXHtiGBuA6lPtq39GaI3I38C13qqY2mYp2fhB06MYk1ruLiUlFHyyAqsJR8iZjlvIGfiN0BJT7ZOHb3aBR+wcrWieGdEd1vA69TSRuEVkUtpy8W2XLgt6zC8WY1Gslv56i7r+1iVoFOICRXhHjq9eDTYuinVnqVNOphuDsWRh1zcbFQLhYeLyPyKVBhpsk++2lG8PV9OYNvij2YIGEND8QT4J5zg03z9c/CANvQeBJt7hbSp2iNpsdcmOBlYtQz3fR0UtCe6ciY2shBPUHXpjxnxV2ep7TnMR4jIdmWcDBvyIXtHAX4h7EsNeditvkPILK1H6mdcAgabRrNVLphycIwydx+j9oiG+RwjJl5Bup6SOZWLWoFrx3zRYUXF50D4mGC7HonM/cmiB9Vzt1a210zB7BcfjQJenhpZVnGPOdY72u2TyYRy6cgAhfQteBPXbshadddlscPu8+LdWOBojk9TWAdWqs63v4BiQJzI72xTuQL/fB8XIzA+3jfrYnL5llI+jH8da3DERdPlrbbcEPPCrHFbHl8iKGkMnSHgVm3QqGRlmSrvOiQgQknwj/yav+IbXZSkC6PYQCM3fkqz62KKsf7j5zBA59lrg03 X-MS-TrafficTypeDiagnostic: VI1PR0102MB3230:EE_ X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: BBC/Fsbj3VKpL2Iu7dcg2r2HFiTBCswhezr7qgVuVzNaIIJbNYLLAWgjJQXMkh9Ry3lTE4O/SKD0iRRj0VdDmgVTTc4rCHJfYbTziDJ4q82raqT/sEVYIITu4aIJs8EMwAQgPQlshbX82J9kYyaWuPNIR2ZmOdVH7WP87AuEYlwi9M9GAeC8XB2ZSEOVosUY9h6g8L+xhiSb1f7FHrrXRG0KXq1Boh+FRZ9vFWcER8DhRr2erW3izw/VpruXm/flfPxfuYCUAQwOaZlM7q35Rv6isnA/PiIWWYbswuGBRMc2uY+XC56OfK8LQfoRWO35TLTmX+eeVXiqcDQWeavDgFaqemdaDfrqQoiGDrkGlU6CMLRyJ3oZ1flZ6qJNDOF4VKFKt5LsNsKYggUG1+E7bMH+IMGss85QlUKtYllN6K8CFT9r3ibkmVeQD6jjqkzOIqxphEh7GnOo9jeBR+VlrXsA5eKhiTAxMSZ23osD60JUbJXPFpytHTQ4liLxye+5HFjD+FiMjjmg/AsymbcpjvW/R8ulUTL8cArAsOT+K5qjZqDSS1uDn0nCNbMlxiXPj/WefkMcc2wzGa8Mz801HMXlNoT/yTBtIkY5ktlQNsKEUeTLHbwSobbXmYqSOBf7 X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?CPxNn9HAdMmLTkRWEXnaoLCHz3i/?= =?utf-8?q?TNYQW/MkHtxAjr6y64noocflcLzL1SKZgD9ZN4m8hZ4QRBEMnm/8GVbA+HI4PKFwO?= =?utf-8?q?OIfeBCBGw6zTMgOaHXNUdp01hfRHqUD4jS0zkYV+EWkYZZ9TqqtfpiV7nCpEOu4HD?= =?utf-8?q?aWXZWXi3AH8YTBpvlIdsHZ9YQZ+Ork6ci7AmNKvqY3whlVuHhgHr2Vo9ohHOyUBJf?= =?utf-8?q?SaX8R8g8uEqZfxeeu5ypMnx1TpMZMq8r7szRy8R00cEIXOIs0Y4NQkgz6jiHKTpfz?= =?utf-8?q?o8iMmWfy865oUOQ3VFEP5f7FgmZVesOoLCVXcmygtaELgGwOoXodIveGeixFKVDkf?= =?utf-8?q?Ultp6U8U29fzdmm8NXJzF4FO+AFSFjnxemJRygYW5x4aB/BiljKxcMNoj1LQxHDp3?= =?utf-8?q?kjloNDynbvwNUTM95t9uGygW1dA4Iv/VGLKQn51v5G1LZU+0FHythir5kgXt7LC9K?= =?utf-8?q?wcHOm27EKlpH9X7Ji/IhGwD7+0N1F5QIdNZPBtOAOAEf8Mry4nwbHv9+yJB6pOIer?= =?utf-8?q?5tTaplmkSCRcPoaWSNzIaCWbRHuSv5ADjTsz3BQP8YYP5Z7eO5HM8EcHD365KqZyH?= =?utf-8?q?8DvTlVLMQbyHXTCvfRnFhhX0Kir2+z+5Bxz3+Kb5e5frFl/yjfvARklP3YHnCwLvl?= =?utf-8?q?mQzv/WscpXrZT6WsnZ8Pu3FviLa+z4PXBHE5HBoCdtCJmUQ78eFNtWihQzhgAi9Z7?= =?utf-8?q?8XOWpJVk/ZVrpGQERUbrTZ9kMSGPUVmJADwm095OiFvKv/4dO2+slZGFrzz/u5sln?= =?utf-8?q?zyOxbdlRFS2Ft7IAxPNvWIgfFiCiQwG/0vA1eG2N34KLnqYDlOZwcr8h3aqo/21FM?= =?utf-8?q?U++T1D68sWenfRWHnrDr3tEcrNDM4ataLc9XREhBIf3X8Tsf5O1LFKQG7DfUvgiTV?= =?utf-8?q?OSwKuwwMu7Bs+037uHpCy51QBa+LaTsakWAXXTeQ1uMoQbk/FGK9fpFi7/0xQRsKF?= =?utf-8?q?OH3mPVBPGiYy6AB8Lf2y4cBEUCBREgv/DflH7DDQdfXsXYX4jFDxO6NhxC6h95KET?= =?utf-8?q?ib6gXJotbmFVDwqG7zbTT3mSGVbW9hjaT+KM+zX8ui3X/C72VNWXvU0cOIzELZCxO?= =?utf-8?q?wxd+2d/9NveGVokshDiGY2L2sFW/e3RoEPr+oBUsuWw4xUXFRxCfMVFLwmUbmphH2?= =?utf-8?q?EgoS+W+G8e1Yckjv/hglqAXESnFRMF0gFCzY470is4G0O4IJmgMZox6E4fiDD6WOM?= =?utf-8?q?6+zQnzDZA0+RNo6nMZo+1SH5/1/4LzgJmZH5QXOp/rDYBfvrYAv+cD7rVsPd2nYMW?= =?utf-8?q?DTuoNT2hrtc8YkgGtsOIizRDCuowl/4ulTrOCC9Wp/yRxBZ3v+4eGKzts8QLjPEWm?= =?utf-8?q?dCEdymVJkZX3TykU8korgTDIgiTKTm52sREo4oIdcf1RZUTkjWMJiBjwUo1vvMW/2?= =?utf-8?q?kFIvLVDvw7mBhPJqj9EbEZGfzL9ITDrw8q8Q=3D=3D?= X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 9a94bbb8-76b8-4292-2b0a-08da2ccfa65e X-MS-Exchange-CrossTenant-AuthSource: AS8PR01MB7944.eurprd01.prod.exchangelabs.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 03 May 2022 06:39:19.4730 (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: VI1PR0102MB3230 Subject: [FFmpeg-devel] [PATCH 07/10] avfilter/vf_nlmeans: Move ff_nlmeans_init into a header 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: NiJ98FpOvHU9 This removes a dependency of checkasm on lavfi/vf_nlmeans.o and also allows to inline ff_nlmeans_init() irrespectively of interposing. Signed-off-by: Andreas Rheinhardt --- libavfilter/vf_nlmeans.c | 108 +------------------------- libavfilter/vf_nlmeans.h | 1 - libavfilter/vf_nlmeans_init.h | 139 ++++++++++++++++++++++++++++++++++ tests/checkasm/vf_nlmeans.c | 2 +- 4 files changed, 141 insertions(+), 109 deletions(-) create mode 100644 libavfilter/vf_nlmeans_init.h diff --git a/libavfilter/vf_nlmeans.c b/libavfilter/vf_nlmeans.c index 8a05965c9b..2fc3adacca 100644 --- a/libavfilter/vf_nlmeans.c +++ b/libavfilter/vf_nlmeans.c @@ -36,6 +36,7 @@ #include "formats.h" #include "internal.h" #include "vf_nlmeans.h" +#include "vf_nlmeans_init.h" #include "video.h" typedef struct NLMeansContext { @@ -84,48 +85,6 @@ static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_NONE }; -/** - * Compute squared difference of the safe area (the zone where s1 and s2 - * overlap). It is likely the largest integral zone, so it is interesting to do - * as little checks as possible; contrary to the unsafe version of this - * function, we do not need any clipping here. - * - * The line above dst and the column to its left are always readable. - */ -static void compute_safe_ssd_integral_image_c(uint32_t *dst, ptrdiff_t dst_linesize_32, - const uint8_t *s1, ptrdiff_t linesize1, - const uint8_t *s2, ptrdiff_t linesize2, - int w, int h) -{ - const uint32_t *dst_top = dst - dst_linesize_32; - - /* SIMD-friendly assumptions allowed here */ - av_assert2(!(w & 0xf) && w >= 16 && h >= 1); - - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x += 4) { - const int d0 = s1[x ] - s2[x ]; - const int d1 = s1[x + 1] - s2[x + 1]; - const int d2 = s1[x + 2] - s2[x + 2]; - const int d3 = s1[x + 3] - s2[x + 3]; - - dst[x ] = dst_top[x ] - dst_top[x - 1] + d0*d0; - dst[x + 1] = dst_top[x + 1] - dst_top[x ] + d1*d1; - dst[x + 2] = dst_top[x + 2] - dst_top[x + 1] + d2*d2; - dst[x + 3] = dst_top[x + 3] - dst_top[x + 2] + d3*d3; - - dst[x ] += dst[x - 1]; - dst[x + 1] += dst[x ]; - dst[x + 2] += dst[x + 1]; - dst[x + 3] += dst[x + 2]; - } - s1 += linesize1; - s2 += linesize2; - dst += dst_linesize_32; - dst_top += dst_linesize_32; - } -} - /** * Compute squared difference of an unsafe area (the zone nor s1 nor s2 could * be readable). @@ -326,59 +285,6 @@ struct thread_data { int p; }; -static void compute_weights_line_c(const uint32_t *const iia, - const uint32_t *const iib, - const uint32_t *const iid, - const uint32_t *const iie, - const uint8_t *const src, - float *total_weight, - float *sum, - const float *const weight_lut, - int max_meaningful_diff, - int startx, int endx) -{ - for (int x = startx; x < endx; x++) { - /* - * M is a discrete map where every entry contains the sum of all the entries - * in the rectangle from the top-left origin of M to its coordinate. In the - * following schema, "i" contains the sum of the whole map: - * - * M = +----------+-----------------+----+ - * | | | | - * | | | | - * | a| b| c| - * +----------+-----------------+----+ - * | | | | - * | | | | - * | | X | | - * | | | | - * | d| e| f| - * +----------+-----------------+----+ - * | | | | - * | g| h| i| - * +----------+-----------------+----+ - * - * The sum of the X box can be calculated with: - * X = e-d-b+a - * - * See https://en.wikipedia.org/wiki/Summed_area_table - * - * The compute*_ssd functions compute the integral image M where every entry - * contains the sum of the squared difference of every corresponding pixels of - * two input planes of the same size as M. - */ - const uint32_t a = iia[x]; - const uint32_t b = iib[x]; - const uint32_t d = iid[x]; - const uint32_t e = iie[x]; - const uint32_t patch_diff_sq = FFMIN(e - d - b + a, max_meaningful_diff); - const float weight = weight_lut[patch_diff_sq]; // exp(-patch_diff_sq * s->pdiff_scale) - - total_weight[x] += weight; - sum[x] += weight * src[x]; - } -} - static int nlmeans_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { NLMeansContext *s = ctx->priv; @@ -512,18 +418,6 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) } \ } while (0) -void ff_nlmeans_init(NLMeansDSPContext *dsp) -{ - dsp->compute_safe_ssd_integral_image = compute_safe_ssd_integral_image_c; - dsp->compute_weights_line = compute_weights_line_c; - - if (ARCH_AARCH64) - ff_nlmeans_init_aarch64(dsp); - - if (ARCH_X86) - ff_nlmeans_init_x86(dsp); -} - static av_cold int init(AVFilterContext *ctx) { NLMeansContext *s = ctx->priv; diff --git a/libavfilter/vf_nlmeans.h b/libavfilter/vf_nlmeans.h index 43611a03bd..61377f8c69 100644 --- a/libavfilter/vf_nlmeans.h +++ b/libavfilter/vf_nlmeans.h @@ -39,7 +39,6 @@ typedef struct NLMeansDSPContext { int startx, int endx); } NLMeansDSPContext; -void ff_nlmeans_init(NLMeansDSPContext *dsp); void ff_nlmeans_init_aarch64(NLMeansDSPContext *dsp); void ff_nlmeans_init_x86(NLMeansDSPContext *dsp); diff --git a/libavfilter/vf_nlmeans_init.h b/libavfilter/vf_nlmeans_init.h new file mode 100644 index 0000000000..04ad8801b6 --- /dev/null +++ b/libavfilter/vf_nlmeans_init.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2016 Clément Bœsch + * + * 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 + */ + +#ifndef AVFILTER_NLMEANS_INIT_H +#define AVFILTER_NLMEANS_INIT_H + +#include +#include + +#include "config.h" +#include "libavutil/avassert.h" +#include "libavutil/macros.h" +#include "vf_nlmeans.h" + +/** + * Compute squared difference of the safe area (the zone where s1 and s2 + * overlap). It is likely the largest integral zone, so it is interesting to do + * as little checks as possible; contrary to the unsafe version of this + * function, we do not need any clipping here. + * + * The line above dst and the column to its left are always readable. + */ +static void compute_safe_ssd_integral_image_c(uint32_t *dst, ptrdiff_t dst_linesize_32, + const uint8_t *s1, ptrdiff_t linesize1, + const uint8_t *s2, ptrdiff_t linesize2, + int w, int h) +{ + const uint32_t *dst_top = dst - dst_linesize_32; + + /* SIMD-friendly assumptions allowed here */ + av_assert2(!(w & 0xf) && w >= 16 && h >= 1); + + for (int y = 0; y < h; y++) { + for (int x = 0; x < w; x += 4) { + const int d0 = s1[x ] - s2[x ]; + const int d1 = s1[x + 1] - s2[x + 1]; + const int d2 = s1[x + 2] - s2[x + 2]; + const int d3 = s1[x + 3] - s2[x + 3]; + + dst[x ] = dst_top[x ] - dst_top[x - 1] + d0*d0; + dst[x + 1] = dst_top[x + 1] - dst_top[x ] + d1*d1; + dst[x + 2] = dst_top[x + 2] - dst_top[x + 1] + d2*d2; + dst[x + 3] = dst_top[x + 3] - dst_top[x + 2] + d3*d3; + + dst[x ] += dst[x - 1]; + dst[x + 1] += dst[x ]; + dst[x + 2] += dst[x + 1]; + dst[x + 3] += dst[x + 2]; + } + s1 += linesize1; + s2 += linesize2; + dst += dst_linesize_32; + dst_top += dst_linesize_32; + } +} + +static void compute_weights_line_c(const uint32_t *const iia, + const uint32_t *const iib, + const uint32_t *const iid, + const uint32_t *const iie, + const uint8_t *const src, + float *total_weight, + float *sum, + const float *const weight_lut, + int max_meaningful_diff, + int startx, int endx) +{ + for (int x = startx; x < endx; x++) { + /* + * M is a discrete map where every entry contains the sum of all the entries + * in the rectangle from the top-left origin of M to its coordinate. In the + * following schema, "i" contains the sum of the whole map: + * + * M = +----------+-----------------+----+ + * | | | | + * | | | | + * | a| b| c| + * +----------+-----------------+----+ + * | | | | + * | | | | + * | | X | | + * | | | | + * | d| e| f| + * +----------+-----------------+----+ + * | | | | + * | g| h| i| + * +----------+-----------------+----+ + * + * The sum of the X box can be calculated with: + * X = e-d-b+a + * + * See https://en.wikipedia.org/wiki/Summed_area_table + * + * The compute*_ssd functions compute the integral image M where every entry + * contains the sum of the squared difference of every corresponding pixels of + * two input planes of the same size as M. + */ + const uint32_t a = iia[x]; + const uint32_t b = iib[x]; + const uint32_t d = iid[x]; + const uint32_t e = iie[x]; + const uint32_t patch_diff_sq = FFMIN(e - d - b + a, max_meaningful_diff); + const float weight = weight_lut[patch_diff_sq]; // exp(-patch_diff_sq * s->pdiff_scale) + + total_weight[x] += weight; + sum[x] += weight * src[x]; + } +} + +static av_unused void ff_nlmeans_init(NLMeansDSPContext *dsp) +{ + dsp->compute_safe_ssd_integral_image = compute_safe_ssd_integral_image_c; + dsp->compute_weights_line = compute_weights_line_c; + + if (ARCH_AARCH64) + ff_nlmeans_init_aarch64(dsp); + + if (ARCH_X86) + ff_nlmeans_init_x86(dsp); +} + +#endif /* AVFILTER_NLMEANS_INIT_H */ diff --git a/tests/checkasm/vf_nlmeans.c b/tests/checkasm/vf_nlmeans.c index 87474d6803..0f1f9fd403 100644 --- a/tests/checkasm/vf_nlmeans.c +++ b/tests/checkasm/vf_nlmeans.c @@ -19,7 +19,7 @@ */ #include "checkasm.h" -#include "libavfilter/vf_nlmeans.h" +#include "libavfilter/vf_nlmeans_init.h" #include "libavutil/avassert.h" #define randomize_buffer(buf, size) do { \