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