fix[h265d]: Fix GDR stream decoding

1. GDR stream started with Non-IDR frame is supported and no need to
disable error.
2. Intra refreshed frames will be mark as discard if started with
Non-IDR frame.

Signed-off-by: Johnson Ding <johnson.ding@rock-chips.com>
Change-Id: Ide470d377f13e0512ceda4eb7219650aeffb0148
This commit is contained in:
Johnson Ding
2025-05-15 11:04:22 +08:00
committed by Herman Chen
parent 3d530016fb
commit 57695b2f59
4 changed files with 28 additions and 9 deletions

View File

@@ -15,6 +15,7 @@ typedef struct SEI_Recovery_Point_t {
RK_S32 recovery_frame_cnt; // H.264: recovery_frame_cnt; H.265: recovery_poc_cnt
RK_S32 first_frm_id; // The frame_num or poc of the frame associated with this SEI
RK_U32 first_frm_valid; // The frame associated with this SEI is valid or not
RK_U32 first_frm_ref_missing;
RK_S32 recovery_pic_id; // first_frm_id + recovery_frame_cnt;
} RecoveryPoint;

View File

@@ -1276,12 +1276,25 @@ static RK_S32 hevc_frame_start(HEVCContext *s)
if (ret < 0)
goto fail;
if (!s->h265dctx->cfg->base.disable_error && s->recovery.valid_flag &&
s->recovery.first_frm_valid && s->recovery.first_frm_ref_missing &&
s->poc < s->recovery.recovery_pic_id && s->poc >= s->recovery.first_frm_id) {
mpp_frame_set_discard(s->frame, 1);
h265d_dbg(H265D_DBG_REF, "mark recovery frame discard, poc %d\n", mpp_frame_get_poc(s->frame));
}
if (!s->h265dctx->cfg->base.disable_error && s->miss_ref_flag) {
if (!IS_IRAP(s) && (!s->recovery.valid_flag ||
(s->recovery.valid_flag && s->recovery.first_frm_valid &&
s->recovery.first_frm_id != s->poc))) {
mpp_frame_set_errinfo(s->frame, MPP_FRAME_ERR_UNKNOW);
s->ref->error_flag = 1;
if (!IS_IRAP(s)) {
if (s->recovery.valid_flag && s->recovery.first_frm_valid && s->recovery.first_frm_id == s->poc) {
s->recovery.first_frm_ref_missing = 1;
mpp_frame_set_discard(s->frame, 1);
h265d_dbg(H265D_DBG_REF, "recovery frame missing ref mark discard, poc %d\n",
mpp_frame_get_poc(s->frame));
} else {
mpp_frame_set_errinfo(s->frame, MPP_FRAME_ERR_UNKNOW);
s->ref->error_flag = 1;
h265d_dbg(H265D_DBG_REF, "missing ref mark error, poc %d\n", mpp_frame_get_poc(s->frame));
}
} else {
/*when found current I frame have miss refer
may be stream have error so first set current frame
@@ -2312,9 +2325,15 @@ MPP_RET h265d_callback(void *ctx, void *err_info)
// s->miss_ref_flag = 1;
mpp_buf_slot_get_prop(s->slots, task_dec->output, SLOT_FRAME_PTR, &frame);
mpp_frame_set_errinfo(frame, MPP_FRAME_ERR_UNKNOW);
h265d_dbg(H265D_DBG_REF, "set decoded frame error, poc %d, slot %d\n",
mpp_frame_get_poc(frame), task_dec->output);
for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) {
if (s->DPB[i].slot_index == task_dec->output) {
s->DPB[i].error_flag = 1;
h265d_dbg(H265D_DBG_REF, "Mark dpb[%d] poc %d, slot_idx %d, err %d, frame: err %d, dis %d\n",
i, mpp_frame_get_poc(s->DPB[i].frame), s->DPB[i].slot_index, s->DPB[i].error_flag,
mpp_frame_get_errinfo(s->DPB[i].frame), mpp_frame_get_discard(s->DPB[i].frame));
}
}
}

View File

@@ -142,10 +142,7 @@ static void fill_picture_parameters(const HEVCContext *h,
pp->IdrPicFlag = (h->first_nal_type == 19 || h->first_nal_type == 20);
pp->IrapPicFlag = (h->first_nal_type >= 16 && h->first_nal_type <= 23);
pp->IntraPicFlag = (h->first_nal_type >= 16 && h->first_nal_type <= 23) ||
(h->sh.slice_type == I_SLICE || (h->recovery.valid_flag &&
h->recovery.first_frm_valid &&
h->recovery.first_frm_id == current_picture->poc));
pp->IntraPicFlag = (h->first_nal_type >= 16 && h->first_nal_type <= 23) || h->sh.slice_type == I_SLICE;
pp->pps_cb_qp_offset = pps->cb_qp_offset;
pp->pps_cr_qp_offset = pps->cr_qp_offset;
if (pps->tiles_enabled_flag) {

View File

@@ -132,6 +132,7 @@ static HEVCFrame *alloc_frame(HEVCContext *s)
mpp_frame_set_thumbnail_en(frame->frame, 0);
mpp_frame_set_errinfo(frame->frame, 0);
mpp_frame_set_discard(frame->frame, 0);
mpp_frame_set_pts(frame->frame, s->pts);
mpp_frame_set_poc(frame->frame, s->poc);
mpp_frame_set_color_range(frame->frame, s->h265dctx->color_range);
@@ -241,6 +242,7 @@ static HEVCFrame *generate_missing_ref(HEVCContext *s, int poc)
mpp_buf_slot_set_prop(s->slots, frame->slot_index, SLOT_FRAME, frame->frame);
mpp_buf_slot_set_flag(s->slots, frame->slot_index, SLOT_CODEC_READY);
mpp_buf_slot_set_flag(s->slots, frame->slot_index, SLOT_CODEC_USE);
mpp_frame_set_poc(frame->frame, poc);
h265d_dbg(H265D_DBG_REF, "generate_missing_ref frame poc %d slot_index %d", poc, frame->slot_index);
frame->sequence = s->seq_decode;
frame->flags = 0;