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 "entropy.h"
     17 #include "predictdc.h"
     18 
     19 //#define EXACT_QUANT
     20 #ifdef EXACT_QUANT
     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;
     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 void vp8_regular_quantize_b(BLOCK *b, BLOCKD *d)
     68 {
     69     int i, rc, eob;
     70     int zbin;
     71     int x, y, z, sz;
     72     short *zbin_boost_ptr  = b->zrun_zbin_boost;
     73     short *coeff_ptr       = b->coeff;
     74     short *zbin_ptr        = b->zbin;
     75     short *round_ptr       = b->round;
     76     short *quant_ptr       = b->quant;
     77     short *quant_shift_ptr = b->quant_shift;
     78     short *qcoeff_ptr      = d->qcoeff;
     79     short *dqcoeff_ptr     = d->dqcoeff;
     80     short *dequant_ptr     = d->dequant;
     81     short zbin_oq_value    = b->zbin_extra;
     82 
     83     vpx_memset(qcoeff_ptr, 0, 32);
     84     vpx_memset(dqcoeff_ptr, 0, 32);
     85 
     86     eob = -1;
     87 
     88     for (i = 0; i < 16; i++)
     89     {
     90         rc   = vp8_default_zig_zag1d[i];
     91         z    = coeff_ptr[rc];
     92 
     93         //if ( i == 0 )
     94         //    zbin = zbin_ptr[rc] + *zbin_boost_ptr + zbin_oq_value/2;
     95         //else
     96         zbin = zbin_ptr[rc] + *zbin_boost_ptr + zbin_oq_value;
     97 
     98         zbin_boost_ptr ++;
     99         sz = (z >> 31);                                 // sign of z
    100         x  = (z ^ sz) - sz;                             // x = abs(z)
    101 
    102         if (x >= zbin)
    103         {
    104             x += round_ptr[rc];
    105             y  = (((x * quant_ptr[rc]) >> 16) + x)
    106                  >> quant_shift_ptr[rc];                // quantize (x)
    107             x  = (y ^ sz) - sz;                         // get the sign back
    108             qcoeff_ptr[rc]  = x;                         // write to destination
    109             dqcoeff_ptr[rc] = x * dequant_ptr[rc];        // dequantized value
    110 
    111             if (y)
    112             {
    113                 eob = i;                                // last nonzero coeffs
    114                 zbin_boost_ptr = &b->zrun_zbin_boost[0];    // reset zero runlength
    115             }
    116         }
    117     }
    118 
    119     d->eob = eob + 1;
    120 }
    121 
    122 /* Perform regular quantization, with unbiased rounding and no zero bin. */
    123 void vp8_strict_quantize_b(BLOCK *b, BLOCKD *d)
    124 {
    125     int i;
    126     int rc;
    127     int eob;
    128     int x;
    129     int y;
    130     int z;
    131     int sz;
    132     short *coeff_ptr;
    133     short *quant_ptr;
    134     short *quant_shift_ptr;
    135     short *qcoeff_ptr;
    136     short *dqcoeff_ptr;
    137     short *dequant_ptr;
    138 
    139     coeff_ptr       = b->coeff;
    140     quant_ptr       = b->quant;
    141     quant_shift_ptr = b->quant_shift;
    142     qcoeff_ptr      = d->qcoeff;
    143     dqcoeff_ptr     = d->dqcoeff;
    144     dequant_ptr     = d->dequant;
    145     eob = - 1;
    146     vpx_memset(qcoeff_ptr, 0, 32);
    147     vpx_memset(dqcoeff_ptr, 0, 32);
    148     for (i = 0; i < 16; i++)
    149     {
    150         int dq;
    151         int round;
    152 
    153         /*TODO: These arrays should be stored in zig-zag order.*/
    154         rc = vp8_default_zig_zag1d[i];
    155         z = coeff_ptr[rc];
    156         dq = dequant_ptr[rc];
    157         round = dq >> 1;
    158         /* Sign of z. */
    159         sz = -(z < 0);
    160         x = (z + sz) ^ sz;
    161         x += round;
    162         if (x >= dq)
    163         {
    164             /* Quantize x. */
    165             y  = (((x * quant_ptr[rc]) >> 16) + x) >> quant_shift_ptr[rc];
    166             /* Put the sign back. */
    167             x = (y + sz) ^ sz;
    168             /* Save the coefficient and its dequantized value. */
    169             qcoeff_ptr[rc] = x;
    170             dqcoeff_ptr[rc] = x * dq;
    171             /* Remember the last non-zero coefficient. */
    172             if (y)
    173                 eob = i;
    174         }
    175     }
    176 
    177     d->eob = eob + 1;
    178 }
    179 
    180 #else
    181 void vp8_fast_quantize_b_c(BLOCK *b, BLOCKD *d)
    182 {
    183     int i, rc, eob;
    184     int zbin;
    185     int x, y, z, sz;
    186     short *coeff_ptr   = b->coeff;
    187     short *round_ptr   = b->round;
    188     short *quant_ptr   = b->quant;
    189     short *qcoeff_ptr  = d->qcoeff;
    190     short *dqcoeff_ptr = d->dqcoeff;
    191     short *dequant_ptr = d->dequant;
    192 
    193     eob = -1;
    194     for (i = 0; i < 16; i++)
    195     {
    196         rc   = vp8_default_zig_zag1d[i];
    197         z    = coeff_ptr[rc];
    198 
    199         sz = (z >> 31);                                 // sign of z
    200         x  = (z ^ sz) - sz;                             // x = abs(z)
    201 
    202         y  = ((x + round_ptr[rc]) * quant_ptr[rc]) >> 16; // quantize (x)
    203         x  = (y ^ sz) - sz;                         // get the sign back
    204         qcoeff_ptr[rc] = x;                          // write to destination
    205         dqcoeff_ptr[rc] = x * dequant_ptr[rc];        // dequantized value
    206 
    207         if (y)
    208         {
    209             eob = i;                                // last nonzero coeffs
    210         }
    211     }
    212     d->eob = eob + 1;
    213 }
    214 
    215 void vp8_regular_quantize_b(BLOCK *b, BLOCKD *d)
    216 {
    217     int i, rc, eob;
    218     int zbin;
    219     int x, y, z, sz;
    220     short *zbin_boost_ptr = b->zrun_zbin_boost;
    221     short *coeff_ptr      = b->coeff;
    222     short *zbin_ptr       = b->zbin;
    223     short *round_ptr      = b->round;
    224     short *quant_ptr      = b->quant;
    225     short *qcoeff_ptr     = d->qcoeff;
    226     short *dqcoeff_ptr    = d->dqcoeff;
    227     short *dequant_ptr    = d->dequant;
    228     short zbin_oq_value   = b->zbin_extra;
    229 
    230     vpx_memset(qcoeff_ptr, 0, 32);
    231     vpx_memset(dqcoeff_ptr, 0, 32);
    232 
    233     eob = -1;
    234 
    235     for (i = 0; i < 16; i++)
    236     {
    237         rc   = vp8_default_zig_zag1d[i];
    238         z    = coeff_ptr[rc];
    239 
    240         //if ( i == 0 )
    241         //    zbin = zbin_ptr[rc] + *zbin_boost_ptr + zbin_oq_value/2;
    242         //else
    243         zbin = zbin_ptr[rc] + *zbin_boost_ptr + zbin_oq_value;
    244 
    245         zbin_boost_ptr ++;
    246         sz = (z >> 31);                                 // sign of z
    247         x  = (z ^ sz) - sz;                             // x = abs(z)
    248 
    249         if (x >= zbin)
    250         {
    251             y  = ((x + round_ptr[rc]) * quant_ptr[rc]) >> 16; // quantize (x)
    252             x  = (y ^ sz) - sz;                         // get the sign back
    253             qcoeff_ptr[rc]  = x;                         // write to destination
    254             dqcoeff_ptr[rc] = x * dequant_ptr[rc];        // dequantized value
    255 
    256             if (y)
    257             {
    258                 eob = i;                                // last nonzero coeffs
    259                 zbin_boost_ptr = &b->zrun_zbin_boost[0];    // reset zero runlength
    260             }
    261         }
    262     }
    263 
    264     d->eob = eob + 1;
    265 }
    266 
    267 #endif
    268 
    269 void vp8_quantize_mby(MACROBLOCK *x)
    270 {
    271     int i;
    272     int has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED
    273         && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV);
    274 
    275     for (i = 0; i < 16; i++)
    276         x->quantize_b(&x->block[i], &x->e_mbd.block[i]);
    277 
    278     if(has_2nd_order)
    279         x->quantize_b(&x->block[24], &x->e_mbd.block[24]);
    280 }
    281 
    282 void vp8_quantize_mb(MACROBLOCK *x)
    283 {
    284     int i;
    285     int has_2nd_order=(x->e_mbd.mode_info_context->mbmi.mode != B_PRED
    286         && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV);
    287 
    288     for (i = 0; i < 24+has_2nd_order; i++)
    289         x->quantize_b(&x->block[i], &x->e_mbd.block[i]);
    290 }
    291 
    292 
    293 void vp8_quantize_mbuv(MACROBLOCK *x)
    294 {
    295     int i;
    296 
    297     for (i = 16; i < 24; i++)
    298         x->quantize_b(&x->block[i], &x->e_mbd.block[i]);
    299 }
    300