blob: 7f0096c82b93442980c0ace7a1b907c51103227b [file] [log] [blame]
Yaowu Xuc27fc142016-08-22 16:08:15 -07001/*
Yaowu Xu9c01aa12016-09-01 14:32:49 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Yaowu Xuc27fc142016-08-22 16:08:15 -07003 *
Yaowu Xu9c01aa12016-09-01 14:32:49 -07004 * 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.
Yaowu Xuc27fc142016-08-22 16:08:15 -070010 */
11
Yaowu Xuc27fc142016-08-22 16:08:15 -070012#include "aom_dsp/quantize.h"
Yaowu Xuf883b422016-08-30 14:01:10 -070013#include "aom_mem/aom_mem.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070014
Thomas Daviesf3b5ee12017-07-18 15:16:43 +010015void quantize_b_helper_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
16 int skip_block, const int16_t *zbin_ptr,
17 const int16_t *round_ptr, const int16_t *quant_ptr,
18 const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
19 tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr,
20 uint16_t *eob_ptr, const int16_t *scan,
21 const int16_t *iscan, const qm_val_t *qm_ptr,
22 const qm_val_t *iqm_ptr, const int log_scale) {
Cheng Chence8275c2017-04-26 11:16:24 -070023 const int zbins[2] = { ROUND_POWER_OF_TWO(zbin_ptr[0], log_scale),
24 ROUND_POWER_OF_TWO(zbin_ptr[1], log_scale) };
25 const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
26 int i, non_zero_count = (int)n_coeffs, eob = -1;
27 (void)iscan;
28
29 memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
30 memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
31
32 if (!skip_block) {
33 // Pre-scan pass
34 for (i = (int)n_coeffs - 1; i >= 0; i--) {
35 const int rc = scan[i];
Thomas Daviesf3b5ee12017-07-18 15:16:43 +010036 const qm_val_t wt = qm_ptr != NULL ? qm_ptr[rc] : (1 << AOM_QM_BITS);
Cheng Chence8275c2017-04-26 11:16:24 -070037 const int coeff = coeff_ptr[rc] * wt;
Cheng Chence8275c2017-04-26 11:16:24 -070038
Hui Suce2e3372017-08-09 15:18:05 -070039 if (coeff < (zbins[rc != 0] * (1 << AOM_QM_BITS)) &&
40 coeff > (nzbins[rc != 0] * (1 << AOM_QM_BITS)))
Cheng Chence8275c2017-04-26 11:16:24 -070041 non_zero_count--;
Cheng Chence8275c2017-04-26 11:16:24 -070042 else
43 break;
44 }
45
46 // Quantization pass: All coefficients with index >= zero_flag are
47 // skippable. Note: zero_flag can be zero.
48 for (i = 0; i < non_zero_count; i++) {
49 const int rc = scan[i];
50 const int coeff = coeff_ptr[rc];
51 const int coeff_sign = (coeff >> 31);
52 const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
53 int tmp32;
54
Thomas Daviesf3b5ee12017-07-18 15:16:43 +010055 const qm_val_t wt = qm_ptr != NULL ? qm_ptr[rc] : (1 << AOM_QM_BITS);
Cheng Chence8275c2017-04-26 11:16:24 -070056 if (abs_coeff * wt >= (zbins[rc != 0] << AOM_QM_BITS)) {
Cheng Chence8275c2017-04-26 11:16:24 -070057 int64_t tmp =
58 clamp(abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], log_scale),
59 INT16_MIN, INT16_MAX);
Cheng Chence8275c2017-04-26 11:16:24 -070060 tmp *= wt;
61 tmp32 = (int)(((((tmp * quant_ptr[rc != 0]) >> 16) + tmp) *
62 quant_shift_ptr[rc != 0]) >>
63 (16 - log_scale + AOM_QM_BITS)); // quantization
Jingning Hand18c84c2017-04-27 11:25:29 -070064 qcoeff_ptr[rc] = (tmp32 ^ coeff_sign) - coeff_sign;
Thomas Daviesf3b5ee12017-07-18 15:16:43 +010065 const int iwt = iqm_ptr != NULL ? iqm_ptr[rc] : (1 << AOM_QM_BITS);
Cheng Chence8275c2017-04-26 11:16:24 -070066 const int dequant =
Thomas Daviesf3b5ee12017-07-18 15:16:43 +010067 (dequant_ptr[rc != 0] * iwt + (1 << (AOM_QM_BITS - 1))) >>
Cheng Chence8275c2017-04-26 11:16:24 -070068 AOM_QM_BITS;
69 dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant / (1 << log_scale);
Cheng Chence8275c2017-04-26 11:16:24 -070070
71 if (tmp32) eob = i;
72 }
73 }
74 }
75 *eob_ptr = eob + 1;
76}
77
Thomas Daviesf3b5ee12017-07-18 15:16:43 +010078void highbd_quantize_b_helper_c(
79 const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block,
80 const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr,
81 const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
82 tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr,
83 const int16_t *scan, const int16_t *iscan, const qm_val_t *qm_ptr,
84 const qm_val_t *iqm_ptr, const int log_scale) {
85 int i, eob = -1;
86 const int zbins[2] = { ROUND_POWER_OF_TWO(zbin_ptr[0], log_scale),
87 ROUND_POWER_OF_TWO(zbin_ptr[1], log_scale) };
88 const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
89 int dequant;
Thomas Daviesf3b5ee12017-07-18 15:16:43 +010090 int idx_arr[4096];
Thomas Daviesf3b5ee12017-07-18 15:16:43 +010091 (void)iscan;
92 int idx = 0;
93
94 memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
95 memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
96
97 if (!skip_block) {
98 // Pre-scan pass
99 for (i = 0; i < n_coeffs; i++) {
100 const int rc = scan[i];
101 const qm_val_t wt = qm_ptr != NULL ? qm_ptr[rc] : (1 << AOM_QM_BITS);
102 const int coeff = coeff_ptr[rc] * wt;
103
104 // If the coefficient is out of the base ZBIN range, keep it for
105 // quantization.
Hui Suce2e3372017-08-09 15:18:05 -0700106 if (coeff >= (zbins[rc != 0] * (1 << AOM_QM_BITS)) ||
107 coeff <= (nzbins[rc != 0] * (1 << AOM_QM_BITS)))
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100108 idx_arr[idx++] = i;
109 }
110
111 // Quantization pass: only process the coefficients selected in
112 // pre-scan pass. Note: idx can be zero.
113 for (i = 0; i < idx; i++) {
114 const int rc = scan[idx_arr[i]];
115 const int coeff = coeff_ptr[rc];
116 const int coeff_sign = (coeff >> 31);
117 const qm_val_t wt = qm_ptr != NULL ? qm_ptr[rc] : (1 << AOM_QM_BITS);
118 const qm_val_t iwt = iqm_ptr != NULL ? iqm_ptr[rc] : (1 << AOM_QM_BITS);
119 const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
120 const int64_t tmp1 =
121 abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], log_scale);
122 const int64_t tmpw = tmp1 * wt;
123 const int64_t tmp2 = ((tmpw * quant_ptr[rc != 0]) >> 16) + tmpw;
Hui Sub2935182017-08-09 15:34:28 -0700124 const int abs_qcoeff = (int)((tmp2 * quant_shift_ptr[rc != 0]) >>
125 (16 - log_scale + AOM_QM_BITS));
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100126 qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
127 dequant = (dequant_ptr[rc != 0] * iwt + (1 << (AOM_QM_BITS - 1))) >>
128 AOM_QM_BITS;
129 dqcoeff_ptr[rc] = (qcoeff_ptr[rc] * dequant) / (1 << log_scale);
130 if (abs_qcoeff) eob = idx_arr[i];
131 }
132 }
133 *eob_ptr = eob + 1;
134}
135
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100136/* These functions should only be called when quantisation matrices
137 are not used. */
Cheng Chence8275c2017-04-26 11:16:24 -0700138void aom_quantize_b_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
139 int skip_block, const int16_t *zbin_ptr,
140 const int16_t *round_ptr, const int16_t *quant_ptr,
141 const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
142 tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr,
143 uint16_t *eob_ptr, const int16_t *scan,
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100144 const int16_t *iscan) {
Cheng Chence8275c2017-04-26 11:16:24 -0700145 quantize_b_helper_c(coeff_ptr, n_coeffs, skip_block, zbin_ptr, round_ptr,
146 quant_ptr, quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr,
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100147 dequant_ptr, eob_ptr, scan, iscan, NULL, NULL, 0);
Cheng Chence8275c2017-04-26 11:16:24 -0700148}
149
150void aom_quantize_b_32x32_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
151 int skip_block, const int16_t *zbin_ptr,
152 const int16_t *round_ptr, const int16_t *quant_ptr,
153 const int16_t *quant_shift_ptr,
154 tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
155 const int16_t *dequant_ptr, uint16_t *eob_ptr,
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100156 const int16_t *scan, const int16_t *iscan) {
Cheng Chence8275c2017-04-26 11:16:24 -0700157 quantize_b_helper_c(coeff_ptr, n_coeffs, skip_block, zbin_ptr, round_ptr,
158 quant_ptr, quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr,
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100159 dequant_ptr, eob_ptr, scan, iscan, NULL, NULL, 1);
Cheng Chence8275c2017-04-26 11:16:24 -0700160}
161
Cheng Chence8275c2017-04-26 11:16:24 -0700162void aom_quantize_b_64x64_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
163 int skip_block, const int16_t *zbin_ptr,
164 const int16_t *round_ptr, const int16_t *quant_ptr,
165 const int16_t *quant_shift_ptr,
166 tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
167 const int16_t *dequant_ptr, uint16_t *eob_ptr,
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100168 const int16_t *scan, const int16_t *iscan) {
Cheng Chence8275c2017-04-26 11:16:24 -0700169 quantize_b_helper_c(coeff_ptr, n_coeffs, skip_block, zbin_ptr, round_ptr,
170 quant_ptr, quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr,
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100171 dequant_ptr, eob_ptr, scan, iscan, NULL, NULL, 2);
Cheng Chence8275c2017-04-26 11:16:24 -0700172}
Cheng Chence8275c2017-04-26 11:16:24 -0700173
Yaowu Xuf883b422016-08-30 14:01:10 -0700174void aom_highbd_quantize_b_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700175 int skip_block, const int16_t *zbin_ptr,
176 const int16_t *round_ptr, const int16_t *quant_ptr,
177 const int16_t *quant_shift_ptr,
178 tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
179 const int16_t *dequant_ptr, uint16_t *eob_ptr,
180 const int16_t *scan, const int16_t *iscan) {
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100181 highbd_quantize_b_helper_c(coeff_ptr, n_coeffs, skip_block, zbin_ptr,
182 round_ptr, quant_ptr, quant_shift_ptr, qcoeff_ptr,
183 dqcoeff_ptr, dequant_ptr, eob_ptr, scan, iscan,
184 NULL, NULL, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700185}
Yaowu Xuc27fc142016-08-22 16:08:15 -0700186
Yaowu Xuf883b422016-08-30 14:01:10 -0700187void aom_highbd_quantize_b_32x32_c(
Yaowu Xuc27fc142016-08-22 16:08:15 -0700188 const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block,
189 const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr,
190 const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
191 tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr,
192 const int16_t *scan, const int16_t *iscan) {
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100193 highbd_quantize_b_helper_c(coeff_ptr, n_coeffs, skip_block, zbin_ptr,
194 round_ptr, quant_ptr, quant_shift_ptr, qcoeff_ptr,
195 dqcoeff_ptr, dequant_ptr, eob_ptr, scan, iscan,
196 NULL, NULL, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700197}
Debargha Mukherjee0e119122016-11-04 12:10:23 -0700198
Debargha Mukherjee0e119122016-11-04 12:10:23 -0700199void aom_highbd_quantize_b_64x64_c(
200 const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block,
201 const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr,
202 const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
203 tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr,
204 const int16_t *scan, const int16_t *iscan) {
Thomas Daviesf3b5ee12017-07-18 15:16:43 +0100205 highbd_quantize_b_helper_c(coeff_ptr, n_coeffs, skip_block, zbin_ptr,
206 round_ptr, quant_ptr, quant_shift_ptr, qcoeff_ptr,
207 dqcoeff_ptr, dequant_ptr, eob_ptr, scan, iscan,
208 NULL, NULL, 2);
Debargha Mukherjee0e119122016-11-04 12:10:23 -0700209}