Home | History | Annotate | Download | only in vpx_dsp
      1 /*
      2  *  Copyright (c) 2015 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 #include "./vpx_dsp_rtcd.h"
     12 #include "vpx_dsp/quantize.h"
     13 #include "vpx_mem/vpx_mem.h"
     14 
     15 void vpx_quantize_dc(const tran_low_t *coeff_ptr, int n_coeffs, int skip_block,
     16                      const int16_t *round_ptr, const int16_t quant,
     17                      tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
     18                      const int16_t dequant_ptr, uint16_t *eob_ptr) {
     19   const int rc = 0;
     20   const int coeff = coeff_ptr[rc];
     21   const int coeff_sign = (coeff >> 31);
     22   const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
     23   int tmp, eob = -1;
     24 
     25   memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
     26   memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
     27 
     28   if (!skip_block) {
     29     tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX);
     30     tmp = (tmp * quant) >> 16;
     31     qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
     32     dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr;
     33     if (tmp) eob = 0;
     34   }
     35   *eob_ptr = eob + 1;
     36 }
     37 
     38 #if CONFIG_VP9_HIGHBITDEPTH
     39 void vpx_highbd_quantize_dc(const tran_low_t *coeff_ptr, int n_coeffs,
     40                             int skip_block, const int16_t *round_ptr,
     41                             const int16_t quant, tran_low_t *qcoeff_ptr,
     42                             tran_low_t *dqcoeff_ptr, const int16_t dequant_ptr,
     43                             uint16_t *eob_ptr) {
     44   int eob = -1;
     45 
     46   memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
     47   memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
     48 
     49   if (!skip_block) {
     50     const int coeff = coeff_ptr[0];
     51     const int coeff_sign = (coeff >> 31);
     52     const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
     53     const int64_t tmp = abs_coeff + round_ptr[0];
     54     const int abs_qcoeff = (int)((tmp * quant) >> 16);
     55     qcoeff_ptr[0] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
     56     dqcoeff_ptr[0] = qcoeff_ptr[0] * dequant_ptr;
     57     if (abs_qcoeff) eob = 0;
     58   }
     59   *eob_ptr = eob + 1;
     60 }
     61 #endif
     62 
     63 void vpx_quantize_dc_32x32(const tran_low_t *coeff_ptr, int skip_block,
     64                            const int16_t *round_ptr, const int16_t quant,
     65                            tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
     66                            const int16_t dequant_ptr, uint16_t *eob_ptr) {
     67   const int n_coeffs = 1024;
     68   const int rc = 0;
     69   const int coeff = coeff_ptr[rc];
     70   const int coeff_sign = (coeff >> 31);
     71   const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
     72   int tmp, eob = -1;
     73 
     74   memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
     75   memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
     76 
     77   if (!skip_block) {
     78     tmp = clamp(abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1),
     79                 INT16_MIN, INT16_MAX);
     80     tmp = (tmp * quant) >> 15;
     81     qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
     82     dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr / 2;
     83     if (tmp) eob = 0;
     84   }
     85   *eob_ptr = eob + 1;
     86 }
     87 
     88 #if CONFIG_VP9_HIGHBITDEPTH
     89 void vpx_highbd_quantize_dc_32x32(const tran_low_t *coeff_ptr, int skip_block,
     90                                   const int16_t *round_ptr, const int16_t quant,
     91                                   tran_low_t *qcoeff_ptr,
     92                                   tran_low_t *dqcoeff_ptr,
     93                                   const int16_t dequant_ptr,
     94                                   uint16_t *eob_ptr) {
     95   const int n_coeffs = 1024;
     96   int eob = -1;
     97 
     98   memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
     99   memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
    100 
    101   if (!skip_block) {
    102     const int coeff = coeff_ptr[0];
    103     const int coeff_sign = (coeff >> 31);
    104     const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
    105     const int64_t tmp = abs_coeff + ROUND_POWER_OF_TWO(round_ptr[0], 1);
    106     const int abs_qcoeff = (int)((tmp * quant) >> 15);
    107     qcoeff_ptr[0] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
    108     dqcoeff_ptr[0] = qcoeff_ptr[0] * dequant_ptr / 2;
    109     if (abs_qcoeff) eob = 0;
    110   }
    111   *eob_ptr = eob + 1;
    112 }
    113 #endif
    114 
    115 void vpx_quantize_b_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
    116                       int skip_block, const int16_t *zbin_ptr,
    117                       const int16_t *round_ptr, const int16_t *quant_ptr,
    118                       const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
    119                       tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr,
    120                       uint16_t *eob_ptr, const int16_t *scan,
    121                       const int16_t *iscan) {
    122   int i, non_zero_count = (int)n_coeffs, eob = -1;
    123   const int zbins[2] = { zbin_ptr[0], zbin_ptr[1] };
    124   const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
    125   (void)iscan;
    126 
    127   memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
    128   memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
    129 
    130   if (!skip_block) {
    131     // Pre-scan pass
    132     for (i = (int)n_coeffs - 1; i >= 0; i--) {
    133       const int rc = scan[i];
    134       const int coeff = coeff_ptr[rc];
    135 
    136       if (coeff < zbins[rc != 0] && coeff > nzbins[rc != 0])
    137         non_zero_count--;
    138       else
    139         break;
    140     }
    141 
    142     // Quantization pass: All coefficients with index >= zero_flag are
    143     // skippable. Note: zero_flag can be zero.
    144     for (i = 0; i < non_zero_count; i++) {
    145       const int rc = scan[i];
    146       const int coeff = coeff_ptr[rc];
    147       const int coeff_sign = (coeff >> 31);
    148       const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
    149 
    150       if (abs_coeff >= zbins[rc != 0]) {
    151         int tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX);
    152         tmp = ((((tmp * quant_ptr[rc != 0]) >> 16) + tmp) *
    153                quant_shift_ptr[rc != 0]) >>
    154               16;  // quantization
    155         qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
    156         dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0];
    157 
    158         if (tmp) eob = i;
    159       }
    160     }
    161   }
    162   *eob_ptr = eob + 1;
    163 }
    164 
    165 #if CONFIG_VP9_HIGHBITDEPTH
    166 void vpx_highbd_quantize_b_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
    167                              int skip_block, const int16_t *zbin_ptr,
    168                              const int16_t *round_ptr, const int16_t *quant_ptr,
    169                              const int16_t *quant_shift_ptr,
    170                              tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
    171                              const int16_t *dequant_ptr, uint16_t *eob_ptr,
    172                              const int16_t *scan, const int16_t *iscan) {
    173   int i, non_zero_count = (int)n_coeffs, eob = -1;
    174   const int zbins[2] = { zbin_ptr[0], zbin_ptr[1] };
    175   const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
    176   (void)iscan;
    177 
    178   memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
    179   memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
    180 
    181   if (!skip_block) {
    182     // Pre-scan pass
    183     for (i = (int)n_coeffs - 1; i >= 0; i--) {
    184       const int rc = scan[i];
    185       const int coeff = coeff_ptr[rc];
    186 
    187       if (coeff < zbins[rc != 0] && coeff > nzbins[rc != 0])
    188         non_zero_count--;
    189       else
    190         break;
    191     }
    192 
    193     // Quantization pass: All coefficients with index >= zero_flag are
    194     // skippable. Note: zero_flag can be zero.
    195     for (i = 0; i < non_zero_count; i++) {
    196       const int rc = scan[i];
    197       const int coeff = coeff_ptr[rc];
    198       const int coeff_sign = (coeff >> 31);
    199       const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
    200 
    201       if (abs_coeff >= zbins[rc != 0]) {
    202         const int64_t tmp1 = abs_coeff + round_ptr[rc != 0];
    203         const int64_t tmp2 = ((tmp1 * quant_ptr[rc != 0]) >> 16) + tmp1;
    204         const uint32_t abs_qcoeff =
    205             (uint32_t)((tmp2 * quant_shift_ptr[rc != 0]) >> 16);
    206         qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
    207         dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0];
    208         if (abs_qcoeff) eob = i;
    209       }
    210     }
    211   }
    212   *eob_ptr = eob + 1;
    213 }
    214 #endif
    215 
    216 void vpx_quantize_b_32x32_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
    217                             int skip_block, const int16_t *zbin_ptr,
    218                             const int16_t *round_ptr, const int16_t *quant_ptr,
    219                             const int16_t *quant_shift_ptr,
    220                             tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
    221                             const int16_t *dequant_ptr, uint16_t *eob_ptr,
    222                             const int16_t *scan, const int16_t *iscan) {
    223   const int zbins[2] = { ROUND_POWER_OF_TWO(zbin_ptr[0], 1),
    224                          ROUND_POWER_OF_TWO(zbin_ptr[1], 1) };
    225   const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
    226 
    227   int idx = 0;
    228   int idx_arr[1024];
    229   int i, eob = -1;
    230   (void)iscan;
    231 
    232   memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
    233   memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
    234 
    235   if (!skip_block) {
    236     // Pre-scan pass
    237     for (i = 0; i < n_coeffs; i++) {
    238       const int rc = scan[i];
    239       const int coeff = coeff_ptr[rc];
    240 
    241       // If the coefficient is out of the base ZBIN range, keep it for
    242       // quantization.
    243       if (coeff >= zbins[rc != 0] || coeff <= nzbins[rc != 0])
    244         idx_arr[idx++] = i;
    245     }
    246 
    247     // Quantization pass: only process the coefficients selected in
    248     // pre-scan pass. Note: idx can be zero.
    249     for (i = 0; i < idx; i++) {
    250       const int rc = scan[idx_arr[i]];
    251       const int coeff = coeff_ptr[rc];
    252       const int coeff_sign = (coeff >> 31);
    253       int tmp;
    254       int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
    255       abs_coeff += ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1);
    256       abs_coeff = clamp(abs_coeff, INT16_MIN, INT16_MAX);
    257       tmp = ((((abs_coeff * quant_ptr[rc != 0]) >> 16) + abs_coeff) *
    258              quant_shift_ptr[rc != 0]) >>
    259             15;
    260 
    261       qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
    262       dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2;
    263 
    264       if (tmp) eob = idx_arr[i];
    265     }
    266   }
    267   *eob_ptr = eob + 1;
    268 }
    269 
    270 #if CONFIG_VP9_HIGHBITDEPTH
    271 void vpx_highbd_quantize_b_32x32_c(
    272     const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block,
    273     const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr,
    274     const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
    275     tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr,
    276     const int16_t *scan, const int16_t *iscan) {
    277   const int zbins[2] = { ROUND_POWER_OF_TWO(zbin_ptr[0], 1),
    278                          ROUND_POWER_OF_TWO(zbin_ptr[1], 1) };
    279   const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
    280 
    281   int idx = 0;
    282   int idx_arr[1024];
    283   int i, eob = -1;
    284   (void)iscan;
    285 
    286   memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
    287   memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
    288 
    289   if (!skip_block) {
    290     // Pre-scan pass
    291     for (i = 0; i < n_coeffs; i++) {
    292       const int rc = scan[i];
    293       const int coeff = coeff_ptr[rc];
    294 
    295       // If the coefficient is out of the base ZBIN range, keep it for
    296       // quantization.
    297       if (coeff >= zbins[rc != 0] || coeff <= nzbins[rc != 0])
    298         idx_arr[idx++] = i;
    299     }
    300 
    301     // Quantization pass: only process the coefficients selected in
    302     // pre-scan pass. Note: idx can be zero.
    303     for (i = 0; i < idx; i++) {
    304       const int rc = scan[idx_arr[i]];
    305       const int coeff = coeff_ptr[rc];
    306       const int coeff_sign = (coeff >> 31);
    307       const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
    308       const int64_t tmp1 =
    309           abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1);
    310       const int64_t tmp2 = ((tmp1 * quant_ptr[rc != 0]) >> 16) + tmp1;
    311       const uint32_t abs_qcoeff =
    312           (uint32_t)((tmp2 * quant_shift_ptr[rc != 0]) >> 15);
    313       qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
    314       dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2;
    315       if (abs_qcoeff) eob = idx_arr[i];
    316     }
    317   }
    318   *eob_ptr = eob + 1;
    319 }
    320 #endif
    321