summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorAndree Buschmann <AndreeBuschmann@t-online.de>2010-05-14 22:06:28 +0000
committerAndree Buschmann <AndreeBuschmann@t-online.de>2010-05-14 22:06:28 +0000
commitdb42781ca855e9062947b4a841b814c6401957b0 (patch)
treed8fb1c83d05421b0002d7a83d7700ab4fe96b252 /apps
parent7036a1012626a34814db888025229983adca29b6 (diff)
Fix FS#11261 (slow seek forward in mpc files). Since the introduction of the sv8 library mpc did not use efficient buffering when seeking forward. With this change the implementation will not flush the buffer on each frame but will keep the already buffered data as long as possible.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26032 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r--apps/codecs/libmusepack/mpc_demux.c45
1 files changed, 27 insertions, 18 deletions
diff --git a/apps/codecs/libmusepack/mpc_demux.c b/apps/codecs/libmusepack/mpc_demux.c
index 244ef25644..e74e420b0d 100644
--- a/apps/codecs/libmusepack/mpc_demux.c
+++ b/apps/codecs/libmusepack/mpc_demux.c
@@ -120,24 +120,33 @@ mpc_demux_fill(mpc_demux * d, mpc_uint32_t min_bytes, int flags)
*/
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;
-
- // 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);
+ // 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;
+
+ // is desired byte position 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);
+ }
}
/**