summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoman Artiukhin <bahusdrive@gmail.com>2024-01-24 11:40:51 +0200
committerRoman Artiukhin <bahusdrive@gmail.com>2024-01-24 12:35:07 +0200
commit1122cae02804bd97887d51be6e5eee6a1616a09b (patch)
treee47a623ed7cc6c1b5a6df245b61adc4ae261fad2
parent49910eca4b400c817d1a6b65a53348280374927a (diff)
downloadrockbox-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.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);