From patchwork Wed Nov 22 11:12:02 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shengbin Meng X-Patchwork-Id: 6266 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.2.161.94 with SMTP id m30csp33064jah; Wed, 22 Nov 2017 03:19:46 -0800 (PST) X-Google-Smtp-Source: AGs4zMb4JuRZBXdUHFR2Gigay/iMbK4IwFXkWtZTw0WeZ6v6ba4KbACv6dv93EGQPk1JWnjDOOLK X-Received: by 10.223.157.27 with SMTP id k27mr13332392wre.153.1511349586832; Wed, 22 Nov 2017 03:19:46 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1511349586; cv=none; d=google.com; s=arc-20160816; b=RXr9ZHS/FsQE4vvDF+4qonfSut5JUqopf19jhKdRoQjRPr1z6d9gYwL9vTqnUSjm94 CBb48wYcEp/7lduN5Rub/515eyfVYrsenuJPvlem4Axddu2ZBwdjEo2JDN3FLYLjHyTx 9/TI1cfXIq3LvBEjylk+yxGW7H68bA8ckx4O6Q39d2jfp24tjM9AostwlgE3SVNO9A8I SSZAUjwehSVNL0VWQ7Sb+h6yjeyMBM3KBqn6ttjRSiIp/Kp6OB6j4tg9pjgE4GoFNuY1 hshmO+QhCK4/Vml+UwvoI7zZfoXu21a793YsUejMJ627nBAWUcquF2YheDy5+y9ExhLY WP+g== 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=ToosZBqhU9L3oa8L6FtBspXD2iifvZKhNMgA9fcLCow=; b=M4EyN+QdDQIfurTfUKqyo+4smrA1/65TO7VfQ43hVVT+iF1e0ONmE5GpjgkYOOiXWg W/LBIFmKN1BAvrsP0ET4akBVslQZ1DGhRxU52//96WqxbxxlvL9cie6tLKIP6nC9Gxog GfCTLRLcEmW3nflg+f3YjL9o+iyJLydhZ5mBwwJpyRy/c1l4PyYKqeAxF5I+ciCEXY/u RH/CoK4hx8aiKdj1UO/u9s7WXDt4thC8dkFNVom2jEHXszmcAdDYWDOd/eUk1r0y5GDm cWsg5vr397mgOs9AsU0pauXM3fzJzFVFaJPW2Bodzqpv/QNXx+TLiyel7oImkPOWZeHc SQXg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=DxRetK7e; 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 o7si13001044wro.100.2017.11.22.03.19.46; Wed, 22 Nov 2017 03:19:46 -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=DxRetK7e; 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 170F968A131; Wed, 22 Nov 2017 13:19:45 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pl0-f67.google.com (mail-pl0-f67.google.com [209.85.160.67]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 0819B68A107 for ; Wed, 22 Nov 2017 13:19:38 +0200 (EET) Received: by mail-pl0-f67.google.com with SMTP id z3so554816plh.9 for ; Wed, 22 Nov 2017 03:19:38 -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=DJ39aOzjJP2J/Mf5klBYrit2rGIn0HH1+7BUklZuaHo=; b=DxRetK7eBa4Vk7lV3V/rOrdPrKPWTJq2v0/iyBo02SrAPo5YO+/eGwMkExu0WKDXes v0zoa/5I1EwD9J8lmnEfzoLw98clxyz09vsbvt1ZXhhfBj7+HXXDm+eVXJDDEiOUUXmb CzovaYtR6IuwO6b8h9uwDd2JQcbln7hRHlZ50emaNTLJuyTNGLwVQ7HO0GyOGnGSaM+8 NOxtcVJkPBmC6682af5XxRi8vXQscK8VRlmJ6Cbx6PEMLEZaf3das8IHpN3Ska87GlTt 4iIGAYvRMASwTcTNoVrQFGEpo3H180V3BmqXb4X0Gkxan+2AxyTSDt/ogcjw1Zt0Cq9q vI/A== 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=DJ39aOzjJP2J/Mf5klBYrit2rGIn0HH1+7BUklZuaHo=; b=UT0ncmhXWVUEjQQcku45vFjBKGoAdk4muek0HF9Ed1nzxFOKVjIjt0BwVwnYNUJWr5 B2xVNoNI71e9yTllPAMipa1M8RJPlFrm9VzLdlUvFMELXVivB/n7YZRpYhdeSqeVjkNq XuYiRoBluVpQpztkWeSvlDcJ3qLSmLLOvQwWl7+ELKXQ06lWzUMEekuCUbg3EM8mIq51 zZC3eVbFrYT4G3hDpzPonsLsg9AZ6TXy6Tjlbn/rDxWt99N52B+tAsQYbk5TOXCkzjLA 996fzFIV9WVw4/s4rkFgC4VVceV2+eSw1BJzXmeRw4aU1twvZW6x2azDUoS4CK6t1RAI 3dAA== X-Gm-Message-State: AJaThX7M1BwvDpjXebvWlRC2H/31lWmaqOiQRxGKF9bwiKSdFNC+NaUC /W/3gPLiZkrfU1HeLn7Lx98x/A== X-Received: by 10.84.231.2 with SMTP id f2mr20492057plk.256.1511349136802; Wed, 22 Nov 2017 03:12:16 -0800 (PST) Received: from Shengbins-Mac-mini.corp.bytedance.com ([103.48.142.82]) by smtp.googlemail.com with ESMTPSA id 69sm29516227pft.11.2017.11.22.03.12.14 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 22 Nov 2017 03:12:16 -0800 (PST) From: Shengbin Meng To: ffmpeg-devel@ffmpeg.org Date: Wed, 22 Nov 2017 19:12:02 +0800 Message-Id: <20171122111206.17214-3-shengbinmeng@gmail.com> X-Mailer: git-send-email 2.13.6 (Apple Git-96) In-Reply-To: <20171122111206.17214-1-shengbinmeng@gmail.com> References: <20171122111206.17214-1-shengbinmeng@gmail.com> Subject: [FFmpeg-devel] [PATCH 2/6] 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 | 459 ++++++++ 3 files changed, 2529 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; @@ -267,6 +711,21 @@ av_cold void ff_hevcdsp_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;