Coverage Report

Created: 2026-09-01 06:54

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libvpx/vp8/encoder/vp8_quantize.c
Line
Count
Source
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
#include <math.h>
12
13
#include "./vpx_config.h"
14
#include "vpx_ports/bitops.h"
15
#include "vpx_mem/vpx_mem.h"
16
17
#include "onyx_int.h"
18
#include "vp8/encoder/quantize.h"
19
#include "vp8/common/quant_common.h"
20
21
0
void vp8_fast_quantize_b_c(BLOCK *b, BLOCKD *d) {
22
0
  int i, rc, eob;
23
0
  int x, y, z, sz;
24
0
  short *coeff_ptr = b->coeff;
25
0
  short *round_ptr = b->round;
26
0
  short *quant_ptr = b->quant_fast;
27
0
  short *qcoeff_ptr = d->qcoeff;
28
0
  short *dqcoeff_ptr = d->dqcoeff;
29
0
  short *dequant_ptr = d->dequant;
30
31
0
  eob = -1;
32
0
  for (i = 0; i < 16; ++i) {
33
0
    rc = vp8_default_zig_zag1d[i];
34
0
    z = coeff_ptr[rc];
35
36
0
    sz = (z >> 31);    /* sign of z */
37
0
    x = (z ^ sz) - sz; /* x = abs(z) */
38
39
0
    y = ((x + round_ptr[rc]) * quant_ptr[rc]) >> 16; /* quantize (x) */
40
0
    x = (y ^ sz) - sz;                               /* get the sign back */
41
0
    qcoeff_ptr[rc] = x;                              /* write to destination */
42
0
    dqcoeff_ptr[rc] = x * dequant_ptr[rc];           /* dequantized value */
43
44
0
    if (y) {
45
0
      eob = i; /* last nonzero coeffs */
46
0
    }
47
0
  }
48
0
  *d->eob = (char)(eob + 1);
49
0
}
50
51
0
void vp8_regular_quantize_b_c(BLOCK *b, BLOCKD *d) {
52
0
  int i, rc, eob;
53
0
  int zbin;
54
0
  int x, y, z, sz;
55
0
  short *zbin_boost_ptr = b->zrun_zbin_boost;
56
0
  short *coeff_ptr = b->coeff;
57
0
  short *zbin_ptr = b->zbin;
58
0
  short *round_ptr = b->round;
59
0
  short *quant_ptr = b->quant;
60
0
  short *quant_shift_ptr = b->quant_shift;
61
0
  short *qcoeff_ptr = d->qcoeff;
62
0
  short *dqcoeff_ptr = d->dqcoeff;
63
0
  short *dequant_ptr = d->dequant;
64
0
  short zbin_oq_value = b->zbin_extra;
65
66
0
  memset(qcoeff_ptr, 0, 32);
67
0
  memset(dqcoeff_ptr, 0, 32);
68
69
0
  eob = -1;
70
71
0
  for (i = 0; i < 16; ++i) {
72
0
    rc = vp8_default_zig_zag1d[i];
73
0
    z = coeff_ptr[rc];
74
75
0
    zbin = zbin_ptr[rc] + *zbin_boost_ptr + zbin_oq_value;
76
77
0
    zbin_boost_ptr++;
78
0
    sz = (z >> 31);    /* sign of z */
79
0
    x = (z ^ sz) - sz; /* x = abs(z) */
80
81
0
    if (x >= zbin) {
82
0
      x += round_ptr[rc];
83
0
      y = ((((x * quant_ptr[rc]) >> 16) + x) * quant_shift_ptr[rc]) >>
84
0
          16;                                /* quantize (x) */
85
0
      x = (y ^ sz) - sz;                     /* get the sign back */
86
0
      qcoeff_ptr[rc] = x;                    /* write to destination */
87
0
      dqcoeff_ptr[rc] = x * dequant_ptr[rc]; /* dequantized value */
88
89
0
      if (y) {
90
0
        eob = i;                             /* last nonzero coeffs */
91
0
        zbin_boost_ptr = b->zrun_zbin_boost; /* reset zero runlength */
92
0
      }
93
0
    }
94
0
  }
95
96
0
  *d->eob = (char)(eob + 1);
97
0
}
98
99
330k
void vp8_quantize_mby(MACROBLOCK *x) {
100
330k
  int i;
101
330k
  int has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED &&
102
330k
                       x->e_mbd.mode_info_context->mbmi.mode != SPLITMV);
103
104
5.61M
  for (i = 0; i < 16; ++i) x->quantize_b(&x->block[i], &x->e_mbd.block[i]);
105
106
330k
  if (has_2nd_order) x->quantize_b(&x->block[24], &x->e_mbd.block[24]);
107
330k
}
108
109
885k
void vp8_quantize_mb(MACROBLOCK *x) {
110
885k
  int i;
111
885k
  int has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED &&
112
885k
                       x->e_mbd.mode_info_context->mbmi.mode != SPLITMV);
113
114
22.7M
  for (i = 0; i < 24 + has_2nd_order; ++i) {
115
21.9M
    x->quantize_b(&x->block[i], &x->e_mbd.block[i]);
116
21.9M
  }
117
885k
}
118
119
9.51M
void vp8_quantize_mbuv(MACROBLOCK *x) {
120
9.51M
  int i;
121
122
85.6M
  for (i = 16; i < 24; ++i) x->quantize_b(&x->block[i], &x->e_mbd.block[i]);
123
9.51M
}
124
125
static const int qrounding_factors[129] = {
126
  48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
127
  48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
128
  48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
129
  48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
130
  48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
131
  48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
132
  48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48
133
};
134
135
static const int qzbin_factors[129] = {
136
  84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
137
  84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
138
  84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 80, 80, 80, 80, 80, 80, 80, 80, 80,
139
  80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
140
  80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
141
  80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
142
  80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80
143
};
144
145
static const int qrounding_factors_y2[129] = {
146
  48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
147
  48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
148
  48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
149
  48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
150
  48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
151
  48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
152
  48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48
153
};
154
155
static const int qzbin_factors_y2[129] = {
156
  84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
157
  84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
158
  84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 80, 80, 80, 80, 80, 80, 80, 80, 80,
159
  80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
160
  80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
161
  80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
162
  80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80
163
};
164
165
static void invert_quant(int improved_quant, short *quant, short *shift,
166
24.2M
                         short d) {
167
24.2M
  if (improved_quant) {
168
20.9M
    unsigned int t;
169
20.9M
    int l, m;
170
20.9M
    t = (unsigned int)d;
171
20.9M
    l = get_msb(t);
172
20.9M
    m = 1 + (1 << (16 + l)) / d;
173
20.9M
    *quant = (short)(m - (1 << 16));
174
20.9M
    *shift = l;
175
    /* use multiplication and constant shift by 16 */
176
20.9M
    *shift = 1 << (16 - *shift);
177
20.9M
  } else {
178
3.27M
    *quant = (1 << 16) / d;
179
3.27M
    *shift = 0;
180
3.27M
  }
181
24.2M
}
182
183
31.5k
void vp8cx_init_quantizer(VP8_COMP *cpi) {
184
31.5k
  int i;
185
31.5k
  int quant_val;
186
31.5k
  int Q;
187
188
31.5k
  int zbin_boost[16] = { 0,  0,  8,  10, 12, 14, 16, 20,
189
31.5k
                         24, 28, 32, 36, 40, 44, 44, 44 };
190
191
4.06M
  for (Q = 0; Q < QINDEX_RANGE; ++Q) {
192
    /* dc values */
193
4.03M
    quant_val = vp8_dc_quant(Q, cpi->common.y1dc_delta_q);
194
4.03M
    cpi->Y1quant_fast[Q][0] = (1 << 16) / quant_val;
195
4.03M
    invert_quant(cpi->sf.improved_quant, cpi->Y1quant[Q] + 0,
196
4.03M
                 cpi->Y1quant_shift[Q] + 0, quant_val);
197
4.03M
    cpi->Y1zbin[Q][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
198
4.03M
    cpi->Y1round[Q][0] = (qrounding_factors[Q] * quant_val) >> 7;
199
4.03M
    cpi->common.Y1dequant[Q][0] = quant_val;
200
4.03M
    cpi->zrun_zbin_boost_y1[Q][0] = (quant_val * zbin_boost[0]) >> 7;
201
202
4.03M
    quant_val = vp8_dc2quant(Q, cpi->common.y2dc_delta_q);
203
4.03M
    cpi->Y2quant_fast[Q][0] = (1 << 16) / quant_val;
204
4.03M
    invert_quant(cpi->sf.improved_quant, cpi->Y2quant[Q] + 0,
205
4.03M
                 cpi->Y2quant_shift[Q] + 0, quant_val);
206
4.03M
    cpi->Y2zbin[Q][0] = ((qzbin_factors_y2[Q] * quant_val) + 64) >> 7;
207
4.03M
    cpi->Y2round[Q][0] = (qrounding_factors_y2[Q] * quant_val) >> 7;
208
4.03M
    cpi->common.Y2dequant[Q][0] = quant_val;
209
4.03M
    cpi->zrun_zbin_boost_y2[Q][0] = (quant_val * zbin_boost[0]) >> 7;
210
211
4.03M
    quant_val = vp8_dc_uv_quant(Q, cpi->common.uvdc_delta_q);
212
4.03M
    cpi->UVquant_fast[Q][0] = (1 << 16) / quant_val;
213
4.03M
    invert_quant(cpi->sf.improved_quant, cpi->UVquant[Q] + 0,
214
4.03M
                 cpi->UVquant_shift[Q] + 0, quant_val);
215
4.03M
    cpi->UVzbin[Q][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
216
4.03M
    cpi->UVround[Q][0] = (qrounding_factors[Q] * quant_val) >> 7;
217
4.03M
    cpi->common.UVdequant[Q][0] = quant_val;
218
4.03M
    cpi->zrun_zbin_boost_uv[Q][0] = (quant_val * zbin_boost[0]) >> 7;
219
220
    /* all the ac values = ; */
221
4.03M
    quant_val = vp8_ac_yquant(Q);
222
4.03M
    cpi->Y1quant_fast[Q][1] = (1 << 16) / quant_val;
223
4.03M
    invert_quant(cpi->sf.improved_quant, cpi->Y1quant[Q] + 1,
224
4.03M
                 cpi->Y1quant_shift[Q] + 1, quant_val);
225
4.03M
    cpi->Y1zbin[Q][1] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
226
4.03M
    cpi->Y1round[Q][1] = (qrounding_factors[Q] * quant_val) >> 7;
227
4.03M
    cpi->common.Y1dequant[Q][1] = quant_val;
228
4.03M
    cpi->zrun_zbin_boost_y1[Q][1] = (quant_val * zbin_boost[1]) >> 7;
229
230
4.03M
    quant_val = vp8_ac2quant(Q, cpi->common.y2ac_delta_q);
231
4.03M
    cpi->Y2quant_fast[Q][1] = (1 << 16) / quant_val;
232
4.03M
    invert_quant(cpi->sf.improved_quant, cpi->Y2quant[Q] + 1,
233
4.03M
                 cpi->Y2quant_shift[Q] + 1, quant_val);
234
4.03M
    cpi->Y2zbin[Q][1] = ((qzbin_factors_y2[Q] * quant_val) + 64) >> 7;
235
4.03M
    cpi->Y2round[Q][1] = (qrounding_factors_y2[Q] * quant_val) >> 7;
236
4.03M
    cpi->common.Y2dequant[Q][1] = quant_val;
237
4.03M
    cpi->zrun_zbin_boost_y2[Q][1] = (quant_val * zbin_boost[1]) >> 7;
238
239
4.03M
    quant_val = vp8_ac_uv_quant(Q, cpi->common.uvac_delta_q);
240
4.03M
    cpi->UVquant_fast[Q][1] = (1 << 16) / quant_val;
241
4.03M
    invert_quant(cpi->sf.improved_quant, cpi->UVquant[Q] + 1,
242
4.03M
                 cpi->UVquant_shift[Q] + 1, quant_val);
243
4.03M
    cpi->UVzbin[Q][1] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
244
4.03M
    cpi->UVround[Q][1] = (qrounding_factors[Q] * quant_val) >> 7;
245
4.03M
    cpi->common.UVdequant[Q][1] = quant_val;
246
4.03M
    cpi->zrun_zbin_boost_uv[Q][1] = (quant_val * zbin_boost[1]) >> 7;
247
248
60.5M
    for (i = 2; i < 16; ++i) {
249
56.4M
      cpi->Y1quant_fast[Q][i] = cpi->Y1quant_fast[Q][1];
250
56.4M
      cpi->Y1quant[Q][i] = cpi->Y1quant[Q][1];
251
56.4M
      cpi->Y1quant_shift[Q][i] = cpi->Y1quant_shift[Q][1];
252
56.4M
      cpi->Y1zbin[Q][i] = cpi->Y1zbin[Q][1];
253
56.4M
      cpi->Y1round[Q][i] = cpi->Y1round[Q][1];
254
56.4M
      cpi->zrun_zbin_boost_y1[Q][i] =
255
56.4M
          (cpi->common.Y1dequant[Q][1] * zbin_boost[i]) >> 7;
256
257
56.4M
      cpi->Y2quant_fast[Q][i] = cpi->Y2quant_fast[Q][1];
258
56.4M
      cpi->Y2quant[Q][i] = cpi->Y2quant[Q][1];
259
56.4M
      cpi->Y2quant_shift[Q][i] = cpi->Y2quant_shift[Q][1];
260
56.4M
      cpi->Y2zbin[Q][i] = cpi->Y2zbin[Q][1];
261
56.4M
      cpi->Y2round[Q][i] = cpi->Y2round[Q][1];
262
56.4M
      cpi->zrun_zbin_boost_y2[Q][i] =
263
56.4M
          (cpi->common.Y2dequant[Q][1] * zbin_boost[i]) >> 7;
264
265
56.4M
      cpi->UVquant_fast[Q][i] = cpi->UVquant_fast[Q][1];
266
56.4M
      cpi->UVquant[Q][i] = cpi->UVquant[Q][1];
267
56.4M
      cpi->UVquant_shift[Q][i] = cpi->UVquant_shift[Q][1];
268
56.4M
      cpi->UVzbin[Q][i] = cpi->UVzbin[Q][1];
269
56.4M
      cpi->UVround[Q][i] = cpi->UVround[Q][1];
270
56.4M
      cpi->zrun_zbin_boost_uv[Q][i] =
271
56.4M
          (cpi->common.UVdequant[Q][1] * zbin_boost[i]) >> 7;
272
56.4M
    }
273
4.03M
  }
274
31.5k
}
275
276
#define ZBIN_EXTRA_Y                                                \
277
12.5M
  ((cpi->common.Y1dequant[QIndex][1] *                              \
278
12.5M
    (x->zbin_over_quant + x->zbin_mode_boost + x->act_zbin_adj)) >> \
279
12.5M
   7)
280
281
#define ZBIN_EXTRA_UV                                               \
282
12.5M
  ((cpi->common.UVdequant[QIndex][1] *                              \
283
12.5M
    (x->zbin_over_quant + x->zbin_mode_boost + x->act_zbin_adj)) >> \
284
12.5M
   7)
285
286
#define ZBIN_EXTRA_Y2                                                     \
287
12.5M
  ((cpi->common.Y2dequant[QIndex][1] *                                    \
288
12.5M
    ((x->zbin_over_quant / 2) + x->zbin_mode_boost + x->act_zbin_adj)) >> \
289
12.5M
   7)
290
291
2.09M
void vp8cx_mb_init_quantizer(VP8_COMP *cpi, MACROBLOCK *x, int ok_to_skip) {
292
2.09M
  int i;
293
2.09M
  int QIndex;
294
2.09M
  MACROBLOCKD *xd = &x->e_mbd;
295
2.09M
  int zbin_extra;
296
297
  /* Select the baseline MB Q index. */
298
2.09M
  if (xd->segmentation_enabled) {
299
    /* Abs Value */
300
2.09M
    if (xd->mb_segment_abs_delta == SEGMENT_ABSDATA) {
301
0
      QIndex = xd->segment_feature_data[MB_LVL_ALT_Q]
302
0
                                       [xd->mode_info_context->mbmi.segment_id];
303
      /* Delta Value */
304
2.09M
    } else {
305
2.09M
      QIndex = cpi->common.base_qindex +
306
2.09M
               xd->segment_feature_data[MB_LVL_ALT_Q]
307
2.09M
                                       [xd->mode_info_context->mbmi.segment_id];
308
      /* Clamp to valid range */
309
2.09M
      QIndex = (QIndex >= 0) ? ((QIndex <= MAXQ) ? QIndex : MAXQ) : 0;
310
2.09M
    }
311
2.09M
  } else {
312
0
    QIndex = cpi->common.base_qindex;
313
0
  }
314
315
  /* This initialization should be called at least once. Use ok_to_skip to
316
   * decide if it is ok to skip.
317
   * Before encoding a frame, this function is always called with ok_to_skip
318
   * =0, which means no skiping of calculations. The "last" values are
319
   * initialized at that time.
320
   */
321
2.09M
  if (!ok_to_skip || QIndex != x->q_index) {
322
409k
    xd->dequant_y1_dc[0] = 1;
323
409k
    xd->dequant_y1[0] = cpi->common.Y1dequant[QIndex][0];
324
409k
    xd->dequant_y2[0] = cpi->common.Y2dequant[QIndex][0];
325
409k
    xd->dequant_uv[0] = cpi->common.UVdequant[QIndex][0];
326
327
6.54M
    for (i = 1; i < 16; ++i) {
328
6.13M
      xd->dequant_y1_dc[i] = xd->dequant_y1[i] =
329
6.13M
          cpi->common.Y1dequant[QIndex][1];
330
6.13M
      xd->dequant_y2[i] = cpi->common.Y2dequant[QIndex][1];
331
6.13M
      xd->dequant_uv[i] = cpi->common.UVdequant[QIndex][1];
332
6.13M
    }
333
409k
#if 1
334
    /*TODO:  Remove dequant from BLOCKD.  This is a temporary solution until
335
     * the quantizer code uses a passed in pointer to the dequant constants.
336
     * This will also require modifications to the x86 and neon assembly.
337
     * */
338
6.95M
    for (i = 0; i < 16; ++i) x->e_mbd.block[i].dequant = xd->dequant_y1;
339
3.68M
    for (i = 16; i < 24; ++i) x->e_mbd.block[i].dequant = xd->dequant_uv;
340
409k
    x->e_mbd.block[24].dequant = xd->dequant_y2;
341
409k
#endif
342
343
    /* Y */
344
409k
    zbin_extra = ZBIN_EXTRA_Y;
345
346
6.95M
    for (i = 0; i < 16; ++i) {
347
6.54M
      x->block[i].quant = cpi->Y1quant[QIndex];
348
6.54M
      x->block[i].quant_fast = cpi->Y1quant_fast[QIndex];
349
6.54M
      x->block[i].quant_shift = cpi->Y1quant_shift[QIndex];
350
6.54M
      x->block[i].zbin = cpi->Y1zbin[QIndex];
351
6.54M
      x->block[i].round = cpi->Y1round[QIndex];
352
6.54M
      x->block[i].zrun_zbin_boost = cpi->zrun_zbin_boost_y1[QIndex];
353
6.54M
      x->block[i].zbin_extra = (short)zbin_extra;
354
6.54M
    }
355
356
    /* UV */
357
409k
    zbin_extra = ZBIN_EXTRA_UV;
358
359
3.68M
    for (i = 16; i < 24; ++i) {
360
3.27M
      x->block[i].quant = cpi->UVquant[QIndex];
361
3.27M
      x->block[i].quant_fast = cpi->UVquant_fast[QIndex];
362
3.27M
      x->block[i].quant_shift = cpi->UVquant_shift[QIndex];
363
3.27M
      x->block[i].zbin = cpi->UVzbin[QIndex];
364
3.27M
      x->block[i].round = cpi->UVround[QIndex];
365
3.27M
      x->block[i].zrun_zbin_boost = cpi->zrun_zbin_boost_uv[QIndex];
366
3.27M
      x->block[i].zbin_extra = (short)zbin_extra;
367
3.27M
    }
368
369
    /* Y2 */
370
409k
    zbin_extra = ZBIN_EXTRA_Y2;
371
372
409k
    x->block[24].quant_fast = cpi->Y2quant_fast[QIndex];
373
409k
    x->block[24].quant = cpi->Y2quant[QIndex];
374
409k
    x->block[24].quant_shift = cpi->Y2quant_shift[QIndex];
375
409k
    x->block[24].zbin = cpi->Y2zbin[QIndex];
376
409k
    x->block[24].round = cpi->Y2round[QIndex];
377
409k
    x->block[24].zrun_zbin_boost = cpi->zrun_zbin_boost_y2[QIndex];
378
409k
    x->block[24].zbin_extra = (short)zbin_extra;
379
380
    /* save this macroblock QIndex for vp8_update_zbin_extra() */
381
409k
    x->q_index = QIndex;
382
383
409k
    x->last_zbin_over_quant = x->zbin_over_quant;
384
409k
    x->last_zbin_mode_boost = x->zbin_mode_boost;
385
409k
    x->last_act_zbin_adj = x->act_zbin_adj;
386
387
1.68M
  } else if (x->last_zbin_over_quant != x->zbin_over_quant ||
388
1.68M
             x->last_zbin_mode_boost != x->zbin_mode_boost ||
389
1.46M
             x->last_act_zbin_adj != x->act_zbin_adj) {
390
    /* Y */
391
214k
    zbin_extra = ZBIN_EXTRA_Y;
392
393
3.64M
    for (i = 0; i < 16; ++i) x->block[i].zbin_extra = (short)zbin_extra;
394
395
    /* UV */
396
214k
    zbin_extra = ZBIN_EXTRA_UV;
397
398
1.92M
    for (i = 16; i < 24; ++i) x->block[i].zbin_extra = (short)zbin_extra;
399
400
    /* Y2 */
401
214k
    zbin_extra = ZBIN_EXTRA_Y2;
402
214k
    x->block[24].zbin_extra = (short)zbin_extra;
403
404
214k
    x->last_zbin_over_quant = x->zbin_over_quant;
405
214k
    x->last_zbin_mode_boost = x->zbin_mode_boost;
406
214k
    x->last_act_zbin_adj = x->act_zbin_adj;
407
214k
  }
408
2.09M
}
409
410
11.9M
void vp8_update_zbin_extra(VP8_COMP *cpi, MACROBLOCK *x) {
411
11.9M
  int i;
412
11.9M
  int QIndex = x->q_index;
413
11.9M
  int zbin_extra;
414
415
  /* Y */
416
11.9M
  zbin_extra = ZBIN_EXTRA_Y;
417
418
203M
  for (i = 0; i < 16; ++i) x->block[i].zbin_extra = (short)zbin_extra;
419
420
  /* UV */
421
11.9M
  zbin_extra = ZBIN_EXTRA_UV;
422
423
107M
  for (i = 16; i < 24; ++i) x->block[i].zbin_extra = (short)zbin_extra;
424
425
  /* Y2 */
426
11.9M
  zbin_extra = ZBIN_EXTRA_Y2;
427
11.9M
  x->block[24].zbin_extra = (short)zbin_extra;
428
11.9M
}
429
#undef ZBIN_EXTRA_Y
430
#undef ZBIN_EXTRA_UV
431
#undef ZBIN_EXTRA_Y2
432
433
409k
void vp8cx_frame_init_quantizer(VP8_COMP *cpi) {
434
  /* Clear Zbin mode boost for default case */
435
409k
  cpi->mb.zbin_mode_boost = 0;
436
437
  /* MB level quantizer setup */
438
409k
  vp8cx_mb_init_quantizer(cpi, &cpi->mb, 0);
439
409k
}
440
441
409k
void vp8_set_quantizer(struct VP8_COMP *cpi, int Q) {
442
409k
  VP8_COMMON *cm = &cpi->common;
443
409k
  MACROBLOCKD *mbd = &cpi->mb.e_mbd;
444
409k
  int update = 0;
445
409k
  int new_delta_q;
446
409k
  int new_uv_delta_q;
447
409k
  cm->base_qindex = Q;
448
449
  /* if any of the delta_q values are changing update flag has to be set */
450
  /* currently only y2dc_delta_q may change */
451
452
409k
  cm->y1dc_delta_q = 0;
453
409k
  cm->y2ac_delta_q = 0;
454
455
409k
  if (Q < 4) {
456
0
    new_delta_q = 4 - Q;
457
409k
  } else {
458
409k
    new_delta_q = 0;
459
409k
  }
460
461
409k
  update |= cm->y2dc_delta_q != new_delta_q;
462
409k
  cm->y2dc_delta_q = new_delta_q;
463
464
409k
  new_uv_delta_q = 0;
465
  // For screen content, lower the q value for UV channel. For now, select
466
  // conservative delta; same delta for dc and ac, and decrease it with lower
467
  // Q, and set to 0 below some threshold. May want to condition this in
468
  // future on the variance/energy in UV channel.
469
409k
  if (cpi->oxcf.screen_content_mode && Q > 40) {
470
0
    new_uv_delta_q = -(int)(0.15 * Q);
471
    // Check range: magnitude of delta is 4 bits.
472
0
    if (new_uv_delta_q < -15) {
473
0
      new_uv_delta_q = -15;
474
0
    }
475
0
  }
476
409k
  update |= cm->uvdc_delta_q != new_uv_delta_q;
477
409k
  cm->uvdc_delta_q = new_uv_delta_q;
478
409k
  cm->uvac_delta_q = new_uv_delta_q;
479
480
  /* Set Segment specific quatizers */
481
409k
  mbd->segment_feature_data[MB_LVL_ALT_Q][0] =
482
409k
      cpi->segment_feature_data[MB_LVL_ALT_Q][0];
483
409k
  mbd->segment_feature_data[MB_LVL_ALT_Q][1] =
484
409k
      cpi->segment_feature_data[MB_LVL_ALT_Q][1];
485
409k
  mbd->segment_feature_data[MB_LVL_ALT_Q][2] =
486
409k
      cpi->segment_feature_data[MB_LVL_ALT_Q][2];
487
409k
  mbd->segment_feature_data[MB_LVL_ALT_Q][3] =
488
409k
      cpi->segment_feature_data[MB_LVL_ALT_Q][3];
489
490
  /* quantizer has to be reinitialized for any delta_q changes */
491
409k
  if (update) vp8cx_init_quantizer(cpi);
492
409k
}