decodeframe.c 132 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
 */

#include <assert.h>

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

19
#include "aom/aom_codec.h"
Yaowu Xu's avatar
Yaowu Xu committed
20
#include "aom_dsp/aom_dsp_common.h"
21
#include "aom_dsp/binary_codes_reader.h"
Jingning Han's avatar
Jingning Han committed
22 23
#include "aom_dsp/bitreader.h"
#include "aom_dsp/bitreader_buffer.h"
Yaowu Xu's avatar
Yaowu Xu committed
24
#include "aom_mem/aom_mem.h"
25
#include "aom_ports/aom_timer.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

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

35
#include "av1/common/alloccommon.h"
36
#include "av1/common/cdef.h"
37 38 39
#if CONFIG_INSPECTION
#include "av1/decoder/inspection.h"
#endif
40 41 42
#include "av1/common/common.h"
#include "av1/common/entropy.h"
#include "av1/common/entropymode.h"
43
#include "av1/common/entropymv.h"
44
#include "av1/common/idct.h"
45
#include "av1/common/mvref_common.h"
46 47 48
#include "av1/common/pred_common.h"
#include "av1/common/quant_common.h"
#include "av1/common/reconinter.h"
Jingning Han's avatar
Jingning Han committed
49
#include "av1/common/reconintra.h"
50
#if CONFIG_HORZONLY_FRAME_SUPERRES
51
#include "av1/common/resize.h"
52
#endif  // CONFIG_HORZONLY_FRAME_SUPERRES
53
#include "av1/common/seg_common.h"
Jingning Han's avatar
Jingning Han committed
54
#include "av1/common/thread_common.h"
55
#include "av1/common/tile_common.h"
56
#include "av1/common/warped_motion.h"
57 58 59
#include "av1/decoder/decodeframe.h"
#include "av1/decoder/decodemv.h"
#include "av1/decoder/decoder.h"
Angie Chiang's avatar
Angie Chiang committed
60 61 62
#if CONFIG_LV_MAP
#include "av1/decoder/decodetxb.h"
#endif
Jingning Han's avatar
Jingning Han committed
63
#include "av1/decoder/detokenize.h"
Yue Chen's avatar
Yue Chen committed
64

Yaowu Xu's avatar
Yaowu Xu committed
65
#define MAX_AV1_HEADER_SIZE 80
Michael Bebenita's avatar
Michael Bebenita committed
66
#define ACCT_STR __func__
Jingning Han's avatar
Jingning Han committed
67

68 69 70 71
#if CONFIG_CFL
#include "av1/common/cfl.h"
#endif

72 73 74 75
#if CONFIG_STRIPED_LOOP_RESTORATION && !CONFIG_LOOP_RESTORATION
#error "striped_loop_restoration requires loop_restoration"
#endif

76 77 78 79 80 81 82
#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

Yaowu Xu's avatar
Yaowu Xu committed
83
static void setup_compound_reference_mode(AV1_COMMON *cm) {
84
  cm->comp_fwd_ref[0] = LAST_FRAME;
85 86 87 88
  cm->comp_fwd_ref[1] = LAST2_FRAME;
  cm->comp_fwd_ref[2] = LAST3_FRAME;
  cm->comp_fwd_ref[3] = GOLDEN_FRAME;

89
  cm->comp_bwd_ref[0] = BWDREF_FRAME;
Zoe Liu's avatar
Zoe Liu committed
90 91
  cm->comp_bwd_ref[1] = ALTREF2_FRAME;
  cm->comp_bwd_ref[2] = ALTREF_FRAME;
Jingning Han's avatar
Jingning Han committed
92 93 94 95 96 97
}

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

98 99 100 101 102 103
#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
104 105
static TX_MODE read_tx_mode(AV1_COMMON *cm, struct aom_read_bit_buffer *rb) {
  if (cm->all_lossless) return ONLY_4X4;
106
#if CONFIG_TX64X64
Urvang Joshi's avatar
Urvang Joshi committed
107 108
  TX_MODE tx_mode =
      aom_rb_read_bit(rb) ? TX_MODE_SELECT : aom_rb_read_literal(rb, 2);
109 110 111
  if (tx_mode == ALLOW_32X32) tx_mode += aom_rb_read_bit(rb);
  return tx_mode;
#else
Yaowu Xu's avatar
Yaowu Xu committed
112
  return aom_rb_read_bit(rb) ? TX_MODE_SELECT : aom_rb_read_literal(rb, 2);
113
#endif  // CONFIG_TX64X64
114
}
115
#endif  // CONFIG_SIMPLIFY_TX_MODE
Jingning Han's avatar
Jingning Han committed
116

117
static REFERENCE_MODE read_frame_reference_mode(
Yaowu Xu's avatar
Yaowu Xu committed
118
    const AV1_COMMON *cm, struct aom_read_bit_buffer *rb) {
119
  if (av1_is_compound_reference_allowed(cm)) {
Zoe Liu's avatar
Zoe Liu committed
120
    return aom_rb_read_bit(rb) ? REFERENCE_MODE_SELECT : SINGLE_REFERENCE;
121 122 123 124
  } else {
    return SINGLE_REFERENCE;
  }
}
Jingning Han's avatar
Jingning Han committed
125

126
static void inverse_transform_block(MACROBLOCKD *xd, int plane,
127
                                    const TX_TYPE tx_type,
128
                                    const TX_SIZE tx_size, uint8_t *dst,
129 130
                                    int stride, int16_t scan_line, int eob,
                                    int reduced_tx_set) {
Jingning Han's avatar
Jingning Han committed
131
  struct macroblockd_plane *const pd = &xd->plane[plane];
132
  tran_low_t *const dqcoeff = pd->dqcoeff;
Sebastien Alaiwan's avatar
Sebastien Alaiwan committed
133 134
  av1_inverse_transform_block(xd, dqcoeff, plane, tx_type, tx_size, dst, stride,
                              eob, reduced_tx_set);
135
  memset(dqcoeff, 0, (scan_line + 1) * sizeof(dqcoeff[0]));
Jingning Han's avatar
Jingning Han committed
136 137
}

138 139 140
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) {
141
  PLANE_TYPE plane_type = get_plane_type(plane);
Luc Trudeau's avatar
Luc Trudeau committed
142
  av1_predict_intra_block_facade(cm, xd, plane, col, row, tx_size);
Jingning Han's avatar
Jingning Han committed
143 144

  if (!mbmi->skip) {
145
    struct macroblockd_plane *const pd = &xd->plane[plane];
146 147 148 149
#if TXCOEFF_TIMER
    struct aom_usec_timer timer;
    aom_usec_timer_start(&timer);
#endif
Angie Chiang's avatar
Angie Chiang committed
150 151
#if CONFIG_LV_MAP
    int16_t max_scan_line = 0;
152
    int eob;
Luc Trudeau's avatar
Luc Trudeau committed
153
    av1_read_coeffs_txb_facade(cm, xd, r, row, col, plane, tx_size,
154
                               &max_scan_line, &eob);
155
    // tx_type will be read out in av1_read_coeffs_txb_facade
156 157
    const TX_TYPE tx_type = av1_get_tx_type(plane_type, xd, row, col, tx_size,
                                            cm->reduced_tx_set_used);
Angie Chiang's avatar
Angie Chiang committed
158
#else   // CONFIG_LV_MAP
159 160
    const TX_TYPE tx_type = av1_get_tx_type(plane_type, xd, row, col, tx_size,
                                            cm->reduced_tx_set_used);
Angie Chiang's avatar
Angie Chiang committed
161
    const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, mbmi);
162 163
    int16_t max_scan_line = 0;
    const int eob =
164
        av1_decode_block_tokens(cm, xd, plane, scan_order, col, row, tx_size,
165
                                tx_type, &max_scan_line, r, mbmi->segment_id);
Angie Chiang's avatar
Angie Chiang committed
166
#endif  // CONFIG_LV_MAP
167 168 169 170 171 172 173

#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
174 175 176
    if (eob) {
      uint8_t *dst =
          &pd->dst.buf[(row * pd->dst.stride + col) << tx_size_wide_log2[0]];
177
      inverse_transform_block(xd, plane, tx_type, tx_size, dst, pd->dst.stride,
178
                              max_scan_line, eob, cm->reduced_tx_set_used);
179
    }
Jingning Han's avatar
Jingning Han committed
180
  }
181
#if CONFIG_CFL
182
  if (plane == AOM_PLANE_Y && xd->cfl.store_y && is_cfl_allowed(mbmi)) {
183
    cfl_store_tx(xd, row, col, tx_size, mbmi->sb_type);
184
  }
Sebastien Alaiwan's avatar
Sebastien Alaiwan committed
185
#endif  // CONFIG_CFL
Jingning Han's avatar
Jingning Han committed
186 187
}

Angie Chiang's avatar
Angie Chiang committed
188 189
static void decode_reconstruct_tx(AV1_COMMON *cm, MACROBLOCKD *const xd,
                                  aom_reader *r, MB_MODE_INFO *const mbmi,
190
                                  int plane, BLOCK_SIZE plane_bsize,
191
                                  int blk_row, int blk_col, int block,
Angie Chiang's avatar
Angie Chiang committed
192 193 194 195
                                  TX_SIZE tx_size, int *eob_total, int mi_row,
                                  int mi_col) {
  (void)mi_row;
  (void)mi_col;
196
  const struct macroblockd_plane *const pd = &xd->plane[plane];
197 198
  const int tx_row = blk_row >> (1 - pd->subsampling_y);
  const int tx_col = blk_col >> (1 - pd->subsampling_x);
199
  const TX_SIZE plane_tx_size =
200
      plane ? av1_get_uv_tx_size(mbmi, pd->subsampling_x, pd->subsampling_y)
201
            : mbmi->inter_tx_size[tx_row][tx_col];
202
  // Scale to match transform block unit.
203 204
  const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
  const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
205

206
  if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
207

208
  if (tx_size == plane_tx_size || plane) {
209
    PLANE_TYPE plane_type = get_plane_type(plane);
210 211 212 213
#if TXCOEFF_TIMER
    struct aom_usec_timer timer;
    aom_usec_timer_start(&timer);
#endif
Angie Chiang's avatar
Angie Chiang committed
214 215
#if CONFIG_LV_MAP
    int16_t max_scan_line = 0;
216
    int eob;
Luc Trudeau's avatar
Luc Trudeau committed
217 218
    av1_read_coeffs_txb_facade(cm, xd, r, blk_row, blk_col, plane, tx_size,
                               &max_scan_line, &eob);
219
    // tx_type will be read out in av1_read_coeffs_txb_facade
220 221
    const TX_TYPE tx_type = av1_get_tx_type(plane_type, xd, blk_row, blk_col,
                                            tx_size, cm->reduced_tx_set_used);
Angie Chiang's avatar
Angie Chiang committed
222
#else   // CONFIG_LV_MAP
223 224
    const TX_TYPE tx_type = av1_get_tx_type(plane_type, xd, blk_row, blk_col,
                                            tx_size, cm->reduced_tx_set_used);
225
    const SCAN_ORDER *sc = get_scan(cm, tx_size, tx_type, mbmi);
226
    int16_t max_scan_line = 0;
227 228 229
    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
230
#endif  // CONFIG_LV_MAP
231 232 233 234 235 236 237 238

#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
239
    uint8_t *dst =
240
        &pd->dst
Angie Chiang's avatar
Angie Chiang committed
241 242 243 244 245
             .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;
246
    BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
247 248
    int blk_w = block_size_wide[bsize];
    int blk_h = block_size_high[bsize];
Angie Chiang's avatar
Angie Chiang committed
249 250 251 252 253
    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
254 255
    *eob_total += eob;
  } else {
256
    const TX_SIZE sub_txs = sub_tx_size_map[1][tx_size];
257 258
    assert(IMPLIES(tx_size <= TX_4X4, sub_txs == tx_size));
    assert(IMPLIES(tx_size > TX_4X4, sub_txs < tx_size));
259 260 261
    const int bsw = tx_size_wide_unit[sub_txs];
    const int bsh = tx_size_high_unit[sub_txs];
    const int sub_step = bsw * bsh;
262

263
    assert(bsw > 0 && bsh > 0);
264

265 266 267 268
    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;
269

270
        if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
271

272
        decode_reconstruct_tx(cm, xd, r, mbmi, plane, plane_bsize, offsetr,
Angie Chiang's avatar
Angie Chiang committed
273 274
                              offsetc, block, sub_txs, eob_total, mi_row,
                              mi_col);
275 276
        block += sub_step;
      }
277 278 279
    }
  }
}
Jingning Han's avatar
Jingning Han committed
280

281 282 283
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) {
284 285
  const int num_planes = av1_num_planes(cm);

Jingning Han's avatar
Jingning Han committed
286 287 288 289 290 291 292 293
  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;
294 295 296
#if CONFIG_RD_DEBUG
  xd->mi[0]->mbmi.mi_row = mi_row;
  xd->mi[0]->mbmi.mi_col = mi_col;
297 298
#endif
#if CONFIG_CFL
299 300
  xd->cfl.mi_row = mi_row;
  xd->cfl.mi_col = mi_col;
301
#endif
302 303

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

311 312
  set_plane_n4(xd, bw, bh, num_planes);
  set_skip_context(xd, mi_row, mi_col, num_planes);
Jingning Han's avatar
Jingning Han committed
313

314 315 316
  // 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,
317
#if CONFIG_DEPENDENT_HORZTILES
318 319 320
                 cm->dependent_horz_tiles,
#endif  // CONFIG_DEPENDENT_HORZTILES
                 cm->mi_rows, cm->mi_cols);
Jingning Han's avatar
Jingning Han committed
321

322
  av1_setup_dst_planes(xd->plane, bsize, get_frame_new_buffer(cm), mi_row,
323
                       mi_col, num_planes);
Jingning Han's avatar
Jingning Han committed
324 325
}

326 327
static void decode_mbmi_block(AV1Decoder *const pbi, MACROBLOCKD *const xd,
                              int mi_row, int mi_col, aom_reader *r,
328
#if CONFIG_EXT_PARTITION_TYPES
329
                              PARTITION_TYPE partition,
330
#endif  // CONFIG_EXT_PARTITION_TYPES
331
                              BLOCK_SIZE bsize) {
Yaowu Xu's avatar
Yaowu Xu committed
332
  AV1_COMMON *const cm = &pbi->common;
333 334
  const int bw = mi_size_wide[bsize];
  const int bh = mi_size_high[bsize];
Yaowu Xu's avatar
Yaowu Xu committed
335 336
  const int x_mis = AOMMIN(bw, cm->mi_cols - mi_col);
  const int y_mis = AOMMIN(bh, cm->mi_rows - mi_row);
337

Michael Bebenita's avatar
Michael Bebenita committed
338 339 340
#if CONFIG_ACCOUNTING
  aom_accounting_set_context(&pbi->accounting, mi_col, mi_row);
#endif
341
  set_offsets(cm, xd, bsize, mi_row, mi_col, bw, bh, x_mis, y_mis);
342 343 344
#if CONFIG_EXT_PARTITION_TYPES
  xd->mi[0]->mbmi.partition = partition;
#endif
Yaowu Xu's avatar
Yaowu Xu committed
345
  av1_read_mode_info(pbi, xd, mi_row, mi_col, r, x_mis, y_mis);
Jingning Han's avatar
Jingning Han committed
346 347 348 349
  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
350
      aom_internal_error(xd->error_info, AOM_CODEC_CORRUPT_FRAME,
351
                         "Invalid block size.");
Jingning Han's avatar
Jingning Han committed
352 353
  }

354 355
  int reader_corrupted_flag = aom_reader_has_error(r);
  aom_merge_corrupted_flag(&xd->corrupted, reader_corrupted_flag);
356 357 358 359 360 361 362
}

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;
363
  const int num_planes = av1_num_planes(cm);
364 365 366 367 368
  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);

369 370
  set_offsets(cm, xd, bsize, mi_row, mi_col, bw, bh, x_mis, y_mis);
  MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
371
#if CONFIG_CFL
372
  CFL_CTX *const cfl = &xd->cfl;
373 374
  cfl->is_chroma_reference = is_chroma_reference(
      mi_row, mi_col, bsize, cfl->subsampling_x, cfl->subsampling_y);
375
#endif  // CONFIG_CFL
376

377
  if (cm->delta_q_present_flag) {
378
    for (int i = 0; i < MAX_SEGMENTS; i++) {
Fangwen Fu's avatar
Fangwen Fu committed
379
#if CONFIG_EXT_DELTA_Q
380 381
      const int current_qindex =
          av1_get_qindex(&cm->seg, i, xd->current_qindex);
Fangwen Fu's avatar
Fangwen Fu committed
382
#else
383 384
      const int current_qindex = xd->current_qindex;
#endif  // CONFIG_EXT_DELTA_Q
385
      for (int j = 0; j < num_planes; ++j) {
386 387 388 389 390
        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);
391 392 393 394
        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);
395
      }
396 397
    }
  }
398
  if (mbmi->skip) av1_reset_skip_context(xd, mi_row, mi_col, bsize, num_planes);
399

400
  if (!is_inter_block(mbmi)) {
401
    for (int plane = 0; plane < AOMMIN(2, num_planes); ++plane) {
402
      if (mbmi->palette_mode_info.palette_size[plane])
Yaowu Xu's avatar
Yaowu Xu committed
403
        av1_decode_palette_tokens(xd, plane, r);
Jingning Han's avatar
Jingning Han committed
404
    }
405

406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440
    const struct macroblockd_plane *const y_pd = &xd->plane[0];
    const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, y_pd);
    int row, col;
    const int max_blocks_wide = max_block_wide(xd, plane_bsize, 0);
    const int max_blocks_high = max_block_high(xd, plane_bsize, 0);

    const BLOCK_SIZE max_unit_bsize = get_plane_block_size(BLOCK_64X64, y_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) {
      for (col = 0; col < max_blocks_wide; col += mu_blocks_wide) {
        for (int plane = 0; plane < num_planes; ++plane) {
          const struct macroblockd_plane *const pd = &xd->plane[plane];
          if (!is_chroma_reference(mi_row, mi_col, bsize, pd->subsampling_x,
                                   pd->subsampling_y))
            continue;

          const TX_SIZE tx_size = av1_get_tx_size(plane, xd);
          const int stepr = tx_size_high_unit[tx_size];
          const int stepc = tx_size_wide_unit[tx_size];

          const int unit_height = ROUND_POWER_OF_TWO(
              AOMMIN(mu_blocks_high + row, max_blocks_high), pd->subsampling_y);
          const int unit_width = ROUND_POWER_OF_TWO(
              AOMMIN(mu_blocks_wide + col, max_blocks_wide), pd->subsampling_x);

          for (int blk_row = row >> pd->subsampling_y; blk_row < unit_height;
               blk_row += stepr)
            for (int blk_col = col >> pd->subsampling_x; blk_col < unit_width;
                 blk_col += stepc)
441 442 443 444
              predict_and_reconstruct_intra_block(cm, xd, r, mbmi, plane,
                                                  blk_row, blk_col, tx_size);
        }
      }
445 446
    }
  } else {
447
    for (int ref = 0; ref < 1 + has_second_ref(mbmi); ++ref) {
448
      const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
Alex Converse's avatar
Alex Converse committed
449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464
      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,
465
                             &ref_buf->sf, num_planes);
Alex Converse's avatar
Alex Converse committed
466
      }
467
    }
468

469
    av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize);
470

Yue Chen's avatar
Yue Chen committed
471
    if (mbmi->motion_mode == OBMC_CAUSAL) {
472
      av1_build_obmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
473
    }
Angie Chiang's avatar
Angie Chiang committed
474 475

#if CONFIG_MISMATCH_DEBUG
476
    for (int plane = 0; plane < num_planes; ++plane) {
Angie Chiang's avatar
Angie Chiang committed
477 478 479 480 481 482 483 484 485 486 487 488
      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

489 490 491
    // Reconstruction
    if (!mbmi->skip) {
      int eobtotal = 0;
492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508

      const struct macroblockd_plane *const y_pd = &xd->plane[0];
      const int max_blocks_wide = max_block_wide(xd, bsize, 0);
      const int max_blocks_high = max_block_high(xd, bsize, 0);
      int row, col;

      const BLOCK_SIZE max_unit_bsize = get_plane_block_size(BLOCK_64X64, y_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) {
        for (col = 0; col < max_blocks_wide; col += mu_blocks_wide) {
509
          for (int plane = 0; plane < num_planes; ++plane) {
510 511 512 513 514 515 516 517 518 519 520 521 522 523 524
            const struct macroblockd_plane *const pd = &xd->plane[plane];
            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);
            const BLOCK_SIZE plane_bsize = get_plane_block_size(bsizec, pd);

            TX_SIZE max_tx_size = get_vartx_max_txsize(
                xd, plane_bsize, pd->subsampling_x || pd->subsampling_y);
            const int bh_var_tx = tx_size_high_unit[max_tx_size];
            const int bw_var_tx = tx_size_wide_unit[max_tx_size];
            int block = 0;
            int step =
                tx_size_wide_unit[max_tx_size] * tx_size_high_unit[max_tx_size];
525
            int blk_row, blk_col;
526 527 528 529 530 531 532 533 534 535 536
            const int unit_height = ROUND_POWER_OF_TWO(
                AOMMIN(mu_blocks_high + row, max_blocks_high),
                pd->subsampling_y);
            const int unit_width = ROUND_POWER_OF_TWO(
                AOMMIN(mu_blocks_wide + col, max_blocks_wide),
                pd->subsampling_x);

            for (blk_row = row >> pd->subsampling_y; blk_row < unit_height;
                 blk_row += bh_var_tx) {
              for (blk_col = col >> pd->subsampling_x; blk_col < unit_width;
                   blk_col += bw_var_tx) {
537 538
                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
539
                                      &eobtotal, mi_row, mi_col);
540 541 542
                block += step;
              }
            }
543 544
          }
        }
545
      }
Jingning Han's avatar
Jingning Han committed
546 547
    }
  }
548
#if CONFIG_CFL
549
  if (mbmi->uv_mode != UV_CFL_PRED) {
550
    if (!cfl->is_chroma_reference && is_inter_block(mbmi) &&
551
        is_cfl_allowed(mbmi)) {
552 553 554
      cfl_store_block(xd, mbmi->sb_type, mbmi->tx_size);
    }
  }
555
#endif  // CONFIG_CFL
Jingning Han's avatar
Jingning Han committed
556

557 558
  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
559 560
}

561 562 563 564 565 566
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) {
567
  decode_mbmi_block(pbi, xd, mi_row, mi_col, r,
568 569 570 571
#if CONFIG_EXT_PARTITION_TYPES
                    partition,
#endif
                    bsize);
572

573
  decode_token_and_recon_block(pbi, xd, mi_row, mi_col, r, bsize);
574 575
}

576 577
static PARTITION_TYPE read_partition(MACROBLOCKD *xd, int mi_row, int mi_col,
                                     aom_reader *r, int has_rows, int has_cols,
578 579
                                     BLOCK_SIZE bsize) {
  const int ctx = partition_plane_context(xd, mi_row, mi_col, bsize);
580
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
Jingning Han's avatar
Jingning Han committed
581

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

584 585
  assert(ctx >= 0);
  aom_cdf_prob *partition_cdf = ec_ctx->partition_cdf[ctx];
586
  if (has_rows && has_cols) {
587 588
    return (PARTITION_TYPE)aom_read_symbol(
        r, partition_cdf, partition_cdf_length(bsize), ACCT_STR);
589
  } else if (!has_rows && has_cols) {
590 591
    assert(bsize > BLOCK_8X8);
    aom_cdf_prob cdf[2];
592
    partition_gather_vert_alike(cdf, partition_cdf, bsize);
593
    assert(cdf[1] == AOM_ICDF(CDF_PROB_TOP));
594 595 596
    return aom_read_cdf(r, cdf, 2, ACCT_STR) ? PARTITION_SPLIT : PARTITION_HORZ;
  } else {
    assert(has_rows && !has_cols);
597 598
    assert(bsize > BLOCK_8X8);
    aom_cdf_prob cdf[2];
599
    partition_gather_horz_alike(cdf, partition_cdf, bsize);
600
    assert(cdf[1] == AOM_ICDF(CDF_PROB_TOP));
601
    return aom_read_cdf(r, cdf, 2, ACCT_STR) ? PARTITION_SPLIT : PARTITION_VERT;
602
  }
Jingning Han's avatar
Jingning Han committed
603 604 605
}

// TODO(slavarnway): eliminate bsize and subsize in future commits
Yaowu Xu's avatar
Yaowu Xu committed
606 607
static void decode_partition(AV1Decoder *const pbi, MACROBLOCKD *const xd,
                             int mi_row, int mi_col, aom_reader *r,
608
                             BLOCK_SIZE bsize) {
Yaowu Xu's avatar
Yaowu Xu committed
609
  AV1_COMMON *const cm = &pbi->common;
610
  const int num_planes = av1_num_planes(cm);
611
  const int num_8x8_wh = mi_size_wide[bsize];
Jingning Han's avatar
Jingning Han committed
612 613 614
  const int hbs = num_8x8_wh >> 1;
  PARTITION_TYPE partition;
  BLOCK_SIZE subsize;
615
#if CONFIG_EXT_PARTITION_TYPES
616
  const int quarter_step = num_8x8_wh / 4;
617
  BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
618
#endif
Jingning Han's avatar
Jingning Han committed
619 620 621
  const int has_rows = (mi_row + hbs) < cm->mi_rows;
  const int has_cols = (mi_col + hbs) < cm->mi_cols;

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

624
#if CONFIG_LOOP_RESTORATION
625
  for (int plane = 0; plane < num_planes; ++plane) {
626 627 628 629 630 631 632 633 634 635 636 637 638 639 640
    int rcol0, rcol1, rrow0, rrow1, tile_tl_idx;
    if (av1_loop_restoration_corners_in_sb(cm, plane, mi_row, mi_col, bsize,
                                           &rcol0, &rcol1, &rrow0, &rrow1,
                                           &tile_tl_idx)) {
      const int rstride = cm->rst_info[plane].horz_units_per_tile;
      for (int rrow = rrow0; rrow < rrow1; ++rrow) {
        for (int rcol = rcol0; rcol < rcol1; ++rcol) {
          const int rtile_idx = tile_tl_idx + rcol + rrow * rstride;
          loop_restoration_read_sb_coeffs(cm, xd, r, plane, rtile_idx);
        }
      }
    }
  }
#endif

641
  partition = (bsize < BLOCK_8X8) ? PARTITION_NONE
642
                                  : read_partition(xd, mi_row, mi_col, r,
643
                                                   has_rows, has_cols, bsize);
Jingning Han's avatar
Jingning Han committed
644
  subsize = subsize_lookup[partition][bsize];  // get_subsize(bsize, partition);
645

646 647 648 649 650 651 652 653 654
  // 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]);
  }

655 656 657 658 659 660 661 662 663 664 665 666
#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))

667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682
  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;
683
#if CONFIG_EXT_PARTITION_TYPES
684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704
    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;
    case PARTITION_HORZ_4:
705
      for (int i = 0; i < 4; ++i) {
706 707 708 709 710 711
        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:
712
      for (int i = 0; i < 4; ++i) {
713 714 715 716 717
        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;
718
#endif  // CONFIG_EXT_PARTITION_TYPES
719
    default: assert(0 && "Invalid partition type");
Jingning Han's avatar
Jingning Han committed
720 721
  }

722 723 724 725 726
#undef DEC_PARTITION
#undef DEC_BLOCK
#undef DEC_BLOCK_EPT_ARG
#undef DEC_BLOCK_STX_ARG

727
#if CONFIG_EXT_PARTITION_TYPES
728
  update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize, partition);
729
#else
Jingning Han's avatar
Jingning Han committed
730 731 732
  // update partition context
  if (bsize >= BLOCK_8X8 &&
      (bsize == BLOCK_8X8 || partition != PARTITION_SPLIT))
733
    update_partition_context(xd, mi_row, mi_col, subsize, bsize);
734
#endif  // CONFIG_EXT_PARTITION_TYPES
Jingning Han's avatar
Jingning Han committed
735 736
}

737
static void setup_bool_decoder(const uint8_t *data, const uint8_t *data_end,
Alex Converse's avatar
Alex Converse committed
738
                               const size_t read_size,
Yaowu Xu's avatar
Yaowu Xu committed
739
                               struct aom_internal_error_info *error_info,
740
                               aom_reader *r, uint8_t allow_update_cdf) {
Alex Converse's avatar
Alex Converse committed
741 742 743 744
  // Validate the calculated partition length. If the buffer
  // described by the partition can't be fully read, then restrict
  // it to the portion that can be (for EC mode) or throw an error.
  if (!read_is_valid(data, read_size, data_end))
Yaowu Xu's avatar
Yaowu Xu committed
745
    aom_internal_error(error_info, AOM_CODEC_CORRUPT_FRAME,
Alex Converse's avatar
Alex Converse committed
746 747
                       "Truncated packet or corrupt tile length");

748
  if (aom_reader_init(r, data, read_size))
Yaowu Xu's avatar
Yaowu Xu committed
749
    aom_internal_error(error_info, AOM_CODEC_MEM_ERROR,
Alex Converse's avatar
Alex Converse committed
750
                       "Failed to allocate bool decoder %d", 1);
751 752

  r->allow_update_cdf = allow_update_cdf;
Alex Converse's avatar
Alex Converse committed
753
}
Jingning Han's avatar
Jingning Han committed
754

Yaowu Xu's avatar
Yaowu Xu committed
755 756
static void setup_segmentation(AV1_COMMON *const cm,
                               struct aom_read_bit_buffer *rb) {
757
  struct segmentation *const seg = &cm->seg;
Jingning Han's avatar
Jingning Han committed
758 759 760

  seg->update_map = 0;
  seg->update_data = 0;
761
  seg->temporal_update = 0;
Jingning Han's avatar
Jingning Han committed
762

Yaowu Xu's avatar
Yaowu Xu committed
763
  seg->enabled = aom_rb_read_bit(rb);
764
  if (!seg->enabled) return;
765 766 767 768
#if CONFIG_SEGMENT_PRED_LAST
  if (cm->seg.enabled && !cm->frame_parallel_decode && cm->prev_frame)
    cm->last_frame_seg_map = cm->prev_frame->seg_map;
#endif
Jingning Han's avatar
Jingning Han committed
769
  // Segmentation map update
770 771 772
  if (frame_is_intra_only(cm) || cm->error_resilient_mode) {
    seg->update_map = 1;
  } else {
Yaowu Xu's avatar
Yaowu Xu committed
773
    seg->update_map = aom_rb_read_bit(rb);
774
  }
Jingning Han's avatar
Jingning Han committed
775
  if (seg->update_map) {
776 777 778
    if (frame_is_intra_only(cm) || cm->error_resilient_mode) {
      seg->temporal_update = 0;
    } else {
Yaowu Xu's avatar
Yaowu Xu committed
779
      seg->temporal_update = aom_rb_read_bit(rb);
780
    }
Jingning Han's avatar
Jingning Han committed
781 782
  }

783 784 785 786
#if CONFIG_SPATIAL_SEGMENTATION
  cm->preskip_segid = 0;
#endif

Jingning Han's avatar
Jingning Han committed
787
  // Segmentation data update
Yaowu Xu's avatar
Yaowu Xu committed
788
  seg->update_data = aom_rb_read_bit(rb);
Jingning Han's avatar
Jingning Han committed
789
  if (seg->update_data) {
Yaowu Xu's avatar
Yaowu Xu committed
790
    av1_clearall_segfeatures(seg);
Jingning Han's avatar
Jingning Han committed
791

792 793
    for (int i = 0; i < MAX_SEGMENTS; i++) {
      for (int j = 0; j < SEG_LVL_MAX; j++) {
Jingning Han's avatar
Jingning Han committed
794
        int data = 0;
Yaowu Xu's avatar
Yaowu Xu committed
795
        const int feature_enabled = aom_rb_read_bit(rb);
Jingning Han's avatar
Jingning Han committed
796
        if (feature_enabled) {
797 798 799 800
#if CONFIG_SPATIAL_SEGMENTATION
          cm->preskip_segid |= j >= SEG_LVL_REF_FRAME;
          cm->last_active_segid = i;
#endif
Yaowu Xu's avatar
Yaowu Xu committed
801
          av1_enable_segfeature(seg, i, j);
802 803 804 805 806 807 808 809 810 811 812 813

          const int data_max = av1_seg_feature_data_max(j);
          const int data_min = -data_max;
          const int ubits = get_unsigned_bits(data_max);

          if (av1_is_segfeature_signed(j)) {
            data = aom_rb_read_inv_signed_literal(rb, ubits);
          } else {
            data = aom_rb_read_literal(rb, ubits);
          }

          data = clamp(data, data_min, data_max);
Jingning Han's avatar
Jingning Han committed
814
        }
Yaowu Xu's avatar
Yaowu Xu committed
815
        av1_set_segdata(seg, i, j, data);