From: frankplow via ffmpeg-devel <ffmpeg-devel@ffmpeg.org> To: ffmpeg-devel@ffmpeg.org Cc: frankplow <code@ffmpeg.org> Subject: [FFmpeg-devel] [PATCH] lavc/vvc: Store RefStruct references to referenced PSs/headers in slice (PR #20557) Date: Fri, 19 Sep 2025 20:23:44 -0000 Message-ID: <175831342515.25.6278373688975206795@463a07221176> (raw) PR #20557 opened by frankplow URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20557 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20557.patch This loosens the coupling between CBS and the decoder by no longer using `CodedBitstreamH266Context` (containing the most recently parsed PSs & PH) to retrieve the PSs & PH in the decoder. Doing so is beneficial in two ways: 1. It improves robustness to the case in which an `AVPacket` doesn't contain precisely one PU. 2. It allows the decoder parameter set manager to properly handle the case in which a single PU (erroneously) contains conflicting parameter sets. >From b736ddd0f324c03577577a721bf82a522d658432 Mon Sep 17 00:00:00 2001 From: Frank Plowman <post@frankplowman.com> Date: Thu, 18 Sep 2025 21:24:29 +0100 Subject: [PATCH] lavc/vvc: Store RefStruct references to referenced PSs/headers in slice This loosens the coupling between CBS and the decoder by no longer using CodedBitstreamH266Context (containing the most recently parsed PSs & PH) to retrieve the PSs & PH in the decoder. Doing so is beneficial in two ways: 1. It improves robustness to the case in which an AVPacket doesn't contain precisely one PU. 2. It allows the decoder parameter set manager to properly handle the case in which a single PU (erroneously) contains conflicting parameter sets. --- libavcodec/cbs_h2645.c | 28 +++++++++++++++++++++++----- libavcodec/cbs_h266.h | 5 +++++ libavcodec/vvc/dec.c | 5 ++--- libavcodec/vvc/ps.c | 32 ++++++++++++++------------------ libavcodec/vvc/ps.h | 3 ++- 5 files changed, 46 insertions(+), 27 deletions(-) diff --git a/libavcodec/cbs_h2645.c b/libavcodec/cbs_h2645.c index 75784b03a9..f537686245 100644 --- a/libavcodec/cbs_h2645.c +++ b/libavcodec/cbs_h2645.c @@ -1086,6 +1086,7 @@ static int cbs_h266_read_nal_unit(CodedBitstreamContext *ctx, { GetBitContext gbc; int err; + CodedBitstreamH266Context *h266 = ctx->priv_data; err = init_get_bits8(&gbc, unit->data, unit->data_size); if (err < 0) @@ -1201,7 +1202,13 @@ static int cbs_h266_read_nal_unit(CodedBitstreamContext *ctx, err = cbs_h266_replace_ph(ctx, unit, &slice->header.sh_picture_header); if (err < 0) return err; + slice->ph_ref = NULL; + } else { + slice->ph_ref = av_refstruct_ref(h266->ph_ref); } + slice->ph = h266->ph; + slice->pps = av_refstruct_ref(h266->pps[slice->ph->ph_pic_parameter_set_id]); + slice->sps = av_refstruct_ref(h266->sps[slice->pps->pps_seq_parameter_set_id]); slice->header_size = pos / 8; slice->data_size = len - pos / 8; @@ -2037,6 +2044,16 @@ static const CodedBitstreamUnitTypeDescriptor cbs_h265_unit_types[] = { CBS_UNIT_TYPE_END_OF_LIST }; +static void cbs_h266_free_slice(AVRefStructOpaque unused, void *content) +{ + H266RawSlice *slice = content; + av_buffer_unref(&slice->data_ref); + av_refstruct_unref(&slice->sps); + av_refstruct_unref(&slice->pps); + av_refstruct_unref(&slice->ph_ref); +} + + static void cbs_h266_free_sei(AVRefStructOpaque unused, void *content) { H266RawSEI *sei = content; @@ -2065,11 +2082,12 @@ static const CodedBitstreamUnitTypeDescriptor cbs_h266_unit_types[] = { CBS_UNIT_TYPE_POD(VVC_PH_NUT , H266RawPH), CBS_UNIT_TYPE_POD(VVC_AUD_NUT, H266RawAUD), - CBS_UNIT_RANGE_INTERNAL_REF(VVC_TRAIL_NUT, VVC_RASL_NUT, - H266RawSlice, data), - - CBS_UNIT_RANGE_INTERNAL_REF(VVC_IDR_W_RADL, VVC_GDR_NUT, - H266RawSlice, data), + CBS_UNIT_TYPES_COMPLEX((VVC_TRAIL_NUT, VVC_STSA_NUT, VVC_RADL_NUT), + H266RawSlice, cbs_h266_free_slice), + CBS_UNIT_TYPES_COMPLEX((VVC_RASL_NUT, VVC_IDR_W_RADL, VVC_IDR_N_LP), + H266RawSlice, cbs_h266_free_slice), + CBS_UNIT_TYPES_COMPLEX((VVC_CRA_NUT, VVC_GDR_NUT), + H266RawSlice, cbs_h266_free_slice), CBS_UNIT_TYPES_COMPLEX((VVC_PREFIX_SEI_NUT, VVC_SUFFIX_SEI_NUT), H266RawSEI, cbs_h266_free_sei), diff --git a/libavcodec/cbs_h266.h b/libavcodec/cbs_h266.h index 67a3ff6151..8d851a0bfb 100644 --- a/libavcodec/cbs_h266.h +++ b/libavcodec/cbs_h266.h @@ -848,6 +848,11 @@ typedef struct H266RawSlice { size_t header_size; size_t data_size; int data_bit_start; + + H266RawSPS *sps; ///< RefStruct reference to referred-to SPS + H266RawPPS *pps; ///< RefStruct reference to referred-to PPS + H266RawPictureHeader *ph; + void *ph_ref; ///< RefStruct reference backing referred-to PH above } H266RawSlice; typedef struct H266RawSEI { diff --git a/libavcodec/vvc/dec.c b/libavcodec/vvc/dec.c index 6f52306080..7ef5bf1b71 100644 --- a/libavcodec/vvc/dec.c +++ b/libavcodec/vvc/dec.c @@ -852,8 +852,6 @@ static int slice_start(SliceContext *sc, VVCContext *s, VVCFrameContext *fc, if (ret < 0) return ret; - av_refstruct_replace(&sc->ref, unit->content_ref); - if (is_first_slice) { ret = frame_start(s, fc, sc); if (ret < 0) @@ -927,7 +925,7 @@ static int export_frame_params(VVCContext *s, const VVCFrameContext *fc) static int frame_setup(VVCFrameContext *fc, VVCContext *s) { - int ret = ff_vvc_decode_frame_ps(&fc->ps, s); + int ret = ff_vvc_decode_frame_ps(fc, s); if (ret < 0) return ret; @@ -954,6 +952,7 @@ static int decode_slice(VVCContext *s, VVCFrameContext *fc, AVBufferRef *buf_ref return ret; sc = fc->slices[fc->nb_slices]; + av_refstruct_replace(&sc->ref, unit->content_ref); s->vcl_unit_type = nal->type; if (is_first_slice) { diff --git a/libavcodec/vvc/ps.c b/libavcodec/vvc/ps.c index 6eec0fe586..8faee1d826 100644 --- a/libavcodec/vvc/ps.c +++ b/libavcodec/vvc/ps.c @@ -743,21 +743,16 @@ static int decode_pps(VVCParamSets *ps, const H266RawPPS *rpps) return ret; } -static int decode_ps(VVCParamSets *ps, AVCodecContext *c, const CodedBitstreamH266Context *h266, int is_clvss) +static int decode_ps(VVCParamSets *ps, AVCodecContext *c, const SliceContext *sc, int is_clvss) { - const H266RawPictureHeader *ph = h266->ph; - const H266RawPPS *rpps; - const H266RawSPS *rsps; + const H266RawSlice *sl = sc->ref; + const H266RawPPS *rpps = sl->pps; + const H266RawSPS *rsps = sl->sps; int ret; - if (!ph) - return AVERROR_INVALIDDATA; - - rpps = h266->pps[ph->ph_pic_parameter_set_id]; if (!rpps) return AVERROR_INVALIDDATA; - rsps = h266->sps[rpps->pps_seq_parameter_set_id]; if (!rsps) return AVERROR_INVALIDDATA; @@ -1005,23 +1000,23 @@ static int decode_ph(VVCFrameParamSets *fps, const H266RawPictureHeader *rph, vo } static int decode_frame_ps(VVCFrameParamSets *fps, const VVCParamSets *ps, - const CodedBitstreamH266Context *h266, const int poc_tid0, const int is_clvss) + const SliceContext *sc, const int poc_tid0, const int is_clvss, const VVCContext *s) { - const H266RawPictureHeader *ph = h266->ph; - const H266RawPPS *rpps; + const H266RawSlice *sl = sc->ref; + const H266RawPictureHeader *ph = sl->ph; + const H266RawPPS *rpps = sl->pps; int ret; if (!ph) return AVERROR_INVALIDDATA; - rpps = h266->pps[ph->ph_pic_parameter_set_id]; if (!rpps) return AVERROR_INVALIDDATA; av_refstruct_replace(&fps->sps, ps->sps_list[rpps->pps_seq_parameter_set_id]); av_refstruct_replace(&fps->pps, ps->pps_list[rpps->pps_pic_parameter_set_id]); - ret = decode_ph(fps, ph, h266->ph_ref, poc_tid0, is_clvss); + ret = decode_ph(fps, ph, sl->ph_ref, poc_tid0, is_clvss); if (ret < 0) return ret; @@ -1058,21 +1053,22 @@ static void decode_recovery_poc(VVCContext *s, const VVCPH *ph) } } -int ff_vvc_decode_frame_ps(VVCFrameParamSets *fps, struct VVCContext *s) +int ff_vvc_decode_frame_ps(struct VVCFrameContext *fc, struct VVCContext *s) { int ret = 0; + VVCFrameParamSets *fps = &fc->ps; VVCParamSets *ps = &s->ps; - const CodedBitstreamH266Context *h266 = s->cbc->priv_data; + const SliceContext *sc = fc->slices[0]; int is_clvss; decode_recovery_flag(s); is_clvss = IS_CLVSS(s); - ret = decode_ps(ps, s->avctx, h266, is_clvss); + ret = decode_ps(ps, s->avctx, sc, is_clvss); if (ret < 0) return ret; - ret = decode_frame_ps(fps, ps, h266, s->poc_tid0, is_clvss); + ret = decode_frame_ps(fps, ps, sc, s->poc_tid0, is_clvss, s); decode_recovery_poc(s, &fps->ph); return ret; } diff --git a/libavcodec/vvc/ps.h b/libavcodec/vvc/ps.h index 3ec2238c17..90bd4c0e9e 100644 --- a/libavcodec/vvc/ps.h +++ b/libavcodec/vvc/ps.h @@ -266,8 +266,9 @@ typedef struct VVCSH { } VVCSH; struct VVCContext; +struct VVCFrameContext; -int ff_vvc_decode_frame_ps(VVCFrameParamSets *fps, struct VVCContext *s); +int ff_vvc_decode_frame_ps(struct VVCFrameContext *fc, struct VVCContext *s); int ff_vvc_decode_aps(VVCParamSets *ps, const CodedBitstreamUnit *unit); int ff_vvc_decode_sh(VVCSH *sh, const VVCFrameParamSets *ps, const CodedBitstreamUnit *unit); void ff_vvc_frame_ps_free(VVCFrameParamSets *fps); -- 2.49.1 _______________________________________________ ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
reply other threads:[~2025-09-19 20:24 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=175831342515.25.6278373688975206795@463a07221176 \ --to=ffmpeg-devel@ffmpeg.org \ --cc=code@ffmpeg.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git