View Single Post
Old 15 May 2010, 09:07 pm   #5
Buschel
The Man
 
Join Date: Mar 2008
Posts: 9
Default

Hi r2d, thanks for your response!

I already submitted the following change (verified by 3 users to the rockbox depot:

static void
mpc_demux_seek(mpc_demux * d, mpc_seek_t fpos, mpc_uint32_t min_bytes) {
- mpc_seek_t next_pos;
- mpc_int_t bit_offset;
+ // d->bits_reader.buff - d->buffer = current byte position within buffer
+ // d->bytes_total = buffer is filled with bytes_total bytes
+ // fpos = desired file position in bit (not byte)
+ // buf_fpos = desired byte position within buffer
+ mpc_seek_t next_pos = fpos>>3;
+ mpc_int_t buf_fpos = next_pos - d->r->tell(d->r) + d->bytes_total;

- // FIXME : do not flush the buffer if fpos is in the current buffer
-
- next_pos = fpos >> 3;
- if (d->si.stream_version == 7)
- next_pos = ((next_pos - d->si.header_position) & (-1 << 2)) + d->si.header_position;
- bit_offset = (int) (fpos - (next_pos << 3));
-
- d->r->seek(d->r, (mpc_int32_t) next_pos);
- mpc_demux_clear_buff(d);
- if (d->si.stream_version == 7)
- mpc_demux_fill(d, (min_bytes + ((bit_offset + 7) >> 3) + 3) & (~3), MPC_BUFFER_SWAP);
- else
- mpc_demux_fill(d, min_bytes + ((bit_offset + 7) >> 3), 0);
- d->bits_reader.buff += bit_offset >> 3;
- d->bits_reader.count = 8 - (bit_offset & 7);
+ // is desired byte position is within lower and upper boundaries of buffer?
+ if (buf_fpos >= 0 && buf_fpos + min_bytes <= DEMUX_BUFFER_SIZE) {
+ // desired bytes are available in current buffer
+ d->bits_reader.buff += buf_fpos - (d->bits_reader.buff - d->buffer);
+ d->bits_reader.count = 8 - (fpos & 7);
+ } else {
+ // buffer needs to be refilled
+ if (d->si.stream_version == 7)
+ next_pos = ((next_pos - d->si.header_position) & (-1 << 2)) + d->si.header_position;
+ buf_fpos = fpos - (next_pos << 3);
+
+ d->r->seek(d->r, (mpc_int32_t) next_pos);
+ mpc_demux_clear_buff(d);
+ if (d->si.stream_version == 7)
+ mpc_demux_fill(d, DEMUX_BUFFER_SIZE, MPC_BUFFER_SWAP);
+ else
+ mpc_demux_fill(d, DEMUX_BUFFER_SIZE, 0);
+ d->bits_reader.buff += buf_fpos >> 3;
+ d->bits_reader.count = 8 - (buf_fpos & 7);
+ }
}

This change is similar to yours but will avoid to refill the buffer with small amounts of data on every call. Instead it will try to work with already buffered data as long as possible. If the buffer runs out of data it will fill the whole buffer. On my test file I could reduce buffer fills to ~1% of all calls.
Buschel is offline   Reply With Quote