diff options
author | roman.artiukhin <bahusdrive@gmail.com> | 2022-10-30 08:11:25 +0200 |
---|---|---|
committer | Aidan MacDonald <amachronic@protonmail.com> | 2022-11-01 09:23:35 -0400 |
commit | 0d303567344ef36c804d0377ae9c43a869a94557 (patch) | |
tree | a2fa906a080f1c84fbe68707fa0dd13361e0d9bd | |
parent | 5d7e15324b792d4033ac49bda4f5ee244d71d7cb (diff) | |
download | rockbox-0d30356734.tar.gz rockbox-0d30356734.zip |
Refactor to reuse seek code for resume by time
It fixes Playback/Bookmarks Resume for long vbr mp3 files
It also fixes resume by time for asf files.
As a replacement for https://gerrit.rockbox.org/r/c/rockbox/+/4750
Change-Id: Iaa59b5862385f5fe91fdc2fb0b1fde8ce75c0b54
-rw-r--r-- | lib/rbcodec/codecs/mpa.c | 73 |
1 files changed, 37 insertions, 36 deletions
diff --git a/lib/rbcodec/codecs/mpa.c b/lib/rbcodec/codecs/mpa.c index d6bcc04910..d374a5229a 100644 --- a/lib/rbcodec/codecs/mpa.c +++ b/lib/rbcodec/codecs/mpa.c @@ -408,6 +408,35 @@ enum codec_status codec_main(enum codec_entry_call_reason reason) return CODEC_OK; } +bool seek_by_time(int64_t* samplesdone, unsigned long current_frequency, unsigned long elapsed_ms) +{ + if (ci->id3->is_asf_stream) { + asf_waveformatex_t *wfx = (asf_waveformatex_t *)(ci->id3->toc); + int elapsedtime = asf_seek(elapsed_ms, wfx); + + *samplesdone = (elapsedtime > 0) ? + (((int64_t)elapsedtime)*current_frequency/1000) : 0; + + if (elapsedtime < 1) { + ci->set_elapsed(0); + return false; + } else { + ci->set_elapsed(elapsedtime); + reset_stream_buffer(); + } + } else { + int newpos = elapsed_ms ? get_file_pos(elapsed_ms) : (int)(ci->id3->first_frame_offset); + + *samplesdone = ((int64_t)elapsed_ms) * current_frequency / 1000; + + if (!ci->seek_buffer(newpos)) + return false; + + ci->set_elapsed((*samplesdone * 1000LL) / current_frequency); + } + return true; +} + /* this is called for each file to process */ enum codec_status codec_run(void) { @@ -431,13 +460,8 @@ enum codec_status codec_run(void) ci->configure(DSP_SET_FREQUENCY, ci->id3->frequency); current_frequency = ci->id3->frequency; codec_set_replaygain(ci->id3); - - if (!ci->id3->is_asf_stream && !ci->id3->offset && ci->id3->elapsed) { - /* Have elapsed time but not offset */ - ci->id3->offset = get_file_pos(ci->id3->elapsed); - } - if (ci->id3->offset) { + if (ci->id3->offset) { if (ci->id3->is_asf_stream) { asf_waveformatex_t *wfx = (asf_waveformatex_t *)(ci->id3->toc); @@ -453,6 +477,9 @@ enum codec_status codec_run(void) set_elapsed(ci->id3); } } + else if (ci->id3->elapsed) + /* Have elapsed time but not offset */ + seek_by_time(&samplesdone, current_frequency, ci->id3->elapsed); else ci->seek_buffer(ci->id3->first_frame_offset); @@ -508,36 +535,10 @@ enum codec_status codec_run(void) samples_to_skip = 0; } - if (ci->id3->is_asf_stream) { - asf_waveformatex_t *wfx = (asf_waveformatex_t *)(ci->id3->toc); - int elapsedtime = asf_seek(param, wfx); - - samplesdone = (elapsedtime > 0) ? - (((int64_t)elapsedtime)*current_frequency/1000) : 0; - - if (elapsedtime < 1) { - ci->set_elapsed(0); - ci->seek_complete(); - break; - } else { - ci->set_elapsed(elapsedtime); - ci->seek_complete(); - reset_stream_buffer(); - } - } else { - int newpos = param ? get_file_pos(param) : (int)(ci->id3->first_frame_offset); - - samplesdone = ((int64_t)param)*current_frequency/1000; - - if (!ci->seek_buffer(newpos)) - { - ci->seek_complete(); - break; - } - - ci->set_elapsed((samplesdone * 1000LL) / current_frequency); - ci->seek_complete(); - } + bool success = seek_by_time(&samplesdone, current_frequency, param); + ci->seek_complete(); + if (!success) + break; init_mad(); framelength = 0; |