From patchwork Sat Oct 22 10:32:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 38902 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:4a86:b0:9d:28a3:170e with SMTP id fn6csp1222973pzb; Sat, 22 Oct 2022 03:34:38 -0700 (PDT) X-Google-Smtp-Source: AMsMyM67guKE9WstALrgMz+oNQEEPY056M6bH0Kyl277J2mSdpJ2m2kZHT7miU1j0au+LTh/01/u X-Received: by 2002:a17:907:2e0b:b0:78e:16cb:327b with SMTP id ig11-20020a1709072e0b00b0078e16cb327bmr19127554ejc.458.1666434877965; Sat, 22 Oct 2022 03:34:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666434877; cv=none; d=google.com; s=arc-20160816; b=HpSkelxolNqfwvNAoateJqEFfagWa0NVBdS2LrDt46HDI7dvAoNPTVjeEQ9XuMIfXM WCWvxa9+OfLQRSq8b5izqVKCKjP8LU2Uxr2gssBEtdchGfjQb9Mu0T+mYksbTvkbkA6e 0GLWZlRWvKQqCdzfytYuh49j37t9GqrDZRPjxyunBiS5nu3KgUuCo4tUDpazXdii+o0i CiXx+TFeEjp14f3VgbSpqUZPe3uYiAICPHkvoMrICd9aF1kzzXj5BoB+RajSBKPrJ1v9 yxZ9AGuze6C0TDd1NF6fzBmZpvCRJ2GoXmw0y6ipXt7rxaDoF1Lik36DDwOOvCivoQi1 IgSA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:references:in-reply-to:message-id :date:to:from:delivered-to; bh=mX4mmlmdwh4RwDxWVyb9jgXo4lETqgtg4YhyPRN+ouY=; b=JyyeRsmVTZQD+XqmwaIbFKDJym3S8uOEkRYF4+Gc6rzsXC/qhu3Z3hZpp571Nk+5Ec mY6Ry2vdjHDD7Fd9+c3g/Iu44fTR7tpU1WkPGWU5+Ka0lAYSMIHlDrQW/0eRQU7VK9ro JPVwOUzoaEjBnxv6cY6rTdjWfoPb8FAOYCiyZtovI+CHUDbrl0PeYVckHUH0J4I3pxZZ 0+AxFdml9rspcj+DRVIqZvWMwcdbQ+eksYynqZjs+ju7l1W7mm3mqEfVmoaayLuWagr6 TlZK4R7CihtgVaqjK74TkL3hFoTBDClxH/lqS4Vi4jNORR7BOjV7Lk+kTtx9xkuHOZj+ 8AEg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id gt31-20020a1709072d9f00b0078debc9d30fsi27473775ejc.45.2022.10.22.03.34.37; Sat, 22 Oct 2022 03:34:37 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 31DB968BE70; Sat, 22 Oct 2022 13:34:24 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail0.khirnov.net (red.khirnov.net [176.97.15.12]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 0FDF768BDAF for ; Sat, 22 Oct 2022 13:34:16 +0300 (EEST) Received: from localhost (localhost [IPv6:::1]) by mail0.khirnov.net (Postfix) with ESMTP id A93EC2404F5 for ; Sat, 22 Oct 2022 12:34:15 +0200 (CEST) Received: from mail0.khirnov.net ([IPv6:::1]) by localhost (mail0.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id Z0mb7hQDXwe9 for ; Sat, 22 Oct 2022 12:34:13 +0200 (CEST) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:2a00:c500:561:201::7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "libav.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail0.khirnov.net (Postfix) with ESMTPS id 3A6BD2404F7 for ; Sat, 22 Oct 2022 12:34:13 +0200 (CEST) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id 332353A13E9 for ; Sat, 22 Oct 2022 12:34:04 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 22 Oct 2022 12:32:57 +0200 Message-Id: <20221022103257.15463-4-anton@khirnov.net> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20221022103257.15463-1-anton@khirnov.net> References: <20221022103257.15463-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v4 4/4] lavc/get_bits: add a compat wrapper for the cached bitstream reader 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: jLDhkE0AJTYy Use that instead of the merged version. --- libavcodec/get_bits.h | 309 +++++++++--------------------------------- 1 file changed, 62 insertions(+), 247 deletions(-) diff --git a/libavcodec/get_bits.h b/libavcodec/get_bits.h index 992765dc92..a50469b427 100644 --- a/libavcodec/get_bits.h +++ b/libavcodec/get_bits.h @@ -1,6 +1,5 @@ /* * Copyright (c) 2004 Michael Niedermayer - * Copyright (c) 2016 Alexandra Hájková * * This file is part of FFmpeg. * @@ -58,12 +57,55 @@ #define CACHED_BITSTREAM_READER 0 #endif -typedef struct GetBitContext { - const uint8_t *buffer, *buffer_end; #if CACHED_BITSTREAM_READER - uint64_t cache; - unsigned bits_left; + +// we always want the LE implementation, to provide get_bits_le() +#define BITSTREAM_LE + +#ifndef BITSTREAM_READER_LE +# define BITSTREAM_BE +# define BITSTREAM_DEFAULT_BE #endif + +#include "bitstream.h" + +#undef BITSTREAM_LE +#undef BITSTREAM_BE +#undef BITSTREAM_DEFAULT_BE + +typedef BitstreamContext GetBitContext; + +#define get_bits_count bits_tell +#define get_bits_left bits_left +#define skip_bits_long bits_skip +#define skip_bits bits_skip +#define get_bits bits_read_nz +#define get_bitsz bits_read +#define get_bits_long bits_read +#define get_bits1 bits_read_bit +#define get_bits64 bits_read_64 +#define get_xbits bits_read_xbits +#define get_sbits bits_read_signed +#define get_sbits_long bits_read_signed +#define show_bits bits_peek +#define show_bits_long bits_peek +#define init_get_bits bits_init +#define init_get_bits8 bits_init8 +#define align_get_bits bits_align +#define get_vlc2 bits_read_vlc + +#define init_get_bits8_le(s, buffer, byte_size) bits_init8_le((BitstreamContextLE*)s, buffer, byte_size) +#define get_bits_le(s, n) bits_read_le((BitstreamContextLE*)s, n) + +#define show_bits1(s) bits_peek(s, 1) +#define skip_bits1(s) bits_skip(s, 1) + +#define skip_1stop_8data_bits bits_skip_1stop_8data + +#else // CACHED_BITSTREAM_READER + +typedef struct GetBitContext { + const uint8_t *buffer, *buffer_end; int index; int size_in_bits; int size_in_bits_plus8; @@ -120,16 +162,12 @@ static inline unsigned int show_bits(GetBitContext *s, int n); * For examples see get_bits, show_bits, skip_bits, get_vlc. */ -#if CACHED_BITSTREAM_READER -# define MIN_CACHE_BITS 64 -#elif defined LONG_BITSTREAM_READER +#if defined LONG_BITSTREAM_READER # define MIN_CACHE_BITS 32 #else # define MIN_CACHE_BITS 25 #endif -#if !CACHED_BITSTREAM_READER - #define OPEN_READER_NOSIZE(name, gb) \ unsigned int name ## _index = (gb)->index; \ unsigned int av_unused name ## _cache @@ -214,73 +252,12 @@ static inline unsigned int show_bits(GetBitContext *s, int n); #define GET_CACHE(name, gb) ((uint32_t) name ## _cache) -#endif static inline int get_bits_count(const GetBitContext *s) { -#if CACHED_BITSTREAM_READER - return s->index - s->bits_left; -#else return s->index; -#endif -} - -#if CACHED_BITSTREAM_READER -static inline void refill_32(GetBitContext *s, int is_le) -{ -#if !UNCHECKED_BITSTREAM_READER - if (s->index >> 3 >= s->buffer_end - s->buffer) - return; -#endif - - if (is_le) - s->cache = (uint64_t)AV_RL32(s->buffer + (s->index >> 3)) << s->bits_left | s->cache; - else - s->cache = s->cache | (uint64_t)AV_RB32(s->buffer + (s->index >> 3)) << (32 - s->bits_left); - s->index += 32; - s->bits_left += 32; -} - -static inline void refill_64(GetBitContext *s, int is_le) -{ -#if !UNCHECKED_BITSTREAM_READER - if (s->index >> 3 >= s->buffer_end - s->buffer) - return; -#endif - - if (is_le) - s->cache = AV_RL64(s->buffer + (s->index >> 3)); - else - s->cache = AV_RB64(s->buffer + (s->index >> 3)); - s->index += 64; - s->bits_left = 64; } -static inline uint64_t get_val(GetBitContext *s, unsigned n, int is_le) -{ - uint64_t ret; - av_assert2(n>0 && n<=63); - if (is_le) { - ret = s->cache & ((UINT64_C(1) << n) - 1); - s->cache >>= n; - } else { - ret = s->cache >> (64 - n); - s->cache <<= n; - } - s->bits_left -= n; - return ret; -} - -static inline unsigned show_val(const GetBitContext *s, unsigned n) -{ -#ifdef BITSTREAM_READER_LE - return s->cache & ((UINT64_C(1) << n) - 1); -#else - return s->cache >> (64 - n); -#endif -} -#endif - /** * Skips the specified number of bits. * @param n the number of bits to skip, @@ -290,28 +267,12 @@ static inline unsigned show_val(const GetBitContext *s, unsigned n) */ static inline void skip_bits_long(GetBitContext *s, int n) { -#if CACHED_BITSTREAM_READER - skip_bits(s, n); -#else #if UNCHECKED_BITSTREAM_READER s->index += n; #else s->index += av_clip(n, -s->index, s->size_in_bits_plus8 - s->index); #endif -#endif -} - -#if CACHED_BITSTREAM_READER -static inline void skip_remaining(GetBitContext *s, unsigned n) -{ -#ifdef BITSTREAM_READER_LE - s->cache >>= n; -#else - s->cache <<= n; -#endif - s->bits_left -= n; } -#endif /** * Read MPEG-1 dc-style VLC (sign bit + mantissa with no MSB). @@ -320,13 +281,6 @@ static inline void skip_remaining(GetBitContext *s, unsigned n) */ static inline int get_xbits(GetBitContext *s, int n) { -#if CACHED_BITSTREAM_READER - int32_t cache = show_bits(s, 32); - int sign = ~cache >> 31; - skip_remaining(s, n); - - return ((((uint32_t)(sign ^ cache)) >> (32 - n)) ^ sign) - sign; -#else register int sign; register int32_t cache; OPEN_READER(re, s); @@ -337,10 +291,8 @@ static inline int get_xbits(GetBitContext *s, int n) LAST_SKIP_BITS(re, s, n); CLOSE_READER(re, s); return (NEG_USR32(sign ^ cache, n) ^ sign) - sign; -#endif } -#if !CACHED_BITSTREAM_READER static inline int get_xbits_le(GetBitContext *s, int n) { register int sign; @@ -354,22 +306,16 @@ static inline int get_xbits_le(GetBitContext *s, int n) CLOSE_READER(re, s); return (zero_extend(sign ^ cache, n) ^ sign) - sign; } -#endif static inline int get_sbits(GetBitContext *s, int n) { register int tmp; -#if CACHED_BITSTREAM_READER - av_assert2(n>0 && n<=25); - tmp = sign_extend(get_bits(s, n), n); -#else OPEN_READER(re, s); av_assert2(n>0 && n<=25); UPDATE_CACHE(re, s); tmp = SHOW_SBITS(re, s, n); LAST_SKIP_BITS(re, s, n); CLOSE_READER(re, s); -#endif return tmp; } @@ -379,32 +325,12 @@ static inline int get_sbits(GetBitContext *s, int n) static inline unsigned int get_bits(GetBitContext *s, int n) { register unsigned int tmp; -#if CACHED_BITSTREAM_READER - - av_assert2(n>0 && n<=32); - if (n > s->bits_left) { -#ifdef BITSTREAM_READER_LE - refill_32(s, 1); -#else - refill_32(s, 0); -#endif - if (s->bits_left < 32) - s->bits_left = n; - } - -#ifdef BITSTREAM_READER_LE - tmp = get_val(s, n, 1); -#else - tmp = get_val(s, n, 0); -#endif -#else OPEN_READER(re, s); av_assert2(n>0 && n<=25); UPDATE_CACHE(re, s); tmp = SHOW_UBITS(re, s, n); LAST_SKIP_BITS(re, s, n); CLOSE_READER(re, s); -#endif av_assert2(tmp < UINT64_C(1) << n); return tmp; } @@ -419,16 +345,6 @@ static av_always_inline int get_bitsz(GetBitContext *s, int n) static inline unsigned int get_bits_le(GetBitContext *s, int n) { -#if CACHED_BITSTREAM_READER - av_assert2(n>0 && n<=32); - if (n > s->bits_left) { - refill_32(s, 1); - if (s->bits_left < 32) - s->bits_left = n; - } - - return get_val(s, n, 1); -#else register int tmp; OPEN_READER(re, s); av_assert2(n>0 && n<=25); @@ -437,7 +353,6 @@ static inline unsigned int get_bits_le(GetBitContext *s, int n) LAST_SKIP_BITS(re, s, n); CLOSE_READER(re, s); return tmp; -#endif } /** @@ -446,71 +361,22 @@ static inline unsigned int get_bits_le(GetBitContext *s, int n) static inline unsigned int show_bits(GetBitContext *s, int n) { register unsigned int tmp; -#if CACHED_BITSTREAM_READER - if (n > s->bits_left) -#ifdef BITSTREAM_READER_LE - refill_32(s, 1); -#else - refill_32(s, 0); -#endif - - tmp = show_val(s, n); -#else OPEN_READER_NOSIZE(re, s); av_assert2(n>0 && n<=25); UPDATE_CACHE(re, s); tmp = SHOW_UBITS(re, s, n); -#endif return tmp; } static inline void skip_bits(GetBitContext *s, int n) { -#if CACHED_BITSTREAM_READER - if (n < s->bits_left) - skip_remaining(s, n); - else { - n -= s->bits_left; - s->cache = 0; - s->bits_left = 0; - - if (n >= 64) { - unsigned skip = (n / 8) * 8; - - n -= skip; - s->index += skip; - } -#ifdef BITSTREAM_READER_LE - refill_64(s, 1); -#else - refill_64(s, 0); -#endif - if (n) - skip_remaining(s, n); - } -#else OPEN_READER(re, s); LAST_SKIP_BITS(re, s, n); CLOSE_READER(re, s); -#endif } static inline unsigned int get_bits1(GetBitContext *s) { -#if CACHED_BITSTREAM_READER - if (!s->bits_left) -#ifdef BITSTREAM_READER_LE - refill_64(s, 1); -#else - refill_64(s, 0); -#endif - -#ifdef BITSTREAM_READER_LE - return get_val(s, 1, 1); -#else - return get_val(s, 1, 0); -#endif -#else unsigned int index = s->index; uint8_t result = s->buffer[index >> 3]; #ifdef BITSTREAM_READER_LE @@ -527,7 +393,6 @@ static inline unsigned int get_bits1(GetBitContext *s) s->index = index; return result; -#endif } static inline unsigned int show_bits1(GetBitContext *s) @@ -548,10 +413,6 @@ static inline unsigned int get_bits_long(GetBitContext *s, int n) av_assert2(n>=0 && n<=32); if (!n) { return 0; -#if CACHED_BITSTREAM_READER - } - return get_bits(s, n); -#else } else if (n <= MIN_CACHE_BITS) { return get_bits(s, n); } else { @@ -563,7 +424,6 @@ static inline unsigned int get_bits_long(GetBitContext *s, int n) return ret | get_bits(s, n - 16); #endif } -#endif } /** @@ -609,8 +469,17 @@ static inline unsigned int show_bits_long(GetBitContext *s, int n) } } -static inline int init_get_bits_xe(GetBitContext *s, const uint8_t *buffer, - int bit_size, int is_le) + +/** + * Initialize GetBitContext. + * @param buffer bitstream buffer, must be AV_INPUT_BUFFER_PADDING_SIZE bytes + * larger than the actual read bits because some optimized bitstream + * readers read 32 or 64 bit at once and could read over the end + * @param bit_size the size of the buffer in bits + * @return 0 on success, AVERROR_INVALIDDATA if the buffer_size would overflow. + */ +static inline int init_get_bits(GetBitContext *s, const uint8_t *buffer, + int bit_size) { int buffer_size; int ret = 0; @@ -629,33 +498,9 @@ static inline int init_get_bits_xe(GetBitContext *s, const uint8_t *buffer, s->buffer_end = buffer + buffer_size; s->index = 0; -#if CACHED_BITSTREAM_READER - s->cache = 0; - s->bits_left = 0; - refill_64(s, is_le); -#endif - return ret; } -/** - * Initialize GetBitContext. - * @param buffer bitstream buffer, must be AV_INPUT_BUFFER_PADDING_SIZE bytes - * larger than the actual read bits because some optimized bitstream - * readers read 32 or 64 bit at once and could read over the end - * @param bit_size the size of the buffer in bits - * @return 0 on success, AVERROR_INVALIDDATA if the buffer_size would overflow. - */ -static inline int init_get_bits(GetBitContext *s, const uint8_t *buffer, - int bit_size) -{ -#ifdef BITSTREAM_READER_LE - return init_get_bits_xe(s, buffer, bit_size, 1); -#else - return init_get_bits_xe(s, buffer, bit_size, 0); -#endif -} - /** * Initialize GetBitContext. * @param buffer bitstream buffer, must be AV_INPUT_BUFFER_PADDING_SIZE bytes @@ -677,7 +522,7 @@ static inline int init_get_bits8_le(GetBitContext *s, const uint8_t *buffer, { if (byte_size > INT_MAX / 8 || byte_size < 0) byte_size = -1; - return init_get_bits_xe(s, buffer, byte_size * 8, 1); + return init_get_bits(s, buffer, byte_size * 8); } static inline const uint8_t *align_get_bits(GetBitContext *s) @@ -762,19 +607,6 @@ static inline const uint8_t *align_get_bits(GetBitContext *s) SKIP_BITS(name, gb, n); \ } while (0) -/* Return the LUT element for the given bitstream configuration. */ -static inline int set_idx(GetBitContext *s, int code, int *n, int *nb_bits, - const VLCElem *table) -{ - unsigned idx; - - *nb_bits = -*n; - idx = show_bits(s, *nb_bits) + code; - *n = table[idx].len; - - return table[idx].sym; -} - /** * Parse a vlc code. * @param bits is the number of bits which will be read at once, must be @@ -787,24 +619,6 @@ static inline int set_idx(GetBitContext *s, int code, int *n, int *nb_bits, static av_always_inline int get_vlc2(GetBitContext *s, const VLCElem *table, int bits, int max_depth) { -#if CACHED_BITSTREAM_READER - int nb_bits; - unsigned idx = show_bits(s, bits); - int code = table[idx].sym; - int n = table[idx].len; - - if (max_depth > 1 && n < 0) { - skip_remaining(s, bits); - code = set_idx(s, code, &n, &nb_bits, table); - if (max_depth > 2 && n < 0) { - skip_remaining(s, nb_bits); - code = set_idx(s, code, &n, &nb_bits, table); - } - } - skip_remaining(s, n); - - return code; -#else int code; OPEN_READER(re, s); @@ -815,7 +629,6 @@ static av_always_inline int get_vlc2(GetBitContext *s, const VLCElem *table, CLOSE_READER(re, s); return code; -#endif } static inline int decode012(GetBitContext *gb) @@ -855,4 +668,6 @@ static inline int skip_1stop_8data_bits(GetBitContext *gb) return 0; } +#endif // CACHED_BITSTREAM_READER + #endif /* AVCODEC_GET_BITS_H */