vp9_mcomp.c 65.6 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/vp9_onyx_int.h"
13
#include "vp9/encoder/vp9_mcomp.h"
John Koleszar's avatar
John Koleszar committed
14
#include "vpx_mem/vpx_mem.h"
15
#include "./vpx_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/vp9_findnearmv.h"
Ronald S. Bultje's avatar
Ronald S. Bultje committed
20
#include "vp9/common/vp9_common.h"
John Koleszar's avatar
John Koleszar committed
21
22
23
24
25
26

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

27
void vp9_clamp_mv_min_max(MACROBLOCK *x, int_mv *ref_mv) {
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
  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;
}

46
int vp9_mv_bit_cost(int_mv *mv, int_mv *ref, int *mvjcost, int *mvcost[2],
47
                    int Weight, int ishp) {
48
49
50
  MV v;
  v.row = (mv->as_mv.row - ref->as_mv.row);
  v.col = (mv->as_mv.col - ref->as_mv.col);
51
  return ((mvjcost[vp9_get_mv_joint(v)] +
52
53
           mvcost[0][v.row] + mvcost[1][v.col]) *
          Weight) >> 7;
John Koleszar's avatar
John Koleszar committed
54
55
}

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

69
70
static int mvsad_err_cost(int_mv *mv, int_mv *ref, int *mvjsadcost,
                          int *mvsadcost[2], int error_per_bit) {
71
72
73
74
75

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

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


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

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

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

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

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

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

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

John Koleszar's avatar
John Koleszar committed
190
191
192
193
194
195
    // Contract.
    Len /= 2;
  }

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

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

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

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

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

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

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

245
int vp9_find_best_sub_pixel_step_iteratively(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
Scott LaVarnway's avatar
Scott LaVarnway committed
246
247
                                             int_mv *bestmv, int_mv *ref_mv,
                                             int error_per_bit,
248
                                             const vp9_variance_fn_ptr_t *vfp,
249
                                             int *mvjcost, int *mvcost[2],
250
                                             int *distortion,
John Koleszar's avatar
John Koleszar committed
251
                                             unsigned int *sse1) {
252
  uint8_t *z = (*(b->base_src) + b->src);
John Koleszar's avatar
John Koleszar committed
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
  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;
268
  int usehp = xd->allow_high_precision_mv;
John Koleszar's avatar
John Koleszar committed
269

270
271
  uint8_t *y = *(d->base_pre) + d->pre +
               (bestmv->as_mv.row) * d->pre_stride + bestmv->as_mv.col;
John Koleszar's avatar
John Koleszar committed
272
  y_stride = d->pre_stride;
273

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

  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;
297
  besterr += mv_err_cost(bestmv, ref_mv, mvjcost, mvcost,
298
                         error_per_bit, xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
299

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

John Koleszar's avatar
John Koleszar committed
414
  return besterr;
John Koleszar's avatar
John Koleszar committed
415
416
417
418
}
#undef MVC
#undef PRE
#undef DIST
419
#undef IFMVCV
John Koleszar's avatar
John Koleszar committed
420
421
422
#undef CHECK_BETTER
#undef MIN
#undef MAX
423

424
int vp9_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
Scott LaVarnway's avatar
Scott LaVarnway committed
425
426
                                 int_mv *bestmv, int_mv *ref_mv,
                                 int error_per_bit,
427
                                 const vp9_variance_fn_ptr_t *vfp,
428
                                 int *mvjcost, int *mvcost[2], int *distortion,
John Koleszar's avatar
John Koleszar committed
429
430
431
432
433
434
                                 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;
435
  uint8_t *z = (*(b->base_src) + b->src);
John Koleszar's avatar
John Koleszar committed
436
437
438
439
440
441
  int left, right, up, down, diag;
  unsigned int sse;
  int whichdir;
  int thismse;
  int y_stride;
  MACROBLOCKD *xd = &x->e_mbd;
442
  int usehp = xd->allow_high_precision_mv;
443

444
445
  uint8_t *y = *(d->base_pre) + d->pre +
               (bestmv->as_mv.row) * d->pre_stride + bestmv->as_mv.col;
John Koleszar's avatar
John Koleszar committed
446
  y_stride = d->pre_stride;
John Koleszar's avatar
John Koleszar committed
447

John Koleszar's avatar
John Koleszar committed
448
449
450
451
452
  // central mv
  bestmv->as_mv.row <<= 3;
  bestmv->as_mv.col <<= 3;
  startmv = *bestmv;
  orig_mv = *bestmv;
John Koleszar's avatar
John Koleszar committed
453

John Koleszar's avatar
John Koleszar committed
454
455
456
  // calculate central point error
  bestmse = vfp->vf(y, y_stride, z, b->src_stride, sse1);
  *distortion = bestmse;
457
  bestmse += mv_err_cost(bestmv, ref_mv, mvjcost, mvcost, error_per_bit,
458
                         xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
459

John Koleszar's avatar
John Koleszar committed
460
461
462
463
  // 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);
464
  left = thismse + mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost, error_per_bit,
465
                               xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
466

John Koleszar's avatar
John Koleszar committed
467
468
469
470
471
472
  if (left < bestmse) {
    *bestmv = this_mv;
    bestmse = left;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
473

John Koleszar's avatar
John Koleszar committed
474
475
  this_mv.as_mv.col += 8;
  thismse = vfp->svf_halfpix_h(y, y_stride, z, b->src_stride, &sse);
476
477
  right = thismse + mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost,
                                error_per_bit, xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
478

John Koleszar's avatar
John Koleszar committed
479
480
481
482
483
484
485
486
487
488
489
  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);
490
  up = thismse + mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost, error_per_bit,
491
                             xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
492

John Koleszar's avatar
John Koleszar committed
493
494
495
496
497
498
  if (up < bestmse) {
    *bestmv = this_mv;
    bestmse = up;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
499

John Koleszar's avatar
John Koleszar committed
500
501
  this_mv.as_mv.row += 8;
  thismse = vfp->svf_halfpix_v(y, y_stride, z, b->src_stride, &sse);
502
  down = thismse + mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost, error_per_bit,
503
                               xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
504

John Koleszar's avatar
John Koleszar committed
505
506
507
508
509
510
  if (down < bestmse) {
    *bestmv = this_mv;
    bestmse = down;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
511
512


John Koleszar's avatar
John Koleszar committed
513
514
515
516
517
  // 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
518

John Koleszar's avatar
John Koleszar committed
519
  switch (whichdir) {
John Koleszar's avatar
John Koleszar committed
520
    case 0:
John Koleszar's avatar
John Koleszar committed
521
522
523
524
      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
525
    case 1:
John Koleszar's avatar
John Koleszar committed
526
527
528
529
      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
530
    case 2:
John Koleszar's avatar
John Koleszar committed
531
532
533
534
      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
535
    case 3:
536
    default:
John Koleszar's avatar
John Koleszar committed
537
538
539
540
541
      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
542

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

John Koleszar's avatar
John Koleszar committed
546
547
548
549
550
551
  if (diag < bestmse) {
    *bestmv = this_mv;
    bestmse = diag;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
552
553
554
555

//  }


John Koleszar's avatar
John Koleszar committed
556
557
558
559
560
  // 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
561

John Koleszar's avatar
John Koleszar committed
562
563
564
565
  if (bestmv->as_mv.col < startmv.as_mv.col) {
    y--;
    ycol_movedback = 1;
  }
John Koleszar's avatar
John Koleszar committed
566

John Koleszar's avatar
John Koleszar committed
567
  startmv = *bestmv;
John Koleszar's avatar
John Koleszar committed
568
569
570



John Koleszar's avatar
John Koleszar committed
571
572
  // go left then right and check error
  this_mv.as_mv.row = startmv.as_mv.row;
John Koleszar's avatar
John Koleszar committed
573

John Koleszar's avatar
John Koleszar committed
574
575
  if (startmv.as_mv.col & 7) {
    this_mv.as_mv.col = startmv.as_mv.col - 2;
576
577
578
    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
579
580
  } else {
    this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6;
581
582
    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
583
  }
John Koleszar's avatar
John Koleszar committed
584

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

John Koleszar's avatar
John Koleszar committed
588
589
590
591
592
593
  if (left < bestmse) {
    *bestmv = this_mv;
    bestmse = left;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
594

John Koleszar's avatar
John Koleszar committed
595
  this_mv.as_mv.col += 4;
596
597
598
  thismse = vfp->svf(y, y_stride,
                     SP(this_mv.as_mv.col), SP(this_mv.as_mv.row),
                     z, b->src_stride, &sse);
599
600
  right = thismse + mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost,
                                error_per_bit, xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
601

John Koleszar's avatar
John Koleszar committed
602
603
604
605
606
607
  if (right < bestmse) {
    *bestmv = this_mv;
    bestmse = right;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
608

John Koleszar's avatar
John Koleszar committed
609
610
  // go up then down and check error
  this_mv.as_mv.col = startmv.as_mv.col;
John Koleszar's avatar
John Koleszar committed
611

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

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

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

John Koleszar's avatar
John Koleszar committed
633
  this_mv.as_mv.row += 4;
634
635
  thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row),
                     z, b->src_stride, &sse);
636
  down = thismse + mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost, error_per_bit,
637
                               xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
638

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


John Koleszar's avatar
John Koleszar committed
647
648
  // now check 1 more diagonal
  whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
John Koleszar's avatar
John Koleszar committed
649
650
651

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

John Koleszar's avatar
John Koleszar committed
654
  switch (whichdir) {
John Koleszar's avatar
John Koleszar committed
655
656
    case 0:

John Koleszar's avatar
John Koleszar committed
657
658
      if (startmv.as_mv.row & 7) {
        this_mv.as_mv.row -= 2;
John Koleszar's avatar
John Koleszar committed
659

John Koleszar's avatar
John Koleszar committed
660
661
662
663
664
665
        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
666
        }
John Koleszar's avatar
John Koleszar committed
667
668
669
670
671
672
673
674
675
      } 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
676
        }
John Koleszar's avatar
John Koleszar committed
677
      }
John Koleszar's avatar
John Koleszar committed
678

John Koleszar's avatar
John Koleszar committed
679
      break;
John Koleszar's avatar
John Koleszar committed
680
    case 1:
John Koleszar's avatar
John Koleszar committed
681
      this_mv.as_mv.col += 2;
John Koleszar's avatar
John Koleszar committed
682

John Koleszar's avatar
John Koleszar committed
683
684
685
686
687
688
689
      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
690

John Koleszar's avatar
John Koleszar committed
691
      break;
John Koleszar's avatar
John Koleszar committed
692
    case 2:
John Koleszar's avatar
John Koleszar committed
693
      this_mv.as_mv.row += 2;
John Koleszar's avatar
John Koleszar committed
694

John Koleszar's avatar
John Koleszar committed
695
696
      if (startmv.as_mv.col & 7) {
        this_mv.as_mv.col -= 2;
697
698
        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
699
700
      } else {
        this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6;
701
702
        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
703
      }
John Koleszar's avatar
John Koleszar committed
704

John Koleszar's avatar
John Koleszar committed
705
      break;
John Koleszar's avatar
John Koleszar committed
706
    case 3:
John Koleszar's avatar
John Koleszar committed
707
708
      this_mv.as_mv.col += 2;
      this_mv.as_mv.row += 2;
709
710
711
      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
712
713
      break;
  }
John Koleszar's avatar
John Koleszar committed
714

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

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

725
  if (x->e_mbd.allow_high_precision_mv) {
726
    usehp = vp9_use_nmv_hp(&ref_mv->as_mv);
727
728
729
730
  } else {
    usehp = 0;
  }
  if (!usehp)
John Koleszar's avatar
John Koleszar committed
731
    return bestmse;
732

John Koleszar's avatar
John Koleszar committed
733
734
735
736
737
  /* Now do 1/8th pixel */
  if (bestmv->as_mv.row < orig_mv.as_mv.row && !yrow_movedback) {
    y -= y_stride;
    yrow_movedback = 1;
  }
738

John Koleszar's avatar
John Koleszar committed
739
740
741
742
  if (bestmv->as_mv.col < orig_mv.as_mv.col && !ycol_movedback) {
    y--;
    ycol_movedback = 1;
  }
743

John Koleszar's avatar
John Koleszar committed
744
  startmv = *bestmv;
745

John Koleszar's avatar
John Koleszar committed
746
747
  // go left then right and check error
  this_mv.as_mv.row = startmv.as_mv.row;
748

John Koleszar's avatar
John Koleszar committed
749
750
  if (startmv.as_mv.col & 7) {
    this_mv.as_mv.col = startmv.as_mv.col - 1;
751
752
753
    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
754
755
  } else {
    this_mv.as_mv.col = (startmv.as_mv.col - 8) | 7;
756
757
    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
758
759
  }

760
  left = thismse + mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost, error_per_bit,
761
                               xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
762
763
764
765
766
767
768
769
770

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

  this_mv.as_mv.col += 2;
771
772
  thismse = vfp->svf(y, y_stride, SP(this_mv.as_mv.col), SP(this_mv.as_mv.row),
                     z, b->src_stride, &sse);
773
774
  right = thismse + mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost,
                                error_per_bit, xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792

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

794
  up = thismse + mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost, error_per_bit,
795
                             xd->allow_high_precision_mv);
796

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

John Koleszar's avatar
John Koleszar committed
804
805
  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);
806
  down = thismse + mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost, error_per_bit,
807
                               xd->allow_high_precision_mv);
808

John Koleszar's avatar
John Koleszar committed
809
810
811
812
813
814
  if (down < bestmse) {
    *bestmv = this_mv;
    bestmse = down;
    *distortion = thismse;
    *sse1 = sse;
  }
815

John Koleszar's avatar
John Koleszar committed
816
817
  // now check 1 more diagonal
  whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
818
819
820

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

John Koleszar's avatar
John Koleszar committed
823
  switch (whichdir) {
824
825
    case 0:

John Koleszar's avatar
John Koleszar committed
826
827
      if (startmv.as_mv.row & 7) {
        this_mv.as_mv.row -= 1;
828

John Koleszar's avatar
John Koleszar committed
829
830
831
832
833
834
        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);;
835
        }
John Koleszar's avatar
John Koleszar committed
836
837
838
839
840
841
842
843
844
      } 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);
845
        }
John Koleszar's avatar
John Koleszar committed
846
      }
847

John Koleszar's avatar
John Koleszar committed
848
      break;
849
    case 1:
John Koleszar's avatar
John Koleszar committed
850
      this_mv.as_mv.col += 1;
851

John Koleszar's avatar
John Koleszar committed
852
853
854
855
856
857
858
      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);
      }
859

John Koleszar's avatar
John Koleszar committed
860
      break;
861
    case 2:
John Koleszar's avatar
John Koleszar committed
862
      this_mv.as_mv.row += 1;
863

John Koleszar's avatar
John Koleszar committed
864
865
866
867
868
869
870
      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);
      }
871

John Koleszar's avatar
John Koleszar committed
872
      break;
873
    case 3:
John Koleszar's avatar
John Koleszar committed
874
875
876
877
878
      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;
  }
879

880
  diag = thismse + mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost, error_per_bit,
881
                               xd->allow_high_precision_mv);
882

John Koleszar's avatar
John Koleszar committed
883
884
885
886
887
888
  if (diag < bestmse) {
    *bestmv = this_mv;
    bestmse = diag;
    *distortion = thismse;
    *sse1 = sse;
  }
889

John Koleszar's avatar
John Koleszar committed
890
  return bestmse;
John Koleszar's avatar
John Koleszar committed
891
892
}

893
894
#undef SP

895
int vp9_find_best_half_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
Scott LaVarnway's avatar
Scott LaVarnway committed
896
897
                                  int_mv *bestmv, int_mv *ref_mv,
                                  int error_per_bit,
898
                                  const vp9_variance_fn_ptr_t *vfp,
899
                                  int *mvjcost, int *mvcost[2],
900
                                  int *distortion,
John Koleszar's avatar
John Koleszar committed
901
902
903
904
                                  unsigned int *sse1) {
  int bestmse = INT_MAX;
  int_mv startmv;
  int_mv this_mv;
905
  uint8_t *z = (*(b->base_src) + b->src);
John Koleszar's avatar
John Koleszar committed
906
907
908
909
910
911
  int left, right, up, down, diag;
  unsigned int sse;
  int whichdir;
  int thismse;
  int y_stride;
  MACROBLOCKD *xd = &x->e_mbd;
912

913
  uint8_t *y = *(d->base_pre) + d->pre +
914
      (bestmv->as_mv.row) * d->pre_stride + bestmv->as_mv.col;
John Koleszar's avatar
John Koleszar committed
915
  y_stride = d->pre_stride;
John Koleszar's avatar
John Koleszar committed
916

John Koleszar's avatar
John Koleszar committed
917
918
919
920
  // central mv
  bestmv->as_mv.row <<= 3;
  bestmv->as_mv.col <<= 3;
  startmv = *bestmv;
John Koleszar's avatar
John Koleszar committed
921

John Koleszar's avatar
John Koleszar committed
922
923
924
  // calculate central point error
  bestmse = vfp->vf(y, y_stride, z, b->src_stride, sse1);
  *distortion = bestmse;
925
  bestmse += mv_err_cost(bestmv, ref_mv, mvjcost, mvcost, error_per_bit,
926
                         xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
927

John Koleszar's avatar
John Koleszar committed
928
929
930
931
  // 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);
932
  left = thismse + mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost, error_per_bit,
933
                               xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
934

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

John Koleszar's avatar
John Koleszar committed
942
943
  this_mv.as_mv.col += 8;
  thismse = vfp->svf_halfpix_h(y, y_stride, z, b->src_stride, &sse);
944
945
  right = thismse + mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost,
                                error_per_bit, xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
946

John Koleszar's avatar
John Koleszar committed
947
948
949
950
951
952
953
954
955
956
957
  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);
958
  up = thismse + mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost, error_per_bit,
959
                             xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
960

John Koleszar's avatar
John Koleszar committed
961
962
963
964
965
966
  if (up < bestmse) {
    *bestmv = this_mv;
    bestmse = up;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
967

John Koleszar's avatar
John Koleszar committed
968
969
  this_mv.as_mv.row += 8;
  thismse = vfp->svf_halfpix_v(y, y_stride, z, b->src_stride, &sse);
970
  down = thismse + mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost, error_per_bit,
971
                               xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
972

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

John Koleszar's avatar
John Koleszar committed
980
981
982
  // now check 1 more diagonal -
  whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
  this_mv = startmv;
John Koleszar's avatar
John Koleszar committed
983

John Koleszar's avatar
John Koleszar committed
984
  switch (whichdir) {
John Koleszar's avatar
John Koleszar committed
985
    case 0:
John Koleszar's avatar
John Koleszar committed
986
987
988
989
      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
990
    case 1:
John Koleszar's avatar
John Koleszar committed
991
992
993
994
      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
995
    case 2:
John Koleszar's avatar
John Koleszar committed
996
997
998
999
      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
1000
    case 3:
Yunqing Wang's avatar
Yunqing Wang committed
1001
    default:
John Koleszar's avatar
John Koleszar committed
1002
1003
1004
1005
1006
      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
1007

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

John Koleszar's avatar
John Koleszar committed
1011
1012
1013
1014
1015
1016
  if (diag < bestmse) {
    *bestmv = this_mv;
    bestmse = diag;
    *distortion = thismse;
    *sse1 = sse;
  }
John Koleszar's avatar
John Koleszar committed
1017

John Koleszar's avatar
John Koleszar committed
1018
  return bestmse;
John Koleszar's avatar
John Koleszar committed
1019
1020
}

Yunqing Wang's avatar
Yunqing Wang committed
1021
#define CHECK_BOUNDS(range) \
John Koleszar's avatar
John Koleszar committed
1022
  {\
Yunqing Wang's avatar
Yunqing Wang committed
1023
1024
1025
1026
1027
    all_in = 1;\
    all_in &= ((br-range) >= x->mv_row_min);\
    all_in &= ((br+range) <= x->mv_row_max);\
    all_in &= ((bc-range) >= x->mv_col_min);\
    all_in &= ((bc+range) <= x->mv_col_max);\
John Koleszar's avatar
John Koleszar committed
1028
  }
Yunqing Wang's avatar
Yunqing Wang committed
1029
1030

#define CHECK_POINT \
John Koleszar's avatar
John Koleszar committed
1031
  {\
Yunqing Wang's avatar
Yunqing Wang committed
1032
1033
1034
1035
    if (this_mv.as_mv.col < x->mv_col_min) continue;\
    if (this_mv.as_mv.col > x->mv_col_max) continue;\
    if (this_mv.as_mv.row < x->mv_row_min) continue;\
    if (this_mv.as_mv.row > x->mv_row_max) continue;\
John Koleszar's avatar
John Koleszar committed
1036
  }
Yunqing Wang's avatar
Yunqing Wang committed
1037
1038

#define CHECK_BETTER \
John Koleszar's avatar
John Koleszar committed
1039
  {\
Yunqing Wang's avatar
Yunqing Wang committed
1040
1041
    if (thissad < bestsad)\
    {\
1042
1043
      thissad += mvsad_err_cost(&this_mv, &fcenter_mv, mvjsadcost, mvsadcost, \
                                sad_per_bit);\
John Koleszar's avatar
John Koleszar committed
1044
1045
1046
1047
1048
      if (thissad < bestsad)\
      {\
        bestsad = thissad;\
        best_site = i;\
      }\
Yunqing Wang's avatar