vp9_mcomp.c 74.1 KB
Newer Older
John Koleszar's avatar
John Koleszar committed
1
/*
2
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
John Koleszar's avatar
John Koleszar committed
3
 *
4
 *  Use of this source code is governed by a BSD-style license
5 6
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
7
 *  in the file PATENTS.  All contributing project authors may
8
 *  be found in the AUTHORS file in the root of the source tree.
John Koleszar's avatar
John Koleszar committed
9 10
 */

Dmitry Kovalev's avatar
Dmitry Kovalev committed
11 12 13
#include <stdio.h>
#include <limits.h>
#include <math.h>
John Koleszar's avatar
John Koleszar committed
14

15
#include "vp9/encoder/vp9_onyx_int.h"
16
#include "vp9/encoder/vp9_mcomp.h"
John Koleszar's avatar
John Koleszar committed
17
#include "vpx_mem/vpx_mem.h"
18
#include "./vpx_config.h"
19
#include "vp9/common/vp9_findnearmv.h"
Ronald S. Bultje's avatar
Ronald S. Bultje committed
20
#include "vp9/common/vp9_common.h"
John Koleszar's avatar
John Koleszar committed
21

22
void vp9_clamp_mv_min_max(MACROBLOCK *x, int_mv *ref_mv) {
23
  int col_min = (ref_mv->as_mv.col >> 3) - MAX_FULL_PEL_VAL +
24
                                 ((ref_mv->as_mv.col & 7) ? 1 : 0);
25
  int row_min = (ref_mv->as_mv.row >> 3) - MAX_FULL_PEL_VAL +
26
                                 ((ref_mv->as_mv.row & 7) ? 1 : 0);
27 28 29 30 31 32 33 34 35 36 37 38 39 40
  int col_max = (ref_mv->as_mv.col >> 3) + MAX_FULL_PEL_VAL;
  int row_max = (ref_mv->as_mv.row >> 3) + MAX_FULL_PEL_VAL;

  /* Get intersection of UMV window and valid MV window to reduce # of checks in diamond search. */
  if (x->mv_col_min < col_min)
    x->mv_col_min = col_min;
  if (x->mv_col_max > col_max)
    x->mv_col_max = col_max;
  if (x->mv_row_min < row_min)
    x->mv_row_min = row_min;
  if (x->mv_row_max > row_max)
    x->mv_row_max = row_max;
}

41 42 43 44 45 46 47 48 49 50 51 52 53
int vp9_init_search_range(int width, int height) {
  int sr = 0;
  int frm = MIN(width, height);

  while ((frm << sr) < MAX_FULL_PEL_VAL)
    sr++;

  if (sr)
    sr--;

  return sr;
}

54
int vp9_mv_bit_cost(int_mv *mv, int_mv *ref, int *mvjcost, int *mvcost[2],
Dmitry Kovalev's avatar
Dmitry Kovalev committed
55
                    int weight, int ishp) {
56
  MV v;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
57 58
  v.row = mv->as_mv.row - ref->as_mv.row;
  v.col = mv->as_mv.col - ref->as_mv.col;
59 60 61
  return ROUND_POWER_OF_TWO((mvjcost[vp9_get_mv_joint(&v)] +
                             mvcost[0][v.row] +
                             mvcost[1][v.col]) * weight, 7);
John Koleszar's avatar
John Koleszar committed
62 63
}

64
static int mv_err_cost(int_mv *mv, int_mv *ref, int *mvjcost, int *mvcost[2],
65
                       int error_per_bit, int ishp) {
66 67
  if (mvcost) {
    MV v;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
68 69
    v.row = mv->as_mv.row - ref->as_mv.row;
    v.col = mv->as_mv.col - ref->as_mv.col;
70 71 72
    return ROUND_POWER_OF_TWO((mvjcost[vp9_get_mv_joint(&v)] +
                               mvcost[0][v.row] +
                               mvcost[1][v.col]) * error_per_bit, 13);
73
  }
John Koleszar's avatar
John Koleszar committed
74
  return 0;
75 76
}

77 78
static int mvsad_err_cost(int_mv *mv, int_mv *ref, int *mvjsadcost,
                          int *mvsadcost[2], int error_per_bit) {
79 80
  if (mvsadcost) {
    MV v;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
81 82
    v.row = mv->as_mv.row - ref->as_mv.row;
    v.col = mv->as_mv.col - ref->as_mv.col;
83 84 85
    return ROUND_POWER_OF_TWO((mvjsadcost[vp9_get_mv_joint(&v)] +
                               mvsadcost[0][v.row] +
                               mvsadcost[1][v.col]) * error_per_bit, 8);
86
  }
John Koleszar's avatar
John Koleszar committed
87
  return 0;
John Koleszar's avatar
John Koleszar committed
88 89
}

90
void vp9_init_dsmotion_compensation(MACROBLOCK *x, int stride) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
91
  int len;
John Koleszar's avatar
John Koleszar committed
92
  int search_site_count = 0;
John Koleszar's avatar
John Koleszar committed
93

John Koleszar's avatar
John Koleszar committed
94 95 96 97 98 99
  // Generate offsets for 4 search sites per step.
  x->ss[search_site_count].mv.col = 0;
  x->ss[search_site_count].mv.row = 0;
  x->ss[search_site_count].offset = 0;
  search_site_count++;

Dmitry Kovalev's avatar
Dmitry Kovalev committed
100
  for (len = MAX_FIRST_STEP; len > 0; len /= 2) {
John Koleszar's avatar
John Koleszar committed
101 102
    // Compute offsets for search sites.
    x->ss[search_site_count].mv.col = 0;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
103 104
    x->ss[search_site_count].mv.row = -len;
    x->ss[search_site_count].offset = -len * stride;
John Koleszar's avatar
John Koleszar committed
105 106 107
    search_site_count++;

    // Compute offsets for search sites.
John Koleszar's avatar
John Koleszar committed
108
    x->ss[search_site_count].mv.col = 0;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
109 110
    x->ss[search_site_count].mv.row = len;
    x->ss[search_site_count].offset = len * stride;
John Koleszar's avatar
John Koleszar committed
111 112 113
    search_site_count++;

    // Compute offsets for search sites.
Dmitry Kovalev's avatar
Dmitry Kovalev committed
114
    x->ss[search_site_count].mv.col = -len;
John Koleszar's avatar
John Koleszar committed
115
    x->ss[search_site_count].mv.row = 0;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
116
    x->ss[search_site_count].offset = -len;
John Koleszar's avatar
John Koleszar committed
117 118
    search_site_count++;

John Koleszar's avatar
John Koleszar committed
119
    // Compute offsets for search sites.
Dmitry Kovalev's avatar
Dmitry Kovalev committed
120
    x->ss[search_site_count].mv.col = len;
John Koleszar's avatar
John Koleszar committed
121
    x->ss[search_site_count].mv.row = 0;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
122
    x->ss[search_site_count].offset = len;
John Koleszar's avatar
John Koleszar committed
123 124 125 126 127
    search_site_count++;
  }

  x->ss_count = search_site_count;
  x->searches_per_step = 4;
John Koleszar's avatar
John Koleszar committed
128 129
}

130
void vp9_init3smotion_compensation(MACROBLOCK *x, int stride) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
131
  int len;
John Koleszar's avatar
John Koleszar committed
132 133 134 135 136 137 138 139
  int search_site_count = 0;

  // Generate offsets for 8 search sites per step.
  x->ss[search_site_count].mv.col = 0;
  x->ss[search_site_count].mv.row = 0;
  x->ss[search_site_count].offset = 0;
  search_site_count++;

Dmitry Kovalev's avatar
Dmitry Kovalev committed
140
  for (len = MAX_FIRST_STEP; len > 0; len /= 2) {
John Koleszar's avatar
John Koleszar committed
141
    // Compute offsets for search sites.
John Koleszar's avatar
John Koleszar committed
142
    x->ss[search_site_count].mv.col = 0;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
143 144
    x->ss[search_site_count].mv.row = -len;
    x->ss[search_site_count].offset = -len * stride;
John Koleszar's avatar
John Koleszar committed
145 146 147 148
    search_site_count++;

    // Compute offsets for search sites.
    x->ss[search_site_count].mv.col = 0;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
149 150
    x->ss[search_site_count].mv.row = len;
    x->ss[search_site_count].offset = len * stride;
John Koleszar's avatar
John Koleszar committed
151 152 153
    search_site_count++;

    // Compute offsets for search sites.
Dmitry Kovalev's avatar
Dmitry Kovalev committed
154
    x->ss[search_site_count].mv.col = -len;
John Koleszar's avatar
John Koleszar committed
155
    x->ss[search_site_count].mv.row = 0;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
156
    x->ss[search_site_count].offset = -len;
John Koleszar's avatar
John Koleszar committed
157 158
    search_site_count++;

John Koleszar's avatar
John Koleszar committed
159
    // Compute offsets for search sites.
Dmitry Kovalev's avatar
Dmitry Kovalev committed
160
    x->ss[search_site_count].mv.col = len;
John Koleszar's avatar
John Koleszar committed
161
    x->ss[search_site_count].mv.row = 0;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
162
    x->ss[search_site_count].offset = len;
John Koleszar's avatar
John Koleszar committed
163 164 165
    search_site_count++;

    // Compute offsets for search sites.
Dmitry Kovalev's avatar
Dmitry Kovalev committed
166 167 168
    x->ss[search_site_count].mv.col = -len;
    x->ss[search_site_count].mv.row = -len;
    x->ss[search_site_count].offset = -len * stride - len;
John Koleszar's avatar
John Koleszar committed
169 170 171
    search_site_count++;

    // Compute offsets for search sites.
Dmitry Kovalev's avatar
Dmitry Kovalev committed
172 173 174
    x->ss[search_site_count].mv.col = len;
    x->ss[search_site_count].mv.row = -len;
    x->ss[search_site_count].offset = -len * stride + len;
John Koleszar's avatar
John Koleszar committed
175 176 177
    search_site_count++;

    // Compute offsets for search sites.
Dmitry Kovalev's avatar
Dmitry Kovalev committed
178 179 180
    x->ss[search_site_count].mv.col = -len;
    x->ss[search_site_count].mv.row = len;
    x->ss[search_site_count].offset = len * stride - len;
John Koleszar's avatar
John Koleszar committed
181 182 183
    search_site_count++;

    // Compute offsets for search sites.
Dmitry Kovalev's avatar
Dmitry Kovalev committed
184 185 186
    x->ss[search_site_count].mv.col = len;
    x->ss[search_site_count].mv.row = len;
    x->ss[search_site_count].offset = len * stride + len;
John Koleszar's avatar
John Koleszar committed
187 188 189 190 191
    search_site_count++;
  }

  x->ss_count = search_site_count;
  x->searches_per_step = 8;
John Koleszar's avatar
John Koleszar committed
192 193
}

194 195 196 197 198 199 200 201 202
/*
 * To avoid the penalty for crossing cache-line read, preload the reference
 * area in a small buffer, which is aligned to make sure there won't be crossing
 * cache-line read while reading from this buffer. This reduced the cpu
 * cycles spent on reading ref data in sub-pixel filter functions.
 * TODO: Currently, since sub-pixel search range here is -3 ~ 3, copy 22 rows x
 * 32 cols area that is enough for 16x16 macroblock. Later, for SPLITMV, we
 * could reduce the area.
 */
203

204
/* estimated cost of a motion vector (r,c) */
205 206 207 208
#define MVC(r, c)                                       \
    (mvcost ?                                           \
     ((mvjcost[((r) != rr) * 2 + ((c) != rc)] +         \
       mvcost[0][((r) - rr)] + mvcost[1][((c) - rc)]) * \
209 210
      error_per_bit + 4096) >> 13 : 0)

211

212 213
#define SP(x) (((x) & 7) << 1)  // convert motion vector component to offset
                                // for svf calc
214

215 216 217 218 219
#define IFMVCV(r, c, s, e)                                \
    if (c >= minc && c <= maxc && r >= minr && r <= maxr) \
      s                                                   \
    else                                                  \
      e;
220 221

/* pointer to predictor base of a motionvector */
222
#define PRE(r, c) (y + (((r) >> 3) * y_stride + ((c) >> 3) -(offset)))
223

224
/* returns subpixel variance error function */
225
#define DIST(r, c) \
John Koleszar's avatar
John Koleszar committed
226
    vfp->svf(PRE(r, c), y_stride, SP(c), SP(r), z, src_stride, &sse)
227 228 229 230 231 232 233 234 235 236 237 238 239 240

/* checks if (r, c) has better score than previous best */
#define CHECK_BETTER(v, r, c) \
    IFMVCV(r, c, {                                                       \
      thismse = (DIST(r, c));                                            \
      if ((v = MVC(r, c) + thismse) < besterr) {                         \
        besterr = v;                                                     \
        br = r;                                                          \
        bc = c;                                                          \
        *distortion = thismse;                                           \
        *sse1 = sse;                                                     \
      }                                                                  \
    },                                                                   \
    v = INT_MAX;)
241

John Koleszar's avatar
John Koleszar committed
242
int vp9_find_best_sub_pixel_step_iteratively(MACROBLOCK *x,
Scott LaVarnway's avatar
Scott LaVarnway committed
243 244
                                             int_mv *bestmv, int_mv *ref_mv,
                                             int error_per_bit,
245
                                             const vp9_variance_fn_ptr_t *vfp,
246
                                             int *mvjcost, int *mvcost[2],
247
                                             int *distortion,
John Koleszar's avatar
John Koleszar committed
248
                                             unsigned int *sse1) {
John Koleszar's avatar
John Koleszar committed
249 250
  uint8_t *z = x->plane[0].src.buf;
  int src_stride = x->plane[0].src.stride;
John Koleszar's avatar
John Koleszar committed
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265
  MACROBLOCKD *xd = &x->e_mbd;

  int rr, rc, br, bc, hstep;
  int tr, tc;
  unsigned int besterr = INT_MAX;
  unsigned int left, right, up, down, diag;
  unsigned int sse;
  unsigned int whichdir;
  unsigned int halfiters = 4;
  unsigned int quarteriters = 4;
  unsigned int eighthiters = 4;
  int thismse;
  int maxc, minc, maxr, minr;
  int y_stride;
  int offset;
266
  int usehp = xd->allow_high_precision_mv;
John Koleszar's avatar
John Koleszar committed
267

268 269 270 271 272
  uint8_t *y = xd->plane[0].pre[0].buf +
               (bestmv->as_mv.row) * xd->plane[0].pre[0].stride +
               bestmv->as_mv.col;

  y_stride = xd->plane[0].pre[0].stride;
273

274 275 276 277 278 279 280 281 282
  rr = ref_mv->as_mv.row;
  rc = ref_mv->as_mv.col;
  br = bestmv->as_mv.row << 3;
  bc = bestmv->as_mv.col << 3;
  hstep = 4;
  minc = MAX(x->mv_col_min << 3, (ref_mv->as_mv.col) - ((1 << MV_MAX_BITS) - 1));
  maxc = MIN(x->mv_col_max << 3, (ref_mv->as_mv.col) + ((1 << MV_MAX_BITS) - 1));
  minr = MAX(x->mv_row_min << 3, (ref_mv->as_mv.row) - ((1 << MV_MAX_BITS) - 1));
  maxr = MIN(x->mv_row_max << 3, (ref_mv->as_mv.row) + ((1 << MV_MAX_BITS) - 1));
John Koleszar's avatar
John Koleszar committed
283 284 285 286 287 288 289 290 291 292 293 294

  tr = br;
  tc = bc;


  offset = (bestmv->as_mv.row) * y_stride + bestmv->as_mv.col;

  // central mv
  bestmv->as_mv.row <<= 3;
  bestmv->as_mv.col <<= 3;

  // calculate central point error
John Koleszar's avatar
John Koleszar committed
295
  besterr = vfp->vf(y, y_stride, z, src_stride, sse1);
John Koleszar's avatar
John Koleszar committed
296
  *distortion = besterr;
297
  besterr += mv_err_cost(bestmv, ref_mv, mvjcost, mvcost,
298
                         error_per_bit, xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
299

300 301
  // TODO: Each subsequent iteration checks at least one point in
  // common with the last iteration could be 2 ( if diag selected)
John Koleszar's avatar
John Koleszar committed
302 303 304 305 306 307
  while (--halfiters) {
    // 1/2 pel
    CHECK_BETTER(left, tr, tc - hstep);
    CHECK_BETTER(right, tr, tc + hstep);
    CHECK_BETTER(up, tr - hstep, tc);
    CHECK_BETTER(down, tr + hstep, tc);
308

John Koleszar's avatar
John Koleszar committed
309
    whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
310

John Koleszar's avatar
John Koleszar committed
311 312 313 314 315 316 317 318 319 320 321 322 323 324
    switch (whichdir) {
      case 0:
        CHECK_BETTER(diag, tr - hstep, tc - hstep);
        break;
      case 1:
        CHECK_BETTER(diag, tr - hstep, tc + hstep);
        break;
      case 2:
        CHECK_BETTER(diag, tr + hstep, tc - hstep);
        break;
      case 3:
        CHECK_BETTER(diag, tr + hstep, tc + hstep);
        break;
    }
325

John Koleszar's avatar
John Koleszar committed
326 327 328
    // no reason to check the same one again.
    if (tr == br && tc == bc)
      break;
John Koleszar's avatar
John Koleszar committed
329

John Koleszar's avatar
John Koleszar committed
330 331 332
    tr = br;
    tc = bc;
  }
John Koleszar's avatar
John Koleszar committed
333

334 335
  // TODO: Each subsequent iteration checks at least one point in common with
  // the last iteration could be 2 ( if diag selected) 1/4 pel
John Koleszar's avatar
John Koleszar committed
336 337 338 339 340 341
  hstep >>= 1;
  while (--quarteriters) {
    CHECK_BETTER(left, tr, tc - hstep);
    CHECK_BETTER(right, tr, tc + hstep);
    CHECK_BETTER(up, tr - hstep, tc);
    CHECK_BETTER(down, tr + hstep, tc);
John Koleszar's avatar
John Koleszar committed
342

John Koleszar's avatar
John Koleszar committed
343
    whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
John Koleszar's avatar
John Koleszar committed
344

John Koleszar's avatar
John Koleszar committed
345 346 347 348 349 350 351 352 353 354 355 356 357 358
    switch (whichdir) {
      case 0:
        CHECK_BETTER(diag, tr - hstep, tc - hstep);
        break;
      case 1:
        CHECK_BETTER(diag, tr - hstep, tc + hstep);
        break;
      case 2:
        CHECK_BETTER(diag, tr + hstep, tc - hstep);
        break;
      case 3:
        CHECK_BETTER(diag, tr + hstep, tc + hstep);
        break;
    }
John Koleszar's avatar
John Koleszar committed
359

John Koleszar's avatar
John Koleszar committed
360 361 362
    // no reason to check the same one again.
    if (tr == br && tc == bc)
      break;
John Koleszar's avatar
John Koleszar committed
363

John Koleszar's avatar
John Koleszar committed
364 365 366
    tr = br;
    tc = bc;
  }
John Koleszar's avatar
John Koleszar committed
367

368
  if (xd->allow_high_precision_mv) {
369
    usehp = vp9_use_mv_hp(&ref_mv->as_mv);
370 371 372 373 374
  } else {
    usehp = 0;
  }

  if (usehp) {
375
    hstep >>= 1;
John Koleszar's avatar
John Koleszar committed
376 377 378 379 380
    while (--eighthiters) {
      CHECK_BETTER(left, tr, tc - hstep);
      CHECK_BETTER(right, tr, tc + hstep);
      CHECK_BETTER(up, tr - hstep, tc);
      CHECK_BETTER(down, tr + hstep, tc);
John Koleszar's avatar
John Koleszar committed
381

John Koleszar's avatar
John Koleszar committed
382
      whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
John Koleszar's avatar
John Koleszar committed
383

John Koleszar's avatar
John Koleszar committed
384
      switch (whichdir) {
John Koleszar's avatar
John Koleszar committed
385
        case 0:
John Koleszar's avatar
John Koleszar committed
386 387
          CHECK_BETTER(diag, tr - hstep, tc - hstep);
          break;
John Koleszar's avatar
John Koleszar committed
388
        case 1:
John Koleszar's avatar
John Koleszar committed
389 390
          CHECK_BETTER(diag, tr - hstep, tc + hstep);
          break;
John Koleszar's avatar
John Koleszar committed
391
        case 2:
John Koleszar's avatar
John Koleszar committed
392 393
          CHECK_BETTER(diag, tr + hstep, tc - hstep);
          break;
John Koleszar's avatar
John Koleszar committed
394
        case 3:
John Koleszar's avatar
John Koleszar committed
395 396 397
          CHECK_BETTER(diag, tr + hstep, tc + hstep);
          break;
      }
John Koleszar's avatar
John Koleszar committed
398

John Koleszar's avatar
John Koleszar committed
399 400 401
      // no reason to check the same one again.
      if (tr == br && tc == bc)
        break;
402

John Koleszar's avatar
John Koleszar committed
403 404
      tr = br;
      tc = bc;
405
    }
John Koleszar's avatar
John Koleszar committed
406
  }
407 408
  bestmv->as_mv.row = br;
  bestmv->as_mv.col = bc;
John Koleszar's avatar
John Koleszar committed
409

John Koleszar's avatar
John Koleszar committed
410 411 412
  if ((abs(bestmv->as_mv.col - ref_mv->as_mv.col) > (MAX_FULL_PEL_VAL << 3)) ||
      (abs(bestmv->as_mv.row - ref_mv->as_mv.row) > (MAX_FULL_PEL_VAL << 3)))
    return INT_MAX;
John Koleszar's avatar
John Koleszar committed
413

John Koleszar's avatar
John Koleszar committed
414
  return besterr;
John Koleszar's avatar
John Koleszar committed
415
}
416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449

#undef DIST
/* returns subpixel variance error function */
#define DIST(r, c) \
    vfp->svaf(PRE(r, c), y_stride, SP(c), SP(r), \
              z, src_stride, &sse, second_pred)

int vp9_find_best_sub_pixel_comp(MACROBLOCK *x,
                                 int_mv *bestmv, int_mv *ref_mv,
                                 int error_per_bit,
                                 const vp9_variance_fn_ptr_t *vfp,
                                 int *mvjcost, int *mvcost[2],
                                 int *distortion,
                                 unsigned int *sse1,
                                 const uint8_t *second_pred, int w, int h) {
  uint8_t *z = x->plane[0].src.buf;
  int src_stride = x->plane[0].src.stride;
  MACROBLOCKD *xd = &x->e_mbd;

  int rr, rc, br, bc, hstep;
  int tr, tc;
  unsigned int besterr = INT_MAX;
  unsigned int left, right, up, down, diag;
  unsigned int sse;
  unsigned int whichdir;
  unsigned int halfiters = 4;
  unsigned int quarteriters = 4;
  unsigned int eighthiters = 4;
  int thismse;
  int maxc, minc, maxr, minr;
  int y_stride;
  int offset;
  int usehp = xd->allow_high_precision_mv;

450
  DECLARE_ALIGNED_ARRAY(16, uint8_t, comp_pred, 64 * 64);
451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558
  uint8_t *y = xd->plane[0].pre[0].buf +
               (bestmv->as_mv.row) * xd->plane[0].pre[0].stride +
               bestmv->as_mv.col;

  y_stride = xd->plane[0].pre[0].stride;

  rr = ref_mv->as_mv.row;
  rc = ref_mv->as_mv.col;
  br = bestmv->as_mv.row << 3;
  bc = bestmv->as_mv.col << 3;
  hstep = 4;
  minc = MAX(x->mv_col_min << 3, (ref_mv->as_mv.col) -
             ((1 << MV_MAX_BITS) - 1));
  maxc = MIN(x->mv_col_max << 3, (ref_mv->as_mv.col) +
             ((1 << MV_MAX_BITS) - 1));
  minr = MAX(x->mv_row_min << 3, (ref_mv->as_mv.row) -
             ((1 << MV_MAX_BITS) - 1));
  maxr = MIN(x->mv_row_max << 3, (ref_mv->as_mv.row) +
             ((1 << MV_MAX_BITS) - 1));

  tr = br;
  tc = bc;


  offset = (bestmv->as_mv.row) * y_stride + bestmv->as_mv.col;

  // central mv
  bestmv->as_mv.row <<= 3;
  bestmv->as_mv.col <<= 3;

  // calculate central point error
  // TODO(yunqingwang): central pointer error was already calculated in full-
  // pixel search, and can be passed in this function.
  comp_avg_pred(comp_pred, second_pred, w, h, y, y_stride);
  besterr = vfp->vf(comp_pred, w, z, src_stride, sse1);
  *distortion = besterr;
  besterr += mv_err_cost(bestmv, ref_mv, mvjcost, mvcost,
                         error_per_bit, xd->allow_high_precision_mv);

  // Each subsequent iteration checks at least one point in
  // common with the last iteration could be 2 ( if diag selected)
  while (--halfiters) {
    // 1/2 pel
    CHECK_BETTER(left, tr, tc - hstep);
    CHECK_BETTER(right, tr, tc + hstep);
    CHECK_BETTER(up, tr - hstep, tc);
    CHECK_BETTER(down, tr + hstep, tc);

    whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);

    switch (whichdir) {
      case 0:
        CHECK_BETTER(diag, tr - hstep, tc - hstep);
        break;
      case 1:
        CHECK_BETTER(diag, tr - hstep, tc + hstep);
        break;
      case 2:
        CHECK_BETTER(diag, tr + hstep, tc - hstep);
        break;
      case 3:
        CHECK_BETTER(diag, tr + hstep, tc + hstep);
        break;
    }

    // no reason to check the same one again.
    if (tr == br && tc == bc)
      break;

    tr = br;
    tc = bc;
  }

  // Each subsequent iteration checks at least one point in common with
  // the last iteration could be 2 ( if diag selected) 1/4 pel
  hstep >>= 1;
  while (--quarteriters) {
    CHECK_BETTER(left, tr, tc - hstep);
    CHECK_BETTER(right, tr, tc + hstep);
    CHECK_BETTER(up, tr - hstep, tc);
    CHECK_BETTER(down, tr + hstep, tc);

    whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);

    switch (whichdir) {
      case 0:
        CHECK_BETTER(diag, tr - hstep, tc - hstep);
        break;
      case 1:
        CHECK_BETTER(diag, tr - hstep, tc + hstep);
        break;
      case 2:
        CHECK_BETTER(diag, tr + hstep, tc - hstep);
        break;
      case 3:
        CHECK_BETTER(diag, tr + hstep, tc + hstep);
        break;
    }

    // no reason to check the same one again.
    if (tr == br && tc == bc)
      break;

    tr = br;
    tc = bc;
  }

  if (xd->allow_high_precision_mv) {
559
    usehp = vp9_use_mv_hp(&ref_mv->as_mv);
560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605
  } else {
    usehp = 0;
  }

  if (usehp) {
    hstep >>= 1;
    while (--eighthiters) {
      CHECK_BETTER(left, tr, tc - hstep);
      CHECK_BETTER(right, tr, tc + hstep);
      CHECK_BETTER(up, tr - hstep, tc);
      CHECK_BETTER(down, tr + hstep, tc);

      whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);

      switch (whichdir) {
        case 0:
          CHECK_BETTER(diag, tr - hstep, tc - hstep);
          break;
        case 1:
          CHECK_BETTER(diag, tr - hstep, tc + hstep);
          break;
        case 2:
          CHECK_BETTER(diag, tr + hstep, tc - hstep);
          break;
        case 3:
          CHECK_BETTER(diag, tr + hstep, tc + hstep);
          break;
      }

      // no reason to check the same one again.
      if (tr == br && tc == bc)
        break;

      tr = br;
      tc = bc;
    }
  }
  bestmv->as_mv.row = br;
  bestmv->as_mv.col = bc;

  if ((abs(bestmv->as_mv.col - ref_mv->as_mv.col) > (MAX_FULL_PEL_VAL << 3)) ||
      (abs(bestmv->as_mv.row - ref_mv->as_mv.row) > (MAX_FULL_PEL_VAL << 3)))
    return INT_MAX;

  return besterr;
}
606

607

John Koleszar's avatar
John Koleszar committed
608 609 610
#undef MVC
#undef PRE
#undef DIST
611
#undef IFMVCV
John Koleszar's avatar
John Koleszar committed
612 613 614
#undef CHECK_BETTER
#undef MIN
#undef MAX
615

John Koleszar's avatar
John Koleszar committed
616
int vp9_find_best_sub_pixel_step(MACROBLOCK *x,
Scott LaVarnway's avatar
Scott LaVarnway committed
617 618
                                 int_mv *bestmv, int_mv *ref_mv,
                                 int error_per_bit,
619
                                 const vp9_variance_fn_ptr_t *vfp,
620
                                 int *mvjcost, int *mvcost[2], int *distortion,
John Koleszar's avatar
John Koleszar committed
621 622 623 624 625 626
                                 unsigned int *sse1) {
  int bestmse = INT_MAX;
  int_mv startmv;
  int_mv this_mv;
  int_mv orig_mv;
  int yrow_movedback = 0, ycol_movedback = 0;
John Koleszar's avatar
John Koleszar committed
627 628
  uint8_t *z = x->plane[0].src.buf;
  int src_stride = x->plane[0].src.stride;
John Koleszar's avatar
John Koleszar committed
629 630 631 632 633 634
  int left, right, up, down, diag;
  unsigned int sse;
  int whichdir;
  int thismse;
  int y_stride;
  MACROBLOCKD *xd = &x->e_mbd;
635
  int usehp = xd->allow_high_precision_mv;
636

637 638 639 640
  uint8_t *y = xd->plane[0].pre[0].buf +
               (bestmv->as_mv.row) * xd->plane[0].pre[0].stride +
               bestmv->as_mv.col;
  y_stride = xd->plane[0].pre[0].stride;
John Koleszar's avatar
John Koleszar committed
641

John Koleszar's avatar
John Koleszar committed
642 643 644 645 646
  // central mv
  bestmv->as_mv.row <<= 3;
  bestmv->as_mv.col <<= 3;
  startmv = *bestmv;
  orig_mv = *bestmv;
John Koleszar's avatar
John Koleszar committed
647

John Koleszar's avatar
John Koleszar committed
648
  // calculate central point error
John Koleszar's avatar
John Koleszar committed
649
  bestmse = vfp->vf(y, y_stride, z, src_stride, sse1);
John Koleszar's avatar
John Koleszar committed
650
  *distortion = bestmse;
651
  bestmse += mv_err_cost(bestmv, ref_mv, mvjcost, mvcost, error_per_bit,
652
                         xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
653

John Koleszar's avatar
John Koleszar committed
654 655 656
  // go left then right and check error
  this_mv.as_mv.row = startmv.as_mv.row;
  this_mv.as_mv.col = ((startmv.as_mv.col - 8) | 4);
John Koleszar's avatar
John Koleszar committed
657
  thismse = vfp->svf_halfpix_h(y - 1, y_stride, z, src_stride, &sse);
658
  left = thismse + mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost, error_per_bit,
659
                               xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
660

John Koleszar's avatar
John Koleszar committed
661 662 663 664 665 666
  if (left < bestmse) {
    *bestmv = this_mv;
    bestmse = left;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
667

John Koleszar's avatar
John Koleszar committed
668
  this_mv.as_mv.col += 8;
John Koleszar's avatar
John Koleszar committed
669
  thismse = vfp->svf_halfpix_h(y, y_stride, z, src_stride, &sse);
670 671
  right = thismse + mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost,
                                error_per_bit, xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
672

John Koleszar's avatar
John Koleszar committed
673 674 675 676 677 678 679 680 681 682
  if (right < bestmse) {
    *bestmv = this_mv;
    bestmse = right;
    *distortion = thismse;
    *sse1 = sse;
  }

  // go up then down and check error
  this_mv.as_mv.col = startmv.as_mv.col;
  this_mv.as_mv.row = ((startmv.as_mv.row - 8) | 4);
John Koleszar's avatar
John Koleszar committed
683
  thismse =  vfp->svf_halfpix_v(y - y_stride, y_stride, z, src_stride, &sse);
684
  up = thismse + mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost, error_per_bit,
685
                             xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
686

John Koleszar's avatar
John Koleszar committed
687 688 689 690 691 692
  if (up < bestmse) {
    *bestmv = this_mv;
    bestmse = up;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
693

John Koleszar's avatar
John Koleszar committed
694
  this_mv.as_mv.row += 8;
John Koleszar's avatar
John Koleszar committed
695
  thismse = vfp->svf_halfpix_v(y, y_stride, z, src_stride, &sse);
696
  down = thismse + mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost, error_per_bit,
697
                               xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
698

John Koleszar's avatar
John Koleszar committed
699 700 701 702 703 704
  if (down < bestmse) {
    *bestmv = this_mv;
    bestmse = down;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
705 706


John Koleszar's avatar
John Koleszar committed
707 708 709 710 711
  // now check 1 more diagonal
  whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
  // for(whichdir =0;whichdir<4;whichdir++)
  // {
  this_mv = startmv;
John Koleszar's avatar
John Koleszar committed
712

John Koleszar's avatar
John Koleszar committed
713
  switch (whichdir) {
John Koleszar's avatar
John Koleszar committed
714
    case 0:
John Koleszar's avatar
John Koleszar committed
715 716
      this_mv.as_mv.col = (this_mv.as_mv.col - 8) | 4;
      this_mv.as_mv.row = (this_mv.as_mv.row - 8) | 4;
John Koleszar's avatar
John Koleszar committed
717 718
      thismse = vfp->svf_halfpix_hv(y - 1 - y_stride, y_stride, z, src_stride,
                                    &sse);
John Koleszar's avatar
John Koleszar committed
719
      break;
John Koleszar's avatar
John Koleszar committed
720
    case 1:
John Koleszar's avatar
John Koleszar committed
721 722
      this_mv.as_mv.col += 4;
      this_mv.as_mv.row = (this_mv.as_mv.row - 8) | 4;
John Koleszar's avatar
John Koleszar committed
723 724
      thismse = vfp->svf_halfpix_hv(y - y_stride, y_stride, z, src_stride,
                                    &sse);
John Koleszar's avatar
John Koleszar committed
725
      break;
John Koleszar's avatar
John Koleszar committed
726
    case 2:
John Koleszar's avatar
John Koleszar committed
727 728
      this_mv.as_mv.col = (this_mv.as_mv.col - 8) | 4;
      this_mv.as_mv.row += 4;
John Koleszar's avatar
John Koleszar committed
729
      thismse = vfp->svf_halfpix_hv(y - 1, y_stride, z, src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
730
      break;
John Koleszar's avatar
John Koleszar committed
731
    case 3:
732
    default:
John Koleszar's avatar
John Koleszar committed
733 734
      this_mv.as_mv.col += 4;
      this_mv.as_mv.row += 4;
John Koleszar's avatar
John Koleszar committed
735
      thismse = vfp->svf_halfpix_hv(y, y_stride, z, src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
736 737
      break;
  }
John Koleszar's avatar
John Koleszar committed
738

739
  diag = thismse + mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost, error_per_bit,
740
                               xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
741

John Koleszar's avatar
John Koleszar committed
742 743 744 745 746 747
  if (diag < bestmse) {
    *bestmv = this_mv;
    bestmse = diag;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
748 749 750 751

//  }


John Koleszar's avatar
John Koleszar committed
752 753 754 755 756
  // time to check quarter pels.
  if (bestmv->as_mv.row < startmv.as_mv.row) {
    y -= y_stride;
    yrow_movedback = 1;
  }
John Koleszar's avatar
John Koleszar committed
757

John Koleszar's avatar
John Koleszar committed
758 759 760 761
  if (bestmv->as_mv.col < startmv.as_mv.col) {
    y--;
    ycol_movedback = 1;
  }
John Koleszar's avatar
John Koleszar committed
762

John Koleszar's avatar
John Koleszar committed
763
  startmv = *bestmv;
John Koleszar's avatar
John Koleszar committed
764 765 766



John Koleszar's avatar
John Koleszar committed
767 768
  // go left then right and check error
  this_mv.as_mv.row = startmv.as_mv.row;
John Koleszar's avatar
John Koleszar committed
769

John Koleszar's avatar
John Koleszar committed
770 771
  if (startmv.as_mv.col & 7) {
    this_mv.as_mv.col = startmv.as_mv.col - 2;
772 773
    thismse = vfp->svf(y, y_stride,
                       SP(this_mv.as_mv.col), SP(this_mv.as_mv.row),
John Koleszar's avatar
John Koleszar committed
774
                       z, src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
775 776
  } else {
    this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6;
777
    thismse = vfp->svf(y - 1, y_stride, SP(6), SP(this_mv.as_mv.row), z,
John Koleszar's avatar
John Koleszar committed
778
                       src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
779
  }
John Koleszar's avatar
John Koleszar committed
780

781
  left = thismse + mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost, error_per_bit,
782
                               xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
783

John Koleszar's avatar
John Koleszar committed
784 785 786 787 788 789
  if (left < bestmse) {
    *bestmv = this_mv;
    bestmse = left;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
790

John Koleszar's avatar
John Koleszar committed
791
  this_mv.as_mv.col += 4;
792 793
  thismse = vfp->svf(y, y_stride,
                     SP(this_mv.as_mv.col), SP(this_mv.as_mv.row),
John Koleszar's avatar
John Koleszar committed
794
                     z, src_stride, &sse);
795 796
  right = thismse + mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost,
                                error_per_bit, xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
797

John Koleszar's avatar
John Koleszar committed
798 799 800 801 802 803
  if (right < bestmse) {
    *bestmv = this_mv;
    bestmse = right;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
804

John Koleszar's avatar
John Koleszar committed
805 806
  // go up then down and check error
  this_mv.as_mv.col = startmv.as_mv.col;
John Koleszar's avatar
John Koleszar committed
807

John Koleszar's avatar
John Koleszar committed
808 809
  if (startmv.as_mv.row & 7) {
    this_mv.as_mv.row = startmv.as_mv.row - 2;
810 811
    thismse = vfp->svf(y, y_stride,
                       SP(this_mv.as_mv.col), SP(this_mv.as_mv.row),
John Koleszar's avatar
John Koleszar committed
812
                       z, src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
813 814
  } else {
    this_mv.as_mv.row = (startmv.as_mv.row - 8) | 6;
815
    thismse = vfp->svf(y - y_stride, y_stride, SP(this_mv.as_mv.col), SP(6),
John Koleszar's avatar
John Koleszar committed
816
                       z, src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
817
  }
John Koleszar's avatar
John Koleszar committed
818

819
  up = thismse + mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost, error_per_bit,
820
                             xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
821

John Koleszar's avatar
John Koleszar committed
822 823 824 825 826 827
  if (up < bestmse) {
    *bestmv = this_mv;
    bestmse = up;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
828

John Koleszar's avatar
John Koleszar committed
829
  this_mv.as_mv.row += 4;
830
  thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row),
John Koleszar's avatar
John Koleszar committed
831
                     z, src_stride, &sse);
832
  down = thismse + mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost, error_per_bit,
833
                               xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
834

John Koleszar's avatar
John Koleszar committed
835 836 837 838 839 840
  if (down < bestmse) {
    *bestmv = this_mv;
    bestmse = down;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
841 842


John Koleszar's avatar
John Koleszar committed
843 844
  // now check 1 more diagonal
  whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
John Koleszar's avatar
John Koleszar committed
845 846 847

//  for(whichdir=0;whichdir<4;whichdir++)
//  {
John Koleszar's avatar
John Koleszar committed
848
  this_mv = startmv;
John Koleszar's avatar
John Koleszar committed
849

John Koleszar's avatar
John Koleszar committed
850
  switch (whichdir) {
John Koleszar's avatar
John Koleszar committed
851 852
    case 0:

John Koleszar's avatar
John Koleszar committed
853 854
      if (startmv.as_mv.row & 7) {
        this_mv.as_mv.row -= 2;
John Koleszar's avatar
John Koleszar committed
855

John Koleszar's avatar
John Koleszar committed
856 857
        if (startmv.as_mv.col & 7) {
          this_mv.as_mv.col -= 2;
John Koleszar's avatar
John Koleszar committed
858 859 860
          thismse = vfp->svf(y, y_stride,
                             SP(this_mv.as_mv.col), SP(this_mv.as_mv.row),
                             z, src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
861 862
        } else {
          this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6;
John Koleszar's avatar
John Koleszar committed
863 864
          thismse = vfp->svf(y - 1, y_stride,
                             SP(6), SP(this_mv.as_mv.row), z, src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
865
        }
John Koleszar's avatar
John Koleszar committed
866 867 868 869 870
      } else {
        this_mv.as_mv.row = (startmv.as_mv.row - 8) | 6;

        if (startmv.as_mv.col & 7) {
          this_mv.as_mv.col -= 2;
John Koleszar's avatar
John Koleszar committed
871 872
          thismse = vfp->svf(y - y_stride, y_stride,
                             SP(this_mv.as_mv.col), SP(6), z, src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
873 874
        } else {
          this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6;
John Koleszar's avatar
John Koleszar committed
875 876
          thismse = vfp->svf(y - y_stride - 1, y_stride,
                             SP(6), SP(6), z, src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
877
        }
John Koleszar's avatar
John Koleszar committed
878
      }
John Koleszar's avatar
John Koleszar committed
879

John Koleszar's avatar
John Koleszar committed
880
      break;
John Koleszar's avatar
John Koleszar committed
881
    case 1:
John Koleszar's avatar
John Koleszar committed
882
      this_mv.as_mv.col += 2;
John Koleszar's avatar
John Koleszar committed
883

John Koleszar's avatar
John Koleszar committed
884 885
      if (startmv.as_mv.row & 7) {
        this_mv.as_mv.row -= 2;
John Koleszar's avatar
John Koleszar committed
886 887 888
        thismse = vfp->svf(y, y_stride,
                           SP(this_mv.as_mv.col), SP(this_mv.as_mv.row),
                           z, src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
889 890
      } else {
        this_mv.as_mv.row = (startmv.as_mv.row - 8) | 6;
John Koleszar's avatar
John Koleszar committed
891 892
        thismse = vfp->svf(y - y_stride, y_stride,
                           SP(this_mv.as_mv.col), SP(6), z, src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
893
      }
John Koleszar's avatar
John Koleszar committed
894

John Koleszar's avatar
John Koleszar committed
895
      break;
John Koleszar's avatar
John Koleszar committed
896
    case 2:
John Koleszar's avatar
John Koleszar committed
897
      this_mv.as_mv.row += 2;
John Koleszar's avatar
John Koleszar committed
898

John Koleszar's avatar
John Koleszar committed
899 900
      if (startmv.as_mv.col & 7) {
        this_mv.as_mv.col -= 2;
John Koleszar's avatar
John Koleszar committed
901 902 903
        thismse = vfp->svf(y, y_stride,
                           SP(this_mv.as_mv.col), SP(this_mv.as_mv.row),
                           z, src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
904 905
      } else {
        this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6;
906
        thismse = vfp->svf(y - 1, y_stride, SP(6), SP(this_mv.as_mv.row), z,
John Koleszar's avatar
John Koleszar committed
907
                           src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
908
      }
John Koleszar's avatar
John Koleszar committed
909

John Koleszar's avatar
John Koleszar committed
910
      break;
John Koleszar's avatar
John Koleszar committed
911
    case 3:
John Koleszar's avatar
John Koleszar committed
912 913
      this_mv.as_mv.col += 2;
      this_mv.as_mv.row += 2;
914 915
      thismse = vfp->svf(y, y_stride,
                         SP(this_mv.as_mv.col), SP(this_mv.as_mv.row),
John Koleszar's avatar
John Koleszar committed
916
                         z, src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
917 918
      break;
  }
John Koleszar's avatar
John Koleszar committed
919

920
  diag = thismse + mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost, error_per_bit,
921
                               xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
922

John Koleszar's avatar
John Koleszar committed
923 924 925 926 927 928
  if (diag < bestmse) {
    *bestmv = this_mv;
    bestmse = diag;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
929

930
  if (x->e_mbd.allow_high_precision_mv) {
931
    usehp = vp9_use_mv_hp(&ref_mv->as_mv);
932 933 934 935
  } else {
    usehp = 0;
  }
  if (!usehp)
John Koleszar's avatar
John Koleszar committed
936
    return bestmse;
937

John Koleszar's avatar
John Koleszar committed
938 939 940 941 942
  /* Now do 1/8th pixel */
  if (bestmv->as_mv.row < orig_mv.as_mv<