mcomp.c 61.5 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
 */


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

24
#ifdef VP8_ENTROPY_STATS
John Koleszar's avatar
John Koleszar committed
25 26 27 28
static int mv_ref_ct [31] [4] [2];
static int mv_mode_cts [4] [2];
#endif

29
int vp8_mv_bit_cost(int_mv *mv, int_mv *ref, int *mvcost[2], int Weight)
John Koleszar's avatar
John Koleszar committed
30
{
31 32 33 34 35 36 37
    /* 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.
     */
38
    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
39 40
}

41
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
42
{
43
    /* Ignore mv costing if mvcost is NULL */
44 45 46 47 48
    if (mvcost)
        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;
    return 0;
John Koleszar's avatar
John Koleszar committed
49 50
}

51
static int mvsad_err_cost(int_mv *mv, int_mv *ref, int *mvsadcost[2], int error_per_bit)
52
{
53 54
    /* Calculate sad error cost on full pixel basis. */
    /* Ignore mv costing if mvsadcost is NULL */
55 56 57 58 59
    if (mvsadcost)
        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;
    return 0;
John Koleszar's avatar
John Koleszar committed
60 61 62 63 64 65 66 67
}

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


68
    /* Generate offsets for 4 search sites per step. */
John Koleszar's avatar
John Koleszar committed
69 70 71 72 73 74 75 76 77
    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)
    {

78
        /* Compute offsets for search sites. */
John Koleszar's avatar
John Koleszar committed
79 80 81 82 83
        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++;

84
        /* Compute offsets for search sites. */
John Koleszar's avatar
John Koleszar committed
85 86 87 88 89
        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++;

90
        /* Compute offsets for search sites. */
John Koleszar's avatar
John Koleszar committed
91 92 93 94 95
        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++;

96
        /* Compute offsets for search sites. */
John Koleszar's avatar
John Koleszar committed
97 98 99 100 101
        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++;

102
        /* Contract. */
John Koleszar's avatar
John Koleszar committed
103 104 105 106 107 108 109 110 111 112 113 114
        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;

115
    /* Generate offsets for 8 search sites per step. */
John Koleszar's avatar
John Koleszar committed
116 117 118 119 120 121 122 123 124
    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)
    {

125
        /* Compute offsets for search sites. */
John Koleszar's avatar
John Koleszar committed
126 127 128 129 130
        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++;

131
        /* Compute offsets for search sites. */
John Koleszar's avatar
John Koleszar committed
132 133 134 135 136
        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++;

137
        /* Compute offsets for search sites. */
John Koleszar's avatar
John Koleszar committed
138 139 140 141 142
        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++;

143
        /* Compute offsets for search sites. */
John Koleszar's avatar
John Koleszar committed
144 145 146 147 148
        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++;

149
        /* Compute offsets for search sites. */
John Koleszar's avatar
John Koleszar committed
150 151 152 153 154
        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++;

155
        /* Compute offsets for search sites. */
John Koleszar's avatar
John Koleszar committed
156 157 158 159 160
        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++;

161
        /* Compute offsets for search sites. */
John Koleszar's avatar
John Koleszar committed
162 163 164 165 166
        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++;

167
        /* Compute offsets for search sites. */
John Koleszar's avatar
John Koleszar committed
168 169 170 171 172 173
        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++;


174
        /* Contract. */
John Koleszar's avatar
John Koleszar committed
175 176 177 178 179 180 181
        Len /= 2;
    }

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

182 183 184 185 186 187 188 189 190
/*
 * 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.
 */
191 192 193 194 195 196 197 198 199

/* estimated cost of a motion vector (r,c) */
#define MVC(r,c) (mvcost ? ((mvcost[0][(r)-rr] + mvcost[1][(c) - rc]) * error_per_bit + 128 )>>8 : 0)
/* pointer to predictor base of a motionvector */
#define PRE(r,c) (y + (((r)>>2) * y_stride + ((c)>>2) -(offset)))
/* convert motion vector component to offset for svf calc */
#define SP(x) (((x)&3)<<1)
/* returns subpixel variance error function. */
#define DIST(r,c) vfp->svf( PRE(r,c), y_stride, SP(c),SP(r), z,b->src_stride,&sse)
John Koleszar's avatar
John Koleszar committed
200
#define IFMVCV(r,c,s,e) if ( c >= minc && c <= maxc && r >= minr && r <= maxr) s else e;
201 202 203
/* returns distortion + motion vector cost */
#define ERR(r,c) (MVC(r,c)+DIST(r,c))
/* checks if (r,c) has better score than previous best */
Johann's avatar
Johann committed
204
#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=UINT_MAX;)
John Koleszar's avatar
John Koleszar committed
205

206 207 208 209 210 211
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
212 213 214
{
    unsigned char *z = (*(b->base_src) + b->src);

215
    int rr = ref_mv->as_mv.row >> 1, rc = ref_mv->as_mv.col >> 1;
Yaowu Xu's avatar
Yaowu Xu committed
216
    int br = bestmv->as_mv.row * 4, bc = bestmv->as_mv.col * 4;
John Koleszar's avatar
John Koleszar committed
217
    int tr = br, tc = bc;
Johann's avatar
Johann committed
218
    unsigned int besterr;
John Koleszar's avatar
John Koleszar committed
219 220 221 222 223
    unsigned int left, right, up, down, diag;
    unsigned int sse;
    unsigned int whichdir;
    unsigned int halfiters = 4;
    unsigned int quarteriters = 4;
224
    int thismse;
John Koleszar's avatar
John Koleszar committed
225

226 227 228 229 230 231 232 233
    int minc = VPXMAX(x->mv_col_min * 4,
                      (ref_mv->as_mv.col >> 1) - ((1 << mvlong_width) - 1));
    int maxc = VPXMIN(x->mv_col_max * 4,
                      (ref_mv->as_mv.col >> 1) + ((1 << mvlong_width) - 1));
    int minr = VPXMAX(x->mv_row_min * 4,
                      (ref_mv->as_mv.row >> 1) - ((1 << mvlong_width) - 1));
    int maxr = VPXMIN(x->mv_row_max * 4,
                      (ref_mv->as_mv.row >> 1) + ((1 << mvlong_width) - 1));
John Koleszar's avatar
John Koleszar committed
234

235 236
    int y_stride;
    int offset;
237 238 239
    int pre_stride = x->e_mbd.pre.y_stride;
    unsigned char *base_pre = x->e_mbd.pre.y_buffer;

240 241 242

#if ARCH_X86 || ARCH_X86_64
    MACROBLOCKD *xd = &x->e_mbd;
243
    unsigned char *y_0 = base_pre + d->offset + (bestmv->as_mv.row) * pre_stride + bestmv->as_mv.col;
244
    unsigned char *y;
245
    int buf_r1, buf_r2, buf_c1;
246

247
    /* Clamping to avoid out-of-range data access */
248 249 250 251 252 253
    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;
    y_stride = 32;

    /* Copy to intermediate buffer before searching. */
254
    vfp->copymem(y_0 - buf_c1 - pre_stride*buf_r1, pre_stride, xd->y_buf, y_stride, 16+buf_r1+buf_r2);
255 256
    y = xd->y_buf + y_stride*buf_r1 +buf_c1;
#else
257 258
    unsigned char *y = base_pre + d->offset + (bestmv->as_mv.row) * pre_stride + bestmv->as_mv.col;
    y_stride = pre_stride;
259 260 261 262
#endif

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

263
    /* central mv */
Yaowu Xu's avatar
Yaowu Xu committed
264 265
    bestmv->as_mv.row *= 8;
    bestmv->as_mv.col *= 8;
John Koleszar's avatar
John Koleszar committed
266

267
    /* calculate central point error */
268
    besterr = vfp->vf(y, y_stride, z, b->src_stride, sse1);
269
    *distortion = besterr;
270
    besterr += mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
271

272 273 274
    /* TODO: Each subsequent iteration checks at least one point in common
     * with the last iteration could be 2 ( if diag selected)
     */
John Koleszar's avatar
John Koleszar committed
275 276
    while (--halfiters)
    {
277
        /* 1/2 pel */
John Koleszar's avatar
John Koleszar committed
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300
        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;
        }

301
        /* no reason to check the same one again. */
John Koleszar's avatar
John Koleszar committed
302 303 304 305 306 307 308
        if (tr == br && tc == bc)
            break;

        tr = br;
        tc = bc;
    }

309 310 311 312 313
    /* TODO: Each subsequent iteration checks at least one point in common
     * with the last iteration could be 2 ( if diag selected)
     */

    /* 1/4 pel */
John Koleszar's avatar
John Koleszar committed
314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338
    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;
        }

339
        /* no reason to check the same one again. */
John Koleszar's avatar
John Koleszar committed
340 341 342 343 344 345 346
        if (tr == br && tc == bc)
            break;

        tr = br;
        tc = bc;
    }

Yaowu Xu's avatar
Yaowu Xu committed
347 348
    bestmv->as_mv.row = br * 2;
    bestmv->as_mv.col = bc * 2;
John Koleszar's avatar
John Koleszar committed
349

350 351
    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
352 353 354 355 356 357 358 359
        return INT_MAX;

    return besterr;
}
#undef MVC
#undef PRE
#undef SP
#undef DIST
360
#undef IFMVCV
John Koleszar's avatar
John Koleszar committed
361 362
#undef ERR
#undef CHECK_BETTER
363

364 365 366 367 368 369
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
370 371
{
    int bestmse = INT_MAX;
372 373
    int_mv startmv;
    int_mv this_mv;
John Koleszar's avatar
John Koleszar committed
374 375 376 377
    unsigned char *z = (*(b->base_src) + b->src);
    int left, right, up, down, diag;
    unsigned int sse;
    int whichdir ;
378
    int thismse;
379
    int y_stride;
380 381
    int pre_stride = x->e_mbd.pre.y_stride;
    unsigned char *base_pre = x->e_mbd.pre.y_buffer;
382 383 384

#if ARCH_X86 || ARCH_X86_64
    MACROBLOCKD *xd = &x->e_mbd;
385
    unsigned char *y_0 = base_pre + d->offset + (bestmv->as_mv.row) * pre_stride + bestmv->as_mv.col;
386 387 388 389
    unsigned char *y;

    y_stride = 32;
    /* Copy 18 rows x 32 cols area to intermediate buffer before searching. */
390
     vfp->copymem(y_0 - 1 - pre_stride, pre_stride, xd->y_buf, y_stride, 18);
391 392
     y = xd->y_buf + y_stride + 1;
#else
393 394
     unsigned char *y = base_pre + d->offset + (bestmv->as_mv.row) * pre_stride + bestmv->as_mv.col;
     y_stride = pre_stride;
395
#endif
John Koleszar's avatar
John Koleszar committed
396

397
    /* central mv */
Yaowu Xu's avatar
Yaowu Xu committed
398 399
    bestmv->as_mv.row *= 8;
    bestmv->as_mv.col *= 8;
John Koleszar's avatar
John Koleszar committed
400 401
    startmv = *bestmv;

402
    /* calculate central point error */
403
    bestmse = vfp->vf(y, y_stride, z, b->src_stride, sse1);
404
    *distortion = bestmse;
405
    bestmse += mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
406

407
    /* go left then right and check error */
408 409
    this_mv.as_mv.row = startmv.as_mv.row;
    this_mv.as_mv.col = ((startmv.as_mv.col - 8) | 4);
410
    thismse = vfp->svf_halfpix_h(y - 1, y_stride, z, b->src_stride, &sse);
411
    left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
412 413 414 415 416

    if (left < bestmse)
    {
        *bestmv = this_mv;
        bestmse = left;
417
        *distortion = thismse;
418
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
419 420
    }

421
    this_mv.as_mv.col += 8;
422
    thismse = vfp->svf_halfpix_h(y, y_stride, z, b->src_stride, &sse);
423
    right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
424 425 426 427 428

    if (right < bestmse)
    {
        *bestmv = this_mv;
        bestmse = right;
429
        *distortion = thismse;
430
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
431 432
    }

433
    /* go up then down and check error */
434 435
    this_mv.as_mv.col = startmv.as_mv.col;
    this_mv.as_mv.row = ((startmv.as_mv.row - 8) | 4);
436
    thismse =  vfp->svf_halfpix_v(y - y_stride, y_stride, z, b->src_stride, &sse);
437
    up = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
438 439 440 441 442

    if (up < bestmse)
    {
        *bestmv = this_mv;
        bestmse = up;
443
        *distortion = thismse;
444
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
445 446
    }

447
    this_mv.as_mv.row += 8;
448
    thismse = vfp->svf_halfpix_v(y, y_stride, z, b->src_stride, &sse);
449
    down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
450 451 452 453 454

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


460
    /* now check 1 more diagonal */
John Koleszar's avatar
John Koleszar committed
461 462 463 464 465 466
    whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
    this_mv = startmv;

    switch (whichdir)
    {
    case 0:
467 468
        this_mv.as_mv.col = (this_mv.as_mv.col - 8) | 4;
        this_mv.as_mv.row = (this_mv.as_mv.row - 8) | 4;
469
        thismse = vfp->svf_halfpix_hv(y - 1 - y_stride, y_stride, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
470 471
        break;
    case 1:
472 473
        this_mv.as_mv.col += 4;
        this_mv.as_mv.row = (this_mv.as_mv.row - 8) | 4;
474
        thismse = vfp->svf_halfpix_hv(y - y_stride, y_stride, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
475 476
        break;
    case 2:
477 478
        this_mv.as_mv.col = (this_mv.as_mv.col - 8) | 4;
        this_mv.as_mv.row += 4;
479
        thismse = vfp->svf_halfpix_hv(y - 1, y_stride, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
480 481
        break;
    case 3:
482
    default:
483 484
        this_mv.as_mv.col += 4;
        this_mv.as_mv.row += 4;
485
        thismse = vfp->svf_halfpix_hv(y, y_stride, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
486 487 488
        break;
    }

489
    diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
490 491 492 493 494

    if (diag < bestmse)
    {
        *bestmv = this_mv;
        bestmse = diag;
495
        *distortion = thismse;
496
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
497 498 499
    }


500
    /* time to check quarter pels. */
501
    if (bestmv->as_mv.row < startmv.as_mv.row)
502
        y -= y_stride;
John Koleszar's avatar
John Koleszar committed
503

504
    if (bestmv->as_mv.col < startmv.as_mv.col)
John Koleszar's avatar
John Koleszar committed
505 506 507 508 509 510
        y--;

    startmv = *bestmv;



511
    /* go left then right and check error */
512
    this_mv.as_mv.row = startmv.as_mv.row;
John Koleszar's avatar
John Koleszar committed
513

514
    if (startmv.as_mv.col & 7)
John Koleszar's avatar
John Koleszar committed
515
    {
516
        this_mv.as_mv.col = startmv.as_mv.col - 2;
517
        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
518 519 520
    }
    else
    {
521
        this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6;
522
        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
523 524
    }

525
    left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
526 527 528 529 530

    if (left < bestmse)
    {
        *bestmv = this_mv;
        bestmse = left;
531
        *distortion = thismse;
532
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
533 534
    }

535
    this_mv.as_mv.col += 4;
536
    thismse = vfp->svf(y, y_stride, this_mv.as_mv.col & 7, this_mv.as_mv.row & 7, z, b->src_stride, &sse);
537
    right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
538 539 540 541 542

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

547
    /* go up then down and check error */
548
    this_mv.as_mv.col = startmv.as_mv.col;
John Koleszar's avatar
John Koleszar committed
549

550
    if (startmv.as_mv.row & 7)
John Koleszar's avatar
John Koleszar committed
551
    {
552
        this_mv.as_mv.row = startmv.as_mv.row - 2;
553
        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
554 555 556
    }
    else
    {
557
        this_mv.as_mv.row = (startmv.as_mv.row - 8) | 6;
558
        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
559 560
    }

561
    up = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
562 563 564 565 566

    if (up < bestmse)
    {
        *bestmv = this_mv;
        bestmse = up;
567
        *distortion = thismse;
568
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
569 570
    }

571
    this_mv.as_mv.row += 4;
572
    thismse = vfp->svf(y, y_stride, this_mv.as_mv.col & 7, this_mv.as_mv.row & 7, z, b->src_stride, &sse);
573
    down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
574 575 576 577 578

    if (down < bestmse)
    {
        *bestmv = this_mv;
        bestmse = down;
579
        *distortion = thismse;
580
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
581 582 583
    }


584
    /* now check 1 more diagonal */
John Koleszar's avatar
John Koleszar committed
585 586 587 588 589 590 591 592
    whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);

    this_mv = startmv;

    switch (whichdir)
    {
    case 0:

593
        if (startmv.as_mv.row & 7)
John Koleszar's avatar
John Koleszar committed
594
        {
595
            this_mv.as_mv.row -= 2;
John Koleszar's avatar
John Koleszar committed
596

597
            if (startmv.as_mv.col & 7)
John Koleszar's avatar
John Koleszar committed
598
            {
599
                this_mv.as_mv.col -= 2;
600
                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
601 602 603
            }
            else
            {
604
                this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6;
605
                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
606 607 608 609
            }
        }
        else
        {
610
            this_mv.as_mv.row = (startmv.as_mv.row - 8) | 6;
John Koleszar's avatar
John Koleszar committed
611

612
            if (startmv.as_mv.col & 7)
John Koleszar's avatar
John Koleszar committed
613
            {
614
                this_mv.as_mv.col -= 2;
615
                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
616 617 618
            }
            else
            {
619
                this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6;
620
                thismse = vfp->svf(y - y_stride - 1, y_stride, 6, 6, z, b->src_stride, &sse);
John Koleszar's avatar
John Koleszar committed
621 622 623 624 625
            }
        }

        break;
    case 1:
626
        this_mv.as_mv.col += 2;
John Koleszar's avatar
John Koleszar committed
627

628
        if (startmv.as_mv.row & 7)
John Koleszar's avatar
John Koleszar committed
629
        {
630
            this_mv.as_mv.row -= 2;
631
            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
632 633 634
        }
        else
        {
635
            this_mv.as_mv.row = (startmv.as_mv.row - 8) | 6;
636
            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
637 638 639 640
        }

        break;
    case 2:
641
        this_mv.as_mv.row += 2;
John Koleszar's avatar
John Koleszar committed
642

643
        if (startmv.as_mv.col & 7)
John Koleszar's avatar
John Koleszar committed
644
        {
645
            this_mv.as_mv.col -= 2;
646
            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
647 648 649
        }
        else
        {
650
            this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6;
651
            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
652 653 654 655
        }

        break;
    case 3:
656 657
        this_mv.as_mv.col += 2;
        this_mv.as_mv.row += 2;
658
        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
659 660 661
        break;
    }

662
    diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
663 664 665 666 667

    if (diag < bestmse)
    {
        *bestmv = this_mv;
        bestmse = diag;
668
        *distortion = thismse;
669
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
670 671 672 673 674
    }

    return bestmse;
}

675
int vp8_find_best_half_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
676 677 678 679 680
                                  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
681 682
{
    int bestmse = INT_MAX;
683 684
    int_mv startmv;
    int_mv this_mv;
John Koleszar's avatar
John Koleszar committed
685 686 687
    unsigned char *z = (*(b->base_src) + b->src);
    int left, right, up, down, diag;
    unsigned int sse;
688
    int whichdir ;
689
    int thismse;
690
    int y_stride;
691 692
    int pre_stride = x->e_mbd.pre.y_stride;
    unsigned char *base_pre = x->e_mbd.pre.y_buffer;
693 694 695

#if ARCH_X86 || ARCH_X86_64
    MACROBLOCKD *xd = &x->e_mbd;
696
    unsigned char *y_0 = base_pre + d->offset + (bestmv->as_mv.row) * pre_stride + bestmv->as_mv.col;
697 698 699 700
    unsigned char *y;

    y_stride = 32;
    /* Copy 18 rows x 32 cols area to intermediate buffer before searching. */
701
    vfp->copymem(y_0 - 1 - pre_stride, pre_stride, xd->y_buf, y_stride, 18);
702 703
    y = xd->y_buf + y_stride + 1;
#else
704 705
    unsigned char *y = base_pre + d->offset + (bestmv->as_mv.row) * pre_stride + bestmv->as_mv.col;
    y_stride = pre_stride;
706
#endif
John Koleszar's avatar
John Koleszar committed
707

708
    /* central mv */
Yaowu Xu's avatar
Yaowu Xu committed
709 710
    bestmv->as_mv.row *= 8;
    bestmv->as_mv.col *= 8;
John Koleszar's avatar
John Koleszar committed
711 712
    startmv = *bestmv;

713
    /* calculate central point error */
714
    bestmse = vfp->vf(y, y_stride, z, b->src_stride, sse1);
715
    *distortion = bestmse;
716
    bestmse += mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
717

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

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

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

    if (right < bestmse)
    {
        *bestmv = this_mv;
        bestmse = right;
740
        *distortion = thismse;
741
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
742 743
    }

744
    /* go up then down and check error */
745 746
    this_mv.as_mv.col = startmv.as_mv.col;
    this_mv.as_mv.row = ((startmv.as_mv.row - 8) | 4);
747
    thismse = vfp->svf_halfpix_v(y - y_stride, y_stride, z, b->src_stride, &sse);
748
    up = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
749 750 751 752 753

    if (up < bestmse)
    {
        *bestmv = this_mv;
        bestmse = up;
754
        *distortion = thismse;
755
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
756 757
    }

758
    this_mv.as_mv.row += 8;
759
    thismse = vfp->svf_halfpix_v(y, y_stride, z, b->src_stride, &sse);
760
    down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
761 762 763 764 765

    if (down < bestmse)
    {
        *bestmv = this_mv;
        bestmse = down;
766
        *distortion = thismse;
767
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
768 769
    }

770
    /* now check 1 more diagonal - */
John Koleszar's avatar
John Koleszar committed
771 772 773 774 775 776
    whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
    this_mv = startmv;

    switch (whichdir)
    {
    case 0:
777 778 779
        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
780 781
        break;
    case 1:
782 783 784
        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
785 786
        break;
    case 2:
787 788 789
        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
790 791
        break;
    case 3:
792 793 794 795
    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
796 797 798
        break;
    }

799
    diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
John Koleszar's avatar
John Koleszar committed
800 801 802 803 804

    if (diag < bestmse)
    {
        *bestmv = this_mv;
        bestmse = diag;
805
        *distortion = thismse;
806
        *sse1 = sse;
John Koleszar's avatar
John Koleszar committed
807 808 809 810 811
    }

    return bestmse;
}

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

842 843 844 845 846 847 848 849 850
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}}
};
851

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

871 872
    unsigned char *what = (*(b->base_src) + b->src);
    int what_stride = b->src_stride;
873 874 875 876
    int pre_stride = x->e_mbd.pre.y_stride;
    unsigned char *base_pre = x->e_mbd.pre.y_buffer;

    int in_what_stride = pre_stride;
877
    int br, bc;
878
    int_mv this_mv;
Johann's avatar
Johann committed
879
    unsigned int bestsad;
880 881 882 883 884 885
    unsigned int thissad;
    unsigned char *base_offset;
    unsigned char *this_offset;
    int k = -1;
    int all_in;
    int best_site = -1;
886 887
    int hex_range = 127;
    int dia_range = 8;
888 889 890 891 892

    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;

893 894
    (void)mvcost;

895
    /* adjust ref_mv to make sure it is within MV range */
896 897 898 899
    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;

900
    /* Work out the start point for the search */
901 902
    base_offset = (unsigned char *)(base_pre + d->offset);
    this_offset = base_offset + (br * (pre_stride)) + bc;
903 904
    this_mv.as_mv.row = br;
    this_mv.as_mv.col = bc;
Johann's avatar
Johann committed
905
    bestsad = vfp->sdf(what, what_stride, this_offset, in_what_stride)
906
            + mvsad_err_cost(&this_mv, &fcenter_mv, mvsadcost, sad_per_bit);
John Koleszar's avatar
John Koleszar committed
907

908 909 910 911 912 913 914 915 916 917
#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;
918 919
#else
    (void)search_param;
920 921
#endif

922
    /* hex search */
923
    CHECK_BOUNDS(2)
924

925
    if(all_in)
926
    {
927
        for (i = 0; i < 6; i++)
928
        {
929 930 931
            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;
Johann's avatar
Johann committed
932
            thissad = vfp->sdf(what, what_stride, this_offset, in_what_stride);
933 934 935 936 937 938 939 940 941 942
            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;
Johann's avatar
Johann committed
943
            thissad = vfp->sdf(what, what_stride, this_offset, in_what_stride);
944
            CHECK_BETTER
945 946 947
        }
    }

948
    if (best_site == -1)
949
        goto cal_neighbors;
950 951 952 953 954 955
    else
    {
        br += hex[best_site].row;
        bc += hex[best_site].col;
        k = best_site;
    }
956

957
    for (j = 1; j < hex_range; j++)
John Koleszar's avatar
John Koleszar committed
958
    {
959 960
        best_site = -1;
        CHECK_BOUNDS(2)
John Koleszar's avatar
John Koleszar committed
961

962
        if(all_in)
John Koleszar's avatar
John Koleszar committed
963
        {
964
            for (i = 0; i < 3; i++)
965
            {
966 967 968
                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;
Johann's avatar
Johann committed
969
                thissad = vfp->sdf(what, what_stride, this_offset, in_what_stride);
970 971 972 973 974 975 976 977 978 979
                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;
Johann's avatar
Johann committed
980
                thissad = vfp->sdf(what, what_stride, this_offset, in_what_stride);
981
                CHECK_BETTER
982
            }
John Koleszar's avatar
John Koleszar committed
983 984
        }

985
        if (best_site == -1)
John Koleszar's avatar
John Koleszar committed
986
            break;
987 988 989 990 991 992 993 994
        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
995 996
    }

997
    /* check 4 1-away neighbors */
998
cal_neighbors:
999
    for (j = 0; j < dia_range; j++)
John Koleszar's avatar
John Koleszar committed
1000
    {
1001 1002
        best_site = -1;
        CHECK_BOUNDS(1)
John Koleszar's avatar
John Koleszar committed
1003

1004
        if(all_in)
Yunqing Wang's avatar
Yunqing Wang committed
1005
        {
1006 1007 1008 1009 1010
            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;
Johann's avatar
Johann committed
1011
                thissad = vfp->sdf(what, what_stride, this_offset, in_what_stride);
1012 1013 1014 1015 1016 1017 1018 1019 1020 1021
                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;
Johann's avatar
Johann committed
1022
                thissad = vfp->sdf(what, what_stride, this_offset, in_what_stride);
1023 1024
                CHECK_BETTER
            }
Yunqing Wang's avatar
Yunqing Wang committed
1025 1026
        }

1027
        if (best_site == -1)
Yunqing Wang's avatar
Yunqing Wang committed
1028
            break;
1029 1030 1031 1032 1033
        else
        {
            br += neighbors[best_site].row;
            bc += neighbors[best_site].col;
        }
John Koleszar's avatar
John Koleszar committed
1034 1035
    }

1036 1037
    best_mv->as_mv.row = br;
    best_mv->as_mv.col = bc;
John Koleszar's avatar
John Koleszar committed
1038

1039
    return bestsad;
John Koleszar's avatar
John Koleszar committed
1040
}
1041 1042
#undef CHECK_BOUNDS
#undef CHECK_POINT
John Koleszar's avatar
John Koleszar committed
1043
#undef CHECK_BETTER
1044

1045
int vp8_diamond_search_sad_c
John Koleszar's avatar
John Koleszar committed
1046 1047 1048 1049
(
    MACROBLOCK *x,
    BLOCK *b,
    BLOCKD *d,
1050 1051
    int_mv *ref_mv,
    int_mv *best_mv,
John Koleszar's avatar
John Koleszar committed
1052
    int search_param,
1053
    int sad_per_bit,
John Koleszar's avatar
John Koleszar committed
1054 1055
    int *num00,
    vp8_variance_fn_ptr_t *fn_ptr,
1056
    int *mvcost[2],
1057
    int_mv *center_mv
John Koleszar's avatar
John Koleszar committed
1058 1059 1060 1061 1062 1063 1064
)
{
    int i, j, step;

    unsigned char *what = (*(b->base_src) + b->src);
    int what_stride = b->src_stride;
    unsigned char *in_what;
1065 1066 1067
    int pre_stride = x->e_mbd.pre.y_stride;
    unsigned char *base_pre = x->e_mbd.pre.y_buffer;
    int in_what_stride = pre_stride;
John Koleszar's avatar
John Koleszar committed
1068 1069 1070
    unsigned char *best_address;

    int tot_steps;
1071
    int_mv this_mv;
John Koleszar's avatar
John Koleszar committed
1072

Johann's avatar
Johann committed
1073 1074
    unsigned int bestsad;
    unsigned int thissad;
John Koleszar's avatar
John Koleszar committed
1075 1076 1077
    int best_site = 0;
    int last_site = 0;

1078 1079
    int ref_row;
    int ref_col;
John Koleszar's avatar
John Koleszar committed
1080 1081 1082 1083 1084 1085
    int this_row_offset;
    int this_col_offset;
    search_site *ss;

    unsigned char *check_here;

1086
    int *mvsadcost[2];
1087
    int_mv fcenter_mv;
1088 1089 1090

    mvsadcost[0] = x->mvsadcost[0];
    mvsadcost[1] = x->mvsadcost[1];
1091 1092
    fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3;
    fcenter_mv.as_mv.col = center_mv->as_mv.col >> 3;
1093

1094 1095 1096
    vp8_clamp_mv(ref_mv, x->mv_col_min, x->mv_col_max, x->mv_row_min, x->mv_row_max);
    ref_row = ref_mv->as_mv.row;
    ref_col = ref_mv->as_mv.col;
1097
    *num00 = 0;
1098 1099
    best_mv->as_mv.row = ref_row;
    best_mv->as_mv.col = ref_col;
1100

1101
    /* Work out the start point for the search */
1102
    in_what = (unsigned char *)(base_pre + d->offset + (ref_row * pre_stride) + ref_col);
John Koleszar's avatar
John Koleszar committed
1103 1104
    best_address = in_what;

1105
    /* Check the starting position */
Johann's avatar
Johann committed
1106
    bestsad = fn_ptr->sdf(what, what_stride, in_what, in_what_stride)
Johann's avatar
Johann committed
1107
            + mvsad_err_cost(best_mv, &fcenter_mv, mvsadcost, sad_per_bit);
John Koleszar's avatar
John Koleszar committed
1108

1109 1110 1111 1112
    /* search_param determines the length of the initial step and hence
     * the number of iterations 0 = initial step (MAX_FIRST_STEP) pel :
     * 1 = (MAX_FIRST_STEP/2) pel, 2 = (MAX_FIRST_STEP/4) pel... etc.
     */
John Koleszar's avatar
John Koleszar committed
1113 1114 1115 1116 1117 1118 1119 1120 1121
    ss = &x->ss[search_param * x->searches_per_step];
    tot_steps = (x->ss_count / x->searches_per_step) - search_param;

    i = 1;

    for (step = 0; step < tot_steps ; step++)
    {
        for (j = 0 ; j < x->searches_per_step ; j++)
        {
1122
            /* Trap illegal vectors */
1123 1124
            this_row_offset = best_mv->as_mv.row + ss[i].mv.row;
            this_col_offset = best_mv->as_mv.col + ss[i].mv.col;
John Koleszar's avatar
John Koleszar committed
1125 1126 1127 1128 1129 1130

            if ((this_col_offset > x->mv_col_min) && (this_col_offset < x->mv_col_max) &&
            (this_row_offset > x->mv_row_min) && (this_row_offset < x->mv_row_max))

            {
                check_here = ss[i].offset + best_address;
Johann's avatar
Johann committed
1131
                thissad = fn_ptr->sdf(what, what_stride, check_here, in_what_stride);
John Koleszar's avatar
John Koleszar committed
1132 1133 1134

                if (thissad < bestsad)
                {
1135 1136
                    this_mv.as_mv.row = this_row_offset;
                    this_mv.as_mv.col = this_col_offset;
1137
                    thissad += mvsad_err_cost(&this_mv, &fcenter_mv,
Johann's avatar
Johann committed
1138
                                              mvsadcost, sad_per_bit);
John Koleszar's avatar
John Koleszar committed
1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152

                    if (thissad < bestsad)
                    {
                        bestsad = thissad;
                        best_site = i;
                    }
                }
            }

            i++;
        }

        if (best_site != last_site)
        {
1153 1154
            best_mv->as_mv.row += ss[best_site].mv.row;
            best_mv->as_mv.col += ss[best_site].mv.col;
John Koleszar's avatar
John Koleszar committed
1155 1156 1157 1158 1159 1160 1161
            best_address += ss[best_site].offset;
            last_site = best_site;
        }
        else if (best_address == in_what)
            (*num00)++;
    }

1162 1163
    this_mv.as_mv.row = best_mv->as_mv.row << 3;
    this_mv.as_mv.col = best_mv->as_mv.col << 3;
John Koleszar's avatar
John Koleszar committed
1164

Johann's avatar
Johann committed
1165 1166
    return fn_ptr->vf(what, what_stride, best_address, in_what_stride, &thissad)
           + mv_err_cost(&this_mv, center_mv, mvcost, x->errorperbit);
John Koleszar's avatar
John Koleszar committed
1167 1168 1169 1170 1171 1172 1173
}

int vp8_diamond_search_sadx4
(
    MACROBLOCK *x,
    BLOCK *b,
    BLOCKD *d,
1174 1175
    int_mv *ref_mv,