]> granicus.if.org Git - libvpx/commitdiff
neon fast quantizer updated
authorTero Rintaluoma <teror@google.com>
Mon, 11 Apr 2011 09:04:17 +0000 (12:04 +0300)
committerTero Rintaluoma <teror@google.com>
Fri, 6 May 2011 05:59:52 +0000 (08:59 +0300)
vp8_fast_quantize_b_neon function updated and further optimized.
 - match current C implementation of fast quantizer
 - updated to use asm_enc_offsets for structure members
 - updated ads2gas scripts to handle alignment issues

Change-Id: I5cbad9c460ad8ddb35d2970a8684cc620711c56d

build/make/ads2gas.pl
build/make/ads2gas_apple.pl
vp8/encoder/arm/arm_csystemdependent.c
vp8/encoder/arm/neon/fastquantizeb_neon.asm
vp8/encoder/arm/quantize_arm.c [deleted file]
vp8/encoder/arm/quantize_arm.h
vp8/encoder/quantize.h
vp8/vp8cx_arm.mk

index 3dff048b559a04f9d39e7c3c55a7a90b5e413bb4..efdfce7a124112eb8fcd42fd36aa426e3515c155 100755 (executable)
@@ -23,6 +23,9 @@ print "\t.equ DO1STROUNDING, 0\n";
 
 while (<STDIN>)
 {
+    # Load and store alignment
+    s/@/,:/g;
+
     # Comment character
     s/;/@/g;
 
@@ -114,8 +117,8 @@ while (<STDIN>)
     # put the colon at the end of the line in the macro
     s/^([a-zA-Z_0-9\$]+)/$1:/ if !/EQU/;
 
-    # Strip ALIGN
-    s/\sALIGN/@ ALIGN/g;
+    # ALIGN directive
+    s/ALIGN/.balign/g;
 
     # Strip ARM
     s/\sARM/@ ARM/g;
index 5014c61fb387d74b2bc320e7456332d866c6bb43..1b303937431693ecc489218deaa3c14f3f928252 100755 (executable)
@@ -41,6 +41,9 @@ sub trim($)
 
 while (<STDIN>)
 {
+    # Load and store alignment
+    s/@/,:/g;
+
     # Comment character
     s/;/@/g;
 
@@ -137,8 +140,8 @@ while (<STDIN>)
     # put the colon at the end of the line in the macro
     s/^([a-zA-Z_0-9\$]+)/$1:/ if !/EQU/;
 
-    # Strip ALIGN
-    s/\sALIGN/@ ALIGN/g;
+    # ALIGN directive
+    s/ALIGN/.balign/g;
 
     # Strip ARM
     s/\sARM/@ ARM/g;
index f148b89970876cbd7299f603fc0c23841082974d..af2a5df9832a503d1302460459ffed4a6498f347 100644 (file)
@@ -121,12 +121,8 @@ void vp8_arch_arm_encoder_init(VP8_COMP *cpi)
         cpi->rtcd.encodemb.submby                = vp8_subtract_mby_neon;
         cpi->rtcd.encodemb.submbuv               = vp8_subtract_mbuv_neon;
 
-        /*cpi->rtcd.quantize.quantb                = vp8_regular_quantize_b;
-        cpi->rtcd.quantize.fastquantb            = vp8_fast_quantize_b_c;*/
-        /* The neon quantizer has not been updated to match the new exact
-         * quantizer introduced in commit e04e2935
-         */
-        /*cpi->rtcd.quantize.fastquantb            = vp8_fast_quantize_b_neon;*/
+        /*cpi->rtcd.quantize.quantb                = vp8_regular_quantize_b;*/
+        cpi->rtcd.quantize.fastquantb            = vp8_fast_quantize_b_neon;
     }
 #endif
 
index ca1ea9c185a208a0581f99c34f58ea90e24477a1..3dd92b12ee210ab7c559766c011116ec9136f8e0 100644 (file)
@@ -1,5 +1,5 @@
 ;
-;  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+;  Copyright (c) 2011 The WebM project authors. All Rights Reserved.
 ;
 ;  Use of this source code is governed by a BSD-style license
 ;  that can be found in the LICENSE file in the root of the source
 ;
 
 
-    EXPORT  |vp8_fast_quantize_b_neon_func|
+    EXPORT  |vp8_fast_quantize_b_neon|
+
+    INCLUDE asm_enc_offsets.asm
 
     ARM
     REQUIRE8
     PRESERVE8
 
-    AREA ||.text||, CODE, READONLY, ALIGN=2
+    AREA ||.text||, CODE, READONLY, ALIGN=4
 
-; r0        short *coeff_ptr
-; r1        short *zbin_ptr
-; r2        short *qcoeff_ptr
-; r3        short *dqcoeff_ptr
-; stack     short *dequant_ptr
-; stack     short *scan_mask
-; stack     short *round_ptr
-; stack     short *quant_ptr
 
-; return    int * eob
-|vp8_fast_quantize_b_neon_func| PROC
-    vld1.16         {q0, q1}, [r0]              ;load z
-    vld1.16         {q10, q11}, [r1]            ;load zbin
+;void vp8_fast_quantize_b_c(BLOCK *b, BLOCKD *d)
+|vp8_fast_quantize_b_neon| PROC
 
-    vabs.s16        q4, q0                      ;calculate x = abs(z)
-    vabs.s16        q5, q1
+    stmfd           sp!, {r4-r7}
 
-    vcge.s16        q10, q4, q10                ;x>=zbin
-    vcge.s16        q11, q5, q11
+    ldr             r3, [r0, #vp8_block_coeff]
+    ldr             r4, [r0, #vp8_block_quant_fast]
+    ldr             r5, [r0, #vp8_block_round]
 
-    ;if x<zbin (q10 & q11 are all 0), go to zero_output
-    vorr.s16        q6, q10, q11
-    vorr.s16        d12, d12, d13
-    vmov            r0, r1, d12
-    orr             r0, r0, r1
-    cmp             r0, #0
-    beq             zero_output
+    vld1.16         {q0, q1}, [r3@128]  ; load z
+    vorr.s16        q14, q0, q1         ; check if all zero (step 1)
+    ldr             r6, [r1, #vp8_blockd_qcoeff]
+    ldr             r7, [r1, #vp8_blockd_dqcoeff]
+    vorr.s16        d28, d28, d29       ; check if all zero (step 2)
 
-    ldr             r0, [sp, #8]                ;load round_ptr
-    ldr             r12, [sp, #12]              ;load quant_ptr
+    vabs.s16        q12, q0             ; calculate x = abs(z)
+    vabs.s16        q13, q1
 
     ;right shift 15 to get sign, all 0 if it is positive, all 1 if it is negative
-    vshr.s16        q2, q0, #15                 ; sz
+    vshr.s16        q2, q0, #15         ; sz
+    vmov            r2, r3, d28         ; check if all zero (step 3)
     vshr.s16        q3, q1, #15
 
-    vld1.s16        {q6, q7}, [r0]              ;load round_ptr [0-15]
-    vld1.s16        {q8, q9}, [r12]             ;load quant_ptr [0-15]
+    vld1.s16        {q14, q15}, [r5@128]; load round_ptr [0-15]
+    vld1.s16        {q8, q9}, [r4@128]  ; load quant_ptr [0-15]
 
-    vadd.s16        q4, q6                      ;x + Round
-    vadd.s16        q5, q7
+    vadd.s16        q12, q14            ; x + Round
+    vadd.s16        q13, q15
 
-    ldr             r0, [sp, #4]                ;load rvsplus1_scan_order ptr
+    ldr             r0, _inv_zig_zag_   ; load ptr of inverse zigzag table
 
-    vqdmulh.s16     q4, q8                      ;y = ((Round + abs(z)) * Quant) >> 16
-    vqdmulh.s16     q5, q9
+    vqdmulh.s16     q12, q8             ; y = ((Round+abs(z)) * Quant) >> 16
+    vqdmulh.s16     q13, q9
 
-    vld1.16         {q0, q1}, [r0]              ;load rvsplus1_scan_order
-    vceq.s16        q8, q8                      ;set q8 to all 1
+    vld1.16         {q10, q11}, [r0@128]; load inverse scan order
 
-    vshr.s16        q4, #1                      ;right shift 1 after vqdmulh
-    vshr.s16        q5, #1
+    vceq.s16        q8, q8              ; set q8 to all 1
 
-    ;modify data to have its original sign
-    veor.s16        q4, q2                      ; y^sz
-    veor.s16        q5, q3
+    ldr             r4, [r1, #vp8_blockd_dequant]
+
+    vshr.s16        q12, #1             ; right shift 1 after vqdmulh
+    vshr.s16        q13, #1
 
-    ldr             r12, [sp]                   ;load dequant_ptr
+    orr             r2, r2, r3          ; check if all zero (step 4)
+    cmp             r2, #0              ; check if all zero (step 5)
+    beq             zero_output         ; check if all zero (step 6)
+
+    ;modify data to have its original sign
+    veor.s16        q12, q2             ; y^sz
+    veor.s16        q13, q3
 
-    vsub.s16        q4, q2                      ; x1 = (y^sz) - sz = (y^sz) - (-1) (two's complement)
-    vsub.s16        q5, q3
+    vsub.s16        q12, q2             ; x1=(y^sz)-sz = (y^sz)-(-1) (2's complement)
+    vsub.s16        q13, q3
 
-    vand.s16        q4, q10                     ;mask off x1 elements
-    vand.s16        q5, q11
+    vld1.s16        {q2, q3}, [r4@128]  ; load dequant_ptr[i]
 
-    vld1.s16        {q6, q7}, [r12]             ;load dequant_ptr[i]
+    vtst.16         q14, q12, q8        ; now find eob
+    vtst.16         q15, q13, q8        ; non-zero element is set to all 1
 
-    vtst.16         q14, q4, q8                 ;now find eob
-    vtst.16         q15, q5, q8                 ;non-zero element is set to all 1 in q4, q5
+    vst1.s16        {q12, q13}, [r6@128]; store: qcoeff = x1
 
-    vst1.s16        {q4, q5}, [r2]              ;store: qcoeff = x1
+    vand            q10, q10, q14       ; get all valid numbers from scan array
+    vand            q11, q11, q15
 
-    vand            q0, q0, q14                 ;get all valid number from rvsplus1_scan_order array
-    vand            q1, q1, q15
 
-    vmax.u16        q0, q0, q1                  ;find maximum value in q0, q1
+    vmax.u16        q0, q10, q11        ; find maximum value in q0, q1
     vmax.u16        d0, d0, d1
     vmovl.u16       q0, d0
 
-    vmul.s16        q6, q4                      ;x * Dequant
-    vmul.s16        q7, q5
+    vmul.s16        q2, q12             ; x * Dequant
+    vmul.s16        q3, q13
 
     vmax.u32        d0, d0, d1
     vpmax.u32       d0, d0, d0
 
-    vst1.s16        {q6, q7}, [r3]              ;store dqcoeff = x * Dequant
+    vst1.s16        {q2, q3}, [r7@128]  ; store dqcoeff = x * Dequant
 
-    vmov.32         r0, d0[0]
+    vmov.32         r0, d0[0]           ; this instruction takes 1+13 cycles
+                                        ; if we have vfp, we could use
+                                        ; vstr      s0, [r1, #vp8_blockd_eob]
+    str             r0, [r1, #vp8_blockd_eob]
+
+    ldmfd           sp!, {r4-r7}
     bx              lr
 
 zero_output
-    vst1.s16        {q10, q11}, [r2]        ; qcoeff = 0
-    vst1.s16        {q10, q11}, [r3]        ; dqcoeff = 0
-    mov             r0, #0
+    str             r2, [r1, #vp8_blockd_eob]
+    vst1.s16        {q0, q1}, [r6@128]  ; qcoeff = 0
+    vst1.s16        {q0, q1}, [r7@128]  ; dqcoeff = 0
 
+    ldmfd           sp!, {r4-r7}
     bx              lr
 
     ENDP
 
+; default inverse zigzag table is defined in vp8/common/entropy.c
+_inv_zig_zag_
+    DCD inv_zig_zag
+
+    ALIGN 16    ; enable use of @128 bit aligned loads
+inv_zig_zag
+    DCW 0x0001, 0x0002, 0x0006, 0x0007
+    DCW 0x0003, 0x0005, 0x0008, 0x000d
+    DCW 0x0004, 0x0009, 0x000c, 0x000e
+    DCW 0x000a, 0x000b, 0x000f, 0x0010
+
     END
+
diff --git a/vp8/encoder/arm/quantize_arm.c b/vp8/encoder/arm/quantize_arm.c
deleted file mode 100644 (file)
index 0e3334a..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-
-#include <math.h>
-#include "vpx_mem/vpx_mem.h"
-
-#include "vp8/encoder/quantize.h"
-#include "vp8/common/entropy.h"
-
-DECLARE_ALIGNED(16, const short, vp8_rvsplus1_default_zig_zag1d[16]) =
-{
-    1,  2,  6,  7,
-    3,  5,  8,  13,
-    4,  9,  12, 14,
-    10, 11, 15, 16,
-};
-
-
-extern int vp8_fast_quantize_b_neon_func(short *coeff_ptr, short *zbin_ptr, short *qcoeff_ptr, short *dqcoeff_ptr, short *dequant_ptr, const short *scan_mask, short *round_ptr, short *quant_ptr);
-
-void vp8_fast_quantize_b_neon(BLOCK *b, BLOCKD *d)
-{
-    d->eob = vp8_fast_quantize_b_neon_func(b->coeff, b->zbin, d->qcoeff, d->dqcoeff, d->dequant, vp8_rvsplus1_default_zig_zag1d, b->round, b->quant_fast);
-}
-
-/*
-//neon code is written according to the following rewritten c code
-void vp8_fast_quantize_b_neon(BLOCK *b,BLOCKD *d)
-{
-    int i, rc, eob;
-    int zbin;
-    int x, x1, y, z, sz;
-    short *coeff_ptr  = &b->Coeff[0];
-    short *zbin_ptr   = &b->Zbin[0][0];
-    short *round_ptr  = &b->Round[0][0];
-    short *quant_ptr  = &b->Quant[0][0];
-    short *qcoeff_ptr = d->qcoeff;
-    short *dqcoeff_ptr= d->dqcoeff;
-    short *dequant_ptr= &d->Dequant[0][0];
-
-    eob = 0;
-
-    for(i=0;i<16;i++)
-    {
-        z    = coeff_ptr[i];
-        zbin = zbin_ptr[i] ;
-        x  = abs(z);                                    // x = abs(z)
-
-        if(x>=zbin)
-        {
-            sz = (z>>31);                               // sign of z
-            y  = ((x+round_ptr[i])*quant_ptr[i])>>16;     // quantize (x)
-            x1  = (y^sz) - sz;                          // get the sign back
-
-            qcoeff_ptr[i] = x1;                          // write to destination
-            dqcoeff_ptr[i] = x1 * dequant_ptr[i];         // dequantized value
-
-            if(y)
-            {
-                if(eob<vp8_rvsplus1_default_zig_zag1d[i])
-                    eob=(int)vp8_rvsplus1_default_zig_zag1d[i];         // last nonzero coeffs
-            }
-        }else
-        {
-            qcoeff_ptr[i] = 0;                          // write to destination
-            dqcoeff_ptr[i] = 0;         // dequantized value
-        }
-    }
-        d->eob = eob;
-}
-*/
index 0c6adf4c25bc4a67bfcdd659f10cfa2d667f4831..af4187ac1d2827ec09fbc2163a009a43bac2401a 100644 (file)
@@ -23,14 +23,13 @@ extern prototype_quantize_block(vp8_fast_quantize_b_armv6);
 
 
 #if HAVE_ARMV7
+
 extern prototype_quantize_block(vp8_fast_quantize_b_neon);
 
-/* The neon quantizer has not been updated to match the new exact
- * quantizer introduced in commit e04e2935
- */
-//#undef  vp8_quantize_fastquantb
-//#define vp8_quantize_fastquantb vp8_fast_quantize_b_neon
+#undef  vp8_quantize_fastquantb
+#define vp8_quantize_fastquantb vp8_fast_quantize_b_neon
 
-#endif
+#endif /* HAVE_ARMV7 */
 
 #endif
+
index b74718bfaa6f07ce00304e5a1b2d0fd99aa7b7c5..e4c32a570f0e769ee367a6fd6cb6080cebb581d5 100644 (file)
@@ -17,6 +17,7 @@
 #define prototype_quantize_block(sym) \
     void (sym)(BLOCK *b,BLOCKD *d)
 
+
 #if ARCH_X86 || ARCH_X86_64
 #include "x86/quantize_x86.h"
 #endif
@@ -41,6 +42,7 @@ typedef struct
     prototype_quantize_block(*fastquantb);
 } vp8_quantize_rtcd_vtable_t;
 
+
 #if CONFIG_RUNTIME_CPU_DETECT
 #define QUANTIZE_INVOKE(ctx,fn) (ctx)->fn
 #else
index 165dada2b2803a07501680ec043228dd92e5ee93..03d42d21552a174c56e3bd197be2b66d9043620a 100644 (file)
@@ -15,7 +15,6 @@
 # encoder
 VP8_CX_SRCS-$(ARCH_ARM)  += encoder/arm/arm_csystemdependent.c
 
-VP8_CX_SRCS-$(HAVE_ARMV7)  += encoder/arm/quantize_arm.c
 VP8_CX_SRCS-$(HAVE_ARMV7)  += encoder/arm/picklpf_arm.c
 VP8_CX_SRCS-$(HAVE_ARMV6)  += encoder/arm/dct_arm.c
 VP8_CX_SRCS-$(HAVE_ARMV6)  += encoder/arm/variance_arm.c