History

avfilter/vf_bwdif: Add neon for filter_edge

Adds clip and spatial macros for aarch64 neon Exports C filter_edge needed for tail fixup of neon code Adds neon for filter_edge

John Cox committed 3 years ago

Commit 8130df81 parent 7ed7c004 files · +205 −4Browse files

Unified · Split

4 files
  1. libavfilter/aarch64/vf_bwdif_init_aarch64.c +20 −0
  2. libavfilter/aarch64/vf_bwdif_neon.S +177 −0
  3. libavfilter/bwdif.h +4 −0
  4. libavfilter/vf_bwdif.c +4 −4
libavfilter/aarch64/vf_bwdif_init_aarch64.c+20−0
@@ -24,10 +24,29 @@ · 23 unmodified lines
24#include "libavfilter/bwdif.h"24#include "libavfilter/bwdif.h"
25#include "libavutil/aarch64/cpu.h"25#include "libavutil/aarch64/cpu.h"
26 26
27void ff_bwdif_filter_edge_neon(void *dst1, void *prev1, void *cur1, void *next1,
28 int w, int prefs, int mrefs, int prefs2, int mrefs2,
29 int parity, int clip_max, int spat);
30
27void ff_bwdif_filter_intra_neon(void *dst1, void *cur1, int w, int prefs, int mrefs,31void ff_bwdif_filter_intra_neon(void *dst1, void *cur1, int w, int prefs, int mrefs,
28 int prefs3, int mrefs3, int parity, int clip_max);32 int prefs3, int mrefs3, int parity, int clip_max);
29 33
30 34
35static void filter_edge_helper(void *dst1, void *prev1, void *cur1, void *next1,
36 int w, int prefs, int mrefs, int prefs2, int mrefs2,
37 int parity, int clip_max, int spat)
38{
39 const int w0 = clip_max != 255 ? 0 : w & ~15;
40
41 ff_bwdif_filter_edge_neon(dst1, prev1, cur1, next1, w0, prefs, mrefs, prefs2, mrefs2,
42 parity, clip_max, spat);
43
44 if (w0 < w)
45 ff_bwdif_filter_edge_c((char *)dst1 + w0, (char *)prev1 + w0, (char *)cur1 + w0, (char *)next1 + w0,
46 w - w0, prefs, mrefs, prefs2, mrefs2,
47 parity, clip_max, spat);
48}
49
31static void filter_intra_helper(void *dst1, void *cur1, int w, int prefs, int mrefs,50static void filter_intra_helper(void *dst1, void *cur1, int w, int prefs, int mrefs,
32 int prefs3, int mrefs3, int parity, int clip_max)51 int prefs3, int mrefs3, int parity, int clip_max)
33{52{
@@ -52,5 +71,6 @@ ff_bwdif_init_aarch64(BWDIFContext *s, int bit_depth) · 18 unmodified lines
52 return;71 return;
53 72
54 s->filter_intra = filter_intra_helper;73 s->filter_intra = filter_intra_helper;
74 s->filter_edge = filter_edge_helper;
55}75}
56 76
libavfilter/aarch64/vf_bwdif_neon.S+177−0
@@ -66,6 +66,79 @@ · 65 unmodified lines
66 umlsl2 \a3\().4s, \s1\().8h, \k66 umlsl2 \a3\().4s, \s1\().8h, \k
67.endm67.endm
68 68
69// int b = m2s1 - m1;
70// int f = p2s1 - p1;
71// int dc = c0s1 - m1;
72// int de = c0s1 - p1;
73// int sp_max = FFMIN(p1 - c0s1, m1 - c0s1);
74// sp_max = FFMIN(sp_max, FFMAX(-b,-f));
75// int sp_min = FFMIN(c0s1 - p1, c0s1 - m1);
76// sp_min = FFMIN(sp_min, FFMAX(b,f));
77// diff = diff == 0 ? 0 : FFMAX3(diff, sp_min, sp_max);
78.macro SPAT_CHECK diff, m2s1, m1, c0s1, p1, p2s1, t0, t1, t2, t3
79 uqsub \t0\().16b, \p1\().16b, \c0s1\().16b
80 uqsub \t2\().16b, \m1\().16b, \c0s1\().16b
81 umin \t2\().16b, \t0\().16b, \t2\().16b
82
83 uqsub \t1\().16b, \m1\().16b, \m2s1\().16b
84 uqsub \t3\().16b, \p1\().16b, \p2s1\().16b
85 umax \t3\().16b, \t3\().16b, \t1\().16b
86 umin \t3\().16b, \t3\().16b, \t2\().16b
87
88 uqsub \t0\().16b, \c0s1\().16b, \p1\().16b
89 uqsub \t2\().16b, \c0s1\().16b, \m1\().16b
90 umin \t2\().16b, \t0\().16b, \t2\().16b
91
92 uqsub \t1\().16b, \m2s1\().16b, \m1\().16b
93 uqsub \t0\().16b, \p2s1\().16b, \p1\().16b
94 umax \t0\().16b, \t0\().16b, \t1\().16b
95 umin \t2\().16b, \t2\().16b, \t0\().16b
96
97 cmeq \t1\().16b, \diff\().16b, #0
98 umax \diff\().16b, \diff\().16b, \t3\().16b
99 umax \diff\().16b, \diff\().16b, \t2\().16b
100 bic \diff\().16b, \diff\().16b, \t1\().16b
101.endm
102
103// i0 = s0;
104// if (i0 > d0 + diff0)
105// i0 = d0 + diff0;
106// else if (i0 < d0 - diff0)
107// i0 = d0 - diff0;
108//
109// i0 = s0 is safe
110.macro DIFF_CLIP i0, s0, d0, diff, t0, t1
111 uqadd \t0\().16b, \d0\().16b, \diff\().16b
112 uqsub \t1\().16b, \d0\().16b, \diff\().16b
113 umin \i0\().16b, \s0\().16b, \t0\().16b
114 umax \i0\().16b, \i0\().16b, \t1\().16b
115.endm
116
117// i0 = FFABS(m1 - p1) > td0 ? i1 : i2;
118// DIFF_CLIP
119//
120// i0 = i1 is safe
121.macro INTERPOL i0, i1, i2, m1, d0, p1, td0, diff, t0, t1, t2
122 uabd \t0\().16b, \m1\().16b, \p1\().16b
123 cmhi \t0\().16b, \t0\().16b, \td0\().16b
124 bsl \t0\().16b, \i1\().16b, \i2\().16b
125 DIFF_CLIP \i0, \t0, \d0, \diff, \t1, \t2
126.endm
127
128.macro PUSH_VREGS
129 stp d8, d9, [sp, #-64]!
130 stp d10, d11, [sp, #16]
131 stp d12, d13, [sp, #32]
132 stp d14, d15, [sp, #48]
133.endm
134
135.macro POP_VREGS
136 ldp d14, d15, [sp, #48]
137 ldp d12, d13, [sp, #32]
138 ldp d10, d11, [sp, #16]
139 ldp d8, d9, [sp], #64
140.endm
141
69.macro LDR_COEFFS d, t0142.macro LDR_COEFFS d, t0
70 movrel \t0, coeffs, 0143 movrel \t0, coeffs, 0
71 ld1 {\d\().8h}, [\t0]144 ld1 {\d\().8h}, [\t0]
@@ -81,6 +154,110 @@ const coeffs, align=4 // align 4 means align on 2^4 boundry · 9 unmodified lines
81 .hword 5077, 981 // sp[0] = v0.h[6]154 .hword 5077, 981 // sp[0] = v0.h[6]
82endconst155endconst
83 156
157// ============================================================================
158//
159// void ff_bwdif_filter_edge_neon(
160// void *dst1, // x0
161// void *prev1, // x1
162// void *cur1, // x2
163// void *next1, // x3
164// int w, // w4
165// int prefs, // w5
166// int mrefs, // w6
167// int prefs2, // w7
168// int mrefs2, // [sp, #0]
169// int parity, // [sp, #SP_INT]
170// int clip_max, // [sp, #SP_INT*2] unused
171// int spat); // [sp, #SP_INT*3]
172
173function ff_bwdif_filter_edge_neon, export=1
174 // Sanity check w
175 cmp w4, #0
176 ble 99f
177
178// #define prev2 cur
179// const uint8_t * restrict next2 = parity ? prev : next;
180
181 ldr w8, [sp, #0] // mrefs2
182
183 ldr w17, [sp, #SP_INT] // parity
184 ldr w16, [sp, #SP_INT*3] // spat
185 cmp w17, #0
186 csel x17, x1, x3, ne
187
188// for (x = 0; x < w; x++) {
189
19010:
191// int m1 = cur[mrefs];
192// int d = (prev2[0] + next2[0]) >> 1;
193// int p1 = cur[prefs];
194// int temporal_diff0 = FFABS(prev2[0] - next2[0]);
195// int temporal_diff1 =(FFABS(prev[mrefs] - m1) + FFABS(prev[prefs] - p1)) >> 1;
196// int temporal_diff2 =(FFABS(next[mrefs] - m1) + FFABS(next[prefs] - p1)) >> 1;
197// int diff = FFMAX3(temporal_diff0 >> 1, temporal_diff1, temporal_diff2);
198 ldr q31, [x2]
199 ldr q21, [x17]
200 uhadd v16.16b, v31.16b, v21.16b // d0 = v16
201 uabd v17.16b, v31.16b, v21.16b // td0 = v17
202 ldr q24, [x2, w6, sxtw] // m1 = v24
203 ldr q22, [x2, w5, sxtw] // p1 = v22
204
205 ldr q0, [x1, w6, sxtw] // prev[mrefs]
206 ldr q2, [x1, w5, sxtw] // prev[prefs]
207 ldr q1, [x3, w6, sxtw] // next[mrefs]
208 ldr q3, [x3, w5, sxtw] // next[prefs]
209
210 ushr v29.16b, v17.16b, #1
211
212 uabd v31.16b, v0.16b, v24.16b
213 uabd v30.16b, v2.16b, v22.16b
214 uhadd v0.16b, v31.16b, v30.16b // td1 = q0
215
216 uabd v31.16b, v1.16b, v24.16b
217 uabd v30.16b, v3.16b, v22.16b
218 uhadd v1.16b, v31.16b, v30.16b // td2 = q1
219
220 umax v0.16b, v0.16b, v29.16b
221 umax v0.16b, v0.16b, v1.16b // diff = v0
222
223// if (spat) {
224// SPAT_CHECK()
225// }
226// i0 = (m1 + p1) >> 1;
227 cbz w16, 1f
228
229 ldr q31, [x2, w8, sxtw]
230 ldr q18, [x17, w8, sxtw]
231 ldr q30, [x2, w7, sxtw]
232 ldr q19, [x17, w7, sxtw]
233 uhadd v18.16b, v18.16b, v31.16b
234 uhadd v19.16b, v19.16b, v30.16b
235
236 SPAT_CHECK v0, v18, v24, v16, v22, v19, v31, v30, v29, v28
237
2381:
239 uhadd v2.16b, v22.16b, v24.16b
240
241 // i0 = v2, s0 = v2, d0 = v16, diff = v0, t0 = v31, t1 = v30
242 DIFF_CLIP v2, v2, v16, v0, v31, v30
243
244// dst[0] = av_clip(interpol, 0, clip_max);
245 str q2, [x0], #16
246
247// dst++;
248// cur++;
249// }
250 subs w4, w4, #16
251 add x1, x1, #16
252 add x2, x2, #16
253 add x3, x3, #16
254 add x17, x17, #16
255 bgt 10b
256
25799:
258 ret
259endfunc
260
84// ============================================================================261// ============================================================================
85//262//
86// void ff_bwdif_filter_intra_neon(263// void ff_bwdif_filter_intra_neon(
libavfilter/bwdif.h+4−0
@@ -41,6 +41,10 @@ void ff_bwdif_init_filter_line(BWDIFContext *bwdif, int bit_depth); · 40 unmodified lines
41void ff_bwdif_init_x86(BWDIFContext *bwdif, int bit_depth);41void ff_bwdif_init_x86(BWDIFContext *bwdif, int bit_depth);
42void ff_bwdif_init_aarch64(BWDIFContext *bwdif, int bit_depth);42void ff_bwdif_init_aarch64(BWDIFContext *bwdif, int bit_depth);
43 43
44void ff_bwdif_filter_edge_c(void *dst1, void *prev1, void *cur1, void *next1,
45 int w, int prefs, int mrefs, int prefs2, int mrefs2,
46 int parity, int clip_max, int spat);
47
44void ff_bwdif_filter_intra_c(void *dst1, void *cur1, int w, int prefs, int mrefs,48void ff_bwdif_filter_intra_c(void *dst1, void *cur1, int w, int prefs, int mrefs,
45 int prefs3, int mrefs3, int parity, int clip_max);49 int prefs3, int mrefs3, int parity, int clip_max);
46 50
libavfilter/vf_bwdif.c+4−4
@@ -150,9 +150,9 @@ static void filter_line_c(void *dst1, void *prev1, void *cur1, void *next1, · 149 unmodified lines
150 FILTER2()150 FILTER2()
151}151}
152 152
153static void filter_edge(void *dst1, void *prev1, void *cur1, void *next1,153void ff_bwdif_filter_edge_c(void *dst1, void *prev1, void *cur1, void *next1,
154 int w, int prefs, int mrefs, int prefs2, int mrefs2,154 int w, int prefs, int mrefs, int prefs2, int mrefs2,
155 int parity, int clip_max, int spat)155 int parity, int clip_max, int spat)
156{156{
157 uint8_t *dst = dst1;157 uint8_t *dst = dst1;
158 uint8_t *prev = prev1;158 uint8_t *prev = prev1;
@@ -364,7 +364,7 @@ av_cold void ff_bwdif_init_filter_line(BWDIFContext *s, int bit_depth) · 205 unmodified lines
364 } else {364 } else {
365 s->filter_intra = ff_bwdif_filter_intra_c;365 s->filter_intra = ff_bwdif_filter_intra_c;
366 s->filter_line = filter_line_c;366 s->filter_line = filter_line_c;
367 s->filter_edge = filter_edge;367 s->filter_edge = ff_bwdif_filter_edge_c;
368 }368 }
369 369
370#if ARCH_X86370#if ARCH_X86

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t