Code cleanup after decoding optimization

This commit is contained in:
Grigory Chudov
2013-03-18 19:40:46 -04:00
parent b71868e235
commit 264d9b7637
2 changed files with 66 additions and 132 deletions

View File

@@ -742,7 +742,7 @@ namespace CUETools.Codecs.FLAKE
{ {
seek_table[e].number = (long)bitreader.readbits64(Flake.FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN); seek_table[e].number = (long)bitreader.readbits64(Flake.FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN);
seek_table[e].offset = (long)bitreader.readbits64(Flake.FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN); seek_table[e].offset = (long)bitreader.readbits64(Flake.FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN);
seek_table[e].framesize = (int)bitreader.readbits24(Flake.FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN); seek_table[e].framesize = (int)bitreader.readbits(Flake.FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN);
} }
} }
if (_framesBufferLength < 4 + len) if (_framesBufferLength < 4 + len)

View File

@@ -71,13 +71,14 @@ namespace CUETools.Codecs
#endregion #endregion
private byte* buffer_m; private byte* buffer_m;
private int buffer_offset_m, buffer_len_m; private byte* bptr_m;
private int bitaccumulator_m; private int buffer_len_m;
private uint cache_m; private int have_bits_m;
private ulong cache_m;
public int Position public int Position
{ {
get { return buffer_offset_m; } get { return (int)(bptr_m - buffer_m - (have_bits_m >> 3)); }
} }
public byte* Buffer public byte* Buffer
@@ -91,9 +92,9 @@ namespace CUETools.Codecs
public BitReader() public BitReader()
{ {
buffer_m = null; buffer_m = null;
buffer_offset_m = 0; bptr_m = null;
buffer_len_m = 0; buffer_len_m = 0;
bitaccumulator_m = 0; have_bits_m = 0;
cache_m = 0; cache_m = 0;
} }
@@ -105,124 +106,83 @@ namespace CUETools.Codecs
public void Reset(byte* _buffer, int _pos, int _len) public void Reset(byte* _buffer, int _pos, int _len)
{ {
buffer_m = _buffer; buffer_m = _buffer;
buffer_offset_m = _pos; bptr_m = _buffer + _pos;
buffer_len_m = _len; buffer_len_m = _len;
bitaccumulator_m = 0; have_bits_m = 0;
cache_m = peek4(); cache_m = 0;
fill();
} }
public uint peek4() public void fill()
{ {
//uint result = ((((uint)buffer[pos]) << 24) | (((uint)buffer[pos + 1]) << 16) | (((uint)buffer[pos + 2]) << 8) | ((uint)buffer[pos + 3])) << bitaccumulator_m; while (have_bits_m < 56)
byte* b = buffer_m + buffer_offset_m; {
uint result = *(b++); have_bits_m += 8;
result = (result << 8) + *(b++); cache_m |= (ulong)*(bptr_m++) << (64 - have_bits_m);
result = (result << 8) + *(b++); }
result = (result << 8) + *(b++); }
result <<= bitaccumulator_m;
return result;
}
/* skip any number of bits */ /* skip any number of bits */
public void skipbits(int bits) public void skipbits(int bits)
{ {
int new_accumulator = (bitaccumulator_m + bits); while (bits > have_bits_m)
buffer_offset_m += (new_accumulator >> 3); {
bitaccumulator_m = (new_accumulator & 7); bits -= have_bits_m;
cache_m = peek4(); cache_m = 0;
} have_bits_m = 0;
fill();
/* skip up to 16 bits */ }
public void skipbits16(int bits) cache_m <<= bits;
{ have_bits_m -= bits;
cache_m <<= bits;
int new_accumulator = (bitaccumulator_m + bits);
buffer_offset_m += (new_accumulator >> 3);
bitaccumulator_m = (new_accumulator & 7);
cache_m |= ((((uint)buffer_m[buffer_offset_m + 2] << 8) + (uint)buffer_m[buffer_offset_m + 3]) << bitaccumulator_m);
}
/* skip up to 8 bits */
public void skipbits8(int bits)
{
cache_m <<= bits;
int new_accumulator = (bitaccumulator_m + bits);
buffer_offset_m += (new_accumulator >> 3);
bitaccumulator_m = (new_accumulator & 7);
cache_m |= ((uint)buffer_m[buffer_offset_m + 3] << bitaccumulator_m);
}
/* supports reading 1 to 24 bits, in big endian format */
public uint readbits24(int bits)
{
//uint result = peek4() >> (32 - bits);
uint result = cache_m >> (32 - bits);
skipbits(bits);
return result;
}
public uint peekbits24(int bits)
{
return cache_m >> 32 - bits;
} }
/* supports reading 1 to 32 bits, in big endian format */ /* supports reading 1 to 32 bits, in big endian format */
public uint readbits(int bits) public uint readbits(int bits)
{ {
uint result = cache_m >> 32 - bits; fill();
if (bits <= 24) uint result = (uint)(cache_m >> 64 - bits);
{ skipbits(bits);
skipbits(bits); return result;
return result; }
}
skipbits(24);
result |= cache_m >> 56 - bits;
skipbits(bits - 24);
return result;
}
public ulong readbits64(int bits) /* supports reading 1 to 64 bits, in big endian format */
public ulong readbits64(int bits)
{ {
if (bits <= 24) if (bits <= 56)
return readbits24(bits); return readbits(bits);
ulong result = readbits24(24); return (readbits(32) << bits - 32) | readbits(bits - 32);
bits -= 24;
if (bits <= 24)
return (result << bits) | readbits24(bits);
result = (result << 24) | readbits24(24);
bits -= 24;
return (result << bits) | readbits24(bits);
} }
/* reads a single bit */ /* reads a single bit */
public uint readbit() public uint readbit()
{ {
uint result = cache_m >> 31; return readbits(1);
skipbits8(1);
return result;
} }
public uint read_unary() public uint read_unary()
{ {
uint val = 0; fill();
uint val = 0;
uint result = cache_m >> 24; ulong result = cache_m >> 56;
while (result == 0) while (result == 0)
{ {
val += 8; val += 8;
skipbits8(8); cache_m <<= 8;
result = cache_m >> 24; cache_m |= (ulong)*(bptr_m++) << (64 - have_bits_m);
result = cache_m >> 56;
} }
val += byte_to_unary_table[result]; val += byte_to_unary_table[result];
skipbits8((int)(val & 7) + 1); skipbits((int)(val & 7) + 1);
return val; return val;
} }
public void flush() public void flush()
{ {
if (bitaccumulator_m > 0) if ((have_bits_m & 7) > 0)
skipbits8(8 - bitaccumulator_m); {
cache_m <<= have_bits_m & 7;
have_bits_m -= have_bits_m & 7;
}
} }
public int readbits_signed(int bits) public int readbits_signed(int bits)
@@ -288,67 +248,41 @@ namespace CUETools.Codecs
return v; return v;
} }
public int read_rice_signed(int k)
{
uint msbs = read_unary();
uint lsbs = readbits24(k);
uint uval = (msbs << k) | lsbs;
return (int)(uval >> 1 ^ -(int)(uval & 1));
}
public int read_unary_signed()
{
uint uval = read_unary();
return (int)(uval >> 1 ^ -(int)(uval & 1));
}
public void read_rice_block(int n, int k, int* r) public void read_rice_block(int n, int k, int* r)
{ {
fill();
fixed (byte* unary_table = byte_to_unary_table) fixed (byte* unary_table = byte_to_unary_table)
{ {
uint mask = (1U << k) - 1; uint mask = (1U << k) - 1;
byte* bptr = &buffer_m[buffer_offset_m]; byte* bptr = bptr_m;
int have_bits = 24 - bitaccumulator_m; int have_bits = have_bits_m;
ulong _lcache = ((ulong)cache_m) << 32; ulong cache = cache_m;
bptr += 3;
for (int i = n; i > 0; i--) for (int i = n; i > 0; i--)
{ {
uint bits; uint bits;
byte* orig_bptr = bptr; byte* orig_bptr = bptr;
while ((bits = unary_table[_lcache >> 56]) == 8) while ((bits = unary_table[cache >> 56]) == 8)
{ {
_lcache <<= 8; cache <<= 8;
_lcache |= (ulong)*(bptr++) << (64 - have_bits); cache |= (ulong)*(bptr++) << (64 - have_bits);
} }
uint msbs = bits + ((uint)(bptr - orig_bptr) << 3); uint msbs = bits + ((uint)(bptr - orig_bptr) << 3);
// assumes k <= 41 (have_bits < 41 + 7 + 1 + 8 == 57, so we don't loose bits here) // assumes k <= 41 (have_bits < 41 + 7 + 1 + 8 == 57, so we don't loose bits here)
while (have_bits < 56) while (have_bits < 56)
{ {
have_bits += 8; have_bits += 8;
_lcache |= (ulong)*(bptr++) << (64 - have_bits); cache |= (ulong)*(bptr++) << (64 - have_bits);
} }
int btsk = k + (int)bits + 1; int btsk = k + (int)bits + 1;
uint uval = (msbs << k) | (uint)((_lcache >> (64 - btsk)) & mask); uint uval = (msbs << k) | (uint)((cache >> (64 - btsk)) & mask);
_lcache <<= btsk; cache <<= btsk;
have_bits -= btsk; have_bits -= btsk;
*(r++) = (int)(uval >> 1 ^ -(int)(uval & 1)); *(r++) = (int)(uval >> 1 ^ -(int)(uval & 1));
} }
while (have_bits <= 24) have_bits_m = have_bits;
{ cache_m = cache;
_lcache |= ((ulong)bptr[0] << 56) >> have_bits; bptr_m = bptr;
have_bits += 8;
bptr++;
}
while (have_bits > 32)
{
have_bits -= 8;
bptr--;
}
bitaccumulator_m = 32 - have_bits;
cache_m = (uint)(_lcache >> 32);
bptr -= 4;
buffer_offset_m = (int)(bptr - buffer_m);
} }
} }
} }