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


Yunqing Wang's avatar
Yunqing Wang committed
12
#include "onyx_int.h"
John Koleszar's avatar
John Koleszar committed
13 14
#include "mcomp.h"
#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 "vp8/common/findnearmv.h"
John Koleszar's avatar
John Koleszar committed
20 21 22 23 24 25

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

Scott LaVarnway's avatar
Scott LaVarnway committed
26
int vp8_mv_bit_cost(int_mv *mv, int_mv *ref, int *mvcost[2], int Weight)
John Koleszar's avatar
John Koleszar committed
27 28 29 30 31
{
    // 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
32
    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
33 34
}

Scott LaVarnway's avatar
Scott LaVarnway committed
35
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
36
{
Scott LaVarnway's avatar
Scott LaVarnway committed
37 38 39
    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;
John Koleszar's avatar
John Koleszar committed
40 41
}

Scott LaVarnway's avatar
Scott LaVarnway committed
42
static int mvsad_err_cost(int_mv *mv, int_mv *ref, int *mvsadcost[2], int error_per_bit)
43 44
{
    /* Calculate sad error cost on full pixel basis. */
Scott LaVarnway's avatar
Scott LaVarnway committed
45 46 47
    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;
John Koleszar's avatar
John Koleszar committed
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
}

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


    // 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.
        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;
        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 = 0;
        x->ss[search_site_count].offset = Len;
        search_site_count++;

        // Contract.
        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;

    // 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)
    {

        // 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 = 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;
        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 = 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++;


        // Contract.
        Len /= 2;
    }

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

170 171 172 173 174 175 176 177 178
/*
 * 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
179
#define MVC(r,c) (((mvcost[0][(r)-rr] + mvcost[1][(c) - rc]) * error_per_bit + 128 )>>8 ) // estimated cost of a motion vector (r,c)
180
#define PRE(r,c) (y + (((r)>>2) * y_stride + ((c)>>2) -(offset))) // pointer to predictor base of a motionvector
John Koleszar's avatar
John Koleszar committed
181
#define SP(x) (((x)&3)<<1) // convert motion vector component to offset for svf calc
182
#define DIST(r,c) vfp->svf( PRE(r,c), y_stride, SP(c),SP(r), z,b->src_stride,&sse) // returns subpixel variance error function.
John Koleszar's avatar
John Koleszar committed
183 184
#define IFMVCV(r,c,s,e) if ( c >= minc && c <= maxc && r >= minr && r <= maxr) s else e;
#define ERR(r,c) (MVC(r,c)+DIST(r,c)) // returns distortion + motion vector cost
185
#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;)// checks if (r,c) has better score than previous best
John Koleszar's avatar
John Koleszar committed
186

Scott LaVarnway's avatar
Scott LaVarnway committed
187 188 189 190 191 192
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
193 194 195
{
    unsigned char *z = (*(b->base_src) + b->src);

Scott LaVarnway's avatar
Scott LaVarnway committed
196 197
    int rr = ref_mv->as_mv.row >> 1, rc = ref_mv->as_mv.col >> 1;
    int br = bestmv->as_mv.row << 2, bc = bestmv->as_mv.col << 2;
John Koleszar's avatar
John Koleszar committed
198 199 200 201 202 203 204
    int tr = br, tc = bc;
    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;
205
    int thismse;
John Koleszar's avatar
John Koleszar committed
206

Scott LaVarnway's avatar
Scott LaVarnway committed
207 208 209 210
    int minc = MAX(x->mv_col_min << 2, (ref_mv->as_mv.col >> 1) - ((1 << mvlong_width) - 1));
    int maxc = MIN(x->mv_col_max << 2, (ref_mv->as_mv.col >> 1) + ((1 << mvlong_width) - 1));
    int minr = MAX(x->mv_row_min << 2, (ref_mv->as_mv.row >> 1) - ((1 << mvlong_width) - 1));
    int maxr = MIN(x->mv_row_max << 2, (ref_mv->as_mv.row >> 1) + ((1 << mvlong_width) - 1));
John Koleszar's avatar
John Koleszar committed
211

212 213
    int y_stride;
    int offset;
Scott LaVarnway's avatar
Scott LaVarnway committed
214 215 216
    int pre_stride = x->e_mbd.pre.y_stride;
    unsigned char *base_pre = x->e_mbd.pre.y_buffer;

217 218 219

#if ARCH_X86 || ARCH_X86_64
    MACROBLOCKD *xd = &x->e_mbd;
Scott LaVarnway's avatar
Scott LaVarnway committed
220
    unsigned char *y0 = base_pre + d->offset + (bestmv->as_mv.row) * pre_stride + bestmv->as_mv.col;
221 222 223 224 225 226 227 228 229 230 231
    unsigned char *y;
    int buf_r1, buf_r2, buf_c1, buf_c2;

    // Clamping to avoid out-of-range data access
    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;
    buf_c2 = ((bestmv->as_mv.col + 3) > x->mv_col_max)?(x->mv_col_max - bestmv->as_mv.col):3;
    y_stride = 32;

    /* Copy to intermediate buffer before searching. */
Scott LaVarnway's avatar
Scott LaVarnway committed
232
    vfp->copymem(y0 - buf_c1 - pre_stride*buf_r1, pre_stride, xd->y_buf, y_stride, 16+buf_r1+buf_r2);
233 234
    y = xd->y_buf + y_stride*buf_r1 +buf_c1;
#else
Scott LaVarnway's avatar
Scott LaVarnway committed
235 236
    unsigned char *y = base_pre + d->offset + (bestmv->as_mv.row) * pre_stride + bestmv->as_mv.col;
    y_stride = pre_stride;
237 238 239 240
#endif

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

John Koleszar's avatar
John Koleszar committed
241
    // central mv
Scott LaVarnway's avatar
Scott LaVarnway committed
242 243
    bestmv->as_mv.row <<= 3;
    bestmv->as_mv.col <<= 3;
John Koleszar's avatar
John Koleszar committed
244 245

    // calculate central point error
246
    besterr = vfp->vf(y, y_stride, z, b->src_stride, sse1);
247
    *distortion = besterr;
248
    besterr += mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319

    // TODO: Each subsequent iteration checks at least one point in common with the last iteration could be 2 ( if diag selected)
    while (--halfiters)
    {
        // 1/2 pel
        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;
        }

        // no reason to check the same one again.
        if (tr == br && tc == bc)
            break;

        tr = br;
        tc = bc;
    }

    // TODO: Each subsequent iteration checks at least one point in common with the last iteration could be 2 ( if diag selected)
    // 1/4 pel
    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;
        }

        // no reason to check the same one again.
        if (tr == br && tc == bc)
            break;

        tr = br;
        tc = bc;
    }

Scott LaVarnway's avatar
Scott LaVarnway committed
320 321
    bestmv->as_mv.row = br << 1;
    bestmv->as_mv.col = bc << 1;
John Koleszar's avatar
John Koleszar committed
322

323 324
    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
325 326 327 328 329 330 331 332
        return INT_MAX;

    return besterr;
}
#undef MVC
#undef PRE
#undef SP
#undef DIST
333
#undef IFMVCV
John Koleszar's avatar
John Koleszar committed
334 335
#undef ERR
#undef CHECK_BETTER
Yunqing Wang's avatar
Yunqing Wang committed
336

Scott LaVarnway's avatar
Scott LaVarnway committed
337 338 339 340 341 342
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
343 344
{
    int bestmse = INT_MAX;
Scott LaVarnway's avatar
Scott LaVarnway committed
345 346
    int_mv startmv;
    int_mv this_mv;
John Koleszar's avatar
John Koleszar committed
347 348 349 350
    unsigned char *z = (*(b->base_src) + b->src);
    int left, right, up, down, diag;
    unsigned int sse;
    int whichdir ;
351
    int thismse;
352
    int y_stride;
Scott LaVarnway's avatar
Scott LaVarnway committed
353 354
    int pre_stride = x->e_mbd.pre.y_stride;
    unsigned char *base_pre = x->e_mbd.pre.y_buffer;
355 356 357

#if ARCH_X86 || ARCH_X86_64
    MACROBLOCKD *xd = &x->e_mbd;
Scott LaVarnway's avatar
Scott LaVarnway committed
358
    unsigned char *y0 = base_pre + d->offset + (bestmv->as_mv.row) * pre_stride + bestmv->as_mv.col;
359 360 361 362
    unsigned char *y;

    y_stride = 32;
    /* Copy 18 rows x 32 cols area to intermediate buffer before searching. */
Scott LaVarnway's avatar
Scott LaVarnway committed
363
     vfp->copymem(y0 - 1 - pre_stride, pre_stride, xd->y_buf, y_stride, 18);
364 365
     y = xd->y_buf + y_stride + 1;
#else
Scott LaVarnway's avatar
Scott LaVarnway committed
366 367
     unsigned char *y = base_pre + d->offset + (bestmv->as_mv.row) * pre_stride + bestmv->as_mv.col;
     y_stride = pre_stride;
368
#endif
John Koleszar's avatar
John Koleszar committed
369 370

    // central mv
Scott LaVarnway's avatar
Scott LaVarnway committed
371 372
    bestmv->as_mv.row <<= 3;
    bestmv->as_mv.col <<= 3;
John Koleszar's avatar
John Koleszar committed
373 374 375
    startmv = *bestmv;

    // calculate central point error
376
    bestmse = vfp->vf(y, y_stride, z, b->src_stride, sse1);
377
    *distortion = bestmse;
378
    bestmse += mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
379 380

    // go left then right and check error
Scott LaVarnway's avatar
Scott LaVarnway committed
381 382
    this_mv.as_mv.row = startmv.as_mv.row;
    this_mv.as_mv.col = ((startmv.as_mv.col - 8) | 4);
383
    thismse = vfp->svf_halfpix_h(y - 1, y_stride, z, b->src_stride, &sse);
384
    left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
385 386 387 388 389

    if (left < bestmse)
    {
        *bestmv = this_mv;
        bestmse = left;
390
        *distortion = thismse;
391
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
392 393
    }

Scott LaVarnway's avatar
Scott LaVarnway committed
394
    this_mv.as_mv.col += 8;
395
    thismse = vfp->svf_halfpix_h(y, y_stride, z, b->src_stride, &sse);
396
    right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
397 398 399 400 401

    if (right < bestmse)
    {
        *bestmv = this_mv;
        bestmse = right;
402
        *distortion = thismse;
403
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
404 405 406
    }

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

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

Scott LaVarnway's avatar
Scott LaVarnway committed
420
    this_mv.as_mv.row += 8;
421
    thismse = vfp->svf_halfpix_v(y, y_stride, z, b->src_stride, &sse);
422
    down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
423 424 425 426 427

    if (down < bestmse)
    {
        *bestmv = this_mv;
        bestmse = down;
428
        *distortion = thismse;
429
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
430 431 432 433 434 435 436 437 438 439 440 441
    }


    // now check 1 more diagonal
    whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
    //for(whichdir =0;whichdir<4;whichdir++)
    //{
    this_mv = startmv;

    switch (whichdir)
    {
    case 0:
Scott LaVarnway's avatar
Scott LaVarnway committed
442 443
        this_mv.as_mv.col = (this_mv.as_mv.col - 8) | 4;
        this_mv.as_mv.row = (this_mv.as_mv.row - 8) | 4;
444
        thismse = vfp->svf_halfpix_hv(y - 1 - y_stride, y_stride, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
445 446
        break;
    case 1:
Scott LaVarnway's avatar
Scott LaVarnway committed
447 448
        this_mv.as_mv.col += 4;
        this_mv.as_mv.row = (this_mv.as_mv.row - 8) | 4;
449
        thismse = vfp->svf_halfpix_hv(y - y_stride, y_stride, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
450 451
        break;
    case 2:
Scott LaVarnway's avatar
Scott LaVarnway committed
452 453
        this_mv.as_mv.col = (this_mv.as_mv.col - 8) | 4;
        this_mv.as_mv.row += 4;
454
        thismse = vfp->svf_halfpix_hv(y - 1, y_stride, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
455 456
        break;
    case 3:
457
    default:
Scott LaVarnway's avatar
Scott LaVarnway committed
458 459
        this_mv.as_mv.col += 4;
        this_mv.as_mv.row += 4;
460
        thismse = vfp->svf_halfpix_hv(y, y_stride, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
461 462 463
        break;
    }

464
    diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
465 466 467 468 469

    if (diag < bestmse)
    {
        *bestmv = this_mv;
        bestmse = diag;
470
        *distortion = thismse;
471
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
472 473 474 475 476 477
    }

//  }


    // time to check quarter pels.
Scott LaVarnway's avatar
Scott LaVarnway committed
478
    if (bestmv->as_mv.row < startmv.as_mv.row)
479
        y -= y_stride;
John Koleszar's avatar
John Koleszar committed
480

Scott LaVarnway's avatar
Scott LaVarnway committed
481
    if (bestmv->as_mv.col < startmv.as_mv.col)
John Koleszar's avatar
John Koleszar committed
482 483 484 485 486 487 488
        y--;

    startmv = *bestmv;



    // go left then right and check error
Scott LaVarnway's avatar
Scott LaVarnway committed
489
    this_mv.as_mv.row = startmv.as_mv.row;
John Koleszar's avatar
John Koleszar committed
490

Scott LaVarnway's avatar
Scott LaVarnway committed
491
    if (startmv.as_mv.col & 7)
John Koleszar's avatar
John Koleszar committed
492
    {
Scott LaVarnway's avatar
Scott LaVarnway committed
493
        this_mv.as_mv.col = startmv.as_mv.col - 2;
494
        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
495 496 497
    }
    else
    {
Scott LaVarnway's avatar
Scott LaVarnway committed
498
        this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6;
499
        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
500 501
    }

502
    left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
503 504 505 506 507

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

Scott LaVarnway's avatar
Scott LaVarnway committed
512
    this_mv.as_mv.col += 4;
513
    thismse = vfp->svf(y, y_stride, this_mv.as_mv.col & 7, this_mv.as_mv.row & 7, z, b->src_stride, &sse);
514
    right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
515 516 517 518 519

    if (right < bestmse)
    {
        *bestmv = this_mv;
        bestmse = right;
520
        *distortion = thismse;
521
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
522 523 524
    }

    // go up then down and check error
Scott LaVarnway's avatar
Scott LaVarnway committed
525
    this_mv.as_mv.col = startmv.as_mv.col;
John Koleszar's avatar
John Koleszar committed
526

Scott LaVarnway's avatar
Scott LaVarnway committed
527
    if (startmv.as_mv.row & 7)
John Koleszar's avatar
John Koleszar committed
528
    {
Scott LaVarnway's avatar
Scott LaVarnway committed
529
        this_mv.as_mv.row = startmv.as_mv.row - 2;
530
        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
531 532 533
    }
    else
    {
Scott LaVarnway's avatar
Scott LaVarnway committed
534
        this_mv.as_mv.row = (startmv.as_mv.row - 8) | 6;
535
        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
536 537
    }

538
    up = 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 (up < bestmse)
    {
        *bestmv = this_mv;
        bestmse = up;
544
        *distortion = thismse;
545
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
546 547
    }

Scott LaVarnway's avatar
Scott LaVarnway committed
548
    this_mv.as_mv.row += 4;
549
    thismse = vfp->svf(y, y_stride, this_mv.as_mv.col & 7, this_mv.as_mv.row & 7, z, b->src_stride, &sse);
550
    down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
551 552 553 554 555

    if (down < bestmse)
    {
        *bestmv = this_mv;
        bestmse = down;
556
        *distortion = thismse;
557
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
558 559 560 561 562 563 564 565 566 567 568 569 570 571
    }


    // now check 1 more diagonal
    whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);

//  for(whichdir=0;whichdir<4;whichdir++)
//  {
    this_mv = startmv;

    switch (whichdir)
    {
    case 0:

Scott LaVarnway's avatar
Scott LaVarnway committed
572
        if (startmv.as_mv.row & 7)
John Koleszar's avatar
John Koleszar committed
573
        {
Scott LaVarnway's avatar
Scott LaVarnway committed
574
            this_mv.as_mv.row -= 2;
John Koleszar's avatar
John Koleszar committed
575

Scott LaVarnway's avatar
Scott LaVarnway committed
576
            if (startmv.as_mv.col & 7)
John Koleszar's avatar
John Koleszar committed
577
            {
Scott LaVarnway's avatar
Scott LaVarnway committed
578
                this_mv.as_mv.col -= 2;
579
                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
580 581 582
            }
            else
            {
Scott LaVarnway's avatar
Scott LaVarnway committed
583
                this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6;
584
                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
585 586 587 588
            }
        }
        else
        {
Scott LaVarnway's avatar
Scott LaVarnway committed
589
            this_mv.as_mv.row = (startmv.as_mv.row - 8) | 6;
John Koleszar's avatar
John Koleszar committed
590

Scott LaVarnway's avatar
Scott LaVarnway committed
591
            if (startmv.as_mv.col & 7)
John Koleszar's avatar
John Koleszar committed
592
            {
Scott LaVarnway's avatar
Scott LaVarnway committed
593
                this_mv.as_mv.col -= 2;
594
                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
595 596 597
            }
            else
            {
Scott LaVarnway's avatar
Scott LaVarnway committed
598
                this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6;
599
                thismse = vfp->svf(y - y_stride - 1, y_stride, 6, 6, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
600 601 602 603 604
            }
        }

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

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

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

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

        break;
    case 3:
Scott LaVarnway's avatar
Scott LaVarnway committed
635 636
        this_mv.as_mv.col += 2;
        this_mv.as_mv.row += 2;
637
        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
638 639 640
        break;
    }

641
    diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
642 643 644 645 646

    if (diag < bestmse)
    {
        *bestmv = this_mv;
        bestmse = diag;
647
        *distortion = thismse;
648
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
649 650 651 652 653
    }

    return bestmse;
}

654
int vp8_find_best_half_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
Scott LaVarnway's avatar
Scott LaVarnway committed
655 656 657 658 659
                                  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
660 661
{
    int bestmse = INT_MAX;
Scott LaVarnway's avatar
Scott LaVarnway committed
662 663
    int_mv startmv;
    int_mv this_mv;
John Koleszar's avatar
John Koleszar committed
664 665 666
    unsigned char *z = (*(b->base_src) + b->src);
    int left, right, up, down, diag;
    unsigned int sse;
Yunqing Wang's avatar
Yunqing Wang committed
667
    int whichdir ;
668
    int thismse;
669
    int y_stride;
Scott LaVarnway's avatar
Scott LaVarnway committed
670 671
    int pre_stride = x->e_mbd.pre.y_stride;
    unsigned char *base_pre = x->e_mbd.pre.y_buffer;
672 673 674

#if ARCH_X86 || ARCH_X86_64
    MACROBLOCKD *xd = &x->e_mbd;
Scott LaVarnway's avatar
Scott LaVarnway committed
675
    unsigned char *y0 = base_pre + d->offset + (bestmv->as_mv.row) * pre_stride + bestmv->as_mv.col;
676 677 678 679
    unsigned char *y;

    y_stride = 32;
    /* Copy 18 rows x 32 cols area to intermediate buffer before searching. */
Scott LaVarnway's avatar
Scott LaVarnway committed
680
    vfp->copymem(y0 - 1 - pre_stride, pre_stride, xd->y_buf, y_stride, 18);
681 682
    y = xd->y_buf + y_stride + 1;
#else
Scott LaVarnway's avatar
Scott LaVarnway committed
683 684
    unsigned char *y = base_pre + d->offset + (bestmv->as_mv.row) * pre_stride + bestmv->as_mv.col;
    y_stride = pre_stride;
685
#endif
John Koleszar's avatar
John Koleszar committed
686 687

    // central mv
Scott LaVarnway's avatar
Scott LaVarnway committed
688 689
    bestmv->as_mv.row <<= 3;
    bestmv->as_mv.col <<= 3;
John Koleszar's avatar
John Koleszar committed
690 691 692
    startmv = *bestmv;

    // calculate central point error
693
    bestmse = vfp->vf(y, y_stride, z, b->src_stride, sse1);
694
    *distortion = bestmse;
695
    bestmse += mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
696 697

    // go left then right and check error
Scott LaVarnway's avatar
Scott LaVarnway committed
698 699
    this_mv.as_mv.row = startmv.as_mv.row;
    this_mv.as_mv.col = ((startmv.as_mv.col - 8) | 4);
700
    thismse = vfp->svf_halfpix_h(y - 1, y_stride, z, b->src_stride, &sse);
701
    left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
702 703 704 705 706

    if (left < bestmse)
    {
        *bestmv = this_mv;
        bestmse = left;
707
        *distortion = thismse;
708
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
709 710
    }

Scott LaVarnway's avatar
Scott LaVarnway committed
711
    this_mv.as_mv.col += 8;
712
    thismse = vfp->svf_halfpix_h(y, y_stride, z, b->src_stride, &sse);
713
    right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
714 715 716 717 718

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

    // go up then down and check error
Scott LaVarnway's avatar
Scott LaVarnway committed
724 725
    this_mv.as_mv.col = startmv.as_mv.col;
    this_mv.as_mv.row = ((startmv.as_mv.row - 8) | 4);
726
    thismse = vfp->svf_halfpix_v(y - y_stride, y_stride, z, b->src_stride, &sse);
727
    up = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
728 729 730 731 732

    if (up < bestmse)
    {
        *bestmv = this_mv;
        bestmse = up;
733
        *distortion = thismse;
734
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
735 736
    }

Scott LaVarnway's avatar
Scott LaVarnway committed
737
    this_mv.as_mv.row += 8;
738
    thismse = vfp->svf_halfpix_v(y, y_stride, z, b->src_stride, &sse);
739
    down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
740 741 742 743 744

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

    // now check 1 more diagonal -
    whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
    this_mv = startmv;

    switch (whichdir)
    {
    case 0:
Yunqing Wang's avatar
Yunqing Wang committed
756 757 758
        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
759 760
        break;
    case 1:
Yunqing Wang's avatar
Yunqing Wang committed
761 762 763
        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
764 765
        break;
    case 2:
Yunqing Wang's avatar
Yunqing Wang committed
766 767 768
        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
769 770
        break;
    case 3:
Yunqing Wang's avatar
Yunqing Wang committed
771 772 773 774
    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
775 776 777
        break;
    }

778
    diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
779 780 781 782 783

    if (diag < bestmse)
    {
        *bestmv = this_mv;
        bestmse = diag;
784
        *distortion = thismse;
785
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
786 787 788 789 790
    }

    return bestmse;
}

Yunqing Wang's avatar
Yunqing Wang committed
791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811
#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)\
    {\
812
        thissad += mvsad_err_cost(&this_mv, &fcenter_mv, mvsadcost, sad_per_bit);\
Yunqing Wang's avatar
Yunqing Wang committed
813 814 815 816 817 818 819
        if (thissad < bestsad)\
        {\
            bestsad = thissad;\
            best_site = i;\
        }\
    }\
}
John Koleszar's avatar
John Koleszar committed
820

821 822 823 824 825 826 827 828 829
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
830

John Koleszar's avatar
John Koleszar committed
831 832 833 834 835
int vp8_hex_search
(
    MACROBLOCK *x,
    BLOCK *b,
    BLOCKD *d,
Scott LaVarnway's avatar
Scott LaVarnway committed
836 837
    int_mv *ref_mv,
    int_mv *best_mv,
John Koleszar's avatar
John Koleszar committed
838
    int search_param,
839
    int sad_per_bit,
840
    const vp8_variance_fn_ptr_t *vfp,
John Koleszar's avatar
John Koleszar committed
841
    int *mvsadcost[2],
842
    int *mvcost[2],
Scott LaVarnway's avatar
Scott LaVarnway committed
843
    int_mv *center_mv
John Koleszar's avatar
John Koleszar committed
844 845
)
{
846
    MV hex[6] = { { -1, -2}, {1, -2}, {2, 0}, {1, 2}, { -1, 2}, { -2, 0} } ;
Yunqing Wang's avatar
Yunqing Wang committed
847
    MV neighbors[4] = {{0, -1}, { -1, 0}, {1, 0}, {0, 1}} ;
John Koleszar's avatar
John Koleszar committed
848 849
    int i, j;

Yunqing Wang's avatar
Yunqing Wang committed
850 851
    unsigned char *what = (*(b->base_src) + b->src);
    int what_stride = b->src_stride;
Scott LaVarnway's avatar
Scott LaVarnway committed
852 853 854 855
    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;
856
    int br, bc;
Yunqing Wang's avatar
Yunqing Wang committed
857 858 859 860 861 862 863 864
    int_mv this_mv;
    unsigned int bestsad = 0x7fffffff;
    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
865 866
    int hex_range = 127;
    int dia_range = 8;
Yunqing Wang's avatar
Yunqing Wang committed
867 868 869 870 871

    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;

872 873 874 875 876
    // adjust ref_mv to make sure it is within MV range
    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;

Yunqing Wang's avatar
Yunqing Wang committed
877
    // Work out the start point for the search
Scott LaVarnway's avatar
Scott LaVarnway committed
878 879
    base_offset = (unsigned char *)(base_pre + d->offset);
    this_offset = base_offset + (br * (pre_stride)) + bc;
Yunqing Wang's avatar
Yunqing Wang committed
880 881
    this_mv.as_mv.row = br;
    this_mv.as_mv.col = bc;
882 883 884
    bestsad = vfp->sdf( what, what_stride, this_offset,
                        in_what_stride, 0x7fffffff)
            + mvsad_err_cost(&this_mv, &fcenter_mv, mvsadcost, sad_per_bit);
John Koleszar's avatar
John Koleszar committed
885

Yunqing Wang's avatar
Yunqing Wang committed
886 887 888 889 890 891 892 893 894 895 896 897
#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;
#endif

898 899
    // hex search
    //j=0
Yunqing Wang's avatar
Yunqing Wang committed
900
    CHECK_BOUNDS(2)
901

Yunqing Wang's avatar
Yunqing Wang committed
902
    if(all_in)
903
    {
Yunqing Wang's avatar
Yunqing Wang committed
904
        for (i = 0; i < 6; i++)
905
        {
Yunqing Wang's avatar
Yunqing Wang committed
906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921
            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;
            thissad=vfp->sdf( what, what_stride, this_offset, in_what_stride, bestsad);
            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;
            thissad=vfp->sdf( what, what_stride, this_offset, in_what_stride, bestsad);
            CHECK_BETTER
922 923 924
        }
    }

Yunqing Wang's avatar
Yunqing Wang committed
925
    if (best_site == -1)
926
        goto cal_neighbors;
Yunqing Wang's avatar
Yunqing Wang committed
927 928 929 930 931 932
    else
    {
        br += hex[best_site].row;
        bc += hex[best_site].col;
        k = best_site;
    }
933

Yunqing Wang's avatar
Yunqing Wang committed
934
    for (j = 1; j < hex_range; j++)
John Koleszar's avatar
John Koleszar committed
935
    {
Yunqing Wang's avatar
Yunqing Wang committed
936 937
        best_site = -1;
        CHECK_BOUNDS(2)
John Koleszar's avatar
John Koleszar committed
938

Yunqing Wang's avatar
Yunqing Wang committed
939
        if(all_in)
John Koleszar's avatar
John Koleszar committed
940
        {
Yunqing Wang's avatar
Yunqing Wang committed
941
            for (i = 0; i < 3; i++)
942
            {
Yunqing Wang's avatar
Yunqing Wang committed
943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958
                this_mv.as_mv.row = br + next_chkpts[k][i].row;
                this_mv.as_mv.col = bc + next_chkpts[k][i].col;
                this_offset = base_offset + (this_mv.as_mv.row * (in_what_stride)) + this_mv.as_mv.col;
                thissad = vfp->sdf( what, what_stride, this_offset, in_what_stride, bestsad);
                CHECK_BETTER
            }
        }else
        {
            for (i = 0; i < 3; i++)
            {
                this_mv.as_mv.row = br + next_chkpts[k][i].row;
                this_mv.as_mv.col = bc + next_chkpts[k][i].col;
                CHECK_POINT
                this_offset = base_offset + (this_mv.as_mv.row * (in_what_stride)) + this_mv.as_mv.col;
                thissad = vfp->sdf( what, what_stride, this_offset, in_what_stride, bestsad);
                CHECK_BETTER
959
            }
John Koleszar's avatar
John Koleszar committed
960 961
        }

Yunqing Wang's avatar
Yunqing Wang committed
962
        if (best_site == -1)
John Koleszar's avatar
John Koleszar committed
963
            break;
Yunqing Wang's avatar
Yunqing Wang committed
964 965 966 967 968 969 970 971
        else
        {
            br += next_chkpts[k][best_site].row;
            bc += next_chkpts[k][best_site].col;
            k += 5 + best_site;
            if (k >= 12) k -= 12;
            else if (k >= 6) k -= 6;
        }
John Koleszar's avatar
John Koleszar committed
972 973
    }

Yunqing Wang's avatar
Yunqing Wang committed
974
    // check 4 1-away neighbors
975
cal_neighbors:
Yunqing Wang's avatar
Yunqing Wang committed
976
    for (j = 0; j < dia_range; j++)
John Koleszar's avatar
John Koleszar committed
977
    {
Yunqing Wang's avatar
Yunqing Wang committed
978 979
        best_site = -1;