tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

av1_quantize.c (46434B)


      1 /*
      2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved.
      3 *
      4 * This source code is subject to the terms of the BSD 2 Clause License and
      5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
      6 * was not distributed with this source code in the LICENSE file, you can
      7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
      8 * Media Patent License 1.0 was not distributed with this source code in the
      9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
     10 */
     11 
     12 #include <math.h>
     13 
     14 #include "config/aom_dsp_rtcd.h"
     15 
     16 #include "aom/aomcx.h"
     17 #include "aom_dsp/quantize.h"
     18 #include "aom_mem/aom_mem.h"
     19 #include "aom_ports/bitops.h"
     20 #include "aom_ports/mem.h"
     21 
     22 #include "av1/common/idct.h"
     23 #include "av1/common/quant_common.h"
     24 #include "av1/common/scan.h"
     25 #include "av1/common/seg_common.h"
     26 
     27 #include "av1/encoder/av1_quantize.h"
     28 #include "av1/encoder/encoder.h"
     29 #include "av1/encoder/rd.h"
     30 
     31 void av1_quantize_skip(intptr_t n_coeffs, tran_low_t *qcoeff_ptr,
     32                       tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr) {
     33  memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
     34  memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
     35  *eob_ptr = 0;
     36 }
     37 
     38 int av1_quantize_fp_no_qmatrix(const int16_t quant_ptr[2],
     39                               const int16_t dequant_ptr[2],
     40                               const int16_t round_ptr[2], int log_scale,
     41                               const int16_t *scan, int coeff_count,
     42                               const tran_low_t *coeff_ptr,
     43                               tran_low_t *qcoeff_ptr,
     44                               tran_low_t *dqcoeff_ptr) {
     45  memset(qcoeff_ptr, 0, coeff_count * sizeof(*qcoeff_ptr));
     46  memset(dqcoeff_ptr, 0, coeff_count * sizeof(*dqcoeff_ptr));
     47  const int rounding[2] = { ROUND_POWER_OF_TWO(round_ptr[0], log_scale),
     48                            ROUND_POWER_OF_TWO(round_ptr[1], log_scale) };
     49  int eob = 0;
     50  for (int i = 0; i < coeff_count; i++) {
     51    const int rc = scan[i];
     52    const int32_t thresh = (int32_t)(dequant_ptr[rc != 0]);
     53    const int coeff = coeff_ptr[rc];
     54    const int coeff_sign = AOMSIGN(coeff);
     55    int64_t abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
     56    int tmp32 = 0;
     57    if ((abs_coeff << (1 + log_scale)) >= thresh) {
     58      abs_coeff = clamp64(abs_coeff + rounding[rc != 0], INT16_MIN, INT16_MAX);
     59      tmp32 = (int)((abs_coeff * quant_ptr[rc != 0]) >> (16 - log_scale));
     60      if (tmp32) {
     61        qcoeff_ptr[rc] = (tmp32 ^ coeff_sign) - coeff_sign;
     62        const tran_low_t abs_dqcoeff =
     63            (tmp32 * dequant_ptr[rc != 0]) >> log_scale;
     64        dqcoeff_ptr[rc] = (abs_dqcoeff ^ coeff_sign) - coeff_sign;
     65      }
     66    }
     67    if (tmp32) eob = i + 1;
     68  }
     69  return eob;
     70 }
     71 
     72 static void quantize_fp_helper_c(
     73    const tran_low_t *coeff_ptr, intptr_t n_coeffs, const int16_t *zbin_ptr,
     74    const int16_t *round_ptr, const int16_t *quant_ptr,
     75    const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
     76    tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr,
     77    const int16_t *scan, const int16_t *iscan, const qm_val_t *qm_ptr,
     78    const qm_val_t *iqm_ptr, int log_scale) {
     79  int i, eob = -1;
     80  const int rounding[2] = { ROUND_POWER_OF_TWO(round_ptr[0], log_scale),
     81                            ROUND_POWER_OF_TWO(round_ptr[1], log_scale) };
     82  // TODO(jingning) Decide the need of these arguments after the
     83  // quantization process is completed.
     84  (void)zbin_ptr;
     85  (void)quant_shift_ptr;
     86  (void)iscan;
     87 
     88  memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
     89  memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
     90 
     91  if (qm_ptr == NULL && iqm_ptr == NULL) {
     92    *eob_ptr = av1_quantize_fp_no_qmatrix(quant_ptr, dequant_ptr, round_ptr,
     93                                          log_scale, scan, (int)n_coeffs,
     94                                          coeff_ptr, qcoeff_ptr, dqcoeff_ptr);
     95  } else {
     96    // Quantization pass: All coefficients with index >= zero_flag are
     97    // skippable. Note: zero_flag can be zero.
     98    for (i = 0; i < n_coeffs; i++) {
     99      const int rc = scan[i];
    100      const int coeff = coeff_ptr[rc];
    101      const qm_val_t wt = qm_ptr ? qm_ptr[rc] : (1 << AOM_QM_BITS);
    102      const qm_val_t iwt = iqm_ptr ? iqm_ptr[rc] : (1 << AOM_QM_BITS);
    103      const int dequant =
    104          (dequant_ptr[rc != 0] * iwt + (1 << (AOM_QM_BITS - 1))) >>
    105          AOM_QM_BITS;
    106      const int coeff_sign = AOMSIGN(coeff);
    107      int64_t abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
    108      int tmp32 = 0;
    109      if (abs_coeff * wt >=
    110          (dequant_ptr[rc != 0] << (AOM_QM_BITS - (1 + log_scale)))) {
    111        abs_coeff += rounding[rc != 0];
    112        abs_coeff = clamp64(abs_coeff, INT16_MIN, INT16_MAX);
    113        tmp32 = (int)((abs_coeff * wt * quant_ptr[rc != 0]) >>
    114                      (16 - log_scale + AOM_QM_BITS));
    115        qcoeff_ptr[rc] = (tmp32 ^ coeff_sign) - coeff_sign;
    116        const tran_low_t abs_dqcoeff = (tmp32 * dequant) >> log_scale;
    117        dqcoeff_ptr[rc] = (abs_dqcoeff ^ coeff_sign) - coeff_sign;
    118      }
    119 
    120      if (tmp32) eob = i;
    121    }
    122    *eob_ptr = eob + 1;
    123  }
    124 }
    125 
    126 #if CONFIG_AV1_HIGHBITDEPTH
    127 static void highbd_quantize_fp_helper_c(
    128    const tran_low_t *coeff_ptr, intptr_t count, const int16_t *zbin_ptr,
    129    const int16_t *round_ptr, const int16_t *quant_ptr,
    130    const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
    131    tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr,
    132    const int16_t *scan, const int16_t *iscan, const qm_val_t *qm_ptr,
    133    const qm_val_t *iqm_ptr, int log_scale) {
    134  int i;
    135  int eob = -1;
    136  const int shift = 16 - log_scale;
    137  // TODO(jingning) Decide the need of these arguments after the
    138  // quantization process is completed.
    139  (void)zbin_ptr;
    140  (void)quant_shift_ptr;
    141  (void)iscan;
    142 
    143  if (qm_ptr || iqm_ptr) {
    144    // Quantization pass: All coefficients with index >= zero_flag are
    145    // skippable. Note: zero_flag can be zero.
    146    for (i = 0; i < count; i++) {
    147      const int rc = scan[i];
    148      const int coeff = coeff_ptr[rc];
    149      const qm_val_t wt = qm_ptr != NULL ? qm_ptr[rc] : (1 << AOM_QM_BITS);
    150      const qm_val_t iwt = iqm_ptr != NULL ? iqm_ptr[rc] : (1 << AOM_QM_BITS);
    151      const int dequant =
    152          (dequant_ptr[rc != 0] * iwt + (1 << (AOM_QM_BITS - 1))) >>
    153          AOM_QM_BITS;
    154      const int coeff_sign = AOMSIGN(coeff);
    155      const int64_t abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
    156      int abs_qcoeff = 0;
    157      if (abs_coeff * wt >=
    158          (dequant_ptr[rc != 0] << (AOM_QM_BITS - (1 + log_scale)))) {
    159        const int64_t tmp =
    160            abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], log_scale);
    161        abs_qcoeff =
    162            (int)((tmp * quant_ptr[rc != 0] * wt) >> (shift + AOM_QM_BITS));
    163        qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
    164        const tran_low_t abs_dqcoeff = (abs_qcoeff * dequant) >> log_scale;
    165        dqcoeff_ptr[rc] = (tran_low_t)((abs_dqcoeff ^ coeff_sign) - coeff_sign);
    166        if (abs_qcoeff) eob = i;
    167      } else {
    168        qcoeff_ptr[rc] = 0;
    169        dqcoeff_ptr[rc] = 0;
    170      }
    171    }
    172  } else {
    173    const int log_scaled_round_arr[2] = {
    174      ROUND_POWER_OF_TWO(round_ptr[0], log_scale),
    175      ROUND_POWER_OF_TWO(round_ptr[1], log_scale),
    176    };
    177    for (i = 0; i < count; i++) {
    178      const int rc = scan[i];
    179      const int coeff = coeff_ptr[rc];
    180      const int rc01 = (rc != 0);
    181      const int coeff_sign = AOMSIGN(coeff);
    182      const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
    183      const int log_scaled_round = log_scaled_round_arr[rc01];
    184      if ((abs_coeff << (1 + log_scale)) >= dequant_ptr[rc01]) {
    185        const int quant = quant_ptr[rc01];
    186        const int dequant = dequant_ptr[rc01];
    187        const int64_t tmp = (int64_t)abs_coeff + log_scaled_round;
    188        const int abs_qcoeff = (int)((tmp * quant) >> shift);
    189        qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
    190        const tran_low_t abs_dqcoeff = (abs_qcoeff * dequant) >> log_scale;
    191        if (abs_qcoeff) eob = i;
    192        dqcoeff_ptr[rc] = (tran_low_t)((abs_dqcoeff ^ coeff_sign) - coeff_sign);
    193      } else {
    194        qcoeff_ptr[rc] = 0;
    195        dqcoeff_ptr[rc] = 0;
    196      }
    197    }
    198  }
    199  *eob_ptr = eob + 1;
    200 }
    201 #endif  // CONFIG_AV1_HIGHBITDEPTH
    202 
    203 void av1_quantize_fp_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
    204                       const int16_t *zbin_ptr, const int16_t *round_ptr,
    205                       const int16_t *quant_ptr, const int16_t *quant_shift_ptr,
    206                       tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
    207                       const int16_t *dequant_ptr, uint16_t *eob_ptr,
    208                       const int16_t *scan, const int16_t *iscan) {
    209  quantize_fp_helper_c(coeff_ptr, n_coeffs, zbin_ptr, round_ptr, quant_ptr,
    210                       quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr, dequant_ptr,
    211                       eob_ptr, scan, iscan, NULL, NULL, 0);
    212 }
    213 
    214 void av1_quantize_lp_c(const int16_t *coeff_ptr, intptr_t n_coeffs,
    215                       const int16_t *round_ptr, const int16_t *quant_ptr,
    216                       int16_t *qcoeff_ptr, int16_t *dqcoeff_ptr,
    217                       const int16_t *dequant_ptr, uint16_t *eob_ptr,
    218                       const int16_t *scan, const int16_t *iscan) {
    219  (void)iscan;
    220  int eob = -1;
    221 
    222  memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
    223  memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
    224 
    225  // Quantization pass: All coefficients with index >= zero_flag are
    226  // skippable. Note: zero_flag can be zero.
    227  for (int i = 0; i < n_coeffs; i++) {
    228    const int rc = scan[i];
    229    const int coeff = coeff_ptr[rc];
    230    const int coeff_sign = AOMSIGN(coeff);
    231    const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
    232 
    233    int tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX);
    234    tmp = (tmp * quant_ptr[rc != 0]) >> 16;
    235 
    236    qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
    237    dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0];
    238 
    239    if (tmp) eob = i;
    240  }
    241  *eob_ptr = eob + 1;
    242 }
    243 
    244 void av1_quantize_fp_32x32_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
    245                             const int16_t *zbin_ptr, const int16_t *round_ptr,
    246                             const int16_t *quant_ptr,
    247                             const int16_t *quant_shift_ptr,
    248                             tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
    249                             const int16_t *dequant_ptr, uint16_t *eob_ptr,
    250                             const int16_t *scan, const int16_t *iscan) {
    251  quantize_fp_helper_c(coeff_ptr, n_coeffs, zbin_ptr, round_ptr, quant_ptr,
    252                       quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr, dequant_ptr,
    253                       eob_ptr, scan, iscan, NULL, NULL, 1);
    254 }
    255 
    256 void av1_quantize_fp_64x64_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
    257                             const int16_t *zbin_ptr, const int16_t *round_ptr,
    258                             const int16_t *quant_ptr,
    259                             const int16_t *quant_shift_ptr,
    260                             tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
    261                             const int16_t *dequant_ptr, uint16_t *eob_ptr,
    262                             const int16_t *scan, const int16_t *iscan) {
    263  quantize_fp_helper_c(coeff_ptr, n_coeffs, zbin_ptr, round_ptr, quant_ptr,
    264                       quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr, dequant_ptr,
    265                       eob_ptr, scan, iscan, NULL, NULL, 2);
    266 }
    267 
    268 void av1_quantize_fp_facade(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
    269                            const MACROBLOCK_PLANE *p, tran_low_t *qcoeff_ptr,
    270                            tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
    271                            const SCAN_ORDER *sc, const QUANT_PARAM *qparam) {
    272  const qm_val_t *qm_ptr = qparam->qmatrix;
    273  const qm_val_t *iqm_ptr = qparam->iqmatrix;
    274  if (qm_ptr != NULL && iqm_ptr != NULL) {
    275    quantize_fp_helper_c(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_fp_QTX,
    276                         p->quant_fp_QTX, p->quant_shift_QTX, qcoeff_ptr,
    277                         dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan,
    278                         sc->iscan, qm_ptr, iqm_ptr, qparam->log_scale);
    279  } else {
    280    switch (qparam->log_scale) {
    281      case 0:
    282        av1_quantize_fp(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_fp_QTX,
    283                        p->quant_fp_QTX, p->quant_shift_QTX, qcoeff_ptr,
    284                        dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan,
    285                        sc->iscan);
    286        break;
    287      case 1:
    288        av1_quantize_fp_32x32(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_fp_QTX,
    289                              p->quant_fp_QTX, p->quant_shift_QTX, qcoeff_ptr,
    290                              dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan,
    291                              sc->iscan);
    292        break;
    293      case 2:
    294        av1_quantize_fp_64x64(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_fp_QTX,
    295                              p->quant_fp_QTX, p->quant_shift_QTX, qcoeff_ptr,
    296                              dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan,
    297                              sc->iscan);
    298        break;
    299      default: assert(0);
    300    }
    301  }
    302 }
    303 
    304 void av1_quantize_b_facade(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
    305                           const MACROBLOCK_PLANE *p, tran_low_t *qcoeff_ptr,
    306                           tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
    307                           const SCAN_ORDER *sc, const QUANT_PARAM *qparam) {
    308  const qm_val_t *qm_ptr = qparam->qmatrix;
    309  const qm_val_t *iqm_ptr = qparam->iqmatrix;
    310 #if !CONFIG_REALTIME_ONLY
    311  if (qparam->use_quant_b_adapt) {
    312    // TODO(sarahparker) These quantize_b optimizations need SIMD
    313    // implementations
    314    if (qm_ptr != NULL && iqm_ptr != NULL) {
    315      aom_quantize_b_adaptive_helper_c(
    316          coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
    317          p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, eob_ptr,
    318          sc->scan, sc->iscan, qm_ptr, iqm_ptr, qparam->log_scale);
    319    } else {
    320      switch (qparam->log_scale) {
    321        case 0:
    322          aom_quantize_b_adaptive(coeff_ptr, n_coeffs, p->zbin_QTX,
    323                                  p->round_QTX, p->quant_QTX,
    324                                  p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr,
    325                                  p->dequant_QTX, eob_ptr, sc->scan, sc->iscan);
    326          break;
    327        case 1:
    328          aom_quantize_b_32x32_adaptive(
    329              coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
    330              p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX,
    331              eob_ptr, sc->scan, sc->iscan);
    332          break;
    333        case 2:
    334          aom_quantize_b_64x64_adaptive(
    335              coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
    336              p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX,
    337              eob_ptr, sc->scan, sc->iscan);
    338          break;
    339        default: assert(0);
    340      }
    341    }
    342    return;
    343  }
    344 #endif  // !CONFIG_REALTIME_ONLY
    345 
    346  if (qm_ptr != NULL && iqm_ptr != NULL) {
    347    aom_quantize_b_helper_c(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX,
    348                            p->quant_QTX, p->quant_shift_QTX, qcoeff_ptr,
    349                            dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan,
    350                            sc->iscan, qm_ptr, iqm_ptr, qparam->log_scale);
    351  } else {
    352    switch (qparam->log_scale) {
    353      case 0:
    354        aom_quantize_b(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX,
    355                       p->quant_QTX, p->quant_shift_QTX, qcoeff_ptr,
    356                       dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan,
    357                       sc->iscan);
    358        break;
    359      case 1:
    360        aom_quantize_b_32x32(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX,
    361                             p->quant_QTX, p->quant_shift_QTX, qcoeff_ptr,
    362                             dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan,
    363                             sc->iscan);
    364        break;
    365      case 2:
    366        aom_quantize_b_64x64(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX,
    367                             p->quant_QTX, p->quant_shift_QTX, qcoeff_ptr,
    368                             dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan,
    369                             sc->iscan);
    370        break;
    371      default: assert(0);
    372    }
    373  }
    374 }
    375 
    376 static void quantize_dc(const tran_low_t *coeff_ptr, int n_coeffs,
    377                        int skip_block, const int16_t *round_ptr,
    378                        const int16_t quant, tran_low_t *qcoeff_ptr,
    379                        tran_low_t *dqcoeff_ptr, const int16_t dequant_ptr,
    380                        uint16_t *eob_ptr, const qm_val_t *qm_ptr,
    381                        const qm_val_t *iqm_ptr, const int log_scale) {
    382  const int rc = 0;
    383  const int coeff = coeff_ptr[rc];
    384  const int coeff_sign = AOMSIGN(coeff);
    385  const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
    386  int64_t tmp;
    387  int eob = -1;
    388  int32_t tmp32;
    389  int dequant;
    390 
    391  memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
    392  memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
    393 
    394  if (!skip_block) {
    395    const int wt = qm_ptr != NULL ? qm_ptr[rc] : (1 << AOM_QM_BITS);
    396    const int iwt = iqm_ptr != NULL ? iqm_ptr[rc] : (1 << AOM_QM_BITS);
    397    tmp = clamp(abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], log_scale),
    398                INT16_MIN, INT16_MAX);
    399    tmp32 = (int32_t)((tmp * wt * quant) >> (16 - log_scale + AOM_QM_BITS));
    400    qcoeff_ptr[rc] = (tmp32 ^ coeff_sign) - coeff_sign;
    401    dequant = (dequant_ptr * iwt + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS;
    402    const tran_low_t abs_dqcoeff = (tmp32 * dequant) >> log_scale;
    403    dqcoeff_ptr[rc] = (tran_low_t)((abs_dqcoeff ^ coeff_sign) - coeff_sign);
    404    if (tmp32) eob = 0;
    405  }
    406  *eob_ptr = eob + 1;
    407 }
    408 
    409 void av1_quantize_dc_facade(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
    410                            const MACROBLOCK_PLANE *p, tran_low_t *qcoeff_ptr,
    411                            tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
    412                            const SCAN_ORDER *sc, const QUANT_PARAM *qparam) {
    413  // obsolete skip_block
    414  const int skip_block = 0;
    415  (void)sc;
    416  assert(qparam->log_scale >= 0 && qparam->log_scale < (3));
    417  const qm_val_t *qm_ptr = qparam->qmatrix;
    418  const qm_val_t *iqm_ptr = qparam->iqmatrix;
    419  quantize_dc(coeff_ptr, (int)n_coeffs, skip_block, p->round_QTX,
    420              p->quant_fp_QTX[0], qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX[0],
    421              eob_ptr, qm_ptr, iqm_ptr, qparam->log_scale);
    422 }
    423 
    424 #if CONFIG_AV1_HIGHBITDEPTH
    425 void av1_highbd_quantize_fp_facade(const tran_low_t *coeff_ptr,
    426                                   intptr_t n_coeffs, const MACROBLOCK_PLANE *p,
    427                                   tran_low_t *qcoeff_ptr,
    428                                   tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
    429                                   const SCAN_ORDER *sc,
    430                                   const QUANT_PARAM *qparam) {
    431  const qm_val_t *qm_ptr = qparam->qmatrix;
    432  const qm_val_t *iqm_ptr = qparam->iqmatrix;
    433  if (qm_ptr != NULL && iqm_ptr != NULL) {
    434    highbd_quantize_fp_helper_c(
    435        coeff_ptr, n_coeffs, p->zbin_QTX, p->round_fp_QTX, p->quant_fp_QTX,
    436        p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, eob_ptr,
    437        sc->scan, sc->iscan, qm_ptr, iqm_ptr, qparam->log_scale);
    438  } else {
    439    av1_highbd_quantize_fp(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_fp_QTX,
    440                           p->quant_fp_QTX, p->quant_shift_QTX, qcoeff_ptr,
    441                           dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan,
    442                           sc->iscan, qparam->log_scale);
    443  }
    444 }
    445 
    446 void av1_highbd_quantize_b_facade(const tran_low_t *coeff_ptr,
    447                                  intptr_t n_coeffs, const MACROBLOCK_PLANE *p,
    448                                  tran_low_t *qcoeff_ptr,
    449                                  tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
    450                                  const SCAN_ORDER *sc,
    451                                  const QUANT_PARAM *qparam) {
    452  const qm_val_t *qm_ptr = qparam->qmatrix;
    453  const qm_val_t *iqm_ptr = qparam->iqmatrix;
    454 #if !CONFIG_REALTIME_ONLY
    455  if (qparam->use_quant_b_adapt) {
    456    if (qm_ptr != NULL && iqm_ptr != NULL) {
    457      aom_highbd_quantize_b_adaptive_helper_c(
    458          coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
    459          p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, eob_ptr,
    460          sc->scan, sc->iscan, qm_ptr, iqm_ptr, qparam->log_scale);
    461    } else {
    462      switch (qparam->log_scale) {
    463        case 0:
    464          aom_highbd_quantize_b_adaptive(
    465              coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
    466              p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX,
    467              eob_ptr, sc->scan, sc->iscan);
    468          break;
    469        case 1:
    470          aom_highbd_quantize_b_32x32_adaptive(
    471              coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
    472              p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX,
    473              eob_ptr, sc->scan, sc->iscan);
    474          break;
    475        case 2:
    476          aom_highbd_quantize_b_64x64_adaptive(
    477              coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
    478              p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX,
    479              eob_ptr, sc->scan, sc->iscan);
    480          break;
    481        default: assert(0);
    482      }
    483    }
    484    return;
    485  }
    486 #endif  // !CONFIG_REALTIME_ONLY
    487 
    488  if (qm_ptr != NULL && iqm_ptr != NULL) {
    489    aom_highbd_quantize_b_helper_c(
    490        coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
    491        p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, eob_ptr,
    492        sc->scan, sc->iscan, qm_ptr, iqm_ptr, qparam->log_scale);
    493  } else {
    494    switch (qparam->log_scale) {
    495      case 0:
    496        aom_highbd_quantize_b(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX,
    497                              p->quant_QTX, p->quant_shift_QTX, qcoeff_ptr,
    498                              dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan,
    499                              sc->iscan);
    500        break;
    501      case 1:
    502        aom_highbd_quantize_b_32x32(
    503            coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
    504            p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX,
    505            eob_ptr, sc->scan, sc->iscan);
    506        break;
    507      case 2:
    508        aom_highbd_quantize_b_64x64(
    509            coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
    510            p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX,
    511            eob_ptr, sc->scan, sc->iscan);
    512        break;
    513      default: assert(0);
    514    }
    515  }
    516 }
    517 
    518 static inline void highbd_quantize_dc(
    519    const tran_low_t *coeff_ptr, int n_coeffs, int skip_block,
    520    const int16_t *round_ptr, const int16_t quant, tran_low_t *qcoeff_ptr,
    521    tran_low_t *dqcoeff_ptr, const int16_t dequant_ptr, uint16_t *eob_ptr,
    522    const qm_val_t *qm_ptr, const qm_val_t *iqm_ptr, const int log_scale) {
    523  int eob = -1;
    524 
    525  memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
    526  memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
    527 
    528  if (!skip_block) {
    529    const qm_val_t wt = qm_ptr != NULL ? qm_ptr[0] : (1 << AOM_QM_BITS);
    530    const qm_val_t iwt = iqm_ptr != NULL ? iqm_ptr[0] : (1 << AOM_QM_BITS);
    531    const int coeff = coeff_ptr[0];
    532    const int coeff_sign = AOMSIGN(coeff);
    533    const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
    534    const int64_t tmp = abs_coeff + ROUND_POWER_OF_TWO(round_ptr[0], log_scale);
    535    const int64_t tmpw = tmp * wt;
    536    const int abs_qcoeff =
    537        (int)((tmpw * quant) >> (16 - log_scale + AOM_QM_BITS));
    538    qcoeff_ptr[0] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
    539    const int dequant =
    540        (dequant_ptr * iwt + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS;
    541 
    542    const tran_low_t abs_dqcoeff = (abs_qcoeff * dequant) >> log_scale;
    543    dqcoeff_ptr[0] = (tran_low_t)((abs_dqcoeff ^ coeff_sign) - coeff_sign);
    544    if (abs_qcoeff) eob = 0;
    545  }
    546  *eob_ptr = eob + 1;
    547 }
    548 
    549 void av1_highbd_quantize_dc_facade(const tran_low_t *coeff_ptr,
    550                                   intptr_t n_coeffs, const MACROBLOCK_PLANE *p,
    551                                   tran_low_t *qcoeff_ptr,
    552                                   tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
    553                                   const SCAN_ORDER *sc,
    554                                   const QUANT_PARAM *qparam) {
    555  // obsolete skip_block
    556  const int skip_block = 0;
    557  const qm_val_t *qm_ptr = qparam->qmatrix;
    558  const qm_val_t *iqm_ptr = qparam->iqmatrix;
    559  (void)sc;
    560 
    561  highbd_quantize_dc(coeff_ptr, (int)n_coeffs, skip_block, p->round_QTX,
    562                     p->quant_fp_QTX[0], qcoeff_ptr, dqcoeff_ptr,
    563                     p->dequant_QTX[0], eob_ptr, qm_ptr, iqm_ptr,
    564                     qparam->log_scale);
    565 }
    566 
    567 void av1_highbd_quantize_fp_c(const tran_low_t *coeff_ptr, intptr_t count,
    568                              const int16_t *zbin_ptr, const int16_t *round_ptr,
    569                              const int16_t *quant_ptr,
    570                              const int16_t *quant_shift_ptr,
    571                              tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
    572                              const int16_t *dequant_ptr, uint16_t *eob_ptr,
    573                              const int16_t *scan, const int16_t *iscan,
    574                              int log_scale) {
    575  highbd_quantize_fp_helper_c(coeff_ptr, count, zbin_ptr, round_ptr, quant_ptr,
    576                              quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr,
    577                              dequant_ptr, eob_ptr, scan, iscan, NULL, NULL,
    578                              log_scale);
    579 }
    580 #endif  // CONFIG_AV1_HIGHBITDEPTH
    581 
    582 static void invert_quant(int16_t *quant, int16_t *shift, int d) {
    583  uint32_t t;
    584  int l, m;
    585  t = d;
    586  l = get_msb(t);
    587  m = 1 + (1 << (16 + l)) / d;
    588  *quant = (int16_t)(m - (1 << 16));
    589  *shift = 1 << (16 - l);
    590 }
    591 
    592 static int get_qzbin_factor(int q, aom_bit_depth_t bit_depth) {
    593  const int quant = av1_dc_quant_QTX(q, 0, bit_depth);
    594  switch (bit_depth) {
    595    case AOM_BITS_8: return q == 0 ? 64 : (quant < 148 ? 84 : 80);
    596    case AOM_BITS_10: return q == 0 ? 64 : (quant < 592 ? 84 : 80);
    597    case AOM_BITS_12: return q == 0 ? 64 : (quant < 2368 ? 84 : 80);
    598    default:
    599      assert(0 && "bit_depth should be AOM_BITS_8, AOM_BITS_10 or AOM_BITS_12");
    600      return -1;
    601  }
    602 }
    603 
    604 void av1_build_quantizer(aom_bit_depth_t bit_depth, int y_dc_delta_q,
    605                         int u_dc_delta_q, int u_ac_delta_q, int v_dc_delta_q,
    606                         int v_ac_delta_q, QUANTS *const quants,
    607                         Dequants *const deq, int sharpness) {
    608  int i, q, quant_QTX;
    609  const int sharpness_adjustment = 16 * (7 - sharpness) / 7;
    610 
    611  for (q = 0; q < QINDEX_RANGE; q++) {
    612    const int qzbin_factor = get_qzbin_factor(q, bit_depth);
    613    int qrounding_factor = q == 0 ? 64 : 48;
    614 
    615    for (i = 0; i < 2; ++i) {
    616      int qrounding_factor_fp = 64;
    617 
    618      if (sharpness != 0 && q != 0) {
    619        qrounding_factor = 64 - sharpness_adjustment;
    620        qrounding_factor_fp = 64 - sharpness_adjustment;
    621      }
    622 
    623      // y quantizer with TX scale
    624      quant_QTX = i == 0 ? av1_dc_quant_QTX(q, y_dc_delta_q, bit_depth)
    625                         : av1_ac_quant_QTX(q, 0, bit_depth);
    626      invert_quant(&quants->y_quant[q][i], &quants->y_quant_shift[q][i],
    627                   quant_QTX);
    628      quants->y_quant_fp[q][i] = (1 << 16) / quant_QTX;
    629      quants->y_round_fp[q][i] = (qrounding_factor_fp * quant_QTX) >> 7;
    630      quants->y_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant_QTX, 7);
    631      quants->y_round[q][i] = (qrounding_factor * quant_QTX) >> 7;
    632      deq->y_dequant_QTX[q][i] = quant_QTX;
    633 
    634      // u quantizer with TX scale
    635      quant_QTX = i == 0 ? av1_dc_quant_QTX(q, u_dc_delta_q, bit_depth)
    636                         : av1_ac_quant_QTX(q, u_ac_delta_q, bit_depth);
    637      invert_quant(&quants->u_quant[q][i], &quants->u_quant_shift[q][i],
    638                   quant_QTX);
    639      quants->u_quant_fp[q][i] = (1 << 16) / quant_QTX;
    640      quants->u_round_fp[q][i] = (qrounding_factor_fp * quant_QTX) >> 7;
    641      quants->u_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant_QTX, 7);
    642      quants->u_round[q][i] = (qrounding_factor * quant_QTX) >> 7;
    643      deq->u_dequant_QTX[q][i] = quant_QTX;
    644 
    645      // v quantizer with TX scale
    646      quant_QTX = i == 0 ? av1_dc_quant_QTX(q, v_dc_delta_q, bit_depth)
    647                         : av1_ac_quant_QTX(q, v_ac_delta_q, bit_depth);
    648      invert_quant(&quants->v_quant[q][i], &quants->v_quant_shift[q][i],
    649                   quant_QTX);
    650      quants->v_quant_fp[q][i] = (1 << 16) / quant_QTX;
    651      quants->v_round_fp[q][i] = (qrounding_factor_fp * quant_QTX) >> 7;
    652      quants->v_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant_QTX, 7);
    653      quants->v_round[q][i] = (qrounding_factor * quant_QTX) >> 7;
    654      deq->v_dequant_QTX[q][i] = quant_QTX;
    655    }
    656 
    657    for (i = 2; i < 8; i++) {  // 8: SIMD width
    658      quants->y_quant[q][i] = quants->y_quant[q][1];
    659      quants->y_quant_fp[q][i] = quants->y_quant_fp[q][1];
    660      quants->y_round_fp[q][i] = quants->y_round_fp[q][1];
    661      quants->y_quant_shift[q][i] = quants->y_quant_shift[q][1];
    662      quants->y_zbin[q][i] = quants->y_zbin[q][1];
    663      quants->y_round[q][i] = quants->y_round[q][1];
    664      deq->y_dequant_QTX[q][i] = deq->y_dequant_QTX[q][1];
    665 
    666      quants->u_quant[q][i] = quants->u_quant[q][1];
    667      quants->u_quant_fp[q][i] = quants->u_quant_fp[q][1];
    668      quants->u_round_fp[q][i] = quants->u_round_fp[q][1];
    669      quants->u_quant_shift[q][i] = quants->u_quant_shift[q][1];
    670      quants->u_zbin[q][i] = quants->u_zbin[q][1];
    671      quants->u_round[q][i] = quants->u_round[q][1];
    672      deq->u_dequant_QTX[q][i] = deq->u_dequant_QTX[q][1];
    673 
    674      quants->v_quant[q][i] = quants->v_quant[q][1];
    675      quants->v_quant_fp[q][i] = quants->v_quant_fp[q][1];
    676      quants->v_round_fp[q][i] = quants->v_round_fp[q][1];
    677      quants->v_quant_shift[q][i] = quants->v_quant_shift[q][1];
    678      quants->v_zbin[q][i] = quants->v_zbin[q][1];
    679      quants->v_round[q][i] = quants->v_round[q][1];
    680      deq->v_dequant_QTX[q][i] = deq->v_dequant_QTX[q][1];
    681    }
    682  }
    683 }
    684 
    685 static inline bool deltaq_params_have_changed(
    686    const DeltaQuantParams *prev_deltaq_params,
    687    const CommonQuantParams *quant_params) {
    688  return (prev_deltaq_params->y_dc_delta_q != quant_params->y_dc_delta_q ||
    689          prev_deltaq_params->u_dc_delta_q != quant_params->u_dc_delta_q ||
    690          prev_deltaq_params->v_dc_delta_q != quant_params->v_dc_delta_q ||
    691          prev_deltaq_params->u_ac_delta_q != quant_params->u_ac_delta_q ||
    692          prev_deltaq_params->v_ac_delta_q != quant_params->v_ac_delta_q ||
    693          prev_deltaq_params->sharpness != quant_params->sharpness);
    694 }
    695 
    696 void av1_init_quantizer(EncQuantDequantParams *const enc_quant_dequant_params,
    697                        CommonQuantParams *quant_params,
    698                        aom_bit_depth_t bit_depth, int sharpness) {
    699  DeltaQuantParams *const prev_deltaq_params =
    700      &enc_quant_dequant_params->prev_deltaq_params;
    701  quant_params->sharpness = sharpness;
    702 
    703  // Re-initialize the quantizer only if any of the dc/ac deltaq parameters
    704  // change.
    705  if (!deltaq_params_have_changed(prev_deltaq_params, quant_params)) return;
    706  QUANTS *const quants = &enc_quant_dequant_params->quants;
    707  Dequants *const dequants = &enc_quant_dequant_params->dequants;
    708  av1_build_quantizer(bit_depth, quant_params->y_dc_delta_q,
    709                      quant_params->u_dc_delta_q, quant_params->u_ac_delta_q,
    710                      quant_params->v_dc_delta_q, quant_params->v_ac_delta_q,
    711                      quants, dequants, sharpness);
    712 
    713  // Record the state of deltaq parameters.
    714  prev_deltaq_params->y_dc_delta_q = quant_params->y_dc_delta_q;
    715  prev_deltaq_params->u_dc_delta_q = quant_params->u_dc_delta_q;
    716  prev_deltaq_params->v_dc_delta_q = quant_params->v_dc_delta_q;
    717  prev_deltaq_params->u_ac_delta_q = quant_params->u_ac_delta_q;
    718  prev_deltaq_params->v_ac_delta_q = quant_params->v_ac_delta_q;
    719  prev_deltaq_params->sharpness = sharpness;
    720 }
    721 
    722 /*!\brief Update quantize parameters in MACROBLOCK
    723 *
    724 * \param[in]  enc_quant_dequant_params This parameter cached the quantize and
    725 *                                      dequantize parameters for all q
    726 *                                      indices.
    727 * \param[in]  qindex                   Quantize index used for the current
    728 *                                      superblock.
    729 * \param[out] x                        A superblock data structure for
    730 *                                      encoder.
    731 */
    732 static void set_q_index(const EncQuantDequantParams *enc_quant_dequant_params,
    733                        int qindex, MACROBLOCK *x) {
    734  const QUANTS *const quants = &enc_quant_dequant_params->quants;
    735  const Dequants *const dequants = &enc_quant_dequant_params->dequants;
    736  x->qindex = qindex;
    737  x->seg_skip_block =
    738      0;  // TODO(angiebird): Find a proper place to init this variable.
    739 
    740  // Y
    741  x->plane[0].quant_QTX = quants->y_quant[qindex];
    742  x->plane[0].quant_fp_QTX = quants->y_quant_fp[qindex];
    743  x->plane[0].round_fp_QTX = quants->y_round_fp[qindex];
    744  x->plane[0].quant_shift_QTX = quants->y_quant_shift[qindex];
    745  x->plane[0].zbin_QTX = quants->y_zbin[qindex];
    746  x->plane[0].round_QTX = quants->y_round[qindex];
    747  x->plane[0].dequant_QTX = dequants->y_dequant_QTX[qindex];
    748 
    749  // U
    750  x->plane[1].quant_QTX = quants->u_quant[qindex];
    751  x->plane[1].quant_fp_QTX = quants->u_quant_fp[qindex];
    752  x->plane[1].round_fp_QTX = quants->u_round_fp[qindex];
    753  x->plane[1].quant_shift_QTX = quants->u_quant_shift[qindex];
    754  x->plane[1].zbin_QTX = quants->u_zbin[qindex];
    755  x->plane[1].round_QTX = quants->u_round[qindex];
    756  x->plane[1].dequant_QTX = dequants->u_dequant_QTX[qindex];
    757 
    758  // V
    759  x->plane[2].quant_QTX = quants->v_quant[qindex];
    760  x->plane[2].quant_fp_QTX = quants->v_quant_fp[qindex];
    761  x->plane[2].round_fp_QTX = quants->v_round_fp[qindex];
    762  x->plane[2].quant_shift_QTX = quants->v_quant_shift[qindex];
    763  x->plane[2].zbin_QTX = quants->v_zbin[qindex];
    764  x->plane[2].round_QTX = quants->v_round[qindex];
    765  x->plane[2].dequant_QTX = dequants->v_dequant_QTX[qindex];
    766 }
    767 
    768 /*!\brief Update quantize matrix in MACROBLOCKD based on segment id
    769 *
    770 * \param[in]  quant_params  Quantize parameters used by encoder and decoder
    771 * \param[in]  segment_id    Segment id.
    772 * \param[out] xd            A superblock data structure used by encoder and
    773 * decoder.
    774 */
    775 static void set_qmatrix(const CommonQuantParams *quant_params, int segment_id,
    776                        MACROBLOCKD *xd) {
    777  const int use_qmatrix = av1_use_qmatrix(quant_params, xd, segment_id);
    778  const int qmlevel_y =
    779      use_qmatrix ? quant_params->qmatrix_level_y : NUM_QM_LEVELS - 1;
    780  const int qmlevel_u =
    781      use_qmatrix ? quant_params->qmatrix_level_u : NUM_QM_LEVELS - 1;
    782  const int qmlevel_v =
    783      use_qmatrix ? quant_params->qmatrix_level_v : NUM_QM_LEVELS - 1;
    784  const int qmlevel_ls[MAX_MB_PLANE] = { qmlevel_y, qmlevel_u, qmlevel_v };
    785  for (int i = 0; i < MAX_MB_PLANE; ++i) {
    786    const int qmlevel = qmlevel_ls[i];
    787    memcpy(&xd->plane[i].seg_qmatrix[segment_id],
    788           quant_params->gqmatrix[qmlevel][i],
    789           sizeof(quant_params->gqmatrix[qmlevel][i]));
    790    memcpy(&xd->plane[i].seg_iqmatrix[segment_id],
    791           quant_params->giqmatrix[qmlevel][i],
    792           sizeof(quant_params->giqmatrix[qmlevel][i]));
    793  }
    794 }
    795 
    796 void av1_init_plane_quantizers(const AV1_COMP *cpi, MACROBLOCK *x,
    797                               int segment_id, const int do_update) {
    798  const AV1_COMMON *const cm = &cpi->common;
    799  const CommonQuantParams *const quant_params = &cm->quant_params;
    800  const GF_GROUP *const gf_group = &cpi->ppi->gf_group;
    801  const int boost_index = AOMMIN(15, (cpi->ppi->p_rc.gfu_boost / 100));
    802  const int layer_depth = AOMMIN(gf_group->layer_depth[cpi->gf_frame_index], 6);
    803  const FRAME_TYPE frame_type = cm->current_frame.frame_type;
    804  int qindex_rd;
    805 
    806  const int current_qindex =
    807      clamp(cm->delta_q_info.delta_q_present_flag
    808                ? quant_params->base_qindex + x->delta_qindex
    809                : quant_params->base_qindex,
    810            0, QINDEX_RANGE - 1);
    811  const int qindex = av1_get_qindex(&cm->seg, segment_id, current_qindex);
    812 
    813  if (cpi->oxcf.sb_qp_sweep) {
    814    const int current_rd_qindex =
    815        clamp(cm->delta_q_info.delta_q_present_flag
    816                  ? quant_params->base_qindex + x->rdmult_delta_qindex
    817                  : quant_params->base_qindex,
    818              0, QINDEX_RANGE - 1);
    819    qindex_rd = av1_get_qindex(&cm->seg, segment_id, current_rd_qindex);
    820  } else {
    821    qindex_rd = qindex;
    822  }
    823 
    824  const int qindex_rdmult = qindex_rd + quant_params->y_dc_delta_q;
    825  const int rdmult = av1_compute_rd_mult(
    826      qindex_rdmult, cm->seq_params->bit_depth,
    827      cpi->ppi->gf_group.update_type[cpi->gf_frame_index], layer_depth,
    828      boost_index, frame_type, cpi->oxcf.q_cfg.use_fixed_qp_offsets,
    829      is_stat_consumption_stage(cpi), cpi->oxcf.tune_cfg.tuning);
    830 
    831  const int qindex_change = x->qindex != qindex;
    832  if (qindex_change || do_update) {
    833    set_q_index(&cpi->enc_quant_dequant_params, qindex, x);
    834  }
    835 
    836  MACROBLOCKD *const xd = &x->e_mbd;
    837  if ((segment_id != x->prev_segment_id) ||
    838      av1_use_qmatrix(quant_params, xd, segment_id)) {
    839    set_qmatrix(quant_params, segment_id, xd);
    840  }
    841 
    842  x->seg_skip_block = segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP);
    843 
    844  av1_set_error_per_bit(&x->errorperbit, rdmult);
    845  av1_set_sad_per_bit(cpi, &x->sadperbit, qindex_rd);
    846 
    847  x->prev_segment_id = segment_id;
    848 }
    849 
    850 void av1_frame_init_quantizer(AV1_COMP *cpi) {
    851  MACROBLOCK *const x = &cpi->td.mb;
    852  MACROBLOCKD *const xd = &x->e_mbd;
    853  x->prev_segment_id = -1;
    854  av1_init_plane_quantizers(cpi, x, xd->mi[0]->segment_id, 1);
    855 }
    856 
    857 static int adjust_hdr_cb_deltaq(int base_qindex) {
    858  double baseQp = base_qindex / QP_SCALE_FACTOR;
    859  const double chromaQp = CHROMA_QP_SCALE * baseQp + CHROMA_QP_OFFSET;
    860  const double dcbQP = CHROMA_CB_QP_SCALE * chromaQp * QP_SCALE_FACTOR;
    861  int dqpCb = (int)(dcbQP + (dcbQP < 0 ? -0.5 : 0.5));
    862  dqpCb = AOMMIN(0, dqpCb);
    863  dqpCb = (int)CLIP(dqpCb, -12 * QP_SCALE_FACTOR, 12 * QP_SCALE_FACTOR);
    864  return dqpCb;
    865 }
    866 
    867 static int adjust_hdr_cr_deltaq(int base_qindex) {
    868  double baseQp = base_qindex / QP_SCALE_FACTOR;
    869  const double chromaQp = CHROMA_QP_SCALE * baseQp + CHROMA_QP_OFFSET;
    870  const double dcrQP = CHROMA_CR_QP_SCALE * chromaQp * QP_SCALE_FACTOR;
    871  int dqpCr = (int)(dcrQP + (dcrQP < 0 ? -0.5 : 0.5));
    872  dqpCr = AOMMIN(0, dqpCr);
    873  dqpCr = (int)CLIP(dqpCr, -12 * QP_SCALE_FACTOR, 12 * QP_SCALE_FACTOR);
    874  return dqpCr;
    875 }
    876 
    877 void av1_set_quantizer(AV1_COMMON *const cm, int min_qmlevel, int max_qmlevel,
    878                       int q, int enable_chroma_deltaq, int enable_hdr_deltaq,
    879                       bool is_allintra, aom_tune_metric tuning) {
    880  // quantizer has to be reinitialized with av1_init_quantizer() if any
    881  // delta_q changes.
    882  CommonQuantParams *quant_params = &cm->quant_params;
    883  quant_params->base_qindex = AOMMAX(cm->delta_q_info.delta_q_present_flag, q);
    884  quant_params->y_dc_delta_q = 0;
    885 
    886  // Disable deltaq in lossless mode.
    887  if (enable_chroma_deltaq && q) {
    888    if (is_allintra &&
    889        (tuning == AOM_TUNE_IQ || tuning == AOM_TUNE_SSIMULACRA2)) {
    890      int chroma_dc_delta_q = 0;
    891      int chroma_ac_delta_q = 0;
    892 
    893      if (cm->seq_params->subsampling_x == 1 &&
    894          cm->seq_params->subsampling_y == 1) {
    895        // 4:2:0 subsampling: Constant chroma delta_q decrease (i.e. improved
    896        // chroma quality relative to luma) with gradual ramp-down for very low
    897        // qindexes.
    898        // Lowering chroma delta_q by 16 was found to improve SSIMULACRA 2
    899        // BD-Rate by 1.5-2% on Daala's subset1, as well as reducing chroma
    900        // artifacts (smudging, discoloration) during subjective quality
    901        // evaluations.
    902        // The ramp-down of chroma increase was determined by generating the
    903        // convex hull of SSIMULACRA 2 scores (for all boosts from 0-16), and
    904        // finding a linear equation that fits the convex hull.
    905        chroma_dc_delta_q = -clamp((quant_params->base_qindex / 2) - 14, 0, 16);
    906        chroma_ac_delta_q = chroma_dc_delta_q;
    907      } else if (cm->seq_params->subsampling_x == 1 &&
    908                 cm->seq_params->subsampling_y == 0) {
    909        // 4:2:2 subsampling: Constant chroma AC delta_q increase (i.e. improved
    910        // luma quality relative to chroma) with gradual ramp-down for very low
    911        // qindexes.
    912        // SSIMULACRA 2 appears to have some issues correctly scoring 4:2:2
    913        // material. Solely optimizing for maximum scores suggests a chroma AC
    914        // delta_q of 12 is the most efficient. However, visual inspection on
    915        // difficult-to-encode material resulted in chroma quality degrading too
    916        // much relative to luma, and chroma channels ending up being too small
    917        // compared to equivalent 4:4:4 or 4:2:0 encodes.
    918        // A chroma AC delta_q of 6 was selected because encoded chroma channels
    919        // have a much closer size to 4:4:4 and 4:2:0 encodes, and have more
    920        // favorable visual quality characteristics.
    921        // The ramp-down of chroma decrease was put into place to match 4:2:0
    922        // and 4:4:4 behavior. There were no special considerations on
    923        // SSIMULACRA 2 scores.
    924        chroma_dc_delta_q = 0;
    925        chroma_ac_delta_q = clamp((quant_params->base_qindex / 2), 0, 6);
    926      } else if (cm->seq_params->subsampling_x == 0 &&
    927                 cm->seq_params->subsampling_y == 0) {
    928        // 4:4:4 subsampling: Constant chroma AC delta_q increase (i.e. improved
    929        // luma quality relative to chroma) with gradual ramp-down for very low
    930        // qindexes.
    931        // Raising chroma AC delta_q by 24 was found to improve SSIMULACRA 2
    932        // BD-Rate by 2.5-3% on Daala's subset1, as well as providing a more
    933        // balanced bit allocation between the (relatively-starved) luma and
    934        // chroma channels.
    935        // Raising chroma DC delta_q appears to be harmful, both for SSIMULACRA
    936        // 2 scores and subjective quality (harshens blocking artifacts).
    937        // The ramp-down of chroma decrease was put into place so (lossy) QP 0
    938        // encodes still score within 0.1 SSIMULACRA 2 points of the equivalent
    939        // with no chroma delta_q (with a small efficiency improvement), while
    940        // encodes in the SSIMULACRA 2 <=90 range yield full benefits from this
    941        // adjustment.
    942        chroma_dc_delta_q = 0;
    943        chroma_ac_delta_q = clamp((quant_params->base_qindex / 2), 0, 24);
    944      }
    945 
    946      // TODO: bug https://crbug.com/aomedia/375221136 - find chroma_delta_q
    947      // values for 4:2:2 subsampling mode.
    948      quant_params->u_dc_delta_q = chroma_dc_delta_q;
    949      quant_params->u_ac_delta_q = chroma_ac_delta_q;
    950      quant_params->v_dc_delta_q = chroma_dc_delta_q;
    951      quant_params->v_ac_delta_q = chroma_ac_delta_q;
    952    } else {
    953      // TODO(aomedia:2717): need to design better delta
    954      quant_params->u_dc_delta_q = 2;
    955      quant_params->u_ac_delta_q = 2;
    956      quant_params->v_dc_delta_q = 2;
    957      quant_params->v_ac_delta_q = 2;
    958    }
    959  } else {
    960    quant_params->u_dc_delta_q = 0;
    961    quant_params->u_ac_delta_q = 0;
    962    quant_params->v_dc_delta_q = 0;
    963    quant_params->v_ac_delta_q = 0;
    964  }
    965 
    966  // following section 8.3.2 in T-REC-H.Sup15 document
    967  // to apply to AV1 qindex in the range of [0, 255]
    968  if (enable_hdr_deltaq && q) {
    969    int dqpCb = adjust_hdr_cb_deltaq(quant_params->base_qindex);
    970    int dqpCr = adjust_hdr_cr_deltaq(quant_params->base_qindex);
    971    quant_params->u_dc_delta_q = quant_params->u_ac_delta_q = dqpCb;
    972    quant_params->v_dc_delta_q = quant_params->v_ac_delta_q = dqpCr;
    973    if (dqpCb != dqpCr) {
    974      cm->seq_params->separate_uv_delta_q = 1;
    975    }
    976  }
    977 
    978  // Select the best luma and chroma QM formulas based on encoding mode and
    979  // tuning
    980  int (*get_luma_qmlevel)(int, int, int);
    981  int (*get_chroma_qmlevel)(int, int, int);
    982 
    983  if (is_allintra) {
    984    if (tuning == AOM_TUNE_IQ || tuning == AOM_TUNE_SSIMULACRA2) {
    985      if (tuning == AOM_TUNE_SSIMULACRA2) {
    986        // Use luma QM formula specifically tailored for tune SSIMULACRA2
    987        get_luma_qmlevel = aom_get_qmlevel_luma_ssimulacra2;
    988      } else {
    989        get_luma_qmlevel = aom_get_qmlevel_allintra;
    990      }
    991 
    992      if (cm->seq_params->subsampling_x == 0 &&
    993          cm->seq_params->subsampling_y == 0) {
    994        // 4:4:4 subsampling mode has 4x the number of chroma coefficients
    995        // compared to 4:2:0 (2x on each dimension). This means the encoder
    996        // should use lower chroma QM levels that more closely match the scaling
    997        // of an equivalent 4:2:0 chroma QM.
    998        get_chroma_qmlevel = aom_get_qmlevel_444_chroma;
    999      } else {
   1000        // For all other chroma subsampling modes, use the all intra QM formula
   1001        get_chroma_qmlevel = aom_get_qmlevel_allintra;
   1002      }
   1003    } else {
   1004      get_luma_qmlevel = aom_get_qmlevel_allintra;
   1005      get_chroma_qmlevel = aom_get_qmlevel_allintra;
   1006    }
   1007  } else {
   1008    get_luma_qmlevel = aom_get_qmlevel;
   1009    get_chroma_qmlevel = aom_get_qmlevel;
   1010  }
   1011 
   1012  quant_params->qmatrix_level_y =
   1013      get_luma_qmlevel(quant_params->base_qindex, min_qmlevel, max_qmlevel);
   1014  quant_params->qmatrix_level_u =
   1015      get_chroma_qmlevel(quant_params->base_qindex + quant_params->u_ac_delta_q,
   1016                         min_qmlevel, max_qmlevel);
   1017 
   1018  if (cm->seq_params->separate_uv_delta_q) {
   1019    quant_params->qmatrix_level_v = get_chroma_qmlevel(
   1020        quant_params->base_qindex + quant_params->v_ac_delta_q, min_qmlevel,
   1021        max_qmlevel);
   1022  } else {
   1023    quant_params->qmatrix_level_v = quant_params->qmatrix_level_u;
   1024  }
   1025 }
   1026 
   1027 // Table that converts 0-63 Q-range values passed in outside to the Qindex
   1028 // range used internally.
   1029 static const int quantizer_to_qindex[] = {
   1030  0,   4,   8,   12,  16,  20,  24,  28,  32,  36,  40,  44,  48,
   1031  52,  56,  60,  64,  68,  72,  76,  80,  84,  88,  92,  96,  100,
   1032  104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 148, 152,
   1033  156, 160, 164, 168, 172, 176, 180, 184, 188, 192, 196, 200, 204,
   1034  208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 249, 255,
   1035 };
   1036 
   1037 int av1_quantizer_to_qindex(int quantizer) {
   1038  return quantizer_to_qindex[quantizer];
   1039 }
   1040 
   1041 int av1_qindex_to_quantizer(int qindex) {
   1042  int quantizer;
   1043 
   1044  for (quantizer = 0; quantizer < 64; ++quantizer)
   1045    if (quantizer_to_qindex[quantizer] >= qindex) return quantizer;
   1046 
   1047  return 63;
   1048 }