From 8a50328131307b53ebde95e9af87a408c4011559 Mon Sep 17 00:00:00 2001 From: Hamsalekha S Date: Tue, 28 Jul 2015 14:41:24 +0530 Subject: Support for level greater than level at init in Decoder Added support to check num_ref_frames in SPS and num_reorder_frames in VUI before returning error for level Bug: 22860270 Change-Id: I392bab419385ca239836d200f9f2b064915a8a46 --- decoder/ih264d.h | 3 ++- decoder/ih264d_parse_headers.c | 48 ++++++++++++++++++++++++++++++++++++++---- decoder/ih264d_utils.c | 44 ++++++++++++++++++++++++++++++++------ decoder/ih264d_utils.h | 4 ++++ 4 files changed, 87 insertions(+), 12 deletions(-) diff --git a/decoder/ih264d.h b/decoder/ih264d.h index 6dd9893..beda247 100644 --- a/decoder/ih264d.h +++ b/decoder/ih264d.h @@ -78,7 +78,8 @@ IV_API_CALL_STATUS_T ih264d_api_function(iv_obj_t *ps_handle, void *pv_api_ip,vo typedef enum { IH264D_VID_HDR_DEC_NUM_FRM_BUF_NOT_SUFFICIENT = IVD_DUMMY_ELEMENT_FOR_CODEC_EXTENSIONS + 1, - IH264D_UNSUPPORTED_LEVEL = IVD_DUMMY_ELEMENT_FOR_CODEC_EXTENSIONS + 2 + IH264D_UNSUPPORTED_LEVEL = IVD_DUMMY_ELEMENT_FOR_CODEC_EXTENSIONS + 2, + IH264D_UNSUPPORTED_NUM_REF_FRAMES = IVD_DUMMY_ELEMENT_FOR_CODEC_EXTENSIONS + 3 }IH264D_ERROR_CODES_T; diff --git a/decoder/ih264d_parse_headers.c b/decoder/ih264d_parse_headers.c index 743b573..35c3a16 100644 --- a/decoder/ih264d_parse_headers.c +++ b/decoder/ih264d_parse_headers.c @@ -728,6 +728,12 @@ WORD32 ih264d_parse_sps(dec_struct_t *ps_dec, dec_bit_stream_t *ps_bitstrm) return ERROR_NUM_REF; } ps_seq->u1_num_ref_frames = u4_temp; + + if(ps_seq->u1_num_ref_frames > ps_dec->u4_num_ref_frames_at_init) + { + return IH264D_UNSUPPORTED_NUM_REF_FRAMES; + } + COPYTHECONTEXT("SPS: num_ref_frames",ps_seq->u1_num_ref_frames); ps_seq->u1_gaps_in_frame_num_value_allowed_flag = ih264d_get_bit_h264( @@ -930,10 +936,6 @@ WORD32 ih264d_parse_sps(dec_struct_t *ps_dec, dec_bit_stream_t *ps_bitstrm) ps_dec->u2_disp_width = i4_cropped_wd; } - if(ps_dec->u4_level_at_init < u1_level_idc) - { - return IH264D_UNSUPPORTED_LEVEL; - } ps_seq->u1_is_valid = TRUE; @@ -944,6 +946,44 @@ WORD32 ih264d_parse_sps(dec_struct_t *ps_dec, dec_bit_stream_t *ps_bitstrm) return ret; } + if(ps_dec->u4_level_at_init < u1_level_idc) + { + UWORD32 u4_num_pic_bufs_reqd, u4_num_reorder_frames, + u4_num_mv_bufs_reqd; + UWORD32 u4_num_pic_bufs_memory, u4_num_mv_bufs_memory; + UWORD32 u4_num_ref_frames; + + u4_num_ref_frames = ps_seq->u1_num_ref_frames; + if(1 == ps_seq->u1_vui_parameters_present_flag) + { + u4_num_reorder_frames = ps_seq->s_vui.u4_num_reorder_frames; + } + else + { + u4_num_reorder_frames = ps_dec->u4_num_reorder_frames_at_init; + } + + u4_num_pic_bufs_reqd = u4_num_ref_frames + u4_num_reorder_frames + 1; + + u4_num_pic_bufs_memory = ih264d_get_numbuf_dpb_bank(ps_dec, u2_frm_wd_y, + u2_frm_ht_y); + + u4_num_mv_bufs_reqd = u4_num_ref_frames + 1; + + if(u4_num_mv_bufs_reqd < 2) + u4_num_mv_bufs_reqd = 2; + + u4_num_mv_bufs_memory = ih264d_get_numbuf_mv_bank(ps_dec, u2_pic_wd, + u2_pic_ht); + + if((u4_num_pic_bufs_reqd > u4_num_pic_bufs_memory) + || (u4_num_mv_bufs_reqd > u4_num_mv_bufs_memory)) + { + return IH264D_UNSUPPORTED_LEVEL; + } + + } + ps_dec->u2_pic_wd = u2_pic_wd; ps_dec->u2_pic_ht = u2_pic_ht; diff --git a/decoder/ih264d_utils.c b/decoder/ih264d_utils.c index 84909ea..a4896c0 100644 --- a/decoder/ih264d_utils.c +++ b/decoder/ih264d_utils.c @@ -831,7 +831,7 @@ WORD32 ih264d_init_dec_mb_grp(dec_struct_t *ps_dec) /*! ************************************************************************** - * \if Function name : get_numbuf_dpb_bank \endif + * \if Function name : ih264d_get_numbuf_dpb_bank \endif * * \brief * Initializes the picture. @@ -844,7 +844,7 @@ WORD32 ih264d_init_dec_mb_grp(dec_struct_t *ps_dec) * NON -IDR picture is encountered. ************************************************************************** */ -static WORD32 get_numbuf_dpb_bank(dec_struct_t *ps_dec) +WORD32 ih264d_get_numbuf_dpb_bank(dec_struct_t *ps_dec, UWORD32 u4_frame_wd, UWORD32 u4_frame_ht) { WORD32 i4_DPB_size; WORD32 i4_pic_size; @@ -852,13 +852,11 @@ static WORD32 get_numbuf_dpb_bank(dec_struct_t *ps_dec) UWORD32 Ysize; UWORD32 UVsize; UWORD32 one_frm_size; - UWORD32 luma_height; - luma_height = ps_dec->u2_pic_ht; i4_DPB_size = ps_dec->ps_mem_tab[MEM_REC_REF_PIC].u4_mem_size; - Ysize = (ps_dec->u2_frm_wd_y) * (luma_height + (PAD_LEN_Y_V << 2)); + Ysize = u4_frame_wd * u4_frame_ht; UVsize = Ysize >> 2; @@ -889,6 +887,32 @@ static WORD32 get_numbuf_dpb_bank(dec_struct_t *ps_dec) return i4_num_buf_alloc; } + +/*! + ************************************************************************** + * \if Function name : ih264d_get_numbuf_mv_bank \endif + * + * \brief + * Computes number of MVbank buffers that can be allocated. + * + * \return + * Number of MV bank buffers that can be allocated. + * + * \note + ************************************************************************** + */ +UWORD32 ih264d_get_numbuf_mv_bank(dec_struct_t *ps_dec, UWORD32 width, + UWORD32 height) +{ + UWORD32 u4_mv_bank_size,one_frame_size; + UWORD32 u4_num_buf_alloc; + + u4_mv_bank_size = ps_dec->ps_mem_tab[MEM_REC_MVBANK].u4_mem_size; + one_frame_size = sizeof(mv_pred_t) + * ((width * (height + PAD_MV_BANK_ROW)) >> 4); + u4_num_buf_alloc = u4_mv_bank_size / one_frame_size; + return u4_num_buf_alloc; +} /*! ************************************************************************** * \if Function name : ih264d_init_pic \endif @@ -955,7 +979,8 @@ WORD32 ih264d_init_pic(dec_struct_t *ps_dec, if(ps_dec->u4_share_disp_buf == 0) { - i4_pic_bufs = get_numbuf_dpb_bank(ps_dec); + i4_pic_bufs = ih264d_get_numbuf_dpb_bank(ps_dec, ps_dec->u2_frm_wd_y, + ps_dec->u2_frm_ht_y); } else { @@ -2514,6 +2539,7 @@ WORD32 ih264d_create_mv_bank(void *pv_dec, UWORD8 *pu1_col_zero_flag_buf; dec_struct_t *ps_dec = (dec_struct_t *)pv_dec; WORD32 buf_ret; + UWORD32 u4_num_bufs; pu1_mv_buf_mgr_base = ps_dec->ps_mem_tab[MEM_REC_MV_BUF_MGR].pv_base; u4_mv_buf_mgr_mem_used = 0; @@ -2532,7 +2558,11 @@ WORD32 ih264d_create_mv_bank(void *pv_dec, u4_mv_buf_mgr_mem_used += sizeof(col_mv_buf_t) * (H264_MAX_REF_PICS * 2); u4_mv_buf_mgr_mem_used = ALIGN128(u4_mv_buf_mgr_mem_used); - for(i = 0 ; i < ps_dec->u1_max_dec_frame_buffering + 1; i++) + u4_num_bufs = ih264d_get_numbuf_mv_bank(ps_dec, ui_width, ui_height); + + u4_num_bufs = MIN(u4_num_bufs, ps_dec->u1_pic_bufs); + + for(i = 0 ; i < u4_num_bufs ; i++) { pu1_col_zero_flag_buf = pu1_mv_buf_mgr_base + u4_mv_buf_mgr_mem_used; u4_mv_buf_mgr_mem_used += col_flag_buffer_size; diff --git a/decoder/ih264d_utils.h b/decoder/ih264d_utils.h index a1a64d5..326acc0 100644 --- a/decoder/ih264d_utils.h +++ b/decoder/ih264d_utils.h @@ -97,5 +97,9 @@ WORD32 ih264d_get_next_nal_unit(UWORD8 *pu1_buf, UWORD32 u4_cur_pos, UWORD32 u4_max_ofst, UWORD32 *pu4_length_of_start_code); +UWORD32 ih264d_get_numbuf_mv_bank(dec_struct_t *ps_dec, UWORD32 width, UWORD32 height); +WORD32 ih264d_get_numbuf_dpb_bank(dec_struct_t *ps_dec, + UWORD32 u2_frame_wd, + UWORD32 u2_frame_ht); #endif /* _IH264D_UTILS_H_ */ -- cgit v1.2.3