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


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

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

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

Scott LaVarnway's avatar
Scott LaVarnway committed
35
static int mv_err_cost(int_mv *mv, int_mv *ref, int *mvcost[2], int error_per_bit)
John Koleszar's avatar
John Koleszar committed
36
{
Scott LaVarnway's avatar
Scott LaVarnway committed
37 38 39
    return ((mvcost[0][(mv->as_mv.row - ref->as_mv.row) >> 1] +
        mvcost[1][(mv->as_mv.col - ref->as_mv.col) >> 1])
        * error_per_bit + 128) >> 8;
John Koleszar's avatar
John Koleszar committed
40 41
}

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

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


    // Generate offsets for 4 search sites per step.
    Len = MAX_FIRST_STEP;
    x->ss[search_site_count].mv.col = 0;
    x->ss[search_site_count].mv.row = 0;
    x->ss[search_site_count].offset = 0;
    search_site_count++;

    while (Len > 0)
    {

        // Compute offsets for search sites.
        x->ss[search_site_count].mv.col = 0;
        x->ss[search_site_count].mv.row = -Len;
        x->ss[search_site_count].offset = -Len * stride;
        search_site_count++;

        // Compute offsets for search sites.
        x->ss[search_site_count].mv.col = 0;
        x->ss[search_site_count].mv.row = Len;
        x->ss[search_site_count].offset = Len * stride;
        search_site_count++;

        // Compute offsets for search sites.
        x->ss[search_site_count].mv.col = -Len;
        x->ss[search_site_count].mv.row = 0;
        x->ss[search_site_count].offset = -Len;
        search_site_count++;

        // Compute offsets for search sites.
        x->ss[search_site_count].mv.col = Len;
        x->ss[search_site_count].mv.row = 0;
        x->ss[search_site_count].offset = Len;
        search_site_count++;

        // Contract.
        Len /= 2;
    }

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

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

    // Generate offsets for 8 search sites per step.
    Len = MAX_FIRST_STEP;
    x->ss[search_site_count].mv.col = 0;
    x->ss[search_site_count].mv.row = 0;
    x->ss[search_site_count].offset = 0;
    search_site_count++;

    while (Len > 0)
    {

        // Compute offsets for search sites.
        x->ss[search_site_count].mv.col = 0;
        x->ss[search_site_count].mv.row = -Len;
        x->ss[search_site_count].offset = -Len * stride;
        search_site_count++;

        // Compute offsets for search sites.
        x->ss[search_site_count].mv.col = 0;
        x->ss[search_site_count].mv.row = Len;
        x->ss[search_site_count].offset = Len * stride;
        search_site_count++;

        // Compute offsets for search sites.
        x->ss[search_site_count].mv.col = -Len;
        x->ss[search_site_count].mv.row = 0;
        x->ss[search_site_count].offset = -Len;
        search_site_count++;

        // Compute offsets for search sites.
        x->ss[search_site_count].mv.col = Len;
        x->ss[search_site_count].mv.row = 0;
        x->ss[search_site_count].offset = Len;
        search_site_count++;

        // Compute offsets for search sites.
        x->ss[search_site_count].mv.col = -Len;
        x->ss[search_site_count].mv.row = -Len;
        x->ss[search_site_count].offset = -Len * stride - Len;
        search_site_count++;

        // Compute offsets for search sites.
        x->ss[search_site_count].mv.col = Len;
        x->ss[search_site_count].mv.row = -Len;
        x->ss[search_site_count].offset = -Len * stride + Len;
        search_site_count++;

        // Compute offsets for search sites.
        x->ss[search_site_count].mv.col = -Len;
        x->ss[search_site_count].mv.row = Len;
        x->ss[search_site_count].offset = Len * stride - Len;
        search_site_count++;

        // Compute offsets for search sites.
        x->ss[search_site_count].mv.col = Len;
        x->ss[search_site_count].mv.row = Len;
        x->ss[search_site_count].offset = Len * stride + Len;
        search_site_count++;


        // Contract.
        Len /= 2;
    }

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

170 171 172 173 174 175 176 177 178
/*
 * To avoid the penalty for crossing cache-line read, preload the reference
 * area in a small buffer, which is aligned to make sure there won't be crossing
 * cache-line read while reading from this buffer. This reduced the cpu
 * cycles spent on reading ref data in sub-pixel filter functions.
 * TODO: Currently, since sub-pixel search range here is -3 ~ 3, copy 22 rows x
 * 32 cols area that is enough for 16x16 macroblock. Later, for SPLITMV, we
 * could reduce the area.
 */
John Koleszar's avatar
John Koleszar committed
179
#define MVC(r,c) (((mvcost[0][(r)-rr] + mvcost[1][(c) - rc]) * error_per_bit + 128 )>>8 ) // estimated cost of a motion vector (r,c)
180
#define PRE(r,c) (y + (((r)>>2) * y_stride + ((c)>>2) -(offset))) // pointer to predictor base of a motionvector
John Koleszar's avatar
John Koleszar committed
181
#define SP(x) (((x)&3)<<1) // convert motion vector component to offset for svf calc
182
#define DIST(r,c) vfp->svf( PRE(r,c), y_stride, SP(c),SP(r), z,b->src_stride,&sse) // returns subpixel variance error function.
John Koleszar's avatar
John Koleszar committed
183 184
#define IFMVCV(r,c,s,e) if ( c >= minc && c <= maxc && r >= minr && r <= maxr) s else e;
#define ERR(r,c) (MVC(r,c)+DIST(r,c)) // returns distortion + motion vector cost
185
#define CHECK_BETTER(v,r,c) IFMVCV(r,c,{thismse = DIST(r,c); if((v = (MVC(r,c)+thismse)) < besterr) { besterr = v; br=r; bc=c; *distortion = thismse; *sse1 = sse; }}, v=INT_MAX;)// checks if (r,c) has better score than previous best
John Koleszar's avatar
John Koleszar committed
186

Scott LaVarnway's avatar
Scott LaVarnway committed
187 188 189 190 191 192
int vp8_find_best_sub_pixel_step_iteratively(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
                                             int_mv *bestmv, int_mv *ref_mv,
                                             int error_per_bit,
                                             const vp8_variance_fn_ptr_t *vfp,
                                             int *mvcost[2], int *distortion,
                                             unsigned int *sse1)
John Koleszar's avatar
John Koleszar committed
193 194 195
{
    unsigned char *z = (*(b->base_src) + b->src);

Scott LaVarnway's avatar
Scott LaVarnway committed
196 197
    int rr = ref_mv->as_mv.row >> 1, rc = ref_mv->as_mv.col >> 1;
    int br = bestmv->as_mv.row << 2, bc = bestmv->as_mv.col << 2;
John Koleszar's avatar
John Koleszar committed
198 199 200 201 202 203 204
    int tr = br, tc = bc;
    unsigned int besterr = INT_MAX;
    unsigned int left, right, up, down, diag;
    unsigned int sse;
    unsigned int whichdir;
    unsigned int halfiters = 4;
    unsigned int quarteriters = 4;
205
    int thismse;
John Koleszar's avatar
John Koleszar committed
206

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

212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
    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
238
    // central mv
Scott LaVarnway's avatar
Scott LaVarnway committed
239 240
    bestmv->as_mv.row <<= 3;
    bestmv->as_mv.col <<= 3;
John Koleszar's avatar
John Koleszar committed
241 242

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

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

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

    return besterr;
}
#undef MVC
#undef PRE
#undef SP
#undef DIST
330
#undef IFMVCV
John Koleszar's avatar
John Koleszar committed
331 332
#undef ERR
#undef CHECK_BETTER
Yunqing Wang's avatar
Yunqing Wang committed
333

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

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

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

    // go left then right and check error
Scott LaVarnway's avatar
Scott LaVarnway committed
376 377
    this_mv.as_mv.row = startmv.as_mv.row;
    this_mv.as_mv.col = ((startmv.as_mv.col - 8) | 4);
378
    thismse = vfp->svf_halfpix_h(y - 1, y_stride, z, b->src_stride, &sse);
379
    left = 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 (left < bestmse)
    {
        *bestmv = this_mv;
        bestmse = left;
385
        *distortion = thismse;
386
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
387 388
    }

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

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

    // go up then down and check error
Scott LaVarnway's avatar
Scott LaVarnway committed
402 403
    this_mv.as_mv.col = startmv.as_mv.col;
    this_mv.as_mv.row = ((startmv.as_mv.row - 8) | 4);
404
    thismse =  vfp->svf_halfpix_v(y - y_stride, y_stride, z, b->src_stride, &sse);
405
    up = 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 (up < bestmse)
    {
        *bestmv = this_mv;
        bestmse = up;
411
        *distortion = thismse;
412
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
413 414
    }

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

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


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

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

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

//  }


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

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

    startmv = *bestmv;



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

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

497
    left = 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 (left < bestmse)
    {
        *bestmv = this_mv;
        bestmse = left;
503
        *distortion = thismse;
504
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
505 506
    }

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

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

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

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

533
    up = 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 (up < bestmse)
    {
        *bestmv = this_mv;
        bestmse = up;
539
        *distortion = thismse;
540
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
541 542
    }

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

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


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

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

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

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

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

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

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

        break;
    case 3:
Scott LaVarnway's avatar
Scott LaVarnway committed
630 631
        this_mv.as_mv.col += 2;
        this_mv.as_mv.row += 2;
632
        thismse = vfp->svf(y, y_stride,  this_mv.as_mv.col & 7, this_mv.as_mv.row & 7, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
633 634 635
        break;
    }

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

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

    return bestmse;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    return bestmse;
}

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

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

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

Yunqing Wang's avatar
Yunqing Wang committed
843 844 845
    unsigned char *what = (*(b->base_src) + b->src);
    int what_stride = b->src_stride;
    int in_what_stride = d->pre_stride;
846
    int br, bc;
Yunqing Wang's avatar
Yunqing Wang committed
847 848 849 850 851 852 853 854
    int_mv this_mv;
    unsigned int bestsad = 0x7fffffff;
    unsigned int thissad;
    unsigned char *base_offset;
    unsigned char *this_offset;
    int k = -1;
    int all_in;
    int best_site = -1;
Yunqing Wang's avatar
Yunqing Wang committed
855 856
    int hex_range = 127;
    int dia_range = 8;
Yunqing Wang's avatar
Yunqing Wang committed
857 858 859 860 861

    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

Yunqing Wang's avatar
Yunqing Wang committed
876 877 878 879 880 881 882 883 884 885 886 887
#if CONFIG_MULTI_RES_ENCODING
    /* Lower search range based on prediction info */
    if (search_param >= 6) goto cal_neighbors;
    else if (search_param >= 5) hex_range = 4;
    else if (search_param >= 4) hex_range = 6;
    else if (search_param >= 3) hex_range = 15;
    else if (search_param >= 2) hex_range = 31;
    else if (search_param >= 1) hex_range = 63;

    dia_range = 8;
#endif

888 889
    // hex search
    //j=0
Yunqing Wang's avatar
Yunqing Wang committed
890
    CHECK_BOUNDS(2)
891

Yunqing Wang's avatar
Yunqing Wang committed
892
    if(all_in)
893
    {
Yunqing Wang's avatar
Yunqing Wang committed
894
        for (i = 0; i < 6; i++)
895
        {
Yunqing Wang's avatar
Yunqing Wang committed
896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911
            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
912 913 914
        }
    }

Yunqing Wang's avatar
Yunqing Wang committed
915
    if (best_site == -1)
916
        goto cal_neighbors;
Yunqing Wang's avatar
Yunqing Wang committed
917 918 919 920 921 922
    else
    {
        br += hex[best_site].row;
        bc += hex[best_site].col;
        k = best_site;
    }
923

Yunqing Wang's avatar
Yunqing Wang committed
924
    for (j = 1; j < hex_range; j++)
John Koleszar's avatar
John Koleszar committed
925
    {
Yunqing Wang's avatar
Yunqing Wang committed
926 927
        best_site = -1;
        CHECK_BOUNDS(2)
John Koleszar's avatar
John Koleszar committed
928

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

Yunqing Wang's avatar
Yunqing Wang committed
952
        if (best_site == -1)
John Koleszar's avatar
John Koleszar committed
953
            break;
Yunqing Wang's avatar
Yunqing Wang committed
954 955 956 957 958 959 960 961
        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
962 963
    }

Yunqing Wang's avatar
Yunqing Wang committed
964
    // check 4 1-away neighbors
965
cal_neighbors:
Yunqing Wang's avatar
Yunqing Wang committed
966
    for (j = 0; j < dia_range; j++)
John Koleszar's avatar
John Koleszar committed
967
    {
Yunqing Wang's avatar
Yunqing Wang committed
968 969
        best_site = -1;
        CHECK_BOUNDS(1)
John Koleszar's avatar
John Koleszar committed
970

Yunqing Wang's avatar
Yunqing Wang committed
971
        if(all_in)
Yunqing Wang's avatar
Yunqing Wang committed
972
        {
Yunqing Wang's avatar
Yunqing Wang committed
973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991
            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
992 993
        }

Yunqing Wang's avatar
Yunqing Wang committed
994
        if (best_site == -1)
Yunqing Wang's avatar
Yunqing Wang committed
995
            break;
Yunqing Wang's avatar
Yunqing Wang committed
996 997 998 999 1000
        else
        {
            br += neighbors[best_site].row;
            bc += neighbors[best_site].col;
        }
John Koleszar's avatar
John Koleszar committed
1001 1002
    }

Scott LaVarnway's avatar
Scott LaVarnway committed
1003 1004
    best_mv->as_mv.row = br;
    best_mv->as_mv.col = bc;
John Koleszar's avatar
John Koleszar committed
1005

1006
    return bestsad;
John Koleszar's avatar
John Koleszar committed
1007
}
Yunqing Wang's avatar
Yunqing Wang committed
1008 1009
#undef CHECK_BOUNDS
#undef CHECK_POINT
John Koleszar's avatar
John Koleszar committed
1010
#undef CHECK_BETTER
1011

1012
int vp8_diamond_search_sad_c
John Koleszar's avatar
John Koleszar committed
1013 1014