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