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