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[0];
     27     short *zbin_ptr   = &b->zbin[0][0];
     28     short *round_ptr  = &b->round[0][0];
     29     short *quant_ptr  = &b->quant[0][0];
     30     short *quant_shift_ptr = &b->quant_shift[0][0];
     31     short *qcoeff_ptr = d->qcoeff;
     32     short *dqcoeff_ptr = d->dqcoeff;
     33     short *dequant_ptr = &d->dequant[0][0];
     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[0];
     73     short *coeff_ptr  = &b->coeff[0];
     74     short *zbin_ptr   = &b->zbin[0][0];
     75     short *round_ptr  = &b->round[0][0];
     76     short *quant_ptr  = &b->quant[0][0];
     77     short *quant_shift_ptr = &b->quant_shift[0][0];
     78     short *qcoeff_ptr = d->qcoeff;
     79     short *dqcoeff_ptr = d->dqcoeff;
     80     short *dequant_ptr = &d->dequant[0][0];
     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 #else
    122 void vp8_fast_quantize_b_c(BLOCK *b, BLOCKD *d)
    123 {
    124     int i, rc, eob;
    125     int zbin;
    126     int x, y, z, sz;
    127     short *coeff_ptr  = &b->coeff[0];
    128     short *zbin_ptr   = &b->zbin[0][0];
    129     short *round_ptr  = &b->round[0][0];
    130     short *quant_ptr  = &b->quant[0][0];
    131     short *qcoeff_ptr = d->qcoeff;
    132     short *dqcoeff_ptr = d->dqcoeff;
    133     short *dequant_ptr = &d->dequant[0][0];
    134 
    135     vpx_memset(qcoeff_ptr, 0, 32);
    136     vpx_memset(dqcoeff_ptr, 0, 32);
    137 
    138     eob = -1;
    139 
    140     for (i = 0; i < 16; i++)
    141     {
    142         rc   = vp8_default_zig_zag1d[i];
    143         z    = coeff_ptr[rc];
    144         zbin = zbin_ptr[rc] ;
    145 
    146         sz = (z >> 31);                                 // sign of z
    147         x  = (z ^ sz) - sz;                             // x = abs(z)
    148 
    149         if (x >= zbin)
    150         {
    151             y  = ((x + round_ptr[rc]) * quant_ptr[rc]) >> 16; // quantize (x)
    152             x  = (y ^ sz) - sz;                         // get the sign back
    153             qcoeff_ptr[rc] = x;                          // write to destination
    154             dqcoeff_ptr[rc] = x * dequant_ptr[rc];        // dequantized value
    155 
    156             if (y)
    157             {
    158                 eob = i;                                // last nonzero coeffs
    159             }
    160         }
    161     }
    162     d->eob = eob + 1;
    163 }
    164 
    165 void vp8_regular_quantize_b(BLOCK *b, BLOCKD *d)
    166 {
    167     int i, rc, eob;
    168     int zbin;
    169     int x, y, z, sz;
    170     short *zbin_boost_ptr = &b->zrun_zbin_boost[0];
    171     short *coeff_ptr  = &b->coeff[0];
    172     short *zbin_ptr   = &b->zbin[0][0];
    173     short *round_ptr  = &b->round[0][0];
    174     short *quant_ptr  = &b->quant[0][0];
    175     short *qcoeff_ptr = d->qcoeff;
    176     short *dqcoeff_ptr = d->dqcoeff;
    177     short *dequant_ptr = &d->dequant[0][0];
    178     short zbin_oq_value = b->zbin_extra;
    179 
    180     vpx_memset(qcoeff_ptr, 0, 32);
    181     vpx_memset(dqcoeff_ptr, 0, 32);
    182 
    183     eob = -1;
    184 
    185     for (i = 0; i < 16; i++)
    186     {
    187         rc   = vp8_default_zig_zag1d[i];
    188         z    = coeff_ptr[rc];
    189 
    190         //if ( i == 0 )
    191         //    zbin = zbin_ptr[rc] + *zbin_boost_ptr + zbin_oq_value/2;
    192         //else
    193         zbin = zbin_ptr[rc] + *zbin_boost_ptr + zbin_oq_value;
    194 
    195         zbin_boost_ptr ++;
    196         sz = (z >> 31);                                 // sign of z
    197         x  = (z ^ sz) - sz;                             // x = abs(z)
    198 
    199         if (x >= zbin)
    200         {
    201             y  = ((x + round_ptr[rc]) * quant_ptr[rc]) >> 16; // quantize (x)
    202             x  = (y ^ sz) - sz;                         // get the sign back
    203             qcoeff_ptr[rc]  = x;                         // write to destination
    204             dqcoeff_ptr[rc] = x * dequant_ptr[rc];        // dequantized value
    205 
    206             if (y)
    207             {
    208                 eob = i;                                // last nonzero coeffs
    209                 zbin_boost_ptr = &b->zrun_zbin_boost[0];    // reset zero runlength
    210             }
    211         }
    212     }
    213 
    214     d->eob = eob + 1;
    215 }
    216 
    217 #endif
    218 
    219 /* Perform regular quantization, with unbiased rounding and no zero bin. */
    220 void vp8_strict_quantize_b(BLOCK *b, BLOCKD *d)
    221 {
    222     int i;
    223     int rc;
    224     int eob;
    225     int x;
    226     int y;
    227     int z;
    228     int sz;
    229     short *coeff_ptr;
    230     short *quant_ptr;
    231     short *quant_shift_ptr;
    232     short *qcoeff_ptr;
    233     short *dqcoeff_ptr;
    234     short *dequant_ptr;
    235 
    236     coeff_ptr = &b->coeff[0];
    237     quant_ptr = &b->quant[0][0];
    238     quant_shift_ptr = &b->quant_shift[0][0];
    239     qcoeff_ptr = d->qcoeff;
    240     dqcoeff_ptr = d->dqcoeff;
    241     dequant_ptr = &d->dequant[0][0];
    242     eob = - 1;
    243     vpx_memset(qcoeff_ptr, 0, 32);
    244     vpx_memset(dqcoeff_ptr, 0, 32);
    245     for (i = 0; i < 16; i++)
    246     {
    247         int dq;
    248         int round;
    249 
    250         /*TODO: These arrays should be stored in zig-zag order.*/
    251         rc = vp8_default_zig_zag1d[i];
    252         z = coeff_ptr[rc];
    253         dq = dequant_ptr[rc];
    254         round = dq >> 1;
    255         /* Sign of z. */
    256         sz = -(z < 0);
    257         x = (z + sz) ^ sz;
    258         x += round;
    259         if (x >= dq)
    260         {
    261             /* Quantize x. */
    262             y  = (((x * quant_ptr[rc]) >> 16) + x) >> quant_shift_ptr[rc];
    263             /* Put the sign back. */
    264             x = (y + sz) ^ sz;
    265             /* Save the coefficient and its dequantized value. */
    266             qcoeff_ptr[rc] = x;
    267             dqcoeff_ptr[rc] = x * dq;
    268             /* Remember the last non-zero coefficient. */
    269             if (y)
    270                 eob = i;
    271         }
    272     }
    273 
    274     d->eob = eob + 1;
    275 }
    276 
    277 void vp8_quantize_mby(MACROBLOCK *x)
    278 {
    279     int i;
    280     int has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED
    281         && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV);
    282 
    283     for (i = 0; i < 16; i++)
    284     {
    285         x->quantize_b(&x->block[i], &x->e_mbd.block[i]);
    286         x->e_mbd.mode_info_context->mbmi.mb_skip_coeff &=
    287             (x->e_mbd.block[i].eob <= has_2nd_order);
    288     }
    289 
    290     if(has_2nd_order)
    291     {
    292         x->quantize_b(&x->block[24], &x->e_mbd.block[24]);
    293         x->e_mbd.mode_info_context->mbmi.mb_skip_coeff &= (!x->e_mbd.block[24].eob);
    294     }
    295 }
    296 
    297 void vp8_quantize_mb(MACROBLOCK *x)
    298 {
    299     int i;
    300     int has_2nd_order=(x->e_mbd.mode_info_context->mbmi.mode != B_PRED
    301         && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV);
    302 
    303     x->e_mbd.mode_info_context->mbmi.mb_skip_coeff = 1;
    304     for (i = 0; i < 24+has_2nd_order; i++)
    305     {
    306         x->quantize_b(&x->block[i], &x->e_mbd.block[i]);
    307         x->e_mbd.mode_info_context->mbmi.mb_skip_coeff &=
    308             (x->e_mbd.block[i].eob <= (has_2nd_order && i<16));
    309     }
    310 }
    311 
    312 
    313 void vp8_quantize_mbuv(MACROBLOCK *x)
    314 {
    315     int i;
    316 
    317     for (i = 16; i < 24; i++)
    318     {
    319         x->quantize_b(&x->block[i], &x->e_mbd.block[i]);
    320         x->e_mbd.mode_info_context->mbmi.mb_skip_coeff &= (!x->e_mbd.block[i].eob);
    321     }
    322 }
    323