1 /*
2 * Copyright (c) 2010 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
12 #include <math.h>
13 #include "vpx_mem/vpx_mem.h"
14
15 #include "quantize.h"
16 #include "entropy.h"
17 #include "predictdc.h"
18
19 //#define EXACT_QUANT
20 #ifdef EXACT_QUANT
vp8_fast_quantize_b_c(BLOCK * b,BLOCKD * d)21 void vp8_fast_quantize_b_c(BLOCK *b, BLOCKD *d)
22 {
23 int i, rc, eob;
24 int zbin;
25 int x, y, z, sz;
26 short *coeff_ptr = b->coeff;
27 short *zbin_ptr = b->zbin;
28 short *round_ptr = b->round;
29 short *quant_ptr = b->quant;
30 short *quant_shift_ptr = b->quant_shift;
31 short *qcoeff_ptr = d->qcoeff;
32 short *dqcoeff_ptr = d->dqcoeff;
33 short *dequant_ptr = d->dequant;
34
35 vpx_memset(qcoeff_ptr, 0, 32);
36 vpx_memset(dqcoeff_ptr, 0, 32);
37
38 eob = -1;
39
40 for (i = 0; i < 16; i++)
41 {
42 rc = vp8_default_zig_zag1d[i];
43 z = coeff_ptr[rc];
44 zbin = zbin_ptr[rc] ;
45
46 sz = (z >> 31); // sign of z
47 x = (z ^ sz) - sz; // x = abs(z)
48
49 if (x >= zbin)
50 {
51 x += round_ptr[rc];
52 y = (((x * quant_ptr[rc]) >> 16) + x)
53 >> quant_shift_ptr[rc]; // quantize (x)
54 x = (y ^ sz) - sz; // get the sign back
55 qcoeff_ptr[rc] = x; // write to destination
56 dqcoeff_ptr[rc] = x * dequant_ptr[rc]; // dequantized value
57
58 if (y)
59 {
60 eob = i; // last nonzero coeffs
61 }
62 }
63 }
64 d->eob = eob + 1;
65 }
66
vp8_regular_quantize_b(BLOCK * b,BLOCKD * d)67 void vp8_regular_quantize_b(BLOCK *b, BLOCKD *d)
68 {
69 int i, rc, eob;
70 int zbin;
71 int x, y, z, sz;
72 short *zbin_boost_ptr = b->zrun_zbin_boost;
73 short *coeff_ptr = b->coeff;
74 short *zbin_ptr = b->zbin;
75 short *round_ptr = b->round;
76 short *quant_ptr = b->quant;
77 short *quant_shift_ptr = b->quant_shift;
78 short *qcoeff_ptr = d->qcoeff;
79 short *dqcoeff_ptr = d->dqcoeff;
80 short *dequant_ptr = d->dequant;
81 short zbin_oq_value = b->zbin_extra;
82
83 vpx_memset(qcoeff_ptr, 0, 32);
84 vpx_memset(dqcoeff_ptr, 0, 32);
85
86 eob = -1;
87
88 for (i = 0; i < 16; i++)
89 {
90 rc = vp8_default_zig_zag1d[i];
91 z = coeff_ptr[rc];
92
93 //if ( i == 0 )
94 // zbin = zbin_ptr[rc] + *zbin_boost_ptr + zbin_oq_value/2;
95 //else
96 zbin = zbin_ptr[rc] + *zbin_boost_ptr + zbin_oq_value;
97
98 zbin_boost_ptr ++;
99 sz = (z >> 31); // sign of z
100 x = (z ^ sz) - sz; // x = abs(z)
101
102 if (x >= zbin)
103 {
104 x += round_ptr[rc];
105 y = (((x * quant_ptr[rc]) >> 16) + x)
106 >> quant_shift_ptr[rc]; // quantize (x)
107 x = (y ^ sz) - sz; // get the sign back
108 qcoeff_ptr[rc] = x; // write to destination
109 dqcoeff_ptr[rc] = x * dequant_ptr[rc]; // dequantized value
110
111 if (y)
112 {
113 eob = i; // last nonzero coeffs
114 zbin_boost_ptr = &b->zrun_zbin_boost[0]; // reset zero runlength
115 }
116 }
117 }
118
119 d->eob = eob + 1;
120 }
121
122 /* Perform regular quantization, with unbiased rounding and no zero bin. */
vp8_strict_quantize_b(BLOCK * b,BLOCKD * d)123 void vp8_strict_quantize_b(BLOCK *b, BLOCKD *d)
124 {
125 int i;
126 int rc;
127 int eob;
128 int x;
129 int y;
130 int z;
131 int sz;
132 short *coeff_ptr;
133 short *quant_ptr;
134 short *quant_shift_ptr;
135 short *qcoeff_ptr;
136 short *dqcoeff_ptr;
137 short *dequant_ptr;
138
139 coeff_ptr = b->coeff;
140 quant_ptr = b->quant;
141 quant_shift_ptr = b->quant_shift;
142 qcoeff_ptr = d->qcoeff;
143 dqcoeff_ptr = d->dqcoeff;
144 dequant_ptr = d->dequant;
145 eob = - 1;
146 vpx_memset(qcoeff_ptr, 0, 32);
147 vpx_memset(dqcoeff_ptr, 0, 32);
148 for (i = 0; i < 16; i++)
149 {
150 int dq;
151 int round;
152
153 /*TODO: These arrays should be stored in zig-zag order.*/
154 rc = vp8_default_zig_zag1d[i];
155 z = coeff_ptr[rc];
156 dq = dequant_ptr[rc];
157 round = dq >> 1;
158 /* Sign of z. */
159 sz = -(z < 0);
160 x = (z + sz) ^ sz;
161 x += round;
162 if (x >= dq)
163 {
164 /* Quantize x. */
165 y = (((x * quant_ptr[rc]) >> 16) + x) >> quant_shift_ptr[rc];
166 /* Put the sign back. */
167 x = (y + sz) ^ sz;
168 /* Save the coefficient and its dequantized value. */
169 qcoeff_ptr[rc] = x;
170 dqcoeff_ptr[rc] = x * dq;
171 /* Remember the last non-zero coefficient. */
172 if (y)
173 eob = i;
174 }
175 }
176
177 d->eob = eob + 1;
178 }
179
180 #else
vp8_fast_quantize_b_c(BLOCK * b,BLOCKD * d)181 void vp8_fast_quantize_b_c(BLOCK *b, BLOCKD *d)
182 {
183 int i, rc, eob;
184 int zbin;
185 int x, y, z, sz;
186 short *coeff_ptr = b->coeff;
187 short *round_ptr = b->round;
188 short *quant_ptr = b->quant;
189 short *qcoeff_ptr = d->qcoeff;
190 short *dqcoeff_ptr = d->dqcoeff;
191 short *dequant_ptr = d->dequant;
192
193 eob = -1;
194 for (i = 0; i < 16; i++)
195 {
196 rc = vp8_default_zig_zag1d[i];
197 z = coeff_ptr[rc];
198
199 sz = (z >> 31); // sign of z
200 x = (z ^ sz) - sz; // x = abs(z)
201
202 y = ((x + round_ptr[rc]) * quant_ptr[rc]) >> 16; // quantize (x)
203 x = (y ^ sz) - sz; // get the sign back
204 qcoeff_ptr[rc] = x; // write to destination
205 dqcoeff_ptr[rc] = x * dequant_ptr[rc]; // dequantized value
206
207 if (y)
208 {
209 eob = i; // last nonzero coeffs
210 }
211 }
212 d->eob = eob + 1;
213 }
214
vp8_regular_quantize_b(BLOCK * b,BLOCKD * d)215 void vp8_regular_quantize_b(BLOCK *b, BLOCKD *d)
216 {
217 int i, rc, eob;
218 int zbin;
219 int x, y, z, sz;
220 short *zbin_boost_ptr = b->zrun_zbin_boost;
221 short *coeff_ptr = b->coeff;
222 short *zbin_ptr = b->zbin;
223 short *round_ptr = b->round;
224 short *quant_ptr = b->quant;
225 short *qcoeff_ptr = d->qcoeff;
226 short *dqcoeff_ptr = d->dqcoeff;
227 short *dequant_ptr = d->dequant;
228 short zbin_oq_value = b->zbin_extra;
229
230 vpx_memset(qcoeff_ptr, 0, 32);
231 vpx_memset(dqcoeff_ptr, 0, 32);
232
233 eob = -1;
234
235 for (i = 0; i < 16; i++)
236 {
237 rc = vp8_default_zig_zag1d[i];
238 z = coeff_ptr[rc];
239
240 //if ( i == 0 )
241 // zbin = zbin_ptr[rc] + *zbin_boost_ptr + zbin_oq_value/2;
242 //else
243 zbin = zbin_ptr[rc] + *zbin_boost_ptr + zbin_oq_value;
244
245 zbin_boost_ptr ++;
246 sz = (z >> 31); // sign of z
247 x = (z ^ sz) - sz; // x = abs(z)
248
249 if (x >= zbin)
250 {
251 y = ((x + round_ptr[rc]) * quant_ptr[rc]) >> 16; // quantize (x)
252 x = (y ^ sz) - sz; // get the sign back
253 qcoeff_ptr[rc] = x; // write to destination
254 dqcoeff_ptr[rc] = x * dequant_ptr[rc]; // dequantized value
255
256 if (y)
257 {
258 eob = i; // last nonzero coeffs
259 zbin_boost_ptr = &b->zrun_zbin_boost[0]; // reset zero runlength
260 }
261 }
262 }
263
264 d->eob = eob + 1;
265 }
266
267 #endif
268
vp8_quantize_mby(MACROBLOCK * x)269 void vp8_quantize_mby(MACROBLOCK *x)
270 {
271 int i;
272 int has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED
273 && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV);
274
275 for (i = 0; i < 16; i++)
276 x->quantize_b(&x->block[i], &x->e_mbd.block[i]);
277
278 if(has_2nd_order)
279 x->quantize_b(&x->block[24], &x->e_mbd.block[24]);
280 }
281
vp8_quantize_mb(MACROBLOCK * x)282 void vp8_quantize_mb(MACROBLOCK *x)
283 {
284 int i;
285 int has_2nd_order=(x->e_mbd.mode_info_context->mbmi.mode != B_PRED
286 && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV);
287
288 for (i = 0; i < 24+has_2nd_order; i++)
289 x->quantize_b(&x->block[i], &x->e_mbd.block[i]);
290 }
291
292
vp8_quantize_mbuv(MACROBLOCK * x)293 void vp8_quantize_mbuv(MACROBLOCK *x)
294 {
295 int i;
296
297 for (i = 16; i < 24; i++)
298 x->quantize_b(&x->block[i], &x->e_mbd.block[i]);
299 }
300