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