diff mbox series

[FFmpeg-devel,23/42] lavc/hevcdec: make a HEVCFrame hold a reference to its PPS

Message ID 20240827154041.13846-25-anton@khirnov.net
State New
Headers show
Series [FFmpeg-devel,01/42] lavu/opt: add API for setting array-type option values | expand

Commit Message

Anton Khirnov Aug. 27, 2024, 3:05 p.m. UTC
ff_hevc_get_ref_list() needs the PPS of a previously decoded frame,
which may be different from the currently active one.
---
 libavcodec/hevc/filter.c  |  4 ++--
 libavcodec/hevc/hevcdec.c |  1 +
 libavcodec/hevc/hevcdec.h |  4 ++--
 libavcodec/hevc/mvs.c     |  2 +-
 libavcodec/hevc/refs.c    | 15 +++++++++------
 5 files changed, 15 insertions(+), 11 deletions(-)
diff mbox series

Patch

diff --git a/libavcodec/hevc/filter.c b/libavcodec/hevc/filter.c
index 298f1792b2..68ae0e9ef6 100644
--- a/libavcodec/hevc/filter.c
+++ b/libavcodec/hevc/filter.c
@@ -767,7 +767,7 @@  void ff_hevc_deblocking_boundary_strengths(HEVCLocalContext *lc, const HEVCLayer
 
     if (boundary_upper) {
         const RefPicList *rpl_top = (lc->boundary_flags & BOUNDARY_UPPER_SLICE) ?
-                                    ff_hevc_get_ref_list(s, s->cur_frame, x0, y0 - 1) :
+                                    ff_hevc_get_ref_list(s->cur_frame, x0, y0 - 1) :
                                     s->cur_frame->refPicList;
         int yp_pu = (y0 - 1) >> log2_min_pu_size;
         int yq_pu =  y0      >> log2_min_pu_size;
@@ -805,7 +805,7 @@  void ff_hevc_deblocking_boundary_strengths(HEVCLocalContext *lc, const HEVCLayer
 
     if (boundary_left) {
         const RefPicList *rpl_left = (lc->boundary_flags & BOUNDARY_LEFT_SLICE) ?
-                                     ff_hevc_get_ref_list(s, s->cur_frame, x0 - 1, y0) :
+                                     ff_hevc_get_ref_list(s->cur_frame, x0 - 1, y0) :
                                      s->cur_frame->refPicList;
         int xp_pu = (x0 - 1) >> log2_min_pu_size;
         int xq_pu =  x0      >> log2_min_pu_size;
diff --git a/libavcodec/hevc/hevcdec.c b/libavcodec/hevc/hevcdec.c
index e02d5bba72..eb41f9a5d6 100644
--- a/libavcodec/hevc/hevcdec.c
+++ b/libavcodec/hevc/hevcdec.c
@@ -3503,6 +3503,7 @@  static int hevc_ref_frame(HEVCFrame *dst, const HEVCFrame *src)
         dst->needs_fg = 1;
     }
 
+    dst->pps     = ff_refstruct_ref_c(src->pps);
     dst->tab_mvf = ff_refstruct_ref(src->tab_mvf);
     dst->rpl_tab = ff_refstruct_ref(src->rpl_tab);
     dst->rpl = ff_refstruct_ref(src->rpl);
diff --git a/libavcodec/hevc/hevcdec.h b/libavcodec/hevc/hevcdec.h
index 0b5d87b18f..a534aee60f 100644
--- a/libavcodec/hevc/hevcdec.h
+++ b/libavcodec/hevc/hevcdec.h
@@ -366,6 +366,7 @@  typedef struct HEVCFrame {
     int ctb_count;
     int poc;
 
+    const HEVCPPS *pps;            ///< RefStruct reference
     RefPicListTab *rpl;            ///< RefStruct reference
     int nb_rpl_elems;
 
@@ -556,8 +557,7 @@  void ff_hevc_clear_refs(HEVCLayerContext *l);
  */
 void ff_hevc_flush_dpb(HEVCContext *s);
 
-const RefPicList *ff_hevc_get_ref_list(const HEVCContext *s, const HEVCFrame *frame,
-                                       int x0, int y0);
+const RefPicList *ff_hevc_get_ref_list(const HEVCFrame *frame, int x0, int y0);
 
 /**
  * Construct the reference picture sets for the current frame.
diff --git a/libavcodec/hevc/mvs.c b/libavcodec/hevc/mvs.c
index 96d8d58f39..55f115ad0c 100644
--- a/libavcodec/hevc/mvs.c
+++ b/libavcodec/hevc/mvs.c
@@ -211,7 +211,7 @@  static int derive_temporal_colocated_mvs(const HEVCContext *s, MvField temp_col,
 #define DERIVE_TEMPORAL_COLOCATED_MVS                                   \
     derive_temporal_colocated_mvs(s, temp_col,                          \
                                   refIdxLx, mvLXCol, X, colPic,         \
-                                  ff_hevc_get_ref_list(s, ref, x, y))
+                                  ff_hevc_get_ref_list(ref, x, y))
 
 /*
  * 8.5.3.1.7  temporal luma motion vector prediction
diff --git a/libavcodec/hevc/refs.c b/libavcodec/hevc/refs.c
index 7b8dff4f55..58edc15a6f 100644
--- a/libavcodec/hevc/refs.c
+++ b/libavcodec/hevc/refs.c
@@ -38,6 +38,7 @@  void ff_hevc_unref_frame(HEVCFrame *frame, int flags)
         av_frame_unref(frame->frame_grain);
         frame->needs_fg = 0;
 
+        ff_refstruct_unref(&frame->pps);
         ff_refstruct_unref(&frame->tab_mvf);
 
         ff_refstruct_unref(&frame->rpl);
@@ -49,13 +50,13 @@  void ff_hevc_unref_frame(HEVCFrame *frame, int flags)
     }
 }
 
-const RefPicList *ff_hevc_get_ref_list(const HEVCContext *s,
-                                       const HEVCFrame *ref, int x0, int y0)
+const RefPicList *ff_hevc_get_ref_list(const HEVCFrame *ref, int x0, int y0)
 {
-    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->pps->ctb_addr_rs_to_ts[y_cb * pic_width_cb + x_cb];
+    const HEVCSPS *sps = ref->pps->sps;
+    int x_cb         = x0 >> sps->log2_ctb_size;
+    int y_cb         = y0 >> sps->log2_ctb_size;
+    int pic_width_cb = sps->ctb_width;
+    int ctb_addr_ts  = ref->pps->ctb_addr_rs_to_ts[y_cb * pic_width_cb + x_cb];
     return &ref->rpl_tab[ctb_addr_ts]->refPicList[0];
 }
 
@@ -116,6 +117,8 @@  static HEVCFrame *alloc_frame(HEVCContext *s, HEVCLayerContext *l)
         if (ret < 0)
             goto fail;
 
+        frame->pps = ff_refstruct_ref_c(s->pps);
+
         return frame;
 fail:
         ff_hevc_unref_frame(frame, ~0);