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); 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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