forked from len0rd/rockbox
Commit FS#9015. Rework of musepack buffered seek. Now a static seek buffer of 8192 entries is used. The seeking precision is adapted to the length of the file (e.g. 26ms for files <=3.5min and 0.4s for files ~60min).
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17604 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
5f8bd63cba
commit
6a74a5dd3b
2 changed files with 77 additions and 119 deletions
|
@ -49,7 +49,7 @@
|
||||||
enum {
|
enum {
|
||||||
MPC_V_MEM = 2304,
|
MPC_V_MEM = 2304,
|
||||||
MPC_DECODER_MEMSIZE = 16384, // overall buffer size (words)
|
MPC_DECODER_MEMSIZE = 16384, // overall buffer size (words)
|
||||||
MPC_SEEK_BUFFER_SIZE = 65536, // seek buffer size (words)
|
MPC_SEEK_BUFFER_SIZE = 8192, // seek buffer size (words)
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -78,9 +78,6 @@ typedef struct mpc_decoder_t {
|
||||||
|
|
||||||
mpc_uint32_t DecodedFrames;
|
mpc_uint32_t DecodedFrames;
|
||||||
mpc_uint32_t OverallFrames;
|
mpc_uint32_t OverallFrames;
|
||||||
mpc_uint32_t MaxDecodedFrames; // Maximum frames decoded (indicates usable seek table entries)
|
|
||||||
mpc_uint16_t SeekTableIndex;
|
|
||||||
mpc_uint32_t SeekTableCounter;
|
|
||||||
mpc_int32_t SampleRate; // Sample frequency
|
mpc_int32_t SampleRate; // Sample frequency
|
||||||
|
|
||||||
mpc_uint32_t StreamVersion; // version of bitstream
|
mpc_uint32_t StreamVersion; // version of bitstream
|
||||||
|
@ -110,8 +107,10 @@ typedef struct mpc_decoder_t {
|
||||||
mpc_int8_t SCFI_R [32]; // describes order of transmitted SCF
|
mpc_int8_t SCFI_R [32]; // describes order of transmitted SCF
|
||||||
mpc_bool_t MS_Flag[32]; // MS used?
|
mpc_bool_t MS_Flag[32]; // MS used?
|
||||||
|
|
||||||
mpc_uint32_t* SeekTable;
|
mpc_uint32_t SeekTableCounter; // used to sum up skip info, if SeekTable_Step != 1
|
||||||
mpc_uint8_t SeekTable_Step;
|
mpc_uint32_t MaxDecodedFrames; // Maximum frames decoded (indicates usable seek table entries)
|
||||||
|
mpc_uint32_t* SeekTable; // seek table itself
|
||||||
|
mpc_uint8_t SeekTable_Step; // frames per seek table index
|
||||||
|
|
||||||
#ifdef MPC_FIXED_POINT
|
#ifdef MPC_FIXED_POINT
|
||||||
mpc_uint8_t SCF_shift[256];
|
mpc_uint8_t SCF_shift[256];
|
||||||
|
|
|
@ -393,7 +393,6 @@ mpc_decoder_reset_globals(mpc_decoder *d)
|
||||||
mpc_decoder_reset_bitstream_decode(d);
|
mpc_decoder_reset_bitstream_decode(d);
|
||||||
|
|
||||||
d->DecodedFrames = 0;
|
d->DecodedFrames = 0;
|
||||||
d->SeekTableIndex = 0;
|
|
||||||
d->MaxDecodedFrames = 0;
|
d->MaxDecodedFrames = 0;
|
||||||
d->StreamVersion = 0;
|
d->StreamVersion = 0;
|
||||||
d->MS_used = 0;
|
d->MS_used = 0;
|
||||||
|
@ -470,7 +469,10 @@ mpc_decoder_decode_internal(mpc_decoder *d, MPC_SAMPLE_FORMAT *buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d->DecodedFrames == 0)
|
if (d->DecodedFrames == 0)
|
||||||
|
{
|
||||||
d->SeekTable[0] = mpc_decoder_bits_read(d);
|
d->SeekTable[0] = mpc_decoder_bits_read(d);
|
||||||
|
d->SeekTableCounter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// read jump-info for validity check of frame
|
// read jump-info for validity check of frame
|
||||||
d->FwdJumpInfo = mpc_decoder_bitstream_read(d, 20);
|
d->FwdJumpInfo = mpc_decoder_bitstream_read(d, 20);
|
||||||
|
@ -499,15 +501,12 @@ mpc_decoder_decode_internal(mpc_decoder *d, MPC_SAMPLE_FORMAT *buffer)
|
||||||
d->DecodedFrames++;
|
d->DecodedFrames++;
|
||||||
|
|
||||||
/* update seek table */
|
/* update seek table */
|
||||||
if (d->SeekTable_Step == 1) {
|
|
||||||
d->SeekTable [d->DecodedFrames] = d->FwdJumpInfo + 20;
|
|
||||||
} else {
|
|
||||||
if ((d->DecodedFrames-1) % d->SeekTable_Step == 0) {
|
|
||||||
d->SeekTable[d->SeekTableIndex] = d->SeekTableCounter;
|
|
||||||
d->SeekTableIndex += 1;
|
|
||||||
d->SeekTableCounter = 0;
|
|
||||||
}
|
|
||||||
d->SeekTableCounter += d->FwdJumpInfo + 20;
|
d->SeekTableCounter += d->FwdJumpInfo + 20;
|
||||||
|
if (0 == (d->DecodedFrames % d->SeekTable_Step))
|
||||||
|
{
|
||||||
|
d->SeekTable[d->DecodedFrames/d->SeekTable_Step] = d->SeekTableCounter;
|
||||||
|
d->MaxDecodedFrames = d->DecodedFrames;
|
||||||
|
d->SeekTableCounter = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// synthesize signal
|
// synthesize signal
|
||||||
|
@ -1436,9 +1435,7 @@ void mpc_decoder_setup(mpc_decoder *d, mpc_reader *r)
|
||||||
d->Ring = 0;
|
d->Ring = 0;
|
||||||
d->WordsRead = 0;
|
d->WordsRead = 0;
|
||||||
d->Max_Band = 0;
|
d->Max_Band = 0;
|
||||||
d->SeekTable = NULL;
|
|
||||||
d->SeekTable_Step = 1;
|
d->SeekTable_Step = 1;
|
||||||
d->SeekTableIndex = 0;
|
|
||||||
d->SeekTableCounter = 0;
|
d->SeekTableCounter = 0;
|
||||||
|
|
||||||
mpc_decoder_initialisiere_quantisierungstabellen(d, 1.0f);
|
mpc_decoder_initialisiere_quantisierungstabellen(d, 1.0f);
|
||||||
|
@ -1488,10 +1485,10 @@ static void mpc_decoder_set_streaminfo(mpc_decoder *d, mpc_streaminfo *si)
|
||||||
|
|
||||||
memset(d->SeekTable, 0, sizeof(Seekbuffer));
|
memset(d->SeekTable, 0, sizeof(Seekbuffer));
|
||||||
|
|
||||||
|
// limit used table size to MPC_SEEK_BUFFER_SIZE
|
||||||
seekTableSize = min(si->frames, MPC_SEEK_BUFFER_SIZE);
|
seekTableSize = min(si->frames, MPC_SEEK_BUFFER_SIZE);
|
||||||
d->SeekTable_Step = si->frames / seekTableSize;
|
// frames per buffer to not exceed buffer and to be able to seek full file
|
||||||
if (si->frames % seekTableSize)
|
d->SeekTable_Step = (si->frames + seekTableSize - 1) / seekTableSize;
|
||||||
d->SeekTable_Step+=1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mpc_bool_t mpc_decoder_initialize(mpc_decoder *d, mpc_streaminfo *si)
|
mpc_bool_t mpc_decoder_initialize(mpc_decoder *d, mpc_streaminfo *si)
|
||||||
|
@ -1599,15 +1596,11 @@ mpc_bool_t mpc_decoder_seek_sample(mpc_decoder *d, mpc_int64_t destsample)
|
||||||
// seek direction (note: avoids casting to int64)
|
// seek direction (note: avoids casting to int64)
|
||||||
delta = (d->DecodedFrames > seekFrame ? -(mpc_int32_t)(d->DecodedFrames - seekFrame) : (mpc_int32_t)(seekFrame - d->DecodedFrames));
|
delta = (d->DecodedFrames > seekFrame ? -(mpc_int32_t)(d->DecodedFrames - seekFrame) : (mpc_int32_t)(seekFrame - d->DecodedFrames));
|
||||||
|
|
||||||
// update max decoded frames
|
|
||||||
if (d->DecodedFrames > d->MaxDecodedFrames)
|
|
||||||
d->MaxDecodedFrames = d->DecodedFrames;
|
|
||||||
|
|
||||||
if (seekFrame > 33)
|
if (seekFrame > 33)
|
||||||
lastFrame = seekFrame - 33 + 1 - d->SeekTable_Step;
|
lastFrame = seekFrame - 33 + 1 - d->SeekTable_Step;
|
||||||
|
|
||||||
if (d->MaxDecodedFrames == 0) {
|
if (d->MaxDecodedFrames == 0) // nothing decoded yet, parse stream
|
||||||
|
{
|
||||||
mpc_decoder_reset_state(d);
|
mpc_decoder_reset_state(d);
|
||||||
|
|
||||||
// starts from the beginning since no frames have been decoded yet, or not using seek table
|
// starts from the beginning since no frames have been decoded yet, or not using seek table
|
||||||
|
@ -1619,97 +1612,82 @@ mpc_bool_t mpc_decoder_seek_sample(mpc_decoder *d, mpc_int64_t destsample)
|
||||||
// reset number of decoded frames
|
// reset number of decoded frames
|
||||||
d->DecodedFrames = 0;
|
d->DecodedFrames = 0;
|
||||||
|
|
||||||
// jump to the last frame, updating seek table
|
// jump to the last frame via parsing, updating seek table
|
||||||
if (d->SeekTable_Step == 1) {
|
|
||||||
d->SeekTable[0] = (mpc_uint32_t)fpos;
|
d->SeekTable[0] = (mpc_uint32_t)fpos;
|
||||||
for (;d->DecodedFrames < lastFrame; d->DecodedFrames++)
|
d->SeekTableCounter = d->SeekTable[0];
|
||||||
d->SeekTable[d->DecodedFrames+1] = mpc_decoder_jump_frame(d);
|
for (d->DecodedFrames = 1; d->DecodedFrames < lastFrame; d->DecodedFrames++)
|
||||||
} else {
|
{
|
||||||
d->SeekTableIndex = 0;
|
d->SeekTableCounter += mpc_decoder_jump_frame(d);
|
||||||
d->SeekTableCounter = (mpc_uint32_t)fpos;
|
if (0 == (d->DecodedFrames % d->SeekTable_Step))
|
||||||
for (;d->DecodedFrames < lastFrame; d->DecodedFrames++) {
|
{
|
||||||
if (d->DecodedFrames % d->SeekTable_Step == 0) {
|
d->SeekTable[d->DecodedFrames/d->SeekTable_Step] = d->SeekTableCounter;
|
||||||
d->SeekTable[d->SeekTableIndex] = d->SeekTableCounter;
|
d->MaxDecodedFrames = d->DecodedFrames;
|
||||||
d->SeekTableIndex += 1;
|
|
||||||
d->SeekTableCounter = 0;
|
d->SeekTableCounter = 0;
|
||||||
}
|
}
|
||||||
d->SeekTableCounter += mpc_decoder_jump_frame(d);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (delta < 0) // jump backwards, seek table is already available
|
||||||
|
{
|
||||||
} else if (delta < 0) {
|
|
||||||
|
|
||||||
mpc_decoder_reset_state(d);
|
mpc_decoder_reset_state(d);
|
||||||
|
|
||||||
// jumps backwards using the seek table
|
// jumps backwards using the seek table
|
||||||
fpos = d->SeekTable[0];
|
fpos = d->SeekTable[0];
|
||||||
if (d->SeekTable_Step == 1) {
|
|
||||||
for (d->DecodedFrames = 0; d->DecodedFrames < lastFrame; d->DecodedFrames++)
|
for (d->DecodedFrames = 0; d->DecodedFrames < lastFrame; d->DecodedFrames++)
|
||||||
fpos += d->SeekTable[d->DecodedFrames+1];
|
{
|
||||||
} else {
|
if (0 == (d->DecodedFrames+1) % d->SeekTable_Step)
|
||||||
d->SeekTableIndex = 0;
|
{
|
||||||
//d->SeekTableCounter = 0;
|
fpos += d->SeekTable[(d->DecodedFrames+1)/d->SeekTable_Step];
|
||||||
for (d->DecodedFrames = 0;d->DecodedFrames < lastFrame; d->DecodedFrames+=d->SeekTable_Step, d->SeekTableIndex++)
|
|
||||||
fpos += d->SeekTable[d->SeekTableIndex+1];
|
|
||||||
d->SeekTableCounter = d->SeekTable[d->SeekTableIndex];
|
|
||||||
}
|
|
||||||
mpc_decoder_seek_to(d, fpos);
|
|
||||||
|
|
||||||
} else if (delta > 33) {
|
|
||||||
|
|
||||||
mpc_decoder_reset_state(d);
|
|
||||||
|
|
||||||
// jumps forward from the current position
|
|
||||||
if (d->MaxDecodedFrames > lastFrame) { // REVIEW: Correct?? or (d->MaxDecodedFrames > d->DecodedFrames)
|
|
||||||
// jump to the last usable position in the seek table
|
|
||||||
if (d->SeekTable_Step == 1) {
|
|
||||||
fpos = mpc_decoder_bits_read(d);
|
|
||||||
for (; d->DecodedFrames < d->MaxDecodedFrames && d->DecodedFrames < lastFrame; d->DecodedFrames++)
|
|
||||||
fpos += d->SeekTable[d->DecodedFrames+1];
|
|
||||||
} else {
|
|
||||||
// could test SeekTable offset and jump to next entry but this is easier for now...
|
|
||||||
//d->SeekTableIndex = 0;
|
|
||||||
//d->SeekTableCounter = 0;
|
|
||||||
fpos = d->SeekTable[0];
|
|
||||||
d->SeekTableIndex = 0;
|
|
||||||
for (d->DecodedFrames = 0;d->DecodedFrames < d->MaxDecodedFrames && d->DecodedFrames < lastFrame; d->DecodedFrames+=d->SeekTable_Step, d->SeekTableIndex++)
|
|
||||||
fpos += d->SeekTable[d->SeekTableIndex+1];
|
|
||||||
d->SeekTableCounter = d->SeekTable[d->SeekTableIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
mpc_decoder_seek_to(d, fpos);
|
|
||||||
}
|
|
||||||
if (d->SeekTable_Step == 1) {
|
|
||||||
for (;d->DecodedFrames < lastFrame; d->DecodedFrames++)
|
|
||||||
d->SeekTable[d->DecodedFrames+1] = mpc_decoder_jump_frame(d);
|
|
||||||
} else {
|
|
||||||
for (;d->DecodedFrames < lastFrame; d->DecodedFrames++) {
|
|
||||||
if (d->DecodedFrames % d->SeekTable_Step == 0) {
|
|
||||||
d->SeekTable[d->SeekTableIndex] = d->SeekTableCounter;
|
|
||||||
d->SeekTableIndex += 1;
|
|
||||||
d->SeekTableCounter = 0;
|
d->SeekTableCounter = 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
mpc_decoder_seek_to(d, fpos);
|
||||||
|
}
|
||||||
|
else if (delta > 33) // jump forward, seek table is available
|
||||||
|
{
|
||||||
|
mpc_decoder_reset_state(d);
|
||||||
|
|
||||||
|
// 1st loop: jump to the last usable position in the seek table
|
||||||
|
fpos = mpc_decoder_bits_read(d);
|
||||||
|
for (; d->DecodedFrames < d->MaxDecodedFrames && d->DecodedFrames < lastFrame; d->DecodedFrames++)
|
||||||
|
{
|
||||||
|
if (0 == (d->DecodedFrames+1) % d->SeekTable_Step)
|
||||||
|
{
|
||||||
|
fpos += d->SeekTable[(d->DecodedFrames+1)/d->SeekTable_Step];
|
||||||
|
d->SeekTableCounter = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mpc_decoder_seek_to(d, fpos);
|
||||||
|
|
||||||
|
// 2nd loop: jump the residual frames via parsing, update seek table
|
||||||
|
for (;d->DecodedFrames < lastFrame; d->DecodedFrames++)
|
||||||
|
{
|
||||||
d->SeekTableCounter += mpc_decoder_jump_frame(d);
|
d->SeekTableCounter += mpc_decoder_jump_frame(d);
|
||||||
|
if (0 == (d->DecodedFrames+1) % d->SeekTable_Step)
|
||||||
|
{
|
||||||
|
d->SeekTable[(d->DecodedFrames+1)/d->SeekTable_Step] = d->SeekTableCounter;
|
||||||
|
d->MaxDecodedFrames = d->DecodedFrames;
|
||||||
|
d->SeekTableCounter = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// until here we jumped to desired position -33 frames
|
||||||
|
|
||||||
// REVIEW: Needed?
|
// now we decode the last 33 frames until we reach the seek position
|
||||||
mpc_decoder_update_buffer(d);
|
// this is neccessary as mpc uses entropy coding in time domain
|
||||||
|
for (;d->DecodedFrames < seekFrame; d->DecodedFrames++)
|
||||||
for (;d->DecodedFrames < seekFrame; d->DecodedFrames++) {
|
{
|
||||||
|
|
||||||
mpc_uint32_t FrameBitCnt;
|
mpc_uint32_t FrameBitCnt;
|
||||||
|
|
||||||
d->FwdJumpInfo = mpc_decoder_bitstream_read(d, 20); // read jump-info
|
d->FwdJumpInfo = mpc_decoder_bitstream_read(d, 20); // read jump-info
|
||||||
d->ActDecodePos = (d->Zaehler << 5) + d->pos;
|
d->ActDecodePos = (d->Zaehler << 5) + d->pos;
|
||||||
FrameBitCnt = mpc_decoder_bits_read(d);
|
FrameBitCnt = mpc_decoder_bits_read(d);
|
||||||
// scanning the scalefactors (and check for validity of frame)
|
// scanning the scalefactors (and check for validity of frame)
|
||||||
if (d->StreamVersion >= 7) {
|
if (d->StreamVersion >= 7)
|
||||||
|
{
|
||||||
mpc_decoder_read_bitstream_sv7(d, (d->DecodedFrames < seekFrame - 1));
|
mpc_decoder_read_bitstream_sv7(d, (d->DecodedFrames < seekFrame - 1));
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
#ifdef MPC_SUPPORT_SV456
|
#ifdef MPC_SUPPORT_SV456
|
||||||
mpc_decoder_read_bitstream_sv6(d);
|
mpc_decoder_read_bitstream_sv6(d);
|
||||||
#else
|
#else
|
||||||
|
@ -1725,34 +1703,15 @@ mpc_bool_t mpc_decoder_seek_sample(mpc_decoder *d, mpc_int64_t destsample)
|
||||||
// Bug in perform_jump;
|
// Bug in perform_jump;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
// REVIEW: Only if decodedFrames < maxDecodedFrames??
|
|
||||||
if (d->SeekTable_Step == 1) {
|
|
||||||
// check that the frame length corresponds with any data already in the seek table
|
|
||||||
if (d->SeekTable[d->DecodedFrames+1] != 0 && d->SeekTable[d->DecodedFrames+1] != d->FwdJumpInfo + 20)
|
|
||||||
return FALSE;
|
|
||||||
d->SeekTable [d->DecodedFrames+1] = d->FwdJumpInfo + 20;
|
|
||||||
} else {
|
|
||||||
if (d->DecodedFrames % d->SeekTable_Step == 0) {
|
|
||||||
if (d->SeekTable[d->SeekTableIndex] != 0 && d->SeekTable[d->SeekTableIndex] != d->SeekTableCounter)
|
|
||||||
return FALSE;
|
|
||||||
d->SeekTable[d->SeekTableIndex] = d->SeekTableCounter;
|
|
||||||
d->SeekTableIndex += 1;
|
|
||||||
d->SeekTableCounter = 0;
|
|
||||||
}
|
|
||||||
d->SeekTableCounter += d->FwdJumpInfo + 20;
|
|
||||||
}
|
|
||||||
|
|
||||||
// update buffer
|
// update buffer
|
||||||
mpc_decoder_update_buffer(d);
|
mpc_decoder_update_buffer(d);
|
||||||
|
|
||||||
if (d->DecodedFrames == seekFrame - 1) {
|
if (d->DecodedFrames == seekFrame - 1)
|
||||||
|
{
|
||||||
// initialize the synth correctly for perfect decoding
|
// initialize the synth correctly for perfect decoding
|
||||||
mpc_decoder_requantisierung(d, d->Max_Band);
|
mpc_decoder_requantisierung(d, d->Max_Band);
|
||||||
mpc_decoder_synthese_filter_float(d, NULL);
|
mpc_decoder_synthese_filter_float(d, NULL);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue