[FFmpeg-devel] [PATCH 05/39] lavc/hevc_ps: make SPS hold a reference to its VPS

Anton Khirnov anton at khirnov.net
Fri Jun 7 16:01:01 EEST 2024


SPS and its dependent PPSes depend on, and are parsed for, specific VPS data.

This will be useful in following commits.
---
 libavcodec/hevc/hevcdec.c |  5 ++---
 libavcodec/hevc/parser.c  |  2 +-
 libavcodec/hevc/ps.c      | 13 +++++++++----
 libavcodec/hevc/ps.h      |  2 ++
 4 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/libavcodec/hevc/hevcdec.c b/libavcodec/hevc/hevcdec.c
index ae4a5888e5..16c46997a8 100644
--- a/libavcodec/hevc/hevcdec.c
+++ b/libavcodec/hevc/hevcdec.c
@@ -319,8 +319,7 @@ static int decode_lt_rps(HEVCContext *s, LongTermRPS *rps, GetBitContext *gb)
 static void export_stream_params(HEVCContext *s, const HEVCSPS *sps)
 {
     AVCodecContext *avctx = s->avctx;
-    const HEVCParamSets *ps = &s->ps;
-    const HEVCVPS *vps = ps->vps_list[sps->vps_id];
+    const HEVCVPS    *vps = sps->vps;
     const HEVCWindow *ow = &sps->output_window;
     unsigned int num = 0, den = 0;
 
@@ -575,7 +574,7 @@ static int set_sps(HEVCContext *s, const HEVCSPS *sps,
     }
 
     s->ps.sps = sps;
-    s->ps.vps = s->ps.vps_list[s->ps.sps->vps_id];
+    s->ps.vps = sps->vps;
 
     return 0;
 
diff --git a/libavcodec/hevc/parser.c b/libavcodec/hevc/parser.c
index d0d5e7fbc2..49f7bccdfa 100644
--- a/libavcodec/hevc/parser.c
+++ b/libavcodec/hevc/parser.c
@@ -82,7 +82,7 @@ static int hevc_parse_slice_header(AVCodecParserContext *s, H2645NAL *nal,
 
     if (ps->sps != ps->pps->sps) {
         ps->sps  = ps->pps->sps;
-        ps->vps  = ps->vps_list[ps->sps->vps_id];
+        ps->vps  = ps->sps->vps;
     }
     ow  = &ps->sps->output_window;
 
diff --git a/libavcodec/hevc/ps.c b/libavcodec/hevc/ps.c
index 98217e337b..eabed69b94 100644
--- a/libavcodec/hevc/ps.c
+++ b/libavcodec/hevc/ps.c
@@ -889,10 +889,13 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id,
 
     sps->vps_id = get_bits(gb, 4);
 
-    if (vps_list && !vps_list[sps->vps_id]) {
-        av_log(avctx, AV_LOG_ERROR, "VPS %d does not exist\n",
-               sps->vps_id);
-        return AVERROR_INVALIDDATA;
+    if (vps_list) {
+        if (!vps_list[sps->vps_id]) {
+            av_log(avctx, AV_LOG_ERROR, "VPS %d does not exist\n",
+                   sps->vps_id);
+            return AVERROR_INVALIDDATA;
+        }
+        sps->vps = ff_refstruct_ref_c(vps_list[sps->vps_id]);
     }
 
     sps->max_sub_layers = get_bits(gb, 3) + 1;
@@ -1298,6 +1301,8 @@ static void hevc_sps_free(FFRefStructOpaque opaque, void *obj)
 {
     HEVCSPS *sps = obj;
 
+    ff_refstruct_unref(&sps->vps);
+
     av_freep(&sps->data);
 }
 
diff --git a/libavcodec/hevc/ps.h b/libavcodec/hevc/ps.h
index 7c9aacf057..fc10876756 100644
--- a/libavcodec/hevc/ps.h
+++ b/libavcodec/hevc/ps.h
@@ -302,6 +302,8 @@ typedef struct HEVCSPS {
 
     uint8_t *data;
     int data_size;
+
+    const HEVCVPS *vps; ///< RefStruct reference
 } HEVCSPS;
 
 typedef struct HEVCPPS {
-- 
2.43.0



More information about the ffmpeg-devel mailing list