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

Showing the changes to libavfilter (4 of 4 files). Show all

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
2424 #include "libavfilter/bwdif.h"
2525 #include "libavutil/aarch64/cpu.h"
2626
27+void 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+
2731 void ff_bwdif_filter_intra_neon(void *dst1, void *cur1, int w, int prefs, int mrefs,
2832 int prefs3, int mrefs3, int parity, int clip_max);
2933
3034
35+static 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+
3150 static void filter_intra_helper(void *dst1, void *cur1, int w, int prefs, int mrefs,
3251 int prefs3, int mrefs3, int parity, int clip_max)
3352 {
@@ -52,5 +71,6 @@ ff_bwdif_init_aarch64(BWDIFContext *s, int bit_depth) · 18 unmodified lines
5271 return;
5372
5473 s->filter_intra = filter_intra_helper;
74+ s->filter_edge = filter_edge_helper;
5575 }
5676
libavfilter/aarch64/vf_bwdif_neon.S+177−0
@@ -66,6 +66,79 @@ · 65 unmodified lines
6666 umlsl2 \a3\().4s, \s1\().8h, \k
6767 .endm
6868
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+
69142 .macro LDR_COEFFS d, t0
70143 movrel \t0, coeffs, 0
71144 ld1 {\d\().8h}, [\t0]
@@ -81,6 +154,110 @@ const coeffs, align=4 // align 4 means align on 2^4 boundry · 9 unmodified lines
81154 .hword 5077, 981 // sp[0] = v0.h[6]
82155 endconst
83156
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+
173+function 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+
190+10:
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+
238+1:
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+
257+99:
258+ ret
259+endfunc
260+
84261 // ============================================================================
85262 //
86263 // 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
4141 void ff_bwdif_init_x86(BWDIFContext *bwdif, int bit_depth);
4242 void ff_bwdif_init_aarch64(BWDIFContext *bwdif, int bit_depth);
4343
44+void 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+
4448 void ff_bwdif_filter_intra_c(void *dst1, void *cur1, int w, int prefs, int mrefs,
4549 int prefs3, int mrefs3, int parity, int clip_max);
4650
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
150150 FILTER2()
151151 }
152152
153−static void filter_edge(void *dst1, void *prev1, void *cur1, void *next1,
154− int w, int prefs, int mrefs, int prefs2, int mrefs2,
155− int parity, int clip_max, int spat)
153+void ff_bwdif_filter_edge_c(void *dst1, void *prev1, void *cur1, void *next1,
154+ int w, int prefs, int mrefs, int prefs2, int mrefs2,
155+ int parity, int clip_max, int spat)
156156 {
157157 uint8_t *dst = dst1;
158158 uint8_t *prev = prev1;
@@ -364,7 +364,7 @@ av_cold void ff_bwdif_init_filter_line(BWDIFContext *s, int bit_depth) · 205 unmodified lines
364364 } else {
365365 s->filter_intra = ff_bwdif_filter_intra_c;
366366 s->filter_line = filter_line_c;
367− s->filter_edge = filter_edge;
367+ s->filter_edge = ff_bwdif_filter_edge_c;
368368 }
369369
370370 #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