[FFmpeg-devel] [PATCH v2 2/5] avcodec/hevcdsp: Add NEON optimization for epel

Shengbin Meng shengbinmeng at gmail.com
Wed Nov 22 15:59:07 EET 2017


From: Meng Wang <wangmeng.kids at bytedance.com>

Signed-off-by: Meng Wang <wangmeng.kids at bytedance.com>
---
 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 <wangmeng.kids at bytedance.com>
+ *
+ * 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)<<shift
+        vsub.s32    q4,   q10
+        ldr         r9,   [sp, #132]  // src2stride
+        lsl         r9,   #1
+        mov         r10,  r11         // r10 store startpoint src2
+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 * w1
+        vmul.s32      q15, q13,     q6  // src * w1
+        vld1.16       {q0}, [r11],  r9  // load 8x16 bit pixels from src2 to q0
+        vmovl.s16     q2,   d0          // extend signed 4x16bit to 4x32 bit
+        vmovl.s16     q5,   d1
+        vmul.s32      q2,   q1          // src2 * w0
+        vmul.s32      q5,   q1          // src2 * w0
+        vadd.s32      q14,  q2          // src * w1 + src2 * w0
+        vadd.s32      q15,  q5          // src * w1 + src2 * w0
+        vadd.s32      q14,  q3          // (src* w1 + src2 * w0 +(ox0 + ox1 + 1))<<shift
+        vadd.s32      q15,  q3
+        vqshl.s32     q12,  q14, q4     // shift
+        vqshl.s32     q13,  q15, q4     // shift
+        vqmovun.s32   d28,   q12        // narrow
+        vqmovun.s32   d29,   q13        // narrow
+        vqmovn.u16    d0,   q14         // narrow
+        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 r11, r10
+        add r7, #8
+        mov r2, r7
+        b     0b
+4:      subs r4, #1
+        \filter
+        vmovl.s16    q12, d14
+        vmul.s32     q14, q12, q6
+        vld1.16      d0, [r11], r9
+        vmovl.s16    q2,  d0
+        vmul.s32     q2,  q1
+        vadd.s32     q14, q2
+        vadd.s32     q14, q3
+        vqshl.s32    q12, q14, q4      // shift
+        vqmovun.s32  d28, q12          // narrow
+        vqmovn.u16   d0,  q14          // narrow
+        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
+        vmul.s32     q14, q12, q6
+        vld1.16      d0, [r11], r9
+        vmovl.s16    q2,  d0
+        vmul.s32     q2,  q1
+        vadd.s32     q14, q2
+        vadd.s32     q14, q3
+        vqshl.s32    q12, q14, q4      // shift
+        vqmovun.s32  d28, q12          // narrow
+        vqmovn.u16   d0,  q14          // narrow
+        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-r12}
+        bx lr
+.endm
+
+function ff_hevc_put_epel_v1_neon_8, export=1
+        hevc_put_epel_vX_neon_8 epel_filter_1
+endfunc
+
+function ff_hevc_put_epel_v2_neon_8, export=1
+        hevc_put_epel_vX_neon_8 epel_filter_2
+endfunc
+
+function ff_hevc_put_epel_v3_neon_8, export=1
+        hevc_put_epel_vX_neon_8 epel_filter_3
+endfunc
+
+function ff_hevc_put_epel_v4_neon_8, export=1
+        hevc_put_epel_vX_neon_8 epel_filter_4
+endfunc
+
+function ff_hevc_put_epel_v5_neon_8, export=1
+        hevc_put_epel_vX_neon_8 epel_filter_5
+endfunc
+
+function ff_hevc_put_epel_v6_neon_8, export=1
+        hevc_put_epel_vX_neon_8 epel_filter_6
+endfunc
+
+function ff_hevc_put_epel_v7_neon_8, export=1
+        hevc_put_epel_vX_neon_8 epel_filter_7
+endfunc
+
+
+function ff_hevc_put_epel_uw_v1_neon_8, export=1
+        hevc_put_epel_uw_vX_neon_8 epel_filter_1
+endfunc
+
+function ff_hevc_put_epel_uw_v2_neon_8, export=1
+        hevc_put_epel_uw_vX_neon_8 epel_filter_2
+endfunc
+
+function ff_hevc_put_epel_uw_v3_neon_8, export=1
+        hevc_put_epel_uw_vX_neon_8 epel_filter_3
+endfunc
+
+function ff_hevc_put_epel_uw_v4_neon_8, export=1
+        hevc_put_epel_uw_vX_neon_8 epel_filter_4
+endfunc
+
+function ff_hevc_put_epel_uw_v5_neon_8, export=1
+        hevc_put_epel_uw_vX_neon_8 epel_filter_5
+endfunc
+
+function ff_hevc_put_epel_uw_v6_neon_8, export=1
+        hevc_put_epel_uw_vX_neon_8 epel_filter_6
+endfunc
+
+function ff_hevc_put_epel_uw_v7_neon_8, export=1
+        hevc_put_epel_uw_vX_neon_8 epel_filter_7
+endfunc
+
+function ff_hevc_put_epel_wt_v1_neon_8, export=1
+        hevc_put_epel_wt_vX_neon_8 epel_filter_1
+endfunc
+
+function ff_hevc_put_epel_wt_v2_neon_8, export=1
+        hevc_put_epel_wt_vX_neon_8 epel_filter_2
+endfunc
+
+function ff_hevc_put_epel_wt_v3_neon_8, export=1
+        hevc_put_epel_wt_vX_neon_8 epel_filter_3
+endfunc
+
+function ff_hevc_put_epel_wt_v4_neon_8, export=1
+        hevc_put_epel_wt_vX_neon_8 epel_filter_4
+endfunc
+
+function ff_hevc_put_epel_wt_v5_neon_8, export=1
+        hevc_put_epel_wt_vX_neon_8 epel_filter_5
+endfunc
+
+function ff_hevc_put_epel_wt_v6_neon_8, export=1
+        hevc_put_epel_wt_vX_neon_8 epel_filter_6
+endfunc
+
+function ff_hevc_put_epel_wt_v7_neon_8, export=1
+        hevc_put_epel_wt_vX_neon_8 epel_filter_7
+endfunc
+
+.macro hevc_put_epel_hX_neon_8 filter
+        push     {r4, r5, r6, r7}
+        ldr    r4, [sp, #16] // height
+        ldr    r5, [sp, #20] // width
+
+        vpush    {d8-d15}
+        sub       r2, #2
+        lsl       r1, #1
+        mov      r12, r4
+        mov       r6, r0
+        mov       r7, r2
+        cmp       r5, #4
+        beq       4f
+        cmp       r5, #2
+        beq       2f
+8:      subs      r4, #1
+        vextin4
+        \filter
+        vst1.16   {q7}, [r0], r1
+        bne       8b
+        subs      r5, #8
+        beq      99f
+        mov       r4, r12
+        add       r6, #16
+        mov       r0, r6
+        add       r7, #8
+        mov       r2, r7
+        cmp       r5, #4
+        bne       8b
+4:      subs      r4, #1
+        vextin4
+        \filter
+        vst1.16  d14, [r0], r1
+        bne       4b
+        b         99f
+2:      subs      r4, #1
+        vextin4
+        \filter
+        vmov.u16       r6, d14[0]
+        strh           r6, [r0], r1
+        bne       2b
+99:     vpop     {d8-d15}
+        pop      {r4, r5, r6, r7}
+        bx lr
+.endm
+
+.macro hevc_put_epel_uw_hX_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, #2
+        mov      r12, r4
+        mov       r6, r0
+        mov       r7, r2
+        cmp       r8, #0
+        bne       .Lbi\@
+        cmp       r5, #4
+        beq       4f
+        cmp       r5, #2
+        beq       2f
+8:      subs      r4, #1
+        vextin4
+        \filter
+        vqrshrun.s16   d0, q7, #6
+        vst1.8    d0, [r0], r1
+        bne       8b
+        subs      r5, #8
+        beq      99f
+        mov       r4, r12
+        add       r6, #8
+        mov       r0, r6
+        add       r7, #8
+        mov       r2, r7
+        cmp       r5, #4
+        bne       8b
+4:      subs      r4, #1
+        vextin4
+        \filter
+        vqrshrun.s16   d0, q7, #6
+        vst1.32  d0[0], [r0], r1
+        bne       4b
+        b         99f
+2:      subs      r4, #1
+        vextin4
+        \filter
+        vqrshrun.s16   d0, q7, #6
+        vmov.u16       r6, d0[0]
+        strh           r6, [r0], r1
+        bne            2b
+        b              99f
+.Lbi\@:
+        lsl       r9, #1
+        cmp       r5, #4
+        beq       4f
+        cmp       r5, #2
+        beq       2f
+        mov       r10, r8
+8:      subs      r4, #1
+        vextin4
+        \filter
+        vld1.16        {q0}, [r8], r9
+        vqadd.s16      q0, q7
+        vqrshrun.s16   d0, q0, #7
+        vst1.8         d0, [r0], r1
+        bne       8b
+        subs      r5, #8
+        beq      99f
+        mov       r4, r12
+        add       r6, #8
+        add       r10, #16
+        mov       r8, r10
+        mov       r0, r6
+        add       r7, #8
+        mov       r2, r7
+        cmp       r5, #4
+        bne       8b
+4:      subs      r4, #1
+        vextin4
+        \filter
+        vld1.16      d0, [r8], r9
+        vqadd.s16    d0, d14
+        vqrshrun.s16 d0, q0, #7
+        vst1.32      d0[0], [r0], r1
+        bne       4b
+        b         99f
+2:      subs      r4, #1
+        vextin4
+        \filter
+        vld1.16      d0, [r8], r9
+        vqadd.s16    d0, d14
+        vqrshrun.s16 d0, q0, #7
+        vmov.u16       r6, d0[0]
+        strh           r6, [r0], r1
+        bne            2b
+99:     vpop     {d8-d15}
+        pop      {r4-r10}
+        bx lr
+.endm
+
+.macro hevc_put_epel_wt_hX_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, #2
+        mov      r12, r4
+        mov       r6, r0
+        mov       r7, r2
+        add       r8, #6       // weight shift = denom + 6
+        vdup.32   q5, r8       // dup shift to 32 bit
+        vneg.s32  q4, q5       // q4 = -q5 shift
+        vdup.32   q6, r9       // q6 wx
+        vdup.32   q5, r10      // q5 ox
+        cmp       r11, #0      // if src2 != 0 goto bi mode
+        bne       .Lbi\@
+        cmp       r5, #4
+        beq       4f
+        cmp       r5, #2
+        beq       2f
+8:      subs      r4, #1
+        vextin4
+        \filter
+        vmovl.s16     q12, d14    // extending signed 4x16bit data to 4x32 bit
+        vmovl.s16     q13, d15
+        vmul.s32      q14, q12, q6
+        vmul.s32      q15, q13, q6
+        vqrshl.s32    q12, q14, q4
+        vqrshl.s32    q13, q15, q4
+        vadd.s32      q14, q12, q5
+        vadd.s32      q15, q13, q5
+        vqmovun.s32   d2,  q14       // narrow
+        vqmovun.s32   d3,  q15       // narrow
+        vqmovn.u16    d0,  q1
+        vst1.8    d0, [r0], r1
+        bne       8b
+        subs      r5, #8
+        beq      99f
+        mov       r4, r12
+        add       r6, #8
+        mov       r0, r6
+        add       r7, #8
+        mov       r2, r7
+        cmp       r5, #4
+        bne       8b
+4:      subs      r4, #1
+        vextin4
+        \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
+        bne       4b
+        b         99f
+2:      subs      r4, #1
+        vextin4
+        \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
+        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)<<shift
+        vsub.s32    q4,   q10
+        ldr         r9,   [sp, #132]  // src2stride
+        lsl         r9,   #1
+        cmp         r5,   #4
+        beq         4f
+        cmp         r5, #2
+        beq         2f
+        mov         r10,  r11
+8:      subs        r4,   #1
+        vextin4
+        \filter
+        vmovl.s16     q12, d14          // extending signed 4x16bit data to 4x32 bit
+        vmovl.s16     q13, d15
+        vmul.s32      q14, q12,     q6  // src * w1
+        vmul.s32      q15, q13,     q6  // src * w1
+        vld1.16       {q0}, [r11],  r9  // load 8x16 bit pixels from src2 to q0
+        vmovl.s16     q2,   d0          // extend signed 4x16bit to 4x32 bit
+        vmovl.s16     q5,   d1
+        vmul.s32      q2,   q1          // src2 * w0
+        vmul.s32      q5,   q1          // src2 * w0
+        vadd.s32      q14,  q2          // src * w1 + src2 * w0
+        vadd.s32      q15,  q5          // src * w1 + src2 * w0
+        vadd.s32      q14,  q3          // (src* w1 + src2 * w0 +(ox0 + ox1 + 1))<<shift
+        vadd.s32      q15,  q3
+        vqshl.s32     q12,  q14,     q4 // shift
+        vqshl.s32     q13,  q15,     q4 // shift
+        vqmovun.s32   d28,  q12         // narrow
+        vqmovun.s32   d29,  q13         // narrow
+        vqmovn.u16    d0,   q14         // narrow
+        vst1.8        d0,   [r0], r1
+        bne           8b
+        subs          r5,   #8
+        beq           99f
+        mov           r4,   r12
+        add           r6,   #8
+        add           r10,  #16
+        mov           r11,  r10
+        mov           r0,   r6
+        add           r7,   #8
+        mov           r2,   r7
+        cmp           r5,   #4
+        bne           8b
+4:      subs          r4,   #1
+        vextin4
+        \filter
+        vmovl.s16     q12,  d14
+        vmul.s32      q14,  q12,   q6
+        vld1.16       d0,   [r11], r9
+        vmovl.s16     q2,   d0
+        vmul.s32      q2,   q1
+        vadd.s32      q14,  q2
+        vadd.s32      q14,  q3
+        vqshl.s32     q12,  q14,   q4    // shift
+        vqmovun.s32   d28,  q12          // narrow
+        vqmovn.u16    d0,   q14          // narrow
+        vst1.32       d0[0], [r0], r1
+        bne       4b
+        b         99f
+2:      subs          r4,   #1
+        vextin4
+        \filter
+        vmovl.s16     q12,  d14
+        vmul.s32      q14,  q12,   q6
+        vld1.16       d0,   [r11], r9
+        vmovl.s16     q2,   d0
+        vmul.s32      q2,   q1
+        vadd.s32      q14,  q2
+        vadd.s32      q14,  q3
+        vqshl.s32     q12,  q14,   q4    // shift
+        vqmovun.s32   d28,  q12          // narrow
+        vqmovn.u16    d0,   q14          // narrow
+        vmov.u16      r6, d0[0]
+        strh          r6, [r0], r1
+        bne           2b
+99:     vpop     {d8-d15}
+        pop      {r4-r12}
+        bx lr
+.endm
+
+function ff_hevc_put_epel_h1_neon_8, export=1
+        hevc_put_epel_hX_neon_8 epel_filter_1
+endfunc
+
+function ff_hevc_put_epel_h2_neon_8, export=1
+        hevc_put_epel_hX_neon_8 epel_filter_2
+endfunc
+
+function ff_hevc_put_epel_h3_neon_8, export=1
+        hevc_put_epel_hX_neon_8 epel_filter_3
+endfunc
+
+function ff_hevc_put_epel_h4_neon_8, export=1
+        hevc_put_epel_hX_neon_8 epel_filter_4
+endfunc
+
+function ff_hevc_put_epel_h5_neon_8, export=1
+        hevc_put_epel_hX_neon_8 epel_filter_5
+endfunc
+
+function ff_hevc_put_epel_h6_neon_8, export=1
+        hevc_put_epel_hX_neon_8 epel_filter_6
+endfunc
+
+function ff_hevc_put_epel_h7_neon_8, export=1
+        hevc_put_epel_hX_neon_8 epel_filter_7
+endfunc
+
+
+function ff_hevc_put_epel_uw_h1_neon_8, export=1
+        hevc_put_epel_uw_hX_neon_8 epel_filter_1
+endfunc
+
+function ff_hevc_put_epel_uw_h2_neon_8, export=1
+        hevc_put_epel_uw_hX_neon_8 epel_filter_2
+endfunc
+
+function ff_hevc_put_epel_uw_h3_neon_8, export=1
+        hevc_put_epel_uw_hX_neon_8 epel_filter_3
+endfunc
+
+function ff_hevc_put_epel_uw_h4_neon_8, export=1
+        hevc_put_epel_uw_hX_neon_8 epel_filter_4
+endfunc
+
+function ff_hevc_put_epel_uw_h5_neon_8, export=1
+        hevc_put_epel_uw_hX_neon_8 epel_filter_5
+endfunc
+
+function ff_hevc_put_epel_uw_h6_neon_8, export=1
+        hevc_put_epel_uw_hX_neon_8 epel_filter_6
+endfunc
+
+function ff_hevc_put_epel_uw_h7_neon_8, export=1
+        hevc_put_epel_uw_hX_neon_8 epel_filter_7
+endfunc
+
+function ff_hevc_put_epel_wt_h1_neon_8, export=1
+        hevc_put_epel_wt_hX_neon_8 epel_filter_1
+endfunc
+
+function ff_hevc_put_epel_wt_h2_neon_8, export=1
+        hevc_put_epel_wt_hX_neon_8 epel_filter_2
+endfunc
+
+function ff_hevc_put_epel_wt_h3_neon_8, export=1
+        hevc_put_epel_wt_hX_neon_8 epel_filter_3
+endfunc
+
+function ff_hevc_put_epel_wt_h4_neon_8, export=1
+        hevc_put_epel_wt_hX_neon_8 epel_filter_4
+endfunc
+
+function ff_hevc_put_epel_wt_h5_neon_8, export=1
+        hevc_put_epel_wt_hX_neon_8 epel_filter_5
+endfunc
+
+function ff_hevc_put_epel_wt_h6_neon_8, export=1
+        hevc_put_epel_wt_hX_neon_8 epel_filter_6
+endfunc
+
+function ff_hevc_put_epel_wt_h7_neon_8, export=1
+        hevc_put_epel_wt_hX_neon_8 epel_filter_7
+endfunc
+
+.macro hevc_put_epel_hXvY_neon_8 filterh filterv
+        push   {r4, r5, r6, r7}
+        ldr    r4, [sp, #16] // height
+        ldr    r5, [sp, #20] // width
+
+        vpush {d8-d15}
+        sub       r2, #2
+        sub       r2, r3  // extra_before 3
+        lsl       r1, #1
+        mov       r12, r4
+        mov       r6, r0
+        mov       r7, r2
+0:      vextin4
+        \filterh q0
+        vextin4
+        \filterh q1
+        vextin4
+        \filterh q2
+        vextin4
+        \filterh q3
+        cmp r5, #4
+        beq 4f
+        cmp r5, #2
+        beq 2f
+8:      subs  r4, #1
+        \filterv
+        vst1.16    {q8}, [r0], r1
+        regshuffle_q4
+        vextin4
+        \filterh q3
+        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
+        \filterv
+        vst1.16    d16, [r0], r1
+        regshuffle_q4
+        vextin4
+        \filterh q3
+        bne 4b
+        b   99f
+2:      subs  r4, #1
+        \filterv
+        vmov.u16      r6, d16[0]
+        strh          r6, [r0], r1
+        regshuffle_q4
+        vextin4
+        \filterh q3
+        bne           2b
+99:     vpop {d8-d15}
+        pop {r4, r5, r6, r7}
+        bx lr
+.endm
+
+.macro hevc_put_epel_uw_hXvY_neon_8 filterh filterv
+        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, #2
+        sub       r2, r3  // extra_before 3
+        mov       r12, r4
+        mov       r6, r0
+        mov       r7, r2
+        cmp       r8, #0
+        bne       .Lbi\@
+0:      vextin4
+        \filterh q0
+        vextin4
+        \filterh q1
+        vextin4
+        \filterh q2
+        vextin4
+        \filterh q3
+        cmp r5, #4
+        beq 4f
+        cmp r5, #2
+        beq 2f
+8:      subs  r4, #1
+        \filterv
+        vqrshrun.s16   d0, q8, #6
+        vst1.8    d0, [r0], r1
+        regshuffle_q4
+        vextin4
+        \filterh q3
+        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
+        \filterv
+        vqrshrun.s16   d0, q8, #6
+        vst1.32        d0[0], [r0], r1
+        regshuffle_q4
+        vextin4
+        \filterh q3
+        bne 4b
+        b   99f
+2:      subs  r4, #1
+        \filterv
+        vqrshrun.s16   d0, q8, #6
+        vmov.u16      r6, d0[0]
+        strh          r6, [r0], r1
+        regshuffle_q4
+        vextin4
+        \filterh q3
+        bne           2b
+        b             99f
+.Lbi\@: lsl      r9, #1
+        mov      r10, r8
+0:      vextin4
+        \filterh q0
+        vextin4
+        \filterh q1
+        vextin4
+        \filterh q2
+        vextin4
+        \filterh q3
+        cmp r5, #4
+        beq 4f
+        cmp r5, #2
+        beq 2f
+8:      subs  r4, #1
+        \filterv
+        vld1.16        {q0}, [r8], r9
+        vqadd.s16      q0, q8
+        vqrshrun.s16   d0, q0, #7
+        vst1.8         d0, [r0], r1
+        regshuffle_q4
+        vextin4
+        \filterh q3
+        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
+        \filterv
+        vld1.16      d0, [r8], r9
+        vqadd.s16    d0, d16
+        vqrshrun.s16 d0, q0, #7
+        vst1.32      d0[0], [r0], r1
+        regshuffle_q4
+        vextin4
+        \filterh q3
+        bne 4b
+        b 99f
+2:      subs  r4, #1
+        \filterv
+        vld1.16      d0, [r8], r9
+        vqadd.s16    d0, d16
+        vqrshrun.s16 d0, q0, #7
+        vmov.u16      r6, d0[0]
+        strh          r6, [r0], r1
+        regshuffle_q4
+        vextin4
+        \filterh q3
+        bne 2b
+99:     vpop {d8-d15}
+        pop {r4-r10}
+        bx lr
+.endm
+
+.macro hevc_put_epel_wt_hXvY_neon_8 filterh filterv
+        push     {r4-r12}
+        ldr       r5, [sp, #36] // width
+        ldr       r4, [sp, #40] // height
+        ldr       r8, [sp, #44] // denom
+        ldr       r9, [sp, #48] // wx
+        ldr       r10,[sp, #52] // ox
+        ldr       r11,[sp, #64] //src2
+        vpush {d8-d15}
+        sub       r2, #2
+        sub       r2, r3  // extra_before 3
+        mov       r12, r4
+        mov       r6, r0
+        mov       r7, r2
+        add       r8, #6
+        vdup.32   q6, r8
+        vneg.s32  q5, q6      // q5 shift
+        vdup.32   q4, r9      // q4 wx
+        vdup.32   q6, r10     // q6 ox
+        vpush     {q4-q6}
+        cmp       r11, #0
+        bne       .Lbi\@
+0:      vextin4
+        \filterh q0
+        vextin4
+        \filterh q1
+        vextin4
+        \filterh q2
+        vextin4
+        \filterh q3
+        cmp r5, #4
+        beq 4f
+        cmp r5, #2
+        beq 2f
+8:      subs  r4, #1
+        \filterv
+        vpop            {q9-q11}     // q9: wx q10: shift q11: ox
+        vmovl.s16       q12, d16
+        vmovl.s16       q13, d17
+        vmul.s32        q14, q12, q9
+        vmul.s32        q15, q13, q9
+        vqrshl.s32      q12, q14, q10
+        vqrshl.s32      q13, q15, q10
+        vadd.s32        q14, q12, q11
+        vadd.s32        q15, q13, q11
+        vqmovun.s32     d24, q14
+        vqmovun.s32     d25, q15
+        vqmovn.u16      d0,  q12
+        vst1.8          d0, [r0], r1
+        vpush           {q9-q11}
+        regshuffle_q4
+        vextin4
+        \filterh q3
+        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
+        \filterv
+        vpop            {q9-q11}     // q9: wx q10: shift q11: ox
+        vmovl.s16       q12, d16
+        vmul.s32        q14, q12, q9
+        vqrshl.s32      q12, q14, q10
+        vadd.s32        q14, q12, q11
+        vqmovun.s32     d24, q14
+        vqmovn.u16      d0,  q12
+        vst1.32         d0[0], [r0], r1
+        vpush           {q9-q11}
+        regshuffle_q4
+        vextin4
+        \filterh q3
+        bne 4b
+        b   99f
+2:      subs  r4, #1
+        \filterv
+        vpop            {q9-q11}     // q9: wx q10: shift q11: ox
+        vmovl.s16       q12, d16
+        vmul.s32        q14, q12, q9
+        vqrshl.s32      q12, q14, q10
+        vadd.s32        q14, q12, q11
+        vqmovun.s32     d24, q14
+        vqmovn.u16      d0,  q12
+        vmov.u16      r6, d0[0]
+        strh          r6, [r0], r1
+        vpush           {q9-q11}
+        regshuffle_q4
+        vextin4
+        \filterh q3
+        bne 2b
+        b   99f
+.Lbi\@: ldr         r8,     [sp, #168]  // w0
+        vdup.32     q1,     r8          // q1 wx0
+        ldr         r8,     [sp, #172]  // ox0
+        vdup.32     q3,     r8          // dup ox0 to q3
+        ldr         r9,     [sp, #180]  // src2stride
+        lsl         r9,     #1
+        vpop        {q9-q11}            // q9: wx q10: shift q11: ox
+        vadd.s32    q3,     q11         // q3 = ox0 + ox1
+        vmov.s32    q4,     #1
+        vadd.s32    q3,     q4          // q3 = ox0 + ox1 + 1
+        vneg.s32    q15,    q10         // q15 = -shift, prepare for left shift
+        vqrshl.s32  q2,     q3,     q15 // q2 = (ox0 + ox1 + 1)<<shift
+        vsub.s32    q10,    q4          // q10 final shift = demon + #7
+        vmov.s32    q3,     q10
+        vmov.s32    q4,     q9
+        vpush       {q1-q4}             // q1: wx0, q2: final offset, q3: final shift, q4: wx1
+        mov         r10,    r11         // r10 store startpoint src2
+0:      vextin4
+        \filterh q0
+        vextin4
+        \filterh q1
+        vextin4
+        \filterh q2
+        vextin4
+        \filterh q3
+        cmp         r5,    #4
+        beq         4f
+        cmp         r5,    #2
+        beq         2f
+8:      subs        r4,    #1
+        \filterv
+        vpop        {q9-q12}            // q9: wx0, q10: final offset, q11: final shift, q4: wx1
+        vmovl.s16   q13,    d16         // move long filter result from q8 to q12
+        vmovl.s16   q14,    d17         // move long filter result from q8 to q13
+        vmul.s32    q13,    q12         // src * wx1
+        vmul.s32    q14,    q12         // src * wx1
+        vld1.16     {q0},   [r11],  r9
+        vmovl.s16   q8,     d0
+        vmovl.s16   q15,    d1
+        vmul.s32    q8,     q9          // src2 * wx0
+        vmul.s32    q15,    q9          // src2 * wx0
+        vadd.s32    q13,    q8          // src * wx1 + src2 * wx0
+        vadd.s32    q14,    q15         // src * wx1 + src2 * wx0
+        vadd.s32    q13,    q10         // src * wx1 + src2 * wx0 + offset
+        vadd.s32    q14,    q10         // src * wx1 + src2 * wx0 + offset
+        vqshl.s32   q8,     q13,    q11 // shift
+        vqshl.s32   q15,    q14,    q11 // shift
+        vqmovun.s32 d28,    q8          // narrow
+        vqmovun.s32 d29,    q15         // narrow
+        vqmovn.u16  d0,     q14         // narrow
+        vst1.8      d0,     [r0],   r1  // store
+        vpush       {q9-q12}            // push
+        regshuffle_q4
+        vextin4
+        \filterh    q3
+        bne         8b
+        subs        r5,     #8
+        beq         98f
+        mov         r4,     r12
+        add         r6,     #8
+        mov         r0,     r6
+        add         r10,    #16
+        mov         r11,    r10
+        add         r7,     #8
+        mov         r2,     r7
+        b           0b
+4:      subs        r4,     #1
+        \filterv
+        vpop        {q9-q12}            // q9: wx0, q10: final offset, q11: final shift, q4: wx1
+        vmovl.s16   q13,    d16         // move long filter result from q8 to q12
+        vmul.s32    q13,    q12         // src * wx1
+        vld1.16     d0,     [r11],  r9
+        vmovl.s16   q8,     d0
+        vmul.s32    q8,     q9          // src2 * wx0
+        vadd.s32    q13,    q8          // src * wx1 + src2 * wx0
+        vadd.s32    q13,    q10         // src * wx1 + src2 * wx0 + offset
+        vqshl.s32   q8,     q13,    q11 // shift
+        vqmovun.s32 d28,    q8          // narrow
+        vqmovn.u16  d0,     q14         // narrow
+        vst1.32     d0[0],  [r0],   r1
+        vpush       {q9-q12}            // push
+        regshuffle_q4
+        vextin4
+        \filterh    q3
+        bne         4b
+        b           98f
+2:      subs        r4,     #1
+        \filterv
+        vpop        {q9-q12}            // q9: wx0, q10: final offset, q11: final shift, q4: wx1
+        vmovl.s16   q13,    d16         // move long filter result from q8 to q12
+        vmul.s32    q13,    q12         // src * wx1
+        vld1.16     d0,     [r11],  r9
+        vmovl.s16   q8,     d0
+        vmul.s32    q8,     q9          // src2 * wx0
+        vadd.s32    q13,    q8          // src * wx1 + src2 * wx0
+        vadd.s32    q13,    q10         // src * wx1 + src2 * wx0 + offset
+        vqshl.s32   q8,     q13,    q11 // shift
+        vqmovun.s32 d28,    q8          // narrow
+        vqmovn.u16  d0,     q14         // narrow
+        vmov.u16      r6, d0[0]
+        strh          r6, [r0], r1
+        vpush       {q9-q12}            // push
+        regshuffle_q4
+        vextin4
+        \filterh    q3
+        bne         2b
+        b         98f
+98:     vpop {q9-q12}
+        vpop {d8-d15}
+        pop  {r4-r12}
+        bx  lr
+99:     vpop {q9-q11}
+        vpop {d8-d15}
+        pop {r4-r12}
+        bx lr
+.endm
+
+
+function ff_hevc_put_epel_h1v1_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_1 epel_filter_1_32b
+endfunc
+
+function ff_hevc_put_epel_h2v1_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_2 epel_filter_1_32b
+endfunc
+
+function ff_hevc_put_epel_h3v1_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_3 epel_filter_1_32b
+endfunc
+
+function ff_hevc_put_epel_h4v1_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_4 epel_filter_1_32b
+endfunc
+
+function ff_hevc_put_epel_h5v1_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_5 epel_filter_1_32b
+endfunc
+
+function ff_hevc_put_epel_h6v1_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_6 epel_filter_1_32b
+endfunc
+
+function ff_hevc_put_epel_h7v1_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_7 epel_filter_1_32b
+endfunc
+
+function ff_hevc_put_epel_h1v2_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_1 epel_filter_2_32b
+endfunc
+
+function ff_hevc_put_epel_h2v2_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_2 epel_filter_2_32b
+endfunc
+
+function ff_hevc_put_epel_h3v2_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_3 epel_filter_2_32b
+endfunc
+
+function ff_hevc_put_epel_h4v2_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_4 epel_filter_2_32b
+endfunc
+
+function ff_hevc_put_epel_h5v2_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_5 epel_filter_2_32b
+endfunc
+
+function ff_hevc_put_epel_h6v2_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_6 epel_filter_2_32b
+endfunc
+
+function ff_hevc_put_epel_h7v2_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_7 epel_filter_2_32b
+endfunc
+
+function ff_hevc_put_epel_h1v3_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_1 epel_filter_3_32b
+endfunc
+
+function ff_hevc_put_epel_h2v3_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_2 epel_filter_3_32b
+endfunc
+
+function ff_hevc_put_epel_h3v3_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_3 epel_filter_3_32b
+endfunc
+
+function ff_hevc_put_epel_h4v3_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_4 epel_filter_3_32b
+endfunc
+
+function ff_hevc_put_epel_h5v3_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_5 epel_filter_3_32b
+endfunc
+
+function ff_hevc_put_epel_h6v3_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_6 epel_filter_3_32b
+endfunc
+
+function ff_hevc_put_epel_h7v3_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_7 epel_filter_3_32b
+endfunc
+
+function ff_hevc_put_epel_h1v4_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_1 epel_filter_4_32b
+endfunc
+
+function ff_hevc_put_epel_h2v4_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_2 epel_filter_4_32b
+endfunc
+
+function ff_hevc_put_epel_h3v4_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_3 epel_filter_4_32b
+endfunc
+
+function ff_hevc_put_epel_h4v4_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_4 epel_filter_4_32b
+endfunc
+
+function ff_hevc_put_epel_h5v4_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_5 epel_filter_4_32b
+endfunc
+
+function ff_hevc_put_epel_h6v4_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_6 epel_filter_4_32b
+endfunc
+
+function ff_hevc_put_epel_h7v4_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_7 epel_filter_4_32b
+endfunc
+
+function ff_hevc_put_epel_h1v5_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_1 epel_filter_5_32b
+endfunc
+
+function ff_hevc_put_epel_h2v5_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_2 epel_filter_5_32b
+endfunc
+
+function ff_hevc_put_epel_h3v5_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_3 epel_filter_5_32b
+endfunc
+
+function ff_hevc_put_epel_h4v5_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_4 epel_filter_5_32b
+endfunc
+
+function ff_hevc_put_epel_h5v5_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_5 epel_filter_5_32b
+endfunc
+
+function ff_hevc_put_epel_h6v5_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_6 epel_filter_5_32b
+endfunc
+
+function ff_hevc_put_epel_h7v5_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_7 epel_filter_5_32b
+endfunc
+
+function ff_hevc_put_epel_h1v6_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_1 epel_filter_6_32b
+endfunc
+
+function ff_hevc_put_epel_h2v6_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_2 epel_filter_6_32b
+endfunc
+
+function ff_hevc_put_epel_h3v6_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_3 epel_filter_6_32b
+endfunc
+
+function ff_hevc_put_epel_h4v6_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_4 epel_filter_6_32b
+endfunc
+
+function ff_hevc_put_epel_h5v6_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_5 epel_filter_6_32b
+endfunc
+
+function ff_hevc_put_epel_h6v6_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_6 epel_filter_6_32b
+endfunc
+
+function ff_hevc_put_epel_h7v6_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_7 epel_filter_6_32b
+endfunc
+
+function ff_hevc_put_epel_h1v7_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_1 epel_filter_7_32b
+endfunc
+
+function ff_hevc_put_epel_h2v7_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_2 epel_filter_7_32b
+endfunc
+
+function ff_hevc_put_epel_h3v7_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_3 epel_filter_7_32b
+endfunc
+
+function ff_hevc_put_epel_h4v7_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_4 epel_filter_7_32b
+endfunc
+
+function ff_hevc_put_epel_h5v7_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_5 epel_filter_7_32b
+endfunc
+
+function ff_hevc_put_epel_h6v7_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_6 epel_filter_7_32b
+endfunc
+
+function ff_hevc_put_epel_h7v7_neon_8, export=1
+        hevc_put_epel_hXvY_neon_8 epel_filter_7 epel_filter_7_32b
+endfunc
+
+
+function ff_hevc_put_epel_uw_h1v1_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_1 epel_filter_1_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h2v1_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_2 epel_filter_1_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h3v1_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_3 epel_filter_1_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h4v1_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_4 epel_filter_1_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h5v1_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_5 epel_filter_1_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h6v1_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_6 epel_filter_1_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h7v1_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_7 epel_filter_1_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h1v2_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_1 epel_filter_2_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h2v2_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_2 epel_filter_2_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h3v2_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_3 epel_filter_2_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h4v2_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_4 epel_filter_2_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h5v2_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_5 epel_filter_2_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h6v2_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_6 epel_filter_2_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h7v2_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_7 epel_filter_2_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h1v3_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_1 epel_filter_3_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h2v3_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_2 epel_filter_3_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h3v3_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_3 epel_filter_3_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h4v3_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_4 epel_filter_3_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h5v3_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_5 epel_filter_3_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h6v3_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_6 epel_filter_3_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h7v3_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_7 epel_filter_3_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h1v4_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_1 epel_filter_4_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h2v4_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_2 epel_filter_4_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h3v4_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_3 epel_filter_4_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h4v4_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_4 epel_filter_4_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h5v4_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_5 epel_filter_4_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h6v4_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_6 epel_filter_4_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h7v4_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_7 epel_filter_4_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h1v5_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_1 epel_filter_5_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h2v5_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_2 epel_filter_5_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h3v5_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_3 epel_filter_5_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h4v5_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_4 epel_filter_5_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h5v5_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_5 epel_filter_5_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h6v5_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_6 epel_filter_5_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h7v5_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_7 epel_filter_5_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h1v6_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_1 epel_filter_6_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h2v6_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_2 epel_filter_6_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h3v6_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_3 epel_filter_6_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h4v6_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_4 epel_filter_6_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h5v6_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_5 epel_filter_6_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h6v6_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_6 epel_filter_6_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h7v6_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_7 epel_filter_6_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h1v7_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_1 epel_filter_7_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h2v7_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_2 epel_filter_7_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h3v7_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_3 epel_filter_7_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h4v7_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_4 epel_filter_7_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h5v7_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_5 epel_filter_7_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h6v7_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_6 epel_filter_7_32b
+endfunc
+
+function ff_hevc_put_epel_uw_h7v7_neon_8, export=1
+        hevc_put_epel_uw_hXvY_neon_8 epel_filter_7 epel_filter_7_32b
+endfunc
+
+
+function ff_hevc_put_epel_wt_h1v1_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_1 epel_filter_1_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h2v1_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_2 epel_filter_1_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h3v1_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_3 epel_filter_1_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h4v1_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_4 epel_filter_1_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h5v1_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_5 epel_filter_1_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h6v1_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_6 epel_filter_1_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h7v1_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_7 epel_filter_1_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h1v2_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_1 epel_filter_2_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h2v2_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_2 epel_filter_2_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h3v2_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_3 epel_filter_2_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h4v2_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_4 epel_filter_2_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h5v2_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_5 epel_filter_2_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h6v2_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_6 epel_filter_2_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h7v2_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_7 epel_filter_2_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h1v3_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_1 epel_filter_3_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h2v3_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_2 epel_filter_3_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h3v3_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_3 epel_filter_3_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h4v3_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_4 epel_filter_3_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h5v3_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_5 epel_filter_3_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h6v3_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_6 epel_filter_3_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h7v3_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_7 epel_filter_3_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h1v4_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_1 epel_filter_4_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h2v4_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_2 epel_filter_4_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h3v4_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_3 epel_filter_4_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h4v4_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_4 epel_filter_4_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h5v4_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_5 epel_filter_4_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h6v4_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_6 epel_filter_4_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h7v4_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_7 epel_filter_4_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h1v5_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_1 epel_filter_5_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h2v5_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_2 epel_filter_5_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h3v5_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_3 epel_filter_5_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h4v5_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_4 epel_filter_5_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h5v5_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_5 epel_filter_5_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h6v5_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_6 epel_filter_5_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h7v5_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_7 epel_filter_5_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h1v6_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_1 epel_filter_6_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h2v6_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_2 epel_filter_6_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h3v6_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_3 epel_filter_6_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h4v6_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_4 epel_filter_6_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h5v6_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_5 epel_filter_6_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h6v6_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_6 epel_filter_6_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h7v6_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_7 epel_filter_6_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h1v7_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_1 epel_filter_7_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h2v7_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_2 epel_filter_7_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h3v7_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_3 epel_filter_7_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h4v7_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_4 epel_filter_7_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h5v7_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_5 epel_filter_7_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h6v7_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_6 epel_filter_7_32b
+endfunc
+
+function ff_hevc_put_epel_wt_h7v7_neon_8, export=1
+        hevc_put_epel_wt_hXvY_neon_8 epel_filter_7 epel_filter_7_32b
+endfunc
diff --git a/libavcodec/arm/hevcdsp_init_neon.c b/libavcodec/arm/hevcdsp_init_neon.c
index 183162803e..7d85c29d6a 100644
--- a/libavcodec/arm/hevcdsp_init_neon.c
+++ b/libavcodec/arm/hevcdsp_init_neon.c
@@ -83,6 +83,12 @@ static void (*put_hevc_qpel_uw_neon[4][4])(uint8_t *dst, ptrdiff_t dststride, ui
                                    int width, int height, int16_t* src2, ptrdiff_t src2stride);
 static void (*put_hevc_qpel_wt_neon[4][4])(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
                                    int width, int height, int denom, int wx1, int ox1, int wx0, int ox0, int16_t* src2, ptrdiff_t src2stride);
+static void (*put_hevc_epel_neon[8][8])(int16_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride,
+                                   int height, int width);
+static void (*put_hevc_epel_uw_neon[8][8])(uint8_t *dst, ptrdiff_t dststride, uint8_t *_src, ptrdiff_t _srcstride,
+                                           int width, int height, int16_t* src2, ptrdiff_t src2stride);
+static void (*put_hevc_epel_wt_neon[8][8])(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,
+                                           int width, int height, int denom, int wx1, int ox1, int wx0, int ox0, int16_t* src2, ptrdiff_t src2stride);
 void ff_hevc_put_qpel_neon_wrapper(int16_t *dst, uint8_t *src, ptrdiff_t srcstride,
                                    int height, intptr_t mx, intptr_t my, int width);
 void ff_hevc_put_qpel_uni_neon_wrapper(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride,
@@ -98,6 +104,21 @@ void ff_hevc_put_qpel_bi_w_neon_wrapper(uint8_t *dst, ptrdiff_t dststride, uint8
                                         int16_t *src2,
                                         int height, int denom, int wx0, int wx1,
                                         int ox0, int ox1, intptr_t mx, intptr_t my, int width);
+void ff_hevc_put_epel_neon_wrapper(int16_t *dst, uint8_t *src, ptrdiff_t srcstride,
+                                   int height, intptr_t mx, intptr_t my, int width);
+void ff_hevc_put_epel_uni_neon_wrapper(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride,
+                                       int height, intptr_t mx, intptr_t my, int width);
+void ff_hevc_put_epel_bi_neon_wrapper(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride,
+                                       int16_t *src2,
+                                       int height, intptr_t mx, intptr_t my, int width);
+void ff_hevc_put_epel_uni_w_neon_wrapper(uint8_t *dst,  ptrdiff_t dststride,
+                                         uint8_t *src, ptrdiff_t srcstride,
+                                         int height, int denom, int wx, int ox,
+                                         intptr_t mx, intptr_t my, int width);
+void ff_hevc_put_epel_bi_w_neon_wrapper(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride,
+                                             int16_t *src2,
+                                             int height, int denom, int wx0, int wx1,
+                                             int ox0, int ox1, intptr_t mx, intptr_t my, int width);
 
 #define QPEL_FUNC(name) \
     void name(int16_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride, \
@@ -173,6 +194,209 @@ QPEL_FUNC_WT(ff_hevc_put_qpel_wt_h3v2_neon_8);
 QPEL_FUNC_WT(ff_hevc_put_qpel_wt_h3v3_neon_8);
 #undef QPEL_FUNC_WT
 
+
+#define EPEL_FUNC(name) \
+    void name(int16_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride, \
+                                   int height, int width)
+EPEL_FUNC(ff_hevc_put_epel_v1_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_v2_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_v3_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_v4_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_v5_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_v6_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_v7_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h1_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h2_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h3_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h4_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h5_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h6_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h7_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h1v1_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h2v1_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h3v1_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h4v1_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h5v1_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h6v1_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h7v1_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h1v2_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h2v2_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h3v2_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h4v2_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h5v2_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h6v2_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h7v2_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h1v3_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h2v3_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h3v3_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h4v3_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h5v3_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h6v3_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h7v3_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h1v4_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h2v4_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h3v4_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h4v4_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h5v4_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h6v4_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h7v4_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h1v5_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h2v5_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h3v5_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h4v5_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h5v5_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h6v5_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h7v5_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h1v6_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h2v6_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h3v6_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h4v6_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h5v6_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h6v6_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h7v6_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h1v7_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h2v7_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h3v7_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h4v7_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h5v7_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h6v7_neon_8);
+EPEL_FUNC(ff_hevc_put_epel_h7v7_neon_8);
+#undef EPEL_FUNC
+#define EPEL_FUNC_UW(name) \
+void name(uint8_t *dst, ptrdiff_t dststride, uint8_t *_src, ptrdiff_t _srcstride, \
+int width, int height, int16_t* src2, ptrdiff_t src2stride);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_v1_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_v2_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_v3_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_v4_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_v5_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_v6_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_v7_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h1_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h2_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h3_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h4_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h5_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h6_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h7_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h1v1_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h2v1_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h3v1_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h4v1_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h5v1_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h6v1_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h7v1_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h1v2_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h2v2_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h3v2_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h4v2_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h5v2_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h6v2_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h7v2_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h1v3_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h2v3_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h3v3_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h4v3_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h5v3_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h6v3_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h7v3_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h1v4_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h2v4_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h3v4_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h4v4_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h5v4_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h6v4_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h7v4_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h1v5_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h2v5_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h3v5_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h4v5_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h5v5_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h6v5_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h7v5_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h1v6_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h2v6_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h3v6_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h4v6_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h5v6_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h6v6_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h7v6_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h1v7_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h2v7_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h3v7_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h4v7_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h5v7_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h6v7_neon_8);
+EPEL_FUNC_UW(ff_hevc_put_epel_uw_h7v7_neon_8);
+#undef EPEL_FUNC_UW
+#define EPEL_FUNC_WT(name) \
+void name(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride, \
+int width, int height, int denom, int wx1, int ox1, int wx0, int ox0, int16_t* src2, ptrdiff_t src2stride);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_v1_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_v2_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_v3_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_v4_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_v5_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_v6_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_v7_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h1_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h2_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h3_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h4_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h5_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h6_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h7_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h1v1_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h2v1_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h3v1_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h4v1_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h5v1_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h6v1_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h7v1_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h1v2_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h2v2_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h3v2_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h4v2_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h5v2_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h6v2_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h7v2_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h1v3_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h2v3_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h3v3_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h4v3_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h5v3_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h6v3_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h7v3_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h1v4_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h2v4_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h3v4_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h4v4_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h5v4_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h6v4_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h7v4_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h1v5_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h2v5_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h3v5_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h4v5_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h5v5_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h6v5_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h7v5_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h1v6_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h2v6_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h3v6_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h4v6_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h5v6_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h6v6_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h7v6_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h1v7_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h2v7_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h3v7_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h4v7_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h5v7_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h6v7_neon_8);
+EPEL_FUNC_WT(ff_hevc_put_epel_wt_h7v7_neon_8);
+#undef EPEL_FUNC_WT
+
 void ff_hevc_put_qpel_neon_wrapper(int16_t *dst, uint8_t *src, ptrdiff_t srcstride,
                                    int height, intptr_t mx, intptr_t my, int width) {
 
@@ -205,6 +429,35 @@ void ff_hevc_put_qpel_bi_w_neon_wrapper(uint8_t *dst, ptrdiff_t dststride, uint8
     put_hevc_qpel_wt_neon[my][mx](dst, dststride, src, srcstride, width, height, denom, wx1, ox1, wx0, ox0, src2, MAX_PB_SIZE);
 }
 
+void ff_hevc_put_epel_neon_wrapper(int16_t *dst, uint8_t *src, ptrdiff_t srcstride,
+                                   int height, intptr_t mx, intptr_t my, int width) {
+    put_hevc_epel_neon[my][mx](dst, MAX_PB_SIZE, src, srcstride, height, width);
+}
+
+void ff_hevc_put_epel_uni_neon_wrapper(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride,
+                                       int height, intptr_t mx, intptr_t my, int width){
+    put_hevc_epel_uw_neon[my][mx](dst, dststride, src, srcstride, width, height, NULL, 0);
+}
+
+void ff_hevc_put_epel_bi_neon_wrapper(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride,
+                                       int16_t *src2,
+                                      int height, intptr_t mx, intptr_t my, int width){
+    put_hevc_epel_uw_neon[my][mx](dst, dststride, src, srcstride, width, height, src2, MAX_PB_SIZE);
+}
+
+void ff_hevc_put_epel_uni_w_neon_wrapper(uint8_t *dst,  ptrdiff_t dststride,
+                                         uint8_t *src, ptrdiff_t srcstride,
+                                         int height, int denom, int wx, int ox,
+                                         intptr_t mx, intptr_t my, int width){
+    put_hevc_epel_wt_neon[my][mx](dst, dststride, src, srcstride, width, height, denom, wx, ox, 0, 0, NULL, 0);
+}
+
+void ff_hevc_put_epel_bi_w_neon_wrapper(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride,
+                                             int16_t *src2,
+                                             int height, int denom, int wx0, int wx1,
+                                             int ox0, int ox1, intptr_t mx, intptr_t my, int width){
+    put_hevc_epel_wt_neon[my][mx](dst, dststride, src, srcstride, width, height, denom, wx1, ox1, wx0, ox0, src2, MAX_PB_SIZE);
+}
 
 av_cold void ff_hevc_dsp_init_neon(HEVCDSPContext *c, const int bit_depth)
 {
@@ -272,6 +525,196 @@ av_cold void ff_hevc_dsp_init_neon(HEVCDSPContext *c, const int bit_depth)
         put_hevc_qpel_wt_neon[3][1]      = ff_hevc_put_qpel_wt_h1v3_neon_8;
         put_hevc_qpel_wt_neon[3][2]      = ff_hevc_put_qpel_wt_h2v3_neon_8;
         put_hevc_qpel_wt_neon[3][3]      = ff_hevc_put_qpel_wt_h3v3_neon_8;
+        put_hevc_epel_neon[1][0]         = ff_hevc_put_epel_v1_neon_8;
+        put_hevc_epel_neon[2][0]         = ff_hevc_put_epel_v2_neon_8;
+        put_hevc_epel_neon[3][0]         = ff_hevc_put_epel_v3_neon_8;
+        put_hevc_epel_neon[4][0]         = ff_hevc_put_epel_v4_neon_8;
+        put_hevc_epel_neon[5][0]         = ff_hevc_put_epel_v5_neon_8;
+        put_hevc_epel_neon[6][0]         = ff_hevc_put_epel_v6_neon_8;
+        put_hevc_epel_neon[7][0]         = ff_hevc_put_epel_v7_neon_8;
+        put_hevc_epel_neon[0][1]         = ff_hevc_put_epel_h1_neon_8;
+        put_hevc_epel_neon[0][2]         = ff_hevc_put_epel_h2_neon_8;
+        put_hevc_epel_neon[0][3]         = ff_hevc_put_epel_h3_neon_8;
+        put_hevc_epel_neon[0][4]         = ff_hevc_put_epel_h4_neon_8;
+        put_hevc_epel_neon[0][5]         = ff_hevc_put_epel_h5_neon_8;
+        put_hevc_epel_neon[0][6]         = ff_hevc_put_epel_h6_neon_8;
+        put_hevc_epel_neon[0][7]         = ff_hevc_put_epel_h7_neon_8;
+        put_hevc_epel_neon[1][1]         = ff_hevc_put_epel_h1v1_neon_8;
+        put_hevc_epel_neon[1][2]         = ff_hevc_put_epel_h2v1_neon_8;
+        put_hevc_epel_neon[1][3]         = ff_hevc_put_epel_h3v1_neon_8;
+        put_hevc_epel_neon[1][4]         = ff_hevc_put_epel_h4v1_neon_8;
+        put_hevc_epel_neon[1][5]         = ff_hevc_put_epel_h5v1_neon_8;
+        put_hevc_epel_neon[1][6]         = ff_hevc_put_epel_h6v1_neon_8;
+        put_hevc_epel_neon[1][7]         = ff_hevc_put_epel_h7v1_neon_8;
+        put_hevc_epel_neon[2][1]         = ff_hevc_put_epel_h1v2_neon_8;
+        put_hevc_epel_neon[2][2]         = ff_hevc_put_epel_h2v2_neon_8;
+        put_hevc_epel_neon[2][3]         = ff_hevc_put_epel_h3v2_neon_8;
+        put_hevc_epel_neon[2][4]         = ff_hevc_put_epel_h4v2_neon_8;
+        put_hevc_epel_neon[2][5]         = ff_hevc_put_epel_h5v2_neon_8;
+        put_hevc_epel_neon[2][6]         = ff_hevc_put_epel_h6v2_neon_8;
+        put_hevc_epel_neon[2][7]         = ff_hevc_put_epel_h7v2_neon_8;
+        put_hevc_epel_neon[3][1]         = ff_hevc_put_epel_h1v3_neon_8;
+        put_hevc_epel_neon[3][2]         = ff_hevc_put_epel_h2v3_neon_8;
+        put_hevc_epel_neon[3][3]         = ff_hevc_put_epel_h3v3_neon_8;
+        put_hevc_epel_neon[3][4]         = ff_hevc_put_epel_h4v3_neon_8;
+        put_hevc_epel_neon[3][5]         = ff_hevc_put_epel_h5v3_neon_8;
+        put_hevc_epel_neon[3][6]         = ff_hevc_put_epel_h6v3_neon_8;
+        put_hevc_epel_neon[3][7]         = ff_hevc_put_epel_h7v3_neon_8;
+        put_hevc_epel_neon[4][1]         = ff_hevc_put_epel_h1v4_neon_8;
+        put_hevc_epel_neon[4][2]         = ff_hevc_put_epel_h2v4_neon_8;
+        put_hevc_epel_neon[4][3]         = ff_hevc_put_epel_h3v4_neon_8;
+        put_hevc_epel_neon[4][4]         = ff_hevc_put_epel_h4v4_neon_8;
+        put_hevc_epel_neon[4][5]         = ff_hevc_put_epel_h5v4_neon_8;
+        put_hevc_epel_neon[4][6]         = ff_hevc_put_epel_h6v4_neon_8;
+        put_hevc_epel_neon[4][7]         = ff_hevc_put_epel_h7v4_neon_8;
+        put_hevc_epel_neon[5][1]         = ff_hevc_put_epel_h1v5_neon_8;
+        put_hevc_epel_neon[5][2]         = ff_hevc_put_epel_h2v5_neon_8;
+        put_hevc_epel_neon[5][3]         = ff_hevc_put_epel_h3v5_neon_8;
+        put_hevc_epel_neon[5][4]         = ff_hevc_put_epel_h4v5_neon_8;
+        put_hevc_epel_neon[5][5]         = ff_hevc_put_epel_h5v5_neon_8;
+        put_hevc_epel_neon[5][6]         = ff_hevc_put_epel_h6v5_neon_8;
+        put_hevc_epel_neon[5][7]         = ff_hevc_put_epel_h7v5_neon_8;
+        put_hevc_epel_neon[6][1]         = ff_hevc_put_epel_h1v6_neon_8;
+        put_hevc_epel_neon[6][2]         = ff_hevc_put_epel_h2v6_neon_8;
+        put_hevc_epel_neon[6][3]         = ff_hevc_put_epel_h3v6_neon_8;
+        put_hevc_epel_neon[6][4]         = ff_hevc_put_epel_h4v6_neon_8;
+        put_hevc_epel_neon[6][5]         = ff_hevc_put_epel_h5v6_neon_8;
+        put_hevc_epel_neon[6][6]         = ff_hevc_put_epel_h6v6_neon_8;
+        put_hevc_epel_neon[6][7]         = ff_hevc_put_epel_h7v6_neon_8;
+        put_hevc_epel_neon[7][1]         = ff_hevc_put_epel_h1v7_neon_8;
+        put_hevc_epel_neon[7][2]         = ff_hevc_put_epel_h2v7_neon_8;
+        put_hevc_epel_neon[7][3]         = ff_hevc_put_epel_h3v7_neon_8;
+        put_hevc_epel_neon[7][4]         = ff_hevc_put_epel_h4v7_neon_8;
+        put_hevc_epel_neon[7][5]         = ff_hevc_put_epel_h5v7_neon_8;
+        put_hevc_epel_neon[7][6]         = ff_hevc_put_epel_h6v7_neon_8;
+        put_hevc_epel_neon[7][7]         = ff_hevc_put_epel_h7v7_neon_8;
+        put_hevc_epel_uw_neon[1][0]      = ff_hevc_put_epel_uw_v1_neon_8;
+        put_hevc_epel_uw_neon[2][0]      = ff_hevc_put_epel_uw_v2_neon_8;
+        put_hevc_epel_uw_neon[3][0]      = ff_hevc_put_epel_uw_v3_neon_8;
+        put_hevc_epel_uw_neon[4][0]      = ff_hevc_put_epel_uw_v4_neon_8;
+        put_hevc_epel_uw_neon[5][0]      = ff_hevc_put_epel_uw_v5_neon_8;
+        put_hevc_epel_uw_neon[6][0]      = ff_hevc_put_epel_uw_v6_neon_8;
+        put_hevc_epel_uw_neon[7][0]      = ff_hevc_put_epel_uw_v7_neon_8;
+        put_hevc_epel_uw_neon[0][1]      = ff_hevc_put_epel_uw_h1_neon_8;
+        put_hevc_epel_uw_neon[0][2]      = ff_hevc_put_epel_uw_h2_neon_8;
+        put_hevc_epel_uw_neon[0][3]      = ff_hevc_put_epel_uw_h3_neon_8;
+        put_hevc_epel_uw_neon[0][4]      = ff_hevc_put_epel_uw_h4_neon_8;
+        put_hevc_epel_uw_neon[0][5]      = ff_hevc_put_epel_uw_h5_neon_8;
+        put_hevc_epel_uw_neon[0][6]      = ff_hevc_put_epel_uw_h6_neon_8;
+        put_hevc_epel_uw_neon[0][7]      = ff_hevc_put_epel_uw_h7_neon_8;
+        put_hevc_epel_uw_neon[1][1]      = ff_hevc_put_epel_uw_h1v1_neon_8;
+        put_hevc_epel_uw_neon[1][2]      = ff_hevc_put_epel_uw_h2v1_neon_8;
+        put_hevc_epel_uw_neon[1][3]      = ff_hevc_put_epel_uw_h3v1_neon_8;
+        put_hevc_epel_uw_neon[1][4]      = ff_hevc_put_epel_uw_h4v1_neon_8;
+        put_hevc_epel_uw_neon[1][5]      = ff_hevc_put_epel_uw_h5v1_neon_8;
+        put_hevc_epel_uw_neon[1][6]      = ff_hevc_put_epel_uw_h6v1_neon_8;
+        put_hevc_epel_uw_neon[1][7]      = ff_hevc_put_epel_uw_h7v1_neon_8;
+        put_hevc_epel_uw_neon[2][1]      = ff_hevc_put_epel_uw_h1v2_neon_8;
+        put_hevc_epel_uw_neon[2][2]      = ff_hevc_put_epel_uw_h2v2_neon_8;
+        put_hevc_epel_uw_neon[2][3]      = ff_hevc_put_epel_uw_h3v2_neon_8;
+        put_hevc_epel_uw_neon[2][4]      = ff_hevc_put_epel_uw_h4v2_neon_8;
+        put_hevc_epel_uw_neon[2][5]      = ff_hevc_put_epel_uw_h5v2_neon_8;
+        put_hevc_epel_uw_neon[2][6]      = ff_hevc_put_epel_uw_h6v2_neon_8;
+        put_hevc_epel_uw_neon[2][7]      = ff_hevc_put_epel_uw_h7v2_neon_8;
+        put_hevc_epel_uw_neon[3][1]      = ff_hevc_put_epel_uw_h1v3_neon_8;
+        put_hevc_epel_uw_neon[3][2]      = ff_hevc_put_epel_uw_h2v3_neon_8;
+        put_hevc_epel_uw_neon[3][3]      = ff_hevc_put_epel_uw_h3v3_neon_8;
+        put_hevc_epel_uw_neon[3][4]      = ff_hevc_put_epel_uw_h4v3_neon_8;
+        put_hevc_epel_uw_neon[3][5]      = ff_hevc_put_epel_uw_h5v3_neon_8;
+        put_hevc_epel_uw_neon[3][6]      = ff_hevc_put_epel_uw_h6v3_neon_8;
+        put_hevc_epel_uw_neon[3][7]      = ff_hevc_put_epel_uw_h7v3_neon_8;
+        put_hevc_epel_uw_neon[4][1]      = ff_hevc_put_epel_uw_h1v4_neon_8;
+        put_hevc_epel_uw_neon[4][2]      = ff_hevc_put_epel_uw_h2v4_neon_8;
+        put_hevc_epel_uw_neon[4][3]      = ff_hevc_put_epel_uw_h3v4_neon_8;
+        put_hevc_epel_uw_neon[4][4]      = ff_hevc_put_epel_uw_h4v4_neon_8;
+        put_hevc_epel_uw_neon[4][5]      = ff_hevc_put_epel_uw_h5v4_neon_8;
+        put_hevc_epel_uw_neon[4][6]      = ff_hevc_put_epel_uw_h6v4_neon_8;
+        put_hevc_epel_uw_neon[4][7]      = ff_hevc_put_epel_uw_h7v4_neon_8;
+        put_hevc_epel_uw_neon[5][1]      = ff_hevc_put_epel_uw_h1v5_neon_8;
+        put_hevc_epel_uw_neon[5][2]      = ff_hevc_put_epel_uw_h2v5_neon_8;
+        put_hevc_epel_uw_neon[5][3]      = ff_hevc_put_epel_uw_h3v5_neon_8;
+        put_hevc_epel_uw_neon[5][4]      = ff_hevc_put_epel_uw_h4v5_neon_8;
+        put_hevc_epel_uw_neon[5][5]      = ff_hevc_put_epel_uw_h5v5_neon_8;
+        put_hevc_epel_uw_neon[5][6]      = ff_hevc_put_epel_uw_h6v5_neon_8;
+        put_hevc_epel_uw_neon[5][7]      = ff_hevc_put_epel_uw_h7v5_neon_8;
+        put_hevc_epel_uw_neon[6][1]      = ff_hevc_put_epel_uw_h1v6_neon_8;
+        put_hevc_epel_uw_neon[6][2]      = ff_hevc_put_epel_uw_h2v6_neon_8;
+        put_hevc_epel_uw_neon[6][3]      = ff_hevc_put_epel_uw_h3v6_neon_8;
+        put_hevc_epel_uw_neon[6][4]      = ff_hevc_put_epel_uw_h4v6_neon_8;
+        put_hevc_epel_uw_neon[6][5]      = ff_hevc_put_epel_uw_h5v6_neon_8;
+        put_hevc_epel_uw_neon[6][6]      = ff_hevc_put_epel_uw_h6v6_neon_8;
+        put_hevc_epel_uw_neon[6][7]      = ff_hevc_put_epel_uw_h7v6_neon_8;
+        put_hevc_epel_uw_neon[7][1]      = ff_hevc_put_epel_uw_h1v7_neon_8;
+        put_hevc_epel_uw_neon[7][2]      = ff_hevc_put_epel_uw_h2v7_neon_8;
+        put_hevc_epel_uw_neon[7][3]      = ff_hevc_put_epel_uw_h3v7_neon_8;
+        put_hevc_epel_uw_neon[7][4]      = ff_hevc_put_epel_uw_h4v7_neon_8;
+        put_hevc_epel_uw_neon[7][5]      = ff_hevc_put_epel_uw_h5v7_neon_8;
+        put_hevc_epel_uw_neon[7][6]      = ff_hevc_put_epel_uw_h6v7_neon_8;
+        put_hevc_epel_uw_neon[7][7]      = ff_hevc_put_epel_uw_h7v7_neon_8;
+        put_hevc_epel_wt_neon[1][0]      = ff_hevc_put_epel_wt_v1_neon_8;
+        put_hevc_epel_wt_neon[2][0]      = ff_hevc_put_epel_wt_v2_neon_8;
+        put_hevc_epel_wt_neon[3][0]      = ff_hevc_put_epel_wt_v3_neon_8;
+        put_hevc_epel_wt_neon[4][0]      = ff_hevc_put_epel_wt_v4_neon_8;
+        put_hevc_epel_wt_neon[5][0]      = ff_hevc_put_epel_wt_v5_neon_8;
+        put_hevc_epel_wt_neon[6][0]      = ff_hevc_put_epel_wt_v6_neon_8;
+        put_hevc_epel_wt_neon[7][0]      = ff_hevc_put_epel_wt_v7_neon_8;
+        put_hevc_epel_wt_neon[0][1]      = ff_hevc_put_epel_wt_h1_neon_8;
+        put_hevc_epel_wt_neon[0][2]      = ff_hevc_put_epel_wt_h2_neon_8;
+        put_hevc_epel_wt_neon[0][3]      = ff_hevc_put_epel_wt_h3_neon_8;
+        put_hevc_epel_wt_neon[0][4]      = ff_hevc_put_epel_wt_h4_neon_8;
+        put_hevc_epel_wt_neon[0][5]      = ff_hevc_put_epel_wt_h5_neon_8;
+        put_hevc_epel_wt_neon[0][6]      = ff_hevc_put_epel_wt_h6_neon_8;
+        put_hevc_epel_wt_neon[0][7]      = ff_hevc_put_epel_wt_h7_neon_8;
+        put_hevc_epel_wt_neon[1][1]      = ff_hevc_put_epel_wt_h1v1_neon_8;
+        put_hevc_epel_wt_neon[1][2]      = ff_hevc_put_epel_wt_h2v1_neon_8;
+        put_hevc_epel_wt_neon[1][3]      = ff_hevc_put_epel_wt_h3v1_neon_8;
+        put_hevc_epel_wt_neon[1][4]      = ff_hevc_put_epel_wt_h4v1_neon_8;
+        put_hevc_epel_wt_neon[1][5]      = ff_hevc_put_epel_wt_h5v1_neon_8;
+        put_hevc_epel_wt_neon[1][6]      = ff_hevc_put_epel_wt_h6v1_neon_8;
+        put_hevc_epel_wt_neon[1][7]      = ff_hevc_put_epel_wt_h7v1_neon_8;
+        put_hevc_epel_wt_neon[2][1]      = ff_hevc_put_epel_wt_h1v2_neon_8;
+        put_hevc_epel_wt_neon[2][2]      = ff_hevc_put_epel_wt_h2v2_neon_8;
+        put_hevc_epel_wt_neon[2][3]      = ff_hevc_put_epel_wt_h3v2_neon_8;
+        put_hevc_epel_wt_neon[2][4]      = ff_hevc_put_epel_wt_h4v2_neon_8;
+        put_hevc_epel_wt_neon[2][5]      = ff_hevc_put_epel_wt_h5v2_neon_8;
+        put_hevc_epel_wt_neon[2][6]      = ff_hevc_put_epel_wt_h6v2_neon_8;
+        put_hevc_epel_wt_neon[2][7]      = ff_hevc_put_epel_wt_h7v2_neon_8;
+        put_hevc_epel_wt_neon[3][1]      = ff_hevc_put_epel_wt_h1v3_neon_8;
+        put_hevc_epel_wt_neon[3][2]      = ff_hevc_put_epel_wt_h2v3_neon_8;
+        put_hevc_epel_wt_neon[3][3]      = ff_hevc_put_epel_wt_h3v3_neon_8;
+        put_hevc_epel_wt_neon[3][4]      = ff_hevc_put_epel_wt_h4v3_neon_8;
+        put_hevc_epel_wt_neon[3][5]      = ff_hevc_put_epel_wt_h5v3_neon_8;
+        put_hevc_epel_wt_neon[3][6]      = ff_hevc_put_epel_wt_h6v3_neon_8;
+        put_hevc_epel_wt_neon[3][7]      = ff_hevc_put_epel_wt_h7v3_neon_8;
+        put_hevc_epel_wt_neon[4][1]      = ff_hevc_put_epel_wt_h1v4_neon_8;
+        put_hevc_epel_wt_neon[4][2]      = ff_hevc_put_epel_wt_h2v4_neon_8;
+        put_hevc_epel_wt_neon[4][3]      = ff_hevc_put_epel_wt_h3v4_neon_8;
+        put_hevc_epel_wt_neon[4][4]      = ff_hevc_put_epel_wt_h4v4_neon_8;
+        put_hevc_epel_wt_neon[4][5]      = ff_hevc_put_epel_wt_h5v4_neon_8;
+        put_hevc_epel_wt_neon[4][6]      = ff_hevc_put_epel_wt_h6v4_neon_8;
+        put_hevc_epel_wt_neon[4][7]      = ff_hevc_put_epel_wt_h7v4_neon_8;
+        put_hevc_epel_wt_neon[5][1]      = ff_hevc_put_epel_wt_h1v5_neon_8;
+        put_hevc_epel_wt_neon[5][2]      = ff_hevc_put_epel_wt_h2v5_neon_8;
+        put_hevc_epel_wt_neon[5][3]      = ff_hevc_put_epel_wt_h3v5_neon_8;
+        put_hevc_epel_wt_neon[5][4]      = ff_hevc_put_epel_wt_h4v5_neon_8;
+        put_hevc_epel_wt_neon[5][5]      = ff_hevc_put_epel_wt_h5v5_neon_8;
+        put_hevc_epel_wt_neon[5][6]      = ff_hevc_put_epel_wt_h6v5_neon_8;
+        put_hevc_epel_wt_neon[5][7]      = ff_hevc_put_epel_wt_h7v5_neon_8;
+        put_hevc_epel_wt_neon[6][1]      = ff_hevc_put_epel_wt_h1v6_neon_8;
+        put_hevc_epel_wt_neon[6][2]      = ff_hevc_put_epel_wt_h2v6_neon_8;
+        put_hevc_epel_wt_neon[6][3]      = ff_hevc_put_epel_wt_h3v6_neon_8;
+        put_hevc_epel_wt_neon[6][4]      = ff_hevc_put_epel_wt_h4v6_neon_8;
+        put_hevc_epel_wt_neon[6][5]      = ff_hevc_put_epel_wt_h5v6_neon_8;
+        put_hevc_epel_wt_neon[6][6]      = ff_hevc_put_epel_wt_h6v6_neon_8;
+        put_hevc_epel_wt_neon[6][7]      = ff_hevc_put_epel_wt_h7v6_neon_8;
+        put_hevc_epel_wt_neon[7][1]      = ff_hevc_put_epel_wt_h1v7_neon_8;
+        put_hevc_epel_wt_neon[7][2]      = ff_hevc_put_epel_wt_h2v7_neon_8;
+        put_hevc_epel_wt_neon[7][3]      = ff_hevc_put_epel_wt_h3v7_neon_8;
+        put_hevc_epel_wt_neon[7][4]      = ff_hevc_put_epel_wt_h4v7_neon_8;
+        put_hevc_epel_wt_neon[7][5]      = ff_hevc_put_epel_wt_h5v7_neon_8;
+        put_hevc_epel_wt_neon[7][6]      = ff_hevc_put_epel_wt_h6v7_neon_8;
+        put_hevc_epel_wt_neon[7][7]      = ff_hevc_put_epel_wt_h7v7_neon_8;
+
         for (x = 0; x < 10; x++) {
             c->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;
-- 
2.13.6 (Apple Git-96)



More information about the ffmpeg-devel mailing list