]> granicus.if.org Git - libvpx/blob - vp10/encoder/mcomp.c
Merge "VPX: scaled convolve : fix windows build errors"
[libvpx] / vp10 / encoder / mcomp.c
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 <limits.h>
12 #include <math.h>
13 #include <stdio.h>
14
15 #include "./vpx_config.h"
16 #include "./vpx_dsp_rtcd.h"
17
18 #include "vpx_mem/vpx_mem.h"
19 #include "vpx_ports/mem.h"
20
21 #include "vp10/common/common.h"
22 #include "vp10/common/reconinter.h"
23
24 #include "vp10/encoder/encoder.h"
25 #include "vp10/encoder/mcomp.h"
26
27 // #define NEW_DIAMOND_SEARCH
28
29 static INLINE const uint8_t *get_buf_from_mv(const struct buf_2d *buf,
30                                              const MV *mv) {
31   return &buf->buf[mv->row * buf->stride + mv->col];
32 }
33
34 void vp10_set_mv_search_range(MACROBLOCK *x, const MV *mv) {
35   int col_min = (mv->col >> 3) - MAX_FULL_PEL_VAL + (mv->col & 7 ? 1 : 0);
36   int row_min = (mv->row >> 3) - MAX_FULL_PEL_VAL + (mv->row & 7 ? 1 : 0);
37   int col_max = (mv->col >> 3) + MAX_FULL_PEL_VAL;
38   int row_max = (mv->row >> 3) + MAX_FULL_PEL_VAL;
39
40   col_min = MAX(col_min, (MV_LOW >> 3) + 1);
41   row_min = MAX(row_min, (MV_LOW >> 3) + 1);
42   col_max = MIN(col_max, (MV_UPP >> 3) - 1);
43   row_max = MIN(row_max, (MV_UPP >> 3) - 1);
44
45   // Get intersection of UMV window and valid MV window to reduce # of checks
46   // in diamond search.
47   if (x->mv_col_min < col_min)
48     x->mv_col_min = col_min;
49   if (x->mv_col_max > col_max)
50     x->mv_col_max = col_max;
51   if (x->mv_row_min < row_min)
52     x->mv_row_min = row_min;
53   if (x->mv_row_max > row_max)
54     x->mv_row_max = row_max;
55 }
56
57 int vp10_init_search_range(int size) {
58   int sr = 0;
59   // Minimum search size no matter what the passed in value.
60   size = MAX(16, size);
61
62   while ((size << sr) < MAX_FULL_PEL_VAL)
63     sr++;
64
65   sr = MIN(sr, MAX_MVSEARCH_STEPS - 2);
66   return sr;
67 }
68
69 static INLINE int mv_cost(const MV *mv,
70                           const int *joint_cost, int *const comp_cost[2]) {
71   return joint_cost[vp10_get_mv_joint(mv)] +
72              comp_cost[0][mv->row] + comp_cost[1][mv->col];
73 }
74
75 int vp10_mv_bit_cost(const MV *mv, const MV *ref,
76                     const int *mvjcost, int *mvcost[2], int weight) {
77   const MV diff = { mv->row - ref->row,
78                     mv->col - ref->col };
79   return ROUND_POWER_OF_TWO(mv_cost(&diff, mvjcost, mvcost) * weight, 7);
80 }
81
82 static int mv_err_cost(const MV *mv, const MV *ref,
83                        const int *mvjcost, int *mvcost[2],
84                        int error_per_bit) {
85   if (mvcost) {
86     const MV diff = { mv->row - ref->row,
87                       mv->col - ref->col };
88     return ROUND_POWER_OF_TWO(mv_cost(&diff, mvjcost, mvcost) *
89                                   error_per_bit, 13);
90   }
91   return 0;
92 }
93
94 static int mvsad_err_cost(const MACROBLOCK *x, const MV *mv, const MV *ref,
95                           int error_per_bit) {
96   const MV diff = { mv->row - ref->row,
97                     mv->col - ref->col };
98   return ROUND_POWER_OF_TWO(mv_cost(&diff, x->nmvjointsadcost,
99                                     x->nmvsadcost) * error_per_bit, 8);
100 }
101
102 void vp10_init_dsmotion_compensation(search_site_config *cfg, int stride) {
103   int len, ss_count = 1;
104
105   cfg->ss[0].mv.col = cfg->ss[0].mv.row = 0;
106   cfg->ss[0].offset = 0;
107
108   for (len = MAX_FIRST_STEP; len > 0; len /= 2) {
109     // Generate offsets for 4 search sites per step.
110     const MV ss_mvs[] = {{-len, 0}, {len, 0}, {0, -len}, {0, len}};
111     int i;
112     for (i = 0; i < 4; ++i) {
113       search_site *const ss = &cfg->ss[ss_count++];
114       ss->mv = ss_mvs[i];
115       ss->offset = ss->mv.row * stride + ss->mv.col;
116     }
117   }
118
119   cfg->ss_count = ss_count;
120   cfg->searches_per_step = 4;
121 }
122
123 void vp10_init3smotion_compensation(search_site_config *cfg, int stride) {
124   int len, ss_count = 1;
125
126   cfg->ss[0].mv.col = cfg->ss[0].mv.row = 0;
127   cfg->ss[0].offset = 0;
128
129   for (len = MAX_FIRST_STEP; len > 0; len /= 2) {
130     // Generate offsets for 8 search sites per step.
131     const MV ss_mvs[8] = {
132       {-len,  0  }, {len,  0  }, { 0,   -len}, {0,    len},
133       {-len, -len}, {-len, len}, {len,  -len}, {len,  len}
134     };
135     int i;
136     for (i = 0; i < 8; ++i) {
137       search_site *const ss = &cfg->ss[ss_count++];
138       ss->mv = ss_mvs[i];
139       ss->offset = ss->mv.row * stride + ss->mv.col;
140     }
141   }
142
143   cfg->ss_count = ss_count;
144   cfg->searches_per_step = 8;
145 }
146
147 /*
148  * To avoid the penalty for crossing cache-line read, preload the reference
149  * area in a small buffer, which is aligned to make sure there won't be crossing
150  * cache-line read while reading from this buffer. This reduced the cpu
151  * cycles spent on reading ref data in sub-pixel filter functions.
152  * TODO: Currently, since sub-pixel search range here is -3 ~ 3, copy 22 rows x
153  * 32 cols area that is enough for 16x16 macroblock. Later, for SPLITMV, we
154  * could reduce the area.
155  */
156
157 /* estimated cost of a motion vector (r,c) */
158 #define MVC(r, c)                                       \
159     (mvcost ?                                           \
160      ((mvjcost[((r) != rr) * 2 + ((c) != rc)] +         \
161        mvcost[0][((r) - rr)] + mvcost[1][((c) - rc)]) * \
162       error_per_bit + 4096) >> 13 : 0)
163
164
165 // convert motion vector component to offset for sv[a]f calc
166 static INLINE int sp(int x) {
167   return x & 7;
168 }
169
170 static INLINE const uint8_t *pre(const uint8_t *buf, int stride, int r, int c) {
171   return &buf[(r >> 3) * stride + (c >> 3)];
172 }
173
174 /* checks if (r, c) has better score than previous best */
175 #define CHECK_BETTER(v, r, c) \
176   if (c >= minc && c <= maxc && r >= minr && r <= maxr) {              \
177     if (second_pred == NULL)                                           \
178       thismse = vfp->svf(pre(y, y_stride, r, c), y_stride, sp(c), sp(r), z, \
179                              src_stride, &sse);                        \
180     else                                                               \
181       thismse = vfp->svaf(pre(y, y_stride, r, c), y_stride, sp(c), sp(r), \
182                               z, src_stride, &sse, second_pred);       \
183     if ((v = MVC(r, c) + thismse) < besterr) {                         \
184       besterr = v;                                                     \
185       br = r;                                                          \
186       bc = c;                                                          \
187       *distortion = thismse;                                           \
188       *sse1 = sse;                                                     \
189     }                                                                  \
190   } else {                                                             \
191     v = INT_MAX;                                                       \
192   }
193
194 #define FIRST_LEVEL_CHECKS                              \
195   {                                                     \
196     unsigned int left, right, up, down, diag;           \
197     CHECK_BETTER(left, tr, tc - hstep);                 \
198     CHECK_BETTER(right, tr, tc + hstep);                \
199     CHECK_BETTER(up, tr - hstep, tc);                   \
200     CHECK_BETTER(down, tr + hstep, tc);                 \
201     whichdir = (left < right ? 0 : 1) +                 \
202                (up < down ? 0 : 2);                     \
203     switch (whichdir) {                                 \
204       case 0:                                           \
205         CHECK_BETTER(diag, tr - hstep, tc - hstep);     \
206         break;                                          \
207       case 1:                                           \
208         CHECK_BETTER(diag, tr - hstep, tc + hstep);     \
209         break;                                          \
210       case 2:                                           \
211         CHECK_BETTER(diag, tr + hstep, tc - hstep);     \
212         break;                                          \
213       case 3:                                           \
214         CHECK_BETTER(diag, tr + hstep, tc + hstep);     \
215         break;                                          \
216     }                                                   \
217   }
218
219 #define SECOND_LEVEL_CHECKS                             \
220   {                                                     \
221     int kr, kc;                                         \
222     unsigned int second;                                \
223     if (tr != br && tc != bc) {                         \
224       kr = br - tr;                                     \
225       kc = bc - tc;                                     \
226       CHECK_BETTER(second, tr + kr, tc + 2 * kc);       \
227       CHECK_BETTER(second, tr + 2 * kr, tc + kc);       \
228     } else if (tr == br && tc != bc) {                  \
229       kc = bc - tc;                                     \
230       CHECK_BETTER(second, tr + hstep, tc + 2 * kc);    \
231       CHECK_BETTER(second, tr - hstep, tc + 2 * kc);    \
232       switch (whichdir) {                               \
233         case 0:                                         \
234         case 1:                                         \
235           CHECK_BETTER(second, tr + hstep, tc + kc);    \
236           break;                                        \
237         case 2:                                         \
238         case 3:                                         \
239           CHECK_BETTER(second, tr - hstep, tc + kc);    \
240           break;                                        \
241       }                                                 \
242     } else if (tr != br && tc == bc) {                  \
243       kr = br - tr;                                     \
244       CHECK_BETTER(second, tr + 2 * kr, tc + hstep);    \
245       CHECK_BETTER(second, tr + 2 * kr, tc - hstep);    \
246       switch (whichdir) {                               \
247         case 0:                                         \
248         case 2:                                         \
249           CHECK_BETTER(second, tr + kr, tc + hstep);    \
250           break;                                        \
251         case 1:                                         \
252         case 3:                                         \
253           CHECK_BETTER(second, tr + kr, tc - hstep);    \
254           break;                                        \
255       }                                                 \
256     }                                                   \
257   }
258
259 // TODO(yunqingwang): SECOND_LEVEL_CHECKS_BEST was a rewrote of
260 // SECOND_LEVEL_CHECKS, and SECOND_LEVEL_CHECKS should be rewritten
261 // later in the same way.
262 #define SECOND_LEVEL_CHECKS_BEST                        \
263   {                                                     \
264     unsigned int second;                                \
265     int br0 = br;                                       \
266     int bc0 = bc;                                       \
267     assert(tr == br || tc == bc);                       \
268     if (tr == br && tc != bc) {                         \
269       kc = bc - tc;                                     \
270     } else if (tr != br && tc == bc) {                  \
271       kr = br - tr;                                     \
272     }                                                   \
273     CHECK_BETTER(second, br0 + kr, bc0);                \
274     CHECK_BETTER(second, br0, bc0 + kc);                \
275     if (br0 != br || bc0 != bc) {                       \
276       CHECK_BETTER(second, br0 + kr, bc0 + kc);         \
277     }                                                   \
278   }
279
280 #define SETUP_SUBPEL_SEARCH                                                \
281   const uint8_t *const z = x->plane[0].src.buf;                            \
282   const int src_stride = x->plane[0].src.stride;                           \
283   const MACROBLOCKD *xd = &x->e_mbd;                                       \
284   unsigned int besterr = INT_MAX;                                          \
285   unsigned int sse;                                                        \
286   unsigned int whichdir;                                                   \
287   int thismse;                                                             \
288   const unsigned int halfiters = iters_per_step;                           \
289   const unsigned int quarteriters = iters_per_step;                        \
290   const unsigned int eighthiters = iters_per_step;                         \
291   const int y_stride = xd->plane[0].pre[0].stride;                         \
292   const int offset = bestmv->row * y_stride + bestmv->col;                 \
293   const uint8_t *const y = xd->plane[0].pre[0].buf;                        \
294                                                                            \
295   int rr = ref_mv->row;                                                    \
296   int rc = ref_mv->col;                                                    \
297   int br = bestmv->row * 8;                                                \
298   int bc = bestmv->col * 8;                                                \
299   int hstep = 4;                                                           \
300   const int minc = MAX(x->mv_col_min * 8, ref_mv->col - MV_MAX);           \
301   const int maxc = MIN(x->mv_col_max * 8, ref_mv->col + MV_MAX);           \
302   const int minr = MAX(x->mv_row_min * 8, ref_mv->row - MV_MAX);           \
303   const int maxr = MIN(x->mv_row_max * 8, ref_mv->row + MV_MAX);           \
304   int tr = br;                                                             \
305   int tc = bc;                                                             \
306                                                                            \
307   bestmv->row *= 8;                                                        \
308   bestmv->col *= 8;
309
310 static unsigned int setup_center_error(const MACROBLOCKD *xd,
311                                        const MV *bestmv,
312                                        const MV *ref_mv,
313                                        int error_per_bit,
314                                        const vp9_variance_fn_ptr_t *vfp,
315                                        const uint8_t *const src,
316                                        const int src_stride,
317                                        const uint8_t *const y,
318                                        int y_stride,
319                                        const uint8_t *second_pred,
320                                        int w, int h, int offset,
321                                        int *mvjcost, int *mvcost[2],
322                                        unsigned int *sse1,
323                                        int *distortion) {
324   unsigned int besterr;
325 #if CONFIG_VP9_HIGHBITDEPTH
326   if (second_pred != NULL) {
327     if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
328       DECLARE_ALIGNED(16, uint16_t, comp_pred16[64 * 64]);
329       vpx_highbd_comp_avg_pred(comp_pred16, second_pred, w, h, y + offset,
330                                y_stride);
331       besterr = vfp->vf(CONVERT_TO_BYTEPTR(comp_pred16), w, src, src_stride,
332                         sse1);
333     } else {
334       DECLARE_ALIGNED(16, uint8_t, comp_pred[64 * 64]);
335       vpx_comp_avg_pred(comp_pred, second_pred, w, h, y + offset, y_stride);
336       besterr = vfp->vf(comp_pred, w, src, src_stride, sse1);
337     }
338   } else {
339     besterr = vfp->vf(y + offset, y_stride, src, src_stride, sse1);
340   }
341   *distortion = besterr;
342   besterr += mv_err_cost(bestmv, ref_mv, mvjcost, mvcost, error_per_bit);
343 #else
344   (void) xd;
345   if (second_pred != NULL) {
346     DECLARE_ALIGNED(16, uint8_t, comp_pred[64 * 64]);
347     vpx_comp_avg_pred(comp_pred, second_pred, w, h, y + offset, y_stride);
348     besterr = vfp->vf(comp_pred, w, src, src_stride, sse1);
349   } else {
350     besterr = vfp->vf(y + offset, y_stride, src, src_stride, sse1);
351   }
352   *distortion = besterr;
353   besterr += mv_err_cost(bestmv, ref_mv, mvjcost, mvcost, error_per_bit);
354 #endif  // CONFIG_VP9_HIGHBITDEPTH
355   return besterr;
356 }
357
358 static INLINE int divide_and_round(const int n, const int d) {
359   return ((n < 0) ^ (d < 0)) ? ((n - d / 2) / d) : ((n + d / 2) / d);
360 }
361
362 static INLINE int is_cost_list_wellbehaved(int *cost_list) {
363   return cost_list[0] < cost_list[1] &&
364          cost_list[0] < cost_list[2] &&
365          cost_list[0] < cost_list[3] &&
366          cost_list[0] < cost_list[4];
367 }
368
369 // Returns surface minima estimate at given precision in 1/2^n bits.
370 // Assume a model for the cost surface: S = A(x - x0)^2 + B(y - y0)^2 + C
371 // For a given set of costs S0, S1, S2, S3, S4 at points
372 // (y, x) = (0, 0), (0, -1), (1, 0), (0, 1) and (-1, 0) respectively,
373 // the solution for the location of the minima (x0, y0) is given by:
374 // x0 = 1/2 (S1 - S3)/(S1 + S3 - 2*S0),
375 // y0 = 1/2 (S4 - S2)/(S4 + S2 - 2*S0).
376 // The code below is an integerized version of that.
377 static void get_cost_surf_min(int *cost_list, int *ir, int *ic,
378                               int bits) {
379   *ic = divide_and_round((cost_list[1] - cost_list[3]) * (1 << (bits - 1)),
380                          (cost_list[1] - 2 * cost_list[0] + cost_list[3]));
381   *ir = divide_and_round((cost_list[4] - cost_list[2]) * (1 << (bits - 1)),
382                          (cost_list[4] - 2 * cost_list[0] + cost_list[2]));
383 }
384
385 int vp10_find_best_sub_pixel_tree_pruned_evenmore(
386     const MACROBLOCK *x,
387     MV *bestmv, const MV *ref_mv,
388     int allow_hp,
389     int error_per_bit,
390     const vp9_variance_fn_ptr_t *vfp,
391     int forced_stop,
392     int iters_per_step,
393     int *cost_list,
394     int *mvjcost, int *mvcost[2],
395     int *distortion,
396     unsigned int *sse1,
397     const uint8_t *second_pred,
398     int w, int h) {
399   SETUP_SUBPEL_SEARCH;
400   besterr = setup_center_error(xd, bestmv, ref_mv, error_per_bit, vfp,
401                                z, src_stride, y, y_stride, second_pred,
402                                w, h, offset, mvjcost, mvcost,
403                                sse1, distortion);
404   (void) halfiters;
405   (void) quarteriters;
406   (void) eighthiters;
407   (void) whichdir;
408   (void) allow_hp;
409   (void) forced_stop;
410   (void) hstep;
411
412   if (cost_list &&
413       cost_list[0] != INT_MAX && cost_list[1] != INT_MAX &&
414       cost_list[2] != INT_MAX && cost_list[3] != INT_MAX &&
415       cost_list[4] != INT_MAX &&
416       is_cost_list_wellbehaved(cost_list)) {
417     int ir, ic;
418     unsigned int minpt;
419     get_cost_surf_min(cost_list, &ir, &ic, 2);
420     if (ir != 0 || ic != 0) {
421       CHECK_BETTER(minpt, tr + 2 * ir, tc + 2 * ic);
422     }
423   } else {
424     FIRST_LEVEL_CHECKS;
425     if (halfiters > 1) {
426       SECOND_LEVEL_CHECKS;
427     }
428
429     tr = br;
430     tc = bc;
431
432     // Each subsequent iteration checks at least one point in common with
433     // the last iteration could be 2 ( if diag selected) 1/4 pel
434     // Note forced_stop: 0 - full, 1 - qtr only, 2 - half only
435     if (forced_stop != 2) {
436       hstep >>= 1;
437       FIRST_LEVEL_CHECKS;
438       if (quarteriters > 1) {
439         SECOND_LEVEL_CHECKS;
440       }
441     }
442   }
443
444   tr = br;
445   tc = bc;
446
447   if (allow_hp && vp10_use_mv_hp(ref_mv) && forced_stop == 0) {
448     hstep >>= 1;
449     FIRST_LEVEL_CHECKS;
450     if (eighthiters > 1) {
451       SECOND_LEVEL_CHECKS;
452     }
453   }
454
455   bestmv->row = br;
456   bestmv->col = bc;
457
458   if ((abs(bestmv->col - ref_mv->col) > (MAX_FULL_PEL_VAL << 3)) ||
459       (abs(bestmv->row - ref_mv->row) > (MAX_FULL_PEL_VAL << 3)))
460     return INT_MAX;
461
462   return besterr;
463 }
464
465 int vp10_find_best_sub_pixel_tree_pruned_more(const MACROBLOCK *x,
466                                              MV *bestmv, const MV *ref_mv,
467                                              int allow_hp,
468                                              int error_per_bit,
469                                              const vp9_variance_fn_ptr_t *vfp,
470                                              int forced_stop,
471                                              int iters_per_step,
472                                              int *cost_list,
473                                              int *mvjcost, int *mvcost[2],
474                                              int *distortion,
475                                              unsigned int *sse1,
476                                              const uint8_t *second_pred,
477                                              int w, int h) {
478   SETUP_SUBPEL_SEARCH;
479   besterr = setup_center_error(xd, bestmv, ref_mv, error_per_bit, vfp,
480                                z, src_stride, y, y_stride, second_pred,
481                                w, h, offset, mvjcost, mvcost,
482                                sse1, distortion);
483   if (cost_list &&
484       cost_list[0] != INT_MAX && cost_list[1] != INT_MAX &&
485       cost_list[2] != INT_MAX && cost_list[3] != INT_MAX &&
486       cost_list[4] != INT_MAX &&
487       is_cost_list_wellbehaved(cost_list)) {
488     unsigned int minpt;
489     int ir, ic;
490     get_cost_surf_min(cost_list, &ir, &ic, 1);
491     if (ir != 0 || ic != 0) {
492       CHECK_BETTER(minpt, tr + ir * hstep, tc + ic * hstep);
493     }
494   } else {
495     FIRST_LEVEL_CHECKS;
496     if (halfiters > 1) {
497       SECOND_LEVEL_CHECKS;
498     }
499   }
500
501   // Each subsequent iteration checks at least one point in common with
502   // the last iteration could be 2 ( if diag selected) 1/4 pel
503
504   // Note forced_stop: 0 - full, 1 - qtr only, 2 - half only
505   if (forced_stop != 2) {
506     tr = br;
507     tc = bc;
508     hstep >>= 1;
509     FIRST_LEVEL_CHECKS;
510     if (quarteriters > 1) {
511       SECOND_LEVEL_CHECKS;
512     }
513   }
514
515   if (allow_hp && vp10_use_mv_hp(ref_mv) && forced_stop == 0) {
516     tr = br;
517     tc = bc;
518     hstep >>= 1;
519     FIRST_LEVEL_CHECKS;
520     if (eighthiters > 1) {
521       SECOND_LEVEL_CHECKS;
522     }
523   }
524   // These lines insure static analysis doesn't warn that
525   // tr and tc aren't used after the above point.
526   (void) tr;
527   (void) tc;
528
529   bestmv->row = br;
530   bestmv->col = bc;
531
532   if ((abs(bestmv->col - ref_mv->col) > (MAX_FULL_PEL_VAL << 3)) ||
533       (abs(bestmv->row - ref_mv->row) > (MAX_FULL_PEL_VAL << 3)))
534     return INT_MAX;
535
536   return besterr;
537 }
538
539 int vp10_find_best_sub_pixel_tree_pruned(const MACROBLOCK *x,
540                                         MV *bestmv, const MV *ref_mv,
541                                         int allow_hp,
542                                         int error_per_bit,
543                                         const vp9_variance_fn_ptr_t *vfp,
544                                         int forced_stop,
545                                         int iters_per_step,
546                                         int *cost_list,
547                                         int *mvjcost, int *mvcost[2],
548                                         int *distortion,
549                                         unsigned int *sse1,
550                                         const uint8_t *second_pred,
551                                         int w, int h) {
552   SETUP_SUBPEL_SEARCH;
553   besterr = setup_center_error(xd, bestmv, ref_mv, error_per_bit, vfp,
554                                z, src_stride, y, y_stride, second_pred,
555                                w, h, offset, mvjcost, mvcost,
556                                sse1, distortion);
557   if (cost_list &&
558       cost_list[0] != INT_MAX && cost_list[1] != INT_MAX &&
559       cost_list[2] != INT_MAX && cost_list[3] != INT_MAX &&
560       cost_list[4] != INT_MAX) {
561     unsigned int left, right, up, down, diag;
562     whichdir = (cost_list[1] < cost_list[3] ? 0 : 1) +
563                (cost_list[2] < cost_list[4] ? 0 : 2);
564     switch (whichdir) {
565       case 0:
566         CHECK_BETTER(left, tr, tc - hstep);
567         CHECK_BETTER(down, tr + hstep, tc);
568         CHECK_BETTER(diag, tr + hstep, tc - hstep);
569         break;
570       case 1:
571         CHECK_BETTER(right, tr, tc + hstep);
572         CHECK_BETTER(down, tr + hstep, tc);
573         CHECK_BETTER(diag, tr + hstep, tc + hstep);
574         break;
575       case 2:
576         CHECK_BETTER(left, tr, tc - hstep);
577         CHECK_BETTER(up, tr - hstep, tc);
578         CHECK_BETTER(diag, tr - hstep, tc - hstep);
579         break;
580       case 3:
581         CHECK_BETTER(right, tr, tc + hstep);
582         CHECK_BETTER(up, tr - hstep, tc);
583         CHECK_BETTER(diag, tr - hstep, tc + hstep);
584         break;
585     }
586   } else {
587     FIRST_LEVEL_CHECKS;
588     if (halfiters > 1) {
589       SECOND_LEVEL_CHECKS;
590     }
591   }
592
593   tr = br;
594   tc = bc;
595
596   // Each subsequent iteration checks at least one point in common with
597   // the last iteration could be 2 ( if diag selected) 1/4 pel
598
599   // Note forced_stop: 0 - full, 1 - qtr only, 2 - half only
600   if (forced_stop != 2) {
601     hstep >>= 1;
602     FIRST_LEVEL_CHECKS;
603     if (quarteriters > 1) {
604       SECOND_LEVEL_CHECKS;
605     }
606     tr = br;
607     tc = bc;
608   }
609
610   if (allow_hp && vp10_use_mv_hp(ref_mv) && forced_stop == 0) {
611     hstep >>= 1;
612     FIRST_LEVEL_CHECKS;
613     if (eighthiters > 1) {
614       SECOND_LEVEL_CHECKS;
615     }
616     tr = br;
617     tc = bc;
618   }
619   // These lines insure static analysis doesn't warn that
620   // tr and tc aren't used after the above point.
621   (void) tr;
622   (void) tc;
623
624   bestmv->row = br;
625   bestmv->col = bc;
626
627   if ((abs(bestmv->col - ref_mv->col) > (MAX_FULL_PEL_VAL << 3)) ||
628       (abs(bestmv->row - ref_mv->row) > (MAX_FULL_PEL_VAL << 3)))
629     return INT_MAX;
630
631   return besterr;
632 }
633
634 static const MV search_step_table[12] = {
635     // left, right, up, down
636     {0, -4}, {0, 4}, {-4, 0}, {4, 0},
637     {0, -2}, {0, 2}, {-2, 0}, {2, 0},
638     {0, -1}, {0, 1}, {-1, 0}, {1, 0}
639 };
640
641 int vp10_find_best_sub_pixel_tree(const MACROBLOCK *x,
642                                  MV *bestmv, const MV *ref_mv,
643                                  int allow_hp,
644                                  int error_per_bit,
645                                  const vp9_variance_fn_ptr_t *vfp,
646                                  int forced_stop,
647                                  int iters_per_step,
648                                  int *cost_list,
649                                  int *mvjcost, int *mvcost[2],
650                                  int *distortion,
651                                  unsigned int *sse1,
652                                  const uint8_t *second_pred,
653                                  int w, int h) {
654   const uint8_t *const z = x->plane[0].src.buf;
655   const uint8_t *const src_address = z;
656   const int src_stride = x->plane[0].src.stride;
657   const MACROBLOCKD *xd = &x->e_mbd;
658   unsigned int besterr = INT_MAX;
659   unsigned int sse;
660   int thismse;
661   const int y_stride = xd->plane[0].pre[0].stride;
662   const int offset = bestmv->row * y_stride + bestmv->col;
663   const uint8_t *const y = xd->plane[0].pre[0].buf;
664
665   int rr = ref_mv->row;
666   int rc = ref_mv->col;
667   int br = bestmv->row * 8;
668   int bc = bestmv->col * 8;
669   int hstep = 4;
670   int iter, round = 3 - forced_stop;
671   const int minc = MAX(x->mv_col_min * 8, ref_mv->col - MV_MAX);
672   const int maxc = MIN(x->mv_col_max * 8, ref_mv->col + MV_MAX);
673   const int minr = MAX(x->mv_row_min * 8, ref_mv->row - MV_MAX);
674   const int maxr = MIN(x->mv_row_max * 8, ref_mv->row + MV_MAX);
675   int tr = br;
676   int tc = bc;
677   const MV *search_step = search_step_table;
678   int idx, best_idx = -1;
679   unsigned int cost_array[5];
680   int kr, kc;
681
682   if (!(allow_hp && vp10_use_mv_hp(ref_mv)))
683     if (round == 3)
684       round = 2;
685
686   bestmv->row *= 8;
687   bestmv->col *= 8;
688
689   besterr = setup_center_error(xd, bestmv, ref_mv, error_per_bit, vfp,
690                                z, src_stride, y, y_stride, second_pred,
691                                w, h, offset, mvjcost, mvcost,
692                                sse1, distortion);
693
694   (void) cost_list;  // to silence compiler warning
695
696   for (iter = 0; iter < round; ++iter) {
697     // Check vertical and horizontal sub-pixel positions.
698     for (idx = 0; idx < 4; ++idx) {
699       tr = br + search_step[idx].row;
700       tc = bc + search_step[idx].col;
701       if (tc >= minc && tc <= maxc && tr >= minr && tr <= maxr) {
702         const uint8_t *const pre_address = y + (tr >> 3) * y_stride + (tc >> 3);
703         MV this_mv;
704         this_mv.row = tr;
705         this_mv.col = tc;
706         if (second_pred == NULL)
707           thismse = vfp->svf(pre_address, y_stride, sp(tc), sp(tr),
708                              src_address, src_stride, &sse);
709         else
710           thismse = vfp->svaf(pre_address, y_stride, sp(tc), sp(tr),
711                               src_address, src_stride, &sse, second_pred);
712         cost_array[idx] = thismse +
713             mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost, error_per_bit);
714
715         if (cost_array[idx] < besterr) {
716           best_idx = idx;
717           besterr = cost_array[idx];
718           *distortion = thismse;
719           *sse1 = sse;
720         }
721       } else {
722         cost_array[idx] = INT_MAX;
723       }
724     }
725
726     // Check diagonal sub-pixel position
727     kc = (cost_array[0] <= cost_array[1] ? -hstep : hstep);
728     kr = (cost_array[2] <= cost_array[3] ? -hstep : hstep);
729
730     tc = bc + kc;
731     tr = br + kr;
732     if (tc >= minc && tc <= maxc && tr >= minr && tr <= maxr) {
733       const uint8_t *const pre_address = y + (tr >> 3) * y_stride + (tc >> 3);
734       MV this_mv = {tr, tc};
735       if (second_pred == NULL)
736         thismse = vfp->svf(pre_address, y_stride, sp(tc), sp(tr),
737                            src_address, src_stride, &sse);
738       else
739         thismse = vfp->svaf(pre_address, y_stride, sp(tc), sp(tr),
740                             src_address, src_stride, &sse, second_pred);
741       cost_array[4] = thismse +
742           mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost, error_per_bit);
743
744       if (cost_array[4] < besterr) {
745         best_idx = 4;
746         besterr = cost_array[4];
747         *distortion = thismse;
748         *sse1 = sse;
749       }
750     } else {
751       cost_array[idx] = INT_MAX;
752     }
753
754     if (best_idx < 4 && best_idx >= 0) {
755       br += search_step[best_idx].row;
756       bc += search_step[best_idx].col;
757     } else if (best_idx == 4) {
758       br = tr;
759       bc = tc;
760     }
761
762     if (iters_per_step > 1 && best_idx != -1)
763       SECOND_LEVEL_CHECKS_BEST;
764
765     tr = br;
766     tc = bc;
767
768     search_step += 4;
769     hstep >>= 1;
770     best_idx = -1;
771   }
772
773   // Each subsequent iteration checks at least one point in common with
774   // the last iteration could be 2 ( if diag selected) 1/4 pel
775
776   // These lines insure static analysis doesn't warn that
777   // tr and tc aren't used after the above point.
778   (void) tr;
779   (void) tc;
780
781   bestmv->row = br;
782   bestmv->col = bc;
783
784   if ((abs(bestmv->col - ref_mv->col) > (MAX_FULL_PEL_VAL << 3)) ||
785       (abs(bestmv->row - ref_mv->row) > (MAX_FULL_PEL_VAL << 3)))
786     return INT_MAX;
787
788   return besterr;
789 }
790
791 #undef MVC
792 #undef PRE
793 #undef CHECK_BETTER
794
795 static INLINE int check_bounds(const MACROBLOCK *x, int row, int col,
796                                int range) {
797   return ((row - range) >= x->mv_row_min) &
798          ((row + range) <= x->mv_row_max) &
799          ((col - range) >= x->mv_col_min) &
800          ((col + range) <= x->mv_col_max);
801 }
802
803 static INLINE int is_mv_in(const MACROBLOCK *x, const MV *mv) {
804   return (mv->col >= x->mv_col_min) && (mv->col <= x->mv_col_max) &&
805          (mv->row >= x->mv_row_min) && (mv->row <= x->mv_row_max);
806 }
807
808 #define CHECK_BETTER \
809   {\
810     if (thissad < bestsad) {\
811       if (use_mvcost) \
812         thissad += mvsad_err_cost(x, &this_mv, &fcenter_mv, sad_per_bit);\
813       if (thissad < bestsad) {\
814         bestsad = thissad;\
815         best_site = i;\
816       }\
817     }\
818   }
819
820 #define MAX_PATTERN_SCALES         11
821 #define MAX_PATTERN_CANDIDATES      8  // max number of canddiates per scale
822 #define PATTERN_CANDIDATES_REF      3  // number of refinement candidates
823
824 // Calculate and return a sad+mvcost list around an integer best pel.
825 static INLINE void calc_int_cost_list(const MACROBLOCK *x,
826                                       const MV *ref_mv,
827                                       int sadpb,
828                                       const vp9_variance_fn_ptr_t *fn_ptr,
829                                       const MV *best_mv,
830                                       int *cost_list) {
831   static const MV neighbors[4] = {{0, -1}, {1, 0}, {0, 1}, {-1, 0}};
832   const struct buf_2d *const what = &x->plane[0].src;
833   const struct buf_2d *const in_what = &x->e_mbd.plane[0].pre[0];
834   const MV fcenter_mv = {ref_mv->row >> 3, ref_mv->col >> 3};
835   int br = best_mv->row;
836   int bc = best_mv->col;
837   MV this_mv;
838   int i;
839   unsigned int sse;
840
841   this_mv.row = br;
842   this_mv.col = bc;
843   cost_list[0] = fn_ptr->vf(what->buf, what->stride,
844                             get_buf_from_mv(in_what, &this_mv),
845                             in_what->stride, &sse) +
846       mvsad_err_cost(x, &this_mv, &fcenter_mv, sadpb);
847   if (check_bounds(x, br, bc, 1)) {
848     for (i = 0; i < 4; i++) {
849       const MV this_mv = {br + neighbors[i].row,
850         bc + neighbors[i].col};
851       cost_list[i + 1] = fn_ptr->vf(what->buf, what->stride,
852                                     get_buf_from_mv(in_what, &this_mv),
853                                     in_what->stride, &sse) +
854           // mvsad_err_cost(x, &this_mv, &fcenter_mv, sadpb);
855           mv_err_cost(&this_mv, &fcenter_mv, x->nmvjointcost, x->mvcost,
856                       x->errorperbit);
857     }
858   } else {
859     for (i = 0; i < 4; i++) {
860       const MV this_mv = {br + neighbors[i].row,
861         bc + neighbors[i].col};
862       if (!is_mv_in(x, &this_mv))
863         cost_list[i + 1] = INT_MAX;
864       else
865         cost_list[i + 1] = fn_ptr->vf(what->buf, what->stride,
866                                       get_buf_from_mv(in_what, &this_mv),
867                                       in_what->stride, &sse) +
868             // mvsad_err_cost(x, &this_mv, &fcenter_mv, sadpb);
869             mv_err_cost(&this_mv, &fcenter_mv, x->nmvjointcost, x->mvcost,
870                         x->errorperbit);
871     }
872   }
873 }
874
875 // Generic pattern search function that searches over multiple scales.
876 // Each scale can have a different number of candidates and shape of
877 // candidates as indicated in the num_candidates and candidates arrays
878 // passed into this function
879 //
880 static int vp10_pattern_search(const MACROBLOCK *x,
881                               MV *ref_mv,
882                               int search_param,
883                               int sad_per_bit,
884                               int do_init_search,
885                               int *cost_list,
886                               const vp9_variance_fn_ptr_t *vfp,
887                               int use_mvcost,
888                               const MV *center_mv,
889                               MV *best_mv,
890                               const int num_candidates[MAX_PATTERN_SCALES],
891                               const MV candidates[MAX_PATTERN_SCALES]
892                                                  [MAX_PATTERN_CANDIDATES]) {
893   const MACROBLOCKD *const xd = &x->e_mbd;
894   static const int search_param_to_steps[MAX_MVSEARCH_STEPS] = {
895     10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
896   };
897   int i, s, t;
898   const struct buf_2d *const what = &x->plane[0].src;
899   const struct buf_2d *const in_what = &xd->plane[0].pre[0];
900   int br, bc;
901   int bestsad = INT_MAX;
902   int thissad;
903   int k = -1;
904   const MV fcenter_mv = {center_mv->row >> 3, center_mv->col >> 3};
905   int best_init_s = search_param_to_steps[search_param];
906   // adjust ref_mv to make sure it is within MV range
907   clamp_mv(ref_mv, x->mv_col_min, x->mv_col_max, x->mv_row_min, x->mv_row_max);
908   br = ref_mv->row;
909   bc = ref_mv->col;
910
911   // Work out the start point for the search
912   bestsad = vfp->sdf(what->buf, what->stride,
913                      get_buf_from_mv(in_what, ref_mv), in_what->stride) +
914       mvsad_err_cost(x, ref_mv, &fcenter_mv, sad_per_bit);
915
916   // Search all possible scales upto the search param around the center point
917   // pick the scale of the point that is best as the starting scale of
918   // further steps around it.
919   if (do_init_search) {
920     s = best_init_s;
921     best_init_s = -1;
922     for (t = 0; t <= s; ++t) {
923       int best_site = -1;
924       if (check_bounds(x, br, bc, 1 << t)) {
925         for (i = 0; i < num_candidates[t]; i++) {
926           const MV this_mv = {br + candidates[t][i].row,
927                               bc + candidates[t][i].col};
928           thissad = vfp->sdf(what->buf, what->stride,
929                              get_buf_from_mv(in_what, &this_mv),
930                              in_what->stride);
931           CHECK_BETTER
932         }
933       } else {
934         for (i = 0; i < num_candidates[t]; i++) {
935           const MV this_mv = {br + candidates[t][i].row,
936                               bc + candidates[t][i].col};
937           if (!is_mv_in(x, &this_mv))
938             continue;
939           thissad = vfp->sdf(what->buf, what->stride,
940                              get_buf_from_mv(in_what, &this_mv),
941                              in_what->stride);
942           CHECK_BETTER
943         }
944       }
945       if (best_site == -1) {
946         continue;
947       } else {
948         best_init_s = t;
949         k = best_site;
950       }
951     }
952     if (best_init_s != -1) {
953       br += candidates[best_init_s][k].row;
954       bc += candidates[best_init_s][k].col;
955     }
956   }
957
958   // If the center point is still the best, just skip this and move to
959   // the refinement step.
960   if (best_init_s != -1) {
961     int best_site = -1;
962     s = best_init_s;
963
964     do {
965       // No need to search all 6 points the 1st time if initial search was used
966       if (!do_init_search || s != best_init_s) {
967         if (check_bounds(x, br, bc, 1 << s)) {
968           for (i = 0; i < num_candidates[s]; i++) {
969             const MV this_mv = {br + candidates[s][i].row,
970                                 bc + candidates[s][i].col};
971             thissad = vfp->sdf(what->buf, what->stride,
972                                get_buf_from_mv(in_what, &this_mv),
973                                in_what->stride);
974             CHECK_BETTER
975           }
976         } else {
977           for (i = 0; i < num_candidates[s]; i++) {
978             const MV this_mv = {br + candidates[s][i].row,
979                                 bc + candidates[s][i].col};
980             if (!is_mv_in(x, &this_mv))
981               continue;
982             thissad = vfp->sdf(what->buf, what->stride,
983                                get_buf_from_mv(in_what, &this_mv),
984                                in_what->stride);
985             CHECK_BETTER
986           }
987         }
988
989         if (best_site == -1) {
990           continue;
991         } else {
992           br += candidates[s][best_site].row;
993           bc += candidates[s][best_site].col;
994           k = best_site;
995         }
996       }
997
998       do {
999         int next_chkpts_indices[PATTERN_CANDIDATES_REF];
1000         best_site = -1;
1001         next_chkpts_indices[0] = (k == 0) ? num_candidates[s] - 1 : k - 1;
1002         next_chkpts_indices[1] = k;
1003         next_chkpts_indices[2] = (k == num_candidates[s] - 1) ? 0 : k + 1;
1004
1005         if (check_bounds(x, br, bc, 1 << s)) {
1006           for (i = 0; i < PATTERN_CANDIDATES_REF; i++) {
1007             const MV this_mv = {br + candidates[s][next_chkpts_indices[i]].row,
1008                                 bc + candidates[s][next_chkpts_indices[i]].col};
1009             thissad = vfp->sdf(what->buf, what->stride,
1010                                get_buf_from_mv(in_what, &this_mv),
1011                                in_what->stride);
1012             CHECK_BETTER
1013           }
1014         } else {
1015           for (i = 0; i < PATTERN_CANDIDATES_REF; i++) {
1016             const MV this_mv = {br + candidates[s][next_chkpts_indices[i]].row,
1017                                 bc + candidates[s][next_chkpts_indices[i]].col};
1018             if (!is_mv_in(x, &this_mv))
1019               continue;
1020             thissad = vfp->sdf(what->buf, what->stride,
1021                                get_buf_from_mv(in_what, &this_mv),
1022                                in_what->stride);
1023             CHECK_BETTER
1024           }
1025         }
1026
1027         if (best_site != -1) {
1028           k = next_chkpts_indices[best_site];
1029           br += candidates[s][k].row;
1030           bc += candidates[s][k].col;
1031         }
1032       } while (best_site != -1);
1033     } while (s--);
1034   }
1035
1036   // Returns the one-away integer pel sad values around the best as follows:
1037   // cost_list[0]: cost at the best integer pel
1038   // cost_list[1]: cost at delta {0, -1} (left)   from the best integer pel
1039   // cost_list[2]: cost at delta { 1, 0} (bottom) from the best integer pel
1040   // cost_list[3]: cost at delta { 0, 1} (right)  from the best integer pel
1041   // cost_list[4]: cost at delta {-1, 0} (top)    from the best integer pel
1042   if (cost_list) {
1043     const MV best_mv = { br, bc };
1044     calc_int_cost_list(x, &fcenter_mv, sad_per_bit, vfp, &best_mv, cost_list);
1045   }
1046   best_mv->row = br;
1047   best_mv->col = bc;
1048   return bestsad;
1049 }
1050
1051 // A specialized function where the smallest scale search candidates
1052 // are 4 1-away neighbors, and cost_list is non-null
1053 // TODO(debargha): Merge this function with the one above. Also remove
1054 // use_mvcost option since it is always 1, to save unnecessary branches.
1055 static int vp10_pattern_search_sad(const MACROBLOCK *x,
1056                                   MV *ref_mv,
1057                                   int search_param,
1058                                   int sad_per_bit,
1059                                   int do_init_search,
1060                                   int *cost_list,
1061                                   const vp9_variance_fn_ptr_t *vfp,
1062                                   int use_mvcost,
1063                                   const MV *center_mv,
1064                                   MV *best_mv,
1065                                   const int num_candidates[MAX_PATTERN_SCALES],
1066                                   const MV candidates[MAX_PATTERN_SCALES]
1067                                                      [MAX_PATTERN_CANDIDATES]) {
1068   const MACROBLOCKD *const xd = &x->e_mbd;
1069   static const int search_param_to_steps[MAX_MVSEARCH_STEPS] = {
1070     10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
1071   };
1072   int i, s, t;
1073   const struct buf_2d *const what = &x->plane[0].src;
1074   const struct buf_2d *const in_what = &xd->plane[0].pre[0];
1075   int br, bc;
1076   int bestsad = INT_MAX;
1077   int thissad;
1078   int k = -1;
1079   const MV fcenter_mv = {center_mv->row >> 3, center_mv->col >> 3};
1080   int best_init_s = search_param_to_steps[search_param];
1081   // adjust ref_mv to make sure it is within MV range
1082   clamp_mv(ref_mv, x->mv_col_min, x->mv_col_max, x->mv_row_min, x->mv_row_max);
1083   br = ref_mv->row;
1084   bc = ref_mv->col;
1085   if (cost_list != NULL) {
1086     cost_list[0] = cost_list[1] = cost_list[2] = cost_list[3] = cost_list[4] =
1087         INT_MAX;
1088   }
1089
1090   // Work out the start point for the search
1091   bestsad = vfp->sdf(what->buf, what->stride,
1092                      get_buf_from_mv(in_what, ref_mv), in_what->stride) +
1093       mvsad_err_cost(x, ref_mv, &fcenter_mv, sad_per_bit);
1094
1095   // Search all possible scales upto the search param around the center point
1096   // pick the scale of the point that is best as the starting scale of
1097   // further steps around it.
1098   if (do_init_search) {
1099     s = best_init_s;
1100     best_init_s = -1;
1101     for (t = 0; t <= s; ++t) {
1102       int best_site = -1;
1103       if (check_bounds(x, br, bc, 1 << t)) {
1104         for (i = 0; i < num_candidates[t]; i++) {
1105           const MV this_mv = {br + candidates[t][i].row,
1106                               bc + candidates[t][i].col};
1107           thissad = vfp->sdf(what->buf, what->stride,
1108                              get_buf_from_mv(in_what, &this_mv),
1109                              in_what->stride);
1110           CHECK_BETTER
1111         }
1112       } else {
1113         for (i = 0; i < num_candidates[t]; i++) {
1114           const MV this_mv = {br + candidates[t][i].row,
1115                               bc + candidates[t][i].col};
1116           if (!is_mv_in(x, &this_mv))
1117             continue;
1118           thissad = vfp->sdf(what->buf, what->stride,
1119                              get_buf_from_mv(in_what, &this_mv),
1120                              in_what->stride);
1121           CHECK_BETTER
1122         }
1123       }
1124       if (best_site == -1) {
1125         continue;
1126       } else {
1127         best_init_s = t;
1128         k = best_site;
1129       }
1130     }
1131     if (best_init_s != -1) {
1132       br += candidates[best_init_s][k].row;
1133       bc += candidates[best_init_s][k].col;
1134     }
1135   }
1136
1137   // If the center point is still the best, just skip this and move to
1138   // the refinement step.
1139   if (best_init_s != -1) {
1140     int do_sad = (num_candidates[0] == 4 && cost_list != NULL);
1141     int best_site = -1;
1142     s = best_init_s;
1143
1144     for (; s >= do_sad; s--) {
1145       if (!do_init_search || s != best_init_s) {
1146         if (check_bounds(x, br, bc, 1 << s)) {
1147           for (i = 0; i < num_candidates[s]; i++) {
1148             const MV this_mv = {br + candidates[s][i].row,
1149                                 bc + candidates[s][i].col};
1150             thissad = vfp->sdf(what->buf, what->stride,
1151                                get_buf_from_mv(in_what, &this_mv),
1152                                in_what->stride);
1153             CHECK_BETTER
1154           }
1155         } else {
1156           for (i = 0; i < num_candidates[s]; i++) {
1157             const MV this_mv = {br + candidates[s][i].row,
1158                                 bc + candidates[s][i].col};
1159             if (!is_mv_in(x, &this_mv))
1160               continue;
1161             thissad = vfp->sdf(what->buf, what->stride,
1162                                get_buf_from_mv(in_what, &this_mv),
1163                                in_what->stride);
1164             CHECK_BETTER
1165           }
1166         }
1167
1168         if (best_site == -1) {
1169           continue;
1170         } else {
1171           br += candidates[s][best_site].row;
1172           bc += candidates[s][best_site].col;
1173           k = best_site;
1174         }
1175       }
1176
1177       do {
1178         int next_chkpts_indices[PATTERN_CANDIDATES_REF];
1179         best_site = -1;
1180         next_chkpts_indices[0] = (k == 0) ? num_candidates[s] - 1 : k - 1;
1181         next_chkpts_indices[1] = k;
1182         next_chkpts_indices[2] = (k == num_candidates[s] - 1) ? 0 : k + 1;
1183
1184         if (check_bounds(x, br, bc, 1 << s)) {
1185           for (i = 0; i < PATTERN_CANDIDATES_REF; i++) {
1186             const MV this_mv = {br + candidates[s][next_chkpts_indices[i]].row,
1187                                 bc + candidates[s][next_chkpts_indices[i]].col};
1188             thissad = vfp->sdf(what->buf, what->stride,
1189                                get_buf_from_mv(in_what, &this_mv),
1190                                in_what->stride);
1191             CHECK_BETTER
1192           }
1193         } else {
1194           for (i = 0; i < PATTERN_CANDIDATES_REF; i++) {
1195             const MV this_mv = {br + candidates[s][next_chkpts_indices[i]].row,
1196                                 bc + candidates[s][next_chkpts_indices[i]].col};
1197             if (!is_mv_in(x, &this_mv))
1198               continue;
1199             thissad = vfp->sdf(what->buf, what->stride,
1200                                get_buf_from_mv(in_what, &this_mv),
1201                                in_what->stride);
1202             CHECK_BETTER
1203           }
1204         }
1205
1206         if (best_site != -1) {
1207           k = next_chkpts_indices[best_site];
1208           br += candidates[s][k].row;
1209           bc += candidates[s][k].col;
1210         }
1211       } while (best_site != -1);
1212     }
1213
1214     // Note: If we enter the if below, then cost_list must be non-NULL.
1215     if (s == 0) {
1216       cost_list[0] = bestsad;
1217       if (!do_init_search || s != best_init_s) {
1218         if (check_bounds(x, br, bc, 1 << s)) {
1219           for (i = 0; i < num_candidates[s]; i++) {
1220             const MV this_mv = {br + candidates[s][i].row,
1221                                 bc + candidates[s][i].col};
1222             cost_list[i + 1] =
1223             thissad = vfp->sdf(what->buf, what->stride,
1224                                get_buf_from_mv(in_what, &this_mv),
1225                                in_what->stride);
1226             CHECK_BETTER
1227           }
1228         } else {
1229           for (i = 0; i < num_candidates[s]; i++) {
1230             const MV this_mv = {br + candidates[s][i].row,
1231                                 bc + candidates[s][i].col};
1232             if (!is_mv_in(x, &this_mv))
1233               continue;
1234             cost_list[i + 1] =
1235             thissad = vfp->sdf(what->buf, what->stride,
1236                                get_buf_from_mv(in_what, &this_mv),
1237                                in_what->stride);
1238             CHECK_BETTER
1239           }
1240         }
1241
1242         if (best_site != -1) {
1243           br += candidates[s][best_site].row;
1244           bc += candidates[s][best_site].col;
1245           k = best_site;
1246         }
1247       }
1248       while (best_site != -1) {
1249         int next_chkpts_indices[PATTERN_CANDIDATES_REF];
1250         best_site = -1;
1251         next_chkpts_indices[0] = (k == 0) ? num_candidates[s] - 1 : k - 1;
1252         next_chkpts_indices[1] = k;
1253         next_chkpts_indices[2] = (k == num_candidates[s] - 1) ? 0 : k + 1;
1254         cost_list[1] = cost_list[2] = cost_list[3] = cost_list[4] = INT_MAX;
1255         cost_list[((k + 2) % 4) + 1] = cost_list[0];
1256         cost_list[0] = bestsad;
1257
1258         if (check_bounds(x, br, bc, 1 << s)) {
1259           for (i = 0; i < PATTERN_CANDIDATES_REF; i++) {
1260             const MV this_mv = {br + candidates[s][next_chkpts_indices[i]].row,
1261                                 bc + candidates[s][next_chkpts_indices[i]].col};
1262             cost_list[next_chkpts_indices[i] + 1] =
1263             thissad = vfp->sdf(what->buf, what->stride,
1264                                get_buf_from_mv(in_what, &this_mv),
1265                                in_what->stride);
1266             CHECK_BETTER
1267           }
1268         } else {
1269           for (i = 0; i < PATTERN_CANDIDATES_REF; i++) {
1270             const MV this_mv = {br + candidates[s][next_chkpts_indices[i]].row,
1271                                 bc + candidates[s][next_chkpts_indices[i]].col};
1272             if (!is_mv_in(x, &this_mv)) {
1273               cost_list[next_chkpts_indices[i] + 1] = INT_MAX;
1274               continue;
1275             }
1276             cost_list[next_chkpts_indices[i] + 1] =
1277             thissad = vfp->sdf(what->buf, what->stride,
1278                                get_buf_from_mv(in_what, &this_mv),
1279                                in_what->stride);
1280             CHECK_BETTER
1281           }
1282         }
1283
1284         if (best_site != -1) {
1285           k = next_chkpts_indices[best_site];
1286           br += candidates[s][k].row;
1287           bc += candidates[s][k].col;
1288         }
1289       }
1290     }
1291   }
1292
1293   // Returns the one-away integer pel sad values around the best as follows:
1294   // cost_list[0]: sad at the best integer pel
1295   // cost_list[1]: sad at delta {0, -1} (left)   from the best integer pel
1296   // cost_list[2]: sad at delta { 1, 0} (bottom) from the best integer pel
1297   // cost_list[3]: sad at delta { 0, 1} (right)  from the best integer pel
1298   // cost_list[4]: sad at delta {-1, 0} (top)    from the best integer pel
1299   if (cost_list) {
1300     static const MV neighbors[4] = {{0, -1}, {1, 0}, {0, 1}, {-1, 0}};
1301     if (cost_list[0] == INT_MAX) {
1302       cost_list[0] = bestsad;
1303       if (check_bounds(x, br, bc, 1)) {
1304         for (i = 0; i < 4; i++) {
1305           const MV this_mv = { br + neighbors[i].row,
1306                                bc + neighbors[i].col };
1307           cost_list[i + 1] = vfp->sdf(what->buf, what->stride,
1308                                      get_buf_from_mv(in_what, &this_mv),
1309                                      in_what->stride);
1310         }
1311       } else {
1312         for (i = 0; i < 4; i++) {
1313           const MV this_mv = {br + neighbors[i].row,
1314             bc + neighbors[i].col};
1315           if (!is_mv_in(x, &this_mv))
1316             cost_list[i + 1] = INT_MAX;
1317           else
1318             cost_list[i + 1] = vfp->sdf(what->buf, what->stride,
1319                                        get_buf_from_mv(in_what, &this_mv),
1320                                        in_what->stride);
1321         }
1322       }
1323     } else {
1324       if (use_mvcost) {
1325         for (i = 0; i < 4; i++) {
1326           const MV this_mv = {br + neighbors[i].row,
1327             bc + neighbors[i].col};
1328           if (cost_list[i + 1] != INT_MAX) {
1329             cost_list[i + 1] +=
1330                 mvsad_err_cost(x, &this_mv, &fcenter_mv, sad_per_bit);
1331           }
1332         }
1333       }
1334     }
1335   }
1336   best_mv->row = br;
1337   best_mv->col = bc;
1338   return bestsad;
1339 }
1340
1341 int vp10_get_mvpred_var(const MACROBLOCK *x,
1342                        const MV *best_mv, const MV *center_mv,
1343                        const vp9_variance_fn_ptr_t *vfp,
1344                        int use_mvcost) {
1345   const MACROBLOCKD *const xd = &x->e_mbd;
1346   const struct buf_2d *const what = &x->plane[0].src;
1347   const struct buf_2d *const in_what = &xd->plane[0].pre[0];
1348   const MV mv = {best_mv->row * 8, best_mv->col * 8};
1349   unsigned int unused;
1350
1351   return vfp->vf(what->buf, what->stride,
1352                  get_buf_from_mv(in_what, best_mv), in_what->stride, &unused) +
1353       (use_mvcost ?  mv_err_cost(&mv, center_mv, x->nmvjointcost,
1354                                  x->mvcost, x->errorperbit) : 0);
1355 }
1356
1357 int vp10_get_mvpred_av_var(const MACROBLOCK *x,
1358                           const MV *best_mv, const MV *center_mv,
1359                           const uint8_t *second_pred,
1360                           const vp9_variance_fn_ptr_t *vfp,
1361                           int use_mvcost) {
1362   const MACROBLOCKD *const xd = &x->e_mbd;
1363   const struct buf_2d *const what = &x->plane[0].src;
1364   const struct buf_2d *const in_what = &xd->plane[0].pre[0];
1365   const MV mv = {best_mv->row * 8, best_mv->col * 8};
1366   unsigned int unused;
1367
1368   return vfp->svaf(get_buf_from_mv(in_what, best_mv), in_what->stride, 0, 0,
1369                    what->buf, what->stride, &unused, second_pred) +
1370       (use_mvcost ?  mv_err_cost(&mv, center_mv, x->nmvjointcost,
1371                                  x->mvcost, x->errorperbit) : 0);
1372 }
1373
1374 int vp10_hex_search(const MACROBLOCK *x,
1375                    MV *ref_mv,
1376                    int search_param,
1377                    int sad_per_bit,
1378                    int do_init_search,
1379                    int *cost_list,
1380                    const vp9_variance_fn_ptr_t *vfp,
1381                    int use_mvcost,
1382                    const MV *center_mv, MV *best_mv) {
1383   // First scale has 8-closest points, the rest have 6 points in hex shape
1384   // at increasing scales
1385   static const int hex_num_candidates[MAX_PATTERN_SCALES] = {
1386     8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6
1387   };
1388   // Note that the largest candidate step at each scale is 2^scale
1389   static const MV hex_candidates[MAX_PATTERN_SCALES][MAX_PATTERN_CANDIDATES] = {
1390     {{-1, -1}, {0, -1}, {1, -1}, {1, 0}, {1, 1}, { 0, 1}, { -1, 1}, {-1, 0}},
1391     {{-1, -2}, {1, -2}, {2, 0}, {1, 2}, { -1, 2}, { -2, 0}},
1392     {{-2, -4}, {2, -4}, {4, 0}, {2, 4}, { -2, 4}, { -4, 0}},
1393     {{-4, -8}, {4, -8}, {8, 0}, {4, 8}, { -4, 8}, { -8, 0}},
1394     {{-8, -16}, {8, -16}, {16, 0}, {8, 16}, { -8, 16}, { -16, 0}},
1395     {{-16, -32}, {16, -32}, {32, 0}, {16, 32}, { -16, 32}, { -32, 0}},
1396     {{-32, -64}, {32, -64}, {64, 0}, {32, 64}, { -32, 64}, { -64, 0}},
1397     {{-64, -128}, {64, -128}, {128, 0}, {64, 128}, { -64, 128}, { -128, 0}},
1398     {{-128, -256}, {128, -256}, {256, 0}, {128, 256}, { -128, 256}, { -256, 0}},
1399     {{-256, -512}, {256, -512}, {512, 0}, {256, 512}, { -256, 512}, { -512, 0}},
1400     {{-512, -1024}, {512, -1024}, {1024, 0}, {512, 1024}, { -512, 1024},
1401       { -1024, 0}},
1402   };
1403   return vp10_pattern_search(x, ref_mv, search_param, sad_per_bit,
1404                             do_init_search, cost_list, vfp, use_mvcost,
1405                             center_mv, best_mv,
1406                             hex_num_candidates, hex_candidates);
1407 }
1408
1409 int vp10_bigdia_search(const MACROBLOCK *x,
1410                       MV *ref_mv,
1411                       int search_param,
1412                       int sad_per_bit,
1413                       int do_init_search,
1414                       int *cost_list,
1415                       const vp9_variance_fn_ptr_t *vfp,
1416                       int use_mvcost,
1417                       const MV *center_mv,
1418                       MV *best_mv) {
1419   // First scale has 4-closest points, the rest have 8 points in diamond
1420   // shape at increasing scales
1421   static const int bigdia_num_candidates[MAX_PATTERN_SCALES] = {
1422     4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
1423   };
1424   // Note that the largest candidate step at each scale is 2^scale
1425   static const MV bigdia_candidates[MAX_PATTERN_SCALES]
1426                                    [MAX_PATTERN_CANDIDATES] = {
1427     {{0, -1}, {1, 0}, { 0, 1}, {-1, 0}},
1428     {{-1, -1}, {0, -2}, {1, -1}, {2, 0}, {1, 1}, {0, 2}, {-1, 1}, {-2, 0}},
1429     {{-2, -2}, {0, -4}, {2, -2}, {4, 0}, {2, 2}, {0, 4}, {-2, 2}, {-4, 0}},
1430     {{-4, -4}, {0, -8}, {4, -4}, {8, 0}, {4, 4}, {0, 8}, {-4, 4}, {-8, 0}},
1431     {{-8, -8}, {0, -16}, {8, -8}, {16, 0}, {8, 8}, {0, 16}, {-8, 8}, {-16, 0}},
1432     {{-16, -16}, {0, -32}, {16, -16}, {32, 0}, {16, 16}, {0, 32},
1433       {-16, 16}, {-32, 0}},
1434     {{-32, -32}, {0, -64}, {32, -32}, {64, 0}, {32, 32}, {0, 64},
1435       {-32, 32}, {-64, 0}},
1436     {{-64, -64}, {0, -128}, {64, -64}, {128, 0}, {64, 64}, {0, 128},
1437       {-64, 64}, {-128, 0}},
1438     {{-128, -128}, {0, -256}, {128, -128}, {256, 0}, {128, 128}, {0, 256},
1439       {-128, 128}, {-256, 0}},
1440     {{-256, -256}, {0, -512}, {256, -256}, {512, 0}, {256, 256}, {0, 512},
1441       {-256, 256}, {-512, 0}},
1442     {{-512, -512}, {0, -1024}, {512, -512}, {1024, 0}, {512, 512}, {0, 1024},
1443       {-512, 512}, {-1024, 0}},
1444   };
1445   return vp10_pattern_search_sad(x, ref_mv, search_param, sad_per_bit,
1446                                 do_init_search, cost_list, vfp, use_mvcost,
1447                                 center_mv, best_mv,
1448                                 bigdia_num_candidates, bigdia_candidates);
1449 }
1450
1451 int vp10_square_search(const MACROBLOCK *x,
1452                       MV *ref_mv,
1453                       int search_param,
1454                       int sad_per_bit,
1455                       int do_init_search,
1456                       int *cost_list,
1457                       const vp9_variance_fn_ptr_t *vfp,
1458                       int use_mvcost,
1459                       const MV *center_mv,
1460                       MV *best_mv) {
1461   // All scales have 8 closest points in square shape
1462   static const int square_num_candidates[MAX_PATTERN_SCALES] = {
1463     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
1464   };
1465   // Note that the largest candidate step at each scale is 2^scale
1466   static const MV square_candidates[MAX_PATTERN_SCALES]
1467                                    [MAX_PATTERN_CANDIDATES] = {
1468     {{-1, -1}, {0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1}, {-1, 1}, {-1, 0}},
1469     {{-2, -2}, {0, -2}, {2, -2}, {2, 0}, {2, 2}, {0, 2}, {-2, 2}, {-2, 0}},
1470     {{-4, -4}, {0, -4}, {4, -4}, {4, 0}, {4, 4}, {0, 4}, {-4, 4}, {-4, 0}},
1471     {{-8, -8}, {0, -8}, {8, -8}, {8, 0}, {8, 8}, {0, 8}, {-8, 8}, {-8, 0}},
1472     {{-16, -16}, {0, -16}, {16, -16}, {16, 0}, {16, 16}, {0, 16},
1473       {-16, 16}, {-16, 0}},
1474     {{-32, -32}, {0, -32}, {32, -32}, {32, 0}, {32, 32}, {0, 32},
1475       {-32, 32}, {-32, 0}},
1476     {{-64, -64}, {0, -64}, {64, -64}, {64, 0}, {64, 64}, {0, 64},
1477       {-64, 64}, {-64, 0}},
1478     {{-128, -128}, {0, -128}, {128, -128}, {128, 0}, {128, 128}, {0, 128},
1479       {-128, 128}, {-128, 0}},
1480     {{-256, -256}, {0, -256}, {256, -256}, {256, 0}, {256, 256}, {0, 256},
1481       {-256, 256}, {-256, 0}},
1482     {{-512, -512}, {0, -512}, {512, -512}, {512, 0}, {512, 512}, {0, 512},
1483       {-512, 512}, {-512, 0}},
1484     {{-1024, -1024}, {0, -1024}, {1024, -1024}, {1024, 0}, {1024, 1024},
1485       {0, 1024}, {-1024, 1024}, {-1024, 0}},
1486   };
1487   return vp10_pattern_search(x, ref_mv, search_param, sad_per_bit,
1488                             do_init_search, cost_list, vfp, use_mvcost,
1489                             center_mv, best_mv,
1490                             square_num_candidates, square_candidates);
1491 }
1492
1493 int vp10_fast_hex_search(const MACROBLOCK *x,
1494                         MV *ref_mv,
1495                         int search_param,
1496                         int sad_per_bit,
1497                         int do_init_search,  // must be zero for fast_hex
1498                         int *cost_list,
1499                         const vp9_variance_fn_ptr_t *vfp,
1500                         int use_mvcost,
1501                         const MV *center_mv,
1502                         MV *best_mv) {
1503   return vp10_hex_search(x, ref_mv, MAX(MAX_MVSEARCH_STEPS - 2, search_param),
1504                         sad_per_bit, do_init_search, cost_list, vfp, use_mvcost,
1505                         center_mv, best_mv);
1506 }
1507
1508 int vp10_fast_dia_search(const MACROBLOCK *x,
1509                         MV *ref_mv,
1510                         int search_param,
1511                         int sad_per_bit,
1512                         int do_init_search,
1513                         int *cost_list,
1514                         const vp9_variance_fn_ptr_t *vfp,
1515                         int use_mvcost,
1516                         const MV *center_mv,
1517                         MV *best_mv) {
1518   return vp10_bigdia_search(x, ref_mv, MAX(MAX_MVSEARCH_STEPS - 2, search_param),
1519                            sad_per_bit, do_init_search, cost_list, vfp,
1520                            use_mvcost, center_mv, best_mv);
1521 }
1522
1523 #undef CHECK_BETTER
1524
1525 int vp10_full_range_search_c(const MACROBLOCK *x,
1526                             const search_site_config *cfg,
1527                             MV *ref_mv, MV *best_mv,
1528                             int search_param, int sad_per_bit, int *num00,
1529                             const vp9_variance_fn_ptr_t *fn_ptr,
1530                             const MV *center_mv) {
1531   const MACROBLOCKD *const xd = &x->e_mbd;
1532   const struct buf_2d *const what = &x->plane[0].src;
1533   const struct buf_2d *const in_what = &xd->plane[0].pre[0];
1534   const int range = 64;
1535   const MV fcenter_mv = {center_mv->row >> 3, center_mv->col >> 3};
1536   unsigned int best_sad = INT_MAX;
1537   int r, c, i;
1538   int start_col, end_col, start_row, end_row;
1539
1540   // The cfg and search_param parameters are not used in this search variant
1541   (void)cfg;
1542   (void)search_param;
1543
1544   clamp_mv(ref_mv, x->mv_col_min, x->mv_col_max, x->mv_row_min, x->mv_row_max);
1545   *best_mv = *ref_mv;
1546   *num00 = 11;
1547   best_sad = fn_ptr->sdf(what->buf, what->stride,
1548                          get_buf_from_mv(in_what, ref_mv), in_what->stride) +
1549                  mvsad_err_cost(x, ref_mv, &fcenter_mv, sad_per_bit);
1550   start_row = MAX(-range, x->mv_row_min - ref_mv->row);
1551   start_col = MAX(-range, x->mv_col_min - ref_mv->col);
1552   end_row = MIN(range, x->mv_row_max - ref_mv->row);
1553   end_col = MIN(range, x->mv_col_max - ref_mv->col);
1554
1555   for (r = start_row; r <= end_row; ++r) {
1556     for (c = start_col; c <= end_col; c += 4) {
1557       if (c + 3 <= end_col) {
1558         unsigned int sads[4];
1559         const uint8_t *addrs[4];
1560         for (i = 0; i < 4; ++i) {
1561           const MV mv = {ref_mv->row + r, ref_mv->col + c + i};
1562           addrs[i] = get_buf_from_mv(in_what, &mv);
1563         }
1564
1565         fn_ptr->sdx4df(what->buf, what->stride, addrs, in_what->stride, sads);
1566
1567         for (i = 0; i < 4; ++i) {
1568           if (sads[i] < best_sad) {
1569             const MV mv = {ref_mv->row + r, ref_mv->col + c + i};
1570             const unsigned int sad = sads[i] +
1571                 mvsad_err_cost(x, &mv, &fcenter_mv, sad_per_bit);
1572             if (sad < best_sad) {
1573               best_sad = sad;
1574               *best_mv = mv;
1575             }
1576           }
1577         }
1578       } else {
1579         for (i = 0; i < end_col - c; ++i) {
1580           const MV mv = {ref_mv->row + r, ref_mv->col + c + i};
1581           unsigned int sad = fn_ptr->sdf(what->buf, what->stride,
1582               get_buf_from_mv(in_what, &mv), in_what->stride);
1583           if (sad < best_sad) {
1584             sad += mvsad_err_cost(x, &mv, &fcenter_mv, sad_per_bit);
1585             if (sad < best_sad) {
1586               best_sad = sad;
1587               *best_mv = mv;
1588             }
1589           }
1590         }
1591       }
1592     }
1593   }
1594
1595   return best_sad;
1596 }
1597
1598 int vp10_diamond_search_sad_c(const MACROBLOCK *x,
1599                              const search_site_config *cfg,
1600                              MV *ref_mv, MV *best_mv, int search_param,
1601                              int sad_per_bit, int *num00,
1602                              const vp9_variance_fn_ptr_t *fn_ptr,
1603                              const MV *center_mv) {
1604   int i, j, step;
1605
1606   const MACROBLOCKD *const xd = &x->e_mbd;
1607   uint8_t *what = x->plane[0].src.buf;
1608   const int what_stride = x->plane[0].src.stride;
1609   const uint8_t *in_what;
1610   const int in_what_stride = xd->plane[0].pre[0].stride;
1611   const uint8_t *best_address;
1612
1613   unsigned int bestsad = INT_MAX;
1614   int best_site = 0;
1615   int last_site = 0;
1616
1617   int ref_row;
1618   int ref_col;
1619
1620   // search_param determines the length of the initial step and hence the number
1621   // of iterations.
1622   // 0 = initial step (MAX_FIRST_STEP) pel
1623   // 1 = (MAX_FIRST_STEP/2) pel,
1624   // 2 = (MAX_FIRST_STEP/4) pel...
1625   const search_site *ss = &cfg->ss[search_param * cfg->searches_per_step];
1626   const int tot_steps = (cfg->ss_count / cfg->searches_per_step) - search_param;
1627
1628   const MV fcenter_mv = {center_mv->row >> 3, center_mv->col >> 3};
1629   clamp_mv(ref_mv, x->mv_col_min, x->mv_col_max, x->mv_row_min, x->mv_row_max);
1630   ref_row = ref_mv->row;
1631   ref_col = ref_mv->col;
1632   *num00 = 0;
1633   best_mv->row = ref_row;
1634   best_mv->col = ref_col;
1635
1636   // Work out the start point for the search
1637   in_what = xd->plane[0].pre[0].buf + ref_row * in_what_stride + ref_col;
1638   best_address = in_what;
1639
1640   // Check the starting position
1641   bestsad = fn_ptr->sdf(what, what_stride, in_what, in_what_stride)
1642                 + mvsad_err_cost(x, best_mv, &fcenter_mv, sad_per_bit);
1643
1644   i = 1;
1645
1646   for (step = 0; step < tot_steps; step++) {
1647     int all_in = 1, t;
1648
1649     // All_in is true if every one of the points we are checking are within
1650     // the bounds of the image.
1651     all_in &= ((best_mv->row + ss[i].mv.row) > x->mv_row_min);
1652     all_in &= ((best_mv->row + ss[i + 1].mv.row) < x->mv_row_max);
1653     all_in &= ((best_mv->col + ss[i + 2].mv.col) > x->mv_col_min);
1654     all_in &= ((best_mv->col + ss[i + 3].mv.col) < x->mv_col_max);
1655
1656     // If all the pixels are within the bounds we don't check whether the
1657     // search point is valid in this loop,  otherwise we check each point
1658     // for validity..
1659     if (all_in) {
1660       unsigned int sad_array[4];
1661
1662       for (j = 0; j < cfg->searches_per_step; j += 4) {
1663         unsigned char const *block_offset[4];
1664
1665         for (t = 0; t < 4; t++)
1666           block_offset[t] = ss[i + t].offset + best_address;
1667
1668         fn_ptr->sdx4df(what, what_stride, block_offset, in_what_stride,
1669                        sad_array);
1670
1671         for (t = 0; t < 4; t++, i++) {
1672           if (sad_array[t] < bestsad) {
1673             const MV this_mv = {best_mv->row + ss[i].mv.row,
1674                                 best_mv->col + ss[i].mv.col};
1675             sad_array[t] += mvsad_err_cost(x, &this_mv, &fcenter_mv,
1676                                            sad_per_bit);
1677             if (sad_array[t] < bestsad) {
1678               bestsad = sad_array[t];
1679               best_site = i;
1680             }
1681           }
1682         }
1683       }
1684     } else {
1685       for (j = 0; j < cfg->searches_per_step; j++) {
1686         // Trap illegal vectors
1687         const MV this_mv = {best_mv->row + ss[i].mv.row,
1688                             best_mv->col + ss[i].mv.col};
1689
1690         if (is_mv_in(x, &this_mv)) {
1691           const uint8_t *const check_here = ss[i].offset + best_address;
1692           unsigned int thissad = fn_ptr->sdf(what, what_stride, check_here,
1693                                              in_what_stride);
1694
1695           if (thissad < bestsad) {
1696             thissad += mvsad_err_cost(x, &this_mv, &fcenter_mv, sad_per_bit);
1697             if (thissad < bestsad) {
1698               bestsad = thissad;
1699               best_site = i;
1700             }
1701           }
1702         }
1703         i++;
1704       }
1705     }
1706     if (best_site != last_site) {
1707       best_mv->row += ss[best_site].mv.row;
1708       best_mv->col += ss[best_site].mv.col;
1709       best_address += ss[best_site].offset;
1710       last_site = best_site;
1711 #if defined(NEW_DIAMOND_SEARCH)
1712       while (1) {
1713         const MV this_mv = {best_mv->row + ss[best_site].mv.row,
1714                             best_mv->col + ss[best_site].mv.col};
1715         if (is_mv_in(x, &this_mv)) {
1716           const uint8_t *const check_here = ss[best_site].offset + best_address;
1717           unsigned int thissad = fn_ptr->sdf(what, what_stride, check_here,
1718                                              in_what_stride);
1719           if (thissad < bestsad) {
1720             thissad += mvsad_err_cost(x, &this_mv, &fcenter_mv, sad_per_bit);
1721             if (thissad < bestsad) {
1722               bestsad = thissad;
1723               best_mv->row += ss[best_site].mv.row;
1724               best_mv->col += ss[best_site].mv.col;
1725               best_address += ss[best_site].offset;
1726               continue;
1727             }
1728           }
1729         }
1730         break;
1731       }
1732 #endif
1733     } else if (best_address == in_what) {
1734       (*num00)++;
1735     }
1736   }
1737   return bestsad;
1738 }
1739
1740 static int vector_match(int16_t *ref, int16_t *src, int bwl) {
1741   int best_sad = INT_MAX;
1742   int this_sad;
1743   int d;
1744   int center, offset = 0;
1745   int bw = 4 << bwl;  // redundant variable, to be changed in the experiments.
1746   for (d = 0; d <= bw; d += 16) {
1747     this_sad = vp10_vector_var(&ref[d], src, bwl);
1748     if (this_sad < best_sad) {
1749       best_sad = this_sad;
1750       offset = d;
1751     }
1752   }
1753   center = offset;
1754
1755   for (d = -8; d <= 8; d += 16) {
1756     int this_pos = offset + d;
1757     // check limit
1758     if (this_pos < 0 || this_pos > bw)
1759       continue;
1760     this_sad = vp10_vector_var(&ref[this_pos], src, bwl);
1761     if (this_sad < best_sad) {
1762       best_sad = this_sad;
1763       center = this_pos;
1764     }
1765   }
1766   offset = center;
1767
1768   for (d = -4; d <= 4; d += 8) {
1769     int this_pos = offset + d;
1770     // check limit
1771     if (this_pos < 0 || this_pos > bw)
1772       continue;
1773     this_sad = vp10_vector_var(&ref[this_pos], src, bwl);
1774     if (this_sad < best_sad) {
1775       best_sad = this_sad;
1776       center = this_pos;
1777     }
1778   }
1779   offset = center;
1780
1781   for (d = -2; d <= 2; d += 4) {
1782     int this_pos = offset + d;
1783     // check limit
1784     if (this_pos < 0 || this_pos > bw)
1785       continue;
1786     this_sad = vp10_vector_var(&ref[this_pos], src, bwl);
1787     if (this_sad < best_sad) {
1788       best_sad = this_sad;
1789       center = this_pos;
1790     }
1791   }
1792   offset = center;
1793
1794   for (d = -1; d <= 1; d += 2) {
1795     int this_pos = offset + d;
1796     // check limit
1797     if (this_pos < 0 || this_pos > bw)
1798       continue;
1799     this_sad = vp10_vector_var(&ref[this_pos], src, bwl);
1800     if (this_sad < best_sad) {
1801       best_sad = this_sad;
1802       center = this_pos;
1803     }
1804   }
1805
1806   return (center - (bw >> 1));
1807 }
1808
1809 static const MV search_pos[4] = {
1810     {-1, 0}, {0, -1}, {0, 1}, {1, 0},
1811 };
1812
1813 unsigned int vp10_int_pro_motion_estimation(const VP10_COMP *cpi, MACROBLOCK *x,
1814                                            BLOCK_SIZE bsize,
1815                                            int mi_row, int mi_col) {
1816   MACROBLOCKD *xd = &x->e_mbd;
1817   MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
1818   struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0, 0}};
1819   DECLARE_ALIGNED(16, int16_t, hbuf[128]);
1820   DECLARE_ALIGNED(16, int16_t, vbuf[128]);
1821   DECLARE_ALIGNED(16, int16_t, src_hbuf[64]);
1822   DECLARE_ALIGNED(16, int16_t, src_vbuf[64]);
1823   int idx;
1824   const int bw = 4 << b_width_log2_lookup[bsize];
1825   const int bh = 4 << b_height_log2_lookup[bsize];
1826   const int search_width = bw << 1;
1827   const int search_height = bh << 1;
1828   const int src_stride = x->plane[0].src.stride;
1829   const int ref_stride = xd->plane[0].pre[0].stride;
1830   uint8_t const *ref_buf, *src_buf;
1831   MV *tmp_mv = &xd->mi[0]->mbmi.mv[0].as_mv;
1832   unsigned int best_sad, tmp_sad, this_sad[4];
1833   MV this_mv;
1834   const int norm_factor = 3 + (bw >> 5);
1835   const YV12_BUFFER_CONFIG *scaled_ref_frame =
1836       vp10_get_scaled_ref_frame(cpi, mbmi->ref_frame[0]);
1837
1838   if (scaled_ref_frame) {
1839     int i;
1840     // Swap out the reference frame for a version that's been scaled to
1841     // match the resolution of the current frame, allowing the existing
1842     // motion search code to be used without additional modifications.
1843     for (i = 0; i < MAX_MB_PLANE; i++)
1844       backup_yv12[i] = xd->plane[i].pre[0];
1845     vp10_setup_pre_planes(xd, 0, scaled_ref_frame, mi_row, mi_col, NULL);
1846   }
1847
1848 #if CONFIG_VP9_HIGHBITDEPTH
1849   {
1850     unsigned int this_sad;
1851     tmp_mv->row = 0;
1852     tmp_mv->col = 0;
1853     this_sad = cpi->fn_ptr[bsize].sdf(x->plane[0].src.buf, src_stride,
1854                                       xd->plane[0].pre[0].buf, ref_stride);
1855
1856     if (scaled_ref_frame) {
1857       int i;
1858       for (i = 0; i < MAX_MB_PLANE; i++)
1859         xd->plane[i].pre[0] = backup_yv12[i];
1860     }
1861     return this_sad;
1862   }
1863 #endif
1864
1865   // Set up prediction 1-D reference set
1866   ref_buf = xd->plane[0].pre[0].buf - (bw >> 1);
1867   for (idx = 0; idx < search_width; idx += 16) {
1868     vp10_int_pro_row(&hbuf[idx], ref_buf, ref_stride, bh);
1869     ref_buf += 16;
1870   }
1871
1872   ref_buf = xd->plane[0].pre[0].buf - (bh >> 1) * ref_stride;
1873   for (idx = 0; idx < search_height; ++idx) {
1874     vbuf[idx] = vp10_int_pro_col(ref_buf, bw) >> norm_factor;
1875     ref_buf += ref_stride;
1876   }
1877
1878   // Set up src 1-D reference set
1879   for (idx = 0; idx < bw; idx += 16) {
1880     src_buf = x->plane[0].src.buf + idx;
1881     vp10_int_pro_row(&src_hbuf[idx], src_buf, src_stride, bh);
1882   }
1883
1884   src_buf = x->plane[0].src.buf;
1885   for (idx = 0; idx < bh; ++idx) {
1886     src_vbuf[idx] = vp10_int_pro_col(src_buf, bw) >> norm_factor;
1887     src_buf += src_stride;
1888   }
1889
1890   // Find the best match per 1-D search
1891   tmp_mv->col = vector_match(hbuf, src_hbuf, b_width_log2_lookup[bsize]);
1892   tmp_mv->row = vector_match(vbuf, src_vbuf, b_height_log2_lookup[bsize]);
1893
1894   this_mv = *tmp_mv;
1895   src_buf = x->plane[0].src.buf;
1896   ref_buf = xd->plane[0].pre[0].buf + this_mv.row * ref_stride + this_mv.col;
1897   best_sad = cpi->fn_ptr[bsize].sdf(src_buf, src_stride, ref_buf, ref_stride);
1898
1899   {
1900     const uint8_t * const pos[4] = {
1901         ref_buf - ref_stride,
1902         ref_buf - 1,
1903         ref_buf + 1,
1904         ref_buf + ref_stride,
1905     };
1906
1907     cpi->fn_ptr[bsize].sdx4df(src_buf, src_stride, pos, ref_stride, this_sad);
1908   }
1909
1910   for (idx = 0; idx < 4; ++idx) {
1911     if (this_sad[idx] < best_sad) {
1912       best_sad = this_sad[idx];
1913       tmp_mv->row = search_pos[idx].row + this_mv.row;
1914       tmp_mv->col = search_pos[idx].col + this_mv.col;
1915     }
1916   }
1917
1918   if (this_sad[0] < this_sad[3])
1919     this_mv.row -= 1;
1920   else
1921     this_mv.row += 1;
1922
1923   if (this_sad[1] < this_sad[2])
1924     this_mv.col -= 1;
1925   else
1926     this_mv.col += 1;
1927
1928   ref_buf = xd->plane[0].pre[0].buf + this_mv.row * ref_stride + this_mv.col;
1929
1930   tmp_sad = cpi->fn_ptr[bsize].sdf(src_buf, src_stride,
1931                                    ref_buf, ref_stride);
1932   if (best_sad > tmp_sad) {
1933     *tmp_mv = this_mv;
1934     best_sad = tmp_sad;
1935   }
1936
1937   tmp_mv->row *= 8;
1938   tmp_mv->col *= 8;
1939
1940   if (scaled_ref_frame) {
1941     int i;
1942     for (i = 0; i < MAX_MB_PLANE; i++)
1943       xd->plane[i].pre[0] = backup_yv12[i];
1944   }
1945
1946   return best_sad;
1947 }
1948
1949 /* do_refine: If last step (1-away) of n-step search doesn't pick the center
1950               point as the best match, we will do a final 1-away diamond
1951               refining search  */
1952 int vp10_full_pixel_diamond(const VP10_COMP *cpi, MACROBLOCK *x,
1953                            MV *mvp_full, int step_param,
1954                            int sadpb, int further_steps, int do_refine,
1955                            int *cost_list,
1956                            const vp9_variance_fn_ptr_t *fn_ptr,
1957                            const MV *ref_mv, MV *dst_mv) {
1958   MV temp_mv;
1959   int thissme, n, num00 = 0;
1960   int bestsme = cpi->diamond_search_sad(x, &cpi->ss_cfg, mvp_full, &temp_mv,
1961                                         step_param, sadpb, &n,
1962                                         fn_ptr, ref_mv);
1963   if (bestsme < INT_MAX)
1964     bestsme = vp10_get_mvpred_var(x, &temp_mv, ref_mv, fn_ptr, 1);
1965   *dst_mv = temp_mv;
1966
1967   // If there won't be more n-step search, check to see if refining search is
1968   // needed.
1969   if (n > further_steps)
1970     do_refine = 0;
1971
1972   while (n < further_steps) {
1973     ++n;
1974
1975     if (num00) {
1976       num00--;
1977     } else {
1978       thissme = cpi->diamond_search_sad(x, &cpi->ss_cfg, mvp_full, &temp_mv,
1979                                         step_param + n, sadpb, &num00,
1980                                         fn_ptr, ref_mv);
1981       if (thissme < INT_MAX)
1982         thissme = vp10_get_mvpred_var(x, &temp_mv, ref_mv, fn_ptr, 1);
1983
1984       // check to see if refining search is needed.
1985       if (num00 > further_steps - n)
1986         do_refine = 0;
1987
1988       if (thissme < bestsme) {
1989         bestsme = thissme;
1990         *dst_mv = temp_mv;
1991       }
1992     }
1993   }
1994
1995   // final 1-away diamond refining search
1996   if (do_refine) {
1997     const int search_range = 8;
1998     MV best_mv = *dst_mv;
1999     thissme = vp10_refining_search_sad(x, &best_mv, sadpb, search_range,
2000                                        fn_ptr, ref_mv);
2001     if (thissme < INT_MAX)
2002       thissme = vp10_get_mvpred_var(x, &best_mv, ref_mv, fn_ptr, 1);
2003     if (thissme < bestsme) {
2004       bestsme = thissme;
2005       *dst_mv = best_mv;
2006     }
2007   }
2008
2009   // Return cost list.
2010   if (cost_list) {
2011     calc_int_cost_list(x, ref_mv, sadpb, fn_ptr, dst_mv, cost_list);
2012   }
2013   return bestsme;
2014 }
2015
2016 int vp10_full_search_sad_c(const MACROBLOCK *x, const MV *ref_mv,
2017                           int sad_per_bit, int distance,
2018                           const vp9_variance_fn_ptr_t *fn_ptr,
2019                           const MV *center_mv, MV *best_mv) {
2020   int r, c;
2021   const MACROBLOCKD *const xd = &x->e_mbd;
2022   const struct buf_2d *const what = &x->plane[0].src;
2023   const struct buf_2d *const in_what = &xd->plane[0].pre[0];
2024   const int row_min = MAX(ref_mv->row - distance, x->mv_row_min);
2025   const int row_max = MIN(ref_mv->row + distance, x->mv_row_max);
2026   const int col_min = MAX(ref_mv->col - distance, x->mv_col_min);
2027   const int col_max = MIN(ref_mv->col + distance, x->mv_col_max);
2028   const MV fcenter_mv = {center_mv->row >> 3, center_mv->col >> 3};
2029   int best_sad = fn_ptr->sdf(what->buf, what->stride,
2030       get_buf_from_mv(in_what, ref_mv), in_what->stride) +
2031       mvsad_err_cost(x, ref_mv, &fcenter_mv, sad_per_bit);
2032   *best_mv = *ref_mv;
2033
2034   for (r = row_min; r < row_max; ++r) {
2035     for (c = col_min; c < col_max; ++c) {
2036       const MV mv = {r, c};
2037       const int sad = fn_ptr->sdf(what->buf, what->stride,
2038           get_buf_from_mv(in_what, &mv), in_what->stride) +
2039               mvsad_err_cost(x, &mv, &fcenter_mv, sad_per_bit);
2040       if (sad < best_sad) {
2041         best_sad = sad;
2042         *best_mv = mv;
2043       }
2044     }
2045   }
2046   return best_sad;
2047 }
2048
2049 int vp10_full_search_sadx3(const MACROBLOCK *x, const MV *ref_mv,
2050                           int sad_per_bit, int distance,
2051                           const vp9_variance_fn_ptr_t *fn_ptr,
2052                           const MV *center_mv, MV *best_mv) {
2053   int r;
2054   const MACROBLOCKD *const xd = &x->e_mbd;
2055   const struct buf_2d *const what = &x->plane[0].src;
2056   const struct buf_2d *const in_what = &xd->plane[0].pre[0];
2057   const int row_min = MAX(ref_mv->row - distance, x->mv_row_min);
2058   const int row_max = MIN(ref_mv->row + distance, x->mv_row_max);
2059   const int col_min = MAX(ref_mv->col - distance, x->mv_col_min);
2060   const int col_max = MIN(ref_mv->col + distance, x->mv_col_max);
2061   const MV fcenter_mv = {center_mv->row >> 3, center_mv->col >> 3};
2062   unsigned int best_sad = fn_ptr->sdf(what->buf, what->stride,
2063       get_buf_from_mv(in_what, ref_mv), in_what->stride) +
2064       mvsad_err_cost(x, ref_mv, &fcenter_mv, sad_per_bit);
2065   *best_mv = *ref_mv;
2066
2067   for (r = row_min; r < row_max; ++r) {
2068     int c = col_min;
2069     const uint8_t *check_here = &in_what->buf[r * in_what->stride + c];
2070
2071     if (fn_ptr->sdx3f != NULL) {
2072       while ((c + 2) < col_max) {
2073         int i;
2074         DECLARE_ALIGNED(16, uint32_t, sads[3]);
2075
2076         fn_ptr->sdx3f(what->buf, what->stride, check_here, in_what->stride,
2077                       sads);
2078
2079         for (i = 0; i < 3; ++i) {
2080           unsigned int sad = sads[i];
2081           if (sad < best_sad) {
2082             const MV mv = {r, c};
2083             sad += mvsad_err_cost(x, &mv, &fcenter_mv, sad_per_bit);
2084             if (sad < best_sad) {
2085               best_sad = sad;
2086               *best_mv = mv;
2087             }
2088           }
2089           ++check_here;
2090           ++c;
2091         }
2092       }
2093     }
2094
2095     while (c < col_max) {
2096       unsigned int sad = fn_ptr->sdf(what->buf, what->stride,
2097                                      check_here, in_what->stride);
2098       if (sad < best_sad) {
2099         const MV mv = {r, c};
2100         sad += mvsad_err_cost(x, &mv, &fcenter_mv, sad_per_bit);
2101         if (sad < best_sad) {
2102           best_sad = sad;
2103           *best_mv = mv;
2104         }
2105       }
2106       ++check_here;
2107       ++c;
2108     }
2109   }
2110
2111   return best_sad;
2112 }
2113
2114 int vp10_full_search_sadx8(const MACROBLOCK *x, const MV *ref_mv,
2115                           int sad_per_bit, int distance,
2116                           const vp9_variance_fn_ptr_t *fn_ptr,
2117                           const MV *center_mv, MV *best_mv) {
2118   int r;
2119   const MACROBLOCKD *const xd = &x->e_mbd;
2120   const struct buf_2d *const what = &x->plane[0].src;
2121   const struct buf_2d *const in_what = &xd->plane[0].pre[0];
2122   const int row_min = MAX(ref_mv->row - distance, x->mv_row_min);
2123   const int row_max = MIN(ref_mv->row + distance, x->mv_row_max);
2124   const int col_min = MAX(ref_mv->col - distance, x->mv_col_min);
2125   const int col_max = MIN(ref_mv->col + distance, x->mv_col_max);
2126   const MV fcenter_mv = {center_mv->row >> 3, center_mv->col >> 3};
2127   unsigned int best_sad = fn_ptr->sdf(what->buf, what->stride,
2128       get_buf_from_mv(in_what, ref_mv), in_what->stride) +
2129       mvsad_err_cost(x, ref_mv, &fcenter_mv, sad_per_bit);
2130   *best_mv = *ref_mv;
2131
2132   for (r = row_min; r < row_max; ++r) {
2133     int c = col_min;
2134     const uint8_t *check_here = &in_what->buf[r * in_what->stride + c];
2135
2136     if (fn_ptr->sdx8f != NULL) {
2137       while ((c + 7) < col_max) {
2138         int i;
2139         DECLARE_ALIGNED(16, uint32_t, sads[8]);
2140
2141         fn_ptr->sdx8f(what->buf, what->stride, check_here, in_what->stride,
2142                       sads);
2143
2144         for (i = 0; i < 8; ++i) {
2145           unsigned int sad = sads[i];
2146           if (sad < best_sad) {
2147             const MV mv = {r, c};
2148             sad += mvsad_err_cost(x, &mv, &fcenter_mv, sad_per_bit);
2149             if (sad < best_sad) {
2150               best_sad = sad;
2151               *best_mv = mv;
2152             }
2153           }
2154           ++check_here;
2155           ++c;
2156         }
2157       }
2158     }
2159
2160     if (fn_ptr->sdx3f != NULL) {
2161       while ((c + 2) < col_max) {
2162         int i;
2163         DECLARE_ALIGNED(16, uint32_t, sads[3]);
2164
2165         fn_ptr->sdx3f(what->buf, what->stride, check_here, in_what->stride,
2166                       sads);
2167
2168         for (i = 0; i < 3; ++i) {
2169           unsigned int sad = sads[i];
2170           if (sad < best_sad) {
2171             const MV mv = {r, c};
2172             sad += mvsad_err_cost(x, &mv, &fcenter_mv, sad_per_bit);
2173             if (sad < best_sad) {
2174               best_sad = sad;
2175               *best_mv = mv;
2176             }
2177           }
2178           ++check_here;
2179           ++c;
2180         }
2181       }
2182     }
2183
2184     while (c < col_max) {
2185       unsigned int sad = fn_ptr->sdf(what->buf, what->stride,
2186                                      check_here, in_what->stride);
2187       if (sad < best_sad) {
2188         const MV mv = {r, c};
2189         sad += mvsad_err_cost(x, &mv, &fcenter_mv, sad_per_bit);
2190         if (sad < best_sad) {
2191           best_sad = sad;
2192           *best_mv = mv;
2193         }
2194       }
2195       ++check_here;
2196       ++c;
2197     }
2198   }
2199
2200   return best_sad;
2201 }
2202
2203 int vp10_refining_search_sad(const MACROBLOCK *x,
2204                             MV *ref_mv, int error_per_bit,
2205                             int search_range,
2206                             const vp9_variance_fn_ptr_t *fn_ptr,
2207                             const MV *center_mv) {
2208   const MACROBLOCKD *const xd = &x->e_mbd;
2209   const MV neighbors[4] = {{ -1, 0}, {0, -1}, {0, 1}, {1, 0}};
2210   const struct buf_2d *const what = &x->plane[0].src;
2211   const struct buf_2d *const in_what = &xd->plane[0].pre[0];
2212   const MV fcenter_mv = {center_mv->row >> 3, center_mv->col >> 3};
2213   const uint8_t *best_address = get_buf_from_mv(in_what, ref_mv);
2214   unsigned int best_sad = fn_ptr->sdf(what->buf, what->stride, best_address,
2215                                     in_what->stride) +
2216       mvsad_err_cost(x, ref_mv, &fcenter_mv, error_per_bit);
2217   int i, j;
2218
2219   for (i = 0; i < search_range; i++) {
2220     int best_site = -1;
2221     const int all_in = ((ref_mv->row - 1) > x->mv_row_min) &
2222                        ((ref_mv->row + 1) < x->mv_row_max) &
2223                        ((ref_mv->col - 1) > x->mv_col_min) &
2224                        ((ref_mv->col + 1) < x->mv_col_max);
2225
2226     if (all_in) {
2227       unsigned int sads[4];
2228       const uint8_t *const positions[4] = {
2229         best_address - in_what->stride,
2230         best_address - 1,
2231         best_address + 1,
2232         best_address + in_what->stride
2233       };
2234
2235       fn_ptr->sdx4df(what->buf, what->stride, positions, in_what->stride, sads);
2236
2237       for (j = 0; j < 4; ++j) {
2238         if (sads[j] < best_sad) {
2239           const MV mv = {ref_mv->row + neighbors[j].row,
2240                          ref_mv->col + neighbors[j].col};
2241           sads[j] += mvsad_err_cost(x, &mv, &fcenter_mv, error_per_bit);
2242           if (sads[j] < best_sad) {
2243             best_sad = sads[j];
2244             best_site = j;
2245           }
2246         }
2247       }
2248     } else {
2249       for (j = 0; j < 4; ++j) {
2250         const MV mv = {ref_mv->row + neighbors[j].row,
2251                        ref_mv->col + neighbors[j].col};
2252
2253         if (is_mv_in(x, &mv)) {
2254           unsigned int sad = fn_ptr->sdf(what->buf, what->stride,
2255                                          get_buf_from_mv(in_what, &mv),
2256                                          in_what->stride);
2257           if (sad < best_sad) {
2258             sad += mvsad_err_cost(x, &mv, &fcenter_mv, error_per_bit);
2259             if (sad < best_sad) {
2260               best_sad = sad;
2261               best_site = j;
2262             }
2263           }
2264         }
2265       }
2266     }
2267
2268     if (best_site == -1) {
2269       break;
2270     } else {
2271       ref_mv->row += neighbors[best_site].row;
2272       ref_mv->col += neighbors[best_site].col;
2273       best_address = get_buf_from_mv(in_what, ref_mv);
2274     }
2275   }
2276
2277   return best_sad;
2278 }
2279
2280 // This function is called when we do joint motion search in comp_inter_inter
2281 // mode.
2282 int vp10_refining_search_8p_c(const MACROBLOCK *x,
2283                              MV *ref_mv, int error_per_bit,
2284                              int search_range,
2285                              const vp9_variance_fn_ptr_t *fn_ptr,
2286                              const MV *center_mv,
2287                              const uint8_t *second_pred) {
2288   const MV neighbors[8] = {{-1, 0}, {0, -1}, {0, 1}, {1, 0},
2289                            {-1, -1}, {1, -1}, {-1, 1}, {1, 1}};
2290   const MACROBLOCKD *const xd = &x->e_mbd;
2291   const struct buf_2d *const what = &x->plane[0].src;
2292   const struct buf_2d *const in_what = &xd->plane[0].pre[0];
2293   const MV fcenter_mv = {center_mv->row >> 3, center_mv->col >> 3};
2294   unsigned int best_sad = fn_ptr->sdaf(what->buf, what->stride,
2295       get_buf_from_mv(in_what, ref_mv), in_what->stride, second_pred) +
2296       mvsad_err_cost(x, ref_mv, &fcenter_mv, error_per_bit);
2297   int i, j;
2298
2299   for (i = 0; i < search_range; ++i) {
2300     int best_site = -1;
2301
2302     for (j = 0; j < 8; ++j) {
2303       const MV mv = {ref_mv->row + neighbors[j].row,
2304                      ref_mv->col + neighbors[j].col};
2305
2306       if (is_mv_in(x, &mv)) {
2307         unsigned int sad = fn_ptr->sdaf(what->buf, what->stride,
2308             get_buf_from_mv(in_what, &mv), in_what->stride, second_pred);
2309         if (sad < best_sad) {
2310           sad += mvsad_err_cost(x, &mv, &fcenter_mv, error_per_bit);
2311           if (sad < best_sad) {
2312             best_sad = sad;
2313             best_site = j;
2314           }
2315         }
2316       }
2317     }
2318
2319     if (best_site == -1) {
2320       break;
2321     } else {
2322       ref_mv->row += neighbors[best_site].row;
2323       ref_mv->col += neighbors[best_site].col;
2324     }
2325   }
2326   return best_sad;
2327 }
2328
2329 int vp10_full_pixel_search(VP10_COMP *cpi, MACROBLOCK *x,
2330                           BLOCK_SIZE bsize, MV *mvp_full,
2331                           int step_param, int error_per_bit,
2332                           int *cost_list,
2333                           const MV *ref_mv, MV *tmp_mv,
2334                           int var_max, int rd) {
2335   const SPEED_FEATURES *const sf = &cpi->sf;
2336   const SEARCH_METHODS method = sf->mv.search_method;
2337   vp9_variance_fn_ptr_t *fn_ptr = &cpi->fn_ptr[bsize];
2338   int var = 0;
2339   if (cost_list) {
2340     cost_list[0] = INT_MAX;
2341     cost_list[1] = INT_MAX;
2342     cost_list[2] = INT_MAX;
2343     cost_list[3] = INT_MAX;
2344     cost_list[4] = INT_MAX;
2345   }
2346
2347   switch (method) {
2348     case FAST_DIAMOND:
2349       var = vp10_fast_dia_search(x, mvp_full, step_param, error_per_bit, 0,
2350                                 cost_list, fn_ptr, 1, ref_mv, tmp_mv);
2351       break;
2352     case FAST_HEX:
2353       var = vp10_fast_hex_search(x, mvp_full, step_param, error_per_bit, 0,
2354                                 cost_list, fn_ptr, 1, ref_mv, tmp_mv);
2355       break;
2356     case HEX:
2357       var = vp10_hex_search(x, mvp_full, step_param, error_per_bit, 1,
2358                            cost_list, fn_ptr, 1, ref_mv, tmp_mv);
2359       break;
2360     case SQUARE:
2361       var = vp10_square_search(x, mvp_full, step_param, error_per_bit, 1,
2362                               cost_list, fn_ptr, 1, ref_mv, tmp_mv);
2363       break;
2364     case BIGDIA:
2365       var = vp10_bigdia_search(x, mvp_full, step_param, error_per_bit, 1,
2366                               cost_list, fn_ptr, 1, ref_mv, tmp_mv);
2367       break;
2368     case NSTEP:
2369       var = vp10_full_pixel_diamond(cpi, x, mvp_full, step_param, error_per_bit,
2370                                    MAX_MVSEARCH_STEPS - 1 - step_param,
2371                                    1, cost_list, fn_ptr, ref_mv, tmp_mv);
2372       break;
2373     default:
2374       assert(0 && "Invalid search method.");
2375   }
2376
2377   if (method != NSTEP && rd && var < var_max)
2378     var = vp10_get_mvpred_var(x, tmp_mv, ref_mv, fn_ptr, 1);
2379
2380   return var;
2381 }