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