xref: /aosp_15_r20/external/libavc/encoder/ih264e_me.c (revision 495ae853bb871d1e5a258cb02c2cc13cde8ddb9a)
1*495ae853SAndroid Build Coastguard Worker /******************************************************************************
2*495ae853SAndroid Build Coastguard Worker  *
3*495ae853SAndroid Build Coastguard Worker  * Copyright (C) 2015 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 *  ih264e_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 *  - ih264e_init_mv_bits
34*495ae853SAndroid Build Coastguard Worker *  - ih264e_get_search_candidates
35*495ae853SAndroid Build Coastguard Worker *  - ih264e_find_pskip_params
36*495ae853SAndroid Build Coastguard Worker *  - ih264e_find_pskip_params_me
37*495ae853SAndroid Build Coastguard Worker *  - ih264e_get_mv_predictor
38*495ae853SAndroid Build Coastguard Worker *  - ih264e_mv_pred
39*495ae853SAndroid Build Coastguard Worker *  - ih264e_mv_pred_me
40*495ae853SAndroid Build Coastguard Worker *  - ih264e_compute_me_single_reflist
41*495ae853SAndroid Build Coastguard Worker *  - ih264e_compute_me_nmb
42*495ae853SAndroid Build Coastguard Worker *  - ih264e_find_bskip_params_me
43*495ae853SAndroid Build Coastguard Worker *  - ih264e_find_bskip_params
44*495ae853SAndroid Build Coastguard Worker *  - ih264e_evaluate_bipred
45*495ae853SAndroid Build Coastguard Worker *  - ih264e_compute_me_multi_reflist
46*495ae853SAndroid Build Coastguard Worker *
47*495ae853SAndroid Build Coastguard Worker * @remarks
48*495ae853SAndroid Build Coastguard Worker *  none
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 /*****************************************************************************/
54*495ae853SAndroid Build Coastguard Worker /* File Includes                                                             */
55*495ae853SAndroid Build Coastguard Worker /*****************************************************************************/
56*495ae853SAndroid Build Coastguard Worker 
57*495ae853SAndroid Build Coastguard Worker /* System Include Files */
58*495ae853SAndroid Build Coastguard Worker #include <stdio.h>
59*495ae853SAndroid Build Coastguard Worker #include <assert.h>
60*495ae853SAndroid Build Coastguard Worker #include <limits.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 "iv2.h"
65*495ae853SAndroid Build Coastguard Worker #include "ive2.h"
66*495ae853SAndroid Build Coastguard Worker #include "ithread.h"
67*495ae853SAndroid Build Coastguard Worker 
68*495ae853SAndroid Build Coastguard Worker #include "ih264_debug.h"
69*495ae853SAndroid Build Coastguard Worker #include "ih264_macros.h"
70*495ae853SAndroid Build Coastguard Worker #include "ih264_defs.h"
71*495ae853SAndroid Build Coastguard Worker #include "ih264_mem_fns.h"
72*495ae853SAndroid Build Coastguard Worker #include "ih264_padding.h"
73*495ae853SAndroid Build Coastguard Worker #include "ih264_structs.h"
74*495ae853SAndroid Build Coastguard Worker #include "ih264_trans_quant_itrans_iquant.h"
75*495ae853SAndroid Build Coastguard Worker #include "ih264_inter_pred_filters.h"
76*495ae853SAndroid Build Coastguard Worker #include "ih264_intra_pred_filters.h"
77*495ae853SAndroid Build Coastguard Worker #include "ih264_deblk_edge_filters.h"
78*495ae853SAndroid Build Coastguard Worker #include "ih264_cabac_tables.h"
79*495ae853SAndroid Build Coastguard Worker #include "ih264_platform_macros.h"
80*495ae853SAndroid Build Coastguard Worker 
81*495ae853SAndroid Build Coastguard Worker #include "ime_defs.h"
82*495ae853SAndroid Build Coastguard Worker #include "ime_distortion_metrics.h"
83*495ae853SAndroid Build Coastguard Worker #include "ime_structs.h"
84*495ae853SAndroid Build Coastguard Worker #include "ime.h"
85*495ae853SAndroid Build Coastguard Worker #include "ime_statistics.h"
86*495ae853SAndroid Build Coastguard Worker 
87*495ae853SAndroid Build Coastguard Worker #include "irc_cntrl_param.h"
88*495ae853SAndroid Build Coastguard Worker #include "irc_frame_info_collector.h"
89*495ae853SAndroid Build Coastguard Worker 
90*495ae853SAndroid Build Coastguard Worker #include "ih264e_error.h"
91*495ae853SAndroid Build Coastguard Worker #include "ih264e_defs.h"
92*495ae853SAndroid Build Coastguard Worker #include "ih264e_globals.h"
93*495ae853SAndroid Build Coastguard Worker #include "ih264e_rate_control.h"
94*495ae853SAndroid Build Coastguard Worker #include "ih264e_bitstream.h"
95*495ae853SAndroid Build Coastguard Worker #include "ih264e_cabac_structs.h"
96*495ae853SAndroid Build Coastguard Worker #include "ih264e_structs.h"
97*495ae853SAndroid Build Coastguard Worker #include "ih264e_mc.h"
98*495ae853SAndroid Build Coastguard Worker #include "ih264e_me.h"
99*495ae853SAndroid Build Coastguard Worker #include "ih264e_half_pel.h"
100*495ae853SAndroid Build Coastguard Worker #include "ih264e_intra_modes_eval.h"
101*495ae853SAndroid Build Coastguard Worker #include "ih264e_core_coding.h"
102*495ae853SAndroid Build Coastguard Worker #include "ih264e_platform_macros.h"
103*495ae853SAndroid Build Coastguard Worker 
104*495ae853SAndroid Build Coastguard Worker 
105*495ae853SAndroid Build Coastguard Worker /*****************************************************************************/
106*495ae853SAndroid Build Coastguard Worker /* Function Definitions                                                      */
107*495ae853SAndroid Build Coastguard Worker /*****************************************************************************/
108*495ae853SAndroid Build Coastguard Worker 
109*495ae853SAndroid Build Coastguard Worker /**
110*495ae853SAndroid Build Coastguard Worker *******************************************************************************
111*495ae853SAndroid Build Coastguard Worker *
112*495ae853SAndroid Build Coastguard Worker * @brief
113*495ae853SAndroid Build Coastguard Worker *  This function populates the length of the codewords for motion vectors in the
114*495ae853SAndroid Build Coastguard Worker *  range (-search range, search range) in pixels
115*495ae853SAndroid Build Coastguard Worker *
116*495ae853SAndroid Build Coastguard Worker * @param[in] ps_me
117*495ae853SAndroid Build Coastguard Worker *  Pointer to me ctxt
118*495ae853SAndroid Build Coastguard Worker *
119*495ae853SAndroid Build Coastguard Worker * @param[out] pu1_mv_bits
120*495ae853SAndroid Build Coastguard Worker *  length of the codeword for all mv's
121*495ae853SAndroid Build Coastguard Worker *
122*495ae853SAndroid Build Coastguard Worker * @remarks The length of the code words are derived from signed exponential
123*495ae853SAndroid Build Coastguard Worker *  goloumb codes.
124*495ae853SAndroid Build Coastguard Worker *
125*495ae853SAndroid Build Coastguard Worker *******************************************************************************
126*495ae853SAndroid Build Coastguard Worker */
ih264e_init_mv_bits(me_ctxt_t * ps_me_ctxt)127*495ae853SAndroid Build Coastguard Worker void ih264e_init_mv_bits(me_ctxt_t *ps_me_ctxt)
128*495ae853SAndroid Build Coastguard Worker {
129*495ae853SAndroid Build Coastguard Worker     /* temp var */
130*495ae853SAndroid Build Coastguard Worker     WORD32 i, codesize = 3, diff, limit;
131*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_code_num, u4_range;
132*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_uev_min, u4_uev_max, u4_sev_min, u4_sev_max;
133*495ae853SAndroid Build Coastguard Worker 
134*495ae853SAndroid Build Coastguard Worker     /* max srch range */
135*495ae853SAndroid Build Coastguard Worker     diff = MAX(DEFAULT_MAX_SRCH_RANGE_X, DEFAULT_MAX_SRCH_RANGE_Y);
136*495ae853SAndroid Build Coastguard Worker     /* sub pel */
137*495ae853SAndroid Build Coastguard Worker     diff <<= 2;
138*495ae853SAndroid Build Coastguard Worker     /* delta mv */
139*495ae853SAndroid Build Coastguard Worker     diff <<= 1;
140*495ae853SAndroid Build Coastguard Worker 
141*495ae853SAndroid Build Coastguard Worker     /* codeNum for positive integer     =  2x-1     : Table9-3  */
142*495ae853SAndroid Build Coastguard Worker     u4_code_num = (diff << 1);
143*495ae853SAndroid Build Coastguard Worker 
144*495ae853SAndroid Build Coastguard Worker     /* get range of the bit string and put using put_bits()                 */
145*495ae853SAndroid Build Coastguard Worker     GETRANGE(u4_range, u4_code_num);
146*495ae853SAndroid Build Coastguard Worker 
147*495ae853SAndroid Build Coastguard Worker     limit = 2*u4_range - 1;
148*495ae853SAndroid Build Coastguard Worker 
149*495ae853SAndroid Build Coastguard Worker     /* init mv bits */
150*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->pu1_mv_bits[0] = 1;
151*495ae853SAndroid Build Coastguard Worker 
152*495ae853SAndroid Build Coastguard Worker     while (codesize < limit)
153*495ae853SAndroid Build Coastguard Worker     {
154*495ae853SAndroid Build Coastguard Worker         u4_uev_min = (1 << (codesize >> 1));
155*495ae853SAndroid Build Coastguard Worker         u4_uev_max = 2*u4_uev_min - 1;
156*495ae853SAndroid Build Coastguard Worker 
157*495ae853SAndroid Build Coastguard Worker         u4_sev_min = u4_uev_min >> 1;
158*495ae853SAndroid Build Coastguard Worker         u4_sev_max = u4_uev_max >> 1;
159*495ae853SAndroid Build Coastguard Worker 
160*495ae853SAndroid Build Coastguard Worker         DEBUG("\n%d min, %d max %d codesize", u4_sev_min, u4_sev_max, codesize);
161*495ae853SAndroid Build Coastguard Worker 
162*495ae853SAndroid Build Coastguard Worker         for (i = u4_sev_min; i <= (WORD32)u4_sev_max; i++)
163*495ae853SAndroid Build Coastguard Worker         {
164*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->pu1_mv_bits[-i] = ps_me_ctxt->pu1_mv_bits[i] = codesize;
165*495ae853SAndroid Build Coastguard Worker         }
166*495ae853SAndroid Build Coastguard Worker 
167*495ae853SAndroid Build Coastguard Worker         codesize += 2;
168*495ae853SAndroid Build Coastguard Worker     }
169*495ae853SAndroid Build Coastguard Worker }
170*495ae853SAndroid Build Coastguard Worker 
171*495ae853SAndroid Build Coastguard Worker /**
172*495ae853SAndroid Build Coastguard Worker *******************************************************************************
173*495ae853SAndroid Build Coastguard Worker *
174*495ae853SAndroid Build Coastguard Worker * @brief Determines the valid candidates for which the initial search shall happen.
175*495ae853SAndroid Build Coastguard Worker * The best of these candidates is used to center the diamond pixel search.
176*495ae853SAndroid Build Coastguard Worker *
177*495ae853SAndroid Build Coastguard Worker * @par Description The function sends the skip, (0,0), left, top and top-right
178*495ae853SAndroid Build Coastguard Worker * neighbouring MBs MVs. The left, top and top-right MBs MVs are used because
179*495ae853SAndroid Build Coastguard Worker * these are the same MVs that are used to form the MV predictor. This initial MV
180*495ae853SAndroid Build Coastguard Worker * search candidates need not take care of slice boundaries and hence neighbor
181*495ae853SAndroid Build Coastguard Worker * availability checks are not made here.
182*495ae853SAndroid Build Coastguard Worker *
183*495ae853SAndroid Build Coastguard Worker * @param[in] ps_proc
184*495ae853SAndroid Build Coastguard Worker *  Pointer to process context
185*495ae853SAndroid Build Coastguard Worker *
186*495ae853SAndroid Build Coastguard Worker * @param[in] ps_me_ctxt
187*495ae853SAndroid Build Coastguard Worker *  pointer to me context
188*495ae853SAndroid Build Coastguard Worker *
189*495ae853SAndroid Build Coastguard Worker * @param[in] i4_ref_list
190*495ae853SAndroid Build Coastguard Worker *  Current active reference list
191*495ae853SAndroid Build Coastguard Worker *
192*495ae853SAndroid Build Coastguard Worker * @returns  The list of MVs to be used of priming the full pel search and the
193*495ae853SAndroid Build Coastguard Worker * number of such MVs
194*495ae853SAndroid Build Coastguard Worker *
195*495ae853SAndroid Build Coastguard Worker * @remarks
196*495ae853SAndroid Build Coastguard Worker *   Assumptions : 1. Assumes Only partition of size 16x16
197*495ae853SAndroid Build Coastguard Worker *
198*495ae853SAndroid Build Coastguard Worker *******************************************************************************
199*495ae853SAndroid Build Coastguard Worker */
ih264e_get_search_candidates(process_ctxt_t * ps_proc,me_ctxt_t * ps_me_ctxt,WORD32 i4_reflist)200*495ae853SAndroid Build Coastguard Worker static void ih264e_get_search_candidates(process_ctxt_t *ps_proc,
201*495ae853SAndroid Build Coastguard Worker                                          me_ctxt_t *ps_me_ctxt,
202*495ae853SAndroid Build Coastguard Worker                                          WORD32 i4_reflist)
203*495ae853SAndroid Build Coastguard Worker {
204*495ae853SAndroid Build Coastguard Worker     /* curr mb indices */
205*495ae853SAndroid Build Coastguard Worker     WORD32 i4_mb_x = ps_proc->i4_mb_x;
206*495ae853SAndroid Build Coastguard Worker 
207*495ae853SAndroid Build Coastguard Worker     /* Motion vector */
208*495ae853SAndroid Build Coastguard Worker     mv_t *ps_left_mv, *ps_top_mv, *ps_top_left_mv, *ps_top_right_mv;
209*495ae853SAndroid Build Coastguard Worker 
210*495ae853SAndroid Build Coastguard Worker     /* Pred modes */
211*495ae853SAndroid Build Coastguard Worker     WORD32 i4_left_mode, i4_top_mode, i4_top_left_mode, i4_top_right_mode;
212*495ae853SAndroid Build Coastguard Worker 
213*495ae853SAndroid Build Coastguard Worker     /* mb part info */
214*495ae853SAndroid Build Coastguard Worker     mb_part_ctxt *ps_mb_part = &ps_me_ctxt->as_mb_part[i4_reflist];
215*495ae853SAndroid Build Coastguard Worker 
216*495ae853SAndroid Build Coastguard Worker     /* mvs */
217*495ae853SAndroid Build Coastguard Worker     WORD32 mvx, mvy;
218*495ae853SAndroid Build Coastguard Worker 
219*495ae853SAndroid Build Coastguard Worker     /* ngbr availability */
220*495ae853SAndroid Build Coastguard Worker     block_neighbors_t *ps_ngbr_avbl = ps_proc->ps_ngbr_avbl;
221*495ae853SAndroid Build Coastguard Worker 
222*495ae853SAndroid Build Coastguard Worker     /* Current mode */
223*495ae853SAndroid Build Coastguard Worker     WORD32 i4_cmpl_predmode = (i4_reflist == 0) ? PRED_L1 : PRED_L0;
224*495ae853SAndroid Build Coastguard Worker 
225*495ae853SAndroid Build Coastguard Worker     /* srch range*/
226*495ae853SAndroid Build Coastguard Worker     WORD32 i4_srch_range_n = ps_me_ctxt->i4_srch_range_n;
227*495ae853SAndroid Build Coastguard Worker     WORD32 i4_srch_range_s = ps_me_ctxt->i4_srch_range_s;
228*495ae853SAndroid Build Coastguard Worker     WORD32 i4_srch_range_e = ps_me_ctxt->i4_srch_range_e;
229*495ae853SAndroid Build Coastguard Worker     WORD32 i4_srch_range_w = ps_me_ctxt->i4_srch_range_w;
230*495ae853SAndroid Build Coastguard Worker 
231*495ae853SAndroid Build Coastguard Worker     /* num of candidate search candidates */
232*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_num_candidates = 0;
233*495ae853SAndroid Build Coastguard Worker 
234*495ae853SAndroid Build Coastguard Worker     ps_left_mv = &ps_proc->s_left_mb_pu_ME.s_me_info[i4_reflist].s_mv;
235*495ae853SAndroid Build Coastguard Worker     ps_top_mv = &(ps_proc->ps_top_row_pu_ME + i4_mb_x)->s_me_info[i4_reflist].s_mv;
236*495ae853SAndroid Build Coastguard Worker     ps_top_left_mv = &ps_proc->s_top_left_mb_pu_ME.s_me_info[i4_reflist].s_mv;
237*495ae853SAndroid Build Coastguard Worker     ps_top_right_mv = &(ps_proc->ps_top_row_pu_ME + i4_mb_x + 1)->s_me_info[i4_reflist].s_mv;
238*495ae853SAndroid Build Coastguard Worker 
239*495ae853SAndroid Build Coastguard Worker     i4_left_mode = ps_proc->s_left_mb_pu_ME.b2_pred_mode != i4_cmpl_predmode;
240*495ae853SAndroid Build Coastguard Worker     i4_top_mode = (ps_proc->ps_top_row_pu_ME + i4_mb_x)->b2_pred_mode != i4_cmpl_predmode;
241*495ae853SAndroid Build Coastguard Worker     i4_top_left_mode = ps_proc->s_top_left_mb_pu_ME.b2_pred_mode != i4_cmpl_predmode;
242*495ae853SAndroid Build Coastguard Worker     i4_top_right_mode = (ps_proc->ps_top_row_pu_ME + i4_mb_x + 1)->b2_pred_mode != i4_cmpl_predmode;
243*495ae853SAndroid Build Coastguard Worker 
244*495ae853SAndroid Build Coastguard Worker     /* Taking the Zero motion vector as one of the candidates   */
245*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->as_mv_init_search[i4_reflist][u4_num_candidates].i2_mvx = 0;
246*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->as_mv_init_search[i4_reflist][u4_num_candidates].i2_mvy = 0;
247*495ae853SAndroid Build Coastguard Worker 
248*495ae853SAndroid Build Coastguard Worker     u4_num_candidates++;
249*495ae853SAndroid Build Coastguard Worker 
250*495ae853SAndroid Build Coastguard Worker     /* Taking the Left MV Predictor as one of the candidates    */
251*495ae853SAndroid Build Coastguard Worker     if (ps_ngbr_avbl->u1_mb_a && i4_left_mode)
252*495ae853SAndroid Build Coastguard Worker     {
253*495ae853SAndroid Build Coastguard Worker         mvx      = (ps_left_mv->i2_mvx + 2) >> 2;
254*495ae853SAndroid Build Coastguard Worker         mvy      = (ps_left_mv->i2_mvy + 2) >> 2;
255*495ae853SAndroid Build Coastguard Worker 
256*495ae853SAndroid Build Coastguard Worker         mvx = CLIP3(i4_srch_range_w, i4_srch_range_e, mvx);
257*495ae853SAndroid Build Coastguard Worker         mvy = CLIP3(i4_srch_range_n, i4_srch_range_s, mvy);
258*495ae853SAndroid Build Coastguard Worker 
259*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->as_mv_init_search[i4_reflist][u4_num_candidates].i2_mvx = mvx;
260*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->as_mv_init_search[i4_reflist][u4_num_candidates].i2_mvy = mvy;
261*495ae853SAndroid Build Coastguard Worker 
262*495ae853SAndroid Build Coastguard Worker         u4_num_candidates ++;
263*495ae853SAndroid Build Coastguard Worker     }
264*495ae853SAndroid Build Coastguard Worker 
265*495ae853SAndroid Build Coastguard Worker     /* Taking the Top MV Predictor as one of the candidates     */
266*495ae853SAndroid Build Coastguard Worker     if (ps_ngbr_avbl->u1_mb_b && i4_top_mode)
267*495ae853SAndroid Build Coastguard Worker     {
268*495ae853SAndroid Build Coastguard Worker         mvx      = (ps_top_mv->i2_mvx + 2) >> 2;
269*495ae853SAndroid Build Coastguard Worker         mvy      = (ps_top_mv->i2_mvy + 2) >> 2;
270*495ae853SAndroid Build Coastguard Worker 
271*495ae853SAndroid Build Coastguard Worker         mvx = CLIP3(i4_srch_range_w, i4_srch_range_e, mvx);
272*495ae853SAndroid Build Coastguard Worker         mvy = CLIP3(i4_srch_range_n, i4_srch_range_s, mvy);
273*495ae853SAndroid Build Coastguard Worker 
274*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->as_mv_init_search[i4_reflist][u4_num_candidates].i2_mvx = mvx;
275*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->as_mv_init_search[i4_reflist][u4_num_candidates].i2_mvy = mvy;
276*495ae853SAndroid Build Coastguard Worker 
277*495ae853SAndroid Build Coastguard Worker         u4_num_candidates ++;
278*495ae853SAndroid Build Coastguard Worker 
279*495ae853SAndroid Build Coastguard Worker         /* Taking the TopRt MV Predictor as one of the candidates   */
280*495ae853SAndroid Build Coastguard Worker         if (ps_ngbr_avbl->u1_mb_c && i4_top_right_mode)
281*495ae853SAndroid Build Coastguard Worker         {
282*495ae853SAndroid Build Coastguard Worker             mvx      = (ps_top_right_mv->i2_mvx + 2) >> 2;
283*495ae853SAndroid Build Coastguard Worker             mvy      = (ps_top_right_mv->i2_mvy + 2)>> 2;
284*495ae853SAndroid Build Coastguard Worker 
285*495ae853SAndroid Build Coastguard Worker             mvx = CLIP3(i4_srch_range_w, i4_srch_range_e, mvx);
286*495ae853SAndroid Build Coastguard Worker             mvy = CLIP3(i4_srch_range_n, i4_srch_range_s, mvy);
287*495ae853SAndroid Build Coastguard Worker 
288*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mv_init_search[i4_reflist][u4_num_candidates].i2_mvx = mvx;
289*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mv_init_search[i4_reflist][u4_num_candidates].i2_mvy = mvy;
290*495ae853SAndroid Build Coastguard Worker 
291*495ae853SAndroid Build Coastguard Worker             u4_num_candidates ++;
292*495ae853SAndroid Build Coastguard Worker         }
293*495ae853SAndroid Build Coastguard Worker         /* Taking the TopLt MV Predictor as one of the candidates   */
294*495ae853SAndroid Build Coastguard Worker         else if(ps_ngbr_avbl->u1_mb_d && i4_top_left_mode)
295*495ae853SAndroid Build Coastguard Worker         {
296*495ae853SAndroid Build Coastguard Worker             mvx      = (ps_top_left_mv->i2_mvx + 2) >> 2;
297*495ae853SAndroid Build Coastguard Worker             mvy      = (ps_top_left_mv->i2_mvy + 2) >> 2;
298*495ae853SAndroid Build Coastguard Worker 
299*495ae853SAndroid Build Coastguard Worker             mvx = CLIP3(i4_srch_range_w, i4_srch_range_e, mvx);
300*495ae853SAndroid Build Coastguard Worker             mvy = CLIP3(i4_srch_range_n, i4_srch_range_s, mvy);
301*495ae853SAndroid Build Coastguard Worker 
302*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mv_init_search[i4_reflist][u4_num_candidates].i2_mvx = mvx;
303*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mv_init_search[i4_reflist][u4_num_candidates].i2_mvy = mvy;
304*495ae853SAndroid Build Coastguard Worker 
305*495ae853SAndroid Build Coastguard Worker             u4_num_candidates ++;
306*495ae853SAndroid Build Coastguard Worker         }
307*495ae853SAndroid Build Coastguard Worker     }
308*495ae853SAndroid Build Coastguard Worker 
309*495ae853SAndroid Build Coastguard Worker     /********************************************************************/
310*495ae853SAndroid Build Coastguard Worker     /*                            MV Prediction                         */
311*495ae853SAndroid Build Coastguard Worker     /********************************************************************/
312*495ae853SAndroid Build Coastguard Worker     ih264e_mv_pred_me(ps_proc, i4_reflist);
313*495ae853SAndroid Build Coastguard Worker 
314*495ae853SAndroid Build Coastguard Worker     ps_mb_part->s_mv_pred.i2_mvx = ps_proc->ps_pred_mv[i4_reflist].s_mv.i2_mvx;
315*495ae853SAndroid Build Coastguard Worker     ps_mb_part->s_mv_pred.i2_mvy = ps_proc->ps_pred_mv[i4_reflist].s_mv.i2_mvy;
316*495ae853SAndroid Build Coastguard Worker 
317*495ae853SAndroid Build Coastguard Worker     /* Get the skip motion vector                               */
318*495ae853SAndroid Build Coastguard Worker     {
319*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->i4_skip_type = ps_proc->ps_codec->apf_find_skip_params_me
320*495ae853SAndroid Build Coastguard Worker                                     [ps_proc->i4_slice_type](ps_proc, i4_reflist);
321*495ae853SAndroid Build Coastguard Worker 
322*495ae853SAndroid Build Coastguard Worker         /* Taking the Skip motion vector as one of the candidates   */
323*495ae853SAndroid Build Coastguard Worker         mvx = (ps_proc->ps_skip_mv[i4_reflist].s_mv.i2_mvx + 2) >> 2;
324*495ae853SAndroid Build Coastguard Worker         mvy = (ps_proc->ps_skip_mv[i4_reflist].s_mv.i2_mvy + 2) >> 2;
325*495ae853SAndroid Build Coastguard Worker 
326*495ae853SAndroid Build Coastguard Worker         mvx = CLIP3(i4_srch_range_w, i4_srch_range_e, mvx);
327*495ae853SAndroid Build Coastguard Worker         mvy = CLIP3(i4_srch_range_n, i4_srch_range_s, mvy);
328*495ae853SAndroid Build Coastguard Worker 
329*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->as_mv_init_search[i4_reflist][u4_num_candidates].i2_mvx = mvx;
330*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->as_mv_init_search[i4_reflist][u4_num_candidates].i2_mvy = mvy;
331*495ae853SAndroid Build Coastguard Worker         u4_num_candidates++;
332*495ae853SAndroid Build Coastguard Worker 
333*495ae853SAndroid Build Coastguard Worker         if (ps_proc->i4_slice_type == BSLICE)
334*495ae853SAndroid Build Coastguard Worker         {
335*495ae853SAndroid Build Coastguard Worker             /* Taking the temporal Skip motion vector as one of the candidates   */
336*495ae853SAndroid Build Coastguard Worker             mvx = (ps_proc->ps_skip_mv[i4_reflist + 2].s_mv.i2_mvx + 2) >> 2;
337*495ae853SAndroid Build Coastguard Worker             mvy = (ps_proc->ps_skip_mv[i4_reflist + 2].s_mv.i2_mvy + 2) >> 2;
338*495ae853SAndroid Build Coastguard Worker 
339*495ae853SAndroid Build Coastguard Worker             mvx = CLIP3(i4_srch_range_w, i4_srch_range_e, mvx);
340*495ae853SAndroid Build Coastguard Worker             mvy = CLIP3(i4_srch_range_n, i4_srch_range_s, mvy);
341*495ae853SAndroid Build Coastguard Worker 
342*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mv_init_search[i4_reflist][u4_num_candidates].i2_mvx = mvx;
343*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mv_init_search[i4_reflist][u4_num_candidates].i2_mvy = mvy;
344*495ae853SAndroid Build Coastguard Worker             u4_num_candidates++;
345*495ae853SAndroid Build Coastguard Worker         }
346*495ae853SAndroid Build Coastguard Worker     }
347*495ae853SAndroid Build Coastguard Worker 
348*495ae853SAndroid Build Coastguard Worker     ASSERT(u4_num_candidates <= 6);
349*495ae853SAndroid Build Coastguard Worker 
350*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->u4_num_candidates[i4_reflist] = u4_num_candidates;
351*495ae853SAndroid Build Coastguard Worker }
352*495ae853SAndroid Build Coastguard Worker 
353*495ae853SAndroid Build Coastguard Worker /**
354*495ae853SAndroid Build Coastguard Worker *******************************************************************************
355*495ae853SAndroid Build Coastguard Worker *
356*495ae853SAndroid Build Coastguard Worker * @brief The function computes parameters for a PSKIP MB
357*495ae853SAndroid Build Coastguard Worker *
358*495ae853SAndroid Build Coastguard Worker * @par Description:
359*495ae853SAndroid Build Coastguard Worker *  The function updates the skip motion vector and checks if the current
360*495ae853SAndroid Build Coastguard Worker *  MB can be a PSKIP MB or not
361*495ae853SAndroid Build Coastguard Worker *
362*495ae853SAndroid Build Coastguard Worker * @param[in] ps_proc
363*495ae853SAndroid Build Coastguard Worker *  Pointer to process context
364*495ae853SAndroid Build Coastguard Worker *
365*495ae853SAndroid Build Coastguard Worker * @param[in] i4_ref_list
366*495ae853SAndroid Build Coastguard Worker *  Current active reference list
367*495ae853SAndroid Build Coastguard Worker *
368*495ae853SAndroid Build Coastguard Worker * @returns Flag indicating if the current MB can be marked as skip
369*495ae853SAndroid Build Coastguard Worker *
370*495ae853SAndroid Build Coastguard Worker *******************************************************************************
371*495ae853SAndroid Build Coastguard Worker */
ih264e_find_pskip_params(process_ctxt_t * ps_proc,WORD32 i4_reflist)372*495ae853SAndroid Build Coastguard Worker WORD32 ih264e_find_pskip_params(process_ctxt_t *ps_proc, WORD32 i4_reflist)
373*495ae853SAndroid Build Coastguard Worker {
374*495ae853SAndroid Build Coastguard Worker     /* left mb motion vector */
375*495ae853SAndroid Build Coastguard Worker     enc_pu_t *ps_left_mb_pu ;
376*495ae853SAndroid Build Coastguard Worker 
377*495ae853SAndroid Build Coastguard Worker     /* top mb motion vector */
378*495ae853SAndroid Build Coastguard Worker     enc_pu_t *ps_top_mb_pu ;
379*495ae853SAndroid Build Coastguard Worker 
380*495ae853SAndroid Build Coastguard Worker     /* Skip mv */
381*495ae853SAndroid Build Coastguard Worker     mv_t *ps_skip_mv = &ps_proc->ps_skip_mv[PRED_L0].s_mv;
382*495ae853SAndroid Build Coastguard Worker 
383*495ae853SAndroid Build Coastguard Worker     UNUSED(i4_reflist);
384*495ae853SAndroid Build Coastguard Worker 
385*495ae853SAndroid Build Coastguard Worker     ps_left_mb_pu = &ps_proc->s_left_mb_pu;
386*495ae853SAndroid Build Coastguard Worker     ps_top_mb_pu = ps_proc->ps_top_row_pu + ps_proc->i4_mb_x;
387*495ae853SAndroid Build Coastguard Worker 
388*495ae853SAndroid Build Coastguard Worker     if ((!ps_proc->ps_ngbr_avbl->u1_mb_a) ||
389*495ae853SAndroid Build Coastguard Worker         (!ps_proc->ps_ngbr_avbl->u1_mb_b) ||
390*495ae853SAndroid Build Coastguard Worker         (
391*495ae853SAndroid Build Coastguard Worker           (ps_left_mb_pu->s_me_info[PRED_L0].i1_ref_idx == -1) &&
392*495ae853SAndroid Build Coastguard Worker           (ps_left_mb_pu->s_me_info[PRED_L0].s_mv.i2_mvx == 0) &&
393*495ae853SAndroid Build Coastguard Worker           (ps_left_mb_pu->s_me_info[PRED_L0].s_mv.i2_mvy == 0)
394*495ae853SAndroid Build Coastguard Worker        ) ||
395*495ae853SAndroid Build Coastguard Worker        (
396*495ae853SAndroid Build Coastguard Worker           (ps_top_mb_pu->s_me_info[PRED_L0].i1_ref_idx == -1) &&
397*495ae853SAndroid Build Coastguard Worker           (ps_top_mb_pu->s_me_info[PRED_L0].s_mv.i2_mvx == 0) &&
398*495ae853SAndroid Build Coastguard Worker           (ps_top_mb_pu->s_me_info[PRED_L0].s_mv.i2_mvy == 0)
399*495ae853SAndroid Build Coastguard Worker        )
400*495ae853SAndroid Build Coastguard Worker      )
401*495ae853SAndroid Build Coastguard Worker     {
402*495ae853SAndroid Build Coastguard Worker         ps_skip_mv->i2_mvx = 0;
403*495ae853SAndroid Build Coastguard Worker         ps_skip_mv->i2_mvy = 0;
404*495ae853SAndroid Build Coastguard Worker     }
405*495ae853SAndroid Build Coastguard Worker     else
406*495ae853SAndroid Build Coastguard Worker     {
407*495ae853SAndroid Build Coastguard Worker         ps_skip_mv->i2_mvx = ps_proc->ps_pred_mv[PRED_L0].s_mv.i2_mvx;
408*495ae853SAndroid Build Coastguard Worker         ps_skip_mv->i2_mvy = ps_proc->ps_pred_mv[PRED_L0].s_mv.i2_mvy;
409*495ae853SAndroid Build Coastguard Worker     }
410*495ae853SAndroid Build Coastguard Worker 
411*495ae853SAndroid Build Coastguard Worker     if ((ps_proc->ps_pu->s_me_info[PRED_L0].s_mv.i2_mvx == ps_skip_mv->i2_mvx)
412*495ae853SAndroid Build Coastguard Worker      && (ps_proc->ps_pu->s_me_info[PRED_L0].s_mv.i2_mvy == ps_skip_mv->i2_mvy))
413*495ae853SAndroid Build Coastguard Worker     {
414*495ae853SAndroid Build Coastguard Worker         return 1;
415*495ae853SAndroid Build Coastguard Worker     }
416*495ae853SAndroid Build Coastguard Worker 
417*495ae853SAndroid Build Coastguard Worker     return 0;
418*495ae853SAndroid Build Coastguard Worker }
419*495ae853SAndroid Build Coastguard Worker 
420*495ae853SAndroid Build Coastguard Worker /**
421*495ae853SAndroid Build Coastguard Worker *******************************************************************************
422*495ae853SAndroid Build Coastguard Worker *
423*495ae853SAndroid Build Coastguard Worker * @brief The function computes parameters for a PSKIP MB
424*495ae853SAndroid Build Coastguard Worker *
425*495ae853SAndroid Build Coastguard Worker * @par Description:
426*495ae853SAndroid Build Coastguard Worker *  The function updates the skip motion vector and checks if the current
427*495ae853SAndroid Build Coastguard Worker *  MB can be a PSKIP MB or not
428*495ae853SAndroid Build Coastguard Worker *
429*495ae853SAndroid Build Coastguard Worker * @param[in] ps_proc
430*495ae853SAndroid Build Coastguard Worker *  Pointer to process context
431*495ae853SAndroid Build Coastguard Worker *
432*495ae853SAndroid Build Coastguard Worker * @param[in] i4_ref_list
433*495ae853SAndroid Build Coastguard Worker *  Current active reference list
434*495ae853SAndroid Build Coastguard Worker *
435*495ae853SAndroid Build Coastguard Worker * @returns Flag indicating if the current MB can be marked as skip
436*495ae853SAndroid Build Coastguard Worker *
437*495ae853SAndroid Build Coastguard Worker *******************************************************************************
438*495ae853SAndroid Build Coastguard Worker */
ih264e_find_pskip_params_me(process_ctxt_t * ps_proc,WORD32 i4_reflist)439*495ae853SAndroid Build Coastguard Worker WORD32 ih264e_find_pskip_params_me(process_ctxt_t *ps_proc, WORD32 i4_reflist)
440*495ae853SAndroid Build Coastguard Worker {
441*495ae853SAndroid Build Coastguard Worker     /* left mb motion vector */
442*495ae853SAndroid Build Coastguard Worker     enc_pu_t *ps_left_mb_pu ;
443*495ae853SAndroid Build Coastguard Worker 
444*495ae853SAndroid Build Coastguard Worker     /* top mb motion vector */
445*495ae853SAndroid Build Coastguard Worker     enc_pu_t *ps_top_mb_pu ;
446*495ae853SAndroid Build Coastguard Worker 
447*495ae853SAndroid Build Coastguard Worker     /* Skip mv */
448*495ae853SAndroid Build Coastguard Worker     mv_t *ps_skip_mv = &ps_proc->ps_skip_mv[PRED_L0].s_mv;
449*495ae853SAndroid Build Coastguard Worker 
450*495ae853SAndroid Build Coastguard Worker     UNUSED(i4_reflist);
451*495ae853SAndroid Build Coastguard Worker 
452*495ae853SAndroid Build Coastguard Worker     ps_left_mb_pu = &ps_proc->s_left_mb_pu_ME;
453*495ae853SAndroid Build Coastguard Worker     ps_top_mb_pu = ps_proc->ps_top_row_pu_ME + ps_proc->i4_mb_x;
454*495ae853SAndroid Build Coastguard Worker 
455*495ae853SAndroid Build Coastguard Worker     if ((!ps_proc->ps_ngbr_avbl->u1_mb_a) ||
456*495ae853SAndroid Build Coastguard Worker         (!ps_proc->ps_ngbr_avbl->u1_mb_b) ||
457*495ae853SAndroid Build Coastguard Worker         (
458*495ae853SAndroid Build Coastguard Worker           (ps_left_mb_pu->s_me_info[PRED_L0].i1_ref_idx == -1) &&
459*495ae853SAndroid Build Coastguard Worker           (ps_left_mb_pu->s_me_info[PRED_L0].s_mv.i2_mvx == 0) &&
460*495ae853SAndroid Build Coastguard Worker           (ps_left_mb_pu->s_me_info[PRED_L0].s_mv.i2_mvy == 0)
461*495ae853SAndroid Build Coastguard Worker         ) ||
462*495ae853SAndroid Build Coastguard Worker         (
463*495ae853SAndroid Build Coastguard Worker           (ps_top_mb_pu->s_me_info[PRED_L0].i1_ref_idx == -1) &&
464*495ae853SAndroid Build Coastguard Worker           (ps_top_mb_pu->s_me_info[PRED_L0].s_mv.i2_mvx == 0) &&
465*495ae853SAndroid Build Coastguard Worker           (ps_top_mb_pu->s_me_info[PRED_L0].s_mv.i2_mvy == 0)
466*495ae853SAndroid Build Coastguard Worker         )
467*495ae853SAndroid Build Coastguard Worker      )
468*495ae853SAndroid Build Coastguard Worker     {
469*495ae853SAndroid Build Coastguard Worker         ps_skip_mv->i2_mvx = 0;
470*495ae853SAndroid Build Coastguard Worker         ps_skip_mv->i2_mvy = 0;
471*495ae853SAndroid Build Coastguard Worker     }
472*495ae853SAndroid Build Coastguard Worker     else
473*495ae853SAndroid Build Coastguard Worker     {
474*495ae853SAndroid Build Coastguard Worker         ps_skip_mv->i2_mvx = ps_proc->ps_pred_mv[PRED_L0].s_mv.i2_mvx;
475*495ae853SAndroid Build Coastguard Worker         ps_skip_mv->i2_mvy = ps_proc->ps_pred_mv[PRED_L0].s_mv.i2_mvy;
476*495ae853SAndroid Build Coastguard Worker     }
477*495ae853SAndroid Build Coastguard Worker 
478*495ae853SAndroid Build Coastguard Worker     return PRED_L0;
479*495ae853SAndroid Build Coastguard Worker }
480*495ae853SAndroid Build Coastguard Worker 
481*495ae853SAndroid Build Coastguard Worker /**
482*495ae853SAndroid Build Coastguard Worker *******************************************************************************
483*495ae853SAndroid Build Coastguard Worker *
484*495ae853SAndroid Build Coastguard Worker * @brief motion vector predictor
485*495ae853SAndroid Build Coastguard Worker *
486*495ae853SAndroid Build Coastguard Worker * @par Description:
487*495ae853SAndroid Build Coastguard Worker *  The routine calculates the motion vector predictor for a given block,
488*495ae853SAndroid Build Coastguard Worker *  given the candidate MV predictors.
489*495ae853SAndroid Build Coastguard Worker *
490*495ae853SAndroid Build Coastguard Worker * @param[in] ps_left_mb_pu
491*495ae853SAndroid Build Coastguard Worker *  pointer to left mb motion vector info
492*495ae853SAndroid Build Coastguard Worker *
493*495ae853SAndroid Build Coastguard Worker * @param[in] ps_top_row_pu
494*495ae853SAndroid Build Coastguard Worker *  pointer to top & top right mb motion vector info
495*495ae853SAndroid Build Coastguard Worker *
496*495ae853SAndroid Build Coastguard Worker * @param[out] ps_pred_mv
497*495ae853SAndroid Build Coastguard Worker *  pointer to candidate predictors for the current block
498*495ae853SAndroid Build Coastguard Worker *
499*495ae853SAndroid Build Coastguard Worker * @param[in] i4_ref_list
500*495ae853SAndroid Build Coastguard Worker *  Current active reference list
501*495ae853SAndroid Build Coastguard Worker *
502*495ae853SAndroid Build Coastguard Worker * @returns  The x & y components of the MV predictor.
503*495ae853SAndroid Build Coastguard Worker *
504*495ae853SAndroid Build Coastguard Worker * @remarks The code implements the logic as described in sec 8.4.1.3 in H264
505*495ae853SAndroid Build Coastguard Worker *   specification.
506*495ae853SAndroid Build Coastguard Worker *   Assumptions : 1. Assumes Single reference frame
507*495ae853SAndroid Build Coastguard Worker *                 2. Assumes Only partition of size 16x16
508*495ae853SAndroid Build Coastguard Worker *
509*495ae853SAndroid Build Coastguard Worker *******************************************************************************
510*495ae853SAndroid Build Coastguard Worker */
ih264e_get_mv_predictor(enc_pu_t * ps_left_mb_pu,enc_pu_t * ps_top_row_pu,enc_pu_mv_t * ps_pred_mv,WORD32 i4_ref_list)511*495ae853SAndroid Build Coastguard Worker void ih264e_get_mv_predictor(enc_pu_t *ps_left_mb_pu,
512*495ae853SAndroid Build Coastguard Worker                              enc_pu_t *ps_top_row_pu,
513*495ae853SAndroid Build Coastguard Worker                              enc_pu_mv_t *ps_pred_mv,
514*495ae853SAndroid Build Coastguard Worker                              WORD32 i4_ref_list)
515*495ae853SAndroid Build Coastguard Worker {
516*495ae853SAndroid Build Coastguard Worker     /* Indicated the current ref */
517*495ae853SAndroid Build Coastguard Worker     WORD8 i1_ref_idx;
518*495ae853SAndroid Build Coastguard Worker 
519*495ae853SAndroid Build Coastguard Worker     /* For pred L0 */
520*495ae853SAndroid Build Coastguard Worker     i1_ref_idx = -1;
521*495ae853SAndroid Build Coastguard Worker     {
522*495ae853SAndroid Build Coastguard Worker         /* temp var */
523*495ae853SAndroid Build Coastguard Worker         WORD32 pred_algo = 3, a, b, c;
524*495ae853SAndroid Build Coastguard Worker 
525*495ae853SAndroid Build Coastguard Worker         /* If only one of the candidate blocks has a reference frame equal to
526*495ae853SAndroid Build Coastguard Worker          * the current block then use the same block as the final predictor */
527*495ae853SAndroid Build Coastguard Worker         a = (ps_left_mb_pu->s_me_info[i4_ref_list].i1_ref_idx == i1_ref_idx) ? 0 : -1;
528*495ae853SAndroid Build Coastguard Worker         b = (ps_top_row_pu[0].s_me_info[i4_ref_list].i1_ref_idx == i1_ref_idx) ? 0 : -1;
529*495ae853SAndroid Build Coastguard Worker         c = (ps_top_row_pu[1].s_me_info[i4_ref_list].i1_ref_idx == i1_ref_idx) ? 0 : -1;
530*495ae853SAndroid Build Coastguard Worker 
531*495ae853SAndroid Build Coastguard Worker         if (a == 0 && b == -1 && c == -1)
532*495ae853SAndroid Build Coastguard Worker             pred_algo = 0; /* LEFT */
533*495ae853SAndroid Build Coastguard Worker         else if(a == -1 && b == 0 && c == -1)
534*495ae853SAndroid Build Coastguard Worker             pred_algo = 1; /* TOP */
535*495ae853SAndroid Build Coastguard Worker         else if(a == -1 && b == -1 && c == 0)
536*495ae853SAndroid Build Coastguard Worker             pred_algo = 2; /* TOP RIGHT */
537*495ae853SAndroid Build Coastguard Worker 
538*495ae853SAndroid Build Coastguard Worker         switch (pred_algo)
539*495ae853SAndroid Build Coastguard Worker         {
540*495ae853SAndroid Build Coastguard Worker             case 0:
541*495ae853SAndroid Build Coastguard Worker                 /* left */
542*495ae853SAndroid Build Coastguard Worker                 ps_pred_mv->s_mv.i2_mvx = ps_left_mb_pu->s_me_info[i4_ref_list].s_mv.i2_mvx;
543*495ae853SAndroid Build Coastguard Worker                 ps_pred_mv->s_mv.i2_mvy = ps_left_mb_pu->s_me_info[i4_ref_list].s_mv.i2_mvy;
544*495ae853SAndroid Build Coastguard Worker                 break;
545*495ae853SAndroid Build Coastguard Worker             case 1:
546*495ae853SAndroid Build Coastguard Worker                 /* top */
547*495ae853SAndroid Build Coastguard Worker                 ps_pred_mv->s_mv.i2_mvx = ps_top_row_pu[0].s_me_info[i4_ref_list].s_mv.i2_mvx;
548*495ae853SAndroid Build Coastguard Worker                 ps_pred_mv->s_mv.i2_mvy = ps_top_row_pu[0].s_me_info[i4_ref_list].s_mv.i2_mvy;
549*495ae853SAndroid Build Coastguard Worker                 break;
550*495ae853SAndroid Build Coastguard Worker             case 2:
551*495ae853SAndroid Build Coastguard Worker                 /* top right */
552*495ae853SAndroid Build Coastguard Worker                 ps_pred_mv->s_mv.i2_mvx = ps_top_row_pu[1].s_me_info[i4_ref_list].s_mv.i2_mvx;
553*495ae853SAndroid Build Coastguard Worker                 ps_pred_mv->s_mv.i2_mvy = ps_top_row_pu[1].s_me_info[i4_ref_list].s_mv.i2_mvy;
554*495ae853SAndroid Build Coastguard Worker                 break;
555*495ae853SAndroid Build Coastguard Worker             case 3:
556*495ae853SAndroid Build Coastguard Worker                 /* median */
557*495ae853SAndroid Build Coastguard Worker                 MEDIAN(ps_left_mb_pu->s_me_info[i4_ref_list].s_mv.i2_mvx,
558*495ae853SAndroid Build Coastguard Worker                        ps_top_row_pu[0].s_me_info[i4_ref_list].s_mv.i2_mvx,
559*495ae853SAndroid Build Coastguard Worker                        ps_top_row_pu[1].s_me_info[i4_ref_list].s_mv.i2_mvx,
560*495ae853SAndroid Build Coastguard Worker                        ps_pred_mv->s_mv.i2_mvx);
561*495ae853SAndroid Build Coastguard Worker                 MEDIAN(ps_left_mb_pu->s_me_info[i4_ref_list].s_mv.i2_mvy,
562*495ae853SAndroid Build Coastguard Worker                        ps_top_row_pu[0].s_me_info[i4_ref_list].s_mv.i2_mvy,
563*495ae853SAndroid Build Coastguard Worker                        ps_top_row_pu[1].s_me_info[i4_ref_list].s_mv.i2_mvy,
564*495ae853SAndroid Build Coastguard Worker                        ps_pred_mv->s_mv.i2_mvy);
565*495ae853SAndroid Build Coastguard Worker 
566*495ae853SAndroid Build Coastguard Worker                 break;
567*495ae853SAndroid Build Coastguard Worker             default:
568*495ae853SAndroid Build Coastguard Worker                 break;
569*495ae853SAndroid Build Coastguard Worker         }
570*495ae853SAndroid Build Coastguard Worker     }
571*495ae853SAndroid Build Coastguard Worker }
572*495ae853SAndroid Build Coastguard Worker 
573*495ae853SAndroid Build Coastguard Worker /**
574*495ae853SAndroid Build Coastguard Worker *******************************************************************************
575*495ae853SAndroid Build Coastguard Worker *
576*495ae853SAndroid Build Coastguard Worker * @brief This function performs MV prediction
577*495ae853SAndroid Build Coastguard Worker *
578*495ae853SAndroid Build Coastguard Worker * @par Description:
579*495ae853SAndroid Build Coastguard Worker *
580*495ae853SAndroid Build Coastguard Worker * @param[in] ps_proc
581*495ae853SAndroid Build Coastguard Worker *  Process context corresponding to the job
582*495ae853SAndroid Build Coastguard Worker *
583*495ae853SAndroid Build Coastguard Worker * @param[in] i4_slice_type
584*495ae853SAndroid Build Coastguard Worker *  slice type
585*495ae853SAndroid Build Coastguard Worker *
586*495ae853SAndroid Build Coastguard Worker * @returns  none
587*495ae853SAndroid Build Coastguard Worker *
588*495ae853SAndroid Build Coastguard Worker * @remarks none
589*495ae853SAndroid Build Coastguard Worker *  This function will update the MB availability since intra inter decision
590*495ae853SAndroid Build Coastguard Worker *  should be done before the call
591*495ae853SAndroid Build Coastguard Worker *
592*495ae853SAndroid Build Coastguard Worker *******************************************************************************
593*495ae853SAndroid Build Coastguard Worker */
ih264e_mv_pred(process_ctxt_t * ps_proc,WORD32 i4_slice_type)594*495ae853SAndroid Build Coastguard Worker void ih264e_mv_pred(process_ctxt_t *ps_proc, WORD32 i4_slice_type)
595*495ae853SAndroid Build Coastguard Worker {
596*495ae853SAndroid Build Coastguard Worker     /* left mb motion vector */
597*495ae853SAndroid Build Coastguard Worker     enc_pu_t *ps_left_mb_pu;
598*495ae853SAndroid Build Coastguard Worker 
599*495ae853SAndroid Build Coastguard Worker     /* top left mb motion vector */
600*495ae853SAndroid Build Coastguard Worker     enc_pu_t *ps_top_left_mb_pu;
601*495ae853SAndroid Build Coastguard Worker 
602*495ae853SAndroid Build Coastguard Worker     /* top row motion vector info */
603*495ae853SAndroid Build Coastguard Worker     enc_pu_t *ps_top_row_pu;
604*495ae853SAndroid Build Coastguard Worker 
605*495ae853SAndroid Build Coastguard Worker     /* predicted motion vector */
606*495ae853SAndroid Build Coastguard Worker     enc_pu_mv_t *ps_pred_mv = ps_proc->ps_pred_mv;
607*495ae853SAndroid Build Coastguard Worker 
608*495ae853SAndroid Build Coastguard Worker     /* zero mv */
609*495ae853SAndroid Build Coastguard Worker     mv_t zero_mv = { 0, 0 };
610*495ae853SAndroid Build Coastguard Worker 
611*495ae853SAndroid Build Coastguard Worker     /*  mb neighbor availability */
612*495ae853SAndroid Build Coastguard Worker     block_neighbors_t *ps_ngbr_avbl = ps_proc->ps_ngbr_avbl;
613*495ae853SAndroid Build Coastguard Worker 
614*495ae853SAndroid Build Coastguard Worker     /* mb syntax elements of neighbors */
615*495ae853SAndroid Build Coastguard Worker     mb_info_t *ps_top_syn = ps_proc->ps_top_row_mb_syntax_ele + ps_proc->i4_mb_x;
616*495ae853SAndroid Build Coastguard Worker     mb_info_t *ps_top_left_syn;
617*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_left_is_intra;
618*495ae853SAndroid Build Coastguard Worker 
619*495ae853SAndroid Build Coastguard Worker     /* Temp var */
620*495ae853SAndroid Build Coastguard Worker     WORD32 i4_reflist, max_reflist, i4_cmpl_predmode;
621*495ae853SAndroid Build Coastguard Worker 
622*495ae853SAndroid Build Coastguard Worker     ps_top_left_syn = &(ps_proc->s_top_left_mb_syntax_ele);
623*495ae853SAndroid Build Coastguard Worker     u4_left_is_intra = ps_proc->s_left_mb_syntax_ele.u2_is_intra;
624*495ae853SAndroid Build Coastguard Worker     ps_left_mb_pu = &ps_proc->s_left_mb_pu;
625*495ae853SAndroid Build Coastguard Worker     ps_top_left_mb_pu = &ps_proc->s_top_left_mb_pu;
626*495ae853SAndroid Build Coastguard Worker     ps_top_row_pu = (ps_proc->ps_top_row_pu + ps_proc->i4_mb_x);
627*495ae853SAndroid Build Coastguard Worker 
628*495ae853SAndroid Build Coastguard Worker     /* Number of ref lists to process */
629*495ae853SAndroid Build Coastguard Worker     max_reflist = (i4_slice_type == PSLICE) ? 1 : 2;
630*495ae853SAndroid Build Coastguard Worker 
631*495ae853SAndroid Build Coastguard Worker     for (i4_reflist = 0; i4_reflist < max_reflist; i4_reflist++)
632*495ae853SAndroid Build Coastguard Worker     {
633*495ae853SAndroid Build Coastguard Worker         i4_cmpl_predmode = (i4_reflist == 0) ? PRED_L1 : PRED_L0;
634*495ae853SAndroid Build Coastguard Worker 
635*495ae853SAndroid Build Coastguard Worker         /* Before performing mv prediction prepare the ngbr information and
636*495ae853SAndroid Build Coastguard Worker          * reset motion vectors basing on their availability */
637*495ae853SAndroid Build Coastguard Worker         if (!ps_ngbr_avbl->u1_mb_a || (u4_left_is_intra == 1)
638*495ae853SAndroid Build Coastguard Worker                         || (ps_left_mb_pu->b2_pred_mode == i4_cmpl_predmode))
639*495ae853SAndroid Build Coastguard Worker         {
640*495ae853SAndroid Build Coastguard Worker             /* left mv */
641*495ae853SAndroid Build Coastguard Worker             ps_left_mb_pu->s_me_info[i4_reflist].i1_ref_idx = 0;
642*495ae853SAndroid Build Coastguard Worker             ps_left_mb_pu->s_me_info[i4_reflist].s_mv = zero_mv;
643*495ae853SAndroid Build Coastguard Worker         }
644*495ae853SAndroid Build Coastguard Worker         if (!ps_ngbr_avbl->u1_mb_b || ps_top_syn->u2_is_intra
645*495ae853SAndroid Build Coastguard Worker                         || (ps_top_row_pu[0].b2_pred_mode == i4_cmpl_predmode))
646*495ae853SAndroid Build Coastguard Worker         {
647*495ae853SAndroid Build Coastguard Worker             /* top mv */
648*495ae853SAndroid Build Coastguard Worker             ps_top_row_pu[0].s_me_info[i4_reflist].i1_ref_idx = 0;
649*495ae853SAndroid Build Coastguard Worker             ps_top_row_pu[0].s_me_info[i4_reflist].s_mv = zero_mv;
650*495ae853SAndroid Build Coastguard Worker         }
651*495ae853SAndroid Build Coastguard Worker 
652*495ae853SAndroid Build Coastguard Worker         if (!ps_ngbr_avbl->u1_mb_c)
653*495ae853SAndroid Build Coastguard Worker         {
654*495ae853SAndroid Build Coastguard Worker             /* top right mv - When top right partition is not available for
655*495ae853SAndroid Build Coastguard Worker              * prediction if top left is available use it for prediction else
656*495ae853SAndroid Build Coastguard Worker              * set the mv information to -1 and (0, 0)
657*495ae853SAndroid Build Coastguard Worker              * */
658*495ae853SAndroid Build Coastguard Worker             if (!ps_ngbr_avbl->u1_mb_d || ps_top_left_syn->u2_is_intra
659*495ae853SAndroid Build Coastguard Worker                             || (ps_top_left_mb_pu->b2_pred_mode == i4_cmpl_predmode))
660*495ae853SAndroid Build Coastguard Worker             {
661*495ae853SAndroid Build Coastguard Worker                 ps_top_row_pu[1].s_me_info[i4_reflist].i1_ref_idx = 0;
662*495ae853SAndroid Build Coastguard Worker                 ps_top_row_pu[1].s_me_info[i4_reflist].s_mv = zero_mv;
663*495ae853SAndroid Build Coastguard Worker             }
664*495ae853SAndroid Build Coastguard Worker             else
665*495ae853SAndroid Build Coastguard Worker             {
666*495ae853SAndroid Build Coastguard Worker                 ps_top_row_pu[1].s_me_info[i4_reflist].i1_ref_idx = ps_top_left_mb_pu->s_me_info[i4_reflist].i1_ref_idx;
667*495ae853SAndroid Build Coastguard Worker                 ps_top_row_pu[1].s_me_info[i4_reflist].s_mv = ps_top_left_mb_pu->s_me_info[i4_reflist].s_mv;
668*495ae853SAndroid Build Coastguard Worker             }
669*495ae853SAndroid Build Coastguard Worker         }
670*495ae853SAndroid Build Coastguard Worker         else if(ps_top_syn[1].u2_is_intra
671*495ae853SAndroid Build Coastguard Worker                         || (ps_top_row_pu[1].b2_pred_mode == i4_cmpl_predmode))
672*495ae853SAndroid Build Coastguard Worker         {
673*495ae853SAndroid Build Coastguard Worker             ps_top_row_pu[1].s_me_info[i4_reflist].i1_ref_idx = 0;
674*495ae853SAndroid Build Coastguard Worker             ps_top_row_pu[1].s_me_info[i4_reflist].s_mv = zero_mv;
675*495ae853SAndroid Build Coastguard Worker         }
676*495ae853SAndroid Build Coastguard Worker 
677*495ae853SAndroid Build Coastguard Worker         ih264e_get_mv_predictor(ps_left_mb_pu, ps_top_row_pu, &ps_pred_mv[i4_reflist], i4_reflist);
678*495ae853SAndroid Build Coastguard Worker     }
679*495ae853SAndroid Build Coastguard Worker }
680*495ae853SAndroid Build Coastguard Worker 
681*495ae853SAndroid Build Coastguard Worker /**
682*495ae853SAndroid Build Coastguard Worker *******************************************************************************
683*495ae853SAndroid Build Coastguard Worker *
684*495ae853SAndroid Build Coastguard Worker * @brief This function approximates Pred. MV
685*495ae853SAndroid Build Coastguard Worker *
686*495ae853SAndroid Build Coastguard Worker * @par Description:
687*495ae853SAndroid Build Coastguard Worker *
688*495ae853SAndroid Build Coastguard Worker * @param[in] ps_proc
689*495ae853SAndroid Build Coastguard Worker *  Process context corresponding to the job
690*495ae853SAndroid Build Coastguard Worker *
691*495ae853SAndroid Build Coastguard Worker * @param[in] i4_ref_list
692*495ae853SAndroid Build Coastguard Worker *  Current active reference list
693*495ae853SAndroid Build Coastguard Worker *
694*495ae853SAndroid Build Coastguard Worker * @returns  none
695*495ae853SAndroid Build Coastguard Worker *
696*495ae853SAndroid Build Coastguard Worker * @remarks none
697*495ae853SAndroid Build Coastguard Worker *  Motion estimation happens at nmb level. For cost calculations, mv is appro
698*495ae853SAndroid Build Coastguard Worker *  ximated using this function
699*495ae853SAndroid Build Coastguard Worker *
700*495ae853SAndroid Build Coastguard Worker *******************************************************************************
701*495ae853SAndroid Build Coastguard Worker */
ih264e_mv_pred_me(process_ctxt_t * ps_proc,WORD32 i4_ref_list)702*495ae853SAndroid Build Coastguard Worker void ih264e_mv_pred_me(process_ctxt_t *ps_proc, WORD32 i4_ref_list)
703*495ae853SAndroid Build Coastguard Worker {
704*495ae853SAndroid Build Coastguard Worker     /* left mb motion vector */
705*495ae853SAndroid Build Coastguard Worker     enc_pu_t *ps_left_mb_pu ;
706*495ae853SAndroid Build Coastguard Worker 
707*495ae853SAndroid Build Coastguard Worker     /* top left mb motion vector */
708*495ae853SAndroid Build Coastguard Worker     enc_pu_t *ps_top_left_mb_pu ;
709*495ae853SAndroid Build Coastguard Worker 
710*495ae853SAndroid Build Coastguard Worker     /* top row motion vector info */
711*495ae853SAndroid Build Coastguard Worker     enc_pu_t *ps_top_row_pu;
712*495ae853SAndroid Build Coastguard Worker 
713*495ae853SAndroid Build Coastguard Worker     enc_pu_t s_top_row_pu[2];
714*495ae853SAndroid Build Coastguard Worker 
715*495ae853SAndroid Build Coastguard Worker     /* predicted motion vector */
716*495ae853SAndroid Build Coastguard Worker     enc_pu_mv_t *ps_pred_mv = ps_proc->ps_pred_mv;
717*495ae853SAndroid Build Coastguard Worker 
718*495ae853SAndroid Build Coastguard Worker     /* zero mv */
719*495ae853SAndroid Build Coastguard Worker     mv_t zero_mv = {0, 0};
720*495ae853SAndroid Build Coastguard Worker 
721*495ae853SAndroid Build Coastguard Worker     /* Complementary pred mode */
722*495ae853SAndroid Build Coastguard Worker     WORD32 i4_cmpl_predmode = (i4_ref_list == 0) ? PRED_L1 : PRED_L0;
723*495ae853SAndroid Build Coastguard Worker 
724*495ae853SAndroid Build Coastguard Worker     /*  mb neighbor availability */
725*495ae853SAndroid Build Coastguard Worker     block_neighbors_t *ps_ngbr_avbl = ps_proc->ps_ngbr_avbl;
726*495ae853SAndroid Build Coastguard Worker 
727*495ae853SAndroid Build Coastguard Worker     ps_left_mb_pu = &ps_proc->s_left_mb_pu_ME;
728*495ae853SAndroid Build Coastguard Worker     ps_top_left_mb_pu = &ps_proc->s_top_left_mb_pu_ME;
729*495ae853SAndroid Build Coastguard Worker     ps_top_row_pu = (ps_proc->ps_top_row_pu_ME + ps_proc->i4_mb_x);
730*495ae853SAndroid Build Coastguard Worker 
731*495ae853SAndroid Build Coastguard Worker     s_top_row_pu[0] = ps_top_row_pu[0];
732*495ae853SAndroid Build Coastguard Worker     s_top_row_pu[1] = ps_top_row_pu[1];
733*495ae853SAndroid Build Coastguard Worker 
734*495ae853SAndroid Build Coastguard Worker     /*
735*495ae853SAndroid Build Coastguard Worker      * Before performing mv prediction prepare the ngbr information and
736*495ae853SAndroid Build Coastguard Worker      * reset motion vectors basing on their availability
737*495ae853SAndroid Build Coastguard Worker      */
738*495ae853SAndroid Build Coastguard Worker     if (!ps_ngbr_avbl->u1_mb_a || (ps_left_mb_pu->b2_pred_mode == i4_cmpl_predmode))
739*495ae853SAndroid Build Coastguard Worker     {
740*495ae853SAndroid Build Coastguard Worker         /* left mv */
741*495ae853SAndroid Build Coastguard Worker         ps_left_mb_pu->s_me_info[i4_ref_list].i1_ref_idx = 0;
742*495ae853SAndroid Build Coastguard Worker         ps_left_mb_pu->s_me_info[i4_ref_list].s_mv = zero_mv;
743*495ae853SAndroid Build Coastguard Worker     }
744*495ae853SAndroid Build Coastguard Worker     if (!ps_ngbr_avbl->u1_mb_b || (s_top_row_pu[0].b2_pred_mode == i4_cmpl_predmode))
745*495ae853SAndroid Build Coastguard Worker     {
746*495ae853SAndroid Build Coastguard Worker         /* top mv */
747*495ae853SAndroid Build Coastguard Worker         s_top_row_pu[0].s_me_info[i4_ref_list].i1_ref_idx = 0;
748*495ae853SAndroid Build Coastguard Worker         s_top_row_pu[0].s_me_info[i4_ref_list].s_mv = zero_mv;
749*495ae853SAndroid Build Coastguard Worker 
750*495ae853SAndroid Build Coastguard Worker     }
751*495ae853SAndroid Build Coastguard Worker     if (!ps_ngbr_avbl->u1_mb_c)
752*495ae853SAndroid Build Coastguard Worker     {
753*495ae853SAndroid Build Coastguard Worker         /* top right mv - When top right partition is not available for
754*495ae853SAndroid Build Coastguard Worker          * prediction if top left is available use it for prediction else
755*495ae853SAndroid Build Coastguard Worker          * set the mv information to -1 and (0, 0)
756*495ae853SAndroid Build Coastguard Worker          * */
757*495ae853SAndroid Build Coastguard Worker         if (!ps_ngbr_avbl->u1_mb_d || (ps_top_left_mb_pu->b2_pred_mode == i4_cmpl_predmode))
758*495ae853SAndroid Build Coastguard Worker         {
759*495ae853SAndroid Build Coastguard Worker             s_top_row_pu[1].s_me_info[i4_ref_list].i1_ref_idx = 0;
760*495ae853SAndroid Build Coastguard Worker             s_top_row_pu[1].s_me_info[i4_ref_list].s_mv = zero_mv;
761*495ae853SAndroid Build Coastguard Worker 
762*495ae853SAndroid Build Coastguard Worker             s_top_row_pu[1].s_me_info[i4_ref_list].i1_ref_idx = 0;
763*495ae853SAndroid Build Coastguard Worker             s_top_row_pu[1].s_me_info[i4_ref_list].s_mv = zero_mv;
764*495ae853SAndroid Build Coastguard Worker         }
765*495ae853SAndroid Build Coastguard Worker         else
766*495ae853SAndroid Build Coastguard Worker         {
767*495ae853SAndroid Build Coastguard Worker             s_top_row_pu[1].s_me_info[i4_ref_list].i1_ref_idx = ps_top_left_mb_pu->s_me_info[0].i1_ref_idx;
768*495ae853SAndroid Build Coastguard Worker             s_top_row_pu[1].s_me_info[i4_ref_list].s_mv = ps_top_left_mb_pu->s_me_info[0].s_mv;
769*495ae853SAndroid Build Coastguard Worker         }
770*495ae853SAndroid Build Coastguard Worker     }
771*495ae853SAndroid Build Coastguard Worker     else if (ps_top_row_pu[1].b2_pred_mode == i4_cmpl_predmode)
772*495ae853SAndroid Build Coastguard Worker     {
773*495ae853SAndroid Build Coastguard Worker         ps_top_row_pu[1].s_me_info[i4_ref_list].i1_ref_idx = 0;
774*495ae853SAndroid Build Coastguard Worker         ps_top_row_pu[1].s_me_info[i4_ref_list].s_mv = zero_mv;
775*495ae853SAndroid Build Coastguard Worker     }
776*495ae853SAndroid Build Coastguard Worker 
777*495ae853SAndroid Build Coastguard Worker     ih264e_get_mv_predictor(ps_left_mb_pu, &(s_top_row_pu[0]),
778*495ae853SAndroid Build Coastguard Worker                             &ps_pred_mv[i4_ref_list], i4_ref_list);
779*495ae853SAndroid Build Coastguard Worker }
780*495ae853SAndroid Build Coastguard Worker 
781*495ae853SAndroid Build Coastguard Worker /**
782*495ae853SAndroid Build Coastguard Worker *******************************************************************************
783*495ae853SAndroid Build Coastguard Worker *
784*495ae853SAndroid Build Coastguard Worker * @brief This function initializes me ctxt
785*495ae853SAndroid Build Coastguard Worker *
786*495ae853SAndroid Build Coastguard Worker * @par Description:
787*495ae853SAndroid Build Coastguard Worker *  Before dispatching the current job to me thread, the me context associated
788*495ae853SAndroid Build Coastguard Worker *  with the job is initialized.
789*495ae853SAndroid Build Coastguard Worker *
790*495ae853SAndroid Build Coastguard Worker * @param[in] ps_proc
791*495ae853SAndroid Build Coastguard Worker *  Process context corresponding to the job
792*495ae853SAndroid Build Coastguard Worker *
793*495ae853SAndroid Build Coastguard Worker * @returns  none
794*495ae853SAndroid Build Coastguard Worker *
795*495ae853SAndroid Build Coastguard Worker * @remarks none
796*495ae853SAndroid Build Coastguard Worker *
797*495ae853SAndroid Build Coastguard Worker *******************************************************************************
798*495ae853SAndroid Build Coastguard Worker */
ih264e_init_me(process_ctxt_t * ps_proc)799*495ae853SAndroid Build Coastguard Worker void ih264e_init_me(process_ctxt_t *ps_proc)
800*495ae853SAndroid Build Coastguard Worker {
801*495ae853SAndroid Build Coastguard Worker     /* me ctxt */
802*495ae853SAndroid Build Coastguard Worker     me_ctxt_t *ps_me_ctxt = &ps_proc->s_me_ctxt;
803*495ae853SAndroid Build Coastguard Worker 
804*495ae853SAndroid Build Coastguard Worker     /* codec context */
805*495ae853SAndroid Build Coastguard Worker     codec_t *ps_codec = ps_proc->ps_codec;
806*495ae853SAndroid Build Coastguard Worker 
807*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->i4_skip_bias[BSLICE] = SKIP_BIAS_B;
808*495ae853SAndroid Build Coastguard Worker 
809*495ae853SAndroid Build Coastguard Worker     if (ps_codec->s_cfg.u4_num_bframes == 0)
810*495ae853SAndroid Build Coastguard Worker     {
811*495ae853SAndroid Build Coastguard Worker        ps_me_ctxt->i4_skip_bias[PSLICE] = 4 * SKIP_BIAS_P;
812*495ae853SAndroid Build Coastguard Worker     }
813*495ae853SAndroid Build Coastguard Worker     else
814*495ae853SAndroid Build Coastguard Worker     {
815*495ae853SAndroid Build Coastguard Worker        ps_me_ctxt->i4_skip_bias[PSLICE] =  SKIP_BIAS_P;
816*495ae853SAndroid Build Coastguard Worker     }
817*495ae853SAndroid Build Coastguard Worker 
818*495ae853SAndroid Build Coastguard Worker     /* src ptr */
819*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->pu1_src_buf_luma = ps_proc->pu1_src_buf_luma;
820*495ae853SAndroid Build Coastguard Worker 
821*495ae853SAndroid Build Coastguard Worker     /* src stride */
822*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->i4_src_strd = ps_proc->i4_src_strd;
823*495ae853SAndroid Build Coastguard Worker 
824*495ae853SAndroid Build Coastguard Worker     /* ref ptrs and corresponding lagrange params */
825*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->apu1_ref_buf_luma[0] = ps_proc->apu1_ref_buf_luma[0];
826*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->apu1_ref_buf_luma[1] = ps_proc->apu1_ref_buf_luma[1];
827*495ae853SAndroid Build Coastguard Worker 
828*495ae853SAndroid Build Coastguard Worker     if (ps_codec->pic_type == PIC_B)
829*495ae853SAndroid Build Coastguard Worker     {
830*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->u4_lambda_motion = gu1_qp_lambdaB[ps_me_ctxt->u1_mb_qp];
831*495ae853SAndroid Build Coastguard Worker     }
832*495ae853SAndroid Build Coastguard Worker     else
833*495ae853SAndroid Build Coastguard Worker     {
834*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->u4_lambda_motion = gu1_qp_lambdaIP[ps_me_ctxt->u1_mb_qp];
835*495ae853SAndroid Build Coastguard Worker     }
836*495ae853SAndroid Build Coastguard Worker }
837*495ae853SAndroid Build Coastguard Worker 
838*495ae853SAndroid Build Coastguard Worker 
839*495ae853SAndroid Build Coastguard Worker /**
840*495ae853SAndroid Build Coastguard Worker *******************************************************************************
841*495ae853SAndroid Build Coastguard Worker *
842*495ae853SAndroid Build Coastguard Worker * @brief This function performs motion estimation for the current mb using
843*495ae853SAndroid Build Coastguard Worker *   single reference list
844*495ae853SAndroid Build Coastguard Worker *
845*495ae853SAndroid Build Coastguard Worker * @par Description:
846*495ae853SAndroid Build Coastguard Worker *  The current mb is compared with a list of mb's in the reference frame for
847*495ae853SAndroid Build Coastguard Worker *  least cost. The mb that offers least cost is chosen as predicted mb and the
848*495ae853SAndroid Build Coastguard Worker *  displacement of the predicted mb from index location of the current mb is
849*495ae853SAndroid Build Coastguard Worker *  signaled as mv. The list of the mb's that are chosen in the reference frame
850*495ae853SAndroid Build Coastguard Worker *  are dependent on the speed of the ME configured.
851*495ae853SAndroid Build Coastguard Worker *
852*495ae853SAndroid Build Coastguard Worker * @param[in] ps_proc
853*495ae853SAndroid Build Coastguard Worker *  Process context corresponding to the job
854*495ae853SAndroid Build Coastguard Worker *
855*495ae853SAndroid Build Coastguard Worker * @returns  motion vector of the pred mb, sad, cost.
856*495ae853SAndroid Build Coastguard Worker *
857*495ae853SAndroid Build Coastguard Worker * @remarks none
858*495ae853SAndroid Build Coastguard Worker *
859*495ae853SAndroid Build Coastguard Worker *******************************************************************************
860*495ae853SAndroid Build Coastguard Worker */
ih264e_compute_me_single_reflist(process_ctxt_t * ps_proc)861*495ae853SAndroid Build Coastguard Worker void ih264e_compute_me_single_reflist(process_ctxt_t *ps_proc)
862*495ae853SAndroid Build Coastguard Worker {
863*495ae853SAndroid Build Coastguard Worker     /* me ctxt */
864*495ae853SAndroid Build Coastguard Worker     me_ctxt_t *ps_me_ctxt = &ps_proc->s_me_ctxt;
865*495ae853SAndroid Build Coastguard Worker 
866*495ae853SAndroid Build Coastguard Worker     /* codec context */
867*495ae853SAndroid Build Coastguard Worker     codec_t *ps_codec = ps_proc->ps_codec;
868*495ae853SAndroid Build Coastguard Worker 
869*495ae853SAndroid Build Coastguard Worker     /* recon stride */
870*495ae853SAndroid Build Coastguard Worker     WORD32 i4_rec_strd = ps_proc->i4_rec_strd;
871*495ae853SAndroid Build Coastguard Worker 
872*495ae853SAndroid Build Coastguard Worker     /* source buffer for halp pel generation functions */
873*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_hpel_src;
874*495ae853SAndroid Build Coastguard Worker 
875*495ae853SAndroid Build Coastguard Worker     /* quantization parameters */
876*495ae853SAndroid Build Coastguard Worker     quant_params_t *ps_qp_params = ps_proc->ps_qp_params[0];
877*495ae853SAndroid Build Coastguard Worker 
878*495ae853SAndroid Build Coastguard Worker     /* Mb part ctxts for SKIP */
879*495ae853SAndroid Build Coastguard Worker     mb_part_ctxt s_skip_mbpart;
880*495ae853SAndroid Build Coastguard Worker 
881*495ae853SAndroid Build Coastguard Worker     /* Sad therholds */
882*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->pu2_sad_thrsh = ps_qp_params->pu2_sad_thrsh;
883*495ae853SAndroid Build Coastguard Worker 
884*495ae853SAndroid Build Coastguard Worker     {
885*495ae853SAndroid Build Coastguard Worker         WORD32 rows_above, rows_below, columns_left, columns_right;
886*495ae853SAndroid Build Coastguard Worker 
887*495ae853SAndroid Build Coastguard Worker         /* During evaluation for motion vectors do not search through padded regions */
888*495ae853SAndroid Build Coastguard Worker         /* Obtain number of rows and columns that are effective for computing for me evaluation */
889*495ae853SAndroid Build Coastguard Worker         rows_above = MB_SIZE + ps_proc->i4_mb_y * MB_SIZE;
890*495ae853SAndroid Build Coastguard Worker         rows_below = (ps_proc->i4_ht_mbs - ps_proc->i4_mb_y) * MB_SIZE;
891*495ae853SAndroid Build Coastguard Worker         columns_left = MB_SIZE + ps_proc->i4_mb_x * MB_SIZE;
892*495ae853SAndroid Build Coastguard Worker         columns_right = (ps_proc->i4_wd_mbs - ps_proc->i4_mb_x) * MB_SIZE;
893*495ae853SAndroid Build Coastguard Worker 
894*495ae853SAndroid Build Coastguard Worker         /* init srch range */
895*495ae853SAndroid Build Coastguard Worker         /* NOTE : For now, lets limit the search range by DEFAULT_MAX_SRCH_RANGE_X / 2
896*495ae853SAndroid Build Coastguard Worker          * on all sides.
897*495ae853SAndroid Build Coastguard Worker          */
898*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->i4_srch_range_w = -MIN(columns_left, DEFAULT_MAX_SRCH_RANGE_X >> 1);
899*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->i4_srch_range_e = MIN(columns_right, DEFAULT_MAX_SRCH_RANGE_X >> 1);
900*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->i4_srch_range_n = -MIN(rows_above, DEFAULT_MAX_SRCH_RANGE_Y >> 1);
901*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->i4_srch_range_s = MIN(rows_below, DEFAULT_MAX_SRCH_RANGE_Y >> 1);
902*495ae853SAndroid Build Coastguard Worker 
903*495ae853SAndroid Build Coastguard Worker         /* this is to facilitate fast sub pel computation with minimal loads */
904*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->i4_srch_range_w += 1;
905*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->i4_srch_range_e -= 1;
906*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->i4_srch_range_n += 1;
907*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->i4_srch_range_s -= 1;
908*495ae853SAndroid Build Coastguard Worker     }
909*495ae853SAndroid Build Coastguard Worker 
910*495ae853SAndroid Build Coastguard Worker     /* Compute ME and store the MVs */
911*495ae853SAndroid Build Coastguard Worker 
912*495ae853SAndroid Build Coastguard Worker     /***********************************************************************
913*495ae853SAndroid Build Coastguard Worker      * Compute ME for list L0
914*495ae853SAndroid Build Coastguard Worker      ***********************************************************************/
915*495ae853SAndroid Build Coastguard Worker 
916*495ae853SAndroid Build Coastguard Worker     /* Init SATQD for the current list */
917*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->u4_min_sad_reached  = 0;
918*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->i4_min_sad = ps_proc->ps_cur_mb->u4_min_sad;
919*495ae853SAndroid Build Coastguard Worker 
920*495ae853SAndroid Build Coastguard Worker     /* Get the seed motion vector candidates                    */
921*495ae853SAndroid Build Coastguard Worker     ih264e_get_search_candidates(ps_proc, ps_me_ctxt, PRED_L0);
922*495ae853SAndroid Build Coastguard Worker 
923*495ae853SAndroid Build Coastguard Worker     /*****************************************************************
924*495ae853SAndroid Build Coastguard Worker      * Evaluate the SKIP for current list
925*495ae853SAndroid Build Coastguard Worker      *****************************************************************/
926*495ae853SAndroid Build Coastguard Worker     s_skip_mbpart.s_mv_curr.i2_mvx = 0;
927*495ae853SAndroid Build Coastguard Worker     s_skip_mbpart.s_mv_curr.i2_mvy = 0;
928*495ae853SAndroid Build Coastguard Worker     s_skip_mbpart.i4_mb_cost = INT_MAX;
929*495ae853SAndroid Build Coastguard Worker     s_skip_mbpart.i4_mb_distortion = INT_MAX;
930*495ae853SAndroid Build Coastguard Worker 
931*495ae853SAndroid Build Coastguard Worker     ime_compute_skip_cost( ps_me_ctxt,
932*495ae853SAndroid Build Coastguard Worker                            (ime_mv_t *)(&ps_proc->ps_skip_mv[PRED_L0].s_mv),
933*495ae853SAndroid Build Coastguard Worker                            &s_skip_mbpart,
934*495ae853SAndroid Build Coastguard Worker                            ps_proc->ps_codec->s_cfg.u4_enable_satqd,
935*495ae853SAndroid Build Coastguard Worker                            PRED_L0,
936*495ae853SAndroid Build Coastguard Worker                            0 /* Not a Bslice */ );
937*495ae853SAndroid Build Coastguard Worker 
938*495ae853SAndroid Build Coastguard Worker     s_skip_mbpart.s_mv_curr.i2_mvx <<= 2;
939*495ae853SAndroid Build Coastguard Worker     s_skip_mbpart.s_mv_curr.i2_mvy <<= 2;
940*495ae853SAndroid Build Coastguard Worker 
941*495ae853SAndroid Build Coastguard Worker     /******************************************************************
942*495ae853SAndroid Build Coastguard Worker      * Evaluate ME For current list
943*495ae853SAndroid Build Coastguard Worker      *****************************************************************/
944*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->as_mb_part[PRED_L0].s_mv_curr.i2_mvx = 0;
945*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->as_mb_part[PRED_L0].s_mv_curr.i2_mvy = 0;
946*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->as_mb_part[PRED_L0].i4_mb_cost = INT_MAX;
947*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->as_mb_part[PRED_L0].i4_mb_distortion = INT_MAX;
948*495ae853SAndroid Build Coastguard Worker 
949*495ae853SAndroid Build Coastguard Worker     /* Init Hpel */
950*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->as_mb_part[PRED_L0].pu1_best_hpel_buf = NULL;
951*495ae853SAndroid Build Coastguard Worker 
952*495ae853SAndroid Build Coastguard Worker     /* In case we found out the minimum SAD, exit the ME eval */
953*495ae853SAndroid Build Coastguard Worker     if (!ps_me_ctxt->u4_min_sad_reached)
954*495ae853SAndroid Build Coastguard Worker     {
955*495ae853SAndroid Build Coastguard Worker         /* Evaluate search candidates for initial mv pt */
956*495ae853SAndroid Build Coastguard Worker         ime_evaluate_init_srchposn_16x16(ps_me_ctxt, PRED_L0);
957*495ae853SAndroid Build Coastguard Worker 
958*495ae853SAndroid Build Coastguard Worker         /********************************************************************/
959*495ae853SAndroid Build Coastguard Worker         /*                  full pel motion estimation                      */
960*495ae853SAndroid Build Coastguard Worker         /********************************************************************/
961*495ae853SAndroid Build Coastguard Worker         ime_full_pel_motion_estimation_16x16(ps_me_ctxt, PRED_L0);
962*495ae853SAndroid Build Coastguard Worker 
963*495ae853SAndroid Build Coastguard Worker         /* Scale the MV to qpel resolution */
964*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->as_mb_part[PRED_L0].s_mv_curr.i2_mvx <<= 2;
965*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->as_mb_part[PRED_L0].s_mv_curr.i2_mvy <<= 2;
966*495ae853SAndroid Build Coastguard Worker 
967*495ae853SAndroid Build Coastguard Worker         if (ps_me_ctxt->u4_enable_hpel)
968*495ae853SAndroid Build Coastguard Worker         {
969*495ae853SAndroid Build Coastguard Worker             /* moving src pointer to the converged motion vector location*/
970*495ae853SAndroid Build Coastguard Worker             pu1_hpel_src = ps_me_ctxt->apu1_ref_buf_luma[PRED_L0]
971*495ae853SAndroid Build Coastguard Worker                            + (ps_me_ctxt->as_mb_part[PRED_L0].s_mv_curr.i2_mvx >> 2)
972*495ae853SAndroid Build Coastguard Worker                            + (ps_me_ctxt->as_mb_part[PRED_L0].s_mv_curr.i2_mvy >> 2) * i4_rec_strd;
973*495ae853SAndroid Build Coastguard Worker 
974*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->apu1_subpel_buffs[0] = ps_proc->apu1_subpel_buffs[0];
975*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->apu1_subpel_buffs[1] = ps_proc->apu1_subpel_buffs[1];
976*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->apu1_subpel_buffs[2] = ps_proc->apu1_subpel_buffs[2];
977*495ae853SAndroid Build Coastguard Worker 
978*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->u4_subpel_buf_strd = HP_BUFF_WD;
979*495ae853SAndroid Build Coastguard Worker 
980*495ae853SAndroid Build Coastguard Worker             /* half  pel search is done for both sides of full pel,
981*495ae853SAndroid Build Coastguard Worker              * hence half_x of width x height = 17x16 is created
982*495ae853SAndroid Build Coastguard Worker              * starting from left half_x of converged full pel */
983*495ae853SAndroid Build Coastguard Worker             pu1_hpel_src -= 1;
984*495ae853SAndroid Build Coastguard Worker 
985*495ae853SAndroid Build Coastguard Worker             /* computing half_x */
986*495ae853SAndroid Build Coastguard Worker             ps_codec->pf_ih264e_sixtapfilter_horz(pu1_hpel_src,
987*495ae853SAndroid Build Coastguard Worker                                                   ps_me_ctxt->apu1_subpel_buffs[0],
988*495ae853SAndroid Build Coastguard Worker                                                   i4_rec_strd,
989*495ae853SAndroid Build Coastguard Worker                                                   ps_me_ctxt->u4_subpel_buf_strd);
990*495ae853SAndroid Build Coastguard Worker 
991*495ae853SAndroid Build Coastguard Worker             /*
992*495ae853SAndroid Build Coastguard Worker              * Halfpel search is done for both sides of full pel,
993*495ae853SAndroid Build Coastguard Worker              * hence half_y of width x height = 16x17 is created
994*495ae853SAndroid Build Coastguard Worker              * starting from top half_y of converged full pel
995*495ae853SAndroid Build Coastguard Worker              * for half_xy top_left is required
996*495ae853SAndroid Build Coastguard Worker              * hence it starts from pu1_hpel_src = full_pel_converged_point - i4_rec_strd - 1
997*495ae853SAndroid Build Coastguard Worker              */
998*495ae853SAndroid Build Coastguard Worker             pu1_hpel_src -= i4_rec_strd;
999*495ae853SAndroid Build Coastguard Worker 
1000*495ae853SAndroid Build Coastguard Worker             /* computing half_y , and half_xy*/
1001*495ae853SAndroid Build Coastguard Worker             ps_codec->pf_ih264e_sixtap_filter_2dvh_vert(
1002*495ae853SAndroid Build Coastguard Worker                             pu1_hpel_src, ps_me_ctxt->apu1_subpel_buffs[1],
1003*495ae853SAndroid Build Coastguard Worker                             ps_me_ctxt->apu1_subpel_buffs[2], i4_rec_strd,
1004*495ae853SAndroid Build Coastguard Worker                             ps_me_ctxt->u4_subpel_buf_strd, ps_proc->ai16_pred1 + 3,
1005*495ae853SAndroid Build Coastguard Worker                             ps_me_ctxt->u4_subpel_buf_strd);
1006*495ae853SAndroid Build Coastguard Worker 
1007*495ae853SAndroid Build Coastguard Worker             ime_sub_pel_motion_estimation_16x16(ps_me_ctxt, PRED_L0);
1008*495ae853SAndroid Build Coastguard Worker         }
1009*495ae853SAndroid Build Coastguard Worker     }
1010*495ae853SAndroid Build Coastguard Worker 
1011*495ae853SAndroid Build Coastguard Worker 
1012*495ae853SAndroid Build Coastguard Worker     /***********************************************************************
1013*495ae853SAndroid Build Coastguard Worker      * If a particular skiip Mv is giving better sad, copy to the corresponding
1014*495ae853SAndroid Build Coastguard Worker      * MBPART
1015*495ae853SAndroid Build Coastguard Worker      * In B slices this loop should go only to PREDL1: If we found min sad
1016*495ae853SAndroid Build Coastguard Worker      * we will go to the skip ref list only
1017*495ae853SAndroid Build Coastguard Worker      * Have to find a way to make it without too much change or new vars
1018*495ae853SAndroid Build Coastguard Worker      **********************************************************************/
1019*495ae853SAndroid Build Coastguard Worker     if (s_skip_mbpart.i4_mb_cost < ps_me_ctxt->as_mb_part[PRED_L0].i4_mb_cost)
1020*495ae853SAndroid Build Coastguard Worker     {
1021*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->as_mb_part[PRED_L0].i4_mb_cost = s_skip_mbpart.i4_mb_cost;
1022*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->as_mb_part[PRED_L0].i4_mb_distortion = s_skip_mbpart.i4_mb_distortion;
1023*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->as_mb_part[PRED_L0].s_mv_curr = s_skip_mbpart.s_mv_curr;
1024*495ae853SAndroid Build Coastguard Worker     }
1025*495ae853SAndroid Build Coastguard Worker     else if (ps_me_ctxt->as_mb_part[PRED_L0].pu1_best_hpel_buf)
1026*495ae853SAndroid Build Coastguard Worker     {
1027*495ae853SAndroid Build Coastguard Worker         /* Now we have to copy the buffers */
1028*495ae853SAndroid Build Coastguard Worker         ps_codec->pf_inter_pred_luma_copy(
1029*495ae853SAndroid Build Coastguard Worker                         ps_me_ctxt->as_mb_part[PRED_L0].pu1_best_hpel_buf,
1030*495ae853SAndroid Build Coastguard Worker                         ps_proc->pu1_best_subpel_buf,
1031*495ae853SAndroid Build Coastguard Worker                         ps_me_ctxt->u4_subpel_buf_strd,
1032*495ae853SAndroid Build Coastguard Worker                         ps_proc->u4_bst_spel_buf_strd, MB_SIZE, MB_SIZE,
1033*495ae853SAndroid Build Coastguard Worker                         NULL, 0);
1034*495ae853SAndroid Build Coastguard Worker     }
1035*495ae853SAndroid Build Coastguard Worker 
1036*495ae853SAndroid Build Coastguard Worker     /**********************************************************************
1037*495ae853SAndroid Build Coastguard Worker      * Now get the minimum of MB part sads by searching over all ref lists
1038*495ae853SAndroid Build Coastguard Worker      **********************************************************************/
1039*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_pu->s_me_info[PRED_L0].s_mv.i2_mvx = ps_me_ctxt->as_mb_part[PRED_L0].s_mv_curr.i2_mvx;
1040*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_pu->s_me_info[PRED_L0].s_mv.i2_mvy = ps_me_ctxt->as_mb_part[PRED_L0].s_mv_curr.i2_mvy;
1041*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_cur_mb->i4_mb_cost = ps_me_ctxt->as_mb_part[PRED_L0].i4_mb_cost;
1042*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_cur_mb->i4_mb_distortion = ps_me_ctxt->as_mb_part[PRED_L0].i4_mb_distortion;
1043*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_cur_mb->u4_mb_type = P16x16;
1044*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_pu->b2_pred_mode = PRED_L0 ;
1045*495ae853SAndroid Build Coastguard Worker 
1046*495ae853SAndroid Build Coastguard Worker     /* Mark the reflists */
1047*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_pu->s_me_info[0].i1_ref_idx = -1;
1048*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_pu->s_me_info[1].i1_ref_idx =  0;
1049*495ae853SAndroid Build Coastguard Worker 
1050*495ae853SAndroid Build Coastguard Worker     /* number of partitions */
1051*495ae853SAndroid Build Coastguard Worker     ps_proc->u4_num_sub_partitions = 1;
1052*495ae853SAndroid Build Coastguard Worker     *(ps_proc->pu4_mb_pu_cnt) = 1;
1053*495ae853SAndroid Build Coastguard Worker 
1054*495ae853SAndroid Build Coastguard Worker     /* position in-terms of PU */
1055*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_pu->b4_pos_x = 0;
1056*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_pu->b4_pos_y = 0;
1057*495ae853SAndroid Build Coastguard Worker 
1058*495ae853SAndroid Build Coastguard Worker     /* PU size */
1059*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_pu->b4_wd = 3;
1060*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_pu->b4_ht = 3;
1061*495ae853SAndroid Build Coastguard Worker 
1062*495ae853SAndroid Build Coastguard Worker     /* Update min sad conditions */
1063*495ae853SAndroid Build Coastguard Worker     if (ps_me_ctxt->u4_min_sad_reached == 1)
1064*495ae853SAndroid Build Coastguard Worker     {
1065*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_cur_mb->u4_min_sad_reached = 1;
1066*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_cur_mb->u4_min_sad = ps_me_ctxt->i4_min_sad;
1067*495ae853SAndroid Build Coastguard Worker     }
1068*495ae853SAndroid Build Coastguard Worker }
1069*495ae853SAndroid Build Coastguard Worker 
1070*495ae853SAndroid Build Coastguard Worker /**
1071*495ae853SAndroid Build Coastguard Worker *******************************************************************************
1072*495ae853SAndroid Build Coastguard Worker *
1073*495ae853SAndroid Build Coastguard Worker * @brief This function performs motion estimation for the current NMB
1074*495ae853SAndroid Build Coastguard Worker *
1075*495ae853SAndroid Build Coastguard Worker * @par Description:
1076*495ae853SAndroid Build Coastguard Worker *  Intializes input and output pointers required by the function ih264e_compute_me
1077*495ae853SAndroid Build Coastguard Worker *  and calls the function ih264e_compute_me in a loop to process NMBs.
1078*495ae853SAndroid Build Coastguard Worker *
1079*495ae853SAndroid Build Coastguard Worker * @param[in] ps_proc
1080*495ae853SAndroid Build Coastguard Worker *  Process context corresponding to the job
1081*495ae853SAndroid Build Coastguard Worker *
1082*495ae853SAndroid Build Coastguard Worker * @param[in] u4_nmb_count
1083*495ae853SAndroid Build Coastguard Worker *  Number of mb's to process
1084*495ae853SAndroid Build Coastguard Worker *
1085*495ae853SAndroid Build Coastguard Worker * @returns
1086*495ae853SAndroid Build Coastguard Worker *
1087*495ae853SAndroid Build Coastguard Worker * @remarks none
1088*495ae853SAndroid Build Coastguard Worker *
1089*495ae853SAndroid Build Coastguard Worker *******************************************************************************
1090*495ae853SAndroid Build Coastguard Worker */
ih264e_compute_me_nmb(process_ctxt_t * ps_proc,UWORD32 u4_nmb_count)1091*495ae853SAndroid Build Coastguard Worker void ih264e_compute_me_nmb(process_ctxt_t *ps_proc, UWORD32 u4_nmb_count)
1092*495ae853SAndroid Build Coastguard Worker {
1093*495ae853SAndroid Build Coastguard Worker     /* pic pu */
1094*495ae853SAndroid Build Coastguard Worker     enc_pu_t *ps_pu_begin = ps_proc->ps_pu;
1095*495ae853SAndroid Build Coastguard Worker 
1096*495ae853SAndroid Build Coastguard Worker     /* ME map */
1097*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_me_map = ps_proc->pu1_me_map + (ps_proc->i4_mb_y * ps_proc->i4_wd_mbs);
1098*495ae853SAndroid Build Coastguard Worker 
1099*495ae853SAndroid Build Coastguard Worker     /* temp var */
1100*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_i;
1101*495ae853SAndroid Build Coastguard Worker 
1102*495ae853SAndroid Build Coastguard Worker     ps_proc->s_me_ctxt.u4_left_is_intra = ps_proc->s_left_mb_syntax_ele.u2_is_intra;
1103*495ae853SAndroid Build Coastguard Worker     ps_proc->s_me_ctxt.u4_left_is_skip = (ps_proc->s_left_mb_syntax_ele.u2_mb_type == PSKIP);
1104*495ae853SAndroid Build Coastguard Worker 
1105*495ae853SAndroid Build Coastguard Worker     for (u4_i = 0; u4_i < u4_nmb_count; u4_i++)
1106*495ae853SAndroid Build Coastguard Worker     {
1107*495ae853SAndroid Build Coastguard Worker         /* Wait for ME map */
1108*495ae853SAndroid Build Coastguard Worker         if (ps_proc->i4_mb_y > 0)
1109*495ae853SAndroid Build Coastguard Worker         {
1110*495ae853SAndroid Build Coastguard Worker             /* Wait for top right ME to be done */
1111*495ae853SAndroid Build Coastguard Worker             UWORD8 *pu1_me_map_tp_rw = ps_proc->pu1_me_map + (ps_proc->i4_mb_y - 1) * ps_proc->i4_wd_mbs;
1112*495ae853SAndroid Build Coastguard Worker 
1113*495ae853SAndroid Build Coastguard Worker             while (1)
1114*495ae853SAndroid Build Coastguard Worker             {
1115*495ae853SAndroid Build Coastguard Worker                 volatile UWORD8 *pu1_buf;
1116*495ae853SAndroid Build Coastguard Worker                 WORD32 idx = ps_proc->i4_mb_x + u4_i + 1;
1117*495ae853SAndroid Build Coastguard Worker 
1118*495ae853SAndroid Build Coastguard Worker                 idx = MIN(idx, (ps_proc->i4_wd_mbs - 1));
1119*495ae853SAndroid Build Coastguard Worker                 pu1_buf =  pu1_me_map_tp_rw + idx;
1120*495ae853SAndroid Build Coastguard Worker                 if(*pu1_buf)
1121*495ae853SAndroid Build Coastguard Worker                     break;
1122*495ae853SAndroid Build Coastguard Worker                 ithread_yield();
1123*495ae853SAndroid Build Coastguard Worker             }
1124*495ae853SAndroid Build Coastguard Worker         }
1125*495ae853SAndroid Build Coastguard Worker 
1126*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_skip_mv = &(ps_proc->ps_nmb_info[u4_i].as_skip_mv[0]);
1127*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_ngbr_avbl = &(ps_proc->ps_nmb_info[u4_i].s_ngbr_avbl);
1128*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_pred_mv = &(ps_proc->ps_nmb_info[u4_i].as_pred_mv[0]);
1129*495ae853SAndroid Build Coastguard Worker 
1130*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_cur_mb = &(ps_proc->ps_nmb_info[u4_i]);
1131*495ae853SAndroid Build Coastguard Worker 
1132*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_cur_mb->u4_min_sad = ps_proc->u4_min_sad;
1133*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_cur_mb->u4_min_sad_reached = 0;
1134*495ae853SAndroid Build Coastguard Worker 
1135*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_cur_mb->i4_mb_cost = INT_MAX;
1136*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_cur_mb->i4_mb_distortion = SHRT_MAX;
1137*495ae853SAndroid Build Coastguard Worker 
1138*495ae853SAndroid Build Coastguard Worker         /* Set the best subpel buf to the correct mb so that the buffer can be copied */
1139*495ae853SAndroid Build Coastguard Worker         ps_proc->pu1_best_subpel_buf = ps_proc->ps_nmb_info[u4_i].pu1_best_sub_pel_buf;
1140*495ae853SAndroid Build Coastguard Worker         ps_proc->u4_bst_spel_buf_strd = ps_proc->ps_nmb_info[u4_i].u4_bst_spel_buf_strd;
1141*495ae853SAndroid Build Coastguard Worker 
1142*495ae853SAndroid Build Coastguard Worker         /* Set the min sad conditions */
1143*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_cur_mb->u4_min_sad = ps_proc->ps_codec->u4_min_sad;
1144*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_cur_mb->u4_min_sad_reached = 0;
1145*495ae853SAndroid Build Coastguard Worker 
1146*495ae853SAndroid Build Coastguard Worker         /* Derive neighbor availability for the current macroblock */
1147*495ae853SAndroid Build Coastguard Worker         ih264e_derive_nghbr_avbl_of_mbs(ps_proc);
1148*495ae853SAndroid Build Coastguard Worker 
1149*495ae853SAndroid Build Coastguard Worker         /* init me */
1150*495ae853SAndroid Build Coastguard Worker         ih264e_init_me(ps_proc);
1151*495ae853SAndroid Build Coastguard Worker 
1152*495ae853SAndroid Build Coastguard Worker         /* Compute ME according to slice type */
1153*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_codec->apf_compute_me[ps_proc->i4_slice_type](ps_proc);
1154*495ae853SAndroid Build Coastguard Worker 
1155*495ae853SAndroid Build Coastguard Worker         /* update top and left structs */
1156*495ae853SAndroid Build Coastguard Worker         {
1157*495ae853SAndroid Build Coastguard Worker             mb_info_t *ps_top_syn = ps_proc->ps_top_row_mb_syntax_ele + ps_proc->i4_mb_x;
1158*495ae853SAndroid Build Coastguard Worker             mb_info_t *ps_top_left_syn = &(ps_proc->s_top_left_mb_syntax_ME);
1159*495ae853SAndroid Build Coastguard Worker             enc_pu_t *ps_left_mb_pu = &ps_proc->s_left_mb_pu_ME;
1160*495ae853SAndroid Build Coastguard Worker             enc_pu_t *ps_top_left_mb_pu = &ps_proc->s_top_left_mb_pu_ME;
1161*495ae853SAndroid Build Coastguard Worker             enc_pu_t *ps_top_mv = ps_proc->ps_top_row_pu_ME + ps_proc->i4_mb_x;
1162*495ae853SAndroid Build Coastguard Worker 
1163*495ae853SAndroid Build Coastguard Worker             *ps_top_left_syn = *ps_top_syn;
1164*495ae853SAndroid Build Coastguard Worker 
1165*495ae853SAndroid Build Coastguard Worker             *ps_top_left_mb_pu = *ps_top_mv;
1166*495ae853SAndroid Build Coastguard Worker             *ps_left_mb_pu = *ps_proc->ps_pu;
1167*495ae853SAndroid Build Coastguard Worker         }
1168*495ae853SAndroid Build Coastguard Worker 
1169*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_pu += *ps_proc->pu4_mb_pu_cnt;
1170*495ae853SAndroid Build Coastguard Worker 
1171*495ae853SAndroid Build Coastguard Worker         /* Copy the min sad reached info */
1172*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_nmb_info[u4_i].u4_min_sad_reached = ps_proc->ps_cur_mb->u4_min_sad_reached;
1173*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_nmb_info[u4_i].u4_min_sad   = ps_proc->ps_cur_mb->u4_min_sad;
1174*495ae853SAndroid Build Coastguard Worker 
1175*495ae853SAndroid Build Coastguard Worker         /*
1176*495ae853SAndroid Build Coastguard Worker          * To make sure that the MV map is properly sync to the
1177*495ae853SAndroid Build Coastguard Worker          * cache we need to do a DDB
1178*495ae853SAndroid Build Coastguard Worker          */
1179*495ae853SAndroid Build Coastguard Worker         {
1180*495ae853SAndroid Build Coastguard Worker             DATA_SYNC();
1181*495ae853SAndroid Build Coastguard Worker 
1182*495ae853SAndroid Build Coastguard Worker             pu1_me_map[ps_proc->i4_mb_x] = 1;
1183*495ae853SAndroid Build Coastguard Worker         }
1184*495ae853SAndroid Build Coastguard Worker         ps_proc->i4_mb_x++;
1185*495ae853SAndroid Build Coastguard Worker 
1186*495ae853SAndroid Build Coastguard Worker         ps_proc->s_me_ctxt.u4_left_is_intra = 0;
1187*495ae853SAndroid Build Coastguard Worker         ps_proc->s_me_ctxt.u4_left_is_skip = (ps_proc->ps_cur_mb->u4_mb_type  == PSKIP);
1188*495ae853SAndroid Build Coastguard Worker 
1189*495ae853SAndroid Build Coastguard Worker         /* update buffers pointers */
1190*495ae853SAndroid Build Coastguard Worker         ps_proc->pu1_src_buf_luma += MB_SIZE;
1191*495ae853SAndroid Build Coastguard Worker         ps_proc->pu1_rec_buf_luma += MB_SIZE;
1192*495ae853SAndroid Build Coastguard Worker         ps_proc->apu1_ref_buf_luma[0] += MB_SIZE;
1193*495ae853SAndroid Build Coastguard Worker         ps_proc->apu1_ref_buf_luma[1] += MB_SIZE;
1194*495ae853SAndroid Build Coastguard Worker 
1195*495ae853SAndroid Build Coastguard Worker         /*
1196*495ae853SAndroid Build Coastguard Worker          * Note: Although chroma mb size is 8, as the chroma buffers are interleaved,
1197*495ae853SAndroid Build Coastguard Worker          * the stride per MB is MB_SIZE
1198*495ae853SAndroid Build Coastguard Worker          */
1199*495ae853SAndroid Build Coastguard Worker         ps_proc->pu1_src_buf_chroma += MB_SIZE;
1200*495ae853SAndroid Build Coastguard Worker         ps_proc->pu1_rec_buf_chroma += MB_SIZE;
1201*495ae853SAndroid Build Coastguard Worker         ps_proc->apu1_ref_buf_chroma[0] += MB_SIZE;
1202*495ae853SAndroid Build Coastguard Worker         ps_proc->apu1_ref_buf_chroma[1] += MB_SIZE;
1203*495ae853SAndroid Build Coastguard Worker 
1204*495ae853SAndroid Build Coastguard Worker 
1205*495ae853SAndroid Build Coastguard Worker         ps_proc->pu4_mb_pu_cnt += 1;
1206*495ae853SAndroid Build Coastguard Worker     }
1207*495ae853SAndroid Build Coastguard Worker 
1208*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_pu = ps_pu_begin;
1209*495ae853SAndroid Build Coastguard Worker     ps_proc->i4_mb_x = ps_proc->i4_mb_x - u4_nmb_count;
1210*495ae853SAndroid Build Coastguard Worker 
1211*495ae853SAndroid Build Coastguard Worker     /* update buffers pointers */
1212*495ae853SAndroid Build Coastguard Worker     ps_proc->pu1_src_buf_luma -= MB_SIZE * u4_nmb_count;
1213*495ae853SAndroid Build Coastguard Worker     ps_proc->pu1_rec_buf_luma -= MB_SIZE * u4_nmb_count;
1214*495ae853SAndroid Build Coastguard Worker     ps_proc->apu1_ref_buf_luma[0] -= MB_SIZE * u4_nmb_count;
1215*495ae853SAndroid Build Coastguard Worker     ps_proc->apu1_ref_buf_luma[1] -= MB_SIZE * u4_nmb_count;
1216*495ae853SAndroid Build Coastguard Worker 
1217*495ae853SAndroid Build Coastguard Worker     /*
1218*495ae853SAndroid Build Coastguard Worker      * Note: Although chroma mb size is 8, as the chroma buffers are interleaved,
1219*495ae853SAndroid Build Coastguard Worker      * the stride per MB is MB_SIZE
1220*495ae853SAndroid Build Coastguard Worker      */
1221*495ae853SAndroid Build Coastguard Worker     ps_proc->pu1_src_buf_chroma -= MB_SIZE * u4_nmb_count;
1222*495ae853SAndroid Build Coastguard Worker     ps_proc->pu1_rec_buf_chroma -= MB_SIZE * u4_nmb_count;
1223*495ae853SAndroid Build Coastguard Worker     ps_proc->apu1_ref_buf_chroma[0] -= MB_SIZE * u4_nmb_count;
1224*495ae853SAndroid Build Coastguard Worker     ps_proc->apu1_ref_buf_chroma[1] -= MB_SIZE * u4_nmb_count;
1225*495ae853SAndroid Build Coastguard Worker 
1226*495ae853SAndroid Build Coastguard Worker     ps_proc->pu4_mb_pu_cnt -= u4_nmb_count;
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 *******************************************************************************
1232*495ae853SAndroid Build Coastguard Worker *
1233*495ae853SAndroid Build Coastguard Worker * @brief The function computes parameters for a BSKIP MB
1234*495ae853SAndroid Build Coastguard Worker *
1235*495ae853SAndroid Build Coastguard Worker * @par Description:
1236*495ae853SAndroid Build Coastguard Worker *  The function updates the skip motion vector for B Mb, check if the Mb can be
1237*495ae853SAndroid Build Coastguard Worker *  marked as skip and returns it
1238*495ae853SAndroid Build Coastguard Worker *
1239*495ae853SAndroid Build Coastguard Worker * @param[in] ps_proc
1240*495ae853SAndroid Build Coastguard Worker *  Pointer to process context
1241*495ae853SAndroid Build Coastguard Worker *
1242*495ae853SAndroid Build Coastguard Worker * @param[in] i4_reflist
1243*495ae853SAndroid Build Coastguard Worker *  Current active reference list
1244*495ae853SAndroid Build Coastguard Worker *
1245*495ae853SAndroid Build Coastguard Worker * @returns Flag indicating if the current Mb can be skip or not
1246*495ae853SAndroid Build Coastguard Worker *
1247*495ae853SAndroid Build Coastguard Worker * @remarks
1248*495ae853SAndroid Build Coastguard Worker *   The code implements the logic as described in sec 8.4.1.2.2
1249*495ae853SAndroid Build Coastguard Worker *   It also computes co-located MB parmas according to sec 8.4.1.2.1
1250*495ae853SAndroid Build Coastguard Worker *
1251*495ae853SAndroid Build Coastguard Worker *   Need to add condition for this fucntion to be used in ME
1252*495ae853SAndroid Build Coastguard Worker *
1253*495ae853SAndroid Build Coastguard Worker *******************************************************************************
1254*495ae853SAndroid Build Coastguard Worker */
ih264e_find_bskip_params_me(process_ctxt_t * ps_proc,WORD32 i4_reflist)1255*495ae853SAndroid Build Coastguard Worker WORD32 ih264e_find_bskip_params_me(process_ctxt_t *ps_proc, WORD32 i4_reflist)
1256*495ae853SAndroid Build Coastguard Worker {
1257*495ae853SAndroid Build Coastguard Worker     /* Colzero for co-located MB */
1258*495ae853SAndroid Build Coastguard Worker     WORD32 i4_colzeroflag;
1259*495ae853SAndroid Build Coastguard Worker 
1260*495ae853SAndroid Build Coastguard Worker     /* motion vectors for neighbouring MBs */
1261*495ae853SAndroid Build Coastguard Worker     enc_pu_t *ps_a_pu, *ps_c_pu, *ps_b_pu;
1262*495ae853SAndroid Build Coastguard Worker 
1263*495ae853SAndroid Build Coastguard Worker     /* Variables to check if a particular mB is available */
1264*495ae853SAndroid Build Coastguard Worker     WORD32 i4_a, i4_b, i4_c, i4_c_avail;
1265*495ae853SAndroid Build Coastguard Worker 
1266*495ae853SAndroid Build Coastguard Worker     /* Mode availability, init to no modes available     */
1267*495ae853SAndroid Build Coastguard Worker     WORD32 i4_mode_avail;
1268*495ae853SAndroid Build Coastguard Worker 
1269*495ae853SAndroid Build Coastguard Worker     /*  mb neighbor availability */
1270*495ae853SAndroid Build Coastguard Worker     block_neighbors_t *ps_ngbr_avbl = ps_proc->ps_ngbr_avbl;
1271*495ae853SAndroid Build Coastguard Worker 
1272*495ae853SAndroid Build Coastguard Worker     /* Temp var */
1273*495ae853SAndroid Build Coastguard Worker     WORD32 i, i4_cmpl_mode, i4_skip_type = -1;
1274*495ae853SAndroid Build Coastguard Worker 
1275*495ae853SAndroid Build Coastguard Worker     /*
1276*495ae853SAndroid Build Coastguard Worker      * Colocated motion vector
1277*495ae853SAndroid Build Coastguard Worker      */
1278*495ae853SAndroid Build Coastguard Worker     mv_t s_mvcol;
1279*495ae853SAndroid Build Coastguard Worker 
1280*495ae853SAndroid Build Coastguard Worker     /*
1281*495ae853SAndroid Build Coastguard Worker      * Colocated picture idx
1282*495ae853SAndroid Build Coastguard Worker      */
1283*495ae853SAndroid Build Coastguard Worker     WORD32 i4_refidxcol;
1284*495ae853SAndroid Build Coastguard Worker 
1285*495ae853SAndroid Build Coastguard Worker     UNUSED(i4_reflist);
1286*495ae853SAndroid Build Coastguard Worker 
1287*495ae853SAndroid Build Coastguard Worker     /**************************************************************************
1288*495ae853SAndroid Build Coastguard Worker      *Find co-located MB parameters
1289*495ae853SAndroid Build Coastguard Worker      *      See sec 8.4.1.2.1  for reference
1290*495ae853SAndroid Build Coastguard Worker      **************************************************************************/
1291*495ae853SAndroid Build Coastguard Worker     {
1292*495ae853SAndroid Build Coastguard Worker         /*
1293*495ae853SAndroid Build Coastguard Worker          * Find the co-located Mb and update the skip and pred appropriately
1294*495ae853SAndroid Build Coastguard Worker          * 1) Default colpic is forward ref : Table 8-6
1295*495ae853SAndroid Build Coastguard Worker          * 2) Default mb col is current MB : Table 8-8
1296*495ae853SAndroid Build Coastguard Worker          */
1297*495ae853SAndroid Build Coastguard Worker 
1298*495ae853SAndroid Build Coastguard Worker         if (ps_proc->ps_colpu->b1_intra_flag)
1299*495ae853SAndroid Build Coastguard Worker         {
1300*495ae853SAndroid Build Coastguard Worker             s_mvcol.i2_mvx = 0;
1301*495ae853SAndroid Build Coastguard Worker             s_mvcol.i2_mvy = 0;
1302*495ae853SAndroid Build Coastguard Worker             i4_refidxcol = -1;
1303*495ae853SAndroid Build Coastguard Worker         }
1304*495ae853SAndroid Build Coastguard Worker         else
1305*495ae853SAndroid Build Coastguard Worker         {
1306*495ae853SAndroid Build Coastguard Worker             if (ps_proc->ps_colpu->b2_pred_mode != PRED_L1)
1307*495ae853SAndroid Build Coastguard Worker             {
1308*495ae853SAndroid Build Coastguard Worker                 s_mvcol = ps_proc->ps_colpu->s_me_info[PRED_L0].s_mv;
1309*495ae853SAndroid Build Coastguard Worker                 i4_refidxcol = 0;
1310*495ae853SAndroid Build Coastguard Worker             }
1311*495ae853SAndroid Build Coastguard Worker             else // if(ps_proc->ps_colpu->b2_pred_mode != PRED_L0)
1312*495ae853SAndroid Build Coastguard Worker             {
1313*495ae853SAndroid Build Coastguard Worker                 s_mvcol = ps_proc->ps_colpu->s_me_info[PRED_L1].s_mv;
1314*495ae853SAndroid Build Coastguard Worker                 i4_refidxcol = 0;
1315*495ae853SAndroid Build Coastguard Worker             }
1316*495ae853SAndroid Build Coastguard Worker         }
1317*495ae853SAndroid Build Coastguard Worker 
1318*495ae853SAndroid Build Coastguard Worker         /* RefPicList1[ 0 ]  is marked as  "used for short-term reference", as default */
1319*495ae853SAndroid Build Coastguard Worker         i4_colzeroflag = (!i4_refidxcol && (ABS(s_mvcol.i2_mvx) <= 1)
1320*495ae853SAndroid Build Coastguard Worker                         && (ABS(s_mvcol.i2_mvy) <= 1));
1321*495ae853SAndroid Build Coastguard Worker 
1322*495ae853SAndroid Build Coastguard Worker     }
1323*495ae853SAndroid Build Coastguard Worker 
1324*495ae853SAndroid Build Coastguard Worker     /***************************************************************************
1325*495ae853SAndroid Build Coastguard Worker      * Evaluating skip params : Spatial Skip
1326*495ae853SAndroid Build Coastguard Worker      **************************************************************************/
1327*495ae853SAndroid Build Coastguard Worker     {
1328*495ae853SAndroid Build Coastguard Worker     /* Get the neighbouring MBS according to Section 8.4.1.2.2 */
1329*495ae853SAndroid Build Coastguard Worker     ps_a_pu = &ps_proc->s_left_mb_pu_ME;
1330*495ae853SAndroid Build Coastguard Worker     ps_b_pu = (ps_proc->ps_top_row_pu_ME + ps_proc->i4_mb_x);
1331*495ae853SAndroid Build Coastguard Worker 
1332*495ae853SAndroid Build Coastguard Worker     i4_c_avail = 0;
1333*495ae853SAndroid Build Coastguard Worker     if (ps_ngbr_avbl->u1_mb_c)
1334*495ae853SAndroid Build Coastguard Worker     {
1335*495ae853SAndroid Build Coastguard Worker         ps_c_pu = &((ps_proc->ps_top_row_pu_ME + ps_proc->i4_mb_x)[1]);
1336*495ae853SAndroid Build Coastguard Worker         i4_c_avail = 1;
1337*495ae853SAndroid Build Coastguard Worker     }
1338*495ae853SAndroid Build Coastguard Worker     else
1339*495ae853SAndroid Build Coastguard Worker     {
1340*495ae853SAndroid Build Coastguard Worker         ps_c_pu = &ps_proc->s_top_left_mb_pu_ME;
1341*495ae853SAndroid Build Coastguard Worker         i4_c_avail = ps_ngbr_avbl->u1_mb_d;
1342*495ae853SAndroid Build Coastguard Worker     }
1343*495ae853SAndroid Build Coastguard Worker 
1344*495ae853SAndroid Build Coastguard Worker     i4_a = ps_ngbr_avbl->u1_mb_a;
1345*495ae853SAndroid Build Coastguard Worker     i4_b = ps_ngbr_avbl->u1_mb_b;
1346*495ae853SAndroid Build Coastguard Worker     i4_c = i4_c_avail;
1347*495ae853SAndroid Build Coastguard Worker 
1348*495ae853SAndroid Build Coastguard Worker     /* Init to no mode avail */
1349*495ae853SAndroid Build Coastguard Worker     i4_mode_avail = 0;
1350*495ae853SAndroid Build Coastguard Worker     for (i = 0; i < 2; i++)
1351*495ae853SAndroid Build Coastguard Worker     {
1352*495ae853SAndroid Build Coastguard Worker         i4_cmpl_mode = (i == 0) ? PRED_L1 : PRED_L0;
1353*495ae853SAndroid Build Coastguard Worker 
1354*495ae853SAndroid Build Coastguard Worker         i4_mode_avail |= (i4_a && (ps_a_pu->b2_pred_mode != i4_cmpl_mode) && (ps_a_pu->s_me_info[i].i1_ref_idx != 0))<<i;
1355*495ae853SAndroid Build Coastguard Worker         i4_mode_avail |= (i4_b && (ps_b_pu->b2_pred_mode != i4_cmpl_mode) && (ps_b_pu->s_me_info[i].i1_ref_idx != 0))<<i;
1356*495ae853SAndroid Build Coastguard Worker         i4_mode_avail |= (i4_c && (ps_c_pu->b2_pred_mode != i4_cmpl_mode) && (ps_c_pu->s_me_info[i].i1_ref_idx != 0))<<i;
1357*495ae853SAndroid Build Coastguard Worker     }
1358*495ae853SAndroid Build Coastguard Worker 
1359*495ae853SAndroid Build Coastguard Worker     if (i4_mode_avail == 0x3 || i4_mode_avail == 0x0)
1360*495ae853SAndroid Build Coastguard Worker     {
1361*495ae853SAndroid Build Coastguard Worker         i4_skip_type= PRED_BI;
1362*495ae853SAndroid Build Coastguard Worker     }
1363*495ae853SAndroid Build Coastguard Worker     else if(i4_mode_avail == 0x1)
1364*495ae853SAndroid Build Coastguard Worker     {
1365*495ae853SAndroid Build Coastguard Worker         i4_skip_type = PRED_L0;
1366*495ae853SAndroid Build Coastguard Worker     }
1367*495ae853SAndroid Build Coastguard Worker     else if(i4_mode_avail == 0x2)
1368*495ae853SAndroid Build Coastguard Worker     {
1369*495ae853SAndroid Build Coastguard Worker         i4_skip_type = PRED_L1;
1370*495ae853SAndroid Build Coastguard Worker     }
1371*495ae853SAndroid Build Coastguard Worker 
1372*495ae853SAndroid Build Coastguard Worker     /* Update skip MV for L0 */
1373*495ae853SAndroid Build Coastguard Worker     if ((i4_mode_avail & 0x1) && (!i4_colzeroflag))
1374*495ae853SAndroid Build Coastguard Worker     {
1375*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_skip_mv[0].s_mv.i2_mvx = ps_proc->ps_pred_mv[0].s_mv.i2_mvx;
1376*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_skip_mv[0].s_mv.i2_mvy = ps_proc->ps_pred_mv[0].s_mv.i2_mvy;
1377*495ae853SAndroid Build Coastguard Worker     }
1378*495ae853SAndroid Build Coastguard Worker     else
1379*495ae853SAndroid Build Coastguard Worker     {
1380*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_skip_mv[0].s_mv.i2_mvx = 0;
1381*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_skip_mv[0].s_mv.i2_mvy = 0;
1382*495ae853SAndroid Build Coastguard Worker     }
1383*495ae853SAndroid Build Coastguard Worker 
1384*495ae853SAndroid Build Coastguard Worker     /* Update skip MV for L1 */
1385*495ae853SAndroid Build Coastguard Worker     if ((i4_mode_avail & 0x2) && (!i4_colzeroflag))
1386*495ae853SAndroid Build Coastguard Worker     {
1387*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_skip_mv[1].s_mv.i2_mvx = ps_proc->ps_pred_mv[1].s_mv.i2_mvx;
1388*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_skip_mv[1].s_mv.i2_mvy = ps_proc->ps_pred_mv[1].s_mv.i2_mvy;
1389*495ae853SAndroid Build Coastguard Worker     }
1390*495ae853SAndroid Build Coastguard Worker     else
1391*495ae853SAndroid Build Coastguard Worker     {
1392*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_skip_mv[1].s_mv.i2_mvx = 0;
1393*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_skip_mv[1].s_mv.i2_mvy = 0;
1394*495ae853SAndroid Build Coastguard Worker     }
1395*495ae853SAndroid Build Coastguard Worker 
1396*495ae853SAndroid Build Coastguard Worker     }
1397*495ae853SAndroid Build Coastguard Worker 
1398*495ae853SAndroid Build Coastguard Worker     /***************************************************************************
1399*495ae853SAndroid Build Coastguard Worker      * Evaluating skip params : Temporal skip
1400*495ae853SAndroid Build Coastguard Worker      **************************************************************************/
1401*495ae853SAndroid Build Coastguard Worker     {
1402*495ae853SAndroid Build Coastguard Worker         pic_buf_t *  ps_ref_pic[MAX_REF_PIC_CNT];
1403*495ae853SAndroid Build Coastguard Worker         WORD32 i4_td, i4_tx, i4_tb, i4_dist_scale_factor;
1404*495ae853SAndroid Build Coastguard Worker         enc_pu_mv_t *ps_skip_mv = &ps_proc->ps_skip_mv[2];
1405*495ae853SAndroid Build Coastguard Worker 
1406*495ae853SAndroid Build Coastguard Worker         ps_ref_pic[PRED_L0] = ps_proc->aps_ref_pic[PRED_L0];
1407*495ae853SAndroid Build Coastguard Worker         ps_ref_pic[PRED_L1] = ps_proc->aps_ref_pic[PRED_L1];
1408*495ae853SAndroid Build Coastguard Worker 
1409*495ae853SAndroid Build Coastguard Worker         i4_tb = ps_proc->ps_codec->i4_poc - ps_ref_pic[PRED_L0]->i4_abs_poc;
1410*495ae853SAndroid Build Coastguard Worker         i4_td = ps_ref_pic[PRED_L1]->i4_abs_poc - ps_ref_pic[PRED_L0]->i4_abs_poc;
1411*495ae853SAndroid Build Coastguard Worker 
1412*495ae853SAndroid Build Coastguard Worker         i4_tb = CLIP3(-128, 127, i4_tb);
1413*495ae853SAndroid Build Coastguard Worker         i4_td = CLIP3(-128, 127, i4_td);
1414*495ae853SAndroid Build Coastguard Worker 
1415*495ae853SAndroid Build Coastguard Worker         i4_tx = ( 16384 + ABS( i4_td / 2 ) ) / i4_td ;
1416*495ae853SAndroid Build Coastguard Worker         i4_dist_scale_factor =  CLIP3( -1024, 1023, ( i4_tb * i4_tx + 32 ) >> 6 );
1417*495ae853SAndroid Build Coastguard Worker 
1418*495ae853SAndroid Build Coastguard Worker         /* Motion vectors taken in full pel resolution , hence  -> (& 0xfffc) operation */
1419*495ae853SAndroid Build Coastguard Worker         ps_skip_mv[PRED_L0].s_mv.i2_mvx = (( i4_dist_scale_factor * s_mvcol.i2_mvx + 128 ) >> 8) & 0xfffc;
1420*495ae853SAndroid Build Coastguard Worker         ps_skip_mv[PRED_L0].s_mv.i2_mvy = (( i4_dist_scale_factor * s_mvcol.i2_mvy + 128 ) >> 8) & 0xfffc;
1421*495ae853SAndroid Build Coastguard Worker 
1422*495ae853SAndroid Build Coastguard Worker         ps_skip_mv[PRED_L1].s_mv.i2_mvx = (ps_skip_mv[PRED_L0].s_mv.i2_mvx - s_mvcol.i2_mvx) & 0xfffc;
1423*495ae853SAndroid Build Coastguard Worker         ps_skip_mv[PRED_L1].s_mv.i2_mvy = (ps_skip_mv[PRED_L0].s_mv.i2_mvy - s_mvcol.i2_mvy) & 0xfffc;
1424*495ae853SAndroid Build Coastguard Worker 
1425*495ae853SAndroid Build Coastguard Worker     }
1426*495ae853SAndroid Build Coastguard Worker 
1427*495ae853SAndroid Build Coastguard Worker     return i4_skip_type;
1428*495ae853SAndroid Build Coastguard Worker }
1429*495ae853SAndroid Build Coastguard Worker 
1430*495ae853SAndroid Build Coastguard Worker /**
1431*495ae853SAndroid Build Coastguard Worker *******************************************************************************
1432*495ae853SAndroid Build Coastguard Worker *
1433*495ae853SAndroid Build Coastguard Worker * @brief The function computes the skip motion vectoe for B mb
1434*495ae853SAndroid Build Coastguard Worker *
1435*495ae853SAndroid Build Coastguard Worker * @par Description:
1436*495ae853SAndroid Build Coastguard Worker *  The function gives the skip motion vector for B Mb, check if the Mb can be
1437*495ae853SAndroid Build Coastguard Worker *  marked as skip
1438*495ae853SAndroid Build Coastguard Worker *
1439*495ae853SAndroid Build Coastguard Worker * @param[in] ps_proc
1440*495ae853SAndroid Build Coastguard Worker *  Pointer to process context
1441*495ae853SAndroid Build Coastguard Worker *
1442*495ae853SAndroid Build Coastguard Worker * @param[in] i4_reflist
1443*495ae853SAndroid Build Coastguard Worker *  Dummy
1444*495ae853SAndroid Build Coastguard Worker *
1445*495ae853SAndroid Build Coastguard Worker * @returns Flag indicating if the current Mb can be skip or not
1446*495ae853SAndroid Build Coastguard Worker *
1447*495ae853SAndroid Build Coastguard Worker * @remarks The code implements the logic as described in sec 8.4.1.2.2 in H264
1448*495ae853SAndroid Build Coastguard Worker *   specification. It also computes co-located MB parmas according to sec 8.4.1.2.1
1449*495ae853SAndroid Build Coastguard Worker *
1450*495ae853SAndroid Build Coastguard Worker *******************************************************************************/
ih264e_find_bskip_params(process_ctxt_t * ps_proc,WORD32 i4_reflist)1451*495ae853SAndroid Build Coastguard Worker WORD32 ih264e_find_bskip_params(process_ctxt_t *ps_proc, WORD32 i4_reflist)
1452*495ae853SAndroid Build Coastguard Worker {
1453*495ae853SAndroid Build Coastguard Worker     /* Colzero for co-located MB */
1454*495ae853SAndroid Build Coastguard Worker     WORD32 i4_colzeroflag;
1455*495ae853SAndroid Build Coastguard Worker 
1456*495ae853SAndroid Build Coastguard Worker     /* motion vectors */
1457*495ae853SAndroid Build Coastguard Worker     enc_pu_t *ps_a_pu, *ps_c_pu, *ps_b_pu;
1458*495ae853SAndroid Build Coastguard Worker 
1459*495ae853SAndroid Build Coastguard Worker     /* Syntax elem */
1460*495ae853SAndroid Build Coastguard Worker     mb_info_t *ps_a_syn, *ps_b_syn, *ps_c_syn;
1461*495ae853SAndroid Build Coastguard Worker 
1462*495ae853SAndroid Build Coastguard Worker     /* Variables to check if a particular mB is available */
1463*495ae853SAndroid Build Coastguard Worker     WORD32 i4_a, i4_b, i4_c, i4_c_avail;
1464*495ae853SAndroid Build Coastguard Worker 
1465*495ae853SAndroid Build Coastguard Worker     /* Mode availability, init to no modes available     */
1466*495ae853SAndroid Build Coastguard Worker     WORD32 i4_mode_avail;
1467*495ae853SAndroid Build Coastguard Worker 
1468*495ae853SAndroid Build Coastguard Worker     /*  mb neighbor availability */
1469*495ae853SAndroid Build Coastguard Worker     block_neighbors_t *ps_ngbr_avbl = ps_proc->ps_ngbr_avbl;
1470*495ae853SAndroid Build Coastguard Worker 
1471*495ae853SAndroid Build Coastguard Worker     /* Temp var */
1472*495ae853SAndroid Build Coastguard Worker     WORD32 i, i4_cmpl_mode;
1473*495ae853SAndroid Build Coastguard Worker 
1474*495ae853SAndroid Build Coastguard Worker     UNUSED(i4_reflist);
1475*495ae853SAndroid Build Coastguard Worker 
1476*495ae853SAndroid Build Coastguard Worker     /**************************************************************************
1477*495ae853SAndroid Build Coastguard Worker      * Find co-locates parameters
1478*495ae853SAndroid Build Coastguard Worker      *      See sec 8.4.1.2.1  for reference
1479*495ae853SAndroid Build Coastguard Worker      **************************************************************************/
1480*495ae853SAndroid Build Coastguard Worker     {
1481*495ae853SAndroid Build Coastguard Worker         /*
1482*495ae853SAndroid Build Coastguard Worker          * Find the co-located Mb and update the skip and pred appropriately
1483*495ae853SAndroid Build Coastguard Worker          * 1) Default colpic is forward ref : Table 8-6
1484*495ae853SAndroid Build Coastguard Worker          * 2) Default mb col is current MB : Table 8-8
1485*495ae853SAndroid Build Coastguard Worker          */
1486*495ae853SAndroid Build Coastguard Worker 
1487*495ae853SAndroid Build Coastguard Worker         mv_t s_mvcol;
1488*495ae853SAndroid Build Coastguard Worker         WORD32 i4_refidxcol;
1489*495ae853SAndroid Build Coastguard Worker 
1490*495ae853SAndroid Build Coastguard Worker         if (ps_proc->ps_colpu->b1_intra_flag)
1491*495ae853SAndroid Build Coastguard Worker         {
1492*495ae853SAndroid Build Coastguard Worker             s_mvcol.i2_mvx = 0;
1493*495ae853SAndroid Build Coastguard Worker             s_mvcol.i2_mvy = 0;
1494*495ae853SAndroid Build Coastguard Worker             i4_refidxcol = -1;
1495*495ae853SAndroid Build Coastguard Worker         }
1496*495ae853SAndroid Build Coastguard Worker         else
1497*495ae853SAndroid Build Coastguard Worker         {
1498*495ae853SAndroid Build Coastguard Worker             if (ps_proc->ps_colpu->b2_pred_mode != PRED_L1)
1499*495ae853SAndroid Build Coastguard Worker             {
1500*495ae853SAndroid Build Coastguard Worker                 s_mvcol = ps_proc->ps_colpu->s_me_info[PRED_L0].s_mv;
1501*495ae853SAndroid Build Coastguard Worker                 i4_refidxcol = 0;
1502*495ae853SAndroid Build Coastguard Worker             }
1503*495ae853SAndroid Build Coastguard Worker             else // if(ps_proc->ps_colpu->b2_pred_mode != PRED_L0)
1504*495ae853SAndroid Build Coastguard Worker             {
1505*495ae853SAndroid Build Coastguard Worker                 s_mvcol = ps_proc->ps_colpu->s_me_info[PRED_L1].s_mv;
1506*495ae853SAndroid Build Coastguard Worker                 i4_refidxcol = 0;
1507*495ae853SAndroid Build Coastguard Worker             }
1508*495ae853SAndroid Build Coastguard Worker         }
1509*495ae853SAndroid Build Coastguard Worker 
1510*495ae853SAndroid Build Coastguard Worker         /* RefPicList1[ 0 ]  is marked as  "used for short-term reference", as default */
1511*495ae853SAndroid Build Coastguard Worker         i4_colzeroflag = (!i4_refidxcol && (ABS(s_mvcol.i2_mvx) <= 1)
1512*495ae853SAndroid Build Coastguard Worker                         && (ABS(s_mvcol.i2_mvy) <= 1));
1513*495ae853SAndroid Build Coastguard Worker 
1514*495ae853SAndroid Build Coastguard Worker     }
1515*495ae853SAndroid Build Coastguard Worker 
1516*495ae853SAndroid Build Coastguard Worker     /***************************************************************************
1517*495ae853SAndroid Build Coastguard Worker      * Evaluating skip params
1518*495ae853SAndroid Build Coastguard Worker      **************************************************************************/
1519*495ae853SAndroid Build Coastguard Worker     /* Section 8.4.1.2.2 */
1520*495ae853SAndroid Build Coastguard Worker     ps_a_syn = &ps_proc->s_left_mb_syntax_ele;
1521*495ae853SAndroid Build Coastguard Worker     ps_a_pu = &ps_proc->s_left_mb_pu;
1522*495ae853SAndroid Build Coastguard Worker 
1523*495ae853SAndroid Build Coastguard Worker     ps_b_syn = ps_proc->ps_top_row_mb_syntax_ele + ps_proc->i4_mb_x;
1524*495ae853SAndroid Build Coastguard Worker     ps_b_pu = (ps_proc->ps_top_row_pu + ps_proc->i4_mb_x);
1525*495ae853SAndroid Build Coastguard Worker 
1526*495ae853SAndroid Build Coastguard Worker     i4_c_avail = 0;
1527*495ae853SAndroid Build Coastguard Worker     if (ps_ngbr_avbl->u1_mb_c)
1528*495ae853SAndroid Build Coastguard Worker     {
1529*495ae853SAndroid Build Coastguard Worker         ps_c_syn = &((ps_proc->ps_top_row_mb_syntax_ele + ps_proc->i4_mb_x)[1]);
1530*495ae853SAndroid Build Coastguard Worker         ps_c_pu = &((ps_proc->ps_top_row_pu + ps_proc->i4_mb_x)[1]);
1531*495ae853SAndroid Build Coastguard Worker         i4_c_avail = 1;
1532*495ae853SAndroid Build Coastguard Worker     }
1533*495ae853SAndroid Build Coastguard Worker     else
1534*495ae853SAndroid Build Coastguard Worker     {
1535*495ae853SAndroid Build Coastguard Worker         ps_c_syn = &(ps_proc->s_top_left_mb_syntax_ele);
1536*495ae853SAndroid Build Coastguard Worker         ps_c_pu = &ps_proc->s_top_left_mb_pu;
1537*495ae853SAndroid Build Coastguard Worker         i4_c_avail = ps_ngbr_avbl->u1_mb_d;
1538*495ae853SAndroid Build Coastguard Worker     }
1539*495ae853SAndroid Build Coastguard Worker 
1540*495ae853SAndroid Build Coastguard Worker 
1541*495ae853SAndroid Build Coastguard Worker     i4_a = ps_ngbr_avbl->u1_mb_a;
1542*495ae853SAndroid Build Coastguard Worker     i4_a &= !ps_a_syn->u2_is_intra;
1543*495ae853SAndroid Build Coastguard Worker 
1544*495ae853SAndroid Build Coastguard Worker     i4_b = ps_ngbr_avbl->u1_mb_b;
1545*495ae853SAndroid Build Coastguard Worker     i4_b &= !ps_b_syn->u2_is_intra;
1546*495ae853SAndroid Build Coastguard Worker 
1547*495ae853SAndroid Build Coastguard Worker     i4_c = i4_c_avail;
1548*495ae853SAndroid Build Coastguard Worker     i4_c &= !ps_c_syn->u2_is_intra;
1549*495ae853SAndroid Build Coastguard Worker 
1550*495ae853SAndroid Build Coastguard Worker     /* Init to no mode avail */
1551*495ae853SAndroid Build Coastguard Worker     i4_mode_avail = 0;
1552*495ae853SAndroid Build Coastguard Worker     for (i = 0; i < 2; i++)
1553*495ae853SAndroid Build Coastguard Worker     {
1554*495ae853SAndroid Build Coastguard Worker         i4_cmpl_mode = (i == 0) ? PRED_L1 : PRED_L0;
1555*495ae853SAndroid Build Coastguard Worker 
1556*495ae853SAndroid Build Coastguard Worker         i4_mode_avail |= (i4_a && (ps_a_pu->b2_pred_mode != i4_cmpl_mode) && (ps_a_pu->s_me_info[i].i1_ref_idx != 0))<<i;
1557*495ae853SAndroid Build Coastguard Worker         i4_mode_avail |= (i4_b && (ps_b_pu->b2_pred_mode != i4_cmpl_mode) && (ps_b_pu->s_me_info[i].i1_ref_idx != 0))<<i;
1558*495ae853SAndroid Build Coastguard Worker         i4_mode_avail |= (i4_c && (ps_c_pu->b2_pred_mode != i4_cmpl_mode) && (ps_c_pu->s_me_info[i].i1_ref_idx != 0))<<i;
1559*495ae853SAndroid Build Coastguard Worker     }
1560*495ae853SAndroid Build Coastguard Worker 
1561*495ae853SAndroid Build Coastguard Worker     /* Update skip MV for L0 */
1562*495ae853SAndroid Build Coastguard Worker     if ((i4_mode_avail & 0x1) && (!i4_colzeroflag))
1563*495ae853SAndroid Build Coastguard Worker     {
1564*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_skip_mv[0].s_mv.i2_mvx = ps_proc->ps_pred_mv[0].s_mv.i2_mvx;
1565*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_skip_mv[0].s_mv.i2_mvy = ps_proc->ps_pred_mv[0].s_mv.i2_mvy;
1566*495ae853SAndroid Build Coastguard Worker     }
1567*495ae853SAndroid Build Coastguard Worker     else
1568*495ae853SAndroid Build Coastguard Worker     {
1569*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_skip_mv[0].s_mv.i2_mvx = 0;
1570*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_skip_mv[0].s_mv.i2_mvy = 0;
1571*495ae853SAndroid Build Coastguard Worker     }
1572*495ae853SAndroid Build Coastguard Worker 
1573*495ae853SAndroid Build Coastguard Worker     /* Update skip MV for L1 */
1574*495ae853SAndroid Build Coastguard Worker     if ((i4_mode_avail & 0x2) && (!i4_colzeroflag))
1575*495ae853SAndroid Build Coastguard Worker     {
1576*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_skip_mv[1].s_mv.i2_mvx = ps_proc->ps_pred_mv[1].s_mv.i2_mvx;
1577*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_skip_mv[1].s_mv.i2_mvy = ps_proc->ps_pred_mv[1].s_mv.i2_mvy;
1578*495ae853SAndroid Build Coastguard Worker     }
1579*495ae853SAndroid Build Coastguard Worker     else
1580*495ae853SAndroid Build Coastguard Worker     {
1581*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_skip_mv[1].s_mv.i2_mvx = 0;
1582*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_skip_mv[1].s_mv.i2_mvy = 0;
1583*495ae853SAndroid Build Coastguard Worker     }
1584*495ae853SAndroid Build Coastguard Worker 
1585*495ae853SAndroid Build Coastguard Worker     /* Now see if the ME information matches the SKIP information */
1586*495ae853SAndroid Build Coastguard Worker     switch (ps_proc->ps_pu->b2_pred_mode)
1587*495ae853SAndroid Build Coastguard Worker     {
1588*495ae853SAndroid Build Coastguard Worker         case PRED_BI:
1589*495ae853SAndroid Build Coastguard Worker             if (  (ps_proc->ps_pu->s_me_info[0].s_mv.i2_mvx == ps_proc->ps_skip_mv[0].s_mv.i2_mvx)
1590*495ae853SAndroid Build Coastguard Worker                && (ps_proc->ps_pu->s_me_info[0].s_mv.i2_mvy == ps_proc->ps_skip_mv[0].s_mv.i2_mvy)
1591*495ae853SAndroid Build Coastguard Worker                && (ps_proc->ps_pu->s_me_info[1].s_mv.i2_mvx == ps_proc->ps_skip_mv[1].s_mv.i2_mvx)
1592*495ae853SAndroid Build Coastguard Worker                && (ps_proc->ps_pu->s_me_info[1].s_mv.i2_mvy == ps_proc->ps_skip_mv[1].s_mv.i2_mvy)
1593*495ae853SAndroid Build Coastguard Worker                && (i4_mode_avail ==  0x3 || i4_mode_avail == 0x0))
1594*495ae853SAndroid Build Coastguard Worker             {
1595*495ae853SAndroid Build Coastguard Worker                 return 1;
1596*495ae853SAndroid Build Coastguard Worker             }
1597*495ae853SAndroid Build Coastguard Worker             break;
1598*495ae853SAndroid Build Coastguard Worker 
1599*495ae853SAndroid Build Coastguard Worker         case PRED_L0:
1600*495ae853SAndroid Build Coastguard Worker             if ( (ps_proc->ps_pu->s_me_info[0].s_mv.i2_mvx == ps_proc->ps_skip_mv[0].s_mv.i2_mvx)
1601*495ae853SAndroid Build Coastguard Worker               && (ps_proc->ps_pu->s_me_info[0].s_mv.i2_mvy == ps_proc->ps_skip_mv[0].s_mv.i2_mvy)
1602*495ae853SAndroid Build Coastguard Worker               && (i4_mode_avail == 0x1))
1603*495ae853SAndroid Build Coastguard Worker             {
1604*495ae853SAndroid Build Coastguard Worker                 return 1;
1605*495ae853SAndroid Build Coastguard Worker             }
1606*495ae853SAndroid Build Coastguard Worker             break;
1607*495ae853SAndroid Build Coastguard Worker 
1608*495ae853SAndroid Build Coastguard Worker         case PRED_L1:
1609*495ae853SAndroid Build Coastguard Worker             if (  (ps_proc->ps_pu->s_me_info[1].s_mv.i2_mvx == ps_proc->ps_skip_mv[1].s_mv.i2_mvx)
1610*495ae853SAndroid Build Coastguard Worker                && (ps_proc->ps_pu->s_me_info[1].s_mv.i2_mvy == ps_proc->ps_skip_mv[1].s_mv.i2_mvy)
1611*495ae853SAndroid Build Coastguard Worker                && (i4_mode_avail == 0x2))
1612*495ae853SAndroid Build Coastguard Worker             {
1613*495ae853SAndroid Build Coastguard Worker                 return 1;
1614*495ae853SAndroid Build Coastguard Worker             }
1615*495ae853SAndroid Build Coastguard Worker             break;
1616*495ae853SAndroid Build Coastguard Worker     }
1617*495ae853SAndroid Build Coastguard Worker 
1618*495ae853SAndroid Build Coastguard Worker     return 0;
1619*495ae853SAndroid Build Coastguard Worker }
1620*495ae853SAndroid Build Coastguard Worker 
1621*495ae853SAndroid Build Coastguard Worker 
1622*495ae853SAndroid Build Coastguard Worker /**
1623*495ae853SAndroid Build Coastguard Worker *******************************************************************************
1624*495ae853SAndroid Build Coastguard Worker *
1625*495ae853SAndroid Build Coastguard Worker * @brief This function computes the best motion vector among the tentative mv
1626*495ae853SAndroid Build Coastguard Worker * candidates chosen.
1627*495ae853SAndroid Build Coastguard Worker *
1628*495ae853SAndroid Build Coastguard Worker * @par Description:
1629*495ae853SAndroid Build Coastguard Worker *  This function determines the position in the search window at which the motion
1630*495ae853SAndroid Build Coastguard Worker *  estimation should begin in order to minimise the number of search iterations.
1631*495ae853SAndroid Build Coastguard Worker *
1632*495ae853SAndroid Build Coastguard Worker * @param[in] ps_me_ctxt
1633*495ae853SAndroid Build Coastguard Worker *  pointer to me context
1634*495ae853SAndroid Build Coastguard Worker *
1635*495ae853SAndroid Build Coastguard Worker * @param[in] ps_proc
1636*495ae853SAndroid Build Coastguard Worker *  process context
1637*495ae853SAndroid Build Coastguard Worker *
1638*495ae853SAndroid Build Coastguard Worker * @param[in] ps_mb_ctxt_bi
1639*495ae853SAndroid Build Coastguard Worker *  pointer to current mb partition ctxt with respect to ME
1640*495ae853SAndroid Build Coastguard Worker *
1641*495ae853SAndroid Build Coastguard Worker * @returns  mv pair & corresponding distortion and cost
1642*495ae853SAndroid Build Coastguard Worker *
1643*495ae853SAndroid Build Coastguard Worker * @remarks Currently only 4 search candiates are supported
1644*495ae853SAndroid Build Coastguard Worker *
1645*495ae853SAndroid Build Coastguard Worker *******************************************************************************
1646*495ae853SAndroid Build Coastguard Worker */
ih264e_evaluate_bipred(me_ctxt_t * ps_me_ctxt,process_ctxt_t * ps_proc,mb_part_ctxt * ps_mb_ctxt_bi)1647*495ae853SAndroid Build Coastguard Worker void ih264e_evaluate_bipred(me_ctxt_t *ps_me_ctxt,
1648*495ae853SAndroid Build Coastguard Worker                             process_ctxt_t *ps_proc,
1649*495ae853SAndroid Build Coastguard Worker                             mb_part_ctxt *ps_mb_ctxt_bi)
1650*495ae853SAndroid Build Coastguard Worker {
1651*495ae853SAndroid Build Coastguard Worker 
1652*495ae853SAndroid Build Coastguard Worker     UWORD32 i, u4_fast_sad;
1653*495ae853SAndroid Build Coastguard Worker 
1654*495ae853SAndroid Build Coastguard Worker     WORD32 i4_dest_buff;
1655*495ae853SAndroid Build Coastguard Worker 
1656*495ae853SAndroid Build Coastguard Worker     mv_t *ps_l0_pred_mv, *ps_l1_pred_mv, s_l0_mv, s_l1_mv;
1657*495ae853SAndroid Build Coastguard Worker 
1658*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_ref_mb_l0, *pu1_ref_mb_l1;
1659*495ae853SAndroid Build Coastguard Worker 
1660*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_dst_buf;
1661*495ae853SAndroid Build Coastguard Worker 
1662*495ae853SAndroid Build Coastguard Worker     WORD32 i4_ref_l0_stride, i4_ref_l1_stride;
1663*495ae853SAndroid Build Coastguard Worker 
1664*495ae853SAndroid Build Coastguard Worker     WORD32 i4_mb_distortion, i4_mb_cost;
1665*495ae853SAndroid Build Coastguard Worker 
1666*495ae853SAndroid Build Coastguard Worker     u4_fast_sad = ps_me_ctxt->u4_enable_fast_sad;
1667*495ae853SAndroid Build Coastguard Worker 
1668*495ae853SAndroid Build Coastguard Worker     i4_dest_buff = 0;
1669*495ae853SAndroid Build Coastguard Worker 
1670*495ae853SAndroid Build Coastguard Worker     for (i = 0; i < ps_me_ctxt->u4_num_candidates[PRED_BI]; i += 2)
1671*495ae853SAndroid Build Coastguard Worker     {
1672*495ae853SAndroid Build Coastguard Worker         pu1_dst_buf = ps_me_ctxt->apu1_subpel_buffs[i4_dest_buff];
1673*495ae853SAndroid Build Coastguard Worker 
1674*495ae853SAndroid Build Coastguard Worker         s_l0_mv.i2_mvx = ps_me_ctxt->as_mv_init_search[PRED_BI][i].i2_mvx >> 2;
1675*495ae853SAndroid Build Coastguard Worker         s_l0_mv.i2_mvy = ps_me_ctxt->as_mv_init_search[PRED_BI][i].i2_mvy >> 2;
1676*495ae853SAndroid Build Coastguard Worker         s_l1_mv.i2_mvx = ps_me_ctxt->as_mv_init_search[PRED_BI][i + 1].i2_mvx >> 2;
1677*495ae853SAndroid Build Coastguard Worker         s_l1_mv.i2_mvy = ps_me_ctxt->as_mv_init_search[PRED_BI][i + 1].i2_mvy >> 2;
1678*495ae853SAndroid Build Coastguard Worker 
1679*495ae853SAndroid Build Coastguard Worker         ps_l0_pred_mv = &ps_proc->ps_pred_mv[PRED_L0].s_mv;
1680*495ae853SAndroid Build Coastguard Worker         ps_l1_pred_mv = &ps_proc->ps_pred_mv[PRED_L1].s_mv;
1681*495ae853SAndroid Build Coastguard Worker 
1682*495ae853SAndroid Build Coastguard Worker         if ((ps_me_ctxt->as_mv_init_search[PRED_BI][i].i2_mvx & 0x3)||
1683*495ae853SAndroid Build Coastguard Worker                         (ps_me_ctxt->as_mv_init_search[PRED_BI][i].i2_mvy & 0x3))
1684*495ae853SAndroid Build Coastguard Worker         {
1685*495ae853SAndroid Build Coastguard Worker             pu1_ref_mb_l0 = ps_me_ctxt->as_mb_part[PRED_L0].pu1_best_hpel_buf;
1686*495ae853SAndroid Build Coastguard Worker             i4_ref_l0_stride = ps_me_ctxt->u4_subpel_buf_strd;
1687*495ae853SAndroid Build Coastguard Worker         }
1688*495ae853SAndroid Build Coastguard Worker         else
1689*495ae853SAndroid Build Coastguard Worker         {
1690*495ae853SAndroid Build Coastguard Worker             pu1_ref_mb_l0 = ps_me_ctxt->apu1_ref_buf_luma[PRED_L0] + (s_l0_mv.i2_mvx) + ((s_l0_mv.i2_mvy) * ps_me_ctxt->i4_rec_strd);
1691*495ae853SAndroid Build Coastguard Worker             i4_ref_l0_stride = ps_me_ctxt->i4_rec_strd;
1692*495ae853SAndroid Build Coastguard Worker         }
1693*495ae853SAndroid Build Coastguard Worker 
1694*495ae853SAndroid Build Coastguard Worker 
1695*495ae853SAndroid Build Coastguard Worker         if ((ps_me_ctxt->as_mv_init_search[PRED_BI][i + 1].i2_mvx & 0x3) ||
1696*495ae853SAndroid Build Coastguard Worker                         (ps_me_ctxt->as_mv_init_search[PRED_BI][i + 1].i2_mvy & 0x3))
1697*495ae853SAndroid Build Coastguard Worker         {
1698*495ae853SAndroid Build Coastguard Worker             pu1_ref_mb_l1 = ps_me_ctxt->as_mb_part[PRED_L1].pu1_best_hpel_buf;
1699*495ae853SAndroid Build Coastguard Worker             i4_ref_l1_stride = ps_me_ctxt->u4_subpel_buf_strd;
1700*495ae853SAndroid Build Coastguard Worker         }
1701*495ae853SAndroid Build Coastguard Worker         else
1702*495ae853SAndroid Build Coastguard Worker         {
1703*495ae853SAndroid Build Coastguard Worker             pu1_ref_mb_l1 = ps_me_ctxt->apu1_ref_buf_luma[PRED_L1] + (s_l1_mv.i2_mvx) + ((s_l1_mv.i2_mvy) * ps_me_ctxt->i4_rec_strd);
1704*495ae853SAndroid Build Coastguard Worker             i4_ref_l1_stride = ps_me_ctxt->i4_rec_strd;
1705*495ae853SAndroid Build Coastguard Worker         }
1706*495ae853SAndroid Build Coastguard Worker 
1707*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_codec->pf_inter_pred_luma_bilinear(
1708*495ae853SAndroid Build Coastguard Worker                         pu1_ref_mb_l0, pu1_ref_mb_l1, pu1_dst_buf,
1709*495ae853SAndroid Build Coastguard Worker                         i4_ref_l0_stride, i4_ref_l1_stride,
1710*495ae853SAndroid Build Coastguard Worker                         ps_me_ctxt->u4_subpel_buf_strd, MB_SIZE, MB_SIZE);
1711*495ae853SAndroid Build Coastguard Worker 
1712*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->pf_ime_compute_sad_16x16[u4_fast_sad](
1713*495ae853SAndroid Build Coastguard Worker                         ps_me_ctxt->pu1_src_buf_luma, pu1_dst_buf,
1714*495ae853SAndroid Build Coastguard Worker                         ps_me_ctxt->i4_src_strd, ps_me_ctxt->u4_subpel_buf_strd,
1715*495ae853SAndroid Build Coastguard Worker                         INT_MAX, &i4_mb_distortion);
1716*495ae853SAndroid Build Coastguard Worker 
1717*495ae853SAndroid Build Coastguard Worker         /* compute cost */
1718*495ae853SAndroid Build Coastguard Worker         i4_mb_cost =  ps_me_ctxt->pu1_mv_bits[ps_me_ctxt->as_mv_init_search[PRED_BI][i].i2_mvx - ps_l0_pred_mv->i2_mvx];
1719*495ae853SAndroid Build Coastguard Worker         i4_mb_cost += ps_me_ctxt->pu1_mv_bits[ps_me_ctxt->as_mv_init_search[PRED_BI][i].i2_mvy - ps_l0_pred_mv->i2_mvy];
1720*495ae853SAndroid Build Coastguard Worker         i4_mb_cost += ps_me_ctxt->pu1_mv_bits[ps_me_ctxt->as_mv_init_search[PRED_BI][i + 1].i2_mvx - ps_l1_pred_mv->i2_mvx];
1721*495ae853SAndroid Build Coastguard Worker         i4_mb_cost += ps_me_ctxt->pu1_mv_bits[ps_me_ctxt->as_mv_init_search[PRED_BI][i + 1].i2_mvy - ps_l1_pred_mv->i2_mvy];
1722*495ae853SAndroid Build Coastguard Worker 
1723*495ae853SAndroid Build Coastguard Worker         i4_mb_cost -= (ps_me_ctxt->i4_skip_bias[BSLICE]) * (ps_me_ctxt->i4_skip_type == PRED_BI) * (i == 0);
1724*495ae853SAndroid Build Coastguard Worker 
1725*495ae853SAndroid Build Coastguard Worker 
1726*495ae853SAndroid Build Coastguard Worker         i4_mb_cost *= ps_me_ctxt->u4_lambda_motion;
1727*495ae853SAndroid Build Coastguard Worker         i4_mb_cost += i4_mb_distortion;
1728*495ae853SAndroid Build Coastguard Worker 
1729*495ae853SAndroid Build Coastguard Worker         if (i4_mb_cost < ps_mb_ctxt_bi->i4_mb_cost)
1730*495ae853SAndroid Build Coastguard Worker         {
1731*495ae853SAndroid Build Coastguard Worker             ps_mb_ctxt_bi->i4_srch_pos_idx = (i>>1);
1732*495ae853SAndroid Build Coastguard Worker             ps_mb_ctxt_bi->i4_mb_cost = i4_mb_cost;
1733*495ae853SAndroid Build Coastguard Worker             ps_mb_ctxt_bi->i4_mb_distortion = i4_mb_distortion;
1734*495ae853SAndroid Build Coastguard Worker             ps_mb_ctxt_bi->pu1_best_hpel_buf = pu1_dst_buf;
1735*495ae853SAndroid Build Coastguard Worker             i4_dest_buff = (i4_dest_buff + 1) % 2;
1736*495ae853SAndroid Build Coastguard Worker         }
1737*495ae853SAndroid Build Coastguard Worker     }
1738*495ae853SAndroid Build Coastguard Worker 
1739*495ae853SAndroid Build Coastguard Worker }
1740*495ae853SAndroid Build Coastguard Worker 
1741*495ae853SAndroid Build Coastguard Worker /**
1742*495ae853SAndroid Build Coastguard Worker *******************************************************************************
1743*495ae853SAndroid Build Coastguard Worker *
1744*495ae853SAndroid Build Coastguard Worker * @brief This function performs motion estimation for the current mb
1745*495ae853SAndroid Build Coastguard Worker *
1746*495ae853SAndroid Build Coastguard Worker * @par Description:
1747*495ae853SAndroid Build Coastguard Worker *  The current mb is compared with a list of mb's in the reference frame for
1748*495ae853SAndroid Build Coastguard Worker *  least cost. The mb that offers least cost is chosen as predicted mb and the
1749*495ae853SAndroid Build Coastguard Worker *  displacement of the predicted mb from index location of the current mb is
1750*495ae853SAndroid Build Coastguard Worker *  signaled as mv. The list of the mb's that are chosen in the reference frame
1751*495ae853SAndroid Build Coastguard Worker *  are dependent on the speed of the ME configured.
1752*495ae853SAndroid Build Coastguard Worker *
1753*495ae853SAndroid Build Coastguard Worker * @param[in] ps_proc
1754*495ae853SAndroid Build Coastguard Worker *  Process context corresponding to the job
1755*495ae853SAndroid Build Coastguard Worker *
1756*495ae853SAndroid Build Coastguard Worker * @returns  motion vector of the pred mb, sad, cost.
1757*495ae853SAndroid Build Coastguard Worker *
1758*495ae853SAndroid Build Coastguard Worker * @remarks none
1759*495ae853SAndroid Build Coastguard Worker *
1760*495ae853SAndroid Build Coastguard Worker *******************************************************************************
1761*495ae853SAndroid Build Coastguard Worker */
ih264e_compute_me_multi_reflist(process_ctxt_t * ps_proc)1762*495ae853SAndroid Build Coastguard Worker void ih264e_compute_me_multi_reflist(process_ctxt_t *ps_proc)
1763*495ae853SAndroid Build Coastguard Worker {
1764*495ae853SAndroid Build Coastguard Worker     /* me ctxt */
1765*495ae853SAndroid Build Coastguard Worker     me_ctxt_t *ps_me_ctxt = &ps_proc->s_me_ctxt;
1766*495ae853SAndroid Build Coastguard Worker 
1767*495ae853SAndroid Build Coastguard Worker     /* codec context */
1768*495ae853SAndroid Build Coastguard Worker     codec_t *ps_codec = ps_proc->ps_codec;
1769*495ae853SAndroid Build Coastguard Worker 
1770*495ae853SAndroid Build Coastguard Worker     /* Temp variables for looping over ref lists */
1771*495ae853SAndroid Build Coastguard Worker     WORD32 i4_reflist, i4_max_reflist;
1772*495ae853SAndroid Build Coastguard Worker 
1773*495ae853SAndroid Build Coastguard Worker     /* recon stride */
1774*495ae853SAndroid Build Coastguard Worker     WORD32 i4_rec_strd = ps_proc->i4_rec_strd;
1775*495ae853SAndroid Build Coastguard Worker 
1776*495ae853SAndroid Build Coastguard Worker     /* source buffer for halp pel generation functions */
1777*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_hpel_src;
1778*495ae853SAndroid Build Coastguard Worker 
1779*495ae853SAndroid Build Coastguard Worker     /* quantization parameters */
1780*495ae853SAndroid Build Coastguard Worker     quant_params_t *ps_qp_params = ps_proc->ps_qp_params[0];
1781*495ae853SAndroid Build Coastguard Worker 
1782*495ae853SAndroid Build Coastguard Worker     /* Mb part ctxts for SKIP */
1783*495ae853SAndroid Build Coastguard Worker     mb_part_ctxt as_skip_mbpart[2];
1784*495ae853SAndroid Build Coastguard Worker 
1785*495ae853SAndroid Build Coastguard Worker     /* Sad therholds */
1786*495ae853SAndroid Build Coastguard Worker     ps_me_ctxt->pu2_sad_thrsh = ps_qp_params->pu2_sad_thrsh;
1787*495ae853SAndroid Build Coastguard Worker 
1788*495ae853SAndroid Build Coastguard Worker     {
1789*495ae853SAndroid Build Coastguard Worker         WORD32 rows_above, rows_below, columns_left, columns_right;
1790*495ae853SAndroid Build Coastguard Worker 
1791*495ae853SAndroid Build Coastguard Worker         /* During evaluation for motion vectors do not search through padded regions */
1792*495ae853SAndroid Build Coastguard Worker         /* Obtain number of rows and columns that are effective for computing for me evaluation */
1793*495ae853SAndroid Build Coastguard Worker         rows_above = MB_SIZE + ps_proc->i4_mb_y * MB_SIZE;
1794*495ae853SAndroid Build Coastguard Worker         rows_below = (ps_proc->i4_ht_mbs - ps_proc->i4_mb_y) * MB_SIZE;
1795*495ae853SAndroid Build Coastguard Worker         columns_left = MB_SIZE + ps_proc->i4_mb_x * MB_SIZE;
1796*495ae853SAndroid Build Coastguard Worker         columns_right = (ps_proc->i4_wd_mbs - ps_proc->i4_mb_x) * MB_SIZE;
1797*495ae853SAndroid Build Coastguard Worker 
1798*495ae853SAndroid Build Coastguard Worker         /* init srch range */
1799*495ae853SAndroid Build Coastguard Worker         /* NOTE : For now, lets limit the search range by DEFAULT_MAX_SRCH_RANGE_X / 2
1800*495ae853SAndroid Build Coastguard Worker          * on all sides.
1801*495ae853SAndroid Build Coastguard Worker          */
1802*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->i4_srch_range_w = -MIN(columns_left, DEFAULT_MAX_SRCH_RANGE_X >> 1);
1803*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->i4_srch_range_e = MIN(columns_right, DEFAULT_MAX_SRCH_RANGE_X >> 1);
1804*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->i4_srch_range_n = -MIN(rows_above, DEFAULT_MAX_SRCH_RANGE_Y >> 1);
1805*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->i4_srch_range_s = MIN(rows_below, DEFAULT_MAX_SRCH_RANGE_Y >> 1);
1806*495ae853SAndroid Build Coastguard Worker 
1807*495ae853SAndroid Build Coastguard Worker         /* this is to facilitate fast sub pel computation with minimal loads */
1808*495ae853SAndroid Build Coastguard Worker         if (ps_me_ctxt->u4_enable_hpel)
1809*495ae853SAndroid Build Coastguard Worker         {
1810*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->i4_srch_range_w += 1;
1811*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->i4_srch_range_e -= 1;
1812*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->i4_srch_range_n += 1;
1813*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->i4_srch_range_s -= 1;
1814*495ae853SAndroid Build Coastguard Worker         }
1815*495ae853SAndroid Build Coastguard Worker     }
1816*495ae853SAndroid Build Coastguard Worker 
1817*495ae853SAndroid Build Coastguard Worker     /* Compute ME and store the MVs */
1818*495ae853SAndroid Build Coastguard Worker     {
1819*495ae853SAndroid Build Coastguard Worker         /***********************************************************************
1820*495ae853SAndroid Build Coastguard Worker          * Compute ME for lists L0 and L1
1821*495ae853SAndroid Build Coastguard Worker          *  For L0 -> L0 skip + L0
1822*495ae853SAndroid Build Coastguard Worker          *  for L1 -> L0 skip + L0 + L1 skip + L1
1823*495ae853SAndroid Build Coastguard Worker          ***********************************************************************/
1824*495ae853SAndroid Build Coastguard Worker         i4_max_reflist = (ps_proc->i4_slice_type == PSLICE) ? PRED_L0 : PRED_L1;
1825*495ae853SAndroid Build Coastguard Worker 
1826*495ae853SAndroid Build Coastguard Worker         /* Init SATQD for the current list */
1827*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->u4_min_sad_reached  = 0;
1828*495ae853SAndroid Build Coastguard Worker         ps_me_ctxt->i4_min_sad = ps_proc->ps_cur_mb->u4_min_sad;
1829*495ae853SAndroid Build Coastguard Worker 
1830*495ae853SAndroid Build Coastguard Worker         for (i4_reflist = PRED_L0; i4_reflist <= i4_max_reflist; i4_reflist++)
1831*495ae853SAndroid Build Coastguard Worker         {
1832*495ae853SAndroid Build Coastguard Worker 
1833*495ae853SAndroid Build Coastguard Worker             /* Get the seed motion vector candidates                    */
1834*495ae853SAndroid Build Coastguard Worker             ih264e_get_search_candidates(ps_proc, ps_me_ctxt, i4_reflist);
1835*495ae853SAndroid Build Coastguard Worker 
1836*495ae853SAndroid Build Coastguard Worker             /* ****************************************************************
1837*495ae853SAndroid Build Coastguard Worker              *Evaluate the SKIP for current list
1838*495ae853SAndroid Build Coastguard Worker              * ****************************************************************/
1839*495ae853SAndroid Build Coastguard Worker             as_skip_mbpart[i4_reflist].s_mv_curr.i2_mvx = 0;
1840*495ae853SAndroid Build Coastguard Worker             as_skip_mbpart[i4_reflist].s_mv_curr.i2_mvy = 0;
1841*495ae853SAndroid Build Coastguard Worker             as_skip_mbpart[i4_reflist].i4_mb_cost = INT_MAX;
1842*495ae853SAndroid Build Coastguard Worker             as_skip_mbpart[i4_reflist].i4_mb_distortion = INT_MAX;
1843*495ae853SAndroid Build Coastguard Worker 
1844*495ae853SAndroid Build Coastguard Worker             if (ps_me_ctxt->i4_skip_type == i4_reflist)
1845*495ae853SAndroid Build Coastguard Worker             {
1846*495ae853SAndroid Build Coastguard Worker                 ime_compute_skip_cost( ps_me_ctxt,
1847*495ae853SAndroid Build Coastguard Worker                                        (ime_mv_t *)(&ps_proc->ps_skip_mv[i4_reflist].s_mv),
1848*495ae853SAndroid Build Coastguard Worker                                        &as_skip_mbpart[i4_reflist],
1849*495ae853SAndroid Build Coastguard Worker                                        ps_proc->ps_codec->s_cfg.u4_enable_satqd,
1850*495ae853SAndroid Build Coastguard Worker                                        i4_reflist,
1851*495ae853SAndroid Build Coastguard Worker                                        (ps_proc->i4_slice_type == BSLICE) );
1852*495ae853SAndroid Build Coastguard Worker             }
1853*495ae853SAndroid Build Coastguard Worker 
1854*495ae853SAndroid Build Coastguard Worker             as_skip_mbpart[i4_reflist].s_mv_curr.i2_mvx <<= 2;
1855*495ae853SAndroid Build Coastguard Worker             as_skip_mbpart[i4_reflist].s_mv_curr.i2_mvy <<= 2;
1856*495ae853SAndroid Build Coastguard Worker 
1857*495ae853SAndroid Build Coastguard Worker             /******************************************************************
1858*495ae853SAndroid Build Coastguard Worker              * Evaluate ME For current list
1859*495ae853SAndroid Build Coastguard Worker              *****************************************************************/
1860*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mb_part[i4_reflist].s_mv_curr.i2_mvx = 0;
1861*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mb_part[i4_reflist].s_mv_curr.i2_mvy = 0;
1862*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mb_part[i4_reflist].i4_mb_cost = INT_MAX;
1863*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mb_part[i4_reflist].i4_mb_distortion = INT_MAX;
1864*495ae853SAndroid Build Coastguard Worker 
1865*495ae853SAndroid Build Coastguard Worker             /* Init Hpel */
1866*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mb_part[i4_reflist].pu1_best_hpel_buf = NULL;
1867*495ae853SAndroid Build Coastguard Worker 
1868*495ae853SAndroid Build Coastguard Worker             /* In case we found out the minimum SAD, exit the ME eval */
1869*495ae853SAndroid Build Coastguard Worker             if (ps_me_ctxt->u4_min_sad_reached)
1870*495ae853SAndroid Build Coastguard Worker             {
1871*495ae853SAndroid Build Coastguard Worker                 i4_max_reflist = i4_reflist;
1872*495ae853SAndroid Build Coastguard Worker                 break;
1873*495ae853SAndroid Build Coastguard Worker             }
1874*495ae853SAndroid Build Coastguard Worker 
1875*495ae853SAndroid Build Coastguard Worker 
1876*495ae853SAndroid Build Coastguard Worker             /* Evaluate search candidates for initial mv pt */
1877*495ae853SAndroid Build Coastguard Worker             ime_evaluate_init_srchposn_16x16(ps_me_ctxt, i4_reflist);
1878*495ae853SAndroid Build Coastguard Worker 
1879*495ae853SAndroid Build Coastguard Worker             /********************************************************************/
1880*495ae853SAndroid Build Coastguard Worker             /*                  full pel motion estimation                      */
1881*495ae853SAndroid Build Coastguard Worker             /********************************************************************/
1882*495ae853SAndroid Build Coastguard Worker             ime_full_pel_motion_estimation_16x16(ps_me_ctxt, i4_reflist);
1883*495ae853SAndroid Build Coastguard Worker 
1884*495ae853SAndroid Build Coastguard Worker             DEBUG_MV_HISTOGRAM_ADD((ps_me_ctxt->as_mb_part[i4_reflist].s_mv_curr.i2_mvx >> 2),
1885*495ae853SAndroid Build Coastguard Worker                                    (ps_me_ctxt->as_mb_part[i4_reflist].s_mv_curr.i2_mvy >> 2));
1886*495ae853SAndroid Build Coastguard Worker 
1887*495ae853SAndroid Build Coastguard Worker             DEBUG_SAD_HISTOGRAM_ADD(ps_me_ctxt->as_mb_part[i4_reflist].i4_mb_distortion, 1);
1888*495ae853SAndroid Build Coastguard Worker 
1889*495ae853SAndroid Build Coastguard Worker             /* Scale the MV to qpel resolution */
1890*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mb_part[i4_reflist].s_mv_curr.i2_mvx <<= 2;
1891*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mb_part[i4_reflist].s_mv_curr.i2_mvy <<= 2;
1892*495ae853SAndroid Build Coastguard Worker 
1893*495ae853SAndroid Build Coastguard Worker             if (ps_me_ctxt->u4_enable_hpel)
1894*495ae853SAndroid Build Coastguard Worker             {
1895*495ae853SAndroid Build Coastguard Worker                 /* moving src pointer to the converged motion vector location */
1896*495ae853SAndroid Build Coastguard Worker                 pu1_hpel_src =   ps_me_ctxt->apu1_ref_buf_luma[i4_reflist]
1897*495ae853SAndroid Build Coastguard Worker                                + (ps_me_ctxt->as_mb_part[i4_reflist].s_mv_curr.i2_mvx >> 2)
1898*495ae853SAndroid Build Coastguard Worker                                + ((ps_me_ctxt->as_mb_part[i4_reflist].s_mv_curr.i2_mvy >> 2)* i4_rec_strd);
1899*495ae853SAndroid Build Coastguard Worker 
1900*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->apu1_subpel_buffs[0] = ps_proc->apu1_subpel_buffs[0];
1901*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->apu1_subpel_buffs[1] = ps_proc->apu1_subpel_buffs[1];
1902*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->apu1_subpel_buffs[2] = ps_proc->apu1_subpel_buffs[2];
1903*495ae853SAndroid Build Coastguard Worker 
1904*495ae853SAndroid Build Coastguard Worker                 /* Init the search position to an invalid number */
1905*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->as_mb_part[i4_reflist].i4_srch_pos_idx = 3;
1906*495ae853SAndroid Build Coastguard Worker 
1907*495ae853SAndroid Build Coastguard Worker                 /* Incase a buffer is still in use by L0, replace it with spare buff */
1908*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->apu1_subpel_buffs[ps_me_ctxt->as_mb_part[PRED_L0].i4_srch_pos_idx] =
1909*495ae853SAndroid Build Coastguard Worker                                 ps_proc->apu1_subpel_buffs[3];
1910*495ae853SAndroid Build Coastguard Worker 
1911*495ae853SAndroid Build Coastguard Worker 
1912*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->u4_subpel_buf_strd = HP_BUFF_WD;
1913*495ae853SAndroid Build Coastguard Worker 
1914*495ae853SAndroid Build Coastguard Worker                 /* half  pel search is done for both sides of full pel,
1915*495ae853SAndroid Build Coastguard Worker                  * hence half_x of width x height = 17x16 is created
1916*495ae853SAndroid Build Coastguard Worker                  * starting from left half_x of converged full pel */
1917*495ae853SAndroid Build Coastguard Worker                 pu1_hpel_src -= 1;
1918*495ae853SAndroid Build Coastguard Worker 
1919*495ae853SAndroid Build Coastguard Worker                 /* computing half_x */
1920*495ae853SAndroid Build Coastguard Worker                 ps_codec->pf_ih264e_sixtapfilter_horz(pu1_hpel_src,
1921*495ae853SAndroid Build Coastguard Worker                                                       ps_me_ctxt->apu1_subpel_buffs[0],
1922*495ae853SAndroid Build Coastguard Worker                                                       i4_rec_strd,
1923*495ae853SAndroid Build Coastguard Worker                                                       ps_me_ctxt->u4_subpel_buf_strd);
1924*495ae853SAndroid Build Coastguard Worker 
1925*495ae853SAndroid Build Coastguard Worker                 /*
1926*495ae853SAndroid Build Coastguard Worker                  * Halfpel search is done for both sides of full pel,
1927*495ae853SAndroid Build Coastguard Worker                  * hence half_y of width x height = 16x17 is created
1928*495ae853SAndroid Build Coastguard Worker                  * starting from top half_y of converged full pel
1929*495ae853SAndroid Build Coastguard Worker                  * for half_xy top_left is required
1930*495ae853SAndroid Build Coastguard Worker                  * hence it starts from pu1_hpel_src = full_pel_converged_point - i4_rec_strd - 1
1931*495ae853SAndroid Build Coastguard Worker                  */
1932*495ae853SAndroid Build Coastguard Worker                 pu1_hpel_src -= i4_rec_strd;
1933*495ae853SAndroid Build Coastguard Worker 
1934*495ae853SAndroid Build Coastguard Worker                 /* computing half_y and half_xy */
1935*495ae853SAndroid Build Coastguard Worker                 ps_codec->pf_ih264e_sixtap_filter_2dvh_vert(
1936*495ae853SAndroid Build Coastguard Worker                                 pu1_hpel_src, ps_me_ctxt->apu1_subpel_buffs[1],
1937*495ae853SAndroid Build Coastguard Worker                                 ps_me_ctxt->apu1_subpel_buffs[2], i4_rec_strd,
1938*495ae853SAndroid Build Coastguard Worker                                 ps_me_ctxt->u4_subpel_buf_strd, ps_proc->ai16_pred1 + 3,
1939*495ae853SAndroid Build Coastguard Worker                                 ps_me_ctxt->u4_subpel_buf_strd);
1940*495ae853SAndroid Build Coastguard Worker 
1941*495ae853SAndroid Build Coastguard Worker                 ime_sub_pel_motion_estimation_16x16(ps_me_ctxt, i4_reflist);
1942*495ae853SAndroid Build Coastguard Worker 
1943*495ae853SAndroid Build Coastguard Worker             }
1944*495ae853SAndroid Build Coastguard Worker         }
1945*495ae853SAndroid Build Coastguard Worker 
1946*495ae853SAndroid Build Coastguard Worker         /***********************************************************************
1947*495ae853SAndroid Build Coastguard Worker          * If a particular skiip Mv is giving better sad, copy to the corresponding
1948*495ae853SAndroid Build Coastguard Worker          * MBPART
1949*495ae853SAndroid Build Coastguard Worker          * In B slices this loop should go only to PREDL1: If we found min sad
1950*495ae853SAndroid Build Coastguard Worker          * we will go to the skip ref list only
1951*495ae853SAndroid Build Coastguard Worker          * Have to find a way to make it without too much change or new vars
1952*495ae853SAndroid Build Coastguard Worker          **********************************************************************/
1953*495ae853SAndroid Build Coastguard Worker         for (i4_reflist = 0; i4_reflist <= i4_max_reflist; i4_reflist++)
1954*495ae853SAndroid Build Coastguard Worker         {
1955*495ae853SAndroid Build Coastguard Worker             if (as_skip_mbpart[i4_reflist].i4_mb_cost < ps_me_ctxt->as_mb_part[i4_reflist].i4_mb_cost)
1956*495ae853SAndroid Build Coastguard Worker             {
1957*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->as_mb_part[i4_reflist].i4_mb_cost = as_skip_mbpart[i4_reflist].i4_mb_cost;
1958*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->as_mb_part[i4_reflist].i4_mb_distortion = as_skip_mbpart[i4_reflist].i4_mb_distortion;
1959*495ae853SAndroid Build Coastguard Worker                 ps_me_ctxt->as_mb_part[i4_reflist].s_mv_curr = as_skip_mbpart[i4_reflist].s_mv_curr;
1960*495ae853SAndroid Build Coastguard Worker             }
1961*495ae853SAndroid Build Coastguard Worker         }
1962*495ae853SAndroid Build Coastguard Worker 
1963*495ae853SAndroid Build Coastguard Worker         /***********************************************************************
1964*495ae853SAndroid Build Coastguard Worker          * Compute ME for BI
1965*495ae853SAndroid Build Coastguard Worker          *  In case of BI we do ME for two candidates
1966*495ae853SAndroid Build Coastguard Worker          *   1) The best L0 and L1 Mvs
1967*495ae853SAndroid Build Coastguard Worker          *   2) Skip L0 and L1 MVs
1968*495ae853SAndroid Build Coastguard Worker          *
1969*495ae853SAndroid Build Coastguard Worker          *   TODO
1970*495ae853SAndroid Build Coastguard Worker          *   one of the search candidates is skip. Hence it may be duplicated
1971*495ae853SAndroid Build Coastguard Worker          ***********************************************************************/
1972*495ae853SAndroid Build Coastguard Worker         if (i4_max_reflist == PRED_L1 && ps_me_ctxt->u4_min_sad_reached == 0)
1973*495ae853SAndroid Build Coastguard Worker         {
1974*495ae853SAndroid Build Coastguard Worker             WORD32 i, j = 0;
1975*495ae853SAndroid Build Coastguard Worker             WORD32 l0_srch_pos_idx, l1_srch_pos_idx;
1976*495ae853SAndroid Build Coastguard Worker             WORD32 i4_l0_skip_mv_idx, i4_l1_skip_mv_idx;
1977*495ae853SAndroid Build Coastguard Worker 
1978*495ae853SAndroid Build Coastguard Worker             /* Get the free buffers */
1979*495ae853SAndroid Build Coastguard Worker             l0_srch_pos_idx = ps_me_ctxt->as_mb_part[PRED_L0].i4_srch_pos_idx;
1980*495ae853SAndroid Build Coastguard Worker             l1_srch_pos_idx = ps_me_ctxt->as_mb_part[PRED_L1].i4_srch_pos_idx;
1981*495ae853SAndroid Build Coastguard Worker 
1982*495ae853SAndroid Build Coastguard Worker             /* Search for the two free buffers in subpel list */
1983*495ae853SAndroid Build Coastguard Worker             for (i = 0; i < SUBPEL_BUFF_CNT; i++)
1984*495ae853SAndroid Build Coastguard Worker             {
1985*495ae853SAndroid Build Coastguard Worker                 if (i != l0_srch_pos_idx && i != l1_srch_pos_idx)
1986*495ae853SAndroid Build Coastguard Worker                 {
1987*495ae853SAndroid Build Coastguard Worker                     ps_me_ctxt->apu1_subpel_buffs[j] = ps_proc->apu1_subpel_buffs[i];
1988*495ae853SAndroid Build Coastguard Worker                     j++;
1989*495ae853SAndroid Build Coastguard Worker                 }
1990*495ae853SAndroid Build Coastguard Worker             }
1991*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->u4_subpel_buf_strd = HP_BUFF_WD;
1992*495ae853SAndroid Build Coastguard Worker 
1993*495ae853SAndroid Build Coastguard Worker             /* Copy the statial SKIP MV of each list */
1994*495ae853SAndroid Build Coastguard Worker             i4_l0_skip_mv_idx = ps_me_ctxt->u4_num_candidates[PRED_L0] - 2;
1995*495ae853SAndroid Build Coastguard Worker             i4_l1_skip_mv_idx = ps_me_ctxt->u4_num_candidates[PRED_L1] - 2;
1996*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mv_init_search[PRED_BI][0].i2_mvx = ps_me_ctxt->as_mv_init_search[PRED_L0][i4_l0_skip_mv_idx].i2_mvx << 2;
1997*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mv_init_search[PRED_BI][0].i2_mvy = ps_me_ctxt->as_mv_init_search[PRED_L0][i4_l0_skip_mv_idx].i2_mvy << 2;
1998*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mv_init_search[PRED_BI][1].i2_mvx = ps_me_ctxt->as_mv_init_search[PRED_L1][i4_l1_skip_mv_idx].i2_mvx << 2;
1999*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mv_init_search[PRED_BI][1].i2_mvy = ps_me_ctxt->as_mv_init_search[PRED_L1][i4_l1_skip_mv_idx].i2_mvy << 2;
2000*495ae853SAndroid Build Coastguard Worker 
2001*495ae853SAndroid Build Coastguard Worker             /* Copy the SKIP MV temporal of each list */
2002*495ae853SAndroid Build Coastguard Worker             i4_l0_skip_mv_idx++;
2003*495ae853SAndroid Build Coastguard Worker             i4_l1_skip_mv_idx++;
2004*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mv_init_search[PRED_BI][2].i2_mvx = ps_me_ctxt->as_mv_init_search[PRED_L0][i4_l0_skip_mv_idx].i2_mvx << 2;
2005*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mv_init_search[PRED_BI][2].i2_mvy = ps_me_ctxt->as_mv_init_search[PRED_L0][i4_l0_skip_mv_idx].i2_mvy << 2;
2006*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mv_init_search[PRED_BI][3].i2_mvx = ps_me_ctxt->as_mv_init_search[PRED_L1][i4_l1_skip_mv_idx].i2_mvx << 2;
2007*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mv_init_search[PRED_BI][3].i2_mvy = ps_me_ctxt->as_mv_init_search[PRED_L1][i4_l1_skip_mv_idx].i2_mvy << 2;
2008*495ae853SAndroid Build Coastguard Worker 
2009*495ae853SAndroid Build Coastguard Worker             /* Copy the best MV after ME */
2010*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mv_init_search[PRED_BI][4] = ps_me_ctxt->as_mb_part[PRED_L0].s_mv_curr;
2011*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mv_init_search[PRED_BI][5] = ps_me_ctxt->as_mb_part[PRED_L1].s_mv_curr;
2012*495ae853SAndroid Build Coastguard Worker 
2013*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->u4_num_candidates[PRED_BI] = 6;
2014*495ae853SAndroid Build Coastguard Worker 
2015*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mb_part[PRED_BI].i4_mb_cost = INT_MAX;
2016*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mb_part[PRED_BI].i4_mb_distortion = INT_MAX;
2017*495ae853SAndroid Build Coastguard Worker 
2018*495ae853SAndroid Build Coastguard Worker             ih264e_evaluate_bipred(ps_me_ctxt, ps_proc,
2019*495ae853SAndroid Build Coastguard Worker                                    &ps_me_ctxt->as_mb_part[PRED_BI]);
2020*495ae853SAndroid Build Coastguard Worker 
2021*495ae853SAndroid Build Coastguard Worker             i4_max_reflist = PRED_BI;
2022*495ae853SAndroid Build Coastguard Worker         }
2023*495ae853SAndroid Build Coastguard Worker 
2024*495ae853SAndroid Build Coastguard Worker         /**********************************************************************
2025*495ae853SAndroid Build Coastguard Worker          * Now get the minimum of MB part sads by searching over all ref lists
2026*495ae853SAndroid Build Coastguard Worker          **********************************************************************/
2027*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_pu->b2_pred_mode = 0x3;
2028*495ae853SAndroid Build Coastguard Worker 
2029*495ae853SAndroid Build Coastguard Worker         for (i4_reflist = 0; i4_reflist <= i4_max_reflist; i4_reflist++)
2030*495ae853SAndroid Build Coastguard Worker         {
2031*495ae853SAndroid Build Coastguard Worker             if (ps_me_ctxt->as_mb_part[i4_reflist].i4_mb_cost < ps_proc->ps_cur_mb->i4_mb_cost)
2032*495ae853SAndroid Build Coastguard Worker             {
2033*495ae853SAndroid Build Coastguard Worker                 ps_proc->ps_cur_mb->i4_mb_cost = ps_me_ctxt->as_mb_part[i4_reflist].i4_mb_cost;
2034*495ae853SAndroid Build Coastguard Worker                 ps_proc->ps_cur_mb->i4_mb_distortion = ps_me_ctxt->as_mb_part[i4_reflist].i4_mb_distortion;
2035*495ae853SAndroid Build Coastguard Worker                 ps_proc->ps_cur_mb->u4_mb_type = (ps_proc->i4_slice_type == PSLICE) ? P16x16 : B16x16;
2036*495ae853SAndroid Build Coastguard Worker                 ps_proc->ps_pu->b2_pred_mode = i4_reflist ;
2037*495ae853SAndroid Build Coastguard Worker             }
2038*495ae853SAndroid Build Coastguard Worker         }
2039*495ae853SAndroid Build Coastguard Worker 
2040*495ae853SAndroid Build Coastguard Worker         /**********************************************************************
2041*495ae853SAndroid Build Coastguard Worker          * In case we have a BI MB, we have to copy the buffers and set proer MV's
2042*495ae853SAndroid Build Coastguard Worker          *  1)In case its BI, we need to get the best MVs given by BI and update
2043*495ae853SAndroid Build Coastguard Worker          *    to their corresponding MB part
2044*495ae853SAndroid Build Coastguard Worker          *  2)We also need to copy the buffer in which bipred buff is populated
2045*495ae853SAndroid Build Coastguard Worker          *
2046*495ae853SAndroid Build Coastguard Worker          *  Not that if we have
2047*495ae853SAndroid Build Coastguard Worker          **********************************************************************/
2048*495ae853SAndroid Build Coastguard Worker         if (ps_proc->ps_pu->b2_pred_mode == PRED_BI)
2049*495ae853SAndroid Build Coastguard Worker         {
2050*495ae853SAndroid Build Coastguard Worker             WORD32 i4_srch_pos = ps_me_ctxt->as_mb_part[PRED_BI].i4_srch_pos_idx;
2051*495ae853SAndroid Build Coastguard Worker             UWORD8 *pu1_bi_buf = ps_me_ctxt->as_mb_part[PRED_BI].pu1_best_hpel_buf;
2052*495ae853SAndroid Build Coastguard Worker 
2053*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mb_part[PRED_L0].s_mv_curr = ps_me_ctxt->as_mv_init_search[PRED_BI][i4_srch_pos << 1];
2054*495ae853SAndroid Build Coastguard Worker             ps_me_ctxt->as_mb_part[PRED_L1].s_mv_curr = ps_me_ctxt->as_mv_init_search[PRED_BI][(i4_srch_pos << 1) + 1];
2055*495ae853SAndroid Build Coastguard Worker 
2056*495ae853SAndroid Build Coastguard Worker             /* Now we have to copy the buffers */
2057*495ae853SAndroid Build Coastguard Worker             ps_codec->pf_inter_pred_luma_copy(pu1_bi_buf,
2058*495ae853SAndroid Build Coastguard Worker                                               ps_proc->pu1_best_subpel_buf,
2059*495ae853SAndroid Build Coastguard Worker                                               ps_me_ctxt->u4_subpel_buf_strd,
2060*495ae853SAndroid Build Coastguard Worker                                               ps_proc->u4_bst_spel_buf_strd,
2061*495ae853SAndroid Build Coastguard Worker                                               MB_SIZE, MB_SIZE, NULL, 0);
2062*495ae853SAndroid Build Coastguard Worker 
2063*495ae853SAndroid Build Coastguard Worker         }
2064*495ae853SAndroid Build Coastguard Worker         else if (ps_me_ctxt->as_mb_part[ps_proc->ps_pu->b2_pred_mode].pu1_best_hpel_buf)
2065*495ae853SAndroid Build Coastguard Worker         {
2066*495ae853SAndroid Build Coastguard Worker             /* Now we have to copy the buffers */
2067*495ae853SAndroid Build Coastguard Worker             ps_codec->pf_inter_pred_luma_copy(
2068*495ae853SAndroid Build Coastguard Worker                             ps_me_ctxt->as_mb_part[ps_proc->ps_pu->b2_pred_mode].pu1_best_hpel_buf,
2069*495ae853SAndroid Build Coastguard Worker                             ps_proc->pu1_best_subpel_buf,
2070*495ae853SAndroid Build Coastguard Worker                             ps_me_ctxt->u4_subpel_buf_strd,
2071*495ae853SAndroid Build Coastguard Worker                             ps_proc->u4_bst_spel_buf_strd, MB_SIZE, MB_SIZE,
2072*495ae853SAndroid Build Coastguard Worker                             NULL, 0);
2073*495ae853SAndroid Build Coastguard Worker         }
2074*495ae853SAndroid Build Coastguard Worker     }
2075*495ae853SAndroid Build Coastguard Worker 
2076*495ae853SAndroid Build Coastguard Worker     /**************************************************************************
2077*495ae853SAndroid Build Coastguard Worker      *Now copy the MVs to the current PU with qpel scaling
2078*495ae853SAndroid Build Coastguard Worker      ***************************************************************************/
2079*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_pu->s_me_info[PRED_L0].s_mv.i2_mvx = (ps_me_ctxt->as_mb_part[PRED_L0].s_mv_curr.i2_mvx);
2080*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_pu->s_me_info[PRED_L0].s_mv.i2_mvy = (ps_me_ctxt->as_mb_part[PRED_L0].s_mv_curr.i2_mvy);
2081*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_pu->s_me_info[PRED_L1].s_mv.i2_mvx = (ps_me_ctxt->as_mb_part[PRED_L1].s_mv_curr.i2_mvx);
2082*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_pu->s_me_info[PRED_L1].s_mv.i2_mvy = (ps_me_ctxt->as_mb_part[PRED_L1].s_mv_curr.i2_mvy);
2083*495ae853SAndroid Build Coastguard Worker 
2084*495ae853SAndroid Build Coastguard Worker 
2085*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_pu->s_me_info[0].i1_ref_idx = (ps_proc->ps_pu->b2_pred_mode != PRED_L1)? -1:0;
2086*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_pu->s_me_info[1].i1_ref_idx = (ps_proc->ps_pu->b2_pred_mode != PRED_L0)? -1:0;
2087*495ae853SAndroid Build Coastguard Worker 
2088*495ae853SAndroid Build Coastguard Worker     /* number of partitions */
2089*495ae853SAndroid Build Coastguard Worker     ps_proc->u4_num_sub_partitions = 1;
2090*495ae853SAndroid Build Coastguard Worker     *(ps_proc->pu4_mb_pu_cnt) = 1;
2091*495ae853SAndroid Build Coastguard Worker 
2092*495ae853SAndroid Build Coastguard Worker     /* position in-terms of PU */
2093*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_pu->b4_pos_x = 0;
2094*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_pu->b4_pos_y = 0;
2095*495ae853SAndroid Build Coastguard Worker 
2096*495ae853SAndroid Build Coastguard Worker     /* PU size */
2097*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_pu->b4_wd = 3;
2098*495ae853SAndroid Build Coastguard Worker     ps_proc->ps_pu->b4_ht = 3;
2099*495ae853SAndroid Build Coastguard Worker 
2100*495ae853SAndroid Build Coastguard Worker     /* Update min sad conditions */
2101*495ae853SAndroid Build Coastguard Worker     if (ps_me_ctxt->u4_min_sad_reached == 1)
2102*495ae853SAndroid Build Coastguard Worker     {
2103*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_cur_mb->u4_min_sad_reached = 1;
2104*495ae853SAndroid Build Coastguard Worker         ps_proc->ps_cur_mb->u4_min_sad = ps_me_ctxt->i4_min_sad;
2105*495ae853SAndroid Build Coastguard Worker     }
2106*495ae853SAndroid Build Coastguard Worker }
2107*495ae853SAndroid Build Coastguard Worker 
2108