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
115ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
125ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#include "./vp9_rtcd.h"
13ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "./vpx_config.h"
145ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
155ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#include "vpx_mem/vpx_mem.h"
165ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
175ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#include "vp9/common/vp9_idct.h"
18ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_reconinter.h"
19ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_reconintra.h"
20ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_systemdependent.h"
21ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
225ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#include "vp9/encoder/vp9_encodemb.h"
235ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#include "vp9/encoder/vp9_quantize.h"
245ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#include "vp9/encoder/vp9_rdopt.h"
255ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#include "vp9/encoder/vp9_tokenize.h"
26ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
27b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstruct optimize_ctx {
28b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  ENTROPY_CONTEXT ta[MAX_MB_PLANE][16];
29b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  ENTROPY_CONTEXT tl[MAX_MB_PLANE][16];
30b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian};
31b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
32b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstruct encode_b_args {
33b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  MACROBLOCK *x;
34b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  struct optimize_ctx *ctx;
35b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  unsigned char *skip;
36b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian};
37b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
3891037db265ecdd914a26e056cf69207b4f50924ehkuangvoid vp9_subtract_block_c(int rows, int cols,
39b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                          int16_t *diff, ptrdiff_t diff_stride,
40b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                          const uint8_t *src, ptrdiff_t src_stride,
41b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                          const uint8_t *pred, ptrdiff_t pred_stride) {
42ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int r, c;
43ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
44ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (r = 0; r < rows; r++) {
45ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (c = 0; c < cols; c++)
46b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      diff[c] = src[c] - pred[c];
47ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
48b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    diff += diff_stride;
49b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    pred += pred_stride;
50b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    src  += src_stride;
51ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
52ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
53ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
54b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianvoid vp9_subtract_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane) {
55ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  struct macroblock_plane *const p = &x->plane[plane];
56b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const struct macroblockd_plane *const pd = &x->e_mbd.plane[plane];
57b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
58b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int bw = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
59b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int bh = 4 * num_4x4_blocks_high_lookup[plane_bsize];
60ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
61b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  vp9_subtract_block(bh, bw, p->src_diff, bw, p->src.buf, p->src.stride,
62ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                     pd->dst.buf, pd->dst.stride);
63ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
64ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
655ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#define RDTRUNC(RM, DM, R, D) ((128 + (R) * (RM)) & 0xFF)
66ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangtypedef struct vp9_token_state vp9_token_state;
67ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
68ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstruct vp9_token_state {
69ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int           rate;
70ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int           error;
71ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int           next;
72ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  signed char   token;
73ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  short         qc;
74ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang};
75ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
765ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang// TODO(jimbankoski): experiment to find optimal RD numbers.
77ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#define Y1_RD_MULT 4
78ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#define UV_RD_MULT 2
79ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
80ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic const int plane_rd_mult[4] = {
81ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  Y1_RD_MULT,
82ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  UV_RD_MULT,
83ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang};
84ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
85ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#define UPDATE_RD_COST()\
86ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang{\
87ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  rd_cost0 = RDCOST(rdmult, rddiv, rate0, error0);\
88ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  rd_cost1 = RDCOST(rdmult, rddiv, rate1, error1);\
89ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (rd_cost0 == rd_cost1) {\
90ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    rd_cost0 = RDTRUNC(rdmult, rddiv, rate0, error0);\
91ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    rd_cost1 = RDTRUNC(rdmult, rddiv, rate1, error1);\
92ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }\
93ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
94ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
95ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang// This function is a place holder for now but may ultimately need
96ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang// to scan previous tokens to work out the correct context.
9791037db265ecdd914a26e056cf69207b4f50924ehkuangstatic int trellis_get_coeff_context(const int16_t *scan,
9891037db265ecdd914a26e056cf69207b4f50924ehkuang                                     const int16_t *nb,
99ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                     int idx, int token,
10091037db265ecdd914a26e056cf69207b4f50924ehkuang                                     uint8_t *token_cache) {
101ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int bak = token_cache[scan[idx]], pt;
102ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  token_cache[scan[idx]] = vp9_pt_energy_class[token];
10391037db265ecdd914a26e056cf69207b4f50924ehkuang  pt = get_coef_context(nb, token_cache, idx + 1);
104ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  token_cache[scan[idx]] = bak;
105ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return pt;
106ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
107ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
108b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic void optimize_b(int plane, int block, BLOCK_SIZE plane_bsize,
109b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                       TX_SIZE tx_size, MACROBLOCK *mb,
110b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                       ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l) {
111ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD *const xd = &mb->e_mbd;
112b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  struct macroblock_plane *p = &mb->plane[plane];
1131184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  struct macroblockd_plane *pd = &xd->plane[plane];
1146ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  const int ref = is_inter_block(&xd->mi[0]->mbmi);
115ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vp9_token_state tokens[1025][2];
116ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  unsigned best_index[1025][2];
117b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int16_t *coeff = BLOCK_OFFSET(mb->plane[plane].coeff, block);
118b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int16_t *qcoeff = BLOCK_OFFSET(p->qcoeff, block);
119b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int16_t *dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
120b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int eob = p->eobs[block], final_eob, sz = 0;
121ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int i0 = 0;
122ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int rc, x, next, i;
123ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int64_t rdmult, rddiv, rd_cost0, rd_cost1;
124ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int rate0, rate1, error0, error1, t0, t1;
125ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int best, band, pt;
1261184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  PLANE_TYPE type = pd->plane_type;
127ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int err_mult = plane_rd_mult[type];
1285ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const int default_eob = 16 << (tx_size << 1);
129ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int mul = 1 + (tx_size == TX_32X32);
130ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  uint8_t token_cache[1024];
1311184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const int16_t *dequant_ptr = pd->dequant;
1325ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const uint8_t *const band_translate = get_band_translate(tx_size);
133b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const scan_order *so = get_scan(xd, tx_size, type, block);
134b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int16_t *scan = so->scan;
135b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int16_t *nb = so->neighbors;
136ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
137ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  assert((!type && !plane) || (type && plane));
138ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  assert(eob <= default_eob);
139ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
140ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* Now set up a Viterbi trellis to evaluate alternative roundings. */
141ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  rdmult = mb->rdmult * err_mult;
1426ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  if (!is_inter_block(&mb->e_mbd.mi[0]->mbmi))
143ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    rdmult = (rdmult * 9) >> 4;
144ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  rddiv = mb->rddiv;
145ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* Initialize the sentinel node of the trellis. */
146ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  tokens[eob][0].rate = 0;
147ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  tokens[eob][0].error = 0;
148ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  tokens[eob][0].next = default_eob;
149b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  tokens[eob][0].token = EOB_TOKEN;
150ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  tokens[eob][0].qc = 0;
151ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  *(tokens[eob] + 1) = *(tokens[eob] + 0);
152ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  next = eob;
153ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0; i < eob; i++)
154ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    token_cache[scan[i]] = vp9_pt_energy_class[vp9_dct_value_tokens_ptr[
155b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        qcoeff[scan[i]]].token];
156ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
157ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = eob; i-- > i0;) {
158ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int base_bits, d2, dx;
159ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
160ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    rc = scan[i];
161b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    x = qcoeff[rc];
162ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    /* Only add a trellis state for non-zero coefficients. */
163ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (x) {
164ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      int shortcut = 0;
165ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      error0 = tokens[next][0].error;
166ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      error1 = tokens[next][1].error;
167ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      /* Evaluate the first possibility for this state. */
168ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      rate0 = tokens[next][0].rate;
169ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      rate1 = tokens[next][1].rate;
170ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      t0 = (vp9_dct_value_tokens_ptr + x)->token;
171ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      /* Consider both possible successor states. */
172ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (next < default_eob) {
1739b35249446b07f40ac5fcc3205f2c048616efacchkuang        band = band_translate[i + 1];
17491037db265ecdd914a26e056cf69207b4f50924ehkuang        pt = trellis_get_coeff_context(scan, nb, i, t0, token_cache);
175ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        rate0 +=
176f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          mb->token_costs[tx_size][type][ref][band][0][pt]
17791037db265ecdd914a26e056cf69207b4f50924ehkuang                         [tokens[next][0].token];
178ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        rate1 +=
179f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          mb->token_costs[tx_size][type][ref][band][0][pt]
18091037db265ecdd914a26e056cf69207b4f50924ehkuang                         [tokens[next][1].token];
181ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
182ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      UPDATE_RD_COST();
183ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      /* And pick the best. */
184ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      best = rd_cost1 < rd_cost0;
185ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      base_bits = *(vp9_dct_value_cost_ptr + x);
186b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      dx = mul * (dqcoeff[rc] - coeff[rc]);
187ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      d2 = dx * dx;
188ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      tokens[i][0].rate = base_bits + (best ? rate1 : rate0);
189ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      tokens[i][0].error = d2 + (best ? error1 : error0);
190ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      tokens[i][0].next = next;
191ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      tokens[i][0].token = t0;
192ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      tokens[i][0].qc = x;
193ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      best_index[i][0] = best;
194ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
195ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      /* Evaluate the second possibility for this state. */
196ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      rate0 = tokens[next][0].rate;
197ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      rate1 = tokens[next][1].rate;
198ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
199b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if ((abs(x)*dequant_ptr[rc != 0] > abs(coeff[rc]) * mul) &&
200b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          (abs(x)*dequant_ptr[rc != 0] < abs(coeff[rc]) * mul +
201ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                         dequant_ptr[rc != 0]))
202ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        shortcut = 1;
203ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      else
204ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        shortcut = 0;
205ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
206ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (shortcut) {
207ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        sz = -(x < 0);
208ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        x -= 2 * sz + 1;
209ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
210ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
211ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      /* Consider both possible successor states. */
212ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (!x) {
213ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        /* If we reduced this coefficient to zero, check to see if
214ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang         *  we need to move the EOB back here.
215ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang         */
216b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        t0 = tokens[next][0].token == EOB_TOKEN ? EOB_TOKEN : ZERO_TOKEN;
217b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        t1 = tokens[next][1].token == EOB_TOKEN ? EOB_TOKEN : ZERO_TOKEN;
218ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      } else {
219ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        t0 = t1 = (vp9_dct_value_tokens_ptr + x)->token;
220ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
221ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (next < default_eob) {
2229b35249446b07f40ac5fcc3205f2c048616efacchkuang        band = band_translate[i + 1];
223b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        if (t0 != EOB_TOKEN) {
22491037db265ecdd914a26e056cf69207b4f50924ehkuang          pt = trellis_get_coeff_context(scan, nb, i, t0, token_cache);
225f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          rate0 += mb->token_costs[tx_size][type][ref][band][!x][pt]
22691037db265ecdd914a26e056cf69207b4f50924ehkuang                                  [tokens[next][0].token];
227ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
228b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        if (t1 != EOB_TOKEN) {
22991037db265ecdd914a26e056cf69207b4f50924ehkuang          pt = trellis_get_coeff_context(scan, nb, i, t1, token_cache);
230f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          rate1 += mb->token_costs[tx_size][type][ref][band][!x][pt]
23191037db265ecdd914a26e056cf69207b4f50924ehkuang                                  [tokens[next][1].token];
232ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
233ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
234ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
235ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      UPDATE_RD_COST();
236ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      /* And pick the best. */
237ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      best = rd_cost1 < rd_cost0;
238ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      base_bits = *(vp9_dct_value_cost_ptr + x);
239ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
240ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (shortcut) {
241ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        dx -= (dequant_ptr[rc != 0] + sz) ^ sz;
242ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        d2 = dx * dx;
243ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
244ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      tokens[i][1].rate = base_bits + (best ? rate1 : rate0);
245ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      tokens[i][1].error = d2 + (best ? error1 : error0);
246ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      tokens[i][1].next = next;
247ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      tokens[i][1].token = best ? t1 : t0;
248ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      tokens[i][1].qc = x;
249ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      best_index[i][1] = best;
250ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      /* Finally, make this the new head of the trellis. */
251ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      next = i;
2525ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    } else {
2535ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      /* There's no choice to make for a zero coefficient, so we don't
2545ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang       *  add a new trellis node, but we do need to update the costs.
2555ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang       */
2569b35249446b07f40ac5fcc3205f2c048616efacchkuang      band = band_translate[i + 1];
257ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      t0 = tokens[next][0].token;
258ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      t1 = tokens[next][1].token;
259ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      /* Update the cost of each path if we're past the EOB token. */
260b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (t0 != EOB_TOKEN) {
261ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        tokens[next][0].rate +=
262f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang            mb->token_costs[tx_size][type][ref][band][1][0][t0];
263ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        tokens[next][0].token = ZERO_TOKEN;
264ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
265b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (t1 != EOB_TOKEN) {
266ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        tokens[next][1].rate +=
267f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang            mb->token_costs[tx_size][type][ref][band][1][0][t1];
268ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        tokens[next][1].token = ZERO_TOKEN;
269ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
27091037db265ecdd914a26e056cf69207b4f50924ehkuang      best_index[i][0] = best_index[i][1] = 0;
271ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      /* Don't update next, because we didn't add a new node. */
272ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
273ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
274ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
275ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* Now pick the best path through the whole trellis. */
2769b35249446b07f40ac5fcc3205f2c048616efacchkuang  band = band_translate[i + 1];
277ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  pt = combine_entropy_contexts(*a, *l);
278ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  rate0 = tokens[next][0].rate;
279ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  rate1 = tokens[next][1].rate;
280ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  error0 = tokens[next][0].error;
281ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  error1 = tokens[next][1].error;
282ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  t0 = tokens[next][0].token;
283ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  t1 = tokens[next][1].token;
284f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  rate0 += mb->token_costs[tx_size][type][ref][band][0][pt][t0];
285f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  rate1 += mb->token_costs[tx_size][type][ref][band][0][pt][t1];
286ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  UPDATE_RD_COST();
287ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  best = rd_cost1 < rd_cost0;
288ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  final_eob = i0 - 1;
289b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  vpx_memset(qcoeff, 0, sizeof(*qcoeff) * (16 << (tx_size * 2)));
290b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  vpx_memset(dqcoeff, 0, sizeof(*dqcoeff) * (16 << (tx_size * 2)));
291ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = next; i < eob; i = next) {
292ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    x = tokens[i][best].qc;
293ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (x) {
294ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      final_eob = i;
295ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
296ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    rc = scan[i];
297b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    qcoeff[rc] = x;
298b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    dqcoeff[rc] = (x * dequant_ptr[rc != 0]) / mul;
299ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
300ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    next = tokens[i][best].next;
301ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    best = best_index[i][best];
302ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
303ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  final_eob++;
304ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
305b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  mb->plane[plane].eobs[block] = final_eob;
306ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  *a = *l = (final_eob > 0);
307ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
308ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
309b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic INLINE void fdct32x32(int rd_transform,
310b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                             const int16_t *src, int16_t *dst, int src_stride) {
311b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (rd_transform)
312b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    vp9_fdct32x32_rd(src, dst, src_stride);
313b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  else
314b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    vp9_fdct32x32(src, dst, src_stride);
315ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
316ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
317b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianvoid vp9_xform_quant(MACROBLOCK *x, int plane, int block,
318b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                     BLOCK_SIZE plane_bsize, TX_SIZE tx_size) {
319b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  MACROBLOCKD *const xd = &x->e_mbd;
320b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const struct macroblock_plane *const p = &x->plane[plane];
321b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const struct macroblockd_plane *const pd = &xd->plane[plane];
322b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const scan_order *const scan_order = &vp9_default_scan_orders[tx_size];
323b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int16_t *const coeff = BLOCK_OFFSET(p->coeff, block);
324b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int16_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
325b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int16_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
326b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  uint16_t *const eob = &p->eobs[block];
327b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int diff_stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
328b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int i, j;
329b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int16_t *src_diff;
330b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &i, &j);
331b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  src_diff = &p->src_diff[4 * (j * diff_stride + i)];
332ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
33391037db265ecdd914a26e056cf69207b4f50924ehkuang  switch (tx_size) {
334ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    case TX_32X32:
335b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      fdct32x32(x->use_lp32x32fdct, src_diff, coeff, diff_stride);
33691037db265ecdd914a26e056cf69207b4f50924ehkuang      vp9_quantize_b_32x32(coeff, 1024, x->skip_block, p->zbin, p->round,
33791037db265ecdd914a26e056cf69207b4f50924ehkuang                           p->quant, p->quant_shift, qcoeff, dqcoeff,
338b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                           pd->dequant, p->zbin_extra, eob, scan_order->scan,
339b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                           scan_order->iscan);
340ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      break;
341ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    case TX_16X16:
342b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      vp9_fdct16x16(src_diff, coeff, diff_stride);
34391037db265ecdd914a26e056cf69207b4f50924ehkuang      vp9_quantize_b(coeff, 256, x->skip_block, p->zbin, p->round,
34491037db265ecdd914a26e056cf69207b4f50924ehkuang                     p->quant, p->quant_shift, qcoeff, dqcoeff,
345b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                     pd->dequant, p->zbin_extra, eob,
346b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                     scan_order->scan, scan_order->iscan);
347ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      break;
348ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    case TX_8X8:
349b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      vp9_fdct8x8(src_diff, coeff, diff_stride);
35091037db265ecdd914a26e056cf69207b4f50924ehkuang      vp9_quantize_b(coeff, 64, x->skip_block, p->zbin, p->round,
35191037db265ecdd914a26e056cf69207b4f50924ehkuang                     p->quant, p->quant_shift, qcoeff, dqcoeff,
352b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                     pd->dequant, p->zbin_extra, eob,
353b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                     scan_order->scan, scan_order->iscan);
354ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      break;
355ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    case TX_4X4:
356b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      x->fwd_txm4x4(src_diff, coeff, diff_stride);
35791037db265ecdd914a26e056cf69207b4f50924ehkuang      vp9_quantize_b(coeff, 16, x->skip_block, p->zbin, p->round,
35891037db265ecdd914a26e056cf69207b4f50924ehkuang                     p->quant, p->quant_shift, qcoeff, dqcoeff,
359b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                     pd->dequant, p->zbin_extra, eob,
360b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                     scan_order->scan, scan_order->iscan);
361ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      break;
362ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    default:
363ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      assert(0);
364ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
365ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
366ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3671184aebb761cbeac9124c37189a80a1a58f04b6bhkuangstatic void encode_block(int plane, int block, BLOCK_SIZE plane_bsize,
3681184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                         TX_SIZE tx_size, void *arg) {
369ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  struct encode_b_args *const args = arg;
370ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCK *const x = args->x;
371ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD *const xd = &x->e_mbd;
3725ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  struct optimize_ctx *const ctx = args->ctx;
373b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  struct macroblock_plane *const p = &x->plane[plane];
374ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  struct macroblockd_plane *const pd = &xd->plane[plane];
3751184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int16_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
3769b35249446b07f40ac5fcc3205f2c048616efacchkuang  int i, j;
3779b35249446b07f40ac5fcc3205f2c048616efacchkuang  uint8_t *dst;
378b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  ENTROPY_CONTEXT *a, *l;
3799b35249446b07f40ac5fcc3205f2c048616efacchkuang  txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &i, &j);
3809b35249446b07f40ac5fcc3205f2c048616efacchkuang  dst = &pd->dst.buf[4 * j * pd->dst.stride + 4 * i];
381b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  a = &ctx->ta[plane][i];
382b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  l = &ctx->tl[plane][j];
3835ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
3845ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // TODO(jingning): per transformed block zero forcing only enabled for
3855ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // luma component. will integrate chroma components as well.
3865ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (x->zcoeff_blk[tx_size][block] && plane == 0) {
387b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    p->eobs[block] = 0;
388b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    *a = *l = 0;
3895ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    return;
3905ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
3915ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
3929b35249446b07f40ac5fcc3205f2c048616efacchkuang  if (!x->skip_recode)
393b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    vp9_xform_quant(x, plane, block, plane_bsize, tx_size);
394ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3959b35249446b07f40ac5fcc3205f2c048616efacchkuang  if (x->optimize && (!x->skip_recode || !x->skip_optimize)) {
396b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    optimize_b(plane, block, plane_bsize, tx_size, x, a, l);
3979b35249446b07f40ac5fcc3205f2c048616efacchkuang  } else {
398b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    *a = *l = p->eobs[block] > 0;
3999b35249446b07f40ac5fcc3205f2c048616efacchkuang  }
400ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
401b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (p->eobs[block])
402b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    *(args->skip) = 0;
403b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
404b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (x->skip_encode || p->eobs[block] == 0)
40591037db265ecdd914a26e056cf69207b4f50924ehkuang    return;
40691037db265ecdd914a26e056cf69207b4f50924ehkuang
4071184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  switch (tx_size) {
408ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    case TX_32X32:
409b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      vp9_idct32x32_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
410ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      break;
411ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    case TX_16X16:
412b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      vp9_idct16x16_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
413ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      break;
414ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    case TX_8X8:
415b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      vp9_idct8x8_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
416ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      break;
417ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    case TX_4X4:
41891037db265ecdd914a26e056cf69207b4f50924ehkuang      // this is like vp9_short_idct4x4 but has a special case around eob<=1
41991037db265ecdd914a26e056cf69207b4f50924ehkuang      // which is significant (not just an optimization) for the lossless
42091037db265ecdd914a26e056cf69207b4f50924ehkuang      // case.
421b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      xd->itxm_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
422ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      break;
4231184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    default:
424b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      assert(0 && "Invalid transform size");
425ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
426ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
427a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian
4285ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangstatic void encode_block_pass1(int plane, int block, BLOCK_SIZE plane_bsize,
4295ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                               TX_SIZE tx_size, void *arg) {
430b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  MACROBLOCK *const x = (MACROBLOCK *)arg;
4315ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MACROBLOCKD *const xd = &x->e_mbd;
432b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  struct macroblock_plane *const p = &x->plane[plane];
4335ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  struct macroblockd_plane *const pd = &xd->plane[plane];
4345ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int16_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
435b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int i, j;
436b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  uint8_t *dst;
437b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &i, &j);
438b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  dst = &pd->dst.buf[4 * j * pd->dst.stride + 4 * i];
4395ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
440b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  vp9_xform_quant(x, plane, block, plane_bsize, tx_size);
4415ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
442b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (p->eobs[block] > 0)
443b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    xd->itxm_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
4445ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang}
4455ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
446b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianvoid vp9_encode_sby_pass1(MACROBLOCK *x, BLOCK_SIZE bsize) {
447b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  vp9_subtract_plane(x, bsize, 0);
448b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  vp9_foreach_transformed_block_in_plane(&x->e_mbd, bsize, 0,
449b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                         encode_block_pass1, x);
450ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
451ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4521184aebb761cbeac9124c37189a80a1a58f04b6bhkuangvoid vp9_encode_sb(MACROBLOCK *x, BLOCK_SIZE bsize) {
453ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD *const xd = &x->e_mbd;
454ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  struct optimize_ctx ctx;
4556ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
456b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  struct encode_b_args arg = {x, &ctx, &mbmi->skip};
457b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int plane;
458b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
459b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
460b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (!x->skip_recode)
461b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      vp9_subtract_plane(x, bsize, plane);
462b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
463b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (x->optimize && (!x->skip_recode || !x->skip_optimize)) {
464b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      const struct macroblockd_plane* const pd = &xd->plane[plane];
465b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      const TX_SIZE tx_size = plane ? get_uv_tx_size(mbmi) : mbmi->tx_size;
466b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      vp9_get_entropy_contexts(bsize, tx_size, pd,
467b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                               ctx.ta[plane], ctx.tl[plane]);
468b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    }
469f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
470b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    vp9_foreach_transformed_block_in_plane(xd, bsize, plane, encode_block,
471b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                           &arg);
472f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  }
473ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
474ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
475b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic void encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize,
476b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                               TX_SIZE tx_size, void *arg) {
477ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  struct encode_b_args* const args = arg;
478ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCK *const x = args->x;
479ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD *const xd = &x->e_mbd;
4806ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
481ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  struct macroblock_plane *const p = &x->plane[plane];
482ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  struct macroblockd_plane *const pd = &xd->plane[plane];
4831184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int16_t *coeff = BLOCK_OFFSET(p->coeff, block);
484b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int16_t *qcoeff = BLOCK_OFFSET(p->qcoeff, block);
4851184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int16_t *dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
486b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const scan_order *scan_order;
487ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  TX_TYPE tx_type;
48891037db265ecdd914a26e056cf69207b4f50924ehkuang  MB_PREDICTION_MODE mode;
489b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int bwl = b_width_log2(plane_bsize);
490b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int diff_stride = 4 * (1 << bwl);
49191037db265ecdd914a26e056cf69207b4f50924ehkuang  uint8_t *src, *dst;
49291037db265ecdd914a26e056cf69207b4f50924ehkuang  int16_t *src_diff;
493b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  uint16_t *eob = &p->eobs[block];
494b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int src_stride = p->src.stride;
495b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int dst_stride = pd->dst.stride;
496b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int i, j;
497b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &i, &j);
498b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  dst = &pd->dst.buf[4 * (j * dst_stride + i)];
499b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  src = &p->src.buf[4 * (j * src_stride + i)];
500b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  src_diff = &p->src_diff[4 * (j * diff_stride + i)];
501ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
50291037db265ecdd914a26e056cf69207b4f50924ehkuang  switch (tx_size) {
503ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    case TX_32X32:
504b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      scan_order = &vp9_default_scan_orders[TX_32X32];
50591037db265ecdd914a26e056cf69207b4f50924ehkuang      mode = plane == 0 ? mbmi->mode : mbmi->uv_mode;
506b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      vp9_predict_intra_block(xd, block >> 6, bwl, TX_32X32, mode,
507b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                              x->skip_encode ? src : dst,
508b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                              x->skip_encode ? src_stride : dst_stride,
509b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                              dst, dst_stride, i, j, plane);
5109b35249446b07f40ac5fcc3205f2c048616efacchkuang      if (!x->skip_recode) {
511b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        vp9_subtract_block(32, 32, src_diff, diff_stride,
512b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                           src, src_stride, dst, dst_stride);
513b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        fdct32x32(x->use_lp32x32fdct, src_diff, coeff, diff_stride);
5149b35249446b07f40ac5fcc3205f2c048616efacchkuang        vp9_quantize_b_32x32(coeff, 1024, x->skip_block, p->zbin, p->round,
5159b35249446b07f40ac5fcc3205f2c048616efacchkuang                             p->quant, p->quant_shift, qcoeff, dqcoeff,
516b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                             pd->dequant, p->zbin_extra, eob, scan_order->scan,
517b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                             scan_order->iscan);
5189b35249446b07f40ac5fcc3205f2c048616efacchkuang      }
51991037db265ecdd914a26e056cf69207b4f50924ehkuang      if (!x->skip_encode && *eob)
520b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        vp9_idct32x32_add(dqcoeff, dst, dst_stride, *eob);
521ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      break;
522ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    case TX_16X16:
523b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      tx_type = get_tx_type(pd->plane_type, xd);
524b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      scan_order = &vp9_scan_orders[TX_16X16][tx_type];
52591037db265ecdd914a26e056cf69207b4f50924ehkuang      mode = plane == 0 ? mbmi->mode : mbmi->uv_mode;
526b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      vp9_predict_intra_block(xd, block >> 4, bwl, TX_16X16, mode,
527b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                              x->skip_encode ? src : dst,
528b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                              x->skip_encode ? src_stride : dst_stride,
529b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                              dst, dst_stride, i, j, plane);
5309b35249446b07f40ac5fcc3205f2c048616efacchkuang      if (!x->skip_recode) {
531b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        vp9_subtract_block(16, 16, src_diff, diff_stride,
532b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                           src, src_stride, dst, dst_stride);
533b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        vp9_fht16x16(src_diff, coeff, diff_stride, tx_type);
5349b35249446b07f40ac5fcc3205f2c048616efacchkuang        vp9_quantize_b(coeff, 256, x->skip_block, p->zbin, p->round,
5359b35249446b07f40ac5fcc3205f2c048616efacchkuang                       p->quant, p->quant_shift, qcoeff, dqcoeff,
536b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                       pd->dequant, p->zbin_extra, eob, scan_order->scan,
537b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                       scan_order->iscan);
5389b35249446b07f40ac5fcc3205f2c048616efacchkuang      }
5395ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (!x->skip_encode && *eob)
540b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        vp9_iht16x16_add(tx_type, dqcoeff, dst, dst_stride, *eob);
541ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      break;
542ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    case TX_8X8:
543b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      tx_type = get_tx_type(pd->plane_type, xd);
544b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      scan_order = &vp9_scan_orders[TX_8X8][tx_type];
54591037db265ecdd914a26e056cf69207b4f50924ehkuang      mode = plane == 0 ? mbmi->mode : mbmi->uv_mode;
546b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      vp9_predict_intra_block(xd, block >> 2, bwl, TX_8X8, mode,
547b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                              x->skip_encode ? src : dst,
548b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                              x->skip_encode ? src_stride : dst_stride,
549b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                              dst, dst_stride, i, j, plane);
5509b35249446b07f40ac5fcc3205f2c048616efacchkuang      if (!x->skip_recode) {
551b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        vp9_subtract_block(8, 8, src_diff, diff_stride,
552b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                           src, src_stride, dst, dst_stride);
553b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        vp9_fht8x8(src_diff, coeff, diff_stride, tx_type);
5549b35249446b07f40ac5fcc3205f2c048616efacchkuang        vp9_quantize_b(coeff, 64, x->skip_block, p->zbin, p->round, p->quant,
5559b35249446b07f40ac5fcc3205f2c048616efacchkuang                       p->quant_shift, qcoeff, dqcoeff,
556b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                       pd->dequant, p->zbin_extra, eob, scan_order->scan,
557b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                       scan_order->iscan);
5589b35249446b07f40ac5fcc3205f2c048616efacchkuang      }
5595ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (!x->skip_encode && *eob)
560b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        vp9_iht8x8_add(tx_type, dqcoeff, dst, dst_stride, *eob);
561ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      break;
562ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    case TX_4X4:
56391037db265ecdd914a26e056cf69207b4f50924ehkuang      tx_type = get_tx_type_4x4(pd->plane_type, xd, block);
564b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      scan_order = &vp9_scan_orders[TX_4X4][tx_type];
5656ac915abcdb404a00d927fe6308a47fcf09d9519hkuang      mode = plane == 0 ? get_y_mode(xd->mi[0], block) : mbmi->uv_mode;
56691037db265ecdd914a26e056cf69207b4f50924ehkuang      vp9_predict_intra_block(xd, block, bwl, TX_4X4, mode,
567b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                              x->skip_encode ? src : dst,
568b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                              x->skip_encode ? src_stride : dst_stride,
569b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                              dst, dst_stride, i, j, plane);
5709b35249446b07f40ac5fcc3205f2c048616efacchkuang
5719b35249446b07f40ac5fcc3205f2c048616efacchkuang      if (!x->skip_recode) {
572b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        vp9_subtract_block(4, 4, src_diff, diff_stride,
573b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                           src, src_stride, dst, dst_stride);
5749b35249446b07f40ac5fcc3205f2c048616efacchkuang        if (tx_type != DCT_DCT)
575b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          vp9_fht4x4(src_diff, coeff, diff_stride, tx_type);
5769b35249446b07f40ac5fcc3205f2c048616efacchkuang        else
577b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          x->fwd_txm4x4(src_diff, coeff, diff_stride);
5789b35249446b07f40ac5fcc3205f2c048616efacchkuang        vp9_quantize_b(coeff, 16, x->skip_block, p->zbin, p->round, p->quant,
5799b35249446b07f40ac5fcc3205f2c048616efacchkuang                       p->quant_shift, qcoeff, dqcoeff,
580b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                       pd->dequant, p->zbin_extra, eob, scan_order->scan,
581b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                       scan_order->iscan);
5829b35249446b07f40ac5fcc3205f2c048616efacchkuang      }
5839b35249446b07f40ac5fcc3205f2c048616efacchkuang
58491037db265ecdd914a26e056cf69207b4f50924ehkuang      if (!x->skip_encode && *eob) {
58591037db265ecdd914a26e056cf69207b4f50924ehkuang        if (tx_type == DCT_DCT)
58691037db265ecdd914a26e056cf69207b4f50924ehkuang          // this is like vp9_short_idct4x4 but has a special case around eob<=1
58791037db265ecdd914a26e056cf69207b4f50924ehkuang          // which is significant (not just an optimization) for the lossless
58891037db265ecdd914a26e056cf69207b4f50924ehkuang          // case.
589b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          xd->itxm_add(dqcoeff, dst, dst_stride, *eob);
59091037db265ecdd914a26e056cf69207b4f50924ehkuang        else
591b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          vp9_iht4x4_16_add(dqcoeff, dst, dst_stride, tx_type);
59291037db265ecdd914a26e056cf69207b4f50924ehkuang      }
593ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      break;
59491037db265ecdd914a26e056cf69207b4f50924ehkuang    default:
59591037db265ecdd914a26e056cf69207b4f50924ehkuang      assert(0);
596ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
597b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (*eob)
598b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    *(args->skip) = 0;
599ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
600ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
601b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianvoid vp9_encode_block_intra(MACROBLOCK *x, int plane, int block,
602b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                            BLOCK_SIZE plane_bsize, TX_SIZE tx_size,
603b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                            unsigned char *skip) {
604b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  struct encode_b_args arg = {x, NULL, skip};
605b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  encode_block_intra(plane, block, plane_bsize, tx_size, &arg);
606ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
607b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
608b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
609b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianvoid vp9_encode_intra_block_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane) {
610b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const MACROBLOCKD *const xd = &x->e_mbd;
6116ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  struct encode_b_args arg = {x, NULL, &xd->mi[0]->mbmi.skip};
612b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
613b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  vp9_foreach_transformed_block_in_plane(xd, bsize, plane, encode_block_intra,
614b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                         &arg);
615ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
616ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
617b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianint vp9_encode_intra(MACROBLOCK *x, int use_16x16_pred) {
6186ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  MB_MODE_INFO * mbmi = &x->e_mbd.mi[0]->mbmi;
619b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  x->skip_encode = 0;
620b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  mbmi->mode = DC_PRED;
621b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  mbmi->ref_frame[0] = INTRA_FRAME;
622b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  mbmi->tx_size = use_16x16_pred ? (mbmi->sb_type >= BLOCK_16X16 ? TX_16X16
623b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                                                 : TX_8X8)
624b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                   : TX_4X4;
625b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  vp9_encode_intra_block_plane(x, mbmi->sb_type, 0);
626b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  return vp9_get_mb_ss(x->plane[0].src_diff);
627b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian}
628