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


Johann's avatar
Johann committed
12 13
#include "./vp8_rtcd.h"
#include "./vpx_dsp_rtcd.h"
Yunqing Wang's avatar
Yunqing Wang committed
14
#include "onyx_int.h"
John Koleszar's avatar
John Koleszar committed
15 16
#include "mcomp.h"
#include "vpx_mem/vpx_mem.h"
17
#include "vpx_config.h"
John Koleszar's avatar
John Koleszar committed
18 19 20
#include <stdio.h>
#include <limits.h>
#include <math.h>
21
#include "vp8/common/findnearmv.h"
22
#include "vp8/common/common.h"
23
#include "vpx_dsp/vpx_dsp_common.h"
John Koleszar's avatar
John Koleszar committed
24

25
#ifdef VP8_ENTROPY_STATS
John Koleszar's avatar
John Koleszar committed
26 27 28 29
static int mv_ref_ct [31] [4] [2];
static int mv_mode_cts [4] [2];
#endif

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

Scott LaVarnway's avatar
Scott LaVarnway committed
42
static int mv_err_cost(int_mv *mv, int_mv *ref, int *mvcost[2], int error_per_bit)
John Koleszar's avatar
John Koleszar committed
43
{
John Koleszar's avatar
John Koleszar committed
44
    /* Ignore mv costing if mvcost is NULL */
45 46 47 48 49
    if (mvcost)
        return ((mvcost[0][(mv->as_mv.row - ref->as_mv.row) >> 1] +
                 mvcost[1][(mv->as_mv.col - ref->as_mv.col) >> 1])
                 * error_per_bit + 128) >> 8;
    return 0;
John Koleszar's avatar
John Koleszar committed
50 51
}

Scott LaVarnway's avatar
Scott LaVarnway committed
52
static int mvsad_err_cost(int_mv *mv, int_mv *ref, int *mvsadcost[2], int error_per_bit)
53
{
John Koleszar's avatar
John Koleszar committed
54 55
    /* Calculate sad error cost on full pixel basis. */
    /* Ignore mv costing if mvsadcost is NULL */
56 57 58 59 60
    if (mvsadcost)
        return ((mvsadcost[0][(mv->as_mv.row - ref->as_mv.row)] +
                 mvsadcost[1][(mv->as_mv.col - ref->as_mv.col)])
                * error_per_bit + 128) >> 8;
    return 0;
John Koleszar's avatar
John Koleszar committed
61 62 63 64 65 66 67 68
}

void vp8_init_dsmotion_compensation(MACROBLOCK *x, int stride)
{
    int Len;
    int search_site_count = 0;


John Koleszar's avatar
John Koleszar committed
69
    /* Generate offsets for 4 search sites per step. */
John Koleszar's avatar
John Koleszar committed
70 71 72 73 74 75 76 77 78
    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
79
        /* Compute offsets for search sites. */
John Koleszar's avatar
John Koleszar committed
80 81 82 83 84
        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++;

John Koleszar's avatar
John Koleszar committed
85
        /* Compute offsets for search sites. */
John Koleszar's avatar
John Koleszar committed
86 87 88 89 90
        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++;

John Koleszar's avatar
John Koleszar committed
91
        /* Compute offsets for search sites. */
John Koleszar's avatar
John Koleszar committed
92 93 94 95 96
        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
97
        /* Compute offsets for search sites. */
John Koleszar's avatar
John Koleszar committed
98 99 100 101 102
        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
103
        /* Contract. */
John Koleszar's avatar
John Koleszar committed
104 105 106 107 108 109 110 111 112 113 114 115
        Len /= 2;
    }

    x->ss_count = search_site_count;
    x->searches_per_step = 4;
}

void vp8_init3smotion_compensation(MACROBLOCK *x, int stride)
{
    int Len;
    int search_site_count = 0;

John Koleszar's avatar
John Koleszar committed
116
    /* Generate offsets for 8 search sites per step. */
John Koleszar's avatar
John Koleszar committed
117 118 119 120 121 122 123 124 125
    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
126
        /* Compute offsets for search sites. */
John Koleszar's avatar
John Koleszar committed
127 128 129 130 131
        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++;

John Koleszar's avatar
John Koleszar committed
132
        /* Compute offsets for search sites. */
John Koleszar's avatar
John Koleszar committed
133 134 135 136 137
        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++;

John Koleszar's avatar
John Koleszar committed
138
        /* Compute offsets for search sites. */
John Koleszar's avatar
John Koleszar committed
139 140 141 142 143
        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
144
        /* Compute offsets for search sites. */
John Koleszar's avatar
John Koleszar committed
145 146 147 148 149
        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
150
        /* Compute offsets for search sites. */
John Koleszar's avatar
John Koleszar committed
151 152 153 154 155
        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
156
        /* Compute offsets for search sites. */
John Koleszar's avatar
John Koleszar committed
157 158 159 160 161
        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
162
        /* Compute offsets for search sites. */
John Koleszar's avatar
John Koleszar committed
163 164 165 166 167
        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
168
        /* Compute offsets for search sites. */
John Koleszar's avatar
John Koleszar committed
169 170 171 172 173 174
        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
175
        /* Contract. */
John Koleszar's avatar
John Koleszar committed
176 177 178 179 180 181 182
        Len /= 2;
    }

    x->ss_count = search_site_count;
    x->searches_per_step = 8;
}

183 184 185 186 187 188 189 190 191
/*
 * 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.
 */
John Koleszar's avatar
John Koleszar committed
192 193 194 195 196 197 198 199 200

/* estimated cost of a motion vector (r,c) */
#define MVC(r,c) (mvcost ? ((mvcost[0][(r)-rr] + mvcost[1][(c) - rc]) * error_per_bit + 128 )>>8 : 0)
/* pointer to predictor base of a motionvector */
#define PRE(r,c) (y + (((r)>>2) * y_stride + ((c)>>2) -(offset)))
/* convert motion vector component to offset for svf calc */
#define SP(x) (((x)&3)<<1)
/* returns subpixel variance error function. */
#define DIST(r,c) vfp->svf( PRE(r,c), y_stride, SP(c),SP(r), z,b->src_stride,&sse)
John Koleszar's avatar
John Koleszar committed
201
#define IFMVCV(r,c,s,e) if ( c >= minc && c <= maxc && r >= minr && r <= maxr) s else e;
John Koleszar's avatar
John Koleszar committed
202 203 204
/* returns distortion + motion vector cost */
#define ERR(r,c) (MVC(r,c)+DIST(r,c))
/* checks if (r,c) has better score than previous best */
Johann's avatar
Johann committed
205
#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=UINT_MAX;)
John Koleszar's avatar
John Koleszar committed
206

Scott LaVarnway's avatar
Scott LaVarnway committed
207 208 209 210 211 212
int vp8_find_best_sub_pixel_step_iteratively(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
                                             int_mv *bestmv, int_mv *ref_mv,
                                             int error_per_bit,
                                             const vp8_variance_fn_ptr_t *vfp,
                                             int *mvcost[2], int *distortion,
                                             unsigned int *sse1)
John Koleszar's avatar
John Koleszar committed
213 214 215
{
    unsigned char *z = (*(b->base_src) + b->src);

Scott LaVarnway's avatar
Scott LaVarnway committed
216
    int rr = ref_mv->as_mv.row >> 1, rc = ref_mv->as_mv.col >> 1;
Yaowu Xu's avatar
Yaowu Xu committed
217
    int br = bestmv->as_mv.row * 4, bc = bestmv->as_mv.col * 4;
John Koleszar's avatar
John Koleszar committed
218
    int tr = br, tc = bc;
Johann's avatar
Johann committed
219
    unsigned int besterr;
John Koleszar's avatar
John Koleszar committed
220 221 222 223 224
    unsigned int left, right, up, down, diag;
    unsigned int sse;
    unsigned int whichdir;
    unsigned int halfiters = 4;
    unsigned int quarteriters = 4;
225
    int thismse;
John Koleszar's avatar
John Koleszar committed
226

227 228 229 230 231 232 233 234
    int minc = VPXMAX(x->mv_col_min * 4,
                      (ref_mv->as_mv.col >> 1) - ((1 << mvlong_width) - 1));
    int maxc = VPXMIN(x->mv_col_max * 4,
                      (ref_mv->as_mv.col >> 1) + ((1 << mvlong_width) - 1));
    int minr = VPXMAX(x->mv_row_min * 4,
                      (ref_mv->as_mv.row >> 1) - ((1 << mvlong_width) - 1));
    int maxr = VPXMIN(x->mv_row_max * 4,
                      (ref_mv->as_mv.row >> 1) + ((1 << mvlong_width) - 1));
John Koleszar's avatar
John Koleszar committed
235

236 237
    int y_stride;
    int offset;
Scott LaVarnway's avatar
Scott LaVarnway committed
238 239 240
    int pre_stride = x->e_mbd.pre.y_stride;
    unsigned char *base_pre = x->e_mbd.pre.y_buffer;

241 242 243

#if ARCH_X86 || ARCH_X86_64
    MACROBLOCKD *xd = &x->e_mbd;
244
    unsigned char *y_0 = base_pre + d->offset + (bestmv->as_mv.row) * pre_stride + bestmv->as_mv.col;
245
    unsigned char *y;
246
    int buf_r1, buf_r2, buf_c1;
247

John Koleszar's avatar
John Koleszar committed
248
    /* Clamping to avoid out-of-range data access */
249 250 251 252 253 254
    buf_r1 = ((bestmv->as_mv.row - 3) < x->mv_row_min)?(bestmv->as_mv.row - x->mv_row_min):3;
    buf_r2 = ((bestmv->as_mv.row + 3) > x->mv_row_max)?(x->mv_row_max - bestmv->as_mv.row):3;
    buf_c1 = ((bestmv->as_mv.col - 3) < x->mv_col_min)?(bestmv->as_mv.col - x->mv_col_min):3;
    y_stride = 32;

    /* Copy to intermediate buffer before searching. */
255
    vfp->copymem(y_0 - buf_c1 - pre_stride*buf_r1, pre_stride, xd->y_buf, y_stride, 16+buf_r1+buf_r2);
256 257
    y = xd->y_buf + y_stride*buf_r1 +buf_c1;
#else
Scott LaVarnway's avatar
Scott LaVarnway committed
258 259
    unsigned char *y = base_pre + d->offset + (bestmv->as_mv.row) * pre_stride + bestmv->as_mv.col;
    y_stride = pre_stride;
260 261 262 263
#endif

    offset = (bestmv->as_mv.row) * y_stride + bestmv->as_mv.col;

John Koleszar's avatar
John Koleszar committed
264
    /* central mv */
Yaowu Xu's avatar
Yaowu Xu committed
265 266
    bestmv->as_mv.row *= 8;
    bestmv->as_mv.col *= 8;
John Koleszar's avatar
John Koleszar committed
267

John Koleszar's avatar
John Koleszar committed
268
    /* calculate central point error */
269
    besterr = vfp->vf(y, y_stride, z, b->src_stride, sse1);
270
    *distortion = besterr;
271
    besterr += mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
272

John Koleszar's avatar
John Koleszar committed
273 274 275
    /* 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
276 277
    while (--halfiters)
    {
John Koleszar's avatar
John Koleszar committed
278
        /* 1/2 pel */
John Koleszar's avatar
John Koleszar committed
279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301
        CHECK_BETTER(left, tr, tc - 2);
        CHECK_BETTER(right, tr, tc + 2);
        CHECK_BETTER(up, tr - 2, tc);
        CHECK_BETTER(down, tr + 2, tc);

        whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);

        switch (whichdir)
        {
        case 0:
            CHECK_BETTER(diag, tr - 2, tc - 2);
            break;
        case 1:
            CHECK_BETTER(diag, tr - 2, tc + 2);
            break;
        case 2:
            CHECK_BETTER(diag, tr + 2, tc - 2);
            break;
        case 3:
            CHECK_BETTER(diag, tr + 2, tc + 2);
            break;
        }

John Koleszar's avatar
John Koleszar committed
302
        /* no reason to check the same one again. */
John Koleszar's avatar
John Koleszar committed
303 304 305 306 307 308 309
        if (tr == br && tc == bc)
            break;

        tr = br;
        tc = bc;
    }

John Koleszar's avatar
John Koleszar committed
310 311 312 313 314
    /* 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
315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339
    while (--quarteriters)
    {
        CHECK_BETTER(left, tr, tc - 1);
        CHECK_BETTER(right, tr, tc + 1);
        CHECK_BETTER(up, tr - 1, tc);
        CHECK_BETTER(down, tr + 1, tc);

        whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);

        switch (whichdir)
        {
        case 0:
            CHECK_BETTER(diag, tr - 1, tc - 1);
            break;
        case 1:
            CHECK_BETTER(diag, tr - 1, tc + 1);
            break;
        case 2:
            CHECK_BETTER(diag, tr + 1, tc - 1);
            break;
        case 3:
            CHECK_BETTER(diag, tr + 1, tc + 1);
            break;
        }

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

        tr = br;
        tc = bc;
    }

Yaowu Xu's avatar
Yaowu Xu committed
348 349
    bestmv->as_mv.row = br * 2;
    bestmv->as_mv.col = bc * 2;
John Koleszar's avatar
John Koleszar committed
350

351 352
    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)))
John Koleszar's avatar
John Koleszar committed
353 354 355 356 357 358 359 360
        return INT_MAX;

    return besterr;
}
#undef MVC
#undef PRE
#undef SP
#undef DIST
361
#undef IFMVCV
John Koleszar's avatar
John Koleszar committed
362 363
#undef ERR
#undef CHECK_BETTER
Yunqing Wang's avatar
Yunqing Wang committed
364

Scott LaVarnway's avatar
Scott LaVarnway committed
365 366 367 368 369 370
int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
                                 int_mv *bestmv, int_mv *ref_mv,
                                 int error_per_bit,
                                 const vp8_variance_fn_ptr_t *vfp,
                                 int *mvcost[2], int *distortion,
                                 unsigned int *sse1)
John Koleszar's avatar
John Koleszar committed
371 372
{
    int bestmse = INT_MAX;
Scott LaVarnway's avatar
Scott LaVarnway committed
373 374
    int_mv startmv;
    int_mv this_mv;
John Koleszar's avatar
John Koleszar committed
375 376 377 378
    unsigned char *z = (*(b->base_src) + b->src);
    int left, right, up, down, diag;
    unsigned int sse;
    int whichdir ;
379
    int thismse;
380
    int y_stride;
Scott LaVarnway's avatar
Scott LaVarnway committed
381 382
    int pre_stride = x->e_mbd.pre.y_stride;
    unsigned char *base_pre = x->e_mbd.pre.y_buffer;
383 384 385

#if ARCH_X86 || ARCH_X86_64
    MACROBLOCKD *xd = &x->e_mbd;
386
    unsigned char *y_0 = base_pre + d->offset + (bestmv->as_mv.row) * pre_stride + bestmv->as_mv.col;
387 388 389 390
    unsigned char *y;

    y_stride = 32;
    /* Copy 18 rows x 32 cols area to intermediate buffer before searching. */
391
     vfp->copymem(y_0 - 1 - pre_stride, pre_stride, xd->y_buf, y_stride, 18);
392 393
     y = xd->y_buf + y_stride + 1;
#else
Scott LaVarnway's avatar
Scott LaVarnway committed
394 395
     unsigned char *y = base_pre + d->offset + (bestmv->as_mv.row) * pre_stride + bestmv->as_mv.col;
     y_stride = pre_stride;
396
#endif
John Koleszar's avatar
John Koleszar committed
397

John Koleszar's avatar
John Koleszar committed
398
    /* central mv */
Yaowu Xu's avatar
Yaowu Xu committed
399 400
    bestmv->as_mv.row *= 8;
    bestmv->as_mv.col *= 8;
John Koleszar's avatar
John Koleszar committed
401 402
    startmv = *bestmv;

John Koleszar's avatar
John Koleszar committed
403
    /* calculate central point error */
404
    bestmse = vfp->vf(y, y_stride, z, b->src_stride, sse1);
405
    *distortion = bestmse;
406
    bestmse += mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
407

John Koleszar's avatar
John Koleszar committed
408
    /* go left then right and check error */
Scott LaVarnway's avatar
Scott LaVarnway committed
409 410
    this_mv.as_mv.row = startmv.as_mv.row;
    this_mv.as_mv.col = ((startmv.as_mv.col - 8) | 4);
411
    thismse = vfp->svf_halfpix_h(y - 1, y_stride, z, b->src_stride, &sse);
412
    left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
413 414 415 416 417

    if (left < bestmse)
    {
        *bestmv = this_mv;
        bestmse = left;
418
        *distortion = thismse;
419
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
420 421
    }

Scott LaVarnway's avatar
Scott LaVarnway committed
422
    this_mv.as_mv.col += 8;
423
    thismse = vfp->svf_halfpix_h(y, y_stride, z, b->src_stride, &sse);
424
    right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
425 426 427 428 429

    if (right < bestmse)
    {
        *bestmv = this_mv;
        bestmse = right;
430
        *distortion = thismse;
431
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
432 433
    }

John Koleszar's avatar
John Koleszar committed
434
    /* go up then down and check error */
Scott LaVarnway's avatar
Scott LaVarnway committed
435 436
    this_mv.as_mv.col = startmv.as_mv.col;
    this_mv.as_mv.row = ((startmv.as_mv.row - 8) | 4);
437
    thismse =  vfp->svf_halfpix_v(y - y_stride, y_stride, z, b->src_stride, &sse);
438
    up = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
439 440 441 442 443

    if (up < bestmse)
    {
        *bestmv = this_mv;
        bestmse = up;
444
        *distortion = thismse;
445
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
446 447
    }

Scott LaVarnway's avatar
Scott LaVarnway committed
448
    this_mv.as_mv.row += 8;
449
    thismse = vfp->svf_halfpix_v(y, y_stride, z, b->src_stride, &sse);
450
    down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
451 452 453 454 455

    if (down < bestmse)
    {
        *bestmv = this_mv;
        bestmse = down;
456
        *distortion = thismse;
457
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
458 459 460
    }


John Koleszar's avatar
John Koleszar committed
461
    /* now check 1 more diagonal */
John Koleszar's avatar
John Koleszar committed
462 463 464 465 466 467
    whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
    this_mv = startmv;

    switch (whichdir)
    {
    case 0:
Scott LaVarnway's avatar
Scott LaVarnway committed
468 469
        this_mv.as_mv.col = (this_mv.as_mv.col - 8) | 4;
        this_mv.as_mv.row = (this_mv.as_mv.row - 8) | 4;
470
        thismse = vfp->svf_halfpix_hv(y - 1 - y_stride, y_stride, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
471 472
        break;
    case 1:
Scott LaVarnway's avatar
Scott LaVarnway committed
473 474
        this_mv.as_mv.col += 4;
        this_mv.as_mv.row = (this_mv.as_mv.row - 8) | 4;
475
        thismse = vfp->svf_halfpix_hv(y - y_stride, y_stride, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
476 477
        break;
    case 2:
Scott LaVarnway's avatar
Scott LaVarnway committed
478 479
        this_mv.as_mv.col = (this_mv.as_mv.col - 8) | 4;
        this_mv.as_mv.row += 4;
480
        thismse = vfp->svf_halfpix_hv(y - 1, y_stride, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
481 482
        break;
    case 3:
483
    default:
Scott LaVarnway's avatar
Scott LaVarnway committed
484 485
        this_mv.as_mv.col += 4;
        this_mv.as_mv.row += 4;
486
        thismse = vfp->svf_halfpix_hv(y, y_stride, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
487 488 489
        break;
    }

490
    diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
491 492 493 494 495

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


John Koleszar's avatar
John Koleszar committed
501
    /* time to check quarter pels. */
Scott LaVarnway's avatar
Scott LaVarnway committed
502
    if (bestmv->as_mv.row < startmv.as_mv.row)
503
        y -= y_stride;
John Koleszar's avatar
John Koleszar committed
504

Scott LaVarnway's avatar
Scott LaVarnway committed
505
    if (bestmv->as_mv.col < startmv.as_mv.col)
John Koleszar's avatar
John Koleszar committed
506 507 508 509 510 511
        y--;

    startmv = *bestmv;



John Koleszar's avatar
John Koleszar committed
512
    /* go left then right and check error */
Scott LaVarnway's avatar
Scott LaVarnway committed
513
    this_mv.as_mv.row = startmv.as_mv.row;
John Koleszar's avatar
John Koleszar committed
514

Scott LaVarnway's avatar
Scott LaVarnway committed
515
    if (startmv.as_mv.col & 7)
John Koleszar's avatar
John Koleszar committed
516
    {
Scott LaVarnway's avatar
Scott LaVarnway committed
517
        this_mv.as_mv.col = startmv.as_mv.col - 2;
518
        thismse = vfp->svf(y, y_stride, this_mv.as_mv.col & 7, this_mv.as_mv.row & 7, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
519 520 521
    }
    else
    {
Scott LaVarnway's avatar
Scott LaVarnway committed
522
        this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6;
523
        thismse = vfp->svf(y - 1, y_stride, 6, this_mv.as_mv.row & 7, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
524 525
    }

526
    left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
527 528 529 530 531

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

Scott LaVarnway's avatar
Scott LaVarnway committed
536
    this_mv.as_mv.col += 4;
537
    thismse = vfp->svf(y, y_stride, this_mv.as_mv.col & 7, this_mv.as_mv.row & 7, z, b->src_stride, &sse);
538
    right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
539 540 541 542 543

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

John Koleszar's avatar
John Koleszar committed
548
    /* go up then down and check error */
Scott LaVarnway's avatar
Scott LaVarnway committed
549
    this_mv.as_mv.col = startmv.as_mv.col;
John Koleszar's avatar
John Koleszar committed
550

Scott LaVarnway's avatar
Scott LaVarnway committed
551
    if (startmv.as_mv.row & 7)
John Koleszar's avatar
John Koleszar committed
552
    {
Scott LaVarnway's avatar
Scott LaVarnway committed
553
        this_mv.as_mv.row = startmv.as_mv.row - 2;
554
        thismse = vfp->svf(y, y_stride, this_mv.as_mv.col & 7, this_mv.as_mv.row & 7, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
555 556 557
    }
    else
    {
Scott LaVarnway's avatar
Scott LaVarnway committed
558
        this_mv.as_mv.row = (startmv.as_mv.row - 8) | 6;
559
        thismse = vfp->svf(y - y_stride, y_stride, this_mv.as_mv.col & 7, 6, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
560 561
    }

562
    up = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
563 564 565 566 567

    if (up < bestmse)
    {
        *bestmv = this_mv;
        bestmse = up;
568
        *distortion = thismse;
569
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
570 571
    }

Scott LaVarnway's avatar
Scott LaVarnway committed
572
    this_mv.as_mv.row += 4;
573
    thismse = vfp->svf(y, y_stride, this_mv.as_mv.col & 7, this_mv.as_mv.row & 7, z, b->src_stride, &sse);
574
    down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
575 576 577 578 579

    if (down < bestmse)
    {
        *bestmv = this_mv;
        bestmse = down;
580
        *distortion = thismse;
581
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
582 583 584
    }


John Koleszar's avatar
John Koleszar committed
585
    /* now check 1 more diagonal */
John Koleszar's avatar
John Koleszar committed
586 587 588 589 590 591 592 593
    whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);

    this_mv = startmv;

    switch (whichdir)
    {
    case 0:

Scott LaVarnway's avatar
Scott LaVarnway committed
594
        if (startmv.as_mv.row & 7)
John Koleszar's avatar
John Koleszar committed
595
        {
Scott LaVarnway's avatar
Scott LaVarnway committed
596
            this_mv.as_mv.row -= 2;
John Koleszar's avatar
John Koleszar committed
597

Scott LaVarnway's avatar
Scott LaVarnway committed
598
            if (startmv.as_mv.col & 7)
John Koleszar's avatar
John Koleszar committed
599
            {
Scott LaVarnway's avatar
Scott LaVarnway committed
600
                this_mv.as_mv.col -= 2;
601
                thismse = vfp->svf(y, y_stride, this_mv.as_mv.col & 7, this_mv.as_mv.row & 7, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
602 603 604
            }
            else
            {
Scott LaVarnway's avatar
Scott LaVarnway committed
605
                this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6;
606
                thismse = vfp->svf(y - 1, y_stride, 6, this_mv.as_mv.row & 7, z, b->src_stride, &sse);;
John Koleszar's avatar
John Koleszar committed
607 608 609 610
            }
        }
        else
        {
Scott LaVarnway's avatar
Scott LaVarnway committed
611
            this_mv.as_mv.row = (startmv.as_mv.row - 8) | 6;
John Koleszar's avatar
John Koleszar committed
612

Scott LaVarnway's avatar
Scott LaVarnway committed
613
            if (startmv.as_mv.col & 7)
John Koleszar's avatar
John Koleszar committed
614
            {
Scott LaVarnway's avatar
Scott LaVarnway committed
615
                this_mv.as_mv.col -= 2;
616
                thismse = vfp->svf(y - y_stride, y_stride, this_mv.as_mv.col & 7, 6, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
617 618 619
            }
            else
            {
Scott LaVarnway's avatar
Scott LaVarnway committed
620
                this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6;
621
                thismse = vfp->svf(y - y_stride - 1, y_stride, 6, 6, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
622 623 624 625 626
            }
        }

        break;
    case 1:
Scott LaVarnway's avatar
Scott LaVarnway committed
627
        this_mv.as_mv.col += 2;
John Koleszar's avatar
John Koleszar committed
628

Scott LaVarnway's avatar
Scott LaVarnway committed
629
        if (startmv.as_mv.row & 7)
John Koleszar's avatar
John Koleszar committed
630
        {
Scott LaVarnway's avatar
Scott LaVarnway committed
631
            this_mv.as_mv.row -= 2;
632
            thismse = vfp->svf(y, y_stride, this_mv.as_mv.col & 7, this_mv.as_mv.row & 7, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
633 634 635
        }
        else
        {
Scott LaVarnway's avatar
Scott LaVarnway committed
636
            this_mv.as_mv.row = (startmv.as_mv.row - 8) | 6;
637
            thismse = vfp->svf(y - y_stride, y_stride, this_mv.as_mv.col & 7, 6, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
638 639 640 641
        }

        break;
    case 2:
Scott LaVarnway's avatar
Scott LaVarnway committed
642
        this_mv.as_mv.row += 2;
John Koleszar's avatar
John Koleszar committed
643

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

        break;
    case 3:
Scott LaVarnway's avatar
Scott LaVarnway committed
657 658
        this_mv.as_mv.col += 2;
        this_mv.as_mv.row += 2;
659
        thismse = vfp->svf(y, y_stride,  this_mv.as_mv.col & 7, this_mv.as_mv.row & 7, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
660 661 662
        break;
    }

663
    diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
664 665 666 667 668

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

    return bestmse;
}

676
int vp8_find_best_half_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
Scott LaVarnway's avatar
Scott LaVarnway committed
677 678 679 680 681
                                  int_mv *bestmv, int_mv *ref_mv,
                                  int error_per_bit,
                                  const vp8_variance_fn_ptr_t *vfp,
                                  int *mvcost[2], int *distortion,
                                  unsigned int *sse1)
John Koleszar's avatar
John Koleszar committed
682 683
{
    int bestmse = INT_MAX;
Scott LaVarnway's avatar
Scott LaVarnway committed
684 685
    int_mv startmv;
    int_mv this_mv;
John Koleszar's avatar
John Koleszar committed
686 687 688
    unsigned char *z = (*(b->base_src) + b->src);
    int left, right, up, down, diag;
    unsigned int sse;
Yunqing Wang's avatar
Yunqing Wang committed
689
    int whichdir ;
690
    int thismse;
691
    int y_stride;
Scott LaVarnway's avatar
Scott LaVarnway committed
692 693
    int pre_stride = x->e_mbd.pre.y_stride;
    unsigned char *base_pre = x->e_mbd.pre.y_buffer;
694 695 696

#if ARCH_X86 || ARCH_X86_64
    MACROBLOCKD *xd = &x->e_mbd;
697
    unsigned char *y_0 = base_pre + d->offset + (bestmv->as_mv.row) * pre_stride + bestmv->as_mv.col;
698 699 700 701
    unsigned char *y;

    y_stride = 32;
    /* Copy 18 rows x 32 cols area to intermediate buffer before searching. */
702
    vfp->copymem(y_0 - 1 - pre_stride, pre_stride, xd->y_buf, y_stride, 18);
703 704
    y = xd->y_buf + y_stride + 1;
#else
Scott LaVarnway's avatar
Scott LaVarnway committed
705 706
    unsigned char *y = base_pre + d->offset + (bestmv->as_mv.row) * pre_stride + bestmv->as_mv.col;
    y_stride = pre_stride;
707
#endif
John Koleszar's avatar
John Koleszar committed
708

John Koleszar's avatar
John Koleszar committed
709
    /* central mv */
Yaowu Xu's avatar
Yaowu Xu committed
710 711
    bestmv->as_mv.row *= 8;
    bestmv->as_mv.col *= 8;
John Koleszar's avatar
John Koleszar committed
712 713
    startmv = *bestmv;

John Koleszar's avatar
John Koleszar committed
714
    /* calculate central point error */
715
    bestmse = vfp->vf(y, y_stride, z, b->src_stride, sse1);
716
    *distortion = bestmse;
717
    bestmse += mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
718

John Koleszar's avatar
John Koleszar committed
719
    /* go left then right and check error */
Scott LaVarnway's avatar
Scott LaVarnway committed
720 721
    this_mv.as_mv.row = startmv.as_mv.row;
    this_mv.as_mv.col = ((startmv.as_mv.col - 8) | 4);
722
    thismse = vfp->svf_halfpix_h(y - 1, y_stride, z, b->src_stride, &sse);
723
    left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
724 725 726 727 728

    if (left < bestmse)
    {
        *bestmv = this_mv;
        bestmse = left;
729
        *distortion = thismse;
730
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
731 732
    }

Scott LaVarnway's avatar
Scott LaVarnway committed
733
    this_mv.as_mv.col += 8;
734
    thismse = vfp->svf_halfpix_h(y, y_stride, z, b->src_stride, &sse);
735
    right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
736 737 738 739 740

    if (right < bestmse)
    {
        *bestmv = this_mv;
        bestmse = right;
741
        *distortion = thismse;
742
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
743 744
    }

John Koleszar's avatar
John Koleszar committed
745
    /* go up then down and check error */
Scott LaVarnway's avatar
Scott LaVarnway committed
746 747
    this_mv.as_mv.col = startmv.as_mv.col;
    this_mv.as_mv.row = ((startmv.as_mv.row - 8) | 4);
748
    thismse = vfp->svf_halfpix_v(y - y_stride, y_stride, z, b->src_stride, &sse);
749
    up = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
750 751 752 753 754

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

Scott LaVarnway's avatar
Scott LaVarnway committed
759
    this_mv.as_mv.row += 8;
760
    thismse = vfp->svf_halfpix_v(y, y_stride, z, b->src_stride, &sse);
761
    down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
762 763 764 765 766

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

John Koleszar's avatar
John Koleszar committed
771
    /* now check 1 more diagonal - */
John Koleszar's avatar
John Koleszar committed
772 773 774 775 776 777
    whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
    this_mv = startmv;

    switch (whichdir)
    {
    case 0:
Yunqing Wang's avatar
Yunqing Wang committed
778 779 780
        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);
John Koleszar's avatar
John Koleszar committed
781 782
        break;
    case 1:
Yunqing Wang's avatar
Yunqing Wang committed
783 784 785
        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);
John Koleszar's avatar
John Koleszar committed
786 787
        break;
    case 2:
Yunqing Wang's avatar
Yunqing Wang committed
788 789 790
        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);
John Koleszar's avatar
John Koleszar committed
791 792
        break;
    case 3:
Yunqing Wang's avatar
Yunqing Wang committed
793 794 795 796
    default:
        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);
John Koleszar's avatar
John Koleszar committed
797 798 799
        break;
    }

800
    diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
801 802 803 804 805

    if (diag < bestmse)
    {
        *bestmv = this_mv;
        bestmse = diag;
806
        *distortion = thismse;
807
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
808 809 810 811 812
    }

    return bestmse;
}

Yunqing Wang's avatar
Yunqing Wang committed
813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833
#define CHECK_BOUNDS(range) \
{\
    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);\
}

#define CHECK_POINT \
{\
    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;\
}

#define CHECK_BETTER \
{\
    if (thissad < bestsad)\
    {\
834
        thissad += mvsad_err_cost(&this_mv, &fcenter_mv, mvsadcost, sad_per_bit);\
Yunqing Wang's avatar
Yunqing Wang committed
835 836 837 838 839 840 841
        if (thissad < bestsad)\
        {\
            bestsad = thissad;\
            best_site = i;\
        }\
    }\
}
John Koleszar's avatar
John Koleszar committed
842

843 844 845 846 847 848 849 850 851
static const MV next_chkpts[6][3] =
{
    {{ -2, 0}, { -1, -2}, {1, -2}},
    {{ -1, -2}, {1, -2}, {2, 0}},
    {{1, -2}, {2, 0}, {1, 2}},
    {{2, 0}, {1, 2}, { -1, 2}},
    {{1, 2}, { -1, 2}, { -2, 0}},
    {{ -1, 2}, { -2, 0}, { -1, -2}}
};
Yunqing Wang's avatar
Yunqing Wang committed
852

John Koleszar's avatar
John Koleszar committed
853 854 855 856 857
int vp8_hex_search
(
    MACROBLOCK *x,
    BLOCK *b,
    BLOCKD *d,
Scott LaVarnway's avatar
Scott LaVarnway committed
858 859
    int_mv *ref_mv,
    int_mv *best_mv,
John Koleszar's avatar
John Koleszar committed
860
    int search_param,
861
    int sad_per_bit,
862
    const vp8_variance_fn_ptr_t *vfp,
John Koleszar's avatar
John Koleszar committed
863
    int *mvsadcost[2],
864
    int *mvcost[2],
Scott LaVarnway's avatar
Scott LaVarnway committed
865
    int_mv *center_mv
John Koleszar's avatar
John Koleszar committed
866 867
)
{
868
    MV hex[6] = { { -1, -2}, {1, -2}, {2, 0}, {1, 2}, { -1, 2}, { -2, 0} } ;
Yunqing Wang's avatar
Yunqing Wang committed
869
    MV neighbors[4] = {{0, -1}, { -1, 0}, {1, 0}, {0, 1}} ;
John Koleszar's avatar
John Koleszar committed
870 871
    int i, j;

Yunqing Wang's avatar
Yunqing Wang committed
872 873
    unsigned char *what = (*(b->base_src) + b->src);
    int what_stride = b->src_stride;
Scott LaVarnway's avatar
Scott LaVarnway committed
874 875 876 877
    int pre_stride = x->e_mbd.pre.y_stride;
    unsigned char *base_pre = x->e_mbd.pre.y_buffer;

    int in_what_stride = pre_stride;
878
    int br, bc;
Yunqing Wang's avatar
Yunqing Wang committed
879
    int_mv this_mv;
Johann's avatar
Johann committed
880
    unsigned int bestsad;
Yunqing Wang's avatar
Yunqing Wang committed
881 882 883 884 885 886
    unsigned int thissad;
    unsigned char *base_offset;
    unsigned char *this_offset;
    int k = -1;
    int all_in;
    int best_site = -1;
Yunqing Wang's avatar
Yunqing Wang committed
887 888
    int hex_range = 127;
    int dia_range = 8;
Yunqing Wang's avatar
Yunqing Wang committed
889 890 891 892 893

    int_mv fcenter_mv;
    fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3;
    fcenter_mv.as_mv.col = center_mv->as_mv.col >> 3;

Johann's avatar
Johann committed
894 895
    (void)mvcost;

John Koleszar's avatar
John Koleszar committed
896
    /* adjust ref_mv to make sure it is within MV range */
897 898 899 900
    vp8_clamp_mv(ref_mv, x->mv_col_min, x->mv_col_max, x->mv_row_min, x->mv_row_max);
    br = ref_mv->as_mv.row;
    bc = ref_mv->as_mv.col;

John Koleszar's avatar
John Koleszar committed
901
    /* Work out the start point for the search */
Scott LaVarnway's avatar
Scott LaVarnway committed
902 903
    base_offset = (unsigned char *)(base_pre + d->offset);
    this_offset = base_offset + (br * (pre_stride)) + bc;
Yunqing Wang's avatar
Yunqing Wang committed
904 905
    this_mv.as_mv.row = br;
    this_mv.as_mv.col = bc;
Johann's avatar
Johann committed
906
    bestsad = vfp->sdf(what, what_stride, this_offset, in_what_stride)
907
            + mvsad_err_cost(&this_mv, &fcenter_mv, mvsadcost, sad_per_bit);
John Koleszar's avatar
John Koleszar committed
908

Yunqing Wang's avatar
Yunqing Wang committed
909 910 911 912 913 914 915 916 917 918
#if CONFIG_MULTI_RES_ENCODING
    /* Lower search range based on prediction info */
    if (search_param >= 6) goto cal_neighbors;
    else if (search_param >= 5) hex_range = 4;
    else if (search_param >= 4) hex_range = 6;
    else if (search_param >= 3) hex_range = 15;
    else if (search_param >= 2) hex_range = 31;
    else if (search_param >= 1) hex_range = 63;

    dia_range = 8;
Johann's avatar
Johann committed
919 920
#else
    (void)search_param;
Yunqing Wang's avatar
Yunqing Wang committed
921 922
#endif

John Koleszar's avatar
John Koleszar committed
923
    /* hex search */
Yunqing Wang's avatar
Yunqing Wang committed
924
    CHECK_BOUNDS(2)
925

Yunqing Wang's avatar
Yunqing Wang committed
926
    if(all_in)
927
    {
Yunqing Wang's avatar
Yunqing Wang committed
928
        for (i = 0; i < 6; i++)
929
        {
Yunqing Wang's avatar
Yunqing Wang committed
930 931 932
            this_mv.as_mv.row = br + hex[i].row;
            this_mv.as_mv.col = bc + hex[i].col;
            this_offset = base_offset + (this_mv.as_mv.row * in_what_stride) + this_mv.as_mv.col;
Johann's avatar
Johann committed
933
            thissad = vfp->sdf(what, what_stride, this_offset, in_what_stride);
Yunqing Wang's avatar
Yunqing Wang committed
934 935 936 937 938 939 940 941 942 943
            CHECK_BETTER
        }
    }else
    {
        for (i = 0; i < 6; i++)
        {
            this_mv.as_mv.row = br + hex[i].row;
            this_mv.as_mv.col = bc + hex[i].col;
            CHECK_POINT
            this_offset = base_offset + (this_mv.as_mv.row * in_what_stride) + this_mv.as_mv.col;
Johann's avatar
Johann committed
944
            thissad = vfp->sdf(what, what_stride, this_offset, in_what_stride);
Yunqing Wang's avatar
Yunqing Wang committed
945
            CHECK_BETTER
946 947 948
        }
    }

Yunqing Wang's avatar
Yunqing Wang committed
949
    if (best_site == -1)
950
        goto cal_neighbors;
Yunqing Wang's avatar
Yunqing Wang committed
951 952 953 954 955 956
    else
    {
        br += hex[best_site].row;
        bc += hex[best_site].col;
        k = best_site;
    }
957

Yunqing Wang's avatar
Yunqing Wang committed
958
    for (j = 1; j < hex_range; j++)
John Koleszar's avatar
John Koleszar committed
959
    {
Yunqing Wang's avatar
Yunqing Wang committed
960 961
        best_site = -1;
        CHECK_BOUNDS(2)
John Koleszar's avatar
John Koleszar committed
962

Yunqing Wang's avatar
Yunqing Wang committed
963
        if(all_in)
John Koleszar's avatar
John Koleszar committed
964
        {
Yunqing Wang's avatar