encodemb.c 55.5 KB
Newer Older
Jingning Han's avatar
Jingning Han committed
1
/*
Yaowu Xu's avatar
Yaowu Xu committed
2
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Jingning Han's avatar
Jingning Han committed
3
 *
Yaowu Xu's avatar
Yaowu Xu committed
4
5
6
7
8
9
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
Jingning Han's avatar
Jingning Han committed
10
11
 */

Yaowu Xu's avatar
Yaowu Xu committed
12
13
14
#include "./av1_rtcd.h"
#include "./aom_config.h"
#include "./aom_dsp_rtcd.h"
Jingning Han's avatar
Jingning Han committed
15

16
#include "aom_dsp/quantize.h"
Yaowu Xu's avatar
Yaowu Xu committed
17
#include "aom_mem/aom_mem.h"
18
#include "aom_ports/mem.h"
Jingning Han's avatar
Jingning Han committed
19

20
21
22
23
#include "av1/common/idct.h"
#include "av1/common/reconinter.h"
#include "av1/common/reconintra.h"
#include "av1/common/scan.h"
Jingning Han's avatar
Jingning Han committed
24

25
26
27
28
29
#include "av1/encoder/encodemb.h"
#include "av1/encoder/hybrid_fwd_txfm.h"
#include "av1/encoder/quantize.h"
#include "av1/encoder/rd.h"
#include "av1/encoder/tokenize.h"
Jingning Han's avatar
Jingning Han committed
30

31
32
33
34
35
36
#if CONFIG_PVQ
#include "av1/encoder/encint.h"
#include "av1/common/partition.h"
#include "av1/encoder/pvq_encoder.h"
#endif

Yaowu Xu's avatar
Yaowu Xu committed
37
void av1_subtract_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane) {
Jingning Han's avatar
Jingning Han committed
38
39
40
41
42
43
  struct macroblock_plane *const p = &x->plane[plane];
  const struct macroblockd_plane *const pd = &x->e_mbd.plane[plane];
  const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
  const int bw = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
  const int bh = 4 * num_4x4_blocks_high_lookup[plane_bsize];

Yaowu Xu's avatar
Yaowu Xu committed
44
#if CONFIG_AOM_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
45
  if (x->e_mbd.cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xu's avatar
Yaowu Xu committed
46
    aom_highbd_subtract_block(bh, bw, p->src_diff, bw, p->src.buf,
Jingning Han's avatar
Jingning Han committed
47
48
49
50
                              p->src.stride, pd->dst.buf, pd->dst.stride,
                              x->e_mbd.bd);
    return;
  }
Yaowu Xu's avatar
Yaowu Xu committed
51
52
#endif  // CONFIG_AOM_HIGHBITDEPTH
  aom_subtract_block(bh, bw, p->src_diff, bw, p->src.buf, p->src.stride,
Jingning Han's avatar
Jingning Han committed
53
54
55
                     pd->dst.buf, pd->dst.stride);
}

Yaowu Xu's avatar
Yaowu Xu committed
56
typedef struct av1_token_state {
57
58
59
60
61
62
  int rate;
  int64_t error;
  int next;
  int16_t token;
  tran_low_t qc;
  tran_low_t dqc;
Yaowu Xu's avatar
Yaowu Xu committed
63
} av1_token_state;
Jingning Han's avatar
Jingning Han committed
64

65
66
// These numbers are empirically obtained.
static const int plane_rd_mult[REF_TYPES][PLANE_TYPES] = {
67
  { 10, 6 }, { 8, 5 },
68
};
Jingning Han's avatar
Jingning Han committed
69

70
71
72
73
74
#define UPDATE_RD_COST()                             \
  {                                                  \
    rd_cost0 = RDCOST(rdmult, rddiv, rate0, error0); \
    rd_cost1 = RDCOST(rdmult, rddiv, rate1, error1); \
  }
Jingning Han's avatar
Jingning Han committed
75

Angie Chiang's avatar
Angie Chiang committed
76
77
int av1_optimize_b(const AV1_COMMON *cm, MACROBLOCK *mb, int plane, int block,
                   TX_SIZE tx_size, int ctx) {
Jingning Han's avatar
Jingning Han committed
78
79
80
81
  MACROBLOCKD *const xd = &mb->e_mbd;
  struct macroblock_plane *const p = &mb->plane[plane];
  struct macroblockd_plane *const pd = &xd->plane[plane];
  const int ref = is_inter_block(&xd->mi[0]->mbmi);
Yaowu Xu's avatar
Yaowu Xu committed
82
  av1_token_state tokens[MAX_TX_SQUARE + 1][2];
83
  unsigned best_index[MAX_TX_SQUARE + 1][2];
84
  uint8_t token_cache[MAX_TX_SQUARE];
Jingning Han's avatar
Jingning Han committed
85
86
87
88
  const tran_low_t *const coeff = BLOCK_OFFSET(mb->plane[plane].coeff, block);
  tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
  tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
  const int eob = p->eobs[block];
89
  const PLANE_TYPE plane_type = pd->plane_type;
90
  const int default_eob = tx_size_2d[tx_size];
91
92
  const int16_t *const dequant_ptr = pd->dequant;
  const uint8_t *const band_translate = get_band_translate(tx_size);
93
  TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
94
  const SCAN_ORDER *const scan_order =
Angie Chiang's avatar
Angie Chiang committed
95
      get_scan(cm, tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
96
97
  const int16_t *const scan = scan_order->scan;
  const int16_t *const nb = scan_order->neighbors;
Thomas Davies's avatar
Thomas Davies committed
98
  int dqv;
99
100
#if CONFIG_AOM_QM
  int seg_id = xd->mi[0]->mbmi.segment_id;
101
  const qm_val_t *iqmatrix = pd->seg_iqmatrix[seg_id][!ref][tx_size];
102
#endif
103
  const int shift = get_tx_scale(tx_size);
104
#if CONFIG_NEW_QUANT
105
  int dq = get_dq_profile_from_ctx(mb->qindex, ctx, ref, plane_type);
106
  const dequant_val_type_nuq *dequant_val = pd->dequant_val_nuq[dq];
107
#else
108
  const int dq_step[2] = { dequant_ptr[0] >> shift, dequant_ptr[1] >> shift };
109
#endif  // CONFIG_NEW_QUANT
Jingning Han's avatar
Jingning Han committed
110
  int next = eob, sz = 0;
111
  const int64_t rdmult = (mb->rdmult * plane_rd_mult[ref][plane_type]) >> 1;
hui su's avatar
hui su committed
112
  const int64_t rddiv = mb->rddiv;
Jingning Han's avatar
Jingning Han committed
113
  int64_t rd_cost0, rd_cost1;
114
115
  int rate0, rate1;
  int64_t error0, error1;
Jingning Han's avatar
Jingning Han committed
116
  int16_t t0, t1;
117
118
  int best, band = (eob < default_eob) ? band_translate[eob]
                                       : band_translate[eob - 1];
119
  int pt, i, final_eob;
Yaowu Xu's avatar
Yaowu Xu committed
120
121
#if CONFIG_AOM_HIGHBITDEPTH
  const int *cat6_high_cost = av1_get_high_cost_table(xd->bd);
Jingning Han's avatar
Jingning Han committed
122
#else
Yaowu Xu's avatar
Yaowu Xu committed
123
  const int *cat6_high_cost = av1_get_high_cost_table(8);
Jingning Han's avatar
Jingning Han committed
124
#endif
125
  unsigned int(*token_costs)[2][COEFF_CONTEXTS][ENTROPY_TOKENS] =
126
      mb->token_costs[txsize_sqr_map[tx_size]][plane_type][ref];
127
128
  const uint16_t *band_counts = &band_count_table[tx_size][band];
  uint16_t band_left = eob - band_cum_count_table[tx_size][band] + 1;
129
130
  int shortcut = 0;
  int next_shortcut = 0;
131

132
  assert((mb->qindex == 0) ^ (xd->lossless[xd->mi[0]->mbmi.segment_id] == 0));
133

134
  token_costs += band;
Jingning Han's avatar
Jingning Han committed
135

136
  assert((!plane_type && !plane) || (plane_type && plane));
Jingning Han's avatar
Jingning Han committed
137
  assert(eob <= default_eob);
138

Jingning Han's avatar
Jingning Han committed
139
140
141
142
143
144
145
146
147
  /* Now set up a Viterbi trellis to evaluate alternative roundings. */
  /* Initialize the sentinel node of the trellis. */
  tokens[eob][0].rate = 0;
  tokens[eob][0].error = 0;
  tokens[eob][0].next = default_eob;
  tokens[eob][0].token = EOB_TOKEN;
  tokens[eob][0].qc = 0;
  tokens[eob][1] = tokens[eob][0];

148
149
  for (i = 0; i < eob; i++) {
    const int rc = scan[i];
Yaowu Xu's avatar
Yaowu Xu committed
150
    tokens[i][0].rate = av1_get_token_cost(qcoeff[rc], &t0, cat6_high_cost);
151
    tokens[i][0].token = t0;
Yaowu Xu's avatar
Yaowu Xu committed
152
    token_cache[rc] = av1_pt_energy_class[t0];
153
  }
Jingning Han's avatar
Jingning Han committed
154
155

  for (i = eob; i-- > 0;) {
156
157
    int base_bits, dx;
    int64_t d2;
Jingning Han's avatar
Jingning Han committed
158
    const int rc = scan[i];
Thomas Davies's avatar
Thomas Davies committed
159
    int x = qcoeff[rc];
160
161
#if CONFIG_AOM_QM
    int iwt = iqmatrix[rc];
Thomas Davies's avatar
Thomas Davies committed
162
163
164
165
    dqv = dequant_ptr[rc != 0];
    dqv = ((iwt * (int)dqv) + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS;
#else
    dqv = dequant_ptr[rc != 0];
166
#endif
167
    next_shortcut = shortcut;
168

Jingning Han's avatar
Jingning Han committed
169
    /* Only add a trellis state for non-zero coefficients. */
170
    if (UNLIKELY(x)) {
Jingning Han's avatar
Jingning Han committed
171
172
173
174
175
      error0 = tokens[next][0].error;
      error1 = tokens[next][1].error;
      /* Evaluate the first possibility for this state. */
      rate0 = tokens[next][0].rate;
      rate1 = tokens[next][1].rate;
176

177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
      if (next_shortcut) {
        /* Consider both possible successor states. */
        if (next < default_eob) {
          pt = get_coef_context(nb, token_cache, i + 1);
          rate0 += (*token_costs)[0][pt][tokens[next][0].token];
          rate1 += (*token_costs)[0][pt][tokens[next][1].token];
        }
        UPDATE_RD_COST();
        /* And pick the best. */
        best = rd_cost1 < rd_cost0;
      } else {
        if (next < default_eob) {
          pt = get_coef_context(nb, token_cache, i + 1);
          rate0 += (*token_costs)[0][pt][tokens[next][0].token];
        }
        best = 0;
Jingning Han's avatar
Jingning Han committed
193
      }
194
195

      dx = (dqcoeff[rc] - coeff[rc]) * (1 << shift);
Yaowu Xu's avatar
Yaowu Xu committed
196
#if CONFIG_AOM_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
197
198
199
      if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
        dx >>= xd->bd - 8;
      }
Yaowu Xu's avatar
Yaowu Xu committed
200
#endif  // CONFIG_AOM_HIGHBITDEPTH
201
      d2 = (int64_t)dx * dx;
202
      tokens[i][0].rate += (best ? rate1 : rate0);
Jingning Han's avatar
Jingning Han committed
203
204
205
      tokens[i][0].error = d2 + (best ? error1 : error0);
      tokens[i][0].next = next;
      tokens[i][0].qc = x;
206
      tokens[i][0].dqc = dqcoeff[rc];
Jingning Han's avatar
Jingning Han committed
207
208
209
210
211
212
      best_index[i][0] = best;

      /* Evaluate the second possibility for this state. */
      rate0 = tokens[next][0].rate;
      rate1 = tokens[next][1].rate;

213
      // The threshold of 3 is empirically obtained.
214
      if (UNLIKELY(abs(x) > 3)) {
215
216
        shortcut = 0;
      } else {
217
#if CONFIG_NEW_QUANT
Thomas Davies's avatar
Thomas Davies committed
218
        shortcut = ((av1_dequant_abscoeff_nuq(abs(x), dqv,
Yaowu Xu's avatar
Yaowu Xu committed
219
                                              dequant_val[band_translate[i]]) >
220
                     (abs(coeff[rc]) << shift)) &&
Thomas Davies's avatar
Thomas Davies committed
221
                    (av1_dequant_abscoeff_nuq(abs(x) - 1, dqv,
Yaowu Xu's avatar
Yaowu Xu committed
222
                                              dequant_val[band_translate[i]]) <
223
                     (abs(coeff[rc]) << shift)));
224
225
226
227
228
229
230
231
#else  // CONFIG_NEW_QUANT
#if CONFIG_AOM_QM
        if ((abs(x) * dequant_ptr[rc != 0] * iwt >
             ((abs(coeff[rc]) << shift) << AOM_QM_BITS)) &&
            (abs(x) * dequant_ptr[rc != 0] * iwt <
             (((abs(coeff[rc]) << shift) + dequant_ptr[rc != 0])
              << AOM_QM_BITS)))
#else
232
        if ((abs(x) * dequant_ptr[rc != 0] > (abs(coeff[rc]) << shift)) &&
233
234
            (abs(x) * dequant_ptr[rc != 0] <
             (abs(coeff[rc]) << shift) + dequant_ptr[rc != 0]))
235
#endif  // CONFIG_AOM_QM
236
237
238
          shortcut = 1;
        else
          shortcut = 0;
239
#endif  // CONFIG_NEW_QUANT
240
      }
Jingning Han's avatar
Jingning Han committed
241
242
243
244

      if (shortcut) {
        sz = -(x < 0);
        x -= 2 * sz + 1;
245
246
247
248
      } else {
        tokens[i][1] = tokens[i][0];
        best_index[i][1] = best_index[i][0];
        next = i;
249

250
        if (UNLIKELY(!(--band_left))) {
251
252
253
254
          --band_counts;
          band_left = *band_counts;
          --token_costs;
        }
255
        continue;
Jingning Han's avatar
Jingning Han committed
256
257
258
259
260
261
262
263
264
      }

      /* Consider both possible successor states. */
      if (!x) {
        /* If we reduced this coefficient to zero, check to see if
         *  we need to move the EOB back here.
         */
        t0 = tokens[next][0].token == EOB_TOKEN ? EOB_TOKEN : ZERO_TOKEN;
        t1 = tokens[next][1].token == EOB_TOKEN ? EOB_TOKEN : ZERO_TOKEN;
265
        base_bits = 0;
Jingning Han's avatar
Jingning Han committed
266
      } else {
Yaowu Xu's avatar
Yaowu Xu committed
267
        base_bits = av1_get_token_cost(x, &t0, cat6_high_cost);
Jingning Han's avatar
Jingning Han committed
268
269
        t1 = t0;
      }
270
271

      if (next_shortcut) {
272
        if (LIKELY(next < default_eob)) {
273
          if (t0 != EOB_TOKEN) {
Yaowu Xu's avatar
Yaowu Xu committed
274
            token_cache[rc] = av1_pt_energy_class[t0];
275
276
277
278
            pt = get_coef_context(nb, token_cache, i + 1);
            rate0 += (*token_costs)[!x][pt][tokens[next][0].token];
          }
          if (t1 != EOB_TOKEN) {
Yaowu Xu's avatar
Yaowu Xu committed
279
            token_cache[rc] = av1_pt_energy_class[t1];
280
281
282
283
284
285
286
287
288
289
290
            pt = get_coef_context(nb, token_cache, i + 1);
            rate1 += (*token_costs)[!x][pt][tokens[next][1].token];
          }
        }

        UPDATE_RD_COST();
        /* And pick the best. */
        best = rd_cost1 < rd_cost0;
      } else {
        // The two states in next stage are identical.
        if (next < default_eob && t0 != EOB_TOKEN) {
Yaowu Xu's avatar
Yaowu Xu committed
291
          token_cache[rc] = av1_pt_energy_class[t0];
Jingning Han's avatar
Jingning Han committed
292
          pt = get_coef_context(nb, token_cache, i + 1);
293
          rate0 += (*token_costs)[!x][pt][tokens[next][0].token];
Jingning Han's avatar
Jingning Han committed
294
        }
295
        best = 0;
Jingning Han's avatar
Jingning Han committed
296
297
      }

298
#if CONFIG_NEW_QUANT
Thomas Davies's avatar
Thomas Davies committed
299
      dx = av1_dequant_coeff_nuq(x, dqv, dequant_val[band_translate[i]]) -
300
           (coeff[rc] << shift);
Yaowu Xu's avatar
Yaowu Xu committed
301
#if CONFIG_AOM_HIGHBITDEPTH
hui su's avatar
hui su committed
302
303
304
      if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
        dx >>= xd->bd - 8;
      }
Yaowu Xu's avatar
Yaowu Xu committed
305
#endif  // CONFIG_AOM_HIGHBITDEPTH
306
#else   // CONFIG_NEW_QUANT
Yaowu Xu's avatar
Yaowu Xu committed
307
#if CONFIG_AOM_HIGHBITDEPTH
hui su's avatar
hui su committed
308
      if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Thomas Davies's avatar
Thomas Davies committed
309
        dx -= ((dqv >> (xd->bd - 8)) + sz) ^ sz;
hui su's avatar
hui su committed
310
      } else {
Thomas Davies's avatar
Thomas Davies committed
311
        dx -= (dqv + sz) ^ sz;
hui su's avatar
hui su committed
312
313
      }
#else
Thomas Davies's avatar
Thomas Davies committed
314
      dx -= (dqv + sz) ^ sz;
Yaowu Xu's avatar
Yaowu Xu committed
315
#endif  // CONFIG_AOM_HIGHBITDEPTH
316
#endif  // CONFIG_NEW_QUANT
317
      d2 = (int64_t)dx * dx;
hui su's avatar
hui su committed
318

Jingning Han's avatar
Jingning Han committed
319
320
321
322
323
      tokens[i][1].rate = base_bits + (best ? rate1 : rate0);
      tokens[i][1].error = d2 + (best ? error1 : error0);
      tokens[i][1].next = next;
      tokens[i][1].token = best ? t1 : t0;
      tokens[i][1].qc = x;
324
325

      if (x) {
326
#if CONFIG_NEW_QUANT
Yaowu Xu's avatar
Yaowu Xu committed
327
        tokens[i][1].dqc = av1_dequant_abscoeff_nuq(
Thomas Davies's avatar
Thomas Davies committed
328
            abs(x), dqv, dequant_val[band_translate[i]]);
329
330
331
        tokens[i][1].dqc = shift ? ROUND_POWER_OF_TWO(tokens[i][1].dqc, shift)
                                 : tokens[i][1].dqc;
        if (sz) tokens[i][1].dqc = -tokens[i][1].dqc;
332
#else
333
334
335
336
// The 32x32 transform coefficient uses half quantization step size.
// Account for the rounding difference in the dequantized coefficeint
// value when the quantization index is dropped from an even number
// to an odd number.
Thomas Davies's avatar
Thomas Davies committed
337
338
339
340
341
342
343

#if CONFIG_AOM_QM
        tran_low_t offset = dqv >> shift;
#else
        tran_low_t offset = dq_step[rc != 0];
#endif
        if (shift & x) offset += (dqv & 0x01);
344
345
346
347
348

        if (sz == 0)
          tokens[i][1].dqc = dqcoeff[rc] - offset;
        else
          tokens[i][1].dqc = dqcoeff[rc] + offset;
349
#endif  // CONFIG_NEW_QUANT
350
351
352
353
      } else {
        tokens[i][1].dqc = 0;
      }

Jingning Han's avatar
Jingning Han committed
354
355
356
357
358
359
360
361
362
      best_index[i][1] = best;
      /* Finally, make this the new head of the trellis. */
      next = i;
    } else {
      /* There's no choice to make for a zero coefficient, so we don't
       *  add a new trellis node, but we do need to update the costs.
       */
      t0 = tokens[next][0].token;
      t1 = tokens[next][1].token;
363
      pt = get_coef_context(nb, token_cache, i + 1);
Jingning Han's avatar
Jingning Han committed
364
365
      /* Update the cost of each path if we're past the EOB token. */
      if (t0 != EOB_TOKEN) {
366
        tokens[next][0].rate += (*token_costs)[1][pt][t0];
Jingning Han's avatar
Jingning Han committed
367
368
369
        tokens[next][0].token = ZERO_TOKEN;
      }
      if (t1 != EOB_TOKEN) {
370
        tokens[next][1].rate += (*token_costs)[1][pt][t1];
Jingning Han's avatar
Jingning Han committed
371
372
373
        tokens[next][1].token = ZERO_TOKEN;
      }
      best_index[i][0] = best_index[i][1] = 0;
374
      shortcut = (tokens[next][0].rate != tokens[next][1].rate);
Jingning Han's avatar
Jingning Han committed
375
376
      /* Don't update next, because we didn't add a new node. */
    }
377

378
    if (UNLIKELY(!(--band_left))) {
379
380
381
382
      --band_counts;
      band_left = *band_counts;
      --token_costs;
    }
Jingning Han's avatar
Jingning Han committed
383
384
385
386
387
388
389
390
391
  }

  /* Now pick the best path through the whole trellis. */
  rate0 = tokens[next][0].rate;
  rate1 = tokens[next][1].rate;
  error0 = tokens[next][0].error;
  error1 = tokens[next][1].error;
  t0 = tokens[next][0].token;
  t1 = tokens[next][1].token;
392
393
  rate0 += (*token_costs)[0][ctx][t0];
  rate1 += (*token_costs)[0][ctx][t1];
Jingning Han's avatar
Jingning Han committed
394
395
  UPDATE_RD_COST();
  best = rd_cost1 < rd_cost0;
396

Jingning Han's avatar
Jingning Han committed
397
  final_eob = -1;
398

Jingning Han's avatar
Jingning Han committed
399
400
401
  for (i = next; i < eob; i = next) {
    const int x = tokens[i][best].qc;
    const int rc = scan[i];
402
    if (x) final_eob = i;
Jingning Han's avatar
Jingning Han committed
403
    qcoeff[rc] = x;
404
405
    dqcoeff[rc] = tokens[i][best].dqc;

Jingning Han's avatar
Jingning Han committed
406
407
408
409
410
411
    next = tokens[i][best].next;
    best = best_index[i][best];
  }
  final_eob++;

  mb->plane[plane].eobs[block] = final_eob;
412
  assert(final_eob <= default_eob);
Jingning Han's avatar
Jingning Han committed
413
414
415
  return final_eob;
}

Yaowu Xu's avatar
Yaowu Xu committed
416
#if CONFIG_AOM_HIGHBITDEPTH
Angie Chiang's avatar
Angie Chiang committed
417
418
typedef enum QUANT_FUNC {
  QUANT_FUNC_LOWBD = 0,
419
420
  QUANT_FUNC_HIGHBD = 1,
  QUANT_FUNC_LAST = 2
Angie Chiang's avatar
Angie Chiang committed
421
422
} QUANT_FUNC;

Yaowu Xu's avatar
Yaowu Xu committed
423
424
425
426
427
static AV1_QUANT_FACADE quant_func_list[AV1_XFORM_QUANT_LAST][QUANT_FUNC_LAST] =
    { { av1_quantize_fp_facade, av1_highbd_quantize_fp_facade },
      { av1_quantize_b_facade, av1_highbd_quantize_b_facade },
      { av1_quantize_dc_facade, av1_highbd_quantize_dc_facade },
      { NULL, NULL } };
428

429
430
#elif !CONFIG_PVQ

Angie Chiang's avatar
Angie Chiang committed
431
432
typedef enum QUANT_FUNC {
  QUANT_FUNC_LOWBD = 0,
433
  QUANT_FUNC_LAST = 1
Angie Chiang's avatar
Angie Chiang committed
434
} QUANT_FUNC;
Angie Chiang's avatar
Angie Chiang committed
435

clang-format's avatar
clang-format committed
436
437
438
439
440
441
442
static AV1_QUANT_FACADE quant_func_list[AV1_XFORM_QUANT_LAST]
                                       [QUANT_FUNC_LAST] = {
                                         { av1_quantize_fp_facade },
                                         { av1_quantize_b_facade },
                                         { av1_quantize_dc_facade },
                                         { NULL }
                                       };
Angie Chiang's avatar
Angie Chiang committed
443
#endif
444

Yaowu Xu's avatar
Yaowu Xu committed
445
static FWD_TXFM_OPT fwd_txfm_opt_list[AV1_XFORM_QUANT_LAST] = {
446
447
  FWD_TXFM_OPT_NORMAL, FWD_TXFM_OPT_NORMAL, FWD_TXFM_OPT_DC, FWD_TXFM_OPT_NORMAL
};
448

Angie Chiang's avatar
Angie Chiang committed
449
450
451
void av1_xform_quant(const AV1_COMMON *cm, MACROBLOCK *x, int plane, int block,
                     int blk_row, int blk_col, BLOCK_SIZE plane_bsize,
                     TX_SIZE tx_size, AV1_XFORM_QUANT xform_quant_idx) {
Jingning Han's avatar
Jingning Han committed
452
  MACROBLOCKD *const xd = &x->e_mbd;
453
#if !CONFIG_PVQ
Jingning Han's avatar
Jingning Han committed
454
455
  const struct macroblock_plane *const p = &x->plane[plane];
  const struct macroblockd_plane *const pd = &xd->plane[plane];
456
457
458
459
#else
  struct macroblock_plane *const p = &x->plane[plane];
  struct macroblockd_plane *const pd = &xd->plane[plane];
#endif
hui su's avatar
hui su committed
460
  PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV;
hui su's avatar
hui su committed
461
  TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
462
  const int is_inter = is_inter_block(&xd->mi[0]->mbmi);
Angie Chiang's avatar
Angie Chiang committed
463
  const SCAN_ORDER *const scan_order = get_scan(cm, tx_size, tx_type, is_inter);
Jingning Han's avatar
Jingning Han committed
464
465
466
467
468
  tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
  tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
  tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
  uint16_t *const eob = &p->eobs[block];
  const int diff_stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
469
470
#if CONFIG_AOM_QM
  int seg_id = xd->mi[0]->mbmi.segment_id;
471
472
  const qm_val_t *qmatrix = pd->seg_qmatrix[seg_id][!is_inter][tx_size];
  const qm_val_t *iqmatrix = pd->seg_iqmatrix[seg_id][!is_inter][tx_size];
473
#endif
Angie Chiang's avatar
Angie Chiang committed
474
475

  FWD_TXFM_PARAM fwd_txfm_param;
476
477
478

#if !CONFIG_PVQ
  const int tx2d_size = tx_size_2d[tx_size];
479
  QUANT_PARAM qparam;
480
481
482
  const int16_t *src_diff;

  src_diff = &p->src_diff[4 * (blk_row * diff_stride + blk_col)];
483
  qparam.log_scale = get_tx_scale(tx_size);
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
#else
  MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
  tran_low_t *ref_coeff = BLOCK_OFFSET(pd->pvq_ref_coeff, block);
  uint8_t *src, *dst;
  int16_t *src_int16, *pred;
  const int src_stride = p->src.stride;
  const int dst_stride = pd->dst.stride;
  int tx_blk_size;
  int i, j;
  int skip = 1;
  PVQ_INFO *pvq_info = NULL;

  (void)scan_order;
  (void)qcoeff;

  if (x->pvq_coded) {
    assert(block < MAX_PVQ_BLOCKS_IN_SB);
    pvq_info = &x->pvq[block][plane];
  }
  dst = &pd->dst.buf[4 * (blk_row * dst_stride + blk_col)];
  src = &p->src.buf[4 * (blk_row * src_stride + blk_col)];
  src_int16 = &p->src_int16[4 * (blk_row * diff_stride + blk_col)];
  pred = &pd->pred[4 * (blk_row * diff_stride + blk_col)];

  // transform block size in pixels
  tx_blk_size = tx_size_wide[tx_size];

  // copy uint8 orig and predicted block to int16 buffer
  // in order to use existing VP10 transform functions
  for (j = 0; j < tx_blk_size; j++)
    for (i = 0; i < tx_blk_size; i++) {
      src_int16[diff_stride * j + i] = src[src_stride * j + i];
      pred[diff_stride * j + i] = dst[dst_stride * j + i];
    }
#endif
519
520

  fwd_txfm_param.tx_type = tx_type;
Angie Chiang's avatar
Angie Chiang committed
521
  fwd_txfm_param.tx_size = tx_size;
522
  fwd_txfm_param.fwd_txfm_opt = fwd_txfm_opt_list[xform_quant_idx];
Angie Chiang's avatar
Angie Chiang committed
523
524
525
  fwd_txfm_param.rd_transform = x->use_lp32x32fdct;
  fwd_txfm_param.lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];

Yaowu Xu's avatar
Yaowu Xu committed
526
#if CONFIG_AOM_HIGHBITDEPTH
527
  fwd_txfm_param.bd = xd->bd;
Jingning Han's avatar
Jingning Han committed
528
  if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Angie Chiang's avatar
Angie Chiang committed
529
    highbd_fwd_txfm(src_diff, coeff, diff_stride, &fwd_txfm_param);
Yaowu Xu's avatar
Yaowu Xu committed
530
    if (xform_quant_idx != AV1_XFORM_QUANT_SKIP_QUANT) {
531
      if (LIKELY(!x->skip_block)) {
532
        quant_func_list[xform_quant_idx][QUANT_FUNC_HIGHBD](
533
534
535
536
537
538
            coeff, tx2d_size, p, qcoeff, pd, dqcoeff, eob, scan_order, &qparam
#if CONFIG_AOM_QM
            ,
            qmatrix, iqmatrix
#endif  // CONFIG_AOM_QM
            );
539
      } else {
Yaowu Xu's avatar
Yaowu Xu committed
540
        av1_quantize_skip(tx2d_size, qcoeff, dqcoeff, eob);
541
542
543
544
      }
    }
    return;
  }
Yaowu Xu's avatar
Yaowu Xu committed
545
#endif  // CONFIG_AOM_HIGHBITDEPTH
546

547
#if !CONFIG_PVQ
548
  fwd_txfm(src_diff, coeff, diff_stride, &fwd_txfm_param);
Yaowu Xu's avatar
Yaowu Xu committed
549
  if (xform_quant_idx != AV1_XFORM_QUANT_SKIP_QUANT) {
550
    if (LIKELY(!x->skip_block)) {
551
      quant_func_list[xform_quant_idx][QUANT_FUNC_LOWBD](
552
553
554
555
556
557
          coeff, tx2d_size, p, qcoeff, pd, dqcoeff, eob, scan_order, &qparam
#if CONFIG_AOM_QM
          ,
          qmatrix, iqmatrix
#endif  // CONFIG_AOM_QM
          );
558
    } else {
Yaowu Xu's avatar
Yaowu Xu committed
559
      av1_quantize_skip(tx2d_size, qcoeff, dqcoeff, eob);
Jingning Han's avatar
Jingning Han committed
560
561
    }
  }
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
#else   // #if !CONFIG_PVQ
  fwd_txfm_param.rd_transform = 0;

  fwd_txfm(src_int16, coeff, diff_stride, &fwd_txfm_param);
  fwd_txfm(pred, ref_coeff, diff_stride, &fwd_txfm_param);

  // PVQ for inter mode block
  if (!x->skip_block)
    skip = av1_pvq_encode_helper(&x->daala_enc,
                                 coeff,        // target original vector
                                 ref_coeff,    // reference vector
                                 dqcoeff,      // de-quantized vector
                                 eob,          // End of Block marker
                                 pd->dequant,  // aom's quantizers
                                 plane,        // image plane
                                 tx_size,      // block size in log_2 - 2
                                 tx_type,
                                 &x->rate,  // rate measured
                                 x->pvq_speed,
                                 pvq_info);  // PVQ info for a block

  x->pvq_skip[plane] = skip;

  if (!skip) mbmi->skip = 0;
#endif  // #if !CONFIG_PVQ
Jingning Han's avatar
Jingning Han committed
587
588
}

589
#if CONFIG_NEW_QUANT
590
// TODO(debargha, sarah): Unify these functions with the ones above
Angie Chiang's avatar
Angie Chiang committed
591
592
593
void av1_xform_quant_nuq(const AV1_COMMON *cm, MACROBLOCK *x, int plane,
                         int block, int blk_row, int blk_col,
                         BLOCK_SIZE plane_bsize, TX_SIZE tx_size, int ctx) {
594
595
596
597
598
  MACROBLOCKD *const xd = &x->e_mbd;
  const struct macroblock_plane *const p = &x->plane[plane];
  const struct macroblockd_plane *const pd = &xd->plane[plane];
  PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV;
  TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
599
  const int is_inter = is_inter_block(&xd->mi[0]->mbmi);
Angie Chiang's avatar
Angie Chiang committed
600
  const SCAN_ORDER *const scan_order = get_scan(cm, tx_size, tx_type, is_inter);
601
602
603
  tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
  tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
  tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
604
  int dq = get_dq_profile_from_ctx(x->qindex, ctx, is_inter, plane_type);
605
606
607
  uint16_t *const eob = &p->eobs[block];
  const int diff_stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
  const int16_t *src_diff;
608
  const uint8_t *band = get_band_translate(tx_size);
609
610
611

  FWD_TXFM_PARAM fwd_txfm_param;

612
  assert((x->qindex == 0) ^ (xd->lossless[xd->mi[0]->mbmi.segment_id] == 0));
613

614
615
  fwd_txfm_param.tx_type = tx_type;
  fwd_txfm_param.tx_size = tx_size;
Yaowu Xu's avatar
Yaowu Xu committed
616
  fwd_txfm_param.fwd_txfm_opt = fwd_txfm_opt_list[AV1_XFORM_QUANT_FP];
617
618
619
620
621
622
623
  fwd_txfm_param.rd_transform = x->use_lp32x32fdct;
  fwd_txfm_param.lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];

  src_diff = &p->src_diff[4 * (blk_row * diff_stride + blk_col)];

// TODO(sarahparker) add all of these new quant quantize functions
// to quant_func_list, just trying to get this expr to work for now
Yaowu Xu's avatar
Yaowu Xu committed
624
#if CONFIG_AOM_HIGHBITDEPTH
625
626
627
  fwd_txfm_param.bd = xd->bd;
  if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
    highbd_fwd_txfm(src_diff, coeff, diff_stride, &fwd_txfm_param);
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
    switch (get_tx_scale(tx_size)) {
#if CONFIG_TX64X64
      case 2:
        highbd_quantize_64x64_nuq(
            coeff, tx_size_2d[tx_size], x->skip_block, p->quant, p->quant_shift,
            pd->dequant, (const cuml_bins_type_nuq *)p->cuml_bins_nuq[dq],
            (const dequant_val_type_nuq *)pd->dequant_val_nuq[dq], qcoeff,
            dqcoeff, eob, scan_order->scan, band);
        break;
#endif  // CONFIG_TX64X64
      case 1:
        highbd_quantize_32x32_nuq(
            coeff, tx_size_2d[tx_size], x->skip_block, p->quant, p->quant_shift,
            pd->dequant, (const cuml_bins_type_nuq *)p->cuml_bins_nuq[dq],
            (const dequant_val_type_nuq *)pd->dequant_val_nuq[dq], qcoeff,
            dqcoeff, eob, scan_order->scan, band);
        break;
      default:
        highbd_quantize_nuq(
            coeff, tx_size_2d[tx_size], x->skip_block, p->quant, p->quant_shift,
            pd->dequant, (const cuml_bins_type_nuq *)p->cuml_bins_nuq[dq],
            (const dequant_val_type_nuq *)pd->dequant_val_nuq[dq], qcoeff,
            dqcoeff, eob, scan_order->scan, band);
        break;
652
653
654
    }
    return;
  }
Yaowu Xu's avatar
Yaowu Xu committed
655
#endif  // CONFIG_AOM_HIGHBITDEPTH
656
657

  fwd_txfm(src_diff, coeff, diff_stride, &fwd_txfm_param);
658
659
660
  switch (get_tx_scale(tx_size)) {
#if CONFIG_TX64X64
    case 2:
Yaowu Xu's avatar
Yaowu Xu committed
661
662
      quantize_64x64_nuq(coeff, tx_size_2d[tx_size], x->skip_block, p->quant,
                         p->quant_shift, pd->dequant,
663
664
665
666
667
668
                         (const cuml_bins_type_nuq *)p->cuml_bins_nuq[dq],
                         (const dequant_val_type_nuq *)pd->dequant_val_nuq[dq],
                         qcoeff, dqcoeff, eob, scan_order->scan, band);
      break;
#endif  // CONFIG_TX64X64
    case 1:
Yaowu Xu's avatar
Yaowu Xu committed
669
670
      quantize_32x32_nuq(coeff, tx_size_2d[tx_size], x->skip_block, p->quant,
                         p->quant_shift, pd->dequant,
671
672
673
674
675
676
677
678
679
680
681
                         (const cuml_bins_type_nuq *)p->cuml_bins_nuq[dq],
                         (const dequant_val_type_nuq *)pd->dequant_val_nuq[dq],
                         qcoeff, dqcoeff, eob, scan_order->scan, band);
      break;
    default:
      quantize_nuq(coeff, tx_size_2d[tx_size], x->skip_block, p->quant,
                   p->quant_shift, pd->dequant,
                   (const cuml_bins_type_nuq *)p->cuml_bins_nuq[dq],
                   (const dequant_val_type_nuq *)pd->dequant_val_nuq[dq],
                   qcoeff, dqcoeff, eob, scan_order->scan, band);
      break;
682
683
684
  }
}

Angie Chiang's avatar
Angie Chiang committed
685
686
687
void av1_xform_quant_fp_nuq(const AV1_COMMON *cm, MACROBLOCK *x, int plane,
                            int block, int blk_row, int blk_col,
                            BLOCK_SIZE plane_bsize, TX_SIZE tx_size, int ctx) {
688
689
690
  MACROBLOCKD *const xd = &x->e_mbd;
  const struct macroblock_plane *const p = &x->plane[plane];
  const struct macroblockd_plane *const pd = &xd->plane[plane];
691
  const int is_inter = is_inter_block(&xd->mi[0]->mbmi);
692
693
  PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV;
  TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
Angie Chiang's avatar
Angie Chiang committed
694
  const SCAN_ORDER *const scan_order = get_scan(cm, tx_size, tx_type, is_inter);
695
  int dq = get_dq_profile_from_ctx(x->qindex, ctx, is_inter, plane_type);
696
697
698
699
700
701
  tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
  tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
  tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
  uint16_t *const eob = &p->eobs[block];
  const int diff_stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
  const int16_t *src_diff;
702
  const uint8_t *band = get_band_translate(tx_size);
703
704
705

  FWD_TXFM_PARAM fwd_txfm_param;

706
  assert((x->qindex == 0) ^ (xd->lossless[xd->mi[0]->mbmi.segment_id] == 0));
707

708
709
  fwd_txfm_param.tx_type = tx_type;
  fwd_txfm_param.tx_size = tx_size;
Yaowu Xu's avatar
Yaowu Xu committed
710
  fwd_txfm_param.fwd_txfm_opt = fwd_txfm_opt_list[AV1_XFORM_QUANT_FP];
711
712
713
714
715
716
717
  fwd_txfm_param.rd_transform = x->use_lp32x32fdct;
  fwd_txfm_param.lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];

  src_diff = &p->src_diff[4 * (blk_row * diff_stride + blk_col)];

// TODO(sarahparker) add all of these new quant quantize functions
// to quant_func_list, just trying to get this expr to work for now
Yaowu Xu's avatar
Yaowu Xu committed
718
#if CONFIG_AOM_HIGHBITDEPTH
719
720
721
  fwd_txfm_param.bd = xd->bd;
  if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
    highbd_fwd_txfm(src_diff, coeff, diff_stride, &fwd_txfm_param);
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
    switch (get_tx_scale(tx_size)) {
#if CONFIG_TX64X64
      case 2:
        highbd_quantize_64x64_fp_nuq(
            coeff, tx_size_2d[tx_size], x->skip_block, p->quant_fp, pd->dequant,
            (const cuml_bins_type_nuq *)p->cuml_bins_nuq[dq],
            (const dequant_val_type_nuq *)pd->dequant_val_nuq[dq], qcoeff,
            dqcoeff, eob, scan_order->scan, band);
        break;
#endif  // CONFIG_TX64X64
      case 1:
        highbd_quantize_32x32_fp_nuq(
            coeff, tx_size_2d[tx_size], x->skip_block, p->quant_fp, pd->dequant,
            (const cuml_bins_type_nuq *)p->cuml_bins_nuq[dq],
            (const dequant_val_type_nuq *)pd->dequant_val_nuq[dq], qcoeff,
            dqcoeff, eob, scan_order->scan, band);
        break;
      default:
        highbd_quantize_fp_nuq(
            coeff, tx_size_2d[tx_size], x->skip_block, p->quant_fp, pd->dequant,
            (const cuml_bins_type_nuq *)p->cuml_bins_nuq[dq],
            (const dequant_val_type_nuq *)pd->dequant_val_nuq[dq], qcoeff,
            dqcoeff, eob, scan_order->scan, band);
    }
    return;
  }
#endif  // CONFIG_AOM_HIGHBITDEPTH

  fwd_txfm(src_diff, coeff, diff_stride, &fwd_txfm_param);
  switch (get_tx_scale(tx_size)) {
#if CONFIG_TX64X64
    case 2:
      quantize_64x64_fp_nuq(
755
756
          coeff, tx_size_2d[tx_size], x->skip_block, p->quant_fp, pd->dequant,
          (const cuml_bins_type_nuq *)p->cuml_bins_nuq[dq],
757
758
          (const dequant_val_type_nuq *)pd->dequant_val_nuq[dq], qcoeff,
          dqcoeff, eob, scan_order->scan, band);
759
760
761
762
      break;
#endif  // CONFIG_TX64X64
    case 1:
      quantize_32x32_fp_nuq(
763
764
          coeff, tx_size_2d[tx_size], x->skip_block, p->quant_fp, pd->dequant,
          (const cuml_bins_type_nuq *)p->cuml_bins_nuq[dq],
765
766
          (const dequant_val_type_nuq *)pd->dequant_val_nuq[dq], qcoeff,
          dqcoeff, eob, scan_order->scan, band);
767
768
769
770
771
772
773
774
      break;
    default:
      quantize_fp_nuq(coeff, tx_size_2d[tx_size], x->skip_block, p->quant_fp,
                      pd->dequant,
                      (const cuml_bins_type_nuq *)p->cuml_bins_nuq[dq],
                      (const dequant_val_type_nuq *)pd->dequant_val_nuq[dq],
                      qcoeff, dqcoeff, eob, scan_order->scan, band);
      break;
775
776
777
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
778
779
780
void av1_xform_quant_dc_nuq(MACROBLOCK *x, int plane, int block, int blk_row,
                            int blk_col, BLOCK_SIZE plane_bsize,
                            TX_SIZE tx_size, int ctx) {
781
782
783
784
785
786
787
788
789
790
791
  MACROBLOCKD *const xd = &x->e_mbd;
  const struct macroblock_plane *const p = &x->plane[plane];
  const struct macroblockd_plane *const pd = &xd->plane[plane];
  PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV;
  TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
  tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
  tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
  tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
  uint16_t *const eob = &p->eobs[block];
  const int diff_stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
  const int16_t *src_diff;
792
  const int is_inter = is_inter_block(&xd->mi[0]->mbmi);
793
  int dq = get_dq_profile_from_ctx(x->qindex, ctx, is_inter, plane_type);
794
795
796

  FWD_TXFM_PARAM fwd_txfm_param;

797
  assert((x->qindex == 0) ^ (xd->lossless[xd->mi[0]->mbmi.segment_id] == 0));
798

799
800
  fwd_txfm_param.tx_type = tx_type;
  fwd_txfm_param.tx_size = tx_size;
Yaowu Xu's avatar
Yaowu Xu committed
801
  fwd_txfm_param.fwd_txfm_opt = fwd_txfm_opt_list[AV1_XFORM_QUANT_DC];
802
803
804
805
806
807
808
  fwd_txfm_param.rd_transform = x->use_lp32x32fdct;
  fwd_txfm_param.lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];

  src_diff = &p->src_diff[4 * (blk_row * diff_stride + blk_col)];

// TODO(sarahparker) add all of these new quant quantize functions
// to quant_func_list, just trying to get this expr to work for now
Yaowu Xu's avatar
Yaowu Xu committed
809
#if CONFIG_AOM_HIGHBITDEPTH
810
811
812
  fwd_txfm_param.bd = xd->bd;
  if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
    highbd_fwd_txfm(src_diff, coeff, diff_stride, &fwd_txfm_param);
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
    switch (get_tx_scale(tx_size)) {
#if CONFIG_TX64X64
      case 2:
        highbd_quantize_dc_64x64_nuq(
            coeff, tx_size_2d[tx_size], x->skip_block, p->quant[0],
            p->quant_shift[0], pd->dequant[0], p->cuml_bins_nuq[dq][0],
            pd->dequant_val_nuq[dq][0], qcoeff, dqcoeff, eob);
        break;
#endif  // CONFIG_TX64X64
      case 1:
        highbd_quantize_dc_32x32_nuq(
            coeff, tx_size_2d[tx_size], x->skip_block, p->quant[0],
            p->quant_shift[0], pd->dequant[0], p->cuml_bins_nuq[dq][0],
            pd->dequant_val_nuq[dq][0], qcoeff, dqcoeff, eob);
        break;
      default:
        highbd_quantize_dc_nuq(
            coeff, tx_size_2d[tx_size], x->skip_block, p->quant[0],
            p->quant_shift[0], pd->dequant[0], p->cuml_bins_nuq[dq][0],
            pd->dequant_val_nuq[dq][0], qcoeff, dqcoeff, eob);
        break;
834
835
836
    }
    return;
  }
Yaowu Xu's avatar
Yaowu Xu committed
837
#endif  // CONFIG_AOM_HIGHBITDEPTH
838
839

  fwd_txfm(src_diff, coeff, diff_stride, &fwd_txfm_param);
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
  switch (get_tx_scale(tx_size)) {
#if CONFIG_TX64X64
    case 2:
      quantize_dc_64x64_nuq(coeff, tx_size_2d[tx_size], x->skip_block,
                            p->quant[0], p->quant_shift[0], pd->dequant[0],
                            p->cuml_bins_nuq[dq][0], pd->dequant_val_nuq[dq][0],
                            qcoeff, dqcoeff, eob);
      break;
#endif  // CONFIG_TX64X64
    case 1:
      quantize_dc_32x32_nuq(coeff, tx_size_2d[tx_size], x->skip_block,
                            p->quant[0], p->quant_shift[0], pd->dequant[0],
                            p->cuml_bins_nuq[dq][0], pd->dequant_val_nuq[dq][0],
                            qcoeff, dqcoeff, eob);
      break;
    default:
      quantize_dc_nuq(coeff, tx_size_2d[tx_size], x->skip_block, p->quant[0],
                      p->quant_shift[0], pd->dequant[0],
                      p->cuml_bins_nuq[dq][0], pd->dequant_val_nuq[dq][0],
                      qcoeff, dqcoeff, eob);
      break;
861
862
863
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
864
865
866
void av1_xform_quant_dc_fp_nuq(MACROBLOCK *x, int plane, int block, int blk_row,
                               int blk_col, BLOCK_SIZE plane_bsize,
                               TX_SIZE tx_size, int ctx) {
867
868
869
870
871
872
873
874
875
876
877
  MACROBLOCKD *const xd = &x->e_mbd;
  const struct macroblock_plane *const p = &x->plane[plane];
  const struct macroblockd_plane *const pd = &xd->plane[plane];
  PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV;
  TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
  tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
  tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
  tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
  uint16_t *const eob = &p->eobs[block];
  const int diff_stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
  const int16_t *src_diff;
878
  const int is_inter = is_inter_block(&xd->mi[0]->mbmi);
879
  int dq = get_dq_profile_from_ctx(x->qindex, ctx, is_inter, plane_type);
880
881
882

  FWD_TXFM_PARAM fwd_txfm_param;

883
  assert((x->qindex == 0) ^ (xd->lossless[xd->mi[0]->mbmi.segment_id] == 0));
884

885
886
  fwd_txfm_param.tx_type = tx_type;
  fwd_txfm_param.tx_size = tx_size;
Yaowu Xu's avatar
Yaowu Xu committed
887
  fwd_txfm_param.fwd_txfm_opt = fwd_txfm_opt_list[AV1_XFORM_QUANT_DC];
888
889
890
891
892
893
894
  fwd_txfm_param.rd_transform = x->use_lp32x32fdct;
  fwd_txfm_param.lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];

  src_diff = &p->src_diff[4 * (blk_row * diff_stride + blk_col)];

// TODO(sarahparker) add all of these new quant quantize functions
// to quant_func_list, just trying to get this expr to work for now
Yaowu Xu's avatar
Yaowu Xu committed
895
#if CONFIG_AOM_HIGHBITDEPTH
896
897
898
  fwd_txfm_param.bd = xd->bd;
  if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
    highbd_fwd_txfm(src_diff, coeff, diff_stride, &fwd_txfm_param);
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
    switch (get_tx_scale(tx_size)) {
#if CONFIG_TX64X64
      case 2:
        highbd_quantize_dc_64x64_fp_nuq(
            coeff, tx_size_2d[tx_size], x->skip_block, p->quant_fp[0],
            pd->dequant[0], p->cuml_bins_nuq[dq][0], pd->dequant_val_nuq[dq][0],
            qcoeff, dqcoeff, eob);
        break;
#endif  // CONFIG_TX64X64
      case 1:
        highbd_quantize_dc_32x32_fp_nuq(
            coeff, tx_size_2d[tx_size], x->skip_block, p->quant_fp[0],
            pd->dequant[0], p->cuml_bins_nuq[dq][0], pd->dequant_val_nuq[dq][0],
            qcoeff, dqcoeff, eob);
        break;
      default:
        highbd_quantize_dc_fp_nuq(
            coeff, tx_size_2d[tx_size], x->skip_block, p->quant_fp[0],
            pd->dequant[0], p->cuml_bins_nuq[dq][0], pd->dequant_val_nuq[dq][0],
            qcoeff, dqcoeff, eob);
        break;
920
921
922
    }
    return;
  }
Yaowu Xu's avatar
Yaowu Xu committed
923
#endif  // CONFIG_AOM_HIGHBITDEPTH
924
925

  fwd_txfm(src_diff, coeff, diff_stride, &fwd_txfm_param);
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
  switch (get_tx_scale(tx_size)) {
#if CONFIG_TX64X64
    case 2:
      quantize_dc_64x64_fp_nuq(
          coeff, tx_size_2d[tx_size], x->skip_block, p->quant_fp[0],
          pd->dequant[0], p->cuml_bins_nuq[dq][0], pd->dequant_val_nuq[dq][0],
          qcoeff, dqcoeff, eob);
      break;
#endif  // CONFIG_TX64X64
    case 1:
      quantize_dc_32x32_fp_nuq(
          coeff, tx_size_2d[tx_size], x->skip_block, p->quant_fp[0],
          pd->dequant[0], p->cuml_bins_nuq[dq][0], pd->dequant_val_nuq[dq][0],
          qcoeff, dqcoeff, eob);
      break;
    default:
      quantize_dc_fp_nuq(coeff, tx_size_2d[tx_size], x->skip_block,
                         p->quant_fp[0], pd->dequant[0],
                         p->cuml_bins_nuq[dq][0], pd->dequant_val_nuq[dq][0],
                         qcoeff, dqcoeff, eob);
      break;
947
948
949
950
  }
}
#endif  // CONFIG_NEW_QUANT

951
static void encode_block(int plane, int block, int blk_row, int blk_col,
952
                         BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *arg) {
Jingning Han's avatar
Jingning Han committed
953
  struct encode_b_args *const args = arg;
Angie Chiang's avatar
Angie Chiang committed
954
  AV1_COMMON *cm = args->cm;
Jingning Han's avatar
Jingning Han committed
955
956
  MACROBLOCK *const x = args->x;
  MACROBLOCKD *const xd = &x->e_mbd;
957
  int ctx;
Jingning Han's avatar
Jingning Han committed
958
959
960
961
962
  struct macroblock_plane *const p = &x->plane[plane];
  struct macroblockd_plane *const pd = &xd->plane[plane];
  tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
  uint8_t *dst;
  ENTROPY_CONTEXT *a, *l;
Angie Chiang's avatar
Angie Chiang committed
963
  INV_TXFM_PARAM inv_txfm_param;
964
965
966
967
#if CONFIG_PVQ
  int tx_blk_size;
  int i, j;
#endif
968
969
#if CONFIG_VAR_TX
  int i;
970
  const int bwl = b_width_log2_lookup[plane_bsize];
971
#endif
972
  dst = &pd->dst.buf[4 * blk_row * pd->dst.stride + 4 * blk_col];
973
974
  a = &args->ta[blk_col];
  l = &args->tl[blk_row];
975
976
977
978
979
#if CONFIG_VAR_TX
  ctx = get_entropy_context(tx_size, a, l);
#else
  ctx = combine_entropy_contexts(*a, *l);
#endif
Jingning Han's avatar
Jingning Han committed
980

Alex Converse's avatar
Alex Converse committed
981
#if CONFIG_VAR_TX
982
  // Assert not magic number (uninitialized).
983
984
  assert(x->blk_skip[plane][(blk_row << bwl) + blk_col] != 234);

985
  if (x->blk_skip[plane][(blk_row << bwl) + blk_col] == 0) {
986
#else
987
  {
988
#endif
989
#if CONFIG_NEW_QUANT
Angie Chiang's avatar
Angie Chiang committed
990
    av1_xform_quant_fp_nuq(cm, x, plane, block, blk_row, blk_col, plane_bsize,
Yaowu Xu's avatar
Yaowu Xu committed
991
                           tx_size, ctx);
992
#else
Angie Chiang's avatar
Angie Chiang committed
993
    av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Yaowu Xu's avatar
Yaowu Xu committed
994
                    AV1_XFORM_QUANT_FP);
995
#endif  // CONFIG_NEW_QUANT
Jingning Han's avatar
Jingning Han committed
996
  }
997
998
#if CONFIG_VAR_TX
  else {
999
    p->eobs[block] = 0;
1000
  }
For faster browsing, not all history is shown. View entire blame