Message ID | 20201115023622.17605-1-oddstone@gmail.com |
---|---|
State | Accepted |
Commit | c8bc0f66a875bc3708d8dc11b757f2198606ffd7 |
Headers | show |
Series | [FFmpeg-devel,v2] avcodec/hevcdec: fix stat_coeff save/load for persistent_rice_adaptation_enabled_flag | expand |
Context | Check | Description |
---|---|---|
andriy/x86_make | success | Make finished |
andriy/x86_make_fate | success | Make fate finished |
andriy/PPC64_make | success | Make finished |
andriy/PPC64_make_fate | success | Make fate finished |
Hi Christophe, Thanks for the test. You are right, It's a wpp decode issue. Please help review it again. I have test it with make fate-hevc THREADS=12 THREAD_TYPE=slice make fate-hevc THREADS=12 make fate-hevc-conformance-WPP_HIGH_TP_444_8BIT_RExt_Apple_2 THREADS=12 THREAD_TYPE=slice thanks On Sun, Nov 15, 2020 at 10:36 AM Xu Guangxin <oddstone@gmail.com> wrote: > It's required by the 9.3.1 TableStatCoeff* section. > > Following clips have this feature: > WPP_HIGH_TP_444_8BIT_RExt_Apple_2.bit > Bitdepth_A_RExt_Sony_1.bin > Bitdepth_B_RExt_Sony_1.bin > EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_10BIT_RExt_Sony_1.bit > EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_12BIT_RExt_Sony_1.bit > EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_8BIT_RExt_Sony_1.bit > EXTPREC_MAIN_444_16_INTRA_10BIT_RExt_Sony_1.bit > EXTPREC_MAIN_444_16_INTRA_12BIT_RExt_Sony_1.bit > EXTPREC_MAIN_444_16_INTRA_8BIT_RExt_Sony_1.bit > WPP_AND_TILE_10Bit422Test_HIGH_TP_444_10BIT_RExt_Apple_2.bit > WPP_AND_TILE_AND_CABAC_BYPASS_ALIGN_0_HIGH_TP_444_14BIT_RExt_Apple_2.bit > WPP_AND_TILE_AND_CABAC_BYPASS_ALIGN_1_HIGH_TP_444_14BIT_RExt_Apple_2.bit > WPP_AND_TILE_HIGH_TP_444_8BIT_RExt_Apple_2.bit > > you can download them from: > > https://www.itu.int/wftp3/av-arch/jctvc-site/bitstream_exchange/draft_conformance/RExt/ > > Signed-off-by: Xu Guangxin <oddstone@gmail.com> > --- > libavcodec/hevc_cabac.c | 15 +++++++++++---- > libavcodec/hevcdec.c | 4 ++-- > libavcodec/hevcdec.h | 6 ++++-- > 3 files changed, 17 insertions(+), 8 deletions(-) > > diff --git a/libavcodec/hevc_cabac.c b/libavcodec/hevc_cabac.c > index 3dc0987dad..93fc1ec795 100644 > --- a/libavcodec/hevc_cabac.c > +++ b/libavcodec/hevc_cabac.c > @@ -454,12 +454,19 @@ void ff_hevc_save_states(HEVCContext *s, int > ctb_addr_ts) > (s->ps.sps->ctb_width == 2 && > ctb_addr_ts % s->ps.sps->ctb_width == 0))) { > memcpy(s->cabac_state, s->HEVClc->cabac_state, HEVC_CONTEXTS); > + if (s->ps.sps->persistent_rice_adaptation_enabled_flag) { > + memcpy(s->stat_coeff, s->HEVClc->stat_coeff, > HEVC_STAT_COEFFS); > + } > } > } > > -static void load_states(HEVCContext *s) > +static void load_states(HEVCContext *s, int thread) > { > memcpy(s->HEVClc->cabac_state, s->cabac_state, HEVC_CONTEXTS); > + if (s->ps.sps->persistent_rice_adaptation_enabled_flag) { > + const HEVCContext *prev = s->sList[(thread + s->threads_number - > 1) % s->threads_number]; > + memcpy(s->HEVClc->stat_coeff, prev->stat_coeff, HEVC_STAT_COEFFS); > + } > } > > static int cabac_reinit(HEVCLocalContext *lc) > @@ -501,7 +508,7 @@ static void cabac_init_state(HEVCContext *s) > s->HEVClc->stat_coeff[i] = 0; > } > > -int ff_hevc_cabac_init(HEVCContext *s, int ctb_addr_ts) > +int ff_hevc_cabac_init(HEVCContext *s, int ctb_addr_ts, int thread) > { > if (ctb_addr_ts == > s->ps.pps->ctb_addr_rs_to_ts[s->sh.slice_ctb_addr_rs]) { > int ret = cabac_init_decoder(s); > @@ -518,7 +525,7 @@ int ff_hevc_cabac_init(HEVCContext *s, int ctb_addr_ts) > if (s->ps.sps->ctb_width == 1) > cabac_init_state(s); > else if (s->sh.dependent_slice_segment_flag == 1) > - load_states(s); > + load_states(s, thread); > } > } > } else { > @@ -549,7 +556,7 @@ int ff_hevc_cabac_init(HEVCContext *s, int ctb_addr_ts) > if (s->ps.sps->ctb_width == 1) > cabac_init_state(s); > else > - load_states(s); > + load_states(s, thread); > } > } > } > diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c > index 699c13bbcc..7191fcf542 100644 > --- a/libavcodec/hevcdec.c > +++ b/libavcodec/hevcdec.c > @@ -2473,7 +2473,7 @@ static int hls_decode_entry(AVCodecContext *avctxt, > void *isFilterThread) > y_ctb = (ctb_addr_rs / ((s->ps.sps->width + ctb_size - 1) >> > s->ps.sps->log2_ctb_size)) << s->ps.sps->log2_ctb_size; > hls_decode_neighbour(s, x_ctb, y_ctb, ctb_addr_ts); > > - ret = ff_hevc_cabac_init(s, ctb_addr_ts); > + ret = ff_hevc_cabac_init(s, ctb_addr_ts, 0); > if (ret < 0) { > s->tab_slice_address[ctb_addr_rs] = -1; > return ret; > @@ -2551,7 +2551,7 @@ static int hls_decode_entry_wpp(AVCodecContext > *avctxt, void *input_ctb_row, int > return 0; > } > > - ret = ff_hevc_cabac_init(s, ctb_addr_ts); > + ret = ff_hevc_cabac_init(s, ctb_addr_ts, thread); > if (ret < 0) > goto error; > hls_sao_param(s, x_ctb >> s->ps.sps->log2_ctb_size, y_ctb >> > s->ps.sps->log2_ctb_size); > diff --git a/libavcodec/hevcdec.h b/libavcodec/hevcdec.h > index 39c5c7f89f..5b49384aea 100644 > --- a/libavcodec/hevcdec.h > +++ b/libavcodec/hevcdec.h > @@ -53,6 +53,7 @@ > #define DEFAULT_INTRA_TC_OFFSET 2 > > #define HEVC_CONTEXTS 199 > +#define HEVC_STAT_COEFFS 4 > > #define MRG_MAX_NUM_CANDS 5 > > @@ -424,7 +425,7 @@ typedef struct HEVCFrame { > typedef struct HEVCLocalContext { > uint8_t cabac_state[HEVC_CONTEXTS]; > > - uint8_t stat_coeff[4]; > + uint8_t stat_coeff[HEVC_STAT_COEFFS]; > > uint8_t first_qp_group; > > @@ -480,6 +481,7 @@ typedef struct HEVCContext { > int height; > > uint8_t *cabac_state; > + uint8_t stat_coeff[HEVC_STAT_COEFFS]; > > /** 1 if the independent slice segment header was successfully parsed > */ > uint8_t slice_initialized; > @@ -594,7 +596,7 @@ int ff_hevc_frame_rps(HEVCContext *s); > int ff_hevc_slice_rpl(HEVCContext *s); > > void ff_hevc_save_states(HEVCContext *s, int ctb_addr_ts); > -int ff_hevc_cabac_init(HEVCContext *s, int ctb_addr_ts); > +int ff_hevc_cabac_init(HEVCContext *s, int ctb_addr_ts, int thread); > int ff_hevc_sao_merge_flag_decode(HEVCContext *s); > int ff_hevc_sao_type_idx_decode(HEVCContext *s); > int ff_hevc_sao_band_position_decode(HEVCContext *s); > -- > 2.17.1 > >
diff --git a/libavcodec/hevc_cabac.c b/libavcodec/hevc_cabac.c index 3dc0987dad..93fc1ec795 100644 --- a/libavcodec/hevc_cabac.c +++ b/libavcodec/hevc_cabac.c @@ -454,12 +454,19 @@ void ff_hevc_save_states(HEVCContext *s, int ctb_addr_ts) (s->ps.sps->ctb_width == 2 && ctb_addr_ts % s->ps.sps->ctb_width == 0))) { memcpy(s->cabac_state, s->HEVClc->cabac_state, HEVC_CONTEXTS); + if (s->ps.sps->persistent_rice_adaptation_enabled_flag) { + memcpy(s->stat_coeff, s->HEVClc->stat_coeff, HEVC_STAT_COEFFS); + } } } -static void load_states(HEVCContext *s) +static void load_states(HEVCContext *s, int thread) { memcpy(s->HEVClc->cabac_state, s->cabac_state, HEVC_CONTEXTS); + if (s->ps.sps->persistent_rice_adaptation_enabled_flag) { + const HEVCContext *prev = s->sList[(thread + s->threads_number - 1) % s->threads_number]; + memcpy(s->HEVClc->stat_coeff, prev->stat_coeff, HEVC_STAT_COEFFS); + } } static int cabac_reinit(HEVCLocalContext *lc) @@ -501,7 +508,7 @@ static void cabac_init_state(HEVCContext *s) s->HEVClc->stat_coeff[i] = 0; } -int ff_hevc_cabac_init(HEVCContext *s, int ctb_addr_ts) +int ff_hevc_cabac_init(HEVCContext *s, int ctb_addr_ts, int thread) { if (ctb_addr_ts == s->ps.pps->ctb_addr_rs_to_ts[s->sh.slice_ctb_addr_rs]) { int ret = cabac_init_decoder(s); @@ -518,7 +525,7 @@ int ff_hevc_cabac_init(HEVCContext *s, int ctb_addr_ts) if (s->ps.sps->ctb_width == 1) cabac_init_state(s); else if (s->sh.dependent_slice_segment_flag == 1) - load_states(s); + load_states(s, thread); } } } else { @@ -549,7 +556,7 @@ int ff_hevc_cabac_init(HEVCContext *s, int ctb_addr_ts) if (s->ps.sps->ctb_width == 1) cabac_init_state(s); else - load_states(s); + load_states(s, thread); } } } diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index 699c13bbcc..7191fcf542 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -2473,7 +2473,7 @@ static int hls_decode_entry(AVCodecContext *avctxt, void *isFilterThread) y_ctb = (ctb_addr_rs / ((s->ps.sps->width + ctb_size - 1) >> s->ps.sps->log2_ctb_size)) << s->ps.sps->log2_ctb_size; hls_decode_neighbour(s, x_ctb, y_ctb, ctb_addr_ts); - ret = ff_hevc_cabac_init(s, ctb_addr_ts); + ret = ff_hevc_cabac_init(s, ctb_addr_ts, 0); if (ret < 0) { s->tab_slice_address[ctb_addr_rs] = -1; return ret; @@ -2551,7 +2551,7 @@ static int hls_decode_entry_wpp(AVCodecContext *avctxt, void *input_ctb_row, int return 0; } - ret = ff_hevc_cabac_init(s, ctb_addr_ts); + ret = ff_hevc_cabac_init(s, ctb_addr_ts, thread); if (ret < 0) goto error; hls_sao_param(s, x_ctb >> s->ps.sps->log2_ctb_size, y_ctb >> s->ps.sps->log2_ctb_size); diff --git a/libavcodec/hevcdec.h b/libavcodec/hevcdec.h index 39c5c7f89f..5b49384aea 100644 --- a/libavcodec/hevcdec.h +++ b/libavcodec/hevcdec.h @@ -53,6 +53,7 @@ #define DEFAULT_INTRA_TC_OFFSET 2 #define HEVC_CONTEXTS 199 +#define HEVC_STAT_COEFFS 4 #define MRG_MAX_NUM_CANDS 5 @@ -424,7 +425,7 @@ typedef struct HEVCFrame { typedef struct HEVCLocalContext { uint8_t cabac_state[HEVC_CONTEXTS]; - uint8_t stat_coeff[4]; + uint8_t stat_coeff[HEVC_STAT_COEFFS]; uint8_t first_qp_group; @@ -480,6 +481,7 @@ typedef struct HEVCContext { int height; uint8_t *cabac_state; + uint8_t stat_coeff[HEVC_STAT_COEFFS]; /** 1 if the independent slice segment header was successfully parsed */ uint8_t slice_initialized; @@ -594,7 +596,7 @@ int ff_hevc_frame_rps(HEVCContext *s); int ff_hevc_slice_rpl(HEVCContext *s); void ff_hevc_save_states(HEVCContext *s, int ctb_addr_ts); -int ff_hevc_cabac_init(HEVCContext *s, int ctb_addr_ts); +int ff_hevc_cabac_init(HEVCContext *s, int ctb_addr_ts, int thread); int ff_hevc_sao_merge_flag_decode(HEVCContext *s); int ff_hevc_sao_type_idx_decode(HEVCContext *s); int ff_hevc_sao_band_position_decode(HEVCContext *s);
It's required by the 9.3.1 TableStatCoeff* section. Following clips have this feature: WPP_HIGH_TP_444_8BIT_RExt_Apple_2.bit Bitdepth_A_RExt_Sony_1.bin Bitdepth_B_RExt_Sony_1.bin EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_10BIT_RExt_Sony_1.bit EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_12BIT_RExt_Sony_1.bit EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_8BIT_RExt_Sony_1.bit EXTPREC_MAIN_444_16_INTRA_10BIT_RExt_Sony_1.bit EXTPREC_MAIN_444_16_INTRA_12BIT_RExt_Sony_1.bit EXTPREC_MAIN_444_16_INTRA_8BIT_RExt_Sony_1.bit WPP_AND_TILE_10Bit422Test_HIGH_TP_444_10BIT_RExt_Apple_2.bit WPP_AND_TILE_AND_CABAC_BYPASS_ALIGN_0_HIGH_TP_444_14BIT_RExt_Apple_2.bit WPP_AND_TILE_AND_CABAC_BYPASS_ALIGN_1_HIGH_TP_444_14BIT_RExt_Apple_2.bit WPP_AND_TILE_HIGH_TP_444_8BIT_RExt_Apple_2.bit you can download them from: https://www.itu.int/wftp3/av-arch/jctvc-site/bitstream_exchange/draft_conformance/RExt/ Signed-off-by: Xu Guangxin <oddstone@gmail.com> --- libavcodec/hevc_cabac.c | 15 +++++++++++---- libavcodec/hevcdec.c | 4 ++-- libavcodec/hevcdec.h | 6 ++++-- 3 files changed, 17 insertions(+), 8 deletions(-)