[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 <herman.chen@rock-chips.com>
Signed-off-by: Lin Kesheng <lks@rock-chips.com>
This commit is contained in:
Herman Chen
2016-11-04 08:37:13 +08:00
parent 6b8fdecf69
commit 4c1ae218e6
70 changed files with 6480 additions and 11253 deletions

View File

@@ -138,6 +138,24 @@ typedef struct MppEncConfig_t {
RK_S32 cabac_en; RK_S32 cabac_en;
} MppEncConfig; } 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 * @ingroup rk_mpi
* @brief mpp main work function set * @brief mpp main work function set

View File

@@ -80,19 +80,25 @@ typedef enum {
MPP_DEC_CMD_END, MPP_DEC_CMD_END,
MPP_ENC_CMD_BASE = CMD_MODULE_CODEC | CMD_CTX_ID_ENC, MPP_ENC_CMD_BASE = CMD_MODULE_CODEC | CMD_CTX_ID_ENC,
MPP_ENC_SET_RC_CFG, /* legacy support for vpuapi */
MPP_ENC_GET_RC_CFG, MPP_ENC_SET_CFG,
MPP_ENC_SET_PREP_CFG, MPP_ENC_GET_CFG,
MPP_ENC_GET_PREP_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_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_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_GET_OSD_CFG,
MPP_ENC_SET_CFG,
MPP_ENC_GET_CFG,
MPP_ENC_SET_EXTRA_INFO, MPP_ENC_SET_EXTRA_INFO,
MPP_ENC_GET_EXTRA_INFO, MPP_ENC_GET_EXTRA_INFO, /* get vps / sps / pps from hal */
MPP_ENC_SET_FORMAT,
MPP_ENC_SET_IDR_FRAME,
MPP_ENC_SET_SEI_CFG, /* SEI: Supplement Enhancemant Information, parameter is MppSeiMode */ 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_SEI_DATA, /* SEI: Supplement Enhancemant Information, parameter is MppPacket */
MPP_ENC_CMD_END, MPP_ENC_CMD_END,
@@ -168,10 +174,10 @@ typedef enum {
* +----------init------------> | | * +----------init------------> | |
* | | | | * | | | |
* | | | | * | | | |
* | MppFrame | | | * | PrepCfg | | |
* +---------control----------> MppFrame | | * +---------control----------> PrepCfg | |
* | +-----control-----> | * | +-----control-----> |
* | | | MppFrame | * | | | PrepCfg |
* | +--------------------------control--------> * | +--------------------------control-------->
* | | | allocate * | | | allocate
* | | | buffer * | | | buffer
@@ -193,10 +199,6 @@ typedef enum {
* +---------control----------> | | * +---------control----------> | |
* | | | | * | | | |
* | | | | * | | | |
* | PrepCfg | | |
* +---------control----------> | PrepCfg |
* | +--------------------------control-------->
* | | | |
* | ROICfg | | | * | ROICfg | | |
* +---------control----------> | ROICfg | * +---------control----------> | ROICfg |
* | +--------------------------control--------> * | +--------------------------control-------->
@@ -240,7 +242,22 @@ typedef enum {
/* /*
* Rate control parameter * Rate control parameter
* */
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 * rc_mode - rate control mode
* Mpp balances quality and bit rate by the mode index * Mpp balances quality and bit rate by the mode index
* Mpp provide 5 level of balance mode of quality and bit rate * Mpp provide 5 level of balance mode of quality and bit rate
@@ -249,7 +266,10 @@ typedef enum {
* 3 - balance mode : balance quality and bitrate 50 to 50 * 3 - balance mode : balance quality and bitrate 50 to 50
* 4 - more bitrate mode: bitrate parameter takes more effect * 4 - more bitrate mode: bitrate parameter takes more effect
* 5 - only bitrate mode: only bitrate parameter takes effect * 5 - only bitrate mode: only bitrate parameter takes effect
* */
RK_S32 rc_mode;
/*
* quality - quality parameter * quality - quality parameter
* mpp does not give the direct parameter in different protocol. * mpp does not give the direct parameter in different protocol.
* mpp provide total 5 quality level 1 ~ 5 * mpp provide total 5 quality level 1 ~ 5
@@ -259,7 +279,10 @@ typedef enum {
* 3 - medium * 3 - medium
* 4 - better * 4 - better
* 5 - best * 5 - best
* */
RK_S32 quality;
/*
* bit rate parameters * bit rate parameters
* mpp gives three bit rate control parameter for control * mpp gives three bit rate control parameter for control
* bps_target - target bit rate, unit: bit per second * bps_target - target bit rate, unit: bit per second
@@ -267,66 +290,134 @@ typedef enum {
* bps_min - minimun 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 constant bit rate set parameters to the similar value
* if user need variable bit rate set parameters as they need * if user need variable bit rate set parameters as they need
* */
RK_S32 bps_target;
RK_S32 bps_max;
RK_S32 bps_min;
/*
* frame rate parameters have great effect on rate control * frame rate parameters have great effect on rate control
* all fps parameter is in 32bit *
* low 16bit is denominator * fps_in_flex
* high 16bit is numerator * 0 - fix input frame rate
* if high 16bit is zero then the whole integer is just fps * 1 - variable input frame rate
* fps_in - input frame rate, unit: frame per second *
* if 0 then default set to 30 * fps_in_num
* fps_out - output frame rate, unit: frame per second * input frame rate numerator, if 0 then default 30
* if 0 then default set to fps_in *
* gop - gap between Intra frame * 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 * 0 for only 1 I frame the rest are all P frames
* 1 for all I frame * 1 for all I frame
* 2 for I P I P I P * 2 for I P I P I P
* 3 for I P P I P P * 3 for I P P I P P
* etc... * etc...
*/
RK_S32 gop;
/*
* skip_cnt - max continuous frame skip count * skip_cnt - max continuous frame skip count
* 0 - frame skip is not allow * 0 - frame skip is not allow
*
*/ */
typedef struct MppEncRcCfg_t {
RK_S32 rc_mode;
RK_S32 quality;
RK_S32 bps_target;
RK_S32 bps_max;
RK_S32 bps_min;
RK_S32 fps_in;
RK_S32 fps_out;
RK_S32 gop;
RK_S32 skip_cnt; RK_S32 skip_cnt;
} MppEncRcCfg; } MppEncRcCfg;
/*
* Mpp frame parameter
* direct use MppFrame to store information
*/
/*
* Mpp codec parameter
* parameter is defined in different syntax header
*/
/* /*
* Mpp preprocess parameter * Mpp preprocess parameter
*/ */
typedef struct MppEncPrepCfg_t { typedef enum MppEncPrepCfgChange_e {
MppFrameFormat format_in; MPP_ENC_PREP_CFG_CHANGE_INPUT = (1 << 0), /* change on input config */
MppFrameFormat format_out; MPP_ENC_PREP_CFG_CHANGE_FORMAT = (1 << 2), /* change on format */
RK_U32 rotation; /* 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; * Preprocess sharpen parameter
RK_U32 src_shp_en_uv; *
RK_U32 src_shp_thr; * 5x5 sharpen core
RK_U32 src_shp_div; *
RK_U32 src_shp_w0; * enable_y - enable luma sharpen
RK_U32 src_shp_w1; * enable_c - enable chroma sharpen
RK_U32 src_shp_w2; */
RK_U32 src_shp_w3; typedef struct {
RK_U32 src_shp_w4; 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; } MppEncPrepCfg;
/* /*
@@ -419,4 +510,323 @@ typedef struct MppEncMDBlkInfo_t {
RK_S32 mvy : 8; /* bit 24~31 - signed vertical mv */ RK_S32 mvy : 8; /* bit 24~31 - signed vertical mv */
} MppEncMDBlkInfo; } 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__*/ #endif /*__RK_MPI_CMD_H__*/

View File

@@ -12,6 +12,7 @@ include_directories(common)
include_directories(base/inc) include_directories(base/inc)
include_directories(codec/inc) include_directories(codec/inc)
include_directories(hal/inc) include_directories(hal/inc)
include_directories(hal/common)
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# add mpp base component # add mpp base component

View File

@@ -10,6 +10,8 @@ add_library(mpp_codec STATIC
mpp_parser.cpp mpp_parser.cpp
) )
add_library(mpp_rc STATIC mpp_rc.cpp)
set_target_properties(mpp_codec PROPERTIES FOLDER "mpp/codec") set_target_properties(mpp_codec PROPERTIES FOLDER "mpp/codec")
add_subdirectory(dec) add_subdirectory(dec)

View File

@@ -10,42 +10,12 @@ set(H264E_COMMON
# h264 encoder header # h264 encoder header
set(H264E_HDR 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_codec.h
include/h264e_utils.h
) )
# h264 encoder sourse # h264 encoder sourse
set(H264E_SRC 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_api.c
src/h264e_utils.c
) )
@@ -56,5 +26,5 @@ add_library(${CODEC_H264E} STATIC
${H264E_SRC} ${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") set_target_properties(${CODEC_H264E} PROPERTIES FOLDER "mpp/codec")

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 */

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -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__*/

View File

@@ -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;
}

View File

@@ -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 <string.h>
#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;
}

View File

@@ -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;
}

View File

@@ -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));
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

File diff suppressed because it is too large Load Diff

View File

@@ -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");
}
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -20,116 +20,137 @@
#include "mpp_env.h" #include "mpp_env.h"
#include "mpp_log.h" #include "mpp_log.h"
#include "mpp_mem.h"
#include "mpp_common.h" #include "mpp_common.h"
#include "H264Instance.h" #include "mpp_rc.h"
#include "h264e_api.h" #include "h264e_api.h"
#include "h264e_codec.h" #include "h264e_codec.h"
#include "h264e_syntax.h" #include "h264e_syntax.h"
#include "h264encapi.h"
#include "mpp_controller.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"); 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); 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"); h264e_dbg_func("leave\n");
return ret; return ret;
} }
MPP_RET h264e_deinit(void *ctx) MPP_RET h264e_deinit(void *ctx)
{ {
H264ECtx * pEncInst = (H264ECtx *)ctx; H264eCtx *p = (H264eCtx *)ctx;
H264EncRet ret/* = MPP_OK*/;
H264EncIn *encIn = &(pEncInst->encIn);
H264EncOut *encOut = &(pEncInst->encOut);
/* End stream */ h264e_dbg_func("enter\n");
ret = H264EncStrmEnd(pEncInst, encIn, encOut);
if (ret != H264ENC_OK) {
mpp_err("H264EncStrmEnd() failed, ret %d.", ret);
}
if ((ret = H264EncRelease(pEncInst)) != H264ENC_OK) { if (p->rc)
mpp_err("H264EncRelease() failed, ret %d.", ret); mpp_rc_deinit(p->rc);
return MPP_NOK;
}
h264e_dbg_func("leave\n");
return MPP_OK; return MPP_OK;
} }
MPP_RET h264e_encode(void *ctx, HalEncTask *task) MPP_RET h264e_encode(void *ctx, HalEncTask *task)
{ {
H264EncRet ret; H264eCtx *p = (H264eCtx *)ctx;
H264ECtx *p = (H264ECtx *)ctx; RcSyntax *rc_syn = &p->syntax;
H264EncIn *encIn = &(p->encIn); MppEncCfgSet *cfg = p->cfg;
H264EncOut *encOut = &(p->encOut); MppEncRcCfg *rc = &cfg->rc;
RK_U32 srcHorStride = p->preProcess.hor_stride;
RK_U32 srcVerStride = p->preProcess.ver_stride;
encIn->pOutBuf = (RK_U32*)mpp_buffer_get_ptr(task->output); if (!p->rc_ready) {
encIn->busOutBuf = mpp_buffer_get_fd(task->output); mpp_err_f("not initialize encoding\n");
encIn->outBufSize = (RK_U32)mpp_buffer_get_size(task->output); task->valid = 0;
/* 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
return MPP_NOK; 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.data = &p->syntax;
task->syntax.number = 1; task->syntax.number = 1;
task->valid = 1;
return MPP_OK; 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 h264e_config(void *ctx, RK_S32 cmd, void *param)
{ {
MPP_RET ret = MPP_NOK; MPP_RET ret = MPP_OK;
H264ECtx *enc = (H264ECtx *)ctx; // add by lance 2016.05.31 H264eCtx *p = (H264eCtx *)ctx;
h264e_dbg_func("enter ctx %p cmd %x param %p\n", ctx, cmd, param); 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 : { case CHK_ENC_CFG : {
ret = h264e_check_mpp_cfg((MppEncConfig *)param); ret = h264e_check_mpp_cfg((MppEncConfig *)param);
} break; } 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 : { case SET_IDR_FRAME : {
H264EncRateCtrl *enc_rc_cfg = &enc->enc_rc_cfg; p->idr_request++;
enc->intraPeriodCnt = enc_rc_cfg->intraPicRate; } break;
ret = MPP_OK; 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; } break;
default: default:
mpp_err("No correspond cmd found, and can not config!"); mpp_err("No correspond cmd found, and can not config!");
ret = MPP_NOK;
break; break;
} }
@@ -397,57 +301,11 @@ MPP_RET h264e_config(void *ctx, RK_S32 cmd, void *param)
MPP_RET h264e_callback(void *ctx, void *feedback) MPP_RET h264e_callback(void *ctx, void *feedback)
{ {
H264ECtx *enc = (H264ECtx *)ctx; H264eCtx *p = (H264eCtx *)ctx;
H264EncIn *encIn = &(enc->encIn);
regValues_s *val = &(enc->asic.regs);
h264e_feedback *fb = (h264e_feedback *)feedback; 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; return MPP_OK;
} }
@@ -460,7 +318,7 @@ MPP_RET h264e_callback(void *ctx, void *feedback)
const ControlApi api_h264e_controller = { const ControlApi api_h264e_controller = {
"h264e_control", "h264e_control",
MPP_VIDEO_CodingAVC, MPP_VIDEO_CodingAVC,
sizeof(H264ECtx), sizeof(H264eCtx),
0, 0,
h264e_init, h264e_init,
h264e_deinit, h264e_deinit,

View File

@@ -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;
}

View File

@@ -177,11 +177,6 @@ MPP_RET jpege_config(void *ctx, RK_S32 cmd, void *param)
mpp_cfg->format = syntax->format; mpp_cfg->format = syntax->format;
mpp_cfg->qp = syntax->quality; mpp_cfg->qp = syntax->quality;
} break; } break;
case GET_ENC_EXTRA_INFO : {
} break;
case GET_OUTPUT_STREAM_SIZE : {
*((RK_U32*)param) = p->feedback.stream_length;
} break;
default: default:
mpp_err("No correspond cmd found, and can not config!"); mpp_err("No correspond cmd found, and can not config!");
ret = MPP_NOK; ret = MPP_NOK;

View File

@@ -17,8 +17,6 @@
#ifndef __DUMMY_ENC_API_H__ #ifndef __DUMMY_ENC_API_H__
#define __DUMMY_ENC_API_H__ #define __DUMMY_ENC_API_H__
#include "mpp_enc.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif

View File

@@ -21,16 +21,11 @@
#include "mpp_buf_slot.h" #include "mpp_buf_slot.h"
#include "hal_task.h" #include "hal_task.h"
// TODO
#include "../enc/h264/include/h264encapi.h"
// config cmd // config cmd
typedef enum EncCfgCmd_t { typedef enum EncCfgCmd_t {
CHK_ENC_CFG, CHK_ENC_CFG,
SET_ENC_CFG, SET_ENC_CFG,
SET_ENC_RC_CFG, SET_ENC_RC_CFG,
GET_ENC_EXTRA_INFO,
GET_OUTPUT_STREAM_SIZE,
SET_IDR_FRAME, SET_IDR_FRAME,
} EncCfgCmd; } EncCfgCmd;
@@ -40,6 +35,8 @@ typedef enum EncCfgCmd_t {
typedef struct EncControllerInitCfg_t { typedef struct EncControllerInitCfg_t {
// input // input
MppCodingType coding; MppCodingType coding;
MppEncCfgSet *cfg;
MppEncCfgSet *set;
// output // output
RK_S32 task_count; RK_S32 task_count;

View File

@@ -21,21 +21,6 @@
typedef void* Controller; 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 #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif

View File

@@ -18,6 +18,8 @@
#define __MPP_ENC_H__ #define __MPP_ENC_H__
#include "rk_mpi.h" #include "rk_mpi.h"
#include "mpp_thread.h"
#include "mpp_controller.h" #include "mpp_controller.h"
#include "mpp_hal.h" #include "mpp_hal.h"
@@ -83,10 +85,10 @@
* +----------init------------> | | * +----------init------------> | |
* | | | | * | | | |
* | | | | * | | | |
* | MppFrame | | | * | PrepCfg | | |
* +---------control----------> MppFrame | | * +---------control----------> PrepCfg | |
* | +-----control-----> | * | +-----control-----> |
* | | | MppFrame | * | | | PrepCfg |
* | +--------------------------control--------> * | +--------------------------control-------->
* | | | allocate * | | | allocate
* | | | buffer * | | | buffer
@@ -108,10 +110,6 @@
* +---------control----------> | | * +---------control----------> | |
* | | | | * | | | |
* | | | | * | | | |
* | PrepCfg | | |
* +---------control----------> | PrepCfg |
* | +--------------------------control-------->
* | | | |
* | ROICfg | | | * | ROICfg | | |
* +---------control----------> | ROICfg | * +---------control----------> | ROICfg |
* | +--------------------------control--------> * | +--------------------------control-------->
@@ -165,12 +163,13 @@ struct MppEnc_t {
MppBufSlots packet_slots; MppBufSlots packet_slots;
HalTaskGroup tasks; HalTaskGroup tasks;
// internal status and protection
Mutex lock;
RK_U32 reset_flag; RK_U32 reset_flag;
void *mpp;
/* Encoder configure set */ /* Encoder configure set */
MppEncRcCfg rc_cfg; MppEncCfgSet cfg;
MppFrame data_cfg; MppEncCfgSet set;
/* /*
* configuration parameter to controller and hal * 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_notify(void *ctx, void *info);
MPP_RET mpp_enc_reset(MppEnc *enc); 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 #ifdef __cplusplus
} }
#endif #endif

244
mpp/codec/inc/mpp_rc.h Normal file
View File

@@ -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__ */

View File

@@ -1038,6 +1038,8 @@ MPP_RET mpp_dec_init(MppDec **dec, MppDecCfg *cfg)
frame_slots, frame_slots,
packet_slots, packet_slots,
NULL, NULL,
NULL,
NULL,
parser_cfg.task_count, parser_cfg.task_count,
cfg->fast_mode, cfg->fast_mode,
cb, cb,

View File

@@ -18,6 +18,7 @@
#include "string.h" #include "string.h"
#include "mpp_env.h"
#include "mpp_log.h" #include "mpp_log.h"
#include "mpp_mem.h" #include "mpp_mem.h"
#include "mpp_common.h" #include "mpp_common.h"
@@ -28,6 +29,17 @@
#include "mpp_packet_impl.h" #include "mpp_packet_impl.h"
#include "hal_h264e_api.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) static void reset_hal_enc_task(HalEncTask *task)
{ {
memset(task, 0, sizeof(*task)); memset(task, 0, sizeof(*task));
@@ -106,7 +118,6 @@ void *mpp_enc_control_thread(void *data)
reset_hal_enc_task(enc_task); reset_hal_enc_task(enc_task);
if (mpp_frame_get_buffer(frame)) { if (mpp_frame_get_buffer(frame)) {
RK_U32 outputStreamSize = 0;
/* /*
* if there is available buffer in the input frame do encoding * 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; MppBuffer buffer = NULL;
mpp_buffer_get(mpp->mPacketGroup, &buffer, size); 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_packet_init_with_buffer(&packet, buffer);
mpp_buffer_put(buffer); mpp_buffer_put(buffer);
} }
@@ -128,11 +138,15 @@ void *mpp_enc_control_thread(void *data)
enc_task->input = mpp_frame_get_buffer(frame); enc_task->input = mpp_frame_get_buffer(frame);
enc_task->output = mpp_packet_get_buffer(packet); enc_task->output = mpp_packet_get_buffer(packet);
enc_task->mv_info = mv_info; enc_task->mv_info = mv_info;
{
AutoMutex auto_lock(&enc->lock);
ret = controller_encode(mpp->mEnc->controller, enc_task); ret = controller_encode(mpp->mEnc->controller, enc_task);
if (ret) { if (ret) {
mpp_err("mpp %p controller_encode failed return %d", mpp, ret); mpp_err("mpp %p controller_encode failed return %d", mpp, ret);
goto TASK_END; goto TASK_END;
} }
}
ret = mpp_hal_reg_gen((mpp->mEnc->hal), &task_info); ret = mpp_hal_reg_gen((mpp->mEnc->hal), &task_info);
if (ret) { if (ret) {
mpp_err("mpp %p hal_reg_gen failed return %d", mpp, ret); mpp_err("mpp %p hal_reg_gen failed return %d", mpp, ret);
@@ -148,9 +162,8 @@ void *mpp_enc_control_thread(void *data)
mpp_err("mpp %p hal_hw_wait failed return %d", mpp, ret); mpp_err("mpp %p hal_hw_wait failed return %d", mpp, ret);
goto TASK_END; goto TASK_END;
} }
controller_config(mpp->mEnc->controller, GET_OUTPUT_STREAM_SIZE, (void*)&outputStreamSize);
TASK_END: TASK_END:
mpp_packet_set_length(packet, outputStreamSize); mpp_packet_set_length(packet, task_info.enc.length);
} else { } else {
/* /*
* else init a empty packet for output * 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; RK_S32 task_count = 2;
IOInterruptCB cb = {NULL, NULL}; IOInterruptCB cb = {NULL, NULL};
mpp_env_get_u32("mpp_enc_debug", &mpp_enc_debug, 0);
if (NULL == enc) { if (NULL == enc) {
mpp_err_f("failed to malloc context\n"); mpp_err_f("failed to malloc context\n");
return MPP_ERR_NULL_PTR; return MPP_ERR_NULL_PTR;
@@ -304,13 +319,15 @@ MPP_RET mpp_enc_init(MppEnc **enc, MppCodingType coding)
cb.callBack = mpp_enc_notify; cb.callBack = mpp_enc_notify;
cb.opaque = p; cb.opaque = p;
ControllerCfg controller_cfg = { ControllerCfg ctrl_cfg = {
coding, coding,
&p->cfg,
&p->set,
task_count, task_count,
cb, cb,
}; };
ret = controller_init(&controller, &controller_cfg); ret = controller_init(&controller, &ctrl_cfg);
if (ret) { if (ret) {
mpp_err_f("could not init controller\n"); mpp_err_f("could not init controller\n");
break; break;
@@ -325,8 +342,10 @@ MPP_RET mpp_enc_init(MppEnc **enc, MppCodingType coding)
HAL_VEPU, HAL_VEPU,
frame_slots, frame_slots,
packet_slots, packet_slots,
&p->cfg,
&p->set,
NULL, NULL,
1/*controller_cfg.task_count*/, // TODO 1/*ctrl_cfg.task_count*/, // TODO
0, 0,
cb, cb,
}; };
@@ -386,7 +405,8 @@ MPP_RET mpp_enc_deinit(MppEnc *enc)
MPP_RET mpp_enc_reset(MppEnc *enc) MPP_RET mpp_enc_reset(MppEnc *enc)
{ {
(void)enc; AutoMutex auto_lock(&enc->lock);
return MPP_OK; 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) MPP_RET mpp_enc_control(MppEnc *enc, MpiCmd cmd, void *param)
{ {
if (NULL == enc) { if (NULL == enc || NULL == param) {
mpp_err_f("found NULL input enc %p\n", enc); mpp_err_f("found NULL input enc %p cmd %x param %d\n", enc, cmd, param);
return MPP_ERR_NULL_PTR; return MPP_ERR_NULL_PTR;
} }
MPP_RET ret = MPP_NOK; MPP_RET ret = MPP_OK;
AutoMutex auto_lock(&enc->lock);
switch (cmd) { switch (cmd) {
case MPP_ENC_SET_CFG : { case MPP_ENC_SET_CFG : {
mpp_enc_dbg_ctrl("set config\n");
#if 0
MppEncConfig *mpp_cfg = &enc->mpp_cfg; MppEncConfig *mpp_cfg = &enc->mpp_cfg;
void *extra_info_cfg = NULL; 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); 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); ret = mpp_hal_control(enc->hal, MPP_ENC_SET_EXTRA_INFO, extra_info_cfg);
#endif
} break; } break;
case MPP_ENC_GET_CFG : { case MPP_ENC_GET_CFG : {
MppEncConfig *mpp_cfg = (MppEncConfig *)param; MppEncConfig *mpp_cfg = (MppEncConfig *)param;
mpp_enc_dbg_ctrl("get config\n");
mpp_assert(mpp_cfg->size == sizeof(enc->mpp_cfg)); mpp_assert(mpp_cfg->size == sizeof(enc->mpp_cfg));
*mpp_cfg = enc->mpp_cfg; *mpp_cfg = enc->mpp_cfg;
ret = MPP_OK;
} break; } 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 : { case MPP_ENC_SET_IDR_FRAME : {
mpp_enc_dbg_ctrl("idr request\n");
ret = controller_config(enc->controller, SET_IDR_FRAME, param); ret = controller_config(enc->controller, SET_IDR_FRAME, param);
} break; } break;
case MPP_ENC_GET_EXTRA_INFO : case MPP_ENC_GET_EXTRA_INFO : {
case MPP_ENC_SET_RC_CFG : mpp_enc_dbg_ctrl("get extra info\n");
case MPP_ENC_GET_RC_CFG : ret = mpp_hal_control(enc->hal, cmd, param);
case MPP_ENC_SET_OSD_PLT_CFG : } break;
case MPP_ENC_SET_OSD_DATA_CFG : case MPP_ENC_SET_OSD_PLT_CFG : {
case MPP_ENC_SET_SEI_CFG : mpp_enc_dbg_ctrl("set osd plt\n");
case MPP_ENC_GET_SEI_DATA : ret = mpp_hal_control(enc->hal, cmd, param);
case MPP_ENC_SET_PREP_CFG : { } 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); ret = mpp_hal_control(enc->hal, cmd, param);
} break; } break;
default : { default : {
mpp_log_f("unsupported cmd id %08x param %p\n", cmd, param);
ret = MPP_NOK;
} break; } break;
} }
return ret; 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;
}
}

619
mpp/codec/mpp_rc.cpp Normal file
View File

@@ -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);
}

View File

@@ -3,6 +3,7 @@
#include "rk_type.h" #include "rk_type.h"
#include "h264_syntax.h" #include "h264_syntax.h"
#include "mpp_rc.h"
#define H264_BIT_DEPTH 8 #define H264_BIT_DEPTH 8
#define H264_QP_BD_OFFSET (6*(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; RK_U32 rd_pos_y : 8;
} h264e_osd_pos; //OSD_POS0-7 } h264e_osd_pos; //OSD_POS0-7
typedef struct h264e_syntax_t { typedef enum H264eHwType_t {
RK_U32 frame_coding_type; //(VEPU)0: inter, 1: intra (RKVENC)RKVENC_FRAME_TYPE_* H264E_RKV,
RK_U32 slice_type; H264E_VPU
RK_S32 pic_init_qp; //COMB, TODO: merge with swreg59.pic_init_qp } H264eHwType;
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 * Overall configuration required by hardware
RK_S32 second_chroma_qp_index_offset; //TODO: may be removed later, get from sps/pps instead * Currently support vepu and rkvenc
RK_S32 deblocking_filter_control; //COMB */
RK_S32 disable_deblocking_filter_idc; typedef struct H264eHwCfg_t {
RK_S32 filter_disable; //TODO: merge width disable_deblocking_filter_idc above H264eHwType hw_type;
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 /* Input data parameter */
RK_S32 frame_num; //COMB TODO: swreg60.frm_num RK_S32 width;
RK_S32 slice_size_mb_rows; RK_S32 height;
RK_S32 h264_inter4x4_disabled; //COMB RK_S32 hor_stride;
RK_S32 enable_cabac; //COMB RK_S32 ver_stride;
RK_S32 transform8x8_mode; //COMB RK_S32 input_format; /* Hardware config format */
RK_S32 cabac_init_idc; //COMB TODO: merge with swreg60.cbc_init_idc 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 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 */ /* rate control relevant */
RK_S32 qp_prev;
RK_S32 qp; RK_S32 qp;
RK_S32 qp_min;
RK_S32 qp_max;
RK_S32 mad_qp_delta; RK_S32 mad_qp_delta;
RK_S32 mad_threshold; 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_distance_mbs;
RK_S32 cp_target[10]; RK_S32 cp_target[10];
RK_S32 target_error[7]; RK_S32 target_error[7];
RK_S32 delta_qp[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 */ /* RKVENC extra syntax below */
RK_S32 profile_idc; //TODO: may be removed later, get from sps/pps instead RK_S32 profile_idc;
RK_S32 level_idc; //TODO: may be removed later, get from sps/pps instead RK_S32 level_idc;
RK_S32 link_table_en; RK_S32 link_table_en;
RK_S32 keyframe_max_interval; RK_S32 keyframe_max_interval;
@@ -73,10 +110,12 @@ typedef struct h264e_syntax_t {
RK_S32 roi_en; 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 osd_mode; //0: disable osd, 1:palette type 0(congfigurable mode), 2:palette type 1(fixed mode).
RK_S32 preproc_en; RK_S32 preproc_en;
} h264e_syntax; RK_S32 coding_type; /* SliceType: P_SLICE = 0 I_SLICE = 2 */
} H264eHwCfg;
typedef struct h264e_feedback_t { typedef struct h264e_feedback_t {
/* rc */ /* rc */
RcHalResult *result;
RK_U32 hw_status; /* 0:corret, 1:error */ RK_U32 hw_status; /* 0:corret, 1:error */
RK_S32 qp_sum; RK_S32 qp_sum;
RK_S32 cp[10]; RK_S32 cp[10];

View File

@@ -1,5 +1,6 @@
# vim: syntax=cmake # vim: syntax=cmake
include_directories(worker/inc) include_directories(worker/inc)
include_directories(common)
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# add hardware hal # add hardware hal
@@ -9,6 +10,7 @@ add_subdirectory(rkdec)
add_subdirectory(rkenc) add_subdirectory(rkenc)
add_subdirectory(dummy) add_subdirectory(dummy)
add_subdirectory(rkdec/avsd) add_subdirectory(rkdec/avsd)
add_subdirectory(common)
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# add mpp_hal implement # add mpp_hal implement

View File

@@ -0,0 +1,4 @@
# vim: syntax=cmake
include_directories(.)
add_subdirectory(h264)

View File

@@ -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)

View File

@@ -27,7 +27,7 @@
#include "mpp_hal.h" #include "mpp_hal.h"
#include "mpp_env.h" #include "mpp_env.h"
#include "hal_h264e_api.h" #include "hal_h264e_api.h"
#include "hal_h264e.h" #include "hal_h264e_com.h"
#include "hal_h264e_vpu.h" #include "hal_h264e_vpu.h"
#include "hal_h264e_rkv.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; h264e_hal_context *ctx = (h264e_hal_context *)hal;
MppHalApi *api = &ctx->api; 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); mpp_env_get_u32("h264e_hal_debug", &h264e_hal_log_mode, 0x00000001);
if (!access("/dev/rkvenc", F_OK)) 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->reset = hal_h264e_vpu_reset;
api->flush = hal_h264e_vpu_flush; api->flush = hal_h264e_vpu_flush;
api->control = hal_h264e_vpu_control; api->control = hal_h264e_vpu_control;
hw_cfg->hw_type = H264E_VPU;
break; break;
case HAL_RKVENC: case HAL_RKVENC:
api->init = hal_h264e_rkv_init; 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->reset = hal_h264e_rkv_reset;
api->flush = hal_h264e_rkv_flush; api->flush = hal_h264e_rkv_flush;
api->control = hal_h264e_rkv_control; api->control = hal_h264e_rkv_control;
hw_cfg->hw_type = H264E_RKV;
break; break;
default: default:
mpp_err("invalid device_id: %d", cfg->device_id); mpp_err("invalid device_id: %d", cfg->device_id);
return MPP_NOK; 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); return api->init(hal, cfg);
} }

View File

@@ -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 <string.h>
#include <math.h>
#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;
}

View File

@@ -22,6 +22,7 @@
#include "mpp_packet.h" #include "mpp_packet.h"
#include "mpp_log.h" #include "mpp_log.h"
#include "mpp_hal.h" #include "mpp_hal.h"
#include "mpp_rc.h"
#include "h264e_syntax.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_DPB 0x00001000
#define H264E_HAL_LOG_HEADER 0x00002000 #define H264E_HAL_LOG_HEADER 0x00002000
#define H264E_HAL_LOG_SEI 0x00004000 #define H264E_HAL_LOG_SEI 0x00004000
#define H264E_HAL_LOG_PP 0x00008000
#define H264E_HAL_LOG_DETAIL 0x00010000 #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_2b (RK_U32)0x00000003
#define H264E_HAL_MASK_3b (RK_U32)0x00000007 #define H264E_HAL_MASK_3b (RK_U32)0x00000007
#define H264E_HAL_MASK_4b (RK_U32)0x0000000F #define H264E_HAL_MASK_4b (RK_U32)0x0000000F
@@ -58,61 +57,55 @@ extern RK_U32 h264e_hal_log_mode;
#define h264e_hal_debug_enter() \ #define h264e_hal_debug_enter() \
do {\ do {\
if (h264e_hal_log_mode & H264E_HAL_LOG_FLOW)\ 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) } while (0)
#define h264e_hal_debug_leave() \ #define h264e_hal_debug_leave() \
do {\ do {\
if (h264e_hal_log_mode & H264E_HAL_LOG_FLOW)\ 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) } while (0)
#define h264e_hal_log_err(fmt, ...) \ #define h264e_hal_log_err(fmt, ...) \
do {\ do {\
if (h264e_hal_log_mode & H264E_HAL_LOG_ERROR)\ if (h264e_hal_log_mode & H264E_HAL_LOG_ERROR)\
{ mpp_err_f(fmt, ## __VA_ARGS__); }\ mpp_err_f(fmt, ## __VA_ARGS__);\
} while (0) } while (0)
#define h264e_hal_log_detail(fmt, ...) \ #define h264e_hal_log_detail(fmt, ...) \
do {\ do {\
if (h264e_hal_log_mode & H264E_HAL_LOG_DETAIL)\ if (h264e_hal_log_mode & H264E_HAL_LOG_DETAIL)\
{ mpp_log(fmt, ## __VA_ARGS__); }\ mpp_log(fmt, ## __VA_ARGS__);\
} while (0) } while (0)
#define h264e_hal_log_dpb(fmt, ...) \ #define h264e_hal_log_dpb(fmt, ...) \
do {\ do {\
if (h264e_hal_log_mode & H264E_HAL_LOG_DPB)\ if (h264e_hal_log_mode & H264E_HAL_LOG_DPB)\
{ mpp_log(fmt, ## __VA_ARGS__); }\ mpp_log(fmt, ## __VA_ARGS__);\
} while (0) } while (0)
#define h264e_hal_log_header(fmt, ...) \ #define h264e_hal_log_header(fmt, ...) \
do {\ do {\
if (h264e_hal_log_mode & H264E_HAL_LOG_HEADER)\ if (h264e_hal_log_mode & H264E_HAL_LOG_HEADER)\
{ mpp_log(fmt, ## __VA_ARGS__); }\ mpp_log(fmt, ## __VA_ARGS__);\
} while (0) } while (0)
#define h264e_hal_log_sei(fmt, ...) \ #define h264e_hal_log_sei(fmt, ...) \
do {\ do {\
if (h264e_hal_log_mode & H264E_HAL_LOG_SEI)\ if (h264e_hal_log_mode & H264E_HAL_LOG_SEI)\
{ mpp_log(fmt, ## __VA_ARGS__); }\ mpp_log(fmt, ## __VA_ARGS__);\
} while (0) } while (0)
#define h264e_hal_log_simple(fmt, ...) \ #define h264e_hal_log_simple(fmt, ...) \
do {\ do {\
if (h264e_hal_log_mode & H264E_HAL_LOG_SIMPLE)\ if (h264e_hal_log_mode & H264E_HAL_LOG_SIMPLE)\
{ mpp_log(fmt, ## __VA_ARGS__); }\ mpp_log(fmt, ## __VA_ARGS__);\
} while (0) } while (0)
#define h264e_hal_log_file(fmt, ...) \ #define h264e_hal_log_file(fmt, ...) \
do {\ do {\
if (h264e_hal_log_mode & H264E_HAL_LOG_FILE)\ if (h264e_hal_log_mode & H264E_HAL_LOG_FILE)\
{ mpp_log(fmt, ## __VA_ARGS__); }\ 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) } while (0)
#define H264E_HAL_MIN(a,b) ( (a)<(b) ? (a) : (b) ) #define H264E_HAL_MIN(a,b) ( (a)<(b) ? (a) : (b) )
@@ -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_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_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 { typedef enum h264e_hal_slice_type_t {
H264E_HAL_SLICE_TYPE_P = 0, H264E_HAL_SLICE_TYPE_P = 0,
H264E_HAL_SLICE_TYPE_B = 1, H264E_HAL_SLICE_TYPE_B = 1,
@@ -201,63 +289,7 @@ typedef struct h264e_hal_sps_t {
RK_S32 i_bottom; RK_S32 i_bottom;
} crop; } crop;
RK_S32 b_vui; MppEncH264VuiCfg 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;
RK_S32 b_qpprime_y_zero_transform_bypass; RK_S32 b_qpprime_y_zero_transform_bypass;
RK_S32 i_chroma_format_idc; RK_S32 i_chroma_format_idc;
@@ -373,17 +405,16 @@ typedef struct h264e_hal_ref_param_t {
typedef struct h264e_hal_param_t { typedef struct h264e_hal_param_t {
RK_S32 hw_type; // 0:rkv, 1:vpu
RK_S32 constrained_intra; RK_S32 constrained_intra;
h264e_hal_vui_param vui; h264e_hal_vui_param vui;
h264e_hal_ref_param ref; h264e_hal_ref_param ref;
} h264e_hal_param; } h264e_hal_param;
typedef struct h264e_hal_context_t { typedef struct h264e_hal_context_t {
MppHalApi api; MppHalApi api;
VPU_CLIENT_TYPE vpu_client; RK_S32 vpu_fd;
RK_S32 vpu_socket;
IOInterruptCB int_cb; IOInterruptCB int_cb;
h264e_feedback feedback; h264e_feedback feedback;
void *regs; void *regs;
@@ -407,7 +438,25 @@ typedef struct h264e_hal_context_t {
RK_U32 osd_plt_type; //0:user define, 1:default RK_U32 osd_plt_type; //0:user define, 1:default
MppEncOSDData osd_data; MppEncOSDData osd_data;
MppEncSeiMode sei_mode; 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; } 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 #endif

View File

@@ -32,7 +32,7 @@
#include "mpp_frame.h" #include "mpp_frame.h"
#include "hal_h264e_api.h" #include "hal_h264e_api.h"
#include "hal_h264e.h" #include "hal_h264e_com.h"
#include "hal_h264e_vpu.h" #include "hal_h264e_vpu.h"
#include "hal_h264e_rkv.h" #include "hal_h264e_rkv.h"
@@ -353,10 +353,10 @@ static MPP_RET h264e_test_close_files()
return MPP_OK; 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 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_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]);; 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); 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; 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 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_U32 frame_size = frame_luma_size * 3 / 2;
mpp_assert(fp_h264e_yuv_in); 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; 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; RK_S32 k = 0;
mpp_assert(fp_golden_syntax_in); mpp_assert(fp_golden_syntax_in);
memset(syn, 0, sizeof(h264e_syntax)); memset(syn, 0, sizeof(H264eHwCfg));
if (fp_golden_syntax_in) { if (fp_golden_syntax_in) {
char temp[512] = {0}; 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); fscanf(fp_golden_syntax_in, "%d", &data);
fgets(temp, 512, fp_golden_syntax_in); fgets(temp, 512, fp_golden_syntax_in);
syn->frame_coding_type = data; syn->frame_type = data;
fscanf(fp_golden_syntax_in, "%d", &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); fscanf(fp_golden_syntax_in, "%d", &data);
fgets(temp, 512, fp_golden_syntax_in); fgets(temp, 512, fp_golden_syntax_in);
syn->h264_inter4x4_disabled = data; syn->inter4x4_disabled = data;
fscanf(fp_golden_syntax_in, "%d", &data); fscanf(fp_golden_syntax_in, "%d", &data);
fgets(temp, 512, fp_golden_syntax_in); 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); fscanf(fp_golden_syntax_in, "%d", &data);
fgets(temp, 512, fp_golden_syntax_in); fgets(temp, 512, fp_golden_syntax_in);
syn->pic_luma_width = data; syn->width = data;
fscanf(fp_golden_syntax_in, "%d", &data); fscanf(fp_golden_syntax_in, "%d", &data);
fgets(temp, 512, fp_golden_syntax_in); fgets(temp, 512, fp_golden_syntax_in);
syn->pic_luma_height = data; syn->height = data;
fscanf(fp_golden_syntax_in, "%d", &data); fscanf(fp_golden_syntax_in, "%d", &data);
fgets(temp, 512, fp_golden_syntax_in); fgets(temp, 512, fp_golden_syntax_in);
syn->input_image_format = data; syn->input_format = data;
fscanf(fp_golden_syntax_in, "%d", &data); fscanf(fp_golden_syntax_in, "%d", &data);
fgets(temp, 512, fp_golden_syntax_in); 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); syn->output_strm_addr = mpp_buffer_get_fd(hw_output_strm_buf);
/* adjust */ /* 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; return MPP_OK;
} }
#if 0 static MPP_RET get_rkv_syntax_in( H264eHwCfg *syn, MppBuffer *hw_in_buf, MppBuffer *hw_output_strm_buf, h264e_hal_test_cfg *cfg)
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)
{ {
h264e_hal_rkv_csp_info csp_info; h264e_hal_rkv_csp_info csp_info;
RK_U32 buf_idx = g_frame_read_cnt % RKV_H264E_LINKTABLE_FRAME_NUM; RK_U32 buf_idx = g_frame_read_cnt % RKV_H264E_LINKTABLE_FRAME_NUM;
h264e_hal_debug_enter(); h264e_hal_debug_enter();
//mpp_assert(fp_golden_syntax_in); //mpp_assert(fp_golden_syntax_in);
memset(syn, 0, sizeof(h264e_syntax)); memset(syn, 0, sizeof(H264eHwCfg));
if (hw_in_buf[buf_idx]) { if (hw_in_buf[buf_idx]) {
syn->input_luma_addr = mpp_buffer_get_fd(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 #if RKV_H264E_SDK_TEST
mpp_log("make syntax begin"); mpp_log("make syntax begin");
syn->pic_luma_width = cfg->pic_width; syn->width = cfg->pic_width;
syn->pic_luma_height = cfg->pic_height; syn->height = cfg->pic_height;
syn->level_idc = H264_LEVEL_4_1; syn->level_idc = H264_LEVEL_4_1;
syn->profile_idc = H264_PROFILE_HIGH; syn->profile_idc = H264_PROFILE_HIGH;
mpp_log("syn->level_idc %d", syn->level_idc); mpp_log("syn->level_idc %d", syn->level_idc);
mpp_log("syn->profile_idc %d", syn->profile_idc); mpp_log("syn->profile_idc %d", syn->profile_idc);
syn->keyframe_max_interval = 30; syn->keyframe_max_interval = 30;
if (g_frame_cnt == 0 || g_frame_cnt % syn->keyframe_max_interval == 0) { if (g_frame_cnt == 0 || g_frame_cnt % syn->keyframe_max_interval == 0) {
syn->frame_coding_type = 1; //intra syn->frame_type = 1; //intra
syn->slice_type = 2;
} else { } else {
syn->frame_coding_type = 0; //inter syn->frame_type = 0; //inter
syn->slice_type = 0;
} }
syn->qp = 26; syn->qp = 26;
csp_info.fmt = H264E_RKV_CSP_YUV420P; csp_info.fmt = H264E_RKV_CSP_YUV420P;
csp_info.cswap = 0; //TODO: csp_info.cswap = 0; //TODO:
csp_info.aswap = 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->enable_cabac = 1;
syn->pic_init_qp = 26; 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)) if (!fgets(temp, 512, fp))
return MPP_EOS_STREAM_REACHED; return MPP_EOS_STREAM_REACHED;
H264E_HAL_FSCAN(fp, "%d\n", syn->pic_luma_width); H264E_HAL_FSCAN(fp, "%d\n", syn->width);
H264E_HAL_FSCAN(fp, "%d\n", syn->pic_luma_height); H264E_HAL_FSCAN(fp, "%d\n", syn->height);
H264E_HAL_FSCAN(fp, "%d\n", syn->level_idc); 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->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->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->enable_cabac);
H264E_HAL_FSCAN(fp, "%d\n", syn->pic_init_qp); 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); fgets(temp, 512, fp);
/* adjust */ /* adjust */
csp_info.fmt = syn->input_image_format; csp_info.fmt = syn->input_format;
csp_info.cswap = 0; //TODO: csp_info.cswap = 0; //TODO:
csp_info.aswap = 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 { } else {
mpp_err("rkv_syntax_in.txt doesn't exits"); mpp_err("rkv_syntax_in.txt doesn't exits");
} }
#endif #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(); h264e_hal_debug_leave();
return MPP_OK; return MPP_OK;
@@ -1335,16 +806,16 @@ MPP_RET h264_hal_test_call_back(void *control, void *feedback)
return MPP_OK; 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->chroma_qp_index_offset = syn->chroma_qp_index_offset;
info->enable_cabac = syn->enable_cabac; info->enable_cabac = syn->enable_cabac;
info->pic_init_qp = syn->pic_init_qp; info->pic_init_qp = syn->pic_init_qp;
info->pic_luma_height = syn->pic_luma_height; info->pic_luma_height = syn->height;
info->pic_luma_width = syn->pic_luma_width; info->pic_luma_width = syn->width;
info->transform8x8_mode = syn->transform8x8_mode; 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->profile_idc = syn->profile_idc;
info->level_idc = syn->level_idc; info->level_idc = syn->level_idc;
info->keyframe_max_interval = syn->keyframe_max_interval; info->keyframe_max_interval = syn->keyframe_max_interval;
@@ -1360,7 +831,7 @@ MPP_RET h264e_hal_vpu_test()
h264e_hal_context ctx; h264e_hal_context ctx;
MppHalCfg hal_cfg; MppHalCfg hal_cfg;
HalTaskInfo task_info; HalTaskInfo task_info;
h264e_syntax syntax_data; H264eHwCfg syntax_data;
h264e_control_extra_info_cfg extra_info_cfg; h264e_control_extra_info_cfg extra_info_cfg;
MppPacket extra_info_pkt; MppPacket extra_info_pkt;
RK_U8 extra_info_buf[H264E_EXTRA_INFO_BUF_SIZE] = {0}; 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) if (fp_golden_syntax_in)
fseek(fp_golden_syntax_in, 0L, SEEK_SET); 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); 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; h264e_control_extra_info_cfg extra_info_cfg;
MppPacket extra_info_pkt; MppPacket extra_info_pkt;
RK_U8 extra_info_buf[H264E_EXTRA_INFO_BUF_SIZE] = {0}; 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_input_buf_grp = NULL;
MppBufferGroup hw_output_buf_grp = NULL; MppBufferGroup hw_output_buf_grp = NULL;
MppBuffer hw_input_buf_mul[RKV_H264E_LINKTABLE_FRAME_NUM] = {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); 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); 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++) 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; 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 { do {
/* get golden input */ /* get golden input */
if (g_frame_read_cnt <= g_frame_cnt) { 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; RK_S32 frame_num = RKV_H264E_ENC_MODE == 1 ? 1 : RKV_H264E_LINKTABLE_FRAME_NUM;
mpp_log("read %d frames input", frame_num); mpp_log("read %d frames input", frame_num);
for (k = 0; k < frame_num; k++, g_frame_read_cnt++) { for (k = 0; k < frame_num; k++, g_frame_read_cnt++) {

View File

@@ -143,6 +143,7 @@ typedef struct HalEncTask_t {
// current tesk output stream buffer // current tesk output stream buffer
MppBuffer output; MppBuffer output;
RK_U32 length;
// current tesk input slot buffer // current tesk input slot buffer
MppBuffer input; MppBuffer input;

View File

@@ -47,6 +47,9 @@ typedef struct MppHalCfg_t {
HalDeviceId device_id; HalDeviceId device_id;
MppBufSlots frame_slots; MppBufSlots frame_slots;
MppBufSlots packet_slots; MppBufSlots packet_slots;
// for encoder
MppEncCfgSet *cfg; /* encoder runtime config */
MppEncCfgSet *set; /* encoder input config */
// output // output
HalTaskGroup tasks; HalTaskGroup tasks;

View File

@@ -118,9 +118,14 @@ MPP_RET mpp_hal_init(MppHal *ctx, MppHalCfg *cfg)
p->api = hw_apis[i]; p->api = hw_apis[i];
p->task_count = cfg->task_count; p->task_count = cfg->task_count;
p->ctx = mpp_calloc_size(void, p->api->ctx_size); 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) { if (ret) {
mpp_err_f("hal_task_group_init failed ret %d\n", ret); mpp_err_f("hal_task_group_init failed ret %d\n", ret);
break; break;

View File

@@ -1,38 +1,21 @@
# vim: syntax=cmake # vim: syntax=cmake
include_directories(.) 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 # hal h264 header
set(HAL_H264E_HDR set(HAL_H264E_HDR
hal_h264e.h
hal_h264e_vpu.h
hal_h264e_rkv.h hal_h264e_rkv.h
) )
# hal h264 encoder sourse # hal h264 encoder sourse
set(HAL_H264E_SRC set(HAL_H264E_SRC
hal_h264e_api.c
hal_h264e_vpu.c
hal_h264e_rkv.c hal_h264e_rkv.c
) )
add_library(hal_h264e STATIC add_library(hal_h264e_rkv STATIC
${HAL_H264E_API}
${HAL_H264E_HDR} ${HAL_H264E_HDR}
${HAL_H264E_SRC} ${HAL_H264E_SRC}
) )
if(RKPLATFORM)
target_link_libraries(hal_h264e worker_vpu mpp_base)
else()
target_link_libraries(hal_h264e mpp_base)
endif()
set_target_properties(hal_h264e PROPERTIES FOLDER "mpp/hal") target_link_libraries(hal_h264e_rkv hal_h264e)
set_target_properties(hal_h264e_rkv PROPERTIES FOLDER "mpp/hal")
add_subdirectory(test)

File diff suppressed because it is too large Load Diff

View File

@@ -39,41 +39,12 @@ enc_mode
#define RKV_H264E_LINKTABLE_EACH_NUM 1 #define RKV_H264E_LINKTABLE_EACH_NUM 1
#endif #endif
#define RKV_H264E_NUM_REFS 1
#define RKV_H264E_LONGTERM_REF_EN 0
//------------------------------------------------------------------------------- //-------------------------------------------------------------------------------
#define RKV_H264E_LINKTABLE_MAX_SIZE 256 #define RKV_H264E_LINKTABLE_MAX_SIZE 256
#define RKV_H264E_ADD_RESERVE_REGS 1 #define RKV_H264E_ADD_RESERVE_REGS 1
#define RKV_H264E_REMOVE_UNNECESSARY_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_ONE_FRAME_FINISH 0x00000001
#define RKV_H264E_INT_LINKTABLE_FINISH 0x00000002 #define RKV_H264E_INT_LINKTABLE_FINISH 0x00000002
#define RKV_H264E_INT_SAFE_CLEAR_FINISH 0x00000004 #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; } h264e_hal_rkv_coveragetest_cfg;
#endif #endif
typedef enum H264eRkvFrameType_t {
typedef enum h264e_rkv_csp_t { H264E_RKV_FRAME_P = 0,
H264E_RKV_CSP_BGRA8888, // 0 H264E_RKV_FRAME_B = 1,
H264E_RKV_CSP_BGR888, // 1 H264E_RKV_FRAME_I = 2
H264E_RKV_CSP_BGR565, // 2 } H264eRkvFrameType;
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 h264e_hal_rkv_buf_grp_t { typedef enum h264e_hal_rkv_buf_grp_t {
H264E_HAL_RKV_BUF_GRP_PP, 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_dsp_buf[2]; //down scale picture
MppBuffer hw_mei_buf[RKV_H264E_LINKTABLE_FRAME_NUM]; MppBuffer hw_mei_buf[RKV_H264E_LINKTABLE_FRAME_NUM];
MppBuffer hw_roi_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; } h264e_hal_rkv_buffers;
typedef struct h264e_hal_rkv_nal_t { 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; RK_S32 i_long_term_reference_flag;
} h264e_hal_rkv_dpb_ctx; } 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 */ /* cmodel version r2893 */
typedef struct h264e_osd_cfg_t { typedef struct h264e_osd_cfg_t {

File diff suppressed because it is too large Load Diff

View File

@@ -23,3 +23,7 @@ endif()
if( HAVE_JPEGE ) if( HAVE_JPEGE )
add_subdirectory(jpege) add_subdirectory(jpege)
endif() endif()
if( HAVE_H264E )
add_subdirectory(h264e)
endif()

View File

@@ -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")

File diff suppressed because it is too large Load Diff

View File

@@ -609,6 +609,11 @@
#define VEPU_H264E_NUM_REGS 184 #define VEPU_H264E_NUM_REGS 184
#define H264E_CABAC_TABLE_BUF_SIZE (52*2*464) #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 { typedef struct h264e_hal_vpu_dump_files_t {
FILE *fp_mpp_syntax_in; FILE *fp_mpp_syntax_in;
FILE *fp_mpp_reg_in; FILE *fp_mpp_reg_in;
@@ -617,33 +622,6 @@ typedef struct h264e_hal_vpu_dump_files_t {
FILE *fp_mpp_feedback; FILE *fp_mpp_feedback;
} h264e_hal_vpu_dump_files; } 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 */ /* struct for assemble bitstream */
typedef struct h264e_hal_vpu_stream_t { typedef struct h264e_hal_vpu_stream_t {
RK_U8 *buffer; /* point to first byte of stream */ 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_sei sei;
} h264e_hal_vpu_extra_info; } 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 { typedef struct h264e_vpu_reg_set_t {
RK_U32 val[VEPU_H264E_NUM_REGS]; RK_U32 val[VEPU_H264E_NUM_REGS];
} h264e_vpu_reg_set; } h264e_vpu_reg_set;

View File

@@ -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

View File

@@ -423,6 +423,7 @@ MPP_RET hal_jpege_wait(void *hal, HalTaskInfo *task)
feedback.hw_status = val & 0x70; feedback.hw_status = val & 0x70;
val = regs[53]; val = regs[53];
feedback.stream_length = jpege_bits_get_bitpos(bits) / 8 + val / 8; 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", hal_jpege_dbg_output("stream length: sw %d hw %d total %d\n",
jpege_bits_get_bitpos(bits) / 8, val / 8, feedback.stream_length); jpege_bits_get_bitpos(bits) / 8, val / 8, feedback.stream_length);

View File

@@ -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); 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); mpi->control(mpp_ctx, MPP_ENC_GET_EXTRA_INFO, &pkt);
if (pkt) { if (pkt) {

View File

@@ -21,6 +21,8 @@
#define MPP_TAG_SIZE 32 #define MPP_TAG_SIZE 32
#define MPP_ABS(x) ((x) < (0) ? -(x) : (x))
#define MPP_MAX(a, b) ((a) > (b) ? (a) : (b)) #define MPP_MAX(a, b) ((a) > (b) ? (a) : (b))
#define MPP_MAX3(a, b, c) MPP_MAX(MPP_MAX(a,b),c) #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))) #define MPP_MAX4(a, b, c, d) MPP_MAX((a), MPP_MAX3((b), (c), (d)))

File diff suppressed because it is too large Load Diff

View File

@@ -757,6 +757,39 @@ static MPP_RET mpi_rc_codec(MpiRcTestCtx *ctx)
goto MPP_TEST_OUT; 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); ret = enc_mpi->control(enc_ctx, MPP_ENC_GET_EXTRA_INFO, &packet);
if (MPP_OK != ret) { if (MPP_OK != ret) {
mpp_err("mpi control enc get extra info failed\n"); mpp_err("mpi control enc get extra info failed\n");