decodeframe.c 164 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
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));
#else
274
275
  const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
#endif  // CONFIG_CHROMA_SUB8X8
276
  const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
277
  const TX_SIZE tx_size = av1_get_tx_size(plane, xd);
278
279
280
281
  const uint8_t txh_unit = tx_size_high_unit[tx_size];
  return row * max_blocks_wide + col * txh_unit;
}

282
#if CONFIG_PVQ
Thomas Daede's avatar
Thomas Daede committed
283
static int av1_pvq_decode_helper(MACROBLOCKD *xd, tran_low_t *ref_coeff,
284
                                 tran_low_t *dqcoeff, int16_t *quant, int pli,
285
                                 int bs, TX_TYPE tx_type, int xdec,
ltrudeau's avatar
ltrudeau committed
286
                                 PVQ_SKIP_TYPE ac_dc_coded) {
287
288
289
290
  unsigned int flags;  // used for daala's stream analyzer.
  int off;
  const int is_keyframe = 0;
  const int has_dc_skip = 1;
291
  int coeff_shift = 3 - av1_get_tx_scale(bs);
Thomas Daede's avatar
Thomas Daede committed
292
  int hbd_downshift = 0;
293
  int rounding_mask;
294
295
296
297
298
299
  // 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
300
  od_dec_ctx *dec = &xd->daala_dec;
301
  int use_activity_masking = dec->use_activity_masking;
302
303
  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]);
304

305
306
  od_coeff ref_int32[OD_TXSIZE_MAX * OD_TXSIZE_MAX];
  od_coeff out_int32[OD_TXSIZE_MAX * OD_TXSIZE_MAX];
307

Thomas Daede's avatar
Thomas Daede committed
308
309
  hbd_downshift = xd->bd - 8;

310
311
312
  od_raster_to_coding_order(ref_coeff_pvq, blk_size, tx_type, ref_coeff,
                            blk_size);

Thomas Daede's avatar
Thomas Daede committed
313
  assert(OD_COEFF_SHIFT >= 4);
314
315
316
  if (lossless)
    pvq_dc_quant = 1;
  else {
317
    if (use_activity_masking)
clang-format's avatar
clang-format committed
318
319
320
321
322
      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);
323
    else
Thomas Daede's avatar
Thomas Daede committed
324
325
      pvq_dc_quant =
          OD_MAXI(1, quant[0] << (OD_COEFF_SHIFT - 3) >> hbd_downshift);
326
327
328
329
330
  }

  off = od_qm_offset(bs, xdec);

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

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

343
344
  if (!has_dc_skip || out_int32[0]) {
    out_int32[0] =
345
        has_dc_skip + generic_decode(dec->r, &dec->state.adapt->model_dc[pli],
346
347
                                     &dec->state.adapt->ex_dc[pli][bs][0], 2,
                                     "dc:mag");
348
349
350
351
352
353
354
355
    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
356
    out_int32[i] = AOM_SIGNED_SHL(out_int32[i], hbd_downshift);
357
358
    dqcoeff_pvq[i] = (out_int32[i] + (out_int32[i] < 0) + rounding_mask) >>
                     (OD_COEFF_SHIFT - coeff_shift);
359
360
361
362
363
364
365
366
367
  }

  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
368
369
370
371
372
373
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
374
  const int ac_dc_coded = aom_read_symbol(
ltrudeau's avatar
ltrudeau committed
375
      xd->daala_dec.r,
376
      xd->daala_dec.state.adapt->skip_cdf[2 * tx_size + (plane != 0)], 4,
377
      "skip");
ltrudeau's avatar
ltrudeau committed
378
379
380
381
382
383
384
385
  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,
386
387
                                  MB_MODE_INFO *const mbmi, int plane, int row,
                                  int col, TX_SIZE tx_size, TX_TYPE tx_type) {
388
389
390
391
392
393
394
395
396
397
  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
398
  const PVQ_SKIP_TYPE ac_dc_coded = read_pvq_skip(cm, xd, plane, tx_size);
399
400
401
402
403
404
405
406

  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;
407
    TxfmParam txfm_param;
408
409
    // ToDo(yaowu): correct this with optimal number from decoding process.
    const int max_scan_line = tx_size_2d[tx_size];
410
#if CONFIG_HIGHBITDEPTH
Thomas Daede's avatar
Thomas Daede committed
411
412
413
414
415
416
417
418
419
420
    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];
421
#if CONFIG_HIGHBITDEPTH
Thomas Daede's avatar
Thomas Daede committed
422
423
    }
#endif
424

425
426
427
    txfm_param.tx_type = tx_type;
    txfm_param.tx_size = tx_size;
    txfm_param.lossless = xd->lossless[seg_id];
428

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

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

Thomas Daede's avatar
Thomas Daede committed
442
443
    eob = av1_pvq_decode_helper(xd, pvq_ref_coeff, dqcoeff, quant, plane,
                                tx_size, tx_type, xdec, ac_dc_coded);
444

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

  return eob;
}
#endif

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

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

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

523
  if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
524

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

    assert(bsl > 0);

    for (i = 0; i < 4; ++i) {
Yue Chen's avatar
Yue Chen committed
570
571
572
573
574
575
576
577
578
#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
579
580
      const int offsetr = blk_row + (i >> 1) * bsl;
      const int offsetc = blk_col + (i & 0x01) * bsl;
Yue Chen's avatar
Yue Chen committed
581
#endif
582

583
      if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
584

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

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

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

648
649
650
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
651
652
653
654
655
656
657
658
659
  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;
660
661
662
#if CONFIG_RD_DEBUG
  xd->mi[0]->mbmi.mi_row = mi_row;
  xd->mi[0]->mbmi.mi_col = mi_col;
663
664
665
666
#endif
#if CONFIG_CFL
  xd->cfl->mi_row = mi_row;
  xd->cfl->mi_col = mi_col;
667
#endif
Jingning Han's avatar
Jingning Han committed
668
  for (y = 0; y < y_mis; ++y)
Jingning Han's avatar
Jingning Han committed
669
    for (x = !y; x < x_mis; ++x) xd->mi[y * cm->mi_stride + x] = xd->mi[0];
Jingning Han's avatar
Jingning Han committed
670

Jingning Han's avatar
Jingning Han committed
671
  set_plane_n4(xd, bw, bh);
Jingning Han's avatar
Jingning Han committed
672
673
  set_skip_context(xd, mi_row, mi_col);

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

682
683
  av1_setup_dst_planes(xd->plane, bsize, get_frame_new_buffer(cm), mi_row,
                       mi_col);
Jingning Han's avatar
Jingning Han committed
684
685
}

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

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

714
715
  int reader_corrupted_flag = aom_reader_has_error(r);
  aom_merge_corrupted_flag(&xd->corrupted, reader_corrupted_flag);
716
717
}

718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
#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);
738
739
740
741
742
743
744
745
    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);
746
747
  } else {
#endif  // CONFIG_HIGHBITDEPTH
748
749
750
751
    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);
752
753
754
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
#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

806
807
808
809
810
811
812
813
814
815
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);

816
817
  set_offsets(cm, xd, bsize, mi_row, mi_col, bw, bh, x_mis, y_mis);
  MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
818
819
820
821
822
#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
823

824
825
826
  if (cm->delta_q_present_flag) {
    int i;
    for (i = 0; i < MAX_SEGMENTS; i++) {
Fangwen Fu's avatar
Fangwen Fu committed
827
#if CONFIG_EXT_DELTA_Q
828
829
      const int current_qindex =
          av1_get_qindex(&cm->seg, i, xd->current_qindex);
Fangwen Fu's avatar
Fangwen Fu committed
830
#else
831
832
833
834
835
836
837
838
839
840
841
842
      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);
      }
843
844
    }
  }
845
  if (mbmi->skip) av1_reset_skip_context(xd, mi_row, mi_col, bsize);
846

847
848
849
850
851
#if CONFIG_COEF_INTERLEAVE
  {
    const struct macroblockd_plane *const pd_y = &xd->plane[0];
    const struct macroblockd_plane *const pd_c = &xd->plane[1];
    const TX_SIZE tx_log2_y = mbmi->tx_size;
852
    const TX_SIZE tx_log2_c = av1_get_uv_tx_size(mbmi, pd_c);
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
    const int tx_sz_y = (1 << tx_log2_y);
    const int tx_sz_c = (1 << tx_log2_c);
    const int num_4x4_w_y = pd_y->n4_w;
    const int num_4x4_h_y = pd_y->n4_h;
    const int num_4x4_w_c = pd_c->n4_w;
    const int num_4x4_h_c = pd_c->n4_h;
    const int max_4x4_w_y = get_max_4x4_size(num_4x4_w_y, xd->mb_to_right_edge,
                                             pd_y->subsampling_x);
    const int max_4x4_h_y = get_max_4x4_size(num_4x4_h_y, xd->mb_to_bottom_edge,
                                             pd_y->subsampling_y);
    const int max_4x4_w_c = get_max_4x4_size(num_4x4_w_c, xd->mb_to_right_edge,
                                             pd_c->subsampling_x);
    const int max_4x4_h_c = get_max_4x4_size(num_4x4_h_c, xd->mb_to_bottom_edge,
                                             pd_c->subsampling_y);

    // The max_4x4_w/h may be smaller than tx_sz under some corner cases,
    // i.e. when the SB is splitted by tile boundaries.
    const int tu_num_w_y = (max_4x4_w_y + tx_sz_y - 1) / tx_sz_y;
    const int tu_num_h_y = (max_4x4_h_y + tx_sz_y - 1) / tx_sz_y;
    const int tu_num_w_c = (max_4x4_w_c + tx_sz_c - 1) / tx_sz_c;
    const int tu_num_h_c = (max_4x4_h_c + tx_sz_c - 1) / tx_sz_c;
    const int tu_num_c = tu_num_w_c * tu_num_h_c;

    if (!is_inter_block(mbmi)) {
      int tu_idx_c = 0;
      int row_y, col_y, row_c, col_c;
      int plane;

881
882
// TODO(anybody) : remove this flag when PVQ supports pallete coding tool
#if !CONFIG_PVQ
883
884
885
886
      for (plane = 0; plane <= 1; ++plane) {
        if (mbmi->palette_mode_info.palette_size[plane])
          av1_decode_palette_tokens(xd, plane, r);
      }
887
#endif  // !CONFIG_PVQ
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918

      for (row_y = 0; row_y < tu_num_h_y; row_y++) {
        for (col_y = 0; col_y < tu_num_w_y; col_y++) {
          // luma
          predict_and_reconstruct_intra_block(
              cm, xd, r, mbmi, 0, row_y * tx_sz_y, col_y * tx_sz_y, tx_log2_y);
          // chroma
          if (tu_idx_c < tu_num_c) {
            row_c = (tu_idx_c / tu_num_w_c) * tx_sz_c;
            col_c = (tu_idx_c % tu_num_w_c) * tx_sz_c;
            predict_and_reconstruct_intra_block(cm, xd, r, mbmi, 1, row_c,
                                                col_c, tx_log2_c);
            predict_and_reconstruct_intra_block(cm, xd, r, mbmi, 2, row_c,
                                                col_c, tx_log2_c);
            tu_idx_c++;
          }
        }
      }

      // In 422 case, it's possilbe that Chroma has more TUs than Luma
      while (tu_idx_c < tu_num_c) {
        row_c = (tu_idx_c / tu_num_w_c) * tx_sz_c;
        col_c = (tu_idx_c % tu_num_w_c) * tx_sz_c;
        predict_and_reconstruct_intra_block(cm, xd, r, mbmi, 1, row_c, col_c,
                                            tx_log2_c);
        predict_and_reconstruct_intra_block(cm, xd, r, mbmi, 2, row_c, col_c,
                                            tx_log2_c);
        tu_idx_c++;
      }
    } else {
      // Prediction
919
      av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL,
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
                                    AOMMAX(bsize, BLOCK_8X8));

      // Reconstruction
      if (!mbmi->skip) {
        int eobtotal = 0;
        int tu_idx_c = 0;
        int row_y, col_y, row_c, col_c;

        for (row_y = 0; row_y < tu_num_h_y; row_y++) {
          for (col_y = 0; col_y < tu_num_w_y; col_y++) {
            // luma
            eobtotal += reconstruct_inter_block(cm, xd, r, mbmi->segment_id, 0,
                                                row_y * tx_sz_y,
                                                col_y * tx_sz_y, tx_log2_y);
            // chroma
            if (tu_idx_c < tu_num_c) {
              row_c = (tu_idx_c / tu_num_w_c) * tx_sz_c;
              col_c = (tu_idx_c % tu_num_w_c) * tx_sz_c;
              eobtotal += reconstruct_inter_block(cm, xd, r, mbmi->segment_id,
                                                  1, row_c, col_c, tx_log2_c);
              eobtotal += reconstruct_inter_block(cm, xd, r, mbmi->segment_id,
                                                  2, row_c, col_c, tx_log2_c);
              tu_idx_c++;
            }
          }
        }

        // In 422 case, it's possilbe that Chroma has more TUs than Luma
        while (tu_idx_c < tu_num_c) {
          row_c = (tu_idx_c / tu_num_w_c) * tx_sz_c;
          col_c = (tu_idx_c % tu_num_w_c) * tx_sz_c;
          eobtotal += reconstruct_inter_block(cm, xd, r, mbmi->segment_id, 1,
                                              row_c, col_c, tx_log2_c);
          eobtotal += reconstruct_inter_block(cm, xd, r, mbmi->segment_id, 2,
                                              row_c, col_c, tx_log2_c);
          tu_idx_c++;
        }