xref: /aosp_15_r20/external/libavc/encoder/svc/isvce_me.c (revision 495ae853bb871d1e5a258cb02c2cc13cde8ddb9a)
1*495ae853SAndroid Build Coastguard Worker /******************************************************************************
2*495ae853SAndroid Build Coastguard Worker  *
3*495ae853SAndroid Build Coastguard Worker  * Copyright (C) 2022 The Android Open Source Project
4*495ae853SAndroid Build Coastguard Worker  *
5*495ae853SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
6*495ae853SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
7*495ae853SAndroid Build Coastguard Worker  * You may obtain a copy of the License at:
8*495ae853SAndroid Build Coastguard Worker  *
9*495ae853SAndroid Build Coastguard Worker  * http://www.apache.org/licenses/LICENSE-2.0
10*495ae853SAndroid Build Coastguard Worker  *
11*495ae853SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
12*495ae853SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
13*495ae853SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*495ae853SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
15*495ae853SAndroid Build Coastguard Worker  * limitations under the License.
16*495ae853SAndroid Build Coastguard Worker  *
17*495ae853SAndroid Build Coastguard Worker  *****************************************************************************
18*495ae853SAndroid Build Coastguard Worker  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19*495ae853SAndroid Build Coastguard Worker  */
20*495ae853SAndroid Build Coastguard Worker 
21*495ae853SAndroid Build Coastguard Worker /**
22*495ae853SAndroid Build Coastguard Worker  *******************************************************************************
23*495ae853SAndroid Build Coastguard Worker  * @file
24*495ae853SAndroid Build Coastguard Worker  *  isvce_me.c
25*495ae853SAndroid Build Coastguard Worker  *
26*495ae853SAndroid Build Coastguard Worker  * @brief
27*495ae853SAndroid Build Coastguard Worker  *  Contains definition of functions for motion estimation
28*495ae853SAndroid Build Coastguard Worker  *
29*495ae853SAndroid Build Coastguard Worker  * @author
30*495ae853SAndroid Build Coastguard Worker  *  ittiam
31*495ae853SAndroid Build Coastguard Worker  *
32*495ae853SAndroid Build Coastguard Worker  * @par List of Functions:
33*495ae853SAndroid Build Coastguard Worker  *  - isvce_init_mv_bits()
34*495ae853SAndroid Build Coastguard Worker  *  - isvce_skip_analysis_chroma()
35*495ae853SAndroid Build Coastguard Worker  *  - isvce_skip_analysis_luma()
36*495ae853SAndroid Build Coastguard Worker  *  - isvce_analyse_skip()
37*495ae853SAndroid Build Coastguard Worker  *  - isvce_get_search_candidates()
38*495ae853SAndroid Build Coastguard Worker  *  - isvce_find_skip_motion_vector()
39*495ae853SAndroid Build Coastguard Worker  *  - isvce_get_mv_predictor()
40*495ae853SAndroid Build Coastguard Worker  *  - isvce_mv_pred()
41*495ae853SAndroid Build Coastguard Worker  *  - isvce_mv_pred_me()
42*495ae853SAndroid Build Coastguard Worker  *  - isvce_init_me()
43*495ae853SAndroid Build Coastguard Worker  *  - isvce_compute_me()
44*495ae853SAndroid Build Coastguard Worker  *  - isvce_compute_me_nmb()
45*495ae853SAndroid Build Coastguard Worker  *
46*495ae853SAndroid Build Coastguard Worker  * @remarks
47*495ae853SAndroid Build Coastguard Worker  *  None
48*495ae853SAndroid Build Coastguard Worker  *
49*495ae853SAndroid Build Coastguard Worker  *******************************************************************************
50*495ae853SAndroid Build Coastguard Worker  */
51*495ae853SAndroid Build Coastguard Worker 
52*495ae853SAndroid Build Coastguard Worker /*****************************************************************************/
53*495ae853SAndroid Build Coastguard Worker /* File Includes                                                             */
54*495ae853SAndroid Build Coastguard Worker /*****************************************************************************/
55*495ae853SAndroid Build Coastguard Worker 
56*495ae853SAndroid Build Coastguard Worker /* System include files */
57*495ae853SAndroid Build Coastguard Worker #include <stdio.h>
58*495ae853SAndroid Build Coastguard Worker #include <assert.h>
59*495ae853SAndroid Build Coastguard Worker #include <limits.h>
60*495ae853SAndroid Build Coastguard Worker #include <stdbool.h>
61*495ae853SAndroid Build Coastguard Worker 
62*495ae853SAndroid Build Coastguard Worker /* User include files */
63*495ae853SAndroid Build Coastguard Worker #include "ih264_typedefs.h"
64*495ae853SAndroid Build Coastguard Worker #include "ih264_macros.h"
65*495ae853SAndroid Build Coastguard Worker #include "isvc_macros.h"
66*495ae853SAndroid Build Coastguard Worker #include "ih264_platform_macros.h"
67*495ae853SAndroid Build Coastguard Worker #include "iv2.h"
68*495ae853SAndroid Build Coastguard Worker #include "ive2.h"
69*495ae853SAndroid Build Coastguard Worker #include "ithread.h"
70*495ae853SAndroid Build Coastguard Worker #include "ih264_platform_macros.h"
71*495ae853SAndroid Build Coastguard Worker #include "isvc_defs.h"
72*495ae853SAndroid Build Coastguard Worker #include "ime_defs.h"
73*495ae853SAndroid Build Coastguard Worker #include "ime_distortion_metrics.h"
74*495ae853SAndroid Build Coastguard Worker #include "ime_structs.h"
75*495ae853SAndroid Build Coastguard Worker #include "isvc_structs.h"
76*495ae853SAndroid Build Coastguard Worker #include "isvc_trans_quant_itrans_iquant.h"
77*495ae853SAndroid Build Coastguard Worker #include "isvc_inter_pred_filters.h"
78*495ae853SAndroid Build Coastguard Worker #include "isvc_mem_fns.h"
79*495ae853SAndroid Build Coastguard Worker #include "ih264_padding.h"
80*495ae853SAndroid Build Coastguard Worker #include "ih264_intra_pred_filters.h"
81*495ae853SAndroid Build Coastguard Worker #include "ih264_deblk_edge_filters.h"
82*495ae853SAndroid Build Coastguard Worker #include "isvc_cabac_tables.h"
83*495ae853SAndroid Build Coastguard Worker #include "isvce_defs.h"
84*495ae853SAndroid Build Coastguard Worker #include "ih264e_error.h"
85*495ae853SAndroid Build Coastguard Worker #include "ih264e_bitstream.h"
86*495ae853SAndroid Build Coastguard Worker #include "irc_cntrl_param.h"
87*495ae853SAndroid Build Coastguard Worker #include "irc_frame_info_collector.h"
88*495ae853SAndroid Build Coastguard Worker #include "isvce_rate_control.h"
89*495ae853SAndroid Build Coastguard Worker #include "isvce_cabac_structs.h"
90*495ae853SAndroid Build Coastguard Worker #include "isvce_structs.h"
91*495ae853SAndroid Build Coastguard Worker #include "isvce_globals.h"
92*495ae853SAndroid Build Coastguard Worker #include "isvce_me.h"
93*495ae853SAndroid Build Coastguard Worker #include "ime.h"
94*495ae853SAndroid Build Coastguard Worker #include "ih264_debug.h"
95*495ae853SAndroid Build Coastguard Worker #include "ih264e_intra_modes_eval.h"
96*495ae853SAndroid Build Coastguard Worker #include "isvce_core_coding.h"
97*495ae853SAndroid Build Coastguard Worker #include "isvce_mc.h"
98*495ae853SAndroid Build Coastguard Worker #include "ih264e_debug.h"
99*495ae853SAndroid Build Coastguard Worker #include "ih264e_half_pel.h"
100*495ae853SAndroid Build Coastguard Worker #include "ime_statistics.h"
101*495ae853SAndroid Build Coastguard Worker #include "ih264e_platform_macros.h"
102*495ae853SAndroid Build Coastguard Worker #include "isvce_defs.h"
103*495ae853SAndroid Build Coastguard Worker #include "isvce_structs.h"
104*495ae853SAndroid Build Coastguard Worker #include "isvce_ilp_mv_utils.h"
105*495ae853SAndroid Build Coastguard Worker #include "isvce_utils.h"
106*495ae853SAndroid Build Coastguard Worker 
107*495ae853SAndroid Build Coastguard Worker /*****************************************************************************/
108*495ae853SAndroid Build Coastguard Worker /* Function Definitions                                                      */
109*495ae853SAndroid Build Coastguard Worker /*****************************************************************************/
110*495ae853SAndroid Build Coastguard Worker 
111*495ae853SAndroid Build Coastguard Worker /**
112*495ae853SAndroid Build Coastguard Worker *******************************************************************************
113*495ae853SAndroid Build Coastguard Worker *
114*495ae853SAndroid Build Coastguard Worker * @brief Diamond Search
115*495ae853SAndroid Build Coastguard Worker *
116*495ae853SAndroid Build Coastguard Worker * @par Description:
117*495ae853SAndroid Build Coastguard Worker *  This function computes the sad at vertices of several layers of diamond grid
118*495ae853SAndroid Build Coastguard Worker *  at a time. The number of layers of diamond grid that would be evaluated is
119*495ae853SAndroid Build Coastguard Worker *  configurable.The function computes the sad at vertices of a diamond grid. If
120*495ae853SAndroid Build Coastguard Worker *  the sad at the center of the diamond grid is lesser than the sad at any other
121*495ae853SAndroid Build Coastguard Worker *  point of the diamond grid, the function marks the candidate Mb partition as
122*495ae853SAndroid Build Coastguard Worker *  mv.
123*495ae853SAndroid Build Coastguard Worker *
124*495ae853SAndroid Build Coastguard Worker * @param[in] ps_mb_part
125*495ae853SAndroid Build Coastguard Worker *  pointer to current mb partition ctxt with respect to ME
126*495ae853SAndroid Build Coastguard Worker *
127*495ae853SAndroid Build Coastguard Worker * @param[in] ps_me_ctxt
128*495ae853SAndroid Build Coastguard Worker *  pointer to me context
129*495ae853SAndroid Build Coastguard Worker *
130*495ae853SAndroid Build Coastguard Worker * @param[in] u4_lambda_motion
131*495ae853SAndroid Build Coastguard Worker *  lambda motion
132*495ae853SAndroid Build Coastguard Worker *
133*495ae853SAndroid Build Coastguard Worker * @param[in] u4_enable_fast_sad
134*495ae853SAndroid Build Coastguard Worker *  enable/disable fast sad computation
135*495ae853SAndroid Build Coastguard Worker *
136*495ae853SAndroid Build Coastguard Worker * @returns  mv pair & corresponding distortion and cost
137*495ae853SAndroid Build Coastguard Worker *
138*495ae853SAndroid Build Coastguard Worker * @remarks Diamond Srch, radius is 1
139*495ae853SAndroid Build Coastguard Worker *
140*495ae853SAndroid Build Coastguard Worker *******************************************************************************
141*495ae853SAndroid Build Coastguard Worker */
isvce_diamond_search_16x16(isvce_me_ctxt_t * ps_me_ctxt,WORD32 i4_reflist)142*495ae853SAndroid Build Coastguard Worker static void isvce_diamond_search_16x16(isvce_me_ctxt_t *ps_me_ctxt, WORD32 i4_reflist)
143*495ae853SAndroid Build Coastguard Worker {
144*495ae853SAndroid Build Coastguard Worker     /* MB partition info */
145*495ae853SAndroid Build Coastguard Worker     mb_part_ctxt *ps_mb_part = &ps_me_ctxt->as_mb_part[i4_reflist];
146*495ae853SAndroid Build Coastguard Worker 
147*495ae853SAndroid Build Coastguard Worker     /* lagrange parameter */
148*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_lambda_motion = ps_me_ctxt->u4_lambda_motion;
149*495ae853SAndroid Build Coastguard Worker 
150*495ae853SAndroid Build Coastguard Worker     /* srch range*/
151*495ae853SAndroid Build Coastguard Worker     WORD32 i4_srch_range_n = ps_me_ctxt->i4_srch_range_n;
152*495ae853SAndroid Build Coastguard Worker     WORD32 i4_srch_range_s = ps_me_ctxt->i4_srch_range_s;
153*495ae853SAndroid Build Coastguard Worker     WORD32 i4_srch_range_e = ps_me_ctxt->i4_srch_range_e;
154*495ae853SAndroid Build Coastguard Worker     WORD32 i4_srch_range_w = ps_me_ctxt->i4_srch_range_w;
155*495ae853SAndroid Build Coastguard Worker 
156*495ae853SAndroid Build Coastguard Worker     /* pointer to src macro block */
157*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_curr_mb = ps_me_ctxt->pu1_src_buf_luma;
158*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_ref_mb = ps_me_ctxt->apu1_ref_buf_luma[i4_reflist];
159*495ae853SAndroid Build Coastguard Worker 
160*495ae853SAndroid Build Coastguard Worker     /* strides */
161*495ae853SAndroid Build Coastguard Worker     WORD32 i4_src_strd = ps_me_ctxt->i4_src_strd;
162*495ae853SAndroid Build Coastguard Worker     WORD32 i4_ref_strd = ps_me_ctxt->ai4_rec_strd[i4_reflist];
163*495ae853SAndroid Build Coastguard Worker 
164*495ae853SAndroid Build Coastguard Worker     /* least cost */
165*495ae853SAndroid Build Coastguard Worker     WORD32 i4_cost_least = ps_mb_part->i4_mb_cost;
166*495ae853SAndroid Build Coastguard Worker 
167*495ae853SAndroid Build Coastguard Worker     /* least sad */
168*495ae853SAndroid Build Coastguard Worker     WORD32 i4_distortion_least = ps_mb_part->i4_mb_distortion;
169*495ae853SAndroid Build Coastguard Worker 
170*495ae853SAndroid Build Coastguard Worker     /* mv pair */
171*495ae853SAndroid Build Coastguard Worker     WORD16 i2_mvx, i2_mvy;
172*495ae853SAndroid Build Coastguard Worker 
173*495ae853SAndroid Build Coastguard Worker     /* mv bits */
174*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_mv_bits = ps_me_ctxt->pu1_mv_bits;
175*495ae853SAndroid Build Coastguard Worker 
176*495ae853SAndroid Build Coastguard Worker     /* temp var */
177*495ae853SAndroid Build Coastguard Worker     WORD32 i4_cost[4];
178*495ae853SAndroid Build Coastguard Worker     WORD32 i4_sad[4];
179*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_ref;
180*495ae853SAndroid Build Coastguard Worker     WORD16 i2_mv_u_x, i2_mv_u_y;
181*495ae853SAndroid Build Coastguard Worker 
182*495ae853SAndroid Build Coastguard Worker     /* Diamond search Iteration Max Cnt */
183*495ae853SAndroid Build Coastguard Worker     WORD64 i8_num_layers = ps_me_ctxt->u4_num_layers;
184*495ae853SAndroid Build Coastguard Worker 
185*495ae853SAndroid Build Coastguard Worker     /* mv with best sad during initial evaluation */
186*495ae853SAndroid Build Coastguard Worker     i2_mvx = ps_mb_part->s_mv_curr.i2_mvx;
187*495ae853SAndroid Build Coastguard Worker     i2_mvy = ps_mb_part->s_mv_curr.i2_mvy;
188*495ae853SAndroid Build Coastguard Worker 
189*495ae853SAndroid Build Coastguard Worker     i2_mv_u_x = i2_mvx;
190*495ae853SAndroid Build Coastguard Worker     i2_mv_u_y = i2_mvy;
191*495ae853SAndroid Build Coastguard Worker 
192*495ae853SAndroid Build Coastguard Worker     while(i8_num_layers--)
193*495ae853SAndroid Build Coastguard Worker     {
194*495ae853SAndroid Build Coastguard Worker         /* FIXME : is this the write way to check for out of bounds ? */
195*495ae853SAndroid Build Coastguard Worker         if((i2_mvx - 1 < i4_srch_range_w) || (i2_mvx + 1 > i4_srch_range_e) ||
196*495ae853SAndroid Build Coastguard Worker            (i2_mvy - 1 < i4_srch_range_n) || (i2_mvy + 1 > i4_srch_range_s))
197*495ae853SAndroid Build Coastguard Worker         {
198*495ae853SAndroid Build Coastguard Worker             break;
199*495ae853SAndroid Build Coastguard Worker         }
200*495ae853SAndroid Build Coastguard Worker 
201*495ae853SAndroid Build Coastguard Worker         pu1_ref = pu1_ref_mb + i2_mvx + (i2_mvy * i4_ref_strd);
202*495ae853SAndroid Build Coastguard Worker 
203*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->pf_ime_compute_sad4_diamond(pu1_ref, pu1_curr_mb, i4_ref_strd, i4_src_strd,
204*495ae853SAndroid Build Coastguard Worker                                                 i4_sad);
205*495ae853SAndroid Build Coastguard Worker 
206*495ae853SAndroid Build Coastguard Worker         DEBUG_SAD_HISTOGRAM_ADD(i4_sad[0], 2);
207*495ae853SAndroid Build Coastguard Worker         DEBUG_SAD_HISTOGRAM_ADD(i4_sad[1], 2);
208*495ae853SAndroid Build Coastguard Worker         DEBUG_SAD_HISTOGRAM_ADD(i4_sad[2], 2);
209*495ae853SAndroid Build Coastguard Worker         DEBUG_SAD_HISTOGRAM_ADD(i4_sad[3], 2);
210*495ae853SAndroid Build Coastguard Worker 
211*495ae853SAndroid Build Coastguard Worker         /* compute cost */
212*495ae853SAndroid Build Coastguard Worker         i4_cost[0] =
213*495ae853SAndroid Build Coastguard Worker             i4_sad[0] +
214*495ae853SAndroid Build Coastguard Worker             u4_lambda_motion * (pu1_mv_bits[((i2_mvx - 1) << 2) - ps_mb_part->s_mv_pred.i2_mvx] +
215*495ae853SAndroid Build Coastguard Worker                                 pu1_mv_bits[(i2_mvy << 2) - ps_mb_part->s_mv_pred.i2_mvy]);
216*495ae853SAndroid Build Coastguard Worker         i4_cost[1] =
217*495ae853SAndroid Build Coastguard Worker             i4_sad[1] +
218*495ae853SAndroid Build Coastguard Worker             u4_lambda_motion * (pu1_mv_bits[((i2_mvx + 1) << 2) - ps_mb_part->s_mv_pred.i2_mvx] +
219*495ae853SAndroid Build Coastguard Worker                                 pu1_mv_bits[(i2_mvy << 2) - ps_mb_part->s_mv_pred.i2_mvy]);
220*495ae853SAndroid Build Coastguard Worker         i4_cost[2] =
221*495ae853SAndroid Build Coastguard Worker             i4_sad[2] +
222*495ae853SAndroid Build Coastguard Worker             u4_lambda_motion * (pu1_mv_bits[(i2_mvx << 2) - ps_mb_part->s_mv_pred.i2_mvx] +
223*495ae853SAndroid Build Coastguard Worker                                 pu1_mv_bits[((i2_mvy - 1) << 2) - ps_mb_part->s_mv_pred.i2_mvy]);
224*495ae853SAndroid Build Coastguard Worker         i4_cost[3] =
225*495ae853SAndroid Build Coastguard Worker             i4_sad[3] +
226*495ae853SAndroid Build Coastguard Worker             u4_lambda_motion * (pu1_mv_bits[(i2_mvx << 2) - ps_mb_part->s_mv_pred.i2_mvx] +
227*495ae853SAndroid Build Coastguard Worker                                 pu1_mv_bits[((i2_mvy + 1) << 2) - ps_mb_part->s_mv_pred.i2_mvy]);
228*495ae853SAndroid Build Coastguard Worker 
229*495ae853SAndroid Build Coastguard Worker         if(i4_cost_least > i4_cost[0])
230*495ae853SAndroid Build Coastguard Worker         {
231*495ae853SAndroid Build Coastguard Worker             i4_cost_least = i4_cost[0];
232*495ae853SAndroid Build Coastguard Worker             i4_distortion_least = i4_sad[0];
233*495ae853SAndroid Build Coastguard Worker 
234*495ae853SAndroid Build Coastguard Worker             i2_mv_u_x = (i2_mvx - 1);
235*495ae853SAndroid Build Coastguard Worker             i2_mv_u_y = i2_mvy;
236*495ae853SAndroid Build Coastguard Worker         }
237*495ae853SAndroid Build Coastguard Worker 
238*495ae853SAndroid Build Coastguard Worker         if(i4_cost_least > i4_cost[1])
239*495ae853SAndroid Build Coastguard Worker         {
240*495ae853SAndroid Build Coastguard Worker             i4_cost_least = i4_cost[1];
241*495ae853SAndroid Build Coastguard Worker             i4_distortion_least = i4_sad[1];
242*495ae853SAndroid Build Coastguard Worker 
243*495ae853SAndroid Build Coastguard Worker             i2_mv_u_x = (i2_mvx + 1);
244*495ae853SAndroid Build Coastguard Worker             i2_mv_u_y = i2_mvy;
245*495ae853SAndroid Build Coastguard Worker         }
246*495ae853SAndroid Build Coastguard Worker 
247*495ae853SAndroid Build Coastguard Worker         if(i4_cost_least > i4_cost[2])
248*495ae853SAndroid Build Coastguard Worker         {
249*495ae853SAndroid Build Coastguard Worker             i4_cost_least = i4_cost[2];
250*495ae853SAndroid Build Coastguard Worker             i4_distortion_least = i4_sad[2];
251*495ae853SAndroid Build Coastguard Worker 
252*495ae853SAndroid Build Coastguard Worker             i2_mv_u_x = i2_mvx;
253*495ae853SAndroid Build Coastguard Worker             i2_mv_u_y = i2_mvy - 1;
254*495ae853SAndroid Build Coastguard Worker         }
255*495ae853SAndroid Build Coastguard Worker 
256*495ae853SAndroid Build Coastguard Worker         if(i4_cost_least > i4_cost[3])
257*495ae853SAndroid Build Coastguard Worker         {
258*495ae853SAndroid Build Coastguard Worker             i4_cost_least = i4_cost[3];
259*495ae853SAndroid Build Coastguard Worker             i4_distortion_least = i4_sad[3];
260*495ae853SAndroid Build Coastguard Worker 
261*495ae853SAndroid Build Coastguard Worker             i2_mv_u_x = i2_mvx;
262*495ae853SAndroid Build Coastguard Worker             i2_mv_u_y = i2_mvy + 1;
263*495ae853SAndroid Build Coastguard Worker         }
264*495ae853SAndroid Build Coastguard Worker 
265*495ae853SAndroid Build Coastguard Worker         if((i2_mv_u_x == i2_mvx) && (i2_mv_u_y == i2_mvy))
266*495ae853SAndroid Build Coastguard Worker         {
267*495ae853SAndroid Build Coastguard Worker             ps_mb_part->u4_exit = 1;
268*495ae853SAndroid Build Coastguard Worker             break;
269*495ae853SAndroid Build Coastguard Worker         }
270*495ae853SAndroid Build Coastguard Worker         else
271*495ae853SAndroid Build Coastguard Worker         {
272*495ae853SAndroid Build Coastguard Worker             i2_mvx = i2_mv_u_x;
273*495ae853SAndroid Build Coastguard Worker             i2_mvy = i2_mv_u_y;
274*495ae853SAndroid Build Coastguard Worker         }
275*495ae853SAndroid Build Coastguard Worker     }
276*495ae853SAndroid Build Coastguard Worker 
277*495ae853SAndroid Build Coastguard Worker     if(i4_cost_least < ps_mb_part->i4_mb_cost)
278*495ae853SAndroid Build Coastguard Worker     {
279*495ae853SAndroid Build Coastguard Worker         ps_mb_part->i4_mb_cost = i4_cost_least;
280*495ae853SAndroid Build Coastguard Worker         ps_mb_part->i4_mb_distortion = i4_distortion_least;
281*495ae853SAndroid Build Coastguard Worker         ps_mb_part->s_mv_curr.i2_mvx = i2_mvx;
282*495ae853SAndroid Build Coastguard Worker         ps_mb_part->s_mv_curr.i2_mvy = i2_mvy;
283*495ae853SAndroid Build Coastguard Worker     }
284*495ae853SAndroid Build Coastguard Worker }
285*495ae853SAndroid Build Coastguard Worker 
286*495ae853SAndroid Build Coastguard Worker /**
287*495ae853SAndroid Build Coastguard Worker *******************************************************************************
288*495ae853SAndroid Build Coastguard Worker *
289*495ae853SAndroid Build Coastguard Worker * @brief This function computes the best motion vector among the tentative mv
290*495ae853SAndroid Build Coastguard Worker * candidates chosen.
291*495ae853SAndroid Build Coastguard Worker *
292*495ae853SAndroid Build Coastguard Worker * @par Description:
293*495ae853SAndroid Build Coastguard Worker *  This function determines the position in the search window at which the
294*495ae853SAndroid Build Coastguard Worker *motion estimation should begin in order to minimise the number of search
295*495ae853SAndroid Build Coastguard Worker *iterations.
296*495ae853SAndroid Build Coastguard Worker *
297*495ae853SAndroid Build Coastguard Worker * @param[in] ps_mb_part
298*495ae853SAndroid Build Coastguard Worker *  pointer to current mb partition ctxt with respect to ME
299*495ae853SAndroid Build Coastguard Worker *
300*495ae853SAndroid Build Coastguard Worker * @param[in] u4_lambda_motion
301*495ae853SAndroid Build Coastguard Worker *  lambda motion
302*495ae853SAndroid Build Coastguard Worker *
303*495ae853SAndroid Build Coastguard Worker * @param[in] u4_fast_flag
304*495ae853SAndroid Build Coastguard Worker *  enable/disable fast sad computation
305*495ae853SAndroid Build Coastguard Worker *
306*495ae853SAndroid Build Coastguard Worker * @returns  mv pair & corresponding distortion and cost
307*495ae853SAndroid Build Coastguard Worker *
308*495ae853SAndroid Build Coastguard Worker * @remarks none
309*495ae853SAndroid Build Coastguard Worker *
310*495ae853SAndroid Build Coastguard Worker *******************************************************************************
311*495ae853SAndroid Build Coastguard Worker */
312*495ae853SAndroid Build Coastguard Worker 
isvce_evaluate_init_srchposn_16x16(isvce_me_ctxt_t * ps_me_ctxt,WORD32 i4_reflist)313*495ae853SAndroid Build Coastguard Worker static void isvce_evaluate_init_srchposn_16x16(isvce_me_ctxt_t *ps_me_ctxt, WORD32 i4_reflist)
314*495ae853SAndroid Build Coastguard Worker {
315*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_lambda_motion = ps_me_ctxt->u4_lambda_motion;
316*495ae853SAndroid Build Coastguard Worker 
317*495ae853SAndroid Build Coastguard Worker     /* candidate mv cnt */
318*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_num_candidates = ps_me_ctxt->u4_num_candidates[i4_reflist];
319*495ae853SAndroid Build Coastguard Worker 
320*495ae853SAndroid Build Coastguard Worker     /* list of candidate mvs */
321*495ae853SAndroid Build Coastguard Worker     ime_mv_t *ps_mv_list = ps_me_ctxt->as_mv_init_search[i4_reflist];
322*495ae853SAndroid Build Coastguard Worker 
323*495ae853SAndroid Build Coastguard Worker     /* pointer to src macro block */
324*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_curr_mb = ps_me_ctxt->pu1_src_buf_luma;
325*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_ref_mb = ps_me_ctxt->apu1_ref_buf_luma[i4_reflist];
326*495ae853SAndroid Build Coastguard Worker 
327*495ae853SAndroid Build Coastguard Worker     /* strides */
328*495ae853SAndroid Build Coastguard Worker     WORD32 i4_src_strd = ps_me_ctxt->i4_src_strd;
329*495ae853SAndroid Build Coastguard Worker     WORD32 i4_ref_strd = ps_me_ctxt->ai4_rec_strd[i4_reflist];
330*495ae853SAndroid Build Coastguard Worker 
331*495ae853SAndroid Build Coastguard Worker     /* enabled fast sad computation */
332*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_enable_fast_sad = ps_me_ctxt->u4_enable_fast_sad;
333*495ae853SAndroid Build Coastguard Worker 
334*495ae853SAndroid Build Coastguard Worker     /* SAD(distortion metric) of an 8x8 block */
335*495ae853SAndroid Build Coastguard Worker     WORD32 i4_mb_distortion;
336*495ae853SAndroid Build Coastguard Worker 
337*495ae853SAndroid Build Coastguard Worker     /* cost = distortion + u4_lambda_motion * rate */
338*495ae853SAndroid Build Coastguard Worker     WORD32 i4_mb_cost, i4_mb_cost_least = INT_MAX, i4_distortion_least = INT_MAX;
339*495ae853SAndroid Build Coastguard Worker 
340*495ae853SAndroid Build Coastguard Worker     /* mb partitions info */
341*495ae853SAndroid Build Coastguard Worker     mb_part_ctxt *ps_mb_part = &(ps_me_ctxt->as_mb_part[i4_reflist]);
342*495ae853SAndroid Build Coastguard Worker 
343*495ae853SAndroid Build Coastguard Worker     /* mv bits */
344*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_mv_bits = ps_me_ctxt->pu1_mv_bits;
345*495ae853SAndroid Build Coastguard Worker 
346*495ae853SAndroid Build Coastguard Worker     /* temp var */
347*495ae853SAndroid Build Coastguard Worker     UWORD32 i, j;
348*495ae853SAndroid Build Coastguard Worker     WORD32 i4_srch_pos_idx = 0;
349*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_ref = NULL;
350*495ae853SAndroid Build Coastguard Worker 
351*495ae853SAndroid Build Coastguard Worker     /* Carry out a search using each of the motion vector pairs identified above
352*495ae853SAndroid Build Coastguard Worker      * as predictors. */
353*495ae853SAndroid Build Coastguard Worker     /* TODO : Just like Skip, Do we need to add any bias to zero mv as well */
354*495ae853SAndroid Build Coastguard Worker     for(i = 0; i < u4_num_candidates; i++)
355*495ae853SAndroid Build Coastguard Worker     {
356*495ae853SAndroid Build Coastguard Worker         /* compute sad */
357*495ae853SAndroid Build Coastguard Worker         WORD32 c_sad = 1;
358*495ae853SAndroid Build Coastguard Worker 
359*495ae853SAndroid Build Coastguard Worker         for(j = 0; j < i; j++)
360*495ae853SAndroid Build Coastguard Worker         {
361*495ae853SAndroid Build Coastguard Worker             if((ps_mv_list[i].i2_mvx == ps_mv_list[j].i2_mvx) &&
362*495ae853SAndroid Build Coastguard Worker                (ps_mv_list[i].i2_mvy == ps_mv_list[j].i2_mvy))
363*495ae853SAndroid Build Coastguard Worker             {
364*495ae853SAndroid Build Coastguard Worker                 c_sad = 0;
365*495ae853SAndroid Build Coastguard Worker                 break;
366*495ae853SAndroid Build Coastguard Worker             }
367*495ae853SAndroid Build Coastguard Worker         }
368*495ae853SAndroid Build Coastguard Worker         if(c_sad)
369*495ae853SAndroid Build Coastguard Worker         {
370*495ae853SAndroid Build Coastguard Worker             /* adjust ref pointer */
371*495ae853SAndroid Build Coastguard Worker             pu1_ref = pu1_ref_mb + ps_mv_list[i].i2_mvx + (ps_mv_list[i].i2_mvy * i4_ref_strd);
372*495ae853SAndroid Build Coastguard Worker 
373*495ae853SAndroid Build Coastguard Worker             /* compute distortion */
374*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->pf_ime_compute_sad_16x16[u4_enable_fast_sad](
375*495ae853SAndroid Build Coastguard Worker                 pu1_curr_mb, pu1_ref, i4_src_strd, i4_ref_strd, i4_mb_cost_least,
376*495ae853SAndroid Build Coastguard Worker                 &i4_mb_distortion);
377*495ae853SAndroid Build Coastguard Worker 
378*495ae853SAndroid Build Coastguard Worker             DEBUG_SAD_HISTOGRAM_ADD(i4_mb_distortion, 3);
379*495ae853SAndroid Build Coastguard Worker             /* compute cost */
380*495ae853SAndroid Build Coastguard Worker             i4_mb_cost =
381*495ae853SAndroid Build Coastguard Worker                 i4_mb_distortion +
382*495ae853SAndroid Build Coastguard Worker                 u4_lambda_motion *
383*495ae853SAndroid Build Coastguard Worker                     (pu1_mv_bits[(ps_mv_list[i].i2_mvx << 2) - ps_mb_part->s_mv_pred.i2_mvx] +
384*495ae853SAndroid Build Coastguard Worker                      pu1_mv_bits[(ps_mv_list[i].i2_mvy << 2) - ps_mb_part->s_mv_pred.i2_mvy]);
385*495ae853SAndroid Build Coastguard Worker 
386*495ae853SAndroid Build Coastguard Worker             if(i4_mb_cost < i4_mb_cost_least)
387*495ae853SAndroid Build Coastguard Worker             {
388*495ae853SAndroid Build Coastguard Worker                 i4_mb_cost_least = i4_mb_cost;
389*495ae853SAndroid Build Coastguard Worker 
390*495ae853SAndroid Build Coastguard Worker                 i4_distortion_least = i4_mb_distortion;
391*495ae853SAndroid Build Coastguard Worker 
392*495ae853SAndroid Build Coastguard Worker                 i4_srch_pos_idx = i;
393*495ae853SAndroid Build Coastguard Worker             }
394*495ae853SAndroid Build Coastguard Worker         }
395*495ae853SAndroid Build Coastguard Worker     }
396*495ae853SAndroid Build Coastguard Worker 
397*495ae853SAndroid Build Coastguard Worker     if(i4_mb_cost_least < ps_mb_part->i4_mb_cost)
398*495ae853SAndroid Build Coastguard Worker     {
399*495ae853SAndroid Build Coastguard Worker         ps_mb_part->i4_srch_pos_idx = i4_srch_pos_idx;
400*495ae853SAndroid Build Coastguard Worker         ps_mb_part->i4_mb_cost = i4_mb_cost_least;
401*495ae853SAndroid Build Coastguard Worker         ps_mb_part->i4_mb_distortion = i4_distortion_least;
402*495ae853SAndroid Build Coastguard Worker         ps_mb_part->s_mv_curr.i2_mvx = ps_mv_list[i4_srch_pos_idx].i2_mvx;
403*495ae853SAndroid Build Coastguard Worker         ps_mb_part->s_mv_curr.i2_mvy = ps_mv_list[i4_srch_pos_idx].i2_mvy;
404*495ae853SAndroid Build Coastguard Worker     }
405*495ae853SAndroid Build Coastguard Worker }
406*495ae853SAndroid Build Coastguard Worker 
407*495ae853SAndroid Build Coastguard Worker /**
408*495ae853SAndroid Build Coastguard Worker *******************************************************************************
409*495ae853SAndroid Build Coastguard Worker *
410*495ae853SAndroid Build Coastguard Worker * @brief Searches for the best matching full pixel predictor within the search
411*495ae853SAndroid Build Coastguard Worker * range
412*495ae853SAndroid Build Coastguard Worker *
413*495ae853SAndroid Build Coastguard Worker * @par Description:
414*495ae853SAndroid Build Coastguard Worker *  This function begins by computing the mv predict vector for the current mb.
415*495ae853SAndroid Build Coastguard Worker *  This is used for cost computations. Further basing on the algo. chosen, it
416*495ae853SAndroid Build Coastguard Worker *  looks through a set of candidate vectors that best represent the mb a least
417*495ae853SAndroid Build Coastguard Worker *  cost and returns this information.
418*495ae853SAndroid Build Coastguard Worker *
419*495ae853SAndroid Build Coastguard Worker * @param[in] ps_proc
420*495ae853SAndroid Build Coastguard Worker *  pointer to current proc ctxt
421*495ae853SAndroid Build Coastguard Worker *
422*495ae853SAndroid Build Coastguard Worker * @param[in] ps_me_ctxt
423*495ae853SAndroid Build Coastguard Worker *  pointer to me context
424*495ae853SAndroid Build Coastguard Worker *
425*495ae853SAndroid Build Coastguard Worker * @returns  mv pair & corresponding distortion and cost
426*495ae853SAndroid Build Coastguard Worker *
427*495ae853SAndroid Build Coastguard Worker * @remarks none
428*495ae853SAndroid Build Coastguard Worker *
429*495ae853SAndroid Build Coastguard Worker *******************************************************************************
430*495ae853SAndroid Build Coastguard Worker */
isvce_full_pel_motion_estimation_16x16(isvce_me_ctxt_t * ps_me_ctxt,WORD32 i4_ref_list)431*495ae853SAndroid Build Coastguard Worker static void isvce_full_pel_motion_estimation_16x16(isvce_me_ctxt_t *ps_me_ctxt, WORD32 i4_ref_list)
432*495ae853SAndroid Build Coastguard Worker {
433*495ae853SAndroid Build Coastguard Worker     /* mb part info */
434*495ae853SAndroid Build Coastguard Worker     mb_part_ctxt *ps_mb_part = &ps_me_ctxt->as_mb_part[i4_ref_list];
435*495ae853SAndroid Build Coastguard Worker 
436*495ae853SAndroid Build Coastguard Worker     /******************************************************************/
437*495ae853SAndroid Build Coastguard Worker     /* Modify Search range about initial candidate instead of zero mv */
438*495ae853SAndroid Build Coastguard Worker     /******************************************************************/
439*495ae853SAndroid Build Coastguard Worker     /*
440*495ae853SAndroid Build Coastguard Worker      * FIXME: The motion vectors in a way can become unbounded. It may so happen
441*495ae853SAndroid Build Coastguard Worker      * that MV might exceed the limit of the profile configured.
442*495ae853SAndroid Build Coastguard Worker      */
443*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->i4_srch_range_w =
444*495ae853SAndroid Build Coastguard Worker         MAX(ps_me_ctxt->i4_srch_range_w,
445*495ae853SAndroid Build Coastguard Worker             -ps_me_ctxt->ai2_srch_boundaries[0] + ps_mb_part->s_mv_curr.i2_mvx);
446*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->i4_srch_range_e =
447*495ae853SAndroid Build Coastguard Worker         MIN(ps_me_ctxt->i4_srch_range_e,
448*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->ai2_srch_boundaries[0] + ps_mb_part->s_mv_curr.i2_mvx);
449*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->i4_srch_range_n =
450*495ae853SAndroid Build Coastguard Worker         MAX(ps_me_ctxt->i4_srch_range_n,
451*495ae853SAndroid Build Coastguard Worker             -ps_me_ctxt->ai2_srch_boundaries[1] + ps_mb_part->s_mv_curr.i2_mvy);
452*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->i4_srch_range_s =
453*495ae853SAndroid Build Coastguard Worker         MIN(ps_me_ctxt->i4_srch_range_s,
454*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->ai2_srch_boundaries[1] + ps_mb_part->s_mv_curr.i2_mvy);
455*495ae853SAndroid Build Coastguard Worker 
456*495ae853SAndroid Build Coastguard Worker     /************************************************************/
457*495ae853SAndroid Build Coastguard Worker     /* Traverse about best initial candidate for mv             */
458*495ae853SAndroid Build Coastguard Worker     /************************************************************/
459*495ae853SAndroid Build Coastguard Worker 
460*495ae853SAndroid Build Coastguard Worker     switch(ps_me_ctxt->u4_me_speed_preset)
461*495ae853SAndroid Build Coastguard Worker     {
462*495ae853SAndroid Build Coastguard Worker         case DMND_SRCH:
463*495ae853SAndroid Build Coastguard Worker             isvce_diamond_search_16x16(ps_me_ctxt, i4_ref_list);
464*495ae853SAndroid Build Coastguard Worker             break;
465*495ae853SAndroid Build Coastguard Worker         default:
466*495ae853SAndroid Build Coastguard Worker             assert(0);
467*495ae853SAndroid Build Coastguard Worker             break;
468*495ae853SAndroid Build Coastguard Worker     }
469*495ae853SAndroid Build Coastguard Worker }
470*495ae853SAndroid Build Coastguard Worker 
471*495ae853SAndroid Build Coastguard Worker /**
472*495ae853SAndroid Build Coastguard Worker *******************************************************************************
473*495ae853SAndroid Build Coastguard Worker *
474*495ae853SAndroid Build Coastguard Worker * @brief Searches for the best matching sub pixel predictor within the search
475*495ae853SAndroid Build Coastguard Worker * range
476*495ae853SAndroid Build Coastguard Worker *
477*495ae853SAndroid Build Coastguard Worker * @par Description:
478*495ae853SAndroid Build Coastguard Worker *  This function begins by searching across all sub pixel sample points
479*495ae853SAndroid Build Coastguard Worker *  around the full pel motion vector. The vector with least cost is chosen as
480*495ae853SAndroid Build Coastguard Worker *  the mv for the current mb. If the skip mode is not evaluated while analysing
481*495ae853SAndroid Build Coastguard Worker *  the initial search candidates then analyse it here and update the mv.
482*495ae853SAndroid Build Coastguard Worker *
483*495ae853SAndroid Build Coastguard Worker * @param[in] ps_proc
484*495ae853SAndroid Build Coastguard Worker *  pointer to current proc ctxt
485*495ae853SAndroid Build Coastguard Worker *
486*495ae853SAndroid Build Coastguard Worker * @param[in] ps_me_ctxt
487*495ae853SAndroid Build Coastguard Worker *  pointer to me context
488*495ae853SAndroid Build Coastguard Worker *
489*495ae853SAndroid Build Coastguard Worker * @returns none
490*495ae853SAndroid Build Coastguard Worker *
491*495ae853SAndroid Build Coastguard Worker * @remarks none
492*495ae853SAndroid Build Coastguard Worker *
493*495ae853SAndroid Build Coastguard Worker *******************************************************************************
494*495ae853SAndroid Build Coastguard Worker */
isvce_sub_pel_motion_estimation_16x16(isvce_me_ctxt_t * ps_me_ctxt,WORD32 i4_reflist)495*495ae853SAndroid Build Coastguard Worker static void isvce_sub_pel_motion_estimation_16x16(isvce_me_ctxt_t *ps_me_ctxt, WORD32 i4_reflist)
496*495ae853SAndroid Build Coastguard Worker {
497*495ae853SAndroid Build Coastguard Worker     /* pointers to src & ref macro block */
498*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_curr_mb = ps_me_ctxt->pu1_src_buf_luma;
499*495ae853SAndroid Build Coastguard Worker 
500*495ae853SAndroid Build Coastguard Worker     /* pointers to ref. half pel planes */
501*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_ref_mb_half_x;
502*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_ref_mb_half_y;
503*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_ref_mb_half_xy;
504*495ae853SAndroid Build Coastguard Worker 
505*495ae853SAndroid Build Coastguard Worker     /* pointers to ref. half pel planes */
506*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_ref_mb_half_x_temp;
507*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_ref_mb_half_y_temp;
508*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_ref_mb_half_xy_temp;
509*495ae853SAndroid Build Coastguard Worker 
510*495ae853SAndroid Build Coastguard Worker     /* strides */
511*495ae853SAndroid Build Coastguard Worker     WORD32 i4_src_strd = ps_me_ctxt->i4_src_strd;
512*495ae853SAndroid Build Coastguard Worker 
513*495ae853SAndroid Build Coastguard Worker     WORD32 i4_ref_strd = ps_me_ctxt->u4_subpel_buf_strd;
514*495ae853SAndroid Build Coastguard Worker 
515*495ae853SAndroid Build Coastguard Worker     /* mb partitions info */
516*495ae853SAndroid Build Coastguard Worker     mb_part_ctxt *ps_mb_part = &ps_me_ctxt->as_mb_part[i4_reflist];
517*495ae853SAndroid Build Coastguard Worker 
518*495ae853SAndroid Build Coastguard Worker     /* SAD(distortion metric) of an mb */
519*495ae853SAndroid Build Coastguard Worker     WORD32 i4_mb_distortion;
520*495ae853SAndroid Build Coastguard Worker     WORD32 i4_distortion_least = ps_mb_part->i4_mb_distortion;
521*495ae853SAndroid Build Coastguard Worker 
522*495ae853SAndroid Build Coastguard Worker     /* cost = distortion + u4_lambda_motion * rate */
523*495ae853SAndroid Build Coastguard Worker     WORD32 i4_mb_cost;
524*495ae853SAndroid Build Coastguard Worker     WORD32 i4_mb_cost_least = ps_mb_part->i4_mb_cost;
525*495ae853SAndroid Build Coastguard Worker 
526*495ae853SAndroid Build Coastguard Worker     /*Best half pel buffer*/
527*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_best_hpel_buf = NULL;
528*495ae853SAndroid Build Coastguard Worker 
529*495ae853SAndroid Build Coastguard Worker     /* mv bits */
530*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_mv_bits = ps_me_ctxt->pu1_mv_bits;
531*495ae853SAndroid Build Coastguard Worker 
532*495ae853SAndroid Build Coastguard Worker     /* Motion vectors in full-pel units */
533*495ae853SAndroid Build Coastguard Worker     WORD16 mv_x, mv_y;
534*495ae853SAndroid Build Coastguard Worker 
535*495ae853SAndroid Build Coastguard Worker     /* lambda - lagrange constant */
536*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_lambda_motion = ps_me_ctxt->u4_lambda_motion;
537*495ae853SAndroid Build Coastguard Worker 
538*495ae853SAndroid Build Coastguard Worker     /* Flags to check if half pel points needs to be evaluated */
539*495ae853SAndroid Build Coastguard Worker     /**************************************/
540*495ae853SAndroid Build Coastguard Worker     /* 1 bit for each half pel candidate  */
541*495ae853SAndroid Build Coastguard Worker     /* bit 0 - half x = 1, half y = 0     */
542*495ae853SAndroid Build Coastguard Worker     /* bit 1 - half x = -1, half y = 0    */
543*495ae853SAndroid Build Coastguard Worker     /* bit 2 - half x = 0, half y = 1     */
544*495ae853SAndroid Build Coastguard Worker     /* bit 3 - half x = 0, half y = -1    */
545*495ae853SAndroid Build Coastguard Worker     /* bit 4 - half x = 1, half y = 1     */
546*495ae853SAndroid Build Coastguard Worker     /* bit 5 - half x = -1, half y = 1    */
547*495ae853SAndroid Build Coastguard Worker     /* bit 6 - half x = 1, half y = -1    */
548*495ae853SAndroid Build Coastguard Worker     /* bit 7 - half x = -1, half y = -1   */
549*495ae853SAndroid Build Coastguard Worker     /**************************************/
550*495ae853SAndroid Build Coastguard Worker     /* temp var */
551*495ae853SAndroid Build Coastguard Worker     WORD16 i2_mv_u_x, i2_mv_u_y;
552*495ae853SAndroid Build Coastguard Worker     WORD32 i, j;
553*495ae853SAndroid Build Coastguard Worker     WORD32 ai4_sad[8];
554*495ae853SAndroid Build Coastguard Worker 
555*495ae853SAndroid Build Coastguard Worker     WORD32 i4_srch_pos_idx = ps_mb_part->i4_srch_pos_idx;
556*495ae853SAndroid Build Coastguard Worker 
557*495ae853SAndroid Build Coastguard Worker     i2_mv_u_x = ps_mb_part->s_mv_curr.i2_mvx;
558*495ae853SAndroid Build Coastguard Worker     i2_mv_u_y = ps_mb_part->s_mv_curr.i2_mvy;
559*495ae853SAndroid Build Coastguard Worker 
560*495ae853SAndroid Build Coastguard Worker     /************************************************************/
561*495ae853SAndroid Build Coastguard Worker     /* Evaluate half pel                                        */
562*495ae853SAndroid Build Coastguard Worker     /************************************************************/
563*495ae853SAndroid Build Coastguard Worker     mv_x = ps_mb_part->s_mv_curr.i2_mvx >> 2;
564*495ae853SAndroid Build Coastguard Worker     mv_y = ps_mb_part->s_mv_curr.i2_mvy >> 2;
565*495ae853SAndroid Build Coastguard Worker 
566*495ae853SAndroid Build Coastguard Worker     /**************************************************************/
567*495ae853SAndroid Build Coastguard Worker     /* ps_me_ctxt->pu1_half_x points to the half pel pixel on the */
568*495ae853SAndroid Build Coastguard Worker     /* left side of full pel                                      */
569*495ae853SAndroid Build Coastguard Worker     /* ps_me_ctxt->pu1_half_y points to the half pel pixel on the */
570*495ae853SAndroid Build Coastguard Worker     /* top  side of full pel                                      */
571*495ae853SAndroid Build Coastguard Worker     /* ps_me_ctxt->pu1_half_xy points to the half pel pixel       */
572*495ae853SAndroid Build Coastguard Worker     /* on the top left side of full pel                           */
573*495ae853SAndroid Build Coastguard Worker     /* for the function pf_ime_sub_pel_compute_sad_16x16 the      */
574*495ae853SAndroid Build Coastguard Worker     /* default postions are                                       */
575*495ae853SAndroid Build Coastguard Worker     /* ps_me_ctxt->pu1_half_x = right halp_pel                    */
576*495ae853SAndroid Build Coastguard Worker     /*  ps_me_ctxt->pu1_half_y = bottom halp_pel                  */
577*495ae853SAndroid Build Coastguard Worker     /*  ps_me_ctxt->pu1_half_xy = bottom right halp_pel           */
578*495ae853SAndroid Build Coastguard Worker     /* Hence corresponding adjustments made here                  */
579*495ae853SAndroid Build Coastguard Worker     /**************************************************************/
580*495ae853SAndroid Build Coastguard Worker 
581*495ae853SAndroid Build Coastguard Worker     pu1_ref_mb_half_x_temp = pu1_ref_mb_half_x = ps_me_ctxt->apu1_subpel_buffs[0] + 1;
582*495ae853SAndroid Build Coastguard Worker     pu1_ref_mb_half_y_temp = pu1_ref_mb_half_y = ps_me_ctxt->apu1_subpel_buffs[1] + 1 + i4_ref_strd;
583*495ae853SAndroid Build Coastguard Worker     pu1_ref_mb_half_xy_temp = pu1_ref_mb_half_xy =
584*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->apu1_subpel_buffs[2] + 1 + i4_ref_strd;
585*495ae853SAndroid Build Coastguard Worker 
586*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->pf_ime_sub_pel_compute_sad_16x16(pu1_curr_mb, pu1_ref_mb_half_x, pu1_ref_mb_half_y,
587*495ae853SAndroid Build Coastguard Worker                                                  pu1_ref_mb_half_xy, i4_src_strd, i4_ref_strd,
588*495ae853SAndroid Build Coastguard Worker                                                  ai4_sad);
589*495ae853SAndroid Build Coastguard Worker 
590*495ae853SAndroid Build Coastguard Worker     /* Half x plane */
591*495ae853SAndroid Build Coastguard Worker     for(i = 0; i < 2; i++)
592*495ae853SAndroid Build Coastguard Worker     {
593*495ae853SAndroid Build Coastguard Worker         WORD32 mv_x_tmp = (mv_x << 2) + 2;
594*495ae853SAndroid Build Coastguard Worker         WORD32 mv_y_tmp = (mv_y << 2);
595*495ae853SAndroid Build Coastguard Worker 
596*495ae853SAndroid Build Coastguard Worker         mv_x_tmp -= (i * 4);
597*495ae853SAndroid Build Coastguard Worker 
598*495ae853SAndroid Build Coastguard Worker         i4_mb_distortion = ai4_sad[i];
599*495ae853SAndroid Build Coastguard Worker 
600*495ae853SAndroid Build Coastguard Worker         /* compute cost */
601*495ae853SAndroid Build Coastguard Worker         i4_mb_cost = i4_mb_distortion +
602*495ae853SAndroid Build Coastguard Worker                      u4_lambda_motion * (pu1_mv_bits[mv_x_tmp - ps_mb_part->s_mv_pred.i2_mvx] +
603*495ae853SAndroid Build Coastguard Worker                                          pu1_mv_bits[mv_y_tmp - ps_mb_part->s_mv_pred.i2_mvy]);
604*495ae853SAndroid Build Coastguard Worker 
605*495ae853SAndroid Build Coastguard Worker         if(i4_mb_cost < i4_mb_cost_least)
606*495ae853SAndroid Build Coastguard Worker         {
607*495ae853SAndroid Build Coastguard Worker             i4_mb_cost_least = i4_mb_cost;
608*495ae853SAndroid Build Coastguard Worker 
609*495ae853SAndroid Build Coastguard Worker             i4_distortion_least = i4_mb_distortion;
610*495ae853SAndroid Build Coastguard Worker 
611*495ae853SAndroid Build Coastguard Worker             i2_mv_u_x = mv_x_tmp;
612*495ae853SAndroid Build Coastguard Worker 
613*495ae853SAndroid Build Coastguard Worker             i2_mv_u_y = mv_y_tmp;
614*495ae853SAndroid Build Coastguard Worker 
615*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->apu1_subpel_buffs[0] = pu1_ref_mb_half_x_temp - i;
616*495ae853SAndroid Build Coastguard Worker             pu1_best_hpel_buf = pu1_ref_mb_half_x_temp - i;
617*495ae853SAndroid Build Coastguard Worker 
618*495ae853SAndroid Build Coastguard Worker             i4_srch_pos_idx = 0;
619*495ae853SAndroid Build Coastguard Worker         }
620*495ae853SAndroid Build Coastguard Worker     }
621*495ae853SAndroid Build Coastguard Worker 
622*495ae853SAndroid Build Coastguard Worker     /* Half y plane */
623*495ae853SAndroid Build Coastguard Worker     for(i = 0; i < 2; i++)
624*495ae853SAndroid Build Coastguard Worker     {
625*495ae853SAndroid Build Coastguard Worker         WORD32 mv_x_tmp = (mv_x << 2);
626*495ae853SAndroid Build Coastguard Worker         WORD32 mv_y_tmp = (mv_y << 2) + 2;
627*495ae853SAndroid Build Coastguard Worker 
628*495ae853SAndroid Build Coastguard Worker         mv_y_tmp -= (i * 4);
629*495ae853SAndroid Build Coastguard Worker 
630*495ae853SAndroid Build Coastguard Worker         i4_mb_distortion = ai4_sad[2 + i];
631*495ae853SAndroid Build Coastguard Worker 
632*495ae853SAndroid Build Coastguard Worker         /* compute cost */
633*495ae853SAndroid Build Coastguard Worker         i4_mb_cost = i4_mb_distortion +
634*495ae853SAndroid Build Coastguard Worker                      u4_lambda_motion * (pu1_mv_bits[mv_x_tmp - ps_mb_part->s_mv_pred.i2_mvx] +
635*495ae853SAndroid Build Coastguard Worker                                          pu1_mv_bits[mv_y_tmp - ps_mb_part->s_mv_pred.i2_mvy]);
636*495ae853SAndroid Build Coastguard Worker 
637*495ae853SAndroid Build Coastguard Worker         if(i4_mb_cost < i4_mb_cost_least)
638*495ae853SAndroid Build Coastguard Worker         {
639*495ae853SAndroid Build Coastguard Worker             i4_mb_cost_least = i4_mb_cost;
640*495ae853SAndroid Build Coastguard Worker 
641*495ae853SAndroid Build Coastguard Worker             i4_distortion_least = i4_mb_distortion;
642*495ae853SAndroid Build Coastguard Worker 
643*495ae853SAndroid Build Coastguard Worker             i2_mv_u_x = mv_x_tmp;
644*495ae853SAndroid Build Coastguard Worker 
645*495ae853SAndroid Build Coastguard Worker             i2_mv_u_y = mv_y_tmp;
646*495ae853SAndroid Build Coastguard Worker 
647*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->apu1_subpel_buffs[1] = pu1_ref_mb_half_y_temp - i * (i4_ref_strd);
648*495ae853SAndroid Build Coastguard Worker             pu1_best_hpel_buf = pu1_ref_mb_half_y_temp - i * (i4_ref_strd);
649*495ae853SAndroid Build Coastguard Worker 
650*495ae853SAndroid Build Coastguard Worker             i4_srch_pos_idx = 1;
651*495ae853SAndroid Build Coastguard Worker         }
652*495ae853SAndroid Build Coastguard Worker     }
653*495ae853SAndroid Build Coastguard Worker 
654*495ae853SAndroid Build Coastguard Worker     /* Half xy plane */
655*495ae853SAndroid Build Coastguard Worker     for(j = 0; j < 2; j++)
656*495ae853SAndroid Build Coastguard Worker     {
657*495ae853SAndroid Build Coastguard Worker         for(i = 0; i < 2; i++)
658*495ae853SAndroid Build Coastguard Worker         {
659*495ae853SAndroid Build Coastguard Worker             WORD32 mv_x_tmp = (mv_x << 2) + 2;
660*495ae853SAndroid Build Coastguard Worker             WORD32 mv_y_tmp = (mv_y << 2) + 2;
661*495ae853SAndroid Build Coastguard Worker 
662*495ae853SAndroid Build Coastguard Worker             mv_x_tmp -= (i * 4);
663*495ae853SAndroid Build Coastguard Worker             mv_y_tmp -= (j * 4);
664*495ae853SAndroid Build Coastguard Worker 
665*495ae853SAndroid Build Coastguard Worker             i4_mb_distortion = ai4_sad[4 + i + 2 * j];
666*495ae853SAndroid Build Coastguard Worker 
667*495ae853SAndroid Build Coastguard Worker             /* compute cost */
668*495ae853SAndroid Build Coastguard Worker             i4_mb_cost = i4_mb_distortion +
669*495ae853SAndroid Build Coastguard Worker                          u4_lambda_motion * (pu1_mv_bits[mv_x_tmp - ps_mb_part->s_mv_pred.i2_mvx] +
670*495ae853SAndroid Build Coastguard Worker                                              pu1_mv_bits[mv_y_tmp - ps_mb_part->s_mv_pred.i2_mvy]);
671*495ae853SAndroid Build Coastguard Worker 
672*495ae853SAndroid Build Coastguard Worker             if(i4_mb_cost < i4_mb_cost_least)
673*495ae853SAndroid Build Coastguard Worker             {
674*495ae853SAndroid Build Coastguard Worker                 i4_mb_cost_least = i4_mb_cost;
675*495ae853SAndroid Build Coastguard Worker 
676*495ae853SAndroid Build Coastguard Worker                 i4_distortion_least = i4_mb_distortion;
677*495ae853SAndroid Build Coastguard Worker 
678*495ae853SAndroid Build Coastguard Worker                 i2_mv_u_x = mv_x_tmp;
679*495ae853SAndroid Build Coastguard Worker 
680*495ae853SAndroid Build Coastguard Worker                 i2_mv_u_y = mv_y_tmp;
681*495ae853SAndroid Build Coastguard Worker 
682*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->apu1_subpel_buffs[2] = pu1_ref_mb_half_xy_temp - j * (i4_ref_strd) -i;
683*495ae853SAndroid Build Coastguard Worker                 pu1_best_hpel_buf = pu1_ref_mb_half_xy_temp - j * (i4_ref_strd) -i;
684*495ae853SAndroid Build Coastguard Worker 
685*495ae853SAndroid Build Coastguard Worker                 i4_srch_pos_idx = 2;
686*495ae853SAndroid Build Coastguard Worker             }
687*495ae853SAndroid Build Coastguard Worker         }
688*495ae853SAndroid Build Coastguard Worker     }
689*495ae853SAndroid Build Coastguard Worker 
690*495ae853SAndroid Build Coastguard Worker     if(i4_mb_cost_least < ps_mb_part->i4_mb_cost)
691*495ae853SAndroid Build Coastguard Worker     {
692*495ae853SAndroid Build Coastguard Worker         ps_mb_part->i4_mb_cost = i4_mb_cost_least;
693*495ae853SAndroid Build Coastguard Worker         ps_mb_part->i4_mb_distortion = i4_distortion_least;
694*495ae853SAndroid Build Coastguard Worker         ps_mb_part->s_mv_curr.i2_mvx = i2_mv_u_x;
695*495ae853SAndroid Build Coastguard Worker         ps_mb_part->s_mv_curr.i2_mvy = i2_mv_u_y;
696*495ae853SAndroid Build Coastguard Worker         ps_mb_part->pu1_best_hpel_buf = pu1_best_hpel_buf;
697*495ae853SAndroid Build Coastguard Worker         ps_mb_part->i4_srch_pos_idx = i4_srch_pos_idx;
698*495ae853SAndroid Build Coastguard Worker     }
699*495ae853SAndroid Build Coastguard Worker }
700*495ae853SAndroid Build Coastguard Worker 
701*495ae853SAndroid Build Coastguard Worker /**
702*495ae853SAndroid Build Coastguard Worker *******************************************************************************
703*495ae853SAndroid Build Coastguard Worker *
704*495ae853SAndroid Build Coastguard Worker * @brief This function computes cost of skip macroblocks
705*495ae853SAndroid Build Coastguard Worker *
706*495ae853SAndroid Build Coastguard Worker * @par Description:
707*495ae853SAndroid Build Coastguard Worker *
708*495ae853SAndroid Build Coastguard Worker * @param[in] ps_me_ctxt
709*495ae853SAndroid Build Coastguard Worker *  pointer to me ctxt
710*495ae853SAndroid Build Coastguard Worker *
711*495ae853SAndroid Build Coastguard Worker *
712*495ae853SAndroid Build Coastguard Worker * @returns  none
713*495ae853SAndroid Build Coastguard Worker *
714*495ae853SAndroid Build Coastguard Worker * @remarks
715*495ae853SAndroid Build Coastguard Worker * NOTE: while computing the skip cost, do not enable early exit from compute
716*495ae853SAndroid Build Coastguard Worker * sad function because, a negative bias gets added later
717*495ae853SAndroid Build Coastguard Worker * Note tha the last ME candidate in me ctxt is taken as skip motion vector
718*495ae853SAndroid Build Coastguard Worker *
719*495ae853SAndroid Build Coastguard Worker *******************************************************************************
720*495ae853SAndroid Build Coastguard Worker */
isvce_compute_skip_cost(isvce_me_ctxt_t * ps_me_ctxt,ime_mv_t * ps_skip_mv,mb_part_ctxt * ps_smb_part_info,UWORD32 u4_use_stat_sad,WORD32 i4_reflist,WORD32 i4_is_slice_type_b)721*495ae853SAndroid Build Coastguard Worker static void isvce_compute_skip_cost(isvce_me_ctxt_t *ps_me_ctxt, ime_mv_t *ps_skip_mv,
722*495ae853SAndroid Build Coastguard Worker                                     mb_part_ctxt *ps_smb_part_info, UWORD32 u4_use_stat_sad,
723*495ae853SAndroid Build Coastguard Worker                                     WORD32 i4_reflist, WORD32 i4_is_slice_type_b)
724*495ae853SAndroid Build Coastguard Worker {
725*495ae853SAndroid Build Coastguard Worker     /* SAD(distortion metric) of an mb */
726*495ae853SAndroid Build Coastguard Worker     WORD32 i4_mb_distortion;
727*495ae853SAndroid Build Coastguard Worker 
728*495ae853SAndroid Build Coastguard Worker     /* cost = distortion + u4_lambda_motion * rate */
729*495ae853SAndroid Build Coastguard Worker     WORD32 i4_mb_cost;
730*495ae853SAndroid Build Coastguard Worker 
731*495ae853SAndroid Build Coastguard Worker     /* temp var */
732*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_ref = NULL;
733*495ae853SAndroid Build Coastguard Worker 
734*495ae853SAndroid Build Coastguard Worker     ime_mv_t s_skip_mv;
735*495ae853SAndroid Build Coastguard Worker 
736*495ae853SAndroid Build Coastguard Worker     s_skip_mv.i2_mvx = (ps_skip_mv->i2_mvx + 2) >> 2;
737*495ae853SAndroid Build Coastguard Worker     s_skip_mv.i2_mvy = (ps_skip_mv->i2_mvy + 2) >> 2;
738*495ae853SAndroid Build Coastguard Worker 
739*495ae853SAndroid Build Coastguard Worker     /* Check if the skip mv is out of bounds or subpel */
740*495ae853SAndroid Build Coastguard Worker     {
741*495ae853SAndroid Build Coastguard Worker         /* skip mv */
742*495ae853SAndroid Build Coastguard Worker         ime_mv_t s_clip_skip_mv;
743*495ae853SAndroid Build Coastguard Worker 
744*495ae853SAndroid Build Coastguard Worker         s_clip_skip_mv.i2_mvx =
745*495ae853SAndroid Build Coastguard Worker             CLIP3(ps_me_ctxt->i4_srch_range_w, ps_me_ctxt->i4_srch_range_e, s_skip_mv.i2_mvx);
746*495ae853SAndroid Build Coastguard Worker         s_clip_skip_mv.i2_mvy =
747*495ae853SAndroid Build Coastguard Worker             CLIP3(ps_me_ctxt->i4_srch_range_n, ps_me_ctxt->i4_srch_range_s, s_skip_mv.i2_mvy);
748*495ae853SAndroid Build Coastguard Worker 
749*495ae853SAndroid Build Coastguard Worker         if((s_clip_skip_mv.i2_mvx != s_skip_mv.i2_mvx) ||
750*495ae853SAndroid Build Coastguard Worker            (s_clip_skip_mv.i2_mvy != s_skip_mv.i2_mvy) || (ps_skip_mv->i2_mvx & 0x3) ||
751*495ae853SAndroid Build Coastguard Worker            (ps_skip_mv->i2_mvy & 0x3))
752*495ae853SAndroid Build Coastguard Worker         {
753*495ae853SAndroid Build Coastguard Worker             return;
754*495ae853SAndroid Build Coastguard Worker         }
755*495ae853SAndroid Build Coastguard Worker     }
756*495ae853SAndroid Build Coastguard Worker 
757*495ae853SAndroid Build Coastguard Worker     /* adjust ref pointer */
758*495ae853SAndroid Build Coastguard Worker     pu1_ref = ps_me_ctxt->apu1_ref_buf_luma[i4_reflist] + s_skip_mv.i2_mvx +
759*495ae853SAndroid Build Coastguard Worker               (s_skip_mv.i2_mvy * ps_me_ctxt->ai4_rec_strd[i4_reflist]);
760*495ae853SAndroid Build Coastguard Worker 
761*495ae853SAndroid Build Coastguard Worker     if(u4_use_stat_sad == 1)
762*495ae853SAndroid Build Coastguard Worker     {
763*495ae853SAndroid Build Coastguard Worker         UWORD32 u4_is_nonzero;
764*495ae853SAndroid Build Coastguard Worker 
765*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->pf_ime_compute_sad_stat_luma_16x16(
766*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->pu1_src_buf_luma, pu1_ref, ps_me_ctxt->i4_src_strd,
767*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->ai4_rec_strd[i4_reflist], ps_me_ctxt->pu2_sad_thrsh, &i4_mb_distortion,
768*495ae853SAndroid Build Coastguard Worker             &u4_is_nonzero);
769*495ae853SAndroid Build Coastguard Worker 
770*495ae853SAndroid Build Coastguard Worker         if(u4_is_nonzero == 0 || i4_mb_distortion <= ps_me_ctxt->i4_min_sad)
771*495ae853SAndroid Build Coastguard Worker         {
772*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->u4_min_sad_reached = 1; /* found min sad */
773*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->i4_min_sad = (u4_is_nonzero == 0) ? 0 : i4_mb_distortion;
774*495ae853SAndroid Build Coastguard Worker         }
775*495ae853SAndroid Build Coastguard Worker     }
776*495ae853SAndroid Build Coastguard Worker     else
777*495ae853SAndroid Build Coastguard Worker     {
778*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->pf_ime_compute_sad_16x16[ps_me_ctxt->u4_enable_fast_sad](
779*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->pu1_src_buf_luma, pu1_ref, ps_me_ctxt->i4_src_strd,
780*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->ai4_rec_strd[i4_reflist], INT_MAX, &i4_mb_distortion);
781*495ae853SAndroid Build Coastguard Worker 
782*495ae853SAndroid Build Coastguard Worker         if(i4_mb_distortion <= ps_me_ctxt->i4_min_sad)
783*495ae853SAndroid Build Coastguard Worker         {
784*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->i4_min_sad = i4_mb_distortion;
785*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->u4_min_sad_reached = 1; /* found min sad */
786*495ae853SAndroid Build Coastguard Worker         }
787*495ae853SAndroid Build Coastguard Worker     }
788*495ae853SAndroid Build Coastguard Worker 
789*495ae853SAndroid Build Coastguard Worker     /* for skip mode cost & distortion are identical
790*495ae853SAndroid Build Coastguard Worker      * But we shall add a bias to favor skip mode.
791*495ae853SAndroid Build Coastguard Worker      * Doc. JVT B118 Suggests SKIP_BIAS as 16.
792*495ae853SAndroid Build Coastguard Worker      * TODO : Empirical analysis of SKIP_BIAS is necessary */
793*495ae853SAndroid Build Coastguard Worker 
794*495ae853SAndroid Build Coastguard Worker     i4_mb_cost = i4_mb_distortion -
795*495ae853SAndroid Build Coastguard Worker                  (ps_me_ctxt->u4_lambda_motion *
796*495ae853SAndroid Build Coastguard Worker                   (ps_me_ctxt->i4_skip_bias[0] + ps_me_ctxt->i4_skip_bias[1] * i4_is_slice_type_b));
797*495ae853SAndroid Build Coastguard Worker 
798*495ae853SAndroid Build Coastguard Worker     if(i4_mb_cost <= ps_smb_part_info->i4_mb_cost)
799*495ae853SAndroid Build Coastguard Worker     {
800*495ae853SAndroid Build Coastguard Worker         ps_smb_part_info->i4_mb_cost = i4_mb_cost;
801*495ae853SAndroid Build Coastguard Worker         ps_smb_part_info->i4_mb_distortion = i4_mb_distortion;
802*495ae853SAndroid Build Coastguard Worker         ps_smb_part_info->s_mv_curr.i2_mvx = s_skip_mv.i2_mvx;
803*495ae853SAndroid Build Coastguard Worker         ps_smb_part_info->s_mv_curr.i2_mvy = s_skip_mv.i2_mvy;
804*495ae853SAndroid Build Coastguard Worker     }
805*495ae853SAndroid Build Coastguard Worker }
806*495ae853SAndroid Build Coastguard Worker 
807*495ae853SAndroid Build Coastguard Worker /**
808*495ae853SAndroid Build Coastguard Worker *******************************************************************************
809*495ae853SAndroid Build Coastguard Worker *
810*495ae853SAndroid Build Coastguard Worker * @brief
811*495ae853SAndroid Build Coastguard Worker *  This function populates the length of the codewords for motion vectors in the
812*495ae853SAndroid Build Coastguard Worker *  range (-search range, search range) in pixels
813*495ae853SAndroid Build Coastguard Worker *
814*495ae853SAndroid Build Coastguard Worker * @param[in] ps_me
815*495ae853SAndroid Build Coastguard Worker *  Pointer to me ctxt
816*495ae853SAndroid Build Coastguard Worker *
817*495ae853SAndroid Build Coastguard Worker * @param[out] pu1_mv_bits
818*495ae853SAndroid Build Coastguard Worker *  length of the codeword for all mv's
819*495ae853SAndroid Build Coastguard Worker *
820*495ae853SAndroid Build Coastguard Worker * @remarks The length of the code words are derived from signed exponential
821*495ae853SAndroid Build Coastguard Worker * goloumb codes.
822*495ae853SAndroid Build Coastguard Worker *
823*495ae853SAndroid Build Coastguard Worker *******************************************************************************
824*495ae853SAndroid Build Coastguard Worker */
isvce_init_mv_bits(isvce_me_ctxt_t * ps_me_ctxt)825*495ae853SAndroid Build Coastguard Worker void isvce_init_mv_bits(isvce_me_ctxt_t *ps_me_ctxt)
826*495ae853SAndroid Build Coastguard Worker {
827*495ae853SAndroid Build Coastguard Worker     /* temp var */
828*495ae853SAndroid Build Coastguard Worker     WORD32 i, codesize = 3, diff, limit;
829*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_code_num, u4_range;
830*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_uev_min, u4_uev_max, u4_sev_min, u4_sev_max;
831*495ae853SAndroid Build Coastguard Worker 
832*495ae853SAndroid Build Coastguard Worker     /* max srch range */
833*495ae853SAndroid Build Coastguard Worker     diff = MAX(DEFAULT_MAX_SRCH_RANGE_X, DEFAULT_MAX_SRCH_RANGE_Y);
834*495ae853SAndroid Build Coastguard Worker     /* sub pel */
835*495ae853SAndroid Build Coastguard Worker     diff <<= 2;
836*495ae853SAndroid Build Coastguard Worker     /* delta mv */
837*495ae853SAndroid Build Coastguard Worker     diff <<= 1;
838*495ae853SAndroid Build Coastguard Worker 
839*495ae853SAndroid Build Coastguard Worker     /* codeNum for positive integer     =  2x-1     : Table9-3  */
840*495ae853SAndroid Build Coastguard Worker     u4_code_num = (diff << 1);
841*495ae853SAndroid Build Coastguard Worker 
842*495ae853SAndroid Build Coastguard Worker     /* get range of the bit string and put using put_bits()                 */
843*495ae853SAndroid Build Coastguard Worker     GETRANGE(u4_range, u4_code_num);
844*495ae853SAndroid Build Coastguard Worker 
845*495ae853SAndroid Build Coastguard Worker     limit = 2 * u4_range - 1;
846*495ae853SAndroid Build Coastguard Worker 
847*495ae853SAndroid Build Coastguard Worker     /* init mv bits */
848*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->pu1_mv_bits[0] = 1;
849*495ae853SAndroid Build Coastguard Worker 
850*495ae853SAndroid Build Coastguard Worker     while(codesize < limit)
851*495ae853SAndroid Build Coastguard Worker     {
852*495ae853SAndroid Build Coastguard Worker         u4_uev_min = (1 << (codesize >> 1));
853*495ae853SAndroid Build Coastguard Worker         u4_uev_max = 2 * u4_uev_min - 1;
854*495ae853SAndroid Build Coastguard Worker 
855*495ae853SAndroid Build Coastguard Worker         u4_sev_min = u4_uev_min >> 1;
856*495ae853SAndroid Build Coastguard Worker         u4_sev_max = u4_uev_max >> 1;
857*495ae853SAndroid Build Coastguard Worker 
858*495ae853SAndroid Build Coastguard Worker         DEBUG("\n%d min, %d max %d codesize", u4_sev_min, u4_sev_max, codesize);
859*495ae853SAndroid Build Coastguard Worker 
860*495ae853SAndroid Build Coastguard Worker         for(i = u4_sev_min; i <= (WORD32) u4_sev_max; i++)
861*495ae853SAndroid Build Coastguard Worker         {
862*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->pu1_mv_bits[-i] = ps_me_ctxt->pu1_mv_bits[i] = codesize;
863*495ae853SAndroid Build Coastguard Worker         }
864*495ae853SAndroid Build Coastguard Worker 
865*495ae853SAndroid Build Coastguard Worker         codesize += 2;
866*495ae853SAndroid Build Coastguard Worker     }
867*495ae853SAndroid Build Coastguard Worker }
868*495ae853SAndroid Build Coastguard Worker 
869*495ae853SAndroid Build Coastguard Worker /**
870*495ae853SAndroid Build Coastguard Worker *******************************************************************************
871*495ae853SAndroid Build Coastguard Worker *
872*495ae853SAndroid Build Coastguard Worker * @brief Adds valid MVs as initial search candidates for motion estimation by
873*495ae853SAndroid Build Coastguard Worker * cheking if it is distinct or not.
874*495ae853SAndroid Build Coastguard Worker *
875*495ae853SAndroid Build Coastguard Worker * @param[in] ps_search_cand
876*495ae853SAndroid Build Coastguard Worker *  MV to add as search candidate
877*495ae853SAndroid Build Coastguard Worker *
878*495ae853SAndroid Build Coastguard Worker * @param[in] ps_me_ctxt
879*495ae853SAndroid Build Coastguard Worker *  pointer to ME context
880*495ae853SAndroid Build Coastguard Worker *
881*495ae853SAndroid Build Coastguard Worker * @param[in] u4_num_candidates
882*495ae853SAndroid Build Coastguard Worker *  Number of inital search candidates value
883*495ae853SAndroid Build Coastguard Worker *
884*495ae853SAndroid Build Coastguard Worker *******************************************************************************
885*495ae853SAndroid Build Coastguard Worker */
isvce_add_me_init_search_cands(mv_t * ps_search_cand,isvce_me_ctxt_t * ps_me_ctxt,WORD32 i4_reflist,UWORD32 * u4_num_candidates,bool b_is_max_mv_diff_lt_4)886*495ae853SAndroid Build Coastguard Worker static FORCEINLINE void isvce_add_me_init_search_cands(mv_t *ps_search_cand,
887*495ae853SAndroid Build Coastguard Worker                                                        isvce_me_ctxt_t *ps_me_ctxt,
888*495ae853SAndroid Build Coastguard Worker                                                        WORD32 i4_reflist,
889*495ae853SAndroid Build Coastguard Worker                                                        UWORD32 *u4_num_candidates,
890*495ae853SAndroid Build Coastguard Worker                                                        bool b_is_max_mv_diff_lt_4)
891*495ae853SAndroid Build Coastguard Worker {
892*495ae853SAndroid Build Coastguard Worker     WORD32 k;
893*495ae853SAndroid Build Coastguard Worker     WORD32 i4_mv_x, i4_mv_y;
894*495ae853SAndroid Build Coastguard Worker 
895*495ae853SAndroid Build Coastguard Worker     bool b_is_mv_identical = false;
896*495ae853SAndroid Build Coastguard Worker 
897*495ae853SAndroid Build Coastguard Worker     WORD32 i4_srch_range_n = ps_me_ctxt->i4_srch_range_n;
898*495ae853SAndroid Build Coastguard Worker     WORD32 i4_srch_range_s = ps_me_ctxt->i4_srch_range_s;
899*495ae853SAndroid Build Coastguard Worker     WORD32 i4_srch_range_e = ps_me_ctxt->i4_srch_range_e;
900*495ae853SAndroid Build Coastguard Worker     WORD32 i4_srch_range_w = ps_me_ctxt->i4_srch_range_w;
901*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_num_init_search_cands = u4_num_candidates[0];
902*495ae853SAndroid Build Coastguard Worker 
903*495ae853SAndroid Build Coastguard Worker     i4_mv_x = (ps_search_cand->i2_mvx + 2) >> 2;
904*495ae853SAndroid Build Coastguard Worker     i4_mv_y = (ps_search_cand->i2_mvy + 2) >> 2;
905*495ae853SAndroid Build Coastguard Worker 
906*495ae853SAndroid Build Coastguard Worker     i4_mv_x = CLIP3(i4_srch_range_w, i4_srch_range_e, i4_mv_x);
907*495ae853SAndroid Build Coastguard Worker     i4_mv_y = CLIP3(i4_srch_range_n, i4_srch_range_s, i4_mv_y);
908*495ae853SAndroid Build Coastguard Worker 
909*495ae853SAndroid Build Coastguard Worker     if(u4_num_init_search_cands == 0)
910*495ae853SAndroid Build Coastguard Worker     {
911*495ae853SAndroid Build Coastguard Worker         b_is_mv_identical = false;
912*495ae853SAndroid Build Coastguard Worker     }
913*495ae853SAndroid Build Coastguard Worker     else
914*495ae853SAndroid Build Coastguard Worker     {
915*495ae853SAndroid Build Coastguard Worker         for(k = u4_num_init_search_cands - 1; k >= 0; k--)
916*495ae853SAndroid Build Coastguard Worker         {
917*495ae853SAndroid Build Coastguard Worker             if((ps_me_ctxt->as_mv_init_search[i4_reflist][k].i2_mvx == i4_mv_x &&
918*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->as_mv_init_search[i4_reflist][k].i2_mvy == i4_mv_y))
919*495ae853SAndroid Build Coastguard Worker             {
920*495ae853SAndroid Build Coastguard Worker                 b_is_mv_identical = true;
921*495ae853SAndroid Build Coastguard Worker             }
922*495ae853SAndroid Build Coastguard Worker         }
923*495ae853SAndroid Build Coastguard Worker     }
924*495ae853SAndroid Build Coastguard Worker 
925*495ae853SAndroid Build Coastguard Worker     if(!b_is_mv_identical)
926*495ae853SAndroid Build Coastguard Worker     {
927*495ae853SAndroid Build Coastguard Worker         if(USE_ILP_MV_IN_ME && ps_me_ctxt->ps_ilp_me_cands)
928*495ae853SAndroid Build Coastguard Worker         {
929*495ae853SAndroid Build Coastguard Worker             if(ps_me_ctxt->ps_ilp_me_cands->u4_num_ilp_mvs < 2 || b_is_max_mv_diff_lt_4)
930*495ae853SAndroid Build Coastguard Worker             {
931*495ae853SAndroid Build Coastguard Worker                 if(u4_num_init_search_cands < MAX_CAND_IF_NUM_ILP_MV_LT_2)
932*495ae853SAndroid Build Coastguard Worker                 {
933*495ae853SAndroid Build Coastguard Worker                     ps_me_ctxt->as_mv_init_search[i4_reflist][u4_num_init_search_cands].i2_mvx =
934*495ae853SAndroid Build Coastguard Worker                         i4_mv_x;
935*495ae853SAndroid Build Coastguard Worker                     ps_me_ctxt->as_mv_init_search[i4_reflist][u4_num_init_search_cands].i2_mvy =
936*495ae853SAndroid Build Coastguard Worker                         i4_mv_y;
937*495ae853SAndroid Build Coastguard Worker 
938*495ae853SAndroid Build Coastguard Worker                     u4_num_candidates[0] += 1;
939*495ae853SAndroid Build Coastguard Worker                 }
940*495ae853SAndroid Build Coastguard Worker             }
941*495ae853SAndroid Build Coastguard Worker             else if(ps_me_ctxt->ps_ilp_me_cands->u4_num_ilp_mvs >= 2 && !b_is_max_mv_diff_lt_4)
942*495ae853SAndroid Build Coastguard Worker             {
943*495ae853SAndroid Build Coastguard Worker                 if(u4_num_init_search_cands < MAX_CAND_IF_NUM_ILP_MV_GTEQ_2)
944*495ae853SAndroid Build Coastguard Worker                 {
945*495ae853SAndroid Build Coastguard Worker                     ps_me_ctxt->as_mv_init_search[i4_reflist][u4_num_init_search_cands].i2_mvx =
946*495ae853SAndroid Build Coastguard Worker                         i4_mv_x;
947*495ae853SAndroid Build Coastguard Worker                     ps_me_ctxt->as_mv_init_search[i4_reflist][u4_num_init_search_cands].i2_mvy =
948*495ae853SAndroid Build Coastguard Worker                         i4_mv_y;
949*495ae853SAndroid Build Coastguard Worker 
950*495ae853SAndroid Build Coastguard Worker                     u4_num_candidates[0] += 1;
951*495ae853SAndroid Build Coastguard Worker                 }
952*495ae853SAndroid Build Coastguard Worker             }
953*495ae853SAndroid Build Coastguard Worker         }
954*495ae853SAndroid Build Coastguard Worker         else
955*495ae853SAndroid Build Coastguard Worker         {
956*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mv_init_search[i4_reflist][u4_num_init_search_cands].i2_mvx = i4_mv_x;
957*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mv_init_search[i4_reflist][u4_num_init_search_cands].i2_mvy = i4_mv_y;
958*495ae853SAndroid Build Coastguard Worker 
959*495ae853SAndroid Build Coastguard Worker             u4_num_candidates[0] += 1;
960*495ae853SAndroid Build Coastguard Worker         }
961*495ae853SAndroid Build Coastguard Worker     }
962*495ae853SAndroid Build Coastguard Worker }
963*495ae853SAndroid Build Coastguard Worker 
964*495ae853SAndroid Build Coastguard Worker /**
965*495ae853SAndroid Build Coastguard Worker *******************************************************************************
966*495ae853SAndroid Build Coastguard Worker *
967*495ae853SAndroid Build Coastguard Worker * @brief Determines the valid candidates for which the initial search shall
968*495ae853SAndroid Build Coastguard Worker *happen. The best of these candidates is used to center the diamond pixel
969*495ae853SAndroid Build Coastguard Worker *search.
970*495ae853SAndroid Build Coastguard Worker *
971*495ae853SAndroid Build Coastguard Worker * @par Description: The function sends the skip, (0,0), left, top and top-right
972*495ae853SAndroid Build Coastguard Worker * neighbouring MBs MVs. The left, top and top-right MBs MVs are used because
973*495ae853SAndroid Build Coastguard Worker * these are the same MVs that are used to form the MV predictor. This initial MV
974*495ae853SAndroid Build Coastguard Worker * search candidates need not take care of slice boundaries and hence neighbor
975*495ae853SAndroid Build Coastguard Worker * availability checks are not made here.
976*495ae853SAndroid Build Coastguard Worker *
977*495ae853SAndroid Build Coastguard Worker * @param[in] ps_left_mb_pu
978*495ae853SAndroid Build Coastguard Worker *  pointer to left mb motion vector info
979*495ae853SAndroid Build Coastguard Worker *
980*495ae853SAndroid Build Coastguard Worker * @param[in] ps_top_mb_pu
981*495ae853SAndroid Build Coastguard Worker *  pointer to top & top right mb motion vector info
982*495ae853SAndroid Build Coastguard Worker *
983*495ae853SAndroid Build Coastguard Worker * @param[in] ps_top_left_mb_pu
984*495ae853SAndroid Build Coastguard Worker *  pointer to top left mb motion vector info
985*495ae853SAndroid Build Coastguard Worker *
986*495ae853SAndroid Build Coastguard Worker * @param[out] ps_skip_mv
987*495ae853SAndroid Build Coastguard Worker *  pointer to skip motion vectors for the curr mb
988*495ae853SAndroid Build Coastguard Worker *
989*495ae853SAndroid Build Coastguard Worker * @param[in] i4_mb_x
990*495ae853SAndroid Build Coastguard Worker *  mb index x
991*495ae853SAndroid Build Coastguard Worker *
992*495ae853SAndroid Build Coastguard Worker * @param[in] i4_mb_y
993*495ae853SAndroid Build Coastguard Worker *  mb index y
994*495ae853SAndroid Build Coastguard Worker *
995*495ae853SAndroid Build Coastguard Worker * @param[in] i4_wd_mbs
996*495ae853SAndroid Build Coastguard Worker *  pic width in mbs
997*495ae853SAndroid Build Coastguard Worker *
998*495ae853SAndroid Build Coastguard Worker * @param[in] ps_motionEst
999*495ae853SAndroid Build Coastguard Worker *  pointer to me context
1000*495ae853SAndroid Build Coastguard Worker *
1001*495ae853SAndroid Build Coastguard Worker * @returns  The list of MVs to be used of priming the full pel search and the
1002*495ae853SAndroid Build Coastguard Worker * number of such MVs
1003*495ae853SAndroid Build Coastguard Worker *
1004*495ae853SAndroid Build Coastguard Worker * @remarks
1005*495ae853SAndroid Build Coastguard Worker *   Assumptions : 1. Assumes Only partition of size 16x16
1006*495ae853SAndroid Build Coastguard Worker *
1007*495ae853SAndroid Build Coastguard Worker *******************************************************************************
1008*495ae853SAndroid Build Coastguard Worker */
isvce_get_search_candidates(isvce_process_ctxt_t * ps_proc,isvce_me_ctxt_t * ps_me_ctxt,WORD32 i4_reflist)1009*495ae853SAndroid Build Coastguard Worker static void isvce_get_search_candidates(isvce_process_ctxt_t *ps_proc, isvce_me_ctxt_t *ps_me_ctxt,
1010*495ae853SAndroid Build Coastguard Worker                                         WORD32 i4_reflist)
1011*495ae853SAndroid Build Coastguard Worker {
1012*495ae853SAndroid Build Coastguard Worker     mv_t s_zero_mv;
1013*495ae853SAndroid Build Coastguard Worker     mv_t *ps_left_mv, *ps_top_mv, *ps_top_left_mv, *ps_top_right_mv;
1014*495ae853SAndroid Build Coastguard Worker 
1015*495ae853SAndroid Build Coastguard Worker     UWORD32 i;
1016*495ae853SAndroid Build Coastguard Worker     WORD32 i4_left_mode, i4_top_mode, i4_top_left_mode, i4_top_right_mode;
1017*495ae853SAndroid Build Coastguard Worker 
1018*495ae853SAndroid Build Coastguard Worker     isvce_codec_t *ps_codec = ps_proc->ps_codec;
1019*495ae853SAndroid Build Coastguard Worker     block_neighbors_t *ps_ngbr_avbl = ps_proc->ps_ngbr_avbl;
1020*495ae853SAndroid Build Coastguard Worker     mb_part_ctxt *ps_mb_part = &ps_me_ctxt->as_mb_part[i4_reflist];
1021*495ae853SAndroid Build Coastguard Worker     ilp_me_cands_t *ps_ilp_me_cands = ps_me_ctxt->ps_ilp_me_cands;
1022*495ae853SAndroid Build Coastguard Worker 
1023*495ae853SAndroid Build Coastguard Worker     bool b_is_max_mv_diff_lt_4 = false;
1024*495ae853SAndroid Build Coastguard Worker     WORD32 i4_mb_x = ps_proc->i4_mb_x;
1025*495ae853SAndroid Build Coastguard Worker     WORD32 i4_cmpl_predmode = (i4_reflist == 0) ? L1 : L0;
1026*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_num_candidates = 0;
1027*495ae853SAndroid Build Coastguard Worker 
1028*495ae853SAndroid Build Coastguard Worker     s_zero_mv.i2_mvx = 0;
1029*495ae853SAndroid Build Coastguard Worker     s_zero_mv.i2_mvy = 0;
1030*495ae853SAndroid Build Coastguard Worker     ps_left_mv = &ps_proc->s_nbr_info.ps_left_mb_info->as_pu->as_me_info[i4_reflist].s_mv;
1031*495ae853SAndroid Build Coastguard Worker     ps_top_mv =
1032*495ae853SAndroid Build Coastguard Worker         &(ps_proc->s_nbr_info.ps_top_row_mb_info + i4_mb_x)->as_pu->as_me_info[i4_reflist].s_mv;
1033*495ae853SAndroid Build Coastguard Worker     ps_top_left_mv = &ps_proc->s_nbr_info.ps_top_row_mb_info->as_pu->as_me_info[i4_reflist].s_mv;
1034*495ae853SAndroid Build Coastguard Worker     ps_top_right_mv =
1035*495ae853SAndroid Build Coastguard Worker         &(ps_proc->s_nbr_info.ps_top_row_mb_info + i4_mb_x + 1)->as_pu->as_me_info[i4_reflist].s_mv;
1036*495ae853SAndroid Build Coastguard Worker 
1037*495ae853SAndroid Build Coastguard Worker     i4_left_mode =
1038*495ae853SAndroid Build Coastguard Worker         ps_ngbr_avbl->u1_mb_a
1039*495ae853SAndroid Build Coastguard Worker             ? (ps_proc->s_nbr_info.ps_left_mb_info->as_pu->u1_pred_mode != i4_cmpl_predmode)
1040*495ae853SAndroid Build Coastguard Worker             : 0;
1041*495ae853SAndroid Build Coastguard Worker     i4_top_mode = ps_ngbr_avbl->u1_mb_b
1042*495ae853SAndroid Build Coastguard Worker                       ? ((ps_proc->s_nbr_info.ps_top_row_mb_info + i4_mb_x)->as_pu->u1_pred_mode !=
1043*495ae853SAndroid Build Coastguard Worker                          i4_cmpl_predmode)
1044*495ae853SAndroid Build Coastguard Worker                       : 0;
1045*495ae853SAndroid Build Coastguard Worker     i4_top_right_mode =
1046*495ae853SAndroid Build Coastguard Worker         ps_ngbr_avbl->u1_mb_c
1047*495ae853SAndroid Build Coastguard Worker             ? ((ps_proc->s_nbr_info.ps_top_row_mb_info + i4_mb_x + 1)->as_pu->u1_pred_mode !=
1048*495ae853SAndroid Build Coastguard Worker                i4_cmpl_predmode)
1049*495ae853SAndroid Build Coastguard Worker             : 0;
1050*495ae853SAndroid Build Coastguard Worker     i4_top_left_mode =
1051*495ae853SAndroid Build Coastguard Worker         ps_ngbr_avbl->u1_mb_d
1052*495ae853SAndroid Build Coastguard Worker             ? ((ps_proc->s_nbr_info.ps_top_row_mb_info + i4_mb_x - 1)->as_pu->u1_pred_mode !=
1053*495ae853SAndroid Build Coastguard Worker                i4_cmpl_predmode)
1054*495ae853SAndroid Build Coastguard Worker             : 0;
1055*495ae853SAndroid Build Coastguard Worker 
1056*495ae853SAndroid Build Coastguard Worker     if(USE_ILP_MV_IN_ME && ps_ilp_me_cands)
1057*495ae853SAndroid Build Coastguard Worker     {
1058*495ae853SAndroid Build Coastguard Worker         if(ps_ilp_me_cands->u4_num_ilp_mvs >= 2)
1059*495ae853SAndroid Build Coastguard Worker         {
1060*495ae853SAndroid Build Coastguard Worker             b_is_max_mv_diff_lt_4 = isvce_check_max_mv_diff_lt_4(ps_ilp_me_cands, i4_reflist);
1061*495ae853SAndroid Build Coastguard Worker         }
1062*495ae853SAndroid Build Coastguard Worker 
1063*495ae853SAndroid Build Coastguard Worker         /* Taking ILP MV Predictor as one of the candidates */
1064*495ae853SAndroid Build Coastguard Worker         if(ps_ilp_me_cands->u4_num_ilp_mvs < 2 || b_is_max_mv_diff_lt_4)
1065*495ae853SAndroid Build Coastguard Worker         {
1066*495ae853SAndroid Build Coastguard Worker             for(i = 0; i < ps_ilp_me_cands->u4_num_ilp_mvs_incl_nbrs; i++)
1067*495ae853SAndroid Build Coastguard Worker             {
1068*495ae853SAndroid Build Coastguard Worker                 if(((ps_ilp_me_cands->ae_pred_mode[i] == ((PRED_MODE_T) i4_reflist)) ||
1069*495ae853SAndroid Build Coastguard Worker                     ((ps_ilp_me_cands->ae_pred_mode[i] == BI))))
1070*495ae853SAndroid Build Coastguard Worker                 {
1071*495ae853SAndroid Build Coastguard Worker                     isvce_add_me_init_search_cands(&ps_ilp_me_cands->as_mv[i][i4_reflist].s_mv,
1072*495ae853SAndroid Build Coastguard Worker                                                    ps_me_ctxt, i4_reflist, &u4_num_candidates,
1073*495ae853SAndroid Build Coastguard Worker                                                    b_is_max_mv_diff_lt_4);
1074*495ae853SAndroid Build Coastguard Worker                 }
1075*495ae853SAndroid Build Coastguard Worker             }
1076*495ae853SAndroid Build Coastguard Worker         }
1077*495ae853SAndroid Build Coastguard Worker     }
1078*495ae853SAndroid Build Coastguard Worker 
1079*495ae853SAndroid Build Coastguard Worker     /* Taking the Top MV Predictor as one of the candidates     */
1080*495ae853SAndroid Build Coastguard Worker     if(ps_ngbr_avbl->u1_mb_b && i4_top_mode)
1081*495ae853SAndroid Build Coastguard Worker     {
1082*495ae853SAndroid Build Coastguard Worker         isvce_add_me_init_search_cands(ps_top_mv, ps_me_ctxt, i4_reflist, &u4_num_candidates,
1083*495ae853SAndroid Build Coastguard Worker                                        b_is_max_mv_diff_lt_4);
1084*495ae853SAndroid Build Coastguard Worker     }
1085*495ae853SAndroid Build Coastguard Worker 
1086*495ae853SAndroid Build Coastguard Worker     /* Taking the Left MV Predictor as one of the candidates    */
1087*495ae853SAndroid Build Coastguard Worker     if(ps_ngbr_avbl->u1_mb_a && i4_left_mode)
1088*495ae853SAndroid Build Coastguard Worker     {
1089*495ae853SAndroid Build Coastguard Worker         isvce_add_me_init_search_cands(ps_left_mv, ps_me_ctxt, i4_reflist, &u4_num_candidates,
1090*495ae853SAndroid Build Coastguard Worker                                        b_is_max_mv_diff_lt_4);
1091*495ae853SAndroid Build Coastguard Worker     }
1092*495ae853SAndroid Build Coastguard Worker 
1093*495ae853SAndroid Build Coastguard Worker     /********************************************************************/
1094*495ae853SAndroid Build Coastguard Worker     /*                            MV Prediction                         */
1095*495ae853SAndroid Build Coastguard Worker     /********************************************************************/
1096*495ae853SAndroid Build Coastguard Worker     isvce_mv_pred_me(ps_proc, i4_reflist);
1097*495ae853SAndroid Build Coastguard Worker 
1098*495ae853SAndroid Build Coastguard Worker     ps_mb_part->s_mv_pred.i2_mvx = ps_proc->ps_pred_mv[i4_reflist].s_mv.i2_mvx;
1099*495ae853SAndroid Build Coastguard Worker     ps_mb_part->s_mv_pred.i2_mvy = ps_proc->ps_pred_mv[i4_reflist].s_mv.i2_mvy;
1100*495ae853SAndroid Build Coastguard Worker 
1101*495ae853SAndroid Build Coastguard Worker     /* Get the skip motion vector                               */
1102*495ae853SAndroid Build Coastguard Worker     {
1103*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->i4_skip_type =
1104*495ae853SAndroid Build Coastguard Worker             ps_codec->apf_find_skip_params_me[ps_proc->i4_slice_type](ps_proc, i4_reflist);
1105*495ae853SAndroid Build Coastguard Worker 
1106*495ae853SAndroid Build Coastguard Worker         /* Taking the Skip motion vector as one of the candidates   */
1107*495ae853SAndroid Build Coastguard Worker         isvce_add_me_init_search_cands(&ps_proc->ps_skip_mv[i4_reflist].s_mv, ps_me_ctxt,
1108*495ae853SAndroid Build Coastguard Worker                                        i4_reflist, &u4_num_candidates, b_is_max_mv_diff_lt_4);
1109*495ae853SAndroid Build Coastguard Worker 
1110*495ae853SAndroid Build Coastguard Worker         if(ps_proc->i4_slice_type == BSLICE)
1111*495ae853SAndroid Build Coastguard Worker         {
1112*495ae853SAndroid Build Coastguard Worker             /* Taking the temporal Skip motion vector as one of the candidates   */
1113*495ae853SAndroid Build Coastguard Worker             isvce_add_me_init_search_cands(&ps_proc->ps_skip_mv[i4_reflist + 2].s_mv, ps_me_ctxt,
1114*495ae853SAndroid Build Coastguard Worker                                            i4_reflist, &u4_num_candidates, b_is_max_mv_diff_lt_4);
1115*495ae853SAndroid Build Coastguard Worker         }
1116*495ae853SAndroid Build Coastguard Worker     }
1117*495ae853SAndroid Build Coastguard Worker 
1118*495ae853SAndroid Build Coastguard Worker     /* Taking ILP MV Predictor as one of the candidates */
1119*495ae853SAndroid Build Coastguard Worker     if(USE_ILP_MV_IN_ME && ps_ilp_me_cands &&
1120*495ae853SAndroid Build Coastguard Worker        (ps_ilp_me_cands->u4_num_ilp_mvs >= 2 && !b_is_max_mv_diff_lt_4))
1121*495ae853SAndroid Build Coastguard Worker     {
1122*495ae853SAndroid Build Coastguard Worker         for(i = 0; i < ps_ilp_me_cands->u4_num_ilp_mvs_incl_nbrs; i++)
1123*495ae853SAndroid Build Coastguard Worker         {
1124*495ae853SAndroid Build Coastguard Worker             if(((ps_ilp_me_cands->ae_pred_mode[i] == ((PRED_MODE_T) i4_reflist)) ||
1125*495ae853SAndroid Build Coastguard Worker                 ((ps_ilp_me_cands->ae_pred_mode[i] == BI))))
1126*495ae853SAndroid Build Coastguard Worker             {
1127*495ae853SAndroid Build Coastguard Worker                 isvce_add_me_init_search_cands(&ps_ilp_me_cands->as_mv[i][i4_reflist].s_mv,
1128*495ae853SAndroid Build Coastguard Worker                                                ps_me_ctxt, i4_reflist, &u4_num_candidates,
1129*495ae853SAndroid Build Coastguard Worker                                                b_is_max_mv_diff_lt_4);
1130*495ae853SAndroid Build Coastguard Worker             }
1131*495ae853SAndroid Build Coastguard Worker         }
1132*495ae853SAndroid Build Coastguard Worker     }
1133*495ae853SAndroid Build Coastguard Worker 
1134*495ae853SAndroid Build Coastguard Worker     if(ps_ngbr_avbl->u1_mb_b && i4_top_mode)
1135*495ae853SAndroid Build Coastguard Worker     {
1136*495ae853SAndroid Build Coastguard Worker         /* Taking the TopRt MV Predictor as one of the candidates   */
1137*495ae853SAndroid Build Coastguard Worker         if(ps_ngbr_avbl->u1_mb_c && i4_top_right_mode)
1138*495ae853SAndroid Build Coastguard Worker         {
1139*495ae853SAndroid Build Coastguard Worker             isvce_add_me_init_search_cands(ps_top_right_mv, ps_me_ctxt, i4_reflist,
1140*495ae853SAndroid Build Coastguard Worker                                            &u4_num_candidates, b_is_max_mv_diff_lt_4);
1141*495ae853SAndroid Build Coastguard Worker         }
1142*495ae853SAndroid Build Coastguard Worker 
1143*495ae853SAndroid Build Coastguard Worker         /* Taking the TopLt MV Predictor as one of the candidates   */
1144*495ae853SAndroid Build Coastguard Worker         else if(ps_ngbr_avbl->u1_mb_d && i4_top_left_mode)
1145*495ae853SAndroid Build Coastguard Worker         {
1146*495ae853SAndroid Build Coastguard Worker             isvce_add_me_init_search_cands(ps_top_left_mv, ps_me_ctxt, i4_reflist,
1147*495ae853SAndroid Build Coastguard Worker                                            &u4_num_candidates, b_is_max_mv_diff_lt_4);
1148*495ae853SAndroid Build Coastguard Worker         }
1149*495ae853SAndroid Build Coastguard Worker     }
1150*495ae853SAndroid Build Coastguard Worker 
1151*495ae853SAndroid Build Coastguard Worker     /* Taking the Zero motion vector as one of the candidates   */
1152*495ae853SAndroid Build Coastguard Worker     isvce_add_me_init_search_cands(&s_zero_mv, ps_me_ctxt, i4_reflist, &u4_num_candidates,
1153*495ae853SAndroid Build Coastguard Worker                                    b_is_max_mv_diff_lt_4);
1154*495ae853SAndroid Build Coastguard Worker 
1155*495ae853SAndroid Build Coastguard Worker     ASSERT(u4_num_candidates <= MAX_FPEL_SEARCH_CANDIDATES);
1156*495ae853SAndroid Build Coastguard Worker 
1157*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->u4_num_candidates[i4_reflist] = u4_num_candidates;
1158*495ae853SAndroid Build Coastguard Worker }
1159*495ae853SAndroid Build Coastguard Worker 
1160*495ae853SAndroid Build Coastguard Worker /**
1161*495ae853SAndroid Build Coastguard Worker *******************************************************************************
1162*495ae853SAndroid Build Coastguard Worker *
1163*495ae853SAndroid Build Coastguard Worker * @brief The function computes parameters for a PSKIP MB
1164*495ae853SAndroid Build Coastguard Worker *
1165*495ae853SAndroid Build Coastguard Worker * @par Description:
1166*495ae853SAndroid Build Coastguard Worker *  The function updates the skip motion vector and checks if the current
1167*495ae853SAndroid Build Coastguard Worker *  MB can be a skip PSKIP mB or not
1168*495ae853SAndroid Build Coastguard Worker *
1169*495ae853SAndroid Build Coastguard Worker * @param[in] ps_proc
1170*495ae853SAndroid Build Coastguard Worker *  Pointer to process context
1171*495ae853SAndroid Build Coastguard Worker *
1172*495ae853SAndroid Build Coastguard Worker * @param[in] u4_for_me
1173*495ae853SAndroid Build Coastguard Worker *  Flag to indicate function is called for ME or not
1174*495ae853SAndroid Build Coastguard Worker *
1175*495ae853SAndroid Build Coastguard Worker * @param[out] i4_ref_list
1176*495ae853SAndroid Build Coastguard Worker *  Current active refernce list
1177*495ae853SAndroid Build Coastguard Worker *
1178*495ae853SAndroid Build Coastguard Worker * @returns Flag indicating if the current MB can be marked as skip
1179*495ae853SAndroid Build Coastguard Worker *
1180*495ae853SAndroid Build Coastguard Worker * @remarks The code implements the logic as described in sec 8.4.1.2.2 in H264
1181*495ae853SAndroid Build Coastguard Worker *   specification.
1182*495ae853SAndroid Build Coastguard Worker *
1183*495ae853SAndroid Build Coastguard Worker *******************************************************************************
1184*495ae853SAndroid Build Coastguard Worker */
isvce_find_pskip_params(isvce_process_ctxt_t * ps_proc,WORD32 i4_reflist)1185*495ae853SAndroid Build Coastguard Worker WORD32 isvce_find_pskip_params(isvce_process_ctxt_t *ps_proc, WORD32 i4_reflist)
1186*495ae853SAndroid Build Coastguard Worker {
1187*495ae853SAndroid Build Coastguard Worker     /* left mb motion vector */
1188*495ae853SAndroid Build Coastguard Worker     isvce_enc_pu_t *ps_left_mb_pu;
1189*495ae853SAndroid Build Coastguard Worker 
1190*495ae853SAndroid Build Coastguard Worker     /* top mb motion vector */
1191*495ae853SAndroid Build Coastguard Worker     isvce_enc_pu_t *ps_top_mb_pu;
1192*495ae853SAndroid Build Coastguard Worker 
1193*495ae853SAndroid Build Coastguard Worker     /* Skip mv */
1194*495ae853SAndroid Build Coastguard Worker     mv_t *ps_skip_mv = &ps_proc->ps_skip_mv[L0].s_mv;
1195*495ae853SAndroid Build Coastguard Worker 
1196*495ae853SAndroid Build Coastguard Worker     UNUSED(i4_reflist);
1197*495ae853SAndroid Build Coastguard Worker 
1198*495ae853SAndroid Build Coastguard Worker     ps_left_mb_pu = ps_proc->s_nbr_info.ps_left_mb_info->as_pu;
1199*495ae853SAndroid Build Coastguard Worker     ps_top_mb_pu = (ps_proc->s_nbr_info.ps_top_row_mb_info + ps_proc->i4_mb_x)->as_pu;
1200*495ae853SAndroid Build Coastguard Worker 
1201*495ae853SAndroid Build Coastguard Worker     if((!ps_proc->ps_ngbr_avbl->u1_mb_a) || (!ps_proc->ps_ngbr_avbl->u1_mb_b) ||
1202*495ae853SAndroid Build Coastguard Worker        ((ps_left_mb_pu->as_me_info[L0].i1_ref_idx == 0) &&
1203*495ae853SAndroid Build Coastguard Worker         (ps_left_mb_pu->as_me_info[L0].s_mv.i2_mvx == 0) &&
1204*495ae853SAndroid Build Coastguard Worker         (ps_left_mb_pu->as_me_info[L0].s_mv.i2_mvy == 0)) ||
1205*495ae853SAndroid Build Coastguard Worker        ((ps_top_mb_pu->as_me_info[L0].i1_ref_idx == 0) &&
1206*495ae853SAndroid Build Coastguard Worker         (ps_top_mb_pu->as_me_info[L0].s_mv.i2_mvx == 0) &&
1207*495ae853SAndroid Build Coastguard Worker         (ps_top_mb_pu->as_me_info[L0].s_mv.i2_mvy == 0)))
1208*495ae853SAndroid Build Coastguard Worker 
1209*495ae853SAndroid Build Coastguard Worker     {
1210*495ae853SAndroid Build Coastguard Worker         ps_skip_mv->i2_mvx = 0;
1211*495ae853SAndroid Build Coastguard Worker         ps_skip_mv->i2_mvy = 0;
1212*495ae853SAndroid Build Coastguard Worker     }
1213*495ae853SAndroid Build Coastguard Worker     else
1214*495ae853SAndroid Build Coastguard Worker     {
1215*495ae853SAndroid Build Coastguard Worker         ps_skip_mv->i2_mvx = ps_proc->ps_pred_mv[L0].s_mv.i2_mvx;
1216*495ae853SAndroid Build Coastguard Worker         ps_skip_mv->i2_mvy = ps_proc->ps_pred_mv[L0].s_mv.i2_mvy;
1217*495ae853SAndroid Build Coastguard Worker     }
1218*495ae853SAndroid Build Coastguard Worker 
1219*495ae853SAndroid Build Coastguard Worker     if((ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvx == ps_skip_mv->i2_mvx) &&
1220*495ae853SAndroid Build Coastguard Worker        (ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvy == ps_skip_mv->i2_mvy))
1221*495ae853SAndroid Build Coastguard Worker     {
1222*495ae853SAndroid Build Coastguard Worker         return 1;
1223*495ae853SAndroid Build Coastguard Worker     }
1224*495ae853SAndroid Build Coastguard Worker 
1225*495ae853SAndroid Build Coastguard Worker     return 0;
1226*495ae853SAndroid Build Coastguard Worker }
1227*495ae853SAndroid Build Coastguard Worker 
1228*495ae853SAndroid Build Coastguard Worker /**
1229*495ae853SAndroid Build Coastguard Worker *******************************************************************************
1230*495ae853SAndroid Build Coastguard Worker *
1231*495ae853SAndroid Build Coastguard Worker * @brief The function computes parameters for a PSKIP MB
1232*495ae853SAndroid Build Coastguard Worker *
1233*495ae853SAndroid Build Coastguard Worker * @par Description:
1234*495ae853SAndroid Build Coastguard Worker *  The function updates the skip motion vector and checks if the current
1235*495ae853SAndroid Build Coastguard Worker *  MB can be a skip PSKIP mB or not
1236*495ae853SAndroid Build Coastguard Worker *
1237*495ae853SAndroid Build Coastguard Worker * @param[in] ps_proc
1238*495ae853SAndroid Build Coastguard Worker *  Pointer to process context
1239*495ae853SAndroid Build Coastguard Worker *
1240*495ae853SAndroid Build Coastguard Worker * @param[in] u4_for_me
1241*495ae853SAndroid Build Coastguard Worker *  Flag to dincate fucntion is called for ME or not
1242*495ae853SAndroid Build Coastguard Worker *
1243*495ae853SAndroid Build Coastguard Worker * @param[out] i4_ref_list
1244*495ae853SAndroid Build Coastguard Worker *  Current active refernce list
1245*495ae853SAndroid Build Coastguard Worker *
1246*495ae853SAndroid Build Coastguard Worker * @returns Flag indicating if the current MB can be marked as skip
1247*495ae853SAndroid Build Coastguard Worker *
1248*495ae853SAndroid Build Coastguard Worker * @remarks The code implements the logic as described in sec 8.4.1.2.2 in H264
1249*495ae853SAndroid Build Coastguard Worker *   specification.
1250*495ae853SAndroid Build Coastguard Worker *
1251*495ae853SAndroid Build Coastguard Worker *******************************************************************************
1252*495ae853SAndroid Build Coastguard Worker */
isvce_find_pskip_params_me(isvce_process_ctxt_t * ps_proc,WORD32 i4_reflist)1253*495ae853SAndroid Build Coastguard Worker WORD32 isvce_find_pskip_params_me(isvce_process_ctxt_t *ps_proc, WORD32 i4_reflist)
1254*495ae853SAndroid Build Coastguard Worker {
1255*495ae853SAndroid Build Coastguard Worker     /* left mb motion vector */
1256*495ae853SAndroid Build Coastguard Worker     isvce_enc_pu_t *ps_left_mb_pu;
1257*495ae853SAndroid Build Coastguard Worker 
1258*495ae853SAndroid Build Coastguard Worker     /* top mb motion vector */
1259*495ae853SAndroid Build Coastguard Worker     isvce_enc_pu_t *ps_top_mb_pu;
1260*495ae853SAndroid Build Coastguard Worker 
1261*495ae853SAndroid Build Coastguard Worker     /* Skip mv */
1262*495ae853SAndroid Build Coastguard Worker     mv_t *ps_skip_mv = &ps_proc->ps_skip_mv[L0].s_mv;
1263*495ae853SAndroid Build Coastguard Worker 
1264*495ae853SAndroid Build Coastguard Worker     UNUSED(i4_reflist);
1265*495ae853SAndroid Build Coastguard Worker 
1266*495ae853SAndroid Build Coastguard Worker     ps_left_mb_pu = ps_proc->s_nbr_info.ps_left_mb_info->as_pu;
1267*495ae853SAndroid Build Coastguard Worker     ps_top_mb_pu = (ps_proc->s_nbr_info.ps_top_row_mb_info + ps_proc->i4_mb_x)->as_pu;
1268*495ae853SAndroid Build Coastguard Worker 
1269*495ae853SAndroid Build Coastguard Worker     if((!ps_proc->ps_ngbr_avbl->u1_mb_a) || (!ps_proc->ps_ngbr_avbl->u1_mb_b) ||
1270*495ae853SAndroid Build Coastguard Worker        ((ps_left_mb_pu->as_me_info[L0].i1_ref_idx == 0) &&
1271*495ae853SAndroid Build Coastguard Worker         (ps_left_mb_pu->as_me_info[L0].s_mv.i2_mvx == 0) &&
1272*495ae853SAndroid Build Coastguard Worker         (ps_left_mb_pu->as_me_info[L0].s_mv.i2_mvy == 0)) ||
1273*495ae853SAndroid Build Coastguard Worker        ((ps_top_mb_pu->as_me_info[L0].i1_ref_idx == 0) &&
1274*495ae853SAndroid Build Coastguard Worker         (ps_top_mb_pu->as_me_info[L0].s_mv.i2_mvx == 0) &&
1275*495ae853SAndroid Build Coastguard Worker         (ps_top_mb_pu->as_me_info[L0].s_mv.i2_mvy == 0)))
1276*495ae853SAndroid Build Coastguard Worker 
1277*495ae853SAndroid Build Coastguard Worker     {
1278*495ae853SAndroid Build Coastguard Worker         ps_skip_mv->i2_mvx = 0;
1279*495ae853SAndroid Build Coastguard Worker         ps_skip_mv->i2_mvy = 0;
1280*495ae853SAndroid Build Coastguard Worker     }
1281*495ae853SAndroid Build Coastguard Worker     else
1282*495ae853SAndroid Build Coastguard Worker     {
1283*495ae853SAndroid Build Coastguard Worker         ps_skip_mv->i2_mvx = ps_proc->ps_pred_mv[L0].s_mv.i2_mvx;
1284*495ae853SAndroid Build Coastguard Worker         ps_skip_mv->i2_mvy = ps_proc->ps_pred_mv[L0].s_mv.i2_mvy;
1285*495ae853SAndroid Build Coastguard Worker     }
1286*495ae853SAndroid Build Coastguard Worker 
1287*495ae853SAndroid Build Coastguard Worker     return L0;
1288*495ae853SAndroid Build Coastguard Worker }
1289*495ae853SAndroid Build Coastguard Worker 
1290*495ae853SAndroid Build Coastguard Worker /**
1291*495ae853SAndroid Build Coastguard Worker *******************************************************************************
1292*495ae853SAndroid Build Coastguard Worker *
1293*495ae853SAndroid Build Coastguard Worker * @brief motion vector predictor
1294*495ae853SAndroid Build Coastguard Worker *
1295*495ae853SAndroid Build Coastguard Worker * @par Description:
1296*495ae853SAndroid Build Coastguard Worker *  The routine calculates the motion vector predictor for a given block,
1297*495ae853SAndroid Build Coastguard Worker *  given the candidate MV predictors.
1298*495ae853SAndroid Build Coastguard Worker *
1299*495ae853SAndroid Build Coastguard Worker * @param[in] ps_left_mb_pu
1300*495ae853SAndroid Build Coastguard Worker *  pointer to left mb motion vector info
1301*495ae853SAndroid Build Coastguard Worker *
1302*495ae853SAndroid Build Coastguard Worker * @param[in] ps_top_row_pu
1303*495ae853SAndroid Build Coastguard Worker *  pointer to top & top right mb motion vector info
1304*495ae853SAndroid Build Coastguard Worker *
1305*495ae853SAndroid Build Coastguard Worker * @param[out] ps_pred_mv
1306*495ae853SAndroid Build Coastguard Worker *  pointer to candidate predictors for the current block
1307*495ae853SAndroid Build Coastguard Worker *
1308*495ae853SAndroid Build Coastguard Worker * @returns  The x & y components of the MV predictor.
1309*495ae853SAndroid Build Coastguard Worker *
1310*495ae853SAndroid Build Coastguard Worker * @remarks The code implements the logic as described in sec 8.4.1.3 in H264
1311*495ae853SAndroid Build Coastguard Worker *   specification.
1312*495ae853SAndroid Build Coastguard Worker *   Assumptions : 1. Assumes Single reference frame
1313*495ae853SAndroid Build Coastguard Worker *                 2. Assumes Only partition of size 16x16
1314*495ae853SAndroid Build Coastguard Worker *
1315*495ae853SAndroid Build Coastguard Worker *******************************************************************************
1316*495ae853SAndroid Build Coastguard Worker */
isvce_get_mv_predictor(isvce_enc_pu_mv_t * ps_pred_mv,isvce_enc_pu_mv_t * ps_neig_mv,WORD32 pred_algo)1317*495ae853SAndroid Build Coastguard Worker void isvce_get_mv_predictor(isvce_enc_pu_mv_t *ps_pred_mv, isvce_enc_pu_mv_t *ps_neig_mv,
1318*495ae853SAndroid Build Coastguard Worker                             WORD32 pred_algo)
1319*495ae853SAndroid Build Coastguard Worker {
1320*495ae853SAndroid Build Coastguard Worker     switch(pred_algo)
1321*495ae853SAndroid Build Coastguard Worker     {
1322*495ae853SAndroid Build Coastguard Worker         case 0:
1323*495ae853SAndroid Build Coastguard Worker             /* left */
1324*495ae853SAndroid Build Coastguard Worker             ps_pred_mv->s_mv.i2_mvx = ps_neig_mv[0].s_mv.i2_mvx;
1325*495ae853SAndroid Build Coastguard Worker             ps_pred_mv->s_mv.i2_mvy = ps_neig_mv[0].s_mv.i2_mvy;
1326*495ae853SAndroid Build Coastguard Worker             break;
1327*495ae853SAndroid Build Coastguard Worker         case 1:
1328*495ae853SAndroid Build Coastguard Worker             /* top */
1329*495ae853SAndroid Build Coastguard Worker             ps_pred_mv->s_mv.i2_mvx = ps_neig_mv[1].s_mv.i2_mvx;
1330*495ae853SAndroid Build Coastguard Worker             ps_pred_mv->s_mv.i2_mvy = ps_neig_mv[1].s_mv.i2_mvy;
1331*495ae853SAndroid Build Coastguard Worker             break;
1332*495ae853SAndroid Build Coastguard Worker         case 2:
1333*495ae853SAndroid Build Coastguard Worker             /* top right */
1334*495ae853SAndroid Build Coastguard Worker             ps_pred_mv->s_mv.i2_mvx = ps_neig_mv[2].s_mv.i2_mvx;
1335*495ae853SAndroid Build Coastguard Worker             ps_pred_mv->s_mv.i2_mvy = ps_neig_mv[2].s_mv.i2_mvy;
1336*495ae853SAndroid Build Coastguard Worker             break;
1337*495ae853SAndroid Build Coastguard Worker         case 3:
1338*495ae853SAndroid Build Coastguard Worker             /* median */
1339*495ae853SAndroid Build Coastguard Worker             MEDIAN(ps_neig_mv[0].s_mv.i2_mvx, ps_neig_mv[1].s_mv.i2_mvx, ps_neig_mv[2].s_mv.i2_mvx,
1340*495ae853SAndroid Build Coastguard Worker                    ps_pred_mv->s_mv.i2_mvx);
1341*495ae853SAndroid Build Coastguard Worker             MEDIAN(ps_neig_mv[0].s_mv.i2_mvy, ps_neig_mv[1].s_mv.i2_mvy, ps_neig_mv[2].s_mv.i2_mvy,
1342*495ae853SAndroid Build Coastguard Worker                    ps_pred_mv->s_mv.i2_mvy);
1343*495ae853SAndroid Build Coastguard Worker 
1344*495ae853SAndroid Build Coastguard Worker             break;
1345*495ae853SAndroid Build Coastguard Worker         default:
1346*495ae853SAndroid Build Coastguard Worker             break;
1347*495ae853SAndroid Build Coastguard Worker     }
1348*495ae853SAndroid Build Coastguard Worker }
1349*495ae853SAndroid Build Coastguard Worker 
1350*495ae853SAndroid Build Coastguard Worker /**
1351*495ae853SAndroid Build Coastguard Worker *******************************************************************************
1352*495ae853SAndroid Build Coastguard Worker *
1353*495ae853SAndroid Build Coastguard Worker * @brief This function performs MV prediction
1354*495ae853SAndroid Build Coastguard Worker *
1355*495ae853SAndroid Build Coastguard Worker * @par Description:
1356*495ae853SAndroid Build Coastguard Worker *
1357*495ae853SAndroid Build Coastguard Worker * @param[in] ps_proc
1358*495ae853SAndroid Build Coastguard Worker *  Process context corresponding to the job
1359*495ae853SAndroid Build Coastguard Worker *
1360*495ae853SAndroid Build Coastguard Worker * @returns  none
1361*495ae853SAndroid Build Coastguard Worker *
1362*495ae853SAndroid Build Coastguard Worker * @remarks none
1363*495ae853SAndroid Build Coastguard Worker *  This function will update the MB availability since intra inter decision
1364*495ae853SAndroid Build Coastguard Worker *  should be done before the call
1365*495ae853SAndroid Build Coastguard Worker *
1366*495ae853SAndroid Build Coastguard Worker *******************************************************************************
1367*495ae853SAndroid Build Coastguard Worker */
isvce_mv_pred(isvce_process_ctxt_t * ps_proc,WORD32 i4_slice_type)1368*495ae853SAndroid Build Coastguard Worker void isvce_mv_pred(isvce_process_ctxt_t *ps_proc, WORD32 i4_slice_type)
1369*495ae853SAndroid Build Coastguard Worker {
1370*495ae853SAndroid Build Coastguard Worker     isvce_enc_pu_mv_t as_pu_mv[3];
1371*495ae853SAndroid Build Coastguard Worker 
1372*495ae853SAndroid Build Coastguard Worker     UWORD8 u1_reflist, u1_cmpl_predmode;
1373*495ae853SAndroid Build Coastguard Worker     WORD32 i;
1374*495ae853SAndroid Build Coastguard Worker 
1375*495ae853SAndroid Build Coastguard Worker     isvce_enc_pu_mv_t *ps_pred_mv = ps_proc->ps_pred_mv;
1376*495ae853SAndroid Build Coastguard Worker     isvce_enc_pu_mv_t s_default_mv_info = {{0, 0}, -1};
1377*495ae853SAndroid Build Coastguard Worker     block_neighbors_t *ps_ngbr_avbl = ps_proc->ps_ngbr_avbl;
1378*495ae853SAndroid Build Coastguard Worker     isvce_mb_info_t *ps_top_mb = ps_proc->s_nbr_info.ps_top_row_mb_info + ps_proc->i4_mb_x;
1379*495ae853SAndroid Build Coastguard Worker     isvce_mb_info_t *ps_top_left_mb = ps_top_mb - 1;
1380*495ae853SAndroid Build Coastguard Worker     isvce_mb_info_t *ps_top_right_mb = ps_top_mb + 1;
1381*495ae853SAndroid Build Coastguard Worker     isvce_mb_info_t *ps_left_mb = ps_proc->s_nbr_info.ps_left_mb_info;
1382*495ae853SAndroid Build Coastguard Worker 
1383*495ae853SAndroid Build Coastguard Worker     UWORD8 u1_left_is_intra = ps_left_mb->u1_is_intra;
1384*495ae853SAndroid Build Coastguard Worker     UWORD8 u1_num_ref_lists = (i4_slice_type == PSLICE) ? 1 : 2;
1385*495ae853SAndroid Build Coastguard Worker 
1386*495ae853SAndroid Build Coastguard Worker     for(u1_reflist = 0; u1_reflist < u1_num_ref_lists; u1_reflist++)
1387*495ae853SAndroid Build Coastguard Worker     {
1388*495ae853SAndroid Build Coastguard Worker         WORD8 i1_cur_ref_idx = 0;
1389*495ae853SAndroid Build Coastguard Worker 
1390*495ae853SAndroid Build Coastguard Worker         WORD32 pred_algo = 3, a, b, c;
1391*495ae853SAndroid Build Coastguard Worker 
1392*495ae853SAndroid Build Coastguard Worker         for(i = 0; i < 3; i++)
1393*495ae853SAndroid Build Coastguard Worker         {
1394*495ae853SAndroid Build Coastguard Worker             as_pu_mv[i] = s_default_mv_info;
1395*495ae853SAndroid Build Coastguard Worker         }
1396*495ae853SAndroid Build Coastguard Worker 
1397*495ae853SAndroid Build Coastguard Worker         u1_cmpl_predmode = (u1_reflist == 0) ? L1 : L0;
1398*495ae853SAndroid Build Coastguard Worker 
1399*495ae853SAndroid Build Coastguard Worker         /* Before performing mv prediction prepare the ngbr information and
1400*495ae853SAndroid Build Coastguard Worker          * reset motion vectors basing on their availability */
1401*495ae853SAndroid Build Coastguard Worker         if(ps_ngbr_avbl->u1_mb_a && (u1_left_is_intra != 1) &&
1402*495ae853SAndroid Build Coastguard Worker            (ps_left_mb->as_pu->u1_pred_mode != u1_cmpl_predmode))
1403*495ae853SAndroid Build Coastguard Worker         {
1404*495ae853SAndroid Build Coastguard Worker             /* left mv */
1405*495ae853SAndroid Build Coastguard Worker             as_pu_mv[0].s_mv = ps_left_mb->as_pu->as_me_info[u1_reflist].s_mv;
1406*495ae853SAndroid Build Coastguard Worker             as_pu_mv[0].i1_ref_idx = ps_left_mb->as_pu->as_me_info[u1_reflist].i1_ref_idx;
1407*495ae853SAndroid Build Coastguard Worker 
1408*495ae853SAndroid Build Coastguard Worker             /* Only left available */
1409*495ae853SAndroid Build Coastguard Worker             if(!ps_ngbr_avbl->u1_mb_b && !ps_ngbr_avbl->u1_mb_c && !ps_ngbr_avbl->u1_mb_d)
1410*495ae853SAndroid Build Coastguard Worker             {
1411*495ae853SAndroid Build Coastguard Worker                 as_pu_mv[1].s_mv = ps_left_mb->as_pu->as_me_info[u1_reflist].s_mv;
1412*495ae853SAndroid Build Coastguard Worker                 as_pu_mv[1].i1_ref_idx = ps_left_mb->as_pu->as_me_info[u1_reflist].i1_ref_idx;
1413*495ae853SAndroid Build Coastguard Worker 
1414*495ae853SAndroid Build Coastguard Worker                 as_pu_mv[2].s_mv = ps_left_mb->as_pu->as_me_info[u1_reflist].s_mv;
1415*495ae853SAndroid Build Coastguard Worker                 as_pu_mv[2].i1_ref_idx = ps_left_mb->as_pu->as_me_info[u1_reflist].i1_ref_idx;
1416*495ae853SAndroid Build Coastguard Worker             }
1417*495ae853SAndroid Build Coastguard Worker         }
1418*495ae853SAndroid Build Coastguard Worker         if(ps_ngbr_avbl->u1_mb_b && !ps_top_mb->u1_is_intra &&
1419*495ae853SAndroid Build Coastguard Worker            (ps_top_mb->as_pu[0].u1_pred_mode != u1_cmpl_predmode))
1420*495ae853SAndroid Build Coastguard Worker         {
1421*495ae853SAndroid Build Coastguard Worker             /* top mv */
1422*495ae853SAndroid Build Coastguard Worker             as_pu_mv[1].s_mv = ps_top_mb->as_pu[0].as_me_info[u1_reflist].s_mv;
1423*495ae853SAndroid Build Coastguard Worker             as_pu_mv[1].i1_ref_idx = ps_top_mb->as_pu[0].as_me_info[u1_reflist].i1_ref_idx;
1424*495ae853SAndroid Build Coastguard Worker         }
1425*495ae853SAndroid Build Coastguard Worker 
1426*495ae853SAndroid Build Coastguard Worker         if(!ps_ngbr_avbl->u1_mb_c)
1427*495ae853SAndroid Build Coastguard Worker         {
1428*495ae853SAndroid Build Coastguard Worker             /* top right mv - When top right partition is not available for
1429*495ae853SAndroid Build Coastguard Worker              * prediction if top left is available use it for prediction else
1430*495ae853SAndroid Build Coastguard Worker              * set the mv information to -1 and (0, 0)
1431*495ae853SAndroid Build Coastguard Worker              * */
1432*495ae853SAndroid Build Coastguard Worker             if(ps_ngbr_avbl->u1_mb_d && !ps_top_left_mb->u1_is_intra &&
1433*495ae853SAndroid Build Coastguard Worker                (ps_top_left_mb->as_pu->u1_pred_mode != u1_cmpl_predmode))
1434*495ae853SAndroid Build Coastguard Worker             {
1435*495ae853SAndroid Build Coastguard Worker                 as_pu_mv[2].s_mv = ps_top_left_mb->as_pu[0].as_me_info[u1_reflist].s_mv;
1436*495ae853SAndroid Build Coastguard Worker                 as_pu_mv[2].i1_ref_idx = ps_top_left_mb->as_pu[0].as_me_info[u1_reflist].i1_ref_idx;
1437*495ae853SAndroid Build Coastguard Worker             }
1438*495ae853SAndroid Build Coastguard Worker         }
1439*495ae853SAndroid Build Coastguard Worker         else if(ps_top_right_mb->as_pu->u1_pred_mode != u1_cmpl_predmode &&
1440*495ae853SAndroid Build Coastguard Worker                 !ps_top_right_mb->u1_is_intra)
1441*495ae853SAndroid Build Coastguard Worker         {
1442*495ae853SAndroid Build Coastguard Worker             as_pu_mv[2].s_mv = ps_top_right_mb->as_pu->as_me_info[u1_reflist].s_mv;
1443*495ae853SAndroid Build Coastguard Worker             as_pu_mv[2].i1_ref_idx = ps_top_right_mb->as_pu->as_me_info[u1_reflist].i1_ref_idx;
1444*495ae853SAndroid Build Coastguard Worker         }
1445*495ae853SAndroid Build Coastguard Worker 
1446*495ae853SAndroid Build Coastguard Worker         /* If only one of the candidate blocks has a reference frame equal to
1447*495ae853SAndroid Build Coastguard Worker          * the current block then use the same block as the final predictor */
1448*495ae853SAndroid Build Coastguard Worker         a = (as_pu_mv[0].i1_ref_idx == i1_cur_ref_idx) ? 0 : -1;
1449*495ae853SAndroid Build Coastguard Worker         b = (as_pu_mv[1].i1_ref_idx == i1_cur_ref_idx) ? 0 : -1;
1450*495ae853SAndroid Build Coastguard Worker         c = (as_pu_mv[2].i1_ref_idx == i1_cur_ref_idx) ? 0 : -1;
1451*495ae853SAndroid Build Coastguard Worker         if(a == 0 && b == -1 && c == -1)
1452*495ae853SAndroid Build Coastguard Worker             pred_algo = 0; /* LEFT */
1453*495ae853SAndroid Build Coastguard Worker         else if(a == -1 && b == 0 && c == -1)
1454*495ae853SAndroid Build Coastguard Worker             pred_algo = 1; /* TOP */
1455*495ae853SAndroid Build Coastguard Worker         else if(a == -1 && b == -1 && c == 0)
1456*495ae853SAndroid Build Coastguard Worker             pred_algo = 2;
1457*495ae853SAndroid Build Coastguard Worker 
1458*495ae853SAndroid Build Coastguard Worker         isvce_get_mv_predictor(&ps_pred_mv[u1_reflist], &as_pu_mv[0], pred_algo);
1459*495ae853SAndroid Build Coastguard Worker 
1460*495ae853SAndroid Build Coastguard Worker         ps_pred_mv[u1_reflist].i1_ref_idx = i1_cur_ref_idx;
1461*495ae853SAndroid Build Coastguard Worker     }
1462*495ae853SAndroid Build Coastguard Worker }
1463*495ae853SAndroid Build Coastguard Worker 
1464*495ae853SAndroid Build Coastguard Worker /**
1465*495ae853SAndroid Build Coastguard Worker *******************************************************************************
1466*495ae853SAndroid Build Coastguard Worker *
1467*495ae853SAndroid Build Coastguard Worker * @brief This function approximates Pred. MV
1468*495ae853SAndroid Build Coastguard Worker *
1469*495ae853SAndroid Build Coastguard Worker * @par Description:
1470*495ae853SAndroid Build Coastguard Worker *
1471*495ae853SAndroid Build Coastguard Worker * @param[in] ps_proc
1472*495ae853SAndroid Build Coastguard Worker *  Process context corresponding to the job
1473*495ae853SAndroid Build Coastguard Worker *
1474*495ae853SAndroid Build Coastguard Worker * @returns  none
1475*495ae853SAndroid Build Coastguard Worker *
1476*495ae853SAndroid Build Coastguard Worker * @remarks none
1477*495ae853SAndroid Build Coastguard Worker *  Motion estimation happens at nmb level. For cost calculations, mv is appro
1478*495ae853SAndroid Build Coastguard Worker *  ximated using this function
1479*495ae853SAndroid Build Coastguard Worker *
1480*495ae853SAndroid Build Coastguard Worker *******************************************************************************
1481*495ae853SAndroid Build Coastguard Worker */
isvce_mv_pred_me(isvce_process_ctxt_t * ps_proc,WORD32 i4_ref_list)1482*495ae853SAndroid Build Coastguard Worker void isvce_mv_pred_me(isvce_process_ctxt_t *ps_proc, WORD32 i4_ref_list)
1483*495ae853SAndroid Build Coastguard Worker {
1484*495ae853SAndroid Build Coastguard Worker     isvce_enc_pu_mv_t as_pu_mv[3];
1485*495ae853SAndroid Build Coastguard Worker 
1486*495ae853SAndroid Build Coastguard Worker     WORD32 i, a, b, c;
1487*495ae853SAndroid Build Coastguard Worker 
1488*495ae853SAndroid Build Coastguard Worker     isvce_enc_pu_mv_t *ps_pred_mv = ps_proc->ps_pred_mv;
1489*495ae853SAndroid Build Coastguard Worker     isvce_enc_pu_mv_t s_default_mv_info = {{0, 0}, -1};
1490*495ae853SAndroid Build Coastguard Worker     block_neighbors_t *ps_ngbr_avbl = ps_proc->ps_ngbr_avbl;
1491*495ae853SAndroid Build Coastguard Worker     isvce_mb_info_t *ps_top_mb = ps_proc->s_nbr_info.ps_top_row_mb_info + ps_proc->i4_mb_x;
1492*495ae853SAndroid Build Coastguard Worker     isvce_mb_info_t *ps_top_left_mb = ps_top_mb - 1;
1493*495ae853SAndroid Build Coastguard Worker     isvce_mb_info_t *ps_top_right_mb = ps_top_mb + 1;
1494*495ae853SAndroid Build Coastguard Worker     isvce_mb_info_t *ps_left_mb = ps_proc->s_nbr_info.ps_left_mb_info;
1495*495ae853SAndroid Build Coastguard Worker 
1496*495ae853SAndroid Build Coastguard Worker     WORD8 i1_cur_ref_idx = 0;
1497*495ae853SAndroid Build Coastguard Worker     WORD32 i4_cmpl_predmode = (i4_ref_list == 0) ? L1 : L0;
1498*495ae853SAndroid Build Coastguard Worker     WORD32 pred_algo = 3;
1499*495ae853SAndroid Build Coastguard Worker 
1500*495ae853SAndroid Build Coastguard Worker     for(i = 0; i < 3; i++)
1501*495ae853SAndroid Build Coastguard Worker     {
1502*495ae853SAndroid Build Coastguard Worker         as_pu_mv[i] = s_default_mv_info;
1503*495ae853SAndroid Build Coastguard Worker     }
1504*495ae853SAndroid Build Coastguard Worker 
1505*495ae853SAndroid Build Coastguard Worker     if(ps_ngbr_avbl->u1_mb_a && !ps_left_mb->u1_is_intra &&
1506*495ae853SAndroid Build Coastguard Worker        (ps_left_mb->as_pu->u1_pred_mode != i4_cmpl_predmode))
1507*495ae853SAndroid Build Coastguard Worker     {
1508*495ae853SAndroid Build Coastguard Worker         /* left mv */
1509*495ae853SAndroid Build Coastguard Worker         as_pu_mv[0].s_mv = ps_left_mb->as_pu->as_me_info[i4_ref_list].s_mv;
1510*495ae853SAndroid Build Coastguard Worker         as_pu_mv[0].i1_ref_idx = ps_left_mb->as_pu->as_me_info[i4_ref_list].i1_ref_idx;
1511*495ae853SAndroid Build Coastguard Worker 
1512*495ae853SAndroid Build Coastguard Worker         /* Only left available */
1513*495ae853SAndroid Build Coastguard Worker         if(!ps_ngbr_avbl->u1_mb_b && !ps_ngbr_avbl->u1_mb_c && !ps_ngbr_avbl->u1_mb_d)
1514*495ae853SAndroid Build Coastguard Worker         {
1515*495ae853SAndroid Build Coastguard Worker             as_pu_mv[1].s_mv = ps_left_mb->as_pu->as_me_info[i4_ref_list].s_mv;
1516*495ae853SAndroid Build Coastguard Worker             as_pu_mv[1].i1_ref_idx = ps_left_mb->as_pu->as_me_info[i4_ref_list].i1_ref_idx;
1517*495ae853SAndroid Build Coastguard Worker 
1518*495ae853SAndroid Build Coastguard Worker             as_pu_mv[2].s_mv = ps_left_mb->as_pu->as_me_info[i4_ref_list].s_mv;
1519*495ae853SAndroid Build Coastguard Worker             as_pu_mv[2].i1_ref_idx = ps_left_mb->as_pu->as_me_info[i4_ref_list].i1_ref_idx;
1520*495ae853SAndroid Build Coastguard Worker         }
1521*495ae853SAndroid Build Coastguard Worker     }
1522*495ae853SAndroid Build Coastguard Worker     if(ps_ngbr_avbl->u1_mb_b && !ps_top_mb->u1_is_intra &&
1523*495ae853SAndroid Build Coastguard Worker        (ps_top_mb->as_pu->u1_pred_mode != i4_cmpl_predmode))
1524*495ae853SAndroid Build Coastguard Worker     {
1525*495ae853SAndroid Build Coastguard Worker         /* top mv */
1526*495ae853SAndroid Build Coastguard Worker         as_pu_mv[1].s_mv = ps_top_mb->as_pu->as_me_info[i4_ref_list].s_mv;
1527*495ae853SAndroid Build Coastguard Worker         as_pu_mv[1].i1_ref_idx = ps_top_mb->as_pu->as_me_info[i4_ref_list].i1_ref_idx;
1528*495ae853SAndroid Build Coastguard Worker     }
1529*495ae853SAndroid Build Coastguard Worker     if(!ps_ngbr_avbl->u1_mb_c)
1530*495ae853SAndroid Build Coastguard Worker     {
1531*495ae853SAndroid Build Coastguard Worker         /* top right mv - When top right partition is not available for
1532*495ae853SAndroid Build Coastguard Worker          * prediction if top left is available use it for prediction else
1533*495ae853SAndroid Build Coastguard Worker          * set the mv information to -1 and (0, 0)
1534*495ae853SAndroid Build Coastguard Worker          * */
1535*495ae853SAndroid Build Coastguard Worker         if(ps_ngbr_avbl->u1_mb_d && !ps_top_left_mb->u1_is_intra &&
1536*495ae853SAndroid Build Coastguard Worker            (ps_top_left_mb->as_pu->u1_pred_mode != i4_cmpl_predmode))
1537*495ae853SAndroid Build Coastguard Worker         {
1538*495ae853SAndroid Build Coastguard Worker             as_pu_mv[2].s_mv = ps_top_left_mb->as_pu->as_me_info[i4_ref_list].s_mv;
1539*495ae853SAndroid Build Coastguard Worker             as_pu_mv[2].i1_ref_idx = ps_top_left_mb->as_pu->as_me_info[i4_ref_list].i1_ref_idx;
1540*495ae853SAndroid Build Coastguard Worker         }
1541*495ae853SAndroid Build Coastguard Worker     }
1542*495ae853SAndroid Build Coastguard Worker     else if(ps_top_right_mb->as_pu->u1_pred_mode != i4_cmpl_predmode &&
1543*495ae853SAndroid Build Coastguard Worker             !ps_top_right_mb->u1_is_intra)
1544*495ae853SAndroid Build Coastguard Worker     {
1545*495ae853SAndroid Build Coastguard Worker         as_pu_mv[2].s_mv = ps_top_right_mb->as_pu->as_me_info[i4_ref_list].s_mv;
1546*495ae853SAndroid Build Coastguard Worker         as_pu_mv[2].i1_ref_idx = ps_top_right_mb->as_pu->as_me_info[i4_ref_list].i1_ref_idx;
1547*495ae853SAndroid Build Coastguard Worker     }
1548*495ae853SAndroid Build Coastguard Worker 
1549*495ae853SAndroid Build Coastguard Worker     /* If only one of the candidate blocks has a reference frame equal to
1550*495ae853SAndroid Build Coastguard Worker      * the current block then use the same block as the final predictor */
1551*495ae853SAndroid Build Coastguard Worker     a = (as_pu_mv[0].i1_ref_idx == i1_cur_ref_idx) ? 0 : -1;
1552*495ae853SAndroid Build Coastguard Worker     b = (as_pu_mv[1].i1_ref_idx == i1_cur_ref_idx) ? 0 : -1;
1553*495ae853SAndroid Build Coastguard Worker     c = (as_pu_mv[2].i1_ref_idx == i1_cur_ref_idx) ? 0 : -1;
1554*495ae853SAndroid Build Coastguard Worker 
1555*495ae853SAndroid Build Coastguard Worker     if(a == 0 && b == -1 && c == -1)
1556*495ae853SAndroid Build Coastguard Worker         pred_algo = 0; /* LEFT */
1557*495ae853SAndroid Build Coastguard Worker     else if(a == -1 && b == 0 && c == -1)
1558*495ae853SAndroid Build Coastguard Worker         pred_algo = 1; /* TOP */
1559*495ae853SAndroid Build Coastguard Worker     else if(a == -1 && b == -1 && c == 0)
1560*495ae853SAndroid Build Coastguard Worker         pred_algo = 2;
1561*495ae853SAndroid Build Coastguard Worker 
1562*495ae853SAndroid Build Coastguard Worker     isvce_get_mv_predictor(&ps_pred_mv[i4_ref_list], &as_pu_mv[0], pred_algo);
1563*495ae853SAndroid Build Coastguard Worker }
1564*495ae853SAndroid Build Coastguard Worker 
1565*495ae853SAndroid Build Coastguard Worker /**
1566*495ae853SAndroid Build Coastguard Worker *******************************************************************************
1567*495ae853SAndroid Build Coastguard Worker *
1568*495ae853SAndroid Build Coastguard Worker * @brief This function initializes me ctxt
1569*495ae853SAndroid Build Coastguard Worker *
1570*495ae853SAndroid Build Coastguard Worker * @par Description:
1571*495ae853SAndroid Build Coastguard Worker *  Before dispatching the current job to me thread, the me context associated
1572*495ae853SAndroid Build Coastguard Worker *  with the job is initialized.
1573*495ae853SAndroid Build Coastguard Worker *
1574*495ae853SAndroid Build Coastguard Worker * @param[in] ps_proc
1575*495ae853SAndroid Build Coastguard Worker *  Process context corresponding to the job
1576*495ae853SAndroid Build Coastguard Worker *
1577*495ae853SAndroid Build Coastguard Worker * @returns  none
1578*495ae853SAndroid Build Coastguard Worker *
1579*495ae853SAndroid Build Coastguard Worker * @remarks none
1580*495ae853SAndroid Build Coastguard Worker *
1581*495ae853SAndroid Build Coastguard Worker *******************************************************************************
1582*495ae853SAndroid Build Coastguard Worker */
isvce_init_me(isvce_process_ctxt_t * ps_proc)1583*495ae853SAndroid Build Coastguard Worker void isvce_init_me(isvce_process_ctxt_t *ps_proc)
1584*495ae853SAndroid Build Coastguard Worker {
1585*495ae853SAndroid Build Coastguard Worker     isvce_me_ctxt_t *ps_me_ctxt = &ps_proc->s_me_ctxt;
1586*495ae853SAndroid Build Coastguard Worker     isvce_codec_t *ps_codec = ps_proc->ps_codec;
1587*495ae853SAndroid Build Coastguard Worker 
1588*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->i4_skip_bias[BSLICE] = SKIP_BIAS_B;
1589*495ae853SAndroid Build Coastguard Worker 
1590*495ae853SAndroid Build Coastguard Worker     if(ps_codec->s_cfg.u4_num_bframes == 0)
1591*495ae853SAndroid Build Coastguard Worker     {
1592*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->i4_skip_bias[PSLICE] = 4 * SKIP_BIAS_P;
1593*495ae853SAndroid Build Coastguard Worker     }
1594*495ae853SAndroid Build Coastguard Worker     else
1595*495ae853SAndroid Build Coastguard Worker     {
1596*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->i4_skip_bias[PSLICE] = SKIP_BIAS_P;
1597*495ae853SAndroid Build Coastguard Worker     }
1598*495ae853SAndroid Build Coastguard Worker 
1599*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->pu1_src_buf_luma = ps_proc->s_src_buf_props.as_component_bufs[0].pv_data;
1600*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->i4_src_strd = ps_proc->s_src_buf_props.as_component_bufs[0].i4_data_stride;
1601*495ae853SAndroid Build Coastguard Worker 
1602*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->apu1_ref_buf_luma[0] = ps_proc->as_ref_buf_props[0].as_component_bufs[0].pv_data;
1603*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->apu1_ref_buf_luma[1] = ps_proc->as_ref_buf_props[1].as_component_bufs[0].pv_data;
1604*495ae853SAndroid Build Coastguard Worker 
1605*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->ai4_rec_strd[0] = ps_proc->as_ref_buf_props[0].as_component_bufs[0].i4_data_stride;
1606*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->ai4_rec_strd[1] = ps_proc->as_ref_buf_props[1].as_component_bufs[0].i4_data_stride;
1607*495ae853SAndroid Build Coastguard Worker 
1608*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->u4_lambda_motion = gu1_qp0[ps_me_ctxt->u1_mb_qp];
1609*495ae853SAndroid Build Coastguard Worker }
1610*495ae853SAndroid Build Coastguard Worker 
1611*495ae853SAndroid Build Coastguard Worker /**
1612*495ae853SAndroid Build Coastguard Worker *******************************************************************************
1613*495ae853SAndroid Build Coastguard Worker *
1614*495ae853SAndroid Build Coastguard Worker * @brief This function performs motion estimation for the current mb using
1615*495ae853SAndroid Build Coastguard Worker *   single reference list
1616*495ae853SAndroid Build Coastguard Worker *
1617*495ae853SAndroid Build Coastguard Worker * @par Description:
1618*495ae853SAndroid Build Coastguard Worker *  The current mb is compared with a list of mb's in the reference frame for
1619*495ae853SAndroid Build Coastguard Worker *  least cost. The mb that offers least cost is chosen as predicted mb and the
1620*495ae853SAndroid Build Coastguard Worker *  displacement of the predicted mb from index location of the current mb is
1621*495ae853SAndroid Build Coastguard Worker *  signaled as mv. The list of the mb's that are chosen in the reference frame
1622*495ae853SAndroid Build Coastguard Worker *  are dependent on the speed of the ME configured.
1623*495ae853SAndroid Build Coastguard Worker *
1624*495ae853SAndroid Build Coastguard Worker * @param[in] ps_proc
1625*495ae853SAndroid Build Coastguard Worker *  Process context corresponding to the job
1626*495ae853SAndroid Build Coastguard Worker *
1627*495ae853SAndroid Build Coastguard Worker * @returns  motion vector of the pred mb, sad, cost.
1628*495ae853SAndroid Build Coastguard Worker *
1629*495ae853SAndroid Build Coastguard Worker * @remarks none
1630*495ae853SAndroid Build Coastguard Worker *
1631*495ae853SAndroid Build Coastguard Worker *******************************************************************************
1632*495ae853SAndroid Build Coastguard Worker */
isvce_compute_me_single_reflist(isvce_process_ctxt_t * ps_proc)1633*495ae853SAndroid Build Coastguard Worker void isvce_compute_me_single_reflist(isvce_process_ctxt_t *ps_proc)
1634*495ae853SAndroid Build Coastguard Worker {
1635*495ae853SAndroid Build Coastguard Worker     mb_part_ctxt s_skip_mbpart;
1636*495ae853SAndroid Build Coastguard Worker 
1637*495ae853SAndroid Build Coastguard Worker     /* source buffer for halp pel generation functions */
1638*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_hpel_src;
1639*495ae853SAndroid Build Coastguard Worker 
1640*495ae853SAndroid Build Coastguard Worker     isvce_me_ctxt_t *ps_me_ctxt = &ps_proc->s_me_ctxt;
1641*495ae853SAndroid Build Coastguard Worker     isvce_codec_t *ps_codec = ps_proc->ps_codec;
1642*495ae853SAndroid Build Coastguard Worker     quant_params_t *ps_qp_params = ps_proc->ps_qp_params[0];
1643*495ae853SAndroid Build Coastguard Worker     isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
1644*495ae853SAndroid Build Coastguard Worker     inter_pred_fxns_t *ps_inter_pred_fxns = &ps_isa_dependent_fxns->s_inter_pred_fxns;
1645*495ae853SAndroid Build Coastguard Worker 
1646*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->pu2_sad_thrsh = ps_qp_params->pu2_sad_thrsh;
1647*495ae853SAndroid Build Coastguard Worker 
1648*495ae853SAndroid Build Coastguard Worker     ASSERT(1 == MAX_REF_FRAMES_PER_PRED_DIR);
1649*495ae853SAndroid Build Coastguard Worker 
1650*495ae853SAndroid Build Coastguard Worker     {
1651*495ae853SAndroid Build Coastguard Worker         WORD32 rows_above, rows_below, columns_left, columns_right;
1652*495ae853SAndroid Build Coastguard Worker 
1653*495ae853SAndroid Build Coastguard Worker         /* During evaluation for motion vectors do not search through padded regions
1654*495ae853SAndroid Build Coastguard Worker          */
1655*495ae853SAndroid Build Coastguard Worker         /* Obtain number of rows and columns that are effective for computing for me
1656*495ae853SAndroid Build Coastguard Worker          * evaluation */
1657*495ae853SAndroid Build Coastguard Worker         rows_above = MB_SIZE + ps_proc->i4_mb_y * MB_SIZE;
1658*495ae853SAndroid Build Coastguard Worker         rows_below = (ps_proc->i4_ht_mbs - ps_proc->i4_mb_y) * MB_SIZE;
1659*495ae853SAndroid Build Coastguard Worker         columns_left = MB_SIZE + ps_proc->i4_mb_x * MB_SIZE;
1660*495ae853SAndroid Build Coastguard Worker         columns_right = (ps_proc->i4_wd_mbs - ps_proc->i4_mb_x) * MB_SIZE;
1661*495ae853SAndroid Build Coastguard Worker 
1662*495ae853SAndroid Build Coastguard Worker         /* init srch range */
1663*495ae853SAndroid Build Coastguard Worker         /* NOTE : For now, lets limit the search range by DEFAULT_MAX_SRCH_RANGE_X /
1664*495ae853SAndroid Build Coastguard Worker          * 2 on all sides.
1665*495ae853SAndroid Build Coastguard Worker          */
1666*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->i4_srch_range_w = -MIN(columns_left, DEFAULT_MAX_SRCH_RANGE_X >> 1);
1667*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->i4_srch_range_e = MIN(columns_right, DEFAULT_MAX_SRCH_RANGE_X >> 1);
1668*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->i4_srch_range_n = -MIN(rows_above, DEFAULT_MAX_SRCH_RANGE_Y >> 1);
1669*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->i4_srch_range_s = MIN(rows_below, DEFAULT_MAX_SRCH_RANGE_Y >> 1);
1670*495ae853SAndroid Build Coastguard Worker 
1671*495ae853SAndroid Build Coastguard Worker         /* this is to facilitate fast sub pel computation with minimal loads */
1672*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->i4_srch_range_w += 1;
1673*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->i4_srch_range_e -= 1;
1674*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->i4_srch_range_n += 1;
1675*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->i4_srch_range_s -= 1;
1676*495ae853SAndroid Build Coastguard Worker     }
1677*495ae853SAndroid Build Coastguard Worker 
1678*495ae853SAndroid Build Coastguard Worker     /***********************************************************************
1679*495ae853SAndroid Build Coastguard Worker      * Compute ME for list L0
1680*495ae853SAndroid Build Coastguard Worker      ***********************************************************************/
1681*495ae853SAndroid Build Coastguard Worker 
1682*495ae853SAndroid Build Coastguard Worker     /* Init SATQD for the current list */
1683*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->u4_min_sad_reached = 0;
1684*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->i4_min_sad = ps_proc->ps_cur_mb->u4_min_sad;
1685*495ae853SAndroid Build Coastguard Worker 
1686*495ae853SAndroid Build Coastguard Worker     /* Get the seed motion vector candidates                    */
1687*495ae853SAndroid Build Coastguard Worker     isvce_get_search_candidates(ps_proc, ps_me_ctxt, L0);
1688*495ae853SAndroid Build Coastguard Worker 
1689*495ae853SAndroid Build Coastguard Worker     /* ****************************************************************
1690*495ae853SAndroid Build Coastguard Worker      *Evaluate the SKIP for current list
1691*495ae853SAndroid Build Coastguard Worker      * ****************************************************************/
1692*495ae853SAndroid Build Coastguard Worker     s_skip_mbpart.s_mv_curr.i2_mvx = 0;
1693*495ae853SAndroid Build Coastguard Worker     s_skip_mbpart.s_mv_curr.i2_mvy = 0;
1694*495ae853SAndroid Build Coastguard Worker     s_skip_mbpart.i4_mb_cost = INT_MAX;
1695*495ae853SAndroid Build Coastguard Worker     s_skip_mbpart.i4_mb_distortion = INT_MAX;
1696*495ae853SAndroid Build Coastguard Worker 
1697*495ae853SAndroid Build Coastguard Worker     isvce_compute_skip_cost(ps_me_ctxt, (ime_mv_t *) (&ps_proc->ps_skip_mv[L0].s_mv),
1698*495ae853SAndroid Build Coastguard Worker                             &s_skip_mbpart, ps_codec->s_cfg.u4_enable_satqd, PRED_L0,
1699*495ae853SAndroid Build Coastguard Worker                             0 /* Not a Bslice */);
1700*495ae853SAndroid Build Coastguard Worker 
1701*495ae853SAndroid Build Coastguard Worker     s_skip_mbpart.s_mv_curr.i2_mvx <<= 2;
1702*495ae853SAndroid Build Coastguard Worker     s_skip_mbpart.s_mv_curr.i2_mvy <<= 2;
1703*495ae853SAndroid Build Coastguard Worker 
1704*495ae853SAndroid Build Coastguard Worker     /******************************************************************
1705*495ae853SAndroid Build Coastguard Worker      * Evaluate ME For current list
1706*495ae853SAndroid Build Coastguard Worker      *****************************************************************/
1707*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->as_mb_part[L0].s_mv_curr.i2_mvx = 0;
1708*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->as_mb_part[L0].s_mv_curr.i2_mvy = 0;
1709*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->as_mb_part[L0].i4_mb_cost = INT_MAX;
1710*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->as_mb_part[L0].i4_mb_distortion = INT_MAX;
1711*495ae853SAndroid Build Coastguard Worker 
1712*495ae853SAndroid Build Coastguard Worker     /* Init Hpel */
1713*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->as_mb_part[L0].pu1_best_hpel_buf = NULL;
1714*495ae853SAndroid Build Coastguard Worker 
1715*495ae853SAndroid Build Coastguard Worker     /* In case we found out the minimum SAD, exit the ME eval */
1716*495ae853SAndroid Build Coastguard Worker     if(!ps_me_ctxt->u4_min_sad_reached)
1717*495ae853SAndroid Build Coastguard Worker     {
1718*495ae853SAndroid Build Coastguard Worker         /* Evaluate search candidates for initial mv pt */
1719*495ae853SAndroid Build Coastguard Worker         isvce_evaluate_init_srchposn_16x16(ps_me_ctxt, L0);
1720*495ae853SAndroid Build Coastguard Worker 
1721*495ae853SAndroid Build Coastguard Worker         /********************************************************************/
1722*495ae853SAndroid Build Coastguard Worker         /*                  full pel motion estimation                      */
1723*495ae853SAndroid Build Coastguard Worker         /********************************************************************/
1724*495ae853SAndroid Build Coastguard Worker         isvce_full_pel_motion_estimation_16x16(ps_me_ctxt, L0);
1725*495ae853SAndroid Build Coastguard Worker 
1726*495ae853SAndroid Build Coastguard Worker         /* Scale the MV to qpel resolution */
1727*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->as_mb_part[L0].s_mv_curr.i2_mvx <<= 2;
1728*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->as_mb_part[L0].s_mv_curr.i2_mvy <<= 2;
1729*495ae853SAndroid Build Coastguard Worker 
1730*495ae853SAndroid Build Coastguard Worker         if(ps_me_ctxt->u4_enable_hpel)
1731*495ae853SAndroid Build Coastguard Worker         {
1732*495ae853SAndroid Build Coastguard Worker             /* moving src pointer to the converged motion vector location*/
1733*495ae853SAndroid Build Coastguard Worker             pu1_hpel_src =
1734*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->apu1_ref_buf_luma[L0] +
1735*495ae853SAndroid Build Coastguard Worker                 (ps_me_ctxt->as_mb_part[L0].s_mv_curr.i2_mvx >> 2) +
1736*495ae853SAndroid Build Coastguard Worker                 (ps_me_ctxt->as_mb_part[L0].s_mv_curr.i2_mvy >> 2) * ps_me_ctxt->ai4_rec_strd[L0];
1737*495ae853SAndroid Build Coastguard Worker 
1738*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->apu1_subpel_buffs[0] = ps_proc->apu1_subpel_buffs[0];
1739*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->apu1_subpel_buffs[1] = ps_proc->apu1_subpel_buffs[1];
1740*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->apu1_subpel_buffs[2] = ps_proc->apu1_subpel_buffs[2];
1741*495ae853SAndroid Build Coastguard Worker 
1742*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->u4_subpel_buf_strd = HP_BUFF_WD;
1743*495ae853SAndroid Build Coastguard Worker 
1744*495ae853SAndroid Build Coastguard Worker             /* half  pel search is done for both sides of full pel,
1745*495ae853SAndroid Build Coastguard Worker              * hence half_x of width x height = 17x16 is created
1746*495ae853SAndroid Build Coastguard Worker              * starting from left half_x of converged full pel */
1747*495ae853SAndroid Build Coastguard Worker             pu1_hpel_src -= 1;
1748*495ae853SAndroid Build Coastguard Worker 
1749*495ae853SAndroid Build Coastguard Worker             /* computing half_x */
1750*495ae853SAndroid Build Coastguard Worker             ps_codec->pf_ih264e_sixtapfilter_horz(pu1_hpel_src, ps_me_ctxt->apu1_subpel_buffs[0],
1751*495ae853SAndroid Build Coastguard Worker                                                   ps_me_ctxt->ai4_rec_strd[L0],
1752*495ae853SAndroid Build Coastguard Worker                                                   ps_me_ctxt->u4_subpel_buf_strd);
1753*495ae853SAndroid Build Coastguard Worker 
1754*495ae853SAndroid Build Coastguard Worker             /*
1755*495ae853SAndroid Build Coastguard Worker              * Halfpel search is done for both sides of full pel,
1756*495ae853SAndroid Build Coastguard Worker              * hence half_y of width x height = 16x17 is created
1757*495ae853SAndroid Build Coastguard Worker              * starting from top half_y of converged full pel
1758*495ae853SAndroid Build Coastguard Worker              * for half_xy top_left is required
1759*495ae853SAndroid Build Coastguard Worker              * hence it starts from pu1_hpel_src = full_pel_converged_point -
1760*495ae853SAndroid Build Coastguard Worker              * i4_rec_strd - 1
1761*495ae853SAndroid Build Coastguard Worker              */
1762*495ae853SAndroid Build Coastguard Worker             pu1_hpel_src -= ps_me_ctxt->ai4_rec_strd[L0];
1763*495ae853SAndroid Build Coastguard Worker 
1764*495ae853SAndroid Build Coastguard Worker             /* computing half_y , and half_xy*/
1765*495ae853SAndroid Build Coastguard Worker             ps_codec->pf_ih264e_sixtap_filter_2dvh_vert(
1766*495ae853SAndroid Build Coastguard Worker                 pu1_hpel_src, ps_me_ctxt->apu1_subpel_buffs[1], ps_me_ctxt->apu1_subpel_buffs[2],
1767*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->ai4_rec_strd[L0], ps_me_ctxt->u4_subpel_buf_strd,
1768*495ae853SAndroid Build Coastguard Worker                 ps_proc->ai16_pred1 + 3, ps_me_ctxt->u4_subpel_buf_strd);
1769*495ae853SAndroid Build Coastguard Worker 
1770*495ae853SAndroid Build Coastguard Worker             isvce_sub_pel_motion_estimation_16x16(ps_me_ctxt, L0);
1771*495ae853SAndroid Build Coastguard Worker         }
1772*495ae853SAndroid Build Coastguard Worker     }
1773*495ae853SAndroid Build Coastguard Worker 
1774*495ae853SAndroid Build Coastguard Worker     /***********************************************************************
1775*495ae853SAndroid Build Coastguard Worker      * If a particular skiip Mv is giving better sad, copy to the corresponding
1776*495ae853SAndroid Build Coastguard Worker      * MBPART
1777*495ae853SAndroid Build Coastguard Worker      * In B slices this loop should go only to PREDL1: If we found min sad
1778*495ae853SAndroid Build Coastguard Worker      * we will go to the skip ref list only
1779*495ae853SAndroid Build Coastguard Worker      * Have to find a way to make it without too much change or new vars
1780*495ae853SAndroid Build Coastguard Worker      **********************************************************************/
1781*495ae853SAndroid Build Coastguard Worker     if(s_skip_mbpart.i4_mb_cost < ps_me_ctxt->as_mb_part[L0].i4_mb_cost)
1782*495ae853SAndroid Build Coastguard Worker     {
1783*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->as_mb_part[L0].i4_mb_cost = s_skip_mbpart.i4_mb_cost;
1784*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->as_mb_part[L0].i4_mb_distortion = s_skip_mbpart.i4_mb_distortion;
1785*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->as_mb_part[L0].s_mv_curr = s_skip_mbpart.s_mv_curr;
1786*495ae853SAndroid Build Coastguard Worker     }
1787*495ae853SAndroid Build Coastguard Worker     else if(ps_me_ctxt->as_mb_part[L0].pu1_best_hpel_buf)
1788*495ae853SAndroid Build Coastguard Worker     {
1789*495ae853SAndroid Build Coastguard Worker         /* Now we have to copy the buffers */
1790*495ae853SAndroid Build Coastguard Worker         ps_inter_pred_fxns->pf_inter_pred_luma_copy(
1791*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mb_part[L0].pu1_best_hpel_buf, ps_proc->pu1_best_subpel_buf,
1792*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->u4_subpel_buf_strd, ps_proc->u4_bst_spel_buf_strd, MB_SIZE, MB_SIZE, NULL,
1793*495ae853SAndroid Build Coastguard Worker             0);
1794*495ae853SAndroid Build Coastguard Worker     }
1795*495ae853SAndroid Build Coastguard Worker 
1796*495ae853SAndroid Build Coastguard Worker     /**********************************************************************
1797*495ae853SAndroid Build Coastguard Worker      * Now get the minimum of MB part sads by searching over all ref lists
1798*495ae853SAndroid Build Coastguard Worker      **********************************************************************/
1799*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvx =
1800*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->as_mb_part[L0].s_mv_curr.i2_mvx;
1801*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvy =
1802*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->as_mb_part[L0].s_mv_curr.i2_mvy;
1803*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_cur_mb->i4_mb_cost = ps_me_ctxt->as_mb_part[L0].i4_mb_cost;
1804*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_cur_mb->i4_mb_distortion = ps_me_ctxt->as_mb_part[L0].i4_mb_distortion;
1805*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_cur_mb->u4_mb_type = P16x16;
1806*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_mb_info->as_pu->u1_pred_mode = L0;
1807*495ae853SAndroid Build Coastguard Worker 
1808*495ae853SAndroid Build Coastguard Worker     /* Mark the reflists */
1809*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_mb_info->as_pu->as_me_info[0].i1_ref_idx = 0;
1810*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_mb_info->as_pu->as_me_info[1].i1_ref_idx = -1;
1811*495ae853SAndroid Build Coastguard Worker 
1812*495ae853SAndroid Build Coastguard Worker     /* number of partitions */
1813*495ae853SAndroid Build Coastguard Worker     ps_proc->u4_num_sub_partitions = 1;
1814*495ae853SAndroid Build Coastguard Worker     *(ps_proc->pu4_mb_pu_cnt) = 1;
1815*495ae853SAndroid Build Coastguard Worker 
1816*495ae853SAndroid Build Coastguard Worker     /* position in-terms of PU */
1817*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_mb_info->as_pu->u1_pos_x_in_4x4 = 0;
1818*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_mb_info->as_pu->u1_pos_y_in_4x4 = 0;
1819*495ae853SAndroid Build Coastguard Worker 
1820*495ae853SAndroid Build Coastguard Worker     /* PU size */
1821*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_mb_info->as_pu->u1_wd_in_4x4_m1 = 3;
1822*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_mb_info->as_pu->u1_ht_in_4x4_m1 = 3;
1823*495ae853SAndroid Build Coastguard Worker 
1824*495ae853SAndroid Build Coastguard Worker     /* Update min sad conditions */
1825*495ae853SAndroid Build Coastguard Worker     if(ps_me_ctxt->u4_min_sad_reached == 1)
1826*495ae853SAndroid Build Coastguard Worker     {
1827*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_cur_mb->u4_min_sad_reached = 1;
1828*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_cur_mb->u4_min_sad = ps_me_ctxt->i4_min_sad;
1829*495ae853SAndroid Build Coastguard Worker     }
1830*495ae853SAndroid Build Coastguard Worker }
1831*495ae853SAndroid Build Coastguard Worker 
1832*495ae853SAndroid Build Coastguard Worker /**
1833*495ae853SAndroid Build Coastguard Worker *******************************************************************************
1834*495ae853SAndroid Build Coastguard Worker *
1835*495ae853SAndroid Build Coastguard Worker * @brief This function performs motion estimation for the current NMB
1836*495ae853SAndroid Build Coastguard Worker *
1837*495ae853SAndroid Build Coastguard Worker * @par Description:
1838*495ae853SAndroid Build Coastguard Worker * Intializes input and output pointers required by the function
1839*495ae853SAndroid Build Coastguard Worker *isvce_compute_me and calls the function isvce_compute_me in a loop to process
1840*495ae853SAndroid Build Coastguard Worker *NMBs.
1841*495ae853SAndroid Build Coastguard Worker *
1842*495ae853SAndroid Build Coastguard Worker * @param[in] ps_proc
1843*495ae853SAndroid Build Coastguard Worker *  Process context corresponding to the job
1844*495ae853SAndroid Build Coastguard Worker *
1845*495ae853SAndroid Build Coastguard Worker * @returns
1846*495ae853SAndroid Build Coastguard Worker *
1847*495ae853SAndroid Build Coastguard Worker * @remarks none
1848*495ae853SAndroid Build Coastguard Worker *
1849*495ae853SAndroid Build Coastguard Worker *******************************************************************************
1850*495ae853SAndroid Build Coastguard Worker */
isvce_compute_me_nmb(isvce_process_ctxt_t * ps_proc,UWORD32 u4_nmb_count)1851*495ae853SAndroid Build Coastguard Worker void isvce_compute_me_nmb(isvce_process_ctxt_t *ps_proc, UWORD32 u4_nmb_count)
1852*495ae853SAndroid Build Coastguard Worker {
1853*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_i;
1854*495ae853SAndroid Build Coastguard Worker 
1855*495ae853SAndroid Build Coastguard Worker     isvce_codec_t *ps_codec = ps_proc->ps_codec;
1856*495ae853SAndroid Build Coastguard Worker     isvce_mb_info_t *ps_mb_begin = ps_proc->ps_mb_info;
1857*495ae853SAndroid Build Coastguard Worker 
1858*495ae853SAndroid Build Coastguard Worker     UWORD32 *pu4_mb_pu_cnt_begin = ps_proc->pu4_mb_pu_cnt;
1859*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_me_map = ps_proc->pu1_me_map + (ps_proc->i4_mb_y * ps_proc->i4_wd_mbs);
1860*495ae853SAndroid Build Coastguard Worker 
1861*495ae853SAndroid Build Coastguard Worker     /* Spatial dependencies for skip are not met if nmb > 1 */
1862*495ae853SAndroid Build Coastguard Worker     ASSERT(1 == u4_nmb_count);
1863*495ae853SAndroid Build Coastguard Worker 
1864*495ae853SAndroid Build Coastguard Worker     if(ps_proc->i4_mb_x)
1865*495ae853SAndroid Build Coastguard Worker     {
1866*495ae853SAndroid Build Coastguard Worker         ps_proc->s_me_ctxt.u4_left_is_intra = ps_proc->s_nbr_info.ps_left_mb_info->u1_is_intra;
1867*495ae853SAndroid Build Coastguard Worker         ps_proc->s_me_ctxt.u4_left_is_skip =
1868*495ae853SAndroid Build Coastguard Worker             (ps_proc->s_nbr_info.ps_left_mb_info->u2_mb_type == PSKIP);
1869*495ae853SAndroid Build Coastguard Worker     }
1870*495ae853SAndroid Build Coastguard Worker 
1871*495ae853SAndroid Build Coastguard Worker     for(u4_i = 0; u4_i < u4_nmb_count; u4_i++)
1872*495ae853SAndroid Build Coastguard Worker     {
1873*495ae853SAndroid Build Coastguard Worker         /* Wait for ME map */
1874*495ae853SAndroid Build Coastguard Worker         if(ps_proc->i4_mb_y > 0)
1875*495ae853SAndroid Build Coastguard Worker         {
1876*495ae853SAndroid Build Coastguard Worker             /* Wait for top right ME to be done */
1877*495ae853SAndroid Build Coastguard Worker             UWORD8 *pu1_me_map_tp_rw =
1878*495ae853SAndroid Build Coastguard Worker                 ps_proc->pu1_me_map + (ps_proc->i4_mb_y - 1) * ps_proc->i4_wd_mbs;
1879*495ae853SAndroid Build Coastguard Worker 
1880*495ae853SAndroid Build Coastguard Worker             while(1)
1881*495ae853SAndroid Build Coastguard Worker             {
1882*495ae853SAndroid Build Coastguard Worker                 volatile UWORD8 *pu1_buf;
1883*495ae853SAndroid Build Coastguard Worker                 WORD32 idx = ps_proc->i4_mb_x + u4_i + 1;
1884*495ae853SAndroid Build Coastguard Worker 
1885*495ae853SAndroid Build Coastguard Worker                 idx = MIN(idx, (ps_proc->i4_wd_mbs - 1));
1886*495ae853SAndroid Build Coastguard Worker                 pu1_buf = pu1_me_map_tp_rw + idx;
1887*495ae853SAndroid Build Coastguard Worker                 if(*pu1_buf) break;
1888*495ae853SAndroid Build Coastguard Worker                 ithread_yield();
1889*495ae853SAndroid Build Coastguard Worker             }
1890*495ae853SAndroid Build Coastguard Worker         }
1891*495ae853SAndroid Build Coastguard Worker 
1892*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_skip_mv = &(ps_proc->ps_nmb_info[u4_i].as_skip_mv[0]);
1893*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_ngbr_avbl = &(ps_proc->ps_nmb_info[u4_i].s_ngbr_avbl);
1894*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_pred_mv = &(ps_proc->ps_nmb_info[u4_i].as_pred_mv[0]);
1895*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_cur_mb = &(ps_proc->ps_nmb_info[u4_i]);
1896*495ae853SAndroid Build Coastguard Worker 
1897*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_cur_mb->u4_min_sad = ps_proc->u4_min_sad;
1898*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_cur_mb->u4_min_sad_reached = 0;
1899*495ae853SAndroid Build Coastguard Worker 
1900*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_cur_mb->i4_mb_cost = INT_MAX;
1901*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_cur_mb->i4_mb_distortion = SHRT_MAX;
1902*495ae853SAndroid Build Coastguard Worker 
1903*495ae853SAndroid Build Coastguard Worker         /* Set the best subpel buf to the correct mb so that the buffer can be
1904*495ae853SAndroid Build Coastguard Worker          * copied */
1905*495ae853SAndroid Build Coastguard Worker         ps_proc->pu1_best_subpel_buf = ps_proc->ps_nmb_info[u4_i].pu1_best_sub_pel_buf;
1906*495ae853SAndroid Build Coastguard Worker         ps_proc->u4_bst_spel_buf_strd = ps_proc->ps_nmb_info[u4_i].u4_bst_spel_buf_strd;
1907*495ae853SAndroid Build Coastguard Worker 
1908*495ae853SAndroid Build Coastguard Worker         /* Set the min sad conditions */
1909*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_cur_mb->u4_min_sad = ps_codec->u4_min_sad;
1910*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_cur_mb->u4_min_sad_reached = 0;
1911*495ae853SAndroid Build Coastguard Worker 
1912*495ae853SAndroid Build Coastguard Worker         isvce_derive_nghbr_avbl_of_mbs(ps_proc);
1913*495ae853SAndroid Build Coastguard Worker 
1914*495ae853SAndroid Build Coastguard Worker         isvce_init_me(ps_proc);
1915*495ae853SAndroid Build Coastguard Worker 
1916*495ae853SAndroid Build Coastguard Worker         /* Compute ME according to slice type */
1917*495ae853SAndroid Build Coastguard Worker         ps_codec->apf_compute_me[ps_proc->i4_slice_type](ps_proc);
1918*495ae853SAndroid Build Coastguard Worker 
1919*495ae853SAndroid Build Coastguard Worker         /* update top and left structs */
1920*495ae853SAndroid Build Coastguard Worker         if(u4_nmb_count > 1)
1921*495ae853SAndroid Build Coastguard Worker         {
1922*495ae853SAndroid Build Coastguard Worker             isvce_mb_info_t *ps_left_syn = ps_proc->s_nbr_info.ps_left_mb_info;
1923*495ae853SAndroid Build Coastguard Worker 
1924*495ae853SAndroid Build Coastguard Worker             ps_left_syn[0] = ps_proc->ps_mb_info[0];
1925*495ae853SAndroid Build Coastguard Worker             ps_left_syn[0].u1_is_intra = 0;
1926*495ae853SAndroid Build Coastguard Worker             ps_left_syn[0].u2_mb_type = ps_proc->ps_cur_mb->u4_mb_type;
1927*495ae853SAndroid Build Coastguard Worker         }
1928*495ae853SAndroid Build Coastguard Worker 
1929*495ae853SAndroid Build Coastguard Worker         /* Copy the min sad reached info */
1930*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_nmb_info[u4_i].u4_min_sad_reached = ps_proc->ps_cur_mb->u4_min_sad_reached;
1931*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_nmb_info[u4_i].u4_min_sad = ps_proc->ps_cur_mb->u4_min_sad;
1932*495ae853SAndroid Build Coastguard Worker 
1933*495ae853SAndroid Build Coastguard Worker         /*
1934*495ae853SAndroid Build Coastguard Worker          * To make sure that the MV map is properly sync to the
1935*495ae853SAndroid Build Coastguard Worker          * cache we need to do a DDB
1936*495ae853SAndroid Build Coastguard Worker          */
1937*495ae853SAndroid Build Coastguard Worker         {
1938*495ae853SAndroid Build Coastguard Worker             DATA_SYNC();
1939*495ae853SAndroid Build Coastguard Worker 
1940*495ae853SAndroid Build Coastguard Worker             pu1_me_map[ps_proc->i4_mb_x] = 1;
1941*495ae853SAndroid Build Coastguard Worker         }
1942*495ae853SAndroid Build Coastguard Worker         ps_proc->i4_mb_x++;
1943*495ae853SAndroid Build Coastguard Worker 
1944*495ae853SAndroid Build Coastguard Worker         ps_proc->s_me_ctxt.u4_left_is_intra = 0;
1945*495ae853SAndroid Build Coastguard Worker         ps_proc->s_me_ctxt.u4_left_is_skip = (ps_proc->ps_cur_mb->u4_mb_type == PSKIP);
1946*495ae853SAndroid Build Coastguard Worker 
1947*495ae853SAndroid Build Coastguard Worker         /* update buffers pointers */
1948*495ae853SAndroid Build Coastguard Worker         ps_proc->s_src_buf_props.as_component_bufs[0].pv_data =
1949*495ae853SAndroid Build Coastguard Worker             ((UWORD8 *) ps_proc->s_src_buf_props.as_component_bufs[0].pv_data) + MB_SIZE;
1950*495ae853SAndroid Build Coastguard Worker         ps_proc->s_rec_buf_props.as_component_bufs[0].pv_data =
1951*495ae853SAndroid Build Coastguard Worker             ((UWORD8 *) ps_proc->s_rec_buf_props.as_component_bufs[0].pv_data) + MB_SIZE;
1952*495ae853SAndroid Build Coastguard Worker         ps_proc->as_ref_buf_props[0].as_component_bufs[0].pv_data =
1953*495ae853SAndroid Build Coastguard Worker             ((UWORD8 *) ps_proc->as_ref_buf_props[0].as_component_bufs[0].pv_data) + MB_SIZE;
1954*495ae853SAndroid Build Coastguard Worker         ps_proc->as_ref_buf_props[1].as_component_bufs[0].pv_data =
1955*495ae853SAndroid Build Coastguard Worker             ((UWORD8 *) ps_proc->as_ref_buf_props[1].as_component_bufs[0].pv_data) + MB_SIZE;
1956*495ae853SAndroid Build Coastguard Worker 
1957*495ae853SAndroid Build Coastguard Worker         /*
1958*495ae853SAndroid Build Coastguard Worker          * Note: Although chroma mb size is 8, as the chroma buffers are
1959*495ae853SAndroid Build Coastguard Worker          * interleaved, the stride per MB is MB_SIZE
1960*495ae853SAndroid Build Coastguard Worker          */
1961*495ae853SAndroid Build Coastguard Worker         ps_proc->s_src_buf_props.as_component_bufs[1].pv_data =
1962*495ae853SAndroid Build Coastguard Worker             ((UWORD8 *) ps_proc->s_src_buf_props.as_component_bufs[1].pv_data) + MB_SIZE;
1963*495ae853SAndroid Build Coastguard Worker         ps_proc->s_rec_buf_props.as_component_bufs[1].pv_data =
1964*495ae853SAndroid Build Coastguard Worker             ((UWORD8 *) ps_proc->s_rec_buf_props.as_component_bufs[1].pv_data) + MB_SIZE;
1965*495ae853SAndroid Build Coastguard Worker         ps_proc->as_ref_buf_props[0].as_component_bufs[1].pv_data =
1966*495ae853SAndroid Build Coastguard Worker             ((UWORD8 *) ps_proc->as_ref_buf_props[0].as_component_bufs[1].pv_data) + MB_SIZE;
1967*495ae853SAndroid Build Coastguard Worker         ps_proc->as_ref_buf_props[1].as_component_bufs[1].pv_data =
1968*495ae853SAndroid Build Coastguard Worker             ((UWORD8 *) ps_proc->as_ref_buf_props[1].as_component_bufs[1].pv_data) + MB_SIZE;
1969*495ae853SAndroid Build Coastguard Worker 
1970*495ae853SAndroid Build Coastguard Worker         ps_proc->pu4_mb_pu_cnt++;
1971*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_mb_info++;
1972*495ae853SAndroid Build Coastguard Worker     }
1973*495ae853SAndroid Build Coastguard Worker 
1974*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_mb_info = ps_mb_begin;
1975*495ae853SAndroid Build Coastguard Worker     ps_proc->pu4_mb_pu_cnt = pu4_mb_pu_cnt_begin;
1976*495ae853SAndroid Build Coastguard Worker     ps_proc->i4_mb_x = ps_proc->i4_mb_x - u4_nmb_count;
1977*495ae853SAndroid Build Coastguard Worker 
1978*495ae853SAndroid Build Coastguard Worker     /* update buffers pointers */
1979*495ae853SAndroid Build Coastguard Worker     ps_proc->s_src_buf_props.as_component_bufs[0].pv_data =
1980*495ae853SAndroid Build Coastguard Worker         ((UWORD8 *) ps_proc->s_src_buf_props.as_component_bufs[0].pv_data) - MB_SIZE * u4_nmb_count;
1981*495ae853SAndroid Build Coastguard Worker     ps_proc->s_rec_buf_props.as_component_bufs[0].pv_data =
1982*495ae853SAndroid Build Coastguard Worker         ((UWORD8 *) ps_proc->s_rec_buf_props.as_component_bufs[0].pv_data) - MB_SIZE * u4_nmb_count;
1983*495ae853SAndroid Build Coastguard Worker     ps_proc->as_ref_buf_props[0].as_component_bufs[0].pv_data =
1984*495ae853SAndroid Build Coastguard Worker         ((UWORD8 *) ps_proc->as_ref_buf_props[0].as_component_bufs[0].pv_data) -
1985*495ae853SAndroid Build Coastguard Worker         MB_SIZE * u4_nmb_count;
1986*495ae853SAndroid Build Coastguard Worker     ps_proc->as_ref_buf_props[1].as_component_bufs[0].pv_data =
1987*495ae853SAndroid Build Coastguard Worker         ((UWORD8 *) ps_proc->as_ref_buf_props[1].as_component_bufs[0].pv_data) -
1988*495ae853SAndroid Build Coastguard Worker         MB_SIZE * u4_nmb_count;
1989*495ae853SAndroid Build Coastguard Worker 
1990*495ae853SAndroid Build Coastguard Worker     /*
1991*495ae853SAndroid Build Coastguard Worker      * Note: Although chroma mb size is 8, as the chroma buffers are
1992*495ae853SAndroid Build Coastguard Worker      * interleaved, the stride per MB is MB_SIZE
1993*495ae853SAndroid Build Coastguard Worker      */
1994*495ae853SAndroid Build Coastguard Worker     ps_proc->s_src_buf_props.as_component_bufs[1].pv_data =
1995*495ae853SAndroid Build Coastguard Worker         ((UWORD8 *) ps_proc->s_src_buf_props.as_component_bufs[1].pv_data) - MB_SIZE * u4_nmb_count;
1996*495ae853SAndroid Build Coastguard Worker     ps_proc->s_rec_buf_props.as_component_bufs[1].pv_data =
1997*495ae853SAndroid Build Coastguard Worker         ((UWORD8 *) ps_proc->s_rec_buf_props.as_component_bufs[1].pv_data) - MB_SIZE * u4_nmb_count;
1998*495ae853SAndroid Build Coastguard Worker     ps_proc->as_ref_buf_props[0].as_component_bufs[1].pv_data =
1999*495ae853SAndroid Build Coastguard Worker         ((UWORD8 *) ps_proc->as_ref_buf_props[0].as_component_bufs[1].pv_data) -
2000*495ae853SAndroid Build Coastguard Worker         MB_SIZE * u4_nmb_count;
2001*495ae853SAndroid Build Coastguard Worker     ps_proc->as_ref_buf_props[1].as_component_bufs[1].pv_data =
2002*495ae853SAndroid Build Coastguard Worker         ((UWORD8 *) ps_proc->as_ref_buf_props[1].as_component_bufs[1].pv_data) -
2003*495ae853SAndroid Build Coastguard Worker         MB_SIZE * u4_nmb_count;
2004*495ae853SAndroid Build Coastguard Worker }
2005*495ae853SAndroid Build Coastguard Worker 
2006*495ae853SAndroid Build Coastguard Worker /**
2007*495ae853SAndroid Build Coastguard Worker *******************************************************************************
2008*495ae853SAndroid Build Coastguard Worker *
2009*495ae853SAndroid Build Coastguard Worker * @brief The function computes parameters for a BSKIP MB
2010*495ae853SAndroid Build Coastguard Worker *
2011*495ae853SAndroid Build Coastguard Worker * @par Description:
2012*495ae853SAndroid Build Coastguard Worker *  The function updates the skip motion vector for B Mb, check if the Mb can be
2013*495ae853SAndroid Build Coastguard Worker *  marked as skip and returns it
2014*495ae853SAndroid Build Coastguard Worker *
2015*495ae853SAndroid Build Coastguard Worker * @param[in] ps_proc
2016*495ae853SAndroid Build Coastguard Worker *  Pointer to process context
2017*495ae853SAndroid Build Coastguard Worker *
2018*495ae853SAndroid Build Coastguard Worker * @param[in] u4_for_me
2019*495ae853SAndroid Build Coastguard Worker *  Dummy
2020*495ae853SAndroid Build Coastguard Worker *
2021*495ae853SAndroid Build Coastguard Worker * @param[in] i4_reflist
2022*495ae853SAndroid Build Coastguard Worker *  Dummy
2023*495ae853SAndroid Build Coastguard Worker *
2024*495ae853SAndroid Build Coastguard Worker * @returns Flag indicating if the current Mb can be skip or not
2025*495ae853SAndroid Build Coastguard Worker *
2026*495ae853SAndroid Build Coastguard Worker * @remarks
2027*495ae853SAndroid Build Coastguard Worker *   The code implements the logic as described in sec 8.4.1.2.2
2028*495ae853SAndroid Build Coastguard Worker *   It also computes co-located MB parmas according to sec 8.4.1.2.1
2029*495ae853SAndroid Build Coastguard Worker *
2030*495ae853SAndroid Build Coastguard Worker *   Need to add condition for this fucntion to be used in ME
2031*495ae853SAndroid Build Coastguard Worker *
2032*495ae853SAndroid Build Coastguard Worker *******************************************************************************/
isvce_find_bskip_params_me(isvce_process_ctxt_t * ps_proc,WORD32 i4_reflist)2033*495ae853SAndroid Build Coastguard Worker WORD32 isvce_find_bskip_params_me(isvce_process_ctxt_t *ps_proc, WORD32 i4_reflist)
2034*495ae853SAndroid Build Coastguard Worker {
2035*495ae853SAndroid Build Coastguard Worker     /* Colzero for co-located MB */
2036*495ae853SAndroid Build Coastguard Worker     WORD32 i4_colzeroflag;
2037*495ae853SAndroid Build Coastguard Worker 
2038*495ae853SAndroid Build Coastguard Worker     /* motion vectors for neighbouring MBs */
2039*495ae853SAndroid Build Coastguard Worker     isvce_enc_pu_t *ps_a_pu, *ps_c_pu, *ps_b_pu;
2040*495ae853SAndroid Build Coastguard Worker 
2041*495ae853SAndroid Build Coastguard Worker     /* Variables to check if a particular mB is available */
2042*495ae853SAndroid Build Coastguard Worker     WORD32 i4_a, i4_b, i4_c, i4_c_avail;
2043*495ae853SAndroid Build Coastguard Worker 
2044*495ae853SAndroid Build Coastguard Worker     /* Mode availability, init to no modes available     */
2045*495ae853SAndroid Build Coastguard Worker     WORD32 i4_mode_avail;
2046*495ae853SAndroid Build Coastguard Worker 
2047*495ae853SAndroid Build Coastguard Worker     /*  mb neighbor availability */
2048*495ae853SAndroid Build Coastguard Worker     block_neighbors_t *ps_ngbr_avbl = ps_proc->ps_ngbr_avbl;
2049*495ae853SAndroid Build Coastguard Worker 
2050*495ae853SAndroid Build Coastguard Worker     /* Temp var */
2051*495ae853SAndroid Build Coastguard Worker     WORD32 i, i4_cmpl_mode, i4_skip_type = -1;
2052*495ae853SAndroid Build Coastguard Worker 
2053*495ae853SAndroid Build Coastguard Worker     /*
2054*495ae853SAndroid Build Coastguard Worker      * Colocated motion vector
2055*495ae853SAndroid Build Coastguard Worker      */
2056*495ae853SAndroid Build Coastguard Worker     mv_t s_mvcol;
2057*495ae853SAndroid Build Coastguard Worker 
2058*495ae853SAndroid Build Coastguard Worker     /*
2059*495ae853SAndroid Build Coastguard Worker      * Colocated picture idx
2060*495ae853SAndroid Build Coastguard Worker      */
2061*495ae853SAndroid Build Coastguard Worker     WORD32 i4_refidxcol;
2062*495ae853SAndroid Build Coastguard Worker 
2063*495ae853SAndroid Build Coastguard Worker     isvce_codec_t *ps_codec = ps_proc->ps_codec;
2064*495ae853SAndroid Build Coastguard Worker 
2065*495ae853SAndroid Build Coastguard Worker     UNUSED(i4_reflist);
2066*495ae853SAndroid Build Coastguard Worker 
2067*495ae853SAndroid Build Coastguard Worker     /**************************************************************************
2068*495ae853SAndroid Build Coastguard Worker      *Find co-located MB parameters
2069*495ae853SAndroid Build Coastguard Worker      *      See sec 8.4.1.2.1  for reference
2070*495ae853SAndroid Build Coastguard Worker      **************************************************************************/
2071*495ae853SAndroid Build Coastguard Worker     {
2072*495ae853SAndroid Build Coastguard Worker         /*
2073*495ae853SAndroid Build Coastguard Worker          * Find the co-located Mb and update the skip and pred appropriately
2074*495ae853SAndroid Build Coastguard Worker          * 1) Default colpic is forward ref : Table 8-6
2075*495ae853SAndroid Build Coastguard Worker          * 2) Default mb col is current MB : Table 8-8
2076*495ae853SAndroid Build Coastguard Worker          */
2077*495ae853SAndroid Build Coastguard Worker 
2078*495ae853SAndroid Build Coastguard Worker         if(ps_proc->ps_col_mb->u1_is_intra)
2079*495ae853SAndroid Build Coastguard Worker         {
2080*495ae853SAndroid Build Coastguard Worker             s_mvcol.i2_mvx = 0;
2081*495ae853SAndroid Build Coastguard Worker             s_mvcol.i2_mvy = 0;
2082*495ae853SAndroid Build Coastguard Worker             i4_refidxcol = -1;
2083*495ae853SAndroid Build Coastguard Worker         }
2084*495ae853SAndroid Build Coastguard Worker         else
2085*495ae853SAndroid Build Coastguard Worker         {
2086*495ae853SAndroid Build Coastguard Worker             if(ps_proc->ps_col_mb->as_pu->u1_pred_mode != L1)
2087*495ae853SAndroid Build Coastguard Worker             {
2088*495ae853SAndroid Build Coastguard Worker                 s_mvcol = ps_proc->ps_col_mb->as_pu->as_me_info[L0].s_mv;
2089*495ae853SAndroid Build Coastguard Worker                 i4_refidxcol = 0;
2090*495ae853SAndroid Build Coastguard Worker             }
2091*495ae853SAndroid Build Coastguard Worker             else
2092*495ae853SAndroid Build Coastguard Worker             {
2093*495ae853SAndroid Build Coastguard Worker                 s_mvcol = ps_proc->ps_col_mb->as_pu->as_me_info[L1].s_mv;
2094*495ae853SAndroid Build Coastguard Worker                 i4_refidxcol = 0;
2095*495ae853SAndroid Build Coastguard Worker             }
2096*495ae853SAndroid Build Coastguard Worker         }
2097*495ae853SAndroid Build Coastguard Worker 
2098*495ae853SAndroid Build Coastguard Worker         /* RefPicList1[ 0 ]  is marked as  "used for short-term reference", as
2099*495ae853SAndroid Build Coastguard Worker          * default */
2100*495ae853SAndroid Build Coastguard Worker         i4_colzeroflag =
2101*495ae853SAndroid Build Coastguard Worker             (!i4_refidxcol && (ABS(s_mvcol.i2_mvx) <= 1) && (ABS(s_mvcol.i2_mvy) <= 1));
2102*495ae853SAndroid Build Coastguard Worker     }
2103*495ae853SAndroid Build Coastguard Worker 
2104*495ae853SAndroid Build Coastguard Worker     /***************************************************************************
2105*495ae853SAndroid Build Coastguard Worker      * Evaluating skip params : Spatial Skip
2106*495ae853SAndroid Build Coastguard Worker      **************************************************************************/
2107*495ae853SAndroid Build Coastguard Worker     {
2108*495ae853SAndroid Build Coastguard Worker         /* Get the neighbouring MBS according to Section 8.4.1.2.2 */
2109*495ae853SAndroid Build Coastguard Worker         ps_a_pu = ps_proc->s_nbr_info.ps_left_mb_info->as_pu;
2110*495ae853SAndroid Build Coastguard Worker         ps_b_pu = ps_proc->s_nbr_info.ps_top_row_mb_info[ps_proc->i4_mb_x].as_pu;
2111*495ae853SAndroid Build Coastguard Worker 
2112*495ae853SAndroid Build Coastguard Worker         i4_c_avail = 0;
2113*495ae853SAndroid Build Coastguard Worker         if(ps_ngbr_avbl->u1_mb_c)
2114*495ae853SAndroid Build Coastguard Worker         {
2115*495ae853SAndroid Build Coastguard Worker             ps_c_pu = ps_proc->s_nbr_info.ps_top_row_mb_info[ps_proc->i4_mb_x + 1].as_pu;
2116*495ae853SAndroid Build Coastguard Worker             i4_c_avail = 1;
2117*495ae853SAndroid Build Coastguard Worker         }
2118*495ae853SAndroid Build Coastguard Worker         else
2119*495ae853SAndroid Build Coastguard Worker         {
2120*495ae853SAndroid Build Coastguard Worker             ps_c_pu = ps_proc->s_nbr_info.ps_top_row_mb_info[ps_proc->i4_mb_x - 1].as_pu;
2121*495ae853SAndroid Build Coastguard Worker             i4_c_avail = ps_ngbr_avbl->u1_mb_d;
2122*495ae853SAndroid Build Coastguard Worker         }
2123*495ae853SAndroid Build Coastguard Worker 
2124*495ae853SAndroid Build Coastguard Worker         i4_a = ps_ngbr_avbl->u1_mb_a;
2125*495ae853SAndroid Build Coastguard Worker         i4_b = ps_ngbr_avbl->u1_mb_b;
2126*495ae853SAndroid Build Coastguard Worker         i4_c = i4_c_avail;
2127*495ae853SAndroid Build Coastguard Worker 
2128*495ae853SAndroid Build Coastguard Worker         /* Init to no mode avail */
2129*495ae853SAndroid Build Coastguard Worker         i4_mode_avail = 0;
2130*495ae853SAndroid Build Coastguard Worker         for(i = 0; i < 2; i++)
2131*495ae853SAndroid Build Coastguard Worker         {
2132*495ae853SAndroid Build Coastguard Worker             i4_cmpl_mode = (i == 0) ? L1 : L0;
2133*495ae853SAndroid Build Coastguard Worker 
2134*495ae853SAndroid Build Coastguard Worker             i4_mode_avail |= (i4_a && (ps_a_pu->u1_pred_mode != i4_cmpl_mode) &&
2135*495ae853SAndroid Build Coastguard Worker                               (ps_a_pu->as_me_info[i].i1_ref_idx == 0))
2136*495ae853SAndroid Build Coastguard Worker                              << i;
2137*495ae853SAndroid Build Coastguard Worker             i4_mode_avail |= (i4_b && (ps_b_pu->u1_pred_mode != i4_cmpl_mode) &&
2138*495ae853SAndroid Build Coastguard Worker                               (ps_b_pu->as_me_info[i].i1_ref_idx == 0))
2139*495ae853SAndroid Build Coastguard Worker                              << i;
2140*495ae853SAndroid Build Coastguard Worker             i4_mode_avail |= (i4_c && (ps_c_pu->u1_pred_mode != i4_cmpl_mode) &&
2141*495ae853SAndroid Build Coastguard Worker                               (ps_c_pu->as_me_info[i].i1_ref_idx == 0))
2142*495ae853SAndroid Build Coastguard Worker                              << i;
2143*495ae853SAndroid Build Coastguard Worker         }
2144*495ae853SAndroid Build Coastguard Worker 
2145*495ae853SAndroid Build Coastguard Worker         if(i4_mode_avail == 0x3 || i4_mode_avail == 0x0)
2146*495ae853SAndroid Build Coastguard Worker         {
2147*495ae853SAndroid Build Coastguard Worker             i4_skip_type = BI;
2148*495ae853SAndroid Build Coastguard Worker         }
2149*495ae853SAndroid Build Coastguard Worker         else if(i4_mode_avail == 0x1)
2150*495ae853SAndroid Build Coastguard Worker         {
2151*495ae853SAndroid Build Coastguard Worker             i4_skip_type = L0;
2152*495ae853SAndroid Build Coastguard Worker         }
2153*495ae853SAndroid Build Coastguard Worker         else if(i4_mode_avail == 0x2)
2154*495ae853SAndroid Build Coastguard Worker         {
2155*495ae853SAndroid Build Coastguard Worker             i4_skip_type = L1;
2156*495ae853SAndroid Build Coastguard Worker         }
2157*495ae853SAndroid Build Coastguard Worker 
2158*495ae853SAndroid Build Coastguard Worker         /* Update skip MV for L0 */
2159*495ae853SAndroid Build Coastguard Worker         if((i4_mode_avail & 0x1) && (!i4_colzeroflag))
2160*495ae853SAndroid Build Coastguard Worker         {
2161*495ae853SAndroid Build Coastguard Worker             ps_proc->ps_skip_mv[0].s_mv.i2_mvx = ps_proc->ps_pred_mv[0].s_mv.i2_mvx;
2162*495ae853SAndroid Build Coastguard Worker             ps_proc->ps_skip_mv[0].s_mv.i2_mvy = ps_proc->ps_pred_mv[0].s_mv.i2_mvy;
2163*495ae853SAndroid Build Coastguard Worker         }
2164*495ae853SAndroid Build Coastguard Worker         else
2165*495ae853SAndroid Build Coastguard Worker         {
2166*495ae853SAndroid Build Coastguard Worker             ps_proc->ps_skip_mv[0].s_mv.i2_mvx = 0;
2167*495ae853SAndroid Build Coastguard Worker             ps_proc->ps_skip_mv[0].s_mv.i2_mvy = 0;
2168*495ae853SAndroid Build Coastguard Worker         }
2169*495ae853SAndroid Build Coastguard Worker 
2170*495ae853SAndroid Build Coastguard Worker         /* Update skip MV for L1 */
2171*495ae853SAndroid Build Coastguard Worker         if((i4_mode_avail & 0x2) && (!i4_colzeroflag))
2172*495ae853SAndroid Build Coastguard Worker         {
2173*495ae853SAndroid Build Coastguard Worker             ps_proc->ps_skip_mv[1].s_mv.i2_mvx = ps_proc->ps_pred_mv[1].s_mv.i2_mvx;
2174*495ae853SAndroid Build Coastguard Worker             ps_proc->ps_skip_mv[1].s_mv.i2_mvy = ps_proc->ps_pred_mv[1].s_mv.i2_mvy;
2175*495ae853SAndroid Build Coastguard Worker         }
2176*495ae853SAndroid Build Coastguard Worker         else
2177*495ae853SAndroid Build Coastguard Worker         {
2178*495ae853SAndroid Build Coastguard Worker             ps_proc->ps_skip_mv[1].s_mv.i2_mvx = 0;
2179*495ae853SAndroid Build Coastguard Worker             ps_proc->ps_skip_mv[1].s_mv.i2_mvy = 0;
2180*495ae853SAndroid Build Coastguard Worker         }
2181*495ae853SAndroid Build Coastguard Worker     }
2182*495ae853SAndroid Build Coastguard Worker 
2183*495ae853SAndroid Build Coastguard Worker     /***************************************************************************
2184*495ae853SAndroid Build Coastguard Worker      * Evaluating skip params : Temporal skip
2185*495ae853SAndroid Build Coastguard Worker      **************************************************************************/
2186*495ae853SAndroid Build Coastguard Worker     {
2187*495ae853SAndroid Build Coastguard Worker         svc_au_buf_t *ps_ref_pic[MAX_REF_PIC_CNT];
2188*495ae853SAndroid Build Coastguard Worker         WORD32 i4_td, i4_tx, i4_tb, i4_dist_scale_factor;
2189*495ae853SAndroid Build Coastguard Worker         isvce_enc_pu_mv_t *ps_skip_mv = &ps_proc->ps_skip_mv[2];
2190*495ae853SAndroid Build Coastguard Worker 
2191*495ae853SAndroid Build Coastguard Worker         ps_ref_pic[L0] = ps_proc->aps_ref_pic[L0];
2192*495ae853SAndroid Build Coastguard Worker         ps_ref_pic[L1] = ps_proc->aps_ref_pic[L1];
2193*495ae853SAndroid Build Coastguard Worker 
2194*495ae853SAndroid Build Coastguard Worker         i4_tb = ps_codec->i4_poc - ps_ref_pic[L0]->i4_abs_poc;
2195*495ae853SAndroid Build Coastguard Worker         i4_td = ps_ref_pic[L1]->i4_abs_poc - ps_ref_pic[L0]->i4_abs_poc;
2196*495ae853SAndroid Build Coastguard Worker 
2197*495ae853SAndroid Build Coastguard Worker         i4_tb = CLIP3(-128, 127, i4_tb);
2198*495ae853SAndroid Build Coastguard Worker         i4_td = CLIP3(-128, 127, i4_td);
2199*495ae853SAndroid Build Coastguard Worker 
2200*495ae853SAndroid Build Coastguard Worker         i4_tx = (16384 + ABS(i4_td / 2)) / i4_td;
2201*495ae853SAndroid Build Coastguard Worker         i4_dist_scale_factor = CLIP3(-1024, 1023, (i4_tb * i4_tx + 32) >> 6);
2202*495ae853SAndroid Build Coastguard Worker 
2203*495ae853SAndroid Build Coastguard Worker         /* Motion vectors taken in full pel resolution , hence  -> (& 0xfffc)
2204*495ae853SAndroid Build Coastguard Worker          * operation */
2205*495ae853SAndroid Build Coastguard Worker         ps_skip_mv[L0].s_mv.i2_mvx = ((i4_dist_scale_factor * s_mvcol.i2_mvx + 128) >> 8) & 0xfffc;
2206*495ae853SAndroid Build Coastguard Worker         ps_skip_mv[L0].s_mv.i2_mvy = ((i4_dist_scale_factor * s_mvcol.i2_mvy + 128) >> 8) & 0xfffc;
2207*495ae853SAndroid Build Coastguard Worker 
2208*495ae853SAndroid Build Coastguard Worker         ps_skip_mv[L1].s_mv.i2_mvx = (ps_skip_mv[L0].s_mv.i2_mvx - s_mvcol.i2_mvx) & 0xfffc;
2209*495ae853SAndroid Build Coastguard Worker         ps_skip_mv[L1].s_mv.i2_mvy = (ps_skip_mv[L0].s_mv.i2_mvy - s_mvcol.i2_mvy) & 0xfffc;
2210*495ae853SAndroid Build Coastguard Worker     }
2211*495ae853SAndroid Build Coastguard Worker 
2212*495ae853SAndroid Build Coastguard Worker     return i4_skip_type;
2213*495ae853SAndroid Build Coastguard Worker }
2214*495ae853SAndroid Build Coastguard Worker 
2215*495ae853SAndroid Build Coastguard Worker /**
2216*495ae853SAndroid Build Coastguard Worker *******************************************************************************
2217*495ae853SAndroid Build Coastguard Worker *
2218*495ae853SAndroid Build Coastguard Worker * @brief The function computes the skip motion vectoe for B mb
2219*495ae853SAndroid Build Coastguard Worker *
2220*495ae853SAndroid Build Coastguard Worker * @par Description:
2221*495ae853SAndroid Build Coastguard Worker *  The function gives the skip motion vector for B Mb, check if the Mb can be
2222*495ae853SAndroid Build Coastguard Worker *  marked as skip
2223*495ae853SAndroid Build Coastguard Worker *
2224*495ae853SAndroid Build Coastguard Worker * @param[in] ps_proc
2225*495ae853SAndroid Build Coastguard Worker *  Pointer to process context
2226*495ae853SAndroid Build Coastguard Worker *
2227*495ae853SAndroid Build Coastguard Worker * @param[in] u4_for_me
2228*495ae853SAndroid Build Coastguard Worker *  Dummy
2229*495ae853SAndroid Build Coastguard Worker *
2230*495ae853SAndroid Build Coastguard Worker * @param[in] u4_for_me
2231*495ae853SAndroid Build Coastguard Worker *  Dummy
2232*495ae853SAndroid Build Coastguard Worker *
2233*495ae853SAndroid Build Coastguard Worker * @returns Flag indicating if the current Mb can be skip or not
2234*495ae853SAndroid Build Coastguard Worker *
2235*495ae853SAndroid Build Coastguard Worker * @remarks The code implements the logic as described in sec 8.4.1.2.2 in H264
2236*495ae853SAndroid Build Coastguard Worker *   specification. It also computes co-located MB parmas according to
2237*495ae853SAndroid Build Coastguard Worker *sec 8.4.1.2.1
2238*495ae853SAndroid Build Coastguard Worker *
2239*495ae853SAndroid Build Coastguard Worker *******************************************************************************/
isvce_find_bskip_params(isvce_process_ctxt_t * ps_proc,WORD32 i4_reflist)2240*495ae853SAndroid Build Coastguard Worker WORD32 isvce_find_bskip_params(isvce_process_ctxt_t *ps_proc, WORD32 i4_reflist)
2241*495ae853SAndroid Build Coastguard Worker {
2242*495ae853SAndroid Build Coastguard Worker     WORD32 i4_colzeroflag;
2243*495ae853SAndroid Build Coastguard Worker 
2244*495ae853SAndroid Build Coastguard Worker     /* motion vectors */
2245*495ae853SAndroid Build Coastguard Worker     isvce_enc_pu_t *ps_a_pu, *ps_c_pu, *ps_b_pu;
2246*495ae853SAndroid Build Coastguard Worker 
2247*495ae853SAndroid Build Coastguard Worker     /* Syntax elem */
2248*495ae853SAndroid Build Coastguard Worker     isvce_mb_info_t *ps_a_syn, *ps_b_syn, *ps_c_syn;
2249*495ae853SAndroid Build Coastguard Worker 
2250*495ae853SAndroid Build Coastguard Worker     /* Variables to check if a particular mB is available */
2251*495ae853SAndroid Build Coastguard Worker     WORD32 i4_a, i4_b, i4_c, i4_c_avail;
2252*495ae853SAndroid Build Coastguard Worker 
2253*495ae853SAndroid Build Coastguard Worker     /* Mode availability, init to no modes available     */
2254*495ae853SAndroid Build Coastguard Worker     WORD32 i4_mode_avail;
2255*495ae853SAndroid Build Coastguard Worker 
2256*495ae853SAndroid Build Coastguard Worker     /*  mb neighbor availability */
2257*495ae853SAndroid Build Coastguard Worker     block_neighbors_t *ps_ngbr_avbl = ps_proc->ps_ngbr_avbl;
2258*495ae853SAndroid Build Coastguard Worker 
2259*495ae853SAndroid Build Coastguard Worker     /* Temp var */
2260*495ae853SAndroid Build Coastguard Worker     WORD32 i, i4_cmpl_mode;
2261*495ae853SAndroid Build Coastguard Worker 
2262*495ae853SAndroid Build Coastguard Worker     UNUSED(i4_reflist);
2263*495ae853SAndroid Build Coastguard Worker 
2264*495ae853SAndroid Build Coastguard Worker     /**************************************************************************
2265*495ae853SAndroid Build Coastguard Worker      *Find co-locates parameters
2266*495ae853SAndroid Build Coastguard Worker      *      See sec 8.4.1.2.1  for reference
2267*495ae853SAndroid Build Coastguard Worker      **************************************************************************/
2268*495ae853SAndroid Build Coastguard Worker     {
2269*495ae853SAndroid Build Coastguard Worker         /*
2270*495ae853SAndroid Build Coastguard Worker          * Find the co-located Mb and update the skip and pred appropriately
2271*495ae853SAndroid Build Coastguard Worker          * 1) Default colpic is forward ref : Table 8-6
2272*495ae853SAndroid Build Coastguard Worker          * 2) Default mb col is current MB : Table 8-8
2273*495ae853SAndroid Build Coastguard Worker          */
2274*495ae853SAndroid Build Coastguard Worker 
2275*495ae853SAndroid Build Coastguard Worker         mv_t s_mvcol;
2276*495ae853SAndroid Build Coastguard Worker         WORD32 i4_refidxcol;
2277*495ae853SAndroid Build Coastguard Worker 
2278*495ae853SAndroid Build Coastguard Worker         if(ps_proc->ps_col_mb->u1_is_intra)
2279*495ae853SAndroid Build Coastguard Worker         {
2280*495ae853SAndroid Build Coastguard Worker             s_mvcol.i2_mvx = 0;
2281*495ae853SAndroid Build Coastguard Worker             s_mvcol.i2_mvy = 0;
2282*495ae853SAndroid Build Coastguard Worker             i4_refidxcol = -1;
2283*495ae853SAndroid Build Coastguard Worker         }
2284*495ae853SAndroid Build Coastguard Worker         else
2285*495ae853SAndroid Build Coastguard Worker         {
2286*495ae853SAndroid Build Coastguard Worker             if(ps_proc->ps_col_mb->as_pu->u1_pred_mode != L1)
2287*495ae853SAndroid Build Coastguard Worker             {
2288*495ae853SAndroid Build Coastguard Worker                 s_mvcol = ps_proc->ps_col_mb->as_pu->as_me_info[L0].s_mv;
2289*495ae853SAndroid Build Coastguard Worker                 i4_refidxcol = 0;
2290*495ae853SAndroid Build Coastguard Worker             }
2291*495ae853SAndroid Build Coastguard Worker             else
2292*495ae853SAndroid Build Coastguard Worker             {
2293*495ae853SAndroid Build Coastguard Worker                 s_mvcol = ps_proc->ps_col_mb->as_pu->as_me_info[L1].s_mv;
2294*495ae853SAndroid Build Coastguard Worker                 i4_refidxcol = 0;
2295*495ae853SAndroid Build Coastguard Worker             }
2296*495ae853SAndroid Build Coastguard Worker         }
2297*495ae853SAndroid Build Coastguard Worker 
2298*495ae853SAndroid Build Coastguard Worker         /* RefPicList1[ 0 ]  is marked as  "used for short-term reference", as
2299*495ae853SAndroid Build Coastguard Worker          * default */
2300*495ae853SAndroid Build Coastguard Worker         i4_colzeroflag =
2301*495ae853SAndroid Build Coastguard Worker             (!i4_refidxcol && (ABS(s_mvcol.i2_mvx) <= 1) && (ABS(s_mvcol.i2_mvy) <= 1));
2302*495ae853SAndroid Build Coastguard Worker     }
2303*495ae853SAndroid Build Coastguard Worker 
2304*495ae853SAndroid Build Coastguard Worker     /***************************************************************************
2305*495ae853SAndroid Build Coastguard Worker      * Evaluating skip params
2306*495ae853SAndroid Build Coastguard Worker      **************************************************************************/
2307*495ae853SAndroid Build Coastguard Worker     /* Section 8.4.1.2.2 */
2308*495ae853SAndroid Build Coastguard Worker     ps_a_syn = ps_proc->s_nbr_info.ps_left_mb_info;
2309*495ae853SAndroid Build Coastguard Worker     ps_a_pu = ps_proc->s_nbr_info.ps_left_mb_info->as_pu;
2310*495ae853SAndroid Build Coastguard Worker 
2311*495ae853SAndroid Build Coastguard Worker     ps_b_syn = ps_proc->s_nbr_info.ps_top_row_mb_info + ps_proc->i4_mb_x;
2312*495ae853SAndroid Build Coastguard Worker     ps_b_pu = ps_b_syn->as_pu;
2313*495ae853SAndroid Build Coastguard Worker 
2314*495ae853SAndroid Build Coastguard Worker     i4_c_avail = 0;
2315*495ae853SAndroid Build Coastguard Worker     if(ps_ngbr_avbl->u1_mb_c)
2316*495ae853SAndroid Build Coastguard Worker     {
2317*495ae853SAndroid Build Coastguard Worker         ps_c_syn = ps_b_syn + 1;
2318*495ae853SAndroid Build Coastguard Worker         ps_c_pu = ps_c_syn->as_pu;
2319*495ae853SAndroid Build Coastguard Worker         i4_c_avail = 1;
2320*495ae853SAndroid Build Coastguard Worker     }
2321*495ae853SAndroid Build Coastguard Worker     else
2322*495ae853SAndroid Build Coastguard Worker     {
2323*495ae853SAndroid Build Coastguard Worker         ps_c_syn = ps_b_syn - 1;
2324*495ae853SAndroid Build Coastguard Worker         ps_c_pu = ps_c_syn->as_pu;
2325*495ae853SAndroid Build Coastguard Worker         i4_c_avail = ps_ngbr_avbl->u1_mb_d;
2326*495ae853SAndroid Build Coastguard Worker     }
2327*495ae853SAndroid Build Coastguard Worker 
2328*495ae853SAndroid Build Coastguard Worker     i4_a = ps_ngbr_avbl->u1_mb_a;
2329*495ae853SAndroid Build Coastguard Worker     i4_a &= !ps_a_syn->u1_is_intra;
2330*495ae853SAndroid Build Coastguard Worker 
2331*495ae853SAndroid Build Coastguard Worker     i4_b = ps_ngbr_avbl->u1_mb_b;
2332*495ae853SAndroid Build Coastguard Worker     i4_b &= !ps_b_syn->u1_is_intra;
2333*495ae853SAndroid Build Coastguard Worker 
2334*495ae853SAndroid Build Coastguard Worker     i4_c = i4_c_avail;
2335*495ae853SAndroid Build Coastguard Worker     i4_c &= !ps_c_syn->u1_is_intra;
2336*495ae853SAndroid Build Coastguard Worker 
2337*495ae853SAndroid Build Coastguard Worker     /* Init to no mode avail */
2338*495ae853SAndroid Build Coastguard Worker     i4_mode_avail = 0;
2339*495ae853SAndroid Build Coastguard Worker     for(i = 0; i < 2; i++)
2340*495ae853SAndroid Build Coastguard Worker     {
2341*495ae853SAndroid Build Coastguard Worker         i4_cmpl_mode = (i == 0) ? L1 : L0;
2342*495ae853SAndroid Build Coastguard Worker 
2343*495ae853SAndroid Build Coastguard Worker         i4_mode_avail |= (i4_a && (ps_a_pu->u1_pred_mode != i4_cmpl_mode) &&
2344*495ae853SAndroid Build Coastguard Worker                           (ps_a_pu->as_me_info[i].i1_ref_idx == 0))
2345*495ae853SAndroid Build Coastguard Worker                          << i;
2346*495ae853SAndroid Build Coastguard Worker         i4_mode_avail |= (i4_b && (ps_b_pu->u1_pred_mode != i4_cmpl_mode) &&
2347*495ae853SAndroid Build Coastguard Worker                           (ps_b_pu->as_me_info[i].i1_ref_idx == 0))
2348*495ae853SAndroid Build Coastguard Worker                          << i;
2349*495ae853SAndroid Build Coastguard Worker         i4_mode_avail |= (i4_c && (ps_c_pu->u1_pred_mode != i4_cmpl_mode) &&
2350*495ae853SAndroid Build Coastguard Worker                           (ps_c_pu->as_me_info[i].i1_ref_idx == 0))
2351*495ae853SAndroid Build Coastguard Worker                          << i;
2352*495ae853SAndroid Build Coastguard Worker     }
2353*495ae853SAndroid Build Coastguard Worker 
2354*495ae853SAndroid Build Coastguard Worker     /* Update skip MV for L0 */
2355*495ae853SAndroid Build Coastguard Worker     if((i4_mode_avail & 0x1) && (!i4_colzeroflag))
2356*495ae853SAndroid Build Coastguard Worker     {
2357*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_skip_mv[0].s_mv.i2_mvx = ps_proc->ps_pred_mv[0].s_mv.i2_mvx;
2358*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_skip_mv[0].s_mv.i2_mvy = ps_proc->ps_pred_mv[0].s_mv.i2_mvy;
2359*495ae853SAndroid Build Coastguard Worker     }
2360*495ae853SAndroid Build Coastguard Worker     else
2361*495ae853SAndroid Build Coastguard Worker     {
2362*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_skip_mv[0].s_mv.i2_mvx = 0;
2363*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_skip_mv[0].s_mv.i2_mvy = 0;
2364*495ae853SAndroid Build Coastguard Worker     }
2365*495ae853SAndroid Build Coastguard Worker 
2366*495ae853SAndroid Build Coastguard Worker     /* Update skip MV for L1 */
2367*495ae853SAndroid Build Coastguard Worker     if((i4_mode_avail & 0x2) && (!i4_colzeroflag))
2368*495ae853SAndroid Build Coastguard Worker     {
2369*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_skip_mv[1].s_mv.i2_mvx = ps_proc->ps_pred_mv[1].s_mv.i2_mvx;
2370*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_skip_mv[1].s_mv.i2_mvy = ps_proc->ps_pred_mv[1].s_mv.i2_mvy;
2371*495ae853SAndroid Build Coastguard Worker     }
2372*495ae853SAndroid Build Coastguard Worker     else
2373*495ae853SAndroid Build Coastguard Worker     {
2374*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_skip_mv[1].s_mv.i2_mvx = 0;
2375*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_skip_mv[1].s_mv.i2_mvy = 0;
2376*495ae853SAndroid Build Coastguard Worker     }
2377*495ae853SAndroid Build Coastguard Worker 
2378*495ae853SAndroid Build Coastguard Worker     /* Now see if the ME information matches the SKIP information */
2379*495ae853SAndroid Build Coastguard Worker     switch(ps_proc->ps_mb_info->as_pu->u1_pred_mode)
2380*495ae853SAndroid Build Coastguard Worker     {
2381*495ae853SAndroid Build Coastguard Worker         case PRED_BI:
2382*495ae853SAndroid Build Coastguard Worker             if((ps_proc->ps_mb_info->as_pu->as_me_info[0].s_mv.i2_mvx ==
2383*495ae853SAndroid Build Coastguard Worker                 ps_proc->ps_skip_mv[0].s_mv.i2_mvx) &&
2384*495ae853SAndroid Build Coastguard Worker                (ps_proc->ps_mb_info->as_pu->as_me_info[0].s_mv.i2_mvy ==
2385*495ae853SAndroid Build Coastguard Worker                 ps_proc->ps_skip_mv[0].s_mv.i2_mvy) &&
2386*495ae853SAndroid Build Coastguard Worker                (ps_proc->ps_mb_info->as_pu->as_me_info[1].s_mv.i2_mvx ==
2387*495ae853SAndroid Build Coastguard Worker                 ps_proc->ps_skip_mv[1].s_mv.i2_mvx) &&
2388*495ae853SAndroid Build Coastguard Worker                (ps_proc->ps_mb_info->as_pu->as_me_info[1].s_mv.i2_mvy ==
2389*495ae853SAndroid Build Coastguard Worker                 ps_proc->ps_skip_mv[1].s_mv.i2_mvy) &&
2390*495ae853SAndroid Build Coastguard Worker                (i4_mode_avail == 0x3 || i4_mode_avail == 0x0))
2391*495ae853SAndroid Build Coastguard Worker             {
2392*495ae853SAndroid Build Coastguard Worker                 return 1;
2393*495ae853SAndroid Build Coastguard Worker             }
2394*495ae853SAndroid Build Coastguard Worker             break;
2395*495ae853SAndroid Build Coastguard Worker 
2396*495ae853SAndroid Build Coastguard Worker         case PRED_L0:
2397*495ae853SAndroid Build Coastguard Worker             if((ps_proc->ps_mb_info->as_pu->as_me_info[0].s_mv.i2_mvx ==
2398*495ae853SAndroid Build Coastguard Worker                 ps_proc->ps_skip_mv[0].s_mv.i2_mvx) &&
2399*495ae853SAndroid Build Coastguard Worker                (ps_proc->ps_mb_info->as_pu->as_me_info[0].s_mv.i2_mvy ==
2400*495ae853SAndroid Build Coastguard Worker                 ps_proc->ps_skip_mv[0].s_mv.i2_mvy) &&
2401*495ae853SAndroid Build Coastguard Worker                (i4_mode_avail == 0x1))
2402*495ae853SAndroid Build Coastguard Worker             {
2403*495ae853SAndroid Build Coastguard Worker                 return 1;
2404*495ae853SAndroid Build Coastguard Worker             }
2405*495ae853SAndroid Build Coastguard Worker             break;
2406*495ae853SAndroid Build Coastguard Worker 
2407*495ae853SAndroid Build Coastguard Worker         case PRED_L1:
2408*495ae853SAndroid Build Coastguard Worker             if((ps_proc->ps_mb_info->as_pu->as_me_info[1].s_mv.i2_mvx ==
2409*495ae853SAndroid Build Coastguard Worker                 ps_proc->ps_skip_mv[1].s_mv.i2_mvx) &&
2410*495ae853SAndroid Build Coastguard Worker                (ps_proc->ps_mb_info->as_pu->as_me_info[1].s_mv.i2_mvy ==
2411*495ae853SAndroid Build Coastguard Worker                 ps_proc->ps_skip_mv[1].s_mv.i2_mvy) &&
2412*495ae853SAndroid Build Coastguard Worker                (i4_mode_avail == 0x2))
2413*495ae853SAndroid Build Coastguard Worker             {
2414*495ae853SAndroid Build Coastguard Worker                 return 1;
2415*495ae853SAndroid Build Coastguard Worker             }
2416*495ae853SAndroid Build Coastguard Worker             break;
2417*495ae853SAndroid Build Coastguard Worker     }
2418*495ae853SAndroid Build Coastguard Worker 
2419*495ae853SAndroid Build Coastguard Worker     return 0;
2420*495ae853SAndroid Build Coastguard Worker }
2421*495ae853SAndroid Build Coastguard Worker 
2422*495ae853SAndroid Build Coastguard Worker /**
2423*495ae853SAndroid Build Coastguard Worker *******************************************************************************
2424*495ae853SAndroid Build Coastguard Worker *
2425*495ae853SAndroid Build Coastguard Worker * @brief This function computes the best motion vector among the tentative mv
2426*495ae853SAndroid Build Coastguard Worker * candidates chosen.
2427*495ae853SAndroid Build Coastguard Worker *
2428*495ae853SAndroid Build Coastguard Worker * @par Description:
2429*495ae853SAndroid Build Coastguard Worker *  This function determines the position in the search window at which the
2430*495ae853SAndroid Build Coastguard Worker *motion estimation should begin in order to minimise the number of search
2431*495ae853SAndroid Build Coastguard Worker *iterations.
2432*495ae853SAndroid Build Coastguard Worker *
2433*495ae853SAndroid Build Coastguard Worker * @param[in] ps_mb_part
2434*495ae853SAndroid Build Coastguard Worker *  pointer to current mb partition ctxt with respect to ME
2435*495ae853SAndroid Build Coastguard Worker *
2436*495ae853SAndroid Build Coastguard Worker * @param[in] u4_lambda_motion
2437*495ae853SAndroid Build Coastguard Worker *  lambda motion
2438*495ae853SAndroid Build Coastguard Worker *
2439*495ae853SAndroid Build Coastguard Worker * @param[in] u4_fast_flag
2440*495ae853SAndroid Build Coastguard Worker *  enable/disable fast sad computation
2441*495ae853SAndroid Build Coastguard Worker *
2442*495ae853SAndroid Build Coastguard Worker * @returns  mv pair & corresponding distortion and cost
2443*495ae853SAndroid Build Coastguard Worker *
2444*495ae853SAndroid Build Coastguard Worker * @remarks Currently onyl 4 search candiates are supported
2445*495ae853SAndroid Build Coastguard Worker *
2446*495ae853SAndroid Build Coastguard Worker *******************************************************************************
2447*495ae853SAndroid Build Coastguard Worker */
isvce_evaluate_bipred(isvce_me_ctxt_t * ps_me_ctxt,isvce_process_ctxt_t * ps_proc,mb_part_ctxt * ps_mb_ctxt_bi)2448*495ae853SAndroid Build Coastguard Worker void isvce_evaluate_bipred(isvce_me_ctxt_t *ps_me_ctxt, isvce_process_ctxt_t *ps_proc,
2449*495ae853SAndroid Build Coastguard Worker                            mb_part_ctxt *ps_mb_ctxt_bi)
2450*495ae853SAndroid Build Coastguard Worker {
2451*495ae853SAndroid Build Coastguard Worker     UWORD32 i, u4_fast_sad;
2452*495ae853SAndroid Build Coastguard Worker 
2453*495ae853SAndroid Build Coastguard Worker     WORD32 i4_dest_buff;
2454*495ae853SAndroid Build Coastguard Worker 
2455*495ae853SAndroid Build Coastguard Worker     mv_t *ps_l0_pred_mv, *ps_l1_pred_mv, s_l0_mv, s_l1_mv;
2456*495ae853SAndroid Build Coastguard Worker 
2457*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_ref_mb_l0, *pu1_ref_mb_l1;
2458*495ae853SAndroid Build Coastguard Worker 
2459*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_dst_buf;
2460*495ae853SAndroid Build Coastguard Worker 
2461*495ae853SAndroid Build Coastguard Worker     WORD32 i4_ref_l0_stride, i4_ref_l1_stride;
2462*495ae853SAndroid Build Coastguard Worker 
2463*495ae853SAndroid Build Coastguard Worker     WORD32 i4_mb_distortion, i4_mb_cost;
2464*495ae853SAndroid Build Coastguard Worker 
2465*495ae853SAndroid Build Coastguard Worker     isvce_codec_t *ps_codec = ps_proc->ps_codec;
2466*495ae853SAndroid Build Coastguard Worker     isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
2467*495ae853SAndroid Build Coastguard Worker     inter_pred_fxns_t *ps_inter_pred_fxns = &ps_isa_dependent_fxns->s_inter_pred_fxns;
2468*495ae853SAndroid Build Coastguard Worker 
2469*495ae853SAndroid Build Coastguard Worker     u4_fast_sad = ps_me_ctxt->u4_enable_fast_sad;
2470*495ae853SAndroid Build Coastguard Worker 
2471*495ae853SAndroid Build Coastguard Worker     i4_dest_buff = 0;
2472*495ae853SAndroid Build Coastguard Worker     for(i = 0; i < ps_me_ctxt->u4_num_candidates[BI]; i += 2)
2473*495ae853SAndroid Build Coastguard Worker     {
2474*495ae853SAndroid Build Coastguard Worker         pu1_dst_buf = ps_me_ctxt->apu1_subpel_buffs[i4_dest_buff];
2475*495ae853SAndroid Build Coastguard Worker 
2476*495ae853SAndroid Build Coastguard Worker         s_l0_mv.i2_mvx = ps_me_ctxt->as_mv_init_search[BI][i].i2_mvx >> 2;
2477*495ae853SAndroid Build Coastguard Worker         s_l0_mv.i2_mvy = ps_me_ctxt->as_mv_init_search[BI][i].i2_mvy >> 2;
2478*495ae853SAndroid Build Coastguard Worker         s_l1_mv.i2_mvx = ps_me_ctxt->as_mv_init_search[BI][i + 1].i2_mvx >> 2;
2479*495ae853SAndroid Build Coastguard Worker         s_l1_mv.i2_mvy = ps_me_ctxt->as_mv_init_search[BI][i + 1].i2_mvy >> 2;
2480*495ae853SAndroid Build Coastguard Worker 
2481*495ae853SAndroid Build Coastguard Worker         ps_l0_pred_mv = &ps_proc->ps_pred_mv[L0].s_mv;
2482*495ae853SAndroid Build Coastguard Worker         ps_l1_pred_mv = &ps_proc->ps_pred_mv[L1].s_mv;
2483*495ae853SAndroid Build Coastguard Worker 
2484*495ae853SAndroid Build Coastguard Worker         if((ps_me_ctxt->as_mv_init_search[BI][i].i2_mvx & 0x3) ||
2485*495ae853SAndroid Build Coastguard Worker            (ps_me_ctxt->as_mv_init_search[BI][i].i2_mvy & 0x3))
2486*495ae853SAndroid Build Coastguard Worker         {
2487*495ae853SAndroid Build Coastguard Worker             pu1_ref_mb_l0 = ps_me_ctxt->as_mb_part[L0].pu1_best_hpel_buf;
2488*495ae853SAndroid Build Coastguard Worker             i4_ref_l0_stride = ps_me_ctxt->u4_subpel_buf_strd;
2489*495ae853SAndroid Build Coastguard Worker         }
2490*495ae853SAndroid Build Coastguard Worker         else
2491*495ae853SAndroid Build Coastguard Worker         {
2492*495ae853SAndroid Build Coastguard Worker             pu1_ref_mb_l0 = ps_me_ctxt->apu1_ref_buf_luma[L0] + (s_l0_mv.i2_mvx) +
2493*495ae853SAndroid Build Coastguard Worker                             ((s_l0_mv.i2_mvy) * ps_me_ctxt->ai4_rec_strd[L0]);
2494*495ae853SAndroid Build Coastguard Worker             i4_ref_l0_stride = ps_me_ctxt->ai4_rec_strd[L0];
2495*495ae853SAndroid Build Coastguard Worker         }
2496*495ae853SAndroid Build Coastguard Worker 
2497*495ae853SAndroid Build Coastguard Worker         if((ps_me_ctxt->as_mv_init_search[BI][i + 1].i2_mvx & 0x3) ||
2498*495ae853SAndroid Build Coastguard Worker            (ps_me_ctxt->as_mv_init_search[BI][i + 1].i2_mvy & 0x3))
2499*495ae853SAndroid Build Coastguard Worker         {
2500*495ae853SAndroid Build Coastguard Worker             pu1_ref_mb_l1 = ps_me_ctxt->as_mb_part[L1].pu1_best_hpel_buf;
2501*495ae853SAndroid Build Coastguard Worker             i4_ref_l1_stride = ps_me_ctxt->u4_subpel_buf_strd;
2502*495ae853SAndroid Build Coastguard Worker         }
2503*495ae853SAndroid Build Coastguard Worker         else
2504*495ae853SAndroid Build Coastguard Worker         {
2505*495ae853SAndroid Build Coastguard Worker             pu1_ref_mb_l1 = ps_me_ctxt->apu1_ref_buf_luma[L1] + (s_l1_mv.i2_mvx) +
2506*495ae853SAndroid Build Coastguard Worker                             ((s_l1_mv.i2_mvy) * ps_me_ctxt->ai4_rec_strd[L1]);
2507*495ae853SAndroid Build Coastguard Worker             i4_ref_l1_stride = ps_me_ctxt->ai4_rec_strd[L1];
2508*495ae853SAndroid Build Coastguard Worker         }
2509*495ae853SAndroid Build Coastguard Worker 
2510*495ae853SAndroid Build Coastguard Worker         ps_inter_pred_fxns->pf_inter_pred_luma_bilinear(
2511*495ae853SAndroid Build Coastguard Worker             pu1_ref_mb_l0, pu1_ref_mb_l1, pu1_dst_buf, i4_ref_l0_stride, i4_ref_l1_stride,
2512*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->u4_subpel_buf_strd, MB_SIZE, MB_SIZE);
2513*495ae853SAndroid Build Coastguard Worker 
2514*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->pf_ime_compute_sad_16x16[u4_fast_sad](
2515*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->pu1_src_buf_luma, pu1_dst_buf, ps_me_ctxt->i4_src_strd,
2516*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->u4_subpel_buf_strd, INT_MAX, &i4_mb_distortion);
2517*495ae853SAndroid Build Coastguard Worker 
2518*495ae853SAndroid Build Coastguard Worker         /* compute cost */
2519*495ae853SAndroid Build Coastguard Worker         i4_mb_cost =
2520*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt
2521*495ae853SAndroid Build Coastguard Worker                 ->pu1_mv_bits[ps_me_ctxt->as_mv_init_search[BI][i].i2_mvx - ps_l0_pred_mv->i2_mvx];
2522*495ae853SAndroid Build Coastguard Worker         i4_mb_cost +=
2523*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt
2524*495ae853SAndroid Build Coastguard Worker                 ->pu1_mv_bits[ps_me_ctxt->as_mv_init_search[BI][i].i2_mvy - ps_l0_pred_mv->i2_mvy];
2525*495ae853SAndroid Build Coastguard Worker         i4_mb_cost += ps_me_ctxt->pu1_mv_bits[ps_me_ctxt->as_mv_init_search[BI][i + 1].i2_mvx -
2526*495ae853SAndroid Build Coastguard Worker                                               ps_l1_pred_mv->i2_mvx];
2527*495ae853SAndroid Build Coastguard Worker         i4_mb_cost += ps_me_ctxt->pu1_mv_bits[ps_me_ctxt->as_mv_init_search[BI][i + 1].i2_mvy -
2528*495ae853SAndroid Build Coastguard Worker                                               ps_l1_pred_mv->i2_mvy];
2529*495ae853SAndroid Build Coastguard Worker 
2530*495ae853SAndroid Build Coastguard Worker         i4_mb_cost -=
2531*495ae853SAndroid Build Coastguard Worker             (ps_me_ctxt->i4_skip_bias[BSLICE]) * (ps_me_ctxt->i4_skip_type == BI) * (i == 0);
2532*495ae853SAndroid Build Coastguard Worker 
2533*495ae853SAndroid Build Coastguard Worker         i4_mb_cost *= ps_me_ctxt->u4_lambda_motion;
2534*495ae853SAndroid Build Coastguard Worker         i4_mb_cost += i4_mb_distortion;
2535*495ae853SAndroid Build Coastguard Worker 
2536*495ae853SAndroid Build Coastguard Worker         if(i4_mb_cost < ps_mb_ctxt_bi->i4_mb_cost)
2537*495ae853SAndroid Build Coastguard Worker         {
2538*495ae853SAndroid Build Coastguard Worker             ps_mb_ctxt_bi->i4_srch_pos_idx = (i >> 1);
2539*495ae853SAndroid Build Coastguard Worker             ps_mb_ctxt_bi->i4_mb_cost = i4_mb_cost;
2540*495ae853SAndroid Build Coastguard Worker             ps_mb_ctxt_bi->i4_mb_distortion = i4_mb_distortion;
2541*495ae853SAndroid Build Coastguard Worker             ps_mb_ctxt_bi->pu1_best_hpel_buf = pu1_dst_buf;
2542*495ae853SAndroid Build Coastguard Worker             i4_dest_buff = (i4_dest_buff + 1) % 2;
2543*495ae853SAndroid Build Coastguard Worker         }
2544*495ae853SAndroid Build Coastguard Worker     }
2545*495ae853SAndroid Build Coastguard Worker }
2546*495ae853SAndroid Build Coastguard Worker 
2547*495ae853SAndroid Build Coastguard Worker /**
2548*495ae853SAndroid Build Coastguard Worker *******************************************************************************
2549*495ae853SAndroid Build Coastguard Worker *
2550*495ae853SAndroid Build Coastguard Worker * @brief This function performs motion estimation for the current mb
2551*495ae853SAndroid Build Coastguard Worker *
2552*495ae853SAndroid Build Coastguard Worker * @par Description:
2553*495ae853SAndroid Build Coastguard Worker *  The current mb is compared with a list of mb's in the reference frame for
2554*495ae853SAndroid Build Coastguard Worker *  least cost. The mb that offers least cost is chosen as predicted mb and the
2555*495ae853SAndroid Build Coastguard Worker *  displacement of the predicted mb from index location of the current mb is
2556*495ae853SAndroid Build Coastguard Worker *  signaled as mv. The list of the mb's that are chosen in the reference frame
2557*495ae853SAndroid Build Coastguard Worker *  are dependent on the speed of the ME configured.
2558*495ae853SAndroid Build Coastguard Worker *
2559*495ae853SAndroid Build Coastguard Worker * @param[in] ps_proc
2560*495ae853SAndroid Build Coastguard Worker *  Process context corresponding to the job
2561*495ae853SAndroid Build Coastguard Worker *
2562*495ae853SAndroid Build Coastguard Worker * @returns  motion vector of the pred mb, sad, cost.
2563*495ae853SAndroid Build Coastguard Worker *
2564*495ae853SAndroid Build Coastguard Worker * @remarks none
2565*495ae853SAndroid Build Coastguard Worker *
2566*495ae853SAndroid Build Coastguard Worker *******************************************************************************
2567*495ae853SAndroid Build Coastguard Worker */
isvce_compute_me_multi_reflist(isvce_process_ctxt_t * ps_proc)2568*495ae853SAndroid Build Coastguard Worker void isvce_compute_me_multi_reflist(isvce_process_ctxt_t *ps_proc)
2569*495ae853SAndroid Build Coastguard Worker {
2570*495ae853SAndroid Build Coastguard Worker     /* me ctxt */
2571*495ae853SAndroid Build Coastguard Worker     isvce_me_ctxt_t *ps_me_ctxt = &ps_proc->s_me_ctxt;
2572*495ae853SAndroid Build Coastguard Worker 
2573*495ae853SAndroid Build Coastguard Worker     /* codec context */
2574*495ae853SAndroid Build Coastguard Worker     isvce_codec_t *ps_codec = ps_proc->ps_codec;
2575*495ae853SAndroid Build Coastguard Worker     isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
2576*495ae853SAndroid Build Coastguard Worker     inter_pred_fxns_t *ps_inter_pred_fxns = &ps_isa_dependent_fxns->s_inter_pred_fxns;
2577*495ae853SAndroid Build Coastguard Worker 
2578*495ae853SAndroid Build Coastguard Worker     /* Temp variables for looping over ref lists */
2579*495ae853SAndroid Build Coastguard Worker     WORD32 i4_reflist, i4_max_reflist;
2580*495ae853SAndroid Build Coastguard Worker 
2581*495ae853SAndroid Build Coastguard Worker     /* source buffer for halp pel generation functions */
2582*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_hpel_src;
2583*495ae853SAndroid Build Coastguard Worker 
2584*495ae853SAndroid Build Coastguard Worker     /* quantization parameters */
2585*495ae853SAndroid Build Coastguard Worker     quant_params_t *ps_qp_params = ps_proc->ps_qp_params[0];
2586*495ae853SAndroid Build Coastguard Worker 
2587*495ae853SAndroid Build Coastguard Worker     /* Mb part ctxts for SKIP */
2588*495ae853SAndroid Build Coastguard Worker     mb_part_ctxt as_skip_mbpart[2];
2589*495ae853SAndroid Build Coastguard Worker 
2590*495ae853SAndroid Build Coastguard Worker     ASSERT(1 == MAX_REF_FRAMES_PER_PRED_DIR);
2591*495ae853SAndroid Build Coastguard Worker 
2592*495ae853SAndroid Build Coastguard Worker     /* Sad therholds */
2593*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->pu2_sad_thrsh = ps_qp_params->pu2_sad_thrsh;
2594*495ae853SAndroid Build Coastguard Worker 
2595*495ae853SAndroid Build Coastguard Worker     {
2596*495ae853SAndroid Build Coastguard Worker         WORD32 rows_above, rows_below, columns_left, columns_right;
2597*495ae853SAndroid Build Coastguard Worker 
2598*495ae853SAndroid Build Coastguard Worker         /* During evaluation for motion vectors do not search through padded regions
2599*495ae853SAndroid Build Coastguard Worker          */
2600*495ae853SAndroid Build Coastguard Worker         /* Obtain number of rows and columns that are effective for computing for me
2601*495ae853SAndroid Build Coastguard Worker          * evaluation */
2602*495ae853SAndroid Build Coastguard Worker         rows_above = MB_SIZE + ps_proc->i4_mb_y * MB_SIZE;
2603*495ae853SAndroid Build Coastguard Worker         rows_below = (ps_proc->i4_ht_mbs - ps_proc->i4_mb_y) * MB_SIZE;
2604*495ae853SAndroid Build Coastguard Worker         columns_left = MB_SIZE + ps_proc->i4_mb_x * MB_SIZE;
2605*495ae853SAndroid Build Coastguard Worker         columns_right = (ps_proc->i4_wd_mbs - ps_proc->i4_mb_x) * MB_SIZE;
2606*495ae853SAndroid Build Coastguard Worker 
2607*495ae853SAndroid Build Coastguard Worker         /* init srch range */
2608*495ae853SAndroid Build Coastguard Worker         /* NOTE : For now, lets limit the search range by DEFAULT_MAX_SRCH_RANGE_X /
2609*495ae853SAndroid Build Coastguard Worker          * 2 on all sides.
2610*495ae853SAndroid Build Coastguard Worker          */
2611*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->i4_srch_range_w = -MIN(columns_left, DEFAULT_MAX_SRCH_RANGE_X >> 1);
2612*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->i4_srch_range_e = MIN(columns_right, DEFAULT_MAX_SRCH_RANGE_X >> 1);
2613*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->i4_srch_range_n = -MIN(rows_above, DEFAULT_MAX_SRCH_RANGE_Y >> 1);
2614*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->i4_srch_range_s = MIN(rows_below, DEFAULT_MAX_SRCH_RANGE_Y >> 1);
2615*495ae853SAndroid Build Coastguard Worker 
2616*495ae853SAndroid Build Coastguard Worker         /* this is to facilitate fast sub pel computation with minimal loads */
2617*495ae853SAndroid Build Coastguard Worker         if(ps_me_ctxt->u4_enable_hpel)
2618*495ae853SAndroid Build Coastguard Worker         {
2619*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->i4_srch_range_w += 1;
2620*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->i4_srch_range_e -= 1;
2621*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->i4_srch_range_n += 1;
2622*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->i4_srch_range_s -= 1;
2623*495ae853SAndroid Build Coastguard Worker         }
2624*495ae853SAndroid Build Coastguard Worker     }
2625*495ae853SAndroid Build Coastguard Worker 
2626*495ae853SAndroid Build Coastguard Worker     /* Compute ME and store the MVs */
2627*495ae853SAndroid Build Coastguard Worker     {
2628*495ae853SAndroid Build Coastguard Worker         /***********************************************************************
2629*495ae853SAndroid Build Coastguard Worker          * Compute ME for lists L0 and L1
2630*495ae853SAndroid Build Coastguard Worker          *  For L0 -> L0 skip + L0
2631*495ae853SAndroid Build Coastguard Worker          *  for L1 -> L0 skip + L0 + L1 skip + L1
2632*495ae853SAndroid Build Coastguard Worker          ***********************************************************************/
2633*495ae853SAndroid Build Coastguard Worker         i4_max_reflist = (ps_proc->i4_slice_type == PSLICE) ? L0 : L1;
2634*495ae853SAndroid Build Coastguard Worker 
2635*495ae853SAndroid Build Coastguard Worker         /* Init SATQD for the current list */
2636*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->u4_min_sad_reached = 0;
2637*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->i4_min_sad = ps_proc->ps_cur_mb->u4_min_sad;
2638*495ae853SAndroid Build Coastguard Worker 
2639*495ae853SAndroid Build Coastguard Worker         for(i4_reflist = L0; i4_reflist <= i4_max_reflist; i4_reflist++)
2640*495ae853SAndroid Build Coastguard Worker         {
2641*495ae853SAndroid Build Coastguard Worker             /* Get the seed motion vector candidates                    */
2642*495ae853SAndroid Build Coastguard Worker             isvce_get_search_candidates(ps_proc, ps_me_ctxt, i4_reflist);
2643*495ae853SAndroid Build Coastguard Worker 
2644*495ae853SAndroid Build Coastguard Worker             /* ****************************************************************
2645*495ae853SAndroid Build Coastguard Worker              *Evaluate the SKIP for current list
2646*495ae853SAndroid Build Coastguard Worker              * ****************************************************************/
2647*495ae853SAndroid Build Coastguard Worker             as_skip_mbpart[i4_reflist].s_mv_curr.i2_mvx = 0;
2648*495ae853SAndroid Build Coastguard Worker             as_skip_mbpart[i4_reflist].s_mv_curr.i2_mvy = 0;
2649*495ae853SAndroid Build Coastguard Worker             as_skip_mbpart[i4_reflist].i4_mb_cost = INT_MAX;
2650*495ae853SAndroid Build Coastguard Worker             as_skip_mbpart[i4_reflist].i4_mb_distortion = INT_MAX;
2651*495ae853SAndroid Build Coastguard Worker 
2652*495ae853SAndroid Build Coastguard Worker             if(ps_me_ctxt->i4_skip_type == i4_reflist)
2653*495ae853SAndroid Build Coastguard Worker             {
2654*495ae853SAndroid Build Coastguard Worker                 isvce_compute_skip_cost(
2655*495ae853SAndroid Build Coastguard Worker                     ps_me_ctxt, (ime_mv_t *) (&ps_proc->ps_skip_mv[i4_reflist].s_mv),
2656*495ae853SAndroid Build Coastguard Worker                     &as_skip_mbpart[i4_reflist], ps_codec->s_cfg.u4_enable_satqd, i4_reflist,
2657*495ae853SAndroid Build Coastguard Worker                     (ps_proc->i4_slice_type == BSLICE));
2658*495ae853SAndroid Build Coastguard Worker             }
2659*495ae853SAndroid Build Coastguard Worker 
2660*495ae853SAndroid Build Coastguard Worker             as_skip_mbpart[i4_reflist].s_mv_curr.i2_mvx <<= 2;
2661*495ae853SAndroid Build Coastguard Worker             as_skip_mbpart[i4_reflist].s_mv_curr.i2_mvy <<= 2;
2662*495ae853SAndroid Build Coastguard Worker 
2663*495ae853SAndroid Build Coastguard Worker             /******************************************************************
2664*495ae853SAndroid Build Coastguard Worker              * Evaluate ME For current list
2665*495ae853SAndroid Build Coastguard Worker              *****************************************************************/
2666*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mb_part[i4_reflist].s_mv_curr.i2_mvx = 0;
2667*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mb_part[i4_reflist].s_mv_curr.i2_mvy = 0;
2668*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mb_part[i4_reflist].i4_mb_cost = INT_MAX;
2669*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mb_part[i4_reflist].i4_mb_distortion = INT_MAX;
2670*495ae853SAndroid Build Coastguard Worker 
2671*495ae853SAndroid Build Coastguard Worker             /* Init Hpel */
2672*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mb_part[i4_reflist].pu1_best_hpel_buf = NULL;
2673*495ae853SAndroid Build Coastguard Worker 
2674*495ae853SAndroid Build Coastguard Worker             /* In case we found out the minimum SAD, exit the ME eval */
2675*495ae853SAndroid Build Coastguard Worker             if(ps_me_ctxt->u4_min_sad_reached)
2676*495ae853SAndroid Build Coastguard Worker             {
2677*495ae853SAndroid Build Coastguard Worker                 i4_max_reflist = i4_reflist;
2678*495ae853SAndroid Build Coastguard Worker                 break;
2679*495ae853SAndroid Build Coastguard Worker             }
2680*495ae853SAndroid Build Coastguard Worker 
2681*495ae853SAndroid Build Coastguard Worker             /* Evaluate search candidates for initial mv pt */
2682*495ae853SAndroid Build Coastguard Worker             isvce_evaluate_init_srchposn_16x16(ps_me_ctxt, i4_reflist);
2683*495ae853SAndroid Build Coastguard Worker 
2684*495ae853SAndroid Build Coastguard Worker             /********************************************************************/
2685*495ae853SAndroid Build Coastguard Worker             /*                  full pel motion estimation                      */
2686*495ae853SAndroid Build Coastguard Worker             /********************************************************************/
2687*495ae853SAndroid Build Coastguard Worker             isvce_full_pel_motion_estimation_16x16(ps_me_ctxt, i4_reflist);
2688*495ae853SAndroid Build Coastguard Worker 
2689*495ae853SAndroid Build Coastguard Worker             DEBUG_MV_HISTOGRAM_ADD((ps_me_ctxt->s_mb_part.s_mv_curr.i2_mvx >> 2),
2690*495ae853SAndroid Build Coastguard Worker                                    (ps_me_ctxt->s_mb_part.s_mv_curr.i2_mvy >> 2));
2691*495ae853SAndroid Build Coastguard Worker 
2692*495ae853SAndroid Build Coastguard Worker             DEBUG_SAD_HISTOGRAM_ADD(ps_me_ctxt->s_mb_part.i4_mb_distortion, 1);
2693*495ae853SAndroid Build Coastguard Worker 
2694*495ae853SAndroid Build Coastguard Worker             /* Scale the MV to qpel resolution */
2695*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mb_part[i4_reflist].s_mv_curr.i2_mvx <<= 2;
2696*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mb_part[i4_reflist].s_mv_curr.i2_mvy <<= 2;
2697*495ae853SAndroid Build Coastguard Worker 
2698*495ae853SAndroid Build Coastguard Worker             if(ps_me_ctxt->u4_enable_hpel)
2699*495ae853SAndroid Build Coastguard Worker             {
2700*495ae853SAndroid Build Coastguard Worker                 /* moving src pointer to the converged motion vector location */
2701*495ae853SAndroid Build Coastguard Worker                 pu1_hpel_src = ps_me_ctxt->apu1_ref_buf_luma[i4_reflist] +
2702*495ae853SAndroid Build Coastguard Worker                                (ps_me_ctxt->as_mb_part[i4_reflist].s_mv_curr.i2_mvx >> 2) +
2703*495ae853SAndroid Build Coastguard Worker                                ((ps_me_ctxt->as_mb_part[i4_reflist].s_mv_curr.i2_mvy >> 2) *
2704*495ae853SAndroid Build Coastguard Worker                                 ps_me_ctxt->ai4_rec_strd[i4_reflist]);
2705*495ae853SAndroid Build Coastguard Worker 
2706*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->apu1_subpel_buffs[0] = ps_proc->apu1_subpel_buffs[0];
2707*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->apu1_subpel_buffs[1] = ps_proc->apu1_subpel_buffs[1];
2708*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->apu1_subpel_buffs[2] = ps_proc->apu1_subpel_buffs[2];
2709*495ae853SAndroid Build Coastguard Worker 
2710*495ae853SAndroid Build Coastguard Worker                 /* Init the search position to an invalid number */
2711*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->as_mb_part[i4_reflist].i4_srch_pos_idx = 3;
2712*495ae853SAndroid Build Coastguard Worker 
2713*495ae853SAndroid Build Coastguard Worker                 /* Incase a buffer is still in use by L0, replace it with spare buff */
2714*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->apu1_subpel_buffs[ps_me_ctxt->as_mb_part[L0].i4_srch_pos_idx] =
2715*495ae853SAndroid Build Coastguard Worker                     ps_proc->apu1_subpel_buffs[3];
2716*495ae853SAndroid Build Coastguard Worker 
2717*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->u4_subpel_buf_strd = HP_BUFF_WD;
2718*495ae853SAndroid Build Coastguard Worker 
2719*495ae853SAndroid Build Coastguard Worker                 /* half  pel search is done for both sides of full pel,
2720*495ae853SAndroid Build Coastguard Worker                  * hence half_x of width x height = 17x16 is created
2721*495ae853SAndroid Build Coastguard Worker                  * starting from left half_x of converged full pel */
2722*495ae853SAndroid Build Coastguard Worker                 pu1_hpel_src -= 1;
2723*495ae853SAndroid Build Coastguard Worker 
2724*495ae853SAndroid Build Coastguard Worker                 /* computing half_x */
2725*495ae853SAndroid Build Coastguard Worker                 ps_codec->pf_ih264e_sixtapfilter_horz(
2726*495ae853SAndroid Build Coastguard Worker                     pu1_hpel_src, ps_me_ctxt->apu1_subpel_buffs[0],
2727*495ae853SAndroid Build Coastguard Worker                     ps_me_ctxt->ai4_rec_strd[i4_reflist], ps_me_ctxt->u4_subpel_buf_strd);
2728*495ae853SAndroid Build Coastguard Worker 
2729*495ae853SAndroid Build Coastguard Worker                 /*
2730*495ae853SAndroid Build Coastguard Worker                  * Halfpel search is done for both sides of full pel,
2731*495ae853SAndroid Build Coastguard Worker                  * hence half_y of width x height = 16x17 is created
2732*495ae853SAndroid Build Coastguard Worker                  * starting from top half_y of converged full pel
2733*495ae853SAndroid Build Coastguard Worker                  * for half_xy top_left is required
2734*495ae853SAndroid Build Coastguard Worker                  * hence it starts from pu1_hpel_src = full_pel_converged_point -
2735*495ae853SAndroid Build Coastguard Worker                  * i4_rec_strd - 1
2736*495ae853SAndroid Build Coastguard Worker                  */
2737*495ae853SAndroid Build Coastguard Worker                 pu1_hpel_src -= ps_me_ctxt->ai4_rec_strd[i4_reflist];
2738*495ae853SAndroid Build Coastguard Worker 
2739*495ae853SAndroid Build Coastguard Worker                 /* computing half_y and half_xy */
2740*495ae853SAndroid Build Coastguard Worker                 ps_codec->pf_ih264e_sixtap_filter_2dvh_vert(
2741*495ae853SAndroid Build Coastguard Worker                     pu1_hpel_src, ps_me_ctxt->apu1_subpel_buffs[1],
2742*495ae853SAndroid Build Coastguard Worker                     ps_me_ctxt->apu1_subpel_buffs[2], ps_me_ctxt->ai4_rec_strd[i4_reflist],
2743*495ae853SAndroid Build Coastguard Worker                     ps_me_ctxt->u4_subpel_buf_strd, ps_proc->ai16_pred1 + 3,
2744*495ae853SAndroid Build Coastguard Worker                     ps_me_ctxt->u4_subpel_buf_strd);
2745*495ae853SAndroid Build Coastguard Worker 
2746*495ae853SAndroid Build Coastguard Worker                 isvce_sub_pel_motion_estimation_16x16(ps_me_ctxt, i4_reflist);
2747*495ae853SAndroid Build Coastguard Worker             }
2748*495ae853SAndroid Build Coastguard Worker         }
2749*495ae853SAndroid Build Coastguard Worker 
2750*495ae853SAndroid Build Coastguard Worker         /***********************************************************************
2751*495ae853SAndroid Build Coastguard Worker          * If a particular skiip Mv is giving better sad, copy to the corresponding
2752*495ae853SAndroid Build Coastguard Worker          * MBPART
2753*495ae853SAndroid Build Coastguard Worker          * In B slices this loop should go only to PREDL1: If we found min sad
2754*495ae853SAndroid Build Coastguard Worker          * we will go to the skip ref list only
2755*495ae853SAndroid Build Coastguard Worker          * Have to find a way to make it without too much change or new vars
2756*495ae853SAndroid Build Coastguard Worker          **********************************************************************/
2757*495ae853SAndroid Build Coastguard Worker         for(i4_reflist = 0; i4_reflist <= i4_max_reflist; i4_reflist++)
2758*495ae853SAndroid Build Coastguard Worker         {
2759*495ae853SAndroid Build Coastguard Worker             if(as_skip_mbpart[i4_reflist].i4_mb_cost <
2760*495ae853SAndroid Build Coastguard Worker                ps_me_ctxt->as_mb_part[i4_reflist].i4_mb_cost)
2761*495ae853SAndroid Build Coastguard Worker             {
2762*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->as_mb_part[i4_reflist].i4_mb_cost =
2763*495ae853SAndroid Build Coastguard Worker                     as_skip_mbpart[i4_reflist].i4_mb_cost;
2764*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->as_mb_part[i4_reflist].i4_mb_distortion =
2765*495ae853SAndroid Build Coastguard Worker                     as_skip_mbpart[i4_reflist].i4_mb_distortion;
2766*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->as_mb_part[i4_reflist].s_mv_curr = as_skip_mbpart[i4_reflist].s_mv_curr;
2767*495ae853SAndroid Build Coastguard Worker             }
2768*495ae853SAndroid Build Coastguard Worker         }
2769*495ae853SAndroid Build Coastguard Worker 
2770*495ae853SAndroid Build Coastguard Worker         /***********************************************************************
2771*495ae853SAndroid Build Coastguard Worker          * Compute ME for BI
2772*495ae853SAndroid Build Coastguard Worker          *  In case of BI we do ME for two candidates
2773*495ae853SAndroid Build Coastguard Worker          *   1) The best L0 and L1 Mvs
2774*495ae853SAndroid Build Coastguard Worker          *   2) Skip L0 and L1 MVs
2775*495ae853SAndroid Build Coastguard Worker          *
2776*495ae853SAndroid Build Coastguard Worker          *   TODO
2777*495ae853SAndroid Build Coastguard Worker          *   one of the search candidates is skip. Hence it may be duplicated
2778*495ae853SAndroid Build Coastguard Worker          ***********************************************************************/
2779*495ae853SAndroid Build Coastguard Worker         if(i4_max_reflist == L1 && ps_me_ctxt->u4_min_sad_reached == 0)
2780*495ae853SAndroid Build Coastguard Worker         {
2781*495ae853SAndroid Build Coastguard Worker             WORD32 i, j = 0;
2782*495ae853SAndroid Build Coastguard Worker             WORD32 l0_srch_pos_idx, l1_srch_pos_idx;
2783*495ae853SAndroid Build Coastguard Worker             WORD32 i4_l0_skip_mv_idx, i4_l1_skip_mv_idx;
2784*495ae853SAndroid Build Coastguard Worker 
2785*495ae853SAndroid Build Coastguard Worker             /* Get the free buffers */
2786*495ae853SAndroid Build Coastguard Worker             l0_srch_pos_idx = ps_me_ctxt->as_mb_part[L0].i4_srch_pos_idx;
2787*495ae853SAndroid Build Coastguard Worker             l1_srch_pos_idx = ps_me_ctxt->as_mb_part[L1].i4_srch_pos_idx;
2788*495ae853SAndroid Build Coastguard Worker 
2789*495ae853SAndroid Build Coastguard Worker             /* Search for the two free buffers in subpel list */
2790*495ae853SAndroid Build Coastguard Worker             for(i = 0; i < SUBPEL_BUFF_CNT; i++)
2791*495ae853SAndroid Build Coastguard Worker             {
2792*495ae853SAndroid Build Coastguard Worker                 if(i != l0_srch_pos_idx && i != l1_srch_pos_idx)
2793*495ae853SAndroid Build Coastguard Worker                 {
2794*495ae853SAndroid Build Coastguard Worker                     ps_me_ctxt->apu1_subpel_buffs[j] = ps_proc->apu1_subpel_buffs[i];
2795*495ae853SAndroid Build Coastguard Worker                     j++;
2796*495ae853SAndroid Build Coastguard Worker                 }
2797*495ae853SAndroid Build Coastguard Worker             }
2798*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->u4_subpel_buf_strd = HP_BUFF_WD;
2799*495ae853SAndroid Build Coastguard Worker 
2800*495ae853SAndroid Build Coastguard Worker             /* Copy the statial SKIP MV of each list */
2801*495ae853SAndroid Build Coastguard Worker             i4_l0_skip_mv_idx = ps_me_ctxt->u4_num_candidates[L0] - 2;
2802*495ae853SAndroid Build Coastguard Worker             i4_l1_skip_mv_idx = ps_me_ctxt->u4_num_candidates[L1] - 2;
2803*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mv_init_search[BI][0].i2_mvx =
2804*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->as_mv_init_search[L0][i4_l0_skip_mv_idx].i2_mvx << 2;
2805*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mv_init_search[BI][0].i2_mvy =
2806*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->as_mv_init_search[L0][i4_l0_skip_mv_idx].i2_mvy << 2;
2807*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mv_init_search[BI][1].i2_mvx =
2808*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->as_mv_init_search[L1][i4_l1_skip_mv_idx].i2_mvx << 2;
2809*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mv_init_search[BI][1].i2_mvy =
2810*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->as_mv_init_search[L1][i4_l1_skip_mv_idx].i2_mvy << 2;
2811*495ae853SAndroid Build Coastguard Worker 
2812*495ae853SAndroid Build Coastguard Worker             /* Copy the SKIP MV temporal of each list */
2813*495ae853SAndroid Build Coastguard Worker             i4_l0_skip_mv_idx++;
2814*495ae853SAndroid Build Coastguard Worker             i4_l1_skip_mv_idx++;
2815*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mv_init_search[BI][2].i2_mvx =
2816*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->as_mv_init_search[L0][i4_l0_skip_mv_idx].i2_mvx << 2;
2817*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mv_init_search[BI][2].i2_mvy =
2818*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->as_mv_init_search[L0][i4_l0_skip_mv_idx].i2_mvy << 2;
2819*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mv_init_search[BI][3].i2_mvx =
2820*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->as_mv_init_search[L1][i4_l1_skip_mv_idx].i2_mvx << 2;
2821*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mv_init_search[BI][3].i2_mvy =
2822*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->as_mv_init_search[L1][i4_l1_skip_mv_idx].i2_mvy << 2;
2823*495ae853SAndroid Build Coastguard Worker 
2824*495ae853SAndroid Build Coastguard Worker             /* Copy the best MV after ME */
2825*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mv_init_search[BI][4] = ps_me_ctxt->as_mb_part[L0].s_mv_curr;
2826*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mv_init_search[BI][5] = ps_me_ctxt->as_mb_part[L1].s_mv_curr;
2827*495ae853SAndroid Build Coastguard Worker 
2828*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->u4_num_candidates[BI] = 6;
2829*495ae853SAndroid Build Coastguard Worker 
2830*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mb_part[BI].i4_mb_cost = INT_MAX;
2831*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mb_part[BI].i4_mb_distortion = INT_MAX;
2832*495ae853SAndroid Build Coastguard Worker 
2833*495ae853SAndroid Build Coastguard Worker             isvce_evaluate_bipred(ps_me_ctxt, ps_proc, &ps_me_ctxt->as_mb_part[BI]);
2834*495ae853SAndroid Build Coastguard Worker 
2835*495ae853SAndroid Build Coastguard Worker             i4_max_reflist = BI;
2836*495ae853SAndroid Build Coastguard Worker         }
2837*495ae853SAndroid Build Coastguard Worker 
2838*495ae853SAndroid Build Coastguard Worker         /**********************************************************************
2839*495ae853SAndroid Build Coastguard Worker          * Now get the minimum of MB part sads by searching over all ref lists
2840*495ae853SAndroid Build Coastguard Worker          **********************************************************************/
2841*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_mb_info->as_pu->u1_pred_mode = 0x3;
2842*495ae853SAndroid Build Coastguard Worker 
2843*495ae853SAndroid Build Coastguard Worker         for(i4_reflist = 0; i4_reflist <= i4_max_reflist; i4_reflist++)
2844*495ae853SAndroid Build Coastguard Worker         {
2845*495ae853SAndroid Build Coastguard Worker             if(ps_me_ctxt->as_mb_part[i4_reflist].i4_mb_cost < ps_proc->ps_cur_mb->i4_mb_cost)
2846*495ae853SAndroid Build Coastguard Worker             {
2847*495ae853SAndroid Build Coastguard Worker                 ps_proc->ps_cur_mb->i4_mb_cost = ps_me_ctxt->as_mb_part[i4_reflist].i4_mb_cost;
2848*495ae853SAndroid Build Coastguard Worker                 ps_proc->ps_cur_mb->i4_mb_distortion =
2849*495ae853SAndroid Build Coastguard Worker                     ps_me_ctxt->as_mb_part[i4_reflist].i4_mb_distortion;
2850*495ae853SAndroid Build Coastguard Worker                 ps_proc->ps_cur_mb->u4_mb_type =
2851*495ae853SAndroid Build Coastguard Worker                     (ps_proc->i4_slice_type == PSLICE) ? P16x16 : B16x16;
2852*495ae853SAndroid Build Coastguard Worker                 ps_proc->ps_mb_info->as_pu->u1_pred_mode = i4_reflist;
2853*495ae853SAndroid Build Coastguard Worker             }
2854*495ae853SAndroid Build Coastguard Worker         }
2855*495ae853SAndroid Build Coastguard Worker 
2856*495ae853SAndroid Build Coastguard Worker         /**********************************************************************
2857*495ae853SAndroid Build Coastguard Worker          * In case we have a BI MB, we have to copy the buffers and set proer MV's
2858*495ae853SAndroid Build Coastguard Worker          *  1)In case its BI, we need to get the best MVs given by BI and update
2859*495ae853SAndroid Build Coastguard Worker          *    to their corresponding MB part
2860*495ae853SAndroid Build Coastguard Worker          *  2)We also need to copy the buffer in which bipred buff is populated
2861*495ae853SAndroid Build Coastguard Worker          *
2862*495ae853SAndroid Build Coastguard Worker          *  Not that if we have
2863*495ae853SAndroid Build Coastguard Worker          **********************************************************************/
2864*495ae853SAndroid Build Coastguard Worker         if(ps_proc->ps_mb_info->as_pu->u1_pred_mode == BI)
2865*495ae853SAndroid Build Coastguard Worker         {
2866*495ae853SAndroid Build Coastguard Worker             WORD32 i4_srch_pos = ps_me_ctxt->as_mb_part[BI].i4_srch_pos_idx;
2867*495ae853SAndroid Build Coastguard Worker             UWORD8 *pu1_bi_buf = ps_me_ctxt->as_mb_part[BI].pu1_best_hpel_buf;
2868*495ae853SAndroid Build Coastguard Worker 
2869*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mb_part[L0].s_mv_curr =
2870*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->as_mv_init_search[BI][i4_srch_pos << 1];
2871*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mb_part[L1].s_mv_curr =
2872*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->as_mv_init_search[BI][(i4_srch_pos << 1) + 1];
2873*495ae853SAndroid Build Coastguard Worker 
2874*495ae853SAndroid Build Coastguard Worker             /* Now we have to copy the buffers */
2875*495ae853SAndroid Build Coastguard Worker             ps_inter_pred_fxns->pf_inter_pred_luma_copy(
2876*495ae853SAndroid Build Coastguard Worker                 pu1_bi_buf, ps_proc->pu1_best_subpel_buf, ps_me_ctxt->u4_subpel_buf_strd,
2877*495ae853SAndroid Build Coastguard Worker                 ps_proc->u4_bst_spel_buf_strd, MB_SIZE, MB_SIZE, NULL, 0);
2878*495ae853SAndroid Build Coastguard Worker         }
2879*495ae853SAndroid Build Coastguard Worker         else if(ps_me_ctxt->as_mb_part[ps_proc->ps_mb_info->as_pu->u1_pred_mode].pu1_best_hpel_buf)
2880*495ae853SAndroid Build Coastguard Worker         {
2881*495ae853SAndroid Build Coastguard Worker             /* Now we have to copy the buffers */
2882*495ae853SAndroid Build Coastguard Worker             ps_inter_pred_fxns->pf_inter_pred_luma_copy(
2883*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->as_mb_part[ps_proc->ps_mb_info->as_pu->u1_pred_mode].pu1_best_hpel_buf,
2884*495ae853SAndroid Build Coastguard Worker                 ps_proc->pu1_best_subpel_buf, ps_me_ctxt->u4_subpel_buf_strd,
2885*495ae853SAndroid Build Coastguard Worker                 ps_proc->u4_bst_spel_buf_strd, MB_SIZE, MB_SIZE, NULL, 0);
2886*495ae853SAndroid Build Coastguard Worker         }
2887*495ae853SAndroid Build Coastguard Worker     }
2888*495ae853SAndroid Build Coastguard Worker 
2889*495ae853SAndroid Build Coastguard Worker     /**************************************************************************
2890*495ae853SAndroid Build Coastguard Worker      *Now copy the MVs to the current PU with qpel scaling
2891*495ae853SAndroid Build Coastguard Worker      ***************************************************************************/
2892*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvx =
2893*495ae853SAndroid Build Coastguard Worker         (ps_me_ctxt->as_mb_part[L0].s_mv_curr.i2_mvx);
2894*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvy =
2895*495ae853SAndroid Build Coastguard Worker         (ps_me_ctxt->as_mb_part[L0].s_mv_curr.i2_mvy);
2896*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_mb_info->as_pu->as_me_info[L1].s_mv.i2_mvx =
2897*495ae853SAndroid Build Coastguard Worker         (ps_me_ctxt->as_mb_part[L1].s_mv_curr.i2_mvx);
2898*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_mb_info->as_pu->as_me_info[L1].s_mv.i2_mvy =
2899*495ae853SAndroid Build Coastguard Worker         (ps_me_ctxt->as_mb_part[L1].s_mv_curr.i2_mvy);
2900*495ae853SAndroid Build Coastguard Worker 
2901*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_mb_info->as_pu->as_me_info[0].i1_ref_idx =
2902*495ae853SAndroid Build Coastguard Worker         (ps_proc->ps_mb_info->as_pu->u1_pred_mode != L1) ? 0 : -1;
2903*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_mb_info->as_pu->as_me_info[1].i1_ref_idx =
2904*495ae853SAndroid Build Coastguard Worker         (ps_proc->ps_mb_info->as_pu->u1_pred_mode != L0) ? 0 : -1;
2905*495ae853SAndroid Build Coastguard Worker 
2906*495ae853SAndroid Build Coastguard Worker     /* number of partitions */
2907*495ae853SAndroid Build Coastguard Worker     ps_proc->u4_num_sub_partitions = 1;
2908*495ae853SAndroid Build Coastguard Worker     *(ps_proc->pu4_mb_pu_cnt) = 1;
2909*495ae853SAndroid Build Coastguard Worker 
2910*495ae853SAndroid Build Coastguard Worker     /* position in-terms of PU */
2911*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_mb_info->as_pu->u1_pos_x_in_4x4 = 0;
2912*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_mb_info->as_pu->u1_pos_y_in_4x4 = 0;
2913*495ae853SAndroid Build Coastguard Worker 
2914*495ae853SAndroid Build Coastguard Worker     /* PU size */
2915*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_mb_info->as_pu->u1_wd_in_4x4_m1 = 3;
2916*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_mb_info->as_pu->u1_ht_in_4x4_m1 = 3;
2917*495ae853SAndroid Build Coastguard Worker 
2918*495ae853SAndroid Build Coastguard Worker     /* Update min sad conditions */
2919*495ae853SAndroid Build Coastguard Worker     if(ps_me_ctxt->u4_min_sad_reached == 1)
2920*495ae853SAndroid Build Coastguard Worker     {
2921*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_cur_mb->u4_min_sad_reached = 1;
2922*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_cur_mb->u4_min_sad = ps_me_ctxt->i4_min_sad;
2923*495ae853SAndroid Build Coastguard Worker     }
2924*495ae853SAndroid Build Coastguard Worker }
2925