From 247d513beb24a55bf3519bd52fa72a9f30f693a5 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt Date: Fri, 22 Jul 2022 03:04:02 +0200 Subject: 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 Signed-off-by: Andreas Rheinhardt --- libavcodec/hevc_cabac.c | 8 ++++---- libavcodec/hevcdec.c | 8 ++------ libavcodec/hevcdec.h | 17 +++++++++++++++-- 3 files changed, 21 insertions(+), 12 deletions(-) (limited to 'libavcodec') 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; -- cgit v1.2.3