1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * Copyright (c) 2017 Meng Wang <wangmeng.kids@bytedance.com>
3cabdff1aSopenharmony_ci *
4cabdff1aSopenharmony_ci * This file is part of FFmpeg.
5cabdff1aSopenharmony_ci *
6cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
7cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
8cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
9cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
10cabdff1aSopenharmony_ci *
11cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
12cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
13cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14cabdff1aSopenharmony_ci * Lesser General Public License for more details.
15cabdff1aSopenharmony_ci *
16cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
17cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
18cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19cabdff1aSopenharmony_ci */
20cabdff1aSopenharmony_ci
21cabdff1aSopenharmony_ci
22cabdff1aSopenharmony_ci#include "libavutil/arm/asm.S"
23cabdff1aSopenharmony_ci#include "neon.S"
24cabdff1aSopenharmony_ci
25cabdff1aSopenharmony_cifunction ff_hevc_sao_band_filter_neon_8, export=1
26cabdff1aSopenharmony_ci        push    {r4-r10}
27cabdff1aSopenharmony_ci        ldr     r5,  [sp, #28]   // width
28cabdff1aSopenharmony_ci        ldr     r4,  [sp, #32]   // height
29cabdff1aSopenharmony_ci        ldr     r8,  [sp, #36]   // offset_table
30cabdff1aSopenharmony_ci        vpush   {d8-d15}
31cabdff1aSopenharmony_ci        mov     r12,  r4         // r12 = height
32cabdff1aSopenharmony_ci        mov     r6,   r0         // r6 = r0 = dst
33cabdff1aSopenharmony_ci        mov     r7,   r1         // r7 = r1 = src
34cabdff1aSopenharmony_ci        vldm    r8,   {q0-q3}
35cabdff1aSopenharmony_ci        vmov.u16    q15,  #1
36cabdff1aSopenharmony_ci        vmov.u8     q14,  #32
37cabdff1aSopenharmony_ci0:      pld      [r1]
38cabdff1aSopenharmony_ci        cmp      r5,    #4
39cabdff1aSopenharmony_ci        beq      4f
40cabdff1aSopenharmony_ci8:      subs     r4,    #1
41cabdff1aSopenharmony_ci        vld1.8   {d16},  [r1], r3
42cabdff1aSopenharmony_ci        vshr.u8  d17,   d16,  #3   // index = [src>>3]
43cabdff1aSopenharmony_ci        vshll.u8 q9,    d17,  #1   // lowIndex = 2*index
44cabdff1aSopenharmony_ci        vadd.u16 q11,   q9,   q15  // highIndex = (2*index+1) << 8
45cabdff1aSopenharmony_ci        vshl.u16 q10,   q11,  #8   // q10: highIndex;  q9: lowIndex;
46cabdff1aSopenharmony_ci        vadd.u16 q10,   q9         // combine high and low index;
47cabdff1aSopenharmony_ci        // Look-up Table Round 1; index range: 0-15
48cabdff1aSopenharmony_ci        vtbx.8   d24,   {q0-q1},   d20
49cabdff1aSopenharmony_ci        vtbx.8   d25,   {q0-q1},   d21
50cabdff1aSopenharmony_ci        // Look-up Table Round 2; index range: 16-31
51cabdff1aSopenharmony_ci        vsub.u8  q10,   q14        // Look-up with 8bit
52cabdff1aSopenharmony_ci        vtbx.8   d24,   {q2-q3},   d20
53cabdff1aSopenharmony_ci        vtbx.8   d25,   {q2-q3},   d21
54cabdff1aSopenharmony_ci        vaddw.u8 q13,   q12,       d16
55cabdff1aSopenharmony_ci        vqmovun.s16      d8,         q13
56cabdff1aSopenharmony_ci        vst1.8    d8,   [r0],      r2
57cabdff1aSopenharmony_ci        bne      8b
58cabdff1aSopenharmony_ci        subs     r5,    #8
59cabdff1aSopenharmony_ci        beq      99f
60cabdff1aSopenharmony_ci        mov      r4,    r12
61cabdff1aSopenharmony_ci        add r6, #8
62cabdff1aSopenharmony_ci        mov r0, r6
63cabdff1aSopenharmony_ci        add r7, #8
64cabdff1aSopenharmony_ci        mov r1, r7
65cabdff1aSopenharmony_ci        b        0b
66cabdff1aSopenharmony_ci4:      subs     r4,    #1
67cabdff1aSopenharmony_ci        vld1.32   {d16[0]},  [r1],  r3
68cabdff1aSopenharmony_ci        vshr.u8  d17,   d16,  #3  // src>>3
69cabdff1aSopenharmony_ci        vshll.u8 q9,    d17,  #1   // lowIndex = 2*index
70cabdff1aSopenharmony_ci        vadd.u16 q11,   q9,   q15  // highIndex = (2*index+1) << 8
71cabdff1aSopenharmony_ci        vshl.u16 q10,   q11,  #8   // q10: highIndex;  q9: lowIndex;
72cabdff1aSopenharmony_ci        vadd.u16 q10,   q9         // combine high and low index;
73cabdff1aSopenharmony_ci        // Look-up Table Round 1; index range: 0-15
74cabdff1aSopenharmony_ci        vtbx.8   d24,   {q0-q1},   d20
75cabdff1aSopenharmony_ci        vtbx.8   d25,   {q0-q1},   d21
76cabdff1aSopenharmony_ci        // Look-up Table Round 2; index range: 16-32
77cabdff1aSopenharmony_ci        vsub.u8  q10,   q14        // Look-up with 8bit
78cabdff1aSopenharmony_ci        vtbx.8   d24,   {q2-q3},   d20
79cabdff1aSopenharmony_ci        vtbx.8   d25,   {q2-q3},   d21
80cabdff1aSopenharmony_ci        vaddw.u8 q13,   q12,       d16
81cabdff1aSopenharmony_ci        vqmovun.s16     d14,       q13
82cabdff1aSopenharmony_ci        vst1.32   d14[0],    [r0],     r2
83cabdff1aSopenharmony_ci        bne      4b
84cabdff1aSopenharmony_ci        b        99f
85cabdff1aSopenharmony_ci99:
86cabdff1aSopenharmony_ci        vpop {d8-d15}
87cabdff1aSopenharmony_ci        pop  {r4-r10}
88cabdff1aSopenharmony_ci        bx   lr
89cabdff1aSopenharmony_ciendfunc
90cabdff1aSopenharmony_ci
91cabdff1aSopenharmony_cifunction ff_hevc_sao_edge_filter_neon_8, export=1
92cabdff1aSopenharmony_ci        push    {r4-r11}
93cabdff1aSopenharmony_ci        ldr     r5,  [sp, #32]   // width
94cabdff1aSopenharmony_ci        ldr     r4,  [sp, #36]   // height
95cabdff1aSopenharmony_ci        ldr     r8,  [sp, #40]   // a_stride
96cabdff1aSopenharmony_ci        ldr     r9,  [sp, #44]   // b_stride
97cabdff1aSopenharmony_ci        ldr     r10, [sp, #48]   // sao_offset_val
98cabdff1aSopenharmony_ci        ldr     r11, [sp, #52]   // edge_idx
99cabdff1aSopenharmony_ci        vpush   {d8-d15}
100cabdff1aSopenharmony_ci        mov     r12,  r4         // r12 = height
101cabdff1aSopenharmony_ci        mov     r6,   r0         // r6 = r0 = dst
102cabdff1aSopenharmony_ci        mov     r7,   r1         // r7 = r1 = src
103cabdff1aSopenharmony_ci        vld1.8  {d0}, [r11]      // edge_idx tabel load in d0 5x8bit
104cabdff1aSopenharmony_ci        vld1.16 {q1}, [r10]      // sao_offset_val table load in q1, 5x16bit
105cabdff1aSopenharmony_ci        vmov.u8  d1,  #2
106cabdff1aSopenharmony_ci        vmov.u16 q2,  #1
107cabdff1aSopenharmony_ci0:      mov      r10,    r1
108cabdff1aSopenharmony_ci        add      r10,    r8           // src[x + a_stride]
109cabdff1aSopenharmony_ci        mov      r11,    r1
110cabdff1aSopenharmony_ci        add      r11,    r9           // src[x + b_stride]
111cabdff1aSopenharmony_ci        pld      [r1]
112cabdff1aSopenharmony_ci        cmp      r5,     #4
113cabdff1aSopenharmony_ci        beq      4f
114cabdff1aSopenharmony_ci8:      subs     r4,     #1
115cabdff1aSopenharmony_ci        vld1.8   {d16},  [r1],  r3    // src[x]  8x8bit
116cabdff1aSopenharmony_ci        vld1.8   {d17},  [r10], r3    // src[x + a_stride]
117cabdff1aSopenharmony_ci        vld1.8   {d18},  [r11], r3    // src[x + b_stride]
118cabdff1aSopenharmony_ci        vcgt.u8  d8,     d16,   d17
119cabdff1aSopenharmony_ci        vshr.u8  d9,     d8,    #7
120cabdff1aSopenharmony_ci        vclt.u8  d8,     d16,   d17
121cabdff1aSopenharmony_ci        vadd.u8  d8,     d9           // diff0
122cabdff1aSopenharmony_ci        vcgt.u8  d10,    d16,   d18
123cabdff1aSopenharmony_ci        vshr.u8  d11,    d10,   #7
124cabdff1aSopenharmony_ci        vclt.u8  d10,    d16,   d18
125cabdff1aSopenharmony_ci        vadd.u8  d10,    d11          // diff1
126cabdff1aSopenharmony_ci        vadd.s8  d8,     d10
127cabdff1aSopenharmony_ci        vadd.s8  d8,     d1
128cabdff1aSopenharmony_ci        vtbx.8   d9,     {d0},  d8    // offset_val
129cabdff1aSopenharmony_ci        vshll.u8 q6,     d9,    #1    // lowIndex
130cabdff1aSopenharmony_ci        vadd.u16 q7,     q6,    q2
131cabdff1aSopenharmony_ci        vshl.u16 q10,    q7,    #8    // highIndex
132cabdff1aSopenharmony_ci        vadd.u16 q10,    q6           // combine lowIndex and highIndex, offset_val
133cabdff1aSopenharmony_ci        vtbx.8   d22,    {q1},  d20
134cabdff1aSopenharmony_ci        vtbx.8   d23,    {q1},  d21
135cabdff1aSopenharmony_ci        vaddw.u8 q12,    q11,   d16
136cabdff1aSopenharmony_ci        vqmovun.s16      d26,   q12
137cabdff1aSopenharmony_ci        vst1.8   d26,    [r0],  r2
138cabdff1aSopenharmony_ci        bne      8b
139cabdff1aSopenharmony_ci        subs     r5,     #8
140cabdff1aSopenharmony_ci        beq      99f
141cabdff1aSopenharmony_ci        mov      r4,     r12
142cabdff1aSopenharmony_ci        add      r6,     #8
143cabdff1aSopenharmony_ci        mov      r0,     r6
144cabdff1aSopenharmony_ci        add      r7,     #8
145cabdff1aSopenharmony_ci        mov      r1,     r7
146cabdff1aSopenharmony_ci        b        0b
147cabdff1aSopenharmony_ci4:      subs     r4,    #1
148cabdff1aSopenharmony_ci        vld1.32   {d16[0]},  [r1],  r3
149cabdff1aSopenharmony_ci        vld1.32   {d17[0]},  [r10], r3    // src[x + a_stride]
150cabdff1aSopenharmony_ci        vld1.32   {d18[0]},  [r11], r3    // src[x + b_stride]
151cabdff1aSopenharmony_ci        vcgt.u8  d8,     d16,   d17
152cabdff1aSopenharmony_ci        vshr.u8  d9,     d8,    #7
153cabdff1aSopenharmony_ci        vclt.u8  d8,     d16,   d17
154cabdff1aSopenharmony_ci        vadd.u8  d8,     d9           // diff0
155cabdff1aSopenharmony_ci        vcgt.u8  d10,    d16,   d18
156cabdff1aSopenharmony_ci        vshr.u8  d11,    d10,   #7
157cabdff1aSopenharmony_ci        vclt.u8  d10,    d16,   d18
158cabdff1aSopenharmony_ci        vadd.u8  d10,    d11          // diff1
159cabdff1aSopenharmony_ci        vadd.s8  d8,     d10
160cabdff1aSopenharmony_ci        vadd.s8  d8,     d1
161cabdff1aSopenharmony_ci        vtbx.8   d9,     {d0},  d8    // offset_val
162cabdff1aSopenharmony_ci        vshll.u8 q6,     d9,    #1    // lowIndex
163cabdff1aSopenharmony_ci        vadd.u16 q7,     q6,    q2
164cabdff1aSopenharmony_ci        vshl.u16 q10,    q7,    #8    // highIndex
165cabdff1aSopenharmony_ci        vadd.u16 q10,    q6           // combine lowIndex and highIndex, offset_val
166cabdff1aSopenharmony_ci        vtbx.8   d22,    {q1},  d20
167cabdff1aSopenharmony_ci        vtbx.8   d23,    {q1},  d21
168cabdff1aSopenharmony_ci        vaddw.u8 q12,    q11,   d16
169cabdff1aSopenharmony_ci        vqmovun.s16      d26,   q12
170cabdff1aSopenharmony_ci        vst1.32  d26[0], [r0],  r2
171cabdff1aSopenharmony_ci        bne      4b
172cabdff1aSopenharmony_ci        b        99f
173cabdff1aSopenharmony_ci99:
174cabdff1aSopenharmony_ci        vpop {d8-d15}
175cabdff1aSopenharmony_ci        pop  {r4-r11}
176cabdff1aSopenharmony_ci        bx   lr
177cabdff1aSopenharmony_ciendfunc
178