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 "onyx_int.h"
16#include "quantize.h"
17#include "vp8/common/quant_common.h"
18
19void vp8_fast_quantize_b_c(BLOCK *b, BLOCKD *d)
20{
21    int i, rc, eob;
22    int x, y, z, sz;
23    short *coeff_ptr   = b->coeff;
24    short *round_ptr   = b->round;
25    short *quant_ptr   = b->quant_fast;
26    short *qcoeff_ptr  = d->qcoeff;
27    short *dqcoeff_ptr = d->dqcoeff;
28    short *dequant_ptr = d->dequant;
29
30    eob = -1;
31    for (i = 0; i < 16; i++)
32    {
33        rc   = vp8_default_zig_zag1d[i];
34        z    = coeff_ptr[rc];
35
36        sz = (z >> 31);                              /* sign of z */
37        x  = (z ^ sz) - sz;                          /* x = abs(z) */
38
39        y  = ((x + round_ptr[rc]) * quant_ptr[rc]) >> 16; /* quantize (x) */
40        x  = (y ^ sz) - sz;                          /* get the sign back */
41        qcoeff_ptr[rc] = x;                          /* write to destination */
42        dqcoeff_ptr[rc] = x * dequant_ptr[rc];       /* dequantized value */
43
44        if (y)
45        {
46            eob = i;                                 /* last nonzero coeffs */
47        }
48    }
49    *d->eob = (char)(eob + 1);
50}
51
52void vp8_regular_quantize_b_c(BLOCK *b, BLOCKD *d)
53{
54    int i, rc, eob;
55    int zbin;
56    int x, y, z, sz;
57    short *zbin_boost_ptr  = b->zrun_zbin_boost;
58    short *coeff_ptr       = b->coeff;
59    short *zbin_ptr        = b->zbin;
60    short *round_ptr       = b->round;
61    short *quant_ptr       = b->quant;
62    short *quant_shift_ptr = b->quant_shift;
63    short *qcoeff_ptr      = d->qcoeff;
64    short *dqcoeff_ptr     = d->dqcoeff;
65    short *dequant_ptr     = d->dequant;
66    short zbin_oq_value    = b->zbin_extra;
67
68    vpx_memset(qcoeff_ptr, 0, 32);
69    vpx_memset(dqcoeff_ptr, 0, 32);
70
71    eob = -1;
72
73    for (i = 0; i < 16; i++)
74    {
75        rc   = vp8_default_zig_zag1d[i];
76        z    = coeff_ptr[rc];
77
78        zbin = zbin_ptr[rc] + *zbin_boost_ptr + zbin_oq_value;
79
80        zbin_boost_ptr ++;
81        sz = (z >> 31);                              /* sign of z */
82        x  = (z ^ sz) - sz;                          /* x = abs(z) */
83
84        if (x >= zbin)
85        {
86            x += round_ptr[rc];
87            y  = ((((x * quant_ptr[rc]) >> 16) + x)
88                 * quant_shift_ptr[rc]) >> 16;       /* quantize (x) */
89            x  = (y ^ sz) - sz;                      /* get the sign back */
90            qcoeff_ptr[rc]  = x;                     /* write to destination */
91            dqcoeff_ptr[rc] = x * dequant_ptr[rc];   /* dequantized value */
92
93            if (y)
94            {
95                eob = i;                             /* last nonzero coeffs */
96                zbin_boost_ptr = b->zrun_zbin_boost; /* reset zero runlength */
97            }
98        }
99    }
100
101    *d->eob = (char)(eob + 1);
102}
103
104void vp8_quantize_mby_c(MACROBLOCK *x)
105{
106    int i;
107    int has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED
108        && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV);
109
110    for (i = 0; i < 16; i++)
111        x->quantize_b(&x->block[i], &x->e_mbd.block[i]);
112
113    if(has_2nd_order)
114        x->quantize_b(&x->block[24], &x->e_mbd.block[24]);
115}
116
117void vp8_quantize_mb_c(MACROBLOCK *x)
118{
119    int i;
120    int has_2nd_order=(x->e_mbd.mode_info_context->mbmi.mode != B_PRED
121        && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV);
122
123    for (i = 0; i < 24+has_2nd_order; i++)
124        x->quantize_b(&x->block[i], &x->e_mbd.block[i]);
125}
126
127
128void vp8_quantize_mbuv_c(MACROBLOCK *x)
129{
130    int i;
131
132    for (i = 16; i < 24; i++)
133        x->quantize_b(&x->block[i], &x->e_mbd.block[i]);
134}
135
136/* quantize_b_pair function pointer in MACROBLOCK structure is set to one of
137 * these two C functions if corresponding optimized routine is not available.
138 * NEON optimized version implements currently the fast quantization for pair
139 * of blocks. */
140void vp8_regular_quantize_b_pair(BLOCK *b1, BLOCK *b2, BLOCKD *d1, BLOCKD *d2)
141{
142    vp8_regular_quantize_b(b1, d1);
143    vp8_regular_quantize_b(b2, d2);
144}
145
146void vp8_fast_quantize_b_pair_c(BLOCK *b1, BLOCK *b2, BLOCKD *d1, BLOCKD *d2)
147{
148    vp8_fast_quantize_b_c(b1, d1);
149    vp8_fast_quantize_b_c(b2, d2);
150}
151
152
153static const int qrounding_factors[129] =
154{
155    48, 48, 48, 48, 48, 48, 48, 48,
156    48, 48, 48, 48, 48, 48, 48, 48,
157    48, 48, 48, 48, 48, 48, 48, 48,
158    48, 48, 48, 48, 48, 48, 48, 48,
159    48, 48, 48, 48, 48, 48, 48, 48,
160    48, 48, 48, 48, 48, 48, 48, 48,
161    48, 48, 48, 48, 48, 48, 48, 48,
162    48, 48, 48, 48, 48, 48, 48, 48,
163    48, 48, 48, 48, 48, 48, 48, 48,
164    48, 48, 48, 48, 48, 48, 48, 48,
165    48, 48, 48, 48, 48, 48, 48, 48,
166    48, 48, 48, 48, 48, 48, 48, 48,
167    48, 48, 48, 48, 48, 48, 48, 48,
168    48, 48, 48, 48, 48, 48, 48, 48,
169    48, 48, 48, 48, 48, 48, 48, 48,
170    48, 48, 48, 48, 48, 48, 48, 48,
171    48
172};
173
174
175static const int qzbin_factors[129] =
176{
177    84, 84, 84, 84, 84, 84, 84, 84,
178    84, 84, 84, 84, 84, 84, 84, 84,
179    84, 84, 84, 84, 84, 84, 84, 84,
180    84, 84, 84, 84, 84, 84, 84, 84,
181    84, 84, 84, 84, 84, 84, 84, 84,
182    84, 84, 84, 84, 84, 84, 84, 84,
183    80, 80, 80, 80, 80, 80, 80, 80,
184    80, 80, 80, 80, 80, 80, 80, 80,
185    80, 80, 80, 80, 80, 80, 80, 80,
186    80, 80, 80, 80, 80, 80, 80, 80,
187    80, 80, 80, 80, 80, 80, 80, 80,
188    80, 80, 80, 80, 80, 80, 80, 80,
189    80, 80, 80, 80, 80, 80, 80, 80,
190    80, 80, 80, 80, 80, 80, 80, 80,
191    80, 80, 80, 80, 80, 80, 80, 80,
192    80, 80, 80, 80, 80, 80, 80, 80,
193    80
194};
195
196
197static const int qrounding_factors_y2[129] =
198{
199    48, 48, 48, 48, 48, 48, 48, 48,
200    48, 48, 48, 48, 48, 48, 48, 48,
201    48, 48, 48, 48, 48, 48, 48, 48,
202    48, 48, 48, 48, 48, 48, 48, 48,
203    48, 48, 48, 48, 48, 48, 48, 48,
204    48, 48, 48, 48, 48, 48, 48, 48,
205    48, 48, 48, 48, 48, 48, 48, 48,
206    48, 48, 48, 48, 48, 48, 48, 48,
207    48, 48, 48, 48, 48, 48, 48, 48,
208    48, 48, 48, 48, 48, 48, 48, 48,
209    48, 48, 48, 48, 48, 48, 48, 48,
210    48, 48, 48, 48, 48, 48, 48, 48,
211    48, 48, 48, 48, 48, 48, 48, 48,
212    48, 48, 48, 48, 48, 48, 48, 48,
213    48, 48, 48, 48, 48, 48, 48, 48,
214    48, 48, 48, 48, 48, 48, 48, 48,
215    48
216};
217
218
219static const int qzbin_factors_y2[129] =
220{
221    84, 84, 84, 84, 84, 84, 84, 84,
222    84, 84, 84, 84, 84, 84, 84, 84,
223    84, 84, 84, 84, 84, 84, 84, 84,
224    84, 84, 84, 84, 84, 84, 84, 84,
225    84, 84, 84, 84, 84, 84, 84, 84,
226    84, 84, 84, 84, 84, 84, 84, 84,
227    80, 80, 80, 80, 80, 80, 80, 80,
228    80, 80, 80, 80, 80, 80, 80, 80,
229    80, 80, 80, 80, 80, 80, 80, 80,
230    80, 80, 80, 80, 80, 80, 80, 80,
231    80, 80, 80, 80, 80, 80, 80, 80,
232    80, 80, 80, 80, 80, 80, 80, 80,
233    80, 80, 80, 80, 80, 80, 80, 80,
234    80, 80, 80, 80, 80, 80, 80, 80,
235    80, 80, 80, 80, 80, 80, 80, 80,
236    80, 80, 80, 80, 80, 80, 80, 80,
237    80
238};
239
240
241static void invert_quant(int improved_quant, short *quant,
242                         short *shift, short d)
243{
244    if(improved_quant)
245    {
246        unsigned t;
247        int l;
248        t = d;
249        for(l = 0; t > 1; l++)
250            t>>=1;
251        t = 1 + (1<<(16+l))/d;
252        *quant = (short)(t - (1<<16));
253        *shift = l;
254        /* use multiplication and constant shift by 16 */
255        *shift = 1 << (16 - *shift);
256    }
257    else
258    {
259        *quant = (1 << 16) / d;
260        *shift = 0;
261        /* use multiplication and constant shift by 16 */
262        *shift = 1 << (16 - *shift);
263    }
264}
265
266
267void vp8cx_init_quantizer(VP8_COMP *cpi)
268{
269    int i;
270    int quant_val;
271    int Q;
272
273    int zbin_boost[16] = {0, 0, 8, 10, 12, 14, 16, 20, 24, 28, 32, 36, 40, 44,
274                          44, 44};
275
276    for (Q = 0; Q < QINDEX_RANGE; Q++)
277    {
278        /* dc values */
279        quant_val = vp8_dc_quant(Q, cpi->common.y1dc_delta_q);
280        cpi->Y1quant_fast[Q][0] = (1 << 16) / quant_val;
281        invert_quant(cpi->sf.improved_quant, cpi->Y1quant[Q] + 0,
282                     cpi->Y1quant_shift[Q] + 0, quant_val);
283        cpi->Y1zbin[Q][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
284        cpi->Y1round[Q][0] = (qrounding_factors[Q] * quant_val) >> 7;
285        cpi->common.Y1dequant[Q][0] = quant_val;
286        cpi->zrun_zbin_boost_y1[Q][0] = (quant_val * zbin_boost[0]) >> 7;
287
288        quant_val = vp8_dc2quant(Q, cpi->common.y2dc_delta_q);
289        cpi->Y2quant_fast[Q][0] = (1 << 16) / quant_val;
290        invert_quant(cpi->sf.improved_quant, cpi->Y2quant[Q] + 0,
291                     cpi->Y2quant_shift[Q] + 0, quant_val);
292        cpi->Y2zbin[Q][0] = ((qzbin_factors_y2[Q] * quant_val) + 64) >> 7;
293        cpi->Y2round[Q][0] = (qrounding_factors_y2[Q] * quant_val) >> 7;
294        cpi->common.Y2dequant[Q][0] = quant_val;
295        cpi->zrun_zbin_boost_y2[Q][0] = (quant_val * zbin_boost[0]) >> 7;
296
297        quant_val = vp8_dc_uv_quant(Q, cpi->common.uvdc_delta_q);
298        cpi->UVquant_fast[Q][0] = (1 << 16) / quant_val;
299        invert_quant(cpi->sf.improved_quant, cpi->UVquant[Q] + 0,
300                     cpi->UVquant_shift[Q] + 0, quant_val);
301        cpi->UVzbin[Q][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;;
302        cpi->UVround[Q][0] = (qrounding_factors[Q] * quant_val) >> 7;
303        cpi->common.UVdequant[Q][0] = quant_val;
304        cpi->zrun_zbin_boost_uv[Q][0] = (quant_val * zbin_boost[0]) >> 7;
305
306        /* all the ac values = ; */
307        quant_val = vp8_ac_yquant(Q);
308        cpi->Y1quant_fast[Q][1] = (1 << 16) / quant_val;
309        invert_quant(cpi->sf.improved_quant, cpi->Y1quant[Q] + 1,
310                     cpi->Y1quant_shift[Q] + 1, quant_val);
311        cpi->Y1zbin[Q][1] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
312        cpi->Y1round[Q][1] = (qrounding_factors[Q] * quant_val) >> 7;
313        cpi->common.Y1dequant[Q][1] = quant_val;
314        cpi->zrun_zbin_boost_y1[Q][1] = (quant_val * zbin_boost[1]) >> 7;
315
316        quant_val = vp8_ac2quant(Q, cpi->common.y2ac_delta_q);
317        cpi->Y2quant_fast[Q][1] = (1 << 16) / quant_val;
318        invert_quant(cpi->sf.improved_quant, cpi->Y2quant[Q] + 1,
319                     cpi->Y2quant_shift[Q] + 1, quant_val);
320        cpi->Y2zbin[Q][1] = ((qzbin_factors_y2[Q] * quant_val) + 64) >> 7;
321        cpi->Y2round[Q][1] = (qrounding_factors_y2[Q] * quant_val) >> 7;
322        cpi->common.Y2dequant[Q][1] = quant_val;
323        cpi->zrun_zbin_boost_y2[Q][1] = (quant_val * zbin_boost[1]) >> 7;
324
325        quant_val = vp8_ac_uv_quant(Q, cpi->common.uvac_delta_q);
326        cpi->UVquant_fast[Q][1] = (1 << 16) / quant_val;
327        invert_quant(cpi->sf.improved_quant, cpi->UVquant[Q] + 1,
328                     cpi->UVquant_shift[Q] + 1, quant_val);
329        cpi->UVzbin[Q][1] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
330        cpi->UVround[Q][1] = (qrounding_factors[Q] * quant_val) >> 7;
331        cpi->common.UVdequant[Q][1] = quant_val;
332        cpi->zrun_zbin_boost_uv[Q][1] = (quant_val * zbin_boost[1]) >> 7;
333
334        for (i = 2; i < 16; i++)
335        {
336            cpi->Y1quant_fast[Q][i] = cpi->Y1quant_fast[Q][1];
337            cpi->Y1quant[Q][i] = cpi->Y1quant[Q][1];
338            cpi->Y1quant_shift[Q][i] = cpi->Y1quant_shift[Q][1];
339            cpi->Y1zbin[Q][i] = cpi->Y1zbin[Q][1];
340            cpi->Y1round[Q][i] = cpi->Y1round[Q][1];
341            cpi->zrun_zbin_boost_y1[Q][i] = (cpi->common.Y1dequant[Q][1] *
342                                             zbin_boost[i]) >> 7;
343
344            cpi->Y2quant_fast[Q][i] = cpi->Y2quant_fast[Q][1];
345            cpi->Y2quant[Q][i] = cpi->Y2quant[Q][1];
346            cpi->Y2quant_shift[Q][i] = cpi->Y2quant_shift[Q][1];
347            cpi->Y2zbin[Q][i] = cpi->Y2zbin[Q][1];
348            cpi->Y2round[Q][i] = cpi->Y2round[Q][1];
349            cpi->zrun_zbin_boost_y2[Q][i] = (cpi->common.Y2dequant[Q][1] *
350                                             zbin_boost[i]) >> 7;
351
352            cpi->UVquant_fast[Q][i] = cpi->UVquant_fast[Q][1];
353            cpi->UVquant[Q][i] = cpi->UVquant[Q][1];
354            cpi->UVquant_shift[Q][i] = cpi->UVquant_shift[Q][1];
355            cpi->UVzbin[Q][i] = cpi->UVzbin[Q][1];
356            cpi->UVround[Q][i] = cpi->UVround[Q][1];
357            cpi->zrun_zbin_boost_uv[Q][i] = (cpi->common.UVdequant[Q][1] *
358                                             zbin_boost[i]) >> 7;
359        }
360    }
361}
362
363#define ZBIN_EXTRA_Y \
364    (( cpi->common.Y1dequant[QIndex][1] *  \
365    ( x->zbin_over_quant +  \
366      x->zbin_mode_boost +  \
367      x->act_zbin_adj ) ) >> 7)
368
369#define ZBIN_EXTRA_UV \
370    (( cpi->common.UVdequant[QIndex][1] *  \
371    ( x->zbin_over_quant +  \
372      x->zbin_mode_boost +  \
373      x->act_zbin_adj ) ) >> 7)
374
375#define ZBIN_EXTRA_Y2 \
376    (( cpi->common.Y2dequant[QIndex][1] *  \
377    ( (x->zbin_over_quant / 2) +  \
378       x->zbin_mode_boost +  \
379       x->act_zbin_adj ) ) >> 7)
380
381void vp8cx_mb_init_quantizer(VP8_COMP *cpi, MACROBLOCK *x, int ok_to_skip)
382{
383    int i;
384    int QIndex;
385    MACROBLOCKD *xd = &x->e_mbd;
386    int zbin_extra;
387
388    /* Select the baseline MB Q index. */
389    if (xd->segmentation_enabled)
390    {
391        /* Abs Value */
392        if (xd->mb_segement_abs_delta == SEGMENT_ABSDATA)
393            QIndex = xd->segment_feature_data[MB_LVL_ALT_Q][xd->mode_info_context->mbmi.segment_id];
394        /* Delta Value */
395        else
396        {
397            QIndex = cpi->common.base_qindex + xd->segment_feature_data[MB_LVL_ALT_Q][xd->mode_info_context->mbmi.segment_id];
398            /* Clamp to valid range */
399            QIndex = (QIndex >= 0) ? ((QIndex <= MAXQ) ? QIndex : MAXQ) : 0;
400        }
401    }
402    else
403        QIndex = cpi->common.base_qindex;
404
405    /* This initialization should be called at least once. Use ok_to_skip to
406     * decide if it is ok to skip.
407     * Before encoding a frame, this function is always called with ok_to_skip
408     * =0, which means no skiping of calculations. The "last" values are
409     * initialized at that time.
410     */
411    if (!ok_to_skip || QIndex != x->q_index)
412    {
413
414        xd->dequant_y1_dc[0] = 1;
415        xd->dequant_y1[0] = cpi->common.Y1dequant[QIndex][0];
416        xd->dequant_y2[0] = cpi->common.Y2dequant[QIndex][0];
417        xd->dequant_uv[0] = cpi->common.UVdequant[QIndex][0];
418
419        for (i = 1; i < 16; i++)
420        {
421            xd->dequant_y1_dc[i] =
422            xd->dequant_y1[i] = cpi->common.Y1dequant[QIndex][1];
423            xd->dequant_y2[i] = cpi->common.Y2dequant[QIndex][1];
424            xd->dequant_uv[i] = cpi->common.UVdequant[QIndex][1];
425        }
426#if 1
427        /*TODO:  Remove dequant from BLOCKD.  This is a temporary solution until
428         * the quantizer code uses a passed in pointer to the dequant constants.
429         * This will also require modifications to the x86 and neon assembly.
430         * */
431        for (i = 0; i < 16; i++)
432            x->e_mbd.block[i].dequant = xd->dequant_y1;
433        for (i = 16; i < 24; i++)
434            x->e_mbd.block[i].dequant = xd->dequant_uv;
435        x->e_mbd.block[24].dequant = xd->dequant_y2;
436#endif
437
438        /* Y */
439        zbin_extra = ZBIN_EXTRA_Y;
440
441        for (i = 0; i < 16; i++)
442        {
443            x->block[i].quant = cpi->Y1quant[QIndex];
444            x->block[i].quant_fast = cpi->Y1quant_fast[QIndex];
445            x->block[i].quant_shift = cpi->Y1quant_shift[QIndex];
446            x->block[i].zbin = cpi->Y1zbin[QIndex];
447            x->block[i].round = cpi->Y1round[QIndex];
448            x->block[i].zrun_zbin_boost = cpi->zrun_zbin_boost_y1[QIndex];
449            x->block[i].zbin_extra = (short)zbin_extra;
450        }
451
452        /* UV */
453        zbin_extra = ZBIN_EXTRA_UV;
454
455        for (i = 16; i < 24; i++)
456        {
457            x->block[i].quant = cpi->UVquant[QIndex];
458            x->block[i].quant_fast = cpi->UVquant_fast[QIndex];
459            x->block[i].quant_shift = cpi->UVquant_shift[QIndex];
460            x->block[i].zbin = cpi->UVzbin[QIndex];
461            x->block[i].round = cpi->UVround[QIndex];
462            x->block[i].zrun_zbin_boost = cpi->zrun_zbin_boost_uv[QIndex];
463            x->block[i].zbin_extra = (short)zbin_extra;
464        }
465
466        /* Y2 */
467        zbin_extra = ZBIN_EXTRA_Y2;
468
469        x->block[24].quant_fast = cpi->Y2quant_fast[QIndex];
470        x->block[24].quant = cpi->Y2quant[QIndex];
471        x->block[24].quant_shift = cpi->Y2quant_shift[QIndex];
472        x->block[24].zbin = cpi->Y2zbin[QIndex];
473        x->block[24].round = cpi->Y2round[QIndex];
474        x->block[24].zrun_zbin_boost = cpi->zrun_zbin_boost_y2[QIndex];
475        x->block[24].zbin_extra = (short)zbin_extra;
476
477        /* save this macroblock QIndex for vp8_update_zbin_extra() */
478        x->q_index = QIndex;
479
480        x->last_zbin_over_quant = x->zbin_over_quant;
481        x->last_zbin_mode_boost = x->zbin_mode_boost;
482        x->last_act_zbin_adj = x->act_zbin_adj;
483
484
485
486    }
487    else if(x->last_zbin_over_quant != x->zbin_over_quant
488            || x->last_zbin_mode_boost != x->zbin_mode_boost
489            || x->last_act_zbin_adj != x->act_zbin_adj)
490    {
491        /* Y */
492        zbin_extra = ZBIN_EXTRA_Y;
493
494        for (i = 0; i < 16; i++)
495            x->block[i].zbin_extra = (short)zbin_extra;
496
497        /* UV */
498        zbin_extra = ZBIN_EXTRA_UV;
499
500        for (i = 16; i < 24; i++)
501            x->block[i].zbin_extra = (short)zbin_extra;
502
503        /* Y2 */
504        zbin_extra = ZBIN_EXTRA_Y2;
505        x->block[24].zbin_extra = (short)zbin_extra;
506
507        x->last_zbin_over_quant = x->zbin_over_quant;
508        x->last_zbin_mode_boost = x->zbin_mode_boost;
509        x->last_act_zbin_adj = x->act_zbin_adj;
510    }
511}
512
513void vp8_update_zbin_extra(VP8_COMP *cpi, MACROBLOCK *x)
514{
515    int i;
516    int QIndex = x->q_index;
517    int zbin_extra;
518
519    /* Y */
520    zbin_extra = ZBIN_EXTRA_Y;
521
522    for (i = 0; i < 16; i++)
523        x->block[i].zbin_extra = (short)zbin_extra;
524
525    /* UV */
526    zbin_extra = ZBIN_EXTRA_UV;
527
528    for (i = 16; i < 24; i++)
529        x->block[i].zbin_extra = (short)zbin_extra;
530
531    /* Y2 */
532    zbin_extra = ZBIN_EXTRA_Y2;
533    x->block[24].zbin_extra = (short)zbin_extra;
534}
535#undef ZBIN_EXTRA_Y
536#undef ZBIN_EXTRA_UV
537#undef ZBIN_EXTRA_Y2
538
539void vp8cx_frame_init_quantizer(VP8_COMP *cpi)
540{
541    /* Clear Zbin mode boost for default case */
542    cpi->mb.zbin_mode_boost = 0;
543
544    /* MB level quantizer setup */
545    vp8cx_mb_init_quantizer(cpi, &cpi->mb, 0);
546}
547
548
549void vp8_set_quantizer(struct VP8_COMP *cpi, int Q)
550{
551    VP8_COMMON *cm = &cpi->common;
552    MACROBLOCKD *mbd = &cpi->mb.e_mbd;
553    int update = 0;
554    int new_delta_q;
555    cm->base_qindex = Q;
556
557    /* if any of the delta_q values are changing update flag has to be set */
558    /* currently only y2dc_delta_q may change */
559
560    cm->y1dc_delta_q = 0;
561    cm->y2ac_delta_q = 0;
562    cm->uvdc_delta_q = 0;
563    cm->uvac_delta_q = 0;
564
565    if (Q < 4)
566    {
567        new_delta_q = 4-Q;
568    }
569    else
570        new_delta_q = 0;
571
572    update |= cm->y2dc_delta_q != new_delta_q;
573    cm->y2dc_delta_q = new_delta_q;
574
575
576    /* Set Segment specific quatizers */
577    mbd->segment_feature_data[MB_LVL_ALT_Q][0] = cpi->segment_feature_data[MB_LVL_ALT_Q][0];
578    mbd->segment_feature_data[MB_LVL_ALT_Q][1] = cpi->segment_feature_data[MB_LVL_ALT_Q][1];
579    mbd->segment_feature_data[MB_LVL_ALT_Q][2] = cpi->segment_feature_data[MB_LVL_ALT_Q][2];
580    mbd->segment_feature_data[MB_LVL_ALT_Q][3] = cpi->segment_feature_data[MB_LVL_ALT_Q][3];
581
582    /* quantizer has to be reinitialized for any delta_q changes */
583    if(update)
584        vp8cx_init_quantizer(cpi);
585
586}
587