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 "vp8/encoder/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    memset(qcoeff_ptr, 0, 32);
69    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(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(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(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
136static const int qrounding_factors[129] =
137{
138    48, 48, 48, 48, 48, 48, 48, 48,
139    48, 48, 48, 48, 48, 48, 48, 48,
140    48, 48, 48, 48, 48, 48, 48, 48,
141    48, 48, 48, 48, 48, 48, 48, 48,
142    48, 48, 48, 48, 48, 48, 48, 48,
143    48, 48, 48, 48, 48, 48, 48, 48,
144    48, 48, 48, 48, 48, 48, 48, 48,
145    48, 48, 48, 48, 48, 48, 48, 48,
146    48, 48, 48, 48, 48, 48, 48, 48,
147    48, 48, 48, 48, 48, 48, 48, 48,
148    48, 48, 48, 48, 48, 48, 48, 48,
149    48, 48, 48, 48, 48, 48, 48, 48,
150    48, 48, 48, 48, 48, 48, 48, 48,
151    48, 48, 48, 48, 48, 48, 48, 48,
152    48, 48, 48, 48, 48, 48, 48, 48,
153    48, 48, 48, 48, 48, 48, 48, 48,
154    48
155};
156
157
158static const int qzbin_factors[129] =
159{
160    84, 84, 84, 84, 84, 84, 84, 84,
161    84, 84, 84, 84, 84, 84, 84, 84,
162    84, 84, 84, 84, 84, 84, 84, 84,
163    84, 84, 84, 84, 84, 84, 84, 84,
164    84, 84, 84, 84, 84, 84, 84, 84,
165    84, 84, 84, 84, 84, 84, 84, 84,
166    80, 80, 80, 80, 80, 80, 80, 80,
167    80, 80, 80, 80, 80, 80, 80, 80,
168    80, 80, 80, 80, 80, 80, 80, 80,
169    80, 80, 80, 80, 80, 80, 80, 80,
170    80, 80, 80, 80, 80, 80, 80, 80,
171    80, 80, 80, 80, 80, 80, 80, 80,
172    80, 80, 80, 80, 80, 80, 80, 80,
173    80, 80, 80, 80, 80, 80, 80, 80,
174    80, 80, 80, 80, 80, 80, 80, 80,
175    80, 80, 80, 80, 80, 80, 80, 80,
176    80
177};
178
179
180static const int qrounding_factors_y2[129] =
181{
182    48, 48, 48, 48, 48, 48, 48, 48,
183    48, 48, 48, 48, 48, 48, 48, 48,
184    48, 48, 48, 48, 48, 48, 48, 48,
185    48, 48, 48, 48, 48, 48, 48, 48,
186    48, 48, 48, 48, 48, 48, 48, 48,
187    48, 48, 48, 48, 48, 48, 48, 48,
188    48, 48, 48, 48, 48, 48, 48, 48,
189    48, 48, 48, 48, 48, 48, 48, 48,
190    48, 48, 48, 48, 48, 48, 48, 48,
191    48, 48, 48, 48, 48, 48, 48, 48,
192    48, 48, 48, 48, 48, 48, 48, 48,
193    48, 48, 48, 48, 48, 48, 48, 48,
194    48, 48, 48, 48, 48, 48, 48, 48,
195    48, 48, 48, 48, 48, 48, 48, 48,
196    48, 48, 48, 48, 48, 48, 48, 48,
197    48, 48, 48, 48, 48, 48, 48, 48,
198    48
199};
200
201
202static const int qzbin_factors_y2[129] =
203{
204    84, 84, 84, 84, 84, 84, 84, 84,
205    84, 84, 84, 84, 84, 84, 84, 84,
206    84, 84, 84, 84, 84, 84, 84, 84,
207    84, 84, 84, 84, 84, 84, 84, 84,
208    84, 84, 84, 84, 84, 84, 84, 84,
209    84, 84, 84, 84, 84, 84, 84, 84,
210    80, 80, 80, 80, 80, 80, 80, 80,
211    80, 80, 80, 80, 80, 80, 80, 80,
212    80, 80, 80, 80, 80, 80, 80, 80,
213    80, 80, 80, 80, 80, 80, 80, 80,
214    80, 80, 80, 80, 80, 80, 80, 80,
215    80, 80, 80, 80, 80, 80, 80, 80,
216    80, 80, 80, 80, 80, 80, 80, 80,
217    80, 80, 80, 80, 80, 80, 80, 80,
218    80, 80, 80, 80, 80, 80, 80, 80,
219    80, 80, 80, 80, 80, 80, 80, 80,
220    80
221};
222
223
224static void invert_quant(int improved_quant, short *quant,
225                         short *shift, short d)
226{
227    if(improved_quant)
228    {
229        unsigned t;
230        int l;
231        t = d;
232        for(l = 0; t > 1; l++)
233            t>>=1;
234        t = 1 + (1<<(16+l))/d;
235        *quant = (short)(t - (1<<16));
236        *shift = l;
237        /* use multiplication and constant shift by 16 */
238        *shift = 1 << (16 - *shift);
239    }
240    else
241    {
242        *quant = (1 << 16) / d;
243        *shift = 0;
244        /* use multiplication and constant shift by 16 */
245        *shift = 1 << (16 - *shift);
246    }
247}
248
249
250void vp8cx_init_quantizer(VP8_COMP *cpi)
251{
252    int i;
253    int quant_val;
254    int Q;
255
256    int zbin_boost[16] = {0, 0, 8, 10, 12, 14, 16, 20, 24, 28, 32, 36, 40, 44,
257                          44, 44};
258
259    for (Q = 0; Q < QINDEX_RANGE; Q++)
260    {
261        /* dc values */
262        quant_val = vp8_dc_quant(Q, cpi->common.y1dc_delta_q);
263        cpi->Y1quant_fast[Q][0] = (1 << 16) / quant_val;
264        invert_quant(cpi->sf.improved_quant, cpi->Y1quant[Q] + 0,
265                     cpi->Y1quant_shift[Q] + 0, quant_val);
266        cpi->Y1zbin[Q][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
267        cpi->Y1round[Q][0] = (qrounding_factors[Q] * quant_val) >> 7;
268        cpi->common.Y1dequant[Q][0] = quant_val;
269        cpi->zrun_zbin_boost_y1[Q][0] = (quant_val * zbin_boost[0]) >> 7;
270
271        quant_val = vp8_dc2quant(Q, cpi->common.y2dc_delta_q);
272        cpi->Y2quant_fast[Q][0] = (1 << 16) / quant_val;
273        invert_quant(cpi->sf.improved_quant, cpi->Y2quant[Q] + 0,
274                     cpi->Y2quant_shift[Q] + 0, quant_val);
275        cpi->Y2zbin[Q][0] = ((qzbin_factors_y2[Q] * quant_val) + 64) >> 7;
276        cpi->Y2round[Q][0] = (qrounding_factors_y2[Q] * quant_val) >> 7;
277        cpi->common.Y2dequant[Q][0] = quant_val;
278        cpi->zrun_zbin_boost_y2[Q][0] = (quant_val * zbin_boost[0]) >> 7;
279
280        quant_val = vp8_dc_uv_quant(Q, cpi->common.uvdc_delta_q);
281        cpi->UVquant_fast[Q][0] = (1 << 16) / quant_val;
282        invert_quant(cpi->sf.improved_quant, cpi->UVquant[Q] + 0,
283                     cpi->UVquant_shift[Q] + 0, quant_val);
284        cpi->UVzbin[Q][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;;
285        cpi->UVround[Q][0] = (qrounding_factors[Q] * quant_val) >> 7;
286        cpi->common.UVdequant[Q][0] = quant_val;
287        cpi->zrun_zbin_boost_uv[Q][0] = (quant_val * zbin_boost[0]) >> 7;
288
289        /* all the ac values = ; */
290        quant_val = vp8_ac_yquant(Q);
291        cpi->Y1quant_fast[Q][1] = (1 << 16) / quant_val;
292        invert_quant(cpi->sf.improved_quant, cpi->Y1quant[Q] + 1,
293                     cpi->Y1quant_shift[Q] + 1, quant_val);
294        cpi->Y1zbin[Q][1] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
295        cpi->Y1round[Q][1] = (qrounding_factors[Q] * quant_val) >> 7;
296        cpi->common.Y1dequant[Q][1] = quant_val;
297        cpi->zrun_zbin_boost_y1[Q][1] = (quant_val * zbin_boost[1]) >> 7;
298
299        quant_val = vp8_ac2quant(Q, cpi->common.y2ac_delta_q);
300        cpi->Y2quant_fast[Q][1] = (1 << 16) / quant_val;
301        invert_quant(cpi->sf.improved_quant, cpi->Y2quant[Q] + 1,
302                     cpi->Y2quant_shift[Q] + 1, quant_val);
303        cpi->Y2zbin[Q][1] = ((qzbin_factors_y2[Q] * quant_val) + 64) >> 7;
304        cpi->Y2round[Q][1] = (qrounding_factors_y2[Q] * quant_val) >> 7;
305        cpi->common.Y2dequant[Q][1] = quant_val;
306        cpi->zrun_zbin_boost_y2[Q][1] = (quant_val * zbin_boost[1]) >> 7;
307
308        quant_val = vp8_ac_uv_quant(Q, cpi->common.uvac_delta_q);
309        cpi->UVquant_fast[Q][1] = (1 << 16) / quant_val;
310        invert_quant(cpi->sf.improved_quant, cpi->UVquant[Q] + 1,
311                     cpi->UVquant_shift[Q] + 1, quant_val);
312        cpi->UVzbin[Q][1] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
313        cpi->UVround[Q][1] = (qrounding_factors[Q] * quant_val) >> 7;
314        cpi->common.UVdequant[Q][1] = quant_val;
315        cpi->zrun_zbin_boost_uv[Q][1] = (quant_val * zbin_boost[1]) >> 7;
316
317        for (i = 2; i < 16; i++)
318        {
319            cpi->Y1quant_fast[Q][i] = cpi->Y1quant_fast[Q][1];
320            cpi->Y1quant[Q][i] = cpi->Y1quant[Q][1];
321            cpi->Y1quant_shift[Q][i] = cpi->Y1quant_shift[Q][1];
322            cpi->Y1zbin[Q][i] = cpi->Y1zbin[Q][1];
323            cpi->Y1round[Q][i] = cpi->Y1round[Q][1];
324            cpi->zrun_zbin_boost_y1[Q][i] = (cpi->common.Y1dequant[Q][1] *
325                                             zbin_boost[i]) >> 7;
326
327            cpi->Y2quant_fast[Q][i] = cpi->Y2quant_fast[Q][1];
328            cpi->Y2quant[Q][i] = cpi->Y2quant[Q][1];
329            cpi->Y2quant_shift[Q][i] = cpi->Y2quant_shift[Q][1];
330            cpi->Y2zbin[Q][i] = cpi->Y2zbin[Q][1];
331            cpi->Y2round[Q][i] = cpi->Y2round[Q][1];
332            cpi->zrun_zbin_boost_y2[Q][i] = (cpi->common.Y2dequant[Q][1] *
333                                             zbin_boost[i]) >> 7;
334
335            cpi->UVquant_fast[Q][i] = cpi->UVquant_fast[Q][1];
336            cpi->UVquant[Q][i] = cpi->UVquant[Q][1];
337            cpi->UVquant_shift[Q][i] = cpi->UVquant_shift[Q][1];
338            cpi->UVzbin[Q][i] = cpi->UVzbin[Q][1];
339            cpi->UVround[Q][i] = cpi->UVround[Q][1];
340            cpi->zrun_zbin_boost_uv[Q][i] = (cpi->common.UVdequant[Q][1] *
341                                             zbin_boost[i]) >> 7;
342        }
343    }
344}
345
346#define ZBIN_EXTRA_Y \
347    (( cpi->common.Y1dequant[QIndex][1] *  \
348    ( x->zbin_over_quant +  \
349      x->zbin_mode_boost +  \
350      x->act_zbin_adj ) ) >> 7)
351
352#define ZBIN_EXTRA_UV \
353    (( cpi->common.UVdequant[QIndex][1] *  \
354    ( x->zbin_over_quant +  \
355      x->zbin_mode_boost +  \
356      x->act_zbin_adj ) ) >> 7)
357
358#define ZBIN_EXTRA_Y2 \
359    (( cpi->common.Y2dequant[QIndex][1] *  \
360    ( (x->zbin_over_quant / 2) +  \
361       x->zbin_mode_boost +  \
362       x->act_zbin_adj ) ) >> 7)
363
364void vp8cx_mb_init_quantizer(VP8_COMP *cpi, MACROBLOCK *x, int ok_to_skip)
365{
366    int i;
367    int QIndex;
368    MACROBLOCKD *xd = &x->e_mbd;
369    int zbin_extra;
370
371    /* Select the baseline MB Q index. */
372    if (xd->segmentation_enabled)
373    {
374        /* Abs Value */
375        if (xd->mb_segement_abs_delta == SEGMENT_ABSDATA)
376            QIndex = xd->segment_feature_data[MB_LVL_ALT_Q][xd->mode_info_context->mbmi.segment_id];
377        /* Delta Value */
378        else
379        {
380            QIndex = cpi->common.base_qindex + xd->segment_feature_data[MB_LVL_ALT_Q][xd->mode_info_context->mbmi.segment_id];
381            /* Clamp to valid range */
382            QIndex = (QIndex >= 0) ? ((QIndex <= MAXQ) ? QIndex : MAXQ) : 0;
383        }
384    }
385    else
386        QIndex = cpi->common.base_qindex;
387
388    /* This initialization should be called at least once. Use ok_to_skip to
389     * decide if it is ok to skip.
390     * Before encoding a frame, this function is always called with ok_to_skip
391     * =0, which means no skiping of calculations. The "last" values are
392     * initialized at that time.
393     */
394    if (!ok_to_skip || QIndex != x->q_index)
395    {
396
397        xd->dequant_y1_dc[0] = 1;
398        xd->dequant_y1[0] = cpi->common.Y1dequant[QIndex][0];
399        xd->dequant_y2[0] = cpi->common.Y2dequant[QIndex][0];
400        xd->dequant_uv[0] = cpi->common.UVdequant[QIndex][0];
401
402        for (i = 1; i < 16; i++)
403        {
404            xd->dequant_y1_dc[i] =
405            xd->dequant_y1[i] = cpi->common.Y1dequant[QIndex][1];
406            xd->dequant_y2[i] = cpi->common.Y2dequant[QIndex][1];
407            xd->dequant_uv[i] = cpi->common.UVdequant[QIndex][1];
408        }
409#if 1
410        /*TODO:  Remove dequant from BLOCKD.  This is a temporary solution until
411         * the quantizer code uses a passed in pointer to the dequant constants.
412         * This will also require modifications to the x86 and neon assembly.
413         * */
414        for (i = 0; i < 16; i++)
415            x->e_mbd.block[i].dequant = xd->dequant_y1;
416        for (i = 16; i < 24; i++)
417            x->e_mbd.block[i].dequant = xd->dequant_uv;
418        x->e_mbd.block[24].dequant = xd->dequant_y2;
419#endif
420
421        /* Y */
422        zbin_extra = ZBIN_EXTRA_Y;
423
424        for (i = 0; i < 16; i++)
425        {
426            x->block[i].quant = cpi->Y1quant[QIndex];
427            x->block[i].quant_fast = cpi->Y1quant_fast[QIndex];
428            x->block[i].quant_shift = cpi->Y1quant_shift[QIndex];
429            x->block[i].zbin = cpi->Y1zbin[QIndex];
430            x->block[i].round = cpi->Y1round[QIndex];
431            x->block[i].zrun_zbin_boost = cpi->zrun_zbin_boost_y1[QIndex];
432            x->block[i].zbin_extra = (short)zbin_extra;
433        }
434
435        /* UV */
436        zbin_extra = ZBIN_EXTRA_UV;
437
438        for (i = 16; i < 24; i++)
439        {
440            x->block[i].quant = cpi->UVquant[QIndex];
441            x->block[i].quant_fast = cpi->UVquant_fast[QIndex];
442            x->block[i].quant_shift = cpi->UVquant_shift[QIndex];
443            x->block[i].zbin = cpi->UVzbin[QIndex];
444            x->block[i].round = cpi->UVround[QIndex];
445            x->block[i].zrun_zbin_boost = cpi->zrun_zbin_boost_uv[QIndex];
446            x->block[i].zbin_extra = (short)zbin_extra;
447        }
448
449        /* Y2 */
450        zbin_extra = ZBIN_EXTRA_Y2;
451
452        x->block[24].quant_fast = cpi->Y2quant_fast[QIndex];
453        x->block[24].quant = cpi->Y2quant[QIndex];
454        x->block[24].quant_shift = cpi->Y2quant_shift[QIndex];
455        x->block[24].zbin = cpi->Y2zbin[QIndex];
456        x->block[24].round = cpi->Y2round[QIndex];
457        x->block[24].zrun_zbin_boost = cpi->zrun_zbin_boost_y2[QIndex];
458        x->block[24].zbin_extra = (short)zbin_extra;
459
460        /* save this macroblock QIndex for vp8_update_zbin_extra() */
461        x->q_index = QIndex;
462
463        x->last_zbin_over_quant = x->zbin_over_quant;
464        x->last_zbin_mode_boost = x->zbin_mode_boost;
465        x->last_act_zbin_adj = x->act_zbin_adj;
466
467
468
469    }
470    else if(x->last_zbin_over_quant != x->zbin_over_quant
471            || x->last_zbin_mode_boost != x->zbin_mode_boost
472            || x->last_act_zbin_adj != x->act_zbin_adj)
473    {
474        /* Y */
475        zbin_extra = ZBIN_EXTRA_Y;
476
477        for (i = 0; i < 16; i++)
478            x->block[i].zbin_extra = (short)zbin_extra;
479
480        /* UV */
481        zbin_extra = ZBIN_EXTRA_UV;
482
483        for (i = 16; i < 24; i++)
484            x->block[i].zbin_extra = (short)zbin_extra;
485
486        /* Y2 */
487        zbin_extra = ZBIN_EXTRA_Y2;
488        x->block[24].zbin_extra = (short)zbin_extra;
489
490        x->last_zbin_over_quant = x->zbin_over_quant;
491        x->last_zbin_mode_boost = x->zbin_mode_boost;
492        x->last_act_zbin_adj = x->act_zbin_adj;
493    }
494}
495
496void vp8_update_zbin_extra(VP8_COMP *cpi, MACROBLOCK *x)
497{
498    int i;
499    int QIndex = x->q_index;
500    int zbin_extra;
501
502    /* Y */
503    zbin_extra = ZBIN_EXTRA_Y;
504
505    for (i = 0; i < 16; i++)
506        x->block[i].zbin_extra = (short)zbin_extra;
507
508    /* UV */
509    zbin_extra = ZBIN_EXTRA_UV;
510
511    for (i = 16; i < 24; i++)
512        x->block[i].zbin_extra = (short)zbin_extra;
513
514    /* Y2 */
515    zbin_extra = ZBIN_EXTRA_Y2;
516    x->block[24].zbin_extra = (short)zbin_extra;
517}
518#undef ZBIN_EXTRA_Y
519#undef ZBIN_EXTRA_UV
520#undef ZBIN_EXTRA_Y2
521
522void vp8cx_frame_init_quantizer(VP8_COMP *cpi)
523{
524    /* Clear Zbin mode boost for default case */
525    cpi->mb.zbin_mode_boost = 0;
526
527    /* MB level quantizer setup */
528    vp8cx_mb_init_quantizer(cpi, &cpi->mb, 0);
529}
530
531
532void vp8_set_quantizer(struct VP8_COMP *cpi, int Q)
533{
534    VP8_COMMON *cm = &cpi->common;
535    MACROBLOCKD *mbd = &cpi->mb.e_mbd;
536    int update = 0;
537    int new_delta_q;
538    int new_uv_delta_q;
539    cm->base_qindex = Q;
540
541    /* if any of the delta_q values are changing update flag has to be set */
542    /* currently only y2dc_delta_q may change */
543
544    cm->y1dc_delta_q = 0;
545    cm->y2ac_delta_q = 0;
546
547    if (Q < 4)
548    {
549        new_delta_q = 4-Q;
550    }
551    else
552        new_delta_q = 0;
553
554    update |= cm->y2dc_delta_q != new_delta_q;
555    cm->y2dc_delta_q = new_delta_q;
556
557    new_uv_delta_q = 0;
558    // For screen content, lower the q value for UV channel. For now, select
559    // conservative delta; same delta for dc and ac, and decrease it with lower
560    // Q, and set to 0 below some threshold. May want to condition this in
561    // future on the variance/energy in UV channel.
562    if (cpi->oxcf.screen_content_mode && Q > 40) {
563      new_uv_delta_q = -(int)(0.15 * Q);
564      // Check range: magnitude of delta is 4 bits.
565      if (new_uv_delta_q < -15) {
566        new_uv_delta_q = -15;
567      }
568    }
569    update |= cm->uvdc_delta_q != new_uv_delta_q;
570    cm->uvdc_delta_q = new_uv_delta_q;
571    cm->uvac_delta_q = new_uv_delta_q;
572
573    /* Set Segment specific quatizers */
574    mbd->segment_feature_data[MB_LVL_ALT_Q][0] = cpi->segment_feature_data[MB_LVL_ALT_Q][0];
575    mbd->segment_feature_data[MB_LVL_ALT_Q][1] = cpi->segment_feature_data[MB_LVL_ALT_Q][1];
576    mbd->segment_feature_data[MB_LVL_ALT_Q][2] = cpi->segment_feature_data[MB_LVL_ALT_Q][2];
577    mbd->segment_feature_data[MB_LVL_ALT_Q][3] = cpi->segment_feature_data[MB_LVL_ALT_Q][3];
578
579    /* quantizer has to be reinitialized for any delta_q changes */
580    if(update)
581        vp8cx_init_quantizer(cpi);
582
583}
584