From: Christophe Gisquet <christophe.gisquet@gmail.com> To: ffmpeg-devel@ffmpeg.org Subject: [FFmpeg-devel] [PATCH 5/7] proresdec2: use VLC for small runs and levels Date: Fri, 8 Sep 2023 10:15:06 +0200 Message-ID: <20230908081508.510-5-christophe.gisquet@gmail.com> (raw) In-Reply-To: <20230908081508.510-1-christophe.gisquet@gmail.com> Basically, the catch-all codebook is for on average long codewords, and with a distribution such that the 3-step VLC reading is not efficient. Furthermore, the complete unrolling make the actual code smaller than the macro, and as the maximum codelength is smaller, smaller amounts of bits, optimized for run and for level, can be read. --- libavcodec/proresdec2.c | 53 +++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 29 deletions(-) diff --git a/libavcodec/proresdec2.c b/libavcodec/proresdec2.c index e3cef402d7..02e1d82d00 100644 --- a/libavcodec/proresdec2.c +++ b/libavcodec/proresdec2.c @@ -132,7 +132,7 @@ static void unpack_alpha_12(GetBitContext *gb, uint16_t *dst, int num_coeffs, #define AC_BITS 12 #define PRORES_LEV_BITS 9 -static const uint8_t ac_info[] = { 0x04, 0x0A, 0x05, 0x06, 0x28, 0x4C }; +static const uint8_t ac_info[] = { 0x04, 0x0A, 0x05, 0x06, 0x28, 0x29 }; static VLC ac_vlc[6]; static av_cold void init_vlcs(void) @@ -152,9 +152,7 @@ static av_cold void init_vlcs(void) switch_val = (switch_bits+1) << rice_order; // Values are actually transformed, but this is more a wrapping - ac_codes[0] = 0; - ac_bits[0] = 0; - for (ac = 0; ac < (1<<AC_BITS)-1; ac++) { + for (ac = 0; ac <1<<AC_BITS; ac++) { int exponent, bits, val = ac; unsigned int code; @@ -171,8 +169,8 @@ static av_cold void init_vlcs(void) code = 1; } if (bits > max_bits) max_bits = bits; - ac_bits [ac+1] = bits; - ac_codes[ac+1] = code; + ac_bits [ac] = bits; + ac_codes[ac] = code; } ff_free_vlc(ac_vlc+i); @@ -507,12 +505,9 @@ static int decode_picture_header(AVCodecContext *avctx, const uint8_t *buf, cons bits = exp_order - switch_bits + (q<<1); \ val = READ_BITS(gb, bits) - (1 << exp_order) + \ ((switch_bits + 1) << rice_order); \ - } else if (rice_order) { \ - skip_remaining(gb, q+1); \ - val = (q << rice_order) + get_bits(gb, rice_order); \ } else { \ - val = q; \ skip_remaining(gb, q+1); \ + val = rice_order ? (q << rice_order) + get_bits(gb, rice_order) : q;\ } \ } while (0) @@ -527,12 +522,10 @@ static int decode_picture_header(AVCodecContext *avctx, const uint8_t *buf, cons if (q > switch_bits) { /* exp golomb */ \ bits = (q<<1) + (int)diff; \ val = READ_BITS(gb, bits) + (int)offset; \ - } else if (rice_order) { \ - skip_remaining(gb, q+1); \ - val = (q << rice_order) + get_bits(gb, rice_order); \ } else { \ - val = q; \ skip_remaining(gb, q+1); \ + val = rice_order ? (q << rice_order) + show_bits(gb, rice_order) : q; \ + skip_remaining(gb, rice_order); \ } \ } while (0) @@ -571,14 +564,6 @@ static av_always_inline int decode_dc_coeffs(GetBitContext *gb, int16_t *out, return 0; } -// adaptive codebook switching lut according to previous run values -static const char run_to_cb[16][4] = { - { 2, 0, -1, 1 }, { 2, 0, -1, 1 }, { 1, 0, 0, 0 }, { 1, 0, 0, 0 }, { 0, 0, 1, -1 }, - { 1, 1, 1, 0 }, { 1, 1, 1, 0 }, { 1, 1, 1, 0 }, { 1, 1, 1, 0 }, - { 0, 1, 2, -2 }, { 0, 1, 2, -2 }, { 0, 1, 2, -2 }, { 0, 1, 2, -2 }, { 0, 1, 2, -2 }, { 0, 1, 2, -2 }, - { 0, 2, 3, -4 } -}; - static av_always_inline int decode_ac_coeffs(AVCodecContext *avctx, GetBitContext *gb, int16_t *out, int blocks_per_slice) { @@ -595,22 +580,32 @@ static av_always_inline int decode_ac_coeffs(AVCodecContext *avctx, GetBitContex block_mask = blocks_per_slice - 1; for (pos = block_mask;;) { - static const uint8_t ctx_to_tbl[] = { 0, 1, 2, 3, 0, 4, 4, 4, 4, 5 }; - const VLC* tbl = ac_vlc + ctx_to_tbl[FFMIN(level, 9)]; - unsigned int runcb = FFMIN(run, 15); bits_rem = get_bits_left(gb); - if (!bits_rem || (bits_rem < 16 && !show_bits(gb, bits_rem))) + if (!bits_rem || (bits_rem < 14 && !show_bits(gb, bits_rem))) break; - DECODE_CODEWORD2(run, run_to_cb[runcb][0], run_to_cb[runcb][1], - run_to_cb[runcb][2], run_to_cb[runcb][3]); + if (run < 15) { + static const uint8_t ctx_to_tbl[] = { 3, 3, 2, 2, 0, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4 }; + const VLC* tbl = ac_vlc + ctx_to_tbl[run]; + run = get_vlc2(gb, tbl->table, PRORES_LEV_BITS, 3); + } else { + unsigned int bits = 21 - 2*av_log2(show_bits(gb, 10)); + run = READ_BITS(gb, bits) - 4; // up to 17 bits + } pos += run + 1; if (pos >= max_coeffs) { av_log(avctx, AV_LOG_ERROR, "ac tex damaged %d, %d\n", pos, max_coeffs); return AVERROR_INVALIDDATA; } - level = get_vlc2(gb, tbl->table, PRORES_LEV_BITS, 3); + if (level < 9) { + static const uint8_t ctx_to_tbl[] = { 0, 1, 2, 3, 0, 4, 4, 4, 4 }; + const VLC* tbl = ac_vlc + ctx_to_tbl[level]; + level = 1+get_vlc2(gb, tbl->table, PRORES_LEV_BITS, 3); + } else { + unsigned int bits = 25 - 2*av_log2(show_bits(gb, 12)); + level = READ_BITS(gb, bits) - 4 + 1; // up to 21 bits + } i = pos >> log2_block_count; -- 2.42.0 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
next prev parent reply other threads:[~2023-09-08 8:16 UTC|newest] Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top 2023-09-08 8:15 [FFmpeg-devel] [PATCH 1/7] proresdec2: port and fix for cached reader Christophe Gisquet 2023-09-08 8:15 ` [FFmpeg-devel] [PATCH 2/7] proresdec2: store precomputed EC parameters Christophe Gisquet 2023-09-08 8:39 ` Andreas Rheinhardt 2023-09-08 8:15 ` [FFmpeg-devel] [PATCH 3/7] proresdec2: use VLC for level instead of EC switch Christophe Gisquet 2023-09-08 8:44 ` Andreas Rheinhardt 2023-09-08 9:58 ` Andreas Rheinhardt 2023-09-10 15:28 ` Christophe Gisquet 2023-09-10 15:41 ` Andreas Rheinhardt 2023-09-10 15:56 ` Christophe Gisquet 2023-09-08 8:15 ` [FFmpeg-devel] [PATCH 4/7] proresdec2: offset VLCs by 1 to avoid 1 add Christophe Gisquet 2023-09-08 8:15 ` Christophe Gisquet [this message] 2023-09-08 8:15 ` [FFmpeg-devel] [PATCH 6/7] proresdec2: remove a useless DC codebook entry Christophe Gisquet 2023-09-08 9:08 ` Andreas Rheinhardt 2023-09-08 8:15 ` [FFmpeg-devel] [PATCH 7/7] prores: use VLC LUTs Christophe Gisquet 2023-09-08 9:20 ` Andreas Rheinhardt 2023-09-08 9:58 ` Christophe Gisquet 2023-09-08 8:20 ` [FFmpeg-devel] [PATCH 1/7] proresdec2: port and fix for cached reader Christophe Gisquet 2023-09-08 8:30 ` Andreas Rheinhardt 2023-09-08 8:34 ` Andreas Rheinhardt 2023-09-11 20:54 ` Christophe Gisquet 2023-09-08 8:36 ` Andreas Rheinhardt 2023-09-08 21:00 ` Michael Niedermayer
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20230908081508.510-5-christophe.gisquet@gmail.com \ --to=christophe.gisquet@gmail.com \ --cc=ffmpeg-devel@ffmpeg.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git