Coverage Report

Created: 2026-06-07 06:59

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
310k
void vp8_quantize_mby(MACROBLOCK *x) {
100
310k
  int i;
101
310k
  int has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED &&
102
310k
                       x->e_mbd.mode_info_context->mbmi.mode != SPLITMV);
103
104
5.27M
  for (i = 0; i < 16; ++i) x->quantize_b(&x->block[i], &x->e_mbd.block[i]);
105
106
310k
  if (has_2nd_order) x->quantize_b(&x->block[24], &x->e_mbd.block[24]);
107
310k
}
108
109
838k
void vp8_quantize_mb(MACROBLOCK *x) {
110
838k
  int i;
111
838k
  int has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED &&
112
838k
                       x->e_mbd.mode_info_context->mbmi.mode != SPLITMV);
113
114
21.6M
  for (i = 0; i < 24 + has_2nd_order; ++i) {
115
20.7M
    x->quantize_b(&x->block[i], &x->e_mbd.block[i]);
116
20.7M
  }
117
838k
}
118
119
8.35M
void vp8_quantize_mbuv(MACROBLOCK *x) {
120
8.35M
  int i;
121
122
75.2M
  for (i = 16; i < 24; ++i) x->quantize_b(&x->block[i], &x->e_mbd.block[i]);
123
8.35M
}
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
25.9M
                         short d) {
167
25.9M
  if (improved_quant) {
168
22.3M
    unsigned int t;
169
22.3M
    int l, m;
170
22.3M
    t = (unsigned int)d;
171
22.3M
    l = get_msb(t);
172
22.3M
    m = 1 + (1 << (16 + l)) / d;
173
22.3M
    *quant = (short)(m - (1 << 16));
174
22.3M
    *shift = l;
175
    /* use multiplication and constant shift by 16 */
176
22.3M
    *shift = 1 << (16 - *shift);
177
22.3M
  } else {
178
3.54M
    *quant = (1 << 16) / d;
179
3.54M
    *shift = 0;
180
3.54M
  }
181
25.9M
}
182
183
33.7k
void vp8cx_init_quantizer(VP8_COMP *cpi) {
184
33.7k
  int i;
185
33.7k
  int quant_val;
186
33.7k
  int Q;
187
188
33.7k
  int zbin_boost[16] = { 0,  0,  8,  10, 12, 14, 16, 20,
189
33.7k
                         24, 28, 32, 36, 40, 44, 44, 44 };
190
191
4.35M
  for (Q = 0; Q < QINDEX_RANGE; ++Q) {
192
    /* dc values */
193
4.31M
    quant_val = vp8_dc_quant(Q, cpi->common.y1dc_delta_q);
194
4.31M
    cpi->Y1quant_fast[Q][0] = (1 << 16) / quant_val;
195
4.31M
    invert_quant(cpi->sf.improved_quant, cpi->Y1quant[Q] + 0,
196
4.31M
                 cpi->Y1quant_shift[Q] + 0, quant_val);
197
4.31M
    cpi->Y1zbin[Q][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
198
4.31M
    cpi->Y1round[Q][0] = (qrounding_factors[Q] * quant_val) >> 7;
199
4.31M
    cpi->common.Y1dequant[Q][0] = quant_val;
200
4.31M
    cpi->zrun_zbin_boost_y1[Q][0] = (quant_val * zbin_boost[0]) >> 7;
201
202
4.31M
    quant_val = vp8_dc2quant(Q, cpi->common.y2dc_delta_q);
203
4.31M
    cpi->Y2quant_fast[Q][0] = (1 << 16) / quant_val;
204
4.31M
    invert_quant(cpi->sf.improved_quant, cpi->Y2quant[Q] + 0,
205
4.31M
                 cpi->Y2quant_shift[Q] + 0, quant_val);
206
4.31M
    cpi->Y2zbin[Q][0] = ((qzbin_factors_y2[Q] * quant_val) + 64) >> 7;
207
4.31M
    cpi->Y2round[Q][0] = (qrounding_factors_y2[Q] * quant_val) >> 7;
208
4.31M
    cpi->common.Y2dequant[Q][0] = quant_val;
209
4.31M
    cpi->zrun_zbin_boost_y2[Q][0] = (quant_val * zbin_boost[0]) >> 7;
210
211
4.31M
    quant_val = vp8_dc_uv_quant(Q, cpi->common.uvdc_delta_q);
212
4.31M
    cpi->UVquant_fast[Q][0] = (1 << 16) / quant_val;
213
4.31M
    invert_quant(cpi->sf.improved_quant, cpi->UVquant[Q] + 0,
214
4.31M
                 cpi->UVquant_shift[Q] + 0, quant_val);
215
4.31M
    cpi->UVzbin[Q][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
216
4.31M
    cpi->UVround[Q][0] = (qrounding_factors[Q] * quant_val) >> 7;
217
4.31M
    cpi->common.UVdequant[Q][0] = quant_val;
218
4.31M
    cpi->zrun_zbin_boost_uv[Q][0] = (quant_val * zbin_boost[0]) >> 7;
219
220
    /* all the ac values = ; */
221
4.31M
    quant_val = vp8_ac_yquant(Q);
222
4.31M
    cpi->Y1quant_fast[Q][1] = (1 << 16) / quant_val;
223
4.31M
    invert_quant(cpi->sf.improved_quant, cpi->Y1quant[Q] + 1,
224
4.31M
                 cpi->Y1quant_shift[Q] + 1, quant_val);
225
4.31M
    cpi->Y1zbin[Q][1] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
226
4.31M
    cpi->Y1round[Q][1] = (qrounding_factors[Q] * quant_val) >> 7;
227
4.31M
    cpi->common.Y1dequant[Q][1] = quant_val;
228
4.31M
    cpi->zrun_zbin_boost_y1[Q][1] = (quant_val * zbin_boost[1]) >> 7;
229
230
4.31M
    quant_val = vp8_ac2quant(Q, cpi->common.y2ac_delta_q);
231
4.31M
    cpi->Y2quant_fast[Q][1] = (1 << 16) / quant_val;
232
4.31M
    invert_quant(cpi->sf.improved_quant, cpi->Y2quant[Q] + 1,
233
4.31M
                 cpi->Y2quant_shift[Q] + 1, quant_val);
234
4.31M
    cpi->Y2zbin[Q][1] = ((qzbin_factors_y2[Q] * quant_val) + 64) >> 7;
235
4.31M
    cpi->Y2round[Q][1] = (qrounding_factors_y2[Q] * quant_val) >> 7;
236
4.31M
    cpi->common.Y2dequant[Q][1] = quant_val;
237
4.31M
    cpi->zrun_zbin_boost_y2[Q][1] = (quant_val * zbin_boost[1]) >> 7;
238
239
4.31M
    quant_val = vp8_ac_uv_quant(Q, cpi->common.uvac_delta_q);
240
4.31M
    cpi->UVquant_fast[Q][1] = (1 << 16) / quant_val;
241
4.31M
    invert_quant(cpi->sf.improved_quant, cpi->UVquant[Q] + 1,
242
4.31M
                 cpi->UVquant_shift[Q] + 1, quant_val);
243
4.31M
    cpi->UVzbin[Q][1] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
244
4.31M
    cpi->UVround[Q][1] = (qrounding_factors[Q] * quant_val) >> 7;
245
4.31M
    cpi->common.UVdequant[Q][1] = quant_val;
246
4.31M
    cpi->zrun_zbin_boost_uv[Q][1] = (quant_val * zbin_boost[1]) >> 7;
247
248
64.7M
    for (i = 2; i < 16; ++i) {
249
60.4M
      cpi->Y1quant_fast[Q][i] = cpi->Y1quant_fast[Q][1];
250
60.4M
      cpi->Y1quant[Q][i] = cpi->Y1quant[Q][1];
251
60.4M
      cpi->Y1quant_shift[Q][i] = cpi->Y1quant_shift[Q][1];
252
60.4M
      cpi->Y1zbin[Q][i] = cpi->Y1zbin[Q][1];
253
60.4M
      cpi->Y1round[Q][i] = cpi->Y1round[Q][1];
254
60.4M
      cpi->zrun_zbin_boost_y1[Q][i] =
255
60.4M
          (cpi->common.Y1dequant[Q][1] * zbin_boost[i]) >> 7;
256
257
60.4M
      cpi->Y2quant_fast[Q][i] = cpi->Y2quant_fast[Q][1];
258
60.4M
      cpi->Y2quant[Q][i] = cpi->Y2quant[Q][1];
259
60.4M
      cpi->Y2quant_shift[Q][i] = cpi->Y2quant_shift[Q][1];
260
60.4M
      cpi->Y2zbin[Q][i] = cpi->Y2zbin[Q][1];
261
60.4M
      cpi->Y2round[Q][i] = cpi->Y2round[Q][1];
262
60.4M
      cpi->zrun_zbin_boost_y2[Q][i] =
263
60.4M
          (cpi->common.Y2dequant[Q][1] * zbin_boost[i]) >> 7;
264
265
60.4M
      cpi->UVquant_fast[Q][i] = cpi->UVquant_fast[Q][1];
266
60.4M
      cpi->UVquant[Q][i] = cpi->UVquant[Q][1];
267
60.4M
      cpi->UVquant_shift[Q][i] = cpi->UVquant_shift[Q][1];
268
60.4M
      cpi->UVzbin[Q][i] = cpi->UVzbin[Q][1];
269
60.4M
      cpi->UVround[Q][i] = cpi->UVround[Q][1];
270
60.4M
      cpi->zrun_zbin_boost_uv[Q][i] =
271
60.4M
          (cpi->common.UVdequant[Q][1] * zbin_boost[i]) >> 7;
272
60.4M
    }
273
4.31M
  }
274
33.7k
}
275
276
#define ZBIN_EXTRA_Y                                                \
277
11.2M
  ((cpi->common.Y1dequant[QIndex][1] *                              \
278
11.2M
    (x->zbin_over_quant + x->zbin_mode_boost + x->act_zbin_adj)) >> \
279
11.2M
   7)
280
281
#define ZBIN_EXTRA_UV                                               \
282
11.2M
  ((cpi->common.UVdequant[QIndex][1] *                              \
283
11.2M
    (x->zbin_over_quant + x->zbin_mode_boost + x->act_zbin_adj)) >> \
284
11.2M
   7)
285
286
#define ZBIN_EXTRA_Y2                                                     \
287
11.2M
  ((cpi->common.Y2dequant[QIndex][1] *                                    \
288
11.2M
    ((x->zbin_over_quant / 2) + x->zbin_mode_boost + x->act_zbin_adj)) >> \
289
11.2M
   7)
290
291
1.96M
void vp8cx_mb_init_quantizer(VP8_COMP *cpi, MACROBLOCK *x, int ok_to_skip) {
292
1.96M
  int i;
293
1.96M
  int QIndex;
294
1.96M
  MACROBLOCKD *xd = &x->e_mbd;
295
1.96M
  int zbin_extra;
296
297
  /* Select the baseline MB Q index. */
298
1.96M
  if (xd->segmentation_enabled) {
299
    /* Abs Value */
300
1.96M
    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
1.96M
    } else {
305
1.96M
      QIndex = cpi->common.base_qindex +
306
1.96M
               xd->segment_feature_data[MB_LVL_ALT_Q]
307
1.96M
                                       [xd->mode_info_context->mbmi.segment_id];
308
      /* Clamp to valid range */
309
1.96M
      QIndex = (QIndex >= 0) ? ((QIndex <= MAXQ) ? QIndex : MAXQ) : 0;
310
1.96M
    }
311
1.96M
  } 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
1.96M
  if (!ok_to_skip || QIndex != x->q_index) {
322
404k
    xd->dequant_y1_dc[0] = 1;
323
404k
    xd->dequant_y1[0] = cpi->common.Y1dequant[QIndex][0];
324
404k
    xd->dequant_y2[0] = cpi->common.Y2dequant[QIndex][0];
325
404k
    xd->dequant_uv[0] = cpi->common.UVdequant[QIndex][0];
326
327
6.46M
    for (i = 1; i < 16; ++i) {
328
6.06M
      xd->dequant_y1_dc[i] = xd->dequant_y1[i] =
329
6.06M
          cpi->common.Y1dequant[QIndex][1];
330
6.06M
      xd->dequant_y2[i] = cpi->common.Y2dequant[QIndex][1];
331
6.06M
      xd->dequant_uv[i] = cpi->common.UVdequant[QIndex][1];
332
6.06M
    }
333
404k
#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.86M
    for (i = 0; i < 16; ++i) x->e_mbd.block[i].dequant = xd->dequant_y1;
339
3.63M
    for (i = 16; i < 24; ++i) x->e_mbd.block[i].dequant = xd->dequant_uv;
340
404k
    x->e_mbd.block[24].dequant = xd->dequant_y2;
341
404k
#endif
342
343
    /* Y */
344
404k
    zbin_extra = ZBIN_EXTRA_Y;
345
346
6.86M
    for (i = 0; i < 16; ++i) {
347
6.46M
      x->block[i].quant = cpi->Y1quant[QIndex];
348
6.46M
      x->block[i].quant_fast = cpi->Y1quant_fast[QIndex];
349
6.46M
      x->block[i].quant_shift = cpi->Y1quant_shift[QIndex];
350
6.46M
      x->block[i].zbin = cpi->Y1zbin[QIndex];
351
6.46M
      x->block[i].round = cpi->Y1round[QIndex];
352
6.46M
      x->block[i].zrun_zbin_boost = cpi->zrun_zbin_boost_y1[QIndex];
353
6.46M
      x->block[i].zbin_extra = (short)zbin_extra;
354
6.46M
    }
355
356
    /* UV */
357
404k
    zbin_extra = ZBIN_EXTRA_UV;
358
359
3.63M
    for (i = 16; i < 24; ++i) {
360
3.23M
      x->block[i].quant = cpi->UVquant[QIndex];
361
3.23M
      x->block[i].quant_fast = cpi->UVquant_fast[QIndex];
362
3.23M
      x->block[i].quant_shift = cpi->UVquant_shift[QIndex];
363
3.23M
      x->block[i].zbin = cpi->UVzbin[QIndex];
364
3.23M
      x->block[i].round = cpi->UVround[QIndex];
365
3.23M
      x->block[i].zrun_zbin_boost = cpi->zrun_zbin_boost_uv[QIndex];
366
3.23M
      x->block[i].zbin_extra = (short)zbin_extra;
367
3.23M
    }
368
369
    /* Y2 */
370
404k
    zbin_extra = ZBIN_EXTRA_Y2;
371
372
404k
    x->block[24].quant_fast = cpi->Y2quant_fast[QIndex];
373
404k
    x->block[24].quant = cpi->Y2quant[QIndex];
374
404k
    x->block[24].quant_shift = cpi->Y2quant_shift[QIndex];
375
404k
    x->block[24].zbin = cpi->Y2zbin[QIndex];
376
404k
    x->block[24].round = cpi->Y2round[QIndex];
377
404k
    x->block[24].zrun_zbin_boost = cpi->zrun_zbin_boost_y2[QIndex];
378
404k
    x->block[24].zbin_extra = (short)zbin_extra;
379
380
    /* save this macroblock QIndex for vp8_update_zbin_extra() */
381
404k
    x->q_index = QIndex;
382
383
404k
    x->last_zbin_over_quant = x->zbin_over_quant;
384
404k
    x->last_zbin_mode_boost = x->zbin_mode_boost;
385
404k
    x->last_act_zbin_adj = x->act_zbin_adj;
386
387
1.55M
  } else if (x->last_zbin_over_quant != x->zbin_over_quant ||
388
1.55M
             x->last_zbin_mode_boost != x->zbin_mode_boost ||
389
1.35M
             x->last_act_zbin_adj != x->act_zbin_adj) {
390
    /* Y */
391
206k
    zbin_extra = ZBIN_EXTRA_Y;
392
393
3.51M
    for (i = 0; i < 16; ++i) x->block[i].zbin_extra = (short)zbin_extra;
394
395
    /* UV */
396
206k
    zbin_extra = ZBIN_EXTRA_UV;
397
398
1.86M
    for (i = 16; i < 24; ++i) x->block[i].zbin_extra = (short)zbin_extra;
399
400
    /* Y2 */
401
206k
    zbin_extra = ZBIN_EXTRA_Y2;
402
206k
    x->block[24].zbin_extra = (short)zbin_extra;
403
404
206k
    x->last_zbin_over_quant = x->zbin_over_quant;
405
206k
    x->last_zbin_mode_boost = x->zbin_mode_boost;
406
206k
    x->last_act_zbin_adj = x->act_zbin_adj;
407
206k
  }
408
1.96M
}
409
410
10.6M
void vp8_update_zbin_extra(VP8_COMP *cpi, MACROBLOCK *x) {
411
10.6M
  int i;
412
10.6M
  int QIndex = x->q_index;
413
10.6M
  int zbin_extra;
414
415
  /* Y */
416
10.6M
  zbin_extra = ZBIN_EXTRA_Y;
417
418
180M
  for (i = 0; i < 16; ++i) x->block[i].zbin_extra = (short)zbin_extra;
419
420
  /* UV */
421
10.6M
  zbin_extra = ZBIN_EXTRA_UV;
422
423
95.5M
  for (i = 16; i < 24; ++i) x->block[i].zbin_extra = (short)zbin_extra;
424
425
  /* Y2 */
426
10.6M
  zbin_extra = ZBIN_EXTRA_Y2;
427
10.6M
  x->block[24].zbin_extra = (short)zbin_extra;
428
10.6M
}
429
#undef ZBIN_EXTRA_Y
430
#undef ZBIN_EXTRA_UV
431
#undef ZBIN_EXTRA_Y2
432
433
404k
void vp8cx_frame_init_quantizer(VP8_COMP *cpi) {
434
  /* Clear Zbin mode boost for default case */
435
404k
  cpi->mb.zbin_mode_boost = 0;
436
437
  /* MB level quantizer setup */
438
404k
  vp8cx_mb_init_quantizer(cpi, &cpi->mb, 0);
439
404k
}
440
441
404k
void vp8_set_quantizer(struct VP8_COMP *cpi, int Q) {
442
404k
  VP8_COMMON *cm = &cpi->common;
443
404k
  MACROBLOCKD *mbd = &cpi->mb.e_mbd;
444
404k
  int update = 0;
445
404k
  int new_delta_q;
446
404k
  int new_uv_delta_q;
447
404k
  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
404k
  cm->y1dc_delta_q = 0;
453
404k
  cm->y2ac_delta_q = 0;
454
455
404k
  if (Q < 4) {
456
0
    new_delta_q = 4 - Q;
457
404k
  } else {
458
404k
    new_delta_q = 0;
459
404k
  }
460
461
404k
  update |= cm->y2dc_delta_q != new_delta_q;
462
404k
  cm->y2dc_delta_q = new_delta_q;
463
464
404k
  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
404k
  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
404k
  update |= cm->uvdc_delta_q != new_uv_delta_q;
477
404k
  cm->uvdc_delta_q = new_uv_delta_q;
478
404k
  cm->uvac_delta_q = new_uv_delta_q;
479
480
  /* Set Segment specific quatizers */
481
404k
  mbd->segment_feature_data[MB_LVL_ALT_Q][0] =
482
404k
      cpi->segment_feature_data[MB_LVL_ALT_Q][0];
483
404k
  mbd->segment_feature_data[MB_LVL_ALT_Q][1] =
484
404k
      cpi->segment_feature_data[MB_LVL_ALT_Q][1];
485
404k
  mbd->segment_feature_data[MB_LVL_ALT_Q][2] =
486
404k
      cpi->segment_feature_data[MB_LVL_ALT_Q][2];
487
404k
  mbd->segment_feature_data[MB_LVL_ALT_Q][3] =
488
404k
      cpi->segment_feature_data[MB_LVL_ALT_Q][3];
489
490
  /* quantizer has to be reinitialized for any delta_q changes */
491
404k
  if (update) vp8cx_init_quantizer(cpi);
492
404k
}