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         ps_dec->u2_forw_f_code                  = 7;
    275         ps_dec->u2_back_f_code                  = 7;
    276 
    277         ps_dec->pf_vld_inv_quant                  = impeg2d_vld_inv_quant_mpeg1;
    278         /*-------------------------------------------------------------------*/
    279         /* Setting of parameters other than those mentioned in MPEG2 standard*/
    280         /* but used in decoding process.                                     */
    281         /*-------------------------------------------------------------------*/
    282     }
    283     /*-----------------------------------------------------------------------*/
    284     /* Bit Stream  that conforms to MPEG-2                                   */
    285     /*-----------------------------------------------------------------------*/
    286     else
    287     {
    288         ps_dec->u2_is_mpeg2                  = 1;
    289         ps_dec->u2_full_pel_forw_vector   = 0;
    290         ps_dec->u2_forw_f_code            = 7;
    291         ps_dec->u2_full_pel_back_vector   = 0;
    292         ps_dec->u2_back_f_code            = 7;
    293         ps_dec->pf_vld_inv_quant       = impeg2d_vld_inv_quant_mpeg2;
    294 
    295 
    296     }
    297 
    298 
    299     impeg2d_init_function_ptr(ps_dec);
    300 
    301     /* Set the frame Width and frame Height */
    302     ps_dec->u2_frame_height        = ALIGN16(ps_dec->u2_vertical_size);
    303     ps_dec->u2_frame_width         = ALIGN16(ps_dec->u2_horizontal_size);
    304     ps_dec->u2_num_horiz_mb         = (ps_dec->u2_horizontal_size + 15) >> 4;
    305    // dec->u4_frm_buf_stride    = dec->frameWidth;
    306     if (ps_dec->u2_frame_height > ps_dec->u2_create_max_height || ps_dec->u2_frame_width > ps_dec->u2_create_max_width)
    307     {
    308         return IMPEG2D_PIC_SIZE_NOT_SUPPORTED;
    309     }
    310 
    311     ps_dec->u2_num_flds_decoded = 0;
    312 
    313     /* Calculate the frame period */
    314     {
    315         UWORD32 numer;
    316         UWORD32 denom;
    317         numer = (UWORD32)gau2_impeg2_frm_rate_code[ps_dec->u2_frame_rate_code][1] *
    318                                 (UWORD32)(ps_dec->u2_frame_rate_extension_d + 1);
    319 
    320         denom = (UWORD32)gau2_impeg2_frm_rate_code[ps_dec->u2_frame_rate_code][0] *
    321                                 (UWORD32)(ps_dec->u2_frame_rate_extension_n + 1);
    322         ps_dec->u2_framePeriod =  (numer * 1000 * 100) / denom;
    323     }
    324 
    325 
    326    if(VERTICAL_SCAN == ps_dec->u2_alternate_scan)
    327    {
    328     ps_dec->pu1_inv_scan_matrix = (UWORD8 *)gau1_impeg2_inv_scan_vertical;
    329    }
    330    else
    331    {
    332     ps_dec->pu1_inv_scan_matrix = (UWORD8 *)gau1_impeg2_inv_scan_zig_zag;
    333    }
    334    return (IMPEG2D_ERROR_CODES_T)IVD_ERROR_NONE;
    335 }
    336 /*******************************************************************************
    337 *
    338 *  Function Name   : impeg2d_pre_pic_dec_proc
    339 *
    340 *  Description     : Does the processing neccessary before picture decoding
    341 *
    342 *  Arguments       :
    343 *  dec             : Decoder context
    344 *
    345 *  Values Returned : None
    346 *******************************************************************************/
    347 IMPEG2D_ERROR_CODES_T impeg2d_pre_pic_dec_proc(dec_state_t *ps_dec)
    348 {
    349     WORD32 u4_get_disp;
    350     pic_buf_t *ps_disp_pic;
    351     IMPEG2D_ERROR_CODES_T e_error = (IMPEG2D_ERROR_CODES_T)IVD_ERROR_NONE;
    352 
    353     u4_get_disp = 0;
    354     ps_disp_pic = NULL;
    355 
    356     /* Field Picture */
    357     if(ps_dec->u2_picture_structure != FRAME_PICTURE)
    358     {
    359         ps_dec->u2_num_vert_mb       = (ps_dec->u2_vertical_size + 31) >> 5;
    360 
    361         if(ps_dec->u2_num_flds_decoded == 0)
    362         {
    363             pic_buf_t *ps_pic_buf;
    364             u4_get_disp = 1;
    365 
    366             ps_pic_buf = impeg2_buf_mgr_get_next_free(ps_dec->pv_pic_buf_mg, &ps_dec->i4_cur_buf_id);
    367 
    368             if (NULL == ps_pic_buf)
    369             {
    370                 return IMPEG2D_NO_FREE_BUF_ERR;
    371             }
    372 
    373             impeg2_buf_mgr_set_status((buf_mgr_t *)ps_dec->pv_pic_buf_mg, ps_dec->i4_cur_buf_id, BUF_MGR_DISP);
    374             impeg2_buf_mgr_set_status((buf_mgr_t *)ps_dec->pv_pic_buf_mg, ps_dec->i4_cur_buf_id, BUF_MGR_REF);
    375             if(ps_dec->u4_deinterlace)
    376                 impeg2_buf_mgr_set_status((buf_mgr_t *)ps_dec->pv_pic_buf_mg, ps_dec->i4_cur_buf_id, MPEG2_BUF_MGR_DEINT);
    377 
    378             ps_pic_buf->u4_ts = ps_dec->u4_inp_ts;
    379             ps_pic_buf->e_pic_type = ps_dec->e_pic_type;
    380             ps_dec->ps_cur_pic = ps_pic_buf;
    381             ps_dec->s_cur_frm_buf.pu1_y = ps_pic_buf->pu1_y;
    382             ps_dec->s_cur_frm_buf.pu1_u = ps_pic_buf->pu1_u;
    383             ps_dec->s_cur_frm_buf.pu1_v = ps_pic_buf->pu1_v;
    384         }
    385 
    386         if(ps_dec->u2_picture_structure == TOP_FIELD)
    387         {
    388             ps_dec->u2_fld_parity = TOP;
    389         }
    390         else
    391         {
    392             ps_dec->u2_fld_parity = BOTTOM;
    393         }
    394         ps_dec->u2_field_dct           = 0;
    395         ps_dec->u2_read_dct_type        = 0;
    396         ps_dec->u2_read_motion_type     = 1;
    397         ps_dec->u2_fld_pic             = 1;
    398         ps_dec->u2_frm_pic             = 0;
    399         ps_dec->ps_func_forw_or_back     = gas_impeg2d_func_fld_fw_or_bk;
    400         ps_dec->ps_func_bi_direct       = gas_impeg2d_func_fld_bi_direct;
    401    }
    402     /* Frame Picture */
    403     else
    404     {
    405         pic_buf_t *ps_pic_buf;
    406 
    407 
    408         ps_dec->u2_num_vert_mb       = (ps_dec->u2_vertical_size + 15) >> 4;
    409         u4_get_disp = 1;
    410         ps_pic_buf = impeg2_buf_mgr_get_next_free(ps_dec->pv_pic_buf_mg, &ps_dec->i4_cur_buf_id);
    411 
    412         if (NULL == ps_pic_buf)
    413         {
    414             return IMPEG2D_NO_FREE_BUF_ERR;
    415         }
    416         impeg2_buf_mgr_set_status((buf_mgr_t *)ps_dec->pv_pic_buf_mg, ps_dec->i4_cur_buf_id, BUF_MGR_DISP);
    417         impeg2_buf_mgr_set_status((buf_mgr_t *)ps_dec->pv_pic_buf_mg, ps_dec->i4_cur_buf_id, BUF_MGR_REF);
    418         if(ps_dec->u4_deinterlace)
    419             impeg2_buf_mgr_set_status((buf_mgr_t *)ps_dec->pv_pic_buf_mg, ps_dec->i4_cur_buf_id, MPEG2_BUF_MGR_DEINT);
    420 
    421         ps_pic_buf->u4_ts = ps_dec->u4_inp_ts;
    422         ps_pic_buf->e_pic_type = ps_dec->e_pic_type;
    423         ps_dec->ps_cur_pic = ps_pic_buf;
    424         ps_dec->s_cur_frm_buf.pu1_y = ps_pic_buf->pu1_y;
    425         ps_dec->s_cur_frm_buf.pu1_u = ps_pic_buf->pu1_u;
    426         ps_dec->s_cur_frm_buf.pu1_v = ps_pic_buf->pu1_v;
    427 
    428 
    429         if(ps_dec->u2_frame_pred_frame_dct == 0)
    430         {
    431             ps_dec->u2_read_dct_type    = 1;
    432             ps_dec->u2_read_motion_type = 1;
    433         }
    434         else
    435         {
    436             ps_dec->u2_read_dct_type    = 0;
    437             ps_dec->u2_read_motion_type = 0;
    438             ps_dec->u2_motion_type     = 2;
    439             ps_dec->u2_field_dct       = 0;
    440         }
    441 
    442         ps_dec->u2_fld_parity          = TOP;
    443         ps_dec->u2_fld_pic             = 0;
    444         ps_dec->u2_frm_pic             = 1;
    445         ps_dec->ps_func_forw_or_back     = gas_impeg2d_func_frm_fw_or_bk;
    446         ps_dec->ps_func_bi_direct       = gas_impeg2d_func_frm_bi_direct;
    447    }
    448     ps_dec->u2_def_dc_pred[Y_LUMA]   = 128 << ps_dec->u2_intra_dc_precision;
    449     ps_dec->u2_def_dc_pred[U_CHROMA]   = 128 << ps_dec->u2_intra_dc_precision;
    450     ps_dec->u2_def_dc_pred[V_CHROMA]   = 128 << ps_dec->u2_intra_dc_precision;
    451     ps_dec->u2_num_mbs_left  = ps_dec->u2_num_horiz_mb * ps_dec->u2_num_vert_mb;
    452     if(u4_get_disp)
    453     {
    454         if(ps_dec->u4_num_frames_decoded > 1)
    455         {
    456             ps_disp_pic = impeg2_disp_mgr_get(&ps_dec->s_disp_mgr, &ps_dec->i4_disp_buf_id);
    457         }
    458         ps_dec->ps_disp_pic = ps_disp_pic;
    459         if(ps_disp_pic)
    460         {
    461             if(1 == ps_dec->u4_share_disp_buf)
    462             {
    463                 ps_dec->ps_disp_frm_buf->pv_y_buf  = ps_disp_pic->pu1_y;
    464                 if(IV_YUV_420P == ps_dec->i4_chromaFormat)
    465                 {
    466                     ps_dec->ps_disp_frm_buf->pv_u_buf  = ps_disp_pic->pu1_u;
    467                     ps_dec->ps_disp_frm_buf->pv_v_buf  = ps_disp_pic->pu1_v;
    468                 }
    469                 else
    470                 {
    471                     UWORD8 *pu1_buf;
    472 
    473                     pu1_buf = ps_dec->as_disp_buffers[ps_disp_pic->i4_buf_id].pu1_bufs[1];
    474                     ps_dec->ps_disp_frm_buf->pv_u_buf  = pu1_buf;
    475 
    476                     pu1_buf = ps_dec->as_disp_buffers[ps_disp_pic->i4_buf_id].pu1_bufs[2];
    477                     ps_dec->ps_disp_frm_buf->pv_v_buf  = pu1_buf;
    478                 }
    479             }
    480         }
    481     }
    482 
    483 
    484     switch(ps_dec->e_pic_type)
    485     {
    486     case I_PIC:
    487         {
    488             ps_dec->pf_decode_slice = impeg2d_dec_i_slice;
    489             break;
    490         }
    491     case D_PIC:
    492         {
    493             ps_dec->pf_decode_slice = impeg2d_dec_d_slice;
    494             break;
    495         }
    496     case P_PIC:
    497         {
    498             ps_dec->pf_decode_slice = impeg2d_dec_p_b_slice;
    499             ps_dec->pu2_mb_type       = gau2_impeg2d_p_mb_type;
    500             break;
    501         }
    502     case B_PIC:
    503         {
    504             ps_dec->pf_decode_slice = impeg2d_dec_p_b_slice;
    505             ps_dec->pu2_mb_type       = gau2_impeg2d_b_mb_type;
    506             break;
    507         }
    508     default:
    509         return IMPEG2D_INVALID_PIC_TYPE;
    510     }
    511 
    512     /*************************************************************************/
    513     /* Set the reference pictures                                            */
    514     /*************************************************************************/
    515 
    516     /* Error resilience: If forward and backward pictures are going to be NULL*/
    517     /* then assign both to the current                                        */
    518     /* if one of them NULL then we will assign the non null to the NULL one   */
    519 
    520     if(ps_dec->e_pic_type == P_PIC)
    521     {
    522         if (NULL == ps_dec->as_recent_fld[1][0].pu1_y)
    523         {
    524             ps_dec->as_recent_fld[1][0] = ps_dec->s_cur_frm_buf;
    525         }
    526         if (NULL == ps_dec->as_recent_fld[1][1].pu1_y)
    527         {
    528             impeg2d_get_bottom_field_buf(&ps_dec->s_cur_frm_buf, &ps_dec->as_recent_fld[1][1],
    529                 ps_dec->u2_frame_width);
    530         }
    531 
    532         ps_dec->as_ref_buf[FORW][TOP]    = ps_dec->as_recent_fld[1][0];
    533         ps_dec->as_ref_buf[FORW][BOTTOM] = ps_dec->as_recent_fld[1][1];
    534 
    535 
    536     }
    537     else if(ps_dec->e_pic_type == B_PIC)
    538     {
    539         if((NULL == ps_dec->as_recent_fld[1][0].pu1_y) && (NULL == ps_dec->as_recent_fld[0][0].pu1_y))
    540         {
    541             // assign the current picture to both
    542             ps_dec->as_recent_fld[1][0] = ps_dec->s_cur_frm_buf;
    543             impeg2d_get_bottom_field_buf(&ps_dec->s_cur_frm_buf, &ps_dec->as_recent_fld[1][1],
    544                 ps_dec->u2_frame_width);
    545             ps_dec->as_recent_fld[0][0] = ps_dec->s_cur_frm_buf;
    546             ps_dec->as_recent_fld[0][1] = ps_dec->as_recent_fld[1][1];
    547         }
    548         //Assign the non-null picture to the null picture
    549         else if ((NULL != ps_dec->as_recent_fld[1][0].pu1_y) && (NULL == ps_dec->as_recent_fld[0][0].pu1_y))
    550         {
    551             ps_dec->as_recent_fld[0][0] = ps_dec->as_recent_fld[1][0];
    552             ps_dec->as_recent_fld[0][1] = ps_dec->as_recent_fld[1][1];
    553         }
    554         else if ((NULL == ps_dec->as_recent_fld[1][0].pu1_y) && (NULL != ps_dec->as_recent_fld[0][0].pu1_y))
    555         {
    556             ps_dec->as_recent_fld[1][0] = ps_dec->as_recent_fld[0][0];
    557             ps_dec->as_recent_fld[1][1] = ps_dec->as_recent_fld[0][1];
    558         }
    559 
    560         /* Error resilience: If forward and backward pictures are going to be NULL*/
    561         /* then assign both to the current                                        */
    562         /* if one of them NULL then we will assign the non null to the NULL one   */
    563 
    564         if((NULL == ps_dec->as_recent_fld[0][1].pu1_y) && (NULL == ps_dec->as_recent_fld[1][1].pu1_y))
    565         {
    566             // assign the current picture to both
    567             ps_dec->as_recent_fld[1][0] = ps_dec->s_cur_frm_buf;
    568             impeg2d_get_bottom_field_buf(&ps_dec->s_cur_frm_buf, &ps_dec->as_recent_fld[1][1],
    569                                          ps_dec->u2_frame_width);
    570             ps_dec->as_recent_fld[0][0] = ps_dec->s_cur_frm_buf;
    571             ps_dec->as_recent_fld[0][1] = ps_dec->as_recent_fld[1][1];
    572         }
    573         //Assign the non-null picture to the null picture
    574 
    575         else if((NULL == ps_dec->as_recent_fld[0][1].pu1_y) && (NULL != ps_dec->as_recent_fld[1][1].pu1_y))
    576         {
    577             ps_dec->as_recent_fld[0][0] = ps_dec->as_recent_fld[1][0];
    578             ps_dec->as_recent_fld[0][1] = ps_dec->as_recent_fld[1][1];
    579         }
    580 
    581         else if((NULL == ps_dec->as_recent_fld[1][1].pu1_y) && (NULL != ps_dec->as_recent_fld[0][1].pu1_y))
    582         {
    583             ps_dec->as_recent_fld[1][0] = ps_dec->as_recent_fld[0][0];
    584             ps_dec->as_recent_fld[1][1] = ps_dec->as_recent_fld[0][1];
    585         }
    586         ps_dec->as_ref_buf[FORW][TOP]    = ps_dec->as_recent_fld[0][0];
    587         ps_dec->as_ref_buf[FORW][BOTTOM] = ps_dec->as_recent_fld[0][1];
    588         ps_dec->as_ref_buf[BACK][TOP]    = ps_dec->as_recent_fld[1][0];
    589         ps_dec->as_ref_buf[BACK][BOTTOM] = ps_dec->as_recent_fld[1][1];
    590 
    591 
    592     }
    593 
    594     return e_error;
    595 }
    596 
    597 /*******************************************************************************
    598 *
    599 *  Function Name   : impeg2d_post_pic_dec_proc
    600 *
    601 *  Description     : Performs processing that is needed at the end of picture
    602 *                    decode
    603 *
    604 *  Arguments       :
    605 *  dec             : Decoder context
    606 *
    607 *  Values Returned : None
    608 *******************************************************************************/
    609 void impeg2d_post_pic_dec_proc(dec_state_t *ps_dec)
    610 {
    611 
    612    WORD32 u4_update_pic_buf = 0;
    613     /*************************************************************************/
    614     /* Processing at the end of picture                                      */
    615     /*************************************************************************/
    616     if(ps_dec->u2_picture_structure != FRAME_PICTURE)
    617     {
    618         ps_dec->u2_num_vert_mb       = (ps_dec->u2_vertical_size + 31) >> 5;
    619 
    620         if(ps_dec->u2_num_flds_decoded == 1)
    621         {
    622             ps_dec->u2_num_flds_decoded = 0;
    623             u4_update_pic_buf = 1;
    624         }
    625         else
    626         {
    627             ps_dec->u2_num_flds_decoded = 1;
    628         }
    629     }
    630     else
    631     {
    632         u4_update_pic_buf = 1;
    633     }
    634 
    635     if(u4_update_pic_buf)
    636     {
    637         ps_dec->i4_frame_decoded = 1;
    638         if(ps_dec->e_pic_type != B_PIC)
    639         {
    640             /* In any sequence first two pictures have to be reference pictures */
    641             /* Adding of first picture in the sequence */
    642             if(ps_dec->aps_ref_pics[0] == NULL)
    643             {
    644                 ps_dec->aps_ref_pics[0] = ps_dec->ps_cur_pic;
    645             }
    646 
    647             /* Adding of second picture in the sequence */
    648             else if(ps_dec->aps_ref_pics[1] == NULL)
    649             {
    650                 ps_dec->aps_ref_pics[1] = ps_dec->ps_cur_pic;
    651                 impeg2_disp_mgr_add(&ps_dec->s_disp_mgr, ps_dec->aps_ref_pics[0], ps_dec->aps_ref_pics[0]->i4_buf_id);
    652             }
    653             else
    654             {
    655 
    656                 impeg2_disp_mgr_add(&ps_dec->s_disp_mgr, ps_dec->aps_ref_pics[1], ps_dec->aps_ref_pics[1]->i4_buf_id);
    657                 impeg2_buf_mgr_release(ps_dec->pv_pic_buf_mg, ps_dec->aps_ref_pics[0]->i4_buf_id, BUF_MGR_REF);
    658                 ps_dec->aps_ref_pics[0] = ps_dec->aps_ref_pics[1];
    659                 ps_dec->aps_ref_pics[1] = ps_dec->ps_cur_pic;
    660 
    661             }
    662         }
    663         else
    664         {
    665             impeg2_disp_mgr_add(&ps_dec->s_disp_mgr, ps_dec->ps_cur_pic, ps_dec->ps_cur_pic->i4_buf_id);
    666 
    667             impeg2_buf_mgr_release(ps_dec->pv_pic_buf_mg, ps_dec->ps_cur_pic->i4_buf_id, BUF_MGR_REF);
    668         }
    669 
    670     }
    671     /*************************************************************************/
    672     /* Update the list of recent reference pictures                          */
    673     /*************************************************************************/
    674     if(ps_dec->e_pic_type != B_PIC)
    675     {
    676         switch(ps_dec->u2_picture_structure)
    677         {
    678         case FRAME_PICTURE:
    679             {
    680                 ps_dec->as_recent_fld[0][0] = ps_dec->as_recent_fld[1][0];
    681                 ps_dec->as_recent_fld[0][1] = ps_dec->as_recent_fld[1][1];
    682 
    683                 ps_dec->as_recent_fld[1][0] = ps_dec->s_cur_frm_buf;
    684                 impeg2d_get_bottom_field_buf(&ps_dec->s_cur_frm_buf, &ps_dec->as_recent_fld[1][1],
    685                 ps_dec->u2_frame_width);
    686                 break;
    687             }
    688         case TOP_FIELD:
    689             {
    690                 ps_dec->as_recent_fld[0][0] = ps_dec->as_recent_fld[1][0];
    691                 ps_dec->as_recent_fld[1][0] = ps_dec->s_cur_frm_buf;
    692                 break;
    693             }
    694         case BOTTOM_FIELD:
    695             {
    696                 ps_dec->as_recent_fld[0][1] = ps_dec->as_recent_fld[1][1];
    697                 impeg2d_get_bottom_field_buf(&ps_dec->s_cur_frm_buf, &ps_dec->as_recent_fld[1][1],
    698                 ps_dec->u2_frame_width);
    699                 break;
    700             }
    701         }
    702     }
    703 }
    704