Re: [FFmpeg-devel] [PATCH v9 03/13] vvcdec: add cabac decoder

2024-01-02 Thread Nuo Mi
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

2024-01-02 Thread Lynne
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

2024-01-02 Thread Nuo Mi
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

2024-01-02 Thread Nuo Mi
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

2024-01-01 Thread Michael Niedermayer
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

2024-01-01 Thread Lynne



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