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