Coverage Report

Created: 2026-01-16 07:48

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