Coverage Report

Created: 2024-09-06 07:53

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