[avs2d]: Optimise dec result when player seeking

Change-Id: I92565bb05956276f0f626f9293d70e8b38211209
Signed-off-by: Johnson Ding <johnson.ding@rock-chips.com>
This commit is contained in:
Johnson Ding
2022-07-13 16:28:45 +08:00
committed by Herman Chen
parent d5061c90aa
commit bd5aa46c51
4 changed files with 131 additions and 32 deletions

View File

@@ -230,7 +230,6 @@ MPP_RET avs2d_parse(void *decoder, HalDecTask *task)
AVS2D_PARSE_TRACE("In."); AVS2D_PARSE_TRACE("In.");
task->valid = 0; task->valid = 0;
// memset(task->refer, -1, sizeof(task->refer));
avs2d_parse_stream(p_dec, task); avs2d_parse_stream(p_dec, task);
if (task->valid) { if (task->valid) {
@@ -252,28 +251,69 @@ MPP_RET avs2d_callback(void *decoder, void *info)
{ {
MPP_RET ret = MPP_ERR_UNKNOW; MPP_RET ret = MPP_ERR_UNKNOW;
Avs2dCtx_t *p_dec = (Avs2dCtx_t *)decoder; Avs2dCtx_t *p_dec = (Avs2dCtx_t *)decoder;
Avs2dFrameMgr_t *mgr = &p_dec->frm_mgr;
DecCbHalDone *ctx = (DecCbHalDone *)info; DecCbHalDone *ctx = (DecCbHalDone *)info;
MppFrame mframe = NULL;
HalDecTask *task_dec = (HalDecTask *)ctx->task; HalDecTask *task_dec = (HalDecTask *)ctx->task;
MppFrame mframe = NULL;
MppFrame ref_frm = NULL;
RK_U32 i = 0;
RK_U32 error = 0;
RK_U32 discard = 0;
RK_U32 ref_used_flag = 0;
AVS2D_PARSE_TRACE("In."); AVS2D_PARSE_TRACE("In.");
mpp_buf_slot_get_prop(p_dec->frame_slots, task_dec->output, SLOT_FRAME_PTR, &mframe); mpp_buf_slot_get_prop(p_dec->frame_slots, task_dec->output, SLOT_FRAME_PTR, &mframe);
AVS2D_DBG(AVS2D_DBG_CALLBACK, "frame poc %d, ref=%d, dpberr=%d, harderr=%d\n", if (!mframe) {
mpp_frame_get_poc(mframe), ret = MPP_ERR_UNKNOW;
task_dec->flags.used_for_ref, task_dec->flags.ref_err, ctx->hard_err); AVS2D_DBG(AVS2D_DBG_CALLBACK, "[CALLBACK]: failed to get frame\n");
goto __FAILED;
}
if (mframe) { if (ctx->hard_err || task_dec->flags.ref_err) {
if (ctx->hard_err || task_dec->flags.ref_err) { if (task_dec->flags.used_for_ref) {
if (task_dec->flags.used_for_ref) { error = 1;
mpp_frame_set_errinfo(mframe, 1); } else {
} else { discard = 1;
mpp_frame_set_discard(mframe, 1); }
} } else {
if (task_dec->flags.ref_miss & task_dec->flags.ref_used) {
discard = 1;
AVS2D_DBG(AVS2D_DBG_CALLBACK, "[CALLBACK]: fake ref used, miss 0x%x used 0x%x\n",
task_dec->flags.ref_miss, task_dec->flags.ref_used);
} }
} }
for (i = 0; i < AVS2_MAX_REFS; i++) {
if (!mgr->refs[i] || !mgr->refs[i]->frame || mgr->refs[i]->slot_idx < 0)
continue;
mpp_buf_slot_get_prop(p_dec->frame_slots, mgr->refs[i]->slot_idx, SLOT_FRAME_PTR, &ref_frm);
if (!ref_frm)
continue;
ref_used_flag = (task_dec->flags.ref_used >> i) & 1;
//TODO: In fast mode, ref list isn't kept sync with task flag.ref_used
AVS2D_DBG(AVS2D_DBG_CALLBACK, "[CALLBACK]: ref_frm poc %d, err %d, dis %d, ref_used %d\n",
mpp_frame_get_poc(ref_frm), mpp_frame_get_errinfo(ref_frm),
mpp_frame_get_discard(ref_frm), ref_used_flag);
if (ref_used_flag) {
discard |= mpp_frame_get_discard(ref_frm);
error |= mpp_frame_get_errinfo(ref_frm);
}
}
mpp_frame_set_errinfo(mframe, error);
mpp_frame_set_discard(mframe, discard);
AVS2D_DBG(AVS2D_DBG_CALLBACK, "[CALLBACK]: frame poc %d, ref=%d, dpberr=%d, harderr=%d, err:dis=%d:%d\n",
mpp_frame_get_poc(mframe), task_dec->flags.used_for_ref, task_dec->flags.ref_err,
ctx->hard_err, error, discard);
__FAILED:
AVS2D_PARSE_TRACE("Out."); AVS2D_PARSE_TRACE("Out.");
return ret = MPP_OK; return ret;
} }
const ParserApi api_avs2d_parser = { const ParserApi api_avs2d_parser = {

View File

@@ -485,6 +485,7 @@ static Avs2dFrame_t *dpb_alloc_frame(Avs2dCtx_t *p_dec, HalDecTask *task)
mpp_frame_set_pts(mframe, mpp_packet_get_pts(task->input_packet)); mpp_frame_set_pts(mframe, mpp_packet_get_pts(task->input_packet));
mpp_frame_set_dts(mframe, mpp_packet_get_dts(task->input_packet)); mpp_frame_set_dts(mframe, mpp_packet_get_dts(task->input_packet));
mpp_frame_set_errinfo(mframe, 0); mpp_frame_set_errinfo(mframe, 0);
mpp_frame_set_discard(mframe, 0);
mpp_frame_set_poc(mframe, frm->poi); mpp_frame_set_poc(mframe, frm->poi);
if (p_dec->got_exh) { if (p_dec->got_exh) {
mpp_frame_set_color_primaries(mframe, exh->color_primaries); mpp_frame_set_color_primaries(mframe, exh->color_primaries);
@@ -638,26 +639,26 @@ static MPP_RET dpb_set_frame_refs(Avs2dCtx_t *p_dec, Avs2dFrameMgr_t *mgr, HalDe
(void) task; (void) task;
avs2d_dbg_dpb("In."); avs2d_dbg_dpb("In.");
for (i = 0; i < AVS2_MAX_REFS; i++) { memset(mgr->refs, 0, sizeof(mgr->refs));
mgr->refs[i] = NULL;
}
p_cur = mgr->cur_frm; p_cur = mgr->cur_frm;
mgr->num_of_ref = 0; mgr->num_of_ref = 0;
p_rps = &mgr->cur_rps; p_rps = &mgr->cur_rps;
num_of_ref = p_rps->num_of_ref; num_of_ref = p_rps->num_of_ref;
task->flags.ref_miss = 0;
for (i = 0; i < num_of_ref; i++) { for (i = 0; i < num_of_ref; i++) {
doi_of_ref = p_cur->doi - p_rps->ref_pic[i]; doi_of_ref = p_cur->doi - p_rps->ref_pic[i];
p = find_ref_frame(mgr, doi_of_ref); p = find_ref_frame(mgr, doi_of_ref);
if (!p) { if (!p) {
mpp_frame_set_discard(p_cur->frame, 1); task->flags.ref_miss |= 1 << i;
avs2d_dbg_dpb("Missing ref doi %d", doi_of_ref); avs2d_dbg_dpb("Missing ref doi %d", doi_of_ref);
} else { } else {
mgr->refs[mgr->num_of_ref] = p; mgr->refs[mgr->num_of_ref] = p;
mgr->num_of_ref++;
mpp_buf_slot_set_flag(p_dec->frame_slots, p->slot_idx, SLOT_CODEC_USE); mpp_buf_slot_set_flag(p_dec->frame_slots, p->slot_idx, SLOT_CODEC_USE);
mpp_buf_slot_set_flag(p_dec->frame_slots, p->slot_idx, SLOT_HAL_INPUT); mpp_buf_slot_set_flag(p_dec->frame_slots, p->slot_idx, SLOT_HAL_INPUT);
} }
mgr->num_of_ref++;
} }
if (mgr->num_of_ref < 1 && !p_cur->intra_frame_flag) { if (mgr->num_of_ref < 1 && !p_cur->intra_frame_flag) {
@@ -668,7 +669,7 @@ static MPP_RET dpb_set_frame_refs(Avs2dCtx_t *p_dec, Avs2dFrameMgr_t *mgr, HalDe
error_flag = 1; error_flag = 1;
} else if (mgr->scene_ref != mgr->refs[0] || mgr->num_of_ref > 1) { } else if (mgr->scene_ref != mgr->refs[0] || mgr->num_of_ref > 1) {
AVS2D_DBG(AVS2D_DBG_ERROR, "Error reference frame(doi %lld ~ %lld) for S.\n", AVS2D_DBG(AVS2D_DBG_ERROR, "Error reference frame(doi %lld ~ %lld) for S.\n",
mgr->scene_ref->doi, mgr->refs[0]->doi); mgr->scene_ref->doi, mgr->refs[0] ? mgr->refs[0]->doi : -1);
mgr->num_of_ref = 1; mgr->num_of_ref = 1;
mgr->refs[mgr->num_of_ref - 1] = mgr->scene_ref; mgr->refs[mgr->num_of_ref - 1] = mgr->scene_ref;
} }
@@ -681,7 +682,8 @@ static MPP_RET dpb_set_frame_refs(Avs2dCtx_t *p_dec, Avs2dFrameMgr_t *mgr, HalDe
mgr->refs[mgr->num_of_ref - 1] = mgr->scene_ref; mgr->refs[mgr->num_of_ref - 1] = mgr->scene_ref;
} }
} else if (p_cur->picture_type == B_PICTURE && } else if (p_cur->picture_type == B_PICTURE &&
(mgr->num_of_ref != 2 || mgr->refs[0]->poi <= p_cur->poi || mgr->refs[1]->poi >= p_cur->poi)) { (mgr->num_of_ref != 2 || (mgr->refs[0] && mgr->refs[0]->poi <= p_cur->poi) ||
(mgr->refs[1] && mgr->refs[1]->poi >= p_cur->poi))) {
error_flag = 1; error_flag = 1;
} }
@@ -740,13 +742,18 @@ MPP_RET avs2d_dpb_insert(Avs2dCtx_t *p_dec, HalDecTask *task)
//!< set task refers //!< set task refers
ret = dpb_set_frame_refs(p_dec, mgr, task); ret = dpb_set_frame_refs(p_dec, mgr, task);
if (ret != MPP_OK) { if (ret)
task->flags.ref_err |= mpp_frame_get_errinfo(mgr->cur_frm); task->flags.ref_err = 0;
}
for (i = 0; i < mgr->num_of_ref; i++) { for (i = 0; i < mgr->num_of_ref; i++) {
task->refer[i] = mgr->refs[i]->slot_idx; task->refer[i] = mgr->refs[i] ? mgr->refs[i]->slot_idx : -1;
avs2d_dbg_dpb("task refer[%d] slot_idx %d doi %d poi %d", i, task->refer[i], mgr->refs[i]->doi, mgr->refs[i]->poi); if (mgr->refs[i]) {
task->refer[i] = mgr->refs[i]->slot_idx;
avs2d_dbg_dpb("task refer[%d] slot_idx %d doi %d poi %d", i, task->refer[i], mgr->refs[i]->doi, mgr->refs[i]->poi);
} else {
task->refer[i] = -1;
avs2d_dbg_dpb("task refer[%d] missing ref\n", i);
}
} }
//!< update dpb by rps //!< update dpb by rps

View File

@@ -325,7 +325,7 @@ MPP_RET avs2d_fill_parameters(Avs2dCtx_t *p_dec, Avs2dSyntax_t *syntax)
refp->ref_pic_num = mgr->num_of_ref; refp->ref_pic_num = mgr->num_of_ref;
memset(refp->ref_poc_list, -1, sizeof(refp->ref_poc_list)); memset(refp->ref_poc_list, -1, sizeof(refp->ref_poc_list));
for (i = 0; i < mgr->num_of_ref; i++) { for (i = 0; i < mgr->num_of_ref; i++) {
refp->ref_poc_list[i] = mgr->refs[i]->poi; refp->ref_poc_list[i] = mgr->refs[i] ? mgr->refs[i]->poi : -1;
} }
//!< picture alf params //!< picture alf params

View File

@@ -315,6 +315,7 @@ static void hal_avs2d_rcb_info_update(void *hal, Vdpu34xAvs2dRegSet *hw_regs)
static MPP_RET fill_registers(Avs2dHalCtx_t *p_hal, Vdpu34xAvs2dRegSet *p_regs, HalTaskInfo *task) static MPP_RET fill_registers(Avs2dHalCtx_t *p_hal, Vdpu34xAvs2dRegSet *p_regs, HalTaskInfo *task)
{ {
MPP_RET ret = MPP_OK;
RK_U32 i; RK_U32 i;
MppFrame mframe = NULL; MppFrame mframe = NULL;
Avs2dSyntax_t *syntax = &p_hal->syntax; Avs2dSyntax_t *syntax = &p_hal->syntax;
@@ -372,14 +373,30 @@ static MPP_RET fill_registers(Avs2dHalCtx_t *p_hal, Vdpu34xAvs2dRegSet *p_regs,
// set reference // set reference
{ {
RK_U64 ref_flag = 0; RK_U64 ref_flag = 0;
RK_S32 valid_slot = -1;
AVS2D_HAL_TRACE("num of ref %d", refp->ref_pic_num); AVS2D_HAL_TRACE("num of ref %d", refp->ref_pic_num);
for (i = 0; i < refp->ref_pic_num; i++) {
if (task_dec->refer[i] < 0)
continue;
valid_slot = i;
break;
}
for (i = 0; i < MAX_REF_NUM; i++) { for (i = 0; i < MAX_REF_NUM; i++) {
if (i < refp->ref_pic_num) { if (i < refp->ref_pic_num) {
MppFrame frame_ref = NULL; MppFrame frame_ref = NULL;
mpp_buf_slot_get_prop(p_hal->frame_slots, task_dec->refer[i], SLOT_FRAME_PTR, &frame_ref); RK_S32 slot_idx = task_dec->refer[i] < 0 ? valid_slot : task_dec->refer[i];
if (slot_idx < 0) {
AVS2D_HAL_TRACE("missing ref, could not found valid ref");
return ret = MPP_ERR_UNKNOW;
}
mpp_buf_slot_get_prop(p_hal->frame_slots, slot_idx, SLOT_FRAME_PTR, &frame_ref);
if (frame_ref) { if (frame_ref) {
RK_U32 frm_flag = 1 << 3; RK_U32 frm_flag = 1 << 3;
@@ -392,14 +409,14 @@ static MPP_RET fill_registers(Avs2dHalCtx_t *p_hal, Vdpu34xAvs2dRegSet *p_regs,
ref_flag |= frm_flag << (i * 8); ref_flag |= frm_flag << (i * 8);
p_regs->avs2d_addr.ref_base[i] = get_frame_fd(p_hal, task_dec->refer[i]); p_regs->avs2d_addr.ref_base[i] = get_frame_fd(p_hal, slot_idx);
mv_buf = hal_bufs_get_buf(p_hal->cmv_bufs, task_dec->refer[i]); mv_buf = hal_bufs_get_buf(p_hal->cmv_bufs, slot_idx);
p_regs->avs2d_addr.colmv_base[i] = mpp_buffer_get_fd(mv_buf->buf[0]); p_regs->avs2d_addr.colmv_base[i] = mpp_buffer_get_fd(mv_buf->buf[0]);
p_regs->avs2d_param.reg67_098_ref_poc[i] = mpp_frame_get_poc(frame_ref); p_regs->avs2d_param.reg67_098_ref_poc[i] = mpp_frame_get_poc(frame_ref);
AVS2D_HAL_TRACE("ref_base[%d] index=%d, fd = %d, colmv %d, poc %d", AVS2D_HAL_TRACE("ref_base[%d] index=%d, fd = %d, colmv %d, poc %d",
i, task_dec->refer[i], p_regs->avs2d_addr.ref_base[i], i, slot_idx, p_regs->avs2d_addr.ref_base[i],
p_regs->avs2d_addr.colmv_base[i], p_regs->avs2d_param.reg67_098_ref_poc[i]); p_regs->avs2d_addr.colmv_base[i], p_regs->avs2d_param.reg67_098_ref_poc[i]);
} }
} }
@@ -418,7 +435,7 @@ static MPP_RET fill_registers(Avs2dHalCtx_t *p_hal, Vdpu34xAvs2dRegSet *p_regs,
common->reg016_str_len = MPP_ALIGN(mpp_packet_get_length(task_dec->input_packet), 16) + 64; common->reg016_str_len = MPP_ALIGN(mpp_packet_get_length(task_dec->input_packet), 16) + 64;
} }
return MPP_OK; return ret;
} }
MPP_RET hal_avs2d_rkv_deinit(void *hal) MPP_RET hal_avs2d_rkv_deinit(void *hal)
@@ -624,7 +641,10 @@ MPP_RET hal_avs2d_rkv_gen_regs(void *hal, HalTaskInfo *task)
prepare_header(p_hal, reg_ctx->shph_dat, sizeof(reg_ctx->shph_dat)); prepare_header(p_hal, reg_ctx->shph_dat, sizeof(reg_ctx->shph_dat));
prepare_scalist(p_hal, reg_ctx->scalist_dat, sizeof(reg_ctx->scalist_dat)); prepare_scalist(p_hal, reg_ctx->scalist_dat, sizeof(reg_ctx->scalist_dat));
fill_registers(p_hal, regs, task); ret = fill_registers(p_hal, regs, task);
if (ret)
goto __RETURN;
{ {
memcpy(reg_ctx->bufs_ptr + reg_ctx->shph_offset, reg_ctx->shph_dat, sizeof(reg_ctx->shph_dat)); memcpy(reg_ctx->bufs_ptr + reg_ctx->shph_offset, reg_ctx->shph_dat, sizeof(reg_ctx->shph_dat));
@@ -686,6 +706,9 @@ MPP_RET hal_avs2d_rkv_gen_regs(void *hal, HalTaskInfo *task)
} }
vdpu34x_setup_statistic(&regs->common, &regs->statistic); vdpu34x_setup_statistic(&regs->common, &regs->statistic);
/* enable reference frame usage feedback */
regs->statistic.reg265.perf_cnt0_sel = 42;
regs->statistic.reg266_perf_cnt0 = 0;
__RETURN: __RETURN:
AVS2D_HAL_TRACE("Out. ret %d", ret); AVS2D_HAL_TRACE("Out. ret %d", ret);
@@ -859,6 +882,26 @@ MPP_RET hal_avs2d_rkv_start(void *hal, HalTaskInfo *task)
break; break;
} }
rd_cfg.reg = &regs->avs2d_param;
rd_cfg.size = sizeof(regs->avs2d_param);
rd_cfg.offset = OFFSET_CODEC_PARAMS_REGS;
ret = mpp_dev_ioctl(dev, MPP_DEV_REG_RD, &rd_cfg);
if (ret) {
mpp_err_f("set register read failed %d\n", ret);
break;
}
rd_cfg.reg = &regs->statistic;
rd_cfg.size = sizeof(regs->statistic);
rd_cfg.offset = OFFSET_STATISTIC_REGS;
ret = mpp_dev_ioctl(dev, MPP_DEV_REG_RD, &rd_cfg);
if (ret) {
mpp_err_f("set register write failed %d\n", ret);
break;
}
if (avs2d_hal_debug & AVS2D_HAL_DBG_REG) { if (avs2d_hal_debug & AVS2D_HAL_DBG_REG) {
memset(reg_ctx->reg_out, 0, sizeof(reg_ctx->reg_out)); memset(reg_ctx->reg_out, 0, sizeof(reg_ctx->reg_out));
rd_cfg.reg = reg_ctx->reg_out; rd_cfg.reg = reg_ctx->reg_out;
@@ -1042,6 +1085,15 @@ MPP_RET hal_avs2d_rkv_wait(void *hal, HalTaskInfo *task)
else else
param.hard_err = 0; param.hard_err = 0;
task->dec.flags.ref_used = p_regs->statistic.reg266_perf_cnt0;
if (task->dec.flags.ref_miss) {
RK_U32 ref_hw_usage = p_regs->statistic.reg266_perf_cnt0;
AVS2D_HAL_TRACE("hal frame %d ref miss %x hard_err %d hw_usage %x", p_hal->frame_no,
task->dec.flags.ref_miss, param.hard_err, ref_hw_usage);
}
AVS2D_HAL_TRACE("hal frame %d hard_err= %d", p_hal->frame_no, param.hard_err); AVS2D_HAL_TRACE("hal frame %d hard_err= %d", p_hal->frame_no, param.hard_err);
mpp_callback(p_hal->dec_cb, &param); mpp_callback(p_hal->dec_cb, &param);