Coverage Report

Created: 2026-10-28 08:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libvpx/vp8/encoder/mcomp.c
Line
Count
Source
1
/*
2
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3
 *
4
 *  Use of this source code is governed by a BSD-style license
5
 *  that can be found in the LICENSE file in the root of the source
6
 *  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.
9
 */
10
11
#include "./vp8_rtcd.h"
12
#include "./vpx_dsp_rtcd.h"
13
#include "onyx_int.h"
14
#include "mcomp.h"
15
#include "vpx_mem/vpx_mem.h"
16
#include "vpx_config.h"
17
#include <stdio.h>
18
#include <limits.h>
19
#include <math.h>
20
#include "vp8/common/findnearmv.h"
21
#include "vp8/common/common.h"
22
#include "vpx_dsp/vpx_dsp_common.h"
23
24
8.75M
int vp8_mv_bit_cost(int_mv *mv, int_mv *ref, int *mvcost[2], int Weight) {
25
  /* MV costing is based on the distribution of vectors in the previous
26
   * frame and as such will tend to over state the cost of vectors. In
27
   * addition coding a new vector can have a knock on effect on the cost
28
   * of subsequent vectors and the quality of prediction from NEAR and
29
   * NEAREST for subsequent blocks. The "Weight" parameter allows, to a
30
   * limited extent, for some account to be taken of these factors.
31
   */
32
8.75M
  const int mv_idx_row =
33
8.75M
      clamp((mv->as_mv.row - ref->as_mv.row) >> 1, 0, MVvals);
34
8.75M
  const int mv_idx_col =
35
8.75M
      clamp((mv->as_mv.col - ref->as_mv.col) >> 1, 0, MVvals);
36
8.75M
  return ((mvcost[0][mv_idx_row] + mvcost[1][mv_idx_col]) * Weight) >> 7;
37
8.75M
}
38
39
static int mv_err_cost(int_mv *mv, int_mv *ref, int *mvcost[2],
40
30.0M
                       int error_per_bit) {
41
  /* Ignore mv costing if mvcost is NULL */
42
30.0M
  if (mvcost) {
43
30.0M
    const int mv_idx_row =
44
30.0M
        clamp((mv->as_mv.row - ref->as_mv.row) >> 1, 0, MVvals);
45
30.0M
    const int mv_idx_col =
46
30.0M
        clamp((mv->as_mv.col - ref->as_mv.col) >> 1, 0, MVvals);
47
30.0M
    return ((mvcost[0][mv_idx_row] + mvcost[1][mv_idx_col]) * error_per_bit +
48
30.0M
            128) >>
49
30.0M
           8;
50
30.0M
  }
51
0
  return 0;
52
30.0M
}
53
54
static int mvsad_err_cost(int_mv *mv, int_mv *ref, int *mvsadcost[2],
55
219M
                          int error_per_bit) {
56
  /* Calculate sad error cost on full pixel basis. */
57
  /* Ignore mv costing if mvsadcost is NULL */
58
219M
  if (mvsadcost) {
59
219M
    return ((mvsadcost[0][(mv->as_mv.row - ref->as_mv.row)] +
60
219M
             mvsadcost[1][(mv->as_mv.col - ref->as_mv.col)]) *
61
219M
                error_per_bit +
62
219M
            128) >>
63
219M
           8;
64
219M
  }
65
0
  return 0;
66
219M
}
67
68
0
void vp8_init_dsmotion_compensation(MACROBLOCK *x, int stride) {
69
0
  int Len;
70
0
  int search_site_count = 0;
71
72
  /* Generate offsets for 4 search sites per step. */
73
0
  Len = MAX_FIRST_STEP;
74
0
  x->ss[search_site_count].mv.col = 0;
75
0
  x->ss[search_site_count].mv.row = 0;
76
0
  x->ss[search_site_count].offset = 0;
77
0
  search_site_count++;
78
79
0
  while (Len > 0) {
80
    /* Compute offsets for search sites. */
81
0
    x->ss[search_site_count].mv.col = 0;
82
0
    x->ss[search_site_count].mv.row = -Len;
83
0
    x->ss[search_site_count].offset = -Len * stride;
84
0
    search_site_count++;
85
86
    /* Compute offsets for search sites. */
87
0
    x->ss[search_site_count].mv.col = 0;
88
0
    x->ss[search_site_count].mv.row = Len;
89
0
    x->ss[search_site_count].offset = Len * stride;
90
0
    search_site_count++;
91
92
    /* Compute offsets for search sites. */
93
0
    x->ss[search_site_count].mv.col = -Len;
94
0
    x->ss[search_site_count].mv.row = 0;
95
0
    x->ss[search_site_count].offset = -Len;
96
0
    search_site_count++;
97
98
    /* Compute offsets for search sites. */
99
0
    x->ss[search_site_count].mv.col = Len;
100
0
    x->ss[search_site_count].mv.row = 0;
101
0
    x->ss[search_site_count].offset = Len;
102
0
    search_site_count++;
103
104
    /* Contract. */
105
0
    Len /= 2;
106
0
  }
107
108
0
  x->ss_count = search_site_count;
109
0
  x->searches_per_step = 4;
110
0
}
111
112
148k
void vp8_init3smotion_compensation(MACROBLOCK *x, int stride) {
113
148k
  int Len;
114
148k
  int search_site_count = 0;
115
116
  /* Generate offsets for 8 search sites per step. */
117
148k
  Len = MAX_FIRST_STEP;
118
148k
  x->ss[search_site_count].mv.col = 0;
119
148k
  x->ss[search_site_count].mv.row = 0;
120
148k
  x->ss[search_site_count].offset = 0;
121
148k
  search_site_count++;
122
123
1.33M
  while (Len > 0) {
124
    /* Compute offsets for search sites. */
125
1.18M
    x->ss[search_site_count].mv.col = 0;
126
1.18M
    x->ss[search_site_count].mv.row = -Len;
127
1.18M
    x->ss[search_site_count].offset = -Len * stride;
128
1.18M
    search_site_count++;
129
130
    /* Compute offsets for search sites. */
131
1.18M
    x->ss[search_site_count].mv.col = 0;
132
1.18M
    x->ss[search_site_count].mv.row = Len;
133
1.18M
    x->ss[search_site_count].offset = Len * stride;
134
1.18M
    search_site_count++;
135
136
    /* Compute offsets for search sites. */
137
1.18M
    x->ss[search_site_count].mv.col = -Len;
138
1.18M
    x->ss[search_site_count].mv.row = 0;
139
1.18M
    x->ss[search_site_count].offset = -Len;
140
1.18M
    search_site_count++;
141
142
    /* Compute offsets for search sites. */
143
1.18M
    x->ss[search_site_count].mv.col = Len;
144
1.18M
    x->ss[search_site_count].mv.row = 0;
145
1.18M
    x->ss[search_site_count].offset = Len;
146
1.18M
    search_site_count++;
147
148
    /* Compute offsets for search sites. */
149
1.18M
    x->ss[search_site_count].mv.col = -Len;
150
1.18M
    x->ss[search_site_count].mv.row = -Len;
151
1.18M
    x->ss[search_site_count].offset = -Len * stride - Len;
152
1.18M
    search_site_count++;
153
154
    /* Compute offsets for search sites. */
155
1.18M
    x->ss[search_site_count].mv.col = Len;
156
1.18M
    x->ss[search_site_count].mv.row = -Len;
157
1.18M
    x->ss[search_site_count].offset = -Len * stride + Len;
158
1.18M
    search_site_count++;
159
160
    /* Compute offsets for search sites. */
161
1.18M
    x->ss[search_site_count].mv.col = -Len;
162
1.18M
    x->ss[search_site_count].mv.row = Len;
163
1.18M
    x->ss[search_site_count].offset = Len * stride - Len;
164
1.18M
    search_site_count++;
165
166
    /* Compute offsets for search sites. */
167
1.18M
    x->ss[search_site_count].mv.col = Len;
168
1.18M
    x->ss[search_site_count].mv.row = Len;
169
1.18M
    x->ss[search_site_count].offset = Len * stride + Len;
170
1.18M
    search_site_count++;
171
172
    /* Contract. */
173
1.18M
    Len /= 2;
174
1.18M
  }
175
176
148k
  x->ss_count = search_site_count;
177
148k
  x->searches_per_step = 8;
178
148k
}
179
180
/*
181
 * To avoid the penalty for crossing cache-line read, preload the reference
182
 * area in a small buffer, which is aligned to make sure there won't be crossing
183
 * cache-line read while reading from this buffer. This reduced the cpu
184
 * cycles spent on reading ref data in sub-pixel filter functions.
185
 * TODO: Currently, since sub-pixel search range here is -3 ~ 3, copy 22 rows x
186
 * 32 cols area that is enough for 16x16 macroblock. Later, for SPLITMV, we
187
 * could reduce the area.
188
 */
189
190
/* estimated cost of a motion vector (r,c) */
191
#define MVC(r, c)                                                          \
192
  (mvcost ? ((mvcost[0][(r) - rr] + mvcost[1][(c) - rc]) * error_per_bit + \
193
             128) >>                                                       \
194
                8                                                          \
195
          : 0)
196
/* pointer to predictor base of a motionvector */
197
#define PRE(r, c) (y + (((r) >> 2) * y_stride + ((c) >> 2) - (offset)))
198
/* convert motion vector component to offset for svf calc */
199
#define SP(x) (((x) & 3) << 1)
200
/* returns subpixel variance error function. */
201
#define DIST(r, c) \
202
  vfp->svf(PRE(r, c), y_stride, SP(c), SP(r), z, b->src_stride, &sse)
203
#define IFMVCV(r, c, s, e) \
204
382M
  if (c >= minc && c <= maxc && r >= minr && r <= maxr) s else e;
205
/* returns distortion + motion vector cost */
206
#define ERR(r, c) (MVC(r, c) + DIST(r, c))
207
/* checks if (r,c) has better score than previous best */
208
#define CHECK_BETTER(v, r, c)                          \
209
93.4M
  do {                                                 \
210
93.4M
    IFMVCV(                                            \
211
93.4M
        r, c,                                          \
212
93.4M
        {                                              \
213
93.4M
          thismse = DIST(r, c);                        \
214
93.4M
          if ((v = (MVC(r, c) + thismse)) < besterr) { \
215
93.4M
            besterr = v;                               \
216
93.4M
            br = r;                                    \
217
93.4M
            bc = c;                                    \
218
93.4M
            *distortion = thismse;                     \
219
93.4M
            *sse1 = sse;                               \
220
93.4M
          }                                            \
221
93.4M
        },                                             \
222
93.4M
        v = UINT_MAX;)                                 \
223
93.4M
  } while (0)
224
225
int vp8_find_best_sub_pixel_step_iteratively(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
226
                                             int_mv *bestmv, int_mv *ref_mv,
227
                                             int error_per_bit,
228
                                             const vp8_variance_fn_ptr_t *vfp,
229
                                             int *mvcost[2], int *distortion,
230
6.36M
                                             unsigned int *sse1) {
231
6.36M
  unsigned char *z = (*(b->base_src) + b->src);
232
233
6.36M
  int rr = ref_mv->as_mv.row >> 1, rc = ref_mv->as_mv.col >> 1;
234
6.36M
  int br = bestmv->as_mv.row * 4, bc = bestmv->as_mv.col * 4;
235
6.36M
  int tr = br, tc = bc;
236
6.36M
  unsigned int besterr;
237
6.36M
  unsigned int left, right, up, down, diag;
238
6.36M
  unsigned int sse;
239
6.36M
  unsigned int whichdir;
240
6.36M
  unsigned int halfiters = 4;
241
6.36M
  unsigned int quarteriters = 4;
242
6.36M
  int thismse;
243
244
6.36M
  int minc = VPXMAX(x->mv_col_min * 4,
245
6.36M
                    (ref_mv->as_mv.col >> 1) - ((1 << mvlong_width) - 1));
246
6.36M
  int maxc = VPXMIN(x->mv_col_max * 4,
247
6.36M
                    (ref_mv->as_mv.col >> 1) + ((1 << mvlong_width) - 1));
248
6.36M
  int minr = VPXMAX(x->mv_row_min * 4,
249
6.36M
                    (ref_mv->as_mv.row >> 1) - ((1 << mvlong_width) - 1));
250
6.36M
  int maxr = VPXMIN(x->mv_row_max * 4,
251
6.36M
                    (ref_mv->as_mv.row >> 1) + ((1 << mvlong_width) - 1));
252
253
6.36M
  int y_stride;
254
6.36M
  int offset;
255
6.36M
  int pre_stride = x->e_mbd.pre.y_stride;
256
6.36M
  unsigned char *base_pre = x->e_mbd.pre.y_buffer;
257
258
6.36M
#if VPX_ARCH_X86 || VPX_ARCH_X86_64
259
6.36M
  MACROBLOCKD *xd = &x->e_mbd;
260
6.36M
  unsigned char *y_0 = base_pre + d->offset + (bestmv->as_mv.row) * pre_stride +
261
6.36M
                       bestmv->as_mv.col;
262
6.36M
  unsigned char *y;
263
6.36M
  int buf_r1, buf_r2, buf_c1;
264
265
  /* Clamping to avoid out-of-range data access */
266
6.36M
  buf_r1 = ((bestmv->as_mv.row - 3) < x->mv_row_min)
267
6.36M
               ? (bestmv->as_mv.row - x->mv_row_min)
268
6.36M
               : 3;
269
6.36M
  buf_r2 = ((bestmv->as_mv.row + 3) > x->mv_row_max)
270
6.36M
               ? (x->mv_row_max - bestmv->as_mv.row)
271
6.36M
               : 3;
272
6.36M
  buf_c1 = ((bestmv->as_mv.col - 3) < x->mv_col_min)
273
6.36M
               ? (bestmv->as_mv.col - x->mv_col_min)
274
6.36M
               : 3;
275
6.36M
  y_stride = 32;
276
277
  /* Copy to intermediate buffer before searching. */
278
6.36M
  vfp->copymem(y_0 - buf_c1 - pre_stride * buf_r1, pre_stride, xd->y_buf,
279
6.36M
               y_stride, 16 + buf_r1 + buf_r2);
280
6.36M
  y = xd->y_buf + y_stride * buf_r1 + buf_c1;
281
#else
282
  unsigned char *y = base_pre + d->offset + (bestmv->as_mv.row) * pre_stride +
283
                     bestmv->as_mv.col;
284
  y_stride = pre_stride;
285
#endif
286
287
6.36M
  offset = (bestmv->as_mv.row) * y_stride + bestmv->as_mv.col;
288
289
  /* central mv */
290
6.36M
  bestmv->as_mv.row = clamp(bestmv->as_mv.row * 8, SHRT_MIN, SHRT_MAX);
291
6.36M
  bestmv->as_mv.col = clamp(bestmv->as_mv.col * 8, SHRT_MIN, SHRT_MAX);
292
293
  /* calculate central point error */
294
6.36M
  besterr = vfp->vf(y, y_stride, z, b->src_stride, sse1);
295
6.36M
  *distortion = besterr;
296
6.36M
  besterr += mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit);
297
298
  /* TODO: Each subsequent iteration checks at least one point in common
299
   * with the last iteration could be 2 ( if diag selected)
300
   */
301
9.90M
  while (--halfiters) {
302
    /* 1/2 pel */
303
9.74M
    CHECK_BETTER(left, tr, tc - 2);
304
9.74M
    CHECK_BETTER(right, tr, tc + 2);
305
9.74M
    CHECK_BETTER(up, tr - 2, tc);
306
9.74M
    CHECK_BETTER(down, tr + 2, tc);
307
308
9.74M
    whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
309
310
9.74M
    switch (whichdir) {
311
2.07M
      case 0: CHECK_BETTER(diag, tr - 2, tc - 2); break;
312
2.21M
      case 1: CHECK_BETTER(diag, tr - 2, tc + 2); break;
313
2.55M
      case 2: CHECK_BETTER(diag, tr + 2, tc - 2); break;
314
2.90M
      case 3: CHECK_BETTER(diag, tr + 2, tc + 2); break;
315
9.74M
    }
316
317
    /* no reason to check the same one again. */
318
9.74M
    if (tr == br && tc == bc) break;
319
320
3.53M
    tr = br;
321
3.53M
    tc = bc;
322
3.53M
  }
323
324
  /* TODO: Each subsequent iteration checks at least one point in common
325
   * with the last iteration could be 2 ( if diag selected)
326
   */
327
328
  /* 1/4 pel */
329
8.99M
  while (--quarteriters) {
330
8.95M
    CHECK_BETTER(left, tr, tc - 1);
331
8.95M
    CHECK_BETTER(right, tr, tc + 1);
332
8.95M
    CHECK_BETTER(up, tr - 1, tc);
333
8.95M
    CHECK_BETTER(down, tr + 1, tc);
334
335
8.95M
    whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
336
337
8.95M
    switch (whichdir) {
338
1.91M
      case 0: CHECK_BETTER(diag, tr - 1, tc - 1); break;
339
2.05M
      case 1: CHECK_BETTER(diag, tr - 1, tc + 1); break;
340
2.25M
      case 2: CHECK_BETTER(diag, tr + 1, tc - 1); break;
341
2.73M
      case 3: CHECK_BETTER(diag, tr + 1, tc + 1); break;
342
8.95M
    }
343
344
    /* no reason to check the same one again. */
345
8.95M
    if (tr == br && tc == bc) break;
346
347
2.62M
    tr = br;
348
2.62M
    tc = bc;
349
2.62M
  }
350
351
6.36M
  bestmv->as_mv.row = clamp(br * 2, SHRT_MIN, SHRT_MAX);
352
6.36M
  bestmv->as_mv.col = clamp(bc * 2, SHRT_MIN, SHRT_MAX);
353
354
6.36M
  if ((abs(bestmv->as_mv.col - ref_mv->as_mv.col) > (MAX_FULL_PEL_VAL << 3)) ||
355
6.36M
      (abs(bestmv->as_mv.row - ref_mv->as_mv.row) > (MAX_FULL_PEL_VAL << 3))) {
356
789
    return INT_MAX;
357
789
  }
358
359
6.36M
  return besterr;
360
6.36M
}
361
#undef MVC
362
#undef PRE
363
#undef SP
364
#undef DIST
365
#undef IFMVCV
366
#undef ERR
367
#undef CHECK_BETTER
368
369
int vp8_find_best_sub_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
370
                                 int_mv *bestmv, int_mv *ref_mv,
371
                                 int error_per_bit,
372
                                 const vp8_variance_fn_ptr_t *vfp,
373
                                 int *mvcost[2], int *distortion,
374
5.64k
                                 unsigned int *sse1) {
375
5.64k
  int bestmse = INT_MAX;
376
5.64k
  int_mv startmv;
377
5.64k
  int_mv this_mv;
378
5.64k
  unsigned char *z = (*(b->base_src) + b->src);
379
5.64k
  int left, right, up, down, diag;
380
5.64k
  unsigned int sse;
381
5.64k
  int whichdir;
382
5.64k
  int thismse;
383
5.64k
  int y_stride;
384
5.64k
  int pre_stride = x->e_mbd.pre.y_stride;
385
5.64k
  unsigned char *base_pre = x->e_mbd.pre.y_buffer;
386
387
5.64k
#if VPX_ARCH_X86 || VPX_ARCH_X86_64
388
5.64k
  MACROBLOCKD *xd = &x->e_mbd;
389
5.64k
  unsigned char *y_0 = base_pre + d->offset + (bestmv->as_mv.row) * pre_stride +
390
5.64k
                       bestmv->as_mv.col;
391
5.64k
  unsigned char *y;
392
393
5.64k
  y_stride = 32;
394
  /* Copy 18 rows x 32 cols area to intermediate buffer before searching. */
395
5.64k
  vfp->copymem(y_0 - 1 - pre_stride, pre_stride, xd->y_buf, y_stride, 18);
396
5.64k
  y = xd->y_buf + y_stride + 1;
397
#else
398
  unsigned char *y = base_pre + d->offset + (bestmv->as_mv.row) * pre_stride +
399
                     bestmv->as_mv.col;
400
  y_stride = pre_stride;
401
#endif
402
403
  /* central mv */
404
5.64k
  bestmv->as_mv.row = clamp(bestmv->as_mv.row * 8, SHRT_MIN, SHRT_MAX);
405
5.64k
  bestmv->as_mv.col = clamp(bestmv->as_mv.col * 8, SHRT_MIN, SHRT_MAX);
406
5.64k
  startmv = *bestmv;
407
408
  /* calculate central point error */
409
5.64k
  bestmse = vfp->vf(y, y_stride, z, b->src_stride, sse1);
410
5.64k
  *distortion = bestmse;
411
5.64k
  bestmse += mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit);
412
413
  /* go left then right and check error */
414
5.64k
  this_mv.as_mv.row = startmv.as_mv.row;
415
5.64k
  this_mv.as_mv.col = ((startmv.as_mv.col - 8) | 4);
416
  /* "halfpix" horizontal variance */
417
5.64k
  thismse = vfp->svf(y - 1, y_stride, 4, 0, z, b->src_stride, &sse);
418
5.64k
  left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
419
420
5.64k
  if (left < bestmse) {
421
5.36k
    *bestmv = this_mv;
422
5.36k
    bestmse = left;
423
5.36k
    *distortion = thismse;
424
5.36k
    *sse1 = sse;
425
5.36k
  }
426
427
5.64k
  this_mv.as_mv.col += 8;
428
  /* "halfpix" horizontal variance */
429
5.64k
  thismse = vfp->svf(y, y_stride, 4, 0, z, b->src_stride, &sse);
430
5.64k
  right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
431
432
5.64k
  if (right < bestmse) {
433
2.65k
    *bestmv = this_mv;
434
2.65k
    bestmse = right;
435
2.65k
    *distortion = thismse;
436
2.65k
    *sse1 = sse;
437
2.65k
  }
438
439
  /* go up then down and check error */
440
5.64k
  this_mv.as_mv.col = startmv.as_mv.col;
441
5.64k
  this_mv.as_mv.row = ((startmv.as_mv.row - 8) | 4);
442
  /* "halfpix" vertical variance */
443
5.64k
  thismse = vfp->svf(y - y_stride, y_stride, 0, 4, z, b->src_stride, &sse);
444
5.64k
  up = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
445
446
5.64k
  if (up < bestmse) {
447
3.48k
    *bestmv = this_mv;
448
3.48k
    bestmse = up;
449
3.48k
    *distortion = thismse;
450
3.48k
    *sse1 = sse;
451
3.48k
  }
452
453
5.64k
  this_mv.as_mv.row += 8;
454
  /* "halfpix" vertical variance */
455
5.64k
  thismse = vfp->svf(y, y_stride, 0, 4, z, b->src_stride, &sse);
456
5.64k
  down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
457
458
5.64k
  if (down < bestmse) {
459
2.02k
    *bestmv = this_mv;
460
2.02k
    bestmse = down;
461
2.02k
    *distortion = thismse;
462
2.02k
    *sse1 = sse;
463
2.02k
  }
464
465
  /* now check 1 more diagonal */
466
5.64k
  whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
467
5.64k
  this_mv = startmv;
468
469
5.64k
  switch (whichdir) {
470
1.46k
    case 0:
471
1.46k
      this_mv.as_mv.col = (this_mv.as_mv.col - 8) | 4;
472
1.46k
      this_mv.as_mv.row = (this_mv.as_mv.row - 8) | 4;
473
      /* "halfpix" horizontal/vertical variance */
474
1.46k
      thismse =
475
1.46k
          vfp->svf(y - 1 - y_stride, y_stride, 4, 4, z, b->src_stride, &sse);
476
1.46k
      break;
477
1.49k
    case 1:
478
1.49k
      this_mv.as_mv.col += 4;
479
1.49k
      this_mv.as_mv.row = (this_mv.as_mv.row - 8) | 4;
480
      /* "halfpix" horizontal/vertical variance */
481
1.49k
      thismse = vfp->svf(y - y_stride, y_stride, 4, 4, z, b->src_stride, &sse);
482
1.49k
      break;
483
1.41k
    case 2:
484
1.41k
      this_mv.as_mv.col = (this_mv.as_mv.col - 8) | 4;
485
1.41k
      this_mv.as_mv.row += 4;
486
      /* "halfpix" horizontal/vertical variance */
487
1.41k
      thismse = vfp->svf(y - 1, y_stride, 4, 4, z, b->src_stride, &sse);
488
1.41k
      break;
489
1.27k
    case 3:
490
1.27k
    default:
491
1.27k
      this_mv.as_mv.col += 4;
492
1.27k
      this_mv.as_mv.row += 4;
493
      /* "halfpix" horizontal/vertical variance */
494
1.27k
      thismse = vfp->svf(y, y_stride, 4, 4, z, b->src_stride, &sse);
495
1.27k
      break;
496
5.64k
  }
497
498
5.64k
  diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
499
500
5.64k
  if (diag < bestmse) {
501
4.63k
    *bestmv = this_mv;
502
4.63k
    bestmse = diag;
503
4.63k
    *distortion = thismse;
504
4.63k
    *sse1 = sse;
505
4.63k
  }
506
507
  /* time to check quarter pels. */
508
5.64k
  if (bestmv->as_mv.row < startmv.as_mv.row) y -= y_stride;
509
510
5.64k
  if (bestmv->as_mv.col < startmv.as_mv.col) y--;
511
512
5.64k
  startmv = *bestmv;
513
514
  /* go left then right and check error */
515
5.64k
  this_mv.as_mv.row = startmv.as_mv.row;
516
517
5.64k
  if (startmv.as_mv.col & 7) {
518
5.43k
    this_mv.as_mv.col = startmv.as_mv.col - 2;
519
5.43k
    thismse = vfp->svf(y, y_stride, this_mv.as_mv.col & 7,
520
5.43k
                       this_mv.as_mv.row & 7, z, b->src_stride, &sse);
521
5.43k
  } else {
522
215
    this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6;
523
215
    thismse = vfp->svf(y - 1, y_stride, 6, this_mv.as_mv.row & 7, z,
524
215
                       b->src_stride, &sse);
525
215
  }
526
527
5.64k
  left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
528
529
5.64k
  if (left < bestmse) {
530
427
    *bestmv = this_mv;
531
427
    bestmse = left;
532
427
    *distortion = thismse;
533
427
    *sse1 = sse;
534
427
  }
535
536
5.64k
  this_mv.as_mv.col += 4;
537
5.64k
  thismse = vfp->svf(y, y_stride, this_mv.as_mv.col & 7, this_mv.as_mv.row & 7,
538
5.64k
                     z, b->src_stride, &sse);
539
5.64k
  right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
540
541
5.64k
  if (right < bestmse) {
542
411
    *bestmv = this_mv;
543
411
    bestmse = right;
544
411
    *distortion = thismse;
545
411
    *sse1 = sse;
546
411
  }
547
548
  /* go up then down and check error */
549
5.64k
  this_mv.as_mv.col = startmv.as_mv.col;
550
551
5.64k
  if (startmv.as_mv.row & 7) {
552
4.72k
    this_mv.as_mv.row = startmv.as_mv.row - 2;
553
4.72k
    thismse = vfp->svf(y, y_stride, this_mv.as_mv.col & 7,
554
4.72k
                       this_mv.as_mv.row & 7, z, b->src_stride, &sse);
555
4.72k
  } else {
556
919
    this_mv.as_mv.row = (startmv.as_mv.row - 8) | 6;
557
919
    thismse = vfp->svf(y - y_stride, y_stride, this_mv.as_mv.col & 7, 6, z,
558
919
                       b->src_stride, &sse);
559
919
  }
560
561
5.64k
  up = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
562
563
5.64k
  if (up < bestmse) {
564
760
    *bestmv = this_mv;
565
760
    bestmse = up;
566
760
    *distortion = thismse;
567
760
    *sse1 = sse;
568
760
  }
569
570
5.64k
  this_mv.as_mv.row += 4;
571
5.64k
  thismse = vfp->svf(y, y_stride, this_mv.as_mv.col & 7, this_mv.as_mv.row & 7,
572
5.64k
                     z, b->src_stride, &sse);
573
5.64k
  down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
574
575
5.64k
  if (down < bestmse) {
576
695
    *bestmv = this_mv;
577
695
    bestmse = down;
578
695
    *distortion = thismse;
579
695
    *sse1 = sse;
580
695
  }
581
582
  /* now check 1 more diagonal */
583
5.64k
  whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
584
585
5.64k
  this_mv = startmv;
586
587
5.64k
  switch (whichdir) {
588
1.40k
    case 0:
589
590
1.40k
      if (startmv.as_mv.row & 7) {
591
1.11k
        this_mv.as_mv.row -= 2;
592
593
1.11k
        if (startmv.as_mv.col & 7) {
594
1.08k
          this_mv.as_mv.col -= 2;
595
1.08k
          thismse = vfp->svf(y, y_stride, this_mv.as_mv.col & 7,
596
1.08k
                             this_mv.as_mv.row & 7, z, b->src_stride, &sse);
597
1.08k
        } else {
598
27
          this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6;
599
27
          thismse = vfp->svf(y - 1, y_stride, 6, this_mv.as_mv.row & 7, z,
600
27
                             b->src_stride, &sse);
601
27
        }
602
1.11k
      } else {
603
293
        this_mv.as_mv.row = (startmv.as_mv.row - 8) | 6;
604
605
293
        if (startmv.as_mv.col & 7) {
606
251
          this_mv.as_mv.col -= 2;
607
251
          thismse = vfp->svf(y - y_stride, y_stride, this_mv.as_mv.col & 7, 6,
608
251
                             z, b->src_stride, &sse);
609
251
        } else {
610
42
          this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6;
611
42
          thismse = vfp->svf(y - y_stride - 1, y_stride, 6, 6, z, b->src_stride,
612
42
                             &sse);
613
42
        }
614
293
      }
615
616
1.40k
      break;
617
1.48k
    case 1:
618
1.48k
      this_mv.as_mv.col += 2;
619
620
1.48k
      if (startmv.as_mv.row & 7) {
621
1.20k
        this_mv.as_mv.row -= 2;
622
1.20k
        thismse = vfp->svf(y, y_stride, this_mv.as_mv.col & 7,
623
1.20k
                           this_mv.as_mv.row & 7, z, b->src_stride, &sse);
624
1.20k
      } else {
625
286
        this_mv.as_mv.row = (startmv.as_mv.row - 8) | 6;
626
286
        thismse = vfp->svf(y - y_stride, y_stride, this_mv.as_mv.col & 7, 6, z,
627
286
                           b->src_stride, &sse);
628
286
      }
629
630
1.48k
      break;
631
1.39k
    case 2:
632
1.39k
      this_mv.as_mv.row += 2;
633
634
1.39k
      if (startmv.as_mv.col & 7) {
635
1.35k
        this_mv.as_mv.col -= 2;
636
1.35k
        thismse = vfp->svf(y, y_stride, this_mv.as_mv.col & 7,
637
1.35k
                           this_mv.as_mv.row & 7, z, b->src_stride, &sse);
638
1.35k
      } else {
639
34
        this_mv.as_mv.col = (startmv.as_mv.col - 8) | 6;
640
34
        thismse = vfp->svf(y - 1, y_stride, 6, this_mv.as_mv.row & 7, z,
641
34
                           b->src_stride, &sse);
642
34
      }
643
644
1.39k
      break;
645
1.36k
    case 3:
646
1.36k
      this_mv.as_mv.col += 2;
647
1.36k
      this_mv.as_mv.row += 2;
648
1.36k
      thismse = vfp->svf(y, y_stride, this_mv.as_mv.col & 7,
649
1.36k
                         this_mv.as_mv.row & 7, z, b->src_stride, &sse);
650
1.36k
      break;
651
5.64k
  }
652
653
5.64k
  diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
654
655
5.64k
  if (diag < bestmse) {
656
166
    *bestmv = this_mv;
657
166
    bestmse = diag;
658
166
    *distortion = thismse;
659
166
    *sse1 = sse;
660
166
  }
661
662
5.64k
  return bestmse;
663
5.64k
}
664
665
int vp8_find_best_half_pixel_step(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
666
                                  int_mv *bestmv, int_mv *ref_mv,
667
                                  int error_per_bit,
668
                                  const vp8_variance_fn_ptr_t *vfp,
669
                                  int *mvcost[2], int *distortion,
670
0
                                  unsigned int *sse1) {
671
0
  int bestmse = INT_MAX;
672
0
  int_mv startmv;
673
0
  int_mv this_mv;
674
0
  unsigned char *z = (*(b->base_src) + b->src);
675
0
  int left, right, up, down, diag;
676
0
  unsigned int sse;
677
0
  int whichdir;
678
0
  int thismse;
679
0
  int y_stride;
680
0
  int pre_stride = x->e_mbd.pre.y_stride;
681
0
  unsigned char *base_pre = x->e_mbd.pre.y_buffer;
682
683
0
#if VPX_ARCH_X86 || VPX_ARCH_X86_64
684
0
  MACROBLOCKD *xd = &x->e_mbd;
685
0
  unsigned char *y_0 = base_pre + d->offset + (bestmv->as_mv.row) * pre_stride +
686
0
                       bestmv->as_mv.col;
687
0
  unsigned char *y;
688
689
0
  y_stride = 32;
690
  /* Copy 18 rows x 32 cols area to intermediate buffer before searching. */
691
0
  vfp->copymem(y_0 - 1 - pre_stride, pre_stride, xd->y_buf, y_stride, 18);
692
0
  y = xd->y_buf + y_stride + 1;
693
#else
694
  unsigned char *y = base_pre + d->offset + (bestmv->as_mv.row) * pre_stride +
695
                     bestmv->as_mv.col;
696
  y_stride = pre_stride;
697
#endif
698
699
  /* central mv */
700
0
  bestmv->as_mv.row = clamp(bestmv->as_mv.row * 8, SHRT_MIN, SHRT_MAX);
701
0
  bestmv->as_mv.col = clamp(bestmv->as_mv.col * 8, SHRT_MIN, SHRT_MAX);
702
0
  startmv = *bestmv;
703
704
  /* calculate central point error */
705
0
  bestmse = vfp->vf(y, y_stride, z, b->src_stride, sse1);
706
0
  *distortion = bestmse;
707
0
  bestmse += mv_err_cost(bestmv, ref_mv, mvcost, error_per_bit);
708
709
  /* go left then right and check error */
710
0
  this_mv.as_mv.row = startmv.as_mv.row;
711
0
  this_mv.as_mv.col = ((startmv.as_mv.col - 8) | 4);
712
  /* "halfpix" horizontal variance */
713
0
  thismse = vfp->svf(y - 1, y_stride, 4, 0, z, b->src_stride, &sse);
714
0
  left = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
715
716
0
  if (left < bestmse) {
717
0
    *bestmv = this_mv;
718
0
    bestmse = left;
719
0
    *distortion = thismse;
720
0
    *sse1 = sse;
721
0
  }
722
723
0
  this_mv.as_mv.col += 8;
724
  /* "halfpix" horizontal variance */
725
0
  thismse = vfp->svf(y, y_stride, 4, 0, z, b->src_stride, &sse);
726
0
  right = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
727
728
0
  if (right < bestmse) {
729
0
    *bestmv = this_mv;
730
0
    bestmse = right;
731
0
    *distortion = thismse;
732
0
    *sse1 = sse;
733
0
  }
734
735
  /* go up then down and check error */
736
0
  this_mv.as_mv.col = startmv.as_mv.col;
737
0
  this_mv.as_mv.row = ((startmv.as_mv.row - 8) | 4);
738
  /* "halfpix" vertical variance */
739
0
  thismse = vfp->svf(y - y_stride, y_stride, 0, 4, z, b->src_stride, &sse);
740
0
  up = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
741
742
0
  if (up < bestmse) {
743
0
    *bestmv = this_mv;
744
0
    bestmse = up;
745
0
    *distortion = thismse;
746
0
    *sse1 = sse;
747
0
  }
748
749
0
  this_mv.as_mv.row += 8;
750
  /* "halfpix" vertical variance */
751
0
  thismse = vfp->svf(y, y_stride, 0, 4, z, b->src_stride, &sse);
752
0
  down = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
753
754
0
  if (down < bestmse) {
755
0
    *bestmv = this_mv;
756
0
    bestmse = down;
757
0
    *distortion = thismse;
758
0
    *sse1 = sse;
759
0
  }
760
761
  /* now check 1 more diagonal - */
762
0
  whichdir = (left < right ? 0 : 1) + (up < down ? 0 : 2);
763
0
  this_mv = startmv;
764
765
0
  switch (whichdir) {
766
0
    case 0:
767
0
      this_mv.as_mv.col = (this_mv.as_mv.col - 8) | 4;
768
0
      this_mv.as_mv.row = (this_mv.as_mv.row - 8) | 4;
769
      /* "halfpix" horizontal/vertical variance */
770
0
      thismse =
771
0
          vfp->svf(y - 1 - y_stride, y_stride, 4, 4, z, b->src_stride, &sse);
772
0
      break;
773
0
    case 1:
774
0
      this_mv.as_mv.col += 4;
775
0
      this_mv.as_mv.row = (this_mv.as_mv.row - 8) | 4;
776
      /* "halfpix" horizontal/vertical variance */
777
0
      thismse = vfp->svf(y - y_stride, y_stride, 4, 4, z, b->src_stride, &sse);
778
0
      break;
779
0
    case 2:
780
0
      this_mv.as_mv.col = (this_mv.as_mv.col - 8) | 4;
781
0
      this_mv.as_mv.row += 4;
782
      /* "halfpix" horizontal/vertical variance */
783
0
      thismse = vfp->svf(y - 1, y_stride, 4, 4, z, b->src_stride, &sse);
784
0
      break;
785
0
    case 3:
786
0
    default:
787
0
      this_mv.as_mv.col += 4;
788
0
      this_mv.as_mv.row += 4;
789
      /* "halfpix" horizontal/vertical variance */
790
0
      thismse = vfp->svf(y, y_stride, 4, 4, z, b->src_stride, &sse);
791
0
      break;
792
0
  }
793
794
0
  diag = thismse + mv_err_cost(&this_mv, ref_mv, mvcost, error_per_bit);
795
796
0
  if (diag < bestmse) {
797
0
    *bestmv = this_mv;
798
0
    bestmse = diag;
799
0
    *distortion = thismse;
800
0
    *sse1 = sse;
801
0
  }
802
803
0
  return bestmse;
804
0
}
805
806
#define CHECK_BOUNDS(range)                    \
807
24.6k
  do {                                         \
808
24.6k
    all_in = 1;                                \
809
24.6k
    all_in &= ((br - range) >= x->mv_row_min); \
810
24.6k
    all_in &= ((br + range) <= x->mv_row_max); \
811
24.6k
    all_in &= ((bc - range) >= x->mv_col_min); \
812
24.6k
    all_in &= ((bc + range) <= x->mv_col_max); \
813
24.6k
  } while (0)
814
815
#define CHECK_POINT                                  \
816
146
  {                                                  \
817
146
    if (this_mv.as_mv.col < x->mv_col_min) continue; \
818
146
    if (this_mv.as_mv.col > x->mv_col_max) continue; \
819
125
    if (this_mv.as_mv.row < x->mv_row_min) continue; \
820
111
    if (this_mv.as_mv.row > x->mv_row_max) continue; \
821
85
  }
822
823
#define CHECK_BETTER                                                     \
824
101k
  do {                                                                   \
825
101k
    if (thissad < bestsad) {                                             \
826
28.5k
      thissad +=                                                         \
827
28.5k
          mvsad_err_cost(&this_mv, &fcenter_mv, mvsadcost, sad_per_bit); \
828
28.5k
      if (thissad < bestsad) {                                           \
829
19.0k
        bestsad = thissad;                                               \
830
19.0k
        best_site = i;                                                   \
831
19.0k
      }                                                                  \
832
28.5k
    }                                                                    \
833
101k
  } while (0)
834
835
static const MV next_chkpts[6][3] = {
836
  { { -2, 0 }, { -1, -2 }, { 1, -2 } }, { { -1, -2 }, { 1, -2 }, { 2, 0 } },
837
  { { 1, -2 }, { 2, 0 }, { 1, 2 } },    { { 2, 0 }, { 1, 2 }, { -1, 2 } },
838
  { { 1, 2 }, { -1, 2 }, { -2, 0 } },   { { -1, 2 }, { -2, 0 }, { -1, -2 } }
839
};
840
841
int vp8_hex_search(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv,
842
                   int_mv *best_mv, int search_param, int sad_per_bit,
843
                   const vp8_variance_fn_ptr_t *vfp, int *mvsadcost[2],
844
5.64k
                   int_mv *center_mv) {
845
5.64k
  MV hex[6] = {
846
5.64k
    { -1, -2 }, { 1, -2 }, { 2, 0 }, { 1, 2 }, { -1, 2 }, { -2, 0 }
847
5.64k
  };
848
5.64k
  MV neighbors[4] = { { 0, -1 }, { -1, 0 }, { 1, 0 }, { 0, 1 } };
849
5.64k
  int i, j;
850
851
5.64k
  unsigned char *what = (*(b->base_src) + b->src);
852
5.64k
  int what_stride = b->src_stride;
853
5.64k
  int pre_stride = x->e_mbd.pre.y_stride;
854
5.64k
  unsigned char *base_pre = x->e_mbd.pre.y_buffer;
855
856
5.64k
  int in_what_stride = pre_stride;
857
5.64k
  int br, bc;
858
5.64k
  int_mv this_mv;
859
5.64k
  unsigned int bestsad;
860
5.64k
  unsigned int thissad;
861
5.64k
  unsigned char *base_offset;
862
5.64k
  unsigned char *this_offset;
863
5.64k
  int k = -1;
864
5.64k
  int all_in;
865
5.64k
  int best_site = -1;
866
5.64k
  int hex_range = 127;
867
5.64k
  int dia_range = 8;
868
869
5.64k
  int_mv fcenter_mv;
870
5.64k
  fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3;
871
5.64k
  fcenter_mv.as_mv.col = center_mv->as_mv.col >> 3;
872
873
  /* adjust ref_mv to make sure it is within MV range */
874
5.64k
  vp8_clamp_mv(ref_mv, x->mv_col_min, x->mv_col_max, x->mv_row_min,
875
5.64k
               x->mv_row_max);
876
5.64k
  br = ref_mv->as_mv.row;
877
5.64k
  bc = ref_mv->as_mv.col;
878
879
  /* Work out the start point for the search */
880
5.64k
  base_offset = (unsigned char *)(base_pre + d->offset);
881
5.64k
  this_offset = base_offset + (br * (pre_stride)) + bc;
882
5.64k
  this_mv.as_mv.row = br;
883
5.64k
  this_mv.as_mv.col = bc;
884
5.64k
  bestsad = vfp->sdf(what, what_stride, this_offset, in_what_stride) +
885
5.64k
            mvsad_err_cost(&this_mv, &fcenter_mv, mvsadcost, sad_per_bit);
886
887
#if CONFIG_MULTI_RES_ENCODING
888
  /* Lower search range based on prediction info */
889
  if (search_param >= 6)
890
    goto cal_neighbors;
891
  else if (search_param >= 5)
892
    hex_range = 4;
893
  else if (search_param >= 4)
894
    hex_range = 6;
895
  else if (search_param >= 3)
896
    hex_range = 15;
897
  else if (search_param >= 2)
898
    hex_range = 31;
899
  else if (search_param >= 1)
900
    hex_range = 63;
901
902
  dia_range = 8;
903
#else
904
5.64k
  (void)search_param;
905
5.64k
#endif
906
907
  /* hex search */
908
5.64k
  CHECK_BOUNDS(2);
909
910
5.64k
  if (all_in) {
911
39.5k
    for (i = 0; i < 6; ++i) {
912
33.8k
      this_mv.as_mv.row = br + hex[i].row;
913
33.8k
      this_mv.as_mv.col = bc + hex[i].col;
914
33.8k
      this_offset = base_offset + (this_mv.as_mv.row * in_what_stride) +
915
33.8k
                    this_mv.as_mv.col;
916
33.8k
      thissad = vfp->sdf(what, what_stride, this_offset, in_what_stride);
917
33.8k
      CHECK_BETTER;
918
33.8k
    }
919
5.64k
  } else {
920
0
    for (i = 0; i < 6; ++i) {
921
0
      this_mv.as_mv.row = br + hex[i].row;
922
0
      this_mv.as_mv.col = bc + hex[i].col;
923
0
      CHECK_POINT
924
0
      this_offset = base_offset + (this_mv.as_mv.row * in_what_stride) +
925
0
                    this_mv.as_mv.col;
926
0
      thissad = vfp->sdf(what, what_stride, this_offset, in_what_stride);
927
0
      CHECK_BETTER;
928
0
    }
929
0
  }
930
931
5.64k
  if (best_site == -1) {
932
1.39k
    goto cal_neighbors;
933
4.24k
  } else {
934
4.24k
    br += hex[best_site].row;
935
4.24k
    bc += hex[best_site].col;
936
4.24k
    k = best_site;
937
4.24k
  }
938
939
8.12k
  for (j = 1; j < hex_range; ++j) {
940
8.12k
    best_site = -1;
941
8.12k
    CHECK_BOUNDS(2);
942
943
8.12k
    if (all_in) {
944
32.3k
      for (i = 0; i < 3; ++i) {
945
24.2k
        this_mv.as_mv.row = br + next_chkpts[k][i].row;
946
24.2k
        this_mv.as_mv.col = bc + next_chkpts[k][i].col;
947
24.2k
        this_offset = base_offset + (this_mv.as_mv.row * (in_what_stride)) +
948
24.2k
                      this_mv.as_mv.col;
949
24.2k
        thissad = vfp->sdf(what, what_stride, this_offset, in_what_stride);
950
24.2k
        CHECK_BETTER;
951
24.2k
      }
952
8.09k
    } else {
953
104
      for (i = 0; i < 3; ++i) {
954
78
        this_mv.as_mv.row = br + next_chkpts[k][i].row;
955
78
        this_mv.as_mv.col = bc + next_chkpts[k][i].col;
956
78
        CHECK_POINT
957
34
        this_offset = base_offset + (this_mv.as_mv.row * (in_what_stride)) +
958
34
                      this_mv.as_mv.col;
959
34
        thissad = vfp->sdf(what, what_stride, this_offset, in_what_stride);
960
34
        CHECK_BETTER;
961
34
      }
962
26
    }
963
964
8.12k
    if (best_site == -1) {
965
4.24k
      break;
966
4.24k
    } else {
967
3.87k
      br += next_chkpts[k][best_site].row;
968
3.87k
      bc += next_chkpts[k][best_site].col;
969
3.87k
      k += 5 + best_site;
970
3.87k
      if (k >= 12) {
971
237
        k -= 12;
972
3.63k
      } else if (k >= 6) {
973
3.43k
        k -= 6;
974
3.43k
      }
975
3.87k
    }
976
8.12k
  }
977
978
/* check 4 1-away neighbors */
979
5.64k
cal_neighbors:
980
10.9k
  for (j = 0; j < dia_range; ++j) {
981
10.8k
    best_site = -1;
982
10.8k
    CHECK_BOUNDS(1);
983
984
10.8k
    if (all_in) {
985
54.3k
      for (i = 0; i < 4; ++i) {
986
43.4k
        this_mv.as_mv.row = br + neighbors[i].row;
987
43.4k
        this_mv.as_mv.col = bc + neighbors[i].col;
988
43.4k
        this_offset = base_offset + (this_mv.as_mv.row * (in_what_stride)) +
989
43.4k
                      this_mv.as_mv.col;
990
43.4k
        thissad = vfp->sdf(what, what_stride, this_offset, in_what_stride);
991
43.4k
        CHECK_BETTER;
992
43.4k
      }
993
10.8k
    } else {
994
85
      for (i = 0; i < 4; ++i) {
995
68
        this_mv.as_mv.row = br + neighbors[i].row;
996
68
        this_mv.as_mv.col = bc + neighbors[i].col;
997
68
        CHECK_POINT
998
51
        this_offset = base_offset + (this_mv.as_mv.row * (in_what_stride)) +
999
51
                      this_mv.as_mv.col;
1000
51
        thissad = vfp->sdf(what, what_stride, this_offset, in_what_stride);
1001
51
        CHECK_BETTER;
1002
51
      }
1003
17
    }
1004
1005
10.8k
    if (best_site == -1) {
1006
5.60k
      break;
1007
5.60k
    } else {
1008
5.27k
      br += neighbors[best_site].row;
1009
5.27k
      bc += neighbors[best_site].col;
1010
5.27k
    }
1011
10.8k
  }
1012
1013
5.64k
  best_mv->as_mv.row = br;
1014
5.64k
  best_mv->as_mv.col = bc;
1015
1016
5.64k
  return bestsad;
1017
4.24k
}
1018
#undef CHECK_BOUNDS
1019
#undef CHECK_POINT
1020
#undef CHECK_BETTER
1021
1022
int vp8_diamond_search_sad_c(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv,
1023
                             int_mv *best_mv, int search_param, int sad_per_bit,
1024
                             int *num00, vp8_variance_fn_ptr_t *fn_ptr,
1025
0
                             int *mvcost[2], int_mv *center_mv) {
1026
0
  int i, j, step;
1027
1028
0
  unsigned char *what = (*(b->base_src) + b->src);
1029
0
  int what_stride = b->src_stride;
1030
0
  unsigned char *in_what;
1031
0
  int pre_stride = x->e_mbd.pre.y_stride;
1032
0
  unsigned char *base_pre = x->e_mbd.pre.y_buffer;
1033
0
  int in_what_stride = pre_stride;
1034
0
  unsigned char *best_address;
1035
1036
0
  int tot_steps;
1037
0
  int_mv this_mv;
1038
1039
0
  unsigned int bestsad;
1040
0
  unsigned int thissad;
1041
0
  int best_site = 0;
1042
0
  int last_site = 0;
1043
1044
0
  int ref_row;
1045
0
  int ref_col;
1046
0
  int this_row_offset;
1047
0
  int this_col_offset;
1048
0
  search_site *ss;
1049
1050
0
  unsigned char *check_here;
1051
1052
0
  int *mvsadcost[2];
1053
0
  int_mv fcenter_mv;
1054
1055
0
  mvsadcost[0] = x->mvsadcost[0];
1056
0
  mvsadcost[1] = x->mvsadcost[1];
1057
0
  fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3;
1058
0
  fcenter_mv.as_mv.col = center_mv->as_mv.col >> 3;
1059
1060
0
  vp8_clamp_mv(ref_mv, x->mv_col_min, x->mv_col_max, x->mv_row_min,
1061
0
               x->mv_row_max);
1062
0
  ref_row = ref_mv->as_mv.row;
1063
0
  ref_col = ref_mv->as_mv.col;
1064
0
  *num00 = 0;
1065
0
  best_mv->as_mv.row = ref_row;
1066
0
  best_mv->as_mv.col = ref_col;
1067
1068
  /* Work out the start point for the search */
1069
0
  in_what = (unsigned char *)(base_pre + d->offset + (ref_row * pre_stride) +
1070
0
                              ref_col);
1071
0
  best_address = in_what;
1072
1073
  /* Check the starting position */
1074
0
  bestsad = fn_ptr->sdf(what, what_stride, in_what, in_what_stride) +
1075
0
            mvsad_err_cost(best_mv, &fcenter_mv, mvsadcost, sad_per_bit);
1076
1077
  /* search_param determines the length of the initial step and hence
1078
   * the number of iterations 0 = initial step (MAX_FIRST_STEP) pel :
1079
   * 1 = (MAX_FIRST_STEP/2) pel, 2 = (MAX_FIRST_STEP/4) pel... etc.
1080
   */
1081
0
  ss = &x->ss[search_param * x->searches_per_step];
1082
0
  tot_steps = (x->ss_count / x->searches_per_step) - search_param;
1083
1084
0
  i = 1;
1085
1086
0
  for (step = 0; step < tot_steps; ++step) {
1087
0
    for (j = 0; j < x->searches_per_step; ++j) {
1088
      /* Trap illegal vectors */
1089
0
      this_row_offset = best_mv->as_mv.row + ss[i].mv.row;
1090
0
      this_col_offset = best_mv->as_mv.col + ss[i].mv.col;
1091
1092
0
      if ((this_col_offset > x->mv_col_min) &&
1093
0
          (this_col_offset < x->mv_col_max) &&
1094
0
          (this_row_offset > x->mv_row_min) &&
1095
0
          (this_row_offset < x->mv_row_max))
1096
1097
0
      {
1098
0
        check_here = ss[i].offset + best_address;
1099
0
        thissad = fn_ptr->sdf(what, what_stride, check_here, in_what_stride);
1100
1101
0
        if (thissad < bestsad) {
1102
0
          this_mv.as_mv.row = this_row_offset;
1103
0
          this_mv.as_mv.col = this_col_offset;
1104
0
          thissad +=
1105
0
              mvsad_err_cost(&this_mv, &fcenter_mv, mvsadcost, sad_per_bit);
1106
1107
0
          if (thissad < bestsad) {
1108
0
            bestsad = thissad;
1109
0
            best_site = i;
1110
0
          }
1111
0
        }
1112
0
      }
1113
1114
0
      i++;
1115
0
    }
1116
1117
0
    if (best_site != last_site) {
1118
0
      best_mv->as_mv.row += ss[best_site].mv.row;
1119
0
      best_mv->as_mv.col += ss[best_site].mv.col;
1120
0
      best_address += ss[best_site].offset;
1121
0
      last_site = best_site;
1122
0
    } else if (best_address == in_what) {
1123
0
      (*num00)++;
1124
0
    }
1125
0
  }
1126
1127
0
  this_mv.as_mv.row = clamp(best_mv->as_mv.row * 8, SHRT_MIN, SHRT_MAX);
1128
0
  this_mv.as_mv.col = clamp(best_mv->as_mv.col * 8, SHRT_MIN, SHRT_MAX);
1129
1130
0
  return fn_ptr->vf(what, what_stride, best_address, in_what_stride, &thissad) +
1131
0
         mv_err_cost(&this_mv, center_mv, mvcost, x->errorperbit);
1132
0
}
1133
1134
#if HAVE_SSE2 || HAVE_MSA || HAVE_LSX
1135
int vp8_diamond_search_sadx4(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv,
1136
                             int_mv *best_mv, int search_param, int sad_per_bit,
1137
                             int *num00, vp8_variance_fn_ptr_t *fn_ptr,
1138
22.9M
                             int *mvcost[2], int_mv *center_mv) {
1139
22.9M
  int i, j, step;
1140
1141
22.9M
  unsigned char *what = (*(b->base_src) + b->src);
1142
22.9M
  int what_stride = b->src_stride;
1143
22.9M
  unsigned char *in_what;
1144
22.9M
  int pre_stride = x->e_mbd.pre.y_stride;
1145
22.9M
  unsigned char *base_pre = x->e_mbd.pre.y_buffer;
1146
22.9M
  int in_what_stride = pre_stride;
1147
22.9M
  unsigned char *best_address;
1148
1149
22.9M
  int tot_steps;
1150
22.9M
  int_mv this_mv;
1151
1152
22.9M
  unsigned int bestsad;
1153
22.9M
  unsigned int thissad;
1154
22.9M
  int best_site = 0;
1155
22.9M
  int last_site = 0;
1156
1157
22.9M
  int ref_row;
1158
22.9M
  int ref_col;
1159
22.9M
  int this_row_offset;
1160
22.9M
  int this_col_offset;
1161
22.9M
  search_site *ss;
1162
1163
22.9M
  unsigned char *check_here;
1164
1165
22.9M
  int *mvsadcost[2];
1166
22.9M
  int_mv fcenter_mv;
1167
1168
22.9M
  mvsadcost[0] = x->mvsadcost[0];
1169
22.9M
  mvsadcost[1] = x->mvsadcost[1];
1170
22.9M
  fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3;
1171
22.9M
  fcenter_mv.as_mv.col = center_mv->as_mv.col >> 3;
1172
1173
22.9M
  vp8_clamp_mv(ref_mv, x->mv_col_min, x->mv_col_max, x->mv_row_min,
1174
22.9M
               x->mv_row_max);
1175
22.9M
  ref_row = ref_mv->as_mv.row;
1176
22.9M
  ref_col = ref_mv->as_mv.col;
1177
22.9M
  *num00 = 0;
1178
22.9M
  best_mv->as_mv.row = ref_row;
1179
22.9M
  best_mv->as_mv.col = ref_col;
1180
1181
  /* Work out the start point for the search */
1182
22.9M
  in_what = (unsigned char *)(base_pre + d->offset + (ref_row * pre_stride) +
1183
22.9M
                              ref_col);
1184
22.9M
  best_address = in_what;
1185
1186
  /* Check the starting position */
1187
22.9M
  bestsad = fn_ptr->sdf(what, what_stride, in_what, in_what_stride) +
1188
22.9M
            mvsad_err_cost(best_mv, &fcenter_mv, mvsadcost, sad_per_bit);
1189
1190
  /* search_param determines the length of the initial step and hence the
1191
   * number of iterations 0 = initial step (MAX_FIRST_STEP) pel : 1 =
1192
   * (MAX_FIRST_STEP/2) pel, 2 = (MAX_FIRST_STEP/4) pel... etc.
1193
   */
1194
22.9M
  ss = &x->ss[search_param * x->searches_per_step];
1195
22.9M
  tot_steps = (x->ss_count / x->searches_per_step) - search_param;
1196
1197
22.9M
  i = 1;
1198
1199
109M
  for (step = 0; step < tot_steps; ++step) {
1200
86.6M
    int all_in = 1, t;
1201
1202
    /* To know if all neighbor points are within the bounds, 4 bounds
1203
     * checking are enough instead of checking 4 bounds for each
1204
     * points.
1205
     */
1206
86.6M
    all_in &= ((best_mv->as_mv.row + ss[i].mv.row) > x->mv_row_min);
1207
86.6M
    all_in &= ((best_mv->as_mv.row + ss[i + 1].mv.row) < x->mv_row_max);
1208
86.6M
    all_in &= ((best_mv->as_mv.col + ss[i + 2].mv.col) > x->mv_col_min);
1209
86.6M
    all_in &= ((best_mv->as_mv.col + ss[i + 3].mv.col) < x->mv_col_max);
1210
1211
86.6M
    if (all_in) {
1212
66.4M
      unsigned int sad_array[4];
1213
1214
199M
      for (j = 0; j < x->searches_per_step; j += 4) {
1215
132M
        const unsigned char *block_offset[4];
1216
1217
664M
        for (t = 0; t < 4; ++t) {
1218
531M
          block_offset[t] = ss[i + t].offset + best_address;
1219
531M
        }
1220
1221
132M
        fn_ptr->sdx4df(what, what_stride, block_offset, in_what_stride,
1222
132M
                       sad_array);
1223
1224
664M
        for (t = 0; t < 4; t++, i++) {
1225
531M
          if (sad_array[t] < bestsad) {
1226
171M
            this_mv.as_mv.row = best_mv->as_mv.row + ss[i].mv.row;
1227
171M
            this_mv.as_mv.col = best_mv->as_mv.col + ss[i].mv.col;
1228
171M
            sad_array[t] +=
1229
171M
                mvsad_err_cost(&this_mv, &fcenter_mv, mvsadcost, sad_per_bit);
1230
1231
171M
            if (sad_array[t] < bestsad) {
1232
58.9M
              bestsad = sad_array[t];
1233
58.9M
              best_site = i;
1234
58.9M
            }
1235
171M
          }
1236
531M
        }
1237
132M
      }
1238
66.4M
    } else {
1239
181M
      for (j = 0; j < x->searches_per_step; ++j) {
1240
        /* Trap illegal vectors */
1241
161M
        this_row_offset = best_mv->as_mv.row + ss[i].mv.row;
1242
161M
        this_col_offset = best_mv->as_mv.col + ss[i].mv.col;
1243
1244
161M
        if ((this_col_offset > x->mv_col_min) &&
1245
138M
            (this_col_offset < x->mv_col_max) &&
1246
114M
            (this_row_offset > x->mv_row_min) &&
1247
87.2M
            (this_row_offset < x->mv_row_max)) {
1248
61.9M
          check_here = ss[i].offset + best_address;
1249
61.9M
          thissad = fn_ptr->sdf(what, what_stride, check_here, in_what_stride);
1250
1251
61.9M
          if (thissad < bestsad) {
1252
23.1M
            this_mv.as_mv.row = this_row_offset;
1253
23.1M
            this_mv.as_mv.col = this_col_offset;
1254
23.1M
            thissad +=
1255
23.1M
                mvsad_err_cost(&this_mv, &fcenter_mv, mvsadcost, sad_per_bit);
1256
1257
23.1M
            if (thissad < bestsad) {
1258
10.5M
              bestsad = thissad;
1259
10.5M
              best_site = i;
1260
10.5M
            }
1261
23.1M
          }
1262
61.9M
        }
1263
161M
        i++;
1264
161M
      }
1265
20.1M
    }
1266
1267
86.6M
    if (best_site != last_site) {
1268
45.6M
      best_mv->as_mv.row += ss[best_site].mv.row;
1269
45.6M
      best_mv->as_mv.col += ss[best_site].mv.col;
1270
45.6M
      best_address += ss[best_site].offset;
1271
45.6M
      last_site = best_site;
1272
45.6M
    } else if (best_address == in_what) {
1273
17.4M
      (*num00)++;
1274
17.4M
    }
1275
86.6M
  }
1276
1277
22.9M
  this_mv.as_mv.row = clamp(best_mv->as_mv.row * 8, SHRT_MIN, SHRT_MAX);
1278
22.9M
  this_mv.as_mv.col = clamp(best_mv->as_mv.col * 8, SHRT_MIN, SHRT_MAX);
1279
1280
22.9M
  return fn_ptr->vf(what, what_stride, best_address, in_what_stride, &thissad) +
1281
22.9M
         mv_err_cost(&this_mv, center_mv, mvcost, x->errorperbit);
1282
22.9M
}
1283
#endif  // HAVE_SSE2 || HAVE_MSA || HAVE_LSX
1284
1285
int vp8_full_search_sad(MACROBLOCK *x, BLOCK *b, BLOCKD *d, int_mv *ref_mv,
1286
                        int sad_per_bit, int distance,
1287
                        vp8_variance_fn_ptr_t *fn_ptr, int *mvcost[2],
1288
0
                        int_mv *center_mv) {
1289
0
  unsigned char *what = (*(b->base_src) + b->src);
1290
0
  int what_stride = b->src_stride;
1291
0
  unsigned char *in_what;
1292
0
  int pre_stride = x->e_mbd.pre.y_stride;
1293
0
  unsigned char *base_pre = x->e_mbd.pre.y_buffer;
1294
0
  int in_what_stride = pre_stride;
1295
0
  int mv_stride = pre_stride;
1296
0
  unsigned char *bestaddress;
1297
0
  int_mv *best_mv = &d->bmi.mv;
1298
0
  int_mv this_mv;
1299
0
  unsigned int bestsad;
1300
0
  unsigned int thissad;
1301
0
  int r, c;
1302
1303
0
  unsigned char *check_here;
1304
1305
0
  int ref_row = ref_mv->as_mv.row;
1306
0
  int ref_col = ref_mv->as_mv.col;
1307
1308
0
  int row_min = ref_row - distance;
1309
0
  int row_max = ref_row + distance;
1310
0
  int col_min = ref_col - distance;
1311
0
  int col_max = ref_col + distance;
1312
1313
0
  int *mvsadcost[2];
1314
0
  int_mv fcenter_mv;
1315
1316
0
  mvsadcost[0] = x->mvsadcost[0];
1317
0
  mvsadcost[1] = x->mvsadcost[1];
1318
0
  fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3;
1319
0
  fcenter_mv.as_mv.col = center_mv->as_mv.col >> 3;
1320
1321
  /* Work out the mid point for the search */
1322
0
  in_what = base_pre + d->offset;
1323
0
  bestaddress = in_what + (ref_row * pre_stride) + ref_col;
1324
1325
0
  best_mv->as_mv.row = ref_row;
1326
0
  best_mv->as_mv.col = ref_col;
1327
1328
  /* Baseline value at the centre */
1329
0
  bestsad = fn_ptr->sdf(what, what_stride, bestaddress, in_what_stride) +
1330
0
            mvsad_err_cost(best_mv, &fcenter_mv, mvsadcost, sad_per_bit);
1331
1332
  /* Apply further limits to prevent us looking using vectors that stretch
1333
   * beyond the UMV border
1334
   */
1335
0
  if (col_min < x->mv_col_min) col_min = x->mv_col_min;
1336
1337
0
  if (col_max > x->mv_col_max) col_max = x->mv_col_max;
1338
1339
0
  if (row_min < x->mv_row_min) row_min = x->mv_row_min;
1340
1341
0
  if (row_max > x->mv_row_max) row_max = x->mv_row_max;
1342
1343
0
  for (r = row_min; r < row_max; ++r) {
1344
0
    this_mv.as_mv.row = r;
1345
0
    check_here = r * mv_stride + in_what + col_min;
1346
1347
0
    for (c = col_min; c < col_max; ++c) {
1348
0
      thissad = fn_ptr->sdf(what, what_stride, check_here, in_what_stride);
1349
1350
0
      if (thissad < bestsad) {
1351
0
        this_mv.as_mv.col = c;
1352
0
        thissad +=
1353
0
            mvsad_err_cost(&this_mv, &fcenter_mv, mvsadcost, sad_per_bit);
1354
1355
0
        if (thissad < bestsad) {
1356
0
          bestsad = thissad;
1357
0
          best_mv->as_mv.row = r;
1358
0
          best_mv->as_mv.col = c;
1359
0
          bestaddress = check_here;
1360
0
        }
1361
0
      }
1362
1363
0
      check_here++;
1364
0
    }
1365
0
  }
1366
1367
0
  this_mv.as_mv.row = clamp(best_mv->as_mv.row * 8, SHRT_MIN, SHRT_MAX);
1368
0
  this_mv.as_mv.col = clamp(best_mv->as_mv.col * 8, SHRT_MIN, SHRT_MAX);
1369
1370
0
  return fn_ptr->vf(what, what_stride, bestaddress, in_what_stride, &thissad) +
1371
0
         mv_err_cost(&this_mv, center_mv, mvcost, x->errorperbit);
1372
0
}
1373
1374
int vp8_refining_search_sad_c(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
1375
                              int_mv *ref_mv, int error_per_bit,
1376
                              int search_range, vp8_variance_fn_ptr_t *fn_ptr,
1377
0
                              int *mvcost[2], int_mv *center_mv) {
1378
0
  MV neighbors[4] = { { -1, 0 }, { 0, -1 }, { 0, 1 }, { 1, 0 } };
1379
0
  int i, j;
1380
0
  short this_row_offset, this_col_offset;
1381
1382
0
  int what_stride = b->src_stride;
1383
0
  int pre_stride = x->e_mbd.pre.y_stride;
1384
0
  unsigned char *base_pre = x->e_mbd.pre.y_buffer;
1385
0
  int in_what_stride = pre_stride;
1386
0
  unsigned char *what = (*(b->base_src) + b->src);
1387
0
  unsigned char *best_address =
1388
0
      (unsigned char *)(base_pre + d->offset +
1389
0
                        (ref_mv->as_mv.row * pre_stride) + ref_mv->as_mv.col);
1390
0
  unsigned char *check_here;
1391
0
  int_mv this_mv;
1392
0
  unsigned int bestsad;
1393
0
  unsigned int thissad;
1394
1395
0
  int *mvsadcost[2];
1396
0
  int_mv fcenter_mv;
1397
1398
0
  mvsadcost[0] = x->mvsadcost[0];
1399
0
  mvsadcost[1] = x->mvsadcost[1];
1400
0
  fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3;
1401
0
  fcenter_mv.as_mv.col = center_mv->as_mv.col >> 3;
1402
1403
0
  bestsad = fn_ptr->sdf(what, what_stride, best_address, in_what_stride) +
1404
0
            mvsad_err_cost(ref_mv, &fcenter_mv, mvsadcost, error_per_bit);
1405
1406
0
  for (i = 0; i < search_range; ++i) {
1407
0
    int best_site = -1;
1408
1409
0
    for (j = 0; j < 4; ++j) {
1410
0
      this_row_offset = ref_mv->as_mv.row + neighbors[j].row;
1411
0
      this_col_offset = ref_mv->as_mv.col + neighbors[j].col;
1412
1413
0
      if ((this_col_offset > x->mv_col_min) &&
1414
0
          (this_col_offset < x->mv_col_max) &&
1415
0
          (this_row_offset > x->mv_row_min) &&
1416
0
          (this_row_offset < x->mv_row_max)) {
1417
0
        check_here = (neighbors[j].row) * in_what_stride + neighbors[j].col +
1418
0
                     best_address;
1419
0
        thissad = fn_ptr->sdf(what, what_stride, check_here, in_what_stride);
1420
1421
0
        if (thissad < bestsad) {
1422
0
          this_mv.as_mv.row = this_row_offset;
1423
0
          this_mv.as_mv.col = this_col_offset;
1424
0
          thissad +=
1425
0
              mvsad_err_cost(&this_mv, &fcenter_mv, mvsadcost, error_per_bit);
1426
1427
0
          if (thissad < bestsad) {
1428
0
            bestsad = thissad;
1429
0
            best_site = j;
1430
0
          }
1431
0
        }
1432
0
      }
1433
0
    }
1434
1435
0
    if (best_site == -1) {
1436
0
      break;
1437
0
    } else {
1438
0
      ref_mv->as_mv.row += neighbors[best_site].row;
1439
0
      ref_mv->as_mv.col += neighbors[best_site].col;
1440
0
      best_address += (neighbors[best_site].row) * in_what_stride +
1441
0
                      neighbors[best_site].col;
1442
0
    }
1443
0
  }
1444
1445
0
  this_mv.as_mv.row = clamp(ref_mv->as_mv.row * 8, SHRT_MIN, SHRT_MAX);
1446
0
  this_mv.as_mv.col = clamp(ref_mv->as_mv.col * 8, SHRT_MIN, SHRT_MAX);
1447
1448
0
  return fn_ptr->vf(what, what_stride, best_address, in_what_stride, &thissad) +
1449
0
         mv_err_cost(&this_mv, center_mv, mvcost, x->errorperbit);
1450
0
}
1451
1452
#if HAVE_SSE2 || HAVE_MSA
1453
int vp8_refining_search_sadx4(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
1454
                              int_mv *ref_mv, int error_per_bit,
1455
                              int search_range, vp8_variance_fn_ptr_t *fn_ptr,
1456
596k
                              int *mvcost[2], int_mv *center_mv) {
1457
596k
  MV neighbors[4] = { { -1, 0 }, { 0, -1 }, { 0, 1 }, { 1, 0 } };
1458
596k
  int i, j;
1459
596k
  short this_row_offset, this_col_offset;
1460
1461
596k
  int what_stride = b->src_stride;
1462
596k
  int pre_stride = x->e_mbd.pre.y_stride;
1463
596k
  unsigned char *base_pre = x->e_mbd.pre.y_buffer;
1464
596k
  int in_what_stride = pre_stride;
1465
596k
  unsigned char *what = (*(b->base_src) + b->src);
1466
596k
  unsigned char *best_address =
1467
596k
      (unsigned char *)(base_pre + d->offset +
1468
596k
                        (ref_mv->as_mv.row * pre_stride) + ref_mv->as_mv.col);
1469
596k
  unsigned char *check_here;
1470
596k
  int_mv this_mv;
1471
596k
  unsigned int bestsad;
1472
596k
  unsigned int thissad;
1473
1474
596k
  int *mvsadcost[2];
1475
596k
  int_mv fcenter_mv;
1476
1477
596k
  mvsadcost[0] = x->mvsadcost[0];
1478
596k
  mvsadcost[1] = x->mvsadcost[1];
1479
596k
  fcenter_mv.as_mv.row = center_mv->as_mv.row >> 3;
1480
596k
  fcenter_mv.as_mv.col = center_mv->as_mv.col >> 3;
1481
1482
596k
  bestsad = fn_ptr->sdf(what, what_stride, best_address, in_what_stride) +
1483
596k
            mvsad_err_cost(ref_mv, &fcenter_mv, mvsadcost, error_per_bit);
1484
1485
727k
  for (i = 0; i < search_range; ++i) {
1486
721k
    int best_site = -1;
1487
721k
    int all_in = 1;
1488
1489
721k
    all_in &= ((ref_mv->as_mv.row - 1) > x->mv_row_min);
1490
721k
    all_in &= ((ref_mv->as_mv.row + 1) < x->mv_row_max);
1491
721k
    all_in &= ((ref_mv->as_mv.col - 1) > x->mv_col_min);
1492
721k
    all_in &= ((ref_mv->as_mv.col + 1) < x->mv_col_max);
1493
1494
721k
    if (all_in) {
1495
600k
      unsigned int sad_array[4];
1496
600k
      const unsigned char *block_offset[4];
1497
600k
      block_offset[0] = best_address - in_what_stride;
1498
600k
      block_offset[1] = best_address - 1;
1499
600k
      block_offset[2] = best_address + 1;
1500
600k
      block_offset[3] = best_address + in_what_stride;
1501
1502
600k
      fn_ptr->sdx4df(what, what_stride, block_offset, in_what_stride,
1503
600k
                     sad_array);
1504
1505
3.00M
      for (j = 0; j < 4; ++j) {
1506
2.40M
        if (sad_array[j] < bestsad) {
1507
802k
          this_mv.as_mv.row = ref_mv->as_mv.row + neighbors[j].row;
1508
802k
          this_mv.as_mv.col = ref_mv->as_mv.col + neighbors[j].col;
1509
802k
          sad_array[j] +=
1510
802k
              mvsad_err_cost(&this_mv, &fcenter_mv, mvsadcost, error_per_bit);
1511
1512
802k
          if (sad_array[j] < bestsad) {
1513
121k
            bestsad = sad_array[j];
1514
121k
            best_site = j;
1515
121k
          }
1516
802k
        }
1517
2.40M
      }
1518
600k
    } else {
1519
605k
      for (j = 0; j < 4; ++j) {
1520
484k
        this_row_offset = ref_mv->as_mv.row + neighbors[j].row;
1521
484k
        this_col_offset = ref_mv->as_mv.col + neighbors[j].col;
1522
1523
484k
        if ((this_col_offset > x->mv_col_min) &&
1524
452k
            (this_col_offset < x->mv_col_max) &&
1525
435k
            (this_row_offset > x->mv_row_min) &&
1526
370k
            (this_row_offset < x->mv_row_max)) {
1527
357k
          check_here = (neighbors[j].row) * in_what_stride + neighbors[j].col +
1528
357k
                       best_address;
1529
357k
          thissad = fn_ptr->sdf(what, what_stride, check_here, in_what_stride);
1530
1531
357k
          if (thissad < bestsad) {
1532
126k
            this_mv.as_mv.row = this_row_offset;
1533
126k
            this_mv.as_mv.col = this_col_offset;
1534
126k
            thissad +=
1535
126k
                mvsad_err_cost(&this_mv, &fcenter_mv, mvsadcost, error_per_bit);
1536
1537
126k
            if (thissad < bestsad) {
1538
14.7k
              bestsad = thissad;
1539
14.7k
              best_site = j;
1540
14.7k
            }
1541
126k
          }
1542
357k
        }
1543
484k
      }
1544
121k
    }
1545
1546
721k
    if (best_site == -1) {
1547
590k
      break;
1548
590k
    } else {
1549
131k
      ref_mv->as_mv.row += neighbors[best_site].row;
1550
131k
      ref_mv->as_mv.col += neighbors[best_site].col;
1551
131k
      best_address += (neighbors[best_site].row) * in_what_stride +
1552
131k
                      neighbors[best_site].col;
1553
131k
    }
1554
721k
  }
1555
1556
596k
  this_mv.as_mv.row = clamp(ref_mv->as_mv.row * 8, SHRT_MIN, SHRT_MAX);
1557
596k
  this_mv.as_mv.col = clamp(ref_mv->as_mv.col * 8, SHRT_MIN, SHRT_MAX);
1558
1559
596k
  return fn_ptr->vf(what, what_stride, best_address, in_what_stride, &thissad) +
1560
596k
         mv_err_cost(&this_mv, center_mv, mvcost, x->errorperbit);
1561
596k
}
1562
#endif  // HAVE_SSE2 || HAVE_MSA