mcomp.c 66.4 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 "vp9/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 "vp9/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
void vp9_clamp_mv_min_max(MACROBLOCK *x, int_mv *ref_mv) {
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
  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 vp9_mv_bit_cost(int_mv *mv, int_mv *ref, DEC_MVCOSTS,
46
                    int Weight, int ishp) {
47
48
49
  MV v;
  v.row = (mv->as_mv.row - ref->as_mv.row);
  v.col = (mv->as_mv.col - ref->as_mv.col);
50
  return ((mvjcost[vp9_get_mv_joint(v)] +
51
52
           mvcost[0][v.row] + mvcost[1][v.col]) *
          Weight) >> 7;
John Koleszar's avatar
John Koleszar committed
53
54
}

55
static int mv_err_cost(int_mv *mv, int_mv *ref, DEC_MVCOSTS,
56
                       int error_per_bit, int ishp) {
57
58
59
60
  if (mvcost) {
    MV v;
    v.row = (mv->as_mv.row - ref->as_mv.row);
    v.col = (mv->as_mv.col - ref->as_mv.col);
61
    return ((mvjcost[vp9_get_mv_joint(v)] +
62
63
64
             mvcost[0][v.row] + mvcost[1][v.col]) *
            error_per_bit + 128) >> 8;
  }
John Koleszar's avatar
John Koleszar committed
65
  return 0;
66
67
}

68
static int mvsad_err_cost(int_mv *mv, int_mv *ref, DEC_MVSADCOSTS,
69
                          int error_per_bit) {
70
71
72
73
74

  if (mvsadcost) {
    MV v;
    v.row = (mv->as_mv.row - ref->as_mv.row);
    v.col = (mv->as_mv.col - ref->as_mv.col);
75
    return ((mvjsadcost[vp9_get_mv_joint(v)] +
76
77
78
             mvsadcost[0][v.row] + mvsadcost[1][v.col]) *
            error_per_bit + 128) >> 8;
  }
John Koleszar's avatar
John Koleszar committed
79
  return 0;
John Koleszar's avatar
John Koleszar committed
80
81
}

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


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

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

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

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

128
void vp9_init3smotion_compensation(MACROBLOCK *x, int stride) {
John Koleszar's avatar
John Koleszar committed
129
130
131
132
133
134
135
136
137
138
139
  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
140

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

John Koleszar's avatar
John Koleszar committed
159
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
187
    // 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
188

John Koleszar's avatar
John Koleszar committed
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
/* estimated cost of a motion vector (r,c) */
208
209
210
211
212
#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)
213

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

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

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

226
/* returns subpixel variance error function */
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
#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;)
243

John Koleszar's avatar
John Koleszar committed
244
245
246
#define MIN(x,y) (((x)<(y))?(x):(y))
#define MAX(x,y) (((x)>(y))?(x):(y))

247
int vp9_find_best_sub_pixel_step_iteratively(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
Scott LaVarnway's avatar
Scott LaVarnway committed
248
249
                                             int_mv *bestmv, int_mv *ref_mv,
                                             int error_per_bit,
250
                                             const vp9_variance_fn_ptr_t *vfp,
251
252
                                             DEC_MVCOSTS,
                                             int *distortion,
John Koleszar's avatar
John Koleszar committed
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
                                             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;
270
  int usehp = xd->allow_high_precision_mv;
John Koleszar's avatar
John Koleszar committed
271

Ronald S. Bultje's avatar
Ronald S. Bultje committed
272
#if !CONFIG_SUPERBLOCKS && (ARCH_X86 || ARCH_X86_64)
John Koleszar's avatar
John Koleszar committed
273
274
275
276
277
  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
John Koleszar's avatar
John Koleszar committed
278
279
280
281
282
283
284
285
  buf_r1 = ((bestmv->as_mv.row - VP9_INTERP_EXTEND) < x->mv_row_min) ?
      (bestmv->as_mv.row - x->mv_row_min) : VP9_INTERP_EXTEND - 1;
  buf_r2 = ((bestmv->as_mv.row + VP9_INTERP_EXTEND) > x->mv_row_max) ?
      (x->mv_row_max - bestmv->as_mv.row) : VP9_INTERP_EXTEND - 1;
  buf_c1 = ((bestmv->as_mv.col - VP9_INTERP_EXTEND) < x->mv_col_min) ?
      (bestmv->as_mv.col - x->mv_col_min) : VP9_INTERP_EXTEND - 1;
  buf_c2 = ((bestmv->as_mv.col + VP9_INTERP_EXTEND) > x->mv_col_max) ?
      (x->mv_col_max - bestmv->as_mv.col) : VP9_INTERP_EXTEND - 1;
John Koleszar's avatar
John Koleszar committed
286
287
288
289
290
  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;
291
#else
John Koleszar's avatar
John Koleszar committed
292
293
  unsigned char *y = *(d->base_pre) + d->pre + (bestmv->as_mv.row) * d->pre_stride + bestmv->as_mv.col;
  y_stride = d->pre_stride;
294
295
#endif

296
297
298
299
300
301
302
303
304
  rr = ref_mv->as_mv.row;
  rc = ref_mv->as_mv.col;
  br = bestmv->as_mv.row << 3;
  bc = bestmv->as_mv.col << 3;
  hstep = 4;
  minc = MAX(x->mv_col_min << 3, (ref_mv->as_mv.col) - ((1 << MV_MAX_BITS) - 1));
  maxc = MIN(x->mv_col_max << 3, (ref_mv->as_mv.col) + ((1 << MV_MAX_BITS) - 1));
  minr = MAX(x->mv_row_min << 3, (ref_mv->as_mv.row) - ((1 << MV_MAX_BITS) - 1));
  maxr = MIN(x->mv_row_max << 3, (ref_mv->as_mv.row) + ((1 << MV_MAX_BITS) - 1));
John Koleszar's avatar
John Koleszar committed
305
306
307
308
309
310
311
312
313
314
315
316
317
318

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

322
323
  // 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
324
325
326
327
328
329
  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

356
357
  // 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
358
359
360
361
362
363
  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

390
  if (xd->allow_high_precision_mv) {
391
    usehp = vp9_use_nmv_hp(&ref_mv->as_mv);
392
393
394
395
396
  } else {
    usehp = 0;
  }

  if (usehp) {
397
    hstep >>= 1;
John Koleszar's avatar
John Koleszar committed
398
399
400
401
402
    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
403

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

John Koleszar's avatar
John Koleszar committed
406
      switch (whichdir) {
John Koleszar's avatar
John Koleszar committed
407
        case 0:
John Koleszar's avatar
John Koleszar committed
408
409
          CHECK_BETTER(diag, tr - hstep, tc - hstep);
          break;
John Koleszar's avatar
John Koleszar committed
410
        case 1:
John Koleszar's avatar
John Koleszar committed
411
412
          CHECK_BETTER(diag, tr - hstep, tc + hstep);
          break;
John Koleszar's avatar
John Koleszar committed
413
        case 2:
John Koleszar's avatar
John Koleszar committed
414
415
          CHECK_BETTER(diag, tr + hstep, tc - hstep);
          break;
John Koleszar's avatar
John Koleszar committed
416
        case 3:
John Koleszar's avatar
John Koleszar committed
417
418
419
          CHECK_BETTER(diag, tr + hstep, tc + hstep);
          break;
      }
John Koleszar's avatar
John Koleszar committed
420

John Koleszar's avatar
John Koleszar committed
421
422
423
      // no reason to check the same one again.
      if (tr == br && tc == bc)
        break;
424

John Koleszar's avatar
John Koleszar committed
425
426
      tr = br;
      tc = bc;
427
    }
John Koleszar's avatar
John Koleszar committed
428
  }
429
430
  bestmv->as_mv.row = br;
  bestmv->as_mv.col = bc;
John Koleszar's avatar
John Koleszar committed
431

John Koleszar's avatar
John Koleszar committed
432
433
434
  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
435

John Koleszar's avatar
John Koleszar committed
436
  return besterr;
John Koleszar's avatar
John Koleszar committed
437
438
439
440
}
#undef MVC
#undef PRE
#undef DIST
441
#undef IFMVCV
John Koleszar's avatar
John Koleszar committed
442
443
444
#undef CHECK_BETTER
#undef MIN
#undef MAX
445

446
int vp9_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
Scott LaVarnway's avatar
Scott LaVarnway committed
447
448
                                 int_mv *bestmv, int_mv *ref_mv,
                                 int error_per_bit,
449
                                 const vp9_variance_fn_ptr_t *vfp,
450
                                 DEC_MVCOSTS, int *distortion,
John Koleszar's avatar
John Koleszar committed
451
452
453
454
455
456
457
458
459
460
461
462
463
                                 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;
464
  int usehp = xd->allow_high_precision_mv;
465

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

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

John Koleszar's avatar
John Koleszar committed
479
480
481
482
483
  // central mv
  bestmv->as_mv.row <<= 3;
  bestmv->as_mv.col <<= 3;
  startmv = *bestmv;
  orig_mv = *bestmv;
John Koleszar's avatar
John Koleszar committed
484

John Koleszar's avatar
John Koleszar committed
485
486
487
  // calculate central point error
  bestmse = vfp->vf(y, y_stride, z, b->src_stride, sse1);
  *distortion = bestmse;
488
  bestmse += mv_err_cost(bestmv, ref_mv, MVCOSTS, error_per_bit,
489
                         xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
490

John Koleszar's avatar
John Koleszar committed
491
492
493
494
  // 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);
495
  left = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit,
496
                               xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
497

John Koleszar's avatar
John Koleszar committed
498
499
500
501
502
503
  if (left < bestmse) {
    *bestmv = this_mv;
    bestmse = left;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
504

John Koleszar's avatar
John Koleszar committed
505
506
  this_mv.as_mv.col += 8;
  thismse = vfp->svf_halfpix_h(y, y_stride, z, b->src_stride, &sse);
507
  right = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit,
508
                                xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
509

John Koleszar's avatar
John Koleszar committed
510
511
512
513
514
515
516
517
518
519
520
  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);
521
  up = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit,
522
                             xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
523

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

John Koleszar's avatar
John Koleszar committed
531
532
  this_mv.as_mv.row += 8;
  thismse = vfp->svf_halfpix_v(y, y_stride, z, b->src_stride, &sse);
533
  down = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit,
534
                               xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
535

John Koleszar's avatar
John Koleszar committed
536
537
538
539
540
541
  if (down < bestmse) {
    *bestmv = this_mv;
    bestmse = down;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
542
543


John Koleszar's avatar
John Koleszar committed
544
545
546
547
548
  // 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
549

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

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

John Koleszar's avatar
John Koleszar committed
577
578
579
580
581
582
  if (diag < bestmse) {
    *bestmv = this_mv;
    bestmse = diag;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
583
584
585
586

//  }


John Koleszar's avatar
John Koleszar committed
587
588
589
590
591
  // 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
592

John Koleszar's avatar
John Koleszar committed
593
594
595
596
  if (bestmv->as_mv.col < startmv.as_mv.col) {
    y--;
    ycol_movedback = 1;
  }
John Koleszar's avatar
John Koleszar committed
597

John Koleszar's avatar
John Koleszar committed
598
  startmv = *bestmv;
John Koleszar's avatar
John Koleszar committed
599
600
601



John Koleszar's avatar
John Koleszar committed
602
603
  // go left then right and check error
  this_mv.as_mv.row = startmv.as_mv.row;
John Koleszar's avatar
John Koleszar committed
604

John Koleszar's avatar
John Koleszar committed
605
606
  if (startmv.as_mv.col & 7) {
    this_mv.as_mv.col = startmv.as_mv.col - 2;
607
608
609
    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
610
611
  } else {
    this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6;
612
613
    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
614
  }
John Koleszar's avatar
John Koleszar committed
615

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

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

John Koleszar's avatar
John Koleszar committed
626
  this_mv.as_mv.col += 4;
627
628
629
  thismse = vfp->svf(y, y_stride,
                     SP(this_mv.as_mv.col), SP(this_mv.as_mv.row),
                     z, b->src_stride, &sse);
630
  right = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit,
631
                                xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
632

John Koleszar's avatar
John Koleszar committed
633
634
635
636
637
638
  if (right < bestmse) {
    *bestmv = this_mv;
    bestmse = right;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
639

John Koleszar's avatar
John Koleszar committed
640
641
  // go up then down and check error
  this_mv.as_mv.col = startmv.as_mv.col;
John Koleszar's avatar
John Koleszar committed
642

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

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

John Koleszar's avatar
John Koleszar committed
657
658
659
660
661
662
  if (up < bestmse) {
    *bestmv = this_mv;
    bestmse = up;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
663

John Koleszar's avatar
John Koleszar committed
664
  this_mv.as_mv.row += 4;
665
666
  thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row),
                     z, b->src_stride, &sse);
667
  down = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit,
668
                               xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
669

John Koleszar's avatar
John Koleszar committed
670
671
672
673
674
675
  if (down < bestmse) {
    *bestmv = this_mv;
    bestmse = down;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
676
677


John Koleszar's avatar
John Koleszar committed
678
679
  // now check 1 more diagonal
  whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
John Koleszar's avatar
John Koleszar committed
680
681
682

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

John Koleszar's avatar
John Koleszar committed
685
  switch (whichdir) {
John Koleszar's avatar
John Koleszar committed
686
687
    case 0:

John Koleszar's avatar
John Koleszar committed
688
689
      if (startmv.as_mv.row & 7) {
        this_mv.as_mv.row -= 2;
John Koleszar's avatar
John Koleszar committed
690

John Koleszar's avatar
John Koleszar committed
691
692
693
694
695
696
        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
697
        }
John Koleszar's avatar
John Koleszar committed
698
699
700
701
702
703
704
705
706
      } 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
707
        }
John Koleszar's avatar
John Koleszar committed
708
      }
John Koleszar's avatar
John Koleszar committed
709

John Koleszar's avatar
John Koleszar committed
710
      break;
John Koleszar's avatar
John Koleszar committed
711
    case 1:
John Koleszar's avatar
John Koleszar committed
712
      this_mv.as_mv.col += 2;
John Koleszar's avatar
John Koleszar committed
713

John Koleszar's avatar
John Koleszar committed
714
715
716
717
718
719
720
      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
721

John Koleszar's avatar
John Koleszar committed
722
      break;
John Koleszar's avatar
John Koleszar committed
723
    case 2:
John Koleszar's avatar
John Koleszar committed
724
      this_mv.as_mv.row += 2;
John Koleszar's avatar
John Koleszar committed
725

John Koleszar's avatar
John Koleszar committed
726
727
      if (startmv.as_mv.col & 7) {
        this_mv.as_mv.col -= 2;
728
729
        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
730
731
      } else {
        this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6;
732
733
        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
734
      }
John Koleszar's avatar
John Koleszar committed
735

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

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

John Koleszar's avatar
John Koleszar committed
749
750
751
752
753
754
  if (diag < bestmse) {
    *bestmv = this_mv;
    bestmse = diag;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
755

756
  if (x->e_mbd.allow_high_precision_mv) {
757
    usehp = vp9_use_nmv_hp(&ref_mv->as_mv);
758
759
760
761
  } else {
    usehp = 0;
  }
  if (!usehp)
John Koleszar's avatar
John Koleszar committed
762
    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
  left = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit,
792
                               xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
793
794
795
796
797
798
799
800
801

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

  this_mv.as_mv.col += 2;
802
803
804
805
  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
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823

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

825
826
  up = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit,
                             xd->allow_high_precision_mv);
827

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

John Koleszar's avatar
John Koleszar committed
835
836
  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);
837
838
  down = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit,
                               xd->allow_high_precision_mv);
839

John Koleszar's avatar
John Koleszar committed
840
841
842
843
844
845
  if (down < bestmse) {
    *bestmv = this_mv;
    bestmse = down;
    *distortion = thismse;
    *sse1 = sse;
  }
846

John Koleszar's avatar
John Koleszar committed
847
848
  // now check 1 more diagonal
  whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
849
850
851

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

John Koleszar's avatar
John Koleszar committed
854
  switch (whichdir) {
855
856
    case 0:

John Koleszar's avatar
John Koleszar committed
857
858
      if (startmv.as_mv.row & 7) {
        this_mv.as_mv.row -= 1;
859

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

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

John Koleszar's avatar
John Koleszar committed
883
884
885
886
887
888
889
      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);
      }
890

John Koleszar's avatar
John Koleszar committed
891
      break;
892
    case 2:
John Koleszar's avatar
John Koleszar committed
893
      this_mv.as_mv.row += 1;
894

John Koleszar's avatar
John Koleszar committed
895
896
897
898
899
900
901
      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);
      }
902

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

911
912
  diag = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit,
                               xd->allow_high_precision_mv);
913

John Koleszar's avatar
John Koleszar committed
914
915
916
917
918
919
  if (diag < bestmse) {
    *bestmv = this_mv;
    bestmse = diag;
    *distortion = thismse;
    *sse1 = sse;
  }
920

John Koleszar's avatar
John Koleszar committed
921
  return bestmse;
John Koleszar's avatar
John Koleszar committed
922
923
}

924
925
#undef SP

926
int vp9_find_best_half_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
Scott LaVarnway's avatar
Scott LaVarnway committed
927
928
                                  int_mv *bestmv, int_mv *ref_mv,
                                  int error_per_bit,
929
                                  const vp9_variance_fn_ptr_t *vfp,
930
931
                                  DEC_MVCOSTS,
                                  int *distortion,
John Koleszar's avatar
John Koleszar committed
932
933
934
935
936
937
938
939
940
941
942
                                  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;
943

944
#if !CONFIG_SUPERBLOCKS && (ARCH_X86 || ARCH_X86_64)
945
946
  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
947
  unsigned char *y;
948

John Koleszar's avatar
John Koleszar committed
949
950
951
952
  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;
953
#else
954
955
  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
956
  y_stride = d->pre_stride;
957
#endif
John Koleszar's avatar
John Koleszar committed
958

John Koleszar's avatar
John Koleszar committed
959
960
961
962
  // central mv
  bestmv->as_mv.row <<= 3;
  bestmv->as_mv.col <<= 3;
  startmv = *bestmv;
John Koleszar's avatar
John Koleszar committed
963

John Koleszar's avatar
John Koleszar committed
964
965
966
  // calculate central point error
  bestmse = vfp->vf(y, y_stride, z, b->src_stride, sse1);
  *distortion = bestmse;
967
  bestmse += mv_err_cost(bestmv, ref_mv, MVCOSTS, error_per_bit,
968
                         xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
969

John Koleszar's avatar
John Koleszar committed
970
971
972
973
  // 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);
974
  left = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit,
975
                               xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
976

John Koleszar's avatar
John Koleszar committed
977
978
979
980
981
982
  if (left < bestmse) {
    *bestmv = this_mv;
    bestmse = left;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
983

John Koleszar's avatar
John Koleszar committed
984
985
  this_mv.as_mv.col += 8;
  thismse = vfp->svf_halfpix_h(y, y_stride, z, b->src_stride, &sse);
986
  right = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit,
987
                                xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
988

John Koleszar's avatar
John Koleszar committed
989
990
991
992
993
994
995
996
997
998
999
  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);
1000
  up = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit,
1001
                             xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
1002

John Koleszar's avatar
John Koleszar committed
1003
1004
1005
1006
1007
1008
  if (up < bestmse) {
    *bestmv = this_mv;
    bestmse = up;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
1009

John Koleszar's avatar
John Koleszar committed
1010
1011
  this_mv.as_mv.row += 8;
  thismse = vfp->svf_halfpix_v(y, y_stride, z, b->src_stride, &sse);
1012
  down = thismse + mv_err_cost(&this_mv, ref_mv, MVCOSTS, error_per_bit,
1013
                               xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
1014

John Koleszar's avatar
John Koleszar committed
1015
1016
1017
1018
1019
1020
  if (down < bestmse) {
    *bestmv = this_mv;
    bestmse = down;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
1021

John Koleszar's avatar
John Koleszar committed
1022
1023
1024
  // now check 1 more diagonal -
  whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
  this_mv = startmv;
John Koleszar's avatar
John Koleszar committed
1025

John Koleszar's avatar
John Koleszar committed
1026
  switch (whichdir) {
John Koleszar's avatar
John Koleszar committed
1027
    case 0:
John Koleszar's avatar
John Koleszar committed
1028
1029
1030
1031
      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
1032
    case 1:
John Koleszar's avatar
John Koleszar committed
1033
1034
1035
1036
      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
1037
    case 2:
John Koleszar's avatar
John Koleszar committed
1038
1039
1040
1041
      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
1042
    case 3:
Yunqing Wang's avatar
Yunqing Wang committed
1043
    default:
John Koleszar's avatar
John Koleszar committed
1044
1045
1046
1047
1048
      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
1049

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

John Koleszar's avatar
John Koleszar committed
1053
1054
1055
1056
1057
1058
  if (diag < bestmse) {
    *bestmv = this_mv;
    bestmse = diag;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
1059

John Koleszar's avatar
John Koleszar committed
1060
  return bestmse;
John Koleszar's avatar
John Koleszar committed
1061
1062
}