1 /******************************************************************************
2  *
3  * Copyright (C) 2015 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************
18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20 /*!
21  **************************************************************************
22  * \file ih264d_inter_pred.c
23  *
24  * \brief
25  *    This file contains routines to perform MotionCompensation tasks
26  *
27  * Detailed_description
28  *
29  * \date
30  *    20/11/2002
31  *
32  * \author  Arvind Raman
33  **************************************************************************
34  */
35 
36 #include <string.h>
37 #include "ih264d_defs.h"
38 #include "ih264d_mvpred.h"
39 #include "ih264d_error_handler.h"
40 #include "ih264d_structs.h"
41 #include "ih264d_defs.h"
42 #include "ih264d_inter_pred.h"
43 #include "ih264_typedefs.h"
44 #include "ih264_macros.h"
45 #include "ih264_platform_macros.h"
46 #include "ih264d_debug.h"
47 #include "ih264d_tables.h"
48 #include "ih264d_mb_utils.h"
49 
50 
51 void ih264d_pad_on_demand(pred_info_t *ps_pred, UWORD8 lum_chrom_blk);
52 
53 
54 
ih264d_copy_multiplex_data(UWORD8 * puc_Source,UWORD8 * puc_To,UWORD32 uc_w,UWORD32 uc_h,UWORD32 ui16_sourceWidth,UWORD32 ui16_toWidth)55 void ih264d_copy_multiplex_data(UWORD8 *puc_Source,
56                                 UWORD8 *puc_To,
57                                 UWORD32 uc_w,
58                                 UWORD32 uc_h,
59                                 UWORD32 ui16_sourceWidth,
60                                 UWORD32 ui16_toWidth)
61 {
62     UWORD8 uc_i, uc_j;
63 
64     for(uc_i = 0; uc_i < uc_h; uc_i++)
65     {
66         memcpy(puc_To, puc_Source, uc_w);
67         puc_To += ui16_toWidth;
68         puc_Source += ui16_sourceWidth;
69     }
70 }
71 
72 
73 /*!
74  **************************************************************************
75  * \if Function name : dma_2d1d \endif
76  *
77  * \brief
78  *    2D -> 1D linear DMA into the reference buffers
79  *
80  * \return
81  *    None
82  **************************************************************************
83  */
ih264d_copy_2d1d(UWORD8 * puc_src,UWORD8 * puc_dest,UWORD16 ui16_srcWidth,UWORD16 ui16_widthToFill,UWORD16 ui16_heightToFill)84 void ih264d_copy_2d1d(UWORD8 *puc_src,
85                       UWORD8 *puc_dest,
86                       UWORD16 ui16_srcWidth,
87                       UWORD16 ui16_widthToFill,
88                       UWORD16 ui16_heightToFill)
89 {
90     UWORD32 uc_w, uc_h;
91     for(uc_h = ui16_heightToFill; uc_h != 0; uc_h--)
92     {
93         memcpy(puc_dest, puc_src, ui16_widthToFill);
94         puc_dest += ui16_widthToFill;
95         puc_src += ui16_srcWidth;
96     }
97 }
98 
99 /*!
100  **************************************************************************
101  * \if Function name : ih264d_fill_pred_info \endif
102  *
103  * \brief
104  *    Fills inter prediction related info
105  *
106  * \return
107  *    None
108  **************************************************************************
109  */
ih264d_fill_pred_info(WORD16 * pi2_mv,WORD32 part_width,WORD32 part_height,WORD32 sub_mb_num,WORD32 pred_dir,pred_info_pkd_t * ps_pred_pkd,WORD8 i1_buf_id,WORD8 i1_ref_idx,UWORD32 * pu4_wt_offset,UWORD8 u1_pic_type)110 void ih264d_fill_pred_info(WORD16 *pi2_mv,WORD32 part_width,WORD32 part_height, WORD32 sub_mb_num,
111                            WORD32 pred_dir,pred_info_pkd_t *ps_pred_pkd,WORD8 i1_buf_id,
112                            WORD8 i1_ref_idx,UWORD32 *pu4_wt_offset,UWORD8 u1_pic_type)
113 {
114     WORD32 insert_bits;
115 
116     ps_pred_pkd->i2_mv[0] = pi2_mv[0];
117     ps_pred_pkd->i2_mv[1] = pi2_mv[1];
118 
119     insert_bits = sub_mb_num & 3; /*sub mb x*/
120     ps_pred_pkd->i1_size_pos_info = insert_bits;
121     insert_bits = sub_mb_num >> 2;/*sub mb y*/
122     ps_pred_pkd->i1_size_pos_info |= insert_bits << 2;
123     insert_bits = part_width >> 1;
124     ps_pred_pkd->i1_size_pos_info |= insert_bits << 4;
125     insert_bits = part_height >> 1;
126     ps_pred_pkd->i1_size_pos_info |= insert_bits << 6;
127 
128     ps_pred_pkd->i1_ref_idx_info = i1_ref_idx;
129     ps_pred_pkd->i1_ref_idx_info |= (pred_dir << 6);
130     ps_pred_pkd->i1_buf_id = i1_buf_id;
131     ps_pred_pkd->pu4_wt_offst = pu4_wt_offset;
132     ps_pred_pkd->u1_pic_type = u1_pic_type;
133 
134 
135 }
136 
137 
138 
139 
140 
141 
142 
143 /*****************************************************************************/
144 /* \if Function name : formMbPartInfo \endif                                 */
145 /*                                                                           */
146 /* \brief                                                                    */
147 /*    Form the Mb partition information structure, to be used by the MC      */
148 /*    routine                                                                */
149 /*                                                                           */
150 /* \return                                                                   */
151 /*    None                                                                   */
152 /* \note                                                                     */
153 /*    c_bufx is used to select PredBuffer,                                   */
154 /*    if it's only Forward/Backward prediction always buffer used is         */
155 /*    puc_MbLumaPredBuffer[0 to X1],pu1_mb_cb_pred_buffer[0 to X1] and          */
156 /*    pu1_mb_cr_pred_buffer[0 to X1]                                            */
157 /*                                                                           */
158 /*    if it's bidirect for forward ..PredBuffer[0 to X1] buffer is used and  */
159 /*    ..PredBuffer[X2 to X3] for backward prediction. and                    */
160 /*                                                                           */
161 /*    Final predicted samples values are the average of ..PredBuffer[0 to X1]*/
162 /*    and ..PredBuffer[X2 to X3]                                             */
163 /*                                                                           */
164 /*    X1 is 255 for Luma and 63 for Chroma                                   */
165 /*    X2 is 256 for Luma and 64 for Chroma                                   */
166 /*    X3 is 511 for Luma and 127 for Chroma                                  */
167 /*                                                                           */
168 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
169 /*         11 05 2005   SWRN            Modified to handle pod               */
170 /*****************************************************************************/
171 
ih264d_form_mb_part_info_bp(pred_info_pkd_t * ps_pred_pkd,dec_struct_t * ps_dec,UWORD16 u2_mb_x,UWORD16 u2_mb_y,WORD32 mb_index,dec_mb_info_t * ps_cur_mb_info)172 WORD32 ih264d_form_mb_part_info_bp(pred_info_pkd_t *ps_pred_pkd,
173                                  dec_struct_t * ps_dec,
174                                  UWORD16 u2_mb_x,
175                                  UWORD16 u2_mb_y,
176                                  WORD32 mb_index,
177                                  dec_mb_info_t *ps_cur_mb_info)
178 {
179     /* The reference buffer pointer */
180     WORD32 i2_frm_x, i2_frm_y;
181     WORD32 i2_tmp_mv_x, i2_tmp_mv_y;
182     WORD32 i2_rec_x, i2_rec_y;
183 
184     WORD32 u2_pic_ht;
185     WORD32 u2_frm_wd;
186     WORD32 u2_rec_wd;
187     UWORD8 u1_sub_x = 0,u1_sub_y=0 ;
188     UWORD8  u1_part_wd = 0,u1_part_ht = 0;
189     WORD16 i2_mv_x,i2_mv_y;
190 
191     /********************************************/
192     /* i1_mc_wd       width reqd for mcomp      */
193     /* u1_dma_ht      height reqd for mcomp     */
194     /* u1_dma_wd      width aligned to 4 bytes  */
195     /* u1_dx          fractional part of width  */
196     /* u1_dx          fractional part of height */
197     /********************************************/
198     UWORD32 i1_mc_wd;
199 
200     WORD32 u1_dma_ht;
201 
202     UWORD32 u1_dma_wd;
203     UWORD32 u1_dx;
204     UWORD32 u1_dy;
205     pred_info_t * ps_pred = ps_dec->ps_pred + ps_dec->u4_pred_info_idx;
206     dec_slice_params_t * const ps_cur_slice = ps_dec->ps_cur_slice;
207     tfr_ctxt_t *ps_frame_buf;
208     struct pic_buffer_t *ps_ref_frm;
209     UWORD8 u1_scale_ref,u1_mbaff,u1_field;
210     pic_buffer_t  **pps_ref_frame;
211     WORD8 i1_size_pos_info,i1_buf_id;
212 
213     PROFILE_DISABLE_MB_PART_INFO()
214 
215      UNUSED(ps_cur_mb_info);
216      i1_size_pos_info = ps_pred_pkd->i1_size_pos_info;
217      GET_XPOS_PRED(u1_sub_x,i1_size_pos_info);
218      GET_YPOS_PRED(u1_sub_y,i1_size_pos_info);
219      GET_WIDTH_PRED(u1_part_wd,i1_size_pos_info);
220      GET_HEIGHT_PRED(u1_part_ht,i1_size_pos_info);
221      i2_mv_x = ps_pred_pkd->i2_mv[0];
222      i2_mv_y = ps_pred_pkd->i2_mv[1];
223      i1_buf_id = ps_pred_pkd->i1_buf_id;
224 
225 
226      ps_ref_frm = ps_dec->apv_buf_id_pic_buf_map[i1_buf_id];
227 
228 
229     {
230         ps_frame_buf = &ps_dec->s_tran_addrecon;
231     }
232 
233 
234     /* Transfer Setup Y */
235     {
236         UWORD8 *pu1_pred, *pu1_rec;
237 
238         /* calculating rounded motion vectors and fractional components */
239         i2_tmp_mv_x = i2_mv_x;
240         i2_tmp_mv_y = i2_mv_y;
241         u1_dx = i2_tmp_mv_x & 0x3;
242         u1_dy = i2_tmp_mv_y & 0x3;
243         i2_tmp_mv_x >>= 2;
244         i2_tmp_mv_y >>= 2;
245         i1_mc_wd = u1_part_wd << 2;
246         u1_dma_ht = u1_part_ht << 2;
247         if(u1_dx)
248         {
249             i2_tmp_mv_x -= 2;
250             i1_mc_wd += 5;
251         }
252         if(u1_dy)
253         {
254             i2_tmp_mv_y -= 2;
255             u1_dma_ht += 5;
256         }
257 
258         /********************************************************************/
259         /* Calulating the horizontal and the vertical u4_ofst from top left  */
260         /* edge of the reference frame, and subsequent clipping             */
261         /********************************************************************/
262         u2_pic_ht = ps_dec->u2_pic_ht;
263         u2_frm_wd = ps_dec->u2_frm_wd_y;
264         i2_rec_x = u1_sub_x << 2;
265         i2_rec_y = u1_sub_y << 2;
266 
267         i2_frm_x = (u2_mb_x << 4) + i2_rec_x + i2_tmp_mv_x;
268         i2_frm_y = (u2_mb_y << 4) + i2_rec_y + i2_tmp_mv_y;
269 
270         i2_frm_x = CLIP3(MAX_OFFSET_OUTSIDE_X_FRM, (ps_dec->u2_pic_wd - 1),
271                          i2_frm_x);
272         i2_frm_y = CLIP3(((1 - u1_dma_ht)), (u2_pic_ht - (1)), i2_frm_y);
273 
274         pu1_pred = ps_ref_frm->pu1_buf1 + i2_frm_y * u2_frm_wd + i2_frm_x;
275 
276         u1_dma_wd = (i1_mc_wd + 3) & 0xFC;
277 
278         /********************************************************************/
279         /* Calulating the horizontal and the vertical u4_ofst from top left  */
280         /* edge of the recon buffer                                         */
281         /********************************************************************/
282         u2_rec_wd = MB_SIZE;
283         {
284             u2_rec_wd = ps_dec->u2_frm_wd_y;
285             i2_rec_x += (mb_index << 4);
286             pu1_rec = ps_frame_buf->pu1_dest_y + i2_rec_y * u2_rec_wd
287                             + i2_rec_x;
288         }
289 
290         /* filling the pred and dma structures for Y */
291         u2_frm_wd = ps_dec->u2_frm_wd_y;
292 
293         ps_pred->u2_u1_ref_buf_wd = u1_dma_wd;
294         ps_pred->i1_dma_ht = u1_dma_ht;
295         ps_pred->i1_mc_wd = i1_mc_wd;
296         ps_pred->u2_frm_wd = u2_frm_wd;
297         ps_pred->pu1_rec_y_u = pu1_rec;
298         ps_pred->u2_dst_stride = u2_rec_wd;
299 
300         ps_pred->i1_mb_partwidth = u1_part_wd << 2;
301         ps_pred->i1_mb_partheight = u1_part_ht << 2;
302         ps_pred->u1_dydx = (u1_dy << 2) + u1_dx;
303 
304         ps_pred->pu1_y_ref = pu1_pred;
305 
306     }
307 
308     /* Increment ps_pred index */
309     ps_pred++;
310 
311     /* Transfer Setup U & V */
312     {
313         WORD32 i4_ref_offset, i4_rec_offset;
314         UWORD8 *pu1_pred_u, *pu1_pred_v;
315 
316 
317         /* calculating rounded motion vectors and fractional components */
318         i2_tmp_mv_x = i2_mv_x;
319         i2_tmp_mv_y = i2_mv_y;
320 
321         /************************************************************************/
322         /* Table 8-9: Derivation of the vertical component of the chroma vector */
323         /* in field coding mode                                                 */
324         /************************************************************************/
325 
326         /* Eighth sample of the chroma MV */
327         u1_dx = i2_tmp_mv_x & 0x7;
328         u1_dy = i2_tmp_mv_y & 0x7;
329 
330         /********************************************************************/
331         /* Calculating the full pel MV for chroma which is 1/2 of the Luma  */
332         /* MV in full pel units                                             */
333         /********************************************************************/
334         i2_mv_x = i2_tmp_mv_x;
335         i2_mv_y = i2_tmp_mv_y;
336         i2_tmp_mv_x = SIGN_POW2_DIV(i2_tmp_mv_x, 3);
337         i2_tmp_mv_y = SIGN_POW2_DIV(i2_tmp_mv_y, 3);
338         i1_mc_wd = u1_part_wd << 1;
339         u1_dma_ht = u1_part_ht << 1;
340         if(u1_dx)
341         {
342             i2_tmp_mv_x -= (i2_mv_x < 0);
343             i1_mc_wd++;
344         }
345         if(u1_dy != 0)
346         {
347             i2_tmp_mv_y -= (i2_mv_y < 0);
348             u1_dma_ht++;
349         }
350 
351         /********************************************************************/
352         /* Calulating the horizontal and the vertical u4_ofst from top left  */
353         /* edge of the reference frame, and subsequent clipping             */
354         /********************************************************************/
355         u2_pic_ht >>= 1;
356         u2_frm_wd = ps_dec->u2_frm_wd_uv;
357         i2_rec_x = u1_sub_x << 1;
358         i2_rec_y = u1_sub_y << 1;
359 
360         i2_frm_x = (u2_mb_x << 3) + i2_rec_x + i2_tmp_mv_x;
361         i2_frm_y = (u2_mb_y << 3) + i2_rec_y + i2_tmp_mv_y;
362 
363         i2_frm_x = CLIP3(MAX_OFFSET_OUTSIDE_UV_FRM,
364                          ((ps_dec->u2_pic_wd >> 1) - 1), i2_frm_x);
365         i2_frm_y = CLIP3(((1 - u1_dma_ht)), (u2_pic_ht - (1)), i2_frm_y);
366 
367         i4_ref_offset = i2_frm_y * u2_frm_wd + i2_frm_x * YUV420SP_FACTOR;
368         u1_dma_wd = (i1_mc_wd + 3) & 0xFC;
369 
370         /********************************************************************/
371         /* Calulating the horizontal and the vertical u4_ofst from top left  */
372         /* edge of the recon buffer                                         */
373         /********************************************************************/
374         /* CHANGED CODE */
375         u2_rec_wd = BLK8x8SIZE * YUV420SP_FACTOR;
376         i4_rec_offset = i2_rec_y * u2_rec_wd + i2_rec_x * YUV420SP_FACTOR;
377 
378         {
379             u2_rec_wd = ps_dec->u2_frm_wd_uv;
380             i2_rec_x += (mb_index << 3);
381             i4_rec_offset = i2_rec_y * u2_rec_wd + i2_rec_x * YUV420SP_FACTOR;
382             ps_pred->pu1_rec_y_u = ps_frame_buf->pu1_dest_u + i4_rec_offset;
383             ps_pred->u1_pi1_wt_ofst_rec_v = ps_frame_buf->pu1_dest_v
384                             + i4_rec_offset;
385         }
386 
387         /* CHANGED CODE */
388 
389         /* filling the common pred structures for U */
390         u2_frm_wd = ps_dec->u2_frm_wd_uv;
391 
392         ps_pred->u2_u1_ref_buf_wd = u1_dma_wd;
393         ps_pred->i1_dma_ht = u1_dma_ht;
394         ps_pred->i1_mc_wd = i1_mc_wd;
395 
396         ps_pred->u2_frm_wd = u2_frm_wd;
397         ps_pred->u2_dst_stride = u2_rec_wd;
398 
399         ps_pred->i1_mb_partwidth = u1_part_wd << 1;
400         ps_pred->i1_mb_partheight = u1_part_ht << 1;
401         ps_pred->u1_dydx = (u1_dy << 3) + u1_dx;
402 
403         pu1_pred_u = ps_ref_frm->pu1_buf2 + i4_ref_offset;
404         pu1_pred_v = ps_ref_frm->pu1_buf3 + i4_ref_offset;
405 
406         /* Copy U & V partitions */
407         ps_pred->pu1_u_ref = pu1_pred_u;
408 
409         /* Increment the reference buffer Index */
410         ps_pred->pu1_v_ref = pu1_pred_v;
411     }
412 
413     /* Increment ps_pred index */
414     ps_dec->u4_pred_info_idx += 2;
415 
416     return OK;
417 
418 }
419 
420 
421 /*****************************************************************************/
422 /* \if Function name : formMbPartInfo \endif                                 */
423 /*                                                                           */
424 /* \brief                                                                    */
425 /*    Form the Mb partition information structure, to be used by the MC      */
426 /*    routine                                                                */
427 /*                                                                           */
428 /* \return                                                                   */
429 /*    None                                                                   */
430 /* \note                                                                     */
431 /*    c_bufx is used to select PredBuffer,                                   */
432 /*    if it's only Forward/Backward prediction always buffer used is         */
433 /*    puc_MbLumaPredBuffer[0 to X1],pu1_mb_cb_pred_buffer[0 to X1] and          */
434 /*    pu1_mb_cr_pred_buffer[0 to X1]                                            */
435 /*                                                                           */
436 /*    if it's bidirect for forward ..PredBuffer[0 to X1] buffer is used and  */
437 /*    ..PredBuffer[X2 to X3] for backward prediction. and                    */
438 /*                                                                           */
439 /*    Final predicted samples values are the average of ..PredBuffer[0 to X1]*/
440 /*    and ..PredBuffer[X2 to X3]                                             */
441 /*                                                                           */
442 /*    X1 is 255 for Luma and 63 for Chroma                                   */
443 /*    X2 is 256 for Luma and 64 for Chroma                                   */
444 /*    X3 is 511 for Luma and 127 for Chroma                                  */
445 /*                                                                           */
446 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
447 /*         11 05 2005   SWRN            Modified to handle pod               */
448 /*****************************************************************************/
ih264d_form_mb_part_info_mp(pred_info_pkd_t * ps_pred_pkd,dec_struct_t * ps_dec,UWORD16 u2_mb_x,UWORD16 u2_mb_y,WORD32 mb_index,dec_mb_info_t * ps_cur_mb_info)449 WORD32 ih264d_form_mb_part_info_mp(pred_info_pkd_t *ps_pred_pkd,
450                                  dec_struct_t * ps_dec,
451                                  UWORD16 u2_mb_x,
452                                  UWORD16 u2_mb_y,
453                                  WORD32 mb_index,
454                                  dec_mb_info_t *ps_cur_mb_info)
455 {
456     /* The reference buffer pointer */
457     UWORD8 *pu1_ref_buf;
458     WORD16 i2_frm_x, i2_frm_y, i2_tmp_mv_x, i2_tmp_mv_y, i2_pod_ht;
459     WORD16 i2_rec_x, i2_rec_y;
460     UWORD16 u2_pic_ht, u2_frm_wd, u2_rec_wd;
461     UWORD8 u1_wght_pred_type, u1_wted_bipred_idc;
462     UWORD16 u2_tot_ref_scratch_size;
463     UWORD8 u1_sub_x = 0;
464     UWORD8 u1_sub_y = 0;
465     UWORD8 u1_is_bi_dir = 0;
466 
467     /********************************************/
468     /* i1_mc_wd       width reqd for mcomp      */
469     /* u1_dma_ht      height reqd for mcomp     */
470     /* u1_dma_wd      width aligned to 4 bytes  */
471     /* u1_dx          fractional part of width  */
472     /* u1_dx          fractional part of height */
473     /********************************************/
474     UWORD8 i1_mc_wd, u1_dma_ht, u1_dma_wd, u1_dx, u1_dy;
475     pred_info_t * ps_pred ;
476     dec_slice_params_t * const ps_cur_slice = ps_dec->ps_cur_slice;
477     const UWORD8 u1_slice_type = ps_cur_slice->u1_slice_type;
478     UWORD8 u1_pod_bot, u1_pod_top;
479 
480     /* load the pictype for pod u4_flag & chroma motion vector derivation */
481     UWORD8 u1_ref_pic_type ;
482 
483     /* set default value to flags specifying field nature of picture & mb */
484     UWORD32 u1_mb_fld = 0, u1_mb_or_pic_fld;
485     UWORD32 u1_mb_bot = 0, u1_pic_bot = 0, u1_mb_or_pic_bot;
486     tfr_ctxt_t *ps_frame_buf;
487     /* calculate flags specifying field nature of picture & mb */
488     const UWORD32 u1_pic_fld = ps_cur_slice->u1_field_pic_flag;
489     WORD8 i1_pred;
490     WORD8 i1_size_pos_info,i1_buf_id,i1_ref_idx;
491     UWORD8 u1_part_wd,u1_part_ht;
492     WORD16 i2_mv_x,i2_mv_y;
493     struct pic_buffer_t *ps_ref_frm;
494     UWORD32 *pu4_wt_offset;
495     UWORD8 *pu1_buf1,*pu1_buf2,*pu1_buf3;
496 
497 
498     PROFILE_DISABLE_MB_PART_INFO()
499 
500     ps_pred = ps_dec->ps_pred + ps_dec->u4_pred_info_idx;
501 
502 
503      i1_size_pos_info = ps_pred_pkd->i1_size_pos_info;
504      GET_XPOS_PRED(u1_sub_x,i1_size_pos_info);
505      GET_YPOS_PRED(u1_sub_y,i1_size_pos_info);
506      GET_WIDTH_PRED(u1_part_wd,i1_size_pos_info);
507      GET_HEIGHT_PRED(u1_part_ht,i1_size_pos_info);
508      i2_mv_x = ps_pred_pkd->i2_mv[0];
509      i2_mv_y = ps_pred_pkd->i2_mv[1];
510      i1_ref_idx = ps_pred_pkd->i1_ref_idx_info & 0x3f;
511      i1_buf_id = ps_pred_pkd->i1_buf_id;
512      ps_ref_frm = ps_dec->apv_buf_id_pic_buf_map[i1_buf_id];
513 
514      i1_pred = (ps_pred_pkd->i1_ref_idx_info & 0xC0) >> 6;
515      u1_is_bi_dir = (i1_pred == BI_PRED);
516 
517 
518     u1_ref_pic_type = ps_pred_pkd->u1_pic_type & PIC_MASK;
519 
520     pu1_buf1  = ps_ref_frm->pu1_buf1;
521     pu1_buf2  = ps_ref_frm->pu1_buf2;
522     pu1_buf3  = ps_ref_frm->pu1_buf3;
523 
524     if(u1_ref_pic_type == BOT_FLD)
525     {
526         pu1_buf1 += ps_ref_frm->u2_frm_wd_y;
527         pu1_buf2 += ps_ref_frm->u2_frm_wd_uv;
528         pu1_buf3 += ps_ref_frm->u2_frm_wd_uv;
529 
530     }
531 
532 
533 
534     if(ps_dec->ps_cur_pps->u1_wted_pred_flag)
535     {
536             pu4_wt_offset = (UWORD32*)&ps_dec->pu4_wt_ofsts[2
537                             * X3(i1_ref_idx)];
538     }
539 
540 
541     pu4_wt_offset = ps_pred_pkd->pu4_wt_offst;
542 
543 
544     /* Pointer to the frame buffer */
545     {
546         ps_frame_buf = &ps_dec->s_tran_addrecon;
547         /* CHANGED CODE */
548     }
549 
550     if(!u1_pic_fld)
551     {
552         u1_mb_fld = ps_cur_mb_info->u1_mb_field_decodingflag;
553         u1_mb_bot = 1 - ps_cur_mb_info->u1_topmb;
554     }
555     else
556         u1_pic_bot = ps_cur_slice->u1_bottom_field_flag;
557 
558     /****************************************************************/
559     /* calculating the flags the tell whether to use frame-padding  */
560     /* or use software pad-on-demand                                */
561     /****************************************************************/
562     u1_mb_or_pic_bot = u1_mb_bot | u1_pic_bot;
563     u1_mb_or_pic_fld = u1_mb_fld | u1_pic_fld;
564     u1_pod_bot = u1_mb_or_pic_fld && (u1_ref_pic_type == TOP_FLD);
565     u1_pod_top = u1_mb_or_pic_fld && (u1_ref_pic_type == BOT_FLD);
566 
567     /* Weighted Pred additions */
568     u1_wted_bipred_idc = ps_dec->ps_cur_pps->u1_wted_bipred_idc;
569 
570     if((u1_slice_type == P_SLICE) || (u1_slice_type == SP_SLICE))
571     {
572         /* P Slice only */
573         u1_wght_pred_type = ps_dec->ps_cur_pps->u1_wted_pred_flag;
574 
575     }
576     else
577     {
578         /* B Slice only */
579         u1_wght_pred_type = 1 + u1_is_bi_dir;
580         if(u1_wted_bipred_idc == 0)
581             u1_wght_pred_type = 0;
582         if((u1_wted_bipred_idc == 2) && (!u1_is_bi_dir))
583             u1_wght_pred_type = 0;
584     }
585     /* load the scratch reference buffer index */
586     pu1_ref_buf = ps_dec->pu1_ref_buff + ps_dec->u4_dma_buf_idx;
587     u2_tot_ref_scratch_size = 0;
588 
589 
590     /* Transfer Setup Y */
591     {
592         UWORD8 *pu1_pred, *pu1_rec;
593         /* calculating rounded motion vectors and fractional components */
594         i2_tmp_mv_x = i2_mv_x;
595         i2_tmp_mv_y = i2_mv_y;
596 
597         u1_dx = i2_tmp_mv_x & 0x3;
598         u1_dy = i2_tmp_mv_y & 0x3;
599         i2_tmp_mv_x >>= 2;
600         i2_tmp_mv_y >>= 2;
601         i1_mc_wd = u1_part_wd << 2;
602         u1_dma_ht = u1_part_ht << 2;
603         if(u1_dx)
604         {
605             i2_tmp_mv_x -= 2;
606             i1_mc_wd += 5;
607         }
608         if(u1_dy)
609         {
610             i2_tmp_mv_y -= 2;
611             u1_dma_ht += 5;
612         }
613 
614         /********************************************************************/
615         /* Calulating the horizontal and the vertical u4_ofst from top left  */
616         /* edge of the reference frame, and subsequent clipping             */
617         /********************************************************************/
618         u2_pic_ht = ps_dec->u2_pic_ht >> u1_pic_fld;
619         u2_frm_wd = ps_dec->u2_frm_wd_y << u1_pic_fld;
620         i2_frm_x = (u2_mb_x << 4) + (u1_sub_x << 2) + i2_tmp_mv_x;
621         i2_frm_y = ((u2_mb_y + (u1_mb_bot && !u1_mb_fld)) << 4)
622                         + (((u1_sub_y << 2) + i2_tmp_mv_y) << u1_mb_fld);
623 
624         i2_frm_x = CLIP3(MAX_OFFSET_OUTSIDE_X_FRM, (ps_dec->u2_pic_wd - 1),
625                          i2_frm_x);
626         i2_frm_y = CLIP3(((1 - u1_dma_ht) << u1_mb_fld),
627                          (u2_pic_ht - (1 << u1_mb_fld)), i2_frm_y);
628 
629         pu1_pred = pu1_buf1 + i2_frm_y * u2_frm_wd + i2_frm_x;
630         u1_dma_wd = (i1_mc_wd + 3) & 0xFC;
631         /********************************************************************/
632         /* Calulating the horizontal and the vertical u4_ofst from top left  */
633         /* edge of the recon buffer                                         */
634         /********************************************************************/
635         /* CHANGED CODE */
636         u2_rec_wd = MB_SIZE;
637         i2_rec_x = u1_sub_x << 2;
638         i2_rec_y = u1_sub_y << 2;
639         {
640             u2_rec_wd = ps_dec->u2_frm_wd_y << u1_mb_or_pic_fld;
641             i2_rec_x += (mb_index << 4);
642             pu1_rec = ps_frame_buf->pu1_dest_y + i2_rec_y * u2_rec_wd
643                             + i2_rec_x;
644             if(u1_mb_bot)
645                 pu1_rec += ps_dec->u2_frm_wd_y << ((u1_mb_fld) ? 0 : 4);
646         }
647 
648         /* CHANGED CODE */
649 
650         /* filling the pred and dma structures for Y */
651         u2_frm_wd = ps_dec->u2_frm_wd_y << u1_mb_or_pic_fld;
652 
653         ps_pred->pu1_dma_dest_addr = pu1_ref_buf;
654         ps_pred->u2_u1_ref_buf_wd = u1_dma_wd;
655         ps_pred->u2_frm_wd = u2_frm_wd;
656         ps_pred->i1_dma_ht = u1_dma_ht;
657         ps_pred->i1_mc_wd = i1_mc_wd;
658         ps_pred->pu1_rec_y_u = pu1_rec;
659         ps_pred->u2_dst_stride = u2_rec_wd;
660 
661         ps_pred->i1_mb_partwidth = u1_part_wd << 2;
662         ps_pred->i1_mb_partheight = u1_part_ht << 2;
663         ps_pred->u1_dydx = (u1_dy << 2) + u1_dx;
664         ps_pred->u1_is_bi_direct = u1_is_bi_dir;
665         ps_pred->u1_pi1_wt_ofst_rec_v = (UWORD8 *)pu4_wt_offset;
666         ps_pred->u1_wght_pred_type = u1_wght_pred_type;
667         ps_pred->i1_pod_ht = 0;
668 
669         /* Increment the Reference buffer Indices */
670         pu1_ref_buf += u1_dma_wd * u1_dma_ht;
671         u2_tot_ref_scratch_size += u1_dma_wd * u1_dma_ht;
672 
673         /* unrestricted field motion comp for top region outside frame */
674         i2_pod_ht = (-i2_frm_y) >> u1_mb_fld;
675         if((i2_pod_ht > 0) && u1_pod_top)
676         {
677             ps_pred->i1_pod_ht = (WORD8)(-i2_pod_ht);
678             u1_dma_ht -= i2_pod_ht;
679             pu1_pred += i2_pod_ht * u2_frm_wd;
680         }
681         /* unrestricted field motion comp for bottom region outside frame */
682         else if(u1_pod_bot)
683         {
684             i2_pod_ht = u1_dma_ht + ((i2_frm_y - u2_pic_ht) >> u1_mb_fld);
685             if(i2_pod_ht > 0)
686             {
687                 u1_dma_ht -= i2_pod_ht;
688                 ps_pred->i1_pod_ht = (WORD8)i2_pod_ht;
689             }
690         }
691 
692         /* Copy Y partition */
693 
694         /*
695          * ps_pred->i1_pod_ht is non zero when MBAFF is present. In case of MBAFF the reference data
696          * is copied in the Scrath buffer so that the padding_on_demand doesnot corrupt the frame data
697          */
698         if(ps_pred->i1_pod_ht)
699         {
700             ps_pred->pu1_pred = pu1_pred;
701             ps_pred->u1_dma_ht_y = u1_dma_ht;
702             ps_pred->u1_dma_wd_y = u1_dma_wd;
703         }
704         ps_pred->pu1_y_ref = pu1_pred;
705     }
706 
707 
708 
709     /* Increment ps_pred index */
710     ps_pred++;
711 
712     /* Transfer Setup U & V */
713     {
714         WORD32 i4_ref_offset, i4_rec_offset;
715         UWORD8 *pu1_pred_u, *pu1_pred_v, u1_tmp_dma_ht;
716         /* CHANGED CODE */
717         UWORD8 u1_chroma_cbp = (UWORD8)(ps_cur_mb_info->u1_cbp >> 4);
718         /* CHANGED CODE */
719 
720         /* calculating rounded motion vectors and fractional components */
721         i2_tmp_mv_x = i2_mv_x;
722         i2_tmp_mv_y = i2_mv_y;
723 
724         /************************************************************************/
725         /* Table 8-9: Derivation of the vertical component of the chroma vector */
726         /* in field coding mode                                                 */
727         /************************************************************************/
728         if(u1_pod_bot && u1_mb_or_pic_bot)
729             i2_tmp_mv_y += 2;
730         if(u1_pod_top && !u1_mb_or_pic_bot)
731             i2_tmp_mv_y -= 2;
732 
733         /* Eighth sample of the chroma MV */
734         u1_dx = i2_tmp_mv_x & 0x7;
735         u1_dy = i2_tmp_mv_y & 0x7;
736 
737         /********************************************************************/
738         /* Calculating the full pel MV for chroma which is 1/2 of the Luma  */
739         /* MV in full pel units                                             */
740         /********************************************************************/
741         i2_mv_x = i2_tmp_mv_x;
742         i2_mv_y = i2_tmp_mv_y;
743         i2_tmp_mv_x = SIGN_POW2_DIV(i2_tmp_mv_x, 3);
744         i2_tmp_mv_y = SIGN_POW2_DIV(i2_tmp_mv_y, 3);
745         i1_mc_wd = u1_part_wd << 1;
746         u1_dma_ht = u1_part_ht << 1;
747         if(u1_dx)
748         {
749             if(i2_mv_x < 0)
750                 i2_tmp_mv_x -= 1;
751             i1_mc_wd++;
752         }
753         if(u1_dy != 0)
754         {
755             if(i2_mv_y < 0)
756                 i2_tmp_mv_y -= 1;
757             u1_dma_ht++;
758         }
759 
760         /********************************************************************/
761         /* Calulating the horizontal and the vertical u4_ofst from top left  */
762         /* edge of the reference frame, and subsequent clipping             */
763         /********************************************************************/
764         u2_pic_ht >>= 1;
765         u2_frm_wd = ps_dec->u2_frm_wd_uv << u1_pic_fld;
766         i2_frm_x = (u2_mb_x << 3) + (u1_sub_x << 1) + i2_tmp_mv_x;
767         i2_frm_y = ((u2_mb_y + (u1_mb_bot && !u1_mb_fld)) << 3)
768                         + (((u1_sub_y << 1) + i2_tmp_mv_y) << u1_mb_fld);
769 
770         i2_frm_x = CLIP3(MAX_OFFSET_OUTSIDE_UV_FRM,
771                          ((ps_dec->u2_pic_wd >> 1) - 1), i2_frm_x);
772         i2_frm_y = CLIP3(((1 - u1_dma_ht) << u1_mb_fld),
773                          (u2_pic_ht - (1 << u1_mb_fld)), i2_frm_y);
774 
775         i4_ref_offset = i2_frm_y * u2_frm_wd + i2_frm_x * YUV420SP_FACTOR;
776         u1_dma_wd = (i1_mc_wd + 3) & 0xFC;
777 
778         /********************************************************************/
779         /* Calulating the horizontal and the vertical u4_ofst from top left  */
780         /* edge of the recon buffer                                         */
781         /********************************************************************/
782         /* CHANGED CODE */
783         u2_rec_wd = BLK8x8SIZE * YUV420SP_FACTOR;
784         i2_rec_x = u1_sub_x << 1;
785         i2_rec_y = u1_sub_y << 1;
786         i4_rec_offset = i2_rec_y * u2_rec_wd + i2_rec_x * YUV420SP_FACTOR;
787         {
788             u2_rec_wd = ps_dec->u2_frm_wd_uv << u1_mb_or_pic_fld;
789 
790             i2_rec_x += (mb_index << 3);
791             i4_rec_offset = i2_rec_y * u2_rec_wd + i2_rec_x * YUV420SP_FACTOR;
792             if(u1_mb_bot)
793                 i4_rec_offset += ps_dec->u2_frm_wd_uv << ((u1_mb_fld) ? 0 : 3);
794             ps_pred->pu1_rec_y_u = ps_frame_buf->pu1_dest_u + i4_rec_offset;
795             ps_pred->u1_pi1_wt_ofst_rec_v = ps_frame_buf->pu1_dest_v
796                             + i4_rec_offset;
797 
798         }
799 
800         /* CHANGED CODE */
801 
802         /* filling the common pred structures for U */
803         u2_frm_wd = ps_dec->u2_frm_wd_uv << u1_mb_or_pic_fld;
804         u1_tmp_dma_ht = u1_dma_ht;
805         ps_pred->u2_u1_ref_buf_wd = u1_dma_wd;
806         ps_pred->u2_frm_wd = u2_frm_wd;
807         ps_pred->i1_dma_ht = u1_dma_ht;
808         ps_pred->i1_mc_wd = i1_mc_wd;
809         ps_pred->u2_dst_stride = u2_rec_wd;
810 
811         ps_pred->i1_mb_partwidth = u1_part_wd << 1;
812         ps_pred->i1_mb_partheight = u1_part_ht << 1;
813         ps_pred->u1_dydx = (u1_dy << 3) + u1_dx;
814         ps_pred->u1_is_bi_direct = u1_is_bi_dir;
815         ps_pred->u1_wght_pred_type = u1_wght_pred_type;
816         ps_pred->i1_pod_ht = 0;
817 
818         ps_pred->pu1_dma_dest_addr = pu1_ref_buf;
819 
820         /* unrestricted field motion comp for top region outside frame */
821         i2_pod_ht = (-i2_frm_y) >> u1_mb_fld;
822         if((i2_pod_ht > 0) && u1_pod_top)
823         {
824             i4_ref_offset += i2_pod_ht * u2_frm_wd;
825             u1_dma_ht -= i2_pod_ht;
826             ps_pred->i1_pod_ht = (WORD8)(-i2_pod_ht);
827         }
828         /* unrestricted field motion comp for bottom region outside frame */
829         else if(u1_pod_bot)
830         {
831             i2_pod_ht = u1_dma_ht + ((i2_frm_y - u2_pic_ht) >> u1_mb_fld);
832             if(i2_pod_ht > 0)
833             {
834                 u1_dma_ht -= i2_pod_ht;
835                 ps_pred->i1_pod_ht = (WORD8)i2_pod_ht;
836             }
837         }
838 
839         pu1_pred_u = pu1_buf2 + i4_ref_offset;
840         pu1_pred_v = pu1_buf3 + i4_ref_offset;
841 
842         /* Copy U & V partitions */
843         if(ps_pred->i1_pod_ht)
844         {
845             ps_pred->pu1_pred_u = pu1_pred_u;
846             ps_pred->u1_dma_ht_uv = u1_dma_ht;
847             ps_pred->u1_dma_wd_uv = u1_dma_wd;
848 
849         }
850         ps_pred->pu1_u_ref = pu1_pred_u;
851 
852         /* Increment the reference buffer Index */
853         u2_tot_ref_scratch_size += (u1_dma_wd * u1_tmp_dma_ht) << 1;
854 
855         if(ps_pred->i1_pod_ht)
856         {
857             ps_pred->pu1_pred_v = pu1_pred_v;
858             ps_pred->u1_dma_ht_uv = u1_dma_ht;
859             ps_pred->u1_dma_wd_uv = u1_dma_wd;
860         }
861 
862         ps_pred->pu1_v_ref = pu1_pred_v;
863     }
864 
865     /* Increment ps_pred index */
866     ps_dec->u4_pred_info_idx += 2;
867 
868 
869     /* Increment the reference buffer Index */
870     ps_dec->u4_dma_buf_idx += u2_tot_ref_scratch_size;
871 
872     if(ps_dec->u4_dma_buf_idx > ps_dec->u4_ref_buf_size)
873         return ERROR_NUM_MV;
874 
875     return OK;
876 
877 
878 
879 }
880 
881 
882 /*!
883  **************************************************************************
884  * \if Function name : MotionCompensate \endif
885  *
886  * \brief
887  *    The routine forms predictor blocks for the entire MB and stores it in
888  *    predictor buffers.This function works only for BASELINE profile
889  *
890  * \param ps_dec: Pointer to the structure decStruct. This is used to get
891  *     pointers to the current and the reference frame and to the MbParams
892  *     structure.
893  *
894  * \return
895  *    None
896  *
897  * \note
898  *    The routine forms predictors for all the luma and the chroma MB
899  *    partitions.
900  **************************************************************************
901  */
902 
ih264d_motion_compensate_bp(dec_struct_t * ps_dec,dec_mb_info_t * ps_cur_mb_info)903 void ih264d_motion_compensate_bp(dec_struct_t * ps_dec, dec_mb_info_t *ps_cur_mb_info)
904 {
905     pred_info_t *ps_pred ;
906     UWORD8 *puc_ref, *pu1_dest_y;
907     UWORD8 *pu1_dest_u;
908     UWORD32 u2_num_pels, u2_ref_wd_y, u2_ref_wd_uv, u2_dst_wd;
909 
910     UWORD32 u4_wd_y, u4_ht_y, u4_wd_uv;
911     UWORD32 u4_ht_uv;
912     UWORD8 *puc_pred0 = (UWORD8 *)(ps_dec->pi2_pred1);
913 
914 
915     PROFILE_DISABLE_INTER_PRED()
916     UNUSED(ps_cur_mb_info);
917     ps_pred = ps_dec->ps_pred ;
918 
919     for(u2_num_pels = 0; u2_num_pels < 256;)
920     {
921         UWORD32 uc_dx, uc_dy;
922         /* Pointer to the destination buffer. If the CBPs of all 8x8 blocks in
923          the MB partition are zero then it would be better to copy the
924          predictor valus directly to the current frame buffer */
925         /*
926          * ps_pred->i1_pod_ht is non zero when MBAFF is present. In case of MBAFF the reference data
927          * is copied in the Scrath buffer so that the padding_on_demand doesnot corrupt the frame data
928          */
929 
930         u2_ref_wd_y = ps_pred->u2_frm_wd;
931         puc_ref = ps_pred->pu1_y_ref;
932         if(ps_pred->u1_dydx & 0x3)
933             puc_ref += 2;
934         if(ps_pred->u1_dydx >> 2)
935             puc_ref += 2 * u2_ref_wd_y;
936 
937         u4_wd_y = ps_pred->i1_mb_partwidth;
938         u4_ht_y = ps_pred->i1_mb_partheight;
939         uc_dx = ps_pred->u1_dydx;
940         uc_dy = uc_dx >> 2;
941         uc_dx &= 0x3;
942 
943         pu1_dest_y = ps_pred->pu1_rec_y_u;
944         u2_dst_wd = ps_pred->u2_dst_stride;
945 
946         ps_dec->apf_inter_pred_luma[ps_pred->u1_dydx](puc_ref, pu1_dest_y,
947                                                       u2_ref_wd_y,
948                                                       u2_dst_wd,
949                                                       u4_ht_y,
950                                                       u4_wd_y, puc_pred0,
951                                                       ps_pred->u1_dydx);
952 
953         ps_pred++;
954 
955         /* Interpolate samples for the chroma components */
956         {
957             UWORD8 *pu1_ref_u;
958 
959             u2_ref_wd_uv = ps_pred->u2_frm_wd;
960             pu1_ref_u = ps_pred->pu1_u_ref;
961 
962             u4_wd_uv = ps_pred->i1_mb_partwidth;
963             u4_ht_uv = ps_pred->i1_mb_partheight;
964             uc_dx = ps_pred->u1_dydx; /* 8*dy + dx */
965             uc_dy = uc_dx >> 3;
966             uc_dx &= 0x7;
967 
968             pu1_dest_u = ps_pred->pu1_rec_y_u;
969             u2_dst_wd = ps_pred->u2_dst_stride;
970 
971             ps_pred++;
972             ps_dec->pf_inter_pred_chroma(pu1_ref_u, pu1_dest_u, u2_ref_wd_uv,
973                                          u2_dst_wd, uc_dx, uc_dy,
974                                          u4_ht_uv, u4_wd_uv);
975 
976         }
977 
978         u2_num_pels += (UWORD8)u4_wd_y * (UWORD8)u4_ht_y;
979 
980     }
981 }
982 
983 
984 /*
985  **************************************************************************
986  * \if Function name : MotionCompensateB \endif
987  *
988  * \brief
989  *    The routine forms predictor blocks for the entire MB and stores it in
990  *    predictor buffers.
991  *
992  * \param ps_dec: Pointer to the structure decStruct. This is used to get
993  *     pointers to the current and the reference frame and to the MbParams
994  *     structure.
995  *
996  * \return
997  *    None
998  *
999  * \note
1000  *    The routine forms predictors for all the luma and the chroma MB
1001  *    partitions.
1002  **************************************************************************
1003  */
1004 
ih264d_motion_compensate_mp(dec_struct_t * ps_dec,dec_mb_info_t * ps_cur_mb_info)1005 void ih264d_motion_compensate_mp(dec_struct_t * ps_dec, dec_mb_info_t *ps_cur_mb_info)
1006 {
1007     pred_info_t *ps_pred ;
1008     pred_info_t *ps_pred_y_forw, *ps_pred_y_back, *ps_pred_cr_forw;
1009     UWORD8 *puc_ref, *pu1_dest_y, *puc_pred0, *puc_pred1;
1010     UWORD8 *pu1_dest_u, *pu1_dest_v;
1011     WORD16 *pi16_intm;
1012     UWORD32 u2_num_pels, u2_ref_wd_y, u2_ref_wd_uv, u2_dst_wd;
1013     UWORD32 u2_dest_wd_y, u2_dest_wd_uv;
1014     UWORD32 u2_row_buf_wd_y = 0;
1015     UWORD32 u2_row_buf_wd_uv = 0;
1016     UWORD32 u2_log2Y_crwd = ps_dec->ps_cur_slice->u2_log2Y_crwd;
1017     UWORD32 u4_wd_y, u4_ht_y, u1_dir, u4_wd_uv;
1018     UWORD32 u4_ht_uv;
1019     UWORD8 *pu1_temp_mc_buffer = ps_dec->pu1_temp_mc_buffer;
1020     WORD32 i2_pod_ht;
1021     UWORD32 u2_pic_ht, u2_frm_wd, u2_rec_wd;
1022     UWORD32 u1_pod_bot, u1_pod_top;
1023     UWORD8 *pu1_pred, *pu1_dma_dst;
1024     UWORD32 u1_dma_wd, u1_dma_ht;
1025 
1026     dec_slice_params_t * const ps_cur_slice = ps_dec->ps_cur_slice;
1027 
1028     /* set default value to flags specifying field nature of picture & mb */
1029     UWORD32 u1_mb_fld = 0, u1_mb_or_pic_fld;
1030     UWORD32 u1_mb_or_pic_bot;
1031     /* calculate flags specifying field nature of picture & mb */
1032     const UWORD8 u1_pic_fld = ps_cur_slice->u1_field_pic_flag;
1033 
1034     PROFILE_DISABLE_INTER_PRED()
1035     ps_pred = ps_dec->ps_pred ;
1036     /* Initialize both ps_pred_y_forw, ps_pred_cr_forw and ps_pred_y_back
1037      * to avoid static analysis warnings */
1038     ps_pred_y_forw = ps_pred;
1039     ps_pred_y_back = ps_pred;
1040     ps_pred_cr_forw = ps_pred;
1041 
1042     if(ps_dec->u1_separate_parse)
1043         u2_log2Y_crwd = ps_dec->ps_decode_cur_slice->u2_log2Y_crwd;
1044 
1045     if(!u1_pic_fld)
1046     {
1047         u1_mb_fld = ps_cur_mb_info->u1_mb_field_decodingflag;
1048     }
1049 
1050     u1_mb_or_pic_fld = u1_mb_fld | u1_pic_fld;
1051 
1052     pi16_intm = ps_dec->pi2_pred1;
1053     puc_pred0 = (UWORD8 *)pi16_intm;
1054     puc_pred1 = puc_pred0 + PRED_BUFFER_WIDTH * PRED_BUFFER_HEIGHT * sizeof(WORD16);
1055 
1056     for(u2_num_pels = 0; u2_num_pels < 256;)
1057     {
1058         UWORD8 uc_dx, uc_dy;
1059         const UWORD8 u1_is_bi_direct = ps_pred->u1_is_bi_direct;
1060         for(u1_dir = 0; u1_dir <= u1_is_bi_direct; u1_dir++)
1061         {
1062             /* Pointer to the destination buffer. If the CBPs of all 8x8 blocks in
1063              the MB partition are zero then it would be better to copy the
1064              predictor valus directly to the current frame buffer */
1065             /*
1066              * ps_pred->i1_pod_ht is non zero when MBAFF is present. In case of MBAFF the reference data
1067              * is copied in the Scrath buffer so that the padding_on_demand doesnot corrupt the frame data
1068              */
1069 
1070             if(ps_pred->i1_pod_ht)
1071             {
1072                 u2_ref_wd_y = ps_pred->u2_u1_ref_buf_wd;
1073                 puc_ref = ps_pred->pu1_dma_dest_addr;
1074             }
1075             else
1076             {
1077                 u2_ref_wd_y = ps_pred->u2_frm_wd;
1078                 puc_ref = ps_pred->pu1_y_ref;
1079 
1080             }
1081 
1082             if(ps_pred->u1_dydx & 0x3)
1083                 puc_ref += 2;
1084             if(ps_pred->u1_dydx >> 2)
1085                 puc_ref += 2 * u2_ref_wd_y;
1086             u4_wd_y = ps_pred->i1_mb_partwidth;
1087             u4_ht_y = ps_pred->i1_mb_partheight;
1088 
1089             uc_dx = ps_pred->u1_dydx;
1090             uc_dy = uc_dx >> 2;
1091             uc_dx &= 0x3;
1092             if(u1_dir == 0)
1093             {
1094                 pu1_dest_y = ps_pred->pu1_rec_y_u;
1095                 u2_row_buf_wd_y = ps_pred->u2_dst_stride;
1096                 u2_dst_wd = ps_pred->u2_dst_stride;
1097                 u2_dest_wd_y = u2_dst_wd;
1098                 ps_pred_y_forw = ps_pred;
1099             }
1100             else
1101             {
1102                 pu1_dest_y = pu1_temp_mc_buffer;
1103                 u2_dst_wd = MB_SIZE;
1104                 u2_dest_wd_y = u2_dst_wd;
1105                 ps_pred_y_back = ps_pred;
1106                 ps_pred_y_back->pu1_rec_y_u = pu1_dest_y;
1107             }
1108 
1109             /* padding on demand (POD) for y done here */
1110 
1111             if(ps_pred->i1_pod_ht)
1112             {
1113                 pu1_pred = ps_pred->pu1_pred;
1114                 pu1_dma_dst = ps_pred->pu1_dma_dest_addr;
1115                 u1_dma_wd = ps_pred->u1_dma_wd_y;
1116                 u1_dma_ht = ps_pred->u1_dma_ht_y;
1117                 u2_frm_wd = ps_dec->u2_frm_wd_y << u1_mb_or_pic_fld;
1118                 if(ps_pred->i1_pod_ht < 0)
1119                 {
1120                     pu1_dma_dst = pu1_dma_dst - (ps_pred->i1_pod_ht * ps_pred->u2_u1_ref_buf_wd);
1121                 }
1122                 ih264d_copy_2d1d(pu1_pred, pu1_dma_dst, u2_frm_wd, u1_dma_wd,
1123                                  u1_dma_ht);
1124                 ih264d_pad_on_demand(ps_pred, LUM_BLK);
1125             }
1126             ps_dec->apf_inter_pred_luma[ps_pred->u1_dydx](puc_ref, pu1_dest_y,
1127                                                           u2_ref_wd_y,
1128                                                           u2_dst_wd,
1129                                                           u4_ht_y,
1130                                                           u4_wd_y,
1131                                                           puc_pred0,
1132                                                           ps_pred->u1_dydx);
1133             ps_pred++;
1134 
1135             /* Interpolate samples for the chroma components */
1136             {
1137                 UWORD8 *pu1_ref_u;
1138                 UWORD32 u1_dma_ht;
1139 
1140                 /* padding on demand (POD) for U and V done here */
1141                 u1_dma_ht = ps_pred->i1_dma_ht;
1142 
1143                 if(ps_pred->i1_pod_ht)
1144                 {
1145                     pu1_pred = ps_pred->pu1_pred_u;
1146                     pu1_dma_dst = ps_pred->pu1_dma_dest_addr;
1147                     u1_dma_ht = ps_pred->u1_dma_ht_uv;
1148                     u1_dma_wd = ps_pred->u1_dma_wd_uv * YUV420SP_FACTOR;
1149                     u2_frm_wd = ps_dec->u2_frm_wd_uv << u1_mb_or_pic_fld;
1150                     if(ps_pred->i1_pod_ht < 0)
1151                     {
1152                         /*Top POD*/
1153                         pu1_dma_dst -= (ps_pred->i1_pod_ht
1154                                         * ps_pred->u2_u1_ref_buf_wd
1155                                         * YUV420SP_FACTOR);
1156                     }
1157 
1158                     ih264d_copy_2d1d(pu1_pred, pu1_dma_dst, u2_frm_wd,
1159                                      u1_dma_wd, u1_dma_ht);
1160 
1161                     pu1_dma_dst += (ps_pred->i1_dma_ht
1162                                     * ps_pred->u2_u1_ref_buf_wd);
1163                     pu1_pred = ps_pred->pu1_pred_v;
1164 
1165                     ih264d_pad_on_demand(ps_pred, CHROM_BLK);
1166                 }
1167 
1168                 if(ps_pred->i1_pod_ht)
1169                 {
1170                     pu1_ref_u = ps_pred->pu1_dma_dest_addr;
1171 
1172                     u2_ref_wd_uv = ps_pred->u2_u1_ref_buf_wd
1173                                     * YUV420SP_FACTOR;
1174                 }
1175                 else
1176                 {
1177                     u2_ref_wd_uv = ps_pred->u2_frm_wd;
1178                     pu1_ref_u = ps_pred->pu1_u_ref;
1179 
1180                 }
1181 
1182                 u4_wd_uv = ps_pred->i1_mb_partwidth;
1183                 u4_ht_uv = ps_pred->i1_mb_partheight;
1184                 uc_dx = ps_pred->u1_dydx; /* 8*dy + dx */
1185                 uc_dy = uc_dx >> 3;
1186                 uc_dx &= 0x7;
1187                 if(u1_dir == 0)
1188                 {
1189                     pu1_dest_u = ps_pred->pu1_rec_y_u;
1190 
1191                     pu1_dest_v = ps_pred->u1_pi1_wt_ofst_rec_v;
1192                     u2_row_buf_wd_uv = ps_pred->u2_dst_stride;
1193                     u2_dst_wd = ps_pred->u2_dst_stride;
1194                     u2_dest_wd_uv = u2_dst_wd;
1195                     ps_pred_cr_forw = ps_pred;
1196                 }
1197                 else
1198                 {
1199                     pu1_dest_u = puc_pred0;
1200 
1201                     pu1_dest_v = puc_pred1;
1202                     u2_dest_wd_uv = BUFFER_WIDTH;
1203                     u2_dst_wd = BUFFER_WIDTH;
1204                     ps_pred->pu1_rec_y_u = pu1_dest_u;
1205                     ps_pred->u1_pi1_wt_ofst_rec_v = pu1_dest_v;
1206                 }
1207 
1208                 ps_pred++;
1209                 ps_dec->pf_inter_pred_chroma(pu1_ref_u, pu1_dest_u,
1210                                              u2_ref_wd_uv, u2_dst_wd,
1211                                              uc_dx, uc_dy, u4_ht_uv,
1212                                              u4_wd_uv);
1213 
1214                 if(ps_cur_mb_info->u1_Mux == 1)
1215                 {
1216                     /******************************************************************/
1217                     /* padding on demand (POD) for U and V done here                  */
1218                     /* ps_pred now points to the Y entry of the 0,0 component         */
1219                     /* Y need not be checked for POD because Y lies within            */
1220                     /* the picture((0,0) mv for Y doesnot get changed. But (0,0) for  */
1221                     /* U and V can need POD beacause of cross-field mv adjustments    */
1222                     /* (Table 8-9 of standard)                                        */
1223                     /******************************************************************/
1224                     if((ps_pred + 1)->i1_pod_ht)
1225                     {
1226                         pu1_pred = (ps_pred + 1)->pu1_pred_u;
1227                         pu1_dma_dst = (ps_pred + 1)->pu1_dma_dest_addr;
1228                         u1_dma_ht = (ps_pred + 1)->u1_dma_ht_uv;
1229                         u1_dma_wd = (ps_pred + 1)->u1_dma_wd_uv
1230                                         * YUV420SP_FACTOR;
1231                         u2_frm_wd = ps_dec->u2_frm_wd_uv << u1_mb_or_pic_fld;
1232                         if((ps_pred + 1)->i1_pod_ht < 0)
1233                         {
1234                             /*Top POD*/
1235                             pu1_dma_dst -= ((ps_pred + 1)->i1_pod_ht
1236                                             * (ps_pred + 1)->u2_u1_ref_buf_wd
1237                                             * YUV420SP_FACTOR);
1238                         }
1239                         ih264d_copy_2d1d(pu1_pred, pu1_dma_dst, u2_frm_wd,
1240                                          u1_dma_wd, u1_dma_ht);
1241                         pu1_dma_dst += ((ps_pred + 1)->i1_dma_ht
1242                                         * (ps_pred + 1)->u2_u1_ref_buf_wd); //(u1_dma_ht * u1_dma_wd);//
1243                         pu1_pred = (ps_pred + 1)->pu1_pred_v;
1244                         ih264d_pad_on_demand(ps_pred + 1, CHROM_BLK);
1245 
1246                     }
1247 
1248                     ih264d_multiplex_ref_data(ps_dec, ps_pred, pu1_dest_y,
1249                                               pu1_dest_u, ps_cur_mb_info,
1250                                               u2_dest_wd_y, u2_dest_wd_uv,
1251                                               u1_dir);
1252                     ps_pred += 2;
1253                 }
1254             }
1255         }
1256         if(u1_dir != 0)
1257             u2_ref_wd_y = MB_SIZE;
1258 
1259         u2_num_pels += u4_wd_y * u4_ht_y;
1260         /* if BI_DIRECT, average the two pred's, and put in ..PredBuffer[0] */
1261         if((u1_is_bi_direct != 0) || (ps_pred_y_forw->u1_wght_pred_type != 0))
1262         {
1263 
1264             switch(ps_pred_y_forw->u1_wght_pred_type)
1265             {
1266                 case 0:
1267                     ps_dec->pf_default_weighted_pred_luma(
1268                                     ps_pred_y_forw->pu1_rec_y_u, pu1_dest_y,
1269                                     ps_pred_y_forw->pu1_rec_y_u,
1270                                     u2_row_buf_wd_y, u2_ref_wd_y,
1271                                     u2_row_buf_wd_y, u4_ht_uv * 2,
1272                                     u4_wd_uv * 2);
1273 
1274                     ps_dec->pf_default_weighted_pred_chroma(
1275                                     ps_pred_cr_forw->pu1_rec_y_u, pu1_dest_u,
1276                                     ps_pred_cr_forw->pu1_rec_y_u,
1277                                     u2_row_buf_wd_uv, u2_dst_wd,
1278                                     u2_row_buf_wd_uv, u4_ht_uv,
1279                                     u4_wd_uv);
1280 
1281                     break;
1282                 case 1:
1283                 {
1284                     UWORD32 *pu4_weight_ofst =
1285                                     (UWORD32*)ps_pred_y_forw->u1_pi1_wt_ofst_rec_v;
1286                     UWORD32 u4_wt_ofst_u, u4_wt_ofst_v;
1287                     UWORD32 u4_wt_ofst_y =
1288                                     (UWORD32)(pu4_weight_ofst[0]);
1289                     WORD32 weight = (WORD16)(u4_wt_ofst_y & 0xffff);
1290                     WORD32 ofst = (WORD8)(u4_wt_ofst_y >> 16);
1291 
1292                     ps_dec->pf_weighted_pred_luma(ps_pred_y_forw->pu1_rec_y_u,
1293                                                   ps_pred_y_forw->pu1_rec_y_u,
1294                                                   u2_row_buf_wd_y,
1295                                                   u2_row_buf_wd_y,
1296                                                   (u2_log2Y_crwd & 0x0ff),
1297                                                   weight, ofst, u4_ht_y,
1298                                                   u4_wd_y);
1299 
1300                     u4_wt_ofst_u = (UWORD32)(pu4_weight_ofst[2]);
1301                     u4_wt_ofst_v = (UWORD32)(pu4_weight_ofst[4]);
1302                     weight = ((u4_wt_ofst_v & 0xffff) << 16)
1303                                     | (u4_wt_ofst_u & 0xffff);
1304                     ofst = ((u4_wt_ofst_v >> 16) << 8)
1305                                     | ((u4_wt_ofst_u >> 16) & 0xFF);
1306 
1307                     ps_dec->pf_weighted_pred_chroma(
1308                                     ps_pred_cr_forw->pu1_rec_y_u,
1309                                     ps_pred_cr_forw->pu1_rec_y_u,
1310                                     u2_row_buf_wd_uv, u2_row_buf_wd_uv,
1311                                     (u2_log2Y_crwd >> 8), weight, ofst,
1312                                     u4_ht_y >> 1, u4_wd_y >> 1);
1313                 }
1314 
1315                     break;
1316                 case 2:
1317                 {
1318                     UWORD32 *pu4_weight_ofst =
1319                                     (UWORD32*)ps_pred_y_forw->u1_pi1_wt_ofst_rec_v;
1320                     UWORD32 u4_wt_ofst_u, u4_wt_ofst_v;
1321                     UWORD32 u4_wt_ofst_y;
1322                     WORD32 weight1, weight2;
1323                     WORD32 ofst1, ofst2;
1324 
1325                     u4_wt_ofst_y = (UWORD32)(pu4_weight_ofst[0]);
1326 
1327                     weight1 = (WORD16)(u4_wt_ofst_y & 0xffff);
1328                     ofst1 = (WORD8)(u4_wt_ofst_y >> 16);
1329 
1330                     u4_wt_ofst_y = (UWORD32)(pu4_weight_ofst[1]);
1331                     weight2 = (WORD16)(u4_wt_ofst_y & 0xffff);
1332                     ofst2 = (WORD8)(u4_wt_ofst_y >> 16);
1333 
1334                     ps_dec->pf_weighted_bi_pred_luma(ps_pred_y_forw->pu1_rec_y_u,
1335                                                      ps_pred_y_back->pu1_rec_y_u,
1336                                                      ps_pred_y_forw->pu1_rec_y_u,
1337                                                      u2_row_buf_wd_y,
1338                                                      u2_ref_wd_y,
1339                                                      u2_row_buf_wd_y,
1340                                                      (u2_log2Y_crwd & 0x0ff),
1341                                                      weight1, weight2, ofst1,
1342                                                      ofst2, u4_ht_y,
1343                                                      u4_wd_y);
1344 
1345                     u4_wt_ofst_u = (UWORD32)(pu4_weight_ofst[2]);
1346                     u4_wt_ofst_v = (UWORD32)(pu4_weight_ofst[4]);
1347                     weight1 = ((u4_wt_ofst_v & 0xffff) << 16)
1348                                     | (u4_wt_ofst_u & 0xffff);
1349                     ofst1 = ((u4_wt_ofst_v >> 16) << 8)
1350                                     | ((u4_wt_ofst_u >> 16) & 0xFF);
1351 
1352                     u4_wt_ofst_u = (UWORD32)(pu4_weight_ofst[3]);
1353                     u4_wt_ofst_v = (UWORD32)(pu4_weight_ofst[5]);
1354                     weight2 = ((u4_wt_ofst_v & 0xffff) << 16)
1355                                     | (u4_wt_ofst_u & 0xffff);
1356                     ofst2 = ((u4_wt_ofst_v >> 16) << 8)
1357                                     | ((u4_wt_ofst_u >> 16) & 0xFF);
1358 
1359                     ps_dec->pf_weighted_bi_pred_chroma(
1360                                     (ps_pred_y_forw + 1)->pu1_rec_y_u,
1361                                     (ps_pred_y_back + 1)->pu1_rec_y_u,
1362                                     (ps_pred_y_forw + 1)->pu1_rec_y_u,
1363                                     u2_row_buf_wd_uv, u2_dst_wd,
1364                                     u2_row_buf_wd_uv, (u2_log2Y_crwd >> 8),
1365                                     weight1, weight2, ofst1, ofst2,
1366                                     u4_ht_y >> 1, u4_wd_y >> 1);
1367                 }
1368 
1369                     break;
1370             }
1371 
1372         }
1373     }
1374 }
1375 
1376 
1377 /*!
1378  **************************************************************************
1379  * \if Function name : ih264d_multiplex_ref_data \endif
1380  *
1381  * \brief
1382  *    Initializes forward and backward refernce lists for B slice decoding.
1383  *
1384  *
1385  * \return
1386  *    0 on Success and Error code otherwise
1387  **************************************************************************
1388  */
1389 
ih264d_multiplex_ref_data(dec_struct_t * ps_dec,pred_info_t * ps_pred,UWORD8 * pu1_dest_y,UWORD8 * pu1_dest_u,dec_mb_info_t * ps_cur_mb_info,UWORD16 u2_dest_wd_y,UWORD16 u2_dest_wd_uv,UWORD8 u1_dir)1390 void ih264d_multiplex_ref_data(dec_struct_t * ps_dec,
1391                                pred_info_t *ps_pred,
1392                                UWORD8* pu1_dest_y,
1393                                UWORD8* pu1_dest_u,
1394                                dec_mb_info_t *ps_cur_mb_info,
1395                                UWORD16 u2_dest_wd_y,
1396                                UWORD16 u2_dest_wd_uv,
1397                                UWORD8 u1_dir)
1398 {
1399     UWORD16 u2_mask = ps_cur_mb_info->u2_mask[u1_dir];
1400     UWORD8 *pu1_ref_y, *pu1_ref_u;
1401     UWORD8 uc_cond, i, j, u1_dydx;
1402     UWORD16 u2_ref_wd_y, u2_ref_wd_uv;
1403 
1404     PROFILE_DISABLE_INTER_PRED()
1405 
1406     if(ps_pred->i1_pod_ht)
1407     {
1408         pu1_ref_y = ps_pred->pu1_dma_dest_addr;
1409 
1410         u2_ref_wd_y = ps_pred->u2_u1_ref_buf_wd;
1411     }
1412     else
1413     {
1414         pu1_ref_y = ps_pred->pu1_y_ref;
1415         u2_ref_wd_y = ps_pred->u2_frm_wd;
1416     }
1417 
1418     ps_pred++;
1419     if(ps_pred->i1_pod_ht)
1420     {
1421         pu1_ref_u = ps_pred->pu1_dma_dest_addr;
1422         u2_ref_wd_uv = ps_pred->u2_u1_ref_buf_wd * YUV420SP_FACTOR;
1423 
1424     }
1425     else
1426     {
1427         pu1_ref_u = ps_pred->pu1_u_ref;
1428         u2_ref_wd_uv = ps_pred->u2_frm_wd;
1429 
1430     }
1431 
1432     u1_dydx = ps_pred->u1_dydx;
1433 
1434     {
1435         UWORD8 uc_dx, uc_dy;
1436         UWORD8 *pu1_scratch_u;
1437 
1438         uc_dx = u1_dydx & 0x3;
1439         uc_dy = u1_dydx >> 3;
1440         if(u1_dydx != 0)
1441         {
1442             pred_info_t * ps_prv_pred = ps_pred - 2;
1443             pu1_scratch_u = ps_prv_pred->pu1_dma_dest_addr;
1444             ps_dec->pf_inter_pred_chroma(pu1_ref_u, pu1_scratch_u,
1445                                          u2_ref_wd_uv, 16, uc_dx, uc_dy, 8,
1446                                          8);
1447 
1448             /* Modify ref pointer and refWidth to point to scratch    */
1449             /* buffer to be used below in ih264d_copy_multiplex_data functions */
1450             /* CHANGED CODE */
1451             pu1_ref_u = pu1_scratch_u;
1452             u2_ref_wd_uv = 8 * YUV420SP_FACTOR;
1453         }
1454     }
1455     {
1456         for(i = 0; i < 4; i++)
1457         {
1458             for(j = 0; j < 4; j++)
1459             {
1460                 uc_cond = u2_mask & 1;
1461                 u2_mask >>= 1;
1462                 if(uc_cond)
1463                 {
1464                     *(UWORD32 *)(pu1_dest_y + u2_dest_wd_y) =
1465                                     *(UWORD32 *)(pu1_ref_y + u2_ref_wd_y);
1466                     *(UWORD32 *)(pu1_dest_y + 2 * u2_dest_wd_y) =
1467                                     *(UWORD32 *)(pu1_ref_y + 2 * u2_ref_wd_y);
1468                     *(UWORD32 *)(pu1_dest_y + 3 * u2_dest_wd_y) =
1469                                     *(UWORD32 *)(pu1_ref_y + 3 * u2_ref_wd_y);
1470                     {
1471                         UWORD32 *dst, *src;
1472                         dst = (UWORD32 *)pu1_dest_y;
1473                         src = (UWORD32 *)pu1_ref_y;
1474                         *dst = *src;
1475                         dst++;
1476                         src++;
1477                         pu1_dest_y = (UWORD8 *)dst;
1478                         pu1_ref_y = (UWORD8 *)src;
1479                     }
1480                     *(UWORD32 *)(pu1_dest_u + u2_dest_wd_uv) =
1481                                     *(UWORD32 *)(pu1_ref_u + u2_ref_wd_uv);
1482                     {
1483                         UWORD32 *dst, *src;
1484                         dst = (UWORD32 *)pu1_dest_u;
1485                         src = (UWORD32 *)pu1_ref_u;
1486                         *dst = *src;
1487                         dst++;
1488                         src++;
1489                         pu1_dest_u = (UWORD8 *)dst;
1490                         pu1_ref_u = (UWORD8 *)src;
1491                     }
1492 
1493                 }
1494                 else
1495                 {
1496                     pu1_dest_y += 4;
1497                     pu1_ref_y += 4;
1498                     pu1_dest_u += 2 * YUV420SP_FACTOR;
1499                     pu1_ref_u += 2 * YUV420SP_FACTOR;
1500                 }
1501             }
1502             pu1_ref_y += 4 * (u2_ref_wd_y - 4);
1503             pu1_ref_u += 2 * (u2_ref_wd_uv - 4 * YUV420SP_FACTOR);
1504             pu1_dest_y += 4 * (u2_dest_wd_y - 4);
1505             pu1_dest_u += 2 * (u2_dest_wd_uv - 4 * YUV420SP_FACTOR);
1506         }
1507     }
1508 }
1509 
ih264d_pad_on_demand(pred_info_t * ps_pred,UWORD8 lum_chrom_blk)1510 void ih264d_pad_on_demand(pred_info_t *ps_pred, UWORD8 lum_chrom_blk)
1511 {
1512     if(CHROM_BLK == lum_chrom_blk)
1513     {
1514         UWORD32 *pu4_pod_src_u, *pu4_pod_dst_u;
1515         UWORD32 *pu4_pod_src_v, *pu4_pod_dst_v;
1516         WORD32 j, u1_wd_stride;
1517         WORD32 i, u1_dma_ht, i1_ht;
1518         UWORD32 u2_dma_size;
1519         u1_wd_stride = (ps_pred->u2_u1_ref_buf_wd >> 2) * YUV420SP_FACTOR;
1520         u1_dma_ht = ps_pred->i1_dma_ht;
1521         u2_dma_size = u1_wd_stride * u1_dma_ht;
1522         pu4_pod_src_u = (UWORD32 *)ps_pred->pu1_dma_dest_addr;
1523         pu4_pod_dst_u = pu4_pod_src_u;
1524 
1525         pu4_pod_src_v = pu4_pod_src_u + u2_dma_size;
1526         pu4_pod_dst_v = pu4_pod_src_v;
1527 
1528         i1_ht = ps_pred->i1_pod_ht;
1529         pu4_pod_src_u -= u1_wd_stride * i1_ht;
1530         pu4_pod_src_v -= u1_wd_stride * i1_ht;
1531         if(i1_ht < 0)
1532             /* Top POD */
1533             i1_ht = -i1_ht;
1534         else
1535         {
1536             /* Bottom POD */
1537             pu4_pod_src_u += (u1_dma_ht - 1) * u1_wd_stride;
1538             pu4_pod_dst_u += (u1_dma_ht - i1_ht) * u1_wd_stride;
1539             pu4_pod_src_v += (u1_dma_ht - 1) * u1_wd_stride;
1540             pu4_pod_dst_v += (u1_dma_ht - i1_ht) * u1_wd_stride;
1541         }
1542 
1543         for(i = 0; i < i1_ht; i++)
1544             for(j = 0; j < u1_wd_stride; j++)
1545             {
1546                 *pu4_pod_dst_u++ = *(pu4_pod_src_u + j);
1547 
1548             }
1549     }
1550     else
1551     {
1552         UWORD32 *pu4_pod_src, *pu4_pod_dst;
1553         WORD32 j, u1_wd_stride;
1554         WORD32 i, i1_ht;
1555         pu4_pod_src = (UWORD32 *)ps_pred->pu1_dma_dest_addr;
1556         pu4_pod_dst = pu4_pod_src;
1557         u1_wd_stride = ps_pred->u2_u1_ref_buf_wd >> 2;
1558         i1_ht = ps_pred->i1_pod_ht;
1559         pu4_pod_src -= u1_wd_stride * i1_ht;
1560         if(i1_ht < 0)
1561             /* Top POD */
1562             i1_ht = -i1_ht;
1563         else
1564         {
1565             /* Bottom POD */
1566             pu4_pod_src += (ps_pred->i1_dma_ht - 1) * u1_wd_stride;
1567             pu4_pod_dst += (ps_pred->i1_dma_ht - i1_ht) * u1_wd_stride;
1568         }
1569 
1570         for(i = 0; i < i1_ht; i++)
1571             for(j = 0; j < u1_wd_stride; j++)
1572                 *pu4_pod_dst++ = *(pu4_pod_src + j);
1573     }
1574 }
1575 
1576