Improved error resilience in decoder
Fixed buffer management for error cases Fixed end of picture detection logic for multiple slice error cases Fixed handling of incomplete frame, missing slices. Change-Id: Iae447667e4d88869a8bf992180cacd77870b9877
This commit is contained in:
parent
b8681a4380
commit
9f0dcba9b4
8 changed files with 262 additions and 184 deletions
|
|
@ -1501,7 +1501,6 @@ void ih264d_init_decoder(void * ps_dec_params)
|
|||
ps_dec->u2_mbx = 0xffff;
|
||||
ps_dec->u2_mby = 0;
|
||||
ps_dec->u2_total_mbs_coded = 0;
|
||||
ps_cur_slice->u1_end_of_frame_signal = 0;
|
||||
|
||||
/* POC initializations */
|
||||
ps_prev_poc = &ps_dec->s_prev_pic_poc;
|
||||
|
|
@ -2859,8 +2858,9 @@ WORD32 ih264d_video_decode(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
|
|||
ps_dec->u2_cur_slice_num = 0;
|
||||
ps_dec->cur_dec_mb_num = 0;
|
||||
ps_dec->cur_recon_mb_num = 0;
|
||||
ps_dec->u4_first_slice_in_pic = 1;
|
||||
ps_dec->u4_first_slice_in_pic = 2;
|
||||
ps_dec->u1_slice_header_done = 0;
|
||||
ps_dec->u1_dangling_field = 0;
|
||||
|
||||
ps_dec->u4_dec_thread_created = 0;
|
||||
ps_dec->u4_bs_deblk_thread_created = 0;
|
||||
|
|
@ -2914,7 +2914,6 @@ WORD32 ih264d_video_decode(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
|
|||
{
|
||||
ps_dec->u2_total_mbs_coded =
|
||||
ps_dec->ps_cur_sps->u2_max_mb_addr + 1;
|
||||
ps_dec->ps_cur_slice->u1_end_of_frame_signal = 1;
|
||||
}
|
||||
|
||||
/* close deblock thread if it is not closed yet*/
|
||||
|
|
@ -3029,16 +3028,39 @@ WORD32 ih264d_video_decode(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
|
|||
ps_dec_op->u4_error_code = error | ret;
|
||||
api_ret_value = IV_FAIL;
|
||||
|
||||
if((ret == IVD_RES_CHANGED)||(ret == IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED))
|
||||
if((ret == IVD_RES_CHANGED) || (ret == IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED))
|
||||
{
|
||||
/*dont consume the SPS*/
|
||||
ps_dec_op->u4_num_bytes_consumed -= bytes_consumed;
|
||||
return IV_FAIL;
|
||||
}
|
||||
if(ret == ERROR_IN_LAST_SLICE_OF_PIC)
|
||||
|
||||
if((ret == IVD_RES_CHANGED) || (ret == IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED))
|
||||
{
|
||||
/*dont consume the SPS*/
|
||||
ps_dec_op->u4_num_bytes_consumed -= bytes_consumed;
|
||||
return IV_FAIL;
|
||||
}
|
||||
|
||||
if((ret == ERROR_UNAVAIL_PICBUF_T) || (ret == ERROR_UNAVAIL_MVBUF_T))
|
||||
{
|
||||
ps_dec_op->u4_num_bytes_consumed -= bytes_consumed;
|
||||
return IV_FAIL;
|
||||
}
|
||||
|
||||
if((ret == ERROR_INCOMPLETE_FRAME) || (ret == ERROR_DANGLING_FIELD_IN_PIC))
|
||||
{
|
||||
ps_dec_op->u4_num_bytes_consumed -= bytes_consumed;
|
||||
api_ret_value = IV_FAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
if(ret == ERROR_IN_LAST_SLICE_OF_PIC)
|
||||
{
|
||||
api_ret_value = IV_FAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(ps_dec->u4_return_to_app)
|
||||
|
|
@ -3079,11 +3101,24 @@ WORD32 ih264d_video_decode(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
|
|||
{
|
||||
// last slice - missing/corruption
|
||||
WORD32 num_mb_skipped;
|
||||
WORD32 prev_slice_err;
|
||||
pocstruct_t temp_poc;
|
||||
|
||||
num_mb_skipped = (ps_dec->u2_frm_ht_in_mbs * ps_dec->u2_frm_wd_in_mbs)
|
||||
- ps_dec->u2_total_mbs_coded;
|
||||
ih264d_mark_err_slice_skip(ps_dec, num_mb_skipped, ps_dec->u1_nal_unit_type == IDR_SLICE_NAL,&temp_poc,3);
|
||||
|
||||
if(ps_dec->u4_first_slice_in_pic)
|
||||
prev_slice_err = 1;
|
||||
else
|
||||
prev_slice_err = 2;
|
||||
|
||||
ret = ih264d_mark_err_slice_skip(ps_dec, num_mb_skipped, ps_dec->u1_nal_unit_type == IDR_SLICE_NAL, ps_dec->ps_cur_slice->u2_frame_num,
|
||||
&temp_poc, prev_slice_err);
|
||||
|
||||
if((ret == ERROR_UNAVAIL_PICBUF_T) || (ret == ERROR_UNAVAIL_MVBUF_T))
|
||||
{
|
||||
return IV_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -3181,19 +3216,6 @@ WORD32 ih264d_video_decode(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
|
|||
* For field pictures, set the bottom and top picture decoded u4_flag correctly.
|
||||
*/
|
||||
|
||||
if(ps_dec->u4_pic_buf_got == 0)
|
||||
{
|
||||
ih264d_fill_output_struct_from_context(ps_dec, ps_dec_op);
|
||||
|
||||
ps_dec_op->u4_frame_decoded_flag = 0;
|
||||
/* close deblock thread if it is not closed yet*/
|
||||
if(ps_dec->u4_num_cores == 3)
|
||||
{
|
||||
ih264d_signal_bs_deblk_thread(ps_dec);
|
||||
}
|
||||
return (IV_FAIL);
|
||||
}
|
||||
|
||||
if(ps_dec->ps_cur_slice->u1_field_pic_flag)
|
||||
{
|
||||
if(1 == ps_dec->ps_cur_slice->u1_bottom_field_flag)
|
||||
|
|
@ -3206,10 +3228,19 @@ WORD32 ih264d_video_decode(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
|
|||
}
|
||||
}
|
||||
|
||||
/* Calling Function to deblock Picture and Display */
|
||||
ret = ih264d_deblock_display(ps_dec);
|
||||
if(ret != 0)
|
||||
return IV_FAIL;
|
||||
/* if new frame in not found (if we are still getting slices from previous frame)
|
||||
* ih264d_deblock_display is not called. Such frames will not be added to reference /display
|
||||
*/
|
||||
if((ps_dec->ps_dec_err_status->u1_err_flag & REJECT_CUR_PIC) == 0)
|
||||
{
|
||||
/* Calling Function to deblock Picture and Display */
|
||||
ret = ih264d_deblock_display(ps_dec);
|
||||
if(ret != 0)
|
||||
{
|
||||
return IV_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*set to complete ,as we dont support partial frame decode*/
|
||||
if(ps_dec->i4_header_decoded == 3)
|
||||
|
|
|
|||
|
|
@ -110,14 +110,18 @@ typedef enum
|
|||
ERROR_LEVEL_UNSUPPORTED = 0x90,
|
||||
ERROR_START_CODE_NOT_FOUND = 0x91,
|
||||
ERROR_PIC_NUM_IS_REPEATED = 0x92,
|
||||
ERROR_IN_LAST_SLICE_OF_PIC = 0x93
|
||||
ERROR_IN_LAST_SLICE_OF_PIC = 0x93,
|
||||
ERROR_NEW_FRAME_EXPECTED = 0x94,
|
||||
ERROR_INCOMPLETE_FRAME = 0x95
|
||||
|
||||
} h264_decoder_error_code_t;
|
||||
|
||||
WORD32 ih264d_mark_err_slice_skip(dec_struct_t * ps_dec,
|
||||
WORD32 num_mb_skip,
|
||||
UWORD8 u1_is_idr_slice,
|
||||
UWORD16 u2_frame_num,
|
||||
pocstruct_t *ps_cur_poc,
|
||||
WORD32 prev_slice_err);
|
||||
|
||||
void ih264d_err_pic_dispbuf_mgr(dec_struct_t *ps_dec);
|
||||
#endif /* _IH264D_ERROR_HANDLER_H_ */
|
||||
|
|
|
|||
|
|
@ -1096,8 +1096,17 @@ WORD32 ih264d_parse_nal_unit(iv_obj_t *dec_hdl,
|
|||
== IDR_SLICE_NAL),
|
||||
u1_nal_ref_idc, ps_dec);
|
||||
|
||||
if((ps_dec->u4_first_slice_in_pic != 0)&&
|
||||
((ps_dec->ps_dec_err_status->u1_err_flag & REJECT_CUR_PIC) == 0))
|
||||
{
|
||||
/* if the first slice header was not valid set to 1 */
|
||||
ps_dec->u4_first_slice_in_pic = 1;
|
||||
}
|
||||
|
||||
if(i_status != OK)
|
||||
{
|
||||
return i_status;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1432,6 +1432,7 @@ WORD32 ih264d_parse_inter_slice_data_cavlc(dec_struct_t * ps_dec,
|
|||
WORD32 ih264d_mark_err_slice_skip(dec_struct_t * ps_dec,
|
||||
WORD32 num_mb_skip,
|
||||
UWORD8 u1_is_idr_slice,
|
||||
UWORD16 u2_frame_num,
|
||||
pocstruct_t *ps_cur_poc,
|
||||
WORD32 prev_slice_err)
|
||||
{
|
||||
|
|
@ -1457,14 +1458,20 @@ WORD32 ih264d_mark_err_slice_skip(dec_struct_t * ps_dec,
|
|||
UWORD16 u2_total_mbs_coded;
|
||||
UWORD32 u1_mbaff = ps_slice->u1_mbaff_frame_flag;
|
||||
parse_part_params_t *ps_part_info;
|
||||
WORD32 ret;
|
||||
|
||||
|
||||
if(ps_dec->ps_dec_err_status->u1_err_flag & REJECT_CUR_PIC)
|
||||
{
|
||||
ih264d_err_pic_dispbuf_mgr(ps_dec);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(prev_slice_err == 1)
|
||||
{
|
||||
// first slice - missing/header corruption
|
||||
if(u1_is_idr_slice)
|
||||
ps_dec->ps_cur_slice->u2_frame_num = 0;
|
||||
else
|
||||
ps_dec->ps_cur_slice->u2_frame_num++;
|
||||
/* first slice - missing/header corruption */
|
||||
ps_dec->ps_cur_slice->u2_frame_num = u2_frame_num;
|
||||
|
||||
|
||||
if(!ps_dec->u1_first_slice_in_stream)
|
||||
{
|
||||
|
|
@ -1482,7 +1489,6 @@ WORD32 ih264d_mark_err_slice_skip(dec_struct_t * ps_dec,
|
|||
ps_dec->pf_mvpred = ih264d_mvpred_nonmbaff;
|
||||
ps_dec->p_form_mb_part_info = ih264d_form_mb_part_info_bp;
|
||||
ps_dec->p_motion_compensate = ih264d_motion_compensate_bp;
|
||||
ps_dec->ps_pps->ps_sps = ps_dec->ps_cur_sps;
|
||||
|
||||
if(ps_dec->ps_cur_pic != NULL)
|
||||
poc = ps_dec->ps_cur_pic->i4_poc + 2;
|
||||
|
|
@ -1491,10 +1497,16 @@ WORD32 ih264d_mark_err_slice_skip(dec_struct_t * ps_dec,
|
|||
for(i = 0; i < MAX_NUM_PIC_PARAMS; i++)
|
||||
if(ps_dec->ps_pps[i].u1_is_valid == TRUE)
|
||||
j = i;
|
||||
{
|
||||
ret = ih264d_start_of_pic(ps_dec, poc, ps_cur_poc,
|
||||
ps_dec->ps_cur_slice->u2_frame_num,
|
||||
&ps_dec->ps_pps[j]);
|
||||
|
||||
ih264d_start_of_pic(ps_dec, poc, ps_cur_poc,
|
||||
ps_dec->ps_cur_slice->u2_frame_num,
|
||||
&ps_dec->ps_pps[j]);
|
||||
if(ret != OK)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ps_dec->ps_ref_pic_buf_lx[0][0]->u1_pic_buf_id = 0;
|
||||
|
||||
|
|
@ -1617,7 +1629,7 @@ WORD32 ih264d_mark_err_slice_skip(dec_struct_t * ps_dec,
|
|||
>= ps_dec->u2_frm_ht_in_mbs * ps_dec->u2_frm_wd_in_mbs)
|
||||
{
|
||||
ps_dec->u1_pic_decode_done = 1;
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Inserting new slice
|
||||
|
|
@ -1685,8 +1697,6 @@ WORD32 ih264d_mark_err_slice_skip(dec_struct_t * ps_dec,
|
|||
/******************************************************/
|
||||
/* Parsing / decoding the slice */
|
||||
/******************************************************/
|
||||
ps_dec->u4_first_slice_in_pic = 0;
|
||||
ps_dec->u1_first_slice_in_stream = 0;
|
||||
ps_dec->u1_slice_header_done = 2;
|
||||
ps_dec->u1_qp = ps_slice->u1_slice_qp;
|
||||
ih264d_update_qp(ps_dec, 0);
|
||||
|
|
@ -1823,6 +1833,11 @@ WORD32 ih264d_mark_err_slice_skip(dec_struct_t * ps_dec,
|
|||
H264_DEC_DEBUG_PRINT("Mbs in slice: %d\n", ps_dec->ps_cur_slice->u4_mbs_in_slice);
|
||||
|
||||
ps_dec->u2_cur_slice_num++;
|
||||
|
||||
/* incremented here only if first slice is inserted */
|
||||
if(ps_dec->u4_first_slice_in_pic != 0)
|
||||
ps_dec->ps_parse_cur_slice++;
|
||||
|
||||
ps_dec->i2_prev_slice_mbx = ps_dec->u2_mbx;
|
||||
ps_dec->i2_prev_slice_mby = ps_dec->u2_mby;
|
||||
|
||||
|
|
@ -1830,7 +1845,6 @@ WORD32 ih264d_mark_err_slice_skip(dec_struct_t * ps_dec,
|
|||
>= ps_dec->u2_frm_ht_in_mbs * ps_dec->u2_frm_wd_in_mbs)
|
||||
{
|
||||
ps_dec->u1_pic_decode_done = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -849,13 +849,6 @@ WORD32 ih264d_end_of_pic_dispbuf_mgr(dec_struct_t * ps_dec)
|
|||
ps_cur_slice->u1_field_pic_flag,
|
||||
ps_dec->u1_second_field);
|
||||
}
|
||||
{
|
||||
|
||||
if(!ps_cur_slice->u1_end_of_frame_signal)
|
||||
{
|
||||
ps_cur_slice->u1_end_of_frame_signal = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(!ps_cur_slice->u1_field_pic_flag
|
||||
|| ((TOP_FIELD_ONLY | BOT_FIELD_ONLY)
|
||||
|
|
@ -961,7 +954,6 @@ WORD32 ih264d_end_of_pic(dec_struct_t *ps_dec,
|
|||
dec_slice_params_t *ps_cur_slice = ps_dec->ps_cur_slice;
|
||||
WORD32 ret;
|
||||
|
||||
ps_dec->u4_first_slice_in_pic = 1;
|
||||
ps_dec->u1_first_pb_nal_in_pic = 1;
|
||||
ps_dec->u2_mbx = 0xffff;
|
||||
ps_dec->u2_mby = 0;
|
||||
|
|
@ -969,9 +961,8 @@ WORD32 ih264d_end_of_pic(dec_struct_t *ps_dec,
|
|||
dec_err_status_t * ps_err = ps_dec->ps_dec_err_status;
|
||||
if(ps_err->u1_err_flag & REJECT_CUR_PIC)
|
||||
{
|
||||
ps_err->u1_err_flag ^= REJECT_CUR_PIC;
|
||||
ih264d_err_pic_dispbuf_mgr(ps_dec);
|
||||
return OK;
|
||||
return ERROR_NEW_FRAME_EXPECTED;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1016,10 +1007,8 @@ WORD32 ih264d_end_of_pic(dec_struct_t *ps_dec,
|
|||
ps_prev_poc->u1_bot_field = ps_cur_poc->u1_bot_field;
|
||||
}
|
||||
}
|
||||
if(!ps_cur_slice->u1_end_of_frame_signal)
|
||||
{
|
||||
return ERROR_END_OF_FRAME_EXPECTED_T;
|
||||
} H264_MUTEX_UNLOCK(&ps_dec->process_disp_mutex);
|
||||
|
||||
H264_MUTEX_UNLOCK(&ps_dec->process_disp_mutex);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
|
@ -1294,6 +1283,22 @@ WORD32 ih264d_parse_decode_slice(UWORD8 u1_is_idr_slice,
|
|||
u1_field_pic_flag,
|
||||
u1_bottom_field_flag);
|
||||
|
||||
/* since we support only Full frame decode, every new process should
|
||||
* process a new pic
|
||||
*/
|
||||
if((ps_dec->u4_first_slice_in_pic == 2) && (i1_is_end_of_poc == 0))
|
||||
{
|
||||
/* if it is the first slice is process call ,it should be a new frame. If it is not
|
||||
* reject current pic and dont add it to dpb
|
||||
*/
|
||||
ps_dec->ps_dec_err_status->u1_err_flag |= REJECT_CUR_PIC;
|
||||
i1_is_end_of_poc = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* reset REJECT_CUR_PIC */
|
||||
ps_dec->ps_dec_err_status->u1_err_flag &= MASK_REJECT_CUR_PIC;
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
|
|
@ -1310,6 +1315,7 @@ WORD32 ih264d_parse_decode_slice(UWORD8 u1_is_idr_slice,
|
|||
&& ps_dec->u1_top_bottom_decoded
|
||||
!= (TOP_FIELD_ONLY | BOT_FIELD_ONLY))
|
||||
{
|
||||
ps_dec->u1_dangling_field = 1;
|
||||
if(ps_dec->u4_first_slice_in_pic)
|
||||
{
|
||||
// first slice - dangling field
|
||||
|
|
@ -1332,7 +1338,7 @@ WORD32 ih264d_parse_decode_slice(UWORD8 u1_is_idr_slice,
|
|||
|
||||
u1_is_idr_slice = ps_cur_slice->u1_nal_unit_type == IDR_SLICE_NAL;
|
||||
}
|
||||
else if(ps_dec->u4_first_slice_in_pic)
|
||||
else if(ps_dec->u4_first_slice_in_pic == 2)
|
||||
{
|
||||
if(u2_first_mb_in_slice > 0)
|
||||
{
|
||||
|
|
@ -1355,10 +1361,25 @@ WORD32 ih264d_parse_decode_slice(UWORD8 u1_is_idr_slice,
|
|||
}
|
||||
else
|
||||
{
|
||||
// last slice - missing/corruption
|
||||
prev_slice_err = 2;
|
||||
num_mb_skipped = (ps_dec->u2_frm_ht_in_mbs * ps_dec->u2_frm_wd_in_mbs)
|
||||
- ps_dec->u2_total_mbs_coded;
|
||||
|
||||
if(ps_dec->u4_first_slice_in_pic)
|
||||
{
|
||||
/* if valid slice header is not decoded do start of pic processing
|
||||
* since in the current process call, frame num is not updated in the slice structure yet
|
||||
* ih264d_is_end_of_pic is checked with valid frame num of previous process call,
|
||||
* although i1_is_end_of_poc is set there could be more slices in the frame,
|
||||
* so conceal only till cur slice */
|
||||
prev_slice_err = 1;
|
||||
num_mb_skipped = u2_first_mb_in_slice << u1_mbaff;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* since i1_is_end_of_poc is set ,means new frame num is encountered. so conceal the current frame
|
||||
* completely */
|
||||
prev_slice_err = 2;
|
||||
num_mb_skipped = (ps_dec->u2_frm_ht_in_mbs * ps_dec->u2_frm_wd_in_mbs)
|
||||
- ps_dec->u2_total_mbs_coded;
|
||||
}
|
||||
ps_cur_poc = &s_tmp_poc;
|
||||
}
|
||||
}
|
||||
|
|
@ -1380,13 +1401,40 @@ WORD32 ih264d_parse_decode_slice(UWORD8 u1_is_idr_slice,
|
|||
|
||||
if(prev_slice_err)
|
||||
{
|
||||
end_of_frame = ih264d_mark_err_slice_skip(ps_dec,num_mb_skipped,u1_is_idr_slice,ps_cur_poc,prev_slice_err);
|
||||
ret = ih264d_mark_err_slice_skip(ps_dec, num_mb_skipped, u1_is_idr_slice, u2_frame_num, ps_cur_poc, prev_slice_err);
|
||||
|
||||
if(end_of_frame)
|
||||
if(ps_dec->u1_dangling_field == 1)
|
||||
{
|
||||
// return if all MBs in frame are parsed
|
||||
ps_dec->u1_second_field = 1 - ps_dec->u1_second_field;
|
||||
ps_cur_slice->u1_bottom_field_flag = u1_bottom_field_flag;
|
||||
ps_dec->u2_prv_frame_num = u2_frame_num;
|
||||
ps_dec->u1_first_slice_in_stream = 0;
|
||||
return ERROR_DANGLING_FIELD_IN_PIC;
|
||||
}
|
||||
|
||||
if(prev_slice_err == 2)
|
||||
{
|
||||
ps_dec->u1_first_slice_in_stream = 0;
|
||||
return ERROR_INCOMPLETE_FRAME;
|
||||
}
|
||||
|
||||
if(ps_dec->u2_total_mbs_coded
|
||||
>= ps_dec->u2_frm_ht_in_mbs * ps_dec->u2_frm_wd_in_mbs)
|
||||
{
|
||||
/* return if all MBs in frame are parsed*/
|
||||
ps_dec->u1_first_slice_in_stream = 0;
|
||||
return ERROR_IN_LAST_SLICE_OF_PIC;
|
||||
}
|
||||
|
||||
if(ps_dec->ps_dec_err_status->u1_err_flag & REJECT_CUR_PIC)
|
||||
{
|
||||
ih264d_err_pic_dispbuf_mgr(ps_dec);
|
||||
return ERROR_NEW_FRAME_EXPECTED;
|
||||
}
|
||||
|
||||
if(ret != OK)
|
||||
return ret;
|
||||
|
||||
i1_is_end_of_poc = 0;
|
||||
}
|
||||
|
||||
|
|
@ -1401,13 +1449,6 @@ WORD32 ih264d_parse_decode_slice(UWORD8 u1_is_idr_slice,
|
|||
if(!ps_dec->u1_first_slice_in_stream)
|
||||
{
|
||||
UWORD8 uc_mbs_exceed = 0;
|
||||
/*since we support only Full frame decode, every new process should
|
||||
* process a new pic
|
||||
*/
|
||||
if(ps_dec->u4_first_slice_in_pic == 1)
|
||||
{
|
||||
i1_is_end_of_poc = 1;
|
||||
}
|
||||
|
||||
if(ps_dec->u2_total_mbs_coded
|
||||
== (ps_dec->ps_cur_sps->u2_max_mb_addr + 1))
|
||||
|
|
@ -1446,45 +1487,8 @@ WORD32 ih264d_parse_decode_slice(UWORD8 u1_is_idr_slice,
|
|||
}
|
||||
}
|
||||
|
||||
ps_cur_slice->u1_end_of_frame_signal = 0;
|
||||
if(u1_field_pic_flag)
|
||||
{
|
||||
/*
|
||||
* Check if the frame number has changed.
|
||||
*/
|
||||
H264_DEC_DEBUG_PRINT(
|
||||
"u2_frame_num: %d ps_dec->u2_prv_frame_num: %d ps_dec->u1_top_bottom_decoded: %d\n",
|
||||
u2_frame_num, ps_dec->u2_prv_frame_num,
|
||||
ps_dec->u1_top_bottom_decoded);
|
||||
if((u2_frame_num != ps_dec->u2_prv_frame_num)
|
||||
&& (0 != ps_dec->u1_top_bottom_decoded))
|
||||
{
|
||||
if((TOP_FIELD_ONLY | BOT_FIELD_ONLY)
|
||||
!= ps_dec->u1_top_bottom_decoded)
|
||||
{
|
||||
H264_DEC_DEBUG_PRINT("Dangling Field, toggling second field\n");
|
||||
ps_dec->u1_second_field = 1 - ps_dec->u1_second_field;
|
||||
ps_dec->u1_dangling_field = 1;
|
||||
/*
|
||||
* Updating the u1_bottom_field_flag since its used in the concealment function.
|
||||
*/
|
||||
ps_cur_slice->u1_bottom_field_flag = u1_bottom_field_flag;
|
||||
ps_dec->u2_prv_frame_num = u2_frame_num;
|
||||
|
||||
ret = ih264d_deblock_display(ps_dec);
|
||||
if(ret != OK)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* The bytes consumed will be handled by the
|
||||
* video_decode function after the error is handled.
|
||||
*/
|
||||
return ERROR_DANGLING_FIELD_IN_PIC;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ps_dec->u2_prv_frame_num = u2_frame_num;
|
||||
}
|
||||
|
||||
|
|
@ -1513,7 +1517,7 @@ WORD32 ih264d_parse_decode_slice(UWORD8 u1_is_idr_slice,
|
|||
ps_dec->ps_cur_pic->i4_poc = i4_temp_poc;
|
||||
ps_dec->ps_cur_pic->i4_avg_poc = i4_temp_poc;
|
||||
}
|
||||
if(ps_dec->u4_first_slice_in_pic)
|
||||
if(ps_dec->u4_first_slice_in_pic == 2)
|
||||
{
|
||||
ret = ih264d_decode_pic_order_cnt(u1_is_idr_slice, u2_frame_num,
|
||||
&ps_dec->s_prev_pic_poc,
|
||||
|
|
@ -1581,11 +1585,14 @@ WORD32 ih264d_parse_decode_slice(UWORD8 u1_is_idr_slice,
|
|||
ps_dec->pf_mvpred = ih264d_mvpred_nonmbaff;
|
||||
}
|
||||
|
||||
if(ps_dec->u4_first_slice_in_pic)
|
||||
if(ps_dec->u4_first_slice_in_pic == 2)
|
||||
{
|
||||
ret = ih264d_start_of_pic(ps_dec, i4_poc, &s_tmp_poc, u2_frame_num, ps_pps);
|
||||
if(ret != OK)
|
||||
return ret;
|
||||
if(u2_first_mb_in_slice == 0)
|
||||
{
|
||||
ret = ih264d_start_of_pic(ps_dec, i4_poc, &s_tmp_poc, u2_frame_num, ps_pps);
|
||||
if(ret != OK)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ps_dec->u4_output_present = 0;
|
||||
|
||||
|
|
@ -1898,7 +1905,8 @@ WORD32 ih264d_parse_decode_slice(UWORD8 u1_is_idr_slice,
|
|||
|
||||
if(ps_dec->u1_slice_header_done)
|
||||
{
|
||||
/*set to zero to indicate a valid slice has been decoded*/
|
||||
/* set to zero to indicate a valid slice has been decoded */
|
||||
/* first slice header successfully decoded */
|
||||
ps_dec->u4_first_slice_in_pic = 0;
|
||||
ps_dec->u1_first_slice_in_stream = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -924,7 +924,10 @@ WORD32 ih264d_process_intra_mb(dec_struct_t * ps_dec,
|
|||
(u1_intrapred_mode ^ 2);
|
||||
|
||||
if((u1_err_code & u1_packed_modes) ^ u1_err_code)
|
||||
{
|
||||
u1_intrapred_mode = 0;
|
||||
ps_dec->i4_error_code = ERROR_INTRAPRED;
|
||||
}
|
||||
}
|
||||
{
|
||||
UWORD8 au1_ngbr_pels[33];
|
||||
|
|
@ -1242,9 +1245,11 @@ WORD32 ih264d_process_intra_mb(dec_struct_t * ps_dec,
|
|||
{
|
||||
UWORD8 u1_err_code = pu1_intra_err_codes[i1_intra_pred];
|
||||
|
||||
/*if((u1_err_code & u1_packed_modes) ^ u1_err_code)
|
||||
if((u1_err_code & u1_packed_modes) ^ u1_err_code)
|
||||
{
|
||||
}*/
|
||||
i1_intra_pred = 0;
|
||||
ps_dec->i4_error_code = ERROR_INTRAPRED;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1649,7 +1654,10 @@ WORD32 ih264d_process_intra_mb(dec_struct_t * ps_dec,
|
|||
UWORD8 u1_err_code = pu1_intra_err_codes[i1_intra_pred];
|
||||
|
||||
if((u1_err_code & u1_packed_modes) ^ u1_err_code)
|
||||
{
|
||||
i1_intra_pred = 0;
|
||||
ps_dec->i4_error_code = ERROR_INTRAPRED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1761,7 +1769,10 @@ WORD32 ih264d_process_intra_mb(dec_struct_t * ps_dec,
|
|||
u1_intra_chrom_pred_mode :
|
||||
(u1_intra_chrom_pred_mode ^ 2);
|
||||
if((u1_err_code & u1_packed_modes) ^ u1_err_code)
|
||||
{
|
||||
u1_intra_chrom_pred_mode = 0;
|
||||
ps_dec->i4_error_code = ERROR_INTRAPRED;
|
||||
}
|
||||
}
|
||||
|
||||
/* CHANGED CODE */
|
||||
|
|
|
|||
|
|
@ -524,7 +524,6 @@ typedef struct
|
|||
unsigned. LSB byte : weight and MSB byte: u4_ofst */
|
||||
UWORD32 u4_wt_ofst_lx[2][MAX_REF_BUFS][3];
|
||||
void * pv_codec_handle; /* For Error Handling */
|
||||
UWORD8 u1_end_of_frame_signal;
|
||||
|
||||
/* This is used when reordering is done in Forward or */
|
||||
/* backward lists. This is because reordering can point */
|
||||
|
|
@ -607,6 +606,9 @@ typedef struct code_overlay_ctxt
|
|||
#define REJECT_CUR_PIC (0x01)
|
||||
#define REJECT_PB_PICS (0x02)
|
||||
|
||||
#define MASK_REJECT_CUR_PIC (0xFE)
|
||||
#define MASK_REJECT_PB_PICS (0xFD)
|
||||
|
||||
#define PIC_TYPE_UNKNOWN (0xFF)
|
||||
#define PIC_TYPE_I (0x00)
|
||||
#define SYNC_FRM_DEFAULT (0xFFFFFFFF)
|
||||
|
|
@ -1351,6 +1353,7 @@ typedef struct _DecStruct
|
|||
UWORD32 u4_cur_slice_decode_done;
|
||||
UWORD32 u4_extra_mem_used;
|
||||
|
||||
/* 2 first slice not parsed , 1 :first slice parsed , 0 :first valid slice header parsed*/
|
||||
UWORD32 u4_first_slice_in_pic;
|
||||
UWORD32 u4_num_cores;
|
||||
IVD_ARCH_T e_processor_arch;
|
||||
|
|
|
|||
|
|
@ -1827,6 +1827,7 @@ int main(WORD32 argc, CHAR *argv[])
|
|||
UWORD32 frm_cnt = 0;
|
||||
WORD32 total_bytes_comsumed;
|
||||
UWORD32 max_op_frm_ts;
|
||||
UWORD32 u4_num_disp_bufs_with_dec;;
|
||||
|
||||
#ifdef PROFILE_ENABLE
|
||||
UWORD32 u4_tot_cycles = 0;
|
||||
|
|
@ -2313,6 +2314,7 @@ int main(WORD32 argc, CHAR *argv[])
|
|||
|
||||
ivd_ctl_getbufinfo_ip_t s_ctl_ip;
|
||||
ivd_ctl_getbufinfo_op_t s_ctl_op;
|
||||
WORD32 outlen = 0;
|
||||
|
||||
s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
|
||||
s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_GETBUFINFO;
|
||||
|
|
@ -2342,7 +2344,6 @@ int main(WORD32 argc, CHAR *argv[])
|
|||
/* Or if shared and output is 420P */
|
||||
if((0 == s_app_ctx.u4_share_disp_buf) || (IV_YUV_420P == s_app_ctx.e_output_chroma_format))
|
||||
{
|
||||
UWORD32 outlen;
|
||||
ps_out_buf->u4_min_out_buf_size[0] =
|
||||
s_ctl_op.u4_min_out_buf_size[0];
|
||||
ps_out_buf->u4_min_out_buf_size[1] =
|
||||
|
|
@ -2377,6 +2378,56 @@ int main(WORD32 argc, CHAR *argv[])
|
|||
ps_out_buf->u4_num_bufs = s_ctl_op.u4_min_num_out_bufs;
|
||||
}
|
||||
|
||||
#ifdef APP_EXTRA_BUFS
|
||||
s_app_ctx.disp_delay = EXTRA_DISP_BUFFERS;
|
||||
s_ctl_op.u4_num_disp_bufs += EXTRA_DISP_BUFFERS;
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
/* API Call: Allocate display buffers for display buffer shared case */
|
||||
/*****************************************************************************/
|
||||
|
||||
for(i = 0; i < s_ctl_op.u4_num_disp_bufs; i++)
|
||||
{
|
||||
|
||||
s_app_ctx.s_disp_buffers[i].u4_min_out_buf_size[0] =
|
||||
s_ctl_op.u4_min_out_buf_size[0];
|
||||
s_app_ctx.s_disp_buffers[i].u4_min_out_buf_size[1] =
|
||||
s_ctl_op.u4_min_out_buf_size[1];
|
||||
s_app_ctx.s_disp_buffers[i].u4_min_out_buf_size[2] =
|
||||
s_ctl_op.u4_min_out_buf_size[2];
|
||||
|
||||
outlen = s_ctl_op.u4_min_out_buf_size[0];
|
||||
if(s_ctl_op.u4_min_num_out_bufs > 1)
|
||||
outlen += s_ctl_op.u4_min_out_buf_size[1];
|
||||
|
||||
if(s_ctl_op.u4_min_num_out_bufs > 2)
|
||||
outlen += s_ctl_op.u4_min_out_buf_size[2];
|
||||
|
||||
s_app_ctx.s_disp_buffers[i].pu1_bufs[0] = (UWORD8 *)malloc(outlen);
|
||||
|
||||
if(s_app_ctx.s_disp_buffers[i].pu1_bufs[0] == NULL)
|
||||
{
|
||||
sprintf(ac_error_str,
|
||||
"\nAllocation failure for output buffer of i4_size %d",
|
||||
outlen);
|
||||
codec_exit(ac_error_str);
|
||||
}
|
||||
|
||||
if(s_ctl_op.u4_min_num_out_bufs > 1)
|
||||
s_app_ctx.s_disp_buffers[i].pu1_bufs[1] =
|
||||
s_app_ctx.s_disp_buffers[i].pu1_bufs[0]
|
||||
+ (s_ctl_op.u4_min_out_buf_size[0]);
|
||||
|
||||
if(s_ctl_op.u4_min_num_out_bufs > 2)
|
||||
s_app_ctx.s_disp_buffers[i].pu1_bufs[2] =
|
||||
s_app_ctx.s_disp_buffers[i].pu1_bufs[1]
|
||||
+ (s_ctl_op.u4_min_out_buf_size[1]);
|
||||
|
||||
s_app_ctx.s_disp_buffers[i].u4_num_bufs =
|
||||
s_ctl_op.u4_min_num_out_bufs;
|
||||
}
|
||||
s_app_ctx.num_disp_buf = s_ctl_op.u4_num_disp_bufs;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2556,73 +2607,6 @@ int main(WORD32 argc, CHAR *argv[])
|
|||
/*************************************************************************/
|
||||
//if(1 == s_app_ctx.u4_share_disp_buf)
|
||||
{
|
||||
ivd_ctl_getbufinfo_ip_t s_ctl_ip;
|
||||
ivd_ctl_getbufinfo_op_t s_ctl_op;
|
||||
WORD32 outlen = 0;
|
||||
|
||||
s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
|
||||
s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_GETBUFINFO;
|
||||
s_ctl_ip.u4_size = sizeof(ivd_ctl_getbufinfo_ip_t);
|
||||
s_ctl_op.u4_size = sizeof(ivd_ctl_getbufinfo_op_t);
|
||||
ret = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip,
|
||||
(void *)&s_ctl_op);
|
||||
if(ret != IV_SUCCESS)
|
||||
{
|
||||
sprintf(ac_error_str, "Error in Get Buf Info %x", s_ctl_op.u4_error_code);
|
||||
codec_exit(ac_error_str);
|
||||
}
|
||||
|
||||
#ifdef APP_EXTRA_BUFS
|
||||
s_app_ctx.disp_delay = EXTRA_DISP_BUFFERS;
|
||||
s_ctl_op.u4_num_disp_bufs += EXTRA_DISP_BUFFERS;
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
/* API Call: Allocate display buffers for display buffer shared case */
|
||||
/*****************************************************************************/
|
||||
|
||||
for(i = 0; i < s_ctl_op.u4_num_disp_bufs; i++)
|
||||
{
|
||||
|
||||
s_app_ctx.s_disp_buffers[i].u4_min_out_buf_size[0] =
|
||||
s_ctl_op.u4_min_out_buf_size[0];
|
||||
s_app_ctx.s_disp_buffers[i].u4_min_out_buf_size[1] =
|
||||
s_ctl_op.u4_min_out_buf_size[1];
|
||||
s_app_ctx.s_disp_buffers[i].u4_min_out_buf_size[2] =
|
||||
s_ctl_op.u4_min_out_buf_size[2];
|
||||
|
||||
outlen = s_ctl_op.u4_min_out_buf_size[0];
|
||||
if(s_ctl_op.u4_min_num_out_bufs > 1)
|
||||
outlen += s_ctl_op.u4_min_out_buf_size[1];
|
||||
|
||||
if(s_ctl_op.u4_min_num_out_bufs > 2)
|
||||
outlen += s_ctl_op.u4_min_out_buf_size[2];
|
||||
|
||||
s_app_ctx.s_disp_buffers[i].pu1_bufs[0] = (UWORD8 *)malloc(outlen);
|
||||
|
||||
if(s_app_ctx.s_disp_buffers[i].pu1_bufs[0] == NULL)
|
||||
{
|
||||
sprintf(ac_error_str,
|
||||
"\nAllocation failure for output buffer of i4_size %d",
|
||||
outlen);
|
||||
codec_exit(ac_error_str);
|
||||
}
|
||||
|
||||
if(s_ctl_op.u4_min_num_out_bufs > 1)
|
||||
s_app_ctx.s_disp_buffers[i].pu1_bufs[1] =
|
||||
s_app_ctx.s_disp_buffers[i].pu1_bufs[0]
|
||||
+ (s_ctl_op.u4_min_out_buf_size[0]);
|
||||
|
||||
if(s_ctl_op.u4_min_num_out_bufs > 2)
|
||||
s_app_ctx.s_disp_buffers[i].pu1_bufs[2] =
|
||||
s_app_ctx.s_disp_buffers[i].pu1_bufs[1]
|
||||
+ (s_ctl_op.u4_min_out_buf_size[1]);
|
||||
|
||||
s_app_ctx.s_disp_buffers[i].u4_num_bufs =
|
||||
s_ctl_op.u4_min_num_out_bufs;
|
||||
}
|
||||
s_app_ctx.num_disp_buf = s_ctl_op.u4_num_disp_bufs;
|
||||
|
||||
/*****************************************************************************/
|
||||
/* API Call: Send the allocated display buffers to codec */
|
||||
/*****************************************************************************/
|
||||
|
|
@ -2638,7 +2622,7 @@ int main(WORD32 argc, CHAR *argv[])
|
|||
|
||||
memcpy(&(s_set_display_frame_ip.s_disp_buffer),
|
||||
&(s_app_ctx.s_disp_buffers),
|
||||
s_ctl_op.u4_num_disp_bufs * sizeof(ivd_out_bufdesc_t));
|
||||
s_app_ctx.num_disp_buf * sizeof(ivd_out_bufdesc_t));
|
||||
|
||||
ret = ivd_api_function((iv_obj_t *)codec_obj,
|
||||
(void *)&s_set_display_frame_ip,
|
||||
|
|
@ -2732,7 +2716,17 @@ int main(WORD32 argc, CHAR *argv[])
|
|||
#ifndef PRINT_PICSIZE
|
||||
get_version(codec_obj);
|
||||
#endif
|
||||
max_op_frm_ts = (s_app_ctx.u4_max_frm_ts > 0)? (s_app_ctx.u4_max_frm_ts + s_app_ctx.disp_delay): 0xffffffff;
|
||||
|
||||
|
||||
max_op_frm_ts = s_app_ctx.u4_max_frm_ts + s_app_ctx.disp_delay;
|
||||
|
||||
if(max_op_frm_ts < s_app_ctx.disp_delay)
|
||||
max_op_frm_ts = 0xffffffff;/* clip as overflow has occured*/
|
||||
|
||||
max_op_frm_ts = (s_app_ctx.u4_max_frm_ts > 0)? (max_op_frm_ts): 0xffffffff;
|
||||
|
||||
u4_num_disp_bufs_with_dec = 0;
|
||||
|
||||
while(u4_op_frm_ts < max_op_frm_ts)
|
||||
{
|
||||
|
||||
|
|
@ -2759,9 +2753,10 @@ int main(WORD32 argc, CHAR *argv[])
|
|||
|
||||
}
|
||||
#endif
|
||||
if(u4_ip_frm_ts < s_app_ctx.num_disp_buf)
|
||||
if(u4_num_disp_bufs_with_dec < s_app_ctx.num_disp_buf)
|
||||
{
|
||||
release_disp_frame(codec_obj, u4_ip_frm_ts);
|
||||
release_disp_frame(codec_obj, u4_num_disp_bufs_with_dec);
|
||||
u4_num_disp_bufs_with_dec ++;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2991,6 +2986,9 @@ int main(WORD32 argc, CHAR *argv[])
|
|||
sprintf(ac_error_str, "Error in Reset");
|
||||
codec_exit(ac_error_str);
|
||||
}
|
||||
|
||||
/*when reset all buffers are released by lib*/
|
||||
u4_num_disp_bufs_with_dec = 0;
|
||||
/*************************************************************************/
|
||||
/* set num of cores */
|
||||
/*************************************************************************/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue