Home | History | Annotate | Download | only in decoder
      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
     23 *  impeg2d_mc.c
     24 *
     25 * @brief
     26 *  Contains MC function definitions for MPEG2 decoder
     27 *
     28 * @author
     29 *  Harish
     30 *
     31 * @par List of Functions:
     32 * - impeg2d_motion_comp()
     33 * - impeg2d_motion_comp_recon_buf()
     34 * - impeg2d_mc_1mv()
     35 * - impeg2d_mc_fw_or_bk_mb()
     36 * - impeg2d_mc_frm_dual_prime()
     37 * - impeg2d_mc_fld_dual_prime()
     38 * - impeg2d_mc_4mv()
     39 * - impeg2d_mc_2mv()
     40 * - impeg2d_dec_intra_mb()
     41 * - impeg2d_dec_skip_p_mb()
     42 * - impeg2d_dec_skip_b_mb()
     43 * - impeg2d_dec_skip_mbs()
     44 * - impeg2d_dec_0mv_coded_mb()
     45 * - impeg2d_mc_halfx_halfy()
     46 * - impeg2d_mc_halfx_fully()
     47 * - impeg2d_mc_fullx_halfy()
     48 * - impeg2d_mc_fullx_fully()
     49 * - impeg2d_set_mc_params()
     50 *
     51 * @remarks
     52 *  None
     53 *
     54 *******************************************************************************
     55 */
     56 #include <string.h>
     57 
     58 #include "iv_datatypedef.h"
     59 #include "iv.h"
     60 
     61 #include "impeg2_buf_mgr.h"
     62 #include "impeg2_disp_mgr.h"
     63 #include "impeg2_defs.h"
     64 #include "impeg2_platform_macros.h"
     65 #include "impeg2_inter_pred.h"
     66 #include "impeg2_idct.h"
     67 #include "impeg2_globals.h"
     68 #include "impeg2_mem_func.h"
     69 #include "impeg2_format_conv.h"
     70 #include "impeg2_macros.h"
     71 
     72 #include "ivd.h"
     73 #include "impeg2d.h"
     74 #include "impeg2d_bitstream.h"
     75 #include "impeg2d_structs.h"
     76 #include "impeg2d_globals.h"
     77 #include "impeg2d_pic_proc.h"
     78 #include "impeg2d_debug.h"
     79 #include "impeg2d_mv_dec.h"
     80 #include "impeg2d_mc.h"
     81 
     82 /*****************************************************************************/
     83 /*                                                                           */
     84 /*  Function Name : impeg2d_motion_comp                                      */
     85 /*                                                                           */
     86 /*  Description   : Perform motion compensation and store the resulting block*/
     87 /*                  in the buf                                               */
     88 /*                                                                           */
     89 /*  Inputs        : params - Parameters required to do motion compensation   */
     90 /*                                                                           */
     91 /*  Globals       :                                                          */
     92 /*                                                                           */
     93 /*  Processing    : Calls appropriate functions depending on the mode of     */
     94 /*                  compensation                                             */
     95 /*                                                                           */
     96 /*  Outputs       : buf       - Buffer for the motion compensation result    */
     97 /*                                                                           */
     98 /*  Returns       : None                                                     */
     99 /*                                                                           */
    100 /*  Issues        : None                                                     */
    101 /*                                                                           */
    102 /*  Revision History:                                                        */
    103 /*                                                                           */
    104 /*         DD MM YYYY   Author(s)       Changes                              */
    105 /*         14 09 2005   Hairsh M        First Version                        */
    106 /*                                                                           */
    107 /*****************************************************************************/
    108 void impeg2d_motion_comp(dec_state_t *ps_dec, mb_mc_params_t *ps_params,yuv_buf_t *ps_buf)
    109 {
    110 
    111     PROFILE_DISABLE_MC_RETURN;
    112 
    113     /* Perform motion compensation for Y */
    114     ps_dec->pf_mc[ps_params->s_luma.u4_mode]((void *)ps_dec, ps_params->s_ref.pu1_y + ps_params->s_luma.u4_src_offset,
    115                 ps_params->s_luma.u4_src_wd,
    116                 ps_buf->pu1_y + ps_params->s_luma.u4_dst_offset_res_buf,
    117                 ps_params->s_luma.u4_dst_wd_res_buf,
    118                 ps_params->s_luma.u4_cols,
    119                 ps_params->s_luma.u4_rows);
    120     /* Perform motion compensation for U */
    121     ps_dec->pf_mc[ps_params->s_chroma.u4_mode]((void *)ps_dec, ps_params->s_ref.pu1_u + ps_params->s_chroma.u4_src_offset,
    122                 ps_params->s_chroma.u4_src_wd,
    123                 ps_buf->pu1_u + ps_params->s_chroma.u4_dst_offset_res_buf,
    124                 ps_params->s_chroma.u4_dst_wd_res_buf,
    125                 ps_params->s_chroma.u4_cols,
    126                 ps_params->s_chroma.u4_rows);
    127 
    128     /* Perform motion compensation for V */
    129     ps_dec->pf_mc[ps_params->s_chroma.u4_mode]((void *)ps_dec, ps_params->s_ref.pu1_v + ps_params->s_chroma.u4_src_offset,
    130                 ps_params->s_chroma.u4_src_wd,
    131                 ps_buf->pu1_v + ps_params->s_chroma.u4_dst_offset_res_buf,
    132                 ps_params->s_chroma.u4_dst_wd_res_buf,
    133                 ps_params->s_chroma.u4_cols,
    134                 ps_params->s_chroma.u4_rows);
    135 }
    136 
    137 
    138 
    139 /*****************************************************************************/
    140 /*                                                                           */
    141 /*  Function Name : impeg2d_motion_comp_recon_buf                          */
    142 /*                                                                           */
    143 /*  Description   : Perform motion compensation and store the resulting block*/
    144 /*                  in the buf                                               */
    145 /*                                                                           */
    146 /*  Inputs        : params - Parameters required to do motion compensation   */
    147 /*                                                                           */
    148 /*  Globals       :                                                          */
    149 /*                                                                           */
    150 /*  Processing    : Calls appropriate functions depending on the mode of     */
    151 /*                  compensation                                             */
    152 /*                                                                           */
    153 /*  Outputs       : buf       - Buffer for the motion compensation result    */
    154 /*                                                                           */
    155 /*  Returns       : None                                                     */
    156 /*                                                                           */
    157 /*  Issues        : None                                                     */
    158 /*                                                                           */
    159 /*  Revision History:                                                        */
    160 /*                                                                           */
    161 /*         DD MM YYYY   Author(s)       Changes                              */
    162 /*         14 09 2005   Harish M        First Version                        */
    163 /*                                                                           */
    164 /*****************************************************************************/
    165 void impeg2d_motion_comp_recon_buf(dec_state_t *ps_dec,
    166                                      mb_mc_params_t *ps_params,
    167                                      yuv_buf_t *ps_dest_buf)
    168 {
    169 
    170     PROFILE_DISABLE_MC_RETURN;
    171 
    172     /* Perform motion compensation for Y */
    173     ps_dec->pf_mc[ps_params->s_luma.u4_mode](ps_dec, ps_params->s_ref.pu1_y + ps_params->s_luma.u4_src_offset,
    174                                         ps_params->s_luma.u4_src_wd,
    175                                         ps_dest_buf->pu1_y + ps_params->s_luma.u4_dst_offset_cur_frm,
    176                                         ps_params->s_luma.u4_dst_wd_cur_frm,
    177                                         ps_params->s_luma.u4_cols,
    178                                         ps_params->s_luma.u4_rows);
    179 
    180     /* Perform motion compensation for U */
    181 
    182     ps_dec->pf_mc[ps_params->s_chroma.u4_mode](ps_dec, ps_params->s_ref.pu1_u + ps_params->s_chroma.u4_src_offset,
    183                                         ps_params->s_chroma.u4_src_wd,
    184                                         ps_dest_buf->pu1_u + ps_params->s_chroma.u4_dst_offset_cur_frm,
    185                                         ps_params->s_chroma.u4_dst_wd_cur_frm,
    186                                         ps_params->s_chroma.u4_cols,
    187                                         ps_params->s_chroma.u4_rows);
    188 
    189     /* Perform motion compensation for V */
    190     ps_dec->pf_mc[ps_params->s_chroma.u4_mode](ps_dec, ps_params->s_ref.pu1_v + ps_params->s_chroma.u4_src_offset,
    191                                         ps_params->s_chroma.u4_src_wd,
    192                                         ps_dest_buf->pu1_v + ps_params->s_chroma.u4_dst_offset_cur_frm,
    193                                         ps_params->s_chroma.u4_dst_wd_cur_frm,
    194                                         ps_params->s_chroma.u4_cols,
    195                                         ps_params->s_chroma.u4_rows);
    196 }
    197 
    198 
    199 
    200 /*****************************************************************************/
    201 /*                                                                           */
    202 /*  Function Name : impeg2d_mc_1mv                                           */
    203 /*                                                                           */
    204 /*  Description   : Perform motion compensation and store the resulting block*/
    205 /*                  in the buf                                               */
    206 /*                                                                           */
    207 /*  Inputs        : params - Parameters required to do motion compensation   */
    208 /*                                                                           */
    209 /*  Globals       :                                                          */
    210 /*                                                                           */
    211 /*  Processing    : Calls appropriate functions depending on the mode of     */
    212 /*                  compensation                                             */
    213 /*                                                                           */
    214 /*  Outputs       : buf       - Buffer for the motion compensation result    */
    215 /*                                                                           */
    216 /*  Returns       : None                                                     */
    217 /*                                                                           */
    218 /*  Issues        : None                                                     */
    219 /*                                                                           */
    220 /*  Revision History:                                                        */
    221 /*                                                                           */
    222 /*         DD MM YYYY   Author(s)       Changes                              */
    223 /*         14 09 2005   Hairsh M        First Version                        */
    224 /*                                                                           */
    225 /*****************************************************************************/
    226 void impeg2d_mc_1mv(dec_state_t *ps_dec)
    227 {
    228 
    229     impeg2d_motion_comp_recon_buf(ps_dec, &ps_dec->as_mb_mc_params[ps_dec->e_mb_pred][FIRST], &ps_dec->s_dest_buf);
    230 }
    231 
    232 
    233 
    234 /*****************************************************************************/
    235 /*                                                                           */
    236 /*  Function Name : impeg2d_mc_fw_or_bk_mb                                   */
    237 /*                                                                           */
    238 /*  Description   : Perform motion compensation and store the resulting block*/
    239 /*                  in the buf                                               */
    240 /*                                                                           */
    241 /*  Inputs        : params - Parameters required to do motion compensation   */
    242 /*                                                                           */
    243 /*  Globals       :                                                          */
    244 /*                                                                           */
    245 /*  Processing    : Calls appropriate functions depending on the mode of     */
    246 /*                  compensation                                             */
    247 /*                                                                           */
    248 /*  Outputs       : buf       - Buffer for the motion compensation result    */
    249 /*                                                                           */
    250 /*  Returns       : None                                                     */
    251 /*                                                                           */
    252 /*  Issues        : None                                                     */
    253 /*                                                                           */
    254 /*  Revision History:                                                        */
    255 /*                                                                           */
    256 /*         DD MM YYYY   Author(s)       Changes                              */
    257 /*         14 09 2005   Hairsh M        First Version                        */
    258 /*                                                                           */
    259 /*****************************************************************************/
    260 void impeg2d_mc_fw_or_bk_mb(dec_state_t *ps_dec)
    261 {
    262     impeg2d_motion_comp_recon_buf(ps_dec, &ps_dec->as_mb_mc_params[FORW][FIRST], &ps_dec->s_dest_buf);
    263     impeg2d_motion_comp_recon_buf(ps_dec, &ps_dec->as_mb_mc_params[FORW][SECOND], &ps_dec->s_dest_buf);
    264 }
    265 
    266 
    267 
    268 /*****************************************************************************/
    269 /*                                                                           */
    270 /*  Function Name : impeg2d_mc_frm_dual_prime                                */
    271 /*                                                                           */
    272 /*  Description   : Perform motion compensation and store the resulting block*/
    273 /*                  in the buf                                               */
    274 /*                                                                           */
    275 /*  Inputs        : params - Parameters required to do motion compensation   */
    276 /*                                                                           */
    277 /*  Globals       :                                                          */
    278 /*                                                                           */
    279 /*  Processing    : Calls appropriate functions depending on the mode of     */
    280 /*                  compensation                                             */
    281 /*                                                                           */
    282 /*  Outputs       : buf       - Buffer for the motion compensation result    */
    283 /*                                                                           */
    284 /*  Returns       : None                                                     */
    285 /*                                                                           */
    286 /*  Issues        : None                                                     */
    287 /*                                                                           */
    288 /*  Revision History:                                                        */
    289 /*                                                                           */
    290 /*         DD MM YYYY   Author(s)       Changes                              */
    291 /*         14 09 2005   Hairsh M        First Version                        */
    292 /*                                                                           */
    293 /*****************************************************************************/
    294 void impeg2d_mc_frm_dual_prime(dec_state_t *ps_dec)
    295 {
    296     /************************************************************************/
    297     /* Perform Motion Compensation                                          */
    298     /************************************************************************/
    299     impeg2d_motion_comp(ps_dec, &ps_dec->as_mb_mc_params[FORW][FIRST], &ps_dec->s_mc_fw_buf);
    300     impeg2d_motion_comp(ps_dec, &ps_dec->as_mb_mc_params[BACK][FIRST], &ps_dec->s_mc_bk_buf);
    301 
    302     impeg2d_motion_comp(ps_dec, &ps_dec->as_mb_mc_params[FORW][SECOND], &ps_dec->s_mc_fw_buf);
    303     impeg2d_motion_comp(ps_dec, &ps_dec->as_mb_mc_params[BACK][SECOND], &ps_dec->s_mc_bk_buf);
    304 
    305 
    306 
    307     ps_dec->pf_interpolate(&ps_dec->s_mc_fw_buf,&ps_dec->s_mc_bk_buf,&ps_dec->s_dest_buf,ps_dec->u2_picture_width);
    308 }
    309 
    310 
    311 
    312 /*****************************************************************************/
    313 /*                                                                           */
    314 /*  Function Name : impeg2d_mc_fld_dual_prime                                */
    315 /*                                                                           */
    316 /*  Description   : Perform motion compensation and store the resulting block*/
    317 /*                  in the buf                                               */
    318 /*                                                                           */
    319 /*  Inputs        : params - Parameters required to do motion compensation   */
    320 /*                                                                           */
    321 /*  Globals       :                                                          */
    322 /*                                                                           */
    323 /*  Processing    : Calls appropriate functions depending on the mode of     */
    324 /*                  compensation                                             */
    325 /*                                                                           */
    326 /*  Outputs       : buf       - Buffer for the motion compensation result    */
    327 /*                                                                           */
    328 /*  Returns       : None                                                     */
    329 /*                                                                           */
    330 /*  Issues        : None                                                     */
    331 /*                                                                           */
    332 /*  Revision History:                                                        */
    333 /*                                                                           */
    334 /*         DD MM YYYY   Author(s)       Changes                              */
    335 /*         14 09 2005   Hairsh M        First Version                        */
    336 /*                                                                           */
    337 /*****************************************************************************/
    338 void impeg2d_mc_fld_dual_prime(dec_state_t *ps_dec)
    339 {
    340     /************************************************************************/
    341     /* Perform Motion Compensation                                          */
    342     /************************************************************************/
    343     impeg2d_motion_comp(ps_dec, &ps_dec->as_mb_mc_params[FORW][FIRST], &ps_dec->s_mc_fw_buf);
    344     impeg2d_motion_comp(ps_dec, &ps_dec->as_mb_mc_params[FORW][SECOND], &ps_dec->s_mc_bk_buf);
    345 
    346 
    347     ps_dec->pf_interpolate(&ps_dec->s_mc_fw_buf,&ps_dec->s_mc_bk_buf,&ps_dec->s_dest_buf,ps_dec->u2_picture_width);
    348 }
    349 
    350 
    351 
    352 
    353 
    354 /*****************************************************************************/
    355 /*                                                                           */
    356 /*  Function Name : impeg2d_mc_4mv                                      */
    357 /*                                                                           */
    358 /*  Description   : Perform motion compensation and store the resulting block*/
    359 /*                  in the buf                                               */
    360 /*                                                                           */
    361 /*  Inputs        : params - Parameters required to do motion compensation   */
    362 /*                                                                           */
    363 /*  Globals       :                                                          */
    364 /*                                                                           */
    365 /*  Processing    : Calls appropriate functions depending on the mode of     */
    366 /*                  compensation                                             */
    367 /*                                                                           */
    368 /*  Outputs       : buf       - Buffer for the motion compensation result    */
    369 /*                                                                           */
    370 /*  Returns       : None                                                     */
    371 /*                                                                           */
    372 /*  Issues        : None                                                     */
    373 /*                                                                           */
    374 /*  Revision History:                                                        */
    375 /*                                                                           */
    376 /*         DD MM YYYY   Author(s)       Changes                              */
    377 /*         14 09 2005   Hairsh M        First Version                        */
    378 /*                                                                           */
    379 /*****************************************************************************/
    380 void impeg2d_mc_4mv(dec_state_t *ps_dec)
    381 {
    382     /************************************************************************/
    383     /* Perform Motion Compensation                                          */
    384     /************************************************************************/
    385     impeg2d_motion_comp(ps_dec, &ps_dec->as_mb_mc_params[FORW][FIRST], &ps_dec->s_mc_fw_buf);
    386     impeg2d_motion_comp(ps_dec, &ps_dec->as_mb_mc_params[BACK][FIRST], &ps_dec->s_mc_bk_buf);
    387     impeg2d_motion_comp(ps_dec, &ps_dec->as_mb_mc_params[FORW][SECOND], &ps_dec->s_mc_fw_buf);
    388     impeg2d_motion_comp(ps_dec, &ps_dec->as_mb_mc_params[BACK][SECOND], &ps_dec->s_mc_bk_buf);
    389 
    390     ps_dec->pf_interpolate(&ps_dec->s_mc_fw_buf,&ps_dec->s_mc_bk_buf,&ps_dec->s_dest_buf,ps_dec->u2_picture_width);
    391 }
    392 
    393 /*****************************************************************************/
    394 /*                                                                           */
    395 /*  Function Name : impeg2d_mc_2mv                                         */
    396 /*                                                                           */
    397 /*  Description   : Perform motion compensation and store the resulting block*/
    398 /*                  in the buf                                               */
    399 /*                                                                           */
    400 /*  Inputs        : params - Parameters required to do motion compensation   */
    401 /*                                                                           */
    402 /*  Globals       :                                                          */
    403 /*                                                                           */
    404 /*  Processing    : Calls appropriate functions depending on the mode of     */
    405 /*                  compensation                                             */
    406 /*                                                                           */
    407 /*  Outputs       : buf       - Buffer for the motion compensation result    */
    408 /*                                                                           */
    409 /*  Returns       : None                                                     */
    410 /*                                                                           */
    411 /*  Issues        : None                                                     */
    412 /*                                                                           */
    413 /*  Revision History:                                                        */
    414 /*                                                                           */
    415 /*         DD MM YYYY   Author(s)       Changes                              */
    416 /*         14 09 2005   Hairsh M        First Version                        */
    417 /*                                                                           */
    418 /*****************************************************************************/
    419 void impeg2d_mc_2mv(dec_state_t *ps_dec)
    420 {
    421    /************************************************************************/
    422     /* Perform Motion Compensation                                          */
    423     /************************************************************************/
    424     impeg2d_motion_comp(ps_dec, &ps_dec->as_mb_mc_params[FORW][FIRST], &ps_dec->s_mc_fw_buf);
    425     impeg2d_motion_comp(ps_dec, &ps_dec->as_mb_mc_params[BACK][FIRST], &ps_dec->s_mc_bk_buf);
    426 
    427     ps_dec->pf_interpolate(&ps_dec->s_mc_fw_buf,&ps_dec->s_mc_bk_buf,&ps_dec->s_dest_buf,ps_dec->u2_picture_width);
    428 }
    429 
    430 /*****************************************************************************
    431 *  Function Name   : impeg2d_dec_intra_mb
    432 *
    433 *  Description     : Performs decoding of Intra MB
    434 *
    435 *  Arguments       :
    436 *  dec             : Decoder state
    437 *
    438 *  Values Returned : None
    439 *****************************************************************************/
    440 void impeg2d_dec_intra_mb(dec_state_t *ps_dec)
    441 {
    442 
    443     ps_dec->u2_cbp = 0x3F;
    444     if(ps_dec->u2_concealment_motion_vectors)
    445     {
    446 
    447         stream_t *ps_stream;
    448 
    449         ps_stream = &ps_dec->s_bit_stream;
    450         /* Decode the concealment motion vector */
    451         impeg2d_dec_mv(ps_stream,ps_dec->ai2_pred_mv[FORW][FIRST],ps_dec->ai2_mv[FORW][FIRST],
    452         ps_dec->au2_f_code[FORW],0,ps_dec->u2_fld_pic);
    453 
    454 
    455         /* Set the second motion vector predictor */
    456         ps_dec->ai2_pred_mv[FORW][SECOND][MV_X] = ps_dec->ai2_pred_mv[FORW][FIRST][MV_X];
    457         ps_dec->ai2_pred_mv[FORW][SECOND][MV_Y] = ps_dec->ai2_pred_mv[FORW][FIRST][MV_Y];
    458 
    459         /* Flush the marker bit */
    460         if(0 == (impeg2d_bit_stream_get(ps_stream,1)))
    461         {
    462             /* Ignore marker bit error */
    463         }
    464     }
    465     else
    466     {
    467         /* Reset the motion vector predictors */
    468         memset(ps_dec->ai2_pred_mv,0,sizeof(ps_dec->ai2_pred_mv));
    469     }
    470 }
    471 
    472 /*****************************************************************************
    473 *  Function Name   : impeg2d_dec_skip_p_mb
    474 *
    475 *  Description     : Performs decoding needed for Skipped MB encountered in
    476 *                    P Pictures and B Pictures with previous MB not bi-predicted
    477 *
    478 *  Arguments       :
    479 *  dec             : Decoder state
    480 *
    481 *  Values Returned : None
    482 *****************************************************************************/
    483 void impeg2d_dec_skip_p_mb(dec_state_t *ps_dec, WORD32 u4_num_of_mbs)
    484 {
    485     WORD16  *pi2_mv;
    486 
    487     e_mb_type_t e_mb_type;
    488     mb_mc_params_t *ps_mc;
    489 
    490 
    491     WORD32 i4_iter;
    492     UWORD32 u4_dst_wd;
    493     UWORD32  u4_dst_offset_x;
    494     UWORD32  u4_dst_offset_y;
    495     UWORD32 u4_frm_offset = 0;
    496     yuv_buf_t s_dst;
    497 
    498     u4_dst_wd = ps_dec->u2_frame_width;
    499 
    500     if(ps_dec->u2_picture_structure != FRAME_PICTURE)
    501     {
    502         u4_dst_wd <<= 1;
    503         if(ps_dec->u2_picture_structure == BOTTOM_FIELD)
    504         {
    505             u4_frm_offset = ps_dec->u2_frame_width;
    506         }
    507     }
    508 
    509     for (i4_iter = u4_num_of_mbs; i4_iter > 0; i4_iter--)
    510     {
    511         if(ps_dec->u2_picture_structure == FRAME_PICTURE)
    512         {
    513             e_mb_type = MC_FRM_FW_AND_BK_2MV;
    514         }
    515         else
    516         {
    517             e_mb_type = MC_FLD_FW_AND_BK_2MV;
    518         }
    519 
    520         ps_dec->u2_prev_intra_mb = 0;
    521         pi2_mv               = (WORD16 *)&(ps_dec->ai2_mv[FORW][FIRST]);
    522 
    523         /* Reset the motion vector predictors */
    524         if(ps_dec->e_pic_type == P_PIC)
    525         {
    526             memset(ps_dec->ai2_pred_mv,0,sizeof(ps_dec->ai2_pred_mv));
    527             pi2_mv[MV_X]    = pi2_mv[MV_Y] = 0;
    528 
    529             ps_dec->u2_cbp     = 0;
    530 
    531             pi2_mv           = (WORD16 *)&ps_dec->ai2_mv[FORW][FIRST];
    532             ps_mc           = &ps_dec->as_mb_mc_params[FORW][FIRST];
    533             ps_mc->s_ref      = ps_dec->as_ref_buf[ps_dec->e_mb_pred][ps_dec->u2_fld_parity];
    534 
    535             impeg2d_set_mc_params(&ps_mc->s_luma, &ps_mc->s_chroma, e_mb_type, 0,
    536                       pi2_mv, ps_dec->u2_mb_x, ps_dec->u2_mb_y, ps_dec->u2_frame_width, ps_dec->u2_frame_height,ps_dec->u2_picture_width);
    537 
    538 
    539             u4_dst_offset_x = (ps_dec->u2_mb_x << 4) + u4_frm_offset;
    540             u4_dst_offset_y = (ps_dec->u2_mb_y << 4) * u4_dst_wd;
    541 
    542             s_dst.pu1_y = ps_dec->s_cur_frm_buf.pu1_y + u4_dst_offset_x + u4_dst_offset_y;
    543 
    544             u4_dst_offset_x = u4_dst_offset_x >> 1;
    545             u4_dst_offset_y = u4_dst_offset_y >> 2;
    546 
    547             s_dst.pu1_u = ps_dec->s_cur_frm_buf.pu1_u + u4_dst_offset_x + u4_dst_offset_y;
    548             s_dst.pu1_v = ps_dec->s_cur_frm_buf.pu1_v + u4_dst_offset_x + u4_dst_offset_y;
    549 
    550 
    551             ps_mc->s_ref.pu1_y += ps_mc->s_luma.u4_src_offset;
    552             ps_mc->s_ref.pu1_u += ps_mc->s_chroma.u4_src_offset;
    553             ps_mc->s_ref.pu1_v += ps_mc->s_chroma.u4_src_offset;
    554 
    555             ps_dec->pf_copy_mb(&ps_mc->s_ref, &s_dst, ps_mc->s_luma.u4_src_wd, u4_dst_wd);
    556         }
    557 
    558         else
    559         {
    560             pi2_mv[MV_X]    = ps_dec->ai2_pred_mv[ps_dec->e_mb_pred][FIRST][MV_X];
    561             pi2_mv[MV_Y]    = ps_dec->ai2_pred_mv[ps_dec->e_mb_pred][FIRST][MV_Y];
    562 
    563             ps_dec->u2_cbp     = 0;
    564 
    565             pi2_mv           = (WORD16 *)&ps_dec->ai2_mv[FORW][FIRST];
    566             ps_mc           = &ps_dec->as_mb_mc_params[FORW][FIRST];
    567             ps_mc->s_ref      = ps_dec->as_ref_buf[ps_dec->e_mb_pred][ps_dec->u2_fld_parity];
    568 
    569             impeg2d_set_mc_params(&ps_mc->s_luma, &ps_mc->s_chroma, e_mb_type, 0,
    570                       pi2_mv, ps_dec->u2_mb_x, ps_dec->u2_mb_y, ps_dec->u2_frame_width, ps_dec->u2_frame_height,ps_dec->u2_picture_width);
    571 
    572             u4_dst_offset_x = (ps_dec->u2_mb_x << 4) + u4_frm_offset;
    573             u4_dst_offset_y = (ps_dec->u2_mb_y << 4) * u4_dst_wd;
    574 
    575             ps_mc->s_luma.u4_dst_offset_res_buf = u4_dst_offset_x + u4_dst_offset_y;
    576             ps_mc->s_luma.u4_dst_wd_res_buf = u4_dst_wd;
    577 
    578             u4_dst_offset_x = u4_dst_offset_x >> 1;
    579             u4_dst_offset_y = u4_dst_offset_y >> 2;
    580 
    581             ps_mc->s_chroma.u4_dst_offset_res_buf = u4_dst_offset_x + u4_dst_offset_y;
    582             ps_mc->s_chroma.u4_dst_wd_res_buf = u4_dst_wd >> 1;
    583 
    584             impeg2d_motion_comp(ps_dec, ps_mc, &ps_dec->s_cur_frm_buf);
    585         }
    586 
    587 
    588         /********************************************************************/
    589         /* Common MB processing tasks                                       */
    590         /********************************************************************/
    591         ps_dec->u2_mb_x++;
    592         ps_dec->u2_num_mbs_left--;
    593 
    594         if (ps_dec->u2_mb_x == ps_dec->u2_num_horiz_mb)
    595         {
    596             ps_dec->u2_mb_x = 0;
    597             ps_dec->u2_mb_y++;
    598         }
    599     }
    600 
    601 }
    602 
    603 /*******************************************************************************
    604 *  Function Name   : impeg2d_dec_skip_b_mb
    605 *
    606 *  Description     : Performs processing needed for Skipped MB encountered in
    607 *                    B Pictures with previous MB bi-predicted.
    608 *
    609 *  Arguments       :
    610 *  dec             : Decoder state
    611 *
    612 *  Values Returned : None
    613 *******************************************************************************/
    614 void impeg2d_dec_skip_b_mb(dec_state_t *ps_dec, WORD32 u4_num_of_mbs)
    615 {
    616 
    617 
    618     WORD16  *pi2_mv;
    619 
    620     UWORD32 i;
    621     e_mb_type_t e_mb_type;
    622     mb_mc_params_t *ps_mc;
    623 
    624     WORD32 i4_iter;
    625     UWORD32 u4_dst_wd;
    626     yuv_buf_t s_dst;
    627     UWORD32  u4_dst_offset_x;
    628     UWORD32  u4_dst_offset_y;
    629     UWORD32 u4_frm_offset = 0;
    630 
    631     u4_dst_wd = ps_dec->u2_frame_width;
    632     s_dst = ps_dec->s_cur_frm_buf;
    633 
    634     if(ps_dec->u2_picture_structure != FRAME_PICTURE)
    635     {
    636         u4_dst_wd <<= 1;
    637         if(ps_dec->u2_picture_structure == BOTTOM_FIELD)
    638         {
    639             u4_frm_offset = ps_dec->u2_frame_width;
    640         }
    641     }
    642 
    643     for (i4_iter = u4_num_of_mbs; i4_iter > 0; i4_iter--)
    644     {
    645         ps_dec->u2_prev_intra_mb = 0;
    646 
    647         if(ps_dec->u2_picture_structure == FRAME_PICTURE)
    648         {
    649             e_mb_type = MC_FRM_FW_AND_BK_2MV;
    650         }
    651         else
    652         {
    653             e_mb_type = MC_FLD_FW_AND_BK_2MV;
    654         }
    655 
    656         /************************************************************************/
    657         /* Setting of first motion vector for B MB                              */
    658         /************************************************************************/
    659         pi2_mv               = (WORD16 *)&(ps_dec->ai2_mv[FORW][FIRST]);
    660         {
    661             pi2_mv[MV_X]         = ps_dec->ai2_pred_mv[FORW][FIRST][MV_X];
    662             pi2_mv[MV_Y]         = ps_dec->ai2_pred_mv[FORW][FIRST][MV_Y];
    663         }
    664         /************************************************************************/
    665         /* Setting of second motion vector for B MB                             */
    666         /************************************************************************/
    667         pi2_mv               = (WORD16 *)&(ps_dec->ai2_mv[BACK][FIRST]);
    668         {
    669             pi2_mv[MV_X]         = ps_dec->ai2_pred_mv[BACK][FIRST][MV_X];
    670             pi2_mv[MV_Y]         = ps_dec->ai2_pred_mv[BACK][FIRST][MV_Y];
    671         }
    672         ps_dec->u2_cbp  = 0;
    673 
    674         for(i = 0; i < 2; i++)
    675         {
    676             pi2_mv          = (WORD16 *)&ps_dec->ai2_mv[i][FIRST];
    677             ps_mc          = &ps_dec->as_mb_mc_params[i][FIRST];
    678             ps_mc->s_ref     = ps_dec->as_ref_buf[i][ps_dec->u2_fld_parity];
    679 
    680             impeg2d_set_mc_params(&ps_mc->s_luma, &ps_mc->s_chroma, e_mb_type, 0, pi2_mv, ps_dec->u2_mb_x,
    681                           ps_dec->u2_mb_y, ps_dec->u2_frame_width, ps_dec->u2_frame_height,ps_dec->u2_picture_width);
    682         }
    683 
    684         impeg2d_motion_comp(ps_dec, &ps_dec->as_mb_mc_params[FORW][FIRST], &ps_dec->s_mc_fw_buf);
    685         impeg2d_motion_comp(ps_dec, &ps_dec->as_mb_mc_params[BACK][FIRST], &ps_dec->s_mc_bk_buf);
    686 
    687         u4_dst_offset_x = (ps_dec->u2_mb_x << 4) + u4_frm_offset;
    688         u4_dst_offset_y = (ps_dec->u2_mb_y << 4) * u4_dst_wd;
    689 
    690         s_dst.pu1_y = ps_dec->s_cur_frm_buf.pu1_y + u4_dst_offset_x + u4_dst_offset_y;
    691 
    692         u4_dst_offset_x = u4_dst_offset_x >> 1;
    693         u4_dst_offset_y = u4_dst_offset_y >> 2;
    694 
    695         s_dst.pu1_u = ps_dec->s_cur_frm_buf.pu1_u + u4_dst_offset_x + u4_dst_offset_y;
    696         s_dst.pu1_v = ps_dec->s_cur_frm_buf.pu1_v + u4_dst_offset_x + u4_dst_offset_y;
    697 
    698         ps_dec->pf_interpolate(&ps_dec->s_mc_fw_buf,&ps_dec->s_mc_bk_buf,&s_dst, u4_dst_wd);
    699 //        dec->pf_copy_mb(&dec->mc_buf, &dst, MB_SIZE, dst_wd);
    700 
    701         /********************************************************************/
    702         /* Common MB processing tasks                                       */
    703         /********************************************************************/
    704         ps_dec->u2_mb_x++;
    705         ps_dec->u2_num_mbs_left--;
    706 
    707         if (ps_dec->u2_mb_x == ps_dec->u2_num_horiz_mb)
    708         {
    709             ps_dec->u2_mb_x = 0;
    710             ps_dec->u2_mb_y++;
    711         }
    712     }
    713 }
    714 /*******************************************************************************
    715 *  Function Name   : impeg2d_dec_skip_mbs
    716 *
    717 *  Description     : Performs processing needed for Skipped MB encountered in
    718 *                    B Pictures with previous MB bi-predicted.
    719 *
    720 *  Arguments       :
    721 *  dec             : Decoder state
    722 *
    723 *  Values Returned : None
    724 *******************************************************************************/
    725 void impeg2d_dec_skip_mbs(dec_state_t *ps_dec, UWORD16 u2_num_skip_mbs)
    726 {
    727     PROFILE_DISABLE_SKIP_MB();
    728 
    729     if(ps_dec->e_mb_pred == BIDIRECT)
    730     {
    731         impeg2d_dec_skip_b_mb(ps_dec, u2_num_skip_mbs);
    732     }
    733     else
    734     {
    735         impeg2d_dec_skip_p_mb(ps_dec, u2_num_skip_mbs);
    736     }
    737 
    738     ps_dec->u2_def_dc_pred[Y_LUMA] = 128 << ps_dec->u2_intra_dc_precision;
    739     ps_dec->u2_def_dc_pred[U_CHROMA] = 128 << ps_dec->u2_intra_dc_precision;
    740     ps_dec->u2_def_dc_pred[V_CHROMA] = 128 << ps_dec->u2_intra_dc_precision;
    741 }
    742 
    743 
    744 
    745 
    746 /*****************************************************************************
    747 *  Function Name   : impeg2d_dec_0mv_coded_mb
    748 *
    749 *  Description     : Decodes the MB with 0 MV but coded. This can occur in P
    750 *                    pictures only
    751 *
    752 *  Arguments       :
    753 *  dec             : Decoder state
    754 *
    755 *  Values Returned : None
    756 *****************************************************************************/
    757 void impeg2d_dec_0mv_coded_mb(dec_state_t *ps_dec)
    758 {
    759 
    760 
    761     WORD16   *pi2_mv;
    762     e_mb_type_t e_mb_type;
    763     mb_mc_params_t *ps_mc;
    764 
    765     if(ps_dec->u2_picture_structure == FRAME_PICTURE)
    766     {
    767         e_mb_type = MC_FRM_FW_AND_BK_2MV;
    768     }
    769     else
    770     {
    771         e_mb_type = MC_FLD_FW_AND_BK_2MV;
    772     }
    773 
    774 
    775 
    776 
    777     /* Reset the motion vector predictors */
    778     memset(ps_dec->ai2_pred_mv,0,sizeof(ps_dec->ai2_pred_mv));
    779 
    780     pi2_mv           = (WORD16 *)&ps_dec->ai2_mv[FORW][FIRST];
    781     ps_mc           = &ps_dec->as_mb_mc_params[FORW][FIRST];
    782     ps_mc->s_ref      = ps_dec->as_ref_buf[FORW][ps_dec->u2_fld_parity];
    783 
    784     pi2_mv[MV_X] = 0;
    785     pi2_mv[MV_Y] = 0;
    786 
    787     impeg2d_set_mc_params(&ps_mc->s_luma, &ps_mc->s_chroma, e_mb_type, 0,
    788               pi2_mv, ps_dec->u2_mb_x, ps_dec->u2_mb_y, ps_dec->u2_frame_width, ps_dec->u2_frame_height,ps_dec->u2_picture_width);
    789 }
    790 
    791 /*****************************************************************************/
    792 /*                                                                           */
    793 /*  Function Name : impeg2d_mc_halfx_halfy()                                 */
    794 /*                                                                           */
    795 /*  Description   : Gets the buffer from (0.5,0.5) to (8.5,8.5)              */
    796 /*                  and the above block of size 8 x 8 will be placed as a    */
    797 /*                  block from the current position of out_buf               */
    798 /*                                                                           */
    799 /*  Inputs        : ref - Reference frame from which the block will be       */
    800 /*                        block will be extracted.                           */
    801 /*                  ref_wid - WIdth of reference frame                       */
    802 /*                  out_wid - WIdth of the output frame                      */
    803 /*                  blk_width  - width of the block                          */
    804 /*                  blk_width  - height of the block                         */
    805 /*                                                                           */
    806 /*  Globals       : None                                                     */
    807 /*                                                                           */
    808 /*  Processing    : Point to the (0,0),(1,0),(0,1),(1,1) position in         */
    809 /*                  the ref frame.Interpolate these four values to get the   */
    810 /*                  value at(0.5,0.5).Repeat this to get an 8 x 8 block      */
    811 /*                  using 9 x 9 block from reference frame                   */
    812 /*                                                                           */
    813 /*  Outputs       : out -  Output containing the extracted block             */
    814 /*                                                                           */
    815 /*  Returns       : None                                                     */
    816 /*                                                                           */
    817 /*  Issues        : None                                                     */
    818 /*                                                                           */
    819 /*  Revision History:                                                        */
    820 /*                                                                           */
    821 /*         DD MM YYYY   Author(s)       Changes                              */
    822 /*         05 09 2005   Harish M        First Version                        */
    823 /*                                                                           */
    824 /*****************************************************************************/
    825 void impeg2d_mc_halfx_halfy(void *pv_dec,
    826                            UWORD8 *pu1_ref,
    827                            UWORD32 u4_ref_wid,
    828                            UWORD8 *pu1_out,
    829                            UWORD32 u4_out_wid,
    830                            UWORD32 u4_blk_width,
    831                            UWORD32 u4_blk_height)
    832 {
    833    UWORD8 *pu1_out_ptr,*pu1_ref_ptr;
    834    dec_state_t *ps_dec = (dec_state_t *)pv_dec;
    835 
    836         pu1_out_ptr = pu1_out;
    837         pu1_ref_ptr = pu1_ref;
    838 
    839     if((u4_blk_width == MB_SIZE) && (u4_blk_height == MB_SIZE))
    840     {
    841 
    842         /*luma 16 x 16*/
    843 
    844         /*block 0*/
    845         ps_dec->pf_halfx_halfy_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
    846 
    847         /*block1*/
    848         pu1_out_ptr = (pu1_out + BLK_SIZE);
    849         pu1_ref_ptr = (pu1_ref + BLK_SIZE);
    850         ps_dec->pf_halfx_halfy_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
    851 
    852         /*block 2*/
    853         pu1_out_ptr = pu1_out + BLK_SIZE * u4_out_wid;
    854         pu1_ref_ptr = pu1_ref + BLK_SIZE * u4_ref_wid;
    855         ps_dec->pf_halfx_halfy_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
    856 
    857         /*block 3*/
    858         pu1_out_ptr = pu1_out + BLK_SIZE * u4_out_wid + BLK_SIZE;
    859         pu1_ref_ptr = pu1_ref + BLK_SIZE * u4_ref_wid + BLK_SIZE;
    860         ps_dec->pf_halfx_halfy_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
    861 
    862 
    863 
    864 
    865     }
    866     else if ((u4_blk_width == BLK_SIZE) && (u4_blk_height == BLK_SIZE))
    867     {
    868         /*chroma 8 x 8*/
    869         ps_dec->pf_halfx_halfy_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
    870     }
    871     else if ((u4_blk_width == MB_SIZE) && (u4_blk_height == BLK_SIZE))
    872     {
    873         /*block 0*/
    874         ps_dec->pf_halfx_halfy_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
    875 
    876         /*block 1*/
    877         pu1_out_ptr = (pu1_out + BLK_SIZE);
    878         pu1_ref_ptr = (pu1_ref + BLK_SIZE);
    879         ps_dec->pf_halfx_halfy_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
    880 
    881     }
    882 
    883     else
    884     {
    885         UWORD8 *ref_p0,*ref_p1,*ref_p2,*ref_p3;
    886         UWORD32 i,j;
    887         /* P0-P3 are the pixels in the reference frame and Q is the value being */
    888         /* estimated                                                            */
    889         /*
    890            P0 P1
    891              Q
    892            P2 P3
    893         */
    894 
    895         ref_p0 = pu1_ref;
    896         ref_p1 = pu1_ref + 1;
    897         ref_p2 = pu1_ref + u4_ref_wid;
    898         ref_p3 = pu1_ref + u4_ref_wid + 1;
    899 
    900         for(i = 0; i < u4_blk_height; i++)
    901         {
    902             for(j = 0; j < u4_blk_width; j++)
    903             {
    904                 *pu1_out++ =   (( (*ref_p0++ )
    905                             + (*ref_p1++ )
    906                             + (*ref_p2++ )
    907                             + (*ref_p3++ ) + 2 ) >> 2);
    908             }
    909             ref_p0 += u4_ref_wid - u4_blk_width;
    910             ref_p1 += u4_ref_wid - u4_blk_width;
    911             ref_p2 += u4_ref_wid - u4_blk_width;
    912             ref_p3 += u4_ref_wid - u4_blk_width;
    913 
    914             pu1_out    += u4_out_wid - u4_blk_width;
    915         }
    916     }
    917     return;
    918 }
    919 
    920 /*****************************************************************************/
    921 /*                                                                           */
    922 /*  Function Name : impeg2d_mc_halfx_fully()                                 */
    923 /*                                                                           */
    924 /*  Description   : Gets the buffer from (0.5,0) to (8.5,8)                  */
    925 /*                  and the above block of size 8 x 8 will be placed as a    */
    926 /*                  block from the current position of out_buf               */
    927 /*                                                                           */
    928 /*  Inputs        : ref - Reference frame from which the block will be       */
    929 /*                        block will be extracted.                           */
    930 /*                  ref_wid - WIdth of reference frame                       */
    931 /*                  out_wid - WIdth of the output frame                      */
    932 /*                  blk_width  - width of the block                          */
    933 /*                  blk_width  - height of the block                         */
    934 /*                                                                           */
    935 /*  Globals       : None                                                     */
    936 /*                                                                           */
    937 /*  Processing    : Point to the (0,0) and (1,0) position in the ref frame   */
    938 /*                  Interpolate these two values to get the value at(0.5,0)  */
    939 /*                  Repeat this to get an 8 x 8 block using 9 x 8 block from */
    940 /*                  reference frame                                          */
    941 /*                                                                           */
    942 /*  Outputs       : out -  Output containing the extracted block             */
    943 /*                                                                           */
    944 /*  Returns       : None                                                     */
    945 /*                                                                           */
    946 /*  Issues        : None                                                     */
    947 /*                                                                           */
    948 /*  Revision History:                                                        */
    949 /*                                                                           */
    950 /*         DD MM YYYY   Author(s)       Changes                              */
    951 /*         05 09 2005   Harish M        First Version                        */
    952 /*                                                                           */
    953 /*****************************************************************************/
    954 
    955 void impeg2d_mc_halfx_fully(void *pv_dec,
    956                             UWORD8 *pu1_ref,
    957                             UWORD32 u4_ref_wid,
    958                             UWORD8 *pu1_out,
    959                             UWORD32 u4_out_wid,
    960                             UWORD32 u4_blk_width,
    961                             UWORD32 u4_blk_height)
    962 {
    963     UWORD8 *pu1_out_ptr,*pu1_ref_ptr;
    964     dec_state_t *ps_dec = (dec_state_t *)pv_dec;
    965 
    966         pu1_out_ptr = pu1_out;
    967         pu1_ref_ptr = pu1_ref;
    968 
    969     if((u4_blk_width == MB_SIZE) && (u4_blk_height == MB_SIZE))
    970     {
    971 
    972         /*luma 16 x 16*/
    973 
    974         /*block 0*/
    975         ps_dec->pf_halfx_fully_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
    976 
    977         /*block1*/
    978         pu1_out_ptr = (pu1_out + BLK_SIZE);
    979         pu1_ref_ptr = (pu1_ref + BLK_SIZE);
    980         ps_dec->pf_halfx_fully_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
    981 
    982         /*block 2*/
    983         pu1_out_ptr = pu1_out + BLK_SIZE * u4_out_wid;
    984         pu1_ref_ptr = pu1_ref + BLK_SIZE * u4_ref_wid;
    985         ps_dec->pf_halfx_fully_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
    986 
    987         /*block 3*/
    988         pu1_out_ptr = pu1_out + BLK_SIZE * u4_out_wid + BLK_SIZE;
    989         pu1_ref_ptr = pu1_ref + BLK_SIZE * u4_ref_wid + BLK_SIZE;
    990         ps_dec->pf_halfx_fully_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
    991 
    992 
    993 
    994 
    995     }
    996     else if ((u4_blk_width == BLK_SIZE) && (u4_blk_height == BLK_SIZE))
    997     {
    998         /*chroma 8 x 8*/
    999         ps_dec->pf_halfx_fully_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
   1000     }
   1001     else if ((u4_blk_width == MB_SIZE) && (u4_blk_height == BLK_SIZE))
   1002     {
   1003         /*block 0*/
   1004         ps_dec->pf_halfx_fully_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
   1005 
   1006         /*block 1*/
   1007         pu1_out_ptr = (pu1_out + BLK_SIZE);
   1008         pu1_ref_ptr = (pu1_ref + BLK_SIZE);
   1009         ps_dec->pf_halfx_fully_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
   1010 
   1011     }
   1012 
   1013     else
   1014     {
   1015         UWORD8 *ref_p0,*ref_p1;
   1016         UWORD32 i,j;
   1017 
   1018         /* P0-P3 are the pixels in the reference frame and Q is the value being */
   1019         /* estimated                                                            */
   1020         /*
   1021            P0 Q P1
   1022         */
   1023 
   1024         ref_p0 = pu1_ref;
   1025         ref_p1 = pu1_ref + 1;
   1026 
   1027         for(i = 0; i < u4_blk_height; i++)
   1028         {
   1029             for(j = 0; j < u4_blk_width; j++)
   1030             {
   1031                 *pu1_out++ =   ((( *ref_p0++ )
   1032                             + (*ref_p1++) + 1 ) >> 1);
   1033             }
   1034             ref_p0 += u4_ref_wid - u4_blk_width;
   1035             ref_p1 += u4_ref_wid - u4_blk_width;
   1036 
   1037             pu1_out    += u4_out_wid - u4_blk_width;
   1038         }
   1039     }
   1040     return;
   1041 }
   1042 
   1043 
   1044 /*****************************************************************************/
   1045 /*                                                                           */
   1046 /*  Function Name : impeg2d_mc_fullx_halfy()                                 */
   1047 /*                                                                           */
   1048 /*  Description   : Gets the buffer from (0,0.5) to (8,8.5)                  */
   1049 /*                  and the above block of size 8 x 8 will be placed as a    */
   1050 /*                  block from the current position of out_buf               */
   1051 /*                                                                           */
   1052 /*  Inputs        : ref - Reference frame from which the block will be       */
   1053 /*                        block will be extracted.                           */
   1054 /*                  ref_wid - WIdth of reference frame                       */
   1055 /*                  out_wid - WIdth of the output frame                      */
   1056 /*                  blk_width  - width of the block                          */
   1057 /*                  blk_width  - height of the block                         */
   1058 /*                                                                           */
   1059 /*  Globals       : None                                                     */
   1060 /*                                                                           */
   1061 /*  Processing    : Point to the (0,0) and (0,1)   position in the ref frame */
   1062 /*                  Interpolate these two values to get the value at(0,0.5)  */
   1063 /*                  Repeat this to get an 8 x 8 block using 8 x 9 block from */
   1064 /*                  reference frame                                          */
   1065 /*                                                                           */
   1066 /*  Outputs       : out -  Output containing the extracted block             */
   1067 /*                                                                           */
   1068 /*  Returns       : None                                                     */
   1069 /*                                                                           */
   1070 /*  Issues        : None                                                     */
   1071 /*                                                                           */
   1072 /*  Revision History:                                                        */
   1073 /*                                                                           */
   1074 /*         DD MM YYYY   Author(s)       Changes                              */
   1075 /*         05 09 2005   Harish M        First Version                        */
   1076 /*                                                                           */
   1077 /*****************************************************************************/
   1078 void impeg2d_mc_fullx_halfy(void *pv_dec,
   1079                             UWORD8 *pu1_ref,
   1080                             UWORD32 u4_ref_wid,
   1081                             UWORD8 *pu1_out,
   1082                             UWORD32 u4_out_wid,
   1083                             UWORD32 u4_blk_width,
   1084                             UWORD32 u4_blk_height)
   1085 {
   1086 
   1087     UWORD8 *pu1_out_ptr,*pu1_ref_ptr;
   1088     dec_state_t *ps_dec = (dec_state_t *)pv_dec;
   1089         pu1_out_ptr = pu1_out;
   1090         pu1_ref_ptr = pu1_ref;
   1091 
   1092     if((u4_blk_width == MB_SIZE) && (u4_blk_height == MB_SIZE))
   1093     {
   1094 
   1095         /*luma 16 x 16*/
   1096 
   1097         /*block 0*/
   1098         ps_dec->pf_fullx_halfy_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
   1099 
   1100         /*block1*/
   1101         pu1_out_ptr = (pu1_out + BLK_SIZE);
   1102         pu1_ref_ptr = (pu1_ref + BLK_SIZE);
   1103         ps_dec->pf_fullx_halfy_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
   1104 
   1105         /*block 2*/
   1106         pu1_out_ptr = pu1_out + BLK_SIZE * u4_out_wid;
   1107         pu1_ref_ptr = pu1_ref + BLK_SIZE * u4_ref_wid;
   1108         ps_dec->pf_fullx_halfy_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
   1109 
   1110         /*block 3*/
   1111         pu1_out_ptr = pu1_out + BLK_SIZE * u4_out_wid + BLK_SIZE;
   1112         pu1_ref_ptr = pu1_ref + BLK_SIZE * u4_ref_wid + BLK_SIZE;
   1113         ps_dec->pf_fullx_halfy_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
   1114 
   1115 
   1116 
   1117 
   1118     }
   1119     else if ((u4_blk_width == BLK_SIZE) && (u4_blk_height == BLK_SIZE))
   1120     {
   1121         /*chroma 8 x 8*/
   1122         ps_dec->pf_fullx_halfy_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
   1123     }
   1124     else if ((u4_blk_width == MB_SIZE) && (u4_blk_height == BLK_SIZE))
   1125     {
   1126         /*block 0*/
   1127         ps_dec->pf_fullx_halfy_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
   1128 
   1129         /*block 1*/
   1130         pu1_out_ptr = (pu1_out + BLK_SIZE);
   1131         pu1_ref_ptr = (pu1_ref + BLK_SIZE);
   1132         ps_dec->pf_fullx_halfy_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
   1133 
   1134     }
   1135 
   1136     else if ((u4_blk_width == BLK_SIZE) && (u4_blk_height == (BLK_SIZE / 2)))
   1137     {
   1138         UWORD8 *ref_p0,*ref_p1;
   1139         UWORD32 i,j;
   1140         /* P0-P3 are the pixels in the reference frame and Q is the value being */
   1141         /* estimated                                                            */
   1142         /*
   1143            P0
   1144             x
   1145            P1
   1146         */
   1147         ref_p0 = pu1_ref;
   1148         ref_p1 = pu1_ref + u4_ref_wid;
   1149 
   1150         for(i = 0; i < u4_blk_height; i++)
   1151         {
   1152             for(j = 0; j < u4_blk_width; j++)
   1153             {
   1154                 *pu1_out++ =   ((( *ref_p0++)
   1155                             + (*ref_p1++) + 1 ) >> 1);
   1156             }
   1157             ref_p0 += u4_ref_wid - u4_blk_width;
   1158             ref_p1 += u4_ref_wid - u4_blk_width;
   1159 
   1160             pu1_out    += u4_out_wid - u4_blk_width;
   1161         }
   1162     }
   1163     return;
   1164 }
   1165 
   1166 /*****************************************************************************/
   1167 /*                                                                           */
   1168 /*  Function Name : impeg2d_mc_fullx_fully()                                 */
   1169 /*                                                                           */
   1170 /*  Description   : Gets the buffer from (x,y) to (x+8,y+8)                  */
   1171 /*                  and the above block of size 8 x 8 will be placed as a    */
   1172 /*                  block from the current position of out_buf               */
   1173 /*                                                                           */
   1174 /*  Inputs        : ref - Reference frame from which the block will be       */
   1175 /*                        block will be extracted.                           */
   1176 /*                  ref_wid - WIdth of reference frame                       */
   1177 /*                  out_wid - WIdth of the output frame                      */
   1178 /*                  blk_width  - width of the block                          */
   1179 /*                  blk_width  - height of the block                         */
   1180 /*                                                                           */
   1181 /*  Globals       : None                                                     */
   1182 /*                                                                           */
   1183 /*  Processing    : Point to the (0,0) position in the ref frame             */
   1184 /*                  Get an 8 x 8 block from reference frame                  */
   1185 /*                                                                           */
   1186 /*  Outputs       : out -  Output containing the extracted block             */
   1187 /*                                                                           */
   1188 /*  Returns       : None                                                     */
   1189 /*                                                                           */
   1190 /*  Issues        : None                                                     */
   1191 /*                                                                           */
   1192 /*  Revision History:                                                        */
   1193 /*                                                                           */
   1194 /*         DD MM YYYY   Author(s)       Changes                              */
   1195 /*         05 09 2005   Harish M        First Version                        */
   1196 /*                                                                           */
   1197 /*****************************************************************************/
   1198 
   1199 void impeg2d_mc_fullx_fully(void *pv_dec,
   1200                             UWORD8 *pu1_ref,
   1201                             UWORD32 u4_ref_wid,
   1202                             UWORD8 *pu1_out,
   1203                             UWORD32 u4_out_wid,
   1204                             UWORD32 u4_blk_width,
   1205                             UWORD32 u4_blk_height)
   1206 {
   1207 
   1208     UWORD8 *pu1_out_ptr,*pu1_ref_ptr;
   1209     dec_state_t *ps_dec = (dec_state_t *)pv_dec;
   1210 
   1211         pu1_out_ptr = pu1_out;
   1212         pu1_ref_ptr = pu1_ref;
   1213 
   1214     if((u4_blk_width == MB_SIZE) && (u4_blk_height == MB_SIZE))
   1215     {
   1216 
   1217         /*luma 16 x 16*/
   1218 
   1219         /*block 0*/
   1220         ps_dec->pf_fullx_fully_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
   1221 
   1222         /*block1*/
   1223         pu1_out_ptr = (pu1_out + BLK_SIZE);
   1224         pu1_ref_ptr = (pu1_ref + BLK_SIZE);
   1225         ps_dec->pf_fullx_fully_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
   1226 
   1227         /*block 2*/
   1228         pu1_out_ptr = pu1_out + BLK_SIZE * u4_out_wid;
   1229         pu1_ref_ptr = pu1_ref + BLK_SIZE * u4_ref_wid;
   1230         ps_dec->pf_fullx_fully_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
   1231 
   1232         /*block 3*/
   1233         pu1_out_ptr = pu1_out + BLK_SIZE * u4_out_wid + BLK_SIZE;
   1234         pu1_ref_ptr = pu1_ref + BLK_SIZE * u4_ref_wid + BLK_SIZE;
   1235         ps_dec->pf_fullx_fully_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
   1236 
   1237 
   1238 
   1239 
   1240     }
   1241     else if ((u4_blk_width == BLK_SIZE) && (u4_blk_height == BLK_SIZE))
   1242     {
   1243         /*chroma 8 x 8*/
   1244         ps_dec->pf_fullx_fully_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
   1245     }
   1246     else if ((u4_blk_width == MB_SIZE) && (u4_blk_height == BLK_SIZE))
   1247     {
   1248         /*block 0*/
   1249         ps_dec->pf_fullx_fully_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
   1250 
   1251         /*block 1*/
   1252         pu1_out_ptr = (pu1_out + BLK_SIZE);
   1253         pu1_ref_ptr = (pu1_ref + BLK_SIZE);
   1254         ps_dec->pf_fullx_fully_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
   1255 
   1256     }
   1257     else
   1258     {
   1259         UWORD32 i;
   1260 
   1261         for(i = 0; i < u4_blk_height; i++)
   1262         {
   1263             memmove(pu1_out, pu1_ref, u4_blk_width);
   1264             pu1_ref += u4_ref_wid;
   1265             pu1_out += u4_out_wid;
   1266         }
   1267     }
   1268     return;
   1269 }
   1270 
   1271 /*******************************************************************************
   1272 *  Function Name   : impeg2d_set_mc_params
   1273 *
   1274 *  Description     : Sets the parameters for Motion Compensation
   1275 *
   1276 *  Arguments       :
   1277 *  luma            : Parameters for luma blocks
   1278 *  chroma          : Parameters for chroma blocks
   1279 *  type            : Motion compensation type
   1280 *  mv_num          : Number of motion vectors
   1281 *  mv              : Motion Vectors
   1282 *  mb_x            : X co-ordinate of MB
   1283 *  mb_y            : Y co-ordinate of MB
   1284 *  frm_wd          : Width of the frame
   1285 *
   1286 *  Values Returned : None
   1287 *******************************************************************************/
   1288 void impeg2d_set_mc_params(comp_mc_params_t *ps_luma,
   1289                            comp_mc_params_t *ps_chroma,
   1290                            e_mb_type_t e_type,
   1291                            UWORD16 u2_mv_num,
   1292                            WORD16 ai2_mv[],
   1293                            UWORD16 u2_mb_x,
   1294                            UWORD16 u2_mb_y,
   1295                            UWORD16 u2_frm_wd,
   1296                            UWORD16 u2_frm_ht,
   1297                            UWORD16 u2_picture_width)
   1298 {
   1299     WORD16 i2_mvy_round;
   1300     WORD16 i2_mvx_round;
   1301     const mc_type_consts_t *ps_mc_params;
   1302     WORD16 i2_mvx_fullp_round;
   1303     WORD16 i2_mvy_fullp_round;
   1304     UWORD32 u4_frm_chroma_wd;
   1305     WORD16 i2_pix_x, i2_pix_y;
   1306 
   1307     ps_mc_params = &gas_impeg2d_mc_params_luma[e_type][u2_mv_num];
   1308     /****************************************************************************/
   1309     /* get luma mc params                                                       */
   1310     /****************************************************************************/
   1311     i2_pix_x = MB_SIZE * u2_mb_x + (ai2_mv[MV_X]>>1);
   1312     i2_pix_y = (MB_SIZE * u2_mb_y  +
   1313         (ai2_mv[MV_Y]>>1) * ps_mc_params->mvy_cf + u2_mv_num * ps_mc_params->mv_num_cf) * ps_mc_params->frm_wd_cf;
   1314 
   1315     // clip pix_x and pix_y so as it falls inside the frame boundary
   1316     CLIP(i2_pix_x, (u2_frm_wd-16), 0);
   1317     CLIP(i2_pix_y, (u2_frm_ht-16), 0);
   1318 
   1319     ps_luma->u4_src_offset = i2_pix_x +  i2_pix_y * u2_frm_wd;
   1320 
   1321 
   1322     /* keep offset  in full pel */
   1323     ps_luma->u4_rows          = ps_mc_params->rows;
   1324     ps_luma->u4_cols          = MB_SIZE;
   1325     ps_luma->u4_dst_wd_res_buf        = ps_mc_params->dst_wd;
   1326     ps_luma->u4_src_wd        = u2_frm_wd * ps_mc_params->src_wd_cf;
   1327     ps_luma->u4_dst_offset_res_buf    = ps_mc_params->dst_offset_scale * MB_SIZE;
   1328     ps_luma->u4_dst_offset_cur_frm    = ps_mc_params->dst_offset_scale * u2_picture_width;
   1329     ps_luma->u4_mode          = ((ai2_mv[MV_X] & 1) << 1) | (ai2_mv[MV_Y] & 1);
   1330 
   1331     /****************************************************************************/
   1332     /* get chroma mc params                                                     */
   1333     /****************************************************************************/
   1334     ps_mc_params   = &gas_impeg2d_mc_params_chroma[e_type][u2_mv_num];
   1335     i2_mvx_round   = ((ai2_mv[MV_X] + IS_NEG(ai2_mv[MV_X]))>>1);
   1336     i2_mvy_round   = ((ai2_mv[MV_Y] + IS_NEG(ai2_mv[MV_Y]))>>1);
   1337 
   1338     i2_mvx_fullp_round = (i2_mvx_round>>1);
   1339     i2_mvy_fullp_round = (i2_mvy_round>>1)*ps_mc_params->mvy_cf;
   1340 
   1341     u4_frm_chroma_wd = (u2_frm_wd>>1);
   1342 
   1343     i2_pix_x = (MB_SIZE/2) * u2_mb_x + i2_mvx_fullp_round;
   1344     i2_pix_y = ((MB_SIZE/2) * u2_mb_y + i2_mvy_fullp_round + u2_mv_num *
   1345                            ps_mc_params->mv_num_cf)*ps_mc_params->frm_wd_cf;
   1346 
   1347     CLIP(i2_pix_x, ((u2_frm_wd / 2)-8), 0);
   1348     CLIP(i2_pix_y, ((u2_frm_ht / 2)-8), 0);
   1349     ps_chroma->u4_src_offset = i2_pix_x + i2_pix_y * u4_frm_chroma_wd;
   1350 
   1351 
   1352     /* keep offset  in full pel */
   1353     ps_chroma->u4_rows = ps_mc_params->rows;
   1354     ps_chroma->u4_cols        = (MB_SIZE >> 1);
   1355     ps_chroma->u4_dst_wd_res_buf = ps_mc_params->dst_wd;
   1356     ps_chroma->u4_src_wd = (u2_frm_wd>>1) * ps_mc_params->src_wd_cf;
   1357     ps_chroma->u4_dst_offset_res_buf = ps_mc_params->dst_offset_scale * MB_CHROMA_SIZE;
   1358     ps_chroma->u4_dst_offset_cur_frm = ps_mc_params->dst_offset_scale * (u2_picture_width >> 1);
   1359     ps_chroma->u4_mode = ((i2_mvx_round & 1) << 1) | (i2_mvy_round & 1);
   1360 
   1361 
   1362 
   1363     ps_luma->u4_dst_wd_cur_frm = u2_picture_width;
   1364     ps_chroma->u4_dst_wd_cur_frm = u2_picture_width >> 1;
   1365 
   1366     if(ps_luma->u4_dst_wd_res_buf == MB_SIZE * 2)
   1367     {
   1368         ps_luma->u4_dst_wd_cur_frm = u2_frm_wd << 1;
   1369         ps_chroma->u4_dst_wd_cur_frm = u2_frm_wd;
   1370     }
   1371 }
   1372 
   1373 
   1374