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