From patchwork Tue Apr 14 10:25:02 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christophe Gisquet X-Patchwork-Id: 18950 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id EAE5844B934 for ; Tue, 14 Apr 2020 13:25:24 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id D751A68B67A; Tue, 14 Apr 2020 13:25:24 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr1-f42.google.com (mail-wr1-f42.google.com [209.85.221.42]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id CFA1F68B4CC for ; Tue, 14 Apr 2020 13:25:14 +0300 (EEST) Received: by mail-wr1-f42.google.com with SMTP id h26so2270876wrb.7 for ; Tue, 14 Apr 2020 03:25:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=wEllzq1XN+WIqn2iqqxKy2ENO2YkSfTj6CiZd7jOMq0=; b=tUrXMQ5ghQ9mMQ3UH8G5ZwEJI5FV3WIUKsxitl0PgsyGwvBaqXZiToZtUaet95rjJa jQc4NnBGIhaEcoqHAsgEYFRy38lIKhUP6mac8SDbTpi7r24HCbi82YGcXbmrG7tBkYTm h+41QhQyNNwsNh2B1mDfkiIL7J+Nsfepfoor8tZBl88PZgS2/7r3d7ilGSSkveBxHl4E OhzyJsbvVM1cELC3IxXAcZ9wpLbX0qEvP2KaDwRBP5wR7inPID16a2Ya3g9oumFC/Dre w4Kne1vlAMI8wNRln5+P3vvJTD6McMy+I57UjRtdwnaRN8WbNTgkShdxq38ldas2GFAn IRMQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=wEllzq1XN+WIqn2iqqxKy2ENO2YkSfTj6CiZd7jOMq0=; b=U0BcC35cWjnRZDN14nz/sjAW5iskCu8dLtMTW0n4+0GChUe1VRMfoScwnXb9wKKJZn 9IZCBjWoO7GRFto7XZfTyeUMuKRuPGo4g1Btg90J7F0Frqn5u/GP+OVXpGYEulf6jC2v cMkcUQaNzY8aIaz7LVjX3vJ6v+G2pYhIawggIpZN0x0/gq/l2005JwJiYq/k8XkROgZD 1R2JeakI06wfNR+Yr7qlsdQR0E0+vNyjtAqUYp+VOTfcPpD8U41HOZdumGweeWFlnCPy gAOQhPjzOxSKpFW/RE7yXkcI15Dye3iCoptP5Firwjn67exzbTCb20YG12xB/xxVcCvI EsMQ== X-Gm-Message-State: AGi0Puag7MYGrjwYXYQnswxY+VyZhLmOS/6FO8ymV9J7+r1D9RTr9b3x ZRI7W1vD0wKZ47C6TfB/w981KMM= X-Google-Smtp-Source: APiQypLiKMIqoMSDDZB3EgaFC+oTY8XT9cQnOCaWPAKxnsivAA2PHfNxUsP8AcyQj3yr6uT/Dad2VQ== X-Received: by 2002:adf:ef51:: with SMTP id c17mr22762678wrp.130.1586859913945; Tue, 14 Apr 2020 03:25:13 -0700 (PDT) Received: from localhost.localdomain (2a01cb0881b29e00157b082460d14b2a.ipv6.abo.wanadoo.fr. [2a01:cb08:81b2:9e00:157b:824:60d1:4b2a]) by smtp.gmail.com with ESMTPSA id i17sm8574487wru.39.2020.04.14.03.25.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Apr 2020 03:25:13 -0700 (PDT) From: Christophe Gisquet To: ffmpeg-devel@ffmpeg.org Date: Tue, 14 Apr 2020 10:25:02 +0000 Message-Id: <20200414102503.7858-7-christophe.gisquet@gmail.com> X-Mailer: git-send-email 2.26.0 In-Reply-To: <20200414102503.7858-1-christophe.gisquet@gmail.com> References: <20200414102503.7858-1-christophe.gisquet@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 6/7] get_bits: change refill to RAD pattern X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 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" Described as variant 4 in the linked article. Results in faster and smaller code. Also, cases for the "refill_all" cases (usually when we want to empty/fill it) have been inlined. --- libavcodec/get_bits.h | 103 +++++++++++++++++------------------------- 1 file changed, 41 insertions(+), 62 deletions(-) diff --git a/libavcodec/get_bits.h b/libavcodec/get_bits.h index da054ebfcb..baff86ecf6 100644 --- a/libavcodec/get_bits.h +++ b/libavcodec/get_bits.h @@ -153,11 +153,7 @@ static inline unsigned int show_bits(GetBitContext *s, int n); */ #if CACHED_BITSTREAM_READER -# if BITSTREAM_BITS == 32 -# define MIN_CACHE_BITS (32-7) -# else -# define MIN_CACHE_BITS 32 -# endif +# define MIN_CACHE_BITS (BITSTREAM_BITS-7) #elif defined LONG_BITSTREAM_READER # define MIN_CACHE_BITS 32 #else @@ -262,46 +258,21 @@ static inline int get_bits_count(const GetBitContext *s) } #if CACHED_BITSTREAM_READER -static inline void refill_half(GetBitContext *s, int is_le) +// See variant 4 in the following article: +// https://fgiesen.wordpress.com/2018/02/20/reading-bits-in-far-too-many-ways-part-2/ +static inline void refill_gb(GetBitContext *s, int is_le) { #if !UNCHECKED_BITSTREAM_READER if (s->ptr >= s->buffer_end) return; #endif -#if BITSTREAM_BITS == 32 - if (s->bits_left > 16) { - if (is_le) - s->cache |= (uint32_t)s->ptr[0] << s->bits_left; - else - s->cache |= (uint32_t)s->ptr[0] << (32 - s->bits_left); - s->ptr++; - s->bits_left += 8; - return; - } -#endif - if (is_le) - s->cache |= (cache_type)AV_RL_HALF(s->ptr) << s->bits_left; + s->cache |= (cache_type)AV_RL_ALL(s->ptr) << s->bits_left; else - s->cache |= (cache_type)AV_RB_HALF(s->ptr) << (BITSTREAM_HBITS - s->bits_left); - s->ptr += sizeof(s->cache)/2; - s->bits_left += BITSTREAM_HBITS; -} - -static inline void refill_all(GetBitContext *s, int is_le) -{ -#if !UNCHECKED_BITSTREAM_READER - if (s->ptr >= s->buffer_end) - return; -#endif - - if (is_le) - s->cache = AV_RL_ALL(s->ptr); - else - s->cache = AV_RB_ALL(s->ptr); - s->ptr += sizeof(s->cache); - s->bits_left = BITSTREAM_BITS; + s->cache |= (cache_type)AV_RB_ALL(s->ptr) >> s->bits_left; + s->ptr += (BITSTREAM_BITS-1 - s->bits_left) >> 3; + s->bits_left |= BITSTREAM_BITS-8; } static inline cache_type get_val(GetBitContext *s, unsigned n, int is_le) @@ -374,9 +345,9 @@ static inline int get_xbits(GetBitContext *s, int n) if (n > s->bits_left) #ifdef BITSTREAM_READER_LE - refill_half(s, 1); + refill_gb(s, 1); #else - refill_half(s, 0); + refill_gb(s, 0); #endif #if BITSTREAM_BITS == 32 @@ -448,9 +419,9 @@ static inline unsigned int get_bits(GetBitContext *s, int n) av_assert2(n>0 && n<=32); if (n > s->bits_left) { #ifdef BITSTREAM_READER_LE - refill_half(s, 1); + refill_gb(s, 1); #else - refill_half(s, 0); + refill_gb(s, 0); #endif if (s->bits_left < BITSTREAM_HBITS) s->bits_left = n; @@ -486,7 +457,7 @@ 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_half(s, 1); + refill_gb(s, 1); if (s->bits_left < BITSTREAM_HBITS) s->bits_left = n; } @@ -513,9 +484,9 @@ static inline unsigned int show_bits(GetBitContext *s, int n) #if CACHED_BITSTREAM_READER if (n > s->bits_left) #ifdef BITSTREAM_READER_LE - refill_half(s, 1); + refill_gb(s, 1); #else - refill_half(s, 0); + refill_gb(s, 0); #endif tmp = show_val(s, n); @@ -535,7 +506,6 @@ static inline void skip_bits(GetBitContext *s, int n) skip_remaining(s, n); else { n -= s->bits_left; - s->cache = 0; if (n >= BITSTREAM_BITS) { unsigned skip = n / 8; @@ -543,11 +513,14 @@ static inline void skip_bits(GetBitContext *s, int n) n -= 8*skip; s->ptr += skip; } + #ifdef BITSTREAM_READER_LE - refill_all(s, 1); + s->cache = AV_RL_ALL(s->ptr); #else - refill_all(s, 0); + s->cache = AV_RB_ALL(s->ptr); #endif + s->ptr += sizeof(cache_type); + s->bits_left = BITSTREAM_BITS; if (n) skip_remaining(s, n); } @@ -561,12 +534,15 @@ static inline void skip_bits(GetBitContext *s, int n) static inline unsigned int get_bits1(GetBitContext *s) { #if CACHED_BITSTREAM_READER - if (!s->bits_left) + if (!s->bits_left) { #ifdef BITSTREAM_READER_LE - refill_all(s, 1); + s->cache = AV_RL_ALL(s->ptr); #else - refill_all(s, 0); + s->cache = AV_RB_ALL(s->ptr); #endif + s->ptr += sizeof(cache_type); + s->bits_left = BITSTREAM_BITS; + } #ifdef BITSTREAM_READER_LE return get_val(s, 1, 1); @@ -621,20 +597,21 @@ static inline unsigned int get_bits_long(GetBitContext *s, int n) if (n > s->bits_left) { n -= s->bits_left; # ifdef BITSTREAM_READER_LE - left = s->bits_left; - ret = get_val(s, s->bits_left, 1); - refill_all(s, 1); + ret = s->cache & ((CACHE_TYPE(1) << s->bits_left) - 1); + s->cache = AV_RL_ALL(s->ptr); # else - ret = get_val(s, s->bits_left, 0); - refill_all(s, 0); + ret = s->cache >> (BITSTREAM_BITS - s->bits_left); + s->cache = AV_RB_ALL(s->ptr); # endif + s->ptr += sizeof(cache_type); + s->bits_left = BITSTREAM_BITS; // OK because consumed right after } -#ifdef BITSTREAM_READER_LE +# ifdef BITSTREAM_READER_LE ret = get_val(s, n, 1) << left | ret; -#else +# else ret = get_val(s, n, 0) | ret << n; -#endif +# endif return ret; #else @@ -725,10 +702,12 @@ static inline int init_get_bits_xe(GetBitContext *s, const uint8_t *buffer, s->buffer_end = buffer + buffer_size; #if CACHED_BITSTREAM_READER - s->ptr = buffer; - s->cache = 0; - s->bits_left = 0; - refill_all(s, is_le); + if (is_le) + s->cache = AV_RL_ALL(buffer); + else + s->cache = AV_RB_ALL(buffer); + s->ptr = buffer+sizeof(cache_type); + s->bits_left = BITSTREAM_BITS; #else s->index = 0; #endif