1/* 2 * Copyright (c) 2008 Mans Rullgard <mans@mansr.com> 3 * 4 * This file is part of FFmpeg. 5 * 6 * FFmpeg is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * FFmpeg is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with FFmpeg; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21#include "libavutil/arm/asm.S" 22#include "neon.S" 23 24 /* H.264 loop filter */ 25 26.macro h264_loop_filter_start 27 ldr r12, [sp] 28 tst r2, r2 29 ldr r12, [r12] 30 it ne 31 tstne r3, r3 32 vmov.32 d24[0], r12 33 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 vdup.8 q11, r2 @ alpha 43 vmovl.u8 q12, d24 44 vabd.u8 q6, q8, q0 @ abs(p0 - q0) 45 vmovl.u16 q12, d24 46 vabd.u8 q14, q9, q8 @ abs(p1 - p0) 47 vsli.16 q12, q12, #8 48 vabd.u8 q15, q1, q0 @ abs(q1 - q0) 49 vsli.32 q12, q12, #16 50 vclt.u8 q6, q6, q11 @ < alpha 51 vdup.8 q11, r3 @ beta 52 vclt.s8 q7, q12, #0 53 vclt.u8 q14, q14, q11 @ < beta 54 vclt.u8 q15, q15, q11 @ < beta 55 vbic q6, q6, q7 56 vabd.u8 q4, q10, q8 @ abs(p2 - p0) 57 vand q6, q6, q14 58 vabd.u8 q5, q2, q0 @ abs(q2 - q0) 59 vclt.u8 q4, q4, q11 @ < beta 60 vand q6, q6, q15 61 vclt.u8 q5, q5, q11 @ < beta 62 vand q4, q4, q6 63 vand q5, q5, q6 64 vand q12, q12, q6 65 vrhadd.u8 q14, q8, q0 66 vsub.i8 q6, q12, q4 67 vqadd.u8 q7, q9, q12 68 vhadd.u8 q10, q10, q14 69 vsub.i8 q6, q6, q5 70 vhadd.u8 q14, q2, q14 71 vmin.u8 q7, q7, q10 72 vqsub.u8 q11, q9, q12 73 vqadd.u8 q2, q1, q12 74 vmax.u8 q7, q7, q11 75 vqsub.u8 q11, q1, q12 76 vmin.u8 q14, q2, q14 77 vmovl.u8 q2, d0 78 vmax.u8 q14, q14, q11 79 vmovl.u8 q10, d1 80 vsubw.u8 q2, q2, d16 81 vsubw.u8 q10, q10, d17 82 vshl.i16 q2, q2, #2 83 vshl.i16 q10, q10, #2 84 vaddw.u8 q2, q2, d18 85 vaddw.u8 q10, q10, d19 86 vsubw.u8 q2, q2, d2 87 vsubw.u8 q10, q10, d3 88 vrshrn.i16 d4, q2, #3 89 vrshrn.i16 d5, q10, #3 90 vbsl q4, q7, q9 91 vbsl q5, q14, q1 92 vneg.s8 q7, q6 93 vmovl.u8 q14, d16 94 vmin.s8 q2, q2, q6 95 vmovl.u8 q6, d17 96 vmax.s8 q2, q2, q7 97 vmovl.u8 q11, d0 98 vmovl.u8 q12, d1 99 vaddw.s8 q14, q14, d4 100 vaddw.s8 q6, q6, d5 101 vsubw.s8 q11, q11, d4 102 vsubw.s8 q12, q12, d5 103 vqmovun.s16 d16, q14 104 vqmovun.s16 d17, q6 105 vqmovun.s16 d0, q11 106 vqmovun.s16 d1, q12 107.endm 108 109function ff_h264_v_loop_filter_luma_neon, export=1 110 h264_loop_filter_start 111 112 vld1.8 {d0, d1}, [r0,:128], r1 113 vld1.8 {d2, d3}, [r0,:128], r1 114 vld1.8 {d4, d5}, [r0,:128], r1 115 sub r0, r0, r1, lsl #2 116 sub r0, r0, r1, lsl #1 117 vld1.8 {d20,d21}, [r0,:128], r1 118 vld1.8 {d18,d19}, [r0,:128], r1 119 vld1.8 {d16,d17}, [r0,:128], r1 120 121 vpush {d8-d15} 122 123 h264_loop_filter_luma 124 125 sub r0, r0, r1, lsl #1 126 vst1.8 {d8, d9}, [r0,:128], r1 127 vst1.8 {d16,d17}, [r0,:128], r1 128 vst1.8 {d0, d1}, [r0,:128], r1 129 vst1.8 {d10,d11}, [r0,:128] 130 131 vpop {d8-d15} 132 bx lr 133endfunc 134 135function ff_h264_h_loop_filter_luma_neon, export=1 136 h264_loop_filter_start 137 138 sub r0, r0, #4 139 vld1.8 {d6}, [r0], r1 140 vld1.8 {d20}, [r0], r1 141 vld1.8 {d18}, [r0], r1 142 vld1.8 {d16}, [r0], r1 143 vld1.8 {d0}, [r0], r1 144 vld1.8 {d2}, [r0], r1 145 vld1.8 {d4}, [r0], r1 146 vld1.8 {d26}, [r0], r1 147 vld1.8 {d7}, [r0], r1 148 vld1.8 {d21}, [r0], r1 149 vld1.8 {d19}, [r0], r1 150 vld1.8 {d17}, [r0], r1 151 vld1.8 {d1}, [r0], r1 152 vld1.8 {d3}, [r0], r1 153 vld1.8 {d5}, [r0], r1 154 vld1.8 {d27}, [r0], r1 155 156 transpose_8x8 q3, q10, q9, q8, q0, q1, q2, q13 157 158 vpush {d8-d15} 159 160 h264_loop_filter_luma 161 162 transpose_4x4 q4, q8, q0, q5 163 164 sub r0, r0, r1, lsl #4 165 add r0, r0, #2 166 vst1.32 {d8[0]}, [r0], r1 167 vst1.32 {d16[0]}, [r0], r1 168 vst1.32 {d0[0]}, [r0], r1 169 vst1.32 {d10[0]}, [r0], r1 170 vst1.32 {d8[1]}, [r0], r1 171 vst1.32 {d16[1]}, [r0], r1 172 vst1.32 {d0[1]}, [r0], r1 173 vst1.32 {d10[1]}, [r0], r1 174 vst1.32 {d9[0]}, [r0], r1 175 vst1.32 {d17[0]}, [r0], r1 176 vst1.32 {d1[0]}, [r0], r1 177 vst1.32 {d11[0]}, [r0], r1 178 vst1.32 {d9[1]}, [r0], r1 179 vst1.32 {d17[1]}, [r0], r1 180 vst1.32 {d1[1]}, [r0], r1 181 vst1.32 {d11[1]}, [r0], r1 182 183 vpop {d8-d15} 184 bx lr 185endfunc 186 187.macro h264_loop_filter_chroma 188 vdup.8 d22, r2 @ alpha 189 vmovl.u8 q12, d24 190 vabd.u8 d26, d16, d0 @ abs(p0 - q0) 191 vmovl.u8 q2, d0 192 vabd.u8 d28, d18, d16 @ abs(p1 - p0) 193 vsubw.u8 q2, q2, d16 194 vsli.16 d24, d24, #8 195 vshl.i16 q2, q2, #2 196 vabd.u8 d30, d2, d0 @ abs(q1 - q0) 197 vaddw.u8 q2, q2, d18 198 vclt.u8 d26, d26, d22 @ < alpha 199 vsubw.u8 q2, q2, d2 200 vdup.8 d22, r3 @ beta 201 vrshrn.i16 d4, q2, #3 202 vclt.u8 d28, d28, d22 @ < beta 203 vclt.u8 d30, d30, d22 @ < beta 204 vmin.s8 d4, d4, d24 205 vneg.s8 d25, d24 206 vand d26, d26, d28 207 vmax.s8 d4, d4, d25 208 vand d26, d26, d30 209 vmovl.u8 q11, d0 210 vand d4, d4, d26 211 vmovl.u8 q14, d16 212 vaddw.s8 q14, q14, d4 213 vsubw.s8 q11, q11, d4 214 vqmovun.s16 d16, q14 215 vqmovun.s16 d0, q11 216.endm 217 218function ff_h264_v_loop_filter_chroma_neon, export=1 219 h264_loop_filter_start 220 221 sub r0, r0, r1, lsl #1 222 vld1.8 {d18}, [r0,:64], r1 223 vld1.8 {d16}, [r0,:64], r1 224 vld1.8 {d0}, [r0,:64], r1 225 vld1.8 {d2}, [r0,:64] 226 227 h264_loop_filter_chroma 228 229 sub r0, r0, r1, lsl #1 230 vst1.8 {d16}, [r0,:64], r1 231 vst1.8 {d0}, [r0,:64], r1 232 233 bx lr 234endfunc 235 236function ff_h264_h_loop_filter_chroma_neon, export=1 237 h264_loop_filter_start 238 239 sub r0, r0, #2 240h_loop_filter_chroma420: 241 vld1.32 {d18[0]}, [r0], r1 242 vld1.32 {d16[0]}, [r0], r1 243 vld1.32 {d0[0]}, [r0], r1 244 vld1.32 {d2[0]}, [r0], r1 245 vld1.32 {d18[1]}, [r0], r1 246 vld1.32 {d16[1]}, [r0], r1 247 vld1.32 {d0[1]}, [r0], r1 248 vld1.32 {d2[1]}, [r0], r1 249 250 vtrn.16 d18, d0 251 vtrn.16 d16, d2 252 vtrn.8 d18, d16 253 vtrn.8 d0, d2 254 255 h264_loop_filter_chroma 256 257 vtrn.16 d18, d0 258 vtrn.16 d16, d2 259 vtrn.8 d18, d16 260 vtrn.8 d0, d2 261 262 sub r0, r0, r1, lsl #3 263 vst1.32 {d18[0]}, [r0], r1 264 vst1.32 {d16[0]}, [r0], r1 265 vst1.32 {d0[0]}, [r0], r1 266 vst1.32 {d2[0]}, [r0], r1 267 vst1.32 {d18[1]}, [r0], r1 268 vst1.32 {d16[1]}, [r0], r1 269 vst1.32 {d0[1]}, [r0], r1 270 vst1.32 {d2[1]}, [r0], r1 271 272 bx lr 273endfunc 274 275function ff_h264_h_loop_filter_chroma422_neon, export=1 276 h264_loop_filter_start 277 push {r4, lr} 278 add r4, r0, r1 279 add r1, r1, r1 280 sub r0, r0, #2 281 282 bl h_loop_filter_chroma420 283 284 ldr r12, [sp, #8] 285 ldr r12, [r12] 286 vmov.32 d24[0], r12 287 sub r0, r4, #2 288 289 bl h_loop_filter_chroma420 290 pop {r4, pc} 291endfunc 292 293@ Biweighted prediction 294 295.macro biweight_16 macs, macd 296 vdup.8 d0, r4 297 vdup.8 d1, r5 298 vmov q2, q8 299 vmov q3, q8 3001: subs r3, r3, #2 301 vld1.8 {d20-d21},[r0,:128], r2 302 \macd q2, d0, d20 303 pld [r0] 304 \macd q3, d0, d21 305 vld1.8 {d22-d23},[r1,:128], r2 306 \macs q2, d1, d22 307 pld [r1] 308 \macs q3, d1, d23 309 vmov q12, q8 310 vld1.8 {d28-d29},[r0,:128], r2 311 vmov q13, q8 312 \macd q12, d0, d28 313 pld [r0] 314 \macd q13, d0, d29 315 vld1.8 {d30-d31},[r1,:128], r2 316 \macs q12, d1, d30 317 pld [r1] 318 \macs q13, d1, d31 319 vshl.s16 q2, q2, q9 320 vshl.s16 q3, q3, q9 321 vqmovun.s16 d4, q2 322 vqmovun.s16 d5, q3 323 vshl.s16 q12, q12, q9 324 vshl.s16 q13, q13, q9 325 vqmovun.s16 d24, q12 326 vqmovun.s16 d25, q13 327 vmov q3, q8 328 vst1.8 {d4- d5}, [r6,:128], r2 329 vmov q2, q8 330 vst1.8 {d24-d25},[r6,:128], r2 331 bne 1b 332 pop {r4-r6, pc} 333.endm 334 335.macro biweight_8 macs, macd 336 vdup.8 d0, r4 337 vdup.8 d1, r5 338 vmov q1, q8 339 vmov q10, q8 3401: subs r3, r3, #2 341 vld1.8 {d4},[r0,:64], r2 342 \macd q1, d0, d4 343 pld [r0] 344 vld1.8 {d5},[r1,:64], r2 345 \macs q1, d1, d5 346 pld [r1] 347 vld1.8 {d6},[r0,:64], r2 348 \macd q10, d0, d6 349 pld [r0] 350 vld1.8 {d7},[r1,:64], r2 351 \macs q10, d1, d7 352 pld [r1] 353 vshl.s16 q1, q1, q9 354 vqmovun.s16 d2, q1 355 vshl.s16 q10, q10, q9 356 vqmovun.s16 d4, q10 357 vmov q10, q8 358 vst1.8 {d2},[r6,:64], r2 359 vmov q1, q8 360 vst1.8 {d4},[r6,:64], r2 361 bne 1b 362 pop {r4-r6, pc} 363.endm 364 365.macro biweight_4 macs, macd 366 vdup.8 d0, r4 367 vdup.8 d1, r5 368 vmov q1, q8 369 vmov q10, q8 3701: subs r3, r3, #4 371 vld1.32 {d4[0]},[r0,:32], r2 372 vld1.32 {d4[1]},[r0,:32], r2 373 \macd q1, d0, d4 374 pld [r0] 375 vld1.32 {d5[0]},[r1,:32], r2 376 vld1.32 {d5[1]},[r1,:32], r2 377 \macs q1, d1, d5 378 pld [r1] 379 blt 2f 380 vld1.32 {d6[0]},[r0,:32], r2 381 vld1.32 {d6[1]},[r0,:32], r2 382 \macd q10, d0, d6 383 pld [r0] 384 vld1.32 {d7[0]},[r1,:32], r2 385 vld1.32 {d7[1]},[r1,:32], r2 386 \macs q10, d1, d7 387 pld [r1] 388 vshl.s16 q1, q1, q9 389 vqmovun.s16 d2, q1 390 vshl.s16 q10, q10, q9 391 vqmovun.s16 d4, q10 392 vmov q10, q8 393 vst1.32 {d2[0]},[r6,:32], r2 394 vst1.32 {d2[1]},[r6,:32], r2 395 vmov q1, q8 396 vst1.32 {d4[0]},[r6,:32], r2 397 vst1.32 {d4[1]},[r6,:32], r2 398 bne 1b 399 pop {r4-r6, pc} 4002: vshl.s16 q1, q1, q9 401 vqmovun.s16 d2, q1 402 vst1.32 {d2[0]},[r6,:32], r2 403 vst1.32 {d2[1]},[r6,:32], r2 404 pop {r4-r6, pc} 405.endm 406 407.macro biweight_func w 408function ff_biweight_h264_pixels_\w\()_neon, export=1 409 push {r4-r6, lr} 410 ldr r12, [sp, #16] 411 add r4, sp, #20 412 ldm r4, {r4-r6} 413 lsr lr, r4, #31 414 add r6, r6, #1 415 eors lr, lr, r5, lsr #30 416 orr r6, r6, #1 417 vdup.16 q9, r12 418 lsl r6, r6, r12 419 vmvn q9, q9 420 vdup.16 q8, r6 421 mov r6, r0 422 beq 10f 423 subs lr, lr, #1 424 beq 20f 425 subs lr, lr, #1 426 beq 30f 427 b 40f 42810: biweight_\w vmlal.u8, vmlal.u8 42920: rsb r4, r4, #0 430 biweight_\w vmlal.u8, vmlsl.u8 43130: rsb r4, r4, #0 432 rsb r5, r5, #0 433 biweight_\w vmlsl.u8, vmlsl.u8 43440: rsb r5, r5, #0 435 biweight_\w vmlsl.u8, vmlal.u8 436endfunc 437.endm 438 439 biweight_func 16 440 biweight_func 8 441 biweight_func 4 442 443@ Weighted prediction 444 445.macro weight_16 add 446 vdup.8 d0, r12 4471: subs r2, r2, #2 448 vld1.8 {d20-d21},[r0,:128], r1 449 vmull.u8 q2, d0, d20 450 pld [r0] 451 vmull.u8 q3, d0, d21 452 vld1.8 {d28-d29},[r0,:128], r1 453 vmull.u8 q12, d0, d28 454 pld [r0] 455 vmull.u8 q13, d0, d29 456 \add q2, q8, q2 457 vrshl.s16 q2, q2, q9 458 \add q3, q8, q3 459 vrshl.s16 q3, q3, q9 460 vqmovun.s16 d4, q2 461 vqmovun.s16 d5, q3 462 \add q12, q8, q12 463 vrshl.s16 q12, q12, q9 464 \add q13, q8, q13 465 vrshl.s16 q13, q13, q9 466 vqmovun.s16 d24, q12 467 vqmovun.s16 d25, q13 468 vst1.8 {d4- d5}, [r4,:128], r1 469 vst1.8 {d24-d25},[r4,:128], r1 470 bne 1b 471 pop {r4, pc} 472.endm 473 474.macro weight_8 add 475 vdup.8 d0, r12 4761: subs r2, r2, #2 477 vld1.8 {d4},[r0,:64], r1 478 vmull.u8 q1, d0, d4 479 pld [r0] 480 vld1.8 {d6},[r0,:64], r1 481 vmull.u8 q10, d0, d6 482 \add q1, q8, q1 483 pld [r0] 484 vrshl.s16 q1, q1, q9 485 vqmovun.s16 d2, q1 486 \add q10, q8, q10 487 vrshl.s16 q10, q10, q9 488 vqmovun.s16 d4, q10 489 vst1.8 {d2},[r4,:64], r1 490 vst1.8 {d4},[r4,:64], r1 491 bne 1b 492 pop {r4, pc} 493.endm 494 495.macro weight_4 add 496 vdup.8 d0, r12 497 vmov q1, q8 498 vmov q10, q8 4991: subs r2, r2, #4 500 vld1.32 {d4[0]},[r0,:32], r1 501 vld1.32 {d4[1]},[r0,:32], r1 502 vmull.u8 q1, d0, d4 503 pld [r0] 504 blt 2f 505 vld1.32 {d6[0]},[r0,:32], r1 506 vld1.32 {d6[1]},[r0,:32], r1 507 vmull.u8 q10, d0, d6 508 pld [r0] 509 \add q1, q8, q1 510 vrshl.s16 q1, q1, q9 511 vqmovun.s16 d2, q1 512 \add q10, q8, q10 513 vrshl.s16 q10, q10, q9 514 vqmovun.s16 d4, q10 515 vmov q10, q8 516 vst1.32 {d2[0]},[r4,:32], r1 517 vst1.32 {d2[1]},[r4,:32], r1 518 vmov q1, q8 519 vst1.32 {d4[0]},[r4,:32], r1 520 vst1.32 {d4[1]},[r4,:32], r1 521 bne 1b 522 pop {r4, pc} 5232: \add q1, q8, q1 524 vrshl.s16 q1, q1, q9 525 vqmovun.s16 d2, q1 526 vst1.32 {d2[0]},[r4,:32], r1 527 vst1.32 {d2[1]},[r4,:32], r1 528 pop {r4, pc} 529.endm 530 531.macro weight_func w 532function ff_weight_h264_pixels_\w\()_neon, export=1 533 push {r4, lr} 534 ldr r12, [sp, #8] 535 ldr r4, [sp, #12] 536 cmp r3, #1 537 lsl r4, r4, r3 538 vdup.16 q8, r4 539 mov r4, r0 540 ble 20f 541 rsb lr, r3, #1 542 vdup.16 q9, lr 543 cmp r12, #0 544 blt 10f 545 weight_\w vhadd.s16 54610: rsb r12, r12, #0 547 weight_\w vhsub.s16 54820: rsb lr, r3, #0 549 vdup.16 q9, lr 550 cmp r12, #0 551 blt 10f 552 weight_\w vadd.s16 55310: rsb r12, r12, #0 554 weight_\w vsub.s16 555endfunc 556.endm 557 558 weight_func 16 559 weight_func 8 560 weight_func 4 561