mirror of
https://github.com/nyanmisaka/mpp.git
synced 2025-10-06 17:46:50 +08:00
[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:
@@ -31,28 +31,6 @@
|
||||
|
||||
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)
|
||||
{
|
||||
H265eCtx *p = (H265eCtx *)ctx;
|
||||
@@ -94,6 +72,7 @@ static MPP_RET h265e_init(void *ctx, EncImplCfg *ctrlCfg)
|
||||
h265->max_i_qp = 51;
|
||||
h265->min_i_qp = 10;
|
||||
h265->ip_qp_delta = 3;
|
||||
h265->raw_dealt_qp = 2;
|
||||
h265->max_delta_qp = 10;
|
||||
h265->const_intra_pred = 0;
|
||||
h265->gop_delta_qp = 0;
|
||||
@@ -394,21 +373,6 @@ static MPP_RET h265e_proc_dpb(void *ctx, HalEncTask *task)
|
||||
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)
|
||||
{
|
||||
(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);
|
||||
|
||||
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;
|
||||
|
||||
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) {
|
||||
p->frms.status.reencode = 1;
|
||||
} else {
|
||||
p->frms.last_frame_type = p->frms.frame_type;
|
||||
}
|
||||
|
||||
h265e_dbg_func("leave\n");
|
||||
return MPP_OK;
|
||||
}
|
||||
|
@@ -22,10 +22,10 @@
|
||||
#include "mpp_rc.h"
|
||||
|
||||
#include "h265e_syntax.h"
|
||||
#include "h265e_syntax_new.h"
|
||||
#include "h265e_dpb.h"
|
||||
#include "enc_impl_api.h"
|
||||
#include "rc_api.h"
|
||||
#include "rc.h"
|
||||
|
||||
#define H265E_DBG_FUNCTION (0x00000001)
|
||||
#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_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 {
|
||||
MppEncCfgSet *cfg;
|
||||
MppEncCfgSet *set;
|
||||
@@ -107,7 +77,7 @@ typedef struct H265eCtx_t {
|
||||
void *extra_info;
|
||||
void *param_buf;
|
||||
MppPacket packeted_param;
|
||||
H265eSyntax syntax;
|
||||
H265eSyntax_new syntax;
|
||||
H265eFeedback feedback;
|
||||
struct list_head rc_list;
|
||||
} H265eCtx;
|
||||
|
@@ -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;
|
||||
MppEncRcCfg *rc = &h->cfg->rc;
|
||||
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;
|
||||
memcpy(syn_frms, frms, sizeof(*frms));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -418,7 +354,7 @@ RK_S32 h265e_syntax_fill(void *ctx)
|
||||
fill_picture_parameters(h, &syn->pp);
|
||||
fill_slice_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;
|
||||
if (h->plt_flag) {
|
||||
syn->ud.plt_data = (void*)&h->cfg->osd_plt;
|
||||
|
@@ -17,6 +17,8 @@
|
||||
#ifndef __H265E_SYNTAX_NEW_H__
|
||||
#define __H265E_SYNTAX_NEW_H__
|
||||
#include "mpp_rc.h"
|
||||
#include "h265_syntax.h"
|
||||
#include "rc.h"
|
||||
|
||||
typedef struct H265PicEntry_t {
|
||||
RK_U8 bPicEntry[3];
|
||||
@@ -188,24 +190,31 @@ typedef struct H265eSlicParams_t {
|
||||
RK_U32 sli_splt_byte;
|
||||
RK_U32 tot_poc_num;
|
||||
} 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 {
|
||||
RK_U8 rc_en;
|
||||
RK_U8 pic_qp;
|
||||
RK_U8 frame_type;
|
||||
RK_U8 coding_type;
|
||||
RK_U8 rc_qp_range;
|
||||
RK_U8 rc_max_qp;
|
||||
RK_U8 rc_min_qp;
|
||||
RK_U16 rc_ctu_num;
|
||||
RK_U32 ctu_ebits;
|
||||
RK_S32 bits_thd[9];
|
||||
RK_S8 qp_adjust[9];
|
||||
RK_U8 qpmax_area[8];
|
||||
RK_U8 qpmin_area[8];
|
||||
RK_U8 qpmap_mode;
|
||||
RK_U32 bit_target;
|
||||
} RcParams;
|
||||
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;
|
||||
|
||||
RcHalCfg rc_cfg;
|
||||
EncFrmStatus status;
|
||||
RK_S32 usage[MAX_REFS + 1];
|
||||
} H265eFrmInfo;
|
||||
|
||||
typedef struct UserDatas_t {
|
||||
void *plt_data;
|
||||
@@ -215,8 +224,8 @@ typedef struct H265eSyntax_new_t {
|
||||
RK_S32 idr_request;
|
||||
H265ePicParams pp;
|
||||
H265eSlicParams sp;
|
||||
RcParams rp;
|
||||
UserDatas ud;
|
||||
H265eFrmInfo frms;
|
||||
} H265eSyntax_new;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@@ -128,6 +128,43 @@ RK_U32 lamd_modb_qp[52] = {
|
||||
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)
|
||||
{
|
||||
@@ -358,8 +395,8 @@ MPP_RET hal_h265e_rkv_init(void *hal, MppEncHalCfg *cfg)
|
||||
ctx->ioctl_output = mpp_calloc(H265eRkvIoctlOutput, 1);
|
||||
ctx->regs = mpp_calloc(H265eRkvRegSet, 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->buffers = mpp_calloc(RcHalCfg, RKVE_LINKTABLE_FRAME_NUM);
|
||||
ctx->rc_hal_cfg = mpp_calloc(RcHalCfg, RKVE_LINKTABLE_FRAME_NUM);
|
||||
ctx->buffers = mpp_calloc(h265e_hal_rkv_buffers, RKVE_LINKTABLE_FRAME_NUM);
|
||||
ctx->set = cfg->set;
|
||||
ctx->cfg = cfg->cfg;
|
||||
|
||||
@@ -607,56 +644,125 @@ h265e_rkv_set_roi_regs(H265eRkvHalContext *ctx, H265eRkvRegSet *regs)
|
||||
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;
|
||||
regs->rc_cfg.rc_en = syn->rp.rc_en;
|
||||
regs->synt_sli1.sli_qp = syn->rp.pic_qp;
|
||||
H265eFrmInfo *frms = &syn->frms;
|
||||
MppEncCfgSet *cfg = ctx->cfg;
|
||||
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;
|
||||
regs->rc_qp.rc_qp_range = syn->rp.rc_qp_range;
|
||||
regs->rc_qp.rc_max_qp = syn->rp.rc_max_qp;
|
||||
regs->rc_qp.rc_min_qp = syn->rp.rc_min_qp;
|
||||
regs->rc_tgt.ctu_ebits = syn->rp.ctu_ebits;
|
||||
if (frms->seq_idx == 0 && frms->status.is_intra) {
|
||||
if (h265->qp_init == -1) {
|
||||
ctx->start_qp = cal_first_i_start_qp(frms->rc_cfg.bit_target, frms->mb_per_frame << 4);
|
||||
ctx->cur_scale_qp = (ctx->start_qp + h265->ip_qp_delta) << 6;
|
||||
} else {
|
||||
|
||||
regs->rc_erp0.bits_thd0 = syn->rp.bits_thd[0];
|
||||
regs->rc_erp1.bits_thd1 = syn->rp.bits_thd[1];
|
||||
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];
|
||||
ctx->start_qp = h265->qp_init;
|
||||
ctx->cur_scale_qp = (ctx->start_qp + h265->ip_qp_delta) << 6;
|
||||
}
|
||||
|
||||
regs->rc_adj0.qp_adjust0 = syn->rp.qp_adjust[0];
|
||||
regs->rc_adj0.qp_adjust1 = syn->rp.qp_adjust[1];
|
||||
regs->rc_adj0.qp_adjust2 = syn->rp.qp_adjust[2];
|
||||
regs->rc_adj0.qp_adjust3 = syn->rp.qp_adjust[3];
|
||||
regs->rc_adj0.qp_adjust4 = syn->rp.qp_adjust[4];
|
||||
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];
|
||||
ctx->pre_i_qp = ctx->cur_scale_qp >> 6;
|
||||
ctx->pre_p_qp = ctx->cur_scale_qp >> 6;
|
||||
} else {
|
||||
RK_S32 qp_scale = ctx->cur_scale_qp + frms->rc_cfg.next_ratio;
|
||||
RK_S32 start_qp = 0;
|
||||
|
||||
regs->qpmap0.qpmin_area0 = syn->rp.qpmin_area[1];
|
||||
regs->qpmap0.qpmax_area0 = syn->rp.qpmax_area[1];
|
||||
regs->qpmap0.qpmin_area1 = syn->rp.qpmin_area[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;
|
||||
if (frms->status.is_intra) {
|
||||
qp_scale = mpp_clip(qp_scale, (h265->min_i_qp << 6), (h265->max_i_qp << 6));
|
||||
start_qp = ((ctx->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);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -808,7 +914,7 @@ MPP_RET hal_h265e_rkv_gen_regs(void *hal, HalEncTask *task)
|
||||
fbc_header_len = (pic_wd64 * pic_h64) << 6;
|
||||
h265e_hal_dbg(H265E_DBG_SIMPLE,
|
||||
"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
|
||||
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.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;
|
||||
} else {
|
||||
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.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.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;
|
||||
|
||||
/* TODO: extend syn->frame_coding_type definition */
|
||||
if (syn->rp.frame_type == INTRA_FRAME) {
|
||||
if (ctx->frame_type == INTRA_FRAME) {
|
||||
/* reset ref pictures */
|
||||
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;
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
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_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;
|
||||
MppFrame frame = task->frame;
|
||||
MppMeta meta = mpp_frame_get_meta(frame);
|
||||
H265eFrmInfo *frms = &syn->frms;
|
||||
|
||||
h265e_hal_enter();
|
||||
if ((!ctx->alloc_flg)) {
|
||||
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;
|
||||
}
|
||||
|
||||
if (frms->status.is_intra) {
|
||||
ctx->frame_type = INTRA_FRAME;
|
||||
} else {
|
||||
ctx->frame_type = INTER_P_FRAME;
|
||||
}
|
||||
|
||||
ctx->roi_data = NULL;
|
||||
ctx->osd_data = NULL;
|
||||
mpp_meta_get_ptr(meta, KEY_ROI_DATA, (void**)&ctx->roi_data);
|
||||
|
@@ -59,6 +59,13 @@ typedef struct H265eRkvHalContext_t {
|
||||
RK_U32 frame_cnt_send_ready;
|
||||
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 */
|
||||
RK_U32 frame_cnt;
|
||||
RK_S32 osd_plt_type;
|
||||
|
Reference in New Issue
Block a user