Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
* [FFmpeg-devel] [PATCH] lavc/vvc: Store RefStruct references to referenced PSs/headers in slice (PR #20557)
@ 2025-09-19 20:23 frankplow via ffmpeg-devel
  0 siblings, 0 replies; only message in thread
From: frankplow via ffmpeg-devel @ 2025-09-19 20:23 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: frankplow

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

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2025-09-19 20:24 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-09-19 20:23 [FFmpeg-devel] [PATCH] lavc/vvc: Store RefStruct references to referenced PSs/headers in slice (PR #20557) frankplow via ffmpeg-devel

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