1 /****************************************************************************** 2 * 3 * Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore 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 /** 19 ******************************************************************************* 20 * @file 21 * ihevcd_decode.c 22 * 23 * @brief 24 * Contains codecs main decode function 25 * 26 * @author 27 * Harish 28 * 29 * @par List of Functions: 30 * - fill_outargs() 31 * - ihevcd_decode 32 * @remarks 33 * None 34 * 35 ******************************************************************************* 36 */ 37 /*****************************************************************************/ 38 /* File Includes */ 39 /*****************************************************************************/ 40 #include <stdio.h> 41 #include <stddef.h> 42 #include <stdlib.h> 43 #include <string.h> 44 #include <assert.h> 45 46 #include "ihevc_typedefs.h" 47 #include "iv.h" 48 #include "ivd.h" 49 #include "ihevcd_cxa.h" 50 #include "ithread.h" 51 52 #include "ihevc_defs.h" 53 #include "ihevc_debug.h" 54 #include "ihevc_structs.h" 55 #include "ihevc_macros.h" 56 #include "ihevc_platform_macros.h" 57 #include "ihevc_cabac_tables.h" 58 #include "ihevc_disp_mgr.h" 59 #include "ihevc_buf_mgr.h" 60 #include "ihevc_dpb_mgr.h" 61 #include "ihevc_error.h" 62 63 #include "ihevcd_defs.h" 64 #include "ihevcd_function_selector.h" 65 #include "ihevcd_structs.h" 66 #include "ihevcd_error.h" 67 #include "ihevcd_nal.h" 68 #include "ihevcd_bitstream.h" 69 #include "ihevcd_fmt_conv.h" 70 #include "ihevcd_job_queue.h" 71 #include "ihevcd_debug.h" 72 #include "ihevcd_process_slice.h" 73 #include "ihevcd_ittiam_logo.h" 74 #include "ihevcd_profile.h" 75 76 #define NUM_FRAMES_LIMIT_ENABLED 0 77 78 #if NUM_FRAMES_LIMIT_ENABLED 79 #define NUM_FRAMES_LIMIT 3600 80 #else 81 #define NUM_FRAMES_LIMIT 0x7FFFFFFF 82 #endif 83 84 IHEVCD_ERROR_T ihevcd_fmt_conv(codec_t *ps_codec, 85 process_ctxt_t *ps_proc, 86 UWORD8 *pu1_y_dst, 87 UWORD8 *pu1_u_dst, 88 UWORD8 *pu1_v_dst, 89 WORD32 cur_row, 90 WORD32 num_rows); 91 WORD32 ihevcd_init(codec_t *ps_codec); 92 /*****************************************************************************/ 93 /* Function Prototypes */ 94 /*****************************************************************************/ 95 96 97 /** 98 ******************************************************************************* 99 * 100 * @brief Fills output arguments for decode process 101 * 102 * @par Description 103 * Fills elements in the output structure based on the current state 104 * 105 * @param[in] ps_codec 106 * Codec context 107 * 108 * @param[in] ps_dec_ip 109 * Pointer to input structure 110 * 111 * @param[in] ps_dec_op 112 * Pointer to output structure 113 * 114 * @returns none 115 * 116 * @remarks 117 * 118 ******************************************************************************* 119 */ 120 static UWORD32 ihevcd_map_error(IHEVCD_ERROR_T e_error) 121 { 122 UWORD32 error_code = 0; 123 error_code = e_error; 124 switch(error_code) 125 { 126 case IHEVCD_SUCCESS : 127 break; 128 case IHEVCD_INIT_NOT_DONE: 129 case IHEVCD_LEVEL_UNSUPPORTED: 130 case IHEVCD_NUM_REF_UNSUPPORTED: 131 case IHEVCD_NUM_REORDER_UNSUPPORTED: 132 case IHEVCD_NUM_EXTRA_DISP_UNSUPPORTED: 133 case IHEVCD_INSUFFICIENT_MEM_MVBANK: 134 case IHEVCD_INSUFFICIENT_MEM_PICBUF: 135 error_code |= 1 << IVD_FATALERROR; 136 break; 137 case IHEVCD_INVALID_DISP_STRD: 138 case IHEVCD_CXA_VERS_BUF_INSUFFICIENT: 139 case IHEVCD_UNSUPPORTED_VPS_ID: 140 case IHEVCD_UNSUPPORTED_SPS_ID: 141 case IHEVCD_UNSUPPORTED_PPS_ID: 142 case IHEVCD_UNSUPPORTED_CHROMA_FMT_IDC: 143 case IHEVCD_UNSUPPORTED_BIT_DEPTH: 144 case IHEVCD_BUF_MGR_ERROR: 145 case IHEVCD_NO_FREE_MVBANK: 146 case IHEVCD_NO_FREE_PICBUF: 147 case IHEVCD_SLICE_IN_HEADER_MODE: 148 case IHEVCD_END_OF_SEQUENCE: 149 break; 150 default: 151 break; 152 } 153 return error_code; 154 } 155 /** 156 ******************************************************************************* 157 * 158 * @brief Fills output arguments for decode process 159 * 160 * @par Description 161 * Fills elements in the output structure based on the current state 162 * 163 * @param[in] ps_codec 164 * Codec context 165 * 166 * @param[in] ps_dec_ip 167 * Pointer to input structure 168 * 169 * @param[in] ps_dec_op 170 * Pointer to output structure 171 * 172 * @returns none 173 * 174 * @remarks 175 * 176 ******************************************************************************* 177 */ 178 static void ihevcd_fill_outargs(codec_t *ps_codec, 179 ivd_video_decode_ip_t *ps_dec_ip, 180 ivd_video_decode_op_t *ps_dec_op) 181 { 182 183 ps_dec_op->u4_error_code = ihevcd_map_error((IHEVCD_ERROR_T)ps_codec->i4_error_code); 184 ps_dec_op->u4_num_bytes_consumed = ps_dec_ip->u4_num_Bytes 185 - ps_codec->i4_bytes_remaining; 186 if(ps_codec->i4_sps_done) 187 { 188 ps_dec_op->u4_pic_wd = ps_codec->i4_disp_wd; 189 ps_dec_op->u4_pic_ht = ps_codec->i4_disp_ht; 190 } 191 else if(ps_codec->i4_error_code == IHEVCD_UNSUPPORTED_DIMENSIONS) 192 { 193 ps_dec_op->u4_pic_wd = ps_codec->i4_new_max_wd; 194 ps_dec_op->u4_pic_ht = ps_codec->i4_new_max_ht; 195 } 196 else 197 { 198 ps_dec_op->u4_pic_wd = 0; 199 ps_dec_op->u4_pic_ht = 0; 200 } 201 202 ps_dec_op->e_pic_type = ps_codec->e_dec_pic_type; 203 ps_dec_op->u4_frame_decoded_flag = ps_codec->i4_pic_present; 204 ps_dec_op->u4_new_seq = 0; 205 206 ps_dec_op->u4_output_present = 0; 207 ps_dec_op->u4_progressive_frame_flag = 1; 208 ps_dec_op->u4_is_ref_flag = 1; 209 ps_dec_op->e_output_format = ps_codec->e_chroma_fmt; 210 ps_dec_op->u4_is_ref_flag = 1; 211 212 ps_dec_op->e4_fld_type = IV_FLD_TYPE_DEFAULT; 213 214 ps_dec_op->u4_ts = (UWORD32)(-1); 215 ps_dec_op->u4_disp_buf_id = ps_codec->i4_disp_buf_id; 216 if(ps_codec->i4_flush_mode) 217 { 218 ps_dec_op->u4_num_bytes_consumed = 0; 219 /*In the case of flush ,since no frame is decoded set pic type as invalid*/ 220 ps_dec_op->u4_is_ref_flag = 0; 221 ps_dec_op->e_pic_type = IV_NA_FRAME; 222 ps_dec_op->u4_frame_decoded_flag = 0; 223 224 } 225 /* If there is a display buffer */ 226 if(ps_codec->ps_disp_buf) 227 { 228 pic_buf_t *ps_disp_buf = ps_codec->ps_disp_buf; 229 230 ps_dec_op->u4_output_present = 1; 231 ps_dec_op->u4_ts = ps_disp_buf->u4_ts; 232 if((ps_codec->i4_flush_mode == 0) && (ps_codec->s_parse.i4_end_of_frame == 0)) 233 ps_dec_op->u4_output_present = 0; 234 ps_dec_op->s_disp_frm_buf.u4_y_wd = ps_codec->i4_disp_wd; 235 ps_dec_op->s_disp_frm_buf.u4_y_ht = ps_codec->i4_disp_ht; 236 237 if(ps_codec->i4_share_disp_buf) 238 { 239 ps_dec_op->s_disp_frm_buf.pv_y_buf = ps_disp_buf->pu1_luma; 240 if(ps_codec->e_chroma_fmt != IV_YUV_420P) 241 { 242 ps_dec_op->s_disp_frm_buf.pv_u_buf = ps_disp_buf->pu1_chroma; 243 ps_dec_op->s_disp_frm_buf.pv_v_buf = NULL; 244 } 245 else 246 { 247 ps_dec_op->s_disp_frm_buf.pv_u_buf = 248 ps_dec_ip->s_out_buffer.pu1_bufs[1]; 249 ps_dec_op->s_disp_frm_buf.pv_v_buf = 250 ps_dec_ip->s_out_buffer.pu1_bufs[2]; 251 252 } 253 ps_dec_op->s_disp_frm_buf.u4_y_strd = ps_codec->i4_strd; 254 255 } 256 else 257 { 258 ps_dec_op->s_disp_frm_buf.pv_y_buf = 259 ps_dec_ip->s_out_buffer.pu1_bufs[0]; 260 ps_dec_op->s_disp_frm_buf.pv_u_buf = 261 ps_dec_ip->s_out_buffer.pu1_bufs[1]; 262 ps_dec_op->s_disp_frm_buf.pv_v_buf = 263 ps_dec_ip->s_out_buffer.pu1_bufs[2]; 264 ps_dec_op->s_disp_frm_buf.u4_y_strd = ps_codec->i4_disp_strd; 265 } 266 267 if((IV_YUV_420SP_VU == ps_codec->e_chroma_fmt) 268 || (IV_YUV_420SP_UV == ps_codec->e_chroma_fmt)) 269 { 270 ps_dec_op->s_disp_frm_buf.u4_u_strd = 271 ps_dec_op->s_disp_frm_buf.u4_y_strd; 272 ps_dec_op->s_disp_frm_buf.u4_v_strd = 0; 273 ps_dec_op->s_disp_frm_buf.u4_u_wd = 274 ps_dec_op->s_disp_frm_buf.u4_y_wd; 275 ps_dec_op->s_disp_frm_buf.u4_v_wd = 0; 276 ps_dec_op->s_disp_frm_buf.u4_u_ht = 277 ps_dec_op->s_disp_frm_buf.u4_y_ht / 2; 278 ps_dec_op->s_disp_frm_buf.u4_v_ht = 0; 279 } 280 else if(IV_YUV_420P == ps_codec->e_chroma_fmt) 281 { 282 ps_dec_op->s_disp_frm_buf.u4_u_strd = 283 ps_dec_op->s_disp_frm_buf.u4_y_strd / 2; 284 ps_dec_op->s_disp_frm_buf.u4_v_strd = 285 ps_dec_op->s_disp_frm_buf.u4_y_strd / 2; 286 ps_dec_op->s_disp_frm_buf.u4_u_wd = 287 ps_dec_op->s_disp_frm_buf.u4_y_wd / 2; 288 ps_dec_op->s_disp_frm_buf.u4_v_wd = 289 ps_dec_op->s_disp_frm_buf.u4_y_wd / 2; 290 ps_dec_op->s_disp_frm_buf.u4_u_ht = 291 ps_dec_op->s_disp_frm_buf.u4_y_ht / 2; 292 ps_dec_op->s_disp_frm_buf.u4_v_ht = 293 ps_dec_op->s_disp_frm_buf.u4_y_ht / 2; 294 } 295 296 } 297 else if(ps_codec->i4_flush_mode) 298 { 299 ps_dec_op->u4_error_code = IHEVCD_END_OF_SEQUENCE; 300 /* Come out of flush mode */ 301 ps_codec->i4_flush_mode = 0; 302 } 303 304 } 305 306 /** 307 ******************************************************************************* 308 * 309 * @brief 310 * Codec process call 311 * 312 * @par Description: 313 * Codec process call Tests for few error checks Handle flush and decode 314 * header related code Parse bitstream for start codes For each NAL unit 315 * call decode NAL function Once a complete frame is decoded (in frame 316 * decode mode) Fill output arguments and return 317 * 318 * @param[in] ps_codec_obj 319 * Pointer to codec object at API level 320 * 321 * @param[in] pv_api_ip 322 * Pointer to input argument structure 323 * 324 * @param[in] pv_api_op 325 * Pointer to output argument structure 326 * 327 * @returns Status 328 * 329 * @remarks 330 * 331 * 332 ******************************************************************************* 333 */ 334 WORD32 ihevcd_decode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) 335 { 336 WORD32 ret = IV_SUCCESS; 337 codec_t *ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle); 338 ivd_video_decode_ip_t *ps_dec_ip; 339 ivd_video_decode_op_t *ps_dec_op; 340 341 WORD32 proc_idx = 0; 342 WORD32 prev_proc_idx = 0; 343 344 /* Initialize error code */ 345 ps_codec->i4_error_code = 0; 346 347 ps_dec_ip = (ivd_video_decode_ip_t *)pv_api_ip; 348 ps_dec_op = (ivd_video_decode_op_t *)pv_api_op; 349 350 memset(ps_dec_op, 0, sizeof(ivd_video_decode_op_t)); 351 if(ps_codec->i4_init_done != 1) 352 { 353 ps_dec_op->u4_error_code |= 1 << IVD_FATALERROR; 354 ps_dec_op->u4_error_code |= IHEVCD_INIT_NOT_DONE; 355 return IV_FAIL; 356 } 357 358 if(ps_codec->u4_pic_cnt >= NUM_FRAMES_LIMIT) 359 { 360 ps_dec_op->u4_error_code |= 1 << IVD_FATALERROR; 361 ps_dec_op->u4_error_code |= IHEVCD_NUM_FRAMES_LIMIT_REACHED; 362 return IV_FAIL; 363 } 364 365 /* If reset flag is set, flush the existing buffers */ 366 if(ps_codec->i4_reset_flag) 367 { 368 ps_codec->i4_flush_mode = 1; 369 } 370 371 /*Data memory barries instruction,so that bitstream write by the application is complete*/ 372 //arm_dsb(); 373 /* In case the decoder is not in flush mode check for input buffer validity */ 374 if(0 == ps_codec->i4_flush_mode) 375 { 376 if(ps_dec_ip->pv_stream_buffer == NULL) 377 { 378 ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; 379 ps_dec_op->u4_error_code |= IVD_DEC_FRM_BS_BUF_NULL; 380 return IV_FAIL; 381 } 382 if(ps_dec_ip->u4_num_Bytes <= MIN_START_CODE_LEN) 383 { 384 if((WORD32)ps_dec_ip->u4_num_Bytes > 0) 385 ps_dec_op->u4_num_bytes_consumed = ps_dec_ip->u4_num_Bytes; 386 else 387 ps_dec_op->u4_num_bytes_consumed = 0; 388 389 ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; 390 ps_dec_op->u4_error_code |= IVD_DEC_NUMBYTES_INV; 391 return IV_FAIL; 392 393 } 394 } 395 396 #ifdef APPLY_CONCEALMENT 397 { 398 WORD32 num_mbs; 399 400 num_mbs = (ps_codec->i4_wd * ps_codec->i4_ht + 255) >> 8; 401 /* Reset MB Count at the beginning of every process call */ 402 ps_codec->mb_count = 0; 403 memset(ps_codec->mb_map, 0, ((num_mbs + 7) >> 3)); 404 } 405 #endif 406 407 if(0 == ps_codec->i4_share_disp_buf && ps_codec->i4_header_mode == 0) 408 { 409 UWORD32 i; 410 if(ps_dec_ip->s_out_buffer.u4_num_bufs == 0) 411 { 412 ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; 413 ps_dec_op->u4_error_code |= IVD_DISP_FRM_ZERO_OP_BUFS; 414 return IV_FAIL; 415 } 416 417 for(i = 0; i < ps_dec_ip->s_out_buffer.u4_num_bufs; i++) 418 { 419 if(ps_dec_ip->s_out_buffer.pu1_bufs[i] == NULL) 420 { 421 ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; 422 ps_dec_op->u4_error_code |= IVD_DISP_FRM_OP_BUF_NULL; 423 return IV_FAIL; 424 } 425 426 if(ps_dec_ip->s_out_buffer.u4_min_out_buf_size[i] == 0) 427 { 428 ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; 429 ps_dec_op->u4_error_code |= IVD_DISP_FRM_ZERO_OP_BUF_SIZE; 430 return IV_FAIL; 431 } 432 } 433 } 434 435 ps_codec->ps_out_buffer = &ps_dec_ip->s_out_buffer; 436 ps_codec->u4_ts = ps_dec_ip->u4_ts; 437 if(ps_codec->i4_flush_mode) 438 { 439 440 ps_dec_op->u4_pic_wd = ps_codec->i4_disp_wd; 441 ps_dec_op->u4_pic_ht = ps_codec->i4_disp_ht; 442 443 ps_dec_op->u4_new_seq = 0; 444 445 ps_codec->ps_disp_buf = (pic_buf_t *)ihevc_disp_mgr_get( 446 (disp_mgr_t *)ps_codec->pv_disp_buf_mgr, &ps_codec->i4_disp_buf_id); 447 /* In case of non-shared mode, then convert/copy the frame to output buffer */ 448 /* Only if the codec is in non-shared mode or in shared mode but needs 420P output */ 449 if((ps_codec->ps_disp_buf) 450 && ((0 == ps_codec->i4_share_disp_buf) 451 || (IV_YUV_420P 452 == ps_codec->e_chroma_fmt))) 453 { 454 455 process_ctxt_t *ps_proc = &ps_codec->as_process[prev_proc_idx]; 456 if(0 == ps_proc->i4_init_done) 457 { 458 ihevcd_init_proc_ctxt(ps_proc, 0); 459 } 460 461 /* Set remaining number of rows to be processed */ 462 ret = ihevcd_fmt_conv(ps_codec, &ps_codec->as_process[prev_proc_idx], 463 ps_dec_ip->s_out_buffer.pu1_bufs[0], 464 ps_dec_ip->s_out_buffer.pu1_bufs[1], 465 ps_dec_ip->s_out_buffer.pu1_bufs[2], 0, 466 ps_codec->i4_disp_ht); 467 468 ihevc_buf_mgr_release((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, 469 ps_codec->i4_disp_buf_id, BUF_MGR_DISP); 470 } 471 472 ihevcd_fill_outargs(ps_codec, ps_dec_ip, ps_dec_op); 473 474 if(1 == ps_dec_op->u4_output_present) 475 { 476 WORD32 xpos = ps_codec->i4_disp_wd - 32 - LOGO_WD; 477 WORD32 ypos = ps_codec->i4_disp_ht - 32 - LOGO_HT; 478 479 if(ypos < 0) 480 ypos = 0; 481 482 if(xpos < 0) 483 xpos = 0; 484 485 INSERT_LOGO(ps_dec_ip->s_out_buffer.pu1_bufs[0], 486 ps_dec_ip->s_out_buffer.pu1_bufs[1], 487 ps_dec_ip->s_out_buffer.pu1_bufs[2], ps_codec->i4_disp_strd, 488 xpos, 489 ypos, 490 ps_codec->e_chroma_fmt, 491 ps_codec->i4_disp_wd, 492 ps_codec->i4_disp_ht); 493 } 494 495 496 if(NULL == ps_codec->ps_disp_buf) 497 { 498 /* If in flush mode and there are no more buffers to flush, 499 * check for the reset flag and reset the decoder */ 500 if(ps_codec->i4_reset_flag) 501 { 502 ihevcd_init(ps_codec); 503 } 504 return (IV_FAIL); 505 } 506 507 return (IV_SUCCESS); 508 509 } 510 /* In case of shared mode, check if there is a free buffer for reconstruction */ 511 if((0 == ps_codec->i4_header_mode) && (1 == ps_codec->i4_share_disp_buf)) 512 { 513 WORD32 buf_status; 514 buf_status = 1; 515 if(ps_codec->pv_pic_buf_mgr) 516 buf_status = ihevc_buf_mgr_check_free((buf_mgr_t *)ps_codec->pv_pic_buf_mgr); 517 518 /* If there is no free buffer, then return with an error code */ 519 if(0 == buf_status) 520 { 521 ps_dec_op->u4_error_code = IVD_DEC_REF_BUF_NULL; 522 ps_dec_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM); 523 return IV_FAIL; 524 } 525 } 526 ps_codec->i4_bytes_remaining = ps_dec_ip->u4_num_Bytes; 527 ps_codec->pu1_inp_bitsbuf = (UWORD8 *)ps_dec_ip->pv_stream_buffer; 528 ps_codec->s_parse.i4_end_of_frame = 0; 529 530 ps_codec->i4_pic_present = 0; 531 ps_codec->i4_slice_error = 0; 532 ps_codec->ps_disp_buf = NULL; 533 534 if(ps_codec->i4_num_cores > 1) 535 { 536 ithread_set_affinity(0); 537 } 538 while(MIN_START_CODE_LEN < ps_codec->i4_bytes_remaining) 539 { 540 WORD32 nal_len; 541 WORD32 nal_ofst; 542 WORD32 bits_len; 543 544 if(ps_codec->i4_slice_error) 545 { 546 slice_header_t *ps_slice_hdr_next = ps_codec->s_parse.ps_slice_hdr_base + (ps_codec->s_parse.i4_cur_slice_idx & (MAX_SLICE_HDR_CNT - 1)); 547 WORD32 next_slice_addr = ps_slice_hdr_next->i2_ctb_x + 548 ps_slice_hdr_next->i2_ctb_y * ps_codec->s_parse.ps_sps->i2_pic_wd_in_ctb; 549 if(ps_codec->s_parse.i4_next_ctb_indx == next_slice_addr) 550 ps_codec->i4_slice_error = 0; 551 } 552 553 nal_ofst = ihevcd_nal_search_start_code(ps_codec->pu1_inp_bitsbuf, 554 ps_codec->i4_bytes_remaining); 555 556 ps_codec->i4_nal_ofst = nal_ofst; 557 { 558 WORD32 bytes_remaining = ps_codec->i4_bytes_remaining - nal_ofst; 559 560 bytes_remaining = MIN((UWORD32)bytes_remaining, ps_codec->u4_bitsbuf_size); 561 ihevcd_nal_remv_emuln_bytes(ps_codec->pu1_inp_bitsbuf + nal_ofst, 562 ps_codec->pu1_bitsbuf, 563 bytes_remaining, 564 &nal_len, &bits_len); 565 } 566 /* This may be used to update the offsets for tiles and entropy sync row offsets */ 567 ps_codec->i4_num_emln_bytes = nal_len - bits_len; 568 ps_codec->i4_nal_len = nal_len; 569 570 ihevcd_bits_init(&ps_codec->s_parse.s_bitstrm, ps_codec->pu1_bitsbuf, 571 bits_len); 572 573 ret = ihevcd_nal_unit(ps_codec); 574 575 /* If the frame is incomplete and 576 * the bytes remaining is zero or a header is received, 577 * complete the frame treating it to be in error */ 578 if(ps_codec->i4_pic_present && 579 (ps_codec->s_parse.i4_next_ctb_indx != ps_codec->s_parse.ps_sps->i4_pic_size_in_ctb)) 580 { 581 if((ps_codec->i4_bytes_remaining - (nal_len + nal_ofst) <= MIN_START_CODE_LEN) || 582 (ps_codec->i4_header_in_slice_mode)) 583 { 584 slice_header_t *ps_slice_hdr_next; 585 586 ps_codec->s_parse.i4_cur_slice_idx--; 587 if(ps_codec->s_parse.i4_cur_slice_idx < 0) 588 ps_codec->s_parse.i4_cur_slice_idx = 0; 589 590 ps_slice_hdr_next = ps_codec->s_parse.ps_slice_hdr_base + ((ps_codec->s_parse.i4_cur_slice_idx + 1) & (MAX_SLICE_HDR_CNT - 1)); 591 ps_slice_hdr_next->i2_ctb_x = 0; 592 ps_slice_hdr_next->i2_ctb_y = ps_codec->s_parse.ps_sps->i2_pic_ht_in_ctb; 593 ps_codec->i4_slice_error = 1; 594 continue; 595 } 596 } 597 598 if(IHEVCD_IGNORE_SLICE == ret) 599 { 600 ps_codec->pu1_inp_bitsbuf += (nal_ofst + nal_len); 601 ps_codec->i4_bytes_remaining -= (nal_ofst + nal_len); 602 603 continue; 604 } 605 606 if(((IHEVCD_FAIL == ret) && (ps_codec->i4_error_code == IVD_RES_CHANGED)) || 607 (IHEVCD_UNSUPPORTED_DIMENSIONS == ret)) 608 { 609 break; 610 } 611 612 /* Update bytes remaining and bytes consumed and input bitstream pointer */ 613 /* Do not consume the NAL in the following cases */ 614 /* Slice header reached during header decode mode */ 615 /* TODO: Next picture's slice reached */ 616 if(ret != IHEVCD_SLICE_IN_HEADER_MODE) 617 { 618 if((0 == ps_codec->i4_slice_error) || 619 (ps_codec->i4_bytes_remaining - (nal_len + nal_ofst) <= MIN_START_CODE_LEN)) 620 { 621 ps_codec->pu1_inp_bitsbuf += (nal_ofst + nal_len); 622 ps_codec->i4_bytes_remaining -= (nal_ofst + nal_len); 623 } 624 if(ret != IHEVCD_SUCCESS) 625 break; 626 627 if(ps_codec->s_parse.i4_end_of_frame) 628 break; 629 } 630 else 631 { 632 ret = IHEVCD_SUCCESS; 633 break; 634 } 635 636 BREAK_AFTER_SLICE_NAL(); 637 } 638 639 if((ps_codec->u4_pic_cnt == 0) && (ret != IHEVCD_SUCCESS)) 640 { 641 ps_codec->i4_error_code = ret; 642 643 ihevcd_fill_outargs(ps_codec, ps_dec_ip, ps_dec_op); 644 return IV_FAIL; 645 } 646 647 if(1 == ps_codec->i4_pic_present) 648 { 649 WORD32 i; 650 sps_t *ps_sps = ps_codec->s_parse.ps_sps; 651 ps_codec->i4_first_pic_done = 1; 652 653 /*TODO temporary fix: end_of_frame is checked before adding format conversion to job queue */ 654 if(ps_codec->i4_num_cores > 1 && ps_codec->s_parse.i4_end_of_frame) 655 { 656 657 /* Add job queue for format conversion / frame copy for each ctb row */ 658 /* Only if the codec is in non-shared mode or in shared mode but needs 420P output */ 659 process_ctxt_t *ps_proc; 660 661 /* i4_num_cores - 1 contexts are currently being used by other threads */ 662 ps_proc = &ps_codec->as_process[ps_codec->i4_num_cores - 1]; 663 664 if((ps_codec->ps_disp_buf) && 665 ((0 == ps_codec->i4_share_disp_buf) || (IV_YUV_420P == ps_codec->e_chroma_fmt))) 666 { 667 /* If format conversion jobs were not issued in pic_init() add them here */ 668 if((0 == ps_codec->u4_enable_fmt_conv_ahead) || 669 (ps_codec->i4_disp_buf_id == ps_proc->i4_cur_pic_buf_id)) 670 for(i = 0; i < ps_sps->i2_pic_ht_in_ctb; i++) 671 { 672 proc_job_t s_job; 673 IHEVCD_ERROR_T ret; 674 s_job.i4_cmd = CMD_FMTCONV; 675 s_job.i2_ctb_cnt = 0; 676 s_job.i2_ctb_x = 0; 677 s_job.i2_ctb_y = i; 678 s_job.i2_slice_idx = 0; 679 s_job.i4_tu_coeff_data_ofst = 0; 680 ret = ihevcd_jobq_queue((jobq_t *)ps_codec->s_parse.pv_proc_jobq, 681 &s_job, sizeof(proc_job_t), 1); 682 if(ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS) 683 return (WORD32)ret; 684 } 685 } 686 /* Reached end of frame : Signal terminate */ 687 /* The terminate flag is checked only after all the jobs are dequeued */ 688 ret = ihevcd_jobq_terminate((jobq_t *)ps_codec->s_parse.pv_proc_jobq); 689 690 while(1) 691 { 692 IHEVCD_ERROR_T ret; 693 proc_job_t s_job; 694 process_ctxt_t *ps_proc; 695 696 /* i4_num_cores - 1 contexts are currently being used by other threads */ 697 ps_proc = &ps_codec->as_process[ps_codec->i4_num_cores - 1]; 698 699 ret = ihevcd_jobq_dequeue((jobq_t *)ps_proc->pv_proc_jobq, &s_job, 700 sizeof(proc_job_t), 1); 701 if((IHEVCD_ERROR_T)IHEVCD_SUCCESS != ret) 702 break; 703 704 ps_proc->i4_ctb_cnt = s_job.i2_ctb_cnt; 705 ps_proc->i4_ctb_x = s_job.i2_ctb_x; 706 ps_proc->i4_ctb_y = s_job.i2_ctb_y; 707 ps_proc->i4_cur_slice_idx = s_job.i2_slice_idx; 708 709 if(CMD_PROCESS == s_job.i4_cmd) 710 { 711 ihevcd_init_proc_ctxt(ps_proc, s_job.i4_tu_coeff_data_ofst); 712 713 ihevcd_process(ps_proc); 714 } 715 else if(CMD_FMTCONV == s_job.i4_cmd) 716 { 717 sps_t *ps_sps = ps_codec->s_parse.ps_sps; 718 WORD32 num_rows = 1 << ps_sps->i1_log2_ctb_size; 719 if(0 == ps_proc->i4_init_done) 720 { 721 ihevcd_init_proc_ctxt(ps_proc, 0); 722 } 723 724 num_rows = MIN(num_rows, (ps_codec->i4_disp_ht - (s_job.i2_ctb_y << ps_sps->i1_log2_ctb_size))); 725 if(num_rows < 0) 726 num_rows = 0; 727 728 ihevcd_fmt_conv(ps_codec, ps_proc, 729 ps_dec_ip->s_out_buffer.pu1_bufs[0], 730 ps_dec_ip->s_out_buffer.pu1_bufs[1], 731 ps_dec_ip->s_out_buffer.pu1_bufs[2], 732 s_job.i2_ctb_y << ps_sps->i1_log2_ctb_size, 733 num_rows); 734 } 735 } 736 } 737 /* In case of non-shared mode and while running in single core mode, then convert/copy the frame to output buffer */ 738 /* Only if the codec is in non-shared mode or in shared mode but needs 420P output */ 739 else if((ps_codec->ps_disp_buf) && ((0 == ps_codec->i4_share_disp_buf) || 740 (IV_YUV_420P == ps_codec->e_chroma_fmt)) && 741 (ps_codec->s_parse.i4_end_of_frame)) 742 { 743 process_ctxt_t *ps_proc = &ps_codec->as_process[proc_idx]; 744 /* Set remaining number of rows to be processed */ 745 ps_codec->s_fmt_conv.i4_num_rows = ps_codec->i4_disp_ht 746 - ps_codec->s_fmt_conv.i4_cur_row; 747 if(0 == ps_proc->i4_init_done) 748 { 749 ihevcd_init_proc_ctxt(ps_proc, 0); 750 } 751 752 if(ps_codec->s_fmt_conv.i4_num_rows < 0) 753 ps_codec->s_fmt_conv.i4_num_rows = 0; 754 755 ret = ihevcd_fmt_conv(ps_codec, ps_proc, 756 ps_dec_ip->s_out_buffer.pu1_bufs[0], 757 ps_dec_ip->s_out_buffer.pu1_bufs[1], 758 ps_dec_ip->s_out_buffer.pu1_bufs[2], 759 ps_codec->s_fmt_conv.i4_cur_row, 760 ps_codec->s_fmt_conv.i4_num_rows); 761 ps_codec->s_fmt_conv.i4_cur_row += ps_codec->s_fmt_conv.i4_num_rows; 762 763 } 764 765 766 DEBUG_DUMP_MV_MAP(ps_codec); 767 768 /* Mark MV Buf as needed for reference */ 769 ihevc_buf_mgr_set_status((buf_mgr_t *)ps_codec->pv_mv_buf_mgr, 770 ps_codec->as_process[proc_idx].i4_cur_mv_bank_buf_id, 771 BUF_MGR_REF); 772 773 /* Mark pic buf as needed for reference */ 774 ihevc_buf_mgr_set_status((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, 775 ps_codec->as_process[proc_idx].i4_cur_pic_buf_id, 776 BUF_MGR_REF); 777 778 /* Mark pic buf as needed for display */ 779 ihevc_buf_mgr_set_status((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, 780 ps_codec->as_process[proc_idx].i4_cur_pic_buf_id, 781 BUF_MGR_DISP); 782 783 /* Insert the current picture as short term reference */ 784 ihevc_dpb_mgr_insert_ref((dpb_mgr_t *)ps_codec->pv_dpb_mgr, 785 ps_codec->as_process[proc_idx].ps_cur_pic, 786 ps_codec->as_process[proc_idx].i4_cur_pic_buf_id); 787 788 /* If a frame was displayed (in non-shared mode), then release it from display manager */ 789 if((0 == ps_codec->i4_share_disp_buf) && (ps_codec->ps_disp_buf)) 790 ihevc_buf_mgr_release((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, 791 ps_codec->i4_disp_buf_id, BUF_MGR_DISP); 792 793 /* Wait for threads */ 794 for(i = 0; i < (ps_codec->i4_num_cores - 1); i++) 795 { 796 if(ps_codec->ai4_process_thread_created[i]) 797 { 798 ithread_join(ps_codec->apv_process_thread_handle[i], NULL); 799 ps_codec->ai4_process_thread_created[i] = 0; 800 } 801 } 802 803 DEBUG_VALIDATE_PADDED_REGION(&ps_codec->as_process[proc_idx]); 804 if(ps_codec->u4_pic_cnt > 0) 805 { 806 DEBUG_DUMP_PIC_PU(ps_codec); 807 } 808 DEBUG_DUMP_PIC_BUFFERS(ps_codec); 809 810 /* Increment the number of pictures decoded */ 811 ps_codec->u4_pic_cnt++; 812 } 813 ihevcd_fill_outargs(ps_codec, ps_dec_ip, ps_dec_op); 814 815 if(1 == ps_dec_op->u4_output_present) 816 { 817 WORD32 xpos = ps_codec->i4_disp_wd - 32 - LOGO_WD; 818 WORD32 ypos = ps_codec->i4_disp_ht - 32 - LOGO_HT; 819 820 if(ypos < 0) 821 ypos = 0; 822 823 if(xpos < 0) 824 xpos = 0; 825 826 INSERT_LOGO(ps_dec_ip->s_out_buffer.pu1_bufs[0], 827 ps_dec_ip->s_out_buffer.pu1_bufs[1], 828 ps_dec_ip->s_out_buffer.pu1_bufs[2], ps_codec->i4_disp_strd, 829 xpos, 830 ypos, 831 ps_codec->e_chroma_fmt, 832 ps_codec->i4_disp_wd, 833 ps_codec->i4_disp_ht); 834 } 835 836 837 return ret; 838 } 839 840