[x264-devel] [PATCH] x264_coeff_level_run4/8/15/16_neon

George Stephanos gaf.stephanos at gmail.com
Wed Feb 8 23:40:29 CET 2012


---
 common/arm/quant-a.S |  104 ++++++++++++++++++++++++++++++++++++++++++++++++++
 common/arm/quant.h   |    5 ++
 common/bitstream.h   |    2 +-
 common/quant.c       |    4 ++
 tools/checkasm.c     |   25 ++++++++++-
 5 files changed, 136 insertions(+), 4 deletions(-)

diff --git a/common/arm/quant-a.S b/common/arm/quant-a.S
index 8e675bd..1c14c86 100644
--- a/common/arm/quant-a.S
+++ b/common/arm/quant-a.S
@@ -353,3 +353,107 @@ function x264_coeff_last64_neon
     movlt       r0,  #0
     bx          lr
 .endfunc
+
+.macro COEFF_LEVEL_RUN size
+function x264_coeff_level_run\size\()_neon
+    push        {r4-r7,lr}
+.if \size == 4
+    vld1.16     {d16}, [r0,:64]
+    vqmovn.u16  d18, q8
+.endif
+
+.if \size == 8
+    vld1.64     {d16,d17}, [r0,:128]
+    vqmovn.u16  d18, q8
+.endif
+
+.if \size == 16 || \size == 15
+    vld1.64     {d16-d19}, [r0]
+    vqmovn.u16  d16, q8
+    vqmovn.u16  d17, q9
+.endif
+
+    movrel      r2, pmovmskb_byte
+
+.if \size == 16 || \size == 15
+    vld1.64     {d0, d1}, [r2]
+    vtst.8      q8, q8
+    vand        q8, q0
+.else
+
+    vld1.64     {d0}, [r2]
+    vtst.8      d18, d18
+    vand        d18, d0
+.endif
+
+.if \size == 4
+    vmov.32     r2, d18[0]
+    add         r2, r2, r2, ror #16
+    add         r2, r2, r2, ror #24
+.endif
+.if \size == 8
+    vmov.i8     d19, #0
+    vpadd.u8    d18, d19
+    vpadd.u8    d18, d19
+    vpadd.u8    d18, d19
+    vmov.32     r2, d18[0]
+.endif
+.if \size == 16 || \size == 15
+    vmov.i8     d19, #0
+    vpadd.u8    d16, d19
+    vpadd.u8    d16, d19
+    vpadd.u8    d16, d19
+
+    vpadd.u8    d17, d19
+    vpadd.u8    d17, d19
+    vpadd.u8    d17, d19
+
+    vmov.32     r2, d16[0]
+    vmov.32     r3, d17[0]
+
+    orr r2, r2, r3, lsl #8
+.endif
+
+.if \size == 4
+    and         r2, #0xff
+.endif
+
+    str         r2, [r1,#4]             //  mask
+
+    orr         r2, #0xf0000000
+    ror         r2, #\size
+    mov         r4, #\size-1
+
+    clz         r3, r2
+
+    add         r2, r2
+    sub         r4, r3
+    lsl         r2, r3
+
+    str         r4, [r1]                // last
+    add         r1, #8
+    add         r6, r1, #64
+    lsl         r4, #1
+    mov         r7, #0
+1:
+    clz         r3, r2
+    ldrsh       r5, [r0, r4]
+    strb        r3, [r6], #1
+    add         r3, #1
+    str         r5, [r1], #4
+    lsl         r2, r3
+    subs        r4, r4, r3, lsl #1
+    add         r7, #1
+    bge         1b
+
+    mov         r0, r7
+    pop         {r4-r7,pc}
+    bx          lr
+.endfunc
+.endm
+
+COEFF_LEVEL_RUN 4
+COEFF_LEVEL_RUN 8
+COEFF_LEVEL_RUN 15
+COEFF_LEVEL_RUN 16
+
diff --git a/common/arm/quant.h b/common/arm/quant.h
index e6fc343..a548d15 100644
--- a/common/arm/quant.h
+++ b/common/arm/quant.h
@@ -42,4 +42,9 @@ int x264_coeff_last15_neon( int16_t * );
 int x264_coeff_last16_neon( int16_t * );
 int x264_coeff_last64_neon( int16_t * );
 
+int x264_coeff_level_run4_neon( int16_t * );
+int x264_coeff_level_run8_neon( int16_t * );
+int x264_coeff_level_run15_neon( int16_t * );
+int x264_coeff_level_run16_neon( int16_t * );
+
 #endif
diff --git a/common/bitstream.h b/common/bitstream.h
index f407e1d..094d5ca 100644
--- a/common/bitstream.h
+++ b/common/bitstream.h
@@ -57,7 +57,7 @@ typedef struct
 {
     int     last;
     int     mask;
-    dctcoef level[16];
+    int32_t level[16];
     uint8_t run[16];
 } x264_run_level_t;
 
diff --git a/common/quant.c b/common/quant.c
index bdf3a0f..5a19d73 100644
--- a/common/quant.c
+++ b/common/quant.c
@@ -706,6 +706,10 @@ void x264_quant_init( x264_t *h, int cpu, x264_quant_function_t *pf )
         pf->coeff_last[ DCT_LUMA_AC] = x264_coeff_last15_neon;
         pf->coeff_last[DCT_LUMA_4x4] = x264_coeff_last16_neon;
         pf->coeff_last[DCT_LUMA_8x8] = x264_coeff_last64_neon;
+        pf->coeff_level_run4 = x264_coeff_level_run4_neon;
+        pf->coeff_level_run8 = x264_coeff_level_run8_neon;
+        pf->coeff_level_run[ DCT_LUMA_AC] = x264_coeff_level_run15_neon;
+        pf->coeff_level_run[DCT_LUMA_4x4] = x264_coeff_level_run16_neon;
     }
 #endif
 #endif // HIGH_BIT_DEPTH
diff --git a/tools/checkasm.c b/tools/checkasm.c
index 88c508c..ae7750f 100644
--- a/tools/checkasm.c
+++ b/tools/checkasm.c
@@ -2022,22 +2022,41 @@ static int check_quant( int cpu_ref, int cpu_new )
             x264_run_level_t runlevel_c, runlevel_a; \
             int nnz = 0; \
             int max = rand() & (size-1); \
-            memset( dct1, 0, size*sizeof(dctcoef) ); \
+            memset( dct1, 0, size*sizeof(int32_t) ); \
             memcpy( &runlevel_a, buf1+i, sizeof(x264_run_level_t) ); \
             memcpy( &runlevel_c, buf1+i, sizeof(x264_run_level_t) ); \
             for( int idx = ac; idx < max; idx++ ) \
-                nnz |= dct1[idx] = !(rand()&3) + (!(rand()&15))*rand(); \
+                nnz |= dct1[idx] = !(rand()&1) + (!(rand()&15))*rand(); \
             if( !nnz ) \
                 dct1[ac] = 1; \
             int result_c = call_c( qf_c.lastname, dct1+ac, &runlevel_c ); \
             int result_a = call_a( qf_a.lastname, dct1+ac, &runlevel_a ); \
             if( result_c != result_a || runlevel_c.last != runlevel_a.last || \
                 runlevel_c.mask != runlevel_a.mask || \
-                memcmp(runlevel_c.level, runlevel_a.level, sizeof(dctcoef)*result_c) || \
+                memcmp(runlevel_c.level, runlevel_a.level, sizeof(int32_t)*result_c) || \
                 memcmp(runlevel_c.run, runlevel_a.run, sizeof(uint8_t)*(result_c-1)) ) \
             { \
                 ok = 0; \
                 fprintf( stderr, #name ": [FAILED]\n" ); \
+                fprintf( stderr, "\ndctcoef: " ); \
+                for (int i = 0; i < size; i++) fprintf( stderr, "%04x ", (dct1+ac)[i] ); \
+                fprintf( stderr, "\n\nresult_a: %d\n", result_a ); \
+                fprintf( stderr, "runlevel_a.last: %d\n", runlevel_a.last ); \
+                fprintf( stderr, "runlevel_a.mask: %d\n", runlevel_a.mask ); \
+                fprintf( stderr, "runlevel_a.level: " ); \
+                for (int i = 0; i < 16; i++) fprintf( stderr, "%08x ", runlevel_a.level[i] ); \
+                fprintf( stderr, "\n" ); \
+                fprintf( stderr, "runlevel_a.run: " ); \
+                for (int i = 0; i < 16; i++) fprintf( stderr, "%02x ", runlevel_a.run[i] ); \
+                fprintf( stderr, "\n\nresult_c: %d\n", result_c ); \
+                fprintf( stderr, "runlevel_c.last: %d\n", runlevel_c.last ); \
+                fprintf( stderr, "runlevel_c.mask: %d\n", runlevel_c.mask ); \
+                fprintf( stderr, "runlevel_c.level: " ); \
+                for (int i = 0; i < 16; i++) fprintf( stderr, "%08x ", runlevel_c.level[i] ); \
+                fprintf( stderr, "\n" ); \
+                fprintf( stderr, "runlevel_c.run: " ); \
+                for (int i = 0; i < 16; i++) fprintf( stderr, "%02x ", runlevel_c.run[i] ); \
+                fprintf( stderr, "\n\n" ); \
                 break; \
             } \
         } \
-- 
1.7.4.1



More information about the x264-devel mailing list