From 37d77b0820c19ea5519769d13a3e54ba88234c0e Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt Date: Sat, 8 Mar 2025 17:35:32 +0100 Subject: [PATCH 2/2] avcodec/put_bits: Add and use put_bits63() When using a 64bit PutBitContext (i.e. on x64), put_bits_no_assert() can naturally write up to 63 bits. So one can avoid treating the cases <32bits, 32 bits and <63 bits differently. As it turns out, no user actually wants to write 64 bit at once (maybe except testprograms). Signed-off-by: Andreas Rheinhardt --- libavcodec/dovi_rpuenc.c | 8 ++++---- libavcodec/put_bits.h | 29 ++++++++++++++++++++++------- libavcodec/put_golomb.h | 2 +- libavcodec/vc2enc.c | 2 +- libavformat/iamf_parse.c | 2 +- libavformat/iamf_writer.c | 2 +- 6 files changed, 30 insertions(+), 15 deletions(-) diff --git a/libavcodec/dovi_rpuenc.c b/libavcodec/dovi_rpuenc.c index eb79a3af5d..334b2c98a0 100644 --- a/libavcodec/dovi_rpuenc.c +++ b/libavcodec/dovi_rpuenc.c @@ -334,12 +334,12 @@ static inline void put_ue_coef(PutBitContext *pb, const AVDOVIRpuDataHeader *hdr switch (hdr->coef_data_type) { case RPU_COEFF_FIXED: set_ue_golomb(pb, coef >> hdr->coef_log2_denom); - put_bits64(pb, hdr->coef_log2_denom, + put_bits63(pb, hdr->coef_log2_denom, coef & ((1LL << hdr->coef_log2_denom) - 1)); break; case RPU_COEFF_FLOAT: fpart.f32 = coef / (float) (1LL << hdr->coef_log2_denom); - put_bits64(pb, hdr->coef_log2_denom, fpart.u32); + put_bits63(pb, hdr->coef_log2_denom, fpart.u32); break; } } @@ -352,12 +352,12 @@ static inline void put_se_coef(PutBitContext *pb, const AVDOVIRpuDataHeader *hdr switch (hdr->coef_data_type) { case RPU_COEFF_FIXED: set_se_golomb(pb, coef >> hdr->coef_log2_denom); - put_bits64(pb, hdr->coef_log2_denom, + put_bits63(pb, hdr->coef_log2_denom, coef & ((1LL << hdr->coef_log2_denom) - 1)); break; case RPU_COEFF_FLOAT: fpart.f32 = coef / (float) (1LL << hdr->coef_log2_denom); - put_bits64(pb, hdr->coef_log2_denom, fpart.u32); + put_bits63(pb, hdr->coef_log2_denom, fpart.u32); break; } } diff --git a/libavcodec/put_bits.h b/libavcodec/put_bits.h index 0caaa6b338..56c3f4cc6d 100644 --- a/libavcodec/put_bits.h +++ b/libavcodec/put_bits.h @@ -39,14 +39,14 @@ typedef uint64_t BitBuf; #define AV_WBBUF AV_WB64 #define AV_WLBUF AV_WL64 +#define BUF_BITS 64 #else typedef uint32_t BitBuf; #define AV_WBBUF AV_WB32 #define AV_WLBUF AV_WL32 +#define BUF_BITS 32 #endif -static const int BUF_BITS = 8 * sizeof(BitBuf); - typedef struct PutBitContext { BitBuf bit_buf; int bit_left; @@ -329,12 +329,15 @@ static void av_unused put_bits32(PutBitContext *s, uint32_t value) } /** - * Write up to 64 bits into a bitstream. + * Write up to 63 bits into a bitstream. */ -static inline void put_bits64(PutBitContext *s, int n, uint64_t value) +static inline void put_bits63(PutBitContext *s, int n, uint64_t value) { - av_assert2((n == 64) || (n < 64 && value < (UINT64_C(1) << n))); + av_assert2(n < 64U && value < (UINT64_C(1) << n)); +#if BUF_BITS >= 64 + put_bits_no_assert(s, n, value); +#else if (n < 32) put_bits(s, n, value); else if (n == 32) @@ -349,6 +352,19 @@ static inline void put_bits64(PutBitContext *s, int n, uint64_t value) put_bits(s, n - 32, hi); put_bits32(s, lo); #endif + } +#endif +} + +/** + * Write up to 64 bits into a bitstream. + */ +static inline void put_bits64(PutBitContext *s, int n, uint64_t value) +{ + av_assert2((n == 64) || (n < 64 && value < (UINT64_C(1) << n))); + + if (n < 64) { + put_bits63(s, n, value); } else { uint32_t lo = value & 0xffffffff; uint32_t hi = value >> 32; @@ -359,7 +375,6 @@ static inline void put_bits64(PutBitContext *s, int n, uint64_t value) put_bits32(s, hi); put_bits32(s, lo); #endif - } } @@ -367,7 +382,7 @@ static inline void put_sbits63(PutBitContext *pb, int n, int64_t value) { av_assert2(n >= 0 && n < 64); - put_bits64(pb, n, (uint64_t)(value) & (~(UINT64_MAX << n))); + put_bits63(pb, n, (uint64_t)(value) & (~(UINT64_MAX << n))); } /** diff --git a/libavcodec/put_golomb.h b/libavcodec/put_golomb.h index 43c1233fdb..91e7852a17 100644 --- a/libavcodec/put_golomb.h +++ b/libavcodec/put_golomb.h @@ -62,7 +62,7 @@ static inline void set_ue_golomb_long(PutBitContext *pb, uint32_t i) put_bits(pb, ff_ue_golomb_len[i], i + 1); else { int e = av_log2(i + 1); - put_bits64(pb, 2 * e + 1, i + 1); + put_bits63(pb, 2 * e + 1, i + 1); } } diff --git a/libavcodec/vc2enc.c b/libavcodec/vc2enc.c index 8e68d7a89d..20022f2205 100644 --- a/libavcodec/vc2enc.c +++ b/libavcodec/vc2enc.c @@ -201,7 +201,7 @@ static av_always_inline void put_vc2_ue_uint(PutBitContext *pb, uint32_t val) pbits |= 0x1; } - put_bits64(pb, bits*2 + 1, (pbits << 1) | 1); + put_bits63(pb, 2 * bits + 1, (pbits << 1) | 1); } static av_always_inline int count_vc2_ue_uint(uint32_t val) diff --git a/libavformat/iamf_parse.c b/libavformat/iamf_parse.c index db40ae37ab..abedfdb066 100644 --- a/libavformat/iamf_parse.c +++ b/libavformat/iamf_parse.c @@ -319,7 +319,7 @@ static int update_extradata(AVCodecParameters *codecpar) return ret; put_bits32(&pb, get_bits_long(&gb, 32)); // min/max blocksize - put_bits64(&pb, 48, get_bits64(&gb, 48)); // min/max framesize + put_bits63(&pb, 48, get_bits64(&gb, 48)); // min/max framesize put_bits(&pb, 20, get_bits(&gb, 20)); // samplerate skip_bits(&gb, 3); put_bits(&pb, 3, codecpar->ch_layout.nb_channels - 1); diff --git a/libavformat/iamf_writer.c b/libavformat/iamf_writer.c index 6b07dd85c9..acac6b87eb 100644 --- a/libavformat/iamf_writer.c +++ b/libavformat/iamf_writer.c @@ -59,7 +59,7 @@ static int update_extradata(IAMFCodecConfig *codec_config) return ret; put_bits32(&pb, get_bits_long(&gb, 32)); // min/max blocksize - put_bits64(&pb, 48, get_bits64(&gb, 48)); // min/max framesize + put_bits63(&pb, 48, get_bits64(&gb, 48)); // min/max framesize put_bits(&pb, 20, get_bits(&gb, 20)); // samplerate skip_bits(&gb, 3); put_bits(&pb, 3, 1); // set channels to stereo -- 2.45.2