decodeframe.c 134 KB
Newer Older
1
/*
2
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
3
 *
4 5 6 7 8 9
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10 11 12 13
 */

#include <assert.h>

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"
18

19
#include "aom/aom_codec.h"
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"
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"
28 29
#include "aom_scale/aom_scale.h"
#include "aom_util/aom_thread.h"
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"
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

65
#define MAX_AV1_HEADER_SIZE 80
Michael Bebenita's avatar
Michael Bebenita committed
66
#define ACCT_STR __func__
67

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

72 73 74 75 76 77 78
#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

79
static void setup_compound_reference_mode(AV1_COMMON *cm) {
80
  cm->comp_fwd_ref[0] = LAST_FRAME;
81 82 83 84
  cm->comp_fwd_ref[1] = LAST2_FRAME;
  cm->comp_fwd_ref[2] = LAST3_FRAME;
  cm->comp_fwd_ref[3] = GOLDEN_FRAME;

85
  cm->comp_bwd_ref[0] = BWDREF_FRAME;
Zoe Liu's avatar
Zoe Liu committed
86 87
  cm->comp_bwd_ref[1] = ALTREF2_FRAME;
  cm->comp_bwd_ref[2] = ALTREF_FRAME;
88 89 90 91 92 93
}

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

94 95 96 97
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;
}
98

99
static REFERENCE_MODE read_frame_reference_mode(
100
    const AV1_COMMON *cm, struct aom_read_bit_buffer *rb) {
101
  if (av1_is_compound_reference_allowed(cm)) {
102
    return aom_rb_read_bit(rb) ? REFERENCE_MODE_SELECT : SINGLE_REFERENCE;
103 104 105 106
  } else {
    return SINGLE_REFERENCE;
  }
}
107

108
static void inverse_transform_block(MACROBLOCKD *xd, int plane,
109
                                    const TX_TYPE tx_type,
110
                                    const TX_SIZE tx_size, uint8_t *dst,
111 112
                                    int stride, int16_t scan_line, int eob,
                                    int reduced_tx_set) {
113
  struct macroblockd_plane *const pd = &xd->plane[plane];
114
  tran_low_t *const dqcoeff = pd->dqcoeff;
115 116
  av1_inverse_transform_block(xd, dqcoeff, plane, tx_type, tx_size, dst, stride,
                              eob, reduced_tx_set);
117
  memset(dqcoeff, 0, (scan_line + 1) * sizeof(dqcoeff[0]));
118 119
}

120 121 122
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) {
123
  PLANE_TYPE plane_type = get_plane_type(plane);
124
  av1_predict_intra_block_facade(cm, xd, plane, col, row, tx_size);
125 126

  if (!mbmi->skip) {
127
    struct macroblockd_plane *const pd = &xd->plane[plane];
128 129 130 131
#if TXCOEFF_TIMER
    struct aom_usec_timer timer;
    aom_usec_timer_start(&timer);
#endif
132 133
#if CONFIG_LV_MAP
    int16_t max_scan_line = 0;
134
    int eob;
135
    av1_read_coeffs_txb_facade(cm, xd, r, row, col, plane, tx_size,
136
                               &max_scan_line, &eob);
137
    // tx_type will be read out in av1_read_coeffs_txb_facade
138 139
    const TX_TYPE tx_type = av1_get_tx_type(plane_type, xd, row, col, tx_size,
                                            cm->reduced_tx_set_used);
140
#else   // CONFIG_LV_MAP
141 142
    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
143
    const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, mbmi);
144 145
    int16_t max_scan_line = 0;
    const int eob =
146
        av1_decode_block_tokens(cm, xd, plane, scan_order, col, row, tx_size,
147
                                tx_type, &max_scan_line, r, mbmi->segment_id);
148
#endif  // CONFIG_LV_MAP
149 150 151 152 153 154 155

#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
156 157 158
    if (eob) {
      uint8_t *dst =
          &pd->dst.buf[(row * pd->dst.stride + col) << tx_size_wide_log2[0]];
159
      inverse_transform_block(xd, plane, tx_type, tx_size, dst, pd->dst.stride,
160
                              max_scan_line, eob, cm->reduced_tx_set_used);
161
    }
162
  }
163
#if CONFIG_CFL
164
  if (plane == AOM_PLANE_Y && xd->cfl.store_y && is_cfl_allowed(mbmi)) {
165
    cfl_store_tx(xd, row, col, tx_size, mbmi->sb_type);
166
  }
Sebastien Alaiwan's avatar
Sebastien Alaiwan committed
167
#endif  // CONFIG_CFL
168 169
}

170 171
static void decode_reconstruct_tx(AV1_COMMON *cm, MACROBLOCKD *const xd,
                                  aom_reader *r, MB_MODE_INFO *const mbmi,
172
                                  int plane, BLOCK_SIZE plane_bsize,
173
                                  int blk_row, int blk_col, int block,
Angie Chiang's avatar
Angie Chiang committed
174 175 176 177
                                  TX_SIZE tx_size, int *eob_total, int mi_row,
                                  int mi_col) {
  (void)mi_row;
  (void)mi_col;
178
  const struct macroblockd_plane *const pd = &xd->plane[plane];
179
  const TX_SIZE plane_tx_size =
180
      plane ? av1_get_uv_tx_size(mbmi, pd->subsampling_x, pd->subsampling_y)
181 182
            : mbmi->inter_tx_size[av1_get_txb_size_index(plane_bsize, blk_row,
                                                         blk_col)];
183
  // Scale to match transform block unit.
184 185
  const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
  const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
186

187
  if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
188

189
  if (tx_size == plane_tx_size || plane) {
190
    PLANE_TYPE plane_type = get_plane_type(plane);
191 192 193 194
#if TXCOEFF_TIMER
    struct aom_usec_timer timer;
    aom_usec_timer_start(&timer);
#endif
195 196
#if CONFIG_LV_MAP
    int16_t max_scan_line = 0;
197
    int eob;
198 199
    av1_read_coeffs_txb_facade(cm, xd, r, blk_row, blk_col, plane, tx_size,
                               &max_scan_line, &eob);
200
    // tx_type will be read out in av1_read_coeffs_txb_facade
201 202
    const TX_TYPE tx_type = av1_get_tx_type(plane_type, xd, blk_row, blk_col,
                                            tx_size, cm->reduced_tx_set_used);
203
#else   // CONFIG_LV_MAP
204 205
    const TX_TYPE tx_type = av1_get_tx_type(plane_type, xd, blk_row, blk_col,
                                            tx_size, cm->reduced_tx_set_used);
206
    const SCAN_ORDER *sc = get_scan(cm, tx_size, tx_type, mbmi);
207
    int16_t max_scan_line = 0;
208 209 210
    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);
211
#endif  // CONFIG_LV_MAP
212 213 214 215 216 217 218 219

#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
220
    uint8_t *dst =
221
        &pd->dst
Angie Chiang's avatar
Angie Chiang committed
222 223 224 225 226
             .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;
227
    BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
228 229
    int blk_w = block_size_wide[bsize];
    int blk_h = block_size_high[bsize];
Angie Chiang's avatar
Angie Chiang committed
230 231
    mi_to_pixel_loc(&pixel_c, &pixel_r, mi_col, mi_row, blk_col, blk_row,
                    pd->subsampling_x, pd->subsampling_y);
232 233 234
    mismatch_check_block_tx(dst, pd->dst.stride, cm->frame_offset, plane,
                            pixel_c, pixel_r, blk_w, blk_h,
                            xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH);
Angie Chiang's avatar
Angie Chiang committed
235
#endif
236 237
    *eob_total += eob;
  } else {
238
    const TX_SIZE sub_txs = sub_tx_size_map[1][tx_size];
239 240
    assert(IMPLIES(tx_size <= TX_4X4, sub_txs == tx_size));
    assert(IMPLIES(tx_size > TX_4X4, sub_txs < tx_size));
241 242 243
    const int bsw = tx_size_wide_unit[sub_txs];
    const int bsh = tx_size_high_unit[sub_txs];
    const int sub_step = bsw * bsh;
244

245
    assert(bsw > 0 && bsh > 0);
246

247 248 249 250
    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;
251

252
        if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
253

254
        decode_reconstruct_tx(cm, xd, r, mbmi, plane, plane_bsize, offsetr,
Angie Chiang's avatar
Angie Chiang committed
255 256
                              offsetc, block, sub_txs, eob_total, mi_row,
                              mi_col);
257 258
        block += sub_step;
      }
259 260 261
    }
  }
}
262

263 264 265
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) {
266 267
  const int num_planes = av1_num_planes(cm);

268 269 270 271 272 273 274 275
  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;
276 277 278
#if CONFIG_RD_DEBUG
  xd->mi[0]->mbmi.mi_row = mi_row;
  xd->mi[0]->mbmi.mi_col = mi_col;
279 280
#endif
#if CONFIG_CFL
281 282
  xd->cfl.mi_row = mi_row;
  xd->cfl.mi_col = mi_col;
283
#endif
284 285

  assert(x_mis && y_mis);
286
  for (int x = 1; x < x_mis; ++x) xd->mi[x] = xd->mi[0];
287
  int idx = cm->mi_stride;
288
  for (int y = 1; y < y_mis; ++y) {
289 290 291
    memcpy(&xd->mi[idx], &xd->mi[0], x_mis * sizeof(xd->mi[0]));
    idx += cm->mi_stride;
  }
292

293 294
  set_plane_n4(xd, bw, bh, num_planes);
  set_skip_context(xd, mi_row, mi_col, num_planes);
295

296 297 298
  // 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,
299
#if CONFIG_DEPENDENT_HORZTILES
300 301 302
                 cm->dependent_horz_tiles,
#endif  // CONFIG_DEPENDENT_HORZTILES
                 cm->mi_rows, cm->mi_cols);
303

304
  av1_setup_dst_planes(xd->plane, bsize, get_frame_new_buffer(cm), mi_row,
305
                       mi_col, num_planes);
306 307
}

308 309
static void decode_mbmi_block(AV1Decoder *const pbi, MACROBLOCKD *const xd,
                              int mi_row, int mi_col, aom_reader *r,
310
#if CONFIG_EXT_PARTITION_TYPES
311
                              PARTITION_TYPE partition,
312
#endif  // CONFIG_EXT_PARTITION_TYPES
313
                              BLOCK_SIZE bsize) {
314
  AV1_COMMON *const cm = &pbi->common;
315 316
  const int bw = mi_size_wide[bsize];
  const int bh = mi_size_high[bsize];
317 318
  const int x_mis = AOMMIN(bw, cm->mi_cols - mi_col);
  const int y_mis = AOMMIN(bh, cm->mi_rows - mi_row);
319

Michael Bebenita's avatar
Michael Bebenita committed
320 321 322
#if CONFIG_ACCOUNTING
  aom_accounting_set_context(&pbi->accounting, mi_col, mi_row);
#endif
323
  set_offsets(cm, xd, bsize, mi_row, mi_col, bw, bh, x_mis, y_mis);
324 325 326
#if CONFIG_EXT_PARTITION_TYPES
  xd->mi[0]->mbmi.partition = partition;
#endif
327
  av1_read_mode_info(pbi, xd, mi_row, mi_col, r, x_mis, y_mis);
328 329 330 331
  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)
332
      aom_internal_error(xd->error_info, AOM_CODEC_CORRUPT_FRAME,
333
                         "Invalid block size.");
334 335
  }

336 337
  int reader_corrupted_flag = aom_reader_has_error(r);
  aom_merge_corrupted_flag(&xd->corrupted, reader_corrupted_flag);
338 339 340 341 342 343 344
}

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;
345
  const int num_planes = av1_num_planes(cm);
346 347 348 349 350
  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);

351 352
  set_offsets(cm, xd, bsize, mi_row, mi_col, bw, bh, x_mis, y_mis);
  MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
353
#if CONFIG_CFL
354
  CFL_CTX *const cfl = &xd->cfl;
355 356
  cfl->is_chroma_reference = is_chroma_reference(
      mi_row, mi_col, bsize, cfl->subsampling_x, cfl->subsampling_y);
357
#endif  // CONFIG_CFL
358

359
  if (cm->delta_q_present_flag) {
360
    for (int i = 0; i < MAX_SEGMENTS; i++) {
361
#if CONFIG_EXT_DELTA_Q
362 363
      const int current_qindex =
          av1_get_qindex(&cm->seg, i, xd->current_qindex);
364
#else
365 366
      const int current_qindex = xd->current_qindex;
#endif  // CONFIG_EXT_DELTA_Q
367
      for (int j = 0; j < num_planes; ++j) {
368 369 370 371 372
        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);
373 374 375 376
        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);
377
      }
378 379
    }
  }
380
  if (mbmi->skip) av1_reset_skip_context(xd, mi_row, mi_col, bsize, num_planes);
381

382
  if (!is_inter_block(mbmi)) {
383
    for (int plane = 0; plane < AOMMIN(2, num_planes); ++plane) {
384
      if (mbmi->palette_mode_info.palette_size[plane])
385
        av1_decode_palette_tokens(xd, plane, r);
386
    }
387

388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422
    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)
423 424 425 426
              predict_and_reconstruct_intra_block(cm, xd, r, mbmi, plane,
                                                  blk_row, blk_col, tx_size);
        }
      }
427 428
    }
  } else {
429
    for (int ref = 0; ref < 1 + has_second_ref(mbmi); ++ref) {
430
      const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446
      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,
447
                             &ref_buf->sf, num_planes);
448
      }
449
    }
450

451
    av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize);
452

Yue Chen's avatar
Yue Chen committed
453
    if (mbmi->motion_mode == OBMC_CAUSAL) {
454
      av1_build_obmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
455
    }
Angie Chiang's avatar
Angie Chiang committed
456 457

#if CONFIG_MISMATCH_DEBUG
458
    for (int plane = 0; plane < num_planes; ++plane) {
Angie Chiang's avatar
Angie Chiang committed
459 460 461 462 463 464 465
      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;
466 467
      mismatch_check_block_pre(pd->dst.buf, pd->dst.stride, cm->frame_offset,
                               plane, pixel_c, pixel_r, pd->width, pd->height,
468
                               xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH);
Angie Chiang's avatar
Angie Chiang committed
469 470 471
    }
#endif

472 473 474
    // Reconstruction
    if (!mbmi->skip) {
      int eobtotal = 0;
475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491

      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) {
492
          for (int plane = 0; plane < num_planes; ++plane) {
493 494 495 496 497 498 499 500 501 502 503 504 505 506 507
            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];
508
            int blk_row, blk_col;
509 510 511 512 513 514 515 516 517 518 519
            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) {
520 521
                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
522
                                      &eobtotal, mi_row, mi_col);
523 524 525
                block += step;
              }
            }
526 527
          }
        }
528
      }
529 530
    }
  }
531
#if CONFIG_CFL
532
  if (mbmi->uv_mode != UV_CFL_PRED) {
533
    if (!cfl->is_chroma_reference && is_inter_block(mbmi) &&
534
        is_cfl_allowed(mbmi)) {
535 536 537
      cfl_store_block(xd, mbmi->sb_type, mbmi->tx_size);
    }
  }
538
#endif  // CONFIG_CFL
539

540 541
  int reader_corrupted_flag = aom_reader_has_error(r);
  aom_merge_corrupted_flag(&xd->corrupted, reader_corrupted_flag);
542 543
}

544 545 546 547 548 549
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) {
550
  decode_mbmi_block(pbi, xd, mi_row, mi_col, r,
551 552 553 554
#if CONFIG_EXT_PARTITION_TYPES
                    partition,
#endif
                    bsize);
555
  decode_token_and_recon_block(pbi, xd, mi_row, mi_col, r, bsize);
556 557
}

558 559
static PARTITION_TYPE read_partition(MACROBLOCKD *xd, int mi_row, int mi_col,
                                     aom_reader *r, int has_rows, int has_cols,
560 561
                                     BLOCK_SIZE bsize) {
  const int ctx = partition_plane_context(xd, mi_row, mi_col, bsize);
562
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
563

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

566 567
  assert(ctx >= 0);
  aom_cdf_prob *partition_cdf = ec_ctx->partition_cdf[ctx];
568
  if (has_rows && has_cols) {
569 570
    return (PARTITION_TYPE)aom_read_symbol(
        r, partition_cdf, partition_cdf_length(bsize), ACCT_STR);
571
  } else if (!has_rows && has_cols) {
572 573
    assert(bsize > BLOCK_8X8);
    aom_cdf_prob cdf[2];
574
    partition_gather_vert_alike(cdf, partition_cdf, bsize);
575
    assert(cdf[1] == AOM_ICDF(CDF_PROB_TOP));
576 577 578
    return aom_read_cdf(r, cdf, 2, ACCT_STR) ? PARTITION_SPLIT : PARTITION_HORZ;
  } else {
    assert(has_rows && !has_cols);
579 580
    assert(bsize > BLOCK_8X8);
    aom_cdf_prob cdf[2];
581
    partition_gather_horz_alike(cdf, partition_cdf, bsize);
582
    assert(cdf[1] == AOM_ICDF(CDF_PROB_TOP));
583
    return aom_read_cdf(r, cdf, 2, ACCT_STR) ? PARTITION_SPLIT : PARTITION_VERT;
584
  }
585 586 587
}

// TODO(slavarnway): eliminate bsize and subsize in future commits
588 589
static void decode_partition(AV1Decoder *const pbi, MACROBLOCKD *const xd,
                             int mi_row, int mi_col, aom_reader *r,
590
                             BLOCK_SIZE bsize) {
591
  AV1_COMMON *const cm = &pbi->common;
592
  const int num_8x8_wh = mi_size_wide[bsize];
593 594 595
  const int hbs = num_8x8_wh >> 1;
  PARTITION_TYPE partition;
  BLOCK_SIZE subsize;
596
#if CONFIG_EXT_PARTITION_TYPES
597
  const int quarter_step = num_8x8_wh / 4;
598
  BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
599
#endif
600 601 602
  const int has_rows = (mi_row + hbs) < cm->mi_rows;
  const int has_cols = (mi_col + hbs) < cm->mi_cols;

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

605
#if CONFIG_LOOP_RESTORATION
606
  const int num_planes = av1_num_planes(cm);
607
  for (int plane = 0; plane < num_planes; ++plane) {
608 609 610 611 612 613 614 615 616 617 618 619 620 621 622
    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

623
  partition = (bsize < BLOCK_8X8) ? PARTITION_NONE
624
                                  : read_partition(xd, mi_row, mi_col, r,
625
                                                   has_rows, has_cols, bsize);
626
  subsize = subsize_lookup[partition][bsize];  // get_subsize(bsize, partition);
627

628 629 630 631 632 633 634 635 636
  // 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]);
  }

637 638 639 640 641 642 643 644 645 646 647 648
#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))

649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664
  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;
665
#if CONFIG_EXT_PARTITION_TYPES
666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686
    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:
687
      for (int i = 0; i < 4; ++i) {
688 689 690 691 692 693
        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:
694
      for (int i = 0; i < 4; ++i) {
695 696 697 698 699
        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;
700
#endif  // CONFIG_EXT_PARTITION_TYPES
701
    default: assert(0 && "Invalid partition type");
702 703
  }

704 705 706 707 708
#undef DEC_PARTITION
#undef DEC_BLOCK
#undef DEC_BLOCK_EPT_ARG
#undef DEC_BLOCK_STX_ARG

709
#if CONFIG_EXT_PARTITION_TYPES
710
  update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize, partition);
711
#else
712 713 714
  // update partition context
  if (bsize >= BLOCK_8X8 &&
      (bsize == BLOCK_8X8 || partition != PARTITION_SPLIT))
715
    update_partition_context(xd, mi_row, mi_col, subsize, bsize);
716
#endif  // CONFIG_EXT_PARTITION_TYPES
717 718
}

719
static void setup_bool_decoder(const uint8_t *data, const uint8_t *data_end,
Alex Converse's avatar
Alex Converse committed
720
                               const size_t read_size,
721
                               struct aom_internal_error_info *error_info,
722
                               aom_reader *r, uint8_t allow_update_cdf) {
Alex Converse's avatar
Alex Converse committed
723 724 725 726
  // 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))
727
    aom_internal_error(error_info, AOM_CODEC_CORRUPT_FRAME,
Alex Converse's avatar
Alex Converse committed
728 729
                       "Truncated packet or corrupt tile length");

730
  if (aom_reader_init(r, data, read_size))
731
    aom_internal_error(error_info, AOM_CODEC_MEM_ERROR,
Alex Converse's avatar
Alex Converse committed
732
                       "Failed to allocate bool decoder %d", 1);
733 734

  r->allow_update_cdf = allow_update_cdf;
Alex Converse's avatar
Alex Converse committed
735
}
736

737 738
static void setup_segmentation(AV1_COMMON *const cm,
                               struct aom_read_bit_buffer *rb) {
739
  struct segmentation *const seg = &cm->seg;
740 741 742

  seg->update_map = 0;
  seg->update_data = 0;
743
  seg->temporal_update = 0;
744

745
  seg->enabled = aom_rb_read_bit(rb);
746 747 748 749 750 751 752
  if (!seg->enabled) {
#if CONFIG_SEGMENT_PRED_LAST
    if (cm->cur_frame->seg_map)
      memset(cm->cur_frame->seg_map, 0, (cm->mi_rows * cm->mi_cols));
#endif  // CONFIG_SEGMENT_PRED_LAST
    return;
  }
753
#if CONFIG_SEGMENT_PRED_LAST
754 755 756
  if (cm->seg.enabled && !cm->frame_parallel_decode && cm->prev_frame &&
      (cm->mi_rows == cm->prev_frame->mi_rows) &&
      (cm->mi_cols == cm->prev_frame->mi_cols)) {
757
    cm->last_frame_seg_map = cm->prev_frame->seg_map;
758 759 760
  } else {
    cm->last_frame_seg_map = NULL;
  }
761
#endif
762
  // Segmentation map update
763 764 765
  if (frame_is_intra_only(cm) || cm->error_resilient_mode) {
    seg->update_map = 1;
  } else {
766
    seg->update_map = aom_rb_read_bit(rb);
767
  }
768
  if (seg->update_map) {
769 770 771
    if (frame_is_intra_only(cm) || cm->error_resilient_mode) {
      seg->temporal_update = 0;
    } else {
772
      seg->temporal_update = aom_rb_read_bit(rb);
773
    }
774 775
  }

776 777 778 779
#if CONFIG_SPATIAL_SEGMENTATION
  cm->preskip_segid = 0;
#endif

780
  // Segmentation data update
781
  seg->update_data = aom_rb_read_bit(rb);
782
  if (seg->update_data) {
783
    av1_clearall_segfeatures(seg);
784

785 786
    for (int i = 0; i < MAX_SEGMENTS; i++) {
      for (int j = 0; j < SEG_LVL_MAX; j++) {
787
        int data = 0;
788
        const int feature_enabled = aom_rb_read_bit(rb);
789
        if (feature_enabled) {
790 791 792 793
#if CONFIG_SPATIAL_SEGMENTATION
          cm->preskip_segid |= j >= SEG_LVL_REF_FRAME;
          cm->last_active_segid = i;
#endif
794
          av1_enable_segfeature(seg, i, j);
795 796 797 798 799 800 801 802 803 804 805 806

          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);
807
        }
808
        av1_set_segdata(seg, i, j, data);
809 810 811 812 813
      }
    }
  }
}

814
#if CONFIG_LOOP_RESTORATION
815 816
static void decode_restoration_mode(AV1_COMMON *cm,
                                    struct aom_read_bit_buffer *rb) {
817
  const int num_planes = av1_num_planes(cm);
818 819 820
#if CONFIG_INTRABC
  if (cm->allow_intrabc && NO_FILTER_FOR_IBC) return;
#endif  // CONFIG_INTRABC
821
  int all_none = 1, chroma_none = 1;
822
  for (int p = 0; p < num_planes; ++p) {
823
    RestorationInfo *rsi = &cm->rst_info[p];
824 825 826 827
    if (aom_rb_read_bit(rb)) {
      rsi->frame_restoration_type =
          aom_rb_read_bit(rb) ? RESTORE_SGRPROJ : RESTORE_WIENER;
    } else {
828 829
      rsi->frame_restoration_type =
          aom_rb_read_bit(rb) ? RESTORE_SWITCHABLE : RESTORE_NONE;
830
    }
831 832 833 834
    if (rsi->frame_restoration_type != RESTORE_NONE) {
      all_none = 0;
      chroma_none &= p == 0;
    }
835
  }
836
  if (!all_none) {
837
#if CONFIG_EXT_PARTITION
838 839 840
    assert(cm->seq_params.sb_size == BLOCK_64X64 ||
           cm->seq_params.sb_size == BLOCK_128X128);
    const int sb_size = cm->seq_params.sb_size == BLOCK_128X128 ? 128 : 64;
841 842 843 844
#else
    assert(cm->seq_params.sb_size == BLOCK_64X64);
    const int sb_size = 64;
#endif
845

846
    for (int p = 0; p < num_planes; ++p)
847
      cm->rst_info[p].restoration_unit_size = sb_size;
848 849

    RestorationInfo *rsi = &cm->rst_info[0];
850 851 852 853 854

    if (sb_size == 64) {
      rsi->restoration_unit_size <<= aom_rb_read_bit(rb);
    }
    if (rsi->restoration_unit_size > 64) {
855
      rsi->restoration_unit_size <<= aom_rb_read_bit(rb);
856
    }
857 858
  } else {
    const int size = RESTORATION_TILESIZE_MAX;
859
    for (int p = 0; p < num_planes; ++p)
860
      cm->rst_info[p].restoration_unit_size = size;
861
  }
862

863
  if (num_planes > 1) {
864 865 866 867 868 869 870 871 872 873
    int s = AOMMIN(cm->subsampling_x, cm->subsampling_y);
    if (s && !chroma_none) {
      cm->rst_info[1].restoration_unit_size =
          cm->rst_info[0].restoration_unit_size >> (aom_rb_read_bit(rb) * s);
    } else {
      cm->rst_info[1].restoration_unit_size =
          cm->rst_info[0].restoration_unit_size;
    }
    cm->rst_info[2].restoration_unit_size =
        cm->rst_info[1].restoration_unit_size;
874
  }
875 876
}

877
static void read_wiener_filter(int wiener_win, WienerInfo *wiener_info,
878
                               WienerInfo *ref_wiener_info, aom_reader *rb) {
879 880 881
  memset(wiener_info->vfilter, 0, sizeof(wiener_info->vfilter));
  memset(wiener_info->hfilter, 0, sizeof(wiener_info->hfilter));

882 883 884 885 886 887 888 889 890
  if (wiener_win == WIENER_WIN)
    wiener_info->vfilter[0] = wiener_info->vfilter[WIENER_WIN - 1] =
        aom_read_primitive_refsubexpfin(
            rb, WIENER_FILT_TAP0_MAXV - WIENER_FILT_TAP0_MINV + 1,
            WIENER_FILT_TAP0_SUBEXP_K,
            ref_wiener_info->vfilter[0] - WIENER_FILT_TAP0_MINV, ACCT_STR) +
        WIENER_FILT_TAP0_MINV;
  else
    wiener_info->vfilter[0] = wiener_info->vfilter[WIENER_WIN - 1] = 0;
891
  wiener_info->vfilter[1] = wiener_info->vfilter[WIENER_WIN - 2] =
892 893 894
      aom_read_primitive_refsubexpfin(
          rb, WIENER_FILT_TAP1_MAXV - WIENER_FILT_TAP1_MINV + 1,
          WIENER_FILT_TAP1_SUBEXP_K,
895
          ref_wiener_info->vfilter[1] - WIENER_FILT_TAP1_MINV, ACCT_STR) +
896
      WIENER_FILT_TAP1_MINV;
897
  wiener_info->vfilter[2] = wiener_info->vfilter[WIENER_WIN - 3] =
898 899 900
      aom_read_primitive_refsubexpfin(
          rb, WIENER_FILT_TAP2_MAXV - WIENER_FILT_TAP2_MINV + 1,
          WIENER_FILT_TAP2_SUBEXP_K,
901
          ref_wiener_info->vfilter[2] - WIENER_FILT_TAP2_MINV, ACCT_STR) +
902
      WIENER_FILT_TAP2_MINV;
903
  // The central element has an implicit +WIENER_FILT_STEP
904
  wiener_info->vfilter[WIENER_HALFWIN] =
905 906 907
      -2 * (wiener_info->vfilter[0] + wiener_info->vfilter[1] +
            wiener_info->vfilter[2]);

908 909 910 911 912 913 914 915 916
  if (wiener_win == WIENER_WIN)
    wiener_info->hfilter[0] = wiener_info->hfilter[WIENER_WIN - 1] =
        aom_read_primitive_refsubexpfin(
            rb, WIENER_FILT_TAP0_MAXV - WIENER_FILT_TAP0_MINV + 1,
            WIENER_FILT_TAP0_SUBEXP_K,
            ref_wiener_info->hfilter[0] - WIENER_FILT_TAP0_MINV, ACCT_STR) +
        WIENER_FILT_TAP0_MINV;
  else
    wiener_info->hfilter[0] = wiener_info->hfilter[WIENER_WIN - 1] = 0;
917
  wiener_info->hfilter[1] = wiener_info->hfilter[WIENER_WIN - 2] =
918 919 920
      aom_read_primitive_refsubexpfin(
          rb, WIENER_FILT_TAP1_MAXV - WIENER_FILT_TAP1_MINV + 1,
          WIENER_FILT_TAP1_SUBEXP_K,
921
          ref_wiener_info->hfilter[1] - WIENER_FILT_TAP1_MINV, ACCT_STR) +
922
      WIENER_FILT_TAP1_MINV;
923
  wiener_info->hfilter[2] = wiener_info->hfilter[WIENER_WIN - 3] =
924 925 926
      aom_read_primitive_refsubexpfin(
          rb, WIENER_FILT_TAP2_MAXV - WIENER_FILT_TAP2_MINV + 1,
          WIENER_FILT_TAP2_SUBEXP_K,
927
          ref_wiener_info->hfilter[2] - WIENER_FILT_TAP2_MINV, ACCT_STR) +
928
      WIENER_FILT_TAP2_MINV;
929
  // The central element has an implicit +WIENER_FILT_STEP
930
  wiener_info->hfilter[WIENER_HALFWIN] =
931 932
      -2 * (wiener_info->hfilter[0] + wiener_info->hfilter[1] +
            wiener_info->hfilter[2]);
933
  memcpy(ref_wiener_info, wiener_info, sizeof(*wiener_info));
934 935
}

936 937
static void read_sgrproj_filter(SgrprojInfo *sgrproj_info,
                                SgrprojInfo *ref_sgrproj_info, aom_reader *rb) {
938 939
  sgrproj_info->ep = aom_read_literal(rb, SGRPROJ_PARAMS_BITS, ACCT_STR);
  sgrproj_info->xqd[0] =
940 941
      aom_read_primitive_refsubexpfin(
          rb, SGRPROJ_PRJ_MAX0 - SGRPROJ_PRJ_MIN0 + 1, SGRPROJ_PRJ_SUBEXP_K,
942
          ref_sgrproj_info->xqd[0] - SGRPROJ_PRJ_MIN0, ACCT_STR) +
943
      SGRPROJ_PRJ_MIN0;
944
  sgrproj_info->xqd[1] =
945 946
      aom_read_primitive_refsubexpfin(
          rb, SGRPROJ_PRJ_MAX1 - SGRPROJ_PRJ_MIN1 + 1, SGRPROJ_PRJ_SUBEXP_K,
947
          ref_sgrproj_info->xqd[1] - SGRPROJ_PRJ_MIN1, ACCT_STR) +
948 949
      SGRPROJ_PRJ_MIN1;
  memcpy(ref_sgrproj_info, sgrproj_info, sizeof(*sgrproj_info));
950 951
}

952 953 954 955
static void loop_restoration_read_sb_coeffs(const AV1_COMMON *const cm,
                                            MACROBLOCKD *xd,
                                            aom_reader *const r, int plane,
                                            int rtile_idx) {
956 957
  const RestorationInfo *rsi = &cm->rst_info[plane];
  RestorationUnitInfo *rui = &rsi->unit_info[rtile_idx];
958 959 960 961 962 963 964
  if (rsi->frame_restoration_type == RESTORE_NONE) return;

  const int wiener_win = (plane > 0) ? WIENER_WIN_CHROMA : WIENER_WIN;
  WienerInfo *wiener_info = xd->wiener_info + plane;
  SgrprojInfo *sgrproj_info = xd->sgrproj_info + plane;

  if (rsi->frame_restoration_type == RESTORE_SWITCHABLE) {
965
    rui->restoration_type =
966 967
        aom_read_symbol(r, xd->tile_ctx->switchable_restore_cdf,
                        RESTORE_SWITCHABLE_TYPES, ACCT_STR);
968 969 970 971 972 973 974 975
    switch (rui->restoration_type) {
      case RESTORE_WIENER:
        read_wiener_filter(wiener_win, &rui->wiener_info, wiener_info, r);
        break;
      case RESTORE_SGRPROJ:
        read_sgrproj_filter(&rui->sgrproj_info, sgrproj_info, r);
        break;
      default: assert(rui->restoration_type == RESTORE_NONE); break;
976
    }
977
  } else if (rsi->frame_restoration_type == RESTORE_WIENER) {
978
    if (aom_read_symbol(r, xd->tile_ctx->wiener_restore_cdf, 2, ACCT_STR)) {
979 980
      rui->restoration_type = RESTORE_WIENER;
      read_wiener_filter(wiener_win, &rui->wiener_info, wiener_info, r);
981
    } else {
982
      rui->restoration_type = RESTORE_NONE;
983 984
    }
  } else if (rsi->frame_restoration_type == RESTORE_SGRPROJ) {
985
    if (aom_read_symbol(r, xd->tile_ctx->sgrproj_restore_cdf, 2, ACCT_STR)) {
986 987
      rui->restoration_type = RESTORE_SGRPROJ;
      read_sgrproj_filter(&rui->sgrproj_info, sgrproj_info, r);
988
    } else {
989
      rui->restoration_type = RESTORE_NONE;
990 991
    }
  }
992 993 994
}
#endif  // CONFIG_LOOP_RESTORATION

995
static void setup_loopfilter(AV1_COMMON *cm, struct aom_read_bit_buffer *rb) {
996
  const int num_planes = av1_num_planes(cm);
Cheng Chen's avatar
Cheng Chen committed
997
#if CONFIG_INTRABC
998
  if (cm->allow_intrabc && NO_FILTER_FOR_IBC) return;
Cheng Chen's avatar
Cheng Chen committed
999
#endif  // CONFIG_INTRABC
1000
  struct loopfilter *lf = &cm->lf;
1001
#if CONFIG_LOOPFILTER_LEVEL
1002 1003
  lf->filter_level[0] = aom_rb_read_literal(rb, 6);
  lf->filter_level[1] = aom_rb_read_literal(rb, 6);
1004
  if (num_planes > 1) {
1005 1006 1007
    if (lf->filter_level[0] || lf->filter_level[1]) {
      lf->filter_level_u = aom_rb_read_literal(rb, 6);
      lf->filter_level_v = aom_rb_read_literal(rb, 6);
1008
    }
1009
  }
1010 1011
#else
  lf->filter_level = aom_rb_read_literal(rb, 6);
1012
#endif
1013
  lf->sharpness_level = aom_rb_read_literal(rb, 3);
1014 1015 1016 1017 1018

  // Read in loop filter deltas applied at the MB level based on mode or ref
  // frame.
  lf->mode_ref_delta_update = 0;

1019
  lf->mode_ref_delta_enabled = aom_rb_read_bit(rb);
1020
  if (lf->mode_ref_delta_enabled) {
1021
    lf->mode_ref_delta_update = aom_rb_read_bit(rb);
1022
    if (lf->mode_ref_delta_update) {
1023
      for (int i = 0; i < TOTAL_REFS_PER_FRAME; i++)
1024 1025
        if (aom_rb_read_bit(rb))
          lf->ref_deltas[i] = aom_rb_read_inv_signed_literal(rb, 6);
1026

1027
      for (int i = 0; i < MAX_MODE_LF_DELTAS; i++)
1028 1029
        if (aom_rb_read_bit(rb))
          lf->mode_deltas[i] = aom_rb_read_inv_signed_literal(rb, 6);
1030 1031 1032 1033
    }
  }
}

1034
static void setup_cdef(AV1_COMMON *cm, struct aom_read_bit_buffer *rb) {
1035
  const int num_planes = av1_num_planes(cm);
1036 1037 1038
#if CONFIG_INTRABC
  if (cm->allow_intrabc && NO_FILTER_FOR_IBC) return;
#endif  // CONFIG_INTRABC
1039
  cm->cdef_pri_damping = cm->cdef_sec_damping = aom_rb_read_literal(rb, 2) + 3;
1040 1041
  cm->cdef_bits = aom_rb_read_literal(rb, 2);
  cm->nb_cdef_strengths = 1 << cm->cdef_bits;
1042
  for (int i = 0; i < cm->nb_cdef_strengths; i++) {
1043
    cm->cdef_strengths[i] = aom_rb_read_literal(rb, CDEF_STRENGTH_BITS);
1044 1045
    cm->cdef_uv_strengths[i] =
        num_planes > 1 ? aom_rb_read_literal(rb, CDEF_STRENGTH_BITS) : 0;
1046
  }
1047 1048
}

1049 1050
static INLINE int read_delta_q(struct aom_read_bit_buffer *rb) {
  return aom_rb_read_bit(rb) ? aom_rb_read_inv_signed_literal(rb, 6) : 0;
1051 1052
}

1053 1054
static void setup_quantization(AV1_COMMON *const cm,
                               struct aom_read_bit_buffer *rb) {
1055
  const int num_planes = av1_num_planes(cm);
1056
  cm->base_qindex = aom_rb_read_literal(rb, QINDEX_BITS);
1057
  cm->y_dc_delta_q = read_delta_q(rb);
1058
  if (num_planes > 1) {
1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069
    int diff_uv_delta = 0;
    if (cm->separate_uv_delta_q) diff_uv_delta = aom_rb_read_bit(rb);
    cm->u_dc_delta_q = read_delta_q(rb);
    cm->u_ac_delta_q = read_delta_q(rb);
    if (diff_uv_delta) {
      cm->v_dc_delta_q = read_delta_q(rb);
      cm->v_ac_delta_q = read_delta_q(rb);
    } else {
      cm->v_dc_delta_q = cm->u_dc_delta_q;
      cm->v_ac_delta_q = cm->u_ac_delta_q;
    }
1070
  }
1071
  cm->dequant_bit_depth = cm->bit_depth;
1072
#if CONFIG_AOM_QM
1073
  cm->using_qmatrix = aom_rb_read_bit(rb);
1074
  if (cm->using_qmatrix) {
1075 1076 1077 1078 1079 1080 1081 1082
#if CONFIG_AOM_QM_EXT
    cm->qm_y = aom_rb_read_literal(rb, QM_LEVEL_BITS);
    cm->qm_u = aom_rb_read_literal(rb, QM_LEVEL_BITS);
    if (!cm->separate_uv_delta_q)
      cm->qm_v = cm->qm_u;
    else
      cm->qm_v = aom_rb_read_literal(rb, QM_LEVEL_BITS);
#else
1083 1084
    cm->min_qmlevel = aom_rb_read_literal(rb, QM_LEVEL_BITS);
    cm->max_qmlevel = aom_rb_read_literal(rb, QM_LEVEL_BITS);
1085
#endif
1086
  } else {
1087 1088 1089 1090 1091
#if CONFIG_AOM_QM_EXT
    cm->qm_y = 0;
    cm->qm_u = 0;
    cm->qm_v = 0;
#else
1092 1093
    cm->min_qmlevel = 0;
    cm->max_qmlevel = 0;
1094
#endif
1095 1096
  }
#endif
1097 1098
}

1099
// Build y/uv dequant values based on segmentation.
1100
static void setup_segmentation_dequant(AV1_COMMON *const cm) {