# HG changeset patch # User mru # Date 1281037557 0 # Node ID ba14e3adeccd53bda781c7bc55637886989a7ac5 # Parent 06bdd447f4f7a2787d5b327739ca2e6f50b6412f ARM: NEON H264 8x8 IDCT Parts by David Conrad. diff -r 06bdd447f4f7 -r ba14e3adeccd arm/h264dsp_init_arm.c --- a/arm/h264dsp_init_arm.c Thu Aug 05 00:49:48 2010 +0000 +++ b/arm/h264dsp_init_arm.c Thu Aug 05 19:45:57 2010 +0000 @@ -86,6 +86,12 @@ DCTELEM *block, int stride, const uint8_t nnzc[6*8]); +void ff_h264_idct8_add_neon(uint8_t *dst, DCTELEM *block, int stride); +void ff_h264_idct8_dc_add_neon(uint8_t *dst, DCTELEM *block, int stride); +void ff_h264_idct8_add4_neon(uint8_t *dst, const int *block_offset, + DCTELEM *block, int stride, + const uint8_t nnzc[6*8]); + static void ff_h264dsp_init_neon(H264DSPContext *c) { c->h264_v_loop_filter_luma = ff_h264_v_loop_filter_luma_neon; @@ -116,6 +122,9 @@ c->h264_idct_add16 = ff_h264_idct_add16_neon; c->h264_idct_add16intra = ff_h264_idct_add16intra_neon; c->h264_idct_add8 = ff_h264_idct_add8_neon; + c->h264_idct8_add = ff_h264_idct8_add_neon; + c->h264_idct8_dc_add = ff_h264_idct8_dc_add_neon; + c->h264_idct8_add4 = ff_h264_idct8_add4_neon; } void ff_h264dsp_init_arm(H264DSPContext *c) diff -r 06bdd447f4f7 -r ba14e3adeccd arm/h264idct_neon.S --- a/arm/h264idct_neon.S Thu Aug 05 00:49:48 2010 +0000 +++ b/arm/h264idct_neon.S Thu Aug 05 19:45:57 2010 +0000 @@ -169,6 +169,210 @@ pop {r4-r10,pc} endfunc +.macro idct8x8_cols pass + .if \pass == 0 + qa .req q2 + qb .req q14 + vshr.s16 q2, q10, #1 + vadd.i16 q0, q8, q12 + vld1.16 {q14-q15},[r1,:128]! + vsub.i16 q1, q8, q12 + vshr.s16 q3, q14, #1 + vsub.i16 q2, q2, q14 + vadd.i16 q3, q3, q10 + .else + qa .req q14 + qb .req q2 + vtrn.32 q8, q10 + vtrn.16 q12, q13 + vtrn.32 q9, q11 + vtrn.32 q12, q2 + vtrn.32 q13, q15 + vswp d21, d4 + vshr.s16 q14, q10, #1 + vswp d17, d24 + vshr.s16 q3, q2, #1 + vswp d19, d26 + vadd.i16 q0, q8, q12 + vswp d23, d30 + vsub.i16 q1, q8, q12 + vsub.i16 q14, q14, q2 + vadd.i16 q3, q3, q10 + .endif + vadd.i16 q10, q1, qa + vsub.i16 q12, q1, qa + vadd.i16 q8, q0, q3 + vsub.i16 qb, q0, q3 + vsub.i16 q0, q13, q11 + vadd.i16 q1, q15, q9 + vsub.i16 qa, q15, q9 + vadd.i16 q3, q13, q11 + vsub.i16 q0, q0, q15 + vsub.i16 q1, q1, q11 + vadd.i16 qa, qa, q13 + vadd.i16 q3, q3, q9 + vshr.s16 q9, q9, #1 + vshr.s16 q11, q11, #1 + vshr.s16 q13, q13, #1 + vshr.s16 q15, q15, #1 + vsub.i16 q0, q0, q15 + vsub.i16 q1, q1, q11 + vadd.i16 qa, qa, q13 + vadd.i16 q3, q3, q9 + vshr.s16 q9, q0, #2 + vshr.s16 q11, q1, #2 + vshr.s16 q13, qa, #2 + vshr.s16 q15, q3, #2 + vsub.i16 q3, q3, q9 + vsub.i16 qa, q11, qa + vadd.i16 q1, q1, q13 + vadd.i16 q0, q0, q15 + .if \pass == 0 + vsub.i16 q15, q8, q3 + vadd.i16 q8, q8, q3 + vadd.i16 q9, q10, q2 + vsub.i16 q2, q10, q2 + vtrn.16 q8, q9 + vadd.i16 q10, q12, q1 + vtrn.16 q2, q15 + vadd.i16 q11, q14, q0 + vsub.i16 q13, q12, q1 + vtrn.16 q10, q11 + vsub.i16 q12, q14, q0 + .else + vsub.i16 q15, q8, q3 + vadd.i16 q8, q8, q3 + vadd.i16 q9, q10, q14 + vsub.i16 q14, q10, q14 + vadd.i16 q10, q12, q1 + vsub.i16 q13, q12, q1 + vadd.i16 q11, q2, q0 + vsub.i16 q12, q2, q0 + .endif + .unreq qa + .unreq qb +.endm + +function ff_h264_idct8_add_neon, export=1 + vld1.16 {q8-q9}, [r1,:128]! + vld1.16 {q10-q11},[r1,:128]! + vld1.16 {q12-q13},[r1,:128]! + + idct8x8_cols 0 + idct8x8_cols 1 + + mov r3, r0 + vrshr.s16 q8, q8, #6 + vld1.8 {d0}, [r0,:64], r2 + vrshr.s16 q9, q9, #6 + vld1.8 {d1}, [r0,:64], r2 + vrshr.s16 q10, q10, #6 + vld1.8 {d2}, [r0,:64], r2 + vrshr.s16 q11, q11, #6 + vld1.8 {d3}, [r0,:64], r2 + vrshr.s16 q12, q12, #6 + vld1.8 {d4}, [r0,:64], r2 + vrshr.s16 q13, q13, #6 + vld1.8 {d5}, [r0,:64], r2 + vrshr.s16 q14, q14, #6 + vld1.8 {d6}, [r0,:64], r2 + vrshr.s16 q15, q15, #6 + vld1.8 {d7}, [r0,:64], r2 + vaddw.u8 q8, q8, d0 + vaddw.u8 q9, q9, d1 + vaddw.u8 q10, q10, d2 + vqmovun.s16 d0, q8 + vaddw.u8 q11, q11, d3 + vqmovun.s16 d1, q9 + vaddw.u8 q12, q12, d4 + vqmovun.s16 d2, q10 + vst1.8 {d0}, [r3,:64], r2 + vaddw.u8 q13, q13, d5 + vqmovun.s16 d3, q11 + vst1.8 {d1}, [r3,:64], r2 + vaddw.u8 q14, q14, d6 + vqmovun.s16 d4, q12 + vst1.8 {d2}, [r3,:64], r2 + vaddw.u8 q15, q15, d7 + vqmovun.s16 d5, q13 + vst1.8 {d3}, [r3,:64], r2 + vqmovun.s16 d6, q14 + vqmovun.s16 d7, q15 + vst1.8 {d4}, [r3,:64], r2 + vst1.8 {d5}, [r3,:64], r2 + vst1.8 {d6}, [r3,:64], r2 + vst1.8 {d7}, [r3,:64], r2 + + sub r1, r1, #128 + bx lr +endfunc + +function ff_h264_idct8_dc_add_neon, export=1 + vld1.16 {d30[],d31[]},[r1,:16] + vld1.32 {d0}, [r0,:64], r2 + vrshr.s16 q15, q15, #6 + vld1.32 {d1}, [r0,:64], r2 + vld1.32 {d2}, [r0,:64], r2 + vaddw.u8 q8, q15, d0 + vld1.32 {d3}, [r0,:64], r2 + vaddw.u8 q9, q15, d1 + vld1.32 {d4}, [r0,:64], r2 + vaddw.u8 q10, q15, d2 + vld1.32 {d5}, [r0,:64], r2 + vaddw.u8 q11, q15, d3 + vld1.32 {d6}, [r0,:64], r2 + vaddw.u8 q12, q15, d4 + vld1.32 {d7}, [r0,:64], r2 + vaddw.u8 q13, q15, d5 + vaddw.u8 q14, q15, d6 + vaddw.u8 q15, q15, d7 + vqmovun.s16 d0, q8 + vqmovun.s16 d1, q9 + vqmovun.s16 d2, q10 + vqmovun.s16 d3, q11 + sub r0, r0, r2, lsl #3 + vst1.32 {d0}, [r0,:64], r2 + vqmovun.s16 d4, q12 + vst1.32 {d1}, [r0,:64], r2 + vqmovun.s16 d5, q13 + vst1.32 {d2}, [r0,:64], r2 + vqmovun.s16 d6, q14 + vst1.32 {d3}, [r0,:64], r2 + vqmovun.s16 d7, q15 + vst1.32 {d4}, [r0,:64], r2 + vst1.32 {d5}, [r0,:64], r2 + vst1.32 {d6}, [r0,:64], r2 + vst1.32 {d7}, [r0,:64], r2 + bx lr +endfunc + +function ff_h264_idct8_add4_neon, export=1 + push {r4-r8,lr} + mov r4, r0 + mov r5, r1 + mov r1, r2 + mov r2, r3 + ldr r6, [sp, #24] + movrel r7, scan8 + mov r12, #16 +1: ldrb r8, [r7], #4 + ldr r0, [r5], #16 + ldrb r8, [r6, r8] + subs r8, r8, #1 + blt 2f + ldrsh lr, [r1] + add r0, r0, r4 + movne lr, #0 + cmp lr, #0 + adrne lr, ff_h264_idct8_dc_add_neon + adreq lr, ff_h264_idct8_add_neon + blx lr +2: subs r12, r12, #4 + add r1, r1, #128 + bne 1b + pop {r4-r8,pc} +endfunc + .section .rodata scan8: .byte 4+1*8, 5+1*8, 4+2*8, 5+2*8 .byte 6+1*8, 7+1*8, 6+2*8, 7+2*8