mcomp.c 61.1 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 346
    int_mv startmv;
    int_mv this_mv;
    unsigned char *y = *(d->base_pre) + d->pre + (bestmv->as_mv.row) * d->pre_stride + bestmv->as_mv.col;
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;
John Koleszar's avatar
John Koleszar committed
352 353

    // central mv
Scott LaVarnway's avatar
Scott LaVarnway committed
354 355
    bestmv->as_mv.row <<= 3;
    bestmv->as_mv.col <<= 3;
John Koleszar's avatar
John Koleszar committed
356 357 358
    startmv = *bestmv;

    // calculate central point error
359
    bestmse = vfp->vf(y, d->pre_stride, z, b->src_stride, sse1);
360
    *distortion = bestmse;
361
    bestmse += mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
362 363

    // go left then right and check error
Scott LaVarnway's avatar
Scott LaVarnway committed
364 365
    this_mv.as_mv.row = startmv.as_mv.row;
    this_mv.as_mv.col = ((startmv.as_mv.col - 8) | 4);
366 367
    thismse = vfp->svf_halfpix_h(y - 1, d->pre_stride, z, b->src_stride, &sse);
    left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
368 369 370 371 372

    if (left < bestmse)
    {
        *bestmv = this_mv;
        bestmse = left;
373
        *distortion = thismse;
374
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
375 376
    }

Scott LaVarnway's avatar
Scott LaVarnway committed
377
    this_mv.as_mv.col += 8;
378 379
    thismse = vfp->svf_halfpix_h(y, d->pre_stride, z, b->src_stride, &sse);
    right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
380 381 382 383 384

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

    // go up then down and check error
Scott LaVarnway's avatar
Scott LaVarnway committed
390 391
    this_mv.as_mv.col = startmv.as_mv.col;
    this_mv.as_mv.row = ((startmv.as_mv.row - 8) | 4);
392 393
    thismse =  vfp->svf_halfpix_v(y - d->pre_stride, d->pre_stride, z, b->src_stride, &sse);
    up = 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 (up < bestmse)
    {
        *bestmv = this_mv;
        bestmse = up;
399
        *distortion = thismse;
400
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
401 402
    }

Scott LaVarnway's avatar
Scott LaVarnway committed
403
    this_mv.as_mv.row += 8;
404 405
    thismse = vfp->svf_halfpix_v(y, d->pre_stride, z, b->src_stride, &sse);
    down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
406 407 408 409 410

    if (down < bestmse)
    {
        *bestmv = this_mv;
        bestmse = down;
411
        *distortion = thismse;
412
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
413 414 415 416 417 418 419 420 421 422 423 424
    }


    // 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
425 426
        this_mv.as_mv.col = (this_mv.as_mv.col - 8) | 4;
        this_mv.as_mv.row = (this_mv.as_mv.row - 8) | 4;
427
        thismse = vfp->svf_halfpix_hv(y - 1 - d->pre_stride, d->pre_stride, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
428 429
        break;
    case 1:
Scott LaVarnway's avatar
Scott LaVarnway committed
430 431
        this_mv.as_mv.col += 4;
        this_mv.as_mv.row = (this_mv.as_mv.row - 8) | 4;
432
        thismse = vfp->svf_halfpix_hv(y - d->pre_stride, d->pre_stride, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
433 434
        break;
    case 2:
Scott LaVarnway's avatar
Scott LaVarnway committed
435 436
        this_mv.as_mv.col = (this_mv.as_mv.col - 8) | 4;
        this_mv.as_mv.row += 4;
437
        thismse = vfp->svf_halfpix_hv(y - 1, d->pre_stride, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
438 439
        break;
    case 3:
440
    default:
Scott LaVarnway's avatar
Scott LaVarnway committed
441 442
        this_mv.as_mv.col += 4;
        this_mv.as_mv.row += 4;
443
        thismse = vfp->svf_halfpix_hv(y, d->pre_stride, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
444 445 446
        break;
    }

447
    diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
448 449 450 451 452

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

//  }


    // time to check quarter pels.
Scott LaVarnway's avatar
Scott LaVarnway committed
461
    if (bestmv->as_mv.row < startmv.as_mv.row)
John Koleszar's avatar
John Koleszar committed
462 463
        y -= d->pre_stride;

Scott LaVarnway's avatar
Scott LaVarnway committed
464
    if (bestmv->as_mv.col < startmv.as_mv.col)
John Koleszar's avatar
John Koleszar committed
465 466 467 468 469 470 471
        y--;

    startmv = *bestmv;



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

Scott LaVarnway's avatar
Scott LaVarnway committed
474
    if (startmv.as_mv.col & 7)
John Koleszar's avatar
John Koleszar committed
475
    {
Scott LaVarnway's avatar
Scott LaVarnway committed
476 477
        this_mv.as_mv.col = startmv.as_mv.col - 2;
        thismse = vfp->svf(y, d->pre_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
478 479 480
    }
    else
    {
Scott LaVarnway's avatar
Scott LaVarnway committed
481 482
        this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6;
        thismse = vfp->svf(y - 1, d->pre_stride, 6, this_mv.as_mv.row & 7, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
483 484
    }

485
    left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
486 487 488 489 490

    if (left < bestmse)
    {
        *bestmv = this_mv;
        bestmse = left;
491
        *distortion = thismse;
492
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
493 494
    }

Scott LaVarnway's avatar
Scott LaVarnway committed
495 496
    this_mv.as_mv.col += 4;
    thismse = vfp->svf(y, d->pre_stride, this_mv.as_mv.col & 7, this_mv.as_mv.row & 7, z, b->src_stride, &sse);
497
    right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
498 499 500 501 502

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

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

Scott LaVarnway's avatar
Scott LaVarnway committed
510
    if (startmv.as_mv.row & 7)
John Koleszar's avatar
John Koleszar committed
511
    {
Scott LaVarnway's avatar
Scott LaVarnway committed
512 513
        this_mv.as_mv.row = startmv.as_mv.row - 2;
        thismse = vfp->svf(y, d->pre_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
514 515 516
    }
    else
    {
Scott LaVarnway's avatar
Scott LaVarnway committed
517 518
        this_mv.as_mv.row = (startmv.as_mv.row - 8) | 6;
        thismse = vfp->svf(y - d->pre_stride, d->pre_stride, this_mv.as_mv.col & 7, 6, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
519 520
    }

521
    up = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
522 523 524 525 526

    if (up < bestmse)
    {
        *bestmv = this_mv;
        bestmse = up;
527
        *distortion = thismse;
528
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
529 530
    }

Scott LaVarnway's avatar
Scott LaVarnway committed
531 532
    this_mv.as_mv.row += 4;
    thismse = vfp->svf(y, d->pre_stride, this_mv.as_mv.col & 7, this_mv.as_mv.row & 7, z, b->src_stride, &sse);
533
    down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
534 535 536 537 538

    if (down < bestmse)
    {
        *bestmv = this_mv;
        bestmse = down;
539
        *distortion = thismse;
540
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
541 542 543 544 545 546 547 548 549 550 551 552 553 554
    }


    // 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
555
        if (startmv.as_mv.row & 7)
John Koleszar's avatar
John Koleszar committed
556
        {
Scott LaVarnway's avatar
Scott LaVarnway committed
557
            this_mv.as_mv.row -= 2;
John Koleszar's avatar
John Koleszar committed
558

Scott LaVarnway's avatar
Scott LaVarnway committed
559
            if (startmv.as_mv.col & 7)
John Koleszar's avatar
John Koleszar committed
560
            {
Scott LaVarnway's avatar
Scott LaVarnway committed
561 562
                this_mv.as_mv.col -= 2;
                thismse = vfp->svf(y, d->pre_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
563 564 565
            }
            else
            {
Scott LaVarnway's avatar
Scott LaVarnway committed
566 567
                this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6;
                thismse = vfp->svf(y - 1, d->pre_stride, 6, this_mv.as_mv.row & 7, z, b->src_stride, &sse);;
John Koleszar's avatar
John Koleszar committed
568 569 570 571
            }
        }
        else
        {
Scott LaVarnway's avatar
Scott LaVarnway committed
572
            this_mv.as_mv.row = (startmv.as_mv.row - 8) | 6;
John Koleszar's avatar
John Koleszar committed
573

Scott LaVarnway's avatar
Scott LaVarnway committed
574
            if (startmv.as_mv.col & 7)
John Koleszar's avatar
John Koleszar committed
575
            {
Scott LaVarnway's avatar
Scott LaVarnway committed
576 577
                this_mv.as_mv.col -= 2;
                thismse = vfp->svf(y - d->pre_stride, d->pre_stride, this_mv.as_mv.col & 7, 6, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
578 579 580
            }
            else
            {
Scott LaVarnway's avatar
Scott LaVarnway committed
581
                this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6;
582
                thismse = vfp->svf(y - d->pre_stride - 1, d->pre_stride, 6, 6, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
583 584 585 586 587
            }
        }

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

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

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

Scott LaVarnway's avatar
Scott LaVarnway committed
605
        if (startmv.as_mv.col & 7)
John Koleszar's avatar
John Koleszar committed
606
        {
Scott LaVarnway's avatar
Scott LaVarnway committed
607 608
            this_mv.as_mv.col -= 2;
            thismse = vfp->svf(y, d->pre_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
609 610 611
        }
        else
        {
Scott LaVarnway's avatar
Scott LaVarnway committed
612 613
            this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6;
            thismse = vfp->svf(y - 1, d->pre_stride, 6, this_mv.as_mv.row & 7, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
614 615 616 617
        }

        break;
    case 3:
Scott LaVarnway's avatar
Scott LaVarnway committed
618 619 620
        this_mv.as_mv.col += 2;
        this_mv.as_mv.row += 2;
        thismse = vfp->svf(y, d->pre_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
621 622 623
        break;
    }

624
    diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
625 626 627 628 629

    if (diag < bestmse)
    {
        *bestmv = this_mv;
        bestmse = diag;
630
        *distortion = thismse;
631
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
632 633 634 635 636
    }

    return bestmse;
}

Scott LaVarnway's avatar
Scott LaVarnway committed
637 638 639 640 641 642
int vp8_find_best_half_pixel_step(MACROBLOCK *mb, 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
643 644
{
    int bestmse = INT_MAX;
Scott LaVarnway's avatar
Scott LaVarnway committed
645 646 647
    int_mv startmv;
    int_mv this_mv;
    unsigned char *y = *(d->base_pre) + d->pre + (bestmv->as_mv.row) * d->pre_stride + bestmv->as_mv.col;
John Koleszar's avatar
John Koleszar committed
648 649 650
    unsigned char *z = (*(b->base_src) + b->src);
    int left, right, up, down, diag;
    unsigned int sse;
651
    int thismse;
John Koleszar's avatar
John Koleszar committed
652 653

    // central mv
Scott LaVarnway's avatar
Scott LaVarnway committed
654 655
    bestmv->as_mv.row <<= 3;
    bestmv->as_mv.col <<= 3;
John Koleszar's avatar
John Koleszar committed
656 657 658
    startmv = *bestmv;

    // calculate central point error
659
    bestmse = vfp->vf(y, d->pre_stride, z, b->src_stride, sse1);
660
    *distortion = bestmse;
661
    bestmse += mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
662 663

    // go left then right and check error
Scott LaVarnway's avatar
Scott LaVarnway committed
664 665
    this_mv.as_mv.row = startmv.as_mv.row;
    this_mv.as_mv.col = ((startmv.as_mv.col - 8) | 4);
666 667
    thismse = vfp->svf_halfpix_h(y - 1, d->pre_stride, z, b->src_stride, &sse);
    left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
668 669 670 671 672

    if (left < bestmse)
    {
        *bestmv = this_mv;
        bestmse = left;
673
        *distortion = thismse;
674
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
675 676
    }

Scott LaVarnway's avatar
Scott LaVarnway committed
677
    this_mv.as_mv.col += 8;
678 679
    thismse = vfp->svf_halfpix_h(y, d->pre_stride, z, b->src_stride, &sse);
    right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
680 681 682 683 684

    if (right < bestmse)
    {
        *bestmv = this_mv;
        bestmse = right;
685
        *distortion = thismse;
686
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
687 688 689
    }

    // go up then down and check error
Scott LaVarnway's avatar
Scott LaVarnway committed
690 691
    this_mv.as_mv.col = startmv.as_mv.col;
    this_mv.as_mv.row = ((startmv.as_mv.row - 8) | 4);
692 693
    thismse = vfp->svf_halfpix_v(y - d->pre_stride, d->pre_stride, z, b->src_stride, &sse);
    up = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
694 695 696 697 698

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

Scott LaVarnway's avatar
Scott LaVarnway committed
703
    this_mv.as_mv.row += 8;
704 705
    thismse = vfp->svf_halfpix_v(y, d->pre_stride, z, b->src_stride, &sse);
    down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
706 707 708 709 710

    if (down < bestmse)
    {
        *bestmv = this_mv;
        bestmse = down;
711
        *distortion = thismse;
712
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
713 714 715 716 717 718 719 720 721 722 723 724 725
    }

    // 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;
726
        diag = vfp->svf(y - 1 - d->pre_stride, d->pre_stride, 4, 4, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
727 728 729 730
        break;
    case 1:
        this_mv.col += 4;
        this_mv.row = (this_mv.row - 8) | 4;
731
        diag = vfp->svf(y - d->pre_stride, d->pre_stride, 4, 4, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
732 733 734 735
        break;
    case 2:
        this_mv.col = (this_mv.col - 8) | 4;
        this_mv.row += 4;
736
        diag = vfp->svf(y - 1, d->pre_stride, 4, 4, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
737 738 739 740
        break;
    case 3:
        this_mv.col += 4;
        this_mv.row += 4;
741
        diag = vfp->svf(y, d->pre_stride, 4, 4, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
742 743 744
        break;
    }

745
    diag += mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
746 747 748 749 750 751 752 753

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

#else
Scott LaVarnway's avatar
Scott LaVarnway committed
754 755
    this_mv.as_mv.col = (this_mv.as_mv.col - 8) | 4;
    this_mv.as_mv.row = (this_mv.as_mv.row - 8) | 4;
756 757
    thismse = vfp->svf_halfpix_hv(y - 1 - d->pre_stride, d->pre_stride, z, b->src_stride, &sse);
    diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
758 759 760 761 762

    if (diag < bestmse)
    {
        *bestmv = this_mv;
        bestmse = diag;
763
        *distortion = thismse;
764
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
765 766
    }

Scott LaVarnway's avatar
Scott LaVarnway committed
767
    this_mv.as_mv.col += 8;
768 769
    thismse = vfp->svf_halfpix_hv(y - d->pre_stride, d->pre_stride, z, b->src_stride, &sse);
    diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
770 771 772 773 774

    if (diag < bestmse)
    {
        *bestmv = this_mv;
        bestmse = diag;
775
        *distortion = thismse;
776
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
777 778
    }

Scott LaVarnway's avatar
Scott LaVarnway committed
779 780
    this_mv.as_mv.col = (this_mv.as_mv.col - 8) | 4;
    this_mv.as_mv.row = startmv.as_mv.row + 4;
781 782
    thismse = vfp->svf_halfpix_hv(y - 1, d->pre_stride, z, b->src_stride, &sse);
    diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
783 784 785 786 787

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

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

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

#endif
    return bestmse;
}

Yunqing Wang's avatar
Yunqing Wang committed
808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828
#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)\
    {\
829
        thissad += mvsad_err_cost(&this_mv, &fcenter_mv, mvsadcost, sad_per_bit);\
Yunqing Wang's avatar
Yunqing Wang committed
830 831 832 833 834 835 836
        if (thissad < bestsad)\
        {\
            bestsad = thissad;\
            best_site = i;\
        }\
    }\
}
John Koleszar's avatar
John Koleszar committed
837

838 839 840 841 842 843 844 845 846
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
847

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

Yunqing Wang's avatar
Yunqing Wang committed
867 868 869
    unsigned char *what = (*(b->base_src) + b->src);
    int what_stride = b->src_stride;
    int in_what_stride = d->pre_stride;
870
    int br, bc;
Yunqing Wang's avatar
Yunqing Wang committed
871 872 873 874 875 876 877 878 879 880 881 882 883
    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;

884 885 886 887 888
    // 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
889 890 891 892 893
    // 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;
894 895 896
    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
897

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 934

    for (j = 1; j < 127; 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 < 32; j++)
John Koleszar's avatar
John Koleszar committed
977
    {
Yunqing Wang's avatar
Yunqing Wang committed
978 979
        best_site = -1;
        CHECK_BOUNDS(1)
John Koleszar's avatar
John Koleszar committed
980

Yunqing Wang's avatar
Yunqing Wang committed
981
        if(all_in)
Yunqing Wang's avatar
Yunqing Wang committed
982
        {
Yunqing Wang's avatar
Yunqing Wang committed
983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001
            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
1002 1003
        }

Yunqing Wang's avatar
Yunqing Wang committed
1004
        if (best_site == -1)
Yunqing Wang's avatar
Yunqing Wang committed
1005
            break;
Yunqing Wang's avatar
Yunqing Wang committed
1006 1007 1008 1009 1010
        else
        {
            br += neighbors[best_site].row;
            bc += neighbors[best_site].col;
        }
John Koleszar's avatar
John Koleszar committed
1011 1012
    }

Scott LaVarnway's avatar
Scott LaVarnway committed
1013 1014
    best_mv->as_mv.row = br;
    best_mv->as_mv.col = bc;
John Koleszar's avatar
John Koleszar committed
1015

1016
    return bestsad;
John Koleszar's avatar
John Koleszar committed
1017
}
Yunqing Wang's avatar
Yunqing Wang committed
1018 1019
#undef CHECK_BOUNDS
#undef CHECK_POINT
John Koleszar's avatar
John Koleszar committed
1020
#undef CHECK_BETTER
1021

John Koleszar's avatar
John Koleszar committed
1022 1023 1024 1025 1026
int vp8_diamond_search_sad
(
    MACROBLOCK *x,
    BLOCK *b,
    BLOCKD *d,
Scott LaVarnway's avatar
Scott LaVarnway committed
1027 1028
    int_mv *ref_mv,
    int_mv *best_mv,
John Koleszar's avatar
John Koleszar committed
1029
    int search_param,
1030
    int sad_per_bit,
John Koleszar's avatar
John Koleszar committed
1031 1032
    int *num00,
    vp8_variance_fn_ptr_t *fn_ptr,
1033
    int *mvcost[2],
Scott LaVarnway's avatar
Scott LaVarnway committed
1034
    int_mv *center_mv
John Koleszar's avatar
John Koleszar committed
1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045
)
{
    int i, j, step;

    unsigned char *what = (*(b->base_src) + b->src);
    int what_stride = b->src_stride;
    unsigned char *in_what;
    int in_what_stride = d->pre_stride;
    unsigned char *best_address;

    int tot_steps;
Scott LaVarnway's avatar
Scott LaVarnway committed
1046
    int_mv this_mv;
John Koleszar's avatar
John Koleszar committed
1047 1048 1049 1050 1051

    int bestsad = INT_MAX;
    int best_site = 0;
    int last_site = 0;