[rkv_h265e]: Move rc qp calc from api to hal

Change-Id: I8d64c97d3be4828feabb10fbe9077ac9a125b229
Signed-off-by: sayon.chen <sayon.chen@rock-chips.com>
This commit is contained in:
sayon.chen
2020-01-06 16:15:01 +08:00
committed by Herman Chen
parent d39238c871
commit 5380307bcc
6 changed files with 208 additions and 242 deletions

View File

@@ -31,28 +31,6 @@
extern RK_U32 h265e_debug; extern RK_U32 h265e_debug;
static RK_U32 mb_num[12] = {
0x0, 0xc8, 0x2bc, 0x4b0,
0x7d0, 0xfa0, 0x1f40, 0x3e80,
0x4e20, 0x4e20, 0x4e20, 0x4e20,
};
static RK_U32 tab_bit[12] = {
0xEC4, 0xDF2, 0xC4E, 0xB7C, 0xAAA, 0xEC4, 0x834, 0x690, 0x834, 0x834, 0x834, 0x834,
};
static RK_U8 qp_table[96] = {
0xF, 0xF, 0xF, 0xF, 0xF, 0x10, 0x12, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x19, 0x1A, 0x1B, 0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E,
0x1E, 0x1F, 0x1F, 0x20, 0x20, 0x21, 0x21, 0x21, 0x22, 0x22, 0x22,
0x22, 0x23, 0x23, 0x23, 0x24, 0x24, 0x24, 0x24, 0x24, 0x25, 0x25,
0x25, 0x25, 0x26, 0x26, 0x26, 0x26, 0x26, 0x27, 0x27, 0x27, 0x27,
0x27, 0x27, 0x28, 0x28, 0x28, 0x28, 0x29, 0x29, 0x29, 0x29, 0x29,
0x29, 0x29, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2B,
0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2C, 0x2C, 0x2C, 0x2C,
0x2C, 0x2C, 0x2C, 0x2C, 0x2D, 0x2D, 0x2D, 0x2D,
};
static MPP_RET h265e_init(void *ctx, EncImplCfg *ctrlCfg) static MPP_RET h265e_init(void *ctx, EncImplCfg *ctrlCfg)
{ {
H265eCtx *p = (H265eCtx *)ctx; H265eCtx *p = (H265eCtx *)ctx;
@@ -94,6 +72,7 @@ static MPP_RET h265e_init(void *ctx, EncImplCfg *ctrlCfg)
h265->max_i_qp = 51; h265->max_i_qp = 51;
h265->min_i_qp = 10; h265->min_i_qp = 10;
h265->ip_qp_delta = 3; h265->ip_qp_delta = 3;
h265->raw_dealt_qp = 2;
h265->max_delta_qp = 10; h265->max_delta_qp = 10;
h265->const_intra_pred = 0; h265->const_intra_pred = 0;
h265->gop_delta_qp = 0; h265->gop_delta_qp = 0;
@@ -394,21 +373,6 @@ static MPP_RET h265e_proc_dpb(void *ctx, HalEncTask *task)
return MPP_OK; return MPP_OK;
} }
static RK_S32 cal_first_i_start_qp(RK_S32 target_bit, RK_U32 total_mb)
{
RK_S32 cnt = 0, index, i;
for (i = 0; i < 11; i++) {
if (mb_num[i] > total_mb)
break;
cnt++;
}
index = (total_mb * tab_bit[cnt] - 300) / target_bit; //
index = mpp_clip(index, 4, 95);
return qp_table[index];
}
static MPP_RET h265e_proc_rc(void *ctx, HalEncTask *task) static MPP_RET h265e_proc_rc(void *ctx, HalEncTask *task)
{ {
(void)task; (void)task;
@@ -425,39 +389,6 @@ static MPP_RET h265e_proc_rc(void *ctx, HalEncTask *task)
rc_frm_start(p->rc_ctx, &frms->rc_cfg, &frms->status); rc_frm_start(p->rc_ctx, &frms->rc_cfg, &frms->status);
if (frms->seq_idx == 0 && frms->status.is_intra) {
if (h265->qp_init == -1) {
frms->start_qp = cal_first_i_start_qp(frms->rc_cfg.bit_target, frms->mb_per_frame << 4);
frms->cur_scale_qp = (frms->start_qp + h265->ip_qp_delta) << 6;
} else {
frms->start_qp = h265->qp_init;
frms->cur_scale_qp = (frms->start_qp + h265->ip_qp_delta) << 6;
}
frms->pre_i_qp = frms->cur_scale_qp >> 6;
frms->pre_p_qp = frms->cur_scale_qp >> 6;
frms->frame_type = INTRA_FRAME;
} else {
RK_S32 qp_scale = frms->cur_scale_qp + frms->rc_cfg.next_ratio;
RK_S32 start_qp = 0;
if (frms->status.is_intra) {
frms->frame_type = INTRA_FRAME;
qp_scale = mpp_clip(qp_scale, (h265->min_i_qp << 6), (h265->max_i_qp << 6));
start_qp = ((frms->pre_i_qp + ((qp_scale + frms->rc_cfg.next_i_ratio) >> 6)) >> 1);
start_qp = mpp_clip(start_qp, h265->min_i_qp, h265->max_i_qp);
frms->pre_i_qp = start_qp;
frms->start_qp = start_qp;
frms->cur_scale_qp = qp_scale;
} else {
frms->frame_type = INTER_P_FRAME;
qp_scale = mpp_clip(qp_scale, (h265->min_qp << 6), (h265->max_qp << 6));
frms->cur_scale_qp = qp_scale;
frms->start_qp = qp_scale >> 6;
}
}
p->frms.status.reencode = 0; p->frms.status.reencode = 0;
h265e_dbg_func("leave\n"); h265e_dbg_func("leave\n");
@@ -523,10 +454,7 @@ static MPP_RET h265e_update_rc(void *ctx, HalEncTask *task)
if (rc_hal_cfg->need_reenc) { if (rc_hal_cfg->need_reenc) {
p->frms.status.reencode = 1; p->frms.status.reencode = 1;
} else {
p->frms.last_frame_type = p->frms.frame_type;
} }
h265e_dbg_func("leave\n"); h265e_dbg_func("leave\n");
return MPP_OK; return MPP_OK;
} }

View File

@@ -22,10 +22,10 @@
#include "mpp_rc.h" #include "mpp_rc.h"
#include "h265e_syntax.h" #include "h265e_syntax.h"
#include "h265e_syntax_new.h"
#include "h265e_dpb.h" #include "h265e_dpb.h"
#include "enc_impl_api.h" #include "enc_impl_api.h"
#include "rc_api.h" #include "rc_api.h"
#include "rc.h"
#define H265E_DBG_FUNCTION (0x00000001) #define H265E_DBG_FUNCTION (0x00000001)
#define H265E_DBG_INPUT (0x00000010) #define H265E_DBG_INPUT (0x00000010)
@@ -55,36 +55,6 @@ extern RK_U32 h265e_debug;
#define h265e_dbg_dpb(fmt, ...) h265e_dbg(H265E_DBG_DPB, fmt, ## __VA_ARGS__) #define h265e_dbg_dpb(fmt, ...) h265e_dbg(H265E_DBG_DPB, fmt, ## __VA_ARGS__)
#define h265e_dbg_slice(fmt, ...) h265e_dbg(H265E_DBG_SLICE, fmt, ## __VA_ARGS__) #define h265e_dbg_slice(fmt, ...) h265e_dbg(H265E_DBG_SLICE, fmt, ## __VA_ARGS__)
/*
* Split reference frame configure to two parts
* The first part is slice depended info like poc / frame_num, and frame
* type and flags.
* The other part is gop structure depended info like gop index, ref_status
* and ref_frm_index. This part is inited from dpb gop hierarchy info.
*/
typedef struct H265eFrmInfo_s {
RK_S32 seq_idx;
RK_S32 curr_idx;
RK_S32 refr_idx;
// current frame rate control and dpb status info
RK_S32 mb_per_frame;
RK_S32 mb_raw;
RK_S32 mb_wid;
RK_S32 frame_type;
RK_S32 last_frame_type;
RK_S32 cur_scale_qp;
RK_S32 pre_i_qp;
RK_S32 pre_p_qp;
RK_S32 start_qp;
RcHalCfg rc_cfg;
EncFrmStatus status;
RK_S32 usage[MAX_REFS + 1];
} H265eFrmInfo;
typedef struct H265eCtx_t { typedef struct H265eCtx_t {
MppEncCfgSet *cfg; MppEncCfgSet *cfg;
MppEncCfgSet *set; MppEncCfgSet *set;
@@ -107,7 +77,7 @@ typedef struct H265eCtx_t {
void *extra_info; void *extra_info;
void *param_buf; void *param_buf;
MppPacket packeted_param; MppPacket packeted_param;
H265eSyntax syntax; H265eSyntax_new syntax;
H265eFeedback feedback; H265eFeedback feedback;
struct list_head rc_list; struct list_head rc_list;
} H265eCtx; } H265eCtx;

View File

@@ -340,74 +340,10 @@ RK_S32 fill_ref_parameters(const H265eCtx *h, H265eSlicParams *sp)
} }
RK_S32 fill_rc_parameters(H265eCtx *h, RcParams *rp) RK_S32 fill_frm_info(H265eCtx *h, H265eFrmInfo *syn_frms)
{ {
H265eFrmInfo *frms = &h->frms; H265eFrmInfo *frms = &h->frms;
MppEncRcCfg *rc = &h->cfg->rc; memcpy(syn_frms, frms, sizeof(*frms));
RcHalCfg *rc_cfg = &frms->rc_cfg;
MppEncCodecCfg *codec = &h->cfg->codec;
MppEncH265Cfg *h265 = &codec->h265;
RK_U32 i;
RK_U32 ctu_target_bits_mul_16 = (rc_cfg->bit_target << 4) / frms->mb_per_frame;
RK_U32 ctu_target_bits;
RK_S32 negative_bits_thd, positive_bits_thd;
memset(rp, 0, sizeof(RcParams));
if (ctu_target_bits_mul_16 >= 0x100000) {
ctu_target_bits_mul_16 = 0x50000;
}
ctu_target_bits = (ctu_target_bits_mul_16 * frms->mb_wid) >> 4;
negative_bits_thd = 0 - ctu_target_bits / 4;
positive_bits_thd = ctu_target_bits / 4;
if (rc->rc_mode == MPP_ENC_RC_MODE_FIXQP) {
rp->pic_qp = h265->qp_init;
rp->rc_max_qp = h265->qp_init;
rp->rc_min_qp = h265->qp_init;
return 0;
}
rp->rc_en = 1;
rp->rc_qp_range = 2;
rp->pic_qp = frms->start_qp;
if (frms->status.is_intra) {
rp->rc_max_qp = h265->max_i_qp;
rp->rc_min_qp = h265->min_i_qp;
} else {
rp->rc_max_qp = h265->max_qp;
rp->rc_min_qp = h265->min_qp;
}
rp->frame_type = frms->status.is_intra ? 2 : 0;
rp->rc_ctu_num = frms->mb_wid;
rp->ctu_ebits = ctu_target_bits_mul_16;
rp->bits_thd[0] = negative_bits_thd;
rp->bits_thd[1] = positive_bits_thd;
rp->bits_thd[2] = positive_bits_thd;
rp->bits_thd[3] = positive_bits_thd;
rp->bits_thd[4] = positive_bits_thd;
rp->bits_thd[5] = positive_bits_thd;
rp->bits_thd[6] = positive_bits_thd;
rp->bits_thd[7] = positive_bits_thd;
rp->bits_thd[8] = positive_bits_thd;
rp->qp_adjust[0] = -1;
rp->qp_adjust[1] = 0;
rp->qp_adjust[2] = 0;
rp->qp_adjust[3] = 0;
rp->qp_adjust[4] = 0;
rp->qp_adjust[5] = 0;
rp->qp_adjust[6] = 0;
rp->qp_adjust[7] = 0;
rp->qp_adjust[8] = 1;
for ( i = 0; i < 8; i++) {
rp->qpmax_area[i] = h265->qpmax_map[i];
rp->qpmin_area[i] = h265->qpmin_map[i];
}
rp->qpmap_mode = h265->qpmap_mode;
return 0; return 0;
} }
@@ -418,7 +354,7 @@ RK_S32 h265e_syntax_fill(void *ctx)
fill_picture_parameters(h, &syn->pp); fill_picture_parameters(h, &syn->pp);
fill_slice_parameters(h, &syn->sp); fill_slice_parameters(h, &syn->sp);
fill_ref_parameters(h, &syn->sp); fill_ref_parameters(h, &syn->sp);
fill_rc_parameters(h, &syn->rp); fill_frm_info(h, &syn->frms);
syn->ud.plt_data = NULL; syn->ud.plt_data = NULL;
if (h->plt_flag) { if (h->plt_flag) {
syn->ud.plt_data = (void*)&h->cfg->osd_plt; syn->ud.plt_data = (void*)&h->cfg->osd_plt;

View File

@@ -17,6 +17,8 @@
#ifndef __H265E_SYNTAX_NEW_H__ #ifndef __H265E_SYNTAX_NEW_H__
#define __H265E_SYNTAX_NEW_H__ #define __H265E_SYNTAX_NEW_H__
#include "mpp_rc.h" #include "mpp_rc.h"
#include "h265_syntax.h"
#include "rc.h"
typedef struct H265PicEntry_t { typedef struct H265PicEntry_t {
RK_U8 bPicEntry[3]; RK_U8 bPicEntry[3];
@@ -188,24 +190,31 @@ typedef struct H265eSlicParams_t {
RK_U32 sli_splt_byte; RK_U32 sli_splt_byte;
RK_U32 tot_poc_num; RK_U32 tot_poc_num;
} H265eSlicParams; } H265eSlicParams;
/*
* Split reference frame configure to two parts
* The first part is slice depended info like poc / frame_num, and frame
* type and flags.
* The other part is gop structure depended info like gop index, ref_status
* and ref_frm_index. This part is inited from dpb gop hierarchy info.
*/
typedef struct RcParams_t { typedef struct H265eFrmInfo_s {
RK_U8 rc_en; RK_S32 seq_idx;
RK_U8 pic_qp;
RK_U8 frame_type; RK_S32 curr_idx;
RK_U8 coding_type; RK_S32 refr_idx;
RK_U8 rc_qp_range;
RK_U8 rc_max_qp; // current frame rate control and dpb status info
RK_U8 rc_min_qp; RK_S32 mb_per_frame;
RK_U16 rc_ctu_num; RK_S32 mb_raw;
RK_U32 ctu_ebits; RK_S32 mb_wid;
RK_S32 bits_thd[9]; RK_S32 frame_type;
RK_S8 qp_adjust[9]; RK_S32 last_frame_type;
RK_U8 qpmax_area[8];
RK_U8 qpmin_area[8]; RcHalCfg rc_cfg;
RK_U8 qpmap_mode; EncFrmStatus status;
RK_U32 bit_target; RK_S32 usage[MAX_REFS + 1];
} RcParams; } H265eFrmInfo;
typedef struct UserDatas_t { typedef struct UserDatas_t {
void *plt_data; void *plt_data;
@@ -215,8 +224,8 @@ typedef struct H265eSyntax_new_t {
RK_S32 idr_request; RK_S32 idr_request;
H265ePicParams pp; H265ePicParams pp;
H265eSlicParams sp; H265eSlicParams sp;
RcParams rp;
UserDatas ud; UserDatas ud;
H265eFrmInfo frms;
} H265eSyntax_new; } H265eSyntax_new;
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -128,6 +128,43 @@ RK_U32 lamd_modb_qp[52] = {
0x00700000, 0x00890000, 0x00b00000, 0x00e00000 0x00700000, 0x00890000, 0x00b00000, 0x00e00000
}; };
static RK_U32 mb_num[12] = {
0x0, 0xc8, 0x2bc, 0x4b0,
0x7d0, 0xfa0, 0x1f40, 0x3e80,
0x4e20, 0x4e20, 0x4e20, 0x4e20,
};
static RK_U32 tab_bit[12] = {
0xEC4, 0xDF2, 0xC4E, 0xB7C, 0xAAA, 0xEC4, 0x834, 0x690, 0x834, 0x834, 0x834, 0x834,
};
static RK_U8 qp_table[96] = {
0xF, 0xF, 0xF, 0xF, 0xF, 0x10, 0x12, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x19, 0x1A, 0x1B, 0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E,
0x1E, 0x1F, 0x1F, 0x20, 0x20, 0x21, 0x21, 0x21, 0x22, 0x22, 0x22,
0x22, 0x23, 0x23, 0x23, 0x24, 0x24, 0x24, 0x24, 0x24, 0x25, 0x25,
0x25, 0x25, 0x26, 0x26, 0x26, 0x26, 0x26, 0x27, 0x27, 0x27, 0x27,
0x27, 0x27, 0x28, 0x28, 0x28, 0x28, 0x29, 0x29, 0x29, 0x29, 0x29,
0x29, 0x29, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2B,
0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2C, 0x2C, 0x2C, 0x2C,
0x2C, 0x2C, 0x2C, 0x2C, 0x2D, 0x2D, 0x2D, 0x2D,
};
static RK_S32 cal_first_i_start_qp(RK_S32 target_bit, RK_U32 total_mb)
{
RK_S32 cnt = 0, index, i;
for (i = 0; i < 11; i++) {
if (mb_num[i] > total_mb)
break;
cnt++;
}
index = (total_mb * tab_bit[cnt] - 300) / target_bit; //
index = mpp_clip(index, 4, 95);
return qp_table[index];
}
static MPP_RET h265e_rkv_free_buffers(H265eRkvHalContext *ctx) static MPP_RET h265e_rkv_free_buffers(H265eRkvHalContext *ctx)
{ {
@@ -358,8 +395,8 @@ MPP_RET hal_h265e_rkv_init(void *hal, MppEncHalCfg *cfg)
ctx->ioctl_output = mpp_calloc(H265eRkvIoctlOutput, 1); ctx->ioctl_output = mpp_calloc(H265eRkvIoctlOutput, 1);
ctx->regs = mpp_calloc(H265eRkvRegSet, RKVE_LINKTABLE_FRAME_NUM); ctx->regs = mpp_calloc(H265eRkvRegSet, RKVE_LINKTABLE_FRAME_NUM);
ctx->l2_regs = mpp_calloc(H265eRkvL2RegSet, RKVE_LINKTABLE_FRAME_NUM); ctx->l2_regs = mpp_calloc(H265eRkvL2RegSet, RKVE_LINKTABLE_FRAME_NUM);
ctx->rc_hal_cfg = mpp_calloc(H265eRkvL2RegSet, RKVE_LINKTABLE_FRAME_NUM); ctx->rc_hal_cfg = mpp_calloc(RcHalCfg, RKVE_LINKTABLE_FRAME_NUM);
ctx->buffers = mpp_calloc(RcHalCfg, RKVE_LINKTABLE_FRAME_NUM); ctx->buffers = mpp_calloc(h265e_hal_rkv_buffers, RKVE_LINKTABLE_FRAME_NUM);
ctx->set = cfg->set; ctx->set = cfg->set;
ctx->cfg = cfg->cfg; ctx->cfg = cfg->cfg;
@@ -607,56 +644,125 @@ h265e_rkv_set_roi_regs(H265eRkvHalContext *ctx, H265eRkvRegSet *regs)
return MPP_OK; return MPP_OK;
} }
static MPP_RET h265e_rkv_set_rc_regs(H265eRkvRegSet *regs, H265eSyntax_new *syn) static MPP_RET h265e_rkv_set_rc_regs(H265eRkvHalContext *ctx, H265eRkvRegSet *regs, H265eSyntax_new *syn)
{ {
regs->enc_pic.pic_qp = syn->rp.pic_qp; H265eFrmInfo *frms = &syn->frms;
regs->rc_cfg.rc_en = syn->rp.rc_en; MppEncCfgSet *cfg = ctx->cfg;
regs->synt_sli1.sli_qp = syn->rp.pic_qp; MppEncRcCfg *rc = &cfg->rc;
RcHalCfg *rc_cfg = &frms->rc_cfg;
MppEncCodecCfg *codec = &cfg->codec;
MppEncH265Cfg *h265 = &codec->h265;
RK_U32 ctu_target_bits_mul_16 = (rc_cfg->bit_target << 4) / frms->mb_per_frame;
RK_U32 ctu_target_bits;
RK_S32 negative_bits_thd, positive_bits_thd;
regs->rc_cfg.rc_ctu_num = syn->rp.rc_ctu_num; if (frms->seq_idx == 0 && frms->status.is_intra) {
regs->rc_qp.rc_qp_range = syn->rp.rc_qp_range; if (h265->qp_init == -1) {
regs->rc_qp.rc_max_qp = syn->rp.rc_max_qp; ctx->start_qp = cal_first_i_start_qp(frms->rc_cfg.bit_target, frms->mb_per_frame << 4);
regs->rc_qp.rc_min_qp = syn->rp.rc_min_qp; ctx->cur_scale_qp = (ctx->start_qp + h265->ip_qp_delta) << 6;
regs->rc_tgt.ctu_ebits = syn->rp.ctu_ebits; } else {
regs->rc_erp0.bits_thd0 = syn->rp.bits_thd[0]; ctx->start_qp = h265->qp_init;
regs->rc_erp1.bits_thd1 = syn->rp.bits_thd[1]; ctx->cur_scale_qp = (ctx->start_qp + h265->ip_qp_delta) << 6;
regs->rc_erp2.bits_thd2 = syn->rp.bits_thd[2]; }
regs->rc_erp3.bits_thd3 = syn->rp.bits_thd[3];
regs->rc_erp4.bits_thd4 = syn->rp.bits_thd[4];
regs->rc_erp5.bits_thd5 = syn->rp.bits_thd[5];
regs->rc_erp6.bits_thd6 = syn->rp.bits_thd[6];
regs->rc_erp7.bits_thd7 = syn->rp.bits_thd[7];
regs->rc_erp8.bits_thd8 = syn->rp.bits_thd[8];
regs->rc_adj0.qp_adjust0 = syn->rp.qp_adjust[0]; ctx->pre_i_qp = ctx->cur_scale_qp >> 6;
regs->rc_adj0.qp_adjust1 = syn->rp.qp_adjust[1]; ctx->pre_p_qp = ctx->cur_scale_qp >> 6;
regs->rc_adj0.qp_adjust2 = syn->rp.qp_adjust[2]; } else {
regs->rc_adj0.qp_adjust3 = syn->rp.qp_adjust[3]; RK_S32 qp_scale = ctx->cur_scale_qp + frms->rc_cfg.next_ratio;
regs->rc_adj0.qp_adjust4 = syn->rp.qp_adjust[4]; RK_S32 start_qp = 0;
regs->rc_adj1.qp_adjust5 = syn->rp.qp_adjust[5];
regs->rc_adj1.qp_adjust6 = syn->rp.qp_adjust[6];
regs->rc_adj1.qp_adjust7 = syn->rp.qp_adjust[7];
regs->rc_adj1.qp_adjust8 = syn->rp.qp_adjust[8];
regs->qpmap0.qpmin_area0 = syn->rp.qpmin_area[1]; if (frms->status.is_intra) {
regs->qpmap0.qpmax_area0 = syn->rp.qpmax_area[1]; qp_scale = mpp_clip(qp_scale, (h265->min_i_qp << 6), (h265->max_i_qp << 6));
regs->qpmap0.qpmin_area1 = syn->rp.qpmin_area[1]; start_qp = ((ctx->pre_i_qp + ((qp_scale + frms->rc_cfg.next_i_ratio) >> 6)) >> 1);
regs->qpmap0.qpmax_area1 = syn->rp.qpmax_area[2];
regs->qpmap0.qpmin_area2 = syn->rp.qpmin_area[2];
regs->qpmap1.qpmax_area2 = syn->rp.qpmax_area[2];
regs->qpmap1.qpmin_area3 = syn->rp.qpmin_area[3];
regs->qpmap1.qpmax_area3 = syn->rp.qpmax_area[3];
regs->qpmap1.qpmin_area4 = syn->rp.qpmin_area[4];
regs->qpmap1.qpmax_area4 = syn->rp.qpmax_area[4];
regs->qpmap2.qpmin_area5 = syn->rp.qpmin_area[5];
regs->qpmap2.qpmax_area5 = syn->rp.qpmax_area[5];
regs->qpmap2.qpmin_area6 = syn->rp.qpmin_area[6];
regs->qpmap2.qpmax_area6 = syn->rp.qpmax_area[6];
regs->qpmap2.qpmin_area7 = syn->rp.qpmin_area[7];
regs->qpmap3.qpmax_area7 = syn->rp.qpmax_area[7];
regs->qpmap3.qpmap_mode = syn->rp.qpmap_mode;
start_qp = mpp_clip(start_qp, h265->min_i_qp, h265->max_i_qp);
ctx->pre_i_qp = start_qp;
ctx->start_qp = start_qp;
ctx->cur_scale_qp = qp_scale;
} else {
qp_scale = mpp_clip(qp_scale, (h265->min_qp << 6), (h265->max_qp << 6));
ctx->cur_scale_qp = qp_scale;
ctx->start_qp = qp_scale >> 6;
}
}
if (rc->rc_mode == MPP_ENC_RC_MODE_FIXQP) {
regs->enc_pic.pic_qp = h265->qp_init;
regs->synt_sli1.sli_qp = h265->qp_init;
regs->rc_qp.rc_max_qp = h265->qp_init;
regs->rc_qp.rc_min_qp = h265->qp_init;
} else {
RK_S32 rc_max_qp, rc_min_qp;
if (ctu_target_bits_mul_16 >= 0x100000) {
ctu_target_bits_mul_16 = 0x50000;
}
ctu_target_bits = (ctu_target_bits_mul_16 * frms->mb_wid) >> 4;
negative_bits_thd = 0 - ctu_target_bits / 4;
positive_bits_thd = ctu_target_bits / 4;
if (frms->status.is_intra) {
rc_max_qp = h265->max_i_qp;
rc_min_qp = h265->min_i_qp;
} else {
rc_max_qp = h265->max_qp;
rc_min_qp = h265->min_qp;
}
mpp_log("ctx->start_qp = %d", ctx->start_qp);
regs->enc_pic.pic_qp = ctx->start_qp;
regs->rc_cfg.rc_en = 1;
regs->synt_sli1.sli_qp = ctx->start_qp;
regs->rc_cfg.rc_ctu_num = frms->mb_wid;
regs->rc_qp.rc_qp_range = h265->raw_dealt_qp;
regs->rc_qp.rc_max_qp = rc_max_qp;
regs->rc_qp.rc_min_qp = rc_min_qp;
regs->rc_tgt.ctu_ebits = ctu_target_bits_mul_16;
regs->rc_erp0.bits_thd0 = negative_bits_thd;
regs->rc_erp1.bits_thd1 = positive_bits_thd;
regs->rc_erp2.bits_thd2 = positive_bits_thd;
regs->rc_erp3.bits_thd3 = positive_bits_thd;
regs->rc_erp4.bits_thd4 = positive_bits_thd;
regs->rc_erp5.bits_thd5 = positive_bits_thd;
regs->rc_erp6.bits_thd6 = positive_bits_thd;
regs->rc_erp7.bits_thd7 = positive_bits_thd;
regs->rc_erp8.bits_thd8 = positive_bits_thd;
regs->rc_adj0.qp_adjust0 = -1;
regs->rc_adj0.qp_adjust1 = 0;
regs->rc_adj0.qp_adjust2 = 0;
regs->rc_adj0.qp_adjust3 = 0;
regs->rc_adj0.qp_adjust4 = 0;
regs->rc_adj1.qp_adjust5 = 0;
regs->rc_adj1.qp_adjust6 = 0;
regs->rc_adj1.qp_adjust7 = 0;
regs->rc_adj1.qp_adjust8 = 1;
regs->qpmap0.qpmin_area0 = h265->qpmin_map[0];
regs->qpmap0.qpmax_area0 = h265->qpmax_map[0];
regs->qpmap0.qpmin_area1 = h265->qpmin_map[1];
regs->qpmap0.qpmax_area1 = h265->qpmax_map[1];
regs->qpmap0.qpmin_area2 = h265->qpmin_map[2];
regs->qpmap1.qpmax_area2 = h265->qpmax_map[2];
regs->qpmap1.qpmin_area3 = h265->qpmin_map[3];
regs->qpmap1.qpmax_area3 = h265->qpmax_map[3];
regs->qpmap1.qpmin_area4 = h265->qpmin_map[4];
regs->qpmap1.qpmax_area4 = h265->qpmax_map[4];
regs->qpmap2.qpmin_area5 = h265->qpmin_map[5];
regs->qpmap2.qpmax_area5 = h265->qpmax_map[5];
regs->qpmap2.qpmin_area6 = h265->qpmin_map[6];
regs->qpmap2.qpmax_area6 = h265->qpmax_map[6];
regs->qpmap2.qpmin_area7 = h265->qpmin_map[7];
regs->qpmap3.qpmax_area7 = h265->qpmax_map[7];
regs->qpmap3.qpmap_mode = h265->qpmap_mode;
}
if (ctx->frame_type == INTRA_FRAME) {
regs->enc_pic.rdo_wgt_sel = 0;
} else {
regs->enc_pic.rdo_wgt_sel = 1;
}
regs->dtrns_cfg.cime_dspw_orsd = (ctx->frame_type == INTER_P_FRAME);
return MPP_OK; return MPP_OK;
} }
@@ -808,7 +914,7 @@ MPP_RET hal_h265e_rkv_gen_regs(void *hal, HalEncTask *task)
fbc_header_len = (pic_wd64 * pic_h64) << 6; fbc_header_len = (pic_wd64 * pic_h64) << 6;
h265e_hal_dbg(H265E_DBG_SIMPLE, h265e_hal_dbg(H265E_DBG_SIMPLE,
"frame %d | type %d | start gen regs", "frame %d | type %d | start gen regs",
ctx->frame_cnt, syn->rp.frame_type); ctx->frame_cnt, ctx->frame_type);
if (ctx->enc_mode == 2 || ctx->enc_mode == 3) { //link table mode if (ctx->enc_mode == 2 || ctx->enc_mode == 3) { //link table mode
RK_U32 idx = ctx->frame_cnt_gen_ready; RK_U32 idx = ctx->frame_cnt_gen_ready;
@@ -859,7 +965,7 @@ MPP_RET hal_h265e_rkv_gen_regs(void *hal, HalEncTask *task)
regs->enc_pic.node_int = 0; regs->enc_pic.node_int = 0;
regs->enc_pic.log2_ctu_num = ceil(log2((double)pic_wd64 * pic_h64)); regs->enc_pic.log2_ctu_num = ceil(log2((double)pic_wd64 * pic_h64));
if (syn->rp.frame_type == INTRA_FRAME) { if (ctx->frame_type == INTRA_FRAME) {
regs->enc_pic.rdo_wgt_sel = 0; regs->enc_pic.rdo_wgt_sel = 0;
} else { } else {
regs->enc_pic.rdo_wgt_sel = 1; regs->enc_pic.rdo_wgt_sel = 1;
@@ -868,7 +974,7 @@ MPP_RET hal_h265e_rkv_gen_regs(void *hal, HalEncTask *task)
regs->enc_wdg.vs_load_thd = 0; regs->enc_wdg.vs_load_thd = 0;
regs->enc_wdg.rfp_load_thd = 0; regs->enc_wdg.rfp_load_thd = 0;
regs->dtrns_cfg.cime_dspw_orsd = (syn->rp.frame_type == INTER_P_FRAME); regs->dtrns_cfg.cime_dspw_orsd = (ctx->frame_type == INTER_P_FRAME);
regs->dtrns_map.src_bus_ordr = 0x0; regs->dtrns_map.src_bus_ordr = 0x0;
regs->dtrns_map.cmvw_bus_ordr = 0x0; regs->dtrns_map.cmvw_bus_ordr = 0x0;
@@ -1044,10 +1150,10 @@ MPP_RET hal_h265e_rkv_gen_regs(void *hal, HalEncTask *task)
RK_U32 i_nal_type = 0; RK_U32 i_nal_type = 0;
/* TODO: extend syn->frame_coding_type definition */ /* TODO: extend syn->frame_coding_type definition */
if (syn->rp.frame_type == INTRA_FRAME) { if (ctx->frame_type == INTRA_FRAME) {
/* reset ref pictures */ /* reset ref pictures */
i_nal_type = NAL_IDR_W_RADL; i_nal_type = NAL_IDR_W_RADL;
} else if (syn->rp.frame_type == INTER_P_FRAME ) { } else if (ctx->frame_type == INTER_P_FRAME ) {
i_nal_type = NAL_TRAIL_R; i_nal_type = NAL_TRAIL_R;
} else { } else {
i_nal_type = NAL_TRAIL_R; i_nal_type = NAL_TRAIL_R;
@@ -1055,7 +1161,9 @@ MPP_RET hal_h265e_rkv_gen_regs(void *hal, HalEncTask *task)
regs->synt_nal.nal_unit_type = i_nal_type; regs->synt_nal.nal_unit_type = i_nal_type;
} }
h265e_rkv_set_pp_regs(regs, &ctx->cfg->prep); h265e_rkv_set_pp_regs(regs, &ctx->cfg->prep);
h265e_rkv_set_rc_regs(regs, syn);
h265e_rkv_set_rc_regs(ctx, regs, syn);
h265e_rkv_set_slice_regs(syn, regs); h265e_rkv_set_slice_regs(syn, regs);
h265e_rkv_set_ref_regs(syn, regs); h265e_rkv_set_ref_regs(syn, regs);
@@ -1321,6 +1429,8 @@ MPP_RET hal_h265e_rkv_get_task(void *hal, HalEncTask *task)
H265eSyntax_new *syn = (H265eSyntax_new *)task->syntax.data; H265eSyntax_new *syn = (H265eSyntax_new *)task->syntax.data;
MppFrame frame = task->frame; MppFrame frame = task->frame;
MppMeta meta = mpp_frame_get_meta(frame); MppMeta meta = mpp_frame_get_meta(frame);
H265eFrmInfo *frms = &syn->frms;
h265e_hal_enter(); h265e_hal_enter();
if ((!ctx->alloc_flg)) { if ((!ctx->alloc_flg)) {
if (MPP_OK != h265e_rkv_allocate_buffers(ctx, syn)) { if (MPP_OK != h265e_rkv_allocate_buffers(ctx, syn)) {
@@ -1332,6 +1442,12 @@ MPP_RET hal_h265e_rkv_get_task(void *hal, HalEncTask *task)
ctx->alloc_flg = 1; ctx->alloc_flg = 1;
} }
if (frms->status.is_intra) {
ctx->frame_type = INTRA_FRAME;
} else {
ctx->frame_type = INTER_P_FRAME;
}
ctx->roi_data = NULL; ctx->roi_data = NULL;
ctx->osd_data = NULL; ctx->osd_data = NULL;
mpp_meta_get_ptr(meta, KEY_ROI_DATA, (void**)&ctx->roi_data); mpp_meta_get_ptr(meta, KEY_ROI_DATA, (void**)&ctx->roi_data);

View File

@@ -59,6 +59,13 @@ typedef struct H265eRkvHalContext_t {
RK_U32 frame_cnt_send_ready; RK_U32 frame_cnt_send_ready;
RK_U32 num_frames_to_send; RK_U32 num_frames_to_send;
/*qp decision*/
RK_S32 cur_scale_qp;
RK_S32 pre_i_qp;
RK_S32 pre_p_qp;
RK_S32 start_qp;
RK_S32 frame_type;
/* @frame_cnt starts from ZERO */ /* @frame_cnt starts from ZERO */
RK_U32 frame_cnt; RK_U32 frame_cnt;
RK_S32 osd_plt_type; RK_S32 osd_plt_type;