/*
|
* Copyright 2017 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_VEPU_V2_H__
|
#define __HAL_H264E_VEPU_V2_H__
|
|
#include "mpp_enc_cfg.h"
|
#include "mpp_rc.h"
|
#include "vepu_common.h"
|
|
#define H264E_HAL_SET_REG(reg, addr, val) \
|
do { \
|
reg[(addr)>>2] = (RK_U32)(val); \
|
if (hal_h264e_debug & 0/*H264E_HAL_LOG_INFO*/) \
|
mpp_log("line(%d) set reg[%03d/%03x]: %08x", __LINE__, (addr)>>2, addr, val); \
|
} while (0)
|
|
typedef enum H264eVpuFrameType_t {
|
H264E_VPU_FRAME_P = 0,
|
H264E_VPU_FRAME_I = 1
|
} H264eVpuFrameType;
|
|
#define VEPU_CTRL_LEVELS 7
|
#define VEPU_CHECK_POINTS_MAX 10
|
|
typedef struct HalH264eVepuInput_t {
|
/* Hardware config format */
|
RK_S32 src_fmt;
|
RK_S32 src_w;
|
RK_S32 src_h;
|
|
VepuStrideCfg stride_cfg;
|
RK_S32 pixel_stride;
|
|
size_t size_y;
|
size_t size_c;
|
|
RK_U32 offset_cb;
|
RK_U32 offset_cr;
|
|
RK_U8 r_mask_msb;
|
RK_U8 g_mask_msb;
|
RK_U8 b_mask_msb;
|
RK_U8 swap_8_in;
|
RK_U8 swap_16_in;
|
RK_U8 swap_32_in;
|
|
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;
|
} HalH264eVepuPrep;
|
|
typedef struct HalH264eVepuFrmAddr_t {
|
// original frame Y/Cb/Cr/RGB address
|
RK_U32 orig[3];
|
// reconstruction frame
|
RK_U32 recn[2];
|
RK_U32 refr[2];
|
} HalH264eVepuAddr;
|
|
/*
|
* Vepu buffer allocater
|
* There are three internal buffer for Vepu encoder:
|
* 1. cabac table input buffer
|
* 2. nal size table output buffer
|
* 3. recon / refer frame buffer
|
*/
|
typedef struct HalH264eVepuBufs_t {
|
MppBufferGroup group;
|
|
/* cabac table buffer */
|
RK_S32 cabac_init_idc;
|
MppBuffer cabac_table;
|
|
/*
|
* nal size table buffer
|
* table size must be 64-bit multiple, space for zero at the end of table
|
* Atleast 1 macroblock row in every slice
|
*/
|
RK_S32 mb_h;
|
RK_S32 nal_tab_size;
|
MppBuffer nal_size_table;
|
|
/*
|
* recon / refer frame buffer
|
* sync with encoder using slot index
|
*/
|
size_t frm_size;
|
size_t yuv_size;
|
RK_S32 frm_cnt;
|
MppBuffer frm_buf[H264E_MAX_REFS_CNT + 1];
|
} HalH264eVepuBufs;
|
|
typedef struct HalH264eVepuMbRc_t {
|
/* VEPU MB rate control parameter for config to hardware */
|
RK_S32 qp_init;
|
RK_S32 qp_min;
|
RK_S32 qp_max;
|
|
/*
|
* VEPU MB can have max 10 check points (cp).
|
*
|
* On each check point hardware will check the target bit and
|
* error bits and change qp according to delta qp step
|
*
|
* cp_distance_mbs check point distance in mbs (0 = disabled)
|
* cp_target bitrate target at each check point
|
* cp_error error bit level step for each delta qp
|
* cp_delta_qp delta qp applied on when on bit rate error amount
|
*/
|
RK_S32 cp_distance_mbs;
|
RK_S32 cp_target[VEPU_CHECK_POINTS_MAX];
|
RK_S32 cp_error[VEPU_CTRL_LEVELS];
|
RK_S32 cp_delta_qp[VEPU_CTRL_LEVELS];
|
|
/*
|
* MAD based QP adjustment
|
* mad_qp_change [-8..7]
|
* mad_threshold MAD threshold div256
|
*/
|
RK_S32 mad_qp_change;
|
RK_S32 mad_threshold;
|
|
/* slice split by mb row (0 = one slice) */
|
RK_S32 slice_size_mb_rows;
|
|
/* favor and penalty for mode decision */
|
|
/*
|
* VEPU MB rate control parameter which is read from hardware
|
* out_strm_size output stream size (bits)
|
* qp_sum QP Sum div2 output
|
* rlc_count RLC codeword count div4 output max 255*255*384/4
|
*/
|
RK_U32 hdr_strm_size;
|
RK_U32 hdr_free_size;
|
RK_U32 out_strm_size;
|
RK_S32 qp_sum;
|
RK_S32 rlc_count;
|
|
RK_S32 cp_usage[VEPU_CHECK_POINTS_MAX];
|
/* Macroblock count with MAD value under threshold output */
|
RK_S32 less_mad_count;
|
/* MB count output */
|
RK_S32 mb_count;
|
|
/* hardware encoding status 0 - corret 1 - error */
|
RK_U32 hw_status;
|
} HalH264eVepuMbRc;
|
|
typedef void *HalH264eVepuMbRcCtx;
|
|
typedef struct HalH264eVepuStreamAmend_t {
|
RK_S32 enable;
|
H264eSlice *slice;
|
H264ePrefixNal *prefix;
|
RK_S32 slice_enabled;
|
|
RK_U8 *src_buf;
|
RK_U8 *dst_buf;
|
RK_S32 buf_size;
|
|
MppPacket packet;
|
RK_S32 buf_base;
|
RK_S32 old_length;
|
RK_S32 new_length;
|
} HalH264eVepuStreamAmend;
|
|
#ifdef __cplusplus
|
extern "C" {
|
#endif
|
|
RK_S32 exp_golomb_signed(RK_S32 val);
|
|
/* buffer management function */
|
MPP_RET h264e_vepu_buf_init(HalH264eVepuBufs *bufs);
|
MPP_RET h264e_vepu_buf_deinit(HalH264eVepuBufs *bufs);
|
|
MPP_RET h264e_vepu_buf_set_cabac_idc(HalH264eVepuBufs *bufs, RK_S32 idc);
|
MPP_RET h264e_vepu_buf_set_frame_size(HalH264eVepuBufs *bufs, RK_S32 w, RK_S32 h);
|
|
MppBuffer h264e_vepu_buf_get_nal_size_table(HalH264eVepuBufs *bufs);
|
MppBuffer h264e_vepu_buf_get_frame_buffer(HalH264eVepuBufs *bufs, RK_S32 index);
|
|
/* preprocess setup function */
|
MPP_RET h264e_vepu_prep_setup(HalH264eVepuPrep *prep, MppEncPrepCfg *cfg);
|
MPP_RET h264e_vepu_prep_get_addr(HalH264eVepuPrep *prep, MppBuffer buffer,
|
RK_U32 (*addr)[3]);
|
|
/* macroblock bitrate control function */
|
MPP_RET h264e_vepu_mbrc_init(HalH264eVepuMbRcCtx *ctx, HalH264eVepuMbRc *mbrc);
|
MPP_RET h264e_vepu_mbrc_deinit(HalH264eVepuMbRcCtx ctx);
|
|
MPP_RET h264e_vepu_mbrc_setup(HalH264eVepuMbRcCtx ctx, MppEncCfgSet *cfg);
|
MPP_RET h264e_vepu_slice_split_cfg(H264eSlice *slice, HalH264eVepuMbRc *mbrc,
|
EncRcTask *rc_task, MppEncCfgSet *set_cfg);
|
|
/*
|
* generate hardware MB rc config by:
|
* 1 - HalH264eVepuMbRcCtx ctx
|
* The previous frame encoding status
|
* 2 - RcSyntax
|
* Provide current frame target bitrate related info
|
* 3 - EncFrmStatus
|
* Provide dpb related info like I / P frame, temporal id, refer distance
|
*
|
* Then output the HalH264eVepuMbRc for register generation
|
*/
|
MPP_RET h264e_vepu_mbrc_prepare(HalH264eVepuMbRcCtx ctx, HalH264eVepuMbRc *mbrc,
|
EncRcTask *rc_task);
|
MPP_RET h264e_vepu_mbrc_update(HalH264eVepuMbRcCtx ctx, HalH264eVepuMbRc *mbrc);
|
|
MPP_RET h264e_vepu_stream_amend_init(HalH264eVepuStreamAmend *ctx);
|
MPP_RET h264e_vepu_stream_amend_deinit(HalH264eVepuStreamAmend *ctx);
|
MPP_RET h264e_vepu_stream_amend_config(HalH264eVepuStreamAmend *ctx,
|
MppPacket packet, MppEncCfgSet *cfg,
|
H264eSlice *slice, H264ePrefixNal *prefix);
|
MPP_RET h264e_vepu_stream_amend_proc(HalH264eVepuStreamAmend *ctx);
|
MPP_RET h264e_vepu_stream_amend_sync_ref_idc(HalH264eVepuStreamAmend *ctx);
|
|
#ifdef __cplusplus
|
}
|
#endif
|
|
#endif
|