diff mbox series

[FFmpeg-devel,12/39] lavc/hevcdec: move active PPS from HEVCParamSets to HEVCContext

Message ID 20240607130135.9088-12-anton@khirnov.net
State New
Headers show
Series [FFmpeg-devel,01/39] lavc/hevcdec: do not free SliceHeader arrays in pic_arrays_free() | expand

Commit Message

Anton Khirnov June 7, 2024, 1:01 p.m. UTC
"Currently active PPS" is a property of the decoding process, not of the
list of available parameter sets.
---
 libavcodec/dxva2_hevc.c   |  8 ++++----
 libavcodec/hevc/hevcdec.c | 19 ++++++++++++-------
 libavcodec/hevc/hevcdec.h |  1 +
 libavcodec/hevc/ps.c      | 12 ++----------
 libavcodec/hevc/ps.h      |  1 -
 libavcodec/hevc/refs.c    | 12 ++++++------
 libavcodec/nvdec_hevc.c   | 10 +++++-----
 libavcodec/vaapi_hevc.c   | 12 ++++++------
 libavcodec/vdpau_hevc.c   |  4 ++--
 libavcodec/videotoolbox.c |  6 +++---
 libavcodec/vulkan_hevc.c  |  8 ++++----
 11 files changed, 45 insertions(+), 48 deletions(-)
diff mbox series

Patch

diff --git a/libavcodec/dxva2_hevc.c b/libavcodec/dxva2_hevc.c
index 2f4073edd6..bd2c6f72a4 100644
--- a/libavcodec/dxva2_hevc.c
+++ b/libavcodec/dxva2_hevc.c
@@ -62,8 +62,8 @@  void ff_dxva2_hevc_fill_picture_parameters(const AVCodecContext *avctx, AVDXVACo
 {
     const HEVCContext *h = avctx->priv_data;
     const HEVCFrame *current_picture = h->cur_frame;
-    const HEVCSPS *sps = h->ps.sps;
-    const HEVCPPS *pps = h->ps.pps;
+    const HEVCPPS *pps = h->pps;
+    const HEVCSPS *sps = pps->sps;
     int i, j;
 
     memset(pp, 0, sizeof(*pp));
@@ -205,8 +205,8 @@  void ff_dxva2_hevc_fill_scaling_lists(const AVCodecContext *avctx, AVDXVAContext
 {
     const HEVCContext *h = avctx->priv_data;
     unsigned i, j, pos;
-    const ScalingList *sl = h->ps.pps->scaling_list_data_present_flag ?
-                            &h->ps.pps->scaling_list : &h->ps.sps->scaling_list;
+    const ScalingList *sl = h->pps->scaling_list_data_present_flag ?
+                            &h->pps->scaling_list : &h->pps->sps->scaling_list;
 
     memset(qm, 0, sizeof(*qm));
     for (i = 0; i < 6; i++) {
diff --git a/libavcodec/hevc/hevcdec.c b/libavcodec/hevc/hevcdec.c
index 14b9a2a844..6dda923df5 100644
--- a/libavcodec/hevc/hevcdec.c
+++ b/libavcodec/hevc/hevcdec.c
@@ -618,12 +618,12 @@  static int hls_slice_header(HEVCContext *s, GetBitContext *gb)
         return AVERROR_INVALIDDATA;
     }
     if (!sh->first_slice_in_pic_flag &&
-        s->ps.pps != s->ps.pps_list[sh->pps_id]) {
+        s->pps != s->ps.pps_list[sh->pps_id]) {
         av_log(s->avctx, AV_LOG_ERROR, "PPS changed between slices.\n");
         return AVERROR_INVALIDDATA;
     }
-    s->ps.pps = s->ps.pps_list[sh->pps_id];
-    pps = s->ps.pps;
+    ff_refstruct_replace(&s->pps, s->ps.pps_list[sh->pps_id]);
+    pps = s->pps;
     sps = pps->sps;
 
     if (s->nal_unit_type == HEVC_NAL_CRA_NUT && s->last_eos == 1)
@@ -2588,7 +2588,7 @@  static void hls_decode_neighbour(HEVCLocalContext *lc,
 static int hls_decode_entry(HEVCContext *s, GetBitContext *gb)
 {
     HEVCLocalContext *const lc = &s->local_ctx[0];
-    const HEVCPPS   *const pps = s->ps.pps;
+    const HEVCPPS   *const pps = s->pps;
     const HEVCSPS   *const sps = pps->sps;
     const uint8_t *slice_data = gb->buffer + s->sh.data_offset;
     const size_t   slice_size = gb->buffer_end - gb->buffer - s->sh.data_offset;
@@ -2656,7 +2656,7 @@  static int hls_decode_entry_wpp(AVCodecContext *avctxt, void *hevc_lclist,
 {
     HEVCLocalContext *lc = &((HEVCLocalContext*)hevc_lclist)[self_id];
     const HEVCContext *const s = lc->parent;
-    const HEVCPPS   *const pps = s->ps.pps;
+    const HEVCPPS   *const pps = s->pps;
     const HEVCSPS   *const sps = pps->sps;
     int ctb_size    = 1 << sps->log2_ctb_size;
     int more_data   = 1;
@@ -2739,7 +2739,7 @@  error:
 
 static int hls_slice_data_wpp(HEVCContext *s, const H2645NAL *nal)
 {
-    const HEVCPPS *const pps = s->ps.pps;
+    const HEVCPPS *const pps = s->pps;
     const HEVCSPS *const sps = pps->sps;
     const uint8_t *data = nal->data;
     int length          = nal->size;
@@ -2928,7 +2928,7 @@  static int set_side_data(HEVCContext *s)
 
 static int hevc_frame_start(HEVCContext *s)
 {
-    const HEVCPPS *const pps = s->ps.pps;
+    const HEVCPPS *const pps = s->pps;
     const HEVCSPS *const sps = pps->sps;
     int pic_size_in_ctb  = ((sps->width  >> sps->log2_min_cb_size) + 1) *
                            ((sps->height >> sps->log2_min_cb_size) + 1);
@@ -3510,6 +3510,8 @@  static av_cold int hevc_decode_free(AVCodecContext *avctx)
 
     pic_arrays_free(s);
 
+    ff_refstruct_unref(&s->pps);
+
     ff_dovi_ctx_unref(&s->dovi_ctx);
     av_buffer_unref(&s->rpu_buf);
 
@@ -3611,6 +3613,9 @@  static int hevc_update_thread_context(AVCodecContext *dst,
     for (int i = 0; i < FF_ARRAY_ELEMS(s->ps.pps_list); i++)
         ff_refstruct_replace(&s->ps.pps_list[i], s0->ps.pps_list[i]);
 
+    // PPS do not persist between frames
+    ff_refstruct_unref(&s->pps);
+
     if (s->ps.sps != s0->ps.sps)
         if ((ret = set_sps(s, s0->ps.sps, src->pix_fmt)) < 0)
             return ret;
diff --git a/libavcodec/hevc/hevcdec.h b/libavcodec/hevc/hevcdec.h
index 3d1a36ecd4..3b7442e5c1 100644
--- a/libavcodec/hevc/hevcdec.h
+++ b/libavcodec/hevc/hevcdec.h
@@ -473,6 +473,7 @@  typedef struct HEVCContext {
     ///< candidate references for the current frame
     RefPicList rps[5];
 
+    const HEVCPPS *pps; ///< RefStruct reference
     SliceHeader sh;
     SAOParams *sao;
     DBParams *deblock;
diff --git a/libavcodec/hevc/ps.c b/libavcodec/hevc/ps.c
index eabed69b94..c02fc8b6c3 100644
--- a/libavcodec/hevc/ps.c
+++ b/libavcodec/hevc/ps.c
@@ -61,13 +61,6 @@  static const uint8_t hevc_sub_height_c[] = {
     1, 2, 1, 1
 };
 
-static void remove_pps(HEVCParamSets *s, int id)
-{
-    if (s->pps == s->pps_list[id])
-        s->pps = NULL;
-    ff_refstruct_unref(&s->pps_list[id]);
-}
-
 static void remove_sps(HEVCParamSets *s, int id)
 {
     int i;
@@ -78,7 +71,7 @@  static void remove_sps(HEVCParamSets *s, int id)
         /* 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)
-                remove_pps(s, i);
+                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]);
@@ -2035,7 +2028,7 @@  int ff_hevc_decode_nal_pps(GetBitContext *gb, AVCodecContext *avctx,
                "Overread PPS by %d bits\n", -get_bits_left(gb));
     }
 
-    remove_pps(ps, pps_id);
+    ff_refstruct_unref(&ps->pps_list[pps_id]);
     ps->pps_list[pps_id] = pps;
 
     return 0;
@@ -2057,7 +2050,6 @@  void ff_hevc_ps_uninit(HEVCParamSets *ps)
         ff_refstruct_unref(&ps->pps_list[i]);
 
     ps->sps = NULL;
-    ps->pps = NULL;
     ps->vps = NULL;
 }
 
diff --git a/libavcodec/hevc/ps.h b/libavcodec/hevc/ps.h
index fc10876756..17395c5510 100644
--- a/libavcodec/hevc/ps.h
+++ b/libavcodec/hevc/ps.h
@@ -451,7 +451,6 @@  typedef struct HEVCParamSets {
     /* currently active parameter sets */
     const HEVCVPS *vps;
     const HEVCSPS *sps;
-    const HEVCPPS *pps;
 } HEVCParamSets;
 
 /**
diff --git a/libavcodec/hevc/refs.c b/libavcodec/hevc/refs.c
index 39ce70ca39..31fcd49d69 100644
--- a/libavcodec/hevc/refs.c
+++ b/libavcodec/hevc/refs.c
@@ -54,7 +54,7 @@  const RefPicList *ff_hevc_get_ref_list(const HEVCContext *s,
     int x_cb         = x0 >> s->ps.sps->log2_ctb_size;
     int y_cb         = y0 >> s->ps.sps->log2_ctb_size;
     int pic_width_cb = s->ps.sps->ctb_width;
-    int ctb_addr_ts  = s->ps.pps->ctb_addr_rs_to_ts[y_cb * pic_width_cb + x_cb];
+    int ctb_addr_ts  = s->pps->ctb_addr_rs_to_ts[y_cb * pic_width_cb + x_cb];
     return &ref->rpl_tab[ctb_addr_ts]->refPicList[0];
 }
 
@@ -283,7 +283,7 @@  static int init_slice_rpl(HEVCContext *s)
 {
     HEVCFrame *frame = s->cur_frame;
     int ctb_count    = frame->ctb_count;
-    int ctb_addr_ts  = s->ps.pps->ctb_addr_rs_to_ts[s->sh.slice_segment_addr];
+    int ctb_addr_ts  = s->pps->ctb_addr_rs_to_ts[s->sh.slice_segment_addr];
     int i;
 
     if (s->slice_idx >= frame->nb_rpl_elems)
@@ -310,7 +310,7 @@  int ff_hevc_slice_rpl(HEVCContext *s)
         return ret;
 
     if (!(s->rps[ST_CURR_BEF].nb_refs + s->rps[ST_CURR_AFT].nb_refs +
-          s->rps[LT_CURR].nb_refs) && !s->ps.pps->pps_curr_pic_ref_enabled_flag) {
+          s->rps[LT_CURR].nb_refs) && !s->pps->pps_curr_pic_ref_enabled_flag) {
         av_log(s->avctx, AV_LOG_ERROR, "Zero refs in the frame RPS.\n");
         return AVERROR_INVALIDDATA;
     }
@@ -338,7 +338,7 @@  int ff_hevc_slice_rpl(HEVCContext *s)
                 }
             }
             // Construct RefPicList0, RefPicList1 (8-8, 8-10)
-            if (s->ps.pps->pps_curr_pic_ref_enabled_flag && rpl_tmp.nb_refs < HEVC_MAX_REFS) {
+            if (s->pps->pps_curr_pic_ref_enabled_flag && rpl_tmp.nb_refs < HEVC_MAX_REFS) {
                 rpl_tmp.list[rpl_tmp.nb_refs]           = s->cur_frame->poc;
                 rpl_tmp.ref[rpl_tmp.nb_refs]            = s->cur_frame;
                 rpl_tmp.isLongTerm[rpl_tmp.nb_refs]     = 1;
@@ -367,7 +367,7 @@  int ff_hevc_slice_rpl(HEVCContext *s)
         }
 
         // 8-9
-        if (s->ps.pps->pps_curr_pic_ref_enabled_flag &&
+        if (s->pps->pps_curr_pic_ref_enabled_flag &&
             !sh->rpl_modification_flag[list_idx] &&
             rpl_tmp.nb_refs > sh->nb_refs[L0]) {
             rpl->list[sh->nb_refs[L0] - 1] = s->cur_frame->poc;
@@ -545,7 +545,7 @@  int ff_hevc_frame_nb_refs(const HEVCContext *s)
             ret += !!long_rps->used[i];
     }
 
-    if (s->ps.pps->pps_curr_pic_ref_enabled_flag)
+    if (s->pps->pps_curr_pic_ref_enabled_flag)
         ret++;
 
     return ret;
diff --git a/libavcodec/nvdec_hevc.c b/libavcodec/nvdec_hevc.c
index 1d23f2ab56..0bebca7568 100644
--- a/libavcodec/nvdec_hevc.c
+++ b/libavcodec/nvdec_hevc.c
@@ -44,8 +44,8 @@  static void dpb_add(CUVIDHEVCPICPARAMS *pp, int idx, const HEVCFrame *src)
 
 static void fill_scaling_lists(CUVIDHEVCPICPARAMS *ppc, const HEVCContext *s)
 {
-    const ScalingList *sl = s->ps.pps->scaling_list_data_present_flag ?
-                            &s->ps.pps->scaling_list : &s->ps.sps->scaling_list;
+    const ScalingList *sl = s->pps->scaling_list_data_present_flag ?
+                            &s->pps->scaling_list : &s->pps->sps->scaling_list;
     int i, j, pos;
 
     for (i = 0; i < 6; i++) {
@@ -73,8 +73,8 @@  static int nvdec_hevc_start_frame(AVCodecContext *avctx,
                                   const uint8_t *buffer, uint32_t size)
 {
     const HEVCContext *s = avctx->priv_data;
-    const HEVCPPS *pps = s->ps.pps;
-    const HEVCSPS *sps = s->ps.sps;
+    const HEVCPPS *pps = s->pps;
+    const HEVCSPS *sps = pps->sps;
 
     NVDECContext       *ctx = avctx->internal->hwaccel_priv_data;
     CUVIDPICPARAMS      *pp = &ctx->pic_params;
@@ -300,7 +300,7 @@  static int nvdec_hevc_frame_params(AVCodecContext *avctx,
                                    AVBufferRef *hw_frames_ctx)
 {
     const HEVCContext *s = avctx->priv_data;
-    const HEVCSPS *sps = s->ps.sps;
+    const HEVCSPS *sps = s->pps->sps;
     return ff_nvdec_frame_params(avctx, hw_frames_ctx, sps->temporal_layer[sps->max_sub_layers - 1].max_dec_pic_buffering + 1, 1);
 }
 
diff --git a/libavcodec/vaapi_hevc.c b/libavcodec/vaapi_hevc.c
index 051762bfef..ad4cd35b26 100644
--- a/libavcodec/vaapi_hevc.c
+++ b/libavcodec/vaapi_hevc.c
@@ -90,7 +90,7 @@  static int find_frame_rps_type(const HEVCContext *h, const HEVCFrame *pic)
             return VA_PICTURE_HEVC_RPS_LT_CURR;
     }
 
-    if (h->ps.pps->pps_curr_pic_ref_enabled_flag && current_picture->poc == pic->poc)
+    if (h->pps->pps_curr_pic_ref_enabled_flag && current_picture->poc == pic->poc)
         return VA_PICTURE_HEVC_LONG_TERM_REFERENCE;
 
     return 0;
@@ -105,7 +105,7 @@  static void fill_vaapi_reference_frames(const HEVCContext *h, VAPictureParameter
         const HEVCFrame *frame = NULL;
 
         while (!frame && j < FF_ARRAY_ELEMS(h->DPB)) {
-            if ((&h->DPB[j] != current_picture || h->ps.pps->pps_curr_pic_ref_enabled_flag) &&
+            if ((&h->DPB[j] != current_picture || h->pps->pps_curr_pic_ref_enabled_flag) &&
                 (h->DPB[j].flags & (HEVC_FRAME_FLAG_LONG_REF | HEVC_FRAME_FLAG_SHORT_REF)))
                 frame = &h->DPB[j];
             j++;
@@ -126,8 +126,8 @@  static int vaapi_hevc_start_frame(AVCodecContext          *avctx,
 {
     const HEVCContext        *h = avctx->priv_data;
     VAAPIDecodePictureHEVC *pic = h->cur_frame->hwaccel_picture_private;
-    const HEVCSPS          *sps = h->ps.sps;
-    const HEVCPPS          *pps = h->ps.pps;
+    const HEVCPPS          *pps = h->pps;
+    const HEVCSPS          *sps = pps->sps;
 
     const ScalingList *scaling_list = NULL;
     int pic_param_size, err, i;
@@ -399,8 +399,8 @@  static void fill_pred_weight_table(AVCodecContext *avctx,
     slice_param->luma_log2_weight_denom         = 0;
 
     if (sh->slice_type == HEVC_SLICE_I ||
-        (sh->slice_type == HEVC_SLICE_P && !h->ps.pps->weighted_pred_flag) ||
-        (sh->slice_type == HEVC_SLICE_B && !h->ps.pps->weighted_bipred_flag))
+        (sh->slice_type == HEVC_SLICE_P && !h->pps->weighted_pred_flag) ||
+        (sh->slice_type == HEVC_SLICE_B && !h->pps->weighted_bipred_flag))
         return;
 
     slice_param->luma_log2_weight_denom = sh->luma_log2_weight_denom;
diff --git a/libavcodec/vdpau_hevc.c b/libavcodec/vdpau_hevc.c
index f7cf1bd9c0..3db7ec156a 100644
--- a/libavcodec/vdpau_hevc.c
+++ b/libavcodec/vdpau_hevc.c
@@ -43,8 +43,8 @@  static int vdpau_hevc_start_frame(AVCodecContext *avctx,
     VdpPictureInfoHEVC444 *info2 = &pic_ctx->info.hevc_444;
 #endif
 
-    const HEVCSPS *sps = h->ps.sps;
-    const HEVCPPS *pps = h->ps.pps;
+    const HEVCPPS *pps = h->pps;
+    const HEVCSPS *sps = pps->sps;
     const SliceHeader *sh = &h->sh;
     const ScalingList *sl = pps->scaling_list_data_present_flag ?
                             &pps->scaling_list : &sps->scaling_list;
diff --git a/libavcodec/videotoolbox.c b/libavcodec/videotoolbox.c
index dcaddf944e..8e50bbb422 100644
--- a/libavcodec/videotoolbox.c
+++ b/libavcodec/videotoolbox.c
@@ -233,9 +233,9 @@  CFDataRef ff_videotoolbox_hvcc_extradata_create(AVCodecContext *avctx)
 {
     HEVCContext *h = avctx->priv_data;
     int i, num_vps = 0, num_sps = 0, num_pps = 0;
-    const HEVCVPS *vps = h->ps.vps;
-    const HEVCSPS *sps = h->ps.sps;
-    const HEVCPPS *pps = h->ps.pps;
+    const HEVCPPS *pps = h->pps;
+    const HEVCSPS *sps = pps->sps;
+    const HEVCVPS *vps = sps->vps;
     PTLCommon ptlc = vps->ptl.general_ptl;
     VUI vui = sps->vui;
     uint8_t parallelismType;
diff --git a/libavcodec/vulkan_hevc.c b/libavcodec/vulkan_hevc.c
index aa721493b0..33a6326297 100644
--- a/libavcodec/vulkan_hevc.c
+++ b/libavcodec/vulkan_hevc.c
@@ -735,8 +735,8 @@  static int vk_hevc_start_frame(AVCodecContext          *avctx,
     FFVulkanDecodeContext *dec = avctx->internal->hwaccel_priv_data;
     HEVCVulkanDecodePicture *hp = pic->hwaccel_picture_private;
     FFVulkanDecodePicture *vp = &hp->vp;
-    const HEVCSPS *sps = h->ps.sps;
-    const HEVCPPS *pps = h->ps.pps;
+    const HEVCPPS *pps = h->pps;
+    const HEVCSPS *sps = pps->sps;
     int nb_refs = 0;
 
     if (!dec->session_params) {
@@ -878,8 +878,8 @@  static int vk_hevc_end_frame(AVCodecContext *avctx)
         return 0;
 
     if (!dec->session_params) {
-        const HEVCSPS *sps = h->ps.sps;
-        const HEVCPPS *pps = h->ps.pps;
+        const HEVCPPS *pps = h->pps;
+        const HEVCSPS *sps = pps->sps;
 
         if (!pps) {
             unsigned int pps_id = h->sh.pps_id;