From patchwork Wed Nov 22 13:59:07 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shengbin Meng X-Patchwork-Id: 6273 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.2.161.94 with SMTP id m30csp201664jah; Wed, 22 Nov 2017 05:59:38 -0800 (PST) X-Google-Smtp-Source: AGs4zMZn8Q58byoe4epii2/p/zO33GAbHwCoC8P9ojBQvnOWXeGUUefH857z+zWdWMoH0+TkAk/0 X-Received: by 10.28.231.19 with SMTP id e19mr4273332wmh.1.1511359178489; Wed, 22 Nov 2017 05:59:38 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1511359178; cv=none; d=google.com; s=arc-20160816; b=KROE9tVkVFjkFOymNTpSJyLXFSyZoKvKs2JRXKNDEyhl13Zc4cCu+85tmJpk148gKm SDm/WY/cZejVxWTgMFkWKuQAobHOWf2tocoMbTKe7vWEoQPmo06pdi7wqanewxftwY1F Q/dufoElNx82tQUqJ8NeZaOnYnYGwyUYR6xFXQj5qrg12iJgfj0yjmNnIWXQWrR8sj7o ZsFzJesisGItixLwac7FXKUocgG2eNpM10FAUXeDD9kOO/LJMNFmbbWDdMn5KZBgpvdQ 72s3vISKw8BcUoM17BZ97W0HugAuWpLalWKDAHrVXlyo3mlpNZWA1hJwZ+Ypx+8MzK5c kCQg== 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:references:in-reply-to:message-id:date :to:from:dkim-signature:delivered-to:arc-authentication-results; bh=4HQJj1gErGX+tSraz4WQ59H9KETzQ9cDj1bRNVeS+L0=; b=qDAExy75VwAcEe1R0gTi+4j7lxwVoqaaSaGWf5O52WasxEqR03ZdNS0PYOGNpt2wm6 2ZPQ5ExIY8pGkQjwKbKlnq3a7X6H3NwlOaOD7XzPfXIZwM2I+NYUsFN1L6E3kIzJhABR T52P1lAjG6TdXo6rFh1m8ONUZafQgIDE7FgGVeb7w0PvkWWSL1or5lGbGgEVjaocVrd3 GEhfCJ7EPDecVjf2IPC1EaghzJOhB+a5sPx/EkvBjY5nbKWHBQogAzDdKCKJj/5A3lK0 xDs+KkuXOd8atBVSIvv+lckGbKH+h7Nwcxd+etYebrwt8EihhSLhxeErQ6JKAL0rk1nv i8VQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=UA4AVcCA; 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=NONE dis=NONE) header.from=gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id m19si12737446wrb.121.2017.11.22.05.59.37; Wed, 22 Nov 2017 05:59:38 -0800 (PST) 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=@gmail.com header.s=20161025 header.b=UA4AVcCA; 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=NONE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 348DC68A16A; Wed, 22 Nov 2017 15:59:28 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pl0-f66.google.com (mail-pl0-f66.google.com [209.85.160.66]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id EAA7C680A27 for ; Wed, 22 Nov 2017 15:59:20 +0200 (EET) Received: by mail-pl0-f66.google.com with SMTP id l16so788534pli.6 for ; Wed, 22 Nov 2017 05:59:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=+5Unj4/K5dw2X6RVeyptZOYjbtRRkvLsyg2YglTg30M=; b=UA4AVcCAD5ZdKGV8gcLABXqQin5Orz7RC3l2QkDEBxdoQPEWzOf7gCFKGMzgDao+6l ixrpYE26RdtHKPa3VW6hTC8yb54wpxQaMt8rjR9ap3Qc1fwUcLajBx8anIUU/MGP8Cxi P6haem/1XRBNvexA5Ejr3Ed3ImvVy9OiZadRjAn55ZoAKo/i97d28V4Wwds9ifMlsm4f tuhLBWr4jCANJDUjxjMUkYNN6dEsvFSXfqdH1O6Iv3xNc/c4N6cPOXOWbj5wp9bHEFwW WUpMLJ5IFTSRLyFLlza1hdQYZIQ1FwNg2UZ0JY46RcL1ycypcWNSRYSRSrz/IqJmpxYT SSvQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=+5Unj4/K5dw2X6RVeyptZOYjbtRRkvLsyg2YglTg30M=; b=HunEgqVs0OfnljtKcMc5QmLT+lqMq1xZ1seQ0z2pAAHKBRdnG6L6nYKUQRfTHkO13/ mwZH3+9cdp3/pn4WOMiFbWzPsXrLFX6zq5MP3c4pXHXOHNWWLS2bG5pE1Qm1FYgpBA8d S9O4ycswFKEmHMcoMbPmbhFoQ7d+veSvoqFYxyz9+x3OeG1BIJx1Bp0qE7xrv4VKRBH/ MoR5WuFn71RKQ2e5yUVYoGMYi3rVRCp8DS48aAaS8TyvWKv3o7/UYlbpase8Z3mMX55b NuuuyrHX2RC+JdTph383OOA6Ssq9Qn/VSnP1E7fzeNHP/12o9fi6K7/au8/pdAxYblVN Xdhw== X-Gm-Message-State: AJaThX5QrslvOv9OZj4sBTk+cFL1NigUAExZFIiujxCg+0na3b9vVYE4 qGRLRJs7dVPE6RPX1rGkrG5Xmw== X-Received: by 10.84.233.8 with SMTP id j8mr1133918plk.231.1511359159227; Wed, 22 Nov 2017 05:59:19 -0800 (PST) Received: from Shengbins-Mac-mini.corp.bytedance.com ([103.48.142.82]) by smtp.googlemail.com with ESMTPSA id 13sm13111692pfs.112.2017.11.22.05.59.17 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 22 Nov 2017 05:59:18 -0800 (PST) From: Shengbin Meng To: ffmpeg-devel@ffmpeg.org Date: Wed, 22 Nov 2017 21:59:07 +0800 Message-Id: <20171122135910.20719-2-shengbinmeng@gmail.com> X-Mailer: git-send-email 2.13.6 (Apple Git-96) In-Reply-To: <20171122135910.20719-1-shengbinmeng@gmail.com> References: <20171122135910.20719-1-shengbinmeng@gmail.com> Subject: [FFmpeg-devel] [PATCH v2 2/5] avcodec/hevcdsp: Add NEON optimization for epel 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: Meng Wang MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" From: Meng Wang Signed-off-by: Meng Wang --- libavcodec/arm/Makefile | 3 +- libavcodec/arm/hevcdsp_epel_neon.S | 2068 ++++++++++++++++++++++++++++++++++++ libavcodec/arm/hevcdsp_init_neon.c | 458 ++++++++ 3 files changed, 2528 insertions(+), 1 deletion(-) create mode 100644 libavcodec/arm/hevcdsp_epel_neon.S diff --git a/libavcodec/arm/Makefile b/libavcodec/arm/Makefile index 1eeac5449e..1acda0b1f8 100644 --- a/libavcodec/arm/Makefile +++ b/libavcodec/arm/Makefile @@ -136,7 +136,8 @@ NEON-OBJS-$(CONFIG_DCA_DECODER) += arm/synth_filter_neon.o NEON-OBJS-$(CONFIG_HEVC_DECODER) += arm/hevcdsp_init_neon.o \ arm/hevcdsp_deblock_neon.o \ arm/hevcdsp_idct_neon.o \ - arm/hevcdsp_qpel_neon.o + arm/hevcdsp_qpel_neon.o \ + arm/hevcdsp_epel_neon.o NEON-OBJS-$(CONFIG_RV30_DECODER) += arm/rv34dsp_neon.o NEON-OBJS-$(CONFIG_RV40_DECODER) += arm/rv34dsp_neon.o \ arm/rv40dsp_neon.o diff --git a/libavcodec/arm/hevcdsp_epel_neon.S b/libavcodec/arm/hevcdsp_epel_neon.S new file mode 100644 index 0000000000..d0d93e8033 --- /dev/null +++ b/libavcodec/arm/hevcdsp_epel_neon.S @@ -0,0 +1,2068 @@ +/* + * Copyright (c) 2017 Meng Wang + * + * 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 "libavutil/arm/asm.S" +#include "neon.S" + +.macro regshuffle_d4 + vmov d16, d17 + vmov d17, d18 + vmov d18, d19 +.endm + +.macro regshuffle_q4 + vmov q0, q1 + vmov q1, q2 + vmov q2, q3 +.endm + +.macro vextin4 + pld [r2] + vld1.8 {q11}, [r2], r3 + vext.8 d16, d22, d23, #1 + vext.8 d17, d22, d23, #2 + vext.8 d18, d22, d23, #3 + vext.8 d19, d22, d23, #4 +.endm + +.macro loadin4 + pld [r2] + vld1.8 {d16}, [r2], r3 + pld [r2] + vld1.8 {d17}, [r2], r3 + pld [r2] + vld1.8 {d18}, [r2], r3 + pld [r2] + vld1.8 {d19}, [r2], r3 +.endm + +.macro epel_filter_1_32b + vmov.i16 d16, #58 + vmov.i16 d17, #10 + vmull.s16 q9, d2, d16 // 58*b0 + vmull.s16 q10, d3, d16 // 58*b1 + vmull.s16 q11, d4, d17 // 10*c0 + vmull.s16 q12, d5, d17 // 10*c1 + vadd.s32 q11, q9 + vadd.s32 q12, q10 + vaddl.s16 q9, d0, d6 + vaddl.s16 q10, d1, d7 + vshl.s32 q13, q9, #1 // 2*a + 2*d + vshl.s32 q14, q10, #1 + vsub.s32 q11, q13 // -2*a + 58*b + 10*c -2*d + vsub.s32 q12, q14 + vqshrn.s32 d16, q11, #6 + vqshrn.s32 d17, q12, #6 // out=q8 +.endm + +.macro epel_filter_2_32b + vmov.i16 d16, #54 + vmull.s16 q9, d2, d16 // 54*b0 + vmull.s16 q10, d3, d16 // 54*b1 + vshll.s16 q11, d4, #4 // 16*c0 + vshll.s16 q12, d5, #4 // 16*c1 + vadd.s32 q9, q11 + vadd.s32 q10, q12 + vshll.s16 q11, d0, #2 // 4*a0 + vshll.s16 q12, d1, #2 // 4*a1 + vshll.s16 q13, d6, #1 // 2*d0 + vshll.s16 q14, d7, #1 // 2*d0 + vadd.s32 q11, q13 + vadd.s32 q12, q14 + vsub.s32 q9, q11 // -4*a + 54*b + 16*c - 2*d + vsub.s32 q10, q12 + vqshrn.s32 d16, q9, #6 + vqshrn.s32 d17, q10, #6 // out=q8 +.endm + +.macro epel_filter_3_32b + vmov.i16 d16, #46 + vmull.s16 q9, d2, d16 // 46*b0 + vmull.s16 q10, d3, d16 // 46*b1 + vshll.s16 q11, d4, #5 + vshll.s16 q12, d5, #5 + vshll.s16 q13, d4, #2 + vshll.s16 q14, d5, #2 + vsub.s32 q11, q13 // 28*c0 + vsub.s32 q12, q14 // 28*c1 + vadd.s32 q9, q11 // 46*b0 + 28*c0 + vadd.s32 q10, q12 // 46*b1 + 28*c1 + vshll.s16 q11, d6, #2 // 4*d0 + vshll.s16 q12, d7, #2 // 4*d1 + vmov.i16 d16, #6 + vmull.s16 q13, d0, d16 // 6*a0 + vmull.s16 q14, d1, d16 // 6*a1 + vadd.s32 q11, q13 + vadd.s32 q12, q14 + vsub.s32 q9, q11 + vsub.s32 q10, q12 // -6*a + 46*b + 28*c - 4*d + vqshrn.s32 d16, q9, #6 + vqshrn.s32 d17, q10, #6 // out=q8 +.endm + +.macro epel_filter_4_32b + vaddl.s16 q9, d2, d4 + vaddl.s16 q10, d3, d5 + vshl.u32 q11, q9, #5 + vshl.u32 q12, q10, #5 + vshl.u32 q13, q9, #2 + vshl.u32 q14, q10, #2 + vadd.s32 q11, q13 // 36*b0 + 36*c0 + vadd.s32 q12, q14 // 36*b1 + 36*c1 + vaddl.s16 q9, d0, d6 + vaddl.s16 q10, d1, d7 + vshl.u32 q13, q9, #2 // 4*a0 + 4*d0 + vshl.u32 q14, q10, #2 // 4*a1 + 4*d1 + vsub.s32 q11, q13 // -4*a0 + 36*b0 + 36*c0 - 4*d0 + vsub.s32 q12, q14 // -4*a1 + 36*b1 + 36*c1 - 4*d1 + vqshrn.s32 d16, q11, #6 + vqshrn.s32 d17, q12, #6 // out=q8 +.endm + +.macro epel_filter_5_32b + vmov.i16 d16, #46 + vmull.s16 q9, d4, d16 // 46*c0 + vmull.s16 q10, d5, d16 // 46*c1 + vshll.s16 q11, d2, #5 + vshll.s16 q12, d3, #5 + vshll.s16 q13, d2, #2 + vshll.s16 q14, d3, #2 + vsub.s32 q11, q13 // 28*b0 + vsub.s32 q12, q14 // 28*b1 + vadd.s32 q9, q11 + vadd.s32 q10, q12 // 28*b + 46*c + vshll.s16 q11, d0, #2 // 4*a0 + vshll.s16 q12, d1, #2 // 4*a1 + vmov.i16 d16, #6 + vmull.s16 q13, d6, d16 // 6*d0 + vmull.s16 q14, d7, d16 // 6*d1 + vadd.s32 q11, q13 // 4*a0 + 6*d0 + vadd.s32 q12, q14 // 4*a1 + 6*d1 + vsub.s32 q9, q11 // -4*a0 + 28*b0 + 46*c0 - 6*d0 + vsub.s32 q10, q12 // -4*a1 + 28*b1 + 46*c1 - 6*d1 + vqshrn.s32 d16, q9, #6 + vqshrn.s32 d17, q10, #6 // out=q8 +.endm + +.macro epel_filter_6_32b + vmov.i16 d16, #54 + vmull.s16 q9, d4, d16 // 54*c0 + vmull.s16 q10, d5, d16 // 54*c1 + vshll.s16 q11, d2, #4 // 16*b0 + vshll.s16 q12, d3, #4 // 16*b1 + vadd.s32 q9, q11 // 54*c0 + 16*b0 + vadd.s32 q10, q12 // 54*c1 + 16*b1 + vshll.s16 q11, d0, #1 // 2*a0 + vshll.s16 q12, d1, #1 // 2*a1 + vshll.s16 q13, d6, #2 // 4*d0 + vshll.s16 q14, d7, #2 // 4*d1 + vadd.s32 q11, q13 // 2*a0 + 4*d0 + vadd.s32 q12, q14 // 2*a1 + 4*d1 + vsub.s32 q9, q11 // -2*a0 + 54*c0 + 16*b0 - 4*d0 + vsub.s32 q10, q12 // -2*a0 + 54*c0 + 16*b0 - 4*d0 + vqshrn.s32 d16, q9, #6 + vqshrn.s32 d17, q10, #6 // out=q8 +.endm + +.macro epel_filter_7_32b + vmov.i16 d16, #58 + vmull.s16 q9, d4, d16 // 58*c0 + vmull.s16 q10, d5, d16 // 58*c1 + vshll.s16 q11, d2, #3 + vshll.s16 q12, d3, #3 + vshll.s16 q13, d2, #1 + vshll.s16 q14, d3, #1 + vadd.s32 q11, q13 // 10*b0 + vadd.s32 q12, q14 // 10*b1 + vadd.s32 q9, q11 + vadd.s32 q10, q12 + vaddl.s16 q11, d0, d6 + vaddl.s16 q12, d1, d7 + vshl.s32 q13, q11, #1 // 2*a0 + 2*d0 + vshl.s32 q14, q12, #1 // 2*a1 + 2*d1 + vsub.s32 q9, q13 // -2*a0 + 10*b0 + 58*c0 -2*d0 + vsub.s32 q10, q14 // -2*a1 + 10*b1 + 58*c1 -2*d1 + vqshrn.s32 d16, q9, #6 + vqshrn.s32 d17, q10, #6 // out=q8 +.endm + +.macro epel_filter_1 out=q7 + vmov.u8 d24, #58 + vmov.u8 d25, #10 + vaddl.u8 q13, d16, d19 // a+d + vshl.u16 q14, q13, #1 // 2*a + 2*d + vmull.u8 q13, d17, d24 // 58*b + vsub.s16 q13, q14 // 58*b - 2*a - 2*d + vmull.u8 q14, d18, d25 // 10*c + vadd.s16 \out, q14, q13 // -2*a + 58*b + 10*c - 2*d +.endm + +.macro epel_filter_2 out=q7 + vmov.u8 d24, #54 + vmull.u8 q13, d17, d24 // 54*b + vshll.u8 q14, d18, #4 // 16*c + vadd.u16 q14, q13 // 54*b + 16*c + vshll.u8 q12, d16, #2 // 4*a + vshll.u8 q13, d19, #1 // 2*d + vadd.u16 q13, q12 // 4*a + 2*d + vsub.s16 \out, q14, q13 // -4*a + 54*b + 16*c - 2*d +.endm + +.macro epel_filter_3 out=q7 + vmov.u8 d24, #46 + vmull.u8 q13, d17, d24 // 46*b + vshll.u8 q14, d18, #5 // 32c + vshll.u8 q12, d18, #2 // 4c + vsub.u16 q14, q12 + vadd.u16 q14, q13 // 46*b + 28*c + vshll.u8 q13, d19, #2 // 4*d + vshll.u8 q12, d16, #2 // 4a + vshll.u8 q15, d16, #1 // 2a + vadd.u16 q12, q15 + vadd.u16 q12, q13 // 6*a + 4*d + vsub.s16 \out, q14, q12 // -6*a + 46*b + 28*c - 4*d +.endm + +.macro epel_filter_4 out=q7 + vaddl.u8 q13, d16, d19 + vshl.u16 q14, q13, #2 // 4*a + 4*d + vaddl.u8 q12, d17, d18 + vshl.u16 q15, q12, #5 + vshl.u16 q13, q12, #2 + vadd.u16 q15, q13 // 36*b + 36*c + vsub.s16 \out, q15, q14 // -4*a + 36*b + 36*c - 4*d +.endm + +.macro epel_filter_5 out=q7 + vaddl.u8 q12, d16, d19 + vshl.u16 q13, q12, #2 + vshll.u8 q12, d19, #1 + vadd.u16 q13, q12 // 4*a + 6*d + vshll.u8 q12, d17, #5 + vshll.u8 q15, d17, #2 + vsub.u16 q12, q15 // 28*b + vshll.u8 q14, d18, #5 + vshll.u8 q15, d18, #4 + vadd.u16 q14, q15 + vshll.u8 q15, d18, #1 + vsub.u16 q14, q15 // 46*c + vadd.u16 q12, q14 // 28*b + 46*c + vsub.s16 \out, q12, q13 // -4*a + 28*b + 46*c - 6*d +.endm + +.macro epel_filter_6 out=q7 + vmov.u8 d24, #54 + vmull.u8 q13, d18, d24 // 54*c + vshll.u8 q14, d17, #4 // 16*b + vshll.u8 q12, d16, #1 // 2*a + vshll.u8 q15, d19, #2 // 4*d + vadd.u16 q12, q15 + vadd.u16 q13, q14 + vsub.s16 \out, q13, q12 // -2*a + 16*b + 54*c - 4*d +.endm + +.macro epel_filter_7 out=q7 + vmov.u8 d24, #58 + vmull.u8 q13, d18, d24 // 58*c + vshll.u8 q12, d17, #3 + vshll.u8 q14, d17, #1 + vadd.u16 q12, q14 // 10*b + vaddl.u8 q14, d16, d19 + vshl.u16 q15, q14, #1 // 2*a + 2*d + vadd.u16 q13, q12 + vsub.s16 \out, q13, q15 // -2*a + 10*b + 58*c - 2*d +.endm + +.macro hevc_put_epel_vX_neon_8 filter + push {r4, r5, r6, r7} + ldr r4, [sp, #16] // height + ldr r5, [sp, #20] // width + vpush {d8-d15} + sub r2, r3 + mov r12, r4 + mov r6, r0 + mov r7, r2 + lsl r1, #1 +0: loadin4 + cmp r5, #4 + beq 4f + cmp r5, #2 + beq 2f +8: subs r4, #1 + \filter + vst1.16 {q7}, [r0], r1 + regshuffle_d4 + vld1.8 {d19}, [r2], r3 + bne 8b + subs r5, #8 + beq 99f + mov r4, r12 + add r6, #16 + mov r0, r6 + add r7, #8 + mov r2, r7 + b 0b +4: subs r4, #1 + \filter + vst1.16 d14, [r0], r1 + regshuffle_d4 + vld1.32 {d19[0]}, [r2], r3 + bne 4b + b 99f +2: subs r4, #1 + \filter + vmov.u16 r6, d14[0] + strh r6, [r0], r1 + regshuffle_d4 + vld1.32 {d19[0]}, [r2], r3 + bne 2b +99: vpop {d8-d15} + pop {r4, r5, r6, r7} + bx lr +.endm + +.macro hevc_put_epel_uw_vX_neon_8 filter + push {r4-r10} + ldr r5, [sp, #28] // width + ldr r4, [sp, #32] // height + ldr r8, [sp, #36] // src2 + ldr r9, [sp, #40] // src2stride + vpush {d8-d15} + sub r2, r3 + mov r12, r4 + mov r6, r0 + mov r7, r2 + cmp r8, #0 + bne .Lbi\@ +0: loadin4 + cmp r5, #4 + beq 4f + cmp r5, #2 + beq 2f +8: subs r4, #1 + \filter + vqrshrun.s16 d0, q7, #6 + vst1.8 d0, [r0], r1 + regshuffle_d4 + vld1.8 {d19}, [r2], r3 + bne 8b + subs r5, #8 + beq 99f + mov r4, r12 + add r6, #8 + mov r0, r6 + add r7, #8 + mov r2, r7 + b 0b +4: subs r4, #1 + \filter + vqrshrun.s16 d0, q7, #6 + vst1.32 d0[0], [r0], r1 + regshuffle_d4 + vld1.32 {d19[0]}, [r2], r3 + bne 4b + b 99f +2: subs r4, #1 + \filter + vqrshrun.s16 d0, q7, #6 + vmov.u16 r6, d0[0] + strh r6, [r0], r1 + regshuffle_d4 + vld1.32 {d19[0]}, [r2], r3 + bne 2b + b 99f +.Lbi\@: lsl r9, #1 + mov r10, r8 +0: loadin4 + cmp r5, #4 + beq 4f + cmp r5, #2 + beq 2f +8: subs r4, #1 + \filter + vld1.16 {q0}, [r8], r9 + vqadd.s16 q0, q7 + vqrshrun.s16 d0, q0, #7 + vst1.8 d0, [r0], r1 + regshuffle_d4 + vld1.8 {d19}, [r2], r3 + bne 8b + subs r5, #8 + beq 99f + mov r4, r12 + add r6, #8 + mov r0, r6 + add r10, #16 + mov r8, r10 + add r7, #8 + mov r2, r7 + b 0b +4: subs r4, #1 + \filter + vld1.16 d0, [r8], r9 + vqadd.s16 d0, d14 + vqrshrun.s16 d0, q0, #7 + vst1.32 d0[0], [r0], r1 + regshuffle_d4 + vld1.32 {d19[0]}, [r2], r3 + bne 4b + b 99f +2: subs r4, #1 + \filter + vld1.16 d0, [r8], r9 + vqadd.s16 d0, d14 + vqrshrun.s16 d0, q0, #7 + vmov.u16 r6, d0[0] + strh r6, [r0], r1 + regshuffle_d4 + vld1.32 {d19[0]}, [r2], r3 + bne 2b +99: vpop {d8-d15} + pop {r4-r10} + bx lr +.endm + +.macro hevc_put_epel_wt_vX_neon_8 filter + push {r4-r12} + ldr r5, [sp, #36] // width + ldr r4, [sp, #40] // height + ldr r8, [sp, #44] // denom + ldr r9, [sp, #48] // wx1 + ldr r10,[sp, #52] // ox1 + ldr r11,[sp, #64] // src2 + vpush {d8-d15} + sub r2, r3 + mov r12, r4 + mov r6, r0 + mov r7, r2 + add r8, #6 // weight shift = denom + 6 + vdup.32 q5, r8 // shift is a 32 bit action + vneg.s32 q4, q5 // q4 = -q5 + vdup.32 q6, r9 // q6 wx + vdup.32 q5, r10 // q5 ox + cmp r11, #0 // if src2 != 0 goto bi mode + bne .Lbi\@ +0: loadin4 + cmp r5, #4 + beq 4f + cmp r5, #2 + beq 2f +8: subs r4, #1 + \filter + vmovl.s16 q12, d14 // extending signed 4x16bit data to 4x32 bit + vmovl.s16 q13, d15 + vmul.s32 q14, q12, q6 // src * wx + vmul.s32 q15, q13, q6 // src * wx + vqrshl.s32 q12, q14, q4 // src * wx >> shift + vqrshl.s32 q13, q15, q4 // src * wx >> shift + vadd.s32 q14, q12, q5 // src * wx >> shift + ox + vadd.s32 q15, q13, q5 // src * wx >> shift + ox + vqmovun.s32 d2, q14 // narrow signed 4x32bit to unsigned 4x16bit + vqmovun.s32 d3, q15 // narrow signed 4x32bit to unsigned 4x16bit + vqmovn.u16 d0, q1 // narrow unsigned 8x16bit to unsigned 8x8bit + vst1.8 d0, [r0], r1 + regshuffle_d4 + vld1.8 {d19}, [r2], r3 + bne 8b + subs r5, #8 + beq 99f + mov r4, r12 + add r6, #8 + mov r0, r6 + add r7, #8 + mov r2, r7 + b 0b +4: subs r4, #1 + \filter + vmovl.s16 q12, d14 // extending signed 4x16bit data to 4x32 bit + vmul.s32 q14, q12, q6 + vqrshl.s32 q12, q14, q4 + vadd.s32 q14, q12, q5 + vqmovun.s32 d14, q14 + vqmovn.u16 d0, q7 + vst1.32 d0[0], [r0], r1 + regshuffle_d4 + vld1.32 {d19[0]}, [r2], r3 + bne 4b + b 99f +2: subs r4, #1 + \filter + vmovl.s16 q12, d14 // extending signed 4x16bit data to 4x32 bit + vmul.s32 q14, q12, q6 + vqrshl.s32 q12, q14, q4 + vadd.s32 q14, q12, q5 + vqmovun.s32 d14, q14 + vqmovn.u16 d0, q7 + vmov.u16 r6, d0[0] + strh r6, [r0], r1 + regshuffle_d4 + vld1.32 {d19[0]}, [r2], r3 + bne 2b + b 99f +.Lbi\@: ldr r8, [sp, #120] // w0 + vdup.32 q1, r8 // q1 wx0 + ldr r8, [sp, #124] // ox0 + vdup.32 q2, r8 // q2 ox0 + vadd.s32 q2, q5 // q2 = ox0 +ox1 + vmov.s32 q10, #1 + vadd.s32 q2, q10 // q2 = ox0 +ox1 + 1 + vneg.s32 q15, q4 // q15 = - q4, preperation for left shift + vqrshl.s32 q3, q2, q15 // q3 = (ox0 + ox1 + 1)<put_hevc_qpel[x][1][0] = ff_hevc_put_qpel_neon_wrapper; c->put_hevc_qpel[x][0][1] = ff_hevc_put_qpel_neon_wrapper; @@ -288,6 +731,21 @@ av_cold void ff_hevc_dsp_init_neon(HEVCDSPContext *c, const int bit_depth) c->put_hevc_qpel_bi_w[x][1][0] = ff_hevc_put_qpel_bi_w_neon_wrapper; c->put_hevc_qpel_bi_w[x][0][1] = ff_hevc_put_qpel_bi_w_neon_wrapper; c->put_hevc_qpel_bi_w[x][1][1] = ff_hevc_put_qpel_bi_w_neon_wrapper; + c->put_hevc_epel[x][1][0] = ff_hevc_put_epel_neon_wrapper; + c->put_hevc_epel[x][0][1] = ff_hevc_put_epel_neon_wrapper; + c->put_hevc_epel[x][1][1] = ff_hevc_put_epel_neon_wrapper; + c->put_hevc_epel_uni[x][1][0] = ff_hevc_put_epel_uni_neon_wrapper; + c->put_hevc_epel_uni[x][0][1] = ff_hevc_put_epel_uni_neon_wrapper; + c->put_hevc_epel_uni[x][1][1] = ff_hevc_put_epel_uni_neon_wrapper; + c->put_hevc_epel_bi[x][1][0] = ff_hevc_put_epel_bi_neon_wrapper; + c->put_hevc_epel_bi[x][0][1] = ff_hevc_put_epel_bi_neon_wrapper; + c->put_hevc_epel_bi[x][1][1] = ff_hevc_put_epel_bi_neon_wrapper; + c->put_hevc_epel_uni_w[x][1][0] = ff_hevc_put_epel_uni_w_neon_wrapper; + c->put_hevc_epel_uni_w[x][0][1] = ff_hevc_put_epel_uni_w_neon_wrapper; + c->put_hevc_epel_uni_w[x][1][1] = ff_hevc_put_epel_uni_w_neon_wrapper; + c->put_hevc_epel_bi_w[x][1][0] = ff_hevc_put_epel_bi_w_neon_wrapper; + c->put_hevc_epel_bi_w[x][0][1] = ff_hevc_put_epel_bi_w_neon_wrapper; + c->put_hevc_epel_bi_w[x][1][1] = ff_hevc_put_epel_bi_w_neon_wrapper; } c->put_hevc_qpel[0][0][0] = ff_hevc_put_pixels_w2_neon_8; c->put_hevc_qpel[1][0][0] = ff_hevc_put_pixels_w4_neon_8;