mcomp.c 60.7 KB
Newer Older
John Koleszar's avatar
John Koleszar committed
1
/*
2
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
John Koleszar's avatar
John Koleszar committed
3
 *
4
 *  Use of this source code is governed by a BSD-style license
5 6
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
7
 *  in the file PATENTS.  All contributing project authors may
8
 *  be found in the AUTHORS file in the root of the source tree.
John Koleszar's avatar
John Koleszar committed
9 10 11 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 18 19 20 21 22 23
#include <stdio.h>
#include <limits.h>
#include <math.h>

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

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

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

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

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

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 333 334
#undef ERR
#undef CHECK_BETTER
#undef MIN
#undef MAX
Scott LaVarnway's avatar
Scott LaVarnway committed
335 336 337 338 339 340
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
341 342
{
    int bestmse = INT_MAX;
Scott LaVarnway's avatar
Scott LaVarnway committed
343 344 345
    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
346 347 348 349
    unsigned char *z = (*(b->base_src) + b->src);
    int left, right, up, down, diag;
    unsigned int sse;
    int whichdir ;
350
    int thismse;
John Koleszar's avatar
John Koleszar committed
351 352

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

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

    // go left then right and check error
Scott LaVarnway's avatar
Scott LaVarnway committed
363 364
    this_mv.as_mv.row = startmv.as_mv.row;
    this_mv.as_mv.col = ((startmv.as_mv.col - 8) | 4);
365 366
    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
367 368 369 370 371

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

Scott LaVarnway's avatar
Scott LaVarnway committed
376
    this_mv.as_mv.col += 8;
377 378
    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
379 380 381 382 383

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

    // go up then down and check error
Scott LaVarnway's avatar
Scott LaVarnway committed
389 390
    this_mv.as_mv.col = startmv.as_mv.col;
    this_mv.as_mv.row = ((startmv.as_mv.row - 8) | 4);
391 392
    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
393 394 395 396 397

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

Scott LaVarnway's avatar
Scott LaVarnway committed
402
    this_mv.as_mv.row += 8;
403 404
    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
405 406 407 408 409

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


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

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

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

//  }


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

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

    startmv = *bestmv;



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

Scott LaVarnway's avatar
Scott LaVarnway committed
473
    if (startmv.as_mv.col & 7)
John Koleszar's avatar
John Koleszar committed
474
    {
Scott LaVarnway's avatar
Scott LaVarnway committed
475 476
        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
477 478 479
    }
    else
    {
Scott LaVarnway's avatar
Scott LaVarnway committed
480 481
        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
482 483
    }

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

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

Scott LaVarnway's avatar
Scott LaVarnway committed
494 495
    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);
496
    right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
497 498 499 500 501

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

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

Scott LaVarnway's avatar
Scott LaVarnway committed
509
    if (startmv.as_mv.row & 7)
John Koleszar's avatar
John Koleszar committed
510
    {
Scott LaVarnway's avatar
Scott LaVarnway committed
511 512
        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
513 514 515
    }
    else
    {
Scott LaVarnway's avatar
Scott LaVarnway committed
516 517
        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
518 519
    }

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

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

Scott LaVarnway's avatar
Scott LaVarnway committed
530 531
    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);
532
    down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
533 534 535 536 537

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


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

Scott LaVarnway's avatar
Scott LaVarnway committed
558
            if (startmv.as_mv.col & 7)
John Koleszar's avatar
John Koleszar committed
559
            {
Scott LaVarnway's avatar
Scott LaVarnway committed
560 561
                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
562 563 564
            }
            else
            {
Scott LaVarnway's avatar
Scott LaVarnway committed
565 566
                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
567 568 569 570
            }
        }
        else
        {
Scott LaVarnway's avatar
Scott LaVarnway committed
571
            this_mv.as_mv.row = (startmv.as_mv.row - 8) | 6;
John Koleszar's avatar
John Koleszar committed
572

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

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

Scott LaVarnway's avatar
Scott LaVarnway committed
589
        if (startmv.as_mv.row & 7)
John Koleszar's avatar
John Koleszar committed
590
        {
Scott LaVarnway's avatar
Scott LaVarnway committed
591 592
            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
593 594 595
        }
        else
        {
Scott LaVarnway's avatar
Scott LaVarnway committed
596 597
            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
598 599 600 601
        }

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

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

        break;
    case 3:
Scott LaVarnway's avatar
Scott LaVarnway committed
617 618 619
        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
620 621 622
        break;
    }

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

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

    return bestmse;
}

Scott LaVarnway's avatar
Scott LaVarnway committed
636 637 638 639 640 641
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
642 643
{
    int bestmse = INT_MAX;
Scott LaVarnway's avatar
Scott LaVarnway committed
644 645 646
    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
647 648 649
    unsigned char *z = (*(b->base_src) + b->src);
    int left, right, up, down, diag;
    unsigned int sse;
650
    int thismse;
John Koleszar's avatar
John Koleszar committed
651 652

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

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

    // go left then right and check error
Scott LaVarnway's avatar
Scott LaVarnway committed
663 664
    this_mv.as_mv.row = startmv.as_mv.row;
    this_mv.as_mv.col = ((startmv.as_mv.col - 8) | 4);
665 666
    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
667 668 669 670 671

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

Scott LaVarnway's avatar
Scott LaVarnway committed
676
    this_mv.as_mv.col += 8;
677 678
    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
679 680 681 682 683

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

    // go up then down and check error
Scott LaVarnway's avatar
Scott LaVarnway committed
689 690
    this_mv.as_mv.col = startmv.as_mv.col;
    this_mv.as_mv.row = ((startmv.as_mv.row - 8) | 4);
691 692
    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
693 694 695 696 697

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

Scott LaVarnway's avatar
Scott LaVarnway committed
702
    this_mv.as_mv.row += 8;
703 704
    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
705 706 707 708 709

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

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

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

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

#else
Scott LaVarnway's avatar
Scott LaVarnway committed
753 754
    this_mv.as_mv.col = (this_mv.as_mv.col - 8) | 4;
    this_mv.as_mv.row = (this_mv.as_mv.row - 8) | 4;
755 756
    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
757 758 759 760 761

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

Scott LaVarnway's avatar
Scott LaVarnway committed
766
    this_mv.as_mv.col += 8;
767 768
    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
769 770 771 772 773

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

Scott LaVarnway's avatar
Scott LaVarnway committed
778 779
    this_mv.as_mv.col = (this_mv.as_mv.col - 8) | 4;
    this_mv.as_mv.row = startmv.as_mv.row + 4;
780 781
    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
782 783 784 785 786

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

Scott LaVarnway's avatar
Scott LaVarnway committed
791
    this_mv.as_mv.col += 8;
792 793
    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
794 795 796 797 798

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

#endif
    return bestmse;
}

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

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

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

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

    // 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;
888 889 890
    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
891

892 893
    // hex search
    //j=0
Yunqing Wang's avatar
Yunqing Wang committed
894
    CHECK_BOUNDS(2)
895

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

Yunqing Wang's avatar
Yunqing Wang committed
919
    if (best_site == -1)
920
        goto cal_neighbors;
Yunqing Wang's avatar
Yunqing Wang committed
921 922 923 924 925 926
    else
    {
        br += hex[best_site].row;
        bc += hex[best_site].col;
        k = best_site;
    }
927 928

    for (j = 1; j < 127; j++)
John Koleszar's avatar
John Koleszar committed
929
    {
Yunqing Wang's avatar
Yunqing Wang committed
930 931
        best_site = -1;
        CHECK_BOUNDS(2)
John Koleszar's avatar
John Koleszar committed
932

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

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

Yunqing Wang's avatar
Yunqing Wang committed
968
    // check 4 1-away neighbors
969
cal_neighbors:
Yunqing Wang's avatar
Yunqing Wang committed
970
    for (j = 0; j < 32; j++)
John Koleszar's avatar
John Koleszar committed
971
    {
Yunqing Wang's avatar
Yunqing Wang committed
972 973
        best_site = -1;
        CHECK_BOUNDS(1)
John Koleszar's avatar
John Koleszar committed
974

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

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

Scott LaVarnway's avatar
Scott LaVarnway committed
1007 1008
    best_mv->as_mv.row = br;
    best_mv->as_mv.col = bc;
John Koleszar's avatar
John Koleszar committed
1009

1010
    return bestsad;
John Koleszar's avatar
John Koleszar committed
1011
}
Yunqing Wang's avatar
Yunqing Wang committed
1012 1013
#undef CHECK_BOUNDS
#undef CHECK_POINT
John Koleszar's avatar
John Koleszar committed
1014
#undef CHECK_BETTER
1015

John Koleszar's avatar
John Koleszar committed
1016 1017 1018 1019 1020
int vp8_diamond_search_sad
(
    MACROBLOCK *x,
    BLOCK *b,
    BLOCKD *d,
Scott LaVarnway's avatar
Scott LaVarnway committed
1021 1022
    int_mv *ref_mv,
    int_mv *best_mv,
John Koleszar's avatar
John Koleszar committed
1023
    int search_param,
1024
    int sad_per_bit,
John Koleszar's avatar
John Koleszar committed
1025 1026
    int *num00,
    vp8_variance_fn_ptr_t *fn_ptr,
1027
    int *mvcost[2],
Scott LaVarnway's avatar
Scott LaVarnway committed
1028
    int_mv *center_mv
John Koleszar's avatar
John Koleszar committed
1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039
)
{
    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
1040
    int_mv this_mv;
John Koleszar's avatar
John Koleszar committed
1041 1042 1043 1044 1045

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

1046 1047
    int ref_row = ref_mv->as_mv.row;
    int ref_col = ref_mv->as_mv.col;
John Koleszar's avatar
John Koleszar committed
1048 1049 1050 1051 1052 1053 1054
    int this_row_offset;
    int this_col_offset;
    search_site *ss;

    unsigned char *check_here;
    int thissad;

1055
    int *mvsadcost[