From fc8df81cb1cce63d9a15b45dbd4abd2cb18b610f Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 5 Jun 2024 16:37:30 +0200 Subject: [PATCH] lavc/hevcdec: move active SPS from HEVCParamSets to HEVCLayerContext Currently active SPS is a per-layer property. --- libavcodec/hevc/hevcdec.c | 29 ++++++++++++++++------------- libavcodec/hevc/hevcdec.h | 2 ++ libavcodec/hevc/ps.c | 6 ------ libavcodec/hevc/ps.h | 3 --- libavcodec/hevc/refs.c | 24 ++++++++++++------------ libavcodec/vaapi_hevc.c | 4 ++-- libavcodec/vdpau_hevc.c | 2 +- 7 files changed, 33 insertions(+), 37 deletions(-) diff --git a/libavcodec/hevc/hevcdec.c b/libavcodec/hevc/hevcdec.c index eb41f9a5d6..6b596f1573 100644 --- a/libavcodec/hevc/hevcdec.c +++ b/libavcodec/hevc/hevcdec.c @@ -555,7 +555,7 @@ static int set_sps(HEVCContext *s, HEVCLayerContext *l, const HEVCSPS *sps) int ret; pic_arrays_free(l); - s->ps.sps = NULL; + ff_refstruct_unref(&l->sps); ff_refstruct_unref(&s->vps); if (!sps) @@ -569,14 +569,14 @@ static int set_sps(HEVCContext *s, HEVCLayerContext *l, const HEVCSPS *sps) ff_hevc_dsp_init (&s->hevcdsp, sps->bit_depth); ff_videodsp_init (&s->vdsp, sps->bit_depth); - s->ps.sps = sps; + l->sps = ff_refstruct_ref_c(sps); s->vps = ff_refstruct_ref_c(sps->vps); return 0; fail: pic_arrays_free(l); - s->ps.sps = NULL; + ff_refstruct_unref(&l->sps); return ret; } @@ -2831,6 +2831,7 @@ static int decode_slice_data(HEVCContext *s, const HEVCLayerContext *l, static int set_side_data(HEVCContext *s) { + const HEVCSPS *sps = s->cur_frame->pps->sps; AVFrame *out = s->cur_frame->f; int ret; @@ -2846,8 +2847,8 @@ static int set_side_data(HEVCContext *s) } ret = ff_h2645_sei_to_frame(out, &s->sei.common, AV_CODEC_ID_HEVC, s->avctx, - &s->ps.sps->vui.common, - s->ps.sps->bit_depth, s->ps.sps->bit_depth_chroma, + &sps->vui.common, + sps->bit_depth, sps->bit_depth_chroma, s->cur_frame->poc /* no poc_offset in HEVC */); if (ret < 0) return ret; @@ -2932,7 +2933,7 @@ static int hevc_frame_start(HEVCContext *s, HEVCLayerContext *l) } ff_refstruct_replace(&s->pps, pps); - if (s->ps.sps != sps) { + if (l->sps != sps) { enum AVPixelFormat pix_fmt; ff_hevc_clear_refs(l); @@ -3523,8 +3524,10 @@ static av_cold int hevc_decode_free(AVCodecContext *avctx) { HEVCContext *s = avctx->priv_data; - for (int i = 0; i < FF_ARRAY_ELEMS(s->layers); i++) + for (int i = 0; i < FF_ARRAY_ELEMS(s->layers); i++) { pic_arrays_free(&s->layers[i]); + ff_refstruct_unref(&s->layers[i].sps); + } ff_refstruct_unref(&s->vps); ff_refstruct_unref(&s->pps); @@ -3620,10 +3623,14 @@ static int hevc_update_thread_context(AVCodecContext *dst, return ret; } } + + if (l->sps != l0->sps) { + ret = set_sps(s, l, l0->sps); + if (ret < 0) + return ret; + } } - if (s->ps.sps != s0->ps.sps) - s->ps.sps = NULL; for (int i = 0; i < FF_ARRAY_ELEMS(s->ps.vps_list); i++) ff_refstruct_replace(&s->ps.vps_list[i], s0->ps.vps_list[i]); @@ -3636,10 +3643,6 @@ static int hevc_update_thread_context(AVCodecContext *dst, // PPS do not persist between frames ff_refstruct_unref(&s->pps); - if (s->ps.sps != s0->ps.sps) - if ((ret = set_sps(s, &s->layers[0], s0->ps.sps)) < 0) - return ret; - s->poc_tid0 = s0->poc_tid0; s->eos = s0->eos; s->no_rasl_output_flag = s0->no_rasl_output_flag; diff --git a/libavcodec/hevc/hevcdec.h b/libavcodec/hevc/hevcdec.h index a534aee60f..e43f2d0201 100644 --- a/libavcodec/hevc/hevcdec.h +++ b/libavcodec/hevc/hevcdec.h @@ -442,6 +442,8 @@ typedef struct HEVCLocalContext { typedef struct HEVCLayerContext { HEVCFrame DPB[32]; + const HEVCSPS *sps; // RefStruct reference + int bs_width; int bs_height; diff --git a/libavcodec/hevc/ps.c b/libavcodec/hevc/ps.c index 0aff8db258..2c3b335966 100644 --- a/libavcodec/hevc/ps.c +++ b/libavcodec/hevc/ps.c @@ -66,15 +66,11 @@ static void remove_sps(HEVCParamSets *s, int id) { int i; if (s->sps_list[id]) { - if (s->sps == s->sps_list[id]) - s->sps = NULL; - /* drop all PPS that depend on this SPS */ for (i = 0; i < FF_ARRAY_ELEMS(s->pps_list); i++) if (s->pps_list[i] && s->pps_list[i]->sps_id == id) ff_refstruct_unref(&s->pps_list[i]); - av_assert0(!(s->sps_list[id] && s->sps == s->sps_list[id])); ff_refstruct_unref(&s->sps_list[id]); } } @@ -2045,8 +2041,6 @@ void ff_hevc_ps_uninit(HEVCParamSets *ps) ff_refstruct_unref(&ps->sps_list[i]); for (i = 0; i < FF_ARRAY_ELEMS(ps->pps_list); i++) ff_refstruct_unref(&ps->pps_list[i]); - - ps->sps = NULL; } int ff_hevc_compute_poc(const HEVCSPS *sps, int pocTid0, int poc_lsb, int nal_unit_type) diff --git a/libavcodec/hevc/ps.h b/libavcodec/hevc/ps.h index 554c86a656..331d163476 100644 --- a/libavcodec/hevc/ps.h +++ b/libavcodec/hevc/ps.h @@ -447,9 +447,6 @@ typedef struct HEVCParamSets { const HEVCVPS *vps_list[HEVC_MAX_VPS_COUNT]; ///< RefStruct references const HEVCSPS *sps_list[HEVC_MAX_SPS_COUNT]; ///< RefStruct references const HEVCPPS *pps_list[HEVC_MAX_PPS_COUNT]; ///< RefStruct references - - /* currently active parameter sets */ - const HEVCSPS *sps; } HEVCParamSets; /** diff --git a/libavcodec/hevc/refs.c b/libavcodec/hevc/refs.c index 58edc15a6f..09d759f936 100644 --- a/libavcodec/hevc/refs.c +++ b/libavcodec/hevc/refs.c @@ -103,7 +103,7 @@ static HEVCFrame *alloc_frame(HEVCContext *s, HEVCLayerContext *l) frame->rpl_tab = ff_refstruct_pool_get(l->rpl_tab_pool); if (!frame->rpl_tab) goto fail; - frame->ctb_count = s->ps.sps->ctb_width * s->ps.sps->ctb_height; + frame->ctb_count = l->sps->ctb_width * l->sps->ctb_height; for (j = 0; j < frame->ctb_count; j++) frame->rpl_tab[j] = frame->rpl; @@ -157,10 +157,10 @@ int ff_hevc_set_new_ref(HEVCContext *s, HEVCLayerContext *l, int poc) ref->flags = HEVC_FRAME_FLAG_SHORT_REF; ref->poc = poc; - ref->f->crop_left = s->ps.sps->output_window.left_offset; - ref->f->crop_right = s->ps.sps->output_window.right_offset; - ref->f->crop_top = s->ps.sps->output_window.top_offset; - ref->f->crop_bottom = s->ps.sps->output_window.bottom_offset; + ref->f->crop_left = l->sps->output_window.left_offset; + ref->f->crop_right = l->sps->output_window.right_offset; + ref->f->crop_top = l->sps->output_window.top_offset; + ref->f->crop_bottom = l->sps->output_window.bottom_offset; return 0; } @@ -321,7 +321,7 @@ int ff_hevc_slice_rpl(HEVCContext *s) static HEVCFrame *find_ref_idx(HEVCContext *s, HEVCLayerContext *l, int poc, uint8_t use_msb) { - int mask = use_msb ? ~0 : (1 << s->ps.sps->log2_max_poc_lsb) - 1; + int mask = use_msb ? ~0 : (1 << l->sps->log2_max_poc_lsb) - 1; int i; for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) { @@ -354,16 +354,16 @@ static HEVCFrame *generate_missing_ref(HEVCContext *s, HEVCLayerContext *l, int return NULL; if (!s->avctx->hwaccel) { - if (!s->ps.sps->pixel_shift) { + if (!l->sps->pixel_shift) { for (i = 0; frame->f->data[i]; i++) - memset(frame->f->data[i], 1 << (s->ps.sps->bit_depth - 1), - frame->f->linesize[i] * AV_CEIL_RSHIFT(s->ps.sps->height, s->ps.sps->vshift[i])); + memset(frame->f->data[i], 1 << (l->sps->bit_depth - 1), + frame->f->linesize[i] * AV_CEIL_RSHIFT(l->sps->height, l->sps->vshift[i])); } else { for (i = 0; frame->f->data[i]; i++) - for (y = 0; y < (s->ps.sps->height >> s->ps.sps->vshift[i]); y++) { + for (y = 0; y < (l->sps->height >> l->sps->vshift[i]); y++) { uint8_t *dst = frame->f->data[i] + y * frame->f->linesize[i]; - AV_WN16(dst, 1 << (s->ps.sps->bit_depth - 1)); - av_memcpy_backptr(dst + 2, 2, 2*(s->ps.sps->width >> s->ps.sps->hshift[i]) - 2); + AV_WN16(dst, 1 << (l->sps->bit_depth - 1)); + av_memcpy_backptr(dst + 2, 2, 2*(l->sps->width >> l->sps->hshift[i]) - 2); } } } diff --git a/libavcodec/vaapi_hevc.c b/libavcodec/vaapi_hevc.c index b97e7c0343..0c5a829220 100644 --- a/libavcodec/vaapi_hevc.c +++ b/libavcodec/vaapi_hevc.c @@ -407,7 +407,7 @@ static void fill_pred_weight_table(AVCodecContext *avctx, slice_param->luma_log2_weight_denom = sh->luma_log2_weight_denom; - if (h->ps.sps->chroma_format_idc) { + if (h->pps->sps->chroma_format_idc) { slice_param->delta_chroma_log2_weight_denom = sh->chroma_log2_weight_denom - sh->luma_log2_weight_denom; } @@ -596,7 +596,7 @@ static int ptl_convert(const PTLCommon *general_ptl, H265RawProfileTierLevel *h2 VAProfile ff_vaapi_parse_hevc_rext_scc_profile(AVCodecContext *avctx) { const HEVCContext *h = avctx->priv_data; - const HEVCSPS *sps = h->ps.sps; + const HEVCSPS *sps = h->pps->sps; const PTL *ptl = &sps->ptl; const PTLCommon *general_ptl = &ptl->general_ptl; const H265ProfileDescriptor *profile; diff --git a/libavcodec/vdpau_hevc.c b/libavcodec/vdpau_hevc.c index e6232567e0..affb7e7f5a 100644 --- a/libavcodec/vdpau_hevc.c +++ b/libavcodec/vdpau_hevc.c @@ -470,7 +470,7 @@ static int ptl_convert(const PTLCommon *general_ptl, H265RawProfileTierLevel *h2 static int vdpau_hevc_parse_rext_profile(AVCodecContext *avctx, VdpDecoderProfile *vdp_profile) { const HEVCContext *h = avctx->priv_data; - const HEVCSPS *sps = h->ps.sps; + const HEVCSPS *sps = h->pps->sps; const PTL *ptl = &sps->ptl; const PTLCommon *general_ptl = &ptl->general_ptl; const H265ProfileDescriptor *profile;