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