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