mcomp.c 60.4 KB
Newer Older
John Koleszar's avatar
John Koleszar committed
1
/*
2
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
John Koleszar's avatar
John Koleszar committed
3
 *
4
 *  Use of this source code is governed by a BSD-style license
5 6
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
7
 *  in the file PATENTS.  All contributing project authors may
8
 *  be found in the AUTHORS file in the root of the source tree.
John Koleszar's avatar
John Koleszar committed
9 10 11 12 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;
Yunqing Wang's avatar
Yunqing Wang committed
664
    int whichdir ;
665
    int thismse;
666 667 668 669 670 671 672 673 674 675 676 677 678 679 680
    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
681 682

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

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

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

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

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

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

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

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

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

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

    // 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
751 752 753
        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
754 755
        break;
    case 1:
Yunqing Wang's avatar
Yunqing Wang committed
756 757 758
        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
759 760
        break;
    case 2:
Yunqing Wang's avatar
Yunqing Wang committed
761 762 763
        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
764 765
        break;
    case 3:
Yunqing Wang's avatar
Yunqing Wang committed
766 767 768 769
    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
770 771 772
        break;
    }

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

    if (diag < bestmse)
    {
        *bestmv = this_mv;
        bestmse = diag;
779
        *distortion = thismse;
780
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
781 782 783 784 785
    }

    return bestmse;
}

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

816 817 818 819 820 821 822 823 824
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
825

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

Yunqing Wang's avatar
Yunqing Wang committed
845 846 847
    unsigned char *what = (*(b->base_src) + b->src);
    int what_stride = b->src_stride;
    int in_what_stride = d->pre_stride;
848
    int br, bc;
Yunqing Wang's avatar
Yunqing Wang committed
849 850 851 852 853 854 855 856 857 858 859 860 861
    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;

862 863 864 865 866
    // 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
867 868 869 870 871
    // 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;
872 873 874
    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
875

876 877
    // hex search
    //j=0
Yunqing Wang's avatar
Yunqing Wang committed
878
    CHECK_BOUNDS(2)
879

Yunqing Wang's avatar
Yunqing Wang committed
880
    if(all_in)
881
    {
Yunqing Wang's avatar
Yunqing Wang committed
882
        for (i = 0; i < 6; i++)
883
        {
Yunqing Wang's avatar
Yunqing Wang committed
884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899
            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
900 901 902
        }
    }

Yunqing Wang's avatar
Yunqing Wang committed
903
    if (best_site == -1)
904
        goto cal_neighbors;
Yunqing Wang's avatar
Yunqing Wang committed
905 906 907 908 909 910
    else
    {
        br += hex[best_site].row;
        bc += hex[best_site].col;
        k = best_site;
    }
911 912

    for (j = 1; j < 127; j++)
John Koleszar's avatar
John Koleszar committed
913
    {
Yunqing Wang's avatar
Yunqing Wang committed
914 915
        best_site = -1;
        CHECK_BOUNDS(2)
John Koleszar's avatar
John Koleszar committed
916

Yunqing Wang's avatar
Yunqing Wang committed
917
        if(all_in)
John Koleszar's avatar
John Koleszar committed
918
        {
Yunqing Wang's avatar
Yunqing Wang committed
919
            for (i = 0; i < 3; i++)
920
            {
Yunqing Wang's avatar
Yunqing Wang committed
921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936
                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
937
            }
John Koleszar's avatar
John Koleszar committed
938 939
        }

Yunqing Wang's avatar
Yunqing Wang committed
940
        if (best_site == -1)
John Koleszar's avatar
John Koleszar committed
941
            break;
Yunqing Wang's avatar
Yunqing Wang committed
942 943 944 945 946 947 948 949
        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
950 951
    }

Yunqing Wang's avatar
Yunqing Wang committed
952
    // check 4 1-away neighbors
953
cal_neighbors:
Yunqing Wang's avatar
Yunqing Wang committed
954
    for (j = 0; j < 32; j++)
John Koleszar's avatar
John Koleszar committed
955
    {
Yunqing Wang's avatar
Yunqing Wang committed
956 957
        best_site = -1;
        CHECK_BOUNDS(1)
John Koleszar's avatar
John Koleszar committed
958

Yunqing Wang's avatar
Yunqing Wang committed
959
        if(all_in)
Yunqing Wang's avatar
Yunqing Wang committed
960
        {
Yunqing Wang's avatar
Yunqing Wang committed
961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979
            for (i = 0; i < 4; i++)
            {
                this_mv.as_mv.row = br + neighbors[i].row;
                this_mv.as_mv.col = bc + neighbors[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 < 4; i++)
            {
                this_mv.as_mv.row = br + neighbors[i].row;
                this_mv.as_mv.col = bc + neighbors[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
            }
Yunqing Wang's avatar
Yunqing Wang committed
980 981
        }

Yunqing Wang's avatar
Yunqing Wang committed
982
        if (best_site == -1)
Yunqing Wang's avatar
Yunqing Wang committed
983
            break;
Yunqing Wang's avatar
Yunqing Wang committed
984 985 986 987 988
        else
        {
            br += neighbors[best_site].row;
            bc += neighbors[best_site].col;
        }
John Koleszar's avatar
John Koleszar committed
989 990
    }

Scott LaVarnway's avatar
Scott LaVarnway committed
991 992
    best_mv->as_mv.row = br;
    best_mv->as_mv.col = bc;
John Koleszar's avatar
John Koleszar committed
993

994
    return bestsad;
John Koleszar's avatar
John Koleszar committed
995
}
Yunqing Wang's avatar
Yunqing Wang committed
996 997
#undef CHECK_BOUNDS
#undef CHECK_POINT
John Koleszar's avatar
John Koleszar committed
998
#undef CHECK_BETTER
999

John Koleszar's avatar
John Koleszar committed
1000 1001 1002 1003 1004
int vp8_diamond_search_sad
(
    MACROBLOCK *x,
    BLOCK *b,
    BLOCKD *d,
Scott LaVarnway's avatar
Scott LaVarnway committed
1005 1006
    int_mv *ref_mv,
    int_mv *best_mv,
John Koleszar's avatar
John Koleszar committed
1007
    int search_param,
1008
    int sad_per_bit,
John Koleszar's avatar
John Koleszar committed
1009 1010
    int *num00,
    vp8_variance_fn_ptr_t *fn_ptr,
1011
    int *mvcost[2],
Scott LaVarnway's avatar
Scott LaVarnway committed
1012
    int_mv *center_mv
John Koleszar's avatar
John Koleszar committed
1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023
)
{
    int i, j, step;

    unsigned char *what = (*(