summaryrefslogtreecommitdiffstats
path: root/lib/rbcodec/codecs/mpa.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/codecs/mpa.c')
-rw-r--r--lib/rbcodec/codecs/mpa.c29
1 files changed, 16 insertions, 13 deletions
diff --git a/lib/rbcodec/codecs/mpa.c b/lib/rbcodec/codecs/mpa.c
index c5d47a6791..5fdcb38da8 100644
--- a/lib/rbcodec/codecs/mpa.c
+++ b/lib/rbcodec/codecs/mpa.c
@@ -176,6 +176,8 @@ static int get_file_pos(int newtime)
struct mp3entry *id3 = ci->id3;
if (id3->vbr) {
+ int curpos = ci->curpos - id3->first_frame_offset;
+ long skipms_from_curpos = curpos > 0 ? (long) (id3->elapsed - newtime) : - newtime;
if (id3->has_toc) {
/* Use the TOC to find the new position */
unsigned int percent = ((uint64_t)newtime * 100) / id3->length;
@@ -183,28 +185,29 @@ static int get_file_pos(int newtime)
percent = 99;
unsigned int pct_timestep = id3->length / 100;
- unsigned int toc_sizestep = id3->filesize / 256;
- unsigned int cur_toc = id3->toc[percent];
- unsigned int next_toc = percent < 99 ? id3->toc[percent+1] : 256;
- unsigned int plength = (next_toc - cur_toc) * toc_sizestep;
-
- /* Seek to TOC mark */
- pos = cur_toc * toc_sizestep;
/* Interpolate between this TOC mark and the next TOC mark */
- int newtime_toc = newtime - percent * pct_timestep;
- pos += (uint64_t)plength * newtime_toc / pct_timestep;
- } else {
+ int skipms_from_toc = newtime - percent * pct_timestep;
+ if (skipms_from_toc < abs(skipms_from_curpos))
+ {
+ unsigned int toc_sizestep = id3->filesize / 256;
+ unsigned int cur_toc = id3->toc[percent];
+ unsigned int next_toc = percent < 99 ? id3->toc[percent+1] : 256;
+ unsigned int plength = (next_toc - cur_toc) * toc_sizestep;
+
+ pos = cur_toc * toc_sizestep + (uint64_t) plength * skipms_from_toc / pct_timestep;
+ }
+ } else if (newtime < abs(skipms_from_curpos)) {
/* No TOC exists, estimate the new position */
pos = (uint64_t)newtime * id3->filesize / id3->length;
}
// VBR seek might be very inaccurate in long files
// So make sure that seeking actually happened in the intended direction
// Fix jumps in the wrong direction by seeking relative to the current position
- long delta = id3->elapsed - newtime;
- if ((delta >= 0 && pos > ci->curpos) || (delta < 0 && pos < ci->curpos))
+ if (pos == -1 || (skipms_from_curpos >= 0 && pos > curpos) || (skipms_from_curpos < 0 && pos < curpos))
{
- pos = ci->curpos - delta * id3->filesize / id3->length;
+ pos = curpos - skipms_from_curpos * (id3->filesize / id3->length);
+ //LOGF("—Āurpos relative seek: %d, curpos: %d, newtime: %d", pos, curpos, newtime);
}
} else if (id3->bitrate) {
pos = newtime * (id3->bitrate / 8);