diff --git a/inc/rk_mpi.h b/inc/rk_mpi.h index 919ead58..8906a373 100644 --- a/inc/rk_mpi.h +++ b/inc/rk_mpi.h @@ -138,6 +138,24 @@ typedef struct MppEncConfig_t { RK_S32 cabac_en; } MppEncConfig; +typedef struct MppEncCodecCfg_t { + MppCodingType coding; + + union { + RK_U32 change; + MppEncH264Cfg h264; + MppEncH265Cfg h265; + MppEncJpegCfg jpeg; + MppEncVp8Cfg vp8; + }; +} MppEncCodecCfg; + +typedef struct MppEncCfgSet_t { + MppEncPrepCfg prep; + MppEncRcCfg rc; + MppEncCodecCfg codec; +} MppEncCfgSet; + /** * @ingroup rk_mpi * @brief mpp main work function set diff --git a/inc/rk_mpi_cmd.h b/inc/rk_mpi_cmd.h index 9ababb18..718a5df3 100644 --- a/inc/rk_mpi_cmd.h +++ b/inc/rk_mpi_cmd.h @@ -80,21 +80,27 @@ typedef enum { MPP_DEC_CMD_END, MPP_ENC_CMD_BASE = CMD_MODULE_CODEC | CMD_CTX_ID_ENC, - MPP_ENC_SET_RC_CFG, - MPP_ENC_GET_RC_CFG, - MPP_ENC_SET_PREP_CFG, - MPP_ENC_GET_PREP_CFG, + /* legacy support for vpuapi */ + MPP_ENC_SET_CFG, + MPP_ENC_GET_CFG, + /* basic encoder setup control */ + MPP_ENC_SET_ALL_CFG, /* set MppEncCfgSet structure */ + MPP_ENC_GET_ALL_CFG, /* get MppEncCfgSet structure */ + MPP_ENC_SET_PREP_CFG, /* set MppEncPrepCfg structure */ + MPP_ENC_GET_PREP_CFG, /* get MppEncPrepCfg structure */ + MPP_ENC_SET_RC_CFG, /* set MppEncRcCfg structure */ + MPP_ENC_GET_RC_CFG, /* get MppEncRcCfg structure */ + MPP_ENC_SET_CODEC_CFG, /* set MppEncCodecCfg structure */ + MPP_ENC_GET_CODEC_CFG, /* get MppEncCodecCfg structure */ + /* runtime encoder setup control */ + MPP_ENC_SET_IDR_FRAME, /* next frame will be encoded as intra frame */ MPP_ENC_SET_OSD_PLT_CFG, /* set OSD palette, parameter should be pointer to MppEncOSDPlt */ MPP_ENC_SET_OSD_DATA_CFG, /* set OSD data with at most 8 regions, parameter should be pointer to MppEncOSDData */ MPP_ENC_GET_OSD_CFG, - MPP_ENC_SET_CFG, - MPP_ENC_GET_CFG, MPP_ENC_SET_EXTRA_INFO, - MPP_ENC_GET_EXTRA_INFO, - MPP_ENC_SET_FORMAT, - MPP_ENC_SET_IDR_FRAME, - MPP_ENC_SET_SEI_CFG, /*SEI: Supplement Enhancemant Information, parameter is MppSeiMode */ - MPP_ENC_GET_SEI_DATA, /*SEI: Supplement Enhancemant Information, parameter is MppPacket */ + MPP_ENC_GET_EXTRA_INFO, /* get vps / sps / pps from hal */ + MPP_ENC_SET_SEI_CFG, /* SEI: Supplement Enhancemant Information, parameter is MppSeiMode */ + MPP_ENC_GET_SEI_DATA, /* SEI: Supplement Enhancemant Information, parameter is MppPacket */ MPP_ENC_CMD_END, MPP_ISP_CMD_BASE = CMD_MODULE_CODEC | CMD_CTX_ID_ISP, @@ -168,10 +174,10 @@ typedef enum { * +----------init------------> | | * | | | | * | | | | - * | MppFrame | | | - * +---------control----------> MppFrame | | + * | PrepCfg | | | + * +---------control----------> PrepCfg | | * | +-----control-----> | - * | | | MppFrame | + * | | | PrepCfg | * | +--------------------------control--------> * | | | allocate * | | | buffer @@ -193,10 +199,6 @@ typedef enum { * +---------control----------> | | * | | | | * | | | | - * | PrepCfg | | | - * +---------control----------> | PrepCfg | - * | +--------------------------control--------> - * | | | | * | ROICfg | | | * +---------control----------> | ROICfg | * | +--------------------------control--------> @@ -240,93 +242,182 @@ typedef enum { /* * Rate control parameter - * - * rc_mode - rate control mode - * Mpp balances quality and bit rate by the mode index - * Mpp provide 5 level of balance mode of quality and bit rate - * 1 - only quality mode: only quality parameter takes effect - * 2 - more quality mode: quality parameter takes more effect - * 3 - balance mode : balance quality and bitrate 50 to 50 - * 4 - more bitrate mode: bitrate parameter takes more effect - * 5 - only bitrate mode: only bitrate parameter takes effect - * - * quality - quality parameter - * mpp does not give the direct parameter in different protocol. - * mpp provide total 5 quality level 1 ~ 5 - * 0 - auto - * 1 - worst - * 2 - worse - * 3 - medium - * 4 - better - * 5 - best - * - * bit rate parameters - * mpp gives three bit rate control parameter for control - * bps_target - target bit rate, unit: bit per second - * bps_max - maximun bit rate, unit: bit per second - * bps_min - minimun bit rate, unit: bit per second - * if user need constant bit rate set parameters to the similar value - * if user need variable bit rate set parameters as they need - * - * frame rate parameters have great effect on rate control - * all fps parameter is in 32bit - * low 16bit is denominator - * high 16bit is numerator - * if high 16bit is zero then the whole integer is just fps - * fps_in - input frame rate, unit: frame per second - * if 0 then default set to 30 - * fps_out - output frame rate, unit: frame per second - * if 0 then default set to fps_in - * gop - gap between Intra frame - * 0 for only 1 I frame the rest are all P frames - * 1 for all I frame - * 2 for I P I P I P - * 3 for I P P I P P - * etc... - * skip_cnt - max continuous frame skip count - * 0 - frame skip is not allow - * */ +typedef enum MppEncRcCfgChange_e { + MPP_ENC_RC_CFG_CHANGE_RC_MODE = (1 << 0), + MPP_ENC_RC_CFG_CHANGE_QUALITY = (1 << 1), + MPP_ENC_RC_CFG_CHANGE_BPS = (1 << 2), /* change on bps target / max / min */ + MPP_ENC_RC_CFG_CHANGE_FPS_IN = (1 << 5), /* change on fps in flex / numerator / denorminator */ + MPP_ENC_RC_CFG_CHANGE_FPS_OUT = (1 << 6), /* change on fps out flex / numerator / denorminator */ + MPP_ENC_RC_CFG_CHANGE_GOP = (1 << 7), + MPP_ENC_RC_CFG_CHANGE_SKIP_CNT = (1 << 8), + MPP_ENC_RC_CFG_CHANGE_ALL = (0xFFFFFFFF), +} MppEncRcCfgChange; + typedef struct MppEncRcCfg_t { + RK_U32 change; + + /* + * rc_mode - rate control mode + * Mpp balances quality and bit rate by the mode index + * Mpp provide 5 level of balance mode of quality and bit rate + * 1 - only quality mode: only quality parameter takes effect + * 2 - more quality mode: quality parameter takes more effect + * 3 - balance mode : balance quality and bitrate 50 to 50 + * 4 - more bitrate mode: bitrate parameter takes more effect + * 5 - only bitrate mode: only bitrate parameter takes effect + */ RK_S32 rc_mode; + + /* + * quality - quality parameter + * mpp does not give the direct parameter in different protocol. + * mpp provide total 5 quality level 1 ~ 5 + * 0 - auto + * 1 - worst + * 2 - worse + * 3 - medium + * 4 - better + * 5 - best + */ RK_S32 quality; + + /* + * bit rate parameters + * mpp gives three bit rate control parameter for control + * bps_target - target bit rate, unit: bit per second + * bps_max - maximun bit rate, unit: bit per second + * bps_min - minimun bit rate, unit: bit per second + * if user need constant bit rate set parameters to the similar value + * if user need variable bit rate set parameters as they need + */ RK_S32 bps_target; RK_S32 bps_max; RK_S32 bps_min; - RK_S32 fps_in; - RK_S32 fps_out; + + /* + * frame rate parameters have great effect on rate control + * + * fps_in_flex + * 0 - fix input frame rate + * 1 - variable input frame rate + * + * fps_in_num + * input frame rate numerator, if 0 then default 30 + * + * fps_in_denorm + * input frame rate denorminator, if 0 then default 1 + * + * fps_out_flex + * 0 - fix output frame rate + * 1 - variable output frame rate + * + * fps_out_num + * output frame rate numerator, if 0 then default 30 + * + * fps_out_denorm + * output frame rate denorminator, if 0 then default 1 + */ + RK_S32 fps_in_flex; + RK_S32 fps_in_num; + RK_S32 fps_in_denorm; + RK_S32 fps_out_flex; + RK_S32 fps_out_num; + RK_S32 fps_out_denorm; + + /* + * gop - group of picture, gap between Intra frame + * 0 for only 1 I frame the rest are all P frames + * 1 for all I frame + * 2 for I P I P I P + * 3 for I P P I P P + * etc... + */ RK_S32 gop; + + /* + * skip_cnt - max continuous frame skip count + * 0 - frame skip is not allow + */ RK_S32 skip_cnt; } MppEncRcCfg; -/* - * Mpp frame parameter - * direct use MppFrame to store information - */ - -/* - * Mpp codec parameter - * parameter is defined in different syntax header - */ - /* * Mpp preprocess parameter */ -typedef struct MppEncPrepCfg_t { - MppFrameFormat format_in; - MppFrameFormat format_out; - RK_U32 rotation; +typedef enum MppEncPrepCfgChange_e { + MPP_ENC_PREP_CFG_CHANGE_INPUT = (1 << 0), /* change on input config */ + MPP_ENC_PREP_CFG_CHANGE_FORMAT = (1 << 2), /* change on format */ + /* transform parameter */ + MPP_ENC_PREP_CFG_CHANGE_ROTATION = (1 << 4), /* change on ration */ + MPP_ENC_PREP_CFG_CHANGE_MIRRORING = (1 << 5), /* change on mirroring */ + /* enhancement parameter */ + MPP_ENC_PREP_CFG_CHANGE_DENOISE = (1 << 8), /* change on denoise */ + MPP_ENC_PREP_CFG_CHANGE_SHARPEN = (1 << 9), /* change on denoise */ + MPP_ENC_PREP_CFG_CHANGE_ALL = (0xFFFFFFFF), +} MppEncPrepCfgChange; - // sharpen - RK_U32 src_shp_en_y; - RK_U32 src_shp_en_uv; - RK_U32 src_shp_thr; - RK_U32 src_shp_div; - RK_U32 src_shp_w0; - RK_U32 src_shp_w1; - RK_U32 src_shp_w2; - RK_U32 src_shp_w3; - RK_U32 src_shp_w4; +/* + * Preprocess sharpen parameter + * + * 5x5 sharpen core + * + * enable_y - enable luma sharpen + * enable_c - enable chroma sharpen + */ +typedef struct { + RK_U32 enable_y; + RK_U32 enable_uv; + RK_S32 coef[5]; + RK_S32 div; + RK_S32 threshold; +} MppEncPrepSharpenCfg; + +typedef struct MppEncPrepCfg_t { + RK_U32 change; + + /* + * Mpp encoder input data dimension config + * + * width / height / hor_stride / ver_stride / format + * These information will be used for buffer allocation and rc config init + * The output format is always YUV420. So if input is RGB then color + * conversion will be done internally + */ + RK_S32 width; + RK_S32 height; + RK_S32 hor_stride; + RK_S32 ver_stride; + + /* + * Mpp encoder input data format config + */ + MppFrameFormat format; + MppFrameColorSpace color; + + /* + * input frame rotation parameter + * 0 - disable rotation + * 1 - 90 degree + * 2 - 180 degree + * 3 - 270 degree + */ + RK_S32 rotation; + + /* + * input frame mirroring parameter + * 0 - disable mirroring + * 1 - horizontal mirroring + * 2 - vertical mirroring + */ + RK_S32 mirroring; + + /* + * TODO: + */ + RK_S32 denoise; + + MppEncPrepSharpenCfg sharpen; } MppEncPrepCfg; /* @@ -419,4 +510,323 @@ typedef struct MppEncMDBlkInfo_t { RK_S32 mvy : 8; /* bit 24~31 - signed vertical mv */ } MppEncMDBlkInfo; +/* + * Mpp video codec related configuration + */ +typedef struct MppEncHwCfg_t { + RK_U32 change; + RK_S32 me_search_range_x; + RK_S32 me_search_range_y; +} MppEncHwCfg; + + +/* + * Mpp codec parameter + * parameter is defined from here + */ + +/* + * H.264 configurable parameter + */ +typedef struct MppEncH264VuiCfg_t { + RK_U32 change; + + RK_U32 b_vui; + + RK_S32 b_aspect_ratio_info_present; + RK_S32 i_sar_width; + RK_S32 i_sar_height; + + RK_S32 b_overscan_info_present; + RK_S32 b_overscan_info; + + RK_S32 b_signal_type_present; + RK_S32 i_vidformat; + RK_S32 b_fullrange; + RK_S32 b_color_description_present; + RK_S32 i_colorprim; + RK_S32 i_transfer; + RK_S32 i_colmatrix; + + RK_S32 b_chroma_loc_info_present; + RK_S32 i_chroma_loc_top; + RK_S32 i_chroma_loc_bottom; + + RK_S32 b_timing_info_present; + RK_U32 i_num_units_in_tick; + RK_U32 i_time_scale; + RK_S32 b_fixed_frame_rate; + + RK_S32 b_nal_hrd_parameters_present; + RK_S32 b_vcl_hrd_parameters_present; + + struct { + RK_S32 i_cpb_cnt; + RK_S32 i_bit_rate_scale; + RK_S32 i_cpb_size_scale; + RK_S32 i_bit_rate_value; + RK_S32 i_cpb_size_value; + RK_S32 i_bit_rate_unscaled; + RK_S32 i_cpb_size_unscaled; + RK_S32 b_cbr_hrd; + + RK_S32 i_initial_cpb_removal_delay_length; + RK_S32 i_cpb_removal_delay_length; + RK_S32 i_dpb_output_delay_length; + RK_S32 i_time_offset_length; + } hrd; + + RK_S32 b_pic_struct_present; + RK_S32 b_bitstream_restriction; + RK_S32 b_motion_vectors_over_pic_boundaries; + RK_S32 i_max_bytes_per_pic_denom; + RK_S32 i_max_bits_per_mb_denom; + RK_S32 i_log2_max_mv_length_horizontal; + RK_S32 i_log2_max_mv_length_vertical; + RK_S32 i_num_reorder_frames; + RK_S32 i_max_dec_frame_buffering; + + /* FIXME to complete */ +} MppEncH264VuiCfg; + +typedef struct MppEncH264RefCfg_t { + RK_S32 i_frame_reference; /* Maximum number of reference frames */ + RK_S32 i_ref_pos; + RK_S32 i_long_term_en; + RK_S32 i_long_term_internal; + RK_S32 hw_longterm_mode; + RK_S32 i_dpb_size; /* Force a DPB size larger than that implied by B-frames and reference frames. + * Useful in combination with interactive error resilience. */ + RK_S32 i_frame_packing; +} MppEncH264RefCfg; + +typedef struct MppEncH264SeiCfg_t { + RK_U32 change; +} MppEncH264SeiCfg; + +typedef enum MppEncH264CfgChange_e { + /* change on stream type */ + MPP_ENC_H264_CFG_STREAM_TYPE = (1 << 0), + /* change on svc / profile / level */ + MPP_ENC_H264_CFG_CHANGE_PROFILE = (1 << 1), + /* change on entropy_coding_mode / cabac_init_idc */ + MPP_ENC_H264_CFG_CHANGE_ENTROPY = (1 << 2), + + /* change on transform8x8_mode */ + MPP_ENC_H264_CFG_CHANGE_TRANS_8x8 = (1 << 4), + /* change on constrained_intra_pred_mode */ + MPP_ENC_H264_CFG_CHANGE_CONST_INTRA = (1 << 5), + /* change on chroma_cb_qp_offset/ chroma_cr_qp_offset */ + MPP_ENC_H264_CFG_CHANGE_CHROMA_QP = (1 << 6), + /* change on deblock_disable / deblock_offset_alpha / deblock_offset_beta */ + MPP_ENC_H264_CFG_CHANGE_DEBLOCKING = (1 << 7), + /* change on use_longterm */ + MPP_ENC_H264_CFG_CHANGE_LONG_TERM = (1 << 8), + + /* change on max_qp / min_qp / max_qp_step */ + MPP_ENC_H264_CFG_CHANGE_QP_LIMIT = (1 << 16), + /* change on intra_refresh_mode / intra_refresh_arg */ + MPP_ENC_H264_CFG_CHANGE_INTRA_REFRESH = (1 << 17), + /* change on slice_mode / slice_arg */ + MPP_ENC_H264_CFG_CHANGE_SLICE_MODE = (1 << 18), + + /* change on vui */ + MPP_ENC_H264_CFG_CHANGE_VUI = (1 << 28), + /* change on sei */ + MPP_ENC_H264_CFG_CHANGE_SEI = (1 << 29), + MPP_ENC_H264_CFG_CHANGE_REF = (1 << 30), + MPP_ENC_H264_CFG_CHANGE_ALL = (0xFFFFFFFF), +} MppEncH264CfgChange; + +typedef struct MppEncH264Cfg_t { + RK_U32 change; + + /* + * H.264 stream format + * 0 - H.264 Annex B: NAL unit starts with '00 00 00 01' + * 1 - Plain NAL units without startcode + */ + RK_S32 stream_type; + + /* H.264 codec syntax config */ + RK_S32 svc; /* 0 - avc 1 - svc */ + + /* + * H.264 profile_idc parameter + * 66 - Baseline profile + * 77 - Main profile + * 100 - High profile + */ + RK_S32 profile; + + /* + * H.264 level_idc parameter + * 10 / 11 / 12 / 13 - qcif@15fps / cif@7.5fps / cif@15fps / cif@30fps + * 20 / 21 / 22 - cif@30fps / half-D1@@25fps / D1@12.5fps + * 30 / 31 / 32 - D1@25fps / 720p@30fps / 720p@60fps + * 40 / 41 / 42 - 1080p@30fps / 1080p@30fps / 1080p@60fps + * 50 / 51 / 52 - 4K@30fps + */ + RK_S32 level; + + /* + * H.264 entropy coding method + * 0 - CAVLC + * 1 - CABAC + * When CABAC is select cabac_init_idc can be range 0~2 + */ + RK_S32 entropy_coding_mode; + RK_S32 cabac_init_idc; + + /* + * 8x8 intra prediction and 8x8 transform enable flag + * This flag can only be enable under High profile + * 0 : disable (BP/MP) + * 1 : enable (HP) + */ + RK_S32 transform8x8_mode; + + /* + * 0 : disable + * 1 : enable + */ + RK_S32 constrained_intra_pred_mode; + + /* + * chroma qp offset (-12 - 12) + */ + RK_S32 chroma_cb_qp_offset; + RK_S32 chroma_cr_qp_offset; + + /* + * H.264 deblock filter mode flag + * 0 : enable + * 1 : disable + * 2 : disable deblocking filter at slice boundaries + * + * deblock filter offset alpha (-6 - 6) + * deblock filter offset beta (-6 - 6) + */ + RK_S32 deblock_disable; + RK_S32 deblock_offset_alpha; + RK_S32 deblock_offset_beta; + + /* + * H.264 long term reference picture enable flag + * 0 - disable + * 1 - enable + */ + RK_S32 use_longterm; + + /* + * quality config + * qp_max - 8 ~ 51 + * qp_min - 0 ~ 48 + * qp_max_step - max delta qp step between two frames + */ + RK_S32 qp_init; + RK_S32 qp_max; + RK_S32 qp_min; + RK_S32 qp_max_step; + + /* + * intra fresh config + * + * intra_refresh_mode + * 0 - no intra refresh + * 1 - intra refresh by MB row + * 2 - intra refresh by MB column + * 3 - intra refresh by MB gap + * + * intra_refresh_arg + * mode 0 - no effect + * mode 1 - refresh MB row number + * mode 2 - refresh MB colmn number + * mode 3 - refresh MB gap count + */ + RK_S32 intra_refresh_mode; + RK_S32 intra_refresh_arg; + + /* slice mode config */ + RK_S32 slice_mode; + RK_S32 slice_arg; + + /* extra info */ + MppEncH264VuiCfg vui; + MppEncH264SeiCfg sei; + MppEncH264RefCfg ref; +} MppEncH264Cfg; + +/* + * H.265 configurable parameter + */ +typedef struct MppEncH265VuiCfg_t { + RK_U32 change; + RK_S32 vui_present; + RK_S32 vui_aspect_ratio; + RK_S32 vui_sar_size; + RK_S32 full_range; + RK_S32 time_scale; +} MppEncH265VuiCfg; + +typedef struct MppEncH265SeiCfg_t { + RK_U32 change; +} MppEncH265SeiCfg; + +typedef struct MppEncH265Cfg_t { + RK_U32 change; + + /* H.265 codec syntax config */ + RK_S32 profile; + RK_S32 level; + RK_S32 tier; + RK_S32 const_intra_pred; /* constraint intra prediction flag */ + RK_S32 ctu_size; + RK_S32 tmvp_enable; + RK_S32 wpp_enable; + RK_S32 merge_range; + RK_S32 sao_enable; + + /* quality config */ + RK_S32 max_qp; + RK_S32 min_qp; + RK_S32 max_delta_qp; + + /* intra fresh config */ + RK_S32 intra_refresh_mode; + RK_S32 intra_refresh_arg; + + /* slice mode config */ + RK_S32 independ_slice_mode; + RK_S32 independ_slice_arg; + RK_S32 depend_slice_mode; + RK_S32 depend_slice_arg; + + /* extra info */ + MppEncH265VuiCfg vui; + MppEncH265SeiCfg sei; +} MppEncH265Cfg; + +/* + * motion jpeg configurable parameter + */ +typedef enum MppEncJpegCfgChange_e { + /* change on quant parameter */ + MPP_ENC_JPEG_CFG_CHANGE_QP = (1 << 0), + MPP_ENC_JPEG_CFG_CHANGE_ALL = (0xFFFFFFFF), +} MppEncJpegCfgChange; + +typedef struct MppEncJpegCfg_t { + RK_U32 change; + RK_S32 quant; +} MppEncJpegCfg; + +/* + * vp8 configurable parameter + */ +typedef struct MppEncVp8Cfg_t { + RK_U32 change; + RK_S32 quant; +} MppEncVp8Cfg; + #endif /*__RK_MPI_CMD_H__*/ diff --git a/mpp/CMakeLists.txt b/mpp/CMakeLists.txt index 4c37c4a7..49146d86 100644 --- a/mpp/CMakeLists.txt +++ b/mpp/CMakeLists.txt @@ -12,6 +12,7 @@ include_directories(common) include_directories(base/inc) include_directories(codec/inc) include_directories(hal/inc) +include_directories(hal/common) # ---------------------------------------------------------------------------- # add mpp base component diff --git a/mpp/codec/CMakeLists.txt b/mpp/codec/CMakeLists.txt index 460ad78a..0477c44c 100644 --- a/mpp/codec/CMakeLists.txt +++ b/mpp/codec/CMakeLists.txt @@ -10,6 +10,8 @@ add_library(mpp_codec STATIC mpp_parser.cpp ) +add_library(mpp_rc STATIC mpp_rc.cpp) + set_target_properties(mpp_codec PROPERTIES FOLDER "mpp/codec") add_subdirectory(dec) diff --git a/mpp/codec/enc/h264/CMakeLists.txt b/mpp/codec/enc/h264/CMakeLists.txt index c19d6a6a..71946e5a 100644 --- a/mpp/codec/enc/h264/CMakeLists.txt +++ b/mpp/codec/enc/h264/CMakeLists.txt @@ -10,42 +10,12 @@ set(H264E_COMMON # h264 encoder header set(H264E_HDR - include/H264CodeFrame.h - include/H264Init.h - include/H264Instance.h - include/H264Mad.h - include/H264NalUnit.h - include/H264PictureParameterSet.h - include/H264PutBits.h - include/H264RateControl.h - include/H264Sei.h - include/H264SequenceParameterSet.h - include/H264Slice.h - include/encasiccontroller.h - include/enccommon.h - include/encpreprocess.h - include/h264encapi.h include/h264e_codec.h - include/h264e_utils.h ) # h264 encoder sourse set(H264E_SRC - src/H264CodeFrame.c - src/H264EncApi.c - src/H264Init.c - src/H264Mad.c - src/H264NalUnit.c - src/H264PictureParameterSet.c - src/H264PutBits.c - src/H264RateControl.c - src/H264Sei.c - src/H264SequenceParameterSet.c - src/H264Slice.c - src/encasiccontroller.c - src/encpreprocess.c src/h264e_api.c - src/h264e_utils.c ) @@ -56,5 +26,5 @@ add_library(${CODEC_H264E} STATIC ${H264E_SRC} ) -target_link_libraries(${CODEC_H264E} mpp_base) +target_link_libraries(${CODEC_H264E} mpp_rc mpp_base) set_target_properties(${CODEC_H264E} PROPERTIES FOLDER "mpp/codec") diff --git a/mpp/codec/enc/h264/include/H264CodeFrame.h b/mpp/codec/enc/h264/include/H264CodeFrame.h deleted file mode 100644 index 2a994069..00000000 --- a/mpp/codec/enc/h264/include/H264CodeFrame.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * 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. - */ - -#ifndef __H264_CODE_FRAME_H__ -#define __H264_CODE_FRAME_H__ - -/*------------------------------------------------------------------------------ - 1. Include headers -------------------------------------------------------------------------------*/ -#include "H264Instance.h" -#include "H264Slice.h" -#include "H264RateControl.h" -#include "encasiccontroller.h" - -/*------------------------------------------------------------------------------ - 2. External compiler flags --------------------------------------------------------------------------------- - --------------------------------------------------------------------------------- - 3. Module defines -------------------------------------------------------------------------------*/ - -typedef enum { - H264ENCODE_OK = 0, - H264ENCODE_TIMEOUT = 1, - H264ENCODE_DATA_ERROR = 2, - H264ENCODE_HW_ERROR = 3, - H264ENCODE_SYSTEM_ERROR = 4, - H264ENCODE_HW_RESET = 5 -} h264EncodeFrame_e; - -/*------------------------------------------------------------------------------ - 4. Function prototypes -------------------------------------------------------------------------------*/ -void H264CodeFrame(H264ECtx * inst, h264e_syntax *syntax_data); - -#endif diff --git a/mpp/codec/enc/h264/include/H264Init.h b/mpp/codec/enc/h264/include/H264Init.h deleted file mode 100644 index 4a5f5d3e..00000000 --- a/mpp/codec/enc/h264/include/H264Init.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * 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. - */ - -#ifndef __H264_INIT_H__ -#define __H264_INIT_H__ - -#include "h264encapi.h" -#include "H264Instance.h" - -RK_S32 H264GetAllowedWidth(RK_S32 width, MppFrameFormat inputType); - -H264EncRet H264Init(H264ECtx * pinst); -H264EncRet H264Cfg(const H264EncConfig * pEncCfg, H264ECtx * pinst); - -#endif diff --git a/mpp/codec/enc/h264/include/H264Instance.h b/mpp/codec/enc/h264/include/H264Instance.h deleted file mode 100644 index 5ade18cc..00000000 --- a/mpp/codec/enc/h264/include/H264Instance.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * 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. - */ - -#ifndef __H264_INSTANCE_H__ -#define __H264_INSTANCE_H__ - -#include "mpp_log.h" - -#include "h264_syntax.h" - - -#include "enccommon.h" -#include "encpreprocess.h" -#include "encasiccontroller.h" - -#include "H264SequenceParameterSet.h" -#include "H264PictureParameterSet.h" -#include "H264Slice.h" -#include "H264RateControl.h" -#include "H264Mad.h" - -#include "h264encapi.h" - - -#endif diff --git a/mpp/codec/enc/h264/include/H264Mad.h b/mpp/codec/enc/h264/include/H264Mad.h deleted file mode 100644 index 46e79c84..00000000 --- a/mpp/codec/enc/h264/include/H264Mad.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * 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. - */ - -#ifndef H264_MAD_H -#define H264_MAD_H - -#include "enccommon.h" - -#define DSCY 32 /* n * 32 */ -#define I32_MAX 2147483647 /* 2 ^ 31 - 1 */ -#define DIV(a, b) (((a) + (SIGN(a) * (b)) / 2) / (b)) -#define MAD_TABLE_LEN 5 - -typedef struct { - RK_S32 a1; /* model parameter, y = a1*x + a2 */ - RK_S32 a2; /* model parameter */ - RK_S32 th[MAD_TABLE_LEN]; /* mad threshold */ - RK_S32 count[MAD_TABLE_LEN]; /* number of macroblocks under threshold */ - RK_S32 pos; /* current position */ - RK_S32 len; /* current lenght */ - RK_S32 threshold; /* current frame threshold */ - RK_S32 mbPerFrame; /* number of macroblocks per frame */ -} madTable_s; - -/*------------------------------------------------------------------------------ - Function prototypes -------------------------------------------------------------------------------*/ - -void H264MadInit(madTable_s *mad, RK_U32 mbPerFrame); - -void H264MadThreshold(madTable_s *madTable, RK_U32 madCount); - -#endif - diff --git a/mpp/codec/enc/h264/include/H264NalUnit.h b/mpp/codec/enc/h264/include/H264NalUnit.h deleted file mode 100644 index 6a3e72a8..00000000 --- a/mpp/codec/enc/h264/include/H264NalUnit.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * 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. - */ - -#ifndef __H264_NAL_UNIT_H__ -#define __H264_NAL_UNIT_H__ - -/*------------------------------------------------------------------------------ - 1. Include headers -------------------------------------------------------------------------------*/ -#include "H264PutBits.h" - -/*------------------------------------------------------------------------------ - 2. External compiler flags --------------------------------------------------------------------------------- - --------------------------------------------------------------------------------- - 3. Module defines -------------------------------------------------------------------------------*/ - -/*------------------------------------------------------------------------------ - 4. Function prototypes -------------------------------------------------------------------------------*/ -void H264NalUnitHdr(stream_s * stream, RK_S32 nalRefIdc, nalUnitType_e - nalUnitType, true_e byteStream); -void H264NalUnitTrailinBits(stream_s * stream, true_e byteStream); -RK_U32 H264FillerNALU(stream_s * sp, RK_S32 cnt, true_e byteStream); - -#endif diff --git a/mpp/codec/enc/h264/include/H264PictureParameterSet.h b/mpp/codec/enc/h264/include/H264PictureParameterSet.h deleted file mode 100644 index 76fb3f7d..00000000 --- a/mpp/codec/enc/h264/include/H264PictureParameterSet.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * 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. - */ - -#ifndef __H264_PICTURE_PARAMETER_SET_H__ -#define __H264_PICTURE_PARAMETER_SET_H__ - -/*------------------------------------------------------------------------------ - 1. Include headers -------------------------------------------------------------------------------*/ -#include "enccommon.h" -#include "H264PutBits.h" - -/*------------------------------------------------------------------------------ - 2. External compiler flags --------------------------------------------------------------------------------- - --------------------------------------------------------------------------------- - 3. Module defines -------------------------------------------------------------------------------*/ -typedef struct { - true_e byteStream; - RK_S32 picParameterSetId; - RK_S32 seqParameterSetId; - true_e entropyCodingMode; - true_e picOrderPresent; - RK_S32 numSliceGroupsMinus1; - RK_S32 numRefIdxL0ActiveMinus1; - RK_S32 numRefIdxL1ActiveMinus1; - true_e weightedPred; - RK_S32 weightedBipredIdc; - RK_S32 picInitQpMinus26; - RK_S32 picInitQsMinus26; - RK_S32 chromaQpIndexOffset; - true_e deblockingFilterControlPresent; - true_e constIntraPred; - true_e redundantPicCntPresent; - true_e transform8x8Mode; -} pps_s; - -/*------------------------------------------------------------------------------ - 4. Function prototypes -------------------------------------------------------------------------------*/ -void H264PicParameterSetInit(pps_s * pps); -void H264PicParameterSet(stream_s * stream, pps_s * pps); - -#endif diff --git a/mpp/codec/enc/h264/include/H264PutBits.h b/mpp/codec/enc/h264/include/H264PutBits.h deleted file mode 100644 index 693e13fa..00000000 --- a/mpp/codec/enc/h264/include/H264PutBits.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * 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. - */ - -#ifndef __H264_PUT_BITS_H__ -#define __H264_PUT_BITS_H__ - -/*------------------------------------------------------------------------------ - 1. Include headers -------------------------------------------------------------------------------*/ -#include "enccommon.h" -/*------------------------------------------------------------------------------ - 2. External compiler flags --------------------------------------------------------------------------------- - --------------------------------------------------------------------------------- - 3. Module defines -------------------------------------------------------------------------------*/ - -#define H264NalBits(stream, val, num) H264PutNalBits(stream, val, num) - -/*------------------------------------------------------------------------------ - 4. Function prototypes -------------------------------------------------------------------------------*/ -bool_e H264SetBuffer(stream_s * buffer, RK_U8 * stream, RK_S32 size); -void H264PutBits(stream_s *, RK_S32, RK_S32); -void H264PutNalBits(stream_s *, RK_S32, RK_S32); -void H264ExpGolombUnsigned(stream_s * stream, RK_U32 val); -void H264ExpGolombSigned(stream_s * stream, RK_S32 val); -void H264RbspTrailingBits(stream_s * stream); -void H264Comment(char *comment); - -#endif diff --git a/mpp/codec/enc/h264/include/H264RateControl.h b/mpp/codec/enc/h264/include/H264RateControl.h deleted file mode 100644 index 6a35ee6f..00000000 --- a/mpp/codec/enc/h264/include/H264RateControl.h +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * 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. - */ - -#ifndef H264_RATE_CONTROL_H -#define H264_RATE_CONTROL_H - -#include "enccommon.h" -#include "H264Sei.h" - -enum -{ H264RC_OVERFLOW = -1 }; - -#define RC_CBR_HRD 0 /* 1 = Constant bit rate model. Must use filler - * data to conform */ - -#define CTRL_LEVELS 7 /* DO NOT CHANGE THIS */ -#define CHECK_POINTS_MAX 10 /* DO NOT CHANGE THIS */ -#define RC_TABLE_LENGTH 10 /* DO NOT CHANGE THIS */ - -typedef struct { - RK_S32 a1; /* model parameter */ - RK_S32 a2; /* model parameter */ - RK_S32 qp_prev; /* previous QP */ - RK_S32 qs[15]; /* quantization step size */ - RK_S32 bits[15]; /* Number of bits needed to code residual */ - RK_S32 pos; /* current position */ - RK_S32 len; /* current lenght */ - RK_S32 zero_div; /* a1 divisor is 0 */ -} linReg_s; - -typedef struct { - RK_S32 wordError[CTRL_LEVELS]; /* Check point error bit */ - RK_S32 qpChange[CTRL_LEVELS]; /* Check point qp difference */ - RK_S32 wordCntTarget[CHECK_POINTS_MAX]; /* Required bit count */ - RK_S32 wordCntPrev[CHECK_POINTS_MAX]; /* Real bit count */ - RK_S32 checkPointDistance; - RK_S32 checkPoints; -} h264QpCtrl_s; - -/* Virtual buffer */ -typedef struct { - RK_S32 bufferSize; /* size of the virtual buffer */ - RK_S32 bitRate; /* input bit rate per second */ - RK_S32 bitPerPic; /* average number of bits per picture */ - RK_S32 picTimeInc; /* timeInc since last coded picture */ - RK_S32 timeScale; /* input frame rate numerator */ - RK_S32 unitsInTic; /* input frame rate denominator */ - RK_S32 virtualBitCnt; /* virtual (channel) bit count */ - RK_S32 realBitCnt; /* real bit count */ - RK_S32 bufferOccupancy; /* number of bits in the buffer */ - RK_S32 skipFrameTarget; /* how many frames should be skipped in a row */ - RK_S32 skippedFrames; /* how many frames have been skipped in a row */ - RK_S32 nonZeroTarget; - RK_S32 bucketFullness; /* Leaky Bucket fullness */ - /* new rate control */ - RK_S32 gopRem; - RK_S32 windowRem; -} h264VirtualBuffer_s; - -typedef struct { - true_e picRc; - true_e mbRc; /* Mb header qp can vary, check point rc */ - true_e picSkip; /* Frame Skip enable */ - true_e hrd; /* HRD restrictions followed or not */ - RK_U32 fillerIdx; - RK_S32 mbPerPic; /* Number of macroblock per picture */ - RK_S32 mbRows; /* MB rows in picture */ - RK_S32 coeffCntMax; /* Number of coeff per picture */ - RK_S32 nonZeroCnt; - RK_S32 srcPrm; /* Source parameter */ - RK_S32 qpSum; /* Qp sum counter */ - RK_U32 sliceTypeCur; - RK_U32 sliceTypePrev; - true_e frameCoded; /* Pic coded information */ - RK_S32 fixedQp; /* Pic header qp when fixed */ - RK_S32 qpHdr; /* Pic header qp of current voded picture */ - RK_S32 qpMin; /* Pic header minimum qp, user set */ - RK_S32 qpMax; /* Pic header maximum qp, user set */ - RK_S32 qpHdrPrev; /* Pic header qp of previous coded picture */ - RK_S32 qpLastCoded; /* Quantization parameter of last coded mb */ - RK_S32 qpTarget; /* Target quantrization parameter */ - RK_U32 estTimeInc; - RK_S32 outRateNum; - RK_S32 outRateDenom; - RK_S32 gDelaySum; - RK_S32 gInitialDelay; - RK_S32 gInitialDoffs; - h264QpCtrl_s qpCtrl; - h264VirtualBuffer_s virtualBuffer; - sei_s sei; - RK_S32 gBufferMin, gBufferMax; - /* new rate control */ - linReg_s linReg; /* Data for R-Q model */ - linReg_s overhead; - linReg_s rError; /* Rate prediction error (bits) */ - RK_S32 targetPicSize; - RK_S32 sad; - RK_S32 frameBitCnt; - /* for gop rate control */ - RK_S32 gopQpSum; - RK_S32 gopQpDiv; - RK_U32 frameCnt; - RK_S32 gopLen; - true_e roiRc; - RK_S32 roiQpHdr; - RK_S32 roiQpDelta; - RK_S32 roiStart; - RK_S32 roiLength; - RK_S32 intraQpDelta; - RK_U32 fixedIntraQp; - RK_S32 mbQpAdjustment; /* QP delta for MAD macroblock QP adjustment */ - - //add for rk30 new ratecontrol - linReg_s intra; /* Data for intra frames */ - linReg_s intraError; /* Prediction error for intra frames */ - linReg_s gop; /* Data for GOP */ - - RK_S32 gopBitCnt; /* Current GOP bit count so far */ - RK_S32 gopAvgBitCnt; /* Previous GOP average bit count */ - - RK_S32 windowLen; /* Bitrate window which tries to match target */ - RK_S32 intraInterval; /* Distance between two previous I-frames */ - RK_S32 intraIntervalCtr; -} h264RateControl_s; - -/*------------------------------------------------------------------------------ - Function prototypes -------------------------------------------------------------------------------*/ - -RK_U32 H264FillerRc(h264RateControl_s * rc, RK_U32 frameCnt); -RK_S32 H264Calculate(RK_S32 a, RK_S32 b, RK_S32 c); - -bool_e H264InitRc(h264RateControl_s * rc); -void H264BeforePicRc(h264RateControl_s * rc, RK_U32 timeInc, RK_U32 sliceType); -RK_S32 H264AfterPicRc(h264RateControl_s * rc, RK_U32 nonZeroCnt, RK_U32 byteCnt, - RK_U32 qpSum); -#endif /* H264_RATE_CONTROL_H */ - diff --git a/mpp/codec/enc/h264/include/H264Sei.h b/mpp/codec/enc/h264/include/H264Sei.h deleted file mode 100644 index 1a976875..00000000 --- a/mpp/codec/enc/h264/include/H264Sei.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * 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. - */ - -#ifndef H264_SEI_H -#define H264_SEI_H - -#include "H264PutBits.h" - -typedef struct { - RK_U32 fts; /* Full time stamp */ - RK_U32 timeScale; - RK_U32 nuit; /* number of units in tick */ - RK_U32 time; /* Modulo time */ - RK_U32 secf; - RK_U32 sec; /* Seconds */ - RK_U32 minf; - RK_U32 min; /* Minutes */ - RK_U32 hrf; - RK_U32 hr; /* Hours */ -} timeStamp_s; - -typedef struct { - timeStamp_s ts; - RK_U32 nalUnitSize; - RK_U32 enabled; - true_e byteStream; - RK_U32 hrd; /* HRD conformance */ - RK_U32 seqId; - RK_U32 icrd; /* initial cpb removal delay */ - RK_U32 icrdLen; - RK_U32 icrdo; /* initial cpb removal delay offset */ - RK_U32 icrdoLen; - RK_U32 crd; /* CPB removal delay */ - RK_U32 crdLen; - RK_U32 dod; /* DPB removal delay */ - RK_U32 dodLen; - RK_U32 psp; - RK_U32 ps; - RK_U32 cts; - RK_U32 cntType; - RK_U32 cdf; - RK_U32 nframes; - RK_U32 toffs; - RK_U32 toffsLen; - RK_U32 userDataEnabled; - const RK_U8 * pUserData; - RK_U32 userDataSize; -} sei_s; - -void H264InitSei(sei_s * sei, true_e byteStream, RK_U32 hrd, RK_U32 timeScale, - RK_U32 nuit); -void H264UpdateSeiTS(sei_s * sei, RK_U32 timeInc); -void H264FillerSei(stream_s * sp, sei_s * sei, RK_S32 cnt); -void H264BufferingSei(stream_s * stream, sei_s * sei); -void H264PicTimingSei(stream_s * stream, sei_s * sei); -void H264UserDataUnregSei(stream_s * sp, sei_s * sei); - -#endif diff --git a/mpp/codec/enc/h264/include/H264SequenceParameterSet.h b/mpp/codec/enc/h264/include/H264SequenceParameterSet.h deleted file mode 100644 index f53e0e62..00000000 --- a/mpp/codec/enc/h264/include/H264SequenceParameterSet.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * 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. - */ - -#ifndef __H264_SEQUENCE_PARAMETER_SET_h__ -#define __H264_SEQUENCE_PARAMETER_SET_h__ - -/*------------------------------------------------------------------------------ - 1. Include headers -------------------------------------------------------------------------------*/ -#include "enccommon.h" -#include "H264PutBits.h" -#include "H264Slice.h" - -/*------------------------------------------------------------------------------ - 2. External compiler flags --------------------------------------------------------------------------------- - --------------------------------------------------------------------------------- - 3. Module defines -------------------------------------------------------------------------------*/ - -typedef struct { - RK_U32 timeScale; - RK_U32 numUnitsInTick; - RK_U32 bitStreamRestrictionFlag; - RK_U32 videoFullRange; - RK_U32 sarWidth; - RK_U32 sarHeight; - RK_U32 nalHrdParametersPresentFlag; - RK_U32 vclHrdParametersPresentFlag; - RK_U32 pictStructPresentFlag; - RK_U32 initialCpbRemovalDelayLength; - RK_U32 cpbRemovalDelayLength; - RK_U32 dpbOutputDelayLength; - RK_U32 timeOffsetLength; - RK_U32 bitRate; - RK_U32 cpbSize; -} vui_t; - -typedef struct { - true_e byteStream; - RK_U32 profileIdc; - true_e constraintSet0; - true_e constraintSet1; - true_e constraintSet2; - true_e constraintSet3; - RK_U32 levelIdc; - RK_U32 levelIdx; - RK_U32 seqParameterSetId; - RK_S32 log2MaxFrameNumMinus4; - RK_U32 picOrderCntType; - RK_U32 numRefFrames; - true_e gapsInFrameNumValueAllowed; - RK_S32 picWidthInMbsMinus1; - RK_S32 picHeightInMapUnitsMinus1; - true_e frameMbsOnly; - true_e direct8x8Inference; - true_e frameCropping; - true_e vuiParametersPresent; - vui_t vui; - RK_U32 frameCropLeftOffset; - RK_U32 frameCropRightOffset; - RK_U32 frameCropTopOffset; - RK_U32 frameCropBottomOffset; -} sps_s; - -extern const RK_U32 H264LevelIdc[]; -extern const RK_U32 H264MaxCPBS[]; -extern const RK_U32 H264MaxFS[]; -extern const RK_U32 H264SqrtMaxFS8[]; -extern const RK_U32 H264MaxMBPS[]; -extern const RK_U32 H264MaxBR[]; - -#define INVALID_LEVEL 0xFFFF - -/*------------------------------------------------------------------------------ - 4. Function prototypes -------------------------------------------------------------------------------*/ -void H264SeqParameterSetInit(sps_s * sps); -void H264SeqParameterSet(stream_s * stream, sps_s * sps); - -void H264EndOfSequence(stream_s * stream, sps_s * sps); -void H264EndOfStream(stream_s * stream, sps_s * sps); - -RK_U32 H264GetLevelIndex(RK_U32 levelIdc); - -bool_e H264CheckLevel(sps_s * sps, RK_S32 bitRate, RK_S32 frameRateNum, - RK_S32 frameRateDenom); - -void H264SpsSetVuiTimigInfo(sps_s * sps, RK_U32 timeScale, RK_U32 numUnitsInTick); -void H264SpsSetVuiVideoInfo(sps_s * sps, RK_U32 videoFullRange); -void H264SpsSetVuiAspectRatio(sps_s * sps, RK_U32 sampleAspectRatioWidth, - RK_U32 sampleAspectRatioHeight); -void H264SpsSetVuiPictStructPresentFlag(sps_s * sps, RK_U32 flag); -void H264SpsSetVuiHrd(sps_s * sps, RK_U32 present); -void H264SpsSetVuiHrdBitRate(sps_s * sps, RK_U32 bitRate); -void H264SpsSetVuiHrdCpbSize(sps_s * sps, RK_U32 cpbSize); -RK_U32 H264SpsGetVuiHrdBitRate(sps_s * sps); -RK_U32 H264SpsGetVuiHrdCpbSize(sps_s * sps); - -#endif diff --git a/mpp/codec/enc/h264/include/H264Slice.h b/mpp/codec/enc/h264/include/H264Slice.h deleted file mode 100644 index c03b475f..00000000 --- a/mpp/codec/enc/h264/include/H264Slice.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * 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. - */ - -#ifndef __H264_SLICE_H__ -#define __H264_SLICE_H__ - -/*------------------------------------------------------------------------------ - 1. Include headers -------------------------------------------------------------------------------*/ -#include "enccommon.h" -#include "H264PutBits.h" -#include "H264NalUnit.h" - -/*------------------------------------------------------------------------------ - 2. External compiler flags --------------------------------------------------------------------------------- - --------------------------------------------------------------------------------- - 3. Module defines -------------------------------------------------------------------------------*/ -typedef enum { - PSLICE = 0, - BSLICE = 1, - ISLICE = 2, - PSLICES = 5, - ISLICES = 7 -} sliceType_e; - -typedef struct { - true_e byteStream; - RK_U32 sliceSize; - sliceType_e sliceType; - nalUnitType_e nalUnitType; - RK_U32 picParameterSetId; - RK_U32 prevFrameNum; - RK_U32 frameNum; - RK_U32 frameNumBits; - RK_U32 idrPicId; - RK_U32 nalRefIdc; - RK_U32 disableDeblocking; - RK_S32 filterOffsetA; - RK_S32 filterOffsetB; - RK_U32 cabacInitIdc; -} slice_s; - -/*------------------------------------------------------------------------------ - 4. Function prototypes -------------------------------------------------------------------------------*/ -void H264SliceInit(slice_s * slice); - -#endif diff --git a/mpp/codec/enc/h264/include/encasiccontroller.h b/mpp/codec/enc/h264/include/encasiccontroller.h deleted file mode 100644 index 435b5463..00000000 --- a/mpp/codec/enc/h264/include/encasiccontroller.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * 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. - */ - -#ifndef __ENC_ASIC_CONTROLLER_H__ -#define __ENC_ASIC_CONTROLLER_H__ - -#include "mpp_mem.h" -#include "mpp_buffer.h" -#include "h264e_syntax.h" - -/* HW status register bits */ -#define ASIC_STATUS_BUFF_FULL 0x020 -#define ASIC_STATUS_HW_RESET 0x100 -#define ASIC_STATUS_ERROR 0x010 -#define ASIC_STATUS_FRAME_READY 0x002 - -#define ASIC_STATUS_ENABLE 0x001 - -#define ASIC_H264_BYTE_STREAM 0x00 -#define ASIC_H264_NAL_UNIT 0x01 - -#define ASIC_INPUT_YUV420PLANAR 0x00 -#define ASIC_INPUT_YUV420SEMIPLANAR 0x01 -#define ASIC_INPUT_YUYV422INTERLEAVED 0x02 -#define ASIC_INPUT_UYVY422INTERLEAVED 0x03 -#define ASIC_INPUT_RGB565 0x04 -#define ASIC_INPUT_RGB555 0x05 -#define ASIC_INPUT_RGB444 0x06 -#define ASIC_INPUT_RGB888 0x07 -#define ASIC_INPUT_RGB101010 0x08 - -typedef enum { - IDLE = 0, /* Initial state, both HW and SW disabled */ - HWON_SWOFF, /* HW processing, SW waiting for HW */ - HWON_SWON, /* Both HW and SW processing */ - HWOFF_SWON, /* HW is paused or disabled, SW is processing */ - DONE -} bufferState_e; - -typedef enum { - ASIC_MPEG4 = 0, - ASIC_H263 = 1, - ASIC_JPEG = 2, - ASIC_H264 = 3 -} asicCodingType_e; - -typedef enum { - ASIC_P_16x16 = 0, - ASIC_P_16x8 = 1, - ASIC_P_8x16 = 2, - ASIC_P_8x8 = 3, - ASIC_I_4x4 = 4, - ASIC_I_16x16 = 5 -} asicMbType_e; - -typedef enum { - ASIC_INTER = 0, - ASIC_INTRA = 1 -} asicFrameCodingType_e; - -typedef struct { - RK_U32 frameCodingType; - RK_S32 sliceAlphaOffset; - RK_S32 sliceBetaOffset; - RK_U32 filterDisable; - RK_U32 inputImageFormat; - RK_U32 inputImageRotation; - RK_U32 outputStrmBase; - RK_U32 outputStrmSize; - - RK_U32 inputLumBase; - RK_U32 inputCbBase; - RK_U32 inputCrBase; - RK_U32 cpDistanceMbs; - RK_U32 *cpTargetResults; - const RK_U32 *cpTarget; - const RK_S32 *targetError; - const RK_S32 *deltaQp; - RK_U32 rlcCount; - RK_U32 qpSum; - RK_U32 h264StrmMode; /* 0 - byte stream, 1 - NAL units */ - RK_U32 inputLumaBaseOffset; - RK_U32 inputChromaBaseOffset; - RK_U32 h264Inter4x4Disabled; - RK_S32 madQpDelta; - RK_U32 madThreshold; - RK_U32 madCount; - RK_U32 colorConversionCoeffA; - RK_U32 colorConversionCoeffB; - RK_U32 colorConversionCoeffC; - RK_U32 colorConversionCoeffE; - RK_U32 colorConversionCoeffF; - RK_U32 rMaskMsb; - RK_U32 gMaskMsb; - RK_U32 bMaskMsb; - RK_U32 hw_status; -} regValues_s; - -typedef struct { - regValues_s regs; -} asicData_s; - -/*------------------------------------------------------------------------------ - 4. Function prototypes -------------------------------------------------------------------------------*/ -RK_S32 EncAsicControllerInit(asicData_s * asic); - -/* Functions for controlling ASIC */ -void EncAsicFrameStart(void * inst, regValues_s * val, h264e_syntax *syntax_data); -#endif diff --git a/mpp/codec/enc/h264/include/enccommon.h b/mpp/codec/enc/h264/include/enccommon.h deleted file mode 100644 index 1bf6d37c..00000000 --- a/mpp/codec/enc/h264/include/enccommon.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * 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. - */ - -#ifndef __ENC_COMMON_H__ -#define __ENC_COMMON_H__ - -/*------------------------------------------------------------------------------ - 2. Include headers -------------------------------------------------------------------------------*/ - -#include "rk_type.h" - -#define ASSERT(expr) -#define DEBUG_PRINT(args) -#define COMMENT(x) -#define TRACE_BIT_STREAM(v,n) - -/*------------------------------------------------------------------------------ - 3. Module defines -------------------------------------------------------------------------------*/ - -typedef enum { - ENCHW_NOK = -1, - ENCHW_OK = 0 -} bool_e; - -typedef enum { - ENCHW_NO = 0, - ENCHW_YES = 1 -} true_e; - -typedef enum { - NONIDR = 1, /* Coded slice of a non-IDR picture */ - IDR = 5, /* Coded slice of an IDR picture */ - SEI = 6, /* SEI message */ - SPSET = 7, /* Sequence parameter set */ - PPSET = 8, /* Picture parameter set */ - ENDOFSEQUENCE = 10, /* End of sequence */ - ENDOFSTREAM = 11, /* End of stream */ - FILLERDATA = 12 /* Filler data */ -} nalUnitType_e; - -/* used in stream buffer handling */ -typedef struct { - RK_U8 *stream; /* Pointer to next byte of stream */ - RK_U32 size; /* Byte size of stream buffer */ - RK_U32 byteCnt; /* Byte counter */ - RK_U32 bitCnt; /* Bit counter */ - RK_U32 byteBuffer; /* Byte buffer */ - RK_U32 bufferedBits; /* Amount of bits in byte buffer, [0-7] */ - RK_U32 zeroBytes; /* Amount of consecutive zero bytes */ - RK_S32 overflow; /* This will signal a buffer overflow */ - RK_U32 emulCnt; /* Counter for emulation_3_byte, needed in SEI */ - RK_S32 *table; /* Video packet or Gob sizes */ - RK_S32 tableSize; /* Size of above table */ - RK_S32 tableCnt; /* Table counter of above table */ -} stream_s; - -/* General tools */ -#define ABS(x) ((x) < (0) ? -(x) : (x)) -#define MAX(a, b) ((a) > (b) ? (a) : (b)) -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#define SIGN(a) ((a) < (0) ? (-1) : (1)) - -#endif diff --git a/mpp/codec/enc/h264/include/encpreprocess.h b/mpp/codec/enc/h264/include/encpreprocess.h deleted file mode 100644 index f80a5fa2..00000000 --- a/mpp/codec/enc/h264/include/encpreprocess.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * 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. - */ - -#ifndef __ENC_PRE_PROCESS_H__ -#define __ENC_PRE_PROCESS_H__ - -/*------------------------------------------------------------------------------ - 1. Include headers -------------------------------------------------------------------------------*/ -#include "encasiccontroller.h" - -/*------------------------------------------------------------------------------ - 2. External compiler flags --------------------------------------------------------------------------------- - --------------------------------------------------------------------------------- - 3. Module defines -------------------------------------------------------------------------------*/ - -#define ROTATE_0 0U -#define ROTATE_90R 1U /* Rotate 90 degrees clockwise */ -#define ROTATE_90L 2U /* Rotate 90 degrees counter-clockwise */ - -/* maximum input picture width set by the available bits in ASIC regs */ -#define MAX_INPUT_IMAGE_WIDTH (8192) - -typedef struct { - RK_U32 lumWidthSrc; /* Source input image width */ - RK_U32 lumHeightSrc; /* Source input image height */ - RK_U32 lumWidth; /* Encoded image width */ - RK_U32 lumHeight; /* Encoded image height */ - RK_U32 hor_stride; /* Encoded image horizontal stride */ - RK_U32 ver_stride; /* Encoded image vertical stride */ - RK_U32 horOffsetSrc; /* Encoded frame offset, reference is ... */ - RK_U32 verOffsetSrc; /* ...top left corner of source image */ - RK_U32 inputFormat; - RK_U32 rotation; - RK_U32 videoStab; - RK_U32 colorConversionType; /* 0 = bt601, 1 = bt709, 2 = user defined */ - RK_U32 colorConversionCoeffA; - RK_U32 colorConversionCoeffB; - RK_U32 colorConversionCoeffC; - RK_U32 colorConversionCoeffE; - RK_U32 colorConversionCoeffF; -} preProcess_s; - -/*------------------------------------------------------------------------------ - 4. Function prototypes -------------------------------------------------------------------------------*/ -RK_S32 EncPreProcessCheck(const preProcess_s * preProcess); -void EncPreProcess(asicData_s * asic, const preProcess_s * preProcess); -void EncSetColorConversion(preProcess_s * preProcess, asicData_s * asic); - -#endif diff --git a/mpp/codec/enc/h264/include/h264e_utils.h b/mpp/codec/enc/h264/include/h264e_utils.h deleted file mode 100644 index 01f66e9b..00000000 --- a/mpp/codec/enc/h264/include/h264e_utils.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * 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. - */ - -#include "H264Instance.h" - -RK_U32 getOutputStreamSize(H264ECtx *pEncInst); diff --git a/mpp/codec/enc/h264/include/h264encapi.h b/mpp/codec/enc/h264/include/h264encapi.h deleted file mode 100644 index 6697c26a..00000000 --- a/mpp/codec/enc/h264/include/h264encapi.h +++ /dev/null @@ -1,364 +0,0 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * 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. - */ - -#ifndef __H264ENCAPI_H__ -#define __H264ENCAPI_H__ - -#include "h264_syntax.h" -#include "h264e_syntax.h" -#include "mpp_frame.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include "H264Instance.h" - -/* Function return values */ -typedef enum { - H264ENC_OK = 0, - H264ENC_FRAME_READY = 1, - - H264ENC_ERROR = -1, - H264ENC_NULL_ARGUMENT = -2, - H264ENC_INVALID_ARGUMENT = -3, - H264ENC_MEMORY_ERROR = -4, - H264ENC_EWL_ERROR = -5, - H264ENC_EWL_MEMORY_ERROR = -6, - H264ENC_INVALID_STATUS = -7, - H264ENC_OUTPUT_BUFFER_OVERFLOW = -8, - H264ENC_HW_BUS_ERROR = -9, - H264ENC_HW_DATA_ERROR = -10, - H264ENC_HW_TIMEOUT = -11, - H264ENC_HW_RESERVED = -12, - H264ENC_SYSTEM_ERROR = -13, - H264ENC_INSTANCE_ERROR = -14, - H264ENC_HRD_ERROR = -15, - H264ENC_HW_RESET = -16 -} H264EncRet; - -/* Picture rotation for pre-processing */ -typedef enum { - H264ENC_ROTATE_0 = 0, - H264ENC_ROTATE_90R = 1, /* Rotate 90 degrees clockwise */ - H264ENC_ROTATE_90L = 2 /* Rotate 90 degrees counter-clockwise */ -} H264EncPictureRotation; - -/* Picture color space conversion (RGB input) for pre-processing */ -typedef enum { - H264ENC_RGBTOYUV_BT601 = 0, /* Color conversion according to BT.601 */ - H264ENC_RGBTOYUV_BT709 = 1, /* Color conversion according to BT.709 */ - H264ENC_RGBTOYUV_USER_DEFINED = 2 /* User defined color conversion */ -} H264EncColorConversionType; - -enum H264EncStatus { - H264ENCSTAT_INIT = 0xA1, - H264ENCSTAT_START_STREAM, - H264ENCSTAT_START_FRAME, - H264ENCSTAT_ERROR -}; - -/* Stream type for initialization */ -typedef enum { - H264ENC_BYTE_STREAM = 0, /* H.264 annex B: NAL unit starts with - * hex bytes '00 00 00 01' */ - H264ENC_NAL_UNIT_STREAM = 1 /* Plain NAL units without startcode */ -} H264EncStreamType; - -/* Picture type for encoding */ -typedef enum { - H264ENC_INTRA_FRAME = 0, - H264ENC_PREDICTED_FRAME = 1, - H264ENC_NOTCODED_FRAME /* Used just as a return value */ -} H264EncPictureCodingType; - - -/*------------------------------------------------------------------------------ - 3. Structures for API function parameters -------------------------------------------------------------------------------*/ - -/* Coding control parameters */ -typedef struct { - RK_U32 sliceSize; /* Slice size in macroblock rows, - * 0 to encode each picture in one slice, - * [0..height/16] - */ - RK_U32 seiMessages; /* Insert picture timing and buffering - * period SEI messages into the stream, - * [0,1] - */ - RK_U32 videoFullRange; /* Input video signal sample range, [0,1] - * 0 = Y range in [16..235], - * Cb&Cr range in [16..240] - * 1 = Y, Cb and Cr range in [0..255] - */ - RK_U32 constrainedIntraPrediction; /* 0 = No constrains, - * 1 = Only use intra neighbours */ - RK_U32 disableDeblockingFilter; /* 0 = Filter enabled, - * 1 = Filter disabled, - * 2 = Filter disabled on slice edges */ - RK_U32 sampleAspectRatioWidth; /* Horizontal size of the sample aspect - * ratio (in arbitrary units), 0 for - * unspecified, [0..65535] - */ - RK_U32 sampleAspectRatioHeight; /* Vertical size of the sample aspect ratio - * (in same units as sampleAspectRatioWidth) - * 0 for unspecified, [0..65535] - */ - RK_U32 enableCabac; /* 0 = CAVLC - Base profile, - * 1 = CABAC - Main profile */ - RK_U32 cabacInitIdc; /* [0,2] */ - RK_U32 transform8x8Mode; /* Enable 8x8 transform mode, High profile - * 0=disabled, 1=adaptive 8x8, 2=always 8x8 */ -} H264EncCodingCtrl; - - -/* Input pre-processing */ -typedef struct { - H264EncColorConversionType type; - RK_U16 coeffA; /* User defined color conversion coefficient */ - RK_U16 coeffB; /* User defined color conversion coefficient */ - RK_U16 coeffC; /* User defined color conversion coefficient */ - RK_U16 coeffE; /* User defined color conversion coefficient */ - RK_U16 coeffF; /* User defined color conversion coefficient */ -} H264EncColorConversion; - -typedef struct { - RK_U32 origWidth; - RK_U32 origHeight; - RK_U32 xOffset; - RK_U32 yOffset; - MppFrameFormat inputType; - H264EncPictureRotation rotation; - RK_U32 videoStabilization; - H264EncColorConversion colorConversion; -} H264EncPreProcessingCfg; - -/* Version information */ -typedef struct { - RK_U32 major; /* Encoder API major version */ - RK_U32 minor; /* Encoder API minor version */ -} H264EncApiVersion; - -typedef struct { - RK_U32 swBuild; /* Software build ID */ - RK_U32 hwBuild; /* Hardware build ID */ -} H264EncBuild; - -/* Encoder input structure */ -typedef struct { - RK_U32 busLuma; /* Bus address for input picture - * planar format: luminance component - * semiplanar format: luminance component - * interleaved format: whole picture - */ - RK_U32 busChromaU; /* Bus address for input chrominance - * planar format: cb component - * semiplanar format: both chrominance - * interleaved format: not used - */ - RK_U32 busChromaV; /* Bus address for input chrominance - * planar format: cr component - * semiplanar format: not used - * interleaved format: not used - */ - RK_U32 timeIncrement; /* The previous picture duration in units - * of frameRateDenom/frameRateNum. - * 0 for the very first picture. - */ - RK_U32 *pOutBuf; /* Pointer to output stream buffer */ - RK_U32 busOutBuf; /* Bus address of output stream buffer */ - RK_U32 outBufSize; /* Size of output stream buffer in bytes */ - - H264EncPictureCodingType codingType; /* Proposed picture coding type, - * INTRA/PREDICTED - */ - RK_U32 busLumaStab; /* bus address of next picture to stabilize (luminance) */ -} H264EncIn; - -/* Encoder output structure */ -typedef struct { - H264EncPictureCodingType codingType; /* Realized picture coding type, - * INTRA/PREDICTED/NOTCODED - */ - RK_U32 streamSize; /* Size of output stream in bytes */ -} H264EncOut; - -/* Configuration info for initialization - * Width and height are picture dimensions after rotation - * Width and height are restricted by level limitations - */ -typedef struct { - H264EncStreamType streamType; /* Byte stream / Plain NAL units */ - /* Stream Profile will be automatically decided, - * CABAC -> main/high, 8x8-transform -> high */ - H264Profile profile; - H264Level level; - RK_U32 width; /* Encoded picture width in pixels, multiple of 4 */ - RK_U32 height; /* Encoded picture height in pixels, multiple of 2 */ - RK_U32 hor_stride; /* Encoded picture horizontal stride in pixels */ - RK_U32 ver_stride; /* Encoded picture vertical stride in pixels */ - RK_U32 frameRateNum; /* The stream time scale, [1..65535] */ - RK_U32 frameRateDenom; /* Maximum frame rate is frameRateNum/frameRateDenom - * in frames/second. The actual frame rate will be - * defined by timeIncrement of encoded pictures, - * [1..frameRateNum] */ - RK_U32 enable_cabac; - RK_U32 transform8x8_mode; - RK_U32 pic_init_qp; - RK_U32 chroma_qp_index_offset; - RK_U32 pic_luma_height; - RK_U32 pic_luma_width; - MppFrameFormat input_image_format; - RK_U32 second_chroma_qp_index_offset; - RK_U32 pps_id; -} H264EncConfig; - -/* Rate control parameters */ -typedef struct { - RK_U32 pictureRc; /* Adjust QP between pictures, [0,1] */ - RK_U32 mbRc; /* Adjust QP inside picture, [0,1] */ - RK_U32 pictureSkip; /* Allow rate control to skip pictures, [0,1] */ - RK_U32 intraPicRate; /* intra period, namely keyframe_max_interval */ - RK_S32 qpHdr; /* QP for next encoded picture, [-1..51] - * -1 = Let rate control calculate initial QP - * This QP is used for all pictures if - * HRD and pictureRc and mbRc are disabled - * If HRD is enabled it may override this QP - */ - RK_U32 qpMin; /* Minimum QP for any picture, [0..51] */ - RK_U32 qpMax; /* Maximum QP for any picture, [0..51] */ - RK_U32 bitPerSecond; /* Target bitrate in bits/second, this is - * needed if pictureRc, mbRc, pictureSkip or - * hrd is enabled - */ - RK_U32 hrd; /* Hypothetical Reference Decoder model, [0,1] - * restricts the instantaneous bitrate and - * total bit amount of every coded picture. - * Enabling HRD will cause tight constrains - * on the operation of the rate control - */ - RK_U32 hrdCpbSize; /* Size of Coded Picture Buffer in HRD (bits) */ - RK_U32 gopLen; /* Length for Group of Pictures, indicates - * the distance of two intra pictures, - * including first intra [1..150] - */ - RK_S32 intraQpDelta; /* Intra QP delta. intraQP = QP + intraQpDelta - * This can be used to change the relative quality - * of the Intra pictures or to lower the size - * of Intra pictures. - */ - RK_U32 fixedIntraQp; /* Fixed QP value for all Intra pictures, - * 0 = Rate control calculates intra QP. - */ - RK_S32 mbQpAdjustment; /* Encoder uses MAD thresholding to recognize - * macroblocks with least details. This value is - * used to adjust the QP of these macroblocks - * increasing the subjective quality. [-8..7] - */ -} H264EncRateCtrl; - -typedef struct { - RK_U32 encStatus; - RK_U32 lumWidthSrc; // TODO need to think again modify by lance 2016.06.15 - RK_U32 lumHeightSrc; // TODO need to think again modify by lance 2016.06.15 - RK_U32 mbPerFrame; - RK_U32 mbPerRow; - RK_U32 mbPerCol; - RK_U32 frameCnt; - RK_U32 fillerNalSize; - RK_U32 testId; - stream_s stream; - preProcess_s preProcess; - sps_s seqParameterSet; - pps_s picParameterSet; - slice_s slice; - h264RateControl_s rateControl; - madTable_s mad; - asicData_s asic; - const void *inst; - RK_U32 time_debug_init; - RK_U32 intraPeriodCnt; // count the frame amount from last intra frame, - // then determine next frame to which type to be encoded - H264EncIn encIn; // put input struct into instance, todo modify by lance 2016.05.31 - H264EncOut encOut; // put input struct into instance, todo modify by lance 2016.05.31 - RK_U32 intraPicRate; // set I frame interval, and is 30 default - - h264e_control_extra_info_cfg info; - H264EncConfig enc_cfg; - H264EncRateCtrl enc_rc_cfg; - - // data for hal - h264e_syntax syntax; -} H264ECtx; - -#define H264E_DBG_FUNCTION (0x00000001) - -extern RK_U32 h264e_debug; - -#define h264e_dbg(flag, fmt, ...) _mpp_dbg(h264e_debug, flag, fmt, ## __VA_ARGS__) -#define h264e_dbg_f(flag, fmt, ...) _mpp_dbg_f(h264e_debug, flag, fmt, ## __VA_ARGS__) - -#define h264e_dbg_func(fmt, ...) h264e_dbg_f(H264E_DBG_FUNCTION, fmt, ## __VA_ARGS__) - -/*------------------------------------------------------------------------------ - 4. Encoder API function prototypes -------------------------------------------------------------------------------*/ - -/* Initialization & release */ -H264EncRet H264EncInit(H264ECtx *inst); -H264EncRet H264EncRelease(H264ECtx *inst); - -/* Encoder configuration before stream generation */ -H264EncRet H264EncCfg(H264ECtx *inst, const H264EncConfig * pEncConfig); -H264EncRet H264EncSetCodingCtrl(H264ECtx *inst, const H264EncCodingCtrl * - pCodingParams); - -/* Encoder configuration before and during stream generation */ -H264EncRet H264EncSetRateCtrl(H264ECtx *inst, - const H264EncRateCtrl * pRateCtrl); - -/* Encoder user data insertion during stream generation */ -H264EncRet H264EncSetSeiUserData(H264ECtx *inst, const RK_U8 * pUserData, - RK_U32 userDataSize); - -/* Stream generation */ - -/* H264EncStrmStart generates the SPS and PPS. SPS is the first NAL unit and PPS - * is the second NAL unit. NaluSizeBuf indicates the size of NAL units. - */ -H264EncRet H264EncStrmStart(H264ECtx *inst, const H264EncIn * pEncIn, - H264EncOut * pEncOut); - -/* H264EncStrmEncode encodes one video frame. If SEI messages are enabled the - * first NAL unit is a SEI message. - */ -H264EncRet H264EncStrmEncode(H264ECtx *inst, const H264EncIn * pEncIn, - H264EncOut * pEncOut, h264e_syntax *syntax_data); - -H264EncRet H264EncStrmEncodeAfter(H264ECtx *inst, - H264EncOut * pEncOut, MPP_RET vpuWaitResult); - -/* H264EncStrmEnd ends a stream with an EOS code. */ -H264EncRet H264EncStrmEnd(H264ECtx *inst, const H264EncIn * pEncIn, - H264EncOut * pEncOut); - -#ifdef __cplusplus -} -#endif - -#endif /*__H264ENCAPI_H__*/ diff --git a/mpp/codec/enc/h264/src/H264CodeFrame.c b/mpp/codec/enc/h264/src/H264CodeFrame.c deleted file mode 100644 index 32c24d42..00000000 --- a/mpp/codec/enc/h264/src/H264CodeFrame.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * 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. - */ - -#include "mpp_log.h" -#include "enccommon.h" -#include "h264encapi.h" -#include "H264CodeFrame.h" - -static void H264SetNewFrame(H264ECtx * inst); - -static RK_S64 encNum = 0; - -void H264CodeFrame(H264ECtx * inst, h264e_syntax *syntax_data) -{ - H264SetNewFrame(inst); - if (!inst->time_debug_init) { - inst->time_debug_init = 1; - encNum = 0; - } - - EncAsicFrameStart((void*)inst, &inst->asic.regs, syntax_data); -} - -void H264SetNewFrame(H264ECtx * ctx) -{ - regValues_s *regs = &ctx->asic.regs; - - regs->outputStrmSize -= ctx->stream.byteCnt; - - /* 64-bit aligned stream base address */ - regs->outputStrmBase += (ctx->stream.byteCnt & (~0x07)); - - if (ctx->rateControl.mbRc) { - regs->cpTarget = (RK_U32 *) ctx->rateControl.qpCtrl.wordCntTarget; - regs->targetError = ctx->rateControl.qpCtrl.wordError; - regs->deltaQp = ctx->rateControl.qpCtrl.qpChange; - - regs->cpDistanceMbs = ctx->rateControl.qpCtrl.checkPointDistance; - - regs->cpTargetResults = (RK_U32 *) ctx->rateControl.qpCtrl.wordCntPrev; - } else { - regs->cpTarget = NULL; - } - - regs->filterDisable = ctx->slice.disableDeblocking; - if (ctx->slice.disableDeblocking != 1) { - regs->sliceAlphaOffset = ctx->slice.filterOffsetA / 2; - regs->sliceBetaOffset = ctx->slice.filterOffsetB / 2; - } else { - regs->sliceAlphaOffset = 0; - regs->sliceBetaOffset = 0; - } - - regs->frameCodingType = - (ctx->slice.sliceType == ISLICE) ? ASIC_INTRA : ASIC_INTER; - - /* MAD threshold range [0, 63*256] register 6-bits range [0,63] */ - regs->madThreshold = ctx->mad.threshold / 256; - regs->madQpDelta = ctx->rateControl.mbQpAdjustment; -} - diff --git a/mpp/codec/enc/h264/src/H264EncApi.c b/mpp/codec/enc/h264/src/H264EncApi.c deleted file mode 100644 index 35a33a24..00000000 --- a/mpp/codec/enc/h264/src/H264EncApi.c +++ /dev/null @@ -1,966 +0,0 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * 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. - */ - -#define MODULE_TAG "H264EncApi" - -#include - -#include "mpp_env.h" -#include "mpp_log.h" - -#include "h264encapi.h" -#include "enccommon.h" -#include "H264Instance.h" -#include "H264Init.h" -#include "H264PutBits.h" -#include "H264CodeFrame.h" -#include "H264Sei.h" -#include "H264RateControl.h" - -/* Parameter limits */ -#define H264ENCSTRMSTART_MIN_BUF 64 -#define H264ENCSTRMENCODE_MIN_BUF 4096 -#define H264ENC_MAX_PP_INPUT_WIDTH 4096 -#define H264ENC_MAX_PP_INPUT_HEIGHT 4096 -#define H264ENC_MAX_BITRATE (50000*1200) /* Level 4.1 limit */ -#define H264ENC_MAX_USER_DATA_SIZE 2048 - -#define H264ENC_IDR_ID_MODULO 16 - -#define H264_BUS_ADDRESS_VALID(bus_address) (((bus_address) != 0)/* &&*/ \ - /*((bus_address & 0x07) == 0)*/) -RK_U32 h264e_debug = 0; - -/*------------------------------------------------------------------------------ - Function name : H264EncInit - Description : Initialize an encoder instance and returns it to application - - Return type : H264EncRet - Argument : pEncCfg - initialization parameters - instAddr - where to save the created instance -------------------------------------------------------------------------------*/ -H264EncRet H264EncInit(H264ECtx *pEncInst) -{ - H264EncRet ret; - - ret = H264Init(pEncInst); - if (ret != H264ENC_OK) { - mpp_err("H264EncInit: ERROR Initialization failed"); - return ret; - } - - /* Status == INIT Initialization succesful */ - - - return H264ENC_OK; -} - -/*------------------------------------------------------------------------------ - - Function name : H264EncRelease - Description : Releases encoder instance and all associated resource - - Return type : H264EncRet - Argument : inst - the instance to be released -------------------------------------------------------------------------------*/ -H264EncRet H264EncRelease(H264ECtx *pEncInst) -{ - h264e_dbg_func("enter\n"); - - /* Check for illegal inputs */ - if (pEncInst == NULL) { - h264e_dbg_func("H264EncRelease: ERROR Null argument"); - return H264ENC_NULL_ARGUMENT; - } - - /* Check for existing instance */ - if (pEncInst->inst != pEncInst) { - h264e_dbg_func("ERROR Invalid instance\n"); - return H264ENC_INSTANCE_ERROR; - } - - h264e_dbg_func("leave\n"); - return H264ENC_OK; -} - -H264EncRet H264EncCfg(H264ECtx *pEncInst, const H264EncConfig * pEncConfig) -{ - H264EncRet ret; - h264e_dbg_func("enter\n"); - - ret = H264Cfg(pEncConfig, pEncInst); - if (ret != H264ENC_OK) { - mpp_err("H264EncCfg: ERROR Config failed"); - return ret; - } - - h264e_dbg_func("leave\n"); - return H264ENC_OK; -} - -/*------------------------------------------------------------------------------ - - Function name : H264EncSetCodingCtrl - Description : Sets encoding parameters - - Return type : H264EncRet - Argument : inst - the instance in use - pCodeParams - user provided parameters -------------------------------------------------------------------------------*/ -H264EncRet H264EncSetCodingCtrl(H264ECtx *pEncInst, const H264EncCodingCtrl * pCodeParams) -{ - h264e_dbg_func("enter\n"); - - /* Check for illegal inputs */ - if ((pEncInst == NULL) || (pCodeParams == NULL)) { - mpp_err_f("ERROR Null argument\n"); - return H264ENC_NULL_ARGUMENT; - } - - /* Check for existing instance */ - if (pEncInst->inst != pEncInst) { - mpp_err_f("ERROR Invalid instance\n"); - return H264ENC_INSTANCE_ERROR; - } - - /* Check for invalid values */ - if (pCodeParams->sliceSize > pEncInst->mbPerCol) { - mpp_err_f("ERROR Invalid sliceSize\n"); - return H264ENC_INVALID_ARGUMENT; - } - - /* Check status, only slice size allowed to be altered after start */ - if (pEncInst->encStatus != H264ENCSTAT_INIT) { - goto set_slice_size; - } - - if (pCodeParams->constrainedIntraPrediction > 1 || - pCodeParams->disableDeblockingFilter > 2 || - pCodeParams->enableCabac > 1 || - pCodeParams->transform8x8Mode > 2 || - pCodeParams->seiMessages > 1 || pCodeParams->videoFullRange > 1) { - mpp_err_f("ERROR Invalid enable/disable\n"); - return H264ENC_INVALID_ARGUMENT; - } - - if (pCodeParams->sampleAspectRatioWidth > 65535 || - pCodeParams->sampleAspectRatioHeight > 65535) { - mpp_err_f("ERROR Invalid sampleAspectRatio\n"); - return H264ENC_INVALID_ARGUMENT; - } - - if (pCodeParams->cabacInitIdc > 2) { - mpp_err_f("ERROR Invalid cabacInitIdc\n"); - return H264ENC_INVALID_ARGUMENT; - } - - /* Configure the values */ - if (pCodeParams->constrainedIntraPrediction == 0) - pEncInst->picParameterSet.constIntraPred = ENCHW_NO; - else - pEncInst->picParameterSet.constIntraPred = ENCHW_YES; - - /* filter control header always present */ - pEncInst->picParameterSet.deblockingFilterControlPresent = ENCHW_YES; - pEncInst->slice.disableDeblocking = pCodeParams->disableDeblockingFilter; - - if (pCodeParams->enableCabac == 0) { - pEncInst->picParameterSet.entropyCodingMode = ENCHW_NO; - } else { - pEncInst->picParameterSet.entropyCodingMode = ENCHW_YES; - pEncInst->slice.cabacInitIdc = pCodeParams->cabacInitIdc; - } - - /* 8x8 mode: 2=enable, 1=adaptive (720p or bigger frame) */ - if ((pCodeParams->transform8x8Mode == 2) || - ((pCodeParams->transform8x8Mode == 1) && - (pEncInst->mbPerFrame >= 3600))) { - pEncInst->picParameterSet.transform8x8Mode = ENCHW_YES; - } - - H264SpsSetVuiAspectRatio(&pEncInst->seqParameterSet, - pCodeParams->sampleAspectRatioWidth, - pCodeParams->sampleAspectRatioHeight); - - H264SpsSetVuiVideoInfo(&pEncInst->seqParameterSet, - pCodeParams->videoFullRange); - - /* SEI messages are written in the beginning of each frame */ - if (pCodeParams->seiMessages) { - pEncInst->rateControl.sei.enabled = ENCHW_YES; - } else { - pEncInst->rateControl.sei.enabled = ENCHW_NO; - } - -set_slice_size: - /* Slice size is set in macroblock rows => convert to macroblocks */ - pEncInst->slice.sliceSize = pCodeParams->sliceSize * pEncInst->mbPerRow; - - h264e_dbg_func("leave\n"); - return H264ENC_OK; -} - -/*------------------------------------------------------------------------------ - - Function name : H264EncSetRateCtrl - Description : Sets rate control parameters - - Return type : H264EncRet - Argument : inst - the instance in use - pRateCtrl - user provided parameters -------------------------------------------------------------------------------*/ -H264EncRet H264EncSetRateCtrl(H264ECtx *pEncInst, - const H264EncRateCtrl * pRateCtrl) -{ - h264RateControl_s *rc; - - RK_U32 i, tmp; - - h264e_dbg_func("enter\n"); - - /* Check for illegal inputs */ - if ((pEncInst == NULL) || (pRateCtrl == NULL)) { - mpp_err_f("ERROR Null argument\n"); - return H264ENC_NULL_ARGUMENT; - } - - /* Check for existing instance */ - if (pEncInst->inst != pEncInst) { - mpp_err_f("ERROR Invalid instance\n"); - return H264ENC_INSTANCE_ERROR; - } - - rc = &pEncInst->rateControl; - - /* after stream was started with HRD ON, - * it is not allowed to change RC params */ - if (pEncInst->encStatus == H264ENCSTAT_START_FRAME && rc->hrd == ENCHW_YES) { - mpp_err_f("ERROR Stream started with HRD ON. Not allowed to change any aprameters\n"); - return H264ENC_INVALID_STATUS; - } - - /* Check for invalid input values */ - if (pRateCtrl->pictureRc > 1 || - pRateCtrl->mbRc > 1 || pRateCtrl->pictureSkip > 1 || pRateCtrl->hrd > 1) { - mpp_err_f("ERROR Invalid enable/disable value\n"); - return H264ENC_INVALID_ARGUMENT; - } - - if (pRateCtrl->qpHdr > 51 || - pRateCtrl->qpMin > 51 || - pRateCtrl->qpMax > 51 || - pRateCtrl->qpMax < pRateCtrl->qpMin) { - mpp_err_f("ERROR Invalid QP\n"); - return H264ENC_INVALID_ARGUMENT; - } - - if ((pRateCtrl->qpHdr != -1) && - (pRateCtrl->qpHdr < (RK_S32)pRateCtrl->qpMin || - pRateCtrl->qpHdr > (RK_S32)pRateCtrl->qpMax)) { - mpp_err_f("ERROR QP out of range\n"); - return H264ENC_INVALID_ARGUMENT; - } - if ((RK_U32)(pRateCtrl->intraQpDelta + 12) > 24) { - mpp_err_f("ERROR intraQpDelta out of range\n"); - return H264ENC_INVALID_ARGUMENT; - } - if (pRateCtrl->fixedIntraQp > 51) { - mpp_err_f("ERROR fixedIntraQp out of range\n"); - return H264ENC_INVALID_ARGUMENT; - } - if (pRateCtrl->gopLen < 1 || pRateCtrl->gopLen > 150) { - mpp_err_f("ERROR Invalid GOP length\n"); - return H264ENC_INVALID_ARGUMENT; - } - - /* Bitrate affects only when rate control is enabled */ - if ((pRateCtrl->pictureRc || pRateCtrl->mbRc || - pRateCtrl->pictureSkip || pRateCtrl->hrd) && - (pRateCtrl->bitPerSecond < 10000 || - pRateCtrl->bitPerSecond > H264ENC_MAX_BITRATE)) { - mpp_err_f("ERROR Invalid bitPerSecond\n"); - return H264ENC_INVALID_ARGUMENT; - } - - { - RK_U32 cpbSize = pRateCtrl->hrdCpbSize; - RK_U32 bps = pRateCtrl->bitPerSecond; - RK_U32 level = pEncInst->seqParameterSet.levelIdx; - - /* Saturates really high settings */ - /* bits per unpacked frame */ - tmp = 3 * 8 * pEncInst->mbPerFrame * 256 / 2; - /* bits per second */ - tmp = H264Calculate(tmp, rc->outRateNum, rc->outRateDenom); - if (bps > (tmp / 2)) - bps = tmp / 2; - - if (cpbSize == 0) { - cpbSize = H264MaxCPBS[level]; - } else if (cpbSize == (RK_U32) (-1)) { - cpbSize = bps; - } - - - /* Limit minimum CPB size based on average bits per frame */ - tmp = H264Calculate(bps, rc->outRateDenom, rc->outRateNum); - cpbSize = MAX(cpbSize, tmp); - - /* cpbSize must be rounded so it is exactly the size written in stream */ - i = 0; - tmp = cpbSize; - while (4095 < (tmp >> (4 + i++))); - - cpbSize = (tmp >> (4 + i)) << (4 + i); - - /* if HRD is ON we have to obay all its limits */ - if (pRateCtrl->hrd != 0) { - if (cpbSize > H264MaxCPBS[level]) { - mpp_err_f("ERROR. HRD is ON. hrdCpbSize higher than maximum allowed for stream level\n"); - return H264ENC_INVALID_ARGUMENT; - } - - if (bps > H264MaxBR[level]) { - mpp_err_f("ERROR. HRD is ON. bitPerSecond higher than maximum allowed for stream level\n"); - return H264ENC_INVALID_ARGUMENT; - } - } - - rc->virtualBuffer.bufferSize = cpbSize; - - /* Set the parameters to rate control */ - if (pRateCtrl->pictureRc != 0) - rc->picRc = ENCHW_YES; - else - rc->picRc = ENCHW_NO; - - /* ROI and MB RC can't be used at the same time */ - if ((pRateCtrl->mbRc != 0) && (rc->roiRc == ENCHW_NO)) { - rc->mbRc = ENCHW_YES; - } else - rc->mbRc = ENCHW_NO; - - if (pRateCtrl->pictureSkip != 0) - rc->picSkip = ENCHW_YES; - else - rc->picSkip = ENCHW_NO; - - if (pRateCtrl->hrd != 0) { - rc->hrd = ENCHW_YES; - rc->picRc = ENCHW_YES; - } else - rc->hrd = ENCHW_NO; - - rc->qpHdr = pRateCtrl->qpHdr; - rc->qpMin = pRateCtrl->qpMin; - rc->qpMax = pRateCtrl->qpMax; - rc->virtualBuffer.bitRate = bps; - rc->gopLen = pRateCtrl->gopLen; - } - rc->intraQpDelta = pRateCtrl->intraQpDelta; - rc->fixedIntraQp = pRateCtrl->fixedIntraQp; - rc->mbQpAdjustment = pRateCtrl->mbQpAdjustment; - (void) H264InitRc(rc); /* new parameters checked already */ - - h264e_dbg_func("leave\n"); - return H264ENC_OK; -} - -H264EncRet H264EncSetSeiUserData(H264ECtx *pEncInst, const RK_U8 * pUserData, - RK_U32 userDataSize) -{ - /* Check for illegal inputs */ - if ((pEncInst == NULL) || (userDataSize != 0 && pUserData == NULL)) { - mpp_err_f("ERROR Null argument\n"); - return H264ENC_NULL_ARGUMENT; - } - - /* Check for existing instance */ - if (pEncInst->inst != pEncInst) { - mpp_err_f("ERROR Invalid instance\n"); - return H264ENC_INSTANCE_ERROR; - } - - /* Disable user data */ - if ((userDataSize < 16) || (userDataSize > H264ENC_MAX_USER_DATA_SIZE)) { - pEncInst->rateControl.sei.userDataEnabled = ENCHW_NO; - pEncInst->rateControl.sei.pUserData = NULL; - pEncInst->rateControl.sei.userDataSize = 0; - } else { - pEncInst->rateControl.sei.userDataEnabled = ENCHW_YES; - pEncInst->rateControl.sei.pUserData = pUserData; - pEncInst->rateControl.sei.userDataSize = userDataSize; - } - - return H264ENC_OK; -} - -/*------------------------------------------------------------------------------ - - Function name : H264EncStrmStart - Description : Starts a new stream - Return type : H264EncRet - Argument : inst - encoder instance - Argument : pEncIn - user provided input parameters - pEncOut - place where output info is returned -------------------------------------------------------------------------------*/ -H264EncRet H264EncStrmStart(H264ECtx *pEncInst, const H264EncIn * pEncIn, - H264EncOut * pEncOut) -{ - h264RateControl_s *rc; - - h264e_dbg_func("enter\n"); - - /* Check for illegal inputs */ - if ((pEncInst == NULL) || (pEncIn == NULL) || (pEncOut == NULL)) { - mpp_err_f("ERROR Null argument\n"); - return H264ENC_NULL_ARGUMENT; - } - - /* Check for existing instance */ - if (pEncInst->inst != pEncInst) { - mpp_err_f("ERROR Invalid instance\n"); - return H264ENC_INSTANCE_ERROR; - } - - rc = &pEncInst->rateControl; - - /* Check status */ - if (pEncInst->encStatus != H264ENCSTAT_INIT) { - mpp_err_f("ERROR Invalid status\n"); - return H264ENC_INVALID_STATUS; - } - - /* Check for invalid input values */ - if ((pEncIn->pOutBuf == NULL) || - (pEncIn->outBufSize < H264ENCSTRMSTART_MIN_BUF)) { - mpp_err_f("ERROR Invalid input. Stream buffer\n"); - return H264ENC_INVALID_ARGUMENT; - } - - /* Set stream buffer, the size has been checked */ - (void) H264SetBuffer(&pEncInst->stream, (RK_U8 *) pEncIn->pOutBuf, - (RK_U32) pEncIn->outBufSize); - - /* Set the profile to be used */ - if (pEncInst->seqParameterSet.profileIdc != 66 && pEncInst->seqParameterSet.profileIdc != 77 - && pEncInst->seqParameterSet.profileIdc != 100) - pEncInst->seqParameterSet.profileIdc = 66; /* base profile */ - - /* CABAC => main profile */ - if (pEncInst->picParameterSet.entropyCodingMode == ENCHW_YES) - pEncInst->seqParameterSet.profileIdc = 77; - - /* 8x8 transform enabled => high profile */ - if (pEncInst->picParameterSet.transform8x8Mode == ENCHW_YES) - pEncInst->seqParameterSet.profileIdc = 100; - - /* update VUI */ - if (rc->sei.enabled == ENCHW_YES) { - H264SpsSetVuiPictStructPresentFlag(&pEncInst->seqParameterSet, 1); - } - - if (rc->hrd == ENCHW_YES) { - H264SpsSetVuiHrd(&pEncInst->seqParameterSet, 1); - - H264SpsSetVuiHrdBitRate(&pEncInst->seqParameterSet, - rc->virtualBuffer.bitRate); - - H264SpsSetVuiHrdCpbSize(&pEncInst->seqParameterSet, - rc->virtualBuffer.bufferSize); - } - - /* Use the first frame QP in the PPS */ - pEncInst->picParameterSet.picInitQpMinus26 = (RK_S32) (rc->qpHdr) - 26; - - /* Init SEI */ - H264InitSei(&rc->sei, pEncInst->seqParameterSet.byteStream, - rc->hrd, rc->outRateNum, rc->outRateDenom); - - H264SeqParameterSet(&pEncInst->stream, &pEncInst->seqParameterSet); - - H264PicParameterSet(&pEncInst->stream, &pEncInst->picParameterSet); - - if (pEncInst->stream.overflow == ENCHW_YES) { - pEncOut->streamSize = 0; - mpp_err_f("ERROR Output buffer too small\n"); - return H264ENC_OUTPUT_BUFFER_OVERFLOW; - } - - /* Bytes generated */ - pEncOut->streamSize = pEncInst->stream.byteCnt; - - /* Status == START_STREAM Stream started */ - pEncInst->encStatus = H264ENCSTAT_START_STREAM; - - pEncInst->slice.frameNum = 0; - pEncInst->rateControl.fillerIdx = (RK_U32) (-1); - - if (rc->hrd == ENCHW_YES) { - /* Update HRD Parameters to RC if needed */ - RK_U32 bitrate = H264SpsGetVuiHrdBitRate(&pEncInst->seqParameterSet); - RK_U32 cpbsize = H264SpsGetVuiHrdCpbSize(&pEncInst->seqParameterSet); - - if ((rc->virtualBuffer.bitRate != (RK_S32)bitrate) || - (rc->virtualBuffer.bufferSize != (RK_S32)cpbsize)) { - rc->virtualBuffer.bitRate = bitrate; - rc->virtualBuffer.bufferSize = cpbsize; - (void) H264InitRc(rc); - } - } - - h264e_dbg_func("leave\n"); - return H264ENC_OK; -} - -/*------------------------------------------------------------------------------ - - Function name : H264EncStrmEncode - Description : Encodes a new picture - Return type : H264EncRet - Argument : inst - encoder instance - Argument : pEncIn - user provided input parameters - pEncOut - place where output info is returned -------------------------------------------------------------------------------*/ -H264EncRet H264EncStrmEncode(H264ECtx *pEncInst, const H264EncIn * pEncIn, - H264EncOut * pEncOut, h264e_syntax *syntax_data) -{ - slice_s *pSlice; - regValues_s *regs; - - h264e_dbg_func("enter\n"); - - /* Check for illegal inputs */ - if ((pEncInst == NULL) || (pEncIn == NULL) || (pEncOut == NULL)) { - mpp_err_f("ERROR Null argument\n"); - return H264ENC_NULL_ARGUMENT; - } - - /* Check for existing instance */ - if (pEncInst->inst != pEncInst) { - mpp_err_f("ERROR Invalid instance\n"); - return H264ENC_INSTANCE_ERROR; - } - - { - RK_U32 nals; - - if (pEncInst->slice.sliceSize != 0) { - /* how many picture slices we have */ - nals = (pEncInst->mbPerFrame + pEncInst->slice.sliceSize - 1) / - pEncInst->slice.sliceSize; - } else { - nals = 1; /* whole pic in one slice */ - } - - nals += 3; /* SEI, Filler and "0-end" */ - - } - - /* Clear the output structure */ - pEncOut->codingType = H264ENC_NOTCODED_FRAME; - pEncOut->streamSize = 0; - - - /* Check status, INIT and ERROR not allowed */ - if ((pEncInst->encStatus != H264ENCSTAT_START_STREAM) && - (pEncInst->encStatus != H264ENCSTAT_START_FRAME)) { - mpp_err_f("ERROR Invalid status\n"); - return H264ENC_INVALID_STATUS; - } - - /* Check for invalid input values */ - if ((!H264_BUS_ADDRESS_VALID(pEncIn->busOutBuf))) { - mpp_err_f("ERROR Invalid input busOutBuf is NULL\n"); - return H264ENC_INVALID_ARGUMENT; - } - if (pEncIn->pOutBuf == NULL) { - mpp_err_f("ERROR Invalid input pOutBuf is NULL\n"); - return H264ENC_INVALID_ARGUMENT; - } - if (pEncIn->outBufSize < H264ENCSTRMENCODE_MIN_BUF) { - mpp_err_f("ERROR Invalid input outBufSize %d < min size %d\n", - pEncIn->outBufSize, H264ENCSTRMENCODE_MIN_BUF); - return H264ENC_INVALID_ARGUMENT; - } - if (pEncIn->codingType > H264ENC_PREDICTED_FRAME) { - mpp_err_f("ERROR Invalid input codingType %d < predicted %d\n", - pEncIn->codingType, H264ENC_PREDICTED_FRAME); - return H264ENC_INVALID_ARGUMENT; - } - - switch (pEncInst->preProcess.inputFormat) { - case MPP_FMT_YUV420P: - if (!H264_BUS_ADDRESS_VALID(pEncIn->busChromaV)) { - mpp_err_f("ERROR Invalid input busChromaV\n"); - return H264ENC_INVALID_ARGUMENT; - } - /* fall through */ - case MPP_FMT_YUV420SP: - case MPP_FMT_YUV420SP_VU: - if (!H264_BUS_ADDRESS_VALID(pEncIn->busChromaU)) { - mpp_err_f("ERROR Invalid input busChromaU\n"); - return H264ENC_INVALID_ARGUMENT; - } - /* fall through */ - case MPP_FMT_YUV422P: - case MPP_FMT_YUV422SP: - case MPP_FMT_YUV422SP_VU: - case MPP_FMT_YUV422_YUYV: - case MPP_FMT_YUV422_UYVY: - case MPP_FMT_RGB565: - case MPP_FMT_BGR565: - case MPP_FMT_RGB555: - case MPP_FMT_BGR555: - case MPP_FMT_RGB444: - case MPP_FMT_BGR444: - case MPP_FMT_RGB888: - case MPP_FMT_BGR888: - case MPP_FMT_RGB101010: - case MPP_FMT_BGR101010: - case MPP_FMT_ARGB8888: - case MPP_FMT_ABGR8888: - if (!H264_BUS_ADDRESS_VALID(pEncIn->busLuma)) { - mpp_err_f("ERROR Invalid input busLuma\n"); - return H264ENC_INVALID_ARGUMENT; - } - break; - default: - mpp_err_f("ERROR Invalid input format %d\n", pEncInst->preProcess.inputFormat); - return H264ENC_INVALID_ARGUMENT; - } - - if (pEncInst->preProcess.videoStab) { - if (!H264_BUS_ADDRESS_VALID(pEncIn->busLumaStab)) { - mpp_err_f("ERROR Invalid input busLumaStab\n"); - return H264ENC_INVALID_ARGUMENT; - } - } - - /* some shortcuts */ - pSlice = &pEncInst->slice; - regs = &pEncInst->asic.regs; - - /* Set stream buffer, the size has been checked */ - if (H264SetBuffer(&pEncInst->stream, (RK_U8 *) pEncIn->pOutBuf, - (RK_S32) pEncIn->outBufSize) == ENCHW_NOK) { - mpp_err_f("ERROR Invalid output buffer\n"); - return H264ENC_INVALID_ARGUMENT; - } - - /* update in/out buffers */ - regs->inputLumBase = pEncIn->busLuma; - regs->inputCbBase = pEncIn->busChromaU; - regs->inputCrBase = pEncIn->busChromaV; - - regs->outputStrmBase = pEncIn->busOutBuf; - regs->outputStrmSize = pEncIn->outBufSize; - - { - H264EncPictureCodingType ct = pEncIn->codingType; - - /* Status may affect the frame coding type */ - if (pEncInst->encStatus == H264ENCSTAT_START_STREAM) { - ct = H264ENC_INTRA_FRAME; - } - pSlice->prevFrameNum = pSlice->frameNum; - - /* Frame coding type defines the NAL unit type */ - switch (ct) { - case H264ENC_INTRA_FRAME: - /* IDR-slice */ - pSlice->nalUnitType = IDR; - pSlice->sliceType = ISLICE; - pSlice->frameNum = 0; - H264MadInit(&pEncInst->mad, pEncInst->mbPerFrame); - break; - case H264ENC_PREDICTED_FRAME: - default: - /* non-IDR slice */ - pSlice->nalUnitType = NONIDR; - pSlice->sliceType = PSLICE; - break; - } - } - - /* Rate control */ - H264BeforePicRc(&pEncInst->rateControl, pEncIn->timeIncrement, - pSlice->sliceType); - - - /* time stamp updated */ - H264UpdateSeiTS(&pEncInst->rateControl.sei, pEncIn->timeIncrement); - - /* Rate control may choose to skip the frame */ - if (pEncInst->rateControl.frameCoded == ENCHW_NO) { - h264e_dbg_func("H264EncStrmEncode: OK, frame skipped"); - pSlice->frameNum = pSlice->prevFrameNum; /* restore frame_num */ - - return H264ENC_FRAME_READY; - } - - /* update any cropping/rotation/filling */ - EncPreProcess(&pEncInst->asic, &pEncInst->preProcess); - - /* SEI message */ - { - sei_s *sei = &pEncInst->rateControl.sei; - - if (sei->enabled == ENCHW_YES || sei->userDataEnabled == ENCHW_YES) { - - H264NalUnitHdr(&pEncInst->stream, 0, SEI, sei->byteStream); - - if (sei->enabled == ENCHW_YES) { - if (pSlice->nalUnitType == IDR) { - H264BufferingSei(&pEncInst->stream, sei); - } - - H264PicTimingSei(&pEncInst->stream, sei); - } - - if (sei->userDataEnabled == ENCHW_YES) { - H264UserDataUnregSei(&pEncInst->stream, sei); - } - - H264RbspTrailingBits(&pEncInst->stream); - - sei->nalUnitSize = pEncInst->stream.byteCnt; - } - } - - /* Code one frame */ - H264CodeFrame(pEncInst, syntax_data); - - // need to think about it also modify by lance 2016.05.07 - return H264ENC_FRAME_READY; -} - -// get the hw status of encoder after encode frame -RK_S32 EncAsicCheckHwStatus(asicData_s *asic) -{ - RK_S32 ret = ASIC_STATUS_FRAME_READY; - /* - RK_U32 status = asic->regs.hw_status; - - if (status & ASIC_STATUS_ERROR) { - ret = ASIC_STATUS_ERROR; - } else if (status & ASIC_STATUS_HW_RESET) { - ret = ASIC_STATUS_HW_RESET; - } else if (status & ASIC_STATUS_FRAME_READY) { - ret = ASIC_STATUS_FRAME_READY; - } else { - ret = ASIC_STATUS_BUFF_FULL; - } - */ - (void)asic; - return ret; -} - -H264EncRet H264EncStrmEncodeAfter(H264ECtx *pEncInst, - H264EncOut * pEncOut, MPP_RET vpuWaitResult) -{ - slice_s *pSlice; - regValues_s *regs; - h264EncodeFrame_e ret = H264ENCODE_OK; - asicData_s *asic = &pEncInst->asic; - - pSlice = &pEncInst->slice; - regs = &pEncInst->asic.regs; - if (vpuWaitResult != MPP_OK) { - if (vpuWaitResult == MPP_NOK) { - /* IRQ error => Stop and release HW */ - ret = H264ENCODE_SYSTEM_ERROR; - } else { /*if(ewl_ret == EWL_HW_WAIT_TIMEOUT) */ - /* IRQ Timeout => Stop and release HW */ - ret = H264ENCODE_TIMEOUT; - } - } else { - RK_S32 status = EncAsicCheckHwStatus(asic); - switch (status) { - case ASIC_STATUS_ERROR: - ret = H264ENCODE_HW_ERROR; - break; - case ASIC_STATUS_BUFF_FULL: - ret = H264ENCODE_OK; - pEncInst->stream.overflow = ENCHW_YES; - break; - case ASIC_STATUS_HW_RESET: - ret = H264ENCODE_HW_RESET; - break; - case ASIC_STATUS_FRAME_READY: { - /* last not full 64-bit counted in HW data */ - const RK_U32 hw_offset = pEncInst->stream.byteCnt & (0x07U); - pEncInst->stream.byteCnt += - (asic->regs.outputStrmSize - hw_offset); - pEncInst->stream.stream += - (asic->regs.outputStrmSize - hw_offset); - ret = H264ENCODE_OK; - break; - } - default: - /* should never get here */ - ASSERT(0); - ret = H264ENCODE_HW_ERROR; - } - } - - if (ret != H264ENCODE_OK) { - /* Error has occured and the frame is invalid */ - H264EncRet to_user; - - switch (ret) { - case H264ENCODE_TIMEOUT: - mpp_err_f("ERROR HW timeout\n"); - to_user = H264ENC_HW_TIMEOUT; - break; - case H264ENCODE_HW_RESET: - mpp_err_f("ERROR HW reset detected\n"); - to_user = H264ENC_HW_RESET; - break; - case H264ENCODE_HW_ERROR: - mpp_err_f("ERROR HW bus access error\n"); - to_user = H264ENC_HW_BUS_ERROR; - break; - case H264ENCODE_SYSTEM_ERROR: - default: - /* System error has occured, encoding can't continue */ - pEncInst->encStatus = H264ENCSTAT_ERROR; - mpp_err_f("ERROR Fatal system error\n"); - to_user = H264ENC_SYSTEM_ERROR; - } - return to_user; - } - - /* Filler data if needed */ - if (0) { - RK_U32 s = H264FillerRc(&pEncInst->rateControl, pEncInst->frameCnt); - - if (s != 0) { - s = H264FillerNALU(&pEncInst->stream, - (RK_S32) s, pEncInst->seqParameterSet.byteStream); - } - pEncInst->fillerNalSize = s; - } - - /* After stream buffer overflow discard the coded frame */ - if (pEncInst->stream.overflow == ENCHW_YES) { - /* Error has occured and the frame is invalid */ - /* pEncOut->codingType = H264ENC_NOTCODED_FRAME; */ - mpp_err_f("ERROR Output buffer too small\n"); - return H264ENC_OUTPUT_BUFFER_OVERFLOW; - } - - /* Rate control action after vop */ - { - RK_S32 stat; - - stat = H264AfterPicRc(&pEncInst->rateControl, regs->rlcCount, - pEncInst->stream.byteCnt, regs->qpSum); - H264MadThreshold(&pEncInst->mad, regs->madCount); - - /* After HRD overflow discard the coded frame and go back old time, - * just like not coded frame */ - if (stat == H264RC_OVERFLOW) { - /* pEncOut->codingType = H264ENC_NOTCODED_FRAME; */ - pSlice->frameNum = pSlice->prevFrameNum; /* revert frame_num */ - mpp_err("H264EncStrmEncode: OK, Frame discarded (HRD overflow)!"); - return H264ENC_FRAME_READY; - } - } - - /* Store the stream size and frame coding type in output structure */ - pEncOut->streamSize = pEncInst->stream.byteCnt; - - if (pSlice->nalUnitType == IDR) { - pEncOut->codingType = H264ENC_INTRA_FRAME; - pSlice->idrPicId += 1; - if (pSlice->idrPicId == H264ENC_IDR_ID_MODULO) - pSlice->idrPicId = 0; - } else { - pEncOut->codingType = H264ENC_PREDICTED_FRAME; - } - - /* Frame was encoded so increment frame number */ - pEncInst->frameCnt++; - pSlice->frameNum++; - pSlice->frameNum %= (1U << pSlice->frameNumBits); - - pEncInst->encStatus = H264ENCSTAT_START_FRAME; - h264e_dbg_func("leave\n"); - return H264ENC_FRAME_READY; -} - -/*------------------------------------------------------------------------------ - - Function name : H264EncStrmEnd - Description : Ends a stream - Return type : H264EncRet - Argument : inst - encoder instance - Argument : pEncIn - user provided input parameters - pEncOut - place where output info is returned -------------------------------------------------------------------------------*/ -H264EncRet H264EncStrmEnd(H264ECtx *pEncInst, const H264EncIn * pEncIn, - H264EncOut * pEncOut) -{ - h264e_dbg_func("enter\n"); - /* Check for illegal inputs */ - if ((pEncInst == NULL) || (pEncIn == NULL) || (pEncOut == NULL)) { - mpp_err_f("ERROR Null argument\n"); - return H264ENC_NULL_ARGUMENT; - } - - /* Check for existing instance */ - if (pEncInst->inst != pEncInst) { - mpp_err_f("ERROR Invalid instance\n"); - return H264ENC_INSTANCE_ERROR; - } - - /* Check status, this also makes sure that the instance is valid */ - if ((pEncInst->encStatus != H264ENCSTAT_START_FRAME) && - (pEncInst->encStatus != H264ENCSTAT_START_STREAM)) { - mpp_err_f("ERROR Invalid status\n"); - return H264ENC_INVALID_STATUS; - } - - pEncOut->streamSize = 0; - - /* Check for invalid input values */ - if (pEncIn->pOutBuf == NULL || - (pEncIn->outBufSize < H264ENCSTRMSTART_MIN_BUF)) { - mpp_err_f("ERROR Invalid input. Stream buffer\n"); - return H264ENC_INVALID_ARGUMENT; - } - - /* Set stream buffer and check the size */ - if (H264SetBuffer(&pEncInst->stream, (RK_U8 *) pEncIn->pOutBuf, - (RK_U32) pEncIn->outBufSize) != ENCHW_OK) { - mpp_err_f("ERROR Output buffer too small\n"); - return H264ENC_INVALID_ARGUMENT; - } - - /* Write end-of-stream code */ -// H264EndOfSequence(&pEncInst->stream, &pEncInst->seqParameterSet); - - /* Bytes generated */ - pEncOut->streamSize = pEncInst->stream.byteCnt; - - /* Status == INIT Stream ended, next stream can be started */ - pEncInst->encStatus = H264ENCSTAT_INIT; - - h264e_dbg_func("leave\n"); - return H264ENC_OK; -} - diff --git a/mpp/codec/enc/h264/src/H264Init.c b/mpp/codec/enc/h264/src/H264Init.c deleted file mode 100644 index 3e08481d..00000000 --- a/mpp/codec/enc/h264/src/H264Init.c +++ /dev/null @@ -1,314 +0,0 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * 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. - */ - -/*------------------------------------------------------------------------------ - 1. Include headers -------------------------------------------------------------------------------*/ -#include "H264Init.h" -#include "enccommon.h" -#include "mpp_log.h" - -/*------------------------------------------------------------------------------ - 2. External compiler flags --------------------------------------------------------------------------------- - --------------------------------------------------------------------------------- - 3. Module defines -------------------------------------------------------------------------------*/ -#define H264ENC_MIN_ENC_WIDTH 96 -#define H264ENC_MAX_ENC_WIDTH 1920 -#define H264ENC_MIN_ENC_HEIGHT 96 -#define H264ENC_MAX_ENC_HEIGHT 1920 - -#define H264ENC_MAX_MBS_PER_PIC 8160 /* 1920x1088 */ - -#define H264ENC_MAX_LEVEL 41 - -#define H264ENC_DEFAULT_QP 26 - -/*------------------------------------------------------------------------------ - 4. Local function prototypes -------------------------------------------------------------------------------*/ -static bool_e SetParameter(H264ECtx * inst, - const H264EncConfig * pEncCfg); -static bool_e CheckParameter(const H264ECtx * inst); - -/*------------------------------------------------------------------------------ - - H264Init - - Function initializes the Encoder and create new encoder instance. - - Input pEncCfg Encoder configuration. - instAddr Pointer to instance will be stored in this address - - Return H264ENC_OK - H264ENC_MEMORY_ERROR - H264ENC_EWL_ERROR - H264ENC_EWL_MEMORY_ERROR - H264ENC_INVALID_ARGUMENT - -------------------------------------------------------------------------------*/ -H264EncRet H264Init(H264ECtx * pinst) -{ - H264ECtx *inst = pinst; - - H264EncRet ret = H264ENC_OK; - - /* Default values */ - H264SeqParameterSetInit(&inst->seqParameterSet); - H264PicParameterSetInit(&inst->picParameterSet); - H264SliceInit(&inst->slice); - - /* Initialize ASIC */ - EncAsicControllerInit(&inst->asic); - - return ret; -} - -/*------------------------------------------------------------------------------ - - SetParameter - - Set all parameters in instance to valid values depending on user config. - -------------------------------------------------------------------------------*/ -bool_e SetParameter(H264ECtx * inst, const H264EncConfig * pEncCfg) -{ - RK_S32 width, height, tmp, bps; - ASSERT(inst); - - /* Internal images, next macroblock boundary */ - width = 16 * ((pEncCfg->width + 15) / 16); - height = 16 * ((pEncCfg->height + 15) / 16); - - /* stream type */ - if (pEncCfg->streamType == H264ENC_BYTE_STREAM) { - inst->asic.regs.h264StrmMode = ASIC_H264_BYTE_STREAM; - inst->picParameterSet.byteStream = ENCHW_YES; - inst->seqParameterSet.byteStream = ENCHW_YES; - inst->rateControl.sei.byteStream = ENCHW_YES; - inst->slice.byteStream = ENCHW_YES; - } else { - inst->asic.regs.h264StrmMode = ASIC_H264_NAL_UNIT; - inst->picParameterSet.byteStream = ENCHW_NO; - inst->seqParameterSet.byteStream = ENCHW_NO; - inst->rateControl.sei.byteStream = ENCHW_NO; - inst->slice.byteStream = ENCHW_NO; - } - - /* Slice */ - inst->slice.sliceSize = 0; - - /*luma width and height*/ - inst->lumWidthSrc = pEncCfg->width; - inst->lumHeightSrc = pEncCfg->height; - - /* Macroblock */ - inst->mbPerFrame = width / 16 * height / 16; - inst->mbPerRow = width / 16; - inst->mbPerCol = height / 16; - - /* Sequence parameter set */ - inst->seqParameterSet.levelIdc = pEncCfg->level; - inst->seqParameterSet.picWidthInMbsMinus1 = width / 16 - 1; - inst->seqParameterSet.picHeightInMapUnitsMinus1 = height / 16 - 1; - - /* Set cropping parameters if required */ - if ( pEncCfg->width % 16 || pEncCfg->height % 16 ) { - inst->seqParameterSet.frameCropping = ENCHW_YES; - inst->seqParameterSet.frameCropRightOffset = (width - pEncCfg->width) / 2 ; - inst->seqParameterSet.frameCropBottomOffset = (height - pEncCfg->height) / 2; - } - - /* Level 1b is indicated with levelIdc == 11 and constraintSet3 */ - if (pEncCfg->level == H264_LEVEL_1_b) { - inst->seqParameterSet.levelIdc = 11; - inst->seqParameterSet.constraintSet3 = ENCHW_YES; - } - - /* Get the index for the table of level maximum values */ - tmp = H264GetLevelIndex(inst->seqParameterSet.levelIdc); - if (tmp == INVALID_LEVEL) { - mpp_err("H264GetLevelIndex failed\n"); - return ENCHW_NOK; - } - - inst->seqParameterSet.levelIdx = tmp; - - /* enforce maximum frame size in level */ - if (inst->mbPerFrame > H264MaxFS[inst->seqParameterSet.levelIdx]) { - while (inst->mbPerFrame > H264MaxFS[inst->seqParameterSet.levelIdx]) - inst->seqParameterSet.levelIdx++; - } - - /* enforce macroblock rate limit in level */ - { - RK_U32 mb_rate = (pEncCfg->frameRateNum * inst->mbPerFrame) / - pEncCfg->frameRateDenom; - - if (mb_rate > H264MaxMBPS[inst->seqParameterSet.levelIdx]) { - mpp_log("input mb rate %d is larger than restriction %d\n", - mb_rate, H264MaxMBPS[inst->seqParameterSet.levelIdx]); - } - } - - /* Picture parameter set */ - inst->picParameterSet.picInitQpMinus26 = (RK_S32) H264ENC_DEFAULT_QP - 26; - - /* Rate control setup */ - - /* Maximum bitrate for the specified level */ - bps = H264MaxBR[inst->seqParameterSet.levelIdx]; - - { - h264RateControl_s *rc = &inst->rateControl; - - rc->outRateDenom = pEncCfg->frameRateDenom; - rc->outRateNum = pEncCfg->frameRateNum; - rc->mbPerPic = (width / 16) * (height / 16); - rc->mbRows = height / 16; - - { - h264VirtualBuffer_s *vb = &rc->virtualBuffer; - - vb->bitRate = bps; - vb->unitsInTic = pEncCfg->frameRateDenom; - vb->timeScale = pEncCfg->frameRateNum; - vb->bufferSize = H264MaxCPBS[inst->seqParameterSet.levelIdx]; - } - - rc->hrd = ENCHW_YES; - rc->picRc = ENCHW_YES; - rc->mbRc = ENCHW_YES; - rc->picSkip = ENCHW_NO; - - rc->qpHdr = H264ENC_DEFAULT_QP; - rc->qpMin = 10; - rc->qpMax = 51; - - rc->frameCoded = ENCHW_YES; - rc->sliceTypeCur = ISLICE; - rc->sliceTypePrev = PSLICE; - rc->gopLen = 150; - - /* Default initial value for intra QP delta */ - rc->intraQpDelta = -3; - rc->fixedIntraQp = 0; - } - - /* no SEI by default */ - inst->rateControl.sei.enabled = ENCHW_NO; - - /* Pre processing */ - inst->preProcess.lumWidth = pEncCfg->width; - inst->preProcess.lumWidthSrc = - H264GetAllowedWidth(pEncCfg->width, MPP_FMT_YUV420P); - - inst->preProcess.lumHeight = pEncCfg->height; - inst->preProcess.lumHeightSrc = pEncCfg->height; - - inst->preProcess.hor_stride = pEncCfg->hor_stride; - inst->preProcess.ver_stride = pEncCfg->ver_stride; - - inst->preProcess.horOffsetSrc = 0; - inst->preProcess.verOffsetSrc = 0; - - inst->preProcess.rotation = ROTATE_0; - inst->preProcess.inputFormat = pEncCfg->input_image_format; - inst->preProcess.videoStab = 0; - - inst->preProcess.colorConversionType = 0; - EncSetColorConversion(&inst->preProcess, &inst->asic); - - return ENCHW_OK; -} - -/*------------------------------------------------------------------------------ - - CheckParameter - -------------------------------------------------------------------------------*/ -bool_e CheckParameter(const H264ECtx * inst) -{ - /* Check crop */ - if (EncPreProcessCheck(&inst->preProcess) != ENCHW_OK) { - return ENCHW_NOK; - } - - return ENCHW_OK; -} - -/*------------------------------------------------------------------------------ - - Round the width to the next multiple of 8 or 16 depending on YUV type. - -------------------------------------------------------------------------------*/ -RK_S32 H264GetAllowedWidth(RK_S32 width, MppFrameFormat inputType) -{ - if (inputType == MPP_FMT_YUV420P) { - /* Width must be multiple of 16 to make - * chrominance row 64-bit aligned */ - return ((width + 15) / 16) * 16; - } else { - /* H264ENC_YUV420_SEMIPLANAR */ - /* H264ENC_YUV422_INTERLEAVED_YUYV */ - /* H264ENC_YUV422_INTERLEAVED_UYVY */ - return ((width + 7) / 8) * 8; - } -} - -H264EncRet H264Cfg(const H264EncConfig * pEncCfg, H264ECtx * pinst) -{ - H264ECtx *inst = pinst; - - H264EncRet ret = H264ENC_OK; - - /* Set parameters depending on user config */ - if (SetParameter(inst, pEncCfg) != ENCHW_OK) { - ret = H264ENC_INVALID_ARGUMENT; - mpp_err_f("SetParameter failed\n"); - return ret; - } - - /* Check and init the rest of parameters */ - if (CheckParameter(inst) != ENCHW_OK) { - ret = H264ENC_INVALID_ARGUMENT; - mpp_err_f("CheckParameter failed\n"); - return ret; - } - - if (H264InitRc(&inst->rateControl) != ENCHW_OK) { - mpp_err_f("H264InitRc failed\n"); - return H264ENC_INVALID_ARGUMENT; - } - - /* init VUI */ - { - const h264VirtualBuffer_s *vb = &inst->rateControl.virtualBuffer; - - H264SpsSetVuiTimigInfo(&inst->seqParameterSet, - vb->timeScale, vb->unitsInTic); - } - - if (inst->seqParameterSet.levelIdc >= 31) - inst->asic.regs.h264Inter4x4Disabled = 1; - else - inst->asic.regs.h264Inter4x4Disabled = 0; - - return ret; -} - diff --git a/mpp/codec/enc/h264/src/H264Mad.c b/mpp/codec/enc/h264/src/H264Mad.c deleted file mode 100644 index af0d582f..00000000 --- a/mpp/codec/enc/h264/src/H264Mad.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * 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. - */ - -#include "H264Mad.h" - -/*------------------------------------------------------------------------------ - - Init MAD structure - -------------------------------------------------------------------------------*/ -void H264MadInit(madTable_s *mad, RK_U32 mbPerFrame) -{ - RK_S32 i; - - mad->mbPerFrame = mbPerFrame; - - mad->threshold = 256 * 6; - - for (i = 0; i < MAD_TABLE_LEN; i++) { - mad->th[i] = 0; - mad->count[i] = 0; - } - mad->pos = 0; - mad->len = 0; -} - -/*------------------------------------------------------------------------------ - update_tables() -------------------------------------------------------------------------------*/ -static void update_tables(madTable_s *p, RK_S32 th, RK_S32 count) -{ - const RK_S32 clen = 3; - RK_S32 tmp = p->pos; - - p->th[tmp] = th; - p->count[tmp] = count; - - if (++p->pos >= clen) { - p->pos = 0; - } - if (p->len < clen) { - p->len++; - } -} -/*------------------------------------------------------------------------------ - lin_sx() calculate value of Sx for n points. -------------------------------------------------------------------------------*/ -static RK_S32 lin_sx(RK_S32 *x, RK_S32 n) -{ - RK_S32 sum = 0; - - while (n--) { - sum += x[n]; - if (sum < 0) { - return I32_MAX; - } - } - return sum; -} - -/*------------------------------------------------------------------------------ - lin_sxy() calculate value of Sxy for n points. -------------------------------------------------------------------------------*/ -static RK_S32 lin_sxy(RK_S32 *qp, RK_S32 *r, RK_S32 n) -{ - RK_S32 sum = 0; - - while (n--) { - sum += qp[n] * r[n]; - if (sum < 0) { - return I32_MAX; - } - } - return sum; -} - -/*------------------------------------------------------------------------------ - lin_nsxx() calculate value of n * Sxx for n points. -------------------------------------------------------------------------------*/ -static RK_S32 lin_nsxx(RK_S32 *qp, RK_S32 n) -{ - RK_S32 sum = 0, d = n; - - while (n--) { - sum += d * qp[n] * qp[n]; - if (sum < 0) { - return I32_MAX; - } - } - return sum; -} - -/*------------------------------------------------------------------------------ - update_model() Update model parameter by Linear Regression. -------------------------------------------------------------------------------*/ -static void update_model(madTable_s *p) -{ - RK_S32 *count = p->count, *th = p->th, n = p->len; - RK_S32 sx = lin_sx(p->count, n); - RK_S32 sy = lin_sx(p->th, n); - RK_S32 a1 = 0, a2 = 0; - - /*RK_S32 i; - for (i = 0; i < n; i++) { - printf("model: cnt %i th %i\n", count[i], th[i]); - }*/ - - ASSERT(sx >= 0); - ASSERT(sy >= 0); - - if (n > 1) { - a1 = lin_sxy(count, th, n); - a1 = a1 < (I32_MAX / n) ? a1 * n : I32_MAX; - - if (sy) { - a1 -= sx < (I32_MAX / sy) ? sx * sy : I32_MAX; - } - - a2 = (lin_nsxx(count, n) - (sx * sx)); - if (a2) { - a1 = DIV(a1 * DSCY, a2); - } else { - a1 = 0; - } - - /* Value of a1 shouldn't be excessive */ - a1 = MAX(a1, 0); - a1 = MIN(a1, 1024 * DSCY); - - if (n) - a2 = DIV(sy, n) - DIV(a1 * sx, n * DSCY); - else - a2 = 0; - } - - p->a1 = a1; - p->a2 = a2; - - /*printf("model: a2:%9d a1:%8d\n", p->a2, p->a1);*/ -} - -/*------------------------------------------------------------------------------ - - Update MAD threshold based on previous frame count of macroblocks with MAD - under threshold. Trying to adjust threshold so that madCount == targetCount. - -------------------------------------------------------------------------------*/ -void H264MadThreshold(madTable_s *mad, RK_U32 madCount) -{ - /* Target to improve quality for 30% of macroblocks */ - RK_U32 targetCount = 30 * mad->mbPerFrame / 100; // modify by lance 2016.05.12 - RK_S32 threshold = mad->threshold; - RK_S32 lowLimit, highLimit; - - update_tables(mad, mad->threshold, madCount); - update_model(mad); - - /* Calculate new threshold for next frame using either linear regression - * model or adjustment based on current setting */ - if (mad->a1) - threshold = mad->a1 * targetCount / DSCY + mad->a2; - else if (madCount < targetCount) - threshold = MAX(mad->threshold * 5 / 4, mad->threshold + 256); - else - threshold = MIN(mad->threshold * 3 / 4, mad->threshold - 256); - - /* For small count, ensure that we increase the threshold minimum 1 step */ - if (madCount < targetCount / 2) - threshold = MAX(threshold, mad->threshold + 256); - - /* If previous frame had zero count, ensure that we increase threshold */ - if (!madCount) - threshold = MAX(threshold, mad->threshold + 256 * 4); - - /* Limit how much the threshold can change between two frames */ - lowLimit = mad->threshold / 2; - highLimit = MAX(mad->threshold * 2, 256 * 4); - mad->threshold = MIN(highLimit, MAX(lowLimit, threshold)); - - /* threshold_div256 has 6-bits range [0,63] */ - mad->threshold = ((mad->threshold + 128) / 256) * 256; - mad->threshold = MAX(0, MIN(63 * 256, mad->threshold)); -} - diff --git a/mpp/codec/enc/h264/src/H264NalUnit.c b/mpp/codec/enc/h264/src/H264NalUnit.c deleted file mode 100644 index 33728d44..00000000 --- a/mpp/codec/enc/h264/src/H264NalUnit.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * 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. - */ - -/*------------------------------------------------------------------------------ - 1. Include headers -------------------------------------------------------------------------------*/ -#include "enccommon.h" -#include "H264NalUnit.h" - -/*------------------------------------------------------------------------------ - 2. External compiler flags --------------------------------------------------------------------------------- - --------------------------------------------------------------------------------- - 3. Module defines -------------------------------------------------------------------------------*/ - -/*------------------------------------------------------------------------------ - 4. Local function prototypes -------------------------------------------------------------------------------*/ - -/*------------------------------------------------------------------------------ - - H264NalUnit - -------------------------------------------------------------------------------*/ -void H264NalUnitHdr(stream_s * stream, RK_S32 nalRefIdc, nalUnitType_e nalUnitType, - true_e byteStream) -{ - if (byteStream == ENCHW_YES) { - H264PutBits(stream, 0, 8); - COMMENT("BYTE STREAM: leadin_zero_8bits"); - - H264PutBits(stream, 0, 8); - COMMENT("BYTE STREAM: Start_code_prefix"); - - H264PutBits(stream, 0, 8); - COMMENT("BYTE STREAM: Start_code_prefix"); - - H264PutBits(stream, 1, 8); - COMMENT("BYTE STREAM: Start_code_prefix"); - } - - H264PutBits(stream, 0, 1); - COMMENT("forbidden_zero_bit"); - - H264PutBits(stream, nalRefIdc, 2); - COMMENT("nal_ref_idc"); - - H264PutBits(stream, (RK_S32) nalUnitType, 5); - COMMENT("nal_unit_type"); - - stream->zeroBytes = 0; /* we start new counter for zero bytes */ - - return; -} - -/*------------------------------------------------------------------------------ - - H264NalUnitTrailinBits - -------------------------------------------------------------------------------*/ -void H264NalUnitTrailinBits(stream_s * stream, true_e byteStream) -{ - H264RbspTrailingBits(stream); - - if (byteStream == ENCHW_YES) { -#if 0 /* system model has removed this */ - H264PutBits(stream, 0, 8); - COMMENT("BYTE STREAM: trailing_zero_8bits"); -#endif - } - - return; -} - -RK_U32 H264FillerNALU(stream_s * sp, RK_S32 cnt, true_e byteStream) -{ - RK_S32 i = cnt; - RK_U32 nal_size; - - nal_size = sp->byteCnt; - - ASSERT(sp != NULL); - - H264NalUnitHdr(sp, 0, FILLERDATA, byteStream); - - for (; i > 0; i--) { - H264NalBits(sp, 0xFF, 8); - COMMENT("filler ff_byte"); - } - H264RbspTrailingBits(sp); - - nal_size = sp->byteCnt - nal_size; - - return nal_size; -} diff --git a/mpp/codec/enc/h264/src/H264PictureParameterSet.c b/mpp/codec/enc/h264/src/H264PictureParameterSet.c deleted file mode 100644 index 1568dd35..00000000 --- a/mpp/codec/enc/h264/src/H264PictureParameterSet.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * 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. - */ - -/*------------------------------------------------------------------------------ - 1. Include headers -------------------------------------------------------------------------------*/ -#include "H264PictureParameterSet.h" -#include "H264NalUnit.h" - -/*------------------------------------------------------------------------------ - 2. External compiler flags --------------------------------------------------------------------------------- - --------------------------------------------------------------------------------- - 3. Module defines -------------------------------------------------------------------------------*/ - -/*------------------------------------------------------------------------------ - 4. Local function prototypes -------------------------------------------------------------------------------*/ - -/*------------------------------------------------------------------------------ - - H264PicParameterInit - -------------------------------------------------------------------------------*/ -void H264PicParameterSetInit(pps_s * pps) -{ - pps->byteStream = ENCHW_YES; - pps->picParameterSetId = 0; - pps->seqParameterSetId = 0; - pps->entropyCodingMode = ENCHW_NO; - pps->picOrderPresent = ENCHW_NO; - pps->numSliceGroupsMinus1 = 0; - pps->numRefIdxL0ActiveMinus1 = 0; - pps->numRefIdxL1ActiveMinus1 = 0; - pps->weightedPred = ENCHW_NO; - pps->weightedBipredIdc = 0; - pps->picInitQpMinus26 = 0; - pps->picInitQsMinus26 = 0; - pps->chromaQpIndexOffset = 2; - pps->deblockingFilterControlPresent = ENCHW_YES; - pps->constIntraPred = ENCHW_NO; - pps->redundantPicCntPresent = ENCHW_NO; - pps->transform8x8Mode = ENCHW_NO; - - return; -} - -/*------------------------------------------------------------------------------ - - H264PicParameterSet - -------------------------------------------------------------------------------*/ -void H264PicParameterSet(stream_s * stream, pps_s * pps) -{ - /* Nal unit sytax */ - H264NalUnitHdr(stream, 1, PPSET, pps->byteStream); - - H264ExpGolombUnsigned(stream, pps->picParameterSetId); - COMMENT("pic_parameter_set_id"); - - H264ExpGolombUnsigned(stream, pps->picParameterSetId); - COMMENT("seq_parameter_set_id"); - - H264NalBits(stream, (RK_S32) pps->entropyCodingMode, 1); - COMMENT("entropy_coding_mode_flag"); - - H264NalBits(stream, (RK_S32) pps->picOrderPresent, 1); - COMMENT("pic_order_present_flag"); - - H264ExpGolombUnsigned(stream, pps->numSliceGroupsMinus1); - COMMENT("num_slice_groups_minus1"); - - /* if( num_slice_groups_minus1 > 0 ) etc... not implementet yet */ - - H264ExpGolombUnsigned(stream, pps->numRefIdxL0ActiveMinus1); - COMMENT("num_ref_idx_l0_active_minus1"); - - H264ExpGolombUnsigned(stream, pps->numRefIdxL1ActiveMinus1); - COMMENT("num_ref_idx_l1_active_minus1"); - - H264NalBits(stream, (RK_S32) pps->weightedPred, 1); - COMMENT("weighted_pred_flag"); - - H264NalBits(stream, pps->weightedBipredIdc, 2); - COMMENT("weighted_bipred_idc"); - - H264ExpGolombSigned(stream, pps->picInitQpMinus26); - COMMENT("pic_init_qp_minus26"); - - H264ExpGolombSigned(stream, pps->picInitQsMinus26); - COMMENT("pic_init_qs_minus26"); - - H264ExpGolombSigned(stream, pps->chromaQpIndexOffset); - COMMENT("chroma_qp_index_offset"); - - H264NalBits(stream, (RK_S32) pps->deblockingFilterControlPresent, 1); - COMMENT("deblocking_filter_control_present_flag"); - - H264NalBits(stream, (RK_S32) pps->constIntraPred, 1); - COMMENT("constrained_intra_pred_flag"); - - H264NalBits(stream, (RK_S32) pps->redundantPicCntPresent, 1); - COMMENT("redundant_pic_cnt_present_flag"); - - if (pps->transform8x8Mode == ENCHW_YES) { - H264NalBits(stream, pps->transform8x8Mode, 1); - COMMENT("transform_8x8_mode_flag"); - - H264NalBits(stream, 0, 1); - COMMENT("pic_scaling_matrix_present_flag"); - - H264ExpGolombSigned(stream, pps->chromaQpIndexOffset); - COMMENT("second_chroma_qp_index_offset"); - } - - - H264NalUnitTrailinBits(stream, pps->byteStream); - - return; -} diff --git a/mpp/codec/enc/h264/src/H264PutBits.c b/mpp/codec/enc/h264/src/H264PutBits.c deleted file mode 100644 index 4ec6aa5b..00000000 --- a/mpp/codec/enc/h264/src/H264PutBits.c +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * 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. - */ - -/*------------------------------------------------------------------------------ - 1. Include headers -------------------------------------------------------------------------------*/ -#include "H264PutBits.h" -#include "enccommon.h" - -/*------------------------------------------------------------------------------ - 2. External compiler flags --------------------------------------------------------------------------------- - --------------------------------------------------------------------------------- - 3. Module defines -------------------------------------------------------------------------------*/ - -/*------------------------------------------------------------------------------ - 4. Local function prototypes -------------------------------------------------------------------------------*/ -static bool_e H264BufferStatus(stream_s * stream); - -/*------------------------------------------------------------------------------ - - H264PutBits - - Write bits to stream. For example (value=2, number=4) write 0010 to the - stream. Number of bits must be < 25, otherwise overflow occur. Four - bytes is maximum number of bytes to put stream and there should be at - least 5 byte free space available because of byte buffer. - - Used only for NAL unit headers! - - Input stream Pointer to the stream stucture - value Bit pattern - number Number of bits - -------------------------------------------------------------------------------*/ -void H264PutBits(stream_s * buffer, RK_S32 value, RK_S32 number) -{ - RK_S32 bits; - RK_U32 byteBuffer = buffer->byteBuffer; - RK_U8 *stream = buffer->stream; - - if (H264BufferStatus(buffer) != ENCHW_OK) { - return; - } - - TRACE_BIT_STREAM(value, number); - - /* Debug: value is too big */ - ASSERT(value < (1 << number)); - ASSERT(number < 25); - - bits = number + buffer->bufferedBits; - value <<= (32 - bits); - byteBuffer = byteBuffer | value; - - while (bits > 7) { - *stream = (RK_U8) (byteBuffer >> 24); - - bits -= 8; - byteBuffer <<= 8; - stream++; - buffer->byteCnt++; - } - - buffer->byteBuffer = byteBuffer; - buffer->bufferedBits = (RK_U8) bits; - buffer->stream = stream; - - return; -} - -/*------------------------------------------------------------------------------ - - H264PutNalBits - - Write bits to stream. For example (value=2, number=4) write 0010 to the - stream. Number of bits must be < 25, otherwise overflow occur. Four - bytes is maximum number of bytes to put stream and there should be at - least 5 byte free space available because of byte buffer. - - Used only for NAL unit RBSP data! - - Input stream Pointer to the stream stucture - value Bit pattern - number Number of bits - -------------------------------------------------------------------------------*/ -void H264PutNalBits(stream_s * buffer, RK_S32 value, RK_S32 number) -{ - RK_S32 bits; - RK_U8 *stream = buffer->stream; - RK_U32 byteBuffer = buffer->byteBuffer; - - ASSERT(value < (1 << number)); - ASSERT(number < 25); - - TRACE_BIT_STREAM(value, number); - - bits = number + buffer->bufferedBits; - byteBuffer = byteBuffer | ((RK_U32) value << (32 - bits)); - - while (bits > 7) { - RK_S32 zeroBytes = buffer->zeroBytes; - RK_S32 byteCnt = buffer->byteCnt; - - if (H264BufferStatus(buffer) != ENCHW_OK) - return; - - *stream = (RK_U8) (byteBuffer >> 24); - byteCnt++; - - if ((zeroBytes == 2) && (*stream < 4)) { - *stream++ = 3; - *stream = (RK_U8) (byteBuffer >> 24); - byteCnt++; - zeroBytes = 0; - buffer->emulCnt++; - } - - if (*stream == 0) - zeroBytes++; - else - zeroBytes = 0; - - bits -= 8; - byteBuffer <<= 8; - stream++; - buffer->zeroBytes = zeroBytes; - buffer->byteCnt = byteCnt; - buffer->stream = stream; - } - - buffer->bufferedBits = (RK_U8) bits; - buffer->byteBuffer = byteBuffer; -} - -/*------------------------------------------------------------------------------ - - EncSetBuffer - - Set stream buffer. - - Input buffer Pointer to the stream_s structure. - stream Pointer to stream buffer. - size Size of stream buffer. - -------------------------------------------------------------------------------*/ -bool_e H264SetBuffer(stream_s * buffer, RK_U8 * stream, RK_S32 size) -{ - buffer->stream = stream; - buffer->size = size; - buffer->byteCnt = 0; - buffer->overflow = ENCHW_NO; - buffer->zeroBytes = 0; - buffer->byteBuffer = 0; - buffer->bufferedBits = 0; - - if (H264BufferStatus(buffer) != ENCHW_OK) { - return ENCHW_NOK; - } - /*buffer->stream[0] = 0; - buffer->stream[1] = 0;*/ - - return ENCHW_OK; -} - -/*------------------------------------------------------------------------------ - - BufferStatus - - Check fullness of stream buffer. - - Input stream Pointer to the stream stucture. - - Return ENCHW_OK Buffer status is ENCHW_OK. - ENCHW_NOK Buffer overflow. - -------------------------------------------------------------------------------*/ -bool_e H264BufferStatus(stream_s * stream) -{ - if (stream->byteCnt + 5 > stream->size) { - stream->overflow = ENCHW_YES; - return ENCHW_NOK; - } - - return ENCHW_OK; -} - -/*------------------------------------------------------------------------------ - - H264ExpGolombUnsigned - -------------------------------------------------------------------------------*/ -void H264ExpGolombUnsigned(stream_s * stream, RK_U32 val) -{ - RK_U32 numBits = 0; - - val++; - while (val >> ++numBits); - - if (numBits > 12) { - RK_U32 tmp; - tmp = numBits - 1; - - if (tmp > 24) { - tmp -= 24; - H264NalBits(stream, 0, 24); - } - - H264NalBits(stream, 0, tmp); - COMMENT("++"); - - if (numBits > 24) { - numBits -= 24; - H264NalBits(stream, val >> numBits, 24); - val = val >> numBits; - } - - H264NalBits(stream, val, numBits); - } else { - H264NalBits(stream, val , 2 * numBits - 1); - } - -} - -/*------------------------------------------------------------------------------ - - H264ExpGolombSigned - -------------------------------------------------------------------------------*/ -void H264ExpGolombSigned(stream_s * stream, RK_S32 val) -{ - RK_U32 tmp; - - if (val > 0) - tmp = (RK_U32) (2 * val - 1); - else - tmp = (RK_U32) (-2 * val); - - H264ExpGolombUnsigned(stream, tmp); -} - -/*------------------------------------------------------------------------------ - - H264RbspTrailingBits - - Function add rbsp_stop_one_bit and p_alignment_zero_bit until next byte - aligned if needed. Note that stream->stream[1] is bits in byte bufer. - - Input stream Pointer to the stream structure. - -------------------------------------------------------------------------------*/ -void H264RbspTrailingBits(stream_s * stream) -{ - H264PutNalBits(stream, 1, 1); - COMMENT("rbsp_stop_one_bit"); - if (stream->bufferedBits > 0) { - H264PutNalBits(stream, 0, 8 - stream->bufferedBits); - COMMENT("bsp_alignment_zero_bit(s)"); - } - - return; -} diff --git a/mpp/codec/enc/h264/src/H264RateControl.c b/mpp/codec/enc/h264/src/H264RateControl.c deleted file mode 100644 index 70ccf02c..00000000 --- a/mpp/codec/enc/h264/src/H264RateControl.c +++ /dev/null @@ -1,1250 +0,0 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * 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. - */ - -/* - * Using only one leaky bucket (Multible buckets is supported by std). - * Constant bit rate (CBR) operation, ie. leaky bucket drain rate equals - * average rate of the stream, is enabled if RC_CBR_HRD = 1. Frame skiping and - * filler data are minimum requirements for the CBR conformance. - * - * Constant HRD parameters: - * low_delay_hrd_flag = 0, assumes constant delay mode. - * cpb_cnt_minus1 = 0, only one leaky bucket used. - * (cbr_flag[0] = RC_CBR_HRD, CBR mode.) - */ -#include "H264RateControl.h" -#include "H264Slice.h" - -/*------------------------------------------------------------------------------ - Module defines -------------------------------------------------------------------------------*/ - -/* Define this if strict bitrate control is needed, each window has a strict - * bit budget. Otherwise a moving window is used for smoother quality. -#define RC_WINDOW_STRICT*/ - -#ifdef TRACE_RC -#include -FILE *fpRcTrc = NULL; -/* Select debug output: fpRcTrc or stdout */ -#define DBGOUTPUT fpRcTrc -/* Select debug level: 0 = minimum, 2 = maximum */ -#define DBG_LEVEL 2 -#define DBG(l, str) if (l <= DBG_LEVEL) fprintf str -#else -#define DBG(l, str) -#endif - -#define INITIAL_BUFFER_FULLNESS 60 /* Decoder Buffer in procents */ -#define MIN_PIC_SIZE 50 /* Procents from picPerPic */ - -#define DIV(a, b) ((b) ? ((a) + (SIGN(a) * (b)) / 2) / (b) : (a)) -#define DSCY 32 /* n * 32 */ -#define I32_MAX 2147483647 /* 2 ^ 31 - 1 */ -#define QP_DELTA 2 -#define QP_DELTA_LIMIT 10 -#define INTRA_QP_DELTA (0) -#define WORD_CNT_MAX 65535 -#define CLIP3(v, min, max) ((v) < (min) ? (min) : ((v) > (max) ? (max) : (v))) // add by lance 2016.05.12 -/*------------------------------------------------------------------------------ - Local structures -------------------------------------------------------------------------------*/ -/* q_step values scaled up by 4 and evenly rounded */ -RK_S32 q_step[53] = { 3, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, 9, 10, 11, - 13, 14, 16, 18, 20, 23, 25, 28, 32, 36, 40, 45, 51, 57, 64, 72, 80, 90, - 101, 114, 128, 144, 160, 180, 203, 228, 256, 288, 320, 360, 405, 456, - 513, 577, 640, 720, 810, 896 - }; - -/*------------------------------------------------------------------------------ - Local function prototypes -------------------------------------------------------------------------------*/ - -static RK_S32 InitialQp_new(RK_S32 bits, RK_S32 pels); -static void MbQuant_new(h264RateControl_s * rc); -static void LinearModel_new(h264RateControl_s * rc); -static void AdaptiveModel_new(h264RateControl_s * rc); -static void SourceParameter_new(h264RateControl_s * rc, RK_S32 nonZeroCnt); -static void PicSkip_new(h264RateControl_s * rc); -static void PicQuantLimit_new(h264RateControl_s * rc); -static RK_S32 VirtualBuffer_new(h264VirtualBuffer_s *vb, RK_S32 timeInc, true_e hrd); -static void PicQuant_new(h264RateControl_s * rc); -static RK_S32 avg_rc_error_new(linReg_s *p); -static void update_rc_error_new(linReg_s *p, RK_S32 bits); -static RK_S32 gop_avg_qp_new(h264RateControl_s *rc); -static RK_S32 new_pic_quant_new(linReg_s *p, RK_S32 bits, true_e useQpDeltaLimit); -static RK_S32 get_avg_bits_new(linReg_s *p, RK_S32 n); -static void update_tables_new(linReg_s *p, RK_S32 qp, RK_S32 bits); -static void update_model_new(linReg_s *p); -static RK_S32 lin_sy_new(RK_S32 *qp, RK_S32 *r, RK_S32 n); -static RK_S32 lin_sx_new(RK_S32 *qp, RK_S32 n); -static RK_S32 lin_sxy_new(RK_S32 *qp, RK_S32 *r, RK_S32 n); -static RK_S32 lin_nsxx_new(RK_S32 *qp, RK_S32 n); - - -/*------------------------------------------------------------------------------ - - H264FillerRc - - Stream watermarking. Insert filler NAL unit of certain size after each - Nth frame. - -------------------------------------------------------------------------------*/ -RK_U32 H264FillerRc(h264RateControl_s * rc, RK_U32 frameCnt) -{ - const RK_U8 filler[] = { 0, 9, 0, 9, 9, 9, 0, 2, 2, 0 }; - RK_U32 idx; - - if (rc->fillerIdx == (RK_U32) (-1)) { - rc->fillerIdx = sizeof(filler) / sizeof(*filler) - 1; - } - - idx = rc->fillerIdx; - if (frameCnt != 0 && ((frameCnt % 128) == 0)) { - idx++; - } - idx %= sizeof(filler) / sizeof(*filler); - - if (idx != rc->fillerIdx) { - rc->fillerIdx = idx; - return filler[idx] + 1; - } - return 0; -} - -/*------------------------------------------------------------------------------ - - Calculate() I try to avoid overflow and calculate good enough result of a*b/c - -------------------------------------------------------------------------------*/ -RK_S32 H264Calculate(RK_S32 a, RK_S32 b, RK_S32 c) -{ - RK_U32 left = 32; - RK_U32 right = 0; - RK_U32 shift; - RK_S32 sign = 1; - RK_S32 tmp; - - if (a == 0 || b == 0) { - return 0; - } else if ((a * b / b) == a && c != 0) { - return (a * b / c); - } - if (a < 0) { - sign = -1; - a = -a; - } - if (b < 0) { - sign *= -1; - b = -b; - } - if (c < 0) { - sign *= -1; - c = -c; - } - - if (c == 0 ) { - return 0x7FFFFFFF * sign; - } - - if (b > a) { - tmp = b; - b = a; - a = tmp; - } - - for (--left; (((RK_U32)a << left) >> left) != (RK_U32)a; --left); - left--; /* unsigned values have one more bit on left, - we want signed accuracy. shifting signed values gives - lint warnings */ - - while (((RK_U32)b >> right) > (RK_U32)c) { - right++; - } - - if (right > left) { - return 0x7FFFFFFF * sign; - } else { - shift = left - right; - return (RK_S32)((((RK_U32)a << shift) / (RK_U32)c * (RK_U32)b) >> shift) * sign; - } -} - -/*------------------------------------------------------------------------------ - - H264InitRc() Initialize rate control. - -------------------------------------------------------------------------------*/ -bool_e H264InitRc(h264RateControl_s * rc) -{ - h264VirtualBuffer_s *vb = &rc->virtualBuffer; - - if ((rc->qpMax > 51)) { - return ENCHW_NOK; - } - - /* QP -1: Initial QP estimation done by RC */ - if (rc->qpHdr == -1) { - RK_S32 tmp = H264Calculate(vb->bitRate, rc->outRateDenom, rc->outRateNum); - rc->qpHdr = InitialQp_new(tmp, rc->mbPerPic * 16 * 16); - PicQuantLimit_new(rc); - } - - if ((rc->qpHdr > rc->qpMax) || (rc->qpHdr < rc->qpMin)) { - return ENCHW_NOK; - } - - rc->mbQpAdjustment = MIN(7, MAX(-8, rc->mbQpAdjustment)); - - /* HRD needs frame RC and macroblock RC*/ - if (rc->hrd == ENCHW_YES) { - rc->picRc = ENCHW_YES; - rc->mbRc = ENCHW_YES; - } - - /* Macroblock RC needs frame RC */ - if (rc->mbRc == ENCHW_YES) - rc->picRc = ENCHW_YES; - - /* mbQpAdjustment disables macroblock RC */ - if (rc->mbQpAdjustment && rc->mbRc) - rc->mbRc = ENCHW_NO; - - rc->coeffCntMax = rc->mbPerPic * 24 * 16; - rc->frameCoded = ENCHW_YES; - rc->sliceTypeCur = ISLICE; - rc->sliceTypePrev = PSLICE; - - rc->qpHdrPrev = rc->qpHdr; - rc->fixedQp = rc->qpHdr; - - vb->bitPerPic = H264Calculate(vb->bitRate, rc->outRateDenom, rc->outRateNum); - - /* Check points are smootly distributed except last one */ - { - h264QpCtrl_s *qpCtrl = &rc->qpCtrl; - - qpCtrl->checkPoints = MIN(rc->mbRows - 1, CHECK_POINTS_MAX); - - if (rc->mbRc == ENCHW_YES) { - qpCtrl->checkPointDistance = - rc->mbPerPic / (qpCtrl->checkPoints + 1); - } else { - qpCtrl->checkPointDistance = 0; - } - } - -#if defined(TRACE_RC) && (DBGOUTPUT == fpRcTrc) - if (!fpRcTrc) fpRcTrc = fopen("rc.trc", "wt"); -#endif - - /* new rate control algorithm */ - update_rc_error_new(&rc->rError, 0x7fffffff); - update_rc_error_new(&rc->intraError, 0x7fffffff); - rc->frameCnt = 0; - rc->linReg.pos = 0; - rc->linReg.len = 0; - rc->linReg.a1 = 0; - rc->linReg.a2 = 0; - rc->linReg.qs[0] = q_step[51]; - rc->linReg.bits[0] = 0; - rc->linReg.qp_prev = rc->qpHdr; - rc->intra.pos = 0; - rc->intra.len = 0; - rc->intra.a1 = 0; - rc->intra.a2 = 0; - rc->intra.qs[0] = q_step[51]; - rc->intra.bits[0] = 0; - rc->intra.qp_prev = rc->qpHdr; - rc->gopQpSum = 0; - rc->gopQpDiv = 0; - /* API parameter is named gopLen but the actual usage is rate controlling - * window in frames. RC tries to match the target bitrate inside the - * window. Each window can contain multiple GOPs and the RC adapts to the - * intra rate by calculating intraInterval. */ - rc->windowLen = rc->gopLen; - vb->windowRem = rc->gopLen; - rc->intraIntervalCtr = rc->intraInterval = rc->gopLen; - rc->targetPicSize = 0; - rc->frameBitCnt = 0; - //printf("rc->gopLen=%d\n", rc->gopLen); - DBG(0, (DBGOUTPUT, "\nInitRc: picRc\t\t%i hrd\t%i PicSkip_new\t%i\n", - rc->picRc, rc->hrd, rc->PicSkip_new)); - DBG(0, (DBGOUTPUT, " mbRc\t\t\t%i qpHdr\t%i Min,Max\t%i,%i\n", - rc->mbRc, rc->qpHdr, rc->qpMin, rc->qpMax)); - DBG(0, (DBGOUTPUT, " checkPointDistance\t%i\n", - rc->qpCtrl.checkPointDistance)); - - DBG(0, (DBGOUTPUT, " CPBsize\t%i\n BitRate\t%i\n BitPerPic\t%i\n", - vb->bufferSize, vb->bitRate, vb->bitPerPic)); - - rc->sei.hrd = rc->hrd; - - if (rc->hrd) { - vb->bucketFullness = - H264Calculate(vb->bufferSize, INITIAL_BUFFER_FULLNESS, 100); - rc->gDelaySum = H264Calculate(90000, vb->bufferSize, vb->bitRate); - rc->gInitialDelay = H264Calculate(90000, vb->bucketFullness, vb->bitRate); - rc->gInitialDoffs = rc->gDelaySum - rc->gInitialDelay; - vb->bucketFullness = vb->bufferSize - vb->bucketFullness; - /* Because is the first frame. Avoids if clauses in VirtualBuffer_new() */ - vb->bucketFullness += vb->bitPerPic; -#ifdef TRACE_RC - rc->gBufferMin = vb->bufferSize; - rc->gBufferMax = 0; -#endif - rc->sei.icrd = (RK_U32)rc->gInitialDelay; - rc->sei.icrdo = (RK_U32)rc->gInitialDoffs; - - DBG(1, (DBGOUTPUT, "\n InitialDelay\t%i\n Offset\t\t%i\n", - rc->gInitialDelay, rc->gInitialDoffs)); - } - return ENCHW_OK; -} - -/*------------------------------------------------------------------------------ - - InitialQp_new() Returns sequence initial quantization parameter. - -------------------------------------------------------------------------------*/ -static RK_S32 InitialQp_new(RK_S32 bits, RK_S32 pels) -{ - const RK_S32 qp_tbl[2][9] = { - {27, 44, 72, 119, 192, 314, 453, 653, 0x7FFFFFFF}, - /*{26, 38, 59, 96, 173, 305, 545, 0x7FFFFFFF},*/ - {49, 45, 41, 37, 33, 29, 25, 21, 17} - }; - const RK_S32 upscale = 8000; - RK_S32 i = -1; - - /* prevents overflow, QP would anyway be 17 with this high bitrate - for all resolutions under and including 1920x1088 */ - if (bits > 1000000) - return 17; - - /* Make room for multiplication */ - pels >>= 8; - bits >>= 5; - - /* Adjust the bits value for the current resolution */ - bits *= pels + 250; - ASSERT(pels > 0); - ASSERT(bits > 0); - bits /= 350 + (3 * pels) / 4; - bits = H264Calculate(bits, upscale, pels << 6); - - while (qp_tbl[0][++i] < bits); - - DBG(0, (DBGOUTPUT, "BPP\t\t%d\n", bits)); - - return qp_tbl[1][i]; -} - -/*------------------------------------------------------------------------------ - VirtualBuffer_new() Return difference of target and real buffer fullness. - Virtual buffer and real bit count grow until one second. After one second - output bit rate per second is removed from virtualBitCnt and realBitCnt. Bit - drifting has been taken care. - - If the leaky bucket in VBR mode becomes empty (e.g. underflow), those R * T_e - bits are lost and must be decremented from virtualBitCnt. (NOTE: Drift - calculation will mess virtualBitCnt up, so the loss is added to realBitCnt) -------------------------------------------------------------------------------*/ -static RK_S32 VirtualBuffer_new(h264VirtualBuffer_s *vb, RK_S32 timeInc, true_e hrd) -{ - RK_S32 drift, target, bitPerPic = vb->bitPerPic; - if (hrd) { -#if RC_CBR_HRD - /* In CBR mode, bucket _must not_ underflow. Insert filler when - * needed. */ - vb->bucketFullness -= bitPerPic; -#else - if (vb->bucketFullness >= bitPerPic) { - vb->bucketFullness -= bitPerPic; - } else { - vb->realBitCnt += (bitPerPic - vb->bucketFullness); - vb->bucketFullness = 0; - } -#endif - } - - /* Saturate realBitCnt, this is to prevent overflows caused by much greater - bitrate setting than is really possible to reach */ - if (vb->realBitCnt > 0x1FFFFFFF) - vb->realBitCnt = 0x1FFFFFFF; - if (vb->realBitCnt < -0x1FFFFFFF) - vb->realBitCnt = -0x1FFFFFFF; - - vb->picTimeInc += timeInc; - vb->virtualBitCnt += H264Calculate(vb->bitRate, timeInc, vb->timeScale); - target = vb->virtualBitCnt - vb->realBitCnt; - - /* Saturate target, prevents rc going totally out of control. - This situation should never happen. */ - if (target > 0x1FFFFFFF) - target = 0x1FFFFFFF; - if (target < -0x1FFFFFFF) - target = -0x1FFFFFFF; - - /* picTimeInc must be in range of [0, timeScale) */ - while (vb->picTimeInc >= vb->timeScale) { - vb->picTimeInc -= vb->timeScale; - vb->virtualBitCnt -= vb->bitRate; - vb->realBitCnt -= vb->bitRate; - // limit realBitCnt to avoid compensating too many bits for next frame - if (vb->realBitCnt < 0 && (ABS(vb->realBitCnt) > vb->bitRate / 10)) - vb->realBitCnt = -vb->bitRate / 10; - } - drift = H264Calculate(vb->bitRate, vb->picTimeInc, vb->timeScale); - drift -= vb->virtualBitCnt; - vb->virtualBitCnt += drift; - - DBG(1, (DBGOUTPUT, "virtualBitCnt:\t\t%6i realBitCnt: %i ", - vb->virtualBitCnt, vb->realBitCnt)); - DBG(1, (DBGOUTPUT, "target: %i timeInc: %i\n", target, timeInc)); - return target; -} - -/*------------------------------------------------------------------------------ - H264AfterPicRc() Update source model, bit rate target error and linear - regression model for frame QP calculation. If HRD enabled, check leaky bucket - status and return RC_OVERFLOW if coded frame must be skipped. Otherwise - returns number of required filler payload bytes. -------------------------------------------------------------------------------*/ -RK_S32 H264AfterPicRc(h264RateControl_s * rc, RK_U32 nonZeroCnt, RK_U32 byteCnt, - RK_U32 qpSum) -{ - h264VirtualBuffer_s *vb = &rc->virtualBuffer; - RK_S32 bitPerPic = rc->virtualBuffer.bitPerPic; - RK_S32 tmp, stat, bitCnt = (RK_S32)byteCnt * 8; - - (void) bitPerPic; - rc->qpSum = (RK_S32)qpSum; - rc->frameBitCnt = bitCnt; - rc->nonZeroCnt = nonZeroCnt; - rc->gopBitCnt += bitCnt; - rc->frameCnt++; - - if (rc->targetPicSize) { - tmp = ((bitCnt - rc->targetPicSize) * 100) / - rc->targetPicSize; - } else { - tmp = -1; - } - - DBG(0, (DBGOUTPUT, "\nAFTER PIC RC:\n")); - DBG(0, (DBGOUTPUT, "BitCnt %3d BitErr/avg %3d%% ", bitCnt, - ((bitCnt - bitPerPic) * 100) / (bitPerPic + 1))); - DBG(1, (DBGOUTPUT, "BitErr/target %3i%% qpHdr %2i avgQp %4i\n", - tmp, rc->qpHdr, rc->qpSum / rc->mbPerPic)); - - /* Calculate the source parameter only for INTER frames */ - if (rc->sliceTypeCur != ISLICE && rc->sliceTypeCur != ISLICES) - SourceParameter_new(rc, rc->nonZeroCnt); - - /* Store the error between target and actual frame size */ - if (rc->sliceTypeCur != ISLICE && rc->sliceTypeCur != ISLICES) { - /* Saturate the error to avoid inter frames with - * mostly intra MBs to affect too much */ - update_rc_error_new(&rc->rError, - MIN(bitCnt - rc->targetPicSize, 2 * rc->targetPicSize)); - } else { - update_rc_error_new(&rc->intraError, bitCnt - rc->targetPicSize); - } - - /* Update number of bits used for residual, inter or intra */ - if (rc->sliceTypeCur != ISLICE && rc->sliceTypeCur != ISLICES) { - update_tables_new(&rc->linReg, rc->qpHdrPrev, - H264Calculate(bitCnt, 256, rc->mbPerPic)); - update_model_new(&rc->linReg); - } else { - update_tables_new(&rc->intra, rc->qpHdrPrev, - H264Calculate(bitCnt, 256, rc->mbPerPic)); - update_model_new(&rc->intra); - } - - /* Post-frame skip if HRD buffer overflow */ - if ((rc->hrd == ENCHW_YES) && (bitCnt > (vb->bufferSize - vb->bucketFullness))) { - DBG(1, (DBGOUTPUT, "Be: %7i ", vb->bucketFullness)); - DBG(1, (DBGOUTPUT, "fillerBits %5i ", 0)); - DBG(1, (DBGOUTPUT, "bitCnt %d spaceLeft %d ", - bitCnt, (vb->bufferSize - vb->bucketFullness))); - DBG(1, (DBGOUTPUT, "bufSize %d bucketFullness %d bitPerPic %d\n", - vb->bufferSize, vb->bucketFullness, bitPerPic)); - DBG(0, (DBGOUTPUT, "HRD overflow, frame discard\n")); - rc->frameCoded = ENCHW_NO; - return H264RC_OVERFLOW; - } else { - vb->bucketFullness += bitCnt; - vb->realBitCnt += bitCnt; - } - - DBG(1, (DBGOUTPUT, "plot\t%4i\t%4i\t%8i\t%8i\t%8i\t%8i\t%8i\n", - rc->frameCnt, rc->qpHdr, rc->targetPicSize, bitCnt, - bitPerPic, rc->gopAvgBitCnt, vb->realBitCnt - vb->virtualBitCnt)); - - if (rc->hrd == ENCHW_NO) { - return 0; - } - - tmp = 0; - -#if RC_CBR_HRD - /* Bits needed to prevent bucket underflow */ - tmp = bitPerPic - vb->bucketFullness; - - if (tmp > 0) { - tmp = (tmp + 7) / 8; - vb->bucketFullness += tmp * 8; - vb->realBitCnt += tmp * 8; - } else { - tmp = 0; - } -#endif - - /* Update Buffering Info */ - stat = vb->bufferSize - vb->bucketFullness; - - rc->gInitialDelay = H264Calculate(90000, stat, vb->bitRate); - rc->gInitialDoffs = rc->gDelaySum - rc->gInitialDelay; - - rc->sei.icrd = (RK_U32)rc->gInitialDelay; - rc->sei.icrdo = (RK_U32)rc->gInitialDoffs; - - DBG(1, (DBGOUTPUT, "initialDelay: %5i ", rc->gInitialDelay)); - DBG(1, (DBGOUTPUT, "initialDoffs: %5i\n", rc->gInitialDoffs)); - DBG(1, (DBGOUTPUT, "Be: %7i ", vb->bucketFullness)); - DBG(1, (DBGOUTPUT, "fillerBits %5i\n", tmp * 8)); - -#ifdef TRACE_RC - if (vb->bucketFullness < rc->gBufferMin) { - rc->gBufferMin = vb->bucketFullness; - } - if (vb->bucketFullness > rc->gBufferMax) { - rc->gBufferMax = vb->bucketFullness; - } - DBG(1, (DBGOUTPUT, "\nLeaky Bucket Min: %i (%d%%) Max: %i (%d%%)\n", - rc->gBufferMin, rc->gBufferMin * 100 / vb->bufferSize, - rc->gBufferMax, rc->gBufferMax * 100 / vb->bufferSize)); -#endif - return tmp; -} - -/*------------------------------------------------------------------------------ - H264BeforePicRc() Update virtual buffer, and calculate picInitQp for current - picture , and coded status. -------------------------------------------------------------------------------*/ -void H264BeforePicRc(h264RateControl_s * rc, RK_U32 timeInc, RK_U32 sliceType) -{ - h264VirtualBuffer_s *vb = &rc->virtualBuffer; - RK_S32 i, rcWindow, intraBits = 0, tmp = 0; - - rc->frameCoded = ENCHW_YES; - rc->sliceTypeCur = sliceType; - - DBG(0, (DBGOUTPUT, "\nBEFORE PIC RC:\n")); - DBG(0, (DBGOUTPUT, "Frame type current\t%2i\n", sliceType)); - - tmp = VirtualBuffer_new(&rc->virtualBuffer, (RK_S32) timeInc, rc->hrd); - //printf("tmp0=%d\n", tmp); - for (i = 0; i < CHECK_POINTS_MAX; i++) { - rc->qpCtrl.wordCntTarget[i] = 0; - } - - if (vb->windowRem == 0) { - vb->windowRem = rc->windowLen - 1; - /* New bitrate window, reset error counters */ - update_rc_error_new(&rc->rError, 0x7fffffff); - /* Don't reset intra error in case of intra-only, it would cause step. */ - if (rc->sliceTypeCur != rc->sliceTypePrev) - update_rc_error_new(&rc->intraError, 0x7fffffff); - } else { - vb->windowRem--; - } - - /* Calculate target size for this picture. Adjust the target bitPerPic - * with the cumulated error between target and actual bitrates (tmp). - * Also take into account the bits used by intra frame starting the GOP. */ - if (rc->sliceTypeCur != ISLICE && rc->sliceTypeCur != ISLICES && - rc->intraInterval > 1) { - /* GOP bits that are used by intra frame. Amount of bits - * "stolen" by intra from each inter frame in the GOP. */ - intraBits = vb->bitPerPic * rc->intraInterval * get_avg_bits_new(&rc->gop, 10) / 100; - intraBits -= vb->bitPerPic; - intraBits /= (rc->intraInterval - 1); - intraBits = MAX(0, intraBits); - } - - /* Compensate for intra "stealing" bits from inters. */ - tmp += intraBits * (rc->intraInterval - rc->intraIntervalCtr); - //printf("tmp1=%d\n", tmp); -#ifdef RC_WINDOW_STRICT - /* In the end of window don't be too strict with matching the error - * otherwise the end of window tends to twist QP. */ - rcWindow = MAX(MAX(3, rc->windowLen / 8), vb->windowRem); -#else - /* Actually we can be fairly easy with this one, let's make it - * a moving window to smoothen the changes. */ - rcWindow = MAX(1, rc->windowLen); - //printf("rc->windowLen=%d\n", rc->windowLen); -#endif - //printf("vb->bitPerPic=%d,intraBits=%d,tmp=%d,rcWindow=%d\n", vb->bitPerPic, intraBits, tmp, rcWindow); - rc->targetPicSize = vb->bitPerPic - intraBits + DIV(tmp, rcWindow); - /* Don't let the target go negative because it won't make any difference - * and it will confuse RC because it can never be reached. */ - rc->targetPicSize = MAX(0, rc->targetPicSize); - - DBG(1, (DBGOUTPUT, "intraBits: %7i\tintraRatio: %3i%%\n", - intraBits, get_avg_bits_new(&rc->gop, 10))); - DBG(1, (DBGOUTPUT, "WndRem: %4i ", vb->windowRem)); - if (rc->sliceTypeCur == ISLICE || rc->sliceTypeCur == ISLICES) { - DBG(1, (DBGOUTPUT, "Rd: %6d ", avg_rc_error_new(&rc->intraError))); - } else { - DBG(1, (DBGOUTPUT, "Rd: %6d ", avg_rc_error_new(&rc->rError))); - } - DBG(1, (DBGOUTPUT, "Tr: %7d\n", rc->targetPicSize)); - - if (rc->picSkip) - PicSkip_new(rc); - - /* determine initial quantization parameter for current picture */ - PicQuant_new(rc); - - /* quantization parameter user defined limitations */ - PicQuantLimit_new(rc); - /* Store the start QP, before ROI adjustment */ - rc->qpHdrPrev = rc->qpHdr; - - if (rc->sliceTypeCur == ISLICE || rc->sliceTypeCur == ISLICES) { - if (rc->fixedIntraQp) - rc->qpHdr = rc->fixedIntraQp; - else if (rc->sliceTypePrev != ISLICE && rc->sliceTypePrev != ISLICES) - rc->qpHdr += rc->intraQpDelta; - - /* quantization parameter user defined limitations still apply */ - PicQuantLimit_new(rc); - if (rc->intraIntervalCtr > 1) - rc->intraInterval = rc->intraIntervalCtr; - rc->intraIntervalCtr = 1; - } else { - /* trace the QP over GOP, excluding Intra QP */ - rc->gopQpSum += rc->qpHdr; - rc->gopQpDiv++; - rc->intraIntervalCtr++; - - /* Check that interval is repeating */ - if (rc->intraIntervalCtr > rc->intraInterval) - rc->intraInterval = rc->intraIntervalCtr; - } - - /* mb rate control (check point rate control) */ - if (rc->mbRc) { - MbQuant_new(rc); - } - - /* reset counters */ - rc->qpSum = 0; - rc->qpLastCoded = rc->qpHdr; - rc->qpTarget = rc->qpHdr; - rc->nonZeroCnt = 0; - rc->sliceTypePrev = rc->sliceTypeCur; - - DBG(0, (DBGOUTPUT, "Frame type current\t%i\n", rc->sliceTypeCur)); - DBG(0, (DBGOUTPUT, "Frame coded\t\t%2i\n", rc->frameCoded)); - DBG(0, (DBGOUTPUT, "Frame qpHdr\t\t%2i\n", rc->qpHdr)); - - for (i = 0; i < CHECK_POINTS_MAX; i++) { - DBG(1, (DBGOUTPUT, "CP %i mbNum %4i wTarg %5i\n", i, - (rc->qpCtrl.checkPointDistance * (i + 1)), - rc->qpCtrl.wordCntTarget[i] * 32)); - } - - rc->sei.crd += timeInc; - - rc->sei.dod = 0; -} - -/*------------------------------------------------------------------------------ - - MbQuant_new() - -------------------------------------------------------------------------------*/ -void MbQuant_new(h264RateControl_s * rc) -{ - RK_S32 nonZeroTarget; - - /* Disable Mb Rc for Intra Slices, because coeffTarget will be wrong */ - if (rc->sliceTypeCur == ISLICE || rc->sliceTypeCur == ISLICES || - rc->srcPrm == 0) { - return; - } - - /* Required zero cnt */ - nonZeroTarget = H264Calculate(rc->targetPicSize, 256, rc->srcPrm); - nonZeroTarget = MIN(rc->coeffCntMax, MAX(0, nonZeroTarget)); - - nonZeroTarget = MIN(0x7FFFFFFFU / 1024U, (RK_U32)nonZeroTarget); - - rc->virtualBuffer.nonZeroTarget = nonZeroTarget; - - /* Use linear model when previous frame can't be used for prediction */ - if ((rc->sliceTypeCur != rc->sliceTypePrev) || (rc->nonZeroCnt == 0)) { - LinearModel_new(rc); - } else { - AdaptiveModel_new(rc); - } -} - -/*------------------------------------------------------------------------------ - - LinearModel_new() - -------------------------------------------------------------------------------*/ -void LinearModel_new(h264RateControl_s * rc) -{ - const RK_S32 sscale = 256; - h264QpCtrl_s *qc = &rc->qpCtrl; - RK_S32 scaler; - RK_S32 i; - RK_S32 tmp, nonZeroTarget = rc->virtualBuffer.nonZeroTarget; - - ASSERT(nonZeroTarget < (0x7FFFFFFF / sscale)); - - if (nonZeroTarget > 0) { - scaler = H264Calculate(nonZeroTarget, sscale, (RK_S32) rc->mbPerPic); - } else { - return; - } - - DBG(1, (DBGOUTPUT, " Linear Target: %8d prevCnt:\t %6d Scaler:\t %6d\n", - nonZeroTarget, rc->nonZeroCnt, scaler / sscale)); - - for (i = 0; i < rc->qpCtrl.checkPoints; i++) { - tmp = (scaler * (qc->checkPointDistance * (i + 1) + 1)) / sscale; - tmp = MIN(WORD_CNT_MAX, tmp / 32 + 1); - if (tmp < 0) tmp = WORD_CNT_MAX; /* Detect overflow */ - qc->wordCntTarget[i] = tmp; /* div32 for regs */ - } - - /* calculate nz count for avg. bits per frame */ - tmp = H264Calculate(rc->virtualBuffer.bitPerPic, 256, rc->srcPrm); - - DBG(1, (DBGOUTPUT, "Error Limit:\t %8d SrcPrm:\t %6d\n", - tmp, rc->srcPrm / 256)); - - qc->wordError[0] = -tmp * 3; - qc->qpChange[0] = -3; - qc->wordError[1] = -tmp * 2; - qc->qpChange[1] = -2; - qc->wordError[2] = -tmp * 1; - qc->qpChange[2] = -1; - qc->wordError[3] = tmp * 1; - qc->qpChange[3] = 0; - qc->wordError[4] = tmp * 2; - qc->qpChange[4] = 1; - qc->wordError[5] = tmp * 3; - qc->qpChange[5] = 2; - qc->wordError[6] = tmp * 4; - qc->qpChange[6] = 3; - - for (i = 0; i < CTRL_LEVELS; i++) { - tmp = qc->wordError[i]; - tmp = CLIP3(tmp / 4, -32768, 32767); - qc->wordError[i] = tmp; - } -} - - -/*------------------------------------------------------------------------------ - - AdaptiveModel_new() - -------------------------------------------------------------------------------*/ -void AdaptiveModel_new(h264RateControl_s * rc) -{ - const RK_S32 sscale = 256; - h264QpCtrl_s *qc = &rc->qpCtrl; - RK_S32 i; - RK_S32 tmp, nonZeroTarget = rc->virtualBuffer.nonZeroTarget; - RK_S32 scaler; - - ASSERT(nonZeroTarget < (0x7FFFFFFF / sscale)); - - if ((nonZeroTarget > 0) && (rc->nonZeroCnt > 0)) { - scaler = H264Calculate(nonZeroTarget, sscale, rc->nonZeroCnt); - } else { - return; - } - DBG(1, (DBGOUTPUT, "Adaptive Target: %8d prevCnt:\t %6d Scaler:\t %6d\n", - nonZeroTarget, rc->nonZeroCnt, scaler / sscale)); - - for (i = 0; i < rc->qpCtrl.checkPoints; i++) { - tmp = (RK_S32) (qc->wordCntPrev[i] * scaler) / sscale; - tmp = MIN(WORD_CNT_MAX, tmp / 32 + 1); - if (tmp < 0) tmp = WORD_CNT_MAX; /* Detect overflow */ - qc->wordCntTarget[i] = tmp; /* div32 for regs */ - DBG(2, (DBGOUTPUT, " CP %i wordCntPrev %6i wordCntTarget_div32 %6i\n", - i, qc->wordCntPrev[i], qc->wordCntTarget[i])); - } - - /* Qp change table */ - - /* calculate nz count for avg. bits per frame */ - tmp = H264Calculate(rc->virtualBuffer.bitPerPic, 256, (rc->srcPrm * 3)); - - DBG(1, (DBGOUTPUT, "Error Limit:\t %8d SrcPrm:\t %6d\n", - tmp, rc->srcPrm / 256)); - - qc->wordError[0] = -tmp * 3; - qc->qpChange[0] = -3; - qc->wordError[1] = -tmp * 2; - qc->qpChange[1] = -2; - qc->wordError[2] = -tmp * 1; - qc->qpChange[2] = -1; - qc->wordError[3] = tmp * 1; - qc->qpChange[3] = 0; - qc->wordError[4] = tmp * 2; - qc->qpChange[4] = 1; - qc->wordError[5] = tmp * 3; - qc->qpChange[5] = 2; - qc->wordError[6] = tmp * 4; - qc->qpChange[6] = 3; - - for (i = 0; i < CTRL_LEVELS; i++) { - tmp = qc->wordError[i]; - tmp = CLIP3(tmp / 4, -32768, 32767); - qc->wordError[i] = tmp; - } -} - -/*------------------------------------------------------------------------------ - - SourceParameter_new() Source parameter of last coded frame. Parameters - has been scaled up by factor 256. - -------------------------------------------------------------------------------*/ -void SourceParameter_new(h264RateControl_s * rc, RK_S32 nonZeroCnt) -{ - ASSERT(rc->qpSum <= 51 * rc->mbPerPic); - ASSERT(nonZeroCnt <= rc->coeffCntMax); - ASSERT(nonZeroCnt >= 0 && rc->coeffCntMax >= 0); - - /* AVOID division by zero */ - if (nonZeroCnt == 0) { - nonZeroCnt = 1; - } - - rc->srcPrm = H264Calculate(rc->frameBitCnt, 256, nonZeroCnt); - - DBG(1, (DBGOUTPUT, "nonZeroCnt %6i, srcPrm %i\n", - nonZeroCnt, rc->srcPrm / 256)); - -} - -/*------------------------------------------------------------------------------ - PicSkip_new() Decrease framerate if not enough bits available. -------------------------------------------------------------------------------*/ -void PicSkip_new(h264RateControl_s * rc) -{ - h264VirtualBuffer_s *vb = &rc->virtualBuffer; - RK_S32 bitAvailable = vb->virtualBitCnt - vb->realBitCnt; - RK_S32 skipIncLimit = -vb->bitPerPic / 3; - RK_S32 skipDecLimit = vb->bitPerPic / 3; - - /* When frameRc is enabled, skipFrameTarget is not allowed to be > 1 - * This makes sure that not too many frames is skipped and lets - * the frameRc adjust QP instead of skipping many frames */ - if (((rc->picRc == ENCHW_NO) || (vb->skipFrameTarget == 0)) && - (bitAvailable < skipIncLimit)) { - vb->skipFrameTarget++; - } - - if ((bitAvailable > skipDecLimit) && vb->skipFrameTarget > 0) { - vb->skipFrameTarget--; - } - - if (vb->skippedFrames < vb->skipFrameTarget) { - vb->skippedFrames++; - rc->frameCoded = ENCHW_NO; - } else { - vb->skippedFrames = 0; - } -} - -/*------------------------------------------------------------------------------ - PicQuant_new() Calculate quantization parameter for next frame. In the beginning - of window use previous GOP average QP and otherwise find new QP - using the target size and previous frames QPs and bit counts. -------------------------------------------------------------------------------*/ -void PicQuant_new(h264RateControl_s * rc) -{ - RK_S32 normBits, targetBits; - true_e useQpDeltaLimit = ENCHW_YES; - - if (rc->picRc != ENCHW_YES) { - rc->qpHdr = rc->fixedQp; - DBG(1, (DBGOUTPUT, "R/cx: xxxx QP: xx xx D: xxxx newQP: xx\n")); - return; - } - - /* If HRD is enabled we must make sure this frame fits in buffer */ - if (rc->hrd == ENCHW_YES) { - RK_S32 bitsAvailable = - (rc->virtualBuffer.bufferSize - rc->virtualBuffer.bucketFullness); - - /* If the previous frame didn't fit the buffer we don't limit QP change */ - if (rc->frameBitCnt > bitsAvailable) { - useQpDeltaLimit = ENCHW_NO; - } - } - - /* determine initial quantization parameter for current picture */ - if (rc->sliceTypeCur == ISLICE || rc->sliceTypeCur == ISLICES) { - /* Default intra QP == prev GOP average */ - rc->qpHdr = gop_avg_qp_new(rc); - /* If all frames are intra we calculate new QP - * for intra the same way as for inter */ - if (rc->sliceTypePrev == ISLICE || rc->sliceTypePrev == ISLICES) { - targetBits = rc->targetPicSize - avg_rc_error_new(&rc->intraError); - normBits = H264Calculate(targetBits, 256, rc->mbPerPic); - rc->qpHdr = new_pic_quant_new(&rc->intra, normBits, useQpDeltaLimit); - } else { - DBG(1, (DBGOUTPUT, "R/cx: xxxx QP: xx xx D: xxxx newQP: xx\n")); - } - } else { - /* Calculate new QP by matching to previous inter frames R-Q curve */ - - targetBits = rc->targetPicSize - avg_rc_error_new(&rc->rError); - normBits = H264Calculate(targetBits, 256, rc->mbPerPic); - rc->qpHdr = new_pic_quant_new(&rc->linReg, normBits, useQpDeltaLimit); - //printf("rc->targetBits=%d,useQpDeltaLimit=%d\n", rc->targetPicSize, useQpDeltaLimit); - //printf("targetBits=%d,normBits=%d,rc->qpHdr=%d\n", targetBits, normBits, rc->qpHdr); - } -} - -/*------------------------------------------------------------------------------ - - PicQuantLimit_new() - -------------------------------------------------------------------------------*/ -void PicQuantLimit_new(h264RateControl_s * rc) -{ - rc->qpHdr = MIN(rc->qpMax, MAX(rc->qpMin, rc->qpHdr)); -} - -/*------------------------------------------------------------------------------ - avg_rc_error_new() PI(D)-control for rate prediction error. -------------------------------------------------------------------------------*/ -static RK_S32 avg_rc_error_new(linReg_s *p) -{ - return DIV(p->bits[2] * 4 + p->bits[1] * 6 + p->bits[0] * 0, 100); -} - -/*------------------------------------------------------------------------------ - update_overhead() Update PI(D)-control values -------------------------------------------------------------------------------*/ -static void update_rc_error_new(linReg_s *p, RK_S32 bits) -{ - p->len = 3; - - if (bits == (RK_S32)0x7fffffff) { - /* RESET */ - p->bits[0] = 0; - p->bits[1] = 0; - p->bits[2] = 0; - return; - } - p->bits[0] = bits - p->bits[2]; /* Derivative */ - if ((bits > 0) && (bits + p->bits[1] > p->bits[1])) - p->bits[1] = bits + p->bits[1]; /* Integral */ - if ((bits < 0) && (bits + p->bits[1] < p->bits[1])) - p->bits[1] = bits + p->bits[1]; /* Integral */ - p->bits[2] = bits; /* Proportional */ - DBG(1, (DBGOUTPUT, "P %6d I %7d D %7d\n", p->bits[2], p->bits[1], p->bits[0])); -} - -/*------------------------------------------------------------------------------ - gop_avg_qp_new() Average quantization parameter of P frames since previous I. -------------------------------------------------------------------------------*/ -RK_S32 gop_avg_qp_new(h264RateControl_s *rc) -{ - RK_S32 tmp = rc->qpHdrPrev; - - if (rc->gopQpSum && rc->gopQpDiv) { - tmp = DIV(rc->gopQpSum, rc->gopQpDiv); - } - /* Average bit count per frame for previous GOP (intra + inter) */ - rc->gopAvgBitCnt = DIV(rc->gopBitCnt, (rc->gopQpDiv + 1)); - /* Ratio of intra_frame_bits/all_gop_bits % for previous GOP */ - if (rc->gopBitCnt) { - RK_S32 gopIntraBitRatio = - H264Calculate(get_avg_bits_new(&rc->intra, 1), rc->mbPerPic, 256) * 100; - gopIntraBitRatio = DIV(gopIntraBitRatio, rc->gopBitCnt); - /* GOP bit count must be > intra bit count, so ratio must be < 100 */ - gopIntraBitRatio = MIN(99, gopIntraBitRatio); - update_tables_new(&rc->gop, tmp, gopIntraBitRatio); - } - rc->gopQpSum = 0; - rc->gopQpDiv = 0; - rc->gopBitCnt = 0; - - return tmp; -} - -/*------------------------------------------------------------------------------ - new_pic_quant_new() Calculate new quantization parameter from the 2nd degree R-Q - equation. Further adjust Qp for "smoother" visual quality. -------------------------------------------------------------------------------*/ -static RK_S32 new_pic_quant_new(linReg_s *p, RK_S32 bits, true_e useQpDeltaLimit) -{ - RK_S32 tmp, qp_best = p->qp_prev, qp = p->qp_prev, diff; - RK_S32 diff_prev = 0, qp_prev = 0, diff_best = 0x7FFFFFFF; - - DBG(1, (DBGOUTPUT, "R/cx:%6d ", bits)); - - if (p->a1 == 0 && p->a2 == 0) { - DBG(1, (DBGOUTPUT, " QP: xx xx D: ==== newQP: %2d\n", qp)); - return qp; - } - if (bits <= 0) { - if (useQpDeltaLimit) - qp = MIN(51, MAX(0, qp + QP_DELTA)); - else - qp = MIN(51, MAX(0, qp + 10)); - - DBG(1, (DBGOUTPUT, " QP: xx xx D: ---- newQP: %2d\n", qp)); - return qp; - } - - do { - tmp = DIV(p->a1, q_step[qp]); - tmp += DIV(p->a2, q_step[qp] * q_step[qp]); - diff = ABS(tmp - bits); - - if (diff < diff_best) { - if (diff_best == 0x7FFFFFFF) { - diff_prev = diff; - qp_prev = qp; - } else { - diff_prev = diff_best; - qp_prev = qp_best; - } - diff_best = diff; - qp_best = qp; - if ((tmp - bits) <= 0) { - if (qp < 1) { - break; - } - qp--; - } else { - if (qp > 50) { - break; - } - qp++; - } - } else { - break; - } - } while ((qp >= 0) && (qp <= 51)); - qp = qp_best; - - DBG(1, (DBGOUTPUT, " QP: %2d %2d D: %5d", qp, qp_prev, diff_prev - diff_best)); - - /* One unit change in Qp changes rate about 12% ca. 1/8. If the - * difference is less than half use the one closer to previous value */ - if (ABS(diff_prev - diff_best) <= ABS(bits) / 16) { - qp = qp_prev; - } - DBG(1, (DBGOUTPUT, " newQP: %2d\n", qp)); - - /* Limit Qp change for smoother visual quality */ - if (useQpDeltaLimit) { - tmp = qp - p->qp_prev; - if (tmp > QP_DELTA) { - qp = p->qp_prev + QP_DELTA; - /* When QP is totally wrong, allow faster QP increase */ - if (tmp > QP_DELTA_LIMIT) - qp = p->qp_prev + QP_DELTA * 2; - } else if (tmp < -QP_DELTA) { - qp = p->qp_prev - QP_DELTA; - } - } - - return qp; -} - -/*------------------------------------------------------------------------------ - get_avg_bits_new() -------------------------------------------------------------------------------*/ -static RK_S32 get_avg_bits_new(linReg_s *p, RK_S32 n) -{ - RK_S32 i; - RK_S32 sum = 0; - RK_S32 pos = p->pos; - - if (!p->len) return 0; - - if (n == -1 || n > p->len) - n = p->len; - - i = n; - while (i--) { - if (pos) pos--; - else pos = p->len - 1; - sum += p->bits[pos]; - if (sum < 0) { - return I32_MAX / (n - i); - } - } - return DIV(sum, n); -} - -/*------------------------------------------------------------------------------ - update_tables_new() only statistics of PSLICE, please. -------------------------------------------------------------------------------*/ -static void update_tables_new(linReg_s *p, RK_S32 qp, RK_S32 bits) -{ - const RK_S32 clen = RC_TABLE_LENGTH; - RK_S32 tmp = p->pos; - - p->qp_prev = qp; - p->qs[tmp] = q_step[qp]; - p->bits[tmp] = bits; - - if (++p->pos >= clen) { - p->pos = 0; - } - if (p->len < clen) { - p->len++; - } -} - -/*------------------------------------------------------------------------------ - update_model_new() Update model parameter by Linear Regression. -------------------------------------------------------------------------------*/ -static void update_model_new(linReg_s *p) -{ - RK_S32 *qs = p->qs, *r = p->bits, n = p->len; - RK_S32 i, a1, a2, sx = lin_sx_new(qs, n), sy = lin_sy_new(qs, r, n); - - for (i = 0; i < n; i++) { - DBG(2, (DBGOUTPUT, "model: qs %i r %i\n", qs[i], r[i])); - } - - a1 = lin_sxy_new(qs, r, n); - a1 = a1 < I32_MAX / n ? a1 * n : I32_MAX; - - if (sy == 0) { - a1 = 0; - } else { - a1 -= sx < I32_MAX / sy ? sx * sy : I32_MAX; - } - - a2 = (lin_nsxx_new(qs, n) - (sx * sx)); - if (a2 == 0) { - if (p->a1 == 0) { - /* If encountered in the beginning */ - a1 = 0; - } else { - a1 = (p->a1 * 2) / 3; - } - } else { - a1 = H264Calculate(a1, DSCY, a2); - } - - /* Value of a1 shouldn't be excessive (small) */ - a1 = MAX(a1, -262144); - a1 = MIN(a1, 262143); - a1 = MAX(a1, -I32_MAX / q_step[51] / RC_TABLE_LENGTH); - a1 = MIN(a1, I32_MAX / q_step[51] / RC_TABLE_LENGTH); - - ASSERT(ABS(a1) * sx >= 0); - ASSERT(sx * DSCY >= 0); - a2 = DIV(sy * DSCY, n) - DIV(a1 * sx, n); - - DBG(2, (DBGOUTPUT, "model: a2:%9d a1:%8d\n", a2, a1)); - - if (p->len > 0) { - p->a1 = a1; - p->a2 = a2; - } -} - -/*------------------------------------------------------------------------------ - lin_sy_new() calculate value of Sy for n points. -------------------------------------------------------------------------------*/ -static RK_S32 lin_sy_new(RK_S32 *qp, RK_S32 *r, RK_S32 n) -{ - RK_S32 sum = 0; - - while (n--) { - sum += qp[n] * qp[n] * r[n]; - if (sum < 0) { - return I32_MAX / DSCY; - } - } - return DIV(sum, DSCY); -} - -/*------------------------------------------------------------------------------ - lin_sx_new() calculate value of Sx for n points. -------------------------------------------------------------------------------*/ -static RK_S32 lin_sx_new(RK_S32 *qp, RK_S32 n) -{ - RK_S32 tmp = 0; - - while (n--) { - ASSERT(qp[n]); - tmp += qp[n]; - } - return tmp; -} - -/*------------------------------------------------------------------------------ - lin_sxy_new() calculate value of Sxy for n points. -------------------------------------------------------------------------------*/ -static RK_S32 lin_sxy_new(RK_S32 *qp, RK_S32 *r, RK_S32 n) -{ - RK_S32 tmp, sum = 0; - - while (n--) { - tmp = qp[n] * qp[n] * qp[n]; - if (tmp > r[n]) { - sum += DIV(tmp, DSCY) * r[n]; - } else { - sum += tmp * DIV(r[n], DSCY); - } - if (sum < 0) { - return I32_MAX; - } - } - return sum; -} - -/*------------------------------------------------------------------------------ - lin_nsxx_new() calculate value of n * Sxy for n points. -------------------------------------------------------------------------------*/ -static RK_S32 lin_nsxx_new(RK_S32 *qp, RK_S32 n) -{ - RK_S32 tmp = 0, sum = 0, d = n ; - - while (n--) { - tmp = qp[n]; - tmp *= tmp; - sum += d * tmp; - } - return sum; -} diff --git a/mpp/codec/enc/h264/src/H264Sei.c b/mpp/codec/enc/h264/src/H264Sei.c deleted file mode 100644 index f94edaf4..00000000 --- a/mpp/codec/enc/h264/src/H264Sei.c +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * 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. - */ - -#include "H264Sei.h" -#include "H264PutBits.h" -#include "H264NalUnit.h" -#include "enccommon.h" - -#define SEI_BUFFERING_PERIOD 0 -#define SEI_PIC_TIMING 1 -#define SEI_FILLER_PAYLOAD 3 -#define SEI_USER_DATA_UNREGISTERED 5 - -/*------------------------------------------------------------------------------ - H264InitSei() -------------------------------------------------------------------------------*/ -void H264InitSei(sei_s * sei, true_e byteStream, RK_U32 hrd, RK_U32 timeScale, - RK_U32 nuit) -{ - ASSERT(sei != NULL); - - sei->byteStream = byteStream; - sei->hrd = hrd; - sei->seqId = 0x0; - sei->psp = (RK_U32) ENCHW_YES; - sei->cts = (RK_U32) ENCHW_YES; - /* sei->icrd = 0; */ - sei->icrdLen = 24; - /* sei->icrdo = 0; */ - sei->icrdoLen = 24; - /* sei->crd = 0; */ - sei->crdLen = 24; - /* sei->dod = 0; */ - sei->dodLen = 24; - sei->ps = 0; - sei->cntType = 1; - sei->cdf = 0; - sei->nframes = 0; - sei->toffs = 0; - - { - RK_U32 n = 1; - - while (nuit > (1U << n)) - n++; - sei->toffsLen = n; - } - - sei->ts.timeScale = timeScale; - sei->ts.nuit = nuit; - sei->ts.time = 0; - sei->ts.sec = 0; - sei->ts.min = 0; - sei->ts.hr = 0; - sei->ts.fts = (RK_U32) ENCHW_YES; - sei->ts.secf = (RK_U32) ENCHW_NO; - sei->ts.minf = (RK_U32) ENCHW_NO; - sei->ts.hrf = (RK_U32) ENCHW_NO; - - sei->userDataEnabled = (RK_U32) ENCHW_NO; - sei->userDataSize = 0; - sei->pUserData = NULL; -} - -/*------------------------------------------------------------------------------ - H264UpdateSeiTS() Calculate new time stamp. -------------------------------------------------------------------------------*/ -void H264UpdateSeiTS(sei_s * sei, RK_U32 timeInc) -{ - timeStamp_s *ts = &sei->ts; - - ASSERT(sei != NULL); - timeInc += ts->time; - - while (timeInc >= ts->timeScale) { - timeInc -= ts->timeScale; - ts->sec++; - if (ts->sec == 60) { - ts->sec = 0; - ts->min++; - if (ts->min == 60) { - ts->min = 0; - ts->hr++; - if (ts->hr == 32) { - ts->hr = 0; - } - } - } - } - - ts->time = timeInc; - - sei->nframes = ts->time / ts->nuit; - sei->toffs = ts->time - sei->nframes * ts->nuit; - - ts->hrf = (ts->hr != 0); - ts->minf = ts->hrf || (ts->min != 0); - ts->secf = ts->minf || (ts->sec != 0); -} - -/*------------------------------------------------------------------------------ - H264FillerSei() Filler payload SEI message. Requested filler payload size - could be huge. Use of temporary stream buffer is not needed, because size is - know. -------------------------------------------------------------------------------*/ -void H264FillerSei(stream_s * sp, sei_s * sei, RK_S32 cnt) -{ - RK_S32 i = cnt; - - ASSERT(sp != NULL && sei != NULL); - - H264NalUnitHdr(sp, 0, SEI, sei->byteStream); - - H264NalBits(sp, SEI_FILLER_PAYLOAD, 8); - COMMENT("last_payload_type_byte"); - - while (cnt >= 255) { - H264NalBits(sp, 0xFF, 0x8); - COMMENT("ff_byte"); - cnt -= 255; - } - H264NalBits(sp, cnt, 8); - COMMENT("last_payload_size_byte"); - - for (; i > 0; i--) { - H264NalBits(sp, 0xFF, 8); - COMMENT("filler ff_byte"); - } - H264RbspTrailingBits(sp); -} - -/*------------------------------------------------------------------------------ - H264BufferingSei() Buffering period SEI message. -------------------------------------------------------------------------------*/ -void H264BufferingSei(stream_s * sp, sei_s * sei) -{ - RK_U8 *pPayloadSizePos; - RK_U32 startByteCnt; - - ASSERT(sei != NULL); - - if (sei->hrd == ENCHW_NO) { - return; - } - - H264NalBits(sp, SEI_BUFFERING_PERIOD, 8); - COMMENT("last_payload_type_byte"); - - pPayloadSizePos = sp->stream; - - H264NalBits(sp, 0xFF, 8); /* this will be updated after we know exact payload size */ - COMMENT("last_payload_size_byte"); - - startByteCnt = sp->byteCnt; - sp->emulCnt = 0; /* count emul_3_byte for this payload */ - - H264ExpGolombUnsigned(sp, sei->seqId); - COMMENT("seq_parameter_set_id"); - - H264NalBits(sp, sei->icrd, sei->icrdLen); - COMMENT("initial_cpb_removal_delay"); - - H264NalBits(sp, sei->icrdo, sei->icrdoLen); - COMMENT("initial_cpb_removal_delay_offset"); - - if (sp->bufferedBits) { - H264RbspTrailingBits(sp); - } - - { - RK_U32 payload_size; - - payload_size = sp->byteCnt - startByteCnt - sp->emulCnt; - *pPayloadSizePos = payload_size; - } - - /* reset cpb_removal_delay */ - sei->crd = 0; -} - -/*------------------------------------------------------------------------------ - TimeStamp() -------------------------------------------------------------------------------*/ -static void TimeStamp(stream_s * sp, timeStamp_s * ts) -{ - if (ts->fts) { - H264NalBits(sp, ts->sec, 6); - COMMENT("seconds_value"); - H264NalBits(sp, ts->min, 6); - COMMENT("minutes_value"); - H264NalBits(sp, ts->hr, 5); - COMMENT("hours_value"); - } else { - H264NalBits(sp, ts->secf, 1); - COMMENT("seconds_flag"); - if (ts->secf) { - H264NalBits(sp, ts->sec, 6); - COMMENT("seconds_value"); - H264NalBits(sp, ts->minf, 1); - COMMENT("minutes_flag"); - if (ts->minf) { - H264NalBits(sp, ts->min, 6); - COMMENT("minutes_value"); - H264NalBits(sp, ts->hrf, 1); - COMMENT("hours_flag"); - if (ts->hrf) { - H264NalBits(sp, ts->hr, 5); - COMMENT("hours_value"); - } - } - } - } -} - -/*------------------------------------------------------------------------------ - H264PicTimingSei() Picture timing SEI message. -------------------------------------------------------------------------------*/ -void H264PicTimingSei(stream_s * sp, sei_s * sei) -{ - RK_U8 *pPayloadSizePos; - RK_U32 startByteCnt; - - ASSERT(sei != NULL); - - H264NalBits(sp, SEI_PIC_TIMING, 8); - COMMENT("last_payload_type_byte"); - - pPayloadSizePos = sp->stream; - - H264NalBits(sp, 0xFF, 8); /* this will be updated after we know exact payload size */ - COMMENT("last_payload_size_byte"); - - startByteCnt = sp->byteCnt; - sp->emulCnt = 0; /* count emul_3_byte for this payload */ - - if (sei->hrd) { - H264NalBits(sp, sei->crd, sei->crdLen); - COMMENT("cpb_removal_delay"); - H264NalBits(sp, sei->dod, sei->dodLen); - COMMENT("dpb_output_delay"); - } - - if (sei->psp) { - H264NalBits(sp, sei->ps, 4); - COMMENT("pic_struct"); - H264NalBits(sp, sei->cts, 1); - COMMENT("clock_timestamp_flag"); - if (sei->cts) { - H264NalBits(sp, 0, 2); - COMMENT("ct_type"); - H264NalBits(sp, 0, 1); - COMMENT("nuit_field_based_flag"); - H264NalBits(sp, sei->cntType, 5); - COMMENT("counting_type"); - H264NalBits(sp, sei->ts.fts, 1); - COMMENT("full_timestamp_flag"); - H264NalBits(sp, 0, 1); - COMMENT("discontinuity_flag"); - H264NalBits(sp, sei->cdf, 1); - COMMENT("cnt_dropped_flag"); - H264NalBits(sp, sei->nframes, 8); - COMMENT("n_frames"); - TimeStamp(sp, &sei->ts); - if (sei->toffsLen > 0) { - H264NalBits(sp, sei->toffs, sei->toffsLen); - COMMENT("time_offset"); - } - } - } - - if (sp->bufferedBits) { - H264RbspTrailingBits(sp); - } - - { - RK_U32 payload_size; - - payload_size = sp->byteCnt - startByteCnt - sp->emulCnt; - *pPayloadSizePos = payload_size; - } -} - -/*------------------------------------------------------------------------------ - H264UserDataUnregSei() User data unregistered SEI message. -------------------------------------------------------------------------------*/ -void H264UserDataUnregSei(stream_s * sp, sei_s * sei) -{ - RK_U32 i, cnt; - const RK_U8 * pUserData; - ASSERT(sei != NULL); - ASSERT(sei->pUserData != NULL); - ASSERT(sei->userDataSize >= 16); - - pUserData = sei->pUserData; - cnt = sei->userDataSize; - if (sei->userDataEnabled == ENCHW_NO) { - return; - } - - H264NalBits(sp, SEI_USER_DATA_UNREGISTERED, 8); - COMMENT("last_payload_type_byte"); - - while (cnt >= 255) { - H264NalBits(sp, 0xFF, 0x8); - COMMENT("ff_byte"); - cnt -= 255; - } - - H264NalBits(sp, cnt, 8); - COMMENT("last_payload_size_byte"); - - /* Write uuid */ - for (i = 0; i < 16; i++) { - H264NalBits(sp, pUserData[i], 8); - COMMENT("uuid_iso_iec_11578_byte"); - } - - /* Write payload */ - for (i = 16; i < sei->userDataSize; i++) { - H264NalBits(sp, pUserData[i], 8); - COMMENT("user_data_payload_byte"); - } -} diff --git a/mpp/codec/enc/h264/src/H264SequenceParameterSet.c b/mpp/codec/enc/h264/src/H264SequenceParameterSet.c deleted file mode 100644 index 7a5639f9..00000000 --- a/mpp/codec/enc/h264/src/H264SequenceParameterSet.c +++ /dev/null @@ -1,721 +0,0 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * 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. - */ - -/*------------------------------------------------------------------------------ - 1. Include headers -------------------------------------------------------------------------------*/ -#include "H264SequenceParameterSet.h" -#include "H264NalUnit.h" - -/*------------------------------------------------------------------------------ - 2. External compiler flags --------------------------------------------------------------------------------- - --------------------------------------------------------------------------------- - 3. Module defines -------------------------------------------------------------------------------*/ - -#define MAX_LEVEL_INDEX (sizeof(H264LevelIdc)/sizeof(*H264LevelIdc)) - -/* max MV length is 128 horizontal and 64 vertical in quarter pixel resolution */ -#define ALOG2_MAX_MV_LENGTH_HOR 7 -#define ALOG2_MAX_MV_LENGTH_VER 6 -#define EXTENDED_SAR 255 - - -const RK_U32 H264LevelIdc[15] = -{ 10, 11, 12, 13, 20, 21, 22, 30, 31, 32, 40, 41, 42, 50, 51 }; - -const RK_U32 H264MaxCPBS[15] = { - 210000, 600000, 1200000, 2400000, 2400000, 4800000, 4800000, 12000000, - 16800000, 24000000, 30000000, 75000000, 75000000, 162000000, 288000000 -}; - -const RK_U32 H264MaxFS[15] = { 99, 396, 396, 396, 396, 792, 1620, 1620, - 3600, 5120, 8192, 8192, 8192, 22080, 36864 - }; - -/* sqrt(8*maxFrameSize) is maximum width and height of specific level */ -const RK_U32 H264SqrtMaxFS8[15] = -{ 28, 56, 56, 56, 56, 79, 113, 113, 169, 202, 256, 256, 256, 420, 543 }; - -const RK_U32 H264MaxMBPS[15] = { - 1485, 3000, 6000, 11880, 11880, 19800, 20250, 40500, - 108000, 216000, 245760, 245760, 491520, 589824, 983040 -}; - -const RK_U32 H264MaxBR[15] = { - 76800, 230400, 460800, 921600, 2400000, 4800000, 4800000, 12000000, - 16800000, 24000000, 24000000, 60000000, 60000000, 162000000, 288000000 -}; - -/*------------------------------------------------------------------------------ - 4. Local function prototypes -------------------------------------------------------------------------------*/ - -static void WriteVui(stream_s * strm, vui_t * vui, RK_S32 numRefFrames); -static RK_S32 GetAspectRatioIdc(RK_S32 sarWidth, RK_S32 sarHeight); -static void UpdateVuiPresence(sps_s * sps); - -/*------------------------------------------------------------------------------ - - H264SpsInit - -------------------------------------------------------------------------------*/ -void H264SeqParameterSetInit(sps_s * sps) -{ - sps->byteStream = ENCHW_YES; - sps->profileIdc = 66; /* 66 = baseline, 77 = main, 100 = high */ - sps->constraintSet0 = ENCHW_YES; - sps->constraintSet1 = ENCHW_YES; - sps->constraintSet2 = ENCHW_YES; - sps->constraintSet3 = ENCHW_NO; - - sps->levelIdc = 30; - sps->seqParameterSetId = 0; - sps->log2MaxFrameNumMinus4 = (16 - 4); - sps->picOrderCntType = 2; - - sps->numRefFrames = 1; - sps->gapsInFrameNumValueAllowed = ENCHW_NO; - sps->picWidthInMbsMinus1 = 176 / 16 - 1; - sps->picHeightInMapUnitsMinus1 = 144 / 16 - 1; - sps->frameMbsOnly = ENCHW_YES; - sps->direct8x8Inference = ENCHW_YES; - sps->frameCropping = ENCHW_NO; - sps->vuiParametersPresent = ENCHW_YES; - sps->vui.bitStreamRestrictionFlag = 1; - - sps->vui.videoFullRange = 0; - sps->vui.sarWidth = 0; - sps->vui.sarHeight = 0; - - sps->frameCropLeftOffset = 0; - sps->frameCropRightOffset = 0; - sps->frameCropTopOffset = 0; - sps->frameCropBottomOffset = 0; - - return; -} - -/*------------------------------------------------------------------------------ - - H264SeqParameterSet - -------------------------------------------------------------------------------*/ -void H264SeqParameterSet(stream_s * stream, sps_s * sps) -{ - /* Nal unit syntax */ - H264NalUnitHdr(stream, 1, SPSET, sps->byteStream); - - H264NalBits(stream, sps->profileIdc, 8); - COMMENT("profile_idc"); - - H264NalBits(stream, (RK_S32) sps->constraintSet0, 1); - COMMENT("constraint_set0_flag"); - - H264NalBits(stream, (RK_S32) sps->constraintSet1, 1); - COMMENT("constraint_set1_flag"); - - H264NalBits(stream, (RK_S32) sps->constraintSet2, 1); - COMMENT("constraint_set2_flag"); - - H264NalBits(stream, (RK_S32) sps->constraintSet3, 1); - COMMENT("constraint_set3_flag"); - - H264NalBits(stream, 0, 4); - COMMENT("reserved_zero_4bits"); - - H264NalBits(stream, sps->levelIdc, 8); - COMMENT("level_idc"); - - H264ExpGolombUnsigned(stream, sps->seqParameterSetId); - COMMENT("seq_parameter_set_id"); - - if (sps->profileIdc >= 100) { - H264ExpGolombUnsigned(stream, 1); - COMMENT("chroma_format_idc"); - - H264ExpGolombUnsigned(stream, 0); - COMMENT("bit_depth_luma_minus8"); - - H264ExpGolombUnsigned(stream, 0); - COMMENT("bit_depth_chroma_minus8"); - - H264NalBits(stream, 0, 1); - COMMENT("qpprime_y_zero_transform_bypass_flag"); - - H264NalBits(stream, 0, 1); - COMMENT("seq_scaling_matrix_present_flag"); - } - - H264ExpGolombUnsigned(stream, sps->log2MaxFrameNumMinus4); - COMMENT("log2_max_frame_num_minus4"); - - H264ExpGolombUnsigned(stream, sps->picOrderCntType); - COMMENT("pic_order_cnt_type"); - - H264ExpGolombUnsigned(stream, sps->numRefFrames); - COMMENT("num_ref_frames"); - - H264NalBits(stream, (RK_S32) sps->gapsInFrameNumValueAllowed, 1); - COMMENT("gaps_in_frame_num_value_allowed_flag"); - - H264ExpGolombUnsigned(stream, sps->picWidthInMbsMinus1); - COMMENT("pic_width_in_mbs_minus1"); - - H264ExpGolombUnsigned(stream, sps->picHeightInMapUnitsMinus1); - COMMENT("pic_height_in_map_units_minus1"); - - H264NalBits(stream, (RK_S32) sps->frameMbsOnly, 1); - COMMENT("frame_mbs_only_flag"); - - H264NalBits(stream, (RK_S32) sps->direct8x8Inference, 1); - COMMENT("direct_8x8_inference_flag"); - - H264NalBits(stream, (RK_S32) sps->frameCropping, 1); - COMMENT("frame_cropping_flag"); - - /* Frame cropping parameters */ - if (sps->frameCropping) { - H264ExpGolombUnsigned(stream, sps->frameCropLeftOffset); - COMMENT("frame_crop_left_offset"); - H264ExpGolombUnsigned(stream, sps->frameCropRightOffset); - COMMENT("frame_crop_right_offset"); - H264ExpGolombUnsigned(stream, sps->frameCropTopOffset); - COMMENT("frame_crop_top_offset"); - H264ExpGolombUnsigned(stream, sps->frameCropBottomOffset); - COMMENT("frame_crop_bottom_offset"); - } - - UpdateVuiPresence(sps); - - H264NalBits(stream, (RK_S32) sps->vuiParametersPresent, 1); - COMMENT("vui_parameters_present_flag"); - - if (sps->vuiParametersPresent == ENCHW_YES) - WriteVui(stream, &sps->vui, sps->numRefFrames); - - H264NalUnitTrailinBits(stream, sps->byteStream); -} - -void UpdateVuiPresence(sps_s * sps) -{ - - if (sps->vui.nalHrdParametersPresentFlag == 0 && - sps->vui.timeScale == 0 && - sps->vui.pictStructPresentFlag == 0 && - sps->vui.sarWidth == 0 && sps->vui.videoFullRange == 0 && - sps->vui.bitStreamRestrictionFlag == 0) { - sps->vuiParametersPresent = ENCHW_NO; - } -} - -/*------------------------------------------------------------------------------ - - Function: WriteVui - - Functional description: - Write VUI params into the stream - - Inputs: - vui_t *vui pointer to VUI params structure - RK_U32 numRefFrames number of reference frames, used as - max_dec_frame_buffering - - Outputs: - stream_s * pointer to stream data - -------------------------------------------------------------------------------*/ -static void WriteVui(stream_s * strm, vui_t * vui, RK_S32 numRefFrames) -{ - - /* Variables */ - - RK_S32 sarIdc; - - /* Code */ - - ASSERT(strm); - ASSERT(vui); - - sarIdc = GetAspectRatioIdc(vui->sarWidth, vui->sarHeight); - - if (sarIdc == 0) { /* unspecified sample aspect ratio -> not present */ - H264NalBits(strm, 0, 1); - COMMENT("aspect_ratio_info_present_flag"); - } else { - H264NalBits(strm, 1, 1); - COMMENT("aspect_ratio_info_present_flag"); - H264NalBits(strm, sarIdc, 8); - COMMENT("aspect_ratio_idc"); - if (sarIdc == EXTENDED_SAR) { - H264NalBits(strm, vui->sarWidth, 16); - COMMENT("sar_width"); - H264NalBits(strm, vui->sarHeight, 16); - COMMENT("sar_height"); - } - } - - H264NalBits(strm, 0, 1); - COMMENT("overscan_info_present_flag"); - - if (vui->videoFullRange != 0) { - H264NalBits(strm, 1, 1); - COMMENT("video_signal_type_present_flag"); - H264NalBits(strm, 5, 3); - COMMENT("unspecified video_format"); - H264NalBits(strm, 1, 1); - COMMENT("video_full_range_flag"); - H264NalBits(strm, 0, 1); - COMMENT("colour_description_present_flag"); - } else { - H264NalBits(strm, 0, 1); - COMMENT("video_signal_type_present_flag"); - } - - H264NalBits(strm, 0, 1); - COMMENT("chroma_loc_info_present_flag"); - - if (vui->timeScale != 0) { - H264NalBits(strm, 1, 1); - COMMENT("timing_info_present_flag"); - H264NalBits(strm, vui->numUnitsInTick >> 16, 16); - COMMENT("num_units_in_tick msb"); - H264NalBits(strm, vui->numUnitsInTick & 0xFFFF, 16); - COMMENT("num_units_in_tick lsb"); - H264NalBits(strm, vui->timeScale >> 16, 16); - COMMENT("time_scale msb"); - H264NalBits(strm, vui->timeScale & 0xFFFF, 16); - COMMENT("time_scale lsb"); - H264NalBits(strm, 0, 1); - COMMENT("fixed_frame_rate_flag"); - } else { - H264NalBits(strm, 0, 1); - COMMENT("timing_info_present_flag"); - } - - H264NalBits(strm, (RK_S32) vui->nalHrdParametersPresentFlag, 1); - COMMENT("nal_hrd_parameters_present_flag"); - - if (vui->nalHrdParametersPresentFlag == ENCHW_YES) { - H264ExpGolombUnsigned(strm, 0); - COMMENT("cpb_cnt_minus1"); - - { - RK_U32 bit_rate_scale = 1; - RK_U32 cpb_size_scale = 1; - RK_U32 tmp, i = 0; - - tmp = vui->cpbSize; - while (4095 < (tmp >> (4 + i++))); - cpb_size_scale = i; - - i = 0; - tmp = vui->bitRate; - while (4095 < (tmp >> (6 + i++))); - bit_rate_scale = i; - - H264NalBits(strm, bit_rate_scale, 4); - COMMENT("bit_rate_scale"); - - H264NalBits(strm, cpb_size_scale, 4); - COMMENT("cpb_size_scale"); - - tmp = vui->bitRate >> (6 + bit_rate_scale); - H264ExpGolombUnsigned(strm, tmp - 1); - vui->bitRate = tmp << (6 + bit_rate_scale); - COMMENT("bit_rate_value_minus1"); - - tmp = vui->cpbSize >> (4 + cpb_size_scale); - H264ExpGolombUnsigned(strm, tmp - 1); - vui->cpbSize = tmp << (4 + cpb_size_scale); - COMMENT("cpb_size_value_minus1"); - } - - H264NalBits(strm, 0, 1); - COMMENT("cbr_flag"); - - H264NalBits(strm, vui->initialCpbRemovalDelayLength - 1, 5); - COMMENT("initial_cpb_removal_delay_length_minus1"); - H264NalBits(strm, vui->cpbRemovalDelayLength - 1, 5); - COMMENT("cpb_removal_delay_length_minus1"); - H264NalBits(strm, vui->dpbOutputDelayLength - 1, 5); - COMMENT("dpb_output_delay_length_minus1"); - H264NalBits(strm, vui->timeOffsetLength, 5); - COMMENT("time_offset_length"); - } - - H264NalBits(strm, 0, 1); - COMMENT("vcl_hrd_parameters_present_flag"); - - if (vui->nalHrdParametersPresentFlag == ENCHW_YES) { - H264NalBits(strm, 0, 1); - COMMENT("low_delay_hrd_flag"); - } - - H264NalBits(strm, (RK_S32) vui->pictStructPresentFlag, 1); - COMMENT("pic_struct_present_flag"); - - H264NalBits(strm, (RK_S32) vui->bitStreamRestrictionFlag, 1); - COMMENT("bit_stream_restriction_flag"); - - if (vui->bitStreamRestrictionFlag == ENCHW_YES) { - H264NalBits(strm, 1, 1); - COMMENT("motion_vectors_over_pic_boundaries"); - - H264ExpGolombUnsigned(strm, 0); - COMMENT("max_bytes_per_pic_denom"); - - H264ExpGolombUnsigned(strm, 0); - COMMENT("max_bits_per_mb_denom"); - - H264ExpGolombUnsigned(strm, ALOG2_MAX_MV_LENGTH_HOR); - COMMENT("log2_mv_length_horizontal"); - - H264ExpGolombUnsigned(strm, ALOG2_MAX_MV_LENGTH_VER); - COMMENT("log2_mv_length_vertical"); - - H264ExpGolombUnsigned(strm, 0); - COMMENT("num_reorder_frames"); - - H264ExpGolombUnsigned(strm, numRefFrames); - COMMENT("max_dec_frame_buffering"); - } - -} - -/*------------------------------------------------------------------------------ - - Function: GetAspectRatioIdc - - Functional description: - - Inputs: - RK_U32 sarWidth sample aspect ratio width - RK_U32 sarHeight sample aspect ratio height - - Outputs: - - Returns: - RK_U32 acpectRatioIdc - -------------------------------------------------------------------------------*/ -static RK_S32 GetAspectRatioIdc(RK_S32 sarWidth, RK_S32 sarHeight) -{ - - RK_S32 aspectRatioIdc; - - if (sarWidth == 0 || sarHeight == 0) /* unspecified */ - aspectRatioIdc = 0; - else if (sarWidth == sarHeight) /* square, 1:1 */ - aspectRatioIdc = 1; - else if (sarHeight == 11) { - if (sarWidth == 12) /* 12:11 */ - aspectRatioIdc = 2; - else if (sarWidth == 10) /* 10:11 */ - aspectRatioIdc = 3; - else if (sarWidth == 16) /* 16:11 */ - aspectRatioIdc = 4; - else if (sarWidth == 24) /* 24:11 */ - aspectRatioIdc = 6; - else if (sarWidth == 20) /* 20:11 */ - aspectRatioIdc = 7; - else if (sarWidth == 32) /* 32:11 */ - aspectRatioIdc = 8; - else if (sarWidth == 18) /* 18:11 */ - aspectRatioIdc = 10; - else if (sarWidth == 15) /* 15:11 */ - aspectRatioIdc = 11; - else /* Extended_SAR */ - aspectRatioIdc = EXTENDED_SAR; - } else if (sarHeight == 33) { - if (sarWidth == 40) /* 40:33 */ - aspectRatioIdc = 5; - else if (sarWidth == 80) /* 80:33 */ - aspectRatioIdc = 9; - else if (sarWidth == 64) /* 64:33 */ - aspectRatioIdc = 12; - else /* Extended_SAR */ - aspectRatioIdc = EXTENDED_SAR; - } else if (sarWidth == 160 && sarHeight == 99) /* 160:99 */ - aspectRatioIdc = 13; - else /* Extended_SAR */ - aspectRatioIdc = EXTENDED_SAR; - - return (aspectRatioIdc); - -} - -/*------------------------------------------------------------------------------ - - Function: H264CheckLevel - - Functional description: - Check whether levelIdc can accommodate the stream based on bit and - frame rates set by the application - - Inputs: - seqParamSet_t * pointer to SPS data structure - RK_U32 bitRate bit rate in bits per second - RK_U32 frameRateNum numerator of the frame rate - RK_U32 frameRateDenom denominator of the frame rate - - Outputs: - seqParamSet_t * pointer to SPS data structure - - Returns: - ENCHW_OK for success - ENCHW_NOK for invalid params - -------------------------------------------------------------------------------*/ -bool_e H264CheckLevel(sps_s * sps, RK_S32 bitRate, RK_S32 frameRateNum, - RK_S32 frameRateDenom) -{ - - /* Variables */ - - RK_S32 tmp, i; - - /* Code */ - - ASSERT(sps); - - if (bitRate <= 0 || frameRateNum <= 0 || frameRateDenom <= 0) - return (ENCHW_NOK); - - i = sps->levelIdx; - - tmp = (sps->picWidthInMbsMinus1 + 1) * (sps->picHeightInMapUnitsMinus1 + 1); - - if ((RK_U32) tmp > H264MaxFS[i] || - (RK_U32) sps->picWidthInMbsMinus1 >= H264SqrtMaxFS8[i] || - (RK_U32) sps->picHeightInMapUnitsMinus1 >= H264SqrtMaxFS8[i]) - return (ENCHW_NOK); - - tmp = frameRateNum * tmp / frameRateDenom; - - if (H264MaxMBPS[sps->levelIdx] < (RK_U32) tmp) - return (ENCHW_NOK); - - return (ENCHW_OK); - -} - -/*------------------------------------------------------------------------------ - - Function: H264GetLevelIndex - - Functional description: - function determines index to level tables - level argument. If invalid level -> return INVALID_LEVEL - - Inputs: - RK_U32 levelIdc - - Outputs: - - Returns: - RK_U32 index - INVALID_LEVEL - -------------------------------------------------------------------------------*/ - -RK_U32 H264GetLevelIndex(RK_U32 levelIdc) -{ - - RK_U32 i; - - i = 0; - while (H264LevelIdc[i] != levelIdc) { - i++; - if (i >= MAX_LEVEL_INDEX) - return INVALID_LEVEL; - } - - return (i); - -} - -/*------------------------------------------------------------------------------ - - Function: H264SpsSetVui - - Functional description: - Set VUI parameters in the SPS structure - - Inputs: - RK_U32 timeScale - RK_U32 numUnitsInTick - bool zeroReorderFrames - - Outputs: - seqParamSet_t * pointer to SPS structure - -------------------------------------------------------------------------------*/ -void H264SpsSetVuiTimigInfo(sps_s * sps, RK_U32 timeScale, RK_U32 numUnitsInTick) -{ - if (timeScale) - sps->vuiParametersPresent = ENCHW_YES; - - sps->vui.timeScale = timeScale; /* used as timing_info_present_flag */ - sps->vui.numUnitsInTick = numUnitsInTick; -} - -void H264SpsSetVuiVideoInfo(sps_s * sps, RK_U32 videoFullRange) -{ - if (videoFullRange) - sps->vuiParametersPresent = ENCHW_YES; - - sps->vui.videoFullRange = videoFullRange; /* used as video_signal_type_present_flag */ -} - -void H264SpsSetVuiAspectRatio(sps_s * sps, RK_U32 sampleAspectRatioWidth, - RK_U32 sampleAspectRatioHeight) -{ - ASSERT(sampleAspectRatioWidth < (1 << 16)); - ASSERT(sampleAspectRatioHeight < (1 << 16)); - - if (sampleAspectRatioWidth) - sps->vuiParametersPresent = ENCHW_YES; - - sps->vui.sarWidth = sampleAspectRatioWidth; /* used as aspect_ratio_info_present_flag */ - sps->vui.sarHeight = sampleAspectRatioHeight; -} - -/*------------------------------------------------------------------------------ - - Function: H264SpsSetVuiHrd - - Functional description: - Set VUI HRD parameters in the SPS structure - - Inputs: - seqParamSet_t * pointer to SPS structure - - Outputs: - seqParamSet_t * pointer to SPS structure - -------------------------------------------------------------------------------*/ - -void H264SpsSetVuiHrd(sps_s * sps, RK_U32 present) -{ - ASSERT(sps); - - sps->vui.nalHrdParametersPresentFlag = present; - - if (present) - sps->vuiParametersPresent = ENCHW_YES; - else { - return; - } - - ASSERT(sps->vui.timeScale && sps->vui.numUnitsInTick); /* set these first */ - - sps->vui.initialCpbRemovalDelayLength = 24; - sps->vui.cpbRemovalDelayLength = 24; - sps->vui.dpbOutputDelayLength = 24; - - { - RK_U32 n = 1; - - while (sps->vui.numUnitsInTick > (1U << n)) { - n++; - } - sps->vui.timeOffsetLength = n; - - } -} - -/*------------------------------------------------------------------------------ - - Function: H264SpsSetVuiHrdBitRate - - Functional description: - Set VUI HRD bit rate in the SPS structure - - Inputs: - seqParamSet_t * pointer to SPS structure - RK_U32 bitRate - - Outputs: - seqParamSet_t * pointer to SPS structure - -------------------------------------------------------------------------------*/ - -void H264SpsSetVuiHrdBitRate(sps_s * sps, RK_U32 bitRate) -{ - ASSERT(sps); - - sps->vui.bitRate = bitRate; -} - -void H264SpsSetVuiHrdCpbSize(sps_s * sps, RK_U32 cpbSize) -{ - ASSERT(sps); - - sps->vui.cpbSize = cpbSize; -} - -RK_U32 H264SpsGetVuiHrdBitRate(sps_s * sps) -{ - ASSERT(sps); - - return sps->vui.bitRate; -} - -RK_U32 H264SpsGetVuiHrdCpbSize(sps_s * sps) -{ - ASSERT(sps); - - return sps->vui.cpbSize; -} - -/*------------------------------------------------------------------------------ - Function name : H264EndOfSequence - Description : - Return type : void - Argument : stream_s *stream - Argument : sps_s *sps -------------------------------------------------------------------------------*/ -void H264EndOfSequence(stream_s * stream, sps_s * sps) -{ - H264NalUnitHdr(stream, 0, ENDOFSEQUENCE, sps->byteStream); -} - -/*------------------------------------------------------------------------------ - Function name : H264EndOfStream - Description : - Return type : void - Argument : stream_s *stream - Argument : sps_s *sps -------------------------------------------------------------------------------*/ -void H264EndOfStream(stream_s * stream, sps_s * sps) -{ - H264NalUnitHdr(stream, 0, ENDOFSTREAM, sps->byteStream); -} - -/*------------------------------------------------------------------------------ - Function name : H264SpsSetVuiPictStructPresentFlag - Description : Signal presence of pic_struct in picture timing SEI - Return type : void - Argument : sps_s * sps - Argument : RK_U32 flag -------------------------------------------------------------------------------*/ -void H264SpsSetVuiPictStructPresentFlag(sps_s * sps, RK_U32 flag) -{ - sps->vui.pictStructPresentFlag = flag; -} diff --git a/mpp/codec/enc/h264/src/H264Slice.c b/mpp/codec/enc/h264/src/H264Slice.c deleted file mode 100644 index 64c90e79..00000000 --- a/mpp/codec/enc/h264/src/H264Slice.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * 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. - */ - -/*------------------------------------------------------------------------------ - 1. Include headers -------------------------------------------------------------------------------*/ -#include "H264Slice.h" - -/*------------------------------------------------------------------------------ - 2. External compiler flags --------------------------------------------------------------------------------- - --------------------------------------------------------------------------------- - 3. Module defines -------------------------------------------------------------------------------*/ - -/*------------------------------------------------------------------------------ - 4. Local function prototypes -------------------------------------------------------------------------------*/ - -/*------------------------------------------------------------------------------ - - H264SliceInit - -------------------------------------------------------------------------------*/ -void H264SliceInit(slice_s * slice) -{ - slice->byteStream = ENCHW_YES; - slice->nalUnitType = IDR; - slice->sliceType = ISLICE; - slice->picParameterSetId = 0; - slice->frameNum = 0; - slice->frameNumBits = 16; - slice->idrPicId = 0; - slice->nalRefIdc = 1; - slice->disableDeblocking = 0; - slice->filterOffsetA = 0; - slice->filterOffsetB = 0; - slice->sliceSize = 0; - slice->cabacInitIdc = 0; - - return; -} diff --git a/mpp/codec/enc/h264/src/encpreprocess.c b/mpp/codec/enc/h264/src/encpreprocess.c deleted file mode 100644 index 5f4d00a2..00000000 --- a/mpp/codec/enc/h264/src/encpreprocess.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * 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. - */ - -/*------------------------------------------------------------------------------ - 1. Include headers -------------------------------------------------------------------------------*/ -#include "vpu.h" -#include "encpreprocess.h" -#include "enccommon.h" -#include "mpp_log.h" -#include "mpp_frame.h" - -/*------------------------------------------------------------------------------ - - EncPreProcessCheck - - Check image size: Cropped frame _must_ fit inside of source image - - Input preProcess Pointer to preProcess_s structure. - - Return ENCHW_OK No errors. - ENCHW_NOK Error condition. - -------------------------------------------------------------------------------*/ -RK_S32 EncPreProcessCheck(const preProcess_s * preProcess) -{ - RK_S32 status = ENCHW_OK; - RK_U32 tmp; - RK_U32 width, height; - -#if 0 - RK_U32 w_mask; - - if (preProcess->inputFormat == 0) - w_mask = 0x0F; /* 16 multiple */ - else - w_mask = 0x07; /* 8 multiple */ - - if (preProcess->lumWidthSrc & w_mask) { - status = ENCHW_NOK; - } -#endif - - if (preProcess->lumHeightSrc & 0x01) { - status = ENCHW_NOK; - } - - if (preProcess->lumWidthSrc > MAX_INPUT_IMAGE_WIDTH) { - status = ENCHW_NOK; - } - - width = preProcess->lumWidth; - height = preProcess->lumHeight; - if (preProcess->rotation) { - RK_U32 tmp_rotation; // modify by lance 2016.05.12 - - tmp_rotation = width; // modify by lance 2016.05.12 - width = height; - height = tmp_rotation; // modify by lance 2016.05.12 - } - - /* Bottom right corner */ - tmp = preProcess->horOffsetSrc + width; - if (tmp > preProcess->lumWidthSrc) { - status = ENCHW_NOK; - } - - tmp = preProcess->verOffsetSrc + height; - if (tmp > preProcess->lumHeightSrc) { - status = ENCHW_NOK; - } - - return status; -} - -/*------------------------------------------------------------------------------ - - EncPreProcess - - Preform cropping - - Input asic Pointer to asicData_s structure - preProcess Pointer to preProcess_s structure. - -------------------------------------------------------------------------------*/ -void EncPreProcess(asicData_s * asic, const preProcess_s * preProcess) -{ - RK_U32 tmp; - RK_U32 width, height; - regValues_s *regs; - RK_U32 stride; - - ASSERT(asic != NULL && preProcess != NULL); - - regs = &asic->regs; - - stride = (preProcess->lumWidthSrc + 15) & (~15); /* 16 pixel multiple stride */ - - /* cropping */ - switch (preProcess->inputFormat) { - case MPP_FMT_YUV420SP : { - tmp = preProcess->verOffsetSrc; - tmp *= stride; - tmp += preProcess->horOffsetSrc; - regs->inputLumBase += (tmp & (~7)); - regs->inputLumaBaseOffset = tmp & 7; - - tmp = preProcess->verOffsetSrc / 2; - tmp *= stride / 2; - tmp += preProcess->horOffsetSrc / 2; -#ifdef RKPLATFORM - if (VPUClientGetIOMMUStatus() <= 0) { - regs->inputCbBase += (tmp & (~7)); - regs->inputCrBase += (tmp & (~7)); - } else { - regs->inputCbBase += (tmp & (~7)) << 10; - regs->inputCrBase += (tmp & (~7)) << 10; - } -#endif - regs->inputChromaBaseOffset = tmp & 7; - } break; - case MPP_FMT_YUV420P : { - /* Input image position after crop and stabilization */ - tmp = preProcess->verOffsetSrc; - tmp *= stride; - tmp += preProcess->horOffsetSrc; - regs->inputLumBase += (tmp & (~7)); - regs->inputLumaBaseOffset = tmp & 7; - - tmp = preProcess->verOffsetSrc / 2; - tmp *= stride / 2; - tmp += preProcess->horOffsetSrc / 2; - tmp *= 2; - - regs->inputCbBase += (tmp & (~7)); - regs->inputChromaBaseOffset = tmp & 7; - } break; - } - if (preProcess->inputFormat < MPP_FMT_YUV_BUTT) { /* YUV 420 */ - } else if (preProcess->inputFormat <= MPP_FMT_BGR444) { /* YUV 422 / RGB 16bpp */ - /* Input image position after crop and stabilization */ - tmp = preProcess->verOffsetSrc; - tmp *= stride; - tmp += preProcess->horOffsetSrc; - tmp *= 2; - - regs->inputLumBase += (tmp & (~7)); - regs->inputLumaBaseOffset = tmp & 7; - regs->inputChromaBaseOffset = (regs->inputLumaBaseOffset / 4) * 4; - } else { /* RGB 32bpp */ - /* Input image position after crop and stabilization */ - tmp = preProcess->verOffsetSrc; - tmp *= stride; - tmp += preProcess->horOffsetSrc; - tmp *= 4; - - regs->inputLumBase += (tmp & (~7)); - /* Note: HW does the cropping AFTER RGB to YUYV conversion - * so the offset is calculated using 16bpp */ - regs->inputLumaBaseOffset = (tmp & 7) / 2; - } - regs->inputImageFormat = preProcess->inputFormat; - - regs->inputImageRotation = preProcess->rotation; - - /* source image setup, size and fill */ - width = preProcess->lumWidth; - height = preProcess->lumHeight; - if (preProcess->rotation) { - RK_U32 tmp_rotation; // modify by lance 2016.05.12 - - tmp_rotation = width; // modify by lance 2016.05.12 - width = height; - height = tmp_rotation; // modify by lance 2016.05.12 - } - - return; -} - -/*------------------------------------------------------------------------------ - - EncSetColorConversion - - Set color conversion coefficients and RGB input mask - - Input asic Pointer to asicData_s structure - preProcess Pointer to preProcess_s structure. - -------------------------------------------------------------------------------*/ -void EncSetColorConversion(preProcess_s * preProcess, asicData_s * asic) -{ - regValues_s *regs; - - ASSERT(asic != NULL && preProcess != NULL); - - regs = &asic->regs; - - switch (preProcess->colorConversionType) { - case 0: /* BT.601 */ - default: - /* Y = 0.2989 R + 0.5866 G + 0.1145 B - * Cb = 0.5647 (B - Y) + 128 - * Cr = 0.7132 (R - Y) + 128 - */ - preProcess->colorConversionType = 0; - regs->colorConversionCoeffA = preProcess->colorConversionCoeffA = 19589; - regs->colorConversionCoeffB = preProcess->colorConversionCoeffB = 38443; - regs->colorConversionCoeffC = preProcess->colorConversionCoeffC = 7504; - regs->colorConversionCoeffE = preProcess->colorConversionCoeffE = 37008; - regs->colorConversionCoeffF = preProcess->colorConversionCoeffF = 46740; - break; - - case 1: /* BT.709 */ - /* Y = 0.2126 R + 0.7152 G + 0.0722 B - * Cb = 0.5389 (B - Y) + 128 - * Cr = 0.6350 (R - Y) + 128 - */ - regs->colorConversionCoeffA = preProcess->colorConversionCoeffA = 13933; - regs->colorConversionCoeffB = preProcess->colorConversionCoeffB = 46871; - regs->colorConversionCoeffC = preProcess->colorConversionCoeffC = 4732; - regs->colorConversionCoeffE = preProcess->colorConversionCoeffE = 35317; - regs->colorConversionCoeffF = preProcess->colorConversionCoeffF = 41615; - break; - - case 2: /* User defined */ - /* Limitations for coefficients: A+B+C <= 65536 */ - regs->colorConversionCoeffA = preProcess->colorConversionCoeffA; - regs->colorConversionCoeffB = preProcess->colorConversionCoeffB; - regs->colorConversionCoeffC = preProcess->colorConversionCoeffC; - regs->colorConversionCoeffE = preProcess->colorConversionCoeffE; - regs->colorConversionCoeffF = preProcess->colorConversionCoeffF; - } - - /* Setup masks to separate R, G and B from RGB */ - switch (preProcess->inputFormat) { - case MPP_FMT_RGB565: /* RGB565 */ - regs->rMaskMsb = 15; - regs->gMaskMsb = 10; - regs->bMaskMsb = 4; - break; - case MPP_FMT_BGR565: /* BGR565 */ - regs->bMaskMsb = 15; - regs->gMaskMsb = 10; - regs->rMaskMsb = 4; - break; - case MPP_FMT_RGB555: /* RGB555 */ - regs->rMaskMsb = 14; - regs->gMaskMsb = 9; - regs->bMaskMsb = 4; - break; - case MPP_FMT_BGR555: /* BGR555 */ - regs->bMaskMsb = 14; - regs->gMaskMsb = 9; - regs->rMaskMsb = 4; - break; - case MPP_FMT_RGB444: /* RGB444 */ - regs->rMaskMsb = 11; - regs->gMaskMsb = 7; - regs->bMaskMsb = 3; - break; - case MPP_FMT_BGR444: /* BGR444 */ - regs->bMaskMsb = 11; - regs->gMaskMsb = 7; - regs->rMaskMsb = 3; - break; - case MPP_FMT_RGB888: /* RGB888 */ - regs->rMaskMsb = 23; - regs->gMaskMsb = 15; - regs->bMaskMsb = 7; - break; - case MPP_FMT_BGR888: /* BGR888 */ - regs->bMaskMsb = 23; - regs->gMaskMsb = 15; - regs->rMaskMsb = 7; - break; - case MPP_FMT_RGB101010: /* RGB101010 */ - regs->rMaskMsb = 29; - regs->gMaskMsb = 19; - regs->bMaskMsb = 9; - break; - case MPP_FMT_BGR101010: /* BGR101010 */ - regs->bMaskMsb = 29; - regs->gMaskMsb = 19; - regs->rMaskMsb = 9; - break; - default: - /* No masks needed for YUV format */ - regs->rMaskMsb = regs->gMaskMsb = regs->bMaskMsb = 0; - } -} - diff --git a/mpp/codec/enc/h264/src/h264e_api.c b/mpp/codec/enc/h264/src/h264e_api.c index 68db1b78..b41d6908 100644 --- a/mpp/codec/enc/h264/src/h264e_api.c +++ b/mpp/codec/enc/h264/src/h264e_api.c @@ -20,116 +20,137 @@ #include "mpp_env.h" #include "mpp_log.h" +#include "mpp_mem.h" #include "mpp_common.h" -#include "H264Instance.h" +#include "mpp_rc.h" + #include "h264e_api.h" #include "h264e_codec.h" #include "h264e_syntax.h" -#include "h264encapi.h" #include "mpp_controller.h" -#include "h264e_utils.h" -RK_U32 h264e_ctrl_debug = 0; +#define H264E_DBG_FUNCTION (0x00000001) -MPP_RET h264e_init(void *ctx, ControllerCfg *ctrlCfg) +#define h264e_dbg(flag, fmt, ...) _mpp_dbg(h264e_debug, flag, fmt, ## __VA_ARGS__) +#define h264e_dbg_f(flag, fmt, ...) _mpp_dbg_f(h264e_debug, flag, fmt, ## __VA_ARGS__) + +#define h264e_dbg_func(fmt, ...) h264e_dbg_f(H264E_DBG_FUNCTION, fmt, ## __VA_ARGS__) + +RK_U32 h264e_debug = 0; + +typedef struct { + /* config from mpp_enc */ + MppEncCfgSet *cfg; + MppEncCfgSet *set; + RK_U32 idr_request; + + /* internal rate control config */ + RK_U32 rc_ready; + RK_U32 prep_ready; + MppRateControl *rc; + + /* output to hal */ + RcSyntax syntax; + + /* + * input from hal + * TODO: on link table mode there will be multiple result + */ + RcHalResult result; +} H264eCtx; + +MPP_RET h264e_init(void *ctx, ControllerCfg *ctrl_cfg) { + MPP_RET ret = MPP_OK; + H264eCtx *p = (H264eCtx *)ctx; + MppEncRcCfg *rc_cfg = &ctrl_cfg->cfg->rc; + MppEncPrepCfg *prep = &ctrl_cfg->cfg->prep; + h264e_dbg_func("enter\n"); - H264ECtx * pEncInst = (H264ECtx*)ctx; - MPP_RET ret = (MPP_RET)H264EncInit(pEncInst); + /* + * default prep: + * 720p + * YUV420SP + */ + prep->change = 0; + prep->width = 1280; + prep->height = 720; + prep->hor_stride = 1280; + prep->ver_stride = 720; + prep->format = MPP_FMT_YUV420SP; + prep->rotation = 0; + prep->mirroring = 0; + prep->denoise = 0; - pEncInst->encStatus = H264ENCSTAT_INIT; - pEncInst->inst = pEncInst; + /* + * default rc_cfg: + * CBR + * 2Mbps +-25% + * 30fps + * gop 60 + */ + rc_cfg->change = 0; + rc_cfg->rc_mode = 3; + rc_cfg->bps_target = 2000 * 1000; + rc_cfg->bps_max = rc_cfg->bps_target * 5 / 4; + rc_cfg->bps_min = rc_cfg->bps_target * 3 / 4; + rc_cfg->fps_in_flex = 0; + rc_cfg->fps_in_num = 30; + rc_cfg->fps_in_denorm = 1; + rc_cfg->fps_out_flex = 0; + rc_cfg->fps_out_num = 30; + rc_cfg->fps_out_denorm = 1; + rc_cfg->gop = 60; + rc_cfg->skip_cnt = 0; + + p->cfg = ctrl_cfg->cfg; + p->set = ctrl_cfg->set; + p->idr_request = 0; + + ret = mpp_rc_init(&p->rc); mpp_env_get_u32("h264e_debug", &h264e_debug, 0); - if (ret) { - mpp_err_f("H264EncInit() failed ret %d", ret); - } - - (void)ctrlCfg; - h264e_dbg_func("leave\n"); return ret; } MPP_RET h264e_deinit(void *ctx) { - H264ECtx * pEncInst = (H264ECtx *)ctx; - H264EncRet ret/* = MPP_OK*/; - H264EncIn *encIn = &(pEncInst->encIn); - H264EncOut *encOut = &(pEncInst->encOut); + H264eCtx *p = (H264eCtx *)ctx; - /* End stream */ - ret = H264EncStrmEnd(pEncInst, encIn, encOut); - if (ret != H264ENC_OK) { - mpp_err("H264EncStrmEnd() failed, ret %d.", ret); - } + h264e_dbg_func("enter\n"); - if ((ret = H264EncRelease(pEncInst)) != H264ENC_OK) { - mpp_err("H264EncRelease() failed, ret %d.", ret); - return MPP_NOK; - } + if (p->rc) + mpp_rc_deinit(p->rc); + h264e_dbg_func("leave\n"); return MPP_OK; } MPP_RET h264e_encode(void *ctx, HalEncTask *task) { - H264EncRet ret; - H264ECtx *p = (H264ECtx *)ctx; - H264EncIn *encIn = &(p->encIn); - H264EncOut *encOut = &(p->encOut); - RK_U32 srcHorStride = p->preProcess.hor_stride; - RK_U32 srcVerStride = p->preProcess.ver_stride; + H264eCtx *p = (H264eCtx *)ctx; + RcSyntax *rc_syn = &p->syntax; + MppEncCfgSet *cfg = p->cfg; + MppEncRcCfg *rc = &cfg->rc; - encIn->pOutBuf = (RK_U32*)mpp_buffer_get_ptr(task->output); - encIn->busOutBuf = mpp_buffer_get_fd(task->output); - encIn->outBufSize = (RK_U32)mpp_buffer_get_size(task->output); - - /* Start stream */ - if (p->encStatus == H264ENCSTAT_INIT) { - ret = H264EncStrmStart(p, encIn, encOut); - if (ret != H264ENC_OK) { - mpp_err("H264EncStrmStart() failed, ret %d.", ret); - return -1; - } - - - /* First frame is always intra with time increment = 0 */ - encIn->codingType = H264ENC_INTRA_FRAME; - encIn->timeIncrement = 0; - } - - /* Setup encoder input */ - // TODO: support more format in the future - encIn->busLuma = mpp_buffer_get_fd(task->input); - encIn->busChromaU = encIn->busLuma | ((srcHorStride * srcVerStride) << 10); - encIn->busChromaV = encIn->busLuma | ((srcHorStride * srcVerStride * 5 / 4) << 10); - - /* Select frame type */ - if (p->intraPicRate != 0 && (p->intraPeriodCnt >= p->intraPicRate)) { - encIn->codingType = H264ENC_INTRA_FRAME; - task->is_intra = 1; - } else { - encIn->codingType = H264ENC_PREDICTED_FRAME; - task->is_intra = 0; - } - - if (encIn->codingType == H264ENC_INTRA_FRAME) - p->intraPeriodCnt = 0; - - memset(&p->syntax, 0, sizeof(p->syntax)); - ret = H264EncStrmEncode(p, encIn, encOut, &p->syntax); - if (ret != H264ENC_FRAME_READY) { - mpp_err("H264EncStrmEncode() failed, ret %d.", ret); // TODO need to be modified by lance 2016.05.31 + if (!p->rc_ready) { + mpp_err_f("not initialize encoding\n"); + task->valid = 0; return MPP_NOK; } + mpp_rc_update_user_cfg(p->rc, rc); + + mpp_rc_bits_allocation(p->rc, rc_syn); + task->syntax.data = &p->syntax; task->syntax.number = 1; + task->valid = 1; return MPP_OK; } @@ -250,8 +271,8 @@ static MPP_RET h264e_check_mpp_cfg(MppEncConfig *mpp_cfg) MPP_RET h264e_config(void *ctx, RK_S32 cmd, void *param) { - MPP_RET ret = MPP_NOK; - H264ECtx *enc = (H264ECtx *)ctx; // add by lance 2016.05.31 + MPP_RET ret = MPP_OK; + H264eCtx *p = (H264eCtx *)ctx; h264e_dbg_func("enter ctx %p cmd %x param %p\n", ctx, cmd, param); @@ -259,134 +280,17 @@ MPP_RET h264e_config(void *ctx, RK_S32 cmd, void *param) case CHK_ENC_CFG : { ret = h264e_check_mpp_cfg((MppEncConfig *)param); } break; - case SET_ENC_CFG : { - MppEncConfig *mpp_cfg = (MppEncConfig *)param; - H264EncConfig *enc_cfg = &enc->enc_cfg; - - H264EncCodingCtrl coding_cfg; - - enc_cfg->streamType = H264ENC_BYTE_STREAM; - enc_cfg->frameRateDenom = 1; - enc_cfg->profile = (H264Profile)mpp_cfg->profile; - enc_cfg->level = (H264Level)mpp_cfg->level; - enc_cfg->enable_cabac = mpp_cfg->cabac_en; - enc_cfg->transform8x8_mode = (enc_cfg->profile >= H264_PROFILE_HIGH) ? (1) : (0); - enc_cfg->pic_init_qp = mpp_cfg->qp; - enc_cfg->pps_id = 0; - enc_cfg->width = mpp_cfg->width; - enc_cfg->height = mpp_cfg->height; - enc_cfg->hor_stride = mpp_cfg->hor_stride; - enc_cfg->ver_stride = mpp_cfg->ver_stride; - enc_cfg->input_image_format = mpp_cfg->format; - enc_cfg->frameRateNum = mpp_cfg->fps_in; - enc_cfg->frameRateDenom = 1; - enc_cfg->chroma_qp_index_offset = 0; - enc_cfg->second_chroma_qp_index_offset = 0; - - ret = H264EncCfg(enc, enc_cfg); - - /* Encoder setup: coding control */ - memset(&coding_cfg, 0, sizeof(coding_cfg)); - coding_cfg.enableCabac = enc_cfg->enable_cabac; - coding_cfg.transform8x8Mode = enc_cfg->transform8x8_mode; - ret = H264EncSetCodingCtrl(enc, &coding_cfg); - if (ret) { - mpp_err("H264EncSetCodingCtrl() failed, ret %d.", ret); - h264e_deinit((void*)enc); - break; - } - } break; - case SET_ENC_RC_CFG : { - MppEncConfig *mpp_cfg = (MppEncConfig *)param; - H264EncRateCtrl *enc_rc_cfg = &enc->enc_rc_cfg; - - mpp_assert(enc); - - if (mpp_cfg->rc_mode) { - /* VBR / CBR mode */ - RK_S32 max_qp = MPP_MAX(mpp_cfg->qp + 6, 51); - RK_S32 min_qp = MPP_MIN(mpp_cfg->qp - 6, 18); - - enc_rc_cfg->pictureRc = 1; - enc_rc_cfg->mbRc = 1; - enc_rc_cfg->qpHdr = mpp_cfg->qp; - enc_rc_cfg->qpMax = max_qp; - enc_rc_cfg->qpMin = min_qp; - enc_rc_cfg->hrd = 0; - enc_rc_cfg->intraQpDelta = -3; - } else { - /* CQP mode */ - enc_rc_cfg->pictureRc = 0; - enc_rc_cfg->mbRc = 0; - enc_rc_cfg->qpHdr = mpp_cfg->qp; - enc_rc_cfg->qpMax = mpp_cfg->qp; - enc_rc_cfg->qpMin = mpp_cfg->qp; - enc_rc_cfg->hrd = 0; - enc_rc_cfg->intraQpDelta = 0; - } - enc_rc_cfg->pictureSkip = mpp_cfg->skip_cnt; - - if (mpp_cfg->gop > 0) - enc_rc_cfg->intraPicRate = mpp_cfg->gop; - else - enc_rc_cfg->intraPicRate = 30; - - enc_rc_cfg->bitPerSecond = mpp_cfg->bps; - enc_rc_cfg->gopLen = mpp_cfg->gop; - enc_rc_cfg->fixedIntraQp = 0; - enc_rc_cfg->mbQpAdjustment = 0; - enc_rc_cfg->hrdCpbSize = mpp_cfg->bps; - - enc->intraPicRate = enc_rc_cfg->intraPicRate; - enc->intraPeriodCnt = enc_rc_cfg->intraPicRate; - - mpp_log("Set rate control: qp %2d [%2d, %2d] bps %8d\n", - enc_rc_cfg->qpHdr, enc_rc_cfg->qpMin, enc_rc_cfg->qpMax, enc_rc_cfg->bitPerSecond); - - mpp_log("pic %d mb %d skip %d hrd %d cpbSize %d gopLen %d\n", - enc_rc_cfg->pictureRc, enc_rc_cfg->mbRc, enc_rc_cfg->pictureSkip, enc_rc_cfg->hrd, - enc_rc_cfg->hrdCpbSize, enc_rc_cfg->gopLen); - - ret = H264EncSetRateCtrl(enc, enc_rc_cfg); - if (ret) - mpp_err("H264EncSetRateCtrl() failed, ret %d.", ret); - - } break; - case GET_ENC_EXTRA_INFO : { - h264e_control_extra_info_cfg **dst = (h264e_control_extra_info_cfg **)param; - h264e_control_extra_info_cfg *info = &enc->info; - H264EncConfig *enc_cfg = &enc->enc_cfg; - H264EncRateCtrl *enc_rc_cfg = &enc->enc_rc_cfg; - - info->chroma_qp_index_offset = enc_cfg->chroma_qp_index_offset; - info->enable_cabac = enc_cfg->enable_cabac; - info->pic_init_qp = enc_cfg->pic_init_qp; - info->pic_luma_height = enc_cfg->height; - info->pic_luma_width = enc_cfg->width; - info->transform8x8_mode = enc_cfg->transform8x8_mode; - - info->input_image_format = enc_cfg->input_image_format; - info->profile_idc = enc_cfg->profile; - info->level_idc = enc_cfg->level; - info->keyframe_max_interval = enc_rc_cfg->intraPicRate; - info->frame_rate = enc_cfg->frameRateNum; - info->second_chroma_qp_index_offset = enc_cfg->second_chroma_qp_index_offset; - info->pps_id = enc_cfg->pps_id; - - *dst = info; - ret = MPP_OK; - } break; - case GET_OUTPUT_STREAM_SIZE : { - *((RK_U32*)param) = getOutputStreamSize(enc); - ret = MPP_OK; - } break; case SET_IDR_FRAME : { - H264EncRateCtrl *enc_rc_cfg = &enc->enc_rc_cfg; - enc->intraPeriodCnt = enc_rc_cfg->intraPicRate; - ret = MPP_OK; + p->idr_request++; + } break; + case MPP_ENC_SET_RC_CFG : { + mpp_log_f("MPP_ENC_SET_RC_CFG bps %d [%d : %d]\n", p->set->rc.bps_target, + p->set->rc.bps_min, p->set->rc.bps_max); + p->rc_ready = 1; } break; default: mpp_err("No correspond cmd found, and can not config!"); + ret = MPP_NOK; break; } @@ -397,57 +301,11 @@ MPP_RET h264e_config(void *ctx, RK_S32 cmd, void *param) MPP_RET h264e_callback(void *ctx, void *feedback) { - H264ECtx *enc = (H264ECtx *)ctx; - H264EncIn *encIn = &(enc->encIn); - regValues_s *val = &(enc->asic.regs); + H264eCtx *p = (H264eCtx *)ctx; h264e_feedback *fb = (h264e_feedback *)feedback; - H264EncOut *encOut = &(enc->encOut); - RK_S32 i = 0; - H264EncRet ret; - MPP_RET vpuWaitResult = MPP_OK; - - /* HW output stream size, bits to bytes */ - val->outputStrmSize = fb->out_strm_size; - - if (val->cpTarget != NULL) { - /* video coding with MB rate control ON */ - for (i = 0; i < 10; i++) { - val->cpTargetResults[i] = fb->cp[i]; - } - } - - /* QP sum div2 */ - val->qpSum = fb->qp_sum; - - /* MAD MB count*/ - val->madCount = fb->mad_count; - - /* Non-zero coefficient count*/ - val->rlcCount = fb->rlc_count; - - /*hw status*/ - val->hw_status = fb->hw_status; - - // vpuWaitResult should be given from hal part, and here assume it is OK // TODO modify by lance 2016.06.01 - ret = H264EncStrmEncodeAfter(enc, encOut, vpuWaitResult); // add by lance 2016.05.07 - switch (ret) { - case H264ENC_FRAME_READY: - if (encOut->codingType != H264ENC_NOTCODED_FRAME) { - enc->intraPeriodCnt++; - } - break; - - case H264ENC_OUTPUT_BUFFER_OVERFLOW: - mpp_log("output buffer overflow!"); - break; - - default: - mpp_log("afterencode default!"); - break; - } - - encIn->timeIncrement = 1; + p->result = *fb->result; + mpp_rc_update_hw_result(p->rc, fb->result); return MPP_OK; } @@ -460,7 +318,7 @@ MPP_RET h264e_callback(void *ctx, void *feedback) const ControlApi api_h264e_controller = { "h264e_control", MPP_VIDEO_CodingAVC, - sizeof(H264ECtx), + sizeof(H264eCtx), 0, h264e_init, h264e_deinit, diff --git a/mpp/codec/enc/h264/src/h264e_utils.c b/mpp/codec/enc/h264/src/h264e_utils.c deleted file mode 100644 index c9cfcf1a..00000000 --- a/mpp/codec/enc/h264/src/h264e_utils.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * 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. - */ - -#include "h264e_utils.h" - -RK_U32 getOutputStreamSize(H264ECtx *pEncInst) -{ - regValues_s *val = &(pEncInst->asic.regs); - - return val->outputStrmSize; -} diff --git a/mpp/codec/enc/jpeg/jpege_api.c b/mpp/codec/enc/jpeg/jpege_api.c index 4626b400..c1ff7049 100644 --- a/mpp/codec/enc/jpeg/jpege_api.c +++ b/mpp/codec/enc/jpeg/jpege_api.c @@ -177,11 +177,6 @@ MPP_RET jpege_config(void *ctx, RK_S32 cmd, void *param) mpp_cfg->format = syntax->format; mpp_cfg->qp = syntax->quality; } break; - case GET_ENC_EXTRA_INFO : { - } break; - case GET_OUTPUT_STREAM_SIZE : { - *((RK_U32*)param) = p->feedback.stream_length; - } break; default: mpp_err("No correspond cmd found, and can not config!"); ret = MPP_NOK; diff --git a/mpp/codec/inc/dummy_enc_api.h b/mpp/codec/inc/dummy_enc_api.h index 5b8fe647..c6a04bef 100644 --- a/mpp/codec/inc/dummy_enc_api.h +++ b/mpp/codec/inc/dummy_enc_api.h @@ -17,8 +17,6 @@ #ifndef __DUMMY_ENC_API_H__ #define __DUMMY_ENC_API_H__ -#include "mpp_enc.h" - #ifdef __cplusplus extern "C" { #endif diff --git a/mpp/codec/inc/encoder_codec_api.h b/mpp/codec/inc/encoder_codec_api.h index 84542fdb..725539f7 100644 --- a/mpp/codec/inc/encoder_codec_api.h +++ b/mpp/codec/inc/encoder_codec_api.h @@ -21,16 +21,11 @@ #include "mpp_buf_slot.h" #include "hal_task.h" -// TODO -#include "../enc/h264/include/h264encapi.h" - // config cmd typedef enum EncCfgCmd_t { CHK_ENC_CFG, SET_ENC_CFG, SET_ENC_RC_CFG, - GET_ENC_EXTRA_INFO, - GET_OUTPUT_STREAM_SIZE, SET_IDR_FRAME, } EncCfgCmd; @@ -40,6 +35,8 @@ typedef enum EncCfgCmd_t { typedef struct EncControllerInitCfg_t { // input MppCodingType coding; + MppEncCfgSet *cfg; + MppEncCfgSet *set; // output RK_S32 task_count; diff --git a/mpp/codec/inc/mpp_controller.h b/mpp/codec/inc/mpp_controller.h index 1de894c4..1bfa0526 100644 --- a/mpp/codec/inc/mpp_controller.h +++ b/mpp/codec/inc/mpp_controller.h @@ -21,21 +21,6 @@ typedef void* Controller; -typedef struct EncTask_t { - HalTaskHnd hnd; - - RK_S32 hal_frm_idx_in; - RK_S32 hal_pkt_idx_out; - - MppBuffer ctrl_frm_buf_in; - MppBuffer ctrl_pkt_buf_out; - - h264e_syntax syntax_data; - - HalTaskInfo info; -} EncTask; - - #ifdef __cplusplus extern "C" { #endif diff --git a/mpp/codec/inc/mpp_enc.h b/mpp/codec/inc/mpp_enc.h index cb8e0c73..fae87e94 100644 --- a/mpp/codec/inc/mpp_enc.h +++ b/mpp/codec/inc/mpp_enc.h @@ -18,6 +18,8 @@ #define __MPP_ENC_H__ #include "rk_mpi.h" + +#include "mpp_thread.h" #include "mpp_controller.h" #include "mpp_hal.h" @@ -83,10 +85,10 @@ * +----------init------------> | | * | | | | * | | | | - * | MppFrame | | | - * +---------control----------> MppFrame | | + * | PrepCfg | | | + * +---------control----------> PrepCfg | | * | +-----control-----> | - * | | | MppFrame | + * | | | PrepCfg | * | +--------------------------control--------> * | | | allocate * | | | buffer @@ -108,10 +110,6 @@ * +---------control----------> | | * | | | | * | | | | - * | PrepCfg | | | - * +---------control----------> | PrepCfg | - * | +--------------------------control--------> - * | | | | * | ROICfg | | | * +---------control----------> | ROICfg | * | +--------------------------control--------> @@ -165,12 +163,13 @@ struct MppEnc_t { MppBufSlots packet_slots; HalTaskGroup tasks; + // internal status and protection + Mutex lock; RK_U32 reset_flag; - void *mpp; /* Encoder configure set */ - MppEncRcCfg rc_cfg; - MppFrame data_cfg; + MppEncCfgSet cfg; + MppEncCfgSet set; /* * configuration parameter to controller and hal @@ -194,6 +193,15 @@ MPP_RET mpp_enc_control(MppEnc *enc, MpiCmd cmd, void *param); MPP_RET mpp_enc_notify(void *ctx, void *info); MPP_RET mpp_enc_reset(MppEnc *enc); +/* + * preprocess config and rate-control config is common config then they will + * be done in mpp_enc layer + * + * codec related config will be set in each hal component + */ +void mpp_enc_update_prep_cfg(MppEncPrepCfg *dst, MppEncPrepCfg *src); +void mpp_enc_update_rc_cfg(MppEncRcCfg *dst, MppEncRcCfg *src); + #ifdef __cplusplus } #endif diff --git a/mpp/codec/inc/mpp_rc.h b/mpp/codec/inc/mpp_rc.h new file mode 100644 index 00000000..830669e3 --- /dev/null +++ b/mpp/codec/inc/mpp_rc.h @@ -0,0 +1,244 @@ +/* + * Copyright 2016 Rockchip Electronics Co. LTD + * + * 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. + */ + +#ifndef __MPP_RC__ +#define __MPP_RC__ + +#include "rk_mpi.h" +#include "mpp_err.h" +#include "mpp_log.h" + +/* + * mpp rate control contain common caculation methd + * + * 1. MppData - data statistic struct + * size - max valid data number + * len - valid data number + * pos - current load/store position + * val - buffer array pointer + */ +typedef struct { + RK_S32 size; + RK_S32 len; + RK_S32 pos; + RK_S32 *val; +} MppData; + +/* + * 2. Proportion Integration Differentiation (PID) control + */ +typedef struct { + RK_S32 p; + RK_S32 i; + RK_S32 d; + RK_S32 coef_p; + RK_S32 coef_i; + RK_S32 coef_d; + RK_S32 div; + RK_S32 len; + RK_S32 count; +} MppPIDCtx; + +/* + * 3. linear module + */ +#define LINEAR_MODEL_STATISTIC_COUNT 15 + +/* + * Linear regression + * C = a * x * r + b * x * x * r + */ +typedef struct linear_model_s { + RK_S32 size; /* elements max size */ + RK_S32 n; /* elements count */ + RK_S32 i; /* elements index for store */ + + RK_S64 a; /* coefficient */ + RK_S64 b; /* coefficient */ + + RK_S32 *x; /* x */ + RK_S32 *r; /* r */ + RK_S64 *y; /* y = x * x * r */ +} MppLinReg; + +typedef enum ENC_FRAME_TYPE_E { + INTER_P_FRAME = 0, + INTER_B_FRAME = 1, + INTRA_FRAME = 2 +} ENC_FRAME_TYPE; + +/* + * MppRateControl has three steps work: + * + * 1. translate user requirement to bit rate parameters + * 2. calculate target bit from bit parameters + * 3. calculate qstep from target bit + * + * That is user setting -> target bit -> qstep. + * + * This struct will be used in both controller and hal. + * Controller provide step 1 and step 2. Hal provide step 3. + * + */ +typedef enum MppEncGopMode_e { + /* gop == 0 */ + MPP_GOP_ALL_INTER, + /* gop == 1 */ + MPP_GOP_ALL_INTRA, + /* gop < fps */ + MPP_GOP_SMALL, + /* gop >= fps */ + MPP_GOP_LARGE, + MPP_GOP_MODE_BUTT, +} MppEncGopMode; + +typedef struct MppRateControl_s { + /* control parameter from external config */ + RK_S32 fps_num; + RK_S32 fps_denom; + RK_S32 fps_out; + RK_S32 gop; + RK_S32 bps_min; + RK_S32 bps_target; + RK_S32 bps_max; + + /* + * derivation parameter + * bits_per_pic - average bit count in gop + * bits_per_intra - target intra frame size + * if not intra frame is encoded default set to a certain + * times of inter frame according to gop + * bits_per_inter - target inter frame size + */ + MppEncGopMode gop_mode; + RK_S32 bits_per_pic; + RK_S32 bits_per_intra; + RK_S32 bits_per_inter; + + /* bitrate window which tries to match target */ + RK_S32 window_len; + RK_S32 intra_to_inter_rate; + + RK_S32 acc_intra_bits; + RK_S32 acc_inter_bits; + RK_S32 acc_total_bits; + + RK_S32 acc_intra_count; + RK_S32 acc_inter_count; + RK_S32 acc_total_count; + + /* runtime status parameter */ + ENC_FRAME_TYPE cur_frmtype; + ENC_FRAME_TYPE pre_frmtype; + + /* + * intra - intra frame bits record + * pid_intra - intra frame bits record + * pid_inter - inter frame bits record + * pid_gop - serial frame bits record + */ + MppData *intra; + MppData *gop_bits; + MppPIDCtx pid_intra; + MppPIDCtx pid_inter; + + /* + * output target bits on current status + * 0 - do not do rate control + * non-zero - have rate control + */ + RK_S32 bits_target; +} MppRateControl; + +/* + * Data structure from encoder to hal + * type - frame encode type + * bit_target - frame target size + * bit_min - frame minimum size + * bit_max - frame maximum size + */ +typedef struct RcSyntax_s { + ENC_FRAME_TYPE type; + RK_S32 bit_target; + RK_S32 bit_max; + RK_S32 bit_min; +} RcSyntax; + +/* + * Data structure from hal to encoder + * type - frame encode type + * bits - frame actual byte size + */ +typedef struct HalRcResult_s { + ENC_FRAME_TYPE type; + RK_S32 time; + RK_S32 bits; +} RcHalResult; + +#ifdef __cplusplus +extern "C" { +#endif + +MPP_RET mpp_data_init(MppData **p, RK_S32 len); +void mpp_data_deinit(MppData *p); +void mpp_data_update(MppData *p, RK_S32 val); +RK_S32 mpp_data_avg(MppData *p, RK_S32 len, RK_S32 num, RK_S32 denorm); + +void mpp_pid_reset(MppPIDCtx *p); +void mpp_pid_set_param(MppPIDCtx *p, RK_S32 coef_p, RK_S32 coef_i, RK_S32 coef_d, RK_S32 div, RK_S32 len); +void mpp_pid_update(MppPIDCtx *p, RK_S32 val); +RK_S32 mpp_pid_calc(MppPIDCtx *ctx); + +MPP_RET mpp_rc_init(MppRateControl **ctx); +MPP_RET mpp_rc_deinit(MppRateControl *ctx); + +/* + * Translate MppEncRcCfg struct to internal bitrate setting + * Called in mpp_control function. + * If parameter changed mark flag and let encoder recalculate bit allocation. + */ +MPP_RET mpp_rc_update_user_cfg(MppRateControl *ctx, MppEncRcCfg *cfg); + +/* + * When one frame is encoded hal will call this function to update paramter + * from hardware. Hardware will update bits / qp_sum / mad or sse data + * + * Then rate control will update the linear regression model + */ +MPP_RET mpp_rc_update_hw_result(MppRateControl *ctx, RcHalResult *result); + +/* + * Use bps/fps config generate bit allocation setting + * Called in controller loop when parameter changed or get a encoder result. + * This function will calculation next frames target bits according to current + * bit rate status. + * + * bits[0] - target + * bits[1] - min + * bits[1] - max + */ +MPP_RET mpp_rc_bits_allocation(MppRateControl *ctx, RcSyntax *rc_syn); + +MPP_RET mpp_linreg_init(MppLinReg **ctx, RK_S32 size); +MPP_RET mpp_linreg_deinit(MppLinReg *ctx); +MPP_RET mpp_linreg_update(MppLinReg *ctx, RK_S32 x, RK_S32 r); +RK_S32 mpp_linreg_calc(MppLinReg *ctx, RK_S32 r); + +#ifdef __cplusplus +} +#endif + +#endif /* __MPP_RC__ */ diff --git a/mpp/codec/mpp_dec.cpp b/mpp/codec/mpp_dec.cpp index cf0a3840..5c508651 100644 --- a/mpp/codec/mpp_dec.cpp +++ b/mpp/codec/mpp_dec.cpp @@ -1038,6 +1038,8 @@ MPP_RET mpp_dec_init(MppDec **dec, MppDecCfg *cfg) frame_slots, packet_slots, NULL, + NULL, + NULL, parser_cfg.task_count, cfg->fast_mode, cb, diff --git a/mpp/codec/mpp_enc.cpp b/mpp/codec/mpp_enc.cpp index 4660cee0..2eb8d0b9 100644 --- a/mpp/codec/mpp_enc.cpp +++ b/mpp/codec/mpp_enc.cpp @@ -18,6 +18,7 @@ #include "string.h" +#include "mpp_env.h" #include "mpp_log.h" #include "mpp_mem.h" #include "mpp_common.h" @@ -28,6 +29,17 @@ #include "mpp_packet_impl.h" #include "hal_h264e_api.h" +#define MPP_ENC_DBG_FUNCTION (0x00000001) +#define MPP_ENC_DBG_CONTROL (0x00000002) + +RK_U32 mpp_enc_debug = 0; + +#define mpp_enc_dbg(flag, fmt, ...) _mpp_dbg(mpp_enc_debug, flag, fmt, ## __VA_ARGS__) +#define mpp_enc_dbg_f(flag, fmt, ...) _mpp_dbg_f(mpp_enc_debug, flag, fmt, ## __VA_ARGS__) + +#define mpp_enc_dbg_func(fmt, ...) mpp_enc_dbg_f(MPP_ENC_DBG_FUNCTION, fmt, ## __VA_ARGS__) +#define mpp_enc_dbg_ctrl(fmt, ...) mpp_enc_dbg_f(MPP_ENC_DBG_CONTROL, fmt, ## __VA_ARGS__) + static void reset_hal_enc_task(HalEncTask *task) { memset(task, 0, sizeof(*task)); @@ -106,7 +118,6 @@ void *mpp_enc_control_thread(void *data) reset_hal_enc_task(enc_task); if (mpp_frame_get_buffer(frame)) { - RK_U32 outputStreamSize = 0; /* * if there is available buffer in the input frame do encoding */ @@ -117,7 +128,6 @@ void *mpp_enc_control_thread(void *data) MppBuffer buffer = NULL; mpp_buffer_get(mpp->mPacketGroup, &buffer, size); - mpp_log("create buffer size %d fd %d\n", size, mpp_buffer_get_fd(buffer)); mpp_packet_init_with_buffer(&packet, buffer); mpp_buffer_put(buffer); } @@ -128,10 +138,14 @@ void *mpp_enc_control_thread(void *data) enc_task->input = mpp_frame_get_buffer(frame); enc_task->output = mpp_packet_get_buffer(packet); enc_task->mv_info = mv_info; - ret = controller_encode(mpp->mEnc->controller, enc_task); - if (ret) { - mpp_err("mpp %p controller_encode failed return %d", mpp, ret); - goto TASK_END; + + { + AutoMutex auto_lock(&enc->lock); + ret = controller_encode(mpp->mEnc->controller, enc_task); + if (ret) { + mpp_err("mpp %p controller_encode failed return %d", mpp, ret); + goto TASK_END; + } } ret = mpp_hal_reg_gen((mpp->mEnc->hal), &task_info); if (ret) { @@ -148,9 +162,8 @@ void *mpp_enc_control_thread(void *data) mpp_err("mpp %p hal_hw_wait failed return %d", mpp, ret); goto TASK_END; } - controller_config(mpp->mEnc->controller, GET_OUTPUT_STREAM_SIZE, (void*)&outputStreamSize); TASK_END: - mpp_packet_set_length(packet, outputStreamSize); + mpp_packet_set_length(packet, task_info.enc.length); } else { /* * else init a empty packet for output @@ -274,6 +287,8 @@ MPP_RET mpp_enc_init(MppEnc **enc, MppCodingType coding) RK_S32 task_count = 2; IOInterruptCB cb = {NULL, NULL}; + mpp_env_get_u32("mpp_enc_debug", &mpp_enc_debug, 0); + if (NULL == enc) { mpp_err_f("failed to malloc context\n"); return MPP_ERR_NULL_PTR; @@ -304,13 +319,15 @@ MPP_RET mpp_enc_init(MppEnc **enc, MppCodingType coding) cb.callBack = mpp_enc_notify; cb.opaque = p; - ControllerCfg controller_cfg = { + ControllerCfg ctrl_cfg = { coding, + &p->cfg, + &p->set, task_count, cb, }; - ret = controller_init(&controller, &controller_cfg); + ret = controller_init(&controller, &ctrl_cfg); if (ret) { mpp_err_f("could not init controller\n"); break; @@ -325,8 +342,10 @@ MPP_RET mpp_enc_init(MppEnc **enc, MppCodingType coding) HAL_VEPU, frame_slots, packet_slots, + &p->cfg, + &p->set, NULL, - 1/*controller_cfg.task_count*/, // TODO + 1/*ctrl_cfg.task_count*/, // TODO 0, cb, }; @@ -386,7 +405,8 @@ MPP_RET mpp_enc_deinit(MppEnc *enc) MPP_RET mpp_enc_reset(MppEnc *enc) { - (void)enc; + AutoMutex auto_lock(&enc->lock); + return MPP_OK; } @@ -400,15 +420,18 @@ MPP_RET mpp_enc_notify(void *ctx, void *info) MPP_RET mpp_enc_control(MppEnc *enc, MpiCmd cmd, void *param) { - if (NULL == enc) { - mpp_err_f("found NULL input enc %p\n", enc); + if (NULL == enc || NULL == param) { + mpp_err_f("found NULL input enc %p cmd %x param %d\n", enc, cmd, param); return MPP_ERR_NULL_PTR; } - MPP_RET ret = MPP_NOK; + MPP_RET ret = MPP_OK; + AutoMutex auto_lock(&enc->lock); switch (cmd) { case MPP_ENC_SET_CFG : { + mpp_enc_dbg_ctrl("set config\n"); +#if 0 MppEncConfig *mpp_cfg = &enc->mpp_cfg; void *extra_info_cfg = NULL; @@ -425,33 +448,171 @@ MPP_RET mpp_enc_control(MppEnc *enc, MpiCmd cmd, void *param) controller_config(enc->controller, GET_ENC_EXTRA_INFO, (void *)&extra_info_cfg); ret = mpp_hal_control(enc->hal, MPP_ENC_SET_EXTRA_INFO, extra_info_cfg); - +#endif } break; case MPP_ENC_GET_CFG : { MppEncConfig *mpp_cfg = (MppEncConfig *)param; + mpp_enc_dbg_ctrl("get config\n"); mpp_assert(mpp_cfg->size == sizeof(enc->mpp_cfg)); *mpp_cfg = enc->mpp_cfg; - ret = MPP_OK; } break; + + case MPP_ENC_SET_PREP_CFG : { + mpp_enc_dbg_ctrl("set prep config\n"); + memcpy(&enc->set.prep, param, sizeof(enc->set.prep)); + + ret = mpp_hal_control(enc->hal, cmd, param); + if (!ret) + mpp_enc_update_prep_cfg(&enc->cfg.prep, &enc->set.prep); + } break; + case MPP_ENC_GET_PREP_CFG : { + MppEncPrepCfg *p = (MppEncPrepCfg *)param; + + mpp_enc_dbg_ctrl("get prep config\n"); + memcpy(p, &enc->cfg.prep, sizeof(*p)); + } break; + case MPP_ENC_SET_RC_CFG : { + mpp_enc_dbg_ctrl("set rc config\n"); + memcpy(&enc->set.rc, param, sizeof(enc->set.rc)); + + ret = controller_config(enc->controller, cmd, param); + if (!ret) + ret = mpp_hal_control(enc->hal, cmd, param); + + if (!ret) + mpp_enc_update_rc_cfg(&enc->cfg.rc, &enc->set.rc); + } break; + case MPP_ENC_GET_RC_CFG : { + MppEncRcCfg *p = (MppEncRcCfg *)param; + + mpp_enc_dbg_ctrl("get rc config\n"); + memcpy(p, &enc->cfg.rc, sizeof(*p)); + } break; + case MPP_ENC_SET_CODEC_CFG : { + mpp_enc_dbg_ctrl("set codec config\n"); + memcpy(&enc->set.codec, param, sizeof(enc->set.codec)); + + ret = mpp_hal_control(enc->hal, cmd, param); + /* NOTE: codec information will be update by encoder hal */ + } break; + case MPP_ENC_GET_CODEC_CFG : { + MppEncCodecCfg *p = (MppEncCodecCfg *)param; + + mpp_enc_dbg_ctrl("get codec config\n"); + memcpy(p, &enc->cfg.codec, sizeof(*p)); + } break; + case MPP_ENC_SET_IDR_FRAME : { + mpp_enc_dbg_ctrl("idr request\n"); ret = controller_config(enc->controller, SET_IDR_FRAME, param); } break; - case MPP_ENC_GET_EXTRA_INFO : - case MPP_ENC_SET_RC_CFG : - case MPP_ENC_GET_RC_CFG : - case MPP_ENC_SET_OSD_PLT_CFG : - case MPP_ENC_SET_OSD_DATA_CFG : - case MPP_ENC_SET_SEI_CFG : - case MPP_ENC_GET_SEI_DATA : - case MPP_ENC_SET_PREP_CFG : { + case MPP_ENC_GET_EXTRA_INFO : { + mpp_enc_dbg_ctrl("get extra info\n"); + ret = mpp_hal_control(enc->hal, cmd, param); + } break; + case MPP_ENC_SET_OSD_PLT_CFG : { + mpp_enc_dbg_ctrl("set osd plt\n"); + ret = mpp_hal_control(enc->hal, cmd, param); + } break; + case MPP_ENC_SET_OSD_DATA_CFG : { + mpp_enc_dbg_ctrl("set osd data\n"); + ret = mpp_hal_control(enc->hal, cmd, param); + } break; + case MPP_ENC_SET_SEI_CFG : { + mpp_enc_dbg_ctrl("set sei\n"); + ret = mpp_hal_control(enc->hal, cmd, param); + } break; + case MPP_ENC_GET_SEI_DATA : { + mpp_enc_dbg_ctrl("get sei\n"); ret = mpp_hal_control(enc->hal, cmd, param); } break; default : { + mpp_log_f("unsupported cmd id %08x param %p\n", cmd, param); + ret = MPP_NOK; } break; } return ret; } +void mpp_enc_update_prep_cfg(MppEncPrepCfg *dst, MppEncPrepCfg *src) +{ + RK_U32 change = src->change; + + if (change) { + if (change & MPP_ENC_PREP_CFG_CHANGE_INPUT) { + dst->width = src->width; + dst->height = src->height; + dst->hor_stride = src->hor_stride; + dst->ver_stride = src->ver_stride; + } + + if (change & MPP_ENC_PREP_CFG_CHANGE_FORMAT) + dst->format = src->format; + + if (change & MPP_ENC_PREP_CFG_CHANGE_ROTATION) + dst->rotation = src->rotation; + + if (change & MPP_ENC_PREP_CFG_CHANGE_MIRRORING) + dst->mirroring = src->mirroring; + + if (change & MPP_ENC_PREP_CFG_CHANGE_DENOISE) + dst->denoise = src->denoise; + + if (change & MPP_ENC_PREP_CFG_CHANGE_SHARPEN) + dst->sharpen = src->sharpen; + + /* + * NOTE: use OR here for avoiding overwrite on multiple config + * When next encoding is trigger the change flag will be clear + */ + dst->change |= change; + src->change = 0; + } +} + +void mpp_enc_update_rc_cfg(MppEncRcCfg *dst, MppEncRcCfg *src) +{ + RK_U32 change = src->change; + if (change) { + if (change & MPP_ENC_RC_CFG_CHANGE_RC_MODE) + dst->rc_mode = src->rc_mode; + + if (change & MPP_ENC_RC_CFG_CHANGE_QUALITY) + dst->quality = src->quality; + + if (change & MPP_ENC_RC_CFG_CHANGE_BPS) { + dst->bps_target = src->bps_target; + dst->bps_max = src->bps_max; + dst->bps_min = src->bps_min; + } + + if (change & MPP_ENC_RC_CFG_CHANGE_FPS_IN) { + dst->fps_in_flex = src->fps_in_flex; + dst->fps_in_num = src->fps_in_num; + dst->fps_in_denorm = src->fps_in_denorm; + } + + if (change & MPP_ENC_RC_CFG_CHANGE_FPS_OUT) { + dst->fps_out_flex = src->fps_out_flex; + dst->fps_out_num = src->fps_out_num; + dst->fps_out_denorm = src->fps_out_denorm; + } + + if (change & MPP_ENC_RC_CFG_CHANGE_GOP) + dst->gop = src->gop; + + if (change & MPP_ENC_RC_CFG_CHANGE_SKIP_CNT) + dst->skip_cnt = src->skip_cnt; + + /* + * NOTE: use OR here for avoiding overwrite on multiple config + * When next encoding is trigger the change flag will be clear + */ + dst->change |= change; + src->change = 0; + } +} + diff --git a/mpp/codec/mpp_rc.cpp b/mpp/codec/mpp_rc.cpp new file mode 100644 index 00000000..2f4aa9b9 --- /dev/null +++ b/mpp/codec/mpp_rc.cpp @@ -0,0 +1,619 @@ +/* + * Copyright 2016 Rockchip Electronics Co. LTD + * + * 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. + */ + +#define MODULE_TAG "mpp_rc" + +#include "mpp_env.h" +#include "mpp_mem.h" +#include "mpp_common.h" +#include "mpp_rc.h" + +#define MPP_RC_DBG_FUNCTION (0x00000001) +#define MPP_RC_DBG_RC (0x00000010) + +#define mpp_rc_dbg(flag, fmt, ...) _mpp_dbg(mpp_rc_debug, flag, fmt, ## __VA_ARGS__) +#define mpp_rc_dbg_f(flag, fmt, ...) _mpp_dbg_f(mpp_rc_debug, flag, fmt, ## __VA_ARGS__) + +#define mpp_rc_dbg_func(fmt, ...) mpp_rc_dbg_f(MPP_RC_DBG_FUNCTION, fmt, ## __VA_ARGS__) +#define mpp_rc_dbg_rc(fmt, ...) mpp_rc_dbg(MPP_RC_DBG_RC, fmt, ## __VA_ARGS__) + +#define SIGN(a) ((a) < (0) ? (-1) : (1)) +#define DIV(a, b) (((a) + (SIGN(a) * (b)) / 2) / (b)) + +static RK_U32 mpp_rc_debug = 0; + +static RK_S32 axb_div_c(RK_S32 a, RK_S32 b, RK_S32 c) +{ + RK_U32 left = 32; + RK_U32 right = 0; + RK_U32 shift; + RK_S32 sign = 1; + RK_S32 tmp; + + if (a == 0 || b == 0) + return 0; + else if ((a * b / b) == a && c != 0) + return (a * b / c); + + if (a < 0) { + sign = -1; + a = -a; + } + if (b < 0) { + sign *= -1; + b = -b; + } + if (c < 0) { + sign *= -1; + c = -c; + } + + if (c == 0) + return 0x7FFFFFFF * sign; + + if (b > a) { + tmp = b; + b = a; + a = tmp; + } + + for (--left; (((RK_U32)a << left) >> left) != (RK_U32)a; --left) + ; + + left--; + + while (((RK_U32)b >> right) > (RK_U32)c) + right++; + + if (right > left) { + return 0x7FFFFFFF * sign; + } else { + shift = left - right; + return (RK_S32)((((RK_U32)a << shift) / + (RK_U32)c * (RK_U32)b) >> shift) * sign; + } +} + +MPP_RET mpp_data_init(MppData **data, RK_S32 size) +{ + if (NULL == data || size <= 0) { + mpp_err_f("invalid data %data size %d\n", data, size); + return MPP_ERR_NULL_PTR; + } + + *data = NULL; + MppData *p = mpp_malloc_size(MppData, sizeof(MppData) + sizeof(RK_S32) * size); + if (NULL == p) { + mpp_err_f("malloc size %d failed\n", size); + return MPP_ERR_MALLOC; + } + p->size = size; + p->len = 0; + p->pos = 0; + p->val = (RK_S32 *)(p + 1); + *data = p; + + return MPP_OK; +} + +void mpp_data_deinit(MppData *p) +{ + if (p) + mpp_free(p); +} + +void mpp_data_update(MppData *p, RK_S32 val) +{ + mpp_assert(p); + + p->val[p->pos] = val; + + if (++p->pos >= p->size) + p->pos = 0; + + if (p->len < p->size) + p->len++; +} + +RK_S32 mpp_data_avg(MppData *p, RK_S32 len, RK_S32 num, RK_S32 denorm) +{ + mpp_assert(p); + + RK_S32 i; + RK_S32 sum = 0; + RK_S32 pos = p->pos; + + if (!p->len) + return 0; + + if (len < 0 || len > p->len) + len = p->len; + + if (num == denorm) { + i = len; + while (i--) { + if (pos) + pos--; + else + pos = p->len - 1; + + sum += p->val[pos]; + } + } else { + mpp_assert(num > denorm); + RK_S32 acc_num = num; + RK_S32 acc_denorm = denorm; + + i = len - 1; + sum = p->val[--pos]; + while (i--) { + if (pos) + pos--; + else + pos = p->len - 1; + + sum += p->val[pos] * acc_num / acc_denorm; + acc_num += num; + acc_denorm += denorm; + } + } + return DIV(sum, len); +} + +void mpp_pid_reset(MppPIDCtx *p) +{ + p->p = 0; + p->i = 0; + p->d = 0; + p->count = 0; +} + +void mpp_pid_set_param(MppPIDCtx *ctx, RK_S32 coef_p, RK_S32 coef_i, RK_S32 coef_d, RK_S32 div, RK_S32 len) +{ + ctx->coef_p = coef_p; + ctx->coef_i = coef_i; + ctx->coef_d = coef_d; + ctx->div = div; + ctx->len = len; + ctx->count = 0; + + mpp_rc_dbg_rc("RC: pid ctx %p coef: P %d I %d D %d div %d len %d\n", + ctx, coef_p, coef_i, coef_d, div, len); +} + +void mpp_pid_update(MppPIDCtx *ctx, RK_S32 val) +{ + mpp_rc_dbg_rc("RC: pid ctx %p update val %d\n", ctx, val); + mpp_rc_dbg_rc("RC: pid ctx %p before update P %d I %d D %d\n", ctx, ctx->p, ctx->i, ctx->d); + + ctx->d = val - ctx->p; /* Derivative */ + ctx->i = val + ctx->i; /* Integral */ + ctx->p = val; /* Proportional */ + + mpp_rc_dbg_rc("RC: pid ctx %p after update P %d I %d D %d\n", ctx, ctx->p, ctx->i, ctx->d); + ctx->count++; + /* + * pid control is a short time control, it needs periodically reset + */ + if (ctx->count >= ctx->len) + mpp_pid_reset(ctx); +} + +RK_S32 mpp_pid_calc(MppPIDCtx *p) +{ + RK_S32 a = p->p * p->coef_p + p->i * p->coef_i + p->d * p->coef_d; + RK_S32 b = p->div; + + mpp_rc_dbg_rc("RC: pid ctx %p p %10d coef %d\n", p, p->p, p->coef_p); + mpp_rc_dbg_rc("RC: pid ctx %p i %10d coef %d\n", p, p->i, p->coef_i); + mpp_rc_dbg_rc("RC: pid ctx %p d %10d coef %d\n", p, p->d, p->coef_d); + mpp_rc_dbg_rc("RC: pid ctx %p a %10d b %d\n", p, a, b); + + return DIV(a, b); +} + +MPP_RET mpp_rc_init(MppRateControl **ctx) +{ + if (NULL == ctx) { + mpp_log_f("invalid ctx %p\n", ctx); + return MPP_ERR_NULL_PTR; + } + + MPP_RET ret = MPP_OK; + MppRateControl *p = mpp_calloc(MppRateControl, 1); + if (NULL == ctx) { + mpp_log_f("malloc failed\n"); + ret = MPP_ERR_MALLOC; + } else { + p->gop = -1; + } + + mpp_env_get_u32("mpp_rc_debug", &mpp_rc_debug, 0); + + *ctx = p; + return ret; +} + +MPP_RET mpp_rc_deinit(MppRateControl *ctx) +{ + if (NULL == ctx) { + mpp_log_f("invalid ctx %p\n", ctx); + return MPP_ERR_NULL_PTR; + } + + if (ctx->intra) { + mpp_data_deinit(ctx->intra); + ctx->intra = NULL; + } + + if (ctx->gop_bits) { + mpp_data_deinit(ctx->gop_bits); + ctx->gop_bits = NULL; + } + + mpp_free(ctx); + return MPP_OK; +} + +MPP_RET mpp_rc_update_user_cfg(MppRateControl *ctx, MppEncRcCfg *cfg) +{ + if (NULL == ctx || NULL == cfg) { + mpp_log_f("invalid ctx %p cfg %p\n", ctx, cfg); + return MPP_ERR_NULL_PTR; + } + + RK_U32 change = cfg->change; + RK_U32 clear_acc = 0; + RK_U32 gop_start = 0; + + /* + * step 1: update parameters + */ + if (change & MPP_ENC_RC_CFG_CHANGE_BPS) { + ctx->bps_min = cfg->bps_min; + ctx->bps_max = cfg->bps_max; + ctx->bps_target = cfg->bps_target; + } + + if (change & MPP_ENC_RC_CFG_CHANGE_FPS_OUT) { + ctx->fps_num = cfg->fps_out_num; + ctx->fps_denom = cfg->fps_out_denorm; + ctx->fps_out = ctx->fps_num / ctx->fps_denom; + clear_acc = 1; + } + + if ((change & MPP_ENC_RC_CFG_CHANGE_GOP) && + (ctx->gop != cfg->gop)) { + RK_S32 gop = cfg->gop; + + if (ctx->intra) + mpp_data_deinit(ctx->intra); + mpp_data_init(&ctx->intra, gop); + + if (ctx->gop_bits) + mpp_data_deinit(ctx->gop_bits); + mpp_data_init(&ctx->gop_bits, gop); + + ctx->gop = gop; + if (gop < ctx->fps_out) + ctx->window_len = ctx->fps_out; + else + ctx->window_len = gop; + + if (ctx->window_len < 10) + ctx->window_len = 10; + + if (ctx->window_len > ctx->fps_out) + ctx->window_len = ctx->fps_out; + + mpp_pid_reset(&ctx->pid_intra); + mpp_pid_reset(&ctx->pid_inter); + mpp_pid_set_param(&ctx->pid_intra, 4, 6, 0, 100, ctx->window_len); + mpp_pid_set_param(&ctx->pid_inter, 4, 6, 0, 100, ctx->window_len); + + clear_acc = 1; + + /* if gop cfg changed, current frame is regarded as IDR frame */ + gop_start = 1; + } + + /* + * step 2: derivate parameters + */ + ctx->bits_per_pic = axb_div_c(cfg->bps_target, ctx->fps_denom, ctx->fps_num); + mpp_rc_dbg_rc("RC: rc ctx %p target bit per picture %d\n", ctx, ctx->bits_per_pic); + + if (clear_acc) { + ctx->acc_intra_bits = 0; + ctx->acc_inter_bits = 0; + ctx->acc_total_bits = 0; + ctx->acc_intra_count = 0; + ctx->acc_inter_count = 0; + } + + RK_S32 gop = ctx->gop; + RK_S32 avg = ctx->bits_per_pic; + + ctx->cur_frmtype = INTER_P_FRAME; + if (gop == 0) { + /* only one intra then all inter */ + ctx->gop_mode = MPP_GOP_ALL_INTER; + ctx->bits_per_inter = avg; + ctx->bits_per_intra = avg * 10; + ctx->intra_to_inter_rate = 0; + } else if (gop == 1) { + /* all intra */ + ctx->gop_mode = MPP_GOP_ALL_INTRA; + ctx->bits_per_inter = 0; + ctx->bits_per_intra = avg; + ctx->intra_to_inter_rate = 0; + gop_start = 1; + } else if (ctx->gop < ctx->window_len) { + /* small gop - use fix allocation */ + ctx->gop_mode = MPP_GOP_SMALL; + ctx->intra_to_inter_rate = gop + 1; + ctx->bits_per_inter = avg / 2; + ctx->bits_per_intra = ctx->bits_per_inter * ctx->intra_to_inter_rate; + } else { + /* large gop - use dynamic allocation */ + ctx->gop_mode = MPP_GOP_LARGE; + ctx->intra_to_inter_rate = 10; + ctx->bits_per_inter = ctx->bits_per_pic; + ctx->bits_per_intra = ctx->bits_per_inter * ctx->intra_to_inter_rate; + } + + if (ctx->acc_total_count == gop) + gop_start = 1; + + if (gop_start) { + ctx->cur_frmtype = INTRA_FRAME; + ctx->acc_total_count = 0; + } + + cfg->change = 0; + + return MPP_OK; +} + +MPP_RET mpp_rc_bits_allocation(MppRateControl *ctx, RcSyntax *rc_syn) +{ + if (NULL == ctx || NULL == rc_syn) { + mpp_log_f("invalid ctx %p rc_syn %p\n", ctx, rc_syn); + return MPP_ERR_NULL_PTR; + } + + /* step 1: calc target frame bits */ + switch (ctx->gop_mode) { + case MPP_GOP_ALL_INTER : { + if (ctx->cur_frmtype == INTRA_FRAME) + ctx->bits_target = ctx->bits_per_intra; + else + ctx->bits_target = ctx->bits_per_inter - mpp_pid_calc(&ctx->pid_inter); + } break; + case MPP_GOP_ALL_INTRA : { + ctx->bits_target = ctx->bits_per_intra - mpp_pid_calc(&ctx->pid_intra); + } break; + default : { + if (ctx->cur_frmtype == INTRA_FRAME) { + ctx->bits_target = ctx->bits_per_intra - mpp_pid_calc(&ctx->pid_intra); + } else { + if (ctx->pre_frmtype == INTRA_FRAME) { + /* + * case - inter frame after intra frame + * update inter target bits with compensation of previous intra frame + */ + RK_S32 bits_prev_intra = mpp_data_avg(ctx->intra, 1, 1, 1); + ctx->bits_per_inter = ctx->bits_per_pic - (bits_prev_intra - ctx->bits_per_pic) / + (ctx->window_len - 1); + mpp_rc_dbg_rc("RC: rc ctx %p bits pic %d win %d intra %d inter %d\n", + ctx, ctx->bits_per_pic, ctx->window_len, + bits_prev_intra, ctx->bits_per_inter); + + mpp_rc_dbg_rc("RC: rc ctx %p update inter target bits to %d\n", + ctx, ctx->bits_per_inter); + ctx->bits_target = ctx->bits_per_inter; + } else { + RK_S32 diff_bit = mpp_pid_calc(&ctx->pid_inter); + ctx->bits_target = ctx->bits_per_inter - diff_bit; + mpp_rc_dbg_rc("RC: rc ctx %p inter pid diff %d target %d\n", + ctx, diff_bit, ctx->bits_target); + } + } + } break; + } + + rc_syn->bit_target = ctx->bits_target; + rc_syn->type = ctx->cur_frmtype; + if (ctx->cur_frmtype == INTRA_FRAME) { + mpp_rc_dbg_rc("RC: rc ctx %p intra target bits %d\n", ctx, ctx->bits_target); + } else { + mpp_rc_dbg_rc("RC: rc ctx %p inter target bits %d\n", ctx, ctx->bits_target); + } + + /* step 2: calc min and max bits */ + + return MPP_OK; +} + +MPP_RET mpp_rc_update_hw_result(MppRateControl *ctx, RcHalResult *result) +{ + if (NULL == ctx || NULL == result) { + mpp_log_f("invalid ctx %p result %p\n", ctx, result); + return MPP_ERR_NULL_PTR; + } + + RK_S32 bits = result->bits; + + if (result->type == INTRA_FRAME) { + mpp_rc_dbg_rc("RC: rc ctx %p intra real bits %d target %d\n", + ctx, bits, ctx->bits_per_intra); + ctx->acc_intra_count++; + ctx->acc_intra_bits += bits; + mpp_data_update(ctx->intra, bits); + mpp_data_update(ctx->gop_bits, bits); + mpp_pid_update(&ctx->pid_intra, bits - ctx->bits_per_intra); + } else { + mpp_rc_dbg_rc("RC: rc ctx %p inter real bits %d target %d\n", + ctx, bits, ctx->bits_per_inter); + ctx->acc_inter_count++; + ctx->acc_inter_bits += bits; + mpp_data_update(ctx->gop_bits, bits); + mpp_pid_update(&ctx->pid_inter, bits - ctx->bits_per_inter); + } + ctx->acc_total_count++; + + switch (ctx->gop_mode) { + case MPP_GOP_ALL_INTER : { + } break; + case MPP_GOP_ALL_INTRA : { + } break; + default : { + } break; + } + + ctx->pre_frmtype = ctx->cur_frmtype; + + return MPP_OK; +} + +MPP_RET mpp_linreg_init(MppLinReg **ctx, RK_S32 size) +{ + if (NULL == ctx) { + mpp_log_f("invalid ctx %p\n", ctx); + return MPP_ERR_NULL_PTR; + } + + MPP_RET ret = MPP_OK; + MppLinReg *p = mpp_calloc_size(MppLinReg, + sizeof(MppLinReg) + + size * (sizeof(RK_S32) * 2 + sizeof(RK_S64))); + if (NULL == p) { + mpp_log_f("malloc failed\n"); + ret = MPP_ERR_MALLOC; + } else { + p->x = (RK_S32 *)(p + 1); + p->r = p->x + size; + p->y = (RK_S64 *)(p->r + size); + p->size = size; + } + + *ctx = p; + return ret; +} + +MPP_RET mpp_linreg_deinit(MppLinReg *ctx) +{ + if (NULL == ctx) { + mpp_log_f("invalid ctx %p\n", ctx); + return MPP_ERR_NULL_PTR; + } + + mpp_free(ctx); + return MPP_OK; +} + +/* + * This function want to calculate coefficient 'b' 'a' using ordinary + * least square. + * y = b * x + a + * b_n = accumulate(x * y) - n * (average(x) * average(y)) + * a_n = accumulate(x * x) * accumulate(y) - accumulate(x) * accumulate(x * y) + * denom = accumulate(x * x) - n * (square(average(x)) + * b = b_n / denom + * a = a_n / denom + */ +MPP_RET mpp_linreg_update(MppLinReg *ctx, RK_S32 x, RK_S32 r) +{ + if (NULL == ctx) { + mpp_log_f("invalid ctx %p\n", ctx); + return MPP_ERR_NULL_PTR; + } + + /* step 1: save data */ + ctx->x[ctx->i] = x; + ctx->r[ctx->i] = r; + ctx->y[ctx->i] = x * x * r; + + mpp_rc_dbg_rc("RC: linreg %p save index %d x %d r %d x*x*r %lld\n", + ctx, ctx->i, x, r, (RK_S64)(x * x * r)); + + if (++ctx->i >= ctx->size) + ctx->i = 0; + + if (ctx->n < ctx->size) + ctx->n++; + + /* step 2: update coefficient */ + RK_S32 i = 0; + RK_S32 n; + RK_S64 acc_xy = 0; + RK_S64 acc_x = 0; + RK_S64 acc_y = 0; + RK_S64 acc_sq_x = 0; + + RK_S64 b_num = 0; + RK_S64 denom = 0; + + RK_S32 *cx = ctx->x; + RK_S64 *cy = ctx->y; + + n = ctx->n; + i = ctx->i; + + while (n--) { + if (i == 0) + i = ctx->size - 1; + else + i--; + + acc_xy += cx[i] * cy[i]; + acc_x += cx[i]; + acc_y += cy[i]; + acc_sq_x += cx[i] * cx[i]; + } + + b_num = n * acc_xy - acc_x * acc_y; + denom = n * acc_sq_x - acc_x * acc_x; + + mpp_rc_dbg_rc("RC: linreg %p acc_xy %lld acc_x %lld acc_y %lld acc_sq_x %lld\n", + ctx, acc_xy, acc_x, acc_y, acc_sq_x); + mpp_rc_dbg_rc("RC: linreg %p n %d b_num %lld denom %lld\n", + ctx, n, b_num, denom); + + mpp_rc_dbg_rc("RC: linreg %p before update coefficient a %d b %d\n", + ctx, ctx->a, ctx->b); + + if (denom) + ctx->b = DIV(b_num, denom); + else + ctx->b = 0; + + ctx->a = DIV(acc_y, n) - DIV(acc_x * ctx->b, n); + + mpp_rc_dbg_rc("RC: linreg %p after update coefficient a %d b %d\n", + ctx, ctx->a, ctx->b); + + return MPP_OK; +} + +RK_S32 mpp_linreg_calc(MppLinReg *ctx, RK_S32 x) +{ + if (x <= 0) + return -1; + + return DIV(ctx->b, x) + DIV(ctx->a, x * x); +} + diff --git a/mpp/common/h264e_syntax.h b/mpp/common/h264e_syntax.h index b26902b2..269e4704 100644 --- a/mpp/common/h264e_syntax.h +++ b/mpp/common/h264e_syntax.h @@ -3,6 +3,7 @@ #include "rk_type.h" #include "h264_syntax.h" +#include "mpp_rc.h" #define H264_BIT_DEPTH 8 #define H264_QP_BD_OFFSET (6*(H264_BIT_DEPTH-8)) @@ -14,58 +15,94 @@ typedef struct h264e_osd_pos_t { RK_U32 rd_pos_y : 8; } h264e_osd_pos; //OSD_POS0-7 -typedef struct h264e_syntax_t { - RK_U32 frame_coding_type; //(VEPU)0: inter, 1: intra (RKVENC)RKVENC_FRAME_TYPE_* - RK_U32 slice_type; - RK_S32 pic_init_qp; //COMB, TODO: merge with swreg59.pic_init_qp - RK_S32 slice_alpha_offset; //COMB TODO: merge with swreg62.sli_beta_ofst - RK_S32 slice_beta_offset; //COMB TODO: merge with swreg62.sli_alph_ofst - RK_S32 chroma_qp_index_offset; //COMB - RK_S32 second_chroma_qp_index_offset; //TODO: may be removed later, get from sps/pps instead - RK_S32 deblocking_filter_control; //COMB - RK_S32 disable_deblocking_filter_idc; - RK_S32 filter_disable; //TODO: merge width disable_deblocking_filter_idc above - RK_U16 idr_pic_id; //COMB - RK_S32 pps_id; //COMB TODO: merge with swreg60.pps_id //TODO: may be removed later, get from sps/pps instead - RK_S32 frame_num; //COMB TODO: swreg60.frm_num - RK_S32 slice_size_mb_rows; - RK_S32 h264_inter4x4_disabled; //COMB - RK_S32 enable_cabac; //COMB - RK_S32 transform8x8_mode; //COMB - RK_S32 cabac_init_idc; //COMB TODO: merge with swreg60.cbc_init_idc +typedef enum H264eHwType_t { + H264E_RKV, + H264E_VPU +} H264eHwType; + +/* + * Overall configuration required by hardware + * Currently support vepu and rkvenc + */ +typedef struct H264eHwCfg_t { + H264eHwType hw_type; + + /* Input data parameter */ + RK_S32 width; + RK_S32 height; + RK_S32 hor_stride; + RK_S32 ver_stride; + RK_S32 input_format; /* Hardware config format */ + RK_S32 r_mask_msb; + RK_S32 g_mask_msb; + RK_S32 b_mask_msb; + RK_S32 uv_rb_swap; /* u/v or R/B planar bit swap flag */ + RK_S32 alpha_swap; /* alpha/RGB bit swap flag */ + RK_U32 color_conversion_coeff_a; + RK_U32 color_conversion_coeff_b; + RK_U32 color_conversion_coeff_c; + RK_U32 color_conversion_coeff_e; + RK_U32 color_conversion_coeff_f; + + /* Buffer parameter */ + RK_U32 input_luma_addr; + RK_U32 input_cb_addr; + RK_U32 input_cr_addr; + RK_U32 output_strm_limit_size; + RK_U32 output_strm_addr; + + /* + * For vpu + * 0 - inter + * 1 - intra + * 2 - mvc-inter + * + * For rkvenc + * RKVENC_FRAME_TYPE_* + */ + RK_S32 frame_type; + + /* Parameter in sps/pps/slice */ + RK_S32 enable_cabac; + RK_S32 cabac_init_idc; + RK_S32 constrained_intra_prediction; + RK_S32 pic_init_qp; + RK_S32 transform8x8_mode; + + RK_S32 pps_id; + RK_S32 frame_num; RK_S32 pic_order_cnt_lsb; + RK_S32 filter_disable; + RK_S32 idr_pic_id; + RK_S32 slice_alpha_offset; + RK_S32 slice_beta_offset; + RK_S32 chroma_qp_index_offset; + RK_S32 second_chroma_qp_index_offset; + RK_S32 inter4x4_disabled; /* rate control relevant */ + RK_S32 qp_prev; RK_S32 qp; + RK_S32 qp_min; + RK_S32 qp_max; RK_S32 mad_qp_delta; RK_S32 mad_threshold; - RK_S32 qp_min; //COMB, TODO: merge width swreg54.rc_min_qp - RK_S32 qp_max; //COMB, TODO: merge width swreg54.rc_max_qp + + /* + * VEPU MB rate control parameter + * VEPU MB can have max 10 check points. + * On each check point hardware will check the target bit and + * error bits and change qp according to delta qp step + */ + RK_S32 slice_size_mb_rows; RK_S32 cp_distance_mbs; RK_S32 cp_target[10]; RK_S32 target_error[7]; RK_S32 delta_qp[7]; - - RK_U32 output_strm_limit_size; // outputStrmSize - RK_U32 output_strm_addr; // outputStrmBase - RK_U32 pic_luma_width; // preProcess->lumWidth - RK_U32 pic_luma_height; // preProcess->lumHeight - RK_U32 pic_hor_stride; // preProcess->hor_stride - RK_U32 pic_ver_stride; // preProcess->ver_stride - RK_U32 input_luma_addr; // inputLumBase - RK_U32 input_cb_addr; // inputCbBase - RK_U32 input_cr_addr; // inputCrBase - RK_U32 input_image_format; // inputImageFormat - RK_U32 color_conversion_coeff_a; //colorConversionCoeffA - RK_U32 color_conversion_coeff_b; //colorConversionCoeffB - RK_U32 color_conversion_coeff_c; //colorConversionCoeffC - RK_U32 color_conversion_coeff_e; //colorConversionCoeffE - RK_U32 color_conversion_coeff_f; //colorConversionCoeffF - /* RKVENC extra syntax below */ - RK_S32 profile_idc; //TODO: may be removed later, get from sps/pps instead - RK_S32 level_idc; //TODO: may be removed later, get from sps/pps instead + RK_S32 profile_idc; + RK_S32 level_idc; RK_S32 link_table_en; RK_S32 keyframe_max_interval; @@ -73,10 +110,12 @@ typedef struct h264e_syntax_t { RK_S32 roi_en; RK_S32 osd_mode; //0: disable osd, 1:palette type 0(congfigurable mode), 2:palette type 1(fixed mode). RK_S32 preproc_en; -} h264e_syntax; + RK_S32 coding_type; /* SliceType: P_SLICE = 0 I_SLICE = 2 */ +} H264eHwCfg; typedef struct h264e_feedback_t { /* rc */ + RcHalResult *result; RK_U32 hw_status; /* 0:corret, 1:error */ RK_S32 qp_sum; RK_S32 cp[10]; diff --git a/mpp/hal/CMakeLists.txt b/mpp/hal/CMakeLists.txt index af72364d..09ecbe92 100644 --- a/mpp/hal/CMakeLists.txt +++ b/mpp/hal/CMakeLists.txt @@ -1,5 +1,6 @@ # vim: syntax=cmake include_directories(worker/inc) +include_directories(common) # ---------------------------------------------------------------------------- # add hardware hal @@ -9,6 +10,7 @@ add_subdirectory(rkdec) add_subdirectory(rkenc) add_subdirectory(dummy) add_subdirectory(rkdec/avsd) +add_subdirectory(common) # ---------------------------------------------------------------------------- # add mpp_hal implement diff --git a/mpp/hal/common/CMakeLists.txt b/mpp/hal/common/CMakeLists.txt new file mode 100644 index 00000000..8c9221d1 --- /dev/null +++ b/mpp/hal/common/CMakeLists.txt @@ -0,0 +1,4 @@ +# vim: syntax=cmake +include_directories(.) + +add_subdirectory(h264) diff --git a/mpp/hal/common/h264/CMakeLists.txt b/mpp/hal/common/h264/CMakeLists.txt new file mode 100644 index 00000000..3642075e --- /dev/null +++ b/mpp/hal/common/h264/CMakeLists.txt @@ -0,0 +1,25 @@ +# vim: syntax=cmake +include_directories(.) +include_directories(../../rkenc/h264e/) +include_directories(../../vpu/h264e/) + +# hal h264 header +set(HAL_H264E_HDR + hal_h264e_com.h + ) + +# hal h264 encoder sourse +set(HAL_H264E_SRC + hal_h264e_com.c + hal_h264e_api.c + ) + +add_library(hal_h264e STATIC + ${HAL_H264E_HDR} + ${HAL_H264E_SRC} + ) + +target_link_libraries(hal_h264e hal_h264e_rkv hal_h264e_vpu mpp_base) +set_target_properties(hal_h264e PROPERTIES FOLDER "mpp/hal") + +add_subdirectory(test) diff --git a/mpp/hal/rkenc/h264e/hal_h264e_api.c b/mpp/hal/common/h264/hal_h264e_api.c similarity index 71% rename from mpp/hal/rkenc/h264e/hal_h264e_api.c rename to mpp/hal/common/h264/hal_h264e_api.c index a1a04ec5..b7fdecad 100644 --- a/mpp/hal/rkenc/h264e/hal_h264e_api.c +++ b/mpp/hal/common/h264/hal_h264e_api.c @@ -27,7 +27,7 @@ #include "mpp_hal.h" #include "mpp_env.h" #include "hal_h264e_api.h" -#include "hal_h264e.h" +#include "hal_h264e_com.h" #include "hal_h264e_vpu.h" #include "hal_h264e_rkv.h" @@ -37,6 +37,11 @@ MPP_RET hal_h264e_init(void *hal, MppHalCfg *cfg) { h264e_hal_context *ctx = (h264e_hal_context *)hal; MppHalApi *api = &ctx->api; + MppEncCodecCfg *codec = &cfg->cfg->codec; + MppEncH264Cfg *h264 = &codec->h264; + MppEncH264VuiCfg *vui = &h264->vui; + MppEncH264RefCfg *ref = &h264->ref; + H264eHwCfg *hw_cfg = &ctx->hw_cfg; mpp_env_get_u32("h264e_hal_debug", &h264e_hal_log_mode, 0x00000001); if (!access("/dev/rkvenc", F_OK)) @@ -54,6 +59,7 @@ MPP_RET hal_h264e_init(void *hal, MppHalCfg *cfg) api->reset = hal_h264e_vpu_reset; api->flush = hal_h264e_vpu_flush; api->control = hal_h264e_vpu_control; + hw_cfg->hw_type = H264E_VPU; break; case HAL_RKVENC: api->init = hal_h264e_rkv_init; @@ -64,12 +70,58 @@ MPP_RET hal_h264e_init(void *hal, MppHalCfg *cfg) api->reset = hal_h264e_rkv_reset; api->flush = hal_h264e_rkv_flush; api->control = hal_h264e_rkv_control; + hw_cfg->hw_type = H264E_RKV; break; default: mpp_err("invalid device_id: %d", cfg->device_id); return MPP_NOK; } + /* + * default codec: + * High Profile + * frame mode + * all flag enabled + */ + codec->change = 0; + codec->coding = MPP_VIDEO_CodingAVC; + h264->profile = 100; + h264->level = 31; + h264->entropy_coding_mode = 1; + h264->cabac_init_idc = 0; + h264->transform8x8_mode = 1; + h264->constrained_intra_pred_mode = 0; + h264->chroma_cb_qp_offset = 0; + h264->chroma_cr_qp_offset = 0; + h264->deblock_disable = 0; + h264->deblock_offset_alpha = 0; + h264->deblock_offset_beta = 0; + h264->use_longterm = 0; + h264->qp_init = 26; + h264->qp_max = 48; + h264->qp_min = 16; + h264->qp_max_step = 8; + h264->intra_refresh_mode = 0; + h264->intra_refresh_arg = 0; + h264->slice_mode = 0; + h264->slice_arg = 0; + h264->vui.change = 0; + h264->sei.change = 0; + + vui->b_vui = 1; + + ref->i_frame_reference = H264E_NUM_REFS; + ref->i_dpb_size = H264E_NUM_REFS; + ref->i_ref_pos = 1; + ref->i_long_term_en = H264E_LONGTERM_REF_EN; + ref->hw_longterm_mode = 0; + ref->i_long_term_internal = 0; + ref->i_frame_packing = -1; + + + ctx->cfg = cfg->cfg; + ctx->set = cfg->set; + return api->init(hal, cfg); } diff --git a/mpp/hal/common/h264/hal_h264e_com.c b/mpp/hal/common/h264/hal_h264e_com.c new file mode 100644 index 00000000..c44db7d6 --- /dev/null +++ b/mpp/hal/common/h264/hal_h264e_com.c @@ -0,0 +1,738 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * 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. + */ + +#define MODULE_TAG "hal_h264e_com" + +#include +#include + +#include "vpu.h" +#include "mpp_common.h" +#include "mpp_mem.h" + +#include "hal_h264e_com.h" + +static const RK_S32 h264e_rkv_csp_idx_map[H264E_RKV_CSP_BUTT] = { + H264E_CSP2_BGRA, H264E_CSP2_BGR, H264E_CSP2_RGB, + H264E_CSP2_NONE, H264E_CSP2_NV16, H264E_CSP2_I422, + H264E_CSP2_NV12, H264E_CSP2_I420, H264E_CSP2_NONE, + H264E_CSP2_NONE +}; + +static const RK_S32 h264e_vpu_csp_idx_map[H264E_VPU_CSP_BUTT] = { + H264E_CSP2_I420, H264E_CSP2_NV12, H264E_CSP2_NONE, + H264E_CSP2_NONE, H264E_CSP2_RGB, H264E_CSP2_BGR, + H264E_CSP2_RGB, H264E_CSP2_BGR, H264E_CSP2_RGB, + H264E_CSP2_BGR, H264E_CSP2_RGB, H264E_CSP2_BGR, + H264E_CSP2_RGB, H264E_CSP2_BGR, +}; + +static const RK_U8 h264e_ue_size_tab[256] = { + 1, 1, 3, 3, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +}; + +/* default quant matrices */ +static const RK_U8 h264e_cqm_jvt4i[16] = { + 6, 13, 20, 28, + 13, 20, 28, 32, + 20, 28, 32, 37, + 28, 32, 37, 42 + +}; +static const RK_U8 h264e_cqm_jvt4p[16] = { + 10, 14, 20, 24, + 14, 20, 24, 27, + 20, 24, 27, 30, + 24, 27, 30, 34 + +}; +static const RK_U8 h264e_cqm_jvt8i[64] = { + 6, 10, 13, 16, 18, 23, 25, 27, + 10, 11, 16, 18, 23, 25, 27, 29, + 13, 16, 18, 23, 25, 27, 29, 31, + 16, 18, 23, 25, 27, 29, 31, 33, + 18, 23, 25, 27, 29, 31, 33, 36, + 23, 25, 27, 29, 31, 33, 36, 38, + 25, 27, 29, 31, 33, 36, 38, 40, + 27, 29, 31, 33, 36, 38, 40, 42 + +}; +static const RK_U8 h264e_cqm_jvt8p[64] = { + 9, 13, 15, 17, 19, 21, 22, 24, + 13, 13, 17, 19, 21, 22, 24, 25, + 15, 17, 19, 21, 22, 24, 25, 27, + 17, 19, 21, 22, 24, 25, 27, 28, + 19, 21, 22, 24, 25, 27, 28, 30, + 21, 22, 24, 25, 27, 28, 30, 32, + 22, 24, 25, 27, 28, 30, 32, 33, + 24, 25, 27, 28, 30, 32, 33, 35 + +}; + +static const RK_U8 h264e_cqm_flat16[64] = { + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16 + +}; + +const RK_U8 * const h264e_cqm_jvt[8] = { + h264e_cqm_jvt4i, h264e_cqm_jvt4p, + h264e_cqm_jvt4i, h264e_cqm_jvt4p, + h264e_cqm_jvt8i, h264e_cqm_jvt8p, + h264e_cqm_jvt8i, h264e_cqm_jvt8p + +}; + +/* zigzags are transposed with respect to the tables in the standard */ +const RK_U8 h264e_zigzag_scan4[2][16] = { + { + // frame + 0, 4, 1, 2, 5, 8, 12, 9, 6, 3, 7, 10, 13, 14, 11, 15 + }, + { + // field + 0, 1, 4, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 + } + +}; +const RK_U8 h264e_zigzag_scan8[2][64] = { + { + 0, 8, 1, 2, 9, 16, 24, 17, 10, 3, 4, 11, 18, 25, 32, 40, + 33, 26, 19, 12, 5, 6, 13, 20, 27, 34, 41, 48, 56, 49, 42, 35, + 28, 21, 14, 7, 15, 22, 29, 36, 43, 50, 57, 58, 51, 44, 37, 30, + 23, 31, 38, 45, 52, 59, 60, 53, 46, 39, 47, 54, 61, 62, 55, 63 + + }, + { + 0, 1, 2, 8, 9, 3, 4, 10, 16, 11, 5, 6, 7, 12, 17, 24, + 18, 13, 14, 15, 19, 25, 32, 26, 20, 21, 22, 23, 27, 33, 40, 34, + 28, 29, 30, 31, 35, 41, 48, 42, 36, 37, 38, 39, 43, 49, 50, 44, + 45, 46, 47, 51, 56, 57, 52, 53, 54, 55, 58, 59, 60, 61, 62, 63 + + } + +}; + +void hal_h264e_rkv_set_format(H264eHwCfg *hw_cfg, MppEncPrepCfg *prep_cfg) +{ + MppFrameFormat format = (MppFrameFormat)prep_cfg->format; + switch (format) { + case MPP_FMT_YUV420P: { + hw_cfg->input_format = (RK_U32)H264E_RKV_CSP_YUV420P; + hw_cfg->uv_rb_swap = 0; + hw_cfg->alpha_swap = 0; + break; + } + case MPP_FMT_YUV420SP: { + hw_cfg->input_format = (RK_U32)H264E_RKV_CSP_YUV420SP; + hw_cfg->uv_rb_swap = 0; + hw_cfg->alpha_swap = 0; + break; + } + case MPP_FMT_YUV420SP_10BIT: { + hw_cfg->input_format = (RK_U32)H264E_RKV_CSP_NONE; + hw_cfg->uv_rb_swap = 0; + hw_cfg->alpha_swap = 0; + break; + } + case MPP_FMT_YUV420SP_VU: { //TODO: to be confirmed + hw_cfg->input_format = (RK_U32)H264E_RKV_CSP_YUV420SP; + hw_cfg->uv_rb_swap = 1; + hw_cfg->alpha_swap = 0; + break; + } + case MPP_FMT_YUV422P: { + hw_cfg->input_format = (RK_U32)H264E_RKV_CSP_YUV422P; + hw_cfg->uv_rb_swap = 0; + hw_cfg->alpha_swap = 0; + break; + } + case MPP_FMT_YUV422SP: { + hw_cfg->input_format = (RK_U32)H264E_RKV_CSP_YUV422SP; + hw_cfg->uv_rb_swap = 0; + hw_cfg->alpha_swap = 0; + break; + } + case MPP_FMT_YUV422SP_10BIT: { + hw_cfg->input_format = (RK_U32)H264E_RKV_CSP_NONE; + hw_cfg->uv_rb_swap = 0; + hw_cfg->alpha_swap = 0; + break; + } + case MPP_FMT_YUV422SP_VU: { + hw_cfg->input_format = (RK_U32)H264E_RKV_CSP_YUV422SP; + hw_cfg->uv_rb_swap = 1; + hw_cfg->alpha_swap = 0; + break; + } + case MPP_FMT_YUV422_YUYV: { + hw_cfg->input_format = (RK_U32)H264E_RKV_CSP_YUYV422; + hw_cfg->uv_rb_swap = 0; + hw_cfg->alpha_swap = 0; + break; + } + case MPP_FMT_YUV422_UYVY: { + hw_cfg->input_format = (RK_U32)H264E_RKV_CSP_UYVY422; + hw_cfg->uv_rb_swap = 0; + hw_cfg->alpha_swap = 0; + break; + } + case MPP_FMT_RGB565: { + hw_cfg->input_format = (RK_U32)H264E_RKV_CSP_BGR565; + hw_cfg->uv_rb_swap = 1; + hw_cfg->alpha_swap = 0; + break; + } + case MPP_FMT_BGR565: { + hw_cfg->input_format = (RK_U32)H264E_RKV_CSP_BGR565; + hw_cfg->uv_rb_swap = 0; + hw_cfg->alpha_swap = 0; + break; + } + case MPP_FMT_RGB555: { + hw_cfg->input_format = (RK_U32)H264E_RKV_CSP_NONE; + hw_cfg->uv_rb_swap = 0; + hw_cfg->alpha_swap = 0; + break; + } + case MPP_FMT_BGR555: { + hw_cfg->input_format = (RK_U32)H264E_RKV_CSP_NONE; + hw_cfg->uv_rb_swap = 0; + hw_cfg->alpha_swap = 0; + break; + } + case MPP_FMT_RGB444: { + hw_cfg->input_format = (RK_U32)H264E_RKV_CSP_NONE; + hw_cfg->uv_rb_swap = 0; + hw_cfg->alpha_swap = 0; + break; + } + case MPP_FMT_BGR444: { + hw_cfg->input_format = (RK_U32)H264E_RKV_CSP_NONE; + hw_cfg->uv_rb_swap = 0; + hw_cfg->alpha_swap = 0; + break; + } + case MPP_FMT_RGB888: { + hw_cfg->input_format = (RK_U32)H264E_RKV_CSP_BGR888; + hw_cfg->uv_rb_swap = 1; + hw_cfg->alpha_swap = 0; + break; + } + case MPP_FMT_BGR888: { + hw_cfg->input_format = (RK_U32)H264E_RKV_CSP_BGR888; + hw_cfg->uv_rb_swap = 0; + hw_cfg->alpha_swap = 0; + break; + } + case MPP_FMT_RGB101010: { + hw_cfg->input_format = (RK_U32)H264E_RKV_CSP_NONE; + hw_cfg->uv_rb_swap = 0; + hw_cfg->alpha_swap = 0; + break; + } + case MPP_FMT_BGR101010: { + hw_cfg->input_format = (RK_U32)H264E_RKV_CSP_NONE; + hw_cfg->uv_rb_swap = 0; + hw_cfg->alpha_swap = 0; + break; + } + case MPP_FMT_ARGB8888: { + hw_cfg->input_format = (RK_U32)H264E_RKV_CSP_BGRA8888; + hw_cfg->uv_rb_swap = 1; + hw_cfg->alpha_swap = 1; + break; + } + case MPP_FMT_ABGR8888: { + hw_cfg->input_format = (RK_U32)H264E_RKV_CSP_BGRA8888; + hw_cfg->uv_rb_swap = 0; + hw_cfg->alpha_swap = 1; + break; + } + default: { + h264e_hal_log_err("unvalid src color space: %d", format); + hw_cfg->input_format = (RK_U32)H264E_RKV_CSP_NONE; + hw_cfg->uv_rb_swap = 0; + hw_cfg->alpha_swap = 0; + } + } +} + + +void hal_h264e_vpu_set_format(H264eHwCfg *hw_cfg, MppEncPrepCfg *prep_cfg) +{ + MppFrameFormat format = (MppFrameFormat)prep_cfg->format; + hw_cfg->input_format = 0; + hw_cfg->r_mask_msb = 0; + hw_cfg->g_mask_msb = 0; + hw_cfg->b_mask_msb = 0; + + switch (format) { + case MPP_FMT_YUV420P: { + hw_cfg->input_format = H264E_VPU_CSP_YUV420P; + break; + } + case MPP_FMT_YUV420SP: { + hw_cfg->input_format = H264E_VPU_CSP_YUV420SP; + break; + } + case MPP_FMT_YUV420SP_10BIT: { + hw_cfg->input_format = H264E_VPU_CSP_NONE; + break; + } + case MPP_FMT_YUV420SP_VU: { //TODO: to be confirmed + hw_cfg->input_format = H264E_VPU_CSP_NONE; + break; + } + case MPP_FMT_YUV422P: { + hw_cfg->input_format = H264E_VPU_CSP_NONE; + break; + } + case MPP_FMT_YUV422SP: { + hw_cfg->input_format = H264E_VPU_CSP_NONE; + break; + } + case MPP_FMT_YUV422SP_10BIT: { + hw_cfg->input_format = H264E_VPU_CSP_NONE; + break; + } + case MPP_FMT_YUV422SP_VU: { + hw_cfg->input_format = H264E_VPU_CSP_NONE; + break; + } + case MPP_FMT_YUV422_YUYV: { + hw_cfg->input_format = H264E_VPU_CSP_YUYV422; + break; + } + case MPP_FMT_YUV422_UYVY: { + hw_cfg->input_format = H264E_VPU_CSP_UYVY422; + break; + } + case MPP_FMT_RGB565: { + hw_cfg->input_format = H264E_VPU_CSP_RGB565; + hw_cfg->r_mask_msb = 15; + hw_cfg->g_mask_msb = 10; + hw_cfg->b_mask_msb = 4; + break; + } + case MPP_FMT_BGR565: { + hw_cfg->input_format = H264E_VPU_CSP_RGB565; + hw_cfg->r_mask_msb = 4; + hw_cfg->g_mask_msb = 10; + hw_cfg->b_mask_msb = 15; + break; + } + case MPP_FMT_RGB555: { + hw_cfg->input_format = H264E_VPU_CSP_RGB555; + hw_cfg->r_mask_msb = 14; + hw_cfg->g_mask_msb = 9; + hw_cfg->b_mask_msb = 4; + break; + } + case MPP_FMT_BGR555: { + hw_cfg->input_format = H264E_VPU_CSP_RGB555; + hw_cfg->r_mask_msb = 14; + hw_cfg->g_mask_msb = 9; + hw_cfg->b_mask_msb = 4; + break; + } + case MPP_FMT_RGB444: { + hw_cfg->input_format = H264E_VPU_CSP_RGB444; + hw_cfg->r_mask_msb = 11; + hw_cfg->g_mask_msb = 7; + hw_cfg->b_mask_msb = 3; + break; + } + case MPP_FMT_BGR444: { + hw_cfg->input_format = H264E_VPU_CSP_RGB444; + hw_cfg->r_mask_msb = 11; + hw_cfg->g_mask_msb = 7; + hw_cfg->b_mask_msb = 3; + break; + } + case MPP_FMT_RGB888: { + hw_cfg->input_format = H264E_VPU_CSP_RGB888; + hw_cfg->r_mask_msb = 23; + hw_cfg->g_mask_msb = 15; + hw_cfg->b_mask_msb = 7; + break; + } + case MPP_FMT_BGR888: { + hw_cfg->input_format = H264E_VPU_CSP_RGB888; + hw_cfg->r_mask_msb = 23; + hw_cfg->g_mask_msb = 15; + hw_cfg->b_mask_msb = 7; + break; + } + case MPP_FMT_RGB101010: { + hw_cfg->input_format = H264E_VPU_CSP_RGB101010; + hw_cfg->r_mask_msb = 29; + hw_cfg->g_mask_msb = 19; + hw_cfg->b_mask_msb = 9; + break; + } + case MPP_FMT_BGR101010: { + hw_cfg->input_format = H264E_VPU_CSP_RGB101010; + hw_cfg->r_mask_msb = 29; + hw_cfg->g_mask_msb = 19; + hw_cfg->b_mask_msb = 9; + break; + } + case MPP_FMT_ARGB8888: { + hw_cfg->input_format = H264E_VPU_CSP_NONE; + break; + } + case MPP_FMT_ABGR8888: { + hw_cfg->input_format = H264E_VPU_CSP_NONE; + break; + } + default: { + mpp_err_f("invalid color space: %d", format); + hw_cfg->input_format = H264E_VPU_CSP_NONE; + } + } +} + + +static RK_S32 hal_h264e_set_format(H264eHwCfg *hw_cfg, MppEncPrepCfg *prep_cfg) +{ + RK_S32 csp = 0; + + if (hw_cfg->hw_type == H264E_RKV) { + hal_h264e_rkv_set_format(hw_cfg, prep_cfg); + csp = h264e_rkv_csp_idx_map[hw_cfg->input_format] & H264E_CSP2_MASK; + } else { + hal_h264e_vpu_set_format(hw_cfg, prep_cfg); + csp = h264e_vpu_csp_idx_map[hw_cfg->input_format] & H264E_CSP2_MASK; + } + + return csp; +} + +static void hal_h264e_set_vui(h264e_hal_vui_param *vui) +{ + vui->i_sar_height = 0; + vui->i_sar_width = 0; + vui->i_overscan = 0; + vui->i_vidformat = 5; + vui->b_fullrange = 0; + vui->i_colorprim = 2; + vui->i_transfer = 2; + vui->i_colmatrix = -1; + vui->i_chroma_loc = 0; +} + +static void hal_h264e_set_ref(h264e_hal_ref_param *ref) +{ + ref->i_frame_reference = H264E_NUM_REFS; + ref->i_dpb_size = H264E_NUM_REFS; + ref->i_ref_pos = 1; + ref->i_long_term_en = H264E_LONGTERM_REF_EN; + ref->hw_longterm_mode = 0; + ref->i_long_term_internal = 0; + ref->i_frame_packing = -1; +} + +void hal_h264e_set_param(h264e_hal_param *p, RK_S32 hw_type) +{ + h264e_hal_vui_param *vui = &p->vui; + h264e_hal_ref_param *ref = &p->ref; + + p->hw_type = hw_type; + p->constrained_intra = 0; + hal_h264e_set_vui(vui); + hal_h264e_set_ref(ref); +} + +MPP_RET hal_h264e_set_sps(h264e_hal_context *ctx, h264e_hal_sps *sps) +{ + H264eHwCfg *hw_cfg = &ctx->hw_cfg; + MppEncH264Cfg *codec = &ctx->cfg->codec.h264; + MppEncPrepCfg *prep = &ctx->cfg->prep; + MppEncRcCfg *rc = &ctx->cfg->rc; + MppEncH264VuiCfg *vui = &codec->vui; + MppEncH264RefCfg *ref = &codec->ref; + RK_S32 max_frame_num = 0; + + /* default settings */ + RK_S32 i_bframe_pyramid = 0; + RK_S32 i_bframe = 0; + RK_S32 b_intra_refresh = 0; + RK_S32 Log2MaxFrameNum = 16; + RK_S32 Sw_log2_max_pic_order_cnt_lsb_minus4 = 12; + RK_S32 i_overscan = 0; + RK_S32 i_vidformat = 5; + RK_S32 b_fullrange = 0; + RK_S32 i_colorprim = 2; + RK_S32 i_transfer = 2; + RK_S32 i_colmatrix = -1; + RK_S32 i_chroma_loc = 0; + RK_S32 b_interlaced = 0; + RK_S32 b_fake_interlaced = 0; + RK_S32 crop_rect_left = 0; + RK_S32 crop_rect_right = 0; + RK_S32 crop_rect_top = 0; + RK_S32 crop_rect_bottom = 0; + RK_S32 i_timebase_num = 1; + RK_S32 i_timebase_den = rc->fps_out_num / rc->fps_out_denorm; + RK_S32 b_vfr_input = 0; + RK_S32 i_nal_hrd = 0; + RK_S32 b_pic_struct = 0; + RK_S32 analyse_mv_range = 128; //TODO: relative to level_idc, transplant x264_validate_levels. + RK_S32 csp = 0; + RK_S32 i_dpb_size = ref->i_dpb_size; + RK_S32 i_frame_reference = ref->i_frame_reference; + + csp = hal_h264e_set_format(hw_cfg, prep); + sps->i_id = 0; + sps->i_mb_width = ( prep->width + 15 ) / 16; + sps->i_mb_height = ( prep->height + 15 ) / 16; + sps->i_chroma_format_idc = csp >= H264E_CSP2_I444 ? H264E_CHROMA_444 : + csp >= H264E_CSP2_I422 ? H264E_CHROMA_422 : H264E_CHROMA_420; + + sps->b_qpprime_y_zero_transform_bypass = 0; //param->rc.i_rc_method == X264_RC_CQP && param->rc.i_qp_constant == 0; + sps->i_profile_idc = codec->profile; + + sps->b_constraint_set0 = 0; //sps->i_profile_idc == H264_PROFILE_BASELINE; + /* x264 doesn't support the features that are in Baseline and not in Main, + * namely arbitrary_slice_order and slice_groups. */ + sps->b_constraint_set1 = 0; //sps->i_profile_idc <= H264_PROFILE_MAIN; + /* Never set constraint_set2, it is not necessary and not used in real world. */ + sps->b_constraint_set2 = 0; + sps->b_constraint_set3 = 0; + + sps->i_level_idc = codec->level; + if ( codec->level == 9 && ( sps->i_profile_idc == H264_PROFILE_BASELINE || sps->i_profile_idc == H264_PROFILE_MAIN ) ) { + mpp_log_f("warnings: for profile %d, change level from 9(that is 1b) to 11", sps->i_profile_idc); + sps->i_level_idc = 11; + } + + sps->vui.i_num_reorder_frames = i_bframe_pyramid ? 2 : i_bframe ? 1 : 0; + /* extra slot with pyramid so that we don't have to override the + * order of forgetting old pictures */ + sps->vui.i_max_dec_frame_buffering = + sps->i_num_ref_frames = H264E_HAL_MIN(H264E_REF_MAX, H264E_HAL_MAX4(i_frame_reference, 1 + sps->vui.i_num_reorder_frames, + i_bframe_pyramid ? 4 : 1, i_dpb_size)); //TODO: multi refs + sps->i_num_ref_frames -= i_bframe_pyramid == H264E_B_PYRAMID_STRICT; //TODO: multi refs + sps->keyframe_max_interval = rc->gop; + if (sps->keyframe_max_interval == 1) { + sps->i_num_ref_frames = 0; + sps->vui.i_max_dec_frame_buffering = 0; + } + + /* number of refs + current frame */ + max_frame_num = sps->vui.i_max_dec_frame_buffering * (!!i_bframe_pyramid + 1) + 1; + /* Intra refresh cannot write a recovery time greater than max frame num-1 */ + if (b_intra_refresh ) { + RK_S32 time_to_recovery = H264E_HAL_MIN( sps->i_mb_width - 1, sps->keyframe_max_interval) + i_bframe - 1; + max_frame_num = H264E_HAL_MAX( max_frame_num, time_to_recovery + 1 ); + } + + sps->i_log2_max_frame_num = Log2MaxFrameNum;//fix by gsl org 16, at least 4 + while ( (1 << sps->i_log2_max_frame_num) <= max_frame_num ) + sps->i_log2_max_frame_num++; + + if (hw_cfg->hw_type == H264E_RKV) + sps->i_poc_type = 0; + else // VPU + sps->i_poc_type = 2; + + if ( sps->i_poc_type == 0 ) { + RK_S32 max_delta_poc = (i_bframe + 2) * (!!i_bframe_pyramid + 1) * 2; + sps->i_log2_max_poc_lsb = Sw_log2_max_pic_order_cnt_lsb_minus4 + 4; + while ( (1 << sps->i_log2_max_poc_lsb) <= max_delta_poc * 2 ) + sps->i_log2_max_poc_lsb++; + + } + + sps->vui.b_vui = 1; + + sps->b_gaps_in_frame_num_value_allowed = 0; + sps->b_frame_mbs_only = !(b_interlaced || b_fake_interlaced); + if ( !sps->b_frame_mbs_only ) + sps->i_mb_height = ( sps->i_mb_height + 1 ) & ~1; + sps->b_mb_adaptive_frame_field = b_interlaced; + sps->b_direct8x8_inference = 1; + + sps->crop.i_left = crop_rect_left; + sps->crop.i_top = crop_rect_top; + sps->crop.i_right = crop_rect_right + sps->i_mb_width * 16 - prep->width; + sps->crop.i_bottom = (crop_rect_bottom + sps->i_mb_height * 16 - prep->height) >> !sps->b_frame_mbs_only; + sps->b_crop = sps->crop.i_left || sps->crop.i_top || + sps->crop.i_right || sps->crop.i_bottom; + + sps->vui.b_aspect_ratio_info_present = 0; + if (vui->i_sar_width > 0 && vui->i_sar_height > 0 ) { + sps->vui.b_aspect_ratio_info_present = 1; + sps->vui.i_sar_width = vui->i_sar_width; + sps->vui.i_sar_height = vui->i_sar_height; + } + + sps->vui.b_overscan_info_present = i_overscan > 0 && i_overscan <= 2; + if ( sps->vui.b_overscan_info_present ) + sps->vui.b_overscan_info = ( i_overscan == 2 ? 1 : 0 ); + + sps->vui.b_signal_type_present = 0; + sps->vui.i_vidformat = ( i_vidformat >= 0 && i_vidformat <= 5 ? i_vidformat : 5 ); + sps->vui.b_fullrange = ( b_fullrange >= 0 && b_fullrange <= 1 ? b_fullrange : + ( csp >= H264E_CSP2_BGR ? 1 : 0 ) ); + sps->vui.b_color_description_present = 0; + + sps->vui.i_colorprim = ( i_colorprim >= 0 && i_colorprim <= 9 ? i_colorprim : 2 ); + sps->vui.i_transfer = ( i_transfer >= 0 && i_transfer <= 15 ? i_transfer : 2 ); + sps->vui.i_colmatrix = ( i_colmatrix >= 0 && i_colmatrix <= 10 ? i_colmatrix : + ( csp >= H264E_CSP2_BGR ? 0 : 2 ) ); + if ( sps->vui.i_colorprim != 2 || + sps->vui.i_transfer != 2 || + sps->vui.i_colmatrix != 2 ) { + sps->vui.b_color_description_present = 1; + } + + if ( sps->vui.i_vidformat != 5 || + sps->vui.b_fullrange || + sps->vui.b_color_description_present ) { + sps->vui.b_signal_type_present = 1; + } + + /* FIXME: not sufficient for interlaced video */ + sps->vui.b_chroma_loc_info_present = i_chroma_loc > 0 && i_chroma_loc <= 5 && + sps->i_chroma_format_idc == H264E_CHROMA_420; + if ( sps->vui.b_chroma_loc_info_present ) { + sps->vui.i_chroma_loc_top = i_chroma_loc; + sps->vui.i_chroma_loc_bottom = i_chroma_loc; + + } + + sps->vui.b_timing_info_present = i_timebase_num > 0 && i_timebase_den > 0; + + if ( sps->vui.b_timing_info_present ) { + sps->vui.i_num_units_in_tick = i_timebase_num; + sps->vui.i_time_scale = i_timebase_den * 2; + sps->vui.b_fixed_frame_rate = !b_vfr_input; + + } + + sps->vui.b_vcl_hrd_parameters_present = 0; // we don't support VCL HRD + sps->vui.b_nal_hrd_parameters_present = !!i_nal_hrd; + sps->vui.b_pic_struct_present = b_pic_struct; + + // NOTE: HRD related parts of the SPS are initialised in x264_ratecontrol_init_reconfigurable + sps->vui.b_bitstream_restriction = sps->keyframe_max_interval > 1; + if ( sps->vui.b_bitstream_restriction ) { + sps->vui.b_motion_vectors_over_pic_boundaries = 1; + sps->vui.i_max_bytes_per_pic_denom = 0; + sps->vui.i_max_bits_per_mb_denom = 0; + sps->vui.i_log2_max_mv_length_horizontal = + sps->vui.i_log2_max_mv_length_vertical = (RK_S32)log2f((float)H264E_HAL_MAX( 1, analyse_mv_range * 4 - 1 ) ) + 1; + } + + return MPP_OK; +} +MPP_RET hal_h264e_set_pps(h264e_hal_context *ctx, h264e_hal_pps *pps, h264e_hal_sps *sps) +{ + MppEncH264Cfg *cfg = &ctx->cfg->codec.h264; + RK_S32 k = 0; + RK_S32 i_avcintra_class = 0; + RK_S32 b_interlaced = 0; + RK_S32 analyse_weighted_pred = 0; + RK_S32 analyse_b_weighted_bipred = 0; + RK_S32 pps_init_qp = -1; //TODO: merge with syn + RK_S32 Sw_deblock_filter_ctrl_present_flag = 1; + RK_S32 b_cqm_preset = 0; + + pps->i_id = 0; + pps->i_sps_id = sps->i_id; + pps->b_cabac = cfg->entropy_coding_mode; + + pps->b_pic_order = !i_avcintra_class && b_interlaced; + pps->i_num_slice_groups = 1; + + pps->i_num_ref_idx_l0_default_active = 1; + pps->i_num_ref_idx_l1_default_active = 1; + + pps->b_weighted_pred = analyse_weighted_pred > 0; + pps->i_weighted_bipred_idc = analyse_b_weighted_bipred ? 2 : 0; + + pps->i_pic_init_qp = cfg->qp_init; + if (pps_init_qp >= 0 && pps_init_qp <= 51) { + pps->i_pic_init_qp = pps_init_qp; + } + pps->i_pic_init_qs = pps->i_pic_init_qp; // only for SP/SI slices + + pps->b_transform_8x8_mode = cfg->transform8x8_mode; + pps->i_chroma_qp_index_offset = cfg->chroma_cb_qp_offset; + pps->i_second_chroma_qp_index_offset = cfg->chroma_cr_qp_offset; + pps->b_deblocking_filter_control = Sw_deblock_filter_ctrl_present_flag; + pps->b_constrained_intra_pred = cfg->constrained_intra_pred_mode; + pps->b_redundant_pic_cnt = 0; + + if (sps->i_profile_idc < H264_PROFILE_HIGH) { + if (pps->b_transform_8x8_mode) { + pps->b_transform_8x8_mode = 0; + mpp_log_f("wanrning: for profile %d b_transform_8x8_mode should be 0", + sps->i_profile_idc); + } + if (pps->i_second_chroma_qp_index_offset) { + pps->i_second_chroma_qp_index_offset = 0; + mpp_log_f("wanrning: for profile %d i_second_chroma_qp_index_offset should be 0", + sps->i_profile_idc); + } + } + + pps->b_cqm_preset = b_cqm_preset; + + switch ( pps->b_cqm_preset ) { + case H264E_CQM_FLAT: + for (k = 0; k < 8; k++ ) + pps->scaling_list[k] = h264e_cqm_flat16; + break; + case H264E_CQM_JVT: + for (k = 0; k < 8; k++ ) + pps->scaling_list[k] = h264e_cqm_jvt[k]; + break; + case H264E_CQM_CUSTOM: + /* match the transposed DCT & zigzag */ + h264e_hal_log_err("CQM_CUSTOM mode is not supported now"); + return MPP_NOK; + default: + h264e_hal_log_err("invalid cqm_preset mode"); + return MPP_NOK; + } + + return MPP_OK; +} + diff --git a/mpp/hal/rkenc/h264e/hal_h264e.h b/mpp/hal/common/h264/hal_h264e_com.h similarity index 63% rename from mpp/hal/rkenc/h264e/hal_h264e.h rename to mpp/hal/common/h264/hal_h264e_com.h index fc9d5405..31e1c010 100644 --- a/mpp/hal/rkenc/h264e/hal_h264e.h +++ b/mpp/hal/common/h264/hal_h264e_com.h @@ -22,6 +22,7 @@ #include "mpp_packet.h" #include "mpp_log.h" #include "mpp_hal.h" +#include "mpp_rc.h" #include "h264e_syntax.h" @@ -36,7 +37,6 @@ extern RK_U32 h264e_hal_log_mode; #define H264E_HAL_LOG_DPB 0x00001000 #define H264E_HAL_LOG_HEADER 0x00002000 #define H264E_HAL_LOG_SEI 0x00004000 -#define H264E_HAL_LOG_PP 0x00008000 #define H264E_HAL_LOG_DETAIL 0x00010000 @@ -44,7 +44,6 @@ extern RK_U32 h264e_hal_log_mode; - #define H264E_HAL_MASK_2b (RK_U32)0x00000003 #define H264E_HAL_MASK_3b (RK_U32)0x00000007 #define H264E_HAL_MASK_4b (RK_U32)0x0000000F @@ -58,62 +57,56 @@ extern RK_U32 h264e_hal_log_mode; #define h264e_hal_debug_enter() \ do {\ if (h264e_hal_log_mode & H264E_HAL_LOG_FLOW)\ - { mpp_log("line(%d), func(%s), enter", __LINE__, __FUNCTION__); }\ + mpp_log("line(%d), func(%s), enter", __LINE__, __FUNCTION__);\ } while (0) #define h264e_hal_debug_leave() \ do {\ if (h264e_hal_log_mode & H264E_HAL_LOG_FLOW)\ - { mpp_log("line(%d), func(%s), leave", __LINE__, __FUNCTION__); }\ + mpp_log("line(%d), func(%s), leave", __LINE__, __FUNCTION__);\ } while (0) #define h264e_hal_log_err(fmt, ...) \ - do {\ - if (h264e_hal_log_mode & H264E_HAL_LOG_ERROR)\ - { mpp_err_f(fmt, ## __VA_ARGS__); }\ - } while (0) + do {\ + if (h264e_hal_log_mode & H264E_HAL_LOG_ERROR)\ + mpp_err_f(fmt, ## __VA_ARGS__);\ + } while (0) #define h264e_hal_log_detail(fmt, ...) \ - do {\ - if (h264e_hal_log_mode & H264E_HAL_LOG_DETAIL)\ - { mpp_log(fmt, ## __VA_ARGS__); }\ - } while (0) + do {\ + if (h264e_hal_log_mode & H264E_HAL_LOG_DETAIL)\ + mpp_log(fmt, ## __VA_ARGS__);\ + } while (0) #define h264e_hal_log_dpb(fmt, ...) \ - do {\ - if (h264e_hal_log_mode & H264E_HAL_LOG_DPB)\ - { mpp_log(fmt, ## __VA_ARGS__); }\ - } while (0) + do {\ + if (h264e_hal_log_mode & H264E_HAL_LOG_DPB)\ + mpp_log(fmt, ## __VA_ARGS__);\ + } while (0) #define h264e_hal_log_header(fmt, ...) \ - do {\ - if (h264e_hal_log_mode & H264E_HAL_LOG_HEADER)\ - { mpp_log(fmt, ## __VA_ARGS__); }\ - } while (0) + do {\ + if (h264e_hal_log_mode & H264E_HAL_LOG_HEADER)\ + mpp_log(fmt, ## __VA_ARGS__);\ + } while (0) #define h264e_hal_log_sei(fmt, ...) \ - do {\ - if (h264e_hal_log_mode & H264E_HAL_LOG_SEI)\ - { mpp_log(fmt, ## __VA_ARGS__); }\ - } while (0) + do {\ + if (h264e_hal_log_mode & H264E_HAL_LOG_SEI)\ + mpp_log(fmt, ## __VA_ARGS__);\ + } while (0) #define h264e_hal_log_simple(fmt, ...) \ - do {\ - if (h264e_hal_log_mode & H264E_HAL_LOG_SIMPLE)\ - { mpp_log(fmt, ## __VA_ARGS__); }\ - } while (0) + do {\ + if (h264e_hal_log_mode & H264E_HAL_LOG_SIMPLE)\ + mpp_log(fmt, ## __VA_ARGS__);\ + } while (0) #define h264e_hal_log_file(fmt, ...) \ - do {\ - if (h264e_hal_log_mode & H264E_HAL_LOG_FILE)\ - { mpp_log(fmt, ## __VA_ARGS__); }\ - } while (0) - -#define h264e_hal_log_pp(fmt, ...) \ - do {\ - if (h264e_hal_log_mode & H264E_HAL_LOG_PP)\ - { mpp_log(fmt, ## __VA_ARGS__); }\ - } while (0) + do {\ + if (h264e_hal_log_mode & H264E_HAL_LOG_FILE)\ + mpp_log(fmt, ## __VA_ARGS__);\ + } while (0) #define H264E_HAL_MIN(a,b) ( (a)<(b) ? (a) : (b) ) #define H264E_HAL_MAX(a,b) ( (a)>(b) ? (a) : (b) ) @@ -128,14 +121,14 @@ extern RK_U32 h264e_hal_log_mode; #define H264E_HAL_SET_REG(reg, addr, val) \ do { \ reg[(addr)>>2] = (RK_U32)(val); \ - if(h264e_hal_log_mode & 0/*H264E_HAL_LOG_INFO*/) \ + if (h264e_hal_log_mode & 0/*H264E_HAL_LOG_INFO*/) \ mpp_log("line(%d) set reg[%03d/%03x]: %08x", __LINE__, (addr)>>2, addr, val); \ } while (0) #define H264E_HAL_VALIDATE_GT(val, name, limit) \ do { \ - if((val)<=(limit)) { \ + if ((val)<=(limit)) { \ mpp_err("%s(%d) should > %d", name, val, limit); \ return MPP_NOK; \ } \ @@ -162,6 +155,101 @@ extern RK_U32 h264e_hal_log_mode; #define H264E_SEI_BUF_SIZE 1024 //unit in byte, may not be large enough in the future #define H264E_EXTRA_INFO_BUF_SIZE (H264E_SPSPPS_BUF_SIZE + H264E_SEI_BUF_SIZE) +#define H264E_NUM_REFS 1 +#define H264E_LONGTERM_REF_EN 0 +#define H264E_CQM_FLAT 0 +#define H264E_CQM_JVT 1 +#define H264E_CQM_CUSTOM 2 +#define H264E_B_PYRAMID_NONE 0 +#define H264E_B_PYRAMID_STRICT 1 +#define H264E_B_PYRAMID_NORMAL 2 + +#define H264E_CSP2_MASK 0x00ff /* */ +#define H264E_CSP2_NONE 0x0000 /* Invalid mode */ +#define H264E_CSP2_I420 0x0001 /* yuv 4:2:0 planar */ +#define H264E_CSP2_YV12 0x0002 /* yvu 4:2:0 planar */ +#define H264E_CSP2_NV12 0x0003 /* yuv 4:2:0, with one y plane and one packed u+v */ +#define H264E_CSP2_I422 0x0004 /* yuv 4:2:2 planar */ +#define H264E_CSP2_YV16 0x0005 /* yvu 4:2:2 planar */ +#define H264E_CSP2_NV16 0x0006 /* yuv 4:2:2, with one y plane and one packed u+v */ +#define H264E_CSP2_V210 0x0007 /* 10-bit yuv 4:2:2 packed in 32 */ +#define H264E_CSP2_I444 0x0008 /* yuv 4:4:4 planar */ +#define H264E_CSP2_YV24 0x0009 /* yvu 4:4:4 planar */ +#define H264E_CSP2_BGR 0x000a /* packed bgr 24bits */ +#define H264E_CSP2_BGRA 0x000b /* packed bgr 32bits */ +#define H264E_CSP2_RGB 0x000c /* packed rgb 24bits */ +#define H264E_CSP2_MAX 0x000d /* end of list */ +#define H264E_CSP2_VFLIP 0x1000 /* the csp is vertically flipped */ +#define H264E_CSP2_HIGH_DEPTH 0x2000 /* the csp has a depth of 16 bits per pixel component */ + +typedef enum h264e_rkv_csp_t { + H264E_RKV_CSP_BGRA8888, // 0 + H264E_RKV_CSP_BGR888, // 1 + H264E_RKV_CSP_BGR565, // 2 + H264E_RKV_CSP_NONE, // 3 + H264E_RKV_CSP_YUV422SP, // 4 + H264E_RKV_CSP_YUV422P, // 5 + H264E_RKV_CSP_YUV420SP, // 6 + H264E_RKV_CSP_YUV420P, // 7 + H264E_RKV_CSP_YUYV422, // 8 + H264E_RKV_CSP_UYVY422, // 9 + H264E_RKV_CSP_BUTT, // 10 +} h264e_hal_rkv_csp; + +typedef struct h264e_hal_rkv_csp_info_t { + RK_U32 fmt; + RK_U32 cswap; // U/V swap for YUV420SP/YUV422SP/YUYV422/UYUV422; R/B swap for BGRA88/RGB888/RGB565. + RK_U32 aswap; // 0: BGRA, 1:ABGR. +} h264e_hal_rkv_csp_info; + +/* transplant from vpu_api.h:EncInputPictureType */ +typedef enum { + H264E_VPU_CSP_YUV420P = 0, // YYYY... UUUU... VVVV + H264E_VPU_CSP_YUV420SP = 1, // YYYY... UVUVUV... + H264E_VPU_CSP_YUYV422 = 2, // YUYVYUYV... + H264E_VPU_CSP_UYVY422 = 3, // UYVYUYVY... + H264E_VPU_CSP_RGB565 = 4, // 16-bit RGB + H264E_VPU_CSP_BGR565 = 5, // 16-bit RGB + H264E_VPU_CSP_RGB555 = 6, // 15-bit RGB + H264E_VPU_CSP_BGR555 = 7, // 15-bit RGB + H264E_VPU_CSP_RGB444 = 8, // 12-bit RGB + H264E_VPU_CSP_BGR444 = 9, // 12-bit RGB + H264E_VPU_CSP_RGB888 = 10, // 24-bit RGB + H264E_VPU_CSP_BGR888 = 11, // 24-bit RGB + H264E_VPU_CSP_RGB101010 = 12, // 30-bit RGB + H264E_VPU_CSP_BGR101010 = 13, // 30-bit RGB + H264E_VPU_CSP_NONE, + H264E_VPU_CSP_BUTT, +} h264e_hal_vpu_csp; + +typedef struct h264e_hal_vpu_csp_info_t { + RK_U32 fmt; + RK_U32 r_mask_msb; + RK_U32 g_mask_msb; + RK_U32 b_mask_msb; +} h264e_hal_vpu_csp_info; + +typedef enum h264e_chroma_fmt_t { + H264E_CHROMA_400 = 0, + H264E_CHROMA_420 = 1, + H264E_CHROMA_422 = 2, + H264E_CHROMA_444 = 3, +} h264e_chroma_fmt; + +typedef enum h264e_cqm4_t { + H264E_CQM_4IY = 0, + H264E_CQM_4PY = 1, + H264E_CQM_4IC = 2, + H264E_CQM_4PC = 3 +} h264e_cqm4; + +typedef enum h264e_cqm8_t { + H264E_CQM_8IY = 0, + H264E_CQM_8PY = 1, + H264E_CQM_8IC = 2, + H264E_CQM_8PC = 3, +} h264e_cqm8; + typedef enum h264e_hal_slice_type_t { H264E_HAL_SLICE_TYPE_P = 0, H264E_HAL_SLICE_TYPE_B = 1, @@ -201,63 +289,7 @@ typedef struct h264e_hal_sps_t { RK_S32 i_bottom; } crop; - RK_S32 b_vui; - struct { - RK_S32 b_aspect_ratio_info_present; - RK_S32 i_sar_width; - RK_S32 i_sar_height; - - RK_S32 b_overscan_info_present; - RK_S32 b_overscan_info; - - RK_S32 b_signal_type_present; - RK_S32 i_vidformat; - RK_S32 b_fullrange; - RK_S32 b_color_description_present; - RK_S32 i_colorprim; - RK_S32 i_transfer; - RK_S32 i_colmatrix; - - RK_S32 b_chroma_loc_info_present; - RK_S32 i_chroma_loc_top; - RK_S32 i_chroma_loc_bottom; - - RK_S32 b_timing_info_present; - RK_U32 i_num_units_in_tick; - RK_U32 i_time_scale; - RK_S32 b_fixed_frame_rate; - - RK_S32 b_nal_hrd_parameters_present; - RK_S32 b_vcl_hrd_parameters_present; - - struct { - RK_S32 i_cpb_cnt; - RK_S32 i_bit_rate_scale; - RK_S32 i_cpb_size_scale; - RK_S32 i_bit_rate_value; - RK_S32 i_cpb_size_value; - RK_S32 i_bit_rate_unscaled; - RK_S32 i_cpb_size_unscaled; - RK_S32 b_cbr_hrd; - - RK_S32 i_initial_cpb_removal_delay_length; - RK_S32 i_cpb_removal_delay_length; - RK_S32 i_dpb_output_delay_length; - RK_S32 i_time_offset_length; - } hrd; - - RK_S32 b_pic_struct_present; - RK_S32 b_bitstream_restriction; - RK_S32 b_motion_vectors_over_pic_boundaries; - RK_S32 i_max_bytes_per_pic_denom; - RK_S32 i_max_bits_per_mb_denom; - RK_S32 i_log2_max_mv_length_horizontal; - RK_S32 i_log2_max_mv_length_vertical; - RK_S32 i_num_reorder_frames; - RK_S32 i_max_dec_frame_buffering; - - /* FIXME to complete */ - } vui; + MppEncH264VuiCfg vui; RK_S32 b_qpprime_y_zero_transform_bypass; RK_S32 i_chroma_format_idc; @@ -373,17 +405,16 @@ typedef struct h264e_hal_ref_param_t { typedef struct h264e_hal_param_t { + RK_S32 hw_type; // 0:rkv, 1:vpu RK_S32 constrained_intra; h264e_hal_vui_param vui; h264e_hal_ref_param ref; - } h264e_hal_param; typedef struct h264e_hal_context_t { MppHalApi api; - VPU_CLIENT_TYPE vpu_client; - RK_S32 vpu_socket; + RK_S32 vpu_fd; IOInterruptCB int_cb; h264e_feedback feedback; void *regs; @@ -407,7 +438,25 @@ typedef struct h264e_hal_context_t { RK_U32 osd_plt_type; //0:user define, 1:default MppEncOSDData osd_data; MppEncSeiMode sei_mode; - MppEncPrepCfg prep_cfg; + + MppEncCfgSet *cfg; + MppEncCfgSet *set; + RK_U32 idr_pic_id; + + RK_U32 buffer_ready; + H264eHwCfg hw_cfg; + MppLinReg *inter_qs; + MppLinReg *intra_qs; } h264e_hal_context; +MPP_RET hal_h264e_set_sps(h264e_hal_context *ctx, h264e_hal_sps *sps); +MPP_RET hal_h264e_set_pps(h264e_hal_context *ctx, h264e_hal_pps *pps, h264e_hal_sps *sps); +void hal_h264e_set_param(h264e_hal_param *p, RK_S32 hw_type); + +const RK_U8 * const h264e_cqm_jvt[8]; +const RK_U8 h264e_zigzag_scan4[2][16]; +const RK_U8 h264e_zigzag_scan8[2][64]; +void hal_h264e_rkv_set_format(H264eHwCfg *hw_cfg, MppEncPrepCfg *prep_cfg); +void hal_h264e_vpu_set_format(H264eHwCfg *hw_cfg, MppEncPrepCfg *prep_cfg); + #endif diff --git a/mpp/hal/rkenc/h264e/test/CMakeLists.txt b/mpp/hal/common/h264/test/CMakeLists.txt similarity index 100% rename from mpp/hal/rkenc/h264e/test/CMakeLists.txt rename to mpp/hal/common/h264/test/CMakeLists.txt diff --git a/mpp/hal/rkenc/h264e/test/h264e_hal_test.c b/mpp/hal/common/h264/test/h264e_hal_test.c similarity index 51% rename from mpp/hal/rkenc/h264e/test/h264e_hal_test.c rename to mpp/hal/common/h264/test/h264e_hal_test.c index 5f6e4573..b6ada974 100644 --- a/mpp/hal/rkenc/h264e/test/h264e_hal_test.c +++ b/mpp/hal/common/h264/test/h264e_hal_test.c @@ -32,7 +32,7 @@ #include "mpp_frame.h" #include "hal_h264e_api.h" -#include "hal_h264e.h" +#include "hal_h264e_com.h" #include "hal_h264e_vpu.h" #include "hal_h264e_rkv.h" @@ -353,10 +353,10 @@ static MPP_RET h264e_test_close_files() return MPP_OK; } -static MPP_RET get_rkv_h264e_yuv_in_frame(h264e_syntax *syn, MppBuffer *hw_buf) +static MPP_RET get_rkv_h264e_yuv_in_frame(H264eHwCfg *syn, MppBuffer *hw_buf) { RK_U32 read_ret = 0; - RK_U32 frame_luma_size = syn->pic_luma_width * syn->pic_luma_height; + RK_U32 frame_luma_size = syn->width * syn->height; RK_U32 frame_size = frame_luma_size * 3 / 2; RK_U8 *hw_buf_ptr = (RK_U8 *)mpp_buffer_get_ptr(hw_buf[g_frame_read_cnt % RKV_H264E_LINKTABLE_FRAME_NUM]);; mpp_assert(fp_h264e_yuv_in); @@ -379,10 +379,10 @@ static MPP_RET get_rkv_h264e_yuv_in_frame(h264e_syntax *syn, MppBuffer *hw_buf) return MPP_OK; } -static MPP_RET get_h264e_yuv_in_one_frame(RK_U8 *sw_buf, h264e_syntax *syn, MppBuffer hw_buf) +static MPP_RET get_h264e_yuv_in_one_frame(RK_U8 *sw_buf, H264eHwCfg *syn, MppBuffer hw_buf) { RK_U32 read_ret = 0; - RK_U32 frame_luma_size = syn->pic_luma_width * syn->pic_luma_height; + RK_U32 frame_luma_size = syn->width * syn->height; RK_U32 frame_size = frame_luma_size * 3 / 2; mpp_assert(fp_h264e_yuv_in); @@ -408,11 +408,11 @@ static MPP_RET get_h264e_yuv_in_one_frame(RK_U8 *sw_buf, h264e_syntax *syn, MppB return MPP_OK; } -static MPP_RET get_vpu_syntax_in(h264e_syntax *syn, MppBuffer hw_in_buf, MppBuffer hw_output_strm_buf, RK_U32 frame_luma_size) +static MPP_RET get_vpu_syntax_in(H264eHwCfg *syn, MppBuffer hw_in_buf, MppBuffer hw_output_strm_buf, RK_U32 frame_luma_size) { RK_S32 k = 0; mpp_assert(fp_golden_syntax_in); - memset(syn, 0, sizeof(h264e_syntax)); + memset(syn, 0, sizeof(H264eHwCfg)); if (fp_golden_syntax_in) { char temp[512] = {0}; @@ -422,7 +422,7 @@ static MPP_RET get_vpu_syntax_in(h264e_syntax *syn, MppBuffer hw_in_buf, MppBuff fscanf(fp_golden_syntax_in, "%d", &data); fgets(temp, 512, fp_golden_syntax_in); - syn->frame_coding_type = data; + syn->frame_type = data; fscanf(fp_golden_syntax_in, "%d", &data); @@ -463,7 +463,7 @@ static MPP_RET get_vpu_syntax_in(h264e_syntax *syn, MppBuffer hw_in_buf, MppBuff fscanf(fp_golden_syntax_in, "%d", &data); fgets(temp, 512, fp_golden_syntax_in); - syn->h264_inter4x4_disabled = data; + syn->inter4x4_disabled = data; fscanf(fp_golden_syntax_in, "%d", &data); fgets(temp, 512, fp_golden_syntax_in); @@ -524,15 +524,15 @@ static MPP_RET get_vpu_syntax_in(h264e_syntax *syn, MppBuffer hw_in_buf, MppBuff fscanf(fp_golden_syntax_in, "%d", &data); fgets(temp, 512, fp_golden_syntax_in); - syn->pic_luma_width = data; + syn->width = data; fscanf(fp_golden_syntax_in, "%d", &data); fgets(temp, 512, fp_golden_syntax_in); - syn->pic_luma_height = data; + syn->height = data; fscanf(fp_golden_syntax_in, "%d", &data); fgets(temp, 512, fp_golden_syntax_in); - syn->input_image_format = data; + syn->input_format = data; fscanf(fp_golden_syntax_in, "%d", &data); fgets(temp, 512, fp_golden_syntax_in); @@ -575,546 +575,19 @@ static MPP_RET get_vpu_syntax_in(h264e_syntax *syn, MppBuffer hw_in_buf, MppBuff syn->output_strm_addr = mpp_buffer_get_fd(hw_output_strm_buf); /* adjust */ - syn->input_image_format = h264e_vpu_revert_csp(syn->input_image_format); + syn->input_format = h264e_vpu_revert_csp(syn->input_format); return MPP_OK; } -#if 0 -static void dump_rkv_mpp_dbg_info(h264e_hal_rkv_dbg_info *info, h264e_syntax *syn) -{ - if (fp_mpp_syntax_in) { - RK_S32 k = 0; - FILE *fp = fp_mpp_syntax_in; - fprintf(fp, "#FRAME %d\n", g_frame_read_cnt); - - fprintf(fp, "%-16d %s\n", syn->pic_luma_width, "pic_luma_width"); - fprintf(fp, "%-16d %s\n", syn->pic_luma_height, "pic_luma_height"); - fprintf(fp, "%-16d %s\n", syn->level_idc, "level_idc"); - fprintf(fp, "%-16d %s\n", syn->profile_idc, "profile_idc"); - fprintf(fp, "%-16d %s\n", syn->frame_coding_type, "frame_coding_type"); - - fprintf(fp, "%-16d %s\n", info->swreg02.lkt_num, "swreg02.lkt_num"); - fprintf(fp, "%-16d %s\n", info->swreg02.rkvenc_cmd, "swreg02.rkvenc_cmd"); - fprintf(fp, "%-16d %s\n", info->swreg02.enc_cke, "swreg02.enc_cke"); - - fprintf(fp, "%-16d %s\n", info->swreg04.lkt_addr, "swreg04.lkt_addr"); - - fprintf(fp, "%-16d %s\n", info->swreg05.ofe_fnsh, "swreg05.ofe_fnsh"); - fprintf(fp, "%-16d %s\n", info->swreg05.lkt_fnsh, "swreg05.lkt_fnsh"); - fprintf(fp, "%-16d %s\n", info->swreg05.clr_fnsh, "swreg05.clr_fnsh"); - fprintf(fp, "%-16d %s\n", info->swreg05.ose_fnsh, "swreg05.ose_fnsh"); - fprintf(fp, "%-16d %s\n", info->swreg05.bs_ovflr, "swreg05.bs_ovflr"); - fprintf(fp, "%-16d %s\n", info->swreg05.brsp_ful, "swreg05.brsp_ful"); - fprintf(fp, "%-16d %s\n", info->swreg05.brsp_err, "swreg05.brsp_err"); - fprintf(fp, "%-16d %s\n", info->swreg05.rrsp_err, "swreg05.rrsp_err"); - fprintf(fp, "%-16d %s\n", info->swreg05.tmt_err, "swreg05.tmt_err"); - - fprintf(fp, "%-16d %s\n", info->swreg10.roi_enc, "swreg10.roi_enc"); - fprintf(fp, "%-16d %s\n", info->swreg10.cur_frm_ref, "swreg10.cur_frm_ref"); - fprintf(fp, "%-16d %s\n", info->swreg10.mei_stor, "swreg10.mei_stor"); - fprintf(fp, "%-16d %s\n", info->swreg10.bs_scp, "swreg10.bs_scp"); - fprintf(fp, "%-16d %s\n", info->swreg10.pic_qp, "swreg10.pic_qp"); - fprintf(fp, "%-16d %s\n", info->swreg10.slice_int, "swreg10.slice_int"); - fprintf(fp, "%-16d %s\n", info->swreg10.node_int, "swreg10.node_int"); - - fprintf(fp, "%-16d %s\n", info->swreg11.ppln_enc_lmt, "swreg11.ppln_enc_lmt"); - fprintf(fp, "%-16d %s\n", info->swreg11.rfp_load_thrd, "swreg11.rfp_load_thrd"); - - fprintf(fp, "%-16d %s\n", info->swreg12.src_bus_edin, "swreg12.src_bus_edin"); - - - fprintf(fp, "%-16d %s\n", info->swreg13.axi_brsp_cke, "swreg13.axi_brsp_cke"); - - fprintf(fp, "%-16d %s\n", info->swreg14.src_aswap, "swreg14.src_aswap"); - fprintf(fp, "%-16d %s\n", info->swreg14.src_cswap, "swreg14.src_cswap"); - fprintf(fp, "%-16d %s\n", info->swreg14.src_cfmt, "swreg14.src_cfmt"); - fprintf(fp, "%-16d %s\n", info->swreg14.src_clip_dis, "swreg14.src_clip_dis"); - - fprintf(fp, "%-16d %s\n", info->swreg15.wght_b2y, "swreg15.wght_b2y"); - fprintf(fp, "%-16d %s\n", info->swreg15.wght_g2y, "swreg15.wght_g2y"); - fprintf(fp, "%-16d %s\n", info->swreg15.wght_r2y, "swreg15.wght_r2y"); - - fprintf(fp, "%-16d %s\n", info->swreg16.wght_b2u, "swreg16.wght_b2u"); - fprintf(fp, "%-16d %s\n", info->swreg16.wght_g2u, "swreg16.wght_g2u"); - fprintf(fp, "%-16d %s\n", info->swreg16.wght_r2u, "swreg16.wght_r2u"); - - fprintf(fp, "%-16d %s\n", info->swreg17.wght_b2v, "swreg17.wght_b2v"); - fprintf(fp, "%-16d %s\n", info->swreg17.wght_g2v, "swreg17.wght_g2v"); - fprintf(fp, "%-16d %s\n", info->swreg17.wght_r2v, "swreg17.wght_r2v"); - - fprintf(fp, "%-16d %s\n", info->swreg18.ofst_rgb2v, "swreg18.ofst_rgb2v"); - fprintf(fp, "%-16d %s\n", info->swreg18.ofst_rgb2u, "swreg18.ofst_rgb2u"); - fprintf(fp, "%-16d %s\n", info->swreg18.ofst_rgb2y, "swreg18.ofst_rgb2y"); - - fprintf(fp, "%-16d %s\n", info->swreg19.src_tfltr, "swreg19.src_tfltr"); - fprintf(fp, "%-16d %s\n", info->swreg19.src_tfltr_we, "swreg19.src_tfltr_we"); - fprintf(fp, "%-16d %s\n", info->swreg19.src_tfltr_bw, "swreg19.src_tfltr_bw"); - fprintf(fp, "%-16d %s\n", info->swreg19.src_sfltr, "swreg19.src_sfltr"); - fprintf(fp, "%-16d %s\n", info->swreg19.src_mfltr_thrd, "swreg19.src_mfltr_thrd"); - fprintf(fp, "%-16d %s\n", info->swreg19.src_mfltr_y, "swreg19.src_mfltr_y"); - fprintf(fp, "%-16d %s\n", info->swreg19.src_mfltr_c, "swreg19.src_mfltr_c"); - fprintf(fp, "%-16d %s\n", info->swreg19.src_bfltr_strg, "swreg19.src_bfltr_strg"); - fprintf(fp, "%-16d %s\n", info->swreg19.src_bfltr, "swreg19.src_bfltr"); - fprintf(fp, "%-16d %s\n", info->swreg19.src_mbflt_odr, "swreg19.src_mbflt_odr"); - fprintf(fp, "%-16d %s\n", info->swreg19.src_matf_y, "swreg19.src_matf_y"); - fprintf(fp, "%-16d %s\n", info->swreg19.src_matf_c, "swreg19.src_matf_c"); - fprintf(fp, "%-16d %s\n", info->swreg19.src_shp_y, "swreg19.src_shp_y"); - fprintf(fp, "%-16d %s\n", info->swreg19.src_shp_c, "swreg19.src_shp_c"); - fprintf(fp, "%-16d %s\n", info->swreg19.src_shp_div, "swreg19.src_shp_div"); - fprintf(fp, "%-16d %s\n", info->swreg19.src_shp_thld, "swreg19.src_shp_thld"); - fprintf(fp, "%-16d %s\n", info->swreg19.src_mirr, "swreg19.src_mirr"); - fprintf(fp, "%-16d %s\n", info->swreg19.src_rot, "swreg19.src_rot"); - fprintf(fp, "%-16d %s\n", info->swreg19.src_matf_itsy, "swreg19.src_matf_itsy"); - - fprintf(fp, "%-16d %s\n", info->swreg20.tfltr_thld_y, "swreg20.tfltr_thld_y"); - fprintf(fp, "%-16d %s\n", info->swreg20.tfltr_thld_c, "swreg20.tfltr_thld_c"); - - for (k = 0; k < 5; k++) - fprintf(fp, "%-16d swreg21_scr_stbl[%d]\n", info->swreg21_scr_stbl[k], k); - - for (k = 0; k < 40; k++) - fprintf(fp, "%-16d swreg22_h3d_tbl[%d]\n", info->swreg22_h3d_tbl[k], k); - - fprintf(fp, "%-16d %s\n", info->swreg23.src_ystrid, "swreg23.src_ystrid"); - fprintf(fp, "%-16d %s\n", info->swreg23.src_cstrid, "swreg23.src_cstrid"); - - fprintf(fp, "%#-16x %s\n", info->addr_cfg.adr_srcy, "addr_cfg.adr_srcy"); - fprintf(fp, "%#-16x %s\n", info->addr_cfg.adr_srcu, "addr_cfg.adr_srcu"); - fprintf(fp, "%#-16x %s\n", info->addr_cfg.adr_srcv, "addr_cfg.adr_srcv"); - fprintf(fp, "%#-16x %s\n", info->addr_cfg.ctuc_addr, "addr_cfg.ctuc_addr"); - fprintf(fp, "%#-16x %s\n", info->addr_cfg.rfpw_addr, "addr_cfg.rfpw_addr"); - fprintf(fp, "%#-16x %s\n", info->addr_cfg.rfpr_addr, "addr_cfg.rfpr_addr"); - fprintf(fp, "%#-16x %s\n", info->addr_cfg.dspw_addr, "addr_cfg.dspw_addr"); - fprintf(fp, "%#-16x %s\n", info->addr_cfg.dspr_addr, "addr_cfg.dspr_addr"); - fprintf(fp, "%#-16x %s\n", info->addr_cfg.bsbw_addr, "addr_cfg.bsbw_addr"); - - fprintf(fp, "%-16d %s\n", info->swreg41.sli_cut, "swreg41.sli_cut"); - fprintf(fp, "%-16d %s\n", info->swreg41.sli_cut_mode, "swreg41.sli_cut_mode"); - fprintf(fp, "%-16d %s\n", info->swreg41.sli_cut_bmod, "swreg41.sli_cut_bmod"); - fprintf(fp, "%-16d %s\n", info->swreg41.sli_max_num, "swreg41.sli_max_num"); - fprintf(fp, "%-16d %s\n", info->swreg41.sli_out_mode, "swreg41.sli_out_mode"); - fprintf(fp, "%-16d %s\n", info->swreg41.sli_cut_cnum, "swreg41.sli_cut_cnum"); - - fprintf(fp, "%-16d %s\n", info->swreg42.sli_cut_byte, "swreg42.sli_cut_byte"); - - fprintf(fp, "%-16d %s\n", info->swreg43.cime_srch_h, "swreg43.cime_srch_h"); - fprintf(fp, "%-16d %s\n", info->swreg43.cime_srch_v, "swreg43.cime_srch_v"); - fprintf(fp, "%-16d %s\n", info->swreg43.rime_srch_h, "swreg43.rime_srch_h"); - fprintf(fp, "%-16d %s\n", info->swreg43.rime_srch_v, "swreg43.rime_srch_v"); - - fprintf(fp, "%-16d %s\n", info->swreg44.pmv_mdst_h, "swreg44.pmv_mdst_h"); - fprintf(fp, "%-16d %s\n", info->swreg44.pmv_mdst_v, "swreg44.pmv_mdst_v"); - fprintf(fp, "%-16d %s\n", info->swreg44.mv_limit, "swreg44.mv_limit"); - fprintf(fp, "%-16d %s\n", info->swreg44.mv_num, "swreg44.mv_num"); - - fprintf(fp, "%-16d %s\n", info->swreg45.cach_l1_dtmr, "swreg45.cach_l1_dtmr"); - - fprintf(fp, "%-16d %s\n", info->swreg46.rc_en, "swreg46.rc_en"); - fprintf(fp, "%-16d %s\n", info->swreg46.rc_mode, "swreg46.rc_mode"); - fprintf(fp, "%-16d %s\n", info->swreg46.aqmode_en, "swreg46.aqmode_en"); - fprintf(fp, "%-16d %s\n", info->swreg46.aq_strg, "swreg46.aq_strg"); - fprintf(fp, "%-16d %s\n", info->swreg46.rc_ctu_num, "swreg46.rc_ctu_num"); - - fprintf(fp, "%-16d %s\n", info->swreg47.bits_error0, "swreg47.bits_error0"); - fprintf(fp, "%-16d %s\n", info->swreg47.bits_error1, "swreg47.bits_error1"); - fprintf(fp, "%-16d %s\n", info->swreg48.bits_error2, "swreg48.bits_error2"); - fprintf(fp, "%-16d %s\n", info->swreg48.bits_error3, "swreg48.bits_error3"); - fprintf(fp, "%-16d %s\n", info->swreg49.bits_error4, "swreg49.bits_error4"); - fprintf(fp, "%-16d %s\n", info->swreg49.bits_error5, "swreg49.bits_error5"); - fprintf(fp, "%-16d %s\n", info->swreg50.bits_error6, "swreg50.bits_error6"); - fprintf(fp, "%-16d %s\n", info->swreg50.bits_error7, "swreg50.bits_error7"); - fprintf(fp, "%-16d %s\n", info->swreg51.bits_error8, "swreg51.bits_error8"); - - fprintf(fp, "%-16d %s\n", info->swreg52.qp_adjuest0, "swreg52.qp_adjuest0"); - fprintf(fp, "%-16d %s\n", info->swreg52.qp_adjuest1, "swreg52.qp_adjuest1"); - fprintf(fp, "%-16d %s\n", info->swreg52.qp_adjuest2, "swreg52.qp_adjuest2"); - fprintf(fp, "%-16d %s\n", info->swreg52.qp_adjuest3, "swreg52.qp_adjuest3"); - fprintf(fp, "%-16d %s\n", info->swreg52.qp_adjuest4, "swreg52.qp_adjuest4"); - fprintf(fp, "%-16d %s\n", info->swreg52.qp_adjuest5, "swreg52.qp_adjuest5"); - fprintf(fp, "%-16d %s\n", info->swreg53.qp_adjuest6, "swreg53.qp_adjuest6"); - fprintf(fp, "%-16d %s\n", info->swreg53.qp_adjuest7, "swreg53.qp_adjuest7"); - fprintf(fp, "%-16d %s\n", info->swreg53.qp_adjuest8, "swreg53.qp_adjuest8"); - - fprintf(fp, "%-16d %s\n", info->swreg54.rc_qp_mod, "swreg54.rc_qp_mod"); - fprintf(fp, "%-16d %s\n", info->swreg54.rc_fact0, "swreg54.rc_fact0"); - fprintf(fp, "%-16d %s\n", info->swreg54.rc_fact1, "swreg54.rc_fact1"); - fprintf(fp, "%-16d %s\n", info->swreg54.rc_qp_range, "swreg54.rc_qp_range"); - fprintf(fp, "%-16d %s\n", info->swreg54.rc_max_qp, "swreg54.rc_max_qp"); - fprintf(fp, "%-16d %s\n", info->swreg54.rc_min_qp, "swreg54.rc_min_qp"); - - fprintf(fp, "%-16d %s\n", info->swreg55.ctu_ebits, "swreg55.ctu_ebits"); - - fprintf(fp, "%-16d %s\n", info->swreg56.arb_sel, "swreg56.arb_sel"); - fprintf(fp, "%-16d %s\n", info->swreg56.rdo_mark, "swreg56.rdo_mark"); - - fprintf(fp, "%-16d %s\n", info->swreg57.nal_ref_idc, "swreg57.nal_ref_idc"); - fprintf(fp, "%-16d %s\n", info->swreg57.nal_unit_type, "swreg57.nal_unit_type"); - - fprintf(fp, "%-16d %s\n", info->swreg58.max_fnum, "swreg58.max_fnum"); - fprintf(fp, "%-16d %s\n", info->swreg58.drct_8x8, "swreg58.drct_8x8"); - fprintf(fp, "%-16d %s\n", info->swreg58.mpoc_lm4, "swreg58.mpoc_lm4"); - - fprintf(fp, "%-16d %s\n", info->swreg59.etpy_mode, "swreg59.etpy_mode"); - fprintf(fp, "%-16d %s\n", info->swreg59.trns_8x8, "swreg59.trns_8x8"); - fprintf(fp, "%-16d %s\n", info->swreg59.csip_flg, "swreg59.csip_flg"); - fprintf(fp, "%-16d %s\n", info->swreg59.num_ref0_idx, "swreg59.num_ref0_idx"); - fprintf(fp, "%-16d %s\n", info->swreg59.num_ref1_idx, "swreg59.num_ref1_idx"); - fprintf(fp, "%-16d %s\n", info->swreg59.pic_init_qp, "swreg59.pic_init_qp"); - fprintf(fp, "%-16d %s\n", info->swreg59.cb_ofst, "swreg59.cb_ofst"); - fprintf(fp, "%-16d %s\n", info->swreg59.cr_ofst, "swreg59.cr_ofst"); - fprintf(fp, "%-16d %s\n", info->swreg59.dbf_cp_flg, "swreg59.dbf_cp_flg"); - - fprintf(fp, "%-16d %s\n", info->swreg60.sli_type, "swreg60.sli_type"); - fprintf(fp, "%-16d %s\n", info->swreg60.pps_id, "swreg60.pps_id"); - fprintf(fp, "%-16d %s\n", info->swreg60.num_ref_ovrd, "swreg60.num_ref_ovrd"); - fprintf(fp, "%-16d %s\n", info->swreg60.cbc_init_idc, "swreg60.cbc_init_idc"); - fprintf(fp, "%-16d %s\n", info->swreg60.frm_num, "swreg60.frm_num"); - - fprintf(fp, "%-16d %s\n", info->swreg61.idr_pid, "swreg61.idr_pid"); - fprintf(fp, "%-16d %s\n", info->swreg61.poc_lsb, "swreg61.poc_lsb"); - - fprintf(fp, "%-16d %s\n", info->swreg62.rodr_pic_idx, "swreg62.rodr_pic_idx"); - fprintf(fp, "%-16d %s\n", info->swreg62.ref_list0_rodr, "swreg62.ref_list0_rodr"); - fprintf(fp, "%-16d %s\n", info->swreg62.sli_beta_ofst, "swreg62.sli_beta_ofst"); - fprintf(fp, "%-16d %s\n", info->swreg62.sli_alph_ofst, "swreg62.sli_alph_ofst"); - fprintf(fp, "%-16d %s\n", info->swreg62.dis_dblk_idc, "swreg62.dis_dblk_idc"); - fprintf(fp, "%-16d %s\n", info->swreg62.rodr_pic_num, "swreg62.rodr_pic_num"); - - fprintf(fp, "%-16d %s\n", info->swreg63.ltrf_flg, "swreg63.ltrf_flg"); - fprintf(fp, "%-16d %s\n", info->swreg63.arpm_flg, "swreg63.arpm_flg"); - fprintf(fp, "%-16d %s\n", info->swreg63.mmco4_pre, "swreg63.mmco4_pre"); - fprintf(fp, "%-16d %s\n", info->swreg63.mmco_0, "swreg63.mmco_0"); - fprintf(fp, "%-16d %s\n", info->swreg63.dopn_m1_0, "swreg63.dopn_m1_0"); - - fprintf(fp, "%-16d %s\n", info->swreg64.mmco_1, "swreg64.mmco_1"); - fprintf(fp, "%-16d %s\n", info->swreg64.dopn_m1_1, "swreg64.dopn_m1_1"); - - fprintf(fp, "%-16d %s\n", info->swreg65.osd_en, "swreg65.osd_en"); - fprintf(fp, "%-16d %s\n", info->swreg65.osd_inv, "swreg65.osd_inv"); - fprintf(fp, "%-16d %s\n", info->swreg65.osd_plt_type, "swreg65.osd_plt_type"); - - fprintf(fp, "%-16d %s\n", info->swreg66.osd_inv_r0, "swreg66.osd_inv_r0"); - fprintf(fp, "%-16d %s\n", info->swreg66.osd_inv_r1, "swreg66.osd_inv_r1"); - fprintf(fp, "%-16d %s\n", info->swreg66.osd_inv_r2, "swreg66.osd_inv_r2"); - fprintf(fp, "%-16d %s\n", info->swreg66.osd_inv_r3, "swreg66.osd_inv_r3"); - fprintf(fp, "%-16d %s\n", info->swreg66.osd_inv_r4, "swreg66.osd_inv_r4"); - fprintf(fp, "%-16d %s\n", info->swreg66.osd_inv_r5, "swreg66.osd_inv_r5"); - fprintf(fp, "%-16d %s\n", info->swreg66.osd_inv_r6, "swreg66.osd_inv_r6"); - fprintf(fp, "%-16d %s\n", info->swreg66.osd_inv_r7, "swreg66.osd_inv_r7"); - - for (k = 0; k < 8; k++) { - fprintf(fp, "%-16d swreg67_osd_pos[%d].lt_pos_x\n", info->swreg67_osd_pos[k].lt_pos_x, k); - fprintf(fp, "%-16d swreg67_osd_pos[%d].lt_pos_y\n", info->swreg67_osd_pos[k].lt_pos_y, k); - fprintf(fp, "%-16d swreg67_osd_pos[%d].rd_pos_x\n", info->swreg67_osd_pos[k].rd_pos_x, k); - fprintf(fp, "%-16d swreg67_osd_pos[%d].rd_pos_y\n", info->swreg67_osd_pos[k].rd_pos_y, k); - } - for (k = 0; k < 8; k++) - fprintf(fp, "%-16d swreg68_indx_addr_i[%d]\n", info->swreg68_indx_addr_i[k], k); - - for (k = 0; k < 256; k++) - fprintf(fp, "%#-16x swreg73_osd_indx_tab_i[%d]\n", info->swreg73_osd_indx_tab_i[k], k); - - fprintf(fp, "%#-16x %s\n", info->swreg77.bsbw_addr, "swreg77.bsbw_addr"); - - fprintf(fp, "\n"); - fflush(fp); - } else { - mpp_log("try to dump data to mpp_syntax_in.txt, but file is not opened"); - } -} -#endif - - -#if 0 -static MPP_RET get_rkv_dbg_info(h264e_hal_rkv_dbg_info *info, h264e_syntax *syn, - MppBuffer *hw_in_buf, MppBuffer *hw_output_strm_buf) - -{ - RK_S32 k = 0; - RK_U32 buf_idx = g_frame_read_cnt % RKV_H264E_LINKTABLE_FRAME_NUM; - h264e_hal_debug_enter(); - mpp_assert(fp_golden_syntax_in); - memset(syn, 0, sizeof(h264e_syntax)); - memset(info, 0, sizeof(h264e_hal_rkv_dbg_info)); - - if (hw_in_buf[buf_idx]) { - syn->input_luma_addr = mpp_buffer_get_fd(hw_in_buf[buf_idx]); - syn->input_cb_addr = syn->input_luma_addr; //NOTE: transfer offset in extra_info - syn->input_cr_addr = syn->input_luma_addr; - } - if (hw_output_strm_buf[buf_idx]) - syn->output_strm_addr = mpp_buffer_get_fd(hw_output_strm_buf[buf_idx]); - - - if (fp_golden_syntax_in) { - FILE *fp = fp_golden_syntax_in; - char temp[512] = {0}; - RK_S32 data = 0; - - if (!fgets(temp, 512, fp)) - return MPP_EOS_STREAM_REACHED; - - H264E_HAL_FSCAN(fp, "%d\n", syn->pic_luma_width); - H264E_HAL_FSCAN(fp, "%d\n", syn->pic_luma_height); - H264E_HAL_FSCAN(fp, "%d\n", syn->level_idc); - H264E_HAL_FSCAN(fp, "%d\n", syn->profile_idc); - H264E_HAL_FSCAN(fp, "%d\n", syn->frame_coding_type); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg02.lkt_num); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg02.rkvenc_cmd); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg02.enc_cke); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg04.lkt_addr); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg05.ofe_fnsh); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg05.lkt_fnsh); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg05.clr_fnsh); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg05.ose_fnsh); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg05.bs_ovflr); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg05.brsp_ful); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg05.brsp_err); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg05.rrsp_err); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg05.tmt_err); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg10.roi_enc); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg10.cur_frm_ref); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg10.mei_stor); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg10.bs_scp); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg10.pic_qp); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg10.slice_int); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg10.node_int); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg11.ppln_enc_lmt); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg11.rfp_load_thrd); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg12.src_bus_edin); - - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg13.axi_brsp_cke); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg14.src_aswap); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg14.src_cswap); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg14.src_cfmt); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg14.src_clip_dis); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg15.wght_b2y); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg15.wght_g2y); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg15.wght_r2y); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg16.wght_b2u); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg16.wght_g2u); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg16.wght_r2u); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg17.wght_b2v); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg17.wght_g2v); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg17.wght_r2v); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg18.ofst_rgb2v); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg18.ofst_rgb2u); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg18.ofst_rgb2y); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_tfltr); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_tfltr_we); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_tfltr_bw); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_sfltr); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_mfltr_thrd); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_mfltr_y); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_mfltr_c); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_bfltr_strg); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_bfltr); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_mbflt_odr); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_matf_y); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_matf_c); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_shp_y); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_shp_c); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_shp_div); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_shp_thld); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_mirr); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_rot); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_matf_itsy); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg20.tfltr_thld_y); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg20.tfltr_thld_c); - - for (k = 0; k < 5; k++) - H264E_HAL_FSCAN(fp, "%d\n", info->swreg21_scr_stbl[k]); - - for (k = 0; k < 40; k++) - H264E_HAL_FSCAN(fp, "%d\n", info->swreg22_h3d_tbl[k]); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg23.src_ystrid); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg23.src_cstrid); - - H264E_HAL_FSCAN(fp, "%x\n", info->addr_cfg.adr_srcy); - H264E_HAL_FSCAN(fp, "%x\n", info->addr_cfg.adr_srcu); - H264E_HAL_FSCAN(fp, "%x\n", info->addr_cfg.adr_srcv); - H264E_HAL_FSCAN(fp, "%x\n", info->addr_cfg.ctuc_addr); - H264E_HAL_FSCAN(fp, "%x\n", info->addr_cfg.rfpw_addr); - H264E_HAL_FSCAN(fp, "%x\n", info->addr_cfg.rfpr_addr); - H264E_HAL_FSCAN(fp, "%x\n", info->addr_cfg.dspw_addr); - H264E_HAL_FSCAN(fp, "%x\n", info->addr_cfg.dspr_addr); - H264E_HAL_FSCAN(fp, "%x\n", info->addr_cfg.bsbw_addr); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg41.sli_cut); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg41.sli_cut_mode); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg41.sli_cut_bmod); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg41.sli_max_num); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg41.sli_out_mode); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg41.sli_cut_cnum); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg42.sli_cut_byte); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg43.cime_srch_h); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg43.cime_srch_v); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg43.rime_srch_h); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg43.rime_srch_v); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg44.pmv_mdst_h); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg44.pmv_mdst_v); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg44.mv_limit); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg44.mv_num); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg45.cach_l1_dtmr); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg46.rc_en); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg46.rc_mode); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg46.aqmode_en); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg46.aq_strg); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg46.rc_ctu_num); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg47.bits_error0); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg47.bits_error1); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg48.bits_error2); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg48.bits_error3); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg49.bits_error4); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg49.bits_error5); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg50.bits_error6); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg50.bits_error7); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg51.bits_error8); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg52.qp_adjuest0); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg52.qp_adjuest1); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg52.qp_adjuest2); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg52.qp_adjuest3); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg52.qp_adjuest4); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg52.qp_adjuest5); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg53.qp_adjuest6); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg53.qp_adjuest7); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg53.qp_adjuest8); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg54.rc_qp_mod); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg54.rc_fact0); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg54.rc_fact1); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg54.rc_qp_range); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg54.rc_max_qp); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg54.rc_min_qp); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg55.ctu_ebits); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg56.arb_sel); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg56.rdo_mark); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg57.nal_ref_idc); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg57.nal_unit_type); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg58.max_fnum); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg58.drct_8x8); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg58.mpoc_lm4); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg59.etpy_mode); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg59.trns_8x8); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg59.csip_flg); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg59.num_ref0_idx); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg59.num_ref1_idx); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg59.pic_init_qp); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg59.cb_ofst); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg59.cr_ofst); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg59.dbf_cp_flg); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg60.sli_type); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg60.pps_id); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg60.num_ref_ovrd); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg60.cbc_init_idc); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg60.frm_num); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg61.idr_pid); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg61.poc_lsb); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg62.rodr_pic_idx); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg62.ref_list0_rodr); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg62.sli_beta_ofst); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg62.sli_alph_ofst); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg62.dis_dblk_idc); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg62.rodr_pic_num); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg63.ltrf_flg); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg63.arpm_flg); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg63.mmco4_pre); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg63.mmco_0); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg63.dopn_m1_0); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg64.mmco_1); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg64.dopn_m1_1); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg65.osd_en); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg65.osd_inv); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg65.osd_plt_type); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg66.osd_inv_r0); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg66.osd_inv_r1); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg66.osd_inv_r2); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg66.osd_inv_r3); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg66.osd_inv_r4); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg66.osd_inv_r5); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg66.osd_inv_r6); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg66.osd_inv_r7); - - for (k = 0; k < 8; k++) { - H264E_HAL_FSCAN(fp, "%d\n", info->swreg67_osd_pos[k].lt_pos_x); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg67_osd_pos[k].lt_pos_y); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg67_osd_pos[k].rd_pos_x); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg67_osd_pos[k].rd_pos_y); - } - for (k = 0; k < 8; k++) - H264E_HAL_FSCAN(fp, "%d\n", info->swreg68_indx_addr_i[k]); - - for (k = 0; k < 256; k++) - H264E_HAL_FSCAN(fp, "%x\n", info->swreg73_osd_indx_tab_i[k]); - - H264E_HAL_FSCAN(fp, "%x\n", info->swreg77.bsbw_addr); - - H264E_HAL_FSCAN(fp, "%x\n", syn->keyframe_max_interval); - - fgets(temp, 512, fp); - - //set values actually used - syn->slice_type = info->swreg60.sli_type; - syn->pps_id = info->swreg60.pps_id; - syn->cabac_init_idc = info->swreg60.cbc_init_idc; - syn->pic_order_cnt_lsb = info->swreg61.poc_lsb; - syn->idr_pic_id = info->swreg61.idr_pid; - syn->pic_init_qp = info->swreg59.pic_init_qp; - syn->qp = info->swreg10.pic_qp; - syn->frame_num = info->swreg60.frm_num; - syn->input_image_format = info->swreg14.src_cfmt; - syn->transform8x8_mode = info->swreg59.trns_8x8; - } - - h264e_hal_debug_leave(); - return MPP_OK; -} -#endif - - -static MPP_RET get_rkv_syntax_in( h264e_syntax *syn, MppBuffer *hw_in_buf, MppBuffer *hw_output_strm_buf, h264e_hal_test_cfg *cfg) +static MPP_RET get_rkv_syntax_in( H264eHwCfg *syn, MppBuffer *hw_in_buf, MppBuffer *hw_output_strm_buf, h264e_hal_test_cfg *cfg) { h264e_hal_rkv_csp_info csp_info; RK_U32 buf_idx = g_frame_read_cnt % RKV_H264E_LINKTABLE_FRAME_NUM; h264e_hal_debug_enter(); //mpp_assert(fp_golden_syntax_in); - memset(syn, 0, sizeof(h264e_syntax)); + memset(syn, 0, sizeof(H264eHwCfg)); if (hw_in_buf[buf_idx]) { syn->input_luma_addr = mpp_buffer_get_fd(hw_in_buf[buf_idx]); @@ -1126,25 +599,23 @@ static MPP_RET get_rkv_syntax_in( h264e_syntax *syn, MppBuffer *hw_in_buf, MppBu #if RKV_H264E_SDK_TEST mpp_log("make syntax begin"); - syn->pic_luma_width = cfg->pic_width; - syn->pic_luma_height = cfg->pic_height; + syn->width = cfg->pic_width; + syn->height = cfg->pic_height; syn->level_idc = H264_LEVEL_4_1; syn->profile_idc = H264_PROFILE_HIGH; mpp_log("syn->level_idc %d", syn->level_idc); mpp_log("syn->profile_idc %d", syn->profile_idc); syn->keyframe_max_interval = 30; if (g_frame_cnt == 0 || g_frame_cnt % syn->keyframe_max_interval == 0) { - syn->frame_coding_type = 1; //intra - syn->slice_type = 2; + syn->frame_type = 1; //intra } else { - syn->frame_coding_type = 0; //inter - syn->slice_type = 0; + syn->frame_type = 0; //inter } syn->qp = 26; csp_info.fmt = H264E_RKV_CSP_YUV420P; csp_info.cswap = 0; //TODO: csp_info.aswap = 0; //TODO: - syn->input_image_format = h264e_rkv_revert_csp(csp_info); + syn->input_format = h264e_rkv_revert_csp(csp_info); syn->enable_cabac = 1; syn->pic_init_qp = 26; @@ -1170,13 +641,13 @@ static MPP_RET get_rkv_syntax_in( h264e_syntax *syn, MppBuffer *hw_in_buf, MppBu if (!fgets(temp, 512, fp)) return MPP_EOS_STREAM_REACHED; - H264E_HAL_FSCAN(fp, "%d\n", syn->pic_luma_width); - H264E_HAL_FSCAN(fp, "%d\n", syn->pic_luma_height); + H264E_HAL_FSCAN(fp, "%d\n", syn->width); + H264E_HAL_FSCAN(fp, "%d\n", syn->height); H264E_HAL_FSCAN(fp, "%d\n", syn->level_idc); H264E_HAL_FSCAN(fp, "%d\n", syn->profile_idc); - H264E_HAL_FSCAN(fp, "%d\n", syn->frame_coding_type); + H264E_HAL_FSCAN(fp, "%d\n", syn->frame_type); H264E_HAL_FSCAN(fp, "%d\n", syn->qp); - H264E_HAL_FSCAN(fp, "%d\n", syn->input_image_format); + H264E_HAL_FSCAN(fp, "%d\n", syn->input_format); H264E_HAL_FSCAN(fp, "%d\n", syn->enable_cabac); H264E_HAL_FSCAN(fp, "%d\n", syn->pic_init_qp); @@ -1197,15 +668,15 @@ static MPP_RET get_rkv_syntax_in( h264e_syntax *syn, MppBuffer *hw_in_buf, MppBu fgets(temp, 512, fp); /* adjust */ - csp_info.fmt = syn->input_image_format; + csp_info.fmt = syn->input_format; csp_info.cswap = 0; //TODO: csp_info.aswap = 0; //TODO: - syn->input_image_format = h264e_rkv_revert_csp(csp_info); + syn->input_format = h264e_rkv_revert_csp(csp_info); } else { mpp_err("rkv_syntax_in.txt doesn't exits"); } #endif - syn->output_strm_limit_size = (RK_U32)(syn->pic_luma_width * syn->pic_luma_height * 3 / 2); + syn->output_strm_limit_size = (RK_U32)(syn->width * syn->height * 3 / 2); h264e_hal_debug_leave(); return MPP_OK; @@ -1335,16 +806,16 @@ MPP_RET h264_hal_test_call_back(void *control, void *feedback) return MPP_OK; } -static void h264e_hal_set_extra_info_cfg(h264e_control_extra_info_cfg *info, h264e_syntax *syn) +static void h264e_hal_set_extra_info_cfg(h264e_control_extra_info_cfg *info, H264eHwCfg *syn) { info->chroma_qp_index_offset = syn->chroma_qp_index_offset; info->enable_cabac = syn->enable_cabac; info->pic_init_qp = syn->pic_init_qp; - info->pic_luma_height = syn->pic_luma_height; - info->pic_luma_width = syn->pic_luma_width; + info->pic_luma_height = syn->height; + info->pic_luma_width = syn->width; info->transform8x8_mode = syn->transform8x8_mode; - info->input_image_format = syn->input_image_format; + info->input_image_format = syn->input_format; info->profile_idc = syn->profile_idc; info->level_idc = syn->level_idc; info->keyframe_max_interval = syn->keyframe_max_interval; @@ -1360,7 +831,7 @@ MPP_RET h264e_hal_vpu_test() h264e_hal_context ctx; MppHalCfg hal_cfg; HalTaskInfo task_info; - h264e_syntax syntax_data; + H264eHwCfg syntax_data; h264e_control_extra_info_cfg extra_info_cfg; MppPacket extra_info_pkt; RK_U8 extra_info_buf[H264E_EXTRA_INFO_BUF_SIZE] = {0}; @@ -1379,7 +850,7 @@ MPP_RET h264e_hal_vpu_test() if (fp_golden_syntax_in) fseek(fp_golden_syntax_in, 0L, SEEK_SET); - frame_luma_size = syntax_data.pic_luma_width * syntax_data.pic_luma_height; + frame_luma_size = syntax_data.width * syntax_data.height; h264e_hal_test_init(&ctx, &task_info); @@ -1477,7 +948,7 @@ MPP_RET h264e_hal_rkv_test(h264e_hal_test_cfg *test_cfg) h264e_control_extra_info_cfg extra_info_cfg; MppPacket extra_info_pkt; RK_U8 extra_info_buf[H264E_EXTRA_INFO_BUF_SIZE] = {0}; - h264e_syntax syntax_data[RKV_H264E_LINKTABLE_FRAME_NUM]; + H264eHwCfg syntax_data[RKV_H264E_LINKTABLE_FRAME_NUM]; MppBufferGroup hw_input_buf_grp = NULL; MppBufferGroup hw_output_buf_grp = NULL; MppBuffer hw_input_buf_mul[RKV_H264E_LINKTABLE_FRAME_NUM] = {NULL}; @@ -1506,7 +977,7 @@ MPP_RET h264e_hal_rkv_test(h264e_hal_test_cfg *test_cfg) fseek(fp_golden_syntax_in, 0L, SEEK_SET); - frame_luma_stride = ((syntax_data[0].pic_luma_width + 15) & (~15)) * ((syntax_data[0].pic_luma_height + 15) & (~15)); + frame_luma_stride = ((syntax_data[0].width + 15) & (~15)) * ((syntax_data[0].height + 15) & (~15)); h264e_hal_test_init(&ctx, &task_info); @@ -1526,7 +997,7 @@ MPP_RET h264e_hal_rkv_test(h264e_hal_test_cfg *test_cfg) } for (k = 0; k < RKV_H264E_LINKTABLE_FRAME_NUM; k++) - mpp_buffer_get(hw_output_buf_grp, &hw_output_strm_buf_mul[k], syntax_data[0].pic_luma_width * syntax_data[0].pic_luma_height * 3 / 2); + mpp_buffer_get(hw_output_buf_grp, &hw_output_strm_buf_mul[k], syntax_data[0].width * syntax_data[0].height * 3 / 2); hal_cfg.hal_int_cb.callBack = h264_hal_test_call_back; @@ -1551,7 +1022,7 @@ MPP_RET h264e_hal_rkv_test(h264e_hal_test_cfg *test_cfg) do { /* get golden input */ if (g_frame_read_cnt <= g_frame_cnt) { - h264e_syntax *syn = NULL; + H264eHwCfg *syn = NULL; RK_S32 frame_num = RKV_H264E_ENC_MODE == 1 ? 1 : RKV_H264E_LINKTABLE_FRAME_NUM; mpp_log("read %d frames input", frame_num); for (k = 0; k < frame_num; k++, g_frame_read_cnt++) { diff --git a/mpp/hal/inc/hal_task.h b/mpp/hal/inc/hal_task.h index 01156bfe..efd6291b 100644 --- a/mpp/hal/inc/hal_task.h +++ b/mpp/hal/inc/hal_task.h @@ -143,6 +143,7 @@ typedef struct HalEncTask_t { // current tesk output stream buffer MppBuffer output; + RK_U32 length; // current tesk input slot buffer MppBuffer input; diff --git a/mpp/hal/inc/mpp_hal.h b/mpp/hal/inc/mpp_hal.h index 5d039091..da3c9f9b 100644 --- a/mpp/hal/inc/mpp_hal.h +++ b/mpp/hal/inc/mpp_hal.h @@ -47,6 +47,9 @@ typedef struct MppHalCfg_t { HalDeviceId device_id; MppBufSlots frame_slots; MppBufSlots packet_slots; + // for encoder + MppEncCfgSet *cfg; /* encoder runtime config */ + MppEncCfgSet *set; /* encoder input config */ // output HalTaskGroup tasks; diff --git a/mpp/hal/mpp_hal.cpp b/mpp/hal/mpp_hal.cpp index cd2e2555..c9ff86b4 100644 --- a/mpp/hal/mpp_hal.cpp +++ b/mpp/hal/mpp_hal.cpp @@ -118,9 +118,14 @@ MPP_RET mpp_hal_init(MppHal *ctx, MppHalCfg *cfg) p->api = hw_apis[i]; p->task_count = cfg->task_count; p->ctx = mpp_calloc_size(void, p->api->ctx_size); - p->api->init(p->ctx, cfg); - MPP_RET ret = hal_task_group_init(&p->tasks, p->type, p->task_count); + MPP_RET ret = p->api->init(p->ctx, cfg); + if (ret) { + mpp_err_f("hal %s init failed ret %d\n", hw_apis[i]->name, ret); + break; + } + + ret = hal_task_group_init(&p->tasks, p->type, p->task_count); if (ret) { mpp_err_f("hal_task_group_init failed ret %d\n", ret); break; diff --git a/mpp/hal/rkenc/h264e/CMakeLists.txt b/mpp/hal/rkenc/h264e/CMakeLists.txt index d92d43b9..b08ff9e9 100644 --- a/mpp/hal/rkenc/h264e/CMakeLists.txt +++ b/mpp/hal/rkenc/h264e/CMakeLists.txt @@ -1,38 +1,21 @@ # vim: syntax=cmake include_directories(.) +include_directories(../../common/h264/) -# hal h264 encoder api -set(HAL_H264E_API - ../../inc/hal_h264e_api.h - ../../../common/h264e_syntax.h +# hal h264 header +set(HAL_H264E_HDR + hal_h264e_rkv.h ) - -# hal h264 header -set(HAL_H264E_HDR - hal_h264e.h - hal_h264e_vpu.h - hal_h264e_rkv.h - ) - # hal h264 encoder sourse set(HAL_H264E_SRC - hal_h264e_api.c - hal_h264e_vpu.c - hal_h264e_rkv.c - ) - -add_library(hal_h264e STATIC - ${HAL_H264E_API} - ${HAL_H264E_HDR} - ${HAL_H264E_SRC} - ) -if(RKPLATFORM) - target_link_libraries(hal_h264e worker_vpu mpp_base) -else() - target_link_libraries(hal_h264e mpp_base) -endif() + hal_h264e_rkv.c + ) -set_target_properties(hal_h264e PROPERTIES FOLDER "mpp/hal") - -add_subdirectory(test) +add_library(hal_h264e_rkv STATIC + ${HAL_H264E_HDR} + ${HAL_H264E_SRC} + ) + +target_link_libraries(hal_h264e_rkv hal_h264e) +set_target_properties(hal_h264e_rkv PROPERTIES FOLDER "mpp/hal") diff --git a/mpp/hal/rkenc/h264e/hal_h264e_rkv.c b/mpp/hal/rkenc/h264e/hal_h264e_rkv.c index c8dc843b..1ccce703 100644 --- a/mpp/hal/rkenc/h264e/hal_h264e_rkv.c +++ b/mpp/hal/rkenc/h264e/hal_h264e_rkv.c @@ -18,35 +18,41 @@ #include #include +#include #include "vpu.h" #include "mpp_common.h" #include "mpp_mem.h" #include "h264_syntax.h" -#include "hal_h264e.h" +#include "hal_h264e_com.h" #include "hal_h264e_rkv.h" -#define RKVENC_DUMP_INFO 0 +#define RKVENC_DUMP_INFO 0 -#define RKVENC_FRAME_TYPE_AUTO 0x0000 /* Let x264 choose the right type */ -#define RKVENC_FRAME_TYPE_IDR 0x0001 -#define RKVENC_FRAME_TYPE_I 0x0002 -#define RKVENC_FRAME_TYPE_P 0x0003 -#define RKVENC_FRAME_TYPE_BREF 0x0004 /* Non-disposable B-frame */ -#define RKVENC_FRAME_TYPE_B 0x0005 -#define RKVENC_FRAME_TYPE_KEYFRAME 0x0006 /* IDR or I depending on b_open_gop option */ -#define RKVENC_IS_TYPE_I(x) ((x)==RKVENC_FRAME_TYPE_I || (x)==RKVENC_FRAME_TYPE_IDR) -#define RKVENC_IS_TYPE_B(x) ((x)==RKVENC_FRAME_TYPE_B || (x)==RKVENC_FRAME_TYPE_BREF) -#define RKVENC_IS_DISPOSABLE(type) ( type == RKVENC_FRAME_TYPE_B ) +#define RKVENC_CODING_TYPE_AUTO 0x0000 /* Let x264 choose the right type */ +#define RKVENC_CODING_TYPE_IDR 0x0001 +#define RKVENC_CODING_TYPE_I 0x0002 +#define RKVENC_CODING_TYPE_P 0x0003 +#define RKVENC_CODING_TYPE_BREF 0x0004 /* Non-disposable B-frame */ +#define RKVENC_CODING_TYPE_B 0x0005 +#define RKVENC_CODING_TYPE_KEYFRAME 0x0006 /* IDR or I depending on b_open_gop option */ +#define RKVENC_IS_TYPE_I(x) ((x)==RKVENC_CODING_TYPE_I || (x)==RKVENC_CODING_TYPE_IDR) +#define RKVENC_IS_TYPE_B(x) ((x)==RKVENC_CODING_TYPE_B || (x)==RKVENC_CODING_TYPE_BREF) +#define RKVENC_IS_DISPOSABLE(type) ( type == RKVENC_CODING_TYPE_B ) #define H264E_IOC_CUSTOM_BASE 0x1000 #define H264E_IOC_SET_OSD_PLT (H264E_IOC_CUSTOM_BASE + 1) -const RK_S32 h264e_csp_idx_map[H264E_RKV_CSP_BUTT] = {RKV_H264E_CSP2_BGRA, RKV_H264E_CSP2_BGR, RKV_H264E_CSP2_RGB, 0, RKV_H264E_CSP2_NV16, RKV_H264E_CSP2_I422, RKV_H264E_CSP2_NV12, - RKV_H264E_CSP2_I420, RKV_H264E_CSP2_RGB, RKV_H264E_CSP2_RGB - }; +static const RK_S32 h264_q_step[] = { + 3, 3, 3, 4, 4, 5, 5, 6, 7, 7, + 8, 9, 10, 11, 13, 14, 16, 18, 20, 23, + 25, 28, 32, 36, 40, 45, 51, 57, 64, 72, + 80, 90, 101, 114, 128, 144, 160, 180, 203, 228, + 256, 288, 320, 360, 405, 456, 513, 577, 640, 720, + 810, 896 +}; static const RK_U32 h264e_h3d_tbl[40] = { 0x0b080400, 0x1815120f, 0x23201e1b, 0x2c2a2725, @@ -80,83 +86,6 @@ static const RK_U8 h264e_ue_size_tab[256] = { 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, }; -/* default quant matrices */ -static const RK_U8 h264e_rkv_cqm_jvt4i[16] = { - 6, 13, 20, 28, - 13, 20, 28, 32, - 20, 28, 32, 37, - 28, 32, 37, 42 -}; -static const RK_U8 h264e_rkv_cqm_jvt4p[16] = { - 10, 14, 20, 24, - 14, 20, 24, 27, - 20, 24, 27, 30, - 24, 27, 30, 34 -}; -static const RK_U8 h264e_rkv_cqm_jvt8i[64] = { - 6, 10, 13, 16, 18, 23, 25, 27, - 10, 11, 16, 18, 23, 25, 27, 29, - 13, 16, 18, 23, 25, 27, 29, 31, - 16, 18, 23, 25, 27, 29, 31, 33, - 18, 23, 25, 27, 29, 31, 33, 36, - 23, 25, 27, 29, 31, 33, 36, 38, - 25, 27, 29, 31, 33, 36, 38, 40, - 27, 29, 31, 33, 36, 38, 40, 42 -}; -static const RK_U8 h264e_rkv_cqm_jvt8p[64] = { - 9, 13, 15, 17, 19, 21, 22, 24, - 13, 13, 17, 19, 21, 22, 24, 25, - 15, 17, 19, 21, 22, 24, 25, 27, - 17, 19, 21, 22, 24, 25, 27, 28, - 19, 21, 22, 24, 25, 27, 28, 30, - 21, 22, 24, 25, 27, 28, 30, 32, - 22, 24, 25, 27, 28, 30, 32, 33, - 24, 25, 27, 28, 30, 32, 33, 35 -}; - -static const RK_U8 h264e_rkv_cqm_flat16[64] = { - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16 -}; -static const RK_U8 * const h264e_rkv_cqm_jvt[8] = { - h264e_rkv_cqm_jvt4i, h264e_rkv_cqm_jvt4p, - h264e_rkv_cqm_jvt4i, h264e_rkv_cqm_jvt4p, - h264e_rkv_cqm_jvt8i, h264e_rkv_cqm_jvt8p, - h264e_rkv_cqm_jvt8i, h264e_rkv_cqm_jvt8p -}; - -/* zigzags are transposed with respect to the tables in the standard */ -static const RK_U8 h264e_rkv_zigzag_scan4[2][16] = { - { - // frame - 0, 4, 1, 2, 5, 8, 12, 9, 6, 3, 7, 10, 13, 14, 11, 15 - }, - { - // field - 0, 1, 4, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 - } -}; -static const RK_U8 h264e_rkv_zigzag_scan8[2][64] = { - { - 0, 8, 1, 2, 9, 16, 24, 17, 10, 3, 4, 11, 18, 25, 32, 40, - 33, 26, 19, 12, 5, 6, 13, 20, 27, 34, 41, 48, 56, 49, 42, 35, - 28, 21, 14, 7, 15, 22, 29, 36, 43, 50, 57, 58, 51, 44, 37, 30, - 23, 31, 38, 45, 52, 59, 60, 53, 46, 39, 47, 54, 61, 62, 55, 63 - }, - { - 0, 1, 2, 8, 9, 3, 4, 10, 16, 11, 5, 6, 7, 12, 17, 24, - 18, 13, 14, 15, 19, 25, 32, 26, 20, 21, 22, 23, 27, 33, 40, 34, - 28, 29, 30, 31, 35, 41, 48, 42, 36, 37, 38, 39, 43, 49, 50, 44, - 45, 46, 47, 51, 56, 57, 52, 53, 54, 55, 58, 59, 60, 61, 62, 63 - } -}; - #if RKVENC_DUMP_INFO static RK_U32 reg_idx2addr_map[132] = { 0xffff, //0, unvalid. @@ -294,156 +223,6 @@ static RK_U32 reg_idx2addr_map[132] = { }; #endif -static h264e_hal_rkv_csp_info hal_h264e_rkv_convert_csp(RK_S32 src_type) -{ - MppFrameFormat src_fmt = (MppFrameFormat)src_type; - h264e_hal_rkv_csp_info dst_info; - switch (src_fmt) { - case MPP_FMT_YUV420P: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_YUV420P; - dst_info.cswap = 0; - dst_info.aswap = 0; - break; - } - case MPP_FMT_YUV420SP: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_YUV420SP; - dst_info.cswap = 0; - dst_info.aswap = 0; - break; - } - case MPP_FMT_YUV420SP_10BIT: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_NONE; - dst_info.cswap = 0; - dst_info.aswap = 0; - break; - } - case MPP_FMT_YUV420SP_VU: { //TODO: to be confirmed - dst_info.fmt = (RK_U32)H264E_RKV_CSP_YUV420SP; - dst_info.cswap = 1; - dst_info.aswap = 0; - break; - } - case MPP_FMT_YUV422P: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_YUV422P; - dst_info.cswap = 0; - dst_info.aswap = 0; - break; - } - case MPP_FMT_YUV422SP: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_YUV422SP; - dst_info.cswap = 0; - dst_info.aswap = 0; - break; - } - case MPP_FMT_YUV422SP_10BIT: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_NONE; - dst_info.cswap = 0; - dst_info.aswap = 0; - break; - } - case MPP_FMT_YUV422SP_VU: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_YUV422SP; - dst_info.cswap = 1; - dst_info.aswap = 0; - break; - } - case MPP_FMT_YUV422_YUYV: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_YUYV422; - dst_info.cswap = 0; - dst_info.aswap = 0; - break; - } - case MPP_FMT_YUV422_UYVY: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_UYVY422; - dst_info.cswap = 0; - dst_info.aswap = 0; - break; - } - case MPP_FMT_RGB565: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_BGR565; - dst_info.cswap = 1; - dst_info.aswap = 0; - break; - } - case MPP_FMT_BGR565: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_BGR565; - dst_info.cswap = 0; - dst_info.aswap = 0; - break; - } - case MPP_FMT_RGB555: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_NONE; - dst_info.cswap = 0; - dst_info.aswap = 0; - break; - } - case MPP_FMT_BGR555: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_NONE; - dst_info.cswap = 0; - dst_info.aswap = 0; - break; - } - case MPP_FMT_RGB444: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_NONE; - dst_info.cswap = 0; - dst_info.aswap = 0; - break; - } - case MPP_FMT_BGR444: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_NONE; - dst_info.cswap = 0; - dst_info.aswap = 0; - break; - } - case MPP_FMT_RGB888: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_BGR888; - dst_info.cswap = 1; - dst_info.aswap = 0; - break; - } - case MPP_FMT_BGR888: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_BGR888; - dst_info.cswap = 0; - dst_info.aswap = 0; - break; - } - case MPP_FMT_RGB101010: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_NONE; - dst_info.cswap = 0; - dst_info.aswap = 0; - break; - } - case MPP_FMT_BGR101010: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_NONE; - dst_info.cswap = 0; - dst_info.aswap = 0; - break; - } - case MPP_FMT_ARGB8888: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_BGRA8888; - dst_info.cswap = 1; - dst_info.aswap = 1; - break; - } - case MPP_FMT_ABGR8888: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_BGRA8888; - dst_info.cswap = 0; - dst_info.aswap = 1; - break; - } - default: { - h264e_hal_log_err("unvalid src color space: %d", src_type); - dst_info.fmt = (RK_U32)H264E_RKV_CSP_NONE; - dst_info.cswap = 0; - dst_info.aswap = 0; - } - } - - return dst_info; -} - - - static MPP_RET hal_h264e_rkv_close_dump_files(void *dump_files) { h264e_hal_rkv_dump_files *files = (h264e_hal_rkv_dump_files *)dump_files; @@ -511,7 +290,7 @@ static MPP_RET hal_h264e_rkv_open_dump_files(void *dump_files) return MPP_OK; } -static void hal_h264e_rkv_dump_mpp_syntax_in(h264e_syntax *syn, h264e_hal_context *ctx) +static void hal_h264e_rkv_dump_mpp_syntax_in(H264eHwCfg *syn, h264e_hal_context *ctx) { #if RKVENC_DUMP_INFO h264e_hal_rkv_dump_files *dump_files = (h264e_hal_rkv_dump_files *)ctx->dump_files; @@ -520,20 +299,20 @@ static void hal_h264e_rkv_dump_mpp_syntax_in(h264e_syntax *syn, h264e_hal_contex //RK_S32 k = 0; fprintf(fp, "#FRAME %d\n", ctx->frame_cnt); - fprintf(fp, "%-16d %s\n", syn->pic_luma_width, "pic_luma_width"); - fprintf(fp, "%-16d %s\n", syn->pic_luma_height, "pic_luma_height"); + fprintf(fp, "%-16d %s\n", syn->width, "pic_luma_width"); + fprintf(fp, "%-16d %s\n", syn->height, "pic_luma_height"); fprintf(fp, "%-16d %s\n", syn->level_idc, "level_idc"); fprintf(fp, "%-16d %s\n", syn->profile_idc, "profile_idc"); - fprintf(fp, "%-16d %s\n", syn->frame_coding_type, "frame_coding_type"); + fprintf(fp, "%-16d %s\n", syn->coding_type, "frame_coding_type"); fprintf(fp, "%-16d %s\n", syn->qp, "swreg10.pic_qp"); - fprintf(fp, "%-16d %s\n", syn->input_image_format, "swreg14.src_cfmt"); + fprintf(fp, "%-16d %s\n", syn->input_format, "swreg14.src_cfmt"); fprintf(fp, "%-16d %s\n", syn->enable_cabac, "swreg59.etpy_mode"); fprintf(fp, "%-16d %s\n", syn->pic_init_qp, "swreg59.pic_init_qp"); fprintf(fp, "%-16d %s\n", syn->chroma_qp_index_offset, "swreg59.cb_ofst"); fprintf(fp, "%-16d %s\n", syn->second_chroma_qp_index_offset, "swreg59.cr_ofst"); - fprintf(fp, "%-16d %s\n", syn->slice_type, "swreg60.sli_type"); + fprintf(fp, "%-16d %s\n", syn->frame_type, "swreg60.sli_type"); fprintf(fp, "%-16d %s\n", syn->pps_id, "swreg60.pps_id"); fprintf(fp, "%-16d %s\n", syn->frame_num, "swreg60.frm_num"); fprintf(fp, "%-16d %s\n", syn->cabac_init_idc, "swreg60.cbc_init_idc"); @@ -716,38 +495,6 @@ static void hal_h264e_rkv_dump_mpp_reg_in(h264e_hal_context *ctx) #endif } -static void hal_h264e_rkv_dump_mpp_extra_info_cfg(h264e_hal_context *ctx, h264e_control_extra_info_cfg *cfg) -{ -#if RKVENC_DUMP_INFO - h264e_hal_rkv_dump_files *dump_files = (h264e_hal_rkv_dump_files *)ctx->dump_files; - FILE *fp = dump_files->fp_mpp_extra_ino_cfg; - if (fp) { - /* common cfg */ - fprintf(fp, "%-16d %s\n", cfg->pic_luma_width, "pic_luma_width"); - fprintf(fp, "%-16d %s\n", cfg->pic_luma_height, "pic_luma_height"); - fprintf(fp, "%-16d %s\n", cfg->enable_cabac, "enable_cabac"); - fprintf(fp, "%-16d %s\n", cfg->transform8x8_mode, "transform8x8_mode"); - fprintf(fp, "%-16d %s\n", cfg->chroma_qp_index_offset, "chroma_qp_index_offset"); - fprintf(fp, "%-16d %s\n", cfg->pic_init_qp, "pic_init_qp"); - //RK_S32 rotation_enable; //0: 0/180 degrees, 1: 90/270 degrees //TODO: add rotation - - /* additional cfg only for rkv */ - fprintf(fp, "%-16d %s\n", cfg->input_image_format, "input_image_format"); - fprintf(fp, "%-16d %s\n", cfg->profile_idc, "profile_idc"); - fprintf(fp, "%-16d %s\n", cfg->level_idc, "level_idc"); //TODO: may be removed later, get from sps/pps instead - fprintf(fp, "%-16d %s\n", cfg->keyframe_max_interval, "keyframe_max_interval"); - fprintf(fp, "%-16d %s\n", cfg->second_chroma_qp_index_offset, "second_chroma_qp_index_offset"); - fprintf(fp, "%-16d %s\n", cfg->pps_id, "pps_id"); //TODO: may be removed later, get from sps/pps instead - - fprintf(fp, "\n"); - fflush(fp); - } -#else - (void)ctx; - (void)cfg; -#endif -} - static void hal_h264e_rkv_dump_mpp_reg_out(h264e_hal_context *ctx) { #if RKVENC_DUMP_INFO @@ -1248,7 +995,7 @@ static MPP_RET hal_h264e_rkv_reference_update( h264e_hal_context *ctx) -static MPP_RET hal_h264e_rkv_reference_frame_set( h264e_hal_context *ctx, h264e_syntax *syn) +static MPP_RET hal_h264e_rkv_reference_frame_set( h264e_hal_context *ctx, H264eHwCfg *syn) { RK_U32 i_nal_type = 0, i_nal_ref_idc = 0; RK_S32 list = 0, k = 0; @@ -1268,14 +1015,14 @@ static MPP_RET hal_h264e_rkv_reference_frame_set( h264e_hal_context *ctx, h264e_ dpb_ctx->i_max_ref0 = ref_cfg->i_frame_reference; dpb_ctx->i_max_ref1 = H264E_HAL_MIN( sps->vui.i_num_reorder_frames, ref_cfg->i_frame_reference ); - if (syn->frame_coding_type == RKVENC_FRAME_TYPE_IDR) { + if (syn->coding_type == RKVENC_CODING_TYPE_IDR) { dpb_ctx->i_frame_num = 0; dpb_ctx->frames.i_last_idr = dpb_ctx->i_frame_cnt; } dpb_ctx->fdec->i_frame_cnt = dpb_ctx->i_frame_cnt; dpb_ctx->fdec->i_frame_num = dpb_ctx->i_frame_num; - dpb_ctx->fdec->i_frame_type = syn->frame_coding_type; + dpb_ctx->fdec->i_frame_type = syn->coding_type; dpb_ctx->fdec->i_poc = 2 * ( dpb_ctx->fdec->i_frame_cnt - H264E_HAL_MAX( dpb_ctx->frames.i_last_idr, 0 ) ); @@ -1287,7 +1034,7 @@ static MPP_RET hal_h264e_rkv_reference_frame_set( h264e_hal_context *ctx, h264e_ /* No valid reference frames left: force an IDR. */ if ( !valid_refs_left ) { dpb_ctx->fdec->b_keyframe = 1; - dpb_ctx->fdec->i_frame_type = RKVENC_FRAME_TYPE_IDR; + dpb_ctx->fdec->i_frame_type = RKVENC_CODING_TYPE_IDR; } } if ( dpb_ctx->fdec->b_keyframe ) @@ -1300,21 +1047,21 @@ static MPP_RET hal_h264e_rkv_reference_frame_set( h264e_hal_context *ctx, h264e_ dpb_ctx->b_ref_pic_list_reordering[1] = 0; /* calculate nal type and nal ref idc */ - if (syn->frame_coding_type == RKVENC_FRAME_TYPE_IDR) { //TODO: extend syn->frame_coding_type definition + if (syn->coding_type == RKVENC_CODING_TYPE_IDR) { //TODO: extend syn->frame_coding_type definition /* reset ref pictures */ i_nal_type = RKVENC_NAL_SLICE_IDR; i_nal_ref_idc = RKVENC_NAL_PRIORITY_HIGHEST; dpb_ctx->i_slice_type = H264E_HAL_SLICE_TYPE_I; hal_h264e_rkv_reference_reset(dpb_ctx); - } else if ( syn->frame_coding_type == RKVENC_FRAME_TYPE_I ) { + } else if ( syn->coding_type == RKVENC_CODING_TYPE_I ) { i_nal_type = RKVENC_NAL_SLICE; i_nal_ref_idc = RKVENC_NAL_PRIORITY_HIGH; /* Not completely true but for now it is (as all I/P are kept as ref)*/ dpb_ctx->i_slice_type = H264E_HAL_SLICE_TYPE_I; - } else if ( syn->frame_coding_type == RKVENC_FRAME_TYPE_P ) { + } else if ( syn->coding_type == RKVENC_CODING_TYPE_P ) { i_nal_type = RKVENC_NAL_SLICE; i_nal_ref_idc = RKVENC_NAL_PRIORITY_HIGH; /* Not completely true but for now it is (as all I/P are kept as ref)*/ dpb_ctx->i_slice_type = H264E_HAL_SLICE_TYPE_P; - } else if ( syn->frame_coding_type == RKVENC_FRAME_TYPE_BREF ) { + } else if ( syn->coding_type == RKVENC_CODING_TYPE_BREF ) { i_nal_type = RKVENC_NAL_SLICE; i_nal_ref_idc = RKVENC_NAL_PRIORITY_HIGH; dpb_ctx->i_slice_type = H264E_HAL_SLICE_TYPE_B; @@ -1462,17 +1209,17 @@ static MPP_RET hal_h264e_rkv_free_buffers(h264e_hal_context *ctx) return MPP_OK; } -static MPP_RET hal_h264e_rkv_allocate_buffers(h264e_hal_context *ctx, h264e_syntax *syn, h264e_hal_rkv_coveragetest_cfg *test_cfg) +static MPP_RET hal_h264e_rkv_allocate_buffers(h264e_hal_context *ctx, H264eHwCfg *syn, h264e_hal_rkv_coveragetest_cfg *test_cfg) { RK_S32 k = 0; h264e_hal_rkv_buffers *buffers = (h264e_hal_rkv_buffers *)ctx->buffers; - RK_U32 num_mbs_oneframe = (syn->pic_luma_width + 15) / 16 * ((syn->pic_luma_height + 15) / 16); - RK_U32 frame_size = ((syn->pic_luma_width + 15) & (~15)) * ((syn->pic_luma_height + 15) & (~15)); //only Y component + RK_U32 num_mbs_oneframe = (syn->width + 15) / 16 * ((syn->height + 15) / 16); + RK_U32 frame_size = ((syn->width + 15) & (~15)) * ((syn->height + 15) & (~15)); //only Y component h264e_hal_rkv_dpb_ctx *dpb_ctx = (h264e_hal_rkv_dpb_ctx *)ctx->dpb_ctx; h264e_hal_rkv_frame *frame_buf = dpb_ctx->frame_buf; h264e_hal_debug_enter(); - switch ((h264e_hal_rkv_csp)syn->input_image_format) { + switch ((h264e_hal_rkv_csp)syn->input_format) { case H264E_RKV_CSP_YUV420P: case H264E_RKV_CSP_YUV420SP: { frame_size = frame_size * 3 / 2; @@ -1495,7 +1242,7 @@ static MPP_RET hal_h264e_rkv_allocate_buffers(h264e_hal_context *ctx, h264e_synt break; } default: { - h264e_hal_log_err("unvalid src color space: %d, return early", syn->input_image_format); + h264e_hal_log_err("unvalid src color space: %d, return early", syn->input_format); return MPP_NOK; } } @@ -1528,7 +1275,7 @@ static MPP_RET hal_h264e_rkv_allocate_buffers(h264e_hal_context *ctx, h264e_synt } #if 0 //default setting - RK_U32 num_mei_oneframe = (syn->pic_luma_width + 255) / 256 * ((syn->pic_luma_height + 15) / 16); + RK_U32 num_mei_oneframe = (syn->width + 255) / 256 * ((syn->height + 15) / 16); for (k = 0; k < RKV_H264E_LINKTABLE_FRAME_NUM; k++) { if (MPP_OK != mpp_buffer_get(buffers->hw_buf_grp[H264E_HAL_RKV_BUF_GRP_MEI], &buffers->hw_mei_buf[k], num_mei_oneframe * 16 * 4)) { h264e_hal_log_err("hw_mei_buf[%d] get failed", k); @@ -1567,215 +1314,17 @@ static MPP_RET hal_h264e_rkv_allocate_buffers(h264e_hal_context *ctx, h264e_synt return MPP_OK; } -static void hal_h264e_rkv_set_param(h264e_hal_param *p) -{ - h264e_hal_vui_param *vui = &p->vui; - h264e_hal_ref_param *ref = &p->ref; - - p->constrained_intra = 0; - - vui->i_sar_height = 0; - vui->i_sar_width = 0; - vui->i_overscan = 0; - vui->i_vidformat = 5; - vui->b_fullrange = 0; - vui->i_colorprim = 2; - vui->i_transfer = 2; - vui->i_colmatrix = -1; - vui->i_chroma_loc = 0; - - ref->i_frame_reference = RKV_H264E_NUM_REFS; - ref->i_dpb_size = RKV_H264E_NUM_REFS; - ref->i_ref_pos = 1; - ref->i_long_term_en = RKV_H264E_LONGTERM_REF_EN; - ref->hw_longterm_mode = 0; - ref->i_long_term_internal = 0; - ref->i_frame_packing = -1; -} - static void hal_h264e_rkv_adjust_param(h264e_hal_context *ctx) { h264e_hal_param *par = &ctx->param; (void)par; } -MPP_RET hal_h264e_rkv_set_sps(h264e_hal_sps *sps, h264e_hal_param *par, h264e_control_extra_info_cfg *cfg) -{ - h264e_hal_vui_param vui = par->vui; - h264e_hal_ref_param ref_cfg = par->ref; - RK_S32 max_frame_num = 0; - - //default settings - RK_S32 i_bframe_pyramid = 0; - RK_S32 i_bframe = 0; - RK_S32 b_intra_refresh = 0; - RK_S32 Log2MaxFrameNum = 16; - RK_S32 Sw_log2_max_pic_order_cnt_lsb_minus4 = 12; - RK_S32 b_interlaced = 0; - RK_S32 b_fake_interlaced = 0; - RK_S32 crop_rect_left = 0; - RK_S32 crop_rect_right = 0; - RK_S32 crop_rect_top = 0; - RK_S32 crop_rect_bottom = 0; - RK_S32 i_timebase_num = 1; - RK_S32 i_timebase_den = cfg->frame_rate; - RK_S32 b_vfr_input = 0; - RK_S32 i_nal_hrd = 0; - RK_S32 b_pic_struct = 0; - RK_S32 analyse_mv_range = 128; //TODO: relative to level_idc, transplant x264_validate_levels. - h264e_hal_rkv_csp_info csp_info = hal_h264e_rkv_convert_csp(cfg->input_image_format); - RK_S32 csp = h264e_csp_idx_map[csp_info.fmt] & RKV_H264E_CSP2_MASK; - RK_S32 i_dpb_size = ref_cfg.i_dpb_size; - RK_S32 i_frame_reference = ref_cfg.i_frame_reference; - - sps->i_id = 0; - sps->i_mb_width = ( cfg->pic_luma_width + 15 ) / 16; - sps->i_mb_height = ( cfg->pic_luma_height + 15 ) / 16; - sps->i_chroma_format_idc = csp >= RKV_H264E_CSP2_I444 ? RKV_H264E_CHROMA_444 : - csp >= RKV_H264E_CSP2_I422 ? RKV_H264E_CHROMA_422 : RKV_H264E_CHROMA_420; - - sps->b_qpprime_y_zero_transform_bypass = 0; //param->rc.i_rc_method == X264_RC_CQP && param->rc.i_qp_constant == 0; - sps->i_profile_idc = cfg->profile_idc; - - sps->b_constraint_set0 = 0; //sps->i_profile_idc == H264_PROFILE_BASELINE; - /* x264 doesn't support the features that are in Baseline and not in Main, - * namely arbitrary_slice_order and slice_groups. */ - sps->b_constraint_set1 = 0; //sps->i_profile_idc <= H264_PROFILE_MAIN; - /* Never set constraint_set2, it is not necessary and not used in real world. */ - sps->b_constraint_set2 = 0; - sps->b_constraint_set3 = 0; - - sps->i_level_idc = cfg->level_idc; - if ( cfg->level_idc == 9 && ( sps->i_profile_idc == H264_PROFILE_BASELINE || sps->i_profile_idc == H264_PROFILE_MAIN ) ) { - mpp_log_f("warnings: for profile %d, change level from 9(that is 1b) to 11", sps->i_profile_idc); - sps->i_level_idc = 11; - } - - sps->vui.i_num_reorder_frames = i_bframe_pyramid ? 2 : i_bframe ? 1 : 0; - /* extra slot with pyramid so that we don't have to override the - * order of forgetting old pictures */ - sps->vui.i_max_dec_frame_buffering = - sps->i_num_ref_frames = H264E_HAL_MIN(H264E_REF_MAX, H264E_HAL_MAX4(i_frame_reference, 1 + sps->vui.i_num_reorder_frames, - i_bframe_pyramid ? 4 : 1, i_dpb_size)); //TODO: multi refs - sps->i_num_ref_frames -= i_bframe_pyramid == RKV_H264E_B_PYRAMID_STRICT; //TODO: multi refs - if ( cfg->keyframe_max_interval == 1 ) { - sps->i_num_ref_frames = 0; - sps->vui.i_max_dec_frame_buffering = 0; - } - - /* number of refs + current frame */ - max_frame_num = sps->vui.i_max_dec_frame_buffering * (!!i_bframe_pyramid + 1) + 1; - /* Intra refresh cannot write a recovery time greater than max frame num-1 */ - if (b_intra_refresh ) { - RK_S32 time_to_recovery = H264E_HAL_MIN( sps->i_mb_width - 1, cfg->keyframe_max_interval) + i_bframe - 1; - max_frame_num = H264E_HAL_MAX( max_frame_num, time_to_recovery + 1 ); - } - - sps->i_log2_max_frame_num = Log2MaxFrameNum;//fix by gsl org 16, at least 4 - while ( (1 << sps->i_log2_max_frame_num) <= max_frame_num ) - sps->i_log2_max_frame_num++; - - sps->i_poc_type = 0; - - if ( sps->i_poc_type == 0 ) { - RK_S32 max_delta_poc = (i_bframe + 2) * (!!i_bframe_pyramid + 1) * 2; - sps->i_log2_max_poc_lsb = Sw_log2_max_pic_order_cnt_lsb_minus4 + 4; - while ( (1 << sps->i_log2_max_poc_lsb) <= max_delta_poc * 2 ) - sps->i_log2_max_poc_lsb++; - } - - sps->b_vui = 1; - - sps->b_gaps_in_frame_num_value_allowed = 0; - sps->b_frame_mbs_only = !(b_interlaced || b_fake_interlaced); - if ( !sps->b_frame_mbs_only ) - sps->i_mb_height = ( sps->i_mb_height + 1 ) & ~1; - sps->b_mb_adaptive_frame_field = b_interlaced; - sps->b_direct8x8_inference = 1; - - sps->crop.i_left = crop_rect_left; - sps->crop.i_top = crop_rect_top; - sps->crop.i_right = crop_rect_right + sps->i_mb_width * 16 - cfg->pic_luma_width; - sps->crop.i_bottom = (crop_rect_bottom + sps->i_mb_height * 16 - cfg->pic_luma_height) >> !sps->b_frame_mbs_only; - sps->b_crop = sps->crop.i_left || sps->crop.i_top || - sps->crop.i_right || sps->crop.i_bottom; - - sps->vui.b_aspect_ratio_info_present = 0; - if (vui.i_sar_width > 0 && vui.i_sar_height > 0 ) { - sps->vui.b_aspect_ratio_info_present = 1; - sps->vui.i_sar_width = vui.i_sar_width; - sps->vui.i_sar_height = vui.i_sar_height; - } - - sps->vui.b_overscan_info_present = vui.i_overscan > 0 && vui.i_overscan <= 2; - if ( sps->vui.b_overscan_info_present ) - sps->vui.b_overscan_info = ( vui.i_overscan == 2 ? 1 : 0 ); - - sps->vui.b_signal_type_present = 0; - sps->vui.i_vidformat = ( vui.i_vidformat >= 0 && vui.i_vidformat <= 5 ? vui.i_vidformat : 5 ); - sps->vui.b_fullrange = ( vui.b_fullrange >= 0 && vui.b_fullrange <= 1 ? vui.b_fullrange : - ( csp >= RKV_H264E_CSP2_BGR ? 1 : 0 ) ); - sps->vui.b_color_description_present = 0; - - sps->vui.i_colorprim = ( vui.i_colorprim >= 0 && vui.i_colorprim <= 9 ? vui.i_colorprim : 2 ); - sps->vui.i_transfer = ( vui.i_transfer >= 0 && vui.i_transfer <= 15 ? vui.i_transfer : 2 ); - sps->vui.i_colmatrix = ( vui.i_colmatrix >= 0 && vui.i_colmatrix <= 10 ? vui.i_colmatrix : - ( csp >= RKV_H264E_CSP2_BGR ? 0 : 2 ) ); - if ( sps->vui.i_colorprim != 2 || - sps->vui.i_transfer != 2 || - sps->vui.i_colmatrix != 2 ) { - sps->vui.b_color_description_present = 1; - } - - if ( sps->vui.i_vidformat != 5 || - sps->vui.b_fullrange || - sps->vui.b_color_description_present ) { - sps->vui.b_signal_type_present = 1; - } - - /* FIXME: not sufficient for interlaced video */ - sps->vui.b_chroma_loc_info_present = vui.i_chroma_loc > 0 && vui.i_chroma_loc <= 5 && - sps->i_chroma_format_idc == RKV_H264E_CHROMA_420; - if ( sps->vui.b_chroma_loc_info_present ) { - sps->vui.i_chroma_loc_top = vui.i_chroma_loc; - sps->vui.i_chroma_loc_bottom = vui.i_chroma_loc; - } - - sps->vui.b_timing_info_present = i_timebase_num > 0 && i_timebase_den > 0; - - if ( sps->vui.b_timing_info_present ) { - sps->vui.i_num_units_in_tick = i_timebase_num; - sps->vui.i_time_scale = i_timebase_den * 2; - sps->vui.b_fixed_frame_rate = !b_vfr_input; - } - - sps->vui.b_vcl_hrd_parameters_present = 0; // we don't support VCL HRD - sps->vui.b_nal_hrd_parameters_present = !!i_nal_hrd; - sps->vui.b_pic_struct_present = b_pic_struct; - - // NOTE: HRD related parts of the SPS are initialised in x264_ratecontrol_init_reconfigurable - - sps->vui.b_bitstream_restriction = cfg->keyframe_max_interval > 1; - if ( sps->vui.b_bitstream_restriction ) { - sps->vui.b_motion_vectors_over_pic_boundaries = 1; - sps->vui.i_max_bytes_per_pic_denom = 0; - sps->vui.i_max_bits_per_mb_denom = 0; - sps->vui.i_log2_max_mv_length_horizontal = - sps->vui.i_log2_max_mv_length_vertical = (RK_S32)log2f((float)H264E_HAL_MAX( 1, analyse_mv_range * 4 - 1 ) ) + 1; - } - - /* only for backup, excluded in read SPS */ - sps->keyframe_max_interval = cfg->keyframe_max_interval; - return MPP_OK; -} - - RK_S32 hal_h264e_rkv_stream_get_pos(h264e_hal_rkv_stream *s) { return (RK_S32)(8 * (s->p - s->p_start) + (4 * 8) - s->i_left); } - MPP_RET hal_h264e_rkv_stream_init(h264e_hal_rkv_stream *s) { RK_S32 offset = 0; @@ -2096,35 +1645,39 @@ MPP_RET hal_h264e_rkv_encapsulate_nals(h264e_hal_rkv_extra_info *out) return MPP_OK; } -static MPP_RET hal_h264e_rkv_sei_pack2str(char *str, h264e_hal_rkv_extra_info *extra_info) +static MPP_RET hal_h264e_rkv_sei_pack2str(char *str, h264e_hal_context *ctx) { - h264e_hal_sei *sei = &extra_info->sei; - h264e_control_extra_info_cfg *extra_info_cfg = &sei->extra_info_cfg; - MppEncRcCfg *rc_cfg = &sei->rc_cfg; + h264e_hal_rkv_extra_info *info = (h264e_hal_rkv_extra_info *)ctx->extra_info; + h264e_hal_sps *sps = &info->sps; + h264e_hal_pps *pps = &info->pps; + MppEncCfgSet *cfg = ctx->cfg; + MppEncPrepCfg *prep = &cfg->prep; + MppEncRcCfg *rc_cfg = &cfg->rc; + h264e_hal_debug_enter(); - H264E_HAL_SPRINT(str, "frame %d rkvenc_cfg: ", sei->frame_cnt); + H264E_HAL_SPRINT(str, "frame %d rkvenc_cfg: ", ctx->frame_cnt); - if (extra_info->sei_change_flg & H264E_SEI_CHG_SPSPPS) { + if (info->sei_change_flg & H264E_SEI_CHG_SPSPPS) { h264e_hal_log_sei("write sei extra_info_cfg"); H264E_HAL_SPRINT(str, "extra_info: "); - H264E_HAL_SPRINT(str, "pic_w %d ", extra_info_cfg->pic_luma_width); - H264E_HAL_SPRINT(str, "pic_h %d ", extra_info_cfg->pic_luma_height); - H264E_HAL_SPRINT(str, "en_cabac %d ", extra_info_cfg->enable_cabac); - H264E_HAL_SPRINT(str, "t8x8 %d ", extra_info_cfg->transform8x8_mode); - H264E_HAL_SPRINT(str, "cb_qp_ofst %d ", extra_info_cfg->chroma_qp_index_offset); - H264E_HAL_SPRINT(str, "pic_init_qp %d ", extra_info_cfg->pic_init_qp); - H264E_HAL_SPRINT(str, "fps %d ", extra_info_cfg->frame_rate); - H264E_HAL_SPRINT(str, "src_fmt %d ", extra_info_cfg->input_image_format); - H264E_HAL_SPRINT(str, "profile %d ", extra_info_cfg->profile_idc); - H264E_HAL_SPRINT(str, "level %d ", extra_info_cfg->level_idc); - H264E_HAL_SPRINT(str, "key_interval %d ", extra_info_cfg->keyframe_max_interval); - H264E_HAL_SPRINT(str, "cr_qp_ofst %d ", extra_info_cfg->second_chroma_qp_index_offset); - H264E_HAL_SPRINT(str, "pps_id %d ", extra_info_cfg->pps_id); - extra_info->sei_change_flg &= ~H264E_SEI_CHG_SPSPPS; + H264E_HAL_SPRINT(str, "pic_w %d ", prep->width); + H264E_HAL_SPRINT(str, "pic_h %d ", prep->height); + H264E_HAL_SPRINT(str, "en_cabac %d ", pps->b_cabac); + H264E_HAL_SPRINT(str, "t8x8 %d ", pps->b_transform_8x8_mode); + H264E_HAL_SPRINT(str, "cb_qp_ofst %d ", pps->i_chroma_qp_index_offset); + H264E_HAL_SPRINT(str, "pic_init_qp %d ", pps->i_pic_init_qp); + H264E_HAL_SPRINT(str, "fps %d ", rc_cfg->fps_in_num / rc_cfg->fps_in_denorm); + H264E_HAL_SPRINT(str, "src_fmt %d ", prep->format); + H264E_HAL_SPRINT(str, "profile %d ", sps->i_profile_idc); + H264E_HAL_SPRINT(str, "level %d ", sps->i_level_idc); + H264E_HAL_SPRINT(str, "key_interval %d ", sps->keyframe_max_interval); + H264E_HAL_SPRINT(str, "cr_qp_ofst %d ", pps->i_second_chroma_qp_index_offset); + H264E_HAL_SPRINT(str, "pps_id %d ", pps->i_id); + info->sei_change_flg &= ~H264E_SEI_CHG_SPSPPS; } - if (extra_info->sei_change_flg & H264E_SEI_CHG_RC) { + if (info->sei_change_flg & H264E_SEI_CHG_RC) { h264e_hal_log_sei("write sei rc_cfg"); H264E_HAL_SPRINT(str, "rc: "); H264E_HAL_SPRINT(str, "mode %d ", rc_cfg->rc_mode); @@ -2132,11 +1685,11 @@ static MPP_RET hal_h264e_rkv_sei_pack2str(char *str, h264e_hal_rkv_extra_info *e H264E_HAL_SPRINT(str, "bps_tgt %d ", rc_cfg->bps_target); H264E_HAL_SPRINT(str, "bps_max %d ", rc_cfg->bps_max); H264E_HAL_SPRINT(str, "bps_min %d ", rc_cfg->bps_min); - H264E_HAL_SPRINT(str, "fps_in %d ", rc_cfg->fps_in); - H264E_HAL_SPRINT(str, "fps_out %d ", rc_cfg->fps_out); + H264E_HAL_SPRINT(str, "fps_in %d ", rc_cfg->fps_in_num / rc_cfg->fps_in_denorm); + H264E_HAL_SPRINT(str, "fps_out %d ", rc_cfg->fps_out_num / rc_cfg->fps_out_denorm); H264E_HAL_SPRINT(str, "gop %d ", rc_cfg->gop); H264E_HAL_SPRINT(str, "skip_cnt %d ", rc_cfg->skip_cnt); - extra_info->sei_change_flg &= ~H264E_SEI_CHG_RC; + info->sei_change_flg &= ~H264E_SEI_CHG_RC; } h264e_hal_debug_leave(); @@ -2172,12 +1725,13 @@ static MPP_RET hal_h264e_rkv_sei_write(h264e_hal_rkv_stream *s, RK_U8 *payload, return MPP_OK; } -MPP_RET hal_h264e_rkv_sei_encode(h264e_hal_rkv_extra_info *info) +MPP_RET hal_h264e_rkv_sei_encode(h264e_hal_context *ctx) { + h264e_hal_rkv_extra_info *info = (h264e_hal_rkv_extra_info *)ctx->extra_info; char *str = (char *)info->sei_buf; RK_S32 str_len = 0; - hal_h264e_rkv_sei_pack2str(str + H264E_UUID_LENGTH, info); + hal_h264e_rkv_sei_pack2str(str + H264E_UUID_LENGTH, ctx); str_len = strlen(str) + 1; if (str_len > H264E_SEI_BUF_SIZE) { @@ -2211,7 +1765,7 @@ MPP_RET hal_h264e_rkv_sps_write(h264e_hal_sps *sps, h264e_hal_rkv_stream *s) if (sps->i_profile_idc >= H264_PROFILE_HIGH) { hal_h264e_rkv_stream_write_ue_with_log(s, sps->i_chroma_format_idc, "chroma_format_idc"); - if (sps->i_chroma_format_idc == RKV_H264E_CHROMA_444) + if (sps->i_chroma_format_idc == H264E_CHROMA_444) hal_h264e_rkv_stream_write1_with_log(s, 0, "separate_colour_plane_flag"); hal_h264e_rkv_stream_write_ue_with_log(s, H264_BIT_DEPTH - 8, "bit_depth_luma_minus8"); hal_h264e_rkv_stream_write_ue_with_log(s, H264_BIT_DEPTH - 8, "bit_depth_chroma_minus8"); @@ -2220,7 +1774,7 @@ MPP_RET hal_h264e_rkv_sps_write(h264e_hal_sps *sps, h264e_hal_rkv_stream *s) } hal_h264e_rkv_stream_write_ue_with_log(s, sps->i_log2_max_frame_num - 4, "log2_max_frame_num_minus4"); - hal_h264e_rkv_stream_write_ue_with_log(s, sps->i_poc_type, "delta_pic_order_always_zero_flag"); + hal_h264e_rkv_stream_write_ue_with_log(s, sps->i_poc_type, "pic_order_cnt_type"); if (sps->i_poc_type == 0) hal_h264e_rkv_stream_write_ue_with_log(s, sps->i_log2_max_poc_lsb - 4, "log2_max_pic_order_cnt_lsb_minus4"); hal_h264e_rkv_stream_write_ue_with_log(s, sps->i_num_ref_frames, "max_num_ref_frames"); @@ -2234,16 +1788,16 @@ MPP_RET hal_h264e_rkv_sps_write(h264e_hal_sps *sps, h264e_hal_rkv_stream *s) hal_h264e_rkv_stream_write1_with_log(s, sps->b_crop, "frame_cropping_flag"); if (sps->b_crop) { - RK_S32 h_shift = sps->i_chroma_format_idc == RKV_H264E_CHROMA_420 || sps->i_chroma_format_idc == RKV_H264E_CHROMA_422; - RK_S32 v_shift = sps->i_chroma_format_idc == RKV_H264E_CHROMA_420; + RK_S32 h_shift = sps->i_chroma_format_idc == H264E_CHROMA_420 || sps->i_chroma_format_idc == H264E_CHROMA_422; + RK_S32 v_shift = sps->i_chroma_format_idc == H264E_CHROMA_420; hal_h264e_rkv_stream_write_ue_with_log(s, sps->crop.i_left >> h_shift, "frame_crop_left_offset"); hal_h264e_rkv_stream_write_ue_with_log(s, sps->crop.i_right >> h_shift, "frame_crop_right_offset"); hal_h264e_rkv_stream_write_ue_with_log(s, sps->crop.i_top >> v_shift, "frame_crop_top_offset"); hal_h264e_rkv_stream_write_ue_with_log(s, sps->crop.i_bottom >> v_shift, "frame_crop_bottom_offset"); } - hal_h264e_rkv_stream_write1_with_log(s, sps->b_vui, "vui_parameters_present_flag"); - if (sps->b_vui) { + hal_h264e_rkv_stream_write1_with_log(s, sps->vui.b_vui, "vui_parameters_present_flag"); + if (sps->vui.b_vui) { hal_h264e_rkv_stream_write1_with_log(s, sps->vui.b_aspect_ratio_info_present, "aspect_ratio_info_present_flag"); if (sps->vui.b_aspect_ratio_info_present) { RK_S32 i = 0; @@ -2328,7 +1882,7 @@ MPP_RET hal_h264e_rkv_sps_write(h264e_hal_sps *sps, h264e_hal_rkv_stream *s) hal_h264e_rkv_stream_write_ue_with_log(s, sps->vui.i_log2_max_mv_length_horizontal, "log2_max_mv_length_horizontal"); hal_h264e_rkv_stream_write_ue_with_log(s, sps->vui.i_log2_max_mv_length_vertical, "log2_max_mv_length_vertical"); hal_h264e_rkv_stream_write_ue_with_log(s, sps->vui.i_num_reorder_frames, "max_num_reorder_frames"); - hal_h264e_rkv_stream_write_ue_with_log(s, sps->vui.i_max_dec_frame_buffering, "max_num_reorder_frames"); + hal_h264e_rkv_stream_write_ue_with_log(s, sps->vui.i_max_dec_frame_buffering, "max_dec_frame_buffering"); } } hal_h264e_rkv_stream_rbsp_trailing(s); @@ -2341,106 +1895,20 @@ MPP_RET hal_h264e_rkv_sps_write(h264e_hal_sps *sps, h264e_hal_rkv_stream *s) return MPP_OK; } - -/* -static void transpose( RK_U8 *buf, RK_S32 w ) -{ - RK_S32 i=0, j=0; - for(i = 0; i < w; i++ ) - for(j = 0; j < i; j++ ) - MPP_SWAP( RK_U8, buf[w*i+j], buf[w*j+i] ); -} -*/ - -MPP_RET hal_h264e_rkv_set_pps(h264e_hal_pps *pps, h264e_hal_param *par, h264e_control_extra_info_cfg *cfg, h264e_hal_sps *sps) -{ - RK_S32 k = 0; - RK_S32 i_avcintra_class = 0; - RK_S32 b_interlaced = 0; - RK_S32 analyse_weighted_pred = 0; - RK_S32 analyse_b_weighted_bipred = 0; - RK_S32 pps_init_qp = -1; //TODO: merge with syn - RK_S32 Sw_deblock_filter_ctrl_present_flag = 1; - RK_S32 b_cqm_preset = 0; - - pps->i_id = cfg->pps_id; - pps->i_sps_id = sps->i_id; - pps->b_cabac = cfg->enable_cabac; - - pps->b_pic_order = !i_avcintra_class && b_interlaced; - pps->i_num_slice_groups = 1; - - pps->i_num_ref_idx_l0_default_active = 1; - pps->i_num_ref_idx_l1_default_active = 1; - - pps->b_weighted_pred = analyse_weighted_pred > 0; - pps->i_weighted_bipred_idc = analyse_b_weighted_bipred ? 2 : 0; - - pps->i_pic_init_qp = cfg->pic_init_qp; - if (pps_init_qp >= 0 && pps_init_qp <= 51) { - pps->i_pic_init_qp = pps_init_qp; - } - pps->i_pic_init_qs = 26 + H264_QP_BD_OFFSET; - - pps->b_transform_8x8_mode = cfg->transform8x8_mode; - pps->i_chroma_qp_index_offset = cfg->chroma_qp_index_offset; - pps->i_second_chroma_qp_index_offset = cfg->second_chroma_qp_index_offset; - pps->b_deblocking_filter_control = Sw_deblock_filter_ctrl_present_flag; - pps->b_constrained_intra_pred = par->constrained_intra; - pps->b_redundant_pic_cnt = 0; - - if (sps->i_profile_idc < H264_PROFILE_HIGH) { - if (pps->b_transform_8x8_mode) { - pps->b_transform_8x8_mode = 0; - mpp_log_f("wanrning: for profile %d b_transform_8x8_mode should be 0", - sps->i_profile_idc); - } - if (pps->i_second_chroma_qp_index_offset) { - pps->i_second_chroma_qp_index_offset = 0; - mpp_log_f("wanrning: for profile %d i_second_chroma_qp_index_offset should be 0", - sps->i_profile_idc); - } - } - - pps->b_cqm_preset = b_cqm_preset; - - switch ( pps->b_cqm_preset ) { - case RKV_H264E_CQM_FLAT: - for (k = 0; k < 8; k++ ) - pps->scaling_list[k] = h264e_rkv_cqm_flat16; - break; - case RKV_H264E_CQM_JVT: - for (k = 0; k < 8; k++ ) - pps->scaling_list[k] = h264e_rkv_cqm_jvt[k]; - break; - case RKV_H264E_CQM_CUSTOM: - /* match the transposed DCT & zigzag */ - h264e_hal_log_err("CQM_CUSTOM mode is not supported now"); - return MPP_NOK; - //break; - default: - h264e_hal_log_err("invalid cqm_preset mode"); - return MPP_NOK; - //break; - } - - return MPP_OK; -} - static void hal_h264e_rkv_scaling_list_write( h264e_hal_rkv_stream *s, h264e_hal_pps *pps, RK_S32 idx ) { RK_S32 k = 0; const RK_S32 len = idx < 4 ? 16 : 64; - const RK_U8 *zigzag = idx < 4 ? h264e_rkv_zigzag_scan4[0] : h264e_rkv_zigzag_scan8[0]; + const RK_U8 *zigzag = idx < 4 ? h264e_zigzag_scan4[0] : h264e_zigzag_scan8[0]; const RK_U8 *list = pps->scaling_list[idx]; - const RK_U8 *def_list = (idx == RKV_H264E_CQM_4IC) ? pps->scaling_list[RKV_H264E_CQM_4IY] - : (idx == RKV_H264E_CQM_4PC) ? pps->scaling_list[RKV_H264E_CQM_4PY] - : (idx == RKV_H264E_CQM_8IC + 4) ? pps->scaling_list[RKV_H264E_CQM_8IY + 4] - : (idx == RKV_H264E_CQM_8PC + 4) ? pps->scaling_list[RKV_H264E_CQM_8PY + 4] - : h264e_rkv_cqm_jvt[idx]; + const RK_U8 *def_list = (idx == H264E_CQM_4IC) ? pps->scaling_list[H264E_CQM_4IY] + : (idx == H264E_CQM_4PC) ? pps->scaling_list[H264E_CQM_4PY] + : (idx == H264E_CQM_8IC + 4) ? pps->scaling_list[H264E_CQM_8IY + 4] + : (idx == H264E_CQM_8PC + 4) ? pps->scaling_list[H264E_CQM_8PY + 4] + : h264e_cqm_jvt[idx]; if ( !memcmp( list, def_list, len ) ) hal_h264e_rkv_stream_write1_with_log( s, 0, "scaling_list_present_flag"); // scaling_list_present_flag - else if ( !memcmp( list, h264e_rkv_cqm_jvt[idx], len ) ) { + else if ( !memcmp( list, h264e_cqm_jvt[idx], len ) ) { hal_h264e_rkv_stream_write1_with_log( s, 1, "scaling_list_present_flag"); // scaling_list_present_flag hal_h264e_rkv_stream_write_se_with_log( s, -8, "use_jvt_list"); // use jvt list } else { @@ -2489,27 +1957,27 @@ MPP_RET hal_h264e_rkv_pps_write(h264e_hal_pps *pps, h264e_hal_sps *sps, h264e_ha hal_h264e_rkv_stream_write1_with_log( s, pps->b_constrained_intra_pred, "constrained_intra_pred_flag"); hal_h264e_rkv_stream_write1_with_log( s, pps->b_redundant_pic_cnt, "redundant_pic_cnt_present_flag"); - if ( pps->b_transform_8x8_mode || pps->b_cqm_preset != RKV_H264E_CQM_FLAT ) { + if ( pps->b_transform_8x8_mode || pps->b_cqm_preset != H264E_CQM_FLAT ) { hal_h264e_rkv_stream_write1_with_log( s, pps->b_transform_8x8_mode, "transform_8x8_mode_flag"); - hal_h264e_rkv_stream_write1_with_log( s, (pps->b_cqm_preset != RKV_H264E_CQM_FLAT), "pic_scaling_matrix_present_flag"); - if ( pps->b_cqm_preset != RKV_H264E_CQM_FLAT ) { - hal_h264e_rkv_scaling_list_write( s, pps, RKV_H264E_CQM_4IY); - hal_h264e_rkv_scaling_list_write( s, pps, RKV_H264E_CQM_4IC ); + hal_h264e_rkv_stream_write1_with_log( s, (pps->b_cqm_preset != H264E_CQM_FLAT), "pic_scaling_matrix_present_flag"); + if ( pps->b_cqm_preset != H264E_CQM_FLAT ) { + hal_h264e_rkv_scaling_list_write( s, pps, H264E_CQM_4IY); + hal_h264e_rkv_scaling_list_write( s, pps, H264E_CQM_4IC ); hal_h264e_rkv_stream_write1_with_log( s, 0, "scaling_list_end_flag"); // Cr = Cb TODO:replaced with real name - hal_h264e_rkv_scaling_list_write( s, pps, RKV_H264E_CQM_4PY ); - hal_h264e_rkv_scaling_list_write( s, pps, RKV_H264E_CQM_4PC ); + hal_h264e_rkv_scaling_list_write( s, pps, H264E_CQM_4PY ); + hal_h264e_rkv_scaling_list_write( s, pps, H264E_CQM_4PC ); hal_h264e_rkv_stream_write1_with_log( s, 0, "scaling_list_end_flag"); // Cr = Cb TODO:replaced with real name if ( pps->b_transform_8x8_mode ) { - if ( sps->i_chroma_format_idc == RKV_H264E_CHROMA_444 ) { - hal_h264e_rkv_scaling_list_write( s, pps, RKV_H264E_CQM_8IY + 4 ); - hal_h264e_rkv_scaling_list_write( s, pps, RKV_H264E_CQM_8IC + 4 ); + if ( sps->i_chroma_format_idc == H264E_CHROMA_444 ) { + hal_h264e_rkv_scaling_list_write( s, pps, H264E_CQM_8IY + 4 ); + hal_h264e_rkv_scaling_list_write( s, pps, H264E_CQM_8IC + 4 ); hal_h264e_rkv_stream_write1_with_log( s, 0, "scaling_list_end_flag" ); // Cr = Cb TODO:replaced with real name - hal_h264e_rkv_scaling_list_write( s, pps, RKV_H264E_CQM_8PY + 4 ); - hal_h264e_rkv_scaling_list_write( s, pps, RKV_H264E_CQM_8PC + 4 ); + hal_h264e_rkv_scaling_list_write( s, pps, H264E_CQM_8PY + 4 ); + hal_h264e_rkv_scaling_list_write( s, pps, H264E_CQM_8PC + 4 ); hal_h264e_rkv_stream_write1_with_log( s, 0, "scaling_list_end_flag" ); // Cr = Cb TODO:replaced with real name } else { - hal_h264e_rkv_scaling_list_write( s, pps, RKV_H264E_CQM_8IY + 4 ); - hal_h264e_rkv_scaling_list_write( s, pps, RKV_H264E_CQM_8PY + 4 ); + hal_h264e_rkv_scaling_list_write( s, pps, H264E_CQM_8IY + 4 ); + hal_h264e_rkv_scaling_list_write( s, pps, H264E_CQM_8PY + 4 ); } } } @@ -2557,37 +2025,31 @@ static MPP_RET hal_h264e_rkv_deinit_extra_info(void *extra_info) return MPP_OK; } -static MPP_RET hal_h264e_rkv_set_extra_info(h264e_hal_context *ctx, void *param) +static MPP_RET hal_h264e_rkv_set_extra_info(h264e_hal_context *ctx) { - h264e_control_extra_info_cfg *cfg = (h264e_control_extra_info_cfg *)param; - h264e_hal_param *par = &ctx->param; h264e_hal_rkv_extra_info *info = (h264e_hal_rkv_extra_info *)ctx->extra_info; - h264e_hal_sei *sei = &info->sei; - h264e_hal_sps *sps_info = &info->sps; - h264e_hal_pps *pps_info = &info->pps; + h264e_hal_sps *sps = &info->sps; + h264e_hal_pps *pps = &info->pps; h264e_hal_debug_enter(); - hal_h264e_rkv_dump_mpp_extra_info_cfg(ctx, cfg); - - sei->extra_info_cfg = *cfg; info->nal_num = 0; hal_h264e_rkv_stream_reset(&info->stream); hal_h264e_rkv_nal_start(info, RKVENC_NAL_SPS, RKVENC_NAL_PRIORITY_HIGHEST); - hal_h264e_rkv_set_sps(sps_info, par, cfg); - hal_h264e_rkv_sps_write(sps_info, &info->stream); + hal_h264e_set_sps(ctx, sps); + hal_h264e_rkv_sps_write(sps, &info->stream); hal_h264e_rkv_nal_end(info); hal_h264e_rkv_nal_start(info, RKVENC_NAL_PPS, RKVENC_NAL_PRIORITY_HIGHEST); - hal_h264e_rkv_set_pps(pps_info, par, cfg, sps_info); - hal_h264e_rkv_pps_write(pps_info, sps_info, &info->stream); + hal_h264e_set_pps(ctx, pps, sps); + hal_h264e_rkv_pps_write(pps, sps, &info->stream); hal_h264e_rkv_nal_end(info); if (ctx->sei_mode == MPP_ENC_SEI_MODE_ONE_SEQ || ctx->sei_mode == MPP_ENC_SEI_MODE_ONE_FRAME) { info->sei_change_flg |= H264E_SEI_CHG_SPSPPS; hal_h264e_rkv_nal_start(info, RKVENC_NAL_SEI, RKVENC_NAL_PRIORITY_DISPOSABLE); - hal_h264e_rkv_sei_encode(info); + hal_h264e_rkv_sei_encode(ctx); hal_h264e_rkv_nal_end(info); } @@ -2623,7 +2085,7 @@ static MPP_RET hal_h264e_rkv_set_osd_plt(h264e_hal_context *ctx, void *param) if (plt->buf) { ctx->osd_plt_type = 0; #ifdef RKPLATFORM - if (MPP_OK != VPUClientSendReg2(ctx->vpu_socket, H264E_IOC_SET_OSD_PLT, sizeof(MppEncOSDPlt), param)) { + if (MPP_OK != VPUClientSendReg2(ctx->vpu_fd, H264E_IOC_SET_OSD_PLT, sizeof(MppEncOSDPlt), param)) { h264e_hal_log_err("set osd plt error"); return MPP_NOK; } @@ -2695,11 +2157,11 @@ static void hal_h264e_rkv_reference_init( void *dpb, h264e_hal_param *par) MPP_RET hal_h264e_rkv_init(void *hal, MppHalCfg *cfg) { + VPU_CLIENT_TYPE type = VPU_ENC_RKV; h264e_hal_context *ctx = (h264e_hal_context *)hal; h264e_hal_rkv_dpb_ctx *dpb_ctx = NULL; h264e_hal_debug_enter(); - hal_h264e_rkv_set_param(&ctx->param); ctx->ioctl_input = mpp_calloc(h264e_rkv_ioctl_input, 1); ctx->ioctl_output = mpp_calloc(h264e_rkv_ioctl_output, 1); @@ -2725,22 +2187,21 @@ MPP_RET hal_h264e_rkv_init(void *hal, MppHalCfg *cfg) dpb_ctx->i_frame_cnt = 0; dpb_ctx->i_frame_num = 0; - ctx->vpu_socket = -1; - ctx->vpu_client = VPU_ENC_RKV; - h264e_hal_log_detail("vpu client: %d", ctx->vpu_client); + ctx->vpu_fd = -1; + h264e_hal_log_detail("vpu client: %d", type); #ifdef RKPLATFORM - if (ctx->vpu_socket <= 0) { - ctx->vpu_socket = VPUClientInit(ctx->vpu_client); - if (ctx->vpu_socket <= 0) { - h264e_hal_log_err("get vpu_socket(%d) <=0, failed. \n", ctx->vpu_socket); + if (ctx->vpu_fd <= 0) { + ctx->vpu_fd = VPUClientInit(type); + if (ctx->vpu_fd <= 0) { + h264e_hal_log_err("get vpu_socket(%d) <=0, failed. \n", ctx->vpu_fd); return MPP_ERR_UNKNOW; } else { VPUHwEncConfig_t hwCfg; - h264e_hal_log_detail("get vpu_socket(%d), success. \n", ctx->vpu_socket); + h264e_hal_log_detail("get vpu_socket(%d), success. \n", ctx->vpu_fd); memset(&hwCfg, 0, sizeof(VPUHwEncConfig_t)); - if (VPUClientGetHwCfg(ctx->vpu_socket, (RK_U32*)&hwCfg, sizeof(hwCfg))) { + if (VPUClientGetHwCfg(ctx->vpu_fd, (RK_U32*)&hwCfg, sizeof(hwCfg))) { h264e_hal_log_err("h264enc # Get HwCfg failed, release vpu\n"); - VPUClientRelease(ctx->vpu_socket); + VPUClientRelease(ctx->vpu_fd); return MPP_NOK; } } @@ -2787,12 +2248,12 @@ MPP_RET hal_h264e_rkv_deinit(void *hal) } #ifdef RKPLATFORM - if (ctx->vpu_socket <= 0) { - h264e_hal_log_err("invalid vpu socket: %d", ctx->vpu_socket); + if (ctx->vpu_fd <= 0) { + h264e_hal_log_err("invalid vpu socket: %d", ctx->vpu_fd); return MPP_NOK; } - if (VPU_SUCCESS != VPUClientRelease(ctx->vpu_socket)) { + if (VPU_SUCCESS != VPUClientRelease(ctx->vpu_fd)) { h264e_hal_log_err("VPUClientRelease failed"); return MPP_ERR_VPUHW; } @@ -2804,11 +2265,11 @@ MPP_RET hal_h264e_rkv_deinit(void *hal) } -MPP_RET hal_h264e_rkv_set_ioctl_extra_info(h264e_rkv_ioctl_extra_info *extra_info, h264e_syntax *syn, h264e_rkv_reg_set *regs) +MPP_RET hal_h264e_rkv_set_ioctl_extra_info(h264e_rkv_ioctl_extra_info *extra_info, H264eHwCfg *syn, h264e_rkv_reg_set *regs) { h264e_rkv_ioctl_extra_info_elem *info = NULL; RK_U32 hor_stride = regs->swreg23.src_ystrid + 1; - RK_U32 ver_stride = syn->pic_ver_stride ? syn->pic_ver_stride : syn->pic_luma_height; + RK_U32 ver_stride = syn->ver_stride ? syn->ver_stride : syn->height; RK_U32 frame_size = hor_stride * ver_stride; // TODO: according to yuv format extra_info->magic = 0; @@ -2826,38 +2287,12 @@ MPP_RET hal_h264e_rkv_set_ioctl_extra_info(h264e_rkv_ioctl_extra_info *extra_inf return MPP_OK; } -static MPP_RET hal_h264e_rkv_validate_syntax(h264e_syntax *syn, h264e_hal_rkv_csp_info *src_fmt) -{ - RK_U32 input_image_format = syn->input_image_format; - h264e_hal_debug_enter(); - - /* validate */ - H264E_HAL_VALIDATE_GT(syn->output_strm_limit_size, "output_strm_limit_size", 0); - - /* adjust */ - *src_fmt = hal_h264e_rkv_convert_csp(input_image_format); - syn->input_image_format = src_fmt->fmt; - - syn->input_cb_addr = syn->input_luma_addr; - syn->input_cr_addr = syn->input_luma_addr; - - H264E_HAL_VALIDATE_NEQ(syn->input_image_format, "input_image_format", H264E_RKV_CSP_NONE); - if (syn->frame_coding_type == 1) { /* ASIC_INTRA */ - syn->frame_coding_type = RKVENC_FRAME_TYPE_IDR; - } else { /* ASIC_INTER */ - syn->frame_coding_type = RKVENC_FRAME_TYPE_P; - } - - h264e_hal_debug_leave(); - return MPP_OK; -} - -MPP_RET hal_h264e_rkv_set_rc_regs(h264e_hal_context *ctx, h264e_rkv_reg_set *regs, h264e_syntax *syn, +MPP_RET hal_h264e_rkv_set_rc_regs(h264e_hal_context *ctx, h264e_rkv_reg_set *regs, H264eHwCfg *syn, h264e_hal_rkv_coveragetest_cfg *test) { if (test && test->mbrc) { - RK_U32 num_mbs_oneframe = (syn->pic_luma_width + 15) / 16 * ((syn->pic_luma_height + 15) / 16); - RK_U32 frame_target_bitrate = (syn->pic_luma_width * syn->pic_luma_height / 1920 / 1080) * 10000000 / 8; //Bytes + RK_U32 num_mbs_oneframe = (syn->width + 15) / 16 * ((syn->height + 15) / 16); + RK_U32 frame_target_bitrate = (syn->width * syn->height / 1920 / 1080) * 10000000 / 8; //Bytes RK_U32 frame_target_size = frame_target_bitrate / syn->keyframe_max_interval; RK_U32 mb_target_size = frame_target_size / num_mbs_oneframe; RK_U32 aq_strength = 2; @@ -2869,7 +2304,7 @@ MPP_RET hal_h264e_rkv_set_rc_regs(h264e_hal_context *ctx, h264e_rkv_reg_set *reg regs->swreg46.aqmode_en = 1; regs->swreg46.aq_strg = (RK_U32)(aq_strength * 1.0397 * 256); regs->swreg46.Reserved = 0x0; - regs->swreg46.rc_ctu_num = (syn->pic_luma_width + 15) / 16; + regs->swreg46.rc_ctu_num = (syn->width + 15) / 16; regs->swreg47.bits_error0 = ((mb_target_size >> 4) * num_mbs_oneframe / 2) * -192; //sw_bits_error[0]; regs->swreg47.bits_error1 = ((mb_target_size >> 4) * num_mbs_oneframe / 2) * -144; //sw_bits_error[1]; @@ -2901,11 +2336,11 @@ MPP_RET hal_h264e_rkv_set_rc_regs(h264e_hal_context *ctx, h264e_rkv_reg_set *reg regs->swreg55.ctu_ebits = mb_target_size; //sw_ctu_target_bits; } else { - h264e_hal_rkv_extra_info *extra_info = (h264e_hal_rkv_extra_info *)ctx->extra_info; - h264e_control_extra_info_cfg *extra_info_cfg = &extra_info->sei.extra_info_cfg; - RK_U32 num_mbs_oneframe = (syn->pic_luma_width + 15) / 16 * ((syn->pic_luma_height + 15) / 16); - RK_U32 frame_target_bitrate = (syn->pic_luma_width * syn->pic_luma_height / 1920 / 1080) * 8000000 / 8; //Bytes - RK_U32 frame_target_size = frame_target_bitrate / extra_info_cfg->keyframe_max_interval; + MppEncCfgSet *cfg = ctx->cfg; + MppEncRcCfg *rc = &cfg->rc; + RK_U32 num_mbs_oneframe = (syn->width + 15) / 16 * ((syn->height + 15) / 16); + RK_U32 frame_target_bitrate = (syn->width * syn->height / 1920 / 1080) * 8000000 / 8; //Bytes + RK_U32 frame_target_size = frame_target_bitrate / (rc->gop ? rc->gop : 1); RK_U32 mb_target_size = frame_target_size / num_mbs_oneframe; RK_U32 aq_strength = 2; @@ -2919,7 +2354,7 @@ MPP_RET hal_h264e_rkv_set_rc_regs(h264e_hal_context *ctx, h264e_rkv_reg_set *reg regs->swreg46.aqmode_en = 1; regs->swreg46.aq_strg = (RK_U32)(aq_strength * 1.0397 * 256); regs->swreg46.Reserved = 0x0; - regs->swreg46.rc_ctu_num = (syn->pic_luma_width + 15) / 16; + regs->swreg46.rc_ctu_num = (syn->width + 15) / 16; regs->swreg47.bits_error0 = ((mb_target_size >> 4) * num_mbs_oneframe / 2) * -192; //sw_bits_error[0]; regs->swreg47.bits_error1 = ((mb_target_size >> 4) * num_mbs_oneframe / 2) * -144; //sw_bits_error[1]; @@ -2954,27 +2389,27 @@ MPP_RET hal_h264e_rkv_set_rc_regs(h264e_hal_context *ctx, h264e_rkv_reg_set *reg return MPP_OK; } -MPP_RET hal_h264e_rkv_set_roi_regs(h264e_rkv_reg_set *regs, h264e_syntax *syn, MppBuffer roi_idx_buf, RK_U32 frame_cnt, +MPP_RET hal_h264e_rkv_set_roi_regs(h264e_rkv_reg_set *regs, H264eHwCfg *syn, MppBuffer roi_idx_buf, RK_U32 frame_cnt, h264e_hal_rkv_coveragetest_cfg *test) { if (test && test->roi) { - RK_U32 k = 0; - RK_U32 num_mbs_oneframe = (syn->pic_luma_width + 15) / 16 * ((syn->pic_luma_height + 15) / 16); + RK_S32 k = 0; + RK_U32 num_mbs_oneframe = (syn->width + 15) / 16 * ((syn->height + 15) / 16); h264e_hal_rkv_roi_cfg *roi_cfg = mpp_calloc(h264e_hal_rkv_roi_cfg, num_mbs_oneframe); h264e_hal_log_detail("---- test-roi ----"); regs->swreg10.roi_enc = 1; regs->swreg29_ctuc_addr = mpp_buffer_get_fd(roi_idx_buf); if (frame_cnt % 3 == 0) { - for (k = 0; k < 4 * ((syn->pic_luma_width + 15) / 16); k++) { + for (k = 0; k < 4 * ((syn->width + 15) / 16); k++) { roi_cfg[k].set_qp_y_en = 1; roi_cfg[k].qp_y = 20; } } else if (frame_cnt % 3 == 1) { - for (k = 0; k < 4 * ((syn->pic_luma_width + 15) / 16); k++) { + for (k = 0; k < 4 * ((syn->width + 15) / 16); k++) { roi_cfg[k].forbit_inter = 1; } } else { // frame_cnt%3==2 - for (k = 0; k < 4 * ((syn->pic_luma_width + 15) / 16); k++) { + for (k = 0; k < 4 * ((syn->width + 15) / 16); k++) { roi_cfg[k].set_qp_y_en = 1; roi_cfg[k].qp_y = 20; roi_cfg[k].forbit_inter = 1; @@ -3045,8 +2480,7 @@ MPP_RET hal_h264e_rkv_set_osd_regs(h264e_hal_context *ctx, h264e_rkv_reg_set *re return MPP_OK; } -MPP_RET hal_h264e_rkv_set_pp_regs(h264e_rkv_reg_set *regs, h264e_syntax *syn, MppEncPrepCfg *prep_cfg, - MppBuffer hw_buf_w, MppBuffer hw_buf_r, RK_U32 frame_cnt, +MPP_RET hal_h264e_rkv_set_pp_regs(h264e_rkv_reg_set *regs, H264eHwCfg *syn, MppEncPrepCfg *prep_cfg, MppBuffer hw_buf_w, MppBuffer hw_buf_r, RK_U32 frame_cnt, h264e_hal_rkv_coveragetest_cfg *test) { RK_S32 k = 0; @@ -3069,7 +2503,7 @@ MPP_RET hal_h264e_rkv_set_pp_regs(h264e_rkv_reg_set *regs, h264e_syntax *syn, Mp h264e_hal_log_detail("---- test-preproc ----"); //regs->swreg14.src_aswap = 0; //h->param.swap_a; //regs->swreg14.src_cswap = 0; //h->param.swap_c; - regs->swreg14.src_cfmt = syn->input_image_format; //(h->param.prep_cfg_val&0xf000) ? h->param.format : 0x7; //src_cfmt + regs->swreg14.src_cfmt = syn->input_format; //(h->param.prep_cfg_val&0xf000) ? h->param.format : 0x7; //src_cfmt regs->swreg14.src_clip_dis = 0; //csc_clip_range; regs->swreg15.wght_b2y = 0;// csc_par_lu_b; @@ -3124,7 +2558,7 @@ MPP_RET hal_h264e_rkv_set_pp_regs(h264e_rkv_reg_set *regs, h264e_syntax *syn, Mp regs->swreg22_h3d_tbl[k] = h3d_tbl[k]; - stridey = (syn->pic_luma_width + 15) & (~15); + stridey = (syn->width + 15) & (~15); stridec = stridey; regs->swreg23.src_ystrid = stridey; @@ -3134,7 +2568,7 @@ MPP_RET hal_h264e_rkv_set_pp_regs(h264e_rkv_reg_set *regs, h264e_syntax *syn, Mp regs->swreg27_fltw_addr = mpp_buffer_get_fd(hw_buf_w); regs->swreg28_fltr_addr = mpp_buffer_get_fd(hw_buf_r); } else { - regs->swreg14.src_cfmt = syn->input_image_format; //syn->swreg14.src_cfmt; //src_cfmt + regs->swreg14.src_cfmt = syn->input_format; //syn->swreg14.src_cfmt; //src_cfmt for (k = 0; k < 5; k++) regs->swreg21_scr_stbl[k] = 0; //syn->swreg21_scr_stbl[k]; @@ -3142,10 +2576,10 @@ MPP_RET hal_h264e_rkv_set_pp_regs(h264e_rkv_reg_set *regs, h264e_syntax *syn, Mp for (k = 0; k < 40; k++) regs->swreg22_h3d_tbl[k] = h264e_h3d_tbl[k]; - if (syn->pic_hor_stride) { - stridey = syn->pic_hor_stride - 1; + if (syn->hor_stride) { + stridey = syn->hor_stride - 1; } else { - stridey = (regs->swreg19.src_rot == 1 || regs->swreg19.src_rot == 3) ? (syn->pic_luma_height - 1) : (syn->pic_luma_width - 1); + stridey = (regs->swreg19.src_rot == 1 || regs->swreg19.src_rot == 3) ? (syn->height - 1) : (syn->width - 1); if (regs->swreg14.src_cfmt == 0 ) stridey = (stridey + 1) * 4 - 1; else if (regs->swreg14.src_cfmt == 1 ) @@ -3157,15 +2591,15 @@ MPP_RET hal_h264e_rkv_set_pp_regs(h264e_rkv_reg_set *regs, h264e_syntax *syn, Mp regs->swreg23.src_ystrid = stridey; regs->swreg23.src_cstrid = stridec; - regs->swreg19.src_shp_y = prep_cfg->src_shp_en_y; - regs->swreg19.src_shp_c = prep_cfg->src_shp_en_uv; - regs->swreg19.src_shp_div = prep_cfg->src_shp_div; - regs->swreg19.src_shp_thld = prep_cfg->src_shp_thr; - regs->swreg21_scr_stbl[0] = prep_cfg->src_shp_w0; - regs->swreg21_scr_stbl[1] = prep_cfg->src_shp_w1; - regs->swreg21_scr_stbl[2] = prep_cfg->src_shp_w2; - regs->swreg21_scr_stbl[3] = prep_cfg->src_shp_w3; - regs->swreg21_scr_stbl[4] = prep_cfg->src_shp_w4; + regs->swreg19.src_shp_y = prep_cfg->sharpen.enable_y; + regs->swreg19.src_shp_c = prep_cfg->sharpen.enable_uv; + regs->swreg19.src_shp_div = prep_cfg->sharpen.div; + regs->swreg19.src_shp_thld = prep_cfg->sharpen.threshold; + regs->swreg21_scr_stbl[0] = prep_cfg->sharpen.coef[0]; + regs->swreg21_scr_stbl[1] = prep_cfg->sharpen.coef[1]; + regs->swreg21_scr_stbl[2] = prep_cfg->sharpen.coef[2]; + regs->swreg21_scr_stbl[3] = prep_cfg->sharpen.coef[3]; + regs->swreg21_scr_stbl[4] = prep_cfg->sharpen.coef[4]; (void)test; } @@ -3173,14 +2607,219 @@ MPP_RET hal_h264e_rkv_set_pp_regs(h264e_rkv_reg_set *regs, h264e_syntax *syn, Mp return MPP_OK; } +static RK_S32 hal_h264e_rkv_find_best_qp(MppLinReg *ctx, MppEncH264Cfg *codec, RK_S32 qp_start, RK_S32 bits) +{ + RK_S32 qp = qp_start; + RK_S32 qp_best = qp_start; + RK_S32 qp_min = codec->qp_min; + RK_S32 qp_max = codec->qp_max; + RK_S32 diff_best = INT_MAX; + + if (ctx->a == 0 && ctx->b == 0) + return qp_best; + + h264e_hal_log_detail("RC: qp est target bit %d\n", bits); + if (bits <= 0) { + qp_best = mpp_clip(qp_best + codec->qp_max_step, qp_min, qp_max); + } else { + do { + RK_S32 est_bits = mpp_linreg_calc(ctx, h264_q_step[qp]); + RK_S32 diff = est_bits - bits; + h264e_hal_log_detail("RC: qp est qp %d bit %d diff %d best %d\n", + qp, bits, diff, diff_best); + if (MPP_ABS(diff) < MPP_ABS(diff_best)) { + diff_best = MPP_ABS(diff); + qp_best = qp; + if (diff > 0) + qp++; + else + qp--; + } else + break; + } while (qp <= qp_max && qp >= qp_min); + } + + return qp_best; +} + +static MPP_RET hal_h264e_rkv_update_hw_cfg(h264e_hal_context *ctx, HalEncTask *task, H264eHwCfg *hw_cfg) +{ + RK_S32 i; + MppEncCfgSet *cfg = ctx->cfg; + MppEncH264Cfg *codec = &cfg->codec.h264; + MppEncPrepCfg *prep = &cfg->prep; + MppEncRcCfg *rc = &cfg->rc; + RcSyntax *rc_syn = (RcSyntax *)task->syntax.data; + + /* preprocess setup */ + if (prep->change) { + RK_U32 change = prep->change; + + if (change & MPP_ENC_PREP_CFG_CHANGE_INPUT) { + hw_cfg->width = prep->width; + hw_cfg->height = prep->height; + hw_cfg->input_format = prep->format; + + mpp_assert(prep->hor_stride == MPP_ALIGN(prep->width, 16)); + mpp_assert(prep->ver_stride == MPP_ALIGN(prep->height, 16)); + + hw_cfg->hor_stride = prep->hor_stride; + hw_cfg->ver_stride = prep->ver_stride; + + hal_h264e_rkv_set_format(hw_cfg, prep); + } + + if (change & MPP_ENC_PREP_CFG_CHANGE_FORMAT) { + switch (prep->color) { + case MPP_FRAME_SPC_RGB : { + /* BT.601 */ + /* Y = 0.2989 R + 0.5866 G + 0.1145 B + * Cb = 0.5647 (B - Y) + 128 + * Cr = 0.7132 (R - Y) + 128 + */ + hw_cfg->color_conversion_coeff_a = 19589; + hw_cfg->color_conversion_coeff_b = 38443; + hw_cfg->color_conversion_coeff_c = 7504; + hw_cfg->color_conversion_coeff_e = 37008; + hw_cfg->color_conversion_coeff_f = 46740; + } break; + case MPP_FRAME_SPC_BT709 : { + /* BT.709 */ + /* Y = 0.2126 R + 0.7152 G + 0.0722 B + * Cb = 0.5389 (B - Y) + 128 + * Cr = 0.6350 (R - Y) + 128 + */ + hw_cfg->color_conversion_coeff_a = 13933; + hw_cfg->color_conversion_coeff_b = 46871; + hw_cfg->color_conversion_coeff_c = 4732; + hw_cfg->color_conversion_coeff_e = 35317; + hw_cfg->color_conversion_coeff_f = 41615; + } break; + default : { + hw_cfg->color_conversion_coeff_a = 19589; + hw_cfg->color_conversion_coeff_b = 38443; + hw_cfg->color_conversion_coeff_c = 7504; + hw_cfg->color_conversion_coeff_e = 37008; + hw_cfg->color_conversion_coeff_f = 46740; + } break; + } + } + + prep->change = 0; + } + + if (codec->change) { + // TODO: setup sps / pps here + + hw_cfg->pps_id = 0; + hw_cfg->idr_pic_id = !ctx->idr_pic_id; + hw_cfg->enable_cabac = codec->entropy_coding_mode; + hw_cfg->cabac_init_idc = codec->cabac_init_idc; + hw_cfg->transform8x8_mode = codec->transform8x8_mode; + hw_cfg->pic_init_qp = codec->qp_init; + hw_cfg->chroma_qp_index_offset = codec->chroma_cb_qp_offset; + hw_cfg->second_chroma_qp_index_offset = codec->chroma_cr_qp_offset; + hw_cfg->filter_disable = codec->deblock_disable; + hw_cfg->slice_alpha_offset = codec->deblock_offset_alpha; + hw_cfg->slice_beta_offset = codec->deblock_offset_beta; + hw_cfg->inter4x4_disabled = (codec->profile >= 31) ? (1) : (0); + hw_cfg->constrained_intra_prediction = codec->constrained_intra_pred_mode; + + hw_cfg->qp_prev = hw_cfg->pic_init_qp; + hw_cfg->qp = hw_cfg->pic_init_qp; + + codec->change = 0; + } + + if (NULL == ctx->intra_qs) + mpp_linreg_init(&ctx->intra_qs, MPP_MIN(rc->gop, 10)); + if (NULL == ctx->inter_qs) + mpp_linreg_init(&ctx->inter_qs, MPP_MIN(rc->gop, 10)); + + mpp_assert(ctx->intra_qs); + mpp_assert(ctx->inter_qs); + + /* frame type and rate control setup */ + h264e_hal_log_detail("RC: qp calc ctx %p qp [%d %d] prev %d target bit %d\n", + ctx->inter_qs, codec->qp_min, codec->qp_max, hw_cfg->qp_prev, + rc_syn->bit_target); + { + RK_S32 prev_coding_type = hw_cfg->coding_type; + + if (rc_syn->type == INTRA_FRAME) { + hw_cfg->frame_type = H264E_RKV_FRAME_I; + hw_cfg->coding_type = RKVENC_CODING_TYPE_IDR; + hw_cfg->frame_num = 0; + + hw_cfg->qp = hal_h264e_rkv_find_best_qp(ctx->intra_qs, codec, hw_cfg->qp_prev, rc_syn->bit_target); + + /* + * Previous frame is inter then intra frame can not + * have a big qp step between these two frames + */ + if (prev_coding_type == 0) + hw_cfg->qp = mpp_clip(hw_cfg->qp, hw_cfg->qp_prev - 4, hw_cfg->qp_prev + 4); + } else { + hw_cfg->frame_type = H264E_RKV_FRAME_P; + hw_cfg->coding_type = RKVENC_CODING_TYPE_P; + + hw_cfg->qp = hal_h264e_rkv_find_best_qp(ctx->inter_qs, codec, hw_cfg->qp_prev, rc_syn->bit_target); + + if (prev_coding_type == 1) + hw_cfg->qp = mpp_clip(hw_cfg->qp, hw_cfg->qp_prev - 4, hw_cfg->qp_prev + 4); + } + } + + h264e_hal_log_detail("RC: qp calc ctx %p qp get %d\n", + ctx->inter_qs, hw_cfg->qp); + + hw_cfg->qp = mpp_clip(hw_cfg->qp, + hw_cfg->qp_prev - codec->qp_max_step, + hw_cfg->qp_prev + codec->qp_max_step); + + h264e_hal_log_detail("RC: qp calc ctx %p qp clip %d prev %d step %d\n", + ctx->inter_qs, hw_cfg->qp, hw_cfg->qp_prev, codec->qp_max_step); + + hw_cfg->qp_prev = hw_cfg->qp; + + hw_cfg->mad_qp_delta = 0; + hw_cfg->mad_threshold = 6; + hw_cfg->keyframe_max_interval = rc->gop ? rc->gop : 1; + hw_cfg->qp_min = codec->qp_min; + hw_cfg->qp_max = codec->qp_max; + + /* disable mb rate control first */ + hw_cfg->cp_distance_mbs = 0; + for (i = 0; i < 10; i++) + hw_cfg->cp_target[i] = 0; + + for (i = 0; i < 7; i++) + hw_cfg->target_error[i] = 0; + + for (i = 0; i < 7; i++) + hw_cfg->delta_qp[i] = 0; + + /* slice mode setup */ + hw_cfg->slice_size_mb_rows = (prep->width + 15) >> 4; + + /* input and preprocess config */ + hw_cfg->input_luma_addr = mpp_buffer_get_fd(task->input); + hw_cfg->input_cb_addr = hw_cfg->input_luma_addr; + hw_cfg->input_cr_addr = hw_cfg->input_cb_addr; + hw_cfg->output_strm_limit_size = mpp_buffer_get_size(task->output); + hw_cfg->output_strm_addr = mpp_buffer_get_fd(task->output); + + return MPP_OK; +} + + MPP_RET hal_h264e_rkv_gen_regs(void *hal, HalTaskInfo *task) { h264e_hal_context *ctx = (h264e_hal_context *)hal; h264e_hal_param *par = &ctx->param; h264e_rkv_reg_set *regs = NULL; h264e_rkv_ioctl_reg_info *ioctl_reg_info = NULL; - h264e_hal_rkv_csp_info src_fmt; - h264e_syntax *syn = (h264e_syntax *)task->enc.syntax.data; + H264eHwCfg *syn = &ctx->hw_cfg; h264e_rkv_ioctl_input *ioctl_info = (h264e_rkv_ioctl_input *)ctx->ioctl_input; h264e_rkv_reg_set *reg_list = (h264e_rkv_reg_set *)ctx->regs; h264e_hal_rkv_dpb_ctx *dpb_ctx = (h264e_hal_rkv_dpb_ctx *)ctx->dpb_ctx; @@ -3189,10 +2828,11 @@ MPP_RET hal_h264e_rkv_gen_regs(void *hal, HalTaskInfo *task) h264e_hal_sps *sps = &extra_info->sps; h264e_hal_pps *pps = &extra_info->pps; HalEncTask *enc_task = &task->enc; + H264eHwCfg *hw_cfg = &ctx->hw_cfg; - RK_S32 pic_width_align16 = (syn->pic_luma_width + 15) & (~15); - RK_S32 pic_height_align16 = (syn->pic_luma_height + 15) & (~15); - RK_S32 pic_width_in_blk64 = (syn->pic_luma_width + 63) / 64; + RK_S32 pic_width_align16 = 0; + RK_S32 pic_height_align16 = 0; + RK_S32 pic_width_in_blk64 = 0; h264e_hal_rkv_buffers *bufs = (h264e_hal_rkv_buffers *)ctx->buffers; RK_U32 mul_buf_idx = ctx->frame_cnt % RKV_H264E_LINKTABLE_FRAME_NUM; RK_U32 buf2_idx = ctx->frame_cnt % 2; @@ -3202,25 +2842,25 @@ MPP_RET hal_h264e_rkv_gen_regs(void *hal, HalTaskInfo *task) ctx->enc_mode = RKV_H264E_ENC_MODE; h264e_hal_debug_enter(); - hal_h264e_rkv_dump_mpp_syntax_in(syn, ctx); enc_task->flags.err = 0; - if (MPP_OK != hal_h264e_rkv_validate_syntax(syn, &src_fmt)) { - h264e_hal_log_err("hal_h264e_rkv_validate_syntax failed, return early"); - enc_task->flags.err |= HAL_ENC_TASK_ERR_GENREG; - return MPP_NOK; - } + hal_h264e_rkv_update_hw_cfg(ctx, &task->enc, syn); + hal_h264e_rkv_dump_mpp_syntax_in(syn, ctx); + + pic_width_align16 = (syn->width + 15) & (~15); + pic_height_align16 = (syn->height + 15) & (~15); + pic_width_in_blk64 = (syn->width + 63) / 64; hal_h264e_rkv_adjust_param(ctx); //TODO: future expansion - h264e_hal_log_simple("frame %d | type %d | start gen regs", ctx->frame_cnt, syn->slice_type); + h264e_hal_log_simple("frame %d | type %d | start gen regs", ctx->frame_cnt, syn->frame_type); if (ctx->sei_mode == MPP_ENC_SEI_MODE_ONE_FRAME && extra_info->sei_change_flg) { extra_info->nal_num = 0; hal_h264e_rkv_stream_reset(&extra_info->stream); hal_h264e_rkv_nal_start(extra_info, RKVENC_NAL_SEI, RKVENC_NAL_PRIORITY_DISPOSABLE); - hal_h264e_rkv_sei_encode(extra_info); + hal_h264e_rkv_sei_encode(ctx); hal_h264e_rkv_nal_end(extra_info); } @@ -3283,9 +2923,9 @@ MPP_RET hal_h264e_rkv_gen_regs(void *hal, HalTaskInfo *task) regs->swreg05.tmt_err = 1; //syn->swreg05.tmt_err ; regs->swreg09.pic_wd8_m1 = pic_width_align16 / 8 - 1; - regs->swreg09.pic_wfill = (syn->pic_luma_width & 0xf) ? (16 - (syn->pic_luma_width & 0xf)) : 0; + regs->swreg09.pic_wfill = (syn->width & 0xf) ? (16 - (syn->width & 0xf)) : 0; regs->swreg09.pic_hd8_m1 = pic_height_align16 / 8 - 1; - regs->swreg09.pic_hfill = (syn->pic_luma_height & 0xf) ? (16 - (syn->pic_luma_height & 0xf)) : 0; + regs->swreg09.pic_hfill = (syn->height & 0xf) ? (16 - (syn->height & 0xf)) : 0; regs->swreg10.enc_stnd = 0; //H264 regs->swreg10.cur_frm_ref = 1; //current frame will be refered @@ -3312,7 +2952,7 @@ MPP_RET hal_h264e_rkv_gen_regs(void *hal, HalTaskInfo *task) regs->swreg13.axi_brsp_cke = 0x7f; //syn->swreg13.axi_brsp_cke; regs->swreg13.cime_dspw_orsd = 0x0; - hal_h264e_rkv_set_pp_regs(regs, syn, &ctx->prep_cfg, bufs->hw_pp_buf[buf2_idx], bufs->hw_pp_buf[1 - buf2_idx], ctx->frame_cnt, test_cfg); + hal_h264e_rkv_set_pp_regs(regs, syn, &ctx->set->prep, bufs->hw_pp_buf[buf2_idx], bufs->hw_pp_buf[1 - buf2_idx], ctx->frame_cnt, test_cfg); hal_h264e_rkv_set_ioctl_extra_info(&ioctl_reg_info->extra_info, syn, regs); regs->swreg24_adr_srcy = syn->input_luma_addr; //syn->addr_cfg.adr_srcy; @@ -3394,7 +3034,6 @@ MPP_RET hal_h264e_rkv_gen_regs(void *hal, HalTaskInfo *task) regs->swreg44.mv_limit = (sps->i_level_idc > 20) ? 2 : ((sps->i_level_idc >= 11) ? 1 : 0); //syn->swreg44.mv_limit; regs->swreg44.mv_num = 3; //syn->swreg44.mv_num; - if (pic_width_align16 > 3584) regs->swreg45.cime_rama_h = 8; else if (pic_width_align16 > 3136) @@ -3453,17 +3092,17 @@ MPP_RET hal_h264e_rkv_gen_regs(void *hal, HalTaskInfo *task) { RK_U32 i_nal_type = 0, i_nal_ref_idc = 0; - if (syn->frame_coding_type == RKVENC_FRAME_TYPE_IDR ) { //TODO: extend syn->frame_coding_type definition + if (syn->coding_type == RKVENC_CODING_TYPE_IDR ) { //TODO: extend syn->frame_coding_type definition /* reset ref pictures */ i_nal_type = RKVENC_NAL_SLICE_IDR; i_nal_ref_idc = RKVENC_NAL_PRIORITY_HIGHEST; - } else if (syn->frame_coding_type == RKVENC_FRAME_TYPE_I ) { + } else if (syn->coding_type == RKVENC_CODING_TYPE_I ) { i_nal_type = RKVENC_NAL_SLICE; i_nal_ref_idc = RKVENC_NAL_PRIORITY_HIGH; /* Not completely true but for now it is (as all I/P are kept as ref)*/ - } else if (syn->frame_coding_type == RKVENC_FRAME_TYPE_P ) { + } else if (syn->coding_type == RKVENC_CODING_TYPE_P ) { i_nal_type = RKVENC_NAL_SLICE; i_nal_ref_idc = RKVENC_NAL_PRIORITY_HIGH; /* Not completely true but for now it is (as all I/P are kept as ref)*/ - } else if (syn->frame_coding_type == RKVENC_FRAME_TYPE_BREF ) { + } else if (syn->coding_type == RKVENC_CODING_TYPE_BREF ) { i_nal_type = RKVENC_NAL_SLICE; i_nal_ref_idc = RKVENC_NAL_PRIORITY_HIGH; } else { /* B frame */ @@ -3477,7 +3116,6 @@ MPP_RET hal_h264e_rkv_gen_regs(void *hal, HalTaskInfo *task) regs->swreg57.nal_unit_type = i_nal_type; //syn->swreg57.nal_unit_type; } - regs->swreg58.max_fnum = sps->i_log2_max_frame_num - 4; //syn->swreg58.max_fnum; regs->swreg58.drct_8x8 = 1; //syn->swreg58.drct_8x8; regs->swreg58.mpoc_lm4 = sps->i_log2_max_poc_lsb - 4; //syn->swreg58.mpoc_lm4; @@ -3493,7 +3131,7 @@ MPP_RET hal_h264e_rkv_gen_regs(void *hal, HalTaskInfo *task) regs->swreg59.wght_pred = 0x0; regs->swreg59.dbf_cp_flg = 1; //syn->deblocking_filter_control; - regs->swreg60.sli_type = syn->slice_type; //syn->swreg60.sli_type; + regs->swreg60.sli_type = syn->frame_type; //syn->swreg60.sli_type; regs->swreg60.pps_id = syn->pps_id; regs->swreg60.drct_smvp = 0x0; regs->swreg60.num_ref_ovrd = 0; @@ -3619,6 +3257,7 @@ MPP_RET hal_h264e_rkv_gen_regs(void *hal, HalTaskInfo *task) ctx->frame_cnt_gen_ready++; ctx->frame_cnt++; extra_info->sei.frame_cnt++; + hw_cfg->frame_num++; h264e_hal_debug_leave(); @@ -3658,13 +3297,13 @@ MPP_RET hal_h264e_rkv_start(void *hal, HalTaskInfo *task) (void)task; #ifdef RKPLATFORM - if (ctx->vpu_socket <= 0) { - h264e_hal_log_err("invalid vpu socket: %d", ctx->vpu_socket); + if (ctx->vpu_fd <= 0) { + h264e_hal_log_err("invalid vpu socket: %d", ctx->vpu_fd); return MPP_NOK; } h264e_hal_log_detail("vpu client is sending %d regs", length); - if (MPP_OK != VPUClientSendReg(ctx->vpu_socket, (RK_U32 *)ioctl_info, length)) { + if (MPP_OK != VPUClientSendReg(ctx->vpu_fd, (RK_U32 *)ioctl_info, length)) { h264e_hal_log_err("VPUClientSendReg Failed!!!"); return MPP_ERR_VPUHW; } else { @@ -3743,6 +3382,9 @@ MPP_RET hal_h264e_rkv_wait(void *hal, HalTaskInfo *task) IOInterruptCB int_cb = ctx->int_cb; h264e_feedback *fb = &ctx->feedback; HalEncTask *enc_task = &task->enc; + MppEncPrepCfg *prep = &ctx->cfg->prep; + RK_S32 num_mb = MPP_ALIGN(prep->width, 16) * MPP_ALIGN(prep->height, 16) / 16 / 16; + h264e_hal_debug_enter(); if (enc_task->flags.err) { @@ -3769,14 +3411,14 @@ MPP_RET hal_h264e_rkv_wait(void *hal, HalTaskInfo *task) } #ifdef RKPLATFORM - if (ctx->vpu_socket <= 0) { - h264e_hal_log_err("invalid vpu socket: %d", ctx->vpu_socket); + if (ctx->vpu_fd <= 0) { + h264e_hal_log_err("invalid vpu socket: %d", ctx->vpu_fd); return MPP_NOK; } h264e_hal_log_detail("VPUClientWaitResult expect length %d\n", length); - hw_ret = VPUClientWaitResult(ctx->vpu_socket, (RK_U32 *)reg_out, + hw_ret = VPUClientWaitResult(ctx->vpu_fd, (RK_U32 *)reg_out, length, &cmd, NULL); h264e_hal_log_detail("VPUClientWaitResult: ret %d, cmd %d, len %d\n", hw_ret, cmd, length); @@ -3795,8 +3437,28 @@ MPP_RET hal_h264e_rkv_wait(void *hal, HalTaskInfo *task) (void)cmd; #endif + hal_h264e_rkv_set_feedback(fb, reg_out); + task->enc.length = fb->out_strm_size; + h264e_hal_log_detail("output stream size %d\n", fb->out_strm_size); if (int_cb.callBack) { - hal_h264e_rkv_set_feedback(fb, reg_out); + RcSyntax *syn = (RcSyntax *)task->enc.syntax.data; + RcHalResult result; + RK_S32 avg_qp = 0; + + avg_qp = fb->qp_sum / num_mb; + + mpp_assert(avg_qp >= 0); + mpp_assert(avg_qp <= 51); + + result.bits = fb->out_strm_size * 8; + result.type = syn->type; + fb->result = &result; + + mpp_linreg_update((syn->type == INTRA_FRAME) ? + (ctx->intra_qs) : + (ctx->inter_qs), + h264_q_step[avg_qp], result.bits); + int_cb.callBack(int_cb.opaque, fb); } @@ -3834,11 +3496,11 @@ MPP_RET hal_h264e_rkv_control(void *hal, RK_S32 cmd_type, void *param) h264e_hal_log_detail("hal_h264e_rkv_control cmd 0x%x, info %p", cmd_type, param); switch (cmd_type) { case MPP_ENC_SET_EXTRA_INFO: { - hal_h264e_rkv_set_extra_info(ctx, param); break; } case MPP_ENC_GET_EXTRA_INFO: { MppPacket *pkt_out = (MppPacket *)param; + hal_h264e_rkv_set_extra_info(ctx); hal_h264e_rkv_get_extra_info(ctx, pkt_out); hal_h264e_rkv_dump_mpp_strm_out_header(ctx, *pkt_out); break; @@ -3860,9 +3522,72 @@ MPP_RET hal_h264e_rkv_control(void *hal, RK_S32 cmd_type, void *param) break; } case MPP_ENC_SET_PREP_CFG: { - memcpy(&ctx->prep_cfg, param, sizeof(ctx->prep_cfg)); + //LKSTODO: check cfg break; } + case MPP_ENC_SET_RC_CFG : { + // TODO: do rate control check here + } break; + case MPP_ENC_SET_CODEC_CFG : { + MppEncH264Cfg *src = &ctx->set->codec.h264; + MppEncH264Cfg *dst = &ctx->cfg->codec.h264; + RK_U32 change = src->change; + + // TODO: do codec check first + + if (change & MPP_ENC_H264_CFG_STREAM_TYPE) + dst->stream_type = src->stream_type; + if (change & MPP_ENC_H264_CFG_CHANGE_PROFILE) { + dst->profile = src->profile; + dst->level = src->level; + } + if (change & MPP_ENC_H264_CFG_CHANGE_ENTROPY) { + dst->entropy_coding_mode = src->entropy_coding_mode; + dst->cabac_init_idc = src->cabac_init_idc; + } + if (change & MPP_ENC_H264_CFG_CHANGE_TRANS_8x8) + dst->transform8x8_mode = src->transform8x8_mode; + if (change & MPP_ENC_H264_CFG_CHANGE_CONST_INTRA) + dst->constrained_intra_pred_mode = src->constrained_intra_pred_mode; + if (change & MPP_ENC_H264_CFG_CHANGE_CHROMA_QP) { + dst->chroma_cb_qp_offset = src->chroma_cb_qp_offset; + dst->chroma_cr_qp_offset = src->chroma_cr_qp_offset; + } + if (change & MPP_ENC_H264_CFG_CHANGE_DEBLOCKING) { + dst->deblock_disable = src->deblock_disable; + dst->deblock_offset_alpha = src->deblock_offset_alpha; + dst->deblock_offset_beta = src->deblock_offset_beta; + } + if (change & MPP_ENC_H264_CFG_CHANGE_LONG_TERM) + dst->use_longterm = src->use_longterm; + if (change & MPP_ENC_H264_CFG_CHANGE_QP_LIMIT) { + dst->qp_init = src->qp_init; + dst->qp_max = src->qp_max; + dst->qp_min = src->qp_min; + dst->qp_max_step = src->qp_max_step; + } + if (change & MPP_ENC_H264_CFG_CHANGE_INTRA_REFRESH) { + dst->intra_refresh_mode = src->intra_refresh_mode; + dst->intra_refresh_arg = src->intra_refresh_arg; + } + if (change & MPP_ENC_H264_CFG_CHANGE_SLICE_MODE) { + dst->slice_mode = src->slice_mode; + dst->slice_arg = src->slice_arg; + } + if (change & MPP_ENC_H264_CFG_CHANGE_VUI) { + dst->vui = src->vui; + } + if (change & MPP_ENC_H264_CFG_CHANGE_SEI) { + dst->sei = src->sei; + } + + /* + * NOTE: use OR here for avoiding overwrite on multiple config + * When next encoding is trigger the change flag will be clear + */ + dst->change |= change; + src->change = 0; + } break; default : { h264e_hal_log_err("unrecognizable cmd type %x", cmd_type); } break; diff --git a/mpp/hal/rkenc/h264e/hal_h264e_rkv.h b/mpp/hal/rkenc/h264e/hal_h264e_rkv.h index b8a52e6f..72659421 100644 --- a/mpp/hal/rkenc/h264e/hal_h264e_rkv.h +++ b/mpp/hal/rkenc/h264e/hal_h264e_rkv.h @@ -39,41 +39,12 @@ enc_mode #define RKV_H264E_LINKTABLE_EACH_NUM 1 #endif -#define RKV_H264E_NUM_REFS 1 -#define RKV_H264E_LONGTERM_REF_EN 0 //------------------------------------------------------------------------------- #define RKV_H264E_LINKTABLE_MAX_SIZE 256 #define RKV_H264E_ADD_RESERVE_REGS 1 #define RKV_H264E_REMOVE_UNNECESSARY_REGS 1 -#define RKV_H264E_CSP2_MASK 0x00ff /* */ -#define RKV_H264E_CSP2_NONE 0x0000 /* Invalid mode */ -#define RKV_H264E_CSP2_I420 0x0001 /* yuv 4:2:0 planar */ -#define RKV_H264E_CSP2_YV12 0x0002 /* yvu 4:2:0 planar */ -#define RKV_H264E_CSP2_NV12 0x0003 /* yuv 4:2:0, with one y plane and one packed u+v */ -#define RKV_H264E_CSP2_I422 0x0004 /* yuv 4:2:2 planar */ -#define RKV_H264E_CSP2_YV16 0x0005 /* yvu 4:2:2 planar */ -#define RKV_H264E_CSP2_NV16 0x0006 /* yuv 4:2:2, with one y plane and one packed u+v */ -#define RKV_H264E_CSP2_V210 0x0007 /* 10-bit yuv 4:2:2 packed in 32 */ -#define RKV_H264E_CSP2_I444 0x0008 /* yuv 4:4:4 planar */ -#define RKV_H264E_CSP2_YV24 0x0009 /* yvu 4:4:4 planar */ -#define RKV_H264E_CSP2_BGR 0x000a /* packed bgr 24bits */ -#define RKV_H264E_CSP2_BGRA 0x000b /* packed bgr 32bits */ -#define RKV_H264E_CSP2_RGB 0x000c /* packed rgb 24bits */ -#define RKV_H264E_CSP2_MAX 0x000d /* end of list */ -#define RKV_H264E_CSP2_VFLIP 0x1000 /* the csp is vertically flipped */ -#define RKV_H264E_CSP2_HIGH_DEPTH 0x2000 /* the csp has a depth of 16 bits per pixel component */ - -#define RKV_H264E_B_PYRAMID_NONE 0 -#define RKV_H264E_B_PYRAMID_STRICT 1 -#define RKV_H264E_B_PYRAMID_NORMAL 2 - -#define RKV_H264E_CQM_FLAT 0 -#define RKV_H264E_CQM_JVT 1 -#define RKV_H264E_CQM_CUSTOM 2 - - #define RKV_H264E_INT_ONE_FRAME_FINISH 0x00000001 #define RKV_H264E_INT_LINKTABLE_FINISH 0x00000002 #define RKV_H264E_INT_SAFE_CLEAR_FINISH 0x00000004 @@ -96,48 +67,11 @@ typedef struct h264e_hal_rkv_coveragetest_cfg_t { } h264e_hal_rkv_coveragetest_cfg; #endif - -typedef enum h264e_rkv_csp_t { - H264E_RKV_CSP_BGRA8888, // 0 - H264E_RKV_CSP_BGR888, // 1 - H264E_RKV_CSP_BGR565, // 2 - H264E_RKV_CSP_NONE, // 3 - H264E_RKV_CSP_YUV422SP, // 4 - H264E_RKV_CSP_YUV422P, // 5 - H264E_RKV_CSP_YUV420SP, // 6 - H264E_RKV_CSP_YUV420P, // 7 - H264E_RKV_CSP_YUYV422, // 8 - H264E_RKV_CSP_UYVY422, // 9 - H264E_RKV_CSP_BUTT, // 10 -} h264e_hal_rkv_csp; - - -typedef enum h264e_rkv_chroma_fmt_t { - RKV_H264E_CHROMA_400 = 0, - RKV_H264E_CHROMA_420 = 1, - RKV_H264E_CHROMA_422 = 2, - RKV_H264E_CHROMA_444 = 3, -} h264e_rkv_chroma_fmt; - -typedef struct h264e_hal_rkv_csp_info_t { - RK_U32 fmt; - RK_U32 cswap; // U/V swap for YUV420SP/YUV422SP/YUYV422/UYUV422; R/B swap for BGRA88/RGB888/RGB565. - RK_U32 aswap; // 0: BGRA, 1:ABGR. -} h264e_hal_rkv_csp_info; - -typedef enum h264e_rkv_cqm4_t { - RKV_H264E_CQM_4IY = 0, - RKV_H264E_CQM_4PY = 1, - RKV_H264E_CQM_4IC = 2, - RKV_H264E_CQM_4PC = 3 -} h264e_rkv_cqm4; - -typedef enum h264e_rkv_cqm8_t { - RKV_H264E_CQM_8IY = 0, - RKV_H264E_CQM_8PY = 1, - RKV_H264E_CQM_8IC = 2, - RKV_H264E_CQM_8PC = 3, -} h264e_rkv_cqm8; +typedef enum H264eRkvFrameType_t { + H264E_RKV_FRAME_P = 0, + H264E_RKV_FRAME_B = 1, + H264E_RKV_FRAME_I = 2 +} H264eRkvFrameType; typedef enum h264e_hal_rkv_buf_grp_t { H264E_HAL_RKV_BUF_GRP_PP, @@ -163,7 +97,7 @@ typedef struct h264e_hal_rkv_buffers_t { MppBuffer hw_dsp_buf[2]; //down scale picture MppBuffer hw_mei_buf[RKV_H264E_LINKTABLE_FRAME_NUM]; MppBuffer hw_roi_buf[RKV_H264E_LINKTABLE_FRAME_NUM]; - MppBuffer hw_rec_buf[RKV_H264E_NUM_REFS + 1]; //extra 1 frame for current recon + MppBuffer hw_rec_buf[H264E_NUM_REFS + 1]; //extra 1 frame for current recon } h264e_hal_rkv_buffers; typedef struct h264e_hal_rkv_nal_t { @@ -317,537 +251,6 @@ typedef struct h264e_hal_rkv_dpb_ctx_t { RK_S32 i_long_term_reference_flag; } h264e_hal_rkv_dpb_ctx; -typedef struct h264e_hal_rkv_dbg_info_t { - struct { - RK_U32 lkt_num : 8; - RK_U32 rkvenc_cmd : 2; //MAY - RK_U32 reserve : 6; - RK_U32 enc_cke : 1; - RK_U32 Reserve : 15; - } swreg02; //ENC_STRT - - struct { - RK_U32 lkt_addr : 32; - } swreg04; //LKT_ADDR - struct { - RK_U32 ofe_fnsh : 1; - RK_U32 lkt_fnsh : 1; - RK_U32 clr_fnsh : 1; - RK_U32 ose_fnsh : 1; - RK_U32 bs_ovflr : 1; - RK_U32 brsp_ful : 1; - RK_U32 brsp_err : 1; - RK_U32 rrsp_err : 1; - RK_U32 tmt_err : 1; - RK_U32 reserve : 23; - } swreg05; //INT_EN - - struct { - RK_U32 enc_stnd : 1; - RK_U32 roi_enc : 1; - RK_U32 cur_frm_ref : 1; - RK_U32 mei_stor : 1; - RK_U32 bs_scp : 1; - RK_U32 reserve : 3; - RK_U32 pic_qp : 6; - RK_U32 reserve1 : 16; - RK_U32 slice_int : 1; - RK_U32 node_int : 1; - } swreg10; //ENC_PIC - - struct { - RK_U32 ppln_enc_lmt : 4; - RK_U32 reserve : 4; - RK_U32 rfp_load_thrd : 8; - RK_U32 reserve1 : 16; - } swreg11; //ENC_WDG - - struct { - RK_U32 src_bus_ordr : 1; - RK_U32 cmvw_bus_ordr : 1; - RK_U32 dspw_bus_ordr : 1; - RK_U32 rfpw_bus_ordr : 1; - RK_U32 src_bus_edin : 4; - RK_U32 meiw_bus_edin : 4; - RK_U32 bsw_bus_edin : 3; - RK_U32 lktr_bus_edin : 4; - RK_U32 ctur_bus_edin : 4; - RK_U32 lktw_bus_edin : 4; - RK_U32 rfp_map_dcol : 2; - RK_U32 rfp_map_sctr : 1; - RK_U32 reserve : 2; - } swreg12; //DTRNS_MAP - - struct { - RK_U32 axi_brsp_cke : 7; - RK_U32 cime_dspw_orsd : 1; - RK_U32 reserve : 24; - } swreg13; // DTRNS_CFG - - struct { - RK_U32 src_aswap : 1; - RK_U32 src_cswap : 1; - RK_U32 src_cfmt : 4; - RK_U32 src_clip_dis : 1; - RK_U32 reserve : 25; - } swreg14; //SRC_FMT - - struct { - RK_U32 wght_b2y : 9; - RK_U32 wght_g2y : 9; - RK_U32 wght_r2y : 9; - RK_U32 reserve : 5; - } swreg15; //SRC_UDFY - - struct { - RK_U32 wght_b2u : 9; - RK_U32 wght_g2u : 9; - RK_U32 wght_r2u : 9; - RK_U32 reserve : 5; - } swreg16; //SRC_UDFU - - struct { - RK_U32 wght_b2v : 9; - RK_U32 wght_g2v : 9; - RK_U32 wght_r2v : 9; - RK_U32 reserve : 5; - } swreg17; //SRC_UDFV - - - struct { - RK_U32 ofst_rgb2v : 8; - RK_U32 ofst_rgb2u : 8; - RK_U32 ofst_rgb2y : 5; - RK_U32 reserve : 11; - } swreg18; //SRC_UDFO - - struct { - RK_U32 src_tfltr : 1; - RK_U32 src_tfltr_we : 1; - RK_U32 src_tfltr_bw : 1; - RK_U32 src_sfltr : 1; - RK_U32 src_mfltr_thrd : 5; - RK_U32 src_mfltr_y : 1; - RK_U32 src_mfltr_c : 1; - RK_U32 src_bfltr_strg : 1; - RK_U32 src_bfltr : 1; - RK_U32 src_mbflt_odr : 1; - RK_U32 src_matf_y : 1; - RK_U32 src_matf_c : 1; - RK_U32 src_shp_y : 1; - RK_U32 src_shp_c : 1; - RK_U32 src_shp_div : 3; - RK_U32 src_shp_thld : 5; - RK_U32 src_mirr : 1; - RK_U32 src_rot : 2; - RK_U32 src_matf_itsy : 1; - RK_U32 reserve : 2; - } swreg19; // SRC_PROC - - struct { - RK_U32 tfltr_thld_y : 15; - RK_U32 reserve : 1; - RK_U32 tfltr_thld_c : 15; - RK_U32 reserve1 : 1; - } swreg20; // SRC_TTHLD - - RK_U32 swreg21_scr_stbl[5]; //4.22. H3D_TBL0~39 - RK_U32 swreg22_h3d_tbl[40]; //4.22. H3D_TBL0~39 - - struct { - RK_U32 src_ystrid : 14; - RK_U32 reserve : 2; - RK_U32 src_cstrid : 14; - RK_U32 reserve1 : 2; - } swreg23; //SRC_STRID - - struct { - RK_U32 adr_srcy; //swreg24 - RK_U32 adr_srcu; - RK_U32 adr_srcv; - RK_U32 fltw_addr; - RK_U32 fltr_addr; - RK_U32 ctuc_addr; - RK_U32 rfpw_addr; - RK_U32 rfpr_addr; - RK_U32 cmvw_addr; - RK_U32 cmvr_addr; - RK_U32 dspw_addr; - RK_U32 dspr_addr; - RK_U32 meiw_addr; - RK_U32 bsbt_addr; - RK_U32 bsbb_addr; - RK_U32 bsbr_addr; - RK_U32 bsbw_addr; - } addr_cfg; - - struct { - RK_U32 sli_cut : 1; - RK_U32 sli_cut_mode : 1; - RK_U32 sli_cut_bmod : 1; - RK_U32 sli_max_num : 10; - RK_U32 sli_out_mode : 1; - RK_U32 reserve : 2; - RK_U32 sli_cut_cnum : 16; - } swreg41; // SLI_SPL - - struct { - RK_U32 sli_cut_byte : 18; - RK_U32 reserve : 14; - } swreg42; // SLI_SPL_BYTE - - struct { - RK_U32 cime_srch_h : 4; - RK_U32 cime_srch_v : 4; - RK_U32 rime_srch_h : 3; - RK_U32 rime_srch_v : 3; - RK_U32 reserved : 2; - RK_U32 dlt_frm_num : 16; - } swreg43; //ME_RNGE - - struct { - RK_U32 pmv_mdst_h : 8; - RK_U32 pmv_mdst_v : 8; - RK_U32 mv_limit : 2; - RK_U32 mv_num : 2; - RK_U32 reserve : 12; - } swreg44; // ME_CNST - - struct { - RK_U32 cime_rama_max : 11; - RK_U32 cime_rama_h : 5; - RK_U32 cach_l2_tag : 2; - RK_U32 cach_l1_dtmr : 5; - RK_U32 reserve : 9; - } swreg45; //ME_RAM - - struct { - RK_U32 rc_en : 1; - RK_U32 rc_mode : 1; - RK_U32 aqmode_en : 1; - RK_U32 aq_strg : 10; - RK_U32 Reserved : 3; - RK_U32 rc_ctu_num : 16; - } swreg46; //RC_CFG - - struct { - RK_U32 bits_error0 : 16; - RK_U32 bits_error1 : 16; - } swreg47; //RC_ERP0 //TODO: merge with reg 48~51, in arrays bit_error[5] - - struct { - RK_U32 bits_error2 : 16; - RK_U32 bits_error3 : 16; - } swreg48; //RC_ERP1 - - struct { - RK_U32 bits_error4 : 16; - RK_U32 bits_error5 : 16; - } swreg49; //RC_ERP2 - - struct { - RK_U32 bits_error6 : 16; - RK_U32 bits_error7 : 16; - } swreg50; //RC_ERP3 - - struct { - RK_U32 bits_error8 : 16; - RK_U32 reserve : 16; - } swreg51; //RC_ERP4 - - struct { - RK_U32 qp_adjuest0 : 5; - RK_U32 qp_adjuest1 : 5; - RK_U32 qp_adjuest2 : 5; - RK_U32 qp_adjuest3 : 5; - RK_U32 qp_adjuest4 : 5; - RK_U32 qp_adjuest5 : 5; - RK_U32 reserve : 2; - } swreg52; // RC_ADJ0 - - struct { - RK_U32 qp_adjuest6 : 5; - RK_U32 qp_adjuest7 : 5; - RK_U32 qp_adjuest8 : 5; - RK_U32 reserve : 17; - } swreg53; // RC_ADJ1 - - struct { - RK_U32 rc_qp_mod : 2; - RK_U32 rc_fact0 : 6; - RK_U32 rc_fact1 : 6; - RK_U32 Reserved : 2; - RK_U32 rc_qp_range : 4; - RK_U32 rc_max_qp : 6; - RK_U32 rc_min_qp : 6; - } swreg54; //RC_QP - - struct { - RK_U32 ctu_ebits : 20; - RK_U32 reserve : 12; - } swreg55; //RC_TGT - - struct { - RK_U32 rect_size : 1; - RK_U32 inter_4x4 : 1; - RK_U32 arb_sel : 1; - RK_U32 vlc_lmt : 1; - RK_U32 reserve : 1; - RK_U32 rdo_mark : 8; - RK_U32 reserve1 : 19; - } swreg56; //RDO_CFG - - struct { - RK_U32 nal_ref_idc : 2; - RK_U32 nal_unit_type : 5; - RK_U32 reserve : 25; - } swreg57; // SYNT_NAL - - struct { - RK_U32 max_fnum : 4; - RK_U32 drct_8x8 : 1; - RK_U32 mpoc_lm4 : 4; - RK_U32 reserve : 23; - } swreg58; // SYNT_SPS - - struct { - RK_U32 etpy_mode : 1; - RK_U32 trns_8x8 : 1; - RK_U32 csip_flg : 1; - RK_U32 num_ref0_idx : 2; - RK_U32 num_ref1_idx : 2; - RK_U32 pic_init_qp : 6; - int cb_ofst : 5; - int cr_ofst : 5; - RK_U32 wght_pred : 1; - RK_U32 dbf_cp_flg : 1; - RK_U32 reserve : 7; - } swreg59; // SYNT_PPS - - struct { - RK_U32 sli_type : 2; - RK_U32 pps_id : 8; - RK_U32 drct_smvp : 1; - RK_U32 num_ref_ovrd : 1; - RK_U32 cbc_init_idc : 2; - RK_U32 reserve : 2; - RK_U32 frm_num : 16; - } swreg60; // SYNT_SLI0 - - struct { - RK_U32 idr_pid : 16; - RK_U32 poc_lsb : 16; - } swreg61; // SYNT_SLI1 - - struct { - RK_U32 rodr_pic_idx : 2; - RK_U32 ref_list0_rodr : 1; - RK_S32 sli_beta_ofst : 4; - RK_S32 sli_alph_ofst : 4; - RK_U32 dis_dblk_idc : 2; - RK_U32 reserve : 3; - RK_U32 rodr_pic_num : 16; - } swreg62; // SYNT_SLI2_RODR - - struct { - RK_U32 nopp_flg : 1; - RK_U32 ltrf_flg : 1; - RK_U32 arpm_flg : 1; - RK_U32 mmco4_pre : 1; - RK_U32 mmco_0 : 3; - RK_U32 dopn_m1_0 : 16; - RK_U32 reserve : 9; - } swreg63; // SYNT_REF_MARK0 - - struct { - RK_U32 mmco_1 : 3; - RK_U32 dopn_m1_1 : 16; - RK_U32 reserve : 13; - } swreg64; // SYNT_REF_MARK1 - - struct { - RK_U32 osd_en : 8; - RK_U32 osd_inv : 8; - RK_U32 osd_clk_sel : 1; - RK_U32 osd_plt_type : 1; - RK_U32 reserve : 14; - } swreg65; //OSD_CFG - - struct { - RK_U32 osd_inv_r0 : 4; - RK_U32 osd_inv_r1 : 4; - RK_U32 osd_inv_r2 : 4; - RK_U32 osd_inv_r3 : 4; - RK_U32 osd_inv_r4 : 4; - RK_U32 osd_inv_r5 : 4; - RK_U32 osd_inv_r6 : 4; - RK_U32 osd_inv_r7 : 4; - } swreg66; //OSD_INV - - h264e_osd_pos swreg67_osd_pos[8]; - - RK_U32 swreg68_indx_addr_i[8]; //4.68. OSD_ADDR0-7 - - struct { - RK_U32 bs_lgth : 32; - } swreg69; //ST_BSL - - struct { - RK_U32 sse_l32 : 32; - } swreg70; // ST_SSE_L32 - - struct { - RK_U32 qp_sum : 22; - RK_U32 reserve : 2; - RK_U32 sse_h8 : 8; - } swreg71; // ST_SSE_QP - - struct { - RK_U32 slice_scnum : 12; - RK_U32 slice_slnum : 12; - RK_U32 reserve : 8; - } swreg72; //ST_SAO - - RK_U32 swreg73_osd_indx_tab_i[256]; //4.73. OSD_PLT0~255 - - struct { - RK_U32 st_enc : 2; - RK_U32 axiw_cln : 2; - RK_U32 axir_cln : 2; - RK_U32 reserve : 26; - } swreg74; // ST_ENC - - struct { - RK_U32 fnum_enc : 8; - RK_U32 fnum_cfg : 8; - RK_U32 fnum_int : 8; - RK_U32 reserve : 8; - } swreg75; // ST_LKT - - struct { - RK_U32 node_addr : 32; - } swreg76; //ST_NOD - - struct { - RK_U32 Bsbw_ovfl : 1; - RK_U32 reserve : 2; - RK_U32 bsbw_addr : 29; - } swreg77; //ST_BSB - -#if 0 - struct { - RK_U32 axib_idl : 7; - RK_U32 axib_ful : 7; - RK_U32 axib_err : 7; - RK_U32 axir_err : 6; - RK_U32 reserve : 5; - } swreg78; //ST_DTRNS - - struct { - RK_U32 slice_num : 6; - RK_U32 reserve : 26; - } swreg79; //ST_SNUM - - struct { - RK_U32 slice_len : 23; - RK_U32 reserve : 9; - } swreg80; //ST_SLEN - - struct { - RK_U32 axip0_work : 1; - RK_U32 axip0_clr : 1; - RK_U32 axip0_frm : 1; - RK_U32 reserve : 29; - } swreg81; // AXIP0_CMD - - struct { - RK_U32 axip0_ltcy_id : 4; - RK_U32 axip0_ltcy_thr : 12; - RK_U32 reserve : 16; - } swreg82; // AXIP0_LTCY - - struct { - RK_U32 axip0_cnt_type : 1; - RK_U32 axip0_cnt_ddr : 2; - RK_U32 axip0_cnt_rid : 5; - RK_U32 axip0_cnt_wid : 5; - RK_U32 reserve : 19; - } swreg83; // AXIP0_CNT - - struct { - RK_U32 axip1_work : 1; - RK_U32 axip1_clr : 1; - RK_U32 reserve : 30; - } swreg84; // AXIP1_CMD - - struct { - RK_U32 axip1_ltcy_id : 4; - RK_U32 axip1_ltcy_thr : 12; - RK_U32 reserve : 16; - } swreg85; // AXIP1_LTCY - - struct { - RK_U32 axip1_cnt_type : 1; - RK_U32 axip1_cnt_ddr : 2; - RK_U32 axip1_cnt_rid : 5; - RK_U32 axip1_cnt_wid : 5; - RK_U32 reserve : 19; - } swreg86; // AXIP1_CNT - - struct { - RK_U32 axip0_cnt_type : 16; - RK_U32 reserve : 16; - } swreg87; // ST_AXIP0_MAXL - - - struct { - RK_U32 axip0_num_ltcy : 32; - } swreg88; // ST_AXIP0_NUML - - struct { - RK_U32 axip0_sum_ltcy : 32; - } swreg89; // ST_AXIP0_SUML - - struct { - RK_U32 axip0_byte_rd : 32; - } swreg90; // ST_AXIP0_RDB - - struct { - RK_U32 axip0_byte_wr : 32; - } swreg91; // ST_AXIP0_WRB - - struct { - RK_U32 axip0_wrk_cyc : 32; - } swreg92; //ST_AXIP0_CYCL - - struct { - RK_U32 axip1_cnt_type : 16; - RK_U32 reserve : 16; - } swreg93; // ST_AXIP1_MAXL - - struct { - RK_U32 axip1_num_ltcy : 32; - } swreg94; // ST_AXIP1_NUML - - struct { - RK_U32 axip1_sum_ltcy : 32; - } swreg95; // ST_AXIP1_SUML - - struct { - RK_U32 axip1_byte_rd : 32; - } swreg96; // ST_AXIP1_RDB - - struct { - RK_U32 axip1_byte_wr : 32; - } swreg97; // ST_AXIP1_WRB - - struct { - RK_U32 axip1_wrk_cyc : 32; - } swreg98; // ST_AXIP1_CYCL -#endif //#if 0 -} h264e_hal_rkv_dbg_info; - - /* cmodel version r2893 */ typedef struct h264e_osd_cfg_t { diff --git a/mpp/hal/rkenc/h264e/hal_h264e_vpu.c b/mpp/hal/rkenc/h264e/hal_h264e_vpu.c deleted file mode 100644 index 13ad39f8..00000000 --- a/mpp/hal/rkenc/h264e/hal_h264e_vpu.c +++ /dev/null @@ -1,2308 +0,0 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * 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. - */ - -#define MODULE_TAG "hal_h264e_vpu" -#include -#include "vpu.h" -#include "rk_mpi.h" -#include "mpp_common.h" -#include "mpp_mem.h" -#include "mpp_frame.h" -#include "hal_h264e.h" -#include "hal_h264e_vpu.h" - -//#define H264E_DUMP_DATA_TO_FILE - -/* H.264 motion estimation parameters */ -static const RK_U32 h264_prev_mode_favor[52] = { - 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 24, 25, 27, 29, 30, 32, 34, 36, 38, 41, 43, 46, - 49, 51, 55, 58, 61, 65, 69, 73, 78, 82, 87, 93, 98, 104, 110, - 117, 124, 132, 140 -}; - -/* sqrt(2^((qp-12)/3))*8 */ -static const RK_U32 h264_diff_mv_penalty[52] = { - 2, 2, 3, 3, 3, 4, 4, 4, 5, 6, - 6, 7, 8, 9, 10, 11, 13, 14, 16, 18, - 20, 23, 26, 29, 32, 36, 40, 45, 51, 57, - 64, 72, 81, 91, 102, 114, 128, 144, 161, 181, - 203, 228, 256, 287, 323, 362, 406, 456, 512, 575, - 645, 724 -}; - -/* 31*sqrt(2^((qp-12)/3))/4 */ -static const RK_U32 h264_diff_mv_penalty4p[52] = { - 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, - 6, 7, 8, 9, 10, 11, 12, 14, 16, 17, - 20, 22, 25, 28, 31, 35, 39, 44, 49, 55, - 62, 70, 78, 88, 98, 110, 124, 139, 156, 175, - 197, 221, 248, 278, 312, 351, 394, 442, 496, 557, - 625, 701 -}; - -static const RK_U32 h264_intra16_favor[52] = { - 24, 24, 24, 26, 27, 30, 32, 35, 39, 43, 48, 53, 58, 64, 71, 78, - 85, 93, 102, 111, 121, 131, 142, 154, 167, 180, 195, 211, 229, - 248, 271, 296, 326, 361, 404, 457, 523, 607, 714, 852, 1034, - 1272, 1588, 2008, 2568, 3318, 4323, 5672, 7486, 9928, 13216, - 17648 -}; - -static const RK_U32 h264_inter_favor[52] = { - 40, 40, 41, 42, 43, 44, 45, 48, 51, 53, 55, 60, 62, 67, 69, 72, - 78, 84, 90, 96, 110, 120, 135, 152, 170, 189, 210, 235, 265, - 297, 335, 376, 420, 470, 522, 572, 620, 670, 724, 770, 820, - 867, 915, 970, 1020, 1076, 1132, 1180, 1230, 1275, 1320, 1370 -}; - -static RK_U32 h264_skip_sad_penalty[52] = { - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 233, 205, 182, 163, - 146, 132, 120, 109, 100, 92, 84, 78, 71, 66, 61, 56, 52, 48, - 44, 41, 38, 35, 32, 30, 27, 25, 23, 21, 19, 17, 15, 14, - 12, 11, 9, 8, 7, 5, 4, 3, 2, 1 -}; - -const RK_S32 h264_context_init_intra[460][2] = { - /* 0 -> 10 */ - { 20, -15 }, { 2, 54 }, { 3, 74 }, { 20, -15 }, - { 2, 54 }, { 3, 74 }, { -28, 127 }, { -23, 104 }, - { -6, 53 }, { -1, 54 }, { 7, 51 }, - - /* 11 -> 23 unsused for I */ - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, - - /* 24 -> 39 */ - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - - /* 40 -> 53 */ - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, - - /* 54 -> 59 */ - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, - - /* 60 -> 69 */ - { 0, 41 }, { 0, 63 }, { 0, 63 }, { 0, 63 }, - { -9, 83 }, { 4, 86 }, { 0, 97 }, { -7, 72 }, - { 13, 41 }, { 3, 62 }, - - /* 70 -> 87 */ - { 0, 11 }, { 1, 55 }, { 0, 69 }, { -17, 127 }, - { -13, 102 }, { 0, 82 }, { -7, 74 }, { -21, 107 }, - { -27, 127 }, { -31, 127 }, { -24, 127 }, { -18, 95 }, - { -27, 127 }, { -21, 114 }, { -30, 127 }, { -17, 123 }, - { -12, 115 }, { -16, 122 }, - - /* 88 -> 104 */ - { -11, 115 }, { -12, 63 }, { -2, 68 }, { -15, 84 }, - { -13, 104 }, { -3, 70 }, { -8, 93 }, { -10, 90 }, - { -30, 127 }, { -1, 74 }, { -6, 97 }, { -7, 91 }, - { -20, 127 }, { -4, 56 }, { -5, 82 }, { -7, 76 }, - { -22, 125 }, - - /* 105 -> 135 */ - { -7, 93 }, { -11, 87 }, { -3, 77 }, { -5, 71 }, - { -4, 63 }, { -4, 68 }, { -12, 84 }, { -7, 62 }, - { -7, 65 }, { 8, 61 }, { 5, 56 }, { -2, 66 }, - { 1, 64 }, { 0, 61 }, { -2, 78 }, { 1, 50 }, - { 7, 52 }, { 10, 35 }, { 0, 44 }, { 11, 38 }, - { 1, 45 }, { 0, 46 }, { 5, 44 }, { 31, 17 }, - { 1, 51 }, { 7, 50 }, { 28, 19 }, { 16, 33 }, - { 14, 62 }, { -13, 108 }, { -15, 100 }, - - /* 136 -> 165 */ - { -13, 101 }, { -13, 91 }, { -12, 94 }, { -10, 88 }, - { -16, 84 }, { -10, 86 }, { -7, 83 }, { -13, 87 }, - { -19, 94 }, { 1, 70 }, { 0, 72 }, { -5, 74 }, - { 18, 59 }, { -8, 102 }, { -15, 100 }, { 0, 95 }, - { -4, 75 }, { 2, 72 }, { -11, 75 }, { -3, 71 }, - { 15, 46 }, { -13, 69 }, { 0, 62 }, { 0, 65 }, - { 21, 37 }, { -15, 72 }, { 9, 57 }, { 16, 54 }, - { 0, 62 }, { 12, 72 }, - - /* 166 -> 196 */ - { 24, 0 }, { 15, 9 }, { 8, 25 }, { 13, 18 }, - { 15, 9 }, { 13, 19 }, { 10, 37 }, { 12, 18 }, - { 6, 29 }, { 20, 33 }, { 15, 30 }, { 4, 45 }, - { 1, 58 }, { 0, 62 }, { 7, 61 }, { 12, 38 }, - { 11, 45 }, { 15, 39 }, { 11, 42 }, { 13, 44 }, - { 16, 45 }, { 12, 41 }, { 10, 49 }, { 30, 34 }, - { 18, 42 }, { 10, 55 }, { 17, 51 }, { 17, 46 }, - { 0, 89 }, { 26, -19 }, { 22, -17 }, - - /* 197 -> 226 */ - { 26, -17 }, { 30, -25 }, { 28, -20 }, { 33, -23 }, - { 37, -27 }, { 33, -23 }, { 40, -28 }, { 38, -17 }, - { 33, -11 }, { 40, -15 }, { 41, -6 }, { 38, 1 }, - { 41, 17 }, { 30, -6 }, { 27, 3 }, { 26, 22 }, - { 37, -16 }, { 35, -4 }, { 38, -8 }, { 38, -3 }, - { 37, 3 }, { 38, 5 }, { 42, 0 }, { 35, 16 }, - { 39, 22 }, { 14, 48 }, { 27, 37 }, { 21, 60 }, - { 12, 68 }, { 2, 97 }, - - /* 227 -> 251 */ - { -3, 71 }, { -6, 42 }, { -5, 50 }, { -3, 54 }, - { -2, 62 }, { 0, 58 }, { 1, 63 }, { -2, 72 }, - { -1, 74 }, { -9, 91 }, { -5, 67 }, { -5, 27 }, - { -3, 39 }, { -2, 44 }, { 0, 46 }, { -16, 64 }, - { -8, 68 }, { -10, 78 }, { -6, 77 }, { -10, 86 }, - { -12, 92 }, { -15, 55 }, { -10, 60 }, { -6, 62 }, - { -4, 65 }, - - /* 252 -> 275 */ - { -12, 73 }, { -8, 76 }, { -7, 80 }, { -9, 88 }, - { -17, 110 }, { -11, 97 }, { -20, 84 }, { -11, 79 }, - { -6, 73 }, { -4, 74 }, { -13, 86 }, { -13, 96 }, - { -11, 97 }, { -19, 117 }, { -8, 78 }, { -5, 33 }, - { -4, 48 }, { -2, 53 }, { -3, 62 }, { -13, 71 }, - { -10, 79 }, { -12, 86 }, { -13, 90 }, { -14, 97 }, - - /* 276 special case, bypass used */ - { 0, 0 }, - - /* 277 -> 307 */ - { -6, 93 }, { -6, 84 }, { -8, 79 }, { 0, 66 }, - { -1, 71 }, { 0, 62 }, { -2, 60 }, { -2, 59 }, - { -5, 75 }, { -3, 62 }, { -4, 58 }, { -9, 66 }, - { -1, 79 }, { 0, 71 }, { 3, 68 }, { 10, 44 }, - { -7, 62 }, { 15, 36 }, { 14, 40 }, { 16, 27 }, - { 12, 29 }, { 1, 44 }, { 20, 36 }, { 18, 32 }, - { 5, 42 }, { 1, 48 }, { 10, 62 }, { 17, 46 }, - { 9, 64 }, { -12, 104 }, { -11, 97 }, - - /* 308 -> 337 */ - { -16, 96 }, { -7, 88 }, { -8, 85 }, { -7, 85 }, - { -9, 85 }, { -13, 88 }, { 4, 66 }, { -3, 77 }, - { -3, 76 }, { -6, 76 }, { 10, 58 }, { -1, 76 }, - { -1, 83 }, { -7, 99 }, { -14, 95 }, { 2, 95 }, - { 0, 76 }, { -5, 74 }, { 0, 70 }, { -11, 75 }, - { 1, 68 }, { 0, 65 }, { -14, 73 }, { 3, 62 }, - { 4, 62 }, { -1, 68 }, { -13, 75 }, { 11, 55 }, - { 5, 64 }, { 12, 70 }, - - /* 338 -> 368 */ - { 15, 6 }, { 6, 19 }, { 7, 16 }, { 12, 14 }, - { 18, 13 }, { 13, 11 }, { 13, 15 }, { 15, 16 }, - { 12, 23 }, { 13, 23 }, { 15, 20 }, { 14, 26 }, - { 14, 44 }, { 17, 40 }, { 17, 47 }, { 24, 17 }, - { 21, 21 }, { 25, 22 }, { 31, 27 }, { 22, 29 }, - { 19, 35 }, { 14, 50 }, { 10, 57 }, { 7, 63 }, - { -2, 77 }, { -4, 82 }, { -3, 94 }, { 9, 69 }, - { -12, 109 }, { 36, -35 }, { 36, -34 }, - - /* 369 -> 398 */ - { 32, -26 }, { 37, -30 }, { 44, -32 }, { 34, -18 }, - { 34, -15 }, { 40, -15 }, { 33, -7 }, { 35, -5 }, - { 33, 0 }, { 38, 2 }, { 33, 13 }, { 23, 35 }, - { 13, 58 }, { 29, -3 }, { 26, 0 }, { 22, 30 }, - { 31, -7 }, { 35, -15 }, { 34, -3 }, { 34, 3 }, - { 36, -1 }, { 34, 5 }, { 32, 11 }, { 35, 5 }, - { 34, 12 }, { 39, 11 }, { 30, 29 }, { 34, 26 }, - { 29, 39 }, { 19, 66 }, - - /* 399 -> 435 */ - { 31, 21 }, { 31, 31 }, { 25, 50 }, - { -17, 120 }, { -20, 112 }, { -18, 114 }, { -11, 85 }, - { -15, 92 }, { -14, 89 }, { -26, 71 }, { -15, 81 }, - { -14, 80 }, { 0, 68 }, { -14, 70 }, { -24, 56 }, - { -23, 68 }, { -24, 50 }, { -11, 74 }, { 23, -13 }, - { 26, -13 }, { 40, -15 }, { 49, -14 }, { 44, 3 }, - { 45, 6 }, { 44, 34 }, { 33, 54 }, { 19, 82 }, - { -3, 75 }, { -1, 23 }, { 1, 34 }, { 1, 43 }, - { 0, 54 }, { -2, 55 }, { 0, 61 }, { 1, 64 }, - { 0, 68 }, { -9, 92 }, - - /* 436 -> 459 */ - { -14, 106 }, { -13, 97 }, { -15, 90 }, { -12, 90 }, - { -18, 88 }, { -10, 73 }, { -9, 79 }, { -14, 86 }, - { -10, 73 }, { -10, 70 }, { -10, 69 }, { -5, 66 }, - { -9, 64 }, { -5, 58 }, { 2, 59 }, { 21, -10 }, - { 24, -11 }, { 28, -8 }, { 28, -1 }, { 29, 3 }, - { 29, 9 }, { 35, 20 }, { 29, 36 }, { 14, 67 } -}; - -const RK_S32 h264_context_init[3][460][2] = { - /* cabac_init_idc == 0 */ - { - /* 0 -> 10 */ - { 20, -15 }, { 2, 54 }, { 3, 74 }, { 20, -15 }, - { 2, 54 }, { 3, 74 }, { -28, 127 }, { -23, 104 }, - { -6, 53 }, { -1, 54 }, { 7, 51 }, - - /* 11 -> 23 */ - { 23, 33 }, { 23, 2 }, { 21, 0 }, { 1, 9 }, - { 0, 49 }, { -37, 118 }, { 5, 57 }, { -13, 78 }, - { -11, 65 }, { 1, 62 }, { 12, 49 }, { -4, 73 }, - { 17, 50 }, - - /* 24 -> 39 */ - { 18, 64 }, { 9, 43 }, { 29, 0 }, { 26, 67 }, - { 16, 90 }, { 9, 104 }, { -46, 127 }, { -20, 104 }, - { 1, 67 }, { -13, 78 }, { -11, 65 }, { 1, 62 }, - { -6, 86 }, { -17, 95 }, { -6, 61 }, { 9, 45 }, - - /* 40 -> 53 */ - { -3, 69 }, { -6, 81 }, { -11, 96 }, { 6, 55 }, - { 7, 67 }, { -5, 86 }, { 2, 88 }, { 0, 58 }, - { -3, 76 }, { -10, 94 }, { 5, 54 }, { 4, 69 }, - { -3, 81 }, { 0, 88 }, - - /* 54 -> 59 */ - { -7, 67 }, { -5, 74 }, { -4, 74 }, { -5, 80 }, - { -7, 72 }, { 1, 58 }, - - /* 60 -> 69 */ - { 0, 41 }, { 0, 63 }, { 0, 63 }, { 0, 63 }, - { -9, 83 }, { 4, 86 }, { 0, 97 }, { -7, 72 }, - { 13, 41 }, { 3, 62 }, - - /* 70 -> 87 */ - { 0, 45 }, { -4, 78 }, { -3, 96 }, { -27, 126 }, - { -28, 98 }, { -25, 101 }, { -23, 67 }, { -28, 82 }, - { -20, 94 }, { -16, 83 }, { -22, 110 }, { -21, 91 }, - { -18, 102 }, { -13, 93 }, { -29, 127 }, { -7, 92 }, - { -5, 89 }, { -7, 96 }, { -13, 108 }, { -3, 46 }, - { -1, 65 }, { -1, 57 }, { -9, 93 }, { -3, 74 }, - { -9, 92 }, { -8, 87 }, { -23, 126 }, { 5, 54 }, - { 6, 60 }, { 6, 59 }, { 6, 69 }, { -1, 48 }, - { 0, 68 }, { -4, 69 }, { -8, 88 }, - - /* 105 -> 165 */ - { -2, 85 }, { -6, 78 }, { -1, 75 }, { -7, 77 }, - { 2, 54 }, { 5, 50 }, { -3, 68 }, { 1, 50 }, - { 6, 42 }, { -4, 81 }, { 1, 63 }, { -4, 70 }, - { 0, 67 }, { 2, 57 }, { -2, 76 }, { 11, 35 }, - { 4, 64 }, { 1, 61 }, { 11, 35 }, { 18, 25 }, - { 12, 24 }, { 13, 29 }, { 13, 36 }, { -10, 93 }, - { -7, 73 }, { -2, 73 }, { 13, 46 }, { 9, 49 }, - { -7, 100 }, { 9, 53 }, { 2, 53 }, { 5, 53 }, - { -2, 61 }, { 0, 56 }, { 0, 56 }, { -13, 63 }, - { -5, 60 }, { -1, 62 }, { 4, 57 }, { -6, 69 }, - { 4, 57 }, { 14, 39 }, { 4, 51 }, { 13, 68 }, - { 3, 64 }, { 1, 61 }, { 9, 63 }, { 7, 50 }, - { 16, 39 }, { 5, 44 }, { 4, 52 }, { 11, 48 }, - { -5, 60 }, { -1, 59 }, { 0, 59 }, { 22, 33 }, - { 5, 44 }, { 14, 43 }, { -1, 78 }, { 0, 60 }, - { 9, 69 }, - - /* 166 -> 226 */ - { 11, 28 }, { 2, 40 }, { 3, 44 }, { 0, 49 }, - { 0, 46 }, { 2, 44 }, { 2, 51 }, { 0, 47 }, - { 4, 39 }, { 2, 62 }, { 6, 46 }, { 0, 54 }, - { 3, 54 }, { 2, 58 }, { 4, 63 }, { 6, 51 }, - { 6, 57 }, { 7, 53 }, { 6, 52 }, { 6, 55 }, - { 11, 45 }, { 14, 36 }, { 8, 53 }, { -1, 82 }, - { 7, 55 }, { -3, 78 }, { 15, 46 }, { 22, 31 }, - { -1, 84 }, { 25, 7 }, { 30, -7 }, { 28, 3 }, - { 28, 4 }, { 32, 0 }, { 34, -1 }, { 30, 6 }, - { 30, 6 }, { 32, 9 }, { 31, 19 }, { 26, 27 }, - { 26, 30 }, { 37, 20 }, { 28, 34 }, { 17, 70 }, - { 1, 67 }, { 5, 59 }, { 9, 67 }, { 16, 30 }, - { 18, 32 }, { 18, 35 }, { 22, 29 }, { 24, 31 }, - { 23, 38 }, { 18, 43 }, { 20, 41 }, { 11, 63 }, - { 9, 59 }, { 9, 64 }, { -1, 94 }, { -2, 89 }, - { -9, 108 }, - - /* 227 -> 275 */ - { -6, 76 }, { -2, 44 }, { 0, 45 }, { 0, 52 }, - { -3, 64 }, { -2, 59 }, { -4, 70 }, { -4, 75 }, - { -8, 82 }, { -17, 102 }, { -9, 77 }, { 3, 24 }, - { 0, 42 }, { 0, 48 }, { 0, 55 }, { -6, 59 }, - { -7, 71 }, { -12, 83 }, { -11, 87 }, { -30, 119 }, - { 1, 58 }, { -3, 29 }, { -1, 36 }, { 1, 38 }, - { 2, 43 }, { -6, 55 }, { 0, 58 }, { 0, 64 }, - { -3, 74 }, { -10, 90 }, { 0, 70 }, { -4, 29 }, - { 5, 31 }, { 7, 42 }, { 1, 59 }, { -2, 58 }, - { -3, 72 }, { -3, 81 }, { -11, 97 }, { 0, 58 }, - { 8, 5 }, { 10, 14 }, { 14, 18 }, { 13, 27 }, - { 2, 40 }, { 0, 58 }, { -3, 70 }, { -6, 79 }, - { -8, 85 }, - - /* 276 special case, bypass used */ - { 0, 0 }, - - /* 277 -> 337 */ - { -13, 106 }, { -16, 106 }, { -10, 87 }, { -21, 114 }, - { -18, 110 }, { -14, 98 }, { -22, 110 }, { -21, 106 }, - { -18, 103 }, { -21, 107 }, { -23, 108 }, { -26, 112 }, - { -10, 96 }, { -12, 95 }, { -5, 91 }, { -9, 93 }, - { -22, 94 }, { -5, 86 }, { 9, 67 }, { -4, 80 }, - { -10, 85 }, { -1, 70 }, { 7, 60 }, { 9, 58 }, - { 5, 61 }, { 12, 50 }, { 15, 50 }, { 18, 49 }, - { 17, 54 }, { 10, 41 }, { 7, 46 }, { -1, 51 }, - { 7, 49 }, { 8, 52 }, { 9, 41 }, { 6, 47 }, - { 2, 55 }, { 13, 41 }, { 10, 44 }, { 6, 50 }, - { 5, 53 }, { 13, 49 }, { 4, 63 }, { 6, 64 }, - { -2, 69 }, { -2, 59 }, { 6, 70 }, { 10, 44 }, - { 9, 31 }, { 12, 43 }, { 3, 53 }, { 14, 34 }, - { 10, 38 }, { -3, 52 }, { 13, 40 }, { 17, 32 }, - { 7, 44 }, { 7, 38 }, { 13, 50 }, { 10, 57 }, - { 26, 43 }, - - /* 338 -> 398 */ - { 14, 11 }, { 11, 14 }, { 9, 11 }, { 18, 11 }, - { 21, 9 }, { 23, -2 }, { 32, -15 }, { 32, -15 }, - { 34, -21 }, { 39, -23 }, { 42, -33 }, { 41, -31 }, - { 46, -28 }, { 38, -12 }, { 21, 29 }, { 45, -24 }, - { 53, -45 }, { 48, -26 }, { 65, -43 }, { 43, -19 }, - { 39, -10 }, { 30, 9 }, { 18, 26 }, { 20, 27 }, - { 0, 57 }, { -14, 82 }, { -5, 75 }, { -19, 97 }, - { -35, 125 }, { 27, 0 }, { 28, 0 }, { 31, -4 }, - { 27, 6 }, { 34, 8 }, { 30, 10 }, { 24, 22 }, - { 33, 19 }, { 22, 32 }, { 26, 31 }, { 21, 41 }, - { 26, 44 }, { 23, 47 }, { 16, 65 }, { 14, 71 }, - { 8, 60 }, { 6, 63 }, { 17, 65 }, { 21, 24 }, - { 23, 20 }, { 26, 23 }, { 27, 32 }, { 28, 23 }, - { 28, 24 }, { 23, 40 }, { 24, 32 }, { 28, 29 }, - { 23, 42 }, { 19, 57 }, { 22, 53 }, { 22, 61 }, - { 11, 86 }, - - /* 399 -> 435 */ - { 12, 40 }, { 11, 51 }, { 14, 59 }, - { -4, 79 }, { -7, 71 }, { -5, 69 }, { -9, 70 }, - { -8, 66 }, { -10, 68 }, { -19, 73 }, { -12, 69 }, - { -16, 70 }, { -15, 67 }, { -20, 62 }, { -19, 70 }, - { -16, 66 }, { -22, 65 }, { -20, 63 }, { 9, -2 }, - { 26, -9 }, { 33, -9 }, { 39, -7 }, { 41, -2 }, - { 45, 3 }, { 49, 9 }, { 45, 27 }, { 36, 59 }, - { -6, 66 }, { -7, 35 }, { -7, 42 }, { -8, 45 }, - { -5, 48 }, { -12, 56 }, { -6, 60 }, { -5, 62 }, - { -8, 66 }, { -8, 76 }, - - /* 436 -> 459 */ - { -5, 85 }, { -6, 81 }, { -10, 77 }, { -7, 81 }, - { -17, 80 }, { -18, 73 }, { -4, 74 }, { -10, 83 }, - { -9, 71 }, { -9, 67 }, { -1, 61 }, { -8, 66 }, - { -14, 66 }, { 0, 59 }, { 2, 59 }, { 21, -13 }, - { 33, -14 }, { 39, -7 }, { 46, -2 }, { 51, 2 }, - { 60, 6 }, { 61, 17 }, { 55, 34 }, { 42, 62 }, - }, - - /* cabac_init_idc == 1 */ - { - /* 0 -> 10 */ - { 20, -15 }, { 2, 54 }, { 3, 74 }, { 20, -15 }, - { 2, 54 }, { 3, 74 }, { -28, 127 }, { -23, 104 }, - { -6, 53 }, { -1, 54 }, { 7, 51 }, - - /* 11 -> 23 */ - { 22, 25 }, { 34, 0 }, { 16, 0 }, { -2, 9 }, - { 4, 41 }, { -29, 118 }, { 2, 65 }, { -6, 71 }, - { -13, 79 }, { 5, 52 }, { 9, 50 }, { -3, 70 }, - { 10, 54 }, - - /* 24 -> 39 */ - { 26, 34 }, { 19, 22 }, { 40, 0 }, { 57, 2 }, - { 41, 36 }, { 26, 69 }, { -45, 127 }, { -15, 101 }, - { -4, 76 }, { -6, 71 }, { -13, 79 }, { 5, 52 }, - { 6, 69 }, { -13, 90 }, { 0, 52 }, { 8, 43 }, - - /* 40 -> 53 */ - { -2, 69 }, { -5, 82 }, { -10, 96 }, { 2, 59 }, - { 2, 75 }, { -3, 87 }, { -3, 100 }, { 1, 56 }, - { -3, 74 }, { -6, 85 }, { 0, 59 }, { -3, 81 }, - { -7, 86 }, { -5, 95 }, - - /* 54 -> 59 */ - { -1, 66 }, { -1, 77 }, { 1, 70 }, { -2, 86 }, - { -5, 72 }, { 0, 61 }, - - /* 60 -> 69 */ - { 0, 41 }, { 0, 63 }, { 0, 63 }, { 0, 63 }, - { -9, 83 }, { 4, 86 }, { 0, 97 }, { -7, 72 }, - { 13, 41 }, { 3, 62 }, - - /* 70 -> 104 */ - { 13, 15 }, { 7, 51 }, { 2, 80 }, { -39, 127 }, - { -18, 91 }, { -17, 96 }, { -26, 81 }, { -35, 98 }, - { -24, 102 }, { -23, 97 }, { -27, 119 }, { -24, 99 }, - { -21, 110 }, { -18, 102 }, { -36, 127 }, { 0, 80 }, - { -5, 89 }, { -7, 94 }, { -4, 92 }, { 0, 39 }, - { 0, 65 }, { -15, 84 }, { -35, 127 }, { -2, 73 }, - { -12, 104 }, { -9, 91 }, { -31, 127 }, { 3, 55 }, - { 7, 56 }, { 7, 55 }, { 8, 61 }, { -3, 53 }, - { 0, 68 }, { -7, 74 }, { -9, 88 }, - - /* 105 -> 165 */ - { -13, 103 }, { -13, 91 }, { -9, 89 }, { -14, 92 }, - { -8, 76 }, { -12, 87 }, { -23, 110 }, { -24, 105 }, - { -10, 78 }, { -20, 112 }, { -17, 99 }, { -78, 127 }, - { -70, 127 }, { -50, 127 }, { -46, 127 }, { -4, 66 }, - { -5, 78 }, { -4, 71 }, { -8, 72 }, { 2, 59 }, - { -1, 55 }, { -7, 70 }, { -6, 75 }, { -8, 89 }, - { -34, 119 }, { -3, 75 }, { 32, 20 }, { 30, 22 }, - { -44, 127 }, { 0, 54 }, { -5, 61 }, { 0, 58 }, - { -1, 60 }, { -3, 61 }, { -8, 67 }, { -25, 84 }, - { -14, 74 }, { -5, 65 }, { 5, 52 }, { 2, 57 }, - { 0, 61 }, { -9, 69 }, { -11, 70 }, { 18, 55 }, - { -4, 71 }, { 0, 58 }, { 7, 61 }, { 9, 41 }, - { 18, 25 }, { 9, 32 }, { 5, 43 }, { 9, 47 }, - { 0, 44 }, { 0, 51 }, { 2, 46 }, { 19, 38 }, - { -4, 66 }, { 15, 38 }, { 12, 42 }, { 9, 34 }, - { 0, 89 }, - - /* 166 -> 226 */ - { 4, 45 }, { 10, 28 }, { 10, 31 }, { 33, -11 }, - { 52, -43 }, { 18, 15 }, { 28, 0 }, { 35, -22 }, - { 38, -25 }, { 34, 0 }, { 39, -18 }, { 32, -12 }, - { 102, -94 }, { 0, 0 }, { 56, -15 }, { 33, -4 }, - { 29, 10 }, { 37, -5 }, { 51, -29 }, { 39, -9 }, - { 52, -34 }, { 69, -58 }, { 67, -63 }, { 44, -5 }, - { 32, 7 }, { 55, -29 }, { 32, 1 }, { 0, 0 }, - { 27, 36 }, { 33, -25 }, { 34, -30 }, { 36, -28 }, - { 38, -28 }, { 38, -27 }, { 34, -18 }, { 35, -16 }, - { 34, -14 }, { 32, -8 }, { 37, -6 }, { 35, 0 }, - { 30, 10 }, { 28, 18 }, { 26, 25 }, { 29, 41 }, - { 0, 75 }, { 2, 72 }, { 8, 77 }, { 14, 35 }, - { 18, 31 }, { 17, 35 }, { 21, 30 }, { 17, 45 }, - { 20, 42 }, { 18, 45 }, { 27, 26 }, { 16, 54 }, - { 7, 66 }, { 16, 56 }, { 11, 73 }, { 10, 67 }, - { -10, 116 }, - - /* 227 -> 275 */ - { -23, 112 }, { -15, 71 }, { -7, 61 }, { 0, 53 }, - { -5, 66 }, { -11, 77 }, { -9, 80 }, { -9, 84 }, - { -10, 87 }, { -34, 127 }, { -21, 101 }, { -3, 39 }, - { -5, 53 }, { -7, 61 }, { -11, 75 }, { -15, 77 }, - { -17, 91 }, { -25, 107 }, { -25, 111 }, { -28, 122 }, - { -11, 76 }, { -10, 44 }, { -10, 52 }, { -10, 57 }, - { -9, 58 }, { -16, 72 }, { -7, 69 }, { -4, 69 }, - { -5, 74 }, { -9, 86 }, { 2, 66 }, { -9, 34 }, - { 1, 32 }, { 11, 31 }, { 5, 52 }, { -2, 55 }, - { -2, 67 }, { 0, 73 }, { -8, 89 }, { 3, 52 }, - { 7, 4 }, { 10, 8 }, { 17, 8 }, { 16, 19 }, - { 3, 37 }, { -1, 61 }, { -5, 73 }, { -1, 70 }, - { -4, 78 }, - - /* 276 special case, bypass used */ - { 0, 0 }, - - /* 277 -> 337 */ - { -21, 126 }, { -23, 124 }, { -20, 110 }, { -26, 126 }, - { -25, 124 }, { -17, 105 }, { -27, 121 }, { -27, 117 }, - { -17, 102 }, { -26, 117 }, { -27, 116 }, { -33, 122 }, - { -10, 95 }, { -14, 100 }, { -8, 95 }, { -17, 111 }, - { -28, 114 }, { -6, 89 }, { -2, 80 }, { -4, 82 }, - { -9, 85 }, { -8, 81 }, { -1, 72 }, { 5, 64 }, - { 1, 67 }, { 9, 56 }, { 0, 69 }, { 1, 69 }, - { 7, 69 }, { -7, 69 }, { -6, 67 }, { -16, 77 }, - { -2, 64 }, { 2, 61 }, { -6, 67 }, { -3, 64 }, - { 2, 57 }, { -3, 65 }, { -3, 66 }, { 0, 62 }, - { 9, 51 }, { -1, 66 }, { -2, 71 }, { -2, 75 }, - { -1, 70 }, { -9, 72 }, { 14, 60 }, { 16, 37 }, - { 0, 47 }, { 18, 35 }, { 11, 37 }, { 12, 41 }, - { 10, 41 }, { 2, 48 }, { 12, 41 }, { 13, 41 }, - { 0, 59 }, { 3, 50 }, { 19, 40 }, { 3, 66 }, - { 18, 50 }, - - /* 338 -> 398 */ - { 19, -6 }, { 18, -6 }, { 14, 0 }, { 26, -12 }, - { 31, -16 }, { 33, -25 }, { 33, -22 }, { 37, -28 }, - { 39, -30 }, { 42, -30 }, { 47, -42 }, { 45, -36 }, - { 49, -34 }, { 41, -17 }, { 32, 9 }, { 69, -71 }, - { 63, -63 }, { 66, -64 }, { 77, -74 }, { 54, -39 }, - { 52, -35 }, { 41, -10 }, { 36, 0 }, { 40, -1 }, - { 30, 14 }, { 28, 26 }, { 23, 37 }, { 12, 55 }, - { 11, 65 }, { 37, -33 }, { 39, -36 }, { 40, -37 }, - { 38, -30 }, { 46, -33 }, { 42, -30 }, { 40, -24 }, - { 49, -29 }, { 38, -12 }, { 40, -10 }, { 38, -3 }, - { 46, -5 }, { 31, 20 }, { 29, 30 }, { 25, 44 }, - { 12, 48 }, { 11, 49 }, { 26, 45 }, { 22, 22 }, - { 23, 22 }, { 27, 21 }, { 33, 20 }, { 26, 28 }, - { 30, 24 }, { 27, 34 }, { 18, 42 }, { 25, 39 }, - { 18, 50 }, { 12, 70 }, { 21, 54 }, { 14, 71 }, - { 11, 83 }, - - /* 399 -> 435 */ - { 25, 32 }, { 21, 49 }, { 21, 54 }, - { -5, 85 }, { -6, 81 }, { -10, 77 }, { -7, 81 }, - { -17, 80 }, { -18, 73 }, { -4, 74 }, { -10, 83 }, - { -9, 71 }, { -9, 67 }, { -1, 61 }, { -8, 66 }, - { -14, 66 }, { 0, 59 }, { 2, 59 }, { 17, -10 }, - { 32, -13 }, { 42, -9 }, { 49, -5 }, { 53, 0 }, - { 64, 3 }, { 68, 10 }, { 66, 27 }, { 47, 57 }, - { -5, 71 }, { 0, 24 }, { -1, 36 }, { -2, 42 }, - { -2, 52 }, { -9, 57 }, { -6, 63 }, { -4, 65 }, - { -4, 67 }, { -7, 82 }, - - /* 436 -> 459 */ - { -3, 81 }, { -3, 76 }, { -7, 72 }, { -6, 78 }, - { -12, 72 }, { -14, 68 }, { -3, 70 }, { -6, 76 }, - { -5, 66 }, { -5, 62 }, { 0, 57 }, { -4, 61 }, - { -9, 60 }, { 1, 54 }, { 2, 58 }, { 17, -10 }, - { 32, -13 }, { 42, -9 }, { 49, -5 }, { 53, 0 }, - { 64, 3 }, { 68, 10 }, { 66, 27 }, { 47, 57 }, - }, - - /* cabac_init_idc == 2 */ - { - /* 0 -> 10 */ - { 20, -15 }, { 2, 54 }, { 3, 74 }, { 20, -15 }, - { 2, 54 }, { 3, 74 }, { -28, 127 }, { -23, 104 }, - { -6, 53 }, { -1, 54 }, { 7, 51 }, - - /* 11 -> 23 */ - { 29, 16 }, { 25, 0 }, { 14, 0 }, { -10, 51 }, - { -3, 62 }, { -27, 99 }, { 26, 16 }, { -4, 85 }, - { -24, 102 }, { 5, 57 }, { 6, 57 }, { -17, 73 }, - { 14, 57 }, - - /* 24 -> 39 */ - { 20, 40 }, { 20, 10 }, { 29, 0 }, { 54, 0 }, - { 37, 42 }, { 12, 97 }, { -32, 127 }, { -22, 117 }, - { -2, 74 }, { -4, 85 }, { -24, 102 }, { 5, 57 }, - { -6, 93 }, { -14, 88 }, { -6, 44 }, { 4, 55 }, - - /* 40 -> 53 */ - { -11, 89 }, { -15, 103 }, { -21, 116 }, { 19, 57 }, - { 20, 58 }, { 4, 84 }, { 6, 96 }, { 1, 63 }, - { -5, 85 }, { -13, 106 }, { 5, 63 }, { 6, 75 }, - { -3, 90 }, { -1, 101 }, - - /* 54 -> 59 */ - { 3, 55 }, { -4, 79 }, { -2, 75 }, { -12, 97 }, - { -7, 50 }, { 1, 60 }, - - /* 60 -> 69 */ - { 0, 41 }, { 0, 63 }, { 0, 63 }, { 0, 63 }, - { -9, 83 }, { 4, 86 }, { 0, 97 }, { -7, 72 }, - { 13, 41 }, { 3, 62 }, - - /* 70 -> 104 */ - { 7, 34 }, { -9, 88 }, { -20, 127 }, { -36, 127 }, - { -17, 91 }, { -14, 95 }, { -25, 84 }, { -25, 86 }, - { -12, 89 }, { -17, 91 }, { -31, 127 }, { -14, 76 }, - { -18, 103 }, { -13, 90 }, { -37, 127 }, { 11, 80 }, - { 5, 76 }, { 2, 84 }, { 5, 78 }, { -6, 55 }, - { 4, 61 }, { -14, 83 }, { -37, 127 }, { -5, 79 }, - { -11, 104 }, { -11, 91 }, { -30, 127 }, { 0, 65 }, - { -2, 79 }, { 0, 72 }, { -4, 92 }, { -6, 56 }, - { 3, 68 }, { -8, 71 }, { -13, 98 }, - - /* 105 -> 165 */ - { -4, 86 }, { -12, 88 }, { -5, 82 }, { -3, 72 }, - { -4, 67 }, { -8, 72 }, { -16, 89 }, { -9, 69 }, - { -1, 59 }, { 5, 66 }, { 4, 57 }, { -4, 71 }, - { -2, 71 }, { 2, 58 }, { -1, 74 }, { -4, 44 }, - { -1, 69 }, { 0, 62 }, { -7, 51 }, { -4, 47 }, - { -6, 42 }, { -3, 41 }, { -6, 53 }, { 8, 76 }, - { -9, 78 }, { -11, 83 }, { 9, 52 }, { 0, 67 }, - { -5, 90 }, { 1, 67 }, { -15, 72 }, { -5, 75 }, - { -8, 80 }, { -21, 83 }, { -21, 64 }, { -13, 31 }, - { -25, 64 }, { -29, 94 }, { 9, 75 }, { 17, 63 }, - { -8, 74 }, { -5, 35 }, { -2, 27 }, { 13, 91 }, - { 3, 65 }, { -7, 69 }, { 8, 77 }, { -10, 66 }, - { 3, 62 }, { -3, 68 }, { -20, 81 }, { 0, 30 }, - { 1, 7 }, { -3, 23 }, { -21, 74 }, { 16, 66 }, - { -23, 124 }, { 17, 37 }, { 44, -18 }, { 50, -34 }, - { -22, 127 }, - - /* 166 -> 226 */ - { 4, 39 }, { 0, 42 }, { 7, 34 }, { 11, 29 }, - { 8, 31 }, { 6, 37 }, { 7, 42 }, { 3, 40 }, - { 8, 33 }, { 13, 43 }, { 13, 36 }, { 4, 47 }, - { 3, 55 }, { 2, 58 }, { 6, 60 }, { 8, 44 }, - { 11, 44 }, { 14, 42 }, { 7, 48 }, { 4, 56 }, - { 4, 52 }, { 13, 37 }, { 9, 49 }, { 19, 58 }, - { 10, 48 }, { 12, 45 }, { 0, 69 }, { 20, 33 }, - { 8, 63 }, { 35, -18 }, { 33, -25 }, { 28, -3 }, - { 24, 10 }, { 27, 0 }, { 34, -14 }, { 52, -44 }, - { 39, -24 }, { 19, 17 }, { 31, 25 }, { 36, 29 }, - { 24, 33 }, { 34, 15 }, { 30, 20 }, { 22, 73 }, - { 20, 34 }, { 19, 31 }, { 27, 44 }, { 19, 16 }, - { 15, 36 }, { 15, 36 }, { 21, 28 }, { 25, 21 }, - { 30, 20 }, { 31, 12 }, { 27, 16 }, { 24, 42 }, - { 0, 93 }, { 14, 56 }, { 15, 57 }, { 26, 38 }, - { -24, 127 }, - - /* 227 -> 275 */ - { -24, 115 }, { -22, 82 }, { -9, 62 }, { 0, 53 }, - { 0, 59 }, { -14, 85 }, { -13, 89 }, { -13, 94 }, - { -11, 92 }, { -29, 127 }, { -21, 100 }, { -14, 57 }, - { -12, 67 }, { -11, 71 }, { -10, 77 }, { -21, 85 }, - { -16, 88 }, { -23, 104 }, { -15, 98 }, { -37, 127 }, - { -10, 82 }, { -8, 48 }, { -8, 61 }, { -8, 66 }, - { -7, 70 }, { -14, 75 }, { -10, 79 }, { -9, 83 }, - { -12, 92 }, { -18, 108 }, { -4, 79 }, { -22, 69 }, - { -16, 75 }, { -2, 58 }, { 1, 58 }, { -13, 78 }, - { -9, 83 }, { -4, 81 }, { -13, 99 }, { -13, 81 }, - { -6, 38 }, { -13, 62 }, { -6, 58 }, { -2, 59 }, - { -16, 73 }, { -10, 76 }, { -13, 86 }, { -9, 83 }, - { -10, 87 }, - - /* 276 special case, bypass used */ - { 0, 0 }, - - /* 277 -> 337 */ - { -22, 127 }, { -25, 127 }, { -25, 120 }, { -27, 127 }, - { -19, 114 }, { -23, 117 }, { -25, 118 }, { -26, 117 }, - { -24, 113 }, { -28, 118 }, { -31, 120 }, { -37, 124 }, - { -10, 94 }, { -15, 102 }, { -10, 99 }, { -13, 106 }, - { -50, 127 }, { -5, 92 }, { 17, 57 }, { -5, 86 }, - { -13, 94 }, { -12, 91 }, { -2, 77 }, { 0, 71 }, - { -1, 73 }, { 4, 64 }, { -7, 81 }, { 5, 64 }, - { 15, 57 }, { 1, 67 }, { 0, 68 }, { -10, 67 }, - { 1, 68 }, { 0, 77 }, { 2, 64 }, { 0, 68 }, - { -5, 78 }, { 7, 55 }, { 5, 59 }, { 2, 65 }, - { 14, 54 }, { 15, 44 }, { 5, 60 }, { 2, 70 }, - { -2, 76 }, { -18, 86 }, { 12, 70 }, { 5, 64 }, - { -12, 70 }, { 11, 55 }, { 5, 56 }, { 0, 69 }, - { 2, 65 }, { -6, 74 }, { 5, 54 }, { 7, 54 }, - { -6, 76 }, { -11, 82 }, { -2, 77 }, { -2, 77 }, - { 25, 42 }, - - /* 338 -> 398 */ - { 17, -13 }, { 16, -9 }, { 17, -12 }, { 27, -21 }, - { 37, -30 }, { 41, -40 }, { 42, -41 }, { 48, -47 }, - { 39, -32 }, { 46, -40 }, { 52, -51 }, { 46, -41 }, - { 52, -39 }, { 43, -19 }, { 32, 11 }, { 61, -55 }, - { 56, -46 }, { 62, -50 }, { 81, -67 }, { 45, -20 }, - { 35, -2 }, { 28, 15 }, { 34, 1 }, { 39, 1 }, - { 30, 17 }, { 20, 38 }, { 18, 45 }, { 15, 54 }, - { 0, 79 }, { 36, -16 }, { 37, -14 }, { 37, -17 }, - { 32, 1 }, { 34, 15 }, { 29, 15 }, { 24, 25 }, - { 34, 22 }, { 31, 16 }, { 35, 18 }, { 31, 28 }, - { 33, 41 }, { 36, 28 }, { 27, 47 }, { 21, 62 }, - { 18, 31 }, { 19, 26 }, { 36, 24 }, { 24, 23 }, - { 27, 16 }, { 24, 30 }, { 31, 29 }, { 22, 41 }, - { 22, 42 }, { 16, 60 }, { 15, 52 }, { 14, 60 }, - { 3, 78 }, { -16, 123 }, { 21, 53 }, { 22, 56 }, - { 25, 61 }, - - /* 399 -> 435 */ - { 21, 33 }, { 19, 50 }, { 17, 61 }, - { -3, 78 }, { -8, 74 }, { -9, 72 }, { -10, 72 }, - { -18, 75 }, { -12, 71 }, { -11, 63 }, { -5, 70 }, - { -17, 75 }, { -14, 72 }, { -16, 67 }, { -8, 53 }, - { -14, 59 }, { -9, 52 }, { -11, 68 }, { 9, -2 }, - { 30, -10 }, { 31, -4 }, { 33, -1 }, { 33, 7 }, - { 31, 12 }, { 37, 23 }, { 31, 38 }, { 20, 64 }, - { -9, 71 }, { -7, 37 }, { -8, 44 }, { -11, 49 }, - { -10, 56 }, { -12, 59 }, { -8, 63 }, { -9, 67 }, - { -6, 68 }, { -10, 79 }, - - /* 436 -> 459 */ - { -3, 78 }, { -8, 74 }, { -9, 72 }, { -10, 72 }, - { -18, 75 }, { -12, 71 }, { -11, 63 }, { -5, 70 }, - { -17, 75 }, { -14, 72 }, { -16, 67 }, { -8, 53 }, - { -14, 59 }, { -9, 52 }, { -11, 68 }, { 9, -2 }, - { 30, -10 }, { 31, -4 }, { 33, -1 }, { 33, 7 }, - { 31, 12 }, { 37, 23 }, { 31, 38 }, { 20, 64 }, - } -}; - -#ifdef H264E_DUMP_DATA_TO_FILE -static MPP_RET hal_h264e_vpu_open_dump_files(void *dump_files) -{ - if (h264e_hal_log_mode & H264E_HAL_LOG_FILE) { - char base_path[512]; - char full_path[512]; - h264e_hal_vpu_dump_files *files = (h264e_hal_vpu_dump_files *)dump_files; - strcpy(base_path, "/sdcard/h264e_data/"); - - sprintf(full_path, "%s%s", base_path, "mpp_syntax_in.txt"); - files->fp_mpp_syntax_in = fopen(full_path, "wb"); - if (!files->fp_mpp_syntax_in) { - mpp_err("%s open error", full_path); - return MPP_ERR_OPEN_FILE; - } - - sprintf(full_path, "%s%s", base_path, "mpp_reg_in.txt"); - files->fp_mpp_reg_in = fopen(full_path, "wb"); - if (!files->fp_mpp_reg_in) { - mpp_err("%s open error", full_path); - return MPP_ERR_OPEN_FILE; - } - - sprintf(full_path, "%s%s", base_path, "mpp_reg_out.txt"); - files->fp_mpp_reg_out = fopen(full_path, "wb"); - if (!files->fp_mpp_reg_out) { - mpp_err("%s open error", full_path); - return MPP_ERR_OPEN_FILE; - } - - sprintf(full_path, "%s%s", base_path, "mpp_feedback.txt"); - files->fp_mpp_feedback = fopen(full_path, "wb"); - if (!files->fp_mpp_feedback) { - mpp_err("%s open error", full_path); - return MPP_ERR_OPEN_FILE; - } - - sprintf(full_path, "%s%s", base_path, "mpp_strm_out.bin"); - files->fp_mpp_strm_out = fopen(full_path, "wb"); - if (!files->fp_mpp_strm_out) { - mpp_err("%s open error", full_path); - return MPP_ERR_OPEN_FILE; - } - } - return MPP_OK; -} - - -static MPP_RET hal_h264e_vpu_close_dump_files(void *dump_files) -{ - h264e_hal_vpu_dump_files *files = (h264e_hal_vpu_dump_files *)dump_files; - H264E_HAL_FCLOSE(files->fp_mpp_syntax_in); - H264E_HAL_FCLOSE(files->fp_mpp_reg_in); - H264E_HAL_FCLOSE(files->fp_mpp_reg_out); - H264E_HAL_FCLOSE(files->fp_mpp_strm_out); - H264E_HAL_FCLOSE(files->fp_mpp_feedback); - return MPP_OK; -} - -static void hal_h264e_vpu_dump_mpp_syntax_in(h264e_syntax *syn, h264e_hal_context *ctx) -{ - h264e_hal_vpu_dump_files *dump_files = (h264e_hal_vpu_dump_files *)ctx->dump_files; - FILE *fp = dump_files->fp_mpp_syntax_in; - if (fp) { - RK_S32 k = 0; - fprintf(fp, "#FRAME %d:\n", ctx->frame_cnt); - fprintf(fp, "%-16d %s\n", syn->frame_coding_type, "frame_coding_type"); - fprintf(fp, "%-16d %s\n", syn->pic_init_qp, "pic_init_qp"); - fprintf(fp, "%-16d %s\n", syn->slice_alpha_offset, "slice_alpha_offset"); - fprintf(fp, "%-16d %s\n", syn->slice_beta_offset, "slice_beta_offset"); - fprintf(fp, "%-16d %s\n", syn->chroma_qp_index_offset, "chroma_qp_index_offset"); - fprintf(fp, "%-16d %s\n", syn->filter_disable, "filter_disable"); - fprintf(fp, "%-16d %s\n", syn->idr_pic_id, "idr_pic_id"); - fprintf(fp, "%-16d %s\n", syn->pps_id, "pps_id"); - fprintf(fp, "%-16d %s\n", syn->frame_num, "frame_num"); - fprintf(fp, "%-16d %s\n", syn->slice_size_mb_rows, "slice_size_mb_rows"); - fprintf(fp, "%-16d %s\n", syn->h264_inter4x4_disabled, "h264_inter4x4_disabled"); - fprintf(fp, "%-16d %s\n", syn->enable_cabac, "enable_cabac"); - fprintf(fp, "%-16d %s\n", syn->transform8x8_mode, "transform8x8_mode"); - fprintf(fp, "%-16d %s\n", syn->cabac_init_idc, "cabac_init_idc"); - fprintf(fp, "%-16d %s\n", syn->qp, "qp"); - fprintf(fp, "%-16d %s\n", syn->mad_qp_delta, "mad_qp_delta"); - fprintf(fp, "%-16d %s\n", syn->mad_threshold, "mad_threshold"); - fprintf(fp, "%-16d %s\n", syn->qp_min, "qp_min"); - fprintf(fp, "%-16d %s\n", syn->qp_max, "qp_max"); - fprintf(fp, "%-16d %s\n", syn->cp_distance_mbs, "cp_distance_mbs"); - for (k = 0; k < 10; k++) - fprintf(fp, "%-16d cp_target[%d]\n", syn->cp_target[k], k); - for (k = 0; k < 7; k++) - fprintf(fp, "%-16d target_error[%d]\n", syn->target_error[k], k); - for (k = 0; k < 7; k++) - fprintf(fp, "%-16d delta_qp[%d]\n", syn->delta_qp[k], k); - fprintf(fp, "%-16d %s\n", syn->output_strm_limit_size, "output_strm_limit_size"); - fprintf(fp, "%-16d %s\n", syn->pic_luma_width, "pic_luma_width"); - fprintf(fp, "%-16d %s\n", syn->pic_luma_height, "pic_luma_height"); - fprintf(fp, "0x%-14x %s\n", syn->input_luma_addr, "input_luma_addr"); - fprintf(fp, "0x%-14x %s\n", syn->input_cb_addr, "input_cb_addr"); - fprintf(fp, "0x%-16x %s\n", syn->input_cr_addr, "input_cr_addr"); - fprintf(fp, "%-16d %s\n", syn->input_image_format, "input_image_format"); - - fprintf(fp, "%-16d %s\n", syn->color_conversion_coeff_a, "color_conversion_coeff_a"); - fprintf(fp, "%-16d %s\n", syn->color_conversion_coeff_b, "color_conversion_coeff_b"); - fprintf(fp, "%-16d %s\n", syn->color_conversion_coeff_c, "color_conversion_coeff_c"); - fprintf(fp, "%-16d %s\n", syn->color_conversion_coeff_e, "color_conversion_coeff_e"); - fprintf(fp, "%-16d %s\n", syn->color_conversion_coeff_f, "color_conversion_coeff_f"); - - fprintf(fp, "\n"); - fflush(fp); - } else { - mpp_log("try to dump data to mpp_syntax_in.txt, but file is not opened"); - } -} - -static void hal_h264e_vpu_dump_mpp_reg_in(h264e_hal_context *ctx) -{ - h264e_hal_vpu_dump_files *dump_files = (h264e_hal_vpu_dump_files *)ctx->dump_files; - FILE *fp = dump_files->fp_mpp_reg_in; - if (fp) { - RK_S32 k = 0; - RK_U32 *reg = (RK_U32 *)ctx->regs; - fprintf(fp, "#FRAME %d:\n", ctx->frame_cnt); - for (k = 0; k < VEPU_H264E_NUM_REGS; k++) { - fprintf(fp, "reg[%03d/%03x]: %08x\n", k, k * 4, reg[k]); - //mpp_log("reg[%03d/%03x]: %08x", k, k*4, reg[k]); - } - fprintf(fp, "\n"); - } else { - mpp_log("try to dump data to mpp_reg_in.txt, but file is not opened"); - } -} - -static void hal_h264e_vpu_dump_mpp_reg_out(h264e_hal_context *ctx) -{ - h264e_hal_vpu_dump_files *dump_files = (h264e_hal_vpu_dump_files *)ctx->dump_files; - FILE *fp = dump_files->fp_mpp_reg_out; - if (fp) { - RK_S32 k = 0; - RK_U32 *reg = (RK_U32 *)ctx->regs; - fprintf(fp, "#FRAME %d:\n", ctx->frame_cnt - 1); - for (k = 0; k < VEPU_H264E_NUM_REGS; k++) { - fprintf(fp, "reg[%03d/%03x]: %08x\n", k, k * 4, reg[k]); - //mpp_log("reg[%03d/%03x]: %08x", k, k*4, reg[k]); - } - fprintf(fp, "\n"); - } else { - mpp_log("try to dump data to mpp_reg_in.txt, but file is not opened"); - } -} - -static void hal_h264e_vpu_dump_mpp_feedback(h264e_hal_context *ctx) -{ - h264e_hal_vpu_dump_files *dump_files = (h264e_hal_vpu_dump_files *)ctx->dump_files; - FILE *fp = dump_files->fp_mpp_feedback; - if (fp) { - RK_S32 k = 0; - h264e_feedback *fb = &ctx->feedback; - fprintf(fp, "#FRAME %d:\n", ctx->frame_cnt - 1); - fprintf(fp, "%-16d %s\n", fb->hw_status, "hw_status"); - fprintf(fp, "%-16d %s\n", fb->out_strm_size, "out_strm_size"); - fprintf(fp, "%-16d %s\n", fb->qp_sum, "qp_sum"); - for (k = 0; k < 10; k++) - fprintf(fp, "%-16d cp[%d]\n", fb->cp[k], k); - fprintf(fp, "%-16d %s\n", fb->mad_count, "mad_count"); - fprintf(fp, "%-16d %s\n", fb->rlc_count, "rlc_count"); - - fprintf(fp, "\n"); - fflush(fp); - } else { - mpp_log("try to dump data to mpp_feedback.txt, but file is not opened"); - } -} - -static void hal_h264e_vpu_dump_mpp_strm_out_header(h264e_hal_context *ctx, MppPacket packet) -{ - h264e_hal_vpu_dump_files *dump_files = (h264e_hal_vpu_dump_files *)ctx->dump_files; - void *ptr = mpp_packet_get_data(packet); - size_t len = mpp_packet_get_length(packet); - FILE *fp = dump_files->fp_mpp_strm_out; - - if (fp) { - fwrite(ptr, 1, len, fp); - fflush(fp); - } else { - mpp_log("try to dump strm header to mpp_strm_out.txt, but file is not opened"); - } -} - -void hal_h264e_vpu_dump_mpp_strm_out(h264e_hal_context *ctx, MppBuffer hw_buf) -{ - h264e_hal_vpu_dump_files *dump_files = (h264e_hal_vpu_dump_files *)ctx->dump_files; - FILE *fp = dump_files->fp_mpp_strm_out; - if (fp && hw_buf) { - RK_U32 *reg_val = (RK_U32 *)ctx->regs; - RK_U32 strm_size = reg_val[VEPU_REG_STR_BUF_LIMIT / 4] / 8; - - RK_U8 *hw_buf_vir_addr = (RK_U8 *)mpp_buffer_get_ptr(hw_buf); - - mpp_log("strm_size: %d", strm_size); - - fwrite(hw_buf_vir_addr, 1, strm_size, fp); - fflush(fp); - } else { - mpp_log("try to dump data to mpp_strm_out.txt, but file is not opened"); - } -} -#endif - -static h264e_hal_vpu_csp_info hal_h264e_vpu_convert_csp(RK_S32 src_type) -{ - MppFrameFormat src_fmt = (MppFrameFormat)src_type; - h264e_hal_vpu_csp_info dst_info; - dst_info.fmt = 0; - dst_info.r_mask_msb = 0; - dst_info.g_mask_msb = 0; - dst_info.b_mask_msb = 0; - - switch (src_fmt) { - case MPP_FMT_YUV420P: { - dst_info.fmt = H264E_VPU_CSP_YUV420P; - break; - } - case MPP_FMT_YUV420SP: { - dst_info.fmt = H264E_VPU_CSP_YUV420SP; - break; - } - case MPP_FMT_YUV420SP_10BIT: { - dst_info.fmt = H264E_VPU_CSP_NONE; - break; - } - case MPP_FMT_YUV420SP_VU: { //TODO: to be confirmed - dst_info.fmt = H264E_VPU_CSP_NONE; - break; - } - case MPP_FMT_YUV422P: { - dst_info.fmt = H264E_VPU_CSP_NONE; - break; - } - case MPP_FMT_YUV422SP: { - dst_info.fmt = H264E_VPU_CSP_NONE; - break; - } - case MPP_FMT_YUV422SP_10BIT: { - dst_info.fmt = H264E_VPU_CSP_NONE; - break; - } - case MPP_FMT_YUV422SP_VU: { - dst_info.fmt = H264E_VPU_CSP_NONE; - break; - } - case MPP_FMT_YUV422_YUYV: { - dst_info.fmt = H264E_VPU_CSP_YUYV422; - break; - } - case MPP_FMT_YUV422_UYVY: { - dst_info.fmt = H264E_VPU_CSP_UYVY422; - break; - } - case MPP_FMT_RGB565: { - dst_info.fmt = H264E_VPU_CSP_RGB565; - dst_info.r_mask_msb = 15; - dst_info.g_mask_msb = 10; - dst_info.b_mask_msb = 4; - break; - } - case MPP_FMT_BGR565: { - dst_info.fmt = H264E_VPU_CSP_RGB565; - dst_info.r_mask_msb = 4; - dst_info.g_mask_msb = 10; - dst_info.b_mask_msb = 15; - break; - } - case MPP_FMT_RGB555: { - dst_info.fmt = H264E_VPU_CSP_RGB555; - dst_info.r_mask_msb = 14; - dst_info.g_mask_msb = 9; - dst_info.b_mask_msb = 4; - break; - } - case MPP_FMT_BGR555: { - dst_info.fmt = H264E_VPU_CSP_RGB555; - dst_info.r_mask_msb = 14; - dst_info.g_mask_msb = 9; - dst_info.b_mask_msb = 4; - break; - } - case MPP_FMT_RGB444: { - dst_info.fmt = H264E_VPU_CSP_RGB444; - dst_info.r_mask_msb = 11; - dst_info.g_mask_msb = 7; - dst_info.b_mask_msb = 3; - break; - } - case MPP_FMT_BGR444: { - dst_info.fmt = H264E_VPU_CSP_RGB444; - dst_info.r_mask_msb = 11; - dst_info.g_mask_msb = 7; - dst_info.b_mask_msb = 3; - break; - } - case MPP_FMT_RGB888: { - dst_info.fmt = H264E_VPU_CSP_RGB888; - dst_info.r_mask_msb = 23; - dst_info.g_mask_msb = 15; - dst_info.b_mask_msb = 7; - break; - } - case MPP_FMT_BGR888: { - dst_info.fmt = H264E_VPU_CSP_RGB888; - dst_info.r_mask_msb = 23; - dst_info.g_mask_msb = 15; - dst_info.b_mask_msb = 7; - break; - } - case MPP_FMT_RGB101010: { - dst_info.fmt = H264E_VPU_CSP_RGB101010; - dst_info.r_mask_msb = 29; - dst_info.g_mask_msb = 19; - dst_info.b_mask_msb = 9; - break; - } - case MPP_FMT_BGR101010: { - dst_info.fmt = H264E_VPU_CSP_RGB101010; - dst_info.r_mask_msb = 29; - dst_info.g_mask_msb = 19; - dst_info.b_mask_msb = 9; - break; - } - case MPP_FMT_ARGB8888: { - dst_info.fmt = H264E_VPU_CSP_NONE; - break; - } - case MPP_FMT_ABGR8888: { - dst_info.fmt = H264E_VPU_CSP_NONE; - break; - } - default: { - h264e_hal_log_err("unvalid src color space: %d", src_type); - dst_info.fmt = H264E_VPU_CSP_NONE; - } - } - - return dst_info; -} - - -static MPP_RET hal_h264e_vpu_free_buffers(h264e_hal_context *ctx) -{ - RK_S32 k = 0; - h264e_hal_vpu_buffers *buffers = (h264e_hal_vpu_buffers *)ctx->buffers; - h264e_hal_debug_enter(); - - if (buffers->hw_cabac_table_buf) { - if (MPP_OK != mpp_buffer_put(buffers->hw_cabac_table_buf)) { - mpp_err("hw_cabac_table_buf put failed"); - return MPP_NOK; - } - } - - if (buffers->hw_nal_size_table_buf) { - if (MPP_OK != mpp_buffer_put(buffers->hw_nal_size_table_buf)) { - mpp_err("hw_nal_size_table_buf put failed"); - return MPP_NOK; - } - } - - - for (k = 0; k < 2; k++) { - if (buffers->hw_rec_buf[k]) { - if (MPP_OK != mpp_buffer_put(buffers->hw_rec_buf[k])) { - mpp_err("hw_rec_buf[%d] put failed", k); - return MPP_NOK; - } - } - } - - if (buffers->hw_buf_grp) { - if (MPP_OK != mpp_buffer_group_put(buffers->hw_buf_grp)) { - mpp_err("buf group[%d] put failed", k); - return MPP_NOK; - } - buffers->hw_buf_grp = NULL; - } - - h264e_hal_debug_leave(); - return MPP_OK; -} - -static void hal_h264e_vpu_swap_endian(RK_U32 *buf, RK_S32 size_bytes) -{ - RK_U32 i = 0; - RK_S32 words = size_bytes / 4; - RK_U32 val, val2, tmp, tmp2; - - mpp_assert((size_bytes % 8) == 0); - - while (words > 0) { - val = buf[i]; - tmp = 0; - - tmp |= (val & 0xFF) << 24; - tmp |= (val & 0xFF00) << 8; - tmp |= (val & 0xFF0000) >> 8; - tmp |= (val & 0xFF000000) >> 24; - - { - val2 = buf[i + 1]; - tmp2 = 0; - - tmp2 |= (val2 & 0xFF) << 24; - tmp2 |= (val2 & 0xFF00) << 8; - tmp2 |= (val2 & 0xFF0000) >> 8; - tmp2 |= (val2 & 0xFF000000) >> 24; - - buf[i] = tmp2; - words--; - i++; - - } - buf[i] = tmp; - words--; - i++; - } -} - -static void hal_h264e_vpu_write_cabac_table(h264e_syntax *syn, MppBuffer hw_cabac_tab_buf) -{ - const RK_S32(*context)[460][2]; - RK_S32 i, j, qp; - - RK_U8 table[H264E_CABAC_TABLE_BUF_SIZE] = {0}; - RK_U32 cabac_init_idc = syn->cabac_init_idc; - - h264e_hal_debug_enter(); - - for (qp = 0; qp < 52; qp++) { /* All QP values */ - for (j = 0; j < 2; j++) { /* Intra/Inter */ - if (j == 0) - /*lint -e(545) */ - context = &h264_context_init_intra; - else - /*lint -e(545) */ - context = &h264_context_init[cabac_init_idc]; - - for (i = 0; i < 460; i++) { - RK_S32 m = (RK_S32)(*context)[i][0]; - RK_S32 n = (RK_S32)(*context)[i][1]; - - RK_S32 pre_ctx_state = H264E_HAL_CLIP3(((m * (RK_S32)qp) >> 4) + n, 1, 126); - - if (pre_ctx_state <= 63) - table[qp * 464 * 2 + j * 464 + i] = (RK_U8)((63 - pre_ctx_state) << 1); - else - table[qp * 464 * 2 + j * 464 + i] = (RK_U8)(((pre_ctx_state - 64) << 1) | 1); - } - } - } - hal_h264e_vpu_swap_endian((RK_U32 *)table, H264E_CABAC_TABLE_BUF_SIZE); - mpp_buffer_write(hw_cabac_tab_buf, 0, table, H264E_CABAC_TABLE_BUF_SIZE); - - h264e_hal_debug_leave(); -} - -static MPP_RET hal_h264e_vpu_allocate_buffers(h264e_hal_context *ctx, h264e_syntax *syn) -{ - MPP_RET ret = MPP_OK; - RK_S32 k = 0; - h264e_hal_vpu_buffers *buffers = (h264e_hal_vpu_buffers *)ctx->buffers; - RK_U32 frame_size = ((syn->pic_luma_width + 15) & (~15)) * ((syn->pic_luma_height + 15) & (~15)) * 3 / 2; - - h264e_hal_debug_enter(); - ret = mpp_buffer_group_get_internal(&buffers->hw_buf_grp, MPP_BUFFER_TYPE_ION); - if (ret) { - mpp_err("buf group get failed ret %d\n", ret); - return ret; - } - - ret = mpp_buffer_get(buffers->hw_buf_grp, &buffers->hw_cabac_table_buf, H264E_CABAC_TABLE_BUF_SIZE); - if (ret) { - mpp_err("hw_cabac_table_buf get failed\n"); - return ret; - } - - ret = mpp_buffer_get(buffers->hw_buf_grp, &buffers->hw_nal_size_table_buf, (sizeof(RK_U32) * (syn->pic_luma_height + 1) + 7) & (~7)); - if (ret) { - mpp_err("hw_nal_size_table_buf get failed\n"); - return ret; - } - - for (k = 0; k < 2; k++) { - ret = mpp_buffer_get(buffers->hw_buf_grp, &buffers->hw_rec_buf[k], frame_size + 4096); - if (ret) { - mpp_err("hw_rec_buf[%d] get failed\n", k); - return ret; - } - } - - hal_h264e_vpu_write_cabac_table(syn, buffers->hw_cabac_table_buf); - - h264e_hal_debug_leave(); - return MPP_OK; -} - - -static MPP_RET hal_h264e_vpu_stream_buffer_status(h264e_hal_vpu_stream *stream) -{ - if (stream->byte_cnt + 5 > stream->size) { - stream->overflow = 1; - return MPP_NOK; - } - - return MPP_OK; -} - -static MPP_RET hal_h264e_vpu_stream_buffer_reset(h264e_hal_vpu_stream *strmbuf) -{ - strmbuf->stream = strmbuf->buffer; - strmbuf->byte_cnt = 0; - strmbuf->overflow = 0; - strmbuf->byte_buffer = 0; - strmbuf->buffered_bits = 0; - strmbuf->zero_bytes = 0; - strmbuf->emul_cnt = 0; - - return MPP_OK; -} - -static MPP_RET hal_h264e_vpu_stream_buffer_init(h264e_hal_vpu_stream *strmbuf, RK_S32 size) -{ - strmbuf->buffer = mpp_calloc(RK_U8, size); - - if (strmbuf->buffer == NULL) { - mpp_err("allocate stream buffer failed\n"); - return MPP_NOK; - } - strmbuf->stream = strmbuf->buffer; - strmbuf->size = size; - strmbuf->byte_cnt = 0; - strmbuf->overflow = 0; - strmbuf->byte_buffer = 0; - strmbuf->buffered_bits = 0; - strmbuf->zero_bytes = 0; - strmbuf->emul_cnt = 0; - - if (MPP_OK != hal_h264e_vpu_stream_buffer_status(strmbuf)) { - mpp_err("stream buffer is overflow, while init"); - return MPP_NOK; - } - - return MPP_OK; -} - - -void hal_h264e_vpu_stream_put_bits(h264e_hal_vpu_stream *buffer, RK_S32 value, RK_S32 number, - const char *name) -{ - RK_S32 bits; - RK_U32 byte_buffer = buffer->byte_buffer; - RK_U8*stream = buffer->stream; - - if (hal_h264e_vpu_stream_buffer_status(buffer) != 0) - return; - - h264e_hal_log_detail("assemble %s value %x, bits %d\n", name, value, number); - - mpp_assert(value < (1 << number)); //opposite to 'BUG_ON' in kernel - mpp_assert(number < 25); - - bits = number + buffer->buffered_bits; - value <<= (32 - bits); - byte_buffer = byte_buffer | value; - - while (bits > 7) { - *stream = (RK_U8)(byte_buffer >> 24); - - bits -= 8; - byte_buffer <<= 8; - stream++; - buffer->byte_cnt++; - } - - buffer->byte_buffer = byte_buffer; - buffer->buffered_bits = (RK_U8)bits; - buffer->stream = stream; - - return; -} - -void hal_h264e_vpu_stream_put_bits_with_detect(h264e_hal_vpu_stream * buffer, RK_S32 value, RK_S32 number, const char *name) -{ - RK_S32 bits; - RK_U8 *stream = buffer->stream; - RK_U32 byte_buffer = buffer->byte_buffer; - - mpp_assert(value < (1 << number)); - mpp_assert(number < 25); - - h264e_hal_log_detail("assemble %s value %x, bits %d\n", name, value, number); - - bits = number + buffer->buffered_bits; - byte_buffer = byte_buffer | ((RK_U32) value << (32 - bits)); - - while (bits > 7) { - RK_S32 zeroBytes = buffer->zero_bytes; - RK_S32 byteCnt = buffer->byte_cnt; - - if (hal_h264e_vpu_stream_buffer_status(buffer) != MPP_OK) - return; - - *stream = (RK_U8) (byte_buffer >> 24); - byteCnt++; - - if ((zeroBytes == 2) && (*stream < 4)) { - *stream++ = 3; - *stream = (RK_U8) (byte_buffer >> 24); - byteCnt++; - zeroBytes = 0; - buffer->emul_cnt++; - } - - if (*stream == 0) - zeroBytes++; - else - zeroBytes = 0; - - bits -= 8; - byte_buffer <<= 8; - stream++; - buffer->zero_bytes = zeroBytes; - buffer->byte_cnt = byteCnt; - buffer->stream = stream; - } - - buffer->buffered_bits = (RK_U8) bits; - buffer->byte_buffer = byte_buffer; -} - - -void hal_h264e_vpu_rbsp_trailing_bits(h264e_hal_vpu_stream * stream) -{ - hal_h264e_vpu_stream_put_bits_with_detect(stream, 1, 1, "rbsp_stop_one_bit"); - if (stream->buffered_bits > 0) { - hal_h264e_vpu_stream_put_bits_with_detect(stream, 0, 8 - stream->buffered_bits, "bsp_alignment_zero_bit(s)"); - } -} - -static void hal_h264e_vpu_write_ue(h264e_hal_vpu_stream *fifo, RK_U32 val, - const char *name) -{ - RK_U32 num_bits = 0; - - val++; - while (val >> ++num_bits); - - if (num_bits > 12) { - RK_U32 tmp; - - tmp = num_bits - 1; - - if (tmp > 24) { - tmp -= 24; - hal_h264e_vpu_stream_put_bits_with_detect(fifo, 0, 24, name); - } - - hal_h264e_vpu_stream_put_bits_with_detect(fifo, 0, tmp, name); - - if (num_bits > 24) { - num_bits -= 24; - hal_h264e_vpu_stream_put_bits_with_detect(fifo, val >> num_bits, 24, name); - val = val >> num_bits; - } - - hal_h264e_vpu_stream_put_bits_with_detect(fifo, val, num_bits, name); - } else { - hal_h264e_vpu_stream_put_bits_with_detect(fifo, val, 2 * num_bits - 1, name); - } -} - -static void hal_h264e_vpu_write_se(h264e_hal_vpu_stream *fifo, RK_S32 val, const char *name) -{ - RK_U32 tmp; - - if (val > 0) - tmp = (RK_U32)(2 * val - 1); - else - tmp = (RK_U32)(-2 * val); - - hal_h264e_vpu_write_ue(fifo, tmp, name); -} - -static MPP_RET hal_h264e_vpu_nal_start(h264e_hal_vpu_stream * stream, RK_S32 nalRefIdc, rkvenc_nal_unit_type nalUnitType) -{ - hal_h264e_vpu_stream_put_bits(stream, 0, 8, "leadin_zero_8bits"); - hal_h264e_vpu_stream_put_bits(stream, 0, 8, "start_code_prefix"); - hal_h264e_vpu_stream_put_bits(stream, 0, 8, "start_code_prefix"); - hal_h264e_vpu_stream_put_bits(stream, 1, 8, "start_code_prefix"); - hal_h264e_vpu_stream_put_bits(stream, 0, 1, "forbidden_zero_bit"); - hal_h264e_vpu_stream_put_bits(stream, nalRefIdc, 2, "nal_ref_idc"); - hal_h264e_vpu_stream_put_bits(stream, (RK_S32)nalUnitType, 5, "nal_unit_type"); - stream->zero_bytes = 0; /* we start new counter for zero bytes */ - - return MPP_OK; -} - - - -static MPP_RET hal_h264e_vpu_write_sps(h264e_hal_vpu_stream *stream, h264e_hal_sps *sps) -{ - h264e_hal_debug_enter(); - - hal_h264e_vpu_nal_start(stream, 1, RKVENC_NAL_SPS); - - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->i_profile_idc, 8, "profile_idc"); //FIXED: 77, 42 - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_constraint_set0, 1, "constraint_set0_flag"); //E0 - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_constraint_set1, 1, "constraint_set1_flag"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_constraint_set2, 1, "constraint_set2_flag"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_constraint_set3, 1, "constraint_set3_flag"); - - hal_h264e_vpu_stream_put_bits_with_detect(stream, 0, 4, "reserved_zero_4bits"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->i_level_idc, 8, "level_idc"); //28 - - hal_h264e_vpu_write_ue(stream, sps->i_id, "seq_parameter_set_id"); //8D - - if (sps->i_profile_idc >= 100) { //High profile - hal_h264e_vpu_write_ue(stream, sps->i_chroma_format_idc, "chroma_format_idc"); - hal_h264e_vpu_write_ue(stream, H264_BIT_DEPTH - 8, "bit_depth_luma_minus8"); - hal_h264e_vpu_write_ue(stream, H264_BIT_DEPTH - 8, "bit_depth_chroma_minus8"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_qpprime_y_zero_transform_bypass, 1, "qpprime_y_zero_transform_bypass_flag"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, 0, 1, "seq_scaling_matrix_present_flag"); - } - - hal_h264e_vpu_write_ue(stream, sps->i_log2_max_frame_num - 4, "log2_max_frame_num_minus4"); - - hal_h264e_vpu_write_ue(stream, sps->i_poc_type, "pic_order_cnt_type"); //68 16 - - hal_h264e_vpu_write_ue(stream, sps->i_num_ref_frames, "num_ref_frames"); - - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_gaps_in_frame_num_value_allowed, 1, "gaps_in_frame_num_value_allowed_flag"); - - hal_h264e_vpu_write_ue(stream, sps->i_mb_width - 1, "pic_width_in_mbs_minus1"); - - hal_h264e_vpu_write_ue(stream, sps->i_mb_height - 1, "pic_height_in_map_units_minus1"); //09 64 - - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_frame_mbs_only, 1, "frame_mbs_only_flag"); - - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_direct8x8_inference, 1, "direct_8x8_inference_flag"); - - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_crop, 1, "frame_cropping_flag"); - if (sps->b_crop) { - hal_h264e_vpu_write_ue(stream, sps->crop.i_left / 2, "frame_crop_left_offset"); - hal_h264e_vpu_write_ue(stream, sps->crop.i_right / 2, "frame_crop_right_offset"); - hal_h264e_vpu_write_ue(stream, sps->crop.i_top / 2, "frame_crop_top_offset"); - hal_h264e_vpu_write_ue(stream, sps->crop.i_bottom / 2, "frame_crop_bottom_offset"); - } - - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_vui, 1, "vui_parameters_present_flag"); - if (sps->b_vui) { - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_aspect_ratio_info_present, 1, "aspect_ratio_info_present_flag"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_overscan_info_present, 1, "overscan_info_present_flag"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_signal_type_present, 1, "video_signal_type_present_flag"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_chroma_loc_info_present, 1, "chroma_loc_info_present_flag"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_timing_info_present, 1, "timing_info_present_flag"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.i_num_units_in_tick >> 16, 16, "num_units_in_tick msb"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.i_num_units_in_tick & 0xffff, 16, "num_units_in_tick lsb"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.i_time_scale >> 16, 16, "time_scale msb"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.i_time_scale & 0xffff, 16, "time_scale lsb"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_fixed_frame_rate, 1, "fixed_frame_rate_flag"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_nal_hrd_parameters_present, 1, "nal_hrd_parameters_present_flag"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_vcl_hrd_parameters_present, 1, "vcl_hrd_parameters_present_flag"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_pic_struct_present, 1, "pic_struct_present_flag"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_bitstream_restriction, 1, "bit_stream_restriction_flag"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_motion_vectors_over_pic_boundaries, 1, "motion_vectors_over_pic_boundaries"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.i_max_bytes_per_pic_denom, 1, "max_bytes_per_pic_denom"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.i_max_bits_per_mb_denom, 1, "max_bits_per_mb_denom"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.i_log2_max_mv_length_horizontal, 7, "log2_mv_length_horizontal"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.i_log2_max_mv_length_vertical, 5, "log2_mv_length_vertical"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.i_num_reorder_frames, 1, "num_reorder_frames"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.i_max_dec_frame_buffering, 3, "max_dec_frame_buffering"); - } - - hal_h264e_vpu_rbsp_trailing_bits(stream); - - h264e_hal_log_detail("sps write size: %d bytes", stream->byte_cnt); - - h264e_hal_debug_leave(); - - return MPP_OK; -} - -static MPP_RET hal_h264e_vpu_write_pps(h264e_hal_vpu_stream *stream, h264e_hal_pps *pps) -{ - h264e_hal_debug_enter(); - - hal_h264e_vpu_nal_start(stream, 1, RKVENC_NAL_PPS); - - hal_h264e_vpu_write_ue(stream, pps->i_id, "pic_parameter_set_id"); - hal_h264e_vpu_write_ue(stream, pps->i_sps_id, "seq_parameter_set_id"); - - hal_h264e_vpu_stream_put_bits_with_detect(stream, pps->b_cabac, 1, "entropy_coding_mode_flag"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, pps->b_pic_order, 1, "pic_order_present_flag"); - - hal_h264e_vpu_write_ue(stream, pps->i_num_slice_groups - 1, "num_slice_groups_minus1"); - hal_h264e_vpu_write_ue(stream, pps->i_num_ref_idx_l0_default_active - 1, "num_ref_idx_l0_active_minus1"); - hal_h264e_vpu_write_ue(stream, pps->i_num_ref_idx_l1_default_active - 1, "num_ref_idx_l1_active_minus1"); - - hal_h264e_vpu_stream_put_bits_with_detect(stream, pps->b_weighted_pred, 1, "weighted_pred_flag"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, pps->i_weighted_bipred_idc, 2, "weighted_bipred_idc"); - - hal_h264e_vpu_write_se(stream, pps->i_pic_init_qp - 26, "pic_init_qp_minus26"); - hal_h264e_vpu_write_se(stream, pps->i_pic_init_qs - 26, "pic_init_qs_minus26"); - hal_h264e_vpu_write_se(stream, pps->i_chroma_qp_index_offset, "chroma_qp_index_offset"); - - hal_h264e_vpu_stream_put_bits_with_detect(stream, pps->b_deblocking_filter_control, 1, "deblocking_filter_control_present_flag"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, pps->b_constrained_intra_pred, 1, "constrained_intra_pred_flag"); - - hal_h264e_vpu_stream_put_bits_with_detect(stream, pps->b_redundant_pic_cnt, 1, "redundant_pic_cnt_present_flag"); - - if (pps->b_transform_8x8_mode) { - hal_h264e_vpu_stream_put_bits_with_detect(stream, pps->b_transform_8x8_mode, 1, "transform_8x8_mode_flag"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, pps->b_cqm_preset, 1, "pic_scaling_matrix_present_flag"); - hal_h264e_vpu_write_se(stream, pps->i_chroma_qp_index_offset, "chroma_qp_index_offset"); - } - - hal_h264e_vpu_rbsp_trailing_bits(stream); - - h264e_hal_log_detail("pps write size: %d bytes", stream->byte_cnt); - - h264e_hal_debug_leave(); - - return MPP_OK; -} - -static void hal_h264e_vpu_set_sps(h264e_hal_sps *sps, h264e_control_extra_info_cfg *cfg) -{ - sps->i_profile_idc = cfg->profile_idc; /* 66 = baseline, 77 = main, 100 = high */ - sps->b_constraint_set0 = 0; - sps->b_constraint_set1 = 0; - sps->b_constraint_set2 = 0; - sps->b_constraint_set3 = 0; - - sps->i_level_idc = cfg->level_idc; - sps->i_id = 0; - sps->i_log2_max_frame_num = 16; - sps->i_poc_type = 2; - - sps->i_num_ref_frames = 1; - sps->b_gaps_in_frame_num_value_allowed = 0; - sps->i_mb_width = ( cfg->pic_luma_width + 15 ) / 16; - sps->i_mb_height = ( cfg->pic_luma_height + 15 ) / 16; - sps->b_frame_mbs_only = 1; - sps->b_direct8x8_inference = 1; - sps->i_chroma_format_idc = 1; //YUV420 - - sps->b_vui = 1; - - sps->vui.b_fullrange = 0; - sps->vui.i_sar_width = 0; - sps->vui.i_sar_height = 0; - sps->vui.b_aspect_ratio_info_present = 0; - sps->vui.b_overscan_info_present = 0; - sps->vui.b_signal_type_present = 0; - sps->vui.b_chroma_loc_info_present = 0; - - sps->vui.b_timing_info_present = 1; - sps->vui.i_num_units_in_tick = 1; - sps->vui.i_time_scale = cfg->frame_rate * 2; - sps->vui.b_fixed_frame_rate = 0; - - sps->vui.b_nal_hrd_parameters_present = 0; - sps->vui.b_vcl_hrd_parameters_present = 0; - sps->vui.b_pic_struct_present = 0; - - sps->vui.b_bitstream_restriction = 1; - sps->vui.b_motion_vectors_over_pic_boundaries = 1; - sps->vui.i_max_bytes_per_pic_denom = 1; - sps->vui.i_max_bits_per_mb_denom = 1; - sps->vui.i_log2_max_mv_length_horizontal = 8; - sps->vui.i_log2_max_mv_length_vertical = 7; - sps->vui.i_num_reorder_frames = 1; - sps->vui.i_max_dec_frame_buffering = 2; - - if (cfg->pic_luma_width % 16 || cfg->pic_luma_height % 16 ) { - RK_U32 fill_right = sps->i_mb_width * 16 - cfg->pic_luma_width; - RK_U32 fill_bottom = sps->i_mb_height * 16 - cfg->pic_luma_height; - sps->b_crop = 1; - sps->crop.i_right = fill_right; - sps->crop.i_bottom = fill_bottom; - sps->crop.i_left = 0; - sps->crop.i_top = 0; - } else { - sps->b_crop = 0; - sps->crop.i_right = 0; - sps->crop.i_bottom = 0; - sps->crop.i_left = 0; - sps->crop.i_top = 0; - } - - /* only for backup, exclued in read SPS */ - sps->keyframe_max_interval = cfg->keyframe_max_interval; -} - -static void hal_h264e_vpu_set_pps(h264e_hal_pps *pps, h264e_control_extra_info_cfg *cfg) -{ - pps->i_id = 0; - pps->i_sps_id = 0; - pps->b_cabac = cfg->enable_cabac; - pps->b_pic_order = 0; - pps->i_num_slice_groups = 1; - pps->i_num_ref_idx_l0_default_active = 1; - pps->i_num_ref_idx_l1_default_active = 1; - pps->b_weighted_pred = 0; - pps->i_weighted_bipred_idc = 0; - pps->i_pic_init_qp = cfg->pic_init_qp; - pps->i_pic_init_qs = cfg->pic_init_qp; - pps->i_chroma_qp_index_offset = cfg->chroma_qp_index_offset; - pps->b_deblocking_filter_control = 1; - pps->b_constrained_intra_pred = 0; - pps->b_redundant_pic_cnt = 0; - pps->b_transform_8x8_mode = cfg->transform8x8_mode; - - (void)cfg; -} - -static MPP_RET hal_h264e_vpu_init_extra_info(void *extra_info) -{ - h264e_hal_vpu_extra_info *info = (h264e_hal_vpu_extra_info *)extra_info; - h264e_hal_vpu_stream *sps_stream = &info->sps_stream; - h264e_hal_vpu_stream *pps_stream = &info->pps_stream; - - if (MPP_OK != hal_h264e_vpu_stream_buffer_init(sps_stream, 128)) { - mpp_err("sps stream sw buf init failed"); - return MPP_NOK; - } - if (MPP_OK != hal_h264e_vpu_stream_buffer_init(pps_stream, 128)) { - mpp_err("pps stream sw buf init failed"); - return MPP_NOK; - } - - return MPP_OK; -} - -static MPP_RET hal_h264e_vpu_deinit_extra_info(void *extra_info) -{ - h264e_hal_vpu_extra_info *info = (h264e_hal_vpu_extra_info *)extra_info; - h264e_hal_vpu_stream *sps_stream = &info->sps_stream; - h264e_hal_vpu_stream *pps_stream = &info->pps_stream; - - MPP_FREE(sps_stream->buffer); - MPP_FREE(pps_stream->buffer); - - return MPP_OK; -} - -static MPP_RET hal_h264e_vpu_set_extra_info(h264e_hal_context *ctx, void *param) -{ - h264e_control_extra_info_cfg *cfg = (h264e_control_extra_info_cfg *)param; - h264e_hal_vpu_extra_info *info = (h264e_hal_vpu_extra_info *)ctx->extra_info; - h264e_hal_vpu_stream *sps_stream = &info->sps_stream; - h264e_hal_vpu_stream *pps_stream = &info->pps_stream; - h264e_hal_sps *sps = &info->sps; - h264e_hal_pps *pps = &info->pps; - h264e_hal_debug_enter(); - - info->sei.extra_info_cfg = *cfg; - hal_h264e_vpu_stream_buffer_reset(sps_stream); - hal_h264e_vpu_stream_buffer_reset(pps_stream); - - hal_h264e_vpu_set_sps(sps, cfg); - hal_h264e_vpu_set_pps(pps, cfg); - - hal_h264e_vpu_write_sps(sps_stream, sps); - hal_h264e_vpu_write_pps(pps_stream, pps); - - h264e_hal_debug_leave(); - - return MPP_OK; -} - -static RK_S32 exp_golomb_signed(RK_S32 val) -{ - RK_S32 tmp = 0; - - if (val > 0) - val = 2 * val; - else - val = -2 * val + 1; - - while (val >> ++tmp) - ; - - return tmp * 2 - 1; -} - - -MPP_RET hal_h264e_vpu_init(void *hal, MppHalCfg *cfg) -{ - h264e_hal_context *ctx = (h264e_hal_context *)hal; - h264e_hal_debug_enter(); - - ctx->int_cb = cfg->hal_int_cb; - ctx->regs = mpp_calloc(h264e_vpu_reg_set, 1); - ctx->buffers = mpp_calloc(h264e_hal_vpu_buffers, 1); - ctx->extra_info = mpp_calloc(h264e_hal_vpu_extra_info, 1); - ctx->dump_files = mpp_calloc(h264e_hal_vpu_dump_files, 1); - ctx->param_buf = mpp_calloc_size(void, H264E_EXTRA_INFO_BUF_SIZE); - mpp_packet_init(&ctx->packeted_param, ctx->param_buf, H264E_EXTRA_INFO_BUF_SIZE); - - hal_h264e_vpu_init_extra_info(ctx->extra_info); -#ifdef H264E_DUMP_DATA_TO_FILE - hal_h264e_vpu_open_dump_files(ctx->dump_files); -#endif - - ctx->vpu_socket = -1; - ctx->vpu_client = VPU_ENC; - h264e_hal_log_detail("vpu client: %d", ctx->vpu_client); -#ifdef RKPLATFORM - if (ctx->vpu_socket <= 0) { - ctx->vpu_socket = VPUClientInit(ctx->vpu_client); - if (ctx->vpu_socket <= 0) { - mpp_err("get vpu_socket(%d) <=0, failed. \n", ctx->vpu_socket); - return MPP_ERR_UNKNOW; - } else { - VPUHwEncConfig_t hwCfg; - h264e_hal_log_detail("get vpu_socket(%d), success. \n", ctx->vpu_socket); - memset(&hwCfg, 0, sizeof(VPUHwEncConfig_t)); - if (VPUClientGetHwCfg(ctx->vpu_socket, (RK_U32*)&hwCfg, sizeof(hwCfg))) { - mpp_err("h264enc # Get HwCfg failed, release vpu\n"); - VPUClientRelease(ctx->vpu_socket); - return MPP_NOK; - } - } - } -#endif - - h264e_hal_debug_leave(); - return MPP_OK; -} - -MPP_RET hal_h264e_vpu_deinit(void *hal) -{ - h264e_hal_context *ctx = (h264e_hal_context *)hal; - h264e_hal_debug_enter(); - - MPP_FREE(ctx->regs); - MPP_FREE(ctx->param_buf); - - if (ctx->extra_info) { - hal_h264e_vpu_deinit_extra_info(ctx->extra_info); - MPP_FREE(ctx->extra_info); - } - - if (ctx->packeted_param) { - mpp_packet_deinit(&ctx->packeted_param); - ctx->packeted_param = NULL; - } - - if (ctx->buffers) { - hal_h264e_vpu_free_buffers(ctx); - MPP_FREE(ctx->buffers); - } - -#ifdef H264E_DUMP_DATA_TO_FILE - if (ctx->dump_files) { - hal_h264e_vpu_close_dump_files(ctx->dump_files); - MPP_FREE(ctx->dump_files); - } -#endif - -#ifdef RKPLATFORM - if (ctx->vpu_socket <= 0) { - mpp_err("invalid vpu socket: %d", ctx->vpu_socket); - return MPP_NOK; - } - - if (VPU_SUCCESS != VPUClientRelease(ctx->vpu_socket)) { - mpp_err("VPUClientRelease failed"); - return MPP_ERR_VPUHW; - } -#endif - - h264e_hal_debug_leave(); - return MPP_OK; -} - -static MPP_RET hal_h264e_vpu_validate_syntax(h264e_syntax *syn, h264e_hal_vpu_csp_info *src_fmt) -{ - MPP_RET ret = MPP_OK; - RK_U32 width_align16 = MPP_ALIGN(syn->pic_luma_width, 16); - RK_U32 height_align16 = MPP_ALIGN(syn->pic_luma_height, 16); - - h264e_hal_debug_enter(); - - /* validate */ - H264E_HAL_VALIDATE_GT(syn->output_strm_limit_size, "output_strm_limit_size", 0); - - /* adjust */ - syn->output_strm_limit_size /= 8; /* 64-bit addresses */ - syn->output_strm_limit_size &= (~0x07); /* 8 multiple size */ - *src_fmt = hal_h264e_vpu_convert_csp(syn->input_image_format); - syn->input_image_format = src_fmt->fmt; - - H264E_HAL_VALIDATE_NEQ(syn->input_image_format, "input_image_format", H264E_VPU_CSP_NONE); - - if (syn->pic_hor_stride != syn->pic_luma_width && - syn->pic_hor_stride != width_align16) { - mpp_err_f("syn->pic_hor_stride %d is not supported for vpu", syn->pic_hor_stride); - ret = MPP_NOK; - goto err; - } - if (syn->pic_ver_stride != syn->pic_luma_height && - syn->pic_ver_stride != height_align16) { - mpp_err_f("syn->pic_ver_stride %d is not supported for vpu", syn->pic_ver_stride); - ret = MPP_NOK; - goto err; - } - -err: - - h264e_hal_debug_leave(); - - return ret; -} - - -MPP_RET hal_h264e_vpu_gen_regs(void *hal, HalTaskInfo *task) -{ - RK_S32 scaler = 0, i = 0; - RK_U32 val = 0, skip_penalty = 0; - RK_U32 overfill_r = 0, overfill_b = 0; - RK_U32 first_free_bit = 0, constrained_intra_prediction = 0; - RK_U8 dmv_penalty[128] = {0}; - RK_U8 dmv_qpel_penalty[128] = {0}; - RK_U32 diff_mv_penalty[3] = {0}; - h264e_hal_vpu_csp_info src_fmt; - - h264e_hal_context *ctx = (h264e_hal_context *)hal; - RK_U32 *reg = (RK_U32 *)ctx->regs; - h264e_syntax *syn = (h264e_syntax *)task->enc.syntax.data; - - RK_U32 mbs_in_row = (syn->pic_luma_width + 15) / 16; - RK_U32 mbs_in_col = (syn->pic_luma_height + 15) / 16; - RK_U32 prev_mode_favor = h264_prev_mode_favor[syn->qp]; - h264e_hal_vpu_buffers *bufs = (h264e_hal_vpu_buffers *)ctx->buffers; - RK_U32 buf2_idx = ctx->frame_cnt % 2; - h264e_hal_vpu_extra_info *extra_info = (h264e_hal_vpu_extra_info *)ctx->extra_info; - h264e_hal_pps *pps = &extra_info->pps; - h264e_hal_debug_enter(); - - if (ctx->frame_cnt == 0) { - if (MPP_OK != hal_h264e_vpu_allocate_buffers(ctx, syn)) { - h264e_hal_log_err("hal_h264e_vpu_allocate_buffers failed, free now"); - hal_h264e_vpu_free_buffers(ctx); - } - } - -#ifdef H264E_DUMP_DATA_TO_FILE - hal_h264e_vpu_dump_mpp_syntax_in(syn, ctx); -#endif - if (MPP_OK != hal_h264e_vpu_validate_syntax(syn, &src_fmt)) { - h264e_hal_log_err("hal_h264e_vpu_validate_syntax failed"); - } - memset(reg, 0, sizeof(h264e_vpu_reg_set)); - - h264e_hal_log_detail("frame %d generate regs now", ctx->frame_cnt); - - /* If frame encode type for current frame is intra, write sps pps to - the output buffer */ - H264E_HAL_SET_REG(reg, VEPU_REG_STR_BUF_LIMIT, syn->output_strm_limit_size); - - /* - * The hardware needs only the value for luma plane, because - * values of other planes are calculated internally based on - * format setting. - */ - val = VEPU_REG_INTRA_AREA_TOP(mbs_in_col) - | VEPU_REG_INTRA_AREA_BOTTOM(mbs_in_col) - | VEPU_REG_INTRA_AREA_LEFT(mbs_in_row) - | VEPU_REG_INTRA_AREA_RIGHT(mbs_in_row); - H264E_HAL_SET_REG(reg, VEPU_REG_INTRA_AREA_CTRL, val); //FIXED - H264E_HAL_SET_REG(reg, VEPU_REG_STR_HDR_REM_MSB, 0); - H264E_HAL_SET_REG(reg, VEPU_REG_STR_HDR_REM_LSB, 0); - - - val = VEPU_REG_AXI_CTRL_READ_ID(0); - val |= VEPU_REG_AXI_CTRL_WRITE_ID(0); - val |= VEPU_REG_AXI_CTRL_BURST_LEN(16); - val |= VEPU_REG_AXI_CTRL_INCREMENT_MODE(0); - val |= VEPU_REG_AXI_CTRL_BIRST_DISCARD(0); - H264E_HAL_SET_REG(reg, VEPU_REG_AXI_CTRL, val); - - H264E_HAL_SET_REG(reg, VEPU_QP_ADJUST_MAD_DELTA_ROI, syn->mad_qp_delta); - - val = 0; - if (mbs_in_row * mbs_in_col > 3600) - val = VEPU_REG_DISABLE_QUARTER_PIXEL_MV; - val |= VEPU_REG_CABAC_INIT_IDC(syn->cabac_init_idc); - if (pps->b_cabac) - val |= VEPU_REG_ENTROPY_CODING_MODE; - if (pps->b_transform_8x8_mode) - val |= VEPU_REG_H264_TRANS8X8_MODE; - if (syn->h264_inter4x4_disabled) - val |= VEPU_REG_H264_INTER4X4_MODE; - /*reg |= VEPU_REG_H264_STREAM_MODE;*/ - val |= VEPU_REG_H264_SLICE_SIZE(syn->slice_size_mb_rows); - H264E_HAL_SET_REG(reg, VEPU_REG_ENC_CTRL0, val); - - scaler = H264E_HAL_MAX(1, 200 / (mbs_in_row + mbs_in_col)); - skip_penalty = H264E_HAL_MIN(255, h264_skip_sad_penalty[syn->qp] * scaler); - if (syn->pic_luma_width & 0x0f) - overfill_r = (16 - (syn->pic_luma_width & 0x0f) ) / 4; - if (syn->pic_luma_height & 0x0f) - overfill_b = 16 - (syn->pic_luma_height & 0x0f); - val = VEPU_REG_STREAM_START_OFFSET(first_free_bit) | - VEPU_REG_SKIP_MACROBLOCK_PENALTY(skip_penalty) | - VEPU_REG_IN_IMG_CTRL_OVRFLR_D4(overfill_r) | - VEPU_REG_IN_IMG_CTRL_OVRFLB(overfill_b); - H264E_HAL_SET_REG(reg, VEPU_REG_ENC_OVER_FILL_STRM_OFFSET, val); - - - val = VEPU_REG_IN_IMG_CHROMA_OFFSET(0) - | VEPU_REG_IN_IMG_LUMA_OFFSET(0) - | VEPU_REG_IN_IMG_CTRL_ROW_LEN(syn->pic_luma_width); - H264E_HAL_SET_REG(reg, VEPU_REG_INPUT_LUMA_INFO, val); - - val = VEPU_REG_CHECKPOINT_CHECK1(syn->cp_target[0]) - | VEPU_REG_CHECKPOINT_CHECK0(syn->cp_target[1]); - H264E_HAL_SET_REG(reg, VEPU_REG_CHECKPOINT(0), val); - - val = VEPU_REG_CHECKPOINT_CHECK1(syn->cp_target[2]) - | VEPU_REG_CHECKPOINT_CHECK0(syn->cp_target[3]); - H264E_HAL_SET_REG(reg, VEPU_REG_CHECKPOINT(1), val); - - val = VEPU_REG_CHECKPOINT_CHECK1(syn->cp_target[4]) - | VEPU_REG_CHECKPOINT_CHECK0(syn->cp_target[5]); - H264E_HAL_SET_REG(reg, VEPU_REG_CHECKPOINT(2), val); - - val = VEPU_REG_CHECKPOINT_CHECK1(syn->cp_target[6]) - | VEPU_REG_CHECKPOINT_CHECK0(syn->cp_target[7]); - H264E_HAL_SET_REG(reg, VEPU_REG_CHECKPOINT(3), val); - - val = VEPU_REG_CHECKPOINT_CHECK1(syn->cp_target[8]) - | VEPU_REG_CHECKPOINT_CHECK0(syn->cp_target[9]); - H264E_HAL_SET_REG(reg, VEPU_REG_CHECKPOINT(4), val); - - val = VEPU_REG_CHKPT_WORD_ERR_CHK1(syn->target_error[0]) - | VEPU_REG_CHKPT_WORD_ERR_CHK0(syn->target_error[1]); - H264E_HAL_SET_REG(reg, VEPU_REG_CHKPT_WORD_ERR(0), val); - - val = VEPU_REG_CHKPT_WORD_ERR_CHK1(syn->target_error[2]) - | VEPU_REG_CHKPT_WORD_ERR_CHK0(syn->target_error[3]); - H264E_HAL_SET_REG(reg, VEPU_REG_CHKPT_WORD_ERR(1), val); - - val = VEPU_REG_CHKPT_WORD_ERR_CHK1(syn->target_error[4]) - | VEPU_REG_CHKPT_WORD_ERR_CHK0(syn->target_error[5]); - H264E_HAL_SET_REG(reg, VEPU_REG_CHKPT_WORD_ERR(2), val); - - val = VEPU_REG_CHKPT_DELTA_QP_CHK6(syn->delta_qp[6]) - | VEPU_REG_CHKPT_DELTA_QP_CHK5(syn->delta_qp[5]) - | VEPU_REG_CHKPT_DELTA_QP_CHK4(syn->delta_qp[4]) - | VEPU_REG_CHKPT_DELTA_QP_CHK3(syn->delta_qp[3]) - | VEPU_REG_CHKPT_DELTA_QP_CHK2(syn->delta_qp[2]) - | VEPU_REG_CHKPT_DELTA_QP_CHK1(syn->delta_qp[1]) - | VEPU_REG_CHKPT_DELTA_QP_CHK0(syn->delta_qp[0]); - H264E_HAL_SET_REG(reg, VEPU_REG_CHKPT_DELTA_QP, val); - - val = VEPU_REG_MAD_THRESHOLD(syn->mad_threshold) - | VEPU_REG_IN_IMG_CTRL_FMT(src_fmt.fmt) - | VEPU_REG_IN_IMG_ROTATE_MODE(0) - | VEPU_REG_SIZE_TABLE_PRESENT; //FIXED - H264E_HAL_SET_REG(reg, VEPU_REG_ENC_CTRL1, val); - - val = VEPU_REG_INTRA16X16_MODE(h264_intra16_favor[syn->qp]) - | VEPU_REG_INTER_MODE(h264_inter_favor[syn->qp]); - H264E_HAL_SET_REG(reg, VEPU_REG_INTRA_INTER_MODE, val); - - val = VEPU_REG_PPS_INIT_QP(syn->pic_init_qp) - | VEPU_REG_SLICE_FILTER_ALPHA(syn->slice_alpha_offset) - | VEPU_REG_SLICE_FILTER_BETA(syn->slice_beta_offset) - | VEPU_REG_CHROMA_QP_OFFSET(syn->chroma_qp_index_offset) - | VEPU_REG_IDR_PIC_ID(syn->idr_pic_id); - - if (syn->filter_disable) - val |= VEPU_REG_FILTER_DISABLE; - - if (constrained_intra_prediction) - val |= VEPU_REG_CONSTRAINED_INTRA_PREDICTION; - H264E_HAL_SET_REG(reg, VEPU_REG_ENC_CTRL2, val); - - H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_NEXT_PIC, 0); - H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_MV_OUT, 0); - H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_CABAC_TBL, mpp_buffer_get_fd(bufs->hw_cabac_table_buf)); - - val = VEPU_REG_ROI1_TOP_MB(mbs_in_col) - | VEPU_REG_ROI1_BOTTOM_MB(mbs_in_col) - | VEPU_REG_ROI1_LEFT_MB(mbs_in_row) - | VEPU_REG_ROI1_RIGHT_MB(mbs_in_row); - H264E_HAL_SET_REG(reg, VEPU_REG_ROI1, val); //FIXED - - val = VEPU_REG_ROI2_TOP_MB(mbs_in_col) - | VEPU_REG_ROI2_BOTTOM_MB(mbs_in_col) - | VEPU_REG_ROI2_LEFT_MB(mbs_in_row) - | VEPU_REG_ROI2_RIGHT_MB(mbs_in_row); - H264E_HAL_SET_REG(reg, VEPU_REG_ROI2, val); //FIXED - H264E_HAL_SET_REG(reg, VEPU_REG_STABLILIZATION_OUTPUT, 0); - - val = VEPU_REG_RGB2YUV_CONVERSION_COEFB(syn->color_conversion_coeff_b) - | VEPU_REG_RGB2YUV_CONVERSION_COEFA(syn->color_conversion_coeff_a); - H264E_HAL_SET_REG(reg, VEPU_REG_RGB2YUV_CONVERSION_COEF1, val); //FIXED - - val = VEPU_REG_RGB2YUV_CONVERSION_COEFE(syn->color_conversion_coeff_e) - | VEPU_REG_RGB2YUV_CONVERSION_COEFC(syn->color_conversion_coeff_c); - H264E_HAL_SET_REG(reg, VEPU_REG_RGB2YUV_CONVERSION_COEF2, val); //FIXED - - val = VEPU_REG_RGB2YUV_CONVERSION_COEFF(syn->color_conversion_coeff_f); - H264E_HAL_SET_REG(reg, VEPU_REG_RGB2YUV_CONVERSION_COEF3, val); //FIXED - - val = VEPU_REG_RGB_MASK_B_MSB(src_fmt.b_mask_msb) - | VEPU_REG_RGB_MASK_G_MSB(src_fmt.g_mask_msb) - | VEPU_REG_RGB_MASK_R_MSB(src_fmt.r_mask_msb); - H264E_HAL_SET_REG(reg, VEPU_REG_RGB_MASK_MSB, val); //FIXED - - diff_mv_penalty[0] = h264_diff_mv_penalty4p[syn->qp]; - diff_mv_penalty[1] = h264_diff_mv_penalty[syn->qp]; - diff_mv_penalty[2] = h264_diff_mv_penalty[syn->qp]; - - val = VEPU_REG_1MV_PENALTY(diff_mv_penalty[1]) - | VEPU_REG_QMV_PENALTY(diff_mv_penalty[2]) - | VEPU_REG_4MV_PENALTY(diff_mv_penalty[0]); - - val |= VEPU_REG_SPLIT_MV_MODE_EN; - H264E_HAL_SET_REG(reg, VEPU_REG_MV_PENALTY, val); - - val = VEPU_REG_H264_LUMA_INIT_QP(syn->qp) - | VEPU_REG_H264_QP_MAX(syn->qp_max) - | VEPU_REG_H264_QP_MIN(syn->qp_min) - | VEPU_REG_H264_CHKPT_DISTANCE(syn->cp_distance_mbs); - H264E_HAL_SET_REG(reg, VEPU_REG_QP_VAL, val); - - val = VEPU_REG_ZERO_MV_FAVOR_D2(10); - H264E_HAL_SET_REG(reg, VEPU_REG_MVC_RELATE, val); - - val = VEPU_REG_OUTPUT_SWAP32 - | VEPU_REG_OUTPUT_SWAP16 - | VEPU_REG_OUTPUT_SWAP8 - | VEPU_REG_INPUT_SWAP8 - | VEPU_REG_INPUT_SWAP16 - | VEPU_REG_INPUT_SWAP32; - H264E_HAL_SET_REG(reg, VEPU_REG_DATA_ENDIAN, val); - - val = VEPU_REG_PPS_ID(syn->pps_id) - | VEPU_REG_INTRA_PRED_MODE(prev_mode_favor) - | VEPU_REG_FRAME_NUM(syn->frame_num); - H264E_HAL_SET_REG(reg, VEPU_REG_ENC_CTRL3, val); - - val = VEPU_REG_INTERRUPT_TIMEOUT_EN; - H264E_HAL_SET_REG(reg, VEPU_REG_INTERRUPT, val); - - for (i = 0; i < 128; i++) { - dmv_penalty[i] = i; - dmv_qpel_penalty[i] = H264E_HAL_MIN(255, exp_golomb_signed(i)); - } - - for (i = 0; i < 128; i += 4) { - val = VEPU_REG_DMV_PENALTY_TABLE_BIT(dmv_penalty[i], 3); - val |= VEPU_REG_DMV_PENALTY_TABLE_BIT(dmv_penalty[i + 1], 2); - val |= VEPU_REG_DMV_PENALTY_TABLE_BIT(dmv_penalty[i + 2], 1); - val |= VEPU_REG_DMV_PENALTY_TABLE_BIT(dmv_penalty[i + 3], 0); - H264E_HAL_SET_REG(reg, VEPU_REG_DMV_PENALTY_TBL(i / 4), val); - - val = VEPU_REG_DMV_Q_PIXEL_PENALTY_TABLE_BIT( - dmv_qpel_penalty[i], 3); - val |= VEPU_REG_DMV_Q_PIXEL_PENALTY_TABLE_BIT( - dmv_qpel_penalty[i + 1], 2); - val |= VEPU_REG_DMV_Q_PIXEL_PENALTY_TABLE_BIT( - dmv_qpel_penalty[i + 2], 1); - val |= VEPU_REG_DMV_Q_PIXEL_PENALTY_TABLE_BIT( - dmv_qpel_penalty[i + 3], 0); - H264E_HAL_SET_REG(reg, VEPU_REG_DMV_Q_PIXEL_PENALTY_TBL(i / 4), val); - } - - /* set buffers addr */ - H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_IN_LUMA, syn->input_luma_addr); - H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_IN_CB, syn->input_cb_addr); - H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_IN_CR, syn->input_cr_addr); - H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_OUTPUT_STREAM, syn->output_strm_addr); - H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_OUTPUT_CTRL, mpp_buffer_get_fd(bufs->hw_nal_size_table_buf)); - - { - RK_S32 recon_chroma_addr = 0, ref_chroma_addr = 0; - RK_U32 frame_luma_size = mbs_in_col * mbs_in_row * 256; - RK_S32 recon_luma_addr = mpp_buffer_get_fd(bufs->hw_rec_buf[buf2_idx]); - RK_S32 ref_luma_addr = mpp_buffer_get_fd(bufs->hw_rec_buf[1 - buf2_idx]); - if (VPUClientGetIOMMUStatus() > 0) { - recon_chroma_addr = recon_luma_addr | (frame_luma_size << 10); - ref_chroma_addr = ref_luma_addr | (frame_luma_size << 10); - } else { - recon_chroma_addr = recon_luma_addr + frame_luma_size; - ref_chroma_addr = ref_luma_addr + frame_luma_size ; - } - H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_REC_LUMA, recon_luma_addr); - H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_REC_CHROMA, recon_chroma_addr); - H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_REF_LUMA, ref_luma_addr); - H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_REF_CHROMA , ref_chroma_addr); - } - - - /* set important encode mode info */ - val = VEPU_REG_MB_HEIGHT(mbs_in_col) - | VEPU_REG_MB_WIDTH(mbs_in_row) - | VEPU_REG_PIC_TYPE(syn->frame_coding_type) - | VEPU_REG_ENCODE_FORMAT(3) - | VEPU_REG_ENCODE_ENABLE; - H264E_HAL_SET_REG(reg, VEPU_REG_ENCODE_START, val); - - -#ifdef H264E_DUMP_DATA_TO_FILE - hal_h264e_vpu_dump_mpp_reg_in(ctx); -#endif - - ctx->frame_cnt++; - h264e_hal_debug_leave(); - return MPP_OK; -} - -MPP_RET hal_h264e_vpu_start(void *hal, HalTaskInfo *task) -{ - h264e_hal_context *ctx = (h264e_hal_context *)hal; - (void)task; - h264e_hal_debug_enter(); -#ifdef RKPLATFORM - if (ctx->vpu_socket > 0) { - RK_U32 *p_regs = (RK_U32 *)ctx->regs; - h264e_hal_log_detail("vpu client is sending %d regs", VEPU_H264E_NUM_REGS); - if (MPP_OK != VPUClientSendReg(ctx->vpu_socket, p_regs, VEPU_H264E_NUM_REGS)) { - mpp_err("VPUClientSendReg Failed!!!"); - return MPP_ERR_VPUHW; - } else { - h264e_hal_log_detail("VPUClientSendReg successfully!"); - } - } else { - mpp_err("invalid vpu socket: %d", ctx->vpu_socket); - return MPP_NOK; - } -#endif - (void)ctx; - h264e_hal_debug_leave(); - - return MPP_OK; -} - -static MPP_RET hal_h264e_vpu_set_feedback(h264e_feedback *fb, h264e_vpu_reg_set *reg) -{ - RK_S32 i = 0; - RK_U32 cpt_prev = 0, overflow = 0; - RK_U32 cpt_idx = VEPU_REG_CHECKPOINT(0) / 4; - RK_U32 *reg_val = (RK_U32 *)reg; - fb->hw_status = reg_val[VEPU_REG_INTERRUPT / 4]; - fb->qp_sum = VEPU_REG_QP_SUM(reg_val[VEPU_REG_QP_SUM_DIV2 / 4]); - fb->mad_count = VEPU_REG_MB_CNT_SET(reg_val[VEPU_REG_MB_CTRL / 4]); - fb->rlc_count = VEPU_REG_RLC_SUM_OUT(reg_val[VEPU_REG_RLC_SUM / 4]); - fb->out_strm_size = reg_val[VEPU_REG_STR_BUF_LIMIT / 4] / 8; - for (i = 0; i < 10; i++) { - RK_U32 cpt = VEPU_REG_CHECKPOINT_RESULT(reg_val[cpt_idx]); - if (cpt < cpt_prev) - overflow += (1 << 21); - fb->cp[i] = cpt + overflow; - cpt_idx += (i & 1); - } - - return MPP_OK; -} - -MPP_RET hal_h264e_vpu_wait(void *hal, HalTaskInfo *task) -{ - h264e_hal_context *ctx = (h264e_hal_context *)hal; - h264e_vpu_reg_set *reg_out = (h264e_vpu_reg_set *)ctx->regs; - IOInterruptCB int_cb = ctx->int_cb; - h264e_feedback *fb = &ctx->feedback; - (void)task; - h264e_hal_debug_enter(); - -#ifdef RKPLATFORM - if (ctx->vpu_socket > 0) { - VPU_CMD_TYPE cmd = 0; - RK_S32 length = 0; - RK_S32 hw_ret = VPUClientWaitResult(ctx->vpu_socket, (RK_U32 *)reg_out, - VEPU_H264E_NUM_REGS, &cmd, &length); - - h264e_hal_log_detail("VPUClientWaitResult: ret %d, cmd %d, len %d\n", hw_ret, cmd, length); - - - if ((VPU_SUCCESS != hw_ret) || (cmd != VPU_SEND_CONFIG_ACK_OK)) - mpp_err("hardware wait error"); - - if (hw_ret != MPP_OK) { - mpp_err("hardware returns error:%d", hw_ret); - return MPP_ERR_VPUHW; - } - } else { - mpp_err("invalid vpu socket: %d", ctx->vpu_socket); - return MPP_NOK; - } -#endif - - if (int_cb.callBack) { - hal_h264e_vpu_set_feedback(fb, reg_out); -#ifdef H264E_DUMP_DATA_TO_FILE - hal_h264e_vpu_dump_mpp_feedback(ctx); -#endif - int_cb.callBack(int_cb.opaque, fb); - } - -#ifdef H264E_DUMP_DATA_TO_FILE - hal_h264e_vpu_dump_mpp_reg_out(ctx); - hal_h264e_vpu_dump_mpp_strm_out(ctx, task->enc.output); -#endif - //hal_h264e_vpu_dump_mpp_strm_out(ctx, NULL); - - h264e_hal_debug_leave(); - - return MPP_OK; -} - -MPP_RET hal_h264e_vpu_reset(void *hal) -{ - (void)hal; - h264e_hal_debug_enter(); - - h264e_hal_debug_leave(); - return MPP_OK; -} - -MPP_RET hal_h264e_vpu_flush(void *hal) -{ - (void)hal; - h264e_hal_debug_enter(); - - h264e_hal_debug_leave(); - return MPP_OK; -} - -MPP_RET hal_h264e_vpu_control(void *hal, RK_S32 cmd_type, void *param) -{ - h264e_hal_context *ctx = (h264e_hal_context *)hal; - h264e_hal_debug_enter(); - - h264e_hal_log_detail("hal_h264e_vpu_control cmd 0x%x, info %p", cmd_type, param); - switch (cmd_type) { - case MPP_ENC_SET_EXTRA_INFO: { - hal_h264e_vpu_set_extra_info(ctx, param); - break; - } - case MPP_ENC_GET_EXTRA_INFO: { - MppPacket pkt = ctx->packeted_param; - MppPacket *pkt_out = (MppPacket *)param; - - h264e_hal_vpu_extra_info *src = (h264e_hal_vpu_extra_info *)ctx->extra_info; - h264e_hal_vpu_stream *sps_stream = &src->sps_stream; - h264e_hal_vpu_stream *pps_stream = &src->pps_stream; - - size_t offset = 0; - - mpp_packet_write(pkt, offset, sps_stream->buffer, sps_stream->byte_cnt); - offset += sps_stream->byte_cnt; - - mpp_packet_write(pkt, offset, pps_stream->buffer, pps_stream->byte_cnt); - offset += pps_stream->byte_cnt; - - mpp_packet_set_length(pkt, offset); - - *pkt_out = pkt; -#ifdef H264E_DUMP_DATA_TO_FILE - hal_h264e_vpu_dump_mpp_strm_out_header(ctx, pkt); -#endif - break; - } - case MPP_ENC_SET_OSD_PLT_CFG: - case MPP_ENC_SET_OSD_DATA_CFG: { - break; - } - case MPP_ENC_SET_SEI_CFG: { - ctx->sei_mode = *((MppEncSeiMode *)param); - break; - } - default : { - mpp_err("unrecognizable cmd type %x", cmd_type); - } break; - } - - h264e_hal_debug_leave(); - return MPP_OK; -} - diff --git a/mpp/hal/vpu/CMakeLists.txt b/mpp/hal/vpu/CMakeLists.txt index 6b00d7fa..945b399a 100644 --- a/mpp/hal/vpu/CMakeLists.txt +++ b/mpp/hal/vpu/CMakeLists.txt @@ -23,3 +23,7 @@ endif() if( HAVE_JPEGE ) add_subdirectory(jpege) endif() + +if( HAVE_H264E ) + add_subdirectory(h264e) +endif() diff --git a/mpp/hal/vpu/h264e/CMakeLists.txt b/mpp/hal/vpu/h264e/CMakeLists.txt new file mode 100644 index 00000000..7d9db143 --- /dev/null +++ b/mpp/hal/vpu/h264e/CMakeLists.txt @@ -0,0 +1,21 @@ +# vim: syntax=cmake +include_directories(.) +include_directories(../../common/h264/) + +# hal h264 header +set(HAL_H264E_HDR + hal_h264e_vpu.h + ) + +# hal h264 encoder sourse +set(HAL_H264E_SRC + hal_h264e_vpu.c + ) + +add_library(hal_h264e_vpu STATIC + ${HAL_H264E_HDR} + ${HAL_H264E_SRC} + ) + +target_link_libraries(hal_h264e_vpu hal_h264e) +set_target_properties(hal_h264e_vpu PROPERTIES FOLDER "mpp/hal") diff --git a/mpp/hal/vpu/h264e/hal_h264e_vpu.c b/mpp/hal/vpu/h264e/hal_h264e_vpu.c new file mode 100644 index 00000000..c9158a55 --- /dev/null +++ b/mpp/hal/vpu/h264e/hal_h264e_vpu.c @@ -0,0 +1,1738 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * 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. + */ + +#define MODULE_TAG "hal_h264e_vpu" + +#include +#include +#include "vpu.h" + +#include "rk_mpi.h" +#include "mpp_env.h" +#include "mpp_mem.h" +#include "mpp_frame.h" +#include "mpp_common.h" +#include "mpp_rc.h" + +#include "hal_h264e_com.h" +#include "hal_h264e_vpu.h" +#include "hal_h264e_vpu_tbl.h" + +//#define H264E_DUMP_DATA_TO_FILE + +typedef struct h264e_hal_vpu_buffers_t { + MppBufferGroup hw_buf_grp; + + MppBuffer hw_rec_buf[2]; + MppBuffer hw_cabac_table_buf; + MppBuffer hw_nal_size_table_buf; +} h264e_hal_vpu_buffers; + +#define HAL_VPU_H264E_DBG_FUNCTION (0x00000001) +#define HAL_VPU_H264E_DBG_QP (0x00000010) + +#define hal_vpu_h264e_dbg(flag, fmt, ...) _mpp_dbg(hal_vpu_h264e_debug, flag, fmt, ## __VA_ARGS__) +#define hal_vpu_h264e_dbg_f(flag, fmt, ...) _mpp_dbg_f(hal_vpu_h264e_debug, flag, fmt, ## __VA_ARGS__) + +#define hal_vpu_h264e_dbg_func(fmt, ...) hal_vpu_h264e_dbg_f(HAL_VPU_H264E_DBG_FUNCTION, fmt, ## __VA_ARGS__) +#define hal_vpu_h264e_dbg_qp(fmt, ...) hal_vpu_h264e_dbg(HAL_VPU_H264E_DBG_QP, fmt, ## __VA_ARGS__) + +static RK_U32 hal_vpu_h264e_debug = 0; + + +#ifdef H264E_DUMP_DATA_TO_FILE +static MPP_RET hal_h264e_vpu_open_dump_files(void *dump_files) +{ + if (h264e_hal_log_mode & H264E_HAL_LOG_FILE) { + char base_path[512]; + char full_path[512]; + h264e_hal_vpu_dump_files *files = (h264e_hal_vpu_dump_files *)dump_files; + strcpy(base_path, "./"); + + sprintf(full_path, "%s%s", base_path, "mpp_syntax_in.txt"); + files->fp_mpp_syntax_in = fopen(full_path, "wb"); + if (!files->fp_mpp_syntax_in) { + mpp_err("%s open error", full_path); + return MPP_ERR_OPEN_FILE; + } + + sprintf(full_path, "%s%s", base_path, "mpp_reg_in.txt"); + files->fp_mpp_reg_in = fopen(full_path, "wb"); + if (!files->fp_mpp_reg_in) { + mpp_err("%s open error", full_path); + return MPP_ERR_OPEN_FILE; + } + + sprintf(full_path, "%s%s", base_path, "mpp_reg_out.txt"); + files->fp_mpp_reg_out = fopen(full_path, "wb"); + if (!files->fp_mpp_reg_out) { + mpp_err("%s open error", full_path); + return MPP_ERR_OPEN_FILE; + } + + sprintf(full_path, "%s%s", base_path, "mpp_feedback.txt"); + files->fp_mpp_feedback = fopen(full_path, "wb"); + if (!files->fp_mpp_feedback) { + mpp_err("%s open error", full_path); + return MPP_ERR_OPEN_FILE; + } + + sprintf(full_path, "%s%s", base_path, "mpp_strm_out.bin"); + files->fp_mpp_strm_out = fopen(full_path, "wb"); + if (!files->fp_mpp_strm_out) { + mpp_err("%s open error", full_path); + return MPP_ERR_OPEN_FILE; + } + } + + return MPP_OK; +} + + +static MPP_RET hal_h264e_vpu_close_dump_files(void *dump_files) +{ + h264e_hal_vpu_dump_files *files = (h264e_hal_vpu_dump_files *)dump_files; + H264E_HAL_FCLOSE(files->fp_mpp_syntax_in); + H264E_HAL_FCLOSE(files->fp_mpp_reg_in); + H264E_HAL_FCLOSE(files->fp_mpp_reg_out); + H264E_HAL_FCLOSE(files->fp_mpp_strm_out); + H264E_HAL_FCLOSE(files->fp_mpp_feedback); + return MPP_OK; +} + +static void hal_h264e_vpu_dump_mpp_syntax_in(H264eHwCfg *syn, h264e_hal_context *ctx) +{ + h264e_hal_vpu_dump_files *dump_files = (h264e_hal_vpu_dump_files *)ctx->dump_files; + FILE *fp = dump_files->fp_mpp_syntax_in; + if (fp) { + RK_S32 k = 0; + fprintf(fp, "#FRAME %d:\n", ctx->frame_cnt); + fprintf(fp, "%-16d %s\n", syn->frame_type, "frame_coding_type"); + fprintf(fp, "%-16d %s\n", syn->pic_init_qp, "pic_init_qp"); + fprintf(fp, "%-16d %s\n", syn->slice_alpha_offset, "slice_alpha_offset"); + fprintf(fp, "%-16d %s\n", syn->slice_beta_offset, "slice_beta_offset"); + fprintf(fp, "%-16d %s\n", syn->chroma_qp_index_offset, "chroma_qp_index_offset"); + fprintf(fp, "%-16d %s\n", syn->filter_disable, "filter_disable"); + fprintf(fp, "%-16d %s\n", syn->idr_pic_id, "idr_pic_id"); + fprintf(fp, "%-16d %s\n", syn->pps_id, "pps_id"); + fprintf(fp, "%-16d %s\n", syn->frame_num, "frame_num"); + fprintf(fp, "%-16d %s\n", syn->slice_size_mb_rows, "slice_size_mb_rows"); + fprintf(fp, "%-16d %s\n", syn->inter4x4_disabled, "h264_inter4x4_disabled"); + fprintf(fp, "%-16d %s\n", syn->enable_cabac, "enable_cabac"); + fprintf(fp, "%-16d %s\n", syn->transform8x8_mode, "transform8x8_mode"); + fprintf(fp, "%-16d %s\n", syn->cabac_init_idc, "cabac_init_idc"); + fprintf(fp, "%-16d %s\n", syn->qp, "qp"); + fprintf(fp, "%-16d %s\n", syn->mad_qp_delta, "mad_qp_delta"); + fprintf(fp, "%-16d %s\n", syn->mad_threshold, "mad_threshold"); + fprintf(fp, "%-16d %s\n", syn->qp_min, "qp_min"); + fprintf(fp, "%-16d %s\n", syn->qp_max, "qp_max"); + fprintf(fp, "%-16d %s\n", syn->cp_distance_mbs, "cp_distance_mbs"); + for (k = 0; k < 10; k++) + fprintf(fp, "%-16d cp_target[%d]\n", syn->cp_target[k], k); + for (k = 0; k < 7; k++) + fprintf(fp, "%-16d target_error[%d]\n", syn->target_error[k], k); + for (k = 0; k < 7; k++) + fprintf(fp, "%-16d delta_qp[%d]\n", syn->delta_qp[k], k); + fprintf(fp, "%-16d %s\n", syn->output_strm_limit_size, "output_strm_limit_size"); + fprintf(fp, "%-16d %s\n", syn->width, "pic_luma_width"); + fprintf(fp, "%-16d %s\n", syn->height, "pic_luma_height"); + fprintf(fp, "0x%-14x %s\n", syn->input_luma_addr, "input_luma_addr"); + fprintf(fp, "0x%-14x %s\n", syn->input_cb_addr, "input_cb_addr"); + fprintf(fp, "0x%-16x %s\n", syn->input_cr_addr, "input_cr_addr"); + fprintf(fp, "%-16d %s\n", syn->input_format, "input_image_format"); + + fprintf(fp, "%-16d %s\n", syn->color_conversion_coeff_a, "color_conversion_coeff_a"); + fprintf(fp, "%-16d %s\n", syn->color_conversion_coeff_b, "color_conversion_coeff_b"); + fprintf(fp, "%-16d %s\n", syn->color_conversion_coeff_c, "color_conversion_coeff_c"); + fprintf(fp, "%-16d %s\n", syn->color_conversion_coeff_e, "color_conversion_coeff_e"); + fprintf(fp, "%-16d %s\n", syn->color_conversion_coeff_f, "color_conversion_coeff_f"); + + fprintf(fp, "\n"); + fflush(fp); + } else { + mpp_log("try to dump data to mpp_syntax_in.txt, but file is not opened"); + } +} + +static void hal_h264e_vpu_dump_mpp_reg_in(h264e_hal_context *ctx) +{ + h264e_hal_vpu_dump_files *dump_files = (h264e_hal_vpu_dump_files *)ctx->dump_files; + FILE *fp = dump_files->fp_mpp_reg_in; + if (fp) { + RK_S32 k = 0; + RK_U32 *reg = (RK_U32 *)ctx->regs; + fprintf(fp, "#FRAME %d:\n", ctx->frame_cnt); + for (k = 0; k < VEPU_H264E_NUM_REGS; k++) { + fprintf(fp, "reg[%03d/%03x]: %08x\n", k, k * 4, reg[k]); + //mpp_log("reg[%03d/%03x]: %08x", k, k*4, reg[k]); + } + fprintf(fp, "\n"); + } else { + mpp_log("try to dump data to mpp_reg_in.txt, but file is not opened"); + } +} + +static void hal_h264e_vpu_dump_mpp_reg_out(h264e_hal_context *ctx) +{ + h264e_hal_vpu_dump_files *dump_files = (h264e_hal_vpu_dump_files *)ctx->dump_files; + FILE *fp = dump_files->fp_mpp_reg_out; + if (fp) { + RK_S32 k = 0; + RK_U32 *reg = (RK_U32 *)ctx->regs; + fprintf(fp, "#FRAME %d:\n", ctx->frame_cnt - 1); + for (k = 0; k < VEPU_H264E_NUM_REGS; k++) { + fprintf(fp, "reg[%03d/%03x]: %08x\n", k, k * 4, reg[k]); + //mpp_log("reg[%03d/%03x]: %08x", k, k*4, reg[k]); + } + fprintf(fp, "\n"); + } else { + mpp_log("try to dump data to mpp_reg_in.txt, but file is not opened"); + } +} + +static void hal_h264e_vpu_dump_mpp_feedback(h264e_hal_context *ctx) +{ + h264e_hal_vpu_dump_files *dump_files = (h264e_hal_vpu_dump_files *)ctx->dump_files; + FILE *fp = dump_files->fp_mpp_feedback; + if (fp) { + RK_S32 k = 0; + h264e_feedback *fb = &ctx->feedback; + fprintf(fp, "#FRAME %d:\n", ctx->frame_cnt - 1); + fprintf(fp, "%-16d %s\n", fb->hw_status, "hw_status"); + fprintf(fp, "%-16d %s\n", fb->out_strm_size, "out_strm_size"); + fprintf(fp, "%-16d %s\n", fb->qp_sum, "qp_sum"); + for (k = 0; k < 10; k++) + fprintf(fp, "%-16d cp[%d]\n", fb->cp[k], k); + fprintf(fp, "%-16d %s\n", fb->mad_count, "mad_count"); + fprintf(fp, "%-16d %s\n", fb->rlc_count, "rlc_count"); + + fprintf(fp, "\n"); + fflush(fp); + } else { + mpp_log("try to dump data to mpp_feedback.txt, but file is not opened"); + } +} + +static void hal_h264e_vpu_dump_mpp_strm_out_header(h264e_hal_context *ctx, MppPacket packet) +{ + h264e_hal_vpu_dump_files *dump_files = (h264e_hal_vpu_dump_files *)ctx->dump_files; + void *ptr = mpp_packet_get_data(packet); + size_t len = mpp_packet_get_length(packet); + FILE *fp = dump_files->fp_mpp_strm_out; + + if (fp) { + fwrite(ptr, 1, len, fp); + fflush(fp); + } else { + mpp_log("try to dump strm header to mpp_strm_out.txt, but file is not opened"); + } +} + +void hal_h264e_vpu_dump_mpp_strm_out(h264e_hal_context *ctx, MppBuffer hw_buf) +{ + h264e_hal_vpu_dump_files *dump_files = (h264e_hal_vpu_dump_files *)ctx->dump_files; + FILE *fp = dump_files->fp_mpp_strm_out; + if (fp && hw_buf) { + RK_U32 *reg_val = (RK_U32 *)ctx->regs; + RK_U32 strm_size = reg_val[VEPU_REG_STR_BUF_LIMIT / 4] / 8; + + RK_U8 *hw_buf_vir_addr = (RK_U8 *)mpp_buffer_get_ptr(hw_buf); + + mpp_log("strm_size: %d", strm_size); + + fwrite(hw_buf_vir_addr, 1, strm_size, fp); + fflush(fp); + } else { + mpp_log("try to dump data to mpp_strm_out.txt, but file is not opened"); + } +} +#endif + +static MPP_RET hal_h264e_vpu_free_buffers(h264e_hal_context *ctx) +{ + MPP_RET ret = MPP_OK; + RK_S32 k = 0; + h264e_hal_vpu_buffers *p = (h264e_hal_vpu_buffers *)ctx->buffers; + h264e_hal_debug_enter(); + + if (p->hw_cabac_table_buf) { + ret = mpp_buffer_put(p->hw_cabac_table_buf); + if (ret) + mpp_err("hw_cabac_table_buf put failed ret %d\n", ret); + + p->hw_cabac_table_buf = NULL; + } + + if (p->hw_nal_size_table_buf) { + ret = mpp_buffer_put(p->hw_nal_size_table_buf); + if (ret) + mpp_err("hw_nal_size_table_buf put failed ret %d\n", ret); + + p->hw_nal_size_table_buf = NULL; + } + + + for (k = 0; k < 2; k++) { + if (p->hw_rec_buf[k]) { + ret = mpp_buffer_put(p->hw_rec_buf[k]); + if (ret) + mpp_err("hw_rec_buf[%d] put failed ret %d\n", k, ret); + + p->hw_rec_buf[k] = NULL; + } + } + + if (p->hw_buf_grp) { + ret = mpp_buffer_group_put(p->hw_buf_grp); + if (ret) + mpp_err("buf group put failed ret %d\n", ret); + + p->hw_buf_grp = NULL; + } + + h264e_hal_debug_leave(); + return ret; +} + +static void hal_h264e_vpu_swap_endian(RK_U32 *buf, RK_S32 size_bytes) +{ + RK_U32 i = 0; + RK_S32 words = size_bytes / 4; + RK_U32 val, val2, tmp, tmp2; + + mpp_assert((size_bytes % 8) == 0); + + while (words > 0) { + val = buf[i]; + tmp = 0; + + tmp |= (val & 0xFF) << 24; + tmp |= (val & 0xFF00) << 8; + tmp |= (val & 0xFF0000) >> 8; + tmp |= (val & 0xFF000000) >> 24; + + { + val2 = buf[i + 1]; + tmp2 = 0; + + tmp2 |= (val2 & 0xFF) << 24; + tmp2 |= (val2 & 0xFF00) << 8; + tmp2 |= (val2 & 0xFF0000) >> 8; + tmp2 |= (val2 & 0xFF000000) >> 24; + + buf[i] = tmp2; + words--; + i++; + + } + buf[i] = tmp; + words--; + i++; + } +} + +static void hal_h264e_vpu_write_cabac_table(MppBuffer hw_cabac_tab_buf, RK_U32 cabac_init_idc) +{ + const RK_S32(*context)[460][2]; + RK_S32 i, j, qp; + + RK_U8 table[H264E_CABAC_TABLE_BUF_SIZE] = {0}; + + h264e_hal_debug_enter(); + + for (qp = 0; qp < 52; qp++) { /* All QP values */ + for (j = 0; j < 2; j++) { /* Intra/Inter */ + if (j == 0) + /*lint -e(545) */ + context = &h264_context_init_intra; + else + /*lint -e(545) */ + context = &h264_context_init[cabac_init_idc]; + + for (i = 0; i < 460; i++) { + RK_S32 m = (RK_S32)(*context)[i][0]; + RK_S32 n = (RK_S32)(*context)[i][1]; + + RK_S32 pre_ctx_state = H264E_HAL_CLIP3(((m * (RK_S32)qp) >> 4) + n, 1, 126); + + if (pre_ctx_state <= 63) + table[qp * 464 * 2 + j * 464 + i] = (RK_U8)((63 - pre_ctx_state) << 1); + else + table[qp * 464 * 2 + j * 464 + i] = (RK_U8)(((pre_ctx_state - 64) << 1) | 1); + } + } + } + hal_h264e_vpu_swap_endian((RK_U32 *)table, H264E_CABAC_TABLE_BUF_SIZE); + mpp_buffer_write(hw_cabac_tab_buf, 0, table, H264E_CABAC_TABLE_BUF_SIZE); + + h264e_hal_debug_leave(); +} + +static MPP_RET hal_h264e_vpu_allocate_buffers(h264e_hal_context *ctx, H264eHwCfg *syn) +{ + MPP_RET ret = MPP_OK; + RK_S32 k = 0; + h264e_hal_vpu_buffers *buffers = (h264e_hal_vpu_buffers *)ctx->buffers; + RK_U32 frame_size = ((syn->width + 15) & (~15)) * ((syn->height + 15) & (~15)) * 3 / 2; + + h264e_hal_debug_enter(); + ret = mpp_buffer_group_get_internal(&buffers->hw_buf_grp, MPP_BUFFER_TYPE_ION); + if (ret) { + mpp_err("buf group get failed ret %d\n", ret); + return ret; + } + + ret = mpp_buffer_get(buffers->hw_buf_grp, &buffers->hw_cabac_table_buf, H264E_CABAC_TABLE_BUF_SIZE); + if (ret) { + mpp_err("hw_cabac_table_buf get failed\n"); + return ret; + } + + ret = mpp_buffer_get(buffers->hw_buf_grp, &buffers->hw_nal_size_table_buf, (sizeof(RK_U32) * (syn->height + 1) + 7) & (~7)); + if (ret) { + mpp_err("hw_nal_size_table_buf get failed\n"); + return ret; + } + + for (k = 0; k < 2; k++) { + ret = mpp_buffer_get(buffers->hw_buf_grp, &buffers->hw_rec_buf[k], frame_size + 4096); + if (ret) { + mpp_err("hw_rec_buf[%d] get failed\n", k); + return ret; + } + } + + hal_h264e_vpu_write_cabac_table(buffers->hw_cabac_table_buf, syn->cabac_init_idc); + + h264e_hal_debug_leave(); + return MPP_OK; +} + + +static MPP_RET hal_h264e_vpu_stream_buffer_status(h264e_hal_vpu_stream *stream) +{ + if (stream->byte_cnt + 5 > stream->size) { + stream->overflow = 1; + return MPP_NOK; + } + + return MPP_OK; +} + +static MPP_RET hal_h264e_vpu_stream_buffer_reset(h264e_hal_vpu_stream *strmbuf) +{ + strmbuf->stream = strmbuf->buffer; + strmbuf->byte_cnt = 0; + strmbuf->overflow = 0; + strmbuf->byte_buffer = 0; + strmbuf->buffered_bits = 0; + strmbuf->zero_bytes = 0; + strmbuf->emul_cnt = 0; + + return MPP_OK; +} + +static MPP_RET hal_h264e_vpu_stream_buffer_init(h264e_hal_vpu_stream *strmbuf, RK_S32 size) +{ + strmbuf->buffer = mpp_calloc(RK_U8, size); + + if (strmbuf->buffer == NULL) { + mpp_err("allocate stream buffer failed\n"); + return MPP_NOK; + } + strmbuf->stream = strmbuf->buffer; + strmbuf->size = size; + strmbuf->byte_cnt = 0; + strmbuf->overflow = 0; + strmbuf->byte_buffer = 0; + strmbuf->buffered_bits = 0; + strmbuf->zero_bytes = 0; + strmbuf->emul_cnt = 0; + + if (MPP_OK != hal_h264e_vpu_stream_buffer_status(strmbuf)) { + mpp_err("stream buffer is overflow, while init"); + return MPP_NOK; + } + + return MPP_OK; +} + + +void hal_h264e_vpu_stream_put_bits(h264e_hal_vpu_stream *buffer, RK_S32 value, RK_S32 number, + const char *name) +{ + RK_S32 bits; + RK_U32 byte_buffer = buffer->byte_buffer; + RK_U8*stream = buffer->stream; + + if (hal_h264e_vpu_stream_buffer_status(buffer) != 0) + return; + + h264e_hal_log_header("assemble %s value %x, bits %d\n", name, value, number); + + mpp_assert(value < (1 << number)); //opposite to 'BUG_ON' in kernel + mpp_assert(number < 25); + + bits = number + buffer->buffered_bits; + value <<= (32 - bits); + byte_buffer = byte_buffer | value; + + while (bits > 7) { + *stream = (RK_U8)(byte_buffer >> 24); + + bits -= 8; + byte_buffer <<= 8; + stream++; + buffer->byte_cnt++; + } + + buffer->byte_buffer = byte_buffer; + buffer->buffered_bits = (RK_U8)bits; + buffer->stream = stream; + + return; +} + +void hal_h264e_vpu_stream_put_bits_with_detect(h264e_hal_vpu_stream * buffer, RK_S32 value, RK_S32 number, const char *name) +{ + RK_S32 bits; + RK_U8 *stream = buffer->stream; + RK_U32 byte_buffer = buffer->byte_buffer; + + mpp_assert(value < (1 << number)); + mpp_assert(number < 25); + + h264e_hal_log_header("assemble %s value %x, bits %d\n", name, value, number); + + bits = number + buffer->buffered_bits; + byte_buffer = byte_buffer | ((RK_U32) value << (32 - bits)); + + while (bits > 7) { + RK_S32 zeroBytes = buffer->zero_bytes; + RK_S32 byteCnt = buffer->byte_cnt; + + if (hal_h264e_vpu_stream_buffer_status(buffer) != MPP_OK) + return; + + *stream = (RK_U8) (byte_buffer >> 24); + byteCnt++; + + if ((zeroBytes == 2) && (*stream < 4)) { + *stream++ = 3; + *stream = (RK_U8) (byte_buffer >> 24); + byteCnt++; + zeroBytes = 0; + buffer->emul_cnt++; + } + + if (*stream == 0) + zeroBytes++; + else + zeroBytes = 0; + + bits -= 8; + byte_buffer <<= 8; + stream++; + buffer->zero_bytes = zeroBytes; + buffer->byte_cnt = byteCnt; + buffer->stream = stream; + } + + buffer->buffered_bits = (RK_U8) bits; + buffer->byte_buffer = byte_buffer; +} + + +void hal_h264e_vpu_rbsp_trailing_bits(h264e_hal_vpu_stream * stream) +{ + hal_h264e_vpu_stream_put_bits_with_detect(stream, 1, 1, "rbsp_stop_one_bit"); + if (stream->buffered_bits > 0) { + hal_h264e_vpu_stream_put_bits_with_detect(stream, 0, 8 - stream->buffered_bits, "bsp_alignment_zero_bit(s)"); + } +} + +static void hal_h264e_vpu_write_ue(h264e_hal_vpu_stream *fifo, RK_U32 val, + const char *name) +{ + RK_U32 num_bits = 0; + + val++; + while (val >> ++num_bits); + + if (num_bits > 12) { + RK_U32 tmp; + + tmp = num_bits - 1; + + if (tmp > 24) { + tmp -= 24; + hal_h264e_vpu_stream_put_bits_with_detect(fifo, 0, 24, name); + } + + hal_h264e_vpu_stream_put_bits_with_detect(fifo, 0, tmp, name); + + if (num_bits > 24) { + num_bits -= 24; + hal_h264e_vpu_stream_put_bits_with_detect(fifo, val >> num_bits, 24, name); + val = val >> num_bits; + } + + hal_h264e_vpu_stream_put_bits_with_detect(fifo, val, num_bits, name); + } else { + hal_h264e_vpu_stream_put_bits_with_detect(fifo, val, 2 * num_bits - 1, name); + } +} + +static void hal_h264e_vpu_write_se(h264e_hal_vpu_stream *fifo, RK_S32 val, const char *name) +{ + RK_U32 tmp; + + if (val > 0) + tmp = (RK_U32)(2 * val - 1); + else + tmp = (RK_U32)(-2 * val); + + hal_h264e_vpu_write_ue(fifo, tmp, name); +} + +static MPP_RET hal_h264e_vpu_nal_start(h264e_hal_vpu_stream * stream, RK_S32 nalRefIdc, rkvenc_nal_unit_type nalUnitType) +{ + hal_h264e_vpu_stream_put_bits(stream, 0, 8, "leadin_zero_8bits"); + hal_h264e_vpu_stream_put_bits(stream, 0, 8, "start_code_prefix"); + hal_h264e_vpu_stream_put_bits(stream, 0, 8, "start_code_prefix"); + hal_h264e_vpu_stream_put_bits(stream, 1, 8, "start_code_prefix"); + hal_h264e_vpu_stream_put_bits(stream, 0, 1, "forbidden_zero_bit"); + hal_h264e_vpu_stream_put_bits(stream, nalRefIdc, 2, "nal_ref_idc"); + hal_h264e_vpu_stream_put_bits(stream, (RK_S32)nalUnitType, 5, "nal_unit_type"); + stream->zero_bytes = 0; /* we start new counter for zero bytes */ + + return MPP_OK; +} + + + +static MPP_RET hal_h264e_vpu_write_sps(h264e_hal_vpu_stream *stream, h264e_hal_sps *sps) +{ + h264e_hal_debug_enter(); + + hal_h264e_vpu_nal_start(stream, 1, RKVENC_NAL_SPS); + + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->i_profile_idc, 8, "profile_idc"); //FIXED: 77, 42 + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_constraint_set0, 1, "constraint_set0_flag"); //E0 + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_constraint_set1, 1, "constraint_set1_flag"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_constraint_set2, 1, "constraint_set2_flag"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_constraint_set3, 1, "constraint_set3_flag"); + + hal_h264e_vpu_stream_put_bits_with_detect(stream, 0, 4, "reserved_zero_4bits"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->i_level_idc, 8, "level_idc"); //28 + + hal_h264e_vpu_write_ue(stream, sps->i_id, "seq_parameter_set_id"); //8D + + if (sps->i_profile_idc >= 100) { //High profile + hal_h264e_vpu_write_ue(stream, sps->i_chroma_format_idc, "chroma_format_idc"); + hal_h264e_vpu_write_ue(stream, H264_BIT_DEPTH - 8, "bit_depth_luma_minus8"); + hal_h264e_vpu_write_ue(stream, H264_BIT_DEPTH - 8, "bit_depth_chroma_minus8"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_qpprime_y_zero_transform_bypass, 1, "qpprime_y_zero_transform_bypass_flag"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, 0, 1, "seq_scaling_matrix_present_flag"); + } + + hal_h264e_vpu_write_ue(stream, sps->i_log2_max_frame_num - 4, "log2_max_frame_num_minus4"); + + hal_h264e_vpu_write_ue(stream, sps->i_poc_type, "pic_order_cnt_type"); //68 16 + + hal_h264e_vpu_write_ue(stream, sps->i_num_ref_frames, "num_ref_frames"); + + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_gaps_in_frame_num_value_allowed, 1, "gaps_in_frame_num_value_allowed_flag"); + + hal_h264e_vpu_write_ue(stream, sps->i_mb_width - 1, "pic_width_in_mbs_minus1"); + + hal_h264e_vpu_write_ue(stream, sps->i_mb_height - 1, "pic_height_in_map_units_minus1"); //09 64 + + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_frame_mbs_only, 1, "frame_mbs_only_flag"); + + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_direct8x8_inference, 1, "direct_8x8_inference_flag"); + + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_crop, 1, "frame_cropping_flag"); + if (sps->b_crop) { + hal_h264e_vpu_write_ue(stream, sps->crop.i_left / 2, "frame_crop_left_offset"); + hal_h264e_vpu_write_ue(stream, sps->crop.i_right / 2, "frame_crop_right_offset"); + hal_h264e_vpu_write_ue(stream, sps->crop.i_top / 2, "frame_crop_top_offset"); + hal_h264e_vpu_write_ue(stream, sps->crop.i_bottom / 2, "frame_crop_bottom_offset"); + } + + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_vui, 1, "vui_parameters_present_flag"); + if (sps->vui.b_vui) { + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_aspect_ratio_info_present, 1, "aspect_ratio_info_present_flag"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_overscan_info_present, 1, "overscan_info_present_flag"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_signal_type_present, 1, "video_signal_type_present_flag"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_chroma_loc_info_present, 1, "chroma_loc_info_present_flag"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_timing_info_present, 1, "timing_info_present_flag"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.i_num_units_in_tick >> 16, 16, "num_units_in_tick msb"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.i_num_units_in_tick & 0xffff, 16, "num_units_in_tick lsb"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.i_time_scale >> 16, 16, "time_scale msb"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.i_time_scale & 0xffff, 16, "time_scale lsb"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_fixed_frame_rate, 1, "fixed_frame_rate_flag"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_nal_hrd_parameters_present, 1, "nal_hrd_parameters_present_flag"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_vcl_hrd_parameters_present, 1, "vcl_hrd_parameters_present_flag"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_pic_struct_present, 1, "pic_struct_present_flag"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_bitstream_restriction, 1, "bit_stream_restriction_flag"); + if (sps->vui.b_bitstream_restriction) { + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_motion_vectors_over_pic_boundaries, 1, "motion_vectors_over_pic_boundaries"); + hal_h264e_vpu_write_ue(stream, sps->vui.i_max_bytes_per_pic_denom, "max_bytes_per_pic_denom"); + hal_h264e_vpu_write_ue(stream, sps->vui.i_max_bits_per_mb_denom, "max_bits_per_mb_denom"); + hal_h264e_vpu_write_ue(stream, sps->vui.i_log2_max_mv_length_horizontal, "log2_mv_length_horizontal"); + hal_h264e_vpu_write_ue(stream, sps->vui.i_log2_max_mv_length_vertical, "log2_mv_length_vertical"); + hal_h264e_vpu_write_ue(stream, sps->vui.i_num_reorder_frames, "num_reorder_frames"); + hal_h264e_vpu_write_ue(stream, sps->vui.i_max_dec_frame_buffering, "max_dec_frame_buffering"); + } + } + + hal_h264e_vpu_rbsp_trailing_bits(stream); + + h264e_hal_log_header("sps write size: %d bytes", stream->byte_cnt); + + h264e_hal_debug_leave(); + + return MPP_OK; +} + +static MPP_RET hal_h264e_vpu_write_pps(h264e_hal_vpu_stream *stream, h264e_hal_pps *pps) +{ + h264e_hal_debug_enter(); + + hal_h264e_vpu_nal_start(stream, 1, RKVENC_NAL_PPS); + + hal_h264e_vpu_write_ue(stream, pps->i_id, "pic_parameter_set_id"); + hal_h264e_vpu_write_ue(stream, pps->i_sps_id, "seq_parameter_set_id"); + + hal_h264e_vpu_stream_put_bits_with_detect(stream, pps->b_cabac, 1, "entropy_coding_mode_flag"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, pps->b_pic_order, 1, "pic_order_present_flag"); + + hal_h264e_vpu_write_ue(stream, pps->i_num_slice_groups - 1, "num_slice_groups_minus1"); + hal_h264e_vpu_write_ue(stream, pps->i_num_ref_idx_l0_default_active - 1, "num_ref_idx_l0_active_minus1"); + hal_h264e_vpu_write_ue(stream, pps->i_num_ref_idx_l1_default_active - 1, "num_ref_idx_l1_active_minus1"); + + hal_h264e_vpu_stream_put_bits_with_detect(stream, pps->b_weighted_pred, 1, "weighted_pred_flag"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, pps->i_weighted_bipred_idc, 2, "weighted_bipred_idc"); + + hal_h264e_vpu_write_se(stream, pps->i_pic_init_qp - 26, "pic_init_qp_minus26"); + hal_h264e_vpu_write_se(stream, pps->i_pic_init_qs - 26, "pic_init_qs_minus26"); + hal_h264e_vpu_write_se(stream, pps->i_chroma_qp_index_offset, "chroma_qp_index_offset"); + + hal_h264e_vpu_stream_put_bits_with_detect(stream, pps->b_deblocking_filter_control, 1, "deblocking_filter_control_present_flag"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, pps->b_constrained_intra_pred, 1, "constrained_intra_pred_flag"); + + hal_h264e_vpu_stream_put_bits_with_detect(stream, pps->b_redundant_pic_cnt, 1, "redundant_pic_cnt_present_flag"); + + if (pps->b_transform_8x8_mode) { + hal_h264e_vpu_stream_put_bits_with_detect(stream, pps->b_transform_8x8_mode, 1, "transform_8x8_mode_flag"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, pps->b_cqm_preset, 1, "pic_scaling_matrix_present_flag"); + hal_h264e_vpu_write_se(stream, pps->i_chroma_qp_index_offset, "chroma_qp_index_offset"); + } + + hal_h264e_vpu_rbsp_trailing_bits(stream); + + h264e_hal_log_header("pps write size: %d bytes", stream->byte_cnt); + + h264e_hal_debug_leave(); + + return MPP_OK; +} + +static MPP_RET hal_h264e_vpu_init_extra_info(void *extra_info) +{ + h264e_hal_vpu_extra_info *info = (h264e_hal_vpu_extra_info *)extra_info; + h264e_hal_vpu_stream *sps_stream = &info->sps_stream; + h264e_hal_vpu_stream *pps_stream = &info->pps_stream; + + if (MPP_OK != hal_h264e_vpu_stream_buffer_init(sps_stream, 128)) { + mpp_err("sps stream sw buf init failed"); + return MPP_NOK; + } + if (MPP_OK != hal_h264e_vpu_stream_buffer_init(pps_stream, 128)) { + mpp_err("pps stream sw buf init failed"); + return MPP_NOK; + } + + return MPP_OK; +} + +static MPP_RET hal_h264e_vpu_deinit_extra_info(void *extra_info) +{ + h264e_hal_vpu_extra_info *info = (h264e_hal_vpu_extra_info *)extra_info; + h264e_hal_vpu_stream *sps_stream = &info->sps_stream; + h264e_hal_vpu_stream *pps_stream = &info->pps_stream; + + MPP_FREE(sps_stream->buffer); + MPP_FREE(pps_stream->buffer); + + return MPP_OK; +} + +static MPP_RET hal_h264e_vpu_set_extra_info(h264e_hal_context *ctx) +{ + h264e_hal_vpu_extra_info *info = (h264e_hal_vpu_extra_info *)ctx->extra_info; + h264e_hal_vpu_stream *sps_stream = &info->sps_stream; + h264e_hal_vpu_stream *pps_stream = &info->pps_stream; + h264e_hal_sps *sps = &info->sps; + h264e_hal_pps *pps = &info->pps; + + h264e_hal_debug_enter(); + + hal_h264e_vpu_stream_buffer_reset(sps_stream); + hal_h264e_vpu_stream_buffer_reset(pps_stream); + + hal_h264e_set_sps(ctx, sps); + hal_h264e_set_pps(ctx, pps, sps); + + hal_h264e_vpu_write_sps(sps_stream, sps); + hal_h264e_vpu_write_pps(pps_stream, pps); + + h264e_hal_debug_leave(); + + return MPP_OK; +} + +static RK_S32 exp_golomb_signed(RK_S32 val) +{ + RK_S32 tmp = 0; + + if (val > 0) + val = 2 * val; + else + val = -2 * val + 1; + + while (val >> ++tmp) + ; + + return tmp * 2 - 1; +} + + +MPP_RET hal_h264e_vpu_init(void *hal, MppHalCfg *cfg) +{ + h264e_hal_context *ctx = (h264e_hal_context *)hal; + MPP_RET ret = MPP_OK; + VPU_CLIENT_TYPE type = VPU_ENC; + + h264e_hal_debug_enter(); + + ctx->int_cb = cfg->hal_int_cb; + ctx->regs = mpp_calloc(h264e_vpu_reg_set, 1); + ctx->buffers = mpp_calloc(h264e_hal_vpu_buffers, 1); + ctx->extra_info = mpp_calloc(h264e_hal_vpu_extra_info, 1); + ctx->dump_files = mpp_calloc(h264e_hal_vpu_dump_files, 1); + ctx->param_buf = mpp_calloc_size(void, H264E_EXTRA_INFO_BUF_SIZE); + mpp_packet_init(&ctx->packeted_param, ctx->param_buf, H264E_EXTRA_INFO_BUF_SIZE); + + hal_h264e_vpu_init_extra_info(ctx->extra_info); +#ifdef H264E_DUMP_DATA_TO_FILE + hal_h264e_vpu_open_dump_files(ctx->dump_files); +#endif + + ctx->vpu_fd = -1; + h264e_hal_log_detail("vpu client: %d", type); + +#ifdef RKPLATFORM + ctx->vpu_fd = VPUClientInit(type); + if (ctx->vpu_fd <= 0) { + mpp_err("get vpu_socket(%d) <=0, failed. \n", ctx->vpu_fd); + ret = MPP_ERR_UNKNOW; + } else { + VPUHwEncConfig_t hwCfg; + h264e_hal_log_detail("get vpu_socket(%d), success. \n", ctx->vpu_fd); + memset(&hwCfg, 0, sizeof(VPUHwEncConfig_t)); + if (VPUClientGetHwCfg(ctx->vpu_fd, (RK_U32*)&hwCfg, sizeof(hwCfg))) { + mpp_err("h264enc # Get HwCfg failed, release vpu\n"); + VPUClientRelease(ctx->vpu_fd); + ctx->vpu_fd = -1; + ret = MPP_NOK; + } + } +#endif + ctx->hw_cfg.qp_prev = ctx->cfg->codec.h264.qp_init; + mpp_env_get_u32("hal_vpu_h264e_debug", &hal_vpu_h264e_debug, 0); + + h264e_hal_debug_leave(); + return ret; +} + +MPP_RET hal_h264e_vpu_deinit(void *hal) +{ + h264e_hal_context *ctx = (h264e_hal_context *)hal; + h264e_hal_debug_enter(); + + MPP_FREE(ctx->regs); + MPP_FREE(ctx->param_buf); + + if (ctx->extra_info) { + hal_h264e_vpu_deinit_extra_info(ctx->extra_info); + MPP_FREE(ctx->extra_info); + } + + if (ctx->packeted_param) { + mpp_packet_deinit(&ctx->packeted_param); + ctx->packeted_param = NULL; + } + + if (ctx->buffers) { + hal_h264e_vpu_free_buffers(ctx); + MPP_FREE(ctx->buffers); + } + + if (ctx->intra_qs) { + mpp_linreg_deinit(ctx->intra_qs); + ctx->intra_qs = NULL; + } + + if (ctx->inter_qs) { + mpp_linreg_deinit(ctx->inter_qs); + ctx->inter_qs = NULL; + } + +#ifdef H264E_DUMP_DATA_TO_FILE + if (ctx->dump_files) { + hal_h264e_vpu_close_dump_files(ctx->dump_files); + MPP_FREE(ctx->dump_files); + } +#endif + +#ifdef RKPLATFORM + if (ctx->vpu_fd <= 0) { + mpp_err("invalid vpu socket: %d", ctx->vpu_fd); + return MPP_NOK; + } + + if (VPU_SUCCESS != VPUClientRelease(ctx->vpu_fd)) { + mpp_err("VPUClientRelease failed"); + return MPP_ERR_VPUHW; + } +#endif + + h264e_hal_debug_leave(); + return MPP_OK; +} + +static RK_S32 find_best_qp(MppLinReg *ctx, MppEncH264Cfg *codec, RK_S32 qp_start, RK_S32 bits) +{ + RK_S32 qp = qp_start; + RK_S32 qp_best = qp_start; + RK_S32 qp_min = codec->qp_min; + RK_S32 qp_max = codec->qp_max; + RK_S32 diff_best = INT_MAX; + + if (ctx->a == 0 && ctx->b == 0) + return qp_best; + + hal_vpu_h264e_dbg_qp("RC: qp est target bit %d\n", bits); + if (bits <= 0) { + qp_best = mpp_clip(qp_best + codec->qp_max_step, qp_min, qp_max); + } else { + do { + RK_S32 est_bits = mpp_linreg_calc(ctx, h264_q_step[qp]); + RK_S32 diff = est_bits - bits; + hal_vpu_h264e_dbg_qp("RC: qp est qp %d bit %d diff %d best %d\n", + qp, bits, diff, diff_best); + if (MPP_ABS(diff) < MPP_ABS(diff_best)) { + diff_best = MPP_ABS(diff); + qp_best = qp; + if (diff > 0) + qp++; + else + qp--; + } else + break; + } while (qp <= qp_max && qp >= qp_min); + } + + return qp_best; +} + +static MPP_RET hal_h264e_vpu_update_hw_cfg(h264e_hal_context *ctx, HalEncTask *task, H264eHwCfg *hw_cfg) +{ + RK_S32 i; + MppEncCfgSet *cfg = ctx->cfg; + MppEncH264Cfg *codec = &cfg->codec.h264; + MppEncPrepCfg *prep = &cfg->prep; + MppEncRcCfg *rc = &cfg->rc; + RcSyntax *rc_syn = (RcSyntax *)task->syntax.data; + + /* preprocess setup */ + if (prep->change) { + RK_U32 change = prep->change; + + if (change & MPP_ENC_PREP_CFG_CHANGE_INPUT) { + hw_cfg->width = prep->width; + hw_cfg->height = prep->height; + hw_cfg->input_format = prep->format; + + mpp_assert(prep->hor_stride == MPP_ALIGN(prep->width, 16)); + mpp_assert(prep->ver_stride == MPP_ALIGN(prep->height, 16)); + + hw_cfg->hor_stride = prep->hor_stride; + hw_cfg->ver_stride = prep->ver_stride; + + hal_h264e_vpu_set_format(hw_cfg, prep); + } + + if (change & MPP_ENC_PREP_CFG_CHANGE_FORMAT) { + switch (prep->color) { + case MPP_FRAME_SPC_RGB : { + /* BT.601 */ + /* Y = 0.2989 R + 0.5866 G + 0.1145 B + * Cb = 0.5647 (B - Y) + 128 + * Cr = 0.7132 (R - Y) + 128 + */ + hw_cfg->color_conversion_coeff_a = 19589; + hw_cfg->color_conversion_coeff_b = 38443; + hw_cfg->color_conversion_coeff_c = 7504; + hw_cfg->color_conversion_coeff_e = 37008; + hw_cfg->color_conversion_coeff_f = 46740; + } break; + case MPP_FRAME_SPC_BT709 : { + /* BT.709 */ + /* Y = 0.2126 R + 0.7152 G + 0.0722 B + * Cb = 0.5389 (B - Y) + 128 + * Cr = 0.6350 (R - Y) + 128 + */ + hw_cfg->color_conversion_coeff_a = 13933; + hw_cfg->color_conversion_coeff_b = 46871; + hw_cfg->color_conversion_coeff_c = 4732; + hw_cfg->color_conversion_coeff_e = 35317; + hw_cfg->color_conversion_coeff_f = 41615; + } break; + default : { + hw_cfg->color_conversion_coeff_a = 19589; + hw_cfg->color_conversion_coeff_b = 38443; + hw_cfg->color_conversion_coeff_c = 7504; + hw_cfg->color_conversion_coeff_e = 37008; + hw_cfg->color_conversion_coeff_f = 46740; + } break; + } + } + + prep->change = 0; + } + + if (codec->change) { + // TODO: setup sps / pps here + + hw_cfg->pps_id = 0; + hw_cfg->idr_pic_id = !ctx->idr_pic_id; + hw_cfg->enable_cabac = codec->entropy_coding_mode; + hw_cfg->cabac_init_idc = codec->cabac_init_idc; + hw_cfg->transform8x8_mode = codec->transform8x8_mode; + hw_cfg->pic_init_qp = codec->qp_init; + hw_cfg->chroma_qp_index_offset = codec->chroma_cb_qp_offset; + hw_cfg->second_chroma_qp_index_offset = codec->chroma_cr_qp_offset; + hw_cfg->filter_disable = codec->deblock_disable; + hw_cfg->slice_alpha_offset = codec->deblock_offset_alpha; + hw_cfg->slice_beta_offset = codec->deblock_offset_beta; + hw_cfg->inter4x4_disabled = (codec->profile >= 31) ? (1) : (0); + hw_cfg->constrained_intra_prediction = codec->constrained_intra_pred_mode; + + hw_cfg->qp_prev = hw_cfg->pic_init_qp; + hw_cfg->qp = hw_cfg->pic_init_qp; + + codec->change = 0; + } + + if (NULL == ctx->intra_qs) + mpp_linreg_init(&ctx->intra_qs, MPP_MIN(rc->gop, 10)); + if (NULL == ctx->inter_qs) + mpp_linreg_init(&ctx->inter_qs, MPP_MIN(rc->gop, 10)); + + mpp_assert(ctx->intra_qs); + mpp_assert(ctx->inter_qs); + + /* frame type and rate control setup */ + hal_vpu_h264e_dbg_qp("RC: qp calc ctx %p qp [%d %d] prev %d target bit %d\n", + ctx->inter_qs, codec->qp_min, codec->qp_max, hw_cfg->qp_prev, + rc_syn->bit_target); + { + RK_S32 prev_coding_type = hw_cfg->frame_type; + + if (rc_syn->type == INTRA_FRAME) { + hw_cfg->frame_type = H264E_VPU_FRAME_I; + hw_cfg->frame_num = 0; + + hw_cfg->qp = find_best_qp(ctx->intra_qs, codec, hw_cfg->qp_prev, rc_syn->bit_target); + + /* + * Previous frame is inter then intra frame can not + * have a big qp step between these two frames + */ + if (prev_coding_type == 0) + hw_cfg->qp = mpp_clip(hw_cfg->qp, hw_cfg->qp_prev - 4, hw_cfg->qp_prev + 4); + } else { + hw_cfg->frame_type = H264E_VPU_FRAME_P; + + hw_cfg->qp = find_best_qp(ctx->inter_qs, codec, hw_cfg->qp_prev, rc_syn->bit_target); + + if (prev_coding_type == 1) + hw_cfg->qp = mpp_clip(hw_cfg->qp, hw_cfg->qp_prev - 4, hw_cfg->qp_prev + 4); + } + } + + hal_vpu_h264e_dbg_qp("RC: qp calc ctx %p qp get %d\n", + ctx->inter_qs, hw_cfg->qp); + + hw_cfg->qp = mpp_clip(hw_cfg->qp, + hw_cfg->qp_prev - codec->qp_max_step, + hw_cfg->qp_prev + codec->qp_max_step); + + hal_vpu_h264e_dbg_qp("RC: qp calc ctx %p qp clip %d prev %d step %d\n", + ctx->inter_qs, hw_cfg->qp, hw_cfg->qp_prev, codec->qp_max_step); + + hw_cfg->qp_prev = hw_cfg->qp; + + hw_cfg->mad_qp_delta = 0; + hw_cfg->mad_threshold = 6; + hw_cfg->keyframe_max_interval = rc->gop; + hw_cfg->qp_min = codec->qp_min; + hw_cfg->qp_max = codec->qp_max; + + /* disable mb rate control first */ + hw_cfg->cp_distance_mbs = 0; + for (i = 0; i < 10; i++) + hw_cfg->cp_target[i] = 0; + + for (i = 0; i < 7; i++) + hw_cfg->target_error[i] = 0; + + for (i = 0; i < 7; i++) + hw_cfg->delta_qp[i] = 0; + + /* slice mode setup */ + hw_cfg->slice_size_mb_rows = 0; //(prep->height + 15) >> 4; + + /* input and preprocess config */ + { + RK_U32 offset_uv = hw_cfg->hor_stride * hw_cfg->ver_stride; + hw_cfg->input_luma_addr = mpp_buffer_get_fd(task->input); + hw_cfg->input_cb_addr = hw_cfg->input_luma_addr + (offset_uv << 10); + hw_cfg->input_cr_addr = hw_cfg->input_cb_addr + (offset_uv << 8); + hw_cfg->output_strm_limit_size = mpp_buffer_get_size(task->output); + hw_cfg->output_strm_addr = mpp_buffer_get_fd(task->output); + } + + /* context update */ + ctx->idr_pic_id = !ctx->idr_pic_id; + return MPP_OK; +} + +MPP_RET hal_h264e_vpu_gen_regs(void *hal, HalTaskInfo *task) +{ + MPP_RET ret = MPP_OK; + h264e_hal_context *ctx = (h264e_hal_context *)hal; + h264e_hal_vpu_buffers *bufs = (h264e_hal_vpu_buffers *)ctx->buffers; + MppEncH264Cfg *codec = &ctx->cfg->codec.h264; + MppEncPrepCfg *prep = &ctx->cfg->prep; + H264eHwCfg *hw_cfg = &ctx->hw_cfg; + RK_U32 *reg = (RK_U32 *)ctx->regs; + HalEncTask *enc_task = &task->enc; + + RK_S32 scaler = 0, i = 0; + RK_U32 val = 0, skip_penalty = 0; + RK_U32 overfill_r = 0, overfill_b = 0; + + RK_U32 mb_w; + RK_U32 mb_h; + + h264e_hal_debug_enter(); + + // generate parameter from config + hal_h264e_vpu_update_hw_cfg(ctx, enc_task, hw_cfg); +#ifdef H264E_DUMP_DATA_TO_FILE + hal_h264e_vpu_dump_mpp_syntax_in(hw_cfg, ctx); +#endif + + // prepare buffer + if (!ctx->buffer_ready) { + ret = hal_h264e_vpu_allocate_buffers(ctx, hw_cfg); + if (ret) { + h264e_hal_log_err("allocate buffers failed\n"); + hal_h264e_vpu_free_buffers(ctx); + return ret; + } else + ctx->buffer_ready = 1; + } + + mb_w = (prep->width + 15) / 16; + mb_h = (prep->height + 15) / 16; + + memset(reg, 0, sizeof(h264e_vpu_reg_set)); + + h264e_hal_log_detail("frame %d generate regs now", ctx->frame_cnt); + + /* output buffer size is 64 bit address then 8 multiple size */ + val = mpp_buffer_get_size(enc_task->output); + val >>= 3; + val &= ~7; + H264E_HAL_SET_REG(reg, VEPU_REG_STR_BUF_LIMIT, val); + + /* + * The hardware needs only the value for luma plane, because + * values of other planes are calculated internally based on + * format setting. + */ + val = VEPU_REG_INTRA_AREA_TOP(mb_h) + | VEPU_REG_INTRA_AREA_BOTTOM(mb_h) + | VEPU_REG_INTRA_AREA_LEFT(mb_w) + | VEPU_REG_INTRA_AREA_RIGHT(mb_w); + H264E_HAL_SET_REG(reg, VEPU_REG_INTRA_AREA_CTRL, val); //FIXED + H264E_HAL_SET_REG(reg, VEPU_REG_STR_HDR_REM_MSB, 0); + H264E_HAL_SET_REG(reg, VEPU_REG_STR_HDR_REM_LSB, 0); + + + val = VEPU_REG_AXI_CTRL_READ_ID(0); + val |= VEPU_REG_AXI_CTRL_WRITE_ID(0); + val |= VEPU_REG_AXI_CTRL_BURST_LEN(16); + val |= VEPU_REG_AXI_CTRL_INCREMENT_MODE(0); + val |= VEPU_REG_AXI_CTRL_BIRST_DISCARD(0); + H264E_HAL_SET_REG(reg, VEPU_REG_AXI_CTRL, val); + + H264E_HAL_SET_REG(reg, VEPU_QP_ADJUST_MAD_DELTA_ROI, hw_cfg->mad_qp_delta); + + val = 0; + if (mb_w * mb_h > 3600) + val = VEPU_REG_DISABLE_QUARTER_PIXEL_MV; + val |= VEPU_REG_CABAC_INIT_IDC(codec->cabac_init_idc); + if (codec->entropy_coding_mode) + val |= VEPU_REG_ENTROPY_CODING_MODE; + if (codec->transform8x8_mode) + val |= VEPU_REG_H264_TRANS8X8_MODE; + if (hw_cfg->inter4x4_disabled) + val |= VEPU_REG_H264_INTER4X4_MODE; + /*reg |= VEPU_REG_H264_STREAM_MODE;*/ + val |= VEPU_REG_H264_SLICE_SIZE(hw_cfg->slice_size_mb_rows); + H264E_HAL_SET_REG(reg, VEPU_REG_ENC_CTRL0, val); + + scaler = H264E_HAL_MAX(1, 200 / (mb_w + mb_h)); + skip_penalty = H264E_HAL_MIN(255, h264_skip_sad_penalty[hw_cfg->qp] * scaler); + skip_penalty = 0xff; + if (prep->width & 0x0f) + overfill_r = (16 - (prep->width & 0x0f) ) / 4; + if (prep->height & 0x0f) + overfill_b = 16 - (prep->height & 0x0f); + val = VEPU_REG_STREAM_START_OFFSET(0) | /* first_free_bit */ + VEPU_REG_SKIP_MACROBLOCK_PENALTY(skip_penalty) | + VEPU_REG_IN_IMG_CTRL_OVRFLR_D4(overfill_r) | + VEPU_REG_IN_IMG_CTRL_OVRFLB(overfill_b); + H264E_HAL_SET_REG(reg, VEPU_REG_ENC_OVER_FILL_STRM_OFFSET, val); + + + val = VEPU_REG_IN_IMG_CHROMA_OFFSET(0) + | VEPU_REG_IN_IMG_LUMA_OFFSET(0) + | VEPU_REG_IN_IMG_CTRL_ROW_LEN(prep->width); + H264E_HAL_SET_REG(reg, VEPU_REG_INPUT_LUMA_INFO, val); + + val = VEPU_REG_CHECKPOINT_CHECK1(hw_cfg->cp_target[0]) + | VEPU_REG_CHECKPOINT_CHECK0(hw_cfg->cp_target[1]); + H264E_HAL_SET_REG(reg, VEPU_REG_CHECKPOINT(0), val); + + val = VEPU_REG_CHECKPOINT_CHECK1(hw_cfg->cp_target[2]) + | VEPU_REG_CHECKPOINT_CHECK0(hw_cfg->cp_target[3]); + H264E_HAL_SET_REG(reg, VEPU_REG_CHECKPOINT(1), val); + + val = VEPU_REG_CHECKPOINT_CHECK1(hw_cfg->cp_target[4]) + | VEPU_REG_CHECKPOINT_CHECK0(hw_cfg->cp_target[5]); + H264E_HAL_SET_REG(reg, VEPU_REG_CHECKPOINT(2), val); + + val = VEPU_REG_CHECKPOINT_CHECK1(hw_cfg->cp_target[6]) + | VEPU_REG_CHECKPOINT_CHECK0(hw_cfg->cp_target[7]); + H264E_HAL_SET_REG(reg, VEPU_REG_CHECKPOINT(3), val); + + val = VEPU_REG_CHECKPOINT_CHECK1(hw_cfg->cp_target[8]) + | VEPU_REG_CHECKPOINT_CHECK0(hw_cfg->cp_target[9]); + H264E_HAL_SET_REG(reg, VEPU_REG_CHECKPOINT(4), val); + + val = VEPU_REG_CHKPT_WORD_ERR_CHK1(hw_cfg->target_error[0]) + | VEPU_REG_CHKPT_WORD_ERR_CHK0(hw_cfg->target_error[1]); + H264E_HAL_SET_REG(reg, VEPU_REG_CHKPT_WORD_ERR(0), val); + + val = VEPU_REG_CHKPT_WORD_ERR_CHK1(hw_cfg->target_error[2]) + | VEPU_REG_CHKPT_WORD_ERR_CHK0(hw_cfg->target_error[3]); + H264E_HAL_SET_REG(reg, VEPU_REG_CHKPT_WORD_ERR(1), val); + + val = VEPU_REG_CHKPT_WORD_ERR_CHK1(hw_cfg->target_error[4]) + | VEPU_REG_CHKPT_WORD_ERR_CHK0(hw_cfg->target_error[5]); + H264E_HAL_SET_REG(reg, VEPU_REG_CHKPT_WORD_ERR(2), val); + + val = VEPU_REG_CHKPT_DELTA_QP_CHK6(hw_cfg->delta_qp[6]) + | VEPU_REG_CHKPT_DELTA_QP_CHK5(hw_cfg->delta_qp[5]) + | VEPU_REG_CHKPT_DELTA_QP_CHK4(hw_cfg->delta_qp[4]) + | VEPU_REG_CHKPT_DELTA_QP_CHK3(hw_cfg->delta_qp[3]) + | VEPU_REG_CHKPT_DELTA_QP_CHK2(hw_cfg->delta_qp[2]) + | VEPU_REG_CHKPT_DELTA_QP_CHK1(hw_cfg->delta_qp[1]) + | VEPU_REG_CHKPT_DELTA_QP_CHK0(hw_cfg->delta_qp[0]); + H264E_HAL_SET_REG(reg, VEPU_REG_CHKPT_DELTA_QP, val); + + val = VEPU_REG_MAD_THRESHOLD(hw_cfg->mad_threshold) + | VEPU_REG_IN_IMG_CTRL_FMT(hw_cfg->input_format) + | VEPU_REG_IN_IMG_ROTATE_MODE(0) + | VEPU_REG_SIZE_TABLE_PRESENT; //FIXED + H264E_HAL_SET_REG(reg, VEPU_REG_ENC_CTRL1, val); + + val = VEPU_REG_INTRA16X16_MODE(h264_intra16_favor[hw_cfg->qp]) + | VEPU_REG_INTER_MODE(h264_inter_favor[hw_cfg->qp]); + H264E_HAL_SET_REG(reg, VEPU_REG_INTRA_INTER_MODE, val); + + val = VEPU_REG_PPS_INIT_QP(hw_cfg->pic_init_qp) + | VEPU_REG_SLICE_FILTER_ALPHA(hw_cfg->slice_alpha_offset) + | VEPU_REG_SLICE_FILTER_BETA(hw_cfg->slice_beta_offset) + | VEPU_REG_CHROMA_QP_OFFSET(hw_cfg->chroma_qp_index_offset) + | VEPU_REG_IDR_PIC_ID(hw_cfg->idr_pic_id); + + if (hw_cfg->filter_disable) + val |= VEPU_REG_FILTER_DISABLE; + + if (hw_cfg->constrained_intra_prediction) + val |= VEPU_REG_CONSTRAINED_INTRA_PREDICTION; + H264E_HAL_SET_REG(reg, VEPU_REG_ENC_CTRL2, val); + + H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_NEXT_PIC, 0); + H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_MV_OUT, 0); + H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_CABAC_TBL, mpp_buffer_get_fd(bufs->hw_cabac_table_buf)); + + val = VEPU_REG_ROI1_TOP_MB(mb_h) + | VEPU_REG_ROI1_BOTTOM_MB(mb_h) + | VEPU_REG_ROI1_LEFT_MB(mb_w) + | VEPU_REG_ROI1_RIGHT_MB(mb_w); + H264E_HAL_SET_REG(reg, VEPU_REG_ROI1, val); //FIXED + + val = VEPU_REG_ROI2_TOP_MB(mb_h) + | VEPU_REG_ROI2_BOTTOM_MB(mb_h) + | VEPU_REG_ROI2_LEFT_MB(mb_w) + | VEPU_REG_ROI2_RIGHT_MB(mb_w); + H264E_HAL_SET_REG(reg, VEPU_REG_ROI2, val); //FIXED + H264E_HAL_SET_REG(reg, VEPU_REG_STABLILIZATION_OUTPUT, 0); + + val = VEPU_REG_RGB2YUV_CONVERSION_COEFB(hw_cfg->color_conversion_coeff_b) + | VEPU_REG_RGB2YUV_CONVERSION_COEFA(hw_cfg->color_conversion_coeff_a); + H264E_HAL_SET_REG(reg, VEPU_REG_RGB2YUV_CONVERSION_COEF1, val); //FIXED + + val = VEPU_REG_RGB2YUV_CONVERSION_COEFE(hw_cfg->color_conversion_coeff_e) + | VEPU_REG_RGB2YUV_CONVERSION_COEFC(hw_cfg->color_conversion_coeff_c); + H264E_HAL_SET_REG(reg, VEPU_REG_RGB2YUV_CONVERSION_COEF2, val); //FIXED + + val = VEPU_REG_RGB2YUV_CONVERSION_COEFF(hw_cfg->color_conversion_coeff_f); + H264E_HAL_SET_REG(reg, VEPU_REG_RGB2YUV_CONVERSION_COEF3, val); //FIXED + + val = VEPU_REG_RGB_MASK_B_MSB(hw_cfg->b_mask_msb) + | VEPU_REG_RGB_MASK_G_MSB(hw_cfg->g_mask_msb) + | VEPU_REG_RGB_MASK_R_MSB(hw_cfg->r_mask_msb); + H264E_HAL_SET_REG(reg, VEPU_REG_RGB_MASK_MSB, val); //FIXED + + { + RK_U32 diff_mv_penalty[3] = {0}; + diff_mv_penalty[0] = h264_diff_mv_penalty4p[hw_cfg->qp]; + diff_mv_penalty[1] = h264_diff_mv_penalty[hw_cfg->qp]; + diff_mv_penalty[2] = h264_diff_mv_penalty[hw_cfg->qp]; + + val = VEPU_REG_1MV_PENALTY(diff_mv_penalty[1]) + | VEPU_REG_QMV_PENALTY(diff_mv_penalty[2]) + | VEPU_REG_4MV_PENALTY(diff_mv_penalty[0]); + } + + val |= VEPU_REG_SPLIT_MV_MODE_EN; + H264E_HAL_SET_REG(reg, VEPU_REG_MV_PENALTY, val); + + val = VEPU_REG_H264_LUMA_INIT_QP(hw_cfg->qp) + | VEPU_REG_H264_QP_MAX(hw_cfg->qp_max) + | VEPU_REG_H264_QP_MIN(hw_cfg->qp_min) + | VEPU_REG_H264_CHKPT_DISTANCE(hw_cfg->cp_distance_mbs); + H264E_HAL_SET_REG(reg, VEPU_REG_QP_VAL, val); + + val = VEPU_REG_ZERO_MV_FAVOR_D2(10); + H264E_HAL_SET_REG(reg, VEPU_REG_MVC_RELATE, val); + + val = VEPU_REG_OUTPUT_SWAP32 + | VEPU_REG_OUTPUT_SWAP16 + | VEPU_REG_OUTPUT_SWAP8 + | VEPU_REG_INPUT_SWAP8 + | VEPU_REG_INPUT_SWAP16 + | VEPU_REG_INPUT_SWAP32; + H264E_HAL_SET_REG(reg, VEPU_REG_DATA_ENDIAN, val); + + val = VEPU_REG_PPS_ID(hw_cfg->pps_id) + | VEPU_REG_INTRA_PRED_MODE(h264_prev_mode_favor[hw_cfg->qp]) + | VEPU_REG_FRAME_NUM(hw_cfg->frame_num); + H264E_HAL_SET_REG(reg, VEPU_REG_ENC_CTRL3, val); + + val = VEPU_REG_INTERRUPT_TIMEOUT_EN; + H264E_HAL_SET_REG(reg, VEPU_REG_INTERRUPT, val); + + { + RK_U8 dmv_penalty[128] = {0}; + RK_U8 dmv_qpel_penalty[128] = {0}; + + for (i = 0; i < 128; i++) { + dmv_penalty[i] = i; + dmv_qpel_penalty[i] = H264E_HAL_MIN(255, exp_golomb_signed(i)); + } + + for (i = 0; i < 128; i += 4) { + val = VEPU_REG_DMV_PENALTY_TABLE_BIT(dmv_penalty[i], 3); + val |= VEPU_REG_DMV_PENALTY_TABLE_BIT(dmv_penalty[i + 1], 2); + val |= VEPU_REG_DMV_PENALTY_TABLE_BIT(dmv_penalty[i + 2], 1); + val |= VEPU_REG_DMV_PENALTY_TABLE_BIT(dmv_penalty[i + 3], 0); + H264E_HAL_SET_REG(reg, VEPU_REG_DMV_PENALTY_TBL(i / 4), val); + + val = VEPU_REG_DMV_Q_PIXEL_PENALTY_TABLE_BIT( + dmv_qpel_penalty[i], 3); + val |= VEPU_REG_DMV_Q_PIXEL_PENALTY_TABLE_BIT( + dmv_qpel_penalty[i + 1], 2); + val |= VEPU_REG_DMV_Q_PIXEL_PENALTY_TABLE_BIT( + dmv_qpel_penalty[i + 2], 1); + val |= VEPU_REG_DMV_Q_PIXEL_PENALTY_TABLE_BIT( + dmv_qpel_penalty[i + 3], 0); + H264E_HAL_SET_REG(reg, VEPU_REG_DMV_Q_PIXEL_PENALTY_TBL(i / 4), val); + } + } + + /* set buffers addr */ + H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_IN_LUMA, hw_cfg->input_luma_addr); + H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_IN_CB, hw_cfg->input_cb_addr); + H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_IN_CR, hw_cfg->input_cr_addr); + H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_OUTPUT_STREAM, hw_cfg->output_strm_addr); + H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_OUTPUT_CTRL, mpp_buffer_get_fd(bufs->hw_nal_size_table_buf)); + + { + RK_U32 buf2_idx = ctx->frame_cnt & 1; + RK_S32 recon_chroma_addr = 0, ref_chroma_addr = 0; + RK_U32 frame_luma_size = mb_h * mb_w * 256; + RK_S32 recon_luma_addr = mpp_buffer_get_fd(bufs->hw_rec_buf[buf2_idx]); + RK_S32 ref_luma_addr = mpp_buffer_get_fd(bufs->hw_rec_buf[1 - buf2_idx]); + if (VPUClientGetIOMMUStatus() > 0) { + recon_chroma_addr = recon_luma_addr | (frame_luma_size << 10); + ref_chroma_addr = ref_luma_addr | (frame_luma_size << 10); + } else { + recon_chroma_addr = recon_luma_addr + frame_luma_size; + ref_chroma_addr = ref_luma_addr + frame_luma_size ; + } + H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_REC_LUMA, recon_luma_addr); + H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_REC_CHROMA, recon_chroma_addr); + H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_REF_LUMA, ref_luma_addr); + H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_REF_CHROMA , ref_chroma_addr); + } + + + /* set important encode mode info */ + val = VEPU_REG_MB_HEIGHT(mb_h) + | VEPU_REG_MB_WIDTH(mb_w) + | VEPU_REG_PIC_TYPE(hw_cfg->frame_type) + | VEPU_REG_ENCODE_FORMAT(3) + | VEPU_REG_ENCODE_ENABLE; + H264E_HAL_SET_REG(reg, VEPU_REG_ENCODE_START, val); + +#ifdef H264E_DUMP_DATA_TO_FILE + hal_h264e_vpu_dump_mpp_reg_in(ctx); +#endif + + ctx->frame_cnt++; + hw_cfg->frame_num++; + if (hw_cfg->frame_type == H264E_VPU_FRAME_I) + hw_cfg->idr_pic_id++; + if (hw_cfg->idr_pic_id == 16) + hw_cfg->idr_pic_id = 0; + + h264e_hal_debug_leave(); + return MPP_OK; +} + +MPP_RET hal_h264e_vpu_start(void *hal, HalTaskInfo *task) +{ + h264e_hal_context *ctx = (h264e_hal_context *)hal; + (void)task; + h264e_hal_debug_enter(); +#ifdef RKPLATFORM + if (ctx->vpu_fd > 0) { + RK_U32 *p_regs = (RK_U32 *)ctx->regs; + h264e_hal_log_detail("vpu client is sending %d regs", VEPU_H264E_NUM_REGS); + if (MPP_OK != VPUClientSendReg(ctx->vpu_fd, p_regs, VEPU_H264E_NUM_REGS)) { + mpp_err("VPUClientSendReg Failed!!!"); + return MPP_ERR_VPUHW; + } else { + h264e_hal_log_detail("VPUClientSendReg successfully!"); + } + } else { + mpp_err("invalid vpu socket: %d", ctx->vpu_fd); + return MPP_NOK; + } +#endif + (void)ctx; + h264e_hal_debug_leave(); + + return MPP_OK; +} + +static MPP_RET hal_h264e_vpu_set_feedback(h264e_feedback *fb, h264e_vpu_reg_set *reg) +{ + RK_S32 i = 0; + RK_U32 cpt_prev = 0, overflow = 0; + RK_U32 cpt_idx = VEPU_REG_CHECKPOINT(0) / 4; + RK_U32 *reg_val = (RK_U32 *)reg; + fb->hw_status = reg_val[VEPU_REG_INTERRUPT / 4]; + fb->qp_sum = ((reg_val[VEPU_REG_QP_SUM_DIV2 / 4] >> 11) & 0x001fffff) * 2; + fb->mad_count = (reg_val[VEPU_REG_MB_CTRL / 4] >> 16) & 0xffff; + fb->rlc_count = reg_val[VEPU_REG_RLC_SUM / 4] & 0x3fffff; + fb->out_strm_size = reg_val[VEPU_REG_STR_BUF_LIMIT / 4] / 8; + for (i = 0; i < 10; i++) { + RK_U32 cpt = VEPU_REG_CHECKPOINT_RESULT(reg_val[cpt_idx]); + if (cpt < cpt_prev) + overflow += (1 << 21); + fb->cp[i] = cpt + overflow; + cpt_idx += (i & 1); + } + + return MPP_OK; +} + +MPP_RET hal_h264e_vpu_wait(void *hal, HalTaskInfo *task) +{ + h264e_hal_context *ctx = (h264e_hal_context *)hal; + h264e_vpu_reg_set *reg_out = (h264e_vpu_reg_set *)ctx->regs; + MppEncPrepCfg *prep = &ctx->set->prep; + IOInterruptCB int_cb = ctx->int_cb; + h264e_feedback *fb = &ctx->feedback; + RK_S32 num_mb = MPP_ALIGN(prep->width, 16) * MPP_ALIGN(prep->height, 16) / 16 / 16; + + h264e_hal_debug_enter(); + +#ifdef RKPLATFORM + if (ctx->vpu_fd > 0) { + VPU_CMD_TYPE cmd = 0; + RK_S32 length = 0; + RK_S32 hw_ret = VPUClientWaitResult(ctx->vpu_fd, (RK_U32 *)reg_out, + VEPU_H264E_NUM_REGS, &cmd, &length); + + h264e_hal_log_detail("VPUClientWaitResult: ret %d, cmd %d, len %d\n", hw_ret, cmd, length); + + + if ((VPU_SUCCESS != hw_ret) || (cmd != VPU_SEND_CONFIG_ACK_OK)) + mpp_err("hardware wait error"); + + if (hw_ret != MPP_OK) { + mpp_err("hardware returns error:%d", hw_ret); + return MPP_ERR_VPUHW; + } + } else { + mpp_err("invalid vpu socket: %d", ctx->vpu_fd); + return MPP_NOK; + } +#endif + + hal_h264e_vpu_set_feedback(fb, reg_out); +#ifdef H264E_DUMP_DATA_TO_FILE + hal_h264e_vpu_dump_mpp_feedback(ctx); +#endif + task->enc.length = fb->out_strm_size; + if (int_cb.callBack) { + RcSyntax *syn = (RcSyntax *)task->enc.syntax.data; + RcHalResult result; + RK_S32 avg_qp = fb->qp_sum / num_mb; + + mpp_assert(avg_qp >= 0); + mpp_assert(avg_qp <= 51); + + mpp_log("qp sum %d avg %d\n", fb->qp_sum, avg_qp); + + result.bits = fb->out_strm_size * 8; + result.type = syn->type; + fb->result = &result; + + mpp_linreg_update((syn->type == INTRA_FRAME) ? + (ctx->intra_qs) : + (ctx->inter_qs), + h264_q_step[avg_qp], result.bits); + + int_cb.callBack(int_cb.opaque, fb); + } + +#ifdef H264E_DUMP_DATA_TO_FILE + hal_h264e_vpu_dump_mpp_reg_out(ctx); + hal_h264e_vpu_dump_mpp_strm_out(ctx, task->enc.output); +#endif + //hal_h264e_vpu_dump_mpp_strm_out(ctx, NULL); + + h264e_hal_debug_leave(); + + return MPP_OK; +} + +MPP_RET hal_h264e_vpu_reset(void *hal) +{ + (void)hal; + h264e_hal_debug_enter(); + + h264e_hal_debug_leave(); + return MPP_OK; +} + +MPP_RET hal_h264e_vpu_flush(void *hal) +{ + (void)hal; + h264e_hal_debug_enter(); + + h264e_hal_debug_leave(); + return MPP_OK; +} + +MPP_RET hal_h264e_vpu_control(void *hal, RK_S32 cmd_type, void *param) +{ + h264e_hal_context *ctx = (h264e_hal_context *)hal; + h264e_hal_debug_enter(); + + h264e_hal_log_detail("hal_h264e_vpu_control cmd 0x%x, info %p", cmd_type, param); + switch (cmd_type) { + case MPP_ENC_SET_EXTRA_INFO: { + break; + } + case MPP_ENC_GET_EXTRA_INFO: { + MppPacket pkt = ctx->packeted_param; + MppPacket *pkt_out = (MppPacket *)param; + + h264e_hal_vpu_extra_info *src = (h264e_hal_vpu_extra_info *)ctx->extra_info; + h264e_hal_vpu_stream *sps_stream = &src->sps_stream; + h264e_hal_vpu_stream *pps_stream = &src->pps_stream; + + size_t offset = 0; + + hal_h264e_vpu_set_extra_info(ctx); + + mpp_packet_write(pkt, offset, sps_stream->buffer, sps_stream->byte_cnt); + offset += sps_stream->byte_cnt; + + mpp_packet_write(pkt, offset, pps_stream->buffer, pps_stream->byte_cnt); + offset += pps_stream->byte_cnt; + + mpp_packet_set_length(pkt, offset); + + *pkt_out = pkt; +#ifdef H264E_DUMP_DATA_TO_FILE + hal_h264e_vpu_dump_mpp_strm_out_header(ctx, pkt); +#endif + break; + } + + case MPP_ENC_SET_PREP_CFG : { + MppEncPrepCfg *set = &ctx->set->prep; + RK_U32 change = set->change; + MPP_RET ret = MPP_NOK; + + if (change & MPP_ENC_PREP_CFG_CHANGE_INPUT) { + if ((set->width < 0 || set->width > 1920) || + (set->height < 0 || set->height > 3840) || + (set->hor_stride < 0 || set->hor_stride > 1920) || + (set->ver_stride < 0 || set->ver_stride > 3840)) { + mpp_err("invalid input w:h [%d:%d] [%d:%d]\n", + set->width, set->height, + set->hor_stride, set->ver_stride); + return ret; + } + } + + if (change & MPP_ENC_PREP_CFG_CHANGE_FORMAT) { + if ((set->format < MPP_FRAME_FMT_RGB && + set->format >= MPP_FMT_YUV_BUTT) || + set->format >= MPP_FMT_RGB_BUTT) { + mpp_err("invalid format %d\n", set->format); + return ret; + } + } + } break; + case MPP_ENC_SET_RC_CFG : { + // TODO: do rate control check here + } break; + case MPP_ENC_SET_CODEC_CFG : { + MppEncH264Cfg *src = &ctx->set->codec.h264; + MppEncH264Cfg *dst = &ctx->cfg->codec.h264; + RK_U32 change = src->change; + + // TODO: do codec check first + + if (change & MPP_ENC_H264_CFG_STREAM_TYPE) + dst->stream_type = src->stream_type; + if (change & MPP_ENC_H264_CFG_CHANGE_PROFILE) { + dst->profile = src->profile; + dst->level = src->level; + } + if (change & MPP_ENC_H264_CFG_CHANGE_ENTROPY) { + dst->entropy_coding_mode = src->entropy_coding_mode; + dst->cabac_init_idc = src->cabac_init_idc; + } + if (change & MPP_ENC_H264_CFG_CHANGE_TRANS_8x8) + dst->transform8x8_mode = src->transform8x8_mode; + if (change & MPP_ENC_H264_CFG_CHANGE_CONST_INTRA) + dst->constrained_intra_pred_mode = src->constrained_intra_pred_mode; + if (change & MPP_ENC_H264_CFG_CHANGE_CHROMA_QP) { + dst->chroma_cb_qp_offset = src->chroma_cb_qp_offset; + dst->chroma_cr_qp_offset = src->chroma_cr_qp_offset; + } + if (change & MPP_ENC_H264_CFG_CHANGE_DEBLOCKING) { + dst->deblock_disable = src->deblock_disable; + dst->deblock_offset_alpha = src->deblock_offset_alpha; + dst->deblock_offset_beta = src->deblock_offset_beta; + } + if (change & MPP_ENC_H264_CFG_CHANGE_LONG_TERM) + dst->use_longterm = src->use_longterm; + if (change & MPP_ENC_H264_CFG_CHANGE_QP_LIMIT) { + dst->qp_init = src->qp_init; + dst->qp_max = src->qp_max; + dst->qp_min = src->qp_min; + dst->qp_max_step = src->qp_max_step; + } + if (change & MPP_ENC_H264_CFG_CHANGE_INTRA_REFRESH) { + dst->intra_refresh_mode = src->intra_refresh_mode; + dst->intra_refresh_arg = src->intra_refresh_arg; + } + if (change & MPP_ENC_H264_CFG_CHANGE_SLICE_MODE) { + dst->slice_mode = src->slice_mode; + dst->slice_arg = src->slice_arg; + } + if (change & MPP_ENC_H264_CFG_CHANGE_VUI) { + dst->vui = src->vui; + } + if (change & MPP_ENC_H264_CFG_CHANGE_SEI) { + dst->sei = src->sei; + } + + /* + * NOTE: use OR here for avoiding overwrite on multiple config + * When next encoding is trigger the change flag will be clear + */ + dst->change |= change; + src->change = 0; + } break; + + case MPP_ENC_SET_OSD_PLT_CFG: + case MPP_ENC_SET_OSD_DATA_CFG: { + break; + } + case MPP_ENC_SET_SEI_CFG: { + ctx->sei_mode = *((MppEncSeiMode *)param); + break; + } + default : { + mpp_err("unrecognizable cmd type %x", cmd_type); + } break; + } + + h264e_hal_debug_leave(); + return MPP_OK; +} + diff --git a/mpp/hal/rkenc/h264e/hal_h264e_vpu.h b/mpp/hal/vpu/h264e/hal_h264e_vpu.h similarity index 96% rename from mpp/hal/rkenc/h264e/hal_h264e_vpu.h rename to mpp/hal/vpu/h264e/hal_h264e_vpu.h index 7d34d34f..d53c33ac 100644 --- a/mpp/hal/rkenc/h264e/hal_h264e_vpu.h +++ b/mpp/hal/vpu/h264e/hal_h264e_vpu.h @@ -609,6 +609,11 @@ #define VEPU_H264E_NUM_REGS 184 #define H264E_CABAC_TABLE_BUF_SIZE (52*2*464) +typedef enum H264eVpuFrameType_t { + H264E_VPU_FRAME_P = 0, + H264E_VPU_FRAME_I = 1 +} H264eVpuFrameType; + typedef struct h264e_hal_vpu_dump_files_t { FILE *fp_mpp_syntax_in; FILE *fp_mpp_reg_in; @@ -617,33 +622,6 @@ typedef struct h264e_hal_vpu_dump_files_t { FILE *fp_mpp_feedback; } h264e_hal_vpu_dump_files; -/* transplant from vpu_api.h:EncInputPictureType */ -typedef enum { - H264E_VPU_CSP_YUV420P = 0, // YYYY... UUUU... VVVV - H264E_VPU_CSP_YUV420SP = 1, // YYYY... UVUVUV... - H264E_VPU_CSP_YUYV422 = 2, // YUYVYUYV... - H264E_VPU_CSP_UYVY422 = 3, // UYVYUYVY... - H264E_VPU_CSP_RGB565 = 4, // 16-bit RGB - H264E_VPU_CSP_BGR565 = 5, // 16-bit RGB - H264E_VPU_CSP_RGB555 = 6, // 15-bit RGB - H264E_VPU_CSP_BGR555 = 7, // 15-bit RGB - H264E_VPU_CSP_RGB444 = 8, // 12-bit RGB - H264E_VPU_CSP_BGR444 = 9, // 12-bit RGB - H264E_VPU_CSP_RGB888 = 10, // 24-bit RGB - H264E_VPU_CSP_BGR888 = 11, // 24-bit RGB - H264E_VPU_CSP_RGB101010 = 12, // 30-bit RGB - H264E_VPU_CSP_BGR101010 = 13, // 30-bit RGB - H264E_VPU_CSP_NONE, - H264E_VPU_CSP_BUTT, -} h264e_hal_vpu_csp; - -typedef struct h264e_hal_vpu_csp_info_t { - RK_U32 fmt; - RK_U32 r_mask_msb; - RK_U32 g_mask_msb; - RK_U32 b_mask_msb; -} h264e_hal_vpu_csp_info; - /* struct for assemble bitstream */ typedef struct h264e_hal_vpu_stream_t { RK_U8 *buffer; /* point to first byte of stream */ @@ -666,21 +644,6 @@ typedef struct h264e_hal_vpu_extra_info_t { h264e_hal_sei sei; } h264e_hal_vpu_extra_info; -typedef enum h264e_hal_vpu_buf_grp_t { - H264E_HAL_VPU_BUF_GRP_REC, - H264E_HAL_VPU_BUF_GRP_CABAC_TBL, - H264E_HAL_VPU_BUF_GRP_NALSIZE_TBL, - H264E_HAL_VPU_BUF_GRP_BUTT, -} h264e_hal_vpu_buf_grp; - -typedef struct h264e_hal_vpu_buffers_t { - MppBufferGroup hw_buf_grp; - - MppBuffer hw_rec_buf[2]; - MppBuffer hw_cabac_table_buf; - MppBuffer hw_nal_size_table_buf; -} h264e_hal_vpu_buffers; - typedef struct h264e_vpu_reg_set_t { RK_U32 val[VEPU_H264E_NUM_REGS]; } h264e_vpu_reg_set; diff --git a/mpp/hal/vpu/h264e/hal_h264e_vpu_tbl.h b/mpp/hal/vpu/h264e/hal_h264e_vpu_tbl.h new file mode 100644 index 00000000..24f5ae53 --- /dev/null +++ b/mpp/hal/vpu/h264e/hal_h264e_vpu_tbl.h @@ -0,0 +1,719 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * 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. + */ + +#ifndef __HAL_H264E_VPU_TBL_H__ +#define __HAL_H264E_VPU_TBL_H__ + +#include "rk_type.h" + +static const RK_S32 h264_q_step[] = { + 3, 3, 3, 4, 4, 5, 5, 6, 7, 7, + 8, 9, 10, 11, 13, 14, 16, 18, 20, 23, + 25, 28, 32, 36, 40, 45, 51, 57, 64, 72, + 80, 90, 101, 114, 128, 144, 160, 180, 203, 228, + 256, 288, 320, 360, 405, 456, 513, 577, 640, 720, + 810, 896 +}; + +/* H.264 motion estimation parameters */ +static const RK_U32 h264_prev_mode_favor[52] = { + 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 24, 25, 27, 29, 30, 32, 34, 36, 38, 41, 43, 46, + 49, 51, 55, 58, 61, 65, 69, 73, 78, 82, 87, 93, 98, 104, 110, + 117, 124, 132, 140 +}; + +/* sqrt(2^((qp-12)/3))*8 */ +static const RK_U32 h264_diff_mv_penalty[52] = { + 2, 2, 3, 3, 3, 4, 4, 4, 5, 6, + 6, 7, 8, 9, 10, 11, 13, 14, 16, 18, + 20, 23, 26, 29, 32, 36, 40, 45, 51, 57, + 64, 72, 81, 91, 102, 114, 128, 144, 161, 181, + 203, 228, 256, 287, 323, 362, 406, 456, 512, 575, + 645, 724 +}; + +/* 31*sqrt(2^((qp-12)/3))/4 */ +static const RK_U32 h264_diff_mv_penalty4p[52] = { + 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, + 6, 7, 8, 9, 10, 11, 12, 14, 16, 17, + 20, 22, 25, 28, 31, 35, 39, 44, 49, 55, + 62, 70, 78, 88, 98, 110, 124, 139, 156, 175, + 197, 221, 248, 278, 312, 351, 394, 442, 496, 557, + 625, 701 +}; + +static const RK_U32 h264_intra16_favor[52] = { + 24, 24, 24, 26, 27, 30, 32, 35, 39, 43, 48, 53, 58, 64, 71, 78, + 85, 93, 102, 111, 121, 131, 142, 154, 167, 180, 195, 211, 229, + 248, 271, 296, 326, 361, 404, 457, 523, 607, 714, 852, 1034, + 1272, 1588, 2008, 2568, 3318, 4323, 5672, 7486, 9928, 13216, + 17648 +}; + +static const RK_U32 h264_inter_favor[52] = { + 40, 40, 41, 42, 43, 44, 45, 48, 51, 53, 55, 60, 62, 67, 69, 72, + 78, 84, 90, 96, 110, 120, 135, 152, 170, 189, 210, 235, 265, + 297, 335, 376, 420, 470, 522, 572, 620, 670, 724, 770, 820, + 867, 915, 970, 1020, 1076, 1132, 1180, 1230, 1275, 1320, 1370 +}; + +static const RK_U32 h264_skip_sad_penalty[52] = { + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 233, 205, 182, 163, + 146, 132, 120, 109, 100, 92, 84, 78, 71, 66, 61, 56, 52, 48, + 44, 41, 38, 35, 32, 30, 27, 25, 23, 21, 19, 17, 15, 14, + 12, 11, 9, 8, 7, 5, 4, 3, 2, 1 +}; + +static const RK_S32 h264_context_init_intra[460][2] = { + /* 0 -> 10 */ + { 20, -15 }, { 2, 54 }, { 3, 74 }, { 20, -15 }, + { 2, 54 }, { 3, 74 }, { -28, 127 }, { -23, 104 }, + { -6, 53 }, { -1, 54 }, { 7, 51 }, + + /* 11 -> 23 unsused for I */ + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, + + /* 24 -> 39 */ + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + + /* 40 -> 53 */ + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, + + /* 54 -> 59 */ + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, + + /* 60 -> 69 */ + { 0, 41 }, { 0, 63 }, { 0, 63 }, { 0, 63 }, + { -9, 83 }, { 4, 86 }, { 0, 97 }, { -7, 72 }, + { 13, 41 }, { 3, 62 }, + + /* 70 -> 87 */ + { 0, 11 }, { 1, 55 }, { 0, 69 }, { -17, 127 }, + { -13, 102 }, { 0, 82 }, { -7, 74 }, { -21, 107 }, + { -27, 127 }, { -31, 127 }, { -24, 127 }, { -18, 95 }, + { -27, 127 }, { -21, 114 }, { -30, 127 }, { -17, 123 }, + { -12, 115 }, { -16, 122 }, + + /* 88 -> 104 */ + { -11, 115 }, { -12, 63 }, { -2, 68 }, { -15, 84 }, + { -13, 104 }, { -3, 70 }, { -8, 93 }, { -10, 90 }, + { -30, 127 }, { -1, 74 }, { -6, 97 }, { -7, 91 }, + { -20, 127 }, { -4, 56 }, { -5, 82 }, { -7, 76 }, + { -22, 125 }, + + /* 105 -> 135 */ + { -7, 93 }, { -11, 87 }, { -3, 77 }, { -5, 71 }, + { -4, 63 }, { -4, 68 }, { -12, 84 }, { -7, 62 }, + { -7, 65 }, { 8, 61 }, { 5, 56 }, { -2, 66 }, + { 1, 64 }, { 0, 61 }, { -2, 78 }, { 1, 50 }, + { 7, 52 }, { 10, 35 }, { 0, 44 }, { 11, 38 }, + { 1, 45 }, { 0, 46 }, { 5, 44 }, { 31, 17 }, + { 1, 51 }, { 7, 50 }, { 28, 19 }, { 16, 33 }, + { 14, 62 }, { -13, 108 }, { -15, 100 }, + + /* 136 -> 165 */ + { -13, 101 }, { -13, 91 }, { -12, 94 }, { -10, 88 }, + { -16, 84 }, { -10, 86 }, { -7, 83 }, { -13, 87 }, + { -19, 94 }, { 1, 70 }, { 0, 72 }, { -5, 74 }, + { 18, 59 }, { -8, 102 }, { -15, 100 }, { 0, 95 }, + { -4, 75 }, { 2, 72 }, { -11, 75 }, { -3, 71 }, + { 15, 46 }, { -13, 69 }, { 0, 62 }, { 0, 65 }, + { 21, 37 }, { -15, 72 }, { 9, 57 }, { 16, 54 }, + { 0, 62 }, { 12, 72 }, + + /* 166 -> 196 */ + { 24, 0 }, { 15, 9 }, { 8, 25 }, { 13, 18 }, + { 15, 9 }, { 13, 19 }, { 10, 37 }, { 12, 18 }, + { 6, 29 }, { 20, 33 }, { 15, 30 }, { 4, 45 }, + { 1, 58 }, { 0, 62 }, { 7, 61 }, { 12, 38 }, + { 11, 45 }, { 15, 39 }, { 11, 42 }, { 13, 44 }, + { 16, 45 }, { 12, 41 }, { 10, 49 }, { 30, 34 }, + { 18, 42 }, { 10, 55 }, { 17, 51 }, { 17, 46 }, + { 0, 89 }, { 26, -19 }, { 22, -17 }, + + /* 197 -> 226 */ + { 26, -17 }, { 30, -25 }, { 28, -20 }, { 33, -23 }, + { 37, -27 }, { 33, -23 }, { 40, -28 }, { 38, -17 }, + { 33, -11 }, { 40, -15 }, { 41, -6 }, { 38, 1 }, + { 41, 17 }, { 30, -6 }, { 27, 3 }, { 26, 22 }, + { 37, -16 }, { 35, -4 }, { 38, -8 }, { 38, -3 }, + { 37, 3 }, { 38, 5 }, { 42, 0 }, { 35, 16 }, + { 39, 22 }, { 14, 48 }, { 27, 37 }, { 21, 60 }, + { 12, 68 }, { 2, 97 }, + + /* 227 -> 251 */ + { -3, 71 }, { -6, 42 }, { -5, 50 }, { -3, 54 }, + { -2, 62 }, { 0, 58 }, { 1, 63 }, { -2, 72 }, + { -1, 74 }, { -9, 91 }, { -5, 67 }, { -5, 27 }, + { -3, 39 }, { -2, 44 }, { 0, 46 }, { -16, 64 }, + { -8, 68 }, { -10, 78 }, { -6, 77 }, { -10, 86 }, + { -12, 92 }, { -15, 55 }, { -10, 60 }, { -6, 62 }, + { -4, 65 }, + + /* 252 -> 275 */ + { -12, 73 }, { -8, 76 }, { -7, 80 }, { -9, 88 }, + { -17, 110 }, { -11, 97 }, { -20, 84 }, { -11, 79 }, + { -6, 73 }, { -4, 74 }, { -13, 86 }, { -13, 96 }, + { -11, 97 }, { -19, 117 }, { -8, 78 }, { -5, 33 }, + { -4, 48 }, { -2, 53 }, { -3, 62 }, { -13, 71 }, + { -10, 79 }, { -12, 86 }, { -13, 90 }, { -14, 97 }, + + /* 276 special case, bypass used */ + { 0, 0 }, + + /* 277 -> 307 */ + { -6, 93 }, { -6, 84 }, { -8, 79 }, { 0, 66 }, + { -1, 71 }, { 0, 62 }, { -2, 60 }, { -2, 59 }, + { -5, 75 }, { -3, 62 }, { -4, 58 }, { -9, 66 }, + { -1, 79 }, { 0, 71 }, { 3, 68 }, { 10, 44 }, + { -7, 62 }, { 15, 36 }, { 14, 40 }, { 16, 27 }, + { 12, 29 }, { 1, 44 }, { 20, 36 }, { 18, 32 }, + { 5, 42 }, { 1, 48 }, { 10, 62 }, { 17, 46 }, + { 9, 64 }, { -12, 104 }, { -11, 97 }, + + /* 308 -> 337 */ + { -16, 96 }, { -7, 88 }, { -8, 85 }, { -7, 85 }, + { -9, 85 }, { -13, 88 }, { 4, 66 }, { -3, 77 }, + { -3, 76 }, { -6, 76 }, { 10, 58 }, { -1, 76 }, + { -1, 83 }, { -7, 99 }, { -14, 95 }, { 2, 95 }, + { 0, 76 }, { -5, 74 }, { 0, 70 }, { -11, 75 }, + { 1, 68 }, { 0, 65 }, { -14, 73 }, { 3, 62 }, + { 4, 62 }, { -1, 68 }, { -13, 75 }, { 11, 55 }, + { 5, 64 }, { 12, 70 }, + + /* 338 -> 368 */ + { 15, 6 }, { 6, 19 }, { 7, 16 }, { 12, 14 }, + { 18, 13 }, { 13, 11 }, { 13, 15 }, { 15, 16 }, + { 12, 23 }, { 13, 23 }, { 15, 20 }, { 14, 26 }, + { 14, 44 }, { 17, 40 }, { 17, 47 }, { 24, 17 }, + { 21, 21 }, { 25, 22 }, { 31, 27 }, { 22, 29 }, + { 19, 35 }, { 14, 50 }, { 10, 57 }, { 7, 63 }, + { -2, 77 }, { -4, 82 }, { -3, 94 }, { 9, 69 }, + { -12, 109 }, { 36, -35 }, { 36, -34 }, + + /* 369 -> 398 */ + { 32, -26 }, { 37, -30 }, { 44, -32 }, { 34, -18 }, + { 34, -15 }, { 40, -15 }, { 33, -7 }, { 35, -5 }, + { 33, 0 }, { 38, 2 }, { 33, 13 }, { 23, 35 }, + { 13, 58 }, { 29, -3 }, { 26, 0 }, { 22, 30 }, + { 31, -7 }, { 35, -15 }, { 34, -3 }, { 34, 3 }, + { 36, -1 }, { 34, 5 }, { 32, 11 }, { 35, 5 }, + { 34, 12 }, { 39, 11 }, { 30, 29 }, { 34, 26 }, + { 29, 39 }, { 19, 66 }, + + /* 399 -> 435 */ + { 31, 21 }, { 31, 31 }, { 25, 50 }, + { -17, 120 }, { -20, 112 }, { -18, 114 }, { -11, 85 }, + { -15, 92 }, { -14, 89 }, { -26, 71 }, { -15, 81 }, + { -14, 80 }, { 0, 68 }, { -14, 70 }, { -24, 56 }, + { -23, 68 }, { -24, 50 }, { -11, 74 }, { 23, -13 }, + { 26, -13 }, { 40, -15 }, { 49, -14 }, { 44, 3 }, + { 45, 6 }, { 44, 34 }, { 33, 54 }, { 19, 82 }, + { -3, 75 }, { -1, 23 }, { 1, 34 }, { 1, 43 }, + { 0, 54 }, { -2, 55 }, { 0, 61 }, { 1, 64 }, + { 0, 68 }, { -9, 92 }, + + /* 436 -> 459 */ + { -14, 106 }, { -13, 97 }, { -15, 90 }, { -12, 90 }, + { -18, 88 }, { -10, 73 }, { -9, 79 }, { -14, 86 }, + { -10, 73 }, { -10, 70 }, { -10, 69 }, { -5, 66 }, + { -9, 64 }, { -5, 58 }, { 2, 59 }, { 21, -10 }, + { 24, -11 }, { 28, -8 }, { 28, -1 }, { 29, 3 }, + { 29, 9 }, { 35, 20 }, { 29, 36 }, { 14, 67 } +}; + +static const RK_S32 h264_context_init[3][460][2] = { + /* cabac_init_idc == 0 */ + { + /* 0 -> 10 */ + { 20, -15 }, { 2, 54 }, { 3, 74 }, { 20, -15 }, + { 2, 54 }, { 3, 74 }, { -28, 127 }, { -23, 104 }, + { -6, 53 }, { -1, 54 }, { 7, 51 }, + + /* 11 -> 23 */ + { 23, 33 }, { 23, 2 }, { 21, 0 }, { 1, 9 }, + { 0, 49 }, { -37, 118 }, { 5, 57 }, { -13, 78 }, + { -11, 65 }, { 1, 62 }, { 12, 49 }, { -4, 73 }, + { 17, 50 }, + + /* 24 -> 39 */ + { 18, 64 }, { 9, 43 }, { 29, 0 }, { 26, 67 }, + { 16, 90 }, { 9, 104 }, { -46, 127 }, { -20, 104 }, + { 1, 67 }, { -13, 78 }, { -11, 65 }, { 1, 62 }, + { -6, 86 }, { -17, 95 }, { -6, 61 }, { 9, 45 }, + + /* 40 -> 53 */ + { -3, 69 }, { -6, 81 }, { -11, 96 }, { 6, 55 }, + { 7, 67 }, { -5, 86 }, { 2, 88 }, { 0, 58 }, + { -3, 76 }, { -10, 94 }, { 5, 54 }, { 4, 69 }, + { -3, 81 }, { 0, 88 }, + + /* 54 -> 59 */ + { -7, 67 }, { -5, 74 }, { -4, 74 }, { -5, 80 }, + { -7, 72 }, { 1, 58 }, + + /* 60 -> 69 */ + { 0, 41 }, { 0, 63 }, { 0, 63 }, { 0, 63 }, + { -9, 83 }, { 4, 86 }, { 0, 97 }, { -7, 72 }, + { 13, 41 }, { 3, 62 }, + + /* 70 -> 87 */ + { 0, 45 }, { -4, 78 }, { -3, 96 }, { -27, 126 }, + { -28, 98 }, { -25, 101 }, { -23, 67 }, { -28, 82 }, + { -20, 94 }, { -16, 83 }, { -22, 110 }, { -21, 91 }, + { -18, 102 }, { -13, 93 }, { -29, 127 }, { -7, 92 }, + { -5, 89 }, { -7, 96 }, { -13, 108 }, { -3, 46 }, + { -1, 65 }, { -1, 57 }, { -9, 93 }, { -3, 74 }, + { -9, 92 }, { -8, 87 }, { -23, 126 }, { 5, 54 }, + { 6, 60 }, { 6, 59 }, { 6, 69 }, { -1, 48 }, + { 0, 68 }, { -4, 69 }, { -8, 88 }, + + /* 105 -> 165 */ + { -2, 85 }, { -6, 78 }, { -1, 75 }, { -7, 77 }, + { 2, 54 }, { 5, 50 }, { -3, 68 }, { 1, 50 }, + { 6, 42 }, { -4, 81 }, { 1, 63 }, { -4, 70 }, + { 0, 67 }, { 2, 57 }, { -2, 76 }, { 11, 35 }, + { 4, 64 }, { 1, 61 }, { 11, 35 }, { 18, 25 }, + { 12, 24 }, { 13, 29 }, { 13, 36 }, { -10, 93 }, + { -7, 73 }, { -2, 73 }, { 13, 46 }, { 9, 49 }, + { -7, 100 }, { 9, 53 }, { 2, 53 }, { 5, 53 }, + { -2, 61 }, { 0, 56 }, { 0, 56 }, { -13, 63 }, + { -5, 60 }, { -1, 62 }, { 4, 57 }, { -6, 69 }, + { 4, 57 }, { 14, 39 }, { 4, 51 }, { 13, 68 }, + { 3, 64 }, { 1, 61 }, { 9, 63 }, { 7, 50 }, + { 16, 39 }, { 5, 44 }, { 4, 52 }, { 11, 48 }, + { -5, 60 }, { -1, 59 }, { 0, 59 }, { 22, 33 }, + { 5, 44 }, { 14, 43 }, { -1, 78 }, { 0, 60 }, + { 9, 69 }, + + /* 166 -> 226 */ + { 11, 28 }, { 2, 40 }, { 3, 44 }, { 0, 49 }, + { 0, 46 }, { 2, 44 }, { 2, 51 }, { 0, 47 }, + { 4, 39 }, { 2, 62 }, { 6, 46 }, { 0, 54 }, + { 3, 54 }, { 2, 58 }, { 4, 63 }, { 6, 51 }, + { 6, 57 }, { 7, 53 }, { 6, 52 }, { 6, 55 }, + { 11, 45 }, { 14, 36 }, { 8, 53 }, { -1, 82 }, + { 7, 55 }, { -3, 78 }, { 15, 46 }, { 22, 31 }, + { -1, 84 }, { 25, 7 }, { 30, -7 }, { 28, 3 }, + { 28, 4 }, { 32, 0 }, { 34, -1 }, { 30, 6 }, + { 30, 6 }, { 32, 9 }, { 31, 19 }, { 26, 27 }, + { 26, 30 }, { 37, 20 }, { 28, 34 }, { 17, 70 }, + { 1, 67 }, { 5, 59 }, { 9, 67 }, { 16, 30 }, + { 18, 32 }, { 18, 35 }, { 22, 29 }, { 24, 31 }, + { 23, 38 }, { 18, 43 }, { 20, 41 }, { 11, 63 }, + { 9, 59 }, { 9, 64 }, { -1, 94 }, { -2, 89 }, + { -9, 108 }, + + /* 227 -> 275 */ + { -6, 76 }, { -2, 44 }, { 0, 45 }, { 0, 52 }, + { -3, 64 }, { -2, 59 }, { -4, 70 }, { -4, 75 }, + { -8, 82 }, { -17, 102 }, { -9, 77 }, { 3, 24 }, + { 0, 42 }, { 0, 48 }, { 0, 55 }, { -6, 59 }, + { -7, 71 }, { -12, 83 }, { -11, 87 }, { -30, 119 }, + { 1, 58 }, { -3, 29 }, { -1, 36 }, { 1, 38 }, + { 2, 43 }, { -6, 55 }, { 0, 58 }, { 0, 64 }, + { -3, 74 }, { -10, 90 }, { 0, 70 }, { -4, 29 }, + { 5, 31 }, { 7, 42 }, { 1, 59 }, { -2, 58 }, + { -3, 72 }, { -3, 81 }, { -11, 97 }, { 0, 58 }, + { 8, 5 }, { 10, 14 }, { 14, 18 }, { 13, 27 }, + { 2, 40 }, { 0, 58 }, { -3, 70 }, { -6, 79 }, + { -8, 85 }, + + /* 276 special case, bypass used */ + { 0, 0 }, + + /* 277 -> 337 */ + { -13, 106 }, { -16, 106 }, { -10, 87 }, { -21, 114 }, + { -18, 110 }, { -14, 98 }, { -22, 110 }, { -21, 106 }, + { -18, 103 }, { -21, 107 }, { -23, 108 }, { -26, 112 }, + { -10, 96 }, { -12, 95 }, { -5, 91 }, { -9, 93 }, + { -22, 94 }, { -5, 86 }, { 9, 67 }, { -4, 80 }, + { -10, 85 }, { -1, 70 }, { 7, 60 }, { 9, 58 }, + { 5, 61 }, { 12, 50 }, { 15, 50 }, { 18, 49 }, + { 17, 54 }, { 10, 41 }, { 7, 46 }, { -1, 51 }, + { 7, 49 }, { 8, 52 }, { 9, 41 }, { 6, 47 }, + { 2, 55 }, { 13, 41 }, { 10, 44 }, { 6, 50 }, + { 5, 53 }, { 13, 49 }, { 4, 63 }, { 6, 64 }, + { -2, 69 }, { -2, 59 }, { 6, 70 }, { 10, 44 }, + { 9, 31 }, { 12, 43 }, { 3, 53 }, { 14, 34 }, + { 10, 38 }, { -3, 52 }, { 13, 40 }, { 17, 32 }, + { 7, 44 }, { 7, 38 }, { 13, 50 }, { 10, 57 }, + { 26, 43 }, + + /* 338 -> 398 */ + { 14, 11 }, { 11, 14 }, { 9, 11 }, { 18, 11 }, + { 21, 9 }, { 23, -2 }, { 32, -15 }, { 32, -15 }, + { 34, -21 }, { 39, -23 }, { 42, -33 }, { 41, -31 }, + { 46, -28 }, { 38, -12 }, { 21, 29 }, { 45, -24 }, + { 53, -45 }, { 48, -26 }, { 65, -43 }, { 43, -19 }, + { 39, -10 }, { 30, 9 }, { 18, 26 }, { 20, 27 }, + { 0, 57 }, { -14, 82 }, { -5, 75 }, { -19, 97 }, + { -35, 125 }, { 27, 0 }, { 28, 0 }, { 31, -4 }, + { 27, 6 }, { 34, 8 }, { 30, 10 }, { 24, 22 }, + { 33, 19 }, { 22, 32 }, { 26, 31 }, { 21, 41 }, + { 26, 44 }, { 23, 47 }, { 16, 65 }, { 14, 71 }, + { 8, 60 }, { 6, 63 }, { 17, 65 }, { 21, 24 }, + { 23, 20 }, { 26, 23 }, { 27, 32 }, { 28, 23 }, + { 28, 24 }, { 23, 40 }, { 24, 32 }, { 28, 29 }, + { 23, 42 }, { 19, 57 }, { 22, 53 }, { 22, 61 }, + { 11, 86 }, + + /* 399 -> 435 */ + { 12, 40 }, { 11, 51 }, { 14, 59 }, + { -4, 79 }, { -7, 71 }, { -5, 69 }, { -9, 70 }, + { -8, 66 }, { -10, 68 }, { -19, 73 }, { -12, 69 }, + { -16, 70 }, { -15, 67 }, { -20, 62 }, { -19, 70 }, + { -16, 66 }, { -22, 65 }, { -20, 63 }, { 9, -2 }, + { 26, -9 }, { 33, -9 }, { 39, -7 }, { 41, -2 }, + { 45, 3 }, { 49, 9 }, { 45, 27 }, { 36, 59 }, + { -6, 66 }, { -7, 35 }, { -7, 42 }, { -8, 45 }, + { -5, 48 }, { -12, 56 }, { -6, 60 }, { -5, 62 }, + { -8, 66 }, { -8, 76 }, + + /* 436 -> 459 */ + { -5, 85 }, { -6, 81 }, { -10, 77 }, { -7, 81 }, + { -17, 80 }, { -18, 73 }, { -4, 74 }, { -10, 83 }, + { -9, 71 }, { -9, 67 }, { -1, 61 }, { -8, 66 }, + { -14, 66 }, { 0, 59 }, { 2, 59 }, { 21, -13 }, + { 33, -14 }, { 39, -7 }, { 46, -2 }, { 51, 2 }, + { 60, 6 }, { 61, 17 }, { 55, 34 }, { 42, 62 }, + }, + + /* cabac_init_idc == 1 */ + { + /* 0 -> 10 */ + { 20, -15 }, { 2, 54 }, { 3, 74 }, { 20, -15 }, + { 2, 54 }, { 3, 74 }, { -28, 127 }, { -23, 104 }, + { -6, 53 }, { -1, 54 }, { 7, 51 }, + + /* 11 -> 23 */ + { 22, 25 }, { 34, 0 }, { 16, 0 }, { -2, 9 }, + { 4, 41 }, { -29, 118 }, { 2, 65 }, { -6, 71 }, + { -13, 79 }, { 5, 52 }, { 9, 50 }, { -3, 70 }, + { 10, 54 }, + + /* 24 -> 39 */ + { 26, 34 }, { 19, 22 }, { 40, 0 }, { 57, 2 }, + { 41, 36 }, { 26, 69 }, { -45, 127 }, { -15, 101 }, + { -4, 76 }, { -6, 71 }, { -13, 79 }, { 5, 52 }, + { 6, 69 }, { -13, 90 }, { 0, 52 }, { 8, 43 }, + + /* 40 -> 53 */ + { -2, 69 }, { -5, 82 }, { -10, 96 }, { 2, 59 }, + { 2, 75 }, { -3, 87 }, { -3, 100 }, { 1, 56 }, + { -3, 74 }, { -6, 85 }, { 0, 59 }, { -3, 81 }, + { -7, 86 }, { -5, 95 }, + + /* 54 -> 59 */ + { -1, 66 }, { -1, 77 }, { 1, 70 }, { -2, 86 }, + { -5, 72 }, { 0, 61 }, + + /* 60 -> 69 */ + { 0, 41 }, { 0, 63 }, { 0, 63 }, { 0, 63 }, + { -9, 83 }, { 4, 86 }, { 0, 97 }, { -7, 72 }, + { 13, 41 }, { 3, 62 }, + + /* 70 -> 104 */ + { 13, 15 }, { 7, 51 }, { 2, 80 }, { -39, 127 }, + { -18, 91 }, { -17, 96 }, { -26, 81 }, { -35, 98 }, + { -24, 102 }, { -23, 97 }, { -27, 119 }, { -24, 99 }, + { -21, 110 }, { -18, 102 }, { -36, 127 }, { 0, 80 }, + { -5, 89 }, { -7, 94 }, { -4, 92 }, { 0, 39 }, + { 0, 65 }, { -15, 84 }, { -35, 127 }, { -2, 73 }, + { -12, 104 }, { -9, 91 }, { -31, 127 }, { 3, 55 }, + { 7, 56 }, { 7, 55 }, { 8, 61 }, { -3, 53 }, + { 0, 68 }, { -7, 74 }, { -9, 88 }, + + /* 105 -> 165 */ + { -13, 103 }, { -13, 91 }, { -9, 89 }, { -14, 92 }, + { -8, 76 }, { -12, 87 }, { -23, 110 }, { -24, 105 }, + { -10, 78 }, { -20, 112 }, { -17, 99 }, { -78, 127 }, + { -70, 127 }, { -50, 127 }, { -46, 127 }, { -4, 66 }, + { -5, 78 }, { -4, 71 }, { -8, 72 }, { 2, 59 }, + { -1, 55 }, { -7, 70 }, { -6, 75 }, { -8, 89 }, + { -34, 119 }, { -3, 75 }, { 32, 20 }, { 30, 22 }, + { -44, 127 }, { 0, 54 }, { -5, 61 }, { 0, 58 }, + { -1, 60 }, { -3, 61 }, { -8, 67 }, { -25, 84 }, + { -14, 74 }, { -5, 65 }, { 5, 52 }, { 2, 57 }, + { 0, 61 }, { -9, 69 }, { -11, 70 }, { 18, 55 }, + { -4, 71 }, { 0, 58 }, { 7, 61 }, { 9, 41 }, + { 18, 25 }, { 9, 32 }, { 5, 43 }, { 9, 47 }, + { 0, 44 }, { 0, 51 }, { 2, 46 }, { 19, 38 }, + { -4, 66 }, { 15, 38 }, { 12, 42 }, { 9, 34 }, + { 0, 89 }, + + /* 166 -> 226 */ + { 4, 45 }, { 10, 28 }, { 10, 31 }, { 33, -11 }, + { 52, -43 }, { 18, 15 }, { 28, 0 }, { 35, -22 }, + { 38, -25 }, { 34, 0 }, { 39, -18 }, { 32, -12 }, + { 102, -94 }, { 0, 0 }, { 56, -15 }, { 33, -4 }, + { 29, 10 }, { 37, -5 }, { 51, -29 }, { 39, -9 }, + { 52, -34 }, { 69, -58 }, { 67, -63 }, { 44, -5 }, + { 32, 7 }, { 55, -29 }, { 32, 1 }, { 0, 0 }, + { 27, 36 }, { 33, -25 }, { 34, -30 }, { 36, -28 }, + { 38, -28 }, { 38, -27 }, { 34, -18 }, { 35, -16 }, + { 34, -14 }, { 32, -8 }, { 37, -6 }, { 35, 0 }, + { 30, 10 }, { 28, 18 }, { 26, 25 }, { 29, 41 }, + { 0, 75 }, { 2, 72 }, { 8, 77 }, { 14, 35 }, + { 18, 31 }, { 17, 35 }, { 21, 30 }, { 17, 45 }, + { 20, 42 }, { 18, 45 }, { 27, 26 }, { 16, 54 }, + { 7, 66 }, { 16, 56 }, { 11, 73 }, { 10, 67 }, + { -10, 116 }, + + /* 227 -> 275 */ + { -23, 112 }, { -15, 71 }, { -7, 61 }, { 0, 53 }, + { -5, 66 }, { -11, 77 }, { -9, 80 }, { -9, 84 }, + { -10, 87 }, { -34, 127 }, { -21, 101 }, { -3, 39 }, + { -5, 53 }, { -7, 61 }, { -11, 75 }, { -15, 77 }, + { -17, 91 }, { -25, 107 }, { -25, 111 }, { -28, 122 }, + { -11, 76 }, { -10, 44 }, { -10, 52 }, { -10, 57 }, + { -9, 58 }, { -16, 72 }, { -7, 69 }, { -4, 69 }, + { -5, 74 }, { -9, 86 }, { 2, 66 }, { -9, 34 }, + { 1, 32 }, { 11, 31 }, { 5, 52 }, { -2, 55 }, + { -2, 67 }, { 0, 73 }, { -8, 89 }, { 3, 52 }, + { 7, 4 }, { 10, 8 }, { 17, 8 }, { 16, 19 }, + { 3, 37 }, { -1, 61 }, { -5, 73 }, { -1, 70 }, + { -4, 78 }, + + /* 276 special case, bypass used */ + { 0, 0 }, + + /* 277 -> 337 */ + { -21, 126 }, { -23, 124 }, { -20, 110 }, { -26, 126 }, + { -25, 124 }, { -17, 105 }, { -27, 121 }, { -27, 117 }, + { -17, 102 }, { -26, 117 }, { -27, 116 }, { -33, 122 }, + { -10, 95 }, { -14, 100 }, { -8, 95 }, { -17, 111 }, + { -28, 114 }, { -6, 89 }, { -2, 80 }, { -4, 82 }, + { -9, 85 }, { -8, 81 }, { -1, 72 }, { 5, 64 }, + { 1, 67 }, { 9, 56 }, { 0, 69 }, { 1, 69 }, + { 7, 69 }, { -7, 69 }, { -6, 67 }, { -16, 77 }, + { -2, 64 }, { 2, 61 }, { -6, 67 }, { -3, 64 }, + { 2, 57 }, { -3, 65 }, { -3, 66 }, { 0, 62 }, + { 9, 51 }, { -1, 66 }, { -2, 71 }, { -2, 75 }, + { -1, 70 }, { -9, 72 }, { 14, 60 }, { 16, 37 }, + { 0, 47 }, { 18, 35 }, { 11, 37 }, { 12, 41 }, + { 10, 41 }, { 2, 48 }, { 12, 41 }, { 13, 41 }, + { 0, 59 }, { 3, 50 }, { 19, 40 }, { 3, 66 }, + { 18, 50 }, + + /* 338 -> 398 */ + { 19, -6 }, { 18, -6 }, { 14, 0 }, { 26, -12 }, + { 31, -16 }, { 33, -25 }, { 33, -22 }, { 37, -28 }, + { 39, -30 }, { 42, -30 }, { 47, -42 }, { 45, -36 }, + { 49, -34 }, { 41, -17 }, { 32, 9 }, { 69, -71 }, + { 63, -63 }, { 66, -64 }, { 77, -74 }, { 54, -39 }, + { 52, -35 }, { 41, -10 }, { 36, 0 }, { 40, -1 }, + { 30, 14 }, { 28, 26 }, { 23, 37 }, { 12, 55 }, + { 11, 65 }, { 37, -33 }, { 39, -36 }, { 40, -37 }, + { 38, -30 }, { 46, -33 }, { 42, -30 }, { 40, -24 }, + { 49, -29 }, { 38, -12 }, { 40, -10 }, { 38, -3 }, + { 46, -5 }, { 31, 20 }, { 29, 30 }, { 25, 44 }, + { 12, 48 }, { 11, 49 }, { 26, 45 }, { 22, 22 }, + { 23, 22 }, { 27, 21 }, { 33, 20 }, { 26, 28 }, + { 30, 24 }, { 27, 34 }, { 18, 42 }, { 25, 39 }, + { 18, 50 }, { 12, 70 }, { 21, 54 }, { 14, 71 }, + { 11, 83 }, + + /* 399 -> 435 */ + { 25, 32 }, { 21, 49 }, { 21, 54 }, + { -5, 85 }, { -6, 81 }, { -10, 77 }, { -7, 81 }, + { -17, 80 }, { -18, 73 }, { -4, 74 }, { -10, 83 }, + { -9, 71 }, { -9, 67 }, { -1, 61 }, { -8, 66 }, + { -14, 66 }, { 0, 59 }, { 2, 59 }, { 17, -10 }, + { 32, -13 }, { 42, -9 }, { 49, -5 }, { 53, 0 }, + { 64, 3 }, { 68, 10 }, { 66, 27 }, { 47, 57 }, + { -5, 71 }, { 0, 24 }, { -1, 36 }, { -2, 42 }, + { -2, 52 }, { -9, 57 }, { -6, 63 }, { -4, 65 }, + { -4, 67 }, { -7, 82 }, + + /* 436 -> 459 */ + { -3, 81 }, { -3, 76 }, { -7, 72 }, { -6, 78 }, + { -12, 72 }, { -14, 68 }, { -3, 70 }, { -6, 76 }, + { -5, 66 }, { -5, 62 }, { 0, 57 }, { -4, 61 }, + { -9, 60 }, { 1, 54 }, { 2, 58 }, { 17, -10 }, + { 32, -13 }, { 42, -9 }, { 49, -5 }, { 53, 0 }, + { 64, 3 }, { 68, 10 }, { 66, 27 }, { 47, 57 }, + }, + + /* cabac_init_idc == 2 */ + { + /* 0 -> 10 */ + { 20, -15 }, { 2, 54 }, { 3, 74 }, { 20, -15 }, + { 2, 54 }, { 3, 74 }, { -28, 127 }, { -23, 104 }, + { -6, 53 }, { -1, 54 }, { 7, 51 }, + + /* 11 -> 23 */ + { 29, 16 }, { 25, 0 }, { 14, 0 }, { -10, 51 }, + { -3, 62 }, { -27, 99 }, { 26, 16 }, { -4, 85 }, + { -24, 102 }, { 5, 57 }, { 6, 57 }, { -17, 73 }, + { 14, 57 }, + + /* 24 -> 39 */ + { 20, 40 }, { 20, 10 }, { 29, 0 }, { 54, 0 }, + { 37, 42 }, { 12, 97 }, { -32, 127 }, { -22, 117 }, + { -2, 74 }, { -4, 85 }, { -24, 102 }, { 5, 57 }, + { -6, 93 }, { -14, 88 }, { -6, 44 }, { 4, 55 }, + + /* 40 -> 53 */ + { -11, 89 }, { -15, 103 }, { -21, 116 }, { 19, 57 }, + { 20, 58 }, { 4, 84 }, { 6, 96 }, { 1, 63 }, + { -5, 85 }, { -13, 106 }, { 5, 63 }, { 6, 75 }, + { -3, 90 }, { -1, 101 }, + + /* 54 -> 59 */ + { 3, 55 }, { -4, 79 }, { -2, 75 }, { -12, 97 }, + { -7, 50 }, { 1, 60 }, + + /* 60 -> 69 */ + { 0, 41 }, { 0, 63 }, { 0, 63 }, { 0, 63 }, + { -9, 83 }, { 4, 86 }, { 0, 97 }, { -7, 72 }, + { 13, 41 }, { 3, 62 }, + + /* 70 -> 104 */ + { 7, 34 }, { -9, 88 }, { -20, 127 }, { -36, 127 }, + { -17, 91 }, { -14, 95 }, { -25, 84 }, { -25, 86 }, + { -12, 89 }, { -17, 91 }, { -31, 127 }, { -14, 76 }, + { -18, 103 }, { -13, 90 }, { -37, 127 }, { 11, 80 }, + { 5, 76 }, { 2, 84 }, { 5, 78 }, { -6, 55 }, + { 4, 61 }, { -14, 83 }, { -37, 127 }, { -5, 79 }, + { -11, 104 }, { -11, 91 }, { -30, 127 }, { 0, 65 }, + { -2, 79 }, { 0, 72 }, { -4, 92 }, { -6, 56 }, + { 3, 68 }, { -8, 71 }, { -13, 98 }, + + /* 105 -> 165 */ + { -4, 86 }, { -12, 88 }, { -5, 82 }, { -3, 72 }, + { -4, 67 }, { -8, 72 }, { -16, 89 }, { -9, 69 }, + { -1, 59 }, { 5, 66 }, { 4, 57 }, { -4, 71 }, + { -2, 71 }, { 2, 58 }, { -1, 74 }, { -4, 44 }, + { -1, 69 }, { 0, 62 }, { -7, 51 }, { -4, 47 }, + { -6, 42 }, { -3, 41 }, { -6, 53 }, { 8, 76 }, + { -9, 78 }, { -11, 83 }, { 9, 52 }, { 0, 67 }, + { -5, 90 }, { 1, 67 }, { -15, 72 }, { -5, 75 }, + { -8, 80 }, { -21, 83 }, { -21, 64 }, { -13, 31 }, + { -25, 64 }, { -29, 94 }, { 9, 75 }, { 17, 63 }, + { -8, 74 }, { -5, 35 }, { -2, 27 }, { 13, 91 }, + { 3, 65 }, { -7, 69 }, { 8, 77 }, { -10, 66 }, + { 3, 62 }, { -3, 68 }, { -20, 81 }, { 0, 30 }, + { 1, 7 }, { -3, 23 }, { -21, 74 }, { 16, 66 }, + { -23, 124 }, { 17, 37 }, { 44, -18 }, { 50, -34 }, + { -22, 127 }, + + /* 166 -> 226 */ + { 4, 39 }, { 0, 42 }, { 7, 34 }, { 11, 29 }, + { 8, 31 }, { 6, 37 }, { 7, 42 }, { 3, 40 }, + { 8, 33 }, { 13, 43 }, { 13, 36 }, { 4, 47 }, + { 3, 55 }, { 2, 58 }, { 6, 60 }, { 8, 44 }, + { 11, 44 }, { 14, 42 }, { 7, 48 }, { 4, 56 }, + { 4, 52 }, { 13, 37 }, { 9, 49 }, { 19, 58 }, + { 10, 48 }, { 12, 45 }, { 0, 69 }, { 20, 33 }, + { 8, 63 }, { 35, -18 }, { 33, -25 }, { 28, -3 }, + { 24, 10 }, { 27, 0 }, { 34, -14 }, { 52, -44 }, + { 39, -24 }, { 19, 17 }, { 31, 25 }, { 36, 29 }, + { 24, 33 }, { 34, 15 }, { 30, 20 }, { 22, 73 }, + { 20, 34 }, { 19, 31 }, { 27, 44 }, { 19, 16 }, + { 15, 36 }, { 15, 36 }, { 21, 28 }, { 25, 21 }, + { 30, 20 }, { 31, 12 }, { 27, 16 }, { 24, 42 }, + { 0, 93 }, { 14, 56 }, { 15, 57 }, { 26, 38 }, + { -24, 127 }, + + /* 227 -> 275 */ + { -24, 115 }, { -22, 82 }, { -9, 62 }, { 0, 53 }, + { 0, 59 }, { -14, 85 }, { -13, 89 }, { -13, 94 }, + { -11, 92 }, { -29, 127 }, { -21, 100 }, { -14, 57 }, + { -12, 67 }, { -11, 71 }, { -10, 77 }, { -21, 85 }, + { -16, 88 }, { -23, 104 }, { -15, 98 }, { -37, 127 }, + { -10, 82 }, { -8, 48 }, { -8, 61 }, { -8, 66 }, + { -7, 70 }, { -14, 75 }, { -10, 79 }, { -9, 83 }, + { -12, 92 }, { -18, 108 }, { -4, 79 }, { -22, 69 }, + { -16, 75 }, { -2, 58 }, { 1, 58 }, { -13, 78 }, + { -9, 83 }, { -4, 81 }, { -13, 99 }, { -13, 81 }, + { -6, 38 }, { -13, 62 }, { -6, 58 }, { -2, 59 }, + { -16, 73 }, { -10, 76 }, { -13, 86 }, { -9, 83 }, + { -10, 87 }, + + /* 276 special case, bypass used */ + { 0, 0 }, + + /* 277 -> 337 */ + { -22, 127 }, { -25, 127 }, { -25, 120 }, { -27, 127 }, + { -19, 114 }, { -23, 117 }, { -25, 118 }, { -26, 117 }, + { -24, 113 }, { -28, 118 }, { -31, 120 }, { -37, 124 }, + { -10, 94 }, { -15, 102 }, { -10, 99 }, { -13, 106 }, + { -50, 127 }, { -5, 92 }, { 17, 57 }, { -5, 86 }, + { -13, 94 }, { -12, 91 }, { -2, 77 }, { 0, 71 }, + { -1, 73 }, { 4, 64 }, { -7, 81 }, { 5, 64 }, + { 15, 57 }, { 1, 67 }, { 0, 68 }, { -10, 67 }, + { 1, 68 }, { 0, 77 }, { 2, 64 }, { 0, 68 }, + { -5, 78 }, { 7, 55 }, { 5, 59 }, { 2, 65 }, + { 14, 54 }, { 15, 44 }, { 5, 60 }, { 2, 70 }, + { -2, 76 }, { -18, 86 }, { 12, 70 }, { 5, 64 }, + { -12, 70 }, { 11, 55 }, { 5, 56 }, { 0, 69 }, + { 2, 65 }, { -6, 74 }, { 5, 54 }, { 7, 54 }, + { -6, 76 }, { -11, 82 }, { -2, 77 }, { -2, 77 }, + { 25, 42 }, + + /* 338 -> 398 */ + { 17, -13 }, { 16, -9 }, { 17, -12 }, { 27, -21 }, + { 37, -30 }, { 41, -40 }, { 42, -41 }, { 48, -47 }, + { 39, -32 }, { 46, -40 }, { 52, -51 }, { 46, -41 }, + { 52, -39 }, { 43, -19 }, { 32, 11 }, { 61, -55 }, + { 56, -46 }, { 62, -50 }, { 81, -67 }, { 45, -20 }, + { 35, -2 }, { 28, 15 }, { 34, 1 }, { 39, 1 }, + { 30, 17 }, { 20, 38 }, { 18, 45 }, { 15, 54 }, + { 0, 79 }, { 36, -16 }, { 37, -14 }, { 37, -17 }, + { 32, 1 }, { 34, 15 }, { 29, 15 }, { 24, 25 }, + { 34, 22 }, { 31, 16 }, { 35, 18 }, { 31, 28 }, + { 33, 41 }, { 36, 28 }, { 27, 47 }, { 21, 62 }, + { 18, 31 }, { 19, 26 }, { 36, 24 }, { 24, 23 }, + { 27, 16 }, { 24, 30 }, { 31, 29 }, { 22, 41 }, + { 22, 42 }, { 16, 60 }, { 15, 52 }, { 14, 60 }, + { 3, 78 }, { -16, 123 }, { 21, 53 }, { 22, 56 }, + { 25, 61 }, + + /* 399 -> 435 */ + { 21, 33 }, { 19, 50 }, { 17, 61 }, + { -3, 78 }, { -8, 74 }, { -9, 72 }, { -10, 72 }, + { -18, 75 }, { -12, 71 }, { -11, 63 }, { -5, 70 }, + { -17, 75 }, { -14, 72 }, { -16, 67 }, { -8, 53 }, + { -14, 59 }, { -9, 52 }, { -11, 68 }, { 9, -2 }, + { 30, -10 }, { 31, -4 }, { 33, -1 }, { 33, 7 }, + { 31, 12 }, { 37, 23 }, { 31, 38 }, { 20, 64 }, + { -9, 71 }, { -7, 37 }, { -8, 44 }, { -11, 49 }, + { -10, 56 }, { -12, 59 }, { -8, 63 }, { -9, 67 }, + { -6, 68 }, { -10, 79 }, + + /* 436 -> 459 */ + { -3, 78 }, { -8, 74 }, { -9, 72 }, { -10, 72 }, + { -18, 75 }, { -12, 71 }, { -11, 63 }, { -5, 70 }, + { -17, 75 }, { -14, 72 }, { -16, 67 }, { -8, 53 }, + { -14, 59 }, { -9, 52 }, { -11, 68 }, { 9, -2 }, + { 30, -10 }, { 31, -4 }, { 33, -1 }, { 33, 7 }, + { 31, 12 }, { 37, 23 }, { 31, 38 }, { 20, 64 }, + } +}; + +#endif diff --git a/mpp/hal/vpu/jpege/hal_jpege_api.c b/mpp/hal/vpu/jpege/hal_jpege_api.c index 70114358..0969cb10 100644 --- a/mpp/hal/vpu/jpege/hal_jpege_api.c +++ b/mpp/hal/vpu/jpege/hal_jpege_api.c @@ -423,6 +423,7 @@ MPP_RET hal_jpege_wait(void *hal, HalTaskInfo *task) feedback.hw_status = val & 0x70; val = regs[53]; feedback.stream_length = jpege_bits_get_bitpos(bits) / 8 + val / 8; + task->enc.length = feedback.stream_length; hal_jpege_dbg_output("stream length: sw %d hw %d total %d\n", jpege_bits_get_bitpos(bits) / 8, val / 8, feedback.stream_length); diff --git a/mpp/legacy/vpu_api_legacy.cpp b/mpp/legacy/vpu_api_legacy.cpp index fe743f74..0c776507 100755 --- a/mpp/legacy/vpu_api_legacy.cpp +++ b/mpp/legacy/vpu_api_legacy.cpp @@ -306,6 +306,97 @@ RK_S32 VpuApiLegacy::init(VpuCodecContext *ctx, RK_U8 *extraData, RK_U32 extra_s mpi->control(mpp_ctx, MPP_ENC_SET_CFG, &mpp_cfg); + MppEncPrepCfg prep_cfg; + prep_cfg.change = MPP_ENC_PREP_CFG_CHANGE_INPUT | + MPP_ENC_PREP_CFG_CHANGE_FORMAT; + prep_cfg.width = param->width; + prep_cfg.height = param->height; + prep_cfg.hor_stride = MPP_ALIGN(param->width, 16); + prep_cfg.ver_stride = MPP_ALIGN(param->height, 16); + prep_cfg.format = (MppFrameFormat)mpp_cfg.format; + + mpi->control(mpp_ctx, MPP_ENC_SET_PREP_CFG, &prep_cfg); + + MppEncRcCfg rc_cfg; + rc_cfg.change = MPP_ENC_RC_CFG_CHANGE_ALL; + rc_cfg.rc_mode = (mpp_cfg.rc_mode == 0) ? (1) : /* 0 - constant QP */ + (mpp_cfg.rc_mode == 1) ? (5) : /* 1 - constant bitrate */ + (3); /* 2 - variable bitrate */ + rc_cfg.quality = 0; /* auto quality */ + + if (rc_cfg.rc_mode == 1) { + /* constant QP does not have bps */ + rc_cfg.bps_target = -1; + rc_cfg.bps_max = -1; + rc_cfg.bps_min = -1; + } else if (rc_cfg.rc_mode == 5) { + /* constant bitrate has very small bps range of 1/16 bps */ + rc_cfg.bps_target = mpp_cfg.bps; + rc_cfg.bps_max = mpp_cfg.bps * 17 / 16; + rc_cfg.bps_min = mpp_cfg.bps * 15 / 16; + } else if (rc_cfg.rc_mode == 3) { + /* variable bitrate has large bps range */ + rc_cfg.bps_target = mpp_cfg.bps; + rc_cfg.bps_max = mpp_cfg.bps * 17 / 16; + rc_cfg.bps_min = mpp_cfg.bps * 1 / 16; + } + + /* fix input / output frame rate */ + rc_cfg.fps_in_flex = 0; + rc_cfg.fps_in_num = mpp_cfg.fps_in; + rc_cfg.fps_in_denorm = 1; + rc_cfg.fps_out_flex = 0; + rc_cfg.fps_out_num = mpp_cfg.fps_out; + rc_cfg.fps_out_denorm = 1; + + rc_cfg.gop = mpp_cfg.gop; + rc_cfg.skip_cnt = mpp_cfg.skip_cnt; + + mpi->control(mpp_ctx, MPP_ENC_SET_RC_CFG, &rc_cfg); + + MppEncCodecCfg codec_cfg; + codec_cfg.coding = (MppCodingType)ctx->videoCoding; + switch (codec_cfg.coding) { + case MPP_VIDEO_CodingAVC : { + codec_cfg.h264.change = MPP_ENC_H264_CFG_STREAM_TYPE | + MPP_ENC_H264_CFG_CHANGE_PROFILE | + MPP_ENC_H264_CFG_CHANGE_ENTROPY | + MPP_ENC_H264_CFG_CHANGE_QP_LIMIT; + codec_cfg.h264.stream_type = 1; + codec_cfg.h264.profile = mpp_cfg.profile; + codec_cfg.h264.level = mpp_cfg.level; + codec_cfg.h264.entropy_coding_mode = mpp_cfg.cabac_en; + + if (rc_cfg.rc_mode == 1) { + /* constant QP mode qp is fixed */ + codec_cfg.h264.qp_max = mpp_cfg.qp; + codec_cfg.h264.qp_min = mpp_cfg.qp; + codec_cfg.h264.qp_max_step = 0; + } else if (rc_cfg.rc_mode == 5) { + /* constant bitrate do not limit qp range */ + codec_cfg.h264.qp_max = 48; + codec_cfg.h264.qp_min = 4; + codec_cfg.h264.qp_max_step = 51; + } else if (rc_cfg.rc_mode == 3) { + /* variable bitrate has qp min limit */ + codec_cfg.h264.qp_max = 48; + codec_cfg.h264.qp_min = mpp_cfg.qp; + codec_cfg.h264.qp_max_step = 8; + } + codec_cfg.h264.qp_init = 26; + } break; + case MPP_VIDEO_CodingMJPEG : { + codec_cfg.jpeg.change = MPP_ENC_JPEG_CFG_CHANGE_QP; + codec_cfg.jpeg.quant = mpp_cfg.qp; + } break; + case MPP_VIDEO_CodingVP8 : + case MPP_VIDEO_CodingHEVC : + default : { + mpp_err_f("support encoder coding type %d\n", codec_cfg.coding); + } break; + } + mpi->control(mpp_ctx, MPP_ENC_SET_CODEC_CFG, &codec_cfg); + mpi->control(mpp_ctx, MPP_ENC_GET_EXTRA_INFO, &pkt); if (pkt) { diff --git a/osal/inc/mpp_common.h b/osal/inc/mpp_common.h index 9519db59..c5345b0e 100644 --- a/osal/inc/mpp_common.h +++ b/osal/inc/mpp_common.h @@ -21,6 +21,8 @@ #define MPP_TAG_SIZE 32 +#define MPP_ABS(x) ((x) < (0) ? -(x) : (x)) + #define MPP_MAX(a, b) ((a) > (b) ? (a) : (b)) #define MPP_MAX3(a, b, c) MPP_MAX(MPP_MAX(a,b),c) #define MPP_MAX4(a, b, c, d) MPP_MAX((a), MPP_MAX3((b), (c), (d))) diff --git a/test/mpi_enc_test.c b/test/mpi_enc_test.c index 05e88d66..4aa93966 100644 --- a/test/mpi_enc_test.c +++ b/test/mpi_enc_test.c @@ -23,8 +23,9 @@ #include #include "rk_mpi.h" -#include "mpp_log.h" #include "mpp_env.h" +#include "mpp_mem.h" +#include "mpp_log.h" #include "mpp_time.h" #include "mpp_common.h" @@ -52,6 +53,66 @@ typedef struct { RK_U32 have_output; } MpiEncTestCmd; +typedef struct { + // global flow control flag + RK_U32 frm_eos; + RK_U32 pkt_eos; + RK_U32 frame_count; + RK_U64 stream_size; + + // src and dst + FILE *fp_input; + FILE *fp_output; + + // base flow context + MppCtx ctx; + MppApi *mpi; + MppEncConfig mpp_cfg; + MppEncPrepCfg prep_cfg; + MppEncRcCfg rc_cfg; + MppEncCodecCfg codec_cfg; + + // input / output + MppBufferGroup frm_grp; + MppBufferGroup pkt_grp; + MppFrame frame; + MppPacket packet; + MppBuffer frm_buf[MPI_ENC_IO_COUNT]; + MppBuffer pkt_buf[MPI_ENC_IO_COUNT]; + MppBuffer md_buf[MPI_ENC_IO_COUNT]; + MppBuffer osd_idx_buf[MPI_ENC_IO_COUNT]; + MppEncOSDPlt osd_plt; + MppEncSeiMode sei_mode; + + // paramter for resource malloc + RK_U32 width; + RK_U32 height; + RK_U32 hor_stride; + RK_U32 ver_stride; + MppFrameFormat fmt; + MppCodingType type; + RK_U32 num_frames; + + // resources + size_t frame_size; + /* NOTE: packet buffer may overflow */ + size_t packet_size; + /* 32bits for each 16x16 block */ + size_t mdinfo_size; + /* osd idx size range from 16x16 bytes(pixels) to hor_stride*ver_stride(bytes). for general use, 1/8 Y buffer is enough. */ + size_t osd_idx_size; + RK_U32 plt_table[8]; + + // rate control runtime parameter + RK_S32 gop; + RK_S32 fps; + RK_S32 bps; + RK_S32 qp_min; + RK_S32 qp_max; + RK_S32 qp_step; + RK_S32 qp_init; +} MpiEncTestData; + static OptionInfo mpi_enc_cmd[] = { {"i", "input_file", "input bitstream file"}, {"o", "output_file", "output bitstream file, "}, @@ -63,16 +124,17 @@ static OptionInfo mpi_enc_cmd[] = { {"d", "debug", "debug flag"}, }; -static MPP_RET read_yuv_image(RK_U8 *buf, MppEncConfig *mpp_cfg, FILE *fp) +static MPP_RET read_yuv_image(RK_U8 *buf, MpiEncTestData *p) { MPP_RET ret = MPP_OK; RK_U32 read_size; RK_U32 row = 0; - RK_U32 width = mpp_cfg->width; - RK_U32 height = mpp_cfg->height; - RK_U32 hor_stride = mpp_cfg->hor_stride; - RK_U32 ver_stride = mpp_cfg->ver_stride; - MppFrameFormat fmt = mpp_cfg->format; + FILE *fp = p->fp_input; + RK_U32 width = p->width; + RK_U32 height = p->height; + RK_U32 hor_stride = p->hor_stride; + RK_U32 ver_stride = p->ver_stride; + MppFrameFormat fmt = p->fmt; RK_U8 *buf_y = buf; RK_U8 *buf_u = buf_y + hor_stride * ver_stride; // NOTE: diff from gen_yuv_image RK_U8 *buf_v = buf_u + hor_stride * ver_stride / 4; // NOTE: diff from gen_yuv_image @@ -136,14 +198,15 @@ err: return ret; } -static MPP_RET fill_yuv_image(RK_U8 *buf, MppEncConfig *mpp_cfg, RK_U32 frame_count) +static MPP_RET fill_yuv_image(RK_U8 *buf, MpiEncTestData *c) { MPP_RET ret = MPP_OK; - RK_U32 width = mpp_cfg->width; - RK_U32 height = mpp_cfg->height; - RK_U32 hor_stride = mpp_cfg->hor_stride; - RK_U32 ver_stride = mpp_cfg->ver_stride; - MppFrameFormat fmt = mpp_cfg->format; + RK_U32 width = c->width; + RK_U32 height = c->height; + RK_U32 hor_stride = c->hor_stride; + RK_U32 ver_stride = c->ver_stride; + MppFrameFormat fmt = c->fmt; + RK_U32 frame_count = c->frame_count; RK_U8 *buf_y = buf; RK_U8 *buf_c = buf + hor_stride * ver_stride; RK_U32 x, y; @@ -232,170 +295,408 @@ static MPP_RET mpi_enc_gen_osd_plt(MppEncOSDPlt *osd_plt, RK_U32 *table) return MPP_OK; } -int mpi_enc_test(MpiEncTestCmd *cmd) +MPP_RET test_ctx_init(MpiEncTestData **data, MpiEncTestCmd *cmd) { - MPP_RET ret = MPP_OK; - RK_U32 frm_eos = 0; - RK_U32 pkt_eos = 0; - FILE *fp_input = NULL; - FILE *fp_output = NULL; + MpiEncTestData *p = NULL; + MPP_RET ret = MPP_OK; - // base flow context - MppCtx ctx = NULL; - MppApi *mpi = NULL; - MppEncConfig mpp_cfg; + if (!data || !cmd) { + mpp_err_f("invalid input data %p cmd %p\n", data, cmd); + return MPP_ERR_NULL_PTR; + } - // input / output - RK_S32 i; - MppBufferGroup frm_grp = NULL; - MppBufferGroup pkt_grp = NULL; - MppFrame frame = NULL; - MppPacket packet = NULL; - MppBuffer frm_buf[MPI_ENC_IO_COUNT] = { NULL }; - MppBuffer pkt_buf[MPI_ENC_IO_COUNT] = { NULL }; - MppBuffer md_buf[MPI_ENC_IO_COUNT] = { NULL }; - MppBuffer osd_idx_buf[MPI_ENC_IO_COUNT] = { NULL }; - MppEncOSDPlt osd_plt; - MppEncSeiMode sei_mode = MPP_ENC_SEI_MODE_ONE_SEQ; + p = mpp_calloc(MpiEncTestData, 1); + if (!p) { + mpp_err_f("create MpiEncTestData failed\n"); + ret = MPP_ERR_MALLOC; + goto RET; + } - // paramter for resource malloc - RK_U32 width = cmd->width; - RK_U32 height = cmd->height; - RK_U32 hor_stride = MPP_ALIGN(width, 16); - RK_U32 ver_stride = MPP_ALIGN(height, 16); - MppFrameFormat fmt = cmd->format; - MppCodingType type = cmd->type; - RK_U32 num_frames = cmd->num_frames; - - // resources - size_t frame_size = hor_stride * ver_stride * 3 / 2; - /* NOTE: packet buffer may overflow */ - size_t packet_size = width * height; - /* 32bits for each 16x16 block */ - size_t mdinfo_size = (((hor_stride + 255) & (~255)) / 16) * (ver_stride / 16) * 4; //NOTE: hor_stride should be 16-MB aligned - /* osd idx size range from 16x16 bytes(pixels) to hor_stride*ver_stride(bytes). for general use, 1/8 Y buffer is enough. */ - size_t osd_idx_size = hor_stride * ver_stride / 8; - RK_U32 frame_count = 0; - RK_U64 stream_size = 0; - RK_U32 plt_table[8] = { - MPP_ENC_OSD_PLT_WHITE, - MPP_ENC_OSD_PLT_YELLOW, - MPP_ENC_OSD_PLT_CYAN, - MPP_ENC_OSD_PLT_GREEN, - MPP_ENC_OSD_PLT_TRANS, - MPP_ENC_OSD_PLT_RED, - MPP_ENC_OSD_PLT_BLUE, - MPP_ENC_OSD_PLT_BLACK - }; - - mpp_log("mpi_enc_test start\n"); + // get paramter from cmd + p->width = cmd->width; + p->height = cmd->height; + p->hor_stride = MPP_ALIGN(cmd->width, 16); + p->ver_stride = MPP_ALIGN(cmd->height, 16); + p->fmt = cmd->format; + p->type = cmd->type; + p->num_frames = cmd->num_frames; if (cmd->have_input) { - fp_input = fopen(cmd->file_input, "rb"); - if (NULL == fp_input) { + p->fp_input = fopen(cmd->file_input, "rb"); + if (NULL == p->fp_input) { mpp_err("failed to open input file %s\n", cmd->file_input); mpp_err("create default yuv image for test\n"); } } if (cmd->have_output) { - fp_output = fopen(cmd->file_output, "w+b"); - if (NULL == fp_output) { + p->fp_output = fopen(cmd->file_output, "w+b"); + if (NULL == p->fp_output) { mpp_err("failed to open output file %s\n", cmd->file_output); ret = MPP_ERR_OPEN_FILE; - goto MPP_TEST_OUT; } } - ret = mpp_buffer_group_get_internal(&frm_grp, MPP_BUFFER_TYPE_ION); - if (ret) { - mpp_err("failed to get buffer group for input frame ret %d\n", ret); - goto MPP_TEST_OUT; + // update resource parameter + p->frame_size = p->hor_stride * p->ver_stride * 3 / 2; + p->packet_size = p->width * p->height; + //NOTE: hor_stride should be 16-MB aligned + p->mdinfo_size = (((p->hor_stride + 255) & (~255)) / 16) * (p->ver_stride / 16) * 4; + /* + * osd idx size range from 16x16 bytes(pixels) to hor_stride*ver_stride(bytes). + * for general use, 1/8 Y buffer is enough. + */ + p->osd_idx_size = p->hor_stride * p->ver_stride / 8; + p->plt_table[0] = MPP_ENC_OSD_PLT_WHITE; + p->plt_table[1] = MPP_ENC_OSD_PLT_YELLOW; + p->plt_table[2] = MPP_ENC_OSD_PLT_CYAN; + p->plt_table[3] = MPP_ENC_OSD_PLT_GREEN; + p->plt_table[4] = MPP_ENC_OSD_PLT_TRANS; + p->plt_table[5] = MPP_ENC_OSD_PLT_RED; + p->plt_table[6] = MPP_ENC_OSD_PLT_BLUE; + p->plt_table[7] = MPP_ENC_OSD_PLT_BLACK; + +RET: + *data = p; + return ret; +} + +MPP_RET test_ctx_deinit(MpiEncTestData **data) +{ + MpiEncTestData *p = NULL; + + if (!data) { + mpp_err_f("invalid input data %p\n", data); + return MPP_ERR_NULL_PTR; } - ret = mpp_buffer_group_get_internal(&pkt_grp, MPP_BUFFER_TYPE_ION); + p = *data; + if (p) { + if (p->fp_input) { + fclose(p->fp_input); + p->fp_input = NULL; + } + if (p->fp_output) { + fclose(p->fp_output); + p->fp_output = NULL; + } + MPP_FREE(p); + *data = NULL; + } + + return MPP_OK; +} + +MPP_RET test_res_init(MpiEncTestData *p) +{ + RK_U32 i; + MPP_RET ret; + + mpp_assert(p); + + ret = mpp_buffer_group_get_internal(&p->frm_grp, MPP_BUFFER_TYPE_ION); + if (ret) { + mpp_err("failed to get buffer group for input frame ret %d\n", ret); + goto RET; + } + + ret = mpp_buffer_group_get_internal(&p->pkt_grp, MPP_BUFFER_TYPE_ION); if (ret) { mpp_err("failed to get buffer group for output packet ret %d\n", ret); - goto MPP_TEST_OUT; + goto RET; } for (i = 0; i < MPI_ENC_IO_COUNT; i++) { - ret = mpp_buffer_get(frm_grp, &frm_buf[i], frame_size); + ret = mpp_buffer_get(p->frm_grp, &p->frm_buf[i], p->frame_size); if (ret) { mpp_err("failed to get buffer for input frame ret %d\n", ret); - goto MPP_TEST_OUT; + goto RET; } - ret = mpp_buffer_get(frm_grp, &osd_idx_buf[i], osd_idx_size); + ret = mpp_buffer_get(p->frm_grp, &p->osd_idx_buf[i], p->osd_idx_size); if (ret) { mpp_err("failed to get buffer for osd idx buf ret %d\n", ret); - goto MPP_TEST_OUT; + goto RET; } - ret = mpp_buffer_get(pkt_grp, &pkt_buf[i], packet_size); + ret = mpp_buffer_get(p->pkt_grp, &p->pkt_buf[i], p->packet_size); if (ret) { mpp_err("failed to get buffer for input frame ret %d\n", ret); - goto MPP_TEST_OUT; + goto RET; } - ret = mpp_buffer_get(pkt_grp, &md_buf[i], mdinfo_size); + ret = mpp_buffer_get(p->pkt_grp, &p->md_buf[i], p->mdinfo_size); if (ret) { mpp_err("failed to get buffer for motion detection info ret %d\n", ret); - goto MPP_TEST_OUT; + goto RET; + } + } +RET: + return ret; +} + +MPP_RET test_res_deinit(MpiEncTestData *p) +{ + RK_U32 i; + + mpp_assert(p); + + for (i = 0; i < MPI_ENC_IO_COUNT; i++) { + if (p->frm_buf[i]) { + mpp_buffer_put(p->frm_buf[i]); + p->frm_buf[i] = NULL; + } + + if (p->pkt_buf[i]) { + mpp_buffer_put(p->pkt_buf[i]); + p->pkt_buf[i] = NULL; + } + + if (p->md_buf[i]) { + mpp_buffer_put(p->md_buf[i]); + p->md_buf[i] = NULL; + } + + if (p->osd_idx_buf[i]) { + mpp_buffer_put(p->osd_idx_buf[i]); + p->osd_idx_buf[i] = NULL; } } - mpp_log("mpi_enc_test encoder test start w %d h %d type %d\n", width, height, type); - - // encoder demo - ret = mpp_create(&ctx, &mpi); - - if (MPP_OK != ret) { - mpp_err("mpp_create failed\n"); - goto MPP_TEST_OUT; + if (p->frm_grp) { + mpp_buffer_group_put(p->frm_grp); + p->frm_grp = NULL; } - ret = mpp_init(ctx, MPP_CTX_ENC, type); - if (MPP_OK != ret) { - mpp_err("mpp_init failed\n"); - goto MPP_TEST_OUT; + if (p->pkt_grp) { + mpp_buffer_group_put(p->pkt_grp); + p->pkt_grp = NULL; } - memset(&mpp_cfg, 0, sizeof(mpp_cfg)); - mpp_cfg.size = sizeof(mpp_cfg); - mpp_cfg.width = width; - mpp_cfg.height = height; - mpp_cfg.hor_stride = hor_stride; - mpp_cfg.ver_stride = ver_stride; - mpp_cfg.format = fmt; - mpp_cfg.rc_mode = 0; - mpp_cfg.skip_cnt = 0; - mpp_cfg.fps_in = 30; - mpp_cfg.fps_out = 30; - mpp_cfg.bps = width * height * 2 * mpp_cfg.fps_in; - mpp_cfg.qp = (type == MPP_VIDEO_CodingMJPEG) ? (10) : (24); - mpp_cfg.gop = 60; + return MPP_OK; +} - mpp_cfg.profile = 100; - mpp_cfg.level = 41; - mpp_cfg.cabac_en = 1; +MPP_RET test_mpp_init(MpiEncTestData *p) +{ + MPP_RET ret; - ret = mpi->control(ctx, MPP_ENC_SET_SEI_CFG, &sei_mode); - if (MPP_OK != ret) { - mpp_err("mpi control enc set sei cfg failed\n"); - goto MPP_TEST_OUT; + if (NULL == p) + return MPP_ERR_NULL_PTR; + + ret = mpp_create(&p->ctx, &p->mpi); + if (ret) { + mpp_err("mpp_create failed ret %d\n", ret); + goto RET; } - ret = mpi->control(ctx, MPP_ENC_SET_CFG, &mpp_cfg); - if (MPP_OK != ret) { - mpp_err("mpi control enc set cfg failed\n"); - goto MPP_TEST_OUT; + ret = mpp_init(p->ctx, MPP_CTX_ENC, p->type); + if (ret) + mpp_err("mpp_init failed ret %d\n", ret); + +RET: + return ret; +} + +MPP_RET test_mpp_setup(MpiEncTestData *p) +{ + MPP_RET ret; + MppApi *mpi; + MppCtx ctx; + MppEncCodecCfg *codec_cfg; + MppEncPrepCfg *prep_cfg; + MppEncRcCfg *rc_cfg; + + if (NULL == p) + return MPP_ERR_NULL_PTR; + + mpi = p->mpi; + ctx = p->ctx; + codec_cfg = &p->codec_cfg; + prep_cfg = &p->prep_cfg; + rc_cfg = &p->rc_cfg; + + /* setup default parameter */ + p->fps = 30; + p->gop = 60; + p->bps = p->width * p->height / 8 * p->fps; + p->qp_init = (p->type == MPP_VIDEO_CodingMJPEG) ? (10) : (26); + + prep_cfg->change = MPP_ENC_PREP_CFG_CHANGE_INPUT | + MPP_ENC_PREP_CFG_CHANGE_FORMAT; + prep_cfg->width = p->width; + prep_cfg->height = p->height; + prep_cfg->hor_stride = p->hor_stride; + prep_cfg->ver_stride = p->ver_stride; + prep_cfg->format = p->fmt; + ret = mpi->control(ctx, MPP_ENC_SET_PREP_CFG, prep_cfg); + if (ret) { + mpp_err("mpi control enc set prep cfg failed ret %d\n", ret); + goto RET; } + rc_cfg->change = MPP_ENC_RC_CFG_CHANGE_ALL; + /* + * rc_mode - rate control mode + * Mpp balances quality and bit rate by the mode index + * Mpp provide 5 level of balance mode of quality and bit rate + * 1 - only quality mode: only quality parameter takes effect + * 2 - more quality mode: quality parameter takes more effect + * 3 - balance mode : balance quality and bitrate 50 to 50 + * 4 - more bitrate mode: bitrate parameter takes more effect + * 5 - only bitrate mode: only bitrate parameter takes effect + */ + rc_cfg->rc_mode = 1; + /* + * quality - quality parameter + * mpp does not give the direct parameter in different protocol. + * mpp provide total 5 quality level 1 ~ 5 + * 0 - auto + * 1 - worst + * 2 - worse + * 3 - medium + * 4 - better + * 5 - best + */ + rc_cfg->quality = 0; + + if (rc_cfg->rc_mode == 1) { + /* constant QP does not have bps */ + rc_cfg->bps_target = -1; + rc_cfg->bps_max = -1; + rc_cfg->bps_min = -1; + } else if (rc_cfg->rc_mode == 5) { + /* constant bitrate has very small bps range of 1/16 bps */ + rc_cfg->bps_target = p->bps; + rc_cfg->bps_max = p->bps * 17 / 16; + rc_cfg->bps_min = p->bps * 15 / 16; + } else if (rc_cfg->rc_mode == 3) { + /* variable bitrate has large bps range */ + rc_cfg->bps_target = p->bps; + rc_cfg->bps_max = p->bps * 17 / 16; + rc_cfg->bps_min = p->bps * 1 / 16; + } + + /* fix input / output frame rate */ + rc_cfg->fps_in_flex = 0; + rc_cfg->fps_in_num = p->fps; + rc_cfg->fps_in_denorm = 1; + rc_cfg->fps_out_flex = 0; + rc_cfg->fps_out_num = p->fps; + rc_cfg->fps_out_denorm = 1; + + rc_cfg->gop = p->gop; + rc_cfg->skip_cnt = 0; + + mpp_log("mpi_enc_test bps %d fps %d gop %d\n", + rc_cfg->bps_target, rc_cfg->fps_out_num, rc_cfg->gop); + ret = mpi->control(ctx, MPP_ENC_SET_RC_CFG, rc_cfg); + if (ret) { + mpp_err("mpi control enc set rc cfg failed ret %d\n", ret); + goto RET; + } + + codec_cfg->coding = p->type; + switch (codec_cfg->coding) { + case MPP_VIDEO_CodingAVC : { + codec_cfg->h264.change = MPP_ENC_H264_CFG_CHANGE_PROFILE | + MPP_ENC_H264_CFG_CHANGE_ENTROPY | + MPP_ENC_H264_CFG_CHANGE_QP_LIMIT; + /* + * H.264 profile_idc parameter + * 66 - Baseline profile + * 77 - Main profile + * 100 - High profile + */ + codec_cfg->h264.profile = 100; + /* + * H.264 level_idc parameter + * 10 / 11 / 12 / 13 - qcif@15fps / cif@7.5fps / cif@15fps / cif@30fps + * 20 / 21 / 22 - cif@30fps / half-D1@@25fps / D1@12.5fps + * 30 / 31 / 32 - D1@25fps / 720p@30fps / 720p@60fps + * 40 / 41 / 42 - 1080p@30fps / 1080p@30fps / 1080p@60fps + * 50 / 51 / 52 - 4K@30fps + */ + codec_cfg->h264.level = 40; + codec_cfg->h264.entropy_coding_mode = 1; + codec_cfg->h264.cabac_init_idc = 0; + + if (rc_cfg->rc_mode == 1) { + /* constant QP mode qp is fixed */ + p->qp_max = p->qp_init; + p->qp_min = p->qp_init; + p->qp_step = 0; + } else if (rc_cfg->rc_mode == 5) { + /* constant bitrate do not limit qp range */ + p->qp_max = 48; + p->qp_min = 4; + p->qp_step = 16; + } else if (rc_cfg->rc_mode == 3) { + /* variable bitrate has qp min limit */ + p->qp_max = 40; + p->qp_min = 12; + p->qp_step = 8; + } + codec_cfg->h264.qp_max = p->qp_max; + codec_cfg->h264.qp_min = p->qp_min; + codec_cfg->h264.qp_max_step = p->qp_step; + codec_cfg->h264.qp_init = p->qp_init; + } break; + case MPP_VIDEO_CodingMJPEG : { + codec_cfg->jpeg.change = MPP_ENC_JPEG_CFG_CHANGE_QP; + codec_cfg->jpeg.quant = p->qp_init; + } break; + case MPP_VIDEO_CodingVP8 : + case MPP_VIDEO_CodingHEVC : + default : { + mpp_err_f("support encoder coding type %d\n", codec_cfg->coding); + } break; + } + ret = mpi->control(ctx, MPP_ENC_SET_CODEC_CFG, codec_cfg); + if (ret) { + mpp_err("mpi control enc set codec cfg failed ret %d\n", ret); + goto RET; + } + + /* optional */ + ret = mpi->control(ctx, MPP_ENC_SET_SEI_CFG, &p->sei_mode); + if (ret) { + mpp_err("mpi control enc set sei cfg failed ret %d\n", ret); + goto RET; + } + + /* gen and cfg osd plt */ + mpi_enc_gen_osd_plt(&p->osd_plt, p->plt_table); +#if MPI_ENC_TEST_SET_OSD + ret = mpi->control(ctx, MPP_ENC_SET_OSD_PLT_CFG, &p->osd_plt); + if (ret) { + mpp_err("mpi control enc set osd plt failed ret %d\n", ret); + goto RET; + } +#endif + +RET: + return ret; +} + +/* + * write header here + */ +MPP_RET test_mpp_preprare(MpiEncTestData *p) +{ + MPP_RET ret; + MppApi *mpi; + MppCtx ctx; + MppPacket packet = NULL; + + if (NULL == p) + return MPP_ERR_NULL_PTR; + + mpi = p->mpi; + ctx = p->ctx; ret = mpi->control(ctx, MPP_ENC_GET_EXTRA_INFO, &packet); - if (MPP_OK != ret) { + if (ret) { mpp_err("mpi control enc get extra info failed\n"); - goto MPP_TEST_OUT; + goto RET; } /* get and write sps/pps for H.264 */ @@ -403,125 +704,125 @@ int mpi_enc_test(MpiEncTestCmd *cmd) void *ptr = mpp_packet_get_pos(packet); size_t len = mpp_packet_get_length(packet); - if (fp_output) - fwrite(ptr, 1, len, fp_output); + if (p->fp_output) + fwrite(ptr, 1, len, p->fp_output); packet = NULL; } +RET: + return ret; +} - ret = mpp_frame_init(&frame); - if (MPP_OK != ret) { - mpp_err("mpp_frame_init failed\n"); - goto MPP_TEST_OUT; +MPP_RET test_mpp_run(MpiEncTestData *p) +{ + MPP_RET ret; + MppApi *mpi; + MppCtx ctx; + MppPacket packet = NULL; + RK_S32 i; + + if (NULL == p) + return MPP_ERR_NULL_PTR; + + mpi = p->mpi; + ctx = p->ctx; + + ret = mpp_frame_init(&p->frame); + if (ret) { + mpp_err_f("mpp_frame_init failed\n"); + goto RET; } - mpp_frame_set_width(frame, width); - mpp_frame_set_height(frame, height); - mpp_frame_set_hor_stride(frame, hor_stride); - mpp_frame_set_ver_stride(frame, ver_stride); - - /* gen and cfg osd plt */ - mpi_enc_gen_osd_plt(&osd_plt, plt_table); -#if MPI_ENC_TEST_SET_OSD - ret = mpi->control(ctx, MPP_ENC_SET_OSD_PLT_CFG, &osd_plt); - if (MPP_OK != ret) { - mpp_err("mpi control enc set osd plt failed\n"); - goto MPP_TEST_OUT; - } -#endif + mpp_frame_set_width(p->frame, p->width); + mpp_frame_set_height(p->frame, p->height); + mpp_frame_set_hor_stride(p->frame, p->hor_stride); + mpp_frame_set_ver_stride(p->frame, p->ver_stride); + mpp_frame_set_fmt(p->frame, p->fmt); i = 0; - while (!pkt_eos) { + while (!p->pkt_eos) { MppTask task = NULL; RK_S32 index = i++; - MppBuffer frm_buf_in = frm_buf[index]; - MppBuffer pkt_buf_out = pkt_buf[index]; - MppBuffer md_info_buf = md_buf[index]; - MppBuffer osd_data_buf = osd_idx_buf[index]; + MppBuffer frm_buf_in = p->frm_buf[index]; + MppBuffer pkt_buf_out = p->pkt_buf[index]; + MppBuffer md_info_buf = p->md_buf[index]; + MppBuffer osd_data_buf = p->osd_idx_buf[index]; MppEncOSDData osd_data; void *buf = mpp_buffer_get_ptr(frm_buf_in); if (i == MPI_ENC_IO_COUNT) i = 0; - if (fp_input) { - ret = read_yuv_image(buf, &mpp_cfg, fp_input); - if (ret != MPP_OK || feof(fp_input)) { - mpp_log("found last frame. feof %d\n", feof(fp_input)); - frm_eos = 1; + if (p->fp_input) { + ret = read_yuv_image(buf, p); + if (ret != MPP_OK || feof(p->fp_input)) { + mpp_log("found last frame. feof %d\n", feof(p->fp_input)); + p->frm_eos = 1; } } else { - ret = fill_yuv_image(buf, &mpp_cfg, frame_count); + ret = fill_yuv_image(buf, p); if (ret) - goto MPP_TEST_OUT; + goto RET; } - mpp_frame_set_buffer(frame, frm_buf_in); - mpp_frame_set_eos(frame, frm_eos); + mpp_frame_set_buffer(p->frame, frm_buf_in); + mpp_frame_set_eos(p->frame, p->frm_eos); mpp_packet_init_with_buffer(&packet, pkt_buf_out); ret = mpi->poll(ctx, MPP_PORT_INPUT, MPP_POLL_BLOCK); if (ret) { mpp_err("mpp task input poll failed ret %d\n", ret); - goto MPP_TEST_OUT; + goto RET; } ret = mpi->dequeue(ctx, MPP_PORT_INPUT, &task); if (ret || NULL == task) { mpp_err("mpp task input dequeue failed ret %d task %p\n", ret, task); - goto MPP_TEST_OUT; + goto RET; } - if (task) { - MppFrame frame_out = NULL; - - mpp_task_meta_get_frame(task, KEY_INPUT_FRAME, &frame_out); - if (frame_out) - mpp_assert(frame_out == frame); - } - - mpp_task_meta_set_frame (task, KEY_INPUT_FRAME, frame); + mpp_task_meta_set_frame (task, KEY_INPUT_FRAME, p->frame); mpp_task_meta_set_packet(task, KEY_OUTPUT_PACKET, packet); mpp_task_meta_set_buffer(task, KEY_MOTION_INFO, md_info_buf); /* set idr frame */ #if MPI_ENC_TEST_SET_IDR_FRAME - if (frame_count && frame_count % (mpp_cfg.gop / 4) == 0) { + if (p->frame_count && p->frame_count % (p->gop / 4) == 0) { ret = mpi->control(ctx, MPP_ENC_SET_IDR_FRAME, NULL); if (MPP_OK != ret) { mpp_err("mpi control enc set idr frame failed\n"); - goto MPP_TEST_OUT; + goto RET; } } #endif /* gen and cfg osd plt */ - mpi_enc_gen_osd_data(&osd_data, osd_data_buf, frame_count); + mpi_enc_gen_osd_data(&osd_data, osd_data_buf, p->frame_count); #if MPI_ENC_TEST_SET_OSD ret = mpi->control(ctx, MPP_ENC_SET_OSD_DATA_CFG, &osd_data); if (MPP_OK != ret) { mpp_err("mpi control enc set osd data failed\n"); - goto MPP_TEST_OUT; + goto RET; } #endif ret = mpi->enqueue(ctx, MPP_PORT_INPUT, task); if (ret) { mpp_err("mpp task input enqueue failed\n"); - goto MPP_TEST_OUT; + goto RET; } ret = mpi->poll(ctx, MPP_PORT_OUTPUT, MPP_POLL_BLOCK); if (ret) { mpp_err("mpp task output poll failed ret %d\n", ret); - goto MPP_TEST_OUT; + goto RET; } ret = mpi->dequeue(ctx, MPP_PORT_OUTPUT, &task); if (ret || NULL == task) { mpp_err("mpp task output dequeue failed ret %d task %p\n", ret, task); - goto MPP_TEST_OUT; + goto RET; } if (task) { @@ -535,103 +836,122 @@ int mpi_enc_test(MpiEncTestCmd *cmd) void *ptr = mpp_packet_get_pos(packet); size_t len = mpp_packet_get_length(packet); - pkt_eos = mpp_packet_get_eos(packet); + p->pkt_eos = mpp_packet_get_eos(packet); - if (fp_output) - fwrite(ptr, 1, len, fp_output); + if (p->fp_output) + fwrite(ptr, 1, len, p->fp_output); mpp_packet_deinit(&packet); - mpp_log_f("encoded frame %d size %d\n", frame_count, len); - stream_size += len; + mpp_log_f("encoded frame %d size %d\n", p->frame_count, len); + p->stream_size += len; - if (pkt_eos) { + if (p->pkt_eos) { mpp_log("found last packet\n"); - mpp_assert(frm_eos); + mpp_assert(p->frm_eos); } } - frame_count++; - - ret = mpi->enqueue(ctx, MPP_PORT_OUTPUT, task); - if (ret) { - mpp_err("mpp task output enqueue failed\n"); - goto MPP_TEST_OUT; - } + p->frame_count++; } - if (num_frames && frame_count >= num_frames) { - mpp_log_f("encode max %d frames", frame_count); + ret = mpi->enqueue(ctx, MPP_PORT_OUTPUT, task); + if (ret) { + mpp_err("mpp task output enqueue failed\n"); + goto RET; + } + + if (p->num_frames && p->frame_count >= p->num_frames) { + mpp_log_f("encode max %d frames", p->frame_count); break; } - if (frm_eos && pkt_eos) + if (p->frm_eos && p->pkt_eos) break; } - ret = mpi->reset(ctx); - if (MPP_OK != ret) { +RET: + if (p->frame) { + mpp_frame_deinit(&p->frame); + p->frame = NULL; + } + + return ret; +} + +MPP_RET test_mpp_deinit(MpiEncTestData *p) +{ + if (p->ctx) { + mpp_destroy(p->ctx); + p->ctx = NULL; + } + + return MPP_OK; +} + +int mpi_enc_test(MpiEncTestCmd *cmd) +{ + MPP_RET ret = MPP_OK; + MpiEncTestData *p = NULL; + + mpp_log("mpi_enc_test start\n"); + + ret = test_ctx_init(&p, cmd); + if (ret) { + mpp_err_f("test data init failed ret %d\n", ret); + goto MPP_TEST_OUT; + } + + ret = test_res_init(p); + if (ret) { + mpp_err_f("test resource init failed ret %d\n", ret); + goto MPP_TEST_OUT; + } + + mpp_log("mpi_enc_test encoder test start w %d h %d type %d\n", + p->width, p->height, p->type); + + // encoder demo + ret = test_mpp_init(p); + if (ret) { + mpp_err_f("test mpp init failed ret %d\n", ret); + goto MPP_TEST_OUT; + } + + ret = test_mpp_setup(p); + if (ret) { + mpp_err_f("test mpp setup failed ret %d\n", ret); + goto MPP_TEST_OUT; + } + + ret = test_mpp_preprare(p); + if (ret) { + mpp_err_f("test mpp prepare failed ret %d\n", ret); + goto MPP_TEST_OUT; + } + + ret = test_mpp_run(p); + if (ret) { + mpp_err_f("test mpp run failed ret %d\n", ret); + goto MPP_TEST_OUT; + } + + ret = p->mpi->reset(p->ctx); + if (ret) { mpp_err("mpi->reset failed\n"); goto MPP_TEST_OUT; } MPP_TEST_OUT: + test_mpp_deinit(p); - if (ctx) { - mpp_destroy(ctx); - ctx = NULL; - } - - if (frame) { - mpp_frame_deinit(&frame); - frame = NULL; - } - - for (i = 0; i < MPI_ENC_IO_COUNT; i++) { - if (frm_buf[i]) { - mpp_buffer_put(frm_buf[i]); - frm_buf[i] = NULL; - } - - if (pkt_buf[i]) { - mpp_buffer_put(pkt_buf[i]); - pkt_buf[i] = NULL; - } - - if (md_buf[i]) { - mpp_buffer_put(md_buf[i]); - md_buf[i] = NULL; - } - - if (osd_idx_buf[i]) { - mpp_buffer_put(osd_idx_buf[i]); - osd_idx_buf[i] = NULL; - } - } - - if (frm_grp) { - mpp_buffer_group_put(frm_grp); - frm_grp = NULL; - } - - if (pkt_grp) { - mpp_buffer_group_put(pkt_grp); - pkt_grp = NULL; - } - - if (fp_output) { - fclose(fp_output); - fp_output = NULL; - } - - if (fp_input) { - fclose(fp_input); - fp_input = NULL; - } + test_res_deinit(p); if (MPP_OK == ret) mpp_log("mpi_enc_test success total frame %d bps %lld\n", - frame_count, (RK_U64)((stream_size * 8 * mpp_cfg.fps_out) / frame_count)); + p->frame_count, (RK_U64)((p->stream_size * 8 * p->fps) / p->frame_count)); else mpp_err("mpi_enc_test failed ret %d\n", ret); + test_ctx_deinit(&p); + return ret; } diff --git a/test/mpi_rc_test.c b/test/mpi_rc_test.c index 85614694..9a5088de 100644 --- a/test/mpi_rc_test.c +++ b/test/mpi_rc_test.c @@ -757,6 +757,39 @@ static MPP_RET mpi_rc_codec(MpiRcTestCtx *ctx) goto MPP_TEST_OUT; } + MppEncRcCfg rc_cfg; + rc_cfg.change = MPP_ENC_RC_CFG_CHANGE_ALL; + rc_cfg.rc_mode = 3; + rc_cfg.quality = 0; + rc_cfg.bps_target = 2000000; + rc_cfg.bps_max = 3000000; + rc_cfg.bps_min = 1000000; + rc_cfg.fps_in_denorm = 1; + rc_cfg.fps_out_denorm = 1; + rc_cfg.fps_in_num = 30; + rc_cfg.fps_out_denorm = 30; + rc_cfg.fps_in_flex = 0; + rc_cfg.fps_out_flex = 0; + rc_cfg.gop = 30; + rc_cfg.skip_cnt = 0; + + ret = enc_mpi->control(enc_ctx, MPP_ENC_SET_RC_CFG, &rc_cfg); + + MppEncPrepCfg prep_cfg; + prep_cfg.change = MPP_ENC_PREP_CFG_CHANGE_INPUT | + MPP_ENC_PREP_CFG_CHANGE_FORMAT; + prep_cfg.width = width; + prep_cfg.height = height; + prep_cfg.hor_stride = hor_stride; + prep_cfg.ver_stride = ver_stride; + prep_cfg.format = fmt; + + ret = enc_mpi->control(enc_ctx, MPP_ENC_SET_PREP_CFG, &prep_cfg); + if (ret) { + mpp_err("mpi control enc set prep cfg failed ret %d\n", ret); + goto MPP_TEST_OUT; + } + ret = enc_mpi->control(enc_ctx, MPP_ENC_GET_EXTRA_INFO, &packet); if (MPP_OK != ret) { mpp_err("mpi control enc get extra info failed\n");