From 9bccc634afeda243e19fdcae5641a87989c87af7 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 5 Jun 2024 12:02:27 +0200 Subject: [PATCH] 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. --- libavcodec/hevc/filter.c | 4 ++-- libavcodec/hevc/hevcdec.c | 1 + libavcodec/hevc/hevcdec.h | 4 ++-- libavcodec/hevc/mvs.c | 2 +- libavcodec/hevc/refs.c | 15 +++++++++------ 5 files changed, 15 insertions(+), 11 deletions(-) diff --git a/libavcodec/hevc/filter.c b/libavcodec/hevc/filter.c index 298f1792b2..68ae0e9ef6 100644 --- a/libavcodec/hevc/filter.c +++ b/libavcodec/hevc/filter.c @@ -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; diff --git a/libavcodec/hevc/hevcdec.c b/libavcodec/hevc/hevcdec.c index e02d5bba72..eb41f9a5d6 100644 --- a/libavcodec/hevc/hevcdec.c +++ b/libavcodec/hevc/hevcdec.c @@ -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); diff --git a/libavcodec/hevc/hevcdec.h b/libavcodec/hevc/hevcdec.h index 0b5d87b18f..a534aee60f 100644 --- a/libavcodec/hevc/hevcdec.h +++ b/libavcodec/hevc/hevcdec.h @@ -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. diff --git a/libavcodec/hevc/mvs.c b/libavcodec/hevc/mvs.c index 96d8d58f39..55f115ad0c 100644 --- a/libavcodec/hevc/mvs.c +++ b/libavcodec/hevc/mvs.c @@ -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 diff --git a/libavcodec/hevc/refs.c b/libavcodec/hevc/refs.c index 7b8dff4f55..58edc15a6f 100644 --- a/libavcodec/hevc/refs.c +++ b/libavcodec/hevc/refs.c @@ -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);