mcomp.c 68.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 11
 */


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

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

26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
void vp8_clamp_mv_min_max(MACROBLOCK *x, int_mv *ref_mv) {
  int col_min = (ref_mv->as_mv.col >> 3) - MAX_FULL_PEL_VAL +
      ((ref_mv->as_mv.col & 7) ? 1 : 0);
  int row_min = (ref_mv->as_mv.row >> 3) - MAX_FULL_PEL_VAL +
      ((ref_mv->as_mv.row & 7) ? 1 : 0);
  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;
}

45
int vp8_mv_bit_cost(int_mv *mv, int_mv *ref, DEC_MVCOSTS,
46
                    int Weight, int ishp) {
47 48 49 50 51 52 53 54 55 56
  MV v;
  v.row = (mv->as_mv.row - ref->as_mv.row);
  v.col = (mv->as_mv.col - ref->as_mv.col);
#if CONFIG_NEWMVENTROPY
  return ((mvjcost[vp8_get_mv_joint(v)] +
           mvcost[0][v.row] + mvcost[1][v.col]) *
          Weight) >> 7;
#else
  return ((mvcost[0][v.row >> (ishp == 0)] +
           mvcost[1][v.col >> (ishp == 0)])
57
          * Weight) >> 7;
58
#endif
John Koleszar's avatar
John Koleszar committed
59 60
}

61
static int mv_err_cost(int_mv *mv, int_mv *ref, DEC_MVCOSTS,
62
                       int error_per_bit, int ishp) {
63 64 65 66 67 68 69 70 71 72 73 74 75
  if (mvcost) {
    MV v;
    v.row = (mv->as_mv.row - ref->as_mv.row);
    v.col = (mv->as_mv.col - ref->as_mv.col);
#if CONFIG_NEWMVENTROPY
    return ((mvjcost[vp8_get_mv_joint(v)] +
             mvcost[0][v.row] + mvcost[1][v.col]) *
            error_per_bit + 128) >> 8;
#else
    return ((mvcost[0][v.row >> (ishp == 0)] +
             mvcost[1][v.col >> (ishp == 0)]) * error_per_bit + 128) >> 8;
#endif
  }
John Koleszar's avatar
John Koleszar committed
76
  return 0;
77 78
}

79
static int mvsad_err_cost(int_mv *mv, int_mv *ref, DEC_MVSADCOSTS,
80
                          int error_per_bit) {
81 82 83 84 85 86 87 88 89 90 91

  if (mvsadcost) {
    MV v;
    v.row = (mv->as_mv.row - ref->as_mv.row);
    v.col = (mv->as_mv.col - ref->as_mv.col);
#if CONFIG_NEWMVENTROPY
    return ((mvjsadcost[vp8_get_mv_joint(v)] +
             mvsadcost[0][v.row] + mvsadcost[1][v.col]) *
            error_per_bit + 128) >> 8;
#else
    return ((mvsadcost[0][v.row] + mvsadcost[1][v.col])
John Koleszar's avatar
John Koleszar committed
92
            * error_per_bit + 128) >> 8;
93 94
#endif
  }
John Koleszar's avatar
John Koleszar committed
95
  return 0;
John Koleszar's avatar
John Koleszar committed
96 97
}

John Koleszar's avatar
John Koleszar committed
98 99 100
void vp8_init_dsmotion_compensation(MACROBLOCK *x, int stride) {
  int Len;
  int search_site_count = 0;
John Koleszar's avatar
John Koleszar committed
101 102


John Koleszar's avatar
John Koleszar committed
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
  // 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
119
    x->ss[search_site_count].mv.col = 0;
John Koleszar's avatar
John Koleszar committed
120 121 122 123 124 125
    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
126
    x->ss[search_site_count].mv.row = 0;
John Koleszar's avatar
John Koleszar committed
127
    x->ss[search_site_count].offset = -Len;
John Koleszar's avatar
John Koleszar committed
128 129
    search_site_count++;

John Koleszar's avatar
John Koleszar committed
130 131 132 133 134
    // 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
135

John Koleszar's avatar
John Koleszar committed
136 137 138 139 140 141
    // Contract.
    Len /= 2;
  }

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

John Koleszar's avatar
John Koleszar committed
144 145 146 147 148 149 150 151 152 153 154 155
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
156

John Koleszar's avatar
John Koleszar committed
157
    // Compute offsets for search sites.
John Koleszar's avatar
John Koleszar committed
158
    x->ss[search_site_count].mv.col = 0;
John Koleszar's avatar
John Koleszar committed
159 160 161 162 163 164 165 166 167 168 169 170
    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
171
    x->ss[search_site_count].mv.row = 0;
John Koleszar's avatar
John Koleszar committed
172
    x->ss[search_site_count].offset = -Len;
John Koleszar's avatar
John Koleszar committed
173 174
    search_site_count++;

John Koleszar's avatar
John Koleszar committed
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
    // 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
204

John Koleszar's avatar
John Koleszar committed
205 206 207 208 209 210
    // Contract.
    Len /= 2;
  }

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

213 214 215 216 217 218 219 220 221
/*
 * 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.
 */
222

223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243
#if CONFIG_NEWMVENTROPY
/* estimated cost of a motion vector (r,c) */
#define MVC(r,c) \
  (mvcost ? \
  ((mvjcost[((r)!=rr)*2 + ((c)!=rc)] + \
    mvcost[0][((r)-rr)] + mvcost[1][((c)-rc)]) * error_per_bit + 128 )>>8 : 0)
#else
#define MVC(r,c) \
  (mvcost ? \
  ((mvcost[0][((r)-rr)>>(xd->allow_high_precision_mv==0)] + \
    mvcost[1][((c)-rc)>>(xd->allow_high_precision_mv==0)]) * \
    error_per_bit + 128 )>>8 : 0)
#endif  /* CONFIG_NEWMVENTROPY */

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

#define IFMVCV(r,c,s,e) \
  if ( c >= minc && c <= maxc && r >= minr && r <= maxr) s else e;

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

245 246 247 248 249 250 251
/* returns subpixel variance error function */
#define DIST(r,c) vfp->svf( PRE(r,c), y_stride, SP(c),SP(r), z,b->src_stride,&sse)

/* 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;)
252

John Koleszar's avatar
John Koleszar committed
253 254 255
#define MIN(x,y) (((x)<(y))?(x):(y))
#define MAX(x,y) (((x)>(y))?(x):(y))

Scott LaVarnway's avatar
Scott LaVarnway committed
256 257 258 259
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,
260 261
                                             DEC_MVCOSTS,
                                             int *distortion,
John Koleszar's avatar
John Koleszar committed
262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278
                                             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;
  unsigned int eighthiters = 4;
  int thismse;
  int maxc, minc, maxr, minr;
  int y_stride;
  int offset;
279
  int usehp = xd->allow_high_precision_mv;
John Koleszar's avatar
John Koleszar committed
280

Ronald S. Bultje's avatar
Ronald S. Bultje committed
281
#if !CONFIG_SUPERBLOCKS && (ARCH_X86 || ARCH_X86_64)
John Koleszar's avatar
John Koleszar committed
282 283 284 285 286
  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
287 288 289 290 291 292 293 294
  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
295 296 297 298 299
  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;
300
#else
John Koleszar's avatar
John Koleszar committed
301 302
  unsigned char *y = *(d->base_pre) + d->pre + (bestmv->as_mv.row) * d->pre_stride + bestmv->as_mv.col;
  y_stride = d->pre_stride;
303 304
#endif

305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320
  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;
#if CONFIG_NEWMVENTROPY
  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));
#else
  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));
#endif
John Koleszar's avatar
John Koleszar committed
321 322 323 324 325 326 327 328 329 330 331 332 333 334

  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;
335 336
  besterr += mv_err_cost(bestmv, ref_mv, MVCOSTS,
                         error_per_bit, xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
337

338 339
  // 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
340 341 342 343 344 345
  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);
346

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

John Koleszar's avatar
John Koleszar committed
349 350 351 352 353 354 355 356 357 358 359 360 361 362
    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;
    }
363

John Koleszar's avatar
John Koleszar committed
364 365 366
    // no reason to check the same one again.
    if (tr == br && tc == bc)
      break;
John Koleszar's avatar
John Koleszar committed
367

John Koleszar's avatar
John Koleszar committed
368 369 370
    tr = br;
    tc = bc;
  }
John Koleszar's avatar
John Koleszar committed
371

372 373
  // 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
374 375 376 377 378 379
  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
380

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

John Koleszar's avatar
John Koleszar committed
383 384 385 386 387 388 389 390 391 392 393 394 395 396
    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
397

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

John Koleszar's avatar
John Koleszar committed
402 403 404
    tr = br;
    tc = bc;
  }
John Koleszar's avatar
John Koleszar committed
405

406 407 408 409 410 411 412 413 414
#if CONFIG_NEWMVENTROPY
  if (xd->allow_high_precision_mv) {
    usehp = vp8_use_nmv_hp(&ref_mv->as_mv);
  } else {
    usehp = 0;
  }
#endif

  if (usehp) {
415
    hstep >>= 1;
John Koleszar's avatar
John Koleszar committed
416 417 418 419 420
    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
421

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

John Koleszar's avatar
John Koleszar committed
424
      switch (whichdir) {
John Koleszar's avatar
John Koleszar committed
425
        case 0:
John Koleszar's avatar
John Koleszar committed
426 427
          CHECK_BETTER(diag, tr - hstep, tc - hstep);
          break;
John Koleszar's avatar
John Koleszar committed
428
        case 1:
John Koleszar's avatar
John Koleszar committed
429 430
          CHECK_BETTER(diag, tr - hstep, tc + hstep);
          break;
John Koleszar's avatar
John Koleszar committed
431
        case 2:
John Koleszar's avatar
John Koleszar committed
432 433
          CHECK_BETTER(diag, tr + hstep, tc - hstep);
          break;
John Koleszar's avatar
John Koleszar committed
434
        case 3:
John Koleszar's avatar
John Koleszar committed
435 436 437
          CHECK_BETTER(diag, tr + hstep, tc + hstep);
          break;
      }
John Koleszar's avatar
John Koleszar committed
438

John Koleszar's avatar
John Koleszar committed
439 440 441
      // no reason to check the same one again.
      if (tr == br && tc == bc)
        break;
442

John Koleszar's avatar
John Koleszar committed
443 444
      tr = br;
      tc = bc;
445
    }
John Koleszar's avatar
John Koleszar committed
446
  }
447 448
  bestmv->as_mv.row = br;
  bestmv->as_mv.col = bc;
John Koleszar's avatar
John Koleszar committed
449

John Koleszar's avatar
John Koleszar committed
450 451 452
  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
453

John Koleszar's avatar
John Koleszar committed
454
  return besterr;
John Koleszar's avatar
John Koleszar committed
455 456 457 458
}
#undef MVC
#undef PRE
#undef DIST
459
#undef IFMVCV
John Koleszar's avatar
John Koleszar committed
460 461 462
#undef CHECK_BETTER
#undef MIN
#undef MAX
463

Scott LaVarnway's avatar
Scott LaVarnway committed
464 465 466 467
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,
468
                                 DEC_MVCOSTS, int *distortion,
John Koleszar's avatar
John Koleszar committed
469 470 471 472 473 474 475 476 477 478 479 480 481
                                 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;
  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;
482
  int usehp = xd->allow_high_precision_mv;
483

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

John Koleszar's avatar
John Koleszar committed
488 489 490 491
  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;
492
#else
John Koleszar's avatar
John Koleszar committed
493 494
  unsigned char *y = *(d->base_pre) + d->pre + (bestmv->as_mv.row) * d->pre_stride + bestmv->as_mv.col;
  y_stride = d->pre_stride;
495
#endif
John Koleszar's avatar
John Koleszar committed
496

John Koleszar's avatar
John Koleszar committed
497 498 499 500 501
  // central mv
  bestmv->as_mv.row <<= 3;
  bestmv->as_mv.col <<= 3;
  startmv = *bestmv;
  orig_mv = *bestmv;
John Koleszar's avatar
John Koleszar committed
502

John Koleszar's avatar
John Koleszar committed
503 504 505
  // calculate central point error
  bestmse = vfp->vf(y, y_stride, z, b->src_stride, sse1);
  *distortion = bestmse;
506
  bestmse += mv_err_cost(bestmv, ref_mv, MVCOSTS, error_per_bit,
507
                         xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
508

John Koleszar's avatar
John Koleszar committed
509 510 511 512
  // 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);
513
  left = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit,
514
                               xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
515

John Koleszar's avatar
John Koleszar committed
516 517 518 519 520 521
  if (left < bestmse) {
    *bestmv = this_mv;
    bestmse = left;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
522

John Koleszar's avatar
John Koleszar committed
523 524
  this_mv.as_mv.col += 8;
  thismse = vfp->svf_halfpix_h(y, y_stride, z, b->src_stride, &sse);
525
  right = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit,
526
                                xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
527

John Koleszar's avatar
John Koleszar committed
528 529 530 531 532 533 534 535 536 537 538
  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);
539
  up = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit,
540
                             xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
541

John Koleszar's avatar
John Koleszar committed
542 543 544 545 546 547
  if (up < bestmse) {
    *bestmv = this_mv;
    bestmse = up;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
548

John Koleszar's avatar
John Koleszar committed
549 550
  this_mv.as_mv.row += 8;
  thismse = vfp->svf_halfpix_v(y, y_stride, z, b->src_stride, &sse);
551
  down = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit,
552
                               xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
553

John Koleszar's avatar
John Koleszar committed
554 555 556 557 558 559
  if (down < bestmse) {
    *bestmv = this_mv;
    bestmse = down;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
560 561


John Koleszar's avatar
John Koleszar committed
562 563 564 565 566
  // 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
567

John Koleszar's avatar
John Koleszar committed
568
  switch (whichdir) {
John Koleszar's avatar
John Koleszar committed
569
    case 0:
John Koleszar's avatar
John Koleszar committed
570 571 572 573
      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
574
    case 1:
John Koleszar's avatar
John Koleszar committed
575 576 577 578
      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
579
    case 2:
John Koleszar's avatar
John Koleszar committed
580 581 582 583
      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
584
    case 3:
585
    default:
John Koleszar's avatar
John Koleszar committed
586 587 588 589 590
      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
591

592
  diag = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit,
593
                               xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
594

John Koleszar's avatar
John Koleszar committed
595 596 597 598 599 600
  if (diag < bestmse) {
    *bestmv = this_mv;
    bestmse = diag;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
601 602 603 604

//  }


John Koleszar's avatar
John Koleszar committed
605 606 607 608 609
  // 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
610

John Koleszar's avatar
John Koleszar committed
611 612 613 614
  if (bestmv->as_mv.col < startmv.as_mv.col) {
    y--;
    ycol_movedback = 1;
  }
John Koleszar's avatar
John Koleszar committed
615

John Koleszar's avatar
John Koleszar committed
616
  startmv = *bestmv;
John Koleszar's avatar
John Koleszar committed
617 618 619



John Koleszar's avatar
John Koleszar committed
620 621
  // go left then right and check error
  this_mv.as_mv.row = startmv.as_mv.row;
John Koleszar's avatar
John Koleszar committed
622

John Koleszar's avatar
John Koleszar committed
623 624
  if (startmv.as_mv.col & 7) {
    this_mv.as_mv.col = startmv.as_mv.col - 2;
625 626 627
    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
628 629
  } else {
    this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6;
630 631
    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
632
  }
John Koleszar's avatar
John Koleszar committed
633

634
  left = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit,
635
                               xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
636

John Koleszar's avatar
John Koleszar committed
637 638 639 640 641 642
  if (left < bestmse) {
    *bestmv = this_mv;
    bestmse = left;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
643

John Koleszar's avatar
John Koleszar committed
644
  this_mv.as_mv.col += 4;
645 646 647
  thismse = vfp->svf(y, y_stride,
                     SP(this_mv.as_mv.col), SP(this_mv.as_mv.row),
                     z, b->src_stride, &sse);
648
  right = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit,
649
                                xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
650

John Koleszar's avatar
John Koleszar committed
651 652 653 654 655 656
  if (right < bestmse) {
    *bestmv = this_mv;
    bestmse = right;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
657

John Koleszar's avatar
John Koleszar committed
658 659
  // go up then down and check error
  this_mv.as_mv.col = startmv.as_mv.col;
John Koleszar's avatar
John Koleszar committed
660

John Koleszar's avatar
John Koleszar committed
661 662
  if (startmv.as_mv.row & 7) {
    this_mv.as_mv.row = startmv.as_mv.row - 2;
663 664 665
    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
666 667
  } else {
    this_mv.as_mv.row = (startmv.as_mv.row - 8) | 6;
668 669
    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
670
  }
John Koleszar's avatar
John Koleszar committed
671

672
  up = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit,
673
                             xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
674

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

John Koleszar's avatar
John Koleszar committed
682
  this_mv.as_mv.row += 4;
683 684
  thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row),
                     z, b->src_stride, &sse);
685
  down = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit,
686
                               xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
687

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


John Koleszar's avatar
John Koleszar committed
696 697
  // now check 1 more diagonal
  whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
John Koleszar's avatar
John Koleszar committed
698 699 700

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

John Koleszar's avatar
John Koleszar committed
703
  switch (whichdir) {
John Koleszar's avatar
John Koleszar committed
704 705
    case 0:

John Koleszar's avatar
John Koleszar committed
706 707
      if (startmv.as_mv.row & 7) {
        this_mv.as_mv.row -= 2;
John Koleszar's avatar
John Koleszar committed
708

John Koleszar's avatar
John Koleszar committed
709 710 711 712 713 714
        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
715
        }
John Koleszar's avatar
John Koleszar committed
716 717 718 719 720 721 722 723 724
      } 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
725
        }
John Koleszar's avatar
John Koleszar committed
726
      }
John Koleszar's avatar
John Koleszar committed
727

John Koleszar's avatar
John Koleszar committed
728
      break;
John Koleszar's avatar
John Koleszar committed
729
    case 1:
John Koleszar's avatar
John Koleszar committed
730
      this_mv.as_mv.col += 2;
John Koleszar's avatar
John Koleszar committed
731

John Koleszar's avatar
John Koleszar committed
732 733 734 735 736 737 738
      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
739

John Koleszar's avatar
John Koleszar committed
740
      break;
John Koleszar's avatar
John Koleszar committed
741
    case 2:
John Koleszar's avatar
John Koleszar committed
742
      this_mv.as_mv.row += 2;
John Koleszar's avatar
John Koleszar committed
743

John Koleszar's avatar
John Koleszar committed
744 745
      if (startmv.as_mv.col & 7) {
        this_mv.as_mv.col -= 2;
746 747
        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
748 749
      } else {
        this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6;
750 751
        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
752
      }
John Koleszar's avatar
John Koleszar committed
753

John Koleszar's avatar
John Koleszar committed
754
      break;
John Koleszar's avatar
John Koleszar committed
755
    case 3:
John Koleszar's avatar
John Koleszar committed
756 757
      this_mv.as_mv.col += 2;
      this_mv.as_mv.row += 2;
758 759 760
      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
761 762
      break;
  }
John Koleszar's avatar
John Koleszar committed
763

764
  diag = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit,
765
                               xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
766

John Koleszar's avatar
John Koleszar committed
767 768 769 770 771 772
  if (diag < bestmse) {
    *bestmv = this_mv;
    bestmse = diag;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
773

774 775 776 777 778 779 780 781
#if CONFIG_NEWMVENTROPY
  if (x->e_mbd.allow_high_precision_mv) {
    usehp = vp8_use_nmv_hp(&ref_mv->as_mv);
  } else {
    usehp = 0;
  }
#endif
  if (!usehp)
John Koleszar's avatar
John Koleszar committed
782
    return bestmse;
783

John Koleszar's avatar
John Koleszar committed
784 785 786 787 788
  /* Now do 1/8th pixel */
  if (bestmv->as_mv.row < orig_mv.as_mv.row && !yrow_movedback) {
    y -= y_stride;
    yrow_movedback = 1;
  }
789

John Koleszar's avatar
John Koleszar committed
790 791 792 793
  if (bestmv->as_mv.col < orig_mv.as_mv.col && !ycol_movedback) {
    y--;
    ycol_movedback = 1;
  }
794

John Koleszar's avatar
John Koleszar committed
795
  startmv = *bestmv;
796

John Koleszar's avatar
John Koleszar committed
797 798
  // go left then right and check error
  this_mv.as_mv.row = startmv.as_mv.row;
799

John Koleszar's avatar
John Koleszar committed
800 801
  if (startmv.as_mv.col & 7) {
    this_mv.as_mv.col = startmv.as_mv.col - 1;
802 803 804
    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
805 806
  } else {
    this_mv.as_mv.col = (startmv.as_mv.col - 8) | 7;
807 808
    thismse = vfp->svf(y - 1, y_stride, SP(7), SP(this_mv.as_mv.row),
                       z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
809 810
  }

811
  left = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit,
812
                               xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
813 814 815 816 817 818 819 820 821

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

  this_mv.as_mv.col += 2;
822 823 824 825
  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, MVCOSTS, error_per_bit,
                                xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843

  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);
  }
844

845 846
  up = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit,
                             xd->allow_high_precision_mv);
847

John Koleszar's avatar
John Koleszar committed
848 849 850 851 852 853
  if (up < bestmse) {
    *bestmv = this_mv;
    bestmse = up;
    *distortion = thismse;
    *sse1 = sse;
  }
854

John Koleszar's avatar
John Koleszar committed
855 856
  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);
857 858
  down = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit,
                               xd->allow_high_precision_mv);
859

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

John Koleszar's avatar
John Koleszar committed
867 868
  // now check 1 more diagonal
  whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
869 870 871

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

John Koleszar's avatar
John Koleszar committed
874
  switch (whichdir) {
875 876
    case 0:

John Koleszar's avatar
John Koleszar committed
877 878
      if (startmv.as_mv.row & 7) {
        this_mv.as_mv.row -= 1;
879

John Koleszar's avatar
John Koleszar committed
880 881 882 883 884 885
        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);;
886
        }
John Koleszar's avatar
John Koleszar committed
887 888 889 890 891 892 893 894 895
      } 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);
896
        }
John Koleszar's avatar
John Koleszar committed
897
      }
898

John Koleszar's avatar
John Koleszar committed
899
      break;
900
    case 1:
John Koleszar's avatar
John Koleszar committed
901
      this_mv.as_mv.col += 1;
902

John Koleszar's avatar
John Koleszar committed
903 904 905 906 907 908 909
      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);
      }
910

John Koleszar's avatar
John Koleszar committed
911
      break;
912
    case 2:
John Koleszar's avatar
John Koleszar committed
913
      this_mv.as_mv.row += 1;
914

John Koleszar's avatar
John Koleszar committed
915 916 917 918 919 920 921
      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);
      }
922

John Koleszar's avatar
John Koleszar committed
923
      break;
924
    case 3:
John Koleszar's avatar
John Koleszar committed
925 926 927 928 929
      this_mv.as_mv.col += 1;
      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);
      break;
  }
930

931 932
  diag = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit,
                               xd->allow_high_precision_mv);
933

John Koleszar's avatar
John Koleszar committed
934 935 936 937 938 939
  if (diag < bestmse) {
    *bestmv = this_mv;
    bestmse = diag;
    *distortion = thismse;
    *sse1 = sse;
  }
940

John Koleszar's avatar
John Koleszar committed
941
  return bestmse;
John Koleszar's avatar
John Koleszar committed
942 943
}

944 945
#undef SP

946
int vp8_find_best_half_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
Scott LaVarnway's avatar
Scott LaVarnway committed
947 948 949
                                  int_mv *bestmv, int_mv *ref_mv,
                                  int error_per_bit,
                                  const vp8_variance_fn_ptr_t *vfp,
950 951
                                  DEC_MVCOSTS,
                                  int *distortion,
John Koleszar's avatar
John Koleszar committed
952 953 954 955 956 957 958 959 960 961 962
                                  unsigned int *sse1) {
  int bestmse = INT_MAX;
  int_mv startmv;
  int_mv this_mv;
  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;
963

964
#if !CONFIG_SUPERBLOCKS && (ARCH_X86 || ARCH_X86_64)
965 966
  unsigned char *y0 = *(d->base_pre) + d->pre +
      (bestmv->as_mv.row) * d->pre_stride + bestmv->as_mv.col;
John Koleszar's avatar
John Koleszar committed
967
  unsigned char *y;
968

John Koleszar's avatar
John Koleszar committed
969 970 971 972
  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;
973
#else
974 975
  unsigned char *y = *(d->base_pre) + d->pre +
      (bestmv->as_mv.row) * d->pre_stride + bestmv->as_mv.col;