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