Line data Source code
1 : /*
2 : * Copyright (c) 2015 The WebM project authors. All Rights Reserved.
3 : *
4 : * Use of this source code is governed by a BSD-style license
5 : * that can be found in the LICENSE file in the root of the source
6 : * tree. An additional intellectual property rights grant can be found
7 : * in the file PATENTS. All contributing project authors may
8 : * be found in the AUTHORS file in the root of the source tree.
9 : */
10 :
11 : #include "./vpx_dsp_rtcd.h"
12 : #include "vpx_dsp/quantize.h"
13 : #include "vpx_mem/vpx_mem.h"
14 :
15 0 : void vpx_quantize_dc(const tran_low_t *coeff_ptr, int n_coeffs, int skip_block,
16 : const int16_t *round_ptr, const int16_t quant,
17 : tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
18 : const int16_t dequant_ptr, uint16_t *eob_ptr) {
19 0 : const int rc = 0;
20 0 : const int coeff = coeff_ptr[rc];
21 0 : const int coeff_sign = (coeff >> 31);
22 0 : const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
23 0 : int tmp, eob = -1;
24 :
25 0 : memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
26 0 : memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
27 :
28 0 : if (!skip_block) {
29 0 : tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX);
30 0 : tmp = (tmp * quant) >> 16;
31 0 : qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
32 0 : dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr;
33 0 : if (tmp) eob = 0;
34 : }
35 0 : *eob_ptr = eob + 1;
36 0 : }
37 :
38 : #if CONFIG_VP9_HIGHBITDEPTH
39 : void vpx_highbd_quantize_dc(const tran_low_t *coeff_ptr, int n_coeffs,
40 : int skip_block, const int16_t *round_ptr,
41 : const int16_t quant, tran_low_t *qcoeff_ptr,
42 : tran_low_t *dqcoeff_ptr, const int16_t dequant_ptr,
43 : uint16_t *eob_ptr) {
44 : int eob = -1;
45 :
46 : memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
47 : memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
48 :
49 : if (!skip_block) {
50 : const int coeff = coeff_ptr[0];
51 : const int coeff_sign = (coeff >> 31);
52 : const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
53 : const int64_t tmp = abs_coeff + round_ptr[0];
54 : const int abs_qcoeff = (int)((tmp * quant) >> 16);
55 : qcoeff_ptr[0] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
56 : dqcoeff_ptr[0] = qcoeff_ptr[0] * dequant_ptr;
57 : if (abs_qcoeff) eob = 0;
58 : }
59 : *eob_ptr = eob + 1;
60 : }
61 : #endif
62 :
63 0 : void vpx_quantize_dc_32x32(const tran_low_t *coeff_ptr, int skip_block,
64 : const int16_t *round_ptr, const int16_t quant,
65 : tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
66 : const int16_t dequant_ptr, uint16_t *eob_ptr) {
67 0 : const int n_coeffs = 1024;
68 0 : const int rc = 0;
69 0 : const int coeff = coeff_ptr[rc];
70 0 : const int coeff_sign = (coeff >> 31);
71 0 : const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
72 0 : int tmp, eob = -1;
73 :
74 0 : memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
75 0 : memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
76 :
77 0 : if (!skip_block) {
78 0 : tmp = clamp(abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1),
79 : INT16_MIN, INT16_MAX);
80 0 : tmp = (tmp * quant) >> 15;
81 0 : qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
82 0 : dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr / 2;
83 0 : if (tmp) eob = 0;
84 : }
85 0 : *eob_ptr = eob + 1;
86 0 : }
87 :
88 : #if CONFIG_VP9_HIGHBITDEPTH
89 : void vpx_highbd_quantize_dc_32x32(const tran_low_t *coeff_ptr, int skip_block,
90 : const int16_t *round_ptr, const int16_t quant,
91 : tran_low_t *qcoeff_ptr,
92 : tran_low_t *dqcoeff_ptr,
93 : const int16_t dequant_ptr,
94 : uint16_t *eob_ptr) {
95 : const int n_coeffs = 1024;
96 : int eob = -1;
97 :
98 : memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
99 : memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
100 :
101 : if (!skip_block) {
102 : const int coeff = coeff_ptr[0];
103 : const int coeff_sign = (coeff >> 31);
104 : const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
105 : const int64_t tmp = abs_coeff + ROUND_POWER_OF_TWO(round_ptr[0], 1);
106 : const int abs_qcoeff = (int)((tmp * quant) >> 15);
107 : qcoeff_ptr[0] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
108 : dqcoeff_ptr[0] = qcoeff_ptr[0] * dequant_ptr / 2;
109 : if (abs_qcoeff) eob = 0;
110 : }
111 : *eob_ptr = eob + 1;
112 : }
113 : #endif
114 :
115 0 : void vpx_quantize_b_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
116 : int skip_block, const int16_t *zbin_ptr,
117 : const int16_t *round_ptr, const int16_t *quant_ptr,
118 : const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
119 : tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr,
120 : uint16_t *eob_ptr, const int16_t *scan,
121 : const int16_t *iscan) {
122 0 : int i, non_zero_count = (int)n_coeffs, eob = -1;
123 0 : const int zbins[2] = { zbin_ptr[0], zbin_ptr[1] };
124 0 : const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
125 : (void)iscan;
126 :
127 0 : memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
128 0 : memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
129 :
130 0 : if (!skip_block) {
131 : // Pre-scan pass
132 0 : for (i = (int)n_coeffs - 1; i >= 0; i--) {
133 0 : const int rc = scan[i];
134 0 : const int coeff = coeff_ptr[rc];
135 :
136 0 : if (coeff < zbins[rc != 0] && coeff > nzbins[rc != 0])
137 0 : non_zero_count--;
138 : else
139 : break;
140 : }
141 :
142 : // Quantization pass: All coefficients with index >= zero_flag are
143 : // skippable. Note: zero_flag can be zero.
144 0 : for (i = 0; i < non_zero_count; i++) {
145 0 : const int rc = scan[i];
146 0 : const int coeff = coeff_ptr[rc];
147 0 : const int coeff_sign = (coeff >> 31);
148 0 : const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
149 :
150 0 : if (abs_coeff >= zbins[rc != 0]) {
151 0 : int tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX);
152 0 : tmp = ((((tmp * quant_ptr[rc != 0]) >> 16) + tmp) *
153 0 : quant_shift_ptr[rc != 0]) >>
154 : 16; // quantization
155 0 : qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
156 0 : dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0];
157 :
158 0 : if (tmp) eob = i;
159 : }
160 : }
161 : }
162 0 : *eob_ptr = eob + 1;
163 0 : }
164 :
165 : #if CONFIG_VP9_HIGHBITDEPTH
166 : void vpx_highbd_quantize_b_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
167 : int skip_block, const int16_t *zbin_ptr,
168 : const int16_t *round_ptr, const int16_t *quant_ptr,
169 : const int16_t *quant_shift_ptr,
170 : tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
171 : const int16_t *dequant_ptr, uint16_t *eob_ptr,
172 : const int16_t *scan, const int16_t *iscan) {
173 : int i, non_zero_count = (int)n_coeffs, eob = -1;
174 : const int zbins[2] = { zbin_ptr[0], zbin_ptr[1] };
175 : const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
176 : (void)iscan;
177 :
178 : memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
179 : memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
180 :
181 : if (!skip_block) {
182 : // Pre-scan pass
183 : for (i = (int)n_coeffs - 1; i >= 0; i--) {
184 : const int rc = scan[i];
185 : const int coeff = coeff_ptr[rc];
186 :
187 : if (coeff < zbins[rc != 0] && coeff > nzbins[rc != 0])
188 : non_zero_count--;
189 : else
190 : break;
191 : }
192 :
193 : // Quantization pass: All coefficients with index >= zero_flag are
194 : // skippable. Note: zero_flag can be zero.
195 : for (i = 0; i < non_zero_count; i++) {
196 : const int rc = scan[i];
197 : const int coeff = coeff_ptr[rc];
198 : const int coeff_sign = (coeff >> 31);
199 : const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
200 :
201 : if (abs_coeff >= zbins[rc != 0]) {
202 : const int64_t tmp1 = abs_coeff + round_ptr[rc != 0];
203 : const int64_t tmp2 = ((tmp1 * quant_ptr[rc != 0]) >> 16) + tmp1;
204 : const uint32_t abs_qcoeff =
205 : (uint32_t)((tmp2 * quant_shift_ptr[rc != 0]) >> 16);
206 : qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
207 : dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0];
208 : if (abs_qcoeff) eob = i;
209 : }
210 : }
211 : }
212 : *eob_ptr = eob + 1;
213 : }
214 : #endif
215 :
216 0 : void vpx_quantize_b_32x32_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
217 : int skip_block, const int16_t *zbin_ptr,
218 : const int16_t *round_ptr, const int16_t *quant_ptr,
219 : const int16_t *quant_shift_ptr,
220 : tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
221 : const int16_t *dequant_ptr, uint16_t *eob_ptr,
222 : const int16_t *scan, const int16_t *iscan) {
223 0 : const int zbins[2] = { ROUND_POWER_OF_TWO(zbin_ptr[0], 1),
224 0 : ROUND_POWER_OF_TWO(zbin_ptr[1], 1) };
225 0 : const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
226 :
227 0 : int idx = 0;
228 : int idx_arr[1024];
229 0 : int i, eob = -1;
230 : (void)iscan;
231 :
232 0 : memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
233 0 : memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
234 :
235 0 : if (!skip_block) {
236 : // Pre-scan pass
237 0 : for (i = 0; i < n_coeffs; i++) {
238 0 : const int rc = scan[i];
239 0 : const int coeff = coeff_ptr[rc];
240 :
241 : // If the coefficient is out of the base ZBIN range, keep it for
242 : // quantization.
243 0 : if (coeff >= zbins[rc != 0] || coeff <= nzbins[rc != 0])
244 0 : idx_arr[idx++] = i;
245 : }
246 :
247 : // Quantization pass: only process the coefficients selected in
248 : // pre-scan pass. Note: idx can be zero.
249 0 : for (i = 0; i < idx; i++) {
250 0 : const int rc = scan[idx_arr[i]];
251 0 : const int coeff = coeff_ptr[rc];
252 0 : const int coeff_sign = (coeff >> 31);
253 : int tmp;
254 0 : int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
255 0 : abs_coeff += ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1);
256 0 : abs_coeff = clamp(abs_coeff, INT16_MIN, INT16_MAX);
257 0 : tmp = ((((abs_coeff * quant_ptr[rc != 0]) >> 16) + abs_coeff) *
258 0 : quant_shift_ptr[rc != 0]) >>
259 : 15;
260 :
261 0 : qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
262 0 : dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2;
263 :
264 0 : if (tmp) eob = idx_arr[i];
265 : }
266 : }
267 0 : *eob_ptr = eob + 1;
268 0 : }
269 :
270 : #if CONFIG_VP9_HIGHBITDEPTH
271 : void vpx_highbd_quantize_b_32x32_c(
272 : const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block,
273 : const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr,
274 : const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
275 : tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr,
276 : const int16_t *scan, const int16_t *iscan) {
277 : const int zbins[2] = { ROUND_POWER_OF_TWO(zbin_ptr[0], 1),
278 : ROUND_POWER_OF_TWO(zbin_ptr[1], 1) };
279 : const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
280 :
281 : int idx = 0;
282 : int idx_arr[1024];
283 : int i, eob = -1;
284 : (void)iscan;
285 :
286 : memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
287 : memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
288 :
289 : if (!skip_block) {
290 : // Pre-scan pass
291 : for (i = 0; i < n_coeffs; i++) {
292 : const int rc = scan[i];
293 : const int coeff = coeff_ptr[rc];
294 :
295 : // If the coefficient is out of the base ZBIN range, keep it for
296 : // quantization.
297 : if (coeff >= zbins[rc != 0] || coeff <= nzbins[rc != 0])
298 : idx_arr[idx++] = i;
299 : }
300 :
301 : // Quantization pass: only process the coefficients selected in
302 : // pre-scan pass. Note: idx can be zero.
303 : for (i = 0; i < idx; i++) {
304 : const int rc = scan[idx_arr[i]];
305 : const int coeff = coeff_ptr[rc];
306 : const int coeff_sign = (coeff >> 31);
307 : const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
308 : const int64_t tmp1 =
309 : abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1);
310 : const int64_t tmp2 = ((tmp1 * quant_ptr[rc != 0]) >> 16) + tmp1;
311 : const uint32_t abs_qcoeff =
312 : (uint32_t)((tmp2 * quant_shift_ptr[rc != 0]) >> 15);
313 : qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
314 : dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2;
315 : if (abs_qcoeff) eob = idx_arr[i];
316 : }
317 : }
318 : *eob_ptr = eob + 1;
319 : }
320 : #endif
|