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 * \file ih264d_mvpred.c
23*495ae853SAndroid Build Coastguard Worker *
24*495ae853SAndroid Build Coastguard Worker * \brief
25*495ae853SAndroid Build Coastguard Worker * This file contains function specific to decoding Motion vector.
26*495ae853SAndroid Build Coastguard Worker *
27*495ae853SAndroid Build Coastguard Worker * Detailed_description
28*495ae853SAndroid Build Coastguard Worker *
29*495ae853SAndroid Build Coastguard Worker * \date
30*495ae853SAndroid Build Coastguard Worker * 10-12-2002
31*495ae853SAndroid Build Coastguard Worker *
32*495ae853SAndroid Build Coastguard Worker * \author Arvind Raman
33*495ae853SAndroid Build Coastguard Worker **************************************************************************
34*495ae853SAndroid Build Coastguard Worker */
35*495ae853SAndroid Build Coastguard Worker #include <string.h>
36*495ae853SAndroid Build Coastguard Worker #include "ih264d_parse_cavlc.h"
37*495ae853SAndroid Build Coastguard Worker #include "ih264d_error_handler.h"
38*495ae853SAndroid Build Coastguard Worker #include "ih264d_structs.h"
39*495ae853SAndroid Build Coastguard Worker #include "ih264d_defs.h"
40*495ae853SAndroid Build Coastguard Worker #include "ih264_typedefs.h"
41*495ae853SAndroid Build Coastguard Worker #include "ih264_macros.h"
42*495ae853SAndroid Build Coastguard Worker #include "ih264_platform_macros.h"
43*495ae853SAndroid Build Coastguard Worker #include "ih264d_mb_utils.h"
44*495ae853SAndroid Build Coastguard Worker #include "ih264d_defs.h"
45*495ae853SAndroid Build Coastguard Worker #include "ih264d_debug.h"
46*495ae853SAndroid Build Coastguard Worker #include "ih264d_tables.h"
47*495ae853SAndroid Build Coastguard Worker #include "ih264d_process_bslice.h"
48*495ae853SAndroid Build Coastguard Worker #include "ih264d_mvpred.h"
49*495ae853SAndroid Build Coastguard Worker #include "ih264d_inter_pred.h"
50*495ae853SAndroid Build Coastguard Worker #include "ih264d_tables.h"
51*495ae853SAndroid Build Coastguard Worker
52*495ae853SAndroid Build Coastguard Worker /*!
53*495ae853SAndroid Build Coastguard Worker **************************************************************************
54*495ae853SAndroid Build Coastguard Worker * \if ih264d_get_motion_vector_predictor name : Name \endif
55*495ae853SAndroid Build Coastguard Worker *
56*495ae853SAndroid Build Coastguard Worker * \brief
57*495ae853SAndroid Build Coastguard Worker * The routine calculates the motion vector predictor for a given block,
58*495ae853SAndroid Build Coastguard Worker * given the candidate MV predictors.
59*495ae853SAndroid Build Coastguard Worker *
60*495ae853SAndroid Build Coastguard Worker * \param ps_mv_pred: Candidate predictors for the current block
61*495ae853SAndroid Build Coastguard Worker * \param ps_currMv: Pointer to the left top edge of the current block in
62*495ae853SAndroid Build Coastguard Worker * the MV bank
63*495ae853SAndroid Build Coastguard Worker *
64*495ae853SAndroid Build Coastguard Worker * \return
65*495ae853SAndroid Build Coastguard Worker * _mvPred: The x & y components of the MV predictor.
66*495ae853SAndroid Build Coastguard Worker *
67*495ae853SAndroid Build Coastguard Worker * \note
68*495ae853SAndroid Build Coastguard Worker * The code implements the logic as described in sec 8.4.1.2.1. Given
69*495ae853SAndroid Build Coastguard Worker * the candidate predictors and the pointer to the top left edge of the
70*495ae853SAndroid Build Coastguard Worker * block in the MV bank.
71*495ae853SAndroid Build Coastguard Worker *
72*495ae853SAndroid Build Coastguard Worker **************************************************************************
73*495ae853SAndroid Build Coastguard Worker */
74*495ae853SAndroid Build Coastguard Worker
ih264d_get_motion_vector_predictor(mv_pred_t * ps_result,mv_pred_t ** ps_mv_pred,UWORD8 u1_ref_idx,UWORD8 u1_B,const UWORD8 * pu1_mv_pred_condition)75*495ae853SAndroid Build Coastguard Worker void ih264d_get_motion_vector_predictor(mv_pred_t * ps_result,
76*495ae853SAndroid Build Coastguard Worker mv_pred_t **ps_mv_pred,
77*495ae853SAndroid Build Coastguard Worker UWORD8 u1_ref_idx,
78*495ae853SAndroid Build Coastguard Worker UWORD8 u1_B,
79*495ae853SAndroid Build Coastguard Worker const UWORD8 *pu1_mv_pred_condition)
80*495ae853SAndroid Build Coastguard Worker {
81*495ae853SAndroid Build Coastguard Worker WORD8 c_temp;
82*495ae853SAndroid Build Coastguard Worker UWORD8 uc_B2 = (u1_B << 1);
83*495ae853SAndroid Build Coastguard Worker
84*495ae853SAndroid Build Coastguard Worker /* If only one of the candidate blocks has a reference frame equal to
85*495ae853SAndroid Build Coastguard Worker the current block then use the same block as the final predictor */
86*495ae853SAndroid Build Coastguard Worker c_temp =
87*495ae853SAndroid Build Coastguard Worker (ps_mv_pred[LEFT]->i1_ref_frame[u1_B] == u1_ref_idx)
88*495ae853SAndroid Build Coastguard Worker | ((ps_mv_pred[TOP]->i1_ref_frame[u1_B]
89*495ae853SAndroid Build Coastguard Worker == u1_ref_idx) << 1)
90*495ae853SAndroid Build Coastguard Worker | ((ps_mv_pred[TOP_R]->i1_ref_frame[u1_B]
91*495ae853SAndroid Build Coastguard Worker == u1_ref_idx) << 2);
92*495ae853SAndroid Build Coastguard Worker c_temp = pu1_mv_pred_condition[c_temp];
93*495ae853SAndroid Build Coastguard Worker
94*495ae853SAndroid Build Coastguard Worker if(c_temp != -1)
95*495ae853SAndroid Build Coastguard Worker {
96*495ae853SAndroid Build Coastguard Worker /* Case when only when one of the cadidate block has the same
97*495ae853SAndroid Build Coastguard Worker reference frame as the current block */
98*495ae853SAndroid Build Coastguard Worker ps_result->i2_mv[uc_B2 + 0] = ps_mv_pred[c_temp]->i2_mv[uc_B2 + 0];
99*495ae853SAndroid Build Coastguard Worker ps_result->i2_mv[uc_B2 + 1] = ps_mv_pred[c_temp]->i2_mv[uc_B2 + 1];
100*495ae853SAndroid Build Coastguard Worker }
101*495ae853SAndroid Build Coastguard Worker else
102*495ae853SAndroid Build Coastguard Worker {
103*495ae853SAndroid Build Coastguard Worker WORD32 D0, D1;
104*495ae853SAndroid Build Coastguard Worker D0 = MIN(ps_mv_pred[0]->i2_mv[uc_B2 + 0],
105*495ae853SAndroid Build Coastguard Worker ps_mv_pred[1]->i2_mv[uc_B2 + 0]);
106*495ae853SAndroid Build Coastguard Worker D1 = MAX(ps_mv_pred[0]->i2_mv[uc_B2 + 0],
107*495ae853SAndroid Build Coastguard Worker ps_mv_pred[1]->i2_mv[uc_B2 + 0]);
108*495ae853SAndroid Build Coastguard Worker D1 = MIN(D1, ps_mv_pred[2]->i2_mv[uc_B2 + 0]);
109*495ae853SAndroid Build Coastguard Worker ps_result->i2_mv[uc_B2 + 0] = (WORD16)(MAX(D0, D1));
110*495ae853SAndroid Build Coastguard Worker
111*495ae853SAndroid Build Coastguard Worker D0 = MIN(ps_mv_pred[0]->i2_mv[uc_B2 + 1],
112*495ae853SAndroid Build Coastguard Worker ps_mv_pred[1]->i2_mv[uc_B2 + 1]);
113*495ae853SAndroid Build Coastguard Worker D1 = MAX(ps_mv_pred[0]->i2_mv[uc_B2 + 1],
114*495ae853SAndroid Build Coastguard Worker ps_mv_pred[1]->i2_mv[uc_B2 + 1]);
115*495ae853SAndroid Build Coastguard Worker D1 = MIN(D1, ps_mv_pred[2]->i2_mv[uc_B2 + 1]);
116*495ae853SAndroid Build Coastguard Worker ps_result->i2_mv[uc_B2 + 1] = (WORD16)(MAX(D0, D1));
117*495ae853SAndroid Build Coastguard Worker
118*495ae853SAndroid Build Coastguard Worker }
119*495ae853SAndroid Build Coastguard Worker }
120*495ae853SAndroid Build Coastguard Worker
121*495ae853SAndroid Build Coastguard Worker /*!
122*495ae853SAndroid Build Coastguard Worker **************************************************************************
123*495ae853SAndroid Build Coastguard Worker * \if ih264d_mbaff_mv_pred name : Name \endif
124*495ae853SAndroid Build Coastguard Worker *
125*495ae853SAndroid Build Coastguard Worker * \brief
126*495ae853SAndroid Build Coastguard Worker * The routine calculates the motion vector predictor for a given block,
127*495ae853SAndroid Build Coastguard Worker * given the candidate MV predictors.
128*495ae853SAndroid Build Coastguard Worker *
129*495ae853SAndroid Build Coastguard Worker * \param ps_mv_pred: Candidate predictors for the current block
130*495ae853SAndroid Build Coastguard Worker * \param ps_currMv: Pointer to the left top edge of the current block in
131*495ae853SAndroid Build Coastguard Worker * the MV bank
132*495ae853SAndroid Build Coastguard Worker *
133*495ae853SAndroid Build Coastguard Worker * \return
134*495ae853SAndroid Build Coastguard Worker * _mvPred: The x & y components of the MV predictor.
135*495ae853SAndroid Build Coastguard Worker *
136*495ae853SAndroid Build Coastguard Worker * \note
137*495ae853SAndroid Build Coastguard Worker * The code implements the logic as described in sec 8.4.1.2.1. Given
138*495ae853SAndroid Build Coastguard Worker * the candidate predictors and the pointer to the top left edge of the
139*495ae853SAndroid Build Coastguard Worker * block in the MV bank.
140*495ae853SAndroid Build Coastguard Worker *
141*495ae853SAndroid Build Coastguard Worker **************************************************************************
142*495ae853SAndroid Build Coastguard Worker */
143*495ae853SAndroid Build Coastguard Worker
ih264d_mbaff_mv_pred(mv_pred_t ** ps_mv_pred,UWORD8 u1_sub_mb_num,mv_pred_t * ps_mv_nmb,mv_pred_t * ps_mv_ntop,dec_struct_t * ps_dec,UWORD8 uc_mb_part_width,dec_mb_info_t * ps_cur_mb_info,UWORD8 * pu0_scale)144*495ae853SAndroid Build Coastguard Worker void ih264d_mbaff_mv_pred(mv_pred_t **ps_mv_pred,
145*495ae853SAndroid Build Coastguard Worker UWORD8 u1_sub_mb_num,
146*495ae853SAndroid Build Coastguard Worker mv_pred_t *ps_mv_nmb,
147*495ae853SAndroid Build Coastguard Worker mv_pred_t *ps_mv_ntop,
148*495ae853SAndroid Build Coastguard Worker dec_struct_t *ps_dec,
149*495ae853SAndroid Build Coastguard Worker UWORD8 uc_mb_part_width,
150*495ae853SAndroid Build Coastguard Worker dec_mb_info_t *ps_cur_mb_info,
151*495ae853SAndroid Build Coastguard Worker UWORD8* pu0_scale)
152*495ae853SAndroid Build Coastguard Worker {
153*495ae853SAndroid Build Coastguard Worker UWORD16 u2_a_in = 0, u2_b_in = 0, u2_c_in = 0, u2_d_in = 0;
154*495ae853SAndroid Build Coastguard Worker mv_pred_t *ps_mvpred_l, *ps_mvpred_tmp;
155*495ae853SAndroid Build Coastguard Worker UWORD8 u1_sub_mb_x = (u1_sub_mb_num & 3), uc_sub_mb_y = (u1_sub_mb_num >> 2);
156*495ae853SAndroid Build Coastguard Worker UWORD8 u1_is_cur_mb_fld, u1_is_left_mb_fld, u1_is_top_mb_fld;
157*495ae853SAndroid Build Coastguard Worker UWORD8 u1_is_cur_mb_top;
158*495ae853SAndroid Build Coastguard Worker
159*495ae853SAndroid Build Coastguard Worker u1_is_cur_mb_fld = ps_cur_mb_info->u1_mb_field_decodingflag;
160*495ae853SAndroid Build Coastguard Worker u1_is_cur_mb_top = ps_cur_mb_info->u1_topmb;
161*495ae853SAndroid Build Coastguard Worker
162*495ae853SAndroid Build Coastguard Worker u1_is_left_mb_fld = ps_cur_mb_info->ps_left_mb->u1_mb_fld;
163*495ae853SAndroid Build Coastguard Worker u1_is_top_mb_fld = ps_cur_mb_info->ps_top_mb->u1_mb_fld;
164*495ae853SAndroid Build Coastguard Worker
165*495ae853SAndroid Build Coastguard Worker /* Checking in the subMB exists, calculating their motion vectors to be
166*495ae853SAndroid Build Coastguard Worker used as predictors and the reference frames of those subMBs */
167*495ae853SAndroid Build Coastguard Worker ps_mv_pred[LEFT] = &ps_dec->s_default_mv_pred;
168*495ae853SAndroid Build Coastguard Worker ps_mv_pred[TOP] = &(ps_dec->s_default_mv_pred);
169*495ae853SAndroid Build Coastguard Worker ps_mv_pred[TOP_R] = &(ps_dec->s_default_mv_pred);
170*495ae853SAndroid Build Coastguard Worker
171*495ae853SAndroid Build Coastguard Worker /* Check if the left subMb is available */
172*495ae853SAndroid Build Coastguard Worker if(u1_sub_mb_x)
173*495ae853SAndroid Build Coastguard Worker {
174*495ae853SAndroid Build Coastguard Worker u2_a_in = 1;
175*495ae853SAndroid Build Coastguard Worker ps_mv_pred[LEFT] = (ps_mv_nmb - 1);
176*495ae853SAndroid Build Coastguard Worker }
177*495ae853SAndroid Build Coastguard Worker else
178*495ae853SAndroid Build Coastguard Worker {
179*495ae853SAndroid Build Coastguard Worker UWORD8 uc_temp;
180*495ae853SAndroid Build Coastguard Worker u2_a_in = (ps_cur_mb_info->u1_mb_ngbr_availablity & LEFT_MB_AVAILABLE_MASK);
181*495ae853SAndroid Build Coastguard Worker if(u2_a_in)
182*495ae853SAndroid Build Coastguard Worker {
183*495ae853SAndroid Build Coastguard Worker ps_mvpred_l = (ps_dec->u4_num_pmbair) ?
184*495ae853SAndroid Build Coastguard Worker ps_mv_nmb :
185*495ae853SAndroid Build Coastguard Worker (ps_dec->ps_mv_left + (uc_sub_mb_y << 2) + 48
186*495ae853SAndroid Build Coastguard Worker - (u1_is_cur_mb_top << 4));
187*495ae853SAndroid Build Coastguard Worker uc_temp = 29;
188*495ae853SAndroid Build Coastguard Worker if(u1_is_cur_mb_fld ^ u1_is_left_mb_fld)
189*495ae853SAndroid Build Coastguard Worker {
190*495ae853SAndroid Build Coastguard Worker if(u1_is_left_mb_fld)
191*495ae853SAndroid Build Coastguard Worker {
192*495ae853SAndroid Build Coastguard Worker uc_temp +=
193*495ae853SAndroid Build Coastguard Worker (((uc_sub_mb_y & 1) << 2)
194*495ae853SAndroid Build Coastguard Worker + ((uc_sub_mb_y & 2) << 1));
195*495ae853SAndroid Build Coastguard Worker uc_temp += ((u1_is_cur_mb_top) ? 0 : 8);
196*495ae853SAndroid Build Coastguard Worker }
197*495ae853SAndroid Build Coastguard Worker else
198*495ae853SAndroid Build Coastguard Worker {
199*495ae853SAndroid Build Coastguard Worker uc_temp = uc_temp - (uc_sub_mb_y << 2);
200*495ae853SAndroid Build Coastguard Worker uc_temp += ((u1_is_cur_mb_top) ? 0 : 16);
201*495ae853SAndroid Build Coastguard Worker }
202*495ae853SAndroid Build Coastguard Worker }
203*495ae853SAndroid Build Coastguard Worker ps_mv_pred[LEFT] = (ps_mvpred_l - uc_temp);
204*495ae853SAndroid Build Coastguard Worker pu0_scale[LEFT] = u1_is_cur_mb_fld - u1_is_left_mb_fld;
205*495ae853SAndroid Build Coastguard Worker }
206*495ae853SAndroid Build Coastguard Worker }
207*495ae853SAndroid Build Coastguard Worker
208*495ae853SAndroid Build Coastguard Worker /* Check if the top subMB is available */
209*495ae853SAndroid Build Coastguard Worker if((uc_sub_mb_y > 0) || ((u1_is_cur_mb_top | u1_is_cur_mb_fld) == 0))
210*495ae853SAndroid Build Coastguard Worker {
211*495ae853SAndroid Build Coastguard Worker u2_b_in = 1;
212*495ae853SAndroid Build Coastguard Worker ps_mv_pred[TOP] = ps_mv_nmb - 4;
213*495ae853SAndroid Build Coastguard Worker }
214*495ae853SAndroid Build Coastguard Worker else
215*495ae853SAndroid Build Coastguard Worker {
216*495ae853SAndroid Build Coastguard Worker u2_b_in = (ps_cur_mb_info->u1_mb_ngbr_availablity & TOP_MB_AVAILABLE_MASK);
217*495ae853SAndroid Build Coastguard Worker if(u2_b_in)
218*495ae853SAndroid Build Coastguard Worker {
219*495ae853SAndroid Build Coastguard Worker /* CHANGED CODE */
220*495ae853SAndroid Build Coastguard Worker
221*495ae853SAndroid Build Coastguard Worker if(u1_is_top_mb_fld && u1_is_cur_mb_fld)
222*495ae853SAndroid Build Coastguard Worker ps_mvpred_tmp = ps_mv_ntop;
223*495ae853SAndroid Build Coastguard Worker else
224*495ae853SAndroid Build Coastguard Worker {
225*495ae853SAndroid Build Coastguard Worker ps_mvpred_tmp = ps_mv_ntop;
226*495ae853SAndroid Build Coastguard Worker if(u1_is_cur_mb_top)
227*495ae853SAndroid Build Coastguard Worker ps_mvpred_tmp += 16;
228*495ae853SAndroid Build Coastguard Worker }
229*495ae853SAndroid Build Coastguard Worker
230*495ae853SAndroid Build Coastguard Worker ps_mv_pred[TOP] = ps_mvpred_tmp;
231*495ae853SAndroid Build Coastguard Worker pu0_scale[TOP] = u1_is_cur_mb_fld - u1_is_top_mb_fld;
232*495ae853SAndroid Build Coastguard Worker }
233*495ae853SAndroid Build Coastguard Worker }
234*495ae853SAndroid Build Coastguard Worker
235*495ae853SAndroid Build Coastguard Worker /* Check if the top right subMb is available. The top right subMb is
236*495ae853SAndroid Build Coastguard Worker defined as the top right subMb at the top right corner of the MB
237*495ae853SAndroid Build Coastguard Worker partition. The top right subMb index starting from the top left
238*495ae853SAndroid Build Coastguard Worker corner of the MB partition is given by
239*495ae853SAndroid Build Coastguard Worker TopRightSubMbIndx = TopLeftSubMbIndx + (WidthOfMbPartition - 6) / 2
240*495ae853SAndroid Build Coastguard Worker */
241*495ae853SAndroid Build Coastguard Worker u2_c_in = CHECKBIT(ps_cur_mb_info->u2_top_right_avail_mask,
242*495ae853SAndroid Build Coastguard Worker (u1_sub_mb_num + uc_mb_part_width - 1));
243*495ae853SAndroid Build Coastguard Worker if(u2_c_in)
244*495ae853SAndroid Build Coastguard Worker {
245*495ae853SAndroid Build Coastguard Worker ps_mv_pred[TOP_R] = ps_mv_pred[TOP] + uc_mb_part_width;
246*495ae853SAndroid Build Coastguard Worker pu0_scale[TOP_R] = pu0_scale[TOP];
247*495ae853SAndroid Build Coastguard Worker if((uc_sub_mb_y == 0) && ((u1_sub_mb_x + uc_mb_part_width) > 3))
248*495ae853SAndroid Build Coastguard Worker {
249*495ae853SAndroid Build Coastguard Worker UWORD8 uc_isTopRtMbFld;
250*495ae853SAndroid Build Coastguard Worker uc_isTopRtMbFld = ps_cur_mb_info->ps_top_right_mb->u1_mb_fld;
251*495ae853SAndroid Build Coastguard Worker /* CHANGED CODE */
252*495ae853SAndroid Build Coastguard Worker ps_mvpred_tmp = ps_mv_ntop + uc_mb_part_width + 12;
253*495ae853SAndroid Build Coastguard Worker ps_mvpred_tmp += (u1_is_cur_mb_top) ? 16 : 0;
254*495ae853SAndroid Build Coastguard Worker ps_mvpred_tmp += (u1_is_cur_mb_fld && u1_is_cur_mb_top && uc_isTopRtMbFld) ?
255*495ae853SAndroid Build Coastguard Worker 0 : 16;
256*495ae853SAndroid Build Coastguard Worker ps_mv_pred[TOP_R] = ps_mvpred_tmp;
257*495ae853SAndroid Build Coastguard Worker pu0_scale[TOP_R] = u1_is_cur_mb_fld - uc_isTopRtMbFld;
258*495ae853SAndroid Build Coastguard Worker }
259*495ae853SAndroid Build Coastguard Worker }
260*495ae853SAndroid Build Coastguard Worker else
261*495ae853SAndroid Build Coastguard Worker {
262*495ae853SAndroid Build Coastguard Worker u2_d_in = CHECKBIT(ps_cur_mb_info->u2_top_left_avail_mask, u1_sub_mb_num);
263*495ae853SAndroid Build Coastguard Worker
264*495ae853SAndroid Build Coastguard Worker /* Check if the the top left subMB is available */
265*495ae853SAndroid Build Coastguard Worker if(u2_d_in)
266*495ae853SAndroid Build Coastguard Worker {
267*495ae853SAndroid Build Coastguard Worker UWORD8 uc_isTopLtMbFld;
268*495ae853SAndroid Build Coastguard Worker
269*495ae853SAndroid Build Coastguard Worker ps_mv_pred[TOP_R] = ps_mv_pred[TOP] - 1;
270*495ae853SAndroid Build Coastguard Worker pu0_scale[TOP_R] = pu0_scale[TOP];
271*495ae853SAndroid Build Coastguard Worker
272*495ae853SAndroid Build Coastguard Worker if(u1_sub_mb_x == 0)
273*495ae853SAndroid Build Coastguard Worker {
274*495ae853SAndroid Build Coastguard Worker if((uc_sub_mb_y > 0) || ((u1_is_cur_mb_top | u1_is_cur_mb_fld) == 0))
275*495ae853SAndroid Build Coastguard Worker {
276*495ae853SAndroid Build Coastguard Worker uc_isTopLtMbFld = u1_is_left_mb_fld;
277*495ae853SAndroid Build Coastguard Worker ps_mvpred_tmp = ps_mv_pred[LEFT] - 4;
278*495ae853SAndroid Build Coastguard Worker
279*495ae853SAndroid Build Coastguard Worker if((u1_is_cur_mb_fld == 0) && uc_isTopLtMbFld)
280*495ae853SAndroid Build Coastguard Worker {
281*495ae853SAndroid Build Coastguard Worker ps_mvpred_tmp = ps_mv_pred[LEFT] + 16;
282*495ae853SAndroid Build Coastguard Worker ps_mvpred_tmp -= (uc_sub_mb_y & 1) ? 0 : 4;
283*495ae853SAndroid Build Coastguard Worker }
284*495ae853SAndroid Build Coastguard Worker }
285*495ae853SAndroid Build Coastguard Worker else
286*495ae853SAndroid Build Coastguard Worker {
287*495ae853SAndroid Build Coastguard Worker UWORD32 u4_cond = ps_dec->u4_num_pmbair;
288*495ae853SAndroid Build Coastguard Worker uc_isTopLtMbFld = ps_cur_mb_info->u1_topleft_mb_fld;
289*495ae853SAndroid Build Coastguard Worker
290*495ae853SAndroid Build Coastguard Worker /* CHANGED CODE */
291*495ae853SAndroid Build Coastguard Worker ps_mvpred_tmp = ps_mv_ntop - 29;
292*495ae853SAndroid Build Coastguard Worker ps_mvpred_tmp += (u1_is_cur_mb_top) ? 16 : 0;
293*495ae853SAndroid Build Coastguard Worker if(u1_is_cur_mb_fld && u1_is_cur_mb_top)
294*495ae853SAndroid Build Coastguard Worker ps_mvpred_tmp -= (uc_isTopLtMbFld) ? 16 : 0;
295*495ae853SAndroid Build Coastguard Worker }
296*495ae853SAndroid Build Coastguard Worker ps_mv_pred[TOP_R] = ps_mvpred_tmp;
297*495ae853SAndroid Build Coastguard Worker pu0_scale[TOP_R] = u1_is_cur_mb_fld - uc_isTopLtMbFld;
298*495ae853SAndroid Build Coastguard Worker }
299*495ae853SAndroid Build Coastguard Worker }
300*495ae853SAndroid Build Coastguard Worker else if(u2_b_in == 0)
301*495ae853SAndroid Build Coastguard Worker {
302*495ae853SAndroid Build Coastguard Worker /* If all the subMBs B, C, D are all out of the frame then their MV
303*495ae853SAndroid Build Coastguard Worker and their reference picture is equal to that of A */
304*495ae853SAndroid Build Coastguard Worker ps_mv_pred[TOP] = ps_mv_pred[LEFT];
305*495ae853SAndroid Build Coastguard Worker ps_mv_pred[TOP_R] = ps_mv_pred[LEFT];
306*495ae853SAndroid Build Coastguard Worker pu0_scale[TOP] = pu0_scale[LEFT];
307*495ae853SAndroid Build Coastguard Worker pu0_scale[TOP_R] = pu0_scale[LEFT];
308*495ae853SAndroid Build Coastguard Worker }
309*495ae853SAndroid Build Coastguard Worker }
310*495ae853SAndroid Build Coastguard Worker }
311*495ae853SAndroid Build Coastguard Worker
312*495ae853SAndroid Build Coastguard Worker /*!
313*495ae853SAndroid Build Coastguard Worker **************************************************************************
314*495ae853SAndroid Build Coastguard Worker * \if ih264d_non_mbaff_mv_pred name : Name \endif
315*495ae853SAndroid Build Coastguard Worker *
316*495ae853SAndroid Build Coastguard Worker * \brief
317*495ae853SAndroid Build Coastguard Worker * The routine calculates the motion vector predictor for a given block,
318*495ae853SAndroid Build Coastguard Worker * given the candidate MV predictors.
319*495ae853SAndroid Build Coastguard Worker *
320*495ae853SAndroid Build Coastguard Worker * \param ps_mv_pred: Candidate predictors for the current block
321*495ae853SAndroid Build Coastguard Worker * \param ps_currMv: Pointer to the left top edge of the current block in
322*495ae853SAndroid Build Coastguard Worker * the MV bank
323*495ae853SAndroid Build Coastguard Worker *
324*495ae853SAndroid Build Coastguard Worker * \return
325*495ae853SAndroid Build Coastguard Worker * _mvPred: The x & y components of the MV predictor.
326*495ae853SAndroid Build Coastguard Worker *
327*495ae853SAndroid Build Coastguard Worker * \note
328*495ae853SAndroid Build Coastguard Worker * The code implements the logic as described in sec 8.4.1.2.1. Given
329*495ae853SAndroid Build Coastguard Worker * the candidate predictors and the pointer to the top left edge of the
330*495ae853SAndroid Build Coastguard Worker * block in the MV bank.
331*495ae853SAndroid Build Coastguard Worker *
332*495ae853SAndroid Build Coastguard Worker **************************************************************************
333*495ae853SAndroid Build Coastguard Worker */
334*495ae853SAndroid Build Coastguard Worker #if(!MVPRED_NONMBAFF)
ih264d_non_mbaff_mv_pred(mv_pred_t ** ps_mv_pred,UWORD8 u1_sub_mb_num,mv_pred_t * ps_mv_nmb,mv_pred_t * ps_mv_ntop,dec_struct_t * ps_dec,UWORD8 uc_mb_part_width,dec_mb_info_t * ps_cur_mb_info)335*495ae853SAndroid Build Coastguard Worker void ih264d_non_mbaff_mv_pred(mv_pred_t **ps_mv_pred,
336*495ae853SAndroid Build Coastguard Worker UWORD8 u1_sub_mb_num,
337*495ae853SAndroid Build Coastguard Worker mv_pred_t *ps_mv_nmb,
338*495ae853SAndroid Build Coastguard Worker mv_pred_t *ps_mv_ntop,
339*495ae853SAndroid Build Coastguard Worker dec_struct_t *ps_dec,
340*495ae853SAndroid Build Coastguard Worker UWORD8 uc_mb_part_width,
341*495ae853SAndroid Build Coastguard Worker dec_mb_info_t *ps_cur_mb_info)
342*495ae853SAndroid Build Coastguard Worker {
343*495ae853SAndroid Build Coastguard Worker UWORD16 u2_b_in = 0, u2_c_in = 0, u2_d_in = 0;
344*495ae853SAndroid Build Coastguard Worker UWORD8 u1_sub_mb_x = (u1_sub_mb_num & 3), uc_sub_mb_y = (u1_sub_mb_num >> 2);
345*495ae853SAndroid Build Coastguard Worker
346*495ae853SAndroid Build Coastguard Worker /* Checking in the subMB exists, calculating their motion vectors to be
347*495ae853SAndroid Build Coastguard Worker used as predictors and the reference frames of those subMBs */
348*495ae853SAndroid Build Coastguard Worker
349*495ae853SAndroid Build Coastguard Worker ps_mv_pred[LEFT] = &ps_dec->s_default_mv_pred;
350*495ae853SAndroid Build Coastguard Worker ps_mv_pred[TOP] = &(ps_dec->s_default_mv_pred);
351*495ae853SAndroid Build Coastguard Worker ps_mv_pred[TOP_R] = &(ps_dec->s_default_mv_pred);
352*495ae853SAndroid Build Coastguard Worker /* Check if the left subMb is available */
353*495ae853SAndroid Build Coastguard Worker
354*495ae853SAndroid Build Coastguard Worker if(u1_sub_mb_x)
355*495ae853SAndroid Build Coastguard Worker {
356*495ae853SAndroid Build Coastguard Worker ps_mv_pred[LEFT] = (ps_mv_nmb - 1);
357*495ae853SAndroid Build Coastguard Worker }
358*495ae853SAndroid Build Coastguard Worker else
359*495ae853SAndroid Build Coastguard Worker {
360*495ae853SAndroid Build Coastguard Worker if(ps_cur_mb_info->u1_mb_ngbr_availablity & LEFT_MB_AVAILABLE_MASK)
361*495ae853SAndroid Build Coastguard Worker {
362*495ae853SAndroid Build Coastguard Worker ps_mv_pred[LEFT] = (ps_mv_nmb - 13);
363*495ae853SAndroid Build Coastguard Worker }
364*495ae853SAndroid Build Coastguard Worker }
365*495ae853SAndroid Build Coastguard Worker
366*495ae853SAndroid Build Coastguard Worker /* Check if the top subMB is available */
367*495ae853SAndroid Build Coastguard Worker if(uc_sub_mb_y)
368*495ae853SAndroid Build Coastguard Worker {
369*495ae853SAndroid Build Coastguard Worker u2_b_in = 1;
370*495ae853SAndroid Build Coastguard Worker ps_mv_ntop = ps_mv_nmb - 4;
371*495ae853SAndroid Build Coastguard Worker ps_mv_pred[TOP] = ps_mv_ntop;
372*495ae853SAndroid Build Coastguard Worker
373*495ae853SAndroid Build Coastguard Worker }
374*495ae853SAndroid Build Coastguard Worker else
375*495ae853SAndroid Build Coastguard Worker {
376*495ae853SAndroid Build Coastguard Worker u2_b_in = (ps_cur_mb_info->u1_mb_ngbr_availablity & TOP_MB_AVAILABLE_MASK);
377*495ae853SAndroid Build Coastguard Worker if(u2_b_in)
378*495ae853SAndroid Build Coastguard Worker {
379*495ae853SAndroid Build Coastguard Worker ps_mv_pred[TOP] = ps_mv_ntop;
380*495ae853SAndroid Build Coastguard Worker }
381*495ae853SAndroid Build Coastguard Worker }
382*495ae853SAndroid Build Coastguard Worker
383*495ae853SAndroid Build Coastguard Worker /* Check if the top right subMb is available. The top right subMb is
384*495ae853SAndroid Build Coastguard Worker defined as the top right subMb at the top right corner of the MB
385*495ae853SAndroid Build Coastguard Worker partition. The top right subMb index starting from the top left
386*495ae853SAndroid Build Coastguard Worker corner of the MB partition is given by
387*495ae853SAndroid Build Coastguard Worker TopRightSubMbIndx = TopLeftSubMbIndx + (WidthOfMbPartition - 6) / 2
388*495ae853SAndroid Build Coastguard Worker */
389*495ae853SAndroid Build Coastguard Worker u2_c_in = CHECKBIT(ps_cur_mb_info->u2_top_right_avail_mask,
390*495ae853SAndroid Build Coastguard Worker (u1_sub_mb_num + uc_mb_part_width - 1));
391*495ae853SAndroid Build Coastguard Worker if(u2_c_in)
392*495ae853SAndroid Build Coastguard Worker {
393*495ae853SAndroid Build Coastguard Worker ps_mv_pred[TOP_R] = (ps_mv_ntop + uc_mb_part_width);
394*495ae853SAndroid Build Coastguard Worker
395*495ae853SAndroid Build Coastguard Worker if(uc_sub_mb_y == 0)
396*495ae853SAndroid Build Coastguard Worker {
397*495ae853SAndroid Build Coastguard Worker /* CHANGED CODE */
398*495ae853SAndroid Build Coastguard Worker if((u1_sub_mb_x + uc_mb_part_width) > 3)
399*495ae853SAndroid Build Coastguard Worker ps_mv_pred[TOP_R] += 12;
400*495ae853SAndroid Build Coastguard Worker }
401*495ae853SAndroid Build Coastguard Worker }
402*495ae853SAndroid Build Coastguard Worker else
403*495ae853SAndroid Build Coastguard Worker {
404*495ae853SAndroid Build Coastguard Worker u2_d_in = CHECKBIT(ps_cur_mb_info->u2_top_left_avail_mask, u1_sub_mb_num);
405*495ae853SAndroid Build Coastguard Worker /* Check if the the top left subMB is available */
406*495ae853SAndroid Build Coastguard Worker if(u2_d_in)
407*495ae853SAndroid Build Coastguard Worker {
408*495ae853SAndroid Build Coastguard Worker /* CHANGED CODE */
409*495ae853SAndroid Build Coastguard Worker ps_mv_pred[TOP_R] = (ps_mv_ntop - 1);
410*495ae853SAndroid Build Coastguard Worker if(u1_sub_mb_x == 0)
411*495ae853SAndroid Build Coastguard Worker {
412*495ae853SAndroid Build Coastguard Worker if(uc_sub_mb_y)
413*495ae853SAndroid Build Coastguard Worker {
414*495ae853SAndroid Build Coastguard Worker ps_mv_pred[TOP_R] = (ps_mv_nmb - 17);
415*495ae853SAndroid Build Coastguard Worker }
416*495ae853SAndroid Build Coastguard Worker else
417*495ae853SAndroid Build Coastguard Worker {
418*495ae853SAndroid Build Coastguard Worker /* CHANGED CODE */
419*495ae853SAndroid Build Coastguard Worker ps_mv_pred[TOP_R] -= 12;
420*495ae853SAndroid Build Coastguard Worker }
421*495ae853SAndroid Build Coastguard Worker }
422*495ae853SAndroid Build Coastguard Worker }
423*495ae853SAndroid Build Coastguard Worker else if(u2_b_in == 0)
424*495ae853SAndroid Build Coastguard Worker {
425*495ae853SAndroid Build Coastguard Worker /* If all the subMBs B, C, D are all out of the frame then their MV
426*495ae853SAndroid Build Coastguard Worker and their reference picture is equal to that of A */
427*495ae853SAndroid Build Coastguard Worker ps_mv_pred[TOP] = ps_mv_pred[LEFT];
428*495ae853SAndroid Build Coastguard Worker ps_mv_pred[TOP_R] = ps_mv_pred[LEFT];
429*495ae853SAndroid Build Coastguard Worker }
430*495ae853SAndroid Build Coastguard Worker }
431*495ae853SAndroid Build Coastguard Worker }
432*495ae853SAndroid Build Coastguard Worker #endif
433*495ae853SAndroid Build Coastguard Worker
434*495ae853SAndroid Build Coastguard Worker /*****************************************************************************/
435*495ae853SAndroid Build Coastguard Worker /* */
436*495ae853SAndroid Build Coastguard Worker /* Function Name : ih264d_mvpred_nonmbaffB */
437*495ae853SAndroid Build Coastguard Worker /* */
438*495ae853SAndroid Build Coastguard Worker /* Description : This function calculates the motion vector predictor, */
439*495ae853SAndroid Build Coastguard Worker /* for B-Slices */
440*495ae853SAndroid Build Coastguard Worker /* Inputs : <What inputs does the function take?> */
441*495ae853SAndroid Build Coastguard Worker /* Globals : None */
442*495ae853SAndroid Build Coastguard Worker /* Processing : The neighbours A(Left),B(Top),C(TopRight) are calculated */
443*495ae853SAndroid Build Coastguard Worker /* and based on the type of Mb the prediction is */
444*495ae853SAndroid Build Coastguard Worker /* appropriately done */
445*495ae853SAndroid Build Coastguard Worker /* Outputs : populates ps_mv_final_pred structure */
446*495ae853SAndroid Build Coastguard Worker /* Returns : u1_direct_zero_pred_flag which is used only in */
447*495ae853SAndroid Build Coastguard Worker /* decodeSpatialdirect() */
448*495ae853SAndroid Build Coastguard Worker /* */
449*495ae853SAndroid Build Coastguard Worker /* Issues : <List any issues or problems with this function> */
450*495ae853SAndroid Build Coastguard Worker /* */
451*495ae853SAndroid Build Coastguard Worker /* Revision History: */
452*495ae853SAndroid Build Coastguard Worker /* */
453*495ae853SAndroid Build Coastguard Worker /* DD MM YYYY Author(s) Changes (Describe the changes made) */
454*495ae853SAndroid Build Coastguard Worker /* 03 05 2005 TA First Draft */
455*495ae853SAndroid Build Coastguard Worker /* */
456*495ae853SAndroid Build Coastguard Worker /*****************************************************************************/
457*495ae853SAndroid Build Coastguard Worker #if(!MVPRED_NONMBAFF)
ih264d_mvpred_nonmbaffB(dec_struct_t * ps_dec,dec_mb_info_t * ps_cur_mb_info,mv_pred_t * ps_mv_nmb,mv_pred_t * ps_mv_ntop,mv_pred_t * ps_mv_final_pred,UWORD8 u1_sub_mb_num,UWORD8 uc_mb_part_width,UWORD8 u1_lx_start,UWORD8 u1_lxend,UWORD8 u1_mb_mc_mode)458*495ae853SAndroid Build Coastguard Worker UWORD8 ih264d_mvpred_nonmbaffB(dec_struct_t *ps_dec,
459*495ae853SAndroid Build Coastguard Worker dec_mb_info_t *ps_cur_mb_info,
460*495ae853SAndroid Build Coastguard Worker mv_pred_t *ps_mv_nmb,
461*495ae853SAndroid Build Coastguard Worker mv_pred_t *ps_mv_ntop,
462*495ae853SAndroid Build Coastguard Worker mv_pred_t *ps_mv_final_pred,
463*495ae853SAndroid Build Coastguard Worker UWORD8 u1_sub_mb_num,
464*495ae853SAndroid Build Coastguard Worker UWORD8 uc_mb_part_width,
465*495ae853SAndroid Build Coastguard Worker UWORD8 u1_lx_start,
466*495ae853SAndroid Build Coastguard Worker UWORD8 u1_lxend,
467*495ae853SAndroid Build Coastguard Worker UWORD8 u1_mb_mc_mode)
468*495ae853SAndroid Build Coastguard Worker {
469*495ae853SAndroid Build Coastguard Worker UWORD8 u1_a_in, u1_b_in, uc_temp1, uc_temp2, uc_temp3;
470*495ae853SAndroid Build Coastguard Worker mv_pred_t *ps_mv_pred[3];
471*495ae853SAndroid Build Coastguard Worker UWORD8 uc_B2, uc_lx, u1_ref_idx;
472*495ae853SAndroid Build Coastguard Worker UWORD8 u1_direct_zero_pred_flag = 0;
473*495ae853SAndroid Build Coastguard Worker
474*495ae853SAndroid Build Coastguard Worker ih264d_non_mbaff_mv_pred(ps_mv_pred, u1_sub_mb_num, ps_mv_nmb, ps_mv_ntop,
475*495ae853SAndroid Build Coastguard Worker ps_dec, uc_mb_part_width, ps_cur_mb_info);
476*495ae853SAndroid Build Coastguard Worker
477*495ae853SAndroid Build Coastguard Worker for(uc_lx = u1_lx_start; uc_lx < u1_lxend; uc_lx++)
478*495ae853SAndroid Build Coastguard Worker {
479*495ae853SAndroid Build Coastguard Worker u1_ref_idx = ps_mv_final_pred->i1_ref_frame[uc_lx];
480*495ae853SAndroid Build Coastguard Worker uc_B2 = (uc_lx << 1);
481*495ae853SAndroid Build Coastguard Worker switch(u1_mb_mc_mode)
482*495ae853SAndroid Build Coastguard Worker {
483*495ae853SAndroid Build Coastguard Worker case PRED_16x8:
484*495ae853SAndroid Build Coastguard Worker /* Directional prediction for a 16x8 MB partition */
485*495ae853SAndroid Build Coastguard Worker if(u1_sub_mb_num == 0)
486*495ae853SAndroid Build Coastguard Worker {
487*495ae853SAndroid Build Coastguard Worker /* Calculating the MV pred for the top 16x8 block */
488*495ae853SAndroid Build Coastguard Worker if(ps_mv_pred[TOP]->i1_ref_frame[uc_lx] == u1_ref_idx)
489*495ae853SAndroid Build Coastguard Worker {
490*495ae853SAndroid Build Coastguard Worker /* If the reference frame used by the top subMB is same as the
491*495ae853SAndroid Build Coastguard Worker reference frame used by the current block then MV predictor to
492*495ae853SAndroid Build Coastguard Worker be used for the current block is same as the MV of the top
493*495ae853SAndroid Build Coastguard Worker subMB */
494*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i2_mv[uc_B2 + 0] =
495*495ae853SAndroid Build Coastguard Worker ps_mv_pred[TOP]->i2_mv[uc_B2 + 0];
496*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i2_mv[uc_B2 + 1] =
497*495ae853SAndroid Build Coastguard Worker ps_mv_pred[TOP]->i2_mv[uc_B2 + 1];
498*495ae853SAndroid Build Coastguard Worker }
499*495ae853SAndroid Build Coastguard Worker else
500*495ae853SAndroid Build Coastguard Worker {
501*495ae853SAndroid Build Coastguard Worker /* The MV predictor is calculated according to the process
502*495ae853SAndroid Build Coastguard Worker defined in 8.4.1.2.1 */
503*495ae853SAndroid Build Coastguard Worker ih264d_get_motion_vector_predictor(
504*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred,
505*495ae853SAndroid Build Coastguard Worker ps_mv_pred,
506*495ae853SAndroid Build Coastguard Worker u1_ref_idx,
507*495ae853SAndroid Build Coastguard Worker uc_lx,
508*495ae853SAndroid Build Coastguard Worker (const UWORD8 *)gau1_ih264d_mv_pred_condition);
509*495ae853SAndroid Build Coastguard Worker }
510*495ae853SAndroid Build Coastguard Worker }
511*495ae853SAndroid Build Coastguard Worker else
512*495ae853SAndroid Build Coastguard Worker {
513*495ae853SAndroid Build Coastguard Worker if(ps_mv_pred[LEFT]->i1_ref_frame[uc_lx] == u1_ref_idx)
514*495ae853SAndroid Build Coastguard Worker {
515*495ae853SAndroid Build Coastguard Worker /* If the reference frame used by the left subMB is same as the
516*495ae853SAndroid Build Coastguard Worker reference frame used by the current block then MV predictor to
517*495ae853SAndroid Build Coastguard Worker be used for the current block is same as the MV of the left
518*495ae853SAndroid Build Coastguard Worker subMB */
519*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i2_mv[uc_B2 + 0] =
520*495ae853SAndroid Build Coastguard Worker ps_mv_pred[LEFT]->i2_mv[uc_B2 + 0];
521*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i2_mv[uc_B2 + 1] =
522*495ae853SAndroid Build Coastguard Worker ps_mv_pred[LEFT]->i2_mv[uc_B2 + 1];
523*495ae853SAndroid Build Coastguard Worker }
524*495ae853SAndroid Build Coastguard Worker else
525*495ae853SAndroid Build Coastguard Worker {
526*495ae853SAndroid Build Coastguard Worker /* The MV predictor is calculated according to the process
527*495ae853SAndroid Build Coastguard Worker defined in 8.4.1.2.1 */
528*495ae853SAndroid Build Coastguard Worker ih264d_get_motion_vector_predictor(
529*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred,
530*495ae853SAndroid Build Coastguard Worker ps_mv_pred,
531*495ae853SAndroid Build Coastguard Worker u1_ref_idx,
532*495ae853SAndroid Build Coastguard Worker uc_lx,
533*495ae853SAndroid Build Coastguard Worker (const UWORD8 *)gau1_ih264d_mv_pred_condition);
534*495ae853SAndroid Build Coastguard Worker }
535*495ae853SAndroid Build Coastguard Worker }
536*495ae853SAndroid Build Coastguard Worker break;
537*495ae853SAndroid Build Coastguard Worker case PRED_8x16:
538*495ae853SAndroid Build Coastguard Worker /* Directional prediction for a 8x16 MB partition */
539*495ae853SAndroid Build Coastguard Worker if(u1_sub_mb_num == 0)
540*495ae853SAndroid Build Coastguard Worker {
541*495ae853SAndroid Build Coastguard Worker if(ps_mv_pred[LEFT]->i1_ref_frame[uc_lx] == u1_ref_idx)
542*495ae853SAndroid Build Coastguard Worker {
543*495ae853SAndroid Build Coastguard Worker /* If the reference frame used by the left subMB is same as the
544*495ae853SAndroid Build Coastguard Worker reference frame used by the current block then MV predictor to
545*495ae853SAndroid Build Coastguard Worker be used for the current block is same as the MV of the left
546*495ae853SAndroid Build Coastguard Worker subMB */
547*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i2_mv[uc_B2 + 0] =
548*495ae853SAndroid Build Coastguard Worker ps_mv_pred[LEFT]->i2_mv[uc_B2 + 0];
549*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i2_mv[uc_B2 + 1] =
550*495ae853SAndroid Build Coastguard Worker ps_mv_pred[LEFT]->i2_mv[uc_B2 + 1];
551*495ae853SAndroid Build Coastguard Worker }
552*495ae853SAndroid Build Coastguard Worker else
553*495ae853SAndroid Build Coastguard Worker {
554*495ae853SAndroid Build Coastguard Worker /* The MV predictor is calculated according to the process
555*495ae853SAndroid Build Coastguard Worker defined in 8.4.1.2.1 */
556*495ae853SAndroid Build Coastguard Worker ih264d_get_motion_vector_predictor(
557*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred,
558*495ae853SAndroid Build Coastguard Worker ps_mv_pred,
559*495ae853SAndroid Build Coastguard Worker u1_ref_idx,
560*495ae853SAndroid Build Coastguard Worker uc_lx,
561*495ae853SAndroid Build Coastguard Worker (const UWORD8 *)gau1_ih264d_mv_pred_condition);
562*495ae853SAndroid Build Coastguard Worker }
563*495ae853SAndroid Build Coastguard Worker }
564*495ae853SAndroid Build Coastguard Worker else
565*495ae853SAndroid Build Coastguard Worker {
566*495ae853SAndroid Build Coastguard Worker if(ps_mv_pred[TOP_R]->i1_ref_frame[uc_lx] == u1_ref_idx)
567*495ae853SAndroid Build Coastguard Worker {
568*495ae853SAndroid Build Coastguard Worker /* If the reference frame used by the top right subMB is same as
569*495ae853SAndroid Build Coastguard Worker the reference frame used by the current block then MV
570*495ae853SAndroid Build Coastguard Worker predictor to be used for the current block is same as the MV
571*495ae853SAndroid Build Coastguard Worker of the left subMB */
572*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i2_mv[uc_B2 + 0] =
573*495ae853SAndroid Build Coastguard Worker ps_mv_pred[TOP_R]->i2_mv[uc_B2 + 0];
574*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i2_mv[uc_B2 + 1] =
575*495ae853SAndroid Build Coastguard Worker ps_mv_pred[TOP_R]->i2_mv[uc_B2 + 1];
576*495ae853SAndroid Build Coastguard Worker }
577*495ae853SAndroid Build Coastguard Worker else
578*495ae853SAndroid Build Coastguard Worker {
579*495ae853SAndroid Build Coastguard Worker /* The MV predictor is calculated according to the process
580*495ae853SAndroid Build Coastguard Worker defined in 8.4.1.2.1 */
581*495ae853SAndroid Build Coastguard Worker ih264d_get_motion_vector_predictor(
582*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred,
583*495ae853SAndroid Build Coastguard Worker ps_mv_pred,
584*495ae853SAndroid Build Coastguard Worker u1_ref_idx,
585*495ae853SAndroid Build Coastguard Worker uc_lx,
586*495ae853SAndroid Build Coastguard Worker (const UWORD8 *)gau1_ih264d_mv_pred_condition);
587*495ae853SAndroid Build Coastguard Worker }
588*495ae853SAndroid Build Coastguard Worker }
589*495ae853SAndroid Build Coastguard Worker break;
590*495ae853SAndroid Build Coastguard Worker case B_DIRECT_SPATIAL:
591*495ae853SAndroid Build Coastguard Worker /* Case when the MB has been skipped */
592*495ae853SAndroid Build Coastguard Worker /* If either of left or the top subMB is not present
593*495ae853SAndroid Build Coastguard Worker OR
594*495ae853SAndroid Build Coastguard Worker If both the MV components of either the left or the top subMB are
595*495ae853SAndroid Build Coastguard Worker zero and their reference frame pointer pointing to 0
596*495ae853SAndroid Build Coastguard Worker then MV for the skipped MB is zero
597*495ae853SAndroid Build Coastguard Worker else the Median of the mv_pred_t is used */
598*495ae853SAndroid Build Coastguard Worker uc_temp1 = (UWORD8)ps_mv_pred[LEFT]->i1_ref_frame[0];
599*495ae853SAndroid Build Coastguard Worker uc_temp2 = (UWORD8)ps_mv_pred[TOP]->i1_ref_frame[0];
600*495ae853SAndroid Build Coastguard Worker uc_temp3 = (UWORD8)ps_mv_pred[TOP_R]->i1_ref_frame[0];
601*495ae853SAndroid Build Coastguard Worker
602*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i1_ref_frame[0] = MIN(uc_temp1,
603*495ae853SAndroid Build Coastguard Worker MIN(uc_temp2, uc_temp3));
604*495ae853SAndroid Build Coastguard Worker
605*495ae853SAndroid Build Coastguard Worker uc_temp1 = (UWORD8)ps_mv_pred[LEFT]->i1_ref_frame[1];
606*495ae853SAndroid Build Coastguard Worker uc_temp2 = (UWORD8)ps_mv_pred[TOP]->i1_ref_frame[1];
607*495ae853SAndroid Build Coastguard Worker uc_temp3 = (UWORD8)ps_mv_pred[TOP_R]->i1_ref_frame[1];
608*495ae853SAndroid Build Coastguard Worker
609*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i1_ref_frame[1] = MIN(uc_temp1,
610*495ae853SAndroid Build Coastguard Worker MIN(uc_temp2, uc_temp3));
611*495ae853SAndroid Build Coastguard Worker
612*495ae853SAndroid Build Coastguard Worker if((ps_mv_final_pred->i1_ref_frame[0] < 0)
613*495ae853SAndroid Build Coastguard Worker && (ps_mv_final_pred->i1_ref_frame[1] < 0))
614*495ae853SAndroid Build Coastguard Worker {
615*495ae853SAndroid Build Coastguard Worker u1_direct_zero_pred_flag = 1;
616*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i1_ref_frame[0] = 0;
617*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i1_ref_frame[1] = 0;
618*495ae853SAndroid Build Coastguard Worker }
619*495ae853SAndroid Build Coastguard Worker ih264d_get_motion_vector_predictor(
620*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred, ps_mv_pred,
621*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i1_ref_frame[0], 0,
622*495ae853SAndroid Build Coastguard Worker (const UWORD8 *)gau1_ih264d_mv_pred_condition);
623*495ae853SAndroid Build Coastguard Worker
624*495ae853SAndroid Build Coastguard Worker ih264d_get_motion_vector_predictor(
625*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred, ps_mv_pred,
626*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i1_ref_frame[1], 1,
627*495ae853SAndroid Build Coastguard Worker (const UWORD8 *)gau1_ih264d_mv_pred_condition);
628*495ae853SAndroid Build Coastguard Worker
629*495ae853SAndroid Build Coastguard Worker break;
630*495ae853SAndroid Build Coastguard Worker case MB_SKIP:
631*495ae853SAndroid Build Coastguard Worker /* Case when the MB has been skipped */
632*495ae853SAndroid Build Coastguard Worker /* If either of left or the top subMB is not present
633*495ae853SAndroid Build Coastguard Worker OR
634*495ae853SAndroid Build Coastguard Worker If both the MV components of either the left or the top subMB are
635*495ae853SAndroid Build Coastguard Worker zero and their reference frame pointer pointing to 0
636*495ae853SAndroid Build Coastguard Worker then MV for the skipped MB is zero
637*495ae853SAndroid Build Coastguard Worker else the Median of the mv_pred_t is used */
638*495ae853SAndroid Build Coastguard Worker u1_a_in = (ps_cur_mb_info->u1_mb_ngbr_availablity &
639*495ae853SAndroid Build Coastguard Worker LEFT_MB_AVAILABLE_MASK);
640*495ae853SAndroid Build Coastguard Worker u1_b_in = (ps_cur_mb_info->u1_mb_ngbr_availablity &
641*495ae853SAndroid Build Coastguard Worker TOP_MB_AVAILABLE_MASK);
642*495ae853SAndroid Build Coastguard Worker if(((u1_a_in * u1_b_in) == 0)
643*495ae853SAndroid Build Coastguard Worker || ((ps_mv_pred[LEFT]->i2_mv[0]
644*495ae853SAndroid Build Coastguard Worker | ps_mv_pred[LEFT]->i2_mv[1]
645*495ae853SAndroid Build Coastguard Worker | ps_mv_pred[LEFT]->i1_ref_frame[0])
646*495ae853SAndroid Build Coastguard Worker == 0)
647*495ae853SAndroid Build Coastguard Worker || ((ps_mv_pred[TOP]->i2_mv[0]
648*495ae853SAndroid Build Coastguard Worker | ps_mv_pred[TOP]->i2_mv[1]
649*495ae853SAndroid Build Coastguard Worker | ps_mv_pred[TOP]->i1_ref_frame[0])
650*495ae853SAndroid Build Coastguard Worker == 0))
651*495ae853SAndroid Build Coastguard Worker {
652*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i2_mv[0] = 0;
653*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i2_mv[1] = 0;
654*495ae853SAndroid Build Coastguard Worker break;
655*495ae853SAndroid Build Coastguard Worker }
656*495ae853SAndroid Build Coastguard Worker /* If the condition above is not true calculate the MV predictor
657*495ae853SAndroid Build Coastguard Worker according to the process defined in sec 8.4.1.2.1 */
658*495ae853SAndroid Build Coastguard Worker default:
659*495ae853SAndroid Build Coastguard Worker ih264d_get_motion_vector_predictor(
660*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred, ps_mv_pred, u1_ref_idx, uc_lx,
661*495ae853SAndroid Build Coastguard Worker (const UWORD8 *)gau1_ih264d_mv_pred_condition);
662*495ae853SAndroid Build Coastguard Worker break;
663*495ae853SAndroid Build Coastguard Worker }
664*495ae853SAndroid Build Coastguard Worker }
665*495ae853SAndroid Build Coastguard Worker return (u1_direct_zero_pred_flag);
666*495ae853SAndroid Build Coastguard Worker }
667*495ae853SAndroid Build Coastguard Worker #endif
668*495ae853SAndroid Build Coastguard Worker
669*495ae853SAndroid Build Coastguard Worker /*****************************************************************************/
670*495ae853SAndroid Build Coastguard Worker /* */
671*495ae853SAndroid Build Coastguard Worker /* Function Name : ih264d_mvpred_nonmbaff */
672*495ae853SAndroid Build Coastguard Worker /* */
673*495ae853SAndroid Build Coastguard Worker /* Description : This function calculates the motion vector predictor, */
674*495ae853SAndroid Build Coastguard Worker /* for all the slice types other than B_SLICE */
675*495ae853SAndroid Build Coastguard Worker /* Inputs : <What inputs does the function take?> */
676*495ae853SAndroid Build Coastguard Worker /* Globals : None */
677*495ae853SAndroid Build Coastguard Worker /* Processing : The neighbours A(Left),B(Top),C(TopRight) are calculated */
678*495ae853SAndroid Build Coastguard Worker /* and based on the type of Mb the prediction is */
679*495ae853SAndroid Build Coastguard Worker /* appropriately done */
680*495ae853SAndroid Build Coastguard Worker /* Outputs : populates ps_mv_final_pred structure */
681*495ae853SAndroid Build Coastguard Worker /* Returns : u1_direct_zero_pred_flag which is used only in */
682*495ae853SAndroid Build Coastguard Worker /* decodeSpatialdirect() */
683*495ae853SAndroid Build Coastguard Worker /* */
684*495ae853SAndroid Build Coastguard Worker /* Issues : <List any issues or problems with this function> */
685*495ae853SAndroid Build Coastguard Worker /* */
686*495ae853SAndroid Build Coastguard Worker /* Revision History: */
687*495ae853SAndroid Build Coastguard Worker /* */
688*495ae853SAndroid Build Coastguard Worker /* DD MM YYYY Author(s) Changes (Describe the changes made) */
689*495ae853SAndroid Build Coastguard Worker /* 03 05 2005 TA First Draft */
690*495ae853SAndroid Build Coastguard Worker /* */
691*495ae853SAndroid Build Coastguard Worker /*****************************************************************************/
692*495ae853SAndroid Build Coastguard Worker #if(!MVPRED_NONMBAFF)
ih264d_mvpred_nonmbaff(dec_struct_t * ps_dec,dec_mb_info_t * ps_cur_mb_info,mv_pred_t * ps_mv_nmb,mv_pred_t * ps_mv_ntop,mv_pred_t * ps_mv_final_pred,UWORD8 u1_sub_mb_num,UWORD8 uc_mb_part_width,UWORD8 u1_lx_start,UWORD8 u1_lxend,UWORD8 u1_mb_mc_mode)693*495ae853SAndroid Build Coastguard Worker UWORD8 ih264d_mvpred_nonmbaff(dec_struct_t *ps_dec,
694*495ae853SAndroid Build Coastguard Worker dec_mb_info_t *ps_cur_mb_info,
695*495ae853SAndroid Build Coastguard Worker mv_pred_t *ps_mv_nmb,
696*495ae853SAndroid Build Coastguard Worker mv_pred_t *ps_mv_ntop,
697*495ae853SAndroid Build Coastguard Worker mv_pred_t *ps_mv_final_pred,
698*495ae853SAndroid Build Coastguard Worker UWORD8 u1_sub_mb_num,
699*495ae853SAndroid Build Coastguard Worker UWORD8 uc_mb_part_width,
700*495ae853SAndroid Build Coastguard Worker UWORD8 u1_lx_start,
701*495ae853SAndroid Build Coastguard Worker UWORD8 u1_lxend,
702*495ae853SAndroid Build Coastguard Worker UWORD8 u1_mb_mc_mode)
703*495ae853SAndroid Build Coastguard Worker {
704*495ae853SAndroid Build Coastguard Worker UWORD8 u1_a_in, u1_b_in, uc_temp1, uc_temp2, uc_temp3;
705*495ae853SAndroid Build Coastguard Worker mv_pred_t *ps_mv_pred[3];
706*495ae853SAndroid Build Coastguard Worker UWORD8 u1_ref_idx;
707*495ae853SAndroid Build Coastguard Worker UWORD8 u1_direct_zero_pred_flag = 0;
708*495ae853SAndroid Build Coastguard Worker UNUSED(u1_lx_start);
709*495ae853SAndroid Build Coastguard Worker UNUSED(u1_lxend);
710*495ae853SAndroid Build Coastguard Worker ih264d_non_mbaff_mv_pred(ps_mv_pred, u1_sub_mb_num, ps_mv_nmb, ps_mv_ntop,
711*495ae853SAndroid Build Coastguard Worker ps_dec, uc_mb_part_width, ps_cur_mb_info);
712*495ae853SAndroid Build Coastguard Worker
713*495ae853SAndroid Build Coastguard Worker u1_ref_idx = ps_mv_final_pred->i1_ref_frame[0];
714*495ae853SAndroid Build Coastguard Worker
715*495ae853SAndroid Build Coastguard Worker switch(u1_mb_mc_mode)
716*495ae853SAndroid Build Coastguard Worker {
717*495ae853SAndroid Build Coastguard Worker case PRED_16x8:
718*495ae853SAndroid Build Coastguard Worker /* Directional prediction for a 16x8 MB partition */
719*495ae853SAndroid Build Coastguard Worker if(u1_sub_mb_num == 0)
720*495ae853SAndroid Build Coastguard Worker {
721*495ae853SAndroid Build Coastguard Worker /* Calculating the MV pred for the top 16x8 block */
722*495ae853SAndroid Build Coastguard Worker if(ps_mv_pred[TOP]->i1_ref_frame[0] == u1_ref_idx)
723*495ae853SAndroid Build Coastguard Worker {
724*495ae853SAndroid Build Coastguard Worker /* If the reference frame used by the top subMB is same as the
725*495ae853SAndroid Build Coastguard Worker reference frame used by the current block then MV predictor to
726*495ae853SAndroid Build Coastguard Worker be used for the current block is same as the MV of the top
727*495ae853SAndroid Build Coastguard Worker subMB */
728*495ae853SAndroid Build Coastguard Worker
729*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i2_mv[0] = ps_mv_pred[TOP]->i2_mv[0];
730*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i2_mv[1] = ps_mv_pred[TOP]->i2_mv[1];
731*495ae853SAndroid Build Coastguard Worker }
732*495ae853SAndroid Build Coastguard Worker else
733*495ae853SAndroid Build Coastguard Worker {
734*495ae853SAndroid Build Coastguard Worker /* The MV predictor is calculated according to the process
735*495ae853SAndroid Build Coastguard Worker defined in 8.4.1.2.1 */
736*495ae853SAndroid Build Coastguard Worker ih264d_get_motion_vector_predictor(
737*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred,
738*495ae853SAndroid Build Coastguard Worker ps_mv_pred,
739*495ae853SAndroid Build Coastguard Worker u1_ref_idx,
740*495ae853SAndroid Build Coastguard Worker 0,
741*495ae853SAndroid Build Coastguard Worker (const UWORD8 *)gau1_ih264d_mv_pred_condition);
742*495ae853SAndroid Build Coastguard Worker }
743*495ae853SAndroid Build Coastguard Worker }
744*495ae853SAndroid Build Coastguard Worker else
745*495ae853SAndroid Build Coastguard Worker {
746*495ae853SAndroid Build Coastguard Worker if(ps_mv_pred[LEFT]->i1_ref_frame[0] == u1_ref_idx)
747*495ae853SAndroid Build Coastguard Worker {
748*495ae853SAndroid Build Coastguard Worker /* If the reference frame used by the left subMB is same as the
749*495ae853SAndroid Build Coastguard Worker reference frame used by the current block then MV predictor to
750*495ae853SAndroid Build Coastguard Worker be used for the current block is same as the MV of the left
751*495ae853SAndroid Build Coastguard Worker subMB */
752*495ae853SAndroid Build Coastguard Worker
753*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i2_mv[0] = ps_mv_pred[LEFT]->i2_mv[0];
754*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i2_mv[1] = ps_mv_pred[LEFT]->i2_mv[1];
755*495ae853SAndroid Build Coastguard Worker }
756*495ae853SAndroid Build Coastguard Worker else
757*495ae853SAndroid Build Coastguard Worker {
758*495ae853SAndroid Build Coastguard Worker /* The MV predictor is calculated according to the process
759*495ae853SAndroid Build Coastguard Worker defined in 8.4.1.2.1 */
760*495ae853SAndroid Build Coastguard Worker ih264d_get_motion_vector_predictor(
761*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred,
762*495ae853SAndroid Build Coastguard Worker ps_mv_pred,
763*495ae853SAndroid Build Coastguard Worker u1_ref_idx,
764*495ae853SAndroid Build Coastguard Worker 0,
765*495ae853SAndroid Build Coastguard Worker (const UWORD8 *)gau1_ih264d_mv_pred_condition);
766*495ae853SAndroid Build Coastguard Worker }
767*495ae853SAndroid Build Coastguard Worker }
768*495ae853SAndroid Build Coastguard Worker break;
769*495ae853SAndroid Build Coastguard Worker case PRED_8x16:
770*495ae853SAndroid Build Coastguard Worker /* Directional prediction for a 8x16 MB partition */
771*495ae853SAndroid Build Coastguard Worker if(u1_sub_mb_num == 0)
772*495ae853SAndroid Build Coastguard Worker {
773*495ae853SAndroid Build Coastguard Worker if(ps_mv_pred[LEFT]->i1_ref_frame[0] == u1_ref_idx)
774*495ae853SAndroid Build Coastguard Worker {
775*495ae853SAndroid Build Coastguard Worker /* If the reference frame used by the left subMB is same as the
776*495ae853SAndroid Build Coastguard Worker reference frame used by the current block then MV predictor to
777*495ae853SAndroid Build Coastguard Worker be used for the current block is same as the MV of the left
778*495ae853SAndroid Build Coastguard Worker subMB */
779*495ae853SAndroid Build Coastguard Worker
780*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i2_mv[0] = ps_mv_pred[LEFT]->i2_mv[0];
781*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i2_mv[1] = ps_mv_pred[LEFT]->i2_mv[1];
782*495ae853SAndroid Build Coastguard Worker }
783*495ae853SAndroid Build Coastguard Worker else
784*495ae853SAndroid Build Coastguard Worker {
785*495ae853SAndroid Build Coastguard Worker /* The MV predictor is calculated according to the process
786*495ae853SAndroid Build Coastguard Worker defined in 8.4.1.2.1 */
787*495ae853SAndroid Build Coastguard Worker ih264d_get_motion_vector_predictor(
788*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred,
789*495ae853SAndroid Build Coastguard Worker ps_mv_pred,
790*495ae853SAndroid Build Coastguard Worker u1_ref_idx,
791*495ae853SAndroid Build Coastguard Worker 0,
792*495ae853SAndroid Build Coastguard Worker (const UWORD8 *)gau1_ih264d_mv_pred_condition);
793*495ae853SAndroid Build Coastguard Worker }
794*495ae853SAndroid Build Coastguard Worker }
795*495ae853SAndroid Build Coastguard Worker else
796*495ae853SAndroid Build Coastguard Worker {
797*495ae853SAndroid Build Coastguard Worker if(ps_mv_pred[TOP_R]->i1_ref_frame[0] == u1_ref_idx)
798*495ae853SAndroid Build Coastguard Worker {
799*495ae853SAndroid Build Coastguard Worker /* If the reference frame used by the top right subMB is same as
800*495ae853SAndroid Build Coastguard Worker the reference frame used by the current block then MV
801*495ae853SAndroid Build Coastguard Worker predictor to be used for the current block is same as the MV
802*495ae853SAndroid Build Coastguard Worker of the left subMB */
803*495ae853SAndroid Build Coastguard Worker
804*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i2_mv[0] = ps_mv_pred[TOP_R]->i2_mv[0];
805*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i2_mv[1] = ps_mv_pred[TOP_R]->i2_mv[1];
806*495ae853SAndroid Build Coastguard Worker }
807*495ae853SAndroid Build Coastguard Worker else
808*495ae853SAndroid Build Coastguard Worker {
809*495ae853SAndroid Build Coastguard Worker /* The MV predictor is calculated according to the process
810*495ae853SAndroid Build Coastguard Worker defined in 8.4.1.2.1 */
811*495ae853SAndroid Build Coastguard Worker ih264d_get_motion_vector_predictor(
812*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred,
813*495ae853SAndroid Build Coastguard Worker ps_mv_pred,
814*495ae853SAndroid Build Coastguard Worker u1_ref_idx,
815*495ae853SAndroid Build Coastguard Worker 0,
816*495ae853SAndroid Build Coastguard Worker (const UWORD8 *)gau1_ih264d_mv_pred_condition);
817*495ae853SAndroid Build Coastguard Worker }
818*495ae853SAndroid Build Coastguard Worker }
819*495ae853SAndroid Build Coastguard Worker break;
820*495ae853SAndroid Build Coastguard Worker case B_DIRECT_SPATIAL:
821*495ae853SAndroid Build Coastguard Worker /* Case when the MB has been skipped */
822*495ae853SAndroid Build Coastguard Worker /* If either of left or the top subMB is not present
823*495ae853SAndroid Build Coastguard Worker OR
824*495ae853SAndroid Build Coastguard Worker If both the MV components of either the left or the top subMB are
825*495ae853SAndroid Build Coastguard Worker zero and their reference frame pointer pointing to 0
826*495ae853SAndroid Build Coastguard Worker then MV for the skipped MB is zero
827*495ae853SAndroid Build Coastguard Worker else the Median of the mv_pred_t is used */
828*495ae853SAndroid Build Coastguard Worker uc_temp1 = (UWORD8)ps_mv_pred[LEFT]->i1_ref_frame[0];
829*495ae853SAndroid Build Coastguard Worker uc_temp2 = (UWORD8)ps_mv_pred[TOP]->i1_ref_frame[0];
830*495ae853SAndroid Build Coastguard Worker uc_temp3 = (UWORD8)ps_mv_pred[TOP_R]->i1_ref_frame[0];
831*495ae853SAndroid Build Coastguard Worker
832*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i1_ref_frame[0] = MIN(uc_temp1,
833*495ae853SAndroid Build Coastguard Worker MIN(uc_temp2, uc_temp3));
834*495ae853SAndroid Build Coastguard Worker
835*495ae853SAndroid Build Coastguard Worker uc_temp1 = (UWORD8)ps_mv_pred[LEFT]->i1_ref_frame[1];
836*495ae853SAndroid Build Coastguard Worker uc_temp2 = (UWORD8)ps_mv_pred[TOP]->i1_ref_frame[1];
837*495ae853SAndroid Build Coastguard Worker uc_temp3 = (UWORD8)ps_mv_pred[TOP_R]->i1_ref_frame[1];
838*495ae853SAndroid Build Coastguard Worker
839*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i1_ref_frame[1] = MIN(uc_temp1,
840*495ae853SAndroid Build Coastguard Worker MIN(uc_temp2, uc_temp3));
841*495ae853SAndroid Build Coastguard Worker
842*495ae853SAndroid Build Coastguard Worker if((ps_mv_final_pred->i1_ref_frame[0] < 0)
843*495ae853SAndroid Build Coastguard Worker && (ps_mv_final_pred->i1_ref_frame[1] < 0))
844*495ae853SAndroid Build Coastguard Worker {
845*495ae853SAndroid Build Coastguard Worker u1_direct_zero_pred_flag = 1;
846*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i1_ref_frame[0] = 0;
847*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i1_ref_frame[1] = 0;
848*495ae853SAndroid Build Coastguard Worker }
849*495ae853SAndroid Build Coastguard Worker ih264d_get_motion_vector_predictor(
850*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred, ps_mv_pred,
851*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i1_ref_frame[0], 0,
852*495ae853SAndroid Build Coastguard Worker (const UWORD8 *)gau1_ih264d_mv_pred_condition);
853*495ae853SAndroid Build Coastguard Worker
854*495ae853SAndroid Build Coastguard Worker ih264d_get_motion_vector_predictor(
855*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred, ps_mv_pred,
856*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i1_ref_frame[1], 1,
857*495ae853SAndroid Build Coastguard Worker (const UWORD8 *)gau1_ih264d_mv_pred_condition);
858*495ae853SAndroid Build Coastguard Worker
859*495ae853SAndroid Build Coastguard Worker break;
860*495ae853SAndroid Build Coastguard Worker case MB_SKIP:
861*495ae853SAndroid Build Coastguard Worker /* Case when the MB has been skipped */
862*495ae853SAndroid Build Coastguard Worker /* If either of left or the top subMB is not present
863*495ae853SAndroid Build Coastguard Worker OR
864*495ae853SAndroid Build Coastguard Worker If both the MV components of either the left or the top subMB are
865*495ae853SAndroid Build Coastguard Worker zero and their reference frame pointer pointing to 0
866*495ae853SAndroid Build Coastguard Worker then MV for the skipped MB is zero
867*495ae853SAndroid Build Coastguard Worker else the Median of the mv_pred_t is used */
868*495ae853SAndroid Build Coastguard Worker u1_a_in = (ps_cur_mb_info->u1_mb_ngbr_availablity &
869*495ae853SAndroid Build Coastguard Worker LEFT_MB_AVAILABLE_MASK);
870*495ae853SAndroid Build Coastguard Worker u1_b_in = (ps_cur_mb_info->u1_mb_ngbr_availablity &
871*495ae853SAndroid Build Coastguard Worker TOP_MB_AVAILABLE_MASK);
872*495ae853SAndroid Build Coastguard Worker if(((u1_a_in * u1_b_in) == 0)
873*495ae853SAndroid Build Coastguard Worker || ((ps_mv_pred[LEFT]->i2_mv[0]
874*495ae853SAndroid Build Coastguard Worker | ps_mv_pred[LEFT]->i2_mv[1]
875*495ae853SAndroid Build Coastguard Worker | ps_mv_pred[LEFT]->i1_ref_frame[0])
876*495ae853SAndroid Build Coastguard Worker == 0)
877*495ae853SAndroid Build Coastguard Worker || ((ps_mv_pred[TOP]->i2_mv[0]
878*495ae853SAndroid Build Coastguard Worker | ps_mv_pred[TOP]->i2_mv[1]
879*495ae853SAndroid Build Coastguard Worker | ps_mv_pred[TOP]->i1_ref_frame[0])
880*495ae853SAndroid Build Coastguard Worker == 0))
881*495ae853SAndroid Build Coastguard Worker {
882*495ae853SAndroid Build Coastguard Worker
883*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i2_mv[0] = 0;
884*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i2_mv[1] = 0;
885*495ae853SAndroid Build Coastguard Worker break;
886*495ae853SAndroid Build Coastguard Worker }
887*495ae853SAndroid Build Coastguard Worker /* If the condition above is not true calculate the MV predictor
888*495ae853SAndroid Build Coastguard Worker according to the process defined in sec 8.4.1.2.1 */
889*495ae853SAndroid Build Coastguard Worker default:
890*495ae853SAndroid Build Coastguard Worker ih264d_get_motion_vector_predictor(
891*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred, ps_mv_pred, u1_ref_idx, 0,
892*495ae853SAndroid Build Coastguard Worker (const UWORD8 *)gau1_ih264d_mv_pred_condition);
893*495ae853SAndroid Build Coastguard Worker break;
894*495ae853SAndroid Build Coastguard Worker }
895*495ae853SAndroid Build Coastguard Worker
896*495ae853SAndroid Build Coastguard Worker return (u1_direct_zero_pred_flag);
897*495ae853SAndroid Build Coastguard Worker }
898*495ae853SAndroid Build Coastguard Worker #endif
899*495ae853SAndroid Build Coastguard Worker
900*495ae853SAndroid Build Coastguard Worker /*****************************************************************************/
901*495ae853SAndroid Build Coastguard Worker /* */
902*495ae853SAndroid Build Coastguard Worker /* Function Name : ih264d_mvpred_mbaff */
903*495ae853SAndroid Build Coastguard Worker /* */
904*495ae853SAndroid Build Coastguard Worker /* Description : This function calculates the motion vector predictor, */
905*495ae853SAndroid Build Coastguard Worker /* Inputs : <What inputs does the function take?> */
906*495ae853SAndroid Build Coastguard Worker /* Globals : None */
907*495ae853SAndroid Build Coastguard Worker /* Processing : The neighbours A(Left),B(Top),C(TopRight) are calculated */
908*495ae853SAndroid Build Coastguard Worker /* and based on the type of Mb the prediction is */
909*495ae853SAndroid Build Coastguard Worker /* appropriately done */
910*495ae853SAndroid Build Coastguard Worker /* Outputs : populates ps_mv_final_pred structure */
911*495ae853SAndroid Build Coastguard Worker /* Returns : u1_direct_zero_pred_flag which is used only in */
912*495ae853SAndroid Build Coastguard Worker /* decodeSpatialdirect() */
913*495ae853SAndroid Build Coastguard Worker /* */
914*495ae853SAndroid Build Coastguard Worker /* Issues : <List any issues or problems with this function> */
915*495ae853SAndroid Build Coastguard Worker /* */
916*495ae853SAndroid Build Coastguard Worker /* Revision History: */
917*495ae853SAndroid Build Coastguard Worker /* */
918*495ae853SAndroid Build Coastguard Worker /* DD MM YYYY Author(s) Changes (Describe the changes made) */
919*495ae853SAndroid Build Coastguard Worker /* 03 05 2005 TA First Draft */
920*495ae853SAndroid Build Coastguard Worker /* */
921*495ae853SAndroid Build Coastguard Worker /*****************************************************************************/
922*495ae853SAndroid Build Coastguard Worker
ih264d_mvpred_mbaff(dec_struct_t * ps_dec,dec_mb_info_t * ps_cur_mb_info,mv_pred_t * ps_mv_nmb,mv_pred_t * ps_mv_ntop,mv_pred_t * ps_mv_final_pred,UWORD8 u1_sub_mb_num,UWORD8 uc_mb_part_width,UWORD8 u1_lx_start,UWORD8 u1_lxend,UWORD8 u1_mb_mc_mode)923*495ae853SAndroid Build Coastguard Worker UWORD8 ih264d_mvpred_mbaff(dec_struct_t *ps_dec,
924*495ae853SAndroid Build Coastguard Worker dec_mb_info_t *ps_cur_mb_info,
925*495ae853SAndroid Build Coastguard Worker mv_pred_t *ps_mv_nmb,
926*495ae853SAndroid Build Coastguard Worker mv_pred_t *ps_mv_ntop,
927*495ae853SAndroid Build Coastguard Worker mv_pred_t *ps_mv_final_pred,
928*495ae853SAndroid Build Coastguard Worker UWORD8 u1_sub_mb_num,
929*495ae853SAndroid Build Coastguard Worker UWORD8 uc_mb_part_width,
930*495ae853SAndroid Build Coastguard Worker UWORD8 u1_lx_start,
931*495ae853SAndroid Build Coastguard Worker UWORD8 u1_lxend,
932*495ae853SAndroid Build Coastguard Worker UWORD8 u1_mb_mc_mode)
933*495ae853SAndroid Build Coastguard Worker {
934*495ae853SAndroid Build Coastguard Worker UWORD8 u1_a_in, u1_b_in, uc_temp1, uc_temp2, uc_temp3;
935*495ae853SAndroid Build Coastguard Worker mv_pred_t *ps_mv_pred[3], s_mvPred[3];
936*495ae853SAndroid Build Coastguard Worker UWORD8 uc_B2, pu0_scale[3], i, uc_lx, u1_ref_idx;
937*495ae853SAndroid Build Coastguard Worker UWORD8 u1_direct_zero_pred_flag = 0;
938*495ae853SAndroid Build Coastguard Worker
939*495ae853SAndroid Build Coastguard Worker pu0_scale[0] = pu0_scale[1] = pu0_scale[2] = 0;
940*495ae853SAndroid Build Coastguard Worker ih264d_mbaff_mv_pred(ps_mv_pred, u1_sub_mb_num, ps_mv_nmb, ps_mv_ntop, ps_dec,
941*495ae853SAndroid Build Coastguard Worker uc_mb_part_width, ps_cur_mb_info, pu0_scale);
942*495ae853SAndroid Build Coastguard Worker for(i = 0; i < 3; i++)
943*495ae853SAndroid Build Coastguard Worker {
944*495ae853SAndroid Build Coastguard Worker if(pu0_scale[i] != 0)
945*495ae853SAndroid Build Coastguard Worker {
946*495ae853SAndroid Build Coastguard Worker memcpy(&s_mvPred[i], ps_mv_pred[i], sizeof(mv_pred_t));
947*495ae853SAndroid Build Coastguard Worker if(pu0_scale[i] == 1)
948*495ae853SAndroid Build Coastguard Worker {
949*495ae853SAndroid Build Coastguard Worker s_mvPred[i].i1_ref_frame[0] = s_mvPred[i].i1_ref_frame[0] << 1;
950*495ae853SAndroid Build Coastguard Worker s_mvPred[i].i1_ref_frame[1] = s_mvPred[i].i1_ref_frame[1] << 1;
951*495ae853SAndroid Build Coastguard Worker s_mvPred[i].i2_mv[1] = SIGN_POW2_DIV(s_mvPred[i].i2_mv[1], 1);
952*495ae853SAndroid Build Coastguard Worker s_mvPred[i].i2_mv[3] = SIGN_POW2_DIV(s_mvPred[i].i2_mv[3], 1);
953*495ae853SAndroid Build Coastguard Worker }
954*495ae853SAndroid Build Coastguard Worker else
955*495ae853SAndroid Build Coastguard Worker {
956*495ae853SAndroid Build Coastguard Worker s_mvPred[i].i1_ref_frame[0] = s_mvPred[i].i1_ref_frame[0] >> 1;
957*495ae853SAndroid Build Coastguard Worker s_mvPred[i].i1_ref_frame[1] = s_mvPred[i].i1_ref_frame[1] >> 1;
958*495ae853SAndroid Build Coastguard Worker s_mvPred[i].i2_mv[1] = s_mvPred[i].i2_mv[1] << 1;
959*495ae853SAndroid Build Coastguard Worker s_mvPred[i].i2_mv[3] = s_mvPred[i].i2_mv[3] << 1;
960*495ae853SAndroid Build Coastguard Worker }
961*495ae853SAndroid Build Coastguard Worker ps_mv_pred[i] = &s_mvPred[i];
962*495ae853SAndroid Build Coastguard Worker }
963*495ae853SAndroid Build Coastguard Worker }
964*495ae853SAndroid Build Coastguard Worker
965*495ae853SAndroid Build Coastguard Worker for(uc_lx = u1_lx_start; uc_lx < u1_lxend; uc_lx++)
966*495ae853SAndroid Build Coastguard Worker {
967*495ae853SAndroid Build Coastguard Worker u1_ref_idx = ps_mv_final_pred->i1_ref_frame[uc_lx];
968*495ae853SAndroid Build Coastguard Worker uc_B2 = (uc_lx << 1);
969*495ae853SAndroid Build Coastguard Worker switch(u1_mb_mc_mode)
970*495ae853SAndroid Build Coastguard Worker {
971*495ae853SAndroid Build Coastguard Worker case PRED_16x8:
972*495ae853SAndroid Build Coastguard Worker /* Directional prediction for a 16x8 MB partition */
973*495ae853SAndroid Build Coastguard Worker if(u1_sub_mb_num == 0)
974*495ae853SAndroid Build Coastguard Worker {
975*495ae853SAndroid Build Coastguard Worker /* Calculating the MV pred for the top 16x8 block */
976*495ae853SAndroid Build Coastguard Worker if(ps_mv_pred[TOP]->i1_ref_frame[uc_lx] == u1_ref_idx)
977*495ae853SAndroid Build Coastguard Worker {
978*495ae853SAndroid Build Coastguard Worker /* If the reference frame used by the top subMB is same as the
979*495ae853SAndroid Build Coastguard Worker reference frame used by the current block then MV predictor to
980*495ae853SAndroid Build Coastguard Worker be used for the current block is same as the MV of the top
981*495ae853SAndroid Build Coastguard Worker subMB */
982*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i2_mv[uc_B2 + 0] =
983*495ae853SAndroid Build Coastguard Worker ps_mv_pred[TOP]->i2_mv[uc_B2 + 0];
984*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i2_mv[uc_B2 + 1] =
985*495ae853SAndroid Build Coastguard Worker ps_mv_pred[TOP]->i2_mv[uc_B2 + 1];
986*495ae853SAndroid Build Coastguard Worker }
987*495ae853SAndroid Build Coastguard Worker else
988*495ae853SAndroid Build Coastguard Worker {
989*495ae853SAndroid Build Coastguard Worker /* The MV predictor is calculated according to the process
990*495ae853SAndroid Build Coastguard Worker defined in 8.4.1.2.1 */
991*495ae853SAndroid Build Coastguard Worker ih264d_get_motion_vector_predictor(
992*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred,
993*495ae853SAndroid Build Coastguard Worker ps_mv_pred,
994*495ae853SAndroid Build Coastguard Worker u1_ref_idx,
995*495ae853SAndroid Build Coastguard Worker uc_lx,
996*495ae853SAndroid Build Coastguard Worker (const UWORD8 *)gau1_ih264d_mv_pred_condition);
997*495ae853SAndroid Build Coastguard Worker }
998*495ae853SAndroid Build Coastguard Worker }
999*495ae853SAndroid Build Coastguard Worker else
1000*495ae853SAndroid Build Coastguard Worker {
1001*495ae853SAndroid Build Coastguard Worker if(ps_mv_pred[LEFT]->i1_ref_frame[uc_lx] == u1_ref_idx)
1002*495ae853SAndroid Build Coastguard Worker {
1003*495ae853SAndroid Build Coastguard Worker /* If the reference frame used by the left subMB is same as the
1004*495ae853SAndroid Build Coastguard Worker reference frame used by the current block then MV predictor to
1005*495ae853SAndroid Build Coastguard Worker be used for the current block is same as the MV of the left
1006*495ae853SAndroid Build Coastguard Worker subMB */
1007*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i2_mv[uc_B2 + 0] =
1008*495ae853SAndroid Build Coastguard Worker ps_mv_pred[LEFT]->i2_mv[uc_B2 + 0];
1009*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i2_mv[uc_B2 + 1] =
1010*495ae853SAndroid Build Coastguard Worker ps_mv_pred[LEFT]->i2_mv[uc_B2 + 1];
1011*495ae853SAndroid Build Coastguard Worker }
1012*495ae853SAndroid Build Coastguard Worker else
1013*495ae853SAndroid Build Coastguard Worker {
1014*495ae853SAndroid Build Coastguard Worker /* The MV predictor is calculated according to the process
1015*495ae853SAndroid Build Coastguard Worker defined in 8.4.1.2.1 */
1016*495ae853SAndroid Build Coastguard Worker ih264d_get_motion_vector_predictor(
1017*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred,
1018*495ae853SAndroid Build Coastguard Worker ps_mv_pred,
1019*495ae853SAndroid Build Coastguard Worker u1_ref_idx,
1020*495ae853SAndroid Build Coastguard Worker uc_lx,
1021*495ae853SAndroid Build Coastguard Worker (const UWORD8 *)gau1_ih264d_mv_pred_condition);
1022*495ae853SAndroid Build Coastguard Worker }
1023*495ae853SAndroid Build Coastguard Worker }
1024*495ae853SAndroid Build Coastguard Worker break;
1025*495ae853SAndroid Build Coastguard Worker case PRED_8x16:
1026*495ae853SAndroid Build Coastguard Worker /* Directional prediction for a 8x16 MB partition */
1027*495ae853SAndroid Build Coastguard Worker if(u1_sub_mb_num == 0)
1028*495ae853SAndroid Build Coastguard Worker {
1029*495ae853SAndroid Build Coastguard Worker if(ps_mv_pred[LEFT]->i1_ref_frame[uc_lx] == u1_ref_idx)
1030*495ae853SAndroid Build Coastguard Worker {
1031*495ae853SAndroid Build Coastguard Worker /* If the reference frame used by the left subMB is same as the
1032*495ae853SAndroid Build Coastguard Worker reference frame used by the current block then MV predictor to
1033*495ae853SAndroid Build Coastguard Worker be used for the current block is same as the MV of the left
1034*495ae853SAndroid Build Coastguard Worker subMB */
1035*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i2_mv[uc_B2 + 0] =
1036*495ae853SAndroid Build Coastguard Worker ps_mv_pred[LEFT]->i2_mv[uc_B2 + 0];
1037*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i2_mv[uc_B2 + 1] =
1038*495ae853SAndroid Build Coastguard Worker ps_mv_pred[LEFT]->i2_mv[uc_B2 + 1];
1039*495ae853SAndroid Build Coastguard Worker }
1040*495ae853SAndroid Build Coastguard Worker else
1041*495ae853SAndroid Build Coastguard Worker {
1042*495ae853SAndroid Build Coastguard Worker /* The MV predictor is calculated according to the process
1043*495ae853SAndroid Build Coastguard Worker defined in 8.4.1.2.1 */
1044*495ae853SAndroid Build Coastguard Worker ih264d_get_motion_vector_predictor(
1045*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred,
1046*495ae853SAndroid Build Coastguard Worker ps_mv_pred,
1047*495ae853SAndroid Build Coastguard Worker u1_ref_idx,
1048*495ae853SAndroid Build Coastguard Worker uc_lx,
1049*495ae853SAndroid Build Coastguard Worker (const UWORD8 *)gau1_ih264d_mv_pred_condition);
1050*495ae853SAndroid Build Coastguard Worker }
1051*495ae853SAndroid Build Coastguard Worker }
1052*495ae853SAndroid Build Coastguard Worker else
1053*495ae853SAndroid Build Coastguard Worker {
1054*495ae853SAndroid Build Coastguard Worker if(ps_mv_pred[TOP_R]->i1_ref_frame[uc_lx] == u1_ref_idx)
1055*495ae853SAndroid Build Coastguard Worker {
1056*495ae853SAndroid Build Coastguard Worker /* If the reference frame used by the top right subMB is same as
1057*495ae853SAndroid Build Coastguard Worker the reference frame used by the current block then MV
1058*495ae853SAndroid Build Coastguard Worker predictor to be used for the current block is same as the MV
1059*495ae853SAndroid Build Coastguard Worker of the left subMB */
1060*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i2_mv[uc_B2 + 0] =
1061*495ae853SAndroid Build Coastguard Worker ps_mv_pred[TOP_R]->i2_mv[uc_B2 + 0];
1062*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i2_mv[uc_B2 + 1] =
1063*495ae853SAndroid Build Coastguard Worker ps_mv_pred[TOP_R]->i2_mv[uc_B2 + 1];
1064*495ae853SAndroid Build Coastguard Worker }
1065*495ae853SAndroid Build Coastguard Worker else
1066*495ae853SAndroid Build Coastguard Worker {
1067*495ae853SAndroid Build Coastguard Worker /* The MV predictor is calculated according to the process
1068*495ae853SAndroid Build Coastguard Worker defined in 8.4.1.2.1 */
1069*495ae853SAndroid Build Coastguard Worker ih264d_get_motion_vector_predictor(
1070*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred,
1071*495ae853SAndroid Build Coastguard Worker ps_mv_pred,
1072*495ae853SAndroid Build Coastguard Worker u1_ref_idx,
1073*495ae853SAndroid Build Coastguard Worker uc_lx,
1074*495ae853SAndroid Build Coastguard Worker (const UWORD8 *)gau1_ih264d_mv_pred_condition);
1075*495ae853SAndroid Build Coastguard Worker }
1076*495ae853SAndroid Build Coastguard Worker }
1077*495ae853SAndroid Build Coastguard Worker break;
1078*495ae853SAndroid Build Coastguard Worker case B_DIRECT_SPATIAL:
1079*495ae853SAndroid Build Coastguard Worker /* Case when the MB has been skipped */
1080*495ae853SAndroid Build Coastguard Worker /* If either of left or the top subMB is not present
1081*495ae853SAndroid Build Coastguard Worker OR
1082*495ae853SAndroid Build Coastguard Worker If both the MV components of either the left or the top subMB are
1083*495ae853SAndroid Build Coastguard Worker zero and their reference frame pointer pointing to 0
1084*495ae853SAndroid Build Coastguard Worker then MV for the skipped MB is zero
1085*495ae853SAndroid Build Coastguard Worker else the Median of the mv_pred_t is used */
1086*495ae853SAndroid Build Coastguard Worker uc_temp1 = (UWORD8)ps_mv_pred[LEFT]->i1_ref_frame[0];
1087*495ae853SAndroid Build Coastguard Worker uc_temp2 = (UWORD8)ps_mv_pred[TOP]->i1_ref_frame[0];
1088*495ae853SAndroid Build Coastguard Worker uc_temp3 = (UWORD8)ps_mv_pred[TOP_R]->i1_ref_frame[0];
1089*495ae853SAndroid Build Coastguard Worker
1090*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i1_ref_frame[0] = MIN(uc_temp1,
1091*495ae853SAndroid Build Coastguard Worker MIN(uc_temp2, uc_temp3));
1092*495ae853SAndroid Build Coastguard Worker
1093*495ae853SAndroid Build Coastguard Worker uc_temp1 = (UWORD8)ps_mv_pred[LEFT]->i1_ref_frame[1];
1094*495ae853SAndroid Build Coastguard Worker uc_temp2 = (UWORD8)ps_mv_pred[TOP]->i1_ref_frame[1];
1095*495ae853SAndroid Build Coastguard Worker uc_temp3 = (UWORD8)ps_mv_pred[TOP_R]->i1_ref_frame[1];
1096*495ae853SAndroid Build Coastguard Worker
1097*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i1_ref_frame[1] = MIN(uc_temp1,
1098*495ae853SAndroid Build Coastguard Worker MIN(uc_temp2, uc_temp3));
1099*495ae853SAndroid Build Coastguard Worker
1100*495ae853SAndroid Build Coastguard Worker /* If the reference indices are negative clip the scaled reference indices to -1 */
1101*495ae853SAndroid Build Coastguard Worker /* i.e invalid reference index */
1102*495ae853SAndroid Build Coastguard Worker
1103*495ae853SAndroid Build Coastguard Worker /*if(ps_mv_final_pred->i1_ref_frame[0] < 0)
1104*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i1_ref_frame[0] = -1;
1105*495ae853SAndroid Build Coastguard Worker
1106*495ae853SAndroid Build Coastguard Worker if(ps_mv_final_pred->i1_ref_frame[1] < 0)
1107*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i1_ref_frame[1] = -1; */
1108*495ae853SAndroid Build Coastguard Worker
1109*495ae853SAndroid Build Coastguard Worker if((ps_mv_final_pred->i1_ref_frame[0] < 0)
1110*495ae853SAndroid Build Coastguard Worker && (ps_mv_final_pred->i1_ref_frame[1] < 0))
1111*495ae853SAndroid Build Coastguard Worker {
1112*495ae853SAndroid Build Coastguard Worker u1_direct_zero_pred_flag = 1;
1113*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i1_ref_frame[0] = 0;
1114*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i1_ref_frame[1] = 0;
1115*495ae853SAndroid Build Coastguard Worker }
1116*495ae853SAndroid Build Coastguard Worker ih264d_get_motion_vector_predictor(
1117*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred, ps_mv_pred,
1118*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i1_ref_frame[0], 0,
1119*495ae853SAndroid Build Coastguard Worker (const UWORD8 *)gau1_ih264d_mv_pred_condition);
1120*495ae853SAndroid Build Coastguard Worker
1121*495ae853SAndroid Build Coastguard Worker ih264d_get_motion_vector_predictor(
1122*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred, ps_mv_pred,
1123*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i1_ref_frame[1], 1,
1124*495ae853SAndroid Build Coastguard Worker (const UWORD8 *)gau1_ih264d_mv_pred_condition);
1125*495ae853SAndroid Build Coastguard Worker
1126*495ae853SAndroid Build Coastguard Worker break;
1127*495ae853SAndroid Build Coastguard Worker case MB_SKIP:
1128*495ae853SAndroid Build Coastguard Worker /* Case when the MB has been skipped */
1129*495ae853SAndroid Build Coastguard Worker /* If either of left or the top subMB is not present
1130*495ae853SAndroid Build Coastguard Worker OR
1131*495ae853SAndroid Build Coastguard Worker If both the MV components of either the left or the top subMB are
1132*495ae853SAndroid Build Coastguard Worker zero and their reference frame pointer pointing to 0
1133*495ae853SAndroid Build Coastguard Worker then MV for the skipped MB is zero
1134*495ae853SAndroid Build Coastguard Worker else the Median of the mv_pred_t is used */
1135*495ae853SAndroid Build Coastguard Worker u1_a_in = (ps_cur_mb_info->u1_mb_ngbr_availablity &
1136*495ae853SAndroid Build Coastguard Worker LEFT_MB_AVAILABLE_MASK);
1137*495ae853SAndroid Build Coastguard Worker u1_b_in = (ps_cur_mb_info->u1_mb_ngbr_availablity &
1138*495ae853SAndroid Build Coastguard Worker TOP_MB_AVAILABLE_MASK);
1139*495ae853SAndroid Build Coastguard Worker if(((u1_a_in * u1_b_in) == 0)
1140*495ae853SAndroid Build Coastguard Worker || ((ps_mv_pred[LEFT]->i2_mv[0]
1141*495ae853SAndroid Build Coastguard Worker | ps_mv_pred[LEFT]->i2_mv[1]
1142*495ae853SAndroid Build Coastguard Worker | ps_mv_pred[LEFT]->i1_ref_frame[0])
1143*495ae853SAndroid Build Coastguard Worker == 0)
1144*495ae853SAndroid Build Coastguard Worker || ((ps_mv_pred[TOP]->i2_mv[0]
1145*495ae853SAndroid Build Coastguard Worker | ps_mv_pred[TOP]->i2_mv[1]
1146*495ae853SAndroid Build Coastguard Worker | ps_mv_pred[TOP]->i1_ref_frame[0])
1147*495ae853SAndroid Build Coastguard Worker == 0))
1148*495ae853SAndroid Build Coastguard Worker {
1149*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i2_mv[0] = 0;
1150*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred->i2_mv[1] = 0;
1151*495ae853SAndroid Build Coastguard Worker break;
1152*495ae853SAndroid Build Coastguard Worker }
1153*495ae853SAndroid Build Coastguard Worker /* If the condition above is not true calculate the MV predictor
1154*495ae853SAndroid Build Coastguard Worker according to the process defined in sec 8.4.1.2.1 */
1155*495ae853SAndroid Build Coastguard Worker default:
1156*495ae853SAndroid Build Coastguard Worker ih264d_get_motion_vector_predictor(
1157*495ae853SAndroid Build Coastguard Worker ps_mv_final_pred, ps_mv_pred, u1_ref_idx, uc_lx,
1158*495ae853SAndroid Build Coastguard Worker (const UWORD8 *)gau1_ih264d_mv_pred_condition);
1159*495ae853SAndroid Build Coastguard Worker break;
1160*495ae853SAndroid Build Coastguard Worker }
1161*495ae853SAndroid Build Coastguard Worker }
1162*495ae853SAndroid Build Coastguard Worker return (u1_direct_zero_pred_flag);
1163*495ae853SAndroid Build Coastguard Worker }
1164*495ae853SAndroid Build Coastguard Worker
1165*495ae853SAndroid Build Coastguard Worker
1166*495ae853SAndroid Build Coastguard Worker
1167*495ae853SAndroid Build Coastguard Worker
ih264d_rep_mv_colz(dec_struct_t * ps_dec,mv_pred_t * ps_mv_pred_src,mv_pred_t * ps_mv_pred_dst,UWORD8 u1_sub_mb_num,UWORD8 u1_colz,UWORD8 u1_ht,UWORD8 u1_wd)1168*495ae853SAndroid Build Coastguard Worker void ih264d_rep_mv_colz(dec_struct_t *ps_dec,
1169*495ae853SAndroid Build Coastguard Worker mv_pred_t *ps_mv_pred_src,
1170*495ae853SAndroid Build Coastguard Worker mv_pred_t *ps_mv_pred_dst,
1171*495ae853SAndroid Build Coastguard Worker UWORD8 u1_sub_mb_num,
1172*495ae853SAndroid Build Coastguard Worker UWORD8 u1_colz,
1173*495ae853SAndroid Build Coastguard Worker UWORD8 u1_ht,
1174*495ae853SAndroid Build Coastguard Worker UWORD8 u1_wd)
1175*495ae853SAndroid Build Coastguard Worker {
1176*495ae853SAndroid Build Coastguard Worker
1177*495ae853SAndroid Build Coastguard Worker UWORD8 k, m;
1178*495ae853SAndroid Build Coastguard Worker UWORD8 *pu1_colz = ps_dec->pu1_col_zero_flag + ps_dec->i4_submb_ofst
1179*495ae853SAndroid Build Coastguard Worker + u1_sub_mb_num;
1180*495ae853SAndroid Build Coastguard Worker
1181*495ae853SAndroid Build Coastguard Worker for(k = 0; k < u1_ht; k++)
1182*495ae853SAndroid Build Coastguard Worker {
1183*495ae853SAndroid Build Coastguard Worker for(m = 0; m < u1_wd; m++)
1184*495ae853SAndroid Build Coastguard Worker {
1185*495ae853SAndroid Build Coastguard Worker *(ps_mv_pred_dst + m) = *(ps_mv_pred_src);
1186*495ae853SAndroid Build Coastguard Worker *(pu1_colz + m) = u1_colz;
1187*495ae853SAndroid Build Coastguard Worker
1188*495ae853SAndroid Build Coastguard Worker }
1189*495ae853SAndroid Build Coastguard Worker pu1_colz += SUB_BLK_WIDTH;
1190*495ae853SAndroid Build Coastguard Worker ps_mv_pred_dst += SUB_BLK_WIDTH;
1191*495ae853SAndroid Build Coastguard Worker }
1192*495ae853SAndroid Build Coastguard Worker }
1193*495ae853SAndroid Build Coastguard Worker
1194