decodeframe.c 153 KB
Newer Older
Jingning Han's avatar
Jingning Han committed
1
/*
2
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Jingning Han's avatar
Jingning Han committed
3
 *
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 12 13 14
 */

#include <assert.h>
#include <stdlib.h>  // qsort()

15 16 17
#include "./aom_config.h"
#include "./aom_dsp_rtcd.h"
#include "./aom_scale_rtcd.h"
Jingning Han's avatar
Jingning Han committed
18
#include "./av1_rtcd.h"
Jingning Han's avatar
Jingning Han committed
19

20
#include "aom/aom_codec.h"
21
#include "aom_dsp/aom_dsp_common.h"
22
#include "aom_dsp/binary_codes_reader.h"
Jingning Han's avatar
Jingning Han committed
23 24
#include "aom_dsp/bitreader.h"
#include "aom_dsp/bitreader_buffer.h"
25
#include "aom_mem/aom_mem.h"
26 27
#include "aom_ports/mem.h"
#include "aom_ports/mem_ops.h"
28 29
#include "aom_scale/aom_scale.h"
#include "aom_util/aom_thread.h"
Jingning Han's avatar
Jingning Han committed
30

31 32 33 34
#if CONFIG_BITSTREAM_DEBUG
#include "aom_util/debug_util.h"
#endif  // CONFIG_BITSTREAM_DEBUG

35
#include "av1/common/alloccommon.h"
36
#if CONFIG_CDEF
37
#include "av1/common/cdef.h"
38
#endif
39 40 41
#if CONFIG_INSPECTION
#include "av1/decoder/inspection.h"
#endif
42 43 44
#include "av1/common/common.h"
#include "av1/common/entropy.h"
#include "av1/common/entropymode.h"
45
#include "av1/common/entropymv.h"
46
#include "av1/common/idct.h"
47
#include "av1/common/mvref_common.h"
48 49 50
#include "av1/common/pred_common.h"
#include "av1/common/quant_common.h"
#include "av1/common/reconinter.h"
Jingning Han's avatar
Jingning Han committed
51
#include "av1/common/reconintra.h"
52 53 54
#if CONFIG_FRAME_SUPERRES
#include "av1/common/resize.h"
#endif  // CONFIG_FRAME_SUPERRES
55
#include "av1/common/seg_common.h"
Jingning Han's avatar
Jingning Han committed
56
#include "av1/common/thread_common.h"
57
#include "av1/common/tile_common.h"
58

59 60 61
#include "av1/decoder/decodeframe.h"
#include "av1/decoder/decodemv.h"
#include "av1/decoder/decoder.h"
62 63 64
#if CONFIG_LV_MAP
#include "av1/decoder/decodetxb.h"
#endif
Jingning Han's avatar
Jingning Han committed
65
#include "av1/decoder/detokenize.h"
66
#include "av1/decoder/dsubexp.h"
67
#include "av1/decoder/symbolrate.h"
Jingning Han's avatar
Jingning Han committed
68

69
#if CONFIG_WARPED_MOTION || CONFIG_GLOBAL_MOTION
Yue Chen's avatar
Yue Chen committed
70
#include "av1/common/warped_motion.h"
71
#endif  // CONFIG_WARPED_MOTION || CONFIG_GLOBAL_MOTION
Yue Chen's avatar
Yue Chen committed
72

73
#define MAX_AV1_HEADER_SIZE 80
Michael Bebenita's avatar
Michael Bebenita committed
74
#define ACCT_STR __func__
Jingning Han's avatar
Jingning Han committed
75

76 77 78 79
#if CONFIG_CFL
#include "av1/common/cfl.h"
#endif

80 81 82 83
#if CONFIG_STRIPED_LOOP_RESTORATION && !CONFIG_LOOP_RESTORATION
#error "striped_loop_restoration requires loop_restoration"
#endif

84 85 86 87 88 89 90
#if CONFIG_LOOP_RESTORATION
static void loop_restoration_read_sb_coeffs(const AV1_COMMON *const cm,
                                            MACROBLOCKD *xd,
                                            aom_reader *const r, int plane,
                                            int rtile_idx);
#endif

91 92 93 94 95 96 97 98
static struct aom_read_bit_buffer *init_read_bit_buffer(
    AV1Decoder *pbi, struct aom_read_bit_buffer *rb, const uint8_t *data,
    const uint8_t *data_end, uint8_t clear_data[MAX_AV1_HEADER_SIZE]);
static int read_compressed_header(AV1Decoder *pbi, const uint8_t *data,
                                  size_t partition_size);
static size_t read_uncompressed_header(AV1Decoder *pbi,
                                       struct aom_read_bit_buffer *rb);

99
static int is_compound_reference_allowed(const AV1_COMMON *cm) {
100
#if CONFIG_ONE_SIDED_COMPOUND  // Normative in decoder
101 102
  return !frame_is_intra_only(cm);
#else
Jingning Han's avatar
Jingning Han committed
103
  int i;
104
  if (frame_is_intra_only(cm)) return 0;
105
  for (i = 1; i < INTER_REFS_PER_FRAME; ++i)
106
    if (cm->ref_frame_sign_bias[i + 1] != cm->ref_frame_sign_bias[1]) return 1;
Jingning Han's avatar
Jingning Han committed
107 108

  return 0;
109
#endif  // CONFIG_ONE_SIDED_COMPOUND
Jingning Han's avatar
Jingning Han committed
110 111
}

112
static void setup_compound_reference_mode(AV1_COMMON *cm) {
113
  cm->comp_fwd_ref[0] = LAST_FRAME;
114 115 116 117
  cm->comp_fwd_ref[1] = LAST2_FRAME;
  cm->comp_fwd_ref[2] = LAST3_FRAME;
  cm->comp_fwd_ref[3] = GOLDEN_FRAME;

118
  cm->comp_bwd_ref[0] = BWDREF_FRAME;
Zoe Liu's avatar
Zoe Liu committed
119 120
  cm->comp_bwd_ref[1] = ALTREF2_FRAME;
  cm->comp_bwd_ref[2] = ALTREF_FRAME;
Jingning Han's avatar
Jingning Han committed
121 122 123 124 125 126
}

static int read_is_valid(const uint8_t *start, size_t len, const uint8_t *end) {
  return len != 0 && len <= (size_t)(end - start);
}

127 128
static int decode_unsigned_max(struct aom_read_bit_buffer *rb, int max) {
  const int data = aom_rb_read_literal(rb, get_unsigned_bits(max));
Jingning Han's avatar
Jingning Han committed
129 130 131
  return data > max ? max : data;
}

132
static TX_MODE read_tx_mode(AV1_COMMON *cm, struct aom_read_bit_buffer *rb) {
133
#if CONFIG_TX64X64
134 135
  TX_MODE tx_mode;
#endif
136
  if (cm->all_lossless) return ONLY_4X4;
137 138 139 140
#if CONFIG_VAR_TX_NO_TX_MODE
  (void)rb;
  return TX_MODE_SELECT;
#else
141 142
#if CONFIG_TX64X64
  tx_mode = aom_rb_read_bit(rb) ? TX_MODE_SELECT : aom_rb_read_literal(rb, 2);
143 144 145
  if (tx_mode == ALLOW_32X32) tx_mode += aom_rb_read_bit(rb);
  return tx_mode;
#else
146
  return aom_rb_read_bit(rb) ? TX_MODE_SELECT : aom_rb_read_literal(rb, 2);
147
#endif  // CONFIG_TX64X64
148
#endif  // CONFIG_VAR_TX_NO_TX_MODE
149
}
Jingning Han's avatar
Jingning Han committed
150

Thomas Davies's avatar
Thomas Davies committed
151
#if !CONFIG_NEW_MULTISYMBOL
152
static void read_inter_mode_probs(FRAME_CONTEXT *fc, aom_reader *r) {
153
  int i;
154
  for (i = 0; i < NEWMV_MODE_CONTEXTS; ++i)
Michael Bebenita's avatar
Michael Bebenita committed
155
    av1_diff_update_prob(r, &fc->newmv_prob[i], ACCT_STR);
156
  for (i = 0; i < ZEROMV_MODE_CONTEXTS; ++i)
Michael Bebenita's avatar
Michael Bebenita committed
157
    av1_diff_update_prob(r, &fc->zeromv_prob[i], ACCT_STR);
158
  for (i = 0; i < REFMV_MODE_CONTEXTS; ++i)
Michael Bebenita's avatar
Michael Bebenita committed
159
    av1_diff_update_prob(r, &fc->refmv_prob[i], ACCT_STR);
160
  for (i = 0; i < DRL_MODE_CONTEXTS; ++i)
Michael Bebenita's avatar
Michael Bebenita committed
161
    av1_diff_update_prob(r, &fc->drl_prob[i], ACCT_STR);
Jingning Han's avatar
Jingning Han committed
162
}
163
#endif
Jingning Han's avatar
Jingning Han committed
164

165
static REFERENCE_MODE read_frame_reference_mode(
166
    const AV1_COMMON *cm, struct aom_read_bit_buffer *rb) {
167
  if (is_compound_reference_allowed(cm)) {
Zoe Liu's avatar
Zoe Liu committed
168 169 170
#if CONFIG_REF_ADAPT
    return aom_rb_read_bit(rb) ? REFERENCE_MODE_SELECT : SINGLE_REFERENCE;
#else
171
    return aom_rb_read_bit(rb)
172
               ? REFERENCE_MODE_SELECT
173
               : (aom_rb_read_bit(rb) ? COMPOUND_REFERENCE : SINGLE_REFERENCE);
Zoe Liu's avatar
Zoe Liu committed
174
#endif  // CONFIG_REF_ADAPT
175 176 177 178
  } else {
    return SINGLE_REFERENCE;
  }
}
Jingning Han's avatar
Jingning Han committed
179

Thomas Davies's avatar
Thomas Davies committed
180
#if !CONFIG_NEW_MULTISYMBOL
181
static void read_frame_reference_mode_probs(AV1_COMMON *cm, aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
182
  FRAME_CONTEXT *const fc = cm->fc;
183
  int i;
Jingning Han's avatar
Jingning Han committed
184 185 186

  if (cm->reference_mode == REFERENCE_MODE_SELECT)
    for (i = 0; i < COMP_INTER_CONTEXTS; ++i)
Michael Bebenita's avatar
Michael Bebenita committed
187
      av1_diff_update_prob(r, &fc->comp_inter_prob[i], ACCT_STR);
Jingning Han's avatar
Jingning Han committed
188

189
  if (cm->reference_mode != COMPOUND_REFERENCE) {
Jingning Han's avatar
Jingning Han committed
190
    for (i = 0; i < REF_CONTEXTS; ++i) {
191
      int j;
192
      for (j = 0; j < (SINGLE_REFS - 1); ++j) {
Michael Bebenita's avatar
Michael Bebenita committed
193
        av1_diff_update_prob(r, &fc->single_ref_prob[i][j], ACCT_STR);
194
      }
Jingning Han's avatar
Jingning Han committed
195
    }
196
  }
Jingning Han's avatar
Jingning Han committed
197

198
  if (cm->reference_mode != SINGLE_REFERENCE) {
199 200 201 202
#if CONFIG_EXT_COMP_REFS
    for (i = 0; i < COMP_REF_TYPE_CONTEXTS; ++i)
      av1_diff_update_prob(r, &fc->comp_ref_type_prob[i], ACCT_STR);

203 204
    for (i = 0; i < UNI_COMP_REF_CONTEXTS; ++i) {
      int j;
205 206
      for (j = 0; j < (UNIDIR_COMP_REFS - 1); ++j)
        av1_diff_update_prob(r, &fc->uni_comp_ref_prob[i][j], ACCT_STR);
207
    }
208 209
#endif  // CONFIG_EXT_COMP_REFS

210
    for (i = 0; i < REF_CONTEXTS; ++i) {
211
      int j;
212
      for (j = 0; j < (FWD_REFS - 1); ++j)
Michael Bebenita's avatar
Michael Bebenita committed
213
        av1_diff_update_prob(r, &fc->comp_ref_prob[i][j], ACCT_STR);
214
      for (j = 0; j < (BWD_REFS - 1); ++j)
Michael Bebenita's avatar
Michael Bebenita committed
215
        av1_diff_update_prob(r, &fc->comp_bwdref_prob[i][j], ACCT_STR);
216 217
    }
  }
Jingning Han's avatar
Jingning Han committed
218 219
}

220
static void update_mv_probs(aom_prob *p, int n, aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
221
  int i;
Michael Bebenita's avatar
Michael Bebenita committed
222
  for (i = 0; i < n; ++i) av1_diff_update_prob(r, &p[i], ACCT_STR);
Jingning Han's avatar
Jingning Han committed
223 224
}

225
static void read_mv_probs(nmv_context *ctx, int allow_hp, aom_reader *r) {
226
  int i;
Jingning Han's avatar
Jingning Han committed
227 228 229 230 231 232 233 234
  if (allow_hp) {
    for (i = 0; i < 2; ++i) {
      nmv_component *const comp_ctx = &ctx->comps[i];
      update_mv_probs(&comp_ctx->class0_hp, 1, r);
      update_mv_probs(&comp_ctx->hp, 1, r);
    }
  }
}
235
#endif
Jingning Han's avatar
Jingning Han committed
236

237
static void inverse_transform_block(MACROBLOCKD *xd, int plane,
238
#if CONFIG_LGT_FROM_PRED
Lester Lu's avatar
Lester Lu committed
239 240
                                    PREDICTION_MODE mode,
#endif
241
                                    const TX_TYPE tx_type,
242
                                    const TX_SIZE tx_size, uint8_t *dst,
243
                                    int stride, int16_t scan_line, int eob) {
Jingning Han's avatar
Jingning Han committed
244
  struct macroblockd_plane *const pd = &xd->plane[plane];
245
  tran_low_t *const dqcoeff = pd->dqcoeff;
Lester Lu's avatar
Lester Lu committed
246
  av1_inverse_transform_block(xd, dqcoeff,
247
#if CONFIG_LGT_FROM_PRED
Lester Lu's avatar
Lester Lu committed
248 249
                              mode,
#endif
Sarah Parker's avatar
Sarah Parker committed
250 251 252
#if CONFIG_MRC_TX && SIGNAL_ANY_MRC_MASK
                              xd->mrc_mask,
#endif  // CONFIG_MRC_TX && SIGNAL_ANY_MRC_MASK
Lester Lu's avatar
Lester Lu committed
253
                              tx_type, tx_size, dst, stride, eob);
254
  memset(dqcoeff, 0, (scan_line + 1) * sizeof(dqcoeff[0]));
Jingning Han's avatar
Jingning Han committed
255 256
}

257 258 259 260 261 262 263
static int get_block_idx(const MACROBLOCKD *xd, int plane, int row, int col) {
  const int bsize = xd->mi[0]->mbmi.sb_type;
  const struct macroblockd_plane *pd = &xd->plane[plane];
#if CONFIG_CHROMA_SUB8X8
  const BLOCK_SIZE plane_bsize =
      AOMMAX(BLOCK_4X4, get_plane_block_size(bsize, pd));
#else
264 265
  const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
#endif  // CONFIG_CHROMA_SUB8X8
266
  const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
267
  const TX_SIZE tx_size = av1_get_tx_size(plane, xd);
268 269 270 271
  const uint8_t txh_unit = tx_size_high_unit[tx_size];
  return row * max_blocks_wide + col * txh_unit;
}

272 273 274
static void predict_and_reconstruct_intra_block(
    AV1_COMMON *cm, MACROBLOCKD *const xd, aom_reader *const r,
    MB_MODE_INFO *const mbmi, int plane, int row, int col, TX_SIZE tx_size) {
275
  PLANE_TYPE plane_type = get_plane_type(plane);
276
  const int block_idx = get_block_idx(xd, plane, row, col);
277
  av1_predict_intra_block_facade(cm, xd, plane, block_idx, col, row, tx_size);
Jingning Han's avatar
Jingning Han committed
278 279

  if (!mbmi->skip) {
280
    struct macroblockd_plane *const pd = &xd->plane[plane];
281 282
#if CONFIG_LV_MAP
    int16_t max_scan_line = 0;
283 284
    int eob;
    av1_read_coeffs_txb_facade(cm, xd, r, row, col, block_idx, plane,
285
                               pd->dqcoeff, tx_size, &max_scan_line, &eob);
286
    // tx_type will be read out in av1_read_coeffs_txb_facade
287 288
    const TX_TYPE tx_type =
        av1_get_tx_type(plane_type, xd, row, col, block_idx, tx_size);
289
#else   // CONFIG_LV_MAP
290 291
    const TX_TYPE tx_type =
        av1_get_tx_type(plane_type, xd, row, col, block_idx, tx_size);
Angie Chiang's avatar
Angie Chiang committed
292
    const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, mbmi);
293 294
    int16_t max_scan_line = 0;
    const int eob =
295
        av1_decode_block_tokens(cm, xd, plane, scan_order, col, row, tx_size,
296
                                tx_type, &max_scan_line, r, mbmi->segment_id);
297
#endif  // CONFIG_LV_MAP
298 299 300
    if (eob) {
      uint8_t *dst =
          &pd->dst.buf[(row * pd->dst.stride + col) << tx_size_wide_log2[0]];
Hui Su's avatar
Hui Su committed
301
      inverse_transform_block(xd, plane,
302
#if CONFIG_LGT_FROM_PRED
Lester Lu's avatar
Lester Lu committed
303
                              mbmi->mode,
Lester Lu's avatar
Lester Lu committed
304
#endif
Hui Su's avatar
Hui Su committed
305 306
                              tx_type, tx_size, dst, pd->dst.stride,
                              max_scan_line, eob);
307
    }
Jingning Han's avatar
Jingning Han committed
308
  }
309
#if CONFIG_CFL
310
  if (plane == AOM_PLANE_Y && xd->cfl->store_y) {
311
    cfl_store_tx(xd, row, col, tx_size, mbmi->sb_type);
312
  }
Sebastien Alaiwan's avatar
Sebastien Alaiwan committed
313
#endif  // CONFIG_CFL
Jingning Han's avatar
Jingning Han committed
314 315
}

316
#if !CONFIG_COEF_INTERLEAVE
Angie Chiang's avatar
Angie Chiang committed
317 318
static void decode_reconstruct_tx(AV1_COMMON *cm, MACROBLOCKD *const xd,
                                  aom_reader *r, MB_MODE_INFO *const mbmi,
319
                                  int plane, BLOCK_SIZE plane_bsize,
320 321
                                  int blk_row, int blk_col, int block,
                                  TX_SIZE tx_size, int *eob_total) {
322
  const struct macroblockd_plane *const pd = &xd->plane[plane];
323
  const BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
324 325
  const int tx_row = blk_row >> (1 - pd->subsampling_y);
  const int tx_col = blk_col >> (1 - pd->subsampling_x);
326
  const TX_SIZE plane_tx_size =
327
      plane ? uv_txsize_lookup[bsize][mbmi->inter_tx_size[tx_row][tx_col]][0][0]
328
            : mbmi->inter_tx_size[tx_row][tx_col];
329
  // Scale to match transform block unit.
330 331
  const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
  const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
332

333
  if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
334

335
  if (tx_size == plane_tx_size) {
336
    PLANE_TYPE plane_type = get_plane_type(plane);
337 338
#if CONFIG_LV_MAP
    int16_t max_scan_line = 0;
339
    int eob;
340
    av1_read_coeffs_txb_facade(cm, xd, r, blk_row, blk_col, block, plane,
341
                               pd->dqcoeff, tx_size, &max_scan_line, &eob);
342
    // tx_type will be read out in av1_read_coeffs_txb_facade
hui su's avatar
hui su committed
343
    const TX_TYPE tx_type =
344
        av1_get_tx_type(plane_type, xd, blk_row, blk_col, block, plane_tx_size);
345
#else   // CONFIG_LV_MAP
hui su's avatar
hui su committed
346
    const TX_TYPE tx_type =
347
        av1_get_tx_type(plane_type, xd, blk_row, blk_col, block, plane_tx_size);
Angie Chiang's avatar
Angie Chiang committed
348
    const SCAN_ORDER *sc = get_scan(cm, plane_tx_size, tx_type, mbmi);
349
    int16_t max_scan_line = 0;
350 351 352
    const int eob = av1_decode_block_tokens(
        cm, xd, plane, sc, blk_col, blk_row, plane_tx_size, tx_type,
        &max_scan_line, r, mbmi->segment_id);
353
#endif  // CONFIG_LV_MAP
Lester Lu's avatar
Lester Lu committed
354
    inverse_transform_block(xd, plane,
355
#if CONFIG_LGT_FROM_PRED
Lester Lu's avatar
Lester Lu committed
356 357 358
                            mbmi->mode,
#endif
                            tx_type, plane_tx_size,
359 360 361
                            &pd->dst.buf[(blk_row * pd->dst.stride + blk_col)
                                         << tx_size_wide_log2[0]],
                            pd->dst.stride, max_scan_line, eob);
362 363
    *eob_total += eob;
  } else {
Yue Chen's avatar
Yue Chen committed
364 365 366 367 368
#if CONFIG_RECT_TX_EXT
    int is_qttx = plane_tx_size == quarter_txsize_lookup[plane_bsize];
    const TX_SIZE sub_txs = is_qttx ? plane_tx_size : sub_tx_size_map[tx_size];
    if (is_qttx) assert(blk_row == 0 && blk_col == 0 && block == 0);
#else
369
    const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
370 371
    assert(IMPLIES(tx_size <= TX_4X4, sub_txs == tx_size));
    assert(IMPLIES(tx_size > TX_4X4, sub_txs < tx_size));
Yue Chen's avatar
Yue Chen committed
372
#endif
373
    const int bsl = tx_size_wide_unit[sub_txs];
374
    int sub_step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
375 376 377 378 379
    int i;

    assert(bsl > 0);

    for (i = 0; i < 4; ++i) {
Yue Chen's avatar
Yue Chen committed
380 381 382 383 384 385 386 387 388
#if CONFIG_RECT_TX_EXT
      int is_wide_tx = tx_size_wide_unit[sub_txs] > tx_size_high_unit[sub_txs];
      const int offsetr =
          is_qttx ? (is_wide_tx ? i * tx_size_high_unit[sub_txs] : 0)
                  : blk_row + ((i >> 1) * bsl);
      const int offsetc =
          is_qttx ? (is_wide_tx ? 0 : i * tx_size_wide_unit[sub_txs])
                  : blk_col + (i & 0x01) * bsl;
#else
389 390
      const int offsetr = blk_row + (i >> 1) * bsl;
      const int offsetc = blk_col + (i & 0x01) * bsl;
Yue Chen's avatar
Yue Chen committed
391
#endif
392

393
      if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
394

395
      decode_reconstruct_tx(cm, xd, r, mbmi, plane, plane_bsize, offsetr,
396 397
                            offsetc, block, sub_txs, eob_total);
      block += sub_step;
398 399 400
    }
  }
}
401
#endif
402

403
#if CONFIG_COEF_INTERLEAVE || (!CONFIG_EXT_TX && CONFIG_RECT_TX)
Angie Chiang's avatar
Angie Chiang committed
404
static int reconstruct_inter_block(AV1_COMMON *cm, MACROBLOCKD *const xd,
405 406
                                   aom_reader *const r, int segment_id,
                                   int plane, int row, int col,
407
                                   TX_SIZE tx_size) {
408
  PLANE_TYPE plane_type = get_plane_type(plane);
409
  int block_idx = get_block_idx(xd, plane, row, col);
410
  struct macroblockd_plane *const pd = &xd->plane[plane];
411

412 413
#if CONFIG_LV_MAP
  (void)segment_id;
414
  int16_t max_scan_line = 0;
415 416
  int eob;
  av1_read_coeffs_txb_facade(cm, xd, r, row, col, block_idx, plane, pd->dqcoeff,
Angie Chiang's avatar
Angie Chiang committed
417
                             tx_size, &max_scan_line, &eob);
418
  // tx_type will be read out in av1_read_coeffs_txb_facade
419 420
  const TX_TYPE tx_type =
      av1_get_tx_type(plane_type, xd, row, col, block_idx, tx_size);
421 422
#else   // CONFIG_LV_MAP
  int16_t max_scan_line = 0;
423 424
  const TX_TYPE tx_type =
      av1_get_tx_type(plane_type, xd, row, col, block_idx, tx_size);
Angie Chiang's avatar
Angie Chiang committed
425 426
  const SCAN_ORDER *scan_order =
      get_scan(cm, tx_size, tx_type, &xd->mi[0]->mbmi);
427
  const int eob =
428 429
      av1_decode_block_tokens(cm, xd, plane, scan_order, col, row, tx_size,
                              tx_type, &max_scan_line, r, segment_id);
430
#endif  // CONFIG_LV_MAP
431 432
  uint8_t *dst =
      &pd->dst.buf[(row * pd->dst.stride + col) << tx_size_wide_log2[0]];
433
  if (eob)
Lester Lu's avatar
Lester Lu committed
434
    inverse_transform_block(xd, plane,
435
#if CONFIG_LGT_FROM_PRED
Lester Lu's avatar
Lester Lu committed
436 437 438
                            xd->mi[0]->mbmi.mode,
#endif
                            tx_type, tx_size, dst, pd->dst.stride,
439
                            max_scan_line, eob);
Yushin Cho's avatar
Yushin Cho committed
440

Jingning Han's avatar
Jingning Han committed
441 442
  return eob;
}
443
#endif  // CONFIG_SUPER_TX
Jingning Han's avatar
Jingning Han committed
444

445 446 447
static void set_offsets(AV1_COMMON *const cm, MACROBLOCKD *const xd,
                        BLOCK_SIZE bsize, int mi_row, int mi_col, int bw,
                        int bh, int x_mis, int y_mis) {
Jingning Han's avatar
Jingning Han committed
448 449 450 451 452 453 454 455 456
  const int offset = mi_row * cm->mi_stride + mi_col;
  int x, y;
  const TileInfo *const tile = &xd->tile;

  xd->mi = cm->mi_grid_visible + offset;
  xd->mi[0] = &cm->mi[offset];
  // TODO(slavarnway): Generate sb_type based on bwl and bhl, instead of
  // passing bsize from decode_partition().
  xd->mi[0]->mbmi.sb_type = bsize;
457 458 459
#if CONFIG_RD_DEBUG
  xd->mi[0]->mbmi.mi_row = mi_row;
  xd->mi[0]->mbmi.mi_col = mi_col;
460 461 462 463
#endif
#if CONFIG_CFL
  xd->cfl->mi_row = mi_row;
  xd->cfl->mi_col = mi_col;
464
#endif
Jingning Han's avatar
Jingning Han committed
465
  for (y = 0; y < y_mis; ++y)
Jingning Han's avatar
Jingning Han committed
466
    for (x = !y; x < x_mis; ++x) xd->mi[y * cm->mi_stride + x] = xd->mi[0];
Jingning Han's avatar
Jingning Han committed
467

Jingning Han's avatar
Jingning Han committed
468
  set_plane_n4(xd, bw, bh);
Jingning Han's avatar
Jingning Han committed
469 470
  set_skip_context(xd, mi_row, mi_col);

471 472 473
  // Distance of Mb to the various image edges. These are specified to 8th pel
  // as they are always compared to values that are in 1/8th pel units
  set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw,
474
#if CONFIG_DEPENDENT_HORZTILES
475 476 477
                 cm->dependent_horz_tiles,
#endif  // CONFIG_DEPENDENT_HORZTILES
                 cm->mi_rows, cm->mi_cols);
Jingning Han's avatar
Jingning Han committed
478

479 480
  av1_setup_dst_planes(xd->plane, bsize, get_frame_new_buffer(cm), mi_row,
                       mi_col);
Jingning Han's avatar
Jingning Han committed
481 482
}

483 484
static void decode_mbmi_block(AV1Decoder *const pbi, MACROBLOCKD *const xd,
                              int mi_row, int mi_col, aom_reader *r,
485
#if CONFIG_EXT_PARTITION_TYPES
486
                              PARTITION_TYPE partition,
487
#endif  // CONFIG_EXT_PARTITION_TYPES
488
                              BLOCK_SIZE bsize) {
489
  AV1_COMMON *const cm = &pbi->common;
490 491
  const int bw = mi_size_wide[bsize];
  const int bh = mi_size_high[bsize];
492 493
  const int x_mis = AOMMIN(bw, cm->mi_cols - mi_col);
  const int y_mis = AOMMIN(bh, cm->mi_rows - mi_row);
494

Michael Bebenita's avatar
Michael Bebenita committed
495 496 497
#if CONFIG_ACCOUNTING
  aom_accounting_set_context(&pbi->accounting, mi_col, mi_row);
#endif
498
  set_offsets(cm, xd, bsize, mi_row, mi_col, bw, bh, x_mis, y_mis);
499 500 501
#if CONFIG_EXT_PARTITION_TYPES
  xd->mi[0]->mbmi.partition = partition;
#endif
502
  av1_read_mode_info(pbi, xd, mi_row, mi_col, r, x_mis, y_mis);
Jingning Han's avatar
Jingning Han committed
503 504 505 506
  if (bsize >= BLOCK_8X8 && (cm->subsampling_x || cm->subsampling_y)) {
    const BLOCK_SIZE uv_subsize =
        ss_size_lookup[bsize][cm->subsampling_x][cm->subsampling_y];
    if (uv_subsize == BLOCK_INVALID)
507
      aom_internal_error(xd->error_info, AOM_CODEC_CORRUPT_FRAME,
508
                         "Invalid block size.");
Jingning Han's avatar
Jingning Han committed
509 510
  }

511 512
  int reader_corrupted_flag = aom_reader_has_error(r);
  aom_merge_corrupted_flag(&xd->corrupted, reader_corrupted_flag);
513 514
}

515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534
#if CONFIG_NCOBMC_ADAPT_WEIGHT
static void set_mode_info_offsets(AV1_COMMON *const cm, MACROBLOCKD *const xd,
                                  int mi_row, int mi_col) {
  const int offset = mi_row * cm->mi_stride + mi_col;
  xd->mi = cm->mi_grid_visible + offset;
  xd->mi[0] = &cm->mi[offset];
}

static void get_ncobmc_recon(AV1_COMMON *const cm, MACROBLOCKD *xd, int mi_row,
                             int mi_col, int bsize, int mode) {
  uint8_t *pred_buf[4][MAX_MB_PLANE];
  int pred_stride[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
  // target block in pxl
  int pxl_row = mi_row << MI_SIZE_LOG2;
  int pxl_col = mi_col << MI_SIZE_LOG2;

  int plane;
#if CONFIG_HIGHBITDEPTH
  if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
    int len = sizeof(uint16_t);
535 536 537 538 539 540 541 542
    ASSIGN_ALIGNED_PTRS_HBD(pred_buf[0], cm->ncobmcaw_buf[0], MAX_SB_SQUARE,
                            len);
    ASSIGN_ALIGNED_PTRS_HBD(pred_buf[1], cm->ncobmcaw_buf[1], MAX_SB_SQUARE,
                            len);
    ASSIGN_ALIGNED_PTRS_HBD(pred_buf[2], cm->ncobmcaw_buf[2], MAX_SB_SQUARE,
                            len);
    ASSIGN_ALIGNED_PTRS_HBD(pred_buf[3], cm->ncobmcaw_buf[3], MAX_SB_SQUARE,
                            len);
543 544
  } else {
#endif  // CONFIG_HIGHBITDEPTH
545 546 547 548
    ASSIGN_ALIGNED_PTRS(pred_buf[0], cm->ncobmcaw_buf[0], MAX_SB_SQUARE);
    ASSIGN_ALIGNED_PTRS(pred_buf[1], cm->ncobmcaw_buf[1], MAX_SB_SQUARE);
    ASSIGN_ALIGNED_PTRS(pred_buf[2], cm->ncobmcaw_buf[2], MAX_SB_SQUARE);
    ASSIGN_ALIGNED_PTRS(pred_buf[3], cm->ncobmcaw_buf[3], MAX_SB_SQUARE);
549 550 551 552 553 554 555 556 557 558 559 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 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602
#if CONFIG_HIGHBITDEPTH
  }
#endif
  av1_get_ext_blk_preds(cm, xd, bsize, mi_row, mi_col, pred_buf, pred_stride);
  av1_get_ori_blk_pred(cm, xd, bsize, mi_row, mi_col, pred_buf[3], pred_stride);
  for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
    build_ncobmc_intrpl_pred(cm, xd, plane, pxl_row, pxl_col, bsize, pred_buf,
                             pred_stride, mode);
  }
}

static void av1_get_ncobmc_recon(AV1_COMMON *const cm, MACROBLOCKD *const xd,
                                 int bsize, const int mi_row, const int mi_col,
                                 const NCOBMC_MODE modes) {
  const int mi_width = mi_size_wide[bsize];
  const int mi_height = mi_size_high[bsize];

  assert(bsize >= BLOCK_8X8);

  reset_xd_boundary(xd, mi_row, mi_height, mi_col, mi_width, cm->mi_rows,
                    cm->mi_cols);
  get_ncobmc_recon(cm, xd, mi_row, mi_col, bsize, modes);
}

static void recon_ncobmc_intrpl_pred(AV1_COMMON *const cm,
                                     MACROBLOCKD *const xd, int mi_row,
                                     int mi_col, BLOCK_SIZE bsize) {
  MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
  const int mi_width = mi_size_wide[bsize];
  const int mi_height = mi_size_high[bsize];
  const int hbs = AOMMAX(mi_size_wide[bsize] / 2, mi_size_high[bsize] / 2);
  const BLOCK_SIZE sqr_blk = bsize_2_sqr_bsize[bsize];
  if (mi_width > mi_height) {
    // horizontal partition
    av1_get_ncobmc_recon(cm, xd, sqr_blk, mi_row, mi_col, mbmi->ncobmc_mode[0]);
    xd->mi += hbs;
    av1_get_ncobmc_recon(cm, xd, sqr_blk, mi_row, mi_col + hbs,
                         mbmi->ncobmc_mode[1]);
  } else if (mi_height > mi_width) {
    // vertical partition
    av1_get_ncobmc_recon(cm, xd, sqr_blk, mi_row, mi_col, mbmi->ncobmc_mode[0]);
    xd->mi += hbs * xd->mi_stride;
    av1_get_ncobmc_recon(cm, xd, sqr_blk, mi_row + hbs, mi_col,
                         mbmi->ncobmc_mode[1]);
  } else {
    av1_get_ncobmc_recon(cm, xd, sqr_blk, mi_row, mi_col, mbmi->ncobmc_mode[0]);
  }
  set_mode_info_offsets(cm, xd, mi_row, mi_col);
  // restore dst buffer and mode info
  av1_setup_dst_planes(xd->plane, bsize, get_frame_new_buffer(cm), mi_row,
                       mi_col);
}
#endif  // CONFIG_NCOBMC_ADAPT_WEIGHT

603 604 605 606 607 608 609 610 611 612
static void decode_token_and_recon_block(AV1Decoder *const pbi,
                                         MACROBLOCKD *const xd, int mi_row,
                                         int mi_col, aom_reader *r,
                                         BLOCK_SIZE bsize) {
  AV1_COMMON *const cm = &pbi->common;
  const int bw = mi_size_wide[bsize];
  const int bh = mi_size_high[bsize];
  const int x_mis = AOMMIN(bw, cm->mi_cols - mi_col);
  const int y_mis = AOMMIN(bh, cm->mi_rows - mi_row);

613 614
  set_offsets(cm, xd, bsize, mi_row, mi_col, bw, bh, x_mis, y_mis);
  MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
615 616 617 618 619
#if CONFIG_CFL && CONFIG_CHROMA_SUB8X8
  CFL_CTX *const cfl = xd->cfl;
  cfl->is_chroma_reference = is_chroma_reference(
      mi_row, mi_col, bsize, cfl->subsampling_x, cfl->subsampling_y);
#endif  // CONFIG_CFL && CONFIG_CHROMA_SUB8X8
620

621 622 623
  if (cm->delta_q_present_flag) {
    int i;
    for (i = 0; i < MAX_SEGMENTS; i++) {
Fangwen Fu's avatar
Fangwen Fu committed
624
#if CONFIG_EXT_DELTA_Q
625 626
      const int current_qindex =
          av1_get_qindex(&cm->seg, i, xd->current_qindex);
Fangwen Fu's avatar
Fangwen Fu committed
627
#else
628 629 630 631 632 633 634 635 636 637 638 639
      const int current_qindex = xd->current_qindex;
#endif  // CONFIG_EXT_DELTA_Q
      int j;
      for (j = 0; j < MAX_MB_PLANE; ++j) {
        const int dc_delta_q = j == 0 ? cm->y_dc_delta_q : cm->uv_dc_delta_q;
        const int ac_delta_q = j == 0 ? 0 : cm->uv_ac_delta_q;

        xd->plane[j].seg_dequant[i][0] =
            av1_dc_quant(current_qindex, dc_delta_q, cm->bit_depth);
        xd->plane[j].seg_dequant[i][1] =
            av1_ac_quant(current_qindex, ac_delta_q, cm->bit_depth);
      }
640 641
    }
  }
642
  if (mbmi->skip) av1_reset_skip_context(xd, mi_row, mi_col, bsize);
643

644 645 646 647 648
#if CONFIG_COEF_INTERLEAVE
  {
    const struct macroblockd_plane *const pd_y = &xd->plane[0];
    const struct macroblockd_plane *const pd_c = &xd->plane[1];
    const TX_SIZE tx_log2_y = mbmi->tx_size;
649
    const TX_SIZE tx_log2_c = av1_get_uv_tx_size(mbmi, pd_c);
650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712
    const int tx_sz_y = (1 << tx_log2_y);
    const int tx_sz_c = (1 << tx_log2_c);
    const int num_4x4_w_y = pd_y->n4_w;
    const int num_4x4_h_y = pd_y->n4_h;
    const int num_4x4_w_c = pd_c->n4_w;
    const int num_4x4_h_c = pd_c->n4_h;
    const int max_4x4_w_y = get_max_4x4_size(num_4x4_w_y, xd->mb_to_right_edge,
                                             pd_y->subsampling_x);
    const int max_4x4_h_y = get_max_4x4_size(num_4x4_h_y, xd->mb_to_bottom_edge,
                                             pd_y->subsampling_y);
    const int max_4x4_w_c = get_max_4x4_size(num_4x4_w_c, xd->mb_to_right_edge,
                                             pd_c->subsampling_x);
    const int max_4x4_h_c = get_max_4x4_size(num_4x4_h_c, xd->mb_to_bottom_edge,
                                             pd_c->subsampling_y);

    // The max_4x4_w/h may be smaller than tx_sz under some corner cases,
    // i.e. when the SB is splitted by tile boundaries.
    const int tu_num_w_y = (max_4x4_w_y + tx_sz_y - 1) / tx_sz_y;
    const int tu_num_h_y = (max_4x4_h_y + tx_sz_y - 1) / tx_sz_y;
    const int tu_num_w_c = (max_4x4_w_c + tx_sz_c - 1) / tx_sz_c;
    const int tu_num_h_c = (max_4x4_h_c + tx_sz_c - 1) / tx_sz_c;
    const int tu_num_c = tu_num_w_c * tu_num_h_c;

    if (!is_inter_block(mbmi)) {
      int tu_idx_c = 0;
      int row_y, col_y, row_c, col_c;
      int plane;

      for (plane = 0; plane <= 1; ++plane) {
        if (mbmi->palette_mode_info.palette_size[plane])
          av1_decode_palette_tokens(xd, plane, r);
      }

      for (row_y = 0; row_y < tu_num_h_y; row_y++) {
        for (col_y = 0; col_y < tu_num_w_y; col_y++) {
          // luma
          predict_and_reconstruct_intra_block(
              cm, xd, r, mbmi, 0, row_y * tx_sz_y, col_y * tx_sz_y, tx_log2_y);
          // chroma
          if (tu_idx_c < tu_num_c) {
            row_c = (tu_idx_c / tu_num_w_c) * tx_sz_c;
            col_c = (tu_idx_c % tu_num_w_c) * tx_sz_c;
            predict_and_reconstruct_intra_block(cm, xd, r, mbmi, 1, row_c,
                                                col_c, tx_log2_c);
            predict_and_reconstruct_intra_block(cm, xd, r, mbmi, 2, row_c,
                                                col_c, tx_log2_c);
            tu_idx_c++;
          }
        }
      }

      // In 422 case, it's possilbe that Chroma has more TUs than Luma
      while (tu_idx_c < tu_num_c) {
        row_c = (tu_idx_c / tu_num_w_c) * tx_sz_c;
        col_c = (tu_idx_c % tu_num_w_c) * tx_sz_c;
        predict_and_reconstruct_intra_block(cm, xd, r, mbmi, 1, row_c, col_c,
                                            tx_log2_c);
        predict_and_reconstruct_intra_block(cm, xd, r, mbmi, 2, row_c, col_c,
                                            tx_log2_c);
        tu_idx_c++;
      }
    } else {
      // Prediction
713
      av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL,
714 715 716 717 718 719 720 721 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
                                    AOMMAX(bsize, BLOCK_8X8));

      // Reconstruction
      if (!mbmi->skip) {
        int eobtotal = 0;
        int tu_idx_c = 0;
        int row_y, col_y, row_c, col_c;

        for (row_y = 0; row_y < tu_num_h_y; row_y++) {
          for (col_y = 0; col_y < tu_num_w_y; col_y++) {
            // luma
            eobtotal += reconstruct_inter_block(cm, xd, r, mbmi->segment_id, 0,
                                                row_y * tx_sz_y,
                                                col_y * tx_sz_y, tx_log2_y);
            // chroma
            if (tu_idx_c < tu_num_c) {
              row_c = (tu_idx_c / tu_num_w_c) * tx_sz_c;
              col_c = (tu_idx_c % tu_num_w_c) * tx_sz_c;
              eobtotal += reconstruct_inter_block(cm, xd, r, mbmi->segment_id,
                                                  1, row_c, col_c, tx_log2_c);
              eobtotal += reconstruct_inter_block(cm, xd, r, mbmi->segment_id,
                                                  2, row_c, col_c, tx_log2_c);
              tu_idx_c++;
            }
          }
        }

        // In 422 case, it's possilbe that Chroma has more TUs than Luma
        while (tu_idx_c < tu_num_c) {
          row_c = (tu_idx_c / tu_num_w_c) * tx_sz_c;
          col_c = (tu_idx_c % tu_num_w_c) * tx_sz_c;
          eobtotal += reconstruct_inter_block(cm, xd, r, mbmi->segment_id, 1,
                                              row_c, col_c, tx_log2_c);
          eobtotal += reconstruct_inter_block(cm, xd, r, mbmi->segment_id, 2,
                                              row_c, col_c, tx_log2_c);
          tu_idx_c++;
        }

752 753 754
        // TODO(CONFIG_COEF_INTERLEAVE owners): bring eob == 0 corner case
        // into line with the defaut configuration
        if (bsize >= BLOCK_8X8 && eobtotal == 0) mbmi->skip = 1;
755 756 757
      }
    }
  }
758
#else  // CONFIG_COEF_INTERLEAVE
759 760
  if (!is_inter_block(mbmi)) {
    int plane;
761

762 763
    for (plane = 0; plane <= 1; ++plane) {
      if (mbmi->palette_mode_info.palette_size[plane])
764
        av1_decode_palette_tokens(xd, plane, r);
Jingning Han's avatar
Jingning Han committed
765
    }
766

767 768
    for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
      const struct macroblockd_plane *const pd = &xd->plane[plane];
769
      const TX_SIZE tx_size = av1_get_tx_size(plane, xd);
770 771
      const int stepr = tx_size_high_unit[tx_size];
      const int stepc = tx_size_wide_unit[tx_size];
772
#if CONFIG_CHROMA_SUB8X8
773 774
      const BLOCK_SIZE plane_bsize =
          AOMMAX(BLOCK_4X4, get_plane_block_size(bsize, pd));
775
#else
776 777
      const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
#endif  // CONFIG_CHROMA_SUB8X8
778
      int row, col;
779 780
      const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
      const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
781 782
      if (!is_chroma_reference(mi_row, mi_col, bsize, pd->subsampling_x,
                               pd->subsampling_y))
783
        continue;
784 785 786 787 788 789 790 791 792 793
      int blk_row, blk_col;
      const BLOCK_SIZE max_unit_bsize = get_plane_block_size(BLOCK_64X64, pd);
      int mu_blocks_wide =
          block_size_wide[max_unit_bsize] >> tx_size_wide_log2[0];
      int mu_blocks_high =
          block_size_high[max_unit_bsize] >> tx_size_high_log2[0];
      mu_blocks_wide = AOMMIN(max_blocks_wide, mu_blocks_wide);
      mu_blocks_high = AOMMIN(max_blocks_high, mu_blocks_high);

      for (row = 0; row < max_blocks_high; row += mu_blocks_high) {
794
        const int unit_height = AOMMIN(mu_blocks_high + row, max_blocks_high);
795 796 797 798 799 800 801 802 803
        for (col = 0; col < max_blocks_wide; col += mu_blocks_wide) {
          const int unit_width = AOMMIN(mu_blocks_wide + col, max_blocks_wide);

          for (blk_row = row; blk_row < unit_height; blk_row += stepr)
            for (blk_col = col; blk_col < unit_width; blk_col += stepc)
              predict_and_reconstruct_intra_block(cm, xd, r, mbmi, plane,
                                                  blk_row, blk_col, tx_size);
        }
      }
804 805
    }
  } else {
806 807
    int ref;

808
#if CONFIG_COMPOUND_SINGLEREF
809 810 811
    for (ref = 0; ref < 1 + is_inter_anyref_comp_mode(mbmi->mode); ++ref)
#else
    for (ref = 0; ref < 1 + has_second_ref(mbmi); ++ref)
812
#endif  // CONFIG_COMPOUND_SINGLEREF
813
    {
814
      const MV_REFERENCE_FRAME frame =
815
#if CONFIG_COMPOUND_SINGLEREF
816 817
          has_second_ref(mbmi) ? mbmi->ref_frame[ref] : mbmi->ref_frame[0];
#else
818
          mbmi->ref_frame[ref];
819
#endif  // CONFIG_COMPOUND_SINGLEREF
820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837
      if (frame < LAST_FRAME) {
#if CONFIG_INTRABC
        assert(is_intrabc_block(mbmi));
        assert(frame == INTRA_FRAME);
        assert(ref == 0);
#else
        assert(0);
#endif  // CONFIG_INTRABC
      } else {
        RefBuffer *ref_buf = &cm->frame_refs[frame - LAST_FRAME];

        xd->block_refs[ref] = ref_buf;
        if ((!av1_is_valid_scale(&ref_buf->sf)))
          aom_internal_error(xd->error_info, AOM_CODEC_UNSUP_BITSTREAM,
                             "Reference frame has invalid dimensions");
        av1_setup_pre_planes(xd, ref, ref_buf->buf, mi_row, mi_col,
                             &ref_buf->sf);
      }
838
    }
839

840
    av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize);
841

Yue Chen's avatar
Yue Chen committed
842 843
#if CONFIG_MOTION_VAR
    if (mbmi->motion_mode == OBMC_CAUSAL) {
Yue Chen's avatar
Yue Chen committed
844 845 846
#if CONFIG_NCOBMC
      av1_build_ncobmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
#else
847
      av1_build_obmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
Yue Chen's avatar
Yue Chen committed
848
#endif
849
    }
Yue Chen's avatar
Yue Chen committed
850
#endif  // CONFIG_MOTION_VAR
851 852 853 854 855 856 857 858 859
#if CONFIG_NCOBMC_ADAPT_WEIGHT
    if (mbmi->motion_mode == NCOBMC_ADAPT_WEIGHT) {
      int plane;
      recon_ncobmc_intrpl_pred(cm, xd, mi_row, mi_col, bsize);
      for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
        get_pred_from_intrpl_buf(xd, mi_row, mi_col, bsize, plane);
      }
    }
#endif
860 861 862 863 864
    // Reconstruction
    if (!mbmi->skip) {
      int eobtotal = 0;
      int plane;

Jingning Han's avatar
Jingning Han committed
865 866
      for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
        const struct macroblockd_plane *const pd = &xd->plane[plane];
867
#if CONFIG_CHROMA_SUB8X8
868 869
        const BLOCK_SIZE plane_bsize =
            AOMMAX(BLOCK_4X4, get_plane_block_size(bsize, pd));
870
#else
871 872
        const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
#endif  // CONFIG_CHROMA_SUB8X8
873 874
        const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
        const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
875
        int row, col;
876

877 878
        if (!is_chroma_reference(mi_row, mi_col, bsize, pd->subsampling_x,
                                 pd->subsampling_y))
879 880
          continue;

881 882 883 884 885 886 887 888 889
        const BLOCK_SIZE max_unit_bsize = get_plane_block_size(BLOCK_64X64, pd);
        int mu_blocks_wide =
            block_size_wide[max_unit_bsize] >> tx_size_wide_log2[0];
        int mu_blocks_high =
            block_size_high[max_unit_bsize] >> tx_size_high_log2[0];

        mu_blocks_wide = AOMMIN(max_blocks_wide, mu_blocks_wide);
        mu_blocks_high = AOMMIN(max_blocks_high, mu_blocks_high);

890 891
        const TX_SIZE max_tx_size = get_vartx_max_txsize(
            mbmi, plane_bsize, pd->subsampling_x || pd->subsampling_y);
892 893
        const int bh_var_tx = tx_size_high_unit[max_tx_size];
        const int bw_var_tx = tx_size_wide_unit[max_tx_size];
894 895 896
        int block = 0;
        int step =
            tx_size_wide_unit[max_tx_size] * tx_size_high_unit[max_tx_size];
897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912

        for (row = 0; row < max_blocks_high; row += mu_blocks_high) {
          for (col = 0; col < max_blocks_wide; col += mu_blocks_wide) {
            int blk_row, blk_col;
            const int unit_height =
                AOMMIN(mu_blocks_high + row, max_blocks_high);
            const int unit_width =
                AOMMIN(mu_blocks_wide + col, max_blocks_wide);
            for (blk_row = row; blk_row < unit_height; blk_row += bh_var_tx) {
              for (blk_col = col; blk_col < unit_width; blk_col += bw_var_tx) {
                decode_reconstruct_tx(cm, xd, r, mbmi, plane, plane_bsize,
                                      blk_row, blk_col, block, max_tx_size,
                                      &eobtotal);
                block += step;
              }
            }
913 914
          }
        }
915
      }
Jingning Han's avatar
Jingning Han committed
916 917
    }
  }
918 919 920 921 922 923 924 925 926 927 928 929
#if CONFIG_CFL && CONFIG_CHROMA_SUB8X8
  if (mbmi->uv_mode != UV_CFL_PRED) {
#if CONFIG_DEBUG
    if (cfl->is_chroma_reference) {
      cfl_clear_sub8x8_val(cfl);
    }
#endif
    if (!cfl->is_chroma_reference && is_inter_block(mbmi)) {
      cfl_store_block(xd, mbmi->sb_type, mbmi->tx_size);
    }
  }
#endif  // CONFIG_CFL && CONFIG_CHROMA_SUB8X8
930
#endif  // CONFIG_COEF_INTERLEAVE
Jingning Han's avatar
Jingning Han committed
931

932 933
  int reader_corrupted_flag = aom_reader_has_error(r);
  aom_merge_corrupted_flag(&xd->corrupted, reader_corrupted_flag);
Jingning Han's avatar
Jingning Han committed
934 935
}

936
#if NC_MODE_INFO && CONFIG_MOTION_VAR
937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954
static void detoken_and_recon_sb(AV1Decoder *const pbi, MACROBLOCKD *const xd,
                                 int mi_row, int mi_col, aom_reader *r,
                                 BLOCK_SIZE bsize) {
  AV1_COMMON *const cm = &pbi->common;
  const int hbs = mi_size_wide[bsize] >> 1;
#if CONFIG_EXT_PARTITION_TYPES
  BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
#endif
  PARTITION_TYPE partition;
  BLOCK_SIZE subsize;
  const int has_rows = (mi_row + hbs) < cm->mi_rows;
  const int has_cols = (mi_col + hbs) < cm->mi_cols;

  if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;

  partition = get_partition(cm, mi_row, mi_col, bsize);
  subsize = subsize_lookup[partition][bsize];

955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974
  switch (partition) {
    case PARTITION_NONE:
      decode_token_and_recon_block(pbi, xd, mi_row, mi_col, r, bsize);
      break;
    case PARTITION_HORZ:
      decode_token_and_recon_block(pbi, xd, mi_row, mi_col, r, subsize);
      if (has_rows)
        decode_token_and_recon_block(pbi, xd, mi_row + hbs, mi_col, r, subsize);
      break;
    case PARTITION_VERT:
      decode_token_and_recon_block(pbi, xd, mi_row, mi_col, r, subsize);
      if (has_cols)
        decode_token_and_recon_block(pbi, xd, mi_row, mi_col + hbs, r, subsize);
      break;
    case PARTITION_SPLIT:
      detoken_and_recon_sb(pbi, xd, mi_row, mi_col, r, subsize);
      detoken_and_recon_sb(pbi, xd, mi_row, mi_col + hbs, r, subsize);
      detoken_and_recon_sb(pbi, xd, mi_row + hbs, mi_col, r, subsize);
      detoken_and_recon_sb(pbi, xd, mi_row + hbs, mi_col + hbs, r, subsize);
      break;
975
#if CONFIG_EXT_PARTITION_TYPES
976 977 978
#if CONFIG_EXT_PARTITION_TYPES_AB
#error NC_MODE_INFO+MOTION_VAR not yet supported for new HORZ/VERT_AB partitions
#endif
979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000
    case PARTITION_HORZ_A:
      decode_token_and_recon_block(pbi, xd, mi_row, mi_col, r, bsize2);
      decode_token_and_recon_block(pbi, xd, mi_row, mi_col + hbs, r, bsize2);
      decode_token_and_recon_block(pbi, xd, mi_row + hbs, mi_col, r, subsize);
      break;
    case PARTITION_HORZ_B:
      decode_token_and_recon_block(pbi, xd, mi_row, mi_col, r, subsize);
      decode_token_and_recon_block(pbi, xd, mi_row + hbs, mi_col, r, bsize2);
      decode_token_and_recon_block(pbi, xd, mi_row + hbs, mi_col + hbs, r,
                                   bsize2);
      break;
    case PARTITION_VERT_A:
      decode_token_and_recon_block(pbi, xd, mi_row, mi_col, r, bsize2);
      decode_token_and_recon_block(pbi, xd, mi_row + hbs, mi_col, r, bsize2);
      decode_token_and_recon_block(pbi, xd, mi_row, mi_col + hbs, r, subsize);
      break;
    case PARTITION_VERT_B:
      decode_token_and_recon_block(pbi, xd, mi_row, mi_col, r, subsize);
      decode_token_and_recon_block(pbi, xd, mi_row, mi_col + hbs, r, bsize2);
      decode_token_and_recon_block(pbi, xd, mi_row + hbs, mi_col + hbs, r,
                                   bsize2);
      break;
1001
#endif
1002
    default: assert(0 && "Invalid partition type");
1003 1004 1005 1006
  }
}
#endif

1007 1008 1009 1010 1011 1012
static void decode_block(AV1Decoder *const pbi, MACROBLOCKD *const xd,
                         int mi_row, int mi_col, aom_reader *r,
#if CONFIG_EXT_PARTITION_TYPES
                         PARTITION_TYPE partition,
#endif  // CONFIG_EXT_PARTITION_TYPES
                         BLOCK_SIZE bsize) {
1013
  decode_mbmi_block(pbi, xd, mi_row, mi_col, r,
1014 1015 1016 1017
#if CONFIG_EXT_PARTITION_TYPES
                    partition,
#endif
                    bsize);
1018

1019
#if !(CONFIG_MOTION_VAR && NC_MODE_INFO)
1020
  decode_token_and_recon_block(pbi, xd, mi_row, mi_col, r, bsize);
1021
#endif
1022 1023
}

1024 1025
static PARTITION_TYPE read_partition(AV1_COMMON *cm, MACROBLOCKD *xd,
                                     int mi_row, int mi_col, aom_reader *r,
1026
                                     int has_rows, int has_cols,
1027
                                     BLOCK_SIZE bsize) {
1028 1029 1030 1031
#if CONFIG_UNPOISON_PARTITION_CTX
  const int ctx =
      partition_plane_context(xd, mi_row, mi_col, has_rows, has_cols, bsize);
#else
1032
  const int ctx = partition_plane_context(xd, mi_row, mi_col, bsize);
1033
#endif
Jingning Han's avatar
Jingning Han committed
1034
  PARTITION_TYPE p;
1035 1036
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
  (void)cm;
Jingning Han's avatar
Jingning Han committed
1037

Jingning Han's avatar
Jingning Han committed
1038 1039
  aom_cdf_prob *partition_cdf = (ctx >= 0) ? ec_ctx->partition_cdf[ctx] : NULL;