From 136ada2fc372e8fd2dcdc2b3b7256529ebcbe275 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt Date: Wed, 29 Jun 2022 17:47:06 +0200 Subject: avcodec/hevc_mvs: Pass HEVCLocalContext when slice-threading The HEVC decoder has both HEVCContext and HEVCLocalContext structures. The latter is supposed to be the structure containing the per-slicethread state. Yet that is not how it is handled in practice: Each HEVCLocalContext has a unique HEVCContext allocated for it and each of these coincides except in exactly one field: The corresponding HEVCLocalContext. This makes it possible to pass the HEVCContext everywhere where logically a HEVCLocalContext should be used. This commit stops doing this for lavc/hevc_mvs.c; it also constifies everything that is possible in order to ensure that no slice thread accidentally modifies the main HEVCContext state. Reviewed-by: Anton Khirnov Signed-off-by: Andreas Rheinhardt --- libavcodec/hevc_mvs.c | 56 +++++++++++++++++++++++++-------------------------- libavcodec/hevcdec.c | 27 +++++++++++++------------ libavcodec/hevcdec.h | 6 +++--- 3 files changed, 45 insertions(+), 44 deletions(-) diff --git a/libavcodec/hevc_mvs.c b/libavcodec/hevc_mvs.c index 516e4a6b7a..bcf6ec3abc 100644 --- a/libavcodec/hevc_mvs.c +++ b/libavcodec/hevc_mvs.c @@ -40,10 +40,10 @@ static const uint8_t l0_l1_cand_idx[12][2] = { { 3, 2, }, }; -void ff_hevc_set_neighbour_available(HEVCContext *s, int x0, int y0, +void ff_hevc_set_neighbour_available(HEVCLocalContext *lc, int x0, int y0, int nPbW, int nPbH) { - HEVCLocalContext *lc = s->HEVClc; + const HEVCContext *const s = lc->parent; int x0b = av_mod_uintp2(x0, s->ps.sps->log2_ctb_size); int y0b = av_mod_uintp2(y0, s->ps.sps->log2_ctb_size); @@ -62,7 +62,7 @@ void ff_hevc_set_neighbour_available(HEVCContext *s, int x0, int y0, /* * 6.4.1 Derivation process for z-scan order block availability */ -static av_always_inline int z_scan_block_avail(HEVCContext *s, int xCurr, int yCurr, +static av_always_inline int z_scan_block_avail(const HEVCContext *s, int xCurr, int yCurr, int xN, int yN) { #define MIN_TB_ADDR_ZS(x, y) \ @@ -84,7 +84,7 @@ static av_always_inline int z_scan_block_avail(HEVCContext *s, int xCurr, int yC } //check if the two luma locations belong to the same motion estimation region -static av_always_inline int is_diff_mer(HEVCContext *s, int xN, int yN, int xP, int yP) +static av_always_inline int is_diff_mer(const HEVCContext *s, int xN, int yN, int xP, int yP) { uint8_t plevel = s->ps.pps->log2_parallel_merge_level; @@ -161,11 +161,11 @@ static int check_mvset(Mv *mvLXCol, const Mv *mvCol, refPicList_col, L ## l, temp_col.ref_idx[l]) // derive the motion vectors section 8.5.3.1.8 -static int derive_temporal_colocated_mvs(HEVCContext *s, MvField temp_col, +static int derive_temporal_colocated_mvs(const HEVCContext *s, MvField temp_col, int refIdxLx, Mv *mvLXCol, int X, int colPic, const RefPicList *refPicList_col) { - RefPicList *refPicList = s->ref->refPicList; + const RefPicList *refPicList = s->ref->refPicList; if (temp_col.pred_flag == PF_INTRA) return 0; @@ -216,11 +216,11 @@ static int derive_temporal_colocated_mvs(HEVCContext *s, MvField temp_col, /* * 8.5.3.1.7 temporal luma motion vector prediction */ -static int temporal_luma_motion_vector(HEVCContext *s, int x0, int y0, +static int temporal_luma_motion_vector(const HEVCContext *s, int x0, int y0, int nPbW, int nPbH, int refIdxLx, Mv *mvLXCol, int X) { - MvField *tab_mvf; + const MvField *tab_mvf; MvField temp_col; int x, y, x_pu, y_pu; int min_pu_width = s->ps.sps->min_pu_width; @@ -283,16 +283,16 @@ static int temporal_luma_motion_vector(HEVCContext *s, int x0, int y0, /* * 8.5.3.1.2 Derivation process for spatial merging candidates */ -static void derive_spatial_merge_candidates(HEVCContext *s, int x0, int y0, +static void derive_spatial_merge_candidates(HEVCLocalContext *lc, const HEVCContext *s, + int x0, int y0, int nPbW, int nPbH, int log2_cb_size, int singleMCLFlag, int part_idx, int merge_idx, struct MvField mergecandlist[]) { - HEVCLocalContext *lc = s->HEVClc; - RefPicList *refPicList = s->ref->refPicList; - MvField *tab_mvf = s->ref->tab_mvf; + const RefPicList *refPicList = s->ref->refPicList; + const MvField *tab_mvf = s->ref->tab_mvf; const int min_pu_width = s->ps.sps->min_pu_width; @@ -477,16 +477,16 @@ static void derive_spatial_merge_candidates(HEVCContext *s, int x0, int y0, /* * 8.5.3.1.1 Derivation process of luma Mvs for merge mode */ -void ff_hevc_luma_mv_merge_mode(HEVCContext *s, int x0, int y0, int nPbW, +void ff_hevc_luma_mv_merge_mode(HEVCLocalContext *lc, int x0, int y0, int nPbW, int nPbH, int log2_cb_size, int part_idx, int merge_idx, MvField *mv) { + const HEVCContext *const s = lc->parent; int singleMCLFlag = 0; int nCS = 1 << log2_cb_size; MvField mergecand_list[MRG_MAX_NUM_CANDS]; int nPbW2 = nPbW; int nPbH2 = nPbH; - HEVCLocalContext *lc = s->HEVClc; if (s->ps.pps->log2_parallel_merge_level > 2 && nCS == 8) { singleMCLFlag = 1; @@ -497,8 +497,8 @@ void ff_hevc_luma_mv_merge_mode(HEVCContext *s, int x0, int y0, int nPbW, part_idx = 0; } - ff_hevc_set_neighbour_available(s, x0, y0, nPbW, nPbH); - derive_spatial_merge_candidates(s, x0, y0, nPbW, nPbH, log2_cb_size, + ff_hevc_set_neighbour_available(lc, x0, y0, nPbW, nPbH); + derive_spatial_merge_candidates(lc, s, x0, y0, nPbW, nPbH, log2_cb_size, singleMCLFlag, part_idx, merge_idx, mergecand_list); @@ -510,12 +510,12 @@ void ff_hevc_luma_mv_merge_mode(HEVCContext *s, int x0, int y0, int nPbW, *mv = mergecand_list[merge_idx]; } -static av_always_inline void dist_scale(HEVCContext *s, Mv *mv, +static av_always_inline void dist_scale(const HEVCContext *s, Mv *mv, int min_pu_width, int x, int y, int elist, int ref_idx_curr, int ref_idx) { - RefPicList *refPicList = s->ref->refPicList; - MvField *tab_mvf = s->ref->tab_mvf; + const RefPicList *refPicList = s->ref->refPicList; + const MvField *tab_mvf = s->ref->tab_mvf; int ref_pic_elist = refPicList[elist].list[TAB_MVF(x, y).ref_idx[elist]]; int ref_pic_curr = refPicList[ref_idx_curr].list[ref_idx]; @@ -527,13 +527,13 @@ static av_always_inline void dist_scale(HEVCContext *s, Mv *mv, } } -static int mv_mp_mode_mx(HEVCContext *s, int x, int y, int pred_flag_index, +static int mv_mp_mode_mx(const HEVCContext *s, int x, int y, int pred_flag_index, Mv *mv, int ref_idx_curr, int ref_idx) { - MvField *tab_mvf = s->ref->tab_mvf; + const MvField *tab_mvf = s->ref->tab_mvf; int min_pu_width = s->ps.sps->min_pu_width; - RefPicList *refPicList = s->ref->refPicList; + const RefPicList *refPicList = s->ref->refPicList; if (((TAB_MVF(x, y).pred_flag) & (1 << pred_flag_index)) && refPicList[pred_flag_index].list[TAB_MVF(x, y).ref_idx[pred_flag_index]] == refPicList[ref_idx_curr].list[ref_idx]) { @@ -543,13 +543,13 @@ static int mv_mp_mode_mx(HEVCContext *s, int x, int y, int pred_flag_index, return 0; } -static int mv_mp_mode_mx_lt(HEVCContext *s, int x, int y, int pred_flag_index, +static int mv_mp_mode_mx_lt(const HEVCContext *s, int x, int y, int pred_flag_index, Mv *mv, int ref_idx_curr, int ref_idx) { - MvField *tab_mvf = s->ref->tab_mvf; + const MvField *tab_mvf = s->ref->tab_mvf; int min_pu_width = s->ps.sps->min_pu_width; - RefPicList *refPicList = s->ref->refPicList; + const RefPicList *refPicList = s->ref->refPicList; if ((TAB_MVF(x, y).pred_flag) & (1 << pred_flag_index)) { int currIsLongTerm = refPicList[ref_idx_curr].isLongTerm[ref_idx]; @@ -580,13 +580,13 @@ static int mv_mp_mode_mx_lt(HEVCContext *s, int x, int y, int pred_flag_index, (y ## v) >> s->ps.sps->log2_min_pu_size, \ pred, &mx, ref_idx_curr, ref_idx) -void ff_hevc_luma_mv_mvp_mode(HEVCContext *s, int x0, int y0, int nPbW, +void ff_hevc_luma_mv_mvp_mode(HEVCLocalContext *lc, int x0, int y0, int nPbW, int nPbH, int log2_cb_size, int part_idx, int merge_idx, MvField *mv, int mvp_lx_flag, int LX) { - HEVCLocalContext *lc = s->HEVClc; - MvField *tab_mvf = s->ref->tab_mvf; + const HEVCContext *const s = lc->parent; + const MvField *const tab_mvf = s->ref->tab_mvf; int isScaledFlag_L0 = 0; int availableFlagLXA0 = 1; int availableFlagLXB0 = 1; diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index 846077b6ab..5307381d8b 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -1107,7 +1107,7 @@ static int hls_transform_unit(HEVCContext *s, int x0, int y0, if (lc->cu.pred_mode == MODE_INTRA) { int trafo_size = 1 << log2_trafo_size; - ff_hevc_set_neighbour_available(s, x0, y0, trafo_size, trafo_size); + ff_hevc_set_neighbour_available(lc, x0, y0, trafo_size, trafo_size); s->hpc.intra_pred[log2_trafo_size - 2](s, x0, y0, 0); } @@ -1194,7 +1194,7 @@ static int hls_transform_unit(HEVCContext *s, int x0, int y0, } for (i = 0; i < (s->ps.sps->chroma_format_idc == 2 ? 2 : 1); i++) { if (lc->cu.pred_mode == MODE_INTRA) { - ff_hevc_set_neighbour_available(s, x0, y0 + (i << log2_trafo_size_c), trafo_size_h, trafo_size_v); + ff_hevc_set_neighbour_available(lc, x0, y0 + (i << log2_trafo_size_c), trafo_size_h, trafo_size_v); s->hpc.intra_pred[log2_trafo_size_c - 2](s, x0, y0 + (i << log2_trafo_size_c), 1); } if (cbf_cb[i]) @@ -1223,7 +1223,8 @@ static int hls_transform_unit(HEVCContext *s, int x0, int y0, } for (i = 0; i < (s->ps.sps->chroma_format_idc == 2 ? 2 : 1); i++) { if (lc->cu.pred_mode == MODE_INTRA) { - ff_hevc_set_neighbour_available(s, x0, y0 + (i << log2_trafo_size_c), trafo_size_h, trafo_size_v); + ff_hevc_set_neighbour_available(lc, x0, y0 + (i << log2_trafo_size_c), + trafo_size_h, trafo_size_v); s->hpc.intra_pred[log2_trafo_size_c - 2](s, x0, y0 + (i << log2_trafo_size_c), 2); } if (cbf_cr[i]) @@ -1251,7 +1252,7 @@ static int hls_transform_unit(HEVCContext *s, int x0, int y0, int trafo_size_v = 1 << (log2_trafo_size + s->ps.sps->vshift[1]); for (i = 0; i < (s->ps.sps->chroma_format_idc == 2 ? 2 : 1); i++) { if (lc->cu.pred_mode == MODE_INTRA) { - ff_hevc_set_neighbour_available(s, xBase, yBase + (i << log2_trafo_size), + ff_hevc_set_neighbour_available(lc, xBase, yBase + (i << log2_trafo_size), trafo_size_h, trafo_size_v); s->hpc.intra_pred[log2_trafo_size - 2](s, xBase, yBase + (i << log2_trafo_size), 1); } @@ -1261,7 +1262,7 @@ static int hls_transform_unit(HEVCContext *s, int x0, int y0, } for (i = 0; i < (s->ps.sps->chroma_format_idc == 2 ? 2 : 1); i++) { if (lc->cu.pred_mode == MODE_INTRA) { - ff_hevc_set_neighbour_available(s, xBase, yBase + (i << log2_trafo_size), + ff_hevc_set_neighbour_available(lc, xBase, yBase + (i << log2_trafo_size), trafo_size_h, trafo_size_v); s->hpc.intra_pred[log2_trafo_size - 2](s, xBase, yBase + (i << log2_trafo_size), 2); } @@ -1274,11 +1275,11 @@ static int hls_transform_unit(HEVCContext *s, int x0, int y0, if (log2_trafo_size > 2 || s->ps.sps->chroma_format_idc == 3) { int trafo_size_h = 1 << (log2_trafo_size_c + s->ps.sps->hshift[1]); int trafo_size_v = 1 << (log2_trafo_size_c + s->ps.sps->vshift[1]); - ff_hevc_set_neighbour_available(s, x0, y0, trafo_size_h, trafo_size_v); + ff_hevc_set_neighbour_available(lc, x0, y0, trafo_size_h, trafo_size_v); s->hpc.intra_pred[log2_trafo_size_c - 2](s, x0, y0, 1); s->hpc.intra_pred[log2_trafo_size_c - 2](s, x0, y0, 2); if (s->ps.sps->chroma_format_idc == 2) { - ff_hevc_set_neighbour_available(s, x0, y0 + (1 << log2_trafo_size_c), + ff_hevc_set_neighbour_available(lc, x0, y0 + (1 << log2_trafo_size_c), trafo_size_h, trafo_size_v); s->hpc.intra_pred[log2_trafo_size_c - 2](s, x0, y0 + (1 << log2_trafo_size_c), 1); s->hpc.intra_pred[log2_trafo_size_c - 2](s, x0, y0 + (1 << log2_trafo_size_c), 2); @@ -1286,12 +1287,12 @@ static int hls_transform_unit(HEVCContext *s, int x0, int y0, } else if (blk_idx == 3) { int trafo_size_h = 1 << (log2_trafo_size + 1); int trafo_size_v = 1 << (log2_trafo_size + s->ps.sps->vshift[1]); - ff_hevc_set_neighbour_available(s, xBase, yBase, + ff_hevc_set_neighbour_available(lc, xBase, yBase, trafo_size_h, trafo_size_v); s->hpc.intra_pred[log2_trafo_size - 2](s, xBase, yBase, 1); s->hpc.intra_pred[log2_trafo_size - 2](s, xBase, yBase, 2); if (s->ps.sps->chroma_format_idc == 2) { - ff_hevc_set_neighbour_available(s, xBase, yBase + (1 << (log2_trafo_size)), + ff_hevc_set_neighbour_available(lc, xBase, yBase + (1 << (log2_trafo_size)), trafo_size_h, trafo_size_v); s->hpc.intra_pred[log2_trafo_size - 2](s, xBase, yBase + (1 << (log2_trafo_size)), 1); s->hpc.intra_pred[log2_trafo_size - 2](s, xBase, yBase + (1 << (log2_trafo_size)), 2); @@ -1822,7 +1823,7 @@ static void hevc_luma_mv_mvp_mode(HEVCContext *s, int x0, int y0, int nPbW, enum InterPredIdc inter_pred_idc = PRED_L0; int mvp_flag; - ff_hevc_set_neighbour_available(s, x0, y0, nPbW, nPbH); + ff_hevc_set_neighbour_available(lc, x0, y0, nPbW, nPbH); mv->pred_flag = 0; if (s->sh.slice_type == HEVC_SLICE_B) inter_pred_idc = ff_hevc_inter_pred_idc_decode(s, nPbW, nPbH); @@ -1834,7 +1835,7 @@ static void hevc_luma_mv_mvp_mode(HEVCContext *s, int x0, int y0, int nPbW, mv->pred_flag = PF_L0; ff_hevc_hls_mvd_coding(s, x0, y0, 0); mvp_flag = ff_hevc_mvp_lx_flag_decode(s); - ff_hevc_luma_mv_mvp_mode(s, x0, y0, nPbW, nPbH, log2_cb_size, + ff_hevc_luma_mv_mvp_mode(lc, x0, y0, nPbW, nPbH, log2_cb_size, part_idx, merge_idx, mv, mvp_flag, 0); mv->mv[0].x += lc->pu.mvd.x; mv->mv[0].y += lc->pu.mvd.y; @@ -1852,7 +1853,7 @@ static void hevc_luma_mv_mvp_mode(HEVCContext *s, int x0, int y0, int nPbW, mv->pred_flag += PF_L1; mvp_flag = ff_hevc_mvp_lx_flag_decode(s); - ff_hevc_luma_mv_mvp_mode(s, x0, y0, nPbW, nPbH, log2_cb_size, + ff_hevc_luma_mv_mvp_mode(lc, x0, y0, nPbW, nPbH, log2_cb_size, part_idx, merge_idx, mv, mvp_flag, 1); mv->mv[1].x += lc->pu.mvd.x; mv->mv[1].y += lc->pu.mvd.y; @@ -1896,7 +1897,7 @@ static void hls_prediction_unit(HEVCContext *s, int x0, int y0, else merge_idx = 0; - ff_hevc_luma_mv_merge_mode(s, x0, y0, nPbW, nPbH, log2_cb_size, + ff_hevc_luma_mv_merge_mode(lc, x0, y0, nPbW, nPbH, log2_cb_size, partIdx, merge_idx, ¤t_mv); } else { hevc_luma_mv_mvp_mode(s, x0, y0, nPbW, nPbH, log2_cb_size, diff --git a/libavcodec/hevcdec.h b/libavcodec/hevcdec.h index 271a55df2f..3bb3fdb90a 100644 --- a/libavcodec/hevcdec.h +++ b/libavcodec/hevcdec.h @@ -667,12 +667,12 @@ void ff_hevc_bump_frame(HEVCContext *s); void ff_hevc_unref_frame(HEVCContext *s, HEVCFrame *frame, int flags); -void ff_hevc_set_neighbour_available(HEVCContext *s, int x0, int y0, +void ff_hevc_set_neighbour_available(HEVCLocalContext *lc, int x0, int y0, int nPbW, int nPbH); -void ff_hevc_luma_mv_merge_mode(HEVCContext *s, int x0, int y0, +void ff_hevc_luma_mv_merge_mode(HEVCLocalContext *lc, int x0, int y0, int nPbW, int nPbH, int log2_cb_size, int part_idx, int merge_idx, MvField *mv); -void ff_hevc_luma_mv_mvp_mode(HEVCContext *s, int x0, int y0, +void ff_hevc_luma_mv_mvp_mode(HEVCLocalContext *lc, int x0, int y0, int nPbW, int nPbH, int log2_cb_size, int part_idx, int merge_idx, MvField *mv, int mvp_lx_flag, int LX); -- cgit v1.2.3