Line data Source code
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 "aom_dsp/quantize.h"
13 : #include "aom_mem/aom_mem.h"
14 :
15 0 : static void 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,
18 : const int16_t *quant_ptr,
19 : const int16_t *quant_shift_ptr,
20 : tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
21 : const int16_t *dequant_ptr, uint16_t *eob_ptr,
22 : const int16_t *scan, const int16_t *iscan,
23 : #if CONFIG_AOM_QM
24 : const qm_val_t *qm_ptr, const qm_val_t *iqm_ptr,
25 : #endif
26 : const int log_scale) {
27 0 : const int zbins[2] = { ROUND_POWER_OF_TWO(zbin_ptr[0], log_scale),
28 0 : ROUND_POWER_OF_TWO(zbin_ptr[1], log_scale) };
29 0 : const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
30 0 : int i, non_zero_count = (int)n_coeffs, eob = -1;
31 : (void)iscan;
32 :
33 0 : memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
34 0 : memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
35 :
36 0 : if (!skip_block) {
37 : // Pre-scan pass
38 0 : for (i = (int)n_coeffs - 1; i >= 0; i--) {
39 0 : const int rc = scan[i];
40 : #if CONFIG_AOM_QM
41 : const qm_val_t wt = qm_ptr[rc];
42 : const int coeff = coeff_ptr[rc] * wt;
43 : #else
44 0 : const int coeff = coeff_ptr[rc];
45 : #endif // CONFIG_AOM_QM
46 :
47 : #if CONFIG_AOM_QM
48 : if (coeff < (zbins[rc != 0] << AOM_QM_BITS) &&
49 : coeff > (nzbins[rc != 0] << AOM_QM_BITS))
50 : non_zero_count--;
51 : #else
52 0 : if (coeff < zbins[rc != 0] && coeff > nzbins[rc != 0]) non_zero_count--;
53 : #endif // CONFIG_AOM_QM
54 : else
55 : break;
56 : }
57 :
58 : // Quantization pass: All coefficients with index >= zero_flag are
59 : // skippable. Note: zero_flag can be zero.
60 0 : for (i = 0; i < non_zero_count; i++) {
61 0 : const int rc = scan[i];
62 0 : const int coeff = coeff_ptr[rc];
63 0 : const int coeff_sign = (coeff >> 31);
64 0 : const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
65 : int tmp32;
66 :
67 : #if CONFIG_AOM_QM
68 : const qm_val_t wt = qm_ptr[rc];
69 : if (abs_coeff * wt >= (zbins[rc != 0] << AOM_QM_BITS)) {
70 : #else
71 0 : if (abs_coeff >= zbins[rc != 0]) {
72 : #endif // CONFIG_AOM_QM
73 0 : int64_t tmp =
74 0 : clamp(abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], log_scale),
75 : INT16_MIN, INT16_MAX);
76 : #if CONFIG_AOM_QM
77 : tmp *= wt;
78 : tmp32 = (int)(((((tmp * quant_ptr[rc != 0]) >> 16) + tmp) *
79 : quant_shift_ptr[rc != 0]) >>
80 : (16 - log_scale + AOM_QM_BITS)); // quantization
81 : #else
82 0 : tmp32 = (int)(((((tmp * quant_ptr[rc != 0]) >> 16) + tmp) *
83 0 : quant_shift_ptr[rc != 0]) >>
84 0 : (16 - log_scale)); // quantization
85 : #endif // CONFIG_AOM_QM
86 0 : qcoeff_ptr[rc] = (tmp32 ^ coeff_sign) - coeff_sign;
87 : #if CONFIG_AOM_QM
88 : const int dequant =
89 : (dequant_ptr[rc != 0] * iqm_ptr[rc] + (1 << (AOM_QM_BITS - 1))) >>
90 : AOM_QM_BITS;
91 : dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant / (1 << log_scale);
92 : #else
93 0 : dqcoeff_ptr[rc] =
94 0 : qcoeff_ptr[rc] * dequant_ptr[rc != 0] / (1 << log_scale);
95 : #endif // CONFIG_AOM_QM
96 :
97 0 : if (tmp32) eob = i;
98 : }
99 : }
100 : }
101 0 : *eob_ptr = eob + 1;
102 0 : }
103 :
104 0 : void aom_quantize_b_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
105 : int skip_block, const int16_t *zbin_ptr,
106 : const int16_t *round_ptr, const int16_t *quant_ptr,
107 : const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
108 : tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr,
109 : uint16_t *eob_ptr, const int16_t *scan,
110 : const int16_t *iscan
111 : #if CONFIG_AOM_QM
112 : ,
113 : const qm_val_t *qm_ptr, const qm_val_t *iqm_ptr
114 : #endif
115 : ) {
116 0 : quantize_b_helper_c(coeff_ptr, n_coeffs, skip_block, zbin_ptr, round_ptr,
117 : quant_ptr, quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr,
118 : dequant_ptr, eob_ptr, scan, iscan,
119 : #if CONFIG_AOM_QM
120 : qm_ptr, iqm_ptr,
121 : #endif
122 : 0);
123 0 : }
124 :
125 0 : void aom_quantize_b_32x32_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
126 : int skip_block, const int16_t *zbin_ptr,
127 : const int16_t *round_ptr, const int16_t *quant_ptr,
128 : const int16_t *quant_shift_ptr,
129 : tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
130 : const int16_t *dequant_ptr, uint16_t *eob_ptr,
131 : const int16_t *scan, const int16_t *iscan
132 : #if CONFIG_AOM_QM
133 : ,
134 : const qm_val_t *qm_ptr, const qm_val_t *iqm_ptr
135 : #endif
136 : ) {
137 0 : quantize_b_helper_c(coeff_ptr, n_coeffs, skip_block, zbin_ptr, round_ptr,
138 : quant_ptr, quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr,
139 : dequant_ptr, eob_ptr, scan, iscan,
140 : #if CONFIG_AOM_QM
141 : qm_ptr, iqm_ptr,
142 : #endif
143 : 1);
144 0 : }
145 :
146 : #if CONFIG_TX64X64
147 : void aom_quantize_b_64x64_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
148 : int skip_block, const int16_t *zbin_ptr,
149 : const int16_t *round_ptr, const int16_t *quant_ptr,
150 : const int16_t *quant_shift_ptr,
151 : tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
152 : const int16_t *dequant_ptr, uint16_t *eob_ptr,
153 : const int16_t *scan, const int16_t *iscan
154 : #if CONFIG_AOM_QM
155 : ,
156 : const qm_val_t *qm_ptr, const qm_val_t *iqm_ptr
157 : #endif
158 : ) {
159 : quantize_b_helper_c(coeff_ptr, n_coeffs, skip_block, zbin_ptr, round_ptr,
160 : quant_ptr, quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr,
161 : dequant_ptr, eob_ptr, scan, iscan,
162 : #if CONFIG_AOM_QM
163 : qm_ptr, iqm_ptr,
164 : #endif
165 : 2);
166 : }
167 : #endif // CONFIG_TX64X64
168 :
169 : #if CONFIG_AOM_QM
170 : void aom_quantize_dc(const tran_low_t *coeff_ptr, int n_coeffs, int skip_block,
171 : const int16_t *round_ptr, const int16_t quant,
172 : tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
173 : const int16_t dequant_ptr, uint16_t *eob_ptr,
174 : const qm_val_t *qm_ptr, const qm_val_t *iqm_ptr) {
175 : const int rc = 0;
176 : const int coeff = coeff_ptr[rc];
177 : const int coeff_sign = (coeff >> 31);
178 : const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
179 : int64_t tmp, eob = -1;
180 : int32_t tmp32;
181 : int dequant =
182 : (dequant_ptr * iqm_ptr[rc] + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS;
183 :
184 : memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
185 : memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
186 :
187 : if (!skip_block) {
188 : tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX);
189 : tmp32 = (int32_t)((tmp * qm_ptr[rc] * quant) >> (16 + AOM_QM_BITS));
190 : qcoeff_ptr[rc] = (tmp32 ^ coeff_sign) - coeff_sign;
191 : dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant;
192 : if (tmp32) eob = 0;
193 : }
194 : *eob_ptr = eob + 1;
195 : }
196 :
197 : void aom_quantize_dc_32x32(const tran_low_t *coeff_ptr, int skip_block,
198 : const int16_t *round_ptr, const int16_t quant,
199 : tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
200 : const int16_t dequant_ptr, uint16_t *eob_ptr,
201 : const qm_val_t *qm_ptr, const qm_val_t *iqm_ptr) {
202 : const int n_coeffs = 1024;
203 : const int rc = 0;
204 : const int coeff = coeff_ptr[rc];
205 : const int coeff_sign = (coeff >> 31);
206 : const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
207 : int64_t tmp, eob = -1;
208 : int32_t tmp32;
209 : int dequant;
210 :
211 : memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
212 : memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
213 :
214 : if (!skip_block) {
215 : tmp = clamp(abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1),
216 : INT16_MIN, INT16_MAX);
217 : tmp32 = (int32_t)((tmp * qm_ptr[rc] * quant) >> (15 + AOM_QM_BITS));
218 : qcoeff_ptr[rc] = (tmp32 ^ coeff_sign) - coeff_sign;
219 : dequant =
220 : (dequant_ptr * iqm_ptr[rc] + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS;
221 : dqcoeff_ptr[rc] = (qcoeff_ptr[rc] * dequant) / 2;
222 : if (tmp32) eob = 0;
223 : }
224 : *eob_ptr = eob + 1;
225 : }
226 :
227 : #if CONFIG_TX64X64
228 : void aom_quantize_dc_64x64(const tran_low_t *coeff_ptr, int skip_block,
229 : const int16_t *round_ptr, const int16_t quant,
230 : tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
231 : const int16_t dequant_ptr, uint16_t *eob_ptr,
232 : const qm_val_t *qm_ptr, const qm_val_t *iqm_ptr) {
233 : const int n_coeffs = 1024;
234 : const int rc = 0;
235 : const int coeff = coeff_ptr[rc];
236 : const int coeff_sign = (coeff >> 31);
237 : const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
238 : int64_t tmp, eob = -1;
239 : int32_t tmp32;
240 : int dequant;
241 :
242 : memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
243 : memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
244 :
245 : if (!skip_block) {
246 : tmp = clamp(abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], 2),
247 : INT16_MIN, INT16_MAX);
248 : tmp32 = (int32_t)((tmp * qm_ptr[rc] * quant) >> (14 + AOM_QM_BITS));
249 : qcoeff_ptr[rc] = (tmp32 ^ coeff_sign) - coeff_sign;
250 : dequant =
251 : (dequant_ptr * iqm_ptr[rc] + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS;
252 : dqcoeff_ptr[rc] = (qcoeff_ptr[rc] * dequant) / 4;
253 : if (tmp32) eob = 0;
254 : }
255 : *eob_ptr = eob + 1;
256 : }
257 : #endif // CONFIG_TX64X64
258 :
259 : #if CONFIG_HIGHBITDEPTH
260 : void aom_highbd_quantize_dc(const tran_low_t *coeff_ptr, int n_coeffs,
261 : int skip_block, const int16_t *round_ptr,
262 : const int16_t quant, tran_low_t *qcoeff_ptr,
263 : tran_low_t *dqcoeff_ptr, const int16_t dequant_ptr,
264 : uint16_t *eob_ptr, const qm_val_t *qm_ptr,
265 : const qm_val_t *iqm_ptr) {
266 : int eob = -1;
267 : int dequant =
268 : (dequant_ptr * iqm_ptr[0] + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS;
269 :
270 : memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
271 : memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
272 :
273 : if (!skip_block) {
274 : const int coeff = coeff_ptr[0];
275 : const int coeff_sign = (coeff >> 31);
276 : const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
277 : const int64_t tmp = abs_coeff + round_ptr[0];
278 : const uint32_t abs_qcoeff =
279 : (uint32_t)((tmp * qm_ptr[0] * quant) >> (16 + AOM_QM_BITS));
280 : qcoeff_ptr[0] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
281 : dqcoeff_ptr[0] = qcoeff_ptr[0] * dequant;
282 : if (abs_qcoeff) eob = 0;
283 : }
284 : *eob_ptr = eob + 1;
285 : }
286 :
287 : void aom_highbd_quantize_dc_32x32(const tran_low_t *coeff_ptr, int skip_block,
288 : const int16_t *round_ptr, const int16_t quant,
289 : tran_low_t *qcoeff_ptr,
290 : tran_low_t *dqcoeff_ptr,
291 : const int16_t dequant_ptr, uint16_t *eob_ptr,
292 : const qm_val_t *qm_ptr,
293 : const qm_val_t *iqm_ptr) {
294 : const int n_coeffs = 1024;
295 : int eob = -1;
296 : int dequant;
297 :
298 : memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
299 : memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
300 :
301 : if (!skip_block) {
302 : const int coeff = coeff_ptr[0];
303 : const int coeff_sign = (coeff >> 31);
304 : const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
305 : const int64_t tmp = abs_coeff + ROUND_POWER_OF_TWO(round_ptr[0], 1);
306 : const uint32_t abs_qcoeff =
307 : (uint32_t)((tmp * qm_ptr[0] * quant) >> (15 + AOM_QM_BITS));
308 : qcoeff_ptr[0] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
309 : dequant =
310 : (dequant_ptr * iqm_ptr[0] + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS;
311 : dqcoeff_ptr[0] = (qcoeff_ptr[0] * dequant) / 2;
312 : if (abs_qcoeff) eob = 0;
313 : }
314 : *eob_ptr = eob + 1;
315 : }
316 :
317 : #if CONFIG_TX64X64
318 : void aom_highbd_quantize_dc_64x64(const tran_low_t *coeff_ptr, int skip_block,
319 : const int16_t *round_ptr, const int16_t quant,
320 : tran_low_t *qcoeff_ptr,
321 : tran_low_t *dqcoeff_ptr,
322 : const int16_t dequant_ptr, uint16_t *eob_ptr,
323 : const qm_val_t *qm_ptr,
324 : const qm_val_t *iqm_ptr) {
325 : const int n_coeffs = 1024;
326 : int eob = -1;
327 : int dequant;
328 :
329 : memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
330 : memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
331 :
332 : if (!skip_block) {
333 : const int coeff = coeff_ptr[0];
334 : const int coeff_sign = (coeff >> 31);
335 : const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
336 : const int64_t tmp = abs_coeff + ROUND_POWER_OF_TWO(round_ptr[0], 2);
337 : const uint32_t abs_qcoeff =
338 : (uint32_t)((tmp * qm_ptr[0] * quant) >> (14 + AOM_QM_BITS));
339 : qcoeff_ptr[0] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
340 : dequant =
341 : (dequant_ptr * iqm_ptr[0] + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS;
342 : dqcoeff_ptr[0] = (qcoeff_ptr[0] * dequant) / 4;
343 : if (abs_qcoeff) eob = 0;
344 : }
345 : *eob_ptr = eob + 1;
346 : }
347 : #endif // CONFIG_TX64X64
348 :
349 : void aom_highbd_quantize_b_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
350 : int skip_block, const int16_t *zbin_ptr,
351 : const int16_t *round_ptr, const int16_t *quant_ptr,
352 : const int16_t *quant_shift_ptr,
353 : tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
354 : const int16_t *dequant_ptr, uint16_t *eob_ptr,
355 : const int16_t *scan, const int16_t *iscan,
356 : const qm_val_t *qm_ptr, const qm_val_t *iqm_ptr) {
357 : int i, non_zero_count = (int)n_coeffs, eob = -1;
358 : const int zbins[2] = { zbin_ptr[0], zbin_ptr[1] };
359 : const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
360 : int dequant;
361 : (void)iscan;
362 :
363 : memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
364 : memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
365 :
366 : if (!skip_block) {
367 : // Pre-scan pass
368 : for (i = (int)n_coeffs - 1; i >= 0; i--) {
369 : const int rc = scan[i];
370 : const qm_val_t wt = qm_ptr[rc];
371 : const int coeff = coeff_ptr[rc] * wt;
372 :
373 : if (coeff < (zbins[rc != 0] << AOM_QM_BITS) &&
374 : coeff > (nzbins[rc != 0] << AOM_QM_BITS))
375 : non_zero_count--;
376 : else
377 : break;
378 : }
379 :
380 : // Quantization pass: All coefficients with index >= zero_flag are
381 : // skippable. Note: zero_flag can be zero.
382 : for (i = 0; i < non_zero_count; i++) {
383 : const int rc = scan[i];
384 : const int coeff = coeff_ptr[rc];
385 : const qm_val_t wt = qm_ptr[rc];
386 : const int coeff_sign = (coeff >> 31);
387 : const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
388 :
389 : if (abs_coeff * wt >= (zbins[rc != 0] << AOM_QM_BITS)) {
390 : const int64_t tmp1 = abs_coeff + round_ptr[rc != 0];
391 : const int64_t tmpw = tmp1 * wt;
392 : const int64_t tmp2 = ((tmpw * quant_ptr[rc != 0]) >> 16) + tmpw;
393 : const uint32_t abs_qcoeff =
394 : (uint32_t)((tmp2 * quant_shift_ptr[rc != 0]) >> (16 + AOM_QM_BITS));
395 : qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
396 : dequant =
397 : (dequant_ptr[rc != 0] * iqm_ptr[rc] + (1 << (AOM_QM_BITS - 1))) >>
398 : AOM_QM_BITS;
399 : dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant;
400 : if (abs_qcoeff) eob = i;
401 : }
402 : }
403 : }
404 : *eob_ptr = eob + 1;
405 : }
406 :
407 : void aom_highbd_quantize_b_32x32_c(
408 : const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block,
409 : const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr,
410 : const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
411 : tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr,
412 : const int16_t *scan, const int16_t *iscan, const qm_val_t *qm_ptr,
413 : const qm_val_t *iqm_ptr) {
414 : const int zbins[2] = { ROUND_POWER_OF_TWO(zbin_ptr[0], 1),
415 : ROUND_POWER_OF_TWO(zbin_ptr[1], 1) };
416 : const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
417 :
418 : int idx = 0;
419 : int idx_arr[1024];
420 : int i, eob = -1;
421 : int dequant;
422 : (void)iscan;
423 :
424 : memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
425 : memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
426 :
427 : if (!skip_block) {
428 : // Pre-scan pass
429 : for (i = 0; i < n_coeffs; i++) {
430 : const int rc = scan[i];
431 : const qm_val_t wt = qm_ptr[rc];
432 : const int coeff = coeff_ptr[rc] * wt;
433 :
434 : // If the coefficient is out of the base ZBIN range, keep it for
435 : // quantization.
436 : if (coeff >= (zbins[rc != 0] << AOM_QM_BITS) ||
437 : coeff <= (nzbins[rc != 0] << AOM_QM_BITS))
438 : idx_arr[idx++] = i;
439 : }
440 :
441 : // Quantization pass: only process the coefficients selected in
442 : // pre-scan pass. Note: idx can be zero.
443 : for (i = 0; i < idx; i++) {
444 : const int rc = scan[idx_arr[i]];
445 : const int coeff = coeff_ptr[rc];
446 : const int coeff_sign = (coeff >> 31);
447 : const qm_val_t wt = qm_ptr[rc];
448 : const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
449 : const int64_t tmp1 =
450 : abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1);
451 : const int64_t tmpw = tmp1 * wt;
452 : const int64_t tmp2 = ((tmpw * quant_ptr[rc != 0]) >> 16) + tmpw;
453 : const uint32_t abs_qcoeff =
454 : (uint32_t)((tmp2 * quant_shift_ptr[rc != 0]) >> (15 + AOM_QM_BITS));
455 : qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
456 : dequant =
457 : (dequant_ptr[rc != 0] * iqm_ptr[rc] + (1 << (AOM_QM_BITS - 1))) >>
458 : AOM_QM_BITS;
459 : dqcoeff_ptr[rc] = (qcoeff_ptr[rc] * dequant) / 2;
460 : if (abs_qcoeff) eob = idx_arr[i];
461 : }
462 : }
463 : *eob_ptr = eob + 1;
464 : }
465 :
466 : #if CONFIG_TX64X64
467 : void aom_highbd_quantize_b_64x64_c(
468 : const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block,
469 : const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr,
470 : const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
471 : tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr,
472 : const int16_t *scan, const int16_t *iscan, const qm_val_t *qm_ptr,
473 : const qm_val_t *iqm_ptr) {
474 : const int zbins[2] = { ROUND_POWER_OF_TWO(zbin_ptr[0], 2),
475 : ROUND_POWER_OF_TWO(zbin_ptr[1], 2) };
476 : const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
477 :
478 : int idx = 0;
479 : int idx_arr[4096];
480 : int i, eob = -1;
481 : int dequant;
482 : (void)iscan;
483 :
484 : memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
485 : memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
486 :
487 : if (!skip_block) {
488 : // Pre-scan pass
489 : for (i = 0; i < n_coeffs; i++) {
490 : const int rc = scan[i];
491 : const qm_val_t wt = qm_ptr[rc];
492 : const int coeff = coeff_ptr[rc] * wt;
493 :
494 : // If the coefficient is out of the base ZBIN range, keep it for
495 : // quantization.
496 : if (coeff >= (zbins[rc != 0] << AOM_QM_BITS) ||
497 : coeff <= (nzbins[rc != 0] << AOM_QM_BITS))
498 : idx_arr[idx++] = i;
499 : }
500 :
501 : // Quantization pass: only process the coefficients selected in
502 : // pre-scan pass. Note: idx can be zero.
503 : for (i = 0; i < idx; i++) {
504 : const int rc = scan[idx_arr[i]];
505 : const int coeff = coeff_ptr[rc];
506 : const int coeff_sign = (coeff >> 31);
507 : const qm_val_t wt = qm_ptr[rc];
508 : const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
509 : const int64_t tmp1 =
510 : abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], 2);
511 : const int64_t tmpw = tmp1 * wt;
512 : const int64_t tmp2 = ((tmpw * quant_ptr[rc != 0]) >> 16) + tmpw;
513 : const uint32_t abs_qcoeff =
514 : (uint32_t)((tmp2 * quant_shift_ptr[rc != 0]) >> (14 + AOM_QM_BITS));
515 : qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
516 : dequant =
517 : (dequant_ptr[rc != 0] * iqm_ptr[rc] + (1 << (AOM_QM_BITS - 1))) >>
518 : AOM_QM_BITS;
519 : dqcoeff_ptr[rc] = (qcoeff_ptr[rc] * dequant) / 4;
520 : if (abs_qcoeff) eob = idx_arr[i];
521 : }
522 : }
523 : *eob_ptr = eob + 1;
524 : }
525 : #endif // CONFIG_TX64X64
526 : #endif // CONFIG_HIGHBITDEPTH
527 :
528 : #else // CONFIG_AOM_QM
529 :
530 0 : void aom_quantize_dc(const tran_low_t *coeff_ptr, int n_coeffs, int skip_block,
531 : const int16_t *round_ptr, const int16_t quant,
532 : tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
533 : const int16_t dequant_ptr, uint16_t *eob_ptr) {
534 0 : const int rc = 0;
535 0 : const int coeff = coeff_ptr[rc];
536 0 : const int coeff_sign = (coeff >> 31);
537 0 : const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
538 0 : int tmp, eob = -1;
539 :
540 0 : memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
541 0 : memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
542 :
543 0 : if (!skip_block) {
544 0 : tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX);
545 0 : tmp = (tmp * quant) >> 16;
546 0 : qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
547 0 : dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr;
548 0 : if (tmp) eob = 0;
549 : }
550 0 : *eob_ptr = eob + 1;
551 0 : }
552 :
553 0 : void aom_quantize_dc_32x32(const tran_low_t *coeff_ptr, int skip_block,
554 : const int16_t *round_ptr, const int16_t quant,
555 : tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
556 : const int16_t dequant_ptr, uint16_t *eob_ptr) {
557 0 : const int n_coeffs = 1024;
558 0 : const int rc = 0;
559 0 : const int coeff = coeff_ptr[rc];
560 0 : const int coeff_sign = (coeff >> 31);
561 0 : const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
562 0 : int tmp, eob = -1;
563 :
564 0 : memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
565 0 : memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
566 :
567 0 : if (!skip_block) {
568 0 : tmp = clamp(abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1),
569 : INT16_MIN, INT16_MAX);
570 0 : tmp = (tmp * quant) >> 15;
571 0 : qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
572 0 : dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr / 2;
573 0 : if (tmp) eob = 0;
574 : }
575 0 : *eob_ptr = eob + 1;
576 0 : }
577 :
578 : #if CONFIG_TX64X64
579 : void aom_quantize_dc_64x64(const tran_low_t *coeff_ptr, int skip_block,
580 : const int16_t *round_ptr, const int16_t quant,
581 : tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
582 : const int16_t dequant_ptr, uint16_t *eob_ptr) {
583 : const int n_coeffs = 4096;
584 : const int rc = 0;
585 : const int coeff = coeff_ptr[rc];
586 : const int coeff_sign = (coeff >> 31);
587 : const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
588 : int tmp, eob = -1;
589 :
590 : memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
591 : memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
592 :
593 : if (!skip_block) {
594 : tmp = clamp(abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], 2),
595 : INT16_MIN, INT16_MAX);
596 : tmp = (tmp * quant) >> 14;
597 : qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
598 : dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr / 4;
599 : if (tmp) eob = 0;
600 : }
601 : *eob_ptr = eob + 1;
602 : }
603 : #endif // CONFIG_TX64X64
604 :
605 : #if CONFIG_HIGHBITDEPTH
606 0 : void aom_highbd_quantize_dc(const tran_low_t *coeff_ptr, int n_coeffs,
607 : int skip_block, const int16_t *round_ptr,
608 : const int16_t quant, tran_low_t *qcoeff_ptr,
609 : tran_low_t *dqcoeff_ptr, const int16_t dequant_ptr,
610 : uint16_t *eob_ptr) {
611 0 : int eob = -1;
612 :
613 0 : memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
614 0 : memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
615 :
616 0 : if (!skip_block) {
617 0 : const int coeff = coeff_ptr[0];
618 0 : const int coeff_sign = (coeff >> 31);
619 0 : const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
620 0 : const int64_t tmp = abs_coeff + round_ptr[0];
621 0 : const uint32_t abs_qcoeff = (uint32_t)((tmp * quant) >> 16);
622 0 : qcoeff_ptr[0] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
623 0 : dqcoeff_ptr[0] = qcoeff_ptr[0] * dequant_ptr;
624 0 : if (abs_qcoeff) eob = 0;
625 : }
626 0 : *eob_ptr = eob + 1;
627 0 : }
628 :
629 0 : void aom_highbd_quantize_dc_32x32(const tran_low_t *coeff_ptr, int skip_block,
630 : const int16_t *round_ptr, const int16_t quant,
631 : tran_low_t *qcoeff_ptr,
632 : tran_low_t *dqcoeff_ptr,
633 : const int16_t dequant_ptr,
634 : uint16_t *eob_ptr) {
635 0 : const int n_coeffs = 1024;
636 0 : int eob = -1;
637 :
638 0 : memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
639 0 : memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
640 :
641 0 : if (!skip_block) {
642 0 : const int coeff = coeff_ptr[0];
643 0 : const int coeff_sign = (coeff >> 31);
644 0 : const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
645 0 : const int64_t tmp = abs_coeff + ROUND_POWER_OF_TWO(round_ptr[0], 1);
646 0 : const uint32_t abs_qcoeff = (uint32_t)((tmp * quant) >> 15);
647 0 : qcoeff_ptr[0] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
648 0 : dqcoeff_ptr[0] = qcoeff_ptr[0] * dequant_ptr / 2;
649 0 : if (abs_qcoeff) eob = 0;
650 : }
651 0 : *eob_ptr = eob + 1;
652 0 : }
653 :
654 : #if CONFIG_TX64X64
655 : void aom_highbd_quantize_dc_64x64(const tran_low_t *coeff_ptr, int skip_block,
656 : const int16_t *round_ptr, const int16_t quant,
657 : tran_low_t *qcoeff_ptr,
658 : tran_low_t *dqcoeff_ptr,
659 : const int16_t dequant_ptr,
660 : uint16_t *eob_ptr) {
661 : const int n_coeffs = 4096;
662 : int eob = -1;
663 :
664 : memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
665 : memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
666 :
667 : if (!skip_block) {
668 : const int coeff = coeff_ptr[0];
669 : const int coeff_sign = (coeff >> 31);
670 : const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
671 : const int64_t tmp = abs_coeff + ROUND_POWER_OF_TWO(round_ptr[0], 2);
672 : const uint32_t abs_qcoeff = (uint32_t)((tmp * quant) >> 14);
673 : qcoeff_ptr[0] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
674 : dqcoeff_ptr[0] = qcoeff_ptr[0] * dequant_ptr / 4;
675 : if (abs_qcoeff) eob = 0;
676 : }
677 : *eob_ptr = eob + 1;
678 : }
679 : #endif // CONFIG_TX64X64
680 :
681 0 : void aom_highbd_quantize_b_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
682 : int skip_block, const int16_t *zbin_ptr,
683 : const int16_t *round_ptr, const int16_t *quant_ptr,
684 : const int16_t *quant_shift_ptr,
685 : tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
686 : const int16_t *dequant_ptr, uint16_t *eob_ptr,
687 : const int16_t *scan, const int16_t *iscan) {
688 0 : int i, non_zero_count = (int)n_coeffs, eob = -1;
689 0 : const int zbins[2] = { zbin_ptr[0], zbin_ptr[1] };
690 0 : const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
691 : (void)iscan;
692 :
693 0 : memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
694 0 : memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
695 :
696 0 : if (!skip_block) {
697 : // Pre-scan pass
698 0 : for (i = (int)n_coeffs - 1; i >= 0; i--) {
699 0 : const int rc = scan[i];
700 0 : const int coeff = coeff_ptr[rc];
701 :
702 0 : if (coeff < zbins[rc != 0] && coeff > nzbins[rc != 0])
703 0 : non_zero_count--;
704 : else
705 : break;
706 : }
707 :
708 : // Quantization pass: All coefficients with index >= zero_flag are
709 : // skippable. Note: zero_flag can be zero.
710 0 : for (i = 0; i < non_zero_count; i++) {
711 0 : const int rc = scan[i];
712 0 : const int coeff = coeff_ptr[rc];
713 0 : const int coeff_sign = (coeff >> 31);
714 0 : const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
715 :
716 0 : if (abs_coeff >= zbins[rc != 0]) {
717 0 : const int64_t tmp1 = abs_coeff + round_ptr[rc != 0];
718 0 : const int64_t tmp2 = ((tmp1 * quant_ptr[rc != 0]) >> 16) + tmp1;
719 0 : const uint32_t abs_qcoeff =
720 0 : (uint32_t)((tmp2 * quant_shift_ptr[rc != 0]) >> 16);
721 0 : qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
722 0 : dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0];
723 0 : if (abs_qcoeff) eob = i;
724 : }
725 : }
726 : }
727 0 : *eob_ptr = eob + 1;
728 0 : }
729 :
730 0 : void aom_highbd_quantize_b_32x32_c(
731 : const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block,
732 : const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr,
733 : const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
734 : tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr,
735 : const int16_t *scan, const int16_t *iscan) {
736 0 : const int zbins[2] = { ROUND_POWER_OF_TWO(zbin_ptr[0], 1),
737 0 : ROUND_POWER_OF_TWO(zbin_ptr[1], 1) };
738 0 : const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
739 :
740 0 : int idx = 0;
741 : int idx_arr[1024];
742 0 : int i, eob = -1;
743 : (void)iscan;
744 :
745 0 : memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
746 0 : memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
747 :
748 0 : if (!skip_block) {
749 : // Pre-scan pass
750 0 : for (i = 0; i < n_coeffs; i++) {
751 0 : const int rc = scan[i];
752 0 : const int coeff = coeff_ptr[rc];
753 :
754 : // If the coefficient is out of the base ZBIN range, keep it for
755 : // quantization.
756 0 : if (coeff >= zbins[rc != 0] || coeff <= nzbins[rc != 0])
757 0 : idx_arr[idx++] = i;
758 : }
759 :
760 : // Quantization pass: only process the coefficients selected in
761 : // pre-scan pass. Note: idx can be zero.
762 0 : for (i = 0; i < idx; i++) {
763 0 : const int rc = scan[idx_arr[i]];
764 0 : const int coeff = coeff_ptr[rc];
765 0 : const int coeff_sign = (coeff >> 31);
766 0 : const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
767 0 : const int64_t tmp1 =
768 0 : abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1);
769 0 : const int64_t tmp2 = ((tmp1 * quant_ptr[rc != 0]) >> 16) + tmp1;
770 0 : const uint32_t abs_qcoeff =
771 0 : (uint32_t)((tmp2 * quant_shift_ptr[rc != 0]) >> 15);
772 0 : qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
773 0 : dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2;
774 0 : if (abs_qcoeff) eob = idx_arr[i];
775 : }
776 : }
777 0 : *eob_ptr = eob + 1;
778 0 : }
779 :
780 : #if CONFIG_TX64X64
781 : void aom_highbd_quantize_b_64x64_c(
782 : const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block,
783 : const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr,
784 : const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
785 : tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr,
786 : const int16_t *scan, const int16_t *iscan) {
787 : const int zbins[2] = { ROUND_POWER_OF_TWO(zbin_ptr[0], 2),
788 : ROUND_POWER_OF_TWO(zbin_ptr[1], 2) };
789 : const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
790 :
791 : int idx = 0;
792 : int idx_arr[4096];
793 : int i, eob = -1;
794 : (void)iscan;
795 :
796 : memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
797 : memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
798 :
799 : if (!skip_block) {
800 : // Pre-scan pass
801 : for (i = 0; i < n_coeffs; i++) {
802 : const int rc = scan[i];
803 : const int coeff = coeff_ptr[rc];
804 :
805 : // If the coefficient is out of the base ZBIN range, keep it for
806 : // quantization.
807 : if (coeff >= zbins[rc != 0] || coeff <= nzbins[rc != 0])
808 : idx_arr[idx++] = i;
809 : }
810 :
811 : // Quantization pass: only process the coefficients selected in
812 : // pre-scan pass. Note: idx can be zero.
813 : for (i = 0; i < idx; i++) {
814 : const int rc = scan[idx_arr[i]];
815 : const int coeff = coeff_ptr[rc];
816 : const int coeff_sign = (coeff >> 31);
817 : const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
818 : const int64_t tmp1 =
819 : abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], 2);
820 : const int64_t tmp2 = ((tmp1 * quant_ptr[rc != 0]) >> 16) + tmp1;
821 : const uint32_t abs_qcoeff =
822 : (uint32_t)((tmp2 * quant_shift_ptr[rc != 0]) >> 14);
823 : qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
824 : dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 4;
825 : if (abs_qcoeff) eob = idx_arr[i];
826 : }
827 : }
828 : *eob_ptr = eob + 1;
829 : }
830 : #endif // CONFIG_TX64X64
831 : #endif // CONFIG_HIGHBITDEPTH
832 : #endif // CONFIG_AOM_QM
|