Re: [FFmpeg-devel] [PATCH v9 03/13] vvcdec: add cabac decoder
On Tue, Jan 2, 2024 at 11:57 PM Lynne wrote: > Jan 2, 2024, 14:22 by nuomi2...@gmail.com: > > > On Mon, Jan 1, 2024 at 11:13 PM Lynne wrote: > > > >> > >> > >> > >> Jan 1, 2024, 15:14 by nuomi2...@gmail.com: > >> > >> > + > >> > +//fixme > >> > +static void vvc_refill2(CABACContext* c) { > >> > > >> > >> Fix what? > >> Also, wrong coding style. > >> > > The function is a copy of refill2 in cabac_functions.h, including the > style. > > The refill2 is protected by get_cabac_inline. > > On x86, get_cabac_inline is only defined when HAVE_7REGS && > > !BROKEN_COMPILER is true. > > It can be challenging to figure out how to get refill2 defined in this > > context. > > Let us use https://github.com/ffvvc/FFmpeg/issues/178 to track this > > > > Are you thinking about sharing the code later on? > If not, then there's no reason to have the duplicated function > and style issues. > Yes, I will remove it and use refill2. But I need help from the original author, @Michael > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". > ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v9 03/13] vvcdec: add cabac decoder
Jan 2, 2024, 14:22 by nuomi2...@gmail.com: > On Mon, Jan 1, 2024 at 11:13 PM Lynne wrote: > >> >> >> >> Jan 1, 2024, 15:14 by nuomi2...@gmail.com: >> >> > + >> > +//fixme >> > +static void vvc_refill2(CABACContext* c) { >> > >> >> Fix what? >> Also, wrong coding style. >> > The function is a copy of refill2 in cabac_functions.h, including the style. > The refill2 is protected by get_cabac_inline. > On x86, get_cabac_inline is only defined when HAVE_7REGS && > !BROKEN_COMPILER is true. > It can be challenging to figure out how to get refill2 defined in this > context. > Let us use https://github.com/ffvvc/FFmpeg/issues/178 to track this > Are you thinking about sharing the code later on? If not, then there's no reason to have the duplicated function and style issues. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v9 03/13] vvcdec: add cabac decoder
On Tue, Jan 2, 2024 at 1:35 AM Michael Niedermayer wrote: > On Mon, Jan 01, 2024 at 10:12:29PM +0800, Nuo Mi wrote: > > add Context-based Adaptive Binary Arithmetic Coding (CABAC) decoder > > > > Co-authored-by: Xu Mu > > Co-authored-by: Frank Plowman > > Co-authored-by: Shaun Loo > > Co-authored-by: Wu Jianhua > > --- > > libavcodec/vvc/Makefile|4 +- > > libavcodec/vvc/vvc_cabac.c | 2478 > > libavcodec/vvc/vvc_cabac.h | 126 ++ > > libavcodec/vvc/vvc_ctu.c | 32 + > > libavcodec/vvc/vvc_ctu.h | 464 +++ > > libavcodec/vvc/vvcdec.h|7 + > > 6 files changed, 3110 insertions(+), 1 deletion(-) > > create mode 100644 libavcodec/vvc/vvc_cabac.c > > create mode 100644 libavcodec/vvc/vvc_cabac.h > > create mode 100644 libavcodec/vvc/vvc_ctu.c > > create mode 100644 libavcodec/vvc/vvc_ctu.h > > [...] > > > +static int residual_ts_coding_subblock(VVCLocalContext *lc, > ResidualCoding* rc, const int i) > > +{ > > +const CodingUnit *cu = lc->cu; > > +TransformBlock *tb = rc->tb; > > +const int bdpcm_flag = cu->bdpcm_flag[tb->c_idx]; > > +const int xs = rc->sb_scan_x_off[i]; > > +const int ys = rc->sb_scan_y_off[i]; > > +uint8_t *sb_coded_flag = rc->sb_coded_flag + ys * rc->width_in_sbs > + xs; > > +int infer_sb_sig_coeff_flag = 1; > > +int last_scan_pos_pass1 = -1, last_scan_pos_pass2 = -1, n; > > +int abs_level_gtx_flag[MAX_SUB_BLOCK_SIZE * MAX_SUB_BLOCK_SIZE]; > > +int abs_level_pass2[MAX_SUB_BLOCK_SIZE * MAX_SUB_BLOCK_SIZE]; > ///< AbsLevelPass2 > > + > > +if (i != rc->last_sub_block || !rc->infer_sb_cbf) > > +*sb_coded_flag = sb_coded_flag_decode(lc, sb_coded_flag, rc, > xs, ys); > > +else > > +*sb_coded_flag = 1; > > +if (*sb_coded_flag && i < rc->last_sub_block) > > +rc->infer_sb_cbf = 0; > > + > > +//first scan pass > > +for (n = 0; n < rc->num_sb_coeff && rc->rem_bins_pass1 >= 4; n++) { > > +const int xc = (xs << rc->log2_sb_w) + rc->scan_x_off[n]; > > +const int yc = (ys << rc->log2_sb_h) + rc->scan_y_off[n]; > > +const int off = yc * tb->tb_width + xc; > > +int *sig_coeff_flag = rc->sig_coeff_flag + off; > > +int *abs_level_pass1 = rc->abs_level_pass1 + off; > > +int *coeff_sign_level = rc->coeff_sign_level + off; > > +int par_level_flag= 0; > > + > > +abs_level_gtx_flag[n] = 0; > > +last_scan_pos_pass1 = n; > > +if (*sb_coded_flag && (n != rc->num_sb_coeff - 1 || > !infer_sb_sig_coeff_flag)) { > > +*sig_coeff_flag = sig_coeff_flag_decode(lc, rc, xc, yc); > > +rc->rem_bins_pass1--; > > +if (*sig_coeff_flag) > > +infer_sb_sig_coeff_flag = 0; > > +} else { > > +*sig_coeff_flag = (n == rc->num_sb_coeff - 1) && > infer_sb_sig_coeff_flag && *sb_coded_flag; > > +} > > +*coeff_sign_level = 0; > > +if (*sig_coeff_flag) { > > +*coeff_sign_level = 1 - 2 * coeff_sign_flag_ts_decode(lc, > cu, rc, xc, yc); > > +abs_level_gtx_flag[n] = abs_level_gt1_flag_ts_decode(lc, > cu, rc, xc, yc); > > +rc->rem_bins_pass1 -= 2; > > +if (abs_level_gtx_flag[n]) { > > +par_level_flag = par_level_flag_ts_decode(lc); > > +rc->rem_bins_pass1--; > > +} > > +} > > +*abs_level_pass1 = *sig_coeff_flag + par_level_flag + > abs_level_gtx_flag[n]; > > +} > > + > > +//greater than x scan pass > > +for (n = 0; n < rc->num_sb_coeff && rc->rem_bins_pass1 >= 4; n++) { > > +const int xc = (xs << rc->log2_sb_w) + rc->scan_x_off[n]; > > +const int yc = (ys << rc->log2_sb_h) + rc->scan_y_off[n]; > > +const int off = yc * tb->tb_width + xc; > > + > > +abs_level_pass2[n] = rc->abs_level_pass1[off]; > > +for (int j = 1; j < 5 && abs_level_gtx_flag[n]; j++) { > > +abs_level_gtx_flag[n] = abs_level_gtx_flag_ts_decode(lc, j); > > +abs_level_pass2[n] += abs_level_gtx_flag[n] << 1; > > +rc->rem_bins_pass1--; > > +} > > +last_scan_pos_pass2 = n; > > +} > > + > > +/* remainder scan pass */ > > +for (n = 0; n < rc->num_sb_coeff; n++) { > > +const int xc = (xs << rc->log2_sb_w) + rc->scan_x_off[n]; > > +const int yc = (ys << rc->log2_sb_h) + rc->scan_y_off[n]; > > +const int off = yc * tb->tb_width + xc; > > +const int *abs_level_pass1 = rc->abs_level_pass1 + off; > > +int *abs_level = rc->abs_level + off; > > +int *coeff_sign_level = rc->coeff_sign_level + off; > > +int abs_remainder = 0; > > + > > +if ((n <= last_scan_pos_pass2 && abs_level_pass2[n] >= 10) || > > +(n > last_scan_pos_pass2 && n <= last_scan_pos_pass1 && > > +*abs_level_pass1 >= 2) || > > +
Re: [FFmpeg-devel] [PATCH v9 03/13] vvcdec: add cabac decoder
On Mon, Jan 1, 2024 at 11:13 PM Lynne wrote: > > > > Jan 1, 2024, 15:14 by nuomi2...@gmail.com: > > > + > > +//fixme > > +static void vvc_refill2(CABACContext* c) { > > > > Fix what? > Also, wrong coding style. > The function is a copy of refill2 in cabac_functions.h, including the style. The refill2 is protected by get_cabac_inline. On x86, get_cabac_inline is only defined when HAVE_7REGS && !BROKEN_COMPILER is true. It can be challenging to figure out how to get refill2 defined in this context. Let us use https://github.com/ffvvc/FFmpeg/issues/178 to track this > > > +int i; > > +unsigned x; > > +#if !HAVE_FAST_CLZ > > +x = c->low ^ (c->low - 1); > > +i = 7 - ff_h264_norm_shift[x >> (CABAC_BITS - 1)]; > > +#else > > +i = ff_ctz(c->low) - CABAC_BITS; > > +#endif > > + > > +x = -CABAC_MASK; > > + > > +#if CABAC_BITS == 16 > > +x += (c->bytestream[0] << 9) + (c->bytestream[1] << 1); > > +#else > > +x += c->bytestream[0] << 1; > > +#endif > > > > CABAC_BITS? > > ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v9 03/13] vvcdec: add cabac decoder
On Mon, Jan 01, 2024 at 10:12:29PM +0800, Nuo Mi wrote: > add Context-based Adaptive Binary Arithmetic Coding (CABAC) decoder > > Co-authored-by: Xu Mu > Co-authored-by: Frank Plowman > Co-authored-by: Shaun Loo > Co-authored-by: Wu Jianhua > --- > libavcodec/vvc/Makefile|4 +- > libavcodec/vvc/vvc_cabac.c | 2478 > libavcodec/vvc/vvc_cabac.h | 126 ++ > libavcodec/vvc/vvc_ctu.c | 32 + > libavcodec/vvc/vvc_ctu.h | 464 +++ > libavcodec/vvc/vvcdec.h|7 + > 6 files changed, 3110 insertions(+), 1 deletion(-) > create mode 100644 libavcodec/vvc/vvc_cabac.c > create mode 100644 libavcodec/vvc/vvc_cabac.h > create mode 100644 libavcodec/vvc/vvc_ctu.c > create mode 100644 libavcodec/vvc/vvc_ctu.h [...] > +static int residual_ts_coding_subblock(VVCLocalContext *lc, ResidualCoding* > rc, const int i) > +{ > +const CodingUnit *cu = lc->cu; > +TransformBlock *tb = rc->tb; > +const int bdpcm_flag = cu->bdpcm_flag[tb->c_idx]; > +const int xs = rc->sb_scan_x_off[i]; > +const int ys = rc->sb_scan_y_off[i]; > +uint8_t *sb_coded_flag = rc->sb_coded_flag + ys * rc->width_in_sbs + xs; > +int infer_sb_sig_coeff_flag = 1; > +int last_scan_pos_pass1 = -1, last_scan_pos_pass2 = -1, n; > +int abs_level_gtx_flag[MAX_SUB_BLOCK_SIZE * MAX_SUB_BLOCK_SIZE]; > +int abs_level_pass2[MAX_SUB_BLOCK_SIZE * MAX_SUB_BLOCK_SIZE]; ///< > AbsLevelPass2 > + > +if (i != rc->last_sub_block || !rc->infer_sb_cbf) > +*sb_coded_flag = sb_coded_flag_decode(lc, sb_coded_flag, rc, xs, ys); > +else > +*sb_coded_flag = 1; > +if (*sb_coded_flag && i < rc->last_sub_block) > +rc->infer_sb_cbf = 0; > + > +//first scan pass > +for (n = 0; n < rc->num_sb_coeff && rc->rem_bins_pass1 >= 4; n++) { > +const int xc = (xs << rc->log2_sb_w) + rc->scan_x_off[n]; > +const int yc = (ys << rc->log2_sb_h) + rc->scan_y_off[n]; > +const int off = yc * tb->tb_width + xc; > +int *sig_coeff_flag = rc->sig_coeff_flag + off; > +int *abs_level_pass1 = rc->abs_level_pass1 + off; > +int *coeff_sign_level = rc->coeff_sign_level + off; > +int par_level_flag= 0; > + > +abs_level_gtx_flag[n] = 0; > +last_scan_pos_pass1 = n; > +if (*sb_coded_flag && (n != rc->num_sb_coeff - 1 || > !infer_sb_sig_coeff_flag)) { > +*sig_coeff_flag = sig_coeff_flag_decode(lc, rc, xc, yc); > +rc->rem_bins_pass1--; > +if (*sig_coeff_flag) > +infer_sb_sig_coeff_flag = 0; > +} else { > +*sig_coeff_flag = (n == rc->num_sb_coeff - 1) && > infer_sb_sig_coeff_flag && *sb_coded_flag; > +} > +*coeff_sign_level = 0; > +if (*sig_coeff_flag) { > +*coeff_sign_level = 1 - 2 * coeff_sign_flag_ts_decode(lc, cu, > rc, xc, yc); > +abs_level_gtx_flag[n] = abs_level_gt1_flag_ts_decode(lc, cu, rc, > xc, yc); > +rc->rem_bins_pass1 -= 2; > +if (abs_level_gtx_flag[n]) { > +par_level_flag = par_level_flag_ts_decode(lc); > +rc->rem_bins_pass1--; > +} > +} > +*abs_level_pass1 = *sig_coeff_flag + par_level_flag + > abs_level_gtx_flag[n]; > +} > + > +//greater than x scan pass > +for (n = 0; n < rc->num_sb_coeff && rc->rem_bins_pass1 >= 4; n++) { > +const int xc = (xs << rc->log2_sb_w) + rc->scan_x_off[n]; > +const int yc = (ys << rc->log2_sb_h) + rc->scan_y_off[n]; > +const int off = yc * tb->tb_width + xc; > + > +abs_level_pass2[n] = rc->abs_level_pass1[off]; > +for (int j = 1; j < 5 && abs_level_gtx_flag[n]; j++) { > +abs_level_gtx_flag[n] = abs_level_gtx_flag_ts_decode(lc, j); > +abs_level_pass2[n] += abs_level_gtx_flag[n] << 1; > +rc->rem_bins_pass1--; > +} > +last_scan_pos_pass2 = n; > +} > + > +/* remainder scan pass */ > +for (n = 0; n < rc->num_sb_coeff; n++) { > +const int xc = (xs << rc->log2_sb_w) + rc->scan_x_off[n]; > +const int yc = (ys << rc->log2_sb_h) + rc->scan_y_off[n]; > +const int off = yc * tb->tb_width + xc; > +const int *abs_level_pass1 = rc->abs_level_pass1 + off; > +int *abs_level = rc->abs_level + off; > +int *coeff_sign_level = rc->coeff_sign_level + off; > +int abs_remainder = 0; > + > +if ((n <= last_scan_pos_pass2 && abs_level_pass2[n] >= 10) || > +(n > last_scan_pos_pass2 && n <= last_scan_pos_pass1 && > +*abs_level_pass1 >= 2) || > +(n > last_scan_pos_pass1 && *sb_coded_flag)) > +abs_remainder = abs_remainder_ts_decode(lc, rc, xc, yc); > +if (n <= last_scan_pos_pass2) { > +*abs_level = abs_level_pass2[n] + 2 * abs_remainder; > +} else if
Re: [FFmpeg-devel] [PATCH v9 03/13] vvcdec: add cabac decoder
Jan 1, 2024, 15:14 by nuomi2...@gmail.com: > + > +//fixme > +static void vvc_refill2(CABACContext* c) { > Fix what? Also, wrong coding style. > +int i; > +unsigned x; > +#if !HAVE_FAST_CLZ > +x = c->low ^ (c->low - 1); > +i = 7 - ff_h264_norm_shift[x >> (CABAC_BITS - 1)]; > +#else > +i = ff_ctz(c->low) - CABAC_BITS; > +#endif > + > +x = -CABAC_MASK; > + > +#if CABAC_BITS == 16 > +x += (c->bytestream[0] << 9) + (c->bytestream[1] << 1); > +#else > +x += c->bytestream[0] << 1; > +#endif > CABAC_BITS? > + > +c->low += x << i; > +#if !UNCHECKED_BITSTREAM_READER > +if (c->bytestream < c->bytestream_end) > +#endif > +c->bytestream += CABAC_BITS / 8; > +} > + > +static int inline vvc_get_cabac(CABACContext *c, VVCCabacState* base, const > int ctx) > +{ > +VVCCabacState *s = base + ctx; > +const int qRangeIdx = c->range >> 5; > +const int pState = s->state[1] + (s->state[0] << 4); > +const int valMps = pState >> 14; > +const int RangeLPS = (qRangeIdx * ((valMps ? 32767 - pState : pState) >> > 9 ) >> 1) + 4; > +int bit, lps_mask; > + > +c->range -= RangeLPS; > +lps_mask = ((c->range<<(CABAC_BITS+1)) - c->low)>>31; > + > +c->low -= (c->range<<(CABAC_BITS+1)) & lps_mask; > +c->range += (RangeLPS - c->range) & lps_mask; > + > +bit = valMps ^ (lps_mask & 1); > + > +lps_mask = ff_h264_norm_shift[c->range]; > +c->range <<= lps_mask; > +c->low <<= lps_mask; > + > +if (!(c->low & CABAC_MASK)) > +vvc_refill2(c); > +s->state[0] = s->state[0] - (s->state[0] >> s->shift[0]) + (1023 * bit > >> s->shift[0]); > +s->state[1] = s->state[1] - (s->state[1] >> s->shift[1]) + (16383 * bit > >> s->shift[1]); > +return bit; > +} > + > +#define GET_CABAC(ctx) vvc_get_cabac(>ep->cc, lc->ep->cabac_state, ctx) > + > +//9.3.3.4 Truncated binary (TB) binarization process > +static int truncated_binary_decode(VVCLocalContext *lc, const int c_max) > +{ > +const int n = c_max + 1; > +const int k = av_log2(n); > +const int u = (1 << (k+1)) - n; > +int v = 0; > +for (int i = 0; i < k; i++) > +v = (v << 1) | get_cabac_bypass(>ep->cc); > +if (v >= u) { > +v = (v << 1) | get_cabac_bypass(>ep->cc); > +v -= u; > +} > +return v; > +} > + > +// 9.3.3.6 Limited k-th order Exp-Golomb binarization process > +static int limited_kth_order_egk_decode(CABACContext *c, const int k, const > int max_pre_ext_len, const int trunc_suffix_len) > +{ > +int pre_ext_len = 0; > +int escape_length; > +int val = 0; > +while ((pre_ext_len < max_pre_ext_len) && get_cabac_bypass(c)) > +pre_ext_len++; > +if (pre_ext_len == max_pre_ext_len) > +escape_length = trunc_suffix_len; > +else > +escape_length = pre_ext_len + k; > +while (escape_length-- > 0) { > +val = (val << 1) + get_cabac_bypass(c); > +} > +val += ((1 << pre_ext_len) - 1) << k; > +return val; > +} > + > +static av_always_inline > +void get_left_top(const VVCLocalContext *lc, uint8_t *left, uint8_t *top, > +const int x0, const int y0, const uint8_t *left_ctx, const uint8_t > *top_ctx) > +{ > +const VVCFrameContext *fc = lc->fc; > +const VVCSPS *sps = fc->ps.sps; > +const int min_cb_width= fc->ps.pps->min_cb_width; > +const int x0b = av_mod_uintp2(x0, sps->ctb_log2_size_y); > +const int y0b = av_mod_uintp2(y0, sps->ctb_log2_size_y); > +const int x_cb = x0 >> sps->min_cb_log2_size_y; > +const int y_cb = y0 >> sps->min_cb_log2_size_y; > + > +if (lc->ctb_left_flag || x0b) > +*left = SAMPLE_CTB(left_ctx, x_cb - 1, y_cb); > +if (lc->ctb_up_flag || y0b) > +*top = SAMPLE_CTB(top_ctx, x_cb, y_cb - 1); > +} > + > +static av_always_inline > +uint8_t get_inc(VVCLocalContext *lc, const uint8_t *ctx) > +{ > +uint8_t left = 0, top = 0; > +get_left_top(lc, , , lc->cu->x0, lc->cu->y0, ctx, ctx); > +return left + top; > +} > + > +int ff_vvc_sao_merge_flag_decode(VVCLocalContext *lc) > +{ > +return GET_CABAC(SAO_MERGE_FLAG); > +} > + > +int ff_vvc_sao_type_idx_decode(VVCLocalContext *lc) > +{ > +if (!GET_CABAC(SAO_TYPE_IDX)) > +return SAO_NOT_APPLIED; > + > +if (!get_cabac_bypass(>ep->cc)) > +return SAO_BAND; > +return SAO_EDGE; > +} > + > +int ff_vvc_sao_band_position_decode(VVCLocalContext *lc) > +{ > +int value = get_cabac_bypass(>ep->cc); > + > +for (int i = 0; i < 4; i++) > +value = (value << 1) | get_cabac_bypass(>ep->cc); > +return value; > +} > + > +int ff_vvc_sao_offset_abs_decode(VVCLocalContext *lc) > +{ > +int i = 0; > +const int length = (1 << (FFMIN(lc->fc->ps.sps->bit_depth, 10) - 5)) - 1; > + > +while (i < length && get_cabac_bypass(>ep->cc)) > +i++; > +return i; > +} > + > +int ff_vvc_sao_offset_sign_decode(VVCLocalContext *lc) > +{ > +return get_cabac_bypass(>ep->cc); > +} > + > +int