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