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

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

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

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

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

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

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

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

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

76 77
#if CONFIG_PVQ
#include "av1/common/partition.h"
hui su's avatar
hui su committed
78 79
#include "av1/common/pvq.h"
#include "av1/common/scan.h"
80
#include "av1/decoder/decint.h"
hui su's avatar
hui su committed
81 82
#include "av1/decoder/pvq_decoder.h"
#include "av1/encoder/encodemb.h"
83 84 85
#include "av1/encoder/hybrid_fwd_txfm.h"
#endif

86 87 88 89
#if CONFIG_CFL
#include "av1/common/cfl.h"
#endif

90 91 92 93
#if CONFIG_STRIPED_LOOP_RESTORATION && !CONFIG_LOOP_RESTORATION
#error "striped_loop_restoration requires loop_restoration"
#endif

94 95 96 97 98 99 100
#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

101 102 103 104 105 106 107 108
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
109
static int is_compound_reference_allowed(const AV1_COMMON *cm) {
110
#if CONFIG_ONE_SIDED_COMPOUND  // Normative in decoder
111 112
  return !frame_is_intra_only(cm);
#else
Jingning Han's avatar
Jingning Han committed
113
  int i;
114
  if (frame_is_intra_only(cm)) return 0;
115
  for (i = 1; i < INTER_REFS_PER_FRAME; ++i)
116
    if (cm->ref_frame_sign_bias[i + 1] != cm->ref_frame_sign_bias[1]) return 1;
Jingning Han's avatar
Jingning Han committed
117 118

  return 0;
119
#endif  // CONFIG_ONE_SIDED_COMPOUND
Jingning Han's avatar
Jingning Han committed
120 121
}

Yaowu Xu's avatar
Yaowu Xu committed
122
static void setup_compound_reference_mode(AV1_COMMON *cm) {
123
  cm->comp_fwd_ref[0] = LAST_FRAME;
124 125 126 127
  cm->comp_fwd_ref[1] = LAST2_FRAME;
  cm->comp_fwd_ref[2] = LAST3_FRAME;
  cm->comp_fwd_ref[3] = GOLDEN_FRAME;

128
  cm->comp_bwd_ref[0] = BWDREF_FRAME;
Zoe Liu's avatar
Zoe Liu committed
129 130
  cm->comp_bwd_ref[1] = ALTREF2_FRAME;
  cm->comp_bwd_ref[2] = ALTREF_FRAME;
Jingning Han's avatar
Jingning Han committed
131 132 133 134 135 136
}

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
137 138
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
139 140 141
  return data > max ? max : data;
}

142
static TX_MODE read_tx_mode(AV1_COMMON *cm, struct aom_read_bit_buffer *rb) {
143
#if CONFIG_TX64X64
144 145
  TX_MODE tx_mode;
#endif
146
  if (cm->all_lossless) return ONLY_4X4;
147 148 149 150
#if CONFIG_VAR_TX_NO_TX_MODE
  (void)rb;
  return TX_MODE_SELECT;
#else
151 152
#if CONFIG_TX64X64
  tx_mode = aom_rb_read_bit(rb) ? TX_MODE_SELECT : aom_rb_read_literal(rb, 2);
153 154 155
  if (tx_mode == ALLOW_32X32) tx_mode += aom_rb_read_bit(rb);
  return tx_mode;
#else
Yaowu Xu's avatar
Yaowu Xu committed
156
  return aom_rb_read_bit(rb) ? TX_MODE_SELECT : aom_rb_read_literal(rb, 2);
157
#endif  // CONFIG_TX64X64
158
#endif  // CONFIG_VAR_TX_NO_TX_MODE
159
}
Jingning Han's avatar
Jingning Han committed
160

161
#if !CONFIG_RESTRICT_COMPRESSED_HDR
Yaowu Xu's avatar
Yaowu Xu committed
162
static void read_inter_mode_probs(FRAME_CONTEXT *fc, aom_reader *r) {
163
  int i;
164
  for (i = 0; i < NEWMV_MODE_CONTEXTS; ++i)
Michael Bebenita's avatar
Michael Bebenita committed
165
    av1_diff_update_prob(r, &fc->newmv_prob[i], ACCT_STR);
166
  for (i = 0; i < ZEROMV_MODE_CONTEXTS; ++i)
Michael Bebenita's avatar
Michael Bebenita committed
167
    av1_diff_update_prob(r, &fc->zeromv_prob[i], ACCT_STR);
168
  for (i = 0; i < REFMV_MODE_CONTEXTS; ++i)
Michael Bebenita's avatar
Michael Bebenita committed
169
    av1_diff_update_prob(r, &fc->refmv_prob[i], ACCT_STR);
170
  for (i = 0; i < DRL_MODE_CONTEXTS; ++i)
Michael Bebenita's avatar
Michael Bebenita committed
171
    av1_diff_update_prob(r, &fc->drl_prob[i], ACCT_STR);
Jingning Han's avatar
Jingning Han committed
172
}
173
#endif
Jingning Han's avatar
Jingning Han committed
174

175
static REFERENCE_MODE read_frame_reference_mode(
Yaowu Xu's avatar
Yaowu Xu committed
176
    const AV1_COMMON *cm, struct aom_read_bit_buffer *rb) {
177
  if (is_compound_reference_allowed(cm)) {
Zoe Liu's avatar
Zoe Liu committed
178 179 180
#if CONFIG_REF_ADAPT
    return aom_rb_read_bit(rb) ? REFERENCE_MODE_SELECT : SINGLE_REFERENCE;
#else
Yaowu Xu's avatar
Yaowu Xu committed
181
    return aom_rb_read_bit(rb)
182
               ? REFERENCE_MODE_SELECT
Yaowu Xu's avatar
Yaowu Xu committed
183
               : (aom_rb_read_bit(rb) ? COMPOUND_REFERENCE : SINGLE_REFERENCE);
Zoe Liu's avatar
Zoe Liu committed
184
#endif  // CONFIG_REF_ADAPT
185 186 187 188
  } else {
    return SINGLE_REFERENCE;
  }
}
Jingning Han's avatar
Jingning Han committed
189

190
#if !CONFIG_RESTRICT_COMPRESSED_HDR
Yaowu Xu's avatar
Yaowu Xu committed
191
static void read_frame_reference_mode_probs(AV1_COMMON *cm, aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
192
  FRAME_CONTEXT *const fc = cm->fc;
193
  int i;
Jingning Han's avatar
Jingning Han committed
194 195 196

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

199
  if (cm->reference_mode != COMPOUND_REFERENCE) {
Jingning Han's avatar
Jingning Han committed
200
    for (i = 0; i < REF_CONTEXTS; ++i) {
201
      int j;
202
      for (j = 0; j < (SINGLE_REFS - 1); ++j) {
Michael Bebenita's avatar
Michael Bebenita committed
203
        av1_diff_update_prob(r, &fc->single_ref_prob[i][j], ACCT_STR);
204
      }
Jingning Han's avatar
Jingning Han committed
205
    }
206
  }
Jingning Han's avatar
Jingning Han committed
207

208
  if (cm->reference_mode != SINGLE_REFERENCE) {
Zoe Liu's avatar
Zoe Liu committed
209 210 211 212
#if CONFIG_EXT_COMP_REFS
    for (i = 0; i < COMP_REF_TYPE_CONTEXTS; ++i)
      av1_diff_update_prob(r, &fc->comp_ref_type_prob[i], ACCT_STR);

213 214
    for (i = 0; i < UNI_COMP_REF_CONTEXTS; ++i) {
      int j;
Zoe Liu's avatar
Zoe Liu committed
215 216
      for (j = 0; j < (UNIDIR_COMP_REFS - 1); ++j)
        av1_diff_update_prob(r, &fc->uni_comp_ref_prob[i][j], ACCT_STR);
217
    }
Zoe Liu's avatar
Zoe Liu committed
218 219
#endif  // CONFIG_EXT_COMP_REFS

220
    for (i = 0; i < REF_CONTEXTS; ++i) {
221
      int j;
222
      for (j = 0; j < (FWD_REFS - 1); ++j)
Michael Bebenita's avatar
Michael Bebenita committed
223
        av1_diff_update_prob(r, &fc->comp_ref_prob[i][j], ACCT_STR);
224
      for (j = 0; j < (BWD_REFS - 1); ++j)
Michael Bebenita's avatar
Michael Bebenita committed
225
        av1_diff_update_prob(r, &fc->comp_bwdref_prob[i][j], ACCT_STR);
226 227
    }
  }
Jingning Han's avatar
Jingning Han committed
228 229
}

Yaowu Xu's avatar
Yaowu Xu committed
230
static void update_mv_probs(aom_prob *p, int n, aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
231
  int i;
Michael Bebenita's avatar
Michael Bebenita committed
232
  for (i = 0; i < n; ++i) av1_diff_update_prob(r, &p[i], ACCT_STR);
Jingning Han's avatar
Jingning Han committed
233 234
}

Yaowu Xu's avatar
Yaowu Xu committed
235
static void read_mv_probs(nmv_context *ctx, int allow_hp, aom_reader *r) {
236
  int i;
Jingning Han's avatar
Jingning Han committed
237 238 239 240 241 242 243 244
  if (allow_hp) {
    for (i = 0; i < 2; ++i) {
      nmv_component *const comp_ctx = &ctx->comps[i];
      update_mv_probs(&comp_ctx->class0_hp, 1, r);
      update_mv_probs(&comp_ctx->hp, 1, r);
    }
  }
}
245
#endif
Jingning Han's avatar
Jingning Han committed
246

247
static void inverse_transform_block(MACROBLOCKD *xd, int plane,
248
#if CONFIG_LGT_FROM_PRED
Lester Lu's avatar
Lester Lu committed
249 250
                                    PREDICTION_MODE mode,
#endif
251
                                    const TX_TYPE tx_type,
252
                                    const TX_SIZE tx_size, uint8_t *dst,
253
                                    int stride, int16_t scan_line, int eob) {
Jingning Han's avatar
Jingning Han committed
254
  struct macroblockd_plane *const pd = &xd->plane[plane];
255
  tran_low_t *const dqcoeff = pd->dqcoeff;
Lester Lu's avatar
Lester Lu committed
256
  av1_inverse_transform_block(xd, dqcoeff,
257
#if CONFIG_LGT_FROM_PRED
Lester Lu's avatar
Lester Lu committed
258 259
                              mode,
#endif
Sarah Parker's avatar
Sarah Parker committed
260 261 262
#if CONFIG_MRC_TX && SIGNAL_ANY_MRC_MASK
                              xd->mrc_mask,
#endif  // CONFIG_MRC_TX && SIGNAL_ANY_MRC_MASK
Lester Lu's avatar
Lester Lu committed
263
                              tx_type, tx_size, dst, stride, eob);
264
  memset(dqcoeff, 0, (scan_line + 1) * sizeof(dqcoeff[0]));
Jingning Han's avatar
Jingning Han committed
265 266
}

267 268 269 270 271 272 273 274 275 276 277 278 279
static int get_block_idx(const MACROBLOCKD *xd, int plane, int row, int col) {
  const int bsize = xd->mi[0]->mbmi.sb_type;
  const struct macroblockd_plane *pd = &xd->plane[plane];
#if CONFIG_CHROMA_SUB8X8
  const BLOCK_SIZE plane_bsize =
      AOMMAX(BLOCK_4X4, get_plane_block_size(bsize, pd));
#elif CONFIG_CB4X4
  const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
#else
  const BLOCK_SIZE plane_bsize =
      get_plane_block_size(AOMMAX(BLOCK_8X8, bsize), pd);
#endif
  const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
280
  const TX_SIZE tx_size = av1_get_tx_size(plane, xd);
281 282 283 284
  const uint8_t txh_unit = tx_size_high_unit[tx_size];
  return row * max_blocks_wide + col * txh_unit;
}

285
#if CONFIG_PVQ
Thomas Daede's avatar
Thomas Daede committed
286
static int av1_pvq_decode_helper(MACROBLOCKD *xd, tran_low_t *ref_coeff,
287
                                 tran_low_t *dqcoeff, int16_t *quant, int pli,
288
                                 int bs, TX_TYPE tx_type, int xdec,
ltrudeau's avatar
ltrudeau committed
289
                                 PVQ_SKIP_TYPE ac_dc_coded) {
290 291 292 293
  unsigned int flags;  // used for daala's stream analyzer.
  int off;
  const int is_keyframe = 0;
  const int has_dc_skip = 1;
294
  int coeff_shift = 3 - av1_get_tx_scale(bs);
Thomas Daede's avatar
Thomas Daede committed
295
  int hbd_downshift = 0;
296
  int rounding_mask;
297 298 299 300 301 302
  // DC quantizer for PVQ
  int pvq_dc_quant;
  int lossless = (quant[0] == 0);
  const int blk_size = tx_size_wide[bs];
  int eob = 0;
  int i;
Thomas Daede's avatar
Thomas Daede committed
303
  od_dec_ctx *dec = &xd->daala_dec;
304
  int use_activity_masking = dec->use_activity_masking;
305 306
  DECLARE_ALIGNED(16, tran_low_t, dqcoeff_pvq[OD_TXSIZE_MAX * OD_TXSIZE_MAX]);
  DECLARE_ALIGNED(16, tran_low_t, ref_coeff_pvq[OD_TXSIZE_MAX * OD_TXSIZE_MAX]);
307

308 309
  od_coeff ref_int32[OD_TXSIZE_MAX * OD_TXSIZE_MAX];
  od_coeff out_int32[OD_TXSIZE_MAX * OD_TXSIZE_MAX];
310

Thomas Daede's avatar
Thomas Daede committed
311 312
  hbd_downshift = xd->bd - 8;

313 314 315
  od_raster_to_coding_order(ref_coeff_pvq, blk_size, tx_type, ref_coeff,
                            blk_size);

Thomas Daede's avatar
Thomas Daede committed
316
  assert(OD_COEFF_SHIFT >= 4);
317 318 319
  if (lossless)
    pvq_dc_quant = 1;
  else {
320
    if (use_activity_masking)
clang-format's avatar
clang-format committed
321 322 323 324 325
      pvq_dc_quant =
          OD_MAXI(1,
                  (quant[0] << (OD_COEFF_SHIFT - 3) >> hbd_downshift) *
                          dec->state.pvq_qm_q4[pli][od_qm_get_index(bs, 0)] >>
                      4);
326
    else
Thomas Daede's avatar
Thomas Daede committed
327 328
      pvq_dc_quant =
          OD_MAXI(1, quant[0] << (OD_COEFF_SHIFT - 3) >> hbd_downshift);
329 330 331 332 333
  }

  off = od_qm_offset(bs, xdec);

  // copy int16 inputs to int32
334
  for (i = 0; i < blk_size * blk_size; i++) {
335
    ref_int32[i] =
Thomas Daede's avatar
Thomas Daede committed
336 337
        AOM_SIGNED_SHL(ref_coeff_pvq[i], OD_COEFF_SHIFT - coeff_shift) >>
        hbd_downshift;
338
  }
339

Thomas Daede's avatar
Thomas Daede committed
340 341
  od_pvq_decode(dec, ref_int32, out_int32,
                OD_MAXI(1, quant[1] << (OD_COEFF_SHIFT - 3) >> hbd_downshift),
342
                pli, bs, OD_PVQ_BETA[use_activity_masking][pli][bs],
343 344
                is_keyframe, &flags, ac_dc_coded, dec->state.qm + off,
                dec->state.qm_inv + off);
345

346 347
  if (!has_dc_skip || out_int32[0]) {
    out_int32[0] =
348
        has_dc_skip + generic_decode(dec->r, &dec->state.adapt->model_dc[pli],
349 350
                                     &dec->state.adapt->ex_dc[pli][bs][0], 2,
                                     "dc:mag");
351 352 353 354 355 356 357 358
    if (out_int32[0]) out_int32[0] *= aom_read_bit(dec->r, "dc:sign") ? -1 : 1;
  }
  out_int32[0] = out_int32[0] * pvq_dc_quant + ref_int32[0];

  // copy int32 result back to int16
  assert(OD_COEFF_SHIFT > coeff_shift);
  rounding_mask = (1 << (OD_COEFF_SHIFT - coeff_shift - 1)) - 1;
  for (i = 0; i < blk_size * blk_size; i++) {
Thomas Daede's avatar
Thomas Daede committed
359
    out_int32[i] = AOM_SIGNED_SHL(out_int32[i], hbd_downshift);
360 361
    dqcoeff_pvq[i] = (out_int32[i] + (out_int32[i] < 0) + rounding_mask) >>
                     (OD_COEFF_SHIFT - coeff_shift);
362 363 364 365 366 367 368 369 370
  }

  od_coding_order_to_raster(dqcoeff, blk_size, tx_type, dqcoeff_pvq, blk_size);

  eob = blk_size * blk_size;

  return eob;
}

ltrudeau's avatar
ltrudeau committed
371 372 373 374 375 376
static PVQ_SKIP_TYPE read_pvq_skip(AV1_COMMON *cm, MACROBLOCKD *const xd,
                                   int plane, TX_SIZE tx_size) {
  // decode ac/dc coded flag. bit0: DC coded, bit1 : AC coded
  // NOTE : we don't use 5 symbols for luma here in aom codebase,
  // since block partition is taken care of by aom.
  // So, only AC/DC skip info is coded
377
  const int ac_dc_coded = aom_read_symbol(
ltrudeau's avatar
ltrudeau committed
378
      xd->daala_dec.r,
379
      xd->daala_dec.state.adapt->skip_cdf[2 * tx_size + (plane != 0)], 4,
380
      "skip");
ltrudeau's avatar
ltrudeau committed
381 382 383 384 385 386 387 388
  if (ac_dc_coded < 0 || ac_dc_coded > 3) {
    aom_internal_error(&cm->error, AOM_CODEC_INVALID_PARAM,
                       "Invalid PVQ Skip Type");
  }
  return ac_dc_coded;
}

static int av1_pvq_decode_helper2(AV1_COMMON *cm, MACROBLOCKD *const xd,
389 390
                                  MB_MODE_INFO *const mbmi, int plane, int row,
                                  int col, TX_SIZE tx_size, TX_TYPE tx_type) {
391 392 393 394 395 396 397 398 399 400
  struct macroblockd_plane *const pd = &xd->plane[plane];
  // transform block size in pixels
  int tx_blk_size = tx_size_wide[tx_size];
  int i, j;
  tran_low_t *pvq_ref_coeff = pd->pvq_ref_coeff;
  const int diff_stride = tx_blk_size;
  int16_t *pred = pd->pred;
  tran_low_t *const dqcoeff = pd->dqcoeff;
  uint8_t *dst;
  int eob;
ltrudeau's avatar
ltrudeau committed
401
  const PVQ_SKIP_TYPE ac_dc_coded = read_pvq_skip(cm, xd, plane, tx_size);
402 403 404 405 406 407 408 409

  eob = 0;
  dst = &pd->dst.buf[4 * row * pd->dst.stride + 4 * col];

  if (ac_dc_coded) {
    int xdec = pd->subsampling_x;
    int seg_id = mbmi->segment_id;
    int16_t *quant;
410
    TxfmParam txfm_param;
411 412
    // ToDo(yaowu): correct this with optimal number from decoding process.
    const int max_scan_line = tx_size_2d[tx_size];
413
#if CONFIG_HIGHBITDEPTH
Thomas Daede's avatar
Thomas Daede committed
414 415 416 417 418 419 420 421 422 423
    if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
      for (j = 0; j < tx_blk_size; j++)
        for (i = 0; i < tx_blk_size; i++)
          pred[diff_stride * j + i] =
              CONVERT_TO_SHORTPTR(dst)[pd->dst.stride * j + i];
    } else {
#endif
      for (j = 0; j < tx_blk_size; j++)
        for (i = 0; i < tx_blk_size; i++)
          pred[diff_stride * j + i] = dst[pd->dst.stride * j + i];
424
#if CONFIG_HIGHBITDEPTH
Thomas Daede's avatar
Thomas Daede committed
425 426
    }
#endif
427

428 429 430
    txfm_param.tx_type = tx_type;
    txfm_param.tx_size = tx_size;
    txfm_param.lossless = xd->lossless[seg_id];
431

432
#if CONFIG_HIGHBITDEPTH
Thomas Daede's avatar
Thomas Daede committed
433
    if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
434 435
      txfm_param.bd = xd->bd;
      av1_highbd_fwd_txfm(pred, pvq_ref_coeff, diff_stride, &txfm_param);
Thomas Daede's avatar
Thomas Daede committed
436
    } else {
437
#endif  // CONFIG_HIGHBITDEPTH
438
      av1_fwd_txfm(pred, pvq_ref_coeff, diff_stride, &txfm_param);
439
#if CONFIG_HIGHBITDEPTH
Thomas Daede's avatar
Thomas Daede committed
440
    }
441
#endif  // CONFIG_HIGHBITDEPTH
442 443 444

    quant = &pd->seg_dequant[seg_id][0];  // aom's quantizer

Thomas Daede's avatar
Thomas Daede committed
445 446
    eob = av1_pvq_decode_helper(xd, pvq_ref_coeff, dqcoeff, quant, plane,
                                tx_size, tx_type, xdec, ac_dc_coded);
447

Lester Lu's avatar
Lester Lu committed
448
    inverse_transform_block(xd, plane, tx_type, tx_size, dst, pd->dst.stride,
449
                            max_scan_line, eob);
450 451 452 453 454 455
  }

  return eob;
}
#endif

456 457 458
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) {
459
  PLANE_TYPE plane_type = get_plane_type(plane);
460
  const int block_idx = get_block_idx(xd, plane, row, col);
461 462 463
#if CONFIG_PVQ
  (void)r;
#endif
464
  av1_predict_intra_block_facade(cm, xd, plane, block_idx, col, row, tx_size);
Jingning Han's avatar
Jingning Han committed
465 466

  if (!mbmi->skip) {
467
#if !CONFIG_PVQ
468
    struct macroblockd_plane *const pd = &xd->plane[plane];
Angie Chiang's avatar
Angie Chiang committed
469 470
#if CONFIG_LV_MAP
    int16_t max_scan_line = 0;
471 472
    int eob;
    av1_read_coeffs_txb_facade(cm, xd, r, row, col, block_idx, plane,
Jingning Han's avatar
Jingning Han committed
473
                               pd->dqcoeff, tx_size, &max_scan_line, &eob);
474
    // tx_type will be read out in av1_read_coeffs_txb_facade
475 476
    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
477
#else   // CONFIG_LV_MAP
478 479
    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
480
    const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, mbmi);
481 482
    int16_t max_scan_line = 0;
    const int eob =
483
        av1_decode_block_tokens(cm, xd, plane, scan_order, col, row, tx_size,
484
                                tx_type, &max_scan_line, r, mbmi->segment_id);
Angie Chiang's avatar
Angie Chiang committed
485
#endif  // CONFIG_LV_MAP
486 487 488
    if (eob) {
      uint8_t *dst =
          &pd->dst.buf[(row * pd->dst.stride + col) << tx_size_wide_log2[0]];
Hui Su's avatar
Hui Su committed
489
      inverse_transform_block(xd, plane,
490
#if CONFIG_LGT_FROM_PRED
Lester Lu's avatar
Lester Lu committed
491
                              mbmi->mode,
Lester Lu's avatar
Lester Lu committed
492
#endif
Hui Su's avatar
Hui Su committed
493 494
                              tx_type, tx_size, dst, pd->dst.stride,
                              max_scan_line, eob);
495
    }
Lester Lu's avatar
Lester Lu committed
496
#else   // !CONFIG_PVQ
497 498
    const TX_TYPE tx_type =
        av1_get_tx_type(plane_type, xd, row, col, block_idx, tx_size);
ltrudeau's avatar
ltrudeau committed
499
    av1_pvq_decode_helper2(cm, xd, mbmi, plane, row, col, tx_size, tx_type);
Lester Lu's avatar
Lester Lu committed
500
#endif  // !CONFIG_PVQ
Jingning Han's avatar
Jingning Han committed
501
  }
502
#if CONFIG_CFL
503
  if (plane == AOM_PLANE_Y && xd->cfl->store_y) {
504
    cfl_store_tx(xd, row, col, tx_size, mbmi->sb_type);
505
  }
Sebastien Alaiwan's avatar
Sebastien Alaiwan committed
506
#endif  // CONFIG_CFL
Jingning Han's avatar
Jingning Han committed
507 508
}

509
#if CONFIG_VAR_TX && !CONFIG_COEF_INTERLEAVE
Angie Chiang's avatar
Angie Chiang committed
510 511
static void decode_reconstruct_tx(AV1_COMMON *cm, MACROBLOCKD *const xd,
                                  aom_reader *r, MB_MODE_INFO *const mbmi,
512
                                  int plane, BLOCK_SIZE plane_bsize,
513 514
                                  int blk_row, int blk_col, int block,
                                  TX_SIZE tx_size, int *eob_total) {
515
  const struct macroblockd_plane *const pd = &xd->plane[plane];
516
  const BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
517 518
  const int tx_row = blk_row >> (1 - pd->subsampling_y);
  const int tx_col = blk_col >> (1 - pd->subsampling_x);
519
  const TX_SIZE plane_tx_size =
520
      plane ? uv_txsize_lookup[bsize][mbmi->inter_tx_size[tx_row][tx_col]][0][0]
521
            : mbmi->inter_tx_size[tx_row][tx_col];
522
  // Scale to match transform block unit.
523 524
  const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
  const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
525

526
  if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
527

528
  if (tx_size == plane_tx_size) {
529
    PLANE_TYPE plane_type = get_plane_type(plane);
Angie Chiang's avatar
Angie Chiang committed
530 531
#if CONFIG_LV_MAP
    int16_t max_scan_line = 0;
532
    int eob;
533
    av1_read_coeffs_txb_facade(cm, xd, r, blk_row, blk_col, block, plane,
Jingning Han's avatar
Jingning Han committed
534
                               pd->dqcoeff, tx_size, &max_scan_line, &eob);
535
    // tx_type will be read out in av1_read_coeffs_txb_facade
hui su's avatar
hui su committed
536
    const TX_TYPE tx_type =
537
        av1_get_tx_type(plane_type, xd, blk_row, blk_col, block, plane_tx_size);
Angie Chiang's avatar
Angie Chiang committed
538
#else   // CONFIG_LV_MAP
hui su's avatar
hui su committed
539
    const TX_TYPE tx_type =
540
        av1_get_tx_type(plane_type, xd, blk_row, blk_col, block, plane_tx_size);
Angie Chiang's avatar
Angie Chiang committed
541
    const SCAN_ORDER *sc = get_scan(cm, plane_tx_size, tx_type, mbmi);
542
    int16_t max_scan_line = 0;
543 544 545
    const int eob = av1_decode_block_tokens(
        cm, xd, plane, sc, blk_col, blk_row, plane_tx_size, tx_type,
        &max_scan_line, r, mbmi->segment_id);
Angie Chiang's avatar
Angie Chiang committed
546
#endif  // CONFIG_LV_MAP
Lester Lu's avatar
Lester Lu committed
547
    inverse_transform_block(xd, plane,
548
#if CONFIG_LGT_FROM_PRED
Lester Lu's avatar
Lester Lu committed
549 550 551
                            mbmi->mode,
#endif
                            tx_type, plane_tx_size,
552 553 554
                            &pd->dst.buf[(blk_row * pd->dst.stride + blk_col)
                                         << tx_size_wide_log2[0]],
                            pd->dst.stride, max_scan_line, eob);
555 556
    *eob_total += eob;
  } else {
Yue Chen's avatar
Yue Chen committed
557 558 559 560 561
#if CONFIG_RECT_TX_EXT
    int is_qttx = plane_tx_size == quarter_txsize_lookup[plane_bsize];
    const TX_SIZE sub_txs = is_qttx ? plane_tx_size : sub_tx_size_map[tx_size];
    if (is_qttx) assert(blk_row == 0 && blk_col == 0 && block == 0);
#else
562
    const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
563 564
    assert(IMPLIES(tx_size <= TX_4X4, sub_txs == tx_size));
    assert(IMPLIES(tx_size > TX_4X4, sub_txs < tx_size));
Yue Chen's avatar
Yue Chen committed
565
#endif
566
    const int bsl = tx_size_wide_unit[sub_txs];
567
    int sub_step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
568 569 570 571 572
    int i;

    assert(bsl > 0);

    for (i = 0; i < 4; ++i) {
Yue Chen's avatar
Yue Chen committed
573 574 575 576 577 578 579 580 581
#if CONFIG_RECT_TX_EXT
      int is_wide_tx = tx_size_wide_unit[sub_txs] > tx_size_high_unit[sub_txs];
      const int offsetr =
          is_qttx ? (is_wide_tx ? i * tx_size_high_unit[sub_txs] : 0)
                  : blk_row + ((i >> 1) * bsl);
      const int offsetc =
          is_qttx ? (is_wide_tx ? 0 : i * tx_size_wide_unit[sub_txs])
                  : blk_col + (i & 0x01) * bsl;
#else
582 583
      const int offsetr = blk_row + (i >> 1) * bsl;
      const int offsetc = blk_col + (i & 0x01) * bsl;
Yue Chen's avatar
Yue Chen committed
584
#endif
585

586
      if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
587

588
      decode_reconstruct_tx(cm, xd, r, mbmi, plane, plane_bsize, offsetr,
589 590
                            offsetc, block, sub_txs, eob_total);
      block += sub_step;
591 592 593
    }
  }
}
594
#endif  // CONFIG_VAR_TX
595

596
#if !CONFIG_VAR_TX || CONFIG_COEF_INTERLEAVE || \
597
    (!CONFIG_VAR_TX && CONFIG_EXT_TX && CONFIG_RECT_TX)
Angie Chiang's avatar
Angie Chiang committed
598
static int reconstruct_inter_block(AV1_COMMON *cm, MACROBLOCKD *const xd,
599 600
                                   aom_reader *const r, int segment_id,
                                   int plane, int row, int col,
601
                                   TX_SIZE tx_size) {
602
  PLANE_TYPE plane_type = get_plane_type(plane);
603
  int block_idx = get_block_idx(xd, plane, row, col);
604 605 606
#if CONFIG_PVQ
  int eob;
  (void)r;
607 608 609
  (void)segment_id;
#else
  struct macroblockd_plane *const pd = &xd->plane[plane];
610 611 612
#endif

#if !CONFIG_PVQ
Angie Chiang's avatar
Angie Chiang committed
613 614
#if CONFIG_LV_MAP
  (void)segment_id;
615
  int16_t max_scan_line = 0;
616 617
  int eob;
  av1_read_coeffs_txb_facade(cm, xd, r, row, col, block_idx, plane, pd->dqcoeff,
Angie Chiang's avatar
Angie Chiang committed
618
                             tx_size, &max_scan_line, &eob);
619
  // tx_type will be read out in av1_read_coeffs_txb_facade
620 621
  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
622 623
#else   // CONFIG_LV_MAP
  int16_t max_scan_line = 0;
624 625
  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
626 627
  const SCAN_ORDER *scan_order =
      get_scan(cm, tx_size, tx_type, &xd->mi[0]->mbmi);
628
  const int eob =
629 630
      av1_decode_block_tokens(cm, xd, plane, scan_order, col, row, tx_size,
                              tx_type, &max_scan_line, r, segment_id);
Angie Chiang's avatar
Angie Chiang committed
631
#endif  // CONFIG_LV_MAP
632 633
  uint8_t *dst =
      &pd->dst.buf[(row * pd->dst.stride + col) << tx_size_wide_log2[0]];
634
  if (eob)
Lester Lu's avatar
Lester Lu committed
635
    inverse_transform_block(xd, plane,
636
#if CONFIG_LGT_FROM_PRED
Lester Lu's avatar
Lester Lu committed
637 638 639
                            xd->mi[0]->mbmi.mode,
#endif
                            tx_type, tx_size, dst, pd->dst.stride,
640
                            max_scan_line, eob);
641
#else
642 643
  const TX_TYPE tx_type =
      av1_get_tx_type(plane_type, xd, row, col, block_idx, tx_size);
ltrudeau's avatar
ltrudeau committed
644 645
  eob = av1_pvq_decode_helper2(cm, xd, &xd->mi[0]->mbmi, plane, row, col,
                               tx_size, tx_type);
646
#endif
Jingning Han's avatar
Jingning Han committed
647 648
  return eob;
}
649
#endif  // !CONFIG_VAR_TX || CONFIG_SUPER_TX
Jingning Han's avatar
Jingning Han committed
650

651 652 653
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
654 655 656 657 658 659 660 661 662
  const int offset = mi_row * cm->mi_stride + mi_col;
  int x, y;
  const TileInfo *const tile = &xd->tile;

  xd->mi = cm->mi_grid_visible + offset;
  xd->mi[0] = &cm->mi[offset];
  // TODO(slavarnway): Generate sb_type based on bwl and bhl, instead of
  // passing bsize from decode_partition().
  xd->mi[0]->mbmi.sb_type = bsize;
663 664 665
#if CONFIG_RD_DEBUG
  xd->mi[0]->mbmi.mi_row = mi_row;
  xd->mi[0]->mbmi.mi_col = mi_col;
666 667 668 669
#endif
#if CONFIG_CFL
  xd->cfl->mi_row = mi_row;
  xd->cfl->mi_col = mi_col;
670
#endif
Jingning Han's avatar
Jingning Han committed
671
  for (y = 0; y < y_mis; ++y)
Jingning Han's avatar
Jingning Han committed
672
    for (x = !y; x < x_mis; ++x) xd->mi[y * cm->mi_stride + x] = xd->mi[0];
Jingning Han's avatar
Jingning Han committed
673

Jingning Han's avatar
Jingning Han committed
674
  set_plane_n4(xd, bw, bh);
Jingning Han's avatar
Jingning Han committed
675 676
  set_skip_context(xd, mi_row, mi_col);

677 678 679
  // 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,
680
#if CONFIG_DEPENDENT_HORZTILES
681 682 683
                 cm->dependent_horz_tiles,
#endif  // CONFIG_DEPENDENT_HORZTILES
                 cm->mi_rows, cm->mi_cols);
Jingning Han's avatar
Jingning Han committed
684

685 686
  av1_setup_dst_planes(xd->plane, bsize, get_frame_new_buffer(cm), mi_row,
                       mi_col);
Jingning Han's avatar
Jingning Han committed
687 688
}

689 690
static void decode_mbmi_block(AV1Decoder *const pbi, MACROBLOCKD *const xd,
                              int mi_row, int mi_col, aom_reader *r,
691
#if CONFIG_EXT_PARTITION_TYPES
692
                              PARTITION_TYPE partition,
693
#endif  // CONFIG_EXT_PARTITION_TYPES
694
                              BLOCK_SIZE bsize) {
Yaowu Xu's avatar
Yaowu Xu committed
695
  AV1_COMMON *const cm = &pbi->common;
696 697
  const int bw = mi_size_wide[bsize];
  const int bh = mi_size_high[bsize];
Yaowu Xu's avatar
Yaowu Xu committed
698 699
  const int x_mis = AOMMIN(bw, cm->mi_cols - mi_col);
  const int y_mis = AOMMIN(bh, cm->mi_rows - mi_row);
700

Michael Bebenita's avatar
Michael Bebenita committed
701 702 703
#if CONFIG_ACCOUNTING
  aom_accounting_set_context(&pbi->accounting, mi_col, mi_row);
#endif
704
  set_offsets(cm, xd, bsize, mi_row, mi_col, bw, bh, x_mis, y_mis);
705 706 707
#if CONFIG_EXT_PARTITION_TYPES
  xd->mi[0]->mbmi.partition = partition;
#endif
Yaowu Xu's avatar
Yaowu Xu committed
708
  av1_read_mode_info(pbi, xd, mi_row, mi_col, r, x_mis, y_mis);
Jingning Han's avatar
Jingning Han committed
709 710 711 712
  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
713
      aom_internal_error(xd->error_info, AOM_CODEC_CORRUPT_FRAME,
714
                         "Invalid block size.");
Jingning Han's avatar
Jingning Han committed
715 716
  }

717 718
  int reader_corrupted_flag = aom_reader_has_error(r);
  aom_merge_corrupted_flag(&xd->corrupted, reader_corrupted_flag);
719 720
}

721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740
#if CONFIG_NCOBMC_ADAPT_WEIGHT
static void set_mode_info_offsets(AV1_COMMON *const cm, MACROBLOCKD *const xd,
                                  int mi_row, int mi_col) {
  const int offset = mi_row * cm->mi_stride + mi_col;
  xd->mi = cm->mi_grid_visible + offset;
  xd->mi[0] = &cm->mi[offset];
}

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

  int plane;
#if CONFIG_HIGHBITDEPTH
  if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
    int len = sizeof(uint16_t);
741 742 743 744 745 746 747 748
    ASSIGN_ALIGNED_PTRS_HBD(pred_buf[0], cm->ncobmcaw_buf[0], MAX_SB_SQUARE,
                            len);
    ASSIGN_ALIGNED_PTRS_HBD(pred_buf[1], cm->ncobmcaw_buf[1], MAX_SB_SQUARE,
                            len);
    ASSIGN_ALIGNED_PTRS_HBD(pred_buf[2], cm->ncobmcaw_buf[2], MAX_SB_SQUARE,
                            len);
    ASSIGN_ALIGNED_PTRS_HBD(pred_buf[3], cm->ncobmcaw_buf[3], MAX_SB_SQUARE,
                            len);
749 750
  } else {
#endif  // CONFIG_HIGHBITDEPTH
751 752 753 754
    ASSIGN_ALIGNED_PTRS(pred_buf[0], cm->ncobmcaw_buf[0], MAX_SB_SQUARE);
    ASSIGN_ALIGNED_PTRS(pred_buf[1], cm->ncobmcaw_buf[1], MAX_SB_SQUARE);
    ASSIGN_ALIGNED_PTRS(pred_buf[2], cm->ncobmcaw_buf[2], MAX_SB_SQUARE);
    ASSIGN_ALIGNED_PTRS(pred_buf[3], cm->ncobmcaw_buf[3], MAX_SB_SQUARE);
755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808
#if CONFIG_HIGHBITDEPTH
  }
#endif
  av1_get_ext_blk_preds(cm, xd, bsize, mi_row, mi_col, pred_buf, pred_stride);
  av1_get_ori_blk_pred(cm, xd, bsize, mi_row, mi_col, pred_buf[3], pred_stride);
  for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
    build_ncobmc_intrpl_pred(cm, xd, plane, pxl_row, pxl_col, bsize, pred_buf,
                             pred_stride, mode);
  }
}

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

  assert(bsize >= BLOCK_8X8);

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

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

809 810 811 812 813 814 815 816 817 818
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);

819 820
  set_offsets(cm, xd, bsize, mi_row, mi_col, bw, bh, x_mis, y_mis);
  MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
821 822 823 824 825
#if CONFIG_CFL && CONFIG_CHROMA_SUB8X8
  CFL_CTX *const cfl = xd->cfl;
  cfl->is_chroma_reference = is_chroma_reference(
      mi_row, mi_col, bsize, cfl->subsampling_x, cfl->subsampling_y);
#endif  // CONFIG_CFL && CONFIG_CHROMA_SUB8X8
826

827 828 829
  if (cm->delta_q_present_flag) {
    int i;
    for (i = 0; i < MAX_SEGMENTS; i++) {
Fangwen Fu's avatar
Fangwen Fu committed
830
#if CONFIG_EXT_DELTA_Q
831 832
      const int current_qindex =
          av1_get_qindex(&cm->seg, i, xd->current_qindex);
Fangwen Fu's avatar
Fangwen Fu committed
833
#else
834 835 836 837 838 839 840 841 842 843 844 845
      const int current_qindex = xd->current_qindex;
#endif  // CONFIG_EXT_DELTA_Q
      int j;
      for (j = 0; j < MAX_MB_PLANE; ++j) {
        const int dc_delta_q = j == 0 ? cm->y_dc_delta_q : cm->uv_dc_delta_q;
        const int ac_delta_q = j == 0 ? 0 : cm->uv_ac_delta_q;

        xd->plane[j].seg_dequant[i][0] =
            av1_dc_quant(current_qindex, dc_delta_q, cm->bit_depth);
        xd->plane[j].seg_dequant[i][1] =
            av1_ac_quant(current_qindex, ac_delta_q, cm->bit_depth);
      }
846 847 848
<