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-0d303567344ef36c804d0377ae9c43a869a94557.tar.gz rockbox-0d303567344ef36c804d0377ae9c43a869a94557.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) | |||
408 | return CODEC_OK; | 408 | return CODEC_OK; |
409 | } | 409 | } |
410 | 410 | ||
411 | bool seek_by_time(int64_t* samplesdone, unsigned long current_frequency, unsigned long elapsed_ms) | ||
412 | { | ||
413 | if (ci->id3->is_asf_stream) { | ||
414 | asf_waveformatex_t *wfx = (asf_waveformatex_t *)(ci->id3->toc); | ||
415 | int elapsedtime = asf_seek(elapsed_ms, wfx); | ||
416 | |||
417 | *samplesdone = (elapsedtime > 0) ? | ||
418 | (((int64_t)elapsedtime)*current_frequency/1000) : 0; | ||
419 | |||
420 | if (elapsedtime < 1) { | ||
421 | ci->set_elapsed(0); | ||
422 | return false; | ||
423 | } else { | ||
424 | ci->set_elapsed(elapsedtime); | ||
425 | reset_stream_buffer(); | ||
426 | } | ||
427 | } else { | ||
428 | int newpos = elapsed_ms ? get_file_pos(elapsed_ms) : (int)(ci->id3->first_frame_offset); | ||
429 | |||
430 | *samplesdone = ((int64_t)elapsed_ms) * current_frequency / 1000; | ||
431 | |||
432 | if (!ci->seek_buffer(newpos)) | ||
433 | return false; | ||
434 | |||
435 | ci->set_elapsed((*samplesdone * 1000LL) / current_frequency); | ||
436 | } | ||
437 | return true; | ||
438 | } | ||
439 | |||
411 | /* this is called for each file to process */ | 440 | /* this is called for each file to process */ |
412 | enum codec_status codec_run(void) | 441 | enum codec_status codec_run(void) |
413 | { | 442 | { |
@@ -431,13 +460,8 @@ enum codec_status codec_run(void) | |||
431 | ci->configure(DSP_SET_FREQUENCY, ci->id3->frequency); | 460 | ci->configure(DSP_SET_FREQUENCY, ci->id3->frequency); |
432 | current_frequency = ci->id3->frequency; | 461 | current_frequency = ci->id3->frequency; |
433 | codec_set_replaygain(ci->id3); | 462 | codec_set_replaygain(ci->id3); |
434 | |||
435 | if (!ci->id3->is_asf_stream && !ci->id3->offset && ci->id3->elapsed) { | ||
436 | /* Have elapsed time but not offset */ | ||
437 | ci->id3->offset = get_file_pos(ci->id3->elapsed); | ||
438 | } | ||
439 | 463 | ||
440 | if (ci->id3->offset) { | 464 | if (ci->id3->offset) { |
441 | 465 | ||
442 | if (ci->id3->is_asf_stream) { | 466 | if (ci->id3->is_asf_stream) { |
443 | asf_waveformatex_t *wfx = (asf_waveformatex_t *)(ci->id3->toc); | 467 | asf_waveformatex_t *wfx = (asf_waveformatex_t *)(ci->id3->toc); |
@@ -453,6 +477,9 @@ enum codec_status codec_run(void) | |||
453 | set_elapsed(ci->id3); | 477 | set_elapsed(ci->id3); |
454 | } | 478 | } |
455 | } | 479 | } |
480 | else if (ci->id3->elapsed) | ||
481 | /* Have elapsed time but not offset */ | ||
482 | seek_by_time(&samplesdone, current_frequency, ci->id3->elapsed); | ||
456 | else | 483 | else |
457 | ci->seek_buffer(ci->id3->first_frame_offset); | 484 | ci->seek_buffer(ci->id3->first_frame_offset); |
458 | 485 | ||
@@ -508,36 +535,10 @@ enum codec_status codec_run(void) | |||
508 | samples_to_skip = 0; | 535 | samples_to_skip = 0; |
509 | } | 536 | } |
510 | 537 | ||
511 | if (ci->id3->is_asf_stream) { | 538 | bool success = seek_by_time(&samplesdone, current_frequency, param); |
512 | asf_waveformatex_t *wfx = (asf_waveformatex_t *)(ci->id3->toc); | 539 | ci->seek_complete(); |
513 | int elapsedtime = asf_seek(param, wfx); | 540 | if (!success) |
514 | 541 | break; | |
515 | samplesdone = (elapsedtime > 0) ? | ||
516 | (((int64_t)elapsedtime)*current_frequency/1000) : 0; | ||
517 | |||
518 | if (elapsedtime < 1) { | ||
519 | ci->set_elapsed(0); | ||
520 | ci->seek_complete(); | ||
521 | break; | ||
522 | } else { | ||
523 | ci->set_elapsed(elapsedtime); | ||
524 | ci->seek_complete(); | ||
525 | reset_stream_buffer(); | ||
526 | } | ||
527 | } else { | ||
528 | int newpos = param ? get_file_pos(param) : (int)(ci->id3->first_frame_offset); | ||
529 | |||
530 | samplesdone = ((int64_t)param)*current_frequency/1000; | ||
531 | |||
532 | if (!ci->seek_buffer(newpos)) | ||
533 | { | ||
534 | ci->seek_complete(); | ||
535 | break; | ||
536 | } | ||
537 | |||
538 | ci->set_elapsed((samplesdone * 1000LL) / current_frequency); | ||
539 | ci->seek_complete(); | ||
540 | } | ||
541 | 542 | ||
542 | init_mad(); | 543 | init_mad(); |
543 | framelength = 0; | 544 | framelength = 0; |