feat[vepu510]: Sync code from enc_tune branch

1. Add cu_qp_delta_depth cfg
2. Configure AQ regs for H.265
3. Configure regs according to scene mode
4. Support fixed frame level QP
5. Add RDO lambda table index
6. Update stat info for HEVC
7. Add tuning code for H.264 encoder

Change-Id: Id7dae4ed55e1b94622aee72cfce8f24c833d00e1
Signed-off-by: Tingjin Huang <timkingh.huang@rock-chips.com>
This commit is contained in:
toby.zhang
2024-04-19 17:25:51 +08:00
committed by Tingjin Huang
parent 12cf338dff
commit 02095f66d3
16 changed files with 736 additions and 122 deletions

View File

@@ -209,6 +209,12 @@ typedef struct EncRcCommonInfo_t {
RK_U32 lvl8_intra_num;
RK_U32 lvl4_intra_num;
RK_U32 motion_level;
RK_U32 complex_level;
RK_S32 complex_scene;
RK_S32 scene_mode;
RK_S32 last_scene_mode;
RK_S32 reserve[5];
} EncRcTaskInfo;

View File

@@ -239,6 +239,7 @@ typedef enum MppEncRcCfgChange_e {
MPP_ENC_RC_CFG_CHANGE_REFRESH = (1 << 27),
MPP_ENC_RC_CFG_CHANGE_GOP_REF_CFG = (1 << 28),
MPP_ENC_RC_CFG_CHANGE_FQP = (1 << 29),
MPP_ENC_RC_CFG_CHANGE_QPDD = (1 << 30),
MPP_ENC_RC_CFG_CHANGE_ALL = (0xFFFFFFFF),
} MppEncRcCfgChange;
@@ -410,6 +411,7 @@ typedef struct MppEncRcCfg_t {
RK_S32 fqp_min_p;
RK_S32 fqp_max_i;
RK_S32 fqp_max_p;
RK_S32 cu_qp_delta_depth;
RK_S32 hier_qp_en;
RK_S32 hier_qp_delta[4];
@@ -1427,12 +1429,16 @@ typedef enum MppEncSceneMode_e {
typedef enum MppEncFineTuneCfgChange_e {
/* change on scene mode */
MPP_ENC_TUNE_CFG_CHANGE_SCENE_MODE = (1 << 0),
MPP_ENC_TUNE_CFG_CHANGE_LAMBDA_IDX_I = (1 << 5),
MPP_ENC_TUNE_CFG_CHANGE_LAMBDA_IDX_P = (1 << 6)
} MppEncFineTuneCfgChange;
typedef struct MppEncFineTuneCfg_t {
RK_U32 change;
MppEncSceneMode scene_mode;
RK_S32 lambda_idx_i;
RK_S32 lambda_idx_p;
} MppEncFineTuneCfg;
#endif /*__RK_VENC_CMD_H__*/

View File

@@ -139,6 +139,7 @@ public:
ENTRY(rc, fqp_min_p, S32, RK_S32, MPP_ENC_RC_CFG_CHANGE_FQP, rc, fqp_min_p) \
ENTRY(rc, fqp_max_i, S32, RK_S32, MPP_ENC_RC_CFG_CHANGE_FQP, rc, fqp_max_i) \
ENTRY(rc, fqp_max_p, S32, RK_S32, MPP_ENC_RC_CFG_CHANGE_FQP, rc, fqp_max_p) \
ENTRY(rc, cu_qp_delta_depth, S32, RK_S32, MPP_ENC_RC_CFG_CHANGE_QPDD, rc, cu_qp_delta_depth) \
/* prep config */ \
ENTRY(prep, width, S32, RK_S32, MPP_ENC_PREP_CFG_CHANGE_INPUT, prep, width) \
ENTRY(prep, height, S32, RK_S32, MPP_ENC_PREP_CFG_CHANGE_INPUT, prep, height) \
@@ -255,7 +256,9 @@ public:
ENTRY(hw, qbias_p, S32, RK_S32, MPP_ENC_HW_CFG_CHANGE_QBIAS_P, hw, qbias_p) \
ENTRY(hw, qbias_en, S32, RK_S32, MPP_ENC_HW_CFG_CHANGE_QBIAS_EN, hw, qbias_en) \
/* quality fine tuning config */ \
ENTRY(tune, scene_mode, S32, MppEncSceneMode, MPP_ENC_TUNE_CFG_CHANGE_SCENE_MODE, tune, scene_mode)
ENTRY(tune, scene_mode, S32, MppEncSceneMode, MPP_ENC_TUNE_CFG_CHANGE_SCENE_MODE, tune, scene_mode) \
ENTRY(tune, lambda_idx_i, S32, RK_S32, MPP_ENC_TUNE_CFG_CHANGE_LAMBDA_IDX_I, tune, lambda_idx_i) \
ENTRY(tune, lambda_idx_p, S32, RK_S32, MPP_ENC_TUNE_CFG_CHANGE_LAMBDA_IDX_P, tune, lambda_idx_p)
static void mpp_enc_cfg_fill(MppTrie trie, MppCfgApi **cfgs)
{

View File

@@ -74,7 +74,7 @@ typedef struct MppTrieNode_t {
RK_U16 next_cnt;
} MppTrieNode;
typedef struct MppAcImpl_t {
typedef struct MppTrieImpl_t {
RK_S32 info_count;
RK_S32 info_used;
MppTrieInfo *info;
@@ -175,7 +175,7 @@ DONE:
MPP_RET mpp_trie_deinit(MppTrie trie)
{
if (NULL == trie) {
mpp_err_f("invalid NULL input trie automation\n");
mpp_err_f("invalid NULL input trie\n");
return MPP_ERR_NULL_PTR;
}

View File

@@ -188,6 +188,9 @@ static void init_h264e_cfg_set(MppEncCfgSet *cfg, MppClientType type)
rc_cfg->fqp_min_p = INT_MAX;
rc_cfg->fqp_max_i = INT_MAX;
rc_cfg->fqp_max_p = INT_MAX;
cfg->tune.lambda_idx_i = 6;
cfg->tune.lambda_idx_p = 6;
}
static void h264e_add_syntax(H264eCtx *ctx, H264eSyntaxType type, void *p)

View File

@@ -110,6 +110,8 @@ static MPP_RET h265e_init(void *ctx, EncImplCfg *ctrlCfg)
h265->merge_cfg.merge_left_flag = 1;
h265->merge_cfg.merge_up_flag = 1;
p->cfg->tune.scene_mode = MPP_ENC_SCENE_MODE_DEFAULT;
p->cfg->tune.lambda_idx_i = 2;
p->cfg->tune.lambda_idx_p = 4;
/*
* default prep:
@@ -167,7 +169,7 @@ static MPP_RET h265e_init(void *ctx, EncImplCfg *ctrlCfg)
rc_cfg->fqp_min_p = INT_MAX;
rc_cfg->fqp_max_i = INT_MAX;
rc_cfg->fqp_max_p = INT_MAX;
rc_cfg->cu_qp_delta_depth = 0;
INIT_LIST_HEAD(&p->rc_list);
h265e_dbg_func("leave ctx %p\n", ctx);

View File

@@ -400,13 +400,14 @@ MPP_RET h265e_set_sps(H265eCtx *ctx, H265eSps *sps, H265eVps *vps)
MPP_RET h265e_set_pps(H265eCtx *ctx, H265ePps *pps, H265eSps *sps)
{
MppEncH265Cfg *codec = &ctx->cfg->codec.h265;
MppEncRcCfg *rc = &ctx->cfg->rc;
pps->m_bConstrainedIntraPred = codec->const_intra_pred;
pps->m_PPSId = 0;
pps->m_SPSId = 0;
pps->m_picInitQPMinus26 = 0;
pps->m_useDQP = 1;
pps->m_maxCuDQPDepth = 0;
pps->m_maxCuDQPDepth = rc->cu_qp_delta_depth;
pps->m_minCuDQPSize = (sps->m_maxCUSize >> pps->m_maxCuDQPDepth);
pps->m_sps = sps;

View File

@@ -681,6 +681,9 @@ MPP_RET mpp_enc_proc_rc_cfg(MppCodingType coding, MppEncRcCfg *dst, MppEncRcCfg
dst->refresh_num = src->refresh_num;
}
if (change & MPP_ENC_RC_CFG_CHANGE_QPDD)
dst->cu_qp_delta_depth = src->cu_qp_delta_depth;
// parameter checking
if (dst->rc_mode >= MPP_ENC_RC_MODE_BUTT) {
mpp_err("invalid rc mode %d should be RC_MODE_VBR or RC_MODE_CBR\n",
@@ -864,6 +867,22 @@ MPP_RET mpp_enc_proc_tune_cfg(MppEncFineTuneCfg *dst, MppEncFineTuneCfg *src)
ret = MPP_ERR_VALUE;
}
if (change & MPP_ENC_TUNE_CFG_CHANGE_LAMBDA_IDX_I)
dst->lambda_idx_i = src->lambda_idx_i;
if (dst->lambda_idx_i < 0 || dst->lambda_idx_i > 8) {
mpp_err("invalid lambda idx i not in range [0 : 8]\n");
ret = MPP_ERR_VALUE;
}
if (change & MPP_ENC_TUNE_CFG_CHANGE_LAMBDA_IDX_P)
dst->lambda_idx_p = src->lambda_idx_p;
if (dst->lambda_idx_p < 0 || dst->lambda_idx_p > 8) {
mpp_err("invalid lambda idx i not in range [0 : 8]\n");
ret = MPP_ERR_VALUE;
}
dst->change |= change;
if (ret) {

View File

@@ -1103,12 +1103,7 @@ typedef struct Vepu510Status_t {
} st_bnum_b16;
/* 0x000040a4 reg4137 */
struct {
RK_U32 rdo_smear_cnt0 : 8;
RK_U32 rdo_smear_cnt1 : 8;
RK_U32 rdo_smear_cnt2 : 8;
RK_U32 rdo_smear_cnt3 : 8;
} st_smear_cnt;
RK_U32 st_smear_cnt_reserved;
/* 0x000040a8 reg4138 */
RK_U32 madi16_sum;

View File

@@ -107,8 +107,13 @@ typedef struct HalH264eVepu510Ctx_t {
RK_S32 poll_slice_max;
RK_S32 poll_cfg_size;
MppDevPollCfg *poll_cfgs;
void *tune;
RK_S32 smart_en;
} HalH264eVepu510Ctx;
#include "hal_h264e_vepu510_tune.c"
static RK_S32 h264_aq_tthd_default[16] = {
0, 0, 0, 0,
3, 3, 5, 5,
@@ -213,6 +218,11 @@ static MPP_RET hal_h264e_vepu510_deinit(void *hal)
p->buf_pass1 = NULL;
}
if (p->tune) {
vepu510_h264e_tune_deinit(p->tune);
p->tune = NULL;
}
hal_h264e_dbg_func("leave %p\n", p);
return MPP_OK;
@@ -326,6 +336,8 @@ static MPP_RET hal_h264e_vepu510_init(void *hal, MppEncHalCfg *cfg)
for (i = 0; i < p->task_cnt; i++)
h264e_vepu_stream_amend_init(&p->amend_sets[i]);
p->tune = vepu510_h264e_tune_init(p);
DONE:
if (ret)
hal_h264e_vepu510_deinit(hal);
@@ -1184,7 +1196,6 @@ static void setup_vepu510_sqi(H264eVepu510Sqi *reg)
static void setup_vepu510_rc_base(HalVepu510RegSet *regs, HalH264eVepu510Ctx *ctx, EncRcTask *rc_task)
{
H264eSps *sps = ctx->sps;
H264eSlice *slice = ctx->slice;
MppEncCfgSet *cfg = ctx->cfg;
@@ -1256,6 +1267,24 @@ static void setup_vepu510_rc_base(HalVepu510RegSet *regs, HalH264eVepu510Ctx *ct
reg_frm->common.rc_qp.rc_min_qp = qp_min;
reg_frm->common.rc_tgt.ctu_ebit = mb_target_bits_mul_16;
{
/* fixed frame level QP */
RK_S32 fqp_min, fqp_max;
if (slice->slice_type == H264_I_SLICE) {
fqp_min = rc->fqp_min_i;
fqp_max = rc->fqp_max_i;
} else {
fqp_min = rc->fqp_min_p;
fqp_max = rc->fqp_max_p;
}
if ((fqp_min == fqp_max) && (fqp_min >= 1) && (fqp_max <= 51)) {
reg_frm->common.enc_pic.pic_qp = fqp_min;
reg_frm->common.rc_qp.rc_qp_range = 0;
}
}
regs->reg_rc_roi.rc_adj0.qp_adj0 = -2;
regs->reg_rc_roi.rc_adj0.qp_adj1 = -1;
regs->reg_rc_roi.rc_adj0.qp_adj2 = 0;
@@ -1626,31 +1655,59 @@ static void setup_vepu510_me(HalVepu510RegSet *regs)
#define H264E_LAMBDA_TAB_SIZE (52 * sizeof(RK_U32))
static RK_U32 h264e_lambda_default[58] = {
0x00000003, 0x00000005, 0x00000006, 0x00000007,
0x00000009, 0x0000000b, 0x0000000e, 0x00000012,
0x00000016, 0x0000001c, 0x00000024, 0x0000002d,
0x00000039, 0x00000048, 0x0000005b, 0x00000073,
0x00000091, 0x000000b6, 0x000000e6, 0x00000122,
0x0000016d, 0x000001cc, 0x00000244, 0x000002db,
0x00000399, 0x00000489, 0x000005b6, 0x00000733,
0x00000912, 0x00000b6d, 0x00000e66, 0x00001224,
0x000016db, 0x00001ccc, 0x00002449, 0x00002db7,
0x00003999, 0x00004892, 0x00005b6f, 0x00007333,
0x00009124, 0x0000b6de, 0x0000e666, 0x00012249,
0x00016dbc, 0x0001cccc, 0x00024492, 0x0002db79,
0x00039999, 0x00048924, 0x0005b6f2, 0x00073333,
0x00091249, 0x000b6de5, 0x000e6666, 0x00122492,
0x0016dbcb, 0x001ccccc,
static RK_U32 h264e_lambda_default[60] = {
0x00000005, 0x00000006, 0x00000007, 0x00000009,
0x0000000b, 0x0000000e, 0x00000012, 0x00000016,
0x0000001c, 0x00000024, 0x0000002d, 0x00000039,
0x00000048, 0x0000005b, 0x00000073, 0x00000091,
0x000000b6, 0x000000e6, 0x00000122, 0x0000016d,
0x000001cc, 0x00000244, 0x000002db, 0x00000399,
0x00000489, 0x000005b6, 0x00000733, 0x00000912,
0x00000b6d, 0x00000e66, 0x00001224, 0x000016db,
0x00001ccc, 0x00002449, 0x00002db7, 0x00003999,
0x00004892, 0x00005b6f, 0x00007333, 0x00009124,
0x0000b6de, 0x0000e666, 0x00012249, 0x00016dbc,
0x0001cccc, 0x00024492, 0x0002db79, 0x00039999,
0x00048924, 0x0005b6f2, 0x00073333, 0x00091249,
0x000b6de5, 0x000e6666, 0x00122492, 0x0016dbcb,
0x001ccccc, 0x00244924, 0x002db796, 0x00399998,
};
static void setup_vepu510_l2(HalVepu510RegSet *regs, H264eSlice *slice, MppEncHwCfg *hw)
static RK_U32 h264e_lambda_cvr[60] = {
0x00000009, 0x0000000b, 0x0000000e, 0x00000011,
0x00000016, 0x0000001b, 0x00000022, 0x0000002b,
0x00000036, 0x00000045, 0x00000056, 0x0000006d,
0x00000089, 0x000000ad, 0x000000da, 0x00000112,
0x00000159, 0x000001b3, 0x00000224, 0x000002b3,
0x00000366, 0x00000449, 0x00000566, 0x000006cd,
0x00000891, 0x00000acb, 0x00000d9a, 0x000013c1,
0x000018e4, 0x00001f5c, 0x00002783, 0x000031c8,
0x00003eb8, 0x00004f06, 0x00006390, 0x00008e14,
0x0000b302, 0x0000e18a, 0x00011c29, 0x00016605,
0x0001c313, 0x00027ae1, 0x00031fe6, 0x0003efcf,
0x0004f5c3, 0x0006e785, 0x0008b2ef, 0x000af5c3,
0x000f1e7a, 0x00130c7f, 0x00180000, 0x001e3cf4,
0x002618fe, 0x00300000, 0x003c79e8, 0x004c31fc,
0x00600000, 0x0078f3d0, 0x009863f8, 0x0c000000,
};
static void
setup_vepu510_l2(HalH264eVepu510Ctx *ctx, H264eSlice *slice, MppEncHwCfg *hw)
{
HalVepu510RegSet *regs = ctx->regs_set;
MppEncSceneMode sm = ctx->cfg->tune.scene_mode;
RK_S32 lambda_idx = ctx->cfg->tune.lambda_idx_i; //TODO: lambda_idx_p
RK_U32 i;
hal_h264e_dbg_func("enter\n");
memcpy(regs->reg_param.rdo_wgta_qp_grpa_0_51, &h264e_lambda_default[6], H264E_LAMBDA_TAB_SIZE);
if (sm == MPP_ENC_SCENE_MODE_IPC) {
memcpy(regs->reg_param.rdo_wgta_qp_grpa_0_51,
&h264e_lambda_default[lambda_idx], H264E_LAMBDA_TAB_SIZE);
} else {
memcpy(regs->reg_param.rdo_wgta_qp_grpa_0_51,
&h264e_lambda_cvr[lambda_idx], H264E_LAMBDA_TAB_SIZE);
}
if (hw->qbias_en) {
regs->reg_param.qnt_bias_comb.qnt_f_bias_i = hw->qbias_i;
@@ -1950,12 +2007,14 @@ static MPP_RET hal_h264e_vepu510_gen_regs(void *hal, HalEncTask *task)
if (frm_status->is_i_refresh)
setup_vepu510_intra_refresh(regs, ctx, frm_status->seq_idx % cfg->rc.gop);
setup_vepu510_l2(regs, slice, &cfg->hw);
setup_vepu510_l2(ctx, slice, &cfg->hw);
setup_vepu510_ext_line_buf(regs, ctx);
if (ctx->roi_data)
vepu510_set_roi(&ctx->regs_set->reg_rc_roi.roi_cfg, ctx->roi_data,
ctx->cfg->prep.width, ctx->cfg->prep.height);
vepu510_h264e_tune_reg_patch(ctx->tune);
/* two pass register patch */
if (frm->save_pass1)
vepu510_h264e_save_pass1_patch(regs, ctx);
@@ -2267,6 +2326,8 @@ static MPP_RET hal_h264e_vepu510_ret_task(void * hal, HalEncTask * task)
h264e_dpb_hal_end(ctx->dpb, task->flags.refr_idx);
}
vepu510_h264e_tune_stat_update(ctx->tune, task);
hal_h264e_dbg_func("leave %p\n", hal);
return MPP_OK;

View File

@@ -0,0 +1,178 @@
/*
* Copyright 2024 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 "hal_enc_task.h"
#include "hal_h264e_vepu510_reg.h"
#define HAL_H264E_DBG_CONTENT (0x00000200)
#define hal_h264e_dbg_content(fmt, ...) hal_h264e_dbg_f(HAL_H264E_DBG_CONTENT, fmt, ## __VA_ARGS__)
/*
* Please follow the configuration below:
*
* FRAME_CONTENT_ANALYSIS_NUM >= 5
* MD_WIN_LEN >= 3
* MD_SHOW_LEN == 4
*/
typedef struct HalH264eVepu510Tune_t {
HalH264eVepu510Ctx *ctx;
RK_S32 pre_madp[2];
RK_S32 pre_madi[2];
} HalH264eVepu510Tune;
static RK_S32 mb_avg_madp_thd[6] = {192, 128, 64, 192, 128, 64};
static RK_S32 atr_wgt[4][9] = {
{22, 19, 16, 22, 19, 18, 22, 19, 16},
{19, 19, 19, 19, 19, 19, 19, 19, 19},
{22, 19, 16, 22, 19, 18, 22, 19, 16},
{20, 20, 20, 20, 20, 20, 20, 20, 20},
};
static RK_S32 skip_atf_wgt[4][13] = {
{16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16},
{16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16},
{16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16},
{16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16},
};
static RK_S32 intra_atf_wgt[4][12] = {
{24, 22, 21, 22, 21, 20, 20, 19, 18, 16, 16, 16},
{16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16},
{22, 21, 20, 21, 20, 19, 20, 19, 18, 16, 16, 16},
{16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16},
};
static RK_S32 cime_multi[4][4] = {
{4, 8, 24, 24},
{4, 7, 20, 20},
{4, 7, 20, 20},
{4, 4, 4, 4},
};
static RK_S32 rime_multi[4][3] = {
{4, 32, 128},
{4, 16, 64},
{4, 16, 64},
{4, 4, 4},
};
static HalH264eVepu510Tune *vepu510_h264e_tune_init(HalH264eVepu510Ctx *ctx)
{
HalH264eVepu510Tune *tune = mpp_malloc(HalH264eVepu510Tune, 1);
if (NULL == tune)
return tune;
tune->ctx = ctx;
tune->pre_madi[0] = tune->pre_madi[1] = -1;
tune->pre_madp[0] = tune->pre_madp[1] = -1;
return tune;
}
static void vepu510_h264e_tune_deinit(void *tune)
{
MPP_FREE(tune);
}
static void vepu510_h264e_tune_reg_patch(void *p)
{
HalH264eVepu510Tune *tune = (HalH264eVepu510Tune *)p;
if (NULL == tune)
return;
}
static void vepu510_h264e_tune_stat_update(void *p, HalEncTask *task)
{
HalH264eVepu510Tune *tune = (HalH264eVepu510Tune *)p;
if (NULL == tune)
return;
EncRcTaskInfo *rc_info = &task->rc_task->info;
HalH264eVepu510Ctx *ctx = tune->ctx;
HalVepu510RegSet *regs = &ctx->regs_sets[task->flags.reg_idx];
Vepu510Status *st = &regs->reg_st;
RK_U32 mb_w = ctx->sps->pic_width_in_mbs;
RK_U32 mb_h = ctx->sps->pic_height_in_mbs;
RK_U32 b16_num = mb_w * mb_h;
RK_U32 madi_cnt = 0;
RK_U32 madi_th_cnt0 = st->st_madi_lt_num0.madi_th_lt_cnt0 +
st->st_madi_rt_num0.madi_th_rt_cnt0 +
st->st_madi_lb_num0.madi_th_lb_cnt0 +
st->st_madi_rb_num0.madi_th_rb_cnt0;
RK_U32 madi_th_cnt1 = st->st_madi_lt_num0.madi_th_lt_cnt1 +
st->st_madi_rt_num0.madi_th_rt_cnt1 +
st->st_madi_lb_num0.madi_th_lb_cnt1 +
st->st_madi_rb_num0.madi_th_rb_cnt1;
RK_U32 madi_th_cnt2 = st->st_madi_lt_num1.madi_th_lt_cnt2 +
st->st_madi_rt_num1.madi_th_rt_cnt2 +
st->st_madi_lb_num1.madi_th_lb_cnt2 +
st->st_madi_rb_num1.madi_th_rb_cnt2;
RK_U32 madi_th_cnt3 = st->st_madi_lt_num1.madi_th_lt_cnt3 +
st->st_madi_rt_num1.madi_th_rt_cnt3 +
st->st_madi_lb_num1.madi_th_lb_cnt3 +
st->st_madi_rb_num1.madi_th_rb_cnt3;
RK_U32 madp_th_cnt0 = st->st_madp_lt_num0.madp_th_lt_cnt0 +
st->st_madp_rt_num0.madp_th_rt_cnt0 +
st->st_madp_lb_num0.madp_th_lb_cnt0 +
st->st_madp_rb_num0.madp_th_rb_cnt0;
RK_U32 madp_th_cnt1 = st->st_madp_lt_num0.madp_th_lt_cnt1 +
st->st_madp_rt_num0.madp_th_rt_cnt1 +
st->st_madp_lb_num0.madp_th_lb_cnt1 +
st->st_madp_rb_num0.madp_th_rb_cnt1;
RK_U32 madp_th_cnt2 = st->st_madp_lt_num1.madp_th_lt_cnt2 +
st->st_madp_rt_num1.madp_th_rt_cnt2 +
st->st_madp_lb_num1.madp_th_lb_cnt2 +
st->st_madp_rb_num1.madp_th_rb_cnt2;
RK_U32 madp_th_cnt3 = st->st_madp_lt_num1.madp_th_lt_cnt3 +
st->st_madp_rt_num1.madp_th_rt_cnt3 +
st->st_madp_lb_num1.madp_th_lb_cnt3 +
st->st_madp_rb_num1.madp_th_rb_cnt3;
madi_cnt = (6 * madi_th_cnt3 + 5 * madi_th_cnt2 + 4 * madi_th_cnt1) >> 2;
rc_info->complex_level = (madi_cnt * 100 > 30 * b16_num) ? 2 :
(madi_cnt * 100 > 13 * b16_num) ? 1 : 0;
{
RK_U32 md_cnt = 0, motion_level = 0;
if (ctx->smart_en)
md_cnt = (12 * madp_th_cnt3 + 11 * madp_th_cnt2 + 8 * madp_th_cnt1) >> 2;
else
md_cnt = (24 * madp_th_cnt3 + 22 * madp_th_cnt2 + 17 * madp_th_cnt1) >> 2;
if (md_cnt * 100 > 15 * b16_num)
motion_level = 200;
else if (md_cnt * 100 > 5 * b16_num)
motion_level = 100;
else if (md_cnt * 100 > (b16_num >> 2))
motion_level = 1;
else
motion_level = 0;
rc_info->motion_level = motion_level;
}
hal_h264e_dbg_rc("complex_level %d motion_level %d\n",
rc_info->complex_level, rc_info->motion_level);
(void)madi_th_cnt0;
(void)madp_th_cnt0;
}

View File

@@ -30,6 +30,7 @@
#include "vepu510_common.h"
#define MAX_FRAME_TASK_NUM 2
#define H265E_LAMBDA_TAB_SIZE (52 * sizeof(RK_U32))
#define hal_h265e_err(fmt, ...) \
do {\
@@ -38,6 +39,7 @@
typedef struct Vepu510H265Fbk_t {
RK_U32 hw_status; /* 0:corret, 1:error */
RK_U32 frame_type;
RK_U32 qp_sum;
RK_U32 out_strm_size;
RK_U32 out_hw_strm_size;
@@ -55,6 +57,8 @@ typedef struct Vepu510H265Fbk_t {
RK_U32 st_madi;
RK_U32 st_mb_num;
RK_U32 st_ctu_num;
RK_U32 st_smear_cnt[5];
RK_S8 tgt_sub_real_lvl[6];
} Vepu510H265Fbk;
typedef struct Vepu510H265eFrmCfg_t {
@@ -117,6 +121,7 @@ typedef struct H265eV510HalContext_t {
RK_S32 prev_idx;
Vepu510H265Fbk feedback;
Vepu510H265Fbk last_frame_fb;
void *dump_files;
RK_U32 frame_cnt_gen_ready;
@@ -144,6 +149,9 @@ typedef struct H265eV510HalContext_t {
RK_S32 fbc_header_len;
RK_U32 title_num;
RK_S32 qpmap_en;
RK_S32 smart_en;
/* external line buffer over 3K */
MppBufferGroup ext_line_buf_grp;
RK_S32 ext_line_buf_size;
@@ -151,8 +159,11 @@ typedef struct H265eV510HalContext_t {
MppBuffer buf_pass1;
MppBuffer ext_line_bufs[MAX_FRAME_TASK_NUM];
void *tune;
} H265eV510HalContext;
#include "hal_h265e_vepu510_tune.c"
static RK_U32 aq_thd_default[16] = {
0, 0, 0, 0,
3, 3, 5, 5,
@@ -167,6 +178,43 @@ static RK_S32 aq_qp_dealt_default[16] = {
4, 5, 6, 8,
};
static RK_U32 rdo_lambda_table_I[60] = {
0x00000012, 0x00000017,
0x0000001d, 0x00000024, 0x0000002e, 0x0000003a,
0x00000049, 0x0000005c, 0x00000074, 0x00000092,
0x000000b8, 0x000000e8, 0x00000124, 0x00000170,
0x000001cf, 0x00000248, 0x000002df, 0x0000039f,
0x0000048f, 0x000005bf, 0x0000073d, 0x0000091f,
0x00000b7e, 0x00000e7a, 0x0000123d, 0x000016fb,
0x00001cf4, 0x0000247b, 0x00002df6, 0x000039e9,
0x000048f6, 0x00005bed, 0x000073d1, 0x000091ec,
0x0000b7d9, 0x0000e7a2, 0x000123d7, 0x00016fb2,
0x0001cf44, 0x000247ae, 0x0002df64, 0x00039e89,
0x00048f5c, 0x0005bec8, 0x00073d12, 0x00091eb8,
0x000b7d90, 0x000e7a23, 0x00123d71, 0x0016fb20,
0x001cf446, 0x00247ae1, 0x002df640, 0x0039e88c,
0x0048f5c3, 0x005bec81, 0x0073d119, 0x0091eb85,
0x00b7d902, 0x00e7a232
};
static RK_U32 rdo_lambda_table_P[60] = {
0x0000002c, 0x00000038, 0x00000044, 0x00000058,
0x00000070, 0x00000089, 0x000000b0, 0x000000e0,
0x00000112, 0x00000160, 0x000001c0, 0x00000224,
0x000002c0, 0x00000380, 0x00000448, 0x00000580,
0x00000700, 0x00000890, 0x00000b00, 0x00000e00,
0x00001120, 0x00001600, 0x00001c00, 0x00002240,
0x00002c00, 0x00003800, 0x00004480, 0x00005800,
0x00007000, 0x00008900, 0x0000b000, 0x0000e000,
0x00011200, 0x00016000, 0x0001c000, 0x00022400,
0x0002c000, 0x00038000, 0x00044800, 0x00058000,
0x00070000, 0x00089000, 0x000b0000, 0x000e0000,
0x00112000, 0x00160000, 0x001c0000, 0x00224000,
0x002c0000, 0x00380000, 0x00448000, 0x00580000,
0x00700000, 0x00890000, 0x00b00000, 0x00e00000,
0x01120000, 0x01600000, 0x01c00000, 0x02240000,
};
static void setup_ext_line_bufs(H265eV510HalContext *ctx)
{
RK_S32 i;
@@ -296,15 +344,15 @@ static MPP_RET vepu510_h265_setup_hal_bufs(H265eV510HalContext *ctx)
return ret;
}
static void vepu510_h265_rdo_cfg(H265eVepu510Sqi *reg)
static void vepu510_h265_rdo_cfg(H265eVepu510Sqi *reg, MppEncSceneMode sm)
{
rdo_skip_par *p_rdo_skip = NULL;
rdo_noskip_par *p_rdo_noskip = NULL;
pre_cst_par *p_pre_cst = NULL;
reg->subj_opt_cfg.subj_opt_en = 1;
reg->subj_opt_cfg.subj_opt_en = (sm == MPP_ENC_SCENE_MODE_IPC);
reg->subj_opt_cfg.subj_opt_strength = 3;
reg->subj_opt_cfg.aq_subj_en = 1;
reg->subj_opt_cfg.aq_subj_en = (sm == MPP_ENC_SCENE_MODE_IPC);
reg->subj_opt_cfg.aq_subj_strength = 4;
reg->subj_opt_dpth_thd.common_thre_num_grdn_point_dep0 = 64;
reg->subj_opt_dpth_thd.common_thre_num_grdn_point_dep1 = 32;
@@ -313,7 +361,7 @@ static void vepu510_h265_rdo_cfg(H265eVepu510Sqi *reg)
reg->subj_opt_inrar_coef.common_rdo_cu_intra_r_coef_dep1 = 160;
/* anti smear */
reg->smear_opt_cfg0.anti_smear_en = 1;
reg->smear_opt_cfg0.anti_smear_en = (sm == MPP_ENC_SCENE_MODE_IPC);
reg->smear_opt_cfg0.smear_stor_en = 0;
reg->smear_opt_cfg0.smear_load_en = 0;
reg->smear_opt_cfg0.smear_strength = 3;
@@ -370,7 +418,7 @@ static void vepu510_h265_rdo_cfg(H265eVepu510Sqi *reg)
reg->smear_madp_cov_thd.smear_thre_qp = 30;
/* skin_opt */
reg->skin_opt_cfg.skin_en = 1;
reg->skin_opt_cfg.skin_en = 0;
reg->skin_opt_cfg.skin_strength = 3;
reg->skin_opt_cfg.thre_uvsqr16_skin = 128;
reg->skin_opt_cfg.skin_thre_cst_best_mad = 1000;
@@ -385,7 +433,7 @@ static void vepu510_h265_rdo_cfg(H265eVepu510Sqi *reg)
reg->subj_opt_dqp1.skin_thre_qp = 31;
/* text_opt */
reg->block_opt_cfg.block_en = 1;
reg->block_opt_cfg.block_en = (sm == MPP_ENC_SCENE_MODE_IPC);
reg->block_opt_cfg.block_thre_cst_best_mad = 1000;
reg->block_opt_cfg.block_thre_cst_best_grdn_blk = 39;
reg->block_opt_cfg.thre_num_grdnt_point_cmplx = 3;
@@ -393,14 +441,14 @@ static void vepu510_h265_rdo_cfg(H265eVepu510Sqi *reg)
reg->cmplx_opt_cfg.cmplx_thre_cst_best_mad_dep0 = 4000;
reg->cmplx_opt_cfg.cmplx_thre_cst_best_mad_dep1 = 2000;
reg->cmplx_opt_cfg.cmplx_en = 1;
reg->cmplx_opt_cfg.cmplx_en = (sm == MPP_ENC_SCENE_MODE_IPC);
reg->cmplx_bst_mad_thd.cmplx_thre_cst_best_mad_dep2 = 200;
reg->cmplx_bst_mad_thd.cmplx_thre_cst_best_grdn_blk_dep0 = 977;
reg->cmplx_bst_grdn_thd.cmplx_thre_cst_best_grdn_blk_dep1 = 0;
reg->cmplx_bst_grdn_thd.cmplx_thre_cst_best_grdn_blk_dep2 = 488;
reg->line_opt_cfg.line_en = 1;
reg->line_opt_cfg.line_en = (sm == MPP_ENC_SCENE_MODE_IPC);
reg->line_opt_cfg.line_thre_min_cst_best_grdn_blk_dep0 = 3;
reg->line_opt_cfg.line_thre_min_cst_best_grdn_blk_dep1 = 20;
reg->line_opt_cfg.line_thre_min_cst_best_grdn_blk_dep2 = 20;
@@ -580,7 +628,7 @@ static void vepu510_h265_rdo_cfg(H265eVepu510Sqi *reg)
reg->cudecis_thd3.delta0_thre_str_edge_bgrad32_intra = 0;
reg->cudecis_thd3.delta1_thre_str_edge_bgrad32_intra = 0;
reg->cudecis_thd3.delta2_thre_str_edge_bgrad32_intra = 7;
reg->cudecis_thd3.delta3_thre_str_edge_bgrad32_intra = 0;
reg->cudecis_thd3.delta3_thre_str_edge_bgrad32_intra = 19;
reg->cudecis_thd3.base_thre_mad16_intra = 6;
reg->cudecis_thd3.delta0_thre_mad16_intra = 0;
@@ -666,25 +714,32 @@ static void vepu510_h265_global_cfg_set(H265eV510HalContext *ctx, H265eV510RegSe
Vepu510RcRoi *rc_regs = &regs->reg_rc_roi;
H265eVepu510Param *reg_param = &regs->reg_param;
H265eVepu510Sqi *reg_sqi = &regs->reg_sqi;
MppEncSceneMode sm = ctx->cfg->tune.scene_mode;
RK_S32 lambda_idx = 0;
vepu510_h265_rdo_cfg(reg_sqi);
vepu510_h265_rdo_cfg(reg_sqi, sm);
memcpy(&reg_param->pprd_lamb_satd_0_51[0], lamd_satd_qp_510, sizeof(lamd_satd_qp));
if (ctx->frame_type == INTRA_FRAME) {
RK_U8 *thd = (RK_U8 *)&rc_regs->aq_tthd0;
for (i = 0; i < MPP_ARRAY_ELEMS(aq_thd_default); i++) {
thd[i] = hw->aq_thrd_i[i];
}
reg_param->iprd_lamb_satd_ofst.lambda_satd_offset = 11;
memcpy(&reg_param->rdo_wgta_qp_grpa_0_51[0], lamd_moda_qp, sizeof(lamd_moda_qp));
lambda_idx = ctx->cfg->tune.lambda_idx_i;
memcpy(&reg_param->rdo_wgta_qp_grpa_0_51[0],
&rdo_lambda_table_I[lambda_idx], H265E_LAMBDA_TAB_SIZE);
} else {
RK_U8 *thd = (RK_U8 *)&rc_regs->aq_tthd0;
for (i = 0; i < MPP_ARRAY_ELEMS(aq_thd_default); i++) {
thd[i] = hw->aq_thrd_p[i];
}
reg_param->iprd_lamb_satd_ofst.lambda_satd_offset = 11;
memcpy(&reg_param->rdo_wgta_qp_grpa_0_51[0], lamd_modb_qp, sizeof(lamd_modb_qp));
lambda_idx = ctx->cfg->tune.lambda_idx_p;
memcpy(&reg_param->rdo_wgta_qp_grpa_0_51[0],
&rdo_lambda_table_P[lambda_idx], H265E_LAMBDA_TAB_SIZE);
}
reg_param->qnt_bias_comb.qnt_f_bias_i = 171;
@@ -693,52 +748,70 @@ static void vepu510_h265_global_cfg_set(H265eV510HalContext *ctx, H265eV510RegSe
reg_param->qnt_bias_comb.qnt_f_bias_i = hw->qbias_i;
reg_param->qnt_bias_comb.qnt_f_bias_p = hw->qbias_p;
}
/* CIME */
{
/* 0x1760 */
regs->reg_param.me_sqi_comb.cime_pmv_num = 1;
regs->reg_param.me_sqi_comb.cime_fuse = 1;
regs->reg_param.me_sqi_comb.itp_mode = 0;
regs->reg_param.me_sqi_comb.move_lambda = 2;
regs->reg_param.me_sqi_comb.rime_lvl_mrg = 1;
regs->reg_param.me_sqi_comb.rime_prelvl_en = 3;
regs->reg_param.me_sqi_comb.rime_prersu_en = 3;
reg_param->me_sqi_comb.cime_pmv_num = 1;
reg_param->me_sqi_comb.cime_fuse = 1;
reg_param->me_sqi_comb.itp_mode = 1;
reg_param->me_sqi_comb.move_lambda = (sm == MPP_ENC_SCENE_MODE_IPC) ? 2 : 8;
reg_param->me_sqi_comb.rime_lvl_mrg = 1;
reg_param->me_sqi_comb.rime_prelvl_en = 3;
reg_param->me_sqi_comb.rime_prersu_en = 0;
reg_param->cime_mvd_th_comb.cime_mvd_th0 = 8;
reg_param->cime_mvd_th_comb.cime_mvd_th1 = 20;
reg_param->cime_mvd_th_comb.cime_mvd_th2 = 32;
reg_param->cime_madp_th_comb.cime_madp_th = (sm == MPP_ENC_SCENE_MODE_IPC) ? 16 : 0;
/* 0x1764 */
regs->reg_param.cime_mvd_th_comb.cime_mvd_th0 = 8;
regs->reg_param.cime_mvd_th_comb.cime_mvd_th1 = 20;
regs->reg_param.cime_mvd_th_comb.cime_mvd_th2 = 32;
/* 0x1768 */
regs->reg_param.cime_madp_th_comb.cime_madp_th = 16;
/* 0x176c */
regs->reg_param.cime_multi_comb.cime_multi0 = 8;
regs->reg_param.cime_multi_comb.cime_multi1 = 12;
regs->reg_param.cime_multi_comb.cime_multi2 = 16;
regs->reg_param.cime_multi_comb.cime_multi3 = 20;
if (sm == MPP_ENC_SCENE_MODE_IPC) {
reg_param->cime_multi_comb.cime_multi0 = 8;
reg_param->cime_multi_comb.cime_multi1 = 12;
reg_param->cime_multi_comb.cime_multi2 = 16;
reg_param->cime_multi_comb.cime_multi3 = 20;
} else {
reg_param->cime_multi_comb.cime_multi0 = 4;
reg_param->cime_multi_comb.cime_multi1 = 4;
reg_param->cime_multi_comb.cime_multi2 = 4;
reg_param->cime_multi_comb.cime_multi3 = 4;
}
}
/* RIME && FME */
if (sm == MPP_ENC_SCENE_MODE_IPC) {
reg_param->rime_mvd_th_comb.rime_mvd_th0 = 1;
reg_param->rime_mvd_th_comb.rime_mvd_th1 = 2;
reg_param->rime_mvd_th_comb.fme_madp_th = 0;
reg_param->rime_madp_th_comb.rime_madp_th0 = 8;
reg_param->rime_madp_th_comb.rime_madp_th1 = 16;
reg_param->rime_multi_comb.rime_multi0 = 4;
reg_param->rime_multi_comb.rime_multi1 = 8;
reg_param->rime_multi_comb.rime_multi2 = 12;
} else {
reg_param->rime_mvd_th_comb.rime_mvd_th0 = 0;
reg_param->rime_mvd_th_comb.rime_mvd_th1 = 0;
reg_param->rime_mvd_th_comb.fme_madp_th = 30;
reg_param->rime_madp_th_comb.rime_madp_th0 = 0;
reg_param->rime_madp_th_comb.rime_madp_th1 = 0;
reg_param->rime_multi_comb.rime_multi0 = 4;
reg_param->rime_multi_comb.rime_multi1 = 4;
reg_param->rime_multi_comb.rime_multi2 = 4;
}
{
/* 0x1770 */
regs->reg_param.rime_mvd_th_comb.rime_mvd_th0 = 1;
regs->reg_param.rime_mvd_th_comb.rime_mvd_th1 = 2;
regs->reg_param.rime_mvd_th_comb.fme_madp_th = 0;
/* 0x1774 */
regs->reg_param.rime_madp_th_comb.rime_madp_th0 = 8;
regs->reg_param.rime_madp_th_comb.rime_madp_th1 = 16;
/* 0x1778 */
regs->reg_param.rime_multi_comb.rime_multi0 = 4;
regs->reg_param.rime_multi_comb.rime_multi1 = 8;
regs->reg_param.rime_multi_comb.rime_multi2 = 12;
/* 0x1064 */
regs->reg_rc_roi.madi_st_thd.madi_th0 = 5;
regs->reg_rc_roi.madi_st_thd.madi_th1 = 12;
regs->reg_rc_roi.madi_st_thd.madi_th2 = 20;
/* 0x1068 */
regs->reg_rc_roi.madp_st_thd0.madp_th0 = 4 << 4;
regs->reg_rc_roi.madp_st_thd0.madp_th1 = 9 << 4;
/* 0x106C */
regs->reg_rc_roi.madp_st_thd1.madp_th2 = 15 << 4;
/* 0x177C */
regs->reg_param.cmv_st_th_comb.cmv_th0 = 64;
regs->reg_param.cmv_st_th_comb.cmv_th1 = 96;
regs->reg_param.cmv_st_th_comb.cmv_th2 = 128;
reg_param->cmv_st_th_comb.cmv_th0 = 64;
reg_param->cmv_st_th_comb.cmv_th1 = 96;
reg_param->cmv_st_th_comb.cmv_th2 = 128;
}
}
@@ -798,6 +871,11 @@ MPP_RET hal_h265e_v510_deinit(void *hal)
ctx->reg_cfg = NULL;
}
if (ctx->tune) {
vepu510_h265e_tune_deinit(ctx->tune);
ctx->tune = NULL;
}
hal_h265e_leave();
return MPP_OK;
}
@@ -875,6 +953,8 @@ MPP_RET hal_h265e_v510_init(void *hal, MppEncHalCfg *cfg)
ctx->output_cb = cfg->output_cb;
cfg->cap_recn_out = 1;
ctx->tune = vepu510_h265e_tune_init(ctx);
DONE:
if (ret)
hal_h265e_v510_deinit(hal);
@@ -1019,7 +1099,6 @@ static MPP_RET vepu510_h265_set_rc_regs(H265eV510HalContext *ctx, H265eV510RegSe
if (rc->rc_mode == MPP_ENC_RC_MODE_FIXQP) {
reg_frm->common.enc_pic.pic_qp = rc_cfg->quality_target;
reg_frm->synt_sli1.sli_qp = rc_cfg->quality_target;
reg_frm->common.rc_qp.rc_max_qp = rc_cfg->quality_target;
reg_frm->common.rc_qp.rc_min_qp = rc_cfg->quality_target;
} else {
@@ -1041,6 +1120,25 @@ static MPP_RET vepu510_h265_set_rc_regs(H265eV510HalContext *ctx, H265eV510RegSe
reg_frm->common.rc_qp.rc_min_qp = rc_cfg->quality_min;
reg_frm->common.rc_tgt.ctu_ebit = ctu_target_bits_mul_16;
{
/* fixed frame qp */
RK_S32 fqp_min, fqp_max;
if (ctx->frame_type == INTRA_FRAME) {
fqp_min = rc->fqp_min_i;
fqp_max = rc->fqp_max_i;
} else {
fqp_min = rc->fqp_min_p;
fqp_max = rc->fqp_max_p;
}
if ((fqp_min == fqp_max) && (fqp_min >= 0) && (fqp_max <= 51)) {
reg_frm->common.enc_pic.pic_qp = fqp_min;
reg_frm->synt_sli1.sli_qp = fqp_min;
reg_frm->common.rc_qp.rc_qp_range = 0;
}
}
reg_rc->rc_dthd_0_8[0] = 2 * negative_bits_thd;
reg_rc->rc_dthd_0_8[1] = negative_bits_thd;
reg_rc->rc_dthd_0_8[2] = positive_bits_thd;
@@ -1230,7 +1328,7 @@ static void vepu510_h265_set_slice_regs(H265eSyntax_new *syn, H265eVepu510Frame
regs->synt_sli1.sp_dblk_fltr_dis = syn->sp.sli_dblk_fltr_dis;
regs->synt_sli1.dblk_fltr_ovrd_flg = syn->sp.dblk_fltr_ovrd_flg;
regs->synt_sli1.sli_cb_qp_ofst = syn->sp.sli_cb_qp_ofst;
regs->synt_sli1.max_mrg_cnd = syn->sp.max_mrg_cnd;
regs->synt_sli1.max_mrg_cnd = 3;//syn->sp.max_mrg_cnd;
regs->synt_sli1.col_ref_idx = syn->sp.col_ref_idx;
regs->synt_sli1.col_frm_l0_flg = syn->sp.col_frm_l0_flg;
@@ -1295,7 +1393,8 @@ static void vepu510_h265_set_me_regs(H265eV510HalContext *ctx, H265eSyntax_new *
regs->common.me_cach.colmv_stor_hevc = 1;
}
regs->common.me_cach.cime_zero_thre = 1024;
regs->common.me_cach.cime_zero_thre = (ctx->cfg->tune.scene_mode ==
MPP_ENC_SCENE_MODE_IPC) ? 1024 : 64;
regs->common.me_cach.fme_prefsu_en = 0;
}
@@ -1567,6 +1666,7 @@ MPP_RET hal_h265e_v510_gen_regs(void *hal, HalEncTask *task)
Vepu510ControlCfg *reg_ctl = &regs->reg_ctl;
H265eVepu510Frame *reg_frm = &regs->reg_frm;
Vepu510RcRoi *reg_klut = &regs->reg_rc_roi;
MppEncSceneMode sm = ctx->cfg->tune.scene_mode;
MPP_RET ret = MPP_OK;
hal_h265e_enter();
@@ -1633,7 +1733,7 @@ MPP_RET hal_h265e_v510_gen_regs(void *hal, HalEncTask *task)
reg_frm->common.src_proc.tile4x4_en = 0;
reg_klut->klut_ofst.chrm_klut_ofst = (ctx->frame_type == INTRA_FRAME) ? 6 :
(ctx->cfg->tune.scene_mode == MPP_ENC_SCENE_MODE_IPC ? 9 : 6);
(sm == MPP_ENC_SCENE_MODE_IPC ? 9 : 6);
reg_frm->sao_cfg.sao_lambda_multi = 5;
@@ -1646,10 +1746,10 @@ MPP_RET hal_h265e_v510_gen_regs(void *hal, HalEncTask *task)
reg_frm->rdo_cfg.chrm_spcl = 0;
reg_frm->rdo_cfg.cu_inter_e = 0xdb;
reg_frm->rdo_cfg.lambda_qp_use_avg_cu16_flag = 1;
reg_frm->rdo_cfg.lambda_qp_use_avg_cu16_flag = (sm == MPP_ENC_SCENE_MODE_IPC);
reg_frm->rdo_cfg.yuvskip_calc_en = 1;
reg_frm->rdo_cfg.atf_e = 1;
reg_frm->rdo_cfg.atr_e = 1;
reg_frm->rdo_cfg.atf_e = (sm == MPP_ENC_SCENE_MODE_IPC);
reg_frm->rdo_cfg.atr_e = (sm == MPP_ENC_SCENE_MODE_IPC);
if (syn->pp.num_long_term_ref_pics_sps) {
reg_frm->rdo_cfg.ltm_col = 0;
@@ -1693,6 +1793,7 @@ MPP_RET hal_h265e_v510_gen_regs(void *hal, HalEncTask *task)
ctx->cfg->prep.width, ctx->cfg->prep.height);
/*paramet cfg*/
vepu510_h265_global_cfg_set(ctx, regs);
vepu510_h265e_tune_reg_patch(ctx->tune);
/* two pass register patch */
if (frm->save_pass1)
@@ -1848,8 +1949,7 @@ static MPP_RET vepu510_h265_set_feedback(H265eV510HalContext *ctx, HalEncTask *e
Vepu510H265eFrmCfg *frm = ctx->frms[enc_task->flags.reg_idx];
Vepu510H265Fbk *fb = &frm->feedback;
MppEncCfgSet *cfg = ctx->cfg;
RK_S32 mb64_num = ((cfg->prep.width + 63) / 64) * ((cfg->prep.height + 63) / 64);
RK_S32 mb8_num = (mb64_num << 6);
RK_S32 mb8_num = MPP_ALIGN(cfg->prep.width, 8) * MPP_ALIGN(cfg->prep.height, 8) / 64;
RK_S32 mb4_num = (mb8_num << 2);
H265eV510StatusElem *elem = (H265eV510StatusElem *)frm->regs_ret;
RK_U32 hw_status = elem->hw_status;
@@ -1902,36 +2002,15 @@ static MPP_RET vepu510_h265_set_feedback(H265eV510HalContext *ctx, HalEncTask *e
fb->st_lvl4_intra_num += elem->st.st_pnum_i4.pnum_i4;
memcpy(&fb->st_cu_num_qp[0], &elem->st.st_b8_qp, 52 * sizeof(RK_U32));
hal_rc_ret->bit_real += fb->out_strm_size * 8;
if (fb->st_mb_num) {
fb->st_madi = fb->st_madi / fb->st_mb_num;
} else {
fb->st_madi = 0;
}
if (fb->st_ctu_num) {
fb->st_madp = fb->st_madp / fb->st_ctu_num;
} else {
fb->st_madp = 0;
}
if (mb4_num > 0)
hal_rc_ret->iblk4_prop = ((((fb->st_lvl4_intra_num + fb->st_lvl8_intra_num) << 2) +
(fb->st_lvl16_intra_num << 4) +
(fb->st_lvl32_intra_num << 6)) << 8) / mb4_num;
if (mb64_num > 0) {
/*
hal_cfg[k].inter_lv8_prop = ((fb->st_lvl8_inter_num + (fb->st_lvl16_inter_num << 2) +
(fb->st_lvl32_inter_num << 4) +
(fb->st_lvl64_inter_num << 6)) << 8) / mb8_num;*/
if (mb8_num > 0) {
hal_rc_ret->quality_real = fb->qp_sum / mb8_num;
// hal_cfg[k].sse = fb->sse_sum / mb64_num;
}
hal_rc_ret->madi = fb->st_madi;
hal_rc_ret->madp = fb->st_madp;
hal_h265e_leave();
return MPP_OK;
}
@@ -2207,8 +2286,9 @@ MPP_RET hal_h265e_v510_ret_task(void *hal, HalEncTask *task)
h265e_dpb_hal_end(ctx->dpb, frm->hal_curr_idx);
h265e_dpb_hal_end(ctx->dpb, frm->hal_refr_idx);
hal_h265e_dbg_detail("output stream size %d\n", fb->out_strm_size);
vepu510_h265e_tune_stat_update(ctx->tune, enc_task);
hal_h265e_dbg_detail("output stream size %d\n", fb->out_strm_size);
hal_h265e_leave();
return MPP_OK;
}

View File

@@ -0,0 +1,241 @@
/*
* Copyright 2024 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 "hal_enc_task.h"
#include "hal_h265e_vepu510_reg.h"
typedef struct HalH265eVepu510Tune_t {
H265eV510HalContext *ctx;
RK_S32 pre_madp[2];
RK_S32 pre_madi[2];
} HalH265eVepu510Tune;
static HalH265eVepu510Tune *vepu510_h265e_tune_init(H265eV510HalContext *ctx)
{
HalH265eVepu510Tune *tune = mpp_malloc(HalH265eVepu510Tune, 1);
if (NULL == tune)
return tune;
tune->ctx = ctx;
tune->pre_madi[0] = tune->pre_madi[1] = -1;
tune->pre_madp[0] = tune->pre_madp[1] = -1;
return tune;
}
static void vepu510_h265e_tune_deinit(void *tune)
{
MPP_FREE(tune);
}
static void vepu510_h265e_tune_aq(HalH265eVepu510Tune *tune)
{
H265eV510HalContext *ctx = tune->ctx;
Vepu510H265eFrmCfg *frm_cfg = ctx->frm;
H265eV510RegSet *regs = frm_cfg->regs_set;
Vepu510RcRoi *r = &regs->reg_rc_roi;
r->aq_stp0.aq_stp_s0 = -8;
r->aq_stp0.aq_stp_0t1 = -7;
r->aq_stp0.aq_stp_1t2 = -6;
r->aq_stp0.aq_stp_2t3 = -5;
r->aq_stp0.aq_stp_3t4 = -4;
r->aq_stp0.aq_stp_4t5 = -3;
r->aq_stp1.aq_stp_5t6 = -2;
r->aq_stp1.aq_stp_6t7 = -1;
r->aq_stp1.aq_stp_7t8 = 0;
r->aq_stp1.aq_stp_8t9 = 1;
r->aq_stp1.aq_stp_9t10 = 2;
r->aq_stp1.aq_stp_10t11 = 3;
r->aq_stp2.aq_stp_11t12 = 4;
r->aq_stp2.aq_stp_12t13 = 5;
r->aq_stp2.aq_stp_13t14 = 6;
r->aq_stp2.aq_stp_14t15 = 7;
r->aq_stp2.aq_stp_b15 = 8;
r->aq_clip.aq16_rnge = 5;
r->aq_clip.aq32_rnge = 5;
r->aq_clip.aq8_rnge = 10;
r->aq_clip.aq16_dif0 = 12;
r->aq_clip.aq16_dif1 = 12;
}
static void vepu510_h265e_tune_reg_patch(void *p)
{
HalH265eVepu510Tune *tune = (HalH265eVepu510Tune *)p;
H265eV510HalContext *ctx = NULL;
RK_S32 scene_mode = 0;
(void)ctx;
(void)scene_mode;
if (NULL == tune)
return;
vepu510_h265e_tune_aq(tune);
}
static void vepu510_h265e_tune_stat_update(void *p, HalEncTask *task)
{
HalH265eVepu510Tune *tune = (HalH265eVepu510Tune *)p;
EncRcTaskInfo *hal_rc_ret = (EncRcTaskInfo *)&task->rc_task->info;
if (NULL == tune)
return;
H265eV510HalContext *ctx = tune->ctx;;
RK_S32 task_idx = task->flags.reg_idx;
Vepu510H265eFrmCfg *frm = ctx->frms[task_idx];
Vepu510H265Fbk *fb = &frm->feedback;
H265eV510RegSet *regs_set = frm->regs_set;
H265eV510StatusElem *elem = frm->regs_ret;
MppEncCfgSet *cfg = ctx->cfg;
RK_U32 b16_num = MPP_ALIGN(cfg->prep.width, 16) * MPP_ALIGN(cfg->prep.height, 16) / 256;
RK_U32 madi_cnt = 0, madp_cnt = 0;
RK_S32 i = 0;
RK_U32 madi_th_cnt0 = elem->st.st_madi_lt_num0.madi_th_lt_cnt0 +
elem->st.st_madi_rt_num0.madi_th_rt_cnt0 +
elem->st.st_madi_lb_num0.madi_th_lb_cnt0 +
elem->st.st_madi_rb_num0.madi_th_rb_cnt0;
RK_U32 madi_th_cnt1 = elem->st.st_madi_lt_num0.madi_th_lt_cnt1 +
elem->st.st_madi_rt_num0.madi_th_rt_cnt1 +
elem->st.st_madi_lb_num0.madi_th_lb_cnt1 +
elem->st.st_madi_rb_num0.madi_th_rb_cnt1;
RK_U32 madi_th_cnt2 = elem->st.st_madi_lt_num1.madi_th_lt_cnt2 +
elem->st.st_madi_rt_num1.madi_th_rt_cnt2 +
elem->st.st_madi_lb_num1.madi_th_lb_cnt2 +
elem->st.st_madi_rb_num1.madi_th_rb_cnt2;
RK_U32 madi_th_cnt3 = elem->st.st_madi_lt_num1.madi_th_lt_cnt3 +
elem->st.st_madi_rt_num1.madi_th_rt_cnt3 +
elem->st.st_madi_lb_num1.madi_th_lb_cnt3 +
elem->st.st_madi_rb_num1.madi_th_rb_cnt3;
RK_U32 madp_th_cnt0 = elem->st.st_madp_lt_num0.madp_th_lt_cnt0 +
elem->st.st_madp_rt_num0.madp_th_rt_cnt0 +
elem->st.st_madp_lb_num0.madp_th_lb_cnt0 +
elem->st.st_madp_rb_num0.madp_th_rb_cnt0;
RK_U32 madp_th_cnt1 = elem->st.st_madp_lt_num0.madp_th_lt_cnt1 +
elem->st.st_madp_rt_num0.madp_th_rt_cnt1 +
elem->st.st_madp_lb_num0.madp_th_lb_cnt1 +
elem->st.st_madp_rb_num0.madp_th_rb_cnt1;
RK_U32 madp_th_cnt2 = elem->st.st_madp_lt_num1.madp_th_lt_cnt2 +
elem->st.st_madp_rt_num1.madp_th_rt_cnt2 +
elem->st.st_madp_lb_num1.madp_th_lb_cnt2 +
elem->st.st_madp_rb_num1.madp_th_rb_cnt2;
RK_U32 madp_th_cnt3 = elem->st.st_madp_lt_num1.madp_th_lt_cnt3 +
elem->st.st_madp_rt_num1.madp_th_rt_cnt3 +
elem->st.st_madp_lb_num1.madp_th_lb_cnt3 +
elem->st.st_madp_rb_num1.madp_th_rb_cnt3;
madi_cnt = (6 * madi_th_cnt3 + 5 * madi_th_cnt2 + 4 * madi_th_cnt1) >> 2;
hal_rc_ret->complex_level = (madi_cnt * 100 > 30 * b16_num) ? 2 :
(madi_cnt * 100 > 13 * b16_num) ? 1 : 0;
{
RK_U32 md_cnt = 0, motion_level = 0;
if (ctx->smart_en)
md_cnt = (12 * madp_th_cnt3 + 11 * madp_th_cnt2 + 8 * madp_th_cnt1) >> 2;
else
md_cnt = (24 * madp_th_cnt3 + 22 * madp_th_cnt2 + 17 * madp_th_cnt1) >> 2;
if (md_cnt * 100 > 15 * b16_num)
motion_level = 200;
else if (md_cnt * 100 > 5 * b16_num)
motion_level = 100;
else if (md_cnt * 100 > (b16_num >> 2))
motion_level = 1;
else
motion_level = 0;
hal_rc_ret->motion_level = motion_level;
}
hal_h265e_dbg_output("complex_level %d motion_level %d\n",
hal_rc_ret->complex_level, hal_rc_ret->motion_level);
fb->st_madi = madi_th_cnt0 * regs_set->reg_rc_roi.madi_st_thd.madi_th0 +
madi_th_cnt1 * (regs_set->reg_rc_roi.madi_st_thd.madi_th0 +
regs_set->reg_rc_roi.madi_st_thd.madi_th1) / 2 +
madi_th_cnt2 * (regs_set->reg_rc_roi.madi_st_thd.madi_th1 +
regs_set->reg_rc_roi.madi_st_thd.madi_th2) / 2 +
madi_th_cnt3 * regs_set->reg_rc_roi.madi_st_thd.madi_th2;
madi_cnt = madi_th_cnt0 + madi_th_cnt1 + madi_th_cnt2 + madi_th_cnt3;
if (madi_cnt)
fb->st_madi = fb->st_madi / madi_cnt;
fb->st_madp = madp_th_cnt0 * regs_set->reg_rc_roi.madp_st_thd0.madp_th0 +
madp_th_cnt1 * (regs_set->reg_rc_roi.madp_st_thd0.madp_th0 +
regs_set->reg_rc_roi.madp_st_thd0.madp_th1) / 2 +
madp_th_cnt2 * (regs_set->reg_rc_roi.madp_st_thd0.madp_th1 +
regs_set->reg_rc_roi.madp_st_thd1.madp_th2) / 2 +
madp_th_cnt3 * regs_set->reg_rc_roi.madp_st_thd1.madp_th2;
madp_cnt = madp_th_cnt0 + madp_th_cnt1 + madp_th_cnt2 + madp_th_cnt3;
if (madp_cnt)
fb->st_madp = fb->st_madp / madp_cnt;
fb->st_mb_num += elem->st.st_bnum_b16.num_b16;
fb->frame_type = task->rc_task->frm.is_intra ? INTRA_FRAME : INTER_P_FRAME;
hal_rc_ret->bit_real += fb->out_strm_size * 8;
hal_h265e_dbg_output("bit_real %d quality_real %d\n",
hal_rc_ret->bit_real, hal_rc_ret->quality_real);
{
/* This code snippet may be unnecessary, but it is kept for rv1103b compatibility. */
RK_S32 bit_tgt = hal_rc_ret->bit_target;
RK_S32 bit_real = hal_rc_ret->bit_real;
RK_S32 real_lvl = 0;
memcpy(fb->tgt_sub_real_lvl, ctx->last_frame_fb.tgt_sub_real_lvl, 6 * sizeof(RK_S8));
for (i = 3; i >= 0; i--)
fb->tgt_sub_real_lvl[i + 1] = fb->tgt_sub_real_lvl[i];
if (bit_tgt > bit_real) {
fb->tgt_sub_real_lvl[0] = (bit_tgt > bit_real * 6 / 4) ? 3 :
(bit_tgt > bit_real * 5 / 4) ? 2 :
(bit_tgt > bit_real * 9 / 8) ? 1 : 0;
} else {
fb->tgt_sub_real_lvl[0] = (bit_real > bit_tgt * 2) ? -5 :
(bit_real > bit_tgt * 7 / 4) ? -4 :
(bit_real > bit_tgt * 6 / 4) ? -3 :
(bit_real > bit_tgt * 5 / 4) ? -2 : -1;
}
for (i = 0; i < 5; i ++)
real_lvl += fb->tgt_sub_real_lvl[i];
if (task->rc_task->frm.is_intra)
fb->tgt_sub_real_lvl[5] = 0;
if (real_lvl < -9)
fb->tgt_sub_real_lvl[5] = 2;
else if (real_lvl < -2 && fb->tgt_sub_real_lvl[5] < 2)
fb->tgt_sub_real_lvl[5] = 1;
}
if (fb->st_mb_num)
fb->st_madi = fb->st_madi / fb->st_mb_num;
else
fb->st_madi = 0;
if (fb->st_ctu_num)
fb->st_madp = fb->st_madp / fb->st_ctu_num;
else
fb->st_madp = 0;
hal_rc_ret->madi = fb->st_madi;
hal_rc_ret->madp = fb->st_madp; /* unused ?? */
}

View File

@@ -118,6 +118,7 @@ typedef struct {
RK_S32 gop_len;
RK_S32 vi_len;
RK_S32 scene_mode;
RK_S32 cu_qp_delta_depth;
RK_S64 first_frm;
RK_S64 first_pkt;
@@ -178,6 +179,7 @@ MPP_RET test_ctx_init(MpiEncMultiCtxInfo *info)
p->fps_out_den = cmd->fps_out_den;
p->fps_out_num = cmd->fps_out_num;
p->scene_mode = cmd->scene_mode;
p->cu_qp_delta_depth = cmd->cu_qp_delta_depth;
p->mdinfo_size = (MPP_VIDEO_CodingHEVC == cmd->type) ?
(MPP_ALIGN(p->hor_stride, 32) >> 5) *
(MPP_ALIGN(p->ver_stride, 32) >> 5) * 16 :
@@ -315,6 +317,8 @@ MPP_RET test_mpp_enc_cfg_setup(MpiEncMultiCtxInfo *info)
if (!p->bps)
p->bps = p->width * p->height / 8 * (p->fps_out_num / p->fps_out_den);
mpp_enc_cfg_set_s32(cfg, "rc:cu_qp_delta_depth", p->cu_qp_delta_depth);
mpp_enc_cfg_set_s32(cfg, "tune:scene_mode", p->scene_mode);
mpp_enc_cfg_set_s32(cfg, "prep:width", p->width);

View File

@@ -488,6 +488,19 @@ RK_S32 mpi_enc_opt_sm(void *ctx, const char *next)
return 0;
}
RK_S32 mpi_enc_opt_qpdd(void *ctx, const char *next)
{
MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx;
if (next) {
cmd->cu_qp_delta_depth = atoi(next);
return 1;
}
mpp_err("invalid cu_qp_delta_depth\n");
return 0;
}
RK_S32 mpi_enc_opt_help(void *ctx, const char *next)
{
(void)ctx;
@@ -518,6 +531,7 @@ static MppOptInfo enc_opts[] = {
{"ini", "ini file", "encoder extra ini config file", mpi_enc_opt_ini},
{"slt", "slt file", "slt verify data file", mpi_enc_opt_slt},
{"sm", "scene mode", "scene_mode, 0:default 1:ipc", mpi_enc_opt_sm},
{"qpdd", "cu_qp_delta_depth", "cu_qp_delta_depth, 0:1:2", mpi_enc_opt_qpdd},
};
static RK_U32 enc_opt_cnt = MPP_ARRAY_ELEMS(enc_opts);
@@ -597,9 +611,7 @@ MPP_RET mpi_enc_test_cmd_update_by_args(MpiEncTestArgs* cmd, int argc, char **ar
/* mark option end */
mpp_opt_add(opts, NULL);
ret = mpp_opt_parse(opts, argc, argv);
/* check essential parameter */
if (cmd->type <= MPP_VIDEO_CodingAutoDetect) {
mpp_err("invalid type %d\n", cmd->type);

View File

@@ -77,6 +77,9 @@ typedef struct MpiEncTestArgs_t {
/* -sm scene_mode */
RK_S32 scene_mode;
/* -qpdd cu_qp_delta_depth */
RK_S32 cu_qp_delta_depth;
/* -v q runtime log disable flag */
RK_U32 quiet;
/* -v f runtime fps log flag */