1ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/*
2ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
4ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  Use of this source code is governed by a BSD-style license
5ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  that can be found in the LICENSE file in the root of the source
6ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  tree. An additional intellectual property rights grant can be found
7ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  in the file PATENTS.  All contributing project authors may
8ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  be found in the AUTHORS file in the root of the source tree.
9ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */
10ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
11ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include <assert.h>
12b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include <stdlib.h>  // qsort()
13ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
14ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "./vp9_rtcd.h"
15b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "./vpx_scale_rtcd.h"
16b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
17ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vpx_mem/vpx_mem.h"
18b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vpx_ports/mem_ops.h"
19ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vpx_scale/vpx_scale.h"
20ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2191037db265ecdd914a26e056cf69207b4f50924ehkuang#include "vp9/common/vp9_alloccommon.h"
22ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_common.h"
23ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_entropy.h"
24ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_entropymode.h"
255ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#include "vp9/common/vp9_idct.h"
2691037db265ecdd914a26e056cf69207b4f50924ehkuang#include "vp9/common/vp9_pred_common.h"
27ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_quant_common.h"
2891037db265ecdd914a26e056cf69207b4f50924ehkuang#include "vp9/common/vp9_reconintra.h"
2991037db265ecdd914a26e056cf69207b4f50924ehkuang#include "vp9/common/vp9_reconinter.h"
30ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_seg_common.h"
31ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_tile_common.h"
32ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
33b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vp9/decoder/vp9_decodeframe.h"
34ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/decoder/vp9_detokenize.h"
35ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/decoder/vp9_decodemv.h"
36b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vp9/decoder/vp9_decoder.h"
3791037db265ecdd914a26e056cf69207b4f50924ehkuang#include "vp9/decoder/vp9_dsubexp.h"
38b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vp9/decoder/vp9_dthread.h"
39ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/decoder/vp9_read_bit_buffer.h"
40b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vp9/decoder/vp9_reader.h"
41f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang#include "vp9/decoder/vp9_thread.h"
42ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
43b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic int is_compound_reference_allowed(const VP9_COMMON *cm) {
445ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int i;
45b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  for (i = 1; i < REFS_PER_FRAME; ++i)
46b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (cm->ref_frame_sign_bias[i + 1] != cm->ref_frame_sign_bias[1])
475ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      return 1;
485ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
495ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  return 0;
505ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang}
515ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
52b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic void setup_compound_reference_mode(VP9_COMMON *cm) {
535ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (cm->ref_frame_sign_bias[LAST_FRAME] ==
545ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          cm->ref_frame_sign_bias[GOLDEN_FRAME]) {
555ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    cm->comp_fixed_ref = ALTREF_FRAME;
565ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    cm->comp_var_ref[0] = LAST_FRAME;
575ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    cm->comp_var_ref[1] = GOLDEN_FRAME;
585ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  } else if (cm->ref_frame_sign_bias[LAST_FRAME] ==
595ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                 cm->ref_frame_sign_bias[ALTREF_FRAME]) {
605ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    cm->comp_fixed_ref = GOLDEN_FRAME;
615ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    cm->comp_var_ref[0] = LAST_FRAME;
625ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    cm->comp_var_ref[1] = ALTREF_FRAME;
635ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  } else {
645ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    cm->comp_fixed_ref = LAST_FRAME;
655ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    cm->comp_var_ref[0] = GOLDEN_FRAME;
665ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    cm->comp_var_ref[1] = ALTREF_FRAME;
675ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
685ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang}
695ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
7091037db265ecdd914a26e056cf69207b4f50924ehkuangstatic int read_is_valid(const uint8_t *start, size_t len, const uint8_t *end) {
71b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  return len != 0 && len <= (size_t)(end - start);
72ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
73ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
74ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic int decode_unsigned_max(struct vp9_read_bit_buffer *rb, int max) {
75ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int data = vp9_rb_read_literal(rb, get_unsigned_bits(max));
76ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return data > max ? max : data;
77ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
78ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
7991037db265ecdd914a26e056cf69207b4f50924ehkuangstatic TX_MODE read_tx_mode(vp9_reader *r) {
8091037db265ecdd914a26e056cf69207b4f50924ehkuang  TX_MODE tx_mode = vp9_read_literal(r, 2);
8191037db265ecdd914a26e056cf69207b4f50924ehkuang  if (tx_mode == ALLOW_32X32)
8291037db265ecdd914a26e056cf69207b4f50924ehkuang    tx_mode += vp9_read_bit(r);
8391037db265ecdd914a26e056cf69207b4f50924ehkuang  return tx_mode;
84ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
85ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
86b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic void read_tx_mode_probs(struct tx_probs *tx_probs, vp9_reader *r) {
8791037db265ecdd914a26e056cf69207b4f50924ehkuang  int i, j;
88ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
8991037db265ecdd914a26e056cf69207b4f50924ehkuang  for (i = 0; i < TX_SIZE_CONTEXTS; ++i)
90f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    for (j = 0; j < TX_SIZES - 3; ++j)
915ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      vp9_diff_update_prob(r, &tx_probs->p8x8[i][j]);
92ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
9391037db265ecdd914a26e056cf69207b4f50924ehkuang  for (i = 0; i < TX_SIZE_CONTEXTS; ++i)
94f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    for (j = 0; j < TX_SIZES - 2; ++j)
955ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      vp9_diff_update_prob(r, &tx_probs->p16x16[i][j]);
96ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
9791037db265ecdd914a26e056cf69207b4f50924ehkuang  for (i = 0; i < TX_SIZE_CONTEXTS; ++i)
98f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    for (j = 0; j < TX_SIZES - 1; ++j)
995ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      vp9_diff_update_prob(r, &tx_probs->p32x32[i][j]);
1005ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang}
1015ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
1025ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangstatic void read_switchable_interp_probs(FRAME_CONTEXT *fc, vp9_reader *r) {
1035ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int i, j;
1045ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  for (j = 0; j < SWITCHABLE_FILTER_CONTEXTS; ++j)
1055ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    for (i = 0; i < SWITCHABLE_FILTERS - 1; ++i)
1065ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      vp9_diff_update_prob(r, &fc->switchable_interp_prob[j][i]);
1075ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang}
1085ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
1095ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangstatic void read_inter_mode_probs(FRAME_CONTEXT *fc, vp9_reader *r) {
1105ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int i, j;
1115ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  for (i = 0; i < INTER_MODE_CONTEXTS; ++i)
1125ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    for (j = 0; j < INTER_MODES - 1; ++j)
1135ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      vp9_diff_update_prob(r, &fc->inter_mode_probs[i][j]);
1145ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang}
1155ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
116b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic REFERENCE_MODE read_frame_reference_mode(const VP9_COMMON *cm,
117b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                                vp9_reader *r) {
118b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (is_compound_reference_allowed(cm)) {
119b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    return vp9_read_bit(r) ? (vp9_read_bit(r) ? REFERENCE_MODE_SELECT
120b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                              : COMPOUND_REFERENCE)
121b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                           : SINGLE_REFERENCE;
122b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  } else {
123b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    return SINGLE_REFERENCE;
124b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  }
1255ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang}
1265ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
127b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic void read_frame_reference_mode_probs(VP9_COMMON *cm, vp9_reader *r) {
128b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  FRAME_CONTEXT *const fc = &cm->fc;
1295ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int i;
1305ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
131b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (cm->reference_mode == REFERENCE_MODE_SELECT)
132b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    for (i = 0; i < COMP_INTER_CONTEXTS; ++i)
133b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      vp9_diff_update_prob(r, &fc->comp_inter_prob[i]);
1345ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
135b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (cm->reference_mode != COMPOUND_REFERENCE)
136b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    for (i = 0; i < REF_CONTEXTS; ++i) {
137b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      vp9_diff_update_prob(r, &fc->single_ref_prob[i][0]);
138b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      vp9_diff_update_prob(r, &fc->single_ref_prob[i][1]);
1395ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
1405ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
141b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (cm->reference_mode != SINGLE_REFERENCE)
142b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    for (i = 0; i < REF_CONTEXTS; ++i)
143b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      vp9_diff_update_prob(r, &fc->comp_ref_prob[i]);
1445ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang}
1455ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
1469b35249446b07f40ac5fcc3205f2c048616efacchkuangstatic void update_mv_probs(vp9_prob *p, int n, vp9_reader *r) {
1479b35249446b07f40ac5fcc3205f2c048616efacchkuang  int i;
1489b35249446b07f40ac5fcc3205f2c048616efacchkuang  for (i = 0; i < n; ++i)
149b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (vp9_read(r, MV_UPDATE_PROB))
150b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      p[i] = (vp9_read_literal(r, 7) << 1) | 1;
1515ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang}
1525ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
1539b35249446b07f40ac5fcc3205f2c048616efacchkuangstatic void read_mv_probs(nmv_context *ctx, int allow_hp, vp9_reader *r) {
1549b35249446b07f40ac5fcc3205f2c048616efacchkuang  int i, j;
1555ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
1569b35249446b07f40ac5fcc3205f2c048616efacchkuang  update_mv_probs(ctx->joints, MV_JOINTS - 1, r);
1575ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
1585ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  for (i = 0; i < 2; ++i) {
1599b35249446b07f40ac5fcc3205f2c048616efacchkuang    nmv_component *const comp_ctx = &ctx->comps[i];
1609b35249446b07f40ac5fcc3205f2c048616efacchkuang    update_mv_probs(&comp_ctx->sign, 1, r);
1619b35249446b07f40ac5fcc3205f2c048616efacchkuang    update_mv_probs(comp_ctx->classes, MV_CLASSES - 1, r);
1629b35249446b07f40ac5fcc3205f2c048616efacchkuang    update_mv_probs(comp_ctx->class0, CLASS0_SIZE - 1, r);
1639b35249446b07f40ac5fcc3205f2c048616efacchkuang    update_mv_probs(comp_ctx->bits, MV_OFFSET_BITS, r);
1645ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
1655ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
1665ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  for (i = 0; i < 2; ++i) {
1679b35249446b07f40ac5fcc3205f2c048616efacchkuang    nmv_component *const comp_ctx = &ctx->comps[i];
1685ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    for (j = 0; j < CLASS0_SIZE; ++j)
169b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      update_mv_probs(comp_ctx->class0_fp[j], MV_FP_SIZE - 1, r);
1709b35249446b07f40ac5fcc3205f2c048616efacchkuang    update_mv_probs(comp_ctx->fp, 3, r);
1715ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
1725ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
1735ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (allow_hp) {
1745ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    for (i = 0; i < 2; ++i) {
1759b35249446b07f40ac5fcc3205f2c048616efacchkuang      nmv_component *const comp_ctx = &ctx->comps[i];
1769b35249446b07f40ac5fcc3205f2c048616efacchkuang      update_mv_probs(&comp_ctx->class0_hp, 1, r);
1779b35249446b07f40ac5fcc3205f2c048616efacchkuang      update_mv_probs(&comp_ctx->hp, 1, r);
1785ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
1795ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
180ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
181ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1821184aebb761cbeac9124c37189a80a1a58f04b6bhkuangstatic void setup_plane_dequants(VP9_COMMON *cm, MACROBLOCKD *xd, int q_index) {
183ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int i;
1841184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  xd->plane[0].dequant = cm->y_dequant[q_index];
185ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
186ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 1; i < MAX_MB_PLANE; i++)
1871184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    xd->plane[i].dequant = cm->uv_dequant[q_index];
188ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
189ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1905ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangstatic void inverse_transform_block(MACROBLOCKD* xd, int plane, int block,
191b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                    TX_SIZE tx_size, uint8_t *dst, int stride,
192b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                    int eob) {
1931184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  struct macroblockd_plane *const pd = &xd->plane[plane];
1945ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (eob > 0) {
1955ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    TX_TYPE tx_type;
1966ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    const PLANE_TYPE plane_type = pd->plane_type;
1979b35249446b07f40ac5fcc3205f2c048616efacchkuang    int16_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
1985ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    switch (tx_size) {
1995ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      case TX_4X4:
2009b35249446b07f40ac5fcc3205f2c048616efacchkuang        tx_type = get_tx_type_4x4(plane_type, xd, block);
2015ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if (tx_type == DCT_DCT)
2025ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          xd->itxm_add(dqcoeff, dst, stride, eob);
2035ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        else
2045ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          vp9_iht4x4_16_add(dqcoeff, dst, stride, tx_type);
2055ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        break;
2065ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      case TX_8X8:
207b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        tx_type = get_tx_type(plane_type, xd);
2085ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        vp9_iht8x8_add(tx_type, dqcoeff, dst, stride, eob);
2095ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        break;
2105ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      case TX_16X16:
211b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        tx_type = get_tx_type(plane_type, xd);
2125ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        vp9_iht16x16_add(tx_type, dqcoeff, dst, stride, eob);
2135ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        break;
2145ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      case TX_32X32:
2155ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        tx_type = DCT_DCT;
2165ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        vp9_idct32x32_add(dqcoeff, dst, stride, eob);
2175ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        break;
2185ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      default:
219b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        assert(0 && "Invalid transform size");
2205ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
2215ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
2225ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (eob == 1) {
2235ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      vpx_memset(dqcoeff, 0, 2 * sizeof(dqcoeff[0]));
2245ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    } else {
2255ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (tx_type == DCT_DCT && tx_size <= TX_16X16 && eob <= 10)
2265ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        vpx_memset(dqcoeff, 0, 4 * (4 << tx_size) * sizeof(dqcoeff[0]));
2275ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      else if (tx_size == TX_32X32 && eob <= 34)
2285ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        vpx_memset(dqcoeff, 0, 256 * sizeof(dqcoeff[0]));
229ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      else
2305ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        vpx_memset(dqcoeff, 0, (16 << (tx_size << 1)) * sizeof(dqcoeff[0]));
23191037db265ecdd914a26e056cf69207b4f50924ehkuang    }
232ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
233ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
234ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2355ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangstruct intra_args {
2365ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  VP9_COMMON *cm;
2375ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MACROBLOCKD *xd;
2385ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  vp9_reader *r;
2395ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang};
2405ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
2415ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangstatic void predict_and_reconstruct_intra_block(int plane, int block,
2425ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                                BLOCK_SIZE plane_bsize,
2435ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                                TX_SIZE tx_size, void *arg) {
2446ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  struct intra_args *const args = (struct intra_args *)arg;
2455ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  VP9_COMMON *const cm = args->cm;
2465ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MACROBLOCKD *const xd = args->xd;
2471184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  struct macroblockd_plane *const pd = &xd->plane[plane];
2486ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  MODE_INFO *const mi = xd->mi[0];
249b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const MB_PREDICTION_MODE mode = (plane == 0) ? get_y_mode(mi, block)
250b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                               : mi->mbmi.uv_mode;
2519b35249446b07f40ac5fcc3205f2c048616efacchkuang  int x, y;
2529b35249446b07f40ac5fcc3205f2c048616efacchkuang  uint8_t *dst;
2539b35249446b07f40ac5fcc3205f2c048616efacchkuang  txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &x, &y);
2549b35249446b07f40ac5fcc3205f2c048616efacchkuang  dst = &pd->dst.buf[4 * y * pd->dst.stride + 4 * x];
255ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2569b35249446b07f40ac5fcc3205f2c048616efacchkuang  vp9_predict_intra_block(xd, block >> (tx_size << 1),
2571184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                          b_width_log2(plane_bsize), tx_size, mode,
258b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                          dst, pd->dst.stride, dst, pd->dst.stride,
259b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                          x, y, plane);
260b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
261b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (!mi->mbmi.skip) {
262b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    const int eob = vp9_decode_block_tokens(cm, xd, plane, block,
263b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                            plane_bsize, x, y, tx_size,
264b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                            args->r);
265b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    inverse_transform_block(xd, plane, block, tx_size, dst, pd->dst.stride,
266b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                            eob);
2675ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
268ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
269ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2705ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangstruct inter_args {
2715ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  VP9_COMMON *cm;
2725ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MACROBLOCKD *xd;
2735ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  vp9_reader *r;
2745ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int *eobtotal;
2755ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang};
2765ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
2775ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangstatic void reconstruct_inter_block(int plane, int block,
2785ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                    BLOCK_SIZE plane_bsize,
2795ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                    TX_SIZE tx_size, void *arg) {
2806ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  struct inter_args *args = (struct inter_args *)arg;
2815ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  VP9_COMMON *const cm = args->cm;
2825ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MACROBLOCKD *const xd = args->xd;
283b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  struct macroblockd_plane *const pd = &xd->plane[plane];
284b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int x, y, eob;
2859b35249446b07f40ac5fcc3205f2c048616efacchkuang  txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &x, &y);
286b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  eob = vp9_decode_block_tokens(cm, xd, plane, block, plane_bsize, x, y,
287b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                tx_size, args->r);
288b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  inverse_transform_block(xd, plane, block, tx_size,
289b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                          &pd->dst.buf[4 * y * pd->dst.stride + 4 * x],
290b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                          pd->dst.stride, eob);
291b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  *args->eobtotal += eob;
292ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
293ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2946ac915abcdb404a00d927fe6308a47fcf09d9519hkuangstatic MB_MODE_INFO *set_offsets(VP9_COMMON *const cm, MACROBLOCKD *const xd,
2956ac915abcdb404a00d927fe6308a47fcf09d9519hkuang                                 const TileInfo *const tile,
2966ac915abcdb404a00d927fe6308a47fcf09d9519hkuang                                 BLOCK_SIZE bsize, int mi_row, int mi_col) {
2971184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const int bw = num_8x8_blocks_wide_lookup[bsize];
298b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int bh = num_8x8_blocks_high_lookup[bsize];
299b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int x_mis = MIN(bw, cm->mi_cols - mi_col);
300b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int y_mis = MIN(bh, cm->mi_rows - mi_row);
3016ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  const int offset = mi_row * cm->mi_stride + mi_col;
302b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int x, y;
3031184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
3046ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  xd->mi = cm->mi_grid_visible + offset;
3056ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  xd->mi[0] = &cm->mi[offset];
3066ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  xd->mi[0]->mbmi.sb_type = bsize;
307b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  for (y = 0; y < y_mis; ++y)
308b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    for (x = !y; x < x_mis; ++x)
3096ac915abcdb404a00d927fe6308a47fcf09d9519hkuang      xd->mi[y * cm->mi_stride + x] = xd->mi[0];
31091037db265ecdd914a26e056cf69207b4f50924ehkuang
3116ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  set_skip_context(xd, mi_row, mi_col);
312ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
313ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Distance of Mb to the various image edges. These are specified to 8th pel
314ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // as they are always compared to values that are in 1/8th pel units
3155ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols);
316ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
317b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  vp9_setup_dst_planes(xd, get_frame_new_buffer(cm), mi_row, mi_col);
3186ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  return &xd->mi[0]->mbmi;
319ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
320ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3215ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangstatic void set_ref(VP9_COMMON *const cm, MACROBLOCKD *const xd,
3225ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                    int idx, int mi_row, int mi_col) {
3236ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
324b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  RefBuffer *ref_buffer = &cm->frame_refs[mbmi->ref_frame[idx] - LAST_FRAME];
325b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  xd->block_refs[idx] = ref_buffer;
326b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (!vp9_is_valid_scale(&ref_buffer->sf))
3271184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
3281184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                       "Invalid scale factors");
329b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  vp9_setup_pre_planes(xd, idx, ref_buffer->buf, mi_row, mi_col,
330b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                       &ref_buffer->sf);
331b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  xd->corrupted |= ref_buffer->buf->corrupted;
332ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
333ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
334a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanianstatic void decode_block(VP9_COMMON *const cm, MACROBLOCKD *const xd,
335a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian                         const TileInfo *const tile,
336a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian                         int mi_row, int mi_col,
337a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian                         vp9_reader *r, BLOCK_SIZE bsize) {
338f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  const int less8x8 = bsize < BLOCK_8X8;
3396ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  MB_MODE_INFO *mbmi = set_offsets(cm, xd, tile, bsize, mi_row, mi_col);
3405ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  vp9_read_mode_info(cm, xd, tile, mi_row, mi_col, r);
341ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
34291037db265ecdd914a26e056cf69207b4f50924ehkuang  if (less8x8)
343f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    bsize = BLOCK_8X8;
344ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
345b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (mbmi->skip) {
3465ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    reset_skip_context(xd, bsize);
34791037db265ecdd914a26e056cf69207b4f50924ehkuang  } else {
3485ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (cm->seg.enabled)
3495ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      setup_plane_dequants(cm, xd, vp9_get_qindex(&cm->seg, mbmi->segment_id,
3505ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                                  cm->base_qindex));
3515ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
35291037db265ecdd914a26e056cf69207b4f50924ehkuang
3535ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (!is_inter_block(mbmi)) {
354b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    struct intra_args arg = { cm, xd, r };
355b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    vp9_foreach_transformed_block(xd, bsize,
356b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                  predict_and_reconstruct_intra_block, &arg);
3575ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  } else {
3585ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // Setup
3595ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    set_ref(cm, xd, 0, mi_row, mi_col);
3601184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    if (has_second_ref(mbmi))
3615ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      set_ref(cm, xd, 1, mi_row, mi_col);
36291037db265ecdd914a26e056cf69207b4f50924ehkuang
3635ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // Prediction
364b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    vp9_dec_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
3655ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
3665ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // Reconstruction
367b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (!mbmi->skip) {
3685ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      int eobtotal = 0;
369b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      struct inter_args arg = { cm, xd, r, &eobtotal };
370b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      vp9_foreach_transformed_block(xd, bsize, reconstruct_inter_block, &arg);
3715ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (!less8x8 && eobtotal == 0)
372b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        mbmi->skip = 1;  // skip loopfilter
37391037db265ecdd914a26e056cf69207b4f50924ehkuang    }
37491037db265ecdd914a26e056cf69207b4f50924ehkuang  }
3755ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
376ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  xd->corrupted |= vp9_reader_has_error(r);
377ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
378ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3795ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangstatic PARTITION_TYPE read_partition(VP9_COMMON *cm, MACROBLOCKD *xd, int hbs,
3805ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                     int mi_row, int mi_col, BLOCK_SIZE bsize,
3815ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                     vp9_reader *r) {
3826ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  const int ctx = partition_plane_context(xd, mi_row, mi_col, bsize);
3835ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const vp9_prob *const probs = get_partition_probs(cm, ctx);
3845ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const int has_rows = (mi_row + hbs) < cm->mi_rows;
3855ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const int has_cols = (mi_col + hbs) < cm->mi_cols;
3865ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  PARTITION_TYPE p;
3875ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
3885ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (has_rows && has_cols)
3896ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    p = (PARTITION_TYPE)vp9_read_tree(r, vp9_partition_tree, probs);
3905ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  else if (!has_rows && has_cols)
3915ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    p = vp9_read(r, probs[1]) ? PARTITION_SPLIT : PARTITION_HORZ;
3925ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  else if (has_rows && !has_cols)
3935ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    p = vp9_read(r, probs[2]) ? PARTITION_SPLIT : PARTITION_VERT;
3945ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  else
3955ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    p = PARTITION_SPLIT;
3965ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
3975ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (!cm->frame_parallel_decoding_mode)
3985ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    ++cm->counts.partition[ctx][p];
3995ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
4005ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  return p;
4015ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang}
4025ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
403a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanianstatic void decode_partition(VP9_COMMON *const cm, MACROBLOCKD *const xd,
404a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian                             const TileInfo *const tile,
405a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian                             int mi_row, int mi_col,
406a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian                             vp9_reader* r, BLOCK_SIZE bsize) {
4071184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const int hbs = num_8x8_blocks_wide_lookup[bsize] / 2;
4085ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  PARTITION_TYPE partition;
4091184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  BLOCK_SIZE subsize;
410ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4111184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
412ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    return;
413ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4145ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  partition = read_partition(cm, xd, hbs, mi_row, mi_col, bsize, r);
415ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  subsize = get_subsize(bsize, partition);
4165ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (subsize < BLOCK_8X8) {
417a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian    decode_block(cm, xd, tile, mi_row, mi_col, r, subsize);
4185ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  } else {
4195ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    switch (partition) {
4205ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      case PARTITION_NONE:
421a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian        decode_block(cm, xd, tile, mi_row, mi_col, r, subsize);
4225ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        break;
4235ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      case PARTITION_HORZ:
424a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian        decode_block(cm, xd, tile, mi_row, mi_col, r, subsize);
4255ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if (mi_row + hbs < cm->mi_rows)
426a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian          decode_block(cm, xd, tile, mi_row + hbs, mi_col, r, subsize);
4275ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        break;
4285ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      case PARTITION_VERT:
429a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian        decode_block(cm, xd, tile, mi_row, mi_col, r, subsize);
4305ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if (mi_col + hbs < cm->mi_cols)
431a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian          decode_block(cm, xd, tile, mi_row, mi_col + hbs, r, subsize);
4325ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        break;
4335ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      case PARTITION_SPLIT:
434a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian        decode_partition(cm, xd, tile, mi_row,       mi_col,       r, subsize);
435a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian        decode_partition(cm, xd, tile, mi_row,       mi_col + hbs, r, subsize);
436a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian        decode_partition(cm, xd, tile, mi_row + hbs, mi_col,       r, subsize);
437a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian        decode_partition(cm, xd, tile, mi_row + hbs, mi_col + hbs, r, subsize);
4385ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        break;
4395ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      default:
440b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        assert(0 && "Invalid partition type");
4415ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
442ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
44391037db265ecdd914a26e056cf69207b4f50924ehkuang
444ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // update partition context
445f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  if (bsize >= BLOCK_8X8 &&
4465ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      (bsize == BLOCK_8X8 || partition != PARTITION_SPLIT))
4476ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    update_partition_context(xd, mi_row, mi_col, subsize, bsize);
448ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
449ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4505ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangstatic void setup_token_decoder(const uint8_t *data,
4515ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                const uint8_t *data_end,
4525ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                size_t read_size,
4535ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                struct vpx_internal_error_info *error_info,
454ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                vp9_reader *r) {
455ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Validate the calculated partition length. If the buffer
456ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // described by the partition can't be fully read, then restrict
457ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // it to the portion that can be (for EC mode) or throw an error.
458ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (!read_is_valid(data, read_size, data_end))
4595ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    vpx_internal_error(error_info, VPX_CODEC_CORRUPT_FRAME,
460ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                       "Truncated packet or corrupt tile length");
461ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
462ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (vp9_reader_init(r, data, read_size))
4635ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    vpx_internal_error(error_info, VPX_CODEC_MEM_ERROR,
464ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                       "Failed to allocate bool decoder %d", 1);
465ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
466ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
46791037db265ecdd914a26e056cf69207b4f50924ehkuangstatic void read_coef_probs_common(vp9_coeff_probs_model *coef_probs,
468ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                   vp9_reader *r) {
46991037db265ecdd914a26e056cf69207b4f50924ehkuang  int i, j, k, l, m;
470ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
47191037db265ecdd914a26e056cf69207b4f50924ehkuang  if (vp9_read_bit(r))
472b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    for (i = 0; i < PLANE_TYPES; ++i)
473b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      for (j = 0; j < REF_TYPES; ++j)
474b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        for (k = 0; k < COEF_BANDS; ++k)
475b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l)
476b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            for (m = 0; m < UNCONSTRAINED_NODES; ++m)
477b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian              vp9_diff_update_prob(r, &coef_probs[i][j][k][l][m]);
47891037db265ecdd914a26e056cf69207b4f50924ehkuang}
479ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
48091037db265ecdd914a26e056cf69207b4f50924ehkuangstatic void read_coef_probs(FRAME_CONTEXT *fc, TX_MODE tx_mode,
48191037db265ecdd914a26e056cf69207b4f50924ehkuang                            vp9_reader *r) {
4825ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    const TX_SIZE max_tx_size = tx_mode_to_biggest_tx_size[tx_mode];
4835ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    TX_SIZE tx_size;
4845ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    for (tx_size = TX_4X4; tx_size <= max_tx_size; ++tx_size)
4855ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      read_coef_probs_common(fc->coef_probs[tx_size], r);
486ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
487ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
48891037db265ecdd914a26e056cf69207b4f50924ehkuangstatic void setup_segmentation(struct segmentation *seg,
48991037db265ecdd914a26e056cf69207b4f50924ehkuang                               struct vp9_read_bit_buffer *rb) {
490ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int i, j;
491ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
49291037db265ecdd914a26e056cf69207b4f50924ehkuang  seg->update_map = 0;
49391037db265ecdd914a26e056cf69207b4f50924ehkuang  seg->update_data = 0;
494ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
49591037db265ecdd914a26e056cf69207b4f50924ehkuang  seg->enabled = vp9_rb_read_bit(rb);
49691037db265ecdd914a26e056cf69207b4f50924ehkuang  if (!seg->enabled)
497ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    return;
498ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
499ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Segmentation map update
50091037db265ecdd914a26e056cf69207b4f50924ehkuang  seg->update_map = vp9_rb_read_bit(rb);
50191037db265ecdd914a26e056cf69207b4f50924ehkuang  if (seg->update_map) {
50291037db265ecdd914a26e056cf69207b4f50924ehkuang    for (i = 0; i < SEG_TREE_PROBS; i++)
50391037db265ecdd914a26e056cf69207b4f50924ehkuang      seg->tree_probs[i] = vp9_rb_read_bit(rb) ? vp9_rb_read_literal(rb, 8)
50491037db265ecdd914a26e056cf69207b4f50924ehkuang                                               : MAX_PROB;
50591037db265ecdd914a26e056cf69207b4f50924ehkuang
50691037db265ecdd914a26e056cf69207b4f50924ehkuang    seg->temporal_update = vp9_rb_read_bit(rb);
50791037db265ecdd914a26e056cf69207b4f50924ehkuang    if (seg->temporal_update) {
508ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      for (i = 0; i < PREDICTION_PROBS; i++)
50991037db265ecdd914a26e056cf69207b4f50924ehkuang        seg->pred_probs[i] = vp9_rb_read_bit(rb) ? vp9_rb_read_literal(rb, 8)
51091037db265ecdd914a26e056cf69207b4f50924ehkuang                                                 : MAX_PROB;
511ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    } else {
512ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      for (i = 0; i < PREDICTION_PROBS; i++)
51391037db265ecdd914a26e056cf69207b4f50924ehkuang        seg->pred_probs[i] = MAX_PROB;
514ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
515ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
516ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
517ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Segmentation data update
51891037db265ecdd914a26e056cf69207b4f50924ehkuang  seg->update_data = vp9_rb_read_bit(rb);
51991037db265ecdd914a26e056cf69207b4f50924ehkuang  if (seg->update_data) {
52091037db265ecdd914a26e056cf69207b4f50924ehkuang    seg->abs_delta = vp9_rb_read_bit(rb);
521ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
52291037db265ecdd914a26e056cf69207b4f50924ehkuang    vp9_clearall_segfeatures(seg);
523ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
52491037db265ecdd914a26e056cf69207b4f50924ehkuang    for (i = 0; i < MAX_SEGMENTS; i++) {
525ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      for (j = 0; j < SEG_LVL_MAX; j++) {
526ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        int data = 0;
527ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        const int feature_enabled = vp9_rb_read_bit(rb);
528ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        if (feature_enabled) {
52991037db265ecdd914a26e056cf69207b4f50924ehkuang          vp9_enable_segfeature(seg, i, j);
530ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          data = decode_unsigned_max(rb, vp9_seg_feature_data_max(j));
531ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          if (vp9_is_segfeature_signed(j))
532ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            data = vp9_rb_read_bit(rb) ? -data : data;
533ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
53491037db265ecdd914a26e056cf69207b4f50924ehkuang        vp9_set_segdata(seg, i, j, data);
535ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
536ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
537ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
538ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
539ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
54091037db265ecdd914a26e056cf69207b4f50924ehkuangstatic void setup_loopfilter(struct loopfilter *lf,
54191037db265ecdd914a26e056cf69207b4f50924ehkuang                             struct vp9_read_bit_buffer *rb) {
54291037db265ecdd914a26e056cf69207b4f50924ehkuang  lf->filter_level = vp9_rb_read_literal(rb, 6);
54391037db265ecdd914a26e056cf69207b4f50924ehkuang  lf->sharpness_level = vp9_rb_read_literal(rb, 3);
544ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
545ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Read in loop filter deltas applied at the MB level based on mode or ref
546ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // frame.
54791037db265ecdd914a26e056cf69207b4f50924ehkuang  lf->mode_ref_delta_update = 0;
548ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
54991037db265ecdd914a26e056cf69207b4f50924ehkuang  lf->mode_ref_delta_enabled = vp9_rb_read_bit(rb);
55091037db265ecdd914a26e056cf69207b4f50924ehkuang  if (lf->mode_ref_delta_enabled) {
55191037db265ecdd914a26e056cf69207b4f50924ehkuang    lf->mode_ref_delta_update = vp9_rb_read_bit(rb);
55291037db265ecdd914a26e056cf69207b4f50924ehkuang    if (lf->mode_ref_delta_update) {
553ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      int i;
554ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
55591037db265ecdd914a26e056cf69207b4f50924ehkuang      for (i = 0; i < MAX_REF_LF_DELTAS; i++)
55691037db265ecdd914a26e056cf69207b4f50924ehkuang        if (vp9_rb_read_bit(rb))
55791037db265ecdd914a26e056cf69207b4f50924ehkuang          lf->ref_deltas[i] = vp9_rb_read_signed_literal(rb, 6);
558ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
55991037db265ecdd914a26e056cf69207b4f50924ehkuang      for (i = 0; i < MAX_MODE_LF_DELTAS; i++)
56091037db265ecdd914a26e056cf69207b4f50924ehkuang        if (vp9_rb_read_bit(rb))
56191037db265ecdd914a26e056cf69207b4f50924ehkuang          lf->mode_deltas[i] = vp9_rb_read_signed_literal(rb, 6);
562ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
563ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
564ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
565ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
566ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic int read_delta_q(struct vp9_read_bit_buffer *rb, int *delta_q) {
567ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int old = *delta_q;
5681184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  *delta_q = vp9_rb_read_bit(rb) ? vp9_rb_read_signed_literal(rb, 4) : 0;
569ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return old != *delta_q;
570ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
571ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
5725ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangstatic void setup_quantization(VP9_COMMON *const cm, MACROBLOCKD *const xd,
5735ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                               struct vp9_read_bit_buffer *rb) {
574ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int update = 0;
575ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
576ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  cm->base_qindex = vp9_rb_read_literal(rb, QINDEX_BITS);
577ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  update |= read_delta_q(rb, &cm->y_dc_delta_q);
578ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  update |= read_delta_q(rb, &cm->uv_dc_delta_q);
579ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  update |= read_delta_q(rb, &cm->uv_ac_delta_q);
580ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (update)
581ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vp9_init_dequantizer(cm);
582ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
583ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  xd->lossless = cm->base_qindex == 0 &&
584ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                 cm->y_dc_delta_q == 0 &&
585ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                 cm->uv_dc_delta_q == 0 &&
586ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                 cm->uv_ac_delta_q == 0;
58791037db265ecdd914a26e056cf69207b4f50924ehkuang
5885ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  xd->itxm_add = xd->lossless ? vp9_iwht4x4_add : vp9_idct4x4_add;
589ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
590ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
591b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic INTERP_FILTER read_interp_filter(struct vp9_read_bit_buffer *rb) {
592b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const INTERP_FILTER literal_to_filter[] = { EIGHTTAP_SMOOTH,
593b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                              EIGHTTAP,
594b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                              EIGHTTAP_SHARP,
595b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                              BILINEAR };
596ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return vp9_rb_read_bit(rb) ? SWITCHABLE
597b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                             : literal_to_filter[vp9_rb_read_literal(rb, 2)];
598ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
599ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
600f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuangstatic void read_frame_size(struct vp9_read_bit_buffer *rb,
601ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                            int *width, int *height) {
602ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int w = vp9_rb_read_literal(rb, 16) + 1;
603ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int h = vp9_rb_read_literal(rb, 16) + 1;
604ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  *width = w;
605ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  *height = h;
606ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
607ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
608f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuangstatic void setup_display_size(VP9_COMMON *cm, struct vp9_read_bit_buffer *rb) {
609ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  cm->display_width = cm->width;
610ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  cm->display_height = cm->height;
611ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (vp9_rb_read_bit(rb))
612f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    read_frame_size(rb, &cm->display_width, &cm->display_height);
613ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
614ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
6156ac915abcdb404a00d927fe6308a47fcf09d9519hkuangstatic void apply_frame_size(VP9_COMMON *cm, int width, int height) {
616ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (cm->width != width || cm->height != height) {
6179b35249446b07f40ac5fcc3205f2c048616efacchkuang    // Change in frame size.
6189b35249446b07f40ac5fcc3205f2c048616efacchkuang    // TODO(agrange) Don't test width/height, check overall size.
6199b35249446b07f40ac5fcc3205f2c048616efacchkuang    if (width > cm->width || height > cm->height) {
6209b35249446b07f40ac5fcc3205f2c048616efacchkuang      // Rescale frame buffers only if they're not big enough already.
6219b35249446b07f40ac5fcc3205f2c048616efacchkuang      if (vp9_resize_frame_buffers(cm, width, height))
622ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
623ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                           "Failed to allocate frame buffers");
624ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
625ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
626ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    cm->width = width;
627ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    cm->height = height;
628ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
629ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vp9_update_frame_size(cm);
630ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
631ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
632b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (vp9_realloc_frame_buffer(
633b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          get_frame_new_buffer(cm), cm->width, cm->height,
634b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          cm->subsampling_x, cm->subsampling_y, VP9_DEC_BORDER_IN_PIXELS,
635b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          &cm->frame_bufs[cm->new_fb_idx].raw_frame_buffer, cm->get_fb_cb,
636b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          cm->cb_priv)) {
637b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
638b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                       "Failed to allocate frame buffer");
639b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  }
640ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
641ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
6426ac915abcdb404a00d927fe6308a47fcf09d9519hkuangstatic void setup_frame_size(VP9_COMMON *cm, struct vp9_read_bit_buffer *rb) {
643ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int width, height;
644f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  read_frame_size(rb, &width, &height);
6456ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  apply_frame_size(cm, width, height);
6466ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  setup_display_size(cm, rb);
647ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
648ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
6496ac915abcdb404a00d927fe6308a47fcf09d9519hkuangstatic void setup_frame_size_with_refs(VP9_COMMON *cm,
650ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                       struct vp9_read_bit_buffer *rb) {
651ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int width, height;
652ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int found = 0, i;
653b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  for (i = 0; i < REFS_PER_FRAME; ++i) {
654ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (vp9_rb_read_bit(rb)) {
655b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      YV12_BUFFER_CONFIG *const buf = cm->frame_refs[i].buf;
656b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      width = buf->y_crop_width;
657b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      height = buf->y_crop_height;
658ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      found = 1;
659ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      break;
660ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
661ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
662ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
663ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (!found)
664f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    read_frame_size(rb, &width, &height);
665ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
666b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (width <= 0 || height <= 0)
667ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME,
668ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                       "Referenced frame with invalid size");
669ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
6706ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  apply_frame_size(cm, width, height);
6711184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  setup_display_size(cm, rb);
672ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
673ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
6746ac915abcdb404a00d927fe6308a47fcf09d9519hkuangstatic void decode_tile(VP9Decoder *pbi, const TileInfo *const tile,
6755ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                        vp9_reader *r) {
676f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  const int num_threads = pbi->oxcf.max_threads;
6771184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  VP9_COMMON *const cm = &pbi->common;
678ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int mi_row, mi_col;
6795ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MACROBLOCKD *xd = &pbi->mb;
680ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
68191037db265ecdd914a26e056cf69207b4f50924ehkuang  if (pbi->do_loopfilter_inline) {
6825ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    LFWorkerData *const lf_data = (LFWorkerData*)pbi->lf_worker.data1;
6835ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    lf_data->frame_buffer = get_frame_new_buffer(cm);
6845ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    lf_data->cm = cm;
6855ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    lf_data->xd = pbi->mb;
6865ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    lf_data->stop = 0;
6875ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    lf_data->y_only = 0;
6881184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    vp9_loop_filter_frame_init(cm, cm->lf.filter_level);
68991037db265ecdd914a26e056cf69207b4f50924ehkuang  }
69091037db265ecdd914a26e056cf69207b4f50924ehkuang
6915ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  for (mi_row = tile->mi_row_start; mi_row < tile->mi_row_end;
69291037db265ecdd914a26e056cf69207b4f50924ehkuang       mi_row += MI_BLOCK_SIZE) {
693ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // For a SB there are 2 left contexts, each pertaining to a MB row within
6945ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    vp9_zero(xd->left_context);
6955ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    vp9_zero(xd->left_seg_context);
6965ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    for (mi_col = tile->mi_col_start; mi_col < tile->mi_col_end;
6979b35249446b07f40ac5fcc3205f2c048616efacchkuang         mi_col += MI_BLOCK_SIZE) {
698a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian      decode_partition(cm, xd, tile, mi_row, mi_col, r, BLOCK_64X64);
6999b35249446b07f40ac5fcc3205f2c048616efacchkuang    }
70091037db265ecdd914a26e056cf69207b4f50924ehkuang
70191037db265ecdd914a26e056cf69207b4f50924ehkuang    if (pbi->do_loopfilter_inline) {
70291037db265ecdd914a26e056cf69207b4f50924ehkuang      const int lf_start = mi_row - MI_BLOCK_SIZE;
7035ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      LFWorkerData *const lf_data = (LFWorkerData*)pbi->lf_worker.data1;
704f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
7055ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      // delay the loopfilter by 1 macroblock row.
7065ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (lf_start < 0) continue;
707f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
7085ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      // decoding has completed: finish up the loop filter in this thread.
7095ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (mi_row + MI_BLOCK_SIZE >= tile->mi_row_end) continue;
7101184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
7115ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      vp9_worker_sync(&pbi->lf_worker);
7125ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      lf_data->start = lf_start;
7135ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      lf_data->stop = mi_row;
7145ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (num_threads > 1) {
715f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        vp9_worker_launch(&pbi->lf_worker);
716f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      } else {
7175ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        vp9_worker_execute(&pbi->lf_worker);
718f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      }
71991037db265ecdd914a26e056cf69207b4f50924ehkuang    }
72091037db265ecdd914a26e056cf69207b4f50924ehkuang  }
72191037db265ecdd914a26e056cf69207b4f50924ehkuang
72291037db265ecdd914a26e056cf69207b4f50924ehkuang  if (pbi->do_loopfilter_inline) {
7235ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    LFWorkerData *const lf_data = (LFWorkerData*)pbi->lf_worker.data1;
7241184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
7255ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    vp9_worker_sync(&pbi->lf_worker);
7265ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    lf_data->start = lf_data->stop;
7275ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    lf_data->stop = cm->mi_rows;
7285ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    vp9_worker_execute(&pbi->lf_worker);
729ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
730ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
731ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
732ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void setup_tile_info(VP9_COMMON *cm, struct vp9_read_bit_buffer *rb) {
73391037db265ecdd914a26e056cf69207b4f50924ehkuang  int min_log2_tile_cols, max_log2_tile_cols, max_ones;
73491037db265ecdd914a26e056cf69207b4f50924ehkuang  vp9_get_tile_n_bits(cm->mi_cols, &min_log2_tile_cols, &max_log2_tile_cols);
735ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
73691037db265ecdd914a26e056cf69207b4f50924ehkuang  // columns
73791037db265ecdd914a26e056cf69207b4f50924ehkuang  max_ones = max_log2_tile_cols - min_log2_tile_cols;
73891037db265ecdd914a26e056cf69207b4f50924ehkuang  cm->log2_tile_cols = min_log2_tile_cols;
73991037db265ecdd914a26e056cf69207b4f50924ehkuang  while (max_ones-- && vp9_rb_read_bit(rb))
74091037db265ecdd914a26e056cf69207b4f50924ehkuang    cm->log2_tile_cols++;
741ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
74291037db265ecdd914a26e056cf69207b4f50924ehkuang  // rows
743ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  cm->log2_tile_rows = vp9_rb_read_bit(rb);
744ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (cm->log2_tile_rows)
745ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    cm->log2_tile_rows += vp9_rb_read_bit(rb);
746ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
747ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
7485ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang// Reads the next tile returning its size and adjusting '*data' accordingly
7495ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang// based on 'is_last'.
7505ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangstatic size_t get_tile(const uint8_t *const data_end,
7515ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                       int is_last,
7525ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                       struct vpx_internal_error_info *error_info,
7535ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                       const uint8_t **data) {
7545ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  size_t size;
7555ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
7565ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (!is_last) {
7575ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (!read_is_valid(*data, 4, data_end))
7585ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      vpx_internal_error(error_info, VPX_CODEC_CORRUPT_FRAME,
759b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                         "Truncated packet or corrupt tile length");
7605ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
761b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    size = mem_get_be32(*data);
7625ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    *data += 4;
763b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
764b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (size > (size_t)(data_end - *data))
765b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      vpx_internal_error(error_info, VPX_CODEC_CORRUPT_FRAME,
766b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                         "Truncated packet or corrupt tile size");
7675ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  } else {
7685ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    size = data_end - *data;
7695ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
7705ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  return size;
7715ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang}
7725ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
7739b35249446b07f40ac5fcc3205f2c048616efacchkuangtypedef struct TileBuffer {
7749b35249446b07f40ac5fcc3205f2c048616efacchkuang  const uint8_t *data;
7759b35249446b07f40ac5fcc3205f2c048616efacchkuang  size_t size;
776b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int col;  // only used with multi-threaded decoding
7779b35249446b07f40ac5fcc3205f2c048616efacchkuang} TileBuffer;
77891037db265ecdd914a26e056cf69207b4f50924ehkuang
7796ac915abcdb404a00d927fe6308a47fcf09d9519hkuangstatic const uint8_t *decode_tiles(VP9Decoder *pbi,
7806ac915abcdb404a00d927fe6308a47fcf09d9519hkuang                                   const uint8_t *data,
7816ac915abcdb404a00d927fe6308a47fcf09d9519hkuang                                   const uint8_t *data_end) {
7821184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  VP9_COMMON *const cm = &pbi->common;
7839b35249446b07f40ac5fcc3205f2c048616efacchkuang  const int aligned_cols = mi_cols_aligned_to_sb(cm->mi_cols);
7841184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const int tile_cols = 1 << cm->log2_tile_cols;
7851184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const int tile_rows = 1 << cm->log2_tile_rows;
7869b35249446b07f40ac5fcc3205f2c048616efacchkuang  TileBuffer tile_buffers[4][1 << 6];
787ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int tile_row, tile_col;
7889b35249446b07f40ac5fcc3205f2c048616efacchkuang  const uint8_t *end = NULL;
7899b35249446b07f40ac5fcc3205f2c048616efacchkuang  vp9_reader r;
7909b35249446b07f40ac5fcc3205f2c048616efacchkuang
7919b35249446b07f40ac5fcc3205f2c048616efacchkuang  assert(tile_rows <= 4);
7929b35249446b07f40ac5fcc3205f2c048616efacchkuang  assert(tile_cols <= (1 << 6));
793ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
794ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Note: this memset assumes above_context[0], [1] and [2]
795ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // are allocated as part of the same buffer.
7966ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  vpx_memset(cm->above_context, 0,
7976ac915abcdb404a00d927fe6308a47fcf09d9519hkuang             sizeof(*cm->above_context) * MAX_MB_PLANE * 2 * aligned_cols);
798ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
7996ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  vpx_memset(cm->above_seg_context, 0,
8006ac915abcdb404a00d927fe6308a47fcf09d9519hkuang             sizeof(*cm->above_seg_context) * aligned_cols);
8019b35249446b07f40ac5fcc3205f2c048616efacchkuang
8029b35249446b07f40ac5fcc3205f2c048616efacchkuang  // Load tile data into tile_buffers
8039b35249446b07f40ac5fcc3205f2c048616efacchkuang  for (tile_row = 0; tile_row < tile_rows; ++tile_row) {
8049b35249446b07f40ac5fcc3205f2c048616efacchkuang    for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
8059b35249446b07f40ac5fcc3205f2c048616efacchkuang      const int last_tile = tile_row == tile_rows - 1 &&
8069b35249446b07f40ac5fcc3205f2c048616efacchkuang                            tile_col == tile_cols - 1;
8079b35249446b07f40ac5fcc3205f2c048616efacchkuang      const size_t size = get_tile(data_end, last_tile, &cm->error, &data);
8089b35249446b07f40ac5fcc3205f2c048616efacchkuang      TileBuffer *const buf = &tile_buffers[tile_row][tile_col];
8099b35249446b07f40ac5fcc3205f2c048616efacchkuang      buf->data = data;
8109b35249446b07f40ac5fcc3205f2c048616efacchkuang      buf->size = size;
8119b35249446b07f40ac5fcc3205f2c048616efacchkuang      data += size;
812ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
8139b35249446b07f40ac5fcc3205f2c048616efacchkuang  }
814ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
8159b35249446b07f40ac5fcc3205f2c048616efacchkuang  // Decode tiles using data from tile_buffers
8169b35249446b07f40ac5fcc3205f2c048616efacchkuang  for (tile_row = 0; tile_row < tile_rows; ++tile_row) {
8179b35249446b07f40ac5fcc3205f2c048616efacchkuang    for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
8189b35249446b07f40ac5fcc3205f2c048616efacchkuang      const int col = pbi->oxcf.inv_tile_order ? tile_cols - tile_col - 1
8199b35249446b07f40ac5fcc3205f2c048616efacchkuang                                               : tile_col;
8209b35249446b07f40ac5fcc3205f2c048616efacchkuang      const int last_tile = tile_row == tile_rows - 1 &&
8219b35249446b07f40ac5fcc3205f2c048616efacchkuang                                 col == tile_cols - 1;
8229b35249446b07f40ac5fcc3205f2c048616efacchkuang      const TileBuffer *const buf = &tile_buffers[tile_row][col];
8239b35249446b07f40ac5fcc3205f2c048616efacchkuang      TileInfo tile;
8249b35249446b07f40ac5fcc3205f2c048616efacchkuang
8259b35249446b07f40ac5fcc3205f2c048616efacchkuang      vp9_tile_init(&tile, cm, tile_row, col);
8269b35249446b07f40ac5fcc3205f2c048616efacchkuang      setup_token_decoder(buf->data, data_end, buf->size, &cm->error, &r);
8279b35249446b07f40ac5fcc3205f2c048616efacchkuang      decode_tile(pbi, &tile, &r);
8289b35249446b07f40ac5fcc3205f2c048616efacchkuang
8299b35249446b07f40ac5fcc3205f2c048616efacchkuang      if (last_tile)
8309b35249446b07f40ac5fcc3205f2c048616efacchkuang        end = vp9_reader_find_end(&r);
831ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
832ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
83391037db265ecdd914a26e056cf69207b4f50924ehkuang
8349b35249446b07f40ac5fcc3205f2c048616efacchkuang  return end;
8359b35249446b07f40ac5fcc3205f2c048616efacchkuang}
8369b35249446b07f40ac5fcc3205f2c048616efacchkuang
8375ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangstatic int tile_worker_hook(void *arg1, void *arg2) {
8389b35249446b07f40ac5fcc3205f2c048616efacchkuang  TileWorkerData *const tile_data = (TileWorkerData*)arg1;
8395ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const TileInfo *const tile = (TileInfo*)arg2;
8405ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int mi_row, mi_col;
8415ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
8425ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  for (mi_row = tile->mi_row_start; mi_row < tile->mi_row_end;
8435ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang       mi_row += MI_BLOCK_SIZE) {
8445ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    vp9_zero(tile_data->xd.left_context);
8455ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    vp9_zero(tile_data->xd.left_seg_context);
8465ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    for (mi_col = tile->mi_col_start; mi_col < tile->mi_col_end;
8475ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang         mi_col += MI_BLOCK_SIZE) {
848a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian      decode_partition(tile_data->cm, &tile_data->xd, tile,
849a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian                       mi_row, mi_col, &tile_data->bit_reader, BLOCK_64X64);
8505ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
8515ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
8525ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  return !tile_data->xd.corrupted;
8535ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang}
8545ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
855b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian// sorts in descending order
856b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic int compare_tile_buffers(const void *a, const void *b) {
857b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const TileBuffer *const buf1 = (const TileBuffer*)a;
858b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const TileBuffer *const buf2 = (const TileBuffer*)b;
859b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (buf1->size < buf2->size) {
860b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    return 1;
861b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  } else if (buf1->size == buf2->size) {
862b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    return 0;
863b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  } else {
864b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    return -1;
865b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  }
866b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian}
867b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
8686ac915abcdb404a00d927fe6308a47fcf09d9519hkuangstatic const uint8_t *decode_tiles_mt(VP9Decoder *pbi,
8696ac915abcdb404a00d927fe6308a47fcf09d9519hkuang                                      const uint8_t *data,
8706ac915abcdb404a00d927fe6308a47fcf09d9519hkuang                                      const uint8_t *data_end) {
8715ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  VP9_COMMON *const cm = &pbi->common;
872b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const uint8_t *bit_reader_end = NULL;
8735ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const int aligned_mi_cols = mi_cols_aligned_to_sb(cm->mi_cols);
8745ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const int tile_cols = 1 << cm->log2_tile_cols;
8755ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const int tile_rows = 1 << cm->log2_tile_rows;
8765ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const int num_workers = MIN(pbi->oxcf.max_threads & ~1, tile_cols);
877b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  TileBuffer tile_buffers[1 << 6];
878b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int n;
879b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int final_worker = -1;
8805ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
881b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  assert(tile_cols <= (1 << 6));
8825ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  assert(tile_rows == 1);
8835ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  (void)tile_rows;
8845ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
8856ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  // TODO(jzern): See if we can remove the restriction of passing in max
8866ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  // threads to the decoder.
8876ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  if (pbi->num_tile_workers == 0) {
8886ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    const int num_threads = pbi->oxcf.max_threads & ~1;
8895ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    int i;
8906ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    // TODO(jzern): Allocate one less worker, as in the current code we only
8916ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    // use num_threads - 1 workers.
8925ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    CHECK_MEM_ERROR(cm, pbi->tile_workers,
8936ac915abcdb404a00d927fe6308a47fcf09d9519hkuang                    vpx_malloc(num_threads * sizeof(*pbi->tile_workers)));
8946ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    for (i = 0; i < num_threads; ++i) {
8955ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      VP9Worker *const worker = &pbi->tile_workers[i];
8965ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      ++pbi->num_tile_workers;
8975ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
8985ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      vp9_worker_init(worker);
8995ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      CHECK_MEM_ERROR(cm, worker->data1,
9005ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                      vpx_memalign(32, sizeof(TileWorkerData)));
9015ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      CHECK_MEM_ERROR(cm, worker->data2, vpx_malloc(sizeof(TileInfo)));
9026ac915abcdb404a00d927fe6308a47fcf09d9519hkuang      if (i < num_threads - 1 && !vp9_worker_reset(worker)) {
9035ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        vpx_internal_error(&cm->error, VPX_CODEC_ERROR,
9045ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                           "Tile decoder thread creation failed");
9055ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      }
9065ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
9075ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
9085ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
909b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  // Reset tile decoding hook
9106ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  for (n = 0; n < num_workers; ++n) {
911b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    pbi->tile_workers[n].hook = (VP9WorkerHook)tile_worker_hook;
912b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  }
913b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
9145ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // Note: this memset assumes above_context[0], [1] and [2]
9155ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // are allocated as part of the same buffer.
9166ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  vpx_memset(cm->above_context, 0,
9176ac915abcdb404a00d927fe6308a47fcf09d9519hkuang             sizeof(*cm->above_context) * MAX_MB_PLANE * 2 * aligned_mi_cols);
9186ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  vpx_memset(cm->above_seg_context, 0,
9196ac915abcdb404a00d927fe6308a47fcf09d9519hkuang             sizeof(*cm->above_seg_context) * aligned_mi_cols);
9205ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
921b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  // Load tile data into tile_buffers
922b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  for (n = 0; n < tile_cols; ++n) {
923b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    const size_t size =
924b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        get_tile(data_end, n == tile_cols - 1, &cm->error, &data);
925b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    TileBuffer *const buf = &tile_buffers[n];
926b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    buf->data = data;
927b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    buf->size = size;
928b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    buf->col = n;
929b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    data += size;
930b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  }
931b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
932b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  // Sort the buffers based on size in descending order.
933b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  qsort(tile_buffers, tile_cols, sizeof(tile_buffers[0]), compare_tile_buffers);
934b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
935b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  // Rearrange the tile buffers such that per-tile group the largest, and
936b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  // presumably the most difficult, tile will be decoded in the main thread.
937b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  // This should help minimize the number of instances where the main thread is
938b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  // waiting for a worker to complete.
939b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {
940b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    int group_start = 0;
941b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    while (group_start < tile_cols) {
942b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      const TileBuffer largest = tile_buffers[group_start];
943b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      const int group_end = MIN(group_start + num_workers, tile_cols) - 1;
944b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      memmove(tile_buffers + group_start, tile_buffers + group_start + 1,
945b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian              (group_end - group_start) * sizeof(tile_buffers[0]));
946b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      tile_buffers[group_end] = largest;
947b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      group_start = group_end + 1;
948b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    }
949b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  }
950b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
951b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  n = 0;
952b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  while (n < tile_cols) {
9535ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    int i;
954b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    for (i = 0; i < num_workers && n < tile_cols; ++i) {
9555ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      VP9Worker *const worker = &pbi->tile_workers[i];
9565ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      TileWorkerData *const tile_data = (TileWorkerData*)worker->data1;
9575ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      TileInfo *const tile = (TileInfo*)worker->data2;
958b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      TileBuffer *const buf = &tile_buffers[n];
9595ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
9605ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      tile_data->cm = cm;
9615ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      tile_data->xd = pbi->mb;
9625ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      tile_data->xd.corrupted = 0;
963b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      vp9_tile_init(tile, tile_data->cm, 0, buf->col);
964b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      setup_token_decoder(buf->data, data_end, buf->size, &cm->error,
9655ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                          &tile_data->bit_reader);
9666ac915abcdb404a00d927fe6308a47fcf09d9519hkuang      init_macroblockd(cm, &tile_data->xd);
9676ac915abcdb404a00d927fe6308a47fcf09d9519hkuang      vp9_zero(tile_data->xd.dqcoeff);
9685ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
9695ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      worker->had_error = 0;
970b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (i == num_workers - 1 || n == tile_cols - 1) {
9715ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        vp9_worker_execute(worker);
9725ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      } else {
9735ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        vp9_worker_launch(worker);
9745ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      }
9755ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
976b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (buf->col == tile_cols - 1) {
977b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        final_worker = i;
978b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      }
979b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
980b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      ++n;
9815ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
9825ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
9835ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    for (; i > 0; --i) {
9845ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      VP9Worker *const worker = &pbi->tile_workers[i - 1];
9855ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      pbi->mb.corrupted |= !vp9_worker_sync(worker);
9865ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
987b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (final_worker > -1) {
988b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      TileWorkerData *const tile_data =
989b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          (TileWorkerData*)pbi->tile_workers[final_worker].data1;
990b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      bit_reader_end = vp9_reader_find_end(&tile_data->bit_reader);
991b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      final_worker = -1;
992b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    }
9935ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
9945ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
995b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  return bit_reader_end;
9965ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang}
9975ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
998ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void check_sync_code(VP9_COMMON *cm, struct vp9_read_bit_buffer *rb) {
9995ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (vp9_rb_read_literal(rb, 8) != VP9_SYNC_CODE_0 ||
10005ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      vp9_rb_read_literal(rb, 8) != VP9_SYNC_CODE_1 ||
10015ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      vp9_rb_read_literal(rb, 8) != VP9_SYNC_CODE_2) {
1002ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
1003ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                       "Invalid frame sync code");
1004ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
1005ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
1006ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1007b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic void error_handler(void *data) {
1008ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  VP9_COMMON *const cm = (VP9_COMMON *)data;
1009ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, "Truncated packet");
1010ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
1011ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
10126ac915abcdb404a00d927fe6308a47fcf09d9519hkuangstatic BITSTREAM_PROFILE read_profile(struct vp9_read_bit_buffer *rb) {
10136ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  int profile = vp9_rb_read_bit(rb);
10146ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  profile |= vp9_rb_read_bit(rb) << 1;
10156ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  return (BITSTREAM_PROFILE) profile;
10166ac915abcdb404a00d927fe6308a47fcf09d9519hkuang}
1017ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
10186ac915abcdb404a00d927fe6308a47fcf09d9519hkuangstatic size_t read_uncompressed_header(VP9Decoder *pbi,
1019ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                       struct vp9_read_bit_buffer *rb) {
1020ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  VP9_COMMON *const cm = &pbi->common;
10215ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  size_t sz;
1022ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int i;
1023ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1024ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  cm->last_frame_type = cm->frame_type;
1025ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
10265ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (vp9_rb_read_literal(rb, 2) != VP9_FRAME_MARKER)
1027ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
1028ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                         "Invalid frame marker");
1029ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
10306ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  cm->profile = read_profile(rb);
10316ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  if (cm->profile >= MAX_PROFILES)
10326ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
10336ac915abcdb404a00d927fe6308a47fcf09d9519hkuang                       "Unsupported bitstream profile");
1034ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1035b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  cm->show_existing_frame = vp9_rb_read_bit(rb);
1036b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (cm->show_existing_frame) {
1037b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    // Show an existing frame directly.
1038b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    const int frame_to_show = cm->ref_frame_map[vp9_rb_read_literal(rb, 3)];
1039b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
1040b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (cm->frame_bufs[frame_to_show].ref_count < 1)
1041b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
1042b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                         "Buffer %d does not contain a decoded frame",
1043b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                         frame_to_show);
1044b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
1045b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    ref_cnt_fb(cm->frame_bufs, &cm->new_fb_idx, frame_to_show);
1046ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    pbi->refresh_frame_flags = 0;
10471184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    cm->lf.filter_level = 0;
1048b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    cm->show_frame = 1;
1049ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    return 0;
1050ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
1051ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1052ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  cm->frame_type = (FRAME_TYPE) vp9_rb_read_bit(rb);
1053ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  cm->show_frame = vp9_rb_read_bit(rb);
1054ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  cm->error_resilient_mode = vp9_rb_read_bit(rb);
1055ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1056ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (cm->frame_type == KEY_FRAME) {
1057ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    check_sync_code(cm, rb);
10586ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    if (cm->profile > PROFILE_1)
10596ac915abcdb404a00d927fe6308a47fcf09d9519hkuang      cm->bit_depth = vp9_rb_read_bit(rb) ? BITS_12 : BITS_10;
10606ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    cm->color_space = (COLOR_SPACE)vp9_rb_read_literal(rb, 3);
10615ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (cm->color_space != SRGB) {
1062ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      vp9_rb_read_bit(rb);  // [16,235] (including xvycc) vs [0,255] range
10636ac915abcdb404a00d927fe6308a47fcf09d9519hkuang      if (cm->profile >= PROFILE_1) {
1064ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        cm->subsampling_x = vp9_rb_read_bit(rb);
1065ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        cm->subsampling_y = vp9_rb_read_bit(rb);
1066ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        vp9_rb_read_bit(rb);  // has extra plane
1067ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      } else {
1068ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        cm->subsampling_y = cm->subsampling_x = 1;
1069ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
1070ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    } else {
10716ac915abcdb404a00d927fe6308a47fcf09d9519hkuang      if (cm->profile >= PROFILE_1) {
1072ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        cm->subsampling_y = cm->subsampling_x = 0;
1073ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        vp9_rb_read_bit(rb);  // has extra plane
1074ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      } else {
1075ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
1076ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                           "RGB not supported in profile 0");
1077ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
1078ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
1079ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1080b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    pbi->refresh_frame_flags = (1 << REF_FRAMES) - 1;
1081ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1082b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    for (i = 0; i < REFS_PER_FRAME; ++i) {
1083b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      cm->frame_refs[i].idx = cm->new_fb_idx;
1084b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      cm->frame_refs[i].buf = get_frame_new_buffer(cm);
1085b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    }
1086ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
10876ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    setup_frame_size(cm, rb);
1088ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  } else {
1089ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    cm->intra_only = cm->show_frame ? 0 : vp9_rb_read_bit(rb);
1090ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1091ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    cm->reset_frame_context = cm->error_resilient_mode ?
1092ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        0 : vp9_rb_read_literal(rb, 2);
1093ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1094ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (cm->intra_only) {
1095ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      check_sync_code(cm, rb);
1096ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1097b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      pbi->refresh_frame_flags = vp9_rb_read_literal(rb, REF_FRAMES);
10986ac915abcdb404a00d927fe6308a47fcf09d9519hkuang      setup_frame_size(cm, rb);
1099ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    } else {
1100b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      pbi->refresh_frame_flags = vp9_rb_read_literal(rb, REF_FRAMES);
1101ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1102b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      for (i = 0; i < REFS_PER_FRAME; ++i) {
1103b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        const int ref = vp9_rb_read_literal(rb, REF_FRAMES_LOG2);
1104b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        const int idx = cm->ref_frame_map[ref];
1105b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        cm->frame_refs[i].idx = idx;
1106b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        cm->frame_refs[i].buf = &cm->frame_bufs[idx].buf;
1107ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        cm->ref_frame_sign_bias[LAST_FRAME + i] = vp9_rb_read_bit(rb);
1108ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
1109ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
11106ac915abcdb404a00d927fe6308a47fcf09d9519hkuang      setup_frame_size_with_refs(cm, rb);
1111ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
11125ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      cm->allow_high_precision_mv = vp9_rb_read_bit(rb);
1113b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      cm->interp_filter = read_interp_filter(rb);
1114b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
1115b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      for (i = 0; i < REFS_PER_FRAME; ++i) {
1116b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        RefBuffer *const ref_buf = &cm->frame_refs[i];
1117b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        vp9_setup_scale_factors_for_frame(&ref_buf->sf,
1118b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                          ref_buf->buf->y_crop_width,
1119b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                          ref_buf->buf->y_crop_height,
1120b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                          cm->width, cm->height);
1121b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        if (vp9_is_scaled(&ref_buf->sf))
1122b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          vp9_extend_frame_borders(ref_buf->buf);
1123b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      }
1124ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
1125ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
1126ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1127ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (!cm->error_resilient_mode) {
1128b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    cm->coding_use_prev_mi = 1;
1129ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    cm->refresh_frame_context = vp9_rb_read_bit(rb);
1130ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    cm->frame_parallel_decoding_mode = vp9_rb_read_bit(rb);
1131ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  } else {
1132b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    cm->coding_use_prev_mi = 0;
1133ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    cm->refresh_frame_context = 0;
1134ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    cm->frame_parallel_decoding_mode = 1;
1135ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
1136ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
11375ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // This flag will be overridden by the call to vp9_setup_past_independence
11385ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // below, forcing the use of context 0 for those frame types.
1139b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  cm->frame_context_idx = vp9_rb_read_literal(rb, FRAME_CONTEXTS_LOG2);
1140ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
11415ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (frame_is_intra_only(cm) || cm->error_resilient_mode)
11421184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    vp9_setup_past_independence(cm);
1143ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
11441184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  setup_loopfilter(&cm->lf, rb);
11455ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  setup_quantization(cm, &pbi->mb, rb);
11461184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  setup_segmentation(&cm->seg, rb);
1147ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1148ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  setup_tile_info(cm, rb);
11495ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  sz = vp9_rb_read_literal(rb, 16);
11505ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
11515ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (sz == 0)
11525ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME,
11535ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                       "Invalid header size");
1154ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
11555ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  return sz;
1156ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
1157ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
11586ac915abcdb404a00d927fe6308a47fcf09d9519hkuangstatic int read_compressed_header(VP9Decoder *pbi, const uint8_t *data,
115991037db265ecdd914a26e056cf69207b4f50924ehkuang                                  size_t partition_size) {
116091037db265ecdd914a26e056cf69207b4f50924ehkuang  VP9_COMMON *const cm = &pbi->common;
116191037db265ecdd914a26e056cf69207b4f50924ehkuang  MACROBLOCKD *const xd = &pbi->mb;
11625ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  FRAME_CONTEXT *const fc = &cm->fc;
116391037db265ecdd914a26e056cf69207b4f50924ehkuang  vp9_reader r;
11645ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int k;
116591037db265ecdd914a26e056cf69207b4f50924ehkuang
116691037db265ecdd914a26e056cf69207b4f50924ehkuang  if (vp9_reader_init(&r, data, partition_size))
116791037db265ecdd914a26e056cf69207b4f50924ehkuang    vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
116891037db265ecdd914a26e056cf69207b4f50924ehkuang                       "Failed to allocate bool decoder 0");
116991037db265ecdd914a26e056cf69207b4f50924ehkuang
117091037db265ecdd914a26e056cf69207b4f50924ehkuang  cm->tx_mode = xd->lossless ? ONLY_4X4 : read_tx_mode(&r);
117191037db265ecdd914a26e056cf69207b4f50924ehkuang  if (cm->tx_mode == TX_MODE_SELECT)
1172b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    read_tx_mode_probs(&fc->tx_probs, &r);
11735ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  read_coef_probs(fc, cm->tx_mode, &r);
11745ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
1175b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  for (k = 0; k < SKIP_CONTEXTS; ++k)
1176b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    vp9_diff_update_prob(&r, &fc->skip_probs[k]);
11775ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
11785ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (!frame_is_intra_only(cm)) {
11795ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    nmv_context *const nmvc = &fc->nmvc;
11805ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    int i, j;
11815ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
11825ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    read_inter_mode_probs(fc, &r);
11835ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
1184b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (cm->interp_filter == SWITCHABLE)
11855ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      read_switchable_interp_probs(fc, &r);
11865ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
11875ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    for (i = 0; i < INTRA_INTER_CONTEXTS; i++)
11885ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      vp9_diff_update_prob(&r, &fc->intra_inter_prob[i]);
11895ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
1190b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    cm->reference_mode = read_frame_reference_mode(cm, &r);
1191b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (cm->reference_mode != SINGLE_REFERENCE)
1192b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      setup_compound_reference_mode(cm);
1193b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    read_frame_reference_mode_probs(cm, &r);
11945ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
11955ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    for (j = 0; j < BLOCK_SIZE_GROUPS; j++)
11965ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      for (i = 0; i < INTRA_MODES - 1; ++i)
11975ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        vp9_diff_update_prob(&r, &fc->y_mode_prob[j][i]);
11985ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
11995ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    for (j = 0; j < PARTITION_CONTEXTS; ++j)
12005ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      for (i = 0; i < PARTITION_TYPES - 1; ++i)
12015ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        vp9_diff_update_prob(&r, &fc->partition_prob[j][i]);
120291037db265ecdd914a26e056cf69207b4f50924ehkuang
12039b35249446b07f40ac5fcc3205f2c048616efacchkuang    read_mv_probs(nmvc, cm->allow_high_precision_mv, &r);
12045ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
120591037db265ecdd914a26e056cf69207b4f50924ehkuang
120691037db265ecdd914a26e056cf69207b4f50924ehkuang  return vp9_reader_has_error(&r);
120791037db265ecdd914a26e056cf69207b4f50924ehkuang}
120891037db265ecdd914a26e056cf69207b4f50924ehkuang
120991037db265ecdd914a26e056cf69207b4f50924ehkuangvoid vp9_init_dequantizer(VP9_COMMON *cm) {
121091037db265ecdd914a26e056cf69207b4f50924ehkuang  int q;
121191037db265ecdd914a26e056cf69207b4f50924ehkuang
121291037db265ecdd914a26e056cf69207b4f50924ehkuang  for (q = 0; q < QINDEX_RANGE; q++) {
121391037db265ecdd914a26e056cf69207b4f50924ehkuang    cm->y_dequant[q][0] = vp9_dc_quant(q, cm->y_dc_delta_q);
121491037db265ecdd914a26e056cf69207b4f50924ehkuang    cm->y_dequant[q][1] = vp9_ac_quant(q, 0);
121591037db265ecdd914a26e056cf69207b4f50924ehkuang
121691037db265ecdd914a26e056cf69207b4f50924ehkuang    cm->uv_dequant[q][0] = vp9_dc_quant(q, cm->uv_dc_delta_q);
121791037db265ecdd914a26e056cf69207b4f50924ehkuang    cm->uv_dequant[q][1] = vp9_ac_quant(q, cm->uv_ac_delta_q);
121891037db265ecdd914a26e056cf69207b4f50924ehkuang  }
121991037db265ecdd914a26e056cf69207b4f50924ehkuang}
122091037db265ecdd914a26e056cf69207b4f50924ehkuang
12215ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#ifdef NDEBUG
12225ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#define debug_check_frame_counts(cm) (void)0
12235ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#else  // !NDEBUG
12245ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang// Counts should only be incremented when frame_parallel_decoding_mode and
12255ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang// error_resilient_mode are disabled.
12265ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangstatic void debug_check_frame_counts(const VP9_COMMON *const cm) {
12275ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  FRAME_COUNTS zero_counts;
12285ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  vp9_zero(zero_counts);
12295ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  assert(cm->frame_parallel_decoding_mode || cm->error_resilient_mode);
12305ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  assert(!memcmp(cm->counts.y_mode, zero_counts.y_mode,
12315ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                 sizeof(cm->counts.y_mode)));
12325ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  assert(!memcmp(cm->counts.uv_mode, zero_counts.uv_mode,
12335ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                 sizeof(cm->counts.uv_mode)));
12345ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  assert(!memcmp(cm->counts.partition, zero_counts.partition,
12355ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                 sizeof(cm->counts.partition)));
12365ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  assert(!memcmp(cm->counts.coef, zero_counts.coef,
12375ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                 sizeof(cm->counts.coef)));
12385ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  assert(!memcmp(cm->counts.eob_branch, zero_counts.eob_branch,
12395ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                 sizeof(cm->counts.eob_branch)));
12405ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  assert(!memcmp(cm->counts.switchable_interp, zero_counts.switchable_interp,
12415ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                 sizeof(cm->counts.switchable_interp)));
12425ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  assert(!memcmp(cm->counts.inter_mode, zero_counts.inter_mode,
12435ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                 sizeof(cm->counts.inter_mode)));
12445ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  assert(!memcmp(cm->counts.intra_inter, zero_counts.intra_inter,
12455ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                 sizeof(cm->counts.intra_inter)));
12465ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  assert(!memcmp(cm->counts.comp_inter, zero_counts.comp_inter,
12475ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                 sizeof(cm->counts.comp_inter)));
12485ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  assert(!memcmp(cm->counts.single_ref, zero_counts.single_ref,
12495ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                 sizeof(cm->counts.single_ref)));
12505ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  assert(!memcmp(cm->counts.comp_ref, zero_counts.comp_ref,
12515ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                 sizeof(cm->counts.comp_ref)));
12525ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  assert(!memcmp(&cm->counts.tx, &zero_counts.tx, sizeof(cm->counts.tx)));
1253b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  assert(!memcmp(cm->counts.skip, zero_counts.skip, sizeof(cm->counts.skip)));
12545ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  assert(!memcmp(&cm->counts.mv, &zero_counts.mv, sizeof(cm->counts.mv)));
12555ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang}
12565ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#endif  // NDEBUG
12575ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
12586ac915abcdb404a00d927fe6308a47fcf09d9519hkuangint vp9_decode_frame(VP9Decoder *pbi,
12596ac915abcdb404a00d927fe6308a47fcf09d9519hkuang                     const uint8_t *data, const uint8_t *data_end,
12606ac915abcdb404a00d927fe6308a47fcf09d9519hkuang                     const uint8_t **p_data_end) {
12611184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  VP9_COMMON *const cm = &pbi->common;
1262ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD *const xd = &pbi->mb;
1263ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
12645ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  struct vp9_read_bit_buffer rb = { data, data_end, 0, cm, error_handler };
1265ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const size_t first_partition_size = read_uncompressed_header(pbi, &rb);
12661184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const int keyframe = cm->frame_type == KEY_FRAME;
12675ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const int tile_rows = 1 << cm->log2_tile_rows;
12685ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const int tile_cols = 1 << cm->log2_tile_cols;
12695ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  YV12_BUFFER_CONFIG *const new_fb = get_frame_new_buffer(cm);
1270b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  xd->cur_buf = new_fb;
1271ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1272ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (!first_partition_size) {
12735ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      // showing a frame directly
12745ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      *p_data_end = data + 1;
12755ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      return 0;
1276ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
1277ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1278ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (!pbi->decoded_key_frame && !keyframe)
1279ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    return -1;
1280ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
12815ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  data += vp9_rb_bytes_read(&rb);
1282ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (!read_is_valid(data, first_partition_size, data_end))
12831184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME,
1284ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                       "Truncated packet or corrupt header length");
1285ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
12865ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  pbi->do_loopfilter_inline =
12875ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      (cm->log2_tile_rows | cm->log2_tile_cols) == 0 && cm->lf.filter_level;
12885ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (pbi->do_loopfilter_inline && pbi->lf_worker.data1 == NULL) {
12896ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    CHECK_MEM_ERROR(cm, pbi->lf_worker.data1,
12906ac915abcdb404a00d927fe6308a47fcf09d9519hkuang                    vpx_memalign(32, sizeof(LFWorkerData)));
12915ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    pbi->lf_worker.hook = (VP9WorkerHook)vp9_loop_filter_worker;
12925ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (pbi->oxcf.max_threads > 1 && !vp9_worker_reset(&pbi->lf_worker)) {
12935ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      vpx_internal_error(&cm->error, VPX_CODEC_ERROR,
12945ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                         "Loop filter thread creation failed");
12955ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
12965ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
12975ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
12986ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  init_macroblockd(cm, &pbi->mb);
12996ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  cm->prev_mi = get_prev_mi(cm);
1300ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
13015ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  setup_plane_dequants(cm, xd, cm->base_qindex);
1302b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  vp9_setup_block_planes(xd, cm->subsampling_x, cm->subsampling_y);
1303ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
13045ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  cm->fc = cm->frame_contexts[cm->frame_context_idx];
13055ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  vp9_zero(cm->counts);
13066ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  vp9_zero(xd->dqcoeff);
1307ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
13085ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  xd->corrupted = 0;
13095ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  new_fb->corrupted = read_compressed_header(pbi, data, first_partition_size);
1310ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
13115ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // TODO(jzern): remove frame_parallel_decoding_mode restriction for
13125ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // single-frame tile decoding.
13135ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (pbi->oxcf.max_threads > 1 && tile_rows == 1 && tile_cols > 1 &&
13145ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      cm->frame_parallel_decoding_mode) {
13156ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    *p_data_end = decode_tiles_mt(pbi, data + first_partition_size, data_end);
13165ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  } else {
13176ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    *p_data_end = decode_tiles(pbi, data + first_partition_size, data_end);
13185ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
1319ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
132091037db265ecdd914a26e056cf69207b4f50924ehkuang  new_fb->corrupted |= xd->corrupted;
1321ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1322ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (!pbi->decoded_key_frame) {
1323ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (keyframe && !new_fb->corrupted)
1324ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      pbi->decoded_key_frame = 1;
1325ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    else
13261184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME,
1327ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                         "A stream must start with a complete key frame");
1328ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
1329ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
13301184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  if (!cm->error_resilient_mode && !cm->frame_parallel_decoding_mode) {
13311184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    vp9_adapt_coef_probs(cm);
1332ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
13335ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (!frame_is_intra_only(cm)) {
13341184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      vp9_adapt_mode_probs(cm);
13355ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      vp9_adapt_mv_probs(cm, cm->allow_high_precision_mv);
1336ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
13375ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  } else {
13385ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    debug_check_frame_counts(cm);
1339ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
1340ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
13411184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  if (cm->refresh_frame_context)
13421184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    cm->frame_contexts[cm->frame_context_idx] = cm->fc;
1343ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1344ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return 0;
1345ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
1346