16fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org/*
26fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
36fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *
46fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *  Use of this source code is governed by a BSD-style license
56fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *  that can be found in the LICENSE file in the root of the source
66fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *  tree. An additional intellectual property rights grant can be found
76fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *  in the file PATENTS.  All contributing project authors may
86fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *  be found in the AUTHORS file in the root of the source tree.
96fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org */
106fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
116fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include <math.h>
12411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org
136fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "vpx_mem/vpx_mem.h"
146fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
156fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "vp9/common/vp9_quant_common.h"
166fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "vp9/common/vp9_seg_common.h"
176fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
18693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com#include "vp9/encoder/vp9_encoder.h"
19411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org#include "vp9/encoder/vp9_quantize.h"
20e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org#include "vp9/encoder/vp9_rd.h"
21411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org
2287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgvoid vp9_quantize_dc(const tran_low_t *coeff_ptr, int skip_block,
2388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org                     const int16_t *round_ptr, const int16_t quant,
2487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                     tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
2588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org                     const int16_t dequant_ptr, uint16_t *eob_ptr) {
2641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  const int rc = 0;
2741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  const int coeff = coeff_ptr[rc];
2841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  const int coeff_sign = (coeff >> 31);
2941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
3041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  int tmp, eob = -1;
3188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
3288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  if (!skip_block) {
3341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX);
3488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    tmp = (tmp * quant) >> 16;
3588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    qcoeff_ptr[rc]  = (tmp ^ coeff_sign) - coeff_sign;
3688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr;
3788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    if (tmp)
3888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org      eob = 0;
3988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  }
4088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  *eob_ptr = eob + 1;
4188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org}
4288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
4387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#if CONFIG_VP9_HIGHBITDEPTH
4487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgvoid vp9_high_quantize_dc(const tran_low_t *coeff_ptr, int skip_block,
4587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                          const int16_t *round_ptr, const int16_t quant,
4687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                          tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
4787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                          const int16_t dequant_ptr, uint16_t *eob_ptr) {
4887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  int eob = -1;
4987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
5087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  if (!skip_block) {
5187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    const int rc = 0;
5287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    const int coeff = coeff_ptr[rc];
5387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    const int coeff_sign = (coeff >> 31);
5487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
5587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
5687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    const int64_t tmp =
5787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        (clamp(abs_coeff + round_ptr[rc != 0], INT32_MIN, INT32_MAX) *
5887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org         quant) >> 16;
5987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    qcoeff_ptr[rc]  = (tmp ^ coeff_sign) - coeff_sign;
6087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr;
6187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    if (tmp)
6287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      eob = 0;
6387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  }
6487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  *eob_ptr = eob + 1;
6587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org}
6687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#endif
6787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
6887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgvoid vp9_quantize_dc_32x32(const tran_low_t *coeff_ptr, int skip_block,
69e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org                           const int16_t *round_ptr, const int16_t quant,
7087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                           tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
71e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org                           const int16_t dequant_ptr, uint16_t *eob_ptr) {
7241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  const int rc = 0;
7341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  const int coeff = coeff_ptr[rc];
7441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  const int coeff_sign = (coeff >> 31);
7541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
7641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  int tmp, eob = -1;
7788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
7888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  if (!skip_block) {
7988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
8041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX);
8188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    tmp = (tmp * quant) >> 15;
8288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    qcoeff_ptr[rc]  = (tmp ^ coeff_sign) - coeff_sign;
8388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr / 2;
8488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    if (tmp)
8588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org      eob = 0;
8688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  }
8788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  *eob_ptr = eob + 1;
8888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org}
8988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
9087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#if CONFIG_VP9_HIGHBITDEPTH
9187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgvoid vp9_high_quantize_dc_32x32(const tran_low_t *coeff_ptr, int skip_block,
9287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                const int16_t *round_ptr, const int16_t quant,
9387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
9487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                const int16_t dequant_ptr, uint16_t *eob_ptr) {
9587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  int eob = -1;
9687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
9787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  if (!skip_block) {
9887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    const int rc = 0;
9987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    const int coeff = coeff_ptr[rc];
10087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    const int coeff_sign = (coeff >> 31);
10187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
10287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
10387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    const int64_t tmp =
10487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        (clamp(abs_coeff + round_ptr[rc != 0], INT32_MIN, INT32_MAX) *
10587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org         quant) >> 15;
10687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    qcoeff_ptr[rc]  = (tmp ^ coeff_sign) - coeff_sign;
10787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr / 2;
10887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    if (tmp)
10987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      eob = 0;
11087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  }
11187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  *eob_ptr = eob + 1;
11287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org}
11387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#endif
11487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
11587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgvoid vp9_quantize_fp_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
116e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org                       int skip_block,
117e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org                       const int16_t *zbin_ptr, const int16_t *round_ptr,
118e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org                       const int16_t *quant_ptr, const int16_t *quant_shift_ptr,
11987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                       tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
120e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org                       const int16_t *dequant_ptr,
121e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org                       int zbin_oq_value, uint16_t *eob_ptr,
122e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org                       const int16_t *scan, const int16_t *iscan) {
123e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org  int i, eob = -1;
124e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org  // TODO(jingning) Decide the need of these arguments after the
125e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org  // quantization process is completed.
126e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org  (void)zbin_ptr;
127e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org  (void)quant_shift_ptr;
128e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org  (void)zbin_oq_value;
129e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org  (void)iscan;
130e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org
13187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  vpx_memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
13287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  vpx_memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
133e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org
134e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org  if (!skip_block) {
135e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org    // Quantization pass: All coefficients with index >= zero_flag are
136e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org    // skippable. Note: zero_flag can be zero.
13787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    for (i = 0; i < n_coeffs; i++) {
138e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      const int rc = scan[i];
139e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      const int coeff = coeff_ptr[rc];
140e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      const int coeff_sign = (coeff >> 31);
141e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
142e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org
143e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      int tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX);
144e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      tmp = (tmp * quant_ptr[rc != 0]) >> 16;
145e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org
146e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
147e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0];
148e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org
149e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      if (tmp)
150e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org        eob = i;
151e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org    }
152e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org  }
153e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org  *eob_ptr = eob + 1;
154e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org}
155e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org
15687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#if CONFIG_VP9_HIGHBITDEPTH
15787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgvoid vp9_high_quantize_fp_c(const tran_low_t *coeff_ptr, intptr_t count,
15887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                            int skip_block, const int16_t *zbin_ptr,
15987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                            const int16_t *round_ptr, const int16_t *quant_ptr,
16087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                            const int16_t *quant_shift_ptr,
16187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                            tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
16287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                            const int16_t *dequant_ptr,
16387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                            int zbin_oq_value, uint16_t *eob_ptr,
16487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                            const int16_t *scan, const int16_t *iscan) {
16587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  int i;
16687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  int eob = -1;
16787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  // TODO(jingning) Decide the need of these arguments after the
16887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  // quantization process is completed.
16987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  (void)zbin_ptr;
17087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  (void)quant_shift_ptr;
17187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  (void)zbin_oq_value;
17287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  (void)iscan;
17387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
17487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  vpx_memset(qcoeff_ptr, 0, count * sizeof(*qcoeff_ptr));
17587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  vpx_memset(dqcoeff_ptr, 0, count * sizeof(*dqcoeff_ptr));
17687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
17787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  if (!skip_block) {
17887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    // Quantization pass: All coefficients with index >= zero_flag are
17987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    // skippable. Note: zero_flag can be zero.
18087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    for (i = 0; i < count; i++) {
18187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      const int rc = scan[i];
18287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      const int coeff = coeff_ptr[rc];
18387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      const int coeff_sign = (coeff >> 31);
18487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
18587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
18687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      const int64_t tmp =
18787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org          (clamp(abs_coeff + round_ptr[rc != 0], INT32_MIN, INT32_MAX) *
18887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org           quant_ptr[rc != 0]) >> 16;
18987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
19087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
19187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0];
19287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
19387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      if (tmp)
19487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        eob = i;
19587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    }
19687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  }
19787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  *eob_ptr = eob + 1;
19887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org}
19987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#endif
20087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
20195aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com// TODO(jingning) Refactor this file and combine functions with similar
20295aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com// operations.
20387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgvoid vp9_quantize_fp_32x32_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
20495aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com                             int skip_block,
20595aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com                             const int16_t *zbin_ptr, const int16_t *round_ptr,
20695aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com                             const int16_t *quant_ptr,
20795aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com                             const int16_t *quant_shift_ptr,
20887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                             tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
20995aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com                             const int16_t *dequant_ptr,
21095aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com                             int zbin_oq_value, uint16_t *eob_ptr,
21195aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com                             const int16_t *scan, const int16_t *iscan) {
21295aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com  int i, eob = -1;
21395aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com  (void)zbin_ptr;
21495aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com  (void)quant_shift_ptr;
21595aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com  (void)zbin_oq_value;
21695aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com  (void)iscan;
21795aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com
21887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  vpx_memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
21987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  vpx_memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
22095aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com
22195aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com  if (!skip_block) {
22295aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com    for (i = 0; i < n_coeffs; i++) {
22395aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com      const int rc = scan[i];
22495aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com      const int coeff = coeff_ptr[rc];
22595aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com      const int coeff_sign = (coeff >> 31);
22695aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com      int tmp = 0;
22795aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com      int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
22895aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com
22995aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com      if (abs_coeff >= (dequant_ptr[rc != 0] >> 2)) {
23095aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com        abs_coeff += ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1);
23195aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com        abs_coeff = clamp(abs_coeff, INT16_MIN, INT16_MAX);
23295aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com        tmp = (abs_coeff * quant_ptr[rc != 0]) >> 15;
23395aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com        qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
23495aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com        dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2;
23595aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com      }
23695aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com
23795aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com      if (tmp)
23895aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com        eob = i;
23995aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com    }
24095aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com  }
24195aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com  *eob_ptr = eob + 1;
24295aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com}
24395aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com
24487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#if CONFIG_VP9_HIGHBITDEPTH
24587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgvoid vp9_high_quantize_fp_32x32_c(const tran_low_t *coeff_ptr,
24687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                  intptr_t n_coeffs, int skip_block,
24787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                  const int16_t *zbin_ptr,
24887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                  const int16_t *round_ptr,
24987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                  const int16_t *quant_ptr,
25087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                  const int16_t *quant_shift_ptr,
25187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                  tran_low_t *qcoeff_ptr,
25287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                  tran_low_t *dqcoeff_ptr,
25387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                  const int16_t *dequant_ptr,
25487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                  int zbin_oq_value, uint16_t *eob_ptr,
25587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                  const int16_t *scan, const int16_t *iscan) {
25687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  int i, eob = -1;
25787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  (void)zbin_ptr;
25887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  (void)quant_shift_ptr;
25987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  (void)zbin_oq_value;
26087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  (void)iscan;
26187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
26287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  vpx_memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
26387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  vpx_memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
26487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
26587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  if (!skip_block) {
26687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    for (i = 0; i < n_coeffs; i++) {
26787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      const int rc = scan[i];
26887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      const int coeff = coeff_ptr[rc];
26987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      const int coeff_sign = (coeff >> 31);
27087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      int64_t tmp = 0;
27187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
27287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
27387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      if (abs_coeff >= (dequant_ptr[rc != 0] >> 2)) {
27487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        tmp = clamp(abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1),
27587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                    INT32_MIN, INT32_MAX);
27687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        tmp = (tmp * quant_ptr[rc != 0]) >> 15;
27787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
27887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2;
27987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      }
28087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
28187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      if (tmp)
28287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        eob = i;
28387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    }
28487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  }
28587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  *eob_ptr = eob + 1;
28687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org}
28787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#endif
28887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
28987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgvoid vp9_quantize_b_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
290ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org                      int skip_block,
291ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org                      const int16_t *zbin_ptr, const int16_t *round_ptr,
292ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org                      const int16_t *quant_ptr, const int16_t *quant_shift_ptr,
29387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                      tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
294ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org                      const int16_t *dequant_ptr,
295ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org                      int zbin_oq_value, uint16_t *eob_ptr,
296ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org                      const int16_t *scan, const int16_t *iscan) {
29787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  int i, non_zero_count = (int)n_coeffs, eob = -1;
298d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  const int zbins[2] = { zbin_ptr[0] + zbin_oq_value,
299d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org                         zbin_ptr[1] + zbin_oq_value };
300d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  const int nzbins[2] = { zbins[0] * -1,
301d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org                          zbins[1] * -1 };
3027765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org  (void)iscan;
3037c1508f4449fe8184aa045737c20ba37e603dd03fgalligan@chromium.org
30487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  vpx_memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
30587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  vpx_memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
3067c1508f4449fe8184aa045737c20ba37e603dd03fgalligan@chromium.org
3077c1508f4449fe8184aa045737c20ba37e603dd03fgalligan@chromium.org  if (!skip_block) {
3087c1508f4449fe8184aa045737c20ba37e603dd03fgalligan@chromium.org    // Pre-scan pass
30987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    for (i = (int)n_coeffs - 1; i >= 0; i--) {
310d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      const int rc = scan[i];
311d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      const int coeff = coeff_ptr[rc];
3127c1508f4449fe8184aa045737c20ba37e603dd03fgalligan@chromium.org
313d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      if (coeff < zbins[rc != 0] && coeff > nzbins[rc != 0])
314d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org        non_zero_count--;
315d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      else
3167c1508f4449fe8184aa045737c20ba37e603dd03fgalligan@chromium.org        break;
3177c1508f4449fe8184aa045737c20ba37e603dd03fgalligan@chromium.org    }
3187c1508f4449fe8184aa045737c20ba37e603dd03fgalligan@chromium.org
3197c1508f4449fe8184aa045737c20ba37e603dd03fgalligan@chromium.org    // Quantization pass: All coefficients with index >= zero_flag are
3207c1508f4449fe8184aa045737c20ba37e603dd03fgalligan@chromium.org    // skippable. Note: zero_flag can be zero.
321d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    for (i = 0; i < non_zero_count; i++) {
322d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      const int rc = scan[i];
323d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      const int coeff = coeff_ptr[rc];
324d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      const int coeff_sign = (coeff >> 31);
325d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
326d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
327d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      if (abs_coeff >= zbins[rc != 0]) {
328d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org        int tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX);
329d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org        tmp = ((((tmp * quant_ptr[rc != 0]) >> 16) + tmp) *
330d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org                  quant_shift_ptr[rc != 0]) >> 16;  // quantization
331d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org        qcoeff_ptr[rc]  = (tmp ^ coeff_sign) - coeff_sign;
332d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org        dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0];
333d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
334d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org        if (tmp)
335d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org          eob = i;
3367c1508f4449fe8184aa045737c20ba37e603dd03fgalligan@chromium.org      }
3377c1508f4449fe8184aa045737c20ba37e603dd03fgalligan@chromium.org    }
3387c1508f4449fe8184aa045737c20ba37e603dd03fgalligan@chromium.org  }
3397c1508f4449fe8184aa045737c20ba37e603dd03fgalligan@chromium.org  *eob_ptr = eob + 1;
3407c1508f4449fe8184aa045737c20ba37e603dd03fgalligan@chromium.org}
3417c1508f4449fe8184aa045737c20ba37e603dd03fgalligan@chromium.org
34287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#if CONFIG_VP9_HIGHBITDEPTH
34387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgvoid vp9_high_quantize_b_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
34487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                           int skip_block, const int16_t *zbin_ptr,
34587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                           const int16_t *round_ptr, const int16_t *quant_ptr,
34687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                           const int16_t *quant_shift_ptr,
34787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                           tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
34887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                           const int16_t *dequant_ptr, int zbin_oq_value,
34987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                           uint16_t *eob_ptr, const int16_t *scan,
35087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                           const int16_t *iscan) {
35187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  int i, non_zero_count = (int)n_coeffs, eob = -1;
35287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  const int zbins[2] = { zbin_ptr[0] + zbin_oq_value,
35387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                         zbin_ptr[1] + zbin_oq_value };
35487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  const int nzbins[2] = { zbins[0] * -1,
35587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                          zbins[1] * -1 };
35687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  (void)iscan;
35787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
35887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  vpx_memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
35987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  vpx_memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
36087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
36187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  if (!skip_block) {
36287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    // Pre-scan pass
36387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    for (i = (int)n_coeffs - 1; i >= 0; i--) {
36487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      const int rc = scan[i];
36587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      const int coeff = coeff_ptr[rc];
36687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
36787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      if (coeff < zbins[rc != 0] && coeff > nzbins[rc != 0])
36887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        non_zero_count--;
36987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      else
37087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        break;
37187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    }
37287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
37387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    // Quantization pass: All coefficients with index >= zero_flag are
37487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    // skippable. Note: zero_flag can be zero.
37587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    for (i = 0; i < non_zero_count; i++) {
37687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      const int rc = scan[i];
37787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      const int coeff = coeff_ptr[rc];
37887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      const int coeff_sign = (coeff >> 31);
37987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
38087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
38187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      if (abs_coeff >= zbins[rc != 0]) {
38287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        int64_t tmp = clamp(abs_coeff + round_ptr[rc != 0],
38387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                            INT32_MIN, INT32_MAX);
38487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        tmp = ((((tmp * quant_ptr[rc != 0]) >> 16) + tmp) *
38587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                  quant_shift_ptr[rc != 0]) >> 16;  // quantization
38687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        qcoeff_ptr[rc]  = (tmp ^ coeff_sign) - coeff_sign;
38787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0];
38887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
38987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        if (tmp)
39087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org          eob = i;
39187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      }
39287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    }
39387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  }
39487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  *eob_ptr = eob + 1;
39587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org}
39687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#endif
39787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
39887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgvoid vp9_quantize_b_32x32_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
39947265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org                            int skip_block,
400ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org                            const int16_t *zbin_ptr, const int16_t *round_ptr,
401ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org                            const int16_t *quant_ptr,
402ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org                            const int16_t *quant_shift_ptr,
40387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                            tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
404ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org                            const int16_t *dequant_ptr,
405ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org                            int zbin_oq_value, uint16_t *eob_ptr,
406ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org                            const int16_t *scan, const int16_t *iscan) {
40776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  const int zbins[2] = { ROUND_POWER_OF_TWO(zbin_ptr[0] + zbin_oq_value, 1),
40876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org                         ROUND_POWER_OF_TWO(zbin_ptr[1] + zbin_oq_value, 1) };
40976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  const int nzbins[2] = {zbins[0] * -1, zbins[1] * -1};
41076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
4117c1508f4449fe8184aa045737c20ba37e603dd03fgalligan@chromium.org  int idx = 0;
41247265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  int idx_arr[1024];
41376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  int i, eob = -1;
4147765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org  (void)iscan;
4157c1508f4449fe8184aa045737c20ba37e603dd03fgalligan@chromium.org
41687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  vpx_memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
41787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  vpx_memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
4187c1508f4449fe8184aa045737c20ba37e603dd03fgalligan@chromium.org
4197c1508f4449fe8184aa045737c20ba37e603dd03fgalligan@chromium.org  if (!skip_block) {
4207c1508f4449fe8184aa045737c20ba37e603dd03fgalligan@chromium.org    // Pre-scan pass
4217c1508f4449fe8184aa045737c20ba37e603dd03fgalligan@chromium.org    for (i = 0; i < n_coeffs; i++) {
42276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      const int rc = scan[i];
42376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      const int coeff = coeff_ptr[rc];
4247c1508f4449fe8184aa045737c20ba37e603dd03fgalligan@chromium.org
4257c1508f4449fe8184aa045737c20ba37e603dd03fgalligan@chromium.org      // If the coefficient is out of the base ZBIN range, keep it for
4267c1508f4449fe8184aa045737c20ba37e603dd03fgalligan@chromium.org      // quantization.
42776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      if (coeff >= zbins[rc != 0] || coeff <= nzbins[rc != 0])
4287c1508f4449fe8184aa045737c20ba37e603dd03fgalligan@chromium.org        idx_arr[idx++] = i;
4297c1508f4449fe8184aa045737c20ba37e603dd03fgalligan@chromium.org    }
4307c1508f4449fe8184aa045737c20ba37e603dd03fgalligan@chromium.org
4317c1508f4449fe8184aa045737c20ba37e603dd03fgalligan@chromium.org    // Quantization pass: only process the coefficients selected in
4327c1508f4449fe8184aa045737c20ba37e603dd03fgalligan@chromium.org    // pre-scan pass. Note: idx can be zero.
4337c1508f4449fe8184aa045737c20ba37e603dd03fgalligan@chromium.org    for (i = 0; i < idx; i++) {
43476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      const int rc = scan[idx_arr[i]];
43576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      const int coeff = coeff_ptr[rc];
43676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      const int coeff_sign = (coeff >> 31);
43776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      int tmp;
43876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
43976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      abs_coeff += ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1);
44076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      abs_coeff = clamp(abs_coeff, INT16_MIN, INT16_MAX);
44176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      tmp = ((((abs_coeff * quant_ptr[rc != 0]) >> 16) + abs_coeff) *
44276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org               quant_shift_ptr[rc != 0]) >> 15;
44376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
44476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
44576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2;
44676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
44776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      if (tmp)
44876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org        eob = idx_arr[i];
4496fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    }
4506fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
451d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org  *eob_ptr = eob + 1;
452d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org}
45310a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org
45487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#if CONFIG_VP9_HIGHBITDEPTH
45587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgvoid vp9_high_quantize_b_32x32_c(const tran_low_t *coeff_ptr,
45687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                 intptr_t n_coeffs, int skip_block,
45787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                 const int16_t *zbin_ptr,
45887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                 const int16_t *round_ptr,
45987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                 const int16_t *quant_ptr,
46087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                 const int16_t *quant_shift_ptr,
46187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                 tran_low_t *qcoeff_ptr,
46287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                 tran_low_t *dqcoeff_ptr,
46387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                 const int16_t *dequant_ptr,
46487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                 int zbin_oq_value, uint16_t *eob_ptr,
46587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                 const int16_t *scan, const int16_t *iscan) {
46687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  const int zbins[2] = { ROUND_POWER_OF_TWO(zbin_ptr[0] + zbin_oq_value, 1),
46787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                         ROUND_POWER_OF_TWO(zbin_ptr[1] + zbin_oq_value, 1) };
46887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
46987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
47087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  int idx = 0;
47187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  int idx_arr[1024];
47287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  int i, eob = -1;
47387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  (void)iscan;
47487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
47587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  vpx_memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
47687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  vpx_memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
47787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
47887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  if (!skip_block) {
47987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    // Pre-scan pass
48087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    for (i = 0; i < n_coeffs; i++) {
48187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      const int rc = scan[i];
48287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      const int coeff = coeff_ptr[rc];
48387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
48487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      // If the coefficient is out of the base ZBIN range, keep it for
48587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      // quantization.
48687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      if (coeff >= zbins[rc != 0] || coeff <= nzbins[rc != 0])
48787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        idx_arr[idx++] = i;
48887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    }
48987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
49087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    // Quantization pass: only process the coefficients selected in
49187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    // pre-scan pass. Note: idx can be zero.
49287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    for (i = 0; i < idx; i++) {
49387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      const int rc = scan[idx_arr[i]];
49487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      const int coeff = coeff_ptr[rc];
49587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      const int coeff_sign = (coeff >> 31);
49687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
49787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      int64_t tmp = clamp(abs_coeff +
49887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                          ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1),
49987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                          INT32_MIN, INT32_MAX);
50087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      tmp = ((((tmp * quant_ptr[rc != 0]) >> 16) + tmp) *
50187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org               quant_shift_ptr[rc != 0]) >> 15;
50287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
50387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
50487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2;
50587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
50687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      if (tmp)
50787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        eob = idx_arr[i];
50887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    }
50987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  }
51087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  *eob_ptr = eob + 1;
51187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org}
51287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#endif
51387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
514d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgvoid vp9_regular_quantize_b_4x4(MACROBLOCK *x, int plane, int block,
515ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org                                const int16_t *scan, const int16_t *iscan) {
516ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org  MACROBLOCKD *const xd = &x->e_mbd;
51776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  struct macroblock_plane *p = &x->plane[plane];
51876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  struct macroblockd_plane *pd = &xd->plane[plane];
519ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org
52087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#if CONFIG_VP9_HIGHBITDEPTH
52187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
52287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    vp9_high_quantize_b(BLOCK_OFFSET(p->coeff, block),
52387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                        16, x->skip_block,
52487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                        p->zbin, p->round, p->quant, p->quant_shift,
52587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                        BLOCK_OFFSET(p->qcoeff, block),
52687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                        BLOCK_OFFSET(pd->dqcoeff, block),
52787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                        pd->dequant, p->zbin_extra, &p->eobs[block],
52887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                        scan, iscan);
52987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    return;
53087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  }
53187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#endif
532d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  vp9_quantize_b(BLOCK_OFFSET(p->coeff, block),
533ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org           16, x->skip_block,
534ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org           p->zbin, p->round, p->quant, p->quant_shift,
535d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org           BLOCK_OFFSET(p->qcoeff, block),
536d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org           BLOCK_OFFSET(pd->dqcoeff, block),
537d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org           pd->dequant, p->zbin_extra, &p->eobs[block], scan, iscan);
5386fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
5396fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
54047265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.orgstatic void invert_quant(int16_t *quant, int16_t *shift, int d) {
5416fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  unsigned t;
5426fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  int l;
5436fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  t = d;
5446fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  for (l = 0; t > 1; l++)
5456fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    t >>= 1;
5466fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  t = 1 + (1 << (16 + l)) / d;
547d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org  *quant = (int16_t)(t - (1 << 16));
54847265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  *shift = 1 << (16 - l);
5496fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
5506fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
55187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgstatic int get_qzbin_factor(int q, vpx_bit_depth_t bit_depth) {
55287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  const int quant = vp9_dc_quant(q, 0, bit_depth);
55387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#if CONFIG_VP9_HIGHBITDEPTH
55487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  switch (bit_depth) {
55587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    case VPX_BITS_8:
55687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      return q == 0 ? 64 : (quant < 148 ? 84 : 80);
55787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    case VPX_BITS_10:
55887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      return q == 0 ? 64 : (quant < 592 ? 84 : 80);
55987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    case VPX_BITS_12:
56087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      return q == 0 ? 64 : (quant < 2368 ? 84 : 80);
56187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    default:
56287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      assert(0 && "bit_depth should be VPX_BITS_8, VPX_BITS_10 or VPX_BITS_12");
56387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      return -1;
56487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  }
56587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#else
56687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  (void) bit_depth;
56787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  return q == 0 ? 64 : (quant < 148 ? 84 : 80);
56887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#endif
56987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org}
57087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
5716fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgvoid vp9_init_quantizer(VP9_COMP *cpi) {
57253a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  VP9_COMMON *const cm = &cpi->common;
57393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  QUANTS *const quants = &cpi->quants;
574411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org  int i, q, quant;
57590c5310de3dfbd1b1624502616cbc8aaf9ad25f0johannkoenig@chromium.org
57690c5310de3dfbd1b1624502616cbc8aaf9ad25f0johannkoenig@chromium.org  for (q = 0; q < QINDEX_RANGE; q++) {
57787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    const int qzbin_factor = get_qzbin_factor(q, cm->bit_depth);
57853a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    const int qrounding_factor = q == 0 ? 64 : 48;
57953a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org
58053a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    for (i = 0; i < 2; ++i) {
581e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      int qrounding_factor_fp = i == 0 ? 48 : 42;
582e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      if (q == 0)
583e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org        qrounding_factor_fp = 64;
584e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org
585411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org      // y
58687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      quant = i == 0 ? vp9_dc_quant(q, cm->y_dc_delta_q, cm->bit_depth)
58787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                     : vp9_ac_quant(q, 0, cm->bit_depth);
58893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      invert_quant(&quants->y_quant[q][i], &quants->y_quant_shift[q][i], quant);
58988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org      quants->y_quant_fp[q][i] = (1 << 16) / quant;
590e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      quants->y_round_fp[q][i] = (qrounding_factor_fp * quant) >> 7;
59193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      quants->y_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant, 7);
59293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      quants->y_round[q][i] = (qrounding_factor * quant) >> 7;
59353a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org      cm->y_dequant[q][i] = quant;
59447265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
595411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org      // uv
59687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      quant = i == 0 ? vp9_dc_quant(q, cm->uv_dc_delta_q, cm->bit_depth)
59787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                     : vp9_ac_quant(q, cm->uv_ac_delta_q, cm->bit_depth);
59893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      invert_quant(&quants->uv_quant[q][i],
59993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                   &quants->uv_quant_shift[q][i], quant);
60088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org      quants->uv_quant_fp[q][i] = (1 << 16) / quant;
601e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      quants->uv_round_fp[q][i] = (qrounding_factor_fp * quant) >> 7;
60293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      quants->uv_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant, 7);
60393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      quants->uv_round[q][i] = (qrounding_factor * quant) >> 7;
60453a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org      cm->uv_dequant[q][i] = quant;
605411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org    }
60647265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
60747265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org    for (i = 2; i < 8; i++) {
60893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      quants->y_quant[q][i] = quants->y_quant[q][1];
60988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org      quants->y_quant_fp[q][i] = quants->y_quant_fp[q][1];
610e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      quants->y_round_fp[q][i] = quants->y_round_fp[q][1];
61193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      quants->y_quant_shift[q][i] = quants->y_quant_shift[q][1];
61293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      quants->y_zbin[q][i] = quants->y_zbin[q][1];
61393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      quants->y_round[q][i] = quants->y_round[q][1];
61453a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org      cm->y_dequant[q][i] = cm->y_dequant[q][1];
61547265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
61693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      quants->uv_quant[q][i] = quants->uv_quant[q][1];
61788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org      quants->uv_quant_fp[q][i] = quants->uv_quant_fp[q][1];
618e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      quants->uv_round_fp[q][i] = quants->uv_round_fp[q][1];
61993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      quants->uv_quant_shift[q][i] = quants->uv_quant_shift[q][1];
62093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      quants->uv_zbin[q][i] = quants->uv_zbin[q][1];
62193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      quants->uv_round[q][i] = quants->uv_round[q][1];
62253a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org      cm->uv_dequant[q][i] = cm->uv_dequant[q][1];
6236fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    }
6246fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
6256fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
6266fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
627411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.orgvoid vp9_init_plane_quantizers(VP9_COMP *cpi, MACROBLOCK *x) {
62876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  const VP9_COMMON *const cm = &cpi->common;
62993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  MACROBLOCKD *const xd = &x->e_mbd;
63093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  QUANTS *const quants = &cpi->quants;
63187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  const int segment_id = xd->mi[0].src_mi->mbmi.segment_id;
63276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  const int qindex = vp9_get_qindex(&cm->seg, segment_id, cm->base_qindex);
63376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  const int rdmult = vp9_compute_rd_mult(cpi, qindex + cm->y_dc_delta_q);
634693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  const int zbin = cpi->zbin_mode_boost;
63576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  int i;
636ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org
6376fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  // Y
63893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  x->plane[0].quant = quants->y_quant[qindex];
63988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  x->plane[0].quant_fp = quants->y_quant_fp[qindex];
640e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org  x->plane[0].round_fp = quants->y_round_fp[qindex];
64193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  x->plane[0].quant_shift = quants->y_quant_shift[qindex];
64293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  x->plane[0].zbin = quants->y_zbin[qindex];
64393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  x->plane[0].round = quants->y_round[qindex];
64441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  x->plane[0].quant_thred[0] = cm->y_dequant[qindex][0] *
64541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                                  cm->y_dequant[qindex][0];
64641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  x->plane[0].quant_thred[1] = cm->y_dequant[qindex][1] *
64741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                                  cm->y_dequant[qindex][1];
64876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  x->plane[0].zbin_extra = (int16_t)((cm->y_dequant[qindex][1] * zbin) >> 7);
64976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  xd->plane[0].dequant = cm->y_dequant[qindex];
6506fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
6516fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  // UV
65210a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  for (i = 1; i < 3; i++) {
65393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    x->plane[i].quant = quants->uv_quant[qindex];
65488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    x->plane[i].quant_fp = quants->uv_quant_fp[qindex];
655e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org    x->plane[i].round_fp = quants->uv_round_fp[qindex];
65693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    x->plane[i].quant_shift = quants->uv_quant_shift[qindex];
65793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    x->plane[i].zbin = quants->uv_zbin[qindex];
65893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    x->plane[i].round = quants->uv_round[qindex];
65941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    x->plane[i].quant_thred[0] = cm->y_dequant[qindex][0] *
66041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                                    cm->y_dequant[qindex][0];
66141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    x->plane[i].quant_thred[1] = cm->y_dequant[qindex][1] *
66241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                                    cm->y_dequant[qindex][1];
66376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    x->plane[i].zbin_extra = (int16_t)((cm->uv_dequant[qindex][1] * zbin) >> 7);
66476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    xd->plane[i].dequant = cm->uv_dequant[qindex];
6656fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
6666fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
66776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  x->skip_block = vp9_segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP);
668d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  x->q_index = qindex;
669ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org
67076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  x->errorperbit = rdmult >> 6;
67176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  x->errorperbit += (x->errorperbit == 0);
672ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org
673d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  vp9_initialize_me_consts(cpi, x->q_index);
6746fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
6756fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
6766fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgvoid vp9_update_zbin_extra(VP9_COMP *cpi, MACROBLOCK *x) {
677d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  const int qindex = x->q_index;
67810a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  const int y_zbin_extra = (cpi->common.y_dequant[qindex][1] *
679693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com                            cpi->zbin_mode_boost) >> 7;
68010a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  const int uv_zbin_extra = (cpi->common.uv_dequant[qindex][1] *
681693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com                             cpi->zbin_mode_boost) >> 7;
6826fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
68310a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  x->plane[0].zbin_extra = (int16_t)y_zbin_extra;
68410a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  x->plane[1].zbin_extra = (int16_t)uv_zbin_extra;
68510a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  x->plane[2].zbin_extra = (int16_t)uv_zbin_extra;
6866fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
6876fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
6886fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgvoid vp9_frame_init_quantizer(VP9_COMP *cpi) {
6896fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  cpi->zbin_mode_boost = 0;
690411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org  vp9_init_plane_quantizers(cpi, &cpi->mb);
6916fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
6926fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
69393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgvoid vp9_set_quantizer(VP9_COMMON *cm, int q) {
694411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org  // quantizer has to be reinitialized with vp9_init_quantizer() if any
695411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org  // delta_q changes.
696ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org  cm->base_qindex = q;
69710a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  cm->y_dc_delta_q = 0;
69810a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  cm->uv_dc_delta_q = 0;
69910a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  cm->uv_ac_delta_q = 0;
7006fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
701693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com
702693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com// Table that converts 0-63 Q-range values passed in outside to the Qindex
703693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com// range used internally.
704693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.comstatic const int quantizer_to_qindex[] = {
705693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  0,    4,   8,  12,  16,  20,  24,  28,
706693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  32,   36,  40,  44,  48,  52,  56,  60,
707693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  64,   68,  72,  76,  80,  84,  88,  92,
708693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  96,  100, 104, 108, 112, 116, 120, 124,
709693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  128, 132, 136, 140, 144, 148, 152, 156,
710693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  160, 164, 168, 172, 176, 180, 184, 188,
711693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  192, 196, 200, 204, 208, 212, 216, 220,
712693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  224, 228, 232, 236, 240, 244, 249, 255,
713693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com};
714693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com
715693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.comint vp9_quantizer_to_qindex(int quantizer) {
716693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  return quantizer_to_qindex[quantizer];
717693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com}
718693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com
719693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.comint vp9_qindex_to_quantizer(int qindex) {
720693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  int quantizer;
721693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com
722693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  for (quantizer = 0; quantizer < 64; ++quantizer)
723693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    if (quantizer_to_qindex[quantizer] >= qindex)
724693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com      return quantizer;
725693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com
726693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  return 63;
727693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com}
728