mirror of
https://github.com/nyanmisaka/mpp.git
synced 2025-10-05 17:16:50 +08:00
[vepu580]: Support intra frame twopass deflicker
NOTE: Only vepu580 support this feature. Change-Id: I05768a5ca5f6d32eab3d0d9eccab0c471882cd0e Signed-off-by: sayon.chen <sayon.chen@rock-chips.com> Signed-off-by: Herman Chen <herman.chen@rock-chips.com>
This commit is contained in:
@@ -43,7 +43,18 @@ typedef union EncFrmStatus_u {
|
|||||||
* 1 - do not write the reconstructed frame pixel to memory
|
* 1 - do not write the reconstructed frame pixel to memory
|
||||||
*/
|
*/
|
||||||
RK_U32 non_recn : 1;
|
RK_U32 non_recn : 1;
|
||||||
RK_U32 reserved0 : 2;
|
|
||||||
|
/*
|
||||||
|
* 0 - normal frame and normal dpb management
|
||||||
|
* 1 - save recon frame as first pass extra frame. Used in two pass mode
|
||||||
|
*/
|
||||||
|
RK_U32 save_pass1 : 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 0 - use normal input source frame as input
|
||||||
|
* 1 - use the previously stored first pass recon frame as input frame
|
||||||
|
*/
|
||||||
|
RK_U32 use_pass1 : 1;
|
||||||
|
|
||||||
/* reference status flag */
|
/* reference status flag */
|
||||||
/*
|
/*
|
||||||
|
@@ -75,6 +75,11 @@ MPP_RET mpp_enc_refs_dryrun(MppEncRefs refs);
|
|||||||
MPP_RET mpp_enc_refs_stash(MppEncRefs refs);
|
MPP_RET mpp_enc_refs_stash(MppEncRefs refs);
|
||||||
MPP_RET mpp_enc_refs_rollback(MppEncRefs refs);
|
MPP_RET mpp_enc_refs_rollback(MppEncRefs refs);
|
||||||
|
|
||||||
|
/* two-pass encoding functions */
|
||||||
|
/* check next frame is intra or not */
|
||||||
|
RK_S32 mpp_enc_refs_next_frm_is_intra(MppEncRefs refs);
|
||||||
|
MPP_RET mpp_enc_refs_get_cpb_pass1(MppEncRefs refs, EncCpbStatus *status);
|
||||||
|
|
||||||
#define dump_frm(frm) _dump_frm(frm, __FUNCTION__, __LINE__)
|
#define dump_frm(frm) _dump_frm(frm, __FUNCTION__, __LINE__)
|
||||||
|
|
||||||
void _dump_frm(EncFrmStatus *frm, const char *func, RK_S32 line);
|
void _dump_frm(EncFrmStatus *frm, const char *func, RK_S32 line);
|
||||||
|
@@ -757,6 +757,7 @@ MPP_RET mpp_enc_refs_get_cpb(MppEncRefs refs, EncCpbStatus *status)
|
|||||||
RefsCnt *lt_cfg = cpb->lt_cnter;
|
RefsCnt *lt_cfg = cpb->lt_cnter;
|
||||||
RK_S32 set_to_lt = 0;
|
RK_S32 set_to_lt = 0;
|
||||||
RK_S32 cleanup_cpb = 0;
|
RK_S32 cleanup_cpb = 0;
|
||||||
|
RK_S32 prev_frm_is_pass1 = frm->save_pass1;
|
||||||
RK_S32 i;
|
RK_S32 i;
|
||||||
|
|
||||||
/* step 1. check igop from cfg_set and force idr for usr_cfg */
|
/* step 1. check igop from cfg_set and force idr for usr_cfg */
|
||||||
@@ -868,6 +869,10 @@ MPP_RET mpp_enc_refs_get_cpb(MppEncRefs refs, EncCpbStatus *status)
|
|||||||
} else
|
} else
|
||||||
ref->val = 0;
|
ref->val = 0;
|
||||||
|
|
||||||
|
/* step 5. check use previous pass one frame as input */
|
||||||
|
if (prev_frm_is_pass1)
|
||||||
|
frm->use_pass1 = 1;
|
||||||
|
|
||||||
if (enc_refs_debug & MPP_ENC_REFS_DBG_FRM) {
|
if (enc_refs_debug & MPP_ENC_REFS_DBG_FRM) {
|
||||||
mpp_log_f("frm status:\n");
|
mpp_log_f("frm status:\n");
|
||||||
dump_frm(frm);
|
dump_frm(frm);
|
||||||
@@ -891,6 +896,93 @@ MPP_RET mpp_enc_refs_get_cpb(MppEncRefs refs, EncCpbStatus *status)
|
|||||||
return MPP_OK;
|
return MPP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RK_S32 mpp_enc_refs_next_frm_is_intra(MppEncRefs refs)
|
||||||
|
{
|
||||||
|
if (NULL == refs) {
|
||||||
|
mpp_err_f("invalid NULL input refs\n");
|
||||||
|
return MPP_ERR_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
enc_refs_dbg_func("enter %p\n", refs);
|
||||||
|
|
||||||
|
MppEncRefsImpl *p = (MppEncRefsImpl *)refs;
|
||||||
|
EncVirtualCpb *cpb = &p->cpb;
|
||||||
|
MppEncRefFrmUsrCfg *usr_cfg = &p->usr_cfg;
|
||||||
|
RK_S32 is_intra = 0;
|
||||||
|
|
||||||
|
if (p->changed & ENC_REFS_IGOP_CHANGED)
|
||||||
|
is_intra = 1;
|
||||||
|
|
||||||
|
if (p->igop && cpb->seq_idx >= p->igop)
|
||||||
|
is_intra = 1;
|
||||||
|
|
||||||
|
if (usr_cfg->force_flag & ENC_FORCE_IDR)
|
||||||
|
is_intra = 1;
|
||||||
|
|
||||||
|
if (!cpb->frm_idx)
|
||||||
|
is_intra = 0;
|
||||||
|
|
||||||
|
enc_refs_dbg_func("leave %p\n", refs);
|
||||||
|
|
||||||
|
return is_intra;
|
||||||
|
}
|
||||||
|
|
||||||
|
MPP_RET mpp_enc_refs_get_cpb_pass1(MppEncRefs refs, EncCpbStatus *status)
|
||||||
|
{
|
||||||
|
if (NULL == refs) {
|
||||||
|
mpp_err_f("invalid NULL input refs\n");
|
||||||
|
return MPP_ERR_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
enc_refs_dbg_func("enter %p\n", refs);
|
||||||
|
|
||||||
|
MppEncRefsImpl *p = (MppEncRefsImpl *)refs;
|
||||||
|
EncVirtualCpb *cpb = &p->cpb;
|
||||||
|
EncFrmStatus *frm = &status->curr;
|
||||||
|
EncFrmStatus *ref = &status->refr;
|
||||||
|
|
||||||
|
frm->valid = 1;
|
||||||
|
frm->save_pass1 = 1;
|
||||||
|
frm->is_non_ref = 1;
|
||||||
|
frm->is_lt_ref = 0;
|
||||||
|
frm->temporal_id = 0;
|
||||||
|
frm->ref_mode = REF_TO_PREV_REF_FRM;
|
||||||
|
frm->ref_arg = 0;
|
||||||
|
frm->non_recn = 0;
|
||||||
|
|
||||||
|
/* step 4. try find ref by the ref_mode */
|
||||||
|
EncFrmStatus *ref_found = get_ref_from_cpb(cpb, frm);
|
||||||
|
if (ref_found) {
|
||||||
|
RK_S32 cpb_idx = check_ref_cpb_pos(cpb, ref_found);
|
||||||
|
|
||||||
|
mpp_assert(cpb_idx >= 0);
|
||||||
|
cpb->list0[0].val = ref->val;
|
||||||
|
ref->val = ref_found->val;
|
||||||
|
} else
|
||||||
|
ref->val = 0;
|
||||||
|
|
||||||
|
if (enc_refs_debug & MPP_ENC_REFS_DBG_FRM) {
|
||||||
|
mpp_log_f("frm status:\n");
|
||||||
|
dump_frm(frm);
|
||||||
|
mpp_log_f("ref status:\n");
|
||||||
|
dump_frm(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* step 5. generate cpb init */
|
||||||
|
memset(status->init, 0, sizeof(status->init));
|
||||||
|
save_cpb_status(cpb, status->init);
|
||||||
|
// TODO: cpb_init must be the same to cpb_final
|
||||||
|
|
||||||
|
/* step 6. store frame according to status */
|
||||||
|
store_ref_to_cpb(cpb, frm);
|
||||||
|
|
||||||
|
/* step 7. generate cpb final */
|
||||||
|
memset(status->final, 0, sizeof(status->final));
|
||||||
|
save_cpb_status(cpb, status->final);
|
||||||
|
|
||||||
|
enc_refs_dbg_func("leave %p\n", refs);
|
||||||
|
return MPP_OK;
|
||||||
|
}
|
||||||
MPP_RET mpp_enc_refs_stash(MppEncRefs refs)
|
MPP_RET mpp_enc_refs_stash(MppEncRefs refs)
|
||||||
{
|
{
|
||||||
if (NULL == refs) {
|
if (NULL == refs) {
|
||||||
|
@@ -54,7 +54,6 @@ static MPP_RET h265e_init(void *ctx, EncImplCfg *ctrlCfg)
|
|||||||
p->cfg = ctrlCfg->cfg;
|
p->cfg = ctrlCfg->cfg;
|
||||||
|
|
||||||
memset(&p->syntax, 0, sizeof(p->syntax));
|
memset(&p->syntax, 0, sizeof(p->syntax));
|
||||||
ctrlCfg->task_count = 1;
|
|
||||||
|
|
||||||
p->extra_info = mpp_calloc(H265eExtraInfo, 1);
|
p->extra_info = mpp_calloc(H265eExtraInfo, 1);
|
||||||
|
|
||||||
|
@@ -75,7 +75,6 @@ static MPP_RET jpege_init_v2(void *ctx, EncImplCfg *cfg)
|
|||||||
p->cfg = cfg->cfg;
|
p->cfg = cfg->cfg;
|
||||||
|
|
||||||
mpp_assert(cfg->coding = MPP_VIDEO_CodingMJPEG);
|
mpp_assert(cfg->coding = MPP_VIDEO_CodingMJPEG);
|
||||||
cfg->task_count = 1;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
/* init default rc config */
|
/* init default rc config */
|
||||||
|
@@ -32,9 +32,6 @@ typedef struct EncImplCfg_t {
|
|||||||
MppClientType type;
|
MppClientType type;
|
||||||
MppEncCfgSet *cfg;
|
MppEncCfgSet *cfg;
|
||||||
MppEncRefs refs;
|
MppEncRefs refs;
|
||||||
|
|
||||||
// output
|
|
||||||
RK_S32 task_count;
|
|
||||||
} EncImplCfg;
|
} EncImplCfg;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -125,6 +125,10 @@ typedef struct MppEncImpl_t {
|
|||||||
MppEncRefs refs;
|
MppEncRefs refs;
|
||||||
MppEncRefFrmUsrCfg frm_cfg;
|
MppEncRefFrmUsrCfg frm_cfg;
|
||||||
|
|
||||||
|
/* two-pass deflicker parameters */
|
||||||
|
RK_U32 support_hw_deflicker;
|
||||||
|
EncRcTaskInfo rc_info_prev;
|
||||||
|
|
||||||
/* Encoder configure set */
|
/* Encoder configure set */
|
||||||
MppEncCfgSet cfg;
|
MppEncCfgSet cfg;
|
||||||
} MppEncImpl;
|
} MppEncImpl;
|
||||||
|
@@ -1201,6 +1201,74 @@ static MPP_RET mpp_enc_check_pkt_buf(MppEncImpl *enc)
|
|||||||
return MPP_OK;
|
return MPP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static MPP_RET mpp_enc_proc_two_pass(Mpp *mpp, EncTask *task)
|
||||||
|
{
|
||||||
|
MppEncImpl *enc = (MppEncImpl *)mpp->mEnc;
|
||||||
|
MPP_RET ret = MPP_OK;
|
||||||
|
|
||||||
|
if (mpp_enc_refs_next_frm_is_intra(enc->refs)) {
|
||||||
|
EncRcTask *rc_task = &enc->rc_task;
|
||||||
|
EncFrmStatus frm_bak = rc_task->frm;
|
||||||
|
EncRcTaskInfo rc_info = rc_task->info;
|
||||||
|
EncCpbStatus *cpb = &rc_task->cpb;
|
||||||
|
EncFrmStatus *frm = &rc_task->frm;
|
||||||
|
HalEncTask *hal_task = &task->info;
|
||||||
|
EncImpl impl = enc->impl;
|
||||||
|
MppEncHal hal = enc->enc_hal;
|
||||||
|
MppPacket packet = hal_task->packet;
|
||||||
|
RK_S32 task_len = hal_task->length;
|
||||||
|
RK_S32 hw_len = hal_task->hw_length;
|
||||||
|
RK_S32 pkt_len = mpp_packet_get_length(packet);
|
||||||
|
|
||||||
|
enc_dbg_detail("task %d two pass mode enter\n", frm->seq_idx);
|
||||||
|
rc_task->info = enc->rc_info_prev;
|
||||||
|
|
||||||
|
enc_dbg_detail("task %d enc proc dpb\n", frm->seq_idx);
|
||||||
|
mpp_enc_refs_get_cpb_pass1(enc->refs, cpb);
|
||||||
|
|
||||||
|
enc_dbg_frm_status("frm %d start ***********************************\n", cpb->curr.seq_idx);
|
||||||
|
ENC_RUN_FUNC2(enc_impl_proc_dpb, impl, hal_task, mpp, ret);
|
||||||
|
|
||||||
|
enc_dbg_detail("task %d enc proc hal\n", frm->seq_idx);
|
||||||
|
ENC_RUN_FUNC2(enc_impl_proc_hal, impl, hal_task, mpp, ret);
|
||||||
|
|
||||||
|
enc_dbg_detail("task %d hal get task\n", frm->seq_idx);
|
||||||
|
ENC_RUN_FUNC2(mpp_enc_hal_get_task, hal, hal_task, mpp, ret);
|
||||||
|
|
||||||
|
enc_dbg_detail("task %d hal generate reg\n", frm->seq_idx);
|
||||||
|
ENC_RUN_FUNC2(mpp_enc_hal_gen_regs, hal, hal_task, mpp, ret);
|
||||||
|
|
||||||
|
enc_dbg_detail("task %d hal start\n", frm->seq_idx);
|
||||||
|
ENC_RUN_FUNC2(mpp_enc_hal_start, hal, hal_task, mpp, ret);
|
||||||
|
|
||||||
|
enc_dbg_detail("task %d hal wait\n", frm->seq_idx);
|
||||||
|
ENC_RUN_FUNC2(mpp_enc_hal_wait, hal, hal_task, mpp, ret);
|
||||||
|
|
||||||
|
enc_dbg_detail("task %d hal ret task\n", frm->seq_idx);
|
||||||
|
ENC_RUN_FUNC2(mpp_enc_hal_ret_task, hal, hal_task, mpp, ret);
|
||||||
|
|
||||||
|
//recover status & packet
|
||||||
|
mpp_packet_set_length(packet, pkt_len);
|
||||||
|
hal_task->hw_length = hw_len;
|
||||||
|
hal_task->length = task_len;
|
||||||
|
|
||||||
|
*frm = frm_bak;
|
||||||
|
rc_task->info = rc_info;
|
||||||
|
|
||||||
|
enc_dbg_detail("task %d two pass mode leave\n", frm->seq_idx);
|
||||||
|
}
|
||||||
|
TASK_DONE:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mpp_enc_rc_info_backup(MppEncImpl *enc)
|
||||||
|
{
|
||||||
|
if (!enc->support_hw_deflicker || !enc->cfg.rc.debreath_en)
|
||||||
|
return;
|
||||||
|
|
||||||
|
enc->rc_info_prev = enc->rc_task.info;
|
||||||
|
}
|
||||||
|
|
||||||
static MPP_RET mpp_enc_normal(Mpp *mpp, EncTask *task)
|
static MPP_RET mpp_enc_normal(Mpp *mpp, EncTask *task)
|
||||||
{
|
{
|
||||||
MppEncImpl *enc = (MppEncImpl *)mpp->mEnc;
|
MppEncImpl *enc = (MppEncImpl *)mpp->mEnc;
|
||||||
@@ -1215,6 +1283,12 @@ static MPP_RET mpp_enc_normal(Mpp *mpp, EncTask *task)
|
|||||||
MppPacket packet = hal_task->packet;
|
MppPacket packet = hal_task->packet;
|
||||||
MPP_RET ret = MPP_OK;
|
MPP_RET ret = MPP_OK;
|
||||||
|
|
||||||
|
if (enc->support_hw_deflicker && enc->cfg.rc.debreath_en) {
|
||||||
|
ret = mpp_enc_proc_two_pass(mpp, task);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
enc_dbg_detail("task %d enc proc dpb\n", frm->seq_idx);
|
enc_dbg_detail("task %d enc proc dpb\n", frm->seq_idx);
|
||||||
mpp_enc_refs_get_cpb(enc->refs, cpb);
|
mpp_enc_refs_get_cpb(enc->refs, cpb);
|
||||||
|
|
||||||
@@ -1923,6 +1997,7 @@ TASK_DONE:
|
|||||||
mpp_task_meta_set_frame(enc->task_in, KEY_INPUT_FRAME, enc->frame);
|
mpp_task_meta_set_frame(enc->task_in, KEY_INPUT_FRAME, enc->frame);
|
||||||
mpp_port_enqueue(enc->input, enc->task_in);
|
mpp_port_enqueue(enc->input, enc->task_in);
|
||||||
|
|
||||||
|
mpp_enc_rc_info_backup(enc);
|
||||||
reset_enc_task(enc);
|
reset_enc_task(enc);
|
||||||
task->status.val = 0;
|
task->status.val = 0;
|
||||||
|
|
||||||
|
@@ -68,12 +68,12 @@ MPP_RET mpp_enc_init_v2(MppEnc *enc, MppEncInitCfg *cfg)
|
|||||||
enc_hal_cfg.cfg = &p->cfg;
|
enc_hal_cfg.cfg = &p->cfg;
|
||||||
enc_hal_cfg.type = VPU_CLIENT_BUTT;
|
enc_hal_cfg.type = VPU_CLIENT_BUTT;
|
||||||
enc_hal_cfg.dev = NULL;
|
enc_hal_cfg.dev = NULL;
|
||||||
|
enc_hal_cfg.cap_recn_out = 0;
|
||||||
|
|
||||||
ctrl_cfg.coding = coding;
|
ctrl_cfg.coding = coding;
|
||||||
ctrl_cfg.type = VPU_CLIENT_BUTT;
|
ctrl_cfg.type = VPU_CLIENT_BUTT;
|
||||||
ctrl_cfg.cfg = &p->cfg;
|
ctrl_cfg.cfg = &p->cfg;
|
||||||
ctrl_cfg.refs = p->refs;
|
ctrl_cfg.refs = p->refs;
|
||||||
ctrl_cfg.task_count = 2;
|
|
||||||
|
|
||||||
ret = mpp_enc_hal_init(&enc_hal, &enc_hal_cfg);
|
ret = mpp_enc_hal_init(&enc_hal, &enc_hal_cfg);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@@ -82,7 +82,6 @@ MPP_RET mpp_enc_init_v2(MppEnc *enc, MppEncInitCfg *cfg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ctrl_cfg.type = enc_hal_cfg.type;
|
ctrl_cfg.type = enc_hal_cfg.type;
|
||||||
ctrl_cfg.task_count = -1;
|
|
||||||
|
|
||||||
ret = enc_impl_init(&impl, &ctrl_cfg);
|
ret = enc_impl_init(&impl, &ctrl_cfg);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@@ -107,6 +106,9 @@ MPP_RET mpp_enc_init_v2(MppEnc *enc, MppEncInitCfg *cfg)
|
|||||||
p->rc_cfg_size = SZ_1K;
|
p->rc_cfg_size = SZ_1K;
|
||||||
p->rc_cfg_info = mpp_calloc_size(char, p->rc_cfg_size);
|
p->rc_cfg_info = mpp_calloc_size(char, p->rc_cfg_size);
|
||||||
|
|
||||||
|
if (enc_hal_cfg.cap_recn_out)
|
||||||
|
p->support_hw_deflicker = 1;
|
||||||
|
|
||||||
{
|
{
|
||||||
// create header packet storage
|
// create header packet storage
|
||||||
size_t size = SZ_1K;
|
size_t size = SZ_1K;
|
||||||
|
@@ -21,7 +21,6 @@
|
|||||||
|
|
||||||
typedef struct RcModelV2Ctx_t {
|
typedef struct RcModelV2Ctx_t {
|
||||||
RcCfg usr_cfg;
|
RcCfg usr_cfg;
|
||||||
EncRcTaskInfo hal_cfg;
|
|
||||||
|
|
||||||
RK_U32 frame_type;
|
RK_U32 frame_type;
|
||||||
RK_U32 last_frame_type;
|
RK_U32 last_frame_type;
|
||||||
|
@@ -474,10 +474,10 @@ MPP_RET calc_next_i_ratio(RcModelV2Ctx *ctx)
|
|||||||
MPP_RET calc_debreath_qp(RcModelV2Ctx *ctx)
|
MPP_RET calc_debreath_qp(RcModelV2Ctx *ctx)
|
||||||
{
|
{
|
||||||
rc_dbg_func("enter %p\n", ctx);
|
rc_dbg_func("enter %p\n", ctx);
|
||||||
RK_S32 qp_start_sum = 0;
|
|
||||||
RK_U8 idx2 = ctx->pre_iblk4_prop >> 5;
|
|
||||||
RK_S32 new_start_qp = 0;
|
|
||||||
RcDebreathCfg *debreath_cfg = &ctx->usr_cfg.debreath_cfg;
|
RcDebreathCfg *debreath_cfg = &ctx->usr_cfg.debreath_cfg;
|
||||||
|
RK_S32 qp_start_sum = 0;
|
||||||
|
RK_S32 new_start_qp = 0;
|
||||||
|
RK_U8 idx2 = MPP_MIN(ctx->pre_iblk4_prop >> 5, (RK_S32)sizeof(intra_qp_map) - 1);
|
||||||
|
|
||||||
static RK_S8 strength_map[36] = {
|
static RK_S8 strength_map[36] = {
|
||||||
0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4,
|
0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4,
|
||||||
@@ -485,7 +485,7 @@ MPP_RET calc_debreath_qp(RcModelV2Ctx *ctx)
|
|||||||
9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12
|
9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12
|
||||||
};
|
};
|
||||||
|
|
||||||
qp_start_sum = ctx->gop_qp_sum / ctx->gop_frm_cnt;
|
qp_start_sum = MPP_MIN(ctx->gop_qp_sum / ctx->gop_frm_cnt, (RK_S32)sizeof(strength_map) - 1);
|
||||||
|
|
||||||
rc_dbg_qp("i start_qp %d, qp_start_sum = %d, intra_lv4_prop %d",
|
rc_dbg_qp("i start_qp %d, qp_start_sum = %d, intra_lv4_prop %d",
|
||||||
ctx->start_qp, qp_start_sum, ctx->pre_iblk4_prop);
|
ctx->start_qp, qp_start_sum, ctx->pre_iblk4_prop);
|
||||||
@@ -496,8 +496,7 @@ MPP_RET calc_debreath_qp(RcModelV2Ctx *ctx)
|
|||||||
else
|
else
|
||||||
new_start_qp = qp_start_sum;
|
new_start_qp = qp_start_sum;
|
||||||
|
|
||||||
ctx->start_qp = new_start_qp;
|
ctx->start_qp = mpp_clip(new_start_qp, ctx->usr_cfg.min_i_quality, ctx->usr_cfg.max_i_quality);
|
||||||
ctx->start_qp = mpp_clip(ctx->start_qp, 20, 51);
|
|
||||||
|
|
||||||
rc_dbg_func("leave %p\n", ctx);
|
rc_dbg_func("leave %p\n", ctx);
|
||||||
return MPP_OK;
|
return MPP_OK;
|
||||||
@@ -1264,11 +1263,6 @@ MPP_RET rc_model_v2_start(void *ctx, EncRcTask *task)
|
|||||||
info->quality_min = usr_cfg->min_quality;
|
info->quality_min = usr_cfg->min_quality;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frm->is_idr) {
|
|
||||||
p->gop_frm_cnt = 0;
|
|
||||||
p->gop_qp_sum = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc_dbg_rc("seq_idx %d intra %d\n", frm->seq_idx, frm->is_intra);
|
rc_dbg_rc("seq_idx %d intra %d\n", frm->seq_idx, frm->is_intra);
|
||||||
rc_dbg_rc("bitrate [%d : %d : %d]\n", info->bit_min, info->bit_target, info->bit_max);
|
rc_dbg_rc("bitrate [%d : %d : %d]\n", info->bit_min, info->bit_target, info->bit_max);
|
||||||
rc_dbg_rc("quality [%d : %d : %d]\n", info->quality_min, info->quality_target, info->quality_max);
|
rc_dbg_rc("quality [%d : %d : %d]\n", info->quality_min, info->quality_target, info->quality_max);
|
||||||
@@ -1407,9 +1401,13 @@ MPP_RET rc_model_v2_hal_start(void *ctx, EncRcTask *task)
|
|||||||
|
|
||||||
if (!p->reenc_cnt) {
|
if (!p->reenc_cnt) {
|
||||||
p->cur_scale_qp = qp_scale;
|
p->cur_scale_qp = qp_scale;
|
||||||
if (p->usr_cfg.debreath_cfg.enable)
|
if (p->usr_cfg.debreath_cfg.enable) {
|
||||||
calc_debreath_qp(ctx);
|
calc_debreath_qp(ctx);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p->gop_frm_cnt = 0;
|
||||||
|
p->gop_qp_sum = 0;
|
||||||
} else {
|
} else {
|
||||||
qp_scale = mpp_clip(qp_scale, (info->quality_min << 6), (info->quality_max << 6));
|
qp_scale = mpp_clip(qp_scale, (info->quality_min << 6), (info->quality_max << 6));
|
||||||
p->cur_scale_qp = qp_scale;
|
p->cur_scale_qp = qp_scale;
|
||||||
|
@@ -29,6 +29,7 @@ typedef struct MppEncHalCfg_t {
|
|||||||
// output from enc_impl
|
// output from enc_impl
|
||||||
MppClientType type;
|
MppClientType type;
|
||||||
MppDev dev;
|
MppDev dev;
|
||||||
|
RK_S32 cap_recn_out;
|
||||||
} MppEncHalCfg;
|
} MppEncHalCfg;
|
||||||
|
|
||||||
typedef struct MppEncHalApi_t {
|
typedef struct MppEncHalApi_t {
|
||||||
|
@@ -49,6 +49,7 @@ typedef struct HalH264eVepu580Ctx_t {
|
|||||||
RK_S32 pixel_buf_size;
|
RK_S32 pixel_buf_size;
|
||||||
RK_S32 thumb_buf_size;
|
RK_S32 thumb_buf_size;
|
||||||
RK_S32 max_buf_cnt;
|
RK_S32 max_buf_cnt;
|
||||||
|
MppDevRegOffCfgs *offsets;
|
||||||
|
|
||||||
/* external line buffer over 4K */
|
/* external line buffer over 4K */
|
||||||
MppBufferGroup ext_line_buf_grp;
|
MppBufferGroup ext_line_buf_grp;
|
||||||
@@ -77,6 +78,9 @@ typedef struct HalH264eVepu580Ctx_t {
|
|||||||
/* finetune */
|
/* finetune */
|
||||||
void *tune;
|
void *tune;
|
||||||
|
|
||||||
|
/* two-pass deflicker */
|
||||||
|
MppBuffer buf_pass1;
|
||||||
|
|
||||||
/* register */
|
/* register */
|
||||||
HalVepu580RegSet regs_set;
|
HalVepu580RegSet regs_set;
|
||||||
} HalH264eVepu580Ctx;
|
} HalH264eVepu580Ctx;
|
||||||
@@ -146,6 +150,16 @@ static MPP_RET hal_h264e_vepu580_deinit(void *hal)
|
|||||||
p->hw_recn = NULL;
|
p->hw_recn = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (p->offsets) {
|
||||||
|
mpp_dev_multi_offset_deinit(p->offsets);
|
||||||
|
p->offsets = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p->buf_pass1) {
|
||||||
|
mpp_buffer_put(p->buf_pass1);
|
||||||
|
p->buf_pass1 = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (p->tune) {
|
if (p->tune) {
|
||||||
vepu580_h264e_tune_deinit(p->tune);
|
vepu580_h264e_tune_deinit(p->tune);
|
||||||
p->tune = NULL;
|
p->tune = NULL;
|
||||||
@@ -198,9 +212,13 @@ static MPP_RET hal_h264e_vepu580_init(void *hal, MppEncHalCfg *cfg)
|
|||||||
memcpy(hw->aq_step_i, h264_I_aq_step_default, sizeof(hw->aq_step_i));
|
memcpy(hw->aq_step_i, h264_I_aq_step_default, sizeof(hw->aq_step_i));
|
||||||
memcpy(hw->aq_step_p, h264_P_aq_step_default, sizeof(hw->aq_step_p));
|
memcpy(hw->aq_step_p, h264_P_aq_step_default, sizeof(hw->aq_step_p));
|
||||||
}
|
}
|
||||||
|
mpp_dev_multi_offset_init(&p->offsets, 24);
|
||||||
|
p->osd_cfg.reg_cfg = p->offsets;
|
||||||
|
|
||||||
p->tune = vepu580_h264e_tune_init(p);
|
p->tune = vepu580_h264e_tune_init(p);
|
||||||
|
|
||||||
|
cfg->cap_recn_out = 1;
|
||||||
|
|
||||||
DONE:
|
DONE:
|
||||||
if (ret)
|
if (ret)
|
||||||
hal_h264e_vepu580_deinit(hal);
|
hal_h264e_vepu580_deinit(hal);
|
||||||
@@ -558,6 +576,71 @@ static MPP_RET setup_vepu580_prep(HalVepu580RegSet *regs, MppEncPrepCfg *prep)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static MPP_RET vepu580_h264e_save_pass1_patch(HalVepu580RegSet *regs, HalH264eVepu580Ctx *ctx)
|
||||||
|
{
|
||||||
|
RK_S32 width_align = MPP_ALIGN(ctx->cfg->prep.width, 16);
|
||||||
|
RK_S32 height_align = MPP_ALIGN(ctx->cfg->prep.height, 16);
|
||||||
|
|
||||||
|
if (NULL == ctx->buf_pass1) {
|
||||||
|
mpp_buffer_get(NULL, &ctx->buf_pass1, width_align * height_align * 3 / 2);
|
||||||
|
if (!ctx->buf_pass1) {
|
||||||
|
mpp_err("buf_pass1 malloc fail, debreath invaild");
|
||||||
|
return MPP_NOK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
regs->reg_base.enc_pic.cur_frm_ref = 1;
|
||||||
|
regs->reg_base.rfpw_h_addr = mpp_buffer_get_fd(ctx->buf_pass1);
|
||||||
|
regs->reg_base.rfpw_b_addr = regs->reg_base.rfpw_h_addr;
|
||||||
|
regs->reg_base.enc_pic.rec_fbc_dis = 1;
|
||||||
|
mpp_dev_multi_offset_update(ctx->offsets, 164, width_align * height_align);
|
||||||
|
|
||||||
|
return MPP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static MPP_RET vepu580_h264e_use_pass1_patch(HalVepu580RegSet *regs, HalH264eVepu580Ctx *ctx)
|
||||||
|
{
|
||||||
|
MppEncPrepCfg *prep = &ctx->cfg->prep;
|
||||||
|
RK_S32 hor_stride = MPP_ALIGN(prep->width, 16);
|
||||||
|
RK_S32 ver_stride = MPP_ALIGN(prep->height, 16);
|
||||||
|
RK_S32 frame_size = hor_stride * ver_stride;
|
||||||
|
RK_S32 fd_in = mpp_buffer_get_fd(ctx->buf_pass1);
|
||||||
|
RK_S32 y_stride;
|
||||||
|
RK_S32 c_stride;
|
||||||
|
|
||||||
|
hal_h264e_dbg_func("enter\n");
|
||||||
|
|
||||||
|
regs->reg_base.src_fmt.src_cfmt = VEPU541_FMT_YUV420SP;
|
||||||
|
regs->reg_base.src_fmt.alpha_swap = 0;
|
||||||
|
regs->reg_base.src_fmt.rbuv_swap = 0;
|
||||||
|
regs->reg_base.src_fmt.out_fmt = 1;
|
||||||
|
|
||||||
|
y_stride = MPP_ALIGN(prep->width, 16);
|
||||||
|
c_stride = y_stride;
|
||||||
|
|
||||||
|
regs->reg_base.src_proc.afbcd_en = 0;
|
||||||
|
regs->reg_base.src_strd0.src_strd0 = y_stride;
|
||||||
|
regs->reg_base.src_strd1.src_strd1 = c_stride;
|
||||||
|
|
||||||
|
regs->reg_base.src_proc.src_mirr = 0;
|
||||||
|
regs->reg_base.src_proc.src_rot = 0;
|
||||||
|
regs->reg_base.src_proc.txa_en = 0;
|
||||||
|
|
||||||
|
regs->reg_base.pic_ofst.pic_ofst_y = 0;
|
||||||
|
regs->reg_base.pic_ofst.pic_ofst_x = 0;
|
||||||
|
|
||||||
|
|
||||||
|
regs->reg_base.adr_src0 = fd_in;
|
||||||
|
regs->reg_base.adr_src1 = fd_in;
|
||||||
|
regs->reg_base.adr_src2 = fd_in;
|
||||||
|
|
||||||
|
mpp_dev_multi_offset_update(ctx->offsets, 161, frame_size);
|
||||||
|
mpp_dev_multi_offset_update(ctx->offsets, 162, frame_size);
|
||||||
|
|
||||||
|
hal_h264e_dbg_func("leave\n");
|
||||||
|
return MPP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static void setup_vepu580_codec(HalVepu580RegSet *regs, H264eSps *sps,
|
static void setup_vepu580_codec(HalVepu580RegSet *regs, H264eSps *sps,
|
||||||
H264ePps *pps, H264eSlice *slice)
|
H264ePps *pps, H264eSlice *slice)
|
||||||
{
|
{
|
||||||
@@ -1056,7 +1139,7 @@ static void setup_vepu580_rc_base(HalVepu580RegSet *regs, H264eSps *sps,
|
|||||||
hal_h264e_dbg_func("leave\n");
|
hal_h264e_dbg_func("leave\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setup_vepu580_io_buf(HalVepu580RegSet *regs, MppDev dev,
|
static void setup_vepu580_io_buf(HalVepu580RegSet *regs, MppDevRegOffCfgs *offsets,
|
||||||
HalEncTask *task)
|
HalEncTask *task)
|
||||||
{
|
{
|
||||||
MppFrame frm = task->frame;
|
MppFrame frm = task->frame;
|
||||||
@@ -1131,23 +1214,10 @@ static void setup_vepu580_io_buf(HalVepu580RegSet *regs, MppDev dev,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MppDevRegOffsetCfg trans_cfg;
|
mpp_dev_multi_offset_update(offsets, 161, off_in[0]);
|
||||||
|
mpp_dev_multi_offset_update(offsets, 162, off_in[1]);
|
||||||
trans_cfg.reg_idx = 161;
|
mpp_dev_multi_offset_update(offsets, 172, siz_out);
|
||||||
trans_cfg.offset = off_in[0];
|
mpp_dev_multi_offset_update(offsets, 175, off_out);
|
||||||
mpp_dev_ioctl(dev, MPP_DEV_REG_OFFSET, &trans_cfg);
|
|
||||||
|
|
||||||
trans_cfg.reg_idx = 162;
|
|
||||||
trans_cfg.offset = off_in[1];
|
|
||||||
mpp_dev_ioctl(dev, MPP_DEV_REG_OFFSET, &trans_cfg);
|
|
||||||
|
|
||||||
trans_cfg.reg_idx = 172;
|
|
||||||
trans_cfg.offset = siz_out;
|
|
||||||
mpp_dev_ioctl(dev, MPP_DEV_REG_OFFSET, &trans_cfg);
|
|
||||||
|
|
||||||
trans_cfg.reg_idx = 175;
|
|
||||||
trans_cfg.offset = off_out;
|
|
||||||
mpp_dev_ioctl(dev, MPP_DEV_REG_OFFSET, &trans_cfg);
|
|
||||||
|
|
||||||
hal_h264e_dbg_func("leave\n");
|
hal_h264e_dbg_func("leave\n");
|
||||||
}
|
}
|
||||||
@@ -1183,13 +1253,14 @@ static void setup_vepu580_roi(HalVepu580RegSet *regs, HalH264eVepu580Ctx *ctx)
|
|||||||
hal_h264e_dbg_func("leave\n");
|
hal_h264e_dbg_func("leave\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setup_vepu580_recn_refr(HalVepu580RegSet *regs, MppDev dev,
|
static void setup_vepu580_recn_refr(HalH264eVepu580Ctx *ctx, HalVepu580RegSet *regs)
|
||||||
H264eFrmInfo *frms, HalBufs bufs,
|
|
||||||
RK_S32 fbc_hdr_size)
|
|
||||||
{
|
{
|
||||||
|
H264eFrmInfo *frms = ctx->frms;
|
||||||
|
HalBufs bufs = ctx->hw_recn;
|
||||||
|
RK_S32 fbc_hdr_size = ctx->pixel_buf_fbc_hdr_size;
|
||||||
|
|
||||||
HalBuf *curr = hal_bufs_get_buf(bufs, frms->curr_idx);
|
HalBuf *curr = hal_bufs_get_buf(bufs, frms->curr_idx);
|
||||||
HalBuf *refr = hal_bufs_get_buf(bufs, frms->refr_idx);
|
HalBuf *refr = hal_bufs_get_buf(bufs, frms->refr_idx);
|
||||||
MppDevRegOffsetCfg trans_cfg;
|
|
||||||
|
|
||||||
hal_h264e_dbg_func("enter\n");
|
hal_h264e_dbg_func("enter\n");
|
||||||
|
|
||||||
@@ -1204,10 +1275,6 @@ static void setup_vepu580_recn_refr(HalVepu580RegSet *regs, MppDev dev,
|
|||||||
regs->reg_base.rfpw_h_addr = fd;
|
regs->reg_base.rfpw_h_addr = fd;
|
||||||
regs->reg_base.rfpw_b_addr = fd;
|
regs->reg_base.rfpw_b_addr = fd;
|
||||||
regs->reg_base.dspw_addr = mpp_buffer_get_fd(buf_thumb);
|
regs->reg_base.dspw_addr = mpp_buffer_get_fd(buf_thumb);
|
||||||
|
|
||||||
trans_cfg.reg_idx = 164;
|
|
||||||
trans_cfg.offset = fbc_hdr_size;
|
|
||||||
mpp_dev_ioctl(dev, MPP_DEV_REG_OFFSET, &trans_cfg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (refr && refr->cnt) {
|
if (refr && refr->cnt) {
|
||||||
@@ -1221,12 +1288,11 @@ static void setup_vepu580_recn_refr(HalVepu580RegSet *regs, MppDev dev,
|
|||||||
regs->reg_base.rfpr_h_addr = fd;
|
regs->reg_base.rfpr_h_addr = fd;
|
||||||
regs->reg_base.rfpr_b_addr = fd;
|
regs->reg_base.rfpr_b_addr = fd;
|
||||||
regs->reg_base.dspr_addr = mpp_buffer_get_fd(buf_thumb);
|
regs->reg_base.dspr_addr = mpp_buffer_get_fd(buf_thumb);
|
||||||
|
|
||||||
trans_cfg.reg_idx = 166;
|
|
||||||
trans_cfg.offset = fbc_hdr_size;
|
|
||||||
mpp_dev_ioctl(dev, MPP_DEV_REG_OFFSET, &trans_cfg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mpp_dev_multi_offset_update(ctx->offsets, 164, fbc_hdr_size);
|
||||||
|
mpp_dev_multi_offset_update(ctx->offsets, 166, fbc_hdr_size);
|
||||||
|
|
||||||
hal_h264e_dbg_func("leave\n");
|
hal_h264e_dbg_func("leave\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1620,20 +1686,21 @@ static void setup_vepu580_l2(HalVepu580RegSet *regs, H264eSlice *slice, MppEncHw
|
|||||||
|
|
||||||
static void setup_vepu580_ext_line_buf(HalVepu580RegSet *regs, HalH264eVepu580Ctx *ctx)
|
static void setup_vepu580_ext_line_buf(HalVepu580RegSet *regs, HalH264eVepu580Ctx *ctx)
|
||||||
{
|
{
|
||||||
|
RK_S32 offset = 0;
|
||||||
|
|
||||||
if (ctx->ext_line_buf) {
|
if (ctx->ext_line_buf) {
|
||||||
MppDevRegOffsetCfg trans_cfg;
|
|
||||||
RK_S32 fd = mpp_buffer_get_fd(ctx->ext_line_buf);
|
RK_S32 fd = mpp_buffer_get_fd(ctx->ext_line_buf);
|
||||||
|
|
||||||
regs->reg_base.ebuft_addr = fd;
|
regs->reg_base.ebuft_addr = fd;
|
||||||
regs->reg_base.ebufb_addr = fd;
|
regs->reg_base.ebufb_addr = fd;
|
||||||
|
|
||||||
trans_cfg.reg_idx = 182;
|
offset = ctx->ext_line_buf_size;
|
||||||
trans_cfg.offset = ctx->ext_line_buf_size;
|
|
||||||
mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_OFFSET, &trans_cfg);
|
|
||||||
} else {
|
} else {
|
||||||
regs->reg_base.ebufb_addr = 0;
|
regs->reg_base.ebufb_addr = 0;
|
||||||
regs->reg_base.ebufb_addr = 0;
|
regs->reg_base.ebufb_addr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mpp_dev_multi_offset_update(ctx->offsets, 182, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
static MPP_RET hal_h264e_vepu580_gen_regs(void *hal, HalEncTask *task)
|
static MPP_RET hal_h264e_vepu580_gen_regs(void *hal, HalEncTask *task)
|
||||||
@@ -1644,6 +1711,8 @@ static MPP_RET hal_h264e_vepu580_gen_regs(void *hal, HalEncTask *task)
|
|||||||
H264eSps *sps = ctx->sps;
|
H264eSps *sps = ctx->sps;
|
||||||
H264ePps *pps = ctx->pps;
|
H264ePps *pps = ctx->pps;
|
||||||
H264eSlice *slice = ctx->slice;
|
H264eSlice *slice = ctx->slice;
|
||||||
|
EncRcTask *rc_task = task->rc_task;
|
||||||
|
EncFrmStatus *frm = &rc_task->frm;
|
||||||
MPP_RET ret = MPP_OK;
|
MPP_RET ret = MPP_OK;
|
||||||
|
|
||||||
hal_h264e_dbg_func("enter %p\n", hal);
|
hal_h264e_dbg_func("enter %p\n", hal);
|
||||||
@@ -1661,11 +1730,10 @@ static MPP_RET hal_h264e_vepu580_gen_regs(void *hal, HalEncTask *task)
|
|||||||
setup_vepu580_rdo_pred(regs, sps, pps, slice);
|
setup_vepu580_rdo_pred(regs, sps, pps, slice);
|
||||||
setup_vepu580_rdo_cfg(®s->reg_rdo);
|
setup_vepu580_rdo_cfg(®s->reg_rdo);
|
||||||
setup_vepu580_scl_cfg(®s->reg_scl);
|
setup_vepu580_scl_cfg(®s->reg_scl);
|
||||||
setup_vepu580_rc_base(regs, sps, slice, &cfg->hw, task->rc_task);
|
setup_vepu580_rc_base(regs, sps, slice, &cfg->hw, rc_task);
|
||||||
setup_vepu580_io_buf(regs, ctx->dev, task);
|
setup_vepu580_io_buf(regs, ctx->offsets, task);
|
||||||
setup_vepu580_roi(regs, ctx);
|
setup_vepu580_roi(regs, ctx);
|
||||||
setup_vepu580_recn_refr(regs, ctx->dev, ctx->frms, ctx->hw_recn,
|
setup_vepu580_recn_refr(ctx, regs);
|
||||||
ctx->pixel_buf_fbc_hdr_size);
|
|
||||||
|
|
||||||
regs->reg_base.meiw_addr = task->mv_info ? mpp_buffer_get_fd(task->mv_info) : 0;
|
regs->reg_base.meiw_addr = task->mv_info ? mpp_buffer_get_fd(task->mv_info) : 0;
|
||||||
|
|
||||||
@@ -1680,6 +1748,13 @@ static MPP_RET hal_h264e_vepu580_gen_regs(void *hal, HalEncTask *task)
|
|||||||
setup_vepu580_ext_line_buf(regs, ctx);
|
setup_vepu580_ext_line_buf(regs, ctx);
|
||||||
vepu580_h264e_tune_reg_patch(ctx->tune);
|
vepu580_h264e_tune_reg_patch(ctx->tune);
|
||||||
|
|
||||||
|
/* two pass register patch */
|
||||||
|
if (frm->save_pass1)
|
||||||
|
vepu580_h264e_save_pass1_patch(regs, ctx);
|
||||||
|
|
||||||
|
if (frm->use_pass1)
|
||||||
|
vepu580_h264e_use_pass1_patch(regs, ctx);
|
||||||
|
|
||||||
mpp_env_get_u32("dump_l1_reg", &dump_l1_reg, 0);
|
mpp_env_get_u32("dump_l1_reg", &dump_l1_reg, 0);
|
||||||
|
|
||||||
if (dump_l1_reg) {
|
if (dump_l1_reg) {
|
||||||
@@ -1789,6 +1864,12 @@ static MPP_RET hal_h264e_vepu580_start(void *hal, HalEncTask *task)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_OFFS, ctx->offsets);
|
||||||
|
if (ret) {
|
||||||
|
mpp_err_f("set register offsets failed %d\n", ret);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
rd_cfg.reg = &ctx->regs_set.reg_st;
|
rd_cfg.reg = &ctx->regs_set.reg_st;
|
||||||
rd_cfg.size = sizeof(ctx->regs_set.reg_st);
|
rd_cfg.size = sizeof(ctx->regs_set.reg_st);
|
||||||
rd_cfg.offset = VEPU580_STATUS_OFFSET;
|
rd_cfg.offset = VEPU580_STATUS_OFFSET;
|
||||||
@@ -1901,6 +1982,8 @@ static MPP_RET hal_h264e_vepu580_ret_task(void *hal, HalEncTask *task)
|
|||||||
|
|
||||||
vepu580_h264e_tune_stat_update(ctx->tune);
|
vepu580_h264e_tune_stat_update(ctx->tune);
|
||||||
|
|
||||||
|
mpp_dev_multi_offset_reset(ctx->offsets);
|
||||||
|
|
||||||
hal_h264e_dbg_func("leave %p\n", hal);
|
hal_h264e_dbg_func("leave %p\n", hal);
|
||||||
|
|
||||||
return MPP_OK;
|
return MPP_OK;
|
||||||
|
@@ -87,6 +87,7 @@ typedef struct H265eV580HalContext_t {
|
|||||||
MppBufferGroup tile_grp;
|
MppBufferGroup tile_grp;
|
||||||
MppBuffer hw_tile_buf[2];
|
MppBuffer hw_tile_buf[2];
|
||||||
MppBuffer hw_tile_stream;
|
MppBuffer hw_tile_stream;
|
||||||
|
MppBuffer buf_pass1;
|
||||||
|
|
||||||
RK_U32 enc_mode;
|
RK_U32 enc_mode;
|
||||||
RK_U32 frame_size;
|
RK_U32 frame_size;
|
||||||
@@ -1172,6 +1173,9 @@ MPP_RET hal_h265e_v580_init(void *hal, MppEncHalCfg *cfg)
|
|||||||
|
|
||||||
ctx->tile_parall_en = cap->send_cmd > MPP_CMD_SET_SESSION_FD;
|
ctx->tile_parall_en = cap->send_cmd > MPP_CMD_SET_SESSION_FD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cfg->cap_recn_out = 1;
|
||||||
|
|
||||||
hal_h265e_leave();
|
hal_h265e_leave();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -1211,6 +1215,11 @@ MPP_RET hal_h265e_v580_deinit(void *hal)
|
|||||||
ctx->tile_grp = NULL;
|
ctx->tile_grp = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ctx->buf_pass1) {
|
||||||
|
mpp_buffer_put(ctx->buf_pass1);
|
||||||
|
ctx->buf_pass1 = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (ctx->dev) {
|
if (ctx->dev) {
|
||||||
mpp_dev_deinit(ctx->dev);
|
mpp_dev_deinit(ctx->dev);
|
||||||
ctx->dev = NULL;
|
ctx->dev = NULL;
|
||||||
@@ -1308,18 +1317,14 @@ vepu580_h265_set_patch_info(MppDevRegOffCfgs *cfgs, H265eSyntax_new *syn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* input cb addr */
|
/* input cb addr */
|
||||||
if (u_offset) {
|
|
||||||
ret = mpp_dev_multi_offset_update(cfgs, 161, u_offset);
|
ret = mpp_dev_multi_offset_update(cfgs, 161, u_offset);
|
||||||
if (ret)
|
if (ret)
|
||||||
mpp_err_f("set input cb addr offset failed %d\n", ret);
|
mpp_err_f("set input cb addr offset failed %d\n", ret);
|
||||||
}
|
|
||||||
|
|
||||||
/* input cr addr */
|
/* input cr addr */
|
||||||
if (v_offset) {
|
|
||||||
ret = mpp_dev_multi_offset_update(cfgs, 162, v_offset);
|
ret = mpp_dev_multi_offset_update(cfgs, 162, v_offset);
|
||||||
if (ret)
|
if (ret)
|
||||||
mpp_err_f("set input cr addr offset failed %d\n", ret);
|
mpp_err_f("set input cr addr offset failed %d\n", ret);
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -1850,6 +1855,7 @@ void vepu580_h265_set_hw_address(H265eV580HalContext *ctx, hevc_vepu580_base *re
|
|||||||
if (!syn->sp.non_reference_flag) {
|
if (!syn->sp.non_reference_flag) {
|
||||||
regs->reg0163_rfpw_h_addr = mpp_buffer_get_fd(recon_buf->buf[0]);
|
regs->reg0163_rfpw_h_addr = mpp_buffer_get_fd(recon_buf->buf[0]);
|
||||||
regs->reg0164_rfpw_b_addr = regs->reg0163_rfpw_h_addr;
|
regs->reg0164_rfpw_b_addr = regs->reg0163_rfpw_h_addr;
|
||||||
|
|
||||||
mpp_dev_multi_offset_update(ctx->reg_cfg, 164, ctx->fbc_header_len);
|
mpp_dev_multi_offset_update(ctx->reg_cfg, 164, ctx->fbc_header_len);
|
||||||
}
|
}
|
||||||
regs->reg0165_rfpr_h_addr = mpp_buffer_get_fd(ref_buf->buf[0]);
|
regs->reg0165_rfpr_h_addr = mpp_buffer_get_fd(ref_buf->buf[0]);
|
||||||
@@ -1899,15 +1905,76 @@ void vepu580_h265_set_hw_address(H265eV580HalContext *ctx, hevc_vepu580_base *re
|
|||||||
|
|
||||||
mpp_dev_multi_offset_update(ctx->reg_cfg, 175, mpp_packet_get_length(task->packet));
|
mpp_dev_multi_offset_update(ctx->reg_cfg, 175, mpp_packet_get_length(task->packet));
|
||||||
mpp_dev_multi_offset_update(ctx->reg_cfg, 172, mpp_buffer_get_size(enc_task->output));
|
mpp_dev_multi_offset_update(ctx->reg_cfg, 172, mpp_buffer_get_size(enc_task->output));
|
||||||
|
}
|
||||||
|
|
||||||
regs->reg0204_pic_ofst.pic_ofst_y = mpp_frame_get_offset_y(task->frame);
|
static MPP_RET vepu580_h265e_save_pass1_patch(H265eV580RegSet *regs, H265eV580HalContext *ctx,
|
||||||
regs->reg0204_pic_ofst.pic_ofst_x = mpp_frame_get_offset_x(task->frame);
|
RK_S32 tiles_enabled_flag)
|
||||||
|
{
|
||||||
|
hevc_vepu580_base *reg_base = ®s->reg_base;
|
||||||
|
RK_S32 width_align = MPP_ALIGN(ctx->cfg->prep.width, 64);
|
||||||
|
RK_S32 height_align = MPP_ALIGN(ctx->cfg->prep.height, 64);
|
||||||
|
|
||||||
|
if (NULL == ctx->buf_pass1) {
|
||||||
|
mpp_buffer_get(NULL, &ctx->buf_pass1, width_align * height_align * 3 / 2);
|
||||||
|
if (!ctx->buf_pass1) {
|
||||||
|
mpp_err("buf_pass1 malloc fail, debreath invaild");
|
||||||
|
return MPP_NOK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reg_base->reg0192_enc_pic.cur_frm_ref = 1;
|
||||||
|
reg_base->reg0163_rfpw_h_addr = mpp_buffer_get_fd(ctx->buf_pass1);
|
||||||
|
reg_base->reg0164_rfpw_b_addr = reg_base->reg0163_rfpw_h_addr;
|
||||||
|
reg_base->reg0192_enc_pic.rec_fbc_dis = 1;
|
||||||
|
|
||||||
|
if (tiles_enabled_flag)
|
||||||
|
reg_base->reg0238_synt_pps.lpf_fltr_acrs_til = 0;
|
||||||
|
|
||||||
|
mpp_dev_multi_offset_update(ctx->reg_cfg, 164, width_align * height_align);
|
||||||
|
|
||||||
|
return MPP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static MPP_RET vepu580_h265e_use_pass1_patch(H265eV580RegSet *regs, H265eV580HalContext *ctx,
|
||||||
|
H265eSyntax_new *syn)
|
||||||
|
{
|
||||||
|
hevc_vepu580_control_cfg *reg_ctl = ®s->reg_ctl;
|
||||||
|
hevc_vepu580_base *reg_base = ®s->reg_base;
|
||||||
|
RK_U32 hor_stride = MPP_ALIGN(syn->pp.pic_width, 64);
|
||||||
|
RK_U32 ver_stride = MPP_ALIGN(syn->pp.pic_height, 64);
|
||||||
|
RK_U32 frame_size = hor_stride * ver_stride;
|
||||||
|
RK_S32 stridey = MPP_ALIGN(syn->pp.pic_width, 64);
|
||||||
|
VepuFmtCfg *fmt = (VepuFmtCfg *)ctx->input_fmt;
|
||||||
|
MPP_RET ret = MPP_OK;
|
||||||
|
|
||||||
|
reg_ctl->reg0012_dtrns_map.src_bus_edin = fmt->src_endian;
|
||||||
|
reg_base->reg0198_src_fmt.src_cfmt = VEPU541_FMT_YUV420SP;
|
||||||
|
reg_base->reg0198_src_fmt.out_fmt = 1;
|
||||||
|
reg_base->reg0205_src_strd0.src_strd0 = stridey;
|
||||||
|
reg_base->reg0206_src_strd1.src_strd1 = stridey;
|
||||||
|
reg_base->reg0160_adr_src0 = mpp_buffer_get_fd(ctx->buf_pass1);
|
||||||
|
reg_base->reg0161_adr_src1 = reg_base->reg0160_adr_src0;
|
||||||
|
reg_base->reg0162_adr_src2 = reg_base->reg0160_adr_src0;
|
||||||
|
|
||||||
|
/* input cb addr */
|
||||||
|
ret = mpp_dev_multi_offset_update(ctx->reg_cfg, 161, frame_size);
|
||||||
|
if (ret)
|
||||||
|
mpp_err_f("set input cb addr offset failed %d\n", ret);
|
||||||
|
|
||||||
|
/* input cr addr */
|
||||||
|
ret = mpp_dev_multi_offset_update(ctx->reg_cfg, 162, frame_size);
|
||||||
|
if (ret)
|
||||||
|
mpp_err_f("set input cr addr offset failed %d\n", ret);
|
||||||
|
|
||||||
|
return MPP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
MPP_RET hal_h265e_v580_gen_regs(void *hal, HalEncTask *task)
|
MPP_RET hal_h265e_v580_gen_regs(void *hal, HalEncTask *task)
|
||||||
{
|
{
|
||||||
H265eV580HalContext *ctx = (H265eV580HalContext *)hal;
|
H265eV580HalContext *ctx = (H265eV580HalContext *)hal;
|
||||||
HalEncTask *enc_task = task;
|
HalEncTask *enc_task = task;
|
||||||
|
EncRcTask *rc_task = enc_task->rc_task;
|
||||||
|
EncFrmStatus *frm = &rc_task->frm;
|
||||||
H265eSyntax_new *syn = (H265eSyntax_new *)enc_task->syntax.data;
|
H265eSyntax_new *syn = (H265eSyntax_new *)enc_task->syntax.data;
|
||||||
H265eV580RegSet *regs = (H265eV580RegSet *)ctx->regs[0];
|
H265eV580RegSet *regs = (H265eV580RegSet *)ctx->regs[0];
|
||||||
RK_U32 pic_width_align8, pic_height_align8;
|
RK_U32 pic_width_align8, pic_height_align8;
|
||||||
@@ -2041,6 +2108,13 @@ MPP_RET hal_h265e_v580_gen_regs(void *hal, HalEncTask *task)
|
|||||||
|
|
||||||
vepu580_h265e_tune_reg_patch(ctx->tune);
|
vepu580_h265e_tune_reg_patch(ctx->tune);
|
||||||
|
|
||||||
|
/* two pass register patch */
|
||||||
|
if (frm->save_pass1)
|
||||||
|
vepu580_h265e_save_pass1_patch(regs, ctx, syn->pp.tiles_enabled_flag);
|
||||||
|
|
||||||
|
if (frm->use_pass1)
|
||||||
|
vepu580_h265e_use_pass1_patch(regs, ctx, syn);
|
||||||
|
|
||||||
ctx->frame_num++;
|
ctx->frame_num++;
|
||||||
|
|
||||||
hal_h265e_leave();
|
hal_h265e_leave();
|
||||||
@@ -2131,11 +2205,14 @@ MPP_RET hal_h265e_v580_start(void *hal, HalEncTask *enc_task)
|
|||||||
hal_h265e_v580_set_uniform_tile(&hw_regs->reg_base, syn, k);
|
hal_h265e_v580_set_uniform_tile(&hw_regs->reg_base, syn, k);
|
||||||
|
|
||||||
if (k) {
|
if (k) {
|
||||||
if (!ctx->tile_parall_en) {
|
RK_U32 offset = 0;
|
||||||
RK_U32 offset = mpp_packet_get_length(enc_task->packet);
|
|
||||||
|
|
||||||
|
if (!ctx->tile_parall_en) {
|
||||||
|
offset = mpp_packet_get_length(enc_task->packet);
|
||||||
offset += stream_len;
|
offset += stream_len;
|
||||||
|
|
||||||
reg_base->reg0173_bsbb_addr = mpp_buffer_get_fd(enc_task->output);
|
reg_base->reg0173_bsbb_addr = mpp_buffer_get_fd(enc_task->output);
|
||||||
|
|
||||||
mpp_dev_multi_offset_update(ctx->reg_cfg, 175, offset);
|
mpp_dev_multi_offset_update(ctx->reg_cfg, 175, offset);
|
||||||
mpp_dev_multi_offset_update(ctx->reg_cfg, 172, mpp_buffer_get_size(enc_task->output));
|
mpp_dev_multi_offset_update(ctx->reg_cfg, 172, mpp_buffer_get_size(enc_task->output));
|
||||||
} else {
|
} else {
|
||||||
@@ -2147,8 +2224,17 @@ MPP_RET hal_h265e_v580_start(void *hal, HalEncTask *enc_task)
|
|||||||
mpp_dev_multi_offset_update(ctx->reg_cfg, 175, 0);
|
mpp_dev_multi_offset_update(ctx->reg_cfg, 175, 0);
|
||||||
mpp_dev_multi_offset_update(ctx->reg_cfg, 172, mpp_buffer_get_size(ctx->hw_tile_stream));
|
mpp_dev_multi_offset_update(ctx->reg_cfg, 172, mpp_buffer_get_size(ctx->hw_tile_stream));
|
||||||
}
|
}
|
||||||
mpp_dev_multi_offset_update(ctx->reg_cfg, 164, ctx->fbc_header_len);
|
|
||||||
mpp_dev_multi_offset_update(ctx->reg_cfg, 166, ctx->fbc_header_len);
|
offset = ctx->fbc_header_len;
|
||||||
|
|
||||||
|
mpp_dev_multi_offset_update(ctx->reg_cfg, 166, offset);
|
||||||
|
mpp_dev_multi_offset_update(ctx->reg_cfg, 164, offset);
|
||||||
|
|
||||||
|
if (enc_task->rc_task->frm.save_pass1)
|
||||||
|
vepu580_h265e_save_pass1_patch(hw_regs, ctx, syn->pp.tiles_enabled_flag);
|
||||||
|
|
||||||
|
if (enc_task->rc_task->frm.use_pass1)
|
||||||
|
vepu580_h265e_use_pass1_patch(hw_regs, ctx, syn);
|
||||||
}
|
}
|
||||||
hal_h265e_v580_send_regs(ctx->dev, hw_regs, reg_out);
|
hal_h265e_v580_send_regs(ctx->dev, hw_regs, reg_out);
|
||||||
|
|
||||||
|
@@ -961,11 +961,6 @@ RET:
|
|||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
static const char *name_of_gop_mode[] = {
|
|
||||||
"normal_p",
|
|
||||||
"smart_p",
|
|
||||||
};
|
|
||||||
|
|
||||||
static void *rc2_pre_dec_thread(void *param)
|
static void *rc2_pre_dec_thread(void *param)
|
||||||
{
|
{
|
||||||
MpiRc2TestCtx *ctx = (MpiRc2TestCtx *)param;
|
MpiRc2TestCtx *ctx = (MpiRc2TestCtx *)param;
|
||||||
@@ -1057,16 +1052,19 @@ static MPP_RET mpi_rc_codec(MpiRc2TestCtx *ctx)
|
|||||||
ctx->frm_idx, elapsed_time / 1000, frame_rate);
|
ctx->frm_idx, elapsed_time / 1000, frame_rate);
|
||||||
|
|
||||||
if (ctx->frm_idx) {
|
if (ctx->frm_idx) {
|
||||||
mpp_log("%s: %s: average: bps %d | psnr %5.2f | ssim %5.5f", ctx->enc_cmd->file_input,
|
MpiEncTestArgs* enc_cmd = ctx->enc_cmd;
|
||||||
name_of_gop_mode[ctx->enc_cmd->gop_mode],
|
|
||||||
|
mpp_log("%s: %s: average: bps %d | psnr %5.2f | ssim %5.5f",
|
||||||
|
enc_cmd->file_input, enc_cmd->gop_mode ? "smart_p" : "normal_p",
|
||||||
30 * (RK_U32)(ctx->total_bits / ctx->frm_idx),
|
30 * (RK_U32)(ctx->total_bits / ctx->frm_idx),
|
||||||
ctx->total_psnrs / ctx->frm_idx, ctx->total_ssims / ctx->frm_idx);
|
ctx->total_psnrs / ctx->frm_idx, ctx->total_ssims / ctx->frm_idx);
|
||||||
if (ctx->file.fp_stat)
|
if (ctx->file.fp_stat)
|
||||||
fprintf(ctx->file.fp_stat, "%s: %s: average: bps %dk | psnr %5.2f | ssim %5.5f \n", ctx->enc_cmd->file_input,
|
fprintf(ctx->file.fp_stat, "%s: %s: average: bps %dk | psnr %5.2f | ssim %5.5f \n",
|
||||||
name_of_gop_mode[ctx->enc_cmd->gop_mode],
|
enc_cmd->file_input, enc_cmd->gop_mode ? "smart_p" : "normal_p",
|
||||||
30 * (RK_U32)(ctx->total_bits / ctx->frm_idx) / 1000,
|
30 * (RK_U32)(ctx->total_bits / ctx->frm_idx) / 1000,
|
||||||
ctx->total_psnrs / ctx->frm_idx, ctx->total_ssims / ctx->frm_idx);
|
ctx->total_psnrs / ctx->frm_idx, ctx->total_ssims / ctx->frm_idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
CHECK_RET(ctx->enc_mpi->reset(ctx->enc_ctx));
|
CHECK_RET(ctx->enc_mpi->reset(ctx->enc_ctx));
|
||||||
CHECK_RET(ctx->dec_mpi_pre->reset(ctx->dec_ctx_pre));
|
CHECK_RET(ctx->dec_mpi_pre->reset(ctx->dec_ctx_pre));
|
||||||
CHECK_RET(ctx->dec_mpi_post->reset(ctx->dec_ctx_post));
|
CHECK_RET(ctx->dec_mpi_post->reset(ctx->dec_ctx_post));
|
||||||
|
Reference in New Issue
Block a user