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