Skip to content

Commit

Permalink
Codecs: mpa: Seek relative to the current position in MP3 VBR files
Browse files Browse the repository at this point in the history
Use current position if it gives better accuracy compared to TOC values

Change-Id: Id72b7c1aa59898293d436e48886b9a07696683b8
  • Loading branch information
bahusoid committed Dec 25, 2023
1 parent 8b3ad3b commit d1e4224
Showing 1 changed file with 18 additions and 10 deletions.
28 changes: 18 additions & 10 deletions lib/rbcodec/codecs/mpa.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ static int get_file_pos(int newtime)
struct mp3entry *id3 = ci->id3;

if (id3->vbr) {
long delta = id3->elapsed - newtime;
int curpos = ci->curpos - id3->first_frame_offset;

if (id3->has_toc) {
/* Use the TOC to find the new position */
unsigned int percent = ((uint64_t)newtime * 100) / id3->length;
Expand All @@ -101,24 +104,22 @@ static int get_file_pos(int newtime)
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;
//LOGF("plength: %ld, delta: %ld, newtime_toc: %ld", plength/1000, delta/1000, newtime_toc/1000 );
if (newtime_toc < abs(delta))
pos = cur_toc * toc_sizestep + (uint64_t)plength * newtime_toc / pct_timestep;
} else {
/* 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;
int curpos = ci->curpos - id3->first_frame_offset;
if ((delta >= 0 && pos > curpos) || (delta < 0 && pos < curpos))
if (pos == -1 || (delta >= 0 && pos > curpos) || (delta < 0 && pos < curpos))
{
pos = curpos - delta * id3->filesize / id3->length;
pos = curpos - delta * (id3->filesize / id3->length);
//LOGF("Relative seek: %ld, curpos: %ld", pos, curpos);
}
} else if (id3->bitrate) {
pos = newtime * (id3->bitrate / 8);
Expand All @@ -130,7 +131,7 @@ static int get_file_pos(int newtime)
transition properly to the next song */
if (pos >= (int)(id3->filesize - id3->id3v1len))
pos = id3->filesize - id3->id3v1len - 1;

/* id3->filesize excludes id3->first_frame_offset, so add it now */
pos += id3->first_frame_offset;

Expand Down Expand Up @@ -348,7 +349,14 @@ enum codec_status codec_run(void)
if (ci->id3->offset)
{
ci->seek_buffer(ci->id3->offset);
set_elapsed(ci->id3);
if(ci->id3->elapsed)
{
ci->set_elapsed(ci->id3->elapsed);
}
else
{
set_elapsed(ci->id3);
}
}
else if (ci->id3->elapsed)
/* Have elapsed time but not offset */
Expand Down

0 comments on commit d1e4224

Please sign in to comment.