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


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

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

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

Scott LaVarnway's avatar
Scott LaVarnway committed
39
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
40
{
John Koleszar's avatar
John Koleszar committed
41
    /* Ignore mv costing if mvcost is NULL */
42
43
44
45
46
    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
47
48
}

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

/* 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
198
#define IFMVCV(r,c,s,e) if ( c >= minc && c <= maxc && r >= minr && r <= maxr) s else e;
John Koleszar's avatar
John Koleszar committed
199
200
201
/* 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
202
#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
203

Scott LaVarnway's avatar
Scott LaVarnway committed
204
205
206
207
208
209
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
210
211
212
{
    unsigned char *z = (*(b->base_src) + b->src);

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

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

233
234
    int y_stride;
    int offset;
Scott LaVarnway's avatar
Scott LaVarnway committed
235
236
237
    int pre_stride = x->e_mbd.pre.y_stride;
    unsigned char *base_pre = x->e_mbd.pre.y_buffer;

238
239
240

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

John Koleszar's avatar
John Koleszar committed
245
    /* Clamping to avoid out-of-range data access */
246
247
248
249
250
251
    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. */
252
    vfp->copymem(y_0 - buf_c1 - pre_stride*buf_r1, pre_stride, xd->y_buf, y_stride, 16+buf_r1+buf_r2);
253
254
    y = xd->y_buf + y_stride*buf_r1 +buf_c1;
#else
Scott LaVarnway's avatar
Scott LaVarnway committed
255
256
    unsigned char *y = base_pre + d->offset + (bestmv->as_mv.row) * pre_stride + bestmv->as_mv.col;
    y_stride = pre_stride;
257
258
259
260
#endif

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

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

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

John Koleszar's avatar
John Koleszar committed
270
271
272
    /* 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
273
274
    while (--halfiters)
    {
John Koleszar's avatar
John Koleszar committed
275
        /* 1/2 pel */
John Koleszar's avatar
John Koleszar committed
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
        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;
        }

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

        tr = br;
        tc = bc;
    }

John Koleszar's avatar
John Koleszar committed
307
308
309
310
311
    /* 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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
    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;
        }

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

        tr = br;
        tc = bc;
    }

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

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

    return besterr;
}
#undef MVC
#undef PRE
#undef SP
#undef DIST
358
#undef IFMVCV
John Koleszar's avatar
John Koleszar committed
359
360
#undef ERR
#undef CHECK_BETTER
Yunqing Wang's avatar
Yunqing Wang committed
361

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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


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

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

    startmv = *bestmv;



John Koleszar's avatar
John Koleszar committed
509
    /* go left then right and check error */
Scott LaVarnway's avatar
Scott LaVarnway committed
510
    this_mv.as_mv.row = startmv.as_mv.row;
John Koleszar's avatar
John Koleszar committed
511

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

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

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

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

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

John Koleszar's avatar
John Koleszar committed
545
    /* go up then down and check error */
Scott LaVarnway's avatar
Scott LaVarnway committed
546
    this_mv.as_mv.col = startmv.as_mv.col;
John Koleszar's avatar
John Koleszar committed
547

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

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

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

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

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


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

    this_mv = startmv;

    switch (whichdir)
    {
    case 0:

Scott LaVarnway's avatar
Scott LaVarnway committed
591
        if (startmv.as_mv.row & 7)
John Koleszar's avatar
John Koleszar committed
592
        {
Scott LaVarnway's avatar
Scott LaVarnway committed
593
            this_mv.as_mv.row -= 2;
John Koleszar's avatar
John Koleszar committed
594

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

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

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

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

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

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

        break;
    case 3:
Scott LaVarnway's avatar
Scott LaVarnway committed
654
655
        this_mv.as_mv.col += 2;
        this_mv.as_mv.row += 2;
656
        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
657
658
659
        break;
    }

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

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

    return bestmse;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    return bestmse;
}

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

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

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

Yunqing Wang's avatar
Yunqing Wang committed
869
870
    unsigned char *what = (*(b->base_src) + b->src);
    int what_stride = b->src_stride;
Scott LaVarnway's avatar
Scott LaVarnway committed
871
872
873
874
    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;
875
    int br, bc;
Yunqing Wang's avatar
Yunqing Wang committed
876
    int_mv this_mv;
Johann's avatar
Johann committed
877
    unsigned int bestsad;
Yunqing Wang's avatar
Yunqing Wang committed
878
879
880
881
882
883
    unsigned int thissad;
    unsigned char *base_offset;
    unsigned char *this_offset;
    int k = -1;
    int all_in;
    int best_site = -1;
Yunqing Wang's avatar
Yunqing Wang committed
884
885
    int hex_range = 127;
    int dia_range = 8;
Yunqing Wang's avatar
Yunqing Wang committed
886
887
888
889
890

    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;

John Koleszar's avatar
John Koleszar committed
891
    /* adjust ref_mv to make sure it is within MV range */
892
893
894
895
    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;

John Koleszar's avatar
John Koleszar committed
896
    /* Work out the start point for the search */
Scott LaVarnway's avatar
Scott LaVarnway committed
897
898
    base_offset = (unsigned char *)(base_pre + d->offset);
    this_offset = base_offset + (br * (pre_stride)) + bc;
Yunqing Wang's avatar
Yunqing Wang committed
899
900
    this_mv.as_mv.row = br;
    this_mv.as_mv.col = bc;
901
    bestsad = vfp->sdf(what, what_stride, this_offset, in_what_stride, UINT_MAX)
902
            + mvsad_err_cost(&this_mv, &fcenter_mv, mvsadcost, sad_per_bit);
John Koleszar's avatar
John Koleszar committed
903

Yunqing Wang's avatar
Yunqing Wang committed
904
905
906
907
908
909
910
911
912
913
914
915
#if CONFIG_MULTI_RES_ENCODING
    /* Lower search range based on prediction info */
    if (search_param >= 6) goto cal_neighbors;
    else if (search_param >= 5) hex_range = 4;
    else if (search_param >= 4) hex_range = 6;
    else if (search_param >= 3) hex_range = 15;
    else if (search_param >= 2) hex_range = 31;
    else if (search_param >= 1) hex_range = 63;

    dia_range = 8;
#endif

John Koleszar's avatar
John Koleszar committed
916
    /* hex search */
Yunqing Wang's avatar
Yunqing Wang committed
917
    CHECK_BOUNDS(2)
918

Yunqing Wang's avatar
Yunqing Wang committed
919
    if(all_in)
920
    {
Yunqing Wang's avatar
Yunqing Wang committed
921
        for (i = 0; i < 6; i++)
922
        {
Yunqing Wang's avatar
Yunqing Wang committed
923
924
925
            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;
926
            thissad = vfp->sdf(what, what_stride, this_offset, in_what_stride, bestsad);
Yunqing Wang's avatar
Yunqing Wang committed
927
928
929
930
931
932
933
934
935
936
            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;
937
            thissad = vfp->sdf(what, what_stride, this_offset, in_what_stride, bestsad);
Yunqing Wang's avatar
Yunqing Wang committed
938
            CHECK_BETTER
939
940
941
        }
    }

Yunqing Wang's avatar
Yunqing Wang committed
942
    if (best_site == -1)
943
        goto cal_neighbors;
Yunqing Wang's avatar
Yunqing Wang committed
944
945
946
947
948
949
    else
    {
        br += hex[best_site].row;
        bc += hex[best_site].col;
        k = best_site;
    }
950

Yunqing Wang's avatar
Yunqing Wang committed
951
    for (j = 1; j < hex_range; j++)
John Koleszar's avatar
John Koleszar committed
952
    {
Yunqing Wang's avatar
Yunqing Wang committed
953
954
        best_site = -1;
        CHECK_BOUNDS(2)
John Koleszar's avatar
John Koleszar committed
955

Yunqing Wang's avatar
Yunqing Wang committed
956
        if(all_in)
John Koleszar's avatar
John Koleszar committed
957
        {
Yunqing Wang's avatar
Yunqing Wang committed
958
            for (i = 0; i < 3; i++)
959
            {
Yunqing Wang's avatar
Yunqing Wang committed
960
961
962
                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;
963
                thissad = vfp->sdf(what, what_stride, this_offset, in_what_stride, bestsad);
Yunqing Wang's avatar
Yunqing Wang committed
964
965
966
967
968
969
970
971
972
973
                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;
974
                thissad = vfp->sdf(what, what_stride, this_offset, in_what_stride, bestsad);
Yunqing Wang's avatar
Yunqing Wang committed
975
                CHECK_BETTER
976
            }
John Koleszar's avatar
John Koleszar committed
977
978
        }

Yunqing Wang's avatar
Yunqing Wang committed
979
        if (best_site == -1)
John Koleszar's avatar
John Koleszar committed
980
            break;
Yunqing Wang's avatar
Yunqing Wang committed
981
982
983
984
985
986
987
988
        else
        {
            br += next_chkpts[k][best_site].row;
            bc += next_chkpts[k][best_site].col;
            k += 5 + best_site;
            if (k >= 12