* [FFmpeg-devel] [PATCH] avcodec/vc2enc: Simplify writing dirac golomb codes
@ 2025-03-08 15:28 Andreas Rheinhardt
2025-03-08 18:31 ` Andreas Rheinhardt
0 siblings, 1 reply; 2+ messages in thread
From: Andreas Rheinhardt @ 2025-03-08 15:28 UTC (permalink / raw)
To: FFmpeg development discussions and patches
[-- Attachment #1: Type: text/plain, Size: 27 bytes --]
Patch attached.
- Andreas
[-- Attachment #2: 0001-avcodec-vc2enc-Simplify-writing-dirac-golomb-codes.patch --]
[-- Type: text/x-patch, Size: 1954 bytes --]
From 4e50b2adb6de16754b629eaf18fc92d67ecdf1ca Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Sat, 8 Mar 2025 15:45:24 +0100
Subject: [PATCH] avcodec/vc2enc: Simplify writing dirac golomb codes
The earlier code used a loop to determine the number of bits used
and called ff_log2() on a power of two (and it would be easy to
keep track of the exponent of said power-of-two); neither GCC nor
Clang optimized the loop away or avoided the ff_log2().
This patch replaces the loop and the log2 with a single av_log2().
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
libavcodec/vc2enc.c | 30 +++---------------------------
1 file changed, 3 insertions(+), 27 deletions(-)
diff --git a/libavcodec/vc2enc.c b/libavcodec/vc2enc.c
index b82370a753..8e68d7a89d 100644
--- a/libavcodec/vc2enc.c
+++ b/libavcodec/vc2enc.c
@@ -189,23 +189,10 @@ typedef struct VC2EncContext {
static av_always_inline void put_vc2_ue_uint(PutBitContext *pb, uint32_t val)
{
int i;
- int bits = 0;
- unsigned topbit = 1, maxval = 1;
+ int bits = av_log2(++val);
+ unsigned topbit = 1 << bits;
uint64_t pbits = 0;
- if (!val++) {
- put_bits(pb, 1, 1);
- return;
- }
-
- while (val > maxval) {
- topbit <<= 1;
- maxval <<= 1;
- maxval |= 1;
- }
-
- bits = ff_log2(topbit);
-
for (i = 0; i < bits; i++) {
topbit >>= 1;
av_assert2(pbits <= UINT64_MAX>>3);
@@ -219,18 +206,7 @@ static av_always_inline void put_vc2_ue_uint(PutBitContext *pb, uint32_t val)
static av_always_inline int count_vc2_ue_uint(uint32_t val)
{
- int topbit = 1, maxval = 1;
-
- if (!val++)
- return 1;
-
- while (val > maxval) {
- topbit <<= 1;
- maxval <<= 1;
- maxval |= 1;
- }
-
- return ff_log2(topbit)*2 + 1;
+ return 2 * av_log2(val + 1) + 1;
}
/* VC-2 10.4 - parse_info() */
--
2.45.2
[-- Attachment #3: Type: text/plain, Size: 251 bytes --]
_______________________________________________
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".
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [FFmpeg-devel] [PATCH] avcodec/vc2enc: Simplify writing dirac golomb codes
2025-03-08 15:28 [FFmpeg-devel] [PATCH] avcodec/vc2enc: Simplify writing dirac golomb codes Andreas Rheinhardt
@ 2025-03-08 18:31 ` Andreas Rheinhardt
0 siblings, 0 replies; 2+ messages in thread
From: Andreas Rheinhardt @ 2025-03-08 18:31 UTC (permalink / raw)
To: ffmpeg-devel
[-- Attachment #1: Type: text/plain, Size: 91 bytes --]
Andreas Rheinhardt:
> Patch attached.
>
> - Andreas
>
Another patch attached
- Andreas
[-- Attachment #2: 0002-avcodec-put_bits-Add-and-use-put_bits63.patch --]
[-- Type: text/x-patch, Size: 6549 bytes --]
From 37d77b0820c19ea5519769d13a3e54ba88234c0e Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
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 <andreas.rheinhardt@outlook.com>
---
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
[-- Attachment #3: Type: text/plain, Size: 251 bytes --]
_______________________________________________
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".
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2025-03-08 18:31 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-03-08 15:28 [FFmpeg-devel] [PATCH] avcodec/vc2enc: Simplify writing dirac golomb codes Andreas Rheinhardt
2025-03-08 18:31 ` Andreas Rheinhardt
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