From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTP id C49904748C for ; Fri, 8 Sep 2023 08:16:07 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id B401568C89F; Fri, 8 Sep 2023 11:15:30 +0300 (EEST) Received: from smtp1-g21.free.fr (unknown [212.27.42.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id B533668C884 for ; Fri, 8 Sep 2023 11:15:22 +0300 (EEST) Received: from localhost.localdomain (unknown [IPv6:2a01:e0a:8a7:6440:5540:d7b2:7ae2:c181]) (Authenticated sender: christophe.gisquet@free.fr) by smtp1-g21.free.fr (Postfix) with ESMTPSA id 475DDB0051B for ; Fri, 8 Sep 2023 10:15:21 +0200 (CEST) From: Christophe Gisquet To: ffmpeg-devel@ffmpeg.org Date: Fri, 8 Sep 2023 10:15:06 +0200 Message-ID: <20230908081508.510-5-christophe.gisquet@gmail.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20230908081508.510-1-christophe.gisquet@gmail.com> References: <20230908081508.510-1-christophe.gisquet@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 5/7] proresdec2: use VLC for small runs and levels X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: 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< 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".