mcomp.c 61.8 KB
Newer Older
John Koleszar's avatar
John Koleszar committed
1
/*
2
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
John Koleszar's avatar
John Koleszar committed
3
 *
4
 *  Use of this source code is governed by a BSD-style license
5 6
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
7
 *  in the file PATENTS.  All contributing project authors may
8
 *  be found in the AUTHORS file in the root of the source tree.
John Koleszar's avatar
John Koleszar committed
9 10 11 12 13
 */


#include "mcomp.h"
#include "vpx_mem/vpx_mem.h"
14
#include "vpx_ports/config.h"
John Koleszar's avatar
John Koleszar committed
15 16 17
#include <stdio.h>
#include <limits.h>
#include <math.h>
18
#include "vp8/common/findnearmv.h"
John Koleszar's avatar
John Koleszar committed
19 20 21 22 23 24

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

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

Scott LaVarnway's avatar
Scott LaVarnway committed
41
static int mvsad_err_cost(int_mv *mv, int_mv *ref, int *mvsadcost[2], int error_per_bit)
42 43
{
    /* Calculate sad error cost on full pixel basis. */
Scott LaVarnway's avatar
Scott LaVarnway committed
44 45 46
    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
47 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
}

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

169 170 171 172 173 174 175 176 177
/*
 * 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
178
#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)
179
#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
180
#define SP(x) (((x)&3)<<1) // convert motion vector component to offset for svf calc
181
#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
182 183
#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
184
#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
185 186 187
#define MIN(x,y) (((x)<(y))?(x):(y))
#define MAX(x,y) (((x)>(y))?(x):(y))

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

Scott LaVarnway's avatar
Scott LaVarnway committed
197 198
    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
199 200 201 202 203 204 205
    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;
206
    int thismse;
John Koleszar's avatar
John Koleszar committed
207

Scott LaVarnway's avatar
Scott LaVarnway committed
208 209 210 211
    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
212

213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
    int y_stride;
    int offset;

#if ARCH_X86 || ARCH_X86_64
    MACROBLOCKD *xd = &x->e_mbd;
    unsigned char *y0 = *(d->base_pre) + d->pre + (bestmv->as_mv.row) * d->pre_stride + bestmv->as_mv.col;
    unsigned char *y;
    int buf_r1, buf_r2, buf_c1, buf_c2;

    // Clamping to avoid out-of-range data access
    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. */
    vfp->copymem(y0 - buf_c1 - d->pre_stride*buf_r1, d->pre_stride, xd->y_buf, y_stride, 16+buf_r1+buf_r2);
    y = xd->y_buf + y_stride*buf_r1 +buf_c1;
#else
    unsigned char *y = *(d->base_pre) + d->pre + (bestmv->as_mv.row) * d->pre_stride + bestmv->as_mv.col;
    y_stride = d->pre_stride;
#endif

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

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

    // calculate central point error
244
    besterr = vfp->vf(y, y_stride, z, b->src_stride, sse1);
245
    *distortion = besterr;
246
    besterr += mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
247 248 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

    // 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
318 319
    bestmv->as_mv.row = br << 1;
    bestmv->as_mv.col = bc << 1;
John Koleszar's avatar
John Koleszar committed
320

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

    return besterr;
}
#undef MVC
#undef PRE
#undef SP
#undef DIST
331
#undef IFMVCV
John Koleszar's avatar
John Koleszar committed
332 333 334 335
#undef ERR
#undef CHECK_BETTER
#undef MIN
#undef MAX
Scott LaVarnway's avatar
Scott LaVarnway committed
336 337 338 339 340 341
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
342 343
{
    int bestmse = INT_MAX;
Scott LaVarnway's avatar
Scott LaVarnway committed
344 345
    int_mv startmv;
    int_mv this_mv;
John Koleszar's avatar
John Koleszar committed
346 347 348 349
    unsigned char *z = (*(b->base_src) + b->src);
    int left, right, up, down, diag;
    unsigned int sse;
    int whichdir ;
350
    int thismse;
351 352 353 354 355 356 357 358 359 360 361 362 363 364 365
    int y_stride;

#if ARCH_X86 || ARCH_X86_64
    MACROBLOCKD *xd = &x->e_mbd;
    unsigned char *y0 = *(d->base_pre) + d->pre + (bestmv->as_mv.row) * d->pre_stride + bestmv->as_mv.col;
    unsigned char *y;

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

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

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

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

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

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

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

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

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

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

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


    // 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
439 440
        this_mv.as_mv.col = (this_mv.as_mv.col - 8) | 4;
        this_mv.as_mv.row = (this_mv.as_mv.row - 8) | 4;
441
        thismse = vfp->svf_halfpix_hv(y - 1 - y_stride, y_stride, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
442 443
        break;
    case 1:
Scott LaVarnway's avatar
Scott LaVarnway committed
444 445
        this_mv.as_mv.col += 4;
        this_mv.as_mv.row = (this_mv.as_mv.row - 8) | 4;
446
        thismse = vfp->svf_halfpix_hv(y - y_stride, y_stride, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
447 448
        break;
    case 2:
Scott LaVarnway's avatar
Scott LaVarnway committed
449 450
        this_mv.as_mv.col = (this_mv.as_mv.col - 8) | 4;
        this_mv.as_mv.row += 4;
451
        thismse = vfp->svf_halfpix_hv(y - 1, y_stride, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
452 453
        break;
    case 3:
454
    default:
Scott LaVarnway's avatar
Scott LaVarnway committed
455 456
        this_mv.as_mv.col += 4;
        this_mv.as_mv.row += 4;
457
        thismse = vfp->svf_halfpix_hv(y, y_stride, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
458 459 460
        break;
    }

461
    diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
462 463 464 465 466

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

//  }


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

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

    startmv = *bestmv;



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

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

499
    left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
500 501 502 503 504

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

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

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

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

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

535
    up = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
536 537 538 539 540

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

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

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


    // 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
569
        if (startmv.as_mv.row & 7)
John Koleszar's avatar
John Koleszar committed
570
        {
Scott LaVarnway's avatar
Scott LaVarnway committed
571
            this_mv.as_mv.row -= 2;
John Koleszar's avatar
John Koleszar committed
572

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

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

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

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

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

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

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

638
    diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
639 640 641 642 643

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

    return bestmse;
}

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

#if ARCH_X86 || ARCH_X86_64
    MACROBLOCKD *xd = &x->e_mbd;
    unsigned char *y0 = *(d->base_pre) + d->pre + (bestmv->as_mv.row) * d->pre_stride + bestmv->as_mv.col;
    unsigned char *y;

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

    // central mv
Scott LaVarnway's avatar
Scott LaVarnway committed
682 683
    bestmv->as_mv.row <<= 3;
    bestmv->as_mv.col <<= 3;
John Koleszar's avatar
John Koleszar committed
684 685 686
    startmv = *bestmv;

    // calculate central point error
687
    bestmse = vfp->vf(y, y_stride, z, b->src_stride, sse1);
688
    *distortion = bestmse;
689
    bestmse += mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
690 691

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

    if (left < bestmse)
    {
        *bestmv = this_mv;
        bestmse = left;
701
        *distortion = thismse;
702
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
703 704
    }

Scott LaVarnway's avatar
Scott LaVarnway committed
705
    this_mv.as_mv.col += 8;
706
    thismse = vfp->svf_halfpix_h(y, y_stride, z, b->src_stride, &sse);
707
    right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
708 709 710 711 712

    if (right < bestmse)
    {
        *bestmv = this_mv;
        bestmse = right;
713
        *distortion = thismse;
714
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
715 716 717
    }

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

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

Scott LaVarnway's avatar
Scott LaVarnway committed
731
    this_mv.as_mv.row += 8;
732
    thismse = vfp->svf_halfpix_v(y, y_stride, z, b->src_stride, &sse);
733
    down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
734 735 736 737 738

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

    // somewhat strangely not doing all the diagonals for half pel is slower than doing them.
#if 0
    // now check 1 more diagonal -
    whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
    this_mv = startmv;

    switch (whichdir)
    {
    case 0:
        this_mv.col = (this_mv.col - 8) | 4;
        this_mv.row = (this_mv.row - 8) | 4;
754
        diag = vfp->svf(y - 1 - y_stride, y_stride, 4, 4, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
755 756 757 758
        break;
    case 1:
        this_mv.col += 4;
        this_mv.row = (this_mv.row - 8) | 4;
759
        diag = vfp->svf(y - y_stride, y_stride, 4, 4, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
760 761 762 763
        break;
    case 2:
        this_mv.col = (this_mv.col - 8) | 4;
        this_mv.row += 4;
764
        diag = vfp->svf(y - 1, y_stride, 4, 4, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
765 766 767 768
        break;
    case 3:
        this_mv.col += 4;
        this_mv.row += 4;
769
        diag = vfp->svf(y, y_stride, 4, 4, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
770 771 772
        break;
    }

773
    diag += mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
774 775 776 777 778 779 780 781

    if (diag < bestmse)
    {
        *bestmv = this_mv;
        bestmse = diag;
    }

#else
Scott LaVarnway's avatar
Scott LaVarnway committed
782 783
    this_mv.as_mv.col = (this_mv.as_mv.col - 8) | 4;
    this_mv.as_mv.row = (this_mv.as_mv.row - 8) | 4;
784
    thismse = vfp->svf_halfpix_hv(y - 1 - y_stride, y_stride, z, b->src_stride, &sse);
785
    diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
786 787 788 789 790

    if (diag < bestmse)
    {
        *bestmv = this_mv;
        bestmse = diag;
791
        *distortion = thismse;
792
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
793 794
    }

Scott LaVarnway's avatar
Scott LaVarnway committed
795
    this_mv.as_mv.col += 8;
796
    thismse = vfp->svf_halfpix_hv(y - y_stride, y_stride, z, b->src_stride, &sse);
797
    diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
798 799 800 801 802

    if (diag < bestmse)
    {
        *bestmv = this_mv;
        bestmse = diag;
803
        *distortion = thismse;
804
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
805 806
    }

Scott LaVarnway's avatar
Scott LaVarnway committed
807 808
    this_mv.as_mv.col = (this_mv.as_mv.col - 8) | 4;
    this_mv.as_mv.row = startmv.as_mv.row + 4;
809
    thismse = vfp->svf_halfpix_hv(y - 1, y_stride, z, b->src_stride, &sse);
810
    diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
811 812 813 814 815

    if (diag < bestmse)
    {
        *bestmv = this_mv;
        bestmse = diag;
816
        *distortion = thismse;
817
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
818 819
    }

Scott LaVarnway's avatar
Scott LaVarnway committed
820
    this_mv.as_mv.col += 8;
821
    thismse = vfp->svf_halfpix_hv(y, y_stride, z, b->src_stride, &sse);
822
    diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
823 824 825 826 827

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

#endif
    return bestmse;
}

Yunqing Wang's avatar
Yunqing Wang committed
836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856
#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)\
    {\
857
        thissad += mvsad_err_cost(&this_mv, &fcenter_mv, mvsadcost, sad_per_bit);\
Yunqing Wang's avatar
Yunqing Wang committed
858 859 860 861 862 863 864
        if (thissad < bestsad)\
        {\
            bestsad = thissad;\
            best_site = i;\
        }\
    }\
}
John Koleszar's avatar
John Koleszar committed
865

866 867 868 869 870 871 872 873 874
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
875

John Koleszar's avatar
John Koleszar committed
876 877 878 879 880
int vp8_hex_search
(
    MACROBLOCK *x,
    BLOCK *b,
    BLOCKD *d,
Scott LaVarnway's avatar
Scott LaVarnway committed
881 882
    int_mv *ref_mv,
    int_mv *best_mv,
John Koleszar's avatar
John Koleszar committed
883
    int search_param,
884
    int sad_per_bit,
885
    const vp8_variance_fn_ptr_t *vfp,
John Koleszar's avatar
John Koleszar committed
886
    int *mvsadcost[2],
887
    int *mvcost[2],
Scott LaVarnway's avatar
Scott LaVarnway committed
888
    int_mv *center_mv
John Koleszar's avatar
John Koleszar committed
889 890
)
{
891
    MV hex[6] = { { -1, -2}, {1, -2}, {2, 0}, {1, 2}, { -1, 2}, { -2, 0} } ;
Yunqing Wang's avatar
Yunqing Wang committed
892
    MV neighbors[4] = {{0, -1}, { -1, 0}, {1, 0}, {0, 1}} ;
John Koleszar's avatar
John Koleszar committed
893 894
    int i, j;

Yunqing Wang's avatar
Yunqing Wang committed
895 896 897
    unsigned char *what = (*(b->base_src) + b->src);
    int what_stride = b->src_stride;
    int in_what_stride = d->pre_stride;
898
    int br, bc;
Yunqing Wang's avatar
Yunqing Wang committed
899 900 901 902 903 904 905 906 907 908 909 910 911
    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;

    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;

912 913 914 915 916
    // 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
917 918 919 920 921
    // Work out the start point for the search
    base_offset = (unsigned char *)(*(d->base_pre) + d->pre);
    this_offset = base_offset + (br * (d->pre_stride)) + bc;
    this_mv.as_mv.row = br;
    this_mv.as_mv.col = bc;
922 923 924
    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
925

926 927
    // hex search
    //j=0
Yunqing Wang's avatar
Yunqing Wang committed
928
    CHECK_BOUNDS(2)
929

Yunqing Wang's avatar
Yunqing Wang committed
930
    if(all_in)
931
    {
Yunqing Wang's avatar
Yunqing Wang committed
932
        for (i = 0; i < 6; i++)
933
        {
Yunqing Wang's avatar
Yunqing Wang committed
934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949
            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
950 951 952
        }
    }

Yunqing Wang's avatar
Yunqing Wang committed
953
    if (best_site == -1)
954
        goto cal_neighbors;
Yunqing Wang's avatar
Yunqing Wang committed
955 956 957 958 959 960
    else
    {
        br += hex[best_site].row;
        bc += hex[best_site].col;
        k = best_site;
    }
961 962

    for (j = 1; j < 127; j++)
John Koleszar's avatar
John Koleszar committed
963
    {
Yunqing Wang's avatar
Yunqing Wang committed
964 965
        best_site = -1;
        CHECK_BOUNDS(2)
John Koleszar's avatar
John Koleszar committed
966

Yunqing Wang's avatar
Yunqing Wang committed
967
        if(all_in)
John Koleszar's avatar
John Koleszar committed
968
        {
Yunqing Wang's avatar
Yunqing Wang committed
969
            for (i = 0; i < 3; i++)
970
            {
Yunqing Wang's avatar
Yunqing Wang committed
971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986
                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
987
            }
John Koleszar's avatar
John Koleszar committed
988 989
        }

Yunqing Wang's avatar
Yunqing Wang committed
990
        if (best_site == -1)
John Koleszar's avatar
John Koleszar committed
991
            break;
Yunqing Wang's avatar
Yunqing Wang committed
992 993 994 995 996 997 998 999
        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
1000 1001
    }

Yunqing Wang's avatar
Yunqing Wang committed
1002
    // check 4 1-away neighbors
1003
cal_neighbors:
Yunqing Wang's avatar
Yunqing Wang committed
1004
    for (j = 0; j < 32; j++)
John Koleszar's avatar
John Koleszar committed
1005
    {
Yunqing Wang's avatar
Yunqing Wang committed
1006 1007
        best_site = -1;
        CHECK_BOUNDS(1)
John Koleszar's avatar
John Koleszar committed
1008

Yunqing Wang's avatar
Yunqing Wang committed
1009
        if(all_in)
Yunqing Wang's avatar
Yunqing Wang committed
1010
        {
Yunqing Wang's avatar
Yunqing Wang committed
1011 1012 1013 1014 1015