lavc/hevcdec: make a HEVCFrame hold a reference to its PPS

ff_hevc_get_ref_list() needs the PPS of a previously decoded frame,
which may be different from the currently active one.
This commit is contained in:
Anton Khirnov 2024-06-05 12:02:27 +02:00
parent 672713761b
commit 9bccc634af
5 changed files with 15 additions and 11 deletions

View File

@ -767,7 +767,7 @@ void ff_hevc_deblocking_boundary_strengths(HEVCLocalContext *lc, const HEVCLayer
if (boundary_upper) {
const RefPicList *rpl_top = (lc->boundary_flags & BOUNDARY_UPPER_SLICE) ?
ff_hevc_get_ref_list(s, s->cur_frame, x0, y0 - 1) :
ff_hevc_get_ref_list(s->cur_frame, x0, y0 - 1) :
s->cur_frame->refPicList;
int yp_pu = (y0 - 1) >> log2_min_pu_size;
int yq_pu = y0 >> log2_min_pu_size;
@ -805,7 +805,7 @@ void ff_hevc_deblocking_boundary_strengths(HEVCLocalContext *lc, const HEVCLayer
if (boundary_left) {
const RefPicList *rpl_left = (lc->boundary_flags & BOUNDARY_LEFT_SLICE) ?
ff_hevc_get_ref_list(s, s->cur_frame, x0 - 1, y0) :
ff_hevc_get_ref_list(s->cur_frame, x0 - 1, y0) :
s->cur_frame->refPicList;
int xp_pu = (x0 - 1) >> log2_min_pu_size;
int xq_pu = x0 >> log2_min_pu_size;

View File

@ -3503,6 +3503,7 @@ static int hevc_ref_frame(HEVCFrame *dst, const HEVCFrame *src)
dst->needs_fg = 1;
}
dst->pps = ff_refstruct_ref_c(src->pps);
dst->tab_mvf = ff_refstruct_ref(src->tab_mvf);
dst->rpl_tab = ff_refstruct_ref(src->rpl_tab);
dst->rpl = ff_refstruct_ref(src->rpl);

View File

@ -366,6 +366,7 @@ typedef struct HEVCFrame {
int ctb_count;
int poc;
const HEVCPPS *pps; ///< RefStruct reference
RefPicListTab *rpl; ///< RefStruct reference
int nb_rpl_elems;
@ -556,8 +557,7 @@ void ff_hevc_clear_refs(HEVCLayerContext *l);
*/
void ff_hevc_flush_dpb(HEVCContext *s);
const RefPicList *ff_hevc_get_ref_list(const HEVCContext *s, const HEVCFrame *frame,
int x0, int y0);
const RefPicList *ff_hevc_get_ref_list(const HEVCFrame *frame, int x0, int y0);
/**
* Construct the reference picture sets for the current frame.

View File

@ -211,7 +211,7 @@ static int derive_temporal_colocated_mvs(const HEVCContext *s, MvField temp_col,
#define DERIVE_TEMPORAL_COLOCATED_MVS \
derive_temporal_colocated_mvs(s, temp_col, \
refIdxLx, mvLXCol, X, colPic, \
ff_hevc_get_ref_list(s, ref, x, y))
ff_hevc_get_ref_list(ref, x, y))
/*
* 8.5.3.1.7 temporal luma motion vector prediction

View File

@ -38,6 +38,7 @@ void ff_hevc_unref_frame(HEVCFrame *frame, int flags)
av_frame_unref(frame->frame_grain);
frame->needs_fg = 0;
ff_refstruct_unref(&frame->pps);
ff_refstruct_unref(&frame->tab_mvf);
ff_refstruct_unref(&frame->rpl);
@ -49,13 +50,13 @@ void ff_hevc_unref_frame(HEVCFrame *frame, int flags)
}
}
const RefPicList *ff_hevc_get_ref_list(const HEVCContext *s,
const HEVCFrame *ref, int x0, int y0)
const RefPicList *ff_hevc_get_ref_list(const HEVCFrame *ref, int x0, int y0)
{
int x_cb = x0 >> s->ps.sps->log2_ctb_size;
int y_cb = y0 >> s->ps.sps->log2_ctb_size;
int pic_width_cb = s->ps.sps->ctb_width;
int ctb_addr_ts = s->pps->ctb_addr_rs_to_ts[y_cb * pic_width_cb + x_cb];
const HEVCSPS *sps = ref->pps->sps;
int x_cb = x0 >> sps->log2_ctb_size;
int y_cb = y0 >> sps->log2_ctb_size;
int pic_width_cb = sps->ctb_width;
int ctb_addr_ts = ref->pps->ctb_addr_rs_to_ts[y_cb * pic_width_cb + x_cb];
return &ref->rpl_tab[ctb_addr_ts]->refPicList[0];
}
@ -116,6 +117,8 @@ static HEVCFrame *alloc_frame(HEVCContext *s, HEVCLayerContext *l)
if (ret < 0)
goto fail;
frame->pps = ff_refstruct_ref_c(s->pps);
return frame;
fail:
ff_hevc_unref_frame(frame, ~0);