Home | History | Annotate | Download | only in encoder
      1 /*
      2  *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 
     12 #include <math.h>
     13 #include "vpx_mem/vpx_mem.h"
     14 
     15 #include "quantize.h"
     16 #include "vp8/common/entropy.h"
     17 
     18 #define EXACT_QUANT
     19 
     20 #ifdef EXACT_FASTQUANT
     21 void vp8_fast_quantize_b_c(BLOCK *b, BLOCKD *d)
     22 {
     23     int i, rc, eob;
     24     int zbin;
     25     int x, y, z, sz;
     26     short *coeff_ptr       = b->coeff;
     27     short *zbin_ptr        = b->zbin;
     28     short *round_ptr       = b->round;
     29     short *quant_ptr       = b->quant_fast;
     30     short *quant_shift_ptr = b->quant_shift;
     31     short *qcoeff_ptr      = d->qcoeff;
     32     short *dqcoeff_ptr     = d->dqcoeff;
     33     short *dequant_ptr     = d->dequant;
     34 
     35     vpx_memset(qcoeff_ptr, 0, 32);
     36     vpx_memset(dqcoeff_ptr, 0, 32);
     37 
     38     eob = -1;
     39 
     40     for (i = 0; i < 16; i++)
     41     {
     42         rc   = vp8_default_zig_zag1d[i];
     43         z    = coeff_ptr[rc];
     44         zbin = zbin_ptr[rc] ;
     45 
     46         sz = (z >> 31);                                 // sign of z
     47         x  = (z ^ sz) - sz;                             // x = abs(z)
     48 
     49         if (x >= zbin)
     50         {
     51             x += round_ptr[rc];
     52             y  = (((x * quant_ptr[rc]) >> 16) + x)
     53                  >> quant_shift_ptr[rc];                // quantize (x)
     54             x  = (y ^ sz) - sz;                         // get the sign back
     55             qcoeff_ptr[rc] = x;                          // write to destination
     56             dqcoeff_ptr[rc] = x * dequant_ptr[rc];        // dequantized value
     57 
     58             if (y)
     59             {
     60                 eob = i;                                // last nonzero coeffs
     61             }
     62         }
     63     }
     64     d->eob = eob + 1;
     65 }
     66 
     67 #else
     68 
     69 void vp8_fast_quantize_b_c(BLOCK *b, BLOCKD *d)
     70 {
     71     int i, rc, eob;
     72     int x, y, z, sz;
     73     short *coeff_ptr   = b->coeff;
     74     short *round_ptr   = b->round;
     75     short *quant_ptr   = b->quant_fast;
     76     short *qcoeff_ptr  = d->qcoeff;
     77     short *dqcoeff_ptr = d->dqcoeff;
     78     short *dequant_ptr = d->dequant;
     79 
     80     eob = -1;
     81     for (i = 0; i < 16; i++)
     82     {
     83         rc   = vp8_default_zig_zag1d[i];
     84         z    = coeff_ptr[rc];
     85 
     86         sz = (z >> 31);                                 // sign of z
     87         x  = (z ^ sz) - sz;                             // x = abs(z)
     88 
     89         y  = ((x + round_ptr[rc]) * quant_ptr[rc]) >> 16; // quantize (x)
     90         x  = (y ^ sz) - sz;                         // get the sign back
     91         qcoeff_ptr[rc] = x;                          // write to destination
     92         dqcoeff_ptr[rc] = x * dequant_ptr[rc];        // dequantized value
     93 
     94         if (y)
     95         {
     96             eob = i;                                // last nonzero coeffs
     97         }
     98     }
     99     d->eob = eob + 1;
    100 }
    101 
    102 #endif
    103 
    104 #ifdef EXACT_QUANT
    105 void vp8_regular_quantize_b(BLOCK *b, BLOCKD *d)
    106 {
    107     int i, rc, eob;
    108     int zbin;
    109     int x, y, z, sz;
    110     short *zbin_boost_ptr  = b->zrun_zbin_boost;
    111     short *coeff_ptr       = b->coeff;
    112     short *zbin_ptr        = b->zbin;
    113     short *round_ptr       = b->round;
    114     short *quant_ptr       = b->quant;
    115     short *quant_shift_ptr = b->quant_shift;
    116     short *qcoeff_ptr      = d->qcoeff;
    117     short *dqcoeff_ptr     = d->dqcoeff;
    118     short *dequant_ptr     = d->dequant;
    119     short zbin_oq_value    = b->zbin_extra;
    120 
    121     vpx_memset(qcoeff_ptr, 0, 32);
    122     vpx_memset(dqcoeff_ptr, 0, 32);
    123 
    124     eob = -1;
    125 
    126     for (i = 0; i < 16; i++)
    127     {
    128         rc   = vp8_default_zig_zag1d[i];
    129         z    = coeff_ptr[rc];
    130 
    131         zbin = zbin_ptr[rc] + *zbin_boost_ptr + zbin_oq_value;
    132 
    133         zbin_boost_ptr ++;
    134         sz = (z >> 31);                                 // sign of z
    135         x  = (z ^ sz) - sz;                             // x = abs(z)
    136 
    137         if (x >= zbin)
    138         {
    139             x += round_ptr[rc];
    140             y  = (((x * quant_ptr[rc]) >> 16) + x)
    141                  >> quant_shift_ptr[rc];                // quantize (x)
    142             x  = (y ^ sz) - sz;                         // get the sign back
    143             qcoeff_ptr[rc]  = x;                        // write to destination
    144             dqcoeff_ptr[rc] = x * dequant_ptr[rc];      // dequantized value
    145 
    146             if (y)
    147             {
    148                 eob = i;                                // last nonzero coeffs
    149                 zbin_boost_ptr = b->zrun_zbin_boost;    // reset zero runlength
    150             }
    151         }
    152     }
    153 
    154     d->eob = eob + 1;
    155 }
    156 
    157 /* Perform regular quantization, with unbiased rounding and no zero bin. */
    158 void vp8_strict_quantize_b(BLOCK *b, BLOCKD *d)
    159 {
    160     int i;
    161     int rc;
    162     int eob;
    163     int x;
    164     int y;
    165     int z;
    166     int sz;
    167     short *coeff_ptr;
    168     short *quant_ptr;
    169     short *quant_shift_ptr;
    170     short *qcoeff_ptr;
    171     short *dqcoeff_ptr;
    172     short *dequant_ptr;
    173 
    174     coeff_ptr       = b->coeff;
    175     quant_ptr       = b->quant;
    176     quant_shift_ptr = b->quant_shift;
    177     qcoeff_ptr      = d->qcoeff;
    178     dqcoeff_ptr     = d->dqcoeff;
    179     dequant_ptr     = d->dequant;
    180     eob = - 1;
    181     vpx_memset(qcoeff_ptr, 0, 32);
    182     vpx_memset(dqcoeff_ptr, 0, 32);
    183     for (i = 0; i < 16; i++)
    184     {
    185         int dq;
    186         int round;
    187 
    188         /*TODO: These arrays should be stored in zig-zag order.*/
    189         rc = vp8_default_zig_zag1d[i];
    190         z = coeff_ptr[rc];
    191         dq = dequant_ptr[rc];
    192         round = dq >> 1;
    193         /* Sign of z. */
    194         sz = -(z < 0);
    195         x = (z + sz) ^ sz;
    196         x += round;
    197         if (x >= dq)
    198         {
    199             /* Quantize x. */
    200             y  = (((x * quant_ptr[rc]) >> 16) + x) >> quant_shift_ptr[rc];
    201             /* Put the sign back. */
    202             x = (y + sz) ^ sz;
    203             /* Save the coefficient and its dequantized value. */
    204             qcoeff_ptr[rc] = x;
    205             dqcoeff_ptr[rc] = x * dq;
    206             /* Remember the last non-zero coefficient. */
    207             if (y)
    208                 eob = i;
    209         }
    210     }
    211 
    212     d->eob = eob + 1;
    213 }
    214 
    215 #else
    216 
    217 void vp8_regular_quantize_b(BLOCK *b, BLOCKD *d)
    218 {
    219     int i, rc, eob;
    220     int zbin;
    221     int x, y, z, sz;
    222     short *zbin_boost_ptr = b->zrun_zbin_boost;
    223     short *coeff_ptr      = b->coeff;
    224     short *zbin_ptr       = b->zbin;
    225     short *round_ptr      = b->round;
    226     short *quant_ptr      = b->quant;
    227     short *qcoeff_ptr     = d->qcoeff;
    228     short *dqcoeff_ptr    = d->dqcoeff;
    229     short *dequant_ptr    = d->dequant;
    230     short zbin_oq_value   = b->zbin_extra;
    231 
    232     vpx_memset(qcoeff_ptr, 0, 32);
    233     vpx_memset(dqcoeff_ptr, 0, 32);
    234 
    235     eob = -1;
    236 
    237     for (i = 0; i < 16; i++)
    238     {
    239         rc   = vp8_default_zig_zag1d[i];
    240         z    = coeff_ptr[rc];
    241 
    242         //if ( i == 0 )
    243         //    zbin = zbin_ptr[rc] + *zbin_boost_ptr + zbin_oq_value/2;
    244         //else
    245         zbin = zbin_ptr[rc] + *zbin_boost_ptr + zbin_oq_value;
    246 
    247         zbin_boost_ptr ++;
    248         sz = (z >> 31);                                 // sign of z
    249         x  = (z ^ sz) - sz;                             // x = abs(z)
    250 
    251         if (x >= zbin)
    252         {
    253             y  = ((x + round_ptr[rc]) * quant_ptr[rc]) >> 16; // quantize (x)
    254             x  = (y ^ sz) - sz;                         // get the sign back
    255             qcoeff_ptr[rc]  = x;                         // write to destination
    256             dqcoeff_ptr[rc] = x * dequant_ptr[rc];        // dequantized value
    257 
    258             if (y)
    259             {
    260                 eob = i;                                // last nonzero coeffs
    261                 zbin_boost_ptr = &b->zrun_zbin_boost[0];    // reset zero runlength
    262             }
    263         }
    264     }
    265 
    266     d->eob = eob + 1;
    267 }
    268 
    269 #endif
    270 
    271 void vp8_quantize_mby(MACROBLOCK *x)
    272 {
    273     int i;
    274     int has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED
    275         && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV);
    276 
    277     for (i = 0; i < 16; i++)
    278         x->quantize_b(&x->block[i], &x->e_mbd.block[i]);
    279 
    280     if(has_2nd_order)
    281         x->quantize_b(&x->block[24], &x->e_mbd.block[24]);
    282 }
    283 
    284 void vp8_quantize_mb(MACROBLOCK *x)
    285 {
    286     int i;
    287     int has_2nd_order=(x->e_mbd.mode_info_context->mbmi.mode != B_PRED
    288         && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV);
    289 
    290     for (i = 0; i < 24+has_2nd_order; i++)
    291         x->quantize_b(&x->block[i], &x->e_mbd.block[i]);
    292 }
    293 
    294 
    295 void vp8_quantize_mbuv(MACROBLOCK *x)
    296 {
    297     int i;
    298 
    299     for (i = 16; i < 24; i++)
    300         x->quantize_b(&x->block[i], &x->e_mbd.block[i]);
    301 }
    302