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 #include <stdio.h>
     21 #include <string.h>
     22 
     23 #include "iv_datatypedef.h"
     24 #include "iv.h"
     25 
     26 #include "impeg2_buf_mgr.h"
     27 #include "impeg2_disp_mgr.h"
     28 #include "impeg2_defs.h"
     29 #include "impeg2_platform_macros.h"
     30 #include "impeg2_inter_pred.h"
     31 #include "impeg2_idct.h"
     32 #include "impeg2_globals.h"
     33 #include "impeg2_mem_func.h"
     34 #include "impeg2_format_conv.h"
     35 #include "impeg2_macros.h"
     36 
     37 #include "ivd.h"
     38 #include "impeg2d.h"
     39 #include "impeg2d_bitstream.h"
     40 #include "impeg2d_structs.h"
     41 #include "impeg2d_globals.h"
     42 #include "impeg2d_vld_tables.h"
     43 #include "impeg2d_vld.h"
     44 #include "impeg2d_pic_proc.h"
     45 #include "impeg2d_debug.h"
     46 
     47 void impeg2d_init_function_ptr(void *pv_codec);
     48 void impeg2d_format_convert(dec_state_t *ps_dec,
     49                             pic_buf_t *ps_src_pic,
     50                             iv_yuv_buf_t    *ps_disp_frm_buf,
     51                             UWORD32 u4_start_row, UWORD32 u4_num_rows)
     52 {
     53     UWORD8  *pu1_src_y,*pu1_src_u,*pu1_src_v;
     54     UWORD8  *pu1_dst_y,*pu1_dst_u,*pu1_dst_v;
     55 
     56 
     57 
     58     if((NULL == ps_src_pic) || (NULL == ps_src_pic->pu1_y) || (0 == u4_num_rows))
     59             return;
     60 
     61     pu1_src_y   = ps_src_pic->pu1_y + (u4_start_row * ps_dec->u2_frame_width);
     62     pu1_src_u   = ps_src_pic->pu1_u + ((u4_start_row >> 1) * (ps_dec->u2_frame_width >> 1));
     63     pu1_src_v   = ps_src_pic->pu1_v + ((u4_start_row >> 1) *(ps_dec->u2_frame_width >> 1));
     64 
     65     pu1_dst_y  =  (UWORD8 *)ps_disp_frm_buf->pv_y_buf + (u4_start_row *  ps_dec->u4_frm_buf_stride);
     66     pu1_dst_u =   (UWORD8 *)ps_disp_frm_buf->pv_u_buf +((u4_start_row >> 1)*(ps_dec->u4_frm_buf_stride >> 1));
     67     pu1_dst_v =   (UWORD8 *)ps_disp_frm_buf->pv_v_buf +((u4_start_row >> 1)*(ps_dec->u4_frm_buf_stride >> 1));
     68 
     69     if (IV_YUV_420P == ps_dec->i4_chromaFormat)
     70     {
     71         ps_dec->pf_copy_yuv420p_buf(pu1_src_y, pu1_src_u, pu1_src_v, pu1_dst_y,
     72                                     pu1_dst_u, pu1_dst_v,
     73                                     ps_dec->u2_horizontal_size,
     74                                     u4_num_rows,
     75                                     ps_dec->u2_frame_width,
     76                                     (ps_dec->u2_frame_width >> 1),
     77                                     (ps_dec->u2_frame_width >> 1),
     78                                     ps_dec->u4_frm_buf_stride,
     79                                     (ps_dec->u4_frm_buf_stride >> 1),
     80                                     (ps_dec->u4_frm_buf_stride >> 1));
     81     }
     82     else if (IV_YUV_422ILE == ps_dec->i4_chromaFormat)
     83     {
     84         void    *pv_yuv422i;
     85         UWORD32 u2_height,u2_width,u2_stride_y,u2_stride_u,u2_stride_v;
     86         UWORD32 u2_stride_yuv422i;
     87 
     88 
     89         pv_yuv422i          = (UWORD8 *)ps_disp_frm_buf->pv_y_buf + ((ps_dec->u2_vertical_size)*(ps_dec->u4_frm_buf_stride));
     90         u2_height           = u4_num_rows;
     91         u2_width            = ps_dec->u2_horizontal_size;
     92         u2_stride_y         = ps_dec->u2_frame_width;
     93         u2_stride_u         = u2_stride_y >> 1;
     94         u2_stride_v         = u2_stride_u;
     95         u2_stride_yuv422i   = (0 == ps_dec->u4_frm_buf_stride) ? ps_dec->u2_horizontal_size : ps_dec->u4_frm_buf_stride;
     96 
     97         ps_dec->pf_fmt_conv_yuv420p_to_yuv422ile(pu1_src_y,
     98             pu1_src_u,
     99             pu1_src_v,
    100             pv_yuv422i,
    101             u2_width,
    102             u2_height,
    103             u2_stride_y,
    104             u2_stride_u,
    105             u2_stride_v,
    106             u2_stride_yuv422i);
    107 
    108     }
    109     else if((ps_dec->i4_chromaFormat == IV_YUV_420SP_UV) ||
    110             (ps_dec->i4_chromaFormat == IV_YUV_420SP_VU))
    111     {
    112 
    113         UWORD32 dest_inc_Y=0,dest_inc_UV=0;
    114         WORD32 convert_uv_only;
    115 
    116         pu1_dst_u =   (UWORD8 *)ps_disp_frm_buf->pv_u_buf +((u4_start_row >> 1)*(ps_dec->u4_frm_buf_stride));
    117         dest_inc_Y =    ps_dec->u4_frm_buf_stride;
    118         dest_inc_UV =   ((ps_dec->u4_frm_buf_stride + 1) >> 1) << 1;
    119         convert_uv_only = 0;
    120 
    121         if(1 == ps_dec->u4_share_disp_buf)
    122             convert_uv_only = 1;
    123 
    124         if(pu1_src_y == pu1_dst_y)
    125             convert_uv_only = 1;
    126 
    127         if(ps_dec->i4_chromaFormat == IV_YUV_420SP_UV)
    128         {
    129             ps_dec->pf_fmt_conv_yuv420p_to_yuv420sp_uv(pu1_src_y,
    130                 pu1_src_u,
    131                 pu1_src_v,
    132                 pu1_dst_y,
    133                 pu1_dst_u,
    134                 u4_num_rows,
    135                 ps_dec->u2_horizontal_size,
    136                 ps_dec->u2_frame_width,
    137                 ps_dec->u2_frame_width >> 1,
    138                 ps_dec->u2_frame_width >> 1,
    139                 dest_inc_Y,
    140                 dest_inc_UV,
    141                 convert_uv_only);
    142         }
    143         else
    144         {
    145             ps_dec->pf_fmt_conv_yuv420p_to_yuv420sp_vu(pu1_src_y,
    146                     pu1_src_u,
    147                     pu1_src_v,
    148                     pu1_dst_y,
    149                     pu1_dst_u,
    150                     u4_num_rows,
    151                     ps_dec->u2_horizontal_size,
    152                     ps_dec->u2_frame_width,
    153                     ps_dec->u2_frame_width >> 1,
    154                     ps_dec->u2_frame_width >> 1,
    155                     dest_inc_Y,
    156                     dest_inc_UV,
    157                     convert_uv_only);
    158         }
    159 
    160 
    161 
    162     }
    163 
    164 }
    165 
    166 
    167 /*******************************************************************************
    168 *
    169 *  Function Name   : impeg2d_get_frm_buf
    170 *
    171 *  Description     : Gets YUV component buffers for the frame
    172 *
    173 *  Arguments       :
    174 *  frm_buf         : YUV buffer
    175 *  frm             : Reference frame
    176 *  width           : Width of the frame
    177 *  Height          : Height of the frame
    178 *
    179 *  Values Returned : None
    180 *******************************************************************************/
    181 void impeg2d_get_frm_buf(yuv_buf_t *ps_frm_buf,UWORD8 *pu1_frm,UWORD32 u4_width,UWORD32 u4_height)
    182 {
    183    UWORD32 u4_luma_size = u4_width * u4_height;
    184    UWORD32 u4_chroma_size = (u4_width * u4_height)>>2;
    185 
    186    ps_frm_buf->pu1_y = pu1_frm;
    187    ps_frm_buf->pu1_u = pu1_frm + u4_luma_size;
    188    ps_frm_buf->pu1_v = pu1_frm + u4_luma_size + u4_chroma_size;
    189 
    190 }
    191 /*******************************************************************************
    192 *
    193 *  Function Name   : impeg2d_get_bottom_field_buf
    194 *
    195 *  Description     : Gets YUV component buffers for bottom field of the frame
    196 *
    197 *  Arguments       :
    198 *  frm_buf         : YUV buffer
    199 *  frm             : Reference frame
    200 *  width           : Width of the frame
    201 *  Height          : Height of the frame
    202 *
    203 *  Values Returned : None
    204 *******************************************************************************/
    205 void impeg2d_get_bottom_field_buf(yuv_buf_t *ps_src_buf,yuv_buf_t *ps_dst_buf,
    206                       UWORD32 u4_width)
    207 {
    208    ps_dst_buf->pu1_y = ps_src_buf->pu1_y + u4_width;
    209    ps_dst_buf->pu1_u = ps_src_buf->pu1_u + (u4_width>>1);
    210    ps_dst_buf->pu1_v = ps_src_buf->pu1_v + (u4_width>>1);
    211 
    212 }
    213 /*******************************************************************************
    214 *  Function Name   : impeg2d_get_mb_addr_incr
    215 *
    216 *  Description     : Decodes the Macroblock address increment
    217 *
    218 *  Arguments       :
    219 *  stream          : Bitstream
    220 *
    221 *  Values Returned : Macroblock address increment
    222 *******************************************************************************/
    223 UWORD16 impeg2d_get_mb_addr_incr(stream_t *ps_stream)
    224 {
    225     UWORD16 u2_mb_addr_incr = 0;
    226     while (impeg2d_bit_stream_nxt(ps_stream,MB_ESCAPE_CODE_LEN) == MB_ESCAPE_CODE &&
    227             ps_stream->u4_offset < ps_stream->u4_max_offset)
    228     {
    229         impeg2d_bit_stream_flush(ps_stream,MB_ESCAPE_CODE_LEN);
    230         u2_mb_addr_incr += 33;
    231     }
    232     u2_mb_addr_incr += impeg2d_dec_vld_symbol(ps_stream,gai2_impeg2d_mb_addr_incr,MB_ADDR_INCR_LEN) +
    233         MB_ADDR_INCR_OFFSET;
    234     return(u2_mb_addr_incr);
    235 }
    236 
    237 /*******************************************************************************
    238 *
    239 *  Function Name   : impeg2d_init_video_state
    240 *
    241 *  Description     : Initializes the Video decoder state
    242 *
    243 *  Arguments       :
    244 *  dec             : Decoder context
    245 *  videoType       : MPEG_2_Video / MPEG_1_Video
    246 *
    247 *  Values Returned : None
    248 *******************************************************************************/
    249 IMPEG2D_ERROR_CODES_T impeg2d_init_video_state(dec_state_t *ps_dec, e_video_type_t e_video_type)
    250 {
    251     /*-----------------------------------------------------------------------*/
    252     /* Bit Stream  that conforms to MPEG-1 <ISO/IEC 11172-2> standard        */
    253     /*-----------------------------------------------------------------------*/
    254     if(e_video_type == MPEG_1_VIDEO)
    255     {
    256         ps_dec->u2_is_mpeg2 = 0;
    257 
    258         /*-------------------------------------------------------------------*/
    259         /* force MPEG-1 parameters for proper decoder behavior               */
    260         /* see ISO/IEC 13818-2 section D.9.14                                */
    261         /*-------------------------------------------------------------------*/
    262         ps_dec->u2_progressive_sequence         = 1;
    263         ps_dec->u2_intra_dc_precision           = 0;
    264         ps_dec->u2_picture_structure            = FRAME_PICTURE;
    265         ps_dec->u2_frame_pred_frame_dct         = 1;
    266         ps_dec->u2_concealment_motion_vectors   = 0;
    267         ps_dec->u2_q_scale_type                 = 0;
    268         ps_dec->u2_intra_vlc_format             = 0;
    269         ps_dec->u2_alternate_scan               = 0;
    270         ps_dec->u2_repeat_first_field           = 0;
    271         ps_dec->u2_progressive_frame            = 1;
    272         ps_dec->u2_frame_rate_extension_n       = 0;
    273         ps_dec->u2_frame_rate_extension_d       = 0;
    274 
    275         ps_dec->pf_vld_inv_quant                  = impeg2d_vld_inv_quant_mpeg1;
    276         /*-------------------------------------------------------------------*/
    277         /* Setting of parameters other than those mentioned in MPEG2 standard*/
    278         /* but used in decoding process.                                     */
    279         /*-------------------------------------------------------------------*/
    280     }
    281     /*-----------------------------------------------------------------------*/
    282     /* Bit Stream  that conforms to MPEG-2                                   */
    283     /*-----------------------------------------------------------------------*/
    284     else
    285     {
    286         ps_dec->u2_is_mpeg2                  = 1;
    287         ps_dec->u2_full_pel_forw_vector   = 0;
    288         ps_dec->u2_forw_f_code            = 7;
    289         ps_dec->u2_full_pel_back_vector   = 0;
    290         ps_dec->u2_back_f_code            = 7;
    291         ps_dec->pf_vld_inv_quant       = impeg2d_vld_inv_quant_mpeg2;
    292 
    293 
    294     }
    295 
    296 
    297     impeg2d_init_function_ptr(ps_dec);
    298 
    299     /* Set the frame Width and frame Height */
    300     ps_dec->u2_frame_height        = ALIGN16(ps_dec->u2_vertical_size);
    301     ps_dec->u2_frame_width         = ALIGN16(ps_dec->u2_horizontal_size);
    302     ps_dec->u2_num_horiz_mb         = (ps_dec->u2_horizontal_size + 15) >> 4;
    303    // dec->u4_frm_buf_stride    = dec->frameWidth;
    304     if (ps_dec->u2_frame_height > ps_dec->u2_create_max_height || ps_dec->u2_frame_width > ps_dec->u2_create_max_width)
    305     {
    306         return IMPEG2D_PIC_SIZE_NOT_SUPPORTED;
    307     }
    308 
    309     ps_dec->u2_num_flds_decoded = 0;
    310 
    311     /* Calculate the frame period */
    312     {
    313         UWORD32 numer;
    314         UWORD32 denom;
    315         numer = (UWORD32)gau2_impeg2_frm_rate_code[ps_dec->u2_frame_rate_code][1] *
    316                                 (UWORD32)(ps_dec->u2_frame_rate_extension_d + 1);
    317 
    318         denom = (UWORD32)gau2_impeg2_frm_rate_code[ps_dec->u2_frame_rate_code][0] *
    319                                 (UWORD32)(ps_dec->u2_frame_rate_extension_n + 1);
    320         ps_dec->u2_framePeriod =  (numer * 1000 * 100) / denom;
    321     }
    322 
    323 
    324    if(VERTICAL_SCAN == ps_dec->u2_alternate_scan)
    325    {
    326     ps_dec->pu1_inv_scan_matrix = (UWORD8 *)gau1_impeg2_inv_scan_vertical;
    327    }
    328    else
    329    {
    330     ps_dec->pu1_inv_scan_matrix = (UWORD8 *)gau1_impeg2_inv_scan_zig_zag;
    331    }
    332    return (IMPEG2D_ERROR_CODES_T)IVD_ERROR_NONE;
    333 }
    334 /*******************************************************************************
    335 *
    336 *  Function Name   : impeg2d_pre_pic_dec_proc
    337 *
    338 *  Description     : Does the processing neccessary before picture decoding
    339 *
    340 *  Arguments       :
    341 *  dec             : Decoder context
    342 *
    343 *  Values Returned : None
    344 *******************************************************************************/
    345 IMPEG2D_ERROR_CODES_T impeg2d_pre_pic_dec_proc(dec_state_t *ps_dec)
    346 {
    347     WORD32 u4_get_disp;
    348     pic_buf_t *ps_disp_pic;
    349     IMPEG2D_ERROR_CODES_T e_error = (IMPEG2D_ERROR_CODES_T)IVD_ERROR_NONE;
    350 
    351     u4_get_disp = 0;
    352     ps_disp_pic = NULL;
    353 
    354     /* Field Picture */
    355     if(ps_dec->u2_picture_structure != FRAME_PICTURE)
    356     {
    357         ps_dec->u2_num_vert_mb       = (ps_dec->u2_vertical_size + 31) >> 5;
    358 
    359         if(ps_dec->u2_num_flds_decoded == 0)
    360         {
    361             pic_buf_t *ps_pic_buf;
    362             u4_get_disp = 1;
    363 
    364             ps_pic_buf = impeg2_buf_mgr_get_next_free(ps_dec->pv_pic_buf_mg, &ps_dec->i4_cur_buf_id);
    365 
    366             if (NULL == ps_pic_buf)
    367             {
    368                 return IMPEG2D_NO_FREE_BUF_ERR;
    369             }
    370 
    371             impeg2_buf_mgr_set_status((buf_mgr_t *)ps_dec->pv_pic_buf_mg, ps_dec->i4_cur_buf_id, BUF_MGR_DISP);
    372             impeg2_buf_mgr_set_status((buf_mgr_t *)ps_dec->pv_pic_buf_mg, ps_dec->i4_cur_buf_id, BUF_MGR_REF);
    373             if(ps_dec->u4_deinterlace)
    374                 impeg2_buf_mgr_set_status((buf_mgr_t *)ps_dec->pv_pic_buf_mg, ps_dec->i4_cur_buf_id, MPEG2_BUF_MGR_DEINT);
    375 
    376             ps_pic_buf->u4_ts = ps_dec->u4_inp_ts;
    377             ps_pic_buf->e_pic_type = ps_dec->e_pic_type;
    378             ps_dec->ps_cur_pic = ps_pic_buf;
    379             ps_dec->s_cur_frm_buf.pu1_y = ps_pic_buf->pu1_y;
    380             ps_dec->s_cur_frm_buf.pu1_u = ps_pic_buf->pu1_u;
    381             ps_dec->s_cur_frm_buf.pu1_v = ps_pic_buf->pu1_v;
    382         }
    383 
    384         if(ps_dec->u2_picture_structure == TOP_FIELD)
    385         {
    386             ps_dec->u2_fld_parity = TOP;
    387         }
    388         else
    389         {
    390             ps_dec->u2_fld_parity = BOTTOM;
    391         }
    392         ps_dec->u2_field_dct           = 0;
    393         ps_dec->u2_read_dct_type        = 0;
    394         ps_dec->u2_read_motion_type     = 1;
    395         ps_dec->u2_fld_pic             = 1;
    396         ps_dec->u2_frm_pic             = 0;
    397         ps_dec->ps_func_forw_or_back     = gas_impeg2d_func_fld_fw_or_bk;
    398         ps_dec->ps_func_bi_direct       = gas_impeg2d_func_fld_bi_direct;
    399    }
    400     /* Frame Picture */
    401     else
    402     {
    403         pic_buf_t *ps_pic_buf;
    404 
    405 
    406         ps_dec->u2_num_vert_mb       = (ps_dec->u2_vertical_size + 15) >> 4;
    407         u4_get_disp = 1;
    408         ps_pic_buf = impeg2_buf_mgr_get_next_free(ps_dec->pv_pic_buf_mg, &ps_dec->i4_cur_buf_id);
    409 
    410         if (NULL == ps_pic_buf)
    411         {
    412             return IMPEG2D_NO_FREE_BUF_ERR;
    413         }
    414         impeg2_buf_mgr_set_status((buf_mgr_t *)ps_dec->pv_pic_buf_mg, ps_dec->i4_cur_buf_id, BUF_MGR_DISP);
    415         impeg2_buf_mgr_set_status((buf_mgr_t *)ps_dec->pv_pic_buf_mg, ps_dec->i4_cur_buf_id, BUF_MGR_REF);
    416         if(ps_dec->u4_deinterlace)
    417             impeg2_buf_mgr_set_status((buf_mgr_t *)ps_dec->pv_pic_buf_mg, ps_dec->i4_cur_buf_id, MPEG2_BUF_MGR_DEINT);
    418 
    419         ps_pic_buf->u4_ts = ps_dec->u4_inp_ts;
    420         ps_pic_buf->e_pic_type = ps_dec->e_pic_type;
    421         ps_dec->ps_cur_pic = ps_pic_buf;
    422         ps_dec->s_cur_frm_buf.pu1_y = ps_pic_buf->pu1_y;
    423         ps_dec->s_cur_frm_buf.pu1_u = ps_pic_buf->pu1_u;
    424         ps_dec->s_cur_frm_buf.pu1_v = ps_pic_buf->pu1_v;
    425 
    426 
    427         if(ps_dec->u2_frame_pred_frame_dct == 0)
    428         {
    429             ps_dec->u2_read_dct_type    = 1;
    430             ps_dec->u2_read_motion_type = 1;
    431         }
    432         else
    433         {
    434             ps_dec->u2_read_dct_type    = 0;
    435             ps_dec->u2_read_motion_type = 0;
    436             ps_dec->u2_motion_type     = 2;
    437             ps_dec->u2_field_dct       = 0;
    438         }
    439 
    440         ps_dec->u2_fld_parity          = TOP;
    441         ps_dec->u2_fld_pic             = 0;
    442         ps_dec->u2_frm_pic             = 1;
    443         ps_dec->ps_func_forw_or_back     = gas_impeg2d_func_frm_fw_or_bk;
    444         ps_dec->ps_func_bi_direct       = gas_impeg2d_func_frm_bi_direct;
    445    }
    446     ps_dec->u2_def_dc_pred[Y_LUMA]   = 128 << ps_dec->u2_intra_dc_precision;
    447     ps_dec->u2_def_dc_pred[U_CHROMA]   = 128 << ps_dec->u2_intra_dc_precision;
    448     ps_dec->u2_def_dc_pred[V_CHROMA]   = 128 << ps_dec->u2_intra_dc_precision;
    449     ps_dec->u2_num_mbs_left  = ps_dec->u2_num_horiz_mb * ps_dec->u2_num_vert_mb;
    450     if(u4_get_disp)
    451     {
    452         if(ps_dec->u4_num_frames_decoded > 1)
    453         {
    454             ps_disp_pic = impeg2_disp_mgr_get(&ps_dec->s_disp_mgr, &ps_dec->i4_disp_buf_id);
    455         }
    456         ps_dec->ps_disp_pic = ps_disp_pic;
    457         if(ps_disp_pic)
    458         {
    459             if(1 == ps_dec->u4_share_disp_buf)
    460             {
    461                 ps_dec->ps_disp_frm_buf->pv_y_buf  = ps_disp_pic->pu1_y;
    462                 if(IV_YUV_420P == ps_dec->i4_chromaFormat)
    463                 {
    464                     ps_dec->ps_disp_frm_buf->pv_u_buf  = ps_disp_pic->pu1_u;
    465                     ps_dec->ps_disp_frm_buf->pv_v_buf  = ps_disp_pic->pu1_v;
    466                 }
    467                 else
    468                 {
    469                     UWORD8 *pu1_buf;
    470 
    471                     pu1_buf = ps_dec->as_disp_buffers[ps_disp_pic->i4_buf_id].pu1_bufs[1];
    472                     ps_dec->ps_disp_frm_buf->pv_u_buf  = pu1_buf;
    473 
    474                     pu1_buf = ps_dec->as_disp_buffers[ps_disp_pic->i4_buf_id].pu1_bufs[2];
    475                     ps_dec->ps_disp_frm_buf->pv_v_buf  = pu1_buf;
    476                 }
    477             }
    478         }
    479     }
    480 
    481 
    482     switch(ps_dec->e_pic_type)
    483     {
    484     case I_PIC:
    485         {
    486             ps_dec->pf_decode_slice = impeg2d_dec_i_slice;
    487             break;
    488         }
    489     case D_PIC:
    490         {
    491             ps_dec->pf_decode_slice = impeg2d_dec_d_slice;
    492             break;
    493         }
    494     case P_PIC:
    495         {
    496             ps_dec->pf_decode_slice = impeg2d_dec_p_b_slice;
    497             ps_dec->pu2_mb_type       = gau2_impeg2d_p_mb_type;
    498             break;
    499         }
    500     case B_PIC:
    501         {
    502             ps_dec->pf_decode_slice = impeg2d_dec_p_b_slice;
    503             ps_dec->pu2_mb_type       = gau2_impeg2d_b_mb_type;
    504             break;
    505         }
    506     default:
    507         return IMPEG2D_INVALID_PIC_TYPE;
    508     }
    509 
    510     /*************************************************************************/
    511     /* Set the reference pictures                                            */
    512     /*************************************************************************/
    513 
    514     /* Error resilience: If forward and backward pictures are going to be NULL*/
    515     /* then assign both to the current                                        */
    516     /* if one of them NULL then we will assign the non null to the NULL one   */
    517 
    518     if(ps_dec->e_pic_type == P_PIC)
    519     {
    520         if (NULL == ps_dec->as_recent_fld[1][0].pu1_y)
    521         {
    522             ps_dec->as_recent_fld[1][0] = ps_dec->s_cur_frm_buf;
    523         }
    524         if (NULL == ps_dec->as_recent_fld[1][1].pu1_y)
    525         {
    526             impeg2d_get_bottom_field_buf(&ps_dec->s_cur_frm_buf, &ps_dec->as_recent_fld[1][1],
    527                 ps_dec->u2_frame_width);
    528         }
    529 
    530         ps_dec->as_ref_buf[FORW][TOP]    = ps_dec->as_recent_fld[1][0];
    531         ps_dec->as_ref_buf[FORW][BOTTOM] = ps_dec->as_recent_fld[1][1];
    532 
    533 
    534     }
    535     else if(ps_dec->e_pic_type == B_PIC)
    536     {
    537         if((NULL == ps_dec->as_recent_fld[1][0].pu1_y) && (NULL == ps_dec->as_recent_fld[0][0].pu1_y))
    538         {
    539             // assign the current picture to both
    540             ps_dec->as_recent_fld[1][0] = ps_dec->s_cur_frm_buf;
    541             impeg2d_get_bottom_field_buf(&ps_dec->s_cur_frm_buf, &ps_dec->as_recent_fld[1][1],
    542                 ps_dec->u2_frame_width);
    543             ps_dec->as_recent_fld[0][0] = ps_dec->s_cur_frm_buf;
    544             ps_dec->as_recent_fld[0][1] = ps_dec->as_recent_fld[1][1];
    545         }
    546         //Assign the non-null picture to the null picture
    547         else if ((NULL != ps_dec->as_recent_fld[1][0].pu1_y) && (NULL == ps_dec->as_recent_fld[0][0].pu1_y))
    548         {
    549             ps_dec->as_recent_fld[0][0] = ps_dec->as_recent_fld[1][0];
    550             ps_dec->as_recent_fld[0][1] = ps_dec->as_recent_fld[1][1];
    551         }
    552         else if ((NULL == ps_dec->as_recent_fld[1][0].pu1_y) && (NULL != ps_dec->as_recent_fld[0][0].pu1_y))
    553         {
    554             ps_dec->as_recent_fld[1][0] = ps_dec->as_recent_fld[0][0];
    555             ps_dec->as_recent_fld[1][1] = ps_dec->as_recent_fld[0][1];
    556         }
    557 
    558         /* Error resilience: If forward and backward pictures are going to be NULL*/
    559         /* then assign both to the current                                        */
    560         /* if one of them NULL then we will assign the non null to the NULL one   */
    561 
    562         if((NULL == ps_dec->as_recent_fld[0][1].pu1_y) && (NULL == ps_dec->as_recent_fld[1][1].pu1_y))
    563         {
    564             // assign the current picture to both
    565             ps_dec->as_recent_fld[1][0] = ps_dec->s_cur_frm_buf;
    566             impeg2d_get_bottom_field_buf(&ps_dec->s_cur_frm_buf, &ps_dec->as_recent_fld[1][1],
    567                                          ps_dec->u2_frame_width);
    568             ps_dec->as_recent_fld[0][0] = ps_dec->s_cur_frm_buf;
    569             ps_dec->as_recent_fld[0][1] = ps_dec->as_recent_fld[1][1];
    570         }
    571         //Assign the non-null picture to the null picture
    572 
    573         else if((NULL == ps_dec->as_recent_fld[0][1].pu1_y) && (NULL != ps_dec->as_recent_fld[1][1].pu1_y))
    574         {
    575             ps_dec->as_recent_fld[0][0] = ps_dec->as_recent_fld[1][0];
    576             ps_dec->as_recent_fld[0][1] = ps_dec->as_recent_fld[1][1];
    577         }
    578 
    579         else if((NULL == ps_dec->as_recent_fld[1][1].pu1_y) && (NULL != ps_dec->as_recent_fld[0][1].pu1_y))
    580         {
    581             ps_dec->as_recent_fld[1][0] = ps_dec->as_recent_fld[0][0];
    582             ps_dec->as_recent_fld[1][1] = ps_dec->as_recent_fld[0][1];
    583         }
    584         ps_dec->as_ref_buf[FORW][TOP]    = ps_dec->as_recent_fld[0][0];
    585         ps_dec->as_ref_buf[FORW][BOTTOM] = ps_dec->as_recent_fld[0][1];
    586         ps_dec->as_ref_buf[BACK][TOP]    = ps_dec->as_recent_fld[1][0];
    587         ps_dec->as_ref_buf[BACK][BOTTOM] = ps_dec->as_recent_fld[1][1];
    588 
    589 
    590     }
    591 
    592     return e_error;
    593 }
    594 
    595 /*******************************************************************************
    596 *
    597 *  Function Name   : impeg2d_post_pic_dec_proc
    598 *
    599 *  Description     : Performs processing that is needed at the end of picture
    600 *                    decode
    601 *
    602 *  Arguments       :
    603 *  dec             : Decoder context
    604 *
    605 *  Values Returned : None
    606 *******************************************************************************/
    607 void impeg2d_post_pic_dec_proc(dec_state_t *ps_dec)
    608 {
    609 
    610    WORD32 u4_update_pic_buf = 0;
    611     /*************************************************************************/
    612     /* Processing at the end of picture                                      */
    613     /*************************************************************************/
    614     if(ps_dec->u2_picture_structure != FRAME_PICTURE)
    615     {
    616         ps_dec->u2_num_vert_mb       = (ps_dec->u2_vertical_size + 31) >> 5;
    617 
    618         if(ps_dec->u2_num_flds_decoded == 1)
    619         {
    620             ps_dec->u2_num_flds_decoded = 0;
    621             u4_update_pic_buf = 1;
    622         }
    623         else
    624         {
    625             ps_dec->u2_num_flds_decoded = 1;
    626         }
    627     }
    628     else
    629     {
    630         u4_update_pic_buf = 1;
    631     }
    632 
    633     if(u4_update_pic_buf)
    634     {
    635         ps_dec->i4_frame_decoded = 1;
    636         if(ps_dec->e_pic_type != B_PIC)
    637         {
    638             /* In any sequence first two pictures have to be reference pictures */
    639             /* Adding of first picture in the sequence */
    640             if(ps_dec->aps_ref_pics[0] == NULL)
    641             {
    642                 ps_dec->aps_ref_pics[0] = ps_dec->ps_cur_pic;
    643             }
    644 
    645             /* Adding of second picture in the sequence */
    646             else if(ps_dec->aps_ref_pics[1] == NULL)
    647             {
    648                 ps_dec->aps_ref_pics[1] = ps_dec->ps_cur_pic;
    649                 impeg2_disp_mgr_add(&ps_dec->s_disp_mgr, ps_dec->aps_ref_pics[0], ps_dec->aps_ref_pics[0]->i4_buf_id);
    650             }
    651             else
    652             {
    653 
    654                 impeg2_disp_mgr_add(&ps_dec->s_disp_mgr, ps_dec->aps_ref_pics[1], ps_dec->aps_ref_pics[1]->i4_buf_id);
    655                 impeg2_buf_mgr_release(ps_dec->pv_pic_buf_mg, ps_dec->aps_ref_pics[0]->i4_buf_id, BUF_MGR_REF);
    656                 ps_dec->aps_ref_pics[0] = ps_dec->aps_ref_pics[1];
    657                 ps_dec->aps_ref_pics[1] = ps_dec->ps_cur_pic;
    658 
    659             }
    660         }
    661         else
    662         {
    663             impeg2_disp_mgr_add(&ps_dec->s_disp_mgr, ps_dec->ps_cur_pic, ps_dec->ps_cur_pic->i4_buf_id);
    664 
    665             impeg2_buf_mgr_release(ps_dec->pv_pic_buf_mg, ps_dec->ps_cur_pic->i4_buf_id, BUF_MGR_REF);
    666         }
    667 
    668     }
    669     /*************************************************************************/
    670     /* Update the list of recent reference pictures                          */
    671     /*************************************************************************/
    672     if(ps_dec->e_pic_type != B_PIC)
    673     {
    674         switch(ps_dec->u2_picture_structure)
    675         {
    676         case FRAME_PICTURE:
    677             {
    678                 ps_dec->as_recent_fld[0][0] = ps_dec->as_recent_fld[1][0];
    679                 ps_dec->as_recent_fld[0][1] = ps_dec->as_recent_fld[1][1];
    680 
    681                 ps_dec->as_recent_fld[1][0] = ps_dec->s_cur_frm_buf;
    682                 impeg2d_get_bottom_field_buf(&ps_dec->s_cur_frm_buf, &ps_dec->as_recent_fld[1][1],
    683                 ps_dec->u2_frame_width);
    684                 break;
    685             }
    686         case TOP_FIELD:
    687             {
    688                 ps_dec->as_recent_fld[0][0] = ps_dec->as_recent_fld[1][0];
    689                 ps_dec->as_recent_fld[1][0] = ps_dec->s_cur_frm_buf;
    690                 break;
    691             }
    692         case BOTTOM_FIELD:
    693             {
    694                 ps_dec->as_recent_fld[0][1] = ps_dec->as_recent_fld[1][1];
    695                 impeg2d_get_bottom_field_buf(&ps_dec->s_cur_frm_buf, &ps_dec->as_recent_fld[1][1],
    696                 ps_dec->u2_frame_width);
    697                 break;
    698             }
    699         }
    700     }
    701 }
    702