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