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
vpx_quantize_dc(const tran_low_t * coeff_ptr,int n_coeffs,int skip_block,const int16_t * round_ptr,const int16_t quant,tran_low_t * qcoeff_ptr,tran_low_t * dqcoeff_ptr,const int16_t dequant_ptr,uint16_t * eob_ptr)15 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 const int rc = 0;
20 const int coeff = coeff_ptr[rc];
21 const int coeff_sign = (coeff >> 31);
22 const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
23 int tmp, eob = -1;
24
25 memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
26 memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
27
28 if (!skip_block) {
29 tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX);
30 tmp = (tmp * quant) >> 16;
31 qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
32 dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr;
33 if (tmp) eob = 0;
34 }
35 *eob_ptr = eob + 1;
36 }
37
38 #if CONFIG_VP9_HIGHBITDEPTH
vpx_highbd_quantize_dc(const tran_low_t * coeff_ptr,int n_coeffs,int skip_block,const int16_t * round_ptr,const int16_t quant,tran_low_t * qcoeff_ptr,tran_low_t * dqcoeff_ptr,const int16_t dequant_ptr,uint16_t * eob_ptr)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
vpx_quantize_dc_32x32(const tran_low_t * coeff_ptr,int skip_block,const int16_t * round_ptr,const int16_t quant,tran_low_t * qcoeff_ptr,tran_low_t * dqcoeff_ptr,const int16_t dequant_ptr,uint16_t * eob_ptr)63 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 const int n_coeffs = 1024;
68 const int rc = 0;
69 const int coeff = coeff_ptr[rc];
70 const int coeff_sign = (coeff >> 31);
71 const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
72 int tmp, eob = -1;
73
74 memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
75 memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
76
77 if (!skip_block) {
78 tmp = clamp(abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1),
79 INT16_MIN, INT16_MAX);
80 tmp = (tmp * quant) >> 15;
81 qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
82 dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr / 2;
83 if (tmp) eob = 0;
84 }
85 *eob_ptr = eob + 1;
86 }
87
88 #if CONFIG_VP9_HIGHBITDEPTH
vpx_highbd_quantize_dc_32x32(const tran_low_t * coeff_ptr,int skip_block,const int16_t * round_ptr,const int16_t quant,tran_low_t * qcoeff_ptr,tran_low_t * dqcoeff_ptr,const int16_t dequant_ptr,uint16_t * eob_ptr)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
vpx_quantize_b_c(const tran_low_t * coeff_ptr,intptr_t n_coeffs,int skip_block,const int16_t * zbin_ptr,const int16_t * round_ptr,const int16_t * quant_ptr,const int16_t * quant_shift_ptr,tran_low_t * qcoeff_ptr,tran_low_t * dqcoeff_ptr,const int16_t * dequant_ptr,uint16_t * eob_ptr,const int16_t * scan,const int16_t * iscan)115 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 int i, non_zero_count = (int)n_coeffs, eob = -1;
123 const int zbins[2] = { zbin_ptr[0], zbin_ptr[1] };
124 const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
125 (void)iscan;
126
127 memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
128 memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
129
130 if (!skip_block) {
131 // Pre-scan pass
132 for (i = (int)n_coeffs - 1; i >= 0; i--) {
133 const int rc = scan[i];
134 const int coeff = coeff_ptr[rc];
135
136 if (coeff < zbins[rc != 0] && coeff > nzbins[rc != 0])
137 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 for (i = 0; i < non_zero_count; i++) {
145 const int rc = scan[i];
146 const int coeff = coeff_ptr[rc];
147 const int coeff_sign = (coeff >> 31);
148 const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
149
150 if (abs_coeff >= zbins[rc != 0]) {
151 int tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX);
152 tmp = ((((tmp * quant_ptr[rc != 0]) >> 16) + tmp) *
153 quant_shift_ptr[rc != 0]) >>
154 16; // quantization
155 qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
156 dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0];
157
158 if (tmp) eob = i;
159 }
160 }
161 }
162 *eob_ptr = eob + 1;
163 }
164
165 #if CONFIG_VP9_HIGHBITDEPTH
vpx_highbd_quantize_b_c(const tran_low_t * coeff_ptr,intptr_t n_coeffs,int skip_block,const int16_t * zbin_ptr,const int16_t * round_ptr,const int16_t * quant_ptr,const int16_t * quant_shift_ptr,tran_low_t * qcoeff_ptr,tran_low_t * dqcoeff_ptr,const int16_t * dequant_ptr,uint16_t * eob_ptr,const int16_t * scan,const int16_t * iscan)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
vpx_quantize_b_32x32_c(const tran_low_t * coeff_ptr,intptr_t n_coeffs,int skip_block,const int16_t * zbin_ptr,const int16_t * round_ptr,const int16_t * quant_ptr,const int16_t * quant_shift_ptr,tran_low_t * qcoeff_ptr,tran_low_t * dqcoeff_ptr,const int16_t * dequant_ptr,uint16_t * eob_ptr,const int16_t * scan,const int16_t * iscan)216 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 const int zbins[2] = { ROUND_POWER_OF_TWO(zbin_ptr[0], 1),
224 ROUND_POWER_OF_TWO(zbin_ptr[1], 1) };
225 const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
226
227 int idx = 0;
228 int idx_arr[1024];
229 int i, eob = -1;
230 (void)iscan;
231
232 memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
233 memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
234
235 if (!skip_block) {
236 // Pre-scan pass
237 for (i = 0; i < n_coeffs; i++) {
238 const int rc = scan[i];
239 const int coeff = coeff_ptr[rc];
240
241 // If the coefficient is out of the base ZBIN range, keep it for
242 // quantization.
243 if (coeff >= zbins[rc != 0] || coeff <= nzbins[rc != 0])
244 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 for (i = 0; i < idx; i++) {
250 const int rc = scan[idx_arr[i]];
251 const int coeff = coeff_ptr[rc];
252 const int coeff_sign = (coeff >> 31);
253 int tmp;
254 int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
255 abs_coeff += ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1);
256 abs_coeff = clamp(abs_coeff, INT16_MIN, INT16_MAX);
257 tmp = ((((abs_coeff * quant_ptr[rc != 0]) >> 16) + abs_coeff) *
258 quant_shift_ptr[rc != 0]) >>
259 15;
260
261 qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
262 dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2;
263
264 if (tmp) eob = idx_arr[i];
265 }
266 }
267 *eob_ptr = eob + 1;
268 }
269
270 #if CONFIG_VP9_HIGHBITDEPTH
vpx_highbd_quantize_b_32x32_c(const tran_low_t * coeff_ptr,intptr_t n_coeffs,int skip_block,const int16_t * zbin_ptr,const int16_t * round_ptr,const int16_t * quant_ptr,const int16_t * quant_shift_ptr,tran_low_t * qcoeff_ptr,tran_low_t * dqcoeff_ptr,const int16_t * dequant_ptr,uint16_t * eob_ptr,const int16_t * scan,const int16_t * iscan)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
321