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 <limits.h>
13b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include <math.h>
14b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include <stdio.h>
15ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
16b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "./vp9_rtcd.h"
17b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
18b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vpx_mem/vpx_mem.h"
19b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
20b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vp9/common/vp9_common.h"
21b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vp9/common/vp9_entropy.h"
22ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_entropymode.h"
23b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vp9/common/vp9_idct.h"
24b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vp9/common/vp9_mvref_common.h"
25b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vp9/common/vp9_pragmas.h"
26b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vp9/common/vp9_pred_common.h"
27b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vp9/common/vp9_quant_common.h"
28ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_reconinter.h"
29ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_reconintra.h"
30b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vp9/common/vp9_seg_common.h"
31b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vp9/common/vp9_systemdependent.h"
32b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
33b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vp9/encoder/vp9_cost.h"
34ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/encoder/vp9_encodemb.h"
35b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vp9/encoder/vp9_encodemv.h"
36ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/encoder/vp9_mcomp.h"
37b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vp9/encoder/vp9_onyx_int.h"
38b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vp9/encoder/vp9_quantize.h"
39ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/encoder/vp9_ratectrl.h"
40b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vp9/encoder/vp9_rdopt.h"
41b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vp9/encoder/vp9_tokenize.h"
42b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vp9/encoder/vp9_variance.h"
43ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
44a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian#define RD_THRESH_MAX_FACT 64
45a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian#define RD_THRESH_INC      1
46a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian#define RD_THRESH_POW      1.25
47a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian#define RD_MULT_EPB_RATIO  64
48a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian
49ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/* Factor to weigh the rate for switchable interp filters */
50ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#define SWITCHABLE_INTERP_RATE_FACTOR 1
51ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
525ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#define LAST_FRAME_MODE_MASK    0xFFEDCD60
535ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#define GOLDEN_FRAME_MODE_MASK  0xFFDA3BB0
545ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#define ALT_REF_MODE_MASK       0xFFC648D0
55ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
565ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#define MIN_EARLY_TERM_INDEX    3
57ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
58b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramaniantypedef struct {
59b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  MB_PREDICTION_MODE mode;
60b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  MV_REFERENCE_FRAME ref_frame[2];
61b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} MODE_DEFINITION;
62b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
63b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramaniantypedef struct {
64b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  MV_REFERENCE_FRAME ref_frame[2];
65b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} REF_DEFINITION;
66b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
67b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstruct rdcost_block_args {
68b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  MACROBLOCK *x;
69b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  ENTROPY_CONTEXT t_above[16];
70b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  ENTROPY_CONTEXT t_left[16];
71b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int rate;
72b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int64_t dist;
73b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int64_t sse;
74b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int this_rate;
75b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int64_t this_dist;
76b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int64_t this_sse;
77b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int64_t this_rd;
78b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int64_t best_rd;
79b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int skip;
80b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int use_fast_coef_costing;
81b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const scan_order *so;
82b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian};
83b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
84ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangconst MODE_DEFINITION vp9_mode_order[MAX_MODES] = {
85b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {NEARESTMV, {LAST_FRAME,   NONE}},
86b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {NEARESTMV, {ALTREF_FRAME, NONE}},
87b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {NEARESTMV, {GOLDEN_FRAME, NONE}},
88b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
89b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {DC_PRED,   {INTRA_FRAME,  NONE}},
90b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
91b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {NEWMV,     {LAST_FRAME,   NONE}},
92b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {NEWMV,     {ALTREF_FRAME, NONE}},
93b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {NEWMV,     {GOLDEN_FRAME, NONE}},
94b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
95b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {NEARMV,    {LAST_FRAME,   NONE}},
96b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {NEARMV,    {ALTREF_FRAME, NONE}},
97b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {NEARESTMV, {LAST_FRAME,   ALTREF_FRAME}},
98b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {NEARESTMV, {GOLDEN_FRAME, ALTREF_FRAME}},
99b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
100b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {TM_PRED,   {INTRA_FRAME,  NONE}},
101b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
102b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {NEARMV,    {LAST_FRAME,   ALTREF_FRAME}},
103b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {NEWMV,     {LAST_FRAME,   ALTREF_FRAME}},
104b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {NEARMV,    {GOLDEN_FRAME, NONE}},
105b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {NEARMV,    {GOLDEN_FRAME, ALTREF_FRAME}},
106b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {NEWMV,     {GOLDEN_FRAME, ALTREF_FRAME}},
107b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
108b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {ZEROMV,    {LAST_FRAME,   NONE}},
109b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {ZEROMV,    {GOLDEN_FRAME, NONE}},
110b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {ZEROMV,    {ALTREF_FRAME, NONE}},
111b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {ZEROMV,    {LAST_FRAME,   ALTREF_FRAME}},
112b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {ZEROMV,    {GOLDEN_FRAME, ALTREF_FRAME}},
113b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
114b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {H_PRED,    {INTRA_FRAME,  NONE}},
115b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {V_PRED,    {INTRA_FRAME,  NONE}},
116b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {D135_PRED, {INTRA_FRAME,  NONE}},
117b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {D207_PRED, {INTRA_FRAME,  NONE}},
118b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {D153_PRED, {INTRA_FRAME,  NONE}},
119b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {D63_PRED,  {INTRA_FRAME,  NONE}},
120b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {D117_PRED, {INTRA_FRAME,  NONE}},
121b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {D45_PRED,  {INTRA_FRAME,  NONE}},
1225ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang};
1235ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
1245ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangconst REF_DEFINITION vp9_ref_order[MAX_REFS] = {
125b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {{LAST_FRAME,   NONE}},
126b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {{GOLDEN_FRAME, NONE}},
127b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {{ALTREF_FRAME, NONE}},
128b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {{LAST_FRAME,   ALTREF_FRAME}},
129b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {{GOLDEN_FRAME, ALTREF_FRAME}},
130b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  {{INTRA_FRAME,  NONE}},
131ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang};
132ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
133ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang// The baseline rd thresholds for breaking out of the rd loop for
134ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang// certain modes are assumed to be based on 8x8 blocks.
135ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang// This table is used to correct for blocks size.
136ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang// The factors here are << 2 (2 = x0.5, 32 = x8 etc).
1371184aebb761cbeac9124c37189a80a1a58f04b6bhkuangstatic int rd_thresh_block_size_factor[BLOCK_SIZES] =
138ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  {2, 3, 3, 4, 6, 6, 8, 12, 12, 16, 24, 24, 32};
139ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
140b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic int raster_block_offset(BLOCK_SIZE plane_bsize,
141b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                               int raster_block, int stride) {
142b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int bw = b_width_log2(plane_bsize);
143b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int y = 4 * (raster_block >> bw);
144b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int x = 4 * (raster_block & ((1 << bw) - 1));
145b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  return y * stride + x;
146b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian}
147b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic int16_t* raster_block_offset_int16(BLOCK_SIZE plane_bsize,
148b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                          int raster_block, int16_t *base) {
149b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
150b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  return base + raster_block_offset(plane_bsize, raster_block, stride);
151b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian}
152b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
153b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic void fill_mode_costs(VP9_COMP *cpi) {
154b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  MACROBLOCK *const x = &cpi->mb;
155b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const FRAME_CONTEXT *const fc = &cpi->common.fc;
156b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int i, j;
1575ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
158b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  for (i = 0; i < INTRA_MODES; i++)
159b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    for (j = 0; j < INTRA_MODES; j++)
160b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      vp9_cost_tokens((int *)x->y_mode_costs[i][j], vp9_kf_y_mode_prob[i][j],
161b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                      vp9_intra_mode_tree);
162b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
163b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  // TODO(rbultje) separate tables for superblock costing?
164b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  vp9_cost_tokens(x->mbmode_cost, fc->y_mode_prob[1], vp9_intra_mode_tree);
165b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  vp9_cost_tokens(x->intra_uv_mode_cost[KEY_FRAME],
166b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                  vp9_kf_uv_mode_prob[TM_PRED], vp9_intra_mode_tree);
167b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  vp9_cost_tokens(x->intra_uv_mode_cost[INTER_FRAME],
168b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                  fc->uv_mode_prob[TM_PRED], vp9_intra_mode_tree);
169b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
170b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i)
171b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    vp9_cost_tokens((int *)x->switchable_interp_costs[i],
172b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                    fc->switchable_interp_prob[i], vp9_switchable_interp_tree);
173b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian}
174ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
175f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuangstatic void fill_token_costs(vp9_coeff_cost *c,
176b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                             vp9_coeff_probs_model (*p)[PLANE_TYPES]) {
177ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int i, j, k, l;
178ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  TX_SIZE t;
179b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  for (t = TX_4X4; t <= TX_32X32; ++t)
180b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    for (i = 0; i < PLANE_TYPES; ++i)
181b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      for (j = 0; j < REF_TYPES; ++j)
182b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        for (k = 0; k < COEF_BANDS; ++k)
183b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) {
184ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            vp9_prob probs[ENTROPY_NODES];
185ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            vp9_model_to_full_probs(p[t][i][j][k][l], probs);
186f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang            vp9_cost_tokens((int *)c[t][i][j][k][0][l], probs,
187ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                            vp9_coef_tree);
188f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang            vp9_cost_tokens_skip((int *)c[t][i][j][k][1][l], probs,
189ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                 vp9_coef_tree);
190b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            assert(c[t][i][j][k][0][l][EOB_TOKEN] ==
191b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                   c[t][i][j][k][1][l][EOB_TOKEN]);
192ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          }
193ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
194ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
19591037db265ecdd914a26e056cf69207b4f50924ehkuangstatic const int rd_iifactor[32] = {
19691037db265ecdd914a26e056cf69207b4f50924ehkuang  4, 4, 3, 2, 1, 0, 0, 0,
19791037db265ecdd914a26e056cf69207b4f50924ehkuang  0, 0, 0, 0, 0, 0, 0, 0,
19891037db265ecdd914a26e056cf69207b4f50924ehkuang  0, 0, 0, 0, 0, 0, 0, 0,
19991037db265ecdd914a26e056cf69207b4f50924ehkuang  0, 0, 0, 0, 0, 0, 0, 0,
20091037db265ecdd914a26e056cf69207b4f50924ehkuang};
201ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
202ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang// 3* dc_qlookup[Q]*dc_qlookup[Q];
203ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
204ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/* values are now correlated to quantizer */
205ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic int sad_per_bit16lut[QINDEX_RANGE];
206ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic int sad_per_bit4lut[QINDEX_RANGE];
207ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
208ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid vp9_init_me_luts() {
209ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int i;
210ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
211ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Initialize the sad lut tables using a formulaic calculation for now
212ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // This is to make it easier to resolve the impact of experimental changes
213ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // to the quantizer tables.
214ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0; i < QINDEX_RANGE; i++) {
215b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    const double q = vp9_convert_qindex_to_q(i);
216b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    sad_per_bit16lut[i] = (int)(0.0418 * q + 2.4107);
217b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    sad_per_bit4lut[i] = (int)(0.063 * q + 2.742);
218ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
219ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
220ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
221b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianint vp9_compute_rd_mult(const VP9_COMP *cpi, int qindex) {
222ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int q = vp9_dc_quant(qindex, 0);
2235ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // TODO(debargha): Adjust the function below
2245ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int rdmult = 88 * q * q / 25;
2255ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (cpi->pass == 2 && (cpi->common.frame_type != KEY_FRAME)) {
2265ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (cpi->twopass.next_iiratio > 31)
2275ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      rdmult += (rdmult * rd_iifactor[31]) >> 4;
2285ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    else
2295ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      rdmult += (rdmult * rd_iifactor[cpi->twopass.next_iiratio]) >> 4;
2305ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
2315ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  return rdmult;
232ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
233ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2345ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangstatic int compute_rd_thresh_factor(int qindex) {
2355ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // TODO(debargha): Adjust the function below
236b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int q = (int)(pow(vp9_dc_quant(qindex, 0) / 4.0, RD_THRESH_POW) * 5.12);
237b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  return MAX(q, 8);
2381184aebb761cbeac9124c37189a80a1a58f04b6bhkuang}
2391184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
240ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid vp9_initialize_me_consts(VP9_COMP *cpi, int qindex) {
241ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  cpi->mb.sadperbit16 = sad_per_bit16lut[qindex];
242ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  cpi->mb.sadperbit4 = sad_per_bit4lut[qindex];
243ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
244ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2455ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangstatic void set_block_thresholds(VP9_COMP *cpi) {
246b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const VP9_COMMON *const cm = &cpi->common;
2475ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int i, bsize, segment_id;
248ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2495ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  for (segment_id = 0; segment_id < MAX_SEGMENTS; ++segment_id) {
250b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    const int qindex = clamp(vp9_get_qindex(&cm->seg, segment_id,
251b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                            cm->base_qindex) + cm->y_dc_delta_q,
252b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                             0, MAXQ);
253b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    const int q = compute_rd_thresh_factor(qindex);
254ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2551184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    for (bsize = 0; bsize < BLOCK_SIZES; ++bsize) {
256b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      // Threshold here seems unnecessarily harsh but fine given actual
257b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      // range of values used for cpi->sf.thresh_mult[].
258b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      const int t = q * rd_thresh_block_size_factor[bsize];
259b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      const int thresh_max = INT_MAX / t;
260b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
261b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      for (i = 0; i < MAX_MODES; ++i)
262b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        cpi->rd_threshes[segment_id][bsize][i] =
2636ac915abcdb404a00d927fe6308a47fcf09d9519hkuang            cpi->rd_thresh_mult[i] < thresh_max ? cpi->rd_thresh_mult[i] * t / 4
264b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                            : INT_MAX;
265ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2665ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      for (i = 0; i < MAX_REFS; ++i) {
267b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        cpi->rd_thresh_sub8x8[segment_id][bsize][i] =
2686ac915abcdb404a00d927fe6308a47fcf09d9519hkuang            cpi->rd_thresh_mult_sub8x8[i] < thresh_max
2696ac915abcdb404a00d927fe6308a47fcf09d9519hkuang                ? cpi->rd_thresh_mult_sub8x8[i] * t / 4
270b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                : INT_MAX;
271ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
272ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
273ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
2745ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang}
2755ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
2765ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangvoid vp9_initialize_rd_consts(VP9_COMP *cpi) {
277b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  VP9_COMMON *const cm = &cpi->common;
278b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  MACROBLOCK *const x = &cpi->mb;
279b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int i;
2805ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
281b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  vp9_clear_system_state();
2825ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
2835ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  cpi->RDDIV = RDDIV_BITS;  // in bits (to multiply D by 128)
284b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  cpi->RDMULT = vp9_compute_rd_mult(cpi, cm->base_qindex + cm->y_dc_delta_q);
285ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
286b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  x->errorperbit = cpi->RDMULT / RD_MULT_EPB_RATIO;
287b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  x->errorperbit += (x->errorperbit == 0);
2885ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
289b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  x->select_txfm_size = (cpi->sf.tx_size_search_method == USE_LARGESTALL &&
290b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                         cm->frame_type != KEY_FRAME) ? 0 : 1;
2919b35249446b07f40ac5fcc3205f2c048616efacchkuang
2925ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  set_block_thresholds(cpi);
293ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
294b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (!cpi->sf.use_nonrd_pick_mode || cm->frame_type == KEY_FRAME) {
295b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    fill_token_costs(x->token_costs, cm->fc.coef_probs);
296ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
297b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    for (i = 0; i < PARTITION_CONTEXTS; i++)
298b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      vp9_cost_tokens(x->partition_cost[i], get_partition_probs(cm, i),
299b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                      vp9_partition_tree);
300b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  }
301ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
302b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (!cpi->sf.use_nonrd_pick_mode || (cm->current_video_frame & 0x07) == 1 ||
303b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      cm->frame_type == KEY_FRAME) {
304b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    fill_mode_costs(cpi);
30591037db265ecdd914a26e056cf69207b4f50924ehkuang
306b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (!frame_is_intra_only(cm)) {
307b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      vp9_build_nmv_cost_table(x->nmvjointcost,
308b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                               cm->allow_high_precision_mv ? x->nmvcost_hp
309b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                                           : x->nmvcost,
310b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                               &cm->fc.nmvc, cm->allow_high_precision_mv);
31191037db265ecdd914a26e056cf69207b4f50924ehkuang
312b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      for (i = 0; i < INTER_MODE_CONTEXTS; ++i)
313b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        vp9_cost_tokens((int *)x->inter_mode_cost[i],
314b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                        cm->fc.inter_mode_probs[i], vp9_inter_mode_tree);
31591037db265ecdd914a26e056cf69207b4f50924ehkuang    }
31691037db265ecdd914a26e056cf69207b4f50924ehkuang  }
31791037db265ecdd914a26e056cf69207b4f50924ehkuang}
31891037db265ecdd914a26e056cf69207b4f50924ehkuang
319b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic const int MAX_XSQ_Q10 = 245727;
32091037db265ecdd914a26e056cf69207b4f50924ehkuang
321b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic void model_rd_norm(int xsq_q10, int *r_q10, int *d_q10) {
32291037db265ecdd914a26e056cf69207b4f50924ehkuang  // NOTE: The tables below must be of the same size
323b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
324b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  // The functions described below are sampled at the four most significant
325b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  // bits of x^2 + 8 / 256
326b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
32791037db265ecdd914a26e056cf69207b4f50924ehkuang  // Normalized rate
32891037db265ecdd914a26e056cf69207b4f50924ehkuang  // This table models the rate for a Laplacian source
32991037db265ecdd914a26e056cf69207b4f50924ehkuang  // source with given variance when quantized with a uniform quantizer
33091037db265ecdd914a26e056cf69207b4f50924ehkuang  // with given stepsize. The closed form expression is:
33191037db265ecdd914a26e056cf69207b4f50924ehkuang  // Rn(x) = H(sqrt(r)) + sqrt(r)*[1 + H(r)/(1 - r)],
33291037db265ecdd914a26e056cf69207b4f50924ehkuang  // where r = exp(-sqrt(2) * x) and x = qpstep / sqrt(variance),
33391037db265ecdd914a26e056cf69207b4f50924ehkuang  // and H(x) is the binary entropy function.
334b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  static const int rate_tab_q10[] = {
335b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    65536,  6086,  5574,  5275,  5063,  4899,  4764,  4651,
336b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian     4553,  4389,  4255,  4142,  4044,  3958,  3881,  3811,
337b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian     3748,  3635,  3538,  3453,  3376,  3307,  3244,  3186,
338b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian     3133,  3037,  2952,  2877,  2809,  2747,  2690,  2638,
339b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian     2589,  2501,  2423,  2353,  2290,  2232,  2179,  2130,
340b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian     2084,  2001,  1928,  1862,  1802,  1748,  1698,  1651,
341b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian     1608,  1530,  1460,  1398,  1342,  1290,  1243,  1199,
342b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian     1159,  1086,  1021,   963,   911,   864,   821,   781,
343b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      745,   680,   623,   574,   530,   490,   455,   424,
344b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      395,   345,   304,   269,   239,   213,   190,   171,
345b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      154,   126,   104,    87,    73,    61,    52,    44,
346b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian       38,    28,    21,    16,    12,    10,     8,     6,
347b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        5,     3,     2,     1,     1,     1,     0,     0,
34891037db265ecdd914a26e056cf69207b4f50924ehkuang  };
34991037db265ecdd914a26e056cf69207b4f50924ehkuang  // Normalized distortion
35091037db265ecdd914a26e056cf69207b4f50924ehkuang  // This table models the normalized distortion for a Laplacian source
35191037db265ecdd914a26e056cf69207b4f50924ehkuang  // source with given variance when quantized with a uniform quantizer
35291037db265ecdd914a26e056cf69207b4f50924ehkuang  // with given stepsize. The closed form expression is:
35391037db265ecdd914a26e056cf69207b4f50924ehkuang  // Dn(x) = 1 - 1/sqrt(2) * x / sinh(x/sqrt(2))
35491037db265ecdd914a26e056cf69207b4f50924ehkuang  // where x = qpstep / sqrt(variance)
35591037db265ecdd914a26e056cf69207b4f50924ehkuang  // Note the actual distortion is Dn * variance.
356b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  static const int dist_tab_q10[] = {
357b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian       0,     0,     1,     1,     1,     2,     2,     2,
358b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian       3,     3,     4,     5,     5,     6,     7,     7,
359b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian       8,     9,    11,    12,    13,    15,    16,    17,
360b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      18,    21,    24,    26,    29,    31,    34,    36,
361b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      39,    44,    49,    54,    59,    64,    69,    73,
362b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      78,    88,    97,   106,   115,   124,   133,   142,
363b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian     151,   167,   184,   200,   215,   231,   245,   260,
364b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian     274,   301,   327,   351,   375,   397,   418,   439,
365b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian     458,   495,   528,   559,   587,   613,   637,   659,
366b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian     680,   717,   749,   777,   801,   823,   842,   859,
367b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian     874,   899,   919,   936,   949,   960,   969,   977,
368b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian     983,   994,  1001,  1006,  1010,  1013,  1015,  1017,
369b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    1018,  1020,  1022,  1022,  1023,  1023,  1023,  1024,
370b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  };
371b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  static const int xsq_iq_q10[] = {
372b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian         0,      4,      8,     12,     16,     20,     24,     28,
373b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        32,     40,     48,     56,     64,     72,     80,     88,
374b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        96,    112,    128,    144,    160,    176,    192,    208,
375b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian       224,    256,    288,    320,    352,    384,    416,    448,
376b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian       480,    544,    608,    672,    736,    800,    864,    928,
377b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian       992,   1120,   1248,   1376,   1504,   1632,   1760,   1888,
378b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      2016,   2272,   2528,   2784,   3040,   3296,   3552,   3808,
379b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      4064,   4576,   5088,   5600,   6112,   6624,   7136,   7648,
380b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      8160,   9184,  10208,  11232,  12256,  13280,  14304,  15328,
381b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian     16352,  18400,  20448,  22496,  24544,  26592,  28640,  30688,
382b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian     32736,  36832,  40928,  45024,  49120,  53216,  57312,  61408,
383b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian     65504,  73696,  81888,  90080,  98272, 106464, 114656, 122848,
384b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    131040, 147424, 163808, 180192, 196576, 212960, 229344, 245728,
38591037db265ecdd914a26e056cf69207b4f50924ehkuang  };
38691037db265ecdd914a26e056cf69207b4f50924ehkuang  /*
387b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  static const int tab_size = sizeof(rate_tab_q10) / sizeof(rate_tab_q10[0]);
388b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  assert(sizeof(dist_tab_q10) / sizeof(dist_tab_q10[0]) == tab_size);
389b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  assert(sizeof(xsq_iq_q10) / sizeof(xsq_iq_q10[0]) == tab_size);
390b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  assert(MAX_XSQ_Q10 + 1 == xsq_iq_q10[tab_size - 1]);
39191037db265ecdd914a26e056cf69207b4f50924ehkuang  */
392b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int tmp = (xsq_q10 >> 2) + 8;
393b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int k = get_msb(tmp) - 3;
394b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int xq = (k << 3) + ((tmp >> k) & 0x7);
395b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int one_q10 = 1 << 10;
396b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int a_q10 = ((xsq_q10 - xsq_iq_q10[xq]) << 10) >> (2 + k);
397b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int b_q10 = one_q10 - a_q10;
398b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  *r_q10 = (rate_tab_q10[xq] * b_q10 + rate_tab_q10[xq + 1] * a_q10) >> 10;
399b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  *d_q10 = (dist_tab_q10[xq] * b_q10 + dist_tab_q10[xq + 1] * a_q10) >> 10;
40091037db265ecdd914a26e056cf69207b4f50924ehkuang}
40191037db265ecdd914a26e056cf69207b4f50924ehkuang
402b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianvoid vp9_model_rd_from_var_lapndz(unsigned int var, unsigned int n,
403b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                  unsigned int qstep, int *rate,
404b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                  int64_t *dist) {
40591037db265ecdd914a26e056cf69207b4f50924ehkuang  // This function models the rate and distortion for a Laplacian
40691037db265ecdd914a26e056cf69207b4f50924ehkuang  // source with given variance when quantized with a uniform quantizer
40791037db265ecdd914a26e056cf69207b4f50924ehkuang  // with given stepsize. The closed form expressions are in:
40891037db265ecdd914a26e056cf69207b4f50924ehkuang  // Hang and Chen, "Source Model for transform video coder and its
40991037db265ecdd914a26e056cf69207b4f50924ehkuang  // application - Part I: Fundamental Theory", IEEE Trans. Circ.
41091037db265ecdd914a26e056cf69207b4f50924ehkuang  // Sys. for Video Tech., April 1997.
411b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (var == 0) {
41291037db265ecdd914a26e056cf69207b4f50924ehkuang    *rate = 0;
41391037db265ecdd914a26e056cf69207b4f50924ehkuang    *dist = 0;
41491037db265ecdd914a26e056cf69207b4f50924ehkuang  } else {
415b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    int d_q10, r_q10;
416b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    const uint64_t xsq_q10_64 =
417b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        ((((uint64_t)qstep * qstep * n) << 10) + (var >> 1)) / var;
418b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    const int xsq_q10 = xsq_q10_64 > MAX_XSQ_Q10 ?
419b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                        MAX_XSQ_Q10 : (int)xsq_q10_64;
420b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    model_rd_norm(xsq_q10, &r_q10, &d_q10);
421b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    *rate = (n * r_q10 + 2) >> 2;
422b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    *dist = (var * (int64_t)d_q10 + 512) >> 10;
42391037db265ecdd914a26e056cf69207b4f50924ehkuang  }
42491037db265ecdd914a26e056cf69207b4f50924ehkuang}
42591037db265ecdd914a26e056cf69207b4f50924ehkuang
4261184aebb761cbeac9124c37189a80a1a58f04b6bhkuangstatic void model_rd_for_sb(VP9_COMP *cpi, BLOCK_SIZE bsize,
42791037db265ecdd914a26e056cf69207b4f50924ehkuang                            MACROBLOCK *x, MACROBLOCKD *xd,
42891037db265ecdd914a26e056cf69207b4f50924ehkuang                            int *out_rate_sum, int64_t *out_dist_sum) {
42991037db265ecdd914a26e056cf69207b4f50924ehkuang  // Note our transform coeffs are 8 times an orthogonal transform.
43091037db265ecdd914a26e056cf69207b4f50924ehkuang  // Hence quantizer step is also 8 times. To get effective quantizer
43191037db265ecdd914a26e056cf69207b4f50924ehkuang  // we need to divide by 8 before sending to modeling function.
432b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int i;
433b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int64_t rate_sum = 0;
434b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int64_t dist_sum = 0;
4356ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  const int ref = xd->mi[0]->mbmi.ref_frame[0];
436b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  unsigned int sse;
43791037db265ecdd914a26e056cf69207b4f50924ehkuang
43891037db265ecdd914a26e056cf69207b4f50924ehkuang  for (i = 0; i < MAX_MB_PLANE; ++i) {
43991037db265ecdd914a26e056cf69207b4f50924ehkuang    struct macroblock_plane *const p = &x->plane[i];
44091037db265ecdd914a26e056cf69207b4f50924ehkuang    struct macroblockd_plane *const pd = &xd->plane[i];
4411184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    const BLOCK_SIZE bs = get_plane_block_size(bsize, pd);
442b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
44391037db265ecdd914a26e056cf69207b4f50924ehkuang    (void) cpi->fn_ptr[bs].vf(p->src.buf, p->src.stride,
44491037db265ecdd914a26e056cf69207b4f50924ehkuang                              pd->dst.buf, pd->dst.stride, &sse);
44591037db265ecdd914a26e056cf69207b4f50924ehkuang
446b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (i == 0)
447b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      x->pred_sse[ref] = sse;
448b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
449b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    // Fast approximate the modelling function.
450b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (cpi->speed > 4) {
451b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      int64_t rate;
452b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      int64_t dist;
453b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      int64_t square_error = sse;
454b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      int quantizer = (pd->dequant[1] >> 3);
455b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
456b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (quantizer < 120)
457b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        rate = (square_error * (280 - quantizer)) >> 8;
458b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      else
459b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        rate = 0;
460b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      dist = (square_error * quantizer) >> 8;
461b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      rate_sum += rate;
462b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      dist_sum += dist;
463b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    } else {
464b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      int rate;
465b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      int64_t dist;
466b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      vp9_model_rd_from_var_lapndz(sse, 1 << num_pels_log2_lookup[bs],
467b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                   pd->dequant[1] >> 3, &rate, &dist);
468b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      rate_sum += rate;
469b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      dist_sum += dist;
470b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    }
47191037db265ecdd914a26e056cf69207b4f50924ehkuang  }
47291037db265ecdd914a26e056cf69207b4f50924ehkuang
473b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  *out_rate_sum = (int)rate_sum;
47491037db265ecdd914a26e056cf69207b4f50924ehkuang  *out_dist_sum = dist_sum << 4;
47591037db265ecdd914a26e056cf69207b4f50924ehkuang}
47691037db265ecdd914a26e056cf69207b4f50924ehkuang
4771184aebb761cbeac9124c37189a80a1a58f04b6bhkuangstatic void model_rd_for_sb_y_tx(VP9_COMP *cpi, BLOCK_SIZE bsize,
47891037db265ecdd914a26e056cf69207b4f50924ehkuang                                 TX_SIZE tx_size,
47991037db265ecdd914a26e056cf69207b4f50924ehkuang                                 MACROBLOCK *x, MACROBLOCKD *xd,
48091037db265ecdd914a26e056cf69207b4f50924ehkuang                                 int *out_rate_sum, int64_t *out_dist_sum,
48191037db265ecdd914a26e056cf69207b4f50924ehkuang                                 int *out_skip) {
4821184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int j, k;
4831184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  BLOCK_SIZE bs;
484b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const struct macroblock_plane *const p = &x->plane[0];
485b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const struct macroblockd_plane *const pd = &xd->plane[0];
486b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int width = 4 * num_4x4_blocks_wide_lookup[bsize];
487b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int height = 4 * num_4x4_blocks_high_lookup[bsize];
48891037db265ecdd914a26e056cf69207b4f50924ehkuang  int rate_sum = 0;
48991037db265ecdd914a26e056cf69207b4f50924ehkuang  int64_t dist_sum = 0;
4901184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const int t = 4 << tx_size;
49191037db265ecdd914a26e056cf69207b4f50924ehkuang
49291037db265ecdd914a26e056cf69207b4f50924ehkuang  if (tx_size == TX_4X4) {
49391037db265ecdd914a26e056cf69207b4f50924ehkuang    bs = BLOCK_4X4;
49491037db265ecdd914a26e056cf69207b4f50924ehkuang  } else if (tx_size == TX_8X8) {
49591037db265ecdd914a26e056cf69207b4f50924ehkuang    bs = BLOCK_8X8;
49691037db265ecdd914a26e056cf69207b4f50924ehkuang  } else if (tx_size == TX_16X16) {
49791037db265ecdd914a26e056cf69207b4f50924ehkuang    bs = BLOCK_16X16;
49891037db265ecdd914a26e056cf69207b4f50924ehkuang  } else if (tx_size == TX_32X32) {
49991037db265ecdd914a26e056cf69207b4f50924ehkuang    bs = BLOCK_32X32;
50091037db265ecdd914a26e056cf69207b4f50924ehkuang  } else {
50191037db265ecdd914a26e056cf69207b4f50924ehkuang    assert(0);
50291037db265ecdd914a26e056cf69207b4f50924ehkuang  }
5031184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
50491037db265ecdd914a26e056cf69207b4f50924ehkuang  *out_skip = 1;
50591037db265ecdd914a26e056cf69207b4f50924ehkuang  for (j = 0; j < height; j += t) {
50691037db265ecdd914a26e056cf69207b4f50924ehkuang    for (k = 0; k < width; k += t) {
50791037db265ecdd914a26e056cf69207b4f50924ehkuang      int rate;
50891037db265ecdd914a26e056cf69207b4f50924ehkuang      int64_t dist;
50991037db265ecdd914a26e056cf69207b4f50924ehkuang      unsigned int sse;
5101184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      cpi->fn_ptr[bs].vf(&p->src.buf[j * p->src.stride + k], p->src.stride,
5111184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                         &pd->dst.buf[j * pd->dst.stride + k], pd->dst.stride,
5121184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                         &sse);
51391037db265ecdd914a26e056cf69207b4f50924ehkuang      // sse works better than var, since there is no dc prediction used
514b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      vp9_model_rd_from_var_lapndz(sse, t * t, pd->dequant[1] >> 3,
515b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                   &rate, &dist);
51691037db265ecdd914a26e056cf69207b4f50924ehkuang      rate_sum += rate;
51791037db265ecdd914a26e056cf69207b4f50924ehkuang      dist_sum += dist;
51891037db265ecdd914a26e056cf69207b4f50924ehkuang      *out_skip &= (rate < 1024);
51991037db265ecdd914a26e056cf69207b4f50924ehkuang    }
520ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
5211184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
52291037db265ecdd914a26e056cf69207b4f50924ehkuang  *out_rate_sum = rate_sum;
5231184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  *out_dist_sum = dist_sum << 4;
524ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
525ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
526b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianint64_t vp9_block_error_c(const int16_t *coeff, const int16_t *dqcoeff,
52791037db265ecdd914a26e056cf69207b4f50924ehkuang                          intptr_t block_size, int64_t *ssz) {
52891037db265ecdd914a26e056cf69207b4f50924ehkuang  int i;
52991037db265ecdd914a26e056cf69207b4f50924ehkuang  int64_t error = 0, sqcoeff = 0;
530ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
531ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0; i < block_size; i++) {
532b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    const int diff = coeff[i] - dqcoeff[i];
533b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    error +=  diff * diff;
534b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    sqcoeff += coeff[i] * coeff[i];
535ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
536ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
53791037db265ecdd914a26e056cf69207b4f50924ehkuang  *ssz = sqcoeff;
538ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return error;
539ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
540ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
541f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang/* The trailing '0' is a terminator which is used inside cost_coeffs() to
542f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang * decide whether to include cost of a trailing EOB node or not (i.e. we
543f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang * can skip this if the last coefficient in this transform block, e.g. the
544f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang * 16th coefficient in a 4x4 block or the 64th coefficient in a 8x8 block,
545f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang * were non-zero). */
546f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuangstatic const int16_t band_counts[TX_SIZES][8] = {
547f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  { 1, 2, 3, 4,  3,   16 - 13, 0 },
548f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  { 1, 2, 3, 4, 11,   64 - 21, 0 },
549f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  { 1, 2, 3, 4, 11,  256 - 21, 0 },
550f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  { 1, 2, 3, 4, 11, 1024 - 21, 0 },
55191037db265ecdd914a26e056cf69207b4f50924ehkuang};
5525ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangstatic INLINE int cost_coeffs(MACROBLOCK *x,
5531184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                              int plane, int block,
55491037db265ecdd914a26e056cf69207b4f50924ehkuang                              ENTROPY_CONTEXT *A, ENTROPY_CONTEXT *L,
555ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                              TX_SIZE tx_size,
556b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                              const int16_t *scan, const int16_t *nb,
557b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                              int use_fast_coef_costing) {
5585ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MACROBLOCKD *const xd = &x->e_mbd;
5596ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
560b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const struct macroblock_plane *p = &x->plane[plane];
561b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const struct macroblockd_plane *pd = &xd->plane[plane];
5621184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const PLANE_TYPE type = pd->plane_type;
563f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  const int16_t *band_count = &band_counts[tx_size][1];
564b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int eob = p->eobs[block];
565b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int16_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
566b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  unsigned int (*token_costs)[2][COEFF_CONTEXTS][ENTROPY_TOKENS] =
567b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                   x->token_costs[tx_size][type][is_inter_block(mbmi)];
5686ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  uint8_t token_cache[32 * 32];
569b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int pt = combine_entropy_contexts(*A, *L);
5701184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int c, cost;
571ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Check for consistency of tx_size with mode info
572b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  assert(type == PLANE_TYPE_Y ? mbmi->tx_size == tx_size
573b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                              : get_uv_tx_size(mbmi) == tx_size);
57491037db265ecdd914a26e056cf69207b4f50924ehkuang
57591037db265ecdd914a26e056cf69207b4f50924ehkuang  if (eob == 0) {
57691037db265ecdd914a26e056cf69207b4f50924ehkuang    // single eob token
577b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    cost = token_costs[0][0][pt][EOB_TOKEN];
57891037db265ecdd914a26e056cf69207b4f50924ehkuang    c = 0;
57991037db265ecdd914a26e056cf69207b4f50924ehkuang  } else {
5801184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    int band_left = *band_count++;
58191037db265ecdd914a26e056cf69207b4f50924ehkuang
58291037db265ecdd914a26e056cf69207b4f50924ehkuang    // dc token
583b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    int v = qcoeff[0];
5841184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    int prev_t = vp9_dct_value_tokens_ptr[v].token;
585f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    cost = (*token_costs)[0][pt][prev_t] + vp9_dct_value_cost_ptr[v];
5866ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    token_cache[0] = vp9_pt_energy_class[prev_t];
587f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    ++token_costs;
58891037db265ecdd914a26e056cf69207b4f50924ehkuang
58991037db265ecdd914a26e056cf69207b4f50924ehkuang    // ac tokens
59091037db265ecdd914a26e056cf69207b4f50924ehkuang    for (c = 1; c < eob; c++) {
59191037db265ecdd914a26e056cf69207b4f50924ehkuang      const int rc = scan[c];
59291037db265ecdd914a26e056cf69207b4f50924ehkuang      int t;
59391037db265ecdd914a26e056cf69207b4f50924ehkuang
594b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      v = qcoeff[rc];
59591037db265ecdd914a26e056cf69207b4f50924ehkuang      t = vp9_dct_value_tokens_ptr[v].token;
596b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (use_fast_coef_costing) {
597b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        cost += (*token_costs)[!prev_t][!prev_t][t] + vp9_dct_value_cost_ptr[v];
598b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      } else {
5996ac915abcdb404a00d927fe6308a47fcf09d9519hkuang        pt = get_coef_context(nb, token_cache, c);
600b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        cost += (*token_costs)[!prev_t][pt][t] + vp9_dct_value_cost_ptr[v];
6016ac915abcdb404a00d927fe6308a47fcf09d9519hkuang        token_cache[rc] = vp9_pt_energy_class[t];
602b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      }
60391037db265ecdd914a26e056cf69207b4f50924ehkuang      prev_t = t;
60491037db265ecdd914a26e056cf69207b4f50924ehkuang      if (!--band_left) {
605f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        band_left = *band_count++;
606f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        ++token_costs;
60791037db265ecdd914a26e056cf69207b4f50924ehkuang      }
60891037db265ecdd914a26e056cf69207b4f50924ehkuang    }
60991037db265ecdd914a26e056cf69207b4f50924ehkuang
61091037db265ecdd914a26e056cf69207b4f50924ehkuang    // eob token
611f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    if (band_left) {
612b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (use_fast_coef_costing) {
613b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        cost += (*token_costs)[0][!prev_t][EOB_TOKEN];
614b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      } else {
6156ac915abcdb404a00d927fe6308a47fcf09d9519hkuang        pt = get_coef_context(nb, token_cache, c);
616b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        cost += (*token_costs)[0][pt][EOB_TOKEN];
617b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      }
61891037db265ecdd914a26e056cf69207b4f50924ehkuang    }
619ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
620ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
62191037db265ecdd914a26e056cf69207b4f50924ehkuang  // is eob first coefficient;
6221184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  *A = *L = (c > 0);
62391037db265ecdd914a26e056cf69207b4f50924ehkuang
62491037db265ecdd914a26e056cf69207b4f50924ehkuang  return cost;
62591037db265ecdd914a26e056cf69207b4f50924ehkuang}
626b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic void dist_block(int plane, int block, TX_SIZE tx_size,
627b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                       struct rdcost_block_args* args) {
6281184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const int ss_txfrm_size = tx_size << 1;
62991037db265ecdd914a26e056cf69207b4f50924ehkuang  MACROBLOCK* const x = args->x;
63091037db265ecdd914a26e056cf69207b4f50924ehkuang  MACROBLOCKD* const xd = &x->e_mbd;
631b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const struct macroblock_plane *const p = &x->plane[plane];
632b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const struct macroblockd_plane *const pd = &xd->plane[plane];
63391037db265ecdd914a26e056cf69207b4f50924ehkuang  int64_t this_sse;
634b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int shift = tx_size == TX_32X32 ? 0 : 2;
6351184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int16_t *const coeff = BLOCK_OFFSET(p->coeff, block);
6361184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int16_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
6375ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  args->dist = vp9_block_error(coeff, dqcoeff, 16 << ss_txfrm_size,
6385ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                               &this_sse) >> shift;
6395ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  args->sse  = this_sse >> shift;
64091037db265ecdd914a26e056cf69207b4f50924ehkuang
6416ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  if (x->skip_encode && !is_inter_block(&xd->mi[0]->mbmi)) {
64291037db265ecdd914a26e056cf69207b4f50924ehkuang    // TODO(jingning): tune the model to better capture the distortion.
64391037db265ecdd914a26e056cf69207b4f50924ehkuang    int64_t p = (pd->dequant[1] * pd->dequant[1] *
6445ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                    (1 << ss_txfrm_size)) >> (shift + 2);
6455ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    args->dist += (p >> 4);
64691037db265ecdd914a26e056cf69207b4f50924ehkuang    args->sse  += p;
64791037db265ecdd914a26e056cf69207b4f50924ehkuang  }
64891037db265ecdd914a26e056cf69207b4f50924ehkuang}
64991037db265ecdd914a26e056cf69207b4f50924ehkuang
6501184aebb761cbeac9124c37189a80a1a58f04b6bhkuangstatic void rate_block(int plane, int block, BLOCK_SIZE plane_bsize,
651b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                       TX_SIZE tx_size, struct rdcost_block_args* args) {
6521184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int x_idx, y_idx;
653b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &x_idx, &y_idx);
65491037db265ecdd914a26e056cf69207b4f50924ehkuang
6555ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  args->rate = cost_coeffs(args->x, plane, block, args->t_above + x_idx,
656b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                           args->t_left + y_idx, tx_size,
657b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                           args->so->scan, args->so->neighbors,
658b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                           args->use_fast_coef_costing);
65991037db265ecdd914a26e056cf69207b4f50924ehkuang}
66091037db265ecdd914a26e056cf69207b4f50924ehkuang
661b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic void block_rd_txfm(int plane, int block, BLOCK_SIZE plane_bsize,
662b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                          TX_SIZE tx_size, void *arg) {
66391037db265ecdd914a26e056cf69207b4f50924ehkuang  struct rdcost_block_args *args = arg;
66491037db265ecdd914a26e056cf69207b4f50924ehkuang  MACROBLOCK *const x = args->x;
66591037db265ecdd914a26e056cf69207b4f50924ehkuang  MACROBLOCKD *const xd = &x->e_mbd;
6666ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
66791037db265ecdd914a26e056cf69207b4f50924ehkuang  int64_t rd1, rd2, rd;
66891037db265ecdd914a26e056cf69207b4f50924ehkuang
66991037db265ecdd914a26e056cf69207b4f50924ehkuang  if (args->skip)
67091037db265ecdd914a26e056cf69207b4f50924ehkuang    return;
67191037db265ecdd914a26e056cf69207b4f50924ehkuang
672b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (!is_inter_block(mbmi))
673b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    vp9_encode_block_intra(x, plane, block, plane_bsize, tx_size, &mbmi->skip);
67491037db265ecdd914a26e056cf69207b4f50924ehkuang  else
675b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    vp9_xform_quant(x, plane, block, plane_bsize, tx_size);
67691037db265ecdd914a26e056cf69207b4f50924ehkuang
6771184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  dist_block(plane, block, tx_size, args);
6781184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  rate_block(plane, block, plane_bsize, tx_size, args);
6795ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  rd1 = RDCOST(x->rdmult, x->rddiv, args->rate, args->dist);
6805ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  rd2 = RDCOST(x->rdmult, x->rddiv, 0, args->sse);
68191037db265ecdd914a26e056cf69207b4f50924ehkuang
6825ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // TODO(jingning): temporarily enabled only for luma component
6835ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  rd = MIN(rd1, rd2);
684b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (plane == 0)
685b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    x->zcoeff_blk[tx_size][block] = !x->plane[plane].eobs[block] ||
686b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                    (rd1 > rd2 && !xd->lossless);
6875ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
6885ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  args->this_rate += args->rate;
6895ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  args->this_dist += args->dist;
6905ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  args->this_sse  += args->sse;
6915ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  args->this_rd += rd;
6925ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
6935ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (args->this_rd > args->best_rd) {
6945ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    args->skip = 1;
6955ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    return;
6965ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
6975ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang}
6981184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
699b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianvoid vp9_get_entropy_contexts(BLOCK_SIZE bsize, TX_SIZE tx_size,
700b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                              const struct macroblockd_plane *pd,
701b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                              ENTROPY_CONTEXT t_above[16],
702b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                              ENTROPY_CONTEXT t_left[16]) {
703b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
704b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int num_4x4_w = num_4x4_blocks_wide_lookup[plane_bsize];
705b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int num_4x4_h = num_4x4_blocks_high_lookup[plane_bsize];
706b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const ENTROPY_CONTEXT *const above = pd->above_context;
707b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const ENTROPY_CONTEXT *const left = pd->left_context;
708b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
7095ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int i;
71091037db265ecdd914a26e056cf69207b4f50924ehkuang  switch (tx_size) {
71191037db265ecdd914a26e056cf69207b4f50924ehkuang    case TX_4X4:
7125ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      vpx_memcpy(t_above, above, sizeof(ENTROPY_CONTEXT) * num_4x4_w);
7135ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      vpx_memcpy(t_left, left, sizeof(ENTROPY_CONTEXT) * num_4x4_h);
71491037db265ecdd914a26e056cf69207b4f50924ehkuang      break;
71591037db265ecdd914a26e056cf69207b4f50924ehkuang    case TX_8X8:
7165ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      for (i = 0; i < num_4x4_w; i += 2)
7175ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        t_above[i] = !!*(const uint16_t *)&above[i];
7185ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      for (i = 0; i < num_4x4_h; i += 2)
7195ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        t_left[i] = !!*(const uint16_t *)&left[i];
72091037db265ecdd914a26e056cf69207b4f50924ehkuang      break;
72191037db265ecdd914a26e056cf69207b4f50924ehkuang    case TX_16X16:
7225ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      for (i = 0; i < num_4x4_w; i += 4)
7235ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        t_above[i] = !!*(const uint32_t *)&above[i];
7245ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      for (i = 0; i < num_4x4_h; i += 4)
7255ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        t_left[i] = !!*(const uint32_t *)&left[i];
72691037db265ecdd914a26e056cf69207b4f50924ehkuang      break;
72791037db265ecdd914a26e056cf69207b4f50924ehkuang    case TX_32X32:
7285ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      for (i = 0; i < num_4x4_w; i += 8)
7295ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        t_above[i] = !!*(const uint64_t *)&above[i];
7305ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      for (i = 0; i < num_4x4_h; i += 8)
7315ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        t_left[i] = !!*(const uint64_t *)&left[i];
73291037db265ecdd914a26e056cf69207b4f50924ehkuang      break;
73391037db265ecdd914a26e056cf69207b4f50924ehkuang    default:
734b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      assert(0 && "Invalid transform size.");
73591037db265ecdd914a26e056cf69207b4f50924ehkuang  }
7365ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang}
7375ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
7385ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangstatic void txfm_rd_in_plane(MACROBLOCK *x,
7395ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                             int *rate, int64_t *distortion,
7405ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                             int *skippable, int64_t *sse,
7415ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                             int64_t ref_best_rd, int plane,
742b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                             BLOCK_SIZE bsize, TX_SIZE tx_size,
743b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                             int use_fast_coef_casting) {
7445ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MACROBLOCKD *const xd = &x->e_mbd;
745b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const struct macroblockd_plane *const pd = &xd->plane[plane];
746b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  struct rdcost_block_args args = { 0 };
747b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  args.x = x;
748b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  args.best_rd = ref_best_rd;
749b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  args.use_fast_coef_costing = use_fast_coef_casting;
75091037db265ecdd914a26e056cf69207b4f50924ehkuang
7515ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (plane == 0)
7526ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    xd->mi[0]->mbmi.tx_size = tx_size;
7535ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
754b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  vp9_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
7555ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
756b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  args.so = get_scan(xd, tx_size, pd->plane_type, 0);
7575ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
758b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  vp9_foreach_transformed_block_in_plane(xd, bsize, plane,
759b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                         block_rd_txfm, &args);
760b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (args.skip) {
7615ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    *rate       = INT_MAX;
7625ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    *distortion = INT64_MAX;
7635ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    *sse        = INT64_MAX;
7645ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    *skippable  = 0;
7655ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  } else {
766b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    *distortion = args.this_dist;
767b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    *rate       = args.this_rate;
768b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    *sse        = args.this_sse;
769b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    *skippable  = vp9_is_skippable_in_plane(x, bsize, plane);
7705ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
77191037db265ecdd914a26e056cf69207b4f50924ehkuang}
77291037db265ecdd914a26e056cf69207b4f50924ehkuang
77391037db265ecdd914a26e056cf69207b4f50924ehkuangstatic void choose_largest_txfm_size(VP9_COMP *cpi, MACROBLOCK *x,
77491037db265ecdd914a26e056cf69207b4f50924ehkuang                                     int *rate, int64_t *distortion,
77591037db265ecdd914a26e056cf69207b4f50924ehkuang                                     int *skip, int64_t *sse,
77691037db265ecdd914a26e056cf69207b4f50924ehkuang                                     int64_t ref_best_rd,
7771184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                     BLOCK_SIZE bs) {
7785ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const TX_SIZE max_tx_size = max_txsize_lookup[bs];
77991037db265ecdd914a26e056cf69207b4f50924ehkuang  VP9_COMMON *const cm = &cpi->common;
7805ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const TX_SIZE largest_tx_size = tx_mode_to_biggest_tx_size[cm->tx_mode];
78191037db265ecdd914a26e056cf69207b4f50924ehkuang  MACROBLOCKD *const xd = &x->e_mbd;
7826ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7835ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
7845ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  mbmi->tx_size = MIN(max_tx_size, largest_tx_size);
7855ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
786b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  txfm_rd_in_plane(x, rate, distortion, skip,
7871184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                   &sse[mbmi->tx_size], ref_best_rd, 0, bs,
788b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                   mbmi->tx_size, cpi->sf.use_fast_coef_costing);
7895ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  cpi->tx_stepdown_count[0]++;
790ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
791ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
792ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void choose_txfm_size_from_rd(VP9_COMP *cpi, MACROBLOCK *x,
793ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                     int (*r)[2], int *rate,
79491037db265ecdd914a26e056cf69207b4f50924ehkuang                                     int64_t *d, int64_t *distortion,
795ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                     int *s, int *skip,
796f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                                     int64_t tx_cache[TX_MODES],
7971184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                     BLOCK_SIZE bs) {
7981184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const TX_SIZE max_tx_size = max_txsize_lookup[bs];
799ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  VP9_COMMON *const cm = &cpi->common;
800ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD *const xd = &x->e_mbd;
8016ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
802b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  vp9_prob skip_prob = vp9_get_skip_prob(cm, xd);
803b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int64_t rd[TX_SIZES][2] = {{INT64_MAX, INT64_MAX},
804b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                             {INT64_MAX, INT64_MAX},
805b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                             {INT64_MAX, INT64_MAX},
806b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                             {INT64_MAX, INT64_MAX}};
807ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int n, m;
808ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int s0, s1;
809b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const TX_SIZE max_mode_tx_size = tx_mode_to_biggest_tx_size[cm->tx_mode];
810b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int64_t best_rd = INT64_MAX;
811b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  TX_SIZE best_tx = TX_4X4;
812ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
8139b35249446b07f40ac5fcc3205f2c048616efacchkuang  const vp9_prob *tx_probs = get_tx_probs2(max_tx_size, xd, &cm->fc.tx_probs);
814ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  assert(skip_prob > 0);
815ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  s0 = vp9_cost_bit(skip_prob, 0);
816ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  s1 = vp9_cost_bit(skip_prob, 1);
817ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
818f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  for (n = TX_4X4; n <= max_tx_size; n++) {
819b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    r[n][1] = r[n][0];
820b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (r[n][0] < INT_MAX) {
821b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      for (m = 0; m <= n - (n == max_tx_size); m++) {
822b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        if (m == n)
823b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          r[n][1] += vp9_cost_zero(tx_probs[m]);
824b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        else
825b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          r[n][1] += vp9_cost_one(tx_probs[m]);
826b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      }
827b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    }
82891037db265ecdd914a26e056cf69207b4f50924ehkuang    if (d[n] == INT64_MAX) {
82991037db265ecdd914a26e056cf69207b4f50924ehkuang      rd[n][0] = rd[n][1] = INT64_MAX;
830b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    } else if (s[n]) {
831ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      rd[n][0] = rd[n][1] = RDCOST(x->rdmult, x->rddiv, s1, d[n]);
832ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    } else {
833ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      rd[n][0] = RDCOST(x->rdmult, x->rddiv, r[n][0] + s0, d[n]);
834ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      rd[n][1] = RDCOST(x->rdmult, x->rddiv, r[n][1] + s0, d[n]);
835ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
836ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
837b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (rd[n][1] < best_rd) {
838b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      best_tx = n;
839b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      best_rd = rd[n][1];
840b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    }
841ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
842b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  mbmi->tx_size = cm->tx_mode == TX_MODE_SELECT ?
843b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                      best_tx : MIN(max_tx_size, max_mode_tx_size);
844b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
845ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
8461184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  *distortion = d[mbmi->tx_size];
8471184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  *rate       = r[mbmi->tx_size][cm->tx_mode == TX_MODE_SELECT];
8481184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  *skip       = s[mbmi->tx_size];
849ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
850f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  tx_cache[ONLY_4X4] = rd[TX_4X4][0];
851f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  tx_cache[ALLOW_8X8] = rd[TX_8X8][0];
852f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  tx_cache[ALLOW_16X16] = rd[MIN(max_tx_size, TX_16X16)][0];
853f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  tx_cache[ALLOW_32X32] = rd[MIN(max_tx_size, TX_32X32)][0];
854ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
855b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (max_tx_size == TX_32X32 && best_tx == TX_32X32) {
856b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    tx_cache[TX_MODE_SELECT] = rd[TX_32X32][1];
8575ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    cpi->tx_stepdown_count[0]++;
858b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  } else if (max_tx_size >= TX_16X16 && best_tx == TX_16X16) {
859b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    tx_cache[TX_MODE_SELECT] = rd[TX_16X16][1];
8605ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    cpi->tx_stepdown_count[max_tx_size - TX_16X16]++;
86191037db265ecdd914a26e056cf69207b4f50924ehkuang  } else if (rd[TX_8X8][1] < rd[TX_4X4][1]) {
862b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    tx_cache[TX_MODE_SELECT] = rd[TX_8X8][1];
8635ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    cpi->tx_stepdown_count[max_tx_size - TX_8X8]++;
86491037db265ecdd914a26e056cf69207b4f50924ehkuang  } else {
865b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    tx_cache[TX_MODE_SELECT] = rd[TX_4X4][1];
8665ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    cpi->tx_stepdown_count[max_tx_size - TX_4X4]++;
867ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
868ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
869ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
870b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic int64_t scaled_rd_cost(int rdmult, int rddiv,
871b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                              int rate, int64_t dist, double scale) {
872b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  return (int64_t) (RDCOST(rdmult, rddiv, rate, dist) * scale);
873b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian}
874b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
87591037db265ecdd914a26e056cf69207b4f50924ehkuangstatic void choose_txfm_size_from_modelrd(VP9_COMP *cpi, MACROBLOCK *x,
87691037db265ecdd914a26e056cf69207b4f50924ehkuang                                          int (*r)[2], int *rate,
87791037db265ecdd914a26e056cf69207b4f50924ehkuang                                          int64_t *d, int64_t *distortion,
87891037db265ecdd914a26e056cf69207b4f50924ehkuang                                          int *s, int *skip, int64_t *sse,
87991037db265ecdd914a26e056cf69207b4f50924ehkuang                                          int64_t ref_best_rd,
8801184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                          BLOCK_SIZE bs) {
8815ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const TX_SIZE max_tx_size = max_txsize_lookup[bs];
88291037db265ecdd914a26e056cf69207b4f50924ehkuang  VP9_COMMON *const cm = &cpi->common;
88391037db265ecdd914a26e056cf69207b4f50924ehkuang  MACROBLOCKD *const xd = &x->e_mbd;
8846ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
885b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  vp9_prob skip_prob = vp9_get_skip_prob(cm, xd);
886b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int64_t rd[TX_SIZES][2] = {{INT64_MAX, INT64_MAX},
887b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                             {INT64_MAX, INT64_MAX},
888b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                             {INT64_MAX, INT64_MAX},
889b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                             {INT64_MAX, INT64_MAX}};
89091037db265ecdd914a26e056cf69207b4f50924ehkuang  int n, m;
89191037db265ecdd914a26e056cf69207b4f50924ehkuang  int s0, s1;
892f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  double scale_rd[TX_SIZES] = {1.73, 1.44, 1.20, 1.00};
893b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const TX_SIZE max_mode_tx_size = tx_mode_to_biggest_tx_size[cm->tx_mode];
894b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int64_t best_rd = INT64_MAX;
895b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  TX_SIZE best_tx = TX_4X4;
896ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
8979b35249446b07f40ac5fcc3205f2c048616efacchkuang  const vp9_prob *tx_probs = get_tx_probs2(max_tx_size, xd, &cm->fc.tx_probs);
898b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  assert(skip_prob > 0);
899b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  s0 = vp9_cost_bit(skip_prob, 0);
900b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  s1 = vp9_cost_bit(skip_prob, 1);
901ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
9025ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  for (n = TX_4X4; n <= max_tx_size; n++) {
903b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    double scale = scale_rd[n];
90491037db265ecdd914a26e056cf69207b4f50924ehkuang    r[n][1] = r[n][0];
9055ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    for (m = 0; m <= n - (n == max_tx_size); m++) {
90691037db265ecdd914a26e056cf69207b4f50924ehkuang      if (m == n)
90791037db265ecdd914a26e056cf69207b4f50924ehkuang        r[n][1] += vp9_cost_zero(tx_probs[m]);
90891037db265ecdd914a26e056cf69207b4f50924ehkuang      else
90991037db265ecdd914a26e056cf69207b4f50924ehkuang        r[n][1] += vp9_cost_one(tx_probs[m]);
91091037db265ecdd914a26e056cf69207b4f50924ehkuang    }
91191037db265ecdd914a26e056cf69207b4f50924ehkuang    if (s[n]) {
912b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      rd[n][0] = rd[n][1] = scaled_rd_cost(x->rdmult, x->rddiv, s1, d[n],
913b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                           scale);
91491037db265ecdd914a26e056cf69207b4f50924ehkuang    } else {
915b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      rd[n][0] = scaled_rd_cost(x->rdmult, x->rddiv, r[n][0] + s0, d[n],
916b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                scale);
917b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      rd[n][1] = scaled_rd_cost(x->rdmult, x->rddiv, r[n][1] + s0, d[n],
918b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                scale);
919b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    }
920b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (rd[n][1] < best_rd) {
921b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      best_rd = rd[n][1];
922b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      best_tx = n;
92391037db265ecdd914a26e056cf69207b4f50924ehkuang    }
924ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
925ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
926b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  mbmi->tx_size = cm->tx_mode == TX_MODE_SELECT ?
927b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                      best_tx : MIN(max_tx_size, max_mode_tx_size);
928ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
9291184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  // Actually encode using the chosen mode if a model was used, but do not
9301184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  // update the r, d costs
931b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  txfm_rd_in_plane(x, rate, distortion, skip,
932b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                   &sse[mbmi->tx_size], ref_best_rd, 0, bs, mbmi->tx_size,
933b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                   cpi->sf.use_fast_coef_costing);
934ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
935b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (max_tx_size == TX_32X32 && best_tx == TX_32X32) {
9365ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    cpi->tx_stepdown_count[0]++;
937b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  } else if (max_tx_size >= TX_16X16 &&  best_tx == TX_16X16) {
9385ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    cpi->tx_stepdown_count[max_tx_size - TX_16X16]++;
93991037db265ecdd914a26e056cf69207b4f50924ehkuang  } else if (rd[TX_8X8][1] <= rd[TX_4X4][1]) {
9405ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    cpi->tx_stepdown_count[max_tx_size - TX_8X8]++;
94191037db265ecdd914a26e056cf69207b4f50924ehkuang  } else {
9425ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    cpi->tx_stepdown_count[max_tx_size - TX_4X4]++;
94391037db265ecdd914a26e056cf69207b4f50924ehkuang  }
944ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
945ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
946b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic void inter_super_block_yrd(VP9_COMP *cpi, MACROBLOCK *x, int *rate,
947b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                  int64_t *distortion, int *skip,
948b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                  int64_t *psse, BLOCK_SIZE bs,
949b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                  int64_t txfm_cache[TX_MODES],
950b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                  int64_t ref_best_rd) {
951f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  int r[TX_SIZES][2], s[TX_SIZES];
952f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  int64_t d[TX_SIZES], sse[TX_SIZES];
953ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD *xd = &x->e_mbd;
9546ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
955b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const TX_SIZE max_tx_size = max_txsize_lookup[bs];
956b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  TX_SIZE tx_size;
957ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
958ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  assert(bs == mbmi->sb_type);
959ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
960b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  vp9_subtract_plane(x, bs, 0);
961b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
962b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (cpi->sf.tx_size_search_method == USE_LARGESTALL) {
963f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    vpx_memset(txfm_cache, 0, TX_MODES * sizeof(int64_t));
96491037db265ecdd914a26e056cf69207b4f50924ehkuang    choose_largest_txfm_size(cpi, x, rate, distortion, skip, sse,
96591037db265ecdd914a26e056cf69207b4f50924ehkuang                             ref_best_rd, bs);
96691037db265ecdd914a26e056cf69207b4f50924ehkuang    if (psse)
9671184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      *psse = sse[mbmi->tx_size];
96891037db265ecdd914a26e056cf69207b4f50924ehkuang    return;
96991037db265ecdd914a26e056cf69207b4f50924ehkuang  }
97091037db265ecdd914a26e056cf69207b4f50924ehkuang
971b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (cpi->sf.tx_size_search_method == USE_LARGESTINTRA_MODELINTER) {
972b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    for (tx_size = TX_4X4; tx_size <= max_tx_size; ++tx_size)
973b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      model_rd_for_sb_y_tx(cpi, bs, tx_size, x, xd,
974b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                           &r[tx_size][0], &d[tx_size], &s[tx_size]);
97591037db265ecdd914a26e056cf69207b4f50924ehkuang    choose_txfm_size_from_modelrd(cpi, x, r, rate, d, distortion, s,
9761184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                  skip, sse, ref_best_rd, bs);
97791037db265ecdd914a26e056cf69207b4f50924ehkuang  } else {
978b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    for (tx_size = TX_4X4; tx_size <= max_tx_size; ++tx_size)
979b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      txfm_rd_in_plane(x, &r[tx_size][0], &d[tx_size],
980b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                       &s[tx_size], &sse[tx_size],
981b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                       ref_best_rd, 0, bs, tx_size,
982b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                       cpi->sf.use_fast_coef_costing);
983b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    choose_txfm_size_from_rd(cpi, x, r, rate, d, distortion, s,
984b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                             skip, txfm_cache, bs);
985b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  }
986b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (psse)
987b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    *psse = sse[mbmi->tx_size];
988b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian}
989b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
990b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic void intra_super_block_yrd(VP9_COMP *cpi, MACROBLOCK *x, int *rate,
991b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                  int64_t *distortion, int *skip,
992b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                  int64_t *psse, BLOCK_SIZE bs,
993b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                  int64_t txfm_cache[TX_MODES],
994b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                  int64_t ref_best_rd) {
995b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int64_t sse[TX_SIZES];
996b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  MACROBLOCKD *xd = &x->e_mbd;
9976ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
998b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
999b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  assert(bs == mbmi->sb_type);
1000b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (cpi->sf.tx_size_search_method != USE_FULL_RD) {
1001b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    vpx_memset(txfm_cache, 0, TX_MODES * sizeof(int64_t));
1002b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    choose_largest_txfm_size(cpi, x, rate, distortion, skip, sse,
1003b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                             ref_best_rd, bs);
1004b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  } else {
1005b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    int r[TX_SIZES][2], s[TX_SIZES];
1006b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    int64_t d[TX_SIZES];
1007b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    TX_SIZE tx_size;
1008b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    for (tx_size = TX_4X4; tx_size <= max_txsize_lookup[bs]; ++tx_size)
1009b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      txfm_rd_in_plane(x, &r[tx_size][0], &d[tx_size],
1010b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                       &s[tx_size], &sse[tx_size],
1011b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                       ref_best_rd, 0, bs, tx_size,
1012b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                       cpi->sf.use_fast_coef_costing);
101391037db265ecdd914a26e056cf69207b4f50924ehkuang    choose_txfm_size_from_rd(cpi, x, r, rate, d, distortion, s,
101491037db265ecdd914a26e056cf69207b4f50924ehkuang                             skip, txfm_cache, bs);
1015ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
101691037db265ecdd914a26e056cf69207b4f50924ehkuang  if (psse)
10171184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    *psse = sse[mbmi->tx_size];
101891037db265ecdd914a26e056cf69207b4f50924ehkuang}
101991037db265ecdd914a26e056cf69207b4f50924ehkuang
1020b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
102191037db265ecdd914a26e056cf69207b4f50924ehkuangstatic int conditional_skipintra(MB_PREDICTION_MODE mode,
102291037db265ecdd914a26e056cf69207b4f50924ehkuang                                 MB_PREDICTION_MODE best_intra_mode) {
102391037db265ecdd914a26e056cf69207b4f50924ehkuang  if (mode == D117_PRED &&
102491037db265ecdd914a26e056cf69207b4f50924ehkuang      best_intra_mode != V_PRED &&
102591037db265ecdd914a26e056cf69207b4f50924ehkuang      best_intra_mode != D135_PRED)
102691037db265ecdd914a26e056cf69207b4f50924ehkuang    return 1;
102791037db265ecdd914a26e056cf69207b4f50924ehkuang  if (mode == D63_PRED &&
102891037db265ecdd914a26e056cf69207b4f50924ehkuang      best_intra_mode != V_PRED &&
102991037db265ecdd914a26e056cf69207b4f50924ehkuang      best_intra_mode != D45_PRED)
103091037db265ecdd914a26e056cf69207b4f50924ehkuang    return 1;
10311184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  if (mode == D207_PRED &&
103291037db265ecdd914a26e056cf69207b4f50924ehkuang      best_intra_mode != H_PRED &&
103391037db265ecdd914a26e056cf69207b4f50924ehkuang      best_intra_mode != D45_PRED)
103491037db265ecdd914a26e056cf69207b4f50924ehkuang    return 1;
103591037db265ecdd914a26e056cf69207b4f50924ehkuang  if (mode == D153_PRED &&
103691037db265ecdd914a26e056cf69207b4f50924ehkuang      best_intra_mode != H_PRED &&
103791037db265ecdd914a26e056cf69207b4f50924ehkuang      best_intra_mode != D135_PRED)
103891037db265ecdd914a26e056cf69207b4f50924ehkuang    return 1;
103991037db265ecdd914a26e056cf69207b4f50924ehkuang  return 0;
1040ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
1041ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1042ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, int ib,
1043ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                     MB_PREDICTION_MODE *best_mode,
1044b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                     const int *bmode_costs,
1045ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                     ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l,
1046ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                     int *bestrate, int *bestratey,
104791037db265ecdd914a26e056cf69207b4f50924ehkuang                                     int64_t *bestdistortion,
10481184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                     BLOCK_SIZE bsize, int64_t rd_thresh) {
1049ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MB_PREDICTION_MODE mode;
1050b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  MACROBLOCKD *const xd = &x->e_mbd;
1051f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  int64_t best_rd = rd_thresh;
1052b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
105391037db265ecdd914a26e056cf69207b4f50924ehkuang  struct macroblock_plane *p = &x->plane[0];
105491037db265ecdd914a26e056cf69207b4f50924ehkuang  struct macroblockd_plane *pd = &xd->plane[0];
105591037db265ecdd914a26e056cf69207b4f50924ehkuang  const int src_stride = p->src.stride;
105691037db265ecdd914a26e056cf69207b4f50924ehkuang  const int dst_stride = pd->dst.stride;
1057b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const uint8_t *src_init = &p->src.buf[raster_block_offset(BLOCK_8X8, ib,
1058b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                                            src_stride)];
1059b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  uint8_t *dst_init = &pd->dst.buf[raster_block_offset(BLOCK_8X8, ib,
1060b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                                       dst_stride)];
1061ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  ENTROPY_CONTEXT ta[2], tempa[2];
1062ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  ENTROPY_CONTEXT tl[2], templ[2];
10635ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
1064f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
1065f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
10665ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int idx, idy;
1067f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  uint8_t best_dst[8 * 8];
1068ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1069ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  assert(ib < 4);
1070ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1071ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vpx_memcpy(ta, a, sizeof(ta));
1072ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vpx_memcpy(tl, l, sizeof(tl));
10736ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  xd->mi[0]->mbmi.tx_size = TX_4X4;
1074ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1075ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
1076ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int64_t this_rd;
1077ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int ratey = 0;
1078b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    int64_t distortion = 0;
1079b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    int rate = bmode_costs[mode];
10801184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
10815ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (!(cpi->sf.intra_y_mode_mask[TX_4X4] & (1 << mode)))
10821184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      continue;
10831184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
108491037db265ecdd914a26e056cf69207b4f50924ehkuang    // Only do the oblique modes if the best so far is
108591037db265ecdd914a26e056cf69207b4f50924ehkuang    // one of the neighboring directional modes
108691037db265ecdd914a26e056cf69207b4f50924ehkuang    if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
108791037db265ecdd914a26e056cf69207b4f50924ehkuang      if (conditional_skipintra(mode, *best_mode))
108891037db265ecdd914a26e056cf69207b4f50924ehkuang          continue;
108991037db265ecdd914a26e056cf69207b4f50924ehkuang    }
1090ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1091ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vpx_memcpy(tempa, ta, sizeof(ta));
1092ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vpx_memcpy(templ, tl, sizeof(tl));
1093ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
109491037db265ecdd914a26e056cf69207b4f50924ehkuang    for (idy = 0; idy < num_4x4_blocks_high; ++idy) {
109591037db265ecdd914a26e056cf69207b4f50924ehkuang      for (idx = 0; idx < num_4x4_blocks_wide; ++idx) {
10965ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        const int block = ib + idy * 2 + idx;
1097b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
1098b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
1099b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        int16_t *const src_diff = raster_block_offset_int16(BLOCK_8X8, block,
1100b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                                            p->src_diff);
1101b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        int16_t *const coeff = BLOCK_OFFSET(x->plane[0].coeff, block);
11026ac915abcdb404a00d927fe6308a47fcf09d9519hkuang        xd->mi[0]->bmi[block].as_mode = mode;
1103f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        vp9_predict_intra_block(xd, block, 1,
110491037db265ecdd914a26e056cf69207b4f50924ehkuang                                TX_4X4, mode,
110591037db265ecdd914a26e056cf69207b4f50924ehkuang                                x->skip_encode ? src : dst,
110691037db265ecdd914a26e056cf69207b4f50924ehkuang                                x->skip_encode ? src_stride : dst_stride,
1107b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                dst, dst_stride, idx, idy, 0);
1108b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        vp9_subtract_block(4, 4, src_diff, 8, src, src_stride, dst, dst_stride);
1109b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
1110b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        if (xd->lossless) {
1111b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          const scan_order *so = &vp9_default_scan_orders[TX_4X4];
1112b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          vp9_fwht4x4(src_diff, coeff, 8);
1113b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          vp9_regular_quantize_b_4x4(x, 0, block, so->scan, so->iscan);
1114b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          ratey += cost_coeffs(x, 0, block, tempa + idx, templ + idy, TX_4X4,
1115b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                               so->scan, so->neighbors,
1116b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                               cpi->sf.use_fast_coef_costing);
1117b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
1118b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            goto next;
1119b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          vp9_iwht4x4_add(BLOCK_OFFSET(pd->dqcoeff, block), dst, dst_stride,
1120b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                          p->eobs[block]);
1121b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        } else {
1122b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          int64_t unused;
1123b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          const TX_TYPE tx_type = get_tx_type_4x4(PLANE_TYPE_Y, xd, block);
1124b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          const scan_order *so = &vp9_scan_orders[TX_4X4][tx_type];
1125b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          vp9_fht4x4(src_diff, coeff, 8, tx_type);
1126b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          vp9_regular_quantize_b_4x4(x, 0, block, so->scan, so->iscan);
1127b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          ratey += cost_coeffs(x, 0, block, tempa + idx, templ + idy, TX_4X4,
1128b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                             so->scan, so->neighbors,
1129b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                             cpi->sf.use_fast_coef_costing);
1130b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          distortion += vp9_block_error(coeff, BLOCK_OFFSET(pd->dqcoeff, block),
1131b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                        16, &unused) >> 2;
1132b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
1133b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            goto next;
1134b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          vp9_iht4x4_add(tx_type, BLOCK_OFFSET(pd->dqcoeff, block),
1135b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                         dst, dst_stride, p->eobs[block]);
1136b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        }
1137ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
1138ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
1139ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1140ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    rate += ratey;
1141ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
1142ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1143ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (this_rd < best_rd) {
1144ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      *bestrate = rate;
1145ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      *bestratey = ratey;
1146ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      *bestdistortion = distortion;
1147ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      best_rd = this_rd;
1148ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      *best_mode = mode;
1149ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      vpx_memcpy(a, tempa, sizeof(tempa));
1150ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      vpx_memcpy(l, templ, sizeof(templ));
1151f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy)
1152f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        vpx_memcpy(best_dst + idy * 8, dst_init + idy * dst_stride,
1153f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                   num_4x4_blocks_wide * 4);
1154ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
1155f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  next:
1156f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    {}
1157ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
1158ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1159f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  if (best_rd >= rd_thresh || x->skip_encode)
116091037db265ecdd914a26e056cf69207b4f50924ehkuang    return best_rd;
116191037db265ecdd914a26e056cf69207b4f50924ehkuang
1162f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy)
1163f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    vpx_memcpy(dst_init + idy * dst_stride, best_dst + idy * 8,
1164f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang               num_4x4_blocks_wide * 4);
1165ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1166ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return best_rd;
1167ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
1168ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1169b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic int64_t rd_pick_intra_sub_8x8_y_mode(VP9_COMP *cpi, MACROBLOCK *mb,
1170b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                            int *rate, int *rate_y,
1171b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                            int64_t *distortion,
1172f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                                            int64_t best_rd) {
1173ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int i, j;
1174b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const MACROBLOCKD *const xd = &mb->e_mbd;
11756ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  MODE_INFO *const mic = xd->mi[0];
11766ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  const MODE_INFO *above_mi = xd->mi[-xd->mi_stride];
11776ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  const MODE_INFO *left_mi = xd->left_available ? xd->mi[-1] : NULL;
11786ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
1179f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
1180f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
1181ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int idx, idy;
1182ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int cost = 0;
1183f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  int64_t total_distortion = 0;
1184ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int tot_rate_y = 0;
1185ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int64_t total_rd = 0;
1186ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  ENTROPY_CONTEXT t_above[4], t_left[4];
1187b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int *bmode_costs = mb->mbmode_cost;
1188ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1189ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vpx_memcpy(t_above, xd->plane[0].above_context, sizeof(t_above));
1190ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vpx_memcpy(t_left, xd->plane[0].left_context, sizeof(t_left));
1191ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1192f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  // Pick modes for each sub-block (of size 4x4, 4x8, or 8x4) in an 8x8 block.
119391037db265ecdd914a26e056cf69207b4f50924ehkuang  for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
119491037db265ecdd914a26e056cf69207b4f50924ehkuang    for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
11951184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      MB_PREDICTION_MODE best_mode = DC_PRED;
11961184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      int r = INT_MAX, ry = INT_MAX;
11971184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      int64_t d = INT64_MAX, this_rd = INT64_MAX;
1198ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      i = idy * 2 + idx;
119991037db265ecdd914a26e056cf69207b4f50924ehkuang      if (cpi->common.frame_type == KEY_FRAME) {
1200b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        const MB_PREDICTION_MODE A = vp9_above_block_mode(mic, above_mi, i);
1201b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        const MB_PREDICTION_MODE L = vp9_left_block_mode(mic, left_mi, i);
1202ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1203ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        bmode_costs  = mb->y_mode_costs[A][L];
1204ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
1205ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1206f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      this_rd = rd_pick_intra4x4block(cpi, mb, i, &best_mode, bmode_costs,
12071184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                      t_above + idx, t_left + idy, &r, &ry, &d,
12081184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                      bsize, best_rd - total_rd);
1209f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      if (this_rd >= best_rd - total_rd)
1210f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        return INT64_MAX;
1211f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
1212f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      total_rd += this_rd;
1213ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      cost += r;
1214f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      total_distortion += d;
1215ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      tot_rate_y += ry;
1216ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
121791037db265ecdd914a26e056cf69207b4f50924ehkuang      mic->bmi[i].as_mode = best_mode;
121891037db265ecdd914a26e056cf69207b4f50924ehkuang      for (j = 1; j < num_4x4_blocks_high; ++j)
121991037db265ecdd914a26e056cf69207b4f50924ehkuang        mic->bmi[i + j * 2].as_mode = best_mode;
122091037db265ecdd914a26e056cf69207b4f50924ehkuang      for (j = 1; j < num_4x4_blocks_wide; ++j)
122191037db265ecdd914a26e056cf69207b4f50924ehkuang        mic->bmi[i + j].as_mode = best_mode;
1222ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1223ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (total_rd >= best_rd)
122491037db265ecdd914a26e056cf69207b4f50924ehkuang        return INT64_MAX;
1225ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
1226ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
1227ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1228f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  *rate = cost;
1229ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  *rate_y = tot_rate_y;
1230f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  *distortion = total_distortion;
12311184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  mic->mbmi.mode = mic->bmi[3].as_mode;
1232ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1233f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  return RDCOST(mb->rdmult, mb->rddiv, cost, total_distortion);
1234ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
1235ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1236ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic int64_t rd_pick_intra_sby_mode(VP9_COMP *cpi, MACROBLOCK *x,
1237ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                      int *rate, int *rate_tokenonly,
123891037db265ecdd914a26e056cf69207b4f50924ehkuang                                      int64_t *distortion, int *skippable,
12391184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                      BLOCK_SIZE bsize,
1240f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                                      int64_t tx_cache[TX_MODES],
124191037db265ecdd914a26e056cf69207b4f50924ehkuang                                      int64_t best_rd) {
1242ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MB_PREDICTION_MODE mode;
12431184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  MB_PREDICTION_MODE mode_selected = DC_PRED;
1244ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD *const xd = &x->e_mbd;
12456ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  MODE_INFO *const mic = xd->mi[0];
124691037db265ecdd914a26e056cf69207b4f50924ehkuang  int this_rate, this_rate_tokenonly, s;
124791037db265ecdd914a26e056cf69207b4f50924ehkuang  int64_t this_distortion, this_rd;
12481184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  TX_SIZE best_tx = TX_4X4;
1249ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int i;
1250ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int *bmode_costs = x->mbmode_cost;
1251ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1252f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  if (cpi->sf.tx_size_search_method == USE_FULL_RD)
1253f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    for (i = 0; i < TX_MODES; i++)
1254f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      tx_cache[i] = INT64_MAX;
1255ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1256f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  /* Y Search for intra prediction mode */
1257ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (mode = DC_PRED; mode <= TM_PRED; mode++) {
1258f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    int64_t local_tx_cache[TX_MODES];
12596ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    MODE_INFO *above_mi = xd->mi[-xd->mi_stride];
12606ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    MODE_INFO *left_mi = xd->left_available ? xd->mi[-1] : NULL;
12611184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
12625ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (!(cpi->sf.intra_y_mode_mask[max_txsize_lookup[bsize]] & (1 << mode)))
12631184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      continue;
1264ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1265ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (cpi->common.frame_type == KEY_FRAME) {
1266b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      const MB_PREDICTION_MODE A = vp9_above_block_mode(mic, above_mi, 0);
1267b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      const MB_PREDICTION_MODE L = vp9_left_block_mode(mic, left_mi, 0);
1268ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1269ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      bmode_costs = x->y_mode_costs[A][L];
1270ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
12711184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    mic->mbmi.mode = mode;
1272ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1273b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    intra_super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
1274b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        &s, NULL, bsize, local_tx_cache, best_rd);
127591037db265ecdd914a26e056cf69207b4f50924ehkuang
127691037db265ecdd914a26e056cf69207b4f50924ehkuang    if (this_rate_tokenonly == INT_MAX)
127791037db265ecdd914a26e056cf69207b4f50924ehkuang      continue;
1278ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1279ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    this_rate = this_rate_tokenonly + bmode_costs[mode];
1280ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
1281ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1282ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (this_rd < best_rd) {
1283ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      mode_selected   = mode;
1284ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      best_rd         = this_rd;
12851184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      best_tx         = mic->mbmi.tx_size;
1286ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      *rate           = this_rate;
1287ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      *rate_tokenonly = this_rate_tokenonly;
1288ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      *distortion     = this_distortion;
1289ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      *skippable      = s;
1290ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
1291ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
129291037db265ecdd914a26e056cf69207b4f50924ehkuang    if (cpi->sf.tx_size_search_method == USE_FULL_RD && this_rd < INT64_MAX) {
12931184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      for (i = 0; i < TX_MODES && local_tx_cache[i] < INT64_MAX; i++) {
1294f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        const int64_t adj_rd = this_rd + local_tx_cache[i] -
1295f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang            local_tx_cache[cpi->common.tx_mode];
1296f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        if (adj_rd < tx_cache[i]) {
1297f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          tx_cache[i] = adj_rd;
129891037db265ecdd914a26e056cf69207b4f50924ehkuang        }
1299ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
1300ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
1301ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
1302ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
13031184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  mic->mbmi.mode = mode_selected;
13041184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  mic->mbmi.tx_size = best_tx;
1305ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1306ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return best_rd;
1307ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
1308ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1309b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic void super_block_uvrd(const VP9_COMP *cpi, MACROBLOCK *x,
131091037db265ecdd914a26e056cf69207b4f50924ehkuang                             int *rate, int64_t *distortion, int *skippable,
13111184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                             int64_t *sse, BLOCK_SIZE bsize,
13121184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                             int64_t ref_best_rd) {
1313ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD *const xd = &x->e_mbd;
13146ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
131591037db265ecdd914a26e056cf69207b4f50924ehkuang  TX_SIZE uv_txfm_size = get_uv_tx_size(mbmi);
13161184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int plane;
13171184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int pnrate = 0, pnskip = 1;
13181184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int64_t pndist = 0, pnsse = 0;
1319ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
13201184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  if (ref_best_rd < 0)
13211184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    goto term;
13221184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
1323b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (is_inter_block(mbmi)) {
1324b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    int plane;
1325b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    for (plane = 1; plane < MAX_MB_PLANE; ++plane)
1326b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      vp9_subtract_plane(x, bsize, plane);
1327b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  }
1328ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
13291184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  *rate = 0;
13301184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  *distortion = 0;
13311184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  *sse = 0;
13321184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  *skippable = 1;
13331184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
13341184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
1335b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    txfm_rd_in_plane(x, &pnrate, &pndist, &pnskip, &pnsse,
1336b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                     ref_best_rd, plane, bsize, uv_txfm_size,
1337b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                     cpi->sf.use_fast_coef_costing);
13381184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    if (pnrate == INT_MAX)
13391184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      goto term;
13401184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    *rate += pnrate;
13411184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    *distortion += pndist;
13421184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    *sse += pnsse;
13431184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    *skippable &= pnskip;
13441184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  }
13451184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  return;
13461184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
13471184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  term:
13481184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  *rate = INT_MAX;
13491184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  *distortion = INT64_MAX;
13501184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  *sse = INT64_MAX;
13511184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  *skippable = 0;
13521184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  return;
1353ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
1354ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1355ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic int64_t rd_pick_intra_sbuv_mode(VP9_COMP *cpi, MACROBLOCK *x,
13569b35249446b07f40ac5fcc3205f2c048616efacchkuang                                       PICK_MODE_CONTEXT *ctx,
1357ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                       int *rate, int *rate_tokenonly,
135891037db265ecdd914a26e056cf69207b4f50924ehkuang                                       int64_t *distortion, int *skippable,
1359b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                       BLOCK_SIZE bsize, TX_SIZE max_tx_size) {
1360b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  MACROBLOCKD *xd = &x->e_mbd;
1361ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MB_PREDICTION_MODE mode;
13621184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  MB_PREDICTION_MODE mode_selected = DC_PRED;
1363ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int64_t best_rd = INT64_MAX, this_rd;
136491037db265ecdd914a26e056cf69207b4f50924ehkuang  int this_rate_tokenonly, this_rate, s;
13651184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int64_t this_distortion, this_sse;
13661184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
1367b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
1368b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (!(cpi->sf.intra_uv_mode_mask[max_tx_size] & (1 << mode)))
13691184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      continue;
1370ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
13716ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    xd->mi[0]->mbmi.uv_mode = mode;
137291037db265ecdd914a26e056cf69207b4f50924ehkuang
13735ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    super_block_uvrd(cpi, x, &this_rate_tokenonly,
13741184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                     &this_distortion, &s, &this_sse, bsize, best_rd);
13751184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    if (this_rate_tokenonly == INT_MAX)
13761184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      continue;
1377ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    this_rate = this_rate_tokenonly +
137891037db265ecdd914a26e056cf69207b4f50924ehkuang                x->intra_uv_mode_cost[cpi->common.frame_type][mode];
1379ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
1380ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1381ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (this_rd < best_rd) {
1382ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      mode_selected   = mode;
1383ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      best_rd         = this_rd;
1384ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      *rate           = this_rate;
1385ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      *rate_tokenonly = this_rate_tokenonly;
1386ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      *distortion     = this_distortion;
1387ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      *skippable      = s;
13889b35249446b07f40ac5fcc3205f2c048616efacchkuang      if (!x->select_txfm_size) {
13899b35249446b07f40ac5fcc3205f2c048616efacchkuang        int i;
13909b35249446b07f40ac5fcc3205f2c048616efacchkuang        struct macroblock_plane *const p = x->plane;
1391b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        struct macroblockd_plane *const pd = xd->plane;
13929b35249446b07f40ac5fcc3205f2c048616efacchkuang        for (i = 1; i < MAX_MB_PLANE; ++i) {
13939b35249446b07f40ac5fcc3205f2c048616efacchkuang          p[i].coeff    = ctx->coeff_pbuf[i][2];
1394b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          p[i].qcoeff   = ctx->qcoeff_pbuf[i][2];
13959b35249446b07f40ac5fcc3205f2c048616efacchkuang          pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][2];
1396b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          p[i].eobs    = ctx->eobs_pbuf[i][2];
13979b35249446b07f40ac5fcc3205f2c048616efacchkuang
13989b35249446b07f40ac5fcc3205f2c048616efacchkuang          ctx->coeff_pbuf[i][2]   = ctx->coeff_pbuf[i][0];
13999b35249446b07f40ac5fcc3205f2c048616efacchkuang          ctx->qcoeff_pbuf[i][2]  = ctx->qcoeff_pbuf[i][0];
14009b35249446b07f40ac5fcc3205f2c048616efacchkuang          ctx->dqcoeff_pbuf[i][2] = ctx->dqcoeff_pbuf[i][0];
14019b35249446b07f40ac5fcc3205f2c048616efacchkuang          ctx->eobs_pbuf[i][2]    = ctx->eobs_pbuf[i][0];
14029b35249446b07f40ac5fcc3205f2c048616efacchkuang
14039b35249446b07f40ac5fcc3205f2c048616efacchkuang          ctx->coeff_pbuf[i][0]   = p[i].coeff;
1404b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          ctx->qcoeff_pbuf[i][0]  = p[i].qcoeff;
14059b35249446b07f40ac5fcc3205f2c048616efacchkuang          ctx->dqcoeff_pbuf[i][0] = pd[i].dqcoeff;
1406b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          ctx->eobs_pbuf[i][0]    = p[i].eobs;
14079b35249446b07f40ac5fcc3205f2c048616efacchkuang        }
14089b35249446b07f40ac5fcc3205f2c048616efacchkuang      }
1409ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
1410ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
1411ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
14126ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  xd->mi[0]->mbmi.uv_mode = mode_selected;
1413ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return best_rd;
1414ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
1415ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1416b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic int64_t rd_sbuv_dcpred(const VP9_COMP *cpi, MACROBLOCK *x,
141791037db265ecdd914a26e056cf69207b4f50924ehkuang                              int *rate, int *rate_tokenonly,
141891037db265ecdd914a26e056cf69207b4f50924ehkuang                              int64_t *distortion, int *skippable,
14191184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                              BLOCK_SIZE bsize) {
1420b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const VP9_COMMON *cm = &cpi->common;
1421b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int64_t unused;
142291037db265ecdd914a26e056cf69207b4f50924ehkuang
14236ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  x->e_mbd.mi[0]->mbmi.uv_mode = DC_PRED;
14245ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  super_block_uvrd(cpi, x, rate_tokenonly, distortion,
1425b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                   skippable, &unused, bsize, INT64_MAX);
1426b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  *rate = *rate_tokenonly + x->intra_uv_mode_cost[cm->frame_type][DC_PRED];
1427b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  return RDCOST(x->rdmult, x->rddiv, *rate, *distortion);
142891037db265ecdd914a26e056cf69207b4f50924ehkuang}
142991037db265ecdd914a26e056cf69207b4f50924ehkuang
14309b35249446b07f40ac5fcc3205f2c048616efacchkuangstatic void choose_intra_uv_mode(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
1431b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                 BLOCK_SIZE bsize, TX_SIZE max_tx_size,
1432b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                 int *rate_uv, int *rate_uv_tokenonly,
143391037db265ecdd914a26e056cf69207b4f50924ehkuang                                 int64_t *dist_uv, int *skip_uv,
143491037db265ecdd914a26e056cf69207b4f50924ehkuang                                 MB_PREDICTION_MODE *mode_uv) {
143591037db265ecdd914a26e056cf69207b4f50924ehkuang  MACROBLOCK *const x = &cpi->mb;
143691037db265ecdd914a26e056cf69207b4f50924ehkuang
143791037db265ecdd914a26e056cf69207b4f50924ehkuang  // Use an estimated rd for uv_intra based on DC_PRED if the
143891037db265ecdd914a26e056cf69207b4f50924ehkuang  // appropriate speed flag is set.
143991037db265ecdd914a26e056cf69207b4f50924ehkuang  if (cpi->sf.use_uv_intra_rd_estimate) {
1440b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    rd_sbuv_dcpred(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv,
1441b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                   skip_uv, bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize);
144291037db265ecdd914a26e056cf69207b4f50924ehkuang  // Else do a proper rd search for each possible transform size that may
144391037db265ecdd914a26e056cf69207b4f50924ehkuang  // be considered in the main rd loop.
144491037db265ecdd914a26e056cf69207b4f50924ehkuang  } else {
14459b35249446b07f40ac5fcc3205f2c048616efacchkuang    rd_pick_intra_sbuv_mode(cpi, x, ctx,
144691037db265ecdd914a26e056cf69207b4f50924ehkuang                            rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
1447b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                            bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize, max_tx_size);
144891037db265ecdd914a26e056cf69207b4f50924ehkuang  }
14496ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  *mode_uv = x->e_mbd.mi[0]->mbmi.uv_mode;
145091037db265ecdd914a26e056cf69207b4f50924ehkuang}
145191037db265ecdd914a26e056cf69207b4f50924ehkuang
14526ac915abcdb404a00d927fe6308a47fcf09d9519hkuangstatic int cost_mv_ref(const VP9_COMP *cpi, MB_PREDICTION_MODE mode,
145391037db265ecdd914a26e056cf69207b4f50924ehkuang                       int mode_context) {
14546ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  const MACROBLOCK *const x = &cpi->mb;
14556ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  const int segment_id = x->e_mbd.mi[0]->mbmi.segment_id;
145691037db265ecdd914a26e056cf69207b4f50924ehkuang
145791037db265ecdd914a26e056cf69207b4f50924ehkuang  // Don't account for mode here if segment skip is enabled.
14581184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  if (!vp9_segfeature_active(&cpi->common.seg, segment_id, SEG_LVL_SKIP)) {
145991037db265ecdd914a26e056cf69207b4f50924ehkuang    assert(is_inter_mode(mode));
14609b35249446b07f40ac5fcc3205f2c048616efacchkuang    return x->inter_mode_cost[mode_context][INTER_OFFSET(mode)];
146191037db265ecdd914a26e056cf69207b4f50924ehkuang  } else {
1462ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    return 0;
146391037db265ecdd914a26e056cf69207b4f50924ehkuang  }
1464ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
1465ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1466ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
14671184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                BLOCK_SIZE bsize,
1468ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                int_mv *frame_mv,
1469ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                int mi_row, int mi_col,
1470ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                int_mv single_newmv[MAX_REF_FRAMES],
1471ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                int *rate_mv);
1472ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1473b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic int labels2mode(VP9_COMP *cpi, MACROBLOCKD *xd, int i,
1474b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                       MB_PREDICTION_MODE mode,
1475b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                       int_mv this_mv[2],
1476ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                       int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES],
1477ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                       int_mv seg_mvs[MAX_REF_FRAMES],
1478b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                       int_mv *best_ref_mv[2],
1479b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                       const int *mvjcost, int *mvcost[2]) {
14806ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  MODE_INFO *const mic = xd->mi[0];
1481b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const MB_MODE_INFO *const mbmi = &mic->mbmi;
1482b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int thismvcost = 0;
1483ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int idx, idy;
1484f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type];
1485f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type];
1486b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int is_compound = has_second_ref(mbmi);
1487ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1488ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // the only time we should do costing for new motion vector or mode
1489ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // is when we are on a new label  (jbb May 08, 2007)
1490b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  switch (mode) {
1491ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    case NEWMV:
1492b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
1493b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      thismvcost += vp9_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
14945ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                    mvjcost, mvcost, MV_COST_WEIGHT_SUB);
1495b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (is_compound) {
1496b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
1497b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        thismvcost += vp9_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
14985ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                      mvjcost, mvcost, MV_COST_WEIGHT_SUB);
1499ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
1500ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      break;
1501ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    case NEARESTMV:
1502b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      this_mv[0].as_int = frame_mv[NEARESTMV][mbmi->ref_frame[0]].as_int;
1503b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (is_compound)
1504b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        this_mv[1].as_int = frame_mv[NEARESTMV][mbmi->ref_frame[1]].as_int;
1505ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      break;
1506ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    case NEARMV:
1507b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      this_mv[0].as_int = frame_mv[NEARMV][mbmi->ref_frame[0]].as_int;
1508b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (is_compound)
1509b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        this_mv[1].as_int = frame_mv[NEARMV][mbmi->ref_frame[1]].as_int;
1510ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      break;
1511ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    case ZEROMV:
1512b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      this_mv[0].as_int = 0;
1513b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (is_compound)
1514b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        this_mv[1].as_int = 0;
1515ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      break;
1516ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    default:
1517ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      break;
1518ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
1519ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1520b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  mic->bmi[i].as_mv[0].as_int = this_mv[0].as_int;
1521b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (is_compound)
1522b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    mic->bmi[i].as_mv[1].as_int = this_mv[1].as_int;
1523ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1524b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  mic->bmi[i].as_mode = mode;
15255ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
152691037db265ecdd914a26e056cf69207b4f50924ehkuang  for (idy = 0; idy < num_4x4_blocks_high; ++idy)
152791037db265ecdd914a26e056cf69207b4f50924ehkuang    for (idx = 0; idx < num_4x4_blocks_wide; ++idx)
1528ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      vpx_memcpy(&mic->bmi[i + idy * 2 + idx],
1529ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                 &mic->bmi[i], sizeof(mic->bmi[i]));
1530ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1531b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  return cost_mv_ref(cpi, mode, mbmi->mode_context[mbmi->ref_frame[0]]) +
1532b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            thismvcost;
1533ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
1534ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
153591037db265ecdd914a26e056cf69207b4f50924ehkuangstatic int64_t encode_inter_mb_segment(VP9_COMP *cpi,
1536ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                       MACROBLOCK *x,
153791037db265ecdd914a26e056cf69207b4f50924ehkuang                                       int64_t best_yrd,
1538ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                       int i,
1539ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                       int *labelyrate,
154091037db265ecdd914a26e056cf69207b4f50924ehkuang                                       int64_t *distortion, int64_t *sse,
1541ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                       ENTROPY_CONTEXT *ta,
1542b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                       ENTROPY_CONTEXT *tl,
1543b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                       int mi_row, int mi_col) {
1544ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int k;
1545ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD *xd = &x->e_mbd;
1546f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  struct macroblockd_plane *const pd = &xd->plane[0];
15475ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  struct macroblock_plane *const p = &x->plane[0];
15486ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  MODE_INFO *const mi = xd->mi[0];
1549b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const BLOCK_SIZE plane_bsize = get_plane_block_size(mi->mbmi.sb_type, pd);
1550b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int width = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
1551b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int height = 4 * num_4x4_blocks_high_lookup[plane_bsize];
1552ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int idx, idy;
15535ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
1554b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const uint8_t *const src = &p->src.buf[raster_block_offset(BLOCK_8X8, i,
1555b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                                             p->src.stride)];
1556b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  uint8_t *const dst = &pd->dst.buf[raster_block_offset(BLOCK_8X8, i,
1557b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                                        pd->dst.stride)];
155891037db265ecdd914a26e056cf69207b4f50924ehkuang  int64_t thisdistortion = 0, thissse = 0;
15595ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int thisrate = 0, ref;
1560b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const scan_order *so = &vp9_default_scan_orders[TX_4X4];
15615ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const int is_compound = has_second_ref(&mi->mbmi);
15626ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  const InterpKernel *kernel = vp9_get_interp_kernel(mi->mbmi.interp_filter);
15636ac915abcdb404a00d927fe6308a47fcf09d9519hkuang
15645ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  for (ref = 0; ref < 1 + is_compound; ++ref) {
1565b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    const uint8_t *pre = &pd->pre[ref].buf[raster_block_offset(BLOCK_8X8, i,
1566b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                               pd->pre[ref].stride)];
15671184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    vp9_build_inter_predictor(pre, pd->pre[ref].stride,
1568f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                              dst, pd->dst.stride,
15691184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                              &mi->bmi[i].as_mv[ref].as_mv,
1570b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                              &xd->block_refs[ref]->sf, width, height, ref,
15716ac915abcdb404a00d927fe6308a47fcf09d9519hkuang                              kernel, MV_PRECISION_Q3,
1572b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                              mi_col * MI_SIZE + 4 * (i % 2),
1573b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                              mi_row * MI_SIZE + 4 * (i / 2));
1574ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
1575ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
15765ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  vp9_subtract_block(height, width,
15775ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                     raster_block_offset_int16(BLOCK_8X8, i, p->src_diff), 8,
15785ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                     src, p->src.stride,
1579f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                     dst, pd->dst.stride);
1580ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1581ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  k = i;
158291037db265ecdd914a26e056cf69207b4f50924ehkuang  for (idy = 0; idy < height / 4; ++idy) {
158391037db265ecdd914a26e056cf69207b4f50924ehkuang    for (idx = 0; idx < width / 4; ++idx) {
158491037db265ecdd914a26e056cf69207b4f50924ehkuang      int64_t ssz, rd, rd1, rd2;
15855ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      int16_t* coeff;
158691037db265ecdd914a26e056cf69207b4f50924ehkuang
1587ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      k += (idy * 2 + idx);
15885ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      coeff = BLOCK_OFFSET(p->coeff, k);
15895ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      x->fwd_txm4x4(raster_block_offset_int16(BLOCK_8X8, k, p->src_diff),
15905ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                    coeff, 8);
1591b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      vp9_regular_quantize_b_4x4(x, 0, k, so->scan, so->iscan);
15921184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      thisdistortion += vp9_block_error(coeff, BLOCK_OFFSET(pd->dqcoeff, k),
1593f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                                        16, &ssz);
159491037db265ecdd914a26e056cf69207b4f50924ehkuang      thissse += ssz;
1595b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      thisrate += cost_coeffs(x, 0, k, ta + (k & 1), tl + (k >> 1), TX_4X4,
1596b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                              so->scan, so->neighbors,
1597b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                              cpi->sf.use_fast_coef_costing);
159891037db265ecdd914a26e056cf69207b4f50924ehkuang      rd1 = RDCOST(x->rdmult, x->rddiv, thisrate, thisdistortion >> 2);
159991037db265ecdd914a26e056cf69207b4f50924ehkuang      rd2 = RDCOST(x->rdmult, x->rddiv, 0, thissse >> 2);
160091037db265ecdd914a26e056cf69207b4f50924ehkuang      rd = MIN(rd1, rd2);
160191037db265ecdd914a26e056cf69207b4f50924ehkuang      if (rd >= best_yrd)
160291037db265ecdd914a26e056cf69207b4f50924ehkuang        return INT64_MAX;
1603ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
1604ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
16055ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
160691037db265ecdd914a26e056cf69207b4f50924ehkuang  *distortion = thisdistortion >> 2;
160791037db265ecdd914a26e056cf69207b4f50924ehkuang  *labelyrate = thisrate;
160891037db265ecdd914a26e056cf69207b4f50924ehkuang  *sse = thissse >> 2;
1609ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1610ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return RDCOST(x->rdmult, x->rddiv, *labelyrate, *distortion);
1611ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
1612ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1613ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangtypedef struct {
161491037db265ecdd914a26e056cf69207b4f50924ehkuang  int eobs;
161591037db265ecdd914a26e056cf69207b4f50924ehkuang  int brate;
161691037db265ecdd914a26e056cf69207b4f50924ehkuang  int byrate;
161791037db265ecdd914a26e056cf69207b4f50924ehkuang  int64_t bdist;
161891037db265ecdd914a26e056cf69207b4f50924ehkuang  int64_t bsse;
161991037db265ecdd914a26e056cf69207b4f50924ehkuang  int64_t brdcost;
162091037db265ecdd914a26e056cf69207b4f50924ehkuang  int_mv mvs[2];
162191037db265ecdd914a26e056cf69207b4f50924ehkuang  ENTROPY_CONTEXT ta[2];
162291037db265ecdd914a26e056cf69207b4f50924ehkuang  ENTROPY_CONTEXT tl[2];
162391037db265ecdd914a26e056cf69207b4f50924ehkuang} SEG_RDSTAT;
162491037db265ecdd914a26e056cf69207b4f50924ehkuang
162591037db265ecdd914a26e056cf69207b4f50924ehkuangtypedef struct {
1626b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int_mv *ref_mv[2];
1627ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int_mv mvp;
1628ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1629ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int64_t segment_rd;
1630ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int r;
163191037db265ecdd914a26e056cf69207b4f50924ehkuang  int64_t d;
163291037db265ecdd914a26e056cf69207b4f50924ehkuang  int64_t sse;
1633ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int segment_yrate;
1634ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MB_PREDICTION_MODE modes[4];
16351184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  SEG_RDSTAT rdstat[4][INTER_MODES];
1636ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int mvthresh;
1637ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} BEST_SEG_INFO;
1638ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1639b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic INLINE int mv_check_bounds(const MACROBLOCK *x, const MV *mv) {
1640b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  return (mv->row >> 3) < x->mv_row_min ||
1641b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian         (mv->row >> 3) > x->mv_row_max ||
1642b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian         (mv->col >> 3) < x->mv_col_min ||
1643b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian         (mv->col >> 3) > x->mv_col_max;
1644ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
1645ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1646ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic INLINE void mi_buf_shift(MACROBLOCK *x, int i) {
16476ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  MB_MODE_INFO *const mbmi = &x->e_mbd.mi[0]->mbmi;
16481184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  struct macroblock_plane *const p = &x->plane[0];
16491184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  struct macroblockd_plane *const pd = &x->e_mbd.plane[0];
16501184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
1651b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  p->src.buf = &p->src.buf[raster_block_offset(BLOCK_8X8, i, p->src.stride)];
16521184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  assert(((intptr_t)pd->pre[0].buf & 0x7) == 0);
1653b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  pd->pre[0].buf = &pd->pre[0].buf[raster_block_offset(BLOCK_8X8, i,
1654b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                                       pd->pre[0].stride)];
16555ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (has_second_ref(mbmi))
1656b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    pd->pre[1].buf = &pd->pre[1].buf[raster_block_offset(BLOCK_8X8, i,
1657b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                                         pd->pre[1].stride)];
1658ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
1659ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1660ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic INLINE void mi_buf_restore(MACROBLOCK *x, struct buf_2d orig_src,
1661ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                  struct buf_2d orig_pre[2]) {
16626ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
1663ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  x->plane[0].src = orig_src;
1664ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  x->e_mbd.plane[0].pre[0] = orig_pre[0];
16655ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (has_second_ref(mbmi))
1666ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    x->e_mbd.plane[0].pre[1] = orig_pre[1];
1667ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
1668ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1669b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic INLINE int mv_has_subpel(const MV *mv) {
1670b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  return (mv->row & 0x0F) || (mv->col & 0x0F);
1671b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian}
1672b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
16736ac915abcdb404a00d927fe6308a47fcf09d9519hkuang// Check if NEARESTMV/NEARMV/ZEROMV is the cheapest way encode zero motion.
16746ac915abcdb404a00d927fe6308a47fcf09d9519hkuang// TODO(aconverse): Find out if this is still productive then clean up or remove
16756ac915abcdb404a00d927fe6308a47fcf09d9519hkuangstatic int check_best_zero_mv(
16766ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    const VP9_COMP *cpi, const uint8_t mode_context[MAX_REF_FRAMES],
16776ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES],
16786ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    int disable_inter_mode_mask, int this_mode, int ref_frame,
16796ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    int second_ref_frame) {
16806ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  if (!(disable_inter_mode_mask & (1 << INTER_OFFSET(ZEROMV))) &&
16816ac915abcdb404a00d927fe6308a47fcf09d9519hkuang      (this_mode == NEARMV || this_mode == NEARESTMV || this_mode == ZEROMV) &&
16826ac915abcdb404a00d927fe6308a47fcf09d9519hkuang      frame_mv[this_mode][ref_frame].as_int == 0 &&
16836ac915abcdb404a00d927fe6308a47fcf09d9519hkuang      (second_ref_frame == NONE ||
16846ac915abcdb404a00d927fe6308a47fcf09d9519hkuang       frame_mv[this_mode][second_ref_frame].as_int == 0)) {
16856ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    int rfc = mode_context[ref_frame];
16866ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    int c1 = cost_mv_ref(cpi, NEARMV, rfc);
16876ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    int c2 = cost_mv_ref(cpi, NEARESTMV, rfc);
16886ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    int c3 = cost_mv_ref(cpi, ZEROMV, rfc);
16896ac915abcdb404a00d927fe6308a47fcf09d9519hkuang
16906ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    if (this_mode == NEARMV) {
16916ac915abcdb404a00d927fe6308a47fcf09d9519hkuang      if (c1 > c3) return 0;
16926ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    } else if (this_mode == NEARESTMV) {
16936ac915abcdb404a00d927fe6308a47fcf09d9519hkuang      if (c2 > c3) return 0;
16946ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    } else {
16956ac915abcdb404a00d927fe6308a47fcf09d9519hkuang      assert(this_mode == ZEROMV);
16966ac915abcdb404a00d927fe6308a47fcf09d9519hkuang      if (second_ref_frame == NONE) {
16976ac915abcdb404a00d927fe6308a47fcf09d9519hkuang        if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frame].as_int == 0) ||
16986ac915abcdb404a00d927fe6308a47fcf09d9519hkuang            (c3 >= c1 && frame_mv[NEARMV][ref_frame].as_int == 0))
16996ac915abcdb404a00d927fe6308a47fcf09d9519hkuang          return 0;
17006ac915abcdb404a00d927fe6308a47fcf09d9519hkuang      } else {
17016ac915abcdb404a00d927fe6308a47fcf09d9519hkuang        if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frame].as_int == 0 &&
17026ac915abcdb404a00d927fe6308a47fcf09d9519hkuang             frame_mv[NEARESTMV][second_ref_frame].as_int == 0) ||
17036ac915abcdb404a00d927fe6308a47fcf09d9519hkuang            (c3 >= c1 && frame_mv[NEARMV][ref_frame].as_int == 0 &&
17046ac915abcdb404a00d927fe6308a47fcf09d9519hkuang             frame_mv[NEARMV][second_ref_frame].as_int == 0))
17056ac915abcdb404a00d927fe6308a47fcf09d9519hkuang          return 0;
17066ac915abcdb404a00d927fe6308a47fcf09d9519hkuang      }
17076ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    }
17086ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  }
17096ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  return 1;
17106ac915abcdb404a00d927fe6308a47fcf09d9519hkuang}
17116ac915abcdb404a00d927fe6308a47fcf09d9519hkuang
1712ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
17135ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                    const TileInfo *const tile,
171491037db265ecdd914a26e056cf69207b4f50924ehkuang                                    BEST_SEG_INFO *bsi_buf, int filter_idx,
1715ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                    int_mv seg_mvs[4][MAX_REF_FRAMES],
1716ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                    int mi_row, int mi_col) {
1717b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int k, br = 0, idx, idy;
171891037db265ecdd914a26e056cf69207b4f50924ehkuang  int64_t bd = 0, block_sse = 0;
1719ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MB_PREDICTION_MODE this_mode;
1720b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  MACROBLOCKD *xd = &x->e_mbd;
1721b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  VP9_COMMON *cm = &cpi->common;
17226ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  MODE_INFO *mi = xd->mi[0];
172391037db265ecdd914a26e056cf69207b4f50924ehkuang  MB_MODE_INFO *const mbmi = &mi->mbmi;
1724b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  struct macroblock_plane *const p = &x->plane[0];
1725b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  struct macroblockd_plane *const pd = &xd->plane[0];
1726ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int label_count = 4;
172791037db265ecdd914a26e056cf69207b4f50924ehkuang  int64_t this_segment_rd = 0;
1728ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int label_mv_thresh;
1729ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int segmentyrate = 0;
17301184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const BLOCK_SIZE bsize = mbmi->sb_type;
1731f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
1732f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
1733b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  vp9_variance_fn_ptr_t *v_fn_ptr = &cpi->fn_ptr[bsize];
173491037db265ecdd914a26e056cf69207b4f50924ehkuang  ENTROPY_CONTEXT t_above[2], t_left[2];
173591037db265ecdd914a26e056cf69207b4f50924ehkuang  BEST_SEG_INFO *bsi = bsi_buf + filter_idx;
173691037db265ecdd914a26e056cf69207b4f50924ehkuang  int mode_idx;
173791037db265ecdd914a26e056cf69207b4f50924ehkuang  int subpelmv = 1, have_ref = 0;
17385ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const int has_second_rf = has_second_ref(mbmi);
1739b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int disable_inter_mode_mask = cpi->sf.disable_inter_mode_mask[bsize];
1740ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
17415ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  vpx_memcpy(t_above, pd->above_context, sizeof(t_above));
17425ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  vpx_memcpy(t_left, pd->left_context, sizeof(t_left));
1743ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1744ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // 64 makes this threshold really big effectively
1745ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // making it so that we very rarely check mvs on
1746ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // segments.   setting this to 1 would make mv thresh
1747ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // roughly equal to what it is for macroblocks
1748ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  label_mv_thresh = 1 * bsi->mvthresh / label_count;
1749ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1750ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Segmentation method overheads
175191037db265ecdd914a26e056cf69207b4f50924ehkuang  for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
175291037db265ecdd914a26e056cf69207b4f50924ehkuang    for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
1753ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // TODO(jingning,rbultje): rewrite the rate-distortion optimization
1754ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // loop for 4x4/4x8/8x4 block coding. to be replaced with new rd loop
1755b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      int_mv mode_mv[MB_MODE_COUNT][2];
1756ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
1757ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      MB_PREDICTION_MODE mode_selected = ZEROMV;
175891037db265ecdd914a26e056cf69207b4f50924ehkuang      int64_t best_rd = INT64_MAX;
1759b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      const int i = idy * 2 + idx;
1760b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      int ref;
1761b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
1762b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      for (ref = 0; ref < 1 + has_second_rf; ++ref) {
1763b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
1764b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        frame_mv[ZEROMV][frame].as_int = 0;
1765b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        vp9_append_sub8x8_mvs_for_idx(cm, xd, tile, i, ref, mi_row, mi_col,
1766b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                      &frame_mv[NEARESTMV][frame],
1767b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                      &frame_mv[NEARMV][frame]);
17685ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      }
1769b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
1770ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // search for the best motion vector on this segment
1771ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode) {
1772ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        const struct buf_2d orig_src = x->plane[0].src;
1773ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        struct buf_2d orig_pre[2];
1774ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
17759b35249446b07f40ac5fcc3205f2c048616efacchkuang        mode_idx = INTER_OFFSET(this_mode);
177691037db265ecdd914a26e056cf69207b4f50924ehkuang        bsi->rdstat[i][mode_idx].brdcost = INT64_MAX;
1777b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        if (disable_inter_mode_mask & (1 << mode_idx))
1778b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          continue;
177991037db265ecdd914a26e056cf69207b4f50924ehkuang
17806ac915abcdb404a00d927fe6308a47fcf09d9519hkuang        if (!check_best_zero_mv(cpi, mbmi->mode_context, frame_mv,
17816ac915abcdb404a00d927fe6308a47fcf09d9519hkuang                                disable_inter_mode_mask,
17826ac915abcdb404a00d927fe6308a47fcf09d9519hkuang                                this_mode, mbmi->ref_frame[0],
17836ac915abcdb404a00d927fe6308a47fcf09d9519hkuang                                mbmi->ref_frame[1]))
17846ac915abcdb404a00d927fe6308a47fcf09d9519hkuang          continue;
178591037db265ecdd914a26e056cf69207b4f50924ehkuang
17865ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        vpx_memcpy(orig_pre, pd->pre, sizeof(orig_pre));
178791037db265ecdd914a26e056cf69207b4f50924ehkuang        vpx_memcpy(bsi->rdstat[i][mode_idx].ta, t_above,
178891037db265ecdd914a26e056cf69207b4f50924ehkuang                   sizeof(bsi->rdstat[i][mode_idx].ta));
178991037db265ecdd914a26e056cf69207b4f50924ehkuang        vpx_memcpy(bsi->rdstat[i][mode_idx].tl, t_left,
179091037db265ecdd914a26e056cf69207b4f50924ehkuang                   sizeof(bsi->rdstat[i][mode_idx].tl));
1791ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1792ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        // motion search for newmv (single predictor case only)
17935ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if (!has_second_rf && this_mode == NEWMV &&
179491037db265ecdd914a26e056cf69207b4f50924ehkuang            seg_mvs[i][mbmi->ref_frame[0]].as_int == INVALID_MV) {
1795b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          int_mv *const new_mv = &mode_mv[NEWMV][0];
1796ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          int step_param = 0;
1797ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          int further_steps;
1798ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          int thissme, bestsme = INT_MAX;
1799ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          int sadpb = x->sadperbit4;
1800b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          MV mvp_full;
18011184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          int max_mv;
1802ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1803ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          /* Is the best so far sufficiently good that we cant justify doing
1804ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang           * and new motion search. */
180591037db265ecdd914a26e056cf69207b4f50924ehkuang          if (best_rd < label_mv_thresh)
1806ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            break;
1807ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1808b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          if (cpi->oxcf.mode != MODE_SECONDPASS_BEST &&
1809b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian              cpi->oxcf.mode != MODE_BESTQUALITY) {
1810ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            // use previous block's result as next block's MV predictor.
1811ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            if (i > 0) {
18121184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              bsi->mvp.as_int = mi->bmi[i - 1].as_mv[0].as_int;
1813ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              if (i == 2)
18141184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                bsi->mvp.as_int = mi->bmi[i - 2].as_mv[0].as_int;
1815ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            }
1816ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          }
18171184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          if (i == 0)
18181184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            max_mv = x->max_mv_context[mbmi->ref_frame[0]];
18191184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          else
18201184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            max_mv = MAX(abs(bsi->mvp.as_mv.row), abs(bsi->mvp.as_mv.col)) >> 3;
18211184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
1822b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          if (cpi->sf.auto_mv_step_size && cm->show_frame) {
182391037db265ecdd914a26e056cf69207b4f50924ehkuang            // Take wtd average of the step_params based on the last frame's
182491037db265ecdd914a26e056cf69207b4f50924ehkuang            // max mv magnitude and the best ref mvs of the current block for
182591037db265ecdd914a26e056cf69207b4f50924ehkuang            // the given reference.
18261184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            step_param = (vp9_init_search_range(cpi, max_mv) +
18271184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                          cpi->mv_step_param) >> 1;
182891037db265ecdd914a26e056cf69207b4f50924ehkuang          } else {
182991037db265ecdd914a26e056cf69207b4f50924ehkuang            step_param = cpi->mv_step_param;
183091037db265ecdd914a26e056cf69207b4f50924ehkuang          }
1831ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1832b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          mvp_full.row = bsi->mvp.as_mv.row >> 3;
1833b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          mvp_full.col = bsi->mvp.as_mv.col >> 3;
1834ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1835b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          if (cpi->sf.adaptive_motion_search && cm->show_frame) {
1836b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            mvp_full.row = x->pred_mv[mbmi->ref_frame[0]].as_mv.row >> 3;
1837b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            mvp_full.col = x->pred_mv[mbmi->ref_frame[0]].as_mv.col >> 3;
18381184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            step_param = MAX(step_param, 8);
18391184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          }
18401184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
18411184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param;
1842ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          // adjust src pointer for this block
1843ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          mi_buf_shift(x, i);
1844b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
1845b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          vp9_set_mv_search_range(x, &bsi->ref_mv[0]->as_mv);
1846b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
18471184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          if (cpi->sf.search_method == HEX) {
1848b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            bestsme = vp9_hex_search(x, &mvp_full,
18491184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                     step_param,
18501184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                     sadpb, 1, v_fn_ptr, 1,
1851b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                     &bsi->ref_mv[0]->as_mv,
1852b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                     &new_mv->as_mv);
1853b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            if (bestsme < INT_MAX)
1854b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian              bestsme = vp9_get_mvpred_var(x, &new_mv->as_mv,
1855b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                           &bsi->ref_mv[0]->as_mv,
1856b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                           v_fn_ptr, 1);
18571184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          } else if (cpi->sf.search_method == SQUARE) {
1858b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            bestsme = vp9_square_search(x, &mvp_full,
18591184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                        step_param,
18601184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                        sadpb, 1, v_fn_ptr, 1,
1861b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                        &bsi->ref_mv[0]->as_mv,
1862b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                        &new_mv->as_mv);
1863b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            if (bestsme < INT_MAX)
1864b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian              bestsme = vp9_get_mvpred_var(x, &new_mv->as_mv,
1865b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                           &bsi->ref_mv[0]->as_mv,
1866b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                           v_fn_ptr, 1);
18671184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          } else if (cpi->sf.search_method == BIGDIA) {
1868b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            bestsme = vp9_bigdia_search(x, &mvp_full,
18691184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                        step_param,
18701184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                        sadpb, 1, v_fn_ptr, 1,
1871b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                        &bsi->ref_mv[0]->as_mv,
1872b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                        &new_mv->as_mv);
1873b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            if (bestsme < INT_MAX)
1874b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian              bestsme = vp9_get_mvpred_var(x, &new_mv->as_mv,
1875b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                           &bsi->ref_mv[0]->as_mv,
1876b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                           v_fn_ptr, 1);
18771184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          } else {
18781184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            bestsme = vp9_full_pixel_diamond(cpi, x, &mvp_full, step_param,
18791184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                             sadpb, further_steps, 0, v_fn_ptr,
1880b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                             &bsi->ref_mv[0]->as_mv,
1881b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                             &new_mv->as_mv);
18821184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          }
1883ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1884ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          // Should we do a full search (best quality only)
1885b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          if (cpi->oxcf.mode == MODE_BESTQUALITY ||
1886b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian              cpi->oxcf.mode == MODE_SECONDPASS_BEST) {
1887b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            int_mv *const best_mv = &mi->bmi[i].as_mv[0];
1888ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            /* Check if mvp_full is within the range. */
1889b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            clamp_mv(&mvp_full, x->mv_col_min, x->mv_col_max,
1890ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                     x->mv_row_min, x->mv_row_max);
1891ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            thissme = cpi->full_search_sad(x, &mvp_full,
1892ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                           sadpb, 16, v_fn_ptr,
1893ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                           x->nmvjointcost, x->mvcost,
1894b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                           &bsi->ref_mv[0]->as_mv,
1895b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                           &best_mv->as_mv);
1896ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            if (thissme < bestsme) {
1897ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              bestsme = thissme;
1898b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian              new_mv->as_int = best_mv->as_int;
1899ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            } else {
1900b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian              // The full search result is actually worse so re-instate the
1901b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian              // previous best vector
1902b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian              best_mv->as_int = new_mv->as_int;
1903ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            }
1904ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          }
1905ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1906ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          if (bestsme < INT_MAX) {
1907ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            int distortion;
19085ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            cpi->find_fractional_mv_step(x,
1909b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                         &new_mv->as_mv,
1910b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                         &bsi->ref_mv[0]->as_mv,
1911b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                         cm->allow_high_precision_mv,
19125ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                         x->errorperbit, v_fn_ptr,
1913b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                         cpi->sf.subpel_force_stop,
1914b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                         cpi->sf.subpel_iters_per_step,
1915ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                         x->nmvjointcost, x->mvcost,
1916b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                         &distortion,
1917b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                         &x->pred_sse[mbmi->ref_frame[0]]);
1918ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
19191184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            // save motion search result for use in compound prediction
1920b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            seg_mvs[i][mbmi->ref_frame[0]].as_int = new_mv->as_int;
1921ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          }
1922ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
19231184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          if (cpi->sf.adaptive_motion_search)
1924b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            x->pred_mv[mbmi->ref_frame[0]].as_int = new_mv->as_int;
19251184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
1926ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          // restore src pointers
1927ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          mi_buf_restore(x, orig_src, orig_pre);
192891037db265ecdd914a26e056cf69207b4f50924ehkuang        }
192991037db265ecdd914a26e056cf69207b4f50924ehkuang
19305ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if (has_second_rf) {
1931ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          if (seg_mvs[i][mbmi->ref_frame[1]].as_int == INVALID_MV ||
1932ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              seg_mvs[i][mbmi->ref_frame[0]].as_int == INVALID_MV)
1933ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            continue;
19345ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        }
1935ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
19365ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if (has_second_rf && this_mode == NEWMV &&
19375ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            mbmi->interp_filter == EIGHTTAP) {
1938ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          // adjust src pointers
1939ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          mi_buf_shift(x, i);
194091037db265ecdd914a26e056cf69207b4f50924ehkuang          if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
1941ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            int rate_mv;
1942ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            joint_motion_search(cpi, x, bsize, frame_mv[this_mode],
1943ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                mi_row, mi_col, seg_mvs[i],
1944ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                &rate_mv);
1945ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            seg_mvs[i][mbmi->ref_frame[0]].as_int =
1946ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
1947ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            seg_mvs[i][mbmi->ref_frame[1]].as_int =
1948ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
1949ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          }
1950ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          // restore src pointers
1951ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          mi_buf_restore(x, orig_src, orig_pre);
1952ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
1953ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
195491037db265ecdd914a26e056cf69207b4f50924ehkuang        bsi->rdstat[i][mode_idx].brate =
1955b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            labels2mode(cpi, xd, i, this_mode, mode_mv[this_mode], frame_mv,
1956b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                        seg_mvs[i], bsi->ref_mv, x->nmvjointcost, x->mvcost);
1957b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
1958b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        for (ref = 0; ref < 1 + has_second_rf; ++ref) {
1959b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          bsi->rdstat[i][mode_idx].mvs[ref].as_int =
1960b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian              mode_mv[this_mode][ref].as_int;
196191037db265ecdd914a26e056cf69207b4f50924ehkuang          if (num_4x4_blocks_wide > 1)
1962b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            bsi->rdstat[i + 1][mode_idx].mvs[ref].as_int =
1963b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                mode_mv[this_mode][ref].as_int;
196491037db265ecdd914a26e056cf69207b4f50924ehkuang          if (num_4x4_blocks_high > 1)
1965b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            bsi->rdstat[i + 2][mode_idx].mvs[ref].as_int =
1966b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                mode_mv[this_mode][ref].as_int;
196791037db265ecdd914a26e056cf69207b4f50924ehkuang        }
1968ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1969ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        // Trap vectors that reach beyond the UMV borders
1970b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        if (mv_check_bounds(x, &mode_mv[this_mode][0].as_mv) ||
1971b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            (has_second_rf &&
1972b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian             mv_check_bounds(x, &mode_mv[this_mode][1].as_mv)))
1973ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          continue;
1974ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
197591037db265ecdd914a26e056cf69207b4f50924ehkuang        if (filter_idx > 0) {
197691037db265ecdd914a26e056cf69207b4f50924ehkuang          BEST_SEG_INFO *ref_bsi = bsi_buf;
1977b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          subpelmv = 0;
1978b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          have_ref = 1;
1979b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
1980b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          for (ref = 0; ref < 1 + has_second_rf; ++ref) {
1981b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            subpelmv |= mv_has_subpel(&mode_mv[this_mode][ref].as_mv);
1982b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            have_ref &= mode_mv[this_mode][ref].as_int ==
1983b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                ref_bsi->rdstat[i][mode_idx].mvs[ref].as_int;
198491037db265ecdd914a26e056cf69207b4f50924ehkuang          }
198591037db265ecdd914a26e056cf69207b4f50924ehkuang
198691037db265ecdd914a26e056cf69207b4f50924ehkuang          if (filter_idx > 1 && !subpelmv && !have_ref) {
198791037db265ecdd914a26e056cf69207b4f50924ehkuang            ref_bsi = bsi_buf + 1;
1988b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            have_ref = 1;
1989b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            for (ref = 0; ref < 1 + has_second_rf; ++ref)
1990b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian              have_ref &= mode_mv[this_mode][ref].as_int ==
1991b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                  ref_bsi->rdstat[i][mode_idx].mvs[ref].as_int;
199291037db265ecdd914a26e056cf69207b4f50924ehkuang          }
199391037db265ecdd914a26e056cf69207b4f50924ehkuang
199491037db265ecdd914a26e056cf69207b4f50924ehkuang          if (!subpelmv && have_ref &&
199591037db265ecdd914a26e056cf69207b4f50924ehkuang              ref_bsi->rdstat[i][mode_idx].brdcost < INT64_MAX) {
199691037db265ecdd914a26e056cf69207b4f50924ehkuang            vpx_memcpy(&bsi->rdstat[i][mode_idx], &ref_bsi->rdstat[i][mode_idx],
199791037db265ecdd914a26e056cf69207b4f50924ehkuang                       sizeof(SEG_RDSTAT));
19985ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            if (num_4x4_blocks_wide > 1)
19995ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang              bsi->rdstat[i + 1][mode_idx].eobs =
20005ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                  ref_bsi->rdstat[i + 1][mode_idx].eobs;
20015ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            if (num_4x4_blocks_high > 1)
20025ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang              bsi->rdstat[i + 2][mode_idx].eobs =
20035ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                  ref_bsi->rdstat[i + 2][mode_idx].eobs;
20045ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
200591037db265ecdd914a26e056cf69207b4f50924ehkuang            if (bsi->rdstat[i][mode_idx].brdcost < best_rd) {
200691037db265ecdd914a26e056cf69207b4f50924ehkuang              mode_selected = this_mode;
200791037db265ecdd914a26e056cf69207b4f50924ehkuang              best_rd = bsi->rdstat[i][mode_idx].brdcost;
200891037db265ecdd914a26e056cf69207b4f50924ehkuang            }
200991037db265ecdd914a26e056cf69207b4f50924ehkuang            continue;
201091037db265ecdd914a26e056cf69207b4f50924ehkuang          }
201191037db265ecdd914a26e056cf69207b4f50924ehkuang        }
201291037db265ecdd914a26e056cf69207b4f50924ehkuang
201391037db265ecdd914a26e056cf69207b4f50924ehkuang        bsi->rdstat[i][mode_idx].brdcost =
201491037db265ecdd914a26e056cf69207b4f50924ehkuang            encode_inter_mb_segment(cpi, x,
201591037db265ecdd914a26e056cf69207b4f50924ehkuang                                    bsi->segment_rd - this_segment_rd, i,
201691037db265ecdd914a26e056cf69207b4f50924ehkuang                                    &bsi->rdstat[i][mode_idx].byrate,
201791037db265ecdd914a26e056cf69207b4f50924ehkuang                                    &bsi->rdstat[i][mode_idx].bdist,
201891037db265ecdd914a26e056cf69207b4f50924ehkuang                                    &bsi->rdstat[i][mode_idx].bsse,
201991037db265ecdd914a26e056cf69207b4f50924ehkuang                                    bsi->rdstat[i][mode_idx].ta,
2020b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                    bsi->rdstat[i][mode_idx].tl,
2021b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                    mi_row, mi_col);
202291037db265ecdd914a26e056cf69207b4f50924ehkuang        if (bsi->rdstat[i][mode_idx].brdcost < INT64_MAX) {
202391037db265ecdd914a26e056cf69207b4f50924ehkuang          bsi->rdstat[i][mode_idx].brdcost += RDCOST(x->rdmult, x->rddiv,
202491037db265ecdd914a26e056cf69207b4f50924ehkuang                                            bsi->rdstat[i][mode_idx].brate, 0);
202591037db265ecdd914a26e056cf69207b4f50924ehkuang          bsi->rdstat[i][mode_idx].brate += bsi->rdstat[i][mode_idx].byrate;
2026b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          bsi->rdstat[i][mode_idx].eobs = p->eobs[i];
20275ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          if (num_4x4_blocks_wide > 1)
2028b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            bsi->rdstat[i + 1][mode_idx].eobs = p->eobs[i + 1];
20295ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          if (num_4x4_blocks_high > 1)
2030b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            bsi->rdstat[i + 2][mode_idx].eobs = p->eobs[i + 2];
203191037db265ecdd914a26e056cf69207b4f50924ehkuang        }
2032ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
203391037db265ecdd914a26e056cf69207b4f50924ehkuang        if (bsi->rdstat[i][mode_idx].brdcost < best_rd) {
2034ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          mode_selected = this_mode;
203591037db265ecdd914a26e056cf69207b4f50924ehkuang          best_rd = bsi->rdstat[i][mode_idx].brdcost;
2036ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
2037ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      } /*for each 4x4 mode*/
2038ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
203991037db265ecdd914a26e056cf69207b4f50924ehkuang      if (best_rd == INT64_MAX) {
204091037db265ecdd914a26e056cf69207b4f50924ehkuang        int iy, midx;
204191037db265ecdd914a26e056cf69207b4f50924ehkuang        for (iy = i + 1; iy < 4; ++iy)
20421184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          for (midx = 0; midx < INTER_MODES; ++midx)
204391037db265ecdd914a26e056cf69207b4f50924ehkuang            bsi->rdstat[iy][midx].brdcost = INT64_MAX;
204491037db265ecdd914a26e056cf69207b4f50924ehkuang        bsi->segment_rd = INT64_MAX;
204591037db265ecdd914a26e056cf69207b4f50924ehkuang        return;
204691037db265ecdd914a26e056cf69207b4f50924ehkuang      }
204791037db265ecdd914a26e056cf69207b4f50924ehkuang
20489b35249446b07f40ac5fcc3205f2c048616efacchkuang      mode_idx = INTER_OFFSET(mode_selected);
204991037db265ecdd914a26e056cf69207b4f50924ehkuang      vpx_memcpy(t_above, bsi->rdstat[i][mode_idx].ta, sizeof(t_above));
205091037db265ecdd914a26e056cf69207b4f50924ehkuang      vpx_memcpy(t_left, bsi->rdstat[i][mode_idx].tl, sizeof(t_left));
2051ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2052b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      labels2mode(cpi, xd, i, mode_selected, mode_mv[mode_selected],
2053b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                  frame_mv, seg_mvs[i], bsi->ref_mv, x->nmvjointcost,
2054b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                  x->mvcost);
2055ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
205691037db265ecdd914a26e056cf69207b4f50924ehkuang      br += bsi->rdstat[i][mode_idx].brate;
205791037db265ecdd914a26e056cf69207b4f50924ehkuang      bd += bsi->rdstat[i][mode_idx].bdist;
205891037db265ecdd914a26e056cf69207b4f50924ehkuang      block_sse += bsi->rdstat[i][mode_idx].bsse;
205991037db265ecdd914a26e056cf69207b4f50924ehkuang      segmentyrate += bsi->rdstat[i][mode_idx].byrate;
206091037db265ecdd914a26e056cf69207b4f50924ehkuang      this_segment_rd += bsi->rdstat[i][mode_idx].brdcost;
206191037db265ecdd914a26e056cf69207b4f50924ehkuang
206291037db265ecdd914a26e056cf69207b4f50924ehkuang      if (this_segment_rd > bsi->segment_rd) {
206391037db265ecdd914a26e056cf69207b4f50924ehkuang        int iy, midx;
206491037db265ecdd914a26e056cf69207b4f50924ehkuang        for (iy = i + 1; iy < 4; ++iy)
20651184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          for (midx = 0; midx < INTER_MODES; ++midx)
206691037db265ecdd914a26e056cf69207b4f50924ehkuang            bsi->rdstat[iy][midx].brdcost = INT64_MAX;
206791037db265ecdd914a26e056cf69207b4f50924ehkuang        bsi->segment_rd = INT64_MAX;
206891037db265ecdd914a26e056cf69207b4f50924ehkuang        return;
206991037db265ecdd914a26e056cf69207b4f50924ehkuang      }
2070ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
2071ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  } /* for each label */
2072ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
207391037db265ecdd914a26e056cf69207b4f50924ehkuang  bsi->r = br;
207491037db265ecdd914a26e056cf69207b4f50924ehkuang  bsi->d = bd;
207591037db265ecdd914a26e056cf69207b4f50924ehkuang  bsi->segment_yrate = segmentyrate;
207691037db265ecdd914a26e056cf69207b4f50924ehkuang  bsi->segment_rd = this_segment_rd;
207791037db265ecdd914a26e056cf69207b4f50924ehkuang  bsi->sse = block_sse;
2078ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
207991037db265ecdd914a26e056cf69207b4f50924ehkuang  // update the coding decisions
2080b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  for (k = 0; k < 4; ++k)
2081b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    bsi->modes[k] = mi->bmi[k].as_mode;
2082ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
2083ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
208491037db265ecdd914a26e056cf69207b4f50924ehkuangstatic int64_t rd_pick_best_mbsegmentation(VP9_COMP *cpi, MACROBLOCK *x,
20855ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                           const TileInfo *const tile,
208691037db265ecdd914a26e056cf69207b4f50924ehkuang                                           int_mv *best_ref_mv,
208791037db265ecdd914a26e056cf69207b4f50924ehkuang                                           int_mv *second_best_ref_mv,
208891037db265ecdd914a26e056cf69207b4f50924ehkuang                                           int64_t best_rd,
208991037db265ecdd914a26e056cf69207b4f50924ehkuang                                           int *returntotrate,
209091037db265ecdd914a26e056cf69207b4f50924ehkuang                                           int *returnyrate,
209191037db265ecdd914a26e056cf69207b4f50924ehkuang                                           int64_t *returndistortion,
209291037db265ecdd914a26e056cf69207b4f50924ehkuang                                           int *skippable, int64_t *psse,
209391037db265ecdd914a26e056cf69207b4f50924ehkuang                                           int mvthresh,
209491037db265ecdd914a26e056cf69207b4f50924ehkuang                                           int_mv seg_mvs[4][MAX_REF_FRAMES],
209591037db265ecdd914a26e056cf69207b4f50924ehkuang                                           BEST_SEG_INFO *bsi_buf,
209691037db265ecdd914a26e056cf69207b4f50924ehkuang                                           int filter_idx,
209791037db265ecdd914a26e056cf69207b4f50924ehkuang                                           int mi_row, int mi_col) {
2098ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int i;
209991037db265ecdd914a26e056cf69207b4f50924ehkuang  BEST_SEG_INFO *bsi = bsi_buf + filter_idx;
210091037db265ecdd914a26e056cf69207b4f50924ehkuang  MACROBLOCKD *xd = &x->e_mbd;
21016ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  MODE_INFO *mi = xd->mi[0];
210291037db265ecdd914a26e056cf69207b4f50924ehkuang  MB_MODE_INFO *mbmi = &mi->mbmi;
210391037db265ecdd914a26e056cf69207b4f50924ehkuang  int mode_idx;
2104ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2105f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  vp9_zero(*bsi);
2106ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
210791037db265ecdd914a26e056cf69207b4f50924ehkuang  bsi->segment_rd = best_rd;
2108b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  bsi->ref_mv[0] = best_ref_mv;
2109b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  bsi->ref_mv[1] = second_best_ref_mv;
211091037db265ecdd914a26e056cf69207b4f50924ehkuang  bsi->mvp.as_int = best_ref_mv->as_int;
211191037db265ecdd914a26e056cf69207b4f50924ehkuang  bsi->mvthresh = mvthresh;
2112ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2113ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0; i < 4; i++)
211491037db265ecdd914a26e056cf69207b4f50924ehkuang    bsi->modes[i] = ZEROMV;
2115ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
21165ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  rd_check_segment_txsize(cpi, x, tile, bsi_buf, filter_idx, seg_mvs,
21175ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                          mi_row, mi_col);
2118ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
211991037db265ecdd914a26e056cf69207b4f50924ehkuang  if (bsi->segment_rd > best_rd)
212091037db265ecdd914a26e056cf69207b4f50924ehkuang    return INT64_MAX;
2121ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* set it to the best */
2122ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0; i < 4; i++) {
21239b35249446b07f40ac5fcc3205f2c048616efacchkuang    mode_idx = INTER_OFFSET(bsi->modes[i]);
212491037db265ecdd914a26e056cf69207b4f50924ehkuang    mi->bmi[i].as_mv[0].as_int = bsi->rdstat[i][mode_idx].mvs[0].as_int;
21255ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (has_second_ref(mbmi))
212691037db265ecdd914a26e056cf69207b4f50924ehkuang      mi->bmi[i].as_mv[1].as_int = bsi->rdstat[i][mode_idx].mvs[1].as_int;
2127b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    x->plane[0].eobs[i] = bsi->rdstat[i][mode_idx].eobs;
21285ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    mi->bmi[i].as_mode = bsi->modes[i];
2129ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
2130ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2131ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /*
2132ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang   * used to set mbmi->mv.as_int
2133ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang   */
213491037db265ecdd914a26e056cf69207b4f50924ehkuang  *returntotrate = bsi->r;
213591037db265ecdd914a26e056cf69207b4f50924ehkuang  *returndistortion = bsi->d;
213691037db265ecdd914a26e056cf69207b4f50924ehkuang  *returnyrate = bsi->segment_yrate;
2137b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  *skippable = vp9_is_skippable_in_plane(x, BLOCK_8X8, 0);
213891037db265ecdd914a26e056cf69207b4f50924ehkuang  *psse = bsi->sse;
213991037db265ecdd914a26e056cf69207b4f50924ehkuang  mbmi->mode = bsi->modes[3];
2140ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
214191037db265ecdd914a26e056cf69207b4f50924ehkuang  return bsi->segment_rd;
2142ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
2143ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2144ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void mv_pred(VP9_COMP *cpi, MACROBLOCK *x,
2145ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                    uint8_t *ref_y_buffer, int ref_y_stride,
21461184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                    int ref_frame, BLOCK_SIZE block_size ) {
2147ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD *xd = &x->e_mbd;
21486ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
2149ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int_mv this_mv;
2150ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int i;
2151ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int zero_seen = 0;
2152ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int best_index = 0;
2153ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int best_sad = INT_MAX;
2154ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int this_sad = INT_MAX;
2155b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int max_mv = 0;
2156ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2157ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  uint8_t *src_y_ptr = x->plane[0].src.buf;
2158ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  uint8_t *ref_y_ptr;
2159ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int row_offset, col_offset;
21601184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int num_mv_refs = MAX_MV_REF_CANDIDATES +
21611184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                    (cpi->sf.adaptive_motion_search &&
21621184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                     cpi->common.show_frame &&
21631184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                     block_size < cpi->sf.max_partition_size);
2164ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2165b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int_mv pred_mv[3];
2166b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  pred_mv[0] = mbmi->ref_mvs[ref_frame][0];
2167b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  pred_mv[1] = mbmi->ref_mvs[ref_frame][1];
2168b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  pred_mv[2] = x->pred_mv[ref_frame];
2169b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
2170ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Get the sad for each candidate reference mv
21711184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  for (i = 0; i < num_mv_refs; i++) {
2172b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    this_mv.as_int = pred_mv[i].as_int;
2173ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
217491037db265ecdd914a26e056cf69207b4f50924ehkuang    max_mv = MAX(max_mv,
217591037db265ecdd914a26e056cf69207b4f50924ehkuang                 MAX(abs(this_mv.as_mv.row), abs(this_mv.as_mv.col)) >> 3);
2176b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    // only need to check zero mv once
2177a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian    if (!this_mv.as_int && zero_seen)
2178b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      continue;
2179a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian
2180ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    zero_seen = zero_seen || !this_mv.as_int;
2181ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2182ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    row_offset = this_mv.as_mv.row >> 3;
2183ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    col_offset = this_mv.as_mv.col >> 3;
2184ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ref_y_ptr = ref_y_buffer + (ref_y_stride * row_offset) + col_offset;
2185ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2186ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Find sad for current vector.
2187ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    this_sad = cpi->fn_ptr[block_size].sdf(src_y_ptr, x->plane[0].src.stride,
2188ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                           ref_y_ptr, ref_y_stride,
2189ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                           0x7fffffff);
2190ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2191ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Note if it is the best so far.
2192ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (this_sad < best_sad) {
2193ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      best_sad = this_sad;
2194ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      best_index = i;
2195ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
2196ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
2197ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2198ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Note the index of the mv that worked best in the reference list.
2199ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  x->mv_best_ref_index[ref_frame] = best_index;
220091037db265ecdd914a26e056cf69207b4f50924ehkuang  x->max_mv_context[ref_frame] = max_mv;
2201b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  x->pred_mv_sad[ref_frame] = best_sad;
2202ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
2203ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2204ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void estimate_ref_frame_costs(VP9_COMP *cpi, int segment_id,
2205ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                     unsigned int *ref_costs_single,
2206ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                     unsigned int *ref_costs_comp,
2207ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                     vp9_prob *comp_mode_p) {
2208ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  VP9_COMMON *const cm = &cpi->common;
2209ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD *const xd = &cpi->mb.e_mbd;
22101184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int seg_ref_active = vp9_segfeature_active(&cm->seg, segment_id,
2211ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                             SEG_LVL_REF_FRAME);
2212ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (seg_ref_active) {
2213ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vpx_memset(ref_costs_single, 0, MAX_REF_FRAMES * sizeof(*ref_costs_single));
2214ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vpx_memset(ref_costs_comp,   0, MAX_REF_FRAMES * sizeof(*ref_costs_comp));
2215ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    *comp_mode_p = 128;
2216ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  } else {
2217b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    vp9_prob intra_inter_p = vp9_get_intra_inter_prob(cm, xd);
2218ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vp9_prob comp_inter_p = 128;
2219ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2220b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (cm->reference_mode == REFERENCE_MODE_SELECT) {
2221b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      comp_inter_p = vp9_get_reference_mode_prob(cm, xd);
2222ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      *comp_mode_p = comp_inter_p;
2223ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    } else {
2224ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      *comp_mode_p = 128;
2225ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
2226ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2227ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ref_costs_single[INTRA_FRAME] = vp9_cost_bit(intra_inter_p, 0);
2228ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2229b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (cm->reference_mode != COMPOUND_REFERENCE) {
223091037db265ecdd914a26e056cf69207b4f50924ehkuang      vp9_prob ref_single_p1 = vp9_get_pred_prob_single_ref_p1(cm, xd);
223191037db265ecdd914a26e056cf69207b4f50924ehkuang      vp9_prob ref_single_p2 = vp9_get_pred_prob_single_ref_p2(cm, xd);
2232ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      unsigned int base_cost = vp9_cost_bit(intra_inter_p, 1);
2233ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2234b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (cm->reference_mode == REFERENCE_MODE_SELECT)
2235ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        base_cost += vp9_cost_bit(comp_inter_p, 0);
2236ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2237ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      ref_costs_single[LAST_FRAME] = ref_costs_single[GOLDEN_FRAME] =
2238ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          ref_costs_single[ALTREF_FRAME] = base_cost;
2239ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      ref_costs_single[LAST_FRAME]   += vp9_cost_bit(ref_single_p1, 0);
2240ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      ref_costs_single[GOLDEN_FRAME] += vp9_cost_bit(ref_single_p1, 1);
2241ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      ref_costs_single[ALTREF_FRAME] += vp9_cost_bit(ref_single_p1, 1);
2242ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      ref_costs_single[GOLDEN_FRAME] += vp9_cost_bit(ref_single_p2, 0);
2243ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      ref_costs_single[ALTREF_FRAME] += vp9_cost_bit(ref_single_p2, 1);
2244ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    } else {
2245ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      ref_costs_single[LAST_FRAME]   = 512;
2246ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      ref_costs_single[GOLDEN_FRAME] = 512;
2247ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      ref_costs_single[ALTREF_FRAME] = 512;
2248ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
2249b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (cm->reference_mode != SINGLE_REFERENCE) {
225091037db265ecdd914a26e056cf69207b4f50924ehkuang      vp9_prob ref_comp_p = vp9_get_pred_prob_comp_ref_p(cm, xd);
2251ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      unsigned int base_cost = vp9_cost_bit(intra_inter_p, 1);
2252ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2253b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (cm->reference_mode == REFERENCE_MODE_SELECT)
2254ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        base_cost += vp9_cost_bit(comp_inter_p, 1);
2255ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2256ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      ref_costs_comp[LAST_FRAME]   = base_cost + vp9_cost_bit(ref_comp_p, 0);
2257ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      ref_costs_comp[GOLDEN_FRAME] = base_cost + vp9_cost_bit(ref_comp_p, 1);
2258ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    } else {
2259ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      ref_costs_comp[LAST_FRAME]   = 512;
2260ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      ref_costs_comp[GOLDEN_FRAME] = 512;
2261ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
2262ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
2263ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
2264ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2265ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void store_coding_context(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
226691037db265ecdd914a26e056cf69207b4f50924ehkuang                         int mode_index,
226791037db265ecdd914a26e056cf69207b4f50924ehkuang                         int_mv *ref_mv,
226891037db265ecdd914a26e056cf69207b4f50924ehkuang                         int_mv *second_ref_mv,
2269b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                         int64_t comp_pred_diff[REFERENCE_MODES],
2270f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                         int64_t tx_size_diff[TX_MODES],
22715ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                         int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS]) {
2272ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD *const xd = &x->e_mbd;
2273ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2274ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Take a snapshot of the coding context so it can be
2275ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // restored if we decide to encode this way
2276ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  ctx->skip = x->skip;
2277ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  ctx->best_mode_index = mode_index;
22786ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  ctx->mic = *xd->mi[0];
2279ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2280b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  ctx->best_ref_mv[0].as_int = ref_mv->as_int;
2281b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  ctx->best_ref_mv[1].as_int = second_ref_mv->as_int;
2282ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2283b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  ctx->single_pred_diff = (int)comp_pred_diff[SINGLE_REFERENCE];
2284b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  ctx->comp_pred_diff   = (int)comp_pred_diff[COMPOUND_REFERENCE];
2285b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  ctx->hybrid_pred_diff = (int)comp_pred_diff[REFERENCE_MODE_SELECT];
2286ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
22875ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  vpx_memcpy(ctx->tx_rd_diff, tx_size_diff, sizeof(ctx->tx_rd_diff));
22885ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  vpx_memcpy(ctx->best_filter_diff, best_filter_diff,
22895ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang             sizeof(*best_filter_diff) * SWITCHABLE_FILTER_CONTEXTS);
2290ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
2291ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2292ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void setup_pred_block(const MACROBLOCKD *xd,
2293ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                             struct buf_2d dst[MAX_MB_PLANE],
2294ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                             const YV12_BUFFER_CONFIG *src,
2295ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                             int mi_row, int mi_col,
2296ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                             const struct scale_factors *scale,
2297ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                             const struct scale_factors *scale_uv) {
2298ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int i;
2299ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2300ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  dst[0].buf = src->y_buffer;
2301ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  dst[0].stride = src->y_stride;
2302ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  dst[1].buf = src->u_buffer;
2303ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  dst[2].buf = src->v_buffer;
2304ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  dst[1].stride = dst[2].stride = src->uv_stride;
2305ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#if CONFIG_ALPHA
2306ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  dst[3].buf = src->alpha_buffer;
2307ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  dst[3].stride = src->alpha_stride;
2308ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#endif
2309ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2310ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // TODO(jkoleszar): Make scale factors per-plane data
2311ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0; i < MAX_MB_PLANE; i++) {
2312ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    setup_pred_plane(dst + i, dst[i].buf, dst[i].stride, mi_row, mi_col,
2313ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                     i ? scale_uv : scale,
2314ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                     xd->plane[i].subsampling_x, xd->plane[i].subsampling_y);
2315ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
2316ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
2317ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2318b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianvoid vp9_setup_buffer_inter(VP9_COMP *cpi, MACROBLOCK *x,
2319b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                            const TileInfo *const tile,
2320b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                            MV_REFERENCE_FRAME ref_frame,
2321b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                            BLOCK_SIZE block_size,
2322b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                            int mi_row, int mi_col,
2323b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                            int_mv frame_nearest_mv[MAX_REF_FRAMES],
2324b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                            int_mv frame_near_mv[MAX_REF_FRAMES],
2325b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                            struct buf_2d yv12_mb[4][MAX_MB_PLANE]) {
2326b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const VP9_COMMON *cm = &cpi->common;
2327b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame);
2328ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD *const xd = &x->e_mbd;
23296ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  MODE_INFO *const mi = xd->mi[0];
2330b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int_mv *const candidates = mi->mbmi.ref_mvs[ref_frame];
2331b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const struct scale_factors *const sf = &cm->frame_refs[ref_frame - 1].sf;
2332ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2333ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // TODO(jkoleszar): Is the UV buffer ever used here? If so, need to make this
2334ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // use the UV scaling factors.
2335b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  setup_pred_block(xd, yv12_mb[ref_frame], yv12, mi_row, mi_col, sf, sf);
2336ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2337ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Gets an initial list of candidate vectors from neighbours and orders them
2338a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian  vp9_find_mv_refs(cm, xd, tile, mi, ref_frame, candidates, mi_row, mi_col);
2339ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2340ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Candidate refinement carried out at encoder and decoder
2341b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  vp9_find_best_ref_mvs(xd, cm->allow_high_precision_mv, candidates,
2342b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                        &frame_nearest_mv[ref_frame],
2343b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                        &frame_near_mv[ref_frame]);
2344ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2345ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Further refinement that is encode side only to test the top few candidates
2346ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // in full and choose the best as the centre point for subsequent searches.
2347ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // The current implementation doesn't support scaling.
2348b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (!vp9_is_scaled(sf) && block_size >= BLOCK_8X8)
2349b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12->y_stride,
2350b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            ref_frame, block_size);
2351ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
2352ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2353b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianconst YV12_BUFFER_CONFIG *vp9_get_scaled_ref_frame(const VP9_COMP *cpi,
2354b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                                   int ref_frame) {
2355b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const VP9_COMMON *const cm = &cpi->common;
2356b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int ref_idx = cm->ref_frame_map[get_ref_frame_idx(cpi, ref_frame)];
2357b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int scaled_idx = cpi->scaled_ref_idx[ref_frame - 1];
2358b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  return (scaled_idx != ref_idx) ? &cm->frame_bufs[scaled_idx].buf : NULL;
2359ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
2360ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
23616ac915abcdb404a00d927fe6308a47fcf09d9519hkuangint vp9_get_switchable_rate(const MACROBLOCK *x) {
23621184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const MACROBLOCKD *const xd = &x->e_mbd;
23636ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
23641184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const int ctx = vp9_get_pred_context_switchable_interp(xd);
23651184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  return SWITCHABLE_INTERP_RATE_FACTOR *
23661184aebb761cbeac9124c37189a80a1a58f04b6bhkuang             x->switchable_interp_costs[ctx][mbmi->interp_filter];
2367ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
2368ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2369ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
23705ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                 const TileInfo *const tile,
23711184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                 BLOCK_SIZE bsize,
2372ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                 int mi_row, int mi_col,
2373ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                 int_mv *tmp_mv, int *rate_mv) {
2374ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD *xd = &x->e_mbd;
237591037db265ecdd914a26e056cf69207b4f50924ehkuang  VP9_COMMON *cm = &cpi->common;
23766ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
2377ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0}};
2378ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int bestsme = INT_MAX;
237991037db265ecdd914a26e056cf69207b4f50924ehkuang  int further_steps, step_param;
2380ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int sadpb = x->sadperbit16;
2381b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  MV mvp_full;
2382ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int ref = mbmi->ref_frame[0];
2383b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  MV ref_mv = mbmi->ref_mvs[ref][0].as_mv;
2384ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2385ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int tmp_col_min = x->mv_col_min;
2386ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int tmp_col_max = x->mv_col_max;
2387ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int tmp_row_min = x->mv_row_min;
2388ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int tmp_row_max = x->mv_row_max;
2389ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2390b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const YV12_BUFFER_CONFIG *scaled_ref_frame = vp9_get_scaled_ref_frame(cpi,
2391b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                                                        ref);
2392b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
2393b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  MV pred_mv[3];
2394b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  pred_mv[0] = mbmi->ref_mvs[ref][0].as_mv;
2395b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  pred_mv[1] = mbmi->ref_mvs[ref][1].as_mv;
2396b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  pred_mv[2] = x->pred_mv[ref].as_mv;
2397ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2398ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (scaled_ref_frame) {
2399ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int i;
2400ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Swap out the reference frame for a version that's been scaled to
2401ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // match the resolution of the current frame, allowing the existing
2402ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // motion search code to be used without additional modifications.
2403ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (i = 0; i < MAX_MB_PLANE; i++)
2404ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      backup_yv12[i] = xd->plane[i].pre[0];
2405ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2406b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    vp9_setup_pre_planes(xd, 0, scaled_ref_frame, mi_row, mi_col, NULL);
2407ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
2408ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2409b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  vp9_set_mv_search_range(x, &ref_mv);
241091037db265ecdd914a26e056cf69207b4f50924ehkuang
2411b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  // Work out the size of the first step in the mv step search.
2412b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  // 0 here is maximum length first step. 1 is MAX >> 1 etc.
2413b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (cpi->sf.auto_mv_step_size && cpi->common.show_frame) {
2414b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    // Take wtd average of the step_params based on the last frame's
2415b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    // max mv magnitude and that based on the best ref mvs of the current
2416b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    // block for the given reference.
2417b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    step_param = (vp9_init_search_range(cpi, x->max_mv_context[ref]) +
2418b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                  cpi->mv_step_param) >> 1;
241991037db265ecdd914a26e056cf69207b4f50924ehkuang  } else {
2420b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    step_param = cpi->mv_step_param;
242191037db265ecdd914a26e056cf69207b4f50924ehkuang  }
2422ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
24231184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  if (cpi->sf.adaptive_motion_search && bsize < BLOCK_64X64 &&
24241184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      cpi->common.show_frame) {
24251184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    int boffset = 2 * (b_width_log2(BLOCK_64X64) - MIN(b_height_log2(bsize),
24261184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                                       b_width_log2(bsize)));
24271184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    step_param = MAX(step_param, boffset);
24281184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  }
24291184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
2430b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (cpi->sf.adaptive_motion_search) {
2431b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    int bwl = b_width_log2_lookup[bsize];
2432b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    int bhl = b_height_log2_lookup[bsize];
2433b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    int i;
2434b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
24351184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
2436b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (tlevel < 5)
2437b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      step_param += 2;
2438ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2439b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    for (i = LAST_FRAME; i <= ALTREF_FRAME && cpi->common.show_frame; ++i) {
2440b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
2441b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        x->pred_mv[ref].as_int = 0;
2442b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        tmp_mv->as_int = INVALID_MV;
2443b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
2444b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        if (scaled_ref_frame) {
2445b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          int i;
2446b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          for (i = 0; i < MAX_MB_PLANE; i++)
2447b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            xd->plane[i].pre[0] = backup_yv12[i];
2448b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        }
2449b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        return;
2450b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      }
2451b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    }
2452b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  }
2453b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
2454b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  mvp_full = pred_mv[x->mv_best_ref_index[ref]];
2455b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
2456b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  mvp_full.col >>= 3;
2457b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  mvp_full.row >>= 3;
2458b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
2459b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  // Further step/diamond searches as necessary
2460ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  further_steps = (cpi->sf.max_step_search_steps - 1) - step_param;
2461ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2462b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (cpi->sf.search_method == FAST_DIAMOND) {
2463b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    bestsme = vp9_fast_dia_search(x, &mvp_full, step_param, sadpb, 0,
2464b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                  &cpi->fn_ptr[bsize], 1,
2465b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                  &ref_mv, &tmp_mv->as_mv);
2466b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (bestsme < INT_MAX)
2467b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      bestsme = vp9_get_mvpred_var(x, &tmp_mv->as_mv, &ref_mv,
2468b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                   &cpi->fn_ptr[bsize], 1);
2469b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  } else if (cpi->sf.search_method == FAST_HEX) {
2470b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    bestsme = vp9_fast_hex_search(x, &mvp_full, step_param, sadpb, 0,
2471b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                  &cpi->fn_ptr[bsize], 1,
2472b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                  &ref_mv, &tmp_mv->as_mv);
2473b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (bestsme < INT_MAX)
2474b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      bestsme = vp9_get_mvpred_var(x, &tmp_mv->as_mv, &ref_mv,
2475b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                   &cpi->fn_ptr[bsize], 1);
2476b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  } else if (cpi->sf.search_method == HEX) {
2477b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    bestsme = vp9_hex_search(x, &mvp_full, step_param, sadpb, 1,
2478b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                             &cpi->fn_ptr[bsize], 1,
2479b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                             &ref_mv, &tmp_mv->as_mv);
2480b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (bestsme < INT_MAX)
2481b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      bestsme = vp9_get_mvpred_var(x, &tmp_mv->as_mv, &ref_mv,
2482b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                   &cpi->fn_ptr[bsize], 1);
24831184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  } else if (cpi->sf.search_method == SQUARE) {
2484b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    bestsme = vp9_square_search(x, &mvp_full, step_param, sadpb, 1,
2485b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                &cpi->fn_ptr[bsize], 1,
2486b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                &ref_mv, &tmp_mv->as_mv);
2487b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (bestsme < INT_MAX)
2488b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      bestsme = vp9_get_mvpred_var(x, &tmp_mv->as_mv, &ref_mv,
2489b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                   &cpi->fn_ptr[bsize], 1);
24901184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  } else if (cpi->sf.search_method == BIGDIA) {
2491b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    bestsme = vp9_bigdia_search(x, &mvp_full, step_param, sadpb, 1,
2492b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                &cpi->fn_ptr[bsize], 1,
2493b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                &ref_mv, &tmp_mv->as_mv);
2494b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (bestsme < INT_MAX)
2495b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      bestsme = vp9_get_mvpred_var(x, &tmp_mv->as_mv, &ref_mv,
2496b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                   &cpi->fn_ptr[bsize], 1);
24971184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  } else {
24981184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    bestsme = vp9_full_pixel_diamond(cpi, x, &mvp_full, step_param,
24991184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                     sadpb, further_steps, 1,
2500b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                     &cpi->fn_ptr[bsize],
2501b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                     &ref_mv, &tmp_mv->as_mv);
25021184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  }
2503ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2504ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  x->mv_col_min = tmp_col_min;
2505ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  x->mv_col_max = tmp_col_max;
2506ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  x->mv_row_min = tmp_row_min;
2507ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  x->mv_row_max = tmp_row_max;
2508ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2509ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (bestsme < INT_MAX) {
25101184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    int dis;  /* TODO: use dis in distortion calculation later. */
2511b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    cpi->find_fractional_mv_step(x, &tmp_mv->as_mv, &ref_mv,
25125ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                 cm->allow_high_precision_mv,
2513ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                 x->errorperbit,
2514b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                 &cpi->fn_ptr[bsize],
2515b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                 cpi->sf.subpel_force_stop,
2516b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                 cpi->sf.subpel_iters_per_step,
2517ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                 x->nmvjointcost, x->mvcost,
2518b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                 &dis, &x->pred_sse[ref]);
2519ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
2520b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  *rate_mv = vp9_mv_bit_cost(&tmp_mv->as_mv, &ref_mv,
25215ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                             x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
25221184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
25231184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  if (cpi->sf.adaptive_motion_search && cpi->common.show_frame)
25241184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    x->pred_mv[ref].as_int = tmp_mv->as_int;
25251184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
2526ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (scaled_ref_frame) {
2527ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int i;
2528ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (i = 0; i < MAX_MB_PLANE; i++)
2529ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      xd->plane[i].pre[0] = backup_yv12[i];
2530ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
2531ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
2532ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2533ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
25341184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                BLOCK_SIZE bsize,
2535ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                int_mv *frame_mv,
2536ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                int mi_row, int mi_col,
2537ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                int_mv single_newmv[MAX_REF_FRAMES],
2538ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                int *rate_mv) {
2539b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int pw = 4 * num_4x4_blocks_wide_lookup[bsize];
2540b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int ph = 4 * num_4x4_blocks_high_lookup[bsize];
2541ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD *xd = &x->e_mbd;
25426ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
25439b35249446b07f40ac5fcc3205f2c048616efacchkuang  const int refs[2] = { mbmi->ref_frame[0],
25449b35249446b07f40ac5fcc3205f2c048616efacchkuang                        mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1] };
2545ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int_mv ref_mv[2];
25469b35249446b07f40ac5fcc3205f2c048616efacchkuang  int ite, ref;
2547ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Prediction buffer from second frame.
2548ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  uint8_t *second_pred = vpx_memalign(16, pw * ph * sizeof(uint8_t));
25496ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  const InterpKernel *kernel = vp9_get_interp_kernel(mbmi->interp_filter);
2550ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2551ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Do joint motion search in compound mode to get more accurate mv.
25529b35249446b07f40ac5fcc3205f2c048616efacchkuang  struct buf_2d backup_yv12[2][MAX_MB_PLANE];
25539b35249446b07f40ac5fcc3205f2c048616efacchkuang  struct buf_2d scaled_first_yv12 = xd->plane[0].pre[0];
2554ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int last_besterr[2] = {INT_MAX, INT_MAX};
2555b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const YV12_BUFFER_CONFIG *const scaled_ref_frame[2] = {
2556b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    vp9_get_scaled_ref_frame(cpi, mbmi->ref_frame[0]),
2557b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    vp9_get_scaled_ref_frame(cpi, mbmi->ref_frame[1])
25589b35249446b07f40ac5fcc3205f2c048616efacchkuang  };
2559ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
25609b35249446b07f40ac5fcc3205f2c048616efacchkuang  for (ref = 0; ref < 2; ++ref) {
25619b35249446b07f40ac5fcc3205f2c048616efacchkuang    ref_mv[ref] = mbmi->ref_mvs[refs[ref]][0];
25629b35249446b07f40ac5fcc3205f2c048616efacchkuang
25639b35249446b07f40ac5fcc3205f2c048616efacchkuang    if (scaled_ref_frame[ref]) {
25649b35249446b07f40ac5fcc3205f2c048616efacchkuang      int i;
25659b35249446b07f40ac5fcc3205f2c048616efacchkuang      // Swap out the reference frame for a version that's been scaled to
25669b35249446b07f40ac5fcc3205f2c048616efacchkuang      // match the resolution of the current frame, allowing the existing
25679b35249446b07f40ac5fcc3205f2c048616efacchkuang      // motion search code to be used without additional modifications.
25689b35249446b07f40ac5fcc3205f2c048616efacchkuang      for (i = 0; i < MAX_MB_PLANE; i++)
25699b35249446b07f40ac5fcc3205f2c048616efacchkuang        backup_yv12[ref][i] = xd->plane[i].pre[ref];
2570b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      vp9_setup_pre_planes(xd, ref, scaled_ref_frame[ref], mi_row, mi_col,
2571b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                           NULL);
25729b35249446b07f40ac5fcc3205f2c048616efacchkuang    }
2573ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
25749b35249446b07f40ac5fcc3205f2c048616efacchkuang    frame_mv[refs[ref]].as_int = single_newmv[refs[ref]].as_int;
2575ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
2576ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2577ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Allow joint search multiple times iteratively for each ref frame
2578ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // and break out the search loop if it couldn't find better mv.
2579ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (ite = 0; ite < 4; ite++) {
2580ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    struct buf_2d ref_yv12[2];
2581ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int bestsme = INT_MAX;
2582ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int sadpb = x->sadperbit16;
2583ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int_mv tmp_mv;
2584ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int search_range = 3;
2585ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2586ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int tmp_col_min = x->mv_col_min;
2587ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int tmp_col_max = x->mv_col_max;
2588ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int tmp_row_min = x->mv_row_min;
2589ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int tmp_row_max = x->mv_row_max;
2590ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int id = ite % 2;
2591ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2592ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Initialized here because of compiler problem in Visual Studio.
2593ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ref_yv12[0] = xd->plane[0].pre[0];
2594ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ref_yv12[1] = xd->plane[0].pre[1];
2595ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2596ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Get pred block from second frame.
2597ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vp9_build_inter_predictor(ref_yv12[!id].buf,
2598ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                              ref_yv12[!id].stride,
2599ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                              second_pred, pw,
2600f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                              &frame_mv[refs[!id]].as_mv,
2601b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                              &xd->block_refs[!id]->sf,
2602ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                              pw, ph, 0,
26036ac915abcdb404a00d927fe6308a47fcf09d9519hkuang                              kernel, MV_PRECISION_Q3,
2604b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                              mi_col * MI_SIZE, mi_row * MI_SIZE);
2605ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2606ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Compound motion search on first ref frame.
2607ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (id)
2608ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      xd->plane[0].pre[0] = ref_yv12[id];
2609b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    vp9_set_mv_search_range(x, &ref_mv[id].as_mv);
2610ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2611ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Use mv result from single mode as mvp.
2612ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    tmp_mv.as_int = frame_mv[refs[id]].as_int;
2613ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2614ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    tmp_mv.as_mv.col >>= 3;
2615ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    tmp_mv.as_mv.row >>= 3;
2616ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2617ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Small-range full-pixel motion search
2618b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    bestsme = vp9_refining_search_8p_c(x, &tmp_mv.as_mv, sadpb,
2619ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                       search_range,
2620b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                       &cpi->fn_ptr[bsize],
2621ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                       x->nmvjointcost, x->mvcost,
2622b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                       &ref_mv[id].as_mv, second_pred,
2623ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                       pw, ph);
2624b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (bestsme < INT_MAX)
2625b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      bestsme = vp9_get_mvpred_av_var(x, &tmp_mv.as_mv, &ref_mv[id].as_mv,
2626b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                      second_pred, &cpi->fn_ptr[bsize], 1);
2627ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2628ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    x->mv_col_min = tmp_col_min;
2629ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    x->mv_col_max = tmp_col_max;
2630ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    x->mv_row_min = tmp_row_min;
2631ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    x->mv_row_max = tmp_row_max;
2632ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2633ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (bestsme < INT_MAX) {
2634ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      int dis; /* TODO: use dis in distortion calculation later. */
2635ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      unsigned int sse;
26361184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      bestsme = cpi->find_fractional_mv_step_comp(
26375ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          x, &tmp_mv.as_mv,
26385ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          &ref_mv[id].as_mv,
26395ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          cpi->common.allow_high_precision_mv,
26401184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          x->errorperbit,
2641b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          &cpi->fn_ptr[bsize],
26421184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          0, cpi->sf.subpel_iters_per_step,
26431184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          x->nmvjointcost, x->mvcost,
26441184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          &dis, &sse, second_pred,
26451184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          pw, ph);
2646ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
2647ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2648ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (id)
2649ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      xd->plane[0].pre[0] = scaled_first_yv12;
2650ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2651ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (bestsme < last_besterr[id]) {
2652ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      frame_mv[refs[id]].as_int = tmp_mv.as_int;
2653ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      last_besterr[id] = bestsme;
2654ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    } else {
2655ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      break;
2656ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
2657ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
2658ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
26599b35249446b07f40ac5fcc3205f2c048616efacchkuang  *rate_mv = 0;
2660ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
26619b35249446b07f40ac5fcc3205f2c048616efacchkuang  for (ref = 0; ref < 2; ++ref) {
26629b35249446b07f40ac5fcc3205f2c048616efacchkuang    if (scaled_ref_frame[ref]) {
26639b35249446b07f40ac5fcc3205f2c048616efacchkuang      // restore the predictor
26649b35249446b07f40ac5fcc3205f2c048616efacchkuang      int i;
26659b35249446b07f40ac5fcc3205f2c048616efacchkuang      for (i = 0; i < MAX_MB_PLANE; i++)
26669b35249446b07f40ac5fcc3205f2c048616efacchkuang        xd->plane[i].pre[ref] = backup_yv12[ref][i];
26679b35249446b07f40ac5fcc3205f2c048616efacchkuang    }
26689b35249446b07f40ac5fcc3205f2c048616efacchkuang
26699b35249446b07f40ac5fcc3205f2c048616efacchkuang    *rate_mv += vp9_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
26709b35249446b07f40ac5fcc3205f2c048616efacchkuang                                &mbmi->ref_mvs[refs[ref]][0].as_mv,
26719b35249446b07f40ac5fcc3205f2c048616efacchkuang                                x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
2672ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
2673ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2674ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vpx_free(second_pred);
2675ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
2676ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2677b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic INLINE void restore_dst_buf(MACROBLOCKD *xd,
2678b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                   uint8_t *orig_dst[MAX_MB_PLANE],
2679b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                   int orig_dst_stride[MAX_MB_PLANE]) {
2680b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int i;
2681b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  for (i = 0; i < MAX_MB_PLANE; i++) {
2682b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    xd->plane[i].dst.buf = orig_dst[i];
2683b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    xd->plane[i].dst.stride = orig_dst_stride[i];
2684b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  }
2685b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian}
2686b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
2687ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
26885ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                 const TileInfo *const tile,
26891184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                 BLOCK_SIZE bsize,
2690ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                 int64_t txfm_cache[],
269191037db265ecdd914a26e056cf69207b4f50924ehkuang                                 int *rate2, int64_t *distortion,
269291037db265ecdd914a26e056cf69207b4f50924ehkuang                                 int *skippable,
269391037db265ecdd914a26e056cf69207b4f50924ehkuang                                 int *rate_y, int64_t *distortion_y,
269491037db265ecdd914a26e056cf69207b4f50924ehkuang                                 int *rate_uv, int64_t *distortion_uv,
2695ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                 int *mode_excluded, int *disable_skip,
2696b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                 INTERP_FILTER *best_filter,
269791037db265ecdd914a26e056cf69207b4f50924ehkuang                                 int_mv (*mode_mv)[MAX_REF_FRAMES],
2698ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                 int mi_row, int mi_col,
269991037db265ecdd914a26e056cf69207b4f50924ehkuang                                 int_mv single_newmv[MAX_REF_FRAMES],
27001184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                 int64_t *psse,
27011184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                 const int64_t ref_best_rd) {
2702ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  VP9_COMMON *cm = &cpi->common;
2703ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD *xd = &x->e_mbd;
27046ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
27055ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const int is_comp_pred = has_second_ref(mbmi);
2706ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int num_refs = is_comp_pred ? 2 : 1;
2707ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int this_mode = mbmi->mode;
270891037db265ecdd914a26e056cf69207b4f50924ehkuang  int_mv *frame_mv = mode_mv[this_mode];
2709ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int i;
2710ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int refs[2] = { mbmi->ref_frame[0],
2711ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
2712ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int_mv cur_mv[2];
2713ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int64_t this_rd = 0;
271491037db265ecdd914a26e056cf69207b4f50924ehkuang  DECLARE_ALIGNED_ARRAY(16, uint8_t, tmp_buf, MAX_MB_PLANE * 64 * 64);
2715ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int pred_exists = 0;
2716ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int intpel_mv;
2717ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int64_t rd, best_rd = INT64_MAX;
271891037db265ecdd914a26e056cf69207b4f50924ehkuang  int best_needs_copy = 0;
271991037db265ecdd914a26e056cf69207b4f50924ehkuang  uint8_t *orig_dst[MAX_MB_PLANE];
272091037db265ecdd914a26e056cf69207b4f50924ehkuang  int orig_dst_stride[MAX_MB_PLANE];
272191037db265ecdd914a26e056cf69207b4f50924ehkuang  int rs = 0;
2722ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
27235ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (is_comp_pred) {
27245ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (frame_mv[refs[0]].as_int == INVALID_MV ||
27255ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        frame_mv[refs[1]].as_int == INVALID_MV)
27265ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      return INT64_MAX;
27275ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
27285ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
2729f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  if (this_mode == NEWMV) {
2730ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int rate_mv;
2731f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    if (is_comp_pred) {
2732f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      // Initialize mv using single prediction mode result.
2733f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
2734f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
2735ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2736f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
2737f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        joint_motion_search(cpi, x, bsize, frame_mv,
2738f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                            mi_row, mi_col, single_newmv, &rate_mv);
2739ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      } else {
27405ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        rate_mv  = vp9_mv_bit_cost(&frame_mv[refs[0]].as_mv,
27415ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                   &mbmi->ref_mvs[refs[0]][0].as_mv,
27425ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                   x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
27435ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        rate_mv += vp9_mv_bit_cost(&frame_mv[refs[1]].as_mv,
27445ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                   &mbmi->ref_mvs[refs[1]][0].as_mv,
27455ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                   x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
2746ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
2747f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      *rate2 += rate_mv;
2748f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    } else {
2749f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      int_mv tmp_mv;
27505ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      single_motion_search(cpi, x, tile, bsize, mi_row, mi_col,
27515ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                           &tmp_mv, &rate_mv);
2752b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (tmp_mv.as_int == INVALID_MV)
2753b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        return INT64_MAX;
2754f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      *rate2 += rate_mv;
2755f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      frame_mv[refs[0]].as_int =
27566ac915abcdb404a00d927fe6308a47fcf09d9519hkuang          xd->mi[0]->bmi[0].as_mv[0].as_int = tmp_mv.as_int;
2757f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      single_newmv[refs[0]].as_int = tmp_mv.as_int;
2758f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    }
2759ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
276091037db265ecdd914a26e056cf69207b4f50924ehkuang
2761ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0; i < num_refs; ++i) {
2762ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    cur_mv[i] = frame_mv[refs[i]];
2763ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Clip "next_nearest" so that it does not extend to far out of image
2764f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    if (this_mode != NEWMV)
2765f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      clamp_mv2(&cur_mv[i].as_mv, xd);
2766ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2767b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (mv_check_bounds(x, &cur_mv[i].as_mv))
2768ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      return INT64_MAX;
2769ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    mbmi->mv[i].as_int = cur_mv[i].as_int;
2770ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
2771ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
277291037db265ecdd914a26e056cf69207b4f50924ehkuang  // do first prediction into the destination buffer. Do the next
277391037db265ecdd914a26e056cf69207b4f50924ehkuang  // prediction into a temporary buffer. Then keep track of which one
277491037db265ecdd914a26e056cf69207b4f50924ehkuang  // of these currently holds the best predictor, and use the other
277591037db265ecdd914a26e056cf69207b4f50924ehkuang  // one for future predictions. In the end, copy from tmp_buf to
277691037db265ecdd914a26e056cf69207b4f50924ehkuang  // dst if necessary.
277791037db265ecdd914a26e056cf69207b4f50924ehkuang  for (i = 0; i < MAX_MB_PLANE; i++) {
277891037db265ecdd914a26e056cf69207b4f50924ehkuang    orig_dst[i] = xd->plane[i].dst.buf;
277991037db265ecdd914a26e056cf69207b4f50924ehkuang    orig_dst_stride[i] = xd->plane[i].dst.stride;
278091037db265ecdd914a26e056cf69207b4f50924ehkuang  }
278191037db265ecdd914a26e056cf69207b4f50924ehkuang
2782ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* We don't include the cost of the second reference here, because there
2783ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang   * are only three options: Last/Golden, ARF/Last or Golden/ARF, or in other
2784ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang   * words if you present them in that order, the second one is always known
2785ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang   * if the first is known */
2786b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  *rate2 += cost_mv_ref(cpi, this_mode, mbmi->mode_context[refs[0]]);
278791037db265ecdd914a26e056cf69207b4f50924ehkuang
2788b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (!(*mode_excluded))
2789b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    *mode_excluded = is_comp_pred ? cm->reference_mode == SINGLE_REFERENCE
2790b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                  : cm->reference_mode == COMPOUND_REFERENCE;
2791ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2792ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  pred_exists = 0;
2793ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Are all MVs integer pel for Y and UV
2794b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  intpel_mv = !mv_has_subpel(&mbmi->mv[0].as_mv);
2795ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (is_comp_pred)
2796b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    intpel_mv &= !mv_has_subpel(&mbmi->mv[1].as_mv);
2797b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
2798ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Search for best switchable filter by checking the variance of
2799ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // pred error irrespective of whether the filter will be used
2800b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  cpi->mask_filter_rd = 0;
2801b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i)
2802b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    cpi->rd_filter_cache[i] = INT64_MAX;
2803b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
2804b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (cm->interp_filter != BILINEAR) {
2805ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    *best_filter = EIGHTTAP;
28061184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    if (x->source_variance <
28071184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        cpi->sf.disable_filter_search_var_thresh) {
28081184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      *best_filter = EIGHTTAP;
28091184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    } else {
2810b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      int newbest;
28111184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      int tmp_rate_sum = 0;
28121184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      int64_t tmp_dist_sum = 0;
28131184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
28141184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      for (i = 0; i < SWITCHABLE_FILTERS; ++i) {
28151184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        int j;
28161184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        int64_t rs_rd;
28171184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        mbmi->interp_filter = i;
28186ac915abcdb404a00d927fe6308a47fcf09d9519hkuang        rs = vp9_get_switchable_rate(x);
28191184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0);
28201184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
28211184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        if (i > 0 && intpel_mv) {
2822b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          rd = RDCOST(x->rdmult, x->rddiv, tmp_rate_sum, tmp_dist_sum);
2823b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          cpi->rd_filter_cache[i] = rd;
28241184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          cpi->rd_filter_cache[SWITCHABLE_FILTERS] =
2825b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian              MIN(cpi->rd_filter_cache[SWITCHABLE_FILTERS], rd + rs_rd);
2826b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          if (cm->interp_filter == SWITCHABLE)
28271184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            rd += rs_rd;
2828b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          cpi->mask_filter_rd = MAX(cpi->mask_filter_rd, rd);
282991037db265ecdd914a26e056cf69207b4f50924ehkuang        } else {
28301184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          int rate_sum = 0;
28311184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          int64_t dist_sum = 0;
2832b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          if ((cm->interp_filter == SWITCHABLE &&
28331184aebb761cbeac9124c37189a80a1a58f04b6bhkuang               (!i || best_needs_copy)) ||
2834b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian              (cm->interp_filter != SWITCHABLE &&
2835b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian               (cm->interp_filter == mbmi->interp_filter ||
28361184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                (i == 0 && intpel_mv)))) {
2837b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            restore_dst_buf(xd, orig_dst, orig_dst_stride);
28381184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          } else {
28391184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            for (j = 0; j < MAX_MB_PLANE; j++) {
28401184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              xd->plane[j].dst.buf = tmp_buf + j * 64 * 64;
28411184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              xd->plane[j].dst.stride = 64;
28421184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            }
28431184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          }
28441184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          vp9_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
28451184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          model_rd_for_sb(cpi, bsize, x, xd, &rate_sum, &dist_sum);
2846b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
2847b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          rd = RDCOST(x->rdmult, x->rddiv, rate_sum, dist_sum);
2848b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          cpi->rd_filter_cache[i] = rd;
28491184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          cpi->rd_filter_cache[SWITCHABLE_FILTERS] =
2850b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian              MIN(cpi->rd_filter_cache[SWITCHABLE_FILTERS], rd + rs_rd);
2851b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          if (cm->interp_filter == SWITCHABLE)
28521184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            rd += rs_rd;
2853b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          cpi->mask_filter_rd = MAX(cpi->mask_filter_rd, rd);
2854b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
28551184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          if (i == 0 && intpel_mv) {
28561184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            tmp_rate_sum = rate_sum;
28571184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            tmp_dist_sum = dist_sum;
285891037db265ecdd914a26e056cf69207b4f50924ehkuang          }
285991037db265ecdd914a26e056cf69207b4f50924ehkuang        }
2860b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
28611184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        if (i == 0 && cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
28621184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          if (rd / 2 > ref_best_rd) {
2863b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            restore_dst_buf(xd, orig_dst, orig_dst_stride);
28641184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            return INT64_MAX;
286591037db265ecdd914a26e056cf69207b4f50924ehkuang          }
286691037db265ecdd914a26e056cf69207b4f50924ehkuang        }
28671184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        newbest = i == 0 || rd < best_rd;
28681184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
28691184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        if (newbest) {
28701184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          best_rd = rd;
28711184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          *best_filter = mbmi->interp_filter;
2872b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          if (cm->interp_filter == SWITCHABLE && i && !intpel_mv)
28731184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            best_needs_copy = !best_needs_copy;
28741184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        }
2875ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2876b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        if ((cm->interp_filter == SWITCHABLE && newbest) ||
2877b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            (cm->interp_filter != SWITCHABLE &&
2878b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian             cm->interp_filter == mbmi->interp_filter)) {
28791184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          pred_exists = 1;
28801184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        }
2881ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
2882b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      restore_dst_buf(xd, orig_dst, orig_dst_stride);
288391037db265ecdd914a26e056cf69207b4f50924ehkuang    }
288491037db265ecdd914a26e056cf69207b4f50924ehkuang  }
2885f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  // Set the appropriate filter
2886b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  mbmi->interp_filter = cm->interp_filter != SWITCHABLE ?
2887b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      cm->interp_filter : *best_filter;
28886ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  rs = cm->interp_filter == SWITCHABLE ? vp9_get_switchable_rate(x) : 0;
2889ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2890ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (pred_exists) {
289191037db265ecdd914a26e056cf69207b4f50924ehkuang    if (best_needs_copy) {
289291037db265ecdd914a26e056cf69207b4f50924ehkuang      // again temporarily set the buffers to local memory to prevent a memcpy
289391037db265ecdd914a26e056cf69207b4f50924ehkuang      for (i = 0; i < MAX_MB_PLANE; i++) {
289491037db265ecdd914a26e056cf69207b4f50924ehkuang        xd->plane[i].dst.buf = tmp_buf + i * 64 * 64;
289591037db265ecdd914a26e056cf69207b4f50924ehkuang        xd->plane[i].dst.stride = 64;
289691037db265ecdd914a26e056cf69207b4f50924ehkuang      }
2897ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
2898ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  } else {
2899ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Handles the special case when a filter that is not in the
2900ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // switchable list (ex. bilinear, 6-tap) is indicated at the frame level
2901ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vp9_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
2902ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
2903ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
290491037db265ecdd914a26e056cf69207b4f50924ehkuang  if (cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
290591037db265ecdd914a26e056cf69207b4f50924ehkuang    int tmp_rate;
290691037db265ecdd914a26e056cf69207b4f50924ehkuang    int64_t tmp_dist;
290791037db265ecdd914a26e056cf69207b4f50924ehkuang    model_rd_for_sb(cpi, bsize, x, xd, &tmp_rate, &tmp_dist);
290891037db265ecdd914a26e056cf69207b4f50924ehkuang    rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist);
290991037db265ecdd914a26e056cf69207b4f50924ehkuang    // if current pred_error modeled rd is substantially more than the best
291091037db265ecdd914a26e056cf69207b4f50924ehkuang    // so far, do not bother doing full rd
291191037db265ecdd914a26e056cf69207b4f50924ehkuang    if (rd / 2 > ref_best_rd) {
2912b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      restore_dst_buf(xd, orig_dst, orig_dst_stride);
291391037db265ecdd914a26e056cf69207b4f50924ehkuang      return INT64_MAX;
291491037db265ecdd914a26e056cf69207b4f50924ehkuang    }
291591037db265ecdd914a26e056cf69207b4f50924ehkuang  }
291691037db265ecdd914a26e056cf69207b4f50924ehkuang
2917b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (cm->interp_filter == SWITCHABLE)
29186ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    *rate2 += vp9_get_switchable_rate(x);
2919f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
2920b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (!is_comp_pred) {
2921a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian    if (!x->in_active_map) {
2922a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian      if (psse)
2923a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian        *psse = 0;
2924a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian      *distortion = 0;
2925f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      x->skip = 1;
2926a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian    } else if (cpi->allow_encode_breakout && x->encode_breakout) {
29271184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      const BLOCK_SIZE y_size = get_plane_block_size(bsize, &xd->plane[0]);
29281184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      const BLOCK_SIZE uv_size = get_plane_block_size(bsize, &xd->plane[1]);
2929f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      unsigned int var, sse;
2930f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      // Skipping threshold for ac.
2931f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      unsigned int thresh_ac;
2932b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      // Set a maximum for threshold to avoid big PSNR loss in low bitrate case.
29331184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      // Use extreme low threshold for static frames to limit skipping.
2934b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      const unsigned int max_thresh = (cpi->allow_encode_breakout ==
2935b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                      ENCODE_BREAKOUT_LIMITED) ? 128 : 36000;
2936b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      // The encode_breakout input
2937b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      const unsigned int min_thresh =
2938b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          MIN(((unsigned int)x->encode_breakout << 4), max_thresh);
2939f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
2940f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      // Calculate threshold according to dequant value.
2941f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      thresh_ac = (xd->plane[0].dequant[1] * xd->plane[0].dequant[1]) / 9;
2942b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      thresh_ac = clamp(thresh_ac, min_thresh, max_thresh);
29431184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
2944f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      var = cpi->fn_ptr[y_size].vf(x->plane[0].src.buf, x->plane[0].src.stride,
2945f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                                   xd->plane[0].dst.buf,
2946f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                                   xd->plane[0].dst.stride, &sse);
2947f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
2948f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      // Adjust threshold according to partition size.
2949f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      thresh_ac >>= 8 - (b_width_log2_lookup[bsize] +
2950f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          b_height_log2_lookup[bsize]);
2951f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
2952f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      // Y skipping condition checking
2953f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      if (sse < thresh_ac || sse == 0) {
2954f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        // Skipping threshold for dc
2955f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        unsigned int thresh_dc;
2956f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
2957f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        thresh_dc = (xd->plane[0].dequant[0] * xd->plane[0].dequant[0] >> 6);
2958f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
2959f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        // dc skipping checking
2960f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        if ((sse - var) < thresh_dc || sse == var) {
2961f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          unsigned int sse_u, sse_v;
2962f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          unsigned int var_u, var_v;
2963f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
2964f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          var_u = cpi->fn_ptr[uv_size].vf(x->plane[1].src.buf,
2965f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                                          x->plane[1].src.stride,
2966f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                                          xd->plane[1].dst.buf,
2967f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                                          xd->plane[1].dst.stride, &sse_u);
2968f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
2969f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          // U skipping condition checking
2970f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          if ((sse_u * 4 < thresh_ac || sse_u == 0) &&
2971f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang              (sse_u - var_u < thresh_dc || sse_u == var_u)) {
2972f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang            var_v = cpi->fn_ptr[uv_size].vf(x->plane[2].src.buf,
2973f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                                            x->plane[2].src.stride,
2974f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                                            xd->plane[2].dst.buf,
2975f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                                            xd->plane[2].dst.stride, &sse_v);
2976f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
2977f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang            // V skipping condition checking
2978f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang            if ((sse_v * 4 < thresh_ac || sse_v == 0) &&
2979f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                (sse_v - var_v < thresh_dc || sse_v == var_v)) {
2980f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang              x->skip = 1;
2981f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
29821184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              // The cost of skip bit needs to be added.
2983b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian              *rate2 += vp9_cost_bit(vp9_get_skip_prob(cm, xd), 1);
2984f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
2985f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang              // Scaling factor for SSE from spatial domain to frequency domain
2986f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang              // is 16. Adjust distortion accordingly.
2987f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang              *distortion_uv = (sse_u + sse_v) << 4;
2988f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang              *distortion = (sse << 4) + *distortion_uv;
2989f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
2990f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang              *disable_skip = 1;
2991f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang              this_rd = RDCOST(x->rdmult, x->rddiv, *rate2, *distortion);
2992f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang            }
2993f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          }
2994ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
2995ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
2996ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
2997ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
2998ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2999ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (!x->skip) {
3000ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int skippable_y, skippable_uv;
30011184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    int64_t sseuv = INT64_MAX;
30021184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    int64_t rdcosty = INT64_MAX;
3003ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3004ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Y cost and distortion
3005b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    inter_super_block_yrd(cpi, x, rate_y, distortion_y, &skippable_y, psse,
3006b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                          bsize, txfm_cache, ref_best_rd);
300791037db265ecdd914a26e056cf69207b4f50924ehkuang
300891037db265ecdd914a26e056cf69207b4f50924ehkuang    if (*rate_y == INT_MAX) {
300991037db265ecdd914a26e056cf69207b4f50924ehkuang      *rate2 = INT_MAX;
301091037db265ecdd914a26e056cf69207b4f50924ehkuang      *distortion = INT64_MAX;
3011b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      restore_dst_buf(xd, orig_dst, orig_dst_stride);
301291037db265ecdd914a26e056cf69207b4f50924ehkuang      return INT64_MAX;
301391037db265ecdd914a26e056cf69207b4f50924ehkuang    }
3014ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3015ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    *rate2 += *rate_y;
3016ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    *distortion += *distortion_y;
3017ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
30181184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    rdcosty = RDCOST(x->rdmult, x->rddiv, *rate2, *distortion);
30191184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    rdcosty = MIN(rdcosty, RDCOST(x->rdmult, x->rddiv, 0, *psse));
30201184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
30215ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    super_block_uvrd(cpi, x, rate_uv, distortion_uv, &skippable_uv, &sseuv,
30221184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                     bsize, ref_best_rd - rdcosty);
30231184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    if (*rate_uv == INT_MAX) {
30241184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      *rate2 = INT_MAX;
30251184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      *distortion = INT64_MAX;
3026b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      restore_dst_buf(xd, orig_dst, orig_dst_stride);
30271184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      return INT64_MAX;
30281184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    }
3029ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
303091037db265ecdd914a26e056cf69207b4f50924ehkuang    *psse += sseuv;
3031ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    *rate2 += *rate_uv;
3032ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    *distortion += *distortion_uv;
3033ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    *skippable = skippable_y && skippable_uv;
3034ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
3035ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3036b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  restore_dst_buf(xd, orig_dst, orig_dst_stride);
3037ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return this_rd;  // if 0, this will be re-calculated by caller
3038ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
3039ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
30409b35249446b07f40ac5fcc3205f2c048616efacchkuangstatic void swap_block_ptr(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
30419b35249446b07f40ac5fcc3205f2c048616efacchkuang                           int max_plane) {
30429b35249446b07f40ac5fcc3205f2c048616efacchkuang  struct macroblock_plane *const p = x->plane;
30439b35249446b07f40ac5fcc3205f2c048616efacchkuang  struct macroblockd_plane *const pd = x->e_mbd.plane;
30449b35249446b07f40ac5fcc3205f2c048616efacchkuang  int i;
30459b35249446b07f40ac5fcc3205f2c048616efacchkuang
30469b35249446b07f40ac5fcc3205f2c048616efacchkuang  for (i = 0; i < max_plane; ++i) {
30479b35249446b07f40ac5fcc3205f2c048616efacchkuang    p[i].coeff    = ctx->coeff_pbuf[i][1];
3048b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    p[i].qcoeff  = ctx->qcoeff_pbuf[i][1];
30499b35249446b07f40ac5fcc3205f2c048616efacchkuang    pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][1];
3050b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    p[i].eobs    = ctx->eobs_pbuf[i][1];
30519b35249446b07f40ac5fcc3205f2c048616efacchkuang
30529b35249446b07f40ac5fcc3205f2c048616efacchkuang    ctx->coeff_pbuf[i][1]   = ctx->coeff_pbuf[i][0];
30539b35249446b07f40ac5fcc3205f2c048616efacchkuang    ctx->qcoeff_pbuf[i][1]  = ctx->qcoeff_pbuf[i][0];
30549b35249446b07f40ac5fcc3205f2c048616efacchkuang    ctx->dqcoeff_pbuf[i][1] = ctx->dqcoeff_pbuf[i][0];
30559b35249446b07f40ac5fcc3205f2c048616efacchkuang    ctx->eobs_pbuf[i][1]    = ctx->eobs_pbuf[i][0];
30569b35249446b07f40ac5fcc3205f2c048616efacchkuang
30579b35249446b07f40ac5fcc3205f2c048616efacchkuang    ctx->coeff_pbuf[i][0]   = p[i].coeff;
3058b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    ctx->qcoeff_pbuf[i][0]  = p[i].qcoeff;
30599b35249446b07f40ac5fcc3205f2c048616efacchkuang    ctx->dqcoeff_pbuf[i][0] = pd[i].dqcoeff;
3060b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    ctx->eobs_pbuf[i][0]    = p[i].eobs;
30619b35249446b07f40ac5fcc3205f2c048616efacchkuang  }
30629b35249446b07f40ac5fcc3205f2c048616efacchkuang}
30639b35249446b07f40ac5fcc3205f2c048616efacchkuang
3064ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid vp9_rd_pick_intra_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
306591037db265ecdd914a26e056cf69207b4f50924ehkuang                               int *returnrate, int64_t *returndist,
30661184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                               BLOCK_SIZE bsize,
306791037db265ecdd914a26e056cf69207b4f50924ehkuang                               PICK_MODE_CONTEXT *ctx, int64_t best_rd) {
306891037db265ecdd914a26e056cf69207b4f50924ehkuang  VP9_COMMON *const cm = &cpi->common;
306991037db265ecdd914a26e056cf69207b4f50924ehkuang  MACROBLOCKD *const xd = &x->e_mbd;
307091037db265ecdd914a26e056cf69207b4f50924ehkuang  int rate_y = 0, rate_uv = 0, rate_y_tokenonly = 0, rate_uv_tokenonly = 0;
30711184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int y_skip = 0, uv_skip = 0;
3072f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  int64_t dist_y = 0, dist_uv = 0, tx_cache[TX_MODES] = { 0 };
3073b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  TX_SIZE max_uv_tx_size;
307491037db265ecdd914a26e056cf69207b4f50924ehkuang  x->skip_encode = 0;
3075ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  ctx->skip = 0;
30766ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  xd->mi[0]->mbmi.ref_frame[0] = INTRA_FRAME;
3077b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
30781184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  if (bsize >= BLOCK_8X8) {
307991037db265ecdd914a26e056cf69207b4f50924ehkuang    if (rd_pick_intra_sby_mode(cpi, x, &rate_y, &rate_y_tokenonly,
3080f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                               &dist_y, &y_skip, bsize, tx_cache,
308191037db265ecdd914a26e056cf69207b4f50924ehkuang                               best_rd) >= best_rd) {
308291037db265ecdd914a26e056cf69207b4f50924ehkuang      *returnrate = INT_MAX;
308391037db265ecdd914a26e056cf69207b4f50924ehkuang      return;
308491037db265ecdd914a26e056cf69207b4f50924ehkuang    }
30856ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    max_uv_tx_size = get_uv_tx_size_impl(xd->mi[0]->mbmi.tx_size, bsize);
30869b35249446b07f40ac5fcc3205f2c048616efacchkuang    rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv, &rate_uv_tokenonly,
3087b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                            &dist_uv, &uv_skip, bsize, max_uv_tx_size);
308891037db265ecdd914a26e056cf69207b4f50924ehkuang  } else {
308991037db265ecdd914a26e056cf69207b4f50924ehkuang    y_skip = 0;
3090f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate_y, &rate_y_tokenonly,
3091f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                                     &dist_y, best_rd) >= best_rd) {
309291037db265ecdd914a26e056cf69207b4f50924ehkuang      *returnrate = INT_MAX;
309391037db265ecdd914a26e056cf69207b4f50924ehkuang      return;
309491037db265ecdd914a26e056cf69207b4f50924ehkuang    }
30956ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    max_uv_tx_size = get_uv_tx_size_impl(xd->mi[0]->mbmi.tx_size, bsize);
30969b35249446b07f40ac5fcc3205f2c048616efacchkuang    rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv, &rate_uv_tokenonly,
3097b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                            &dist_uv, &uv_skip, BLOCK_8X8, max_uv_tx_size);
309891037db265ecdd914a26e056cf69207b4f50924ehkuang  }
3099ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3100ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (y_skip && uv_skip) {
3101ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    *returnrate = rate_y + rate_uv - rate_y_tokenonly - rate_uv_tokenonly +
3102b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                  vp9_cost_bit(vp9_get_skip_prob(cm, xd), 1);
31031184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    *returndist = dist_y + dist_uv;
3104f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    vp9_zero(ctx->tx_rd_diff);
3105ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  } else {
310691037db265ecdd914a26e056cf69207b4f50924ehkuang    int i;
3107b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    *returnrate = rate_y + rate_uv + vp9_cost_bit(vp9_get_skip_prob(cm, xd), 0);
31081184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    *returndist = dist_y + dist_uv;
3109f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    if (cpi->sf.tx_size_search_method == USE_FULL_RD)
31105ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      for (i = 0; i < TX_MODES; i++) {
31115ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if (tx_cache[i] < INT64_MAX && tx_cache[cm->tx_mode] < INT64_MAX)
31125ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          ctx->tx_rd_diff[i] = tx_cache[i] - tx_cache[cm->tx_mode];
31135ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        else
31145ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          ctx->tx_rd_diff[i] = 0;
31155ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      }
3116ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
3117ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
31186ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  ctx->mic = *xd->mi[0];
3119ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
3120ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3121ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangint64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
31225ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                  const TileInfo *const tile,
3123ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                  int mi_row, int mi_col,
3124ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                  int *returnrate,
312591037db265ecdd914a26e056cf69207b4f50924ehkuang                                  int64_t *returndistortion,
31261184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                  BLOCK_SIZE bsize,
312791037db265ecdd914a26e056cf69207b4f50924ehkuang                                  PICK_MODE_CONTEXT *ctx,
312891037db265ecdd914a26e056cf69207b4f50924ehkuang                                  int64_t best_rd_so_far) {
3129b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  VP9_COMMON *const cm = &cpi->common;
3130b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  MACROBLOCKD *const xd = &x->e_mbd;
31316ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3132b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const struct segmentation *const seg = &cm->seg;
31335ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MB_PREDICTION_MODE this_mode;
3134f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  MV_REFERENCE_FRAME ref_frame, second_ref_frame;
31351184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  unsigned char segment_id = mbmi->segment_id;
3136ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int comp_pred, i;
3137ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
3138ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  struct buf_2d yv12_mb[4][MAX_MB_PLANE];
31391184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int_mv single_newmv[MAX_REF_FRAMES] = { { 0 } };
3140ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  static const int flag_list[4] = { 0, VP9_LAST_FLAG, VP9_GOLD_FLAG,
3141ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                    VP9_ALT_FLAG };
314291037db265ecdd914a26e056cf69207b4f50924ehkuang  int64_t best_rd = best_rd_so_far;
3143f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  int64_t best_tx_rd[TX_MODES];
3144f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  int64_t best_tx_diff[TX_MODES];
3145b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int64_t best_pred_diff[REFERENCE_MODES];
3146b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int64_t best_pred_rd[REFERENCE_MODES];
31475ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int64_t best_filter_rd[SWITCHABLE_FILTER_CONTEXTS];
31485ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS];
31491184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  MB_MODE_INFO best_mbmode = { 0 };
3150ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int mode_index, best_mode_index = 0;
3151ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  unsigned int ref_costs_single[MAX_REF_FRAMES], ref_costs_comp[MAX_REF_FRAMES];
3152ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vp9_prob comp_mode_p;
315391037db265ecdd914a26e056cf69207b4f50924ehkuang  int64_t best_intra_rd = INT64_MAX;
315491037db265ecdd914a26e056cf69207b4f50924ehkuang  int64_t best_inter_rd = INT64_MAX;
315591037db265ecdd914a26e056cf69207b4f50924ehkuang  MB_PREDICTION_MODE best_intra_mode = DC_PRED;
315691037db265ecdd914a26e056cf69207b4f50924ehkuang  MV_REFERENCE_FRAME best_inter_ref_frame = LAST_FRAME;
3157b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  INTERP_FILTER tmp_best_filter = SWITCHABLE;
3158f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  int rate_uv_intra[TX_SIZES], rate_uv_tokenonly[TX_SIZES];
3159f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  int64_t dist_uv[TX_SIZES];
3160f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  int skip_uv[TX_SIZES];
3161f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  MB_PREDICTION_MODE mode_uv[TX_SIZES];
3162ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int64_t mode_distortions[MB_MODE_COUNT] = {-1};
31635ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int intra_cost_penalty = 20 * vp9_dc_quant(cm->base_qindex, cm->y_dc_delta_q);
31641184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const int bws = num_8x8_blocks_wide_lookup[bsize] / 2;
31651184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const int bhs = num_8x8_blocks_high_lookup[bsize] / 2;
316691037db265ecdd914a26e056cf69207b4f50924ehkuang  int best_skip2 = 0;
3167b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int mode_skip_mask = 0;
3168a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian  int mode_skip_start = cpi->sf.mode_skip_start + 1;
3169b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int *const rd_threshes = cpi->rd_threshes[segment_id][bsize];
3170b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int *const rd_thresh_freq_fact = cpi->rd_thresh_freq_fact[bsize];
3171b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int mode_search_skip_flags = cpi->sf.mode_search_skip_flags;
3172b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  const int intra_y_mode_mask =
3173b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      cpi->sf.intra_y_mode_mask[max_txsize_lookup[bsize]];
3174a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian  int disable_inter_mode_mask = cpi->sf.disable_inter_mode_mask[bsize];
317591037db265ecdd914a26e056cf69207b4f50924ehkuang
31769b35249446b07f40ac5fcc3205f2c048616efacchkuang  x->skip_encode = cpi->sf.skip_encode_frame && x->q_index < QIDX_SKIP_THRESH;
3177ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3178ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  estimate_ref_frame_costs(cpi, segment_id, ref_costs_single, ref_costs_comp,
3179ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                           &comp_mode_p);
3180ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3181b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  for (i = 0; i < REFERENCE_MODES; ++i)
3182ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    best_pred_rd[i] = INT64_MAX;
3183f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  for (i = 0; i < TX_MODES; i++)
3184f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    best_tx_rd[i] = INT64_MAX;
31855ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
318691037db265ecdd914a26e056cf69207b4f50924ehkuang    best_filter_rd[i] = INT64_MAX;
3187f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  for (i = 0; i < TX_SIZES; i++)
318891037db265ecdd914a26e056cf69207b4f50924ehkuang    rate_uv_intra[i] = INT_MAX;
3189b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  for (i = 0; i < MAX_REF_FRAMES; ++i)
3190b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    x->pred_sse[i] = INT_MAX;
319191037db265ecdd914a26e056cf69207b4f50924ehkuang
319291037db265ecdd914a26e056cf69207b4f50924ehkuang  *returnrate = INT_MAX;
3193ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3194b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
3195b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    x->pred_mv_sad[ref_frame] = INT_MAX;
3196b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (cpi->ref_frame_flags & flag_list[ref_frame]) {
3197b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      vp9_setup_buffer_inter(cpi, x, tile,
31986ac915abcdb404a00d927fe6308a47fcf09d9519hkuang                             ref_frame, bsize, mi_row, mi_col,
3199b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                             frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
3200b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    }
3201b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
3202b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    frame_mv[ZEROMV][ref_frame].as_int = 0;
3203b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  }
3204b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
3205b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
3206b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    // All modes from vp9_mode_order that use this frame as any ref
3207b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    static const int ref_frame_mask_all[] = {
3208b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        0x0, 0x123291, 0x25c444, 0x39b722
3209b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    };
3210b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    // Fixed mv modes (NEARESTMV, NEARMV, ZEROMV) from vp9_mode_order that use
3211b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    // this frame as their primary ref
3212b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    static const int ref_frame_mask_fixedmv[] = {
3213b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        0x0, 0x121281, 0x24c404, 0x080102
3214b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    };
3215b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (!(cpi->ref_frame_flags & flag_list[ref_frame])) {
3216b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      // Skip modes for missing references
3217b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      mode_skip_mask |= ref_frame_mask_all[ref_frame];
3218b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    } else if (cpi->sf.reference_masking) {
3219b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
3220b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        // Skip fixed mv modes for poor references
3221b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        if ((x->pred_mv_sad[ref_frame] >> 2) > x->pred_mv_sad[i]) {
3222b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          mode_skip_mask |= ref_frame_mask_fixedmv[ref_frame];
3223b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          break;
3224ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
3225b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      }
3226b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    }
3227b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    // If the segment reference frame feature is enabled....
3228b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    // then do nothing if the current ref frame is not allowed..
3229b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (vp9_segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
3230b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        vp9_get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
3231b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      mode_skip_mask |= ref_frame_mask_all[ref_frame];
3232ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
3233ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
3234ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3235b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  // If the segment skip feature is enabled....
3236b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  // then do nothing if the current mode is not allowed..
3237b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (vp9_segfeature_active(seg, segment_id, SEG_LVL_SKIP)) {
3238b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    const int inter_non_zero_mode_mask = 0x1F7F7;
3239b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    mode_skip_mask |= inter_non_zero_mode_mask;
3240b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  }
3241b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
3242b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  // Disable this drop out case if the ref frame
3243b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  // segment level feature is enabled for this segment. This is to
3244b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  // prevent the possibility that we end up unable to pick any mode.
3245b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (!vp9_segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
3246b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
3247b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    // unless ARNR filtering is enabled in which case we want
3248b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    // an unfiltered alternative. We allow near/nearest as well
3249b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    // because they may result in zero-zero MVs but be cheaper.
3250b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) {
3251b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      const int altref_zero_mask =
3252b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          ~((1 << THR_NEARESTA) | (1 << THR_NEARA) | (1 << THR_ZEROA));
3253b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      mode_skip_mask |= altref_zero_mask;
3254b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (frame_mv[NEARMV][ALTREF_FRAME].as_int != 0)
3255b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        mode_skip_mask |= (1 << THR_NEARA);
3256b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (frame_mv[NEARESTMV][ALTREF_FRAME].as_int != 0)
3257b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        mode_skip_mask |= (1 << THR_NEARESTA);
3258ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
3259b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  }
3260b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
3261b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  // TODO(JBB): This is to make up for the fact that we don't have sad
3262b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  // functions that work when the block size reads outside the umv.  We
3263b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  // should fix this either by making the motion search just work on
3264b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  // a representative block in the boundary ( first ) and then implement a
3265b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  // function that does sads when inside the border..
3266b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if ((mi_row + bhs) > cm->mi_rows || (mi_col + bws) > cm->mi_cols) {
3267b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    const int new_modes_mask =
3268b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        (1 << THR_NEWMV) | (1 << THR_NEWG) | (1 << THR_NEWA) |
3269b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        (1 << THR_COMP_NEWLA) | (1 << THR_COMP_NEWGA);
3270b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    mode_skip_mask |= new_modes_mask;
3271b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  }
3272b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
3273b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (bsize > cpi->sf.max_intra_bsize) {
3274b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    mode_skip_mask |= 0xFF30808;
3275ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
3276ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3277a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian  if (!x->in_active_map) {
3278a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian    int mode_index;
3279a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian    assert(cpi->ref_frame_flags & VP9_LAST_FLAG);
3280a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian    if (frame_mv[NEARESTMV][LAST_FRAME].as_int == 0)
3281a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian      mode_index = THR_NEARESTMV;
3282a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian    else if (frame_mv[NEARMV][LAST_FRAME].as_int == 0)
3283a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian      mode_index = THR_NEARMV;
3284a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian    else
3285a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian      mode_index = THR_ZEROMV;
3286a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian    mode_skip_mask = ~(1 << mode_index);
3287a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian    mode_skip_start = MAX_MODES;
3288a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian    disable_inter_mode_mask = 0;
3289a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian  }
3290a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian
3291ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (mode_index = 0; mode_index < MAX_MODES; ++mode_index) {
3292ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int mode_excluded = 0;
3293ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int64_t this_rd = INT64_MAX;
3294ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int disable_skip = 0;
3295ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int compmode_cost = 0;
3296ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int rate2 = 0, rate_y = 0, rate_uv = 0;
329791037db265ecdd914a26e056cf69207b4f50924ehkuang    int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
32981184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    int skippable = 0;
3299f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    int64_t tx_cache[TX_MODES];
3300ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int i;
330191037db265ecdd914a26e056cf69207b4f50924ehkuang    int this_skip2 = 0;
3302b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    int64_t total_sse = INT64_MAX;
330391037db265ecdd914a26e056cf69207b4f50924ehkuang    int early_term = 0;
3304ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
33051184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    // Look at the reference frame of the best mode so far and set the
33061184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    // skip mask to look at a subset of the remaining modes.
3307b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (mode_index == mode_skip_start) {
3308b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      switch (vp9_mode_order[best_mode_index].ref_frame[0]) {
3309b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        case INTRA_FRAME:
3310b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          break;
3311b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        case LAST_FRAME:
3312b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          mode_skip_mask |= LAST_FRAME_MODE_MASK;
3313b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          break;
3314b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        case GOLDEN_FRAME:
3315b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          mode_skip_mask |= GOLDEN_FRAME_MODE_MASK;
3316b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          break;
3317b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        case ALTREF_FRAME:
3318b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          mode_skip_mask |= ALT_REF_MODE_MASK;
3319b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          break;
3320b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        case NONE:
3321b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        case MAX_REF_FRAMES:
3322b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          assert(0 && "Invalid Reference frame");
33231184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      }
33241184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    }
3325b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (mode_skip_mask & (1 << mode_index))
332691037db265ecdd914a26e056cf69207b4f50924ehkuang      continue;
332791037db265ecdd914a26e056cf69207b4f50924ehkuang
3328ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Test best rd so far against threshold for trying this mode.
3329b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (best_rd < ((int64_t)rd_threshes[mode_index] *
3330b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                  rd_thresh_freq_fact[mode_index] >> 5) ||
3331b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        rd_threshes[mode_index] == INT_MAX)
3332b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian     continue;
3333ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3334b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    this_mode = vp9_mode_order[mode_index].mode;
3335b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    ref_frame = vp9_mode_order[mode_index].ref_frame[0];
3336b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (ref_frame != INTRA_FRAME &&
3337b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        disable_inter_mode_mask & (1 << INTER_OFFSET(this_mode)))
333891037db265ecdd914a26e056cf69207b4f50924ehkuang      continue;
3339b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    second_ref_frame = vp9_mode_order[mode_index].ref_frame[1];
334091037db265ecdd914a26e056cf69207b4f50924ehkuang
3341b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    comp_pred = second_ref_frame > INTRA_FRAME;
3342b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (comp_pred) {
3343b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if ((mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
3344b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          vp9_mode_order[best_mode_index].ref_frame[0] == INTRA_FRAME)
3345ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        continue;
3346b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if ((mode_search_skip_flags & FLAG_SKIP_COMP_REFMISMATCH) &&
3347b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          ref_frame != best_inter_ref_frame &&
3348b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          second_ref_frame != best_inter_ref_frame)
3349ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        continue;
3350b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
3351b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    } else {
3352b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (ref_frame != INTRA_FRAME)
3353b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
3354ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
3355ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3356b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (ref_frame == INTRA_FRAME) {
3357b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (!(intra_y_mode_mask & (1 << this_mode)))
3358b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        continue;
3359b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (this_mode != DC_PRED) {
3360b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        // Disable intra modes other than DC_PRED for blocks with low variance
3361b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        // Threshold for intra skipping based on source variance
3362b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        // TODO(debargha): Specialize the threshold for super block sizes
3363b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        const unsigned int skip_intra_var_thresh = 64;
3364b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        if ((mode_search_skip_flags & FLAG_SKIP_INTRA_LOWVAR) &&
3365b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            x->source_variance < skip_intra_var_thresh)
336691037db265ecdd914a26e056cf69207b4f50924ehkuang          continue;
3367b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        // Only search the oblique modes if the best so far is
3368b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        // one of the neighboring directional modes
3369b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        if ((mode_search_skip_flags & FLAG_SKIP_INTRA_BESTINTER) &&
3370b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            (this_mode >= D45_PRED && this_mode <= TM_PRED)) {
3371b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          if (vp9_mode_order[best_mode_index].ref_frame[0] > INTRA_FRAME)
3372b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            continue;
3373b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        }
3374b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        if (mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
3375b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          if (conditional_skipintra(this_mode, best_intra_mode))
3376b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian              continue;
3377b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        }
3378b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      }
3379b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    } else {
3380a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian      if (x->in_active_map &&
33816ac915abcdb404a00d927fe6308a47fcf09d9519hkuang          !vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP))
33826ac915abcdb404a00d927fe6308a47fcf09d9519hkuang        if (!check_best_zero_mv(cpi, mbmi->mode_context, frame_mv,
33836ac915abcdb404a00d927fe6308a47fcf09d9519hkuang                                disable_inter_mode_mask, this_mode, ref_frame,
33846ac915abcdb404a00d927fe6308a47fcf09d9519hkuang                                second_ref_frame))
33856ac915abcdb404a00d927fe6308a47fcf09d9519hkuang          continue;
338691037db265ecdd914a26e056cf69207b4f50924ehkuang    }
3387ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3388b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    mbmi->mode = this_mode;
3389a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian    mbmi->uv_mode = x->in_active_map ? DC_PRED : this_mode;
3390b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    mbmi->ref_frame[0] = ref_frame;
3391b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    mbmi->ref_frame[1] = second_ref_frame;
3392ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Evaluate all sub-pel filters irrespective of whether we can use
3393ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // them for this frame.
3394b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP
3395b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                                          : cm->interp_filter;
3396b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    x->skip = 0;
3397b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
3398ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3399f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    // Select prediction reference frames.
3400ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (i = 0; i < MAX_MB_PLANE; i++) {
3401ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
3402ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (comp_pred)
3403f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
3404ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
3405ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3406b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    for (i = 0; i < TX_MODES; ++i)
3407b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      tx_cache[i] = INT64_MAX;
3408ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
34091184aebb761cbeac9124c37189a80a1a58f04b6bhkuang#ifdef MODE_TEST_HIT_STATS
34101184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    // TEST/DEBUG CODE
34111184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    // Keep a rcord of the number of test hits at each size
34121184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    cpi->mode_test_hits[bsize]++;
34131184aebb761cbeac9124c37189a80a1a58f04b6bhkuang#endif
34141184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
34155ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (ref_frame == INTRA_FRAME) {
3416ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      TX_SIZE uv_tx;
3417b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      intra_super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable, NULL,
3418b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                            bsize, tx_cache, best_rd);
341991037db265ecdd914a26e056cf69207b4f50924ehkuang
342091037db265ecdd914a26e056cf69207b4f50924ehkuang      if (rate_y == INT_MAX)
342191037db265ecdd914a26e056cf69207b4f50924ehkuang        continue;
342291037db265ecdd914a26e056cf69207b4f50924ehkuang
3423b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      uv_tx = get_uv_tx_size_impl(mbmi->tx_size, bsize);
342491037db265ecdd914a26e056cf69207b4f50924ehkuang      if (rate_uv_intra[uv_tx] == INT_MAX) {
3425b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        choose_intra_uv_mode(cpi, ctx, bsize, uv_tx,
3426b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                             &rate_uv_intra[uv_tx], &rate_uv_tokenonly[uv_tx],
3427b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                             &dist_uv[uv_tx], &skip_uv[uv_tx], &mode_uv[uv_tx]);
342891037db265ecdd914a26e056cf69207b4f50924ehkuang      }
342991037db265ecdd914a26e056cf69207b4f50924ehkuang
343091037db265ecdd914a26e056cf69207b4f50924ehkuang      rate_uv = rate_uv_tokenonly[uv_tx];
3431ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      distortion_uv = dist_uv[uv_tx];
3432ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      skippable = skippable && skip_uv[uv_tx];
3433ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      mbmi->uv_mode = mode_uv[uv_tx];
3434ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
343591037db265ecdd914a26e056cf69207b4f50924ehkuang      rate2 = rate_y + x->mbmode_cost[mbmi->mode] + rate_uv_intra[uv_tx];
34365ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (this_mode != DC_PRED && this_mode != TM_PRED)
3437ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        rate2 += intra_cost_penalty;
3438ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      distortion2 = distortion_y + distortion_uv;
34395ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    } else {
34405ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      this_rd = handle_inter_mode(cpi, x, tile, bsize,
34415ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                  tx_cache,
34425ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                  &rate2, &distortion2, &skippable,
34435ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                  &rate_y, &distortion_y,
34445ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                  &rate_uv, &distortion_uv,
34455ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                  &mode_excluded, &disable_skip,
34465ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                  &tmp_best_filter, frame_mv,
34475ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                  mi_row, mi_col,
34485ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                  single_newmv, &total_sse, best_rd);
34495ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (this_rd == INT64_MAX)
34505ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        continue;
34511184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
3452b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      compmode_cost = vp9_cost_bit(comp_mode_p, comp_pred);
3453b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
3454b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (cm->reference_mode == REFERENCE_MODE_SELECT)
3455b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        rate2 += compmode_cost;
34565ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
34571184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
34585ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // Estimate the reference frame signaling cost and add it
34595ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // to the rolling cost variable.
3460b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (comp_pred) {
34615ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      rate2 += ref_costs_comp[ref_frame];
34625ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    } else {
34635ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      rate2 += ref_costs_single[ref_frame];
34645ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
34655ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
34665ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (!disable_skip) {
34675ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      // Test for the condition where skip block will be activated
34685ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      // because there are no non zero coefficients and make any
34695ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      // necessary adjustment for rate. Ignore if skip is coded at
34705ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      // segment level as the cost wont have been added in.
34715ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      // Is Mb level skip allowed (i.e. not coded at segment level).
34725ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      const int mb_skip_allowed = !vp9_segfeature_active(seg, segment_id,
34735ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                                         SEG_LVL_SKIP);
34745ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
34755ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (skippable) {
34765ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        // Back out the coefficient coding costs
34775ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        rate2 -= (rate_y + rate_uv);
34785ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        // for best yrd calculation
34795ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        rate_uv = 0;
34805ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
34815ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if (mb_skip_allowed) {
34825ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          int prob_skip_cost;
34835ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
34845ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          // Cost the skip mb case
3485b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          vp9_prob skip_prob = vp9_get_skip_prob(cm, xd);
34865ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          if (skip_prob) {
34875ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            prob_skip_cost = vp9_cost_bit(skip_prob, 1);
34885ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            rate2 += prob_skip_cost;
34895ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          }
34905ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        }
34915ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      } else if (mb_skip_allowed && ref_frame != INTRA_FRAME && !xd->lossless) {
34925ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
34935ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
34945ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          // Add in the cost of the no skip flag.
3495b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          rate2 += vp9_cost_bit(vp9_get_skip_prob(cm, xd), 0);
34965ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        } else {
34975ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          // FIXME(rbultje) make this work for splitmv also
3498b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          rate2 += vp9_cost_bit(vp9_get_skip_prob(cm, xd), 1);
34995ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          distortion2 = total_sse;
35005ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          assert(total_sse >= 0);
35015ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          rate2 -= (rate_y + rate_uv);
35025ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          rate_y = 0;
35035ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          rate_uv = 0;
35045ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          this_skip2 = 1;
35055ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        }
35065ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      } else if (mb_skip_allowed) {
35075ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        // Add in the cost of the no skip flag.
3508b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        rate2 += vp9_cost_bit(vp9_get_skip_prob(cm, xd), 0);
35095ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      }
35105ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
35115ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      // Calculate the final RD estimate for this mode.
35125ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
35135ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
35145ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
3515b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (ref_frame == INTRA_FRAME) {
35165ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // Keep record of best intra rd
3517b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (this_rd < best_intra_rd) {
3518b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        best_intra_rd = this_rd;
3519b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        best_intra_mode = mbmi->mode;
3520b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      }
3521b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    } else {
3522b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      // Keep record of best inter rd with single reference
3523b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (!comp_pred && !mode_excluded && this_rd < best_inter_rd) {
3524b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        best_inter_rd = this_rd;
3525b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        best_inter_ref_frame = ref_frame;
3526b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      }
35275ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
35285ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
35295ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (!disable_skip && ref_frame == INTRA_FRAME) {
3530b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      for (i = 0; i < REFERENCE_MODES; ++i)
35315ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        best_pred_rd[i] = MIN(best_pred_rd[i], this_rd);
35325ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
35335ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        best_filter_rd[i] = MIN(best_filter_rd[i], this_rd);
35345ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
35355ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
35365ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // Store the respective mode distortions for later use.
35375ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (mode_distortions[this_mode] == -1
35385ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        || distortion2 < mode_distortions[this_mode]) {
35395ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      mode_distortions[this_mode] = distortion2;
35405ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
35415ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
35425ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // Did this mode help.. i.e. is it the new best mode
35435ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (this_rd < best_rd || x->skip) {
35449b35249446b07f40ac5fcc3205f2c048616efacchkuang      int max_plane = MAX_MB_PLANE;
35455ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (!mode_excluded) {
35465ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        // Note index of best mode so far
35475ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        best_mode_index = mode_index;
35485ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
35495ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if (ref_frame == INTRA_FRAME) {
35505ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          /* required for left and above block mv */
35515ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          mbmi->mv[0].as_int = 0;
35529b35249446b07f40ac5fcc3205f2c048616efacchkuang          max_plane = 1;
35535ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        }
35545ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
35555ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        *returnrate = rate2;
35565ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        *returndistortion = distortion2;
35575ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        best_rd = this_rd;
35585ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        best_mbmode = *mbmi;
35595ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        best_skip2 = this_skip2;
35609b35249446b07f40ac5fcc3205f2c048616efacchkuang        if (!x->select_txfm_size)
35619b35249446b07f40ac5fcc3205f2c048616efacchkuang          swap_block_ptr(x, ctx, max_plane);
35625ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        vpx_memcpy(ctx->zcoeff_blk, x->zcoeff_blk[mbmi->tx_size],
35635ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                   sizeof(uint8_t) * ctx->num_4x4_blk);
35645ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
35655ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        // TODO(debargha): enhance this test with a better distortion prediction
35665ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        // based on qp, activity mask and history
3567b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        if ((mode_search_skip_flags & FLAG_EARLY_TERMINATE) &&
35685ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            (mode_index > MIN_EARLY_TERM_INDEX)) {
35695ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          const int qstep = xd->plane[0].dequant[1];
35705ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          // TODO(debargha): Enhance this by specializing for each mode_index
35715ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          int scale = 4;
35725ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          if (x->source_variance < UINT_MAX) {
35735ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            const int var_adjust = (x->source_variance < 16);
35745ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            scale -= var_adjust;
35755ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          }
35765ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          if (ref_frame > INTRA_FRAME &&
35775ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang              distortion2 * scale < qstep * qstep) {
35785ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            early_term = 1;
35795ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          }
35805ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        }
35815ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      }
35825ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
35835ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
35845ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    /* keep record of best compound/single-only prediction */
35855ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (!disable_skip && ref_frame != INTRA_FRAME) {
3586b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
35875ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
3588b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (cm->reference_mode == REFERENCE_MODE_SELECT) {
35895ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        single_rate = rate2 - compmode_cost;
35905ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        hybrid_rate = rate2;
35915ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      } else {
35925ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        single_rate = rate2;
35935ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        hybrid_rate = rate2 + compmode_cost;
35945ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      }
35955ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
35965ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
35975ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
35985ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
3599b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (!comp_pred) {
3600b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        if (single_rd < best_pred_rd[SINGLE_REFERENCE]) {
3601b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          best_pred_rd[SINGLE_REFERENCE] = single_rd;
3602b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        }
3603b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      } else {
3604b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        if (single_rd < best_pred_rd[COMPOUND_REFERENCE]) {
3605b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          best_pred_rd[COMPOUND_REFERENCE] = single_rd;
3606b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        }
36075ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      }
3608b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
3609b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
3610b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
3611b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      /* keep record of best filter type */
3612b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (!mode_excluded && cm->interp_filter != BILINEAR) {
3613b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        int64_t ref = cpi->rd_filter_cache[cm->interp_filter == SWITCHABLE ?
3614b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                              SWITCHABLE_FILTERS : cm->interp_filter];
3615b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
3616b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) {
3617b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          int64_t adj_rd;
3618b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          if (ref == INT64_MAX)
3619b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            adj_rd = 0;
3620b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          else if (cpi->rd_filter_cache[i] == INT64_MAX)
3621b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            // when early termination is triggered, the encoder does not have
3622b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            // access to the rate-distortion cost. it only knows that the cost
3623b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            // should be above the maximum valid value. hence it takes the known
3624b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            // maximum plus an arbitrary constant as the rate-distortion cost.
3625b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            adj_rd = cpi->mask_filter_rd - ref + 10;
3626b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          else
3627b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            adj_rd = cpi->rd_filter_cache[i] - ref;
36285ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
3629b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          adj_rd += this_rd;
3630b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          best_filter_rd[i] = MIN(best_filter_rd[i], adj_rd);
36315ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        }
36325ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      }
36335ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
36345ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
36355ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    /* keep record of best txfm size */
36365ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (bsize < BLOCK_32X32) {
36375ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (bsize < BLOCK_16X16)
36385ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        tx_cache[ALLOW_16X16] = tx_cache[ALLOW_8X8];
36395ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
36405ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      tx_cache[ALLOW_32X32] = tx_cache[ALLOW_16X16];
36415ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
36425ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (!mode_excluded && this_rd != INT64_MAX) {
36435ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      for (i = 0; i < TX_MODES && tx_cache[i] < INT64_MAX; i++) {
36445ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        int64_t adj_rd = INT64_MAX;
36455ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        adj_rd = this_rd + tx_cache[i] - tx_cache[cm->tx_mode];
36465ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
36475ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if (adj_rd < best_tx_rd[i])
36485ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          best_tx_rd[i] = adj_rd;
36495ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      }
36505ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
36515ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
36525ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (early_term)
36535ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      break;
36545ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
36555ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (x->skip && !comp_pred)
36565ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      break;
36575ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
36585ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
36595ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (best_rd >= best_rd_so_far)
36605ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    return INT64_MAX;
36615ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
36625ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // If we used an estimate for the uv intra rd in the loop above...
36635ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (cpi->sf.use_uv_intra_rd_estimate) {
36645ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // Do Intra UV best rd mode selection if best mode choice above was intra.
3665b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (vp9_mode_order[best_mode_index].ref_frame[0] == INTRA_FRAME) {
3666b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      TX_SIZE uv_tx_size;
3667b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      *mbmi = best_mbmode;
3668b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      uv_tx_size = get_uv_tx_size(mbmi);
36699b35249446b07f40ac5fcc3205f2c048616efacchkuang      rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv_intra[uv_tx_size],
36705ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                              &rate_uv_tokenonly[uv_tx_size],
36715ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                              &dist_uv[uv_tx_size],
36725ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                              &skip_uv[uv_tx_size],
3673b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                              bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize,
3674b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                              uv_tx_size);
36755ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
36765ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
36775ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
3678b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  assert((cm->interp_filter == SWITCHABLE) ||
3679b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian         (cm->interp_filter == best_mbmode.interp_filter) ||
3680b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian         !is_inter_block(&best_mbmode));
36815ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
36825ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // Updating rd_thresh_freq_fact[] here means that the different
36835ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // partition/block sizes are handled independently based on the best
36845ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // choice for the current partition. It may well be better to keep a scaled
36855ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // best rd so far value and update rd_thresh_freq_fact based on the mode/size
36865ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // combination that wins out.
36875ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (cpi->sf.adaptive_rd_thresh) {
36885ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    for (mode_index = 0; mode_index < MAX_MODES; ++mode_index) {
3689b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      int *const fact = &cpi->rd_thresh_freq_fact[bsize][mode_index];
3690b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
36915ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (mode_index == best_mode_index) {
3692b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        *fact -= (*fact >> 3);
36935ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      } else {
3694b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        *fact = MIN(*fact + RD_THRESH_INC,
3695b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                    cpi->sf.adaptive_rd_thresh * RD_THRESH_MAX_FACT);
36965ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      }
36975ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
36985ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
36995ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
37005ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // macroblock modes
37015ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  *mbmi = best_mbmode;
37025ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  x->skip |= best_skip2;
37035ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
3704b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  for (i = 0; i < REFERENCE_MODES; ++i) {
37055ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (best_pred_rd[i] == INT64_MAX)
37065ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      best_pred_diff[i] = INT_MIN;
37075ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    else
37085ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      best_pred_diff[i] = best_rd - best_pred_rd[i];
37095ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
37105ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
37115ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (!x->skip) {
37125ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) {
37135ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (best_filter_rd[i] == INT64_MAX)
37145ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        best_filter_diff[i] = 0;
37155ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      else
37165ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        best_filter_diff[i] = best_rd - best_filter_rd[i];
37175ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
3718b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (cm->interp_filter == SWITCHABLE)
37195ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      assert(best_filter_diff[SWITCHABLE_FILTERS] == 0);
37205ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    for (i = 0; i < TX_MODES; i++) {
37215ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (best_tx_rd[i] == INT64_MAX)
37225ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        best_tx_diff[i] = 0;
37235ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      else
37245ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        best_tx_diff[i] = best_rd - best_tx_rd[i];
37255ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
37265ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  } else {
3727b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    vp9_zero(best_filter_diff);
37285ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    vp9_zero(best_tx_diff);
37295ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
37305ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
3731a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian  if (!x->in_active_map) {
3732a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian    assert(mbmi->ref_frame[0] == LAST_FRAME);
3733a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian    assert(mbmi->ref_frame[1] == NONE);
3734a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian    assert(mbmi->mode == NEARESTMV ||
3735a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian           mbmi->mode == NEARMV ||
3736a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian           mbmi->mode == ZEROMV);
3737a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian    assert(frame_mv[mbmi->mode][LAST_FRAME].as_int == 0);
3738a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian    assert(mbmi->mode == mbmi->uv_mode);
3739a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian  }
3740a72801d7d92ababb50eecf27a36bd222d031d2feVignesh Venkatasubramanian
3741b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
37425ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  store_coding_context(x, ctx, best_mode_index,
37435ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                       &mbmi->ref_mvs[mbmi->ref_frame[0]][0],
37445ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                       &mbmi->ref_mvs[mbmi->ref_frame[1] < 0 ? 0 :
37455ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                      mbmi->ref_frame[1]][0],
37465ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                       best_pred_diff, best_tx_diff, best_filter_diff);
37475ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
37485ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  return best_rd;
37495ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang}
37505ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
37515ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
37525ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangint64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x,
37535ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                      const TileInfo *const tile,
37545ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                      int mi_row, int mi_col,
37555ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                      int *returnrate,
37565ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                      int64_t *returndistortion,
37575ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                      BLOCK_SIZE bsize,
37585ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                      PICK_MODE_CONTEXT *ctx,
37595ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                      int64_t best_rd_so_far) {
37605ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  VP9_COMMON *cm = &cpi->common;
37615ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MACROBLOCKD *xd = &x->e_mbd;
37626ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
37635ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const struct segmentation *seg = &cm->seg;
37645ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MV_REFERENCE_FRAME ref_frame, second_ref_frame;
37655ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  unsigned char segment_id = mbmi->segment_id;
37665ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int comp_pred, i;
37675ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
37685ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  struct buf_2d yv12_mb[4][MAX_MB_PLANE];
37695ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  static const int flag_list[4] = { 0, VP9_LAST_FLAG, VP9_GOLD_FLAG,
37705ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                    VP9_ALT_FLAG };
37715ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int64_t best_rd = best_rd_so_far;
37725ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int64_t best_yrd = best_rd_so_far;  // FIXME(rbultje) more precise
37735ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int64_t best_tx_rd[TX_MODES];
37745ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int64_t best_tx_diff[TX_MODES];
3775b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int64_t best_pred_diff[REFERENCE_MODES];
3776b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int64_t best_pred_rd[REFERENCE_MODES];
37775ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int64_t best_filter_rd[SWITCHABLE_FILTER_CONTEXTS];
37785ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS];
37795ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MB_MODE_INFO best_mbmode = { 0 };
37805ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int mode_index, best_mode_index = 0;
37815ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  unsigned int ref_costs_single[MAX_REF_FRAMES], ref_costs_comp[MAX_REF_FRAMES];
37825ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  vp9_prob comp_mode_p;
37835ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int64_t best_inter_rd = INT64_MAX;
37845ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MV_REFERENCE_FRAME best_inter_ref_frame = LAST_FRAME;
3785b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  INTERP_FILTER tmp_best_filter = SWITCHABLE;
37865ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int rate_uv_intra[TX_SIZES], rate_uv_tokenonly[TX_SIZES];
37875ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int64_t dist_uv[TX_SIZES];
37885ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int skip_uv[TX_SIZES];
37895ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MB_PREDICTION_MODE mode_uv[TX_SIZES] = { 0 };
3790b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int intra_cost_penalty = 20 * vp9_dc_quant(cm->base_qindex, cm->y_dc_delta_q);
37915ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int_mv seg_mvs[4][MAX_REF_FRAMES];
37925ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  b_mode_info best_bmodes[4];
37935ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int best_skip2 = 0;
3794b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int ref_frame_mask = 0;
3795b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  int mode_skip_mask = 0;
37965ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
37979b35249446b07f40ac5fcc3205f2c048616efacchkuang  x->skip_encode = cpi->sf.skip_encode_frame && x->q_index < QIDX_SKIP_THRESH;
37985ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  vpx_memset(x->zcoeff_blk[TX_4X4], 0, 4);
37995ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
38005ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  for (i = 0; i < 4; i++) {
38015ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    int j;
38025ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    for (j = 0; j < MAX_REF_FRAMES; j++)
38035ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      seg_mvs[i][j].as_int = INVALID_MV;
38045ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
38055ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
38065ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  estimate_ref_frame_costs(cpi, segment_id, ref_costs_single, ref_costs_comp,
38075ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                           &comp_mode_p);
38085ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
3809b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  for (i = 0; i < REFERENCE_MODES; ++i)
38105ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    best_pred_rd[i] = INT64_MAX;
38115ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  for (i = 0; i < TX_MODES; i++)
38125ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    best_tx_rd[i] = INT64_MAX;
38135ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
38145ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    best_filter_rd[i] = INT64_MAX;
38155ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  for (i = 0; i < TX_SIZES; i++)
38165ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    rate_uv_intra[i] = INT_MAX;
38175ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
38185ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  *returnrate = INT_MAX;
38195ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
38205ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
38215ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (cpi->ref_frame_flags & flag_list[ref_frame]) {
3822b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      vp9_setup_buffer_inter(cpi, x, tile,
38236ac915abcdb404a00d927fe6308a47fcf09d9519hkuang                             ref_frame, bsize, mi_row, mi_col,
3824b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                             frame_mv[NEARESTMV], frame_mv[NEARMV],
3825b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                             yv12_mb);
38265ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
38275ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
38285ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    frame_mv[ZEROMV][ref_frame].as_int = 0;
38295ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
38305ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
3831b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  for (ref_frame = LAST_FRAME;
3832b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian       ref_frame <= ALTREF_FRAME && cpi->sf.reference_masking; ++ref_frame) {
3833b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    int i;
3834b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
3835b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if ((x->pred_mv_sad[ref_frame] >> 1) > x->pred_mv_sad[i]) {
3836b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        ref_frame_mask |= (1 << ref_frame);
3837b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        break;
3838b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      }
3839b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    }
3840b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  }
3841b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
38425ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  for (mode_index = 0; mode_index < MAX_REFS; ++mode_index) {
38435ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    int mode_excluded = 0;
38445ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    int64_t this_rd = INT64_MAX;
38455ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    int disable_skip = 0;
38465ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    int compmode_cost = 0;
38475ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    int rate2 = 0, rate_y = 0, rate_uv = 0;
38485ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
38495ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    int skippable = 0;
38505ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    int64_t tx_cache[TX_MODES];
38515ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    int i;
38525ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    int this_skip2 = 0;
38535ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    int64_t total_sse = INT_MAX;
38545ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    int early_term = 0;
38555ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
38565ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    for (i = 0; i < TX_MODES; ++i)
38575ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      tx_cache[i] = INT64_MAX;
38585ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
38595ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    x->skip = 0;
3860b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    ref_frame = vp9_ref_order[mode_index].ref_frame[0];
3861b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    second_ref_frame = vp9_ref_order[mode_index].ref_frame[1];
38625ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
38635ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // Look at the reference frame of the best mode so far and set the
38645ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // skip mask to look at a subset of the remaining modes.
38655ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (mode_index > 2 && cpi->sf.mode_skip_start < MAX_MODES) {
38665ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (mode_index == 3) {
3867b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        switch (vp9_ref_order[best_mode_index].ref_frame[0]) {
38685ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          case INTRA_FRAME:
3869b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            mode_skip_mask = 0;
38705ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            break;
38715ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          case LAST_FRAME:
3872b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            mode_skip_mask = 0x0010;
38735ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            break;
38745ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          case GOLDEN_FRAME:
3875b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            mode_skip_mask = 0x0008;
38765ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            break;
38775ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          case ALTREF_FRAME:
3878b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            mode_skip_mask = 0x0000;
38795ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            break;
38805ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          case NONE:
38815ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          case MAX_REF_FRAMES:
3882b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            assert(0 && "Invalid Reference frame");
38835ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        }
38845ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      }
3885b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (mode_skip_mask & (1 << mode_index))
38865ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        continue;
38875ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
38885ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
38895ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // Test best rd so far against threshold for trying this mode.
38905ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if ((best_rd <
38915ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang         ((int64_t)cpi->rd_thresh_sub8x8[segment_id][bsize][mode_index] *
38925ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          cpi->rd_thresh_freq_sub8x8[bsize][mode_index] >> 5)) ||
38935ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        cpi->rd_thresh_sub8x8[segment_id][bsize][mode_index] == INT_MAX)
38945ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      continue;
38955ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
38965ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // Do not allow compound prediction if the segment level reference
38975ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // frame feature is in use as in this case there can only be one reference.
38985ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if ((second_ref_frame > INTRA_FRAME) &&
38995ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang         vp9_segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME))
39005ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      continue;
39015ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
39025ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    mbmi->ref_frame[0] = ref_frame;
39035ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    mbmi->ref_frame[1] = second_ref_frame;
39045ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
39055ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (!(ref_frame == INTRA_FRAME
39065ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        || (cpi->ref_frame_flags & flag_list[ref_frame]))) {
39075ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      continue;
39085ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
39095ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (!(second_ref_frame == NONE
39105ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        || (cpi->ref_frame_flags & flag_list[second_ref_frame]))) {
39115ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      continue;
39125ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
39135ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
39145ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    comp_pred = second_ref_frame > INTRA_FRAME;
39155ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (comp_pred) {
39165ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA)
3917b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        if (vp9_ref_order[best_mode_index].ref_frame[0] == INTRA_FRAME)
39185ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          continue;
39195ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_COMP_REFMISMATCH)
39205ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if (ref_frame != best_inter_ref_frame &&
39215ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            second_ref_frame != best_inter_ref_frame)
39225ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          continue;
39235ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
39245ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
39255ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // TODO(jingning, jkoleszar): scaling reference frame not supported for
39265ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // sub8x8 blocks.
3927b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (ref_frame > 0 && vp9_is_scaled(&cm->frame_refs[ref_frame - 1].sf))
39285ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      continue;
39295ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
39305ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (second_ref_frame > 0 &&
3931b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        vp9_is_scaled(&cm->frame_refs[second_ref_frame - 1].sf))
39325ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      continue;
39335ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
3934b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
39355ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    mbmi->uv_mode = DC_PRED;
39365ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
39375ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // Evaluate all sub-pel filters irrespective of whether we can use
39385ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // them for this frame.
3939b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP
3940b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                                          : cm->interp_filter;
39415ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
39425ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (comp_pred) {
39435ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (!(cpi->ref_frame_flags & flag_list[second_ref_frame]))
39445ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        continue;
39455ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
3946b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      mode_excluded = mode_excluded ? mode_excluded
3947b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                    : cm->reference_mode == SINGLE_REFERENCE;
39485ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    } else {
39495ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (ref_frame != INTRA_FRAME && second_ref_frame != INTRA_FRAME) {
3950b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        mode_excluded = mode_excluded ?
3951b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            mode_excluded : cm->reference_mode == COMPOUND_REFERENCE;
39525ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      }
39535ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
39545ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
39555ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // Select prediction reference frames.
39565ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    for (i = 0; i < MAX_MB_PLANE; i++) {
39575ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
39585ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (comp_pred)
39595ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
39605ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
39615ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
39625ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // If the segment reference frame feature is enabled....
39635ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // then do nothing if the current ref frame is not allowed..
39645ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (vp9_segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
39655ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        vp9_get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) !=
39665ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            (int)ref_frame) {
39675ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      continue;
39685ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // If the segment skip feature is enabled....
39695ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // then do nothing if the current mode is not allowed..
39705ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    } else if (vp9_segfeature_active(seg, segment_id, SEG_LVL_SKIP) &&
39715ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang               ref_frame != INTRA_FRAME) {
39725ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      continue;
39735ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // Disable this drop out case if the ref frame
39745ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // segment level feature is enabled for this segment. This is to
39755ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // prevent the possibility that we end up unable to pick any mode.
39765ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    } else if (!vp9_segfeature_active(seg, segment_id,
39775ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                      SEG_LVL_REF_FRAME)) {
39785ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
39795ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      // unless ARNR filtering is enabled in which case we want
39805ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      // an unfiltered alternative. We allow near/nearest as well
39815ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      // because they may result in zero-zero MVs but be cheaper.
3982b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0))
39835ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        continue;
39845ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
39855ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
39865ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#ifdef MODE_TEST_HIT_STATS
39875ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // TEST/DEBUG CODE
39885ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // Keep a rcord of the number of test hits at each size
39895ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    cpi->mode_test_hits[bsize]++;
39905ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#endif
39915ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
39925ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (ref_frame == INTRA_FRAME) {
39935ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      int rate;
39945ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      mbmi->tx_size = TX_4X4;
39955ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate, &rate_y,
39965ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                       &distortion_y, best_rd) >= best_rd)
39975ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        continue;
39985ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      rate2 += rate;
39995ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      rate2 += intra_cost_penalty;
40005ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      distortion2 += distortion_y;
40015ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
40025ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (rate_uv_intra[TX_4X4] == INT_MAX) {
4003b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        choose_intra_uv_mode(cpi, ctx, bsize, TX_4X4,
4004b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                             &rate_uv_intra[TX_4X4],
40055ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                             &rate_uv_tokenonly[TX_4X4],
40065ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                             &dist_uv[TX_4X4], &skip_uv[TX_4X4],
40075ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                             &mode_uv[TX_4X4]);
40085ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      }
40095ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      rate2 += rate_uv_intra[TX_4X4];
40105ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      rate_uv = rate_uv_tokenonly[TX_4X4];
40115ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      distortion2 += dist_uv[TX_4X4];
40125ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      distortion_uv = dist_uv[TX_4X4];
40135ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      mbmi->uv_mode = mode_uv[TX_4X4];
40145ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      tx_cache[ONLY_4X4] = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
40155ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      for (i = 0; i < TX_MODES; ++i)
40165ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        tx_cache[i] = tx_cache[ONLY_4X4];
40175ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    } else {
40185ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      int rate;
40195ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      int64_t distortion;
40205ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      int64_t this_rd_thresh;
40215ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      int64_t tmp_rd, tmp_best_rd = INT64_MAX, tmp_best_rdu = INT64_MAX;
40225ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      int tmp_best_rate = INT_MAX, tmp_best_ratey = INT_MAX;
40235ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      int64_t tmp_best_distortion = INT_MAX, tmp_best_sse, uv_sse;
40245ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      int tmp_best_skippable = 0;
40255ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      int switchable_filter_index;
40265ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      int_mv *second_ref = comp_pred ?
40275ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                             &mbmi->ref_mvs[second_ref_frame][0] : NULL;
40285ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      b_mode_info tmp_best_bmodes[16];
40295ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      MB_MODE_INFO tmp_best_mbmode;
40305ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      BEST_SEG_INFO bsi[SWITCHABLE_FILTERS];
40315ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      int pred_exists = 0;
40325ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      int uv_skippable;
40335ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
40345ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      this_rd_thresh = (ref_frame == LAST_FRAME) ?
40355ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          cpi->rd_thresh_sub8x8[segment_id][bsize][THR_LAST] :
40365ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          cpi->rd_thresh_sub8x8[segment_id][bsize][THR_ALTR];
40375ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      this_rd_thresh = (ref_frame == GOLDEN_FRAME) ?
40385ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          cpi->rd_thresh_sub8x8[segment_id][bsize][THR_GOLD] : this_rd_thresh;
40396ac915abcdb404a00d927fe6308a47fcf09d9519hkuang      xd->mi[0]->mbmi.tx_size = TX_4X4;
40405ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
4041b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      cpi->mask_filter_rd = 0;
4042b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i)
4043b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        cpi->rd_filter_cache[i] = INT64_MAX;
4044b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
4045b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (cm->interp_filter != BILINEAR) {
40465ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        tmp_best_filter = EIGHTTAP;
40475ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if (x->source_variance <
40485ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            cpi->sf.disable_filter_search_var_thresh) {
40495ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          tmp_best_filter = EIGHTTAP;
4050b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        } else if (cpi->sf.adaptive_pred_interp_filter == 1 &&
4051b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                   ctx->pred_interp_filter < SWITCHABLE) {
4052b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          tmp_best_filter = ctx->pred_interp_filter;
4053b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        } else if (cpi->sf.adaptive_pred_interp_filter == 2) {
4054b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          tmp_best_filter = ctx->pred_interp_filter < SWITCHABLE ?
4055b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                              ctx->pred_interp_filter : 0;
40565ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        } else {
40575ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          for (switchable_filter_index = 0;
40585ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang               switchable_filter_index < SWITCHABLE_FILTERS;
40595ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang               ++switchable_filter_index) {
40605ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            int newbest, rs;
40615ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            int64_t rs_rd;
40625ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            mbmi->interp_filter = switchable_filter_index;
40635ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            tmp_rd = rd_pick_best_mbsegmentation(cpi, x, tile,
40641184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                                 &mbmi->ref_mvs[ref_frame][0],
40651184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                                 second_ref,
40661184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                                 best_yrd,
40671184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                                 &rate, &rate_y, &distortion,
40681184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                                 &skippable, &total_sse,
40691184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                                 (int)this_rd_thresh, seg_mvs,
40701184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                                 bsi, switchable_filter_index,
40711184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                                 mi_row, mi_col);
40721184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
40731184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            if (tmp_rd == INT64_MAX)
40741184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              continue;
40756ac915abcdb404a00d927fe6308a47fcf09d9519hkuang            rs = vp9_get_switchable_rate(x);
40761184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0);
4077b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            cpi->rd_filter_cache[switchable_filter_index] = tmp_rd;
40781184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            cpi->rd_filter_cache[SWITCHABLE_FILTERS] =
40791184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                MIN(cpi->rd_filter_cache[SWITCHABLE_FILTERS],
40801184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                    tmp_rd + rs_rd);
4081b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            if (cm->interp_filter == SWITCHABLE)
40821184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              tmp_rd += rs_rd;
40831184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
4084b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            cpi->mask_filter_rd = MAX(cpi->mask_filter_rd, tmp_rd);
4085b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
40861184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            newbest = (tmp_rd < tmp_best_rd);
40871184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            if (newbest) {
408891037db265ecdd914a26e056cf69207b4f50924ehkuang              tmp_best_filter = mbmi->interp_filter;
40891184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              tmp_best_rd = tmp_rd;
4090ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            }
4091b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian            if ((newbest && cm->interp_filter == SWITCHABLE) ||
4092b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                (mbmi->interp_filter == cm->interp_filter &&
4093b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                 cm->interp_filter != SWITCHABLE)) {
40941184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              tmp_best_rdu = tmp_rd;
40951184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              tmp_best_rate = rate;
40961184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              tmp_best_ratey = rate_y;
40971184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              tmp_best_distortion = distortion;
40981184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              tmp_best_sse = total_sse;
40991184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              tmp_best_skippable = skippable;
41001184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              tmp_best_mbmode = *mbmi;
41015ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang              for (i = 0; i < 4; i++) {
41026ac915abcdb404a00d927fe6308a47fcf09d9519hkuang                tmp_best_bmodes[i] = xd->mi[0]->bmi[i];
4103b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                x->zcoeff_blk[TX_4X4][i] = !x->plane[0].eobs[i];
41045ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang              }
41051184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              pred_exists = 1;
41061184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              if (switchable_filter_index == 0 &&
41071184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  cpi->sf.use_rd_breakout &&
41081184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  best_rd < INT64_MAX) {
41091184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                if (tmp_best_rdu / 2 > best_rd) {
41101184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  // skip searching the other filters if the first is
41111184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  // already substantially larger than the best so far
41121184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  tmp_best_filter = mbmi->interp_filter;
41131184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  tmp_best_rdu = INT64_MAX;
41141184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  break;
41151184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                }
41161184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              }
41171184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            }
41181184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          }  // switchable_filter_index loop
411991037db265ecdd914a26e056cf69207b4f50924ehkuang        }
41201184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      }
4121ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4122b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (tmp_best_rdu == INT64_MAX && pred_exists)
412391037db265ecdd914a26e056cf69207b4f50924ehkuang        continue;
412491037db265ecdd914a26e056cf69207b4f50924ehkuang
4125b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      mbmi->interp_filter = (cm->interp_filter == SWITCHABLE ?
4126b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                             tmp_best_filter : cm->interp_filter);
4127ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (!pred_exists) {
4128ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        // Handles the special case when a filter that is not in the
4129ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        // switchable list (bilinear, 6-tap) is indicated at the frame level
41305ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        tmp_rd = rd_pick_best_mbsegmentation(cpi, x, tile,
4131f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                     &mbmi->ref_mvs[ref_frame][0],
413291037db265ecdd914a26e056cf69207b4f50924ehkuang                     second_ref,
413391037db265ecdd914a26e056cf69207b4f50924ehkuang                     best_yrd,
4134ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                     &rate, &rate_y, &distortion,
413591037db265ecdd914a26e056cf69207b4f50924ehkuang                     &skippable, &total_sse,
4136ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                     (int)this_rd_thresh, seg_mvs,
413791037db265ecdd914a26e056cf69207b4f50924ehkuang                     bsi, 0,
4138ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                     mi_row, mi_col);
413991037db265ecdd914a26e056cf69207b4f50924ehkuang        if (tmp_rd == INT64_MAX)
414091037db265ecdd914a26e056cf69207b4f50924ehkuang          continue;
4141ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      } else {
414291037db265ecdd914a26e056cf69207b4f50924ehkuang        total_sse = tmp_best_sse;
4143ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        rate = tmp_best_rate;
4144ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        rate_y = tmp_best_ratey;
4145ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        distortion = tmp_best_distortion;
4146ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        skippable = tmp_best_skippable;
4147ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        *mbmi = tmp_best_mbmode;
4148ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        for (i = 0; i < 4; i++)
41496ac915abcdb404a00d927fe6308a47fcf09d9519hkuang          xd->mi[0]->bmi[i] = tmp_best_bmodes[i];
4150ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
4151ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4152ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      rate2 += rate;
4153ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      distortion2 += distortion;
4154ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4155b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (cm->interp_filter == SWITCHABLE)
41566ac915abcdb404a00d927fe6308a47fcf09d9519hkuang        rate2 += vp9_get_switchable_rate(x);
4157ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4158b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (!mode_excluded)
4159b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        mode_excluded = comp_pred ? cm->reference_mode == SINGLE_REFERENCE
4160b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                                  : cm->reference_mode == COMPOUND_REFERENCE;
4161b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
41625ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      compmode_cost = vp9_cost_bit(comp_mode_p, comp_pred);
416391037db265ecdd914a26e056cf69207b4f50924ehkuang
41641184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      tmp_best_rdu = best_rd -
41651184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          MIN(RDCOST(x->rdmult, x->rddiv, rate2, distortion2),
41661184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              RDCOST(x->rdmult, x->rddiv, 0, total_sse));
41671184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
41681184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      if (tmp_best_rdu > 0) {
416991037db265ecdd914a26e056cf69207b4f50924ehkuang        // If even the 'Y' rd value of split is higher than best so far
417091037db265ecdd914a26e056cf69207b4f50924ehkuang        // then dont bother looking at UV
417191037db265ecdd914a26e056cf69207b4f50924ehkuang        vp9_build_inter_predictors_sbuv(&x->e_mbd, mi_row, mi_col,
41721184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                        BLOCK_8X8);
41735ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        super_block_uvrd(cpi, x, &rate_uv, &distortion_uv, &uv_skippable,
41741184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                         &uv_sse, BLOCK_8X8, tmp_best_rdu);
41751184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        if (rate_uv == INT_MAX)
41761184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          continue;
417791037db265ecdd914a26e056cf69207b4f50924ehkuang        rate2 += rate_uv;
417891037db265ecdd914a26e056cf69207b4f50924ehkuang        distortion2 += distortion_uv;
417991037db265ecdd914a26e056cf69207b4f50924ehkuang        skippable = skippable && uv_skippable;
418091037db265ecdd914a26e056cf69207b4f50924ehkuang        total_sse += uv_sse;
418191037db265ecdd914a26e056cf69207b4f50924ehkuang
4182f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        tx_cache[ONLY_4X4] = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
4183f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        for (i = 0; i < TX_MODES; ++i)
4184f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          tx_cache[i] = tx_cache[ONLY_4X4];
418591037db265ecdd914a26e056cf69207b4f50924ehkuang      }
4186ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
4187ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4188b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (cm->reference_mode == REFERENCE_MODE_SELECT)
4189ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      rate2 += compmode_cost;
4190ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4191ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Estimate the reference frame signaling cost and add it
4192ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // to the rolling cost variable.
4193f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    if (second_ref_frame > INTRA_FRAME) {
4194f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      rate2 += ref_costs_comp[ref_frame];
4195ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    } else {
4196f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      rate2 += ref_costs_single[ref_frame];
4197ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
4198ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4199ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (!disable_skip) {
4200ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // Test for the condition where skip block will be activated
4201ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // because there are no non zero coefficients and make any
4202ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // necessary adjustment for rate. Ignore if skip is coded at
4203ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // segment level as the cost wont have been added in.
4204ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // Is Mb level skip allowed (i.e. not coded at segment level).
4205f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      const int mb_skip_allowed = !vp9_segfeature_active(seg, segment_id,
420691037db265ecdd914a26e056cf69207b4f50924ehkuang                                                         SEG_LVL_SKIP);
4207ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
42085ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (mb_skip_allowed && ref_frame != INTRA_FRAME && !xd->lossless) {
420991037db265ecdd914a26e056cf69207b4f50924ehkuang        if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
421091037db265ecdd914a26e056cf69207b4f50924ehkuang            RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
421191037db265ecdd914a26e056cf69207b4f50924ehkuang          // Add in the cost of the no skip flag.
4212b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          rate2 += vp9_cost_bit(vp9_get_skip_prob(cm, xd), 0);
421391037db265ecdd914a26e056cf69207b4f50924ehkuang        } else {
421491037db265ecdd914a26e056cf69207b4f50924ehkuang          // FIXME(rbultje) make this work for splitmv also
4215b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          rate2 += vp9_cost_bit(vp9_get_skip_prob(cm, xd), 1);
421691037db265ecdd914a26e056cf69207b4f50924ehkuang          distortion2 = total_sse;
421791037db265ecdd914a26e056cf69207b4f50924ehkuang          assert(total_sse >= 0);
421891037db265ecdd914a26e056cf69207b4f50924ehkuang          rate2 -= (rate_y + rate_uv);
421991037db265ecdd914a26e056cf69207b4f50924ehkuang          rate_y = 0;
422091037db265ecdd914a26e056cf69207b4f50924ehkuang          rate_uv = 0;
422191037db265ecdd914a26e056cf69207b4f50924ehkuang          this_skip2 = 1;
422291037db265ecdd914a26e056cf69207b4f50924ehkuang        }
4223ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      } else if (mb_skip_allowed) {
4224ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        // Add in the cost of the no skip flag.
4225b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        rate2 += vp9_cost_bit(vp9_get_skip_prob(cm, xd), 0);
4226ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
4227ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4228ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // Calculate the final RD estimate for this mode.
4229ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
4230ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
4231ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
423291037db265ecdd914a26e056cf69207b4f50924ehkuang    // Keep record of best inter rd with single reference
42336ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    if (is_inter_block(&xd->mi[0]->mbmi) &&
42346ac915abcdb404a00d927fe6308a47fcf09d9519hkuang        !has_second_ref(&xd->mi[0]->mbmi) &&
423591037db265ecdd914a26e056cf69207b4f50924ehkuang        !mode_excluded &&
423691037db265ecdd914a26e056cf69207b4f50924ehkuang        this_rd < best_inter_rd) {
423791037db265ecdd914a26e056cf69207b4f50924ehkuang      best_inter_rd = this_rd;
423891037db265ecdd914a26e056cf69207b4f50924ehkuang      best_inter_ref_frame = ref_frame;
4239ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
4240ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4241f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    if (!disable_skip && ref_frame == INTRA_FRAME) {
4242b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      for (i = 0; i < REFERENCE_MODES; ++i)
4243ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        best_pred_rd[i] = MIN(best_pred_rd[i], this_rd);
42445ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
424591037db265ecdd914a26e056cf69207b4f50924ehkuang        best_filter_rd[i] = MIN(best_filter_rd[i], this_rd);
4246ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
4247ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4248ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Did this mode help.. i.e. is it the new best mode
4249ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (this_rd < best_rd || x->skip) {
4250ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (!mode_excluded) {
42519b35249446b07f40ac5fcc3205f2c048616efacchkuang        int max_plane = MAX_MB_PLANE;
4252ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        // Note index of best mode so far
4253ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        best_mode_index = mode_index;
4254ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4255ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        if (ref_frame == INTRA_FRAME) {
4256ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          /* required for left and above block mv */
4257ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          mbmi->mv[0].as_int = 0;
42589b35249446b07f40ac5fcc3205f2c048616efacchkuang          max_plane = 1;
4259ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
4260ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4261ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        *returnrate = rate2;
4262ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        *returndistortion = distortion2;
4263ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        best_rd = this_rd;
426491037db265ecdd914a26e056cf69207b4f50924ehkuang        best_yrd = best_rd -
426591037db265ecdd914a26e056cf69207b4f50924ehkuang                   RDCOST(x->rdmult, x->rddiv, rate_uv, distortion_uv);
4266ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        best_mbmode = *mbmi;
426791037db265ecdd914a26e056cf69207b4f50924ehkuang        best_skip2 = this_skip2;
42689b35249446b07f40ac5fcc3205f2c048616efacchkuang        if (!x->select_txfm_size)
42699b35249446b07f40ac5fcc3205f2c048616efacchkuang          swap_block_ptr(x, ctx, max_plane);
42705ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        vpx_memcpy(ctx->zcoeff_blk, x->zcoeff_blk[mbmi->tx_size],
42715ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                   sizeof(uint8_t) * ctx->num_4x4_blk);
4272ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
42735ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        for (i = 0; i < 4; i++)
42746ac915abcdb404a00d927fe6308a47fcf09d9519hkuang          best_bmodes[i] = xd->mi[0]->bmi[i];
427591037db265ecdd914a26e056cf69207b4f50924ehkuang
427691037db265ecdd914a26e056cf69207b4f50924ehkuang        // TODO(debargha): enhance this test with a better distortion prediction
427791037db265ecdd914a26e056cf69207b4f50924ehkuang        // based on qp, activity mask and history
42785ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if ((cpi->sf.mode_search_skip_flags & FLAG_EARLY_TERMINATE) &&
42795ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            (mode_index > MIN_EARLY_TERM_INDEX)) {
4280f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          const int qstep = xd->plane[0].dequant[1];
4281f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          // TODO(debargha): Enhance this by specializing for each mode_index
4282f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          int scale = 4;
4283f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          if (x->source_variance < UINT_MAX) {
4284f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang            const int var_adjust = (x->source_variance < 16);
4285f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang            scale -= var_adjust;
4286f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          }
4287f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          if (ref_frame > INTRA_FRAME &&
4288f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang              distortion2 * scale < qstep * qstep) {
428991037db265ecdd914a26e056cf69207b4f50924ehkuang            early_term = 1;
4290f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          }
4291f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        }
4292ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
4293ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
4294ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4295ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    /* keep record of best compound/single-only prediction */
4296f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    if (!disable_skip && ref_frame != INTRA_FRAME) {
4297b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
4298ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4299b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (cm->reference_mode == REFERENCE_MODE_SELECT) {
4300ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        single_rate = rate2 - compmode_cost;
4301ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        hybrid_rate = rate2;
4302ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      } else {
4303ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        single_rate = rate2;
4304ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        hybrid_rate = rate2 + compmode_cost;
4305ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
4306ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4307ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
4308ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
4309ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4310f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      if (second_ref_frame <= INTRA_FRAME &&
4311b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          single_rd < best_pred_rd[SINGLE_REFERENCE]) {
4312b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        best_pred_rd[SINGLE_REFERENCE] = single_rd;
4313f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      } else if (second_ref_frame > INTRA_FRAME &&
4314b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                 single_rd < best_pred_rd[COMPOUND_REFERENCE]) {
4315b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        best_pred_rd[COMPOUND_REFERENCE] = single_rd;
4316ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
4317b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
4318b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
4319ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
4320ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
432191037db265ecdd914a26e056cf69207b4f50924ehkuang    /* keep record of best filter type */
4322f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    if (!mode_excluded && !disable_skip && ref_frame != INTRA_FRAME &&
4323b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        cm->interp_filter != BILINEAR) {
4324b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      int64_t ref = cpi->rd_filter_cache[cm->interp_filter == SWITCHABLE ?
4325b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                              SWITCHABLE_FILTERS : cm->interp_filter];
4326b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      int64_t adj_rd;
43275ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) {
4328b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        if (ref == INT64_MAX)
4329b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          adj_rd = 0;
4330b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        else if (cpi->rd_filter_cache[i] == INT64_MAX)
4331b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          // when early termination is triggered, the encoder does not have
4332b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          // access to the rate-distortion cost. it only knows that the cost
4333b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          // should be above the maximum valid value. hence it takes the known
4334b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          // maximum plus an arbitrary constant as the rate-distortion cost.
4335b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          adj_rd = cpi->mask_filter_rd - ref + 10;
4336b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        else
4337b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian          adj_rd = cpi->rd_filter_cache[i] - ref;
4338b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
4339b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        adj_rd += this_rd;
434091037db265ecdd914a26e056cf69207b4f50924ehkuang        best_filter_rd[i] = MIN(best_filter_rd[i], adj_rd);
434191037db265ecdd914a26e056cf69207b4f50924ehkuang      }
434291037db265ecdd914a26e056cf69207b4f50924ehkuang    }
434391037db265ecdd914a26e056cf69207b4f50924ehkuang
4344ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    /* keep record of best txfm size */
4345f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    if (bsize < BLOCK_32X32) {
4346f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      if (bsize < BLOCK_16X16) {
43475ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        tx_cache[ALLOW_8X8] = tx_cache[ONLY_4X4];
4348f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        tx_cache[ALLOW_16X16] = tx_cache[ALLOW_8X8];
4349ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
4350f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      tx_cache[ALLOW_32X32] = tx_cache[ALLOW_16X16];
4351ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
4352ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (!mode_excluded && this_rd != INT64_MAX) {
43531184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      for (i = 0; i < TX_MODES && tx_cache[i] < INT64_MAX; i++) {
4354ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        int64_t adj_rd = INT64_MAX;
43555ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if (ref_frame > INTRA_FRAME)
4356f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          adj_rd = this_rd + tx_cache[i] - tx_cache[cm->tx_mode];
43575ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        else
4358ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          adj_rd = this_rd;
4359ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4360f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        if (adj_rd < best_tx_rd[i])
4361f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          best_tx_rd[i] = adj_rd;
4362ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
4363ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
4364ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
436591037db265ecdd914a26e056cf69207b4f50924ehkuang    if (early_term)
436691037db265ecdd914a26e056cf69207b4f50924ehkuang      break;
436791037db265ecdd914a26e056cf69207b4f50924ehkuang
4368f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    if (x->skip && !comp_pred)
4369ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      break;
4370ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
4371f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
437291037db265ecdd914a26e056cf69207b4f50924ehkuang  if (best_rd >= best_rd_so_far)
437391037db265ecdd914a26e056cf69207b4f50924ehkuang    return INT64_MAX;
437491037db265ecdd914a26e056cf69207b4f50924ehkuang
437591037db265ecdd914a26e056cf69207b4f50924ehkuang  // If we used an estimate for the uv intra rd in the loop above...
437691037db265ecdd914a26e056cf69207b4f50924ehkuang  if (cpi->sf.use_uv_intra_rd_estimate) {
437791037db265ecdd914a26e056cf69207b4f50924ehkuang    // Do Intra UV best rd mode selection if best mode choice above was intra.
4378b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (vp9_ref_order[best_mode_index].ref_frame[0] == INTRA_FRAME) {
4379b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      TX_SIZE uv_tx_size;
4380b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      *mbmi = best_mbmode;
4381b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      uv_tx_size = get_uv_tx_size(mbmi);
43829b35249446b07f40ac5fcc3205f2c048616efacchkuang      rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv_intra[uv_tx_size],
438391037db265ecdd914a26e056cf69207b4f50924ehkuang                              &rate_uv_tokenonly[uv_tx_size],
438491037db265ecdd914a26e056cf69207b4f50924ehkuang                              &dist_uv[uv_tx_size],
438591037db265ecdd914a26e056cf69207b4f50924ehkuang                              &skip_uv[uv_tx_size],
4386b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                              BLOCK_8X8, uv_tx_size);
438791037db265ecdd914a26e056cf69207b4f50924ehkuang    }
438891037db265ecdd914a26e056cf69207b4f50924ehkuang  }
438991037db265ecdd914a26e056cf69207b4f50924ehkuang
43901184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  if (best_rd == INT64_MAX && bsize < BLOCK_8X8) {
4391ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    *returnrate = INT_MAX;
4392b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    *returndistortion = INT64_MAX;
4393ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    return best_rd;
4394ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
4395ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4396b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  assert((cm->interp_filter == SWITCHABLE) ||
4397b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian         (cm->interp_filter == best_mbmode.interp_filter) ||
4398b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian         !is_inter_block(&best_mbmode));
4399ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4400f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  // Updating rd_thresh_freq_fact[] here means that the different
4401ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // partition/block sizes are handled independently based on the best
4402ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // choice for the current partition. It may well be better to keep a scaled
4403ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // best rd so far value and update rd_thresh_freq_fact based on the mode/size
4404ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // combination that wins out.
440591037db265ecdd914a26e056cf69207b4f50924ehkuang  if (cpi->sf.adaptive_rd_thresh) {
44065ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    for (mode_index = 0; mode_index < MAX_REFS; ++mode_index) {
4407b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian      int *const fact = &cpi->rd_thresh_freq_sub8x8[bsize][mode_index];
4408b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
4409ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (mode_index == best_mode_index) {
4410b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        *fact -= (*fact >> 3);
4411ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      } else {
4412b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian        *fact = MIN(*fact + RD_THRESH_INC,
4413b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                    cpi->sf.adaptive_rd_thresh * RD_THRESH_MAX_FACT);
4414ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
4415ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
4416ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
4417ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4418ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // macroblock modes
4419ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  *mbmi = best_mbmode;
442091037db265ecdd914a26e056cf69207b4f50924ehkuang  x->skip |= best_skip2;
4421b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  if (!is_inter_block(&best_mbmode)) {
4422ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (i = 0; i < 4; i++)
44236ac915abcdb404a00d927fe6308a47fcf09d9519hkuang      xd->mi[0]->bmi[i].as_mode = best_bmodes[i].as_mode;
44245ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  } else {
44255ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    for (i = 0; i < 4; ++i)
44266ac915abcdb404a00d927fe6308a47fcf09d9519hkuang      vpx_memcpy(&xd->mi[0]->bmi[i], &best_bmodes[i], sizeof(b_mode_info));
4427ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
44286ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    mbmi->mv[0].as_int = xd->mi[0]->bmi[3].as_mv[0].as_int;
44296ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    mbmi->mv[1].as_int = xd->mi[0]->bmi[3].as_mv[1].as_int;
4430ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
4431ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4432b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  for (i = 0; i < REFERENCE_MODES; ++i) {
4433ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (best_pred_rd[i] == INT64_MAX)
4434ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      best_pred_diff[i] = INT_MIN;
4435ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    else
4436ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      best_pred_diff[i] = best_rd - best_pred_rd[i];
4437ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
4438ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4439ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (!x->skip) {
44405ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) {
444191037db265ecdd914a26e056cf69207b4f50924ehkuang      if (best_filter_rd[i] == INT64_MAX)
444291037db265ecdd914a26e056cf69207b4f50924ehkuang        best_filter_diff[i] = 0;
444391037db265ecdd914a26e056cf69207b4f50924ehkuang      else
444491037db265ecdd914a26e056cf69207b4f50924ehkuang        best_filter_diff[i] = best_rd - best_filter_rd[i];
444591037db265ecdd914a26e056cf69207b4f50924ehkuang    }
4446b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian    if (cm->interp_filter == SWITCHABLE)
44471184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      assert(best_filter_diff[SWITCHABLE_FILTERS] == 0);
444891037db265ecdd914a26e056cf69207b4f50924ehkuang  } else {
44495ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    vp9_zero(best_filter_diff);
445091037db265ecdd914a26e056cf69207b4f50924ehkuang  }
445191037db265ecdd914a26e056cf69207b4f50924ehkuang
445291037db265ecdd914a26e056cf69207b4f50924ehkuang  if (!x->skip) {
4453f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    for (i = 0; i < TX_MODES; i++) {
4454f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      if (best_tx_rd[i] == INT64_MAX)
4455f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        best_tx_diff[i] = 0;
4456ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      else
4457f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        best_tx_diff[i] = best_rd - best_tx_rd[i];
4458ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
4459ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  } else {
44605ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    vp9_zero(best_tx_diff);
4461ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
4462ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4463b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
4464ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  store_coding_context(x, ctx, best_mode_index,
4465ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                       &mbmi->ref_mvs[mbmi->ref_frame[0]][0],
4466ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                       &mbmi->ref_mvs[mbmi->ref_frame[1] < 0 ? 0 :
4467ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                      mbmi->ref_frame[1]][0],
4468f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                       best_pred_diff, best_tx_diff, best_filter_diff);
4469ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4470ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return best_rd;
4471ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
4472