[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