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 
19 void 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 
52 void 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 
104 void 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 
117 void 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 
128 void 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 
136 static 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 
158 static 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 
180 static 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 
202 static 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 
224 static 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 
250 void 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 
364 void 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 
496 void 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 
522 void 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 
532 void 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