decodeframe.c 86 KB
Newer Older
Jingning Han's avatar
Jingning Han committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/*
 *  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"
#include "./vpx_dsp_rtcd.h"
#include "./vpx_scale_rtcd.h"

#include "vpx_dsp/bitreader_buffer.h"
#include "vpx_dsp/bitreader.h"
20
#include "vpx_dsp/vpx_dsp_common.h"
Jingning Han's avatar
Jingning Han committed
21 22 23 24 25 26
#include "vpx_mem/vpx_mem.h"
#include "vpx_ports/mem.h"
#include "vpx_ports/mem_ops.h"
#include "vpx_scale/vpx_scale.h"
#include "vpx_util/vpx_thread.h"

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

#include "vp10/decoder/decodeframe.h"
#include "vp10/decoder/detokenize.h"
#include "vp10/decoder/decodemv.h"
#include "vp10/decoder/decoder.h"
#include "vp10/decoder/dsubexp.h"
Jingning Han's avatar
Jingning Han committed
48

49
#define MAX_VP10_HEADER_SIZE 80
Jingning Han's avatar
Jingning Han committed
50

Yaowu Xu's avatar
Yaowu Xu committed
51
static int is_compound_reference_allowed(const VP10_COMMON *cm) {
Jingning Han's avatar
Jingning Han committed
52
  int i;
clang-format's avatar
clang-format committed
53
  if (frame_is_intra_only(cm)) return 0;
Jingning Han's avatar
Jingning Han committed
54
  for (i = 1; i < REFS_PER_FRAME; ++i)
clang-format's avatar
clang-format committed
55
    if (cm->ref_frame_sign_bias[i + 1] != cm->ref_frame_sign_bias[1]) return 1;
Jingning Han's avatar
Jingning Han committed
56 57 58 59

  return 0;
}

Yaowu Xu's avatar
Yaowu Xu committed
60
static void setup_compound_reference_mode(VP10_COMMON *cm) {
Jingning Han's avatar
Jingning Han committed
61
  if (cm->ref_frame_sign_bias[LAST_FRAME] ==
clang-format's avatar
clang-format committed
62
      cm->ref_frame_sign_bias[GOLDEN_FRAME]) {
Jingning Han's avatar
Jingning Han committed
63 64 65 66
    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] ==
clang-format's avatar
clang-format committed
67
             cm->ref_frame_sign_bias[ALTREF_FRAME]) {
Jingning Han's avatar
Jingning Han committed
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
    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;
  }
}

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

87 88 89 90 91
#if CONFIG_MISC_FIXES
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);
}
#else
Jingning Han's avatar
Jingning Han committed
92 93
static TX_MODE read_tx_mode(vpx_reader *r) {
  TX_MODE tx_mode = vpx_read_literal(r, 2);
clang-format's avatar
clang-format committed
94
  if (tx_mode == ALLOW_32X32) tx_mode += vpx_read_bit(r);
Jingning Han's avatar
Jingning Han committed
95 96
  return tx_mode;
}
97
#endif
Jingning Han's avatar
Jingning Han committed
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128

static void read_tx_mode_probs(struct tx_probs *tx_probs, vpx_reader *r) {
  int i, j;

  for (i = 0; i < TX_SIZE_CONTEXTS; ++i)
    for (j = 0; j < TX_SIZES - 3; ++j)
      vp10_diff_update_prob(r, &tx_probs->p8x8[i][j]);

  for (i = 0; i < TX_SIZE_CONTEXTS; ++i)
    for (j = 0; j < TX_SIZES - 2; ++j)
      vp10_diff_update_prob(r, &tx_probs->p16x16[i][j]);

  for (i = 0; i < TX_SIZE_CONTEXTS; ++i)
    for (j = 0; j < TX_SIZES - 1; ++j)
      vp10_diff_update_prob(r, &tx_probs->p32x32[i][j]);
}

static void read_switchable_interp_probs(FRAME_CONTEXT *fc, vpx_reader *r) {
  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]);
}

static void read_inter_mode_probs(FRAME_CONTEXT *fc, vpx_reader *r) {
  int i, j;
  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]);
}

129
#if CONFIG_MISC_FIXES
clang-format's avatar
clang-format committed
130 131
static REFERENCE_MODE read_frame_reference_mode(
    const VP10_COMMON *cm, struct vpx_read_bit_buffer *rb) {
132
  if (is_compound_reference_allowed(cm)) {
clang-format's avatar
clang-format committed
133 134 135
    return vpx_rb_read_bit(rb)
               ? REFERENCE_MODE_SELECT
               : (vpx_rb_read_bit(rb) ? COMPOUND_REFERENCE : SINGLE_REFERENCE);
136 137 138 139 140
  } else {
    return SINGLE_REFERENCE;
  }
}
#else
Yaowu Xu's avatar
Yaowu Xu committed
141
static REFERENCE_MODE read_frame_reference_mode(const VP10_COMMON *cm,
Jingning Han's avatar
Jingning Han committed
142 143
                                                vpx_reader *r) {
  if (is_compound_reference_allowed(cm)) {
clang-format's avatar
clang-format committed
144 145 146
    return vpx_read_bit(r)
               ? (vpx_read_bit(r) ? REFERENCE_MODE_SELECT : COMPOUND_REFERENCE)
               : SINGLE_REFERENCE;
Jingning Han's avatar
Jingning Han committed
147 148 149 150
  } else {
    return SINGLE_REFERENCE;
  }
}
151
#endif
Jingning Han's avatar
Jingning Han committed
152

Yaowu Xu's avatar
Yaowu Xu committed
153
static void read_frame_reference_mode_probs(VP10_COMMON *cm, vpx_reader *r) {
Jingning Han's avatar
Jingning Han committed
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
  FRAME_CONTEXT *const fc = cm->fc;
  int i;

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

  if (cm->reference_mode != COMPOUND_REFERENCE)
    for (i = 0; i < REF_CONTEXTS; ++i) {
      vp10_diff_update_prob(r, &fc->single_ref_prob[i][0]);
      vp10_diff_update_prob(r, &fc->single_ref_prob[i][1]);
    }

  if (cm->reference_mode != SINGLE_REFERENCE)
    for (i = 0; i < REF_CONTEXTS; ++i)
      vp10_diff_update_prob(r, &fc->comp_ref_prob[i]);
}

static void update_mv_probs(vpx_prob *p, int n, vpx_reader *r) {
  int i;
  for (i = 0; i < n; ++i)
175 176 177
#if CONFIG_MISC_FIXES
    vp10_diff_update_prob(r, &p[i]);
#else
clang-format's avatar
clang-format committed
178
    if (vpx_read(r, MV_UPDATE_PROB)) p[i] = (vpx_read_literal(r, 7) << 1) | 1;
179
#endif
Jingning Han's avatar
Jingning Han committed
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
}

static void read_mv_probs(nmv_context *ctx, int allow_hp, vpx_reader *r) {
  int i, j;

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

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

clang-format's avatar
clang-format committed
211 212 213
static void inverse_transform_block_inter(MACROBLOCKD *xd, int plane,
                                          const TX_SIZE tx_size, uint8_t *dst,
                                          int stride, int eob, int block) {
Jingning Han's avatar
Jingning Han committed
214
  struct macroblockd_plane *const pd = &xd->plane[plane];
hui su's avatar
hui su committed
215
  TX_TYPE tx_type = get_tx_type(pd->plane_type, xd, block);
216
  const int seg_id = xd->mi[0]->mbmi.segment_id;
Jingning Han's avatar
Jingning Han committed
217 218
  if (eob > 0) {
    tran_low_t *const dqcoeff = pd->dqcoeff;
219
#if CONFIG_VPX_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
220
    if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
hui su's avatar
hui su committed
221 222 223
      switch (tx_size) {
        case TX_4X4:
          vp10_highbd_inv_txfm_add_4x4(dqcoeff, dst, stride, eob, xd->bd,
224
                                       tx_type, xd->lossless[seg_id]);
hui su's avatar
hui su committed
225 226 227 228 229 230 231 232 233 234 235 236 237
          break;
        case TX_8X8:
          vp10_highbd_inv_txfm_add_8x8(dqcoeff, dst, stride, eob, xd->bd,
                                       tx_type);
          break;
        case TX_16X16:
          vp10_highbd_inv_txfm_add_16x16(dqcoeff, dst, stride, eob, xd->bd,
                                         tx_type);
          break;
        case TX_32X32:
          vp10_highbd_inv_txfm_add_32x32(dqcoeff, dst, stride, eob, xd->bd,
                                         tx_type);
          break;
clang-format's avatar
clang-format committed
238
        default: assert(0 && "Invalid transform size"); return;
Jingning Han's avatar
Jingning Han committed
239 240
      }
    } else {
241
#endif  // CONFIG_VPX_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
242 243
      switch (tx_size) {
        case TX_4X4:
hui su's avatar
hui su committed
244
          vp10_inv_txfm_add_4x4(dqcoeff, dst, stride, eob, tx_type,
245
                                xd->lossless[seg_id]);
Jingning Han's avatar
Jingning Han committed
246 247
          break;
        case TX_8X8:
hui su's avatar
hui su committed
248
          vp10_inv_txfm_add_8x8(dqcoeff, dst, stride, eob, tx_type);
Jingning Han's avatar
Jingning Han committed
249 250
          break;
        case TX_16X16:
hui su's avatar
hui su committed
251
          vp10_inv_txfm_add_16x16(dqcoeff, dst, stride, eob, tx_type);
Jingning Han's avatar
Jingning Han committed
252 253
          break;
        case TX_32X32:
hui su's avatar
hui su committed
254
          vp10_inv_txfm_add_32x32(dqcoeff, dst, stride, eob, tx_type);
Jingning Han's avatar
Jingning Han committed
255
          break;
clang-format's avatar
clang-format committed
256
        default: assert(0 && "Invalid transform size"); return;
Jingning Han's avatar
Jingning Han committed
257
      }
258
#if CONFIG_VPX_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
259
    }
260
#endif  // CONFIG_VPX_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
261 262 263 264

    if (eob == 1) {
      dqcoeff[0] = 0;
    } else {
265
      if (tx_type == DCT_DCT && tx_size <= TX_16X16 && eob <= 10)
Jingning Han's avatar
Jingning Han committed
266 267 268 269 270 271 272 273 274
        memset(dqcoeff, 0, 4 * (4 << tx_size) * sizeof(dqcoeff[0]));
      else if (tx_size == TX_32X32 && eob <= 34)
        memset(dqcoeff, 0, 256 * sizeof(dqcoeff[0]));
      else
        memset(dqcoeff, 0, (16 << (tx_size << 1)) * sizeof(dqcoeff[0]));
    }
  }
}

clang-format's avatar
clang-format committed
275
static void inverse_transform_block_intra(MACROBLOCKD *xd, int plane,
Jingning Han's avatar
Jingning Han committed
276
                                          const TX_TYPE tx_type,
clang-format's avatar
clang-format committed
277 278
                                          const TX_SIZE tx_size, uint8_t *dst,
                                          int stride, int eob) {
Jingning Han's avatar
Jingning Han committed
279
  struct macroblockd_plane *const pd = &xd->plane[plane];
280
  const int seg_id = xd->mi[0]->mbmi.segment_id;
Jingning Han's avatar
Jingning Han committed
281 282
  if (eob > 0) {
    tran_low_t *const dqcoeff = pd->dqcoeff;
283
#if CONFIG_VPX_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
284
    if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
hui su's avatar
hui su committed
285 286 287
      switch (tx_size) {
        case TX_4X4:
          vp10_highbd_inv_txfm_add_4x4(dqcoeff, dst, stride, eob, xd->bd,
288
                                       tx_type, xd->lossless[seg_id]);
hui su's avatar
hui su committed
289 290 291 292 293 294 295 296 297 298 299 300 301
          break;
        case TX_8X8:
          vp10_highbd_inv_txfm_add_8x8(dqcoeff, dst, stride, eob, xd->bd,
                                       tx_type);
          break;
        case TX_16X16:
          vp10_highbd_inv_txfm_add_16x16(dqcoeff, dst, stride, eob, xd->bd,
                                         tx_type);
          break;
        case TX_32X32:
          vp10_highbd_inv_txfm_add_32x32(dqcoeff, dst, stride, eob, xd->bd,
                                         tx_type);
          break;
clang-format's avatar
clang-format committed
302
        default: assert(0 && "Invalid transform size"); return;
Jingning Han's avatar
Jingning Han committed
303 304
      }
    } else {
305
#endif  // CONFIG_VPX_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
306 307
      switch (tx_size) {
        case TX_4X4:
hui su's avatar
hui su committed
308
          vp10_inv_txfm_add_4x4(dqcoeff, dst, stride, eob, tx_type,
309
                                xd->lossless[seg_id]);
Jingning Han's avatar
Jingning Han committed
310 311
          break;
        case TX_8X8:
hui su's avatar
hui su committed
312
          vp10_inv_txfm_add_8x8(dqcoeff, dst, stride, eob, tx_type);
Jingning Han's avatar
Jingning Han committed
313 314
          break;
        case TX_16X16:
hui su's avatar
hui su committed
315
          vp10_inv_txfm_add_16x16(dqcoeff, dst, stride, eob, tx_type);
Jingning Han's avatar
Jingning Han committed
316 317
          break;
        case TX_32X32:
hui su's avatar
hui su committed
318
          vp10_inv_txfm_add_32x32(dqcoeff, dst, stride, eob, tx_type);
Jingning Han's avatar
Jingning Han committed
319
          break;
clang-format's avatar
clang-format committed
320
        default: assert(0 && "Invalid transform size"); return;
Jingning Han's avatar
Jingning Han committed
321
      }
322
#if CONFIG_VPX_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
323
    }
324
#endif  // CONFIG_VPX_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341

    if (eob == 1) {
      dqcoeff[0] = 0;
    } else {
      if (tx_type == DCT_DCT && tx_size <= TX_16X16 && eob <= 10)
        memset(dqcoeff, 0, 4 * (4 << tx_size) * sizeof(dqcoeff[0]));
      else if (tx_size == TX_32X32 && eob <= 34)
        memset(dqcoeff, 0, 256 * sizeof(dqcoeff[0]));
      else
        memset(dqcoeff, 0, (16 << (tx_size << 1)) * sizeof(dqcoeff[0]));
    }
  }
}

static void predict_and_reconstruct_intra_block(MACROBLOCKD *const xd,
                                                vpx_reader *r,
                                                MB_MODE_INFO *const mbmi,
clang-format's avatar
clang-format committed
342
                                                int plane, int row, int col,
Jingning Han's avatar
Jingning Han committed
343 344 345
                                                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
346
  PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV;
Jingning Han's avatar
Jingning Han committed
347
  uint8_t *dst;
hui su's avatar
hui su committed
348
  int block_idx = (row << 1) + col;
Jingning Han's avatar
Jingning Han committed
349 350 351
  dst = &pd->dst.buf[4 * row * pd->dst.stride + 4 * col];

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

clang-format's avatar
clang-format committed
354 355 356
  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
357 358

  if (!mbmi->skip) {
hui su's avatar
hui su committed
359 360
    TX_TYPE tx_type = get_tx_type(plane_type, xd, block_idx);
    const scan_order *sc = get_scan(tx_size, tx_type);
Jingning Han's avatar
Jingning Han committed
361
    const int eob = vp10_decode_block_tokens(xd, plane, sc, col, row, tx_size,
hui su's avatar
hui su committed
362
                                             r, mbmi->segment_id);
clang-format's avatar
clang-format committed
363 364
    inverse_transform_block_intra(xd, plane, tx_type, tx_size, dst,
                                  pd->dst.stride, eob);
Jingning Han's avatar
Jingning Han committed
365 366 367 368
  }
}

static int reconstruct_inter_block(MACROBLOCKD *const xd, vpx_reader *r,
clang-format's avatar
clang-format committed
369 370
                                   MB_MODE_INFO *const mbmi, int plane, int row,
                                   int col, TX_SIZE tx_size) {
Jingning Han's avatar
Jingning Han committed
371
  struct macroblockd_plane *const pd = &xd->plane[plane];
hui su's avatar
hui su committed
372 373 374 375
  PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV;
  int block_idx = (row << 1) + col;
  TX_TYPE tx_type = get_tx_type(plane_type, xd, block_idx);
  const scan_order *sc = get_scan(tx_size, tx_type);
Jingning Han's avatar
Jingning Han committed
376
  const int eob = vp10_decode_block_tokens(xd, plane, sc, col, row, tx_size, r,
clang-format's avatar
clang-format committed
377
                                           mbmi->segment_id);
Jingning Han's avatar
Jingning Han committed
378

clang-format's avatar
clang-format committed
379 380 381
  inverse_transform_block_inter(
      xd, plane, tx_size, &pd->dst.buf[4 * row * pd->dst.stride + 4 * col],
      pd->dst.stride, eob, block_idx);
Jingning Han's avatar
Jingning Han committed
382 383 384
  return eob;
}

clang-format's avatar
clang-format committed
385 386 387
static void build_mc_border(const uint8_t *src, int src_stride, uint8_t *dst,
                            int dst_stride, int x, int y, int b_w, int b_h,
                            int w, int h) {
Jingning Han's avatar
Jingning Han committed
388 389 390 391 392 393 394 395 396 397 398 399
  // Get a pointer to the start of the real data for this row.
  const uint8_t *ref_row = src - x - y * src_stride;

  if (y >= h)
    ref_row += (h - 1) * src_stride;
  else if (y > 0)
    ref_row += y * src_stride;

  do {
    int right = 0, copy;
    int left = x < 0 ? -x : 0;

clang-format's avatar
clang-format committed
400
    if (left > b_w) left = b_w;
Jingning Han's avatar
Jingning Han committed
401

clang-format's avatar
clang-format committed
402
    if (x + b_w > w) right = x + b_w - w;
Jingning Han's avatar
Jingning Han committed
403

clang-format's avatar
clang-format committed
404
    if (right > b_w) right = b_w;
Jingning Han's avatar
Jingning Han committed
405 406 407

    copy = b_w - left - right;

clang-format's avatar
clang-format committed
408
    if (left) memset(dst, ref_row[0], left);
Jingning Han's avatar
Jingning Han committed
409

clang-format's avatar
clang-format committed
410
    if (copy) memcpy(dst + left, ref_row + x + left, copy);
Jingning Han's avatar
Jingning Han committed
411

clang-format's avatar
clang-format committed
412
    if (right) memset(dst + left + copy, ref_row[w - 1], right);
Jingning Han's avatar
Jingning Han committed
413 414 415 416

    dst += dst_stride;
    ++y;

clang-format's avatar
clang-format committed
417
    if (y > 0 && y < h) ref_row += src_stride;
Jingning Han's avatar
Jingning Han committed
418 419 420
  } while (--b_h);
}

421
#if CONFIG_VPX_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
422
static void high_build_mc_border(const uint8_t *src8, int src_stride,
clang-format's avatar
clang-format committed
423 424
                                 uint16_t *dst, int dst_stride, int x, int y,
                                 int b_w, int b_h, int w, int h) {
Jingning Han's avatar
Jingning Han committed
425 426 427 428 429 430 431 432 433 434 435 436 437
  // Get a pointer to the start of the real data for this row.
  const uint16_t *src = CONVERT_TO_SHORTPTR(src8);
  const uint16_t *ref_row = src - x - y * src_stride;

  if (y >= h)
    ref_row += (h - 1) * src_stride;
  else if (y > 0)
    ref_row += y * src_stride;

  do {
    int right = 0, copy;
    int left = x < 0 ? -x : 0;

clang-format's avatar
clang-format committed
438
    if (left > b_w) left = b_w;
Jingning Han's avatar
Jingning Han committed
439

clang-format's avatar
clang-format committed
440
    if (x + b_w > w) right = x + b_w - w;
Jingning Han's avatar
Jingning Han committed
441

clang-format's avatar
clang-format committed
442
    if (right > b_w) right = b_w;
Jingning Han's avatar
Jingning Han committed
443 444 445

    copy = b_w - left - right;

clang-format's avatar
clang-format committed
446
    if (left) vpx_memset16(dst, ref_row[0], left);
Jingning Han's avatar
Jingning Han committed
447

clang-format's avatar
clang-format committed
448
    if (copy) memcpy(dst + left, ref_row + x + left, copy * sizeof(uint16_t));
Jingning Han's avatar
Jingning Han committed
449

clang-format's avatar
clang-format committed
450
    if (right) vpx_memset16(dst + left + copy, ref_row[w - 1], right);
Jingning Han's avatar
Jingning Han committed
451 452 453 454

    dst += dst_stride;
    ++y;

clang-format's avatar
clang-format committed
455
    if (y > 0 && y < h) ref_row += src_stride;
Jingning Han's avatar
Jingning Han committed
456 457
  } while (--b_h);
}
458
#endif  // CONFIG_VPX_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
459

460
#if CONFIG_VPX_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
461 462 463
static void extend_and_predict(const uint8_t *buf_ptr1, int pre_buf_stride,
                               int x0, int y0, int b_w, int b_h,
                               int frame_width, int frame_height,
clang-format's avatar
clang-format committed
464 465
                               int border_offset, uint8_t *const dst,
                               int dst_buf_stride, int subpel_x, int subpel_y,
Jingning Han's avatar
Jingning Han committed
466
                               const InterpKernel *kernel,
clang-format's avatar
clang-format committed
467
                               const struct scale_factors *sf, MACROBLOCKD *xd,
Jingning Han's avatar
Jingning Han committed
468 469 470 471 472
                               int w, int h, int ref, int xs, int ys) {
  DECLARE_ALIGNED(16, uint16_t, mc_buf_high[80 * 2 * 80 * 2]);
  const uint8_t *buf_ptr;

  if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
clang-format's avatar
clang-format committed
473 474
    high_build_mc_border(buf_ptr1, pre_buf_stride, mc_buf_high, b_w, x0, y0,
                         b_w, b_h, frame_width, frame_height);
Jingning Han's avatar
Jingning Han committed
475 476
    buf_ptr = CONVERT_TO_BYTEPTR(mc_buf_high) + border_offset;
  } else {
clang-format's avatar
clang-format committed
477 478
    build_mc_border(buf_ptr1, pre_buf_stride, (uint8_t *)mc_buf_high, b_w, x0,
                    y0, b_w, b_h, frame_width, frame_height);
Jingning Han's avatar
Jingning Han committed
479 480 481 482
    buf_ptr = ((uint8_t *)mc_buf_high) + border_offset;
  }

  if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
clang-format's avatar
clang-format committed
483 484
    high_inter_predictor(buf_ptr, b_w, dst, dst_buf_stride, subpel_x, subpel_y,
                         sf, w, h, ref, kernel, xs, ys, xd->bd);
Jingning Han's avatar
Jingning Han committed
485
  } else {
clang-format's avatar
clang-format committed
486 487
    inter_predictor(buf_ptr, b_w, dst, dst_buf_stride, subpel_x, subpel_y, sf,
                    w, h, ref, kernel, xs, ys);
Jingning Han's avatar
Jingning Han committed
488 489 490 491 492 493
  }
}
#else
static void extend_and_predict(const uint8_t *buf_ptr1, int pre_buf_stride,
                               int x0, int y0, int b_w, int b_h,
                               int frame_width, int frame_height,
clang-format's avatar
clang-format committed
494 495
                               int border_offset, uint8_t *const dst,
                               int dst_buf_stride, int subpel_x, int subpel_y,
Jingning Han's avatar
Jingning Han committed
496
                               const InterpKernel *kernel,
clang-format's avatar
clang-format committed
497 498
                               const struct scale_factors *sf, int w, int h,
                               int ref, int xs, int ys) {
Jingning Han's avatar
Jingning Han committed
499 500 501
  DECLARE_ALIGNED(16, uint8_t, mc_buf[80 * 2 * 80 * 2]);
  const uint8_t *buf_ptr;

clang-format's avatar
clang-format committed
502 503
  build_mc_border(buf_ptr1, pre_buf_stride, mc_buf, b_w, x0, y0, b_w, b_h,
                  frame_width, frame_height);
Jingning Han's avatar
Jingning Han committed
504 505
  buf_ptr = mc_buf + border_offset;

clang-format's avatar
clang-format committed
506 507
  inter_predictor(buf_ptr, b_w, dst, dst_buf_stride, subpel_x, subpel_y, sf, w,
                  h, ref, kernel, xs, ys);
Jingning Han's avatar
Jingning Han committed
508
}
509
#endif  // CONFIG_VPX_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
510

clang-format's avatar
clang-format committed
511 512 513 514 515 516
static void dec_build_inter_predictors(
    VP10Decoder *const pbi, MACROBLOCKD *xd, int plane, int bw, int bh, int x,
    int y, int w, int h, int mi_x, int mi_y, const InterpKernel *kernel,
    const struct scale_factors *sf, struct buf_2d *pre_buf,
    struct buf_2d *dst_buf, const MV *mv, RefCntBuffer *ref_frame_buf,
    int is_scaled, int ref) {
517
  VP10_COMMON *const cm = &pbi->common;
Jingning Han's avatar
Jingning Han committed
518 519 520
  struct macroblockd_plane *const pd = &xd->plane[plane];
  uint8_t *const dst = dst_buf->buf + dst_buf->stride * y + x;
  MV32 scaled_mv;
clang-format's avatar
clang-format committed
521 522
  int xs, ys, x0, y0, x0_16, y0_16, frame_width, frame_height, buf_stride,
      subpel_x, subpel_y;
Jingning Han's avatar
Jingning Han committed
523 524 525 526 527 528 529 530 531 532
  uint8_t *ref_frame, *buf_ptr;

  // Get reference frame pointer, width and height.
  if (plane == 0) {
    frame_width = ref_frame_buf->buf.y_crop_width;
    frame_height = ref_frame_buf->buf.y_crop_height;
    ref_frame = ref_frame_buf->buf.y_buffer;
  } else {
    frame_width = ref_frame_buf->buf.uv_crop_width;
    frame_height = ref_frame_buf->buf.uv_crop_height;
clang-format's avatar
clang-format committed
533 534
    ref_frame =
        plane == 1 ? ref_frame_buf->buf.u_buffer : ref_frame_buf->buf.v_buffer;
Jingning Han's avatar
Jingning Han committed
535 536 537
  }

  if (is_scaled) {
clang-format's avatar
clang-format committed
538 539
    const MV mv_q4 = clamp_mv_to_umv_border_sb(
        xd, mv, bw, bh, pd->subsampling_x, pd->subsampling_y);
Jingning Han's avatar
Jingning Han committed
540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590
    // Co-ordinate of containing block to pixel precision.
    int x_start = (-xd->mb_to_left_edge >> (3 + pd->subsampling_x));
    int y_start = (-xd->mb_to_top_edge >> (3 + pd->subsampling_y));

    // Co-ordinate of the block to 1/16th pixel precision.
    x0_16 = (x_start + x) << SUBPEL_BITS;
    y0_16 = (y_start + y) << SUBPEL_BITS;

    // Co-ordinate of current block in reference frame
    // to 1/16th pixel precision.
    x0_16 = sf->scale_value_x(x0_16, sf);
    y0_16 = sf->scale_value_y(y0_16, sf);

    // Map the top left corner of the block into the reference frame.
    x0 = sf->scale_value_x(x_start + x, sf);
    y0 = sf->scale_value_y(y_start + y, sf);

    // Scale the MV and incorporate the sub-pixel offset of the block
    // in the reference frame.
    scaled_mv = vp10_scale_mv(&mv_q4, mi_x + x, mi_y + y, sf);
    xs = sf->x_step_q4;
    ys = sf->y_step_q4;
  } else {
    // Co-ordinate of containing block to pixel precision.
    x0 = (-xd->mb_to_left_edge >> (3 + pd->subsampling_x)) + x;
    y0 = (-xd->mb_to_top_edge >> (3 + pd->subsampling_y)) + y;

    // Co-ordinate of the block to 1/16th pixel precision.
    x0_16 = x0 << SUBPEL_BITS;
    y0_16 = y0 << SUBPEL_BITS;

    scaled_mv.row = mv->row * (1 << (1 - pd->subsampling_y));
    scaled_mv.col = mv->col * (1 << (1 - pd->subsampling_x));
    xs = ys = 16;
  }
  subpel_x = scaled_mv.col & SUBPEL_MASK;
  subpel_y = scaled_mv.row & SUBPEL_MASK;

  // Calculate the top left corner of the best matching block in the
  // reference frame.
  x0 += scaled_mv.col >> SUBPEL_BITS;
  y0 += scaled_mv.row >> SUBPEL_BITS;
  x0_16 += scaled_mv.col;
  y0_16 += scaled_mv.row;

  // Get reference block pointer.
  buf_ptr = ref_frame + y0 * pre_buf->stride + x0;
  buf_stride = pre_buf->stride;

  // Do border extension if there is motion or the
  // width/height is not a multiple of 8 pixels.
clang-format's avatar
clang-format committed
591 592
  if (is_scaled || scaled_mv.col || scaled_mv.row || (frame_width & 0x7) ||
      (frame_height & 0x7)) {
Jingning Han's avatar
Jingning Han committed
593 594 595 596 597 598 599
    int y1 = ((y0_16 + (h - 1) * ys) >> SUBPEL_BITS) + 1;

    // Get reference block bottom right horizontal coordinate.
    int x1 = ((x0_16 + (w - 1) * xs) >> SUBPEL_BITS) + 1;
    int x_pad = 0, y_pad = 0;

    if (subpel_x || (sf->x_step_q4 != SUBPEL_SHIFTS)) {
600 601
      x0 -= VPX_INTERP_EXTEND - 1;
      x1 += VPX_INTERP_EXTEND;
Jingning Han's avatar
Jingning Han committed
602 603 604 605
      x_pad = 1;
    }

    if (subpel_y || (sf->y_step_q4 != SUBPEL_SHIFTS)) {
606 607
      y0 -= VPX_INTERP_EXTEND - 1;
      y1 += VPX_INTERP_EXTEND;
Jingning Han's avatar
Jingning Han committed
608 609 610 611 612
      y_pad = 1;
    }

    // Wait until reference block is ready. Pad 7 more pixels as last 7
    // pixels of each superblock row can be changed by next superblock row.
613
    if (cm->frame_parallel_decode)
Jingning Han's avatar
Jingning Han committed
614
      vp10_frameworker_wait(pbi->frame_worker_owner, ref_frame_buf,
615
                            VPXMAX(0, (y1 + 7)) << (plane == 0 ? 0 : 1));
Jingning Han's avatar
Jingning Han committed
616 617 618 619 620 621 622 623 624 625

    // Skip border extension if block is inside the frame.
    if (x0 < 0 || x0 > frame_width - 1 || x1 < 0 || x1 > frame_width - 1 ||
        y0 < 0 || y0 > frame_height - 1 || y1 < 0 || y1 > frame_height - 1) {
      // Extend the border.
      const uint8_t *const buf_ptr1 = ref_frame + y0 * buf_stride + x0;
      const int b_w = x1 - x0 + 1;
      const int b_h = y1 - y0 + 1;
      const int border_offset = y_pad * 3 * b_w + x_pad * 3;

clang-format's avatar
clang-format committed
626 627 628
      extend_and_predict(buf_ptr1, buf_stride, x0, y0, b_w, b_h, frame_width,
                         frame_height, border_offset, dst, dst_buf->stride,
                         subpel_x, subpel_y, kernel, sf,
629
#if CONFIG_VPX_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
630 631 632 633 634 635 636 637
                         xd,
#endif
                         w, h, ref, xs, ys);
      return;
    }
  } else {
    // Wait until reference block is ready. Pad 7 more pixels as last 7
    // pixels of each superblock row can be changed by next superblock row.
clang-format's avatar
clang-format committed
638 639 640 641 642
    if (cm->frame_parallel_decode) {
      const int y1 = (y0_16 + (h - 1) * ys) >> SUBPEL_BITS;
      vp10_frameworker_wait(pbi->frame_worker_owner, ref_frame_buf,
                            VPXMAX(0, (y1 + 7)) << (plane == 0 ? 0 : 1));
    }
Jingning Han's avatar
Jingning Han committed
643
  }
644
#if CONFIG_VPX_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
645 646 647 648 649 650 651 652
  if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
    high_inter_predictor(buf_ptr, buf_stride, dst, dst_buf->stride, subpel_x,
                         subpel_y, sf, w, h, ref, kernel, xs, ys, xd->bd);
  } else {
    inter_predictor(buf_ptr, buf_stride, dst, dst_buf->stride, subpel_x,
                    subpel_y, sf, w, h, ref, kernel, xs, ys);
  }
#else
clang-format's avatar
clang-format committed
653 654
  inter_predictor(buf_ptr, buf_stride, dst, dst_buf->stride, subpel_x, subpel_y,
                  sf, w, h, ref, kernel, xs, ys);
655
#endif  // CONFIG_VPX_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
656 657
}

Yaowu Xu's avatar
Yaowu Xu committed
658
static void dec_build_inter_predictors_sb(VP10Decoder *const pbi,
clang-format's avatar
clang-format committed
659 660
                                          MACROBLOCKD *xd, int mi_row,
                                          int mi_col) {
Jingning Han's avatar
Jingning Han committed
661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687
  int plane;
  const int mi_x = mi_col * MI_SIZE;
  const int mi_y = mi_row * MI_SIZE;
  const MODE_INFO *mi = xd->mi[0];
  const InterpKernel *kernel = vp10_filter_kernels[mi->mbmi.interp_filter];
  const BLOCK_SIZE sb_type = mi->mbmi.sb_type;
  const int is_compound = has_second_ref(&mi->mbmi);

  for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
    struct macroblockd_plane *const pd = &xd->plane[plane];
    struct buf_2d *const dst_buf = &pd->dst;
    const int num_4x4_w = pd->n4_w;
    const int num_4x4_h = pd->n4_h;

    const int n4w_x4 = 4 * num_4x4_w;
    const int n4h_x4 = 4 * num_4x4_h;
    int ref;

    for (ref = 0; ref < 1 + is_compound; ++ref) {
      const struct scale_factors *const sf = &xd->block_refs[ref]->sf;
      struct buf_2d *const pre_buf = &pd->pre[ref];
      const int idx = xd->block_refs[ref]->idx;
      BufferPool *const pool = pbi->common.buffer_pool;
      RefCntBuffer *const ref_frame_buf = &pool->frame_bufs[idx];
      const int is_scaled = vp10_is_scaled(sf);

      if (sb_type < BLOCK_8X8) {
688 689 690 691 692 693 694
        const PARTITION_TYPE bp = BLOCK_8X8 - sb_type;
        const int have_vsplit = bp != PARTITION_HORZ;
        const int have_hsplit = bp != PARTITION_VERT;
        const int num_4x4_w = 2 >> ((!have_vsplit) | pd->subsampling_x);
        const int num_4x4_h = 2 >> ((!have_hsplit) | pd->subsampling_y);
        const int pw = 8 >> (have_vsplit | pd->subsampling_x);
        const int ph = 8 >> (have_hsplit | pd->subsampling_y);
695
        int x, y;
Jingning Han's avatar
Jingning Han committed
696 697
        for (y = 0; y < num_4x4_h; ++y) {
          for (x = 0; x < num_4x4_w; ++x) {
698
            const MV mv = average_split_mvs(pd, mi, ref, y * 2 + x);
clang-format's avatar
clang-format committed
699 700 701 702
            dec_build_inter_predictors(pbi, xd, plane, n4w_x4, n4h_x4, 4 * x,
                                       4 * y, pw, ph, mi_x, mi_y, kernel, sf,
                                       pre_buf, dst_buf, &mv, ref_frame_buf,
                                       is_scaled, ref);
Jingning Han's avatar
Jingning Han committed
703 704 705 706
          }
        }
      } else {
        const MV mv = mi->mbmi.mv[ref].as_mv;
clang-format's avatar
clang-format committed
707 708 709
        dec_build_inter_predictors(pbi, xd, plane, n4w_x4, n4h_x4, 0, 0, n4w_x4,
                                   n4h_x4, mi_x, mi_y, kernel, sf, pre_buf,
                                   dst_buf, &mv, ref_frame_buf, is_scaled, ref);
Jingning Han's avatar
Jingning Han committed
710 711 712 713 714
      }
    }
  }
}

clang-format's avatar
clang-format committed
715 716
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
717
  // get minimum log2 num4x4s dimension
718
  const int x = VPXMIN(n4_wl, n4_hl);
clang-format's avatar
clang-format committed
719
  return VPXMIN(mbmi->tx_size, x);
Jingning Han's avatar
Jingning Han committed
720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741
}

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
742
static MB_MODE_INFO *set_offsets(VP10_COMMON *const cm, MACROBLOCKD *const xd,
Jingning Han's avatar
Jingning Han committed
743
                                 BLOCK_SIZE bsize, int mi_row, int mi_col,
clang-format's avatar
clang-format committed
744 745
                                 int bw, int bh, int x_mis, int y_mis, int bwl,
                                 int bhl) {
Jingning Han's avatar
Jingning Han committed
746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771
  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);

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

Yaowu Xu's avatar
Yaowu Xu committed
772
static void decode_block(VP10Decoder *const pbi, MACROBLOCKD *const xd,
clang-format's avatar
clang-format committed
773 774
                         int mi_row, int mi_col, vpx_reader *r,
                         BLOCK_SIZE bsize, int bwl, int bhl) {
Yaowu Xu's avatar
Yaowu Xu committed
775
  VP10_COMMON *const cm = &pbi->common;
Jingning Han's avatar
Jingning Han committed
776 777 778
  const int less8x8 = bsize < BLOCK_8X8;
  const int bw = 1 << (bwl - 1);
  const int bh = 1 << (bhl - 1);
779 780
  const int x_mis = VPXMIN(bw, cm->mi_cols - mi_col);
  const int y_mis = VPXMIN(bh, cm->mi_rows - mi_row);
Jingning Han's avatar
Jingning Han committed
781

clang-format's avatar
clang-format committed
782 783
  MB_MODE_INFO *mbmi = set_offsets(cm, xd, bsize, mi_row, mi_col, bw, bh, x_mis,
                                   y_mis, bwl, bhl);
Jingning Han's avatar
Jingning Han committed
784 785 786 787 788

  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)
clang-format's avatar
clang-format committed
789 790
      vpx_internal_error(xd->error_info, VPX_CODEC_CORRUPT_FRAME,
                         "Invalid block size.");
Jingning Han's avatar
Jingning Han committed
791 792 793 794 795 796 797 798 799 800 801 802 803 804
  }

  vp10_read_mode_info(pbi, xd, mi_row, mi_col, r, x_mis, y_mis);

  if (mbmi->skip) {
    dec_reset_skip_context(xd);
  }

  if (!is_inter_block(mbmi)) {
    int plane;
    for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
      const struct macroblockd_plane *const pd = &xd->plane[plane];
      const TX_SIZE tx_size =
          plane ? dec_get_uv_tx_size(mbmi, pd->n4_wl, pd->n4_hl)
clang-format's avatar
clang-format committed
805
                : mbmi->tx_size;
Jingning Han's avatar
Jingning Han committed
806 807 808 809
      const int num_4x4_w = pd->n4_w;
      const int num_4x4_h = pd->n4_h;
      const int step = (1 << tx_size);
      int row, col;
clang-format's avatar
clang-format committed
810 811 812 813 814 815 816 817
      const int max_blocks_wide =
          num_4x4_w + (xd->mb_to_right_edge >= 0
                           ? 0
                           : xd->mb_to_right_edge >> (5 + pd->subsampling_x));
      const int max_blocks_high =
          num_4x4_h + (xd->mb_to_bottom_edge >= 0
                           ? 0
                           : xd->mb_to_bottom_edge >> (5 + pd->subsampling_y));
Jingning Han's avatar
Jingning Han committed
818 819 820

      for (row = 0; row < max_blocks_high; row += step)
        for (col = 0; col < max_blocks_wide; col += step)
clang-format's avatar
clang-format committed
821 822
          predict_and_reconstruct_intra_block(xd, r, mbmi, plane, row, col,
                                              tx_size);
Jingning Han's avatar
Jingning Han committed
823 824 825 826 827 828 829 830 831 832 833 834 835 836
    }
  } else {
    // Prediction
    dec_build_inter_predictors_sb(pbi, xd, mi_row, mi_col);

    // Reconstruction
    if (!mbmi->skip) {
      int eobtotal = 0;
      int plane;

      for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
        const struct macroblockd_plane *const pd = &xd->plane[plane];
        const TX_SIZE tx_size =
            plane ? dec_get_uv_tx_size(mbmi, pd->n4_wl, pd->n4_hl)
clang-format's avatar
clang-format committed
837
                  : mbmi->tx_size;
Jingning Han's avatar
Jingning Han committed
838 839 840 841
        const int num_4x4_w = pd->n4_w;
        const int num_4x4_h = pd->n4_h;
        const int step = (1 << tx_size);
        int row, col;
clang-format's avatar
clang-format committed
842 843 844 845 846 847 848 849
        const int max_blocks_wide =
            num_4x4_w + (xd->mb_to_right_edge >= 0
                             ? 0
                             : xd->mb_to_right_edge >> (5 + pd->subsampling_x));
        const int max_blocks_high =
            num_4x4_h +
            (xd->mb_to_bottom_edge >= 0 ? 0 : xd->mb_to_bottom_edge >>
                                                  (5 + pd->subsampling_y));
Jingning Han's avatar
Jingning Han committed
850 851 852

        for (row = 0; row < max_blocks_high; row += step)
          for (col = 0; col < max_blocks_wide; col += step)
clang-format's avatar
clang-format committed
853 854
            eobtotal +=
                reconstruct_inter_block(xd, r, mbmi, plane, row, col, tx_size);
Jingning Han's avatar
Jingning Han committed
855 856 857
      }

      if (!less8x8 && eobtotal == 0)
858 859 860
#if CONFIG_MISC_FIXES
        mbmi->has_no_coeffs = 1;  // skip loopfilter
#else
Jingning Han's avatar
Jingning Han committed
861
        mbmi->skip = 1;  // skip loopfilter
862
#endif
Jingning Han's avatar
Jingning Han committed
863 864 865 866 867 868
    }
  }

  xd->corrupted |= vpx_reader_has_error(r);
}

clang-format's avatar
clang-format committed
869 870
static INLINE int dec_partition_plane_context(const MACROBLOCKD *xd, int mi_row,
                                              int mi_col, int bsl) {
Jingning Han's avatar
Jingning Han committed
871 872
  const PARTITION_CONTEXT *above_ctx = xd->above_seg_context + mi_col;
  const PARTITION_CONTEXT *left_ctx = xd->left_seg_context + (mi_row & MI_MASK);
clang-format's avatar
clang-format committed
873
  int above = (*above_ctx >> bsl) & 1, left = (*left_ctx >> bsl) & 1;
Jingning Han's avatar
Jingning Han committed
874

clang-format's avatar
clang-format committed
875
  //  assert(bsl >= 0);
Jingning Han's avatar
Jingning Han committed
876 877 878 879

  return (left * 2 + above) + bsl * PARTITION_PLOFFSET;
}

clang-format's avatar
clang-format committed
880 881
static INLINE void dec_update_partition_context(MACROBLOCKD *xd, int mi_row,
                                                int mi_col, BLOCK_SIZE subsize,
Jingning Han's avatar
Jingning Han committed
882 883 884 885 886 887 888 889 890 891 892
                                                int bw) {
  PARTITION_CONTEXT *const above_ctx = xd->above_seg_context + mi_col;
  PARTITION_CONTEXT *const left_ctx = xd->left_seg_context + (mi_row & MI_MASK);

  // update the partition context at the end notes. set partition bits
  // of block sizes larger than the current one to be one, and partition
  // bits of smaller block sizes to be zero.
  memset(above_ctx, partition_context_lookup[subsize].above, bw);
  memset(left_ctx, partition_context_lookup[subsize].left, bw);
}

893 894
static PARTITION_TYPE read_partition(VP10_COMMON *cm, MACROBLOCKD *xd,
                                     int mi_row, int mi_col, vpx_reader *r,
Jingning Han's avatar
Jingning Han committed
895 896
                                     int has_rows, int has_cols, int bsl) {
  const int ctx = dec_partition_plane_context(xd, mi_row, mi_col, bsl);
897
  const vpx_prob *const probs = cm->fc->partition_prob[ctx];
Jingning Han's avatar
Jingning Han committed
898 899 900 901 902 903 904 905 906 907 908 909
  FRAME_COUNTS *counts = xd->counts;
  PARTITION_TYPE p;

  if (has_rows && has_cols)
    p = (PARTITION_TYPE)vpx_read_tree(r, vp10_partition_tree, probs);
  else if (!has_rows && has_cols)
    p = vpx_read(r, probs[1]) ? PARTITION_SPLIT : PARTITION_HORZ;
  else if (has_rows && !has_cols)
    p = vpx_read(r, probs[2]) ? PARTITION_SPLIT : PARTITION_VERT;
  else
    p = PARTITION_SPLIT;

clang-format's avatar
clang-format committed
910
  if (counts) ++counts->partition[ctx][p];
Jingning Han's avatar
Jingning Han committed
911 912 913 914 915

  return p;
}

// TODO(slavarnway): eliminate bsize and subsize in future commits
Yaowu Xu's avatar
Yaowu Xu committed
916
static void decode_partition(VP10Decoder *const pbi, MACROBLOCKD *const xd,
clang-format's avatar
clang-format committed
917 918
                             int mi_row, int mi_col, vpx_reader *r,
                             BLOCK_SIZE bsize, int n4x4_l2) {
Yaowu Xu's avatar
Yaowu Xu committed
919
  VP10_COMMON *const cm = &pbi->common;
Jingning Han's avatar
Jingning Han committed
920 921 922 923 924 925 926 927
  const int n8x8_l2 = n4x4_l2 - 1;
  const int num_8x8_wh = 1 << n8x8_l2;
  const int hbs = num_8x8_wh >> 1;
  PARTITION_TYPE partition;
  BLOCK_SIZE subsize;
  const int has_rows = (mi_row + hbs) < cm->mi_rows;
  const int has_cols = (mi_col + hbs) < cm->mi_cols;

clang-format's avatar
clang-format committed
928
  if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
Jingning Han's avatar
Jingning Han committed
929

clang-format's avatar
clang-format committed
930 931
  partition =
      read_partition(cm, xd, mi_row, mi_col, r, has_rows, has_cols, n8x8_l2);
Jingning Han's avatar
Jingning Han committed
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 958 959 960 961
  subsize = subsize_lookup[partition][bsize];  // get_subsize(bsize, partition);
  if (!hbs) {
    // calculate bmode block dimensions (log 2)
    xd->bmode_blocks_wl = 1 >> !!(partition & PARTITION_VERT);
    xd->bmode_blocks_hl = 1 >> !!(partition & PARTITION_HORZ);
    decode_block(pbi, xd, mi_row, mi_col, r, subsize, 1, 1);
  } else {
    switch (partition) {
      case PARTITION_NONE:
        decode_block(pbi, xd, mi_row, mi_col, r, subsize, n4x4_l2, n4x4_l2);
        break;
      case PARTITION_HORZ:
        decode_block(pbi, xd, mi_row, mi_col, r, subsize, n4x4_l2, n8x8_l2);
        if (has_rows)
          decode_block(pbi, xd, mi_row + hbs, mi_col, r, subsize, n4x4_l2,
                       n8x8_l2);
        break;
      case PARTITION_VERT:
        decode_block(pbi, xd, mi_row, mi_col, r, subsize, n8x8_l2, n4x4_l2);
        if (has_cols)
          decode_block(pbi, xd, mi_row, mi_col + hbs, r, subsize, n8x8_l2,
                       n4x4_l2);
        break;
      case PARTITION_SPLIT:
        decode_partition(pbi, xd, mi_row, mi_col, r, subsize, n8x8_l2);
        decode_partition(pbi, xd, mi_row, mi_col + hbs, r, subsize, n8x8_l2);
        decode_partition(pbi, xd, mi_row + hbs, mi_col, r, subsize, n8x8_l2);
        decode_partition(pbi, xd, mi_row + hbs, mi_col + hbs, r, subsize,
                         n8x8_l2);
        break;
clang-format's avatar
clang-format committed
962
      default: assert(0 && "Invalid partition type");
Jingning Han's avatar
Jingning Han committed
963 964 965 966 967 968 969 970 971
    }
  }

  // update partition context
  if (bsize >= BLOCK_8X8 &&
      (bsize == BLOCK_8X8 || partition != PARTITION_SPLIT))
    dec_update_partition_context(xd, mi_row, mi_col, subsize, num_8x8_wh);
}

clang-format's avatar
clang-format committed
972
static void setup_token_decoder(const uint8_t *data, const uint8_t *data_end,
Jingning Han's avatar
Jingning Han committed
973 974
                                size_t read_size,
                                struct vpx_internal_error_info *error_info,
clang-format's avatar
clang-format committed
975
                                vpx_reader *r, vpx_decrypt_cb decrypt_cb,
Jingning Han's avatar
Jingning Han committed
976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001
                                void *decrypt_state) {
  // Validate the calculated partition length. If the buffer
  // described by the partition can't be fully read, then restrict
  // it to the portion that can be (for EC mode) or throw an error.
  if (!read_is_valid(data, read_size, data_end))
    vpx_internal_error(error_info, VPX_CODEC_CORRUPT_FRAME,
                       "Truncated packet or corrupt tile length");

  if (vpx_reader_init(r, data, read_size, decrypt_cb, decrypt_state))
    vpx_internal_error(error_info, VPX_CODEC_MEM_ERROR,
                       "Failed to allocate bool decoder %d", 1);
}

static void read_coef_probs_common(vp10_coeff_probs_model *coef_probs,
                                   vpx_reader *r) {
  int i, j, k, l, m;

  if (vpx_read_bit(r))
    for (i = 0; i < PLANE_TYPES; ++i)
      for (j = 0; j < REF_TYPES; ++j)
        for (k = 0; k < COEF_BANDS; ++k)
          for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l)
            for (m = 0; m < UNCONSTRAINED_NODES; ++m)
              vp10_diff_update_prob(r, &coef_probs[i][j][k][l][m]);
}

clang-format's avatar
clang-format committed
1002 1003 1004 1005 1006
static void read_coef_probs(FRAME_CONTEXT *fc, TX_MODE tx_mode, vpx_reader *r) {
  const TX_SIZE max_tx_size = tx_mode_to_biggest_tx_size[tx_mode];
  TX_SIZE tx_size;
  for (tx_size = TX_4X4; tx_size <= max_tx_size; ++tx_size)
    read_coef_probs_common(fc->coef_probs[tx_size], r);
Jingning Han's avatar
Jingning Han committed
1007 1008
}

1009
static void setup_segmentation(VP10_COMMON *const cm,
Jingning Han's avatar
Jingning Han committed
1010
                               struct vpx_read_bit_buffer *rb) {
1011
  struct segmentation *const seg = &cm->seg;
1012 1013 1014
#if !CONFIG_MISC_FIXES
  struct segmentation_probs *const segp = &cm->segp;
#endif
Jingning Han's avatar
Jingning Han committed
1015 1016 1017 1018 1019 1020
  int i, j;

  seg->update_map = 0;
  seg->update_data = 0;

  seg->enabled = vpx_rb_read_bit(rb);
clang-format's avatar
clang-format committed
1021
  if (!seg->enabled) return;
Jingning Han's avatar
Jingning Han committed
1022 1023

  // Segmentation map update
1024 1025 1026 1027 1028 </