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
47void impeg2d_init_function_ptr(void *pv_codec);
48void 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*******************************************************************************/
181void 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*******************************************************************************/
205void 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*******************************************************************************/
223UWORD16 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*******************************************************************************/
249IMPEG2D_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*******************************************************************************/
345IMPEG2D_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*******************************************************************************/
607void 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