decodeframe.c 148 KB
Newer Older
Jingning Han's avatar
Jingning Han committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/*
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

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

#include "./vp10_rtcd.h"
15
#include "./vpx_config.h"
Jingning Han's avatar
Jingning Han committed
16 17
#include "./vpx_dsp_rtcd.h"
#include "./vpx_scale_rtcd.h"
18
#include "./vpx_config.h"
Jingning Han's avatar
Jingning Han committed
19

20 21 22 23 24 25 26 27
#include "aom_dsp/bitreader_buffer.h"
#include "av1/decoder/bitreader.h"
#include "aom_dsp/vpx_dsp_common.h"
#include "aom_mem/vpx_mem.h"
#include "aom_ports/mem.h"
#include "aom_ports/mem_ops.h"
#include "aom_scale/vpx_scale.h"
#include "aom_util/vpx_thread.h"
Jingning Han's avatar
Jingning Han committed
28

29
#include "av1/common/alloccommon.h"
30
#if CONFIG_CLPF
31
#include "av1/common/clpf.h"
32
#endif
33
#include "av1/common/common.h"
Yaowu Xu's avatar
Yaowu Xu committed
34
#if CONFIG_DERING
35
#include "av1/common/dering.h"
Yaowu Xu's avatar
Yaowu Xu committed
36
#endif  // CONFIG_DERING
37 38 39 40 41 42 43 44 45 46
#include "av1/common/entropy.h"
#include "av1/common/entropymode.h"
#include "av1/common/idct.h"
#include "av1/common/thread_common.h"
#include "av1/common/pred_common.h"
#include "av1/common/quant_common.h"
#include "av1/common/reconintra.h"
#include "av1/common/reconinter.h"
#include "av1/common/seg_common.h"
#include "av1/common/tile_common.h"
47

48 49 50 51 52
#include "av1/decoder/decodeframe.h"
#include "av1/decoder/detokenize.h"
#include "av1/decoder/decodemv.h"
#include "av1/decoder/decoder.h"
#include "av1/decoder/dsubexp.h"
Jingning Han's avatar
Jingning Han committed
53

54
#define MAX_VPX_HEADER_SIZE 80
Jingning Han's avatar
Jingning Han committed
55

Yaowu Xu's avatar
Yaowu Xu committed
56
static int is_compound_reference_allowed(const VP10_COMMON *cm) {
Jingning Han's avatar
Jingning Han committed
57
  int i;
58
  if (frame_is_intra_only(cm)) return 0;
59
  for (i = 1; i < INTER_REFS_PER_FRAME; ++i)
60
    if (cm->ref_frame_sign_bias[i + 1] != cm->ref_frame_sign_bias[1]) return 1;
Jingning Han's avatar
Jingning Han committed
61 62 63 64

  return 0;
}

Yaowu Xu's avatar
Yaowu Xu committed
65
static void setup_compound_reference_mode(VP10_COMMON *cm) {
66
#if CONFIG_EXT_REFS
67
  cm->comp_fwd_ref[0] = LAST_FRAME;
68 69 70 71
  cm->comp_fwd_ref[1] = LAST2_FRAME;
  cm->comp_fwd_ref[2] = LAST3_FRAME;
  cm->comp_fwd_ref[3] = GOLDEN_FRAME;

72 73
  cm->comp_bwd_ref[0] = BWDREF_FRAME;
  cm->comp_bwd_ref[1] = ALTREF_FRAME;
74
#else
Jingning Han's avatar
Jingning Han committed
75
  if (cm->ref_frame_sign_bias[LAST_FRAME] ==
76
      cm->ref_frame_sign_bias[GOLDEN_FRAME]) {
Jingning Han's avatar
Jingning Han committed
77 78 79 80
    cm->comp_fixed_ref = ALTREF_FRAME;
    cm->comp_var_ref[0] = LAST_FRAME;
    cm->comp_var_ref[1] = GOLDEN_FRAME;
  } else if (cm->ref_frame_sign_bias[LAST_FRAME] ==
81
             cm->ref_frame_sign_bias[ALTREF_FRAME]) {
Jingning Han's avatar
Jingning Han committed
82 83 84 85 86 87 88 89
    cm->comp_fixed_ref = GOLDEN_FRAME;
    cm->comp_var_ref[0] = LAST_FRAME;
    cm->comp_var_ref[1] = ALTREF_FRAME;
  } else {
    cm->comp_fixed_ref = LAST_FRAME;
    cm->comp_var_ref[0] = GOLDEN_FRAME;
    cm->comp_var_ref[1] = ALTREF_FRAME;
  }
90
#endif  // CONFIG_EXT_REFS
Jingning Han's avatar
Jingning Han committed
91 92 93 94 95 96 97 98 99 100 101
}

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

static int decode_unsigned_max(struct vpx_read_bit_buffer *rb, int max) {
  const int data = vpx_rb_read_literal(rb, get_unsigned_bits(max));
  return data > max ? max : data;
}

102 103 104
static TX_MODE read_tx_mode(struct vpx_read_bit_buffer *rb) {
  return vpx_rb_read_bit(rb) ? TX_MODE_SELECT : vpx_rb_read_literal(rb, 2);
}
Jingning Han's avatar
Jingning Han committed
105

106
static void read_switchable_interp_probs(FRAME_CONTEXT *fc, vp10_reader *r) {
Jingning Han's avatar
Jingning Han committed
107 108 109 110 111 112
  int i, j;
  for (j = 0; j < SWITCHABLE_FILTER_CONTEXTS; ++j)
    for (i = 0; i < SWITCHABLE_FILTERS - 1; ++i)
      vp10_diff_update_prob(r, &fc->switchable_interp_prob[j][i]);
}

113
static void read_inter_mode_probs(FRAME_CONTEXT *fc, vp10_reader *r) {
114 115 116 117 118 119 120 121
  int i;
#if CONFIG_REF_MV
  for (i = 0; i < NEWMV_MODE_CONTEXTS; ++i)
    vp10_diff_update_prob(r, &fc->newmv_prob[i]);
  for (i = 0; i < ZEROMV_MODE_CONTEXTS; ++i)
    vp10_diff_update_prob(r, &fc->zeromv_prob[i]);
  for (i = 0; i < REFMV_MODE_CONTEXTS; ++i)
    vp10_diff_update_prob(r, &fc->refmv_prob[i]);
122
  for (i = 0; i < DRL_MODE_CONTEXTS; ++i)
123
    vp10_diff_update_prob(r, &fc->drl_prob[i]);
Yue Chen's avatar
Yue Chen committed
124 125 126
#if CONFIG_EXT_INTER
  vp10_diff_update_prob(r, &fc->new2mv_prob);
#endif  // CONFIG_EXT_INTER
127 128
#else
  int j;
Jingning Han's avatar
Jingning Han committed
129 130 131
  for (i = 0; i < INTER_MODE_CONTEXTS; ++i)
    for (j = 0; j < INTER_MODES - 1; ++j)
      vp10_diff_update_prob(r, &fc->inter_mode_probs[i][j]);
132
#endif
Jingning Han's avatar
Jingning Han committed
133 134
}

135
#if CONFIG_EXT_INTER
136
static void read_inter_compound_mode_probs(FRAME_CONTEXT *fc, vp10_reader *r) {
137
  int i, j;
138
  if (vp10_read(r, GROUP_DIFF_UPDATE_PROB)) {
139 140 141 142 143 144 145 146 147
    for (j = 0; j < INTER_MODE_CONTEXTS; ++j) {
      for (i = 0; i < INTER_COMPOUND_MODES - 1; ++i) {
        vp10_diff_update_prob(r, &fc->inter_compound_mode_probs[j][i]);
      }
    }
  }
}
#endif  // CONFIG_EXT_INTER

148 149
static REFERENCE_MODE read_frame_reference_mode(
    const VP10_COMMON *cm, struct vpx_read_bit_buffer *rb) {
150
  if (is_compound_reference_allowed(cm)) {
151 152 153
    return vpx_rb_read_bit(rb)
               ? REFERENCE_MODE_SELECT
               : (vpx_rb_read_bit(rb) ? COMPOUND_REFERENCE : SINGLE_REFERENCE);
154 155 156 157
  } else {
    return SINGLE_REFERENCE;
  }
}
Jingning Han's avatar
Jingning Han committed
158

159
static void read_frame_reference_mode_probs(VP10_COMMON *cm, vp10_reader *r) {
Jingning Han's avatar
Jingning Han committed
160
  FRAME_CONTEXT *const fc = cm->fc;
161
  int i, j;
Jingning Han's avatar
Jingning Han committed
162 163 164 165 166

  if (cm->reference_mode == REFERENCE_MODE_SELECT)
    for (i = 0; i < COMP_INTER_CONTEXTS; ++i)
      vp10_diff_update_prob(r, &fc->comp_inter_prob[i]);

167
  if (cm->reference_mode != COMPOUND_REFERENCE) {
Jingning Han's avatar
Jingning Han committed
168
    for (i = 0; i < REF_CONTEXTS; ++i) {
169 170 171
      for (j = 0; j < (SINGLE_REFS - 1); ++j) {
        vp10_diff_update_prob(r, &fc->single_ref_prob[i][j]);
      }
Jingning Han's avatar
Jingning Han committed
172
    }
173
  }
Jingning Han's avatar
Jingning Han committed
174

175 176
  if (cm->reference_mode != SINGLE_REFERENCE) {
    for (i = 0; i < REF_CONTEXTS; ++i) {
177
#if CONFIG_EXT_REFS
178
      for (j = 0; j < (FWD_REFS - 1); ++j)
179
        vp10_diff_update_prob(r, &fc->comp_ref_prob[i][j]);
180 181 182 183 184
      for (j = 0; j < (BWD_REFS - 1); ++j)
        vp10_diff_update_prob(r, &fc->comp_bwdref_prob[i][j]);
#else
      for (j = 0; j < (COMP_REFS - 1); ++j)
        vp10_diff_update_prob(r, &fc->comp_ref_prob[i][j]);
185
#endif  // CONFIG_EXT_REFS
186 187
    }
  }
Jingning Han's avatar
Jingning Han committed
188 189
}

190
static void update_mv_probs(vpx_prob *p, int n, vp10_reader *r) {
Jingning Han's avatar
Jingning Han committed
191
  int i;
192
  for (i = 0; i < n; ++i) vp10_diff_update_prob(r, &p[i]);
Jingning Han's avatar
Jingning Han committed
193 194
}

195
static void read_mv_probs(nmv_context *ctx, int allow_hp, vp10_reader *r) {
Jingning Han's avatar
Jingning Han committed
196 197 198 199
  int i, j;

  update_mv_probs(ctx->joints, MV_JOINTS - 1, r);

200 201 202 203
#if CONFIG_REF_MV
  vp10_diff_update_prob(r, &ctx->zero_rmv);
#endif

Jingning Han's avatar
Jingning Han committed
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227
  for (i = 0; i < 2; ++i) {
    nmv_component *const comp_ctx = &ctx->comps[i];
    update_mv_probs(&comp_ctx->sign, 1, r);
    update_mv_probs(comp_ctx->classes, MV_CLASSES - 1, r);
    update_mv_probs(comp_ctx->class0, CLASS0_SIZE - 1, r);
    update_mv_probs(comp_ctx->bits, MV_OFFSET_BITS, r);
  }

  for (i = 0; i < 2; ++i) {
    nmv_component *const comp_ctx = &ctx->comps[i];
    for (j = 0; j < CLASS0_SIZE; ++j)
      update_mv_probs(comp_ctx->class0_fp[j], MV_FP_SIZE - 1, r);
    update_mv_probs(comp_ctx->fp, 3, r);
  }

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

228
static void inverse_transform_block(MACROBLOCKD *xd, int plane,
229
                                    const TX_TYPE tx_type,
230 231
                                    const TX_SIZE tx_size, uint8_t *dst,
                                    int stride, int eob) {
Jingning Han's avatar
Jingning Han committed
232 233 234
  struct macroblockd_plane *const pd = &xd->plane[plane];
  if (eob > 0) {
    tran_low_t *const dqcoeff = pd->dqcoeff;
Angie Chiang's avatar
Angie Chiang committed
235 236 237 238
    INV_TXFM_PARAM inv_txfm_param;
    inv_txfm_param.tx_type = tx_type;
    inv_txfm_param.tx_size = tx_size;
    inv_txfm_param.eob = eob;
239
    inv_txfm_param.lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
Angie Chiang's avatar
Angie Chiang committed
240

Jingning Han's avatar
Jingning Han committed
241 242
#if CONFIG_VP9_HIGHBITDEPTH
    if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Angie Chiang's avatar
Angie Chiang committed
243 244
      inv_txfm_param.bd = xd->bd;
      highbd_inv_txfm_add(dqcoeff, dst, stride, &inv_txfm_param);
Jingning Han's avatar
Jingning Han committed
245
    } else {
246
#endif  // CONFIG_VP9_HIGHBITDEPTH
Angie Chiang's avatar
Angie Chiang committed
247
      inv_txfm_add(dqcoeff, dst, stride, &inv_txfm_param);
hui su's avatar
hui su committed
248
#if CONFIG_VP9_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
249 250 251 252 253 254
    }
#endif  // CONFIG_VP9_HIGHBITDEPTH

    if (eob == 1) {
      dqcoeff[0] = 0;
    } else {
255
      if (tx_type == DCT_DCT && tx_size <= TX_16X16 && eob <= 10)
256
        memset(dqcoeff, 0, 4 * 4 * num_4x4_blocks_wide_txsize_lookup[tx_size] *
257
                               sizeof(dqcoeff[0]));
258 259
#if CONFIG_EXT_TX
      else
260
        memset(dqcoeff, 0, get_tx2d_size(tx_size) * sizeof(dqcoeff[0]));
261
#else
Jingning Han's avatar
Jingning Han committed
262 263 264
      else if (tx_size == TX_32X32 && eob <= 34)
        memset(dqcoeff, 0, 256 * sizeof(dqcoeff[0]));
      else
265
        memset(dqcoeff, 0, get_tx2d_size(tx_size) * sizeof(dqcoeff[0]));
266
#endif
Jingning Han's avatar
Jingning Han committed
267 268 269 270 271
    }
  }
}

static void predict_and_reconstruct_intra_block(MACROBLOCKD *const xd,
Alex Converse's avatar
Alex Converse committed
272 273 274
#if CONFIG_ANS
                                                struct AnsDecoder *const r,
#else
275
                                                vp10_reader *r,
Alex Converse's avatar
Alex Converse committed
276
#endif  // CONFIG_ANS
Jingning Han's avatar
Jingning Han committed
277
                                                MB_MODE_INFO *const mbmi,
278
                                                int plane, int row, int col,
Jingning Han's avatar
Jingning Han committed
279 280 281
                                                TX_SIZE tx_size) {
  struct macroblockd_plane *const pd = &xd->plane[plane];
  PREDICTION_MODE mode = (plane == 0) ? mbmi->mode : mbmi->uv_mode;
hui su's avatar
hui su committed
282
  PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV;
Jingning Han's avatar
Jingning Han committed
283
  uint8_t *dst;
hui su's avatar
hui su committed
284
  int block_idx = (row << 1) + col;
Jingning Han's avatar
Jingning Han committed
285 286 287
  dst = &pd->dst.buf[4 * row * pd->dst.stride + 4 * col];

  if (mbmi->sb_type < BLOCK_8X8)
288
    if (plane == 0) mode = xd->mi[0]->bmi[(row << 1) + col].as_mode;
Jingning Han's avatar
Jingning Han committed
289

290 291 292
  vp10_predict_intra_block(xd, pd->n4_wl, pd->n4_hl, tx_size, mode, dst,
                           pd->dst.stride, dst, pd->dst.stride, col, row,
                           plane);
Jingning Han's avatar
Jingning Han committed
293 294

  if (!mbmi->skip) {
hui su's avatar
hui su committed
295
    TX_TYPE tx_type = get_tx_type(plane_type, xd, block_idx, tx_size);
296
    const scan_order *sc = get_scan(tx_size, tx_type, 0);
297
    const int eob = vp10_decode_block_tokens(xd, plane, sc, col, row, tx_size,
Angie Chiang's avatar
Angie Chiang committed
298
                                             tx_type, r, mbmi->segment_id);
299 300
    inverse_transform_block(xd, plane, tx_type, tx_size, dst, pd->dst.stride,
                            eob);
Jingning Han's avatar
Jingning Han committed
301 302 303
  }
}

304
#if CONFIG_VAR_TX
305
static void decode_reconstruct_tx(MACROBLOCKD *const xd, vp10_reader *r,
306 307 308 309
                                  MB_MODE_INFO *const mbmi, int plane,
                                  BLOCK_SIZE plane_bsize, int block,
                                  int blk_row, int blk_col, TX_SIZE tx_size,
                                  int *eob_total) {
310
  const struct macroblockd_plane *const pd = &xd->plane[plane];
311
  const BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
312 313
  const int tx_row = blk_row >> (1 - pd->subsampling_y);
  const int tx_col = blk_col >> (1 - pd->subsampling_x);
314 315 316 317
  const TX_SIZE plane_tx_size =
      plane ? get_uv_tx_size_impl(mbmi->inter_tx_size[tx_row][tx_col], bsize, 0,
                                  0)
            : mbmi->inter_tx_size[tx_row][tx_col];
318 319 320 321 322 323 324 325
  int max_blocks_high = num_4x4_blocks_high_lookup[plane_bsize];
  int max_blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize];

  if (xd->mb_to_bottom_edge < 0)
    max_blocks_high += xd->mb_to_bottom_edge >> (5 + pd->subsampling_y);
  if (xd->mb_to_right_edge < 0)
    max_blocks_wide += xd->mb_to_right_edge >> (5 + pd->subsampling_x);

326
  if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
327

328
  if (tx_size == plane_tx_size) {
329
    PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV;
330 331
    TX_TYPE tx_type = get_tx_type(plane_type, xd, block, plane_tx_size);
    const scan_order *sc = get_scan(plane_tx_size, tx_type, 1);
332 333 334 335 336
    const int eob =
        vp10_decode_block_tokens(xd, plane, sc, blk_col, blk_row, plane_tx_size,
                                 tx_type, r, mbmi->segment_id);
    inverse_transform_block(
        xd, plane, tx_type, plane_tx_size,
337
        &pd->dst.buf[4 * blk_row * pd->dst.stride + 4 * blk_col],
338
        pd->dst.stride, eob);
339 340 341 342 343 344 345 346 347 348 349
    *eob_total += eob;
  } else {
    int bsl = b_width_log2_lookup[bsize];
    int i;

    assert(bsl > 0);
    --bsl;

    for (i = 0; i < 4; ++i) {
      const int offsetr = blk_row + ((i >> 1) << bsl);
      const int offsetc = blk_col + ((i & 0x01) << bsl);
350
      int step = num_4x4_blocks_txsize_lookup[tx_size - 1];
351

352
      if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
353 354 355 356 357 358

      decode_reconstruct_tx(xd, r, mbmi, plane, plane_bsize, block + i * step,
                            offsetr, offsetc, tx_size - 1, eob_total);
    }
  }
}
359
#endif  // CONFIG_VAR_TX
360

361
#if !CONFIG_VAR_TX || CONFIG_SUPERTX || (CONFIG_EXT_TX && CONFIG_RECT_TX)
Alex Converse's avatar
Alex Converse committed
362 363 364 365
static int reconstruct_inter_block(MACROBLOCKD *const xd,
#if CONFIG_ANS
                                   struct AnsDecoder *const r,
#else
366
                                   vp10_reader *r,
Alex Converse's avatar
Alex Converse committed
367
#endif
368 369
                                   int segment_id, int plane, int row, int col,
                                   TX_SIZE tx_size) {
Jingning Han's avatar
Jingning Han committed
370
  struct macroblockd_plane *const pd = &xd->plane[plane];
hui su's avatar
hui su committed
371 372
  PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV;
  int block_idx = (row << 1) + col;
hui su's avatar
hui su committed
373
  TX_TYPE tx_type = get_tx_type(plane_type, xd, block_idx, tx_size);
374
  const scan_order *sc = get_scan(tx_size, tx_type, 1);
375 376
  const int eob = vp10_decode_block_tokens(xd, plane, sc, col, row, tx_size,
                                           tx_type, r, segment_id);
Jingning Han's avatar
Jingning Han committed
377

378 379 380
  inverse_transform_block(xd, plane, tx_type, tx_size,
                          &pd->dst.buf[4 * row * pd->dst.stride + 4 * col],
                          pd->dst.stride, eob);
Jingning Han's avatar
Jingning Han committed
381 382
  return eob;
}
383
#endif  // !CONFIG_VAR_TX || CONFIG_SUPER_TX
Jingning Han's avatar
Jingning Han committed
384

385 386
static INLINE TX_SIZE dec_get_uv_tx_size(const MB_MODE_INFO *mbmi, int n4_wl,
                                         int n4_hl) {
Jingning Han's avatar
Jingning Han committed
387
  // get minimum log2 num4x4s dimension
388
  const int x = VPXMIN(n4_wl, n4_hl);
Debargha Mukherjee's avatar
Debargha Mukherjee committed
389
  return VPXMIN(txsize_sqr_map[mbmi->tx_size], x);
Jingning Han's avatar
Jingning Han committed
390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411
}

static INLINE void dec_reset_skip_context(MACROBLOCKD *xd) {
  int i;
  for (i = 0; i < MAX_MB_PLANE; i++) {
    struct macroblockd_plane *const pd = &xd->plane[i];
    memset(pd->above_context, 0, sizeof(ENTROPY_CONTEXT) * pd->n4_w);
    memset(pd->left_context, 0, sizeof(ENTROPY_CONTEXT) * pd->n4_h);
  }
}

static void set_plane_n4(MACROBLOCKD *const xd, int bw, int bh, int bwl,
                         int bhl) {
  int i;
  for (i = 0; i < MAX_MB_PLANE; i++) {
    xd->plane[i].n4_w = (bw << 1) >> xd->plane[i].subsampling_x;
    xd->plane[i].n4_h = (bh << 1) >> xd->plane[i].subsampling_y;
    xd->plane[i].n4_wl = bwl - xd->plane[i].subsampling_x;
    xd->plane[i].n4_hl = bhl - xd->plane[i].subsampling_y;
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
412
static MB_MODE_INFO *set_offsets(VP10_COMMON *const cm, MACROBLOCKD *const xd,
Jingning Han's avatar
Jingning Han committed
413
                                 BLOCK_SIZE bsize, int mi_row, int mi_col,
414 415
                                 int bw, int bh, int x_mis, int y_mis, int bwl,
                                 int bhl) {
Jingning Han's avatar
Jingning Han committed
416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433
  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;
  for (y = 0; y < y_mis; ++y)
    for (x = !y; x < x_mis; ++x) {
      xd->mi[y * cm->mi_stride + x] = xd->mi[0];
    }

  set_plane_n4(xd, bw, bh, bwl, bhl);

  set_skip_context(xd, mi_row, mi_col);

434 435 436 437
#if CONFIG_VAR_TX
  xd->max_tx_size = max_txsize_lookup[bsize];
#endif

Jingning Han's avatar
Jingning Han committed
438 439 440 441 442 443 444 445
  // 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, cm->mi_rows, cm->mi_cols);

  vp10_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
  return &xd->mi[0]->mbmi;
}

446 447 448 449
#if CONFIG_SUPERTX
static MB_MODE_INFO *set_offsets_extend(VP10_COMMON *const cm,
                                        MACROBLOCKD *const xd,
                                        const TileInfo *const tile,
450 451 452
                                        BLOCK_SIZE bsize_pred, int mi_row_pred,
                                        int mi_col_pred, int mi_row_ori,
                                        int mi_col_ori) {
453 454 455 456 457 458 459 460 461 462
  // Used in supertx
  // (mi_row_ori, mi_col_ori): location for mv
  // (mi_row_pred, mi_col_pred, bsize_pred): region to predict
  const int bw = num_8x8_blocks_wide_lookup[bsize_pred];
  const int bh = num_8x8_blocks_high_lookup[bsize_pred];
  const int offset = mi_row_ori * cm->mi_stride + mi_col_ori;
  const int bwl = b_width_log2_lookup[bsize_pred];
  const int bhl = b_height_log2_lookup[bsize_pred];
  xd->mi = cm->mi_grid_visible + offset;
  xd->mi[0] = cm->mi + offset;
463 464
  set_mi_row_col(xd, tile, mi_row_pred, bh, mi_col_pred, bw, cm->mi_rows,
                 cm->mi_cols);
465

466 467
  xd->up_available = (mi_row_ori > tile->mi_row_start);
  xd->left_available = (mi_col_ori > tile->mi_col_start);
468 469 470 471 472 473 474

  set_plane_n4(xd, bw, bh, bwl, bhl);

  return &xd->mi[0]->mbmi;
}

static MB_MODE_INFO *set_mb_offsets(VP10_COMMON *const cm,
475 476
                                    MACROBLOCKD *const xd, BLOCK_SIZE bsize,
                                    int mi_row, int mi_col, int bw, int bh,
477 478 479 480 481 482 483 484 485
                                    int x_mis, int y_mis) {
  const int offset = mi_row * cm->mi_stride + mi_col;
  const TileInfo *const tile = &xd->tile;
  int x, y;

  xd->mi = cm->mi_grid_visible + offset;
  xd->mi[0] = cm->mi + offset;
  xd->mi[0]->mbmi.sb_type = bsize;
  for (y = 0; y < y_mis; ++y)
486
    for (x = !y; x < x_mis; ++x) xd->mi[y * cm->mi_stride + x] = xd->mi[0];
487 488 489 490 491 492

  set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols);
  return &xd->mi[0]->mbmi;
}

static void set_offsets_topblock(VP10_COMMON *const cm, MACROBLOCKD *const xd,
493 494
                                 const TileInfo *const tile, BLOCK_SIZE bsize,
                                 int mi_row, int mi_col) {
495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510
  const int bw = num_8x8_blocks_wide_lookup[bsize];
  const int bh = num_8x8_blocks_high_lookup[bsize];
  const int offset = mi_row * cm->mi_stride + mi_col;
  const int bwl = b_width_log2_lookup[bsize];
  const int bhl = b_height_log2_lookup[bsize];

  xd->mi = cm->mi_grid_visible + offset;
  xd->mi[0] = cm->mi + offset;

  set_plane_n4(xd, bw, bh, bwl, bhl);

  set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols);

  vp10_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
}

511
static void set_param_topblock(VP10_COMMON *const cm, MACROBLOCKD *const xd,
512
                               BLOCK_SIZE bsize, int mi_row, int mi_col,
513
                               int txfm, int skip) {
514 515 516 517 518 519 520 521 522 523 524 525 526 527 528
  const int bw = num_8x8_blocks_wide_lookup[bsize];
  const int bh = num_8x8_blocks_high_lookup[bsize];
  const int x_mis = VPXMIN(bw, cm->mi_cols - mi_col);
  const int y_mis = VPXMIN(bh, cm->mi_rows - mi_row);
  const int offset = mi_row * cm->mi_stride + mi_col;
  int x, y;

  xd->mi = cm->mi_grid_visible + offset;
  xd->mi[0] = cm->mi + offset;

  for (y = 0; y < y_mis; ++y)
    for (x = 0; x < x_mis; ++x) {
      xd->mi[y * cm->mi_stride + x]->mbmi.skip = skip;
      xd->mi[y * cm->mi_stride + x]->mbmi.tx_type = txfm;
    }
529 530
#if CONFIG_VAR_TX
  xd->above_txfm_context = cm->above_txfm_context + mi_col;
531
  xd->left_txfm_context =
532
      xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
533
  set_txfm_ctxs(xd->mi[0]->mbmi.tx_size, bw, bh, xd);
534
#endif
535 536
}

537 538
static void set_ref(VP10_COMMON *const cm, MACROBLOCKD *const xd, int idx,
                    int mi_row, int mi_col) {
539 540 541 542 543 544 545 546 547 548 549 550
  MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
  RefBuffer *ref_buffer = &cm->frame_refs[mbmi->ref_frame[idx] - LAST_FRAME];
  xd->block_refs[idx] = ref_buffer;
  if (!vp10_is_valid_scale(&ref_buffer->sf))
    vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
                       "Invalid scale factors");
  vp10_setup_pre_planes(xd, idx, ref_buffer->buf, mi_row, mi_col,
                        &ref_buffer->sf);
  xd->corrupted |= ref_buffer->buf->corrupted;
}

static void dec_predict_b_extend(
551 552 553 554
    VP10Decoder *const pbi, MACROBLOCKD *const xd, const TileInfo *const tile,
    int block, int mi_row_ori, int mi_col_ori, int mi_row_pred, int mi_col_pred,
    int mi_row_top, int mi_col_top, uint8_t *dst_buf[3], int dst_stride[3],
    BLOCK_SIZE bsize_top, BLOCK_SIZE bsize_pred, int b_sub8x8, int bextend) {
555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570
  // Used in supertx
  // (mi_row_ori, mi_col_ori): location for mv
  // (mi_row_pred, mi_col_pred, bsize_pred): region to predict
  // (mi_row_top, mi_col_top, bsize_top): region of the top partition size
  // block: sub location of sub8x8 blocks
  // b_sub8x8: 1: ori is sub8x8; 0: ori is not sub8x8
  // bextend: 1: region to predict is an extension of ori; 0: not
  int r = (mi_row_pred - mi_row_top) * MI_SIZE;
  int c = (mi_col_pred - mi_col_top) * MI_SIZE;
  const int mi_width_top = num_8x8_blocks_wide_lookup[bsize_top];
  const int mi_height_top = num_8x8_blocks_high_lookup[bsize_top];
  MB_MODE_INFO *mbmi;
  VP10_COMMON *const cm = &pbi->common;

  if (mi_row_pred < mi_row_top || mi_col_pred < mi_col_top ||
      mi_row_pred >= mi_row_top + mi_height_top ||
571 572
      mi_col_pred >= mi_col_top + mi_width_top || mi_row_pred >= cm->mi_rows ||
      mi_col_pred >= cm->mi_cols)
573 574
    return;

575
  mbmi = set_offsets_extend(cm, xd, tile, bsize_pred, mi_row_pred, mi_col_pred,
576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598
                            mi_row_ori, mi_col_ori);
  set_ref(cm, xd, 0, mi_row_pred, mi_col_pred);
  if (has_second_ref(&xd->mi[0]->mbmi))
    set_ref(cm, xd, 1, mi_row_pred, mi_col_pred);

  if (!bextend) {
    mbmi->tx_size = b_width_log2_lookup[bsize_top];
  }

  xd->plane[0].dst.stride = dst_stride[0];
  xd->plane[1].dst.stride = dst_stride[1];
  xd->plane[2].dst.stride = dst_stride[2];
  xd->plane[0].dst.buf = dst_buf[0] +
                         (r >> xd->plane[0].subsampling_y) * dst_stride[0] +
                         (c >> xd->plane[0].subsampling_x);
  xd->plane[1].dst.buf = dst_buf[1] +
                         (r >> xd->plane[1].subsampling_y) * dst_stride[1] +
                         (c >> xd->plane[1].subsampling_x);
  xd->plane[2].dst.buf = dst_buf[2] +
                         (r >> xd->plane[2].subsampling_y) * dst_stride[2] +
                         (c >> xd->plane[2].subsampling_x);

  if (!b_sub8x8)
599
    vp10_build_inter_predictors_sb_extend(xd,
600
#if CONFIG_EXT_INTER
601
                                          mi_row_ori, mi_col_ori,
602
#endif  // CONFIG_EXT_INTER
603
                                          mi_row_pred, mi_col_pred, bsize_pred);
604
  else
605
    vp10_build_inter_predictors_sb_sub8x8_extend(xd,
606
#if CONFIG_EXT_INTER
607
                                                 mi_row_ori, mi_col_ori,
608
#endif  // CONFIG_EXT_INTER
609 610
                                                 mi_row_pred, mi_col_pred,
                                                 bsize_pred, block);
611 612 613 614
}

static void dec_extend_dir(VP10Decoder *const pbi, MACROBLOCKD *const xd,
                           const TileInfo *const tile, int block,
615 616 617
                           BLOCK_SIZE bsize, BLOCK_SIZE top_bsize, int mi_row,
                           int mi_col, int mi_row_top, int mi_col_top,
                           uint8_t *dst_buf[3], int dst_stride[3], int dir) {
618 619 620 621 622 623 624 625 626 627 628
  // dir: 0-lower, 1-upper, 2-left, 3-right
  //      4-lowerleft, 5-upperleft, 6-lowerright, 7-upperright
  const int mi_width = num_8x8_blocks_wide_lookup[bsize];
  const int mi_height = num_8x8_blocks_high_lookup[bsize];
  int xss = xd->plane[1].subsampling_x;
  int yss = xd->plane[1].subsampling_y;
  int b_sub8x8 = (bsize < BLOCK_8X8) ? 1 : 0;
  BLOCK_SIZE extend_bsize;
  int unit, mi_row_pred, mi_col_pred;

  if (dir == 0 || dir == 1) {
629 630 631
    extend_bsize = (mi_width == 1 || bsize < BLOCK_8X8 || xss < yss)
                       ? BLOCK_8X8
                       : BLOCK_16X8;
632 633 634 635
    unit = num_8x8_blocks_wide_lookup[extend_bsize];
    mi_row_pred = mi_row + ((dir == 0) ? mi_height : -1);
    mi_col_pred = mi_col;

636 637 638
    dec_predict_b_extend(pbi, xd, tile, block, mi_row, mi_col, mi_row_pred,
                         mi_col_pred, mi_row_top, mi_col_top, dst_buf,
                         dst_stride, top_bsize, extend_bsize, b_sub8x8, 1);
639 640 641 642

    if (mi_width > unit) {
      int i;
      assert(!b_sub8x8);
643
      for (i = 0; i < mi_width / unit - 1; i++) {
644
        mi_col_pred += unit;
645 646 647
        dec_predict_b_extend(pbi, xd, tile, block, mi_row, mi_col, mi_row_pred,
                             mi_col_pred, mi_row_top, mi_col_top, dst_buf,
                             dst_stride, top_bsize, extend_bsize, b_sub8x8, 1);
648 649 650
      }
    }
  } else if (dir == 2 || dir == 3) {
651 652 653
    extend_bsize = (mi_height == 1 || bsize < BLOCK_8X8 || yss < xss)
                       ? BLOCK_8X8
                       : BLOCK_8X16;
654 655 656 657
    unit = num_8x8_blocks_high_lookup[extend_bsize];
    mi_row_pred = mi_row;
    mi_col_pred = mi_col + ((dir == 3) ? mi_width : -1);

658 659 660
    dec_predict_b_extend(pbi, xd, tile, block, mi_row, mi_col, mi_row_pred,
                         mi_col_pred, mi_row_top, mi_col_top, dst_buf,
                         dst_stride, top_bsize, extend_bsize, b_sub8x8, 1);
661 662 663

    if (mi_height > unit) {
      int i;
664
      for (i = 0; i < mi_height / unit - 1; i++) {
665
        mi_row_pred += unit;
666 667 668
        dec_predict_b_extend(pbi, xd, tile, block, mi_row, mi_col, mi_row_pred,
                             mi_col_pred, mi_row_top, mi_col_top, dst_buf,
                             dst_stride, top_bsize, extend_bsize, b_sub8x8, 1);
669 670 671 672 673 674
      }
    }
  } else {
    extend_bsize = BLOCK_8X8;
    mi_row_pred = mi_row + ((dir == 4 || dir == 6) ? mi_height : -1);
    mi_col_pred = mi_col + ((dir == 6 || dir == 7) ? mi_width : -1);
675 676 677
    dec_predict_b_extend(pbi, xd, tile, block, mi_row, mi_col, mi_row_pred,
                         mi_col_pred, mi_row_top, mi_col_top, dst_buf,
                         dst_stride, top_bsize, extend_bsize, b_sub8x8, 1);
678 679 680 681 682
  }
}

static void dec_extend_all(VP10Decoder *const pbi, MACROBLOCKD *const xd,
                           const TileInfo *const tile, int block,
683 684 685
                           BLOCK_SIZE bsize, BLOCK_SIZE top_bsize, int mi_row,
                           int mi_col, int mi_row_top, int mi_col_top,
                           uint8_t *dst_buf[3], int dst_stride[3]) {
686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705
  dec_extend_dir(pbi, xd, tile, block, bsize, top_bsize, mi_row, mi_col,
                 mi_row_top, mi_col_top, dst_buf, dst_stride, 0);
  dec_extend_dir(pbi, xd, tile, block, bsize, top_bsize, mi_row, mi_col,
                 mi_row_top, mi_col_top, dst_buf, dst_stride, 1);
  dec_extend_dir(pbi, xd, tile, block, bsize, top_bsize, mi_row, mi_col,
                 mi_row_top, mi_col_top, dst_buf, dst_stride, 2);
  dec_extend_dir(pbi, xd, tile, block, bsize, top_bsize, mi_row, mi_col,
                 mi_row_top, mi_col_top, dst_buf, dst_stride, 3);
  dec_extend_dir(pbi, xd, tile, block, bsize, top_bsize, mi_row, mi_col,
                 mi_row_top, mi_col_top, dst_buf, dst_stride, 4);
  dec_extend_dir(pbi, xd, tile, block, bsize, top_bsize, mi_row, mi_col,
                 mi_row_top, mi_col_top, dst_buf, dst_stride, 5);
  dec_extend_dir(pbi, xd, tile, block, bsize, top_bsize, mi_row, mi_col,
                 mi_row_top, mi_col_top, dst_buf, dst_stride, 6);
  dec_extend_dir(pbi, xd, tile, block, bsize, top_bsize, mi_row, mi_col,
                 mi_row_top, mi_col_top, dst_buf, dst_stride, 7);
}

static void dec_predict_sb_complex(VP10Decoder *const pbi,
                                   MACROBLOCKD *const xd,
706 707
                                   const TileInfo *const tile, int mi_row,
                                   int mi_col, int mi_row_top, int mi_col_top,
708 709
                                   BLOCK_SIZE bsize, BLOCK_SIZE top_bsize,
                                   uint8_t *dst_buf[3], int dst_stride[3]) {
710 711 712 713
  const VP10_COMMON *const cm = &pbi->common;
  const int hbs = num_8x8_blocks_wide_lookup[bsize] / 2;
  const PARTITION_TYPE partition = get_partition(cm, mi_row, mi_col, bsize);
  const BLOCK_SIZE subsize = get_subsize(bsize, partition);
714
#if CONFIG_EXT_PARTITION_TYPES
715
  const BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
716
#endif
717 718
  int i;
  const int mi_offset = mi_row * cm->mi_stride + mi_col;
719 720
  uint8_t *dst_buf1[3], *dst_buf2[3], *dst_buf3[3];

721 722 723 724 725 726
  DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_TX_SQUARE * 2]);
  DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_TX_SQUARE * 2]);
  DECLARE_ALIGNED(16, uint8_t, tmp_buf3[MAX_MB_PLANE * MAX_TX_SQUARE * 2]);
  int dst_stride1[3] = { MAX_TX_SIZE, MAX_TX_SIZE, MAX_TX_SIZE };
  int dst_stride2[3] = { MAX_TX_SIZE, MAX_TX_SIZE, MAX_TX_SIZE };
  int dst_stride3[3] = { MAX_TX_SIZE, MAX_TX_SIZE, MAX_TX_SIZE };
727 728 729 730 731

#if CONFIG_VP9_HIGHBITDEPTH
  if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
    int len = sizeof(uint16_t);
    dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
732 733
    dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_TX_SQUARE * len);
    dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + 2 * MAX_TX_SQUARE * len);
734
    dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
735 736
    dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_TX_SQUARE * len);
    dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + 2 * MAX_TX_SQUARE * len);
737
    dst_buf3[0] = CONVERT_TO_BYTEPTR(tmp_buf3);
738 739
    dst_buf3[1] = CONVERT_TO_BYTEPTR(tmp_buf3 + MAX_TX_SQUARE * len);
    dst_buf3[2] = CONVERT_TO_BYTEPTR(tmp_buf3 + 2 * MAX_TX_SQUARE * len);
740 741 742
  } else {
#endif
    dst_buf1[0] = tmp_buf1;
743 744
    dst_buf1[1] = tmp_buf1 + MAX_TX_SQUARE;
    dst_buf1[2] = tmp_buf1 + 2 * MAX_TX_SQUARE;
745
    dst_buf2[0] = tmp_buf2;
746 747
    dst_buf2[1] = tmp_buf2 + MAX_TX_SQUARE;
    dst_buf2[2] = tmp_buf2 + 2 * MAX_TX_SQUARE;
748
    dst_buf3[0] = tmp_buf3;
749 750
    dst_buf3[1] = tmp_buf3 + MAX_TX_SQUARE;
    dst_buf3[2] = tmp_buf3 + 2 * MAX_TX_SQUARE;
751 752 753 754
#if CONFIG_VP9_HIGHBITDEPTH
  }
#endif

755
  if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
756

757 758
  xd->mi = cm->mi_grid_visible + mi_offset;
  xd->mi[0] = cm->mi + mi_offset;
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

  for (i = 0; i < MAX_MB_PLANE; i++) {
    xd->plane[i].dst.buf = dst_buf[i];
    xd->plane[i].dst.stride = dst_stride[i];
  }

  switch (partition) {
    case PARTITION_NONE:
      assert(bsize < top_bsize);
      dec_predict_b_extend(pbi, xd, tile, 0, mi_row, mi_col, mi_row, mi_col,
                           mi_row_top, mi_col_top, dst_buf, dst_stride,
                           top_bsize, bsize, 0, 0);
      dec_extend_all(pbi, xd, tile, 0, bsize, top_bsize, mi_row, mi_col,
                     mi_row_top, mi_col_top, dst_buf, dst_stride);
      break;
    case PARTITION_HORZ:
      if (bsize == BLOCK_8X8) {
        // For sub8x8, predict in 8x8 unit
        // First half
        dec_predict_b_extend(pbi, xd, tile, 0, mi_row, mi_col, mi_row, mi_col,
                             mi_row_top, mi_col_top, dst_buf, dst_stride,
                             top_bsize, BLOCK_8X8, 1, 0);
        if (bsize < top_bsize)
          dec_extend_all(pbi, xd, tile, 0, subsize, top_bsize, mi_row, mi_col,
                         mi_row_top, mi_col_top, dst_buf, dst_stride);

        // Second half
        dec_predict_b_extend(pbi, xd, tile, 2, mi_row, mi_col, mi_row, mi_col,
                             mi_row_top, mi_col_top, dst_buf1, dst_stride1,
                             top_bsize, BLOCK_8X8, 1, 1);
        if (bsize < top_bsize)
          dec_extend_all(pbi, xd, tile, 2, subsize, top_bsize, mi_row, mi_col,
                         mi_row_top, mi_col_top, dst_buf1, dst_stride1);

        // weighted average to smooth the boundary
        xd->plane[0].dst.buf = dst_buf[0];
        xd->plane[0].dst.stride = dst_stride[0];
796 797 798 799
        vp10_build_masked_inter_predictor_complex(
            xd, dst_buf[0], dst_stride[0], dst_buf1[0], dst_stride1[0], mi_row,
            mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
            0);
800 801 802 803 804 805 806 807 808 809 810 811 812 813 814
      } else {
        // First half
        dec_predict_b_extend(pbi, xd, tile, 0, mi_row, mi_col, mi_row, mi_col,
                             mi_row_top, mi_col_top, dst_buf, dst_stride,
                             top_bsize, subsize, 0, 0);
        if (bsize < top_bsize)
          dec_extend_all(pbi, xd, tile, 0, subsize, top_bsize, mi_row, mi_col,
                         mi_row_top, mi_col_top, dst_buf, dst_stride);
        else
          dec_extend_dir(pbi, xd, tile, 0, subsize, top_bsize, mi_row, mi_col,
                         mi_row_top, mi_col_top, dst_buf, dst_stride, 0);

        if (mi_row + hbs < cm->mi_rows) {
          // Second half
          dec_predict_b_extend(pbi, xd, tile, 0, mi_row + hbs, mi_col,
815 816
                               mi_row + hbs, mi_col, mi_row_top, mi_col_top,
                               dst_buf1, dst_stride1, top_bsize, subsize, 0, 0);
817
          if (bsize < top_bsize)
818 819 820
            dec_extend_all(pbi, xd, tile, 0, subsize, top_bsize, mi_row + hbs,
                           mi_col, mi_row_top, mi_col_top, dst_buf1,
                           dst_stride1);
821
          else
822 823 824
            dec_extend_dir(pbi, xd, tile, 0, subsize, top_bsize, mi_row + hbs,
                           mi_col, mi_row_top, mi_col_top, dst_buf1,
                           dst_stride1, 1);
825 826 827 828 829 830 831

          // weighted average to smooth the boundary
          for (i = 0; i < MAX_MB_PLANE; i++) {
            xd->plane[i].dst.buf = dst_buf[i];
            xd->plane[i].dst.stride = dst_stride[i];
            vp10_build_masked_inter_predictor_complex(
                xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i],
832 833
                mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
                PARTITION_HORZ, i);
834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858
          }
        }
      }
      break;
    case PARTITION_VERT:
      if (bsize == BLOCK_8X8) {
        // First half
        dec_predict_b_extend(pbi, xd, tile, 0, mi_row, mi_col, mi_row, mi_col,
                             mi_row_top, mi_col_top, dst_buf, dst_stride,
                             top_bsize, BLOCK_8X8, 1, 0);
        if (bsize < top_bsize)
          dec_extend_all(pbi, xd, tile, 0, subsize, top_bsize, mi_row, mi_col,
                         mi_row_top, mi_col_top, dst_buf, dst_stride);

        // Second half
        dec_predict_b_extend(pbi, xd, tile, 1, mi_row, mi_col, mi_row, mi_col,
                             mi_row_top, mi_col_top, dst_buf1, dst_stride1,
                             top_bsize, BLOCK_8X8, 1, 1);
        if (bsize < top_bsize)
          dec_extend_all(pbi, xd, tile, 1, subsize, top_bsize, mi_row, mi_col,
                         mi_row_top, mi_col_top, dst_buf1, dst_stride1);

        // Smooth
        xd->plane[0].dst.buf = dst_buf[0];
        xd->plane[0].dst.stride = dst_stride[0];
859 860 861 862
        vp10_build_masked_inter_predictor_complex(
            xd, dst_buf[0], dst_stride[0], dst_buf1[0], dst_stride1[0], mi_row,
            mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
            0);
863 864 865 866 867 868 869 870 871 872 873 874 875 876
      } else {
        // First half
        dec_predict_b_extend(pbi, xd, tile, 0, mi_row, mi_col, mi_row, mi_col,
                             mi_row_top, mi_col_top, dst_buf, dst_stride,
                             top_bsize, subsize, 0, 0);
        if (bsize < top_bsize)
          dec_extend_all(pbi, xd, tile, 0, subsize, top_bsize, mi_row, mi_col,
                         mi_row_top, mi_col_top, dst_buf, dst_stride);
        else
          dec_extend_dir(pbi, xd, tile, 0, subsize, top_bsize, mi_row, mi_col,
                         mi_row_top, mi_col_top, dst_buf, dst_stride, 3);

        // Second half
        if (mi_col + hbs < cm->mi_cols) {
877 878 879
          dec_predict_b_extend(pbi, xd, tile, 0, mi_row, mi_col + hbs, mi_row,
                               mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
                               dst_stride1, top_bsize, subsize, 0, 0);
880
          if (bsize < top_bsize)
881 882 883
            dec_extend_all(pbi, xd, tile, 0, subsize, top_bsize, mi_row,
                           mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
                           dst_stride1);
884
          else
885 886 887
            dec_extend_dir(pbi, xd, tile, 0, subsize, top_bsize, mi_row,
                           mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
                           dst_stride1, 2);
888 889 890 891 892 893 894

          // Smooth
          for (i = 0; i < MAX_MB_PLANE; i++) {
            xd->plane[i].dst.buf = dst_buf[i];
            xd->plane[i].dst.stride = dst_stride[i];
            vp10_build_masked_inter_predictor_complex(
                xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i],
895 896
                mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
                PARTITION_VERT, i);
897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925
          }
        }
      }
      break;
    case PARTITION_SPLIT:
      if (bsize == BLOCK_8X8) {
        dec_predict_b_extend(pbi, xd, tile, 0, mi_row, mi_col, mi_row, mi_col,
                             mi_row_top, mi_col_top, dst_buf, dst_stride,
                             top_bsize, BLOCK_8X8, 1, 0);
        dec_predict_b_extend(pbi, xd, tile, 1, mi_row, mi_col, mi_row, mi_col,
                             mi_row_top, mi_col_top, dst_buf1, dst_stride1,
                             top_bsize, BLOCK_8X8, 1, 1);
        dec_predict_b_extend(pbi, xd, tile, 2, mi_row, mi_col, mi_row, mi_col,
                             mi_row_top, mi_col_top, dst_buf2, dst_stride2,
                             top_bsize, BLOCK_8X8, 1, 1);
        dec_predict_b_extend(pbi, xd, tile, 3, mi_row, mi_col, mi_row, mi_col,
                             mi_row_top, mi_col_top, dst_buf3, dst_stride3,
                             top_bsize, BLOCK_8X8, 1, 1);
        if (bsize < top_bsize) {
          dec_extend_all(pbi, xd, tile, 0, subsize, top_bsize, mi_row, mi_col,
                         mi_row_top, mi_col_top, dst_buf, dst_stride);
          dec_extend_all(pbi, xd, tile, 1, subsize, top_bsize, mi_row, mi_col,
                         mi_row_top, mi_col_top, dst_buf1, dst_stride1);
          dec_extend_all(pbi, xd, tile, 2, subsize, top_bsize, mi_row, mi_col,
                         mi_row_top, mi_col_top, dst_buf2, dst_stride2);
          dec_extend_all(pbi, xd, tile, 3, subsize, top_bsize, mi_row, mi_col,
                         mi_row_top, mi_col_top, dst_buf3, dst_stride3);
        }
      } else {
926 927 928
        dec_predict_sb_complex(pbi, xd, tile, mi_row, mi_col, mi_row_top,
                               mi_col_top, subsize, top_bsize, dst_buf,
                               dst_stride);
929 930 931 932 933 934 935 936 937 938 939 940 941
        if (mi_row < cm->mi_rows && mi_col + hbs < cm->mi_cols)
          dec_predict_sb_complex(pbi, xd, tile, mi_row, mi_col + hbs,
                                 mi_row_top, mi_col_top, subsize, top_bsize,
                                 dst_buf1, dst_stride1);
        if (mi_row + hbs < cm->mi_rows && mi_col < cm->mi_cols)
          dec_predict_sb_complex(pbi, xd, tile, mi_row + hbs, mi_col,
                                 mi_row_top, mi_col_top, subsize, top_bsize,
                                 dst_buf2, dst_stride2);
        if (mi_row + hbs < cm->mi_rows && mi_col + hbs < cm->mi_cols)
          dec_predict_sb_complex(pbi, xd, tile, mi_row + hbs, mi_col + hbs,
                                 mi_row_top, mi_col_top, subsize, top_bsize,
                                 dst_buf3, dst_stride3);
      }
942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958
      for (i = 0; i < MAX_MB_PLANE; i++) {
        if (bsize == BLOCK_8X8 && i != 0)
          continue;  // Skip <4x4 chroma smoothing
        if (mi_row < cm->mi_rows && mi_col + hbs < cm->mi_cols) {
          vp10_build_masked_inter_predictor_complex(
              xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i],
              mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
              PARTITION_VERT, i);
          if (mi_row + hbs < cm->mi_rows) {
            vp10_build_masked_inter_predictor_complex(
                xd, dst_buf2[i], dst_stride2[i], dst_buf3[i], dst_stride3[i],
                mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
                PARTITION_VERT, i);
            vp10_build_masked_inter_predictor_complex(
                xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i],
                mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
                PARTITION_HORZ, i);
959
          }
960 961 962 963 964
        } else if (mi_row + hbs < cm->mi_rows && mi_col < cm->mi_cols) {
          vp10_build_masked_inter_predictor_complex(
              xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i],
              mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
              PARTITION_HORZ, i);
965
        }
966
      }
967
      break;
968 969 970 971 972 973 974 975 976
#if CONFIG_EXT_PARTITION_TYPES
    case PARTITION_HORZ_A:
      dec_predict_b_extend(pbi, xd, tile, 0, mi_row, mi_col, mi_row, mi_col,
                           mi_row_top, mi_col_top, dst_buf, dst_stride,
                           top_bsize, bsize2, 0, 0);
      dec_extend_all(pbi, xd, tile, 0, bsize2, top_bsize, mi_row, mi_col,
                     mi_row_top, mi_col_top, dst_buf, dst_stride);

      dec_predict_b_extend(pbi, xd, tile, 0, mi_row, mi_col + hbs, mi_row,
977 978
                           mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
                           dst_stride1, top_bsize, bsize2, 0, 0);
979 980 981
      dec_extend_all(pbi, xd, tile, 0, bsize2, top_bsize, mi_row, mi_col + hbs,
                     mi_row_top, mi_col_top, dst_buf1, dst_stride1);

982 983 984
      dec_predict_b_extend(pbi, xd, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
                           mi_col, mi_row_top, mi_col_top, dst_buf2,
                           dst_stride2, top_bsize, subsize, 0, 0);
985
      if (bsize < top_bsize)
986 987
        dec_extend_all(pbi, xd, tile, 0, subsize, top_bsize, mi_row + hbs,
                       mi_col, mi_row_top, mi_col_top, dst_buf2, dst_stride2);
988
      else
989 990 991
        dec_extend_dir(pbi, xd, tile, 0, subsize, top_bsize, mi_row + hbs,
                       mi_col, mi_row_top, mi_col_top, dst_buf2, dst_stride2,
                       1);
992 993 994 995

      for (i = 0; i < MAX_MB_PLANE; i++) {
        xd->plane[i].dst.buf = dst_buf[i];
        xd->plane[i].dst.stride = dst_stride[i];
996 997 998 999
        vp10_build_masked_inter_predictor_complex(
            xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
            mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
            i);
1000 1001
      }
      for (i = 0; i < MAX_MB_PLANE; i++) {
1002 1003 1004 1005
        vp10_build_masked_inter_predictor_complex(
            xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i], mi_row,
            mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
            i);
1006 1007 1008 1009 1010 1011 1012 1013 1014 1015
      }
      break;
    case PARTITION_VERT_A:

      dec_predict_b_extend(pbi, xd, tile, 0, mi_row, mi_col, mi_row, mi_col,
                           mi_row_top, mi_col_top, dst_buf, dst_stride,
                           top_bsize, bsize2, 0, 0);
      dec_extend_all(pbi, xd, tile, 0, bsize2, top_bsize, mi_row, mi_col,
                     mi_row_top, mi_col_top, dst_buf, dst_stride);

1016 1017 1018
      dec_predict_b_extend(pbi, xd, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
                           mi_col, mi_row_top, mi_col_top, dst_buf1,
                           dst_stride1, top_bsize, bsize2, 0, 0);
1019 1020 1021
      dec_extend_all(pbi, xd, tile, 0, bsize2, top_bsize, mi_row + hbs, mi_col,
                     mi_row_top, mi_col_top, dst_buf1, dst_stride1);

1022 1023 1024
      dec_predict_b_extend(pbi, xd, tile, 0, mi_row, mi_col + hbs, mi_row,
                           mi_col + hbs, mi_row_top, mi_col_top, dst_buf2,
                           dst_stride2, top_bsize, subsize, 0, 0);
1025
      if (bsize < top_bsize)
1026 1027 1028
        dec_extend_all(pbi, xd, tile, 0, subsize, top_bsize, mi_row,
                       mi_col + hbs, mi_row_top, mi_col_top, dst_buf2,
                       dst_stride2);
1029
      else
1030 1031 1032
        dec_extend_dir(pbi, xd, tile, 0, subsize, top_bsize, mi_row,
                       mi_col + hbs, mi_row_top, mi_col_top, dst_buf2,
                       dst_stride2, 2);
1033 1034 1035 1036

      for (i = 0; i < MAX_MB_PLANE; i++) {
        xd->plane[i].dst.buf = dst_buf[i];
        xd->plane[i].dst.stride = dst_stride[i];
1037 1038 1039 1040
        vp10_build_masked_inter_predictor_complex(
            xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
            mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
            i);
1041 1042
      }
      for (i = 0; i < MAX_MB_PLANE; i++) {
1043 1044 1045 1046
        vp10_build_masked_inter_predictor_complex(
            xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i], mi_row,
            mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
            i