ARM: NEON H264 8x8 IDCT
authorMåns Rullgård <mans@mansr.com>
Thu, 5 Aug 2010 19:45:57 +0000 (19:45 +0000)
committerMåns Rullgård <mans@mansr.com>
Thu, 5 Aug 2010 19:45:57 +0000 (19:45 +0000)
Parts by David Conrad.

Originally committed as revision 24706 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavcodec/arm/h264dsp_init_arm.c
libavcodec/arm/h264idct_neon.S

index 3955d2c..e55a9f4 100644 (file)
@@ -86,6 +86,12 @@ void ff_h264_idct_add8_neon(uint8_t **dest, const int *block_offset,
                             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 @@ static void ff_h264dsp_init_neon(H264DSPContext *c)
     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)
index 0ba4880..abe0862 100644 (file)
@@ -169,6 +169,210 @@ function ff_h264_idct_add8_neon, export=1
         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