diff options
author | Roman Artiukhin <bahusdrive@gmail.com> | 2024-01-24 11:40:51 +0200 |
---|---|---|
committer | Roman Artiukhin <bahusdrive@gmail.com> | 2024-01-24 12:35:07 +0200 |
commit | 1122cae02804bd97887d51be6e5eee6a1616a09b (patch) | |
tree | e47a623ed7cc6c1b5a6df245b61adc4ae261fad2 | |
parent | 49910eca4b400c817d1a6b65a53348280374927a (diff) | |
download | rockbox-1122cae028.tar.gz rockbox-1122cae028.zip |
Codecs: mpa: Improve seek in large mp3 vbr files
Use current position as toc mark and use it if it gives better accuracy.
Continuation of 3883c978
Change-Id: Ic6e8192fc43061f3c07128486dbefba7382be5ce
-rw-r--r-- | lib/rbcodec/codecs/mpa.c | 29 |
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); |