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