summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorroman.artiukhin <bahusdrive@gmail.com>2022-10-30 08:11:25 +0200
committerAidan MacDonald <amachronic@protonmail.com>2022-11-01 09:23:35 -0400
commit0d303567344ef36c804d0377ae9c43a869a94557 (patch)
treea2fa906a080f1c84fbe68707fa0dd13361e0d9bd
parent5d7e15324b792d4033ac49bda4f5ee244d71d7cb (diff)
downloadrockbox-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.c73
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
411bool 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 */
412enum codec_status codec_run(void) 441enum 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;