[FFmpeg-devel] [PATCH 08/42] lavc/hevcdec: move active VPS from HEVCParamSets to HEVCContext

Anton Khirnov anton at khirnov.net
Tue Aug 27 18:04:48 EEST 2024


Active VPS is a property of the decoding process, not of the list of
parameter sets.

Check that the VPS can only change in a base layer - while this can
never happen currently (as no other layers can exist in the decoder), it
will become useful when multilayer decoding is supported.
---
 libavcodec/hevc/hevcdec.c | 11 +++++++++--
 libavcodec/hevc/hevcdec.h |  1 +
 libavcodec/hevc/ps.c      |  4 ----
 libavcodec/hevc/ps.h      |  1 -
 4 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/libavcodec/hevc/hevcdec.c b/libavcodec/hevc/hevcdec.c
index 669c8f550b..b44bc93507 100644
--- a/libavcodec/hevc/hevcdec.c
+++ b/libavcodec/hevc/hevcdec.c
@@ -533,7 +533,7 @@ static int set_sps(HEVCContext *s, const HEVCSPS *sps)
 
     pic_arrays_free(s);
     s->ps.sps = NULL;
-    s->ps.vps = NULL;
+    ff_refstruct_unref(&s->vps);
 
     if (!sps)
         return 0;
@@ -571,7 +571,7 @@ static int set_sps(HEVCContext *s, const HEVCSPS *sps)
     }
 
     s->ps.sps = sps;
-    s->ps.vps = sps->vps;
+    s->vps    = ff_refstruct_ref_c(sps->vps);
 
     return 0;
 
@@ -2911,6 +2911,12 @@ static int hevc_frame_start(HEVCContext *s, HEVCLayerContext *l)
     int new_sequence = IS_IDR(s) || IS_BLA(s) || s->last_eos;
     int ret;
 
+    if (sps->vps != s->vps && l != &s->layers[0]) {
+        av_log(s->avctx, AV_LOG_ERROR, "VPS changed in a non-base layer\n");
+        set_sps(s, NULL, AV_PIX_FMT_NONE);
+        return AVERROR_INVALIDDATA;
+    }
+
     ff_refstruct_replace(&s->pps, pps);
     if (s->ps.sps != sps) {
         enum AVPixelFormat pix_fmt;
@@ -3505,6 +3511,7 @@ static av_cold int hevc_decode_free(AVCodecContext *avctx)
 
     pic_arrays_free(s);
 
+    ff_refstruct_unref(&s->vps);
     ff_refstruct_unref(&s->pps);
 
     ff_dovi_ctx_unref(&s->dovi_ctx);
diff --git a/libavcodec/hevc/hevcdec.h b/libavcodec/hevc/hevcdec.h
index aab09bfd94..be5d76c183 100644
--- a/libavcodec/hevc/hevcdec.h
+++ b/libavcodec/hevc/hevcdec.h
@@ -470,6 +470,7 @@ typedef struct HEVCContext {
     ///< candidate references for the current frame
     RefPicList rps[5];
 
+    const HEVCVPS *vps; ///< RefStruct reference
     const HEVCPPS *pps; ///< RefStruct reference
     SliceHeader sh;
     SAOParams *sao;
diff --git a/libavcodec/hevc/ps.c b/libavcodec/hevc/ps.c
index dbdfc16cfa..99382876af 100644
--- a/libavcodec/hevc/ps.c
+++ b/libavcodec/hevc/ps.c
@@ -83,9 +83,6 @@ static void remove_vps(HEVCParamSets *s, int id)
 {
     int i;
     if (s->vps_list[id]) {
-        if (s->vps == s->vps_list[id])
-            s->vps = NULL;
-
         for (i = 0; i < FF_ARRAY_ELEMS(s->sps_list); i++)
             if (s->sps_list[i] && s->sps_list[i]->vps_id == id)
                 remove_sps(s, i);
@@ -2047,7 +2044,6 @@ void ff_hevc_ps_uninit(HEVCParamSets *ps)
         ff_refstruct_unref(&ps->pps_list[i]);
 
     ps->sps = NULL;
-    ps->vps = 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 17395c5510..554c86a656 100644
--- a/libavcodec/hevc/ps.h
+++ b/libavcodec/hevc/ps.h
@@ -449,7 +449,6 @@ typedef struct HEVCParamSets {
     const HEVCPPS *pps_list[HEVC_MAX_PPS_COUNT]; ///< RefStruct references
 
     /* currently active parameter sets */
-    const HEVCVPS *vps;
     const HEVCSPS *sps;
 } HEVCParamSets;
 
-- 
2.43.0



More information about the ffmpeg-devel mailing list