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 <stdio.h>
12ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include <math.h>
13ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include <limits.h>
14ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include <assert.h>
15ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
16ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_pragmas.h"
17ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/encoder/vp9_tokenize.h"
18ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/encoder/vp9_treewriter.h"
19ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/encoder/vp9_onyx_int.h"
20ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/encoder/vp9_modecosts.h"
21ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/encoder/vp9_encodeintra.h"
22ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_entropymode.h"
23ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_reconinter.h"
24ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_reconintra.h"
25ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_findnearmv.h"
26ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_quant_common.h"
27ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/encoder/vp9_encodemb.h"
28ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/encoder/vp9_quantize.h"
29ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/encoder/vp9_variance.h"
30ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/encoder/vp9_mcomp.h"
31ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/encoder/vp9_rdopt.h"
32ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/encoder/vp9_ratectrl.h"
33ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vpx_mem/vpx_mem.h"
34ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_systemdependent.h"
35ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/encoder/vp9_encodemv.h"
36ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_seg_common.h"
37ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_pred_common.h"
38ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_entropy.h"
395ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#include "./vp9_rtcd.h"
40ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_mvref_common.h"
41ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_common.h"
42ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
43ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#define INVALID_MV 0x80008000
44ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
45ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/* Factor to weigh the rate for switchable interp filters */
46ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#define SWITCHABLE_INTERP_RATE_FACTOR 1
47ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
485ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#define LAST_FRAME_MODE_MASK    0xFFEDCD60
495ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#define GOLDEN_FRAME_MODE_MASK  0xFFDA3BB0
505ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#define ALT_REF_MODE_MASK       0xFFC648D0
51ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
525ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#define MIN_EARLY_TERM_INDEX    3
53ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
54ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangconst MODE_DEFINITION vp9_mode_order[MAX_MODES] = {
555ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  {NEARESTMV, LAST_FRAME,   NONE},
565ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  {NEARESTMV, ALTREF_FRAME, NONE},
575ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  {NEARESTMV, GOLDEN_FRAME, NONE},
585ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
595ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  {DC_PRED,   INTRA_FRAME,  NONE},
605ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
615ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  {NEWMV,     LAST_FRAME,   NONE},
625ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  {NEWMV,     ALTREF_FRAME, NONE},
635ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  {NEWMV,     GOLDEN_FRAME, NONE},
645ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
655ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  {NEARMV,    LAST_FRAME,   NONE},
665ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  {NEARMV,    ALTREF_FRAME, NONE},
675ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  {NEARESTMV, LAST_FRAME,   ALTREF_FRAME},
685ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  {NEARESTMV, GOLDEN_FRAME, ALTREF_FRAME},
695ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
705ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  {TM_PRED,   INTRA_FRAME,  NONE},
715ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
725ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  {NEARMV,    LAST_FRAME,   ALTREF_FRAME},
735ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  {NEWMV,     LAST_FRAME,   ALTREF_FRAME},
745ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  {NEARMV,    GOLDEN_FRAME, NONE},
755ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  {NEARMV,    GOLDEN_FRAME, ALTREF_FRAME},
765ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  {NEWMV,     GOLDEN_FRAME, ALTREF_FRAME},
775ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
785ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  {ZEROMV,    LAST_FRAME,   NONE},
795ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  {ZEROMV,    GOLDEN_FRAME, NONE},
805ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  {ZEROMV,    ALTREF_FRAME, NONE},
815ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  {ZEROMV,    LAST_FRAME,   ALTREF_FRAME},
825ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  {ZEROMV,    GOLDEN_FRAME, ALTREF_FRAME},
835ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
845ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  {H_PRED,    INTRA_FRAME,  NONE},
855ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  {V_PRED,    INTRA_FRAME,  NONE},
865ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  {D135_PRED, INTRA_FRAME,  NONE},
875ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  {D207_PRED, INTRA_FRAME,  NONE},
885ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  {D153_PRED, INTRA_FRAME,  NONE},
895ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  {D63_PRED,  INTRA_FRAME,  NONE},
905ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  {D117_PRED, INTRA_FRAME,  NONE},
915ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  {D45_PRED,  INTRA_FRAME,  NONE},
925ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang};
935ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
945ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangconst REF_DEFINITION vp9_ref_order[MAX_REFS] = {
955ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  {LAST_FRAME,   NONE},
965ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  {GOLDEN_FRAME, NONE},
975ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  {ALTREF_FRAME, NONE},
985ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  {LAST_FRAME,   ALTREF_FRAME},
995ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  {GOLDEN_FRAME, ALTREF_FRAME},
1005ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  {INTRA_FRAME,  NONE},
101ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang};
102ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
103ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang// The baseline rd thresholds for breaking out of the rd loop for
104ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang// certain modes are assumed to be based on 8x8 blocks.
105ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang// This table is used to correct for blocks size.
106ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang// The factors here are << 2 (2 = x0.5, 32 = x8 etc).
1071184aebb761cbeac9124c37189a80a1a58f04b6bhkuangstatic int rd_thresh_block_size_factor[BLOCK_SIZES] =
108ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  {2, 3, 3, 4, 6, 6, 8, 12, 12, 16, 24, 24, 32};
109ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1105ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#define RD_THRESH_MAX_FACT 64
1115ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#define RD_THRESH_INC      1
1125ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#define RD_THRESH_POW      1.25
1135ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#define RD_MULT_EPB_RATIO  64
1145ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
1155ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#define MV_COST_WEIGHT      108
1165ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#define MV_COST_WEIGHT_SUB  120
117ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
118f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuangstatic void fill_token_costs(vp9_coeff_cost *c,
119ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                             vp9_coeff_probs_model (*p)[BLOCK_TYPES]) {
120ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int i, j, k, l;
121ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  TX_SIZE t;
122ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (t = TX_4X4; t <= TX_32X32; t++)
123ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (i = 0; i < BLOCK_TYPES; i++)
124ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      for (j = 0; j < REF_TYPES; j++)
125ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        for (k = 0; k < COEF_BANDS; k++)
126ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          for (l = 0; l < PREV_COEF_CONTEXTS; l++) {
127ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            vp9_prob probs[ENTROPY_NODES];
128ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            vp9_model_to_full_probs(p[t][i][j][k][l], probs);
129f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang            vp9_cost_tokens((int *)c[t][i][j][k][0][l], probs,
130ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                            vp9_coef_tree);
131f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang            vp9_cost_tokens_skip((int *)c[t][i][j][k][1][l], probs,
132ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                 vp9_coef_tree);
133f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang            assert(c[t][i][j][k][0][l][DCT_EOB_TOKEN] ==
134f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                   c[t][i][j][k][1][l][DCT_EOB_TOKEN]);
135ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          }
136ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
137ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
13891037db265ecdd914a26e056cf69207b4f50924ehkuangstatic const int rd_iifactor[32] = {
13991037db265ecdd914a26e056cf69207b4f50924ehkuang  4, 4, 3, 2, 1, 0, 0, 0,
14091037db265ecdd914a26e056cf69207b4f50924ehkuang  0, 0, 0, 0, 0, 0, 0, 0,
14191037db265ecdd914a26e056cf69207b4f50924ehkuang  0, 0, 0, 0, 0, 0, 0, 0,
14291037db265ecdd914a26e056cf69207b4f50924ehkuang  0, 0, 0, 0, 0, 0, 0, 0,
14391037db265ecdd914a26e056cf69207b4f50924ehkuang};
144ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
145ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang// 3* dc_qlookup[Q]*dc_qlookup[Q];
146ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
147ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/* values are now correlated to quantizer */
148ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic int sad_per_bit16lut[QINDEX_RANGE];
149ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic int sad_per_bit4lut[QINDEX_RANGE];
150ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
151ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid vp9_init_me_luts() {
152ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int i;
153ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
154ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Initialize the sad lut tables using a formulaic calculation for now
155ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // This is to make it easier to resolve the impact of experimental changes
156ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // to the quantizer tables.
157ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0; i < QINDEX_RANGE; i++) {
158ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    sad_per_bit16lut[i] =
159ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      (int)((0.0418 * vp9_convert_qindex_to_q(i)) + 2.4107);
160ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    sad_per_bit4lut[i] = (int)(0.063 * vp9_convert_qindex_to_q(i) + 2.742);
161ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
162ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
163ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1645ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangint vp9_compute_rd_mult(VP9_COMP *cpi, int qindex) {
165ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int q = vp9_dc_quant(qindex, 0);
1665ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // TODO(debargha): Adjust the function below
1675ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int rdmult = 88 * q * q / 25;
1685ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (cpi->pass == 2 && (cpi->common.frame_type != KEY_FRAME)) {
1695ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (cpi->twopass.next_iiratio > 31)
1705ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      rdmult += (rdmult * rd_iifactor[31]) >> 4;
1715ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    else
1725ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      rdmult += (rdmult * rd_iifactor[cpi->twopass.next_iiratio]) >> 4;
1735ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
1745ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  return rdmult;
175ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
176ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1775ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangstatic int compute_rd_thresh_factor(int qindex) {
1785ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int q;
1795ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // TODO(debargha): Adjust the function below
1805ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  q = (int)(pow(vp9_dc_quant(qindex, 0) / 4.0, RD_THRESH_POW) * 5.12);
1815ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (q < 8)
1825ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    q = 8;
1835ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  return q;
1841184aebb761cbeac9124c37189a80a1a58f04b6bhkuang}
1851184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
186ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid vp9_initialize_me_consts(VP9_COMP *cpi, int qindex) {
187ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  cpi->mb.sadperbit16 = sad_per_bit16lut[qindex];
188ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  cpi->mb.sadperbit4 = sad_per_bit4lut[qindex];
189ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
190ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1915ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangstatic void set_block_thresholds(VP9_COMP *cpi) {
1925ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int i, bsize, segment_id;
1935ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  VP9_COMMON *cm = &cpi->common;
194ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1955ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  for (segment_id = 0; segment_id < MAX_SEGMENTS; ++segment_id) {
1965ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    int q;
1975ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    int segment_qindex = vp9_get_qindex(&cm->seg, segment_id, cm->base_qindex);
1985ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    segment_qindex = clamp(segment_qindex + cm->y_dc_delta_q, 0, MAXQ);
1995ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    q = compute_rd_thresh_factor(segment_qindex);
200ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2011184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    for (bsize = 0; bsize < BLOCK_SIZES; ++bsize) {
2025ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      // Threshold here seem unecessarily harsh but fine given actual
2035ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      // range of values used for cpi->sf.thresh_mult[]
2045ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      int thresh_max = INT_MAX / (q * rd_thresh_block_size_factor[bsize]);
2055ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
206ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      for (i = 0; i < MAX_MODES; ++i) {
2075ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if (cpi->sf.thresh_mult[i] < thresh_max) {
2085ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          cpi->rd_threshes[segment_id][bsize][i] =
2095ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang              cpi->sf.thresh_mult[i] * q *
2105ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang              rd_thresh_block_size_factor[bsize] / 4;
211ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        } else {
2125ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          cpi->rd_threshes[segment_id][bsize][i] = INT_MAX;
213ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
214ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
215ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2165ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      for (i = 0; i < MAX_REFS; ++i) {
2175ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if (cpi->sf.thresh_mult_sub8x8[i] < thresh_max) {
2185ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          cpi->rd_thresh_sub8x8[segment_id][bsize][i] =
2195ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang              cpi->sf.thresh_mult_sub8x8[i] * q *
2205ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang              rd_thresh_block_size_factor[bsize] / 4;
221ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        } else {
2225ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          cpi->rd_thresh_sub8x8[segment_id][bsize][i] = INT_MAX;
223ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
224ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
225ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
226ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
2275ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang}
2285ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
2295ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangvoid vp9_initialize_rd_consts(VP9_COMP *cpi) {
2305ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  VP9_COMMON *cm = &cpi->common;
2315ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int qindex, i;
2325ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
2335ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  vp9_clear_system_state();  // __asm emms;
2345ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
2355ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // Further tests required to see if optimum is different
2365ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // for key frames, golden frames and arf frames.
2375ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // if (cpi->common.refresh_golden_frame ||
2385ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  //     cpi->common.refresh_alt_ref_frame)
2395ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  qindex = clamp(cm->base_qindex + cm->y_dc_delta_q, 0, MAXQ);
2405ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
2415ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  cpi->RDDIV = RDDIV_BITS;  // in bits (to multiply D by 128)
2425ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  cpi->RDMULT = vp9_compute_rd_mult(cpi, qindex);
243ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2445ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  cpi->mb.errorperbit = cpi->RDMULT / RD_MULT_EPB_RATIO;
2455ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  cpi->mb.errorperbit += (cpi->mb.errorperbit == 0);
2465ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
2475ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  vp9_set_speed_features(cpi);
2485ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
2499b35249446b07f40ac5fcc3205f2c048616efacchkuang  cpi->mb.select_txfm_size = (cpi->sf.tx_size_search_method == USE_LARGESTALL &&
2509b35249446b07f40ac5fcc3205f2c048616efacchkuang                              cm->frame_type != KEY_FRAME) ?
2519b35249446b07f40ac5fcc3205f2c048616efacchkuang                             0 : 1;
2529b35249446b07f40ac5fcc3205f2c048616efacchkuang
2535ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  set_block_thresholds(cpi);
254ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2555ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  fill_token_costs(cpi->mb.token_costs, cm->fc.coef_probs);
2565ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
2575ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  for (i = 0; i < PARTITION_CONTEXTS; i++)
2585ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    vp9_cost_tokens(cpi->mb.partition_cost[i], get_partition_probs(cm, i),
259ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                    vp9_partition_tree);
260ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
261ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /*rough estimate for costing*/
262ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vp9_init_mode_costs(cpi);
263ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2645ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (!frame_is_intra_only(cm)) {
265ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vp9_build_nmv_cost_table(
266ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        cpi->mb.nmvjointcost,
2675ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        cm->allow_high_precision_mv ? cpi->mb.nmvcost_hp : cpi->mb.nmvcost,
2685ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        &cm->fc.nmvc,
2695ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        cm->allow_high_precision_mv, 1, 1);
27091037db265ecdd914a26e056cf69207b4f50924ehkuang
27191037db265ecdd914a26e056cf69207b4f50924ehkuang    for (i = 0; i < INTER_MODE_CONTEXTS; i++) {
27291037db265ecdd914a26e056cf69207b4f50924ehkuang      MB_PREDICTION_MODE m;
27391037db265ecdd914a26e056cf69207b4f50924ehkuang
27491037db265ecdd914a26e056cf69207b4f50924ehkuang      for (m = NEARESTMV; m < MB_MODE_COUNT; m++)
2759b35249446b07f40ac5fcc3205f2c048616efacchkuang        cpi->mb.inter_mode_cost[i][INTER_OFFSET(m)] =
27691037db265ecdd914a26e056cf69207b4f50924ehkuang            cost_token(vp9_inter_mode_tree,
2775ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                       cm->fc.inter_mode_probs[i],
2789b35249446b07f40ac5fcc3205f2c048616efacchkuang                       &vp9_inter_mode_encodings[INTER_OFFSET(m)]);
27991037db265ecdd914a26e056cf69207b4f50924ehkuang    }
28091037db265ecdd914a26e056cf69207b4f50924ehkuang  }
28191037db265ecdd914a26e056cf69207b4f50924ehkuang}
28291037db265ecdd914a26e056cf69207b4f50924ehkuang
28391037db265ecdd914a26e056cf69207b4f50924ehkuangstatic INLINE void linear_interpolate2(double x, int ntab, int inv_step,
28491037db265ecdd914a26e056cf69207b4f50924ehkuang                                       const double *tab1, const double *tab2,
28591037db265ecdd914a26e056cf69207b4f50924ehkuang                                       double *v1, double *v2) {
28691037db265ecdd914a26e056cf69207b4f50924ehkuang  double y = x * inv_step;
28791037db265ecdd914a26e056cf69207b4f50924ehkuang  int d = (int) y;
28891037db265ecdd914a26e056cf69207b4f50924ehkuang  if (d >= ntab - 1) {
28991037db265ecdd914a26e056cf69207b4f50924ehkuang    *v1 = tab1[ntab - 1];
29091037db265ecdd914a26e056cf69207b4f50924ehkuang    *v2 = tab2[ntab - 1];
29191037db265ecdd914a26e056cf69207b4f50924ehkuang  } else {
29291037db265ecdd914a26e056cf69207b4f50924ehkuang    double a = y - d;
29391037db265ecdd914a26e056cf69207b4f50924ehkuang    *v1 = tab1[d] * (1 - a) + tab1[d + 1] * a;
29491037db265ecdd914a26e056cf69207b4f50924ehkuang    *v2 = tab2[d] * (1 - a) + tab2[d + 1] * a;
29591037db265ecdd914a26e056cf69207b4f50924ehkuang  }
29691037db265ecdd914a26e056cf69207b4f50924ehkuang}
29791037db265ecdd914a26e056cf69207b4f50924ehkuang
29891037db265ecdd914a26e056cf69207b4f50924ehkuangstatic void model_rd_norm(double x, double *R, double *D) {
29991037db265ecdd914a26e056cf69207b4f50924ehkuang  static const int inv_tab_step = 8;
30091037db265ecdd914a26e056cf69207b4f50924ehkuang  static const int tab_size = 120;
30191037db265ecdd914a26e056cf69207b4f50924ehkuang  // NOTE: The tables below must be of the same size
30291037db265ecdd914a26e056cf69207b4f50924ehkuang  //
30391037db265ecdd914a26e056cf69207b4f50924ehkuang  // Normalized rate
30491037db265ecdd914a26e056cf69207b4f50924ehkuang  // This table models the rate for a Laplacian source
30591037db265ecdd914a26e056cf69207b4f50924ehkuang  // source with given variance when quantized with a uniform quantizer
30691037db265ecdd914a26e056cf69207b4f50924ehkuang  // with given stepsize. The closed form expression is:
30791037db265ecdd914a26e056cf69207b4f50924ehkuang  // Rn(x) = H(sqrt(r)) + sqrt(r)*[1 + H(r)/(1 - r)],
30891037db265ecdd914a26e056cf69207b4f50924ehkuang  // where r = exp(-sqrt(2) * x) and x = qpstep / sqrt(variance),
30991037db265ecdd914a26e056cf69207b4f50924ehkuang  // and H(x) is the binary entropy function.
31091037db265ecdd914a26e056cf69207b4f50924ehkuang  static const double rate_tab[] = {
31191037db265ecdd914a26e056cf69207b4f50924ehkuang    64.00, 4.944, 3.949, 3.372, 2.966, 2.655, 2.403, 2.194,
31291037db265ecdd914a26e056cf69207b4f50924ehkuang    2.014, 1.858, 1.720, 1.596, 1.485, 1.384, 1.291, 1.206,
31391037db265ecdd914a26e056cf69207b4f50924ehkuang    1.127, 1.054, 0.986, 0.923, 0.863, 0.808, 0.756, 0.708,
31491037db265ecdd914a26e056cf69207b4f50924ehkuang    0.662, 0.619, 0.579, 0.541, 0.506, 0.473, 0.442, 0.412,
31591037db265ecdd914a26e056cf69207b4f50924ehkuang    0.385, 0.359, 0.335, 0.313, 0.291, 0.272, 0.253, 0.236,
31691037db265ecdd914a26e056cf69207b4f50924ehkuang    0.220, 0.204, 0.190, 0.177, 0.165, 0.153, 0.142, 0.132,
31791037db265ecdd914a26e056cf69207b4f50924ehkuang    0.123, 0.114, 0.106, 0.099, 0.091, 0.085, 0.079, 0.073,
31891037db265ecdd914a26e056cf69207b4f50924ehkuang    0.068, 0.063, 0.058, 0.054, 0.050, 0.047, 0.043, 0.040,
31991037db265ecdd914a26e056cf69207b4f50924ehkuang    0.037, 0.034, 0.032, 0.029, 0.027, 0.025, 0.023, 0.022,
32091037db265ecdd914a26e056cf69207b4f50924ehkuang    0.020, 0.019, 0.017, 0.016, 0.015, 0.014, 0.013, 0.012,
32191037db265ecdd914a26e056cf69207b4f50924ehkuang    0.011, 0.010, 0.009, 0.008, 0.008, 0.007, 0.007, 0.006,
32291037db265ecdd914a26e056cf69207b4f50924ehkuang    0.006, 0.005, 0.005, 0.005, 0.004, 0.004, 0.004, 0.003,
32391037db265ecdd914a26e056cf69207b4f50924ehkuang    0.003, 0.003, 0.003, 0.002, 0.002, 0.002, 0.002, 0.002,
32491037db265ecdd914a26e056cf69207b4f50924ehkuang    0.002, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001,
32591037db265ecdd914a26e056cf69207b4f50924ehkuang    0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.000,
32691037db265ecdd914a26e056cf69207b4f50924ehkuang  };
32791037db265ecdd914a26e056cf69207b4f50924ehkuang  // Normalized distortion
32891037db265ecdd914a26e056cf69207b4f50924ehkuang  // This table models the normalized distortion 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  // Dn(x) = 1 - 1/sqrt(2) * x / sinh(x/sqrt(2))
33291037db265ecdd914a26e056cf69207b4f50924ehkuang  // where x = qpstep / sqrt(variance)
33391037db265ecdd914a26e056cf69207b4f50924ehkuang  // Note the actual distortion is Dn * variance.
33491037db265ecdd914a26e056cf69207b4f50924ehkuang  static const double dist_tab[] = {
33591037db265ecdd914a26e056cf69207b4f50924ehkuang    0.000, 0.001, 0.005, 0.012, 0.021, 0.032, 0.045, 0.061,
33691037db265ecdd914a26e056cf69207b4f50924ehkuang    0.079, 0.098, 0.119, 0.142, 0.166, 0.190, 0.216, 0.242,
33791037db265ecdd914a26e056cf69207b4f50924ehkuang    0.269, 0.296, 0.324, 0.351, 0.378, 0.405, 0.432, 0.458,
33891037db265ecdd914a26e056cf69207b4f50924ehkuang    0.484, 0.509, 0.534, 0.557, 0.580, 0.603, 0.624, 0.645,
33991037db265ecdd914a26e056cf69207b4f50924ehkuang    0.664, 0.683, 0.702, 0.719, 0.735, 0.751, 0.766, 0.780,
34091037db265ecdd914a26e056cf69207b4f50924ehkuang    0.794, 0.807, 0.819, 0.830, 0.841, 0.851, 0.861, 0.870,
34191037db265ecdd914a26e056cf69207b4f50924ehkuang    0.878, 0.886, 0.894, 0.901, 0.907, 0.913, 0.919, 0.925,
34291037db265ecdd914a26e056cf69207b4f50924ehkuang    0.930, 0.935, 0.939, 0.943, 0.947, 0.951, 0.954, 0.957,
34391037db265ecdd914a26e056cf69207b4f50924ehkuang    0.960, 0.963, 0.966, 0.968, 0.971, 0.973, 0.975, 0.976,
34491037db265ecdd914a26e056cf69207b4f50924ehkuang    0.978, 0.980, 0.981, 0.982, 0.984, 0.985, 0.986, 0.987,
34591037db265ecdd914a26e056cf69207b4f50924ehkuang    0.988, 0.989, 0.990, 0.990, 0.991, 0.992, 0.992, 0.993,
34691037db265ecdd914a26e056cf69207b4f50924ehkuang    0.993, 0.994, 0.994, 0.995, 0.995, 0.996, 0.996, 0.996,
34791037db265ecdd914a26e056cf69207b4f50924ehkuang    0.996, 0.997, 0.997, 0.997, 0.997, 0.998, 0.998, 0.998,
34891037db265ecdd914a26e056cf69207b4f50924ehkuang    0.998, 0.998, 0.998, 0.999, 0.999, 0.999, 0.999, 0.999,
34991037db265ecdd914a26e056cf69207b4f50924ehkuang    0.999, 0.999, 0.999, 0.999, 0.999, 0.999, 0.999, 1.000,
35091037db265ecdd914a26e056cf69207b4f50924ehkuang  };
35191037db265ecdd914a26e056cf69207b4f50924ehkuang  /*
35291037db265ecdd914a26e056cf69207b4f50924ehkuang  assert(sizeof(rate_tab) == tab_size * sizeof(rate_tab[0]);
35391037db265ecdd914a26e056cf69207b4f50924ehkuang  assert(sizeof(dist_tab) == tab_size * sizeof(dist_tab[0]);
35491037db265ecdd914a26e056cf69207b4f50924ehkuang  assert(sizeof(rate_tab) == sizeof(dist_tab));
35591037db265ecdd914a26e056cf69207b4f50924ehkuang  */
35691037db265ecdd914a26e056cf69207b4f50924ehkuang  assert(x >= 0.0);
35791037db265ecdd914a26e056cf69207b4f50924ehkuang  linear_interpolate2(x, tab_size, inv_tab_step,
35891037db265ecdd914a26e056cf69207b4f50924ehkuang                      rate_tab, dist_tab, R, D);
35991037db265ecdd914a26e056cf69207b4f50924ehkuang}
36091037db265ecdd914a26e056cf69207b4f50924ehkuang
36191037db265ecdd914a26e056cf69207b4f50924ehkuangstatic void model_rd_from_var_lapndz(int var, int n, int qstep,
36291037db265ecdd914a26e056cf69207b4f50924ehkuang                                     int *rate, int64_t *dist) {
36391037db265ecdd914a26e056cf69207b4f50924ehkuang  // This function models the rate and distortion for a Laplacian
36491037db265ecdd914a26e056cf69207b4f50924ehkuang  // source with given variance when quantized with a uniform quantizer
36591037db265ecdd914a26e056cf69207b4f50924ehkuang  // with given stepsize. The closed form expressions are in:
36691037db265ecdd914a26e056cf69207b4f50924ehkuang  // Hang and Chen, "Source Model for transform video coder and its
36791037db265ecdd914a26e056cf69207b4f50924ehkuang  // application - Part I: Fundamental Theory", IEEE Trans. Circ.
36891037db265ecdd914a26e056cf69207b4f50924ehkuang  // Sys. for Video Tech., April 1997.
36991037db265ecdd914a26e056cf69207b4f50924ehkuang  vp9_clear_system_state();
37091037db265ecdd914a26e056cf69207b4f50924ehkuang  if (var == 0 || n == 0) {
37191037db265ecdd914a26e056cf69207b4f50924ehkuang    *rate = 0;
37291037db265ecdd914a26e056cf69207b4f50924ehkuang    *dist = 0;
37391037db265ecdd914a26e056cf69207b4f50924ehkuang  } else {
37491037db265ecdd914a26e056cf69207b4f50924ehkuang    double D, R;
37591037db265ecdd914a26e056cf69207b4f50924ehkuang    double s2 = (double) var / n;
37691037db265ecdd914a26e056cf69207b4f50924ehkuang    double x = qstep / sqrt(s2);
37791037db265ecdd914a26e056cf69207b4f50924ehkuang    model_rd_norm(x, &R, &D);
3785ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    *rate = (int)((n << 8) * R + 0.5);
3795ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    *dist = (int)(var * D + 0.5);
38091037db265ecdd914a26e056cf69207b4f50924ehkuang  }
38191037db265ecdd914a26e056cf69207b4f50924ehkuang  vp9_clear_system_state();
38291037db265ecdd914a26e056cf69207b4f50924ehkuang}
38391037db265ecdd914a26e056cf69207b4f50924ehkuang
3841184aebb761cbeac9124c37189a80a1a58f04b6bhkuangstatic void model_rd_for_sb(VP9_COMP *cpi, BLOCK_SIZE bsize,
38591037db265ecdd914a26e056cf69207b4f50924ehkuang                            MACROBLOCK *x, MACROBLOCKD *xd,
38691037db265ecdd914a26e056cf69207b4f50924ehkuang                            int *out_rate_sum, int64_t *out_dist_sum) {
38791037db265ecdd914a26e056cf69207b4f50924ehkuang  // Note our transform coeffs are 8 times an orthogonal transform.
38891037db265ecdd914a26e056cf69207b4f50924ehkuang  // Hence quantizer step is also 8 times. To get effective quantizer
38991037db265ecdd914a26e056cf69207b4f50924ehkuang  // we need to divide by 8 before sending to modeling function.
39091037db265ecdd914a26e056cf69207b4f50924ehkuang  int i, rate_sum = 0, dist_sum = 0;
39191037db265ecdd914a26e056cf69207b4f50924ehkuang
39291037db265ecdd914a26e056cf69207b4f50924ehkuang  for (i = 0; i < MAX_MB_PLANE; ++i) {
39391037db265ecdd914a26e056cf69207b4f50924ehkuang    struct macroblock_plane *const p = &x->plane[i];
39491037db265ecdd914a26e056cf69207b4f50924ehkuang    struct macroblockd_plane *const pd = &xd->plane[i];
3951184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    const BLOCK_SIZE bs = get_plane_block_size(bsize, pd);
39691037db265ecdd914a26e056cf69207b4f50924ehkuang    unsigned int sse;
39791037db265ecdd914a26e056cf69207b4f50924ehkuang    int rate;
39891037db265ecdd914a26e056cf69207b4f50924ehkuang    int64_t dist;
39991037db265ecdd914a26e056cf69207b4f50924ehkuang    (void) cpi->fn_ptr[bs].vf(p->src.buf, p->src.stride,
40091037db265ecdd914a26e056cf69207b4f50924ehkuang                              pd->dst.buf, pd->dst.stride, &sse);
40191037db265ecdd914a26e056cf69207b4f50924ehkuang    // sse works better than var, since there is no dc prediction used
4021184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    model_rd_from_var_lapndz(sse, 1 << num_pels_log2_lookup[bs],
40391037db265ecdd914a26e056cf69207b4f50924ehkuang                             pd->dequant[1] >> 3, &rate, &dist);
40491037db265ecdd914a26e056cf69207b4f50924ehkuang
40591037db265ecdd914a26e056cf69207b4f50924ehkuang    rate_sum += rate;
4065ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    dist_sum += (int)dist;
40791037db265ecdd914a26e056cf69207b4f50924ehkuang  }
40891037db265ecdd914a26e056cf69207b4f50924ehkuang
40991037db265ecdd914a26e056cf69207b4f50924ehkuang  *out_rate_sum = rate_sum;
41091037db265ecdd914a26e056cf69207b4f50924ehkuang  *out_dist_sum = dist_sum << 4;
41191037db265ecdd914a26e056cf69207b4f50924ehkuang}
41291037db265ecdd914a26e056cf69207b4f50924ehkuang
4131184aebb761cbeac9124c37189a80a1a58f04b6bhkuangstatic void model_rd_for_sb_y_tx(VP9_COMP *cpi, BLOCK_SIZE bsize,
41491037db265ecdd914a26e056cf69207b4f50924ehkuang                                 TX_SIZE tx_size,
41591037db265ecdd914a26e056cf69207b4f50924ehkuang                                 MACROBLOCK *x, MACROBLOCKD *xd,
41691037db265ecdd914a26e056cf69207b4f50924ehkuang                                 int *out_rate_sum, int64_t *out_dist_sum,
41791037db265ecdd914a26e056cf69207b4f50924ehkuang                                 int *out_skip) {
4181184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int j, k;
4191184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  BLOCK_SIZE bs;
42091037db265ecdd914a26e056cf69207b4f50924ehkuang  struct macroblock_plane *const p = &x->plane[0];
42191037db265ecdd914a26e056cf69207b4f50924ehkuang  struct macroblockd_plane *const pd = &xd->plane[0];
4221184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const int width = 4 << num_4x4_blocks_wide_lookup[bsize];
4231184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const int height = 4 << num_4x4_blocks_high_lookup[bsize];
42491037db265ecdd914a26e056cf69207b4f50924ehkuang  int rate_sum = 0;
42591037db265ecdd914a26e056cf69207b4f50924ehkuang  int64_t dist_sum = 0;
4261184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const int t = 4 << tx_size;
42791037db265ecdd914a26e056cf69207b4f50924ehkuang
42891037db265ecdd914a26e056cf69207b4f50924ehkuang  if (tx_size == TX_4X4) {
42991037db265ecdd914a26e056cf69207b4f50924ehkuang    bs = BLOCK_4X4;
43091037db265ecdd914a26e056cf69207b4f50924ehkuang  } else if (tx_size == TX_8X8) {
43191037db265ecdd914a26e056cf69207b4f50924ehkuang    bs = BLOCK_8X8;
43291037db265ecdd914a26e056cf69207b4f50924ehkuang  } else if (tx_size == TX_16X16) {
43391037db265ecdd914a26e056cf69207b4f50924ehkuang    bs = BLOCK_16X16;
43491037db265ecdd914a26e056cf69207b4f50924ehkuang  } else if (tx_size == TX_32X32) {
43591037db265ecdd914a26e056cf69207b4f50924ehkuang    bs = BLOCK_32X32;
43691037db265ecdd914a26e056cf69207b4f50924ehkuang  } else {
43791037db265ecdd914a26e056cf69207b4f50924ehkuang    assert(0);
43891037db265ecdd914a26e056cf69207b4f50924ehkuang  }
4391184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
44091037db265ecdd914a26e056cf69207b4f50924ehkuang  *out_skip = 1;
44191037db265ecdd914a26e056cf69207b4f50924ehkuang  for (j = 0; j < height; j += t) {
44291037db265ecdd914a26e056cf69207b4f50924ehkuang    for (k = 0; k < width; k += t) {
44391037db265ecdd914a26e056cf69207b4f50924ehkuang      int rate;
44491037db265ecdd914a26e056cf69207b4f50924ehkuang      int64_t dist;
44591037db265ecdd914a26e056cf69207b4f50924ehkuang      unsigned int sse;
4461184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      cpi->fn_ptr[bs].vf(&p->src.buf[j * p->src.stride + k], p->src.stride,
4471184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                         &pd->dst.buf[j * pd->dst.stride + k], pd->dst.stride,
4481184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                         &sse);
44991037db265ecdd914a26e056cf69207b4f50924ehkuang      // sse works better than var, since there is no dc prediction used
4501184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      model_rd_from_var_lapndz(sse, t * t, pd->dequant[1] >> 3, &rate, &dist);
45191037db265ecdd914a26e056cf69207b4f50924ehkuang      rate_sum += rate;
45291037db265ecdd914a26e056cf69207b4f50924ehkuang      dist_sum += dist;
45391037db265ecdd914a26e056cf69207b4f50924ehkuang      *out_skip &= (rate < 1024);
45491037db265ecdd914a26e056cf69207b4f50924ehkuang    }
455ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
4561184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
45791037db265ecdd914a26e056cf69207b4f50924ehkuang  *out_rate_sum = rate_sum;
4581184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  *out_dist_sum = dist_sum << 4;
459ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
460ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
46191037db265ecdd914a26e056cf69207b4f50924ehkuangint64_t vp9_block_error_c(int16_t *coeff, int16_t *dqcoeff,
46291037db265ecdd914a26e056cf69207b4f50924ehkuang                          intptr_t block_size, int64_t *ssz) {
46391037db265ecdd914a26e056cf69207b4f50924ehkuang  int i;
46491037db265ecdd914a26e056cf69207b4f50924ehkuang  int64_t error = 0, sqcoeff = 0;
465ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
466ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0; i < block_size; i++) {
467ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int this_diff = coeff[i] - dqcoeff[i];
46891037db265ecdd914a26e056cf69207b4f50924ehkuang    error += (unsigned)this_diff * this_diff;
46991037db265ecdd914a26e056cf69207b4f50924ehkuang    sqcoeff += (unsigned) coeff[i] * coeff[i];
470ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
471ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
47291037db265ecdd914a26e056cf69207b4f50924ehkuang  *ssz = sqcoeff;
473ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return error;
474ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
475ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
476f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang/* The trailing '0' is a terminator which is used inside cost_coeffs() to
477f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang * decide whether to include cost of a trailing EOB node or not (i.e. we
478f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang * can skip this if the last coefficient in this transform block, e.g. the
479f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang * 16th coefficient in a 4x4 block or the 64th coefficient in a 8x8 block,
480f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang * were non-zero). */
481f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuangstatic const int16_t band_counts[TX_SIZES][8] = {
482f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  { 1, 2, 3, 4,  3,   16 - 13, 0 },
483f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  { 1, 2, 3, 4, 11,   64 - 21, 0 },
484f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  { 1, 2, 3, 4, 11,  256 - 21, 0 },
485f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  { 1, 2, 3, 4, 11, 1024 - 21, 0 },
48691037db265ecdd914a26e056cf69207b4f50924ehkuang};
48791037db265ecdd914a26e056cf69207b4f50924ehkuang
4885ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangstatic INLINE int cost_coeffs(MACROBLOCK *x,
4891184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                              int plane, int block,
49091037db265ecdd914a26e056cf69207b4f50924ehkuang                              ENTROPY_CONTEXT *A, ENTROPY_CONTEXT *L,
491ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                              TX_SIZE tx_size,
49291037db265ecdd914a26e056cf69207b4f50924ehkuang                              const int16_t *scan, const int16_t *nb) {
4935ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MACROBLOCKD *const xd = &x->e_mbd;
4945ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi;
4951184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  struct macroblockd_plane *pd = &xd->plane[plane];
4961184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const PLANE_TYPE type = pd->plane_type;
497f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  const int16_t *band_count = &band_counts[tx_size][1];
4981184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const int eob = pd->eobs[block];
4991184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const int16_t *const qcoeff_ptr = BLOCK_OFFSET(pd->qcoeff, block);
500ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int ref = mbmi->ref_frame[0] != INTRA_FRAME;
5011184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  unsigned int (*token_costs)[2][PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS] =
5025ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                   x->token_costs[tx_size][type][ref];
5031184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const ENTROPY_CONTEXT above_ec = !!*A, left_ec = !!*L;
5045ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  uint8_t *p_tok = x->token_cache;
5051184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int pt = combine_entropy_contexts(above_ec, left_ec);
5061184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int c, cost;
507ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
508ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Check for consistency of tx_size with mode info
5091184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  assert(type == PLANE_TYPE_Y_WITH_DC ? mbmi->tx_size == tx_size
5101184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                      : get_uv_tx_size(mbmi) == tx_size);
51191037db265ecdd914a26e056cf69207b4f50924ehkuang
51291037db265ecdd914a26e056cf69207b4f50924ehkuang  if (eob == 0) {
51391037db265ecdd914a26e056cf69207b4f50924ehkuang    // single eob token
51491037db265ecdd914a26e056cf69207b4f50924ehkuang    cost = token_costs[0][0][pt][DCT_EOB_TOKEN];
51591037db265ecdd914a26e056cf69207b4f50924ehkuang    c = 0;
51691037db265ecdd914a26e056cf69207b4f50924ehkuang  } else {
5171184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    int band_left = *band_count++;
51891037db265ecdd914a26e056cf69207b4f50924ehkuang
51991037db265ecdd914a26e056cf69207b4f50924ehkuang    // dc token
5201184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    int v = qcoeff_ptr[0];
5211184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    int prev_t = vp9_dct_value_tokens_ptr[v].token;
522f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    cost = (*token_costs)[0][pt][prev_t] + vp9_dct_value_cost_ptr[v];
5235ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    p_tok[0] = vp9_pt_energy_class[prev_t];
524f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    ++token_costs;
52591037db265ecdd914a26e056cf69207b4f50924ehkuang
52691037db265ecdd914a26e056cf69207b4f50924ehkuang    // ac tokens
52791037db265ecdd914a26e056cf69207b4f50924ehkuang    for (c = 1; c < eob; c++) {
52891037db265ecdd914a26e056cf69207b4f50924ehkuang      const int rc = scan[c];
52991037db265ecdd914a26e056cf69207b4f50924ehkuang      int t;
53091037db265ecdd914a26e056cf69207b4f50924ehkuang
53191037db265ecdd914a26e056cf69207b4f50924ehkuang      v = qcoeff_ptr[rc];
53291037db265ecdd914a26e056cf69207b4f50924ehkuang      t = vp9_dct_value_tokens_ptr[v].token;
5335ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      pt = get_coef_context(nb, p_tok, c);
534f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      cost += (*token_costs)[!prev_t][pt][t] + vp9_dct_value_cost_ptr[v];
5355ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      p_tok[rc] = vp9_pt_energy_class[t];
53691037db265ecdd914a26e056cf69207b4f50924ehkuang      prev_t = t;
53791037db265ecdd914a26e056cf69207b4f50924ehkuang      if (!--band_left) {
538f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        band_left = *band_count++;
539f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        ++token_costs;
54091037db265ecdd914a26e056cf69207b4f50924ehkuang      }
54191037db265ecdd914a26e056cf69207b4f50924ehkuang    }
54291037db265ecdd914a26e056cf69207b4f50924ehkuang
54391037db265ecdd914a26e056cf69207b4f50924ehkuang    // eob token
544f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    if (band_left) {
5455ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      pt = get_coef_context(nb, p_tok, c);
546f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      cost += (*token_costs)[0][pt][DCT_EOB_TOKEN];
54791037db265ecdd914a26e056cf69207b4f50924ehkuang    }
548ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
549ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
55091037db265ecdd914a26e056cf69207b4f50924ehkuang  // is eob first coefficient;
5511184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  *A = *L = (c > 0);
55291037db265ecdd914a26e056cf69207b4f50924ehkuang
55391037db265ecdd914a26e056cf69207b4f50924ehkuang  return cost;
55491037db265ecdd914a26e056cf69207b4f50924ehkuang}
55591037db265ecdd914a26e056cf69207b4f50924ehkuang
5561184aebb761cbeac9124c37189a80a1a58f04b6bhkuangstatic void dist_block(int plane, int block, TX_SIZE tx_size, void *arg) {
5571184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const int ss_txfrm_size = tx_size << 1;
55891037db265ecdd914a26e056cf69207b4f50924ehkuang  struct rdcost_block_args* args = arg;
55991037db265ecdd914a26e056cf69207b4f50924ehkuang  MACROBLOCK* const x = args->x;
56091037db265ecdd914a26e056cf69207b4f50924ehkuang  MACROBLOCKD* const xd = &x->e_mbd;
5611184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  struct macroblock_plane *const p = &x->plane[plane];
5621184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  struct macroblockd_plane *const pd = &xd->plane[plane];
56391037db265ecdd914a26e056cf69207b4f50924ehkuang  int64_t this_sse;
56491037db265ecdd914a26e056cf69207b4f50924ehkuang  int shift = args->tx_size == TX_32X32 ? 0 : 2;
5651184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int16_t *const coeff = BLOCK_OFFSET(p->coeff, block);
5661184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int16_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
5675ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  args->dist = vp9_block_error(coeff, dqcoeff, 16 << ss_txfrm_size,
5685ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                               &this_sse) >> shift;
5695ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  args->sse  = this_sse >> shift;
57091037db265ecdd914a26e056cf69207b4f50924ehkuang
57191037db265ecdd914a26e056cf69207b4f50924ehkuang  if (x->skip_encode &&
5725ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      xd->mi_8x8[0]->mbmi.ref_frame[0] == INTRA_FRAME) {
57391037db265ecdd914a26e056cf69207b4f50924ehkuang    // TODO(jingning): tune the model to better capture the distortion.
57491037db265ecdd914a26e056cf69207b4f50924ehkuang    int64_t p = (pd->dequant[1] * pd->dequant[1] *
5755ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                    (1 << ss_txfrm_size)) >> (shift + 2);
5765ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    args->dist += (p >> 4);
57791037db265ecdd914a26e056cf69207b4f50924ehkuang    args->sse  += p;
57891037db265ecdd914a26e056cf69207b4f50924ehkuang  }
57991037db265ecdd914a26e056cf69207b4f50924ehkuang}
58091037db265ecdd914a26e056cf69207b4f50924ehkuang
5811184aebb761cbeac9124c37189a80a1a58f04b6bhkuangstatic void rate_block(int plane, int block, BLOCK_SIZE plane_bsize,
5821184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                       TX_SIZE tx_size, void *arg) {
58391037db265ecdd914a26e056cf69207b4f50924ehkuang  struct rdcost_block_args* args = arg;
58491037db265ecdd914a26e056cf69207b4f50924ehkuang
5851184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int x_idx, y_idx;
5861184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  txfrm_block_to_raster_xy(plane_bsize, args->tx_size, block, &x_idx, &y_idx);
58791037db265ecdd914a26e056cf69207b4f50924ehkuang
5885ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  args->rate = cost_coeffs(args->x, plane, block, args->t_above + x_idx,
5895ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                           args->t_left + y_idx, args->tx_size,
5905ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                           args->scan, args->nb);
59191037db265ecdd914a26e056cf69207b4f50924ehkuang}
59291037db265ecdd914a26e056cf69207b4f50924ehkuang
5931184aebb761cbeac9124c37189a80a1a58f04b6bhkuangstatic void block_yrd_txfm(int plane, int block, BLOCK_SIZE plane_bsize,
5941184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                           TX_SIZE tx_size, void *arg) {
59591037db265ecdd914a26e056cf69207b4f50924ehkuang  struct rdcost_block_args *args = arg;
59691037db265ecdd914a26e056cf69207b4f50924ehkuang  MACROBLOCK *const x = args->x;
59791037db265ecdd914a26e056cf69207b4f50924ehkuang  MACROBLOCKD *const xd = &x->e_mbd;
5981184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  struct encode_b_args encode_args = {x, NULL};
59991037db265ecdd914a26e056cf69207b4f50924ehkuang  int64_t rd1, rd2, rd;
60091037db265ecdd914a26e056cf69207b4f50924ehkuang
60191037db265ecdd914a26e056cf69207b4f50924ehkuang  if (args->skip)
60291037db265ecdd914a26e056cf69207b4f50924ehkuang    return;
60391037db265ecdd914a26e056cf69207b4f50924ehkuang
6045ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (!is_inter_block(&xd->mi_8x8[0]->mbmi))
6051184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    vp9_encode_block_intra(plane, block, plane_bsize, tx_size, &encode_args);
60691037db265ecdd914a26e056cf69207b4f50924ehkuang  else
6071184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    vp9_xform_quant(plane, block, plane_bsize, tx_size, &encode_args);
60891037db265ecdd914a26e056cf69207b4f50924ehkuang
6091184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  dist_block(plane, block, tx_size, args);
6101184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  rate_block(plane, block, plane_bsize, tx_size, args);
6115ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  rd1 = RDCOST(x->rdmult, x->rddiv, args->rate, args->dist);
6125ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  rd2 = RDCOST(x->rdmult, x->rddiv, 0, args->sse);
61391037db265ecdd914a26e056cf69207b4f50924ehkuang
6145ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // TODO(jingning): temporarily enabled only for luma component
6155ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  rd = MIN(rd1, rd2);
6169b35249446b07f40ac5fcc3205f2c048616efacchkuang  if (!xd->lossless && plane == 0)
6175ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    x->zcoeff_blk[tx_size][block] = rd1 > rd2 || !xd->plane[plane].eobs[block];
6185ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
6195ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  args->this_rate += args->rate;
6205ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  args->this_dist += args->dist;
6215ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  args->this_sse  += args->sse;
6225ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  args->this_rd += rd;
6235ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
6245ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (args->this_rd > args->best_rd) {
6255ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    args->skip = 1;
6265ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    return;
6275ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
6285ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang}
6291184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
6305ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangvoid vp9_get_entropy_contexts(TX_SIZE tx_size,
6315ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    ENTROPY_CONTEXT t_above[16], ENTROPY_CONTEXT t_left[16],
6325ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    const ENTROPY_CONTEXT *above, const ENTROPY_CONTEXT *left,
6335ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    int num_4x4_w, int num_4x4_h) {
6345ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int i;
63591037db265ecdd914a26e056cf69207b4f50924ehkuang  switch (tx_size) {
63691037db265ecdd914a26e056cf69207b4f50924ehkuang    case TX_4X4:
6375ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      vpx_memcpy(t_above, above, sizeof(ENTROPY_CONTEXT) * num_4x4_w);
6385ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      vpx_memcpy(t_left, left, sizeof(ENTROPY_CONTEXT) * num_4x4_h);
63991037db265ecdd914a26e056cf69207b4f50924ehkuang      break;
64091037db265ecdd914a26e056cf69207b4f50924ehkuang    case TX_8X8:
6415ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      for (i = 0; i < num_4x4_w; i += 2)
6425ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        t_above[i] = !!*(const uint16_t *)&above[i];
6435ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      for (i = 0; i < num_4x4_h; i += 2)
6445ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        t_left[i] = !!*(const uint16_t *)&left[i];
64591037db265ecdd914a26e056cf69207b4f50924ehkuang      break;
64691037db265ecdd914a26e056cf69207b4f50924ehkuang    case TX_16X16:
6475ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      for (i = 0; i < num_4x4_w; i += 4)
6485ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        t_above[i] = !!*(const uint32_t *)&above[i];
6495ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      for (i = 0; i < num_4x4_h; i += 4)
6505ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        t_left[i] = !!*(const uint32_t *)&left[i];
65191037db265ecdd914a26e056cf69207b4f50924ehkuang      break;
65291037db265ecdd914a26e056cf69207b4f50924ehkuang    case TX_32X32:
6535ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      for (i = 0; i < num_4x4_w; i += 8)
6545ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        t_above[i] = !!*(const uint64_t *)&above[i];
6555ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      for (i = 0; i < num_4x4_h; i += 8)
6565ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        t_left[i] = !!*(const uint64_t *)&left[i];
65791037db265ecdd914a26e056cf69207b4f50924ehkuang      break;
65891037db265ecdd914a26e056cf69207b4f50924ehkuang    default:
6595ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      assert(!"Invalid transform size.");
66091037db265ecdd914a26e056cf69207b4f50924ehkuang  }
6615ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang}
6625ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
6635ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangstatic void init_rdcost_stack(MACROBLOCK *x, TX_SIZE tx_size,
6645ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                              const int num_4x4_w, const int num_4x4_h,
6655ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                              const int64_t ref_rdcost,
6665ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                              struct rdcost_block_args *arg) {
6675ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  vpx_memset(arg, 0, sizeof(struct rdcost_block_args));
6685ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  arg->x = x;
6695ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  arg->tx_size = tx_size;
6705ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  arg->bw = num_4x4_w;
6715ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  arg->bh = num_4x4_h;
6725ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  arg->best_rd = ref_rdcost;
6735ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang}
6745ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
6755ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangstatic void txfm_rd_in_plane(MACROBLOCK *x,
6765ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                             struct rdcost_block_args *rd_stack,
6775ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                             int *rate, int64_t *distortion,
6785ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                             int *skippable, int64_t *sse,
6795ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                             int64_t ref_best_rd, int plane,
6805ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                             BLOCK_SIZE bsize, TX_SIZE tx_size) {
6815ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MACROBLOCKD *const xd = &x->e_mbd;
6825ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  struct macroblockd_plane *const pd = &xd->plane[plane];
6835ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const BLOCK_SIZE bs = get_plane_block_size(bsize, pd);
6845ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const int num_4x4_w = num_4x4_blocks_wide_lookup[bs];
6855ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const int num_4x4_h = num_4x4_blocks_high_lookup[bs];
68691037db265ecdd914a26e056cf69207b4f50924ehkuang
6875ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  init_rdcost_stack(x, tx_size, num_4x4_w, num_4x4_h,
6885ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                    ref_best_rd, rd_stack);
6895ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (plane == 0)
6905ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    xd->mi_8x8[0]->mbmi.tx_size = tx_size;
6915ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
6925ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  vp9_get_entropy_contexts(tx_size, rd_stack->t_above, rd_stack->t_left,
6935ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                           pd->above_context, pd->left_context,
6945ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                           num_4x4_w, num_4x4_h);
6955ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
6965ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  get_scan(xd, tx_size, pd->plane_type, 0, &rd_stack->scan, &rd_stack->nb);
6975ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
6985ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  foreach_transformed_block_in_plane(xd, bsize, plane,
6995ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                     block_yrd_txfm, rd_stack);
7005ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (rd_stack->skip) {
7015ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    *rate       = INT_MAX;
7025ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    *distortion = INT64_MAX;
7035ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    *sse        = INT64_MAX;
7045ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    *skippable  = 0;
7055ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  } else {
7065ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    *distortion = rd_stack->this_dist;
7075ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    *rate       = rd_stack->this_rate;
7085ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    *sse        = rd_stack->this_sse;
7095ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    *skippable  = vp9_is_skippable_in_plane(xd, bsize, plane);
7105ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
71191037db265ecdd914a26e056cf69207b4f50924ehkuang}
71291037db265ecdd914a26e056cf69207b4f50924ehkuang
71391037db265ecdd914a26e056cf69207b4f50924ehkuangstatic void choose_largest_txfm_size(VP9_COMP *cpi, MACROBLOCK *x,
71491037db265ecdd914a26e056cf69207b4f50924ehkuang                                     int *rate, int64_t *distortion,
71591037db265ecdd914a26e056cf69207b4f50924ehkuang                                     int *skip, int64_t *sse,
71691037db265ecdd914a26e056cf69207b4f50924ehkuang                                     int64_t ref_best_rd,
7171184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                     BLOCK_SIZE bs) {
7185ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const TX_SIZE max_tx_size = max_txsize_lookup[bs];
71991037db265ecdd914a26e056cf69207b4f50924ehkuang  VP9_COMMON *const cm = &cpi->common;
7205ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const TX_SIZE largest_tx_size = tx_mode_to_biggest_tx_size[cm->tx_mode];
72191037db265ecdd914a26e056cf69207b4f50924ehkuang  MACROBLOCKD *const xd = &x->e_mbd;
7225ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi;
7235ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
7245ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  mbmi->tx_size = MIN(max_tx_size, largest_tx_size);
7255ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
7265ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  txfm_rd_in_plane(x, &cpi->rdcost_stack, rate, distortion, skip,
7271184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                   &sse[mbmi->tx_size], ref_best_rd, 0, bs,
7281184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                   mbmi->tx_size);
7295ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  cpi->tx_stepdown_count[0]++;
730ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
731ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
732ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void choose_txfm_size_from_rd(VP9_COMP *cpi, MACROBLOCK *x,
733ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                     int (*r)[2], int *rate,
73491037db265ecdd914a26e056cf69207b4f50924ehkuang                                     int64_t *d, int64_t *distortion,
735ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                     int *s, int *skip,
736f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                                     int64_t tx_cache[TX_MODES],
7371184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                     BLOCK_SIZE bs) {
7381184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const TX_SIZE max_tx_size = max_txsize_lookup[bs];
739ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  VP9_COMMON *const cm = &cpi->common;
740ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD *const xd = &x->e_mbd;
7415ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi;
74291037db265ecdd914a26e056cf69207b4f50924ehkuang  vp9_prob skip_prob = vp9_get_pred_prob_mbskip(cm, xd);
743f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  int64_t rd[TX_SIZES][2];
744ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int n, m;
745ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int s0, s1;
746ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
7479b35249446b07f40ac5fcc3205f2c048616efacchkuang  const vp9_prob *tx_probs = get_tx_probs2(max_tx_size, xd, &cm->fc.tx_probs);
748ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
749f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  for (n = TX_4X4; n <= max_tx_size; n++) {
750ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    r[n][1] = r[n][0];
75191037db265ecdd914a26e056cf69207b4f50924ehkuang    if (r[n][0] == INT_MAX)
75291037db265ecdd914a26e056cf69207b4f50924ehkuang      continue;
753f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    for (m = 0; m <= n - (n == max_tx_size); m++) {
754ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (m == n)
755ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        r[n][1] += vp9_cost_zero(tx_probs[m]);
756ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      else
757ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        r[n][1] += vp9_cost_one(tx_probs[m]);
758ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
759ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
760ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
761ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  assert(skip_prob > 0);
762ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  s0 = vp9_cost_bit(skip_prob, 0);
763ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  s1 = vp9_cost_bit(skip_prob, 1);
764ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
765f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  for (n = TX_4X4; n <= max_tx_size; n++) {
76691037db265ecdd914a26e056cf69207b4f50924ehkuang    if (d[n] == INT64_MAX) {
76791037db265ecdd914a26e056cf69207b4f50924ehkuang      rd[n][0] = rd[n][1] = INT64_MAX;
76891037db265ecdd914a26e056cf69207b4f50924ehkuang      continue;
76991037db265ecdd914a26e056cf69207b4f50924ehkuang    }
770ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (s[n]) {
771ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      rd[n][0] = rd[n][1] = RDCOST(x->rdmult, x->rddiv, s1, d[n]);
772ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    } else {
773ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      rd[n][0] = RDCOST(x->rdmult, x->rddiv, r[n][0] + s0, d[n]);
774ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      rd[n][1] = RDCOST(x->rdmult, x->rddiv, r[n][1] + s0, d[n]);
775ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
776ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
777ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
778f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  if (max_tx_size == TX_32X32 &&
77991037db265ecdd914a26e056cf69207b4f50924ehkuang      (cm->tx_mode == ALLOW_32X32 ||
78091037db265ecdd914a26e056cf69207b4f50924ehkuang       (cm->tx_mode == TX_MODE_SELECT &&
781ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        rd[TX_32X32][1] < rd[TX_16X16][1] && rd[TX_32X32][1] < rd[TX_8X8][1] &&
782ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        rd[TX_32X32][1] < rd[TX_4X4][1]))) {
7831184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    mbmi->tx_size = TX_32X32;
784f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  } else if (max_tx_size >= TX_16X16 &&
78591037db265ecdd914a26e056cf69207b4f50924ehkuang             (cm->tx_mode == ALLOW_16X16 ||
78691037db265ecdd914a26e056cf69207b4f50924ehkuang              cm->tx_mode == ALLOW_32X32 ||
78791037db265ecdd914a26e056cf69207b4f50924ehkuang              (cm->tx_mode == TX_MODE_SELECT &&
788ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang               rd[TX_16X16][1] < rd[TX_8X8][1] &&
789ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang               rd[TX_16X16][1] < rd[TX_4X4][1]))) {
7901184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    mbmi->tx_size = TX_16X16;
79191037db265ecdd914a26e056cf69207b4f50924ehkuang  } else if (cm->tx_mode == ALLOW_8X8 ||
79291037db265ecdd914a26e056cf69207b4f50924ehkuang             cm->tx_mode == ALLOW_16X16 ||
79391037db265ecdd914a26e056cf69207b4f50924ehkuang             cm->tx_mode == ALLOW_32X32 ||
79491037db265ecdd914a26e056cf69207b4f50924ehkuang           (cm->tx_mode == TX_MODE_SELECT && rd[TX_8X8][1] < rd[TX_4X4][1])) {
7951184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    mbmi->tx_size = TX_8X8;
796ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  } else {
7971184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    mbmi->tx_size = TX_4X4;
798ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
799ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
8001184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  *distortion = d[mbmi->tx_size];
8011184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  *rate       = r[mbmi->tx_size][cm->tx_mode == TX_MODE_SELECT];
8021184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  *skip       = s[mbmi->tx_size];
803ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
804f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  tx_cache[ONLY_4X4] = rd[TX_4X4][0];
805f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  tx_cache[ALLOW_8X8] = rd[TX_8X8][0];
806f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  tx_cache[ALLOW_16X16] = rd[MIN(max_tx_size, TX_16X16)][0];
807f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  tx_cache[ALLOW_32X32] = rd[MIN(max_tx_size, TX_32X32)][0];
808f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  if (max_tx_size == TX_32X32 &&
809ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      rd[TX_32X32][1] < rd[TX_16X16][1] && rd[TX_32X32][1] < rd[TX_8X8][1] &&
810ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      rd[TX_32X32][1] < rd[TX_4X4][1])
811f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    tx_cache[TX_MODE_SELECT] = rd[TX_32X32][1];
812f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  else if (max_tx_size >= TX_16X16 &&
813ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang           rd[TX_16X16][1] < rd[TX_8X8][1] && rd[TX_16X16][1] < rd[TX_4X4][1])
814f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    tx_cache[TX_MODE_SELECT] = rd[TX_16X16][1];
815ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  else
816f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    tx_cache[TX_MODE_SELECT] = rd[TX_4X4][1] < rd[TX_8X8][1] ?
817ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                 rd[TX_4X4][1] : rd[TX_8X8][1];
818ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
819f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  if (max_tx_size == TX_32X32 &&
82091037db265ecdd914a26e056cf69207b4f50924ehkuang      rd[TX_32X32][1] < rd[TX_16X16][1] &&
82191037db265ecdd914a26e056cf69207b4f50924ehkuang      rd[TX_32X32][1] < rd[TX_8X8][1] &&
82291037db265ecdd914a26e056cf69207b4f50924ehkuang      rd[TX_32X32][1] < rd[TX_4X4][1]) {
8235ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    cpi->tx_stepdown_count[0]++;
824f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  } else if (max_tx_size >= TX_16X16 &&
82591037db265ecdd914a26e056cf69207b4f50924ehkuang             rd[TX_16X16][1] < rd[TX_8X8][1] &&
82691037db265ecdd914a26e056cf69207b4f50924ehkuang             rd[TX_16X16][1] < rd[TX_4X4][1]) {
8275ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    cpi->tx_stepdown_count[max_tx_size - TX_16X16]++;
82891037db265ecdd914a26e056cf69207b4f50924ehkuang  } else if (rd[TX_8X8][1] < rd[TX_4X4][1]) {
8295ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    cpi->tx_stepdown_count[max_tx_size - TX_8X8]++;
83091037db265ecdd914a26e056cf69207b4f50924ehkuang  } else {
8315ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    cpi->tx_stepdown_count[max_tx_size - TX_4X4]++;
832ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
833ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
834ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
83591037db265ecdd914a26e056cf69207b4f50924ehkuangstatic void choose_txfm_size_from_modelrd(VP9_COMP *cpi, MACROBLOCK *x,
83691037db265ecdd914a26e056cf69207b4f50924ehkuang                                          int (*r)[2], int *rate,
83791037db265ecdd914a26e056cf69207b4f50924ehkuang                                          int64_t *d, int64_t *distortion,
83891037db265ecdd914a26e056cf69207b4f50924ehkuang                                          int *s, int *skip, int64_t *sse,
83991037db265ecdd914a26e056cf69207b4f50924ehkuang                                          int64_t ref_best_rd,
8401184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                          BLOCK_SIZE bs) {
8415ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const TX_SIZE max_tx_size = max_txsize_lookup[bs];
84291037db265ecdd914a26e056cf69207b4f50924ehkuang  VP9_COMMON *const cm = &cpi->common;
84391037db265ecdd914a26e056cf69207b4f50924ehkuang  MACROBLOCKD *const xd = &x->e_mbd;
8445ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi;
84591037db265ecdd914a26e056cf69207b4f50924ehkuang  vp9_prob skip_prob = vp9_get_pred_prob_mbskip(cm, xd);
846f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  int64_t rd[TX_SIZES][2];
84791037db265ecdd914a26e056cf69207b4f50924ehkuang  int n, m;
84891037db265ecdd914a26e056cf69207b4f50924ehkuang  int s0, s1;
849f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  double scale_rd[TX_SIZES] = {1.73, 1.44, 1.20, 1.00};
850f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  // double scale_r[TX_SIZES] = {2.82, 2.00, 1.41, 1.00};
851ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
8529b35249446b07f40ac5fcc3205f2c048616efacchkuang  const vp9_prob *tx_probs = get_tx_probs2(max_tx_size, xd, &cm->fc.tx_probs);
853ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
85491037db265ecdd914a26e056cf69207b4f50924ehkuang  // for (n = TX_4X4; n <= max_txfm_size; n++)
85591037db265ecdd914a26e056cf69207b4f50924ehkuang  //   r[n][0] = (r[n][0] * scale_r[n]);
856ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
8575ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  for (n = TX_4X4; n <= max_tx_size; n++) {
85891037db265ecdd914a26e056cf69207b4f50924ehkuang    r[n][1] = r[n][0];
8595ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    for (m = 0; m <= n - (n == max_tx_size); m++) {
86091037db265ecdd914a26e056cf69207b4f50924ehkuang      if (m == n)
86191037db265ecdd914a26e056cf69207b4f50924ehkuang        r[n][1] += vp9_cost_zero(tx_probs[m]);
86291037db265ecdd914a26e056cf69207b4f50924ehkuang      else
86391037db265ecdd914a26e056cf69207b4f50924ehkuang        r[n][1] += vp9_cost_one(tx_probs[m]);
86491037db265ecdd914a26e056cf69207b4f50924ehkuang    }
86591037db265ecdd914a26e056cf69207b4f50924ehkuang  }
866ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
86791037db265ecdd914a26e056cf69207b4f50924ehkuang  assert(skip_prob > 0);
86891037db265ecdd914a26e056cf69207b4f50924ehkuang  s0 = vp9_cost_bit(skip_prob, 0);
86991037db265ecdd914a26e056cf69207b4f50924ehkuang  s1 = vp9_cost_bit(skip_prob, 1);
870ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
8715ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  for (n = TX_4X4; n <= max_tx_size; n++) {
87291037db265ecdd914a26e056cf69207b4f50924ehkuang    if (s[n]) {
87391037db265ecdd914a26e056cf69207b4f50924ehkuang      rd[n][0] = rd[n][1] = RDCOST(x->rdmult, x->rddiv, s1, d[n]);
87491037db265ecdd914a26e056cf69207b4f50924ehkuang    } else {
87591037db265ecdd914a26e056cf69207b4f50924ehkuang      rd[n][0] = RDCOST(x->rdmult, x->rddiv, r[n][0] + s0, d[n]);
87691037db265ecdd914a26e056cf69207b4f50924ehkuang      rd[n][1] = RDCOST(x->rdmult, x->rddiv, r[n][1] + s0, d[n]);
87791037db265ecdd914a26e056cf69207b4f50924ehkuang    }
87891037db265ecdd914a26e056cf69207b4f50924ehkuang  }
8795ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  for (n = TX_4X4; n <= max_tx_size; n++) {
8805ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    rd[n][0] = (int64_t)(scale_rd[n] * rd[n][0]);
8815ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    rd[n][1] = (int64_t)(scale_rd[n] * rd[n][1]);
882ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
883ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
8845ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (max_tx_size == TX_32X32 &&
88591037db265ecdd914a26e056cf69207b4f50924ehkuang      (cm->tx_mode == ALLOW_32X32 ||
88691037db265ecdd914a26e056cf69207b4f50924ehkuang       (cm->tx_mode == TX_MODE_SELECT &&
88791037db265ecdd914a26e056cf69207b4f50924ehkuang        rd[TX_32X32][1] <= rd[TX_16X16][1] &&
88891037db265ecdd914a26e056cf69207b4f50924ehkuang        rd[TX_32X32][1] <= rd[TX_8X8][1] &&
88991037db265ecdd914a26e056cf69207b4f50924ehkuang        rd[TX_32X32][1] <= rd[TX_4X4][1]))) {
8901184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    mbmi->tx_size = TX_32X32;
8915ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  } else if (max_tx_size >= TX_16X16 &&
89291037db265ecdd914a26e056cf69207b4f50924ehkuang             (cm->tx_mode == ALLOW_16X16 ||
89391037db265ecdd914a26e056cf69207b4f50924ehkuang              cm->tx_mode == ALLOW_32X32 ||
89491037db265ecdd914a26e056cf69207b4f50924ehkuang              (cm->tx_mode == TX_MODE_SELECT &&
89591037db265ecdd914a26e056cf69207b4f50924ehkuang               rd[TX_16X16][1] <= rd[TX_8X8][1] &&
89691037db265ecdd914a26e056cf69207b4f50924ehkuang               rd[TX_16X16][1] <= rd[TX_4X4][1]))) {
8971184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    mbmi->tx_size = TX_16X16;
89891037db265ecdd914a26e056cf69207b4f50924ehkuang  } else if (cm->tx_mode == ALLOW_8X8 ||
89991037db265ecdd914a26e056cf69207b4f50924ehkuang             cm->tx_mode == ALLOW_16X16 ||
90091037db265ecdd914a26e056cf69207b4f50924ehkuang             cm->tx_mode == ALLOW_32X32 ||
90191037db265ecdd914a26e056cf69207b4f50924ehkuang           (cm->tx_mode == TX_MODE_SELECT &&
90291037db265ecdd914a26e056cf69207b4f50924ehkuang            rd[TX_8X8][1] <= rd[TX_4X4][1])) {
9031184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    mbmi->tx_size = TX_8X8;
90491037db265ecdd914a26e056cf69207b4f50924ehkuang  } else {
9051184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    mbmi->tx_size = TX_4X4;
90691037db265ecdd914a26e056cf69207b4f50924ehkuang  }
907ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
9081184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  // Actually encode using the chosen mode if a model was used, but do not
9091184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  // update the r, d costs
9105ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  txfm_rd_in_plane(x, &cpi->rdcost_stack, rate, distortion, skip,
9115ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                   &sse[mbmi->tx_size], ref_best_rd, 0, bs, mbmi->tx_size);
912ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
9135ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (max_tx_size == TX_32X32 &&
91491037db265ecdd914a26e056cf69207b4f50924ehkuang      rd[TX_32X32][1] <= rd[TX_16X16][1] &&
91591037db265ecdd914a26e056cf69207b4f50924ehkuang      rd[TX_32X32][1] <= rd[TX_8X8][1] &&
91691037db265ecdd914a26e056cf69207b4f50924ehkuang      rd[TX_32X32][1] <= rd[TX_4X4][1]) {
9175ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    cpi->tx_stepdown_count[0]++;
9185ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  } else if (max_tx_size >= TX_16X16 &&
91991037db265ecdd914a26e056cf69207b4f50924ehkuang             rd[TX_16X16][1] <= rd[TX_8X8][1] &&
92091037db265ecdd914a26e056cf69207b4f50924ehkuang             rd[TX_16X16][1] <= rd[TX_4X4][1]) {
9215ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    cpi->tx_stepdown_count[max_tx_size - TX_16X16]++;
92291037db265ecdd914a26e056cf69207b4f50924ehkuang  } else if (rd[TX_8X8][1] <= rd[TX_4X4][1]) {
9235ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    cpi->tx_stepdown_count[max_tx_size - TX_8X8]++;
92491037db265ecdd914a26e056cf69207b4f50924ehkuang  } else {
9255ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    cpi->tx_stepdown_count[max_tx_size - TX_4X4]++;
92691037db265ecdd914a26e056cf69207b4f50924ehkuang  }
927ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
928ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
929ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void super_block_yrd(VP9_COMP *cpi,
93091037db265ecdd914a26e056cf69207b4f50924ehkuang                            MACROBLOCK *x, int *rate, int64_t *distortion,
9311184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                            int *skip, int64_t *psse, BLOCK_SIZE bs,
932f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                            int64_t txfm_cache[TX_MODES],
93391037db265ecdd914a26e056cf69207b4f50924ehkuang                            int64_t ref_best_rd) {
934f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  int r[TX_SIZES][2], s[TX_SIZES];
935f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  int64_t d[TX_SIZES], sse[TX_SIZES];
936ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD *xd = &x->e_mbd;
9375ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi;
9385ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  struct rdcost_block_args *rdcost_stack = &cpi->rdcost_stack;
9395ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const int b_inter_mode = is_inter_block(mbmi);
940ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
941ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  assert(bs == mbmi->sb_type);
9425ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (b_inter_mode)
943ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vp9_subtract_sby(x, bs);
944ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
94591037db265ecdd914a26e056cf69207b4f50924ehkuang  if (cpi->sf.tx_size_search_method == USE_LARGESTALL ||
94691037db265ecdd914a26e056cf69207b4f50924ehkuang      (cpi->sf.tx_size_search_method != USE_FULL_RD &&
9475ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang       !b_inter_mode)) {
948f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    vpx_memset(txfm_cache, 0, TX_MODES * sizeof(int64_t));
94991037db265ecdd914a26e056cf69207b4f50924ehkuang    choose_largest_txfm_size(cpi, x, rate, distortion, skip, sse,
95091037db265ecdd914a26e056cf69207b4f50924ehkuang                             ref_best_rd, bs);
95191037db265ecdd914a26e056cf69207b4f50924ehkuang    if (psse)
9521184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      *psse = sse[mbmi->tx_size];
95391037db265ecdd914a26e056cf69207b4f50924ehkuang    return;
95491037db265ecdd914a26e056cf69207b4f50924ehkuang  }
95591037db265ecdd914a26e056cf69207b4f50924ehkuang
95691037db265ecdd914a26e056cf69207b4f50924ehkuang  if (cpi->sf.tx_size_search_method == USE_LARGESTINTRA_MODELINTER &&
9575ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      b_inter_mode) {
9581184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    if (bs >= BLOCK_32X32)
9591184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      model_rd_for_sb_y_tx(cpi, bs, TX_32X32, x, xd,
9601184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                           &r[TX_32X32][0], &d[TX_32X32], &s[TX_32X32]);
9611184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    if (bs >= BLOCK_16X16)
9621184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      model_rd_for_sb_y_tx(cpi, bs, TX_16X16, x, xd,
9631184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                           &r[TX_16X16][0], &d[TX_16X16], &s[TX_16X16]);
964f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
9651184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    model_rd_for_sb_y_tx(cpi, bs, TX_8X8, x, xd,
9661184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                         &r[TX_8X8][0], &d[TX_8X8], &s[TX_8X8]);
9671184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
9681184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    model_rd_for_sb_y_tx(cpi, bs, TX_4X4, x, xd,
9691184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                         &r[TX_4X4][0], &d[TX_4X4], &s[TX_4X4]);
970f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
97191037db265ecdd914a26e056cf69207b4f50924ehkuang    choose_txfm_size_from_modelrd(cpi, x, r, rate, d, distortion, s,
9721184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                  skip, sse, ref_best_rd, bs);
97391037db265ecdd914a26e056cf69207b4f50924ehkuang  } else {
974f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    if (bs >= BLOCK_32X32)
9755ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      txfm_rd_in_plane(x, rdcost_stack, &r[TX_32X32][0], &d[TX_32X32],
9765ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                       &s[TX_32X32], &sse[TX_32X32],
9775ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                       ref_best_rd, 0, bs, TX_32X32);
978f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    if (bs >= BLOCK_16X16)
9795ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      txfm_rd_in_plane(x, rdcost_stack, &r[TX_16X16][0], &d[TX_16X16],
9805ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                       &s[TX_16X16], &sse[TX_16X16],
9815ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                       ref_best_rd, 0, bs, TX_16X16);
9825ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    txfm_rd_in_plane(x, rdcost_stack, &r[TX_8X8][0], &d[TX_8X8], &s[TX_8X8],
9831184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                     &sse[TX_8X8], ref_best_rd, 0, bs, TX_8X8);
9845ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    txfm_rd_in_plane(x, rdcost_stack, &r[TX_4X4][0], &d[TX_4X4], &s[TX_4X4],
9851184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                     &sse[TX_4X4], ref_best_rd, 0, bs, TX_4X4);
98691037db265ecdd914a26e056cf69207b4f50924ehkuang    choose_txfm_size_from_rd(cpi, x, r, rate, d, distortion, s,
98791037db265ecdd914a26e056cf69207b4f50924ehkuang                             skip, txfm_cache, bs);
988ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
98991037db265ecdd914a26e056cf69207b4f50924ehkuang  if (psse)
9901184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    *psse = sse[mbmi->tx_size];
99191037db265ecdd914a26e056cf69207b4f50924ehkuang}
99291037db265ecdd914a26e056cf69207b4f50924ehkuang
99391037db265ecdd914a26e056cf69207b4f50924ehkuangstatic int conditional_skipintra(MB_PREDICTION_MODE mode,
99491037db265ecdd914a26e056cf69207b4f50924ehkuang                                 MB_PREDICTION_MODE best_intra_mode) {
99591037db265ecdd914a26e056cf69207b4f50924ehkuang  if (mode == D117_PRED &&
99691037db265ecdd914a26e056cf69207b4f50924ehkuang      best_intra_mode != V_PRED &&
99791037db265ecdd914a26e056cf69207b4f50924ehkuang      best_intra_mode != D135_PRED)
99891037db265ecdd914a26e056cf69207b4f50924ehkuang    return 1;
99991037db265ecdd914a26e056cf69207b4f50924ehkuang  if (mode == D63_PRED &&
100091037db265ecdd914a26e056cf69207b4f50924ehkuang      best_intra_mode != V_PRED &&
100191037db265ecdd914a26e056cf69207b4f50924ehkuang      best_intra_mode != D45_PRED)
100291037db265ecdd914a26e056cf69207b4f50924ehkuang    return 1;
10031184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  if (mode == D207_PRED &&
100491037db265ecdd914a26e056cf69207b4f50924ehkuang      best_intra_mode != H_PRED &&
100591037db265ecdd914a26e056cf69207b4f50924ehkuang      best_intra_mode != D45_PRED)
100691037db265ecdd914a26e056cf69207b4f50924ehkuang    return 1;
100791037db265ecdd914a26e056cf69207b4f50924ehkuang  if (mode == D153_PRED &&
100891037db265ecdd914a26e056cf69207b4f50924ehkuang      best_intra_mode != H_PRED &&
100991037db265ecdd914a26e056cf69207b4f50924ehkuang      best_intra_mode != D135_PRED)
101091037db265ecdd914a26e056cf69207b4f50924ehkuang    return 1;
101191037db265ecdd914a26e056cf69207b4f50924ehkuang  return 0;
1012ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
1013ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1014ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, int ib,
1015ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                     MB_PREDICTION_MODE *best_mode,
1016ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                     int *bmode_costs,
1017ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                     ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l,
1018ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                     int *bestrate, int *bestratey,
101991037db265ecdd914a26e056cf69207b4f50924ehkuang                                     int64_t *bestdistortion,
10201184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                     BLOCK_SIZE bsize, int64_t rd_thresh) {
1021ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MB_PREDICTION_MODE mode;
1022ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD *xd = &x->e_mbd;
1023f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  int64_t best_rd = rd_thresh;
1024ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int rate = 0;
102591037db265ecdd914a26e056cf69207b4f50924ehkuang  int64_t distortion;
102691037db265ecdd914a26e056cf69207b4f50924ehkuang  struct macroblock_plane *p = &x->plane[0];
102791037db265ecdd914a26e056cf69207b4f50924ehkuang  struct macroblockd_plane *pd = &xd->plane[0];
102891037db265ecdd914a26e056cf69207b4f50924ehkuang  const int src_stride = p->src.stride;
102991037db265ecdd914a26e056cf69207b4f50924ehkuang  const int dst_stride = pd->dst.stride;
10301184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  uint8_t *src_init = raster_block_offset_uint8(BLOCK_8X8, ib,
1031f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                                                p->src.buf, src_stride);
10321184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  uint8_t *dst_init = raster_block_offset_uint8(BLOCK_8X8, ib,
1033f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                                                pd->dst.buf, dst_stride);
1034ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int16_t *src_diff, *coeff;
1035ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1036ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  ENTROPY_CONTEXT ta[2], tempa[2];
1037ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  ENTROPY_CONTEXT tl[2], templ[2];
10385ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
1039f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
1040f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
10415ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int idx, idy;
1042f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  uint8_t best_dst[8 * 8];
1043ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1044ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  assert(ib < 4);
1045ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1046ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vpx_memcpy(ta, a, sizeof(ta));
1047ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vpx_memcpy(tl, l, sizeof(tl));
10485ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  xd->mi_8x8[0]->mbmi.tx_size = TX_4X4;
1049ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1050ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
1051ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int64_t this_rd;
1052ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int ratey = 0;
10531184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
10545ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (!(cpi->sf.intra_y_mode_mask[TX_4X4] & (1 << mode)))
10551184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      continue;
10561184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
105791037db265ecdd914a26e056cf69207b4f50924ehkuang    // Only do the oblique modes if the best so far is
105891037db265ecdd914a26e056cf69207b4f50924ehkuang    // one of the neighboring directional modes
105991037db265ecdd914a26e056cf69207b4f50924ehkuang    if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
106091037db265ecdd914a26e056cf69207b4f50924ehkuang      if (conditional_skipintra(mode, *best_mode))
106191037db265ecdd914a26e056cf69207b4f50924ehkuang          continue;
106291037db265ecdd914a26e056cf69207b4f50924ehkuang    }
1063ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1064ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    rate = bmode_costs[mode];
1065ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    distortion = 0;
1066ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1067ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vpx_memcpy(tempa, ta, sizeof(ta));
1068ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vpx_memcpy(templ, tl, sizeof(tl));
1069ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
107091037db265ecdd914a26e056cf69207b4f50924ehkuang    for (idy = 0; idy < num_4x4_blocks_high; ++idy) {
107191037db265ecdd914a26e056cf69207b4f50924ehkuang      for (idx = 0; idx < num_4x4_blocks_wide; ++idx) {
107291037db265ecdd914a26e056cf69207b4f50924ehkuang        int64_t ssz;
107391037db265ecdd914a26e056cf69207b4f50924ehkuang        const int16_t *scan;
10745ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        const int16_t *nb;
1075f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        uint8_t *src = src_init + idx * 4 + idy * 4 * src_stride;
1076f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        uint8_t *dst = dst_init + idx * 4 + idy * 4 * dst_stride;
10775ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        const int block = ib + idy * 2 + idx;
10785ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        TX_TYPE tx_type;
10795ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        xd->mi_8x8[0]->bmi[block].as_mode = mode;
10801184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        src_diff = raster_block_offset_int16(BLOCK_8X8, block, p->src_diff);
10811184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        coeff = BLOCK_OFFSET(x->plane[0].coeff, block);
1082f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        vp9_predict_intra_block(xd, block, 1,
108391037db265ecdd914a26e056cf69207b4f50924ehkuang                                TX_4X4, mode,
108491037db265ecdd914a26e056cf69207b4f50924ehkuang                                x->skip_encode ? src : dst,
108591037db265ecdd914a26e056cf69207b4f50924ehkuang                                x->skip_encode ? src_stride : dst_stride,
108691037db265ecdd914a26e056cf69207b4f50924ehkuang                                dst, dst_stride);
1087ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        vp9_subtract_block(4, 4, src_diff, 8,
1088ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                           src, src_stride,
108991037db265ecdd914a26e056cf69207b4f50924ehkuang                           dst, dst_stride);
1090ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
109191037db265ecdd914a26e056cf69207b4f50924ehkuang        tx_type = get_tx_type_4x4(PLANE_TYPE_Y_WITH_DC, xd, block);
10925ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        get_scan_nb_4x4(tx_type, &scan, &nb);
10935ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
10945ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if (tx_type != DCT_DCT)
1095ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          vp9_short_fht4x4(src_diff, coeff, 8, tx_type);
10965ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        else
10975ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          x->fwd_txm4x4(src_diff, coeff, 8);
10985ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
10995ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        vp9_regular_quantize_b_4x4(x, 4, block, scan, get_iscan_4x4(tx_type));
1100ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
11011184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        ratey += cost_coeffs(x, 0, block,
11025ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                             tempa + idx, templ + idy, TX_4X4, scan, nb);
11031184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        distortion += vp9_block_error(coeff, BLOCK_OFFSET(pd->dqcoeff, block),
110491037db265ecdd914a26e056cf69207b4f50924ehkuang                                      16, &ssz) >> 2;
1105f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
1106f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          goto next;
110791037db265ecdd914a26e056cf69207b4f50924ehkuang
110891037db265ecdd914a26e056cf69207b4f50924ehkuang        if (tx_type != DCT_DCT)
11095ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          vp9_iht4x4_16_add(BLOCK_OFFSET(pd->dqcoeff, block),
111091037db265ecdd914a26e056cf69207b4f50924ehkuang                               dst, pd->dst.stride, tx_type);
1111ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        else
11125ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          xd->itxm_add(BLOCK_OFFSET(pd->dqcoeff, block), dst, pd->dst.stride,
11135ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                       16);
1114ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
1115ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
1116ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1117ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    rate += ratey;
1118ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
1119ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1120ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (this_rd < best_rd) {
1121ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      *bestrate = rate;
1122ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      *bestratey = ratey;
1123ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      *bestdistortion = distortion;
1124ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      best_rd = this_rd;
1125ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      *best_mode = mode;
1126ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      vpx_memcpy(a, tempa, sizeof(tempa));
1127ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      vpx_memcpy(l, templ, sizeof(templ));
1128f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy)
1129f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        vpx_memcpy(best_dst + idy * 8, dst_init + idy * dst_stride,
1130f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                   num_4x4_blocks_wide * 4);
1131ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
1132f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  next:
1133f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    {}
1134ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
1135ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1136f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  if (best_rd >= rd_thresh || x->skip_encode)
113791037db265ecdd914a26e056cf69207b4f50924ehkuang    return best_rd;
113891037db265ecdd914a26e056cf69207b4f50924ehkuang
1139f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy)
1140f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    vpx_memcpy(dst_init + idy * dst_stride, best_dst + idy * 8,
1141f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang               num_4x4_blocks_wide * 4);
1142ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1143ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return best_rd;
1144ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
1145ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1146f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuangstatic int64_t rd_pick_intra_sub_8x8_y_mode(VP9_COMP * const cpi,
1147f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                                            MACROBLOCK * const mb,
1148f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                                            int * const rate,
1149f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                                            int * const rate_y,
1150f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                                            int64_t * const distortion,
1151f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                                            int64_t best_rd) {
1152ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int i, j;
1153ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD *const xd = &mb->e_mbd;
11545ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MODE_INFO *const mic = xd->mi_8x8[0];
11551184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const MODE_INFO *above_mi = xd->mi_8x8[-xd->mode_info_stride];
11565ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const MODE_INFO *left_mi = xd->left_available ? xd->mi_8x8[-1] : NULL;
11575ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const BLOCK_SIZE bsize = xd->mi_8x8[0]->mbmi.sb_type;
1158f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
1159f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
1160ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int idx, idy;
1161ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int cost = 0;
1162f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  int64_t total_distortion = 0;
1163ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int tot_rate_y = 0;
1164ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int64_t total_rd = 0;
1165ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  ENTROPY_CONTEXT t_above[4], t_left[4];
1166ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int *bmode_costs;
1167ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1168ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vpx_memcpy(t_above, xd->plane[0].above_context, sizeof(t_above));
1169ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vpx_memcpy(t_left, xd->plane[0].left_context, sizeof(t_left));
1170ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1171ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  bmode_costs = mb->mbmode_cost;
1172ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1173f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  // Pick modes for each sub-block (of size 4x4, 4x8, or 8x4) in an 8x8 block.
117491037db265ecdd914a26e056cf69207b4f50924ehkuang  for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
117591037db265ecdd914a26e056cf69207b4f50924ehkuang    for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
11761184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      MB_PREDICTION_MODE best_mode = DC_PRED;
11771184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      int r = INT_MAX, ry = INT_MAX;
11781184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      int64_t d = INT64_MAX, this_rd = INT64_MAX;
1179ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      i = idy * 2 + idx;
118091037db265ecdd914a26e056cf69207b4f50924ehkuang      if (cpi->common.frame_type == KEY_FRAME) {
11811184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        const MB_PREDICTION_MODE A = above_block_mode(mic, above_mi, i);
11825ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        const MB_PREDICTION_MODE L = left_block_mode(mic, left_mi, i);
1183ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1184ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        bmode_costs  = mb->y_mode_costs[A][L];
1185ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
1186ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1187f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      this_rd = rd_pick_intra4x4block(cpi, mb, i, &best_mode, bmode_costs,
11881184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                      t_above + idx, t_left + idy, &r, &ry, &d,
11891184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                      bsize, best_rd - total_rd);
1190f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      if (this_rd >= best_rd - total_rd)
1191f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        return INT64_MAX;
1192f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
1193f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      total_rd += this_rd;
1194ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      cost += r;
1195f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      total_distortion += d;
1196ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      tot_rate_y += ry;
1197ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
119891037db265ecdd914a26e056cf69207b4f50924ehkuang      mic->bmi[i].as_mode = best_mode;
119991037db265ecdd914a26e056cf69207b4f50924ehkuang      for (j = 1; j < num_4x4_blocks_high; ++j)
120091037db265ecdd914a26e056cf69207b4f50924ehkuang        mic->bmi[i + j * 2].as_mode = best_mode;
120191037db265ecdd914a26e056cf69207b4f50924ehkuang      for (j = 1; j < num_4x4_blocks_wide; ++j)
120291037db265ecdd914a26e056cf69207b4f50924ehkuang        mic->bmi[i + j].as_mode = best_mode;
1203ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1204ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (total_rd >= best_rd)
120591037db265ecdd914a26e056cf69207b4f50924ehkuang        return INT64_MAX;
1206ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
1207ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
1208ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1209f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  *rate = cost;
1210ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  *rate_y = tot_rate_y;
1211f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  *distortion = total_distortion;
12121184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  mic->mbmi.mode = mic->bmi[3].as_mode;
1213ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1214f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  return RDCOST(mb->rdmult, mb->rddiv, cost, total_distortion);
1215ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
1216ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1217ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic int64_t rd_pick_intra_sby_mode(VP9_COMP *cpi, MACROBLOCK *x,
1218ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                      int *rate, int *rate_tokenonly,
121991037db265ecdd914a26e056cf69207b4f50924ehkuang                                      int64_t *distortion, int *skippable,
12201184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                      BLOCK_SIZE bsize,
1221f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                                      int64_t tx_cache[TX_MODES],
122291037db265ecdd914a26e056cf69207b4f50924ehkuang                                      int64_t best_rd) {
1223ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MB_PREDICTION_MODE mode;
12241184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  MB_PREDICTION_MODE mode_selected = DC_PRED;
1225ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD *const xd = &x->e_mbd;
12265ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MODE_INFO *const mic = xd->mi_8x8[0];
122791037db265ecdd914a26e056cf69207b4f50924ehkuang  int this_rate, this_rate_tokenonly, s;
122891037db265ecdd914a26e056cf69207b4f50924ehkuang  int64_t this_distortion, this_rd;
12291184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  TX_SIZE best_tx = TX_4X4;
1230ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int i;
1231ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int *bmode_costs = x->mbmode_cost;
1232ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1233f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  if (cpi->sf.tx_size_search_method == USE_FULL_RD)
1234f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    for (i = 0; i < TX_MODES; i++)
1235f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      tx_cache[i] = INT64_MAX;
1236ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1237f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  /* Y Search for intra prediction mode */
1238ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (mode = DC_PRED; mode <= TM_PRED; mode++) {
1239f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    int64_t local_tx_cache[TX_MODES];
12401184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    MODE_INFO *above_mi = xd->mi_8x8[-xd->mode_info_stride];
12415ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    MODE_INFO *left_mi = xd->left_available ? xd->mi_8x8[-1] : NULL;
12421184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
12435ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (!(cpi->sf.intra_y_mode_mask[max_txsize_lookup[bsize]] & (1 << mode)))
12441184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      continue;
1245ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1246ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (cpi->common.frame_type == KEY_FRAME) {
12471184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      const MB_PREDICTION_MODE A = above_block_mode(mic, above_mi, 0);
12485ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      const MB_PREDICTION_MODE L = left_block_mode(mic, left_mi, 0);
1249ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1250ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      bmode_costs = x->y_mode_costs[A][L];
1251ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
12521184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    mic->mbmi.mode = mode;
1253ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
125491037db265ecdd914a26e056cf69207b4f50924ehkuang    super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion, &s, NULL,
1255f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                    bsize, local_tx_cache, best_rd);
125691037db265ecdd914a26e056cf69207b4f50924ehkuang
125791037db265ecdd914a26e056cf69207b4f50924ehkuang    if (this_rate_tokenonly == INT_MAX)
125891037db265ecdd914a26e056cf69207b4f50924ehkuang      continue;
1259ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1260ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    this_rate = this_rate_tokenonly + bmode_costs[mode];
1261ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
1262ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1263ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (this_rd < best_rd) {
1264ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      mode_selected   = mode;
1265ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      best_rd         = this_rd;
12661184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      best_tx         = mic->mbmi.tx_size;
1267ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      *rate           = this_rate;
1268ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      *rate_tokenonly = this_rate_tokenonly;
1269ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      *distortion     = this_distortion;
1270ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      *skippable      = s;
1271ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
1272ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
127391037db265ecdd914a26e056cf69207b4f50924ehkuang    if (cpi->sf.tx_size_search_method == USE_FULL_RD && this_rd < INT64_MAX) {
12741184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      for (i = 0; i < TX_MODES && local_tx_cache[i] < INT64_MAX; i++) {
1275f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        const int64_t adj_rd = this_rd + local_tx_cache[i] -
1276f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang            local_tx_cache[cpi->common.tx_mode];
1277f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        if (adj_rd < tx_cache[i]) {
1278f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          tx_cache[i] = adj_rd;
127991037db265ecdd914a26e056cf69207b4f50924ehkuang        }
1280ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
1281ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
1282ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
1283ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
12841184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  mic->mbmi.mode = mode_selected;
12851184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  mic->mbmi.tx_size = best_tx;
1286ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1287ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return best_rd;
1288ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
1289ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
12905ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangstatic void super_block_uvrd(VP9_COMP *const cpi, MACROBLOCK *x,
129191037db265ecdd914a26e056cf69207b4f50924ehkuang                             int *rate, int64_t *distortion, int *skippable,
12921184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                             int64_t *sse, BLOCK_SIZE bsize,
12931184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                             int64_t ref_best_rd) {
1294ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD *const xd = &x->e_mbd;
12955ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi;
129691037db265ecdd914a26e056cf69207b4f50924ehkuang  TX_SIZE uv_txfm_size = get_uv_tx_size(mbmi);
12971184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int plane;
12981184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int pnrate = 0, pnskip = 1;
12991184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int64_t pndist = 0, pnsse = 0;
1300ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
13011184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  if (ref_best_rd < 0)
13021184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    goto term;
13031184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
13041184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  if (is_inter_block(mbmi))
1305ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vp9_subtract_sbuv(x, bsize);
1306ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
13071184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  *rate = 0;
13081184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  *distortion = 0;
13091184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  *sse = 0;
13101184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  *skippable = 1;
13111184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
13121184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
13135ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    txfm_rd_in_plane(x, &cpi->rdcost_stack, &pnrate, &pndist, &pnskip, &pnsse,
13141184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                     ref_best_rd, plane, bsize, uv_txfm_size);
13151184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    if (pnrate == INT_MAX)
13161184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      goto term;
13171184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    *rate += pnrate;
13181184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    *distortion += pndist;
13191184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    *sse += pnsse;
13201184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    *skippable &= pnskip;
13211184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  }
13221184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  return;
13231184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
13241184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  term:
13251184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  *rate = INT_MAX;
13261184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  *distortion = INT64_MAX;
13271184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  *sse = INT64_MAX;
13281184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  *skippable = 0;
13291184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  return;
1330ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
1331ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1332ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic int64_t rd_pick_intra_sbuv_mode(VP9_COMP *cpi, MACROBLOCK *x,
13339b35249446b07f40ac5fcc3205f2c048616efacchkuang                                       PICK_MODE_CONTEXT *ctx,
1334ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                       int *rate, int *rate_tokenonly,
133591037db265ecdd914a26e056cf69207b4f50924ehkuang                                       int64_t *distortion, int *skippable,
13361184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                       BLOCK_SIZE bsize) {
1337ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MB_PREDICTION_MODE mode;
13381184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  MB_PREDICTION_MODE mode_selected = DC_PRED;
1339ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int64_t best_rd = INT64_MAX, this_rd;
134091037db265ecdd914a26e056cf69207b4f50924ehkuang  int this_rate_tokenonly, this_rate, s;
13411184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int64_t this_distortion, this_sse;
13421184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
13431184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  // int mode_mask = (bsize <= BLOCK_8X8)
13441184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  //                ? ALL_INTRA_MODES : cpi->sf.intra_uv_mode_mask;
13451184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
13465ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  for (mode = DC_PRED; mode <= TM_PRED; mode ++) {
13471184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    // if (!(mode_mask & (1 << mode)))
13485ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (!(cpi->sf.intra_uv_mode_mask[max_uv_txsize_lookup[bsize]]
13495ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          & (1 << mode)))
13501184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      continue;
1351ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
13521184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    x->e_mbd.mi_8x8[0]->mbmi.uv_mode = mode;
135391037db265ecdd914a26e056cf69207b4f50924ehkuang
13545ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    super_block_uvrd(cpi, x, &this_rate_tokenonly,
13551184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                     &this_distortion, &s, &this_sse, bsize, best_rd);
13561184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    if (this_rate_tokenonly == INT_MAX)
13571184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      continue;
1358ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    this_rate = this_rate_tokenonly +
135991037db265ecdd914a26e056cf69207b4f50924ehkuang                x->intra_uv_mode_cost[cpi->common.frame_type][mode];
1360ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
1361ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1362ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (this_rd < best_rd) {
1363ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      mode_selected   = mode;
1364ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      best_rd         = this_rd;
1365ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      *rate           = this_rate;
1366ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      *rate_tokenonly = this_rate_tokenonly;
1367ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      *distortion     = this_distortion;
1368ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      *skippable      = s;
13699b35249446b07f40ac5fcc3205f2c048616efacchkuang      if (!x->select_txfm_size) {
13709b35249446b07f40ac5fcc3205f2c048616efacchkuang        int i;
13719b35249446b07f40ac5fcc3205f2c048616efacchkuang        struct macroblock_plane *const p = x->plane;
13729b35249446b07f40ac5fcc3205f2c048616efacchkuang        struct macroblockd_plane *const pd = x->e_mbd.plane;
13739b35249446b07f40ac5fcc3205f2c048616efacchkuang        for (i = 1; i < MAX_MB_PLANE; ++i) {
13749b35249446b07f40ac5fcc3205f2c048616efacchkuang          p[i].coeff    = ctx->coeff_pbuf[i][2];
13759b35249446b07f40ac5fcc3205f2c048616efacchkuang          pd[i].qcoeff  = ctx->qcoeff_pbuf[i][2];
13769b35249446b07f40ac5fcc3205f2c048616efacchkuang          pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][2];
13779b35249446b07f40ac5fcc3205f2c048616efacchkuang          pd[i].eobs    = ctx->eobs_pbuf[i][2];
13789b35249446b07f40ac5fcc3205f2c048616efacchkuang
13799b35249446b07f40ac5fcc3205f2c048616efacchkuang          ctx->coeff_pbuf[i][2]   = ctx->coeff_pbuf[i][0];
13809b35249446b07f40ac5fcc3205f2c048616efacchkuang          ctx->qcoeff_pbuf[i][2]  = ctx->qcoeff_pbuf[i][0];
13819b35249446b07f40ac5fcc3205f2c048616efacchkuang          ctx->dqcoeff_pbuf[i][2] = ctx->dqcoeff_pbuf[i][0];
13829b35249446b07f40ac5fcc3205f2c048616efacchkuang          ctx->eobs_pbuf[i][2]    = ctx->eobs_pbuf[i][0];
13839b35249446b07f40ac5fcc3205f2c048616efacchkuang
13849b35249446b07f40ac5fcc3205f2c048616efacchkuang          ctx->coeff_pbuf[i][0]   = p[i].coeff;
13859b35249446b07f40ac5fcc3205f2c048616efacchkuang          ctx->qcoeff_pbuf[i][0]  = pd[i].qcoeff;
13869b35249446b07f40ac5fcc3205f2c048616efacchkuang          ctx->dqcoeff_pbuf[i][0] = pd[i].dqcoeff;
13879b35249446b07f40ac5fcc3205f2c048616efacchkuang          ctx->eobs_pbuf[i][0]    = pd[i].eobs;
13889b35249446b07f40ac5fcc3205f2c048616efacchkuang        }
13899b35249446b07f40ac5fcc3205f2c048616efacchkuang      }
1390ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
1391ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
1392ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
13931184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  x->e_mbd.mi_8x8[0]->mbmi.uv_mode = mode_selected;
1394ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1395ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return best_rd;
1396ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
1397ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
139891037db265ecdd914a26e056cf69207b4f50924ehkuangstatic int64_t rd_sbuv_dcpred(VP9_COMP *cpi, MACROBLOCK *x,
139991037db265ecdd914a26e056cf69207b4f50924ehkuang                              int *rate, int *rate_tokenonly,
140091037db265ecdd914a26e056cf69207b4f50924ehkuang                              int64_t *distortion, int *skippable,
14011184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                              BLOCK_SIZE bsize) {
140291037db265ecdd914a26e056cf69207b4f50924ehkuang  int64_t this_rd;
14031184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int64_t this_sse;
140491037db265ecdd914a26e056cf69207b4f50924ehkuang
14051184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  x->e_mbd.mi_8x8[0]->mbmi.uv_mode = DC_PRED;
14065ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  super_block_uvrd(cpi, x, rate_tokenonly, distortion,
14075ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                   skippable, &this_sse, bsize, INT64_MAX);
140891037db265ecdd914a26e056cf69207b4f50924ehkuang  *rate = *rate_tokenonly +
140991037db265ecdd914a26e056cf69207b4f50924ehkuang          x->intra_uv_mode_cost[cpi->common.frame_type][DC_PRED];
141091037db265ecdd914a26e056cf69207b4f50924ehkuang  this_rd = RDCOST(x->rdmult, x->rddiv, *rate, *distortion);
141191037db265ecdd914a26e056cf69207b4f50924ehkuang
141291037db265ecdd914a26e056cf69207b4f50924ehkuang  return this_rd;
141391037db265ecdd914a26e056cf69207b4f50924ehkuang}
141491037db265ecdd914a26e056cf69207b4f50924ehkuang
14159b35249446b07f40ac5fcc3205f2c048616efacchkuangstatic void choose_intra_uv_mode(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
14169b35249446b07f40ac5fcc3205f2c048616efacchkuang                                 BLOCK_SIZE bsize, int *rate_uv,
14179b35249446b07f40ac5fcc3205f2c048616efacchkuang                                 int *rate_uv_tokenonly,
141891037db265ecdd914a26e056cf69207b4f50924ehkuang                                 int64_t *dist_uv, int *skip_uv,
141991037db265ecdd914a26e056cf69207b4f50924ehkuang                                 MB_PREDICTION_MODE *mode_uv) {
142091037db265ecdd914a26e056cf69207b4f50924ehkuang  MACROBLOCK *const x = &cpi->mb;
142191037db265ecdd914a26e056cf69207b4f50924ehkuang
142291037db265ecdd914a26e056cf69207b4f50924ehkuang  // Use an estimated rd for uv_intra based on DC_PRED if the
142391037db265ecdd914a26e056cf69207b4f50924ehkuang  // appropriate speed flag is set.
142491037db265ecdd914a26e056cf69207b4f50924ehkuang  if (cpi->sf.use_uv_intra_rd_estimate) {
142591037db265ecdd914a26e056cf69207b4f50924ehkuang    rd_sbuv_dcpred(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
14261184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                   bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize);
142791037db265ecdd914a26e056cf69207b4f50924ehkuang  // Else do a proper rd search for each possible transform size that may
142891037db265ecdd914a26e056cf69207b4f50924ehkuang  // be considered in the main rd loop.
142991037db265ecdd914a26e056cf69207b4f50924ehkuang  } else {
14309b35249446b07f40ac5fcc3205f2c048616efacchkuang    rd_pick_intra_sbuv_mode(cpi, x, ctx,
143191037db265ecdd914a26e056cf69207b4f50924ehkuang                            rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
14321184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                            bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize);
143391037db265ecdd914a26e056cf69207b4f50924ehkuang  }
14341184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  *mode_uv = x->e_mbd.mi_8x8[0]->mbmi.uv_mode;
143591037db265ecdd914a26e056cf69207b4f50924ehkuang}
143691037db265ecdd914a26e056cf69207b4f50924ehkuang
143791037db265ecdd914a26e056cf69207b4f50924ehkuangstatic int cost_mv_ref(VP9_COMP *cpi, MB_PREDICTION_MODE mode,
143891037db265ecdd914a26e056cf69207b4f50924ehkuang                       int mode_context) {
143991037db265ecdd914a26e056cf69207b4f50924ehkuang  MACROBLOCK *const x = &cpi->mb;
144091037db265ecdd914a26e056cf69207b4f50924ehkuang  MACROBLOCKD *const xd = &x->e_mbd;
14415ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const int segment_id = xd->mi_8x8[0]->mbmi.segment_id;
144291037db265ecdd914a26e056cf69207b4f50924ehkuang
144391037db265ecdd914a26e056cf69207b4f50924ehkuang  // Don't account for mode here if segment skip is enabled.
14441184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  if (!vp9_segfeature_active(&cpi->common.seg, segment_id, SEG_LVL_SKIP)) {
144591037db265ecdd914a26e056cf69207b4f50924ehkuang    assert(is_inter_mode(mode));
14469b35249446b07f40ac5fcc3205f2c048616efacchkuang    return x->inter_mode_cost[mode_context][INTER_OFFSET(mode)];
144791037db265ecdd914a26e056cf69207b4f50924ehkuang  } else {
1448ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    return 0;
144991037db265ecdd914a26e056cf69207b4f50924ehkuang  }
1450ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
1451ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1452ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid vp9_set_mbmode_and_mvs(MACROBLOCK *x, MB_PREDICTION_MODE mb, int_mv *mv) {
14531184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  x->e_mbd.mi_8x8[0]->mbmi.mode = mb;
14541184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  x->e_mbd.mi_8x8[0]->mbmi.mv[0].as_int = mv->as_int;
1455ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
1456ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1457ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
14581184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                BLOCK_SIZE bsize,
1459ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                int_mv *frame_mv,
1460ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                int mi_row, int mi_col,
1461ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                int_mv single_newmv[MAX_REF_FRAMES],
1462ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                int *rate_mv);
1463ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1464ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic int labels2mode(MACROBLOCK *x, int i,
1465ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                       MB_PREDICTION_MODE this_mode,
1466ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                       int_mv *this_mv, int_mv *this_second_mv,
1467ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                       int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES],
1468ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                       int_mv seg_mvs[MAX_REF_FRAMES],
1469ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                       int_mv *best_ref_mv,
1470ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                       int_mv *second_best_ref_mv,
1471ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                       int *mvjcost, int *mvcost[2], VP9_COMP *cpi) {
1472ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD *const xd = &x->e_mbd;
14735ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MODE_INFO *const mic = xd->mi_8x8[0];
14741184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  MB_MODE_INFO *mbmi = &mic->mbmi;
1475ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int cost = 0, thismvcost = 0;
1476ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int idx, idy;
1477f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type];
1478f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type];
14795ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const int has_second_rf = has_second_ref(mbmi);
1480ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1481ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* We have to be careful retrieving previously-encoded motion vectors.
1482ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang   Ones from this macroblock have to be pulled from the BLOCKD array
1483ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang   as they have not yet made it to the bmi array in our MB_MODE_INFO. */
1484ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MB_PREDICTION_MODE m;
1485ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1486ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // the only time we should do costing for new motion vector or mode
1487ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // is when we are on a new label  (jbb May 08, 2007)
1488ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  switch (m = this_mode) {
1489ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    case NEWMV:
1490ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      this_mv->as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
14915ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      thismvcost  = vp9_mv_bit_cost(&this_mv->as_mv, &best_ref_mv->as_mv,
14925ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                    mvjcost, mvcost, MV_COST_WEIGHT_SUB);
14935ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (has_second_rf) {
1494ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        this_second_mv->as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
14955ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        thismvcost += vp9_mv_bit_cost(&this_second_mv->as_mv,
14965ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                      &second_best_ref_mv->as_mv,
14975ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                      mvjcost, mvcost, MV_COST_WEIGHT_SUB);
1498ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
1499ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      break;
1500ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    case NEARESTMV:
1501ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      this_mv->as_int = frame_mv[NEARESTMV][mbmi->ref_frame[0]].as_int;
15025ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (has_second_rf)
1503ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        this_second_mv->as_int =
1504ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            frame_mv[NEARESTMV][mbmi->ref_frame[1]].as_int;
1505ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      break;
1506ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    case NEARMV:
1507ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      this_mv->as_int = frame_mv[NEARMV][mbmi->ref_frame[0]].as_int;
15085ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (has_second_rf)
1509ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        this_second_mv->as_int =
1510ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            frame_mv[NEARMV][mbmi->ref_frame[1]].as_int;
1511ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      break;
1512ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    case ZEROMV:
1513ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      this_mv->as_int = 0;
15145ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (has_second_rf)
1515ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        this_second_mv->as_int = 0;
1516ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      break;
1517ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    default:
1518ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      break;
1519ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
1520ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
152191037db265ecdd914a26e056cf69207b4f50924ehkuang  cost = cost_mv_ref(cpi, this_mode,
15221184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                     mbmi->mode_context[mbmi->ref_frame[0]]);
1523ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1524ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  mic->bmi[i].as_mv[0].as_int = this_mv->as_int;
15255ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (has_second_rf)
1526ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    mic->bmi[i].as_mv[1].as_int = this_second_mv->as_int;
1527ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
15285ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  mic->bmi[i].as_mode = m;
15295ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
153091037db265ecdd914a26e056cf69207b4f50924ehkuang  for (idy = 0; idy < num_4x4_blocks_high; ++idy)
153191037db265ecdd914a26e056cf69207b4f50924ehkuang    for (idx = 0; idx < num_4x4_blocks_wide; ++idx)
1532ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      vpx_memcpy(&mic->bmi[i + idy * 2 + idx],
1533ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                 &mic->bmi[i], sizeof(mic->bmi[i]));
1534ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1535ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  cost += thismvcost;
1536ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return cost;
1537ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
1538ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
153991037db265ecdd914a26e056cf69207b4f50924ehkuangstatic int64_t encode_inter_mb_segment(VP9_COMP *cpi,
1540ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                       MACROBLOCK *x,
154191037db265ecdd914a26e056cf69207b4f50924ehkuang                                       int64_t best_yrd,
1542ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                       int i,
1543ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                       int *labelyrate,
154491037db265ecdd914a26e056cf69207b4f50924ehkuang                                       int64_t *distortion, int64_t *sse,
1545ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                       ENTROPY_CONTEXT *ta,
1546ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                       ENTROPY_CONTEXT *tl) {
1547ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int k;
1548ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD *xd = &x->e_mbd;
1549f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  struct macroblockd_plane *const pd = &xd->plane[0];
15505ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  struct macroblock_plane *const p = &x->plane[0];
15515ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MODE_INFO *const mi = xd->mi_8x8[0];
15521184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const BLOCK_SIZE bsize = mi->mbmi.sb_type;
1553f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  const int width = plane_block_width(bsize, pd);
1554f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  const int height = plane_block_height(bsize, pd);
1555ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int idx, idy;
15565ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
15575ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  uint8_t *const src = raster_block_offset_uint8(BLOCK_8X8, i,
15585ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                                 p->src.buf, p->src.stride);
15595ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  uint8_t *const dst = raster_block_offset_uint8(BLOCK_8X8, i,
15601184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                                 pd->dst.buf, pd->dst.stride);
156191037db265ecdd914a26e056cf69207b4f50924ehkuang  int64_t thisdistortion = 0, thissse = 0;
15625ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int thisrate = 0, ref;
15635ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const int is_compound = has_second_ref(&mi->mbmi);
15645ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  for (ref = 0; ref < 1 + is_compound; ++ref) {
15651184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    const uint8_t *pre = raster_block_offset_uint8(BLOCK_8X8, i,
15661184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                     pd->pre[ref].buf, 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,
15701184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                              &xd->scale_factor[ref],
15711184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                              width, height, ref, &xd->subpix, MV_PRECISION_Q3);
1572ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
1573ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
15745ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  vp9_subtract_block(height, width,
15755ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                     raster_block_offset_int16(BLOCK_8X8, i, p->src_diff), 8,
15765ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                     src, p->src.stride,
1577f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                     dst, pd->dst.stride);
1578ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1579ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  k = i;
158091037db265ecdd914a26e056cf69207b4f50924ehkuang  for (idy = 0; idy < height / 4; ++idy) {
158191037db265ecdd914a26e056cf69207b4f50924ehkuang    for (idx = 0; idx < width / 4; ++idx) {
158291037db265ecdd914a26e056cf69207b4f50924ehkuang      int64_t ssz, rd, rd1, rd2;
15835ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      int16_t* coeff;
158491037db265ecdd914a26e056cf69207b4f50924ehkuang
1585ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      k += (idy * 2 + idx);
15865ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      coeff = BLOCK_OFFSET(p->coeff, k);
15875ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      x->fwd_txm4x4(raster_block_offset_int16(BLOCK_8X8, k, p->src_diff),
15885ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                    coeff, 8);
15895ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      vp9_regular_quantize_b_4x4(x, 4, k, get_scan_4x4(DCT_DCT),
15905ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                 get_iscan_4x4(DCT_DCT));
15911184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      thisdistortion += vp9_block_error(coeff, BLOCK_OFFSET(pd->dqcoeff, k),
1592f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                                        16, &ssz);
159391037db265ecdd914a26e056cf69207b4f50924ehkuang      thissse += ssz;
15941184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      thisrate += cost_coeffs(x, 0, k,
1595ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                              ta + (k & 1),
159691037db265ecdd914a26e056cf69207b4f50924ehkuang                              tl + (k >> 1), TX_4X4,
159791037db265ecdd914a26e056cf69207b4f50924ehkuang                              vp9_default_scan_4x4,
159891037db265ecdd914a26e056cf69207b4f50924ehkuang                              vp9_default_scan_4x4_neighbors);
159991037db265ecdd914a26e056cf69207b4f50924ehkuang      rd1 = RDCOST(x->rdmult, x->rddiv, thisrate, thisdistortion >> 2);
160091037db265ecdd914a26e056cf69207b4f50924ehkuang      rd2 = RDCOST(x->rdmult, x->rddiv, 0, thissse >> 2);
160191037db265ecdd914a26e056cf69207b4f50924ehkuang      rd = MIN(rd1, rd2);
160291037db265ecdd914a26e056cf69207b4f50924ehkuang      if (rd >= best_yrd)
160391037db265ecdd914a26e056cf69207b4f50924ehkuang        return INT64_MAX;
1604ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
1605ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
16065ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
160791037db265ecdd914a26e056cf69207b4f50924ehkuang  *distortion = thisdistortion >> 2;
160891037db265ecdd914a26e056cf69207b4f50924ehkuang  *labelyrate = thisrate;
160991037db265ecdd914a26e056cf69207b4f50924ehkuang  *sse = thissse >> 2;
1610ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1611ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return RDCOST(x->rdmult, x->rddiv, *labelyrate, *distortion);
1612ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
1613ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1614ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangtypedef struct {
161591037db265ecdd914a26e056cf69207b4f50924ehkuang  int eobs;
161691037db265ecdd914a26e056cf69207b4f50924ehkuang  int brate;
161791037db265ecdd914a26e056cf69207b4f50924ehkuang  int byrate;
161891037db265ecdd914a26e056cf69207b4f50924ehkuang  int64_t bdist;
161991037db265ecdd914a26e056cf69207b4f50924ehkuang  int64_t bsse;
162091037db265ecdd914a26e056cf69207b4f50924ehkuang  int64_t brdcost;
162191037db265ecdd914a26e056cf69207b4f50924ehkuang  int_mv mvs[2];
162291037db265ecdd914a26e056cf69207b4f50924ehkuang  ENTROPY_CONTEXT ta[2];
162391037db265ecdd914a26e056cf69207b4f50924ehkuang  ENTROPY_CONTEXT tl[2];
162491037db265ecdd914a26e056cf69207b4f50924ehkuang} SEG_RDSTAT;
162591037db265ecdd914a26e056cf69207b4f50924ehkuang
162691037db265ecdd914a26e056cf69207b4f50924ehkuangtypedef struct {
1627ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int_mv *ref_mv, *second_ref_mv;
1628ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int_mv mvp;
1629ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1630ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int64_t segment_rd;
1631ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int r;
163291037db265ecdd914a26e056cf69207b4f50924ehkuang  int64_t d;
163391037db265ecdd914a26e056cf69207b4f50924ehkuang  int64_t sse;
1634ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int segment_yrate;
1635ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MB_PREDICTION_MODE modes[4];
16361184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  SEG_RDSTAT rdstat[4][INTER_MODES];
1637ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int mvthresh;
1638ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} BEST_SEG_INFO;
1639ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1640ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic INLINE int mv_check_bounds(MACROBLOCK *x, int_mv *mv) {
1641ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int r = 0;
1642ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  r |= (mv->as_mv.row >> 3) < x->mv_row_min;
1643ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  r |= (mv->as_mv.row >> 3) > x->mv_row_max;
1644ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  r |= (mv->as_mv.col >> 3) < x->mv_col_min;
1645ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  r |= (mv->as_mv.col >> 3) > x->mv_col_max;
1646ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return r;
1647ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
1648ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1649ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic INLINE void mi_buf_shift(MACROBLOCK *x, int i) {
16501184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  MB_MODE_INFO *const mbmi = &x->e_mbd.mi_8x8[0]->mbmi;
16511184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  struct macroblock_plane *const p = &x->plane[0];
16521184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  struct macroblockd_plane *const pd = &x->e_mbd.plane[0];
16531184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
16541184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  p->src.buf = raster_block_offset_uint8(BLOCK_8X8, i, p->src.buf,
16551184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                         p->src.stride);
16561184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  assert(((intptr_t)pd->pre[0].buf & 0x7) == 0);
16571184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  pd->pre[0].buf = raster_block_offset_uint8(BLOCK_8X8, i, pd->pre[0].buf,
16581184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                             pd->pre[0].stride);
16595ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (has_second_ref(mbmi))
16601184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    pd->pre[1].buf = raster_block_offset_uint8(BLOCK_8X8, i, pd->pre[1].buf,
16611184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                               pd->pre[1].stride);
1662ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
1663ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1664ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic INLINE void mi_buf_restore(MACROBLOCK *x, struct buf_2d orig_src,
1665ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                  struct buf_2d orig_pre[2]) {
16661184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  MB_MODE_INFO *mbmi = &x->e_mbd.mi_8x8[0]->mbmi;
1667ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  x->plane[0].src = orig_src;
1668ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  x->e_mbd.plane[0].pre[0] = orig_pre[0];
16695ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (has_second_ref(mbmi))
1670ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    x->e_mbd.plane[0].pre[1] = orig_pre[1];
1671ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
1672ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1673ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
16745ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                    const TileInfo *const tile,
167591037db265ecdd914a26e056cf69207b4f50924ehkuang                                    BEST_SEG_INFO *bsi_buf, int filter_idx,
1676ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                    int_mv seg_mvs[4][MAX_REF_FRAMES],
1677ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                    int mi_row, int mi_col) {
16785ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int i, br = 0, idx, idy;
167991037db265ecdd914a26e056cf69207b4f50924ehkuang  int64_t bd = 0, block_sse = 0;
1680ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MB_PREDICTION_MODE this_mode;
16811184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  MODE_INFO *mi = x->e_mbd.mi_8x8[0];
168291037db265ecdd914a26e056cf69207b4f50924ehkuang  MB_MODE_INFO *const mbmi = &mi->mbmi;
16835ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  struct macroblockd_plane *const pd = &x->e_mbd.plane[0];
1684ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int label_count = 4;
168591037db265ecdd914a26e056cf69207b4f50924ehkuang  int64_t this_segment_rd = 0;
1686ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int label_mv_thresh;
1687ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int segmentyrate = 0;
16881184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const BLOCK_SIZE bsize = mbmi->sb_type;
1689f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
1690f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
1691ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vp9_variance_fn_ptr_t *v_fn_ptr;
169291037db265ecdd914a26e056cf69207b4f50924ehkuang  ENTROPY_CONTEXT t_above[2], t_left[2];
169391037db265ecdd914a26e056cf69207b4f50924ehkuang  BEST_SEG_INFO *bsi = bsi_buf + filter_idx;
169491037db265ecdd914a26e056cf69207b4f50924ehkuang  int mode_idx;
169591037db265ecdd914a26e056cf69207b4f50924ehkuang  int subpelmv = 1, have_ref = 0;
16965ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const int has_second_rf = has_second_ref(mbmi);
1697ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
16985ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  vpx_memcpy(t_above, pd->above_context, sizeof(t_above));
16995ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  vpx_memcpy(t_left, pd->left_context, sizeof(t_left));
1700ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
170191037db265ecdd914a26e056cf69207b4f50924ehkuang  v_fn_ptr = &cpi->fn_ptr[bsize];
1702ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1703ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // 64 makes this threshold really big effectively
1704ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // making it so that we very rarely check mvs on
1705ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // segments.   setting this to 1 would make mv thresh
1706ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // roughly equal to what it is for macroblocks
1707ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  label_mv_thresh = 1 * bsi->mvthresh / label_count;
1708ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1709ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Segmentation method overheads
171091037db265ecdd914a26e056cf69207b4f50924ehkuang  for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
171191037db265ecdd914a26e056cf69207b4f50924ehkuang    for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
1712ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // TODO(jingning,rbultje): rewrite the rate-distortion optimization
1713ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // loop for 4x4/4x8/8x4 block coding. to be replaced with new rd loop
1714ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      int_mv mode_mv[MB_MODE_COUNT], second_mode_mv[MB_MODE_COUNT];
1715ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
1716ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      MB_PREDICTION_MODE mode_selected = ZEROMV;
171791037db265ecdd914a26e056cf69207b4f50924ehkuang      int64_t best_rd = INT64_MAX;
1718ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      i = idy * 2 + idx;
1719ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1720ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      frame_mv[ZEROMV][mbmi->ref_frame[0]].as_int = 0;
17215ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      vp9_append_sub8x8_mvs_for_idx(&cpi->common, &x->e_mbd, tile,
1722ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                    &frame_mv[NEARESTMV][mbmi->ref_frame[0]],
1723ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                    &frame_mv[NEARMV][mbmi->ref_frame[0]],
1724f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                                    i, 0, mi_row, mi_col);
17255ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (has_second_rf) {
17265ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        frame_mv[ZEROMV][mbmi->ref_frame[1]].as_int = 0;
17275ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        vp9_append_sub8x8_mvs_for_idx(&cpi->common, &x->e_mbd, tile,
17285ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                      &frame_mv[NEARESTMV][mbmi->ref_frame[1]],
17295ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                      &frame_mv[NEARMV][mbmi->ref_frame[1]],
17305ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                      i, 1, mi_row, mi_col);
17315ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      }
1732ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // search for the best motion vector on this segment
1733ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode) {
1734ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        const struct buf_2d orig_src = x->plane[0].src;
1735ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        struct buf_2d orig_pre[2];
1736ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
17379b35249446b07f40ac5fcc3205f2c048616efacchkuang        mode_idx = INTER_OFFSET(this_mode);
173891037db265ecdd914a26e056cf69207b4f50924ehkuang        bsi->rdstat[i][mode_idx].brdcost = INT64_MAX;
173991037db265ecdd914a26e056cf69207b4f50924ehkuang
174091037db265ecdd914a26e056cf69207b4f50924ehkuang        // if we're near/nearest and mv == 0,0, compare to zeromv
174191037db265ecdd914a26e056cf69207b4f50924ehkuang        if ((this_mode == NEARMV || this_mode == NEARESTMV ||
174291037db265ecdd914a26e056cf69207b4f50924ehkuang             this_mode == ZEROMV) &&
174391037db265ecdd914a26e056cf69207b4f50924ehkuang            frame_mv[this_mode][mbmi->ref_frame[0]].as_int == 0 &&
17445ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            (!has_second_rf ||
174591037db265ecdd914a26e056cf69207b4f50924ehkuang             frame_mv[this_mode][mbmi->ref_frame[1]].as_int == 0)) {
17461184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          int rfc = mbmi->mode_context[mbmi->ref_frame[0]];
174791037db265ecdd914a26e056cf69207b4f50924ehkuang          int c1 = cost_mv_ref(cpi, NEARMV, rfc);
174891037db265ecdd914a26e056cf69207b4f50924ehkuang          int c2 = cost_mv_ref(cpi, NEARESTMV, rfc);
174991037db265ecdd914a26e056cf69207b4f50924ehkuang          int c3 = cost_mv_ref(cpi, ZEROMV, rfc);
175091037db265ecdd914a26e056cf69207b4f50924ehkuang
175191037db265ecdd914a26e056cf69207b4f50924ehkuang          if (this_mode == NEARMV) {
175291037db265ecdd914a26e056cf69207b4f50924ehkuang            if (c1 > c3)
175391037db265ecdd914a26e056cf69207b4f50924ehkuang              continue;
175491037db265ecdd914a26e056cf69207b4f50924ehkuang          } else if (this_mode == NEARESTMV) {
175591037db265ecdd914a26e056cf69207b4f50924ehkuang            if (c2 > c3)
175691037db265ecdd914a26e056cf69207b4f50924ehkuang              continue;
175791037db265ecdd914a26e056cf69207b4f50924ehkuang          } else {
175891037db265ecdd914a26e056cf69207b4f50924ehkuang            assert(this_mode == ZEROMV);
17595ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            if (!has_second_rf) {
176091037db265ecdd914a26e056cf69207b4f50924ehkuang              if ((c3 >= c2 &&
176191037db265ecdd914a26e056cf69207b4f50924ehkuang                   frame_mv[NEARESTMV][mbmi->ref_frame[0]].as_int == 0) ||
176291037db265ecdd914a26e056cf69207b4f50924ehkuang                  (c3 >= c1 &&
176391037db265ecdd914a26e056cf69207b4f50924ehkuang                   frame_mv[NEARMV][mbmi->ref_frame[0]].as_int == 0))
176491037db265ecdd914a26e056cf69207b4f50924ehkuang                continue;
176591037db265ecdd914a26e056cf69207b4f50924ehkuang            } else {
176691037db265ecdd914a26e056cf69207b4f50924ehkuang              if ((c3 >= c2 &&
176791037db265ecdd914a26e056cf69207b4f50924ehkuang                   frame_mv[NEARESTMV][mbmi->ref_frame[0]].as_int == 0 &&
176891037db265ecdd914a26e056cf69207b4f50924ehkuang                   frame_mv[NEARESTMV][mbmi->ref_frame[1]].as_int == 0) ||
176991037db265ecdd914a26e056cf69207b4f50924ehkuang                  (c3 >= c1 &&
177091037db265ecdd914a26e056cf69207b4f50924ehkuang                   frame_mv[NEARMV][mbmi->ref_frame[0]].as_int == 0 &&
177191037db265ecdd914a26e056cf69207b4f50924ehkuang                   frame_mv[NEARMV][mbmi->ref_frame[1]].as_int == 0))
177291037db265ecdd914a26e056cf69207b4f50924ehkuang                continue;
177391037db265ecdd914a26e056cf69207b4f50924ehkuang            }
177491037db265ecdd914a26e056cf69207b4f50924ehkuang          }
177591037db265ecdd914a26e056cf69207b4f50924ehkuang        }
177691037db265ecdd914a26e056cf69207b4f50924ehkuang
17775ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        vpx_memcpy(orig_pre, pd->pre, sizeof(orig_pre));
177891037db265ecdd914a26e056cf69207b4f50924ehkuang        vpx_memcpy(bsi->rdstat[i][mode_idx].ta, t_above,
177991037db265ecdd914a26e056cf69207b4f50924ehkuang                   sizeof(bsi->rdstat[i][mode_idx].ta));
178091037db265ecdd914a26e056cf69207b4f50924ehkuang        vpx_memcpy(bsi->rdstat[i][mode_idx].tl, t_left,
178191037db265ecdd914a26e056cf69207b4f50924ehkuang                   sizeof(bsi->rdstat[i][mode_idx].tl));
1782ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1783ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        // motion search for newmv (single predictor case only)
17845ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if (!has_second_rf && this_mode == NEWMV &&
178591037db265ecdd914a26e056cf69207b4f50924ehkuang            seg_mvs[i][mbmi->ref_frame[0]].as_int == INVALID_MV) {
1786ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          int step_param = 0;
1787ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          int further_steps;
1788ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          int thissme, bestsme = INT_MAX;
1789ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          int sadpb = x->sadperbit4;
1790ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          int_mv mvp_full;
17911184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          int max_mv;
1792ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1793ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          /* Is the best so far sufficiently good that we cant justify doing
1794ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang           * and new motion search. */
179591037db265ecdd914a26e056cf69207b4f50924ehkuang          if (best_rd < label_mv_thresh)
1796ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            break;
1797ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1798ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          if (cpi->compressor_speed) {
1799ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            // use previous block's result as next block's MV predictor.
1800ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            if (i > 0) {
18011184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              bsi->mvp.as_int = mi->bmi[i - 1].as_mv[0].as_int;
1802ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              if (i == 2)
18031184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                bsi->mvp.as_int = mi->bmi[i - 2].as_mv[0].as_int;
1804ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            }
1805ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          }
18061184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          if (i == 0)
18071184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            max_mv = x->max_mv_context[mbmi->ref_frame[0]];
18081184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          else
18091184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            max_mv = MAX(abs(bsi->mvp.as_mv.row), abs(bsi->mvp.as_mv.col)) >> 3;
18101184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
181191037db265ecdd914a26e056cf69207b4f50924ehkuang          if (cpi->sf.auto_mv_step_size && cpi->common.show_frame) {
181291037db265ecdd914a26e056cf69207b4f50924ehkuang            // Take wtd average of the step_params based on the last frame's
181391037db265ecdd914a26e056cf69207b4f50924ehkuang            // max mv magnitude and the best ref mvs of the current block for
181491037db265ecdd914a26e056cf69207b4f50924ehkuang            // the given reference.
18151184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            step_param = (vp9_init_search_range(cpi, max_mv) +
18161184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                          cpi->mv_step_param) >> 1;
181791037db265ecdd914a26e056cf69207b4f50924ehkuang          } else {
181891037db265ecdd914a26e056cf69207b4f50924ehkuang            step_param = cpi->mv_step_param;
181991037db265ecdd914a26e056cf69207b4f50924ehkuang          }
1820ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1821ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          mvp_full.as_mv.row = bsi->mvp.as_mv.row >> 3;
1822ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          mvp_full.as_mv.col = bsi->mvp.as_mv.col >> 3;
1823ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
18241184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          if (cpi->sf.adaptive_motion_search && cpi->common.show_frame) {
18251184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            mvp_full.as_mv.row = x->pred_mv[mbmi->ref_frame[0]].as_mv.row >> 3;
18261184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            mvp_full.as_mv.col = x->pred_mv[mbmi->ref_frame[0]].as_mv.col >> 3;
18271184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            step_param = MAX(step_param, 8);
18281184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          }
18291184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
18301184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param;
1831ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          // adjust src pointer for this block
1832ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          mi_buf_shift(x, i);
18331184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          if (cpi->sf.search_method == HEX) {
18345ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            bestsme = vp9_hex_search(x, &mvp_full.as_mv,
18351184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                     step_param,
18361184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                     sadpb, 1, v_fn_ptr, 1,
18375ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                     &bsi->ref_mv->as_mv,
18385ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                     &mode_mv[NEWMV].as_mv);
18391184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          } else if (cpi->sf.search_method == SQUARE) {
18405ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            bestsme = vp9_square_search(x, &mvp_full.as_mv,
18411184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                        step_param,
18421184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                        sadpb, 1, v_fn_ptr, 1,
18435ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                        &bsi->ref_mv->as_mv,
18445ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                        &mode_mv[NEWMV].as_mv);
18451184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          } else if (cpi->sf.search_method == BIGDIA) {
18465ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            bestsme = vp9_bigdia_search(x, &mvp_full.as_mv,
18471184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                        step_param,
18481184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                        sadpb, 1, v_fn_ptr, 1,
18495ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                        &bsi->ref_mv->as_mv,
18505ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                        &mode_mv[NEWMV].as_mv);
18511184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          } else {
18521184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            bestsme = vp9_full_pixel_diamond(cpi, x, &mvp_full, step_param,
18531184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                             sadpb, further_steps, 0, v_fn_ptr,
18541184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                             bsi->ref_mv, &mode_mv[NEWMV]);
18551184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          }
1856ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1857ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          // Should we do a full search (best quality only)
1858ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          if (cpi->compressor_speed == 0) {
1859ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            /* Check if mvp_full is within the range. */
1860f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang            clamp_mv(&mvp_full.as_mv, x->mv_col_min, x->mv_col_max,
1861ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                     x->mv_row_min, x->mv_row_max);
1862ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1863ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            thissme = cpi->full_search_sad(x, &mvp_full,
1864ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                           sadpb, 16, v_fn_ptr,
1865ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                           x->nmvjointcost, x->mvcost,
1866ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                           bsi->ref_mv, i);
1867ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1868ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            if (thissme < bestsme) {
1869ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              bestsme = thissme;
18701184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              mode_mv[NEWMV].as_int = mi->bmi[i].as_mv[0].as_int;
1871ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            } else {
1872ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              /* The full search result is actually worse so re-instate the
1873ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang               * previous best vector */
18741184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              mi->bmi[i].as_mv[0].as_int = mode_mv[NEWMV].as_int;
1875ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            }
1876ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          }
1877ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1878ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          if (bestsme < INT_MAX) {
1879ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            int distortion;
1880ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            unsigned int sse;
18815ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            cpi->find_fractional_mv_step(x,
18825ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                         &mode_mv[NEWMV].as_mv,
18835ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                         &bsi->ref_mv->as_mv,
18845ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                         cpi->common.allow_high_precision_mv,
18855ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                         x->errorperbit, v_fn_ptr,
18861184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                         0, cpi->sf.subpel_iters_per_step,
1887ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                         x->nmvjointcost, x->mvcost,
1888ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                         &distortion, &sse);
1889ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
18901184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            // save motion search result for use in compound prediction
1891ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            seg_mvs[i][mbmi->ref_frame[0]].as_int = mode_mv[NEWMV].as_int;
1892ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          }
1893ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
18941184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          if (cpi->sf.adaptive_motion_search)
18951184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            x->pred_mv[mbmi->ref_frame[0]].as_int = mode_mv[NEWMV].as_int;
18961184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
1897ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          // restore src pointers
1898ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          mi_buf_restore(x, orig_src, orig_pre);
189991037db265ecdd914a26e056cf69207b4f50924ehkuang        }
190091037db265ecdd914a26e056cf69207b4f50924ehkuang
19015ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if (has_second_rf) {
1902ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          if (seg_mvs[i][mbmi->ref_frame[1]].as_int == INVALID_MV ||
1903ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              seg_mvs[i][mbmi->ref_frame[0]].as_int == INVALID_MV)
1904ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            continue;
19055ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        }
1906ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
19075ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if (has_second_rf && this_mode == NEWMV &&
19085ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            mbmi->interp_filter == EIGHTTAP) {
1909ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          // adjust src pointers
1910ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          mi_buf_shift(x, i);
191191037db265ecdd914a26e056cf69207b4f50924ehkuang          if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
1912ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            int rate_mv;
1913ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            joint_motion_search(cpi, x, bsize, frame_mv[this_mode],
1914ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                mi_row, mi_col, seg_mvs[i],
1915ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                &rate_mv);
1916ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            seg_mvs[i][mbmi->ref_frame[0]].as_int =
1917ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
1918ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            seg_mvs[i][mbmi->ref_frame[1]].as_int =
1919ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
1920ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          }
1921ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          // restore src pointers
1922ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          mi_buf_restore(x, orig_src, orig_pre);
1923ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
1924ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
192591037db265ecdd914a26e056cf69207b4f50924ehkuang        bsi->rdstat[i][mode_idx].brate =
192691037db265ecdd914a26e056cf69207b4f50924ehkuang            labels2mode(x, i, this_mode, &mode_mv[this_mode],
192791037db265ecdd914a26e056cf69207b4f50924ehkuang                        &second_mode_mv[this_mode], frame_mv, seg_mvs[i],
192891037db265ecdd914a26e056cf69207b4f50924ehkuang                        bsi->ref_mv, bsi->second_ref_mv, x->nmvjointcost,
192991037db265ecdd914a26e056cf69207b4f50924ehkuang                        x->mvcost, cpi);
193091037db265ecdd914a26e056cf69207b4f50924ehkuang
19319b35249446b07f40ac5fcc3205f2c048616efacchkuang
193291037db265ecdd914a26e056cf69207b4f50924ehkuang        bsi->rdstat[i][mode_idx].mvs[0].as_int = mode_mv[this_mode].as_int;
193391037db265ecdd914a26e056cf69207b4f50924ehkuang        if (num_4x4_blocks_wide > 1)
193491037db265ecdd914a26e056cf69207b4f50924ehkuang          bsi->rdstat[i + 1][mode_idx].mvs[0].as_int =
193591037db265ecdd914a26e056cf69207b4f50924ehkuang              mode_mv[this_mode].as_int;
193691037db265ecdd914a26e056cf69207b4f50924ehkuang        if (num_4x4_blocks_high > 1)
193791037db265ecdd914a26e056cf69207b4f50924ehkuang          bsi->rdstat[i + 2][mode_idx].mvs[0].as_int =
193891037db265ecdd914a26e056cf69207b4f50924ehkuang              mode_mv[this_mode].as_int;
19395ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if (has_second_rf) {
194091037db265ecdd914a26e056cf69207b4f50924ehkuang          bsi->rdstat[i][mode_idx].mvs[1].as_int =
194191037db265ecdd914a26e056cf69207b4f50924ehkuang              second_mode_mv[this_mode].as_int;
194291037db265ecdd914a26e056cf69207b4f50924ehkuang          if (num_4x4_blocks_wide > 1)
194391037db265ecdd914a26e056cf69207b4f50924ehkuang            bsi->rdstat[i + 1][mode_idx].mvs[1].as_int =
194491037db265ecdd914a26e056cf69207b4f50924ehkuang                second_mode_mv[this_mode].as_int;
194591037db265ecdd914a26e056cf69207b4f50924ehkuang          if (num_4x4_blocks_high > 1)
194691037db265ecdd914a26e056cf69207b4f50924ehkuang            bsi->rdstat[i + 2][mode_idx].mvs[1].as_int =
194791037db265ecdd914a26e056cf69207b4f50924ehkuang                second_mode_mv[this_mode].as_int;
194891037db265ecdd914a26e056cf69207b4f50924ehkuang        }
1949ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1950ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        // Trap vectors that reach beyond the UMV borders
195191037db265ecdd914a26e056cf69207b4f50924ehkuang        if (mv_check_bounds(x, &mode_mv[this_mode]))
1952ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          continue;
19535ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if (has_second_rf &&
1954ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            mv_check_bounds(x, &second_mode_mv[this_mode]))
1955ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          continue;
1956ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
195791037db265ecdd914a26e056cf69207b4f50924ehkuang        if (filter_idx > 0) {
195891037db265ecdd914a26e056cf69207b4f50924ehkuang          BEST_SEG_INFO *ref_bsi = bsi_buf;
195991037db265ecdd914a26e056cf69207b4f50924ehkuang          subpelmv = (mode_mv[this_mode].as_mv.row & 0x0f) ||
196091037db265ecdd914a26e056cf69207b4f50924ehkuang                     (mode_mv[this_mode].as_mv.col & 0x0f);
196191037db265ecdd914a26e056cf69207b4f50924ehkuang          have_ref = mode_mv[this_mode].as_int ==
196291037db265ecdd914a26e056cf69207b4f50924ehkuang                     ref_bsi->rdstat[i][mode_idx].mvs[0].as_int;
19635ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          if (has_second_rf) {
196491037db265ecdd914a26e056cf69207b4f50924ehkuang            subpelmv |= (second_mode_mv[this_mode].as_mv.row & 0x0f) ||
196591037db265ecdd914a26e056cf69207b4f50924ehkuang                        (second_mode_mv[this_mode].as_mv.col & 0x0f);
196691037db265ecdd914a26e056cf69207b4f50924ehkuang            have_ref  &= second_mode_mv[this_mode].as_int ==
196791037db265ecdd914a26e056cf69207b4f50924ehkuang                         ref_bsi->rdstat[i][mode_idx].mvs[1].as_int;
196891037db265ecdd914a26e056cf69207b4f50924ehkuang          }
196991037db265ecdd914a26e056cf69207b4f50924ehkuang
197091037db265ecdd914a26e056cf69207b4f50924ehkuang          if (filter_idx > 1 && !subpelmv && !have_ref) {
197191037db265ecdd914a26e056cf69207b4f50924ehkuang            ref_bsi = bsi_buf + 1;
197291037db265ecdd914a26e056cf69207b4f50924ehkuang            have_ref = mode_mv[this_mode].as_int ==
197391037db265ecdd914a26e056cf69207b4f50924ehkuang                       ref_bsi->rdstat[i][mode_idx].mvs[0].as_int;
19745ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            if (has_second_rf) {
197591037db265ecdd914a26e056cf69207b4f50924ehkuang              have_ref  &= second_mode_mv[this_mode].as_int ==
197691037db265ecdd914a26e056cf69207b4f50924ehkuang                           ref_bsi->rdstat[i][mode_idx].mvs[1].as_int;
197791037db265ecdd914a26e056cf69207b4f50924ehkuang            }
197891037db265ecdd914a26e056cf69207b4f50924ehkuang          }
197991037db265ecdd914a26e056cf69207b4f50924ehkuang
198091037db265ecdd914a26e056cf69207b4f50924ehkuang          if (!subpelmv && have_ref &&
198191037db265ecdd914a26e056cf69207b4f50924ehkuang              ref_bsi->rdstat[i][mode_idx].brdcost < INT64_MAX) {
198291037db265ecdd914a26e056cf69207b4f50924ehkuang            vpx_memcpy(&bsi->rdstat[i][mode_idx], &ref_bsi->rdstat[i][mode_idx],
198391037db265ecdd914a26e056cf69207b4f50924ehkuang                       sizeof(SEG_RDSTAT));
19845ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            if (num_4x4_blocks_wide > 1)
19855ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang              bsi->rdstat[i + 1][mode_idx].eobs =
19865ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                  ref_bsi->rdstat[i + 1][mode_idx].eobs;
19875ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            if (num_4x4_blocks_high > 1)
19885ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang              bsi->rdstat[i + 2][mode_idx].eobs =
19895ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                  ref_bsi->rdstat[i + 2][mode_idx].eobs;
19905ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
199191037db265ecdd914a26e056cf69207b4f50924ehkuang            if (bsi->rdstat[i][mode_idx].brdcost < best_rd) {
199291037db265ecdd914a26e056cf69207b4f50924ehkuang              mode_selected = this_mode;
199391037db265ecdd914a26e056cf69207b4f50924ehkuang              best_rd = bsi->rdstat[i][mode_idx].brdcost;
199491037db265ecdd914a26e056cf69207b4f50924ehkuang            }
199591037db265ecdd914a26e056cf69207b4f50924ehkuang            continue;
199691037db265ecdd914a26e056cf69207b4f50924ehkuang          }
199791037db265ecdd914a26e056cf69207b4f50924ehkuang        }
199891037db265ecdd914a26e056cf69207b4f50924ehkuang
199991037db265ecdd914a26e056cf69207b4f50924ehkuang        bsi->rdstat[i][mode_idx].brdcost =
200091037db265ecdd914a26e056cf69207b4f50924ehkuang            encode_inter_mb_segment(cpi, x,
200191037db265ecdd914a26e056cf69207b4f50924ehkuang                                    bsi->segment_rd - this_segment_rd, i,
200291037db265ecdd914a26e056cf69207b4f50924ehkuang                                    &bsi->rdstat[i][mode_idx].byrate,
200391037db265ecdd914a26e056cf69207b4f50924ehkuang                                    &bsi->rdstat[i][mode_idx].bdist,
200491037db265ecdd914a26e056cf69207b4f50924ehkuang                                    &bsi->rdstat[i][mode_idx].bsse,
200591037db265ecdd914a26e056cf69207b4f50924ehkuang                                    bsi->rdstat[i][mode_idx].ta,
200691037db265ecdd914a26e056cf69207b4f50924ehkuang                                    bsi->rdstat[i][mode_idx].tl);
200791037db265ecdd914a26e056cf69207b4f50924ehkuang        if (bsi->rdstat[i][mode_idx].brdcost < INT64_MAX) {
200891037db265ecdd914a26e056cf69207b4f50924ehkuang          bsi->rdstat[i][mode_idx].brdcost += RDCOST(x->rdmult, x->rddiv,
200991037db265ecdd914a26e056cf69207b4f50924ehkuang                                            bsi->rdstat[i][mode_idx].brate, 0);
201091037db265ecdd914a26e056cf69207b4f50924ehkuang          bsi->rdstat[i][mode_idx].brate += bsi->rdstat[i][mode_idx].byrate;
20115ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          bsi->rdstat[i][mode_idx].eobs = pd->eobs[i];
20125ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          if (num_4x4_blocks_wide > 1)
20135ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            bsi->rdstat[i + 1][mode_idx].eobs = pd->eobs[i + 1];
20145ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          if (num_4x4_blocks_high > 1)
20155ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            bsi->rdstat[i + 2][mode_idx].eobs = pd->eobs[i + 2];
201691037db265ecdd914a26e056cf69207b4f50924ehkuang        }
2017ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
201891037db265ecdd914a26e056cf69207b4f50924ehkuang        if (bsi->rdstat[i][mode_idx].brdcost < best_rd) {
2019ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          mode_selected = this_mode;
202091037db265ecdd914a26e056cf69207b4f50924ehkuang          best_rd = bsi->rdstat[i][mode_idx].brdcost;
2021ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
2022ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      } /*for each 4x4 mode*/
2023ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
202491037db265ecdd914a26e056cf69207b4f50924ehkuang      if (best_rd == INT64_MAX) {
202591037db265ecdd914a26e056cf69207b4f50924ehkuang        int iy, midx;
202691037db265ecdd914a26e056cf69207b4f50924ehkuang        for (iy = i + 1; iy < 4; ++iy)
20271184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          for (midx = 0; midx < INTER_MODES; ++midx)
202891037db265ecdd914a26e056cf69207b4f50924ehkuang            bsi->rdstat[iy][midx].brdcost = INT64_MAX;
202991037db265ecdd914a26e056cf69207b4f50924ehkuang        bsi->segment_rd = INT64_MAX;
203091037db265ecdd914a26e056cf69207b4f50924ehkuang        return;
203191037db265ecdd914a26e056cf69207b4f50924ehkuang      }
203291037db265ecdd914a26e056cf69207b4f50924ehkuang
20339b35249446b07f40ac5fcc3205f2c048616efacchkuang      mode_idx = INTER_OFFSET(mode_selected);
203491037db265ecdd914a26e056cf69207b4f50924ehkuang      vpx_memcpy(t_above, bsi->rdstat[i][mode_idx].ta, sizeof(t_above));
203591037db265ecdd914a26e056cf69207b4f50924ehkuang      vpx_memcpy(t_left, bsi->rdstat[i][mode_idx].tl, sizeof(t_left));
2036ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2037ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      labels2mode(x, i, mode_selected, &mode_mv[mode_selected],
2038ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                  &second_mode_mv[mode_selected], frame_mv, seg_mvs[i],
2039ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                  bsi->ref_mv, bsi->second_ref_mv, x->nmvjointcost,
2040ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                  x->mvcost, cpi);
2041ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
204291037db265ecdd914a26e056cf69207b4f50924ehkuang      br += bsi->rdstat[i][mode_idx].brate;
204391037db265ecdd914a26e056cf69207b4f50924ehkuang      bd += bsi->rdstat[i][mode_idx].bdist;
204491037db265ecdd914a26e056cf69207b4f50924ehkuang      block_sse += bsi->rdstat[i][mode_idx].bsse;
204591037db265ecdd914a26e056cf69207b4f50924ehkuang      segmentyrate += bsi->rdstat[i][mode_idx].byrate;
204691037db265ecdd914a26e056cf69207b4f50924ehkuang      this_segment_rd += bsi->rdstat[i][mode_idx].brdcost;
204791037db265ecdd914a26e056cf69207b4f50924ehkuang
204891037db265ecdd914a26e056cf69207b4f50924ehkuang      if (this_segment_rd > bsi->segment_rd) {
204991037db265ecdd914a26e056cf69207b4f50924ehkuang        int iy, midx;
205091037db265ecdd914a26e056cf69207b4f50924ehkuang        for (iy = i + 1; iy < 4; ++iy)
20511184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          for (midx = 0; midx < INTER_MODES; ++midx)
205291037db265ecdd914a26e056cf69207b4f50924ehkuang            bsi->rdstat[iy][midx].brdcost = INT64_MAX;
205391037db265ecdd914a26e056cf69207b4f50924ehkuang        bsi->segment_rd = INT64_MAX;
205491037db265ecdd914a26e056cf69207b4f50924ehkuang        return;
205591037db265ecdd914a26e056cf69207b4f50924ehkuang      }
2056ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
2057ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  } /* for each label */
2058ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
205991037db265ecdd914a26e056cf69207b4f50924ehkuang  bsi->r = br;
206091037db265ecdd914a26e056cf69207b4f50924ehkuang  bsi->d = bd;
206191037db265ecdd914a26e056cf69207b4f50924ehkuang  bsi->segment_yrate = segmentyrate;
206291037db265ecdd914a26e056cf69207b4f50924ehkuang  bsi->segment_rd = this_segment_rd;
206391037db265ecdd914a26e056cf69207b4f50924ehkuang  bsi->sse = block_sse;
2064ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
206591037db265ecdd914a26e056cf69207b4f50924ehkuang  // update the coding decisions
206691037db265ecdd914a26e056cf69207b4f50924ehkuang  for (i = 0; i < 4; ++i)
20675ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    bsi->modes[i] = mi->bmi[i].as_mode;
2068ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
2069ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
207091037db265ecdd914a26e056cf69207b4f50924ehkuangstatic int64_t rd_pick_best_mbsegmentation(VP9_COMP *cpi, MACROBLOCK *x,
20715ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                           const TileInfo *const tile,
207291037db265ecdd914a26e056cf69207b4f50924ehkuang                                           int_mv *best_ref_mv,
207391037db265ecdd914a26e056cf69207b4f50924ehkuang                                           int_mv *second_best_ref_mv,
207491037db265ecdd914a26e056cf69207b4f50924ehkuang                                           int64_t best_rd,
207591037db265ecdd914a26e056cf69207b4f50924ehkuang                                           int *returntotrate,
207691037db265ecdd914a26e056cf69207b4f50924ehkuang                                           int *returnyrate,
207791037db265ecdd914a26e056cf69207b4f50924ehkuang                                           int64_t *returndistortion,
207891037db265ecdd914a26e056cf69207b4f50924ehkuang                                           int *skippable, int64_t *psse,
207991037db265ecdd914a26e056cf69207b4f50924ehkuang                                           int mvthresh,
208091037db265ecdd914a26e056cf69207b4f50924ehkuang                                           int_mv seg_mvs[4][MAX_REF_FRAMES],
208191037db265ecdd914a26e056cf69207b4f50924ehkuang                                           BEST_SEG_INFO *bsi_buf,
208291037db265ecdd914a26e056cf69207b4f50924ehkuang                                           int filter_idx,
208391037db265ecdd914a26e056cf69207b4f50924ehkuang                                           int mi_row, int mi_col) {
2084ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int i;
208591037db265ecdd914a26e056cf69207b4f50924ehkuang  BEST_SEG_INFO *bsi = bsi_buf + filter_idx;
208691037db265ecdd914a26e056cf69207b4f50924ehkuang  MACROBLOCKD *xd = &x->e_mbd;
20875ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MODE_INFO *mi = xd->mi_8x8[0];
208891037db265ecdd914a26e056cf69207b4f50924ehkuang  MB_MODE_INFO *mbmi = &mi->mbmi;
208991037db265ecdd914a26e056cf69207b4f50924ehkuang  int mode_idx;
2090ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2091f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  vp9_zero(*bsi);
2092ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
209391037db265ecdd914a26e056cf69207b4f50924ehkuang  bsi->segment_rd = best_rd;
209491037db265ecdd914a26e056cf69207b4f50924ehkuang  bsi->ref_mv = best_ref_mv;
209591037db265ecdd914a26e056cf69207b4f50924ehkuang  bsi->second_ref_mv = second_best_ref_mv;
209691037db265ecdd914a26e056cf69207b4f50924ehkuang  bsi->mvp.as_int = best_ref_mv->as_int;
209791037db265ecdd914a26e056cf69207b4f50924ehkuang  bsi->mvthresh = mvthresh;
2098ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2099ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0; i < 4; i++)
210091037db265ecdd914a26e056cf69207b4f50924ehkuang    bsi->modes[i] = ZEROMV;
2101ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
21025ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  rd_check_segment_txsize(cpi, x, tile, bsi_buf, filter_idx, seg_mvs,
21035ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                          mi_row, mi_col);
2104ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
210591037db265ecdd914a26e056cf69207b4f50924ehkuang  if (bsi->segment_rd > best_rd)
210691037db265ecdd914a26e056cf69207b4f50924ehkuang    return INT64_MAX;
2107ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* set it to the best */
2108ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0; i < 4; i++) {
21099b35249446b07f40ac5fcc3205f2c048616efacchkuang    mode_idx = INTER_OFFSET(bsi->modes[i]);
211091037db265ecdd914a26e056cf69207b4f50924ehkuang    mi->bmi[i].as_mv[0].as_int = bsi->rdstat[i][mode_idx].mvs[0].as_int;
21115ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (has_second_ref(mbmi))
211291037db265ecdd914a26e056cf69207b4f50924ehkuang      mi->bmi[i].as_mv[1].as_int = bsi->rdstat[i][mode_idx].mvs[1].as_int;
211391037db265ecdd914a26e056cf69207b4f50924ehkuang    xd->plane[0].eobs[i] = bsi->rdstat[i][mode_idx].eobs;
21145ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    mi->bmi[i].as_mode = bsi->modes[i];
2115ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
2116ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2117ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /*
2118ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang   * used to set mbmi->mv.as_int
2119ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang   */
212091037db265ecdd914a26e056cf69207b4f50924ehkuang  *returntotrate = bsi->r;
212191037db265ecdd914a26e056cf69207b4f50924ehkuang  *returndistortion = bsi->d;
212291037db265ecdd914a26e056cf69207b4f50924ehkuang  *returnyrate = bsi->segment_yrate;
21231184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  *skippable = vp9_is_skippable_in_plane(&x->e_mbd, BLOCK_8X8, 0);
212491037db265ecdd914a26e056cf69207b4f50924ehkuang  *psse = bsi->sse;
212591037db265ecdd914a26e056cf69207b4f50924ehkuang  mbmi->mode = bsi->modes[3];
2126ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
212791037db265ecdd914a26e056cf69207b4f50924ehkuang  return bsi->segment_rd;
2128ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
2129ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2130ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void mv_pred(VP9_COMP *cpi, MACROBLOCK *x,
2131ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                    uint8_t *ref_y_buffer, int ref_y_stride,
21321184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                    int ref_frame, BLOCK_SIZE block_size ) {
2133ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD *xd = &x->e_mbd;
21345ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi;
2135ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int_mv this_mv;
2136ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int i;
2137ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int zero_seen = 0;
2138ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int best_index = 0;
2139ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int best_sad = INT_MAX;
2140ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int this_sad = INT_MAX;
214191037db265ecdd914a26e056cf69207b4f50924ehkuang  unsigned int max_mv = 0;
2142ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2143ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  uint8_t *src_y_ptr = x->plane[0].src.buf;
2144ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  uint8_t *ref_y_ptr;
2145ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int row_offset, col_offset;
21461184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int num_mv_refs = MAX_MV_REF_CANDIDATES +
21471184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                    (cpi->sf.adaptive_motion_search &&
21481184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                     cpi->common.show_frame &&
21491184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                     block_size < cpi->sf.max_partition_size);
2150ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2151ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Get the sad for each candidate reference mv
21521184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  for (i = 0; i < num_mv_refs; i++) {
21531184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    this_mv.as_int = (i < MAX_MV_REF_CANDIDATES) ?
21541184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        mbmi->ref_mvs[ref_frame][i].as_int : x->pred_mv[ref_frame].as_int;
2155ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
215691037db265ecdd914a26e056cf69207b4f50924ehkuang    max_mv = MAX(max_mv,
215791037db265ecdd914a26e056cf69207b4f50924ehkuang                 MAX(abs(this_mv.as_mv.row), abs(this_mv.as_mv.col)) >> 3);
2158ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // The list is at an end if we see 0 for a second time.
2159ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (!this_mv.as_int && zero_seen)
2160ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      break;
2161ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    zero_seen = zero_seen || !this_mv.as_int;
2162ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2163ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    row_offset = this_mv.as_mv.row >> 3;
2164ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    col_offset = this_mv.as_mv.col >> 3;
2165ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ref_y_ptr = ref_y_buffer + (ref_y_stride * row_offset) + col_offset;
2166ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2167ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Find sad for current vector.
2168ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    this_sad = cpi->fn_ptr[block_size].sdf(src_y_ptr, x->plane[0].src.stride,
2169ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                           ref_y_ptr, ref_y_stride,
2170ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                           0x7fffffff);
2171ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2172ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Note if it is the best so far.
2173ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (this_sad < best_sad) {
2174ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      best_sad = this_sad;
2175ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      best_index = i;
2176ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
2177ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
2178ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2179ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Note the index of the mv that worked best in the reference list.
2180ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  x->mv_best_ref_index[ref_frame] = best_index;
218191037db265ecdd914a26e056cf69207b4f50924ehkuang  x->max_mv_context[ref_frame] = max_mv;
2182ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
2183ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2184ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void estimate_ref_frame_costs(VP9_COMP *cpi, int segment_id,
2185ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                     unsigned int *ref_costs_single,
2186ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                     unsigned int *ref_costs_comp,
2187ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                     vp9_prob *comp_mode_p) {
2188ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  VP9_COMMON *const cm = &cpi->common;
2189ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD *const xd = &cpi->mb.e_mbd;
21901184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int seg_ref_active = vp9_segfeature_active(&cm->seg, segment_id,
2191ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                             SEG_LVL_REF_FRAME);
2192ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (seg_ref_active) {
2193ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vpx_memset(ref_costs_single, 0, MAX_REF_FRAMES * sizeof(*ref_costs_single));
2194ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vpx_memset(ref_costs_comp,   0, MAX_REF_FRAMES * sizeof(*ref_costs_comp));
2195ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    *comp_mode_p = 128;
2196ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  } else {
219791037db265ecdd914a26e056cf69207b4f50924ehkuang    vp9_prob intra_inter_p = vp9_get_pred_prob_intra_inter(cm, xd);
2198ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vp9_prob comp_inter_p = 128;
2199ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2200ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (cm->comp_pred_mode == HYBRID_PREDICTION) {
220191037db265ecdd914a26e056cf69207b4f50924ehkuang      comp_inter_p = vp9_get_pred_prob_comp_inter_inter(cm, xd);
2202ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      *comp_mode_p = comp_inter_p;
2203ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    } else {
2204ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      *comp_mode_p = 128;
2205ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
2206ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2207ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ref_costs_single[INTRA_FRAME] = vp9_cost_bit(intra_inter_p, 0);
2208ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2209ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (cm->comp_pred_mode != COMP_PREDICTION_ONLY) {
221091037db265ecdd914a26e056cf69207b4f50924ehkuang      vp9_prob ref_single_p1 = vp9_get_pred_prob_single_ref_p1(cm, xd);
221191037db265ecdd914a26e056cf69207b4f50924ehkuang      vp9_prob ref_single_p2 = vp9_get_pred_prob_single_ref_p2(cm, xd);
2212ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      unsigned int base_cost = vp9_cost_bit(intra_inter_p, 1);
2213ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2214ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (cm->comp_pred_mode == HYBRID_PREDICTION)
2215ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        base_cost += vp9_cost_bit(comp_inter_p, 0);
2216ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2217ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      ref_costs_single[LAST_FRAME] = ref_costs_single[GOLDEN_FRAME] =
2218ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          ref_costs_single[ALTREF_FRAME] = base_cost;
2219ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      ref_costs_single[LAST_FRAME]   += vp9_cost_bit(ref_single_p1, 0);
2220ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      ref_costs_single[GOLDEN_FRAME] += vp9_cost_bit(ref_single_p1, 1);
2221ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      ref_costs_single[ALTREF_FRAME] += vp9_cost_bit(ref_single_p1, 1);
2222ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      ref_costs_single[GOLDEN_FRAME] += vp9_cost_bit(ref_single_p2, 0);
2223ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      ref_costs_single[ALTREF_FRAME] += vp9_cost_bit(ref_single_p2, 1);
2224ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    } else {
2225ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      ref_costs_single[LAST_FRAME]   = 512;
2226ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      ref_costs_single[GOLDEN_FRAME] = 512;
2227ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      ref_costs_single[ALTREF_FRAME] = 512;
2228ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
2229ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (cm->comp_pred_mode != SINGLE_PREDICTION_ONLY) {
223091037db265ecdd914a26e056cf69207b4f50924ehkuang      vp9_prob ref_comp_p = vp9_get_pred_prob_comp_ref_p(cm, xd);
2231ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      unsigned int base_cost = vp9_cost_bit(intra_inter_p, 1);
2232ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2233ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (cm->comp_pred_mode == HYBRID_PREDICTION)
2234ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        base_cost += vp9_cost_bit(comp_inter_p, 1);
2235ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2236ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      ref_costs_comp[LAST_FRAME]   = base_cost + vp9_cost_bit(ref_comp_p, 0);
2237ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      ref_costs_comp[GOLDEN_FRAME] = base_cost + vp9_cost_bit(ref_comp_p, 1);
2238ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    } else {
2239ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      ref_costs_comp[LAST_FRAME]   = 512;
2240ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      ref_costs_comp[GOLDEN_FRAME] = 512;
2241ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
2242ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
2243ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
2244ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2245ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void store_coding_context(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
224691037db265ecdd914a26e056cf69207b4f50924ehkuang                         int mode_index,
224791037db265ecdd914a26e056cf69207b4f50924ehkuang                         int_mv *ref_mv,
224891037db265ecdd914a26e056cf69207b4f50924ehkuang                         int_mv *second_ref_mv,
224991037db265ecdd914a26e056cf69207b4f50924ehkuang                         int64_t comp_pred_diff[NB_PREDICTION_TYPES],
2250f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                         int64_t tx_size_diff[TX_MODES],
22515ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                         int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS]) {
2252ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD *const xd = &x->e_mbd;
2253ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2254ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Take a snapshot of the coding context so it can be
2255ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // restored if we decide to encode this way
2256ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  ctx->skip = x->skip;
2257ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  ctx->best_mode_index = mode_index;
22585ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  ctx->mic = *xd->mi_8x8[0];
2259ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2260ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  ctx->best_ref_mv.as_int = ref_mv->as_int;
2261ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  ctx->second_best_ref_mv.as_int = second_ref_mv->as_int;
2262ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2263ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  ctx->single_pred_diff = (int)comp_pred_diff[SINGLE_PREDICTION_ONLY];
2264ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  ctx->comp_pred_diff   = (int)comp_pred_diff[COMP_PREDICTION_ONLY];
2265ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  ctx->hybrid_pred_diff = (int)comp_pred_diff[HYBRID_PREDICTION];
2266ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
22675ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  vpx_memcpy(ctx->tx_rd_diff, tx_size_diff, sizeof(ctx->tx_rd_diff));
22685ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  vpx_memcpy(ctx->best_filter_diff, best_filter_diff,
22695ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang             sizeof(*best_filter_diff) * SWITCHABLE_FILTER_CONTEXTS);
2270ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
2271ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2272ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void setup_pred_block(const MACROBLOCKD *xd,
2273ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                             struct buf_2d dst[MAX_MB_PLANE],
2274ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                             const YV12_BUFFER_CONFIG *src,
2275ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                             int mi_row, int mi_col,
2276ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                             const struct scale_factors *scale,
2277ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                             const struct scale_factors *scale_uv) {
2278ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int i;
2279ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2280ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  dst[0].buf = src->y_buffer;
2281ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  dst[0].stride = src->y_stride;
2282ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  dst[1].buf = src->u_buffer;
2283ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  dst[2].buf = src->v_buffer;
2284ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  dst[1].stride = dst[2].stride = src->uv_stride;
2285ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#if CONFIG_ALPHA
2286ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  dst[3].buf = src->alpha_buffer;
2287ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  dst[3].stride = src->alpha_stride;
2288ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#endif
2289ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2290ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // TODO(jkoleszar): Make scale factors per-plane data
2291ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0; i < MAX_MB_PLANE; i++) {
2292ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    setup_pred_plane(dst + i, dst[i].buf, dst[i].stride, mi_row, mi_col,
2293ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                     i ? scale_uv : scale,
2294ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                     xd->plane[i].subsampling_x, xd->plane[i].subsampling_y);
2295ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
2296ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
2297ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2298ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void setup_buffer_inter(VP9_COMP *cpi, MACROBLOCK *x,
22995ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                               const TileInfo *const tile,
2300ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                               int idx, MV_REFERENCE_FRAME frame_type,
23011184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                               BLOCK_SIZE block_size,
2302ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                               int mi_row, int mi_col,
2303ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                               int_mv frame_nearest_mv[MAX_REF_FRAMES],
2304ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                               int_mv frame_near_mv[MAX_REF_FRAMES],
2305ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                               struct buf_2d yv12_mb[4][MAX_MB_PLANE],
2306ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                               struct scale_factors scale[MAX_REF_FRAMES]) {
2307ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  VP9_COMMON *cm = &cpi->common;
2308ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  YV12_BUFFER_CONFIG *yv12 = &cm->yv12_fb[cpi->common.ref_frame_map[idx]];
2309ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD *const xd = &x->e_mbd;
23105ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi;
2311ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2312ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // set up scaling factors
2313ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  scale[frame_type] = cpi->common.active_ref_scale[frame_type - 1];
2314ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
23155ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  scale[frame_type].sfc->set_scaled_offsets(&scale[frame_type],
23165ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                            mi_row * MI_SIZE, mi_col * MI_SIZE);
2317ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2318ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // TODO(jkoleszar): Is the UV buffer ever used here? If so, need to make this
2319ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // use the UV scaling factors.
2320ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  setup_pred_block(xd, yv12_mb[frame_type], yv12, mi_row, mi_col,
2321ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                   &scale[frame_type], &scale[frame_type]);
2322ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2323ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Gets an initial list of candidate vectors from neighbours and orders them
23245ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  vp9_find_mv_refs(cm, xd, tile, xd->mi_8x8[0],
23251184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                   xd->last_mi,
2326ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                   frame_type,
23271184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                   mbmi->ref_mvs[frame_type], mi_row, mi_col);
2328ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2329ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Candidate refinement carried out at encoder and decoder
23305ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  vp9_find_best_ref_mvs(xd, cm->allow_high_precision_mv,
2331ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                        mbmi->ref_mvs[frame_type],
2332ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                        &frame_nearest_mv[frame_type],
2333ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                        &frame_near_mv[frame_type]);
2334ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2335ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Further refinement that is encode side only to test the top few candidates
2336ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // in full and choose the best as the centre point for subsequent searches.
2337ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // The current implementation doesn't support scaling.
23385ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (!vp9_is_scaled(scale[frame_type].sfc) && block_size >= BLOCK_8X8)
2339ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    mv_pred(cpi, x, yv12_mb[frame_type][0].buf, yv12->y_stride,
2340ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            frame_type, block_size);
2341ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
2342ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2343ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic YV12_BUFFER_CONFIG *get_scaled_ref_frame(VP9_COMP *cpi, int ref_frame) {
2344ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  YV12_BUFFER_CONFIG *scaled_ref_frame = NULL;
2345ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int fb = get_ref_frame_idx(cpi, ref_frame);
23461184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int fb_scale = get_scale_ref_frame_idx(cpi, ref_frame);
23471184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  if (cpi->scaled_ref_idx[fb_scale] != cpi->common.ref_frame_map[fb])
23481184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    scaled_ref_frame = &cpi->common.yv12_fb[cpi->scaled_ref_idx[fb_scale]];
2349ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return scaled_ref_frame;
2350ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
2351ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
23521184aebb761cbeac9124c37189a80a1a58f04b6bhkuangstatic INLINE int get_switchable_rate(const MACROBLOCK *x) {
23531184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const MACROBLOCKD *const xd = &x->e_mbd;
23545ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi;
23551184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const int ctx = vp9_get_pred_context_switchable_interp(xd);
23561184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  return SWITCHABLE_INTERP_RATE_FACTOR *
23571184aebb761cbeac9124c37189a80a1a58f04b6bhkuang             x->switchable_interp_costs[ctx][mbmi->interp_filter];
2358ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
2359ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2360ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
23615ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                 const TileInfo *const tile,
23621184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                 BLOCK_SIZE bsize,
2363ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                 int mi_row, int mi_col,
2364ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                 int_mv *tmp_mv, int *rate_mv) {
2365ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD *xd = &x->e_mbd;
236691037db265ecdd914a26e056cf69207b4f50924ehkuang  VP9_COMMON *cm = &cpi->common;
23675ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi;
2368ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0}};
2369ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int bestsme = INT_MAX;
237091037db265ecdd914a26e056cf69207b4f50924ehkuang  int further_steps, step_param;
2371ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int sadpb = x->sadperbit16;
2372ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int_mv mvp_full;
2373ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int ref = mbmi->ref_frame[0];
2374ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int_mv ref_mv = mbmi->ref_mvs[ref][0];
23751184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const BLOCK_SIZE block_size = get_plane_block_size(bsize, &xd->plane[0]);
2376ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2377ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int tmp_col_min = x->mv_col_min;
2378ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int tmp_col_max = x->mv_col_max;
2379ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int tmp_row_min = x->mv_row_min;
2380ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int tmp_row_max = x->mv_row_max;
2381ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2382ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  YV12_BUFFER_CONFIG *scaled_ref_frame = get_scaled_ref_frame(cpi, ref);
2383ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2384ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (scaled_ref_frame) {
2385ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int i;
2386ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Swap out the reference frame for a version that's been scaled to
2387ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // match the resolution of the current frame, allowing the existing
2388ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // motion search code to be used without additional modifications.
2389ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (i = 0; i < MAX_MB_PLANE; i++)
2390ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      backup_yv12[i] = xd->plane[i].pre[0];
2391ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
239291037db265ecdd914a26e056cf69207b4f50924ehkuang    setup_pre_planes(xd, 0, scaled_ref_frame, mi_row, mi_col, NULL);
2393ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
2394ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
23951184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  vp9_clamp_mv_min_max(x, &ref_mv.as_mv);
2396ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
239791037db265ecdd914a26e056cf69207b4f50924ehkuang  // Adjust search parameters based on small partitions' result.
239891037db265ecdd914a26e056cf69207b4f50924ehkuang  if (x->fast_ms) {
239991037db265ecdd914a26e056cf69207b4f50924ehkuang    // && abs(mvp_full.as_mv.row - x->pred_mv.as_mv.row) < 24 &&
240091037db265ecdd914a26e056cf69207b4f50924ehkuang    // abs(mvp_full.as_mv.col - x->pred_mv.as_mv.col) < 24) {
240191037db265ecdd914a26e056cf69207b4f50924ehkuang    // adjust search range
240291037db265ecdd914a26e056cf69207b4f50924ehkuang    step_param = 6;
240391037db265ecdd914a26e056cf69207b4f50924ehkuang    if (x->fast_ms > 1)
240491037db265ecdd914a26e056cf69207b4f50924ehkuang      step_param = 8;
240591037db265ecdd914a26e056cf69207b4f50924ehkuang
240691037db265ecdd914a26e056cf69207b4f50924ehkuang    // Get prediction MV.
24071184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    mvp_full.as_int = x->pred_mv[ref].as_int;
240891037db265ecdd914a26e056cf69207b4f50924ehkuang
240991037db265ecdd914a26e056cf69207b4f50924ehkuang    // Adjust MV sign if needed.
241091037db265ecdd914a26e056cf69207b4f50924ehkuang    if (cm->ref_frame_sign_bias[ref]) {
241191037db265ecdd914a26e056cf69207b4f50924ehkuang      mvp_full.as_mv.col *= -1;
241291037db265ecdd914a26e056cf69207b4f50924ehkuang      mvp_full.as_mv.row *= -1;
241391037db265ecdd914a26e056cf69207b4f50924ehkuang    }
241491037db265ecdd914a26e056cf69207b4f50924ehkuang  } else {
241591037db265ecdd914a26e056cf69207b4f50924ehkuang    // Work out the size of the first step in the mv step search.
241691037db265ecdd914a26e056cf69207b4f50924ehkuang    // 0 here is maximum length first step. 1 is MAX >> 1 etc.
241791037db265ecdd914a26e056cf69207b4f50924ehkuang    if (cpi->sf.auto_mv_step_size && cpi->common.show_frame) {
241891037db265ecdd914a26e056cf69207b4f50924ehkuang      // Take wtd average of the step_params based on the last frame's
241991037db265ecdd914a26e056cf69207b4f50924ehkuang      // max mv magnitude and that based on the best ref mvs of the current
242091037db265ecdd914a26e056cf69207b4f50924ehkuang      // block for the given reference.
242191037db265ecdd914a26e056cf69207b4f50924ehkuang      step_param = (vp9_init_search_range(cpi, x->max_mv_context[ref]) +
242291037db265ecdd914a26e056cf69207b4f50924ehkuang                    cpi->mv_step_param) >> 1;
242391037db265ecdd914a26e056cf69207b4f50924ehkuang    } else {
242491037db265ecdd914a26e056cf69207b4f50924ehkuang      step_param = cpi->mv_step_param;
242591037db265ecdd914a26e056cf69207b4f50924ehkuang    }
242691037db265ecdd914a26e056cf69207b4f50924ehkuang  }
2427ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
24281184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  if (cpi->sf.adaptive_motion_search && bsize < BLOCK_64X64 &&
24291184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      cpi->common.show_frame) {
24301184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    int boffset = 2 * (b_width_log2(BLOCK_64X64) - MIN(b_height_log2(bsize),
24311184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                                       b_width_log2(bsize)));
24321184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    step_param = MAX(step_param, boffset);
24331184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  }
24341184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
24351184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  mvp_full.as_int = x->mv_best_ref_index[ref] < MAX_MV_REF_CANDIDATES ?
24361184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      mbmi->ref_mvs[ref][x->mv_best_ref_index[ref]].as_int :
24371184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      x->pred_mv[ref].as_int;
24381184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
2439ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  mvp_full.as_mv.col >>= 3;
2440ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  mvp_full.as_mv.row >>= 3;
2441ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2442ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Further step/diamond searches as necessary
2443ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  further_steps = (cpi->sf.max_step_search_steps - 1) - step_param;
2444ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
24451184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  if (cpi->sf.search_method == HEX) {
24465ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    bestsme = vp9_hex_search(x, &mvp_full.as_mv,
24471184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                             step_param,
24481184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                             sadpb, 1,
24491184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                             &cpi->fn_ptr[block_size], 1,
24505ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                             &ref_mv.as_mv, &tmp_mv->as_mv);
24511184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  } else if (cpi->sf.search_method == SQUARE) {
24525ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    bestsme = vp9_square_search(x, &mvp_full.as_mv,
24531184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                step_param,
24541184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                sadpb, 1,
24551184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                &cpi->fn_ptr[block_size], 1,
24565ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                &ref_mv.as_mv, &tmp_mv->as_mv);
24571184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  } else if (cpi->sf.search_method == BIGDIA) {
24585ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    bestsme = vp9_bigdia_search(x, &mvp_full.as_mv,
24591184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                step_param,
24601184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                sadpb, 1,
24611184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                &cpi->fn_ptr[block_size], 1,
24625ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                &ref_mv.as_mv, &tmp_mv->as_mv);
24631184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  } else {
24641184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    bestsme = vp9_full_pixel_diamond(cpi, x, &mvp_full, step_param,
24651184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                     sadpb, further_steps, 1,
24661184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                     &cpi->fn_ptr[block_size],
24671184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                     &ref_mv, tmp_mv);
24681184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  }
2469ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2470ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  x->mv_col_min = tmp_col_min;
2471ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  x->mv_col_max = tmp_col_max;
2472ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  x->mv_row_min = tmp_row_min;
2473ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  x->mv_row_max = tmp_row_max;
2474ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2475ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (bestsme < INT_MAX) {
24761184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    int dis;  /* TODO: use dis in distortion calculation later. */
2477ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    unsigned int sse;
24785ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    cpi->find_fractional_mv_step(x, &tmp_mv->as_mv, &ref_mv.as_mv,
24795ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                 cm->allow_high_precision_mv,
2480ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                 x->errorperbit,
2481ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                 &cpi->fn_ptr[block_size],
24821184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                 0, cpi->sf.subpel_iters_per_step,
2483ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                 x->nmvjointcost, x->mvcost,
2484ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                 &dis, &sse);
2485ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
24865ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  *rate_mv = vp9_mv_bit_cost(&tmp_mv->as_mv, &ref_mv.as_mv,
24875ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                             x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
24881184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
24891184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  if (cpi->sf.adaptive_motion_search && cpi->common.show_frame)
24901184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    x->pred_mv[ref].as_int = tmp_mv->as_int;
24911184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
2492ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (scaled_ref_frame) {
2493ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int i;
2494ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (i = 0; i < MAX_MB_PLANE; i++)
2495ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      xd->plane[i].pre[0] = backup_yv12[i];
2496ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
2497ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
2498ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2499ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
25001184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                BLOCK_SIZE bsize,
2501ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                int_mv *frame_mv,
2502ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                int mi_row, int mi_col,
2503ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                int_mv single_newmv[MAX_REF_FRAMES],
2504ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                int *rate_mv) {
2505ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int pw = 4 << b_width_log2(bsize), ph = 4 << b_height_log2(bsize);
2506ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD *xd = &x->e_mbd;
25075ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi;
25089b35249446b07f40ac5fcc3205f2c048616efacchkuang  const int refs[2] = { mbmi->ref_frame[0],
25099b35249446b07f40ac5fcc3205f2c048616efacchkuang                        mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1] };
2510ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int_mv ref_mv[2];
25111184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const BLOCK_SIZE block_size = get_plane_block_size(bsize, &xd->plane[0]);
25129b35249446b07f40ac5fcc3205f2c048616efacchkuang  int ite, ref;
2513ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Prediction buffer from second frame.
2514ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  uint8_t *second_pred = vpx_memalign(16, pw * ph * sizeof(uint8_t));
2515ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2516ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Do joint motion search in compound mode to get more accurate mv.
25179b35249446b07f40ac5fcc3205f2c048616efacchkuang  struct buf_2d backup_yv12[2][MAX_MB_PLANE];
25189b35249446b07f40ac5fcc3205f2c048616efacchkuang  struct buf_2d scaled_first_yv12 = xd->plane[0].pre[0];
2519ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int last_besterr[2] = {INT_MAX, INT_MAX};
25209b35249446b07f40ac5fcc3205f2c048616efacchkuang  YV12_BUFFER_CONFIG *const scaled_ref_frame[2] = {
25219b35249446b07f40ac5fcc3205f2c048616efacchkuang    get_scaled_ref_frame(cpi, mbmi->ref_frame[0]),
25229b35249446b07f40ac5fcc3205f2c048616efacchkuang    get_scaled_ref_frame(cpi, mbmi->ref_frame[1])
25239b35249446b07f40ac5fcc3205f2c048616efacchkuang  };
2524ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
25259b35249446b07f40ac5fcc3205f2c048616efacchkuang  for (ref = 0; ref < 2; ++ref) {
25269b35249446b07f40ac5fcc3205f2c048616efacchkuang    ref_mv[ref] = mbmi->ref_mvs[refs[ref]][0];
25279b35249446b07f40ac5fcc3205f2c048616efacchkuang
25289b35249446b07f40ac5fcc3205f2c048616efacchkuang    if (scaled_ref_frame[ref]) {
25299b35249446b07f40ac5fcc3205f2c048616efacchkuang      int i;
25309b35249446b07f40ac5fcc3205f2c048616efacchkuang      // Swap out the reference frame for a version that's been scaled to
25319b35249446b07f40ac5fcc3205f2c048616efacchkuang      // match the resolution of the current frame, allowing the existing
25329b35249446b07f40ac5fcc3205f2c048616efacchkuang      // motion search code to be used without additional modifications.
25339b35249446b07f40ac5fcc3205f2c048616efacchkuang      for (i = 0; i < MAX_MB_PLANE; i++)
25349b35249446b07f40ac5fcc3205f2c048616efacchkuang        backup_yv12[ref][i] = xd->plane[i].pre[ref];
25359b35249446b07f40ac5fcc3205f2c048616efacchkuang      setup_pre_planes(xd, ref, scaled_ref_frame[ref], mi_row, mi_col, NULL);
25369b35249446b07f40ac5fcc3205f2c048616efacchkuang    }
2537ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
25389b35249446b07f40ac5fcc3205f2c048616efacchkuang    xd->scale_factor[ref].sfc->set_scaled_offsets(&xd->scale_factor[ref],
25399b35249446b07f40ac5fcc3205f2c048616efacchkuang                                                  mi_row, mi_col);
25409b35249446b07f40ac5fcc3205f2c048616efacchkuang    frame_mv[refs[ref]].as_int = single_newmv[refs[ref]].as_int;
2541ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
2542ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2543ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Allow joint search multiple times iteratively for each ref frame
2544ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // and break out the search loop if it couldn't find better mv.
2545ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (ite = 0; ite < 4; ite++) {
2546ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    struct buf_2d ref_yv12[2];
2547ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int bestsme = INT_MAX;
2548ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int sadpb = x->sadperbit16;
2549ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int_mv tmp_mv;
2550ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int search_range = 3;
2551ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2552ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int tmp_col_min = x->mv_col_min;
2553ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int tmp_col_max = x->mv_col_max;
2554ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int tmp_row_min = x->mv_row_min;
2555ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int tmp_row_max = x->mv_row_max;
2556ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int id = ite % 2;
2557ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2558ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Initialized here because of compiler problem in Visual Studio.
2559ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ref_yv12[0] = xd->plane[0].pre[0];
2560ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ref_yv12[1] = xd->plane[0].pre[1];
2561ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2562ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Get pred block from second frame.
2563ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vp9_build_inter_predictor(ref_yv12[!id].buf,
2564ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                              ref_yv12[!id].stride,
2565ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                              second_pred, pw,
2566f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                              &frame_mv[refs[!id]].as_mv,
2567ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                              &xd->scale_factor[!id],
2568ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                              pw, ph, 0,
256991037db265ecdd914a26e056cf69207b4f50924ehkuang                              &xd->subpix, MV_PRECISION_Q3);
2570ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2571ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Compound motion search on first ref frame.
2572ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (id)
2573ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      xd->plane[0].pre[0] = ref_yv12[id];
25741184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    vp9_clamp_mv_min_max(x, &ref_mv[id].as_mv);
2575ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2576ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Use mv result from single mode as mvp.
2577ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    tmp_mv.as_int = frame_mv[refs[id]].as_int;
2578ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2579ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    tmp_mv.as_mv.col >>= 3;
2580ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    tmp_mv.as_mv.row >>= 3;
2581ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2582ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Small-range full-pixel motion search
2583ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    bestsme = vp9_refining_search_8p_c(x, &tmp_mv, sadpb,
2584ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                       search_range,
2585ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                       &cpi->fn_ptr[block_size],
2586ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                       x->nmvjointcost, x->mvcost,
2587ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                       &ref_mv[id], second_pred,
2588ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                       pw, ph);
2589ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2590ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    x->mv_col_min = tmp_col_min;
2591ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    x->mv_col_max = tmp_col_max;
2592ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    x->mv_row_min = tmp_row_min;
2593ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    x->mv_row_max = tmp_row_max;
2594ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2595ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (bestsme < INT_MAX) {
2596ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      int dis; /* TODO: use dis in distortion calculation later. */
2597ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      unsigned int sse;
2598ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
25991184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      bestsme = cpi->find_fractional_mv_step_comp(
26005ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          x, &tmp_mv.as_mv,
26015ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          &ref_mv[id].as_mv,
26025ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          cpi->common.allow_high_precision_mv,
26031184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          x->errorperbit,
26041184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          &cpi->fn_ptr[block_size],
26051184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          0, cpi->sf.subpel_iters_per_step,
26061184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          x->nmvjointcost, x->mvcost,
26071184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          &dis, &sse, second_pred,
26081184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          pw, ph);
2609ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
2610ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2611ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (id)
2612ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      xd->plane[0].pre[0] = scaled_first_yv12;
2613ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2614ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (bestsme < last_besterr[id]) {
2615ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      frame_mv[refs[id]].as_int = tmp_mv.as_int;
2616ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      last_besterr[id] = bestsme;
2617ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    } else {
2618ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      break;
2619ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
2620ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
2621ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
26229b35249446b07f40ac5fcc3205f2c048616efacchkuang  *rate_mv = 0;
2623ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
26249b35249446b07f40ac5fcc3205f2c048616efacchkuang  for (ref = 0; ref < 2; ++ref) {
26259b35249446b07f40ac5fcc3205f2c048616efacchkuang    if (scaled_ref_frame[ref]) {
26269b35249446b07f40ac5fcc3205f2c048616efacchkuang      // restore the predictor
26279b35249446b07f40ac5fcc3205f2c048616efacchkuang      int i;
26289b35249446b07f40ac5fcc3205f2c048616efacchkuang      for (i = 0; i < MAX_MB_PLANE; i++)
26299b35249446b07f40ac5fcc3205f2c048616efacchkuang        xd->plane[i].pre[ref] = backup_yv12[ref][i];
26309b35249446b07f40ac5fcc3205f2c048616efacchkuang    }
26319b35249446b07f40ac5fcc3205f2c048616efacchkuang
26329b35249446b07f40ac5fcc3205f2c048616efacchkuang    *rate_mv += vp9_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
26339b35249446b07f40ac5fcc3205f2c048616efacchkuang                                &mbmi->ref_mvs[refs[ref]][0].as_mv,
26349b35249446b07f40ac5fcc3205f2c048616efacchkuang                                x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
2635ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
2636ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2637ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vpx_free(second_pred);
2638ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
2639ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2640ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
26415ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                 const TileInfo *const tile,
26421184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                 BLOCK_SIZE bsize,
2643ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                 int64_t txfm_cache[],
264491037db265ecdd914a26e056cf69207b4f50924ehkuang                                 int *rate2, int64_t *distortion,
264591037db265ecdd914a26e056cf69207b4f50924ehkuang                                 int *skippable,
264691037db265ecdd914a26e056cf69207b4f50924ehkuang                                 int *rate_y, int64_t *distortion_y,
264791037db265ecdd914a26e056cf69207b4f50924ehkuang                                 int *rate_uv, int64_t *distortion_uv,
2648ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                 int *mode_excluded, int *disable_skip,
26495ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                 INTERPOLATION_TYPE *best_filter,
265091037db265ecdd914a26e056cf69207b4f50924ehkuang                                 int_mv (*mode_mv)[MAX_REF_FRAMES],
2651ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                 int mi_row, int mi_col,
265291037db265ecdd914a26e056cf69207b4f50924ehkuang                                 int_mv single_newmv[MAX_REF_FRAMES],
26531184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                 int64_t *psse,
26541184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                 const int64_t ref_best_rd) {
2655ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  VP9_COMMON *cm = &cpi->common;
2656ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD *xd = &x->e_mbd;
26575ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi;
26585ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const int is_comp_pred = has_second_ref(mbmi);
2659ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int num_refs = is_comp_pred ? 2 : 1;
2660ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int this_mode = mbmi->mode;
266191037db265ecdd914a26e056cf69207b4f50924ehkuang  int_mv *frame_mv = mode_mv[this_mode];
2662ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int i;
2663ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int refs[2] = { mbmi->ref_frame[0],
2664ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
2665ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int_mv cur_mv[2];
2666ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int64_t this_rd = 0;
266791037db265ecdd914a26e056cf69207b4f50924ehkuang  DECLARE_ALIGNED_ARRAY(16, uint8_t, tmp_buf, MAX_MB_PLANE * 64 * 64);
2668ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int pred_exists = 0;
2669ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int intpel_mv;
2670ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int64_t rd, best_rd = INT64_MAX;
267191037db265ecdd914a26e056cf69207b4f50924ehkuang  int best_needs_copy = 0;
267291037db265ecdd914a26e056cf69207b4f50924ehkuang  uint8_t *orig_dst[MAX_MB_PLANE];
267391037db265ecdd914a26e056cf69207b4f50924ehkuang  int orig_dst_stride[MAX_MB_PLANE];
267491037db265ecdd914a26e056cf69207b4f50924ehkuang  int rs = 0;
2675ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
26765ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (is_comp_pred) {
26775ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (frame_mv[refs[0]].as_int == INVALID_MV ||
26785ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        frame_mv[refs[1]].as_int == INVALID_MV)
26795ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      return INT64_MAX;
26805ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
26815ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
2682f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  if (this_mode == NEWMV) {
2683ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int rate_mv;
2684f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    if (is_comp_pred) {
2685f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      // Initialize mv using single prediction mode result.
2686f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
2687f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
2688ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2689f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
2690f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        joint_motion_search(cpi, x, bsize, frame_mv,
2691f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                            mi_row, mi_col, single_newmv, &rate_mv);
2692ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      } else {
26935ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        rate_mv  = vp9_mv_bit_cost(&frame_mv[refs[0]].as_mv,
26945ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                   &mbmi->ref_mvs[refs[0]][0].as_mv,
26955ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                   x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
26965ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        rate_mv += vp9_mv_bit_cost(&frame_mv[refs[1]].as_mv,
26975ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                   &mbmi->ref_mvs[refs[1]][0].as_mv,
26985ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                   x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
2699ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
2700f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      *rate2 += rate_mv;
2701f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    } else {
2702f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      int_mv tmp_mv;
27035ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      single_motion_search(cpi, x, tile, bsize, mi_row, mi_col,
27045ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                           &tmp_mv, &rate_mv);
2705f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      *rate2 += rate_mv;
2706f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      frame_mv[refs[0]].as_int =
27075ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          xd->mi_8x8[0]->bmi[0].as_mv[0].as_int = tmp_mv.as_int;
2708f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      single_newmv[refs[0]].as_int = tmp_mv.as_int;
2709f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    }
2710ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
271191037db265ecdd914a26e056cf69207b4f50924ehkuang
271291037db265ecdd914a26e056cf69207b4f50924ehkuang  // if we're near/nearest and mv == 0,0, compare to zeromv
271391037db265ecdd914a26e056cf69207b4f50924ehkuang  if ((this_mode == NEARMV || this_mode == NEARESTMV || this_mode == ZEROMV) &&
271491037db265ecdd914a26e056cf69207b4f50924ehkuang      frame_mv[refs[0]].as_int == 0 &&
27151184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      !vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP) &&
271691037db265ecdd914a26e056cf69207b4f50924ehkuang      (num_refs == 1 || frame_mv[refs[1]].as_int == 0)) {
27171184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    int rfc = mbmi->mode_context[mbmi->ref_frame[0]];
271891037db265ecdd914a26e056cf69207b4f50924ehkuang    int c1 = cost_mv_ref(cpi, NEARMV, rfc);
271991037db265ecdd914a26e056cf69207b4f50924ehkuang    int c2 = cost_mv_ref(cpi, NEARESTMV, rfc);
272091037db265ecdd914a26e056cf69207b4f50924ehkuang    int c3 = cost_mv_ref(cpi, ZEROMV, rfc);
272191037db265ecdd914a26e056cf69207b4f50924ehkuang
272291037db265ecdd914a26e056cf69207b4f50924ehkuang    if (this_mode == NEARMV) {
272391037db265ecdd914a26e056cf69207b4f50924ehkuang      if (c1 > c3)
272491037db265ecdd914a26e056cf69207b4f50924ehkuang        return INT64_MAX;
272591037db265ecdd914a26e056cf69207b4f50924ehkuang    } else if (this_mode == NEARESTMV) {
272691037db265ecdd914a26e056cf69207b4f50924ehkuang      if (c2 > c3)
272791037db265ecdd914a26e056cf69207b4f50924ehkuang        return INT64_MAX;
272891037db265ecdd914a26e056cf69207b4f50924ehkuang    } else {
272991037db265ecdd914a26e056cf69207b4f50924ehkuang      assert(this_mode == ZEROMV);
273091037db265ecdd914a26e056cf69207b4f50924ehkuang      if (num_refs == 1) {
273191037db265ecdd914a26e056cf69207b4f50924ehkuang        if ((c3 >= c2 &&
273291037db265ecdd914a26e056cf69207b4f50924ehkuang             mode_mv[NEARESTMV][mbmi->ref_frame[0]].as_int == 0) ||
273391037db265ecdd914a26e056cf69207b4f50924ehkuang            (c3 >= c1 &&
273491037db265ecdd914a26e056cf69207b4f50924ehkuang             mode_mv[NEARMV][mbmi->ref_frame[0]].as_int == 0))
273591037db265ecdd914a26e056cf69207b4f50924ehkuang          return INT64_MAX;
273691037db265ecdd914a26e056cf69207b4f50924ehkuang      } else {
273791037db265ecdd914a26e056cf69207b4f50924ehkuang        if ((c3 >= c2 &&
273891037db265ecdd914a26e056cf69207b4f50924ehkuang             mode_mv[NEARESTMV][mbmi->ref_frame[0]].as_int == 0 &&
273991037db265ecdd914a26e056cf69207b4f50924ehkuang             mode_mv[NEARESTMV][mbmi->ref_frame[1]].as_int == 0) ||
274091037db265ecdd914a26e056cf69207b4f50924ehkuang            (c3 >= c1 &&
274191037db265ecdd914a26e056cf69207b4f50924ehkuang             mode_mv[NEARMV][mbmi->ref_frame[0]].as_int == 0 &&
274291037db265ecdd914a26e056cf69207b4f50924ehkuang             mode_mv[NEARMV][mbmi->ref_frame[1]].as_int == 0))
274391037db265ecdd914a26e056cf69207b4f50924ehkuang          return INT64_MAX;
274491037db265ecdd914a26e056cf69207b4f50924ehkuang      }
274591037db265ecdd914a26e056cf69207b4f50924ehkuang    }
274691037db265ecdd914a26e056cf69207b4f50924ehkuang  }
274791037db265ecdd914a26e056cf69207b4f50924ehkuang
2748ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0; i < num_refs; ++i) {
2749ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    cur_mv[i] = frame_mv[refs[i]];
2750ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Clip "next_nearest" so that it does not extend to far out of image
2751f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    if (this_mode != NEWMV)
2752f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      clamp_mv2(&cur_mv[i].as_mv, xd);
2753ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2754ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (mv_check_bounds(x, &cur_mv[i]))
2755ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      return INT64_MAX;
2756ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    mbmi->mv[i].as_int = cur_mv[i].as_int;
2757ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
2758ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
275991037db265ecdd914a26e056cf69207b4f50924ehkuang  // do first prediction into the destination buffer. Do the next
276091037db265ecdd914a26e056cf69207b4f50924ehkuang  // prediction into a temporary buffer. Then keep track of which one
276191037db265ecdd914a26e056cf69207b4f50924ehkuang  // of these currently holds the best predictor, and use the other
276291037db265ecdd914a26e056cf69207b4f50924ehkuang  // one for future predictions. In the end, copy from tmp_buf to
276391037db265ecdd914a26e056cf69207b4f50924ehkuang  // dst if necessary.
276491037db265ecdd914a26e056cf69207b4f50924ehkuang  for (i = 0; i < MAX_MB_PLANE; i++) {
276591037db265ecdd914a26e056cf69207b4f50924ehkuang    orig_dst[i] = xd->plane[i].dst.buf;
276691037db265ecdd914a26e056cf69207b4f50924ehkuang    orig_dst_stride[i] = xd->plane[i].dst.stride;
276791037db265ecdd914a26e056cf69207b4f50924ehkuang  }
276891037db265ecdd914a26e056cf69207b4f50924ehkuang
2769ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* We don't include the cost of the second reference here, because there
2770ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang   * are only three options: Last/Golden, ARF/Last or Golden/ARF, or in other
2771ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang   * words if you present them in that order, the second one is always known
2772ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang   * if the first is known */
277391037db265ecdd914a26e056cf69207b4f50924ehkuang  *rate2 += cost_mv_ref(cpi, this_mode,
27741184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                        mbmi->mode_context[mbmi->ref_frame[0]]);
277591037db265ecdd914a26e056cf69207b4f50924ehkuang
277691037db265ecdd914a26e056cf69207b4f50924ehkuang  if (!(*mode_excluded)) {
277791037db265ecdd914a26e056cf69207b4f50924ehkuang    if (is_comp_pred) {
277891037db265ecdd914a26e056cf69207b4f50924ehkuang      *mode_excluded = (cpi->common.comp_pred_mode == SINGLE_PREDICTION_ONLY);
277991037db265ecdd914a26e056cf69207b4f50924ehkuang    } else {
278091037db265ecdd914a26e056cf69207b4f50924ehkuang      *mode_excluded = (cpi->common.comp_pred_mode == COMP_PREDICTION_ONLY);
278191037db265ecdd914a26e056cf69207b4f50924ehkuang    }
278291037db265ecdd914a26e056cf69207b4f50924ehkuang  }
2783ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2784ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  pred_exists = 0;
2785ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Are all MVs integer pel for Y and UV
2786ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  intpel_mv = (mbmi->mv[0].as_mv.row & 15) == 0 &&
2787ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      (mbmi->mv[0].as_mv.col & 15) == 0;
2788ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (is_comp_pred)
2789ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    intpel_mv &= (mbmi->mv[1].as_mv.row & 15) == 0 &&
2790ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        (mbmi->mv[1].as_mv.col & 15) == 0;
2791ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Search for best switchable filter by checking the variance of
2792ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // pred error irrespective of whether the filter will be used
27931184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  if (cm->mcomp_filter_type != BILINEAR) {
2794ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    *best_filter = EIGHTTAP;
27951184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    if (x->source_variance <
27961184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        cpi->sf.disable_filter_search_var_thresh) {
27971184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      *best_filter = EIGHTTAP;
27981184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      vp9_zero(cpi->rd_filter_cache);
27991184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    } else {
28001184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      int i, newbest;
28011184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      int tmp_rate_sum = 0;
28021184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      int64_t tmp_dist_sum = 0;
28031184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
28041184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      cpi->rd_filter_cache[SWITCHABLE_FILTERS] = INT64_MAX;
28051184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      for (i = 0; i < SWITCHABLE_FILTERS; ++i) {
28061184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        int j;
28071184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        int64_t rs_rd;
28081184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        mbmi->interp_filter = i;
28091184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        vp9_setup_interp_filters(xd, mbmi->interp_filter, cm);
28101184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        rs = get_switchable_rate(x);
28111184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0);
28121184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
28131184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        if (i > 0 && intpel_mv) {
28141184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          cpi->rd_filter_cache[i] = RDCOST(x->rdmult, x->rddiv,
28151184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                           tmp_rate_sum, tmp_dist_sum);
28161184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          cpi->rd_filter_cache[SWITCHABLE_FILTERS] =
28171184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              MIN(cpi->rd_filter_cache[SWITCHABLE_FILTERS],
28181184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  cpi->rd_filter_cache[i] + rs_rd);
28191184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          rd = cpi->rd_filter_cache[i];
28201184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          if (cm->mcomp_filter_type == SWITCHABLE)
28211184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            rd += rs_rd;
282291037db265ecdd914a26e056cf69207b4f50924ehkuang        } else {
28231184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          int rate_sum = 0;
28241184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          int64_t dist_sum = 0;
28251184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          if ((cm->mcomp_filter_type == SWITCHABLE &&
28261184aebb761cbeac9124c37189a80a1a58f04b6bhkuang               (!i || best_needs_copy)) ||
28271184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              (cm->mcomp_filter_type != SWITCHABLE &&
28281184aebb761cbeac9124c37189a80a1a58f04b6bhkuang               (cm->mcomp_filter_type == mbmi->interp_filter ||
28291184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                (i == 0 && intpel_mv)))) {
28301184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            for (j = 0; j < MAX_MB_PLANE; j++) {
28311184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              xd->plane[j].dst.buf = orig_dst[j];
28321184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              xd->plane[j].dst.stride = orig_dst_stride[j];
28331184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            }
28341184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          } else {
28351184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            for (j = 0; j < MAX_MB_PLANE; j++) {
28361184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              xd->plane[j].dst.buf = tmp_buf + j * 64 * 64;
28371184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              xd->plane[j].dst.stride = 64;
28381184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            }
28391184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          }
28401184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          vp9_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
28411184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          model_rd_for_sb(cpi, bsize, x, xd, &rate_sum, &dist_sum);
28421184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          cpi->rd_filter_cache[i] = RDCOST(x->rdmult, x->rddiv,
28431184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                           rate_sum, dist_sum);
28441184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          cpi->rd_filter_cache[SWITCHABLE_FILTERS] =
28451184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              MIN(cpi->rd_filter_cache[SWITCHABLE_FILTERS],
28461184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  cpi->rd_filter_cache[i] + rs_rd);
28471184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          rd = cpi->rd_filter_cache[i];
28481184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          if (cm->mcomp_filter_type == SWITCHABLE)
28491184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            rd += rs_rd;
28501184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          if (i == 0 && intpel_mv) {
28511184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            tmp_rate_sum = rate_sum;
28521184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            tmp_dist_sum = dist_sum;
285391037db265ecdd914a26e056cf69207b4f50924ehkuang          }
285491037db265ecdd914a26e056cf69207b4f50924ehkuang        }
28551184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        if (i == 0 && cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
28561184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          if (rd / 2 > ref_best_rd) {
28571184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            for (i = 0; i < MAX_MB_PLANE; i++) {
28581184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              xd->plane[i].dst.buf = orig_dst[i];
28591184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              xd->plane[i].dst.stride = orig_dst_stride[i];
28601184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            }
28611184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            return INT64_MAX;
286291037db265ecdd914a26e056cf69207b4f50924ehkuang          }
286391037db265ecdd914a26e056cf69207b4f50924ehkuang        }
28641184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        newbest = i == 0 || rd < best_rd;
28651184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
28661184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        if (newbest) {
28671184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          best_rd = rd;
28681184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          *best_filter = mbmi->interp_filter;
28691184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          if (cm->mcomp_filter_type == SWITCHABLE && i && !intpel_mv)
28701184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            best_needs_copy = !best_needs_copy;
28711184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        }
2872ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
28731184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        if ((cm->mcomp_filter_type == SWITCHABLE && newbest) ||
28741184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            (cm->mcomp_filter_type != SWITCHABLE &&
28751184aebb761cbeac9124c37189a80a1a58f04b6bhkuang             cm->mcomp_filter_type == mbmi->interp_filter)) {
28761184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          pred_exists = 1;
28771184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        }
2878ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
2879ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
28801184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      for (i = 0; i < MAX_MB_PLANE; i++) {
28811184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        xd->plane[i].dst.buf = orig_dst[i];
28821184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        xd->plane[i].dst.stride = orig_dst_stride[i];
28831184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      }
288491037db265ecdd914a26e056cf69207b4f50924ehkuang    }
288591037db265ecdd914a26e056cf69207b4f50924ehkuang  }
2886f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  // Set the appropriate filter
2887ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  mbmi->interp_filter = cm->mcomp_filter_type != SWITCHABLE ?
2888ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      cm->mcomp_filter_type : *best_filter;
2889ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vp9_setup_interp_filters(xd, mbmi->interp_filter, cm);
2890f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  rs = cm->mcomp_filter_type == SWITCHABLE ? get_switchable_rate(x) : 0;
2891ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2892ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (pred_exists) {
289391037db265ecdd914a26e056cf69207b4f50924ehkuang    if (best_needs_copy) {
289491037db265ecdd914a26e056cf69207b4f50924ehkuang      // again temporarily set the buffers to local memory to prevent a memcpy
289591037db265ecdd914a26e056cf69207b4f50924ehkuang      for (i = 0; i < MAX_MB_PLANE; i++) {
289691037db265ecdd914a26e056cf69207b4f50924ehkuang        xd->plane[i].dst.buf = tmp_buf + i * 64 * 64;
289791037db265ecdd914a26e056cf69207b4f50924ehkuang        xd->plane[i].dst.stride = 64;
289891037db265ecdd914a26e056cf69207b4f50924ehkuang      }
2899ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
2900ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  } else {
2901ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Handles the special case when a filter that is not in the
2902ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // switchable list (ex. bilinear, 6-tap) is indicated at the frame level
2903ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    vp9_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
2904ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
2905ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
290691037db265ecdd914a26e056cf69207b4f50924ehkuang
290791037db265ecdd914a26e056cf69207b4f50924ehkuang  if (cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
290891037db265ecdd914a26e056cf69207b4f50924ehkuang    int tmp_rate;
290991037db265ecdd914a26e056cf69207b4f50924ehkuang    int64_t tmp_dist;
291091037db265ecdd914a26e056cf69207b4f50924ehkuang    model_rd_for_sb(cpi, bsize, x, xd, &tmp_rate, &tmp_dist);
291191037db265ecdd914a26e056cf69207b4f50924ehkuang    rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist);
291291037db265ecdd914a26e056cf69207b4f50924ehkuang    // if current pred_error modeled rd is substantially more than the best
291391037db265ecdd914a26e056cf69207b4f50924ehkuang    // so far, do not bother doing full rd
291491037db265ecdd914a26e056cf69207b4f50924ehkuang    if (rd / 2 > ref_best_rd) {
291591037db265ecdd914a26e056cf69207b4f50924ehkuang      for (i = 0; i < MAX_MB_PLANE; i++) {
291691037db265ecdd914a26e056cf69207b4f50924ehkuang        xd->plane[i].dst.buf = orig_dst[i];
291791037db265ecdd914a26e056cf69207b4f50924ehkuang        xd->plane[i].dst.stride = orig_dst_stride[i];
291891037db265ecdd914a26e056cf69207b4f50924ehkuang      }
291991037db265ecdd914a26e056cf69207b4f50924ehkuang      return INT64_MAX;
292091037db265ecdd914a26e056cf69207b4f50924ehkuang    }
292191037db265ecdd914a26e056cf69207b4f50924ehkuang  }
292291037db265ecdd914a26e056cf69207b4f50924ehkuang
2923ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (cpi->common.mcomp_filter_type == SWITCHABLE)
2924f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    *rate2 += get_switchable_rate(x);
2925f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
29261184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  if (!is_comp_pred && cpi->enable_encode_breakout) {
2927f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    if (cpi->active_map_enabled && x->active_ptr[0] == 0)
2928f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      x->skip = 1;
2929f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    else if (x->encode_breakout) {
29301184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      const BLOCK_SIZE y_size = get_plane_block_size(bsize, &xd->plane[0]);
29311184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      const BLOCK_SIZE uv_size = get_plane_block_size(bsize, &xd->plane[1]);
2932f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      unsigned int var, sse;
2933f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      // Skipping threshold for ac.
2934f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      unsigned int thresh_ac;
2935f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      // The encode_breakout input
2936f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      unsigned int encode_breakout = x->encode_breakout << 4;
29375ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      unsigned int max_thresh = 36000;
29381184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
29391184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      // Use extreme low threshold for static frames to limit skipping.
29401184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      if (cpi->enable_encode_breakout == 2)
29411184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        max_thresh = 128;
2942f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
2943f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      // Calculate threshold according to dequant value.
2944f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      thresh_ac = (xd->plane[0].dequant[1] * xd->plane[0].dequant[1]) / 9;
2945f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
2946f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      // Use encode_breakout input if it is bigger than internal threshold.
2947f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      if (thresh_ac < encode_breakout)
2948f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        thresh_ac = encode_breakout;
2949f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
29501184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      // Set a maximum for threshold to avoid big PSNR loss in low bitrate case.
29511184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      if (thresh_ac > max_thresh)
29521184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        thresh_ac = max_thresh;
29531184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
2954f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      var = cpi->fn_ptr[y_size].vf(x->plane[0].src.buf, x->plane[0].src.stride,
2955f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                                   xd->plane[0].dst.buf,
2956f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                                   xd->plane[0].dst.stride, &sse);
2957f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
2958f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      // Adjust threshold according to partition size.
2959f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      thresh_ac >>= 8 - (b_width_log2_lookup[bsize] +
2960f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          b_height_log2_lookup[bsize]);
2961f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
2962f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      // Y skipping condition checking
2963f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      if (sse < thresh_ac || sse == 0) {
2964f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        // Skipping threshold for dc
2965f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        unsigned int thresh_dc;
2966f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
2967f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        thresh_dc = (xd->plane[0].dequant[0] * xd->plane[0].dequant[0] >> 6);
2968f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
2969f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        // dc skipping checking
2970f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        if ((sse - var) < thresh_dc || sse == var) {
2971f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          unsigned int sse_u, sse_v;
2972f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          unsigned int var_u, var_v;
2973f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
2974f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          var_u = cpi->fn_ptr[uv_size].vf(x->plane[1].src.buf,
2975f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                                          x->plane[1].src.stride,
2976f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                                          xd->plane[1].dst.buf,
2977f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                                          xd->plane[1].dst.stride, &sse_u);
2978f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
2979f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          // U skipping condition checking
2980f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          if ((sse_u * 4 < thresh_ac || sse_u == 0) &&
2981f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang              (sse_u - var_u < thresh_dc || sse_u == var_u)) {
2982f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang            var_v = cpi->fn_ptr[uv_size].vf(x->plane[2].src.buf,
2983f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                                            x->plane[2].src.stride,
2984f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                                            xd->plane[2].dst.buf,
2985f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                                            xd->plane[2].dst.stride, &sse_v);
2986f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
2987f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang            // V skipping condition checking
2988f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang            if ((sse_v * 4 < thresh_ac || sse_v == 0) &&
2989f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                (sse_v - var_v < thresh_dc || sse_v == var_v)) {
2990f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang              x->skip = 1;
2991f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
29921184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              // The cost of skip bit needs to be added.
29931184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              *rate2 += vp9_cost_bit(vp9_get_pred_prob_mbskip(cm, xd), 1);
2994f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
2995f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang              // Scaling factor for SSE from spatial domain to frequency domain
2996f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang              // is 16. Adjust distortion accordingly.
2997f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang              *distortion_uv = (sse_u + sse_v) << 4;
2998f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang              *distortion = (sse << 4) + *distortion_uv;
2999f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
3000f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang              *disable_skip = 1;
3001f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang              this_rd = RDCOST(x->rdmult, x->rddiv, *rate2, *distortion);
3002f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang            }
3003f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          }
3004ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
3005ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
3006ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
3007ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
3008ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3009ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (!x->skip) {
3010ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int skippable_y, skippable_uv;
30111184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    int64_t sseuv = INT64_MAX;
30121184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    int64_t rdcosty = INT64_MAX;
3013ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3014ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Y cost and distortion
301591037db265ecdd914a26e056cf69207b4f50924ehkuang    super_block_yrd(cpi, x, rate_y, distortion_y, &skippable_y, psse,
301691037db265ecdd914a26e056cf69207b4f50924ehkuang                    bsize, txfm_cache, ref_best_rd);
301791037db265ecdd914a26e056cf69207b4f50924ehkuang
301891037db265ecdd914a26e056cf69207b4f50924ehkuang    if (*rate_y == INT_MAX) {
301991037db265ecdd914a26e056cf69207b4f50924ehkuang      *rate2 = INT_MAX;
302091037db265ecdd914a26e056cf69207b4f50924ehkuang      *distortion = INT64_MAX;
302191037db265ecdd914a26e056cf69207b4f50924ehkuang      for (i = 0; i < MAX_MB_PLANE; i++) {
302291037db265ecdd914a26e056cf69207b4f50924ehkuang        xd->plane[i].dst.buf = orig_dst[i];
302391037db265ecdd914a26e056cf69207b4f50924ehkuang        xd->plane[i].dst.stride = orig_dst_stride[i];
302491037db265ecdd914a26e056cf69207b4f50924ehkuang      }
302591037db265ecdd914a26e056cf69207b4f50924ehkuang      return INT64_MAX;
302691037db265ecdd914a26e056cf69207b4f50924ehkuang    }
3027ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3028ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    *rate2 += *rate_y;
3029ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    *distortion += *distortion_y;
3030ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
30311184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    rdcosty = RDCOST(x->rdmult, x->rddiv, *rate2, *distortion);
30321184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    rdcosty = MIN(rdcosty, RDCOST(x->rdmult, x->rddiv, 0, *psse));
30331184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
30345ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    super_block_uvrd(cpi, x, rate_uv, distortion_uv, &skippable_uv, &sseuv,
30351184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                     bsize, ref_best_rd - rdcosty);
30361184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    if (*rate_uv == INT_MAX) {
30371184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      *rate2 = INT_MAX;
30381184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      *distortion = INT64_MAX;
30391184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      for (i = 0; i < MAX_MB_PLANE; i++) {
30401184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        xd->plane[i].dst.buf = orig_dst[i];
30411184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        xd->plane[i].dst.stride = orig_dst_stride[i];
30421184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      }
30431184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      return INT64_MAX;
30441184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    }
3045ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
304691037db265ecdd914a26e056cf69207b4f50924ehkuang    *psse += sseuv;
3047ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    *rate2 += *rate_uv;
3048ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    *distortion += *distortion_uv;
3049ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    *skippable = skippable_y && skippable_uv;
3050ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
3051ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
305291037db265ecdd914a26e056cf69207b4f50924ehkuang  for (i = 0; i < MAX_MB_PLANE; i++) {
305391037db265ecdd914a26e056cf69207b4f50924ehkuang    xd->plane[i].dst.buf = orig_dst[i];
305491037db265ecdd914a26e056cf69207b4f50924ehkuang    xd->plane[i].dst.stride = orig_dst_stride[i];
3055ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
3056ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3057ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return this_rd;  // if 0, this will be re-calculated by caller
3058ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
3059ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
30609b35249446b07f40ac5fcc3205f2c048616efacchkuangstatic void swap_block_ptr(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
30619b35249446b07f40ac5fcc3205f2c048616efacchkuang                           int max_plane) {
30629b35249446b07f40ac5fcc3205f2c048616efacchkuang  struct macroblock_plane *const p = x->plane;
30639b35249446b07f40ac5fcc3205f2c048616efacchkuang  struct macroblockd_plane *const pd = x->e_mbd.plane;
30649b35249446b07f40ac5fcc3205f2c048616efacchkuang  int i;
30659b35249446b07f40ac5fcc3205f2c048616efacchkuang
30669b35249446b07f40ac5fcc3205f2c048616efacchkuang  for (i = 0; i < max_plane; ++i) {
30679b35249446b07f40ac5fcc3205f2c048616efacchkuang    p[i].coeff    = ctx->coeff_pbuf[i][1];
30689b35249446b07f40ac5fcc3205f2c048616efacchkuang    pd[i].qcoeff  = ctx->qcoeff_pbuf[i][1];
30699b35249446b07f40ac5fcc3205f2c048616efacchkuang    pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][1];
30709b35249446b07f40ac5fcc3205f2c048616efacchkuang    pd[i].eobs    = ctx->eobs_pbuf[i][1];
30719b35249446b07f40ac5fcc3205f2c048616efacchkuang
30729b35249446b07f40ac5fcc3205f2c048616efacchkuang    ctx->coeff_pbuf[i][1]   = ctx->coeff_pbuf[i][0];
30739b35249446b07f40ac5fcc3205f2c048616efacchkuang    ctx->qcoeff_pbuf[i][1]  = ctx->qcoeff_pbuf[i][0];
30749b35249446b07f40ac5fcc3205f2c048616efacchkuang    ctx->dqcoeff_pbuf[i][1] = ctx->dqcoeff_pbuf[i][0];
30759b35249446b07f40ac5fcc3205f2c048616efacchkuang    ctx->eobs_pbuf[i][1]    = ctx->eobs_pbuf[i][0];
30769b35249446b07f40ac5fcc3205f2c048616efacchkuang
30779b35249446b07f40ac5fcc3205f2c048616efacchkuang    ctx->coeff_pbuf[i][0]   = p[i].coeff;
30789b35249446b07f40ac5fcc3205f2c048616efacchkuang    ctx->qcoeff_pbuf[i][0]  = pd[i].qcoeff;
30799b35249446b07f40ac5fcc3205f2c048616efacchkuang    ctx->dqcoeff_pbuf[i][0] = pd[i].dqcoeff;
30809b35249446b07f40ac5fcc3205f2c048616efacchkuang    ctx->eobs_pbuf[i][0]    = pd[i].eobs;
30819b35249446b07f40ac5fcc3205f2c048616efacchkuang  }
30829b35249446b07f40ac5fcc3205f2c048616efacchkuang}
30839b35249446b07f40ac5fcc3205f2c048616efacchkuang
3084ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid vp9_rd_pick_intra_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
308591037db265ecdd914a26e056cf69207b4f50924ehkuang                               int *returnrate, int64_t *returndist,
30861184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                               BLOCK_SIZE bsize,
308791037db265ecdd914a26e056cf69207b4f50924ehkuang                               PICK_MODE_CONTEXT *ctx, int64_t best_rd) {
308891037db265ecdd914a26e056cf69207b4f50924ehkuang  VP9_COMMON *const cm = &cpi->common;
308991037db265ecdd914a26e056cf69207b4f50924ehkuang  MACROBLOCKD *const xd = &x->e_mbd;
309091037db265ecdd914a26e056cf69207b4f50924ehkuang  int rate_y = 0, rate_uv = 0, rate_y_tokenonly = 0, rate_uv_tokenonly = 0;
30911184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int y_skip = 0, uv_skip = 0;
3092f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  int64_t dist_y = 0, dist_uv = 0, tx_cache[TX_MODES] = { 0 };
309391037db265ecdd914a26e056cf69207b4f50924ehkuang  x->skip_encode = 0;
3094ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  ctx->skip = 0;
30955ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  xd->mi_8x8[0]->mbmi.ref_frame[0] = INTRA_FRAME;
30961184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  if (bsize >= BLOCK_8X8) {
309791037db265ecdd914a26e056cf69207b4f50924ehkuang    if (rd_pick_intra_sby_mode(cpi, x, &rate_y, &rate_y_tokenonly,
3098f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                               &dist_y, &y_skip, bsize, tx_cache,
309991037db265ecdd914a26e056cf69207b4f50924ehkuang                               best_rd) >= best_rd) {
310091037db265ecdd914a26e056cf69207b4f50924ehkuang      *returnrate = INT_MAX;
310191037db265ecdd914a26e056cf69207b4f50924ehkuang      return;
310291037db265ecdd914a26e056cf69207b4f50924ehkuang    }
31039b35249446b07f40ac5fcc3205f2c048616efacchkuang    rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv, &rate_uv_tokenonly,
310491037db265ecdd914a26e056cf69207b4f50924ehkuang                            &dist_uv, &uv_skip, bsize);
310591037db265ecdd914a26e056cf69207b4f50924ehkuang  } else {
310691037db265ecdd914a26e056cf69207b4f50924ehkuang    y_skip = 0;
3107f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate_y, &rate_y_tokenonly,
3108f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                                     &dist_y, best_rd) >= best_rd) {
310991037db265ecdd914a26e056cf69207b4f50924ehkuang      *returnrate = INT_MAX;
311091037db265ecdd914a26e056cf69207b4f50924ehkuang      return;
311191037db265ecdd914a26e056cf69207b4f50924ehkuang    }
31129b35249446b07f40ac5fcc3205f2c048616efacchkuang    rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv, &rate_uv_tokenonly,
31131184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                            &dist_uv, &uv_skip, BLOCK_8X8);
311491037db265ecdd914a26e056cf69207b4f50924ehkuang  }
3115ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3116ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (y_skip && uv_skip) {
3117ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    *returnrate = rate_y + rate_uv - rate_y_tokenonly - rate_uv_tokenonly +
311891037db265ecdd914a26e056cf69207b4f50924ehkuang                  vp9_cost_bit(vp9_get_pred_prob_mbskip(cm, xd), 1);
31191184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    *returndist = dist_y + dist_uv;
3120f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    vp9_zero(ctx->tx_rd_diff);
3121ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  } else {
312291037db265ecdd914a26e056cf69207b4f50924ehkuang    int i;
3123ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    *returnrate = rate_y + rate_uv +
312491037db265ecdd914a26e056cf69207b4f50924ehkuang        vp9_cost_bit(vp9_get_pred_prob_mbskip(cm, xd), 0);
31251184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    *returndist = dist_y + dist_uv;
3126f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    if (cpi->sf.tx_size_search_method == USE_FULL_RD)
31275ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      for (i = 0; i < TX_MODES; i++) {
31285ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if (tx_cache[i] < INT64_MAX && tx_cache[cm->tx_mode] < INT64_MAX)
31295ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          ctx->tx_rd_diff[i] = tx_cache[i] - tx_cache[cm->tx_mode];
31305ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        else
31315ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          ctx->tx_rd_diff[i] = 0;
31325ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      }
3133ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
3134ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
31355ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  ctx->mic = *xd->mi_8x8[0];
3136ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
3137ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3138ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangint64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
31395ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                  const TileInfo *const tile,
3140ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                  int mi_row, int mi_col,
3141ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                  int *returnrate,
314291037db265ecdd914a26e056cf69207b4f50924ehkuang                                  int64_t *returndistortion,
31431184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                  BLOCK_SIZE bsize,
314491037db265ecdd914a26e056cf69207b4f50924ehkuang                                  PICK_MODE_CONTEXT *ctx,
314591037db265ecdd914a26e056cf69207b4f50924ehkuang                                  int64_t best_rd_so_far) {
3146ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  VP9_COMMON *cm = &cpi->common;
3147ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD *xd = &x->e_mbd;
31485ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi;
31491184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const struct segmentation *seg = &cm->seg;
31501184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const BLOCK_SIZE block_size = get_plane_block_size(bsize, &xd->plane[0]);
31515ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MB_PREDICTION_MODE this_mode;
3152f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  MV_REFERENCE_FRAME ref_frame, second_ref_frame;
31531184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  unsigned char segment_id = mbmi->segment_id;
3154ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int comp_pred, i;
3155ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
3156ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  struct buf_2d yv12_mb[4][MAX_MB_PLANE];
31571184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int_mv single_newmv[MAX_REF_FRAMES] = { { 0 } };
3158ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  static const int flag_list[4] = { 0, VP9_LAST_FLAG, VP9_GOLD_FLAG,
3159ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                    VP9_ALT_FLAG };
3160ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int idx_list[4] = {0,
3161ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                     cpi->lst_fb_idx,
3162ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                     cpi->gld_fb_idx,
3163ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                     cpi->alt_fb_idx};
316491037db265ecdd914a26e056cf69207b4f50924ehkuang  int64_t best_rd = best_rd_so_far;
3165f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  int64_t best_tx_rd[TX_MODES];
3166f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  int64_t best_tx_diff[TX_MODES];
3167ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int64_t best_pred_diff[NB_PREDICTION_TYPES];
3168ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int64_t best_pred_rd[NB_PREDICTION_TYPES];
31695ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int64_t best_filter_rd[SWITCHABLE_FILTER_CONTEXTS];
31705ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS];
31711184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  MB_MODE_INFO best_mbmode = { 0 };
3172ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int j;
3173ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int mode_index, best_mode_index = 0;
3174ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  unsigned int ref_costs_single[MAX_REF_FRAMES], ref_costs_comp[MAX_REF_FRAMES];
3175ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vp9_prob comp_mode_p;
317691037db265ecdd914a26e056cf69207b4f50924ehkuang  int64_t best_intra_rd = INT64_MAX;
317791037db265ecdd914a26e056cf69207b4f50924ehkuang  int64_t best_inter_rd = INT64_MAX;
317891037db265ecdd914a26e056cf69207b4f50924ehkuang  MB_PREDICTION_MODE best_intra_mode = DC_PRED;
317991037db265ecdd914a26e056cf69207b4f50924ehkuang  MV_REFERENCE_FRAME best_inter_ref_frame = LAST_FRAME;
31805ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  INTERPOLATION_TYPE tmp_best_filter = SWITCHABLE;
3181f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  int rate_uv_intra[TX_SIZES], rate_uv_tokenonly[TX_SIZES];
3182f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  int64_t dist_uv[TX_SIZES];
3183f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  int skip_uv[TX_SIZES];
3184f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  MB_PREDICTION_MODE mode_uv[TX_SIZES];
3185ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  struct scale_factors scale_factor[4];
3186ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  unsigned int ref_frame_mask = 0;
3187ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  unsigned int mode_mask = 0;
3188ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int64_t mode_distortions[MB_MODE_COUNT] = {-1};
3189ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int64_t frame_distortions[MAX_REF_FRAMES] = {-1};
31905ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int intra_cost_penalty = 20 * vp9_dc_quant(cm->base_qindex, cm->y_dc_delta_q);
31911184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const int bws = num_8x8_blocks_wide_lookup[bsize] / 2;
31921184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const int bhs = num_8x8_blocks_high_lookup[bsize] / 2;
319391037db265ecdd914a26e056cf69207b4f50924ehkuang  int best_skip2 = 0;
319491037db265ecdd914a26e056cf69207b4f50924ehkuang
31959b35249446b07f40ac5fcc3205f2c048616efacchkuang  x->skip_encode = cpi->sf.skip_encode_frame && x->q_index < QIDX_SKIP_THRESH;
3196ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3197ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Everywhere the flag is set the error is much higher than its neighbors.
3198ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  ctx->frames_with_high_error = 0;
3199ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  ctx->modes_with_high_error = 0;
3200ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3201ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  estimate_ref_frame_costs(cpi, segment_id, ref_costs_single, ref_costs_comp,
3202ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                           &comp_mode_p);
3203ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3204ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0; i < NB_PREDICTION_TYPES; ++i)
3205ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    best_pred_rd[i] = INT64_MAX;
3206f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  for (i = 0; i < TX_MODES; i++)
3207f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    best_tx_rd[i] = INT64_MAX;
32085ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
320991037db265ecdd914a26e056cf69207b4f50924ehkuang    best_filter_rd[i] = INT64_MAX;
3210f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  for (i = 0; i < TX_SIZES; i++)
321191037db265ecdd914a26e056cf69207b4f50924ehkuang    rate_uv_intra[i] = INT_MAX;
321291037db265ecdd914a26e056cf69207b4f50924ehkuang
321391037db265ecdd914a26e056cf69207b4f50924ehkuang  *returnrate = INT_MAX;
3214ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3215f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  // Create a mask set to 1 for each reference frame used by a smaller
3216f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  // resolution.
321791037db265ecdd914a26e056cf69207b4f50924ehkuang  if (cpi->sf.use_avoid_tested_higherror) {
3218ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    switch (block_size) {
3219ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      case BLOCK_64X64:
3220ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        for (i = 0; i < 4; i++) {
3221ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          for (j = 0; j < 4; j++) {
3222ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            ref_frame_mask |= x->mb_context[i][j].frames_with_high_error;
3223ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            mode_mask |= x->mb_context[i][j].modes_with_high_error;
3224ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          }
3225ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
3226ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        for (i = 0; i < 4; i++) {
3227ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          ref_frame_mask |= x->sb32_context[i].frames_with_high_error;
3228ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          mode_mask |= x->sb32_context[i].modes_with_high_error;
3229ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
3230ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        break;
3231ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      case BLOCK_32X32:
3232ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        for (i = 0; i < 4; i++) {
3233ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          ref_frame_mask |=
32349b35249446b07f40ac5fcc3205f2c048616efacchkuang              x->mb_context[x->sb_index][i].frames_with_high_error;
32359b35249446b07f40ac5fcc3205f2c048616efacchkuang          mode_mask |= x->mb_context[x->sb_index][i].modes_with_high_error;
3236ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
3237ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        break;
3238ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      default:
3239ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        // Until we handle all block sizes set it to present;
3240ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        ref_frame_mask = 0;
3241ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        mode_mask = 0;
3242ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        break;
3243ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
3244ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ref_frame_mask = ~ref_frame_mask;
3245ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    mode_mask = ~mode_mask;
3246ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
3247ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3248ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
3249ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (cpi->ref_frame_flags & flag_list[ref_frame]) {
32505ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      setup_buffer_inter(cpi, x, tile, idx_list[ref_frame], ref_frame,
32515ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                         block_size, mi_row, mi_col,
32525ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                         frame_mv[NEARESTMV], frame_mv[NEARMV],
3253ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                         yv12_mb, scale_factor);
3254ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
3255ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
3256ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    frame_mv[ZEROMV][ref_frame].as_int = 0;
3257ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
3258ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3259ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (mode_index = 0; mode_index < MAX_MODES; ++mode_index) {
3260ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int mode_excluded = 0;
3261ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int64_t this_rd = INT64_MAX;
3262ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int disable_skip = 0;
3263ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int compmode_cost = 0;
3264ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int rate2 = 0, rate_y = 0, rate_uv = 0;
326591037db265ecdd914a26e056cf69207b4f50924ehkuang    int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
32661184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    int skippable = 0;
3267f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    int64_t tx_cache[TX_MODES];
3268ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int i;
326991037db265ecdd914a26e056cf69207b4f50924ehkuang    int this_skip2 = 0;
327091037db265ecdd914a26e056cf69207b4f50924ehkuang    int64_t total_sse = INT_MAX;
327191037db265ecdd914a26e056cf69207b4f50924ehkuang    int early_term = 0;
3272ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3273f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    for (i = 0; i < TX_MODES; ++i)
3274f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      tx_cache[i] = INT64_MAX;
3275ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3276f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    x->skip = 0;
327791037db265ecdd914a26e056cf69207b4f50924ehkuang    this_mode = vp9_mode_order[mode_index].mode;
327891037db265ecdd914a26e056cf69207b4f50924ehkuang    ref_frame = vp9_mode_order[mode_index].ref_frame;
3279f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    second_ref_frame = vp9_mode_order[mode_index].second_ref_frame;
328091037db265ecdd914a26e056cf69207b4f50924ehkuang
32811184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    // Look at the reference frame of the best mode so far and set the
32821184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    // skip mask to look at a subset of the remaining modes.
32831184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    if (mode_index > cpi->sf.mode_skip_start) {
32841184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      if (mode_index == (cpi->sf.mode_skip_start + 1)) {
32851184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        switch (vp9_mode_order[best_mode_index].ref_frame) {
32861184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          case INTRA_FRAME:
32871184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            cpi->mode_skip_mask = 0;
32881184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            break;
32891184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          case LAST_FRAME:
32901184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            cpi->mode_skip_mask = LAST_FRAME_MODE_MASK;
32911184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            break;
32921184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          case GOLDEN_FRAME:
32931184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            cpi->mode_skip_mask = GOLDEN_FRAME_MODE_MASK;
32941184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            break;
32951184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          case ALTREF_FRAME:
32961184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            cpi->mode_skip_mask = ALT_REF_MODE_MASK;
32971184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            break;
32981184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          case NONE:
32991184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          case MAX_REF_FRAMES:
33001184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            assert(!"Invalid Reference frame");
33011184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        }
33021184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      }
33035ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (cpi->mode_skip_mask & ((int64_t)1 << mode_index))
33041184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        continue;
33051184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    }
330691037db265ecdd914a26e056cf69207b4f50924ehkuang
3307f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    // Skip if the current reference frame has been masked off
330891037db265ecdd914a26e056cf69207b4f50924ehkuang    if (cpi->sf.reference_masking && !cpi->set_ref_frame_mask &&
330991037db265ecdd914a26e056cf69207b4f50924ehkuang        (cpi->ref_frame_mask & (1 << ref_frame)))
331091037db265ecdd914a26e056cf69207b4f50924ehkuang      continue;
331191037db265ecdd914a26e056cf69207b4f50924ehkuang
3312ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Test best rd so far against threshold for trying this mode.
33135ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if ((best_rd < ((int64_t)cpi->rd_threshes[segment_id][bsize][mode_index] *
33145ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                     cpi->rd_thresh_freq_fact[bsize][mode_index] >> 5)) ||
33155ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        cpi->rd_threshes[segment_id][bsize][mode_index] == INT_MAX)
3316ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      continue;
3317ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3318ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Do not allow compound prediction if the segment level reference
3319ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // frame feature is in use as in this case there can only be one reference.
3320f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    if ((second_ref_frame > INTRA_FRAME) &&
3321f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang         vp9_segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME))
3322ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      continue;
3323ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
332491037db265ecdd914a26e056cf69207b4f50924ehkuang    // Skip some checking based on small partitions' result.
332591037db265ecdd914a26e056cf69207b4f50924ehkuang    if (x->fast_ms > 1 && !ref_frame)
332691037db265ecdd914a26e056cf69207b4f50924ehkuang      continue;
332791037db265ecdd914a26e056cf69207b4f50924ehkuang    if (x->fast_ms > 2 && ref_frame != x->subblock_ref)
332891037db265ecdd914a26e056cf69207b4f50924ehkuang      continue;
332991037db265ecdd914a26e056cf69207b4f50924ehkuang
33301184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    if (cpi->sf.use_avoid_tested_higherror && bsize >= BLOCK_8X8) {
3331ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (!(ref_frame_mask & (1 << ref_frame))) {
3332ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        continue;
3333ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
3334ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (!(mode_mask & (1 << this_mode))) {
3335ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        continue;
3336ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
3337f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      if (second_ref_frame != NONE
3338f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          && !(ref_frame_mask & (1 << second_ref_frame))) {
3339ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        continue;
3340ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
3341ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
3342ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3343ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    mbmi->ref_frame[0] = ref_frame;
3344f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    mbmi->ref_frame[1] = second_ref_frame;
3345ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3346ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (!(ref_frame == INTRA_FRAME
3347ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        || (cpi->ref_frame_flags & flag_list[ref_frame]))) {
3348ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      continue;
3349ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
3350f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    if (!(second_ref_frame == NONE
3351f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        || (cpi->ref_frame_flags & flag_list[second_ref_frame]))) {
3352ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      continue;
3353ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
3354ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3355f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    comp_pred = second_ref_frame > INTRA_FRAME;
335691037db265ecdd914a26e056cf69207b4f50924ehkuang    if (comp_pred) {
335791037db265ecdd914a26e056cf69207b4f50924ehkuang      if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA)
335891037db265ecdd914a26e056cf69207b4f50924ehkuang        if (vp9_mode_order[best_mode_index].ref_frame == INTRA_FRAME)
335991037db265ecdd914a26e056cf69207b4f50924ehkuang          continue;
336091037db265ecdd914a26e056cf69207b4f50924ehkuang      if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_COMP_REFMISMATCH)
3361f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        if (ref_frame != best_inter_ref_frame &&
3362f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang            second_ref_frame != best_inter_ref_frame)
336391037db265ecdd914a26e056cf69207b4f50924ehkuang          continue;
336491037db265ecdd914a26e056cf69207b4f50924ehkuang    }
3365ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3366f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    set_scale_factors(xd, ref_frame, second_ref_frame, scale_factor);
3367ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    mbmi->uv_mode = DC_PRED;
3368ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3369ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Evaluate all sub-pel filters irrespective of whether we can use
3370ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // them for this frame.
3371ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    mbmi->interp_filter = cm->mcomp_filter_type;
33725ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    vp9_setup_interp_filters(xd, mbmi->interp_filter, cm);
3373ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3374ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (comp_pred) {
3375f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      if (!(cpi->ref_frame_flags & flag_list[second_ref_frame]))
3376ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        continue;
3377f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      set_scale_factors(xd, ref_frame, second_ref_frame, scale_factor);
3378ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
337991037db265ecdd914a26e056cf69207b4f50924ehkuang      mode_excluded = mode_excluded
338091037db265ecdd914a26e056cf69207b4f50924ehkuang                         ? mode_excluded
338191037db265ecdd914a26e056cf69207b4f50924ehkuang                         : cm->comp_pred_mode == SINGLE_PREDICTION_ONLY;
3382ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    } else {
3383f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      if (ref_frame != INTRA_FRAME && second_ref_frame != INTRA_FRAME) {
3384f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        mode_excluded =
3385f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang            mode_excluded ?
3386f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                mode_excluded : cm->comp_pred_mode == COMP_PREDICTION_ONLY;
3387ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
3388ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
3389ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3390f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    // Select prediction reference frames.
3391ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (i = 0; i < MAX_MB_PLANE; i++) {
3392ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
3393ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (comp_pred)
3394f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
3395ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
3396ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3397ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // If the segment reference frame feature is enabled....
3398ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // then do nothing if the current ref frame is not allowed..
3399f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    if (vp9_segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
3400f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        vp9_get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) !=
340191037db265ecdd914a26e056cf69207b4f50924ehkuang            (int)ref_frame) {
3402ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      continue;
3403ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // If the segment skip feature is enabled....
3404ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // then do nothing if the current mode is not allowed..
3405f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    } else if (vp9_segfeature_active(seg, segment_id, SEG_LVL_SKIP) &&
34065ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang               (this_mode != ZEROMV && ref_frame != INTRA_FRAME)) {
3407ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      continue;
3408ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Disable this drop out case if the ref frame
3409ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // segment level feature is enabled for this segment. This is to
3410ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // prevent the possibility that we end up unable to pick any mode.
3411f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    } else if (!vp9_segfeature_active(seg, segment_id,
341291037db265ecdd914a26e056cf69207b4f50924ehkuang                                      SEG_LVL_REF_FRAME)) {
3413ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
3414ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // unless ARNR filtering is enabled in which case we want
341591037db265ecdd914a26e056cf69207b4f50924ehkuang      // an unfiltered alternative. We allow near/nearest as well
341691037db265ecdd914a26e056cf69207b4f50924ehkuang      // because they may result in zero-zero MVs but be cheaper.
3417ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (cpi->is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) {
34185ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if ((this_mode != ZEROMV &&
34195ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang             !(this_mode == NEARMV &&
34205ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang               frame_mv[NEARMV][ALTREF_FRAME].as_int == 0) &&
34215ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang             !(this_mode == NEARESTMV &&
34225ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang               frame_mv[NEARESTMV][ALTREF_FRAME].as_int == 0)) ||
342391037db265ecdd914a26e056cf69207b4f50924ehkuang            ref_frame != ALTREF_FRAME) {
3424ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          continue;
3425ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
3426ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
3427ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
3428ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // TODO(JBB): This is to make up for the fact that we don't have sad
3429ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // functions that work when the block size reads outside the umv.  We
3430ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // should fix this either by making the motion search just work on
3431ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // a representative block in the boundary ( first ) and then implement a
3432ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // function that does sads when inside the border..
3433ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (((mi_row + bhs) > cm->mi_rows || (mi_col + bws) > cm->mi_cols) &&
34345ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        this_mode == NEWMV) {
3435ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      continue;
3436ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
3437ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
34381184aebb761cbeac9124c37189a80a1a58f04b6bhkuang#ifdef MODE_TEST_HIT_STATS
34391184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    // TEST/DEBUG CODE
34401184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    // Keep a rcord of the number of test hits at each size
34411184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    cpi->mode_test_hits[bsize]++;
34421184aebb761cbeac9124c37189a80a1a58f04b6bhkuang#endif
34431184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
3444ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
34455ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (ref_frame == INTRA_FRAME) {
3446ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      TX_SIZE uv_tx;
3447f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      // Disable intra modes other than DC_PRED for blocks with low variance
3448f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      // Threshold for intra skipping based on source variance
3449f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      // TODO(debargha): Specialize the threshold for super block sizes
34505ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      static const unsigned int skip_intra_var_thresh[BLOCK_SIZES] = {
3451f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
3452f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      };
3453f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      if ((cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_LOWVAR) &&
34545ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          this_mode != DC_PRED &&
3455f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          x->source_variance < skip_intra_var_thresh[mbmi->sb_type])
3456f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        continue;
345791037db265ecdd914a26e056cf69207b4f50924ehkuang      // Only search the oblique modes if the best so far is
345891037db265ecdd914a26e056cf69207b4f50924ehkuang      // one of the neighboring directional modes
345991037db265ecdd914a26e056cf69207b4f50924ehkuang      if ((cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_BESTINTER) &&
34605ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          (this_mode >= D45_PRED && this_mode <= TM_PRED)) {
346191037db265ecdd914a26e056cf69207b4f50924ehkuang        if (vp9_mode_order[best_mode_index].ref_frame > INTRA_FRAME)
346291037db265ecdd914a26e056cf69207b4f50924ehkuang          continue;
346391037db265ecdd914a26e056cf69207b4f50924ehkuang      }
34645ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      mbmi->mode = this_mode;
346591037db265ecdd914a26e056cf69207b4f50924ehkuang      if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
346691037db265ecdd914a26e056cf69207b4f50924ehkuang        if (conditional_skipintra(mbmi->mode, best_intra_mode))
346791037db265ecdd914a26e056cf69207b4f50924ehkuang            continue;
346891037db265ecdd914a26e056cf69207b4f50924ehkuang      }
34691184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
347091037db265ecdd914a26e056cf69207b4f50924ehkuang      super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable, NULL,
3471f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                      bsize, tx_cache, best_rd);
347291037db265ecdd914a26e056cf69207b4f50924ehkuang
347391037db265ecdd914a26e056cf69207b4f50924ehkuang      if (rate_y == INT_MAX)
347491037db265ecdd914a26e056cf69207b4f50924ehkuang        continue;
347591037db265ecdd914a26e056cf69207b4f50924ehkuang
34761184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      uv_tx = MIN(mbmi->tx_size, max_uv_txsize_lookup[bsize]);
347791037db265ecdd914a26e056cf69207b4f50924ehkuang      if (rate_uv_intra[uv_tx] == INT_MAX) {
34789b35249446b07f40ac5fcc3205f2c048616efacchkuang        choose_intra_uv_mode(cpi, ctx, bsize, &rate_uv_intra[uv_tx],
347991037db265ecdd914a26e056cf69207b4f50924ehkuang                             &rate_uv_tokenonly[uv_tx],
348091037db265ecdd914a26e056cf69207b4f50924ehkuang                             &dist_uv[uv_tx], &skip_uv[uv_tx],
348191037db265ecdd914a26e056cf69207b4f50924ehkuang                             &mode_uv[uv_tx]);
348291037db265ecdd914a26e056cf69207b4f50924ehkuang      }
348391037db265ecdd914a26e056cf69207b4f50924ehkuang
348491037db265ecdd914a26e056cf69207b4f50924ehkuang      rate_uv = rate_uv_tokenonly[uv_tx];
3485ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      distortion_uv = dist_uv[uv_tx];
3486ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      skippable = skippable && skip_uv[uv_tx];
3487ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      mbmi->uv_mode = mode_uv[uv_tx];
3488ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
348991037db265ecdd914a26e056cf69207b4f50924ehkuang      rate2 = rate_y + x->mbmode_cost[mbmi->mode] + rate_uv_intra[uv_tx];
34905ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (this_mode != DC_PRED && this_mode != TM_PRED)
3491ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        rate2 += intra_cost_penalty;
3492ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      distortion2 = distortion_y + distortion_uv;
34935ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    } else {
34945ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      mbmi->mode = this_mode;
34955ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      compmode_cost = vp9_cost_bit(comp_mode_p, second_ref_frame > INTRA_FRAME);
34965ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      this_rd = handle_inter_mode(cpi, x, tile, bsize,
34975ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                  tx_cache,
34985ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                  &rate2, &distortion2, &skippable,
34995ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                  &rate_y, &distortion_y,
35005ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                  &rate_uv, &distortion_uv,
35015ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                  &mode_excluded, &disable_skip,
35025ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                  &tmp_best_filter, frame_mv,
35035ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                  mi_row, mi_col,
35045ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                  single_newmv, &total_sse, best_rd);
35055ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (this_rd == INT64_MAX)
35065ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        continue;
35075ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
35081184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
35095ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (cm->comp_pred_mode == HYBRID_PREDICTION) {
35105ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      rate2 += compmode_cost;
35115ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
35121184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
35135ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // Estimate the reference frame signaling cost and add it
35145ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // to the rolling cost variable.
35155ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (second_ref_frame > INTRA_FRAME) {
35165ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      rate2 += ref_costs_comp[ref_frame];
35175ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    } else {
35185ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      rate2 += ref_costs_single[ref_frame];
35195ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
35205ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
35215ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (!disable_skip) {
35225ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      // Test for the condition where skip block will be activated
35235ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      // because there are no non zero coefficients and make any
35245ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      // necessary adjustment for rate. Ignore if skip is coded at
35255ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      // segment level as the cost wont have been added in.
35265ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      // Is Mb level skip allowed (i.e. not coded at segment level).
35275ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      const int mb_skip_allowed = !vp9_segfeature_active(seg, segment_id,
35285ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                                         SEG_LVL_SKIP);
35295ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
35305ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (skippable) {
35315ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        // Back out the coefficient coding costs
35325ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        rate2 -= (rate_y + rate_uv);
35335ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        // for best yrd calculation
35345ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        rate_uv = 0;
35355ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
35365ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if (mb_skip_allowed) {
35375ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          int prob_skip_cost;
35385ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
35395ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          // Cost the skip mb case
35405ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          vp9_prob skip_prob =
35415ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            vp9_get_pred_prob_mbskip(cm, xd);
35425ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
35435ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          if (skip_prob) {
35445ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            prob_skip_cost = vp9_cost_bit(skip_prob, 1);
35455ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            rate2 += prob_skip_cost;
35465ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          }
35475ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        }
35485ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      } else if (mb_skip_allowed && ref_frame != INTRA_FRAME && !xd->lossless) {
35495ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
35505ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
35515ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          // Add in the cost of the no skip flag.
35525ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          int prob_skip_cost = vp9_cost_bit(vp9_get_pred_prob_mbskip(cm, xd),
35535ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                            0);
35545ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          rate2 += prob_skip_cost;
35555ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        } else {
35565ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          // FIXME(rbultje) make this work for splitmv also
35575ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          int prob_skip_cost = vp9_cost_bit(vp9_get_pred_prob_mbskip(cm, xd),
35585ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                            1);
35595ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          rate2 += prob_skip_cost;
35605ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          distortion2 = total_sse;
35615ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          assert(total_sse >= 0);
35625ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          rate2 -= (rate_y + rate_uv);
35635ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          rate_y = 0;
35645ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          rate_uv = 0;
35655ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          this_skip2 = 1;
35665ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        }
35675ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      } else if (mb_skip_allowed) {
35685ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        // Add in the cost of the no skip flag.
35695ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        int prob_skip_cost = vp9_cost_bit(vp9_get_pred_prob_mbskip(cm, xd),
35705ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                          0);
35715ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        rate2 += prob_skip_cost;
35725ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      }
35735ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
35745ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      // Calculate the final RD estimate for this mode.
35755ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
35765ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
35775ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
35785ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // Keep record of best intra rd
35795ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (!is_inter_block(&xd->mi_8x8[0]->mbmi) &&
35805ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        this_rd < best_intra_rd) {
35815ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      best_intra_rd = this_rd;
35825ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      best_intra_mode = xd->mi_8x8[0]->mbmi.mode;
35835ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
35845ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
35855ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // Keep record of best inter rd with single reference
35865ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (is_inter_block(&xd->mi_8x8[0]->mbmi) &&
35875ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        !has_second_ref(&xd->mi_8x8[0]->mbmi) &&
35885ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        !mode_excluded && this_rd < best_inter_rd) {
35895ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      best_inter_rd = this_rd;
35905ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      best_inter_ref_frame = ref_frame;
35915ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
35925ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
35935ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (!disable_skip && ref_frame == INTRA_FRAME) {
35945ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      for (i = 0; i < NB_PREDICTION_TYPES; ++i)
35955ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        best_pred_rd[i] = MIN(best_pred_rd[i], this_rd);
35965ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
35975ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        best_filter_rd[i] = MIN(best_filter_rd[i], this_rd);
35985ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
35995ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
36005ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // Store the respective mode distortions for later use.
36015ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (mode_distortions[this_mode] == -1
36025ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        || distortion2 < mode_distortions[this_mode]) {
36035ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      mode_distortions[this_mode] = distortion2;
36045ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
36055ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (frame_distortions[ref_frame] == -1
36065ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        || distortion2 < frame_distortions[ref_frame]) {
36075ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      frame_distortions[ref_frame] = distortion2;
36085ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
36095ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
36105ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // Did this mode help.. i.e. is it the new best mode
36115ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (this_rd < best_rd || x->skip) {
36129b35249446b07f40ac5fcc3205f2c048616efacchkuang      int max_plane = MAX_MB_PLANE;
36135ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (!mode_excluded) {
36145ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        // Note index of best mode so far
36155ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        best_mode_index = mode_index;
36165ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
36175ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if (ref_frame == INTRA_FRAME) {
36185ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          /* required for left and above block mv */
36195ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          mbmi->mv[0].as_int = 0;
36209b35249446b07f40ac5fcc3205f2c048616efacchkuang          max_plane = 1;
36215ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        }
36225ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
36235ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        *returnrate = rate2;
36245ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        *returndistortion = distortion2;
36255ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        best_rd = this_rd;
36265ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        best_mbmode = *mbmi;
36275ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        best_skip2 = this_skip2;
36289b35249446b07f40ac5fcc3205f2c048616efacchkuang        if (!x->select_txfm_size)
36299b35249446b07f40ac5fcc3205f2c048616efacchkuang          swap_block_ptr(x, ctx, max_plane);
36305ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        vpx_memcpy(ctx->zcoeff_blk, x->zcoeff_blk[mbmi->tx_size],
36315ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                   sizeof(uint8_t) * ctx->num_4x4_blk);
36325ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
36335ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        // TODO(debargha): enhance this test with a better distortion prediction
36345ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        // based on qp, activity mask and history
36355ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if ((cpi->sf.mode_search_skip_flags & FLAG_EARLY_TERMINATE) &&
36365ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            (mode_index > MIN_EARLY_TERM_INDEX)) {
36375ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          const int qstep = xd->plane[0].dequant[1];
36385ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          // TODO(debargha): Enhance this by specializing for each mode_index
36395ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          int scale = 4;
36405ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          if (x->source_variance < UINT_MAX) {
36415ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            const int var_adjust = (x->source_variance < 16);
36425ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            scale -= var_adjust;
36435ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          }
36445ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          if (ref_frame > INTRA_FRAME &&
36455ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang              distortion2 * scale < qstep * qstep) {
36465ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            early_term = 1;
36475ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          }
36485ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        }
36495ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      }
36505ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
36515ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
36525ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    /* keep record of best compound/single-only prediction */
36535ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (!disable_skip && ref_frame != INTRA_FRAME) {
36545ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      int single_rd, hybrid_rd, single_rate, hybrid_rate;
36555ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
36565ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (cm->comp_pred_mode == HYBRID_PREDICTION) {
36575ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        single_rate = rate2 - compmode_cost;
36585ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        hybrid_rate = rate2;
36595ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      } else {
36605ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        single_rate = rate2;
36615ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        hybrid_rate = rate2 + compmode_cost;
36625ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      }
36635ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
36645ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
36655ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
36665ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
36675ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (second_ref_frame <= INTRA_FRAME &&
36685ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          single_rd < best_pred_rd[SINGLE_PREDICTION_ONLY]) {
36695ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        best_pred_rd[SINGLE_PREDICTION_ONLY] = single_rd;
36705ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      } else if (second_ref_frame > INTRA_FRAME &&
36715ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                 single_rd < best_pred_rd[COMP_PREDICTION_ONLY]) {
36725ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        best_pred_rd[COMP_PREDICTION_ONLY] = single_rd;
36735ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      }
36745ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (hybrid_rd < best_pred_rd[HYBRID_PREDICTION])
36755ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        best_pred_rd[HYBRID_PREDICTION] = hybrid_rd;
36765ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
36775ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
36785ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    /* keep record of best filter type */
36795ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (!mode_excluded && !disable_skip && ref_frame != INTRA_FRAME &&
36805ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        cm->mcomp_filter_type != BILINEAR) {
36815ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      int64_t ref = cpi->rd_filter_cache[cm->mcomp_filter_type == SWITCHABLE ?
36825ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                              SWITCHABLE_FILTERS : cm->mcomp_filter_type];
36835ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) {
36845ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        int64_t adj_rd;
36855ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        // In cases of poor prediction, filter_cache[] can contain really big
36865ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        // values, which actually are bigger than this_rd itself. This can
36875ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        // cause negative best_filter_rd[] values, which is obviously silly.
36885ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        // Therefore, if filter_cache < ref, we do an adjusted calculation.
36895ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if (cpi->rd_filter_cache[i] >= ref) {
36905ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          adj_rd = this_rd + cpi->rd_filter_cache[i] - ref;
36915ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        } else {
36925ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          // FIXME(rbultje) do this for comppsred also
36935ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          //
36945ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          // To prevent out-of-range computation in
36955ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          //    adj_rd = cpi->rd_filter_cache[i] * this_rd / ref
36965ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          // cpi->rd_filter_cache[i] / ref is converted to a 256 based ratio.
36975ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          int tmp = cpi->rd_filter_cache[i] * 256 / ref;
36985ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          adj_rd = (this_rd * tmp) >> 8;
36995ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        }
37005ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        best_filter_rd[i] = MIN(best_filter_rd[i], adj_rd);
37015ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      }
37025ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
37035ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
37045ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    /* keep record of best txfm size */
37055ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (bsize < BLOCK_32X32) {
37065ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (bsize < BLOCK_16X16)
37075ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        tx_cache[ALLOW_16X16] = tx_cache[ALLOW_8X8];
37085ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
37095ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      tx_cache[ALLOW_32X32] = tx_cache[ALLOW_16X16];
37105ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
37115ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (!mode_excluded && this_rd != INT64_MAX) {
37125ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      for (i = 0; i < TX_MODES && tx_cache[i] < INT64_MAX; i++) {
37135ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        int64_t adj_rd = INT64_MAX;
37145ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        adj_rd = this_rd + tx_cache[i] - tx_cache[cm->tx_mode];
37155ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
37165ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if (adj_rd < best_tx_rd[i])
37175ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          best_tx_rd[i] = adj_rd;
37185ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      }
37195ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
37205ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
37215ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (early_term)
37225ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      break;
37235ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
37245ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (x->skip && !comp_pred)
37255ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      break;
37265ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
37275ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
37285ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (best_rd >= best_rd_so_far)
37295ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    return INT64_MAX;
37305ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
37315ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // If we used an estimate for the uv intra rd in the loop above...
37325ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (cpi->sf.use_uv_intra_rd_estimate) {
37335ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // Do Intra UV best rd mode selection if best mode choice above was intra.
37345ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (vp9_mode_order[best_mode_index].ref_frame == INTRA_FRAME) {
37355ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      TX_SIZE uv_tx_size = get_uv_tx_size(mbmi);
37369b35249446b07f40ac5fcc3205f2c048616efacchkuang      rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv_intra[uv_tx_size],
37375ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                              &rate_uv_tokenonly[uv_tx_size],
37385ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                              &dist_uv[uv_tx_size],
37395ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                              &skip_uv[uv_tx_size],
37405ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                              bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize);
37415ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
37425ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
37435ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
37445ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // If we are using reference masking and the set mask flag is set then
37455ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // create the reference frame mask.
37465ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (cpi->sf.reference_masking && cpi->set_ref_frame_mask)
37475ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    cpi->ref_frame_mask = ~(1 << vp9_mode_order[best_mode_index].ref_frame);
37485ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
37495ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // Flag all modes that have a distortion thats > 2x the best we found at
37505ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // this level.
37515ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  for (mode_index = 0; mode_index < MB_MODE_COUNT; ++mode_index) {
37525ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (mode_index == NEARESTMV || mode_index == NEARMV || mode_index == NEWMV)
37535ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      continue;
37545ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
37555ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (mode_distortions[mode_index] > 2 * *returndistortion) {
37565ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      ctx->modes_with_high_error |= (1 << mode_index);
37575ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
37585ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
37595ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
37605ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // Flag all ref frames that have a distortion thats > 2x the best we found at
37615ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // this level.
37625ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  for (ref_frame = INTRA_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
37635ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (frame_distortions[ref_frame] > 2 * *returndistortion) {
37645ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      ctx->frames_with_high_error |= (1 << ref_frame);
37655ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
37665ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
37675ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
37685ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  assert((cm->mcomp_filter_type == SWITCHABLE) ||
37695ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang         (cm->mcomp_filter_type == best_mbmode.interp_filter) ||
37705ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang         (best_mbmode.ref_frame[0] == INTRA_FRAME));
37715ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
37725ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // Updating rd_thresh_freq_fact[] here means that the different
37735ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // partition/block sizes are handled independently based on the best
37745ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // choice for the current partition. It may well be better to keep a scaled
37755ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // best rd so far value and update rd_thresh_freq_fact based on the mode/size
37765ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // combination that wins out.
37775ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (cpi->sf.adaptive_rd_thresh) {
37785ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    for (mode_index = 0; mode_index < MAX_MODES; ++mode_index) {
37795ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (mode_index == best_mode_index) {
37805ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        cpi->rd_thresh_freq_fact[bsize][mode_index] -=
37815ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          (cpi->rd_thresh_freq_fact[bsize][mode_index] >> 3);
37825ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      } else {
37835ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        cpi->rd_thresh_freq_fact[bsize][mode_index] += RD_THRESH_INC;
37845ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if (cpi->rd_thresh_freq_fact[bsize][mode_index] >
37855ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            (cpi->sf.adaptive_rd_thresh * RD_THRESH_MAX_FACT)) {
37865ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          cpi->rd_thresh_freq_fact[bsize][mode_index] =
37875ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            cpi->sf.adaptive_rd_thresh * RD_THRESH_MAX_FACT;
37885ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        }
37895ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      }
37905ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
37915ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
37925ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
37935ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // macroblock modes
37945ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  *mbmi = best_mbmode;
37955ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  x->skip |= best_skip2;
37965ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
37975ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  for (i = 0; i < NB_PREDICTION_TYPES; ++i) {
37985ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (best_pred_rd[i] == INT64_MAX)
37995ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      best_pred_diff[i] = INT_MIN;
38005ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    else
38015ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      best_pred_diff[i] = best_rd - best_pred_rd[i];
38025ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
38035ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
38045ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (!x->skip) {
38055ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) {
38065ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (best_filter_rd[i] == INT64_MAX)
38075ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        best_filter_diff[i] = 0;
38085ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      else
38095ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        best_filter_diff[i] = best_rd - best_filter_rd[i];
38105ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
38115ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (cm->mcomp_filter_type == SWITCHABLE)
38125ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      assert(best_filter_diff[SWITCHABLE_FILTERS] == 0);
38135ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  } else {
38145ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    vp9_zero(best_filter_diff);
38155ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
38165ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
38175ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (!x->skip) {
38185ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    for (i = 0; i < TX_MODES; i++) {
38195ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (best_tx_rd[i] == INT64_MAX)
38205ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        best_tx_diff[i] = 0;
38215ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      else
38225ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        best_tx_diff[i] = best_rd - best_tx_rd[i];
38235ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
38245ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  } else {
38255ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    vp9_zero(best_tx_diff);
38265ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
38275ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
38285ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  set_scale_factors(xd, mbmi->ref_frame[0], mbmi->ref_frame[1],
38295ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                    scale_factor);
38305ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  store_coding_context(x, ctx, best_mode_index,
38315ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                       &mbmi->ref_mvs[mbmi->ref_frame[0]][0],
38325ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                       &mbmi->ref_mvs[mbmi->ref_frame[1] < 0 ? 0 :
38335ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                      mbmi->ref_frame[1]][0],
38345ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                       best_pred_diff, best_tx_diff, best_filter_diff);
38355ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
38365ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  return best_rd;
38375ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang}
38385ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
38395ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
38405ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangint64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x,
38415ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                      const TileInfo *const tile,
38425ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                      int mi_row, int mi_col,
38435ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                      int *returnrate,
38445ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                      int64_t *returndistortion,
38455ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                      BLOCK_SIZE bsize,
38465ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                      PICK_MODE_CONTEXT *ctx,
38475ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                      int64_t best_rd_so_far) {
38485ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  VP9_COMMON *cm = &cpi->common;
38495ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MACROBLOCKD *xd = &x->e_mbd;
38505ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi;
38515ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const struct segmentation *seg = &cm->seg;
38525ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  const BLOCK_SIZE block_size = get_plane_block_size(bsize, &xd->plane[0]);
38535ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MV_REFERENCE_FRAME ref_frame, second_ref_frame;
38545ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  unsigned char segment_id = mbmi->segment_id;
38555ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int comp_pred, i;
38565ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
38575ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  struct buf_2d yv12_mb[4][MAX_MB_PLANE];
38585ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  static const int flag_list[4] = { 0, VP9_LAST_FLAG, VP9_GOLD_FLAG,
38595ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                    VP9_ALT_FLAG };
38605ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int idx_list[4] = {0,
38615ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                     cpi->lst_fb_idx,
38625ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                     cpi->gld_fb_idx,
38635ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                     cpi->alt_fb_idx};
38645ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int64_t best_rd = best_rd_so_far;
38655ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int64_t best_yrd = best_rd_so_far;  // FIXME(rbultje) more precise
38665ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int64_t best_tx_rd[TX_MODES];
38675ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int64_t best_tx_diff[TX_MODES];
38685ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int64_t best_pred_diff[NB_PREDICTION_TYPES];
38695ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int64_t best_pred_rd[NB_PREDICTION_TYPES];
38705ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int64_t best_filter_rd[SWITCHABLE_FILTER_CONTEXTS];
38715ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS];
38725ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MB_MODE_INFO best_mbmode = { 0 };
38735ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int mode_index, best_mode_index = 0;
38745ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  unsigned int ref_costs_single[MAX_REF_FRAMES], ref_costs_comp[MAX_REF_FRAMES];
38755ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  vp9_prob comp_mode_p;
38765ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int64_t best_inter_rd = INT64_MAX;
38775ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MV_REFERENCE_FRAME best_inter_ref_frame = LAST_FRAME;
38785ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  INTERPOLATION_TYPE tmp_best_filter = SWITCHABLE;
38795ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int rate_uv_intra[TX_SIZES], rate_uv_tokenonly[TX_SIZES];
38805ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int64_t dist_uv[TX_SIZES];
38815ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int skip_uv[TX_SIZES];
38825ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  MB_PREDICTION_MODE mode_uv[TX_SIZES] = { 0 };
38835ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  struct scale_factors scale_factor[4];
38845ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  unsigned int ref_frame_mask = 0;
38855ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  unsigned int mode_mask = 0;
38865ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int intra_cost_penalty = 20 * vp9_dc_quant(cpi->common.base_qindex,
38875ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                             cpi->common.y_dc_delta_q);
38885ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int_mv seg_mvs[4][MAX_REF_FRAMES];
38895ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  b_mode_info best_bmodes[4];
38905ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int best_skip2 = 0;
38915ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
38929b35249446b07f40ac5fcc3205f2c048616efacchkuang  x->skip_encode = cpi->sf.skip_encode_frame && x->q_index < QIDX_SKIP_THRESH;
38935ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  vpx_memset(x->zcoeff_blk[TX_4X4], 0, 4);
38945ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
38955ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  for (i = 0; i < 4; i++) {
38965ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    int j;
38975ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    for (j = 0; j < MAX_REF_FRAMES; j++)
38985ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      seg_mvs[i][j].as_int = INVALID_MV;
38995ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
39005ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
39015ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  estimate_ref_frame_costs(cpi, segment_id, ref_costs_single, ref_costs_comp,
39025ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                           &comp_mode_p);
39035ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
39045ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  for (i = 0; i < NB_PREDICTION_TYPES; ++i)
39055ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    best_pred_rd[i] = INT64_MAX;
39065ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  for (i = 0; i < TX_MODES; i++)
39075ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    best_tx_rd[i] = INT64_MAX;
39085ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
39095ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    best_filter_rd[i] = INT64_MAX;
39105ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  for (i = 0; i < TX_SIZES; i++)
39115ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    rate_uv_intra[i] = INT_MAX;
39125ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
39135ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  *returnrate = INT_MAX;
39145ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
39155ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // Create a mask set to 1 for each reference frame used by a smaller
39165ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // resolution.
39175ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (cpi->sf.use_avoid_tested_higherror) {
39185ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    ref_frame_mask = 0;
39195ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    mode_mask = 0;
39205ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    ref_frame_mask = ~ref_frame_mask;
39215ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    mode_mask = ~mode_mask;
39225ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
39235ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
39245ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
39255ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (cpi->ref_frame_flags & flag_list[ref_frame]) {
39265ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      setup_buffer_inter(cpi, x, tile, idx_list[ref_frame], ref_frame,
39275ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                         block_size, mi_row, mi_col,
39285ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                         frame_mv[NEARESTMV], frame_mv[NEARMV],
39295ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                         yv12_mb, scale_factor);
39305ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
39315ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
39325ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    frame_mv[ZEROMV][ref_frame].as_int = 0;
39335ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  }
39345ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
39355ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  for (mode_index = 0; mode_index < MAX_REFS; ++mode_index) {
39365ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    int mode_excluded = 0;
39375ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    int64_t this_rd = INT64_MAX;
39385ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    int disable_skip = 0;
39395ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    int compmode_cost = 0;
39405ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    int rate2 = 0, rate_y = 0, rate_uv = 0;
39415ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
39425ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    int skippable = 0;
39435ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    int64_t tx_cache[TX_MODES];
39445ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    int i;
39455ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    int this_skip2 = 0;
39465ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    int64_t total_sse = INT_MAX;
39475ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    int early_term = 0;
39485ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
39495ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    for (i = 0; i < TX_MODES; ++i)
39505ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      tx_cache[i] = INT64_MAX;
39515ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
39525ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    x->skip = 0;
39535ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    ref_frame = vp9_ref_order[mode_index].ref_frame;
39545ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    second_ref_frame = vp9_ref_order[mode_index].second_ref_frame;
39555ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
39565ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // Look at the reference frame of the best mode so far and set the
39575ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // skip mask to look at a subset of the remaining modes.
39585ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (mode_index > 2 && cpi->sf.mode_skip_start < MAX_MODES) {
39595ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (mode_index == 3) {
39605ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        switch (vp9_ref_order[best_mode_index].ref_frame) {
39615ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          case INTRA_FRAME:
39625ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            cpi->mode_skip_mask = 0;
39635ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            break;
39645ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          case LAST_FRAME:
39655ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            cpi->mode_skip_mask = 0x0010;
39665ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            break;
39675ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          case GOLDEN_FRAME:
39685ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            cpi->mode_skip_mask = 0x0008;
39695ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            break;
39705ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          case ALTREF_FRAME:
39715ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            cpi->mode_skip_mask = 0x0000;
39725ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            break;
39735ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          case NONE:
39745ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          case MAX_REF_FRAMES:
39755ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            assert(!"Invalid Reference frame");
39765ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        }
39775ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      }
39785ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (cpi->mode_skip_mask & ((int64_t)1 << mode_index))
39795ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        continue;
39805ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
39815ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
39825ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // Skip if the current reference frame has been masked off
39835ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (cpi->sf.reference_masking && !cpi->set_ref_frame_mask &&
39845ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        (cpi->ref_frame_mask & (1 << ref_frame)))
39855ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      continue;
39865ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
39875ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // Test best rd so far against threshold for trying this mode.
39885ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if ((best_rd <
39895ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang         ((int64_t)cpi->rd_thresh_sub8x8[segment_id][bsize][mode_index] *
39905ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          cpi->rd_thresh_freq_sub8x8[bsize][mode_index] >> 5)) ||
39915ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        cpi->rd_thresh_sub8x8[segment_id][bsize][mode_index] == INT_MAX)
39925ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      continue;
39935ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
39945ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // Do not allow compound prediction if the segment level reference
39955ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // frame feature is in use as in this case there can only be one reference.
39965ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if ((second_ref_frame > INTRA_FRAME) &&
39975ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang         vp9_segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME))
39985ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      continue;
39995ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
40005ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    mbmi->ref_frame[0] = ref_frame;
40015ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    mbmi->ref_frame[1] = second_ref_frame;
40025ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
40035ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (!(ref_frame == INTRA_FRAME
40045ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        || (cpi->ref_frame_flags & flag_list[ref_frame]))) {
40055ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      continue;
40065ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
40075ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (!(second_ref_frame == NONE
40085ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        || (cpi->ref_frame_flags & flag_list[second_ref_frame]))) {
40095ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      continue;
40105ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
40115ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
40125ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    comp_pred = second_ref_frame > INTRA_FRAME;
40135ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (comp_pred) {
40145ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA)
40155ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if (vp9_ref_order[best_mode_index].ref_frame == INTRA_FRAME)
40165ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          continue;
40175ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_COMP_REFMISMATCH)
40185ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if (ref_frame != best_inter_ref_frame &&
40195ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            second_ref_frame != best_inter_ref_frame)
40205ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          continue;
40215ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
40225ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
40235ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // TODO(jingning, jkoleszar): scaling reference frame not supported for
40245ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // sub8x8 blocks.
40255ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (ref_frame > 0 &&
40265ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        vp9_is_scaled(scale_factor[ref_frame].sfc))
40275ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      continue;
40285ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
40295ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (second_ref_frame > 0 &&
40305ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        vp9_is_scaled(scale_factor[second_ref_frame].sfc))
40315ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      continue;
40325ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
40335ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    set_scale_factors(xd, ref_frame, second_ref_frame, scale_factor);
40345ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    mbmi->uv_mode = DC_PRED;
40355ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
40365ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // Evaluate all sub-pel filters irrespective of whether we can use
40375ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // them for this frame.
40385ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    mbmi->interp_filter = cm->mcomp_filter_type;
40395ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    vp9_setup_interp_filters(xd, mbmi->interp_filter, &cpi->common);
40405ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
40415ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (comp_pred) {
40425ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (!(cpi->ref_frame_flags & flag_list[second_ref_frame]))
40435ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        continue;
40445ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      set_scale_factors(xd, ref_frame, second_ref_frame, scale_factor);
40455ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
40465ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      mode_excluded = mode_excluded
40475ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                         ? mode_excluded
40485ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                         : cm->comp_pred_mode == SINGLE_PREDICTION_ONLY;
40495ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    } else {
40505ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (ref_frame != INTRA_FRAME && second_ref_frame != INTRA_FRAME) {
40515ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        mode_excluded =
40525ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            mode_excluded ?
40535ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                mode_excluded : cm->comp_pred_mode == COMP_PREDICTION_ONLY;
40545ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      }
40555ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
40565ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
40575ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // Select prediction reference frames.
40585ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    for (i = 0; i < MAX_MB_PLANE; i++) {
40595ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
40605ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (comp_pred)
40615ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
40625ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
40635ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
40645ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // If the segment reference frame feature is enabled....
40655ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // then do nothing if the current ref frame is not allowed..
40665ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (vp9_segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
40675ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        vp9_get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) !=
40685ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            (int)ref_frame) {
40695ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      continue;
40705ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // If the segment skip feature is enabled....
40715ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // then do nothing if the current mode is not allowed..
40725ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    } else if (vp9_segfeature_active(seg, segment_id, SEG_LVL_SKIP) &&
40735ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang               ref_frame != INTRA_FRAME) {
40745ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      continue;
40755ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // Disable this drop out case if the ref frame
40765ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // segment level feature is enabled for this segment. This is to
40775ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // prevent the possibility that we end up unable to pick any mode.
40785ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    } else if (!vp9_segfeature_active(seg, segment_id,
40795ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                      SEG_LVL_REF_FRAME)) {
40805ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
40815ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      // unless ARNR filtering is enabled in which case we want
40825ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      // an unfiltered alternative. We allow near/nearest as well
40835ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      // because they may result in zero-zero MVs but be cheaper.
40845ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (cpi->is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0))
40855ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        continue;
40865ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    }
40875ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
40885ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#ifdef MODE_TEST_HIT_STATS
40895ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // TEST/DEBUG CODE
40905ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // Keep a rcord of the number of test hits at each size
40915ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    cpi->mode_test_hits[bsize]++;
40925ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#endif
40935ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
40945ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (ref_frame == INTRA_FRAME) {
40955ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      int rate;
40965ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      mbmi->tx_size = TX_4X4;
40975ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate, &rate_y,
40985ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                       &distortion_y, best_rd) >= best_rd)
40995ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        continue;
41005ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      rate2 += rate;
41015ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      rate2 += intra_cost_penalty;
41025ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      distortion2 += distortion_y;
41035ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
41045ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (rate_uv_intra[TX_4X4] == INT_MAX) {
41059b35249446b07f40ac5fcc3205f2c048616efacchkuang        choose_intra_uv_mode(cpi, ctx, bsize, &rate_uv_intra[TX_4X4],
41065ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                             &rate_uv_tokenonly[TX_4X4],
41075ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                             &dist_uv[TX_4X4], &skip_uv[TX_4X4],
41085ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                             &mode_uv[TX_4X4]);
41095ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      }
41105ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      rate2 += rate_uv_intra[TX_4X4];
41115ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      rate_uv = rate_uv_tokenonly[TX_4X4];
41125ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      distortion2 += dist_uv[TX_4X4];
41135ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      distortion_uv = dist_uv[TX_4X4];
41145ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      mbmi->uv_mode = mode_uv[TX_4X4];
41155ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      tx_cache[ONLY_4X4] = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
41165ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      for (i = 0; i < TX_MODES; ++i)
41175ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        tx_cache[i] = tx_cache[ONLY_4X4];
41185ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    } else {
41195ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      int rate;
41205ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      int64_t distortion;
41215ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      int64_t this_rd_thresh;
41225ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      int64_t tmp_rd, tmp_best_rd = INT64_MAX, tmp_best_rdu = INT64_MAX;
41235ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      int tmp_best_rate = INT_MAX, tmp_best_ratey = INT_MAX;
41245ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      int64_t tmp_best_distortion = INT_MAX, tmp_best_sse, uv_sse;
41255ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      int tmp_best_skippable = 0;
41265ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      int switchable_filter_index;
41275ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      int_mv *second_ref = comp_pred ?
41285ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                             &mbmi->ref_mvs[second_ref_frame][0] : NULL;
41295ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      b_mode_info tmp_best_bmodes[16];
41305ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      MB_MODE_INFO tmp_best_mbmode;
41315ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      BEST_SEG_INFO bsi[SWITCHABLE_FILTERS];
41325ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      int pred_exists = 0;
41335ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      int uv_skippable;
41345ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
41355ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      this_rd_thresh = (ref_frame == LAST_FRAME) ?
41365ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          cpi->rd_thresh_sub8x8[segment_id][bsize][THR_LAST] :
41375ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          cpi->rd_thresh_sub8x8[segment_id][bsize][THR_ALTR];
41385ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      this_rd_thresh = (ref_frame == GOLDEN_FRAME) ?
41395ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          cpi->rd_thresh_sub8x8[segment_id][bsize][THR_GOLD] : this_rd_thresh;
41405ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      xd->mi_8x8[0]->mbmi.tx_size = TX_4X4;
41415ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
41425ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      cpi->rd_filter_cache[SWITCHABLE_FILTERS] = INT64_MAX;
41435ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (cm->mcomp_filter_type != BILINEAR) {
41445ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        tmp_best_filter = EIGHTTAP;
41455ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if (x->source_variance <
41465ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            cpi->sf.disable_filter_search_var_thresh) {
41475ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          tmp_best_filter = EIGHTTAP;
41485ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          vp9_zero(cpi->rd_filter_cache);
41495ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        } else {
41505ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          for (switchable_filter_index = 0;
41515ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang               switchable_filter_index < SWITCHABLE_FILTERS;
41525ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang               ++switchable_filter_index) {
41535ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            int newbest, rs;
41545ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            int64_t rs_rd;
41555ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            mbmi->interp_filter = switchable_filter_index;
41565ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            vp9_setup_interp_filters(xd, mbmi->interp_filter, &cpi->common);
41575ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
41585ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            tmp_rd = rd_pick_best_mbsegmentation(cpi, x, tile,
41591184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                                 &mbmi->ref_mvs[ref_frame][0],
41601184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                                 second_ref,
41611184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                                 best_yrd,
41621184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                                 &rate, &rate_y, &distortion,
41631184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                                 &skippable, &total_sse,
41641184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                                 (int)this_rd_thresh, seg_mvs,
41651184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                                 bsi, switchable_filter_index,
41661184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                                 mi_row, mi_col);
41671184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
41681184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            if (tmp_rd == INT64_MAX)
41691184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              continue;
41701184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            cpi->rd_filter_cache[switchable_filter_index] = tmp_rd;
41711184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            rs = get_switchable_rate(x);
41721184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0);
41731184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            cpi->rd_filter_cache[SWITCHABLE_FILTERS] =
41741184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                MIN(cpi->rd_filter_cache[SWITCHABLE_FILTERS],
41751184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                    tmp_rd + rs_rd);
41761184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            if (cm->mcomp_filter_type == SWITCHABLE)
41771184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              tmp_rd += rs_rd;
41781184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
41791184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            newbest = (tmp_rd < tmp_best_rd);
41801184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            if (newbest) {
418191037db265ecdd914a26e056cf69207b4f50924ehkuang              tmp_best_filter = mbmi->interp_filter;
41821184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              tmp_best_rd = tmp_rd;
4183ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            }
41841184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            if ((newbest && cm->mcomp_filter_type == SWITCHABLE) ||
41851184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                (mbmi->interp_filter == cm->mcomp_filter_type &&
41861184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                 cm->mcomp_filter_type != SWITCHABLE)) {
41871184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              tmp_best_rdu = tmp_rd;
41881184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              tmp_best_rate = rate;
41891184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              tmp_best_ratey = rate_y;
41901184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              tmp_best_distortion = distortion;
41911184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              tmp_best_sse = total_sse;
41921184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              tmp_best_skippable = skippable;
41931184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              tmp_best_mbmode = *mbmi;
41945ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang              for (i = 0; i < 4; i++) {
41955ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                tmp_best_bmodes[i] = xd->mi_8x8[0]->bmi[i];
41965ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                x->zcoeff_blk[TX_4X4][i] = !xd->plane[0].eobs[i];
41975ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang              }
41981184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              pred_exists = 1;
41991184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              if (switchable_filter_index == 0 &&
42001184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  cpi->sf.use_rd_breakout &&
42011184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  best_rd < INT64_MAX) {
42021184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                if (tmp_best_rdu / 2 > best_rd) {
42031184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  // skip searching the other filters if the first is
42041184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  // already substantially larger than the best so far
42051184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  tmp_best_filter = mbmi->interp_filter;
42061184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  tmp_best_rdu = INT64_MAX;
42071184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                  break;
42081184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                }
42091184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              }
42101184aebb761cbeac9124c37189a80a1a58f04b6bhkuang            }
42111184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          }  // switchable_filter_index loop
421291037db265ecdd914a26e056cf69207b4f50924ehkuang        }
42131184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      }
4214ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
421591037db265ecdd914a26e056cf69207b4f50924ehkuang      if (tmp_best_rdu == INT64_MAX)
421691037db265ecdd914a26e056cf69207b4f50924ehkuang        continue;
421791037db265ecdd914a26e056cf69207b4f50924ehkuang
4218ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      mbmi->interp_filter = (cm->mcomp_filter_type == SWITCHABLE ?
4219ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                             tmp_best_filter : cm->mcomp_filter_type);
4220ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      vp9_setup_interp_filters(xd, mbmi->interp_filter, &cpi->common);
4221ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (!pred_exists) {
4222ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        // Handles the special case when a filter that is not in the
4223ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        // switchable list (bilinear, 6-tap) is indicated at the frame level
42245ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        tmp_rd = rd_pick_best_mbsegmentation(cpi, x, tile,
4225f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                     &mbmi->ref_mvs[ref_frame][0],
422691037db265ecdd914a26e056cf69207b4f50924ehkuang                     second_ref,
422791037db265ecdd914a26e056cf69207b4f50924ehkuang                     best_yrd,
4228ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                     &rate, &rate_y, &distortion,
422991037db265ecdd914a26e056cf69207b4f50924ehkuang                     &skippable, &total_sse,
4230ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                     (int)this_rd_thresh, seg_mvs,
423191037db265ecdd914a26e056cf69207b4f50924ehkuang                     bsi, 0,
4232ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                     mi_row, mi_col);
423391037db265ecdd914a26e056cf69207b4f50924ehkuang        if (tmp_rd == INT64_MAX)
423491037db265ecdd914a26e056cf69207b4f50924ehkuang          continue;
4235ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      } else {
4236ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        if (cpi->common.mcomp_filter_type == SWITCHABLE) {
4237f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          int rs = get_switchable_rate(x);
4238ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          tmp_best_rdu -= RDCOST(x->rdmult, x->rddiv, rs, 0);
4239ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
4240ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        tmp_rd = tmp_best_rdu;
424191037db265ecdd914a26e056cf69207b4f50924ehkuang        total_sse = tmp_best_sse;
4242ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        rate = tmp_best_rate;
4243ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        rate_y = tmp_best_ratey;
4244ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        distortion = tmp_best_distortion;
4245ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        skippable = tmp_best_skippable;
4246ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        *mbmi = tmp_best_mbmode;
4247ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        for (i = 0; i < 4; i++)
42485ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          xd->mi_8x8[0]->bmi[i] = tmp_best_bmodes[i];
4249ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
4250ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4251ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      rate2 += rate;
4252ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      distortion2 += distortion;
4253ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4254ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (cpi->common.mcomp_filter_type == SWITCHABLE)
4255f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        rate2 += get_switchable_rate(x);
4256ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4257ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (!mode_excluded) {
42585ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if (comp_pred)
4259ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          mode_excluded = cpi->common.comp_pred_mode == SINGLE_PREDICTION_ONLY;
4260ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        else
4261ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          mode_excluded = cpi->common.comp_pred_mode == COMP_PREDICTION_ONLY;
4262ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
42635ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      compmode_cost = vp9_cost_bit(comp_mode_p, comp_pred);
426491037db265ecdd914a26e056cf69207b4f50924ehkuang
42651184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      tmp_best_rdu = best_rd -
42661184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          MIN(RDCOST(x->rdmult, x->rddiv, rate2, distortion2),
42671184aebb761cbeac9124c37189a80a1a58f04b6bhkuang              RDCOST(x->rdmult, x->rddiv, 0, total_sse));
42681184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
42691184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      if (tmp_best_rdu > 0) {
427091037db265ecdd914a26e056cf69207b4f50924ehkuang        // If even the 'Y' rd value of split is higher than best so far
427191037db265ecdd914a26e056cf69207b4f50924ehkuang        // then dont bother looking at UV
427291037db265ecdd914a26e056cf69207b4f50924ehkuang        vp9_build_inter_predictors_sbuv(&x->e_mbd, mi_row, mi_col,
42731184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                        BLOCK_8X8);
42745ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        super_block_uvrd(cpi, x, &rate_uv, &distortion_uv, &uv_skippable,
42751184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                         &uv_sse, BLOCK_8X8, tmp_best_rdu);
42761184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        if (rate_uv == INT_MAX)
42771184aebb761cbeac9124c37189a80a1a58f04b6bhkuang          continue;
427891037db265ecdd914a26e056cf69207b4f50924ehkuang        rate2 += rate_uv;
427991037db265ecdd914a26e056cf69207b4f50924ehkuang        distortion2 += distortion_uv;
428091037db265ecdd914a26e056cf69207b4f50924ehkuang        skippable = skippable && uv_skippable;
428191037db265ecdd914a26e056cf69207b4f50924ehkuang        total_sse += uv_sse;
428291037db265ecdd914a26e056cf69207b4f50924ehkuang
4283f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        tx_cache[ONLY_4X4] = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
4284f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        for (i = 0; i < TX_MODES; ++i)
4285f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          tx_cache[i] = tx_cache[ONLY_4X4];
428691037db265ecdd914a26e056cf69207b4f50924ehkuang      }
4287ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
4288ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4289ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (cpi->common.comp_pred_mode == HYBRID_PREDICTION) {
4290ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      rate2 += compmode_cost;
4291ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
4292ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4293ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Estimate the reference frame signaling cost and add it
4294ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // to the rolling cost variable.
4295f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    if (second_ref_frame > INTRA_FRAME) {
4296f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      rate2 += ref_costs_comp[ref_frame];
4297ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    } else {
4298f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      rate2 += ref_costs_single[ref_frame];
4299ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
4300ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4301ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (!disable_skip) {
4302ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // Test for the condition where skip block will be activated
4303ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // because there are no non zero coefficients and make any
4304ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // necessary adjustment for rate. Ignore if skip is coded at
4305ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // segment level as the cost wont have been added in.
4306ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // Is Mb level skip allowed (i.e. not coded at segment level).
4307f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      const int mb_skip_allowed = !vp9_segfeature_active(seg, segment_id,
430891037db265ecdd914a26e056cf69207b4f50924ehkuang                                                         SEG_LVL_SKIP);
4309ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
43105ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      if (mb_skip_allowed && ref_frame != INTRA_FRAME && !xd->lossless) {
431191037db265ecdd914a26e056cf69207b4f50924ehkuang        if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
431291037db265ecdd914a26e056cf69207b4f50924ehkuang            RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
431391037db265ecdd914a26e056cf69207b4f50924ehkuang          // Add in the cost of the no skip flag.
431491037db265ecdd914a26e056cf69207b4f50924ehkuang          int prob_skip_cost = vp9_cost_bit(vp9_get_pred_prob_mbskip(cm, xd),
431591037db265ecdd914a26e056cf69207b4f50924ehkuang                                            0);
431691037db265ecdd914a26e056cf69207b4f50924ehkuang          rate2 += prob_skip_cost;
431791037db265ecdd914a26e056cf69207b4f50924ehkuang        } else {
431891037db265ecdd914a26e056cf69207b4f50924ehkuang          // FIXME(rbultje) make this work for splitmv also
431991037db265ecdd914a26e056cf69207b4f50924ehkuang          int prob_skip_cost = vp9_cost_bit(vp9_get_pred_prob_mbskip(cm, xd),
432091037db265ecdd914a26e056cf69207b4f50924ehkuang                                            1);
432191037db265ecdd914a26e056cf69207b4f50924ehkuang          rate2 += prob_skip_cost;
432291037db265ecdd914a26e056cf69207b4f50924ehkuang          distortion2 = total_sse;
432391037db265ecdd914a26e056cf69207b4f50924ehkuang          assert(total_sse >= 0);
432491037db265ecdd914a26e056cf69207b4f50924ehkuang          rate2 -= (rate_y + rate_uv);
432591037db265ecdd914a26e056cf69207b4f50924ehkuang          rate_y = 0;
432691037db265ecdd914a26e056cf69207b4f50924ehkuang          rate_uv = 0;
432791037db265ecdd914a26e056cf69207b4f50924ehkuang          this_skip2 = 1;
432891037db265ecdd914a26e056cf69207b4f50924ehkuang        }
4329ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      } else if (mb_skip_allowed) {
4330ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        // Add in the cost of the no skip flag.
433191037db265ecdd914a26e056cf69207b4f50924ehkuang        int prob_skip_cost = vp9_cost_bit(vp9_get_pred_prob_mbskip(cm, xd),
433291037db265ecdd914a26e056cf69207b4f50924ehkuang                                          0);
4333ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        rate2 += prob_skip_cost;
4334ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
4335ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4336ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // Calculate the final RD estimate for this mode.
4337ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
4338ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
4339ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
434091037db265ecdd914a26e056cf69207b4f50924ehkuang    // Keep record of best inter rd with single reference
43415ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (xd->mi_8x8[0]->mbmi.ref_frame[0] > INTRA_FRAME &&
43425ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        xd->mi_8x8[0]->mbmi.ref_frame[1] == NONE &&
434391037db265ecdd914a26e056cf69207b4f50924ehkuang        !mode_excluded &&
434491037db265ecdd914a26e056cf69207b4f50924ehkuang        this_rd < best_inter_rd) {
434591037db265ecdd914a26e056cf69207b4f50924ehkuang      best_inter_rd = this_rd;
434691037db265ecdd914a26e056cf69207b4f50924ehkuang      best_inter_ref_frame = ref_frame;
4347ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
4348ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4349f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    if (!disable_skip && ref_frame == INTRA_FRAME) {
4350ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      for (i = 0; i < NB_PREDICTION_TYPES; ++i)
4351ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        best_pred_rd[i] = MIN(best_pred_rd[i], this_rd);
43525ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
435391037db265ecdd914a26e056cf69207b4f50924ehkuang        best_filter_rd[i] = MIN(best_filter_rd[i], this_rd);
4354ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
4355ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4356ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Did this mode help.. i.e. is it the new best mode
4357ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (this_rd < best_rd || x->skip) {
4358ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (!mode_excluded) {
43599b35249446b07f40ac5fcc3205f2c048616efacchkuang        int max_plane = MAX_MB_PLANE;
4360ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        // Note index of best mode so far
4361ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        best_mode_index = mode_index;
4362ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4363ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        if (ref_frame == INTRA_FRAME) {
4364ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          /* required for left and above block mv */
4365ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          mbmi->mv[0].as_int = 0;
43669b35249446b07f40ac5fcc3205f2c048616efacchkuang          max_plane = 1;
4367ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
4368ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4369ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        *returnrate = rate2;
4370ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        *returndistortion = distortion2;
4371ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        best_rd = this_rd;
437291037db265ecdd914a26e056cf69207b4f50924ehkuang        best_yrd = best_rd -
437391037db265ecdd914a26e056cf69207b4f50924ehkuang                   RDCOST(x->rdmult, x->rddiv, rate_uv, distortion_uv);
4374ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        best_mbmode = *mbmi;
437591037db265ecdd914a26e056cf69207b4f50924ehkuang        best_skip2 = this_skip2;
43769b35249446b07f40ac5fcc3205f2c048616efacchkuang        if (!x->select_txfm_size)
43779b35249446b07f40ac5fcc3205f2c048616efacchkuang          swap_block_ptr(x, ctx, max_plane);
43785ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        vpx_memcpy(ctx->zcoeff_blk, x->zcoeff_blk[mbmi->tx_size],
43795ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                   sizeof(uint8_t) * ctx->num_4x4_blk);
4380ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
43815ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        for (i = 0; i < 4; i++)
43825ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          best_bmodes[i] = xd->mi_8x8[0]->bmi[i];
438391037db265ecdd914a26e056cf69207b4f50924ehkuang
438491037db265ecdd914a26e056cf69207b4f50924ehkuang        // TODO(debargha): enhance this test with a better distortion prediction
438591037db265ecdd914a26e056cf69207b4f50924ehkuang        // based on qp, activity mask and history
43865ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if ((cpi->sf.mode_search_skip_flags & FLAG_EARLY_TERMINATE) &&
43875ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            (mode_index > MIN_EARLY_TERM_INDEX)) {
4388f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          const int qstep = xd->plane[0].dequant[1];
4389f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          // TODO(debargha): Enhance this by specializing for each mode_index
4390f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          int scale = 4;
4391f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          if (x->source_variance < UINT_MAX) {
4392f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang            const int var_adjust = (x->source_variance < 16);
4393f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang            scale -= var_adjust;
4394f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          }
4395f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          if (ref_frame > INTRA_FRAME &&
4396f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang              distortion2 * scale < qstep * qstep) {
439791037db265ecdd914a26e056cf69207b4f50924ehkuang            early_term = 1;
4398f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          }
4399f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        }
4400ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
4401ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
4402ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4403ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    /* keep record of best compound/single-only prediction */
4404f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    if (!disable_skip && ref_frame != INTRA_FRAME) {
4405ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      int single_rd, hybrid_rd, single_rate, hybrid_rate;
4406ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4407ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (cpi->common.comp_pred_mode == HYBRID_PREDICTION) {
4408ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        single_rate = rate2 - compmode_cost;
4409ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        hybrid_rate = rate2;
4410ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      } else {
4411ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        single_rate = rate2;
4412ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        hybrid_rate = rate2 + compmode_cost;
4413ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
4414ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4415ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
4416ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
4417ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4418f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      if (second_ref_frame <= INTRA_FRAME &&
4419ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          single_rd < best_pred_rd[SINGLE_PREDICTION_ONLY]) {
4420ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        best_pred_rd[SINGLE_PREDICTION_ONLY] = single_rd;
4421f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      } else if (second_ref_frame > INTRA_FRAME &&
4422ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                 single_rd < best_pred_rd[COMP_PREDICTION_ONLY]) {
4423ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        best_pred_rd[COMP_PREDICTION_ONLY] = single_rd;
4424ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
4425ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (hybrid_rd < best_pred_rd[HYBRID_PREDICTION])
4426ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        best_pred_rd[HYBRID_PREDICTION] = hybrid_rd;
4427ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
4428ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
442991037db265ecdd914a26e056cf69207b4f50924ehkuang    /* keep record of best filter type */
4430f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    if (!mode_excluded && !disable_skip && ref_frame != INTRA_FRAME &&
443191037db265ecdd914a26e056cf69207b4f50924ehkuang        cm->mcomp_filter_type != BILINEAR) {
443291037db265ecdd914a26e056cf69207b4f50924ehkuang      int64_t ref = cpi->rd_filter_cache[cm->mcomp_filter_type == SWITCHABLE ?
44331184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                              SWITCHABLE_FILTERS : cm->mcomp_filter_type];
44345ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) {
443591037db265ecdd914a26e056cf69207b4f50924ehkuang        int64_t adj_rd;
443691037db265ecdd914a26e056cf69207b4f50924ehkuang        // In cases of poor prediction, filter_cache[] can contain really big
443791037db265ecdd914a26e056cf69207b4f50924ehkuang        // values, which actually are bigger than this_rd itself. This can
443891037db265ecdd914a26e056cf69207b4f50924ehkuang        // cause negative best_filter_rd[] values, which is obviously silly.
443991037db265ecdd914a26e056cf69207b4f50924ehkuang        // Therefore, if filter_cache < ref, we do an adjusted calculation.
444091037db265ecdd914a26e056cf69207b4f50924ehkuang        if (cpi->rd_filter_cache[i] >= ref)
444191037db265ecdd914a26e056cf69207b4f50924ehkuang          adj_rd = this_rd + cpi->rd_filter_cache[i] - ref;
444291037db265ecdd914a26e056cf69207b4f50924ehkuang        else  // FIXME(rbultje) do this for comppred also
444391037db265ecdd914a26e056cf69207b4f50924ehkuang          adj_rd = this_rd - (ref - cpi->rd_filter_cache[i]) * this_rd / ref;
444491037db265ecdd914a26e056cf69207b4f50924ehkuang        best_filter_rd[i] = MIN(best_filter_rd[i], adj_rd);
444591037db265ecdd914a26e056cf69207b4f50924ehkuang      }
444691037db265ecdd914a26e056cf69207b4f50924ehkuang    }
444791037db265ecdd914a26e056cf69207b4f50924ehkuang
4448ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    /* keep record of best txfm size */
4449f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    if (bsize < BLOCK_32X32) {
4450f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      if (bsize < BLOCK_16X16) {
44515ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        tx_cache[ALLOW_8X8] = tx_cache[ONLY_4X4];
4452f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        tx_cache[ALLOW_16X16] = tx_cache[ALLOW_8X8];
4453ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
4454f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      tx_cache[ALLOW_32X32] = tx_cache[ALLOW_16X16];
4455ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
4456ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (!mode_excluded && this_rd != INT64_MAX) {
44571184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      for (i = 0; i < TX_MODES && tx_cache[i] < INT64_MAX; i++) {
4458ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        int64_t adj_rd = INT64_MAX;
44595ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if (ref_frame > INTRA_FRAME)
4460f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          adj_rd = this_rd + tx_cache[i] - tx_cache[cm->tx_mode];
44615ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        else
4462ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          adj_rd = this_rd;
4463ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4464f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        if (adj_rd < best_tx_rd[i])
4465f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang          best_tx_rd[i] = adj_rd;
4466ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
4467ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
4468ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
446991037db265ecdd914a26e056cf69207b4f50924ehkuang    if (early_term)
447091037db265ecdd914a26e056cf69207b4f50924ehkuang      break;
447191037db265ecdd914a26e056cf69207b4f50924ehkuang
4472f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    if (x->skip && !comp_pred)
4473ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      break;
4474ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
4475f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang
447691037db265ecdd914a26e056cf69207b4f50924ehkuang  if (best_rd >= best_rd_so_far)
447791037db265ecdd914a26e056cf69207b4f50924ehkuang    return INT64_MAX;
447891037db265ecdd914a26e056cf69207b4f50924ehkuang
447991037db265ecdd914a26e056cf69207b4f50924ehkuang  // If we used an estimate for the uv intra rd in the loop above...
448091037db265ecdd914a26e056cf69207b4f50924ehkuang  if (cpi->sf.use_uv_intra_rd_estimate) {
448191037db265ecdd914a26e056cf69207b4f50924ehkuang    // Do Intra UV best rd mode selection if best mode choice above was intra.
44825ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    if (vp9_ref_order[best_mode_index].ref_frame == INTRA_FRAME) {
448391037db265ecdd914a26e056cf69207b4f50924ehkuang      TX_SIZE uv_tx_size = get_uv_tx_size(mbmi);
44849b35249446b07f40ac5fcc3205f2c048616efacchkuang      rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv_intra[uv_tx_size],
448591037db265ecdd914a26e056cf69207b4f50924ehkuang                              &rate_uv_tokenonly[uv_tx_size],
448691037db265ecdd914a26e056cf69207b4f50924ehkuang                              &dist_uv[uv_tx_size],
448791037db265ecdd914a26e056cf69207b4f50924ehkuang                              &skip_uv[uv_tx_size],
44885ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                              BLOCK_8X8);
448991037db265ecdd914a26e056cf69207b4f50924ehkuang    }
449091037db265ecdd914a26e056cf69207b4f50924ehkuang  }
449191037db265ecdd914a26e056cf69207b4f50924ehkuang
449291037db265ecdd914a26e056cf69207b4f50924ehkuang  // If we are using reference masking and the set mask flag is set then
449391037db265ecdd914a26e056cf69207b4f50924ehkuang  // create the reference frame mask.
449491037db265ecdd914a26e056cf69207b4f50924ehkuang  if (cpi->sf.reference_masking && cpi->set_ref_frame_mask)
44955ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    cpi->ref_frame_mask = ~(1 << vp9_ref_order[best_mode_index].ref_frame);
4496ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
44971184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  if (best_rd == INT64_MAX && bsize < BLOCK_8X8) {
4498ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    *returnrate = INT_MAX;
4499ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    *returndistortion = INT_MAX;
4500ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    return best_rd;
4501ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
4502ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4503ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  assert((cm->mcomp_filter_type == SWITCHABLE) ||
4504ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang         (cm->mcomp_filter_type == best_mbmode.interp_filter) ||
4505ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang         (best_mbmode.ref_frame[0] == INTRA_FRAME));
4506ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4507f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  // Updating rd_thresh_freq_fact[] here means that the different
4508ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // partition/block sizes are handled independently based on the best
4509ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // choice for the current partition. It may well be better to keep a scaled
4510ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // best rd so far value and update rd_thresh_freq_fact based on the mode/size
4511ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // combination that wins out.
451291037db265ecdd914a26e056cf69207b4f50924ehkuang  if (cpi->sf.adaptive_rd_thresh) {
45135ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    for (mode_index = 0; mode_index < MAX_REFS; ++mode_index) {
4514ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (mode_index == best_mode_index) {
45155ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        cpi->rd_thresh_freq_sub8x8[bsize][mode_index] -=
45165ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          (cpi->rd_thresh_freq_sub8x8[bsize][mode_index] >> 3);
4517ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      } else {
45185ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        cpi->rd_thresh_freq_sub8x8[bsize][mode_index] += RD_THRESH_INC;
45195ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        if (cpi->rd_thresh_freq_sub8x8[bsize][mode_index] >
45205ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            (cpi->sf.adaptive_rd_thresh * RD_THRESH_MAX_FACT)) {
45215ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang          cpi->rd_thresh_freq_sub8x8[bsize][mode_index] =
45225ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang            cpi->sf.adaptive_rd_thresh * RD_THRESH_MAX_FACT;
4523ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
4524ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
4525ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
4526ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
4527ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4528ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // macroblock modes
4529ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  *mbmi = best_mbmode;
453091037db265ecdd914a26e056cf69207b4f50924ehkuang  x->skip |= best_skip2;
45315ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (best_mbmode.ref_frame[0] == INTRA_FRAME) {
4532ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (i = 0; i < 4; i++)
45335ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      xd->mi_8x8[0]->bmi[i].as_mode = best_bmodes[i].as_mode;
45345ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  } else {
45355ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    for (i = 0; i < 4; ++i)
45365ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      vpx_memcpy(&xd->mi_8x8[0]->bmi[i], &best_bmodes[i], sizeof(b_mode_info));
4537ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
45385ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    mbmi->mv[0].as_int = xd->mi_8x8[0]->bmi[3].as_mv[0].as_int;
45395ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    mbmi->mv[1].as_int = xd->mi_8x8[0]->bmi[3].as_mv[1].as_int;
4540ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
4541ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4542ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0; i < NB_PREDICTION_TYPES; ++i) {
4543ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (best_pred_rd[i] == INT64_MAX)
4544ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      best_pred_diff[i] = INT_MIN;
4545ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    else
4546ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      best_pred_diff[i] = best_rd - best_pred_rd[i];
4547ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
4548ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4549ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (!x->skip) {
45505ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) {
455191037db265ecdd914a26e056cf69207b4f50924ehkuang      if (best_filter_rd[i] == INT64_MAX)
455291037db265ecdd914a26e056cf69207b4f50924ehkuang        best_filter_diff[i] = 0;
455391037db265ecdd914a26e056cf69207b4f50924ehkuang      else
455491037db265ecdd914a26e056cf69207b4f50924ehkuang        best_filter_diff[i] = best_rd - best_filter_rd[i];
455591037db265ecdd914a26e056cf69207b4f50924ehkuang    }
455691037db265ecdd914a26e056cf69207b4f50924ehkuang    if (cm->mcomp_filter_type == SWITCHABLE)
45571184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      assert(best_filter_diff[SWITCHABLE_FILTERS] == 0);
455891037db265ecdd914a26e056cf69207b4f50924ehkuang  } else {
45595ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    vp9_zero(best_filter_diff);
456091037db265ecdd914a26e056cf69207b4f50924ehkuang  }
456191037db265ecdd914a26e056cf69207b4f50924ehkuang
456291037db265ecdd914a26e056cf69207b4f50924ehkuang  if (!x->skip) {
4563f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    for (i = 0; i < TX_MODES; i++) {
4564f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang      if (best_tx_rd[i] == INT64_MAX)
4565f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        best_tx_diff[i] = 0;
4566ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      else
4567f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang        best_tx_diff[i] = best_rd - best_tx_rd[i];
4568ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
4569ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  } else {
45705ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    vp9_zero(best_tx_diff);
4571ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
4572ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4573ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  set_scale_factors(xd, mbmi->ref_frame[0], mbmi->ref_frame[1],
4574ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                    scale_factor);
4575ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  store_coding_context(x, ctx, best_mode_index,
4576ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                       &mbmi->ref_mvs[mbmi->ref_frame[0]][0],
4577ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                       &mbmi->ref_mvs[mbmi->ref_frame[1] < 0 ? 0 :
4578ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                      mbmi->ref_frame[1]][0],
4579f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang                       best_pred_diff, best_tx_diff, best_filter_diff);
4580ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4581ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return best_rd;
4582ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
4583