mcomp.c 68.3 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 11 12 13
 */


#include "mcomp.h"
#include "vpx_mem/vpx_mem.h"
14
#include "vpx_ports/config.h"
John Koleszar's avatar
John Koleszar committed
15 16 17
#include <stdio.h>
#include <limits.h>
#include <math.h>
18
#include "vp8/common/findnearmv.h"
John Koleszar's avatar
John Koleszar committed
19 20 21 22 23 24

#ifdef ENTROPY_STATS
static int mv_ref_ct [31] [4] [2];
static int mv_mode_cts [4] [2];
#endif

25
#if CONFIG_HIGH_PRECISION_MV
John Koleszar's avatar
John Koleszar committed
26 27 28 29 30 31
int vp8_mv_bit_cost(int_mv *mv, int_mv *ref, int *mvcost[2], int Weight, int ishp) {
  // MV costing is based on the distribution of vectors in the previous frame and as such will tend to
  // over state the cost of vectors. In addition coding a new vector can have a knock on effect on the
  // cost of subsequent vectors and the quality of prediction from NEAR and NEAREST for subsequent blocks.
  // The "Weight" parameter allows, to a limited extent, for some account to be taken of these factors.
  return ((mvcost[0][(mv->as_mv.row - ref->as_mv.row) >> (ishp == 0)] + mvcost[1][(mv->as_mv.col - ref->as_mv.col) >> (ishp == 0)]) * Weight) >> 7;
John Koleszar's avatar
John Koleszar committed
32
}
33
#else
John Koleszar's avatar
John Koleszar committed
34 35 36 37 38 39
int vp8_mv_bit_cost(int_mv *mv, int_mv *ref, int *mvcost[2], int Weight) {
  // MV costing is based on the distribution of vectors in the previous frame and as such will tend to
  // over state the cost of vectors. In addition coding a new vector can have a knock on effect on the
  // cost of subsequent vectors and the quality of prediction from NEAR and NEAREST for subsequent blocks.
  // The "Weight" parameter allows, to a limited extent, for some account to be taken of these factors.
  return ((mvcost[0][(mv->as_mv.row - ref->as_mv.row) >> 1] + mvcost[1][(mv->as_mv.col - ref->as_mv.col) >> 1]) * Weight) >> 7;
40 41
}
#endif
John Koleszar's avatar
John Koleszar committed
42

43
#if CONFIG_HIGH_PRECISION_MV
John Koleszar's avatar
John Koleszar committed
44 45 46 47 48 49 50
static int mv_err_cost(int_mv *mv, int_mv *ref, int *mvcost[2], int error_per_bit, int ishp) {
  // Ignore costing if mvcost is NULL
  if (mvcost)
    return ((mvcost[0][(mv->as_mv.row - ref->as_mv.row) >> (ishp == 0)] +
             mvcost[1][(mv->as_mv.col - ref->as_mv.col) >> (ishp == 0)])
            * error_per_bit + 128) >> 8;
  return 0;
51 52
}
#else
John Koleszar's avatar
John Koleszar committed
53 54 55 56 57 58 59
static int mv_err_cost(int_mv *mv, int_mv *ref, int *mvcost[2], int error_per_bit) {
  // Ignore costing if mvcost is NULL
  if (mvcost)
    return ((mvcost[0][(mv->as_mv.row - ref->as_mv.row) >> 1] +
             mvcost[1][(mv->as_mv.col - ref->as_mv.col) >> 1])
            * error_per_bit + 128) >> 8;
  return 0;
John Koleszar's avatar
John Koleszar committed
60
}
61 62
#endif

John Koleszar's avatar
John Koleszar committed
63

John Koleszar's avatar
John Koleszar committed
64 65 66 67 68 69 70 71
static int mvsad_err_cost(int_mv *mv, int_mv *ref, int *mvsadcost[2], int error_per_bit) {
  // Calculate sad error cost on full pixel basis.
  // Ignore costing if mvcost is NULL
  if (mvsadcost)
    return ((mvsadcost[0][(mv->as_mv.row - ref->as_mv.row)] +
             mvsadcost[1][(mv->as_mv.col - ref->as_mv.col)])
            * error_per_bit + 128) >> 8;
  return 0;
John Koleszar's avatar
John Koleszar committed
72 73
}

74

John Koleszar's avatar
John Koleszar committed
75 76 77
void vp8_init_dsmotion_compensation(MACROBLOCK *x, int stride) {
  int Len;
  int search_site_count = 0;
John Koleszar's avatar
John Koleszar committed
78 79


John Koleszar's avatar
John Koleszar committed
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
  // Generate offsets for 4 search sites per step.
  Len = MAX_FIRST_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++;

  while (Len > 0) {

    // Compute offsets for search sites.
    x->ss[search_site_count].mv.col = 0;
    x->ss[search_site_count].mv.row = -Len;
    x->ss[search_site_count].offset = -Len * stride;
    search_site_count++;

    // Compute offsets for search sites.
John Koleszar's avatar
John Koleszar committed
96
    x->ss[search_site_count].mv.col = 0;
John Koleszar's avatar
John Koleszar committed
97 98 99 100 101 102
    x->ss[search_site_count].mv.row = Len;
    x->ss[search_site_count].offset = Len * stride;
    search_site_count++;

    // Compute offsets for search sites.
    x->ss[search_site_count].mv.col = -Len;
John Koleszar's avatar
John Koleszar committed
103
    x->ss[search_site_count].mv.row = 0;
John Koleszar's avatar
John Koleszar committed
104
    x->ss[search_site_count].offset = -Len;
John Koleszar's avatar
John Koleszar committed
105 106
    search_site_count++;

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

John Koleszar's avatar
John Koleszar committed
113 114 115 116 117 118
    // Contract.
    Len /= 2;
  }

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

John Koleszar's avatar
John Koleszar committed
121 122 123 124 125 126 127 128 129 130 131 132
void vp8_init3smotion_compensation(MACROBLOCK *x, int stride) {
  int Len;
  int search_site_count = 0;

  // Generate offsets for 8 search sites per step.
  Len = MAX_FIRST_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++;

  while (Len > 0) {
John Koleszar's avatar
John Koleszar committed
133

John Koleszar's avatar
John Koleszar committed
134
    // Compute offsets for search sites.
John Koleszar's avatar
John Koleszar committed
135
    x->ss[search_site_count].mv.col = 0;
John Koleszar's avatar
John Koleszar committed
136 137 138 139 140 141 142 143 144 145 146 147
    x->ss[search_site_count].mv.row = -Len;
    x->ss[search_site_count].offset = -Len * stride;
    search_site_count++;

    // Compute offsets for search sites.
    x->ss[search_site_count].mv.col = 0;
    x->ss[search_site_count].mv.row = Len;
    x->ss[search_site_count].offset = Len * stride;
    search_site_count++;

    // Compute offsets for search sites.
    x->ss[search_site_count].mv.col = -Len;
John Koleszar's avatar
John Koleszar committed
148
    x->ss[search_site_count].mv.row = 0;
John Koleszar's avatar
John Koleszar committed
149
    x->ss[search_site_count].offset = -Len;
John Koleszar's avatar
John Koleszar committed
150 151
    search_site_count++;

John Koleszar's avatar
John Koleszar committed
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
    // Compute offsets for search sites.
    x->ss[search_site_count].mv.col = Len;
    x->ss[search_site_count].mv.row = 0;
    x->ss[search_site_count].offset = Len;
    search_site_count++;

    // Compute offsets for search sites.
    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;
    search_site_count++;

    // Compute offsets for search sites.
    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;
    search_site_count++;

    // Compute offsets for search sites.
    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;
    search_site_count++;

    // Compute offsets for search sites.
    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;
    search_site_count++;
John Koleszar's avatar
John Koleszar committed
181

John Koleszar's avatar
John Koleszar committed
182 183 184 185 186 187 188

    // Contract.
    Len /= 2;
  }

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

191 192 193 194 195 196 197 198 199
/*
 * 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.
 */
200

201
#define PRE(r,c) (y + (((r)>>2) * y_stride + ((c)>>2) -(offset))) // pointer to predictor base of a motionvector
202 203 204
#if CONFIG_SIXTEENTH_SUBPEL_UV
#define SP(x) (((x)&3)<<2) // convert motion vector component to offset for svf calc
#else
John Koleszar's avatar
John Koleszar committed
205
#define SP(x) (((x)&3)<<1) // convert motion vector component to offset for svf calc
206
#endif  /* CONFIG_SIXTEENTH_SUBPEL_UV */
207
#define MVC(r,c) (mvcost ? ((mvcost[0][(r)-rr] + mvcost[1][(c)-rc]) * error_per_bit + 128 )>>8 : 0) // estimated cost of a motion vector (r,c)
208
#define DIST(r,c) vfp->svf( PRE(r,c), y_stride, SP(c),SP(r), z,b->src_stride,&sse) // returns subpixel variance error function.
John Koleszar's avatar
John Koleszar committed
209
#define ERR(r,c) (MVC(r,c)+DIST(r,c)) // returns distortion + motion vector cost
210 211 212 213 214 215 216 217 218 219 220 221 222
#define IFMVCV(r,c,s,e) if ( c >= minc && c <= maxc && r >= minr && r <= maxr) s else e;

#if CONFIG_HIGH_PRECISION_MV
#define PREHP(r,c) (y + (((r)>>3) * y_stride + ((c)>>3) -(offset))) // pointer to predictor base of a motionvector
#if CONFIG_SIXTEENTH_SUBPEL_UV
#define SPHP(x) (((x)&7)<<1) // convert motion vector component to offset for svf calc
#else /* CONFIG_SIXTEENTH_SUBPEL_UV */
#define SPHP(x) ((x)&7) // convert motion vector component to offset for svf calc
#endif  /* CONFIG_SIXTEENTH_SUBPEL_UV */
#define DISTHP(r,c) vfp->svf( PREHP(r,c), y_stride, SPHP(c),SPHP(r), z,b->src_stride,&sse) // returns subpixel variance error function.
#define ERRHP(r,c) (MVC(r,c)+DISTHP(r,c)) // returns distortion + motion vector cost
#define CHECK_BETTER(v,r,c) IFMVCV(r,c,{thismse = ((xd->allow_high_precision_mv)?DISTHP(r,c):DIST(r,c)); if((v = (MVC(r,c)+thismse)) < besterr) { besterr = v; br=r; bc=c; *distortion = thismse; *sse1 = sse; }}, v=INT_MAX;)// checks if (r,c) has better score than previous best
#else
223
#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;)// checks if (r,c) has better score than previous best
224
#endif /* CONFIG_HIGH_PRECISION_MV */
225

John Koleszar's avatar
John Koleszar committed
226 227 228
#define MIN(x,y) (((x)<(y))?(x):(y))
#define MAX(x,y) (((x)>(y))?(x):(y))

Scott LaVarnway's avatar
Scott LaVarnway committed
229 230 231 232 233
int vp8_find_best_sub_pixel_step_iteratively(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
                                             int_mv *bestmv, int_mv *ref_mv,
                                             int error_per_bit,
                                             const vp8_variance_fn_ptr_t *vfp,
                                             int *mvcost[2], int *distortion,
John Koleszar's avatar
John Koleszar committed
234 235 236 237 238 239 240 241 242 243 244 245
                                             unsigned int *sse1) {
  unsigned char *z = (*(b->base_src) + b->src);
  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;
246
#if CONFIG_HIGH_PRECISION_MV
John Koleszar's avatar
John Koleszar committed
247
  unsigned int eighthiters = 4;
248
#endif
John Koleszar's avatar
John Koleszar committed
249 250 251 252
  int thismse;
  int maxc, minc, maxr, minr;
  int y_stride;
  int offset;
John Koleszar's avatar
John Koleszar committed
253

254
#if ARCH_X86 || ARCH_X86_64
John Koleszar's avatar
John Koleszar committed
255 256 257 258 259
  unsigned char *y0 = *(d->base_pre) + d->pre + (bestmv->as_mv.row) * d->pre_stride + bestmv->as_mv.col;
  unsigned char *y;
  int buf_r1, buf_r2, buf_c1, buf_c2;

  // Clamping to avoid out-of-range data access
260 261 262 263 264 265 266 267
  buf_r1 = ((bestmv->as_mv.row - INTERP_EXTEND) < x->mv_row_min) ?
      (bestmv->as_mv.row - x->mv_row_min) : INTERP_EXTEND - 1;
  buf_r2 = ((bestmv->as_mv.row + INTERP_EXTEND) > x->mv_row_max) ?
      (x->mv_row_max - bestmv->as_mv.row) : INTERP_EXTEND - 1;
  buf_c1 = ((bestmv->as_mv.col - INTERP_EXTEND) < x->mv_col_min) ?
      (bestmv->as_mv.col - x->mv_col_min) : INTERP_EXTEND - 1;
  buf_c2 = ((bestmv->as_mv.col + INTERP_EXTEND) > x->mv_col_max) ?
      (x->mv_col_max - bestmv->as_mv.col) : INTERP_EXTEND - 1;
John Koleszar's avatar
John Koleszar committed
268 269 270 271 272
  y_stride = 32;

  /* Copy to intermediate buffer before searching. */
  vfp->copymem(y0 - buf_c1 - d->pre_stride * buf_r1, d->pre_stride, xd->y_buf, y_stride, 16 + buf_r1 + buf_r2);
  y = xd->y_buf + y_stride * buf_r1 + buf_c1;
273
#else
John Koleszar's avatar
John Koleszar committed
274 275
  unsigned char *y = *(d->base_pre) + d->pre + (bestmv->as_mv.row) * d->pre_stride + bestmv->as_mv.col;
  y_stride = d->pre_stride;
276 277 278
#endif


279
#if CONFIG_HIGH_PRECISION_MV
John Koleszar's avatar
John Koleszar committed
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320
  if (xd->allow_high_precision_mv) {
    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 << mvlong_width_hp) - 1));
    maxc = MIN(x->mv_col_max << 3, (ref_mv->as_mv.col) + ((1 << mvlong_width_hp) - 1));
    minr = MAX(x->mv_row_min << 3, (ref_mv->as_mv.row) - ((1 << mvlong_width_hp) - 1));
    maxr = MIN(x->mv_row_max << 3, (ref_mv->as_mv.row) + ((1 << mvlong_width_hp) - 1));
  } else
#endif
  {
    rr = ref_mv->as_mv.row >> 1;
    rc = ref_mv->as_mv.col >> 1;
    br = bestmv->as_mv.row << 2;
    bc = bestmv->as_mv.col << 2;
    hstep = 2;
    minc = MAX(x->mv_col_min << 2, (ref_mv->as_mv.col >> 1) - ((1 << mvlong_width) - 1));
    maxc = MIN(x->mv_col_max << 2, (ref_mv->as_mv.col >> 1) + ((1 << mvlong_width) - 1));
    minr = MAX(x->mv_row_min << 2, (ref_mv->as_mv.row >> 1) - ((1 << mvlong_width) - 1));
    maxr = MIN(x->mv_row_max << 2, (ref_mv->as_mv.row >> 1) + ((1 << mvlong_width) - 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
  besterr = vfp->vf(y, y_stride, z, b->src_stride, sse1);
  *distortion = besterr;
#if CONFIG_HIGH_PRECISION_MV
  besterr += mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);
#else
  besterr += mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit);
321
#endif
John Koleszar's avatar
John Koleszar committed
322

John Koleszar's avatar
John Koleszar committed
323 324 325 326 327 328 329
  // TODO: 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);
330

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

John Koleszar's avatar
John Koleszar committed
333 334 335 336 337 338 339 340 341 342 343 344 345 346
    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;
    }
347

John Koleszar's avatar
John Koleszar committed
348 349 350
    // no reason to check the same one again.
    if (tr == br && tc == bc)
      break;
John Koleszar's avatar
John Koleszar committed
351

John Koleszar's avatar
John Koleszar committed
352 353 354
    tr = br;
    tc = bc;
  }
John Koleszar's avatar
John Koleszar committed
355

John Koleszar's avatar
John Koleszar committed
356 357 358 359 360 361 362 363
  // TODO: 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);
John Koleszar's avatar
John Koleszar committed
364

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

John Koleszar's avatar
John Koleszar committed
367 368 369 370 371 372 373 374 375 376 377 378 379 380
    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
381

John Koleszar's avatar
John Koleszar committed
382 383 384
    // no reason to check the same one again.
    if (tr == br && tc == bc)
      break;
John Koleszar's avatar
John Koleszar committed
385

John Koleszar's avatar
John Koleszar committed
386 387 388
    tr = br;
    tc = bc;
  }
John Koleszar's avatar
John Koleszar committed
389

John Koleszar's avatar
John Koleszar committed
390 391
#if CONFIG_HIGH_PRECISION_MV
  if (x->e_mbd.allow_high_precision_mv) {
392
    hstep >>= 1;
John Koleszar's avatar
John Koleszar committed
393 394 395 396 397
    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
398

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

John Koleszar's avatar
John Koleszar committed
401
      switch (whichdir) {
John Koleszar's avatar
John Koleszar committed
402
        case 0:
John Koleszar's avatar
John Koleszar committed
403 404
          CHECK_BETTER(diag, tr - hstep, tc - hstep);
          break;
John Koleszar's avatar
John Koleszar committed
405
        case 1:
John Koleszar's avatar
John Koleszar committed
406 407
          CHECK_BETTER(diag, tr - hstep, tc + hstep);
          break;
John Koleszar's avatar
John Koleszar committed
408
        case 2:
John Koleszar's avatar
John Koleszar committed
409 410
          CHECK_BETTER(diag, tr + hstep, tc - hstep);
          break;
John Koleszar's avatar
John Koleszar committed
411
        case 3:
John Koleszar's avatar
John Koleszar committed
412 413 414
          CHECK_BETTER(diag, tr + hstep, tc + hstep);
          break;
      }
John Koleszar's avatar
John Koleszar committed
415

John Koleszar's avatar
John Koleszar committed
416 417 418
      // no reason to check the same one again.
      if (tr == br && tc == bc)
        break;
419

John Koleszar's avatar
John Koleszar committed
420 421
      tr = br;
      tc = bc;
422
    }
John Koleszar's avatar
John Koleszar committed
423
  }
424 425
#endif
#if CONFIG_HIGH_PRECISION_MV
John Koleszar's avatar
John Koleszar committed
426 427 428 429
  if (x->e_mbd.allow_high_precision_mv) {
    bestmv->as_mv.row = br;
    bestmv->as_mv.col = bc;
  } else
430
#endif  /* CONFIG_HIGH_PRECISION_MV */
John Koleszar's avatar
John Koleszar committed
431 432 433 434
  {
    bestmv->as_mv.row = br << 1;
    bestmv->as_mv.col = bc << 1;
  }
John Koleszar's avatar
John Koleszar committed
435

John Koleszar's avatar
John Koleszar committed
436 437 438
  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
439

John Koleszar's avatar
John Koleszar committed
440
  return besterr;
John Koleszar's avatar
John Koleszar committed
441 442 443 444 445
}
#undef MVC
#undef PRE
#undef SP
#undef DIST
446
#undef IFMVCV
John Koleszar's avatar
John Koleszar committed
447 448 449 450
#undef ERR
#undef CHECK_BETTER
#undef MIN
#undef MAX
451

452 453 454 455 456 457 458
#if CONFIG_HIGH_PRECISION_MV
#undef PREHP
#undef DPHP
#undef DISTHP
#undef ERRHP
#endif

459 460 461 462
#if CONFIG_SIXTEENTH_SUBPEL_UV
#define SP(x) (((x)&7)<<1) // convert motion vector component to offset for svf calc
#else
#define SP(x) ((x)&7) // convert motion vector component to offset for svf calc
463
#endif  /* CONFIG_SIXTEENTH_SUBPEL_UV */
Scott LaVarnway's avatar
Scott LaVarnway committed
464 465 466 467 468
int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
                                 int_mv *bestmv, int_mv *ref_mv,
                                 int error_per_bit,
                                 const vp8_variance_fn_ptr_t *vfp,
                                 int *mvcost[2], int *distortion,
John Koleszar's avatar
John Koleszar committed
469 470 471 472
                                 unsigned int *sse1) {
  int bestmse = INT_MAX;
  int_mv startmv;
  int_mv this_mv;
473
#if CONFIG_HIGH_PRECISION_MV
John Koleszar's avatar
John Koleszar committed
474 475
  int_mv orig_mv;
  int yrow_movedback = 0, ycol_movedback = 0;
476
#endif
John Koleszar's avatar
John Koleszar committed
477 478 479 480 481 482 483
  unsigned char *z = (*(b->base_src) + b->src);
  int left, right, up, down, diag;
  unsigned int sse;
  int whichdir;
  int thismse;
  int y_stride;
  MACROBLOCKD *xd = &x->e_mbd;
484 485

#if ARCH_X86 || ARCH_X86_64
John Koleszar's avatar
John Koleszar committed
486 487
  unsigned char *y0 = *(d->base_pre) + d->pre + (bestmv->as_mv.row) * d->pre_stride + bestmv->as_mv.col;
  unsigned char *y;
488

John Koleszar's avatar
John Koleszar committed
489 490 491 492
  y_stride = 32;
  /* Copy 18 rows x 32 cols area to intermediate buffer before searching. */
  vfp->copymem(y0 - 1 - d->pre_stride, d->pre_stride, xd->y_buf, y_stride, 18);
  y = xd->y_buf + y_stride + 1;
493
#else
John Koleszar's avatar
John Koleszar committed
494 495
  unsigned char *y = *(d->base_pre) + d->pre + (bestmv->as_mv.row) * d->pre_stride + bestmv->as_mv.col;
  y_stride = d->pre_stride;
496
#endif
John Koleszar's avatar
John Koleszar committed
497

John Koleszar's avatar
John Koleszar committed
498 499 500 501
  // central mv
  bestmv->as_mv.row <<= 3;
  bestmv->as_mv.col <<= 3;
  startmv = *bestmv;
502
#if CONFIG_HIGH_PRECISION_MV
John Koleszar's avatar
John Koleszar committed
503
  orig_mv = *bestmv;
504
#endif
John Koleszar's avatar
John Koleszar committed
505

John Koleszar's avatar
John Koleszar committed
506 507 508
  // calculate central point error
  bestmse = vfp->vf(y, y_stride, z, b->src_stride, sse1);
  *distortion = bestmse;
509
#if CONFIG_HIGH_PRECISION_MV
John Koleszar's avatar
John Koleszar committed
510
  bestmse += mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);
511
#else
John Koleszar's avatar
John Koleszar committed
512
  bestmse += mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit);
513
#endif
John Koleszar's avatar
John Koleszar committed
514

John Koleszar's avatar
John Koleszar committed
515 516 517 518
  // 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);
  thismse = vfp->svf_halfpix_h(y - 1, y_stride, z, b->src_stride, &sse);
519
#if CONFIG_HIGH_PRECISION_MV
John Koleszar's avatar
John Koleszar committed
520
  left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);
521
#else
John Koleszar's avatar
John Koleszar committed
522
  left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
523
#endif
John Koleszar's avatar
John Koleszar committed
524

John Koleszar's avatar
John Koleszar committed
525 526 527 528 529 530
  if (left < bestmse) {
    *bestmv = this_mv;
    bestmse = left;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
531

John Koleszar's avatar
John Koleszar committed
532 533
  this_mv.as_mv.col += 8;
  thismse = vfp->svf_halfpix_h(y, y_stride, z, b->src_stride, &sse);
534
#if CONFIG_HIGH_PRECISION_MV
John Koleszar's avatar
John Koleszar committed
535
  right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);
536
#else
John Koleszar's avatar
John Koleszar committed
537
  right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
538
#endif
John Koleszar's avatar
John Koleszar committed
539

John Koleszar's avatar
John Koleszar committed
540 541 542 543 544 545 546 547 548 549 550
  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);
  thismse =  vfp->svf_halfpix_v(y - y_stride, y_stride, z, b->src_stride, &sse);
551
#if CONFIG_HIGH_PRECISION_MV
John Koleszar's avatar
John Koleszar committed
552
  up = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);
553
#else
John Koleszar's avatar
John Koleszar committed
554
  up = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
555
#endif
John Koleszar's avatar
John Koleszar committed
556

John Koleszar's avatar
John Koleszar committed
557 558 559 560 561 562
  if (up < bestmse) {
    *bestmv = this_mv;
    bestmse = up;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
563

John Koleszar's avatar
John Koleszar committed
564 565
  this_mv.as_mv.row += 8;
  thismse = vfp->svf_halfpix_v(y, y_stride, z, b->src_stride, &sse);
566
#if CONFIG_HIGH_PRECISION_MV
John Koleszar's avatar
John Koleszar committed
567
  down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);
568
#else
John Koleszar's avatar
John Koleszar committed
569
  down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
570
#endif
John Koleszar's avatar
John Koleszar committed
571

John Koleszar's avatar
John Koleszar committed
572 573 574 575 576 577
  if (down < bestmse) {
    *bestmv = this_mv;
    bestmse = down;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
578 579


John Koleszar's avatar
John Koleszar committed
580 581 582 583 584
  // 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
585

John Koleszar's avatar
John Koleszar committed
586
  switch (whichdir) {
John Koleszar's avatar
John Koleszar committed
587
    case 0:
John Koleszar's avatar
John Koleszar committed
588 589 590 591
      this_mv.as_mv.col = (this_mv.as_mv.col - 8) | 4;
      this_mv.as_mv.row = (this_mv.as_mv.row - 8) | 4;
      thismse = vfp->svf_halfpix_hv(y - 1 - y_stride, y_stride, z, b->src_stride, &sse);
      break;
John Koleszar's avatar
John Koleszar committed
592
    case 1:
John Koleszar's avatar
John Koleszar committed
593 594 595 596
      this_mv.as_mv.col += 4;
      this_mv.as_mv.row = (this_mv.as_mv.row - 8) | 4;
      thismse = vfp->svf_halfpix_hv(y - y_stride, y_stride, z, b->src_stride, &sse);
      break;
John Koleszar's avatar
John Koleszar committed
597
    case 2:
John Koleszar's avatar
John Koleszar committed
598 599 600 601
      this_mv.as_mv.col = (this_mv.as_mv.col - 8) | 4;
      this_mv.as_mv.row += 4;
      thismse = vfp->svf_halfpix_hv(y - 1, y_stride, z, b->src_stride, &sse);
      break;
John Koleszar's avatar
John Koleszar committed
602
    case 3:
603
    default:
John Koleszar's avatar
John Koleszar committed
604 605 606 607 608
      this_mv.as_mv.col += 4;
      this_mv.as_mv.row += 4;
      thismse = vfp->svf_halfpix_hv(y, y_stride, z, b->src_stride, &sse);
      break;
  }
John Koleszar's avatar
John Koleszar committed
609

610
#if CONFIG_HIGH_PRECISION_MV
John Koleszar's avatar
John Koleszar committed
611
  diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);
612
#else
John Koleszar's avatar
John Koleszar committed
613
  diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
614
#endif
John Koleszar's avatar
John Koleszar committed
615

John Koleszar's avatar
John Koleszar committed
616 617 618 619 620 621
  if (diag < bestmse) {
    *bestmv = this_mv;
    bestmse = diag;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
622 623 624 625

//  }


John Koleszar's avatar
John Koleszar committed
626 627 628
  // time to check quarter pels.
  if (bestmv->as_mv.row < startmv.as_mv.row) {
    y -= y_stride;
629
#if CONFIG_HIGH_PRECISION_MV
John Koleszar's avatar
John Koleszar committed
630
    yrow_movedback = 1;
631
#endif
John Koleszar's avatar
John Koleszar committed
632
  }
John Koleszar's avatar
John Koleszar committed
633

John Koleszar's avatar
John Koleszar committed
634 635
  if (bestmv->as_mv.col < startmv.as_mv.col) {
    y--;
636
#if CONFIG_HIGH_PRECISION_MV
John Koleszar's avatar
John Koleszar committed
637
    ycol_movedback = 1;
638
#endif
John Koleszar's avatar
John Koleszar committed
639
  }
John Koleszar's avatar
John Koleszar committed
640

John Koleszar's avatar
John Koleszar committed
641
  startmv = *bestmv;
John Koleszar's avatar
John Koleszar committed
642 643 644



John Koleszar's avatar
John Koleszar committed
645 646
  // go left then right and check error
  this_mv.as_mv.row = startmv.as_mv.row;
John Koleszar's avatar
John Koleszar committed
647

John Koleszar's avatar
John Koleszar committed
648 649 650 651 652 653 654
  if (startmv.as_mv.col & 7) {
    this_mv.as_mv.col = startmv.as_mv.col - 2;
    thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
  } else {
    this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6;
    thismse = vfp->svf(y - 1, y_stride, SP(6), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
  }
John Koleszar's avatar
John Koleszar committed
655

656
#if CONFIG_HIGH_PRECISION_MV
John Koleszar's avatar
John Koleszar committed
657
  left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);
658
#else
John Koleszar's avatar
John Koleszar committed
659
  left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
660
#endif
John Koleszar's avatar
John Koleszar committed
661

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

John Koleszar's avatar
John Koleszar committed
669 670
  this_mv.as_mv.col += 4;
  thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
671
#if CONFIG_HIGH_PRECISION_MV
John Koleszar's avatar
John Koleszar committed
672
  right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);
673
#else
John Koleszar's avatar
John Koleszar committed
674
  right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
675
#endif
John Koleszar's avatar
John Koleszar committed
676

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

John Koleszar's avatar
John Koleszar committed
684 685
  // go up then down and check error
  this_mv.as_mv.col = startmv.as_mv.col;
John Koleszar's avatar
John Koleszar committed
686

John Koleszar's avatar
John Koleszar committed
687 688 689 690 691 692 693
  if (startmv.as_mv.row & 7) {
    this_mv.as_mv.row = startmv.as_mv.row - 2;
    thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
  } else {
    this_mv.as_mv.row = (startmv.as_mv.row - 8) | 6;
    thismse = vfp->svf(y - y_stride, y_stride, SP(this_mv.as_mv.col), SP(6), z, b->src_stride, &sse);
  }
John Koleszar's avatar
John Koleszar committed
694

695
#if CONFIG_HIGH_PRECISION_MV
John Koleszar's avatar
John Koleszar committed
696
  up = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);
697
#else
John Koleszar's avatar
John Koleszar committed
698
  up = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
699
#endif
John Koleszar's avatar
John Koleszar committed
700

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

John Koleszar's avatar
John Koleszar committed
708 709
  this_mv.as_mv.row += 4;
  thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
710
#if CONFIG_HIGH_PRECISION_MV
John Koleszar's avatar
John Koleszar committed
711
  down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);
712
#else
John Koleszar's avatar
John Koleszar committed
713
  down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
714
#endif
John Koleszar's avatar
John Koleszar committed
715

John Koleszar's avatar
John Koleszar committed
716 717 718 719 720 721
  if (down < bestmse) {
    *bestmv = this_mv;
    bestmse = down;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
722 723


John Koleszar's avatar
John Koleszar committed
724 725
  // now check 1 more diagonal
  whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
John Koleszar's avatar
John Koleszar committed
726 727 728

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

John Koleszar's avatar
John Koleszar committed
731
  switch (whichdir) {
John Koleszar's avatar
John Koleszar committed
732 733
    case 0:

John Koleszar's avatar
John Koleszar committed
734 735
      if (startmv.as_mv.row & 7) {
        this_mv.as_mv.row -= 2;
John Koleszar's avatar
John Koleszar committed
736

John Koleszar's avatar
John Koleszar committed
737 738 739 740 741 742
        if (startmv.as_mv.col & 7) {
          this_mv.as_mv.col -= 2;
          thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
        } else {
          this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6;
          thismse = vfp->svf(y - 1, y_stride, SP(6), SP(this_mv.as_mv.row), z, b->src_stride, &sse);;
John Koleszar's avatar
John Koleszar committed
743
        }
John Koleszar's avatar
John Koleszar committed
744 745 746 747 748 749 750 751 752
      } else {
        this_mv.as_mv.row = (startmv.as_mv.row - 8) | 6;

        if (startmv.as_mv.col & 7) {
          this_mv.as_mv.col -= 2;
          thismse = vfp->svf(y - y_stride, y_stride, SP(this_mv.as_mv.col), SP(6), z, b->src_stride, &sse);
        } else {
          this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6;
          thismse = vfp->svf(y - y_stride - 1, y_stride, SP(6), SP(6), z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
753
        }
John Koleszar's avatar
John Koleszar committed
754
      }
John Koleszar's avatar
John Koleszar committed
755

John Koleszar's avatar
John Koleszar committed
756
      break;
John Koleszar's avatar
John Koleszar committed
757
    case 1:
John Koleszar's avatar
John Koleszar committed
758
      this_mv.as_mv.col += 2;
John Koleszar's avatar
John Koleszar committed
759

John Koleszar's avatar
John Koleszar committed
760 761 762 763 764 765 766
      if (startmv.as_mv.row & 7) {
        this_mv.as_mv.row -= 2;
        thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
      } else {
        this_mv.as_mv.row = (startmv.as_mv.row - 8) | 6;
        thismse = vfp->svf(y - y_stride, y_stride, SP(this_mv.as_mv.col), SP(6), z, b->src_stride, &sse);
      }
John Koleszar's avatar
John Koleszar committed
767

John Koleszar's avatar
John Koleszar committed
768
      break;
John Koleszar's avatar
John Koleszar committed
769
    case 2:
John Koleszar's avatar
John Koleszar committed
770
      this_mv.as_mv.row += 2;
John Koleszar's avatar
John Koleszar committed
771

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

John Koleszar's avatar
John Koleszar committed
780
      break;
John Koleszar's avatar
John Koleszar committed
781
    case 3:
John Koleszar's avatar
John Koleszar committed
782 783 784 785 786
      this_mv.as_mv.col += 2;
      this_mv.as_mv.row += 2;
      thismse = vfp->svf(y, y_stride,  SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
      break;
  }
John Koleszar's avatar
John Koleszar committed
787

788
#if CONFIG_HIGH_PRECISION_MV
John Koleszar's avatar
John Koleszar committed
789
  diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);
790
#else
John Koleszar's avatar
John Koleszar committed
791
  diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
792
#endif
John Koleszar's avatar
John Koleszar committed
793

John Koleszar's avatar
John Koleszar committed
794 795 796 797 798 799
  if (diag < bestmse) {
    *bestmv = this_mv;
    bestmse = diag;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
800

801
#if CONFIG_HIGH_PRECISION_MV
John Koleszar's avatar
John Koleszar committed
802 803
  if (!x->e_mbd.allow_high_precision_mv)
    return bestmse;
804

John Koleszar's avatar
John Koleszar committed
805 806 807 808 809
  /* Now do 1/8th pixel */
  if (bestmv->as_mv.row < orig_mv.as_mv.row && !yrow_movedback) {
    y -= y_stride;
    yrow_movedback = 1;
  }
810

John Koleszar's avatar
John Koleszar committed
811 812 813 814
  if (bestmv->as_mv.col < orig_mv.as_mv.col && !ycol_movedback) {
    y--;
    ycol_movedback = 1;
  }
815

John Koleszar's avatar
John Koleszar committed
816
  startmv = *bestmv;
817

John Koleszar's avatar
John Koleszar committed
818 819
  // go left then right and check error
  this_mv.as_mv.row = startmv.as_mv.row;
820

John Koleszar's avatar
John Koleszar committed
821 822
  if (startmv.as_mv.col & 7) {
    this_mv.as_mv.col = startmv.as_mv.col - 1;
823
    thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858
  } else {
    this_mv.as_mv.col = (startmv.as_mv.col - 8) | 7;
    thismse = vfp->svf(y - 1, y_stride, SP(7), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
  }

  left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);

  if (left < bestmse) {
    *bestmv = this_mv;
    bestmse = left;
    *distortion = thismse;
    *sse1 = sse;
  }

  this_mv.as_mv.col += 2;
  thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
  right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);

  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;

  if (startmv.as_mv.row & 7) {
    this_mv.as_mv.row = startmv.as_mv.row - 1;
    thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
  } else {
    this_mv.as_mv.row = (startmv.as_mv.row - 8) | 7;
    thismse = vfp->svf(y - y_stride, y_stride, SP(this_mv.as_mv.col), SP(7), z, b->src_stride, &sse);
  }
859

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

John Koleszar's avatar
John Koleszar committed
862 863 864 865 866 867
  if (up < bestmse) {
    *bestmv = this_mv;
    bestmse = up;
    *distortion = thismse;
    *sse1 = sse;
  }
868

John Koleszar's avatar
John Koleszar committed
869 870 871
  this_mv.as_mv.row += 2;
  thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
  down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit, xd->allow_high_precision_mv);
872

John Koleszar's avatar
John Koleszar committed
873 874 875 876 877 878
  if (down < bestmse) {
    *bestmv = this_mv;
    bestmse = down;
    *distortion = thismse;
    *sse1 = sse;
  }
879 880


John Koleszar's avatar
John Koleszar committed
881 882
  // now check 1 more diagonal
  whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
883 884 885

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

John Koleszar's avatar
John Koleszar committed
888
  switch (whichdir) {
889 890
    case 0:

John Koleszar's avatar
John Koleszar committed
891 892
      if (startmv.as_mv.row & 7) {
        this_mv.as_mv.row -= 1;
893

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

        if (startmv.as_mv.col & 7) {
          this_mv.as_mv.col -= 1;
          thismse = vfp->svf(y - y_stride, y_stride, SP(this_mv.as_mv.col), SP(7), z, b->src_stride, &sse);
        } else {
          this_mv.as_mv.col = (startmv.as_mv.col - 8) | 7;
          thismse = vfp->svf(y - y_stride - 1, y_stride, SP(7), SP(7), z, b->src_stride, &sse);
910
        }
John Koleszar's avatar
John Koleszar committed
911
      }
912

John Koleszar's avatar
John Koleszar committed
913
      break;
914
    case 1:
John Koleszar's avatar
John Koleszar committed
915
      this_mv.as_mv.col += 1;
916

John Koleszar's avatar
John Koleszar committed
917 918 919 920 921 922 923
      if (startmv.as_mv.row & 7) {
        this_mv.as_mv.row -= 1;
        thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
      } else {
        this_mv.as_mv.row = (startmv.as_mv.row - 8) | 7;
        thismse = vfp->svf(y - y_stride, y_stride, SP(this_mv.as_mv.col), SP(7), z, b->src_stride, &sse);
      }
924

John Koleszar's avatar
John Koleszar committed
925
      break;
926
    case 2:
John Koleszar's avatar
John Koleszar committed
927
      this_mv.as_mv.row += 1;
928

John Koleszar's avatar
John Koleszar committed
929 930 931 932 933 934 935
      if (startmv.as_mv.col & 7) {
        this_mv.as_mv.col -= 1;
        thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
      } else {
        this_mv.as_mv.col = (startmv.as_mv.col - 8) | 7;
        thismse = vfp->svf(y - 1, y_stride, SP(7), SP(this_mv.as_mv.row), z, b->src_stride, &sse);
      }
936

John Koleszar's avatar