decodeframe.c 144 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
#include "aom_ports/aom_timer.h"
27 28
#include "aom_ports/mem.h"
#include "aom_ports/mem_ops.h"
Yaowu Xu's avatar
Yaowu Xu committed
29 30
#include "aom_scale/aom_scale.h"
#include "aom_util/aom_thread.h"
Jingning Han's avatar
Jingning Han committed
31

Angie Chiang's avatar
Angie Chiang committed
32
#if CONFIG_BITSTREAM_DEBUG || CONFIG_MISMATCH_DEBUG
33
#include "aom_util/debug_util.h"
Angie Chiang's avatar
Angie Chiang committed
34
#endif  // CONFIG_BITSTREAM_DEBUG || CONFIG_MISMATCH_DEBUG
35

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

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

Yue Chen's avatar
Yue Chen committed
68 69
#include "av1/common/warped_motion.h"

Yaowu Xu's avatar
Yaowu Xu committed
70
#define MAX_AV1_HEADER_SIZE 80
Michael Bebenita's avatar
Michael Bebenita committed
71
#define ACCT_STR __func__
Jingning Han's avatar
Jingning Han committed
72

73 74 75 76
#if CONFIG_CFL
#include "av1/common/cfl.h"
#endif

77 78 79 80
#if CONFIG_STRIPED_LOOP_RESTORATION && !CONFIG_LOOP_RESTORATION
#error "striped_loop_restoration requires loop_restoration"
#endif

81 82 83 84 85 86 87
#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

88 89 90 91 92 93 94 95
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
96
static int is_compound_reference_allowed(const AV1_COMMON *cm) {
97
  return !frame_is_intra_only(cm);
Jingning Han's avatar
Jingning Han committed
98 99
}

Yaowu Xu's avatar
Yaowu Xu committed
100
static void setup_compound_reference_mode(AV1_COMMON *cm) {
101
  cm->comp_fwd_ref[0] = LAST_FRAME;
102 103 104 105
  cm->comp_fwd_ref[1] = LAST2_FRAME;
  cm->comp_fwd_ref[2] = LAST3_FRAME;
  cm->comp_fwd_ref[3] = GOLDEN_FRAME;

106
  cm->comp_bwd_ref[0] = BWDREF_FRAME;
Zoe Liu's avatar
Zoe Liu committed
107 108
  cm->comp_bwd_ref[1] = ALTREF2_FRAME;
  cm->comp_bwd_ref[2] = ALTREF_FRAME;
Jingning Han's avatar
Jingning Han committed
109 110 111 112 113 114
}

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
115 116
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
117 118 119
  return data > max ? max : data;
}

120 121 122 123 124 125
#if CONFIG_SIMPLIFY_TX_MODE
static TX_MODE read_tx_mode(AV1_COMMON *cm, struct aom_read_bit_buffer *rb) {
  if (cm->all_lossless) return ONLY_4X4;
  return aom_rb_read_bit(rb) ? TX_MODE_SELECT : TX_MODE_LARGEST;
}
#else
126 127
static TX_MODE read_tx_mode(AV1_COMMON *cm, struct aom_read_bit_buffer *rb) {
  if (cm->all_lossless) return ONLY_4X4;
128
#if CONFIG_TX64X64
Urvang Joshi's avatar
Urvang Joshi committed
129 130
  TX_MODE tx_mode =
      aom_rb_read_bit(rb) ? TX_MODE_SELECT : aom_rb_read_literal(rb, 2);
131 132 133
  if (tx_mode == ALLOW_32X32) tx_mode += aom_rb_read_bit(rb);
  return tx_mode;
#else
Yaowu Xu's avatar
Yaowu Xu committed
134
  return aom_rb_read_bit(rb) ? TX_MODE_SELECT : aom_rb_read_literal(rb, 2);
135
#endif  // CONFIG_TX64X64
136
}
137
#endif  // CONFIG_SIMPLIFY_TX_MODE
Jingning Han's avatar
Jingning Han committed
138

139
static REFERENCE_MODE read_frame_reference_mode(
Yaowu Xu's avatar
Yaowu Xu committed
140
    const AV1_COMMON *cm, struct aom_read_bit_buffer *rb) {
141
  if (is_compound_reference_allowed(cm)) {
Zoe Liu's avatar
Zoe Liu committed
142 143 144
#if CONFIG_REF_ADAPT
    return aom_rb_read_bit(rb) ? REFERENCE_MODE_SELECT : SINGLE_REFERENCE;
#else
Yaowu Xu's avatar
Yaowu Xu committed
145
    return aom_rb_read_bit(rb)
146
               ? REFERENCE_MODE_SELECT
Yaowu Xu's avatar
Yaowu Xu committed
147
               : (aom_rb_read_bit(rb) ? COMPOUND_REFERENCE : SINGLE_REFERENCE);
Zoe Liu's avatar
Zoe Liu committed
148
#endif  // CONFIG_REF_ADAPT
149 150 151 152
  } else {
    return SINGLE_REFERENCE;
  }
}
Jingning Han's avatar
Jingning Han committed
153

154
static void inverse_transform_block(MACROBLOCKD *xd, int plane,
155
                                    const TX_TYPE tx_type,
156
                                    const TX_SIZE tx_size, uint8_t *dst,
157 158
                                    int stride, int16_t scan_line, int eob,
                                    int reduced_tx_set) {
Jingning Han's avatar
Jingning Han committed
159
  struct macroblockd_plane *const pd = &xd->plane[plane];
160
  tran_low_t *const dqcoeff = pd->dqcoeff;
Sebastien Alaiwan's avatar
Sebastien Alaiwan committed
161 162
  av1_inverse_transform_block(xd, dqcoeff, plane, tx_type, tx_size, dst, stride,
                              eob, reduced_tx_set);
163
  memset(dqcoeff, 0, (scan_line + 1) * sizeof(dqcoeff[0]));
Jingning Han's avatar
Jingning Han committed
164 165
}

166 167 168 169 170 171
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);
172
  const TX_SIZE tx_size = av1_get_tx_size(plane, xd);
173 174 175 176
  const uint8_t txh_unit = tx_size_high_unit[tx_size];
  return row * max_blocks_wide + col * txh_unit;
}

177 178 179
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) {
180
  PLANE_TYPE plane_type = get_plane_type(plane);
181
  const int block_idx = get_block_idx(xd, plane, row, col);
182
  av1_predict_intra_block_facade(cm, xd, plane, block_idx, col, row, tx_size);
Jingning Han's avatar
Jingning Han committed
183 184

  if (!mbmi->skip) {
185
    struct macroblockd_plane *const pd = &xd->plane[plane];
186 187 188 189
#if TXCOEFF_TIMER
    struct aom_usec_timer timer;
    aom_usec_timer_start(&timer);
#endif
Angie Chiang's avatar
Angie Chiang committed
190 191
#if CONFIG_LV_MAP
    int16_t max_scan_line = 0;
192
    int eob;
193 194
    av1_read_coeffs_txb_facade(cm, xd, r, row, col, block_idx, plane, tx_size,
                               &max_scan_line, &eob);
195
    // tx_type will be read out in av1_read_coeffs_txb_facade
196 197
    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
198
#else   // CONFIG_LV_MAP
199 200
    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
201
    const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, mbmi);
202 203
    int16_t max_scan_line = 0;
    const int eob =
204
        av1_decode_block_tokens(cm, xd, plane, scan_order, col, row, tx_size,
205
                                tx_type, &max_scan_line, r, mbmi->segment_id);
Angie Chiang's avatar
Angie Chiang committed
206
#endif  // CONFIG_LV_MAP
207 208 209 210 211 212 213

#if TXCOEFF_TIMER
    aom_usec_timer_mark(&timer);
    const int64_t elapsed_time = aom_usec_timer_elapsed(&timer);
    cm->txcoeff_timer += elapsed_time;
    ++cm->txb_count;
#endif
214 215 216
    if (eob) {
      uint8_t *dst =
          &pd->dst.buf[(row * pd->dst.stride + col) << tx_size_wide_log2[0]];
217
      inverse_transform_block(xd, plane, tx_type, tx_size, dst, pd->dst.stride,
218
                              max_scan_line, eob, cm->reduced_tx_set_used);
219
    }
Jingning Han's avatar
Jingning Han committed
220
  }
221
#if CONFIG_CFL
222
  if (plane == AOM_PLANE_Y && xd->cfl.store_y && is_cfl_allowed(mbmi)) {
223
    cfl_store_tx(xd, row, col, tx_size, mbmi->sb_type);
224
  }
Sebastien Alaiwan's avatar
Sebastien Alaiwan committed
225
#endif  // CONFIG_CFL
Jingning Han's avatar
Jingning Han committed
226 227
}

Angie Chiang's avatar
Angie Chiang committed
228 229
static void decode_reconstruct_tx(AV1_COMMON *cm, MACROBLOCKD *const xd,
                                  aom_reader *r, MB_MODE_INFO *const mbmi,
230
                                  int plane, BLOCK_SIZE plane_bsize,
231
                                  int blk_row, int blk_col, int block,
Angie Chiang's avatar
Angie Chiang committed
232 233 234 235
                                  TX_SIZE tx_size, int *eob_total, int mi_row,
                                  int mi_col) {
  (void)mi_row;
  (void)mi_col;
236
  const struct macroblockd_plane *const pd = &xd->plane[plane];
237
  const BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
238 239
  const int tx_row = blk_row >> (1 - pd->subsampling_y);
  const int tx_col = blk_col >> (1 - pd->subsampling_x);
240
  const TX_SIZE plane_tx_size =
241
      plane ? uv_txsize_lookup[bsize][mbmi->inter_tx_size[tx_row][tx_col]][0][0]
242
            : mbmi->inter_tx_size[tx_row][tx_col];
243
  // Scale to match transform block unit.
244 245
  const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
  const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
246

247
  if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
248

249 250 251 252 253
  if (tx_size == plane_tx_size
#if DISABLE_VARTX_FOR_CHROMA
      || pd->subsampling_x || pd->subsampling_y
#endif  // DISABLE_VARTX_FOR_CHROMA
      ) {
254
    PLANE_TYPE plane_type = get_plane_type(plane);
255 256 257 258
#if TXCOEFF_TIMER
    struct aom_usec_timer timer;
    aom_usec_timer_start(&timer);
#endif
Angie Chiang's avatar
Angie Chiang committed
259 260
#if CONFIG_LV_MAP
    int16_t max_scan_line = 0;
261
    int eob;
262
    av1_read_coeffs_txb_facade(cm, xd, r, blk_row, blk_col, block, plane,
263
                               tx_size, &max_scan_line, &eob);
264
    // tx_type will be read out in av1_read_coeffs_txb_facade
hui su's avatar
hui su committed
265
    const TX_TYPE tx_type =
266
        av1_get_tx_type(plane_type, xd, blk_row, blk_col, block, tx_size);
Angie Chiang's avatar
Angie Chiang committed
267
#else   // CONFIG_LV_MAP
hui su's avatar
hui su committed
268
    const TX_TYPE tx_type =
269 270
        av1_get_tx_type(plane_type, xd, blk_row, blk_col, block, tx_size);
    const SCAN_ORDER *sc = get_scan(cm, tx_size, tx_type, mbmi);
271
    int16_t max_scan_line = 0;
272 273 274
    const int eob =
        av1_decode_block_tokens(cm, xd, plane, sc, blk_col, blk_row, tx_size,
                                tx_type, &max_scan_line, r, mbmi->segment_id);
Angie Chiang's avatar
Angie Chiang committed
275
#endif  // CONFIG_LV_MAP
276 277 278 279 280 281 282 283

#if TXCOEFF_TIMER
    aom_usec_timer_mark(&timer);
    const int64_t elapsed_time = aom_usec_timer_elapsed(&timer);
    cm->txcoeff_timer += elapsed_time;
    ++cm->txb_count;
#endif

Angie Chiang's avatar
Angie Chiang committed
284
    uint8_t *dst =
285
        &pd->dst
Angie Chiang's avatar
Angie Chiang committed
286 287 288 289 290 291 292 293 294 295 296 297
             .buf[(blk_row * pd->dst.stride + blk_col) << tx_size_wide_log2[0]];
    inverse_transform_block(xd, plane, tx_type, tx_size, dst, pd->dst.stride,
                            max_scan_line, eob, cm->reduced_tx_set_used);
#if CONFIG_MISMATCH_DEBUG
    int pixel_c, pixel_r;
    int blk_w = block_size_wide[plane_bsize];
    int blk_h = block_size_high[plane_bsize];
    mi_to_pixel_loc(&pixel_c, &pixel_r, mi_col, mi_row, blk_col, blk_row,
                    pd->subsampling_x, pd->subsampling_y);
    mismatch_check_block_tx(dst, pd->dst.stride, plane, pixel_c, pixel_r, blk_w,
                            blk_h);
#endif
298 299
    *eob_total += eob;
  } else {
300
    const TX_SIZE sub_txs = sub_tx_size_map[1][tx_size];
301 302
    assert(IMPLIES(tx_size <= TX_4X4, sub_txs == tx_size));
    assert(IMPLIES(tx_size > TX_4X4, sub_txs < tx_size));
303 304 305
    const int bsw = tx_size_wide_unit[sub_txs];
    const int bsh = tx_size_high_unit[sub_txs];
    const int sub_step = bsw * bsh;
306

307
    assert(bsw > 0 && bsh > 0);
308

309 310 311 312
    for (int row = 0; row < tx_size_high_unit[tx_size]; row += bsh) {
      for (int col = 0; col < tx_size_wide_unit[tx_size]; col += bsw) {
        const int offsetr = blk_row + row;
        const int offsetc = blk_col + col;
313

314
        if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
315

316
        decode_reconstruct_tx(cm, xd, r, mbmi, plane, plane_bsize, offsetr,
Angie Chiang's avatar
Angie Chiang committed
317 318
                              offsetc, block, sub_txs, eob_total, mi_row,
                              mi_col);
319 320
        block += sub_step;
      }
321 322 323
    }
  }
}
Jingning Han's avatar
Jingning Han committed
324

325 326 327
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
328 329 330 331 332 333 334 335
  const int offset = mi_row * cm->mi_stride + mi_col;
  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;
336 337 338
#if CONFIG_RD_DEBUG
  xd->mi[0]->mbmi.mi_row = mi_row;
  xd->mi[0]->mbmi.mi_col = mi_col;
339 340
#endif
#if CONFIG_CFL
341 342
  xd->cfl.mi_row = mi_row;
  xd->cfl.mi_col = mi_col;
343
#endif
344 345

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

Jingning Han's avatar
Jingning Han committed
353
  set_plane_n4(xd, bw, bh);
Jingning Han's avatar
Jingning Han committed
354 355
  set_skip_context(xd, mi_row, mi_col);

356 357 358
  // 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,
359
#if CONFIG_DEPENDENT_HORZTILES
360 361 362
                 cm->dependent_horz_tiles,
#endif  // CONFIG_DEPENDENT_HORZTILES
                 cm->mi_rows, cm->mi_cols);
Jingning Han's avatar
Jingning Han committed
363

364 365
  av1_setup_dst_planes(xd->plane, bsize, get_frame_new_buffer(cm), mi_row,
                       mi_col);
Jingning Han's avatar
Jingning Han committed
366 367
}

368 369
static void decode_mbmi_block(AV1Decoder *const pbi, MACROBLOCKD *const xd,
                              int mi_row, int mi_col, aom_reader *r,
370
#if CONFIG_EXT_PARTITION_TYPES
371
                              PARTITION_TYPE partition,
372
#endif  // CONFIG_EXT_PARTITION_TYPES
373
                              BLOCK_SIZE bsize) {
Yaowu Xu's avatar
Yaowu Xu committed
374
  AV1_COMMON *const cm = &pbi->common;
375 376
  const int bw = mi_size_wide[bsize];
  const int bh = mi_size_high[bsize];
Yaowu Xu's avatar
Yaowu Xu committed
377 378
  const int x_mis = AOMMIN(bw, cm->mi_cols - mi_col);
  const int y_mis = AOMMIN(bh, cm->mi_rows - mi_row);
379

Michael Bebenita's avatar
Michael Bebenita committed
380 381 382
#if CONFIG_ACCOUNTING
  aom_accounting_set_context(&pbi->accounting, mi_col, mi_row);
#endif
383
  set_offsets(cm, xd, bsize, mi_row, mi_col, bw, bh, x_mis, y_mis);
384 385 386
#if CONFIG_EXT_PARTITION_TYPES
  xd->mi[0]->mbmi.partition = partition;
#endif
Yaowu Xu's avatar
Yaowu Xu committed
387
  av1_read_mode_info(pbi, xd, mi_row, mi_col, r, x_mis, y_mis);
Jingning Han's avatar
Jingning Han committed
388 389 390 391
  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
392
      aom_internal_error(xd->error_info, AOM_CODEC_CORRUPT_FRAME,
393
                         "Invalid block size.");
Jingning Han's avatar
Jingning Han committed
394 395
  }

396 397
  int reader_corrupted_flag = aom_reader_has_error(r);
  aom_merge_corrupted_flag(&xd->corrupted, reader_corrupted_flag);
398 399 400 401 402 403 404 405 406 407 408 409
}

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);

410 411
  set_offsets(cm, xd, bsize, mi_row, mi_col, bw, bh, x_mis, y_mis);
  MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
412
#if CONFIG_CFL
413
  CFL_CTX *const cfl = &xd->cfl;
414 415
  cfl->is_chroma_reference = is_chroma_reference(
      mi_row, mi_col, bsize, cfl->subsampling_x, cfl->subsampling_y);
416
#endif  // CONFIG_CFL
417

418
  if (cm->delta_q_present_flag) {
419
    for (int i = 0; i < MAX_SEGMENTS; i++) {
Fangwen Fu's avatar
Fangwen Fu committed
420
#if CONFIG_EXT_DELTA_Q
421 422
      const int current_qindex =
          av1_get_qindex(&cm->seg, i, xd->current_qindex);
Fangwen Fu's avatar
Fangwen Fu committed
423
#else
424 425
      const int current_qindex = xd->current_qindex;
#endif  // CONFIG_EXT_DELTA_Q
426
      for (int j = 0; j < av1_num_planes(cm); ++j) {
427 428 429 430 431
        const int dc_delta_q =
            j == 0 ? cm->y_dc_delta_q
                   : (j == 1 ? cm->u_dc_delta_q : cm->v_dc_delta_q);
        const int ac_delta_q =
            j == 0 ? 0 : (j == 1 ? cm->u_ac_delta_q : cm->v_ac_delta_q);
432 433 434 435
        xd->plane[j].seg_dequant_QTX[i][0] =
            av1_dc_quant_QTX(current_qindex, dc_delta_q, cm->bit_depth);
        xd->plane[j].seg_dequant_QTX[i][1] =
            av1_ac_quant_QTX(current_qindex, ac_delta_q, cm->bit_depth);
436
      }
437 438
    }
  }
439
  if (mbmi->skip) av1_reset_skip_context(xd, mi_row, mi_col, bsize);
440

441
  if (!is_inter_block(mbmi)) {
442 443
    const int num_planes = av1_num_planes(cm);
    for (int plane = 0; plane < AOMMIN(2, num_planes); ++plane) {
444
      if (mbmi->palette_mode_info.palette_size[plane])
Yaowu Xu's avatar
Yaowu Xu committed
445
        av1_decode_palette_tokens(xd, plane, r);
Jingning Han's avatar
Jingning Han committed
446
    }
447

448
    for (int plane = 0; plane < num_planes; ++plane) {
449
      const struct macroblockd_plane *const pd = &xd->plane[plane];
450
      const TX_SIZE tx_size = av1_get_tx_size(plane, xd);
451 452
      const int stepr = tx_size_high_unit[tx_size];
      const int stepc = tx_size_wide_unit[tx_size];
453 454
      const BLOCK_SIZE plane_bsize =
          AOMMAX(BLOCK_4X4, get_plane_block_size(bsize, pd));
455
      int row, col;
456 457
      const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
      const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
458 459
      if (!is_chroma_reference(mi_row, mi_col, bsize, pd->subsampling_x,
                               pd->subsampling_y))
460
        continue;
461 462 463 464 465 466 467 468 469 470
      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) {
471
        const int unit_height = AOMMIN(mu_blocks_high + row, max_blocks_high);
472 473 474 475 476 477 478 479 480
        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);
        }
      }
481 482
    }
  } else {
483 484
    int ref;

485 486
    for (ref = 0; ref < 1 + has_second_ref(mbmi); ++ref) {
      const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
Alex Converse's avatar
Alex Converse committed
487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504
      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);
      }
505
    }
506

507
    av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize);
508

Yue Chen's avatar
Yue Chen committed
509
    if (mbmi->motion_mode == OBMC_CAUSAL) {
510
      av1_build_obmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
511
    }
Angie Chiang's avatar
Angie Chiang committed
512 513 514 515 516 517 518 519 520 521 522 523 524 525 526

#if CONFIG_MISMATCH_DEBUG
    for (int plane = 0; plane < 3; ++plane) {
      const struct macroblockd_plane *pd = &xd->plane[plane];
      int pixel_c, pixel_r;
      mi_to_pixel_loc(&pixel_c, &pixel_r, mi_col, mi_row, 0, 0,
                      pd->subsampling_x, pd->subsampling_y);
      if (!is_chroma_reference(mi_row, mi_col, bsize, pd->subsampling_x,
                               pd->subsampling_y))
        continue;
      mismatch_check_block_pre(pd->dst.buf, pd->dst.stride, plane, pixel_c,
                               pixel_r, pd->width, pd->height);
    }
#endif

527 528 529
    // Reconstruction
    if (!mbmi->skip) {
      int eobtotal = 0;
530
      for (int plane = 0; plane < av1_num_planes(cm); ++plane) {
Jingning Han's avatar
Jingning Han committed
531
        const struct macroblockd_plane *const pd = &xd->plane[plane];
532 533 534 535 536
        if (!is_chroma_reference(mi_row, mi_col, bsize, pd->subsampling_x,
                                 pd->subsampling_y))
          continue;
        const BLOCK_SIZE bsizec =
            scale_chroma_bsize(bsize, pd->subsampling_x, pd->subsampling_y);
537
        const BLOCK_SIZE plane_bsize =
538
            AOMMAX(BLOCK_4X4, get_plane_block_size(bsizec, pd));
539 540
        const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
        const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
541
        int row, col;
542

543 544 545 546 547 548 549 550 551
        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);

552
        TX_SIZE max_tx_size = get_vartx_max_txsize(
553
            xd, plane_bsize, pd->subsampling_x || pd->subsampling_y);
554 555 556 557 558 559 560 561 562
#if DISABLE_VARTX_FOR_CHROMA == 2
        // If the luma transform size is split at least one level, split the
        // chroma by one level. Otherwise use the  largest possible trasnform
        // size for chroma.
        if (plane && (pd->subsampling_x || pd->subsampling_y)) {
          const TX_SIZE l_max_tx_size = get_vartx_max_txsize(xd, bsizec, 0);
          const int is_split =
              (l_max_tx_size != mbmi->inter_tx_size[0][0] && bsize == bsizec &&
               txsize_to_bsize[l_max_tx_size] == bsizec);
563
          if (is_split) max_tx_size = sub_tx_size_map[1][max_tx_size];
564 565
        }
#endif  // DISABLE_VARTX_FOR_CHROMA == 2
566 567
        const int bh_var_tx = tx_size_high_unit[max_tx_size];
        const int bw_var_tx = tx_size_wide_unit[max_tx_size];
568 569 570
        int block = 0;
        int step =
            tx_size_wide_unit[max_tx_size] * tx_size_high_unit[max_tx_size];
571 572 573 574 575 576 577 578 579 580 581 582

        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,
Angie Chiang's avatar
Angie Chiang committed
583
                                      &eobtotal, mi_row, mi_col);
584 585 586
                block += step;
              }
            }
587 588
          }
        }
589
      }
Jingning Han's avatar
Jingning Han committed
590 591
    }
  }
592
#if CONFIG_CFL
593
  if (mbmi->uv_mode != UV_CFL_PRED) {
594 595
    if (!cfl->is_chroma_reference && is_inter_block(mbmi) &&
        is_cfl_allowed(mbmi)) {
596 597 598
      cfl_store_block(xd, mbmi->sb_type, mbmi->tx_size);
    }
  }
599
#endif  // CONFIG_CFL
Jingning Han's avatar
Jingning Han committed
600

601 602
  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
603 604
}

605 606 607 608 609 610
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) {
611
  decode_mbmi_block(pbi, xd, mi_row, mi_col, r,
612 613 614 615
#if CONFIG_EXT_PARTITION_TYPES
                    partition,
#endif
                    bsize);
616

617
  decode_token_and_recon_block(pbi, xd, mi_row, mi_col, r, bsize);
618 619
}

620 621
static PARTITION_TYPE read_partition(MACROBLOCKD *xd, int mi_row, int mi_col,
                                     aom_reader *r, int has_rows, int has_cols,
622 623
                                     BLOCK_SIZE bsize) {
  const int ctx = partition_plane_context(xd, mi_row, mi_col, bsize);
624
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
Jingning Han's avatar
Jingning Han committed
625

626
  if (!has_rows && !has_cols) return PARTITION_SPLIT;
Jingning Han's avatar
Jingning Han committed
627

628 629
  assert(ctx >= 0);
  aom_cdf_prob *partition_cdf = ec_ctx->partition_cdf[ctx];
630
  if (has_rows && has_cols) {
631 632
    return (PARTITION_TYPE)aom_read_symbol(
        r, partition_cdf, partition_cdf_length(bsize), ACCT_STR);
633
  } else if (!has_rows && has_cols) {
634 635
    assert(bsize > BLOCK_8X8);
    aom_cdf_prob cdf[2];
636
    partition_gather_vert_alike(cdf, partition_cdf, bsize);
637
    assert(cdf[1] == AOM_ICDF(CDF_PROB_TOP));
638 639 640
    return aom_read_cdf(r, cdf, 2, ACCT_STR) ? PARTITION_SPLIT : PARTITION_HORZ;
  } else {
    assert(has_rows && !has_cols);
641 642
    assert(bsize > BLOCK_8X8);
    aom_cdf_prob cdf[2];
643
    partition_gather_horz_alike(cdf, partition_cdf, bsize);
644
    assert(cdf[1] == AOM_ICDF(CDF_PROB_TOP));
645
    return aom_read_cdf(r, cdf, 2, ACCT_STR) ? PARTITION_SPLIT : PARTITION_VERT;
646
  }
Jingning Han's avatar
Jingning Han committed
647 648 649
}

// TODO(slavarnway): eliminate bsize and subsize in future commits
Yaowu Xu's avatar
Yaowu Xu committed
650 651
static void decode_partition(AV1Decoder *const pbi, MACROBLOCKD *const xd,
                             int mi_row, int mi_col, aom_reader *r,
652
                             BLOCK_SIZE bsize) {
Yaowu Xu's avatar
Yaowu Xu committed
653
  AV1_COMMON *const cm = &pbi->common;
654
  const int num_8x8_wh = mi_size_wide[bsize];
Jingning Han's avatar
Jingning Han committed
655
  const int hbs = num_8x8_wh >> 1;
656 657 658
#if CONFIG_EXT_PARTITION_TYPES && CONFIG_EXT_PARTITION_TYPES_AB
  const int qbs = num_8x8_wh >> 2;
#endif
Jingning Han's avatar
Jingning Han committed
659 660
  PARTITION_TYPE partition;
  BLOCK_SIZE subsize;
661
#if CONFIG_EXT_PARTITION_TYPES
662
  const int quarter_step = num_8x8_wh / 4;
663 664 665
#if !CONFIG_EXT_PARTITION_TYPES_AB
  BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
#endif
666
#endif
Jingning Han's avatar
Jingning Han committed
667 668 669
  const int has_rows = (mi_row + hbs) < cm->mi_rows;
  const int has_cols = (mi_col + hbs) < cm->mi_cols;

670
  if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
Jingning Han's avatar
Jingning Han committed
671

672
  partition = (bsize < BLOCK_8X8) ? PARTITION_NONE
673
                                  : read_partition(xd, mi_row, mi_col, r,
674
                                                   has_rows, has_cols, bsize);
Jingning Han's avatar
Jingning Han committed
675
  subsize = subsize_lookup[partition][bsize];  // get_subsize(bsize, partition);
676

677 678 679 680 681 682 683 684 685
  // Check the bitstream is conformant: if there is subsampling on the
  // chroma planes, subsize must subsample to a valid block size.
  const struct macroblockd_plane *const pd_u = &xd->plane[1];
  if (get_plane_block_size(subsize, pd_u) == BLOCK_INVALID) {
    aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
                       "Block size %dx%d invalid with this subsampling mode",
                       block_size_wide[subsize], block_size_high[subsize]);
  }

686 687 688 689 690 691 692 693 694 695 696 697
#define DEC_BLOCK_STX_ARG
#if CONFIG_EXT_PARTITION_TYPES
#define DEC_BLOCK_EPT_ARG partition,
#else
#define DEC_BLOCK_EPT_ARG
#endif
#define DEC_BLOCK(db_r, db_c, db_subsize)                   \
  decode_block(pbi, xd, DEC_BLOCK_STX_ARG(db_r), (db_c), r, \
               DEC_BLOCK_EPT_ARG(db_subsize))
#define DEC_PARTITION(db_r, db_c, db_subsize) \
  decode_partition(pbi, xd, DEC_BLOCK_STX_ARG(db_r), (db_c), r, (db_subsize))

698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713
  switch (partition) {
    case PARTITION_NONE: DEC_BLOCK(mi_row, mi_col, subsize); break;
    case PARTITION_HORZ:
      DEC_BLOCK(mi_row, mi_col, subsize);
      if (has_rows) DEC_BLOCK(mi_row + hbs, mi_col, subsize);
      break;
    case PARTITION_VERT:
      DEC_BLOCK(mi_row, mi_col, subsize);
      if (has_cols) DEC_BLOCK(mi_row, mi_col + hbs, subsize);
      break;
    case PARTITION_SPLIT:
      DEC_PARTITION(mi_row, mi_col, subsize);
      DEC_PARTITION(mi_row, mi_col + hbs, subsize);
      DEC_PARTITION(mi_row + hbs, mi_col, subsize);
      DEC_PARTITION(mi_row + hbs, mi_col + hbs, subsize);
      break;
714
#if CONFIG_EXT_PARTITION_TYPES
715
#if CONFIG_EXT_PARTITION_TYPES_AB
716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739
    case PARTITION_HORZ_A:
      DEC_BLOCK(mi_row, mi_col, get_subsize(bsize, PARTITION_HORZ_4));
      DEC_BLOCK(mi_row + qbs, mi_col, get_subsize(bsize, PARTITION_HORZ_4));
      DEC_BLOCK(mi_row + hbs, mi_col, subsize);
      break;
    case PARTITION_HORZ_B:
      DEC_BLOCK(mi_row, mi_col, subsize);
      DEC_BLOCK(mi_row + hbs, mi_col, get_subsize(bsize, PARTITION_HORZ_4));
      if (mi_row + 3 * qbs < cm->mi_rows)
        DEC_BLOCK(mi_row + 3 * qbs, mi_col,
                  get_subsize(bsize, PARTITION_HORZ_4));
      break;
    case PARTITION_VERT_A:
      DEC_BLOCK(mi_row, mi_col, get_subsize(bsize, PARTITION_VERT_4));
      DEC_BLOCK(mi_row, mi_col + qbs, get_subsize(bsize, PARTITION_VERT_4));
      DEC_BLOCK(mi_row, mi_col + hbs, subsize);
      break;
    case PARTITION_VERT_B:
      DEC_BLOCK(mi_row, mi_col, subsize);
      DEC_BLOCK(mi_row, mi_col + hbs, get_subsize(bsize, PARTITION_VERT_4));
      if (mi_col + 3 * qbs < cm->mi_cols)
        DEC_BLOCK(mi_row, mi_col + 3 * qbs,
                  get_subsize(bsize, PARTITION_VERT_4));
      break;
740
#else
741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760
    case PARTITION_HORZ_A:
      DEC_BLOCK(mi_row, mi_col, bsize2);
      DEC_BLOCK(mi_row, mi_col + hbs, bsize2);
      DEC_BLOCK(mi_row + hbs, mi_col, subsize);
      break;
    case PARTITION_HORZ_B:
      DEC_BLOCK(mi_row, mi_col, subsize);
      DEC_BLOCK(mi_row + hbs, mi_col, bsize2);
      DEC_BLOCK(mi_row + hbs, mi_col + hbs, bsize2);
      break;
    case PARTITION_VERT_A:
      DEC_BLOCK(mi_row, mi_col, bsize2);
      DEC_BLOCK(mi_row + hbs, mi_col, bsize2);
      DEC_BLOCK(mi_row, mi_col + hbs, subsize);
      break;
    case PARTITION_VERT_B:
      DEC_BLOCK(mi_row, mi_col, subsize);
      DEC_BLOCK(mi_row, mi_col + hbs, bsize2);
      DEC_BLOCK(mi_row + hbs, mi_col + hbs, bsize2);
      break;
761
#endif
762
    case PARTITION_HORZ_4:
763
      for (int i = 0; i < 4; ++i) {
764 765 766 767 768 769
        int this_mi_row = mi_row + i * quarter_step;
        if (i > 0 && this_mi_row >= cm->mi_rows) break;
        DEC_BLOCK(this_mi_row, mi_col, subsize);
      }
      break;
    case PARTITION_VERT_4:
770
      for (int i = 0; i < 4; ++i) {
771 772 773 774 775
        int this_mi_col = mi_col + i * quarter_step;
        if (i > 0 && this_mi_col >= cm->mi_cols) break;
        DEC_BLOCK(mi_row, this_mi_col, subsize);
      }
      break;
776
#endif  // CONFIG_EXT_PARTITION_TYPES
777
    default: assert(0 && "Invalid partition type");
Jingning Han's avatar
Jingning Han committed
778 779
  }

780 781 782 783 784
#undef DEC_PARTITION
#undef DEC_BLOCK
#undef DEC_BLOCK_EPT_ARG
#undef DEC_BLOCK_STX_ARG

785
#if CONFIG_EXT_PARTITION_TYPES
786
  update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize, partition);
787
#else
Jingning Han's avatar
Jingning Han committed
788 789 790
  // update partition context
  if (bsize >= BLOCK_8X8 &&
      (bsize == BLOCK_8X8 || partition != PARTITION_SPLIT))
791
    update_partition_context(xd, mi_row, mi_col, subsize, bsize);
792
#endif  // CONFIG_EXT_PARTITION_TYPES
793

794
#if CONFIG_LPF_SB
795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865
#if CONFIG_LOOPFILTER_LEVEL
  if (bsize == cm->sb_size && !USE_GUESS_LEVEL) {
    int lvl_idx;
    int filt_lvl[4];
    if (mi_row == 0 && mi_col == 0) {
      filt_lvl[0] = aom_read_literal(r, 6, ACCT_STR);
      filt_lvl[1] = aom_read_literal(r, 6, ACCT_STR);
      if (filt_lvl[0] || filt_lvl[1]) {
        filt_lvl[2] = aom_read_literal(r, 6, ACCT_STR);
        filt_lvl[3] = aom_read_literal(r, 6, ACCT_STR);
      }
      for (lvl_idx = 0; lvl_idx < 4; ++lvl_idx) {
        cm->mi_grid_visible[0]->mbmi.reuse_sb_lvl[lvl_idx] = 0;
        cm->mi_grid_visible[0]->mbmi.delta[lvl_idx] = 0;
        cm->mi_grid_visible[0]->mbmi.sign[lvl_idx] = 0;
      }
    } else {
      int prev_mi_row, prev_mi_col;
      if (mi_col - MAX_MIB_SIZE < 0) {
        prev_mi_row = mi_row - MAX_MIB_SIZE;
        prev_mi_col = mi_col;
      } else {
        prev_mi_row = mi_row;
        prev_mi_col = mi_col - MAX_MIB_SIZE;
      }

      MB_MODE_INFO *curr_mbmi =
          &cm->mi_grid_visible[mi_row * cm->mi_stride + mi_col]->mbmi;
      MB_MODE_INFO *prev_mbmi =
          &cm->mi_grid_visible[prev_mi_row * cm->mi_stride + prev_mi_col]->mbmi;
      for (lvl_idx = 0; lvl_idx < 4; ++lvl_idx) {
        const uint8_t prev_lvl = prev_mbmi->filt_lvl[lvl_idx];

        const int reuse_ctx = prev_mbmi->reuse_sb_lvl[lvl_idx];
        co