bitreaders: improve performance a bit for EALayer3

This commit is contained in:
bnnm 2023-11-26 20:59:09 +01:00
parent fa89dcc8a0
commit e8643c333c
2 changed files with 27 additions and 17 deletions

View File

@ -1,10 +1,11 @@
#ifndef _BITSTREAM_LSB_H #ifndef _BITSTREAM_LSB_H
#define _BITSTREAM_LSB_H #define _BITSTREAM_LSB_H
#include "../streamtypes.h" #include <stdint.h>
/* Simple bitreader for Vorbis' bit style, in 'least significant byte' (LSB) format. /* Simple bitreader for Vorbis' bit style, in 'least significant byte' (LSB) format.
* Example: 0x12345678 is read as 12,34,56,78 (continuous). * Example: with 0x1234 = 00010010 00110100, reading 5b + 6b = 10010 100000
* (first lower 5b, then next upper 3b and next lower 3b = 6b)
* Kept in .h since it's slightly faster (compiler can optimize statics better using default compile flags). */ * Kept in .h since it's slightly faster (compiler can optimize statics better using default compile flags). */
@ -23,7 +24,7 @@ static inline void bl_setup(bitstream_t* b, uint8_t* buf, size_t bufsize) {
/* same as (1 << bits) - 1, but that seems to trigger some nasty UB when bits = 32 /* same as (1 << bits) - 1, but that seems to trigger some nasty UB when bits = 32
* (though in theory (1 << 32) = 0, 0 - 1 = UINT_MAX, but gives 0 compiling in some cases, but not always) */ * (though in theory (1 << 32) = 0, 0 - 1 = UINT_MAX, but gives 0 compiling in some cases, but not always) */
static const uint32_t MASK_TABLE[33] = { static const uint32_t MASK_TABLE_LSB[33] = {
0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff, 0x0001ffff, 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff, 0x0001ffff,
0x0003ffff, 0x0007ffff, 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x0003ffff, 0x0007ffff, 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff, 0x01ffffff, 0x03ffffff,
@ -40,7 +41,7 @@ static inline int bl_get(bitstream_t* ib, uint32_t bits, uint32_t* value) {
pos = ib->b_off / 8; /* byte offset */ pos = ib->b_off / 8; /* byte offset */
shift = ib->b_off % 8; /* bit sub-offset */ shift = ib->b_off % 8; /* bit sub-offset */
mask = MASK_TABLE[bits]; /* to remove upper in highest byte */ mask = MASK_TABLE_LSB[bits]; /* to remove upper in highest byte */
val = ib->buf[pos+0] >> shift; val = ib->buf[pos+0] >> shift;
if (bits + shift > 8) { if (bits + shift > 8) {

View File

@ -1,10 +1,11 @@
#ifndef _BITSTREAM_MSB_H #ifndef _BITSTREAM_MSB_H
#define _BITSTREAM_MSB_H #define _BITSTREAM_MSB_H
#include "../streamtypes.h" #include <stdint.h>
/* Simple bitreader for MPEG/standard bit style, in 'most significant byte' (MSB) format. /* Simple bitreader for MPEG/standard bit style, in 'most significant byte' (MSB) format.
* Example: 0x12345678 is read as 78,56,34,12 then each byte's bits. * Example: with 0x1234 = 00010010 00110100, reading 5b + 6b = 00010 010001
* (first upper 5b, then next lower 3b and next upper 3b = 6b)
* Kept in .h since it's slightly faster (compiler can optimize statics better using default compile flags). */ * Kept in .h since it's slightly faster (compiler can optimize statics better using default compile flags). */
typedef struct { typedef struct {
@ -14,7 +15,7 @@ typedef struct {
uint32_t b_off; /* current offset in bits inside buffer */ uint32_t b_off; /* current offset in bits inside buffer */
} bitstream_t; } bitstream_t;
/* convenience util */
static inline void bm_setup(bitstream_t* bs, uint8_t* buf, size_t bufsize) { static inline void bm_setup(bitstream_t* bs, uint8_t* buf, size_t bufsize) {
bs->buf = buf; bs->buf = buf;
bs->bufsize = bufsize; bs->bufsize = bufsize;
@ -60,10 +61,20 @@ static inline int bm_pos(bitstream_t* bs) {
return bs->b_off; return bs->b_off;
} }
/* same as (1 << bits) - 1, but that seems to trigger some nasty UB when bits = 32
* (though in theory (1 << 32) = 0, 0 - 1 = UINT_MAX, but gives 0 compiling in some cases, but not always) */
static const uint32_t MASK_TABLE_MSB[33] = {
0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff, 0x0001ffff,
0x0003ffff, 0x0007ffff, 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff, 0x01ffffff, 0x03ffffff,
0x07ffffff, 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff
};
/* Read bits (max 32) from buf and update the bit offset. Order is BE (MSB). */ /* Read bits (max 32) from buf and update the bit offset. Order is BE (MSB). */
static inline int bm_get(bitstream_t* ib, uint32_t bits, uint32_t* value) { static inline int bm_get(bitstream_t* ib, uint32_t bits, uint32_t* value) {
uint32_t shift, pos, val; uint32_t shift, pos, mask;
int i, bit_buf, bit_val; uint64_t val; //TODO: could use u32 with some shift fiddling
int i, bit_buf, bit_val, left;
if (bits > 32 || ib->b_off + bits > ib->b_max) if (bits > 32 || ib->b_off + bits > ib->b_max)
goto fail; goto fail;
@ -71,7 +82,7 @@ static inline int bm_get(bitstream_t* ib, uint32_t bits, uint32_t* value) {
pos = ib->b_off / 8; /* byte offset */ pos = ib->b_off / 8; /* byte offset */
shift = ib->b_off % 8; /* bit sub-offset */ shift = ib->b_off % 8; /* bit sub-offset */
#if 1 //naive approach #if 0 //naive approach
val = 0; val = 0;
for (i = 0; i < bits; i++) { for (i = 0; i < bits; i++) {
bit_buf = (1U << (8-1-shift)) & 0xFF; /* bit check for buf */ bit_buf = (1U << (8-1-shift)) & 0xFF; /* bit check for buf */
@ -86,12 +97,10 @@ static inline int bm_get(bitstream_t* ib, uint32_t bits, uint32_t* value) {
pos++; pos++;
} }
} }
#else //has bugs #else
pos = ib->b_off / 8; /* byte offset */ mask = MASK_TABLE_MSB[bits]; /* to remove upper in highest byte */
shift = ib->b_off % 8; /* bit sub-offset */
uint32_t mask = MASK_TABLE[bits]; /* to remove upper in highest byte */
int left = 0; left = 0;
if (bits == 0) if (bits == 0)
val = 0; val = 0;
else else
@ -102,12 +111,12 @@ static inline int bm_get(bitstream_t* ib, uint32_t bits, uint32_t* value) {
left = 16 - (bits + shift); left = 16 - (bits + shift);
if (bits + shift > 16) { if (bits + shift > 16) {
val = (val << 8u) | ib->buf[pos+2]; val = (val << 8u) | ib->buf[pos+2];
left = 32 - (bits + shift); left = 24 - (bits + shift);
if (bits + shift > 24) { if (bits + shift > 24) {
val = (val << 8u) | ib->buf[pos+3]; val = (val << 8u) | ib->buf[pos+3];
left = 32 - (bits + shift); left = 32 - (bits + shift);
if (bits + shift > 32) { if (bits + shift > 32) {
val = (val << 8u) | ib->buf[pos+4]; /* upper bits are lost (shifting over 32) */ TO-DO val = (val << 8u) | ib->buf[pos+4];
left = 40 - (bits + shift); left = 40 - (bits + shift);
} }
} }