mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-24 06:50:20 +01:00
bitreaders: improve performance a bit for EALayer3
This commit is contained in:
parent
fa89dcc8a0
commit
e8643c333c
@ -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) {
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user