diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-07-15 01:26:07 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-07-15 01:26:07 +0000 |
commit | a47d75d2553f3b4b2b78530e1691d5529ade38a4 (patch) | |
tree | d849791180a7c14f53a5946412e6122e22634147 | |
parent | 778bff514515654b8104fa194d388b4a4ef047d4 (diff) | |
parent | d71b96802c05252b4826f5cb9abee389c9c7b37d (diff) | |
download | libavc-android12-mainline-conscrypt-release.tar.gz |
Snap for 7550844 from d71b96802c05252b4826f5cb9abee389c9c7b37d to mainline-conscrypt-releaseandroid-mainline-12.0.0_r8android-mainline-12.0.0_r25android12-mainline-conscrypt-release
Change-Id: I27fa58e19f09e521abe326c9f166ce0a4862abca
31 files changed, 1951 insertions, 509 deletions
@@ -1,3 +1,20 @@ +package { + default_applicable_licenses: ["external_libavc_license"], +} + +// Added automatically by a large-scale-change +// See: http://go/android-license-faq +license { + name: "external_libavc_license", + visibility: [":__subpackages__"], + license_kinds: [ + "SPDX-license-identifier-Apache-2.0", + ], + license_text: [ + "NOTICE", + ], +} + cc_library_static { name: "libavcdec", vendor_available: true, @@ -162,18 +179,6 @@ cc_library_static { ], }, - mips: { - local_include_dirs: ["common/mips"], - - srcs: ["decoder/mips/ih264d_function_selector.c"], - }, - - mips64: { - local_include_dirs: ["common/mips"], - - srcs: ["decoder/mips/ih264d_function_selector.c"], - }, - x86: { cflags: [ "-DX86", @@ -240,9 +245,11 @@ cc_library_static { sanitize: { integer_overflow: true, misc_undefined: ["bounds"], - // Enable CFI if this becomes a shared library. - // cfi: true, - blacklist: "libavc_blacklist.txt", + cfi: true, + config: { + cfi_assembly_support: true, + }, + blocklist: "libavc_blocklist.txt", }, apex_available: [ "//apex_available:platform", // used by libstagefright_soft_avcdec @@ -427,24 +434,6 @@ cc_library_static { ], }, - mips: { - local_include_dirs: [ - "common/mips", - "encoder/mips", - ], - - srcs: ["encoder/mips/ih264e_function_selector.c"], - }, - - mips64: { - local_include_dirs: [ - "common/mips", - "encoder/mips", - ], - - srcs: ["encoder/mips/ih264e_function_selector.c"], - }, - x86: { cflags: [ "-DX86", @@ -519,9 +508,11 @@ cc_library_static { sanitize: { integer_overflow: true, misc_undefined: ["bounds"], - // Enable CFI if this becomes a shared library. - // cfi: true, - blacklist: "libavc_blacklist.txt", + cfi: true, + config: { + cfi_assembly_support: true, + }, + blocklist: "libavc_blocklist.txt", }, apex_available: [ "//apex_available:platform", //due to libstagefright_soft_avcenc diff --git a/METADATA b/METADATA new file mode 100644 index 0000000..d97975c --- /dev/null +++ b/METADATA @@ -0,0 +1,3 @@ +third_party { + license_type: NOTICE +} @@ -1,4 +1,4 @@ -marcone@google.com +# owners for external/libavc +include platform/frameworks/av:/media/janitors/codec_OWNERS essick@google.com -lajos@google.com hkuang@google.com diff --git a/decoder/ih264d_api.c b/decoder/ih264d_api.c index 3dfcbf2..2508d7b 100644 --- a/decoder/ih264d_api.c +++ b/decoder/ih264d_api.c @@ -1972,18 +1972,22 @@ WORD32 ih264d_video_decode(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) WORD32 ret = 0,api_ret_value = IV_SUCCESS; WORD32 header_data_left = 0,frame_data_left = 0; UWORD8 *pu1_bitstrm_buf; + ih264d_video_decode_ip_t *ps_h264d_dec_ip; + ih264d_video_decode_op_t *ps_h264d_dec_op; ivd_video_decode_ip_t *ps_dec_ip; ivd_video_decode_op_t *ps_dec_op; ithread_set_name((void*)"Parse_thread"); - ps_dec_ip = (ivd_video_decode_ip_t *)pv_api_ip; - ps_dec_op = (ivd_video_decode_op_t *)pv_api_op; + ps_h264d_dec_ip = (ih264d_video_decode_ip_t *)pv_api_ip; + ps_h264d_dec_op = (ih264d_video_decode_op_t *)pv_api_op; + ps_dec_ip = &ps_h264d_dec_ip->s_ivd_video_decode_ip_t; + ps_dec_op = &ps_h264d_dec_op->s_ivd_video_decode_op_t; { UWORD32 u4_size; u4_size = ps_dec_op->u4_size; - memset(ps_dec_op, 0, sizeof(ivd_video_decode_op_t)); + memset(ps_h264d_dec_op, 0, sizeof(ih264d_video_decode_op_t)); ps_dec_op->u4_size = u4_size; } @@ -3236,10 +3240,14 @@ WORD32 ih264d_set_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) dec_struct_t * ps_dec; WORD32 ret = IV_SUCCESS; + ih264d_ctl_set_config_ip_t *ps_h264d_ctl_ip = + (ih264d_ctl_set_config_ip_t *)pv_api_ip; + ih264d_ctl_set_config_op_t *ps_h264d_ctl_op = + (ih264d_ctl_set_config_op_t *)pv_api_op;; ivd_ctl_set_config_ip_t *ps_ctl_ip = - (ivd_ctl_set_config_ip_t *)pv_api_ip; + &ps_h264d_ctl_ip->s_ivd_ctl_set_config_ip_t; ivd_ctl_set_config_op_t *ps_ctl_op = - (ivd_ctl_set_config_op_t *)pv_api_op; + &ps_h264d_ctl_op->s_ivd_ctl_set_config_op_t; ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle); diff --git a/decoder/ih264d_defs.h b/decoder/ih264d_defs.h index 73604f1..aeb2520 100644 --- a/decoder/ih264d_defs.h +++ b/decoder/ih264d_defs.h @@ -602,8 +602,9 @@ enum #define DISP_BOT_FLD_FIRST 2 /** Misc error resilience requirements*/ -#define MASK_LOG2_WEIGHT_DENOM 0xFFFFFFF8 -#define MASK_PRED_WEIGHT_OFFSET 0xFFFFFF00 +#define MAX_LOG2_WEIGHT_DENOM 7 +#define PRED_WEIGHT_MIN (-128) +#define PRED_WEIGHT_MAX 127 #define MAX_REDUNDANT_PIC_CNT 127 diff --git a/decoder/ih264d_dpb_manager.h b/decoder/ih264d_dpb_manager.h index 3bf00b7..5747016 100644 --- a/decoder/ih264d_dpb_manager.h +++ b/decoder/ih264d_dpb_manager.h @@ -106,6 +106,7 @@ typedef struct WORD8 i1_gaps_deleted; UWORD16 u2_pic_wd; UWORD16 u2_pic_ht; + UWORD8 u1_mmco_error_in_seq; }dpb_manager_t; /** Structure store the MMC Commands */ diff --git a/decoder/ih264d_dpb_mgr.c b/decoder/ih264d_dpb_mgr.c index 28c9619..ce977d7 100644 --- a/decoder/ih264d_dpb_mgr.c +++ b/decoder/ih264d_dpb_mgr.c @@ -88,6 +88,7 @@ void ih264d_init_ref_bufs(dpb_manager_t *ps_dpb_mgr) ps_dpb_mgr->ps_dpb_ht_head = NULL; ps_dpb_mgr->i1_gaps_deleted = 0; ps_dpb_mgr->i1_poc_buf_id_entries = 0; + ps_dpb_mgr->u1_mmco_error_in_seq = 0; ps_dpb_mgr->u1_num_gaps = 0; for(i = 0; i < MAX_FRAMES; i++) @@ -647,6 +648,7 @@ void ih264d_reset_ref_bufs(dpb_manager_t *ps_dpb_mgr) ps_dpb_mgr->u1_num_st_ref_bufs = ps_dpb_mgr->u1_num_lt_ref_bufs = 0; ps_dpb_mgr->ps_dpb_st_head = NULL; ps_dpb_mgr->ps_dpb_ht_head = NULL; + ps_dpb_mgr->u1_mmco_error_in_seq = 0; /* release all gaps */ ps_dpb_mgr->u1_num_gaps = 0; diff --git a/decoder/ih264d_error_handler.h b/decoder/ih264d_error_handler.h index 6cdbc81..a651c46 100644 --- a/decoder/ih264d_error_handler.h +++ b/decoder/ih264d_error_handler.h @@ -122,7 +122,8 @@ typedef enum ERROR_INV_SEI_MDCV_PARAMS = 0x9C, ERROR_INV_SEI_CLL_PARAMS = 0x9D, ERROR_INV_SEI_AVE_PARAMS = 0x9E, - ERROR_INV_SEI_CCV_PARAMS = 0x9F + ERROR_INV_SEI_CCV_PARAMS = 0x9F, + ERROR_INV_FRAME_NUM = 0xA0 } h264_decoder_error_code_t; diff --git a/decoder/ih264d_parse_bslice.c b/decoder/ih264d_parse_bslice.c index 0af4214..936963a 100644 --- a/decoder/ih264d_parse_bslice.c +++ b/decoder/ih264d_parse_bslice.c @@ -34,6 +34,7 @@ */ #include <string.h> +#include "ih264_defs.h" #include "ih264d_bitstrm.h" #include "ih264d_defs.h" #include "ih264d_debug.h" @@ -1196,8 +1197,8 @@ void ih264d_get_implicit_weights(dec_struct_t *ps_dec) UWORD8 i, j; struct pic_buffer_t *ps_pic_buff0, *ps_pic_buff1; WORD16 i2_dist_scale_factor; - WORD16 i16_tb, i16_td, i16_tx; - WORD32 i4_tb, i4_td; + WORD16 i2_tb, i2_td, i2_tx; + WORD64 i8_tb, i8_td; WORD32 i4_poc0, i4_poc1; UWORD32 ui_temp0, ui_temp1; UWORD8 uc_num_ref_idx_l0_active, uc_num_ref_idx_l1_active; @@ -1219,13 +1220,13 @@ void ih264d_get_implicit_weights(dec_struct_t *ps_dec) if(i4_poc1 != i4_poc0) { - i4_tb = ps_dec->ps_cur_pic->i4_poc - i4_poc0; - i16_tb = CLIP_S8(i4_tb); - i4_td = i4_poc1 - i4_poc0; - i16_td = CLIP_S8(i4_td); - i16_tx = (16384 + ABS(SIGN_POW2_DIV(i16_td, 1))) / i16_td; + i8_tb = (WORD64)ps_dec->ps_cur_pic->i4_poc - i4_poc0; + i2_tb = CLIP_S8(i8_tb); + i8_td = (WORD64)i4_poc1 - i4_poc0; + i2_td = CLIP_S8(i8_td); + i2_tx = (16384 + ABS(SIGN_POW2_DIV(i2_td, 1))) / i2_td; i2_dist_scale_factor = CLIP_S11( - (((i16_tb * i16_tx) + 32) >> 6)); + (((i2_tb * i2_tx) + 32) >> 6)); if(/*((u4_poc1 - u4_poc0) == 0) ||*/ (!(ps_pic_buff1->u1_is_short && ps_pic_buff0->u1_is_short)) @@ -1289,14 +1290,14 @@ void ih264d_get_implicit_weights(dec_struct_t *ps_dec) i4_poc1 = ps_pic_buff1->i4_poc; if(i4_poc1 != i4_poc0) { - i4_tb = i4_cur_poc - i4_poc0; - i16_tb = CLIP_S8(i4_tb); - i4_td = i4_poc1 - i4_poc0; - i16_td = CLIP_S8(i4_td); - i16_tx = (16384 + ABS(SIGN_POW2_DIV(i16_td, 1))) - / i16_td; + i8_tb = (WORD64)i4_cur_poc - i4_poc0; + i2_tb = CLIP_S8(i8_tb); + i8_td = (WORD64)i4_poc1 - i4_poc0; + i2_td = CLIP_S8(i8_td); + i2_tx = (16384 + ABS(SIGN_POW2_DIV(i2_td, 1))) + / i2_td; i2_dist_scale_factor = CLIP_S11( - (((i16_tb * i16_tx) + 32) >> 6)); + (((i2_tb * i2_tx) + 32) >> 6)); if(/*((u4_poc1 - u4_poc0) == 0) ||*/ (!(ps_pic_buff1->u1_is_short && ps_pic_buff0->u1_is_short)) @@ -1354,6 +1355,7 @@ WORD32 ih264d_parse_bslice(dec_struct_t * ps_dec, UWORD16 u2_first_mb_in_slice) UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer; UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst; + UWORD64 u8_ref_idx_l0, u8_ref_idx_l1; UWORD32 u4_temp, ui_temp1; WORD32 i_temp; WORD32 ret; @@ -1380,31 +1382,31 @@ WORD32 ih264d_parse_bslice(dec_struct_t * ps_dec, UWORD16 u2_first_mb_in_slice) COPYTHECONTEXT("SH: num_ref_idx_override_flag", ps_slice->u1_num_ref_idx_active_override_flag); - u4_temp = ps_dec->ps_cur_pps->u1_num_ref_idx_lx_active[0]; - ui_temp1 = ps_dec->ps_cur_pps->u1_num_ref_idx_lx_active[1]; + u8_ref_idx_l0 = ps_dec->ps_cur_pps->u1_num_ref_idx_lx_active[0]; + u8_ref_idx_l1 = ps_dec->ps_cur_pps->u1_num_ref_idx_lx_active[1]; if(ps_slice->u1_num_ref_idx_active_override_flag) { - u4_temp = 1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + u8_ref_idx_l0 = (UWORD64)1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); COPYTHECONTEXT("SH: num_ref_idx_l0_active_minus1", - u4_temp - 1); - ui_temp1 = 1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + u8_ref_idx_l0 - 1); + + u8_ref_idx_l1 = (UWORD64)1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); COPYTHECONTEXT("SH: num_ref_idx_l1_active_minus1", - ui_temp1 - 1); + u8_ref_idx_l1 - 1); } { - UWORD8 u1_max_ref_idx = MAX_FRAMES; + UWORD8 u1_max_ref_idx = H264_MAX_REF_PICS; if(ps_slice->u1_field_pic_flag) { - u1_max_ref_idx = MAX_FRAMES << 1; + u1_max_ref_idx = H264_MAX_REF_PICS << 1; } - if((u4_temp > u1_max_ref_idx) || (ui_temp1 > u1_max_ref_idx) - || (u4_temp < 1) || (ui_temp1 < 1)) + if((u8_ref_idx_l0 > u1_max_ref_idx) || (u8_ref_idx_l1 > u1_max_ref_idx)) { return ERROR_NUM_REF; } - ps_slice->u1_num_ref_idx_lx_active[0] = u4_temp; - ps_slice->u1_num_ref_idx_lx_active[1] = ui_temp1; + ps_slice->u1_num_ref_idx_lx_active[0] = u8_ref_idx_l0; + ps_slice->u1_num_ref_idx_lx_active[1] = u8_ref_idx_l1; } @@ -1600,13 +1602,13 @@ WORD32 ih264d_parse_bslice(dec_struct_t * ps_dec, UWORD16 u2_first_mb_in_slice) } /* Read slice_qp_delta */ - i_temp = ps_pps->u1_pic_init_qp - + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); - if((i_temp < 0) || (i_temp > 51)) + WORD64 i8_temp = (WORD64)ps_pps->u1_pic_init_qp + + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + if((i8_temp < MIN_H264_QP) || (i8_temp > MAX_H264_QP)) { return ERROR_INV_RANGE_QP_T; } - ps_slice->u1_slice_qp = i_temp; + ps_slice->u1_slice_qp = i8_temp; COPYTHECONTEXT("SH: slice_qp_delta", (WORD8)(ps_slice->u1_slice_qp - ps_pps->u1_pic_init_qp)); diff --git a/decoder/ih264d_parse_headers.c b/decoder/ih264d_parse_headers.c index 160336a..8f0cb40 100644 --- a/decoder/ih264d_parse_headers.c +++ b/decoder/ih264d_parse_headers.c @@ -35,6 +35,7 @@ #include "ih264_typedefs.h" #include "ih264_macros.h" #include "ih264_platform_macros.h" +#include "ih264_defs.h" #include "ih264d_bitstrm.h" #include "ih264d_structs.h" #include "ih264d_parse_cavlc.h" @@ -275,6 +276,7 @@ WORD32 ih264d_parse_pps(dec_struct_t * ps_dec, dec_bit_stream_t * ps_bitstrm) UWORD32 *pu4_bitstrm_ofst = &ps_dec->ps_bitstrm->u4_ofst; /* Variables used for error resilience checks */ + UWORD64 u8_temp; UWORD32 u4_temp; WORD32 i_temp; @@ -327,30 +329,28 @@ WORD32 ih264d_parse_pps(dec_struct_t * ps_dec, dec_bit_stream_t * ps_bitstrm) /*--------------------------------------------------------------------*/ /* Decode num_slice_groups_minus1 */ /*--------------------------------------------------------------------*/ - u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf) + 1; - if(u4_temp != 1) + u8_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf) + (UWORD64)1; + if(u8_temp != 1) { - UWORD32 i4_error_code; - i4_error_code = ERROR_FEATURE_UNAVAIL; - return i4_error_code; + return ERROR_FEATURE_UNAVAIL; } - ps_pps->u1_num_slice_groups = u4_temp; + ps_pps->u1_num_slice_groups = u8_temp; COPYTHECONTEXT("PPS: num_slice_groups_minus1",ps_pps->u1_num_slice_groups -1); /*--------------------------------------------------------------------*/ /* Other parameter set values */ /*--------------------------------------------------------------------*/ - u4_temp = 1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); - if(u4_temp > H264_MAX_REF_IDX) + u8_temp = (UWORD64)1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + if(u8_temp > H264_MAX_REF_IDX) return ERROR_REF_IDX; - ps_pps->u1_num_ref_idx_lx_active[0] = u4_temp; + ps_pps->u1_num_ref_idx_lx_active[0] = u8_temp; COPYTHECONTEXT("PPS: num_ref_idx_l0_active_minus1", ps_pps->u1_num_ref_idx_lx_active[0] - 1); - u4_temp = 1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); - if(u4_temp > H264_MAX_REF_IDX) + u8_temp = (UWORD64)1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + if(u8_temp > H264_MAX_REF_IDX) return ERROR_REF_IDX; - ps_pps->u1_num_ref_idx_lx_active[1] = u4_temp; + ps_pps->u1_num_ref_idx_lx_active[1] = u8_temp; COPYTHECONTEXT("PPS: num_ref_idx_l1_active_minus1", ps_pps->u1_num_ref_idx_lx_active[1] - 1); @@ -363,20 +363,21 @@ WORD32 ih264d_parse_pps(dec_struct_t * ps_dec, dec_bit_stream_t * ps_bitstrm) if(ps_pps->u1_wted_bipred_idc > MAX_WEIGHT_BIPRED_IDC) return ERROR_INV_SPS_PPS_T; - i_temp = 26 + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + WORD64 i8_temp = (WORD64)26 + + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); - if((i_temp < 0) || (i_temp > 51)) + if((i8_temp < MIN_H264_QP) || (i8_temp > MAX_H264_QP)) return ERROR_INV_RANGE_QP_T; - ps_pps->u1_pic_init_qp = i_temp; + ps_pps->u1_pic_init_qp = i8_temp; COPYTHECONTEXT("PPS: pic_init_qp_minus26",ps_pps->u1_pic_init_qp - 26); - i_temp = 26 + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + i8_temp = (WORD64)26 + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); - if((i_temp < 0) || (i_temp > 51)) + if((i8_temp < MIN_H264_QP) || (i8_temp > MAX_H264_QP)) return ERROR_INV_RANGE_QP_T; - ps_pps->u1_pic_init_qs = i_temp; + ps_pps->u1_pic_init_qs = i8_temp; COPYTHECONTEXT("PPS: pic_init_qs_minus26",ps_pps->u1_pic_init_qs - 26); i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); @@ -577,6 +578,7 @@ WORD32 ih264d_parse_sps(dec_struct_t *ps_dec, dec_bit_stream_t *ps_bitstrm) UWORD8 u1_frm, uc_constraint_set0_flag, uc_constraint_set1_flag; WORD32 i4_cropped_ht, i4_cropped_wd; UWORD32 u4_temp; + UWORD64 u8_temp; UWORD32 u4_pic_height_in_map_units, u4_pic_width_in_mbs; UWORD32 u2_pic_wd = 0; UWORD32 u2_pic_ht = 0; @@ -771,12 +773,12 @@ WORD32 ih264d_parse_sps(dec_struct_t *ps_dec, dec_bit_stream_t *ps_bitstrm) /*--------------------------------------------------------------------*/ /* Decode MaxFrameNum */ /*--------------------------------------------------------------------*/ - u4_temp = 4 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); - if(u4_temp > MAX_BITS_IN_FRAME_NUM) + u8_temp = (UWORD64)4 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + if(u8_temp > MAX_BITS_IN_FRAME_NUM) { return ERROR_INV_SPS_PPS_T; } - ps_seq->u1_bits_in_frm_num = u4_temp; + ps_seq->u1_bits_in_frm_num = u8_temp; COPYTHECONTEXT("SPS: log2_max_frame_num_minus4", (ps_seq->u1_bits_in_frm_num - 4)); @@ -797,14 +799,14 @@ WORD32 ih264d_parse_sps(dec_struct_t *ps_dec, dec_bit_stream_t *ps_bitstrm) ps_seq->u1_num_ref_frames_in_pic_order_cnt_cycle = 1; if(ps_seq->u1_pic_order_cnt_type == 0) { - u4_temp = 4 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); - if(u4_temp > MAX_BITS_IN_POC_LSB) + u8_temp = (UWORD64)4 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + if(u8_temp > MAX_BITS_IN_POC_LSB) { return ERROR_INV_SPS_PPS_T; } - ps_seq->u1_log2_max_pic_order_cnt_lsb_minus = u4_temp; - ps_seq->i4_max_pic_order_cntLsb = (1 << u4_temp); - COPYTHECONTEXT("SPS: log2_max_pic_order_cnt_lsb_minus4",(u4_temp - 4)); + ps_seq->u1_log2_max_pic_order_cnt_lsb_minus = u8_temp; + ps_seq->i4_max_pic_order_cntLsb = (1 << u8_temp); + COPYTHECONTEXT("SPS: log2_max_pic_order_cnt_lsb_minus4",(u8_temp - 4)); } else if(ps_seq->u1_pic_order_cnt_type == 1) { @@ -864,20 +866,23 @@ WORD32 ih264d_parse_sps(dec_struct_t *ps_dec, dec_bit_stream_t *ps_bitstrm) /*--------------------------------------------------------------------*/ /* Decode FrameWidth and FrameHeight and related values */ /*--------------------------------------------------------------------*/ - u4_pic_width_in_mbs = 1 - + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + u8_temp = (UWORD64)1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + /* Check for unsupported resolutions*/ + if(u8_temp > (H264_MAX_FRAME_WIDTH >> 4)) + { + return IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED; + } + u4_pic_width_in_mbs = u8_temp; COPYTHECONTEXT("SPS: pic_width_in_mbs_minus1", u4_pic_width_in_mbs - 1); - u4_pic_height_in_map_units = 1 + ih264d_uev(pu4_bitstrm_ofst, - pu4_bitstrm_buf); - - /* Check for unsupported resolutions*/ - if((u4_pic_width_in_mbs > (H264_MAX_FRAME_WIDTH >> 4)) || - (u4_pic_height_in_map_units > (H264_MAX_FRAME_HEIGHT >> 4))) + u8_temp = (UWORD64)1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + if (u8_temp > (H264_MAX_FRAME_HEIGHT >> 4)) { return IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED; } + u4_pic_height_in_map_units = u8_temp; + ps_seq->u2_frm_wd_in_mbs = u4_pic_width_in_mbs; ps_seq->u2_frm_ht_in_mbs = u4_pic_height_in_map_units; diff --git a/decoder/ih264d_parse_islice.c b/decoder/ih264d_parse_islice.c index 46a87d1..0b8111a 100644 --- a/decoder/ih264d_parse_islice.c +++ b/decoder/ih264d_parse_islice.c @@ -33,9 +33,10 @@ * \author NS ************************************************************************** */ +#include <string.h> +#include "ih264_defs.h" #include "ih264d_error_handler.h" #include "ih264d_debug.h" -#include <string.h> #include "ih264d_bitstrm.h" #include "ih264d_defs.h" #include "ih264d_debug.h" @@ -1399,11 +1400,11 @@ WORD32 ih264d_parse_islice(dec_struct_t *ps_dec, /* G050 */ /* Read slice_qp_delta */ - i_temp = ps_pps->u1_pic_init_qp - + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); - if((i_temp < 0) || (i_temp > 51)) + WORD64 i8_temp = (WORD64)ps_pps->u1_pic_init_qp + + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + if((i8_temp < MIN_H264_QP) || (i8_temp > MAX_H264_QP)) return ERROR_INV_RANGE_QP_T; - ps_slice->u1_slice_qp = i_temp; + ps_slice->u1_slice_qp = i8_temp; COPYTHECONTEXT("SH: slice_qp_delta", ps_slice->u1_slice_qp - ps_pps->u1_pic_init_qp); diff --git a/decoder/ih264d_parse_pslice.c b/decoder/ih264d_parse_pslice.c index 9b9256b..6f8df9e 100644 --- a/decoder/ih264d_parse_pslice.c +++ b/decoder/ih264d_parse_pslice.c @@ -35,6 +35,7 @@ */ #include <string.h> +#include "ih264_defs.h" #include "ih264d_bitstrm.h" #include "ih264d_defs.h" #include "ih264d_debug.h" @@ -1494,7 +1495,11 @@ WORD32 ih264d_mark_err_slice_skip(dec_struct_t * ps_dec, ps_dec->p_motion_compensate = ih264d_motion_compensate_bp; if(ps_dec->ps_cur_pic != NULL) - poc = ps_dec->ps_cur_pic->i4_poc + 2; + { + poc = ps_dec->ps_cur_pic->i4_poc; + if (poc <= INT32_MAX - 2) + poc += 2; + } j = -1; for(i = 0; i < MAX_NUM_PIC_PARAMS; i++) @@ -1922,6 +1927,7 @@ WORD32 ih264d_parse_pslice(dec_struct_t *ps_dec, UWORD16 u2_first_mb_in_slice) UWORD8 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag; //ps_dec->ps_cur_sps->u1_mb_aff_flag; UWORD8 u1_field_pic_flag = ps_cur_slice->u1_field_pic_flag; + UWORD64 u8_ref_idx_l0; UWORD32 u4_temp; WORD32 i_temp; WORD32 ret; @@ -1950,22 +1956,19 @@ WORD32 ih264d_parse_pslice(dec_struct_t *ps_dec, UWORD16 u2_first_mb_in_slice) COPYTHECONTEXT("SH: num_ref_idx_override_flag", ps_cur_slice->u1_num_ref_idx_active_override_flag); - u4_temp = ps_dec->ps_cur_pps->u1_num_ref_idx_lx_active[0]; + u8_ref_idx_l0 = ps_dec->ps_cur_pps->u1_num_ref_idx_lx_active[0]; if(ps_cur_slice->u1_num_ref_idx_active_override_flag) { - u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf) + 1; + u8_ref_idx_l0 = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf) + (UWORD64)1; } { - - - - UWORD8 u1_max_ref_idx = MAX_FRAMES << u1_field_pic_flag; - if(u4_temp > u1_max_ref_idx || u4_temp < 1) + UWORD8 u1_max_ref_idx = H264_MAX_REF_PICS << u1_field_pic_flag; + if(u8_ref_idx_l0 > u1_max_ref_idx) { return ERROR_NUM_REF; } - ps_cur_slice->u1_num_ref_idx_lx_active[0] = u4_temp; + ps_cur_slice->u1_num_ref_idx_lx_active[0] = u8_ref_idx_l0; COPYTHECONTEXT("SH: num_ref_idx_l0_active_minus1", ps_cur_slice->u1_num_ref_idx_lx_active[0] - 1); @@ -2126,13 +2129,13 @@ WORD32 ih264d_parse_pslice(dec_struct_t *ps_dec, UWORD16 u2_first_mb_in_slice) } /* Read slice_qp_delta */ - i_temp = ps_pps->u1_pic_init_qp - + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); - if((i_temp < 0) || (i_temp > 51)) + WORD64 i8_temp = (WORD64)ps_pps->u1_pic_init_qp + + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + if((i8_temp < MIN_H264_QP) || (i8_temp > MAX_H264_QP)) { return ERROR_INV_RANGE_QP_T; } - ps_cur_slice->u1_slice_qp = i_temp; + ps_cur_slice->u1_slice_qp = i8_temp; COPYTHECONTEXT("SH: slice_qp_delta", (WORD8)(ps_cur_slice->u1_slice_qp - ps_pps->u1_pic_init_qp)); diff --git a/decoder/ih264d_parse_slice.c b/decoder/ih264d_parse_slice.c index 9879549..266c69b 100644 --- a/decoder/ih264d_parse_slice.c +++ b/decoder/ih264d_parse_slice.c @@ -1435,17 +1435,20 @@ WORD32 ih264d_parse_decode_slice(UWORD8 u1_is_idr_slice, i1_is_end_of_poc = 0; } - if (ps_dec->u4_first_slice_in_pic == 0) + /* Increment only if the current slice has atleast 1 more MB */ + if (ps_dec->u4_first_slice_in_pic == 0 && + (ps_dec->ps_parse_cur_slice->u4_first_mb_in_slice < + (UWORD32)(ps_dec->u2_total_mbs_coded >> ps_dec->ps_cur_slice->u1_mbaff_frame_flag))) { ps_dec->ps_parse_cur_slice++; ps_dec->u2_cur_slice_num++; + // in the case of single core increment ps_decode_cur_slice + if(ps_dec->u1_separate_parse == 0) + { + ps_dec->ps_decode_cur_slice++; + } } - // in the case of single core increment ps_decode_cur_slice - if((ps_dec->u1_separate_parse == 0) && (ps_dec->u4_first_slice_in_pic == 0)) - { - ps_dec->ps_decode_cur_slice++; - } ps_dec->u1_slice_header_done = 0; @@ -1472,10 +1475,20 @@ WORD32 ih264d_parse_decode_slice(UWORD8 u1_is_idr_slice, else i4_temp_poc = ps_dec->ps_cur_pic->i4_bottom_field_order_cnt; - ps_dec->ps_cur_pic->i4_top_field_order_cnt = i4_temp_poc + WORD64 i8_result = (WORD64)i4_temp_poc - ps_dec->ps_cur_pic->i4_top_field_order_cnt; - ps_dec->ps_cur_pic->i4_bottom_field_order_cnt = i4_temp_poc + if(IS_OUT_OF_RANGE_S32(i8_result)) + { + return ERROR_INV_POC; + } + ps_dec->ps_cur_pic->i4_top_field_order_cnt = i8_result; + i8_result = (WORD64)i4_temp_poc - ps_dec->ps_cur_pic->i4_bottom_field_order_cnt; + if(IS_OUT_OF_RANGE_S32(i8_result)) + { + return ERROR_INV_POC; + } + ps_dec->ps_cur_pic->i4_bottom_field_order_cnt = i8_result; ps_dec->ps_cur_pic->i4_poc = i4_temp_poc; ps_dec->ps_cur_pic->i4_avg_poc = i4_temp_poc; } diff --git a/decoder/ih264d_process_bslice.c b/decoder/ih264d_process_bslice.c index 5dfba33..fffa586 100644 --- a/decoder/ih264d_process_bslice.c +++ b/decoder/ih264d_process_bslice.c @@ -756,7 +756,7 @@ WORD32 ih264d_decode_temporal_direct(dec_struct_t * ps_dec, } { WORD16 i16_td; - WORD32 diff; + WORD64 diff; if(c_refFrm0 >= 0) { i2_mv_x0 = ps_mv->i2_mv[0]; @@ -782,7 +782,7 @@ WORD32 ih264d_decode_temporal_direct(dec_struct_t * ps_dec, i2_mv_y0 *= 2; } - diff = pic1_poc - pic0_poc; + diff = (WORD64)pic1_poc - pic0_poc; i16_td = CLIP_S8(diff); if((ps_pic_buff0->u1_is_short == 0) || (i16_td == 0)) { @@ -791,21 +791,21 @@ WORD32 ih264d_decode_temporal_direct(dec_struct_t * ps_dec, } else { - WORD16 i16_tb, i16_tx, i2_dist_scale_factor, i16_temp; + WORD16 i2_tb, i2_tx, i2_dist_scale_factor, i2_temp; - diff = cur_poc - pic0_poc; - i16_tb = CLIP_S8(diff); + diff = (WORD64)cur_poc - pic0_poc; + i2_tb = CLIP_S8(diff); - i16_tx = (16384 + ABS(SIGN_POW2_DIV(i16_td, 1))) / i16_td; + i2_tx = (16384 + ABS(SIGN_POW2_DIV(i16_td, 1))) / i16_td; i2_dist_scale_factor = CLIP_S11( - (((i16_tb * i16_tx) + 32) >> 6)); - i16_temp = (i2_mv_x0 * i2_dist_scale_factor + 128) >> 8; - i2_mv_x1 = i16_temp - i2_mv_x0; - i2_mv_x0 = i16_temp; - - i16_temp = (i2_mv_y0 * i2_dist_scale_factor + 128) >> 8; - i2_mv_y1 = i16_temp - i2_mv_y0; - i2_mv_y0 = i16_temp; + (((i2_tb * i2_tx) + 32) >> 6)); + i2_temp = (i2_mv_x0 * i2_dist_scale_factor + 128) >> 8; + i2_mv_x1 = i2_temp - i2_mv_x0; + i2_mv_x0 = i2_temp; + + i2_temp = (i2_mv_y0 * i2_dist_scale_factor + 128) >> 8; + i2_mv_y1 = i2_temp - i2_mv_y0; + i2_mv_y0 = i2_temp; } { mv_pred_t *ps_mv; @@ -2304,8 +2304,9 @@ void ih264d_fld_to_mbaff(dec_struct_t *ps_dec, { if(ABS(ps_col_pic->i4_top_field_order_cnt - - ps_dec->ps_cur_pic->i4_poc) >= - ABS(ps_dec->ps_cur_pic->i4_poc - ps_col_pic->i4_bottom_field_order_cnt)) + - (WORD64)ps_dec->ps_cur_pic->i4_poc) >= + ABS((WORD64)ps_dec->ps_cur_pic->i4_poc + - ps_col_pic->i4_bottom_field_order_cnt)) { ps_col_pic = ps_dec->ps_ref_pic_buf_lx[1][MAX_REF_BUFS]; } @@ -2336,8 +2337,9 @@ void ih264d_fld_to_mbaff(dec_struct_t *ps_dec, if(u1_is_cur_mb_fld == 0) { if(ABS(ps_col_pic->i4_top_field_order_cnt - - ps_dec->ps_cur_pic->i4_poc) >= - ABS(ps_dec->ps_cur_pic->i4_poc - ps_col_pic->i4_bottom_field_order_cnt)) + - (WORD64)ps_dec->ps_cur_pic->i4_poc) >= + ABS((WORD64)ps_dec->ps_cur_pic->i4_poc + - ps_col_pic->i4_bottom_field_order_cnt)) { u2_sub_mb_ofst += 0x10; } diff --git a/decoder/ih264d_process_pslice.c b/decoder/ih264d_process_pslice.c index 7c24383..c29063a 100644 --- a/decoder/ih264d_process_pslice.c +++ b/decoder/ih264d_process_pslice.c @@ -829,7 +829,7 @@ WORD32 ih264d_parse_pred_weight_table(dec_slice_params_t * ps_cur_slice, WORD32 i_temp; u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); - if(u4_temp & MASK_LOG2_WEIGHT_DENOM) + if(u4_temp > MAX_LOG2_WEIGHT_DENOM) { return ERROR_PRED_WEIGHT_TABLE_T; } @@ -838,7 +838,7 @@ WORD32 ih264d_parse_pred_weight_table(dec_slice_params_t * ps_cur_slice, ui32_y_def_weight_ofst = (1 << uc_luma_log2_weight_denom); u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); - if(u4_temp & MASK_LOG2_WEIGHT_DENOM) + if(u4_temp > MAX_LOG2_WEIGHT_DENOM) { return ERROR_PRED_WEIGHT_TABLE_T; } @@ -864,14 +864,14 @@ WORD32 ih264d_parse_pred_weight_table(dec_slice_params_t * ps_cur_slice, { i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); - if((i_temp + 128) & MASK_PRED_WEIGHT_OFFSET) + if((i_temp < PRED_WEIGHT_MIN) || (i_temp > PRED_WEIGHT_MAX)) return ERROR_PRED_WEIGHT_TABLE_T; c_weight = i_temp; COPYTHECONTEXT("SH: luma_weight_l0",c_weight); i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); - if((i_temp + 128) & MASK_PRED_WEIGHT_OFFSET) + if((i_temp < PRED_WEIGHT_MIN) || (i_temp > PRED_WEIGHT_MAX)) return ERROR_PRED_WEIGHT_TABLE_T; c_offset = i_temp; COPYTHECONTEXT("SH: luma_offset_l0",c_offset); @@ -894,14 +894,14 @@ WORD32 ih264d_parse_pred_weight_table(dec_slice_params_t * ps_cur_slice, { i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); - if((i_temp + 128) & MASK_PRED_WEIGHT_OFFSET) + if((i_temp < PRED_WEIGHT_MIN) || (i_temp > PRED_WEIGHT_MAX)) return ERROR_PRED_WEIGHT_TABLE_T; c_weightCb = i_temp; COPYTHECONTEXT("SH: chroma_weight_l0",c_weightCb); i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); - if((i_temp + 128) & MASK_PRED_WEIGHT_OFFSET) + if((i_temp < PRED_WEIGHT_MIN) || (i_temp > PRED_WEIGHT_MAX)) return ERROR_PRED_WEIGHT_TABLE_T; c_offsetCb = i_temp; COPYTHECONTEXT("SH: chroma_weight_l0",c_offsetCb); @@ -911,14 +911,14 @@ WORD32 ih264d_parse_pred_weight_table(dec_slice_params_t * ps_cur_slice, i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); - if((i_temp + 128) & MASK_PRED_WEIGHT_OFFSET) + if((i_temp < PRED_WEIGHT_MIN) || (i_temp > PRED_WEIGHT_MAX)) return ERROR_PRED_WEIGHT_TABLE_T; c_weightCr = i_temp; COPYTHECONTEXT("SH: chroma_weight_l0",c_weightCr); i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); - if((i_temp + 128) & MASK_PRED_WEIGHT_OFFSET) + if((i_temp < PRED_WEIGHT_MIN) || (i_temp > PRED_WEIGHT_MAX)) return ERROR_PRED_WEIGHT_TABLE_T; c_offsetCr = i_temp; COPYTHECONTEXT("SH: chroma_weight_l0",c_offsetCr); diff --git a/decoder/ih264d_utils.c b/decoder/ih264d_utils.c index 0893c3f..93c379b 100644 --- a/decoder/ih264d_utils.c +++ b/decoder/ih264d_utils.c @@ -161,7 +161,7 @@ WORD32 ih264d_decode_pic_order_cnt(UWORD8 u1_is_idr_slice, UWORD8 u1_field_pic_flag, WORD32 *pi4_poc) { - WORD16 i1_pic_msb; + WORD64 i8_pic_msb; WORD32 i4_top_field_order_cnt = 0, i4_bottom_field_order_cnt = 0; dec_seq_params_t *ps_seq = ps_pps->ps_sps; WORD32 i4_prev_frame_num_ofst; @@ -197,7 +197,7 @@ WORD32 ih264d_decode_pic_order_cnt(UWORD8 u1_is_idr_slice, >= (ps_seq->i4_max_pic_order_cntLsb >> 1))) { - i1_pic_msb = ps_prev_poc->i4_pic_order_cnt_msb + i8_pic_msb = (WORD64)ps_prev_poc->i4_pic_order_cnt_msb + ps_seq->i4_max_pic_order_cntLsb; } else if((ps_cur_poc->i4_pic_order_cnt_lsb @@ -207,29 +207,49 @@ WORD32 ih264d_decode_pic_order_cnt(UWORD8 u1_is_idr_slice, >= (ps_seq->i4_max_pic_order_cntLsb >> 1))) { - i1_pic_msb = ps_prev_poc->i4_pic_order_cnt_msb + i8_pic_msb = (WORD64)ps_prev_poc->i4_pic_order_cnt_msb - ps_seq->i4_max_pic_order_cntLsb; } else { - i1_pic_msb = ps_prev_poc->i4_pic_order_cnt_msb; + i8_pic_msb = ps_prev_poc->i4_pic_order_cnt_msb; } if(!u1_field_pic_flag || !u1_bottom_field_flag) - i4_top_field_order_cnt = i1_pic_msb - + ps_cur_poc->i4_pic_order_cnt_lsb; + { + WORD64 i8_result = i8_pic_msb + ps_cur_poc->i4_pic_order_cnt_lsb; + if(IS_OUT_OF_RANGE_S32(i8_result)) + { + return ERROR_INV_POC; + } + i4_top_field_order_cnt = i8_result; + } if(!u1_field_pic_flag) { - i4_bottom_field_order_cnt = i4_top_field_order_cnt - + ps_cur_poc->i4_delta_pic_order_cnt_bottom; + WORD64 i8_result = (WORD64)i4_top_field_order_cnt + + ps_cur_poc->i4_delta_pic_order_cnt_bottom; + if(IS_OUT_OF_RANGE_S32(i8_result)) + { + return ERROR_INV_POC; + } + i4_bottom_field_order_cnt = i8_result; } else if(u1_bottom_field_flag) { - i4_bottom_field_order_cnt = i1_pic_msb - + ps_cur_poc->i4_pic_order_cnt_lsb; + WORD64 i8_result = i8_pic_msb + ps_cur_poc->i4_pic_order_cnt_lsb; + if(IS_OUT_OF_RANGE_S32(i8_result)) + { + return ERROR_INV_POC; + } + i4_bottom_field_order_cnt = i8_result; + } + + if(IS_OUT_OF_RANGE_S32(i8_pic_msb)) + { + return ERROR_INV_POC; } - ps_cur_poc->i4_pic_order_cnt_msb = i1_pic_msb; + ps_cur_poc->i4_pic_order_cnt_msb = i8_pic_msb; break; case 1: @@ -269,15 +289,27 @@ WORD32 ih264d_decode_pic_order_cnt(UWORD8 u1_is_idr_slice, } else if(prev_frame_num > ((WORD32)u2_frame_num)) { - frame_num_ofst = i4_prev_frame_num_ofst - + (WORD32)ps_seq->u2_u4_max_pic_num_minus1 + 1; + WORD64 i8_result = i4_prev_frame_num_ofst + + (WORD64)ps_seq->u2_u4_max_pic_num_minus1 + 1; + if(IS_OUT_OF_RANGE_S32(i8_result)) + { + return ERROR_INV_FRAME_NUM; + } + frame_num_ofst = i8_result; } else frame_num_ofst = i4_prev_frame_num_ofst; /* 2. Derivation for absFrameNum */ if(0 != ps_seq->u1_num_ref_frames_in_pic_order_cnt_cycle) - abs_frm_num = frame_num_ofst + (WORD32)u2_frame_num; + { + WORD64 i8_result = frame_num_ofst + (WORD64)u2_frame_num; + if(IS_OUT_OF_RANGE_S32(i8_result)) + { + return ERROR_INV_FRAME_NUM; + } + abs_frm_num = i8_result; + } else abs_frm_num = 0; if((u1_nal_ref_idc == 0) && (abs_frm_num > 0)) @@ -405,8 +437,13 @@ WORD32 ih264d_decode_pic_order_cnt(UWORD8 u1_is_idr_slice, } else if(prev_frame_num > ((WORD32)u2_frame_num)) { - frame_num_ofst = i4_prev_frame_num_ofst - + (WORD32)ps_seq->u2_u4_max_pic_num_minus1 + 1; + WORD64 i8_result = i4_prev_frame_num_ofst + + (WORD64)ps_seq->u2_u4_max_pic_num_minus1 + 1; + if(IS_OUT_OF_RANGE_S32(i8_result)) + { + return ERROR_INV_FRAME_NUM; + } + frame_num_ofst = i8_result; } else frame_num_ofst = i4_prev_frame_num_ofst; @@ -415,10 +452,23 @@ WORD32 ih264d_decode_pic_order_cnt(UWORD8 u1_is_idr_slice, if(u1_is_idr_slice) tmp_poc = 0; else if(u1_nal_ref_idc == 0) - tmp_poc = ((frame_num_ofst + (WORD32)u2_frame_num) << 1) - - 1; + { + WORD64 i8_result = ((frame_num_ofst + (WORD64)u2_frame_num) << 1) - 1; + if(IS_OUT_OF_RANGE_S32(i8_result)) + { + return ERROR_INV_POC; + } + tmp_poc = i8_result; + } else - tmp_poc = ((frame_num_ofst + (WORD32)u2_frame_num) << 1); + { + WORD64 i8_result = (frame_num_ofst + (WORD64)u2_frame_num) << 1; + if(IS_OUT_OF_RANGE_S32(i8_result)) + { + return ERROR_INV_POC; + } + tmp_poc = i8_result; + } /* 6. TopFieldOrderCnt or BottomFieldOrderCnt are derived as */ if(!u1_field_pic_flag) @@ -501,6 +551,7 @@ WORD32 ih264d_end_of_pic_processing(dec_struct_t *ps_dec) { if(ps_cur_slice->u1_nal_unit_type == IDR_SLICE_NAL) { + ps_dec->ps_dpb_mgr->u1_mmco_error_in_seq = 0; if(ps_dec->ps_dpb_cmds->u1_long_term_reference_flag == 0) { ih264d_reset_ref_bufs(ps_dec->ps_dpb_mgr); @@ -538,16 +589,17 @@ WORD32 ih264d_end_of_pic_processing(dec_struct_t *ps_dec) { UWORD16 u2_pic_num = ps_cur_slice->u2_frame_num; - /* ignore DPB errors */ - ih264d_do_mmco_buffer(ps_dec->ps_dpb_cmds, ps_dec->ps_dpb_mgr, - ps_dec->ps_cur_sps->u1_num_ref_frames, u2_pic_num, - (ps_dec->ps_cur_sps->u2_u4_max_pic_num_minus1), - ps_dec->u1_nal_unit_type, ps_dec->ps_cur_pic, - ps_dec->u1_pic_buf_id, - ps_cur_slice->u1_field_pic_flag, - ps_dec->e_dec_status); - - + if(!ps_dec->ps_dpb_mgr->u1_mmco_error_in_seq) + { + WORD32 ret = ih264d_do_mmco_buffer(ps_dec->ps_dpb_cmds, ps_dec->ps_dpb_mgr, + ps_dec->ps_cur_sps->u1_num_ref_frames, u2_pic_num, + (ps_dec->ps_cur_sps->u2_u4_max_pic_num_minus1), + ps_dec->u1_nal_unit_type, ps_dec->ps_cur_pic, + ps_dec->u1_pic_buf_id, + ps_cur_slice->u1_field_pic_flag, + ps_dec->e_dec_status); + ps_dec->ps_dpb_mgr->u1_mmco_error_in_seq = ret != OK; + } } } ih264d_update_default_index_list(ps_dec->ps_dpb_mgr); diff --git a/encoder/ih264e_api.c b/encoder/ih264e_api.c index 61ef6b5..53067e0 100644 --- a/encoder/ih264e_api.c +++ b/encoder/ih264e_api.c @@ -142,6 +142,101 @@ WORD32 ih264e_get_rate_control_mem_tab(void *pv_rate_control, ******************************************************************************* * * @brief +* Used to test validity of input dimensions +* +* @par Description: +* Dimensions of the input buffer passed to encode call are validated +* +* @param[in] ps_codec +* Codec context +* +* @param[in] ps_ip +* Pointer to input structure +* +* @param[out] ps_op +* Pointer to output structure +* +* @returns error status +* +* @remarks none +* +******************************************************************************* +*/ +static IV_STATUS_T api_check_input_dimensions(codec_t *ps_codec, + ih264e_video_encode_ip_t *ps_ip, + ih264e_video_encode_op_t *ps_op) +{ + UWORD32 u4_wd, u4_ht; + cfg_params_t *ps_curr_cfg = &ps_codec->s_cfg; + iv_raw_buf_t *ps_inp_buf = &ps_ip->s_ive_ip.s_inp_buf; + + u4_wd = ps_inp_buf->au4_wd[0]; + u4_ht = ps_inp_buf->au4_ht[0]; + switch (ps_inp_buf->e_color_fmt) + { + case IV_YUV_420P: + if (((ps_inp_buf->au4_wd[0] / 2) != ps_inp_buf->au4_wd[1]) || + ((ps_inp_buf->au4_wd[0] / 2) != ps_inp_buf->au4_wd[2]) || + (ps_inp_buf->au4_wd[1] != ps_inp_buf->au4_wd[2])) + { + ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; + ps_op->s_ive_op.u4_error_code |= IH264E_WIDTH_NOT_SUPPORTED; + return (IV_FAIL); + } + if (((ps_inp_buf->au4_ht[0] / 2) != ps_inp_buf->au4_ht[1]) || + ((ps_inp_buf->au4_ht[0] / 2) != ps_inp_buf->au4_ht[2]) || + (ps_inp_buf->au4_ht[1] != ps_inp_buf->au4_ht[2])) + { + ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; + ps_op->s_ive_op.u4_error_code |= IH264E_HEIGHT_NOT_SUPPORTED; + return (IV_FAIL); + } + break; + case IV_YUV_420SP_UV: + case IV_YUV_420SP_VU: + if ((ps_inp_buf->au4_wd[0] / 2) != ps_inp_buf->au4_wd[1]) + { + ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; + ps_op->s_ive_op.u4_error_code |= IH264E_WIDTH_NOT_SUPPORTED; + return (IV_FAIL); + } + if ((ps_inp_buf->au4_ht[0] / 2) != ps_inp_buf->au4_ht[1]) + { + ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; + ps_op->s_ive_op.u4_error_code |= IH264E_HEIGHT_NOT_SUPPORTED; + return (IV_FAIL); + } + break; + case IV_YUV_422ILE: + u4_wd = ps_inp_buf->au4_wd[0] / 2; + break; + default: + ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; + ps_op->s_ive_op.u4_error_code |= IH264E_INPUT_CHROMA_FORMAT_NOT_SUPPORTED; + return (IV_FAIL); + } + + if (u4_wd != ps_curr_cfg->u4_disp_wd) + { + ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; + ps_op->s_ive_op.u4_error_code |= IH264E_WIDTH_NOT_SUPPORTED; + return (IV_FAIL); + } + + if (u4_ht != ps_curr_cfg->u4_disp_ht) + { + ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; + ps_op->s_ive_op.u4_error_code |= IH264E_HEIGHT_NOT_SUPPORTED; + return (IV_FAIL); + } + + return IV_SUCCESS; +} + +/** +******************************************************************************* +* +* @brief * Used to test arguments for corresponding API call * * @par Description: @@ -818,6 +913,7 @@ static IV_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle, case IVE_CMD_VIDEO_ENCODE: { + codec_t *ps_codec = (codec_t *) (ps_handle->pv_codec_handle); ih264e_video_encode_ip_t *ps_ip = pv_api_ip; ih264e_video_encode_op_t *ps_op = pv_api_op; @@ -836,6 +932,15 @@ static IV_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle, IVE_ERR_OP_ENCODE_API_STRUCT_SIZE_INCORRECT; return (IV_FAIL); } + + if (NULL != ps_ip->s_ive_ip.s_inp_buf.apv_bufs[0] && + ps_codec->i4_header_mode != 1 && + IV_SUCCESS != api_check_input_dimensions(ps_codec, ps_ip, ps_op)) + { + ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; + ps_op->s_ive_op.u4_error_code |= IVE_ERR_OP_ENCODE_API_STRUCT_SIZE_INCORRECT; + return (IV_FAIL); + } break; } @@ -4059,6 +4164,11 @@ static WORD32 ih264e_init_mem_rec(iv_obj_t *ps_codec_obj, /* Update config params as per input */ ps_cfg->u4_max_wd = ALIGN16(ps_ip->s_ive_ip.u4_max_wd); ps_cfg->u4_max_ht = ALIGN16(ps_ip->s_ive_ip.u4_max_ht); + + /* Initialize dimensions to max dimensions during init */ + ps_cfg->u4_wd = ps_cfg->u4_disp_wd = ps_cfg->u4_max_wd; + ps_cfg->u4_ht = ps_cfg->u4_disp_ht = ps_cfg->u4_max_ht; + ps_cfg->i4_wd_mbs = ps_cfg->u4_max_wd >> 4; ps_cfg->i4_ht_mbs = ps_cfg->u4_max_ht >> 4; ps_cfg->u4_max_ref_cnt = ps_ip->s_ive_ip.u4_max_ref_cnt; diff --git a/encoder/ih264e_bitstream.c b/encoder/ih264e_bitstream.c index d79f637..9f73f69 100644 --- a/encoder/ih264e_bitstream.c +++ b/encoder/ih264e_bitstream.c @@ -182,27 +182,9 @@ IH264E_ERROR_T ih264e_put_bits(bitstrm_t *ps_bitstrm, /* 4. insert remaining bits of code starting from msb of cur word */ /* 5. update bitsleft in current word and stream buffer offset */ /********************************************************************/ - UWORD32 u4_strm_buf_offset = ps_bitstrm->u4_strm_buf_offset; - - UWORD32 u4_max_strm_size = ps_bitstrm->u4_max_strm_size; - - WORD32 zero_run = ps_bitstrm->i4_zero_bytes_run; - - UWORD8* pu1_strm_buf = ps_bitstrm->pu1_strm_buffer; - + IH264E_ERROR_T status = IH264E_SUCCESS; WORD32 i, rem_bits = (code_len - bits_left_in_cw); - - /*********************************************************************/ - /* Bitstream overflow check */ - /* NOTE: corner case of epb bytes (max 2 for 32bit word) not handled */ - /*********************************************************************/ - if((u4_strm_buf_offset + (WORD_SIZE>>3)) >= u4_max_strm_size) - { - /* return without corrupting the buffer beyond its size */ - return(IH264E_BITSTREAM_BUFFER_OVERFLOW); - } - /* insert parital code corresponding to bits left in cur word */ u4_cur_word |= u4_code_val >> rem_bits; @@ -211,7 +193,7 @@ IH264E_ERROR_T ih264e_put_bits(bitstrm_t *ps_bitstrm, /* flush the bits in cur word byte by byte and copy to stream */ UWORD8 u1_next_byte = (u4_cur_word >> (i-8)) & 0xFF; - PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, u1_next_byte, zero_run); + status |= ih264e_put_byte_epb(ps_bitstrm, u1_next_byte); } /* insert the remaining bits from code val into current word */ @@ -220,9 +202,8 @@ IH264E_ERROR_T ih264e_put_bits(bitstrm_t *ps_bitstrm, /* update the state variables and return success */ ps_bitstrm->u4_cur_word = u4_cur_word; ps_bitstrm->i4_bits_left_in_cw = WORD_SIZE - rem_bits; - ps_bitstrm->i4_zero_bytes_run = zero_run; - ps_bitstrm->u4_strm_buf_offset = u4_strm_buf_offset; - return (IH264E_SUCCESS); + return (status); + } } @@ -281,22 +262,7 @@ IH264E_ERROR_T ih264e_put_rbsp_trailing_bits(bitstrm_t *ps_bitstrm) UWORD32 u4_cur_word = ps_bitstrm->u4_cur_word; WORD32 bits_left_in_cw = ps_bitstrm->i4_bits_left_in_cw; WORD32 bytes_left_in_cw = (bits_left_in_cw - 1) >> 3; - - UWORD32 u4_strm_buf_offset = ps_bitstrm->u4_strm_buf_offset; - UWORD32 u4_max_strm_size = ps_bitstrm->u4_max_strm_size; - WORD32 zero_run = ps_bitstrm->i4_zero_bytes_run; - UWORD8* pu1_strm_buf = ps_bitstrm->pu1_strm_buffer; - - /*********************************************************************/ - /* Bitstream overflow check */ - /* NOTE: corner case of epb bytes (max 2 for 32bit word) not handled */ - /*********************************************************************/ - if((u4_strm_buf_offset + (WORD_SIZE>>3) - bytes_left_in_cw) >= - u4_max_strm_size) - { - /* return without corrupting the buffer beyond its size */ - return(IH264E_BITSTREAM_BUFFER_OVERFLOW); - } + IH264E_ERROR_T status = IH264E_SUCCESS; /* insert a 1 at the end of current word and flush all the bits */ u4_cur_word |= (1 << (bits_left_in_cw - 1)); @@ -309,18 +275,15 @@ IH264E_ERROR_T ih264e_put_rbsp_trailing_bits(bitstrm_t *ps_bitstrm) /* flush the bits in cur word byte by byte and copy to stream */ UWORD8 u1_next_byte = (u4_cur_word >> (i-8)) & 0xFF; - PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, u1_next_byte, zero_run); + status |= ih264e_put_byte_epb(ps_bitstrm, u1_next_byte); } - /* update the stream offset */ - ps_bitstrm->u4_strm_buf_offset = u4_strm_buf_offset; - /* Default init values for scratch variables of bitstream context */ ps_bitstrm->u4_cur_word = 0; ps_bitstrm->i4_bits_left_in_cw = WORD_SIZE; ps_bitstrm->i4_zero_bytes_run = 0; - return (IH264E_SUCCESS); + return (status); } /** diff --git a/encoder/ih264e_bitstream.h b/encoder/ih264e_bitstream.h index 9cd2b81..5b5c700 100644 --- a/encoder/ih264e_bitstream.h +++ b/encoder/ih264e_bitstream.h @@ -169,29 +169,7 @@ { \ const WORD32 len = (WORD32)((ps_bitstrm->i4_bits_left_in_cw) & 0x07);\ ih264e_put_bits(ps_bitstrm, (UWORD32)((1 << len) - 1), len); \ - } - - -/** -****************************************************************************** -* flush the bits in cur word byte by byte and copy to stream * -* (current word is assumed to be byte aligned) * -****************************************************************************** -*/ -#define BITSTREAM_FLUSH(ps_bitstrm) \ -{ \ - WORD32 i; \ - for (i = WORD_SIZE; i > ps_bitstrm->i4_bits_left_in_cw; i -= 8) \ - { \ - UWORD8 u1_next_byte = (ps_bitstrm->u4_cur_word >> (i - 8)) & 0xFF; \ - PUTBYTE_EPB(ps_bitstrm->pu1_strm_buffer, ps_bitstrm->u4_strm_buf_offset,\ - u1_next_byte, ps_bitstrm->i4_zero_bytes_run); \ - } \ - ps_bitstrm->u4_cur_word = 0; \ - ps_bitstrm->i4_bits_left_in_cw = WORD_SIZE; \ -} \ - - + } \ /*****************************************************************************/ @@ -245,6 +223,54 @@ typedef struct bitstrm } bitstrm_t; +/** +****************************************************************************** +* @brief Inserts 1 byte and Emulation Prevention Byte(if any) into bitstream +* Increments the stream offset and zero run correspondingly +****************************************************************************** +*/ +static inline IH264E_ERROR_T ih264e_put_byte_epb(bitstrm_t *ps_bitstrm, UWORD8 byte) +{ + if (INSERT_EPB(ps_bitstrm->i4_zero_bytes_run, byte)) + { + if ((ps_bitstrm->u4_strm_buf_offset + 1) >= ps_bitstrm->u4_max_strm_size) + { + return IH264E_BITSTREAM_BUFFER_OVERFLOW; + } + ps_bitstrm->pu1_strm_buffer[ps_bitstrm->u4_strm_buf_offset++] = EPB_BYTE; + ps_bitstrm->i4_zero_bytes_run = 0; + } + + if ((ps_bitstrm->u4_strm_buf_offset + 1) >= ps_bitstrm->u4_max_strm_size) + { + return IH264E_BITSTREAM_BUFFER_OVERFLOW; + } + ps_bitstrm->pu1_strm_buffer[ps_bitstrm->u4_strm_buf_offset++] = byte; + ps_bitstrm->i4_zero_bytes_run = byte ? 0 : ps_bitstrm->i4_zero_bytes_run + 1; + + return IH264E_SUCCESS; +} + +/** +****************************************************************************** +* flush the bits in cur word byte by byte and copy to stream * +* (current word is assumed to be byte aligned) * +****************************************************************************** +*/ +#define BITSTREAM_FLUSH(ps_bitstrm, err) \ +{ \ + WORD32 i; \ + for (i = WORD_SIZE; i > ps_bitstrm->i4_bits_left_in_cw; i -= 8) \ + { \ + UWORD8 u1_next_byte = (ps_bitstrm->u4_cur_word >> (i - 8)) & 0xFF; \ + err |= ih264e_put_byte_epb(ps_bitstrm, u1_next_byte); \ + } \ + ps_bitstrm->u4_cur_word = 0; \ + ps_bitstrm->i4_bits_left_in_cw = WORD_SIZE; \ +} \ + + + /*****************************************************************************/ /* Extern Function Declarations */ /*****************************************************************************/ diff --git a/encoder/ih264e_cabac.c b/encoder/ih264e_cabac.c index 26ded4d..2d91058 100644 --- a/encoder/ih264e_cabac.c +++ b/encoder/ih264e_cabac.c @@ -242,18 +242,16 @@ void ih264e_get_cabac_context(entropy_ctxt_t *ps_ent_ctxt, WORD32 u4_mb_type) * ******************************************************************************* */ -void ih264e_cabac_flush(cabac_ctxt_t *ps_cabac_ctxt) +IH264E_ERROR_T ih264e_cabac_flush(cabac_ctxt_t *ps_cabac_ctxt) { - /* bit stream ptr */ bitstrm_t *ps_stream = ps_cabac_ctxt->ps_bitstrm; encoding_envirnoment_t *ps_cab_enc_env = &(ps_cabac_ctxt->s_cab_enc_env); UWORD32 u4_low = ps_cab_enc_env->u4_code_int_low; UWORD32 u4_bits_gen = ps_cab_enc_env->u4_bits_gen; UWORD8 *pu1_strm_buf = ps_stream->pu1_strm_buffer; - UWORD32 u4_strm_buf_offset = ps_stream->u4_strm_buf_offset; - WORD32 zero_run = ps_stream->i4_zero_bytes_run; UWORD32 u4_out_standing_bytes = ps_cab_enc_env->u4_out_standing_bytes; + IH264E_ERROR_T status = IH264E_SUCCESS; /************************************************************************/ /* Insert the carry (propogated in previous byte) along with */ @@ -274,17 +272,17 @@ void ih264e_cabac_flush(cabac_ctxt_t *ps_cabac_ctxt) as per standard */ /* so check for previous four bytes and if it is equal to 0x00000303 then subtract u4_strm_buf_offset by 1 */ - if (pu1_strm_buf[u4_strm_buf_offset - 1] == 0x03 - && pu1_strm_buf[u4_strm_buf_offset - 2] == 0x03 - && pu1_strm_buf[u4_strm_buf_offset - 3] == 0x00 - && pu1_strm_buf[u4_strm_buf_offset - 4] == 0x00) + if (pu1_strm_buf[ps_stream->u4_strm_buf_offset - 1] == 0x03 + && pu1_strm_buf[ps_stream->u4_strm_buf_offset - 2] == 0x03 + && pu1_strm_buf[ps_stream->u4_strm_buf_offset - 3] == 0x00 + && pu1_strm_buf[ps_stream->u4_strm_buf_offset - 4] == 0x00) { - u4_strm_buf_offset -= 1; + ps_stream->u4_strm_buf_offset -= 1; } /* previous byte carry add will not result in overflow to */ /* u4_strm_buf_offset - 2 as we track 0xff as outstanding bytes */ - pu1_strm_buf[u4_strm_buf_offset - 1] += carry; - zero_run = 0; + pu1_strm_buf[ps_stream->u4_strm_buf_offset - 1] += carry; + ps_stream->i4_zero_bytes_run = 0; } /* Insert outstanding bytes (if any) */ @@ -292,7 +290,7 @@ void ih264e_cabac_flush(cabac_ctxt_t *ps_cabac_ctxt) { UWORD8 u1_0_or_ff = carry ? 0 : 0xFF; - PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, u1_0_or_ff, zero_run); + status |= ih264e_put_byte_epb(ps_stream, u1_0_or_ff); u4_out_standing_bytes--; } @@ -307,7 +305,7 @@ void ih264e_cabac_flush(cabac_ctxt_t *ps_cabac_ctxt) if (bits_left >= 8) { last_byte = (rem_bits >> (bits_left - 8)) & 0xFF; - PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, last_byte, zero_run); + status |= ih264e_put_byte_epb(ps_stream, last_byte); bits_left -= 8; } @@ -315,16 +313,16 @@ void ih264e_cabac_flush(cabac_ctxt_t *ps_cabac_ctxt) last_byte = (rem_bits << (8 - bits_left)) | (1 << (7 - bits_left) | (1 << (7 - bits_left - 1))); last_byte &= 0xFF; - PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, last_byte, zero_run); + status |= ih264e_put_byte_epb(ps_stream, last_byte); /* update the state variables and return success */ - ps_stream->u4_strm_buf_offset = u4_strm_buf_offset; ps_stream->i4_zero_bytes_run = 0; /* Default init values for scratch variables of bitstream context */ ps_stream->u4_cur_word = 0; ps_stream->i4_bits_left_in_cw = WORD_SIZE; } + return status; } /** @@ -349,15 +347,16 @@ void ih264e_cabac_flush(cabac_ctxt_t *ps_cabac_ctxt) * ****************************************************************************** */ -void ih264e_cabac_put_byte(cabac_ctxt_t *ps_cabac_ctxt) +IH264E_ERROR_T ih264e_cabac_put_byte(cabac_ctxt_t *ps_cabac_ctxt) { - /* bit stream ptr */ bitstrm_t *ps_stream = ps_cabac_ctxt->ps_bitstrm; encoding_envirnoment_t *ps_cab_enc_env = &(ps_cabac_ctxt->s_cab_enc_env); UWORD32 u4_low = ps_cab_enc_env->u4_code_int_low; UWORD32 u4_bits_gen = ps_cab_enc_env->u4_bits_gen; + UWORD8 *pu1_strm_buf = ps_stream->pu1_strm_buffer; WORD32 lead_byte = u4_low >> (u4_bits_gen + CABAC_BITS - 8); + IH264E_ERROR_T status = IH264E_SUCCESS; /* Sanity checks */ ASSERT((ps_cab_enc_env->u4_code_int_range >= 256) @@ -381,15 +380,11 @@ void ih264e_cabac_put_byte(cabac_ctxt_t *ps_cabac_ctxt) { /* actual bits depend on carry propogration */ ps_cab_enc_env->u4_out_standing_bytes++; - return ; } else { /* carry = 1 => putbit(1); carry propogated due to L renorm */ WORD32 carry = (lead_byte >> 8) & 0x1; - UWORD8 *pu1_strm_buf = ps_stream->pu1_strm_buffer; - UWORD32 u4_strm_buf_offset = ps_stream->u4_strm_buf_offset; - WORD32 zero_run = ps_stream->i4_zero_bytes_run; UWORD32 u4_out_standing_bytes = ps_cab_enc_env->u4_out_standing_bytes; @@ -407,17 +402,17 @@ void ih264e_cabac_put_byte(cabac_ctxt_t *ps_cabac_ctxt) as per standard */ /* so check for previous four bytes and if it is equal to 0x00000303 then subtract u4_strm_buf_offset by 1 */ - if (pu1_strm_buf[u4_strm_buf_offset - 1] == 0x03 - && pu1_strm_buf[u4_strm_buf_offset - 2] == 0x03 - && pu1_strm_buf[u4_strm_buf_offset - 3] == 0x00 - && pu1_strm_buf[u4_strm_buf_offset - 4] == 0x00) + if (pu1_strm_buf[ps_stream->u4_strm_buf_offset - 1] == 0x03 + && pu1_strm_buf[ps_stream->u4_strm_buf_offset - 2] == 0x03 + && pu1_strm_buf[ps_stream->u4_strm_buf_offset - 3] == 0x00 + && pu1_strm_buf[ps_stream->u4_strm_buf_offset - 4] == 0x00) { - u4_strm_buf_offset -= 1; + ps_stream->u4_strm_buf_offset -= 1; } /* previous byte carry add will not result in overflow to */ /* u4_strm_buf_offset - 2 as we track 0xff as outstanding bytes */ - pu1_strm_buf[u4_strm_buf_offset - 1] += carry; - zero_run = 0; + pu1_strm_buf[ps_stream->u4_strm_buf_offset - 1] += carry; + ps_stream->i4_zero_bytes_run = 0; } /* Insert outstanding bytes (if any) */ @@ -425,7 +420,7 @@ void ih264e_cabac_put_byte(cabac_ctxt_t *ps_cabac_ctxt) { UWORD8 u1_0_or_ff = carry ? 0 : 0xFF; - PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, u1_0_or_ff, zero_run); + status |= ih264e_put_byte_epb(ps_stream, u1_0_or_ff); u4_out_standing_bytes--; } @@ -433,13 +428,9 @@ void ih264e_cabac_put_byte(cabac_ctxt_t *ps_cabac_ctxt) /* Insert the leading byte */ lead_byte &= 0xFF; - PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, lead_byte, zero_run); - - /* update the state variables and return success */ - ps_stream->u4_strm_buf_offset = u4_strm_buf_offset; - ps_stream->i4_zero_bytes_run = zero_run; - + status |= ih264e_put_byte_epb(ps_stream, lead_byte); } + return status; } diff --git a/encoder/ih264e_cabac.h b/encoder/ih264e_cabac.h index e4722fa..bc4b07c 100644 --- a/encoder/ih264e_cabac.h +++ b/encoder/ih264e_cabac.h @@ -190,7 +190,7 @@ void ih264e_get_cabac_context(entropy_ctxt_t *ps_ent_ctxt, WORD32 u4_mb_type); * ******************************************************************************* */ -void ih264e_cabac_flush(cabac_ctxt_t *ps_cabac_ctxt); +IH264E_ERROR_T ih264e_cabac_flush(cabac_ctxt_t *ps_cabac_ctxt); /** @@ -215,7 +215,7 @@ void ih264e_cabac_flush(cabac_ctxt_t *ps_cabac_ctxt); * ****************************************************************************** */ -void ih264e_cabac_put_byte(cabac_ctxt_t *ps_cabac_ctxt); +IH264E_ERROR_T ih264e_cabac_put_byte(cabac_ctxt_t *ps_cabac_ctxt); /** diff --git a/encoder/ih264e_encode.c b/encoder/ih264e_encode.c index fb37765..6a4e3a2 100644 --- a/encoder/ih264e_encode.c +++ b/encoder/ih264e_encode.c @@ -228,6 +228,9 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) ps_video_encode_op->s_ive_op.output_present = 0; ps_video_encode_op->s_ive_op.dump_recon = 0; ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_NA_FRAME; + /* By default set the current input buffer as the buffer to be freed */ + /* This will later be updated to the actual input that gets encoded */ + ps_video_encode_op->s_ive_op.s_inp_buf = ps_video_encode_ip->s_ive_ip.s_inp_buf; /* Check for output memory allocation size */ if (ps_video_encode_ip->s_ive_ip.s_out_buf.u4_bufsize < MIN_STREAM_SIZE) @@ -474,6 +477,9 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) s_out_buf.u4_is_last = s_inp_buf.u4_is_last; ps_video_encode_op->s_ive_op.u4_is_last = s_inp_buf.u4_is_last; + /* Send the input to application so that it can free it */ + ps_video_encode_op->s_ive_op.s_inp_buf = s_inp_buf.s_raw_buf; + /* Only encode if the current frame is not pre-encode skip */ if (!i4_rc_pre_enc_skip && s_inp_buf.s_raw_buf.apv_bufs[0]) { @@ -545,16 +551,16 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) * We need to return a recon when ever we consume an input buffer. This * comsumption include a pre or post enc skip. Thus dump recon is set for * all cases except when - * 1) We are waiting -> ps_codec->i4_frame_num > 1 - * 2) When the input buffer is null [ ie we are not consuming any inp] + * 1) We are waiting -> ps_codec->i4_pic_cnt > ps_codec->s_cfg.u4_num_bframe * An exception need to be made for the case when we have the last buffer * since we need to flush out the on remainig recon. ****************************************************************************/ ps_video_encode_op->s_ive_op.dump_recon = 0; - if (ps_codec->s_cfg.u4_enable_recon && (ps_codec->i4_frame_num > 1 || s_inp_buf.u4_is_last) - && (s_inp_buf.s_raw_buf.apv_bufs[0] || s_inp_buf.u4_is_last)) + if (ps_codec->s_cfg.u4_enable_recon + && (ps_codec->i4_pic_cnt > (WORD32)ps_codec->s_cfg.u4_num_bframes || + s_inp_buf.u4_is_last)) { /* error status */ IH264_ERROR_T ret = IH264_SUCCESS; @@ -774,12 +780,6 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) } else { - /* proc ctxt base idx */ - WORD32 proc_ctxt_select = ctxt_sel * MAX_PROCESS_THREADS; - - /* proc ctxt */ - process_ctxt_t *ps_proc = &ps_codec->as_process[proc_ctxt_select]; - /* receive output back from codec */ s_out_buf = ps_codec->as_out_buf[ctxt_sel]; @@ -790,18 +790,11 @@ WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) ps_video_encode_op->s_ive_op.u4_timestamp_low = 0; ps_video_encode_op->s_ive_op.u4_timestamp_high = 0; - /* receive input back from codec and send it to app */ - s_inp_buf = ps_proc->s_inp_buf; - ps_video_encode_op->s_ive_op.s_inp_buf = s_inp_buf.s_raw_buf; - ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_NA_FRAME; } - /* Send the input to encoder so that it can free it if possible */ ps_video_encode_op->s_ive_op.s_out_buf = s_out_buf.s_bits_buf; - ps_video_encode_op->s_ive_op.s_inp_buf = s_inp_buf.s_raw_buf; - if (1 == s_inp_buf.u4_is_last) { diff --git a/encoder/ih264e_process.c b/encoder/ih264e_process.c index 490c6d8..bf4c1e7 100644 --- a/encoder/ih264e_process.c +++ b/encoder/ih264e_process.c @@ -444,7 +444,7 @@ IH264E_ERROR_T ih264e_entropy(process_ctxt_t *ps_proc) if (CABAC == ps_entropy->u1_entropy_coding_mode_flag) { BITSTREAM_BYTE_ALIGN(ps_bitstrm); - BITSTREAM_FLUSH(ps_bitstrm); + BITSTREAM_FLUSH(ps_bitstrm, ps_entropy->i4_error_code); ih264e_init_cabac_ctxt(ps_entropy); } } @@ -571,7 +571,7 @@ IH264E_ERROR_T ih264e_entropy(process_ctxt_t *ps_proc) if (CABAC == ps_entropy->u1_entropy_coding_mode_flag) { BITSTREAM_BYTE_ALIGN(ps_bitstrm); - BITSTREAM_FLUSH(ps_bitstrm); + BITSTREAM_FLUSH(ps_bitstrm, ps_entropy->i4_error_code); ih264e_init_cabac_ctxt(ps_entropy); } } @@ -1259,7 +1259,8 @@ IH264E_ERROR_T ih264e_init_proc_ctxt(process_ctxt_t *ps_proc) /* init buffer pointers */ convert_uv_only = 1; if (u4_pad_bottom_sz || u4_pad_right_sz || - ps_codec->s_cfg.e_inp_color_fmt == IV_YUV_422ILE) + ps_codec->s_cfg.e_inp_color_fmt == IV_YUV_422ILE || + ps_proc->i4_mb_y == (ps_proc->i4_ht_mbs - 1)) { if (ps_proc->i4_mb_y == ps_proc->i4_ht_mbs - 1) u2_num_rows = (UWORD16) MB_SIZE - u4_pad_bottom_sz; @@ -1311,7 +1312,7 @@ IH264E_ERROR_T ih264e_init_proc_ctxt(process_ctxt_t *ps_proc) case IV_YUV_420SP_UV: case IV_YUV_420SP_VU: /* In case of 420 semi-planar input, copy last few rows to intermediate - buffer as chroma trans functions access one extra byte due to interleaved input. + buffer as few SIMD functions access upto 16 more bytes. This data will be padded if required */ if (ps_proc->i4_mb_y == (ps_proc->i4_ht_mbs - 1) || u4_pad_bottom_sz || u4_pad_right_sz) { @@ -1324,16 +1325,13 @@ IH264E_ERROR_T ih264e_init_proc_ctxt(process_ctxt_t *ps_proc) pu1_dst = ps_proc->pu1_src_buf_luma; - /* If padding is required, we always copy luma, if padding isn't required we never copy luma. */ - if (u4_pad_bottom_sz || u4_pad_right_sz) { - if (ps_proc->i4_mb_y == (ps_proc->i4_ht_mbs - 1)) - num_rows = MB_SIZE - u4_pad_bottom_sz; - for (i = 0; i < num_rows; i++) - { - memcpy(pu1_dst, pu1_src, ps_codec->s_cfg.u4_wd); - pu1_src += ps_proc->s_inp_buf.s_raw_buf.au4_strd[0]; - pu1_dst += ps_proc->i4_src_strd; - } + if (ps_proc->i4_mb_y == (ps_proc->i4_ht_mbs - 1)) + num_rows = MB_SIZE - u4_pad_bottom_sz; + for (i = 0; i < num_rows; i++) + { + memcpy(pu1_dst, pu1_src, ps_codec->s_cfg.u4_wd); + pu1_src += ps_proc->s_inp_buf.s_raw_buf.au4_strd[0]; + pu1_dst += ps_proc->i4_src_strd; } pu1_src = (UWORD8 *)ps_proc->s_inp_buf.s_raw_buf.apv_bufs[1] + (i4_mb_x * BLK8x8SIZE) + ps_proc->s_inp_buf.s_raw_buf.au4_strd[1] * (i4_mb_y * BLK8x8SIZE); @@ -1414,6 +1412,18 @@ IH264E_ERROR_T ih264e_init_proc_ctxt(process_ctxt_t *ps_proc) ps_proc->i4_src_chroma_strd, u4_pad_ht / 2, u4_pad_wd); } + if (ps_proc->i4_mb_y && ps_proc->i4_mb_y == ps_proc->i4_ht_mbs - 1) { + UWORD8 *pu1_src = (UWORD8 *)ps_proc->s_inp_buf.s_raw_buf.apv_bufs[0] + + ps_proc->s_inp_buf.s_raw_buf.au4_strd[0] * (i4_mb_y * MB_SIZE) - + ps_proc->s_inp_buf.s_raw_buf.au4_strd[0]; + UWORD8 *pu1_dst = ps_proc->pu1_src_buf_luma - ps_proc->i4_src_strd; + memcpy(pu1_dst, pu1_src, ps_codec->s_cfg.u4_wd); + if (u4_pad_right_sz && (ps_proc->i4_mb_x == 0)) { + pu1_dst += ps_codec->s_cfg.u4_disp_wd; + memset(pu1_dst, pu1_dst[-1], u4_pad_right_sz); + } + } + /* pad bottom edge */ if (u4_pad_bottom_sz && (ps_proc->i4_mb_y == ps_proc->i4_ht_mbs - 1) && ps_proc->i4_mb_x == 0) { diff --git a/encoder/ih264e_utils.c b/encoder/ih264e_utils.c index 2196a64..239271e 100644 --- a/encoder/ih264e_utils.c +++ b/encoder/ih264e_utils.c @@ -445,11 +445,6 @@ WORD32 ih264e_input_queue_update(codec_t *ps_codec, } } - if (ps_enc_buff->u4_is_last) - { - ps_codec->pic_type = PIC_NA; - } - /* The buffer in the queue is set to NULL to specify that encoding is done for that frame */ for(i = 0; i < 3; i++) { diff --git a/fuzzer/Android.bp b/fuzzer/Android.bp index 8540107..4c83461 100644 --- a/fuzzer/Android.bp +++ b/fuzzer/Android.bp @@ -1,3 +1,12 @@ +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "external_libavc_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["external_libavc_license"], +} + cc_fuzz { name: "avc_dec_fuzzer", host_supported: true, @@ -13,4 +22,32 @@ cc_fuzz { enabled: false, }, }, + fuzz_config: { + cc: [ + "android-media-fuzzing-reports@google.com", + ], + componentid: 155276, + }, +} + +cc_fuzz { + name: "avc_enc_fuzzer", + host_supported: true, + srcs: [ + "avc_enc_fuzzer.cpp", + ], + static_libs: [ + "libavcenc", + "liblog", + ], + cflags: [ + "-Wall", + "-Werror", + ], + fuzz_config: { + cc: [ + "android-media-fuzzing-reports@google.com", + ], + componentid: 155276, + }, } diff --git a/fuzzer/README.md b/fuzzer/README.md index a42e8b5..8e29ec6 100644 --- a/fuzzer/README.md +++ b/fuzzer/README.md @@ -64,6 +64,138 @@ To run on host $ $ANDROID_HOST_OUT/fuzz/avc_dec_fuzzer CORPUS_DIR ``` + +# Fuzzer for libavc encoder + +## Plugin Design Considerations +The fuzzer plugin for AVC is designed based on the understanding of the +codec and tries to achieve the following: + +##### Maximize code coverage +The configuration parameters are not hardcoded, but instead selected based on +incoming data. This ensures more code paths are reached by the fuzzer. + +AVC supports the following parameters: +1. Frame Width (parameter name: `u4_wd`) +2. Frame Height (parameter name: `u4_ht`) +3. Input color format (parameter name: `e_inp_color_fmt`) +4. Architecture type (parameter name: `e_arch`) +5. Rate control mode (parameter name: `e_rc_mode`) +6. Number of cores (parameter name: `u4_num_cores`) +7. Maximum B frames (parameter name: `u4_num_bframes`) +8. Encoder speed preset (parameter name: `u4_enc_speed_preset`) +9. enable constrained intra prediction (parameter name: `u4_constrained_intra_pred`) +10. enable intra 4x4 (parameter name: `u4_enable_intra_4x4`) +11. Qp for I frames (parameter name: `u4_i_qp`) +12. Qp for P frames (parameter name: `u4_p_qp`) +13. Qp for B frames (parameter name: `u4_b_qp`) +14. Target Bitrate (parameter name: `u4_target_bitrate`) +15. Intra refresh period in frames (parameter name: `u4_air_refresh_period`) +16. Enable half pel ME (parameter name: `u4_enable_hpel`) +17. Enable quarter pel ME (parameter name: `u4_enable_qpel`) +18. ME speed preset (parameter name: `u4_me_speed_preset`) +19. Adaptive intra refresh mode (parameter name: `e_air_mode`) +20. Disable deblock level (parameter name: `u4_disable_deblock_level`) +21. Max search range in X direction (parameter name: `u4_srch_rng_x`) +22. Max search range in Y direction (parameter name: `u4_srch_rng_y`) +23. I frame interval (parameter name: `u4_i_frm_interval`) +24. IDR frame interval (parameter name: `u4_idr_frm_interval`) +25. Enable mastering display color volume info (parameter name: `u1_sei_mdcv_params_present_flag`) +26. Enable content light level info (parameter name: `u1_sei_cll_params_present_flag`) +27. Enable ambient viewing environment info (parameter name: `u1_sei_ave_params_present_flag`) +28. Enable content color volume info (parameter name: `u1_sei_ccv_params_present_flag`) +29. Profile (parameter name: `e_profile`) +30. Enable aspect_ratio info (parameter name: `u1_aspect_ratio_info_present_flag`) +31. Enable NAL HRD parameters presence (parameter name: `u1_nal_hrd_parameters_present_flag`) +32. Enable VCL HRD parameters presence (parameter name: `u1_vcl_hrd_parameters_present_flag`) +33. Enable force IDR frame (parameter name: `mIsForceIdrEnabled`) +34. Enable dynamic bitrate change (parameter name: `mIsDynamicBitRateChangeEnabled`) +35. Enable dynamic framerate change (parameter name: `mIsDynamicFrameRateChangeEnabled`) +36. Force IDR frame number (parameter name: `mForceIdrInterval`) +37. Frame number for dynamic bitrate (parameter name: `mDynamicBitRateInterval`) +38. Frame number for dynamic framerate (parameter name: `mDynamicFrameRateInterval`) + +| Parameter| Valid Values| Configured Value| +|------------- |-------------| ----- | +| `u4_wd` | In the range `0 to 10239` | All the bits of 1st and 2nd byte of data | +| `u4_ht` | In the range `0 to 10239` | All the bits of 3rd and 4th byte of data | +| `e_inp_color_fmt` | 0. `IV_YUV_420P` 1. `IV_YUV_420SP_UV` 2. `IV_YUV_422ILE` 3. `IV_YUV_420SP_VU` | All the bits of 5th byte of data | +| `e_arch` | 0. `ARCH_ARM_NONEON` 1. `ARCH_NA` | bit 0 and 1 of 6th byte of data | +| `e_rc_mode` | 0. `IVE_RC_NONE` 1. `IVE_RC_STORAGE` 2. `IVE_RC_CBR_NON_LOW_DELAY` 3. `IVE_RC_CBR_LOW_DELAY` | All the bits of 7th byte of data modulus 4 | +| `u4_num_cores` | 0. `0` 1. `1` 2. `2` 3. `3`| bit 0 and 1 of 8th byte of data | +| `u4_num_bframes` | In the range `0 to 7` | bit 0, 1 and 2 of 9th byte of data | +| `u4_enc_speed_preset` | 0. `IVE_CONFIG` 1. `IVE_SLOWEST` 2. `IVE_NORMAL` 3. `IVE_FAST` 4. `IVE_HIGH_SPEED` 5. `IVE_FASTEST` | All the bits of 10th byte of data modulus 6 | +| `u4_constrained_intra_pred` | 0. `0` 1. `1` | bit 0 of 11th byte of data | +| `u4_enable_intra_4x4` | 0. `0` 1. `1` | bit 0 of 12th byte of data | +| `u4_i_qp` | In the range `4 to 51` | All the bits of 13th byte of data | +| `u4_p_qp` | In the range `4 to 51` | All the bits of 14th byte of data | +| `u4_b_qp` | In the range `4 to 51` | All the bits of 15th byte of data | +| `u4_target_bitrate` | In the range `0 to 500000000` | All the bits of 16th and 17th byte of data | +| `u4_target_bitrate` | In the range `0 to 255` | All the bits of 18th byte of data | +| `u4_air_refresh_period` | In the range `1 to 256` | All the bits of 19th byte of data | +| `u4_air_refresh_period` | In the range `1 to 256` | All the bits of 19th byte of data | +| `u4_enable_hpel` | 0. `0` 1. `1` | bit 0 of 20th byte of data | +| `u4_enable_qpel` | 0. `0` 1. `1` | bit 0 of 21st byte of data | +| `u4_me_speed_preset` | 0. `0` 1. `50` 2. `75` 3. `100` | All the bits of 22nd byte of data modulus 4 | +| `e_air_mode` | 0. `IVE_AIR_MODE_NONE` 1. `IVE_AIR_MODE_CYCLIC` 2. `IVE_AIR_MODE_RANDOM` | All the bits of 23rd byte of data modulus 3 | +| `u4_disable_deblock_level` | 0. `0` 1. `1` 2. `2` 3. `3` | bit 0 and 1 of 24th byte of data | +| `u4_srch_rng_x` | In the range `0 to 255` | All the bits of 25th byte of data | +| `u4_srch_rng_y` | In the range `0 to 255`| All the bits of 26th byte of data | +| `u4_i_frm_interval` | In the range `1 to 256` | All the bits of 27th byte of data | +| `u4_idr_frm_interval` | In the range `1 to 256` | All the bits of 28th byte of data | +| `u1_sei_mdcv_params_present_flag` | 0. `0` 1. `1` | bit 0 of 29th byte of data | +| `u1_sei_cll_params_present_flag` | 0. `0` 1. `1` | bit 0 of 30th byte of data | +| `u1_sei_ave_params_present_flag` | 0. `0` 1. `1` | bit 0 of 31st byte of data | +| `u1_sei_ccv_params_present_flag` | 0. `0` 1. `1` | bit 0 of 32nd byte of data | +| `e_profile` | 0. `IV_PROFILE_BASE` 1. `IV_PROFILE_MAIN` | bit 0 and 1 of 33th byte of data modulus 2 | +| `u1_aspect_ratio_info_present_flag` | 0. `0` 1. `1` | bit 0 of 34th byte of data | +| `u1_nal_hrd_parameters_present_flag` | 0. `0` 1. `1` | bit 0 of 35th byte of data | +| `u1_vcl_hrd_parameters_present_flag` | 0. `0` 1. `1` | bit 0 of 36th byte of data | +| `mIsForceIdrEnabled` | 0. `0` 1. `1` | bit 0 of 37th byte of data | +| `mIsDynamicBitRateChangeEnabled` | 0. `0` 1. `1` | bit 0 of 38th byte of data | +| `mIsDynamicFrameRateChangeEnabled` | 0. `0` 1. `1` | bit 0 of 39th byte of data | +| `mForceIdrInterval` | In the range `0 to 7` | bit 0, 1 and 2 of 40th byte of data | +| `mDynamicBitRateInterval` | In the range `0 to 7` | bit 0, 1 and 2 of 41st byte of data | +| `mDynamicFrameRateInterval` | In the range `0 to 7` | bit 0, 1 and 2 of 42nd byte of data | + +This also ensures that the plugin is always deterministic for any given input. + +##### Maximize utilization of input data +The plugin feeds the entire input data to the codec using a loop. +If the encode operation was successful, the input is advanced by the frame size. +If the encode operation was un-successful, the input is still advanced by frame size so +that the fuzzer can proceed to feed the next frame. + +This ensures that the plugin tolerates any kind of input (empty, huge, +malformed, etc) and doesnt `exit()` on any input and thereby increasing the +chance of identifying vulnerabilities. + +## Build + +This describes steps to build avc_enc_fuzzer binary. + +### Android + +#### Steps to build +Build the fuzzer +``` + $ mm -j$(nproc) avc_enc_fuzzer +``` + +#### Steps to run +Create a directory CORPUS_DIR and copy some yuv files to that folder +Push this directory to device. + +To run on device +``` + $ adb sync data + $ adb shell /data/fuzz/arm64/avc_enc_fuzzer/avc_enc_fuzzer CORPUS_DIR +``` +To run on host +``` + $ $ANDROID_HOST_OUT/fuzz/x86_64/avc_enc_fuzzer/avc_enc_fuzzer CORPUS_DIR +``` + ## References: * http://llvm.org/docs/LibFuzzer.html * https://github.com/google/oss-fuzz diff --git a/fuzzer/avc_enc_fuzzer.cpp b/fuzzer/avc_enc_fuzzer.cpp new file mode 100644 index 0000000..426eedb --- /dev/null +++ b/fuzzer/avc_enc_fuzzer.cpp @@ -0,0 +1,1059 @@ +/****************************************************************************** + * + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ +#include <malloc.h> +#include <algorithm> +#include <vector> + +#include "ih264_defs.h" +#include "ih264_typedefs.h" +#include "ih264e.h" +#include "ih264e_error.h" +#define ive_api_function ih264e_api_function +typedef std::tuple<uint8_t *, uint8_t *, uint8_t *> bufferPtrs; + +constexpr static int kMaxNumEncodeCalls = 100; +constexpr uint32_t kHeaderLength = 0x800; +constexpr int16_t kCompressionRatio = 1; + +constexpr int kMeSpeedPreset[] = {0, 50, 75, 100}; +constexpr IVE_AIR_MODE_T kAirMode[] = {IVE_AIR_MODE_NONE, IVE_AIR_MODE_CYCLIC, IVE_AIR_MODE_RANDOM}; +constexpr IVE_SPEED_CONFIG kEncSpeed[] = {IVE_CONFIG, IVE_SLOWEST, IVE_NORMAL, + IVE_FAST, IVE_HIGH_SPEED, IVE_FASTEST}; +constexpr IV_PROFILE_T kProfle[] = {IV_PROFILE_BASE, IV_PROFILE_MAIN}; +constexpr IVE_RC_MODE_T kRCMode[] = {IVE_RC_NONE, IVE_RC_STORAGE, IVE_RC_CBR_NON_LOW_DELAY, + IVE_RC_CBR_LOW_DELAY}; +constexpr IV_COLOR_FORMAT_T kSupportedColorFormats[] = {IV_YUV_420P, IV_YUV_420SP_UV, IV_YUV_422ILE, + IV_YUV_420SP_VU}; + +constexpr size_t kAirModeNum = std::size(kAirMode); +constexpr size_t kEncSpeedNum = std::size(kEncSpeed); +constexpr size_t kMeSpeedPresetNum = std::size(kMeSpeedPreset); +constexpr size_t kProfleNum = std::size(kProfle); +constexpr size_t kRCModeNum = std::size(kRCMode); +constexpr size_t kSupportedColorFormatsNum = std::size(kSupportedColorFormats); +constexpr size_t kMinQP = 4; +constexpr size_t kMaxWidth = 10240; +constexpr size_t kMaxHeight = 10240; +constexpr size_t kMaxBitrate = 500000000; + +enum { + IDX_WD_BYTE_1, + IDX_WD_BYTE_2, + IDX_HT_BYTE_1, + IDX_HT_BYTE_2, + IDX_COLOR_FORMAT, + IDX_ARCH_TYPE, + IDX_RC_MODE, + IDX_NUM_CORES, + IDX_NUM_B_FRAMES, + IDX_ENC_SPEED, + IDX_CONSTRAINED_INTRA_FLAG, + IDX_INTRA_4x4, + IDX_I_FRAME_QP, + IDX_P_FRAME_QP, + IDX_B_FRAME_QP, + IDX_BITRATE_BYTE_1, + IDX_BITRATE_BYTE_2, + IDX_FRAME_RATE, + IDX_INTRA_REFRESH, + IDX_ENABLE_HALF_PEL, + IDX_ENABLE_Q_PEL, + IDX_ME_SPEED_PRESET, + IDX_AIR_MODE, + IDX_DISABLE_DEBLOCK_LEVEL, + IDX_SEARCH_RANGE_X, + IDX_SEARCH_RANGE_Y, + IDX_I_INTERVAL, + IDX_IDR_INTERVAL, + IDX_SEI_MDCV_FLAG, + IDX_SEI_CLL_FLAG, + IDX_SEI_AVE_FLAG, + IDX_SEI_CCV_FLAG, + IDX_PROFILE, + IDX_ASPECT_RATIO_FLAG, + IDX_NAL_HRD_FLAG, + IDX_VCL_HRD_FLAG, + IDX_ENABLE_FORCE_IDR, + IDX_ENABLE_DYNAMIC_BITRATE, + IDX_ENABLE_DYNAMIC_FRAME_RATE, + IDX_FORCE_IDR_INTERVAL, + IDX_DYNAMIC_BITRATE_INTERVAL, + IDX_DYNAMIC_FRAME_RATE_INTERVAL, + IDX_SEND_EOS_WITH_LAST_FRAME, + IDX_LAST +}; + +class Codec { + public: + Codec() = default; + ~Codec() { deInitEncoder(); } + bool initEncoder(const uint8_t **pdata, size_t *psize); + void encodeFrames(const uint8_t *data, size_t size); + void deInitEncoder(); + + private: + bufferPtrs setEncParams(iv_raw_buf_t *psInpRawBuf, const uint8_t *data, size_t frameSize); + void setFrameType(IV_PICTURE_CODING_TYPE_T eFrameType); + void setQp(); + void setEncMode(IVE_ENC_MODE_T eEncMode); + void setDimensions(); + void setNumCores(); + void setFrameRate(); + void setIpeParams(); + void setBitRate(); + void setAirParams(); + void setMeParams(); + void setGopParams(); + void setProfileParams(); + void setDeblockParams(); + void setVbvParams(); + void setDefault(); + void setVuiParams(); + void getBufInfo(); + void setSeiMdcvParams(); + void setSeiCllParams(); + void setSeiAveParams(); + void setSeiCcvParams(); + void logVersion(); + bool mHalfPelEnable = 1; + bool mQPelEnable = 1; + bool mIntra4x4 = 0; + bool mEnableFastSad = 0; + bool mEnableAltRef = 0; + bool mConstrainedIntraFlag = 0; + bool mSeiCllFlag = 1; + bool mSeiAveFlag = 1; + bool mSeiCcvFlag = 1; + bool mSeiMdcvFlag = 1; + bool mAspectRatioFlag = 0; + bool mNalHrdFlag = 0; + bool mVclHrdFlag = 0; + bool mIsForceIdrEnabled = false; + bool mIsDynamicBitRateChangeEnabled = false; + bool mIsDynamicFrameRateChangeEnabled = false; + bool mSendEosWithLastFrame = false; + uint32_t mWidth = 2560; + uint32_t mHeight = 2560; + uint32_t mAvcEncLevel = 41; + uint32_t mNumMemRecords = 0; + uint32_t mNumCores = 1; + uint32_t mBframes = 0; + uint32_t mSliceParam = 256; + uint32_t mMeSpeedPreset = 100; + uint32_t mIInterval = 60; + uint32_t mIDRInterval = 60; + uint32_t mDisableDeblockLevel = 0; + uint32_t m_I_QP = 22; + uint32_t m_P_QP = 28; + uint32_t m_B_QP = 22; + uint32_t mIntraRefresh = 30; + uint32_t mSearchRangeX = 64; + uint32_t mSearchRangeY = 48; + uint32_t mForceIdrInterval = 0; // in number of frames + uint32_t mDynamicBitRateInterval = 0; // in number of frames + uint32_t mDynamicFrameRateInterval = 0; // in number of frames + uint64_t mBitrate = 6000000; + float mFrameRate = 30; + iv_obj_t *mCodecCtx = nullptr; + iv_mem_rec_t *mMemRecords = nullptr; + IVE_AIR_MODE_T mAirMode = IVE_AIR_MODE_NONE; + IVE_SPEED_CONFIG mEncSpeed = IVE_NORMAL; + IVE_RC_MODE_T mRCMode = IVE_RC_STORAGE; + IV_ARCH_T mArch = ARCH_NA; + IVE_SLICE_MODE_T mSliceMode = IVE_SLICE_MODE_NONE; + IV_COLOR_FORMAT_T mIvVideoColorFormat = IV_YUV_420P; + IV_COLOR_FORMAT_T mReconFormat = IV_YUV_420P; + IV_PROFILE_T mProfile = IV_PROFILE_BASE; +}; + +bool Codec::initEncoder(const uint8_t **pdata, size_t *psize) { + uint8_t *data = const_cast<uint8_t *>(*pdata); + mWidth = ((data[IDX_WD_BYTE_1] << 8) | data[IDX_WD_BYTE_2]) % kMaxWidth; + mHeight = ((data[IDX_HT_BYTE_1] << 8) | data[IDX_HT_BYTE_2]) % kMaxHeight; + + mIvVideoColorFormat = + kSupportedColorFormats[data[IDX_COLOR_FORMAT] % kSupportedColorFormatsNum]; + mArch = ((data[IDX_ARCH_TYPE] & 0x03) == 0x00) ? ARCH_ARM_NONEON : ARCH_NA; + mRCMode = kRCMode[data[IDX_RC_MODE] % kRCModeNum]; + mNumCores = (data[IDX_NUM_CORES] & 0x07) + 1; + mBframes = data[IDX_NUM_B_FRAMES] & 0x07; + mEncSpeed = kEncSpeed[data[IDX_ENC_SPEED] % kEncSpeedNum]; + mConstrainedIntraFlag = data[IDX_CONSTRAINED_INTRA_FLAG] & 0x01; + mIntra4x4 = data[IDX_INTRA_4x4] & 0x01; + m_I_QP = (data[IDX_I_FRAME_QP] % (MAX_H264_QP - kMinQP)) + kMinQP; + m_P_QP = (data[IDX_P_FRAME_QP] % (MAX_H264_QP - kMinQP)) + kMinQP; + m_B_QP = (data[IDX_B_FRAME_QP] % (MAX_H264_QP - kMinQP)) + kMinQP; + mBitrate = (((data[IDX_BITRATE_BYTE_1] << 8) | data[IDX_BITRATE_BYTE_2]) * 1000) % kMaxBitrate; + mFrameRate = data[IDX_FRAME_RATE]; + mIntraRefresh = data[IDX_INTRA_REFRESH] + 1; + mHalfPelEnable = data[IDX_ENABLE_HALF_PEL] & 0x01; + mQPelEnable = data[IDX_ENABLE_Q_PEL] & 0x01; + mMeSpeedPreset = kMeSpeedPreset[data[IDX_ME_SPEED_PRESET] % kMeSpeedPresetNum]; + mAirMode = kAirMode[data[IDX_AIR_MODE] % kAirModeNum]; + mDisableDeblockLevel = data[IDX_DISABLE_DEBLOCK_LEVEL] & 0x03; + mSearchRangeX = data[IDX_SEARCH_RANGE_X]; + mSearchRangeY = data[IDX_SEARCH_RANGE_Y]; + mIInterval = data[IDX_I_INTERVAL] + 1; + mIDRInterval = data[IDX_IDR_INTERVAL] + 1; + mSeiMdcvFlag = data[IDX_SEI_MDCV_FLAG] & 0x01; + mSeiCllFlag = data[IDX_SEI_CLL_FLAG] & 0x01; + mSeiAveFlag = data[IDX_SEI_AVE_FLAG] & 0x01; + mSeiCcvFlag = data[IDX_SEI_CCV_FLAG] & 0x01; + mProfile = kProfle[data[IDX_PROFILE] % kProfleNum]; + mAspectRatioFlag = data[IDX_ASPECT_RATIO_FLAG] & 0x01; + mNalHrdFlag = data[IDX_NAL_HRD_FLAG] & 0x01; + mVclHrdFlag = data[IDX_VCL_HRD_FLAG] & 0x01; + mIsForceIdrEnabled = data[IDX_ENABLE_FORCE_IDR] & 0x01; + mIsDynamicBitRateChangeEnabled = data[IDX_ENABLE_DYNAMIC_BITRATE] & 0x01; + mIsDynamicFrameRateChangeEnabled = data[IDX_ENABLE_DYNAMIC_FRAME_RATE] & 0x01; + mSendEosWithLastFrame = data[IDX_SEND_EOS_WITH_LAST_FRAME] & 0x01; + mForceIdrInterval = data[IDX_FORCE_IDR_INTERVAL] & 0x07; + mDynamicBitRateInterval = data[IDX_DYNAMIC_BITRATE_INTERVAL] & 0x07; + mDynamicFrameRateInterval = data[IDX_DYNAMIC_FRAME_RATE_INTERVAL] & 0x07; + + /* Getting Number of MemRecords */ + iv_num_mem_rec_ip_t sNumMemRecIp{}; + iv_num_mem_rec_op_t sNumMemRecOp{}; + + sNumMemRecIp.u4_size = sizeof(iv_num_mem_rec_ip_t); + sNumMemRecOp.u4_size = sizeof(iv_num_mem_rec_op_t); + sNumMemRecIp.e_cmd = IV_CMD_GET_NUM_MEM_REC; + + if (IV_SUCCESS != ive_api_function(nullptr, &sNumMemRecIp, &sNumMemRecOp)) { + return false; + } + mNumMemRecords = sNumMemRecOp.u4_num_mem_rec; + mMemRecords = (iv_mem_rec_t *)malloc(mNumMemRecords * sizeof(iv_mem_rec_t)); + if (!mMemRecords) { + return false; + } + iv_mem_rec_t *psMemRec; + psMemRec = mMemRecords; + for (size_t i = 0; i < mNumMemRecords; ++i) { + psMemRec->u4_size = sizeof(iv_mem_rec_t); + psMemRec->pv_base = nullptr; + psMemRec->u4_mem_size = 0; + psMemRec->u4_mem_alignment = 0; + psMemRec->e_mem_type = IV_NA_MEM_TYPE; + ++psMemRec; + } + + /* Getting MemRecords Attributes */ + iv_fill_mem_rec_ip_t sFillMemRecIp{}; + iv_fill_mem_rec_op_t sFillMemRecOp{}; + + sFillMemRecIp.u4_size = sizeof(iv_fill_mem_rec_ip_t); + sFillMemRecOp.u4_size = sizeof(iv_fill_mem_rec_op_t); + + sFillMemRecIp.e_cmd = IV_CMD_FILL_NUM_MEM_REC; + sFillMemRecIp.ps_mem_rec = mMemRecords; + sFillMemRecIp.u4_num_mem_rec = mNumMemRecords; + sFillMemRecIp.u4_max_wd = mWidth; + sFillMemRecIp.u4_max_ht = mHeight; + sFillMemRecIp.u4_max_level = mAvcEncLevel; + sFillMemRecIp.e_color_format = IV_YUV_420SP_VU; + sFillMemRecIp.u4_max_ref_cnt = 2; + sFillMemRecIp.u4_max_reorder_cnt = 0; + sFillMemRecIp.u4_max_srch_rng_x = 256; + sFillMemRecIp.u4_max_srch_rng_y = 256; + + if (IV_SUCCESS != ive_api_function(nullptr, &sFillMemRecIp, &sFillMemRecOp)) { + return false; + } + /* Allocating Memory for Mem Records */ + psMemRec = mMemRecords; + for (size_t i = 0; i < mNumMemRecords; ++i) { + posix_memalign(&psMemRec->pv_base, psMemRec->u4_mem_alignment, psMemRec->u4_mem_size); + if (!psMemRec->pv_base) { + return false; + } + ++psMemRec; + } + + /* Codec Instance Creation */ + ive_init_ip_t sInitIp{}; + ive_init_op_t sInitOp{}; + + mCodecCtx = (iv_obj_t *)mMemRecords[0].pv_base; + mCodecCtx->u4_size = sizeof(iv_obj_t); + mCodecCtx->pv_fxns = (void *)ive_api_function; + + sInitIp.u4_size = sizeof(ive_init_ip_t); + sInitOp.u4_size = sizeof(ive_init_op_t); + + sInitIp.e_cmd = IV_CMD_INIT; + sInitIp.u4_num_mem_rec = mNumMemRecords; + sInitIp.ps_mem_rec = mMemRecords; + sInitIp.u4_max_wd = mWidth; + sInitIp.u4_max_ht = mHeight; + sInitIp.u4_max_ref_cnt = 2; + sInitIp.u4_max_reorder_cnt = 0; + sInitIp.u4_max_level = mAvcEncLevel; + sInitIp.e_inp_color_fmt = mIvVideoColorFormat; + sInitIp.u4_enable_recon = 0; + sInitIp.e_recon_color_fmt = mReconFormat; + sInitIp.e_rc_mode = mRCMode; + sInitIp.u4_max_framerate = 120000; + sInitIp.u4_max_bitrate = 240000000; + sInitIp.u4_num_bframes = mBframes; + sInitIp.e_content_type = IV_PROGRESSIVE; + sInitIp.u4_max_srch_rng_x = 256; + sInitIp.u4_max_srch_rng_y = 256; + sInitIp.e_slice_mode = mSliceMode; + sInitIp.u4_slice_param = mSliceParam; + sInitIp.e_arch = mArch; + sInitIp.e_soc = SOC_GENERIC; + + if (IV_SUCCESS != ive_api_function(mCodecCtx, &sInitIp, &sInitOp)) { + return false; + } + + logVersion(); + setDefault(); + getBufInfo(); + setNumCores(); + setDimensions(); + setFrameRate(); + setIpeParams(); + setBitRate(); + setQp(); + setAirParams(); + setVbvParams(); + setMeParams(); + setGopParams(); + setDeblockParams(); + setVuiParams(); + setSeiMdcvParams(); + setSeiCllParams(); + setSeiAveParams(); + setSeiCcvParams(); + setProfileParams(); + setEncMode(IVE_ENC_MODE_HEADER); + + *pdata += IDX_LAST; + *psize -= IDX_LAST; + return true; +} + +void Codec::setDimensions() { + ive_ctl_set_dimensions_ip_t sDimensionsIp{}; + ive_ctl_set_dimensions_op_t sDimensionsOp{}; + + sDimensionsIp.e_cmd = IVE_CMD_VIDEO_CTL; + sDimensionsIp.e_sub_cmd = IVE_CMD_CTL_SET_DIMENSIONS; + sDimensionsIp.u4_ht = mHeight; + sDimensionsIp.u4_wd = mWidth; + + sDimensionsIp.u4_timestamp_high = -1; + sDimensionsIp.u4_timestamp_low = -1; + + sDimensionsIp.u4_size = sizeof(ive_ctl_set_dimensions_ip_t); + sDimensionsOp.u4_size = sizeof(ive_ctl_set_dimensions_op_t); + + ive_api_function(mCodecCtx, &sDimensionsIp, &sDimensionsOp); + return; +} + +void Codec::setNumCores() { + ive_ctl_set_num_cores_ip_t sNumCoresIp{}; + ive_ctl_set_num_cores_op_t sNumCoresOp{}; + + sNumCoresIp.e_cmd = IVE_CMD_VIDEO_CTL; + sNumCoresIp.e_sub_cmd = IVE_CMD_CTL_SET_NUM_CORES; + sNumCoresIp.u4_num_cores = mNumCores; + + sNumCoresIp.u4_timestamp_high = -1; + sNumCoresIp.u4_timestamp_low = -1; + + sNumCoresIp.u4_size = sizeof(ive_ctl_set_num_cores_ip_t); + sNumCoresOp.u4_size = sizeof(ive_ctl_set_num_cores_op_t); + + ive_api_function(mCodecCtx, (void *)&sNumCoresIp, (void *)&sNumCoresOp); + return; +} + +void Codec::setDefault() { + ive_ctl_setdefault_ip_t sDefaultIp{}; + ive_ctl_setdefault_op_t sDefaultOp{}; + + sDefaultIp.e_cmd = IVE_CMD_VIDEO_CTL; + sDefaultIp.e_sub_cmd = IVE_CMD_CTL_SETDEFAULT; + + sDefaultIp.u4_timestamp_high = -1; + sDefaultIp.u4_timestamp_low = -1; + + sDefaultIp.u4_size = sizeof(ive_ctl_setdefault_ip_t); + sDefaultOp.u4_size = sizeof(ive_ctl_setdefault_op_t); + + ive_api_function(mCodecCtx, &sDefaultIp, &sDefaultOp); + return; +} + +void Codec::getBufInfo() { + ih264e_ctl_getbufinfo_ip_t sGetBufInfoIp{}; + ih264e_ctl_getbufinfo_op_t sGetBufInfoOp{}; + + sGetBufInfoIp.s_ive_ip.u4_size = sizeof(ih264e_ctl_getbufinfo_ip_t); + sGetBufInfoOp.s_ive_op.u4_size = sizeof(ih264e_ctl_getbufinfo_op_t); + + sGetBufInfoIp.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; + sGetBufInfoIp.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_GETBUFINFO; + sGetBufInfoIp.s_ive_ip.u4_max_ht = mHeight; + sGetBufInfoIp.s_ive_ip.u4_max_wd = mWidth; + sGetBufInfoIp.s_ive_ip.e_inp_color_fmt = mIvVideoColorFormat; + + ih264e_api_function(mCodecCtx, &sGetBufInfoIp, &sGetBufInfoOp); + return; +} + +void Codec::setFrameRate() { + ive_ctl_set_frame_rate_ip_t sFrameRateIp{}; + ive_ctl_set_frame_rate_op_t sFrameRateOp{}; + + sFrameRateIp.e_cmd = IVE_CMD_VIDEO_CTL; + sFrameRateIp.e_sub_cmd = IVE_CMD_CTL_SET_FRAMERATE; + sFrameRateIp.u4_src_frame_rate = mFrameRate; + sFrameRateIp.u4_tgt_frame_rate = mFrameRate; + + sFrameRateIp.u4_timestamp_high = -1; + sFrameRateIp.u4_timestamp_low = -1; + + sFrameRateIp.u4_size = sizeof(ive_ctl_set_frame_rate_ip_t); + sFrameRateOp.u4_size = sizeof(ive_ctl_set_frame_rate_op_t); + + ive_api_function(mCodecCtx, &sFrameRateIp, &sFrameRateOp); + return; +} + +void Codec::setIpeParams() { + ive_ctl_set_ipe_params_ip_t sIpeParamsIp{}; + ive_ctl_set_ipe_params_op_t sIpeParamsOp{}; + + sIpeParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; + sIpeParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_IPE_PARAMS; + sIpeParamsIp.u4_enable_intra_4x4 = mIntra4x4; + sIpeParamsIp.u4_enc_speed_preset = mEncSpeed; + sIpeParamsIp.u4_constrained_intra_pred = mConstrainedIntraFlag; + + sIpeParamsIp.u4_timestamp_high = -1; + sIpeParamsIp.u4_timestamp_low = -1; + + sIpeParamsIp.u4_size = sizeof(ive_ctl_set_ipe_params_ip_t); + sIpeParamsOp.u4_size = sizeof(ive_ctl_set_ipe_params_op_t); + + ive_api_function(mCodecCtx, &sIpeParamsIp, &sIpeParamsOp); + return; +} + +void Codec::setBitRate() { + ive_ctl_set_bitrate_ip_t sBitrateIp{}; + ive_ctl_set_bitrate_op_t sBitrateOp{}; + + sBitrateIp.e_cmd = IVE_CMD_VIDEO_CTL; + sBitrateIp.e_sub_cmd = IVE_CMD_CTL_SET_BITRATE; + sBitrateIp.u4_target_bitrate = mBitrate; + + sBitrateIp.u4_timestamp_high = -1; + sBitrateIp.u4_timestamp_low = -1; + + sBitrateIp.u4_size = sizeof(ive_ctl_set_bitrate_ip_t); + sBitrateOp.u4_size = sizeof(ive_ctl_set_bitrate_op_t); + + ive_api_function(mCodecCtx, &sBitrateIp, &sBitrateOp); + return; +} + +void Codec::setFrameType(IV_PICTURE_CODING_TYPE_T eFrameType) { + ive_ctl_set_frame_type_ip_t sFrameTypeIp{}; + ive_ctl_set_frame_type_op_t sFrameTypeOp{}; + + sFrameTypeIp.e_cmd = IVE_CMD_VIDEO_CTL; + sFrameTypeIp.e_sub_cmd = IVE_CMD_CTL_SET_FRAMETYPE; + sFrameTypeIp.e_frame_type = eFrameType; + + sFrameTypeIp.u4_timestamp_high = -1; + sFrameTypeIp.u4_timestamp_low = -1; + + sFrameTypeIp.u4_size = sizeof(ive_ctl_set_frame_type_ip_t); + sFrameTypeOp.u4_size = sizeof(ive_ctl_set_frame_type_op_t); + + ive_api_function(mCodecCtx, &sFrameTypeIp, &sFrameTypeOp); + return; +} + +void Codec::setQp() { + ive_ctl_set_qp_ip_t s_QpIp{}; + ive_ctl_set_qp_op_t s_QpOp{}; + + s_QpIp.e_cmd = IVE_CMD_VIDEO_CTL; + s_QpIp.e_sub_cmd = IVE_CMD_CTL_SET_QP; + + s_QpIp.u4_i_qp = m_I_QP; + s_QpIp.u4_i_qp_max = MAX_H264_QP; + s_QpIp.u4_i_qp_min = kMinQP; + + s_QpIp.u4_p_qp = m_P_QP; + s_QpIp.u4_p_qp_max = MAX_H264_QP; + s_QpIp.u4_p_qp_min = kMinQP; + + s_QpIp.u4_b_qp = m_B_QP; + s_QpIp.u4_b_qp_max = MAX_H264_QP; + s_QpIp.u4_b_qp_min = kMinQP; + + s_QpIp.u4_timestamp_high = -1; + s_QpIp.u4_timestamp_low = -1; + + s_QpIp.u4_size = sizeof(ive_ctl_set_qp_ip_t); + s_QpOp.u4_size = sizeof(ive_ctl_set_qp_op_t); + + ive_api_function(mCodecCtx, &s_QpIp, &s_QpOp); + return; +} + +void Codec::setEncMode(IVE_ENC_MODE_T eEncMode) { + ive_ctl_set_enc_mode_ip_t sEncModeIp{}; + ive_ctl_set_enc_mode_op_t sEncModeOp{}; + + sEncModeIp.e_cmd = IVE_CMD_VIDEO_CTL; + sEncModeIp.e_sub_cmd = IVE_CMD_CTL_SET_ENC_MODE; + sEncModeIp.e_enc_mode = eEncMode; + + sEncModeIp.u4_timestamp_high = -1; + sEncModeIp.u4_timestamp_low = -1; + + sEncModeIp.u4_size = sizeof(ive_ctl_set_enc_mode_ip_t); + sEncModeOp.u4_size = sizeof(ive_ctl_set_enc_mode_op_t); + + ive_api_function(mCodecCtx, &sEncModeIp, &sEncModeOp); + return; +} + +void Codec::setVbvParams() { + ive_ctl_set_vbv_params_ip_t sVbvIp{}; + ive_ctl_set_vbv_params_op_t sVbvOp{}; + + sVbvIp.e_cmd = IVE_CMD_VIDEO_CTL; + sVbvIp.e_sub_cmd = IVE_CMD_CTL_SET_VBV_PARAMS; + sVbvIp.u4_vbv_buf_size = 0; + sVbvIp.u4_vbv_buffer_delay = 1000; + + sVbvIp.u4_timestamp_high = -1; + sVbvIp.u4_timestamp_low = -1; + + sVbvIp.u4_size = sizeof(ive_ctl_set_vbv_params_ip_t); + sVbvOp.u4_size = sizeof(ive_ctl_set_vbv_params_op_t); + + ive_api_function(mCodecCtx, &sVbvIp, &sVbvOp); + return; +} + +void Codec::setAirParams() { + ive_ctl_set_air_params_ip_t sAirIp{}; + ive_ctl_set_air_params_op_t sAirOp{}; + + sAirIp.e_cmd = IVE_CMD_VIDEO_CTL; + sAirIp.e_sub_cmd = IVE_CMD_CTL_SET_AIR_PARAMS; + sAirIp.e_air_mode = mAirMode; + sAirIp.u4_air_refresh_period = mIntraRefresh; + + sAirIp.u4_timestamp_high = -1; + sAirIp.u4_timestamp_low = -1; + + sAirIp.u4_size = sizeof(ive_ctl_set_air_params_ip_t); + sAirOp.u4_size = sizeof(ive_ctl_set_air_params_op_t); + + ive_api_function(mCodecCtx, &sAirIp, &sAirOp); + return; +} + +void Codec::setMeParams() { + ive_ctl_set_me_params_ip_t sMeParamsIp{}; + ive_ctl_set_me_params_op_t sMeParamsOp{}; + + sMeParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; + sMeParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_ME_PARAMS; + sMeParamsIp.u4_enable_fast_sad = mEnableFastSad; + sMeParamsIp.u4_enable_alt_ref = mEnableAltRef; + + sMeParamsIp.u4_enable_hpel = mHalfPelEnable; + sMeParamsIp.u4_enable_qpel = mQPelEnable; + sMeParamsIp.u4_me_speed_preset = mMeSpeedPreset; + sMeParamsIp.u4_srch_rng_x = mSearchRangeX; + sMeParamsIp.u4_srch_rng_y = mSearchRangeY; + + sMeParamsIp.u4_timestamp_high = -1; + sMeParamsIp.u4_timestamp_low = -1; + + sMeParamsIp.u4_size = sizeof(ive_ctl_set_me_params_ip_t); + sMeParamsOp.u4_size = sizeof(ive_ctl_set_me_params_op_t); + + ive_api_function(mCodecCtx, &sMeParamsIp, &sMeParamsOp); + return; +} + +void Codec::setGopParams() { + ive_ctl_set_gop_params_ip_t sGopParamsIp{}; + ive_ctl_set_gop_params_op_t sGopParamsOp{}; + + sGopParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; + sGopParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_GOP_PARAMS; + + sGopParamsIp.u4_i_frm_interval = mIInterval; + sGopParamsIp.u4_idr_frm_interval = mIDRInterval; + + sGopParamsIp.u4_timestamp_high = -1; + sGopParamsIp.u4_timestamp_low = -1; + + sGopParamsIp.u4_size = sizeof(ive_ctl_set_gop_params_ip_t); + sGopParamsOp.u4_size = sizeof(ive_ctl_set_gop_params_op_t); + + ive_api_function(mCodecCtx, &sGopParamsIp, &sGopParamsOp); + return; +} + +void Codec::setProfileParams() { + ive_ctl_set_profile_params_ip_t sProfileParamsIp{}; + ive_ctl_set_profile_params_op_t sProfileParamsOp{}; + + sProfileParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; + sProfileParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_PROFILE_PARAMS; + + sProfileParamsIp.e_profile = mProfile; + if (sProfileParamsIp.e_profile == IV_PROFILE_BASE) { + sProfileParamsIp.u4_entropy_coding_mode = 0; + } else { + sProfileParamsIp.u4_entropy_coding_mode = 1; + } + sProfileParamsIp.u4_timestamp_high = -1; + sProfileParamsIp.u4_timestamp_low = -1; + + sProfileParamsIp.u4_size = sizeof(ive_ctl_set_profile_params_ip_t); + sProfileParamsOp.u4_size = sizeof(ive_ctl_set_profile_params_op_t); + + ive_api_function(mCodecCtx, &sProfileParamsIp, &sProfileParamsOp); + return; +} + +void Codec::setDeblockParams() { + ive_ctl_set_deblock_params_ip_t sDeblockParamsIp{}; + ive_ctl_set_deblock_params_op_t sDeblockParamsOp{}; + + sDeblockParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; + sDeblockParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_DEBLOCK_PARAMS; + + sDeblockParamsIp.u4_disable_deblock_level = mDisableDeblockLevel; + + sDeblockParamsIp.u4_timestamp_high = -1; + sDeblockParamsIp.u4_timestamp_low = -1; + + sDeblockParamsIp.u4_size = sizeof(ive_ctl_set_deblock_params_ip_t); + sDeblockParamsOp.u4_size = sizeof(ive_ctl_set_deblock_params_op_t); + + ive_api_function(mCodecCtx, &sDeblockParamsIp, &sDeblockParamsOp); + return; +} + +void Codec::setVuiParams() { + ih264e_vui_ip_t sVuiParamsIp{}; + ih264e_vui_op_t sVuiParamsOp{}; + + sVuiParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; + sVuiParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_VUI_PARAMS; + + sVuiParamsIp.u1_aspect_ratio_info_present_flag = mAspectRatioFlag; + sVuiParamsIp.u1_aspect_ratio_idc = 0; + sVuiParamsIp.u2_sar_width = 0; + sVuiParamsIp.u2_sar_height = 0; + sVuiParamsIp.u1_overscan_info_present_flag = 0; + sVuiParamsIp.u1_overscan_appropriate_flag = 0; + sVuiParamsIp.u1_video_signal_type_present_flag = 1; + sVuiParamsIp.u1_video_format = 0; + sVuiParamsIp.u1_video_full_range_flag = 0; + sVuiParamsIp.u1_colour_description_present_flag = 1; + sVuiParamsIp.u1_colour_primaries = 0; + sVuiParamsIp.u1_transfer_characteristics = 0; + sVuiParamsIp.u1_matrix_coefficients = 0; + sVuiParamsIp.u1_chroma_loc_info_present_flag = 0; + sVuiParamsIp.u1_chroma_sample_loc_type_top_field = 0; + sVuiParamsIp.u1_chroma_sample_loc_type_bottom_field = 0; + sVuiParamsIp.u1_vui_timing_info_present_flag = 0; + sVuiParamsIp.u4_vui_num_units_in_tick = 0; + sVuiParamsIp.u4_vui_time_scale = 0; + sVuiParamsIp.u1_fixed_frame_rate_flag = 0; + sVuiParamsIp.u1_nal_hrd_parameters_present_flag = mNalHrdFlag; + sVuiParamsIp.u1_vcl_hrd_parameters_present_flag = mVclHrdFlag; + sVuiParamsIp.u1_low_delay_hrd_flag = 0; + sVuiParamsIp.u1_pic_struct_present_flag = 0; + sVuiParamsIp.u1_bitstream_restriction_flag = 0; + sVuiParamsIp.u1_motion_vectors_over_pic_boundaries_flag = 0; + sVuiParamsIp.u1_max_bytes_per_pic_denom = 0; + sVuiParamsIp.u1_max_bits_per_mb_denom = 0; + sVuiParamsIp.u1_log2_max_mv_length_horizontal = 0; + sVuiParamsIp.u1_log2_max_mv_length_vertical = 0; + sVuiParamsIp.u1_num_reorder_frames = 0; + sVuiParamsIp.u1_max_dec_frame_buffering = 0; + + sVuiParamsIp.u4_size = sizeof(ih264e_vui_ip_t); + sVuiParamsOp.u4_size = sizeof(ih264e_vui_op_t); + + ive_api_function(mCodecCtx, &sVuiParamsIp, &sVuiParamsOp); + return; +} + +void Codec::setSeiMdcvParams() { + ih264e_ctl_set_sei_mdcv_params_ip_t sSeiMdcvParamsIp{}; + ih264e_ctl_set_sei_mdcv_params_op_t sSeiMdcvParamsOp{}; + + sSeiMdcvParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; + sSeiMdcvParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_SEI_MDCV_PARAMS; + sSeiMdcvParamsIp.u1_sei_mdcv_params_present_flag = mSeiMdcvFlag; + if (mSeiMdcvFlag) { + for (int i4_count = 0; i4_count < NUM_SEI_MDCV_PRIMARIES; ++i4_count) { + sSeiMdcvParamsIp.au2_display_primaries_x[i4_count] = 30000; + sSeiMdcvParamsIp.au2_display_primaries_y[i4_count] = 35000; + } + sSeiMdcvParamsIp.u2_white_point_x = 30000; + sSeiMdcvParamsIp.u2_white_point_y = 35000; + sSeiMdcvParamsIp.u4_max_display_mastering_luminance = 100000000; + sSeiMdcvParamsIp.u4_min_display_mastering_luminance = 50000; + } + + sSeiMdcvParamsIp.u4_timestamp_high = -1; + sSeiMdcvParamsIp.u4_timestamp_low = -1; + + sSeiMdcvParamsIp.u4_size = sizeof(ih264e_ctl_set_sei_mdcv_params_ip_t); + sSeiMdcvParamsOp.u4_size = sizeof(ih264e_ctl_set_sei_mdcv_params_op_t); + ih264e_api_function(mCodecCtx, &sSeiMdcvParamsIp, &sSeiMdcvParamsOp); + return; +} + +void Codec::setSeiCllParams() { + ih264e_ctl_set_sei_cll_params_ip_t sSeiCllParamsIp{}; + ih264e_ctl_set_sei_cll_params_op_t sSeiCllParamsOp{}; + + sSeiCllParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; + sSeiCllParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_SEI_CLL_PARAMS; + sSeiCllParamsIp.u1_sei_cll_params_present_flag = mSeiCllFlag; + if (mSeiCllFlag) { + sSeiCllParamsIp.u2_max_content_light_level = 0; + sSeiCllParamsIp.u2_max_pic_average_light_level = 0; + } + + sSeiCllParamsIp.u4_timestamp_high = -1; + sSeiCllParamsIp.u4_timestamp_low = -1; + + sSeiCllParamsIp.u4_size = sizeof(ih264e_ctl_set_sei_cll_params_ip_t); + sSeiCllParamsOp.u4_size = sizeof(ih264e_ctl_set_sei_cll_params_op_t); + + ih264e_api_function(mCodecCtx, &sSeiCllParamsIp, &sSeiCllParamsOp); + return; +} + +void Codec::setSeiAveParams() { + ih264e_ctl_set_sei_ave_params_ip_t sSeiAveParamsIp{}; + ih264e_ctl_set_sei_ave_params_op_t sSeiAveParamsOp{}; + + sSeiAveParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; + sSeiAveParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_SEI_AVE_PARAMS; + sSeiAveParamsIp.u1_sei_ave_params_present_flag = mSeiAveFlag; + if (mSeiAveFlag) { + sSeiAveParamsIp.u4_ambient_illuminance = 1; + sSeiAveParamsIp.u2_ambient_light_x = 0; + sSeiAveParamsIp.u2_ambient_light_y = 0; + } + + sSeiAveParamsIp.u4_timestamp_high = -1; + sSeiAveParamsIp.u4_timestamp_low = -1; + + sSeiAveParamsIp.u4_size = sizeof(ih264e_ctl_set_sei_ave_params_ip_t); + sSeiAveParamsOp.u4_size = sizeof(ih264e_ctl_set_sei_ave_params_op_t); + + ih264e_api_function(mCodecCtx, &sSeiAveParamsIp, &sSeiAveParamsOp); + return; +} + +void Codec::setSeiCcvParams() { + ih264e_ctl_set_sei_ccv_params_ip_t sSeiCcvParamsIp{}; + ih264e_ctl_set_sei_ccv_params_op_t sSeiCcvParamsOp{}; + + sSeiCcvParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; + sSeiCcvParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_SEI_CCV_PARAMS; + sSeiCcvParamsIp.u1_sei_ccv_params_present_flag = mSeiCcvFlag; + if (mSeiCcvFlag) { + sSeiCcvParamsIp.u1_ccv_cancel_flag = 0; + sSeiCcvParamsIp.u1_ccv_persistence_flag = 1; + sSeiCcvParamsIp.u1_ccv_primaries_present_flag = 1; + sSeiCcvParamsIp.u1_ccv_min_luminance_value_present_flag = 1; + sSeiCcvParamsIp.u1_ccv_max_luminance_value_present_flag = 1; + sSeiCcvParamsIp.u1_ccv_avg_luminance_value_present_flag = 1; + sSeiCcvParamsIp.u1_ccv_reserved_zero_2bits = 0; + for (int i4_count = 0; i4_count < NUM_SEI_CCV_PRIMARIES; ++i4_count) { + sSeiCcvParamsIp.ai4_ccv_primaries_x[i4_count] = 1; + sSeiCcvParamsIp.ai4_ccv_primaries_y[i4_count] = 1; + } + sSeiCcvParamsIp.u4_ccv_min_luminance_value = 1; + sSeiCcvParamsIp.u4_ccv_max_luminance_value = 1; + sSeiCcvParamsIp.u4_ccv_avg_luminance_value = 1; + } + + sSeiCcvParamsIp.u4_timestamp_high = -1; + sSeiCcvParamsIp.u4_timestamp_low = -1; + + sSeiCcvParamsIp.u4_size = sizeof(ih264e_ctl_set_sei_ccv_params_ip_t); + sSeiCcvParamsOp.u4_size = sizeof(ih264e_ctl_set_sei_ccv_params_op_t); + + ih264e_api_function(mCodecCtx, &sSeiCcvParamsIp, &sSeiCcvParamsOp); + return; +} + +void Codec::logVersion() { + ive_ctl_getversioninfo_ip_t sCtlIp{}; + ive_ctl_getversioninfo_op_t sCtlOp{}; + UWORD8 au1Buf[512]; + + sCtlIp.e_cmd = IVE_CMD_VIDEO_CTL; + sCtlIp.e_sub_cmd = IVE_CMD_CTL_GETVERSION; + + sCtlIp.u4_size = sizeof(ive_ctl_getversioninfo_ip_t); + sCtlOp.u4_size = sizeof(ive_ctl_getversioninfo_op_t); + sCtlIp.pu1_version = au1Buf; + sCtlIp.u4_version_bufsize = sizeof(au1Buf); + + ive_api_function(mCodecCtx, (void *)&sCtlIp, (void *)&sCtlOp); + return; +} + +void Codec::encodeFrames(const uint8_t *data, size_t size) { + size_t frameSize = (mIvVideoColorFormat == IV_YUV_422ILE) ? (mWidth * mHeight * 2) + : ((mWidth * mHeight * 3) / 2); + ive_video_encode_ip_t sEncodeIp{}; + ive_video_encode_op_t sEncodeOp{}; + uint8_t header[kHeaderLength]; + int32_t numEncodeCalls = 0; + iv_raw_buf_t *psInpRawBuf = &sEncodeIp.s_inp_buf; + sEncodeIp.s_out_buf.pv_buf = header; + sEncodeIp.s_out_buf.u4_bytes = 0; + sEncodeIp.s_out_buf.u4_bufsize = kHeaderLength; + sEncodeIp.u4_size = sizeof(ive_video_encode_ip_t); + sEncodeOp.u4_size = sizeof(ive_video_encode_op_t); + + sEncodeIp.e_cmd = IVE_CMD_VIDEO_ENCODE; + sEncodeIp.pv_bufs = nullptr; + sEncodeIp.pv_mb_info = nullptr; + sEncodeIp.pv_pic_info = nullptr; + sEncodeIp.u4_mb_info_type = 0; + sEncodeIp.u4_pic_info_type = 0; + sEncodeOp.s_out_buf.pv_buf = nullptr; + + /* Initialize color formats */ + memset(psInpRawBuf, 0, sizeof(iv_raw_buf_t)); + psInpRawBuf->u4_size = sizeof(iv_raw_buf_t); + psInpRawBuf->e_color_fmt = mIvVideoColorFormat; + + ive_api_function(mCodecCtx, &sEncodeIp, &sEncodeOp); + size_t numFrame = 0; + std::vector<bufferPtrs> inBuffers; + uint64_t outputBufferSize = (frameSize / kCompressionRatio); + while (!sEncodeOp.u4_is_last && numEncodeCalls < kMaxNumEncodeCalls) { + uint8_t *outputBuffer = (uint8_t *)malloc(outputBufferSize); + sEncodeIp.s_out_buf.pv_buf = outputBuffer; + sEncodeIp.s_out_buf.u4_bufsize = outputBufferSize; + if (size > 0) { + uint8_t *tmpData = (uint8_t *)malloc(frameSize); + size_t bytesConsumed = std::min(size, frameSize); + if (bytesConsumed < frameSize) { + memset(&tmpData[bytesConsumed], data[0], frameSize - bytesConsumed); + } + memcpy(tmpData, data, bytesConsumed); + bufferPtrs inBuffer = setEncParams(psInpRawBuf, tmpData, frameSize); + inBuffers.push_back(inBuffer); + free(tmpData); + sEncodeIp.u4_is_last = 0; + if (mSendEosWithLastFrame && size == bytesConsumed) { + sEncodeIp.u4_is_last = 1; + } + if (mIsForceIdrEnabled) { + if (numFrame == mForceIdrInterval) { + setFrameType(IV_IDR_FRAME); + } + } + if (mIsDynamicBitRateChangeEnabled) { + if (numFrame == mDynamicBitRateInterval) { + if (data[0] & 0x01) { + mBitrate *= 2; + } else { + mBitrate /= 2; + } + setBitRate(); + } + } + if (mIsDynamicFrameRateChangeEnabled) { + if (numFrame == mDynamicFrameRateInterval) { + if (size > 1 && data[1] & 0x01) { + mFrameRate *= 2; + } else { + mFrameRate /= 2; + } + setFrameRate(); + } + } + ++numFrame; + data += bytesConsumed; + size -= bytesConsumed; + } else { + sEncodeIp.u4_is_last = 1; + psInpRawBuf->apv_bufs[0] = nullptr; + psInpRawBuf->apv_bufs[1] = nullptr; + psInpRawBuf->apv_bufs[2] = nullptr; + } + ive_api_function(mCodecCtx, &sEncodeIp, &sEncodeOp); + if (sEncodeOp.s_inp_buf.apv_bufs[0]) { + std::vector<bufferPtrs>::iterator iter; + uint8_t *inputbuf = (uint8_t *)sEncodeOp.s_inp_buf.apv_bufs[0]; + iter = std::find_if( + inBuffers.begin(), inBuffers.end(), + [=, &inputbuf](const bufferPtrs &buf) { return std::get<0>(buf) == inputbuf; }); + if (iter != inBuffers.end()) { + inBuffers.erase(iter); + free(sEncodeOp.s_inp_buf.apv_bufs[0]); + if (sEncodeOp.s_inp_buf.apv_bufs[1]) { + free(sEncodeOp.s_inp_buf.apv_bufs[1]); + } + if (sEncodeOp.s_inp_buf.apv_bufs[2]) { + free(sEncodeOp.s_inp_buf.apv_bufs[2]); + } + } + } + ++numEncodeCalls; + free(outputBuffer); + } + for (const auto &buffer : inBuffers) { + free(std::get<0>(buffer)); + if (std::get<1>(buffer)) { + free(std::get<1>(buffer)); + } + if (std::get<2>(buffer)) { + free(std::get<2>(buffer)); + } + } + inBuffers.clear(); +} + +bufferPtrs Codec::setEncParams(iv_raw_buf_t *psInpRawBuf, const uint8_t *data, size_t frameSize) { + bufferPtrs inBuffer; + switch (mIvVideoColorFormat) { + case IV_YUV_420SP_UV: + [[fallthrough]]; + case IV_YUV_420SP_VU: { + uint8_t *yPlane = (uint8_t *)malloc(mWidth * mHeight); + uint8_t *uPlane = (uint8_t *)malloc(frameSize - (mWidth * mHeight)); + memcpy(yPlane, data, mWidth * mHeight); + memcpy(uPlane, data + (mWidth * mHeight), frameSize - (mWidth * mHeight)); + int32_t yStride = mWidth; + int32_t uStride = mWidth / 2; + psInpRawBuf->apv_bufs[0] = yPlane; + psInpRawBuf->apv_bufs[1] = uPlane; + + psInpRawBuf->au4_wd[0] = mWidth; + psInpRawBuf->au4_wd[1] = mWidth; + + psInpRawBuf->au4_ht[0] = mHeight; + psInpRawBuf->au4_ht[1] = mHeight / 2; + + psInpRawBuf->au4_strd[0] = yStride; + psInpRawBuf->au4_strd[1] = uStride; + inBuffer = std::make_tuple(yPlane, uPlane, nullptr); + break; + } + case IV_YUV_422ILE: { + uint8_t *yPlane = (uint8_t *)malloc(frameSize); + memcpy(yPlane, data, frameSize); + psInpRawBuf->apv_bufs[0] = yPlane; + + psInpRawBuf->au4_wd[0] = mWidth * 2; + + psInpRawBuf->au4_ht[0] = mHeight; + + psInpRawBuf->au4_strd[0] = mWidth * 2; + inBuffer = std::make_tuple(yPlane, nullptr, nullptr); + break; + } + case IV_YUV_420P: + [[fallthrough]]; + default: { + uint8_t *yPlane = (uint8_t *)malloc(mWidth * mHeight); + uint8_t *uPlane = (uint8_t *)malloc((mWidth * mHeight) / 4); + uint8_t *vPlane = (uint8_t *)malloc(frameSize - ((mWidth * mHeight) * 5) / 4); + memcpy(yPlane, data, mWidth * mHeight); + memcpy(uPlane, data + (mWidth * mHeight), (mWidth * mHeight) / 4); + memcpy(vPlane, data + ((mWidth * mHeight) * 5) / 4, + frameSize - ((mWidth * mHeight) * 5) / 4); + int32_t yStride = mWidth; + int32_t uStride = mWidth / 2; + int32_t vStride = mWidth / 2; + + psInpRawBuf->apv_bufs[0] = yPlane; + psInpRawBuf->apv_bufs[1] = uPlane; + psInpRawBuf->apv_bufs[2] = vPlane; + + psInpRawBuf->au4_wd[0] = mWidth; + psInpRawBuf->au4_wd[1] = mWidth / 2; + psInpRawBuf->au4_wd[2] = mWidth / 2; + + psInpRawBuf->au4_ht[0] = mHeight; + psInpRawBuf->au4_ht[1] = mHeight / 2; + psInpRawBuf->au4_ht[2] = mHeight / 2; + + psInpRawBuf->au4_strd[0] = yStride; + psInpRawBuf->au4_strd[1] = uStride; + psInpRawBuf->au4_strd[2] = vStride; + inBuffer = std::make_tuple(yPlane, uPlane, vPlane); + break; + } + } + return inBuffer; +} + +void Codec::deInitEncoder() { + iv_mem_rec_t *ps_mem_rec = mMemRecords; + for (size_t i = 0; i < mNumMemRecords; ++i) { + if (ps_mem_rec) { + free(ps_mem_rec->pv_base); + } + ++ps_mem_rec; + } + if (mMemRecords) { + free(mMemRecords); + } + mCodecCtx = nullptr; + return; +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + if (size < IDX_LAST) { + return 0; + } + Codec *codec = new Codec(); + if (codec->initEncoder(&data, &size)) { + codec->encodeFrames(data, size); + } + delete codec; + return 0; +} diff --git a/libavc_blacklist.txt b/libavc_blocklist.txt index 5bb3630..30a2cef 100644 --- a/libavc_blacklist.txt +++ b/libavc_blocklist.txt @@ -1,5 +1,4 @@ [cfi] -src:*external/libavc/* [integer] # decoder/ih264d_dpb_mgr.c:1174: 2 - 3 cannot be represented in type 'unsigned int' diff --git a/test/Android.bp b/test/Android.bp index a62b56c..b859f49 100644 --- a/test/Android.bp +++ b/test/Android.bp @@ -1,3 +1,12 @@ +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "external_libavc_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["external_libavc_license"], +} + cc_test { name: "avcdec", gtest: false, diff --git a/test/decoder/main.c b/test/decoder/main.c index 533f72a..046c689 100644 --- a/test/decoder/main.c +++ b/test/decoder/main.c @@ -553,22 +553,24 @@ IV_API_CALL_STATUS_T set_degrade(void *codec_obj, UWORD32 type, WORD32 pics) IV_API_CALL_STATUS_T enable_skipb_frames(void *codec_obj, vid_dec_ctx_t *ps_app_ctx) { - ivd_ctl_set_config_ip_t s_ctl_ip; - ivd_ctl_set_config_op_t s_ctl_op; + ih264d_ctl_set_config_ip_t s_h264d_ctl_ip = {}; + ih264d_ctl_set_config_op_t s_h264d_ctl_op = {}; + ivd_ctl_set_config_ip_t *ps_ctl_ip = &s_h264d_ctl_ip.s_ivd_ctl_set_config_ip_t; + ivd_ctl_set_config_op_t *ps_ctl_op = &s_h264d_ctl_op.s_ivd_ctl_set_config_op_t; IV_API_CALL_STATUS_T e_dec_status; - s_ctl_ip.u4_disp_wd = ps_app_ctx->u4_strd; - s_ctl_ip.e_frm_skip_mode = IVD_SKIP_B; + ps_ctl_ip->u4_disp_wd = ps_app_ctx->u4_strd; + ps_ctl_ip->e_frm_skip_mode = IVD_SKIP_B; - s_ctl_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT; - s_ctl_ip.e_vid_dec_mode = IVD_DECODE_FRAME; - s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL; - s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS; - s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t); - s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_op_t); + ps_ctl_ip->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT; + ps_ctl_ip->e_vid_dec_mode = IVD_DECODE_FRAME; + ps_ctl_ip->e_cmd = IVD_CMD_VIDEO_CTL; + ps_ctl_ip->e_sub_cmd = IVD_CMD_CTL_SETPARAMS; + ps_ctl_ip->u4_size = sizeof(ih264d_ctl_set_config_ip_t); + ps_ctl_op->u4_size = sizeof(ih264d_ctl_set_config_op_t); - e_dec_status = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip, - (void *)&s_ctl_op); + e_dec_status = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_h264d_ctl_ip, + (void *)&s_h264d_ctl_op); if(IV_SUCCESS != e_dec_status) { @@ -603,22 +605,24 @@ IV_API_CALL_STATUS_T enable_skipb_frames(void *codec_obj, IV_API_CALL_STATUS_T disable_skipb_frames(void *codec_obj, vid_dec_ctx_t *ps_app_ctx) { - ivd_ctl_set_config_ip_t s_ctl_ip; - ivd_ctl_set_config_op_t s_ctl_op; + ih264d_ctl_set_config_ip_t s_h264d_ctl_ip = {}; + ih264d_ctl_set_config_op_t s_h264d_ctl_op = {}; + ivd_ctl_set_config_ip_t *ps_ctl_ip = &s_h264d_ctl_ip.s_ivd_ctl_set_config_ip_t; + ivd_ctl_set_config_op_t *ps_ctl_op = &s_h264d_ctl_op.s_ivd_ctl_set_config_op_t; IV_API_CALL_STATUS_T e_dec_status; - s_ctl_ip.u4_disp_wd = ps_app_ctx->u4_strd; - s_ctl_ip.e_frm_skip_mode = IVD_SKIP_NONE; + ps_ctl_ip->u4_disp_wd = ps_app_ctx->u4_strd; + ps_ctl_ip->e_frm_skip_mode = IVD_SKIP_NONE; - s_ctl_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT; - s_ctl_ip.e_vid_dec_mode = IVD_DECODE_FRAME; - s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL; - s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS; - s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t); - s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_op_t); + ps_ctl_ip->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT; + ps_ctl_ip->e_vid_dec_mode = IVD_DECODE_FRAME; + ps_ctl_ip->e_cmd = IVD_CMD_VIDEO_CTL; + ps_ctl_ip->e_sub_cmd = IVD_CMD_CTL_SETPARAMS; + ps_ctl_ip->u4_size = sizeof(ih264d_ctl_set_config_ip_t); + ps_ctl_op->u4_size = sizeof(ih264d_ctl_set_config_op_t); - e_dec_status = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip, - (void *)&s_ctl_op); + e_dec_status = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_h264d_ctl_ip, + (void *)&s_h264d_ctl_op); if(IV_SUCCESS != e_dec_status) { @@ -654,22 +658,24 @@ IV_API_CALL_STATUS_T disable_skipb_frames(void *codec_obj, IV_API_CALL_STATUS_T enable_skippb_frames(void *codec_obj, vid_dec_ctx_t *ps_app_ctx) { - ivd_ctl_set_config_ip_t s_ctl_ip; - ivd_ctl_set_config_op_t s_ctl_op; + ih264d_ctl_set_config_ip_t s_h264d_ctl_ip = {}; + ih264d_ctl_set_config_op_t s_h264d_ctl_op = {}; + ivd_ctl_set_config_ip_t *ps_ctl_ip = &s_h264d_ctl_ip.s_ivd_ctl_set_config_ip_t; + ivd_ctl_set_config_op_t *ps_ctl_op = &s_h264d_ctl_op.s_ivd_ctl_set_config_op_t; IV_API_CALL_STATUS_T e_dec_status; - s_ctl_ip.u4_disp_wd = ps_app_ctx->u4_strd; - s_ctl_ip.e_frm_skip_mode = IVD_SKIP_PB; + ps_ctl_ip->u4_disp_wd = ps_app_ctx->u4_strd; + ps_ctl_ip->e_frm_skip_mode = IVD_SKIP_PB; - s_ctl_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT; - s_ctl_ip.e_vid_dec_mode = IVD_DECODE_FRAME; - s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL; - s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS; - s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t); - s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_op_t); + ps_ctl_ip->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT; + ps_ctl_ip->e_vid_dec_mode = IVD_DECODE_FRAME; + ps_ctl_ip->e_cmd = IVD_CMD_VIDEO_CTL; + ps_ctl_ip->e_sub_cmd = IVD_CMD_CTL_SETPARAMS; + ps_ctl_ip->u4_size = sizeof(ih264d_ctl_set_config_ip_t); + ps_ctl_op->u4_size = sizeof(ih264d_ctl_set_config_op_t); - e_dec_status = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip, - (void *)&s_ctl_op); + e_dec_status = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_h264d_ctl_ip, + (void *)&s_h264d_ctl_op); if(IV_SUCCESS != e_dec_status) { printf("Error in Enable SkipPB frames\n"); @@ -704,22 +710,24 @@ IV_API_CALL_STATUS_T enable_skippb_frames(void *codec_obj, IV_API_CALL_STATUS_T disable_skippb_frames(void *codec_obj, vid_dec_ctx_t *ps_app_ctx) { - ivd_ctl_set_config_ip_t s_ctl_ip; - ivd_ctl_set_config_op_t s_ctl_op; + ih264d_ctl_set_config_ip_t s_h264d_ctl_ip = {}; + ih264d_ctl_set_config_op_t s_h264d_ctl_op = {}; + ivd_ctl_set_config_ip_t *ps_ctl_ip = &s_h264d_ctl_ip.s_ivd_ctl_set_config_ip_t; + ivd_ctl_set_config_op_t *ps_ctl_op = &s_h264d_ctl_op.s_ivd_ctl_set_config_op_t; IV_API_CALL_STATUS_T e_dec_status; - s_ctl_ip.u4_disp_wd = ps_app_ctx->u4_strd; - s_ctl_ip.e_frm_skip_mode = IVD_SKIP_NONE; + ps_ctl_ip->u4_disp_wd = ps_app_ctx->u4_strd; + ps_ctl_ip->e_frm_skip_mode = IVD_SKIP_NONE; - s_ctl_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT; - s_ctl_ip.e_vid_dec_mode = IVD_DECODE_FRAME; - s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL; - s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS; - s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t); - s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_op_t); + ps_ctl_ip->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT; + ps_ctl_ip->e_vid_dec_mode = IVD_DECODE_FRAME; + ps_ctl_ip->e_cmd = IVD_CMD_VIDEO_CTL; + ps_ctl_ip->e_sub_cmd = IVD_CMD_CTL_SETPARAMS; + ps_ctl_ip->u4_size = sizeof(ih264d_ctl_set_config_ip_t); + ps_ctl_op->u4_size = sizeof(ih264d_ctl_set_config_op_t); - e_dec_status = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip, - (void *)&s_ctl_op); + e_dec_status = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_h264d_ctl_ip, + (void *)&s_h264d_ctl_op); if(IV_SUCCESS != e_dec_status) { printf("Error in Disable SkipPB frames\n"); @@ -1657,39 +1665,41 @@ void flush_output(iv_obj_t *codec_obj, if(IV_SUCCESS == ret) { - ivd_video_decode_ip_t s_video_decode_ip; - ivd_video_decode_op_t s_video_decode_op; - - s_video_decode_ip.e_cmd = IVD_CMD_VIDEO_DECODE; - s_video_decode_ip.u4_ts = u4_ip_frm_ts; - s_video_decode_ip.pv_stream_buffer = pu1_bs_buf; - s_video_decode_ip.u4_num_Bytes = u4_bytes_remaining; - s_video_decode_ip.u4_size = sizeof(ivd_video_decode_ip_t); - s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[0] = + ih264d_video_decode_ip_t s_h264d_decode_ip = {}; + ih264d_video_decode_op_t s_h264d_decode_op = {}; + ivd_video_decode_ip_t *ps_video_decode_ip = &s_h264d_decode_ip.s_ivd_video_decode_ip_t; + ivd_video_decode_op_t *ps_video_decode_op = &s_h264d_decode_op.s_ivd_video_decode_op_t; + + ps_video_decode_ip->e_cmd = IVD_CMD_VIDEO_DECODE; + ps_video_decode_ip->u4_ts = u4_ip_frm_ts; + ps_video_decode_ip->pv_stream_buffer = pu1_bs_buf; + ps_video_decode_ip->u4_num_Bytes = u4_bytes_remaining; + ps_video_decode_ip->u4_size = sizeof(ih264d_video_decode_ip_t); + ps_video_decode_ip->s_out_buffer.u4_min_out_buf_size[0] = ps_out_buf->u4_min_out_buf_size[0]; - s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[1] = + ps_video_decode_ip->s_out_buffer.u4_min_out_buf_size[1] = ps_out_buf->u4_min_out_buf_size[1]; - s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[2] = + ps_video_decode_ip->s_out_buffer.u4_min_out_buf_size[2] = ps_out_buf->u4_min_out_buf_size[2]; - s_video_decode_ip.s_out_buffer.pu1_bufs[0] = + ps_video_decode_ip->s_out_buffer.pu1_bufs[0] = ps_out_buf->pu1_bufs[0]; - s_video_decode_ip.s_out_buffer.pu1_bufs[1] = + ps_video_decode_ip->s_out_buffer.pu1_bufs[1] = ps_out_buf->pu1_bufs[1]; - s_video_decode_ip.s_out_buffer.pu1_bufs[2] = + ps_video_decode_ip->s_out_buffer.pu1_bufs[2] = ps_out_buf->pu1_bufs[2]; - s_video_decode_ip.s_out_buffer.u4_num_bufs = + ps_video_decode_ip->s_out_buffer.u4_num_bufs = ps_out_buf->u4_num_bufs; - s_video_decode_op.u4_size = sizeof(ivd_video_decode_op_t); + ps_video_decode_op->u4_size = sizeof(ih264d_video_decode_op_t); /*****************************************************************************/ /* API Call: Video Decode */ /*****************************************************************************/ - ret = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_video_decode_ip, - (void *)&s_video_decode_op); + ret = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_h264d_decode_ip, + (void *)&s_h264d_decode_op); - if(1 == s_video_decode_op.u4_output_present) + if(1 == ps_video_decode_op->u4_output_present) { CHAR cur_fname[1000]; CHAR *extn = NULL; @@ -1701,7 +1711,7 @@ void flush_output(iv_obj_t *codec_obj, /*************************************************************************/ /* Get SEI MDCV parameters */ /*************************************************************************/ - if(1 == s_video_decode_op.s_sei_decode_op.u1_sei_mdcv_params_present_flag) + if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_mdcv_params_present_flag) { ih264d_ctl_get_sei_mdcv_params_ip_t s_ctl_get_sei_mdcv_params_ip; ih264d_ctl_get_sei_mdcv_params_op_t s_ctl_get_sei_mdcv_params_op; @@ -1732,7 +1742,7 @@ void flush_output(iv_obj_t *codec_obj, /*************************************************************************/ /* Get SEI CLL parameters */ /*************************************************************************/ - if(1 == s_video_decode_op.s_sei_decode_op.u1_sei_cll_params_present_flag) + if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_cll_params_present_flag) { ih264d_ctl_get_sei_cll_params_ip_t s_ctl_get_sei_cll_params_ip; ih264d_ctl_get_sei_cll_params_op_t s_ctl_get_sei_cll_params_op; @@ -1763,7 +1773,7 @@ void flush_output(iv_obj_t *codec_obj, /*************************************************************************/ /* Get SEI AVE parameters */ /*************************************************************************/ - if(1 == s_video_decode_op.s_sei_decode_op.u1_sei_ave_params_present_flag) + if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_ave_params_present_flag) { ih264d_ctl_get_sei_ave_params_ip_t s_ctl_get_sei_ave_params_ip; ih264d_ctl_get_sei_ave_params_op_t s_ctl_get_sei_ave_params_op; @@ -1794,7 +1804,7 @@ void flush_output(iv_obj_t *codec_obj, /*************************************************************************/ /* Get SEI CCV parameters */ /*************************************************************************/ - if(1 == s_video_decode_op.s_sei_decode_op.u1_sei_ccv_params_present_flag) + if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_ccv_params_present_flag) { ih264d_ctl_get_sei_ccv_params_ip_t s_ctl_get_sei_ccv_params_ip; ih264d_ctl_get_sei_ccv_params_op_t s_ctl_get_sei_ccv_params_op; @@ -1845,8 +1855,8 @@ void flush_output(iv_obj_t *codec_obj, } } - dump_output(ps_app_ctx, &(s_video_decode_op.s_disp_frm_buf), - s_video_decode_op.u4_disp_buf_id, ps_op_file, + dump_output(ps_app_ctx, &(ps_video_decode_op->s_disp_frm_buf), + ps_video_decode_op->u4_disp_buf_id, ps_op_file, ps_op_chksum_file, *pu4_op_frm_ts, ps_app_ctx->u4_file_save_flag, ps_app_ctx->u4_chksum_save_flag); @@ -2275,24 +2285,26 @@ int main(WORD32 argc, CHAR *argv[]) /* set stride */ /*****************************************************************************/ { - ivd_ctl_set_config_ip_t s_ctl_ip; - ivd_ctl_set_config_op_t s_ctl_op; + ih264d_ctl_set_config_ip_t s_h264d_ctl_ip = {}; + ih264d_ctl_set_config_op_t s_h264d_ctl_op = {}; + ivd_ctl_set_config_ip_t *ps_ctl_ip = &s_h264d_ctl_ip.s_ivd_ctl_set_config_ip_t; + ivd_ctl_set_config_op_t *ps_ctl_op = &s_h264d_ctl_op.s_ivd_ctl_set_config_op_t; - s_ctl_ip.u4_disp_wd = STRIDE; + ps_ctl_ip->u4_disp_wd = STRIDE; if(1 == s_app_ctx.display) - s_ctl_ip.u4_disp_wd = s_app_ctx.get_stride(); - - s_ctl_ip.e_frm_skip_mode = IVD_SKIP_NONE; - s_ctl_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT; - s_ctl_ip.e_vid_dec_mode = IVD_DECODE_HEADER; - s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL; - s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS; - s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t); - s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_op_t); - - ret = ivd_api_function((iv_obj_t*)codec_obj, (void *)&s_ctl_ip, - (void *)&s_ctl_op); + ps_ctl_ip->u4_disp_wd = s_app_ctx.get_stride(); + + ps_ctl_ip->e_frm_skip_mode = IVD_SKIP_NONE; + ps_ctl_ip->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT; + ps_ctl_ip->e_vid_dec_mode = IVD_DECODE_HEADER; + ps_ctl_ip->e_cmd = IVD_CMD_VIDEO_CTL; + ps_ctl_ip->e_sub_cmd = IVD_CMD_CTL_SETPARAMS; + ps_ctl_ip->u4_size = sizeof(ih264d_ctl_set_config_ip_t); + ps_ctl_op->u4_size = sizeof(ih264d_ctl_set_config_op_t); + + ret = ivd_api_function((iv_obj_t*)codec_obj, (void *)&s_h264d_ctl_ip, + (void *)&s_h264d_ctl_op); if(ret != IV_SUCCESS) { sprintf(ac_error_str, @@ -2366,30 +2378,34 @@ int main(WORD32 argc, CHAR *argv[]) /* Decode header to get width and height and buffer sizes */ /*****************************************************************************/ { - ivd_video_decode_ip_t s_video_decode_ip; - ivd_video_decode_op_t s_video_decode_op; + ih264d_video_decode_ip_t s_h264d_decode_ip = {}; + ih264d_video_decode_op_t s_h264d_decode_op = {}; + ivd_video_decode_ip_t *ps_video_decode_ip = &s_h264d_decode_ip.s_ivd_video_decode_ip_t; + ivd_video_decode_op_t *ps_video_decode_op = &s_h264d_decode_op.s_ivd_video_decode_op_t; { - ivd_ctl_set_config_ip_t s_ctl_ip; - ivd_ctl_set_config_op_t s_ctl_op; + ih264d_ctl_set_config_ip_t s_h264d_ctl_ip = {}; + ih264d_ctl_set_config_op_t s_h264d_ctl_op = {}; + ivd_ctl_set_config_ip_t *ps_ctl_ip = &s_h264d_ctl_ip.s_ivd_ctl_set_config_ip_t; + ivd_ctl_set_config_op_t *ps_ctl_op = &s_h264d_ctl_op.s_ivd_ctl_set_config_op_t; - s_ctl_ip.u4_disp_wd = STRIDE; + ps_ctl_ip->u4_disp_wd = STRIDE; if(1 == s_app_ctx.display) - s_ctl_ip.u4_disp_wd = s_app_ctx.get_stride(); - - s_ctl_ip.e_frm_skip_mode = IVD_SKIP_NONE; - s_ctl_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT; - s_ctl_ip.e_vid_dec_mode = IVD_DECODE_HEADER; - s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL; - s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS; - s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t); - s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_op_t); - - ret = ivd_api_function((iv_obj_t*)codec_obj, (void *)&s_ctl_ip, - (void *)&s_ctl_op); + ps_ctl_ip->u4_disp_wd = s_app_ctx.get_stride(); + + ps_ctl_ip->e_frm_skip_mode = IVD_SKIP_NONE; + ps_ctl_ip->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT; + ps_ctl_ip->e_vid_dec_mode = IVD_DECODE_HEADER; + ps_ctl_ip->e_cmd = IVD_CMD_VIDEO_CTL; + ps_ctl_ip->e_sub_cmd = IVD_CMD_CTL_SETPARAMS; + ps_ctl_ip->u4_size = sizeof(ih264d_ctl_set_config_ip_t); + ps_ctl_op->u4_size = sizeof(ih264d_ctl_set_config_op_t); + + ret = ivd_api_function((iv_obj_t*)codec_obj, (void *)&s_h264d_ctl_ip, + (void *)&s_h264d_ctl_op); if(ret != IV_SUCCESS) { sprintf(ac_error_str, @@ -2436,36 +2452,36 @@ int main(WORD32 argc, CHAR *argv[]) codec_exit(ac_error_str); } - s_video_decode_ip.e_cmd = IVD_CMD_VIDEO_DECODE; - s_video_decode_ip.u4_ts = u4_ip_frm_ts; - s_video_decode_ip.pv_stream_buffer = pu1_bs_buf; - s_video_decode_ip.u4_num_Bytes = u4_bytes_remaining; - s_video_decode_ip.u4_size = sizeof(ivd_video_decode_ip_t); - s_video_decode_op.u4_size = sizeof(ivd_video_decode_op_t); + ps_video_decode_ip->e_cmd = IVD_CMD_VIDEO_DECODE; + ps_video_decode_ip->u4_ts = u4_ip_frm_ts; + ps_video_decode_ip->pv_stream_buffer = pu1_bs_buf; + ps_video_decode_ip->u4_num_Bytes = u4_bytes_remaining; + ps_video_decode_ip->u4_size = sizeof(ih264d_video_decode_ip_t); + ps_video_decode_op->u4_size = sizeof(ih264d_video_decode_op_t); /*****************************************************************************/ /* API Call: Header Decode */ /*****************************************************************************/ - ret = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_video_decode_ip, - (void *)&s_video_decode_op); + ret = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_h264d_decode_ip, + (void *)&s_h264d_decode_op); if(ret != IV_SUCCESS) { - printf("Error in header decode 0x%x\n", s_video_decode_op.u4_error_code); + printf("Error in header decode 0x%x\n", ps_video_decode_op->u4_error_code); // codec_exit(ac_error_str); } - u4_num_bytes_dec = s_video_decode_op.u4_num_bytes_consumed; + u4_num_bytes_dec = ps_video_decode_op->u4_num_bytes_consumed; #ifndef PROFILE_ENABLE - printf("%d\n",s_video_decode_op.u4_num_bytes_consumed); + printf("%d\n",ps_video_decode_op->u4_num_bytes_consumed); #endif file_pos += u4_num_bytes_dec; total_bytes_comsumed += u4_num_bytes_dec; }while(ret != IV_SUCCESS); /* copy pic_wd and pic_ht to initialize buffers */ - s_app_ctx.u4_pic_wd = s_video_decode_op.u4_pic_wd; - s_app_ctx.u4_pic_ht = s_video_decode_op.u4_pic_ht; + s_app_ctx.u4_pic_wd = ps_video_decode_op->u4_pic_wd; + s_app_ctx.u4_pic_ht = ps_video_decode_op->u4_pic_ht; free(pu1_bs_buf); @@ -2767,23 +2783,26 @@ int main(WORD32 argc, CHAR *argv[]) /*************************************************************************/ { - ivd_ctl_set_config_ip_t s_ctl_ip; - ivd_ctl_set_config_op_t s_ctl_op; + ih264d_ctl_set_config_ip_t s_h264d_ctl_ip = {}; + ih264d_ctl_set_config_op_t s_h264d_ctl_op = {}; + ivd_ctl_set_config_ip_t *ps_ctl_ip = &s_h264d_ctl_ip.s_ivd_ctl_set_config_ip_t; + ivd_ctl_set_config_op_t *ps_ctl_op = &s_h264d_ctl_op.s_ivd_ctl_set_config_op_t; - s_ctl_ip.u4_disp_wd = STRIDE; + ps_ctl_ip->u4_disp_wd = STRIDE; if(1 == s_app_ctx.display) - s_ctl_ip.u4_disp_wd = s_app_ctx.get_stride(); - s_ctl_ip.e_frm_skip_mode = IVD_SKIP_NONE; + ps_ctl_ip->u4_disp_wd = s_app_ctx.get_stride(); + ps_ctl_ip->e_frm_skip_mode = IVD_SKIP_NONE; - s_ctl_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT; - s_ctl_ip.e_vid_dec_mode = IVD_DECODE_FRAME; - s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL; - s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS; - s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t); + ps_ctl_ip->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT; + ps_ctl_ip->e_vid_dec_mode = IVD_DECODE_FRAME; + ps_ctl_ip->e_cmd = IVD_CMD_VIDEO_CTL; + ps_ctl_ip->e_sub_cmd = IVD_CMD_CTL_SETPARAMS; + ps_ctl_ip->u4_size = sizeof(ih264d_ctl_set_config_ip_t); - s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_op_t); + ps_ctl_op->u4_size = sizeof(ih264d_ctl_set_config_op_t); - ret = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip, (void *)&s_ctl_op); + ret = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_h264d_ctl_ip, + (void *)&s_h264d_ctl_op); if(IV_SUCCESS != ret) { @@ -2947,8 +2966,10 @@ int main(WORD32 argc, CHAR *argv[]) { - ivd_video_decode_ip_t s_video_decode_ip; - ivd_video_decode_op_t s_video_decode_op; + ih264d_video_decode_ip_t s_h264d_decode_ip = {}; + ih264d_video_decode_op_t s_h264d_decode_op = {}; + ivd_video_decode_ip_t *ps_video_decode_ip = &s_h264d_decode_ip.s_ivd_video_decode_ip_t; + ivd_video_decode_op_t *ps_video_decode_op = &s_h264d_decode_op.s_ivd_video_decode_op_t; #ifdef PROFILE_ENABLE UWORD32 s_elapsed_time; TIMER s_start_timer; @@ -2956,27 +2977,27 @@ int main(WORD32 argc, CHAR *argv[]) #endif - s_video_decode_ip.e_cmd = IVD_CMD_VIDEO_DECODE; - s_video_decode_ip.u4_ts = u4_ip_frm_ts; - s_video_decode_ip.pv_stream_buffer = pu1_bs_buf; - s_video_decode_ip.u4_num_Bytes = u4_bytes_remaining; - s_video_decode_ip.u4_size = sizeof(ivd_video_decode_ip_t); - s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[0] = + ps_video_decode_ip->e_cmd = IVD_CMD_VIDEO_DECODE; + ps_video_decode_ip->u4_ts = u4_ip_frm_ts; + ps_video_decode_ip->pv_stream_buffer = pu1_bs_buf; + ps_video_decode_ip->u4_num_Bytes = u4_bytes_remaining; + ps_video_decode_ip->u4_size = sizeof(ih264d_video_decode_ip_t); + ps_video_decode_ip->s_out_buffer.u4_min_out_buf_size[0] = ps_out_buf->u4_min_out_buf_size[0]; - s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[1] = + ps_video_decode_ip->s_out_buffer.u4_min_out_buf_size[1] = ps_out_buf->u4_min_out_buf_size[1]; - s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[2] = + ps_video_decode_ip->s_out_buffer.u4_min_out_buf_size[2] = ps_out_buf->u4_min_out_buf_size[2]; - s_video_decode_ip.s_out_buffer.pu1_bufs[0] = + ps_video_decode_ip->s_out_buffer.pu1_bufs[0] = ps_out_buf->pu1_bufs[0]; - s_video_decode_ip.s_out_buffer.pu1_bufs[1] = + ps_video_decode_ip->s_out_buffer.pu1_bufs[1] = ps_out_buf->pu1_bufs[1]; - s_video_decode_ip.s_out_buffer.pu1_bufs[2] = + ps_video_decode_ip->s_out_buffer.pu1_bufs[2] = ps_out_buf->pu1_bufs[2]; - s_video_decode_ip.s_out_buffer.u4_num_bufs = + ps_video_decode_ip->s_out_buffer.u4_num_bufs = ps_out_buf->u4_num_bufs; - s_video_decode_op.u4_size = sizeof(ivd_video_decode_op_t); + ps_video_decode_op->u4_size = sizeof(ih264d_video_decode_op_t); /* Get display buffer pointers */ if(1 == s_app_ctx.display) @@ -2989,9 +3010,9 @@ int main(WORD32 argc, CHAR *argv[]) break; s_app_ctx.set_disp_buffers(s_app_ctx.pv_disp_ctx, wr_idx, - &s_video_decode_ip.s_out_buffer.pu1_bufs[0], - &s_video_decode_ip.s_out_buffer.pu1_bufs[1], - &s_video_decode_ip.s_out_buffer.pu1_bufs[2]); + &ps_video_decode_ip->s_out_buffer.pu1_bufs[0], + &ps_video_decode_ip->s_out_buffer.pu1_bufs[1], + &ps_video_decode_ip->s_out_buffer.pu1_bufs[2]); } /*****************************************************************************/ @@ -3000,8 +3021,8 @@ int main(WORD32 argc, CHAR *argv[]) GETTIME(&s_start_timer); - ret = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_video_decode_ip, - (void *)&s_video_decode_op); + ret = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_h264d_decode_ip, + (void *)&s_h264d_decode_op); GETTIME(&s_end_timer); @@ -3024,12 +3045,12 @@ int main(WORD32 argc, CHAR *argv[]) frm_cnt++; printf("FrameNum: %4d TimeTaken(microsec): %6d AvgTime: %6d PeakAvgTimeMax: %6d Output: %2d NumBytes: %6d \n", - frm_cnt, s_elapsed_time, u4_tot_cycles / frm_cnt, peak_avg_max, s_video_decode_op.u4_output_present, s_video_decode_op.u4_num_bytes_consumed); + frm_cnt, s_elapsed_time, u4_tot_cycles / frm_cnt, peak_avg_max, ps_video_decode_op->u4_output_present, ps_video_decode_op->u4_num_bytes_consumed); } #ifdef INTEL_CE5300 time_consumed += s_elapsed_time; - bytes_consumed += s_video_decode_op.u4_num_bytes_consumed; + bytes_consumed += ps_video_decode_op->u4_num_bytes_consumed; if (!(frm_cnt % (s_app_ctx.fps))) { time_consumed = time_consumed/s_app_ctx.fps; @@ -3041,17 +3062,17 @@ int main(WORD32 argc, CHAR *argv[]) } #endif #else - printf("%d\n",s_video_decode_op.u4_num_bytes_consumed); + printf("%d\n",ps_video_decode_op->u4_num_bytes_consumed); #endif if(ret != IV_SUCCESS) { printf("Error in video Frame decode : ret %x Error %x\n", ret, - s_video_decode_op.u4_error_code); + ps_video_decode_op->u4_error_code); } if((IV_SUCCESS != ret) && - ((s_video_decode_op.u4_error_code & 0xFF) == IVD_RES_CHANGED)) + ((ps_video_decode_op->u4_error_code & 0xFF) == IVD_RES_CHANGED)) { ivd_ctl_reset_ip_t s_ctl_ip; ivd_ctl_reset_op_t s_ctl_op; @@ -3129,7 +3150,7 @@ int main(WORD32 argc, CHAR *argv[]) /*************************************************************************/ /* Get SEI MDCV parameters */ /*************************************************************************/ - if(1 == s_video_decode_op.s_sei_decode_op.u1_sei_mdcv_params_present_flag) + if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_mdcv_params_present_flag) { ih264d_ctl_get_sei_mdcv_params_ip_t s_ctl_get_sei_mdcv_params_ip; ih264d_ctl_get_sei_mdcv_params_op_t s_ctl_get_sei_mdcv_params_op; @@ -3160,7 +3181,7 @@ int main(WORD32 argc, CHAR *argv[]) /*************************************************************************/ /* Get SEI CLL parameters */ /*************************************************************************/ - if(1 == s_video_decode_op.s_sei_decode_op.u1_sei_cll_params_present_flag) + if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_cll_params_present_flag) { ih264d_ctl_get_sei_cll_params_ip_t s_ctl_get_sei_cll_params_ip; @@ -3192,7 +3213,7 @@ int main(WORD32 argc, CHAR *argv[]) /*************************************************************************/ /* Get SEI AVE parameters */ /*************************************************************************/ - if(1 == s_video_decode_op.s_sei_decode_op.u1_sei_ave_params_present_flag) + if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_ave_params_present_flag) { ih264d_ctl_get_sei_ave_params_ip_t s_ctl_get_sei_ave_params_ip; ih264d_ctl_get_sei_ave_params_op_t s_ctl_get_sei_ave_params_op; @@ -3223,7 +3244,7 @@ int main(WORD32 argc, CHAR *argv[]) /*************************************************************************/ /* Get SEI CCV parameters */ /*************************************************************************/ - if(1 == s_video_decode_op.s_sei_decode_op.u1_sei_ccv_params_present_flag) + if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_ccv_params_present_flag) { ih264d_ctl_get_sei_ccv_params_ip_t s_ctl_get_sei_ccv_params_ip; ih264d_ctl_get_sei_ccv_params_op_t s_ctl_get_sei_ccv_params_op; @@ -3253,22 +3274,22 @@ int main(WORD32 argc, CHAR *argv[]) } if((1 == s_app_ctx.display) && - (1 == s_video_decode_op.u4_output_present)) + (1 == ps_video_decode_op->u4_output_present)) { dispq_producer_queue(&s_app_ctx); } - if(IV_B_FRAME == s_video_decode_op.e_pic_type) + if(IV_B_FRAME == ps_video_decode_op->e_pic_type) s_app_ctx.b_pic_present |= 1; - u4_num_bytes_dec = s_video_decode_op.u4_num_bytes_consumed; + u4_num_bytes_dec = ps_video_decode_op->u4_num_bytes_consumed; file_pos += u4_num_bytes_dec; total_bytes_comsumed += u4_num_bytes_dec; u4_ip_frm_ts++; - if(1 == s_video_decode_op.u4_output_present) + if(1 == ps_video_decode_op->u4_output_present) { CHAR cur_fname[1000]; @@ -3298,10 +3319,10 @@ int main(WORD32 argc, CHAR *argv[]) } } - width = s_video_decode_op.s_disp_frm_buf.u4_y_wd; - height = s_video_decode_op.s_disp_frm_buf.u4_y_ht; - dump_output(&s_app_ctx, &(s_video_decode_op.s_disp_frm_buf), - s_video_decode_op.u4_disp_buf_id, ps_op_file, + width = ps_video_decode_op->s_disp_frm_buf.u4_y_wd; + height = ps_video_decode_op->s_disp_frm_buf.u4_y_ht; + dump_output(&s_app_ctx, &(ps_video_decode_op->s_disp_frm_buf), + ps_video_decode_op->u4_disp_buf_id, ps_op_file, ps_op_chksum_file, u4_op_frm_ts, s_app_ctx.u4_file_save_flag, s_app_ctx.u4_chksum_save_flag); @@ -3313,7 +3334,7 @@ int main(WORD32 argc, CHAR *argv[]) } else { - if((s_video_decode_op.u4_error_code >> IVD_FATALERROR) & 1) + if((ps_video_decode_op->u4_error_code >> IVD_FATALERROR) & 1) { printf("Fatal error\n"); break; diff --git a/test/encoder/psnr.c b/test/encoder/psnr.c index d5a953c..87a03b0 100644 --- a/test/encoder/psnr.c +++ b/test/encoder/psnr.c @@ -111,13 +111,13 @@ void compute_psnr(app_ctxt_t *ps_app_ctxt, iv_raw_buf_t *ps_buf1, iv_raw_buf_t * pu1_buf2 = (UWORD8 *)ps_buf2->apv_bufs[comp]; wd = ps_buf1->au4_wd[comp]; ht = ps_buf1->au4_ht[comp]; - strd1 = ps_buf1->au4_strd[comp]; - strd2 = ps_buf2->au4_strd[comp]; + strd1 = ps_buf1->au4_strd[comp] - ps_buf1->au4_wd[comp]; + strd2 = ps_buf2->au4_strd[comp] - ps_buf2->au4_wd[comp]; incr1 = 1; incr2 = 1; if((IV_YUV_420SP_UV == ps_buf1->e_color_fmt) - || (IV_YUV_420SP_UV == ps_buf1->e_color_fmt)) + || (IV_YUV_420SP_VU == ps_buf1->e_color_fmt)) { switch(comp) { @@ -130,6 +130,8 @@ void compute_psnr(app_ctxt_t *ps_app_ctxt, iv_raw_buf_t *ps_buf1, iv_raw_buf_t * else pu1_buf1 = (UWORD8 *)ps_buf1->apv_bufs[1] + 1; incr1 = 2; + wd = ps_buf1->au4_wd[0] >> 1; + ht = ps_buf1->au4_ht[0] >> 1; break; case 2: if(IV_YUV_420SP_UV == ps_buf1->e_color_fmt) @@ -137,11 +139,14 @@ void compute_psnr(app_ctxt_t *ps_app_ctxt, iv_raw_buf_t *ps_buf1, iv_raw_buf_t * else pu1_buf1 = ps_buf1->apv_bufs[1]; incr1 = 2; + wd = ps_buf1->au4_wd[0] >> 1; + ht = ps_buf1->au4_ht[0] >> 1; + strd1 = ps_buf1->au4_strd[1] - ps_buf1->au4_wd[1]; break; } } if ((IV_YUV_420SP_UV == ps_buf2->e_color_fmt) - || (IV_YUV_420SP_UV == ps_buf2->e_color_fmt)) + || (IV_YUV_420SP_VU == ps_buf2->e_color_fmt)) { switch(comp) { @@ -153,14 +158,21 @@ void compute_psnr(app_ctxt_t *ps_app_ctxt, iv_raw_buf_t *ps_buf1, iv_raw_buf_t * pu1_buf2 = ps_buf2->apv_bufs[1]; else pu1_buf2 = (UWORD8 *)ps_buf2->apv_bufs[1] + 1; - incr1 = 2; + incr2 = 2; + wd = ps_buf2->au4_wd[0] >> 1; + ht = ps_buf2->au4_ht[0] >> 1; + break; case 2: if(IV_YUV_420SP_UV == ps_buf2->e_color_fmt) pu1_buf2 = (UWORD8 *)ps_buf2->apv_bufs[1] + 1; else pu1_buf2 = ps_buf2->apv_bufs[1]; - incr1 = 2; + incr2 = 2; + wd = ps_buf2->au4_wd[0] >> 1; + ht = ps_buf2->au4_ht[0] >> 1; + strd2 = ps_buf2->au4_strd[1] - ps_buf2->au4_wd[1]; + break; } } @@ -175,8 +187,8 @@ void compute_psnr(app_ctxt_t *ps_app_ctxt, iv_raw_buf_t *ps_buf1, iv_raw_buf_t * pu1_buf2 += incr2; df_psnr[comp] += diff * diff; } - pu1_buf1 += strd1 - ps_buf1->au4_wd[comp]; - pu1_buf2 += strd2 - ps_buf2->au4_wd[comp]; + pu1_buf1 += strd1; + pu1_buf2 += strd2; } df_psnr[comp] /= (wd * ht); if(df_psnr[comp]) |