decodeframe.c 153 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
12
13
14
 */

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

Yaowu Xu's avatar
Yaowu Xu committed
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"
Yaowu Xu's avatar
Yaowu Xu committed
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"
Yaowu Xu's avatar
Yaowu Xu committed
25
#include "aom_mem/aom_mem.h"
26
27
#include "aom_ports/mem.h"
#include "aom_ports/mem_ops.h"
Yaowu Xu's avatar
Yaowu Xu committed
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"
Angie Chiang's avatar
Angie Chiang committed
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

Yaowu Xu's avatar
Yaowu Xu committed
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);

Yaowu Xu's avatar
Yaowu Xu committed
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
}

Yaowu Xu's avatar
Yaowu Xu committed
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);
}

Yaowu Xu's avatar
Yaowu Xu committed
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
Yaowu Xu's avatar
Yaowu Xu committed
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
Yaowu Xu's avatar
Yaowu Xu committed
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(
Yaowu Xu's avatar
Yaowu Xu committed
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
Yaowu Xu's avatar
Yaowu Xu committed
171
    return aom_rb_read_bit(rb)
172
               ? REFERENCE_MODE_SELECT
Yaowu Xu's avatar
Yaowu Xu committed
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
Yaowu Xu's avatar
Yaowu Xu committed
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) {
Zoe Liu's avatar
Zoe Liu committed
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;
Zoe Liu's avatar
Zoe Liu committed
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
    }
Zoe Liu's avatar
Zoe Liu committed
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
}

Yaowu Xu's avatar
Yaowu Xu committed
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
}

Yaowu Xu's avatar
Yaowu Xu committed
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
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];
  const BLOCK_SIZE plane_bsize =
      AOMMAX(BLOCK_4X4, get_plane_block_size(bsize, pd));
  const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
263
  const TX_SIZE tx_size = av1_get_tx_size(plane, xd);
264
265
266
267
  const uint8_t txh_unit = tx_size_high_unit[tx_size];
  return row * max_blocks_wide + col * txh_unit;
}

268
269
270
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) {
271
  PLANE_TYPE plane_type = get_plane_type(plane);
272
  const int block_idx = get_block_idx(xd, plane, row, col);
273
  av1_predict_intra_block_facade(cm, xd, plane, block_idx, col, row, tx_size);
Jingning Han's avatar
Jingning Han committed
274
275

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

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

329
  if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
330

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

    assert(bsl > 0);

    for (i = 0; i < 4; ++i) {
Yue Chen's avatar
Yue Chen committed
376
377
378
379
380
381
382
383
384
#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
385
386
      const int offsetr = blk_row + (i >> 1) * bsl;
      const int offsetc = blk_col + (i & 0x01) * bsl;
Yue Chen's avatar
Yue Chen committed
387
#endif
388

389
      if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
390

391
      decode_reconstruct_tx(cm, xd, r, mbmi, plane, plane_bsize, offsetr,
392
393
                            offsetc, block, sub_txs, eob_total);
      block += sub_step;
394
395
396
    }
  }
}
397
#endif
398

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

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

Jingning Han's avatar
Jingning Han committed
437
438
  return eob;
}
439
#endif  // CONFIG_COEF_INTERLEAVE
Jingning Han's avatar
Jingning Han committed
440

441
442
443
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
444
445
446
447
448
449
450
451
452
  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;
453
454
455
#if CONFIG_RD_DEBUG
  xd->mi[0]->mbmi.mi_row = mi_row;
  xd->mi[0]->mbmi.mi_col = mi_col;
456
457
458
459
#endif
#if CONFIG_CFL
  xd->cfl->mi_row = mi_row;
  xd->cfl->mi_col = mi_col;
460
#endif
461
462
463
464
465
466
467
468

  assert(x_mis && y_mis);
  for (x = 1; x < x_mis; ++x) xd->mi[x] = xd->mi[0];
  int idx = cm->mi_stride;
  for (y = 1; y < y_mis; ++y) {
    memcpy(&xd->mi[idx], &xd->mi[0], x_mis * sizeof(xd->mi[0]));
    idx += cm->mi_stride;
  }
Jingning Han's avatar
Jingning Han committed
469

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

473
474
475
  // 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,
476
#if CONFIG_DEPENDENT_HORZTILES
477
478
479
                 cm->dependent_horz_tiles,
#endif  // CONFIG_DEPENDENT_HORZTILES
                 cm->mi_rows, cm->mi_cols);
Jingning Han's avatar
Jingning Han committed
480

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

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

Michael Bebenita's avatar
Michael Bebenita committed
497
498
499
#if CONFIG_ACCOUNTING
  aom_accounting_set_context(&pbi->accounting, mi_col, mi_row);
#endif
500
  set_offsets(cm, xd, bsize, mi_row, mi_col, bw, bh, x_mis, y_mis);
501
502
503
#if CONFIG_EXT_PARTITION_TYPES
  xd->mi[0]->mbmi.partition = partition;
#endif
Yaowu Xu's avatar
Yaowu Xu committed
504
  av1_read_mode_info(pbi, xd, mi_row, mi_col, r, x_mis, y_mis);
Jingning Han's avatar
Jingning Han committed
505
506
507
508
  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)
Yaowu Xu's avatar
Yaowu Xu committed
509
      aom_internal_error(xd->error_info, AOM_CODEC_CORRUPT_FRAME,
510
                         "Invalid block size.");
Jingning Han's avatar
Jingning Han committed
511
512
  }

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

517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
#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);
537
538
539
540
541
542
543
544
    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);
545
546
  } else {
#endif  // CONFIG_HIGHBITDEPTH
547
548
549
550
    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);
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
603
604
#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

605
606
607
608
609
610
611
612
613
614
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);

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

623
624
625
  if (cm->delta_q_present_flag) {
    int i;
    for (i = 0; i < MAX_SEGMENTS; i++) {
Fangwen Fu's avatar
Fangwen Fu committed
626
#if CONFIG_EXT_DELTA_Q
627
628
      const int current_qindex =
          av1_get_qindex(&cm->seg, i, xd->current_qindex);
Fangwen Fu's avatar
Fangwen Fu committed
629
#else
630
631
632
633
634
635
636
637
638
639
640
641
      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);
      }
642
643
    }
  }
644
  if (mbmi->skip) av1_reset_skip_context(xd, mi_row, mi_col, bsize);
645

646
647
648
649
650
#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;
651
    const TX_SIZE tx_log2_c = av1_get_uv_tx_size(mbmi, pd_c);
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
713
714
    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
715
      av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL,
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
752
753
                                    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++;
        }

754
755
756
        // 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;
757
758
759
      }
    }
  }
Angie Chiang's avatar
Angie Chiang committed
760
#else  // CONFIG_COEF_INTERLEAVE
761
762
  if (!is_inter_block(mbmi)) {
    int plane;
763

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

769
770
    for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
      const struct macroblockd_plane *const pd = &xd->plane[plane];
771
      const TX_SIZE tx_size = av1_get_tx_size(plane, xd);
772
773
      const int stepr = tx_size_high_unit[tx_size];
      const int stepc = tx_size_wide_unit[tx_size];
774
775
      const BLOCK_SIZE plane_bsize =
          AOMMAX(BLOCK_4X4, get_plane_block_size(bsize, pd));
776
      int row, col;
777
778
      const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
      const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
779
780
      if (!is_chroma_reference(mi_row, mi_col, bsize, pd->subsampling_x,
                               pd->subsampling_y))
781
        continue;
782
783
784
785
786
787
788
789
790
791
      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) {
792
        const int unit_height = AOMMIN(mu_blocks_high + row, max_blocks_high);
793
794
795
796
797
798
799
800
801
        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);
        }
      }
802
803
    }
  } else {
804
805
    int ref;

806
#if CONFIG_COMPOUND_SINGLEREF
807
808
809
    for (ref = 0; ref < 1 + is_inter_anyref_comp_mode(mbmi->mode); ++ref)
#else
    for (ref = 0; ref < 1 + has_second_ref(mbmi); ++ref)
810
#endif  // CONFIG_COMPOUND_SINGLEREF
811
    {
812
      const MV_REFERENCE_FRAME frame =
813
#if CONFIG_COMPOUND_SINGLEREF
814
815
          has_second_ref(mbmi) ? mbmi->ref_frame[ref] : mbmi->ref_frame[0];
#else
816
          mbmi->ref_frame[ref];
817
#endif  // CONFIG_COMPOUND_SINGLEREF
Alex Converse's avatar
Alex Converse committed
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
      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);
      }
836
    }
837

838
    av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize);
839

Yue Chen's avatar
Yue Chen committed
840
841
#if CONFIG_MOTION_VAR
    if (mbmi->motion_mode == OBMC_CAUSAL) {
Yue Chen's avatar
Yue Chen committed
842
843
844
#if CONFIG_NCOBMC
      av1_build_ncobmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
#else
845
      av1_build_obmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
Yue Chen's avatar
Yue Chen committed
846
#endif
847
    }
Yue Chen's avatar
Yue Chen committed
848
#endif  // CONFIG_MOTION_VAR
849
850
851
852
853
854
855
856
857
#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
858
859
860
861
862
    // Reconstruction
    if (!mbmi->skip) {
      int eobtotal = 0;
      int plane;

Jingning Han's avatar
Jingning Han committed
863
864
      for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
        const struct macroblockd_plane *const pd = &xd->plane[plane];
865
866
        const BLOCK_SIZE plane_bsize =
            AOMMAX(BLOCK_4X4, get_plane_block_size(bsize, pd));
867
868
        const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
        const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
869
        int row, col;
870

871
872
        if (!is_chroma_reference(mi_row, mi_col, bsize, pd->subsampling_x,
                                 pd->subsampling_y))
873
874
          continue;

875
876
877
878
879
880
881
882
883
        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);

884
885
        const TX_SIZE max_tx_size = get_vartx_max_txsize(
            mbmi, plane_bsize, pd->subsampling_x || pd->subsampling_y);
886
887
        const int bh_var_tx = tx_size_high_unit[max_tx_size];
        const int bw_var_tx = tx_size_wide_unit[max_tx_size];
888
889
890
        int block = 0;
        int step =
            tx_size_wide_unit[max_tx_size] * tx_size_high_unit[max_tx_size];
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906

        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;
              }
            }
907
908
          }
        }
909
      }
Jingning Han's avatar
Jingning Han committed
910
911
    }
  }
912
#if CONFIG_CFL
913
914
915
916
917
918
919
920
921
922
  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);
    }
  }
923
#endif  // CONFIG_CFL
Angie Chiang's avatar
Angie Chiang committed
924
#endif  // CONFIG_COEF_INTERLEAVE
Jingning Han's avatar
Jingning Han committed
925

926
927
  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
928
929
}

930
#if NC_MODE_INFO && CONFIG_MOTION_VAR
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
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];

949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
  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;
969
#if CONFIG_EXT_PARTITION_TYPES
970
971
972
#if CONFIG_EXT_PARTITION_TYPES_AB
#error NC_MODE_INFO+MOTION_VAR not yet supported for new HORZ/VERT_AB partitions
#endif
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
    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;
995
#endif
996
    default: assert(0 && "Invalid partition type");
997
998
999
1000
  }
}
#endif

1001
1002
1003
1004
1005
1006
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) {
1007
  decode_mbmi_block(pbi, xd, mi_row, mi_col, r,
1008
1009
1010
1011
#if CONFIG_EXT_PARTITION_TYPES
                    partition,
#endif
                    bsize);