mcomp.c 67.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 46 47 48 49 50 51 52 53 54 55
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
56 57
}

58 59
static int mv_err_cost(int_mv *mv, int_mv *ref, int *mvcost[2],
                       int error_per_bit, int ishp) {
John Koleszar's avatar
John Koleszar committed
60 61 62 63 64 65
  // 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;
66 67
}

John Koleszar's avatar
John Koleszar committed
68

69 70
static int mvsad_err_cost(int_mv *mv, int_mv *ref, int *mvsadcost[2],
                          int error_per_bit) {
John Koleszar's avatar
John Koleszar committed
71 72 73 74 75 76 77
  // 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
78 79
}

80

John Koleszar's avatar
John Koleszar committed
81 82 83
void vp8_init_dsmotion_compensation(MACROBLOCK *x, int stride) {
  int Len;
  int search_site_count = 0;
John Koleszar's avatar
John Koleszar committed
84 85


John Koleszar's avatar
John Koleszar committed
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
  // 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
102
    x->ss[search_site_count].mv.col = 0;
John Koleszar's avatar
John Koleszar committed
103 104 105 106 107 108
    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
109
    x->ss[search_site_count].mv.row = 0;
John Koleszar's avatar
John Koleszar committed
110
    x->ss[search_site_count].offset = -Len;
John Koleszar's avatar
John Koleszar committed
111 112
    search_site_count++;

John Koleszar's avatar
John Koleszar committed
113 114 115 116 117
    // 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
118

John Koleszar's avatar
John Koleszar committed
119 120 121 122 123 124
    // Contract.
    Len /= 2;
  }

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

John Koleszar's avatar
John Koleszar committed
127 128 129 130 131 132 133 134 135 136 137 138
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
139

John Koleszar's avatar
John Koleszar committed
140
    // Compute offsets for search sites.
John Koleszar's avatar
John Koleszar committed
141
    x->ss[search_site_count].mv.col = 0;
John Koleszar's avatar
John Koleszar committed
142 143 144 145 146 147 148 149 150 151 152 153
    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
154
    x->ss[search_site_count].mv.row = 0;
John Koleszar's avatar
John Koleszar committed
155
    x->ss[search_site_count].offset = -Len;
John Koleszar's avatar
John Koleszar committed
156 157
    search_site_count++;

John Koleszar's avatar
John Koleszar committed
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
    // 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
187

John Koleszar's avatar
John Koleszar committed
188 189 190 191 192 193 194

    // Contract.
    Len /= 2;
  }

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

197 198 199 200 201 202 203 204 205
/*
 * 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.
 */
206

207
#define PRE(r,c) (y + (((r)>>2) * y_stride + ((c)>>2) -(offset))) // pointer to predictor base of a motionvector
208 209 210
#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
211
#define SP(x) (((x)&3)<<1) // convert motion vector component to offset for svf calc
212
#endif  /* CONFIG_SIXTEENTH_SUBPEL_UV */
213
#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)
214
#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
215
#define ERR(r,c) (MVC(r,c)+DIST(r,c)) // returns distortion + motion vector cost
216 217 218 219 220 221 222 223 224 225 226
#define IFMVCV(r,c,s,e) if ( c >= minc && c <= maxc && r >= minr && r <= maxr) s else e;

#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
227

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

Scott LaVarnway's avatar
Scott LaVarnway committed
231 232 233 234 235
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
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252
                                             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;
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


John Koleszar's avatar
John Koleszar committed
279 280 281 282 283 284 285 286 287 288
  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));
289
  } else {
John Koleszar's avatar
John Koleszar committed
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313
    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;
314 315
  besterr += mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit,
                         xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
316

317 318
  // 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
319 320 321 322 323 324
  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);
325

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

John Koleszar's avatar
John Koleszar committed
328 329 330 331 332 333 334 335 336 337 338 339 340 341
    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;
    }
342

John Koleszar's avatar
John Koleszar committed
343 344 345
    // no reason to check the same one again.
    if (tr == br && tc == bc)
      break;
John Koleszar's avatar
John Koleszar committed
346

John Koleszar's avatar
John Koleszar committed
347 348 349
    tr = br;
    tc = bc;
  }
John Koleszar's avatar
John Koleszar committed
350

351 352
  // 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
353 354 355 356 357 358
  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
359

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

John Koleszar's avatar
John Koleszar committed
362 363 364 365 366 367 368 369 370 371 372 373 374 375
    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
376

John Koleszar's avatar
John Koleszar committed
377 378 379
    // no reason to check the same one again.
    if (tr == br && tc == bc)
      break;
John Koleszar's avatar
John Koleszar committed
380

John Koleszar's avatar
John Koleszar committed
381 382 383
    tr = br;
    tc = bc;
  }
John Koleszar's avatar
John Koleszar committed
384

John Koleszar's avatar
John Koleszar committed
385
  if (x->e_mbd.allow_high_precision_mv) {
386
    hstep >>= 1;
John Koleszar's avatar
John Koleszar committed
387 388 389 390 391
    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
392

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

John Koleszar's avatar
John Koleszar committed
395
      switch (whichdir) {
John Koleszar's avatar
John Koleszar committed
396
        case 0:
John Koleszar's avatar
John Koleszar committed
397 398
          CHECK_BETTER(diag, tr - hstep, tc - hstep);
          break;
John Koleszar's avatar
John Koleszar committed
399
        case 1:
John Koleszar's avatar
John Koleszar committed
400 401
          CHECK_BETTER(diag, tr - hstep, tc + hstep);
          break;
John Koleszar's avatar
John Koleszar committed
402
        case 2:
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 3:
John Koleszar's avatar
John Koleszar committed
406 407 408
          CHECK_BETTER(diag, tr + hstep, tc + hstep);
          break;
      }
John Koleszar's avatar
John Koleszar committed
409

John Koleszar's avatar
John Koleszar committed
410 411 412
      // no reason to check the same one again.
      if (tr == br && tc == bc)
        break;
413

John Koleszar's avatar
John Koleszar committed
414 415
      tr = br;
      tc = bc;
416
    }
John Koleszar's avatar
John Koleszar committed
417 418 419 420
  }
  if (x->e_mbd.allow_high_precision_mv) {
    bestmv->as_mv.row = br;
    bestmv->as_mv.col = bc;
421
  } else {
John Koleszar's avatar
John Koleszar committed
422 423 424
    bestmv->as_mv.row = br << 1;
    bestmv->as_mv.col = bc << 1;
  }
John Koleszar's avatar
John Koleszar committed
425

John Koleszar's avatar
John Koleszar committed
426 427 428
  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
429

John Koleszar's avatar
John Koleszar committed
430
  return besterr;
John Koleszar's avatar
John Koleszar committed
431 432 433 434 435
}
#undef MVC
#undef PRE
#undef SP
#undef DIST
436
#undef IFMVCV
John Koleszar's avatar
John Koleszar committed
437 438 439 440
#undef ERR
#undef CHECK_BETTER
#undef MIN
#undef MAX
441

442 443 444 445 446
#undef PREHP
#undef DPHP
#undef DISTHP
#undef ERRHP

447 448 449 450
#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
451
#endif  /* CONFIG_SIXTEENTH_SUBPEL_UV */
Scott LaVarnway's avatar
Scott LaVarnway committed
452 453 454 455 456
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
457 458 459 460 461 462 463 464 465 466 467 468 469
                                 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;
470 471

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

John Koleszar's avatar
John Koleszar committed
475 476 477 478
  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;
479
#else
John Koleszar's avatar
John Koleszar committed
480 481
  unsigned char *y = *(d->base_pre) + d->pre + (bestmv->as_mv.row) * d->pre_stride + bestmv->as_mv.col;
  y_stride = d->pre_stride;
482
#endif
John Koleszar's avatar
John Koleszar committed
483

John Koleszar's avatar
John Koleszar committed
484 485 486 487 488
  // central mv
  bestmv->as_mv.row <<= 3;
  bestmv->as_mv.col <<= 3;
  startmv = *bestmv;
  orig_mv = *bestmv;
John Koleszar's avatar
John Koleszar committed
489

John Koleszar's avatar
John Koleszar committed
490 491 492
  // calculate central point error
  bestmse = vfp->vf(y, y_stride, z, b->src_stride, sse1);
  *distortion = bestmse;
493 494
  bestmse += mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit,
                         xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
495

John Koleszar's avatar
John Koleszar committed
496 497 498 499
  // 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);
500 501
  left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit,
                               xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
502

John Koleszar's avatar
John Koleszar committed
503 504 505 506 507 508
  if (left < bestmse) {
    *bestmv = this_mv;
    bestmse = left;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
509

John Koleszar's avatar
John Koleszar committed
510 511
  this_mv.as_mv.col += 8;
  thismse = vfp->svf_halfpix_h(y, y_stride, z, b->src_stride, &sse);
512 513
  right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit,
                                xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
514

John Koleszar's avatar
John Koleszar committed
515 516 517 518 519 520 521 522 523 524 525
  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);
526 527
  up = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit,
                             xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
528

John Koleszar's avatar
John Koleszar committed
529 530 531 532 533 534
  if (up < bestmse) {
    *bestmv = this_mv;
    bestmse = up;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
535

John Koleszar's avatar
John Koleszar committed
536 537
  this_mv.as_mv.row += 8;
  thismse = vfp->svf_halfpix_v(y, y_stride, z, b->src_stride, &sse);
538 539
  down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit,
                               xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
540

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


John Koleszar's avatar
John Koleszar committed
549 550 551 552 553
  // 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
554

John Koleszar's avatar
John Koleszar committed
555
  switch (whichdir) {
John Koleszar's avatar
John Koleszar committed
556
    case 0:
John Koleszar's avatar
John Koleszar committed
557 558 559 560
      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
561
    case 1:
John Koleszar's avatar
John Koleszar committed
562 563 564 565
      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
566
    case 2:
John Koleszar's avatar
John Koleszar committed
567 568 569 570
      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
571
    case 3:
572
    default:
John Koleszar's avatar
John Koleszar committed
573 574 575 576 577
      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
578

579 580
  diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit,
                               xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
581

John Koleszar's avatar
John Koleszar committed
582 583 584 585 586 587
  if (diag < bestmse) {
    *bestmv = this_mv;
    bestmse = diag;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
588 589 590 591

//  }


John Koleszar's avatar
John Koleszar committed
592 593 594 595 596
  // 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
597

John Koleszar's avatar
John Koleszar committed
598 599 600 601
  if (bestmv->as_mv.col < startmv.as_mv.col) {
    y--;
    ycol_movedback = 1;
  }
John Koleszar's avatar
John Koleszar committed
602

John Koleszar's avatar
John Koleszar committed
603
  startmv = *bestmv;
John Koleszar's avatar
John Koleszar committed
604 605 606



John Koleszar's avatar
John Koleszar committed
607 608
  // go left then right and check error
  this_mv.as_mv.row = startmv.as_mv.row;
John Koleszar's avatar
John Koleszar committed
609

John Koleszar's avatar
John Koleszar committed
610 611
  if (startmv.as_mv.col & 7) {
    this_mv.as_mv.col = startmv.as_mv.col - 2;
612 613 614
    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
615 616
  } else {
    this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6;
617 618
    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
619
  }
John Koleszar's avatar
John Koleszar committed
620

621 622
  left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit,
                               xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
623

John Koleszar's avatar
John Koleszar committed
624 625 626 627 628 629
  if (left < bestmse) {
    *bestmv = this_mv;
    bestmse = left;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
630

John Koleszar's avatar
John Koleszar committed
631
  this_mv.as_mv.col += 4;
632 633 634 635 636
  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);
John Koleszar's avatar
John Koleszar committed
637

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

John Koleszar's avatar
John Koleszar committed
645 646
  // go up then down and check error
  this_mv.as_mv.col = startmv.as_mv.col;
John Koleszar's avatar
John Koleszar committed
647

John Koleszar's avatar
John Koleszar committed
648 649
  if (startmv.as_mv.row & 7) {
    this_mv.as_mv.row = startmv.as_mv.row - 2;
650 651 652
    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
653 654
  } else {
    this_mv.as_mv.row = (startmv.as_mv.row - 8) | 6;
655 656
    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
657
  }
John Koleszar's avatar
John Koleszar committed
658

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

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

John Koleszar's avatar
John Koleszar committed
669
  this_mv.as_mv.row += 4;
670 671 672 673
  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);
John Koleszar's avatar
John Koleszar committed
674

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


John Koleszar's avatar
John Koleszar committed
683 684
  // now check 1 more diagonal
  whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
John Koleszar's avatar
John Koleszar committed
685 686 687

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

John Koleszar's avatar
John Koleszar committed
690
  switch (whichdir) {
John Koleszar's avatar
John Koleszar committed
691 692
    case 0:

John Koleszar's avatar
John Koleszar committed
693 694
      if (startmv.as_mv.row & 7) {
        this_mv.as_mv.row -= 2;
John Koleszar's avatar
John Koleszar committed
695

John Koleszar's avatar
John Koleszar committed
696 697 698 699 700 701
        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
702
        }
John Koleszar's avatar
John Koleszar committed
703 704 705 706 707 708 709 710 711
      } 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
712
        }
John Koleszar's avatar
John Koleszar committed
713
      }
John Koleszar's avatar
John Koleszar committed
714

John Koleszar's avatar
John Koleszar committed
715
      break;
John Koleszar's avatar
John Koleszar committed
716
    case 1:
John Koleszar's avatar
John Koleszar committed
717
      this_mv.as_mv.col += 2;
John Koleszar's avatar
John Koleszar committed
718

John Koleszar's avatar
John Koleszar committed
719 720 721 722 723 724 725
      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
726

John Koleszar's avatar
John Koleszar committed
727
      break;
John Koleszar's avatar
John Koleszar committed
728
    case 2:
John Koleszar's avatar
John Koleszar committed
729
      this_mv.as_mv.row += 2;
John Koleszar's avatar
John Koleszar committed
730

John Koleszar's avatar
John Koleszar committed
731 732
      if (startmv.as_mv.col & 7) {
        this_mv.as_mv.col -= 2;
733 734
        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
735 736
      } else {
        this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6;
737 738
        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
739
      }
John Koleszar's avatar
John Koleszar committed
740

John Koleszar's avatar
John Koleszar committed
741
      break;
John Koleszar's avatar
John Koleszar committed
742
    case 3:
John Koleszar's avatar
John Koleszar committed
743 744
      this_mv.as_mv.col += 2;
      this_mv.as_mv.row += 2;
745 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
      break;
  }
John Koleszar's avatar
John Koleszar committed
750

751 752
  diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit,
                               xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
753

John Koleszar's avatar
John Koleszar committed
754 755 756 757 758 759
  if (diag < bestmse) {
    *bestmv = this_mv;
    bestmse = diag;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
760

John Koleszar's avatar
John Koleszar committed
761 762
  if (!x->e_mbd.allow_high_precision_mv)
    return bestmse;
763

John Koleszar's avatar
John Koleszar committed
764 765 766 767 768
  /* Now do 1/8th pixel */
  if (bestmv->as_mv.row < orig_mv.as_mv.row && !yrow_movedback) {
    y -= y_stride;
    yrow_movedback = 1;
  }
769

John Koleszar's avatar
John Koleszar committed
770 771 772 773
  if (bestmv->as_mv.col < orig_mv.as_mv.col && !ycol_movedback) {
    y--;
    ycol_movedback = 1;
  }
774

John Koleszar's avatar
John Koleszar committed
775
  startmv = *bestmv;
776

John Koleszar's avatar
John Koleszar committed
777 778
  // go left then right and check error
  this_mv.as_mv.row = startmv.as_mv.row;
779

John Koleszar's avatar
John Koleszar committed
780 781
  if (startmv.as_mv.col & 7) {
    this_mv.as_mv.col = startmv.as_mv.col - 1;
782 783 784
    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
785 786
  } else {
    this_mv.as_mv.col = (startmv.as_mv.col - 8) | 7;
787 788
    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
789 790
  }

791 792
  left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit,
                               xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 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;
  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);
  }
822

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

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

John Koleszar's avatar
John Koleszar committed
832 833 834
  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);
835

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

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

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

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

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

John Koleszar's avatar
John Koleszar committed
856 857 858 859 860 861
        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);;
862
        }
John Koleszar's avatar
John Koleszar committed
863 864 865 866 867 868 869 870 871
      } 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);
872
        }
John Koleszar's avatar
John Koleszar committed
873
      }
874

John Koleszar's avatar
John Koleszar committed
875
      break;
876
    case 1:
John Koleszar's avatar
John Koleszar committed
877
      this_mv.as_mv.col += 1;
878

John Koleszar's avatar
John Koleszar committed
879 880 881 882 883 884 885
      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);
      }
886

John Koleszar's avatar
John Koleszar committed
887
      break;
888
    case 2:
John Koleszar's avatar
John Koleszar committed
889
      this_mv.as_mv.row += 1;
890

John Koleszar's avatar
John Koleszar committed
891 892 893 894 895 896 897
      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);
      }
898

John Koleszar's avatar
John Koleszar committed
899
      break;
900
    case 3:
John Koleszar's avatar
John Koleszar committed
901 902 903 904 905
      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;
  }
906

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

John Koleszar's avatar
John Koleszar committed
909 910 911 912 913 914
  if (diag < bestmse) {
    *bestmv = this_mv;
    bestmse = diag;
    *distortion = thismse;
    *sse1 = sse;
  }
915

John Koleszar's avatar
John Koleszar committed
916
  return bestmse;
John Koleszar's avatar
John Koleszar committed
917 918
}

919 920
#undef SP

921
int vp8_find_best_half_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
Scott LaVarnway's avatar
Scott LaVarnway committed
922 923 924 925
                                  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
926 927 928 929 930 931 932 933 934 935 936
                                  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;
937 938

#if ARCH_X86 || ARCH_X86_64
939 940
  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
941
  unsigned char *y;
942

John Koleszar's avatar
John Koleszar committed
943 944 945 946
  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;
947
#else
948 949
  unsigned char *y = *(d->base_pre) + d->pre +
      (bestmv->as_mv.row) * d->pre_stride + bestmv->as_mv.col;
John Koleszar's avatar
John Koleszar committed
950
  y_stride = d->pre_stride;
951
#endif
John Koleszar's avatar
John Koleszar committed
952

John Koleszar's avatar
John Koleszar committed
953 954 955 956
  // central mv
  bestmv->as_mv.row <<= 3;
  bestmv->as_mv.col <<= 3;
  startmv = *bestmv;
John Koleszar's avatar
John Koleszar committed
957

John Koleszar's avatar
John Koleszar committed
958 959 960
  // calculate central point error
  bestmse = vfp->vf(y, y_stride, z, b->src_stride, sse1);
  *distortion = bestmse;
961 962
  bestmse += mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit,
                         xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
963

John Koleszar's avatar
John Koleszar committed
964 965 966 967
  // 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);
968 969
  left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit,
                               xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
970

John Koleszar's avatar
John Koleszar committed
971 972 973 974 975 976
  if (left < bestmse) {
    *bestmv = this_mv;
    bestmse = left;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
977

John Koleszar's avatar
John Koleszar committed
978 979
  this_mv.as_mv.col += 8;
  thismse = vfp->svf_halfpix_h(y, y_stride, z, b->src_stride, &sse);
980 981
  right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit,
                                xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
982