]> git.sesse.net Git - x264/blob - common/arm/deblock-a.S
arm: Implement chroma intra deblock
[x264] / common / arm / deblock-a.S
1 /*****************************************************************************
2  * deblock.S: arm deblocking
3  *****************************************************************************
4  * Copyright (C) 2009-2015 x264 project
5  *
6  * Authors: Mans Rullgard <mans@mansr.com>
7  *          Martin Storsjo <martin@martin.st>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
22  *
23  * This program is also available under a commercial proprietary license.
24  * For more information, contact us at licensing@x264.com.
25  *****************************************************************************/
26
27 #include "asm.S"
28
29 .macro h264_loop_filter_start
30     ldr             ip,  [sp]
31     ldr             ip,  [ip]
32     vdup.32         d24, ip
33     and             ip,  ip,  ip, lsl #16
34     ands            ip,  ip,  ip, lsl #8
35     bxlt            lr
36 .endm
37
38 .macro align_push_regs
39     and             ip,  sp,  #15
40     add             ip,  ip,  #32
41     sub             sp,  sp,  ip
42     vst1.64         {d12-d15}, [sp,:128]
43     sub             sp,  sp,  #32
44     vst1.64         {d8-d11},  [sp,:128]
45 .endm
46
47 .macro align_pop_regs
48     vld1.64         {d8-d11},  [sp,:128]!
49     vld1.64         {d12-d15}, [sp,:128], ip
50 .endm
51
52 .macro h264_loop_filter_luma
53     vdup.8          q11, r2         @ alpha
54     vmovl.u8        q12, d24
55     vabd.u8         q6,  q8,  q0    @ abs(p0 - q0)
56     vmovl.u16       q12, d24
57     vabd.u8         q14, q9,  q8    @ abs(p1 - p0)
58     vsli.16         q12, q12, #8
59     vabd.u8         q15, q1,  q0    @ abs(q1 - q0)
60     vsli.32         q12, q12, #16
61     vclt.u8         q6,  q6,  q11   @ < alpha
62     vdup.8          q11, r3         @ beta
63     vclt.s8         q7,  q12, #0
64     vclt.u8         q14, q14, q11   @ < beta
65     vclt.u8         q15, q15, q11   @ < beta
66     vbic            q6,  q6,  q7
67     vabd.u8         q4,  q10, q8    @ abs(p2 - p0)
68     vand            q6,  q6,  q14
69     vabd.u8         q5,  q2,  q0    @ abs(q2 - q0)
70     vclt.u8         q4,  q4,  q11   @ < beta
71     vand            q6,  q6,  q15
72     vclt.u8         q5,  q5,  q11   @ < beta
73     vand            q4,  q4,  q6
74     vand            q5,  q5,  q6
75     vand            q12, q12, q6
76     vrhadd.u8       q14, q8,  q0
77     vsub.i8         q6,  q12, q4
78     vqadd.u8        q7,  q9,  q12
79     vhadd.u8        q10, q10, q14
80     vsub.i8         q6,  q6,  q5
81     vhadd.u8        q14, q2,  q14
82     vmin.u8         q7,  q7,  q10
83     vqsub.u8        q11, q9,  q12
84     vqadd.u8        q2,  q1,  q12
85     vmax.u8         q7,  q7,  q11
86     vqsub.u8        q11, q1,  q12
87     vmin.u8         q14, q2,  q14
88     vmovl.u8        q2,  d0
89     vmax.u8         q14, q14, q11
90     vmovl.u8        q10, d1
91     vsubw.u8        q2,  q2,  d16
92     vsubw.u8        q10, q10, d17
93     vshl.i16        q2,  q2,  #2
94     vshl.i16        q10, q10, #2
95     vaddw.u8        q2,  q2,  d18
96     vaddw.u8        q10, q10, d19
97     vsubw.u8        q2,  q2,  d2
98     vsubw.u8        q10, q10, d3
99     vrshrn.i16      d4,  q2,  #3
100     vrshrn.i16      d5,  q10, #3
101     vbsl            q4,  q7,  q9
102     vbsl            q5,  q14, q1
103     vneg.s8         q7,  q6
104     vmovl.u8        q14, d16
105     vmin.s8         q2,  q2,  q6
106     vmovl.u8        q6,  d17
107     vmax.s8         q2,  q2,  q7
108     vmovl.u8        q11, d0
109     vmovl.u8        q12, d1
110     vaddw.s8        q14, q14, d4
111     vaddw.s8        q6,  q6,  d5
112     vsubw.s8        q11, q11, d4
113     vsubw.s8        q12, q12, d5
114     vqmovun.s16     d16, q14
115     vqmovun.s16     d17, q6
116     vqmovun.s16     d0,  q11
117     vqmovun.s16     d1,  q12
118 .endm
119
120 function x264_deblock_v_luma_neon
121     h264_loop_filter_start
122
123     vld1.64         {d0, d1},  [r0,:128], r1
124     vld1.64         {d2, d3},  [r0,:128], r1
125     vld1.64         {d4, d5},  [r0,:128], r1
126     sub             r0,  r0,  r1, lsl #2
127     sub             r0,  r0,  r1, lsl #1
128     vld1.64         {d20,d21}, [r0,:128], r1
129     vld1.64         {d18,d19}, [r0,:128], r1
130     vld1.64         {d16,d17}, [r0,:128], r1
131
132     align_push_regs
133
134     h264_loop_filter_luma
135
136     sub             r0,  r0,  r1, lsl #1
137     vst1.64         {d8, d9},  [r0,:128], r1
138     vst1.64         {d16,d17}, [r0,:128], r1
139     vst1.64         {d0, d1},  [r0,:128], r1
140     vst1.64         {d10,d11}, [r0,:128]
141
142     align_pop_regs
143     bx              lr
144 endfunc
145
146 function x264_deblock_h_luma_neon
147     h264_loop_filter_start
148
149     sub             r0,  r0,  #4
150     vld1.64         {d6},  [r0], r1
151     vld1.64         {d20}, [r0], r1
152     vld1.64         {d18}, [r0], r1
153     vld1.64         {d16}, [r0], r1
154     vld1.64         {d0},  [r0], r1
155     vld1.64         {d2},  [r0], r1
156     vld1.64         {d4},  [r0], r1
157     vld1.64         {d26}, [r0], r1
158     vld1.64         {d7},  [r0], r1
159     vld1.64         {d21}, [r0], r1
160     vld1.64         {d19}, [r0], r1
161     vld1.64         {d17}, [r0], r1
162     vld1.64         {d1},  [r0], r1
163     vld1.64         {d3},  [r0], r1
164     vld1.64         {d5},  [r0], r1
165     vld1.64         {d27}, [r0], r1
166
167     TRANSPOSE8x8    q3, q10, q9, q8, q0, q1, q2, q13
168
169     align_push_regs
170
171     h264_loop_filter_luma
172
173     TRANSPOSE4x4    q4, q8, q0, q5
174
175     sub             r0,  r0,  r1, lsl #4
176     add             r0,  r0,  #2
177     vst1.32         {d8[0]},  [r0], r1
178     vst1.32         {d16[0]}, [r0], r1
179     vst1.32         {d0[0]},  [r0], r1
180     vst1.32         {d10[0]}, [r0], r1
181     vst1.32         {d8[1]},  [r0], r1
182     vst1.32         {d16[1]}, [r0], r1
183     vst1.32         {d0[1]},  [r0], r1
184     vst1.32         {d10[1]}, [r0], r1
185     vst1.32         {d9[0]},  [r0], r1
186     vst1.32         {d17[0]}, [r0], r1
187     vst1.32         {d1[0]},  [r0], r1
188     vst1.32         {d11[0]}, [r0], r1
189     vst1.32         {d9[1]},  [r0], r1
190     vst1.32         {d17[1]}, [r0], r1
191     vst1.32         {d1[1]},  [r0], r1
192     vst1.32         {d11[1]}, [r0], r1
193
194     align_pop_regs
195     bx              lr
196 endfunc
197
198 .macro h264_loop_filter_chroma
199     vdup.8          q11, r2         // alpha
200     vmovl.u8        q12, d24
201     vabd.u8         q13, q8,  q0    // abs(p0 - q0)
202     vabd.u8         q14, q9,  q8    // abs(p1 - p0)
203     vsubl.u8        q2,  d0,  d16
204     vsubl.u8        q3,  d1,  d17
205     vsli.16         q12, q12, #8
206     vshl.i16        q2,  q2,  #2
207     vshl.i16        q3,  q3,  #2
208     vabd.u8         q15, q1,  q0    // abs(q1 - q0)
209     vmovl.u8        q12, d24
210     vaddw.u8        q2,  q2,  d18
211     vaddw.u8        q3,  q3,  d19
212     vclt.u8         q13, q13, q11   // < alpha
213     vsubw.u8        q2,  q2,  d2
214     vsubw.u8        q3,  q3,  d3
215     vsli.16         q12, q12, #8
216     vdup.8          q11, r3         // beta
217     vclt.s8         q10, q12, #0
218     vrshrn.i16      d4,  q2,  #3
219     vrshrn.i16      d5,  q3,  #3
220     vclt.u8         q14, q14, q11   // < beta
221     vbic            q13, q13, q10
222     vclt.u8         q15, q15, q11   // < beta
223     vand            q13, q13, q14
224     vneg.s8         q10, q12
225     vand            q13, q13, q15
226     vmin.s8         q2,  q2,  q12
227     vmovl.u8        q14, d16
228     vand            q2,  q2,  q13
229     vmovl.u8        q15, d17
230     vmax.s8         q2,  q2,  q10
231     vmovl.u8        q11, d0
232     vmovl.u8        q12, d1
233     vaddw.s8        q14, q14, d4
234     vaddw.s8        q15, q15, d5
235     vsubw.s8        q11, q11, d4
236     vsubw.s8        q12, q12, d5
237     vqmovun.s16     d16, q14
238     vqmovun.s16     d17, q15
239     vqmovun.s16     d0,  q11
240     vqmovun.s16     d1,  q12
241 .endm
242
243 function x264_deblock_v_chroma_neon
244     h264_loop_filter_start
245
246     sub             r0,  r0,  r1, lsl #1
247     vld1.8          {d18,d19}, [r0,:128], r1
248     vld1.8          {d16,d17}, [r0,:128], r1
249     vld1.8          {d0, d1},  [r0,:128], r1
250     vld1.8          {d2, d3},  [r0,:128]
251
252     h264_loop_filter_chroma
253
254     sub             r0,  r0,  r1, lsl #1
255     vst1.8          {d16,d17}, [r0,:128], r1
256     vst1.8          {d0, d1},  [r0,:128], r1
257
258     bx              lr
259 endfunc
260
261 function x264_deblock_h_chroma_neon
262     h264_loop_filter_start
263
264     sub             r0,  r0,  #4
265 deblock_h_chroma:
266     vld1.8          {d18}, [r0], r1
267     vld1.8          {d16}, [r0], r1
268     vld1.8          {d0},  [r0], r1
269     vld1.8          {d2},  [r0], r1
270     vld1.8          {d19}, [r0], r1
271     vld1.8          {d17}, [r0], r1
272     vld1.8          {d1},  [r0], r1
273     vld1.8          {d3},  [r0], r1
274
275     TRANSPOSE4x4_16 q9, q8, q0, q1
276
277     h264_loop_filter_chroma
278
279     vtrn.16         q8,  q0
280
281     sub             r0,  r0,  r1, lsl #3
282     add             r0,  r0,  #2
283     vst1.32         {d16[0]}, [r0], r1
284     vst1.32         {d0[0]},  [r0], r1
285     vst1.32         {d16[1]}, [r0], r1
286     vst1.32         {d0[1]},  [r0], r1
287     vst1.32         {d17[0]}, [r0], r1
288     vst1.32         {d1[0]},  [r0], r1
289     vst1.32         {d17[1]}, [r0], r1
290     vst1.32         {d1[1]},  [r0], r1
291
292     bx              lr
293 endfunc
294
295 function x264_deblock_h_chroma_422_neon
296     h264_loop_filter_start
297     push            {lr}
298     sub             r0,  r0,  #4
299     add             r1,  r1,  r1
300     bl              deblock_h_chroma
301     ldr             ip,  [sp, #4]
302     ldr             ip,  [ip]
303     vdup.32         d24, ip
304     sub             r0,  r0,  r1, lsl #3
305     add             r0,  r0,  r1, lsr #1
306     sub             r0,  r0,  #2
307     pop             {lr}
308     b               deblock_h_chroma
309 endfunc
310
311 .macro h264_loop_filter_chroma8
312     vdup.8          d22, r2         @ alpha
313     vmovl.u8        q12, d24
314     vabd.u8         d26, d16, d0    @ abs(p0 - q0)
315     vabd.u8         d28, d18, d16   @ abs(p1 - p0)
316     vsubl.u8        q2,  d0,  d16
317     vsli.16         d24, d24, #8
318     vshl.i16        q2,  q2,  #2
319     vabd.u8         d30, d2,  d0    @ abs(q1 - q0)
320     vaddw.u8        q2,  q2,  d18
321     vclt.u8         d26, d26, d22   @ < alpha
322     vsubw.u8        q2,  q2,  d2
323     vdup.8          d22, r3         @ beta
324     vclt.s8         d20, d24, #0
325     vrshrn.i16      d4,  q2,  #3
326     vclt.u8         d28, d28, d22   @ < beta
327     vbic            d26, d26, d20
328     vclt.u8         d30, d30, d22   @ < beta
329     vand            d26, d26, d28
330     vneg.s8         d20, d24
331     vand            d26, d26, d30
332     vmin.s8         d4,  d4,  d24
333     vmovl.u8        q14, d16
334     vand            d4,  d4,  d26
335     vmax.s8         d4,  d4,  d20
336     vmovl.u8        q11, d0
337     vaddw.s8        q14, q14, d4
338     vsubw.s8        q11, q11, d4
339     vqmovun.s16     d16, q14
340     vqmovun.s16     d0,  q11
341 .endm
342
343 function x264_deblock_h_chroma_mbaff_neon
344     h264_loop_filter_start
345
346     sub             r0,  r0,  #4
347     vld1.8          {d18}, [r0], r1
348     vld1.8          {d16}, [r0], r1
349     vld1.8          {d0},  [r0], r1
350     vld1.8          {d2},  [r0], r1
351
352     TRANSPOSE4x4_16 d18, d16, d0, d2
353
354     h264_loop_filter_chroma8
355
356     vtrn.16         d16, d0
357
358     sub             r0,  r0,  r1, lsl #2
359     add             r0,  r0,  #2
360     vst1.32         {d16[0]}, [r0], r1
361     vst1.32         {d0[0]},  [r0], r1
362     vst1.32         {d16[1]}, [r0], r1
363     vst1.32         {d0[1]},  [r0]
364
365     bx              lr
366 endfunc
367
368 .macro h264_loop_filter_chroma_intra, width=16
369     vdup.8          q11, r2         @ alpha
370     vabd.u8         q13, q8,  q0    @ abs(p0 - q0)
371     vabd.u8         q14, q9,  q8    @ abs(p1 - p0)
372     vabd.u8         q15, q1,  q0    @ abs(q1 - q0)
373     vclt.u8         q13, q13, q11   @ < alpha
374     vdup.8          q11, r3         @ beta
375     vclt.u8         q14, q14, q11   @ < beta
376     vclt.u8         q15, q15, q11   @ < beta
377     vand            q13, q13, q14
378     vand            q13, q13, q15
379
380     vshll.u8        q14, d18, #1
381     vshll.u8        q2,  d2,  #1
382 .ifc \width, 16
383     vshll.u8        q15, d19, #1
384     vshll.u8        q3,  d3,  #1
385     vaddl.u8        q12, d17, d3
386     vaddl.u8        q10, d1,  d19
387 .endif
388     vaddl.u8        q11, d16, d2
389     vaddl.u8        q1,  d18, d0    @ or vaddw q2, to not clobber q1
390     vadd.u16        q14, q14, q11
391     vadd.u16        q2,  q2,  q1
392 .ifc \width, 16
393     vadd.u16        q15, q15, q12
394     vadd.u16        q3,  q3,  q10
395 .endif
396     vqrshrn.u16     d28, q14, #2
397     vqrshrn.u16     d4,  q2, #2
398 .ifc \width, 16
399     vqrshrn.u16     d29, q15, #2
400     vqrshrn.u16     d5,  q3, #2
401 .endif
402     vbit            q8,  q14, q13
403     vbit            q0,  q2,  q13
404 .endm
405
406 function x264_deblock_v_chroma_intra_neon
407     sub             r0,  r0,  r1, lsl #1
408     vld2.8          {d18,d19}, [r0,:128], r1
409     vld2.8          {d16,d17}, [r0,:128], r1
410     vld2.8          {d0, d1},  [r0,:128], r1
411     vld2.8          {d2, d3},  [r0,:128]
412
413     h264_loop_filter_chroma_intra
414
415     sub             r0,  r0,  r1, lsl #1
416     vst2.8          {d16,d17}, [r0,:128], r1
417     vst2.8          {d0, d1},  [r0,:128], r1
418
419     bx              lr
420 endfunc
421
422 function x264_deblock_h_chroma_intra_neon
423     sub             r0,  r0,  #4
424     vld1.8          {d18}, [r0], r1
425     vld1.8          {d16}, [r0], r1
426     vld1.8          {d0},  [r0], r1
427     vld1.8          {d2},  [r0], r1
428     vld1.8          {d19}, [r0], r1
429     vld1.8          {d17}, [r0], r1
430     vld1.8          {d1},  [r0], r1
431     vld1.8          {d3},  [r0], r1
432
433     TRANSPOSE4x4_16 q9, q8, q0, q1
434
435     h264_loop_filter_chroma_intra
436
437     vtrn.16         q8,  q0
438
439     sub             r0,  r0,  r1, lsl #3
440     add             r0,  r0,  #2
441     vst1.32         {d16[0]}, [r0], r1
442     vst1.32         {d0[0]},  [r0], r1
443     vst1.32         {d16[1]}, [r0], r1
444     vst1.32         {d0[1]},  [r0], r1
445     vst1.32         {d17[0]}, [r0], r1
446     vst1.32         {d1[0]},  [r0], r1
447     vst1.32         {d17[1]}, [r0], r1
448     vst1.32         {d1[1]},  [r0], r1
449
450     bx              lr
451 endfunc
452
453 function x264_deblock_h_chroma_422_intra_neon
454     push            {lr}
455     bl              X(x264_deblock_h_chroma_intra_neon)
456     add             r0, r0,  #2
457     pop             {lr}
458     b               X(x264_deblock_h_chroma_intra_neon)
459 endfunc
460
461 function x264_deblock_h_chroma_intra_mbaff_neon
462     sub             r0,  r0,  #4
463     vld1.8          {d18}, [r0], r1
464     vld1.8          {d16}, [r0], r1
465     vld1.8          {d0},  [r0], r1
466     vld1.8          {d2},  [r0], r1
467
468     TRANSPOSE4x4_16 d18, d16, d0, d2
469
470     h264_loop_filter_chroma_intra width=8
471
472     vtrn.16         d16, d0
473
474     sub             r0,  r0,  r1, lsl #2
475     add             r0,  r0,  #2
476     vst1.32         {d16[0]}, [r0], r1
477     vst1.32         {d0[0]},  [r0], r1
478     vst1.32         {d16[1]}, [r0], r1
479     vst1.32         {d0[1]},  [r0]
480
481     bx              lr
482 endfunc
483
484 function x264_deblock_strength_neon
485     ldr             ip,  [sp]
486     vmov.i8         q8,  #0
487     lsl             ip,  ip,  #8
488     add             r3,  r3,  #32
489     sub             ip,  ip,  #(1<<8)-3
490     vmov.i8         q9,  #0
491     vdup.16         q10, ip
492     ldr             ip,  [sp, #4]
493
494 lists:
495     @ load bytes ref
496     vld1.8          {d31}, [r1]!
497     add             r2,  r2,  #16
498     vld1.8          {q1},  [r1]!
499     vmov.i8         q0,  #0
500     vld1.8          {q2},  [r1]!
501     vext.8          q3,  q0,  q1,  #15
502     vext.8          q0,  q0,  q2,  #15
503     vuzp.32         q1,  q2
504     vuzp.32         q3,  q0
505     vext.8          q1,  q15, q2,  #12
506
507     veor            q0,  q0,  q2
508     veor            q1,  q1,  q2
509     vorr            q8,  q8,  q0
510     vorr            q9,  q9,  q1
511
512     vld1.16         {q11}, [r2,:128]!   @ mv + 0x10
513     vld1.16         {q3},  [r2,:128]!   @ mv + 0x20
514     vld1.16         {q12}, [r2,:128]!   @ mv + 0x30
515     vld1.16         {q2},  [r2,:128]!   @ mv + 0x40
516     vld1.16         {q13}, [r2,:128]!   @ mv + 0x50
517     vext.8          q3,  q3,  q12, #12
518     vext.8          q2,  q2,  q13, #12
519     vabd.s16        q0,  q12, q3
520     vld1.16         {q3},  [r2,:128]!   @ mv + 0x60
521     vabd.s16        q1,  q13, q2
522     vld1.16         {q14}, [r2,:128]!   @ mv + 0x70
523     vqmovn.u16      d0,  q0
524     vld1.16         {q2},  [r2,:128]!   @ mv + 0x80
525     vld1.16         {q15}, [r2,:128]!   @ mv + 0x90
526     vqmovn.u16      d1,  q1
527     vext.8          q3,  q3,  q14, #12
528     vext.8          q2,  q2,  q15, #12
529     vabd.s16        q3,  q14, q3
530     vabd.s16        q2,  q15, q2
531     vqmovn.u16      d2,  q3
532     vqmovn.u16      d3,  q2
533
534     vqsub.u8        q0,  q0,  q10
535     vqsub.u8        q1,  q1,  q10
536     vqmovn.u16      d0,  q0
537     vqmovn.u16      d1,  q1
538
539     vabd.s16        q1,  q12, q13
540     vorr            q8,  q8,  q0
541
542     vabd.s16        q0,  q11, q12
543     vabd.s16        q2,  q13, q14
544     vabd.s16        q3,  q14, q15
545     vqmovn.u16      d0,  q0
546     vqmovn.u16      d1,  q1
547     vqmovn.u16      d2,  q2
548     vqmovn.u16      d3,  q3
549
550     vqsub.u8        q0,  q0,  q10
551     vqsub.u8        q1,  q1,  q10
552     vqmovn.u16      d0,  q0
553     vqmovn.u16      d1,  q1
554     subs            ip,  ip,  #1
555     vorr            q9,  q9,  q0
556     beq             lists
557
558     mov             ip,  #-32
559     @ load bytes nnz
560     vld1.8          {d31}, [r0]!
561     vld1.8          {q1},  [r0]!
562     vmov.i8         q0,  #0
563     vld1.8          {q2},  [r0]
564     vext.8          q3,  q0,  q1,  #15
565     vext.8          q0,  q0,  q2,  #15
566     vuzp.32         q1,  q2
567     vuzp.32         q3,  q0
568     vext.8          q1,  q15, q2,  #12
569
570     vorr            q0,  q0,  q2
571     vorr            q1,  q1,  q2
572     vmov.u8         q10, #1
573     vmin.u8         q0,  q0,  q10
574     vmin.u8         q1,  q1,  q10
575     vmin.u8         q8,  q8,  q10       @ mv ? 1 : 0
576     vmin.u8         q9,  q9,  q10
577     vadd.u8         q0,  q0,  q0        @ nnz ? 2 : 0
578     vadd.u8         q1,  q1,  q1
579     vmax.u8         q8,  q8,  q0
580     vmax.u8         q9,  q9,  q1
581     vzip.16         d16, d17
582     vst1.8          {q9}, [r3,:128], ip @ bs[1]
583     vtrn.8          d16, d17
584     vtrn.32         d16, d17
585
586     vst1.8          {q8}, [r3,:128]     @ bs[0]
587     bx              lr
588 endfunc