[FFmpeg-cvslog] lavc/hevcdec: move active SPS from HEVCParamSets to HEVCLayerContext

Anton Khirnov git at videolan.org
Fri Sep 6 15:26:10 EEST 2024


ffmpeg | branch: master | Anton Khirnov <anton at khirnov.net> | Wed Jun  5 16:37:30 2024 +0200| [fc8df81cb1cce63d9a15b45dbd4abd2cb18b610f] | committer: Anton Khirnov

lavc/hevcdec: move active SPS from HEVCParamSets to HEVCLayerContext

Currently active SPS is a per-layer property.

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=fc8df81cb1cce63d9a15b45dbd4abd2cb18b610f
---

 libavcodec/hevc/hevcdec.c | 29 ++++++++++++++++-------------
 libavcodec/hevc/hevcdec.h |  2 ++
 libavcodec/hevc/ps.c      |  6 ------
 libavcodec/hevc/ps.h      |  3 ---
 libavcodec/hevc/refs.c    | 24 ++++++++++++------------
 libavcodec/vaapi_hevc.c   |  4 ++--
 libavcodec/vdpau_hevc.c   |  2 +-
 7 files changed, 33 insertions(+), 37 deletions(-)

diff --git a/libavcodec/hevc/hevcdec.c b/libavcodec/hevc/hevcdec.c
index eb41f9a5d6..6b596f1573 100644
--- a/libavcodec/hevc/hevcdec.c
+++ b/libavcodec/hevc/hevcdec.c
@@ -555,7 +555,7 @@ static int set_sps(HEVCContext *s, HEVCLayerContext *l, const HEVCSPS *sps)
     int ret;
 
     pic_arrays_free(l);
-    s->ps.sps = NULL;
+    ff_refstruct_unref(&l->sps);
     ff_refstruct_unref(&s->vps);
 
     if (!sps)
@@ -569,14 +569,14 @@ static int set_sps(HEVCContext *s, HEVCLayerContext *l, const HEVCSPS *sps)
     ff_hevc_dsp_init (&s->hevcdsp, sps->bit_depth);
     ff_videodsp_init (&s->vdsp,    sps->bit_depth);
 
-    s->ps.sps = sps;
+    l->sps    = ff_refstruct_ref_c(sps);
     s->vps    = ff_refstruct_ref_c(sps->vps);
 
     return 0;
 
 fail:
     pic_arrays_free(l);
-    s->ps.sps = NULL;
+    ff_refstruct_unref(&l->sps);
     return ret;
 }
 
@@ -2831,6 +2831,7 @@ static int decode_slice_data(HEVCContext *s, const HEVCLayerContext *l,
 
 static int set_side_data(HEVCContext *s)
 {
+    const HEVCSPS *sps = s->cur_frame->pps->sps;
     AVFrame *out = s->cur_frame->f;
     int ret;
 
@@ -2846,8 +2847,8 @@ static int set_side_data(HEVCContext *s)
     }
 
     ret = ff_h2645_sei_to_frame(out, &s->sei.common, AV_CODEC_ID_HEVC, s->avctx,
-                                &s->ps.sps->vui.common,
-                                s->ps.sps->bit_depth, s->ps.sps->bit_depth_chroma,
+                                &sps->vui.common,
+                                sps->bit_depth, sps->bit_depth_chroma,
                                 s->cur_frame->poc /* no poc_offset in HEVC */);
     if (ret < 0)
         return ret;
@@ -2932,7 +2933,7 @@ static int hevc_frame_start(HEVCContext *s, HEVCLayerContext *l)
     }
 
     ff_refstruct_replace(&s->pps, pps);
-    if (s->ps.sps != sps) {
+    if (l->sps != sps) {
         enum AVPixelFormat pix_fmt;
 
         ff_hevc_clear_refs(l);
@@ -3523,8 +3524,10 @@ static av_cold int hevc_decode_free(AVCodecContext *avctx)
 {
     HEVCContext       *s = avctx->priv_data;
 
-    for (int i = 0; i < FF_ARRAY_ELEMS(s->layers); i++)
+    for (int i = 0; i < FF_ARRAY_ELEMS(s->layers); i++) {
         pic_arrays_free(&s->layers[i]);
+        ff_refstruct_unref(&s->layers[i].sps);
+    }
 
     ff_refstruct_unref(&s->vps);
     ff_refstruct_unref(&s->pps);
@@ -3620,10 +3623,14 @@ static int hevc_update_thread_context(AVCodecContext *dst,
                     return ret;
             }
         }
+
+        if (l->sps != l0->sps) {
+            ret = set_sps(s, l, l0->sps);
+            if (ret < 0)
+                return ret;
+        }
     }
 
-    if (s->ps.sps != s0->ps.sps)
-        s->ps.sps = NULL;
     for (int i = 0; i < FF_ARRAY_ELEMS(s->ps.vps_list); i++)
         ff_refstruct_replace(&s->ps.vps_list[i], s0->ps.vps_list[i]);
 
@@ -3636,10 +3643,6 @@ static int hevc_update_thread_context(AVCodecContext *dst,
     // PPS do not persist between frames
     ff_refstruct_unref(&s->pps);
 
-    if (s->ps.sps != s0->ps.sps)
-        if ((ret = set_sps(s, &s->layers[0], s0->ps.sps)) < 0)
-            return ret;
-
     s->poc_tid0   = s0->poc_tid0;
     s->eos        = s0->eos;
     s->no_rasl_output_flag = s0->no_rasl_output_flag;
diff --git a/libavcodec/hevc/hevcdec.h b/libavcodec/hevc/hevcdec.h
index a534aee60f..e43f2d0201 100644
--- a/libavcodec/hevc/hevcdec.h
+++ b/libavcodec/hevc/hevcdec.h
@@ -442,6 +442,8 @@ typedef struct HEVCLocalContext {
 typedef struct HEVCLayerContext {
     HEVCFrame               DPB[32];
 
+    const HEVCSPS          *sps; // RefStruct reference
+
     int                     bs_width;
     int                     bs_height;
 
diff --git a/libavcodec/hevc/ps.c b/libavcodec/hevc/ps.c
index 0aff8db258..2c3b335966 100644
--- a/libavcodec/hevc/ps.c
+++ b/libavcodec/hevc/ps.c
@@ -66,15 +66,11 @@ static void remove_sps(HEVCParamSets *s, int id)
 {
     int i;
     if (s->sps_list[id]) {
-        if (s->sps == s->sps_list[id])
-            s->sps = NULL;
-
         /* drop all PPS that depend on this SPS */
         for (i = 0; i < FF_ARRAY_ELEMS(s->pps_list); i++)
             if (s->pps_list[i] && s->pps_list[i]->sps_id == id)
                 ff_refstruct_unref(&s->pps_list[i]);
 
-        av_assert0(!(s->sps_list[id] && s->sps == s->sps_list[id]));
         ff_refstruct_unref(&s->sps_list[id]);
     }
 }
@@ -2045,8 +2041,6 @@ void ff_hevc_ps_uninit(HEVCParamSets *ps)
         ff_refstruct_unref(&ps->sps_list[i]);
     for (i = 0; i < FF_ARRAY_ELEMS(ps->pps_list); i++)
         ff_refstruct_unref(&ps->pps_list[i]);
-
-    ps->sps = 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 554c86a656..331d163476 100644
--- a/libavcodec/hevc/ps.h
+++ b/libavcodec/hevc/ps.h
@@ -447,9 +447,6 @@ typedef struct HEVCParamSets {
     const HEVCVPS *vps_list[HEVC_MAX_VPS_COUNT]; ///< RefStruct references
     const HEVCSPS *sps_list[HEVC_MAX_SPS_COUNT]; ///< RefStruct references
     const HEVCPPS *pps_list[HEVC_MAX_PPS_COUNT]; ///< RefStruct references
-
-    /* currently active parameter sets */
-    const HEVCSPS *sps;
 } HEVCParamSets;
 
 /**
diff --git a/libavcodec/hevc/refs.c b/libavcodec/hevc/refs.c
index 58edc15a6f..09d759f936 100644
--- a/libavcodec/hevc/refs.c
+++ b/libavcodec/hevc/refs.c
@@ -103,7 +103,7 @@ static HEVCFrame *alloc_frame(HEVCContext *s, HEVCLayerContext *l)
         frame->rpl_tab = ff_refstruct_pool_get(l->rpl_tab_pool);
         if (!frame->rpl_tab)
             goto fail;
-        frame->ctb_count = s->ps.sps->ctb_width * s->ps.sps->ctb_height;
+        frame->ctb_count = l->sps->ctb_width * l->sps->ctb_height;
         for (j = 0; j < frame->ctb_count; j++)
             frame->rpl_tab[j] = frame->rpl;
 
@@ -157,10 +157,10 @@ int ff_hevc_set_new_ref(HEVCContext *s, HEVCLayerContext *l, int poc)
         ref->flags = HEVC_FRAME_FLAG_SHORT_REF;
 
     ref->poc      = poc;
-    ref->f->crop_left   = s->ps.sps->output_window.left_offset;
-    ref->f->crop_right  = s->ps.sps->output_window.right_offset;
-    ref->f->crop_top    = s->ps.sps->output_window.top_offset;
-    ref->f->crop_bottom = s->ps.sps->output_window.bottom_offset;
+    ref->f->crop_left   = l->sps->output_window.left_offset;
+    ref->f->crop_right  = l->sps->output_window.right_offset;
+    ref->f->crop_top    = l->sps->output_window.top_offset;
+    ref->f->crop_bottom = l->sps->output_window.bottom_offset;
 
     return 0;
 }
@@ -321,7 +321,7 @@ int ff_hevc_slice_rpl(HEVCContext *s)
 static HEVCFrame *find_ref_idx(HEVCContext *s, HEVCLayerContext *l,
                                int poc, uint8_t use_msb)
 {
-    int mask = use_msb ? ~0 : (1 << s->ps.sps->log2_max_poc_lsb) - 1;
+    int mask = use_msb ? ~0 : (1 << l->sps->log2_max_poc_lsb) - 1;
     int i;
 
     for (i = 0; i < FF_ARRAY_ELEMS(l->DPB); i++) {
@@ -354,16 +354,16 @@ static HEVCFrame *generate_missing_ref(HEVCContext *s, HEVCLayerContext *l, int
         return NULL;
 
     if (!s->avctx->hwaccel) {
-        if (!s->ps.sps->pixel_shift) {
+        if (!l->sps->pixel_shift) {
             for (i = 0; frame->f->data[i]; i++)
-                memset(frame->f->data[i], 1 << (s->ps.sps->bit_depth - 1),
-                       frame->f->linesize[i] * AV_CEIL_RSHIFT(s->ps.sps->height, s->ps.sps->vshift[i]));
+                memset(frame->f->data[i], 1 << (l->sps->bit_depth - 1),
+                       frame->f->linesize[i] * AV_CEIL_RSHIFT(l->sps->height, l->sps->vshift[i]));
         } else {
             for (i = 0; frame->f->data[i]; i++)
-                for (y = 0; y < (s->ps.sps->height >> s->ps.sps->vshift[i]); y++) {
+                for (y = 0; y < (l->sps->height >> l->sps->vshift[i]); y++) {
                     uint8_t *dst = frame->f->data[i] + y * frame->f->linesize[i];
-                    AV_WN16(dst, 1 << (s->ps.sps->bit_depth - 1));
-                    av_memcpy_backptr(dst + 2, 2, 2*(s->ps.sps->width >> s->ps.sps->hshift[i]) - 2);
+                    AV_WN16(dst, 1 << (l->sps->bit_depth - 1));
+                    av_memcpy_backptr(dst + 2, 2, 2*(l->sps->width >> l->sps->hshift[i]) - 2);
                 }
         }
     }
diff --git a/libavcodec/vaapi_hevc.c b/libavcodec/vaapi_hevc.c
index b97e7c0343..0c5a829220 100644
--- a/libavcodec/vaapi_hevc.c
+++ b/libavcodec/vaapi_hevc.c
@@ -407,7 +407,7 @@ static void fill_pred_weight_table(AVCodecContext *avctx,
 
     slice_param->luma_log2_weight_denom = sh->luma_log2_weight_denom;
 
-    if (h->ps.sps->chroma_format_idc) {
+    if (h->pps->sps->chroma_format_idc) {
         slice_param->delta_chroma_log2_weight_denom = sh->chroma_log2_weight_denom - sh->luma_log2_weight_denom;
     }
 
@@ -596,7 +596,7 @@ static int ptl_convert(const PTLCommon *general_ptl, H265RawProfileTierLevel *h2
 VAProfile ff_vaapi_parse_hevc_rext_scc_profile(AVCodecContext *avctx)
 {
     const HEVCContext *h = avctx->priv_data;
-    const HEVCSPS *sps = h->ps.sps;
+    const HEVCSPS *sps = h->pps->sps;
     const PTL *ptl = &sps->ptl;
     const PTLCommon *general_ptl = &ptl->general_ptl;
     const H265ProfileDescriptor *profile;
diff --git a/libavcodec/vdpau_hevc.c b/libavcodec/vdpau_hevc.c
index e6232567e0..affb7e7f5a 100644
--- a/libavcodec/vdpau_hevc.c
+++ b/libavcodec/vdpau_hevc.c
@@ -470,7 +470,7 @@ static int ptl_convert(const PTLCommon *general_ptl, H265RawProfileTierLevel *h2
 static int vdpau_hevc_parse_rext_profile(AVCodecContext *avctx, VdpDecoderProfile *vdp_profile)
 {
     const HEVCContext *h = avctx->priv_data;
-    const HEVCSPS *sps = h->ps.sps;
+    const HEVCSPS *sps = h->pps->sps;
     const PTL *ptl = &sps->ptl;
     const PTLCommon *general_ptl = &ptl->general_ptl;
     const H265ProfileDescriptor *profile;



More information about the ffmpeg-cvslog mailing list