Coverage Report

Created: 2026-04-01 07:42

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