encodemb.c 41.3 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
  const int shift = get_tx_scale(tx_size);
100 101
#if CONFIG_AOM_QM
  int seg_id = xd->mi[0]->mbmi.segment_id;
102
  const qm_val_t *iqmatrix = pd->seg_iqmatrix[seg_id][!ref][tx_size];
103
#endif
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
#elif !CONFIG_AOM_QM
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
  QUANT_FUNC_HIGHBD = 1,
420
  QUANT_FUNC_TYPES = 2
Angie Chiang's avatar
Angie Chiang committed
421 422
} QUANT_FUNC;

423 424 425
static AV1_QUANT_FACADE
    quant_func_list[AV1_XFORM_QUANT_TYPES][QUANT_FUNC_TYPES] = {
      { av1_quantize_fp_facade, av1_highbd_quantize_fp_facade },
Yaowu Xu's avatar
Yaowu Xu committed
426 427
      { av1_quantize_b_facade, av1_highbd_quantize_b_facade },
      { av1_quantize_dc_facade, av1_highbd_quantize_dc_facade },
428 429 430 431 432 433 434
#if CONFIG_NEW_QUANT
      { av1_quantize_fp_nuq_facade, av1_highbd_quantize_fp_nuq_facade },
      { av1_quantize_b_nuq_facade, av1_highbd_quantize_b_nuq_facade },
      { av1_quantize_dc_nuq_facade, av1_highbd_quantize_dc_nuq_facade },
#endif  // CONFIG_NEW_QUANT
      { NULL, NULL }
    };
435

436 437
#elif !CONFIG_PVQ

Angie Chiang's avatar
Angie Chiang committed
438 439
typedef enum QUANT_FUNC {
  QUANT_FUNC_LOWBD = 0,
440
  QUANT_FUNC_TYPES = 1
Angie Chiang's avatar
Angie Chiang committed
441
} QUANT_FUNC;
Angie Chiang's avatar
Angie Chiang committed
442

443 444
static AV1_QUANT_FACADE quant_func_list[AV1_XFORM_QUANT_TYPES]
                                       [QUANT_FUNC_TYPES] = {
clang-format's avatar
clang-format committed
445 446 447
                                         { av1_quantize_fp_facade },
                                         { av1_quantize_b_facade },
                                         { av1_quantize_dc_facade },
448 449 450 451 452
#if CONFIG_NEW_QUANT
                                         { av1_quantize_fp_nuq_facade },
                                         { av1_quantize_b_nuq_facade },
                                         { av1_quantize_dc_nuq_facade },
#endif  // CONFIG_NEW_QUANT
clang-format's avatar
clang-format committed
453 454
                                         { NULL }
                                       };
Angie Chiang's avatar
Angie Chiang committed
455
#endif
456

457 458 459 460 461 462
static FWD_TXFM_OPT fwd_txfm_opt_list[AV1_XFORM_QUANT_TYPES] = {
  FWD_TXFM_OPT_NORMAL, FWD_TXFM_OPT_NORMAL, FWD_TXFM_OPT_DC,
#if CONFIG_NEW_QUANT
  FWD_TXFM_OPT_NORMAL, FWD_TXFM_OPT_NORMAL, FWD_TXFM_OPT_DC,
#endif  // CONFIG_NEW_QUANT
  FWD_TXFM_OPT_NORMAL
463
};
464

Angie Chiang's avatar
Angie Chiang committed
465 466
void av1_xform_quant(const AV1_COMMON *cm, MACROBLOCK *x, int plane, int block,
                     int blk_row, int blk_col, BLOCK_SIZE plane_bsize,
467 468
                     TX_SIZE tx_size, int ctx,
                     AV1_XFORM_QUANT xform_quant_idx) {
Jingning Han's avatar
Jingning Han committed
469
  MACROBLOCKD *const xd = &x->e_mbd;
470
#if !CONFIG_PVQ
Jingning Han's avatar
Jingning Han committed
471 472
  const struct macroblock_plane *const p = &x->plane[plane];
  const struct macroblockd_plane *const pd = &xd->plane[plane];
473 474 475 476
#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
477
  PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV;
hui su's avatar
hui su committed
478
  TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
479
  const int is_inter = is_inter_block(&xd->mi[0]->mbmi);
Angie Chiang's avatar
Angie Chiang committed
480
  const SCAN_ORDER *const scan_order = get_scan(cm, tx_size, tx_type, is_inter);
Jingning Han's avatar
Jingning Han committed
481 482 483 484 485
  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];
486 487
#if CONFIG_AOM_QM
  int seg_id = xd->mi[0]->mbmi.segment_id;
488 489
  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];
490
#endif
Angie Chiang's avatar
Angie Chiang committed
491 492

  FWD_TXFM_PARAM fwd_txfm_param;
493 494 495

#if !CONFIG_PVQ
  const int tx2d_size = tx_size_2d[tx_size];
496
  QUANT_PARAM qparam;
497 498 499
  const int16_t *src_diff;

  src_diff = &p->src_diff[4 * (blk_row * diff_stride + blk_col)];
500
  qparam.log_scale = get_tx_scale(tx_size);
501 502 503 504 505 506 507 508
#if CONFIG_NEW_QUANT
  qparam.tx_size = tx_size;
  qparam.dq = get_dq_profile_from_ctx(x->qindex, ctx, is_inter, plane_type);
#endif  // CONFIG_NEW_QUANT
#if CONFIG_AOM_QM
  qparam.qmatrix = qmatrix;
  qparam.iqmatrix = iqmatrix;
#endif  // CONFIG_AOM_QM
509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543
#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
544
  (void)ctx;
545 546

  fwd_txfm_param.tx_type = tx_type;
Angie Chiang's avatar
Angie Chiang committed
547
  fwd_txfm_param.tx_size = tx_size;
548
  fwd_txfm_param.fwd_txfm_opt = fwd_txfm_opt_list[xform_quant_idx];
Angie Chiang's avatar
Angie Chiang committed
549 550 551
  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
552
#if CONFIG_AOM_HIGHBITDEPTH
553
  fwd_txfm_param.bd = xd->bd;
Jingning Han's avatar
Jingning Han committed
554
  if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Angie Chiang's avatar
Angie Chiang committed
555
    highbd_fwd_txfm(src_diff, coeff, diff_stride, &fwd_txfm_param);
Yaowu Xu's avatar
Yaowu Xu committed
556
    if (xform_quant_idx != AV1_XFORM_QUANT_SKIP_QUANT) {
557
      if (LIKELY(!x->skip_block)) {
558
        quant_func_list[xform_quant_idx][QUANT_FUNC_HIGHBD](
559
            coeff, tx2d_size, p, qcoeff, pd, dqcoeff, eob, scan_order, &qparam);
560
      } else {
Yaowu Xu's avatar
Yaowu Xu committed
561
        av1_quantize_skip(tx2d_size, qcoeff, dqcoeff, eob);
562 563 564 565
      }
    }
    return;
  }
Yaowu Xu's avatar
Yaowu Xu committed
566
#endif  // CONFIG_AOM_HIGHBITDEPTH
567

568
#if !CONFIG_PVQ
569
  fwd_txfm(src_diff, coeff, diff_stride, &fwd_txfm_param);
Yaowu Xu's avatar
Yaowu Xu committed
570
  if (xform_quant_idx != AV1_XFORM_QUANT_SKIP_QUANT) {
571
    if (LIKELY(!x->skip_block)) {
572
      quant_func_list[xform_quant_idx][QUANT_FUNC_LOWBD](
573
          coeff, tx2d_size, p, qcoeff, pd, dqcoeff, eob, scan_order, &qparam);
574
    } else {
Yaowu Xu's avatar
Yaowu Xu committed
575
      av1_quantize_skip(tx2d_size, qcoeff, dqcoeff, eob);
Jingning Han's avatar
Jingning Han committed
576 577
    }
  }
578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602
#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
603 604
}

605
static void encode_block(int plane, int block, int blk_row, int blk_col,
606
                         BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *arg) {
Jingning Han's avatar
Jingning Han committed
607
  struct encode_b_args *const args = arg;
Angie Chiang's avatar
Angie Chiang committed
608
  AV1_COMMON *cm = args->cm;
Jingning Han's avatar
Jingning Han committed
609 610
  MACROBLOCK *const x = args->x;
  MACROBLOCKD *const xd = &x->e_mbd;
611
  int ctx;
Jingning Han's avatar
Jingning Han committed
612 613 614 615 616
  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
617
  INV_TXFM_PARAM inv_txfm_param;
618 619 620 621
#if CONFIG_PVQ
  int tx_blk_size;
  int i, j;
#endif
622 623
#if CONFIG_VAR_TX
  int i;
624
  const int bwl = b_width_log2_lookup[plane_bsize];
625
#endif
626
  dst = &pd->dst.buf[4 * blk_row * pd->dst.stride + 4 * blk_col];
627 628
  a = &args->ta[blk_col];
  l = &args->tl[blk_row];
629 630 631 632 633
#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
634

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

639
  if (x->blk_skip[plane][(blk_row << bwl) + blk_col] == 0) {
640
#else
641
  {
642
#endif
643
#if CONFIG_NEW_QUANT
644 645
    av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
                    ctx, AV1_XFORM_QUANT_FP_NUQ);
646
#else
Angie Chiang's avatar
Angie Chiang committed
647
    av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
648
                    ctx, AV1_XFORM_QUANT_FP);
649
#endif  // CONFIG_NEW_QUANT
Jingning Han's avatar
Jingning Han committed
650
  }
651 652
#if CONFIG_VAR_TX
  else {
653
    p->eobs[block] = 0;
654 655
  }
#endif
656
#if !CONFIG_PVQ
657
  if (p->eobs[block] && !xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Angie Chiang's avatar
Angie Chiang committed
658
    *a = *l = av1_optimize_b(cm, x, plane, block, tx_size, ctx) > 0;
Jingning Han's avatar
Jingning Han committed
659 660 661 662
  } else {
    *a = *l = p->eobs[block] > 0;
  }

663
#if CONFIG_VAR_TX
664 665 666
  for (i = 0; i < tx_size_wide_unit[tx_size]; ++i) a[i] = a[0];

  for (i = 0; i < tx_size_high_unit[tx_size]; ++i) l[i] = l[0];
667 668
#endif

669
  if (p->eobs[block]) *(args->skip) = 0;
Jingning Han's avatar
Jingning Han committed
670

671
  if (p->eobs[block] == 0) return;
672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689
#else
  (void)ctx;
  *a = *l = !x->pvq_skip[plane];

  if (!x->pvq_skip[plane]) *(args->skip) = 0;

  if (x->pvq_skip[plane]) return;

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

  // Since av1 does not have separate function which does inverse transform
  // but av1_inv_txfm_add_*x*() also does addition of predicted image to
  // inverse transformed image,
  // pass blank dummy image to av1_inv_txfm_add_*x*(), i.e. set dst as zeros
  for (j = 0; j < tx_blk_size; j++)
    for (i = 0; i < tx_blk_size; i++) dst[j * pd->dst.stride + i] = 0;
#endif
Angie Chiang's avatar
Angie Chiang committed
690 691 692 693 694 695 696

  // inverse transform parameters
  inv_txfm_param.tx_type = get_tx_type(pd->plane_type, xd, block, tx_size);
  inv_txfm_param.tx_size = tx_size;
  inv_txfm_param.eob = p->eobs[block];
  inv_txfm_param.lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];

Yaowu Xu's avatar
Yaowu Xu committed
697
#if CONFIG_AOM_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
698
  if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Angie Chiang's avatar
Angie Chiang committed
699 700
    inv_txfm_param.bd = xd->bd;
    highbd_inv_txfm_add(dqcoeff, dst, pd->dst.stride, &inv_txfm_param);
Jingning Han's avatar
Jingning Han committed
701 702
    return;
  }
Yaowu Xu's avatar
Yaowu Xu committed
703
#endif  // CONFIG_AOM_HIGHBITDEPTH
Angie Chiang's avatar
Angie Chiang committed
704
  inv_txfm_add(dqcoeff, dst, pd->dst.stride, &inv_txfm_param);
Jingning Han's avatar
Jingning Han committed
705 706
}

707 708 709 710 711 712 713 714
#if CONFIG_VAR_TX
static void encode_block_inter(int plane, int block, int blk_row, int blk_col,
                               BLOCK_SIZE plane_bsize, TX_SIZE tx_size,
                               void *arg) {
  struct encode_b_args *const args = arg;
  MACROBLOCK *const x = args->x;
  MACROBLOCKD *const xd = &x->e_mbd;
  MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
715
  const BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
716
  const struct macroblockd_plane *const pd = &xd->plane[plane];
717 718
  const int tx_row = blk_row >> (1 - pd->subsampling_y);
  const int tx_col = blk_col >> (1 - pd->subsampling_x);
Debargha Mukherjee's avatar
Debargha Mukherjee committed
719
  TX_SIZE plane_tx_size;
720 721
  const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
  const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
722

723
  if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
724

725 726 727
  plane_tx_size =
      plane ? uv_txsize_lookup[bsize][mbmi->inter_tx_size[tx_row][tx_col]][0][0]
            : mbmi->inter_tx_size[tx_row][tx_col];
Debargha Mukherjee's avatar
Debargha Mukherjee committed
728

729
  if (tx_size == plane_tx_size) {
730
    encode_block(plane, block, blk_row, blk_col, plane_bsize, tx_size, arg);
731
  } else {
732 733 734
    const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
    // This is the square transform block partition entry point.
    int bsl = tx_size_wide_unit[sub_txs];
735 736
    int i;
    assert(bsl > 0);
737
    assert(tx_size < TX_SIZES_ALL);
738

739
    for (i = 0; i < 4; ++i) {
740 741 742
      const int offsetr = blk_row + ((i >> 1) * bsl);
      const int offsetc = blk_col + ((i & 0x01) * bsl);
      int step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
743

744
      if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
745

746 747 748
      encode_block_inter(plane, block, offsetr, offsetc, plane_bsize, sub_txs,
                         arg);
      block += step;
749 750 751 752 753
    }
  }
}
#endif

Angie Chiang's avatar
Angie Chiang committed
754 755 756 757 758
typedef struct encode_block_pass1_args {
  AV1_COMMON *cm;
  MACROBLOCK *x;
} encode_block_pass1_args;

759
static void encode_block_pass1(int plane, int block, int blk_row, int blk_col,
760 761
                               BLOCK_SIZE plane_bsize, TX_SIZE tx_size,
                               void *arg) {
Angie Chiang's avatar
Angie Chiang committed
762 763 764
  encode_block_pass1_args *args = (encode_block_pass1_args *)arg;
  AV1_COMMON *cm = args->cm;
  MACROBLOCK *const x = args->x;
Jingning Han's avatar
Jingning Han committed
765 766 767 768 769
  MACROBLOCKD *const xd = &x->e_mbd;
  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;
770
  int ctx = 0;
771
  dst = &pd->dst.buf[4 * blk_row * pd->dst.stride + 4 * blk_col];
Jingning Han's avatar
Jingning Han committed
772

773
#if CONFIG_NEW_QUANT
774 775
  av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
                  ctx, AV1_XFORM_QUANT_B_NUQ);
776
#else
Angie Chiang's avatar
Angie Chiang committed
777
  av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
778
                  ctx, AV1_XFORM_QUANT_B);
779
#endif  // CONFIG_NEW_QUANT
780
#if !CONFIG_PVQ
Jingning Han's avatar
Jingning Han committed
781
  if (p->eobs[block] > 0) {
782 783 784 785 786 787 788 789 790 791 792 793 794 795 796
#else
  if (!x->pvq_skip[plane]) {
    {
      int tx_blk_size;
      int i, j;
      // transform block size in pixels
      tx_blk_size = tx_size_wide[tx_size];

      // Since av1 does not have separate function which does inverse transform
      // but av1_inv_txfm_add_*x*() also does addition of predicted image to
      // inverse transformed image,
      // pass blank dummy image to av1_inv_txfm_add_*x*(), i.e. set dst as zeros
      for (j = 0; j < tx_blk_size; j++)
        for (i = 0; i < tx_blk_size; i++) dst[j * pd->dst.stride + i] = 0;
    }
Jingning Han's avatar
Jingning Han committed
797
#endif  // !CONFIG_PVQ
Yaowu Xu's avatar
Yaowu Xu committed
798
#if CONFIG_AOM_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
799
    if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xu's avatar
Yaowu Xu committed
800
      if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Yaowu Xu's avatar
Yaowu Xu committed
801 802
        av1_highbd_iwht4x4_add(dqcoeff, dst, pd->dst.stride, p->eobs[block],
                               xd->bd);
803
      } else {
Yaowu Xu's avatar
Yaowu Xu committed
804 805
        av1_highbd_idct4x4_add(dqcoeff, dst, pd->dst.stride, p->eobs[block],
                               xd->bd);
806 807
      }
      return;
Jingning Han's avatar
Jingning Han committed
808
    }
809
#endif  //  CONFIG_AOM_HIGHBITDEPTH
Yaowu Xu's avatar
Yaowu Xu committed
810
    if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Yaowu Xu's avatar
Yaowu Xu committed
811
      av1_iwht4x4_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
812
    } else {
Yaowu Xu's avatar
Yaowu Xu committed
813
      av1_idct4x4_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
814
    }
Jingning Han's avatar
Jingning Han committed
815 816 817
  }
}

Angie Chiang's avatar
Angie Chiang committed
818 819
void av1_encode_sby_pass1(AV1_COMMON *cm, MACROBLOCK *x, BLOCK_SIZE bsize) {
  encode_block_pass1_args args = { cm, x };
Yaowu Xu's avatar
Yaowu Xu committed
820 821
  av1_subtract_plane(x, bsize, 0);
  av1_foreach_transformed_block_in_plane(&x->e_mbd, bsize, 0,
Angie Chiang's avatar
Angie Chiang committed
822
                                         encode_block_pass1, &args);
Jingning Han's avatar
Jingning Han committed
823 824
}

Angie Chiang's avatar
Angie Chiang committed
825
void av1_encode_sb(AV1_COMMON *cm, MACROBLOCK *x, BLOCK_SIZE bsize) {
Jingning Han's avatar
Jingning Han committed
826 827 828
  MACROBLOCKD *const xd = &x->e_mbd;
  struct optimize_ctx ctx;
  MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Angie Chiang's avatar
Angie Chiang committed
829
  struct encode_b_args arg = { cm, x, &ctx, &mbmi->skip, NULL, NULL, 1 };
Jingning Han's avatar
Jingning Han committed
830 831 832 833
  int plane;

  mbmi->skip = 1;

834
  if (x->skip) return;
Jingning Han's avatar
Jingning Han committed
835 836

  for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
837 838 839 840
#if CONFIG_VAR_TX
    // TODO(jingning): Clean this up.
    const struct macroblockd_plane *const pd = &xd->plane[plane];
    const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
841 842
    const int mi_width = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
    const int mi_height = block_size_high[plane_bsize] >> tx_size_wide_log2[0];
843
    const TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
844
    const BLOCK_SIZE txb_size = txsize_to_bsize[max_tx_size];
845 846
    const int bw = block_size_wide[txb_size] >> tx_size_wide_log2[0];
    const int bh = block_size_high[txb_size] >> tx_size_wide_log2[0];
847 848
    int idx, idy;
    int block = 0;
849
    int step = tx_size_wide_unit[max_tx_size] * tx_size_high_unit[max_tx_size];
Yaowu Xu's avatar
Yaowu Xu committed
850
    av1_get_entropy_contexts(bsize, TX_4X4, pd, ctx.ta[plane], ctx.tl[plane]);
851
#else
852
    const struct macroblockd_plane *const pd = &xd->plane[plane];
853
    const TX_SIZE tx_size = plane ? get_uv_tx_size(mbmi, pd) : mbmi->tx_size;
Yaowu Xu's avatar
Yaowu Xu committed
854
    av1_get_entropy_contexts(bsize, tx_size, pd, ctx.ta[plane], ctx.tl[plane]);
855
#endif
856