From 4c1ae218e600b945d124c71ea55f6b168367c8bc Mon Sep 17 00:00:00 2001 From: Herman Chen Date: Fri, 4 Nov 2016 08:37:13 +0800 Subject: [PATCH] [mpi/mpp/enc]: New encoder framework 1. Interface change: Separate normal config into three basic config and several runtime config: Three basic config - a. rate control config b. preprocess config c. video codec protocol config More flexible rate control interfaces are provided. More codec configure interfaces are provided. Change flag with bitmap is provided for further optimization. 2. Remove old codec config from controller and left rate control module only Encoder controller only handle user rate control requirement and bit allocation. Hal hardware encoder only handle qp calculation according given target bit. Remove all old codec code. 3. Move codec process to hal Different hardware will share same codec process function in common protocol directory. And different hardware api will register to same api set. Codec header generation is moved to separate hal directory. 4. Encoder will return length by task Encoder will NOT get stream information feedback from controller. All information required by encoder will be all stored in Task. 5. Add mpp_rc for rate control Move some common rate control utils to mpp_base. 6. Update mpi_enc_test and mpi_rc_test with new interface Change-Id: Iebb5e276a48f547167e1bed4673f21cc2f0c8ad5 Signed-off-by: Herman Chen Signed-off-by: Lin Kesheng --- inc/rk_mpi.h | 18 + inc/rk_mpi_cmd.h | 590 ++++- mpp/CMakeLists.txt | 1 + mpp/codec/CMakeLists.txt | 2 + mpp/codec/enc/h264/CMakeLists.txt | 32 +- mpp/codec/enc/h264/include/H264CodeFrame.h | 50 - mpp/codec/enc/h264/include/H264Init.h | 28 - mpp/codec/enc/h264/include/H264Instance.h | 38 - mpp/codec/enc/h264/include/H264Mad.h | 47 - mpp/codec/enc/h264/include/H264NalUnit.h | 41 - .../h264/include/H264PictureParameterSet.h | 59 - mpp/codec/enc/h264/include/H264PutBits.h | 45 - mpp/codec/enc/h264/include/H264RateControl.h | 151 -- mpp/codec/enc/h264/include/H264Sei.h | 71 - .../h264/include/H264SequenceParameterSet.h | 114 - mpp/codec/enc/h264/include/H264Slice.h | 64 - .../enc/h264/include/encasiccontroller.h | 123 - mpp/codec/enc/h264/include/enccommon.h | 78 - mpp/codec/enc/h264/include/encpreprocess.h | 67 - mpp/codec/enc/h264/include/h264e_utils.h | 19 - mpp/codec/enc/h264/include/h264encapi.h | 364 --- mpp/codec/enc/h264/src/H264CodeFrame.c | 74 - mpp/codec/enc/h264/src/H264EncApi.c | 966 ------- mpp/codec/enc/h264/src/H264Init.c | 314 --- mpp/codec/enc/h264/src/H264Mad.c | 197 -- mpp/codec/enc/h264/src/H264NalUnit.c | 110 - .../enc/h264/src/H264PictureParameterSet.c | 135 - mpp/codec/enc/h264/src/H264PutBits.c | 279 -- mpp/codec/enc/h264/src/H264RateControl.c | 1250 --------- mpp/codec/enc/h264/src/H264Sei.c | 336 --- .../enc/h264/src/H264SequenceParameterSet.c | 721 ----- mpp/codec/enc/h264/src/H264Slice.c | 56 - mpp/codec/enc/h264/src/encpreprocess.c | 304 --- mpp/codec/enc/h264/src/h264e_api.c | 358 +-- mpp/codec/enc/h264/src/h264e_utils.c | 24 - mpp/codec/enc/jpeg/jpege_api.c | 5 - mpp/codec/inc/dummy_enc_api.h | 2 - mpp/codec/inc/encoder_codec_api.h | 7 +- mpp/codec/inc/mpp_controller.h | 15 - mpp/codec/inc/mpp_enc.h | 28 +- mpp/codec/inc/mpp_rc.h | 244 ++ mpp/codec/mpp_dec.cpp | 2 + mpp/codec/mpp_enc.cpp | 211 +- mpp/codec/mpp_rc.cpp | 619 +++++ mpp/common/h264e_syntax.h | 121 +- mpp/hal/CMakeLists.txt | 2 + mpp/hal/common/CMakeLists.txt | 4 + mpp/hal/common/h264/CMakeLists.txt | 25 + .../h264e => common/h264}/hal_h264e_api.c | 54 +- mpp/hal/common/h264/hal_h264e_com.c | 738 ++++++ .../h264/hal_h264e_com.h} | 251 +- .../h264e => common/h264}/test/CMakeLists.txt | 0 .../h264}/test/h264e_hal_test.c | 603 +---- mpp/hal/inc/hal_task.h | 1 + mpp/hal/inc/mpp_hal.h | 3 + mpp/hal/mpp_hal.cpp | 9 +- mpp/hal/rkenc/h264e/CMakeLists.txt | 43 +- mpp/hal/rkenc/h264e/hal_h264e_rkv.c | 1233 ++++----- mpp/hal/rkenc/h264e/hal_h264e_rkv.h | 609 +---- mpp/hal/rkenc/h264e/hal_h264e_vpu.c | 2308 ----------------- mpp/hal/vpu/CMakeLists.txt | 4 + mpp/hal/vpu/h264e/CMakeLists.txt | 21 + mpp/hal/vpu/h264e/hal_h264e_vpu.c | 1738 +++++++++++++ mpp/hal/{rkenc => vpu}/h264e/hal_h264e_vpu.h | 47 +- mpp/hal/vpu/h264e/hal_h264e_vpu_tbl.h | 719 +++++ mpp/hal/vpu/jpege/hal_jpege_api.c | 1 + mpp/legacy/vpu_api_legacy.cpp | 91 + osal/inc/mpp_common.h | 2 + test/mpi_enc_test.c | 814 ++++-- test/mpi_rc_test.c | 33 + 70 files changed, 6480 insertions(+), 11253 deletions(-) delete mode 100644 mpp/codec/enc/h264/include/H264CodeFrame.h delete mode 100644 mpp/codec/enc/h264/include/H264Init.h delete mode 100644 mpp/codec/enc/h264/include/H264Instance.h delete mode 100644 mpp/codec/enc/h264/include/H264Mad.h delete mode 100644 mpp/codec/enc/h264/include/H264NalUnit.h delete mode 100644 mpp/codec/enc/h264/include/H264PictureParameterSet.h delete mode 100644 mpp/codec/enc/h264/include/H264PutBits.h delete mode 100644 mpp/codec/enc/h264/include/H264RateControl.h delete mode 100644 mpp/codec/enc/h264/include/H264Sei.h delete mode 100644 mpp/codec/enc/h264/include/H264SequenceParameterSet.h delete mode 100644 mpp/codec/enc/h264/include/H264Slice.h delete mode 100644 mpp/codec/enc/h264/include/encasiccontroller.h delete mode 100644 mpp/codec/enc/h264/include/enccommon.h delete mode 100644 mpp/codec/enc/h264/include/encpreprocess.h delete mode 100644 mpp/codec/enc/h264/include/h264e_utils.h delete mode 100644 mpp/codec/enc/h264/include/h264encapi.h delete mode 100644 mpp/codec/enc/h264/src/H264CodeFrame.c delete mode 100644 mpp/codec/enc/h264/src/H264EncApi.c delete mode 100644 mpp/codec/enc/h264/src/H264Init.c delete mode 100644 mpp/codec/enc/h264/src/H264Mad.c delete mode 100644 mpp/codec/enc/h264/src/H264NalUnit.c delete mode 100644 mpp/codec/enc/h264/src/H264PictureParameterSet.c delete mode 100644 mpp/codec/enc/h264/src/H264PutBits.c delete mode 100644 mpp/codec/enc/h264/src/H264RateControl.c delete mode 100644 mpp/codec/enc/h264/src/H264Sei.c delete mode 100644 mpp/codec/enc/h264/src/H264SequenceParameterSet.c delete mode 100644 mpp/codec/enc/h264/src/H264Slice.c delete mode 100644 mpp/codec/enc/h264/src/encpreprocess.c delete mode 100644 mpp/codec/enc/h264/src/h264e_utils.c create mode 100644 mpp/codec/inc/mpp_rc.h create mode 100644 mpp/codec/mpp_rc.cpp create mode 100644 mpp/hal/common/CMakeLists.txt create mode 100644 mpp/hal/common/h264/CMakeLists.txt rename mpp/hal/{rkenc/h264e => common/h264}/hal_h264e_api.c (71%) create mode 100644 mpp/hal/common/h264/hal_h264e_com.c rename mpp/hal/{rkenc/h264e/hal_h264e.h => common/h264/hal_h264e_com.h} (63%) rename mpp/hal/{rkenc/h264e => common/h264}/test/CMakeLists.txt (100%) rename mpp/hal/{rkenc/h264e => common/h264}/test/h264e_hal_test.c (51%) delete mode 100644 mpp/hal/rkenc/h264e/hal_h264e_vpu.c create mode 100644 mpp/hal/vpu/h264e/CMakeLists.txt create mode 100644 mpp/hal/vpu/h264e/hal_h264e_vpu.c rename mpp/hal/{rkenc => vpu}/h264e/hal_h264e_vpu.h (96%) create mode 100644 mpp/hal/vpu/h264e/hal_h264e_vpu_tbl.h 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");