[FFmpeg-cvslog] avcodec/hevcdec: Avoid allocation of common CABAC state

Andreas Rheinhardt git at videolan.org
Tue Jul 26 00:59:10 EEST 2022


ffmpeg | branch: master | Andreas Rheinhardt <andreas.rheinhardt at outlook.com> | Fri Jul 22 03:04:02 2022 +0200| [247d513beb24a55bf3519bd52fa72a9f30f693a5] | committer: Andreas Rheinhardt

avcodec/hevcdec: Avoid allocation of common CABAC state

It used to be allocated separately, so that the pointer to it
is copied to all HEVCContexts, so that all slice-threads
use the same. This is completely unnecessary now that there
is only one HEVCContext any more. There is just one minor
complication left: The slice-threads only get a pointer to
const HEVCContext, but they need to modify the common CABAC
state. Fix this by adding a pointer to the common CABAC state
to HEVCLocalContext and document why it exists.

Reviewed-by: Anton Khirnov <anton at khirnov.net>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at outlook.com>

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

 libavcodec/hevc_cabac.c |  8 ++++----
 libavcodec/hevcdec.c    |  8 ++------
 libavcodec/hevcdec.h    | 17 +++++++++++++++--
 3 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/libavcodec/hevc_cabac.c b/libavcodec/hevc_cabac.c
index f8f349dc4c..6b38da84bd 100644
--- a/libavcodec/hevc_cabac.c
+++ b/libavcodec/hevc_cabac.c
@@ -455,18 +455,18 @@ void ff_hevc_save_states(HEVCLocalContext *lc, int ctb_addr_ts)
         (ctb_addr_ts % s->ps.sps->ctb_width == 2 ||
          (s->ps.sps->ctb_width == 2 &&
           ctb_addr_ts % s->ps.sps->ctb_width == 0))) {
-        memcpy(s->cabac->state, lc->cabac_state, HEVC_CONTEXTS);
+        memcpy(lc->common_cabac_state->state, lc->cabac_state, HEVC_CONTEXTS);
         if (s->ps.sps->persistent_rice_adaptation_enabled_flag) {
-            memcpy(s->cabac->stat_coeff, lc->stat_coeff, HEVC_STAT_COEFFS);
+            memcpy(lc->common_cabac_state->stat_coeff, lc->stat_coeff, HEVC_STAT_COEFFS);
         }
     }
 }
 
 static void load_states(HEVCLocalContext *lc, const HEVCContext *s)
 {
-    memcpy(lc->cabac_state, s->cabac->state, HEVC_CONTEXTS);
+    memcpy(lc->cabac_state, lc->common_cabac_state->state, HEVC_CONTEXTS);
     if (s->ps.sps->persistent_rice_adaptation_enabled_flag) {
-        memcpy(lc->stat_coeff, s->cabac->stat_coeff, HEVC_STAT_COEFFS);
+        memcpy(lc->stat_coeff, lc->common_cabac_state->stat_coeff, HEVC_STAT_COEFFS);
     }
 }
 
diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c
index f9cc83b2c9..0421db201e 100644
--- a/libavcodec/hevcdec.c
+++ b/libavcodec/hevcdec.c
@@ -2653,6 +2653,7 @@ static int hls_slice_data_wpp(HEVCContext *s, const H2645NAL *nal)
             return AVERROR(ENOMEM);
         s->HEVClcList[i]->logctx = s->avctx;
         s->HEVClcList[i]->parent = s;
+        s->HEVClcList[i]->common_cabac_state = &s->cabac;
     }
 
     offset = (lc->gb.index >> 3);
@@ -3582,8 +3583,6 @@ static av_cold int hevc_decode_free(AVCodecContext *avctx)
 
     av_freep(&s->md5_ctx);
 
-    av_freep(&s->cabac);
-
     for (i = 0; i < 3; i++) {
         av_freep(&s->sao_pixel_buffer_h[i]);
         av_freep(&s->sao_pixel_buffer_v[i]);
@@ -3630,12 +3629,9 @@ static av_cold int hevc_init_context(AVCodecContext *avctx)
         return AVERROR(ENOMEM);
     s->HEVClc->parent = s;
     s->HEVClc->logctx = avctx;
+    s->HEVClc->common_cabac_state = &s->cabac;
     s->HEVClcList[0] = s->HEVClc;
 
-    s->cabac = av_malloc(sizeof(*s->cabac));
-    if (!s->cabac)
-        return AVERROR(ENOMEM);
-
     s->output_frame = av_frame_alloc();
     if (!s->output_frame)
         return AVERROR(ENOMEM);
diff --git a/libavcodec/hevcdec.h b/libavcodec/hevcdec.h
index 3367ee312a..6cef9e6f0a 100644
--- a/libavcodec/hevcdec.h
+++ b/libavcodec/hevcdec.h
@@ -439,6 +439,18 @@ typedef struct HEVCLocalContext {
     GetBitContext gb;
     CABACContext cc;
 
+    /**
+     * This is a pointer to the common CABAC state.
+     * In case entropy_coding_sync_enabled_flag is set,
+     * the CABAC state after decoding the second CTU in a row is
+     * stored here and used to initialize the CABAC state before
+     * decoding the first CTU in the next row.
+     * This is the basis for WPP and in case slice-threading is used,
+     * the next row is decoded by another thread making this state
+     * shared between threads.
+     */
+    HEVCCABACState *common_cabac_state;
+
     int8_t qp_y;
     int8_t curr_qp_y;
 
@@ -485,8 +497,6 @@ typedef struct HEVCContext {
     int                 width;
     int                 height;
 
-    HEVCCABACState *cabac;
-
     /** 1 if the independent slice segment header was successfully parsed */
     uint8_t slice_initialized;
 
@@ -559,6 +569,9 @@ typedef struct HEVCContext {
     uint16_t seq_decode;
     uint16_t seq_output;
 
+    /** The target for the common_cabac_state of the local contexts. */
+    HEVCCABACState cabac;
+
     int enable_parallel_tiles;
     atomic_int wpp_err;
 



More information about the ffmpeg-cvslog mailing list