/src/aom/av1/encoder/av1_quantize.c
Line | Count | Source (jump to first uncovered line) |
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_dsp/quantize.h" |
17 | | #include "aom_mem/aom_mem.h" |
18 | | #include "aom_ports/mem.h" |
19 | | |
20 | | #include "av1/common/idct.h" |
21 | | #include "av1/common/quant_common.h" |
22 | | #include "av1/common/scan.h" |
23 | | #include "av1/common/seg_common.h" |
24 | | |
25 | | #include "av1/encoder/av1_quantize.h" |
26 | | #include "av1/encoder/encoder.h" |
27 | | #include "av1/encoder/rd.h" |
28 | | |
29 | | void av1_quantize_skip(intptr_t n_coeffs, tran_low_t *qcoeff_ptr, |
30 | 0 | tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr) { |
31 | 0 | memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr)); |
32 | 0 | memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr)); |
33 | 0 | *eob_ptr = 0; |
34 | 0 | } |
35 | | |
36 | | int av1_quantize_fp_no_qmatrix(const int16_t quant_ptr[2], |
37 | | const int16_t dequant_ptr[2], |
38 | | const int16_t round_ptr[2], int log_scale, |
39 | | const int16_t *scan, int coeff_count, |
40 | | const tran_low_t *coeff_ptr, |
41 | | tran_low_t *qcoeff_ptr, |
42 | 3.50M | tran_low_t *dqcoeff_ptr) { |
43 | 3.50M | memset(qcoeff_ptr, 0, coeff_count * sizeof(*qcoeff_ptr)); |
44 | 3.50M | memset(dqcoeff_ptr, 0, coeff_count * sizeof(*dqcoeff_ptr)); |
45 | 3.50M | const int rounding[2] = { ROUND_POWER_OF_TWO(round_ptr[0], log_scale), |
46 | 3.50M | ROUND_POWER_OF_TWO(round_ptr[1], log_scale) }; |
47 | 3.50M | int eob = 0; |
48 | 1.07G | for (int i = 0; i < coeff_count; i++) { |
49 | 1.07G | const int rc = scan[i]; |
50 | 1.07G | const int32_t thresh = (int32_t)(dequant_ptr[rc != 0]); |
51 | 1.07G | const int coeff = coeff_ptr[rc]; |
52 | 1.07G | const int coeff_sign = AOMSIGN(coeff); |
53 | 1.07G | int64_t abs_coeff = (coeff ^ coeff_sign) - coeff_sign; |
54 | 1.07G | int tmp32 = 0; |
55 | 1.07G | if ((abs_coeff << (1 + log_scale)) >= thresh) { |
56 | 463k | abs_coeff = clamp64(abs_coeff + rounding[rc != 0], INT16_MIN, INT16_MAX); |
57 | 463k | tmp32 = (int)((abs_coeff * quant_ptr[rc != 0]) >> (16 - log_scale)); |
58 | 463k | if (tmp32) { |
59 | 462k | qcoeff_ptr[rc] = (tmp32 ^ coeff_sign) - coeff_sign; |
60 | 462k | const tran_low_t abs_dqcoeff = |
61 | 462k | (tmp32 * dequant_ptr[rc != 0]) >> log_scale; |
62 | 462k | dqcoeff_ptr[rc] = (abs_dqcoeff ^ coeff_sign) - coeff_sign; |
63 | 462k | } |
64 | 463k | } |
65 | 1.07G | if (tmp32) eob = i + 1; |
66 | 1.07G | } |
67 | 3.50M | return eob; |
68 | 3.50M | } |
69 | | |
70 | | static void quantize_fp_helper_c( |
71 | | const tran_low_t *coeff_ptr, intptr_t n_coeffs, const int16_t *zbin_ptr, |
72 | | const int16_t *round_ptr, const int16_t *quant_ptr, |
73 | | const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, |
74 | | tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, |
75 | | const int16_t *scan, const int16_t *iscan, const qm_val_t *qm_ptr, |
76 | 3.50M | const qm_val_t *iqm_ptr, int log_scale) { |
77 | 3.50M | int i, eob = -1; |
78 | 3.50M | const int rounding[2] = { ROUND_POWER_OF_TWO(round_ptr[0], log_scale), |
79 | 3.50M | ROUND_POWER_OF_TWO(round_ptr[1], log_scale) }; |
80 | | // TODO(jingning) Decide the need of these arguments after the |
81 | | // quantization process is completed. |
82 | 3.50M | (void)zbin_ptr; |
83 | 3.50M | (void)quant_shift_ptr; |
84 | 3.50M | (void)iscan; |
85 | | |
86 | 3.50M | memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr)); |
87 | 3.50M | memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr)); |
88 | | |
89 | 3.50M | if (qm_ptr == NULL && iqm_ptr == NULL) { |
90 | 3.50M | *eob_ptr = av1_quantize_fp_no_qmatrix(quant_ptr, dequant_ptr, round_ptr, |
91 | 3.50M | log_scale, scan, (int)n_coeffs, |
92 | 3.50M | coeff_ptr, qcoeff_ptr, dqcoeff_ptr); |
93 | 18.4E | } else { |
94 | | // Quantization pass: All coefficients with index >= zero_flag are |
95 | | // skippable. Note: zero_flag can be zero. |
96 | 18.4E | for (i = 0; i < n_coeffs; i++) { |
97 | 0 | const int rc = scan[i]; |
98 | 0 | const int coeff = coeff_ptr[rc]; |
99 | 0 | const qm_val_t wt = qm_ptr ? qm_ptr[rc] : (1 << AOM_QM_BITS); |
100 | 0 | const qm_val_t iwt = iqm_ptr ? iqm_ptr[rc] : (1 << AOM_QM_BITS); |
101 | 0 | const int dequant = |
102 | 0 | (dequant_ptr[rc != 0] * iwt + (1 << (AOM_QM_BITS - 1))) >> |
103 | 0 | AOM_QM_BITS; |
104 | 0 | const int coeff_sign = AOMSIGN(coeff); |
105 | 0 | int64_t abs_coeff = (coeff ^ coeff_sign) - coeff_sign; |
106 | 0 | int tmp32 = 0; |
107 | 0 | if (abs_coeff * wt >= |
108 | 0 | (dequant_ptr[rc != 0] << (AOM_QM_BITS - (1 + log_scale)))) { |
109 | 0 | abs_coeff += rounding[rc != 0]; |
110 | 0 | abs_coeff = clamp64(abs_coeff, INT16_MIN, INT16_MAX); |
111 | 0 | tmp32 = (int)((abs_coeff * wt * quant_ptr[rc != 0]) >> |
112 | 0 | (16 - log_scale + AOM_QM_BITS)); |
113 | 0 | qcoeff_ptr[rc] = (tmp32 ^ coeff_sign) - coeff_sign; |
114 | 0 | const tran_low_t abs_dqcoeff = (tmp32 * dequant) >> log_scale; |
115 | 0 | dqcoeff_ptr[rc] = (abs_dqcoeff ^ coeff_sign) - coeff_sign; |
116 | 0 | } |
117 | |
|
118 | 0 | if (tmp32) eob = i; |
119 | 0 | } |
120 | 18.4E | *eob_ptr = eob + 1; |
121 | 18.4E | } |
122 | 3.50M | } |
123 | | |
124 | | #if CONFIG_AV1_HIGHBITDEPTH |
125 | | static void highbd_quantize_fp_helper_c( |
126 | | const tran_low_t *coeff_ptr, intptr_t count, const int16_t *zbin_ptr, |
127 | | const int16_t *round_ptr, const int16_t *quant_ptr, |
128 | | const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, |
129 | | tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, |
130 | | const int16_t *scan, const int16_t *iscan, const qm_val_t *qm_ptr, |
131 | 0 | const qm_val_t *iqm_ptr, int log_scale) { |
132 | 0 | int i; |
133 | 0 | int eob = -1; |
134 | 0 | const int shift = 16 - log_scale; |
135 | | // TODO(jingning) Decide the need of these arguments after the |
136 | | // quantization process is completed. |
137 | 0 | (void)zbin_ptr; |
138 | 0 | (void)quant_shift_ptr; |
139 | 0 | (void)iscan; |
140 | |
|
141 | 0 | if (qm_ptr || iqm_ptr) { |
142 | | // Quantization pass: All coefficients with index >= zero_flag are |
143 | | // skippable. Note: zero_flag can be zero. |
144 | 0 | for (i = 0; i < count; i++) { |
145 | 0 | const int rc = scan[i]; |
146 | 0 | const int coeff = coeff_ptr[rc]; |
147 | 0 | const qm_val_t wt = qm_ptr != NULL ? qm_ptr[rc] : (1 << AOM_QM_BITS); |
148 | 0 | const qm_val_t iwt = iqm_ptr != NULL ? iqm_ptr[rc] : (1 << AOM_QM_BITS); |
149 | 0 | const int dequant = |
150 | 0 | (dequant_ptr[rc != 0] * iwt + (1 << (AOM_QM_BITS - 1))) >> |
151 | 0 | AOM_QM_BITS; |
152 | 0 | const int coeff_sign = AOMSIGN(coeff); |
153 | 0 | const int64_t abs_coeff = (coeff ^ coeff_sign) - coeff_sign; |
154 | 0 | int abs_qcoeff = 0; |
155 | 0 | if (abs_coeff * wt >= |
156 | 0 | (dequant_ptr[rc != 0] << (AOM_QM_BITS - (1 + log_scale)))) { |
157 | 0 | const int64_t tmp = |
158 | 0 | abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], log_scale); |
159 | 0 | abs_qcoeff = |
160 | 0 | (int)((tmp * quant_ptr[rc != 0] * wt) >> (shift + AOM_QM_BITS)); |
161 | 0 | qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign); |
162 | 0 | const tran_low_t abs_dqcoeff = (abs_qcoeff * dequant) >> log_scale; |
163 | 0 | dqcoeff_ptr[rc] = (tran_low_t)((abs_dqcoeff ^ coeff_sign) - coeff_sign); |
164 | 0 | if (abs_qcoeff) eob = i; |
165 | 0 | } else { |
166 | 0 | qcoeff_ptr[rc] = 0; |
167 | 0 | dqcoeff_ptr[rc] = 0; |
168 | 0 | } |
169 | 0 | } |
170 | 0 | } else { |
171 | 0 | const int log_scaled_round_arr[2] = { |
172 | 0 | ROUND_POWER_OF_TWO(round_ptr[0], log_scale), |
173 | 0 | ROUND_POWER_OF_TWO(round_ptr[1], log_scale), |
174 | 0 | }; |
175 | 0 | for (i = 0; i < count; i++) { |
176 | 0 | const int rc = scan[i]; |
177 | 0 | const int coeff = coeff_ptr[rc]; |
178 | 0 | const int rc01 = (rc != 0); |
179 | 0 | const int coeff_sign = AOMSIGN(coeff); |
180 | 0 | const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; |
181 | 0 | const int log_scaled_round = log_scaled_round_arr[rc01]; |
182 | 0 | if ((abs_coeff << (1 + log_scale)) >= dequant_ptr[rc01]) { |
183 | 0 | const int quant = quant_ptr[rc01]; |
184 | 0 | const int dequant = dequant_ptr[rc01]; |
185 | 0 | const int64_t tmp = (int64_t)abs_coeff + log_scaled_round; |
186 | 0 | const int abs_qcoeff = (int)((tmp * quant) >> shift); |
187 | 0 | qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign); |
188 | 0 | const tran_low_t abs_dqcoeff = (abs_qcoeff * dequant) >> log_scale; |
189 | 0 | if (abs_qcoeff) eob = i; |
190 | 0 | dqcoeff_ptr[rc] = (tran_low_t)((abs_dqcoeff ^ coeff_sign) - coeff_sign); |
191 | 0 | } else { |
192 | 0 | qcoeff_ptr[rc] = 0; |
193 | 0 | dqcoeff_ptr[rc] = 0; |
194 | 0 | } |
195 | 0 | } |
196 | 0 | } |
197 | 0 | *eob_ptr = eob + 1; |
198 | 0 | } |
199 | | #endif // CONFIG_AV1_HIGHBITDEPTH |
200 | | |
201 | | void av1_quantize_fp_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, |
202 | | const int16_t *zbin_ptr, const int16_t *round_ptr, |
203 | | const int16_t *quant_ptr, const int16_t *quant_shift_ptr, |
204 | | tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, |
205 | | const int16_t *dequant_ptr, uint16_t *eob_ptr, |
206 | 2.50M | const int16_t *scan, const int16_t *iscan) { |
207 | 2.50M | quantize_fp_helper_c(coeff_ptr, n_coeffs, zbin_ptr, round_ptr, quant_ptr, |
208 | 2.50M | quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr, dequant_ptr, |
209 | 2.50M | eob_ptr, scan, iscan, NULL, NULL, 0); |
210 | 2.50M | } |
211 | | |
212 | | void av1_quantize_lp_c(const int16_t *coeff_ptr, intptr_t n_coeffs, |
213 | | const int16_t *round_ptr, const int16_t *quant_ptr, |
214 | | int16_t *qcoeff_ptr, int16_t *dqcoeff_ptr, |
215 | | const int16_t *dequant_ptr, uint16_t *eob_ptr, |
216 | 0 | const int16_t *scan, const int16_t *iscan) { |
217 | 0 | (void)iscan; |
218 | 0 | int eob = -1; |
219 | |
|
220 | 0 | memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr)); |
221 | 0 | memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr)); |
222 | | |
223 | | // Quantization pass: All coefficients with index >= zero_flag are |
224 | | // skippable. Note: zero_flag can be zero. |
225 | 0 | for (int i = 0; i < n_coeffs; i++) { |
226 | 0 | const int rc = scan[i]; |
227 | 0 | const int coeff = coeff_ptr[rc]; |
228 | 0 | const int coeff_sign = AOMSIGN(coeff); |
229 | 0 | const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; |
230 | |
|
231 | 0 | int tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX); |
232 | 0 | tmp = (tmp * quant_ptr[rc != 0]) >> 16; |
233 | |
|
234 | 0 | qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign; |
235 | 0 | dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0]; |
236 | |
|
237 | 0 | if (tmp) eob = i; |
238 | 0 | } |
239 | 0 | *eob_ptr = eob + 1; |
240 | 0 | } |
241 | | |
242 | | void av1_quantize_fp_32x32_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, |
243 | | const int16_t *zbin_ptr, const int16_t *round_ptr, |
244 | | const int16_t *quant_ptr, |
245 | | const int16_t *quant_shift_ptr, |
246 | | tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, |
247 | | const int16_t *dequant_ptr, uint16_t *eob_ptr, |
248 | 653k | const int16_t *scan, const int16_t *iscan) { |
249 | 653k | quantize_fp_helper_c(coeff_ptr, n_coeffs, zbin_ptr, round_ptr, quant_ptr, |
250 | 653k | quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr, dequant_ptr, |
251 | 653k | eob_ptr, scan, iscan, NULL, NULL, 1); |
252 | 653k | } |
253 | | |
254 | | void av1_quantize_fp_64x64_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, |
255 | | const int16_t *zbin_ptr, const int16_t *round_ptr, |
256 | | const int16_t *quant_ptr, |
257 | | const int16_t *quant_shift_ptr, |
258 | | tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, |
259 | | const int16_t *dequant_ptr, uint16_t *eob_ptr, |
260 | 353k | const int16_t *scan, const int16_t *iscan) { |
261 | 353k | quantize_fp_helper_c(coeff_ptr, n_coeffs, zbin_ptr, round_ptr, quant_ptr, |
262 | 353k | quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr, dequant_ptr, |
263 | 353k | eob_ptr, scan, iscan, NULL, NULL, 2); |
264 | 353k | } |
265 | | |
266 | | void av1_quantize_fp_facade(const tran_low_t *coeff_ptr, intptr_t n_coeffs, |
267 | | const MACROBLOCK_PLANE *p, tran_low_t *qcoeff_ptr, |
268 | | tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr, |
269 | 3.50M | const SCAN_ORDER *sc, const QUANT_PARAM *qparam) { |
270 | 3.50M | const qm_val_t *qm_ptr = qparam->qmatrix; |
271 | 3.50M | const qm_val_t *iqm_ptr = qparam->iqmatrix; |
272 | 3.50M | if (qm_ptr != NULL && iqm_ptr != NULL) { |
273 | 0 | quantize_fp_helper_c(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_fp_QTX, |
274 | 0 | p->quant_fp_QTX, p->quant_shift_QTX, qcoeff_ptr, |
275 | 0 | dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan, |
276 | 0 | sc->iscan, qm_ptr, iqm_ptr, qparam->log_scale); |
277 | 3.50M | } else { |
278 | 3.50M | switch (qparam->log_scale) { |
279 | 2.50M | case 0: |
280 | 2.50M | av1_quantize_fp(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_fp_QTX, |
281 | 2.50M | p->quant_fp_QTX, p->quant_shift_QTX, qcoeff_ptr, |
282 | 2.50M | dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan, |
283 | 2.50M | sc->iscan); |
284 | 2.50M | break; |
285 | 653k | case 1: |
286 | 653k | av1_quantize_fp_32x32(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_fp_QTX, |
287 | 653k | p->quant_fp_QTX, p->quant_shift_QTX, qcoeff_ptr, |
288 | 653k | dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan, |
289 | 653k | sc->iscan); |
290 | 653k | break; |
291 | 353k | case 2: |
292 | 353k | av1_quantize_fp_64x64(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_fp_QTX, |
293 | 353k | p->quant_fp_QTX, p->quant_shift_QTX, qcoeff_ptr, |
294 | 353k | dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan, |
295 | 353k | sc->iscan); |
296 | 353k | break; |
297 | 0 | default: assert(0); |
298 | 3.50M | } |
299 | 3.50M | } |
300 | 3.50M | } |
301 | | |
302 | | void av1_quantize_b_facade(const tran_low_t *coeff_ptr, intptr_t n_coeffs, |
303 | | const MACROBLOCK_PLANE *p, tran_low_t *qcoeff_ptr, |
304 | | tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr, |
305 | 42.6M | const SCAN_ORDER *sc, const QUANT_PARAM *qparam) { |
306 | 42.6M | const qm_val_t *qm_ptr = qparam->qmatrix; |
307 | 42.6M | const qm_val_t *iqm_ptr = qparam->iqmatrix; |
308 | 42.6M | if (qparam->use_quant_b_adapt) { |
309 | | // TODO(sarahparker) These quantize_b optimizations need SIMD |
310 | | // implementations |
311 | 0 | if (qm_ptr != NULL && iqm_ptr != NULL) { |
312 | 0 | aom_quantize_b_adaptive_helper_c( |
313 | 0 | coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX, |
314 | 0 | p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, eob_ptr, |
315 | 0 | sc->scan, sc->iscan, qm_ptr, iqm_ptr, qparam->log_scale); |
316 | 0 | } else { |
317 | 0 | switch (qparam->log_scale) { |
318 | 0 | case 0: |
319 | 0 | aom_quantize_b_adaptive(coeff_ptr, n_coeffs, p->zbin_QTX, |
320 | 0 | p->round_QTX, p->quant_QTX, |
321 | 0 | p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, |
322 | 0 | p->dequant_QTX, eob_ptr, sc->scan, sc->iscan); |
323 | 0 | break; |
324 | 0 | case 1: |
325 | 0 | aom_quantize_b_32x32_adaptive( |
326 | 0 | coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX, |
327 | 0 | p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, |
328 | 0 | eob_ptr, sc->scan, sc->iscan); |
329 | 0 | break; |
330 | 0 | case 2: |
331 | 0 | aom_quantize_b_64x64_adaptive( |
332 | 0 | coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX, |
333 | 0 | p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, |
334 | 0 | eob_ptr, sc->scan, sc->iscan); |
335 | 0 | break; |
336 | 0 | default: assert(0); |
337 | 0 | } |
338 | 0 | } |
339 | 42.6M | } else { |
340 | 42.6M | if (qm_ptr != NULL && iqm_ptr != NULL) { |
341 | 0 | aom_quantize_b_helper_c(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, |
342 | 0 | p->quant_QTX, p->quant_shift_QTX, qcoeff_ptr, |
343 | 0 | dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan, |
344 | 0 | sc->iscan, qm_ptr, iqm_ptr, qparam->log_scale); |
345 | 42.6M | } else { |
346 | 42.6M | switch (qparam->log_scale) { |
347 | 42.6M | case 0: |
348 | 42.6M | aom_quantize_b(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, |
349 | 42.6M | p->quant_QTX, p->quant_shift_QTX, qcoeff_ptr, |
350 | 42.6M | dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan, |
351 | 42.6M | sc->iscan); |
352 | 42.6M | break; |
353 | 31.2k | case 1: |
354 | 31.2k | aom_quantize_b_32x32(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, |
355 | 31.2k | p->quant_QTX, p->quant_shift_QTX, qcoeff_ptr, |
356 | 31.2k | dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan, |
357 | 31.2k | sc->iscan); |
358 | 31.2k | break; |
359 | 11.1k | case 2: |
360 | 11.1k | aom_quantize_b_64x64(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, |
361 | 11.1k | p->quant_QTX, p->quant_shift_QTX, qcoeff_ptr, |
362 | 11.1k | dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan, |
363 | 11.1k | sc->iscan); |
364 | 11.1k | break; |
365 | 0 | default: assert(0); |
366 | 42.6M | } |
367 | 42.6M | } |
368 | 42.6M | } |
369 | 42.6M | } |
370 | | |
371 | | static void quantize_dc(const tran_low_t *coeff_ptr, int n_coeffs, |
372 | | int skip_block, const int16_t *round_ptr, |
373 | | const int16_t quant, tran_low_t *qcoeff_ptr, |
374 | | tran_low_t *dqcoeff_ptr, const int16_t dequant_ptr, |
375 | | uint16_t *eob_ptr, const qm_val_t *qm_ptr, |
376 | 0 | const qm_val_t *iqm_ptr, const int log_scale) { |
377 | 0 | const int rc = 0; |
378 | 0 | const int coeff = coeff_ptr[rc]; |
379 | 0 | const int coeff_sign = AOMSIGN(coeff); |
380 | 0 | const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; |
381 | 0 | int64_t tmp; |
382 | 0 | int eob = -1; |
383 | 0 | int32_t tmp32; |
384 | 0 | int dequant; |
385 | |
|
386 | 0 | memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr)); |
387 | 0 | memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr)); |
388 | |
|
389 | 0 | if (!skip_block) { |
390 | 0 | const int wt = qm_ptr != NULL ? qm_ptr[rc] : (1 << AOM_QM_BITS); |
391 | 0 | const int iwt = iqm_ptr != NULL ? iqm_ptr[rc] : (1 << AOM_QM_BITS); |
392 | 0 | tmp = clamp(abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], log_scale), |
393 | 0 | INT16_MIN, INT16_MAX); |
394 | 0 | tmp32 = (int32_t)((tmp * wt * quant) >> (16 - log_scale + AOM_QM_BITS)); |
395 | 0 | qcoeff_ptr[rc] = (tmp32 ^ coeff_sign) - coeff_sign; |
396 | 0 | dequant = (dequant_ptr * iwt + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS; |
397 | 0 | const tran_low_t abs_dqcoeff = (tmp32 * dequant) >> log_scale; |
398 | 0 | dqcoeff_ptr[rc] = (tran_low_t)((abs_dqcoeff ^ coeff_sign) - coeff_sign); |
399 | 0 | if (tmp32) eob = 0; |
400 | 0 | } |
401 | 0 | *eob_ptr = eob + 1; |
402 | 0 | } |
403 | | |
404 | | void av1_quantize_dc_facade(const tran_low_t *coeff_ptr, intptr_t n_coeffs, |
405 | | const MACROBLOCK_PLANE *p, tran_low_t *qcoeff_ptr, |
406 | | tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr, |
407 | 0 | const SCAN_ORDER *sc, const QUANT_PARAM *qparam) { |
408 | | // obsolete skip_block |
409 | 0 | const int skip_block = 0; |
410 | 0 | (void)sc; |
411 | 0 | assert(qparam->log_scale >= 0 && qparam->log_scale < (3)); |
412 | 0 | const qm_val_t *qm_ptr = qparam->qmatrix; |
413 | 0 | const qm_val_t *iqm_ptr = qparam->iqmatrix; |
414 | 0 | quantize_dc(coeff_ptr, (int)n_coeffs, skip_block, p->round_QTX, |
415 | 0 | p->quant_fp_QTX[0], qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX[0], |
416 | 0 | eob_ptr, qm_ptr, iqm_ptr, qparam->log_scale); |
417 | 0 | } |
418 | | |
419 | | #if CONFIG_AV1_HIGHBITDEPTH |
420 | | void av1_highbd_quantize_fp_facade(const tran_low_t *coeff_ptr, |
421 | | intptr_t n_coeffs, const MACROBLOCK_PLANE *p, |
422 | | tran_low_t *qcoeff_ptr, |
423 | | tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr, |
424 | | const SCAN_ORDER *sc, |
425 | 0 | const QUANT_PARAM *qparam) { |
426 | 0 | const qm_val_t *qm_ptr = qparam->qmatrix; |
427 | 0 | const qm_val_t *iqm_ptr = qparam->iqmatrix; |
428 | 0 | if (qm_ptr != NULL && iqm_ptr != NULL) { |
429 | 0 | highbd_quantize_fp_helper_c( |
430 | 0 | coeff_ptr, n_coeffs, p->zbin_QTX, p->round_fp_QTX, p->quant_fp_QTX, |
431 | 0 | p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, eob_ptr, |
432 | 0 | sc->scan, sc->iscan, qm_ptr, iqm_ptr, qparam->log_scale); |
433 | 0 | } else { |
434 | 0 | av1_highbd_quantize_fp(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_fp_QTX, |
435 | 0 | p->quant_fp_QTX, p->quant_shift_QTX, qcoeff_ptr, |
436 | 0 | dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan, |
437 | 0 | sc->iscan, qparam->log_scale); |
438 | 0 | } |
439 | 0 | } |
440 | | |
441 | | void av1_highbd_quantize_b_facade(const tran_low_t *coeff_ptr, |
442 | | intptr_t n_coeffs, const MACROBLOCK_PLANE *p, |
443 | | tran_low_t *qcoeff_ptr, |
444 | | tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr, |
445 | | const SCAN_ORDER *sc, |
446 | 0 | const QUANT_PARAM *qparam) { |
447 | 0 | const qm_val_t *qm_ptr = qparam->qmatrix; |
448 | 0 | const qm_val_t *iqm_ptr = qparam->iqmatrix; |
449 | 0 | if (qparam->use_quant_b_adapt) { |
450 | 0 | if (qm_ptr != NULL && iqm_ptr != NULL) { |
451 | 0 | aom_highbd_quantize_b_adaptive_helper_c( |
452 | 0 | coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX, |
453 | 0 | p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, eob_ptr, |
454 | 0 | sc->scan, sc->iscan, qm_ptr, iqm_ptr, qparam->log_scale); |
455 | 0 | } else { |
456 | 0 | switch (qparam->log_scale) { |
457 | 0 | case 0: |
458 | 0 | aom_highbd_quantize_b_adaptive( |
459 | 0 | coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX, |
460 | 0 | p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, |
461 | 0 | eob_ptr, sc->scan, sc->iscan); |
462 | 0 | break; |
463 | 0 | case 1: |
464 | 0 | aom_highbd_quantize_b_32x32_adaptive( |
465 | 0 | coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX, |
466 | 0 | p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, |
467 | 0 | eob_ptr, sc->scan, sc->iscan); |
468 | 0 | break; |
469 | 0 | case 2: |
470 | 0 | aom_highbd_quantize_b_64x64_adaptive( |
471 | 0 | coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX, |
472 | 0 | p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, |
473 | 0 | eob_ptr, sc->scan, sc->iscan); |
474 | 0 | break; |
475 | 0 | default: assert(0); |
476 | 0 | } |
477 | 0 | } |
478 | 0 | } else { |
479 | 0 | if (qm_ptr != NULL && iqm_ptr != NULL) { |
480 | 0 | aom_highbd_quantize_b_helper_c( |
481 | 0 | coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX, |
482 | 0 | p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, eob_ptr, |
483 | 0 | sc->scan, sc->iscan, qm_ptr, iqm_ptr, qparam->log_scale); |
484 | 0 | } else { |
485 | 0 | switch (qparam->log_scale) { |
486 | 0 | case 0: |
487 | 0 | aom_highbd_quantize_b(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, |
488 | 0 | p->quant_QTX, p->quant_shift_QTX, qcoeff_ptr, |
489 | 0 | dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan, |
490 | 0 | sc->iscan); |
491 | 0 | break; |
492 | 0 | case 1: |
493 | 0 | aom_highbd_quantize_b_32x32( |
494 | 0 | coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX, |
495 | 0 | p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, |
496 | 0 | eob_ptr, sc->scan, sc->iscan); |
497 | 0 | break; |
498 | 0 | case 2: |
499 | 0 | aom_highbd_quantize_b_64x64( |
500 | 0 | coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX, |
501 | 0 | p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, |
502 | 0 | eob_ptr, sc->scan, sc->iscan); |
503 | 0 | break; |
504 | 0 | default: assert(0); |
505 | 0 | } |
506 | 0 | } |
507 | 0 | } |
508 | 0 | } |
509 | | |
510 | | static INLINE void highbd_quantize_dc( |
511 | | const tran_low_t *coeff_ptr, int n_coeffs, int skip_block, |
512 | | const int16_t *round_ptr, const int16_t quant, tran_low_t *qcoeff_ptr, |
513 | | tran_low_t *dqcoeff_ptr, const int16_t dequant_ptr, uint16_t *eob_ptr, |
514 | 0 | const qm_val_t *qm_ptr, const qm_val_t *iqm_ptr, const int log_scale) { |
515 | 0 | int eob = -1; |
516 | |
|
517 | 0 | memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr)); |
518 | 0 | memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr)); |
519 | |
|
520 | 0 | if (!skip_block) { |
521 | 0 | const qm_val_t wt = qm_ptr != NULL ? qm_ptr[0] : (1 << AOM_QM_BITS); |
522 | 0 | const qm_val_t iwt = iqm_ptr != NULL ? iqm_ptr[0] : (1 << AOM_QM_BITS); |
523 | 0 | const int coeff = coeff_ptr[0]; |
524 | 0 | const int coeff_sign = AOMSIGN(coeff); |
525 | 0 | const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; |
526 | 0 | const int64_t tmp = abs_coeff + ROUND_POWER_OF_TWO(round_ptr[0], log_scale); |
527 | 0 | const int64_t tmpw = tmp * wt; |
528 | 0 | const int abs_qcoeff = |
529 | 0 | (int)((tmpw * quant) >> (16 - log_scale + AOM_QM_BITS)); |
530 | 0 | qcoeff_ptr[0] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign); |
531 | 0 | const int dequant = |
532 | 0 | (dequant_ptr * iwt + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS; |
533 | |
|
534 | 0 | const tran_low_t abs_dqcoeff = (abs_qcoeff * dequant) >> log_scale; |
535 | 0 | dqcoeff_ptr[0] = (tran_low_t)((abs_dqcoeff ^ coeff_sign) - coeff_sign); |
536 | 0 | if (abs_qcoeff) eob = 0; |
537 | 0 | } |
538 | 0 | *eob_ptr = eob + 1; |
539 | 0 | } |
540 | | |
541 | | void av1_highbd_quantize_dc_facade(const tran_low_t *coeff_ptr, |
542 | | intptr_t n_coeffs, const MACROBLOCK_PLANE *p, |
543 | | tran_low_t *qcoeff_ptr, |
544 | | tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr, |
545 | | const SCAN_ORDER *sc, |
546 | 0 | const QUANT_PARAM *qparam) { |
547 | | // obsolete skip_block |
548 | 0 | const int skip_block = 0; |
549 | 0 | const qm_val_t *qm_ptr = qparam->qmatrix; |
550 | 0 | const qm_val_t *iqm_ptr = qparam->iqmatrix; |
551 | 0 | (void)sc; |
552 | |
|
553 | 0 | highbd_quantize_dc(coeff_ptr, (int)n_coeffs, skip_block, p->round_QTX, |
554 | 0 | p->quant_fp_QTX[0], qcoeff_ptr, dqcoeff_ptr, |
555 | 0 | p->dequant_QTX[0], eob_ptr, qm_ptr, iqm_ptr, |
556 | 0 | qparam->log_scale); |
557 | 0 | } |
558 | | |
559 | | void av1_highbd_quantize_fp_c(const tran_low_t *coeff_ptr, intptr_t count, |
560 | | const int16_t *zbin_ptr, const int16_t *round_ptr, |
561 | | const int16_t *quant_ptr, |
562 | | const int16_t *quant_shift_ptr, |
563 | | tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, |
564 | | const int16_t *dequant_ptr, uint16_t *eob_ptr, |
565 | | const int16_t *scan, const int16_t *iscan, |
566 | 0 | int log_scale) { |
567 | 0 | highbd_quantize_fp_helper_c(coeff_ptr, count, zbin_ptr, round_ptr, quant_ptr, |
568 | 0 | quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr, |
569 | 0 | dequant_ptr, eob_ptr, scan, iscan, NULL, NULL, |
570 | 0 | log_scale); |
571 | 0 | } |
572 | | #endif // CONFIG_AV1_HIGHBITDEPTH |
573 | | |
574 | 3.87M | static void invert_quant(int16_t *quant, int16_t *shift, int d) { |
575 | 3.87M | uint32_t t; |
576 | 3.87M | int l, m; |
577 | 3.87M | t = d; |
578 | 30.2M | for (l = 0; t > 1; l++) t >>= 1; |
579 | 3.87M | m = 1 + (1 << (16 + l)) / d; |
580 | 3.87M | *quant = (int16_t)(m - (1 << 16)); |
581 | 3.87M | *shift = 1 << (16 - l); |
582 | 3.87M | } |
583 | | |
584 | 646k | static int get_qzbin_factor(int q, aom_bit_depth_t bit_depth) { |
585 | 646k | const int quant = av1_dc_quant_QTX(q, 0, bit_depth); |
586 | 646k | switch (bit_depth) { |
587 | 646k | case AOM_BITS_8: return q == 0 ? 64 : (quant < 148 ? 84 : 80); |
588 | 0 | case AOM_BITS_10: return q == 0 ? 64 : (quant < 592 ? 84 : 80); |
589 | 0 | case AOM_BITS_12: return q == 0 ? 64 : (quant < 2368 ? 84 : 80); |
590 | 0 | default: |
591 | 0 | assert(0 && "bit_depth should be AOM_BITS_8, AOM_BITS_10 or AOM_BITS_12"); |
592 | 0 | return -1; |
593 | 646k | } |
594 | 646k | } |
595 | | |
596 | | void av1_build_quantizer(aom_bit_depth_t bit_depth, int y_dc_delta_q, |
597 | | int u_dc_delta_q, int u_ac_delta_q, int v_dc_delta_q, |
598 | | int v_ac_delta_q, QUANTS *const quants, |
599 | 2.52k | Dequants *const deq) { |
600 | 2.52k | int i, q, quant_QTX; |
601 | | |
602 | 648k | for (q = 0; q < QINDEX_RANGE; q++) { |
603 | 646k | const int qzbin_factor = get_qzbin_factor(q, bit_depth); |
604 | 646k | const int qrounding_factor = q == 0 ? 64 : 48; |
605 | | |
606 | 1.93M | for (i = 0; i < 2; ++i) { |
607 | 1.29M | const int qrounding_factor_fp = 64; |
608 | | // y quantizer with TX scale |
609 | 1.29M | quant_QTX = i == 0 ? av1_dc_quant_QTX(q, y_dc_delta_q, bit_depth) |
610 | 1.29M | : av1_ac_quant_QTX(q, 0, bit_depth); |
611 | 1.29M | invert_quant(&quants->y_quant[q][i], &quants->y_quant_shift[q][i], |
612 | 1.29M | quant_QTX); |
613 | 1.29M | quants->y_quant_fp[q][i] = (1 << 16) / quant_QTX; |
614 | 1.29M | quants->y_round_fp[q][i] = (qrounding_factor_fp * quant_QTX) >> 7; |
615 | 1.29M | quants->y_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant_QTX, 7); |
616 | 1.29M | quants->y_round[q][i] = (qrounding_factor * quant_QTX) >> 7; |
617 | 1.29M | deq->y_dequant_QTX[q][i] = quant_QTX; |
618 | | |
619 | | // u quantizer with TX scale |
620 | 1.29M | quant_QTX = i == 0 ? av1_dc_quant_QTX(q, u_dc_delta_q, bit_depth) |
621 | 1.29M | : av1_ac_quant_QTX(q, u_ac_delta_q, bit_depth); |
622 | 1.29M | invert_quant(&quants->u_quant[q][i], &quants->u_quant_shift[q][i], |
623 | 1.29M | quant_QTX); |
624 | 1.29M | quants->u_quant_fp[q][i] = (1 << 16) / quant_QTX; |
625 | 1.29M | quants->u_round_fp[q][i] = (qrounding_factor_fp * quant_QTX) >> 7; |
626 | 1.29M | quants->u_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant_QTX, 7); |
627 | 1.29M | quants->u_round[q][i] = (qrounding_factor * quant_QTX) >> 7; |
628 | 1.29M | deq->u_dequant_QTX[q][i] = quant_QTX; |
629 | | |
630 | | // v quantizer with TX scale |
631 | 1.29M | quant_QTX = i == 0 ? av1_dc_quant_QTX(q, v_dc_delta_q, bit_depth) |
632 | 1.29M | : av1_ac_quant_QTX(q, v_ac_delta_q, bit_depth); |
633 | 1.29M | invert_quant(&quants->v_quant[q][i], &quants->v_quant_shift[q][i], |
634 | 1.29M | quant_QTX); |
635 | 1.29M | quants->v_quant_fp[q][i] = (1 << 16) / quant_QTX; |
636 | 1.29M | quants->v_round_fp[q][i] = (qrounding_factor_fp * quant_QTX) >> 7; |
637 | 1.29M | quants->v_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant_QTX, 7); |
638 | 1.29M | quants->v_round[q][i] = (qrounding_factor * quant_QTX) >> 7; |
639 | 1.29M | deq->v_dequant_QTX[q][i] = quant_QTX; |
640 | 1.29M | } |
641 | | |
642 | 4.52M | for (i = 2; i < 8; i++) { // 8: SIMD width |
643 | 3.87M | quants->y_quant[q][i] = quants->y_quant[q][1]; |
644 | 3.87M | quants->y_quant_fp[q][i] = quants->y_quant_fp[q][1]; |
645 | 3.87M | quants->y_round_fp[q][i] = quants->y_round_fp[q][1]; |
646 | 3.87M | quants->y_quant_shift[q][i] = quants->y_quant_shift[q][1]; |
647 | 3.87M | quants->y_zbin[q][i] = quants->y_zbin[q][1]; |
648 | 3.87M | quants->y_round[q][i] = quants->y_round[q][1]; |
649 | 3.87M | deq->y_dequant_QTX[q][i] = deq->y_dequant_QTX[q][1]; |
650 | | |
651 | 3.87M | quants->u_quant[q][i] = quants->u_quant[q][1]; |
652 | 3.87M | quants->u_quant_fp[q][i] = quants->u_quant_fp[q][1]; |
653 | 3.87M | quants->u_round_fp[q][i] = quants->u_round_fp[q][1]; |
654 | 3.87M | quants->u_quant_shift[q][i] = quants->u_quant_shift[q][1]; |
655 | 3.87M | quants->u_zbin[q][i] = quants->u_zbin[q][1]; |
656 | 3.87M | quants->u_round[q][i] = quants->u_round[q][1]; |
657 | 3.87M | deq->u_dequant_QTX[q][i] = deq->u_dequant_QTX[q][1]; |
658 | | |
659 | 3.87M | quants->v_quant[q][i] = quants->v_quant[q][1]; |
660 | 3.87M | quants->v_quant_fp[q][i] = quants->v_quant_fp[q][1]; |
661 | 3.87M | quants->v_round_fp[q][i] = quants->v_round_fp[q][1]; |
662 | 3.87M | quants->v_quant_shift[q][i] = quants->v_quant_shift[q][1]; |
663 | 3.87M | quants->v_zbin[q][i] = quants->v_zbin[q][1]; |
664 | 3.87M | quants->v_round[q][i] = quants->v_round[q][1]; |
665 | 3.87M | deq->v_dequant_QTX[q][i] = deq->v_dequant_QTX[q][1]; |
666 | 3.87M | } |
667 | 646k | } |
668 | 2.52k | } |
669 | | |
670 | | void av1_init_quantizer(EncQuantDequantParams *const enc_quant_dequant_params, |
671 | | const CommonQuantParams *quant_params, |
672 | 2.52k | aom_bit_depth_t bit_depth) { |
673 | 2.52k | QUANTS *const quants = &enc_quant_dequant_params->quants; |
674 | 2.52k | Dequants *const dequants = &enc_quant_dequant_params->dequants; |
675 | 2.52k | av1_build_quantizer(bit_depth, quant_params->y_dc_delta_q, |
676 | 2.52k | quant_params->u_dc_delta_q, quant_params->u_ac_delta_q, |
677 | 2.52k | quant_params->v_dc_delta_q, quant_params->v_ac_delta_q, |
678 | 2.52k | quants, dequants); |
679 | 2.52k | } |
680 | | |
681 | | void av1_set_q_index(const EncQuantDequantParams *enc_quant_dequant_params, |
682 | 1.26k | int qindex, MACROBLOCK *x) { |
683 | 1.26k | const QUANTS *const quants = &enc_quant_dequant_params->quants; |
684 | 1.26k | const Dequants *const dequants = &enc_quant_dequant_params->dequants; |
685 | 1.26k | x->qindex = qindex; |
686 | 1.26k | x->seg_skip_block = |
687 | 1.26k | 0; // TODO(angiebird): Find a proper place to init this variable. |
688 | | |
689 | | // Y |
690 | 1.26k | x->plane[0].quant_QTX = quants->y_quant[qindex]; |
691 | 1.26k | x->plane[0].quant_fp_QTX = quants->y_quant_fp[qindex]; |
692 | 1.26k | x->plane[0].round_fp_QTX = quants->y_round_fp[qindex]; |
693 | 1.26k | x->plane[0].quant_shift_QTX = quants->y_quant_shift[qindex]; |
694 | 1.26k | x->plane[0].zbin_QTX = quants->y_zbin[qindex]; |
695 | 1.26k | x->plane[0].round_QTX = quants->y_round[qindex]; |
696 | 1.26k | x->plane[0].dequant_QTX = dequants->y_dequant_QTX[qindex]; |
697 | | |
698 | | // U |
699 | 1.26k | x->plane[1].quant_QTX = quants->u_quant[qindex]; |
700 | 1.26k | x->plane[1].quant_fp_QTX = quants->u_quant_fp[qindex]; |
701 | 1.26k | x->plane[1].round_fp_QTX = quants->u_round_fp[qindex]; |
702 | 1.26k | x->plane[1].quant_shift_QTX = quants->u_quant_shift[qindex]; |
703 | 1.26k | x->plane[1].zbin_QTX = quants->u_zbin[qindex]; |
704 | 1.26k | x->plane[1].round_QTX = quants->u_round[qindex]; |
705 | 1.26k | x->plane[1].dequant_QTX = dequants->u_dequant_QTX[qindex]; |
706 | | |
707 | | // V |
708 | 1.26k | x->plane[2].quant_QTX = quants->v_quant[qindex]; |
709 | 1.26k | x->plane[2].quant_fp_QTX = quants->v_quant_fp[qindex]; |
710 | 1.26k | x->plane[2].round_fp_QTX = quants->v_round_fp[qindex]; |
711 | 1.26k | x->plane[2].quant_shift_QTX = quants->v_quant_shift[qindex]; |
712 | 1.26k | x->plane[2].zbin_QTX = quants->v_zbin[qindex]; |
713 | 1.26k | x->plane[2].round_QTX = quants->v_round[qindex]; |
714 | 1.26k | x->plane[2].dequant_QTX = dequants->v_dequant_QTX[qindex]; |
715 | 1.26k | } |
716 | | |
717 | | void av1_set_qmatrix(const CommonQuantParams *quant_params, int segment_id, |
718 | 1.26k | MACROBLOCKD *xd) { |
719 | 1.26k | const int use_qmatrix = av1_use_qmatrix(quant_params, xd, segment_id); |
720 | 1.26k | const int qmlevel_y = |
721 | 1.26k | use_qmatrix ? quant_params->qmatrix_level_y : NUM_QM_LEVELS - 1; |
722 | 1.26k | const int qmlevel_u = |
723 | 1.26k | use_qmatrix ? quant_params->qmatrix_level_u : NUM_QM_LEVELS - 1; |
724 | 1.26k | const int qmlevel_v = |
725 | 1.26k | use_qmatrix ? quant_params->qmatrix_level_v : NUM_QM_LEVELS - 1; |
726 | 1.26k | const int qmlevel_ls[MAX_MB_PLANE] = { qmlevel_y, qmlevel_u, qmlevel_v }; |
727 | 5.04k | for (int i = 0; i < MAX_MB_PLANE; ++i) { |
728 | 3.78k | const int qmlevel = qmlevel_ls[i]; |
729 | 3.78k | memcpy(&xd->plane[i].seg_qmatrix[segment_id], |
730 | 3.78k | quant_params->gqmatrix[qmlevel][i], |
731 | 3.78k | sizeof(quant_params->gqmatrix[qmlevel][i])); |
732 | 3.78k | memcpy(&xd->plane[i].seg_iqmatrix[segment_id], |
733 | 3.78k | quant_params->giqmatrix[qmlevel][i], |
734 | 3.78k | sizeof(quant_params->giqmatrix[qmlevel][i])); |
735 | 3.78k | } |
736 | 1.26k | } |
737 | | |
738 | | void av1_init_plane_quantizers(const AV1_COMP *cpi, MACROBLOCK *x, |
739 | 1.26k | int segment_id) { |
740 | 1.26k | const AV1_COMMON *const cm = &cpi->common; |
741 | 1.26k | const CommonQuantParams *const quant_params = &cm->quant_params; |
742 | 1.26k | const int current_qindex = AOMMAX( |
743 | 1.26k | 0, |
744 | 1.26k | AOMMIN(QINDEX_RANGE - 1, cm->delta_q_info.delta_q_present_flag |
745 | 1.26k | ? quant_params->base_qindex + x->delta_qindex |
746 | 1.26k | : quant_params->base_qindex)); |
747 | 1.26k | const int qindex = av1_get_qindex(&cm->seg, segment_id, current_qindex); |
748 | 1.26k | const int rdmult = |
749 | 1.26k | av1_compute_rd_mult(cpi, qindex + quant_params->y_dc_delta_q); |
750 | 1.26k | av1_set_q_index(&cpi->enc_quant_dequant_params, qindex, x); |
751 | | |
752 | 1.26k | MACROBLOCKD *const xd = &x->e_mbd; |
753 | 1.26k | av1_set_qmatrix(quant_params, segment_id, xd); |
754 | | |
755 | 1.26k | x->seg_skip_block = segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP); |
756 | | |
757 | 1.26k | av1_set_error_per_bit(&x->errorperbit, rdmult); |
758 | 1.26k | av1_set_sad_per_bit(cpi, &x->sadperbit, qindex); |
759 | 1.26k | } |
760 | | |
761 | 1.26k | void av1_frame_init_quantizer(AV1_COMP *cpi) { |
762 | 1.26k | MACROBLOCK *const x = &cpi->td.mb; |
763 | 1.26k | MACROBLOCKD *const xd = &x->e_mbd; |
764 | 1.26k | av1_init_plane_quantizers(cpi, x, xd->mi[0]->segment_id); |
765 | 1.26k | } |
766 | | |
767 | 0 | static int adjust_hdr_cb_deltaq(int base_qindex) { |
768 | 0 | double baseQp = base_qindex / QP_SCALE_FACTOR; |
769 | 0 | const double chromaQp = CHROMA_QP_SCALE * baseQp + CHROMA_QP_OFFSET; |
770 | 0 | const double dcbQP = CHROMA_CB_QP_SCALE * chromaQp * QP_SCALE_FACTOR; |
771 | 0 | int dqpCb = (int)(dcbQP + (dcbQP < 0 ? -0.5 : 0.5)); |
772 | 0 | dqpCb = AOMMIN(0, dqpCb); |
773 | 0 | dqpCb = (int)CLIP(dqpCb, -12 * QP_SCALE_FACTOR, 12 * QP_SCALE_FACTOR); |
774 | 0 | return dqpCb; |
775 | 0 | } |
776 | | |
777 | 0 | static int adjust_hdr_cr_deltaq(int base_qindex) { |
778 | 0 | double baseQp = base_qindex / QP_SCALE_FACTOR; |
779 | 0 | const double chromaQp = CHROMA_QP_SCALE * baseQp + CHROMA_QP_OFFSET; |
780 | 0 | const double dcrQP = CHROMA_CR_QP_SCALE * chromaQp * QP_SCALE_FACTOR; |
781 | 0 | int dqpCr = (int)(dcrQP + (dcrQP < 0 ? -0.5 : 0.5)); |
782 | 0 | dqpCr = AOMMIN(0, dqpCr); |
783 | 0 | dqpCr = (int)CLIP(dqpCr, -12 * QP_SCALE_FACTOR, 12 * QP_SCALE_FACTOR); |
784 | 0 | return dqpCr; |
785 | 0 | } |
786 | | |
787 | | void av1_set_quantizer(AV1_COMMON *const cm, int min_qmlevel, int max_qmlevel, |
788 | 1.26k | int q, int enable_chroma_deltaq, int enable_hdr_deltaq) { |
789 | | // quantizer has to be reinitialized with av1_init_quantizer() if any |
790 | | // delta_q changes. |
791 | 1.26k | CommonQuantParams *quant_params = &cm->quant_params; |
792 | 1.26k | quant_params->base_qindex = AOMMAX(cm->delta_q_info.delta_q_present_flag, q); |
793 | 1.26k | quant_params->y_dc_delta_q = 0; |
794 | | |
795 | 1.26k | if (enable_chroma_deltaq) { |
796 | | // TODO(aomedia:2717): need to design better delta |
797 | 0 | quant_params->u_dc_delta_q = 2; |
798 | 0 | quant_params->u_ac_delta_q = 2; |
799 | 0 | quant_params->v_dc_delta_q = 2; |
800 | 0 | quant_params->v_ac_delta_q = 2; |
801 | 1.26k | } else { |
802 | 1.26k | quant_params->u_dc_delta_q = 0; |
803 | 1.26k | quant_params->u_ac_delta_q = 0; |
804 | 1.26k | quant_params->v_dc_delta_q = 0; |
805 | 1.26k | quant_params->v_ac_delta_q = 0; |
806 | 1.26k | } |
807 | | |
808 | | // following section 8.3.2 in T-REC-H.Sup15 document |
809 | | // to apply to AV1 qindex in the range of [0, 255] |
810 | 1.26k | if (enable_hdr_deltaq) { |
811 | 0 | int dqpCb = adjust_hdr_cb_deltaq(quant_params->base_qindex); |
812 | 0 | int dqpCr = adjust_hdr_cr_deltaq(quant_params->base_qindex); |
813 | 0 | quant_params->u_dc_delta_q = quant_params->u_ac_delta_q = dqpCb; |
814 | 0 | quant_params->v_dc_delta_q = quant_params->v_ac_delta_q = dqpCr; |
815 | 0 | if (dqpCb != dqpCr) { |
816 | 0 | cm->seq_params->separate_uv_delta_q = 1; |
817 | 0 | } |
818 | 0 | } |
819 | | |
820 | 1.26k | quant_params->qmatrix_level_y = |
821 | 1.26k | aom_get_qmlevel(quant_params->base_qindex, min_qmlevel, max_qmlevel); |
822 | 1.26k | quant_params->qmatrix_level_u = |
823 | 1.26k | aom_get_qmlevel(quant_params->base_qindex + quant_params->u_ac_delta_q, |
824 | 1.26k | min_qmlevel, max_qmlevel); |
825 | | |
826 | 1.26k | if (!cm->seq_params->separate_uv_delta_q) |
827 | 1.26k | quant_params->qmatrix_level_v = quant_params->qmatrix_level_u; |
828 | 0 | else |
829 | 0 | quant_params->qmatrix_level_v = |
830 | 0 | aom_get_qmlevel(quant_params->base_qindex + quant_params->v_ac_delta_q, |
831 | 0 | min_qmlevel, max_qmlevel); |
832 | 1.26k | } |
833 | | |
834 | | // Table that converts 0-63 Q-range values passed in outside to the Qindex |
835 | | // range used internally. |
836 | | static const int quantizer_to_qindex[] = { |
837 | | 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, |
838 | | 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, |
839 | | 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 148, 152, |
840 | | 156, 160, 164, 168, 172, 176, 180, 184, 188, 192, 196, 200, 204, |
841 | | 208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 249, 255, |
842 | | }; |
843 | | |
844 | 38.0k | int av1_quantizer_to_qindex(int quantizer) { |
845 | 38.0k | return quantizer_to_qindex[quantizer]; |
846 | 38.0k | } |
847 | | |
848 | 0 | int av1_qindex_to_quantizer(int qindex) { |
849 | 0 | int quantizer; |
850 | |
|
851 | 0 | for (quantizer = 0; quantizer < 64; ++quantizer) |
852 | 0 | if (quantizer_to_qindex[quantizer] >= qindex) return quantizer; |
853 | | |
854 | 0 | return 63; |
855 | 0 | } |