• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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