h264dsp_neon.S 17.9 KB
Newer Older
1 2 3
/*
 * Copyright (c) 2008 Mans Rullgard <mans@mansr.com>
 *
4
 * This file is part of Libav.
5
 *
6
 * Libav is free software; you can redistribute it and/or
7 8 9 10
 * 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.
 *
11
 * Libav is distributed in the hope that it will be useful,
12 13 14 15 16
 * 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
17
 * License along with Libav; if not, write to the Free Software
18 19 20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

21
#include "libavutil/arm/asm.S"
22
#include "neon.S"
23

24 25
        /* H.264 loop filter */

26 27
.macro  h264_loop_filter_start
        ldr             r12, [sp]
28
        tst             r2,  r2
29
        ldr             r12, [r12]
30
        it              ne
31
        tstne           r3,  r3
32 33
        vmov.32         d24[0], r12
        and             r12, r12, r12, lsl #16
34
        it              eq
35
        bxeq            lr
36
        ands            r12, r12, r12, lsl #8
37
        it              lt
38
        bxlt            lr
39
.endm
40

41
.macro  h264_loop_filter_luma
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
        vdup.8          q11, r2         @ alpha
        vmovl.u8        q12, d24
        vabd.u8         q6,  q8,  q0    @ abs(p0 - q0)
        vmovl.u16       q12, d24
        vabd.u8         q14, q9,  q8    @ abs(p1 - p0)
        vsli.16         q12, q12, #8
        vabd.u8         q15, q1,  q0    @ abs(q1 - q0)
        vsli.32         q12, q12, #16
        vclt.u8         q6,  q6,  q11   @ < alpha
        vdup.8          q11, r3         @ beta
        vclt.s8         q7,  q12, #0
        vclt.u8         q14, q14, q11   @ < beta
        vclt.u8         q15, q15, q11   @ < beta
        vbic            q6,  q6,  q7
        vabd.u8         q4,  q10, q8    @ abs(p2 - p0)
        vand            q6,  q6,  q14
        vabd.u8         q5,  q2,  q0    @ abs(q2 - q0)
        vclt.u8         q4,  q4,  q11   @ < beta
        vand            q6,  q6,  q15
        vclt.u8         q5,  q5,  q11   @ < beta
        vand            q4,  q4,  q6
        vand            q5,  q5,  q6
        vand            q12, q12, q6
        vrhadd.u8       q14, q8,  q0
        vsub.i8         q6,  q12, q4
        vqadd.u8        q7,  q9,  q12
        vhadd.u8        q10, q10, q14
        vsub.i8         q6,  q6,  q5
        vhadd.u8        q14, q2,  q14
        vmin.u8         q7,  q7,  q10
        vqsub.u8        q11, q9,  q12
        vqadd.u8        q2,  q1,  q12
        vmax.u8         q7,  q7,  q11
        vqsub.u8        q11, q1,  q12
        vmin.u8         q14, q2,  q14
        vmovl.u8        q2,  d0
        vmax.u8         q14, q14, q11
        vmovl.u8        q10, d1
        vsubw.u8        q2,  q2,  d16
        vsubw.u8        q10, q10, d17
        vshl.i16        q2,  q2,  #2
        vshl.i16        q10, q10, #2
        vaddw.u8        q2,  q2,  d18
        vaddw.u8        q10, q10, d19
        vsubw.u8        q2,  q2,  d2
        vsubw.u8        q10, q10, d3
        vrshrn.i16      d4,  q2,  #3
        vrshrn.i16      d5,  q10, #3
        vbsl            q4,  q7,  q9
        vbsl            q5,  q14, q1
        vneg.s8         q7,  q6
        vmovl.u8        q14, d16
        vmin.s8         q2,  q2,  q6
        vmovl.u8        q6,  d17
        vmax.s8         q2,  q2,  q7
        vmovl.u8        q11, d0
        vmovl.u8        q12, d1
        vaddw.s8        q14, q14, d4
        vaddw.s8        q6,  q6,  d5
        vsubw.s8        q11, q11, d4
        vsubw.s8        q12, q12, d5
        vqmovun.s16     d16, q14
        vqmovun.s16     d17, q6
        vqmovun.s16     d0,  q11
        vqmovun.s16     d1,  q12
107
.endm
108 109 110 111

function ff_h264_v_loop_filter_luma_neon, export=1
        h264_loop_filter_start

112 113 114
        vld1.8          {d0, d1},  [r0,:128], r1
        vld1.8          {d2, d3},  [r0,:128], r1
        vld1.8          {d4, d5},  [r0,:128], r1
115 116
        sub             r0,  r0,  r1, lsl #2
        sub             r0,  r0,  r1, lsl #1
117 118 119
        vld1.8          {d20,d21}, [r0,:128], r1
        vld1.8          {d18,d19}, [r0,:128], r1
        vld1.8          {d16,d17}, [r0,:128], r1
120

121
        vpush           {d8-d15}
122 123 124 125

        h264_loop_filter_luma

        sub             r0,  r0,  r1, lsl #1
126 127 128 129
        vst1.8          {d8, d9},  [r0,:128], r1
        vst1.8          {d16,d17}, [r0,:128], r1
        vst1.8          {d0, d1},  [r0,:128], r1
        vst1.8          {d10,d11}, [r0,:128]
130

131
        vpop            {d8-d15}
132
        bx              lr
133
endfunc
134 135 136 137 138

function ff_h264_h_loop_filter_luma_neon, export=1
        h264_loop_filter_start

        sub             r0,  r0,  #4
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
        vld1.8          {d6},  [r0], r1
        vld1.8          {d20}, [r0], r1
        vld1.8          {d18}, [r0], r1
        vld1.8          {d16}, [r0], r1
        vld1.8          {d0},  [r0], r1
        vld1.8          {d2},  [r0], r1
        vld1.8          {d4},  [r0], r1
        vld1.8          {d26}, [r0], r1
        vld1.8          {d7},  [r0], r1
        vld1.8          {d21}, [r0], r1
        vld1.8          {d19}, [r0], r1
        vld1.8          {d17}, [r0], r1
        vld1.8          {d1},  [r0], r1
        vld1.8          {d3},  [r0], r1
        vld1.8          {d5},  [r0], r1
        vld1.8          {d27}, [r0], r1
155

156
        transpose_8x8   q3, q10, q9, q8, q0, q1, q2, q13
157

158
        vpush           {d8-d15}
159 160 161

        h264_loop_filter_luma

162
        transpose_4x4   q4, q8, q0, q5
163 164

        sub             r0,  r0,  r1, lsl #4
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
        add             r0,  r0,  #2
        vst1.32         {d8[0]},  [r0], r1
        vst1.32         {d16[0]}, [r0], r1
        vst1.32         {d0[0]},  [r0], r1
        vst1.32         {d10[0]}, [r0], r1
        vst1.32         {d8[1]},  [r0], r1
        vst1.32         {d16[1]}, [r0], r1
        vst1.32         {d0[1]},  [r0], r1
        vst1.32         {d10[1]}, [r0], r1
        vst1.32         {d9[0]},  [r0], r1
        vst1.32         {d17[0]}, [r0], r1
        vst1.32         {d1[0]},  [r0], r1
        vst1.32         {d11[0]}, [r0], r1
        vst1.32         {d9[1]},  [r0], r1
        vst1.32         {d17[1]}, [r0], r1
        vst1.32         {d1[1]},  [r0], r1
        vst1.32         {d11[1]}, [r0], r1
182

183
        vpop            {d8-d15}
184
        bx              lr
185
endfunc
186

187
.macro  h264_loop_filter_chroma
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
        vdup.8          d22, r2         @ alpha
        vmovl.u8        q12, d24
        vabd.u8         d26, d16, d0    @ abs(p0 - q0)
        vmovl.u8        q2,  d0
        vabd.u8         d28, d18, d16   @ abs(p1 - p0)
        vsubw.u8        q2,  q2,  d16
        vsli.16         d24, d24, #8
        vshl.i16        q2,  q2,  #2
        vabd.u8         d30, d2,  d0    @ abs(q1 - q0)
        vaddw.u8        q2,  q2,  d18
        vclt.u8         d26, d26, d22   @ < alpha
        vsubw.u8        q2,  q2,  d2
        vdup.8          d22, r3         @ beta
        vrshrn.i16      d4,  q2,  #3
        vclt.u8         d28, d28, d22   @ < beta
        vclt.u8         d30, d30, d22   @ < beta
        vmin.s8         d4,  d4,  d24
205 206
        vneg.s8         d25, d24
        vand            d26, d26, d28
207
        vmax.s8         d4,  d4,  d25
208
        vand            d26, d26, d30
209
        vmovl.u8        q11, d0
210 211
        vand            d4,  d4,  d26
        vmovl.u8        q14, d16
212 213 214 215
        vaddw.s8        q14, q14, d4
        vsubw.s8        q11, q11, d4
        vqmovun.s16     d16, q14
        vqmovun.s16     d0,  q11
216
.endm
217 218 219 220 221

function ff_h264_v_loop_filter_chroma_neon, export=1
        h264_loop_filter_start

        sub             r0,  r0,  r1, lsl #1
222 223 224 225
        vld1.8          {d18}, [r0,:64], r1
        vld1.8          {d16}, [r0,:64], r1
        vld1.8          {d0},  [r0,:64], r1
        vld1.8          {d2},  [r0,:64]
226 227 228 229

        h264_loop_filter_chroma

        sub             r0,  r0,  r1, lsl #1
230 231
        vst1.8          {d16}, [r0,:64], r1
        vst1.8          {d0},  [r0,:64], r1
232 233

        bx              lr
234
endfunc
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271

function ff_h264_h_loop_filter_chroma_neon, export=1
        h264_loop_filter_start

        sub             r0,  r0,  #2
        vld1.32         {d18[0]}, [r0], r1
        vld1.32         {d16[0]}, [r0], r1
        vld1.32         {d0[0]},  [r0], r1
        vld1.32         {d2[0]},  [r0], r1
        vld1.32         {d18[1]}, [r0], r1
        vld1.32         {d16[1]}, [r0], r1
        vld1.32         {d0[1]},  [r0], r1
        vld1.32         {d2[1]},  [r0], r1

        vtrn.16         d18, d0
        vtrn.16         d16, d2
        vtrn.8          d18, d16
        vtrn.8          d0,  d2

        h264_loop_filter_chroma

        vtrn.16         d18, d0
        vtrn.16         d16, d2
        vtrn.8          d18, d16
        vtrn.8          d0,  d2

        sub             r0,  r0,  r1, lsl #3
        vst1.32         {d18[0]}, [r0], r1
        vst1.32         {d16[0]}, [r0], r1
        vst1.32         {d0[0]},  [r0], r1
        vst1.32         {d2[0]},  [r0], r1
        vst1.32         {d18[1]}, [r0], r1
        vst1.32         {d16[1]}, [r0], r1
        vst1.32         {d0[1]},  [r0], r1
        vst1.32         {d2[1]},  [r0], r1

        bx              lr
272
endfunc
273

274 275
@ Biweighted prediction

276
.macro  biweight_16     macs, macd
277 278 279 280
        vdup.8          d0,  r4
        vdup.8          d1,  r5
        vmov            q2,  q8
        vmov            q3,  q8
281
1:      subs            r3,  r3,  #2
282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313
        vld1.8          {d20-d21},[r0,:128], r2
        \macd           q2,  d0,  d20
        pld             [r0]
        \macd           q3,  d0,  d21
        vld1.8          {d22-d23},[r1,:128], r2
        \macs           q2,  d1,  d22
        pld             [r1]
        \macs           q3,  d1,  d23
        vmov            q12, q8
        vld1.8          {d28-d29},[r0,:128], r2
        vmov            q13, q8
        \macd           q12, d0,  d28
        pld             [r0]
        \macd           q13, d0,  d29
        vld1.8          {d30-d31},[r1,:128], r2
        \macs           q12, d1,  d30
        pld             [r1]
        \macs           q13, d1,  d31
        vshl.s16        q2,  q2,  q9
        vshl.s16        q3,  q3,  q9
        vqmovun.s16     d4,  q2
        vqmovun.s16     d5,  q3
        vshl.s16        q12, q12, q9
        vshl.s16        q13, q13, q9
        vqmovun.s16     d24, q12
        vqmovun.s16     d25, q13
        vmov            q3,  q8
        vst1.8          {d4- d5}, [r6,:128], r2
        vmov            q2,  q8
        vst1.8          {d24-d25},[r6,:128], r2
        bne             1b
        pop             {r4-r6, pc}
314
.endm
315

316
.macro  biweight_8      macs, macd
317 318 319 320
        vdup.8          d0,  r4
        vdup.8          d1,  r5
        vmov            q1,  q8
        vmov            q10, q8
321
1:      subs            r3,  r3,  #2
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343
        vld1.8          {d4},[r0,:64], r2
        \macd           q1,  d0,  d4
        pld             [r0]
        vld1.8          {d5},[r1,:64], r2
        \macs           q1,  d1,  d5
        pld             [r1]
        vld1.8          {d6},[r0,:64], r2
        \macd           q10, d0,  d6
        pld             [r0]
        vld1.8          {d7},[r1,:64], r2
        \macs           q10, d1,  d7
        pld             [r1]
        vshl.s16        q1,  q1,  q9
        vqmovun.s16     d2,  q1
        vshl.s16        q10, q10, q9
        vqmovun.s16     d4,  q10
        vmov            q10, q8
        vst1.8          {d2},[r6,:64], r2
        vmov            q1,  q8
        vst1.8          {d4},[r6,:64], r2
        bne             1b
        pop             {r4-r6, pc}
344
.endm
345

346
.macro  biweight_4      macs, macd
347 348 349 350
        vdup.8          d0,  r4
        vdup.8          d1,  r5
        vmov            q1,  q8
        vmov            q10, q8
351
1:      subs            r3,  r3,  #4
352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385
        vld1.32         {d4[0]},[r0,:32], r2
        vld1.32         {d4[1]},[r0,:32], r2
        \macd           q1,  d0,  d4
        pld             [r0]
        vld1.32         {d5[0]},[r1,:32], r2
        vld1.32         {d5[1]},[r1,:32], r2
        \macs           q1,  d1,  d5
        pld             [r1]
        blt             2f
        vld1.32         {d6[0]},[r0,:32], r2
        vld1.32         {d6[1]},[r0,:32], r2
        \macd           q10, d0,  d6
        pld             [r0]
        vld1.32         {d7[0]},[r1,:32], r2
        vld1.32         {d7[1]},[r1,:32], r2
        \macs           q10, d1,  d7
        pld             [r1]
        vshl.s16        q1,  q1,  q9
        vqmovun.s16     d2,  q1
        vshl.s16        q10, q10, q9
        vqmovun.s16     d4,  q10
        vmov            q10, q8
        vst1.32         {d2[0]},[r6,:32], r2
        vst1.32         {d2[1]},[r6,:32], r2
        vmov            q1,  q8
        vst1.32         {d4[0]},[r6,:32], r2
        vst1.32         {d4[1]},[r6,:32], r2
        bne             1b
        pop             {r4-r6, pc}
2:      vshl.s16        q1,  q1,  q9
        vqmovun.s16     d2,  q1
        vst1.32         {d2[0]},[r6,:32], r2
        vst1.32         {d2[1]},[r6,:32], r2
        pop             {r4-r6, pc}
386
.endm
387

388
.macro  biweight_func   w
389
function ff_biweight_h264_pixels_\w\()_neon, export=1
390
        push            {r4-r6, lr}
391 392
        ldr             r12, [sp, #16]
        add             r4,  sp,  #20
393 394 395 396 397
        ldm             r4,  {r4-r6}
        lsr             lr,  r4,  #31
        add             r6,  r6,  #1
        eors            lr,  lr,  r5,  lsr #30
        orr             r6,  r6,  #1
398 399
        vdup.16         q9,  r12
        lsl             r6,  r6,  r12
400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416
        vmvn            q9,  q9
        vdup.16         q8,  r6
        mov             r6,  r0
        beq             10f
        subs            lr,  lr,  #1
        beq             20f
        subs            lr,  lr,  #1
        beq             30f
        b               40f
10:     biweight_\w     vmlal.u8, vmlal.u8
20:     rsb             r4,  r4,  #0
        biweight_\w     vmlal.u8, vmlsl.u8
30:     rsb             r4,  r4,  #0
        rsb             r5,  r5,  #0
        biweight_\w     vmlsl.u8, vmlsl.u8
40:     rsb             r5,  r5,  #0
        biweight_\w     vmlsl.u8, vmlal.u8
417
endfunc
418
.endm
419 420 421 422

        biweight_func   16
        biweight_func   8
        biweight_func   4
423 424 425

@ Weighted prediction

426
.macro  weight_16       add
427 428
        vdup.8          d0,  r12
1:      subs            r2,  r2,  #2
429
        vld1.8          {d20-d21},[r0,:128], r1
430
        vmull.u8        q2,  d0,  d20
431
        pld             [r0]
432
        vmull.u8        q3,  d0,  d21
433
        vld1.8          {d28-d29},[r0,:128], r1
434
        vmull.u8        q12, d0,  d28
435
        pld             [r0]
436 437 438 439 440
        vmull.u8        q13, d0,  d29
        \add            q2,  q8,  q2
        vrshl.s16       q2,  q2,  q9
        \add            q3,  q8,  q3
        vrshl.s16       q3,  q3,  q9
441 442
        vqmovun.s16     d4,  q2
        vqmovun.s16     d5,  q3
443 444 445 446
        \add            q12, q8,  q12
        vrshl.s16       q12, q12, q9
        \add            q13, q8,  q13
        vrshl.s16       q13, q13, q9
447 448 449 450 451 452
        vqmovun.s16     d24, q12
        vqmovun.s16     d25, q13
        vst1.8          {d4- d5}, [r4,:128], r1
        vst1.8          {d24-d25},[r4,:128], r1
        bne             1b
        pop             {r4, pc}
453
.endm
454

455
.macro  weight_8        add
456 457
        vdup.8          d0,  r12
1:      subs            r2,  r2,  #2
458
        vld1.8          {d4},[r0,:64], r1
459
        vmull.u8        q1,  d0,  d4
460 461
        pld             [r0]
        vld1.8          {d6},[r0,:64], r1
462 463
        vmull.u8        q10, d0,  d6
        \add            q1,  q8,  q1
464
        pld             [r0]
465
        vrshl.s16       q1,  q1,  q9
466
        vqmovun.s16     d2,  q1
467 468
        \add            q10, q8,  q10
        vrshl.s16       q10, q10, q9
469 470 471 472 473
        vqmovun.s16     d4,  q10
        vst1.8          {d2},[r4,:64], r1
        vst1.8          {d4},[r4,:64], r1
        bne             1b
        pop             {r4, pc}
474
.endm
475

476
.macro  weight_4        add
477
        vdup.8          d0,  r12
478 479
        vmov            q1,  q8
        vmov            q10, q8
480
1:      subs            r2,  r2,  #4
481 482
        vld1.32         {d4[0]},[r0,:32], r1
        vld1.32         {d4[1]},[r0,:32], r1
483
        vmull.u8        q1,  d0,  d4
484 485 486 487
        pld             [r0]
        blt             2f
        vld1.32         {d6[0]},[r0,:32], r1
        vld1.32         {d6[1]},[r0,:32], r1
488
        vmull.u8        q10, d0,  d6
489
        pld             [r0]
490 491
        \add            q1,  q8,  q1
        vrshl.s16       q1,  q1,  q9
492
        vqmovun.s16     d2,  q1
493 494
        \add            q10, q8,  q10
        vrshl.s16       q10, q10, q9
495 496 497 498 499 500 501 502 503
        vqmovun.s16     d4,  q10
        vmov            q10, q8
        vst1.32         {d2[0]},[r4,:32], r1
        vst1.32         {d2[1]},[r4,:32], r1
        vmov            q1,  q8
        vst1.32         {d4[0]},[r4,:32], r1
        vst1.32         {d4[1]},[r4,:32], r1
        bne             1b
        pop             {r4, pc}
504 505
2:      \add            q1,  q8,  q1
        vrshl.s16       q1,  q1,  q9
506 507 508 509
        vqmovun.s16     d2,  q1
        vst1.32         {d2[0]},[r4,:32], r1
        vst1.32         {d2[1]},[r4,:32], r1
        pop             {r4, pc}
510
.endm
511

512
.macro  weight_func     w
513
function ff_weight_h264_pixels_\w\()_neon, export=1
514
        push            {r4, lr}
515 516 517 518
        ldr             r12, [sp, #8]
        ldr             r4,  [sp, #12]
        cmp             r3,  #1
        lsl             r4,  r4,  r3
519 520
        vdup.16         q8,  r4
        mov             r4,  r0
521
        ble             20f
522
        rsb             lr,  r3,  #1
523
        vdup.16         q9,  lr
524
        cmp             r12, #0
525 526
        blt             10f
        weight_\w       vhadd.s16
527
10:     rsb             r12, r12, #0
528
        weight_\w       vhsub.s16
529
20:     rsb             lr,  r3,  #0
530
        vdup.16         q9,  lr
531
        cmp             r12, #0
532
        blt             10f
533
        weight_\w       vadd.s16
534
10:     rsb             r12, r12, #0
535
        weight_\w       vsub.s16
536
endfunc
537
.endm
538 539 540 541

        weight_func     16
        weight_func     8
        weight_func     4