1233d2500723e5594f3e7c70896ffeeef32b9c950ywan/*
2233d2500723e5594f3e7c70896ffeeef32b9c950ywan *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3233d2500723e5594f3e7c70896ffeeef32b9c950ywan *
4233d2500723e5594f3e7c70896ffeeef32b9c950ywan *  Use of this source code is governed by a BSD-style license
5233d2500723e5594f3e7c70896ffeeef32b9c950ywan *  that can be found in the LICENSE file in the root of the source
6233d2500723e5594f3e7c70896ffeeef32b9c950ywan *  tree. An additional intellectual property rights grant can be found
7233d2500723e5594f3e7c70896ffeeef32b9c950ywan *  in the file PATENTS.  All contributing project authors may
8233d2500723e5594f3e7c70896ffeeef32b9c950ywan *  be found in the AUTHORS file in the root of the source tree.
9233d2500723e5594f3e7c70896ffeeef32b9c950ywan */
10233d2500723e5594f3e7c70896ffeeef32b9c950ywan
11233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <assert.h>
12233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <limits.h>
13233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <math.h>
14233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <stdio.h>
15233d2500723e5594f3e7c70896ffeeef32b9c950ywan
16233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "./vp9_rtcd.h"
17233d2500723e5594f3e7c70896ffeeef32b9c950ywan
18233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vpx_mem/vpx_mem.h"
19233d2500723e5594f3e7c70896ffeeef32b9c950ywan
20233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/common/vp9_common.h"
21233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/common/vp9_entropy.h"
22233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/common/vp9_entropymode.h"
23233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/common/vp9_idct.h"
24233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/common/vp9_mvref_common.h"
25233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/common/vp9_pragmas.h"
26233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/common/vp9_pred_common.h"
27233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/common/vp9_quant_common.h"
28233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/common/vp9_reconinter.h"
29233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/common/vp9_reconintra.h"
30233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/common/vp9_seg_common.h"
31233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/common/vp9_systemdependent.h"
32233d2500723e5594f3e7c70896ffeeef32b9c950ywan
33233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/encoder/vp9_cost.h"
34233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/encoder/vp9_encodemb.h"
35233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/encoder/vp9_encodemv.h"
36233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/encoder/vp9_mcomp.h"
37233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/encoder/vp9_onyx_int.h"
38233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/encoder/vp9_quantize.h"
39233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/encoder/vp9_ratectrl.h"
40233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/encoder/vp9_rdopt.h"
41233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/encoder/vp9_tokenize.h"
42233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/encoder/vp9_variance.h"
43233d2500723e5594f3e7c70896ffeeef32b9c950ywan
44233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define RD_THRESH_MAX_FACT 64
45233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define RD_THRESH_INC      1
46233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define RD_THRESH_POW      1.25
47233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define RD_MULT_EPB_RATIO  64
48233d2500723e5594f3e7c70896ffeeef32b9c950ywan
49233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* Factor to weigh the rate for switchable interp filters */
50233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define SWITCHABLE_INTERP_RATE_FACTOR 1
51233d2500723e5594f3e7c70896ffeeef32b9c950ywan
52233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define LAST_FRAME_MODE_MASK    0xFFEDCD60
53233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define GOLDEN_FRAME_MODE_MASK  0xFFDA3BB0
54233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ALT_REF_MODE_MASK       0xFFC648D0
55233d2500723e5594f3e7c70896ffeeef32b9c950ywan
56233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define MIN_EARLY_TERM_INDEX    3
57233d2500723e5594f3e7c70896ffeeef32b9c950ywan
58233d2500723e5594f3e7c70896ffeeef32b9c950ywantypedef struct {
59233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MB_PREDICTION_MODE mode;
60233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MV_REFERENCE_FRAME ref_frame[2];
61233d2500723e5594f3e7c70896ffeeef32b9c950ywan} MODE_DEFINITION;
62233d2500723e5594f3e7c70896ffeeef32b9c950ywan
63233d2500723e5594f3e7c70896ffeeef32b9c950ywantypedef struct {
64233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MV_REFERENCE_FRAME ref_frame[2];
65233d2500723e5594f3e7c70896ffeeef32b9c950ywan} REF_DEFINITION;
66233d2500723e5594f3e7c70896ffeeef32b9c950ywan
67233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct rdcost_block_args {
68233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MACROBLOCK *x;
69233d2500723e5594f3e7c70896ffeeef32b9c950ywan  ENTROPY_CONTEXT t_above[16];
70233d2500723e5594f3e7c70896ffeeef32b9c950ywan  ENTROPY_CONTEXT t_left[16];
71233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int rate;
72233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t dist;
73233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t sse;
74233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int this_rate;
75233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t this_dist;
76233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t this_sse;
77233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t this_rd;
78233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t best_rd;
79233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int skip;
80233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int use_fast_coef_costing;
81233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const scan_order *so;
82233d2500723e5594f3e7c70896ffeeef32b9c950ywan};
83233d2500723e5594f3e7c70896ffeeef32b9c950ywan
84233d2500723e5594f3e7c70896ffeeef32b9c950ywanconst MODE_DEFINITION vp9_mode_order[MAX_MODES] = {
85233d2500723e5594f3e7c70896ffeeef32b9c950ywan  {NEARESTMV, {LAST_FRAME,   NONE}},
86233d2500723e5594f3e7c70896ffeeef32b9c950ywan  {NEARESTMV, {ALTREF_FRAME, NONE}},
87233d2500723e5594f3e7c70896ffeeef32b9c950ywan  {NEARESTMV, {GOLDEN_FRAME, NONE}},
88233d2500723e5594f3e7c70896ffeeef32b9c950ywan
89233d2500723e5594f3e7c70896ffeeef32b9c950ywan  {DC_PRED,   {INTRA_FRAME,  NONE}},
90233d2500723e5594f3e7c70896ffeeef32b9c950ywan
91233d2500723e5594f3e7c70896ffeeef32b9c950ywan  {NEWMV,     {LAST_FRAME,   NONE}},
92233d2500723e5594f3e7c70896ffeeef32b9c950ywan  {NEWMV,     {ALTREF_FRAME, NONE}},
93233d2500723e5594f3e7c70896ffeeef32b9c950ywan  {NEWMV,     {GOLDEN_FRAME, NONE}},
94233d2500723e5594f3e7c70896ffeeef32b9c950ywan
95233d2500723e5594f3e7c70896ffeeef32b9c950ywan  {NEARMV,    {LAST_FRAME,   NONE}},
96233d2500723e5594f3e7c70896ffeeef32b9c950ywan  {NEARMV,    {ALTREF_FRAME, NONE}},
97233d2500723e5594f3e7c70896ffeeef32b9c950ywan  {NEARESTMV, {LAST_FRAME,   ALTREF_FRAME}},
98233d2500723e5594f3e7c70896ffeeef32b9c950ywan  {NEARESTMV, {GOLDEN_FRAME, ALTREF_FRAME}},
99233d2500723e5594f3e7c70896ffeeef32b9c950ywan
100233d2500723e5594f3e7c70896ffeeef32b9c950ywan  {TM_PRED,   {INTRA_FRAME,  NONE}},
101233d2500723e5594f3e7c70896ffeeef32b9c950ywan
102233d2500723e5594f3e7c70896ffeeef32b9c950ywan  {NEARMV,    {LAST_FRAME,   ALTREF_FRAME}},
103233d2500723e5594f3e7c70896ffeeef32b9c950ywan  {NEWMV,     {LAST_FRAME,   ALTREF_FRAME}},
104233d2500723e5594f3e7c70896ffeeef32b9c950ywan  {NEARMV,    {GOLDEN_FRAME, NONE}},
105233d2500723e5594f3e7c70896ffeeef32b9c950ywan  {NEARMV,    {GOLDEN_FRAME, ALTREF_FRAME}},
106233d2500723e5594f3e7c70896ffeeef32b9c950ywan  {NEWMV,     {GOLDEN_FRAME, ALTREF_FRAME}},
107233d2500723e5594f3e7c70896ffeeef32b9c950ywan
108233d2500723e5594f3e7c70896ffeeef32b9c950ywan  {ZEROMV,    {LAST_FRAME,   NONE}},
109233d2500723e5594f3e7c70896ffeeef32b9c950ywan  {ZEROMV,    {GOLDEN_FRAME, NONE}},
110233d2500723e5594f3e7c70896ffeeef32b9c950ywan  {ZEROMV,    {ALTREF_FRAME, NONE}},
111233d2500723e5594f3e7c70896ffeeef32b9c950ywan  {ZEROMV,    {LAST_FRAME,   ALTREF_FRAME}},
112233d2500723e5594f3e7c70896ffeeef32b9c950ywan  {ZEROMV,    {GOLDEN_FRAME, ALTREF_FRAME}},
113233d2500723e5594f3e7c70896ffeeef32b9c950ywan
114233d2500723e5594f3e7c70896ffeeef32b9c950ywan  {H_PRED,    {INTRA_FRAME,  NONE}},
115233d2500723e5594f3e7c70896ffeeef32b9c950ywan  {V_PRED,    {INTRA_FRAME,  NONE}},
116233d2500723e5594f3e7c70896ffeeef32b9c950ywan  {D135_PRED, {INTRA_FRAME,  NONE}},
117233d2500723e5594f3e7c70896ffeeef32b9c950ywan  {D207_PRED, {INTRA_FRAME,  NONE}},
118233d2500723e5594f3e7c70896ffeeef32b9c950ywan  {D153_PRED, {INTRA_FRAME,  NONE}},
119233d2500723e5594f3e7c70896ffeeef32b9c950ywan  {D63_PRED,  {INTRA_FRAME,  NONE}},
120233d2500723e5594f3e7c70896ffeeef32b9c950ywan  {D117_PRED, {INTRA_FRAME,  NONE}},
121233d2500723e5594f3e7c70896ffeeef32b9c950ywan  {D45_PRED,  {INTRA_FRAME,  NONE}},
122233d2500723e5594f3e7c70896ffeeef32b9c950ywan};
123233d2500723e5594f3e7c70896ffeeef32b9c950ywan
124233d2500723e5594f3e7c70896ffeeef32b9c950ywanconst REF_DEFINITION vp9_ref_order[MAX_REFS] = {
125233d2500723e5594f3e7c70896ffeeef32b9c950ywan  {{LAST_FRAME,   NONE}},
126233d2500723e5594f3e7c70896ffeeef32b9c950ywan  {{GOLDEN_FRAME, NONE}},
127233d2500723e5594f3e7c70896ffeeef32b9c950ywan  {{ALTREF_FRAME, NONE}},
128233d2500723e5594f3e7c70896ffeeef32b9c950ywan  {{LAST_FRAME,   ALTREF_FRAME}},
129233d2500723e5594f3e7c70896ffeeef32b9c950ywan  {{GOLDEN_FRAME, ALTREF_FRAME}},
130233d2500723e5594f3e7c70896ffeeef32b9c950ywan  {{INTRA_FRAME,  NONE}},
131233d2500723e5594f3e7c70896ffeeef32b9c950ywan};
132233d2500723e5594f3e7c70896ffeeef32b9c950ywan
133233d2500723e5594f3e7c70896ffeeef32b9c950ywan// The baseline rd thresholds for breaking out of the rd loop for
134233d2500723e5594f3e7c70896ffeeef32b9c950ywan// certain modes are assumed to be based on 8x8 blocks.
135233d2500723e5594f3e7c70896ffeeef32b9c950ywan// This table is used to correct for blocks size.
136233d2500723e5594f3e7c70896ffeeef32b9c950ywan// The factors here are << 2 (2 = x0.5, 32 = x8 etc).
137233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int rd_thresh_block_size_factor[BLOCK_SIZES] =
138233d2500723e5594f3e7c70896ffeeef32b9c950ywan  {2, 3, 3, 4, 6, 6, 8, 12, 12, 16, 24, 24, 32};
139233d2500723e5594f3e7c70896ffeeef32b9c950ywan
140233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int raster_block_offset(BLOCK_SIZE plane_bsize,
141233d2500723e5594f3e7c70896ffeeef32b9c950ywan                               int raster_block, int stride) {
142233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int bw = b_width_log2(plane_bsize);
143233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int y = 4 * (raster_block >> bw);
144233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int x = 4 * (raster_block & ((1 << bw) - 1));
145233d2500723e5594f3e7c70896ffeeef32b9c950ywan  return y * stride + x;
146233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
147233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int16_t* raster_block_offset_int16(BLOCK_SIZE plane_bsize,
148233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                          int raster_block, int16_t *base) {
149233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
150233d2500723e5594f3e7c70896ffeeef32b9c950ywan  return base + raster_block_offset(plane_bsize, raster_block, stride);
151233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
152233d2500723e5594f3e7c70896ffeeef32b9c950ywan
153233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void fill_mode_costs(VP9_COMP *cpi) {
154233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MACROBLOCK *const x = &cpi->mb;
155233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const FRAME_CONTEXT *const fc = &cpi->common.fc;
156233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int i, j;
157233d2500723e5594f3e7c70896ffeeef32b9c950ywan
158233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (i = 0; i < INTRA_MODES; i++)
159233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (j = 0; j < INTRA_MODES; j++)
160233d2500723e5594f3e7c70896ffeeef32b9c950ywan      vp9_cost_tokens((int *)x->y_mode_costs[i][j], vp9_kf_y_mode_prob[i][j],
161233d2500723e5594f3e7c70896ffeeef32b9c950ywan                      vp9_intra_mode_tree);
162233d2500723e5594f3e7c70896ffeeef32b9c950ywan
163233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // TODO(rbultje) separate tables for superblock costing?
164233d2500723e5594f3e7c70896ffeeef32b9c950ywan  vp9_cost_tokens(x->mbmode_cost, fc->y_mode_prob[1], vp9_intra_mode_tree);
165233d2500723e5594f3e7c70896ffeeef32b9c950ywan  vp9_cost_tokens(x->intra_uv_mode_cost[KEY_FRAME],
166233d2500723e5594f3e7c70896ffeeef32b9c950ywan                  vp9_kf_uv_mode_prob[TM_PRED], vp9_intra_mode_tree);
167233d2500723e5594f3e7c70896ffeeef32b9c950ywan  vp9_cost_tokens(x->intra_uv_mode_cost[INTER_FRAME],
168233d2500723e5594f3e7c70896ffeeef32b9c950ywan                  fc->uv_mode_prob[TM_PRED], vp9_intra_mode_tree);
169233d2500723e5594f3e7c70896ffeeef32b9c950ywan
170233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i)
171233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vp9_cost_tokens((int *)x->switchable_interp_costs[i],
172233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    fc->switchable_interp_prob[i], vp9_switchable_interp_tree);
173233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
174233d2500723e5594f3e7c70896ffeeef32b9c950ywan
175233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void fill_token_costs(vp9_coeff_cost *c,
176233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             vp9_coeff_probs_model (*p)[PLANE_TYPES]) {
177233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int i, j, k, l;
178233d2500723e5594f3e7c70896ffeeef32b9c950ywan  TX_SIZE t;
179233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (t = TX_4X4; t <= TX_32X32; ++t)
180233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (i = 0; i < PLANE_TYPES; ++i)
181233d2500723e5594f3e7c70896ffeeef32b9c950ywan      for (j = 0; j < REF_TYPES; ++j)
182233d2500723e5594f3e7c70896ffeeef32b9c950ywan        for (k = 0; k < COEF_BANDS; ++k)
183233d2500723e5594f3e7c70896ffeeef32b9c950ywan          for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) {
184233d2500723e5594f3e7c70896ffeeef32b9c950ywan            vp9_prob probs[ENTROPY_NODES];
185233d2500723e5594f3e7c70896ffeeef32b9c950ywan            vp9_model_to_full_probs(p[t][i][j][k][l], probs);
186233d2500723e5594f3e7c70896ffeeef32b9c950ywan            vp9_cost_tokens((int *)c[t][i][j][k][0][l], probs,
187233d2500723e5594f3e7c70896ffeeef32b9c950ywan                            vp9_coef_tree);
188233d2500723e5594f3e7c70896ffeeef32b9c950ywan            vp9_cost_tokens_skip((int *)c[t][i][j][k][1][l], probs,
189233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                 vp9_coef_tree);
190233d2500723e5594f3e7c70896ffeeef32b9c950ywan            assert(c[t][i][j][k][0][l][EOB_TOKEN] ==
191233d2500723e5594f3e7c70896ffeeef32b9c950ywan                   c[t][i][j][k][1][l][EOB_TOKEN]);
192233d2500723e5594f3e7c70896ffeeef32b9c950ywan          }
193233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
194233d2500723e5594f3e7c70896ffeeef32b9c950ywan
195233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic const int rd_iifactor[32] = {
196233d2500723e5594f3e7c70896ffeeef32b9c950ywan  4, 4, 3, 2, 1, 0, 0, 0,
197233d2500723e5594f3e7c70896ffeeef32b9c950ywan  0, 0, 0, 0, 0, 0, 0, 0,
198233d2500723e5594f3e7c70896ffeeef32b9c950ywan  0, 0, 0, 0, 0, 0, 0, 0,
199233d2500723e5594f3e7c70896ffeeef32b9c950ywan  0, 0, 0, 0, 0, 0, 0, 0,
200233d2500723e5594f3e7c70896ffeeef32b9c950ywan};
201233d2500723e5594f3e7c70896ffeeef32b9c950ywan
202233d2500723e5594f3e7c70896ffeeef32b9c950ywan// 3* dc_qlookup[Q]*dc_qlookup[Q];
203233d2500723e5594f3e7c70896ffeeef32b9c950ywan
204233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* values are now correlated to quantizer */
205233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int sad_per_bit16lut[QINDEX_RANGE];
206233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int sad_per_bit4lut[QINDEX_RANGE];
207233d2500723e5594f3e7c70896ffeeef32b9c950ywan
208233d2500723e5594f3e7c70896ffeeef32b9c950ywanvoid vp9_init_me_luts() {
209233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int i;
210233d2500723e5594f3e7c70896ffeeef32b9c950ywan
211233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Initialize the sad lut tables using a formulaic calculation for now
212233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // This is to make it easier to resolve the impact of experimental changes
213233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // to the quantizer tables.
214233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (i = 0; i < QINDEX_RANGE; i++) {
215233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const double q = vp9_convert_qindex_to_q(i);
216233d2500723e5594f3e7c70896ffeeef32b9c950ywan    sad_per_bit16lut[i] = (int)(0.0418 * q + 2.4107);
217233d2500723e5594f3e7c70896ffeeef32b9c950ywan    sad_per_bit4lut[i] = (int)(0.063 * q + 2.742);
218233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
219233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
220233d2500723e5594f3e7c70896ffeeef32b9c950ywan
221233d2500723e5594f3e7c70896ffeeef32b9c950ywanint vp9_compute_rd_mult(const VP9_COMP *cpi, int qindex) {
222233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int q = vp9_dc_quant(qindex, 0);
223233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // TODO(debargha): Adjust the function below
224233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int rdmult = 88 * q * q / 25;
225233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (cpi->pass == 2 && (cpi->common.frame_type != KEY_FRAME)) {
226233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (cpi->twopass.next_iiratio > 31)
227233d2500723e5594f3e7c70896ffeeef32b9c950ywan      rdmult += (rdmult * rd_iifactor[31]) >> 4;
228233d2500723e5594f3e7c70896ffeeef32b9c950ywan    else
229233d2500723e5594f3e7c70896ffeeef32b9c950ywan      rdmult += (rdmult * rd_iifactor[cpi->twopass.next_iiratio]) >> 4;
230233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
231233d2500723e5594f3e7c70896ffeeef32b9c950ywan  return rdmult;
232233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
233233d2500723e5594f3e7c70896ffeeef32b9c950ywan
234233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int compute_rd_thresh_factor(int qindex) {
235233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // TODO(debargha): Adjust the function below
236233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int q = (int)(pow(vp9_dc_quant(qindex, 0) / 4.0, RD_THRESH_POW) * 5.12);
237233d2500723e5594f3e7c70896ffeeef32b9c950ywan  return MAX(q, 8);
238233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
239233d2500723e5594f3e7c70896ffeeef32b9c950ywan
240233d2500723e5594f3e7c70896ffeeef32b9c950ywanvoid vp9_initialize_me_consts(VP9_COMP *cpi, int qindex) {
241233d2500723e5594f3e7c70896ffeeef32b9c950ywan  cpi->mb.sadperbit16 = sad_per_bit16lut[qindex];
242233d2500723e5594f3e7c70896ffeeef32b9c950ywan  cpi->mb.sadperbit4 = sad_per_bit4lut[qindex];
243233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
244233d2500723e5594f3e7c70896ffeeef32b9c950ywan
245233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void set_block_thresholds(VP9_COMP *cpi) {
246233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const VP9_COMMON *const cm = &cpi->common;
247233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int i, bsize, segment_id;
248233d2500723e5594f3e7c70896ffeeef32b9c950ywan
249233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (segment_id = 0; segment_id < MAX_SEGMENTS; ++segment_id) {
250233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const int qindex = clamp(vp9_get_qindex(&cm->seg, segment_id,
251233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                            cm->base_qindex) + cm->y_dc_delta_q,
252233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             0, MAXQ);
253233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const int q = compute_rd_thresh_factor(qindex);
254233d2500723e5594f3e7c70896ffeeef32b9c950ywan
255233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (bsize = 0; bsize < BLOCK_SIZES; ++bsize) {
256233d2500723e5594f3e7c70896ffeeef32b9c950ywan      // Threshold here seems unnecessarily harsh but fine given actual
257233d2500723e5594f3e7c70896ffeeef32b9c950ywan      // range of values used for cpi->sf.thresh_mult[].
258233d2500723e5594f3e7c70896ffeeef32b9c950ywan      const int t = q * rd_thresh_block_size_factor[bsize];
259233d2500723e5594f3e7c70896ffeeef32b9c950ywan      const int thresh_max = INT_MAX / t;
260233d2500723e5594f3e7c70896ffeeef32b9c950ywan
261233d2500723e5594f3e7c70896ffeeef32b9c950ywan      for (i = 0; i < MAX_MODES; ++i)
262233d2500723e5594f3e7c70896ffeeef32b9c950ywan        cpi->rd_threshes[segment_id][bsize][i] =
263233d2500723e5594f3e7c70896ffeeef32b9c950ywan            cpi->rd_thresh_mult[i] < thresh_max ? cpi->rd_thresh_mult[i] * t / 4
264233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                            : INT_MAX;
265233d2500723e5594f3e7c70896ffeeef32b9c950ywan
266233d2500723e5594f3e7c70896ffeeef32b9c950ywan      for (i = 0; i < MAX_REFS; ++i) {
267233d2500723e5594f3e7c70896ffeeef32b9c950ywan        cpi->rd_thresh_sub8x8[segment_id][bsize][i] =
268233d2500723e5594f3e7c70896ffeeef32b9c950ywan            cpi->rd_thresh_mult_sub8x8[i] < thresh_max
269233d2500723e5594f3e7c70896ffeeef32b9c950ywan                ? cpi->rd_thresh_mult_sub8x8[i] * t / 4
270233d2500723e5594f3e7c70896ffeeef32b9c950ywan                : INT_MAX;
271233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
272233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
273233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
274233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
275233d2500723e5594f3e7c70896ffeeef32b9c950ywan
276233d2500723e5594f3e7c70896ffeeef32b9c950ywanvoid vp9_initialize_rd_consts(VP9_COMP *cpi) {
277233d2500723e5594f3e7c70896ffeeef32b9c950ywan  VP9_COMMON *const cm = &cpi->common;
278233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MACROBLOCK *const x = &cpi->mb;
279233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int i;
280233d2500723e5594f3e7c70896ffeeef32b9c950ywan
281233d2500723e5594f3e7c70896ffeeef32b9c950ywan  vp9_clear_system_state();
282233d2500723e5594f3e7c70896ffeeef32b9c950ywan
283233d2500723e5594f3e7c70896ffeeef32b9c950ywan  cpi->RDDIV = RDDIV_BITS;  // in bits (to multiply D by 128)
284233d2500723e5594f3e7c70896ffeeef32b9c950ywan  cpi->RDMULT = vp9_compute_rd_mult(cpi, cm->base_qindex + cm->y_dc_delta_q);
285233d2500723e5594f3e7c70896ffeeef32b9c950ywan
286233d2500723e5594f3e7c70896ffeeef32b9c950ywan  x->errorperbit = cpi->RDMULT / RD_MULT_EPB_RATIO;
287233d2500723e5594f3e7c70896ffeeef32b9c950ywan  x->errorperbit += (x->errorperbit == 0);
288233d2500723e5594f3e7c70896ffeeef32b9c950ywan
289233d2500723e5594f3e7c70896ffeeef32b9c950ywan  x->select_txfm_size = (cpi->sf.tx_size_search_method == USE_LARGESTALL &&
290233d2500723e5594f3e7c70896ffeeef32b9c950ywan                         cm->frame_type != KEY_FRAME) ? 0 : 1;
291233d2500723e5594f3e7c70896ffeeef32b9c950ywan
292233d2500723e5594f3e7c70896ffeeef32b9c950ywan  set_block_thresholds(cpi);
293233d2500723e5594f3e7c70896ffeeef32b9c950ywan
294233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (!cpi->sf.use_nonrd_pick_mode || cm->frame_type == KEY_FRAME) {
295233d2500723e5594f3e7c70896ffeeef32b9c950ywan    fill_token_costs(x->token_costs, cm->fc.coef_probs);
296233d2500723e5594f3e7c70896ffeeef32b9c950ywan
297233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (i = 0; i < PARTITION_CONTEXTS; i++)
298233d2500723e5594f3e7c70896ffeeef32b9c950ywan      vp9_cost_tokens(x->partition_cost[i], get_partition_probs(cm, i),
299233d2500723e5594f3e7c70896ffeeef32b9c950ywan                      vp9_partition_tree);
300233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
301233d2500723e5594f3e7c70896ffeeef32b9c950ywan
302233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (!cpi->sf.use_nonrd_pick_mode || (cm->current_video_frame & 0x07) == 1 ||
303233d2500723e5594f3e7c70896ffeeef32b9c950ywan      cm->frame_type == KEY_FRAME) {
304233d2500723e5594f3e7c70896ffeeef32b9c950ywan    fill_mode_costs(cpi);
305233d2500723e5594f3e7c70896ffeeef32b9c950ywan
306233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (!frame_is_intra_only(cm)) {
307233d2500723e5594f3e7c70896ffeeef32b9c950ywan      vp9_build_nmv_cost_table(x->nmvjointcost,
308233d2500723e5594f3e7c70896ffeeef32b9c950ywan                               cm->allow_high_precision_mv ? x->nmvcost_hp
309233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                                           : x->nmvcost,
310233d2500723e5594f3e7c70896ffeeef32b9c950ywan                               &cm->fc.nmvc, cm->allow_high_precision_mv);
311233d2500723e5594f3e7c70896ffeeef32b9c950ywan
312233d2500723e5594f3e7c70896ffeeef32b9c950ywan      for (i = 0; i < INTER_MODE_CONTEXTS; ++i)
313233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vp9_cost_tokens((int *)x->inter_mode_cost[i],
314233d2500723e5594f3e7c70896ffeeef32b9c950ywan                        cm->fc.inter_mode_probs[i], vp9_inter_mode_tree);
315233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
316233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
317233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
318233d2500723e5594f3e7c70896ffeeef32b9c950ywan
319233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic const int MAX_XSQ_Q10 = 245727;
320233d2500723e5594f3e7c70896ffeeef32b9c950ywan
321233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void model_rd_norm(int xsq_q10, int *r_q10, int *d_q10) {
322233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // NOTE: The tables below must be of the same size
323233d2500723e5594f3e7c70896ffeeef32b9c950ywan
324233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // The functions described below are sampled at the four most significant
325233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // bits of x^2 + 8 / 256
326233d2500723e5594f3e7c70896ffeeef32b9c950ywan
327233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Normalized rate
328233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // This table models the rate for a Laplacian source
329233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // source with given variance when quantized with a uniform quantizer
330233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // with given stepsize. The closed form expression is:
331233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Rn(x) = H(sqrt(r)) + sqrt(r)*[1 + H(r)/(1 - r)],
332233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // where r = exp(-sqrt(2) * x) and x = qpstep / sqrt(variance),
333233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // and H(x) is the binary entropy function.
334233d2500723e5594f3e7c70896ffeeef32b9c950ywan  static const int rate_tab_q10[] = {
335233d2500723e5594f3e7c70896ffeeef32b9c950ywan    65536,  6086,  5574,  5275,  5063,  4899,  4764,  4651,
336233d2500723e5594f3e7c70896ffeeef32b9c950ywan     4553,  4389,  4255,  4142,  4044,  3958,  3881,  3811,
337233d2500723e5594f3e7c70896ffeeef32b9c950ywan     3748,  3635,  3538,  3453,  3376,  3307,  3244,  3186,
338233d2500723e5594f3e7c70896ffeeef32b9c950ywan     3133,  3037,  2952,  2877,  2809,  2747,  2690,  2638,
339233d2500723e5594f3e7c70896ffeeef32b9c950ywan     2589,  2501,  2423,  2353,  2290,  2232,  2179,  2130,
340233d2500723e5594f3e7c70896ffeeef32b9c950ywan     2084,  2001,  1928,  1862,  1802,  1748,  1698,  1651,
341233d2500723e5594f3e7c70896ffeeef32b9c950ywan     1608,  1530,  1460,  1398,  1342,  1290,  1243,  1199,
342233d2500723e5594f3e7c70896ffeeef32b9c950ywan     1159,  1086,  1021,   963,   911,   864,   821,   781,
343233d2500723e5594f3e7c70896ffeeef32b9c950ywan      745,   680,   623,   574,   530,   490,   455,   424,
344233d2500723e5594f3e7c70896ffeeef32b9c950ywan      395,   345,   304,   269,   239,   213,   190,   171,
345233d2500723e5594f3e7c70896ffeeef32b9c950ywan      154,   126,   104,    87,    73,    61,    52,    44,
346233d2500723e5594f3e7c70896ffeeef32b9c950ywan       38,    28,    21,    16,    12,    10,     8,     6,
347233d2500723e5594f3e7c70896ffeeef32b9c950ywan        5,     3,     2,     1,     1,     1,     0,     0,
348233d2500723e5594f3e7c70896ffeeef32b9c950ywan  };
349233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Normalized distortion
350233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // This table models the normalized distortion for a Laplacian source
351233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // source with given variance when quantized with a uniform quantizer
352233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // with given stepsize. The closed form expression is:
353233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Dn(x) = 1 - 1/sqrt(2) * x / sinh(x/sqrt(2))
354233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // where x = qpstep / sqrt(variance)
355233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Note the actual distortion is Dn * variance.
356233d2500723e5594f3e7c70896ffeeef32b9c950ywan  static const int dist_tab_q10[] = {
357233d2500723e5594f3e7c70896ffeeef32b9c950ywan       0,     0,     1,     1,     1,     2,     2,     2,
358233d2500723e5594f3e7c70896ffeeef32b9c950ywan       3,     3,     4,     5,     5,     6,     7,     7,
359233d2500723e5594f3e7c70896ffeeef32b9c950ywan       8,     9,    11,    12,    13,    15,    16,    17,
360233d2500723e5594f3e7c70896ffeeef32b9c950ywan      18,    21,    24,    26,    29,    31,    34,    36,
361233d2500723e5594f3e7c70896ffeeef32b9c950ywan      39,    44,    49,    54,    59,    64,    69,    73,
362233d2500723e5594f3e7c70896ffeeef32b9c950ywan      78,    88,    97,   106,   115,   124,   133,   142,
363233d2500723e5594f3e7c70896ffeeef32b9c950ywan     151,   167,   184,   200,   215,   231,   245,   260,
364233d2500723e5594f3e7c70896ffeeef32b9c950ywan     274,   301,   327,   351,   375,   397,   418,   439,
365233d2500723e5594f3e7c70896ffeeef32b9c950ywan     458,   495,   528,   559,   587,   613,   637,   659,
366233d2500723e5594f3e7c70896ffeeef32b9c950ywan     680,   717,   749,   777,   801,   823,   842,   859,
367233d2500723e5594f3e7c70896ffeeef32b9c950ywan     874,   899,   919,   936,   949,   960,   969,   977,
368233d2500723e5594f3e7c70896ffeeef32b9c950ywan     983,   994,  1001,  1006,  1010,  1013,  1015,  1017,
369233d2500723e5594f3e7c70896ffeeef32b9c950ywan    1018,  1020,  1022,  1022,  1023,  1023,  1023,  1024,
370233d2500723e5594f3e7c70896ffeeef32b9c950ywan  };
371233d2500723e5594f3e7c70896ffeeef32b9c950ywan  static const int xsq_iq_q10[] = {
372233d2500723e5594f3e7c70896ffeeef32b9c950ywan         0,      4,      8,     12,     16,     20,     24,     28,
373233d2500723e5594f3e7c70896ffeeef32b9c950ywan        32,     40,     48,     56,     64,     72,     80,     88,
374233d2500723e5594f3e7c70896ffeeef32b9c950ywan        96,    112,    128,    144,    160,    176,    192,    208,
375233d2500723e5594f3e7c70896ffeeef32b9c950ywan       224,    256,    288,    320,    352,    384,    416,    448,
376233d2500723e5594f3e7c70896ffeeef32b9c950ywan       480,    544,    608,    672,    736,    800,    864,    928,
377233d2500723e5594f3e7c70896ffeeef32b9c950ywan       992,   1120,   1248,   1376,   1504,   1632,   1760,   1888,
378233d2500723e5594f3e7c70896ffeeef32b9c950ywan      2016,   2272,   2528,   2784,   3040,   3296,   3552,   3808,
379233d2500723e5594f3e7c70896ffeeef32b9c950ywan      4064,   4576,   5088,   5600,   6112,   6624,   7136,   7648,
380233d2500723e5594f3e7c70896ffeeef32b9c950ywan      8160,   9184,  10208,  11232,  12256,  13280,  14304,  15328,
381233d2500723e5594f3e7c70896ffeeef32b9c950ywan     16352,  18400,  20448,  22496,  24544,  26592,  28640,  30688,
382233d2500723e5594f3e7c70896ffeeef32b9c950ywan     32736,  36832,  40928,  45024,  49120,  53216,  57312,  61408,
383233d2500723e5594f3e7c70896ffeeef32b9c950ywan     65504,  73696,  81888,  90080,  98272, 106464, 114656, 122848,
384233d2500723e5594f3e7c70896ffeeef32b9c950ywan    131040, 147424, 163808, 180192, 196576, 212960, 229344, 245728,
385233d2500723e5594f3e7c70896ffeeef32b9c950ywan  };
386233d2500723e5594f3e7c70896ffeeef32b9c950ywan  /*
387233d2500723e5594f3e7c70896ffeeef32b9c950ywan  static const int tab_size = sizeof(rate_tab_q10) / sizeof(rate_tab_q10[0]);
388233d2500723e5594f3e7c70896ffeeef32b9c950ywan  assert(sizeof(dist_tab_q10) / sizeof(dist_tab_q10[0]) == tab_size);
389233d2500723e5594f3e7c70896ffeeef32b9c950ywan  assert(sizeof(xsq_iq_q10) / sizeof(xsq_iq_q10[0]) == tab_size);
390233d2500723e5594f3e7c70896ffeeef32b9c950ywan  assert(MAX_XSQ_Q10 + 1 == xsq_iq_q10[tab_size - 1]);
391233d2500723e5594f3e7c70896ffeeef32b9c950ywan  */
392233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int tmp = (xsq_q10 >> 2) + 8;
393233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int k = get_msb(tmp) - 3;
394233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int xq = (k << 3) + ((tmp >> k) & 0x7);
395233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int one_q10 = 1 << 10;
396233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int a_q10 = ((xsq_q10 - xsq_iq_q10[xq]) << 10) >> (2 + k);
397233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int b_q10 = one_q10 - a_q10;
398233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *r_q10 = (rate_tab_q10[xq] * b_q10 + rate_tab_q10[xq + 1] * a_q10) >> 10;
399233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *d_q10 = (dist_tab_q10[xq] * b_q10 + dist_tab_q10[xq + 1] * a_q10) >> 10;
400233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
401233d2500723e5594f3e7c70896ffeeef32b9c950ywan
402233d2500723e5594f3e7c70896ffeeef32b9c950ywanvoid vp9_model_rd_from_var_lapndz(unsigned int var, unsigned int n,
403233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  unsigned int qstep, int *rate,
404233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  int64_t *dist) {
405233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // This function models the rate and distortion for a Laplacian
406233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // source with given variance when quantized with a uniform quantizer
407233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // with given stepsize. The closed form expressions are in:
408233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Hang and Chen, "Source Model for transform video coder and its
409233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // application - Part I: Fundamental Theory", IEEE Trans. Circ.
410233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Sys. for Video Tech., April 1997.
411233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (var == 0) {
412233d2500723e5594f3e7c70896ffeeef32b9c950ywan    *rate = 0;
413233d2500723e5594f3e7c70896ffeeef32b9c950ywan    *dist = 0;
414233d2500723e5594f3e7c70896ffeeef32b9c950ywan  } else {
415233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int d_q10, r_q10;
416233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const uint64_t xsq_q10_64 =
417233d2500723e5594f3e7c70896ffeeef32b9c950ywan        ((((uint64_t)qstep * qstep * n) << 10) + (var >> 1)) / var;
418233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const int xsq_q10 = xsq_q10_64 > MAX_XSQ_Q10 ?
419233d2500723e5594f3e7c70896ffeeef32b9c950ywan                        MAX_XSQ_Q10 : (int)xsq_q10_64;
420233d2500723e5594f3e7c70896ffeeef32b9c950ywan    model_rd_norm(xsq_q10, &r_q10, &d_q10);
421233d2500723e5594f3e7c70896ffeeef32b9c950ywan    *rate = (n * r_q10 + 2) >> 2;
422233d2500723e5594f3e7c70896ffeeef32b9c950ywan    *dist = (var * (int64_t)d_q10 + 512) >> 10;
423233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
424233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
425233d2500723e5594f3e7c70896ffeeef32b9c950ywan
426233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void model_rd_for_sb(VP9_COMP *cpi, BLOCK_SIZE bsize,
427233d2500723e5594f3e7c70896ffeeef32b9c950ywan                            MACROBLOCK *x, MACROBLOCKD *xd,
428233d2500723e5594f3e7c70896ffeeef32b9c950ywan                            int *out_rate_sum, int64_t *out_dist_sum) {
429233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Note our transform coeffs are 8 times an orthogonal transform.
430233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Hence quantizer step is also 8 times. To get effective quantizer
431233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // we need to divide by 8 before sending to modeling function.
432233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int i;
433233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t rate_sum = 0;
434233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t dist_sum = 0;
435233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int ref = xd->mi[0]->mbmi.ref_frame[0];
436233d2500723e5594f3e7c70896ffeeef32b9c950ywan  unsigned int sse;
437233d2500723e5594f3e7c70896ffeeef32b9c950ywan
438233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (i = 0; i < MAX_MB_PLANE; ++i) {
439233d2500723e5594f3e7c70896ffeeef32b9c950ywan    struct macroblock_plane *const p = &x->plane[i];
440233d2500723e5594f3e7c70896ffeeef32b9c950ywan    struct macroblockd_plane *const pd = &xd->plane[i];
441233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const BLOCK_SIZE bs = get_plane_block_size(bsize, pd);
442233d2500723e5594f3e7c70896ffeeef32b9c950ywan
443233d2500723e5594f3e7c70896ffeeef32b9c950ywan    (void) cpi->fn_ptr[bs].vf(p->src.buf, p->src.stride,
444233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              pd->dst.buf, pd->dst.stride, &sse);
445233d2500723e5594f3e7c70896ffeeef32b9c950ywan
446233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (i == 0)
447233d2500723e5594f3e7c70896ffeeef32b9c950ywan      x->pred_sse[ref] = sse;
448233d2500723e5594f3e7c70896ffeeef32b9c950ywan
449233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Fast approximate the modelling function.
450233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (cpi->speed > 4) {
451233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int64_t rate;
452233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int64_t dist;
453233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int64_t square_error = sse;
454233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int quantizer = (pd->dequant[1] >> 3);
455233d2500723e5594f3e7c70896ffeeef32b9c950ywan
456233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (quantizer < 120)
457233d2500723e5594f3e7c70896ffeeef32b9c950ywan        rate = (square_error * (280 - quantizer)) >> 8;
458233d2500723e5594f3e7c70896ffeeef32b9c950ywan      else
459233d2500723e5594f3e7c70896ffeeef32b9c950ywan        rate = 0;
460233d2500723e5594f3e7c70896ffeeef32b9c950ywan      dist = (square_error * quantizer) >> 8;
461233d2500723e5594f3e7c70896ffeeef32b9c950ywan      rate_sum += rate;
462233d2500723e5594f3e7c70896ffeeef32b9c950ywan      dist_sum += dist;
463233d2500723e5594f3e7c70896ffeeef32b9c950ywan    } else {
464233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int rate;
465233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int64_t dist;
466233d2500723e5594f3e7c70896ffeeef32b9c950ywan      vp9_model_rd_from_var_lapndz(sse, 1 << num_pels_log2_lookup[bs],
467233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                   pd->dequant[1] >> 3, &rate, &dist);
468233d2500723e5594f3e7c70896ffeeef32b9c950ywan      rate_sum += rate;
469233d2500723e5594f3e7c70896ffeeef32b9c950ywan      dist_sum += dist;
470233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
471233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
472233d2500723e5594f3e7c70896ffeeef32b9c950ywan
473233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *out_rate_sum = (int)rate_sum;
474233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *out_dist_sum = dist_sum << 4;
475233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
476233d2500723e5594f3e7c70896ffeeef32b9c950ywan
477233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void model_rd_for_sb_y_tx(VP9_COMP *cpi, BLOCK_SIZE bsize,
478233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                 TX_SIZE tx_size,
479233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                 MACROBLOCK *x, MACROBLOCKD *xd,
480233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                 int *out_rate_sum, int64_t *out_dist_sum,
481233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                 int *out_skip) {
482233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int j, k;
483233d2500723e5594f3e7c70896ffeeef32b9c950ywan  BLOCK_SIZE bs;
484233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const struct macroblock_plane *const p = &x->plane[0];
485233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const struct macroblockd_plane *const pd = &xd->plane[0];
486233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int width = 4 * num_4x4_blocks_wide_lookup[bsize];
487233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int height = 4 * num_4x4_blocks_high_lookup[bsize];
488233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int rate_sum = 0;
489233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t dist_sum = 0;
490233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int t = 4 << tx_size;
491233d2500723e5594f3e7c70896ffeeef32b9c950ywan
492233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (tx_size == TX_4X4) {
493233d2500723e5594f3e7c70896ffeeef32b9c950ywan    bs = BLOCK_4X4;
494233d2500723e5594f3e7c70896ffeeef32b9c950ywan  } else if (tx_size == TX_8X8) {
495233d2500723e5594f3e7c70896ffeeef32b9c950ywan    bs = BLOCK_8X8;
496233d2500723e5594f3e7c70896ffeeef32b9c950ywan  } else if (tx_size == TX_16X16) {
497233d2500723e5594f3e7c70896ffeeef32b9c950ywan    bs = BLOCK_16X16;
498233d2500723e5594f3e7c70896ffeeef32b9c950ywan  } else if (tx_size == TX_32X32) {
499233d2500723e5594f3e7c70896ffeeef32b9c950ywan    bs = BLOCK_32X32;
500233d2500723e5594f3e7c70896ffeeef32b9c950ywan  } else {
501233d2500723e5594f3e7c70896ffeeef32b9c950ywan    assert(0);
502233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
503233d2500723e5594f3e7c70896ffeeef32b9c950ywan
504233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *out_skip = 1;
505233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (j = 0; j < height; j += t) {
506233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (k = 0; k < width; k += t) {
507233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int rate;
508233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int64_t dist;
509233d2500723e5594f3e7c70896ffeeef32b9c950ywan      unsigned int sse;
510233d2500723e5594f3e7c70896ffeeef32b9c950ywan      cpi->fn_ptr[bs].vf(&p->src.buf[j * p->src.stride + k], p->src.stride,
511233d2500723e5594f3e7c70896ffeeef32b9c950ywan                         &pd->dst.buf[j * pd->dst.stride + k], pd->dst.stride,
512233d2500723e5594f3e7c70896ffeeef32b9c950ywan                         &sse);
513233d2500723e5594f3e7c70896ffeeef32b9c950ywan      // sse works better than var, since there is no dc prediction used
514233d2500723e5594f3e7c70896ffeeef32b9c950ywan      vp9_model_rd_from_var_lapndz(sse, t * t, pd->dequant[1] >> 3,
515233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                   &rate, &dist);
516233d2500723e5594f3e7c70896ffeeef32b9c950ywan      rate_sum += rate;
517233d2500723e5594f3e7c70896ffeeef32b9c950ywan      dist_sum += dist;
518233d2500723e5594f3e7c70896ffeeef32b9c950ywan      *out_skip &= (rate < 1024);
519233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
520233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
521233d2500723e5594f3e7c70896ffeeef32b9c950ywan
522233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *out_rate_sum = rate_sum;
523233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *out_dist_sum = dist_sum << 4;
524233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
525233d2500723e5594f3e7c70896ffeeef32b9c950ywan
526233d2500723e5594f3e7c70896ffeeef32b9c950ywanint64_t vp9_block_error_c(const int16_t *coeff, const int16_t *dqcoeff,
527233d2500723e5594f3e7c70896ffeeef32b9c950ywan                          intptr_t block_size, int64_t *ssz) {
528233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int i;
529233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t error = 0, sqcoeff = 0;
530233d2500723e5594f3e7c70896ffeeef32b9c950ywan
531233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (i = 0; i < block_size; i++) {
532233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const int diff = coeff[i] - dqcoeff[i];
533233d2500723e5594f3e7c70896ffeeef32b9c950ywan    error +=  diff * diff;
534233d2500723e5594f3e7c70896ffeeef32b9c950ywan    sqcoeff += coeff[i] * coeff[i];
535233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
536233d2500723e5594f3e7c70896ffeeef32b9c950ywan
537233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *ssz = sqcoeff;
538233d2500723e5594f3e7c70896ffeeef32b9c950ywan  return error;
539233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
540233d2500723e5594f3e7c70896ffeeef32b9c950ywan
541233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* The trailing '0' is a terminator which is used inside cost_coeffs() to
542233d2500723e5594f3e7c70896ffeeef32b9c950ywan * decide whether to include cost of a trailing EOB node or not (i.e. we
543233d2500723e5594f3e7c70896ffeeef32b9c950ywan * can skip this if the last coefficient in this transform block, e.g. the
544233d2500723e5594f3e7c70896ffeeef32b9c950ywan * 16th coefficient in a 4x4 block or the 64th coefficient in a 8x8 block,
545233d2500723e5594f3e7c70896ffeeef32b9c950ywan * were non-zero). */
546233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic const int16_t band_counts[TX_SIZES][8] = {
547233d2500723e5594f3e7c70896ffeeef32b9c950ywan  { 1, 2, 3, 4,  3,   16 - 13, 0 },
548233d2500723e5594f3e7c70896ffeeef32b9c950ywan  { 1, 2, 3, 4, 11,   64 - 21, 0 },
549233d2500723e5594f3e7c70896ffeeef32b9c950ywan  { 1, 2, 3, 4, 11,  256 - 21, 0 },
550233d2500723e5594f3e7c70896ffeeef32b9c950ywan  { 1, 2, 3, 4, 11, 1024 - 21, 0 },
551233d2500723e5594f3e7c70896ffeeef32b9c950ywan};
552233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic INLINE int cost_coeffs(MACROBLOCK *x,
553233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              int plane, int block,
554233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              ENTROPY_CONTEXT *A, ENTROPY_CONTEXT *L,
555233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              TX_SIZE tx_size,
556233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              const int16_t *scan, const int16_t *nb,
557233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              int use_fast_coef_costing) {
558233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MACROBLOCKD *const xd = &x->e_mbd;
559233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
560233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const struct macroblock_plane *p = &x->plane[plane];
561233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const struct macroblockd_plane *pd = &xd->plane[plane];
562233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const PLANE_TYPE type = pd->plane_type;
563233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int16_t *band_count = &band_counts[tx_size][1];
564233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int eob = p->eobs[block];
565233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int16_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
566233d2500723e5594f3e7c70896ffeeef32b9c950ywan  unsigned int (*token_costs)[2][COEFF_CONTEXTS][ENTROPY_TOKENS] =
567233d2500723e5594f3e7c70896ffeeef32b9c950ywan                   x->token_costs[tx_size][type][is_inter_block(mbmi)];
568233d2500723e5594f3e7c70896ffeeef32b9c950ywan  uint8_t token_cache[32 * 32];
569233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int pt = combine_entropy_contexts(*A, *L);
570233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int c, cost;
571233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Check for consistency of tx_size with mode info
572233d2500723e5594f3e7c70896ffeeef32b9c950ywan  assert(type == PLANE_TYPE_Y ? mbmi->tx_size == tx_size
573233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              : get_uv_tx_size(mbmi) == tx_size);
574233d2500723e5594f3e7c70896ffeeef32b9c950ywan
575233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (eob == 0) {
576233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // single eob token
577233d2500723e5594f3e7c70896ffeeef32b9c950ywan    cost = token_costs[0][0][pt][EOB_TOKEN];
578233d2500723e5594f3e7c70896ffeeef32b9c950ywan    c = 0;
579233d2500723e5594f3e7c70896ffeeef32b9c950ywan  } else {
580233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int band_left = *band_count++;
581233d2500723e5594f3e7c70896ffeeef32b9c950ywan
582233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // dc token
583233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int v = qcoeff[0];
584233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int prev_t = vp9_dct_value_tokens_ptr[v].token;
585233d2500723e5594f3e7c70896ffeeef32b9c950ywan    cost = (*token_costs)[0][pt][prev_t] + vp9_dct_value_cost_ptr[v];
586233d2500723e5594f3e7c70896ffeeef32b9c950ywan    token_cache[0] = vp9_pt_energy_class[prev_t];
587233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ++token_costs;
588233d2500723e5594f3e7c70896ffeeef32b9c950ywan
589233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // ac tokens
590233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (c = 1; c < eob; c++) {
591233d2500723e5594f3e7c70896ffeeef32b9c950ywan      const int rc = scan[c];
592233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int t;
593233d2500723e5594f3e7c70896ffeeef32b9c950ywan
594233d2500723e5594f3e7c70896ffeeef32b9c950ywan      v = qcoeff[rc];
595233d2500723e5594f3e7c70896ffeeef32b9c950ywan      t = vp9_dct_value_tokens_ptr[v].token;
596233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (use_fast_coef_costing) {
597233d2500723e5594f3e7c70896ffeeef32b9c950ywan        cost += (*token_costs)[!prev_t][!prev_t][t] + vp9_dct_value_cost_ptr[v];
598233d2500723e5594f3e7c70896ffeeef32b9c950ywan      } else {
599233d2500723e5594f3e7c70896ffeeef32b9c950ywan        pt = get_coef_context(nb, token_cache, c);
600233d2500723e5594f3e7c70896ffeeef32b9c950ywan        cost += (*token_costs)[!prev_t][pt][t] + vp9_dct_value_cost_ptr[v];
601233d2500723e5594f3e7c70896ffeeef32b9c950ywan        token_cache[rc] = vp9_pt_energy_class[t];
602233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
603233d2500723e5594f3e7c70896ffeeef32b9c950ywan      prev_t = t;
604233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (!--band_left) {
605233d2500723e5594f3e7c70896ffeeef32b9c950ywan        band_left = *band_count++;
606233d2500723e5594f3e7c70896ffeeef32b9c950ywan        ++token_costs;
607233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
608233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
609233d2500723e5594f3e7c70896ffeeef32b9c950ywan
610233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // eob token
611233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (band_left) {
612233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (use_fast_coef_costing) {
613233d2500723e5594f3e7c70896ffeeef32b9c950ywan        cost += (*token_costs)[0][!prev_t][EOB_TOKEN];
614233d2500723e5594f3e7c70896ffeeef32b9c950ywan      } else {
615233d2500723e5594f3e7c70896ffeeef32b9c950ywan        pt = get_coef_context(nb, token_cache, c);
616233d2500723e5594f3e7c70896ffeeef32b9c950ywan        cost += (*token_costs)[0][pt][EOB_TOKEN];
617233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
618233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
619233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
620233d2500723e5594f3e7c70896ffeeef32b9c950ywan
621233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // is eob first coefficient;
622233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *A = *L = (c > 0);
623233d2500723e5594f3e7c70896ffeeef32b9c950ywan
624233d2500723e5594f3e7c70896ffeeef32b9c950ywan  return cost;
625233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
626233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void dist_block(int plane, int block, TX_SIZE tx_size,
627233d2500723e5594f3e7c70896ffeeef32b9c950ywan                       struct rdcost_block_args* args) {
628233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int ss_txfrm_size = tx_size << 1;
629233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MACROBLOCK* const x = args->x;
630233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MACROBLOCKD* const xd = &x->e_mbd;
631233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const struct macroblock_plane *const p = &x->plane[plane];
632233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const struct macroblockd_plane *const pd = &xd->plane[plane];
633233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t this_sse;
634233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int shift = tx_size == TX_32X32 ? 0 : 2;
635233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int16_t *const coeff = BLOCK_OFFSET(p->coeff, block);
636233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int16_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
637233d2500723e5594f3e7c70896ffeeef32b9c950ywan  args->dist = vp9_block_error(coeff, dqcoeff, 16 << ss_txfrm_size,
638233d2500723e5594f3e7c70896ffeeef32b9c950ywan                               &this_sse) >> shift;
639233d2500723e5594f3e7c70896ffeeef32b9c950ywan  args->sse  = this_sse >> shift;
640233d2500723e5594f3e7c70896ffeeef32b9c950ywan
641233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (x->skip_encode && !is_inter_block(&xd->mi[0]->mbmi)) {
642233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // TODO(jingning): tune the model to better capture the distortion.
643233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int64_t p = (pd->dequant[1] * pd->dequant[1] *
644233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    (1 << ss_txfrm_size)) >> (shift + 2);
645233d2500723e5594f3e7c70896ffeeef32b9c950ywan    args->dist += (p >> 4);
646233d2500723e5594f3e7c70896ffeeef32b9c950ywan    args->sse  += p;
647233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
648233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
649233d2500723e5594f3e7c70896ffeeef32b9c950ywan
650233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void rate_block(int plane, int block, BLOCK_SIZE plane_bsize,
651233d2500723e5594f3e7c70896ffeeef32b9c950ywan                       TX_SIZE tx_size, struct rdcost_block_args* args) {
652233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int x_idx, y_idx;
653233d2500723e5594f3e7c70896ffeeef32b9c950ywan  txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &x_idx, &y_idx);
654233d2500723e5594f3e7c70896ffeeef32b9c950ywan
655233d2500723e5594f3e7c70896ffeeef32b9c950ywan  args->rate = cost_coeffs(args->x, plane, block, args->t_above + x_idx,
656233d2500723e5594f3e7c70896ffeeef32b9c950ywan                           args->t_left + y_idx, tx_size,
657233d2500723e5594f3e7c70896ffeeef32b9c950ywan                           args->so->scan, args->so->neighbors,
658233d2500723e5594f3e7c70896ffeeef32b9c950ywan                           args->use_fast_coef_costing);
659233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
660233d2500723e5594f3e7c70896ffeeef32b9c950ywan
661233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void block_rd_txfm(int plane, int block, BLOCK_SIZE plane_bsize,
662233d2500723e5594f3e7c70896ffeeef32b9c950ywan                          TX_SIZE tx_size, void *arg) {
663233d2500723e5594f3e7c70896ffeeef32b9c950ywan  struct rdcost_block_args *args = arg;
664233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MACROBLOCK *const x = args->x;
665233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MACROBLOCKD *const xd = &x->e_mbd;
666233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
667233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t rd1, rd2, rd;
668233d2500723e5594f3e7c70896ffeeef32b9c950ywan
669233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (args->skip)
670233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return;
671233d2500723e5594f3e7c70896ffeeef32b9c950ywan
672233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (!is_inter_block(mbmi))
673233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vp9_encode_block_intra(x, plane, block, plane_bsize, tx_size, &mbmi->skip);
674233d2500723e5594f3e7c70896ffeeef32b9c950ywan  else
675233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vp9_xform_quant(x, plane, block, plane_bsize, tx_size);
676233d2500723e5594f3e7c70896ffeeef32b9c950ywan
677233d2500723e5594f3e7c70896ffeeef32b9c950ywan  dist_block(plane, block, tx_size, args);
678233d2500723e5594f3e7c70896ffeeef32b9c950ywan  rate_block(plane, block, plane_bsize, tx_size, args);
679233d2500723e5594f3e7c70896ffeeef32b9c950ywan  rd1 = RDCOST(x->rdmult, x->rddiv, args->rate, args->dist);
680233d2500723e5594f3e7c70896ffeeef32b9c950ywan  rd2 = RDCOST(x->rdmult, x->rddiv, 0, args->sse);
681233d2500723e5594f3e7c70896ffeeef32b9c950ywan
682233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // TODO(jingning): temporarily enabled only for luma component
683233d2500723e5594f3e7c70896ffeeef32b9c950ywan  rd = MIN(rd1, rd2);
684233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (plane == 0)
685233d2500723e5594f3e7c70896ffeeef32b9c950ywan    x->zcoeff_blk[tx_size][block] = !x->plane[plane].eobs[block] ||
686233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                    (rd1 > rd2 && !xd->lossless);
687233d2500723e5594f3e7c70896ffeeef32b9c950ywan
688233d2500723e5594f3e7c70896ffeeef32b9c950ywan  args->this_rate += args->rate;
689233d2500723e5594f3e7c70896ffeeef32b9c950ywan  args->this_dist += args->dist;
690233d2500723e5594f3e7c70896ffeeef32b9c950ywan  args->this_sse  += args->sse;
691233d2500723e5594f3e7c70896ffeeef32b9c950ywan  args->this_rd += rd;
692233d2500723e5594f3e7c70896ffeeef32b9c950ywan
693233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (args->this_rd > args->best_rd) {
694233d2500723e5594f3e7c70896ffeeef32b9c950ywan    args->skip = 1;
695233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return;
696233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
697233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
698233d2500723e5594f3e7c70896ffeeef32b9c950ywan
699233d2500723e5594f3e7c70896ffeeef32b9c950ywanvoid vp9_get_entropy_contexts(BLOCK_SIZE bsize, TX_SIZE tx_size,
700233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              const struct macroblockd_plane *pd,
701233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              ENTROPY_CONTEXT t_above[16],
702233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              ENTROPY_CONTEXT t_left[16]) {
703233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
704233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int num_4x4_w = num_4x4_blocks_wide_lookup[plane_bsize];
705233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int num_4x4_h = num_4x4_blocks_high_lookup[plane_bsize];
706233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const ENTROPY_CONTEXT *const above = pd->above_context;
707233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const ENTROPY_CONTEXT *const left = pd->left_context;
708233d2500723e5594f3e7c70896ffeeef32b9c950ywan
709233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int i;
710233d2500723e5594f3e7c70896ffeeef32b9c950ywan  switch (tx_size) {
711233d2500723e5594f3e7c70896ffeeef32b9c950ywan    case TX_4X4:
712233d2500723e5594f3e7c70896ffeeef32b9c950ywan      vpx_memcpy(t_above, above, sizeof(ENTROPY_CONTEXT) * num_4x4_w);
713233d2500723e5594f3e7c70896ffeeef32b9c950ywan      vpx_memcpy(t_left, left, sizeof(ENTROPY_CONTEXT) * num_4x4_h);
714233d2500723e5594f3e7c70896ffeeef32b9c950ywan      break;
715233d2500723e5594f3e7c70896ffeeef32b9c950ywan    case TX_8X8:
716233d2500723e5594f3e7c70896ffeeef32b9c950ywan      for (i = 0; i < num_4x4_w; i += 2)
717233d2500723e5594f3e7c70896ffeeef32b9c950ywan        t_above[i] = !!*(const uint16_t *)&above[i];
718233d2500723e5594f3e7c70896ffeeef32b9c950ywan      for (i = 0; i < num_4x4_h; i += 2)
719233d2500723e5594f3e7c70896ffeeef32b9c950ywan        t_left[i] = !!*(const uint16_t *)&left[i];
720233d2500723e5594f3e7c70896ffeeef32b9c950ywan      break;
721233d2500723e5594f3e7c70896ffeeef32b9c950ywan    case TX_16X16:
722233d2500723e5594f3e7c70896ffeeef32b9c950ywan      for (i = 0; i < num_4x4_w; i += 4)
723233d2500723e5594f3e7c70896ffeeef32b9c950ywan        t_above[i] = !!*(const uint32_t *)&above[i];
724233d2500723e5594f3e7c70896ffeeef32b9c950ywan      for (i = 0; i < num_4x4_h; i += 4)
725233d2500723e5594f3e7c70896ffeeef32b9c950ywan        t_left[i] = !!*(const uint32_t *)&left[i];
726233d2500723e5594f3e7c70896ffeeef32b9c950ywan      break;
727233d2500723e5594f3e7c70896ffeeef32b9c950ywan    case TX_32X32:
728233d2500723e5594f3e7c70896ffeeef32b9c950ywan      for (i = 0; i < num_4x4_w; i += 8)
729233d2500723e5594f3e7c70896ffeeef32b9c950ywan        t_above[i] = !!*(const uint64_t *)&above[i];
730233d2500723e5594f3e7c70896ffeeef32b9c950ywan      for (i = 0; i < num_4x4_h; i += 8)
731233d2500723e5594f3e7c70896ffeeef32b9c950ywan        t_left[i] = !!*(const uint64_t *)&left[i];
732233d2500723e5594f3e7c70896ffeeef32b9c950ywan      break;
733233d2500723e5594f3e7c70896ffeeef32b9c950ywan    default:
734233d2500723e5594f3e7c70896ffeeef32b9c950ywan      assert(0 && "Invalid transform size.");
735233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
736233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
737233d2500723e5594f3e7c70896ffeeef32b9c950ywan
738233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void txfm_rd_in_plane(MACROBLOCK *x,
739233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             int *rate, int64_t *distortion,
740233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             int *skippable, int64_t *sse,
741233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             int64_t ref_best_rd, int plane,
742233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             BLOCK_SIZE bsize, TX_SIZE tx_size,
743233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             int use_fast_coef_casting) {
744233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MACROBLOCKD *const xd = &x->e_mbd;
745233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const struct macroblockd_plane *const pd = &xd->plane[plane];
746233d2500723e5594f3e7c70896ffeeef32b9c950ywan  struct rdcost_block_args args = { 0 };
747233d2500723e5594f3e7c70896ffeeef32b9c950ywan  args.x = x;
748233d2500723e5594f3e7c70896ffeeef32b9c950ywan  args.best_rd = ref_best_rd;
749233d2500723e5594f3e7c70896ffeeef32b9c950ywan  args.use_fast_coef_costing = use_fast_coef_casting;
750233d2500723e5594f3e7c70896ffeeef32b9c950ywan
751233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (plane == 0)
752233d2500723e5594f3e7c70896ffeeef32b9c950ywan    xd->mi[0]->mbmi.tx_size = tx_size;
753233d2500723e5594f3e7c70896ffeeef32b9c950ywan
754233d2500723e5594f3e7c70896ffeeef32b9c950ywan  vp9_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
755233d2500723e5594f3e7c70896ffeeef32b9c950ywan
756233d2500723e5594f3e7c70896ffeeef32b9c950ywan  args.so = get_scan(xd, tx_size, pd->plane_type, 0);
757233d2500723e5594f3e7c70896ffeeef32b9c950ywan
758233d2500723e5594f3e7c70896ffeeef32b9c950ywan  vp9_foreach_transformed_block_in_plane(xd, bsize, plane,
759233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                         block_rd_txfm, &args);
760233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (args.skip) {
761233d2500723e5594f3e7c70896ffeeef32b9c950ywan    *rate       = INT_MAX;
762233d2500723e5594f3e7c70896ffeeef32b9c950ywan    *distortion = INT64_MAX;
763233d2500723e5594f3e7c70896ffeeef32b9c950ywan    *sse        = INT64_MAX;
764233d2500723e5594f3e7c70896ffeeef32b9c950ywan    *skippable  = 0;
765233d2500723e5594f3e7c70896ffeeef32b9c950ywan  } else {
766233d2500723e5594f3e7c70896ffeeef32b9c950ywan    *distortion = args.this_dist;
767233d2500723e5594f3e7c70896ffeeef32b9c950ywan    *rate       = args.this_rate;
768233d2500723e5594f3e7c70896ffeeef32b9c950ywan    *sse        = args.this_sse;
769233d2500723e5594f3e7c70896ffeeef32b9c950ywan    *skippable  = vp9_is_skippable_in_plane(x, bsize, plane);
770233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
771233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
772233d2500723e5594f3e7c70896ffeeef32b9c950ywan
773233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void choose_largest_txfm_size(VP9_COMP *cpi, MACROBLOCK *x,
774233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                     int *rate, int64_t *distortion,
775233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                     int *skip, int64_t *sse,
776233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                     int64_t ref_best_rd,
777233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                     BLOCK_SIZE bs) {
778233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const TX_SIZE max_tx_size = max_txsize_lookup[bs];
779233d2500723e5594f3e7c70896ffeeef32b9c950ywan  VP9_COMMON *const cm = &cpi->common;
780233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const TX_SIZE largest_tx_size = tx_mode_to_biggest_tx_size[cm->tx_mode];
781233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MACROBLOCKD *const xd = &x->e_mbd;
782233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
783233d2500723e5594f3e7c70896ffeeef32b9c950ywan
784233d2500723e5594f3e7c70896ffeeef32b9c950ywan  mbmi->tx_size = MIN(max_tx_size, largest_tx_size);
785233d2500723e5594f3e7c70896ffeeef32b9c950ywan
786233d2500723e5594f3e7c70896ffeeef32b9c950ywan  txfm_rd_in_plane(x, rate, distortion, skip,
787233d2500723e5594f3e7c70896ffeeef32b9c950ywan                   &sse[mbmi->tx_size], ref_best_rd, 0, bs,
788233d2500723e5594f3e7c70896ffeeef32b9c950ywan                   mbmi->tx_size, cpi->sf.use_fast_coef_costing);
789233d2500723e5594f3e7c70896ffeeef32b9c950ywan  cpi->tx_stepdown_count[0]++;
790233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
791233d2500723e5594f3e7c70896ffeeef32b9c950ywan
792233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void choose_txfm_size_from_rd(VP9_COMP *cpi, MACROBLOCK *x,
793233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                     int (*r)[2], int *rate,
794233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                     int64_t *d, int64_t *distortion,
795233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                     int *s, int *skip,
796233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                     int64_t tx_cache[TX_MODES],
797233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                     BLOCK_SIZE bs) {
798233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const TX_SIZE max_tx_size = max_txsize_lookup[bs];
799233d2500723e5594f3e7c70896ffeeef32b9c950ywan  VP9_COMMON *const cm = &cpi->common;
800233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MACROBLOCKD *const xd = &x->e_mbd;
801233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
802233d2500723e5594f3e7c70896ffeeef32b9c950ywan  vp9_prob skip_prob = vp9_get_skip_prob(cm, xd);
803233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t rd[TX_SIZES][2] = {{INT64_MAX, INT64_MAX},
804233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             {INT64_MAX, INT64_MAX},
805233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             {INT64_MAX, INT64_MAX},
806233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             {INT64_MAX, INT64_MAX}};
807233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int n, m;
808233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int s0, s1;
809233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const TX_SIZE max_mode_tx_size = tx_mode_to_biggest_tx_size[cm->tx_mode];
810233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t best_rd = INT64_MAX;
811233d2500723e5594f3e7c70896ffeeef32b9c950ywan  TX_SIZE best_tx = TX_4X4;
812233d2500723e5594f3e7c70896ffeeef32b9c950ywan
813233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const vp9_prob *tx_probs = get_tx_probs2(max_tx_size, xd, &cm->fc.tx_probs);
814233d2500723e5594f3e7c70896ffeeef32b9c950ywan  assert(skip_prob > 0);
815233d2500723e5594f3e7c70896ffeeef32b9c950ywan  s0 = vp9_cost_bit(skip_prob, 0);
816233d2500723e5594f3e7c70896ffeeef32b9c950ywan  s1 = vp9_cost_bit(skip_prob, 1);
817233d2500723e5594f3e7c70896ffeeef32b9c950ywan
818233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (n = TX_4X4; n <= max_tx_size; n++) {
819233d2500723e5594f3e7c70896ffeeef32b9c950ywan    r[n][1] = r[n][0];
820233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (r[n][0] < INT_MAX) {
821233d2500723e5594f3e7c70896ffeeef32b9c950ywan      for (m = 0; m <= n - (n == max_tx_size); m++) {
822233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (m == n)
823233d2500723e5594f3e7c70896ffeeef32b9c950ywan          r[n][1] += vp9_cost_zero(tx_probs[m]);
824233d2500723e5594f3e7c70896ffeeef32b9c950ywan        else
825233d2500723e5594f3e7c70896ffeeef32b9c950ywan          r[n][1] += vp9_cost_one(tx_probs[m]);
826233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
827233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
828233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (d[n] == INT64_MAX) {
829233d2500723e5594f3e7c70896ffeeef32b9c950ywan      rd[n][0] = rd[n][1] = INT64_MAX;
830233d2500723e5594f3e7c70896ffeeef32b9c950ywan    } else if (s[n]) {
831233d2500723e5594f3e7c70896ffeeef32b9c950ywan      rd[n][0] = rd[n][1] = RDCOST(x->rdmult, x->rddiv, s1, d[n]);
832233d2500723e5594f3e7c70896ffeeef32b9c950ywan    } else {
833233d2500723e5594f3e7c70896ffeeef32b9c950ywan      rd[n][0] = RDCOST(x->rdmult, x->rddiv, r[n][0] + s0, d[n]);
834233d2500723e5594f3e7c70896ffeeef32b9c950ywan      rd[n][1] = RDCOST(x->rdmult, x->rddiv, r[n][1] + s0, d[n]);
835233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
836233d2500723e5594f3e7c70896ffeeef32b9c950ywan
837233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (rd[n][1] < best_rd) {
838233d2500723e5594f3e7c70896ffeeef32b9c950ywan      best_tx = n;
839233d2500723e5594f3e7c70896ffeeef32b9c950ywan      best_rd = rd[n][1];
840233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
841233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
842233d2500723e5594f3e7c70896ffeeef32b9c950ywan  mbmi->tx_size = cm->tx_mode == TX_MODE_SELECT ?
843233d2500723e5594f3e7c70896ffeeef32b9c950ywan                      best_tx : MIN(max_tx_size, max_mode_tx_size);
844233d2500723e5594f3e7c70896ffeeef32b9c950ywan
845233d2500723e5594f3e7c70896ffeeef32b9c950ywan
846233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *distortion = d[mbmi->tx_size];
847233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *rate       = r[mbmi->tx_size][cm->tx_mode == TX_MODE_SELECT];
848233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *skip       = s[mbmi->tx_size];
849233d2500723e5594f3e7c70896ffeeef32b9c950ywan
850233d2500723e5594f3e7c70896ffeeef32b9c950ywan  tx_cache[ONLY_4X4] = rd[TX_4X4][0];
851233d2500723e5594f3e7c70896ffeeef32b9c950ywan  tx_cache[ALLOW_8X8] = rd[TX_8X8][0];
852233d2500723e5594f3e7c70896ffeeef32b9c950ywan  tx_cache[ALLOW_16X16] = rd[MIN(max_tx_size, TX_16X16)][0];
853233d2500723e5594f3e7c70896ffeeef32b9c950ywan  tx_cache[ALLOW_32X32] = rd[MIN(max_tx_size, TX_32X32)][0];
854233d2500723e5594f3e7c70896ffeeef32b9c950ywan
855233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (max_tx_size == TX_32X32 && best_tx == TX_32X32) {
856233d2500723e5594f3e7c70896ffeeef32b9c950ywan    tx_cache[TX_MODE_SELECT] = rd[TX_32X32][1];
857233d2500723e5594f3e7c70896ffeeef32b9c950ywan    cpi->tx_stepdown_count[0]++;
858233d2500723e5594f3e7c70896ffeeef32b9c950ywan  } else if (max_tx_size >= TX_16X16 && best_tx == TX_16X16) {
859233d2500723e5594f3e7c70896ffeeef32b9c950ywan    tx_cache[TX_MODE_SELECT] = rd[TX_16X16][1];
860233d2500723e5594f3e7c70896ffeeef32b9c950ywan    cpi->tx_stepdown_count[max_tx_size - TX_16X16]++;
861233d2500723e5594f3e7c70896ffeeef32b9c950ywan  } else if (rd[TX_8X8][1] < rd[TX_4X4][1]) {
862233d2500723e5594f3e7c70896ffeeef32b9c950ywan    tx_cache[TX_MODE_SELECT] = rd[TX_8X8][1];
863233d2500723e5594f3e7c70896ffeeef32b9c950ywan    cpi->tx_stepdown_count[max_tx_size - TX_8X8]++;
864233d2500723e5594f3e7c70896ffeeef32b9c950ywan  } else {
865233d2500723e5594f3e7c70896ffeeef32b9c950ywan    tx_cache[TX_MODE_SELECT] = rd[TX_4X4][1];
866233d2500723e5594f3e7c70896ffeeef32b9c950ywan    cpi->tx_stepdown_count[max_tx_size - TX_4X4]++;
867233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
868233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
869233d2500723e5594f3e7c70896ffeeef32b9c950ywan
870233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int64_t scaled_rd_cost(int rdmult, int rddiv,
871233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              int rate, int64_t dist, double scale) {
872233d2500723e5594f3e7c70896ffeeef32b9c950ywan  return (int64_t) (RDCOST(rdmult, rddiv, rate, dist) * scale);
873233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
874233d2500723e5594f3e7c70896ffeeef32b9c950ywan
875233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void choose_txfm_size_from_modelrd(VP9_COMP *cpi, MACROBLOCK *x,
876233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                          int (*r)[2], int *rate,
877233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                          int64_t *d, int64_t *distortion,
878233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                          int *s, int *skip, int64_t *sse,
879233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                          int64_t ref_best_rd,
880233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                          BLOCK_SIZE bs) {
881233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const TX_SIZE max_tx_size = max_txsize_lookup[bs];
882233d2500723e5594f3e7c70896ffeeef32b9c950ywan  VP9_COMMON *const cm = &cpi->common;
883233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MACROBLOCKD *const xd = &x->e_mbd;
884233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
885233d2500723e5594f3e7c70896ffeeef32b9c950ywan  vp9_prob skip_prob = vp9_get_skip_prob(cm, xd);
886233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t rd[TX_SIZES][2] = {{INT64_MAX, INT64_MAX},
887233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             {INT64_MAX, INT64_MAX},
888233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             {INT64_MAX, INT64_MAX},
889233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             {INT64_MAX, INT64_MAX}};
890233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int n, m;
891233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int s0, s1;
892233d2500723e5594f3e7c70896ffeeef32b9c950ywan  double scale_rd[TX_SIZES] = {1.73, 1.44, 1.20, 1.00};
893233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const TX_SIZE max_mode_tx_size = tx_mode_to_biggest_tx_size[cm->tx_mode];
894233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t best_rd = INT64_MAX;
895233d2500723e5594f3e7c70896ffeeef32b9c950ywan  TX_SIZE best_tx = TX_4X4;
896233d2500723e5594f3e7c70896ffeeef32b9c950ywan
897233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const vp9_prob *tx_probs = get_tx_probs2(max_tx_size, xd, &cm->fc.tx_probs);
898233d2500723e5594f3e7c70896ffeeef32b9c950ywan  assert(skip_prob > 0);
899233d2500723e5594f3e7c70896ffeeef32b9c950ywan  s0 = vp9_cost_bit(skip_prob, 0);
900233d2500723e5594f3e7c70896ffeeef32b9c950ywan  s1 = vp9_cost_bit(skip_prob, 1);
901233d2500723e5594f3e7c70896ffeeef32b9c950ywan
902233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (n = TX_4X4; n <= max_tx_size; n++) {
903233d2500723e5594f3e7c70896ffeeef32b9c950ywan    double scale = scale_rd[n];
904233d2500723e5594f3e7c70896ffeeef32b9c950ywan    r[n][1] = r[n][0];
905233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (m = 0; m <= n - (n == max_tx_size); m++) {
906233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (m == n)
907233d2500723e5594f3e7c70896ffeeef32b9c950ywan        r[n][1] += vp9_cost_zero(tx_probs[m]);
908233d2500723e5594f3e7c70896ffeeef32b9c950ywan      else
909233d2500723e5594f3e7c70896ffeeef32b9c950ywan        r[n][1] += vp9_cost_one(tx_probs[m]);
910233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
911233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (s[n]) {
912233d2500723e5594f3e7c70896ffeeef32b9c950ywan      rd[n][0] = rd[n][1] = scaled_rd_cost(x->rdmult, x->rddiv, s1, d[n],
913233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                           scale);
914233d2500723e5594f3e7c70896ffeeef32b9c950ywan    } else {
915233d2500723e5594f3e7c70896ffeeef32b9c950ywan      rd[n][0] = scaled_rd_cost(x->rdmult, x->rddiv, r[n][0] + s0, d[n],
916233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                scale);
917233d2500723e5594f3e7c70896ffeeef32b9c950ywan      rd[n][1] = scaled_rd_cost(x->rdmult, x->rddiv, r[n][1] + s0, d[n],
918233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                scale);
919233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
920233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (rd[n][1] < best_rd) {
921233d2500723e5594f3e7c70896ffeeef32b9c950ywan      best_rd = rd[n][1];
922233d2500723e5594f3e7c70896ffeeef32b9c950ywan      best_tx = n;
923233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
924233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
925233d2500723e5594f3e7c70896ffeeef32b9c950ywan
926233d2500723e5594f3e7c70896ffeeef32b9c950ywan  mbmi->tx_size = cm->tx_mode == TX_MODE_SELECT ?
927233d2500723e5594f3e7c70896ffeeef32b9c950ywan                      best_tx : MIN(max_tx_size, max_mode_tx_size);
928233d2500723e5594f3e7c70896ffeeef32b9c950ywan
929233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Actually encode using the chosen mode if a model was used, but do not
930233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // update the r, d costs
931233d2500723e5594f3e7c70896ffeeef32b9c950ywan  txfm_rd_in_plane(x, rate, distortion, skip,
932233d2500723e5594f3e7c70896ffeeef32b9c950ywan                   &sse[mbmi->tx_size], ref_best_rd, 0, bs, mbmi->tx_size,
933233d2500723e5594f3e7c70896ffeeef32b9c950ywan                   cpi->sf.use_fast_coef_costing);
934233d2500723e5594f3e7c70896ffeeef32b9c950ywan
935233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (max_tx_size == TX_32X32 && best_tx == TX_32X32) {
936233d2500723e5594f3e7c70896ffeeef32b9c950ywan    cpi->tx_stepdown_count[0]++;
937233d2500723e5594f3e7c70896ffeeef32b9c950ywan  } else if (max_tx_size >= TX_16X16 &&  best_tx == TX_16X16) {
938233d2500723e5594f3e7c70896ffeeef32b9c950ywan    cpi->tx_stepdown_count[max_tx_size - TX_16X16]++;
939233d2500723e5594f3e7c70896ffeeef32b9c950ywan  } else if (rd[TX_8X8][1] <= rd[TX_4X4][1]) {
940233d2500723e5594f3e7c70896ffeeef32b9c950ywan    cpi->tx_stepdown_count[max_tx_size - TX_8X8]++;
941233d2500723e5594f3e7c70896ffeeef32b9c950ywan  } else {
942233d2500723e5594f3e7c70896ffeeef32b9c950ywan    cpi->tx_stepdown_count[max_tx_size - TX_4X4]++;
943233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
944233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
945233d2500723e5594f3e7c70896ffeeef32b9c950ywan
946233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void inter_super_block_yrd(VP9_COMP *cpi, MACROBLOCK *x, int *rate,
947233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  int64_t *distortion, int *skip,
948233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  int64_t *psse, BLOCK_SIZE bs,
949233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  int64_t txfm_cache[TX_MODES],
950233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  int64_t ref_best_rd) {
951233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int r[TX_SIZES][2], s[TX_SIZES];
952233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t d[TX_SIZES], sse[TX_SIZES];
953233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MACROBLOCKD *xd = &x->e_mbd;
954233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
955233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const TX_SIZE max_tx_size = max_txsize_lookup[bs];
956233d2500723e5594f3e7c70896ffeeef32b9c950ywan  TX_SIZE tx_size;
957233d2500723e5594f3e7c70896ffeeef32b9c950ywan
958233d2500723e5594f3e7c70896ffeeef32b9c950ywan  assert(bs == mbmi->sb_type);
959233d2500723e5594f3e7c70896ffeeef32b9c950ywan
960233d2500723e5594f3e7c70896ffeeef32b9c950ywan  vp9_subtract_plane(x, bs, 0);
961233d2500723e5594f3e7c70896ffeeef32b9c950ywan
962233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (cpi->sf.tx_size_search_method == USE_LARGESTALL) {
963233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vpx_memset(txfm_cache, 0, TX_MODES * sizeof(int64_t));
964233d2500723e5594f3e7c70896ffeeef32b9c950ywan    choose_largest_txfm_size(cpi, x, rate, distortion, skip, sse,
965233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             ref_best_rd, bs);
966233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (psse)
967233d2500723e5594f3e7c70896ffeeef32b9c950ywan      *psse = sse[mbmi->tx_size];
968233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return;
969233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
970233d2500723e5594f3e7c70896ffeeef32b9c950ywan
971233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (cpi->sf.tx_size_search_method == USE_LARGESTINTRA_MODELINTER) {
972233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (tx_size = TX_4X4; tx_size <= max_tx_size; ++tx_size)
973233d2500723e5594f3e7c70896ffeeef32b9c950ywan      model_rd_for_sb_y_tx(cpi, bs, tx_size, x, xd,
974233d2500723e5594f3e7c70896ffeeef32b9c950ywan                           &r[tx_size][0], &d[tx_size], &s[tx_size]);
975233d2500723e5594f3e7c70896ffeeef32b9c950ywan    choose_txfm_size_from_modelrd(cpi, x, r, rate, d, distortion, s,
976233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  skip, sse, ref_best_rd, bs);
977233d2500723e5594f3e7c70896ffeeef32b9c950ywan  } else {
978233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (tx_size = TX_4X4; tx_size <= max_tx_size; ++tx_size)
979233d2500723e5594f3e7c70896ffeeef32b9c950ywan      txfm_rd_in_plane(x, &r[tx_size][0], &d[tx_size],
980233d2500723e5594f3e7c70896ffeeef32b9c950ywan                       &s[tx_size], &sse[tx_size],
981233d2500723e5594f3e7c70896ffeeef32b9c950ywan                       ref_best_rd, 0, bs, tx_size,
982233d2500723e5594f3e7c70896ffeeef32b9c950ywan                       cpi->sf.use_fast_coef_costing);
983233d2500723e5594f3e7c70896ffeeef32b9c950ywan    choose_txfm_size_from_rd(cpi, x, r, rate, d, distortion, s,
984233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             skip, txfm_cache, bs);
985233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
986233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (psse)
987233d2500723e5594f3e7c70896ffeeef32b9c950ywan    *psse = sse[mbmi->tx_size];
988233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
989233d2500723e5594f3e7c70896ffeeef32b9c950ywan
990233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void intra_super_block_yrd(VP9_COMP *cpi, MACROBLOCK *x, int *rate,
991233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  int64_t *distortion, int *skip,
992233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  int64_t *psse, BLOCK_SIZE bs,
993233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  int64_t txfm_cache[TX_MODES],
994233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  int64_t ref_best_rd) {
995233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t sse[TX_SIZES];
996233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MACROBLOCKD *xd = &x->e_mbd;
997233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
998233d2500723e5594f3e7c70896ffeeef32b9c950ywan
999233d2500723e5594f3e7c70896ffeeef32b9c950ywan  assert(bs == mbmi->sb_type);
1000233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (cpi->sf.tx_size_search_method != USE_FULL_RD) {
1001233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vpx_memset(txfm_cache, 0, TX_MODES * sizeof(int64_t));
1002233d2500723e5594f3e7c70896ffeeef32b9c950ywan    choose_largest_txfm_size(cpi, x, rate, distortion, skip, sse,
1003233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             ref_best_rd, bs);
1004233d2500723e5594f3e7c70896ffeeef32b9c950ywan  } else {
1005233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int r[TX_SIZES][2], s[TX_SIZES];
1006233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int64_t d[TX_SIZES];
1007233d2500723e5594f3e7c70896ffeeef32b9c950ywan    TX_SIZE tx_size;
1008233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (tx_size = TX_4X4; tx_size <= max_txsize_lookup[bs]; ++tx_size)
1009233d2500723e5594f3e7c70896ffeeef32b9c950ywan      txfm_rd_in_plane(x, &r[tx_size][0], &d[tx_size],
1010233d2500723e5594f3e7c70896ffeeef32b9c950ywan                       &s[tx_size], &sse[tx_size],
1011233d2500723e5594f3e7c70896ffeeef32b9c950ywan                       ref_best_rd, 0, bs, tx_size,
1012233d2500723e5594f3e7c70896ffeeef32b9c950ywan                       cpi->sf.use_fast_coef_costing);
1013233d2500723e5594f3e7c70896ffeeef32b9c950ywan    choose_txfm_size_from_rd(cpi, x, r, rate, d, distortion, s,
1014233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             skip, txfm_cache, bs);
1015233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
1016233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (psse)
1017233d2500723e5594f3e7c70896ffeeef32b9c950ywan    *psse = sse[mbmi->tx_size];
1018233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
1019233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1020233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1021233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int conditional_skipintra(MB_PREDICTION_MODE mode,
1022233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                 MB_PREDICTION_MODE best_intra_mode) {
1023233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (mode == D117_PRED &&
1024233d2500723e5594f3e7c70896ffeeef32b9c950ywan      best_intra_mode != V_PRED &&
1025233d2500723e5594f3e7c70896ffeeef32b9c950ywan      best_intra_mode != D135_PRED)
1026233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return 1;
1027233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (mode == D63_PRED &&
1028233d2500723e5594f3e7c70896ffeeef32b9c950ywan      best_intra_mode != V_PRED &&
1029233d2500723e5594f3e7c70896ffeeef32b9c950ywan      best_intra_mode != D45_PRED)
1030233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return 1;
1031233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (mode == D207_PRED &&
1032233d2500723e5594f3e7c70896ffeeef32b9c950ywan      best_intra_mode != H_PRED &&
1033233d2500723e5594f3e7c70896ffeeef32b9c950ywan      best_intra_mode != D45_PRED)
1034233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return 1;
1035233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (mode == D153_PRED &&
1036233d2500723e5594f3e7c70896ffeeef32b9c950ywan      best_intra_mode != H_PRED &&
1037233d2500723e5594f3e7c70896ffeeef32b9c950ywan      best_intra_mode != D135_PRED)
1038233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return 1;
1039233d2500723e5594f3e7c70896ffeeef32b9c950ywan  return 0;
1040233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
1041233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1042233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, int ib,
1043233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                     MB_PREDICTION_MODE *best_mode,
1044233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                     const int *bmode_costs,
1045233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                     ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l,
1046233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                     int *bestrate, int *bestratey,
1047233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                     int64_t *bestdistortion,
1048233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                     BLOCK_SIZE bsize, int64_t rd_thresh) {
1049233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MB_PREDICTION_MODE mode;
1050233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MACROBLOCKD *const xd = &x->e_mbd;
1051233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t best_rd = rd_thresh;
1052233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1053233d2500723e5594f3e7c70896ffeeef32b9c950ywan  struct macroblock_plane *p = &x->plane[0];
1054233d2500723e5594f3e7c70896ffeeef32b9c950ywan  struct macroblockd_plane *pd = &xd->plane[0];
1055233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int src_stride = p->src.stride;
1056233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int dst_stride = pd->dst.stride;
1057233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const uint8_t *src_init = &p->src.buf[raster_block_offset(BLOCK_8X8, ib,
1058233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                                            src_stride)];
1059233d2500723e5594f3e7c70896ffeeef32b9c950ywan  uint8_t *dst_init = &pd->dst.buf[raster_block_offset(BLOCK_8X8, ib,
1060233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                                       dst_stride)];
1061233d2500723e5594f3e7c70896ffeeef32b9c950ywan  ENTROPY_CONTEXT ta[2], tempa[2];
1062233d2500723e5594f3e7c70896ffeeef32b9c950ywan  ENTROPY_CONTEXT tl[2], templ[2];
1063233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1064233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
1065233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
1066233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int idx, idy;
1067233d2500723e5594f3e7c70896ffeeef32b9c950ywan  uint8_t best_dst[8 * 8];
1068233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1069233d2500723e5594f3e7c70896ffeeef32b9c950ywan  assert(ib < 4);
1070233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1071233d2500723e5594f3e7c70896ffeeef32b9c950ywan  vpx_memcpy(ta, a, sizeof(ta));
1072233d2500723e5594f3e7c70896ffeeef32b9c950ywan  vpx_memcpy(tl, l, sizeof(tl));
1073233d2500723e5594f3e7c70896ffeeef32b9c950ywan  xd->mi[0]->mbmi.tx_size = TX_4X4;
1074233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1075233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
1076233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int64_t this_rd;
1077233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int ratey = 0;
1078233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int64_t distortion = 0;
1079233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int rate = bmode_costs[mode];
1080233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1081233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (!(cpi->sf.intra_y_mode_mask[TX_4X4] & (1 << mode)))
1082233d2500723e5594f3e7c70896ffeeef32b9c950ywan      continue;
1083233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1084233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Only do the oblique modes if the best so far is
1085233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // one of the neighboring directional modes
1086233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
1087233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (conditional_skipintra(mode, *best_mode))
1088233d2500723e5594f3e7c70896ffeeef32b9c950ywan          continue;
1089233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
1090233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1091233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vpx_memcpy(tempa, ta, sizeof(ta));
1092233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vpx_memcpy(templ, tl, sizeof(tl));
1093233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1094233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (idy = 0; idy < num_4x4_blocks_high; ++idy) {
1095233d2500723e5594f3e7c70896ffeeef32b9c950ywan      for (idx = 0; idx < num_4x4_blocks_wide; ++idx) {
1096233d2500723e5594f3e7c70896ffeeef32b9c950ywan        const int block = ib + idy * 2 + idx;
1097233d2500723e5594f3e7c70896ffeeef32b9c950ywan        const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
1098233d2500723e5594f3e7c70896ffeeef32b9c950ywan        uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
1099233d2500723e5594f3e7c70896ffeeef32b9c950ywan        int16_t *const src_diff = raster_block_offset_int16(BLOCK_8X8, block,
1100233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                                            p->src_diff);
1101233d2500723e5594f3e7c70896ffeeef32b9c950ywan        int16_t *const coeff = BLOCK_OFFSET(x->plane[0].coeff, block);
1102233d2500723e5594f3e7c70896ffeeef32b9c950ywan        xd->mi[0]->bmi[block].as_mode = mode;
1103233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vp9_predict_intra_block(xd, block, 1,
1104233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                TX_4X4, mode,
1105233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                x->skip_encode ? src : dst,
1106233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                x->skip_encode ? src_stride : dst_stride,
1107233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                dst, dst_stride, idx, idy, 0);
1108233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vp9_subtract_block(4, 4, src_diff, 8, src, src_stride, dst, dst_stride);
1109233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1110233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (xd->lossless) {
1111233d2500723e5594f3e7c70896ffeeef32b9c950ywan          const scan_order *so = &vp9_default_scan_orders[TX_4X4];
1112233d2500723e5594f3e7c70896ffeeef32b9c950ywan          vp9_fwht4x4(src_diff, coeff, 8);
1113233d2500723e5594f3e7c70896ffeeef32b9c950ywan          vp9_regular_quantize_b_4x4(x, 0, block, so->scan, so->iscan);
1114233d2500723e5594f3e7c70896ffeeef32b9c950ywan          ratey += cost_coeffs(x, 0, block, tempa + idx, templ + idy, TX_4X4,
1115233d2500723e5594f3e7c70896ffeeef32b9c950ywan                               so->scan, so->neighbors,
1116233d2500723e5594f3e7c70896ffeeef32b9c950ywan                               cpi->sf.use_fast_coef_costing);
1117233d2500723e5594f3e7c70896ffeeef32b9c950ywan          if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
1118233d2500723e5594f3e7c70896ffeeef32b9c950ywan            goto next;
1119233d2500723e5594f3e7c70896ffeeef32b9c950ywan          vp9_iwht4x4_add(BLOCK_OFFSET(pd->dqcoeff, block), dst, dst_stride,
1120233d2500723e5594f3e7c70896ffeeef32b9c950ywan                          p->eobs[block]);
1121233d2500723e5594f3e7c70896ffeeef32b9c950ywan        } else {
1122233d2500723e5594f3e7c70896ffeeef32b9c950ywan          int64_t unused;
1123233d2500723e5594f3e7c70896ffeeef32b9c950ywan          const TX_TYPE tx_type = get_tx_type_4x4(PLANE_TYPE_Y, xd, block);
1124233d2500723e5594f3e7c70896ffeeef32b9c950ywan          const scan_order *so = &vp9_scan_orders[TX_4X4][tx_type];
1125233d2500723e5594f3e7c70896ffeeef32b9c950ywan          vp9_fht4x4(src_diff, coeff, 8, tx_type);
1126233d2500723e5594f3e7c70896ffeeef32b9c950ywan          vp9_regular_quantize_b_4x4(x, 0, block, so->scan, so->iscan);
1127233d2500723e5594f3e7c70896ffeeef32b9c950ywan          ratey += cost_coeffs(x, 0, block, tempa + idx, templ + idy, TX_4X4,
1128233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             so->scan, so->neighbors,
1129233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             cpi->sf.use_fast_coef_costing);
1130233d2500723e5594f3e7c70896ffeeef32b9c950ywan          distortion += vp9_block_error(coeff, BLOCK_OFFSET(pd->dqcoeff, block),
1131233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                        16, &unused) >> 2;
1132233d2500723e5594f3e7c70896ffeeef32b9c950ywan          if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
1133233d2500723e5594f3e7c70896ffeeef32b9c950ywan            goto next;
1134233d2500723e5594f3e7c70896ffeeef32b9c950ywan          vp9_iht4x4_add(tx_type, BLOCK_OFFSET(pd->dqcoeff, block),
1135233d2500723e5594f3e7c70896ffeeef32b9c950ywan                         dst, dst_stride, p->eobs[block]);
1136233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
1137233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
1138233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
1139233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1140233d2500723e5594f3e7c70896ffeeef32b9c950ywan    rate += ratey;
1141233d2500723e5594f3e7c70896ffeeef32b9c950ywan    this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
1142233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1143233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (this_rd < best_rd) {
1144233d2500723e5594f3e7c70896ffeeef32b9c950ywan      *bestrate = rate;
1145233d2500723e5594f3e7c70896ffeeef32b9c950ywan      *bestratey = ratey;
1146233d2500723e5594f3e7c70896ffeeef32b9c950ywan      *bestdistortion = distortion;
1147233d2500723e5594f3e7c70896ffeeef32b9c950ywan      best_rd = this_rd;
1148233d2500723e5594f3e7c70896ffeeef32b9c950ywan      *best_mode = mode;
1149233d2500723e5594f3e7c70896ffeeef32b9c950ywan      vpx_memcpy(a, tempa, sizeof(tempa));
1150233d2500723e5594f3e7c70896ffeeef32b9c950ywan      vpx_memcpy(l, templ, sizeof(templ));
1151233d2500723e5594f3e7c70896ffeeef32b9c950ywan      for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy)
1152233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vpx_memcpy(best_dst + idy * 8, dst_init + idy * dst_stride,
1153233d2500723e5594f3e7c70896ffeeef32b9c950ywan                   num_4x4_blocks_wide * 4);
1154233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
1155233d2500723e5594f3e7c70896ffeeef32b9c950ywan  next:
1156233d2500723e5594f3e7c70896ffeeef32b9c950ywan    {}
1157233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
1158233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1159233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (best_rd >= rd_thresh || x->skip_encode)
1160233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return best_rd;
1161233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1162233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy)
1163233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vpx_memcpy(dst_init + idy * dst_stride, best_dst + idy * 8,
1164233d2500723e5594f3e7c70896ffeeef32b9c950ywan               num_4x4_blocks_wide * 4);
1165233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1166233d2500723e5594f3e7c70896ffeeef32b9c950ywan  return best_rd;
1167233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
1168233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1169233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int64_t rd_pick_intra_sub_8x8_y_mode(VP9_COMP *cpi, MACROBLOCK *mb,
1170233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                            int *rate, int *rate_y,
1171233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                            int64_t *distortion,
1172233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                            int64_t best_rd) {
1173233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int i, j;
1174233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const MACROBLOCKD *const xd = &mb->e_mbd;
1175233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MODE_INFO *const mic = xd->mi[0];
1176233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const MODE_INFO *above_mi = xd->mi[-xd->mi_stride];
1177233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const MODE_INFO *left_mi = xd->left_available ? xd->mi[-1] : NULL;
1178233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
1179233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
1180233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
1181233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int idx, idy;
1182233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int cost = 0;
1183233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t total_distortion = 0;
1184233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int tot_rate_y = 0;
1185233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t total_rd = 0;
1186233d2500723e5594f3e7c70896ffeeef32b9c950ywan  ENTROPY_CONTEXT t_above[4], t_left[4];
1187233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int *bmode_costs = mb->mbmode_cost;
1188233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1189233d2500723e5594f3e7c70896ffeeef32b9c950ywan  vpx_memcpy(t_above, xd->plane[0].above_context, sizeof(t_above));
1190233d2500723e5594f3e7c70896ffeeef32b9c950ywan  vpx_memcpy(t_left, xd->plane[0].left_context, sizeof(t_left));
1191233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1192233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Pick modes for each sub-block (of size 4x4, 4x8, or 8x4) in an 8x8 block.
1193233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
1194233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
1195233d2500723e5594f3e7c70896ffeeef32b9c950ywan      MB_PREDICTION_MODE best_mode = DC_PRED;
1196233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int r = INT_MAX, ry = INT_MAX;
1197233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int64_t d = INT64_MAX, this_rd = INT64_MAX;
1198233d2500723e5594f3e7c70896ffeeef32b9c950ywan      i = idy * 2 + idx;
1199233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (cpi->common.frame_type == KEY_FRAME) {
1200233d2500723e5594f3e7c70896ffeeef32b9c950ywan        const MB_PREDICTION_MODE A = vp9_above_block_mode(mic, above_mi, i);
1201233d2500723e5594f3e7c70896ffeeef32b9c950ywan        const MB_PREDICTION_MODE L = vp9_left_block_mode(mic, left_mi, i);
1202233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1203233d2500723e5594f3e7c70896ffeeef32b9c950ywan        bmode_costs  = mb->y_mode_costs[A][L];
1204233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
1205233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1206233d2500723e5594f3e7c70896ffeeef32b9c950ywan      this_rd = rd_pick_intra4x4block(cpi, mb, i, &best_mode, bmode_costs,
1207233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                      t_above + idx, t_left + idy, &r, &ry, &d,
1208233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                      bsize, best_rd - total_rd);
1209233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (this_rd >= best_rd - total_rd)
1210233d2500723e5594f3e7c70896ffeeef32b9c950ywan        return INT64_MAX;
1211233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1212233d2500723e5594f3e7c70896ffeeef32b9c950ywan      total_rd += this_rd;
1213233d2500723e5594f3e7c70896ffeeef32b9c950ywan      cost += r;
1214233d2500723e5594f3e7c70896ffeeef32b9c950ywan      total_distortion += d;
1215233d2500723e5594f3e7c70896ffeeef32b9c950ywan      tot_rate_y += ry;
1216233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1217233d2500723e5594f3e7c70896ffeeef32b9c950ywan      mic->bmi[i].as_mode = best_mode;
1218233d2500723e5594f3e7c70896ffeeef32b9c950ywan      for (j = 1; j < num_4x4_blocks_high; ++j)
1219233d2500723e5594f3e7c70896ffeeef32b9c950ywan        mic->bmi[i + j * 2].as_mode = best_mode;
1220233d2500723e5594f3e7c70896ffeeef32b9c950ywan      for (j = 1; j < num_4x4_blocks_wide; ++j)
1221233d2500723e5594f3e7c70896ffeeef32b9c950ywan        mic->bmi[i + j].as_mode = best_mode;
1222233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1223233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (total_rd >= best_rd)
1224233d2500723e5594f3e7c70896ffeeef32b9c950ywan        return INT64_MAX;
1225233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
1226233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
1227233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1228233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *rate = cost;
1229233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *rate_y = tot_rate_y;
1230233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *distortion = total_distortion;
1231233d2500723e5594f3e7c70896ffeeef32b9c950ywan  mic->mbmi.mode = mic->bmi[3].as_mode;
1232233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1233233d2500723e5594f3e7c70896ffeeef32b9c950ywan  return RDCOST(mb->rdmult, mb->rddiv, cost, total_distortion);
1234233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
1235233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1236233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int64_t rd_pick_intra_sby_mode(VP9_COMP *cpi, MACROBLOCK *x,
1237233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                      int *rate, int *rate_tokenonly,
1238233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                      int64_t *distortion, int *skippable,
1239233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                      BLOCK_SIZE bsize,
1240233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                      int64_t tx_cache[TX_MODES],
1241233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                      int64_t best_rd) {
1242233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MB_PREDICTION_MODE mode;
1243233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MB_PREDICTION_MODE mode_selected = DC_PRED;
1244233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MACROBLOCKD *const xd = &x->e_mbd;
1245233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MODE_INFO *const mic = xd->mi[0];
1246233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int this_rate, this_rate_tokenonly, s;
1247233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t this_distortion, this_rd;
1248233d2500723e5594f3e7c70896ffeeef32b9c950ywan  TX_SIZE best_tx = TX_4X4;
1249233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int i;
1250233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int *bmode_costs = x->mbmode_cost;
1251233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1252233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (cpi->sf.tx_size_search_method == USE_FULL_RD)
1253233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (i = 0; i < TX_MODES; i++)
1254233d2500723e5594f3e7c70896ffeeef32b9c950ywan      tx_cache[i] = INT64_MAX;
1255233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1256233d2500723e5594f3e7c70896ffeeef32b9c950ywan  /* Y Search for intra prediction mode */
1257233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (mode = DC_PRED; mode <= TM_PRED; mode++) {
1258233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int64_t local_tx_cache[TX_MODES];
1259233d2500723e5594f3e7c70896ffeeef32b9c950ywan    MODE_INFO *above_mi = xd->mi[-xd->mi_stride];
1260233d2500723e5594f3e7c70896ffeeef32b9c950ywan    MODE_INFO *left_mi = xd->left_available ? xd->mi[-1] : NULL;
1261233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1262233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (!(cpi->sf.intra_y_mode_mask[max_txsize_lookup[bsize]] & (1 << mode)))
1263233d2500723e5594f3e7c70896ffeeef32b9c950ywan      continue;
1264233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1265233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (cpi->common.frame_type == KEY_FRAME) {
1266233d2500723e5594f3e7c70896ffeeef32b9c950ywan      const MB_PREDICTION_MODE A = vp9_above_block_mode(mic, above_mi, 0);
1267233d2500723e5594f3e7c70896ffeeef32b9c950ywan      const MB_PREDICTION_MODE L = vp9_left_block_mode(mic, left_mi, 0);
1268233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1269233d2500723e5594f3e7c70896ffeeef32b9c950ywan      bmode_costs = x->y_mode_costs[A][L];
1270233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
1271233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mic->mbmi.mode = mode;
1272233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1273233d2500723e5594f3e7c70896ffeeef32b9c950ywan    intra_super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
1274233d2500723e5594f3e7c70896ffeeef32b9c950ywan        &s, NULL, bsize, local_tx_cache, best_rd);
1275233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1276233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (this_rate_tokenonly == INT_MAX)
1277233d2500723e5594f3e7c70896ffeeef32b9c950ywan      continue;
1278233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1279233d2500723e5594f3e7c70896ffeeef32b9c950ywan    this_rate = this_rate_tokenonly + bmode_costs[mode];
1280233d2500723e5594f3e7c70896ffeeef32b9c950ywan    this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
1281233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1282233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (this_rd < best_rd) {
1283233d2500723e5594f3e7c70896ffeeef32b9c950ywan      mode_selected   = mode;
1284233d2500723e5594f3e7c70896ffeeef32b9c950ywan      best_rd         = this_rd;
1285233d2500723e5594f3e7c70896ffeeef32b9c950ywan      best_tx         = mic->mbmi.tx_size;
1286233d2500723e5594f3e7c70896ffeeef32b9c950ywan      *rate           = this_rate;
1287233d2500723e5594f3e7c70896ffeeef32b9c950ywan      *rate_tokenonly = this_rate_tokenonly;
1288233d2500723e5594f3e7c70896ffeeef32b9c950ywan      *distortion     = this_distortion;
1289233d2500723e5594f3e7c70896ffeeef32b9c950ywan      *skippable      = s;
1290233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
1291233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1292233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (cpi->sf.tx_size_search_method == USE_FULL_RD && this_rd < INT64_MAX) {
1293233d2500723e5594f3e7c70896ffeeef32b9c950ywan      for (i = 0; i < TX_MODES && local_tx_cache[i] < INT64_MAX; i++) {
1294233d2500723e5594f3e7c70896ffeeef32b9c950ywan        const int64_t adj_rd = this_rd + local_tx_cache[i] -
1295233d2500723e5594f3e7c70896ffeeef32b9c950ywan            local_tx_cache[cpi->common.tx_mode];
1296233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (adj_rd < tx_cache[i]) {
1297233d2500723e5594f3e7c70896ffeeef32b9c950ywan          tx_cache[i] = adj_rd;
1298233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
1299233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
1300233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
1301233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
1302233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1303233d2500723e5594f3e7c70896ffeeef32b9c950ywan  mic->mbmi.mode = mode_selected;
1304233d2500723e5594f3e7c70896ffeeef32b9c950ywan  mic->mbmi.tx_size = best_tx;
1305233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1306233d2500723e5594f3e7c70896ffeeef32b9c950ywan  return best_rd;
1307233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
1308233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1309233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void super_block_uvrd(const VP9_COMP *cpi, MACROBLOCK *x,
1310233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             int *rate, int64_t *distortion, int *skippable,
1311233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             int64_t *sse, BLOCK_SIZE bsize,
1312233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             int64_t ref_best_rd) {
1313233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MACROBLOCKD *const xd = &x->e_mbd;
1314233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1315233d2500723e5594f3e7c70896ffeeef32b9c950ywan  TX_SIZE uv_txfm_size = get_uv_tx_size(mbmi);
1316233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int plane;
1317233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int pnrate = 0, pnskip = 1;
1318233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t pndist = 0, pnsse = 0;
1319233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1320233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (ref_best_rd < 0)
1321233d2500723e5594f3e7c70896ffeeef32b9c950ywan    goto term;
1322233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1323233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (is_inter_block(mbmi)) {
1324233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int plane;
1325233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (plane = 1; plane < MAX_MB_PLANE; ++plane)
1326233d2500723e5594f3e7c70896ffeeef32b9c950ywan      vp9_subtract_plane(x, bsize, plane);
1327233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
1328233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1329233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *rate = 0;
1330233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *distortion = 0;
1331233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *sse = 0;
1332233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *skippable = 1;
1333233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1334233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
1335233d2500723e5594f3e7c70896ffeeef32b9c950ywan    txfm_rd_in_plane(x, &pnrate, &pndist, &pnskip, &pnsse,
1336233d2500723e5594f3e7c70896ffeeef32b9c950ywan                     ref_best_rd, plane, bsize, uv_txfm_size,
1337233d2500723e5594f3e7c70896ffeeef32b9c950ywan                     cpi->sf.use_fast_coef_costing);
1338233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (pnrate == INT_MAX)
1339233d2500723e5594f3e7c70896ffeeef32b9c950ywan      goto term;
1340233d2500723e5594f3e7c70896ffeeef32b9c950ywan    *rate += pnrate;
1341233d2500723e5594f3e7c70896ffeeef32b9c950ywan    *distortion += pndist;
1342233d2500723e5594f3e7c70896ffeeef32b9c950ywan    *sse += pnsse;
1343233d2500723e5594f3e7c70896ffeeef32b9c950ywan    *skippable &= pnskip;
1344233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
1345233d2500723e5594f3e7c70896ffeeef32b9c950ywan  return;
1346233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1347233d2500723e5594f3e7c70896ffeeef32b9c950ywan  term:
1348233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *rate = INT_MAX;
1349233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *distortion = INT64_MAX;
1350233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *sse = INT64_MAX;
1351233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *skippable = 0;
1352233d2500723e5594f3e7c70896ffeeef32b9c950ywan  return;
1353233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
1354233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1355233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int64_t rd_pick_intra_sbuv_mode(VP9_COMP *cpi, MACROBLOCK *x,
1356233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                       PICK_MODE_CONTEXT *ctx,
1357233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                       int *rate, int *rate_tokenonly,
1358233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                       int64_t *distortion, int *skippable,
1359233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                       BLOCK_SIZE bsize, TX_SIZE max_tx_size) {
1360233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MACROBLOCKD *xd = &x->e_mbd;
1361233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MB_PREDICTION_MODE mode;
1362233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MB_PREDICTION_MODE mode_selected = DC_PRED;
1363233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t best_rd = INT64_MAX, this_rd;
1364233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int this_rate_tokenonly, this_rate, s;
1365233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t this_distortion, this_sse;
1366233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1367233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
1368233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (!(cpi->sf.intra_uv_mode_mask[max_tx_size] & (1 << mode)))
1369233d2500723e5594f3e7c70896ffeeef32b9c950ywan      continue;
1370233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1371233d2500723e5594f3e7c70896ffeeef32b9c950ywan    xd->mi[0]->mbmi.uv_mode = mode;
1372233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1373233d2500723e5594f3e7c70896ffeeef32b9c950ywan    super_block_uvrd(cpi, x, &this_rate_tokenonly,
1374233d2500723e5594f3e7c70896ffeeef32b9c950ywan                     &this_distortion, &s, &this_sse, bsize, best_rd);
1375233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (this_rate_tokenonly == INT_MAX)
1376233d2500723e5594f3e7c70896ffeeef32b9c950ywan      continue;
1377233d2500723e5594f3e7c70896ffeeef32b9c950ywan    this_rate = this_rate_tokenonly +
1378233d2500723e5594f3e7c70896ffeeef32b9c950ywan                x->intra_uv_mode_cost[cpi->common.frame_type][mode];
1379233d2500723e5594f3e7c70896ffeeef32b9c950ywan    this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
1380233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1381233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (this_rd < best_rd) {
1382233d2500723e5594f3e7c70896ffeeef32b9c950ywan      mode_selected   = mode;
1383233d2500723e5594f3e7c70896ffeeef32b9c950ywan      best_rd         = this_rd;
1384233d2500723e5594f3e7c70896ffeeef32b9c950ywan      *rate           = this_rate;
1385233d2500723e5594f3e7c70896ffeeef32b9c950ywan      *rate_tokenonly = this_rate_tokenonly;
1386233d2500723e5594f3e7c70896ffeeef32b9c950ywan      *distortion     = this_distortion;
1387233d2500723e5594f3e7c70896ffeeef32b9c950ywan      *skippable      = s;
1388233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (!x->select_txfm_size) {
1389233d2500723e5594f3e7c70896ffeeef32b9c950ywan        int i;
1390233d2500723e5594f3e7c70896ffeeef32b9c950ywan        struct macroblock_plane *const p = x->plane;
1391233d2500723e5594f3e7c70896ffeeef32b9c950ywan        struct macroblockd_plane *const pd = xd->plane;
1392233d2500723e5594f3e7c70896ffeeef32b9c950ywan        for (i = 1; i < MAX_MB_PLANE; ++i) {
1393233d2500723e5594f3e7c70896ffeeef32b9c950ywan          p[i].coeff    = ctx->coeff_pbuf[i][2];
1394233d2500723e5594f3e7c70896ffeeef32b9c950ywan          p[i].qcoeff   = ctx->qcoeff_pbuf[i][2];
1395233d2500723e5594f3e7c70896ffeeef32b9c950ywan          pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][2];
1396233d2500723e5594f3e7c70896ffeeef32b9c950ywan          p[i].eobs    = ctx->eobs_pbuf[i][2];
1397233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1398233d2500723e5594f3e7c70896ffeeef32b9c950ywan          ctx->coeff_pbuf[i][2]   = ctx->coeff_pbuf[i][0];
1399233d2500723e5594f3e7c70896ffeeef32b9c950ywan          ctx->qcoeff_pbuf[i][2]  = ctx->qcoeff_pbuf[i][0];
1400233d2500723e5594f3e7c70896ffeeef32b9c950ywan          ctx->dqcoeff_pbuf[i][2] = ctx->dqcoeff_pbuf[i][0];
1401233d2500723e5594f3e7c70896ffeeef32b9c950ywan          ctx->eobs_pbuf[i][2]    = ctx->eobs_pbuf[i][0];
1402233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1403233d2500723e5594f3e7c70896ffeeef32b9c950ywan          ctx->coeff_pbuf[i][0]   = p[i].coeff;
1404233d2500723e5594f3e7c70896ffeeef32b9c950ywan          ctx->qcoeff_pbuf[i][0]  = p[i].qcoeff;
1405233d2500723e5594f3e7c70896ffeeef32b9c950ywan          ctx->dqcoeff_pbuf[i][0] = pd[i].dqcoeff;
1406233d2500723e5594f3e7c70896ffeeef32b9c950ywan          ctx->eobs_pbuf[i][0]    = p[i].eobs;
1407233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
1408233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
1409233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
1410233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
1411233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1412233d2500723e5594f3e7c70896ffeeef32b9c950ywan  xd->mi[0]->mbmi.uv_mode = mode_selected;
1413233d2500723e5594f3e7c70896ffeeef32b9c950ywan  return best_rd;
1414233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
1415233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1416233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int64_t rd_sbuv_dcpred(const VP9_COMP *cpi, MACROBLOCK *x,
1417233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              int *rate, int *rate_tokenonly,
1418233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              int64_t *distortion, int *skippable,
1419233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              BLOCK_SIZE bsize) {
1420233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const VP9_COMMON *cm = &cpi->common;
1421233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t unused;
1422233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1423233d2500723e5594f3e7c70896ffeeef32b9c950ywan  x->e_mbd.mi[0]->mbmi.uv_mode = DC_PRED;
1424233d2500723e5594f3e7c70896ffeeef32b9c950ywan  super_block_uvrd(cpi, x, rate_tokenonly, distortion,
1425233d2500723e5594f3e7c70896ffeeef32b9c950ywan                   skippable, &unused, bsize, INT64_MAX);
1426233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *rate = *rate_tokenonly + x->intra_uv_mode_cost[cm->frame_type][DC_PRED];
1427233d2500723e5594f3e7c70896ffeeef32b9c950ywan  return RDCOST(x->rdmult, x->rddiv, *rate, *distortion);
1428233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
1429233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1430233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void choose_intra_uv_mode(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
1431233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                 BLOCK_SIZE bsize, TX_SIZE max_tx_size,
1432233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                 int *rate_uv, int *rate_uv_tokenonly,
1433233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                 int64_t *dist_uv, int *skip_uv,
1434233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                 MB_PREDICTION_MODE *mode_uv) {
1435233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MACROBLOCK *const x = &cpi->mb;
1436233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1437233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Use an estimated rd for uv_intra based on DC_PRED if the
1438233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // appropriate speed flag is set.
1439233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (cpi->sf.use_uv_intra_rd_estimate) {
1440233d2500723e5594f3e7c70896ffeeef32b9c950ywan    rd_sbuv_dcpred(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv,
1441233d2500723e5594f3e7c70896ffeeef32b9c950ywan                   skip_uv, bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize);
1442233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Else do a proper rd search for each possible transform size that may
1443233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // be considered in the main rd loop.
1444233d2500723e5594f3e7c70896ffeeef32b9c950ywan  } else {
1445233d2500723e5594f3e7c70896ffeeef32b9c950ywan    rd_pick_intra_sbuv_mode(cpi, x, ctx,
1446233d2500723e5594f3e7c70896ffeeef32b9c950ywan                            rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
1447233d2500723e5594f3e7c70896ffeeef32b9c950ywan                            bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize, max_tx_size);
1448233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
1449233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *mode_uv = x->e_mbd.mi[0]->mbmi.uv_mode;
1450233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
1451233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1452233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int cost_mv_ref(const VP9_COMP *cpi, MB_PREDICTION_MODE mode,
1453233d2500723e5594f3e7c70896ffeeef32b9c950ywan                       int mode_context) {
1454233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const MACROBLOCK *const x = &cpi->mb;
1455233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int segment_id = x->e_mbd.mi[0]->mbmi.segment_id;
1456233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1457233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Don't account for mode here if segment skip is enabled.
1458233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (!vp9_segfeature_active(&cpi->common.seg, segment_id, SEG_LVL_SKIP)) {
1459233d2500723e5594f3e7c70896ffeeef32b9c950ywan    assert(is_inter_mode(mode));
1460233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return x->inter_mode_cost[mode_context][INTER_OFFSET(mode)];
1461233d2500723e5594f3e7c70896ffeeef32b9c950ywan  } else {
1462233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return 0;
1463233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
1464233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
1465233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1466233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
1467233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                BLOCK_SIZE bsize,
1468233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                int_mv *frame_mv,
1469233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                int mi_row, int mi_col,
1470233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                int_mv single_newmv[MAX_REF_FRAMES],
1471233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                int *rate_mv);
1472233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1473233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int labels2mode(VP9_COMP *cpi, MACROBLOCKD *xd, int i,
1474233d2500723e5594f3e7c70896ffeeef32b9c950ywan                       MB_PREDICTION_MODE mode,
1475233d2500723e5594f3e7c70896ffeeef32b9c950ywan                       int_mv this_mv[2],
1476233d2500723e5594f3e7c70896ffeeef32b9c950ywan                       int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES],
1477233d2500723e5594f3e7c70896ffeeef32b9c950ywan                       int_mv seg_mvs[MAX_REF_FRAMES],
1478233d2500723e5594f3e7c70896ffeeef32b9c950ywan                       int_mv *best_ref_mv[2],
1479233d2500723e5594f3e7c70896ffeeef32b9c950ywan                       const int *mvjcost, int *mvcost[2]) {
1480233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MODE_INFO *const mic = xd->mi[0];
1481233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const MB_MODE_INFO *const mbmi = &mic->mbmi;
1482233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int thismvcost = 0;
1483233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int idx, idy;
1484233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type];
1485233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type];
1486233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int is_compound = has_second_ref(mbmi);
1487233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1488233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // the only time we should do costing for new motion vector or mode
1489233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // is when we are on a new label  (jbb May 08, 2007)
1490233d2500723e5594f3e7c70896ffeeef32b9c950ywan  switch (mode) {
1491233d2500723e5594f3e7c70896ffeeef32b9c950ywan    case NEWMV:
1492233d2500723e5594f3e7c70896ffeeef32b9c950ywan      this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
1493233d2500723e5594f3e7c70896ffeeef32b9c950ywan      thismvcost += vp9_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
1494233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                    mvjcost, mvcost, MV_COST_WEIGHT_SUB);
1495233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (is_compound) {
1496233d2500723e5594f3e7c70896ffeeef32b9c950ywan        this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
1497233d2500723e5594f3e7c70896ffeeef32b9c950ywan        thismvcost += vp9_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
1498233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                      mvjcost, mvcost, MV_COST_WEIGHT_SUB);
1499233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
1500233d2500723e5594f3e7c70896ffeeef32b9c950ywan      break;
1501233d2500723e5594f3e7c70896ffeeef32b9c950ywan    case NEARESTMV:
1502233d2500723e5594f3e7c70896ffeeef32b9c950ywan      this_mv[0].as_int = frame_mv[NEARESTMV][mbmi->ref_frame[0]].as_int;
1503233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (is_compound)
1504233d2500723e5594f3e7c70896ffeeef32b9c950ywan        this_mv[1].as_int = frame_mv[NEARESTMV][mbmi->ref_frame[1]].as_int;
1505233d2500723e5594f3e7c70896ffeeef32b9c950ywan      break;
1506233d2500723e5594f3e7c70896ffeeef32b9c950ywan    case NEARMV:
1507233d2500723e5594f3e7c70896ffeeef32b9c950ywan      this_mv[0].as_int = frame_mv[NEARMV][mbmi->ref_frame[0]].as_int;
1508233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (is_compound)
1509233d2500723e5594f3e7c70896ffeeef32b9c950ywan        this_mv[1].as_int = frame_mv[NEARMV][mbmi->ref_frame[1]].as_int;
1510233d2500723e5594f3e7c70896ffeeef32b9c950ywan      break;
1511233d2500723e5594f3e7c70896ffeeef32b9c950ywan    case ZEROMV:
1512233d2500723e5594f3e7c70896ffeeef32b9c950ywan      this_mv[0].as_int = 0;
1513233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (is_compound)
1514233d2500723e5594f3e7c70896ffeeef32b9c950ywan        this_mv[1].as_int = 0;
1515233d2500723e5594f3e7c70896ffeeef32b9c950ywan      break;
1516233d2500723e5594f3e7c70896ffeeef32b9c950ywan    default:
1517233d2500723e5594f3e7c70896ffeeef32b9c950ywan      break;
1518233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
1519233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1520233d2500723e5594f3e7c70896ffeeef32b9c950ywan  mic->bmi[i].as_mv[0].as_int = this_mv[0].as_int;
1521233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (is_compound)
1522233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mic->bmi[i].as_mv[1].as_int = this_mv[1].as_int;
1523233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1524233d2500723e5594f3e7c70896ffeeef32b9c950ywan  mic->bmi[i].as_mode = mode;
1525233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1526233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (idy = 0; idy < num_4x4_blocks_high; ++idy)
1527233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (idx = 0; idx < num_4x4_blocks_wide; ++idx)
1528233d2500723e5594f3e7c70896ffeeef32b9c950ywan      vpx_memcpy(&mic->bmi[i + idy * 2 + idx],
1529233d2500723e5594f3e7c70896ffeeef32b9c950ywan                 &mic->bmi[i], sizeof(mic->bmi[i]));
1530233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1531233d2500723e5594f3e7c70896ffeeef32b9c950ywan  return cost_mv_ref(cpi, mode, mbmi->mode_context[mbmi->ref_frame[0]]) +
1532233d2500723e5594f3e7c70896ffeeef32b9c950ywan            thismvcost;
1533233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
1534233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1535233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int64_t encode_inter_mb_segment(VP9_COMP *cpi,
1536233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                       MACROBLOCK *x,
1537233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                       int64_t best_yrd,
1538233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                       int i,
1539233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                       int *labelyrate,
1540233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                       int64_t *distortion, int64_t *sse,
1541233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                       ENTROPY_CONTEXT *ta,
1542233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                       ENTROPY_CONTEXT *tl,
1543233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                       int mi_row, int mi_col) {
1544233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int k;
1545233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MACROBLOCKD *xd = &x->e_mbd;
1546233d2500723e5594f3e7c70896ffeeef32b9c950ywan  struct macroblockd_plane *const pd = &xd->plane[0];
1547233d2500723e5594f3e7c70896ffeeef32b9c950ywan  struct macroblock_plane *const p = &x->plane[0];
1548233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MODE_INFO *const mi = xd->mi[0];
1549233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const BLOCK_SIZE plane_bsize = get_plane_block_size(mi->mbmi.sb_type, pd);
1550233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int width = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
1551233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int height = 4 * num_4x4_blocks_high_lookup[plane_bsize];
1552233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int idx, idy;
1553233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1554233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const uint8_t *const src = &p->src.buf[raster_block_offset(BLOCK_8X8, i,
1555233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                                             p->src.stride)];
1556233d2500723e5594f3e7c70896ffeeef32b9c950ywan  uint8_t *const dst = &pd->dst.buf[raster_block_offset(BLOCK_8X8, i,
1557233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                                        pd->dst.stride)];
1558233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t thisdistortion = 0, thissse = 0;
1559233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int thisrate = 0, ref;
1560233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const scan_order *so = &vp9_default_scan_orders[TX_4X4];
1561233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int is_compound = has_second_ref(&mi->mbmi);
1562233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const InterpKernel *kernel = vp9_get_interp_kernel(mi->mbmi.interp_filter);
1563233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1564233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (ref = 0; ref < 1 + is_compound; ++ref) {
1565233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const uint8_t *pre = &pd->pre[ref].buf[raster_block_offset(BLOCK_8X8, i,
1566233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                               pd->pre[ref].stride)];
1567233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vp9_build_inter_predictor(pre, pd->pre[ref].stride,
1568233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              dst, pd->dst.stride,
1569233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              &mi->bmi[i].as_mv[ref].as_mv,
1570233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              &xd->block_refs[ref]->sf, width, height, ref,
1571233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              kernel, MV_PRECISION_Q3,
1572233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              mi_col * MI_SIZE + 4 * (i % 2),
1573233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              mi_row * MI_SIZE + 4 * (i / 2));
1574233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
1575233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1576233d2500723e5594f3e7c70896ffeeef32b9c950ywan  vp9_subtract_block(height, width,
1577233d2500723e5594f3e7c70896ffeeef32b9c950ywan                     raster_block_offset_int16(BLOCK_8X8, i, p->src_diff), 8,
1578233d2500723e5594f3e7c70896ffeeef32b9c950ywan                     src, p->src.stride,
1579233d2500723e5594f3e7c70896ffeeef32b9c950ywan                     dst, pd->dst.stride);
1580233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1581233d2500723e5594f3e7c70896ffeeef32b9c950ywan  k = i;
1582233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (idy = 0; idy < height / 4; ++idy) {
1583233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (idx = 0; idx < width / 4; ++idx) {
1584233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int64_t ssz, rd, rd1, rd2;
1585233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int16_t* coeff;
1586233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1587233d2500723e5594f3e7c70896ffeeef32b9c950ywan      k += (idy * 2 + idx);
1588233d2500723e5594f3e7c70896ffeeef32b9c950ywan      coeff = BLOCK_OFFSET(p->coeff, k);
1589233d2500723e5594f3e7c70896ffeeef32b9c950ywan      x->fwd_txm4x4(raster_block_offset_int16(BLOCK_8X8, k, p->src_diff),
1590233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    coeff, 8);
1591233d2500723e5594f3e7c70896ffeeef32b9c950ywan      vp9_regular_quantize_b_4x4(x, 0, k, so->scan, so->iscan);
1592233d2500723e5594f3e7c70896ffeeef32b9c950ywan      thisdistortion += vp9_block_error(coeff, BLOCK_OFFSET(pd->dqcoeff, k),
1593233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                        16, &ssz);
1594233d2500723e5594f3e7c70896ffeeef32b9c950ywan      thissse += ssz;
1595233d2500723e5594f3e7c70896ffeeef32b9c950ywan      thisrate += cost_coeffs(x, 0, k, ta + (k & 1), tl + (k >> 1), TX_4X4,
1596233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              so->scan, so->neighbors,
1597233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              cpi->sf.use_fast_coef_costing);
1598233d2500723e5594f3e7c70896ffeeef32b9c950ywan      rd1 = RDCOST(x->rdmult, x->rddiv, thisrate, thisdistortion >> 2);
1599233d2500723e5594f3e7c70896ffeeef32b9c950ywan      rd2 = RDCOST(x->rdmult, x->rddiv, 0, thissse >> 2);
1600233d2500723e5594f3e7c70896ffeeef32b9c950ywan      rd = MIN(rd1, rd2);
1601233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (rd >= best_yrd)
1602233d2500723e5594f3e7c70896ffeeef32b9c950ywan        return INT64_MAX;
1603233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
1604233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
1605233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1606233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *distortion = thisdistortion >> 2;
1607233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *labelyrate = thisrate;
1608233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *sse = thissse >> 2;
1609233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1610233d2500723e5594f3e7c70896ffeeef32b9c950ywan  return RDCOST(x->rdmult, x->rddiv, *labelyrate, *distortion);
1611233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
1612233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1613233d2500723e5594f3e7c70896ffeeef32b9c950ywantypedef struct {
1614233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int eobs;
1615233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int brate;
1616233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int byrate;
1617233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t bdist;
1618233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t bsse;
1619233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t brdcost;
1620233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int_mv mvs[2];
1621233d2500723e5594f3e7c70896ffeeef32b9c950ywan  ENTROPY_CONTEXT ta[2];
1622233d2500723e5594f3e7c70896ffeeef32b9c950ywan  ENTROPY_CONTEXT tl[2];
1623233d2500723e5594f3e7c70896ffeeef32b9c950ywan} SEG_RDSTAT;
1624233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1625233d2500723e5594f3e7c70896ffeeef32b9c950ywantypedef struct {
1626233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int_mv *ref_mv[2];
1627233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int_mv mvp;
1628233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1629233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t segment_rd;
1630233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int r;
1631233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t d;
1632233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t sse;
1633233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int segment_yrate;
1634233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MB_PREDICTION_MODE modes[4];
1635233d2500723e5594f3e7c70896ffeeef32b9c950ywan  SEG_RDSTAT rdstat[4][INTER_MODES];
1636233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int mvthresh;
1637233d2500723e5594f3e7c70896ffeeef32b9c950ywan} BEST_SEG_INFO;
1638233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1639233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic INLINE int mv_check_bounds(const MACROBLOCK *x, const MV *mv) {
1640233d2500723e5594f3e7c70896ffeeef32b9c950ywan  return (mv->row >> 3) < x->mv_row_min ||
1641233d2500723e5594f3e7c70896ffeeef32b9c950ywan         (mv->row >> 3) > x->mv_row_max ||
1642233d2500723e5594f3e7c70896ffeeef32b9c950ywan         (mv->col >> 3) < x->mv_col_min ||
1643233d2500723e5594f3e7c70896ffeeef32b9c950ywan         (mv->col >> 3) > x->mv_col_max;
1644233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
1645233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1646233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic INLINE void mi_buf_shift(MACROBLOCK *x, int i) {
1647233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MB_MODE_INFO *const mbmi = &x->e_mbd.mi[0]->mbmi;
1648233d2500723e5594f3e7c70896ffeeef32b9c950ywan  struct macroblock_plane *const p = &x->plane[0];
1649233d2500723e5594f3e7c70896ffeeef32b9c950ywan  struct macroblockd_plane *const pd = &x->e_mbd.plane[0];
1650233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1651233d2500723e5594f3e7c70896ffeeef32b9c950ywan  p->src.buf = &p->src.buf[raster_block_offset(BLOCK_8X8, i, p->src.stride)];
1652233d2500723e5594f3e7c70896ffeeef32b9c950ywan  assert(((intptr_t)pd->pre[0].buf & 0x7) == 0);
1653233d2500723e5594f3e7c70896ffeeef32b9c950ywan  pd->pre[0].buf = &pd->pre[0].buf[raster_block_offset(BLOCK_8X8, i,
1654233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                                       pd->pre[0].stride)];
1655233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (has_second_ref(mbmi))
1656233d2500723e5594f3e7c70896ffeeef32b9c950ywan    pd->pre[1].buf = &pd->pre[1].buf[raster_block_offset(BLOCK_8X8, i,
1657233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                                         pd->pre[1].stride)];
1658233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
1659233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1660233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic INLINE void mi_buf_restore(MACROBLOCK *x, struct buf_2d orig_src,
1661233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  struct buf_2d orig_pre[2]) {
1662233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
1663233d2500723e5594f3e7c70896ffeeef32b9c950ywan  x->plane[0].src = orig_src;
1664233d2500723e5594f3e7c70896ffeeef32b9c950ywan  x->e_mbd.plane[0].pre[0] = orig_pre[0];
1665233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (has_second_ref(mbmi))
1666233d2500723e5594f3e7c70896ffeeef32b9c950ywan    x->e_mbd.plane[0].pre[1] = orig_pre[1];
1667233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
1668233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1669233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic INLINE int mv_has_subpel(const MV *mv) {
1670233d2500723e5594f3e7c70896ffeeef32b9c950ywan  return (mv->row & 0x0F) || (mv->col & 0x0F);
1671233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
1672233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1673233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Check if NEARESTMV/NEARMV/ZEROMV is the cheapest way encode zero motion.
1674233d2500723e5594f3e7c70896ffeeef32b9c950ywan// TODO(aconverse): Find out if this is still productive then clean up or remove
1675233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int check_best_zero_mv(
1676233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const VP9_COMP *cpi, const uint8_t mode_context[MAX_REF_FRAMES],
1677233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES],
1678233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int disable_inter_mode_mask, int this_mode, int ref_frame,
1679233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int second_ref_frame) {
1680233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (!(disable_inter_mode_mask & (1 << INTER_OFFSET(ZEROMV))) &&
1681233d2500723e5594f3e7c70896ffeeef32b9c950ywan      (this_mode == NEARMV || this_mode == NEARESTMV || this_mode == ZEROMV) &&
1682233d2500723e5594f3e7c70896ffeeef32b9c950ywan      frame_mv[this_mode][ref_frame].as_int == 0 &&
1683233d2500723e5594f3e7c70896ffeeef32b9c950ywan      (second_ref_frame == NONE ||
1684233d2500723e5594f3e7c70896ffeeef32b9c950ywan       frame_mv[this_mode][second_ref_frame].as_int == 0)) {
1685233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int rfc = mode_context[ref_frame];
1686233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int c1 = cost_mv_ref(cpi, NEARMV, rfc);
1687233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int c2 = cost_mv_ref(cpi, NEARESTMV, rfc);
1688233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int c3 = cost_mv_ref(cpi, ZEROMV, rfc);
1689233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1690233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (this_mode == NEARMV) {
1691233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (c1 > c3) return 0;
1692233d2500723e5594f3e7c70896ffeeef32b9c950ywan    } else if (this_mode == NEARESTMV) {
1693233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (c2 > c3) return 0;
1694233d2500723e5594f3e7c70896ffeeef32b9c950ywan    } else {
1695233d2500723e5594f3e7c70896ffeeef32b9c950ywan      assert(this_mode == ZEROMV);
1696233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (second_ref_frame == NONE) {
1697233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frame].as_int == 0) ||
1698233d2500723e5594f3e7c70896ffeeef32b9c950ywan            (c3 >= c1 && frame_mv[NEARMV][ref_frame].as_int == 0))
1699233d2500723e5594f3e7c70896ffeeef32b9c950ywan          return 0;
1700233d2500723e5594f3e7c70896ffeeef32b9c950ywan      } else {
1701233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frame].as_int == 0 &&
1702233d2500723e5594f3e7c70896ffeeef32b9c950ywan             frame_mv[NEARESTMV][second_ref_frame].as_int == 0) ||
1703233d2500723e5594f3e7c70896ffeeef32b9c950ywan            (c3 >= c1 && frame_mv[NEARMV][ref_frame].as_int == 0 &&
1704233d2500723e5594f3e7c70896ffeeef32b9c950ywan             frame_mv[NEARMV][second_ref_frame].as_int == 0))
1705233d2500723e5594f3e7c70896ffeeef32b9c950ywan          return 0;
1706233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
1707233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
1708233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
1709233d2500723e5594f3e7c70896ffeeef32b9c950ywan  return 1;
1710233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
1711233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1712233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
1713233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                    const TileInfo *const tile,
1714233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                    BEST_SEG_INFO *bsi_buf, int filter_idx,
1715233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                    int_mv seg_mvs[4][MAX_REF_FRAMES],
1716233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                    int mi_row, int mi_col) {
1717233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int k, br = 0, idx, idy;
1718233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t bd = 0, block_sse = 0;
1719233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MB_PREDICTION_MODE this_mode;
1720233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MACROBLOCKD *xd = &x->e_mbd;
1721233d2500723e5594f3e7c70896ffeeef32b9c950ywan  VP9_COMMON *cm = &cpi->common;
1722233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MODE_INFO *mi = xd->mi[0];
1723233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MB_MODE_INFO *const mbmi = &mi->mbmi;
1724233d2500723e5594f3e7c70896ffeeef32b9c950ywan  struct macroblock_plane *const p = &x->plane[0];
1725233d2500723e5594f3e7c70896ffeeef32b9c950ywan  struct macroblockd_plane *const pd = &xd->plane[0];
1726233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int label_count = 4;
1727233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t this_segment_rd = 0;
1728233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int label_mv_thresh;
1729233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int segmentyrate = 0;
1730233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const BLOCK_SIZE bsize = mbmi->sb_type;
1731233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
1732233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
1733233d2500723e5594f3e7c70896ffeeef32b9c950ywan  vp9_variance_fn_ptr_t *v_fn_ptr = &cpi->fn_ptr[bsize];
1734233d2500723e5594f3e7c70896ffeeef32b9c950ywan  ENTROPY_CONTEXT t_above[2], t_left[2];
1735233d2500723e5594f3e7c70896ffeeef32b9c950ywan  BEST_SEG_INFO *bsi = bsi_buf + filter_idx;
1736233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int mode_idx;
1737233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int subpelmv = 1, have_ref = 0;
1738233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int has_second_rf = has_second_ref(mbmi);
1739233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int disable_inter_mode_mask = cpi->sf.disable_inter_mode_mask[bsize];
1740233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1741233d2500723e5594f3e7c70896ffeeef32b9c950ywan  vpx_memcpy(t_above, pd->above_context, sizeof(t_above));
1742233d2500723e5594f3e7c70896ffeeef32b9c950ywan  vpx_memcpy(t_left, pd->left_context, sizeof(t_left));
1743233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1744233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // 64 makes this threshold really big effectively
1745233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // making it so that we very rarely check mvs on
1746233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // segments.   setting this to 1 would make mv thresh
1747233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // roughly equal to what it is for macroblocks
1748233d2500723e5594f3e7c70896ffeeef32b9c950ywan  label_mv_thresh = 1 * bsi->mvthresh / label_count;
1749233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1750233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Segmentation method overheads
1751233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
1752233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
1753233d2500723e5594f3e7c70896ffeeef32b9c950ywan      // TODO(jingning,rbultje): rewrite the rate-distortion optimization
1754233d2500723e5594f3e7c70896ffeeef32b9c950ywan      // loop for 4x4/4x8/8x4 block coding. to be replaced with new rd loop
1755233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int_mv mode_mv[MB_MODE_COUNT][2];
1756233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
1757233d2500723e5594f3e7c70896ffeeef32b9c950ywan      MB_PREDICTION_MODE mode_selected = ZEROMV;
1758233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int64_t best_rd = INT64_MAX;
1759233d2500723e5594f3e7c70896ffeeef32b9c950ywan      const int i = idy * 2 + idx;
1760233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int ref;
1761233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1762233d2500723e5594f3e7c70896ffeeef32b9c950ywan      for (ref = 0; ref < 1 + has_second_rf; ++ref) {
1763233d2500723e5594f3e7c70896ffeeef32b9c950ywan        const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
1764233d2500723e5594f3e7c70896ffeeef32b9c950ywan        frame_mv[ZEROMV][frame].as_int = 0;
1765233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vp9_append_sub8x8_mvs_for_idx(cm, xd, tile, i, ref, mi_row, mi_col,
1766233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                      &frame_mv[NEARESTMV][frame],
1767233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                      &frame_mv[NEARMV][frame]);
1768233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
1769233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1770233d2500723e5594f3e7c70896ffeeef32b9c950ywan      // search for the best motion vector on this segment
1771233d2500723e5594f3e7c70896ffeeef32b9c950ywan      for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode) {
1772233d2500723e5594f3e7c70896ffeeef32b9c950ywan        const struct buf_2d orig_src = x->plane[0].src;
1773233d2500723e5594f3e7c70896ffeeef32b9c950ywan        struct buf_2d orig_pre[2];
1774233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1775233d2500723e5594f3e7c70896ffeeef32b9c950ywan        mode_idx = INTER_OFFSET(this_mode);
1776233d2500723e5594f3e7c70896ffeeef32b9c950ywan        bsi->rdstat[i][mode_idx].brdcost = INT64_MAX;
1777233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (disable_inter_mode_mask & (1 << mode_idx))
1778233d2500723e5594f3e7c70896ffeeef32b9c950ywan          continue;
1779233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1780233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (!check_best_zero_mv(cpi, mbmi->mode_context, frame_mv,
1781233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                disable_inter_mode_mask,
1782233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                this_mode, mbmi->ref_frame[0],
1783233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                mbmi->ref_frame[1]))
1784233d2500723e5594f3e7c70896ffeeef32b9c950ywan          continue;
1785233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1786233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vpx_memcpy(orig_pre, pd->pre, sizeof(orig_pre));
1787233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vpx_memcpy(bsi->rdstat[i][mode_idx].ta, t_above,
1788233d2500723e5594f3e7c70896ffeeef32b9c950ywan                   sizeof(bsi->rdstat[i][mode_idx].ta));
1789233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vpx_memcpy(bsi->rdstat[i][mode_idx].tl, t_left,
1790233d2500723e5594f3e7c70896ffeeef32b9c950ywan                   sizeof(bsi->rdstat[i][mode_idx].tl));
1791233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1792233d2500723e5594f3e7c70896ffeeef32b9c950ywan        // motion search for newmv (single predictor case only)
1793233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (!has_second_rf && this_mode == NEWMV &&
1794233d2500723e5594f3e7c70896ffeeef32b9c950ywan            seg_mvs[i][mbmi->ref_frame[0]].as_int == INVALID_MV) {
1795233d2500723e5594f3e7c70896ffeeef32b9c950ywan          int_mv *const new_mv = &mode_mv[NEWMV][0];
1796233d2500723e5594f3e7c70896ffeeef32b9c950ywan          int step_param = 0;
1797233d2500723e5594f3e7c70896ffeeef32b9c950ywan          int further_steps;
1798233d2500723e5594f3e7c70896ffeeef32b9c950ywan          int thissme, bestsme = INT_MAX;
1799233d2500723e5594f3e7c70896ffeeef32b9c950ywan          int sadpb = x->sadperbit4;
1800233d2500723e5594f3e7c70896ffeeef32b9c950ywan          MV mvp_full;
1801233d2500723e5594f3e7c70896ffeeef32b9c950ywan          int max_mv;
1802233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1803233d2500723e5594f3e7c70896ffeeef32b9c950ywan          /* Is the best so far sufficiently good that we cant justify doing
1804233d2500723e5594f3e7c70896ffeeef32b9c950ywan           * and new motion search. */
1805233d2500723e5594f3e7c70896ffeeef32b9c950ywan          if (best_rd < label_mv_thresh)
1806233d2500723e5594f3e7c70896ffeeef32b9c950ywan            break;
1807233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1808233d2500723e5594f3e7c70896ffeeef32b9c950ywan          if (cpi->oxcf.mode != MODE_SECONDPASS_BEST &&
1809233d2500723e5594f3e7c70896ffeeef32b9c950ywan              cpi->oxcf.mode != MODE_BESTQUALITY) {
1810233d2500723e5594f3e7c70896ffeeef32b9c950ywan            // use previous block's result as next block's MV predictor.
1811233d2500723e5594f3e7c70896ffeeef32b9c950ywan            if (i > 0) {
1812233d2500723e5594f3e7c70896ffeeef32b9c950ywan              bsi->mvp.as_int = mi->bmi[i - 1].as_mv[0].as_int;
1813233d2500723e5594f3e7c70896ffeeef32b9c950ywan              if (i == 2)
1814233d2500723e5594f3e7c70896ffeeef32b9c950ywan                bsi->mvp.as_int = mi->bmi[i - 2].as_mv[0].as_int;
1815233d2500723e5594f3e7c70896ffeeef32b9c950ywan            }
1816233d2500723e5594f3e7c70896ffeeef32b9c950ywan          }
1817233d2500723e5594f3e7c70896ffeeef32b9c950ywan          if (i == 0)
1818233d2500723e5594f3e7c70896ffeeef32b9c950ywan            max_mv = x->max_mv_context[mbmi->ref_frame[0]];
1819233d2500723e5594f3e7c70896ffeeef32b9c950ywan          else
1820233d2500723e5594f3e7c70896ffeeef32b9c950ywan            max_mv = MAX(abs(bsi->mvp.as_mv.row), abs(bsi->mvp.as_mv.col)) >> 3;
1821233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1822233d2500723e5594f3e7c70896ffeeef32b9c950ywan          if (cpi->sf.auto_mv_step_size && cm->show_frame) {
1823233d2500723e5594f3e7c70896ffeeef32b9c950ywan            // Take wtd average of the step_params based on the last frame's
1824233d2500723e5594f3e7c70896ffeeef32b9c950ywan            // max mv magnitude and the best ref mvs of the current block for
1825233d2500723e5594f3e7c70896ffeeef32b9c950ywan            // the given reference.
1826233d2500723e5594f3e7c70896ffeeef32b9c950ywan            step_param = (vp9_init_search_range(cpi, max_mv) +
1827233d2500723e5594f3e7c70896ffeeef32b9c950ywan                          cpi->mv_step_param) >> 1;
1828233d2500723e5594f3e7c70896ffeeef32b9c950ywan          } else {
1829233d2500723e5594f3e7c70896ffeeef32b9c950ywan            step_param = cpi->mv_step_param;
1830233d2500723e5594f3e7c70896ffeeef32b9c950ywan          }
1831233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1832233d2500723e5594f3e7c70896ffeeef32b9c950ywan          mvp_full.row = bsi->mvp.as_mv.row >> 3;
1833233d2500723e5594f3e7c70896ffeeef32b9c950ywan          mvp_full.col = bsi->mvp.as_mv.col >> 3;
1834233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1835233d2500723e5594f3e7c70896ffeeef32b9c950ywan          if (cpi->sf.adaptive_motion_search && cm->show_frame) {
1836233d2500723e5594f3e7c70896ffeeef32b9c950ywan            mvp_full.row = x->pred_mv[mbmi->ref_frame[0]].as_mv.row >> 3;
1837233d2500723e5594f3e7c70896ffeeef32b9c950ywan            mvp_full.col = x->pred_mv[mbmi->ref_frame[0]].as_mv.col >> 3;
1838233d2500723e5594f3e7c70896ffeeef32b9c950ywan            step_param = MAX(step_param, 8);
1839233d2500723e5594f3e7c70896ffeeef32b9c950ywan          }
1840233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1841233d2500723e5594f3e7c70896ffeeef32b9c950ywan          further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param;
1842233d2500723e5594f3e7c70896ffeeef32b9c950ywan          // adjust src pointer for this block
1843233d2500723e5594f3e7c70896ffeeef32b9c950ywan          mi_buf_shift(x, i);
1844233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1845233d2500723e5594f3e7c70896ffeeef32b9c950ywan          vp9_set_mv_search_range(x, &bsi->ref_mv[0]->as_mv);
1846233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1847233d2500723e5594f3e7c70896ffeeef32b9c950ywan          if (cpi->sf.search_method == HEX) {
1848233d2500723e5594f3e7c70896ffeeef32b9c950ywan            bestsme = vp9_hex_search(x, &mvp_full,
1849233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                     step_param,
1850233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                     sadpb, 1, v_fn_ptr, 1,
1851233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                     &bsi->ref_mv[0]->as_mv,
1852233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                     &new_mv->as_mv);
1853233d2500723e5594f3e7c70896ffeeef32b9c950ywan            if (bestsme < INT_MAX)
1854233d2500723e5594f3e7c70896ffeeef32b9c950ywan              bestsme = vp9_get_mvpred_var(x, &new_mv->as_mv,
1855233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                           &bsi->ref_mv[0]->as_mv,
1856233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                           v_fn_ptr, 1);
1857233d2500723e5594f3e7c70896ffeeef32b9c950ywan          } else if (cpi->sf.search_method == SQUARE) {
1858233d2500723e5594f3e7c70896ffeeef32b9c950ywan            bestsme = vp9_square_search(x, &mvp_full,
1859233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                        step_param,
1860233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                        sadpb, 1, v_fn_ptr, 1,
1861233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                        &bsi->ref_mv[0]->as_mv,
1862233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                        &new_mv->as_mv);
1863233d2500723e5594f3e7c70896ffeeef32b9c950ywan            if (bestsme < INT_MAX)
1864233d2500723e5594f3e7c70896ffeeef32b9c950ywan              bestsme = vp9_get_mvpred_var(x, &new_mv->as_mv,
1865233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                           &bsi->ref_mv[0]->as_mv,
1866233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                           v_fn_ptr, 1);
1867233d2500723e5594f3e7c70896ffeeef32b9c950ywan          } else if (cpi->sf.search_method == BIGDIA) {
1868233d2500723e5594f3e7c70896ffeeef32b9c950ywan            bestsme = vp9_bigdia_search(x, &mvp_full,
1869233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                        step_param,
1870233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                        sadpb, 1, v_fn_ptr, 1,
1871233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                        &bsi->ref_mv[0]->as_mv,
1872233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                        &new_mv->as_mv);
1873233d2500723e5594f3e7c70896ffeeef32b9c950ywan            if (bestsme < INT_MAX)
1874233d2500723e5594f3e7c70896ffeeef32b9c950ywan              bestsme = vp9_get_mvpred_var(x, &new_mv->as_mv,
1875233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                           &bsi->ref_mv[0]->as_mv,
1876233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                           v_fn_ptr, 1);
1877233d2500723e5594f3e7c70896ffeeef32b9c950ywan          } else {
1878233d2500723e5594f3e7c70896ffeeef32b9c950ywan            bestsme = vp9_full_pixel_diamond(cpi, x, &mvp_full, step_param,
1879233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                             sadpb, further_steps, 0, v_fn_ptr,
1880233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                             &bsi->ref_mv[0]->as_mv,
1881233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                             &new_mv->as_mv);
1882233d2500723e5594f3e7c70896ffeeef32b9c950ywan          }
1883233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1884233d2500723e5594f3e7c70896ffeeef32b9c950ywan          // Should we do a full search (best quality only)
1885233d2500723e5594f3e7c70896ffeeef32b9c950ywan          if (cpi->oxcf.mode == MODE_BESTQUALITY ||
1886233d2500723e5594f3e7c70896ffeeef32b9c950ywan              cpi->oxcf.mode == MODE_SECONDPASS_BEST) {
1887233d2500723e5594f3e7c70896ffeeef32b9c950ywan            int_mv *const best_mv = &mi->bmi[i].as_mv[0];
1888233d2500723e5594f3e7c70896ffeeef32b9c950ywan            /* Check if mvp_full is within the range. */
1889233d2500723e5594f3e7c70896ffeeef32b9c950ywan            clamp_mv(&mvp_full, x->mv_col_min, x->mv_col_max,
1890233d2500723e5594f3e7c70896ffeeef32b9c950ywan                     x->mv_row_min, x->mv_row_max);
1891233d2500723e5594f3e7c70896ffeeef32b9c950ywan            thissme = cpi->full_search_sad(x, &mvp_full,
1892233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                           sadpb, 16, v_fn_ptr,
1893233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                           x->nmvjointcost, x->mvcost,
1894233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                           &bsi->ref_mv[0]->as_mv,
1895233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                           &best_mv->as_mv);
1896233d2500723e5594f3e7c70896ffeeef32b9c950ywan            if (thissme < bestsme) {
1897233d2500723e5594f3e7c70896ffeeef32b9c950ywan              bestsme = thissme;
1898233d2500723e5594f3e7c70896ffeeef32b9c950ywan              new_mv->as_int = best_mv->as_int;
1899233d2500723e5594f3e7c70896ffeeef32b9c950ywan            } else {
1900233d2500723e5594f3e7c70896ffeeef32b9c950ywan              // The full search result is actually worse so re-instate the
1901233d2500723e5594f3e7c70896ffeeef32b9c950ywan              // previous best vector
1902233d2500723e5594f3e7c70896ffeeef32b9c950ywan              best_mv->as_int = new_mv->as_int;
1903233d2500723e5594f3e7c70896ffeeef32b9c950ywan            }
1904233d2500723e5594f3e7c70896ffeeef32b9c950ywan          }
1905233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1906233d2500723e5594f3e7c70896ffeeef32b9c950ywan          if (bestsme < INT_MAX) {
1907233d2500723e5594f3e7c70896ffeeef32b9c950ywan            int distortion;
1908233d2500723e5594f3e7c70896ffeeef32b9c950ywan            cpi->find_fractional_mv_step(x,
1909233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                         &new_mv->as_mv,
1910233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                         &bsi->ref_mv[0]->as_mv,
1911233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                         cm->allow_high_precision_mv,
1912233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                         x->errorperbit, v_fn_ptr,
1913233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                         cpi->sf.subpel_force_stop,
1914233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                         cpi->sf.subpel_iters_per_step,
1915233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                         x->nmvjointcost, x->mvcost,
1916233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                         &distortion,
1917233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                         &x->pred_sse[mbmi->ref_frame[0]]);
1918233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1919233d2500723e5594f3e7c70896ffeeef32b9c950ywan            // save motion search result for use in compound prediction
1920233d2500723e5594f3e7c70896ffeeef32b9c950ywan            seg_mvs[i][mbmi->ref_frame[0]].as_int = new_mv->as_int;
1921233d2500723e5594f3e7c70896ffeeef32b9c950ywan          }
1922233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1923233d2500723e5594f3e7c70896ffeeef32b9c950ywan          if (cpi->sf.adaptive_motion_search)
1924233d2500723e5594f3e7c70896ffeeef32b9c950ywan            x->pred_mv[mbmi->ref_frame[0]].as_int = new_mv->as_int;
1925233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1926233d2500723e5594f3e7c70896ffeeef32b9c950ywan          // restore src pointers
1927233d2500723e5594f3e7c70896ffeeef32b9c950ywan          mi_buf_restore(x, orig_src, orig_pre);
1928233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
1929233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1930233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (has_second_rf) {
1931233d2500723e5594f3e7c70896ffeeef32b9c950ywan          if (seg_mvs[i][mbmi->ref_frame[1]].as_int == INVALID_MV ||
1932233d2500723e5594f3e7c70896ffeeef32b9c950ywan              seg_mvs[i][mbmi->ref_frame[0]].as_int == INVALID_MV)
1933233d2500723e5594f3e7c70896ffeeef32b9c950ywan            continue;
1934233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
1935233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1936233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (has_second_rf && this_mode == NEWMV &&
1937233d2500723e5594f3e7c70896ffeeef32b9c950ywan            mbmi->interp_filter == EIGHTTAP) {
1938233d2500723e5594f3e7c70896ffeeef32b9c950ywan          // adjust src pointers
1939233d2500723e5594f3e7c70896ffeeef32b9c950ywan          mi_buf_shift(x, i);
1940233d2500723e5594f3e7c70896ffeeef32b9c950ywan          if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
1941233d2500723e5594f3e7c70896ffeeef32b9c950ywan            int rate_mv;
1942233d2500723e5594f3e7c70896ffeeef32b9c950ywan            joint_motion_search(cpi, x, bsize, frame_mv[this_mode],
1943233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                mi_row, mi_col, seg_mvs[i],
1944233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                &rate_mv);
1945233d2500723e5594f3e7c70896ffeeef32b9c950ywan            seg_mvs[i][mbmi->ref_frame[0]].as_int =
1946233d2500723e5594f3e7c70896ffeeef32b9c950ywan                frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
1947233d2500723e5594f3e7c70896ffeeef32b9c950ywan            seg_mvs[i][mbmi->ref_frame[1]].as_int =
1948233d2500723e5594f3e7c70896ffeeef32b9c950ywan                frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
1949233d2500723e5594f3e7c70896ffeeef32b9c950ywan          }
1950233d2500723e5594f3e7c70896ffeeef32b9c950ywan          // restore src pointers
1951233d2500723e5594f3e7c70896ffeeef32b9c950ywan          mi_buf_restore(x, orig_src, orig_pre);
1952233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
1953233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1954233d2500723e5594f3e7c70896ffeeef32b9c950ywan        bsi->rdstat[i][mode_idx].brate =
1955233d2500723e5594f3e7c70896ffeeef32b9c950ywan            labels2mode(cpi, xd, i, this_mode, mode_mv[this_mode], frame_mv,
1956233d2500723e5594f3e7c70896ffeeef32b9c950ywan                        seg_mvs[i], bsi->ref_mv, x->nmvjointcost, x->mvcost);
1957233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1958233d2500723e5594f3e7c70896ffeeef32b9c950ywan        for (ref = 0; ref < 1 + has_second_rf; ++ref) {
1959233d2500723e5594f3e7c70896ffeeef32b9c950ywan          bsi->rdstat[i][mode_idx].mvs[ref].as_int =
1960233d2500723e5594f3e7c70896ffeeef32b9c950ywan              mode_mv[this_mode][ref].as_int;
1961233d2500723e5594f3e7c70896ffeeef32b9c950ywan          if (num_4x4_blocks_wide > 1)
1962233d2500723e5594f3e7c70896ffeeef32b9c950ywan            bsi->rdstat[i + 1][mode_idx].mvs[ref].as_int =
1963233d2500723e5594f3e7c70896ffeeef32b9c950ywan                mode_mv[this_mode][ref].as_int;
1964233d2500723e5594f3e7c70896ffeeef32b9c950ywan          if (num_4x4_blocks_high > 1)
1965233d2500723e5594f3e7c70896ffeeef32b9c950ywan            bsi->rdstat[i + 2][mode_idx].mvs[ref].as_int =
1966233d2500723e5594f3e7c70896ffeeef32b9c950ywan                mode_mv[this_mode][ref].as_int;
1967233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
1968233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1969233d2500723e5594f3e7c70896ffeeef32b9c950ywan        // Trap vectors that reach beyond the UMV borders
1970233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (mv_check_bounds(x, &mode_mv[this_mode][0].as_mv) ||
1971233d2500723e5594f3e7c70896ffeeef32b9c950ywan            (has_second_rf &&
1972233d2500723e5594f3e7c70896ffeeef32b9c950ywan             mv_check_bounds(x, &mode_mv[this_mode][1].as_mv)))
1973233d2500723e5594f3e7c70896ffeeef32b9c950ywan          continue;
1974233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1975233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (filter_idx > 0) {
1976233d2500723e5594f3e7c70896ffeeef32b9c950ywan          BEST_SEG_INFO *ref_bsi = bsi_buf;
1977233d2500723e5594f3e7c70896ffeeef32b9c950ywan          subpelmv = 0;
1978233d2500723e5594f3e7c70896ffeeef32b9c950ywan          have_ref = 1;
1979233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1980233d2500723e5594f3e7c70896ffeeef32b9c950ywan          for (ref = 0; ref < 1 + has_second_rf; ++ref) {
1981233d2500723e5594f3e7c70896ffeeef32b9c950ywan            subpelmv |= mv_has_subpel(&mode_mv[this_mode][ref].as_mv);
1982233d2500723e5594f3e7c70896ffeeef32b9c950ywan            have_ref &= mode_mv[this_mode][ref].as_int ==
1983233d2500723e5594f3e7c70896ffeeef32b9c950ywan                ref_bsi->rdstat[i][mode_idx].mvs[ref].as_int;
1984233d2500723e5594f3e7c70896ffeeef32b9c950ywan          }
1985233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1986233d2500723e5594f3e7c70896ffeeef32b9c950ywan          if (filter_idx > 1 && !subpelmv && !have_ref) {
1987233d2500723e5594f3e7c70896ffeeef32b9c950ywan            ref_bsi = bsi_buf + 1;
1988233d2500723e5594f3e7c70896ffeeef32b9c950ywan            have_ref = 1;
1989233d2500723e5594f3e7c70896ffeeef32b9c950ywan            for (ref = 0; ref < 1 + has_second_rf; ++ref)
1990233d2500723e5594f3e7c70896ffeeef32b9c950ywan              have_ref &= mode_mv[this_mode][ref].as_int ==
1991233d2500723e5594f3e7c70896ffeeef32b9c950ywan                  ref_bsi->rdstat[i][mode_idx].mvs[ref].as_int;
1992233d2500723e5594f3e7c70896ffeeef32b9c950ywan          }
1993233d2500723e5594f3e7c70896ffeeef32b9c950ywan
1994233d2500723e5594f3e7c70896ffeeef32b9c950ywan          if (!subpelmv && have_ref &&
1995233d2500723e5594f3e7c70896ffeeef32b9c950ywan              ref_bsi->rdstat[i][mode_idx].brdcost < INT64_MAX) {
1996233d2500723e5594f3e7c70896ffeeef32b9c950ywan            vpx_memcpy(&bsi->rdstat[i][mode_idx], &ref_bsi->rdstat[i][mode_idx],
1997233d2500723e5594f3e7c70896ffeeef32b9c950ywan                       sizeof(SEG_RDSTAT));
1998233d2500723e5594f3e7c70896ffeeef32b9c950ywan            if (num_4x4_blocks_wide > 1)
1999233d2500723e5594f3e7c70896ffeeef32b9c950ywan              bsi->rdstat[i + 1][mode_idx].eobs =
2000233d2500723e5594f3e7c70896ffeeef32b9c950ywan                  ref_bsi->rdstat[i + 1][mode_idx].eobs;
2001233d2500723e5594f3e7c70896ffeeef32b9c950ywan            if (num_4x4_blocks_high > 1)
2002233d2500723e5594f3e7c70896ffeeef32b9c950ywan              bsi->rdstat[i + 2][mode_idx].eobs =
2003233d2500723e5594f3e7c70896ffeeef32b9c950ywan                  ref_bsi->rdstat[i + 2][mode_idx].eobs;
2004233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2005233d2500723e5594f3e7c70896ffeeef32b9c950ywan            if (bsi->rdstat[i][mode_idx].brdcost < best_rd) {
2006233d2500723e5594f3e7c70896ffeeef32b9c950ywan              mode_selected = this_mode;
2007233d2500723e5594f3e7c70896ffeeef32b9c950ywan              best_rd = bsi->rdstat[i][mode_idx].brdcost;
2008233d2500723e5594f3e7c70896ffeeef32b9c950ywan            }
2009233d2500723e5594f3e7c70896ffeeef32b9c950ywan            continue;
2010233d2500723e5594f3e7c70896ffeeef32b9c950ywan          }
2011233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
2012233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2013233d2500723e5594f3e7c70896ffeeef32b9c950ywan        bsi->rdstat[i][mode_idx].brdcost =
2014233d2500723e5594f3e7c70896ffeeef32b9c950ywan            encode_inter_mb_segment(cpi, x,
2015233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                    bsi->segment_rd - this_segment_rd, i,
2016233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                    &bsi->rdstat[i][mode_idx].byrate,
2017233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                    &bsi->rdstat[i][mode_idx].bdist,
2018233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                    &bsi->rdstat[i][mode_idx].bsse,
2019233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                    bsi->rdstat[i][mode_idx].ta,
2020233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                    bsi->rdstat[i][mode_idx].tl,
2021233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                    mi_row, mi_col);
2022233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (bsi->rdstat[i][mode_idx].brdcost < INT64_MAX) {
2023233d2500723e5594f3e7c70896ffeeef32b9c950ywan          bsi->rdstat[i][mode_idx].brdcost += RDCOST(x->rdmult, x->rddiv,
2024233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                            bsi->rdstat[i][mode_idx].brate, 0);
2025233d2500723e5594f3e7c70896ffeeef32b9c950ywan          bsi->rdstat[i][mode_idx].brate += bsi->rdstat[i][mode_idx].byrate;
2026233d2500723e5594f3e7c70896ffeeef32b9c950ywan          bsi->rdstat[i][mode_idx].eobs = p->eobs[i];
2027233d2500723e5594f3e7c70896ffeeef32b9c950ywan          if (num_4x4_blocks_wide > 1)
2028233d2500723e5594f3e7c70896ffeeef32b9c950ywan            bsi->rdstat[i + 1][mode_idx].eobs = p->eobs[i + 1];
2029233d2500723e5594f3e7c70896ffeeef32b9c950ywan          if (num_4x4_blocks_high > 1)
2030233d2500723e5594f3e7c70896ffeeef32b9c950ywan            bsi->rdstat[i + 2][mode_idx].eobs = p->eobs[i + 2];
2031233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
2032233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2033233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (bsi->rdstat[i][mode_idx].brdcost < best_rd) {
2034233d2500723e5594f3e7c70896ffeeef32b9c950ywan          mode_selected = this_mode;
2035233d2500723e5594f3e7c70896ffeeef32b9c950ywan          best_rd = bsi->rdstat[i][mode_idx].brdcost;
2036233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
2037233d2500723e5594f3e7c70896ffeeef32b9c950ywan      } /*for each 4x4 mode*/
2038233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2039233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (best_rd == INT64_MAX) {
2040233d2500723e5594f3e7c70896ffeeef32b9c950ywan        int iy, midx;
2041233d2500723e5594f3e7c70896ffeeef32b9c950ywan        for (iy = i + 1; iy < 4; ++iy)
2042233d2500723e5594f3e7c70896ffeeef32b9c950ywan          for (midx = 0; midx < INTER_MODES; ++midx)
2043233d2500723e5594f3e7c70896ffeeef32b9c950ywan            bsi->rdstat[iy][midx].brdcost = INT64_MAX;
2044233d2500723e5594f3e7c70896ffeeef32b9c950ywan        bsi->segment_rd = INT64_MAX;
2045233d2500723e5594f3e7c70896ffeeef32b9c950ywan        return;
2046233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
2047233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2048233d2500723e5594f3e7c70896ffeeef32b9c950ywan      mode_idx = INTER_OFFSET(mode_selected);
2049233d2500723e5594f3e7c70896ffeeef32b9c950ywan      vpx_memcpy(t_above, bsi->rdstat[i][mode_idx].ta, sizeof(t_above));
2050233d2500723e5594f3e7c70896ffeeef32b9c950ywan      vpx_memcpy(t_left, bsi->rdstat[i][mode_idx].tl, sizeof(t_left));
2051233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2052233d2500723e5594f3e7c70896ffeeef32b9c950ywan      labels2mode(cpi, xd, i, mode_selected, mode_mv[mode_selected],
2053233d2500723e5594f3e7c70896ffeeef32b9c950ywan                  frame_mv, seg_mvs[i], bsi->ref_mv, x->nmvjointcost,
2054233d2500723e5594f3e7c70896ffeeef32b9c950ywan                  x->mvcost);
2055233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2056233d2500723e5594f3e7c70896ffeeef32b9c950ywan      br += bsi->rdstat[i][mode_idx].brate;
2057233d2500723e5594f3e7c70896ffeeef32b9c950ywan      bd += bsi->rdstat[i][mode_idx].bdist;
2058233d2500723e5594f3e7c70896ffeeef32b9c950ywan      block_sse += bsi->rdstat[i][mode_idx].bsse;
2059233d2500723e5594f3e7c70896ffeeef32b9c950ywan      segmentyrate += bsi->rdstat[i][mode_idx].byrate;
2060233d2500723e5594f3e7c70896ffeeef32b9c950ywan      this_segment_rd += bsi->rdstat[i][mode_idx].brdcost;
2061233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2062233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (this_segment_rd > bsi->segment_rd) {
2063233d2500723e5594f3e7c70896ffeeef32b9c950ywan        int iy, midx;
2064233d2500723e5594f3e7c70896ffeeef32b9c950ywan        for (iy = i + 1; iy < 4; ++iy)
2065233d2500723e5594f3e7c70896ffeeef32b9c950ywan          for (midx = 0; midx < INTER_MODES; ++midx)
2066233d2500723e5594f3e7c70896ffeeef32b9c950ywan            bsi->rdstat[iy][midx].brdcost = INT64_MAX;
2067233d2500723e5594f3e7c70896ffeeef32b9c950ywan        bsi->segment_rd = INT64_MAX;
2068233d2500723e5594f3e7c70896ffeeef32b9c950ywan        return;
2069233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
2070233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
2071233d2500723e5594f3e7c70896ffeeef32b9c950ywan  } /* for each label */
2072233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2073233d2500723e5594f3e7c70896ffeeef32b9c950ywan  bsi->r = br;
2074233d2500723e5594f3e7c70896ffeeef32b9c950ywan  bsi->d = bd;
2075233d2500723e5594f3e7c70896ffeeef32b9c950ywan  bsi->segment_yrate = segmentyrate;
2076233d2500723e5594f3e7c70896ffeeef32b9c950ywan  bsi->segment_rd = this_segment_rd;
2077233d2500723e5594f3e7c70896ffeeef32b9c950ywan  bsi->sse = block_sse;
2078233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2079233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // update the coding decisions
2080233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (k = 0; k < 4; ++k)
2081233d2500723e5594f3e7c70896ffeeef32b9c950ywan    bsi->modes[k] = mi->bmi[k].as_mode;
2082233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
2083233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2084233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int64_t rd_pick_best_mbsegmentation(VP9_COMP *cpi, MACROBLOCK *x,
2085233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                           const TileInfo *const tile,
2086233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                           int_mv *best_ref_mv,
2087233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                           int_mv *second_best_ref_mv,
2088233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                           int64_t best_rd,
2089233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                           int *returntotrate,
2090233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                           int *returnyrate,
2091233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                           int64_t *returndistortion,
2092233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                           int *skippable, int64_t *psse,
2093233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                           int mvthresh,
2094233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                           int_mv seg_mvs[4][MAX_REF_FRAMES],
2095233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                           BEST_SEG_INFO *bsi_buf,
2096233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                           int filter_idx,
2097233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                           int mi_row, int mi_col) {
2098233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int i;
2099233d2500723e5594f3e7c70896ffeeef32b9c950ywan  BEST_SEG_INFO *bsi = bsi_buf + filter_idx;
2100233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MACROBLOCKD *xd = &x->e_mbd;
2101233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MODE_INFO *mi = xd->mi[0];
2102233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MB_MODE_INFO *mbmi = &mi->mbmi;
2103233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int mode_idx;
2104233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2105233d2500723e5594f3e7c70896ffeeef32b9c950ywan  vp9_zero(*bsi);
2106233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2107233d2500723e5594f3e7c70896ffeeef32b9c950ywan  bsi->segment_rd = best_rd;
2108233d2500723e5594f3e7c70896ffeeef32b9c950ywan  bsi->ref_mv[0] = best_ref_mv;
2109233d2500723e5594f3e7c70896ffeeef32b9c950ywan  bsi->ref_mv[1] = second_best_ref_mv;
2110233d2500723e5594f3e7c70896ffeeef32b9c950ywan  bsi->mvp.as_int = best_ref_mv->as_int;
2111233d2500723e5594f3e7c70896ffeeef32b9c950ywan  bsi->mvthresh = mvthresh;
2112233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2113233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (i = 0; i < 4; i++)
2114233d2500723e5594f3e7c70896ffeeef32b9c950ywan    bsi->modes[i] = ZEROMV;
2115233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2116233d2500723e5594f3e7c70896ffeeef32b9c950ywan  rd_check_segment_txsize(cpi, x, tile, bsi_buf, filter_idx, seg_mvs,
2117233d2500723e5594f3e7c70896ffeeef32b9c950ywan                          mi_row, mi_col);
2118233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2119233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (bsi->segment_rd > best_rd)
2120233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return INT64_MAX;
2121233d2500723e5594f3e7c70896ffeeef32b9c950ywan  /* set it to the best */
2122233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (i = 0; i < 4; i++) {
2123233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mode_idx = INTER_OFFSET(bsi->modes[i]);
2124233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mi->bmi[i].as_mv[0].as_int = bsi->rdstat[i][mode_idx].mvs[0].as_int;
2125233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (has_second_ref(mbmi))
2126233d2500723e5594f3e7c70896ffeeef32b9c950ywan      mi->bmi[i].as_mv[1].as_int = bsi->rdstat[i][mode_idx].mvs[1].as_int;
2127233d2500723e5594f3e7c70896ffeeef32b9c950ywan    x->plane[0].eobs[i] = bsi->rdstat[i][mode_idx].eobs;
2128233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mi->bmi[i].as_mode = bsi->modes[i];
2129233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
2130233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2131233d2500723e5594f3e7c70896ffeeef32b9c950ywan  /*
2132233d2500723e5594f3e7c70896ffeeef32b9c950ywan   * used to set mbmi->mv.as_int
2133233d2500723e5594f3e7c70896ffeeef32b9c950ywan   */
2134233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *returntotrate = bsi->r;
2135233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *returndistortion = bsi->d;
2136233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *returnyrate = bsi->segment_yrate;
2137233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *skippable = vp9_is_skippable_in_plane(x, BLOCK_8X8, 0);
2138233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *psse = bsi->sse;
2139233d2500723e5594f3e7c70896ffeeef32b9c950ywan  mbmi->mode = bsi->modes[3];
2140233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2141233d2500723e5594f3e7c70896ffeeef32b9c950ywan  return bsi->segment_rd;
2142233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
2143233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2144233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void mv_pred(VP9_COMP *cpi, MACROBLOCK *x,
2145233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    uint8_t *ref_y_buffer, int ref_y_stride,
2146233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    int ref_frame, BLOCK_SIZE block_size ) {
2147233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MACROBLOCKD *xd = &x->e_mbd;
2148233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
2149233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int_mv this_mv;
2150233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int i;
2151233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int zero_seen = 0;
2152233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int best_index = 0;
2153233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int best_sad = INT_MAX;
2154233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int this_sad = INT_MAX;
2155233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int max_mv = 0;
2156233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2157233d2500723e5594f3e7c70896ffeeef32b9c950ywan  uint8_t *src_y_ptr = x->plane[0].src.buf;
2158233d2500723e5594f3e7c70896ffeeef32b9c950ywan  uint8_t *ref_y_ptr;
2159233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int row_offset, col_offset;
2160233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int num_mv_refs = MAX_MV_REF_CANDIDATES +
2161233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    (cpi->sf.adaptive_motion_search &&
2162233d2500723e5594f3e7c70896ffeeef32b9c950ywan                     cpi->common.show_frame &&
2163233d2500723e5594f3e7c70896ffeeef32b9c950ywan                     block_size < cpi->sf.max_partition_size);
2164233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2165233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int_mv pred_mv[3];
2166233d2500723e5594f3e7c70896ffeeef32b9c950ywan  pred_mv[0] = mbmi->ref_mvs[ref_frame][0];
2167233d2500723e5594f3e7c70896ffeeef32b9c950ywan  pred_mv[1] = mbmi->ref_mvs[ref_frame][1];
2168233d2500723e5594f3e7c70896ffeeef32b9c950ywan  pred_mv[2] = x->pred_mv[ref_frame];
2169233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2170233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Get the sad for each candidate reference mv
2171233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (i = 0; i < num_mv_refs; i++) {
2172233d2500723e5594f3e7c70896ffeeef32b9c950ywan    this_mv.as_int = pred_mv[i].as_int;
2173233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2174233d2500723e5594f3e7c70896ffeeef32b9c950ywan    max_mv = MAX(max_mv,
2175233d2500723e5594f3e7c70896ffeeef32b9c950ywan                 MAX(abs(this_mv.as_mv.row), abs(this_mv.as_mv.col)) >> 3);
2176233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // only need to check zero mv once
2177233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (!this_mv.as_int && zero_seen)
2178233d2500723e5594f3e7c70896ffeeef32b9c950ywan      continue;
2179233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2180233d2500723e5594f3e7c70896ffeeef32b9c950ywan    zero_seen = zero_seen || !this_mv.as_int;
2181233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2182233d2500723e5594f3e7c70896ffeeef32b9c950ywan    row_offset = this_mv.as_mv.row >> 3;
2183233d2500723e5594f3e7c70896ffeeef32b9c950ywan    col_offset = this_mv.as_mv.col >> 3;
2184233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ref_y_ptr = ref_y_buffer + (ref_y_stride * row_offset) + col_offset;
2185233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2186233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Find sad for current vector.
2187233d2500723e5594f3e7c70896ffeeef32b9c950ywan    this_sad = cpi->fn_ptr[block_size].sdf(src_y_ptr, x->plane[0].src.stride,
2188233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                           ref_y_ptr, ref_y_stride,
2189233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                           0x7fffffff);
2190233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2191233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Note if it is the best so far.
2192233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (this_sad < best_sad) {
2193233d2500723e5594f3e7c70896ffeeef32b9c950ywan      best_sad = this_sad;
2194233d2500723e5594f3e7c70896ffeeef32b9c950ywan      best_index = i;
2195233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
2196233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
2197233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2198233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Note the index of the mv that worked best in the reference list.
2199233d2500723e5594f3e7c70896ffeeef32b9c950ywan  x->mv_best_ref_index[ref_frame] = best_index;
2200233d2500723e5594f3e7c70896ffeeef32b9c950ywan  x->max_mv_context[ref_frame] = max_mv;
2201233d2500723e5594f3e7c70896ffeeef32b9c950ywan  x->pred_mv_sad[ref_frame] = best_sad;
2202233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
2203233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2204233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void estimate_ref_frame_costs(VP9_COMP *cpi, int segment_id,
2205233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                     unsigned int *ref_costs_single,
2206233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                     unsigned int *ref_costs_comp,
2207233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                     vp9_prob *comp_mode_p) {
2208233d2500723e5594f3e7c70896ffeeef32b9c950ywan  VP9_COMMON *const cm = &cpi->common;
2209233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MACROBLOCKD *const xd = &cpi->mb.e_mbd;
2210233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int seg_ref_active = vp9_segfeature_active(&cm->seg, segment_id,
2211233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                             SEG_LVL_REF_FRAME);
2212233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (seg_ref_active) {
2213233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vpx_memset(ref_costs_single, 0, MAX_REF_FRAMES * sizeof(*ref_costs_single));
2214233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vpx_memset(ref_costs_comp,   0, MAX_REF_FRAMES * sizeof(*ref_costs_comp));
2215233d2500723e5594f3e7c70896ffeeef32b9c950ywan    *comp_mode_p = 128;
2216233d2500723e5594f3e7c70896ffeeef32b9c950ywan  } else {
2217233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vp9_prob intra_inter_p = vp9_get_intra_inter_prob(cm, xd);
2218233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vp9_prob comp_inter_p = 128;
2219233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2220233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (cm->reference_mode == REFERENCE_MODE_SELECT) {
2221233d2500723e5594f3e7c70896ffeeef32b9c950ywan      comp_inter_p = vp9_get_reference_mode_prob(cm, xd);
2222233d2500723e5594f3e7c70896ffeeef32b9c950ywan      *comp_mode_p = comp_inter_p;
2223233d2500723e5594f3e7c70896ffeeef32b9c950ywan    } else {
2224233d2500723e5594f3e7c70896ffeeef32b9c950ywan      *comp_mode_p = 128;
2225233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
2226233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2227233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ref_costs_single[INTRA_FRAME] = vp9_cost_bit(intra_inter_p, 0);
2228233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2229233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (cm->reference_mode != COMPOUND_REFERENCE) {
2230233d2500723e5594f3e7c70896ffeeef32b9c950ywan      vp9_prob ref_single_p1 = vp9_get_pred_prob_single_ref_p1(cm, xd);
2231233d2500723e5594f3e7c70896ffeeef32b9c950ywan      vp9_prob ref_single_p2 = vp9_get_pred_prob_single_ref_p2(cm, xd);
2232233d2500723e5594f3e7c70896ffeeef32b9c950ywan      unsigned int base_cost = vp9_cost_bit(intra_inter_p, 1);
2233233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2234233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (cm->reference_mode == REFERENCE_MODE_SELECT)
2235233d2500723e5594f3e7c70896ffeeef32b9c950ywan        base_cost += vp9_cost_bit(comp_inter_p, 0);
2236233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2237233d2500723e5594f3e7c70896ffeeef32b9c950ywan      ref_costs_single[LAST_FRAME] = ref_costs_single[GOLDEN_FRAME] =
2238233d2500723e5594f3e7c70896ffeeef32b9c950ywan          ref_costs_single[ALTREF_FRAME] = base_cost;
2239233d2500723e5594f3e7c70896ffeeef32b9c950ywan      ref_costs_single[LAST_FRAME]   += vp9_cost_bit(ref_single_p1, 0);
2240233d2500723e5594f3e7c70896ffeeef32b9c950ywan      ref_costs_single[GOLDEN_FRAME] += vp9_cost_bit(ref_single_p1, 1);
2241233d2500723e5594f3e7c70896ffeeef32b9c950ywan      ref_costs_single[ALTREF_FRAME] += vp9_cost_bit(ref_single_p1, 1);
2242233d2500723e5594f3e7c70896ffeeef32b9c950ywan      ref_costs_single[GOLDEN_FRAME] += vp9_cost_bit(ref_single_p2, 0);
2243233d2500723e5594f3e7c70896ffeeef32b9c950ywan      ref_costs_single[ALTREF_FRAME] += vp9_cost_bit(ref_single_p2, 1);
2244233d2500723e5594f3e7c70896ffeeef32b9c950ywan    } else {
2245233d2500723e5594f3e7c70896ffeeef32b9c950ywan      ref_costs_single[LAST_FRAME]   = 512;
2246233d2500723e5594f3e7c70896ffeeef32b9c950ywan      ref_costs_single[GOLDEN_FRAME] = 512;
2247233d2500723e5594f3e7c70896ffeeef32b9c950ywan      ref_costs_single[ALTREF_FRAME] = 512;
2248233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
2249233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (cm->reference_mode != SINGLE_REFERENCE) {
2250233d2500723e5594f3e7c70896ffeeef32b9c950ywan      vp9_prob ref_comp_p = vp9_get_pred_prob_comp_ref_p(cm, xd);
2251233d2500723e5594f3e7c70896ffeeef32b9c950ywan      unsigned int base_cost = vp9_cost_bit(intra_inter_p, 1);
2252233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2253233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (cm->reference_mode == REFERENCE_MODE_SELECT)
2254233d2500723e5594f3e7c70896ffeeef32b9c950ywan        base_cost += vp9_cost_bit(comp_inter_p, 1);
2255233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2256233d2500723e5594f3e7c70896ffeeef32b9c950ywan      ref_costs_comp[LAST_FRAME]   = base_cost + vp9_cost_bit(ref_comp_p, 0);
2257233d2500723e5594f3e7c70896ffeeef32b9c950ywan      ref_costs_comp[GOLDEN_FRAME] = base_cost + vp9_cost_bit(ref_comp_p, 1);
2258233d2500723e5594f3e7c70896ffeeef32b9c950ywan    } else {
2259233d2500723e5594f3e7c70896ffeeef32b9c950ywan      ref_costs_comp[LAST_FRAME]   = 512;
2260233d2500723e5594f3e7c70896ffeeef32b9c950ywan      ref_costs_comp[GOLDEN_FRAME] = 512;
2261233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
2262233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
2263233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
2264233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2265233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void store_coding_context(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
2266233d2500723e5594f3e7c70896ffeeef32b9c950ywan                         int mode_index,
2267233d2500723e5594f3e7c70896ffeeef32b9c950ywan                         int_mv *ref_mv,
2268233d2500723e5594f3e7c70896ffeeef32b9c950ywan                         int_mv *second_ref_mv,
2269233d2500723e5594f3e7c70896ffeeef32b9c950ywan                         int64_t comp_pred_diff[REFERENCE_MODES],
2270233d2500723e5594f3e7c70896ffeeef32b9c950ywan                         int64_t tx_size_diff[TX_MODES],
2271233d2500723e5594f3e7c70896ffeeef32b9c950ywan                         int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS]) {
2272233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MACROBLOCKD *const xd = &x->e_mbd;
2273233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2274233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Take a snapshot of the coding context so it can be
2275233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // restored if we decide to encode this way
2276233d2500723e5594f3e7c70896ffeeef32b9c950ywan  ctx->skip = x->skip;
2277233d2500723e5594f3e7c70896ffeeef32b9c950ywan  ctx->best_mode_index = mode_index;
2278233d2500723e5594f3e7c70896ffeeef32b9c950ywan  ctx->mic = *xd->mi[0];
2279233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2280233d2500723e5594f3e7c70896ffeeef32b9c950ywan  ctx->best_ref_mv[0].as_int = ref_mv->as_int;
2281233d2500723e5594f3e7c70896ffeeef32b9c950ywan  ctx->best_ref_mv[1].as_int = second_ref_mv->as_int;
2282233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2283233d2500723e5594f3e7c70896ffeeef32b9c950ywan  ctx->single_pred_diff = (int)comp_pred_diff[SINGLE_REFERENCE];
2284233d2500723e5594f3e7c70896ffeeef32b9c950ywan  ctx->comp_pred_diff   = (int)comp_pred_diff[COMPOUND_REFERENCE];
2285233d2500723e5594f3e7c70896ffeeef32b9c950ywan  ctx->hybrid_pred_diff = (int)comp_pred_diff[REFERENCE_MODE_SELECT];
2286233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2287233d2500723e5594f3e7c70896ffeeef32b9c950ywan  vpx_memcpy(ctx->tx_rd_diff, tx_size_diff, sizeof(ctx->tx_rd_diff));
2288233d2500723e5594f3e7c70896ffeeef32b9c950ywan  vpx_memcpy(ctx->best_filter_diff, best_filter_diff,
2289233d2500723e5594f3e7c70896ffeeef32b9c950ywan             sizeof(*best_filter_diff) * SWITCHABLE_FILTER_CONTEXTS);
2290233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
2291233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2292233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void setup_pred_block(const MACROBLOCKD *xd,
2293233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             struct buf_2d dst[MAX_MB_PLANE],
2294233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             const YV12_BUFFER_CONFIG *src,
2295233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             int mi_row, int mi_col,
2296233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             const struct scale_factors *scale,
2297233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             const struct scale_factors *scale_uv) {
2298233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int i;
2299233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2300233d2500723e5594f3e7c70896ffeeef32b9c950ywan  dst[0].buf = src->y_buffer;
2301233d2500723e5594f3e7c70896ffeeef32b9c950ywan  dst[0].stride = src->y_stride;
2302233d2500723e5594f3e7c70896ffeeef32b9c950ywan  dst[1].buf = src->u_buffer;
2303233d2500723e5594f3e7c70896ffeeef32b9c950ywan  dst[2].buf = src->v_buffer;
2304233d2500723e5594f3e7c70896ffeeef32b9c950ywan  dst[1].stride = dst[2].stride = src->uv_stride;
2305233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if CONFIG_ALPHA
2306233d2500723e5594f3e7c70896ffeeef32b9c950ywan  dst[3].buf = src->alpha_buffer;
2307233d2500723e5594f3e7c70896ffeeef32b9c950ywan  dst[3].stride = src->alpha_stride;
2308233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif
2309233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2310233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // TODO(jkoleszar): Make scale factors per-plane data
2311233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (i = 0; i < MAX_MB_PLANE; i++) {
2312233d2500723e5594f3e7c70896ffeeef32b9c950ywan    setup_pred_plane(dst + i, dst[i].buf, dst[i].stride, mi_row, mi_col,
2313233d2500723e5594f3e7c70896ffeeef32b9c950ywan                     i ? scale_uv : scale,
2314233d2500723e5594f3e7c70896ffeeef32b9c950ywan                     xd->plane[i].subsampling_x, xd->plane[i].subsampling_y);
2315233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
2316233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
2317233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2318233d2500723e5594f3e7c70896ffeeef32b9c950ywanvoid vp9_setup_buffer_inter(VP9_COMP *cpi, MACROBLOCK *x,
2319233d2500723e5594f3e7c70896ffeeef32b9c950ywan                            const TileInfo *const tile,
2320233d2500723e5594f3e7c70896ffeeef32b9c950ywan                            MV_REFERENCE_FRAME ref_frame,
2321233d2500723e5594f3e7c70896ffeeef32b9c950ywan                            BLOCK_SIZE block_size,
2322233d2500723e5594f3e7c70896ffeeef32b9c950ywan                            int mi_row, int mi_col,
2323233d2500723e5594f3e7c70896ffeeef32b9c950ywan                            int_mv frame_nearest_mv[MAX_REF_FRAMES],
2324233d2500723e5594f3e7c70896ffeeef32b9c950ywan                            int_mv frame_near_mv[MAX_REF_FRAMES],
2325233d2500723e5594f3e7c70896ffeeef32b9c950ywan                            struct buf_2d yv12_mb[4][MAX_MB_PLANE]) {
2326233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const VP9_COMMON *cm = &cpi->common;
2327233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame);
2328233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MACROBLOCKD *const xd = &x->e_mbd;
2329233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MODE_INFO *const mi = xd->mi[0];
2330233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int_mv *const candidates = mi->mbmi.ref_mvs[ref_frame];
2331233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const struct scale_factors *const sf = &cm->frame_refs[ref_frame - 1].sf;
2332233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2333233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // TODO(jkoleszar): Is the UV buffer ever used here? If so, need to make this
2334233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // use the UV scaling factors.
2335233d2500723e5594f3e7c70896ffeeef32b9c950ywan  setup_pred_block(xd, yv12_mb[ref_frame], yv12, mi_row, mi_col, sf, sf);
2336233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2337233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Gets an initial list of candidate vectors from neighbours and orders them
2338233d2500723e5594f3e7c70896ffeeef32b9c950ywan  vp9_find_mv_refs(cm, xd, tile, mi, ref_frame, candidates, mi_row, mi_col);
2339233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2340233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Candidate refinement carried out at encoder and decoder
2341233d2500723e5594f3e7c70896ffeeef32b9c950ywan  vp9_find_best_ref_mvs(xd, cm->allow_high_precision_mv, candidates,
2342233d2500723e5594f3e7c70896ffeeef32b9c950ywan                        &frame_nearest_mv[ref_frame],
2343233d2500723e5594f3e7c70896ffeeef32b9c950ywan                        &frame_near_mv[ref_frame]);
2344233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2345233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Further refinement that is encode side only to test the top few candidates
2346233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // in full and choose the best as the centre point for subsequent searches.
2347233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // The current implementation doesn't support scaling.
2348233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (!vp9_is_scaled(sf) && block_size >= BLOCK_8X8)
2349233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12->y_stride,
2350233d2500723e5594f3e7c70896ffeeef32b9c950ywan            ref_frame, block_size);
2351233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
2352233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2353233d2500723e5594f3e7c70896ffeeef32b9c950ywanconst YV12_BUFFER_CONFIG *vp9_get_scaled_ref_frame(const VP9_COMP *cpi,
2354233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                                   int ref_frame) {
2355233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const VP9_COMMON *const cm = &cpi->common;
2356233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int ref_idx = cm->ref_frame_map[get_ref_frame_idx(cpi, ref_frame)];
2357233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int scaled_idx = cpi->scaled_ref_idx[ref_frame - 1];
2358233d2500723e5594f3e7c70896ffeeef32b9c950ywan  return (scaled_idx != ref_idx) ? &cm->frame_bufs[scaled_idx].buf : NULL;
2359233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
2360233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2361233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic INLINE int get_switchable_rate(const MACROBLOCK *x) {
2362233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const MACROBLOCKD *const xd = &x->e_mbd;
2363233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
2364233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int ctx = vp9_get_pred_context_switchable_interp(xd);
2365233d2500723e5594f3e7c70896ffeeef32b9c950ywan  return SWITCHABLE_INTERP_RATE_FACTOR *
2366233d2500723e5594f3e7c70896ffeeef32b9c950ywan             x->switchable_interp_costs[ctx][mbmi->interp_filter];
2367233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
2368233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2369233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
2370233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                 const TileInfo *const tile,
2371233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                 BLOCK_SIZE bsize,
2372233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                 int mi_row, int mi_col,
2373233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                 int_mv *tmp_mv, int *rate_mv) {
2374233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MACROBLOCKD *xd = &x->e_mbd;
2375233d2500723e5594f3e7c70896ffeeef32b9c950ywan  VP9_COMMON *cm = &cpi->common;
2376233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
2377233d2500723e5594f3e7c70896ffeeef32b9c950ywan  struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0}};
2378233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int bestsme = INT_MAX;
2379233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int further_steps, step_param;
2380233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int sadpb = x->sadperbit16;
2381233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MV mvp_full;
2382233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int ref = mbmi->ref_frame[0];
2383233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MV ref_mv = mbmi->ref_mvs[ref][0].as_mv;
2384233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2385233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int tmp_col_min = x->mv_col_min;
2386233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int tmp_col_max = x->mv_col_max;
2387233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int tmp_row_min = x->mv_row_min;
2388233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int tmp_row_max = x->mv_row_max;
2389233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2390233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const YV12_BUFFER_CONFIG *scaled_ref_frame = vp9_get_scaled_ref_frame(cpi,
2391233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                                                        ref);
2392233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2393233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MV pred_mv[3];
2394233d2500723e5594f3e7c70896ffeeef32b9c950ywan  pred_mv[0] = mbmi->ref_mvs[ref][0].as_mv;
2395233d2500723e5594f3e7c70896ffeeef32b9c950ywan  pred_mv[1] = mbmi->ref_mvs[ref][1].as_mv;
2396233d2500723e5594f3e7c70896ffeeef32b9c950ywan  pred_mv[2] = x->pred_mv[ref].as_mv;
2397233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2398233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (scaled_ref_frame) {
2399233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int i;
2400233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Swap out the reference frame for a version that's been scaled to
2401233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // match the resolution of the current frame, allowing the existing
2402233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // motion search code to be used without additional modifications.
2403233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (i = 0; i < MAX_MB_PLANE; i++)
2404233d2500723e5594f3e7c70896ffeeef32b9c950ywan      backup_yv12[i] = xd->plane[i].pre[0];
2405233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2406233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vp9_setup_pre_planes(xd, 0, scaled_ref_frame, mi_row, mi_col, NULL);
2407233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
2408233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2409233d2500723e5594f3e7c70896ffeeef32b9c950ywan  vp9_set_mv_search_range(x, &ref_mv);
2410233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2411233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Work out the size of the first step in the mv step search.
2412233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // 0 here is maximum length first step. 1 is MAX >> 1 etc.
2413233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (cpi->sf.auto_mv_step_size && cpi->common.show_frame) {
2414233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Take wtd average of the step_params based on the last frame's
2415233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // max mv magnitude and that based on the best ref mvs of the current
2416233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // block for the given reference.
2417233d2500723e5594f3e7c70896ffeeef32b9c950ywan    step_param = (vp9_init_search_range(cpi, x->max_mv_context[ref]) +
2418233d2500723e5594f3e7c70896ffeeef32b9c950ywan                  cpi->mv_step_param) >> 1;
2419233d2500723e5594f3e7c70896ffeeef32b9c950ywan  } else {
2420233d2500723e5594f3e7c70896ffeeef32b9c950ywan    step_param = cpi->mv_step_param;
2421233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
2422233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2423233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (cpi->sf.adaptive_motion_search && bsize < BLOCK_64X64 &&
2424233d2500723e5594f3e7c70896ffeeef32b9c950ywan      cpi->common.show_frame) {
2425233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int boffset = 2 * (b_width_log2(BLOCK_64X64) - MIN(b_height_log2(bsize),
2426233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                                       b_width_log2(bsize)));
2427233d2500723e5594f3e7c70896ffeeef32b9c950ywan    step_param = MAX(step_param, boffset);
2428233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
2429233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2430233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (cpi->sf.adaptive_motion_search) {
2431233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int bwl = b_width_log2_lookup[bsize];
2432233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int bhl = b_height_log2_lookup[bsize];
2433233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int i;
2434233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
2435233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2436233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (tlevel < 5)
2437233d2500723e5594f3e7c70896ffeeef32b9c950ywan      step_param += 2;
2438233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2439233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (i = LAST_FRAME; i <= ALTREF_FRAME && cpi->common.show_frame; ++i) {
2440233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
2441233d2500723e5594f3e7c70896ffeeef32b9c950ywan        x->pred_mv[ref].as_int = 0;
2442233d2500723e5594f3e7c70896ffeeef32b9c950ywan        tmp_mv->as_int = INVALID_MV;
2443233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2444233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (scaled_ref_frame) {
2445233d2500723e5594f3e7c70896ffeeef32b9c950ywan          int i;
2446233d2500723e5594f3e7c70896ffeeef32b9c950ywan          for (i = 0; i < MAX_MB_PLANE; i++)
2447233d2500723e5594f3e7c70896ffeeef32b9c950ywan            xd->plane[i].pre[0] = backup_yv12[i];
2448233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
2449233d2500723e5594f3e7c70896ffeeef32b9c950ywan        return;
2450233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
2451233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
2452233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
2453233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2454233d2500723e5594f3e7c70896ffeeef32b9c950ywan  mvp_full = pred_mv[x->mv_best_ref_index[ref]];
2455233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2456233d2500723e5594f3e7c70896ffeeef32b9c950ywan  mvp_full.col >>= 3;
2457233d2500723e5594f3e7c70896ffeeef32b9c950ywan  mvp_full.row >>= 3;
2458233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2459233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Further step/diamond searches as necessary
2460233d2500723e5594f3e7c70896ffeeef32b9c950ywan  further_steps = (cpi->sf.max_step_search_steps - 1) - step_param;
2461233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2462233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (cpi->sf.search_method == FAST_DIAMOND) {
2463233d2500723e5594f3e7c70896ffeeef32b9c950ywan    bestsme = vp9_fast_dia_search(x, &mvp_full, step_param, sadpb, 0,
2464233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  &cpi->fn_ptr[bsize], 1,
2465233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  &ref_mv, &tmp_mv->as_mv);
2466233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (bestsme < INT_MAX)
2467233d2500723e5594f3e7c70896ffeeef32b9c950ywan      bestsme = vp9_get_mvpred_var(x, &tmp_mv->as_mv, &ref_mv,
2468233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                   &cpi->fn_ptr[bsize], 1);
2469233d2500723e5594f3e7c70896ffeeef32b9c950ywan  } else if (cpi->sf.search_method == FAST_HEX) {
2470233d2500723e5594f3e7c70896ffeeef32b9c950ywan    bestsme = vp9_fast_hex_search(x, &mvp_full, step_param, sadpb, 0,
2471233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  &cpi->fn_ptr[bsize], 1,
2472233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  &ref_mv, &tmp_mv->as_mv);
2473233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (bestsme < INT_MAX)
2474233d2500723e5594f3e7c70896ffeeef32b9c950ywan      bestsme = vp9_get_mvpred_var(x, &tmp_mv->as_mv, &ref_mv,
2475233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                   &cpi->fn_ptr[bsize], 1);
2476233d2500723e5594f3e7c70896ffeeef32b9c950ywan  } else if (cpi->sf.search_method == HEX) {
2477233d2500723e5594f3e7c70896ffeeef32b9c950ywan    bestsme = vp9_hex_search(x, &mvp_full, step_param, sadpb, 1,
2478233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             &cpi->fn_ptr[bsize], 1,
2479233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             &ref_mv, &tmp_mv->as_mv);
2480233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (bestsme < INT_MAX)
2481233d2500723e5594f3e7c70896ffeeef32b9c950ywan      bestsme = vp9_get_mvpred_var(x, &tmp_mv->as_mv, &ref_mv,
2482233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                   &cpi->fn_ptr[bsize], 1);
2483233d2500723e5594f3e7c70896ffeeef32b9c950ywan  } else if (cpi->sf.search_method == SQUARE) {
2484233d2500723e5594f3e7c70896ffeeef32b9c950ywan    bestsme = vp9_square_search(x, &mvp_full, step_param, sadpb, 1,
2485233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                &cpi->fn_ptr[bsize], 1,
2486233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                &ref_mv, &tmp_mv->as_mv);
2487233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (bestsme < INT_MAX)
2488233d2500723e5594f3e7c70896ffeeef32b9c950ywan      bestsme = vp9_get_mvpred_var(x, &tmp_mv->as_mv, &ref_mv,
2489233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                   &cpi->fn_ptr[bsize], 1);
2490233d2500723e5594f3e7c70896ffeeef32b9c950ywan  } else if (cpi->sf.search_method == BIGDIA) {
2491233d2500723e5594f3e7c70896ffeeef32b9c950ywan    bestsme = vp9_bigdia_search(x, &mvp_full, step_param, sadpb, 1,
2492233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                &cpi->fn_ptr[bsize], 1,
2493233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                &ref_mv, &tmp_mv->as_mv);
2494233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (bestsme < INT_MAX)
2495233d2500723e5594f3e7c70896ffeeef32b9c950ywan      bestsme = vp9_get_mvpred_var(x, &tmp_mv->as_mv, &ref_mv,
2496233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                   &cpi->fn_ptr[bsize], 1);
2497233d2500723e5594f3e7c70896ffeeef32b9c950ywan  } else {
2498233d2500723e5594f3e7c70896ffeeef32b9c950ywan    bestsme = vp9_full_pixel_diamond(cpi, x, &mvp_full, step_param,
2499233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                     sadpb, further_steps, 1,
2500233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                     &cpi->fn_ptr[bsize],
2501233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                     &ref_mv, &tmp_mv->as_mv);
2502233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
2503233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2504233d2500723e5594f3e7c70896ffeeef32b9c950ywan  x->mv_col_min = tmp_col_min;
2505233d2500723e5594f3e7c70896ffeeef32b9c950ywan  x->mv_col_max = tmp_col_max;
2506233d2500723e5594f3e7c70896ffeeef32b9c950ywan  x->mv_row_min = tmp_row_min;
2507233d2500723e5594f3e7c70896ffeeef32b9c950ywan  x->mv_row_max = tmp_row_max;
2508233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2509233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (bestsme < INT_MAX) {
2510233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int dis;  /* TODO: use dis in distortion calculation later. */
2511233d2500723e5594f3e7c70896ffeeef32b9c950ywan    cpi->find_fractional_mv_step(x, &tmp_mv->as_mv, &ref_mv,
2512233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                 cm->allow_high_precision_mv,
2513233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                 x->errorperbit,
2514233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                 &cpi->fn_ptr[bsize],
2515233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                 cpi->sf.subpel_force_stop,
2516233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                 cpi->sf.subpel_iters_per_step,
2517233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                 x->nmvjointcost, x->mvcost,
2518233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                 &dis, &x->pred_sse[ref]);
2519233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
2520233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *rate_mv = vp9_mv_bit_cost(&tmp_mv->as_mv, &ref_mv,
2521233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
2522233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2523233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (cpi->sf.adaptive_motion_search && cpi->common.show_frame)
2524233d2500723e5594f3e7c70896ffeeef32b9c950ywan    x->pred_mv[ref].as_int = tmp_mv->as_int;
2525233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2526233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (scaled_ref_frame) {
2527233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int i;
2528233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (i = 0; i < MAX_MB_PLANE; i++)
2529233d2500723e5594f3e7c70896ffeeef32b9c950ywan      xd->plane[i].pre[0] = backup_yv12[i];
2530233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
2531233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
2532233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2533233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
2534233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                BLOCK_SIZE bsize,
2535233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                int_mv *frame_mv,
2536233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                int mi_row, int mi_col,
2537233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                int_mv single_newmv[MAX_REF_FRAMES],
2538233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                int *rate_mv) {
2539233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int pw = 4 * num_4x4_blocks_wide_lookup[bsize];
2540233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int ph = 4 * num_4x4_blocks_high_lookup[bsize];
2541233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MACROBLOCKD *xd = &x->e_mbd;
2542233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
2543233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int refs[2] = { mbmi->ref_frame[0],
2544233d2500723e5594f3e7c70896ffeeef32b9c950ywan                        mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1] };
2545233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int_mv ref_mv[2];
2546233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int ite, ref;
2547233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Prediction buffer from second frame.
2548233d2500723e5594f3e7c70896ffeeef32b9c950ywan  uint8_t *second_pred = vpx_memalign(16, pw * ph * sizeof(uint8_t));
2549233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const InterpKernel *kernel = vp9_get_interp_kernel(mbmi->interp_filter);
2550233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2551233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Do joint motion search in compound mode to get more accurate mv.
2552233d2500723e5594f3e7c70896ffeeef32b9c950ywan  struct buf_2d backup_yv12[2][MAX_MB_PLANE];
2553233d2500723e5594f3e7c70896ffeeef32b9c950ywan  struct buf_2d scaled_first_yv12 = xd->plane[0].pre[0];
2554233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int last_besterr[2] = {INT_MAX, INT_MAX};
2555233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const YV12_BUFFER_CONFIG *const scaled_ref_frame[2] = {
2556233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vp9_get_scaled_ref_frame(cpi, mbmi->ref_frame[0]),
2557233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vp9_get_scaled_ref_frame(cpi, mbmi->ref_frame[1])
2558233d2500723e5594f3e7c70896ffeeef32b9c950ywan  };
2559233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2560233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (ref = 0; ref < 2; ++ref) {
2561233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ref_mv[ref] = mbmi->ref_mvs[refs[ref]][0];
2562233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2563233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (scaled_ref_frame[ref]) {
2564233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int i;
2565233d2500723e5594f3e7c70896ffeeef32b9c950ywan      // Swap out the reference frame for a version that's been scaled to
2566233d2500723e5594f3e7c70896ffeeef32b9c950ywan      // match the resolution of the current frame, allowing the existing
2567233d2500723e5594f3e7c70896ffeeef32b9c950ywan      // motion search code to be used without additional modifications.
2568233d2500723e5594f3e7c70896ffeeef32b9c950ywan      for (i = 0; i < MAX_MB_PLANE; i++)
2569233d2500723e5594f3e7c70896ffeeef32b9c950ywan        backup_yv12[ref][i] = xd->plane[i].pre[ref];
2570233d2500723e5594f3e7c70896ffeeef32b9c950ywan      vp9_setup_pre_planes(xd, ref, scaled_ref_frame[ref], mi_row, mi_col,
2571233d2500723e5594f3e7c70896ffeeef32b9c950ywan                           NULL);
2572233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
2573233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2574233d2500723e5594f3e7c70896ffeeef32b9c950ywan    frame_mv[refs[ref]].as_int = single_newmv[refs[ref]].as_int;
2575233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
2576233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2577233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Allow joint search multiple times iteratively for each ref frame
2578233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // and break out the search loop if it couldn't find better mv.
2579233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (ite = 0; ite < 4; ite++) {
2580233d2500723e5594f3e7c70896ffeeef32b9c950ywan    struct buf_2d ref_yv12[2];
2581233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int bestsme = INT_MAX;
2582233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int sadpb = x->sadperbit16;
2583233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int_mv tmp_mv;
2584233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int search_range = 3;
2585233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2586233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int tmp_col_min = x->mv_col_min;
2587233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int tmp_col_max = x->mv_col_max;
2588233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int tmp_row_min = x->mv_row_min;
2589233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int tmp_row_max = x->mv_row_max;
2590233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int id = ite % 2;
2591233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2592233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Initialized here because of compiler problem in Visual Studio.
2593233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ref_yv12[0] = xd->plane[0].pre[0];
2594233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ref_yv12[1] = xd->plane[0].pre[1];
2595233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2596233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Get pred block from second frame.
2597233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vp9_build_inter_predictor(ref_yv12[!id].buf,
2598233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              ref_yv12[!id].stride,
2599233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              second_pred, pw,
2600233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              &frame_mv[refs[!id]].as_mv,
2601233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              &xd->block_refs[!id]->sf,
2602233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              pw, ph, 0,
2603233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              kernel, MV_PRECISION_Q3,
2604233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              mi_col * MI_SIZE, mi_row * MI_SIZE);
2605233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2606233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Compound motion search on first ref frame.
2607233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (id)
2608233d2500723e5594f3e7c70896ffeeef32b9c950ywan      xd->plane[0].pre[0] = ref_yv12[id];
2609233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vp9_set_mv_search_range(x, &ref_mv[id].as_mv);
2610233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2611233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Use mv result from single mode as mvp.
2612233d2500723e5594f3e7c70896ffeeef32b9c950ywan    tmp_mv.as_int = frame_mv[refs[id]].as_int;
2613233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2614233d2500723e5594f3e7c70896ffeeef32b9c950ywan    tmp_mv.as_mv.col >>= 3;
2615233d2500723e5594f3e7c70896ffeeef32b9c950ywan    tmp_mv.as_mv.row >>= 3;
2616233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2617233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Small-range full-pixel motion search
2618233d2500723e5594f3e7c70896ffeeef32b9c950ywan    bestsme = vp9_refining_search_8p_c(x, &tmp_mv.as_mv, sadpb,
2619233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                       search_range,
2620233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                       &cpi->fn_ptr[bsize],
2621233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                       x->nmvjointcost, x->mvcost,
2622233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                       &ref_mv[id].as_mv, second_pred,
2623233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                       pw, ph);
2624233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (bestsme < INT_MAX)
2625233d2500723e5594f3e7c70896ffeeef32b9c950ywan      bestsme = vp9_get_mvpred_av_var(x, &tmp_mv.as_mv, &ref_mv[id].as_mv,
2626233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                      second_pred, &cpi->fn_ptr[bsize], 1);
2627233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2628233d2500723e5594f3e7c70896ffeeef32b9c950ywan    x->mv_col_min = tmp_col_min;
2629233d2500723e5594f3e7c70896ffeeef32b9c950ywan    x->mv_col_max = tmp_col_max;
2630233d2500723e5594f3e7c70896ffeeef32b9c950ywan    x->mv_row_min = tmp_row_min;
2631233d2500723e5594f3e7c70896ffeeef32b9c950ywan    x->mv_row_max = tmp_row_max;
2632233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2633233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (bestsme < INT_MAX) {
2634233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int dis; /* TODO: use dis in distortion calculation later. */
2635233d2500723e5594f3e7c70896ffeeef32b9c950ywan      unsigned int sse;
2636233d2500723e5594f3e7c70896ffeeef32b9c950ywan      bestsme = cpi->find_fractional_mv_step_comp(
2637233d2500723e5594f3e7c70896ffeeef32b9c950ywan          x, &tmp_mv.as_mv,
2638233d2500723e5594f3e7c70896ffeeef32b9c950ywan          &ref_mv[id].as_mv,
2639233d2500723e5594f3e7c70896ffeeef32b9c950ywan          cpi->common.allow_high_precision_mv,
2640233d2500723e5594f3e7c70896ffeeef32b9c950ywan          x->errorperbit,
2641233d2500723e5594f3e7c70896ffeeef32b9c950ywan          &cpi->fn_ptr[bsize],
2642233d2500723e5594f3e7c70896ffeeef32b9c950ywan          0, cpi->sf.subpel_iters_per_step,
2643233d2500723e5594f3e7c70896ffeeef32b9c950ywan          x->nmvjointcost, x->mvcost,
2644233d2500723e5594f3e7c70896ffeeef32b9c950ywan          &dis, &sse, second_pred,
2645233d2500723e5594f3e7c70896ffeeef32b9c950ywan          pw, ph);
2646233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
2647233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2648233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (id)
2649233d2500723e5594f3e7c70896ffeeef32b9c950ywan      xd->plane[0].pre[0] = scaled_first_yv12;
2650233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2651233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (bestsme < last_besterr[id]) {
2652233d2500723e5594f3e7c70896ffeeef32b9c950ywan      frame_mv[refs[id]].as_int = tmp_mv.as_int;
2653233d2500723e5594f3e7c70896ffeeef32b9c950ywan      last_besterr[id] = bestsme;
2654233d2500723e5594f3e7c70896ffeeef32b9c950ywan    } else {
2655233d2500723e5594f3e7c70896ffeeef32b9c950ywan      break;
2656233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
2657233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
2658233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2659233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *rate_mv = 0;
2660233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2661233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (ref = 0; ref < 2; ++ref) {
2662233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (scaled_ref_frame[ref]) {
2663233d2500723e5594f3e7c70896ffeeef32b9c950ywan      // restore the predictor
2664233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int i;
2665233d2500723e5594f3e7c70896ffeeef32b9c950ywan      for (i = 0; i < MAX_MB_PLANE; i++)
2666233d2500723e5594f3e7c70896ffeeef32b9c950ywan        xd->plane[i].pre[ref] = backup_yv12[ref][i];
2667233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
2668233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2669233d2500723e5594f3e7c70896ffeeef32b9c950ywan    *rate_mv += vp9_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
2670233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                &mbmi->ref_mvs[refs[ref]][0].as_mv,
2671233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
2672233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
2673233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2674233d2500723e5594f3e7c70896ffeeef32b9c950ywan  vpx_free(second_pred);
2675233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
2676233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2677233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic INLINE void restore_dst_buf(MACROBLOCKD *xd,
2678233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                   uint8_t *orig_dst[MAX_MB_PLANE],
2679233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                   int orig_dst_stride[MAX_MB_PLANE]) {
2680233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int i;
2681233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (i = 0; i < MAX_MB_PLANE; i++) {
2682233d2500723e5594f3e7c70896ffeeef32b9c950ywan    xd->plane[i].dst.buf = orig_dst[i];
2683233d2500723e5594f3e7c70896ffeeef32b9c950ywan    xd->plane[i].dst.stride = orig_dst_stride[i];
2684233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
2685233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
2686233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2687233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
2688233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                 const TileInfo *const tile,
2689233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                 BLOCK_SIZE bsize,
2690233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                 int64_t txfm_cache[],
2691233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                 int *rate2, int64_t *distortion,
2692233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                 int *skippable,
2693233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                 int *rate_y, int64_t *distortion_y,
2694233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                 int *rate_uv, int64_t *distortion_uv,
2695233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                 int *mode_excluded, int *disable_skip,
2696233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                 INTERP_FILTER *best_filter,
2697233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                 int_mv (*mode_mv)[MAX_REF_FRAMES],
2698233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                 int mi_row, int mi_col,
2699233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                 int_mv single_newmv[MAX_REF_FRAMES],
2700233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                 int64_t *psse,
2701233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                 const int64_t ref_best_rd) {
2702233d2500723e5594f3e7c70896ffeeef32b9c950ywan  VP9_COMMON *cm = &cpi->common;
2703233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MACROBLOCKD *xd = &x->e_mbd;
2704233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
2705233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int is_comp_pred = has_second_ref(mbmi);
2706233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int num_refs = is_comp_pred ? 2 : 1;
2707233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int this_mode = mbmi->mode;
2708233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int_mv *frame_mv = mode_mv[this_mode];
2709233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int i;
2710233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int refs[2] = { mbmi->ref_frame[0],
2711233d2500723e5594f3e7c70896ffeeef32b9c950ywan    (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
2712233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int_mv cur_mv[2];
2713233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t this_rd = 0;
2714233d2500723e5594f3e7c70896ffeeef32b9c950ywan  DECLARE_ALIGNED_ARRAY(16, uint8_t, tmp_buf, MAX_MB_PLANE * 64 * 64);
2715233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int pred_exists = 0;
2716233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int intpel_mv;
2717233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t rd, best_rd = INT64_MAX;
2718233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int best_needs_copy = 0;
2719233d2500723e5594f3e7c70896ffeeef32b9c950ywan  uint8_t *orig_dst[MAX_MB_PLANE];
2720233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int orig_dst_stride[MAX_MB_PLANE];
2721233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int rs = 0;
2722233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2723233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (is_comp_pred) {
2724233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (frame_mv[refs[0]].as_int == INVALID_MV ||
2725233d2500723e5594f3e7c70896ffeeef32b9c950ywan        frame_mv[refs[1]].as_int == INVALID_MV)
2726233d2500723e5594f3e7c70896ffeeef32b9c950ywan      return INT64_MAX;
2727233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
2728233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2729233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (this_mode == NEWMV) {
2730233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int rate_mv;
2731233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (is_comp_pred) {
2732233d2500723e5594f3e7c70896ffeeef32b9c950ywan      // Initialize mv using single prediction mode result.
2733233d2500723e5594f3e7c70896ffeeef32b9c950ywan      frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
2734233d2500723e5594f3e7c70896ffeeef32b9c950ywan      frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
2735233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2736233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
2737233d2500723e5594f3e7c70896ffeeef32b9c950ywan        joint_motion_search(cpi, x, bsize, frame_mv,
2738233d2500723e5594f3e7c70896ffeeef32b9c950ywan                            mi_row, mi_col, single_newmv, &rate_mv);
2739233d2500723e5594f3e7c70896ffeeef32b9c950ywan      } else {
2740233d2500723e5594f3e7c70896ffeeef32b9c950ywan        rate_mv  = vp9_mv_bit_cost(&frame_mv[refs[0]].as_mv,
2741233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                   &mbmi->ref_mvs[refs[0]][0].as_mv,
2742233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                   x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
2743233d2500723e5594f3e7c70896ffeeef32b9c950ywan        rate_mv += vp9_mv_bit_cost(&frame_mv[refs[1]].as_mv,
2744233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                   &mbmi->ref_mvs[refs[1]][0].as_mv,
2745233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                   x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
2746233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
2747233d2500723e5594f3e7c70896ffeeef32b9c950ywan      *rate2 += rate_mv;
2748233d2500723e5594f3e7c70896ffeeef32b9c950ywan    } else {
2749233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int_mv tmp_mv;
2750233d2500723e5594f3e7c70896ffeeef32b9c950ywan      single_motion_search(cpi, x, tile, bsize, mi_row, mi_col,
2751233d2500723e5594f3e7c70896ffeeef32b9c950ywan                           &tmp_mv, &rate_mv);
2752233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (tmp_mv.as_int == INVALID_MV)
2753233d2500723e5594f3e7c70896ffeeef32b9c950ywan        return INT64_MAX;
2754233d2500723e5594f3e7c70896ffeeef32b9c950ywan      *rate2 += rate_mv;
2755233d2500723e5594f3e7c70896ffeeef32b9c950ywan      frame_mv[refs[0]].as_int =
2756233d2500723e5594f3e7c70896ffeeef32b9c950ywan          xd->mi[0]->bmi[0].as_mv[0].as_int = tmp_mv.as_int;
2757233d2500723e5594f3e7c70896ffeeef32b9c950ywan      single_newmv[refs[0]].as_int = tmp_mv.as_int;
2758233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
2759233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
2760233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2761233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (i = 0; i < num_refs; ++i) {
2762233d2500723e5594f3e7c70896ffeeef32b9c950ywan    cur_mv[i] = frame_mv[refs[i]];
2763233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Clip "next_nearest" so that it does not extend to far out of image
2764233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (this_mode != NEWMV)
2765233d2500723e5594f3e7c70896ffeeef32b9c950ywan      clamp_mv2(&cur_mv[i].as_mv, xd);
2766233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2767233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (mv_check_bounds(x, &cur_mv[i].as_mv))
2768233d2500723e5594f3e7c70896ffeeef32b9c950ywan      return INT64_MAX;
2769233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mbmi->mv[i].as_int = cur_mv[i].as_int;
2770233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
2771233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2772233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // do first prediction into the destination buffer. Do the next
2773233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // prediction into a temporary buffer. Then keep track of which one
2774233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // of these currently holds the best predictor, and use the other
2775233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // one for future predictions. In the end, copy from tmp_buf to
2776233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // dst if necessary.
2777233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (i = 0; i < MAX_MB_PLANE; i++) {
2778233d2500723e5594f3e7c70896ffeeef32b9c950ywan    orig_dst[i] = xd->plane[i].dst.buf;
2779233d2500723e5594f3e7c70896ffeeef32b9c950ywan    orig_dst_stride[i] = xd->plane[i].dst.stride;
2780233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
2781233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2782233d2500723e5594f3e7c70896ffeeef32b9c950ywan  /* We don't include the cost of the second reference here, because there
2783233d2500723e5594f3e7c70896ffeeef32b9c950ywan   * are only three options: Last/Golden, ARF/Last or Golden/ARF, or in other
2784233d2500723e5594f3e7c70896ffeeef32b9c950ywan   * words if you present them in that order, the second one is always known
2785233d2500723e5594f3e7c70896ffeeef32b9c950ywan   * if the first is known */
2786233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *rate2 += cost_mv_ref(cpi, this_mode, mbmi->mode_context[refs[0]]);
2787233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2788233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (!(*mode_excluded))
2789233d2500723e5594f3e7c70896ffeeef32b9c950ywan    *mode_excluded = is_comp_pred ? cm->reference_mode == SINGLE_REFERENCE
2790233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  : cm->reference_mode == COMPOUND_REFERENCE;
2791233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2792233d2500723e5594f3e7c70896ffeeef32b9c950ywan  pred_exists = 0;
2793233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Are all MVs integer pel for Y and UV
2794233d2500723e5594f3e7c70896ffeeef32b9c950ywan  intpel_mv = !mv_has_subpel(&mbmi->mv[0].as_mv);
2795233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (is_comp_pred)
2796233d2500723e5594f3e7c70896ffeeef32b9c950ywan    intpel_mv &= !mv_has_subpel(&mbmi->mv[1].as_mv);
2797233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2798233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Search for best switchable filter by checking the variance of
2799233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // pred error irrespective of whether the filter will be used
2800233d2500723e5594f3e7c70896ffeeef32b9c950ywan  cpi->mask_filter_rd = 0;
2801233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i)
2802233d2500723e5594f3e7c70896ffeeef32b9c950ywan    cpi->rd_filter_cache[i] = INT64_MAX;
2803233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2804233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (cm->interp_filter != BILINEAR) {
2805233d2500723e5594f3e7c70896ffeeef32b9c950ywan    *best_filter = EIGHTTAP;
2806233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (x->source_variance <
2807233d2500723e5594f3e7c70896ffeeef32b9c950ywan        cpi->sf.disable_filter_search_var_thresh) {
2808233d2500723e5594f3e7c70896ffeeef32b9c950ywan      *best_filter = EIGHTTAP;
2809233d2500723e5594f3e7c70896ffeeef32b9c950ywan    } else {
2810233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int newbest;
2811233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int tmp_rate_sum = 0;
2812233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int64_t tmp_dist_sum = 0;
2813233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2814233d2500723e5594f3e7c70896ffeeef32b9c950ywan      for (i = 0; i < SWITCHABLE_FILTERS; ++i) {
2815233d2500723e5594f3e7c70896ffeeef32b9c950ywan        int j;
2816233d2500723e5594f3e7c70896ffeeef32b9c950ywan        int64_t rs_rd;
2817233d2500723e5594f3e7c70896ffeeef32b9c950ywan        mbmi->interp_filter = i;
2818233d2500723e5594f3e7c70896ffeeef32b9c950ywan        rs = get_switchable_rate(x);
2819233d2500723e5594f3e7c70896ffeeef32b9c950ywan        rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0);
2820233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2821233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (i > 0 && intpel_mv) {
2822233d2500723e5594f3e7c70896ffeeef32b9c950ywan          rd = RDCOST(x->rdmult, x->rddiv, tmp_rate_sum, tmp_dist_sum);
2823233d2500723e5594f3e7c70896ffeeef32b9c950ywan          cpi->rd_filter_cache[i] = rd;
2824233d2500723e5594f3e7c70896ffeeef32b9c950ywan          cpi->rd_filter_cache[SWITCHABLE_FILTERS] =
2825233d2500723e5594f3e7c70896ffeeef32b9c950ywan              MIN(cpi->rd_filter_cache[SWITCHABLE_FILTERS], rd + rs_rd);
2826233d2500723e5594f3e7c70896ffeeef32b9c950ywan          if (cm->interp_filter == SWITCHABLE)
2827233d2500723e5594f3e7c70896ffeeef32b9c950ywan            rd += rs_rd;
2828233d2500723e5594f3e7c70896ffeeef32b9c950ywan          cpi->mask_filter_rd = MAX(cpi->mask_filter_rd, rd);
2829233d2500723e5594f3e7c70896ffeeef32b9c950ywan        } else {
2830233d2500723e5594f3e7c70896ffeeef32b9c950ywan          int rate_sum = 0;
2831233d2500723e5594f3e7c70896ffeeef32b9c950ywan          int64_t dist_sum = 0;
2832233d2500723e5594f3e7c70896ffeeef32b9c950ywan          if ((cm->interp_filter == SWITCHABLE &&
2833233d2500723e5594f3e7c70896ffeeef32b9c950ywan               (!i || best_needs_copy)) ||
2834233d2500723e5594f3e7c70896ffeeef32b9c950ywan              (cm->interp_filter != SWITCHABLE &&
2835233d2500723e5594f3e7c70896ffeeef32b9c950ywan               (cm->interp_filter == mbmi->interp_filter ||
2836233d2500723e5594f3e7c70896ffeeef32b9c950ywan                (i == 0 && intpel_mv)))) {
2837233d2500723e5594f3e7c70896ffeeef32b9c950ywan            restore_dst_buf(xd, orig_dst, orig_dst_stride);
2838233d2500723e5594f3e7c70896ffeeef32b9c950ywan          } else {
2839233d2500723e5594f3e7c70896ffeeef32b9c950ywan            for (j = 0; j < MAX_MB_PLANE; j++) {
2840233d2500723e5594f3e7c70896ffeeef32b9c950ywan              xd->plane[j].dst.buf = tmp_buf + j * 64 * 64;
2841233d2500723e5594f3e7c70896ffeeef32b9c950ywan              xd->plane[j].dst.stride = 64;
2842233d2500723e5594f3e7c70896ffeeef32b9c950ywan            }
2843233d2500723e5594f3e7c70896ffeeef32b9c950ywan          }
2844233d2500723e5594f3e7c70896ffeeef32b9c950ywan          vp9_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
2845233d2500723e5594f3e7c70896ffeeef32b9c950ywan          model_rd_for_sb(cpi, bsize, x, xd, &rate_sum, &dist_sum);
2846233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2847233d2500723e5594f3e7c70896ffeeef32b9c950ywan          rd = RDCOST(x->rdmult, x->rddiv, rate_sum, dist_sum);
2848233d2500723e5594f3e7c70896ffeeef32b9c950ywan          cpi->rd_filter_cache[i] = rd;
2849233d2500723e5594f3e7c70896ffeeef32b9c950ywan          cpi->rd_filter_cache[SWITCHABLE_FILTERS] =
2850233d2500723e5594f3e7c70896ffeeef32b9c950ywan              MIN(cpi->rd_filter_cache[SWITCHABLE_FILTERS], rd + rs_rd);
2851233d2500723e5594f3e7c70896ffeeef32b9c950ywan          if (cm->interp_filter == SWITCHABLE)
2852233d2500723e5594f3e7c70896ffeeef32b9c950ywan            rd += rs_rd;
2853233d2500723e5594f3e7c70896ffeeef32b9c950ywan          cpi->mask_filter_rd = MAX(cpi->mask_filter_rd, rd);
2854233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2855233d2500723e5594f3e7c70896ffeeef32b9c950ywan          if (i == 0 && intpel_mv) {
2856233d2500723e5594f3e7c70896ffeeef32b9c950ywan            tmp_rate_sum = rate_sum;
2857233d2500723e5594f3e7c70896ffeeef32b9c950ywan            tmp_dist_sum = dist_sum;
2858233d2500723e5594f3e7c70896ffeeef32b9c950ywan          }
2859233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
2860233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2861233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (i == 0 && cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
2862233d2500723e5594f3e7c70896ffeeef32b9c950ywan          if (rd / 2 > ref_best_rd) {
2863233d2500723e5594f3e7c70896ffeeef32b9c950ywan            restore_dst_buf(xd, orig_dst, orig_dst_stride);
2864233d2500723e5594f3e7c70896ffeeef32b9c950ywan            return INT64_MAX;
2865233d2500723e5594f3e7c70896ffeeef32b9c950ywan          }
2866233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
2867233d2500723e5594f3e7c70896ffeeef32b9c950ywan        newbest = i == 0 || rd < best_rd;
2868233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2869233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (newbest) {
2870233d2500723e5594f3e7c70896ffeeef32b9c950ywan          best_rd = rd;
2871233d2500723e5594f3e7c70896ffeeef32b9c950ywan          *best_filter = mbmi->interp_filter;
2872233d2500723e5594f3e7c70896ffeeef32b9c950ywan          if (cm->interp_filter == SWITCHABLE && i && !intpel_mv)
2873233d2500723e5594f3e7c70896ffeeef32b9c950ywan            best_needs_copy = !best_needs_copy;
2874233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
2875233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2876233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if ((cm->interp_filter == SWITCHABLE && newbest) ||
2877233d2500723e5594f3e7c70896ffeeef32b9c950ywan            (cm->interp_filter != SWITCHABLE &&
2878233d2500723e5594f3e7c70896ffeeef32b9c950ywan             cm->interp_filter == mbmi->interp_filter)) {
2879233d2500723e5594f3e7c70896ffeeef32b9c950ywan          pred_exists = 1;
2880233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
2881233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
2882233d2500723e5594f3e7c70896ffeeef32b9c950ywan      restore_dst_buf(xd, orig_dst, orig_dst_stride);
2883233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
2884233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
2885233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Set the appropriate filter
2886233d2500723e5594f3e7c70896ffeeef32b9c950ywan  mbmi->interp_filter = cm->interp_filter != SWITCHABLE ?
2887233d2500723e5594f3e7c70896ffeeef32b9c950ywan      cm->interp_filter : *best_filter;
2888233d2500723e5594f3e7c70896ffeeef32b9c950ywan  rs = cm->interp_filter == SWITCHABLE ? get_switchable_rate(x) : 0;
2889233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2890233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (pred_exists) {
2891233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (best_needs_copy) {
2892233d2500723e5594f3e7c70896ffeeef32b9c950ywan      // again temporarily set the buffers to local memory to prevent a memcpy
2893233d2500723e5594f3e7c70896ffeeef32b9c950ywan      for (i = 0; i < MAX_MB_PLANE; i++) {
2894233d2500723e5594f3e7c70896ffeeef32b9c950ywan        xd->plane[i].dst.buf = tmp_buf + i * 64 * 64;
2895233d2500723e5594f3e7c70896ffeeef32b9c950ywan        xd->plane[i].dst.stride = 64;
2896233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
2897233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
2898233d2500723e5594f3e7c70896ffeeef32b9c950ywan  } else {
2899233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Handles the special case when a filter that is not in the
2900233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // switchable list (ex. bilinear, 6-tap) is indicated at the frame level
2901233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vp9_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
2902233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
2903233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2904233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
2905233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int tmp_rate;
2906233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int64_t tmp_dist;
2907233d2500723e5594f3e7c70896ffeeef32b9c950ywan    model_rd_for_sb(cpi, bsize, x, xd, &tmp_rate, &tmp_dist);
2908233d2500723e5594f3e7c70896ffeeef32b9c950ywan    rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist);
2909233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // if current pred_error modeled rd is substantially more than the best
2910233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // so far, do not bother doing full rd
2911233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (rd / 2 > ref_best_rd) {
2912233d2500723e5594f3e7c70896ffeeef32b9c950ywan      restore_dst_buf(xd, orig_dst, orig_dst_stride);
2913233d2500723e5594f3e7c70896ffeeef32b9c950ywan      return INT64_MAX;
2914233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
2915233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
2916233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2917233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (cm->interp_filter == SWITCHABLE)
2918233d2500723e5594f3e7c70896ffeeef32b9c950ywan    *rate2 += get_switchable_rate(x);
2919233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2920233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (!is_comp_pred) {
2921233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (!x->in_active_map) {
2922233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (psse)
2923233d2500723e5594f3e7c70896ffeeef32b9c950ywan        *psse = 0;
2924233d2500723e5594f3e7c70896ffeeef32b9c950ywan      *distortion = 0;
2925233d2500723e5594f3e7c70896ffeeef32b9c950ywan      x->skip = 1;
2926233d2500723e5594f3e7c70896ffeeef32b9c950ywan    } else if (cpi->allow_encode_breakout && x->encode_breakout) {
2927233d2500723e5594f3e7c70896ffeeef32b9c950ywan      const BLOCK_SIZE y_size = get_plane_block_size(bsize, &xd->plane[0]);
2928233d2500723e5594f3e7c70896ffeeef32b9c950ywan      const BLOCK_SIZE uv_size = get_plane_block_size(bsize, &xd->plane[1]);
2929233d2500723e5594f3e7c70896ffeeef32b9c950ywan      unsigned int var, sse;
2930233d2500723e5594f3e7c70896ffeeef32b9c950ywan      // Skipping threshold for ac.
2931233d2500723e5594f3e7c70896ffeeef32b9c950ywan      unsigned int thresh_ac;
2932233d2500723e5594f3e7c70896ffeeef32b9c950ywan      // Set a maximum for threshold to avoid big PSNR loss in low bitrate case.
2933233d2500723e5594f3e7c70896ffeeef32b9c950ywan      // Use extreme low threshold for static frames to limit skipping.
2934233d2500723e5594f3e7c70896ffeeef32b9c950ywan      const unsigned int max_thresh = (cpi->allow_encode_breakout ==
2935233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                      ENCODE_BREAKOUT_LIMITED) ? 128 : 36000;
2936233d2500723e5594f3e7c70896ffeeef32b9c950ywan      // The encode_breakout input
2937233d2500723e5594f3e7c70896ffeeef32b9c950ywan      const unsigned int min_thresh =
2938233d2500723e5594f3e7c70896ffeeef32b9c950ywan          MIN(((unsigned int)x->encode_breakout << 4), max_thresh);
2939233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2940233d2500723e5594f3e7c70896ffeeef32b9c950ywan      // Calculate threshold according to dequant value.
2941233d2500723e5594f3e7c70896ffeeef32b9c950ywan      thresh_ac = (xd->plane[0].dequant[1] * xd->plane[0].dequant[1]) / 9;
2942233d2500723e5594f3e7c70896ffeeef32b9c950ywan      thresh_ac = clamp(thresh_ac, min_thresh, max_thresh);
2943233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2944233d2500723e5594f3e7c70896ffeeef32b9c950ywan      var = cpi->fn_ptr[y_size].vf(x->plane[0].src.buf, x->plane[0].src.stride,
2945233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                   xd->plane[0].dst.buf,
2946233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                   xd->plane[0].dst.stride, &sse);
2947233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2948233d2500723e5594f3e7c70896ffeeef32b9c950ywan      // Adjust threshold according to partition size.
2949233d2500723e5594f3e7c70896ffeeef32b9c950ywan      thresh_ac >>= 8 - (b_width_log2_lookup[bsize] +
2950233d2500723e5594f3e7c70896ffeeef32b9c950ywan          b_height_log2_lookup[bsize]);
2951233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2952233d2500723e5594f3e7c70896ffeeef32b9c950ywan      // Y skipping condition checking
2953233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (sse < thresh_ac || sse == 0) {
2954233d2500723e5594f3e7c70896ffeeef32b9c950ywan        // Skipping threshold for dc
2955233d2500723e5594f3e7c70896ffeeef32b9c950ywan        unsigned int thresh_dc;
2956233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2957233d2500723e5594f3e7c70896ffeeef32b9c950ywan        thresh_dc = (xd->plane[0].dequant[0] * xd->plane[0].dequant[0] >> 6);
2958233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2959233d2500723e5594f3e7c70896ffeeef32b9c950ywan        // dc skipping checking
2960233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if ((sse - var) < thresh_dc || sse == var) {
2961233d2500723e5594f3e7c70896ffeeef32b9c950ywan          unsigned int sse_u, sse_v;
2962233d2500723e5594f3e7c70896ffeeef32b9c950ywan          unsigned int var_u, var_v;
2963233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2964233d2500723e5594f3e7c70896ffeeef32b9c950ywan          var_u = cpi->fn_ptr[uv_size].vf(x->plane[1].src.buf,
2965233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                          x->plane[1].src.stride,
2966233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                          xd->plane[1].dst.buf,
2967233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                          xd->plane[1].dst.stride, &sse_u);
2968233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2969233d2500723e5594f3e7c70896ffeeef32b9c950ywan          // U skipping condition checking
2970233d2500723e5594f3e7c70896ffeeef32b9c950ywan          if ((sse_u * 4 < thresh_ac || sse_u == 0) &&
2971233d2500723e5594f3e7c70896ffeeef32b9c950ywan              (sse_u - var_u < thresh_dc || sse_u == var_u)) {
2972233d2500723e5594f3e7c70896ffeeef32b9c950ywan            var_v = cpi->fn_ptr[uv_size].vf(x->plane[2].src.buf,
2973233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                            x->plane[2].src.stride,
2974233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                            xd->plane[2].dst.buf,
2975233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                            xd->plane[2].dst.stride, &sse_v);
2976233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2977233d2500723e5594f3e7c70896ffeeef32b9c950ywan            // V skipping condition checking
2978233d2500723e5594f3e7c70896ffeeef32b9c950ywan            if ((sse_v * 4 < thresh_ac || sse_v == 0) &&
2979233d2500723e5594f3e7c70896ffeeef32b9c950ywan                (sse_v - var_v < thresh_dc || sse_v == var_v)) {
2980233d2500723e5594f3e7c70896ffeeef32b9c950ywan              x->skip = 1;
2981233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2982233d2500723e5594f3e7c70896ffeeef32b9c950ywan              // The cost of skip bit needs to be added.
2983233d2500723e5594f3e7c70896ffeeef32b9c950ywan              *rate2 += vp9_cost_bit(vp9_get_skip_prob(cm, xd), 1);
2984233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2985233d2500723e5594f3e7c70896ffeeef32b9c950ywan              // Scaling factor for SSE from spatial domain to frequency domain
2986233d2500723e5594f3e7c70896ffeeef32b9c950ywan              // is 16. Adjust distortion accordingly.
2987233d2500723e5594f3e7c70896ffeeef32b9c950ywan              *distortion_uv = (sse_u + sse_v) << 4;
2988233d2500723e5594f3e7c70896ffeeef32b9c950ywan              *distortion = (sse << 4) + *distortion_uv;
2989233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2990233d2500723e5594f3e7c70896ffeeef32b9c950ywan              *disable_skip = 1;
2991233d2500723e5594f3e7c70896ffeeef32b9c950ywan              this_rd = RDCOST(x->rdmult, x->rddiv, *rate2, *distortion);
2992233d2500723e5594f3e7c70896ffeeef32b9c950ywan            }
2993233d2500723e5594f3e7c70896ffeeef32b9c950ywan          }
2994233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
2995233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
2996233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
2997233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
2998233d2500723e5594f3e7c70896ffeeef32b9c950ywan
2999233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (!x->skip) {
3000233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int skippable_y, skippable_uv;
3001233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int64_t sseuv = INT64_MAX;
3002233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int64_t rdcosty = INT64_MAX;
3003233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3004233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Y cost and distortion
3005233d2500723e5594f3e7c70896ffeeef32b9c950ywan    inter_super_block_yrd(cpi, x, rate_y, distortion_y, &skippable_y, psse,
3006233d2500723e5594f3e7c70896ffeeef32b9c950ywan                          bsize, txfm_cache, ref_best_rd);
3007233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3008233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (*rate_y == INT_MAX) {
3009233d2500723e5594f3e7c70896ffeeef32b9c950ywan      *rate2 = INT_MAX;
3010233d2500723e5594f3e7c70896ffeeef32b9c950ywan      *distortion = INT64_MAX;
3011233d2500723e5594f3e7c70896ffeeef32b9c950ywan      restore_dst_buf(xd, orig_dst, orig_dst_stride);
3012233d2500723e5594f3e7c70896ffeeef32b9c950ywan      return INT64_MAX;
3013233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
3014233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3015233d2500723e5594f3e7c70896ffeeef32b9c950ywan    *rate2 += *rate_y;
3016233d2500723e5594f3e7c70896ffeeef32b9c950ywan    *distortion += *distortion_y;
3017233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3018233d2500723e5594f3e7c70896ffeeef32b9c950ywan    rdcosty = RDCOST(x->rdmult, x->rddiv, *rate2, *distortion);
3019233d2500723e5594f3e7c70896ffeeef32b9c950ywan    rdcosty = MIN(rdcosty, RDCOST(x->rdmult, x->rddiv, 0, *psse));
3020233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3021233d2500723e5594f3e7c70896ffeeef32b9c950ywan    super_block_uvrd(cpi, x, rate_uv, distortion_uv, &skippable_uv, &sseuv,
3022233d2500723e5594f3e7c70896ffeeef32b9c950ywan                     bsize, ref_best_rd - rdcosty);
3023233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (*rate_uv == INT_MAX) {
3024233d2500723e5594f3e7c70896ffeeef32b9c950ywan      *rate2 = INT_MAX;
3025233d2500723e5594f3e7c70896ffeeef32b9c950ywan      *distortion = INT64_MAX;
3026233d2500723e5594f3e7c70896ffeeef32b9c950ywan      restore_dst_buf(xd, orig_dst, orig_dst_stride);
3027233d2500723e5594f3e7c70896ffeeef32b9c950ywan      return INT64_MAX;
3028233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
3029233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3030233d2500723e5594f3e7c70896ffeeef32b9c950ywan    *psse += sseuv;
3031233d2500723e5594f3e7c70896ffeeef32b9c950ywan    *rate2 += *rate_uv;
3032233d2500723e5594f3e7c70896ffeeef32b9c950ywan    *distortion += *distortion_uv;
3033233d2500723e5594f3e7c70896ffeeef32b9c950ywan    *skippable = skippable_y && skippable_uv;
3034233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
3035233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3036233d2500723e5594f3e7c70896ffeeef32b9c950ywan  restore_dst_buf(xd, orig_dst, orig_dst_stride);
3037233d2500723e5594f3e7c70896ffeeef32b9c950ywan  return this_rd;  // if 0, this will be re-calculated by caller
3038233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
3039233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3040233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void swap_block_ptr(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
3041233d2500723e5594f3e7c70896ffeeef32b9c950ywan                           int max_plane) {
3042233d2500723e5594f3e7c70896ffeeef32b9c950ywan  struct macroblock_plane *const p = x->plane;
3043233d2500723e5594f3e7c70896ffeeef32b9c950ywan  struct macroblockd_plane *const pd = x->e_mbd.plane;
3044233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int i;
3045233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3046233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (i = 0; i < max_plane; ++i) {
3047233d2500723e5594f3e7c70896ffeeef32b9c950ywan    p[i].coeff    = ctx->coeff_pbuf[i][1];
3048233d2500723e5594f3e7c70896ffeeef32b9c950ywan    p[i].qcoeff  = ctx->qcoeff_pbuf[i][1];
3049233d2500723e5594f3e7c70896ffeeef32b9c950ywan    pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][1];
3050233d2500723e5594f3e7c70896ffeeef32b9c950ywan    p[i].eobs    = ctx->eobs_pbuf[i][1];
3051233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3052233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ctx->coeff_pbuf[i][1]   = ctx->coeff_pbuf[i][0];
3053233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ctx->qcoeff_pbuf[i][1]  = ctx->qcoeff_pbuf[i][0];
3054233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ctx->dqcoeff_pbuf[i][1] = ctx->dqcoeff_pbuf[i][0];
3055233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ctx->eobs_pbuf[i][1]    = ctx->eobs_pbuf[i][0];
3056233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3057233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ctx->coeff_pbuf[i][0]   = p[i].coeff;
3058233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ctx->qcoeff_pbuf[i][0]  = p[i].qcoeff;
3059233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ctx->dqcoeff_pbuf[i][0] = pd[i].dqcoeff;
3060233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ctx->eobs_pbuf[i][0]    = p[i].eobs;
3061233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
3062233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
3063233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3064233d2500723e5594f3e7c70896ffeeef32b9c950ywanvoid vp9_rd_pick_intra_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
3065233d2500723e5594f3e7c70896ffeeef32b9c950ywan                               int *returnrate, int64_t *returndist,
3066233d2500723e5594f3e7c70896ffeeef32b9c950ywan                               BLOCK_SIZE bsize,
3067233d2500723e5594f3e7c70896ffeeef32b9c950ywan                               PICK_MODE_CONTEXT *ctx, int64_t best_rd) {
3068233d2500723e5594f3e7c70896ffeeef32b9c950ywan  VP9_COMMON *const cm = &cpi->common;
3069233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MACROBLOCKD *const xd = &x->e_mbd;
3070233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int rate_y = 0, rate_uv = 0, rate_y_tokenonly = 0, rate_uv_tokenonly = 0;
3071233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int y_skip = 0, uv_skip = 0;
3072233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t dist_y = 0, dist_uv = 0, tx_cache[TX_MODES] = { 0 };
3073233d2500723e5594f3e7c70896ffeeef32b9c950ywan  TX_SIZE max_uv_tx_size;
3074233d2500723e5594f3e7c70896ffeeef32b9c950ywan  x->skip_encode = 0;
3075233d2500723e5594f3e7c70896ffeeef32b9c950ywan  ctx->skip = 0;
3076233d2500723e5594f3e7c70896ffeeef32b9c950ywan  xd->mi[0]->mbmi.ref_frame[0] = INTRA_FRAME;
3077233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3078233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (bsize >= BLOCK_8X8) {
3079233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (rd_pick_intra_sby_mode(cpi, x, &rate_y, &rate_y_tokenonly,
3080233d2500723e5594f3e7c70896ffeeef32b9c950ywan                               &dist_y, &y_skip, bsize, tx_cache,
3081233d2500723e5594f3e7c70896ffeeef32b9c950ywan                               best_rd) >= best_rd) {
3082233d2500723e5594f3e7c70896ffeeef32b9c950ywan      *returnrate = INT_MAX;
3083233d2500723e5594f3e7c70896ffeeef32b9c950ywan      return;
3084233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
3085233d2500723e5594f3e7c70896ffeeef32b9c950ywan    max_uv_tx_size = get_uv_tx_size_impl(xd->mi[0]->mbmi.tx_size, bsize);
3086233d2500723e5594f3e7c70896ffeeef32b9c950ywan    rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv, &rate_uv_tokenonly,
3087233d2500723e5594f3e7c70896ffeeef32b9c950ywan                            &dist_uv, &uv_skip, bsize, max_uv_tx_size);
3088233d2500723e5594f3e7c70896ffeeef32b9c950ywan  } else {
3089233d2500723e5594f3e7c70896ffeeef32b9c950ywan    y_skip = 0;
3090233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate_y, &rate_y_tokenonly,
3091233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                     &dist_y, best_rd) >= best_rd) {
3092233d2500723e5594f3e7c70896ffeeef32b9c950ywan      *returnrate = INT_MAX;
3093233d2500723e5594f3e7c70896ffeeef32b9c950ywan      return;
3094233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
3095233d2500723e5594f3e7c70896ffeeef32b9c950ywan    max_uv_tx_size = get_uv_tx_size_impl(xd->mi[0]->mbmi.tx_size, bsize);
3096233d2500723e5594f3e7c70896ffeeef32b9c950ywan    rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv, &rate_uv_tokenonly,
3097233d2500723e5594f3e7c70896ffeeef32b9c950ywan                            &dist_uv, &uv_skip, BLOCK_8X8, max_uv_tx_size);
3098233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
3099233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3100233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (y_skip && uv_skip) {
3101233d2500723e5594f3e7c70896ffeeef32b9c950ywan    *returnrate = rate_y + rate_uv - rate_y_tokenonly - rate_uv_tokenonly +
3102233d2500723e5594f3e7c70896ffeeef32b9c950ywan                  vp9_cost_bit(vp9_get_skip_prob(cm, xd), 1);
3103233d2500723e5594f3e7c70896ffeeef32b9c950ywan    *returndist = dist_y + dist_uv;
3104233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vp9_zero(ctx->tx_rd_diff);
3105233d2500723e5594f3e7c70896ffeeef32b9c950ywan  } else {
3106233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int i;
3107233d2500723e5594f3e7c70896ffeeef32b9c950ywan    *returnrate = rate_y + rate_uv + vp9_cost_bit(vp9_get_skip_prob(cm, xd), 0);
3108233d2500723e5594f3e7c70896ffeeef32b9c950ywan    *returndist = dist_y + dist_uv;
3109233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (cpi->sf.tx_size_search_method == USE_FULL_RD)
3110233d2500723e5594f3e7c70896ffeeef32b9c950ywan      for (i = 0; i < TX_MODES; i++) {
3111233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (tx_cache[i] < INT64_MAX && tx_cache[cm->tx_mode] < INT64_MAX)
3112233d2500723e5594f3e7c70896ffeeef32b9c950ywan          ctx->tx_rd_diff[i] = tx_cache[i] - tx_cache[cm->tx_mode];
3113233d2500723e5594f3e7c70896ffeeef32b9c950ywan        else
3114233d2500723e5594f3e7c70896ffeeef32b9c950ywan          ctx->tx_rd_diff[i] = 0;
3115233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
3116233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
3117233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3118233d2500723e5594f3e7c70896ffeeef32b9c950ywan  ctx->mic = *xd->mi[0];
3119233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
3120233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3121233d2500723e5594f3e7c70896ffeeef32b9c950ywanint64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
3122233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  const TileInfo *const tile,
3123233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  int mi_row, int mi_col,
3124233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  int *returnrate,
3125233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  int64_t *returndistortion,
3126233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  BLOCK_SIZE bsize,
3127233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  PICK_MODE_CONTEXT *ctx,
3128233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  int64_t best_rd_so_far) {
3129233d2500723e5594f3e7c70896ffeeef32b9c950ywan  VP9_COMMON *const cm = &cpi->common;
3130233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MACROBLOCKD *const xd = &x->e_mbd;
3131233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3132233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const struct segmentation *const seg = &cm->seg;
3133233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MB_PREDICTION_MODE this_mode;
3134233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MV_REFERENCE_FRAME ref_frame, second_ref_frame;
3135233d2500723e5594f3e7c70896ffeeef32b9c950ywan  unsigned char segment_id = mbmi->segment_id;
3136233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int comp_pred, i;
3137233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
3138233d2500723e5594f3e7c70896ffeeef32b9c950ywan  struct buf_2d yv12_mb[4][MAX_MB_PLANE];
3139233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int_mv single_newmv[MAX_REF_FRAMES] = { { 0 } };
3140233d2500723e5594f3e7c70896ffeeef32b9c950ywan  static const int flag_list[4] = { 0, VP9_LAST_FLAG, VP9_GOLD_FLAG,
3141233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                    VP9_ALT_FLAG };
3142233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t best_rd = best_rd_so_far;
3143233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t best_tx_rd[TX_MODES];
3144233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t best_tx_diff[TX_MODES];
3145233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t best_pred_diff[REFERENCE_MODES];
3146233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t best_pred_rd[REFERENCE_MODES];
3147233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t best_filter_rd[SWITCHABLE_FILTER_CONTEXTS];
3148233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS];
3149233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MB_MODE_INFO best_mbmode = { 0 };
3150233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int mode_index, best_mode_index = 0;
3151233d2500723e5594f3e7c70896ffeeef32b9c950ywan  unsigned int ref_costs_single[MAX_REF_FRAMES], ref_costs_comp[MAX_REF_FRAMES];
3152233d2500723e5594f3e7c70896ffeeef32b9c950ywan  vp9_prob comp_mode_p;
3153233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t best_intra_rd = INT64_MAX;
3154233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t best_inter_rd = INT64_MAX;
3155233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MB_PREDICTION_MODE best_intra_mode = DC_PRED;
3156233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MV_REFERENCE_FRAME best_inter_ref_frame = LAST_FRAME;
3157233d2500723e5594f3e7c70896ffeeef32b9c950ywan  INTERP_FILTER tmp_best_filter = SWITCHABLE;
3158233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int rate_uv_intra[TX_SIZES], rate_uv_tokenonly[TX_SIZES];
3159233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t dist_uv[TX_SIZES];
3160233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int skip_uv[TX_SIZES];
3161233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MB_PREDICTION_MODE mode_uv[TX_SIZES];
3162233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t mode_distortions[MB_MODE_COUNT] = {-1};
3163233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int intra_cost_penalty = 20 * vp9_dc_quant(cm->base_qindex, cm->y_dc_delta_q);
3164233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int bws = num_8x8_blocks_wide_lookup[bsize] / 2;
3165233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int bhs = num_8x8_blocks_high_lookup[bsize] / 2;
3166233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int best_skip2 = 0;
3167233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int mode_skip_mask = 0;
3168233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int mode_skip_start = cpi->sf.mode_skip_start + 1;
3169233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int *const rd_threshes = cpi->rd_threshes[segment_id][bsize];
3170233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int *const rd_thresh_freq_fact = cpi->rd_thresh_freq_fact[bsize];
3171233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int mode_search_skip_flags = cpi->sf.mode_search_skip_flags;
3172233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const int intra_y_mode_mask =
3173233d2500723e5594f3e7c70896ffeeef32b9c950ywan      cpi->sf.intra_y_mode_mask[max_txsize_lookup[bsize]];
3174233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int disable_inter_mode_mask = cpi->sf.disable_inter_mode_mask[bsize];
3175233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3176233d2500723e5594f3e7c70896ffeeef32b9c950ywan  x->skip_encode = cpi->sf.skip_encode_frame && x->q_index < QIDX_SKIP_THRESH;
3177233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3178233d2500723e5594f3e7c70896ffeeef32b9c950ywan  estimate_ref_frame_costs(cpi, segment_id, ref_costs_single, ref_costs_comp,
3179233d2500723e5594f3e7c70896ffeeef32b9c950ywan                           &comp_mode_p);
3180233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3181233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (i = 0; i < REFERENCE_MODES; ++i)
3182233d2500723e5594f3e7c70896ffeeef32b9c950ywan    best_pred_rd[i] = INT64_MAX;
3183233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (i = 0; i < TX_MODES; i++)
3184233d2500723e5594f3e7c70896ffeeef32b9c950ywan    best_tx_rd[i] = INT64_MAX;
3185233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
3186233d2500723e5594f3e7c70896ffeeef32b9c950ywan    best_filter_rd[i] = INT64_MAX;
3187233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (i = 0; i < TX_SIZES; i++)
3188233d2500723e5594f3e7c70896ffeeef32b9c950ywan    rate_uv_intra[i] = INT_MAX;
3189233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (i = 0; i < MAX_REF_FRAMES; ++i)
3190233d2500723e5594f3e7c70896ffeeef32b9c950ywan    x->pred_sse[i] = INT_MAX;
3191233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3192233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *returnrate = INT_MAX;
3193233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3194233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
3195233d2500723e5594f3e7c70896ffeeef32b9c950ywan    x->pred_mv_sad[ref_frame] = INT_MAX;
3196233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (cpi->ref_frame_flags & flag_list[ref_frame]) {
3197233d2500723e5594f3e7c70896ffeeef32b9c950ywan      vp9_setup_buffer_inter(cpi, x, tile,
3198233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             ref_frame, bsize, mi_row, mi_col,
3199233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
3200233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
3201233d2500723e5594f3e7c70896ffeeef32b9c950ywan    frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
3202233d2500723e5594f3e7c70896ffeeef32b9c950ywan    frame_mv[ZEROMV][ref_frame].as_int = 0;
3203233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
3204233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3205233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
3206233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // All modes from vp9_mode_order that use this frame as any ref
3207233d2500723e5594f3e7c70896ffeeef32b9c950ywan    static const int ref_frame_mask_all[] = {
3208233d2500723e5594f3e7c70896ffeeef32b9c950ywan        0x0, 0x123291, 0x25c444, 0x39b722
3209233d2500723e5594f3e7c70896ffeeef32b9c950ywan    };
3210233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Fixed mv modes (NEARESTMV, NEARMV, ZEROMV) from vp9_mode_order that use
3211233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // this frame as their primary ref
3212233d2500723e5594f3e7c70896ffeeef32b9c950ywan    static const int ref_frame_mask_fixedmv[] = {
3213233d2500723e5594f3e7c70896ffeeef32b9c950ywan        0x0, 0x121281, 0x24c404, 0x080102
3214233d2500723e5594f3e7c70896ffeeef32b9c950ywan    };
3215233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (!(cpi->ref_frame_flags & flag_list[ref_frame])) {
3216233d2500723e5594f3e7c70896ffeeef32b9c950ywan      // Skip modes for missing references
3217233d2500723e5594f3e7c70896ffeeef32b9c950ywan      mode_skip_mask |= ref_frame_mask_all[ref_frame];
3218233d2500723e5594f3e7c70896ffeeef32b9c950ywan    } else if (cpi->sf.reference_masking) {
3219233d2500723e5594f3e7c70896ffeeef32b9c950ywan      for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
3220233d2500723e5594f3e7c70896ffeeef32b9c950ywan        // Skip fixed mv modes for poor references
3221233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if ((x->pred_mv_sad[ref_frame] >> 2) > x->pred_mv_sad[i]) {
3222233d2500723e5594f3e7c70896ffeeef32b9c950ywan          mode_skip_mask |= ref_frame_mask_fixedmv[ref_frame];
3223233d2500723e5594f3e7c70896ffeeef32b9c950ywan          break;
3224233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
3225233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
3226233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
3227233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // If the segment reference frame feature is enabled....
3228233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // then do nothing if the current ref frame is not allowed..
3229233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (vp9_segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
3230233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vp9_get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
3231233d2500723e5594f3e7c70896ffeeef32b9c950ywan      mode_skip_mask |= ref_frame_mask_all[ref_frame];
3232233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
3233233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
3234233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3235233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // If the segment skip feature is enabled....
3236233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // then do nothing if the current mode is not allowed..
3237233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (vp9_segfeature_active(seg, segment_id, SEG_LVL_SKIP)) {
3238233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const int inter_non_zero_mode_mask = 0x1F7F7;
3239233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mode_skip_mask |= inter_non_zero_mode_mask;
3240233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
3241233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3242233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Disable this drop out case if the ref frame
3243233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // segment level feature is enabled for this segment. This is to
3244233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // prevent the possibility that we end up unable to pick any mode.
3245233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (!vp9_segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
3246233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
3247233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // unless ARNR filtering is enabled in which case we want
3248233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // an unfiltered alternative. We allow near/nearest as well
3249233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // because they may result in zero-zero MVs but be cheaper.
3250233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) {
3251233d2500723e5594f3e7c70896ffeeef32b9c950ywan      const int altref_zero_mask =
3252233d2500723e5594f3e7c70896ffeeef32b9c950ywan          ~((1 << THR_NEARESTA) | (1 << THR_NEARA) | (1 << THR_ZEROA));
3253233d2500723e5594f3e7c70896ffeeef32b9c950ywan      mode_skip_mask |= altref_zero_mask;
3254233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (frame_mv[NEARMV][ALTREF_FRAME].as_int != 0)
3255233d2500723e5594f3e7c70896ffeeef32b9c950ywan        mode_skip_mask |= (1 << THR_NEARA);
3256233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (frame_mv[NEARESTMV][ALTREF_FRAME].as_int != 0)
3257233d2500723e5594f3e7c70896ffeeef32b9c950ywan        mode_skip_mask |= (1 << THR_NEARESTA);
3258233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
3259233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
3260233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3261233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // TODO(JBB): This is to make up for the fact that we don't have sad
3262233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // functions that work when the block size reads outside the umv.  We
3263233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // should fix this either by making the motion search just work on
3264233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // a representative block in the boundary ( first ) and then implement a
3265233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // function that does sads when inside the border..
3266233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if ((mi_row + bhs) > cm->mi_rows || (mi_col + bws) > cm->mi_cols) {
3267233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const int new_modes_mask =
3268233d2500723e5594f3e7c70896ffeeef32b9c950ywan        (1 << THR_NEWMV) | (1 << THR_NEWG) | (1 << THR_NEWA) |
3269233d2500723e5594f3e7c70896ffeeef32b9c950ywan        (1 << THR_COMP_NEWLA) | (1 << THR_COMP_NEWGA);
3270233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mode_skip_mask |= new_modes_mask;
3271233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
3272233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3273233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (bsize > cpi->sf.max_intra_bsize) {
3274233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mode_skip_mask |= 0xFF30808;
3275233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
3276233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3277233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (!x->in_active_map) {
3278233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int mode_index;
3279233d2500723e5594f3e7c70896ffeeef32b9c950ywan    assert(cpi->ref_frame_flags & VP9_LAST_FLAG);
3280233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (frame_mv[NEARESTMV][LAST_FRAME].as_int == 0)
3281233d2500723e5594f3e7c70896ffeeef32b9c950ywan      mode_index = THR_NEARESTMV;
3282233d2500723e5594f3e7c70896ffeeef32b9c950ywan    else if (frame_mv[NEARMV][LAST_FRAME].as_int == 0)
3283233d2500723e5594f3e7c70896ffeeef32b9c950ywan      mode_index = THR_NEARMV;
3284233d2500723e5594f3e7c70896ffeeef32b9c950ywan    else
3285233d2500723e5594f3e7c70896ffeeef32b9c950ywan      mode_index = THR_ZEROMV;
3286233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mode_skip_mask = ~(1 << mode_index);
3287233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mode_skip_start = MAX_MODES;
3288233d2500723e5594f3e7c70896ffeeef32b9c950ywan    disable_inter_mode_mask = 0;
3289233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
3290233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3291233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (mode_index = 0; mode_index < MAX_MODES; ++mode_index) {
3292233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int mode_excluded = 0;
3293233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int64_t this_rd = INT64_MAX;
3294233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int disable_skip = 0;
3295233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int compmode_cost = 0;
3296233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int rate2 = 0, rate_y = 0, rate_uv = 0;
3297233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
3298233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int skippable = 0;
3299233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int64_t tx_cache[TX_MODES];
3300233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int i;
3301233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int this_skip2 = 0;
3302233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int64_t total_sse = INT64_MAX;
3303233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int early_term = 0;
3304233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3305233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Look at the reference frame of the best mode so far and set the
3306233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // skip mask to look at a subset of the remaining modes.
3307233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (mode_index == mode_skip_start) {
3308233d2500723e5594f3e7c70896ffeeef32b9c950ywan      switch (vp9_mode_order[best_mode_index].ref_frame[0]) {
3309233d2500723e5594f3e7c70896ffeeef32b9c950ywan        case INTRA_FRAME:
3310233d2500723e5594f3e7c70896ffeeef32b9c950ywan          break;
3311233d2500723e5594f3e7c70896ffeeef32b9c950ywan        case LAST_FRAME:
3312233d2500723e5594f3e7c70896ffeeef32b9c950ywan          mode_skip_mask |= LAST_FRAME_MODE_MASK;
3313233d2500723e5594f3e7c70896ffeeef32b9c950ywan          break;
3314233d2500723e5594f3e7c70896ffeeef32b9c950ywan        case GOLDEN_FRAME:
3315233d2500723e5594f3e7c70896ffeeef32b9c950ywan          mode_skip_mask |= GOLDEN_FRAME_MODE_MASK;
3316233d2500723e5594f3e7c70896ffeeef32b9c950ywan          break;
3317233d2500723e5594f3e7c70896ffeeef32b9c950ywan        case ALTREF_FRAME:
3318233d2500723e5594f3e7c70896ffeeef32b9c950ywan          mode_skip_mask |= ALT_REF_MODE_MASK;
3319233d2500723e5594f3e7c70896ffeeef32b9c950ywan          break;
3320233d2500723e5594f3e7c70896ffeeef32b9c950ywan        case NONE:
3321233d2500723e5594f3e7c70896ffeeef32b9c950ywan        case MAX_REF_FRAMES:
3322233d2500723e5594f3e7c70896ffeeef32b9c950ywan          assert(0 && "Invalid Reference frame");
3323233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
3324233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
3325233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (mode_skip_mask & (1 << mode_index))
3326233d2500723e5594f3e7c70896ffeeef32b9c950ywan      continue;
3327233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3328233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Test best rd so far against threshold for trying this mode.
3329233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (best_rd < ((int64_t)rd_threshes[mode_index] *
3330233d2500723e5594f3e7c70896ffeeef32b9c950ywan                  rd_thresh_freq_fact[mode_index] >> 5) ||
3331233d2500723e5594f3e7c70896ffeeef32b9c950ywan        rd_threshes[mode_index] == INT_MAX)
3332233d2500723e5594f3e7c70896ffeeef32b9c950ywan     continue;
3333233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3334233d2500723e5594f3e7c70896ffeeef32b9c950ywan    this_mode = vp9_mode_order[mode_index].mode;
3335233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ref_frame = vp9_mode_order[mode_index].ref_frame[0];
3336233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (ref_frame != INTRA_FRAME &&
3337233d2500723e5594f3e7c70896ffeeef32b9c950ywan        disable_inter_mode_mask & (1 << INTER_OFFSET(this_mode)))
3338233d2500723e5594f3e7c70896ffeeef32b9c950ywan      continue;
3339233d2500723e5594f3e7c70896ffeeef32b9c950ywan    second_ref_frame = vp9_mode_order[mode_index].ref_frame[1];
3340233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3341233d2500723e5594f3e7c70896ffeeef32b9c950ywan    comp_pred = second_ref_frame > INTRA_FRAME;
3342233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (comp_pred) {
3343233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if ((mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
3344233d2500723e5594f3e7c70896ffeeef32b9c950ywan          vp9_mode_order[best_mode_index].ref_frame[0] == INTRA_FRAME)
3345233d2500723e5594f3e7c70896ffeeef32b9c950ywan        continue;
3346233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if ((mode_search_skip_flags & FLAG_SKIP_COMP_REFMISMATCH) &&
3347233d2500723e5594f3e7c70896ffeeef32b9c950ywan          ref_frame != best_inter_ref_frame &&
3348233d2500723e5594f3e7c70896ffeeef32b9c950ywan          second_ref_frame != best_inter_ref_frame)
3349233d2500723e5594f3e7c70896ffeeef32b9c950ywan        continue;
3350233d2500723e5594f3e7c70896ffeeef32b9c950ywan      mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
3351233d2500723e5594f3e7c70896ffeeef32b9c950ywan    } else {
3352233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (ref_frame != INTRA_FRAME)
3353233d2500723e5594f3e7c70896ffeeef32b9c950ywan        mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
3354233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
3355233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3356233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (ref_frame == INTRA_FRAME) {
3357233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (!(intra_y_mode_mask & (1 << this_mode)))
3358233d2500723e5594f3e7c70896ffeeef32b9c950ywan        continue;
3359233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (this_mode != DC_PRED) {
3360233d2500723e5594f3e7c70896ffeeef32b9c950ywan        // Disable intra modes other than DC_PRED for blocks with low variance
3361233d2500723e5594f3e7c70896ffeeef32b9c950ywan        // Threshold for intra skipping based on source variance
3362233d2500723e5594f3e7c70896ffeeef32b9c950ywan        // TODO(debargha): Specialize the threshold for super block sizes
3363233d2500723e5594f3e7c70896ffeeef32b9c950ywan        const unsigned int skip_intra_var_thresh = 64;
3364233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if ((mode_search_skip_flags & FLAG_SKIP_INTRA_LOWVAR) &&
3365233d2500723e5594f3e7c70896ffeeef32b9c950ywan            x->source_variance < skip_intra_var_thresh)
3366233d2500723e5594f3e7c70896ffeeef32b9c950ywan          continue;
3367233d2500723e5594f3e7c70896ffeeef32b9c950ywan        // Only search the oblique modes if the best so far is
3368233d2500723e5594f3e7c70896ffeeef32b9c950ywan        // one of the neighboring directional modes
3369233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if ((mode_search_skip_flags & FLAG_SKIP_INTRA_BESTINTER) &&
3370233d2500723e5594f3e7c70896ffeeef32b9c950ywan            (this_mode >= D45_PRED && this_mode <= TM_PRED)) {
3371233d2500723e5594f3e7c70896ffeeef32b9c950ywan          if (vp9_mode_order[best_mode_index].ref_frame[0] > INTRA_FRAME)
3372233d2500723e5594f3e7c70896ffeeef32b9c950ywan            continue;
3373233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
3374233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
3375233d2500723e5594f3e7c70896ffeeef32b9c950ywan          if (conditional_skipintra(this_mode, best_intra_mode))
3376233d2500723e5594f3e7c70896ffeeef32b9c950ywan              continue;
3377233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
3378233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
3379233d2500723e5594f3e7c70896ffeeef32b9c950ywan    } else {
3380233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (x->in_active_map &&
3381233d2500723e5594f3e7c70896ffeeef32b9c950ywan          !vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP))
3382233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (!check_best_zero_mv(cpi, mbmi->mode_context, frame_mv,
3383233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                disable_inter_mode_mask, this_mode, ref_frame,
3384233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                second_ref_frame))
3385233d2500723e5594f3e7c70896ffeeef32b9c950ywan          continue;
3386233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
3387233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3388233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mbmi->mode = this_mode;
3389233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mbmi->uv_mode = x->in_active_map ? DC_PRED : this_mode;
3390233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mbmi->ref_frame[0] = ref_frame;
3391233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mbmi->ref_frame[1] = second_ref_frame;
3392233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Evaluate all sub-pel filters irrespective of whether we can use
3393233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // them for this frame.
3394233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP
3395233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                                          : cm->interp_filter;
3396233d2500723e5594f3e7c70896ffeeef32b9c950ywan    x->skip = 0;
3397233d2500723e5594f3e7c70896ffeeef32b9c950ywan    set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
3398233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3399233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Select prediction reference frames.
3400233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (i = 0; i < MAX_MB_PLANE; i++) {
3401233d2500723e5594f3e7c70896ffeeef32b9c950ywan      xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
3402233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (comp_pred)
3403233d2500723e5594f3e7c70896ffeeef32b9c950ywan        xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
3404233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
3405233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3406233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (i = 0; i < TX_MODES; ++i)
3407233d2500723e5594f3e7c70896ffeeef32b9c950ywan      tx_cache[i] = INT64_MAX;
3408233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3409233d2500723e5594f3e7c70896ffeeef32b9c950ywan#ifdef MODE_TEST_HIT_STATS
3410233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // TEST/DEBUG CODE
3411233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Keep a rcord of the number of test hits at each size
3412233d2500723e5594f3e7c70896ffeeef32b9c950ywan    cpi->mode_test_hits[bsize]++;
3413233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif
3414233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3415233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (ref_frame == INTRA_FRAME) {
3416233d2500723e5594f3e7c70896ffeeef32b9c950ywan      TX_SIZE uv_tx;
3417233d2500723e5594f3e7c70896ffeeef32b9c950ywan      intra_super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable, NULL,
3418233d2500723e5594f3e7c70896ffeeef32b9c950ywan                            bsize, tx_cache, best_rd);
3419233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3420233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (rate_y == INT_MAX)
3421233d2500723e5594f3e7c70896ffeeef32b9c950ywan        continue;
3422233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3423233d2500723e5594f3e7c70896ffeeef32b9c950ywan      uv_tx = get_uv_tx_size_impl(mbmi->tx_size, bsize);
3424233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (rate_uv_intra[uv_tx] == INT_MAX) {
3425233d2500723e5594f3e7c70896ffeeef32b9c950ywan        choose_intra_uv_mode(cpi, ctx, bsize, uv_tx,
3426233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             &rate_uv_intra[uv_tx], &rate_uv_tokenonly[uv_tx],
3427233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             &dist_uv[uv_tx], &skip_uv[uv_tx], &mode_uv[uv_tx]);
3428233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
3429233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3430233d2500723e5594f3e7c70896ffeeef32b9c950ywan      rate_uv = rate_uv_tokenonly[uv_tx];
3431233d2500723e5594f3e7c70896ffeeef32b9c950ywan      distortion_uv = dist_uv[uv_tx];
3432233d2500723e5594f3e7c70896ffeeef32b9c950ywan      skippable = skippable && skip_uv[uv_tx];
3433233d2500723e5594f3e7c70896ffeeef32b9c950ywan      mbmi->uv_mode = mode_uv[uv_tx];
3434233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3435233d2500723e5594f3e7c70896ffeeef32b9c950ywan      rate2 = rate_y + x->mbmode_cost[mbmi->mode] + rate_uv_intra[uv_tx];
3436233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (this_mode != DC_PRED && this_mode != TM_PRED)
3437233d2500723e5594f3e7c70896ffeeef32b9c950ywan        rate2 += intra_cost_penalty;
3438233d2500723e5594f3e7c70896ffeeef32b9c950ywan      distortion2 = distortion_y + distortion_uv;
3439233d2500723e5594f3e7c70896ffeeef32b9c950ywan    } else {
3440233d2500723e5594f3e7c70896ffeeef32b9c950ywan      this_rd = handle_inter_mode(cpi, x, tile, bsize,
3441233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  tx_cache,
3442233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  &rate2, &distortion2, &skippable,
3443233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  &rate_y, &distortion_y,
3444233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  &rate_uv, &distortion_uv,
3445233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  &mode_excluded, &disable_skip,
3446233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  &tmp_best_filter, frame_mv,
3447233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  mi_row, mi_col,
3448233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  single_newmv, &total_sse, best_rd);
3449233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (this_rd == INT64_MAX)
3450233d2500723e5594f3e7c70896ffeeef32b9c950ywan        continue;
3451233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3452233d2500723e5594f3e7c70896ffeeef32b9c950ywan      compmode_cost = vp9_cost_bit(comp_mode_p, comp_pred);
3453233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3454233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (cm->reference_mode == REFERENCE_MODE_SELECT)
3455233d2500723e5594f3e7c70896ffeeef32b9c950ywan        rate2 += compmode_cost;
3456233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
3457233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3458233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Estimate the reference frame signaling cost and add it
3459233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // to the rolling cost variable.
3460233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (comp_pred) {
3461233d2500723e5594f3e7c70896ffeeef32b9c950ywan      rate2 += ref_costs_comp[ref_frame];
3462233d2500723e5594f3e7c70896ffeeef32b9c950ywan    } else {
3463233d2500723e5594f3e7c70896ffeeef32b9c950ywan      rate2 += ref_costs_single[ref_frame];
3464233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
3465233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3466233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (!disable_skip) {
3467233d2500723e5594f3e7c70896ffeeef32b9c950ywan      // Test for the condition where skip block will be activated
3468233d2500723e5594f3e7c70896ffeeef32b9c950ywan      // because there are no non zero coefficients and make any
3469233d2500723e5594f3e7c70896ffeeef32b9c950ywan      // necessary adjustment for rate. Ignore if skip is coded at
3470233d2500723e5594f3e7c70896ffeeef32b9c950ywan      // segment level as the cost wont have been added in.
3471233d2500723e5594f3e7c70896ffeeef32b9c950ywan      // Is Mb level skip allowed (i.e. not coded at segment level).
3472233d2500723e5594f3e7c70896ffeeef32b9c950ywan      const int mb_skip_allowed = !vp9_segfeature_active(seg, segment_id,
3473233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                                         SEG_LVL_SKIP);
3474233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3475233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (skippable) {
3476233d2500723e5594f3e7c70896ffeeef32b9c950ywan        // Back out the coefficient coding costs
3477233d2500723e5594f3e7c70896ffeeef32b9c950ywan        rate2 -= (rate_y + rate_uv);
3478233d2500723e5594f3e7c70896ffeeef32b9c950ywan        // for best yrd calculation
3479233d2500723e5594f3e7c70896ffeeef32b9c950ywan        rate_uv = 0;
3480233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3481233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (mb_skip_allowed) {
3482233d2500723e5594f3e7c70896ffeeef32b9c950ywan          int prob_skip_cost;
3483233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3484233d2500723e5594f3e7c70896ffeeef32b9c950ywan          // Cost the skip mb case
3485233d2500723e5594f3e7c70896ffeeef32b9c950ywan          vp9_prob skip_prob = vp9_get_skip_prob(cm, xd);
3486233d2500723e5594f3e7c70896ffeeef32b9c950ywan          if (skip_prob) {
3487233d2500723e5594f3e7c70896ffeeef32b9c950ywan            prob_skip_cost = vp9_cost_bit(skip_prob, 1);
3488233d2500723e5594f3e7c70896ffeeef32b9c950ywan            rate2 += prob_skip_cost;
3489233d2500723e5594f3e7c70896ffeeef32b9c950ywan          }
3490233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
3491233d2500723e5594f3e7c70896ffeeef32b9c950ywan      } else if (mb_skip_allowed && ref_frame != INTRA_FRAME && !xd->lossless) {
3492233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
3493233d2500723e5594f3e7c70896ffeeef32b9c950ywan            RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
3494233d2500723e5594f3e7c70896ffeeef32b9c950ywan          // Add in the cost of the no skip flag.
3495233d2500723e5594f3e7c70896ffeeef32b9c950ywan          rate2 += vp9_cost_bit(vp9_get_skip_prob(cm, xd), 0);
3496233d2500723e5594f3e7c70896ffeeef32b9c950ywan        } else {
3497233d2500723e5594f3e7c70896ffeeef32b9c950ywan          // FIXME(rbultje) make this work for splitmv also
3498233d2500723e5594f3e7c70896ffeeef32b9c950ywan          rate2 += vp9_cost_bit(vp9_get_skip_prob(cm, xd), 1);
3499233d2500723e5594f3e7c70896ffeeef32b9c950ywan          distortion2 = total_sse;
3500233d2500723e5594f3e7c70896ffeeef32b9c950ywan          assert(total_sse >= 0);
3501233d2500723e5594f3e7c70896ffeeef32b9c950ywan          rate2 -= (rate_y + rate_uv);
3502233d2500723e5594f3e7c70896ffeeef32b9c950ywan          rate_y = 0;
3503233d2500723e5594f3e7c70896ffeeef32b9c950ywan          rate_uv = 0;
3504233d2500723e5594f3e7c70896ffeeef32b9c950ywan          this_skip2 = 1;
3505233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
3506233d2500723e5594f3e7c70896ffeeef32b9c950ywan      } else if (mb_skip_allowed) {
3507233d2500723e5594f3e7c70896ffeeef32b9c950ywan        // Add in the cost of the no skip flag.
3508233d2500723e5594f3e7c70896ffeeef32b9c950ywan        rate2 += vp9_cost_bit(vp9_get_skip_prob(cm, xd), 0);
3509233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
3510233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3511233d2500723e5594f3e7c70896ffeeef32b9c950ywan      // Calculate the final RD estimate for this mode.
3512233d2500723e5594f3e7c70896ffeeef32b9c950ywan      this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
3513233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
3514233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3515233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (ref_frame == INTRA_FRAME) {
3516233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Keep record of best intra rd
3517233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (this_rd < best_intra_rd) {
3518233d2500723e5594f3e7c70896ffeeef32b9c950ywan        best_intra_rd = this_rd;
3519233d2500723e5594f3e7c70896ffeeef32b9c950ywan        best_intra_mode = mbmi->mode;
3520233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
3521233d2500723e5594f3e7c70896ffeeef32b9c950ywan    } else {
3522233d2500723e5594f3e7c70896ffeeef32b9c950ywan      // Keep record of best inter rd with single reference
3523233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (!comp_pred && !mode_excluded && this_rd < best_inter_rd) {
3524233d2500723e5594f3e7c70896ffeeef32b9c950ywan        best_inter_rd = this_rd;
3525233d2500723e5594f3e7c70896ffeeef32b9c950ywan        best_inter_ref_frame = ref_frame;
3526233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
3527233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
3528233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3529233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (!disable_skip && ref_frame == INTRA_FRAME) {
3530233d2500723e5594f3e7c70896ffeeef32b9c950ywan      for (i = 0; i < REFERENCE_MODES; ++i)
3531233d2500723e5594f3e7c70896ffeeef32b9c950ywan        best_pred_rd[i] = MIN(best_pred_rd[i], this_rd);
3532233d2500723e5594f3e7c70896ffeeef32b9c950ywan      for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
3533233d2500723e5594f3e7c70896ffeeef32b9c950ywan        best_filter_rd[i] = MIN(best_filter_rd[i], this_rd);
3534233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
3535233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3536233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Store the respective mode distortions for later use.
3537233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (mode_distortions[this_mode] == -1
3538233d2500723e5594f3e7c70896ffeeef32b9c950ywan        || distortion2 < mode_distortions[this_mode]) {
3539233d2500723e5594f3e7c70896ffeeef32b9c950ywan      mode_distortions[this_mode] = distortion2;
3540233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
3541233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3542233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Did this mode help.. i.e. is it the new best mode
3543233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (this_rd < best_rd || x->skip) {
3544233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int max_plane = MAX_MB_PLANE;
3545233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (!mode_excluded) {
3546233d2500723e5594f3e7c70896ffeeef32b9c950ywan        // Note index of best mode so far
3547233d2500723e5594f3e7c70896ffeeef32b9c950ywan        best_mode_index = mode_index;
3548233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3549233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (ref_frame == INTRA_FRAME) {
3550233d2500723e5594f3e7c70896ffeeef32b9c950ywan          /* required for left and above block mv */
3551233d2500723e5594f3e7c70896ffeeef32b9c950ywan          mbmi->mv[0].as_int = 0;
3552233d2500723e5594f3e7c70896ffeeef32b9c950ywan          max_plane = 1;
3553233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
3554233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3555233d2500723e5594f3e7c70896ffeeef32b9c950ywan        *returnrate = rate2;
3556233d2500723e5594f3e7c70896ffeeef32b9c950ywan        *returndistortion = distortion2;
3557233d2500723e5594f3e7c70896ffeeef32b9c950ywan        best_rd = this_rd;
3558233d2500723e5594f3e7c70896ffeeef32b9c950ywan        best_mbmode = *mbmi;
3559233d2500723e5594f3e7c70896ffeeef32b9c950ywan        best_skip2 = this_skip2;
3560233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (!x->select_txfm_size)
3561233d2500723e5594f3e7c70896ffeeef32b9c950ywan          swap_block_ptr(x, ctx, max_plane);
3562233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vpx_memcpy(ctx->zcoeff_blk, x->zcoeff_blk[mbmi->tx_size],
3563233d2500723e5594f3e7c70896ffeeef32b9c950ywan                   sizeof(uint8_t) * ctx->num_4x4_blk);
3564233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3565233d2500723e5594f3e7c70896ffeeef32b9c950ywan        // TODO(debargha): enhance this test with a better distortion prediction
3566233d2500723e5594f3e7c70896ffeeef32b9c950ywan        // based on qp, activity mask and history
3567233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if ((mode_search_skip_flags & FLAG_EARLY_TERMINATE) &&
3568233d2500723e5594f3e7c70896ffeeef32b9c950ywan            (mode_index > MIN_EARLY_TERM_INDEX)) {
3569233d2500723e5594f3e7c70896ffeeef32b9c950ywan          const int qstep = xd->plane[0].dequant[1];
3570233d2500723e5594f3e7c70896ffeeef32b9c950ywan          // TODO(debargha): Enhance this by specializing for each mode_index
3571233d2500723e5594f3e7c70896ffeeef32b9c950ywan          int scale = 4;
3572233d2500723e5594f3e7c70896ffeeef32b9c950ywan          if (x->source_variance < UINT_MAX) {
3573233d2500723e5594f3e7c70896ffeeef32b9c950ywan            const int var_adjust = (x->source_variance < 16);
3574233d2500723e5594f3e7c70896ffeeef32b9c950ywan            scale -= var_adjust;
3575233d2500723e5594f3e7c70896ffeeef32b9c950ywan          }
3576233d2500723e5594f3e7c70896ffeeef32b9c950ywan          if (ref_frame > INTRA_FRAME &&
3577233d2500723e5594f3e7c70896ffeeef32b9c950ywan              distortion2 * scale < qstep * qstep) {
3578233d2500723e5594f3e7c70896ffeeef32b9c950ywan            early_term = 1;
3579233d2500723e5594f3e7c70896ffeeef32b9c950ywan          }
3580233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
3581233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
3582233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
3583233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3584233d2500723e5594f3e7c70896ffeeef32b9c950ywan    /* keep record of best compound/single-only prediction */
3585233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (!disable_skip && ref_frame != INTRA_FRAME) {
3586233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
3587233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3588233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (cm->reference_mode == REFERENCE_MODE_SELECT) {
3589233d2500723e5594f3e7c70896ffeeef32b9c950ywan        single_rate = rate2 - compmode_cost;
3590233d2500723e5594f3e7c70896ffeeef32b9c950ywan        hybrid_rate = rate2;
3591233d2500723e5594f3e7c70896ffeeef32b9c950ywan      } else {
3592233d2500723e5594f3e7c70896ffeeef32b9c950ywan        single_rate = rate2;
3593233d2500723e5594f3e7c70896ffeeef32b9c950ywan        hybrid_rate = rate2 + compmode_cost;
3594233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
3595233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3596233d2500723e5594f3e7c70896ffeeef32b9c950ywan      single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
3597233d2500723e5594f3e7c70896ffeeef32b9c950ywan      hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
3598233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3599233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (!comp_pred) {
3600233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (single_rd < best_pred_rd[SINGLE_REFERENCE]) {
3601233d2500723e5594f3e7c70896ffeeef32b9c950ywan          best_pred_rd[SINGLE_REFERENCE] = single_rd;
3602233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
3603233d2500723e5594f3e7c70896ffeeef32b9c950ywan      } else {
3604233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (single_rd < best_pred_rd[COMPOUND_REFERENCE]) {
3605233d2500723e5594f3e7c70896ffeeef32b9c950ywan          best_pred_rd[COMPOUND_REFERENCE] = single_rd;
3606233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
3607233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
3608233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
3609233d2500723e5594f3e7c70896ffeeef32b9c950ywan        best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
3610233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3611233d2500723e5594f3e7c70896ffeeef32b9c950ywan      /* keep record of best filter type */
3612233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (!mode_excluded && cm->interp_filter != BILINEAR) {
3613233d2500723e5594f3e7c70896ffeeef32b9c950ywan        int64_t ref = cpi->rd_filter_cache[cm->interp_filter == SWITCHABLE ?
3614233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              SWITCHABLE_FILTERS : cm->interp_filter];
3615233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3616233d2500723e5594f3e7c70896ffeeef32b9c950ywan        for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) {
3617233d2500723e5594f3e7c70896ffeeef32b9c950ywan          int64_t adj_rd;
3618233d2500723e5594f3e7c70896ffeeef32b9c950ywan          if (ref == INT64_MAX)
3619233d2500723e5594f3e7c70896ffeeef32b9c950ywan            adj_rd = 0;
3620233d2500723e5594f3e7c70896ffeeef32b9c950ywan          else if (cpi->rd_filter_cache[i] == INT64_MAX)
3621233d2500723e5594f3e7c70896ffeeef32b9c950ywan            // when early termination is triggered, the encoder does not have
3622233d2500723e5594f3e7c70896ffeeef32b9c950ywan            // access to the rate-distortion cost. it only knows that the cost
3623233d2500723e5594f3e7c70896ffeeef32b9c950ywan            // should be above the maximum valid value. hence it takes the known
3624233d2500723e5594f3e7c70896ffeeef32b9c950ywan            // maximum plus an arbitrary constant as the rate-distortion cost.
3625233d2500723e5594f3e7c70896ffeeef32b9c950ywan            adj_rd = cpi->mask_filter_rd - ref + 10;
3626233d2500723e5594f3e7c70896ffeeef32b9c950ywan          else
3627233d2500723e5594f3e7c70896ffeeef32b9c950ywan            adj_rd = cpi->rd_filter_cache[i] - ref;
3628233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3629233d2500723e5594f3e7c70896ffeeef32b9c950ywan          adj_rd += this_rd;
3630233d2500723e5594f3e7c70896ffeeef32b9c950ywan          best_filter_rd[i] = MIN(best_filter_rd[i], adj_rd);
3631233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
3632233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
3633233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
3634233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3635233d2500723e5594f3e7c70896ffeeef32b9c950ywan    /* keep record of best txfm size */
3636233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (bsize < BLOCK_32X32) {
3637233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (bsize < BLOCK_16X16)
3638233d2500723e5594f3e7c70896ffeeef32b9c950ywan        tx_cache[ALLOW_16X16] = tx_cache[ALLOW_8X8];
3639233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3640233d2500723e5594f3e7c70896ffeeef32b9c950ywan      tx_cache[ALLOW_32X32] = tx_cache[ALLOW_16X16];
3641233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
3642233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (!mode_excluded && this_rd != INT64_MAX) {
3643233d2500723e5594f3e7c70896ffeeef32b9c950ywan      for (i = 0; i < TX_MODES && tx_cache[i] < INT64_MAX; i++) {
3644233d2500723e5594f3e7c70896ffeeef32b9c950ywan        int64_t adj_rd = INT64_MAX;
3645233d2500723e5594f3e7c70896ffeeef32b9c950ywan        adj_rd = this_rd + tx_cache[i] - tx_cache[cm->tx_mode];
3646233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3647233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (adj_rd < best_tx_rd[i])
3648233d2500723e5594f3e7c70896ffeeef32b9c950ywan          best_tx_rd[i] = adj_rd;
3649233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
3650233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
3651233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3652233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (early_term)
3653233d2500723e5594f3e7c70896ffeeef32b9c950ywan      break;
3654233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3655233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (x->skip && !comp_pred)
3656233d2500723e5594f3e7c70896ffeeef32b9c950ywan      break;
3657233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
3658233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3659233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (best_rd >= best_rd_so_far)
3660233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return INT64_MAX;
3661233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3662233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // If we used an estimate for the uv intra rd in the loop above...
3663233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (cpi->sf.use_uv_intra_rd_estimate) {
3664233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Do Intra UV best rd mode selection if best mode choice above was intra.
3665233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (vp9_mode_order[best_mode_index].ref_frame[0] == INTRA_FRAME) {
3666233d2500723e5594f3e7c70896ffeeef32b9c950ywan      TX_SIZE uv_tx_size;
3667233d2500723e5594f3e7c70896ffeeef32b9c950ywan      *mbmi = best_mbmode;
3668233d2500723e5594f3e7c70896ffeeef32b9c950ywan      uv_tx_size = get_uv_tx_size(mbmi);
3669233d2500723e5594f3e7c70896ffeeef32b9c950ywan      rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv_intra[uv_tx_size],
3670233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              &rate_uv_tokenonly[uv_tx_size],
3671233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              &dist_uv[uv_tx_size],
3672233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              &skip_uv[uv_tx_size],
3673233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize,
3674233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              uv_tx_size);
3675233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
3676233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
3677233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3678233d2500723e5594f3e7c70896ffeeef32b9c950ywan  assert((cm->interp_filter == SWITCHABLE) ||
3679233d2500723e5594f3e7c70896ffeeef32b9c950ywan         (cm->interp_filter == best_mbmode.interp_filter) ||
3680233d2500723e5594f3e7c70896ffeeef32b9c950ywan         !is_inter_block(&best_mbmode));
3681233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3682233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Updating rd_thresh_freq_fact[] here means that the different
3683233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // partition/block sizes are handled independently based on the best
3684233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // choice for the current partition. It may well be better to keep a scaled
3685233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // best rd so far value and update rd_thresh_freq_fact based on the mode/size
3686233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // combination that wins out.
3687233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (cpi->sf.adaptive_rd_thresh) {
3688233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (mode_index = 0; mode_index < MAX_MODES; ++mode_index) {
3689233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int *const fact = &cpi->rd_thresh_freq_fact[bsize][mode_index];
3690233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3691233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (mode_index == best_mode_index) {
3692233d2500723e5594f3e7c70896ffeeef32b9c950ywan        *fact -= (*fact >> 3);
3693233d2500723e5594f3e7c70896ffeeef32b9c950ywan      } else {
3694233d2500723e5594f3e7c70896ffeeef32b9c950ywan        *fact = MIN(*fact + RD_THRESH_INC,
3695233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    cpi->sf.adaptive_rd_thresh * RD_THRESH_MAX_FACT);
3696233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
3697233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
3698233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
3699233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3700233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // macroblock modes
3701233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *mbmi = best_mbmode;
3702233d2500723e5594f3e7c70896ffeeef32b9c950ywan  x->skip |= best_skip2;
3703233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3704233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (i = 0; i < REFERENCE_MODES; ++i) {
3705233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (best_pred_rd[i] == INT64_MAX)
3706233d2500723e5594f3e7c70896ffeeef32b9c950ywan      best_pred_diff[i] = INT_MIN;
3707233d2500723e5594f3e7c70896ffeeef32b9c950ywan    else
3708233d2500723e5594f3e7c70896ffeeef32b9c950ywan      best_pred_diff[i] = best_rd - best_pred_rd[i];
3709233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
3710233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3711233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (!x->skip) {
3712233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) {
3713233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (best_filter_rd[i] == INT64_MAX)
3714233d2500723e5594f3e7c70896ffeeef32b9c950ywan        best_filter_diff[i] = 0;
3715233d2500723e5594f3e7c70896ffeeef32b9c950ywan      else
3716233d2500723e5594f3e7c70896ffeeef32b9c950ywan        best_filter_diff[i] = best_rd - best_filter_rd[i];
3717233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
3718233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (cm->interp_filter == SWITCHABLE)
3719233d2500723e5594f3e7c70896ffeeef32b9c950ywan      assert(best_filter_diff[SWITCHABLE_FILTERS] == 0);
3720233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (i = 0; i < TX_MODES; i++) {
3721233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (best_tx_rd[i] == INT64_MAX)
3722233d2500723e5594f3e7c70896ffeeef32b9c950ywan        best_tx_diff[i] = 0;
3723233d2500723e5594f3e7c70896ffeeef32b9c950ywan      else
3724233d2500723e5594f3e7c70896ffeeef32b9c950ywan        best_tx_diff[i] = best_rd - best_tx_rd[i];
3725233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
3726233d2500723e5594f3e7c70896ffeeef32b9c950ywan  } else {
3727233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vp9_zero(best_filter_diff);
3728233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vp9_zero(best_tx_diff);
3729233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
3730233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3731233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (!x->in_active_map) {
3732233d2500723e5594f3e7c70896ffeeef32b9c950ywan    assert(mbmi->ref_frame[0] == LAST_FRAME);
3733233d2500723e5594f3e7c70896ffeeef32b9c950ywan    assert(mbmi->ref_frame[1] == NONE);
3734233d2500723e5594f3e7c70896ffeeef32b9c950ywan    assert(mbmi->mode == NEARESTMV ||
3735233d2500723e5594f3e7c70896ffeeef32b9c950ywan           mbmi->mode == NEARMV ||
3736233d2500723e5594f3e7c70896ffeeef32b9c950ywan           mbmi->mode == ZEROMV);
3737233d2500723e5594f3e7c70896ffeeef32b9c950ywan    assert(frame_mv[mbmi->mode][LAST_FRAME].as_int == 0);
3738233d2500723e5594f3e7c70896ffeeef32b9c950ywan    assert(mbmi->mode == mbmi->uv_mode);
3739233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
3740233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3741233d2500723e5594f3e7c70896ffeeef32b9c950ywan  set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
3742233d2500723e5594f3e7c70896ffeeef32b9c950ywan  store_coding_context(x, ctx, best_mode_index,
3743233d2500723e5594f3e7c70896ffeeef32b9c950ywan                       &mbmi->ref_mvs[mbmi->ref_frame[0]][0],
3744233d2500723e5594f3e7c70896ffeeef32b9c950ywan                       &mbmi->ref_mvs[mbmi->ref_frame[1] < 0 ? 0 :
3745233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                      mbmi->ref_frame[1]][0],
3746233d2500723e5594f3e7c70896ffeeef32b9c950ywan                       best_pred_diff, best_tx_diff, best_filter_diff);
3747233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3748233d2500723e5594f3e7c70896ffeeef32b9c950ywan  return best_rd;
3749233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
3750233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3751233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3752233d2500723e5594f3e7c70896ffeeef32b9c950ywanint64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x,
3753233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                      const TileInfo *const tile,
3754233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                      int mi_row, int mi_col,
3755233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                      int *returnrate,
3756233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                      int64_t *returndistortion,
3757233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                      BLOCK_SIZE bsize,
3758233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                      PICK_MODE_CONTEXT *ctx,
3759233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                      int64_t best_rd_so_far) {
3760233d2500723e5594f3e7c70896ffeeef32b9c950ywan  VP9_COMMON *cm = &cpi->common;
3761233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MACROBLOCKD *xd = &x->e_mbd;
3762233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
3763233d2500723e5594f3e7c70896ffeeef32b9c950ywan  const struct segmentation *seg = &cm->seg;
3764233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MV_REFERENCE_FRAME ref_frame, second_ref_frame;
3765233d2500723e5594f3e7c70896ffeeef32b9c950ywan  unsigned char segment_id = mbmi->segment_id;
3766233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int comp_pred, i;
3767233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
3768233d2500723e5594f3e7c70896ffeeef32b9c950ywan  struct buf_2d yv12_mb[4][MAX_MB_PLANE];
3769233d2500723e5594f3e7c70896ffeeef32b9c950ywan  static const int flag_list[4] = { 0, VP9_LAST_FLAG, VP9_GOLD_FLAG,
3770233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                    VP9_ALT_FLAG };
3771233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t best_rd = best_rd_so_far;
3772233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t best_yrd = best_rd_so_far;  // FIXME(rbultje) more precise
3773233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t best_tx_rd[TX_MODES];
3774233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t best_tx_diff[TX_MODES];
3775233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t best_pred_diff[REFERENCE_MODES];
3776233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t best_pred_rd[REFERENCE_MODES];
3777233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t best_filter_rd[SWITCHABLE_FILTER_CONTEXTS];
3778233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS];
3779233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MB_MODE_INFO best_mbmode = { 0 };
3780233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int mode_index, best_mode_index = 0;
3781233d2500723e5594f3e7c70896ffeeef32b9c950ywan  unsigned int ref_costs_single[MAX_REF_FRAMES], ref_costs_comp[MAX_REF_FRAMES];
3782233d2500723e5594f3e7c70896ffeeef32b9c950ywan  vp9_prob comp_mode_p;
3783233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t best_inter_rd = INT64_MAX;
3784233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MV_REFERENCE_FRAME best_inter_ref_frame = LAST_FRAME;
3785233d2500723e5594f3e7c70896ffeeef32b9c950ywan  INTERP_FILTER tmp_best_filter = SWITCHABLE;
3786233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int rate_uv_intra[TX_SIZES], rate_uv_tokenonly[TX_SIZES];
3787233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int64_t dist_uv[TX_SIZES];
3788233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int skip_uv[TX_SIZES];
3789233d2500723e5594f3e7c70896ffeeef32b9c950ywan  MB_PREDICTION_MODE mode_uv[TX_SIZES] = { 0 };
3790233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int intra_cost_penalty = 20 * vp9_dc_quant(cm->base_qindex, cm->y_dc_delta_q);
3791233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int_mv seg_mvs[4][MAX_REF_FRAMES];
3792233d2500723e5594f3e7c70896ffeeef32b9c950ywan  b_mode_info best_bmodes[4];
3793233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int best_skip2 = 0;
3794233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int ref_frame_mask = 0;
3795233d2500723e5594f3e7c70896ffeeef32b9c950ywan  int mode_skip_mask = 0;
3796233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3797233d2500723e5594f3e7c70896ffeeef32b9c950ywan  x->skip_encode = cpi->sf.skip_encode_frame && x->q_index < QIDX_SKIP_THRESH;
3798233d2500723e5594f3e7c70896ffeeef32b9c950ywan  vpx_memset(x->zcoeff_blk[TX_4X4], 0, 4);
3799233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3800233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (i = 0; i < 4; i++) {
3801233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int j;
3802233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (j = 0; j < MAX_REF_FRAMES; j++)
3803233d2500723e5594f3e7c70896ffeeef32b9c950ywan      seg_mvs[i][j].as_int = INVALID_MV;
3804233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
3805233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3806233d2500723e5594f3e7c70896ffeeef32b9c950ywan  estimate_ref_frame_costs(cpi, segment_id, ref_costs_single, ref_costs_comp,
3807233d2500723e5594f3e7c70896ffeeef32b9c950ywan                           &comp_mode_p);
3808233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3809233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (i = 0; i < REFERENCE_MODES; ++i)
3810233d2500723e5594f3e7c70896ffeeef32b9c950ywan    best_pred_rd[i] = INT64_MAX;
3811233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (i = 0; i < TX_MODES; i++)
3812233d2500723e5594f3e7c70896ffeeef32b9c950ywan    best_tx_rd[i] = INT64_MAX;
3813233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
3814233d2500723e5594f3e7c70896ffeeef32b9c950ywan    best_filter_rd[i] = INT64_MAX;
3815233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (i = 0; i < TX_SIZES; i++)
3816233d2500723e5594f3e7c70896ffeeef32b9c950ywan    rate_uv_intra[i] = INT_MAX;
3817233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3818233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *returnrate = INT_MAX;
3819233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3820233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
3821233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (cpi->ref_frame_flags & flag_list[ref_frame]) {
3822233d2500723e5594f3e7c70896ffeeef32b9c950ywan      vp9_setup_buffer_inter(cpi, x, tile,
3823233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             ref_frame, bsize, mi_row, mi_col,
3824233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             frame_mv[NEARESTMV], frame_mv[NEARMV],
3825233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             yv12_mb);
3826233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
3827233d2500723e5594f3e7c70896ffeeef32b9c950ywan    frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
3828233d2500723e5594f3e7c70896ffeeef32b9c950ywan    frame_mv[ZEROMV][ref_frame].as_int = 0;
3829233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
3830233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3831233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (ref_frame = LAST_FRAME;
3832233d2500723e5594f3e7c70896ffeeef32b9c950ywan       ref_frame <= ALTREF_FRAME && cpi->sf.reference_masking; ++ref_frame) {
3833233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int i;
3834233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
3835233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if ((x->pred_mv_sad[ref_frame] >> 1) > x->pred_mv_sad[i]) {
3836233d2500723e5594f3e7c70896ffeeef32b9c950ywan        ref_frame_mask |= (1 << ref_frame);
3837233d2500723e5594f3e7c70896ffeeef32b9c950ywan        break;
3838233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
3839233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
3840233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
3841233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3842233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (mode_index = 0; mode_index < MAX_REFS; ++mode_index) {
3843233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int mode_excluded = 0;
3844233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int64_t this_rd = INT64_MAX;
3845233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int disable_skip = 0;
3846233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int compmode_cost = 0;
3847233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int rate2 = 0, rate_y = 0, rate_uv = 0;
3848233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
3849233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int skippable = 0;
3850233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int64_t tx_cache[TX_MODES];
3851233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int i;
3852233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int this_skip2 = 0;
3853233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int64_t total_sse = INT_MAX;
3854233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int early_term = 0;
3855233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3856233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (i = 0; i < TX_MODES; ++i)
3857233d2500723e5594f3e7c70896ffeeef32b9c950ywan      tx_cache[i] = INT64_MAX;
3858233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3859233d2500723e5594f3e7c70896ffeeef32b9c950ywan    x->skip = 0;
3860233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ref_frame = vp9_ref_order[mode_index].ref_frame[0];
3861233d2500723e5594f3e7c70896ffeeef32b9c950ywan    second_ref_frame = vp9_ref_order[mode_index].ref_frame[1];
3862233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3863233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Look at the reference frame of the best mode so far and set the
3864233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // skip mask to look at a subset of the remaining modes.
3865233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (mode_index > 2 && cpi->sf.mode_skip_start < MAX_MODES) {
3866233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (mode_index == 3) {
3867233d2500723e5594f3e7c70896ffeeef32b9c950ywan        switch (vp9_ref_order[best_mode_index].ref_frame[0]) {
3868233d2500723e5594f3e7c70896ffeeef32b9c950ywan          case INTRA_FRAME:
3869233d2500723e5594f3e7c70896ffeeef32b9c950ywan            mode_skip_mask = 0;
3870233d2500723e5594f3e7c70896ffeeef32b9c950ywan            break;
3871233d2500723e5594f3e7c70896ffeeef32b9c950ywan          case LAST_FRAME:
3872233d2500723e5594f3e7c70896ffeeef32b9c950ywan            mode_skip_mask = 0x0010;
3873233d2500723e5594f3e7c70896ffeeef32b9c950ywan            break;
3874233d2500723e5594f3e7c70896ffeeef32b9c950ywan          case GOLDEN_FRAME:
3875233d2500723e5594f3e7c70896ffeeef32b9c950ywan            mode_skip_mask = 0x0008;
3876233d2500723e5594f3e7c70896ffeeef32b9c950ywan            break;
3877233d2500723e5594f3e7c70896ffeeef32b9c950ywan          case ALTREF_FRAME:
3878233d2500723e5594f3e7c70896ffeeef32b9c950ywan            mode_skip_mask = 0x0000;
3879233d2500723e5594f3e7c70896ffeeef32b9c950ywan            break;
3880233d2500723e5594f3e7c70896ffeeef32b9c950ywan          case NONE:
3881233d2500723e5594f3e7c70896ffeeef32b9c950ywan          case MAX_REF_FRAMES:
3882233d2500723e5594f3e7c70896ffeeef32b9c950ywan            assert(0 && "Invalid Reference frame");
3883233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
3884233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
3885233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (mode_skip_mask & (1 << mode_index))
3886233d2500723e5594f3e7c70896ffeeef32b9c950ywan        continue;
3887233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
3888233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3889233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Test best rd so far against threshold for trying this mode.
3890233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if ((best_rd <
3891233d2500723e5594f3e7c70896ffeeef32b9c950ywan         ((int64_t)cpi->rd_thresh_sub8x8[segment_id][bsize][mode_index] *
3892233d2500723e5594f3e7c70896ffeeef32b9c950ywan          cpi->rd_thresh_freq_sub8x8[bsize][mode_index] >> 5)) ||
3893233d2500723e5594f3e7c70896ffeeef32b9c950ywan        cpi->rd_thresh_sub8x8[segment_id][bsize][mode_index] == INT_MAX)
3894233d2500723e5594f3e7c70896ffeeef32b9c950ywan      continue;
3895233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3896233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Do not allow compound prediction if the segment level reference
3897233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // frame feature is in use as in this case there can only be one reference.
3898233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if ((second_ref_frame > INTRA_FRAME) &&
3899233d2500723e5594f3e7c70896ffeeef32b9c950ywan         vp9_segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME))
3900233d2500723e5594f3e7c70896ffeeef32b9c950ywan      continue;
3901233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3902233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mbmi->ref_frame[0] = ref_frame;
3903233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mbmi->ref_frame[1] = second_ref_frame;
3904233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3905233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (!(ref_frame == INTRA_FRAME
3906233d2500723e5594f3e7c70896ffeeef32b9c950ywan        || (cpi->ref_frame_flags & flag_list[ref_frame]))) {
3907233d2500723e5594f3e7c70896ffeeef32b9c950ywan      continue;
3908233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
3909233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (!(second_ref_frame == NONE
3910233d2500723e5594f3e7c70896ffeeef32b9c950ywan        || (cpi->ref_frame_flags & flag_list[second_ref_frame]))) {
3911233d2500723e5594f3e7c70896ffeeef32b9c950ywan      continue;
3912233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
3913233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3914233d2500723e5594f3e7c70896ffeeef32b9c950ywan    comp_pred = second_ref_frame > INTRA_FRAME;
3915233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (comp_pred) {
3916233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA)
3917233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (vp9_ref_order[best_mode_index].ref_frame[0] == INTRA_FRAME)
3918233d2500723e5594f3e7c70896ffeeef32b9c950ywan          continue;
3919233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_COMP_REFMISMATCH)
3920233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (ref_frame != best_inter_ref_frame &&
3921233d2500723e5594f3e7c70896ffeeef32b9c950ywan            second_ref_frame != best_inter_ref_frame)
3922233d2500723e5594f3e7c70896ffeeef32b9c950ywan          continue;
3923233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
3924233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3925233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // TODO(jingning, jkoleszar): scaling reference frame not supported for
3926233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // sub8x8 blocks.
3927233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (ref_frame > 0 && vp9_is_scaled(&cm->frame_refs[ref_frame - 1].sf))
3928233d2500723e5594f3e7c70896ffeeef32b9c950ywan      continue;
3929233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3930233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (second_ref_frame > 0 &&
3931233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vp9_is_scaled(&cm->frame_refs[second_ref_frame - 1].sf))
3932233d2500723e5594f3e7c70896ffeeef32b9c950ywan      continue;
3933233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3934233d2500723e5594f3e7c70896ffeeef32b9c950ywan    set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
3935233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mbmi->uv_mode = DC_PRED;
3936233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3937233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Evaluate all sub-pel filters irrespective of whether we can use
3938233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // them for this frame.
3939233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP
3940233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                                          : cm->interp_filter;
3941233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3942233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (comp_pred) {
3943233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (!(cpi->ref_frame_flags & flag_list[second_ref_frame]))
3944233d2500723e5594f3e7c70896ffeeef32b9c950ywan        continue;
3945233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3946233d2500723e5594f3e7c70896ffeeef32b9c950ywan      mode_excluded = mode_excluded ? mode_excluded
3947233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                    : cm->reference_mode == SINGLE_REFERENCE;
3948233d2500723e5594f3e7c70896ffeeef32b9c950ywan    } else {
3949233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (ref_frame != INTRA_FRAME && second_ref_frame != INTRA_FRAME) {
3950233d2500723e5594f3e7c70896ffeeef32b9c950ywan        mode_excluded = mode_excluded ?
3951233d2500723e5594f3e7c70896ffeeef32b9c950ywan            mode_excluded : cm->reference_mode == COMPOUND_REFERENCE;
3952233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
3953233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
3954233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3955233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Select prediction reference frames.
3956233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (i = 0; i < MAX_MB_PLANE; i++) {
3957233d2500723e5594f3e7c70896ffeeef32b9c950ywan      xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
3958233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (comp_pred)
3959233d2500723e5594f3e7c70896ffeeef32b9c950ywan        xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
3960233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
3961233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3962233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // If the segment reference frame feature is enabled....
3963233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // then do nothing if the current ref frame is not allowed..
3964233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (vp9_segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
3965233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vp9_get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) !=
3966233d2500723e5594f3e7c70896ffeeef32b9c950ywan            (int)ref_frame) {
3967233d2500723e5594f3e7c70896ffeeef32b9c950ywan      continue;
3968233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // If the segment skip feature is enabled....
3969233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // then do nothing if the current mode is not allowed..
3970233d2500723e5594f3e7c70896ffeeef32b9c950ywan    } else if (vp9_segfeature_active(seg, segment_id, SEG_LVL_SKIP) &&
3971233d2500723e5594f3e7c70896ffeeef32b9c950ywan               ref_frame != INTRA_FRAME) {
3972233d2500723e5594f3e7c70896ffeeef32b9c950ywan      continue;
3973233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Disable this drop out case if the ref frame
3974233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // segment level feature is enabled for this segment. This is to
3975233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // prevent the possibility that we end up unable to pick any mode.
3976233d2500723e5594f3e7c70896ffeeef32b9c950ywan    } else if (!vp9_segfeature_active(seg, segment_id,
3977233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                      SEG_LVL_REF_FRAME)) {
3978233d2500723e5594f3e7c70896ffeeef32b9c950ywan      // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
3979233d2500723e5594f3e7c70896ffeeef32b9c950ywan      // unless ARNR filtering is enabled in which case we want
3980233d2500723e5594f3e7c70896ffeeef32b9c950ywan      // an unfiltered alternative. We allow near/nearest as well
3981233d2500723e5594f3e7c70896ffeeef32b9c950ywan      // because they may result in zero-zero MVs but be cheaper.
3982233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0))
3983233d2500723e5594f3e7c70896ffeeef32b9c950ywan        continue;
3984233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
3985233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3986233d2500723e5594f3e7c70896ffeeef32b9c950ywan#ifdef MODE_TEST_HIT_STATS
3987233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // TEST/DEBUG CODE
3988233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Keep a rcord of the number of test hits at each size
3989233d2500723e5594f3e7c70896ffeeef32b9c950ywan    cpi->mode_test_hits[bsize]++;
3990233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif
3991233d2500723e5594f3e7c70896ffeeef32b9c950ywan
3992233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (ref_frame == INTRA_FRAME) {
3993233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int rate;
3994233d2500723e5594f3e7c70896ffeeef32b9c950ywan      mbmi->tx_size = TX_4X4;
3995233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate, &rate_y,
3996233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                       &distortion_y, best_rd) >= best_rd)
3997233d2500723e5594f3e7c70896ffeeef32b9c950ywan        continue;
3998233d2500723e5594f3e7c70896ffeeef32b9c950ywan      rate2 += rate;
3999233d2500723e5594f3e7c70896ffeeef32b9c950ywan      rate2 += intra_cost_penalty;
4000233d2500723e5594f3e7c70896ffeeef32b9c950ywan      distortion2 += distortion_y;
4001233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4002233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (rate_uv_intra[TX_4X4] == INT_MAX) {
4003233d2500723e5594f3e7c70896ffeeef32b9c950ywan        choose_intra_uv_mode(cpi, ctx, bsize, TX_4X4,
4004233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             &rate_uv_intra[TX_4X4],
4005233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             &rate_uv_tokenonly[TX_4X4],
4006233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             &dist_uv[TX_4X4], &skip_uv[TX_4X4],
4007233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             &mode_uv[TX_4X4]);
4008233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
4009233d2500723e5594f3e7c70896ffeeef32b9c950ywan      rate2 += rate_uv_intra[TX_4X4];
4010233d2500723e5594f3e7c70896ffeeef32b9c950ywan      rate_uv = rate_uv_tokenonly[TX_4X4];
4011233d2500723e5594f3e7c70896ffeeef32b9c950ywan      distortion2 += dist_uv[TX_4X4];
4012233d2500723e5594f3e7c70896ffeeef32b9c950ywan      distortion_uv = dist_uv[TX_4X4];
4013233d2500723e5594f3e7c70896ffeeef32b9c950ywan      mbmi->uv_mode = mode_uv[TX_4X4];
4014233d2500723e5594f3e7c70896ffeeef32b9c950ywan      tx_cache[ONLY_4X4] = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
4015233d2500723e5594f3e7c70896ffeeef32b9c950ywan      for (i = 0; i < TX_MODES; ++i)
4016233d2500723e5594f3e7c70896ffeeef32b9c950ywan        tx_cache[i] = tx_cache[ONLY_4X4];
4017233d2500723e5594f3e7c70896ffeeef32b9c950ywan    } else {
4018233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int rate;
4019233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int64_t distortion;
4020233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int64_t this_rd_thresh;
4021233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int64_t tmp_rd, tmp_best_rd = INT64_MAX, tmp_best_rdu = INT64_MAX;
4022233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int tmp_best_rate = INT_MAX, tmp_best_ratey = INT_MAX;
4023233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int64_t tmp_best_distortion = INT_MAX, tmp_best_sse, uv_sse;
4024233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int tmp_best_skippable = 0;
4025233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int switchable_filter_index;
4026233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int_mv *second_ref = comp_pred ?
4027233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             &mbmi->ref_mvs[second_ref_frame][0] : NULL;
4028233d2500723e5594f3e7c70896ffeeef32b9c950ywan      b_mode_info tmp_best_bmodes[16];
4029233d2500723e5594f3e7c70896ffeeef32b9c950ywan      MB_MODE_INFO tmp_best_mbmode;
4030233d2500723e5594f3e7c70896ffeeef32b9c950ywan      BEST_SEG_INFO bsi[SWITCHABLE_FILTERS];
4031233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int pred_exists = 0;
4032233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int uv_skippable;
4033233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4034233d2500723e5594f3e7c70896ffeeef32b9c950ywan      this_rd_thresh = (ref_frame == LAST_FRAME) ?
4035233d2500723e5594f3e7c70896ffeeef32b9c950ywan          cpi->rd_thresh_sub8x8[segment_id][bsize][THR_LAST] :
4036233d2500723e5594f3e7c70896ffeeef32b9c950ywan          cpi->rd_thresh_sub8x8[segment_id][bsize][THR_ALTR];
4037233d2500723e5594f3e7c70896ffeeef32b9c950ywan      this_rd_thresh = (ref_frame == GOLDEN_FRAME) ?
4038233d2500723e5594f3e7c70896ffeeef32b9c950ywan          cpi->rd_thresh_sub8x8[segment_id][bsize][THR_GOLD] : this_rd_thresh;
4039233d2500723e5594f3e7c70896ffeeef32b9c950ywan      xd->mi[0]->mbmi.tx_size = TX_4X4;
4040233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4041233d2500723e5594f3e7c70896ffeeef32b9c950ywan      cpi->mask_filter_rd = 0;
4042233d2500723e5594f3e7c70896ffeeef32b9c950ywan      for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i)
4043233d2500723e5594f3e7c70896ffeeef32b9c950ywan        cpi->rd_filter_cache[i] = INT64_MAX;
4044233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4045233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (cm->interp_filter != BILINEAR) {
4046233d2500723e5594f3e7c70896ffeeef32b9c950ywan        tmp_best_filter = EIGHTTAP;
4047233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (x->source_variance <
4048233d2500723e5594f3e7c70896ffeeef32b9c950ywan            cpi->sf.disable_filter_search_var_thresh) {
4049233d2500723e5594f3e7c70896ffeeef32b9c950ywan          tmp_best_filter = EIGHTTAP;
4050233d2500723e5594f3e7c70896ffeeef32b9c950ywan        } else if (cpi->sf.adaptive_pred_interp_filter == 1 &&
4051233d2500723e5594f3e7c70896ffeeef32b9c950ywan                   ctx->pred_interp_filter < SWITCHABLE) {
4052233d2500723e5594f3e7c70896ffeeef32b9c950ywan          tmp_best_filter = ctx->pred_interp_filter;
4053233d2500723e5594f3e7c70896ffeeef32b9c950ywan        } else if (cpi->sf.adaptive_pred_interp_filter == 2) {
4054233d2500723e5594f3e7c70896ffeeef32b9c950ywan          tmp_best_filter = ctx->pred_interp_filter < SWITCHABLE ?
4055233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              ctx->pred_interp_filter : 0;
4056233d2500723e5594f3e7c70896ffeeef32b9c950ywan        } else {
4057233d2500723e5594f3e7c70896ffeeef32b9c950ywan          for (switchable_filter_index = 0;
4058233d2500723e5594f3e7c70896ffeeef32b9c950ywan               switchable_filter_index < SWITCHABLE_FILTERS;
4059233d2500723e5594f3e7c70896ffeeef32b9c950ywan               ++switchable_filter_index) {
4060233d2500723e5594f3e7c70896ffeeef32b9c950ywan            int newbest, rs;
4061233d2500723e5594f3e7c70896ffeeef32b9c950ywan            int64_t rs_rd;
4062233d2500723e5594f3e7c70896ffeeef32b9c950ywan            mbmi->interp_filter = switchable_filter_index;
4063233d2500723e5594f3e7c70896ffeeef32b9c950ywan            tmp_rd = rd_pick_best_mbsegmentation(cpi, x, tile,
4064233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                                 &mbmi->ref_mvs[ref_frame][0],
4065233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                                 second_ref,
4066233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                                 best_yrd,
4067233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                                 &rate, &rate_y, &distortion,
4068233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                                 &skippable, &total_sse,
4069233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                                 (int)this_rd_thresh, seg_mvs,
4070233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                                 bsi, switchable_filter_index,
4071233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                                 mi_row, mi_col);
4072233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4073233d2500723e5594f3e7c70896ffeeef32b9c950ywan            if (tmp_rd == INT64_MAX)
4074233d2500723e5594f3e7c70896ffeeef32b9c950ywan              continue;
4075233d2500723e5594f3e7c70896ffeeef32b9c950ywan            rs = get_switchable_rate(x);
4076233d2500723e5594f3e7c70896ffeeef32b9c950ywan            rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0);
4077233d2500723e5594f3e7c70896ffeeef32b9c950ywan            cpi->rd_filter_cache[switchable_filter_index] = tmp_rd;
4078233d2500723e5594f3e7c70896ffeeef32b9c950ywan            cpi->rd_filter_cache[SWITCHABLE_FILTERS] =
4079233d2500723e5594f3e7c70896ffeeef32b9c950ywan                MIN(cpi->rd_filter_cache[SWITCHABLE_FILTERS],
4080233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    tmp_rd + rs_rd);
4081233d2500723e5594f3e7c70896ffeeef32b9c950ywan            if (cm->interp_filter == SWITCHABLE)
4082233d2500723e5594f3e7c70896ffeeef32b9c950ywan              tmp_rd += rs_rd;
4083233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4084233d2500723e5594f3e7c70896ffeeef32b9c950ywan            cpi->mask_filter_rd = MAX(cpi->mask_filter_rd, tmp_rd);
4085233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4086233d2500723e5594f3e7c70896ffeeef32b9c950ywan            newbest = (tmp_rd < tmp_best_rd);
4087233d2500723e5594f3e7c70896ffeeef32b9c950ywan            if (newbest) {
4088233d2500723e5594f3e7c70896ffeeef32b9c950ywan              tmp_best_filter = mbmi->interp_filter;
4089233d2500723e5594f3e7c70896ffeeef32b9c950ywan              tmp_best_rd = tmp_rd;
4090233d2500723e5594f3e7c70896ffeeef32b9c950ywan            }
4091233d2500723e5594f3e7c70896ffeeef32b9c950ywan            if ((newbest && cm->interp_filter == SWITCHABLE) ||
4092233d2500723e5594f3e7c70896ffeeef32b9c950ywan                (mbmi->interp_filter == cm->interp_filter &&
4093233d2500723e5594f3e7c70896ffeeef32b9c950ywan                 cm->interp_filter != SWITCHABLE)) {
4094233d2500723e5594f3e7c70896ffeeef32b9c950ywan              tmp_best_rdu = tmp_rd;
4095233d2500723e5594f3e7c70896ffeeef32b9c950ywan              tmp_best_rate = rate;
4096233d2500723e5594f3e7c70896ffeeef32b9c950ywan              tmp_best_ratey = rate_y;
4097233d2500723e5594f3e7c70896ffeeef32b9c950ywan              tmp_best_distortion = distortion;
4098233d2500723e5594f3e7c70896ffeeef32b9c950ywan              tmp_best_sse = total_sse;
4099233d2500723e5594f3e7c70896ffeeef32b9c950ywan              tmp_best_skippable = skippable;
4100233d2500723e5594f3e7c70896ffeeef32b9c950ywan              tmp_best_mbmode = *mbmi;
4101233d2500723e5594f3e7c70896ffeeef32b9c950ywan              for (i = 0; i < 4; i++) {
4102233d2500723e5594f3e7c70896ffeeef32b9c950ywan                tmp_best_bmodes[i] = xd->mi[0]->bmi[i];
4103233d2500723e5594f3e7c70896ffeeef32b9c950ywan                x->zcoeff_blk[TX_4X4][i] = !x->plane[0].eobs[i];
4104233d2500723e5594f3e7c70896ffeeef32b9c950ywan              }
4105233d2500723e5594f3e7c70896ffeeef32b9c950ywan              pred_exists = 1;
4106233d2500723e5594f3e7c70896ffeeef32b9c950ywan              if (switchable_filter_index == 0 &&
4107233d2500723e5594f3e7c70896ffeeef32b9c950ywan                  cpi->sf.use_rd_breakout &&
4108233d2500723e5594f3e7c70896ffeeef32b9c950ywan                  best_rd < INT64_MAX) {
4109233d2500723e5594f3e7c70896ffeeef32b9c950ywan                if (tmp_best_rdu / 2 > best_rd) {
4110233d2500723e5594f3e7c70896ffeeef32b9c950ywan                  // skip searching the other filters if the first is
4111233d2500723e5594f3e7c70896ffeeef32b9c950ywan                  // already substantially larger than the best so far
4112233d2500723e5594f3e7c70896ffeeef32b9c950ywan                  tmp_best_filter = mbmi->interp_filter;
4113233d2500723e5594f3e7c70896ffeeef32b9c950ywan                  tmp_best_rdu = INT64_MAX;
4114233d2500723e5594f3e7c70896ffeeef32b9c950ywan                  break;
4115233d2500723e5594f3e7c70896ffeeef32b9c950ywan                }
4116233d2500723e5594f3e7c70896ffeeef32b9c950ywan              }
4117233d2500723e5594f3e7c70896ffeeef32b9c950ywan            }
4118233d2500723e5594f3e7c70896ffeeef32b9c950ywan          }  // switchable_filter_index loop
4119233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
4120233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
4121233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4122233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (tmp_best_rdu == INT64_MAX && pred_exists)
4123233d2500723e5594f3e7c70896ffeeef32b9c950ywan        continue;
4124233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4125233d2500723e5594f3e7c70896ffeeef32b9c950ywan      mbmi->interp_filter = (cm->interp_filter == SWITCHABLE ?
4126233d2500723e5594f3e7c70896ffeeef32b9c950ywan                             tmp_best_filter : cm->interp_filter);
4127233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (!pred_exists) {
4128233d2500723e5594f3e7c70896ffeeef32b9c950ywan        // Handles the special case when a filter that is not in the
4129233d2500723e5594f3e7c70896ffeeef32b9c950ywan        // switchable list (bilinear, 6-tap) is indicated at the frame level
4130233d2500723e5594f3e7c70896ffeeef32b9c950ywan        tmp_rd = rd_pick_best_mbsegmentation(cpi, x, tile,
4131233d2500723e5594f3e7c70896ffeeef32b9c950ywan                     &mbmi->ref_mvs[ref_frame][0],
4132233d2500723e5594f3e7c70896ffeeef32b9c950ywan                     second_ref,
4133233d2500723e5594f3e7c70896ffeeef32b9c950ywan                     best_yrd,
4134233d2500723e5594f3e7c70896ffeeef32b9c950ywan                     &rate, &rate_y, &distortion,
4135233d2500723e5594f3e7c70896ffeeef32b9c950ywan                     &skippable, &total_sse,
4136233d2500723e5594f3e7c70896ffeeef32b9c950ywan                     (int)this_rd_thresh, seg_mvs,
4137233d2500723e5594f3e7c70896ffeeef32b9c950ywan                     bsi, 0,
4138233d2500723e5594f3e7c70896ffeeef32b9c950ywan                     mi_row, mi_col);
4139233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (tmp_rd == INT64_MAX)
4140233d2500723e5594f3e7c70896ffeeef32b9c950ywan          continue;
4141233d2500723e5594f3e7c70896ffeeef32b9c950ywan      } else {
4142233d2500723e5594f3e7c70896ffeeef32b9c950ywan        total_sse = tmp_best_sse;
4143233d2500723e5594f3e7c70896ffeeef32b9c950ywan        rate = tmp_best_rate;
4144233d2500723e5594f3e7c70896ffeeef32b9c950ywan        rate_y = tmp_best_ratey;
4145233d2500723e5594f3e7c70896ffeeef32b9c950ywan        distortion = tmp_best_distortion;
4146233d2500723e5594f3e7c70896ffeeef32b9c950ywan        skippable = tmp_best_skippable;
4147233d2500723e5594f3e7c70896ffeeef32b9c950ywan        *mbmi = tmp_best_mbmode;
4148233d2500723e5594f3e7c70896ffeeef32b9c950ywan        for (i = 0; i < 4; i++)
4149233d2500723e5594f3e7c70896ffeeef32b9c950ywan          xd->mi[0]->bmi[i] = tmp_best_bmodes[i];
4150233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
4151233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4152233d2500723e5594f3e7c70896ffeeef32b9c950ywan      rate2 += rate;
4153233d2500723e5594f3e7c70896ffeeef32b9c950ywan      distortion2 += distortion;
4154233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4155233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (cm->interp_filter == SWITCHABLE)
4156233d2500723e5594f3e7c70896ffeeef32b9c950ywan        rate2 += get_switchable_rate(x);
4157233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4158233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (!mode_excluded)
4159233d2500723e5594f3e7c70896ffeeef32b9c950ywan        mode_excluded = comp_pred ? cm->reference_mode == SINGLE_REFERENCE
4160233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  : cm->reference_mode == COMPOUND_REFERENCE;
4161233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4162233d2500723e5594f3e7c70896ffeeef32b9c950ywan      compmode_cost = vp9_cost_bit(comp_mode_p, comp_pred);
4163233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4164233d2500723e5594f3e7c70896ffeeef32b9c950ywan      tmp_best_rdu = best_rd -
4165233d2500723e5594f3e7c70896ffeeef32b9c950ywan          MIN(RDCOST(x->rdmult, x->rddiv, rate2, distortion2),
4166233d2500723e5594f3e7c70896ffeeef32b9c950ywan              RDCOST(x->rdmult, x->rddiv, 0, total_sse));
4167233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4168233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (tmp_best_rdu > 0) {
4169233d2500723e5594f3e7c70896ffeeef32b9c950ywan        // If even the 'Y' rd value of split is higher than best so far
4170233d2500723e5594f3e7c70896ffeeef32b9c950ywan        // then dont bother looking at UV
4171233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vp9_build_inter_predictors_sbuv(&x->e_mbd, mi_row, mi_col,
4172233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                        BLOCK_8X8);
4173233d2500723e5594f3e7c70896ffeeef32b9c950ywan        super_block_uvrd(cpi, x, &rate_uv, &distortion_uv, &uv_skippable,
4174233d2500723e5594f3e7c70896ffeeef32b9c950ywan                         &uv_sse, BLOCK_8X8, tmp_best_rdu);
4175233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (rate_uv == INT_MAX)
4176233d2500723e5594f3e7c70896ffeeef32b9c950ywan          continue;
4177233d2500723e5594f3e7c70896ffeeef32b9c950ywan        rate2 += rate_uv;
4178233d2500723e5594f3e7c70896ffeeef32b9c950ywan        distortion2 += distortion_uv;
4179233d2500723e5594f3e7c70896ffeeef32b9c950ywan        skippable = skippable && uv_skippable;
4180233d2500723e5594f3e7c70896ffeeef32b9c950ywan        total_sse += uv_sse;
4181233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4182233d2500723e5594f3e7c70896ffeeef32b9c950ywan        tx_cache[ONLY_4X4] = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
4183233d2500723e5594f3e7c70896ffeeef32b9c950ywan        for (i = 0; i < TX_MODES; ++i)
4184233d2500723e5594f3e7c70896ffeeef32b9c950ywan          tx_cache[i] = tx_cache[ONLY_4X4];
4185233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
4186233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
4187233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4188233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (cm->reference_mode == REFERENCE_MODE_SELECT)
4189233d2500723e5594f3e7c70896ffeeef32b9c950ywan      rate2 += compmode_cost;
4190233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4191233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Estimate the reference frame signaling cost and add it
4192233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // to the rolling cost variable.
4193233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (second_ref_frame > INTRA_FRAME) {
4194233d2500723e5594f3e7c70896ffeeef32b9c950ywan      rate2 += ref_costs_comp[ref_frame];
4195233d2500723e5594f3e7c70896ffeeef32b9c950ywan    } else {
4196233d2500723e5594f3e7c70896ffeeef32b9c950ywan      rate2 += ref_costs_single[ref_frame];
4197233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
4198233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4199233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (!disable_skip) {
4200233d2500723e5594f3e7c70896ffeeef32b9c950ywan      // Test for the condition where skip block will be activated
4201233d2500723e5594f3e7c70896ffeeef32b9c950ywan      // because there are no non zero coefficients and make any
4202233d2500723e5594f3e7c70896ffeeef32b9c950ywan      // necessary adjustment for rate. Ignore if skip is coded at
4203233d2500723e5594f3e7c70896ffeeef32b9c950ywan      // segment level as the cost wont have been added in.
4204233d2500723e5594f3e7c70896ffeeef32b9c950ywan      // Is Mb level skip allowed (i.e. not coded at segment level).
4205233d2500723e5594f3e7c70896ffeeef32b9c950ywan      const int mb_skip_allowed = !vp9_segfeature_active(seg, segment_id,
4206233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                                         SEG_LVL_SKIP);
4207233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4208233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (mb_skip_allowed && ref_frame != INTRA_FRAME && !xd->lossless) {
4209233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
4210233d2500723e5594f3e7c70896ffeeef32b9c950ywan            RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
4211233d2500723e5594f3e7c70896ffeeef32b9c950ywan          // Add in the cost of the no skip flag.
4212233d2500723e5594f3e7c70896ffeeef32b9c950ywan          rate2 += vp9_cost_bit(vp9_get_skip_prob(cm, xd), 0);
4213233d2500723e5594f3e7c70896ffeeef32b9c950ywan        } else {
4214233d2500723e5594f3e7c70896ffeeef32b9c950ywan          // FIXME(rbultje) make this work for splitmv also
4215233d2500723e5594f3e7c70896ffeeef32b9c950ywan          rate2 += vp9_cost_bit(vp9_get_skip_prob(cm, xd), 1);
4216233d2500723e5594f3e7c70896ffeeef32b9c950ywan          distortion2 = total_sse;
4217233d2500723e5594f3e7c70896ffeeef32b9c950ywan          assert(total_sse >= 0);
4218233d2500723e5594f3e7c70896ffeeef32b9c950ywan          rate2 -= (rate_y + rate_uv);
4219233d2500723e5594f3e7c70896ffeeef32b9c950ywan          rate_y = 0;
4220233d2500723e5594f3e7c70896ffeeef32b9c950ywan          rate_uv = 0;
4221233d2500723e5594f3e7c70896ffeeef32b9c950ywan          this_skip2 = 1;
4222233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
4223233d2500723e5594f3e7c70896ffeeef32b9c950ywan      } else if (mb_skip_allowed) {
4224233d2500723e5594f3e7c70896ffeeef32b9c950ywan        // Add in the cost of the no skip flag.
4225233d2500723e5594f3e7c70896ffeeef32b9c950ywan        rate2 += vp9_cost_bit(vp9_get_skip_prob(cm, xd), 0);
4226233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
4227233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4228233d2500723e5594f3e7c70896ffeeef32b9c950ywan      // Calculate the final RD estimate for this mode.
4229233d2500723e5594f3e7c70896ffeeef32b9c950ywan      this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
4230233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
4231233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4232233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Keep record of best inter rd with single reference
4233233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (is_inter_block(&xd->mi[0]->mbmi) &&
4234233d2500723e5594f3e7c70896ffeeef32b9c950ywan        !has_second_ref(&xd->mi[0]->mbmi) &&
4235233d2500723e5594f3e7c70896ffeeef32b9c950ywan        !mode_excluded &&
4236233d2500723e5594f3e7c70896ffeeef32b9c950ywan        this_rd < best_inter_rd) {
4237233d2500723e5594f3e7c70896ffeeef32b9c950ywan      best_inter_rd = this_rd;
4238233d2500723e5594f3e7c70896ffeeef32b9c950ywan      best_inter_ref_frame = ref_frame;
4239233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
4240233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4241233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (!disable_skip && ref_frame == INTRA_FRAME) {
4242233d2500723e5594f3e7c70896ffeeef32b9c950ywan      for (i = 0; i < REFERENCE_MODES; ++i)
4243233d2500723e5594f3e7c70896ffeeef32b9c950ywan        best_pred_rd[i] = MIN(best_pred_rd[i], this_rd);
4244233d2500723e5594f3e7c70896ffeeef32b9c950ywan      for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
4245233d2500723e5594f3e7c70896ffeeef32b9c950ywan        best_filter_rd[i] = MIN(best_filter_rd[i], this_rd);
4246233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
4247233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4248233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Did this mode help.. i.e. is it the new best mode
4249233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (this_rd < best_rd || x->skip) {
4250233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (!mode_excluded) {
4251233d2500723e5594f3e7c70896ffeeef32b9c950ywan        int max_plane = MAX_MB_PLANE;
4252233d2500723e5594f3e7c70896ffeeef32b9c950ywan        // Note index of best mode so far
4253233d2500723e5594f3e7c70896ffeeef32b9c950ywan        best_mode_index = mode_index;
4254233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4255233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (ref_frame == INTRA_FRAME) {
4256233d2500723e5594f3e7c70896ffeeef32b9c950ywan          /* required for left and above block mv */
4257233d2500723e5594f3e7c70896ffeeef32b9c950ywan          mbmi->mv[0].as_int = 0;
4258233d2500723e5594f3e7c70896ffeeef32b9c950ywan          max_plane = 1;
4259233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
4260233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4261233d2500723e5594f3e7c70896ffeeef32b9c950ywan        *returnrate = rate2;
4262233d2500723e5594f3e7c70896ffeeef32b9c950ywan        *returndistortion = distortion2;
4263233d2500723e5594f3e7c70896ffeeef32b9c950ywan        best_rd = this_rd;
4264233d2500723e5594f3e7c70896ffeeef32b9c950ywan        best_yrd = best_rd -
4265233d2500723e5594f3e7c70896ffeeef32b9c950ywan                   RDCOST(x->rdmult, x->rddiv, rate_uv, distortion_uv);
4266233d2500723e5594f3e7c70896ffeeef32b9c950ywan        best_mbmode = *mbmi;
4267233d2500723e5594f3e7c70896ffeeef32b9c950ywan        best_skip2 = this_skip2;
4268233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (!x->select_txfm_size)
4269233d2500723e5594f3e7c70896ffeeef32b9c950ywan          swap_block_ptr(x, ctx, max_plane);
4270233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vpx_memcpy(ctx->zcoeff_blk, x->zcoeff_blk[mbmi->tx_size],
4271233d2500723e5594f3e7c70896ffeeef32b9c950ywan                   sizeof(uint8_t) * ctx->num_4x4_blk);
4272233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4273233d2500723e5594f3e7c70896ffeeef32b9c950ywan        for (i = 0; i < 4; i++)
4274233d2500723e5594f3e7c70896ffeeef32b9c950ywan          best_bmodes[i] = xd->mi[0]->bmi[i];
4275233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4276233d2500723e5594f3e7c70896ffeeef32b9c950ywan        // TODO(debargha): enhance this test with a better distortion prediction
4277233d2500723e5594f3e7c70896ffeeef32b9c950ywan        // based on qp, activity mask and history
4278233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if ((cpi->sf.mode_search_skip_flags & FLAG_EARLY_TERMINATE) &&
4279233d2500723e5594f3e7c70896ffeeef32b9c950ywan            (mode_index > MIN_EARLY_TERM_INDEX)) {
4280233d2500723e5594f3e7c70896ffeeef32b9c950ywan          const int qstep = xd->plane[0].dequant[1];
4281233d2500723e5594f3e7c70896ffeeef32b9c950ywan          // TODO(debargha): Enhance this by specializing for each mode_index
4282233d2500723e5594f3e7c70896ffeeef32b9c950ywan          int scale = 4;
4283233d2500723e5594f3e7c70896ffeeef32b9c950ywan          if (x->source_variance < UINT_MAX) {
4284233d2500723e5594f3e7c70896ffeeef32b9c950ywan            const int var_adjust = (x->source_variance < 16);
4285233d2500723e5594f3e7c70896ffeeef32b9c950ywan            scale -= var_adjust;
4286233d2500723e5594f3e7c70896ffeeef32b9c950ywan          }
4287233d2500723e5594f3e7c70896ffeeef32b9c950ywan          if (ref_frame > INTRA_FRAME &&
4288233d2500723e5594f3e7c70896ffeeef32b9c950ywan              distortion2 * scale < qstep * qstep) {
4289233d2500723e5594f3e7c70896ffeeef32b9c950ywan            early_term = 1;
4290233d2500723e5594f3e7c70896ffeeef32b9c950ywan          }
4291233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
4292233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
4293233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
4294233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4295233d2500723e5594f3e7c70896ffeeef32b9c950ywan    /* keep record of best compound/single-only prediction */
4296233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (!disable_skip && ref_frame != INTRA_FRAME) {
4297233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
4298233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4299233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (cm->reference_mode == REFERENCE_MODE_SELECT) {
4300233d2500723e5594f3e7c70896ffeeef32b9c950ywan        single_rate = rate2 - compmode_cost;
4301233d2500723e5594f3e7c70896ffeeef32b9c950ywan        hybrid_rate = rate2;
4302233d2500723e5594f3e7c70896ffeeef32b9c950ywan      } else {
4303233d2500723e5594f3e7c70896ffeeef32b9c950ywan        single_rate = rate2;
4304233d2500723e5594f3e7c70896ffeeef32b9c950ywan        hybrid_rate = rate2 + compmode_cost;
4305233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
4306233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4307233d2500723e5594f3e7c70896ffeeef32b9c950ywan      single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
4308233d2500723e5594f3e7c70896ffeeef32b9c950ywan      hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
4309233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4310233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (second_ref_frame <= INTRA_FRAME &&
4311233d2500723e5594f3e7c70896ffeeef32b9c950ywan          single_rd < best_pred_rd[SINGLE_REFERENCE]) {
4312233d2500723e5594f3e7c70896ffeeef32b9c950ywan        best_pred_rd[SINGLE_REFERENCE] = single_rd;
4313233d2500723e5594f3e7c70896ffeeef32b9c950ywan      } else if (second_ref_frame > INTRA_FRAME &&
4314233d2500723e5594f3e7c70896ffeeef32b9c950ywan                 single_rd < best_pred_rd[COMPOUND_REFERENCE]) {
4315233d2500723e5594f3e7c70896ffeeef32b9c950ywan        best_pred_rd[COMPOUND_REFERENCE] = single_rd;
4316233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
4317233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
4318233d2500723e5594f3e7c70896ffeeef32b9c950ywan        best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
4319233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
4320233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4321233d2500723e5594f3e7c70896ffeeef32b9c950ywan    /* keep record of best filter type */
4322233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (!mode_excluded && !disable_skip && ref_frame != INTRA_FRAME &&
4323233d2500723e5594f3e7c70896ffeeef32b9c950ywan        cm->interp_filter != BILINEAR) {
4324233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int64_t ref = cpi->rd_filter_cache[cm->interp_filter == SWITCHABLE ?
4325233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              SWITCHABLE_FILTERS : cm->interp_filter];
4326233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int64_t adj_rd;
4327233d2500723e5594f3e7c70896ffeeef32b9c950ywan      for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) {
4328233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (ref == INT64_MAX)
4329233d2500723e5594f3e7c70896ffeeef32b9c950ywan          adj_rd = 0;
4330233d2500723e5594f3e7c70896ffeeef32b9c950ywan        else if (cpi->rd_filter_cache[i] == INT64_MAX)
4331233d2500723e5594f3e7c70896ffeeef32b9c950ywan          // when early termination is triggered, the encoder does not have
4332233d2500723e5594f3e7c70896ffeeef32b9c950ywan          // access to the rate-distortion cost. it only knows that the cost
4333233d2500723e5594f3e7c70896ffeeef32b9c950ywan          // should be above the maximum valid value. hence it takes the known
4334233d2500723e5594f3e7c70896ffeeef32b9c950ywan          // maximum plus an arbitrary constant as the rate-distortion cost.
4335233d2500723e5594f3e7c70896ffeeef32b9c950ywan          adj_rd = cpi->mask_filter_rd - ref + 10;
4336233d2500723e5594f3e7c70896ffeeef32b9c950ywan        else
4337233d2500723e5594f3e7c70896ffeeef32b9c950ywan          adj_rd = cpi->rd_filter_cache[i] - ref;
4338233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4339233d2500723e5594f3e7c70896ffeeef32b9c950ywan        adj_rd += this_rd;
4340233d2500723e5594f3e7c70896ffeeef32b9c950ywan        best_filter_rd[i] = MIN(best_filter_rd[i], adj_rd);
4341233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
4342233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
4343233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4344233d2500723e5594f3e7c70896ffeeef32b9c950ywan    /* keep record of best txfm size */
4345233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (bsize < BLOCK_32X32) {
4346233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (bsize < BLOCK_16X16) {
4347233d2500723e5594f3e7c70896ffeeef32b9c950ywan        tx_cache[ALLOW_8X8] = tx_cache[ONLY_4X4];
4348233d2500723e5594f3e7c70896ffeeef32b9c950ywan        tx_cache[ALLOW_16X16] = tx_cache[ALLOW_8X8];
4349233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
4350233d2500723e5594f3e7c70896ffeeef32b9c950ywan      tx_cache[ALLOW_32X32] = tx_cache[ALLOW_16X16];
4351233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
4352233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (!mode_excluded && this_rd != INT64_MAX) {
4353233d2500723e5594f3e7c70896ffeeef32b9c950ywan      for (i = 0; i < TX_MODES && tx_cache[i] < INT64_MAX; i++) {
4354233d2500723e5594f3e7c70896ffeeef32b9c950ywan        int64_t adj_rd = INT64_MAX;
4355233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (ref_frame > INTRA_FRAME)
4356233d2500723e5594f3e7c70896ffeeef32b9c950ywan          adj_rd = this_rd + tx_cache[i] - tx_cache[cm->tx_mode];
4357233d2500723e5594f3e7c70896ffeeef32b9c950ywan        else
4358233d2500723e5594f3e7c70896ffeeef32b9c950ywan          adj_rd = this_rd;
4359233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4360233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (adj_rd < best_tx_rd[i])
4361233d2500723e5594f3e7c70896ffeeef32b9c950ywan          best_tx_rd[i] = adj_rd;
4362233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
4363233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
4364233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4365233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (early_term)
4366233d2500723e5594f3e7c70896ffeeef32b9c950ywan      break;
4367233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4368233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (x->skip && !comp_pred)
4369233d2500723e5594f3e7c70896ffeeef32b9c950ywan      break;
4370233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
4371233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4372233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (best_rd >= best_rd_so_far)
4373233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return INT64_MAX;
4374233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4375233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // If we used an estimate for the uv intra rd in the loop above...
4376233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (cpi->sf.use_uv_intra_rd_estimate) {
4377233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Do Intra UV best rd mode selection if best mode choice above was intra.
4378233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (vp9_ref_order[best_mode_index].ref_frame[0] == INTRA_FRAME) {
4379233d2500723e5594f3e7c70896ffeeef32b9c950ywan      TX_SIZE uv_tx_size;
4380233d2500723e5594f3e7c70896ffeeef32b9c950ywan      *mbmi = best_mbmode;
4381233d2500723e5594f3e7c70896ffeeef32b9c950ywan      uv_tx_size = get_uv_tx_size(mbmi);
4382233d2500723e5594f3e7c70896ffeeef32b9c950ywan      rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv_intra[uv_tx_size],
4383233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              &rate_uv_tokenonly[uv_tx_size],
4384233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              &dist_uv[uv_tx_size],
4385233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              &skip_uv[uv_tx_size],
4386233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              BLOCK_8X8, uv_tx_size);
4387233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
4388233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
4389233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4390233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (best_rd == INT64_MAX && bsize < BLOCK_8X8) {
4391233d2500723e5594f3e7c70896ffeeef32b9c950ywan    *returnrate = INT_MAX;
4392233d2500723e5594f3e7c70896ffeeef32b9c950ywan    *returndistortion = INT64_MAX;
4393233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return best_rd;
4394233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
4395233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4396233d2500723e5594f3e7c70896ffeeef32b9c950ywan  assert((cm->interp_filter == SWITCHABLE) ||
4397233d2500723e5594f3e7c70896ffeeef32b9c950ywan         (cm->interp_filter == best_mbmode.interp_filter) ||
4398233d2500723e5594f3e7c70896ffeeef32b9c950ywan         !is_inter_block(&best_mbmode));
4399233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4400233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // Updating rd_thresh_freq_fact[] here means that the different
4401233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // partition/block sizes are handled independently based on the best
4402233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // choice for the current partition. It may well be better to keep a scaled
4403233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // best rd so far value and update rd_thresh_freq_fact based on the mode/size
4404233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // combination that wins out.
4405233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (cpi->sf.adaptive_rd_thresh) {
4406233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (mode_index = 0; mode_index < MAX_REFS; ++mode_index) {
4407233d2500723e5594f3e7c70896ffeeef32b9c950ywan      int *const fact = &cpi->rd_thresh_freq_sub8x8[bsize][mode_index];
4408233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4409233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (mode_index == best_mode_index) {
4410233d2500723e5594f3e7c70896ffeeef32b9c950ywan        *fact -= (*fact >> 3);
4411233d2500723e5594f3e7c70896ffeeef32b9c950ywan      } else {
4412233d2500723e5594f3e7c70896ffeeef32b9c950ywan        *fact = MIN(*fact + RD_THRESH_INC,
4413233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    cpi->sf.adaptive_rd_thresh * RD_THRESH_MAX_FACT);
4414233d2500723e5594f3e7c70896ffeeef32b9c950ywan      }
4415233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
4416233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
4417233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4418233d2500723e5594f3e7c70896ffeeef32b9c950ywan  // macroblock modes
4419233d2500723e5594f3e7c70896ffeeef32b9c950ywan  *mbmi = best_mbmode;
4420233d2500723e5594f3e7c70896ffeeef32b9c950ywan  x->skip |= best_skip2;
4421233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (!is_inter_block(&best_mbmode)) {
4422233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (i = 0; i < 4; i++)
4423233d2500723e5594f3e7c70896ffeeef32b9c950ywan      xd->mi[0]->bmi[i].as_mode = best_bmodes[i].as_mode;
4424233d2500723e5594f3e7c70896ffeeef32b9c950ywan  } else {
4425233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (i = 0; i < 4; ++i)
4426233d2500723e5594f3e7c70896ffeeef32b9c950ywan      vpx_memcpy(&xd->mi[0]->bmi[i], &best_bmodes[i], sizeof(b_mode_info));
4427233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4428233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mbmi->mv[0].as_int = xd->mi[0]->bmi[3].as_mv[0].as_int;
4429233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mbmi->mv[1].as_int = xd->mi[0]->bmi[3].as_mv[1].as_int;
4430233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
4431233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4432233d2500723e5594f3e7c70896ffeeef32b9c950ywan  for (i = 0; i < REFERENCE_MODES; ++i) {
4433233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (best_pred_rd[i] == INT64_MAX)
4434233d2500723e5594f3e7c70896ffeeef32b9c950ywan      best_pred_diff[i] = INT_MIN;
4435233d2500723e5594f3e7c70896ffeeef32b9c950ywan    else
4436233d2500723e5594f3e7c70896ffeeef32b9c950ywan      best_pred_diff[i] = best_rd - best_pred_rd[i];
4437233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
4438233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4439233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (!x->skip) {
4440233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) {
4441233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (best_filter_rd[i] == INT64_MAX)
4442233d2500723e5594f3e7c70896ffeeef32b9c950ywan        best_filter_diff[i] = 0;
4443233d2500723e5594f3e7c70896ffeeef32b9c950ywan      else
4444233d2500723e5594f3e7c70896ffeeef32b9c950ywan        best_filter_diff[i] = best_rd - best_filter_rd[i];
4445233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
4446233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (cm->interp_filter == SWITCHABLE)
4447233d2500723e5594f3e7c70896ffeeef32b9c950ywan      assert(best_filter_diff[SWITCHABLE_FILTERS] == 0);
4448233d2500723e5594f3e7c70896ffeeef32b9c950ywan  } else {
4449233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vp9_zero(best_filter_diff);
4450233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
4451233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4452233d2500723e5594f3e7c70896ffeeef32b9c950ywan  if (!x->skip) {
4453233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (i = 0; i < TX_MODES; i++) {
4454233d2500723e5594f3e7c70896ffeeef32b9c950ywan      if (best_tx_rd[i] == INT64_MAX)
4455233d2500723e5594f3e7c70896ffeeef32b9c950ywan        best_tx_diff[i] = 0;
4456233d2500723e5594f3e7c70896ffeeef32b9c950ywan      else
4457233d2500723e5594f3e7c70896ffeeef32b9c950ywan        best_tx_diff[i] = best_rd - best_tx_rd[i];
4458233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
4459233d2500723e5594f3e7c70896ffeeef32b9c950ywan  } else {
4460233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vp9_zero(best_tx_diff);
4461233d2500723e5594f3e7c70896ffeeef32b9c950ywan  }
4462233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4463233d2500723e5594f3e7c70896ffeeef32b9c950ywan  set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
4464233d2500723e5594f3e7c70896ffeeef32b9c950ywan  store_coding_context(x, ctx, best_mode_index,
4465233d2500723e5594f3e7c70896ffeeef32b9c950ywan                       &mbmi->ref_mvs[mbmi->ref_frame[0]][0],
4466233d2500723e5594f3e7c70896ffeeef32b9c950ywan                       &mbmi->ref_mvs[mbmi->ref_frame[1] < 0 ? 0 :
4467233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                      mbmi->ref_frame[1]][0],
4468233d2500723e5594f3e7c70896ffeeef32b9c950ywan                       best_pred_diff, best_tx_diff, best_filter_diff);
4469233d2500723e5594f3e7c70896ffeeef32b9c950ywan
4470233d2500723e5594f3e7c70896ffeeef32b9c950ywan  return best_rd;
4471233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
4472