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