encodemb.c 55.9 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