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 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 *******************************************************************************/ 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->u4_ts = ps_dec->u4_inp_ts; 379 ps_pic_buf->e_pic_type = ps_dec->e_pic_type; 380 ps_dec->ps_cur_pic = ps_pic_buf; 381 ps_dec->s_cur_frm_buf.pu1_y = ps_pic_buf->pu1_y; 382 ps_dec->s_cur_frm_buf.pu1_u = ps_pic_buf->pu1_u; 383 ps_dec->s_cur_frm_buf.pu1_v = ps_pic_buf->pu1_v; 384 } 385 386 if(ps_dec->u2_picture_structure == TOP_FIELD) 387 { 388 ps_dec->u2_fld_parity = TOP; 389 } 390 else 391 { 392 ps_dec->u2_fld_parity = BOTTOM; 393 } 394 ps_dec->u2_field_dct = 0; 395 ps_dec->u2_read_dct_type = 0; 396 ps_dec->u2_read_motion_type = 1; 397 ps_dec->u2_fld_pic = 1; 398 ps_dec->u2_frm_pic = 0; 399 ps_dec->ps_func_forw_or_back = gas_impeg2d_func_fld_fw_or_bk; 400 ps_dec->ps_func_bi_direct = gas_impeg2d_func_fld_bi_direct; 401 } 402 /* Frame Picture */ 403 else 404 { 405 pic_buf_t *ps_pic_buf; 406 407 408 ps_dec->u2_num_vert_mb = (ps_dec->u2_vertical_size + 15) >> 4; 409 u4_get_disp = 1; 410 ps_pic_buf = impeg2_buf_mgr_get_next_free(ps_dec->pv_pic_buf_mg, &ps_dec->i4_cur_buf_id); 411 412 if (NULL == ps_pic_buf) 413 { 414 return IMPEG2D_NO_FREE_BUF_ERR; 415 } 416 impeg2_buf_mgr_set_status((buf_mgr_t *)ps_dec->pv_pic_buf_mg, ps_dec->i4_cur_buf_id, BUF_MGR_DISP); 417 impeg2_buf_mgr_set_status((buf_mgr_t *)ps_dec->pv_pic_buf_mg, ps_dec->i4_cur_buf_id, BUF_MGR_REF); 418 if(ps_dec->u4_deinterlace) 419 impeg2_buf_mgr_set_status((buf_mgr_t *)ps_dec->pv_pic_buf_mg, ps_dec->i4_cur_buf_id, MPEG2_BUF_MGR_DEINT); 420 421 ps_pic_buf->u4_ts = ps_dec->u4_inp_ts; 422 ps_pic_buf->e_pic_type = ps_dec->e_pic_type; 423 ps_dec->ps_cur_pic = ps_pic_buf; 424 ps_dec->s_cur_frm_buf.pu1_y = ps_pic_buf->pu1_y; 425 ps_dec->s_cur_frm_buf.pu1_u = ps_pic_buf->pu1_u; 426 ps_dec->s_cur_frm_buf.pu1_v = ps_pic_buf->pu1_v; 427 428 429 if(ps_dec->u2_frame_pred_frame_dct == 0) 430 { 431 ps_dec->u2_read_dct_type = 1; 432 ps_dec->u2_read_motion_type = 1; 433 } 434 else 435 { 436 ps_dec->u2_read_dct_type = 0; 437 ps_dec->u2_read_motion_type = 0; 438 ps_dec->u2_motion_type = 2; 439 ps_dec->u2_field_dct = 0; 440 } 441 442 ps_dec->u2_fld_parity = TOP; 443 ps_dec->u2_fld_pic = 0; 444 ps_dec->u2_frm_pic = 1; 445 ps_dec->ps_func_forw_or_back = gas_impeg2d_func_frm_fw_or_bk; 446 ps_dec->ps_func_bi_direct = gas_impeg2d_func_frm_bi_direct; 447 } 448 ps_dec->u2_def_dc_pred[Y_LUMA] = 128 << ps_dec->u2_intra_dc_precision; 449 ps_dec->u2_def_dc_pred[U_CHROMA] = 128 << ps_dec->u2_intra_dc_precision; 450 ps_dec->u2_def_dc_pred[V_CHROMA] = 128 << ps_dec->u2_intra_dc_precision; 451 ps_dec->u2_num_mbs_left = ps_dec->u2_num_horiz_mb * ps_dec->u2_num_vert_mb; 452 if(u4_get_disp) 453 { 454 if(ps_dec->u4_num_frames_decoded > 1) 455 { 456 ps_disp_pic = impeg2_disp_mgr_get(&ps_dec->s_disp_mgr, &ps_dec->i4_disp_buf_id); 457 } 458 ps_dec->ps_disp_pic = ps_disp_pic; 459 if(ps_disp_pic) 460 { 461 if(1 == ps_dec->u4_share_disp_buf) 462 { 463 ps_dec->ps_disp_frm_buf->pv_y_buf = ps_disp_pic->pu1_y; 464 if(IV_YUV_420P == ps_dec->i4_chromaFormat) 465 { 466 ps_dec->ps_disp_frm_buf->pv_u_buf = ps_disp_pic->pu1_u; 467 ps_dec->ps_disp_frm_buf->pv_v_buf = ps_disp_pic->pu1_v; 468 } 469 else 470 { 471 UWORD8 *pu1_buf; 472 473 pu1_buf = ps_dec->as_disp_buffers[ps_disp_pic->i4_buf_id].pu1_bufs[1]; 474 ps_dec->ps_disp_frm_buf->pv_u_buf = pu1_buf; 475 476 pu1_buf = ps_dec->as_disp_buffers[ps_disp_pic->i4_buf_id].pu1_bufs[2]; 477 ps_dec->ps_disp_frm_buf->pv_v_buf = pu1_buf; 478 } 479 } 480 } 481 } 482 483 484 switch(ps_dec->e_pic_type) 485 { 486 case I_PIC: 487 { 488 ps_dec->pf_decode_slice = impeg2d_dec_i_slice; 489 break; 490 } 491 case D_PIC: 492 { 493 ps_dec->pf_decode_slice = impeg2d_dec_d_slice; 494 break; 495 } 496 case P_PIC: 497 { 498 ps_dec->pf_decode_slice = impeg2d_dec_p_b_slice; 499 ps_dec->pu2_mb_type = gau2_impeg2d_p_mb_type; 500 break; 501 } 502 case B_PIC: 503 { 504 ps_dec->pf_decode_slice = impeg2d_dec_p_b_slice; 505 ps_dec->pu2_mb_type = gau2_impeg2d_b_mb_type; 506 break; 507 } 508 default: 509 return IMPEG2D_INVALID_PIC_TYPE; 510 } 511 512 /*************************************************************************/ 513 /* Set the reference pictures */ 514 /*************************************************************************/ 515 516 /* Error resilience: If forward and backward pictures are going to be NULL*/ 517 /* then assign both to the current */ 518 /* if one of them NULL then we will assign the non null to the NULL one */ 519 520 if(ps_dec->e_pic_type == P_PIC) 521 { 522 if (NULL == ps_dec->as_recent_fld[1][0].pu1_y) 523 { 524 ps_dec->as_recent_fld[1][0] = ps_dec->s_cur_frm_buf; 525 } 526 if (NULL == ps_dec->as_recent_fld[1][1].pu1_y) 527 { 528 impeg2d_get_bottom_field_buf(&ps_dec->s_cur_frm_buf, &ps_dec->as_recent_fld[1][1], 529 ps_dec->u2_frame_width); 530 } 531 532 ps_dec->as_ref_buf[FORW][TOP] = ps_dec->as_recent_fld[1][0]; 533 ps_dec->as_ref_buf[FORW][BOTTOM] = ps_dec->as_recent_fld[1][1]; 534 535 536 } 537 else if(ps_dec->e_pic_type == B_PIC) 538 { 539 if((NULL == ps_dec->as_recent_fld[1][0].pu1_y) && (NULL == ps_dec->as_recent_fld[0][0].pu1_y)) 540 { 541 // assign the current picture to both 542 ps_dec->as_recent_fld[1][0] = ps_dec->s_cur_frm_buf; 543 impeg2d_get_bottom_field_buf(&ps_dec->s_cur_frm_buf, &ps_dec->as_recent_fld[1][1], 544 ps_dec->u2_frame_width); 545 ps_dec->as_recent_fld[0][0] = ps_dec->s_cur_frm_buf; 546 ps_dec->as_recent_fld[0][1] = ps_dec->as_recent_fld[1][1]; 547 } 548 //Assign the non-null picture to the null picture 549 else if ((NULL != ps_dec->as_recent_fld[1][0].pu1_y) && (NULL == ps_dec->as_recent_fld[0][0].pu1_y)) 550 { 551 ps_dec->as_recent_fld[0][0] = ps_dec->as_recent_fld[1][0]; 552 ps_dec->as_recent_fld[0][1] = ps_dec->as_recent_fld[1][1]; 553 } 554 else if ((NULL == ps_dec->as_recent_fld[1][0].pu1_y) && (NULL != ps_dec->as_recent_fld[0][0].pu1_y)) 555 { 556 ps_dec->as_recent_fld[1][0] = ps_dec->as_recent_fld[0][0]; 557 ps_dec->as_recent_fld[1][1] = ps_dec->as_recent_fld[0][1]; 558 } 559 560 /* Error resilience: If forward and backward pictures are going to be NULL*/ 561 /* then assign both to the current */ 562 /* if one of them NULL then we will assign the non null to the NULL one */ 563 564 if((NULL == ps_dec->as_recent_fld[0][1].pu1_y) && (NULL == ps_dec->as_recent_fld[1][1].pu1_y)) 565 { 566 // assign the current picture to both 567 ps_dec->as_recent_fld[1][0] = ps_dec->s_cur_frm_buf; 568 impeg2d_get_bottom_field_buf(&ps_dec->s_cur_frm_buf, &ps_dec->as_recent_fld[1][1], 569 ps_dec->u2_frame_width); 570 ps_dec->as_recent_fld[0][0] = ps_dec->s_cur_frm_buf; 571 ps_dec->as_recent_fld[0][1] = ps_dec->as_recent_fld[1][1]; 572 } 573 //Assign the non-null picture to the null picture 574 575 else if((NULL == ps_dec->as_recent_fld[0][1].pu1_y) && (NULL != ps_dec->as_recent_fld[1][1].pu1_y)) 576 { 577 ps_dec->as_recent_fld[0][0] = ps_dec->as_recent_fld[1][0]; 578 ps_dec->as_recent_fld[0][1] = ps_dec->as_recent_fld[1][1]; 579 } 580 581 else if((NULL == ps_dec->as_recent_fld[1][1].pu1_y) && (NULL != ps_dec->as_recent_fld[0][1].pu1_y)) 582 { 583 ps_dec->as_recent_fld[1][0] = ps_dec->as_recent_fld[0][0]; 584 ps_dec->as_recent_fld[1][1] = ps_dec->as_recent_fld[0][1]; 585 } 586 ps_dec->as_ref_buf[FORW][TOP] = ps_dec->as_recent_fld[0][0]; 587 ps_dec->as_ref_buf[FORW][BOTTOM] = ps_dec->as_recent_fld[0][1]; 588 ps_dec->as_ref_buf[BACK][TOP] = ps_dec->as_recent_fld[1][0]; 589 ps_dec->as_ref_buf[BACK][BOTTOM] = ps_dec->as_recent_fld[1][1]; 590 591 592 } 593 594 return e_error; 595 } 596 597 /******************************************************************************* 598 * 599 * Function Name : impeg2d_post_pic_dec_proc 600 * 601 * Description : Performs processing that is needed at the end of picture 602 * decode 603 * 604 * Arguments : 605 * dec : Decoder context 606 * 607 * Values Returned : None 608 *******************************************************************************/ 609 void impeg2d_post_pic_dec_proc(dec_state_t *ps_dec) 610 { 611 612 WORD32 u4_update_pic_buf = 0; 613 /*************************************************************************/ 614 /* Processing at the end of picture */ 615 /*************************************************************************/ 616 if(ps_dec->u2_picture_structure != FRAME_PICTURE) 617 { 618 ps_dec->u2_num_vert_mb = (ps_dec->u2_vertical_size + 31) >> 5; 619 620 if(ps_dec->u2_num_flds_decoded == 1) 621 { 622 ps_dec->u2_num_flds_decoded = 0; 623 u4_update_pic_buf = 1; 624 } 625 else 626 { 627 ps_dec->u2_num_flds_decoded = 1; 628 } 629 } 630 else 631 { 632 u4_update_pic_buf = 1; 633 } 634 635 if(u4_update_pic_buf) 636 { 637 ps_dec->i4_frame_decoded = 1; 638 if(ps_dec->e_pic_type != B_PIC) 639 { 640 /* In any sequence first two pictures have to be reference pictures */ 641 /* Adding of first picture in the sequence */ 642 if(ps_dec->aps_ref_pics[0] == NULL) 643 { 644 ps_dec->aps_ref_pics[0] = ps_dec->ps_cur_pic; 645 } 646 647 /* Adding of second picture in the sequence */ 648 else if(ps_dec->aps_ref_pics[1] == NULL) 649 { 650 ps_dec->aps_ref_pics[1] = ps_dec->ps_cur_pic; 651 impeg2_disp_mgr_add(&ps_dec->s_disp_mgr, ps_dec->aps_ref_pics[0], ps_dec->aps_ref_pics[0]->i4_buf_id); 652 } 653 else 654 { 655 656 impeg2_disp_mgr_add(&ps_dec->s_disp_mgr, ps_dec->aps_ref_pics[1], ps_dec->aps_ref_pics[1]->i4_buf_id); 657 impeg2_buf_mgr_release(ps_dec->pv_pic_buf_mg, ps_dec->aps_ref_pics[0]->i4_buf_id, BUF_MGR_REF); 658 ps_dec->aps_ref_pics[0] = ps_dec->aps_ref_pics[1]; 659 ps_dec->aps_ref_pics[1] = ps_dec->ps_cur_pic; 660 661 } 662 } 663 else 664 { 665 impeg2_disp_mgr_add(&ps_dec->s_disp_mgr, ps_dec->ps_cur_pic, ps_dec->ps_cur_pic->i4_buf_id); 666 667 impeg2_buf_mgr_release(ps_dec->pv_pic_buf_mg, ps_dec->ps_cur_pic->i4_buf_id, BUF_MGR_REF); 668 } 669 670 } 671 /*************************************************************************/ 672 /* Update the list of recent reference pictures */ 673 /*************************************************************************/ 674 if(ps_dec->e_pic_type != B_PIC) 675 { 676 switch(ps_dec->u2_picture_structure) 677 { 678 case FRAME_PICTURE: 679 { 680 ps_dec->as_recent_fld[0][0] = ps_dec->as_recent_fld[1][0]; 681 ps_dec->as_recent_fld[0][1] = ps_dec->as_recent_fld[1][1]; 682 683 ps_dec->as_recent_fld[1][0] = ps_dec->s_cur_frm_buf; 684 impeg2d_get_bottom_field_buf(&ps_dec->s_cur_frm_buf, &ps_dec->as_recent_fld[1][1], 685 ps_dec->u2_frame_width); 686 break; 687 } 688 case TOP_FIELD: 689 { 690 ps_dec->as_recent_fld[0][0] = ps_dec->as_recent_fld[1][0]; 691 ps_dec->as_recent_fld[1][0] = ps_dec->s_cur_frm_buf; 692 break; 693 } 694 case BOTTOM_FIELD: 695 { 696 ps_dec->as_recent_fld[0][1] = ps_dec->as_recent_fld[1][1]; 697 impeg2d_get_bottom_field_buf(&ps_dec->s_cur_frm_buf, &ps_dec->as_recent_fld[1][1], 698 ps_dec->u2_frame_width); 699 break; 700 } 701 } 702 } 703 } 704