summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/opus.c
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2013-07-14 07:59:39 -0400
committerMichael Sevakis <jethead71@rockbox.org>2014-03-10 04:12:30 +0100
commit31b712286721dd606940c7b557d03e3f714b9604 (patch)
tree8c4a4cc32e9000ea721ebb23aa3c0129ca97bf53 /lib/rbcodec/codecs/opus.c
parentdda54b85daa83b7803b4fb189ab45859f96ff3f9 (diff)
downloadrockbox-31b712286721dd606940c7b557d03e3f714b9604.tar.gz
rockbox-31b712286721dd606940c7b557d03e3f714b9604.zip
Implement time-based resume and playback start.
This complements offset-based resume and playback start funcionality. The implementation is global on both HWCODEC and SWCODEC. Basically, if either the specified elapsed or offset are non-zero, it indicates a mid-track resume. To resume by time only, set elapsed to nonzero and offset to zero. To resume by offset only, set offset to nonzero and elapsed to zero. Which one the codec uses and which has priority is up to the codec; however, using an elapsed time covers more cases: * Codecs not able to use an offset such as VGM or other atomic formats * Starting playback at a nonzero elapsed time from a source that contains no offset, such as a cuesheet The change re-versions pretty much everything from tagcache to nvram. Change-Id: Ic7aebb24e99a03ae99585c5e236eba960d163f38 Reviewed-on: http://gerrit.rockbox.org/516 Reviewed-by: Michael Sevakis <jethead71@rockbox.org> Tested: Michael Sevakis <jethead71@rockbox.org>
Diffstat (limited to 'lib/rbcodec/codecs/opus.c')
-rw-r--r--lib/rbcodec/codecs/opus.c47
1 files changed, 32 insertions, 15 deletions
diff --git a/lib/rbcodec/codecs/opus.c b/lib/rbcodec/codecs/opus.c
index 15d96ff6fe..2c495aa8d0 100644
--- a/lib/rbcodec/codecs/opus.c
+++ b/lib/rbcodec/codecs/opus.c
@@ -314,6 +314,7 @@ enum codec_status codec_main(enum codec_entry_call_reason reason)
314enum codec_status codec_run(void) 314enum codec_status codec_run(void)
315{ 315{
316 int error = CODEC_ERROR; 316 int error = CODEC_ERROR;
317 enum codec_command_action action;
317 intptr_t param; 318 intptr_t param;
318 ogg_sync_state oy; 319 ogg_sync_state oy;
319 ogg_page og; 320 ogg_page og;
@@ -325,13 +326,17 @@ enum codec_status codec_run(void)
325 OpusDecoder *st = NULL; 326 OpusDecoder *st = NULL;
326 OpusHeader header; 327 OpusHeader header;
327 int ret; 328 int ret;
328 unsigned long strtoffset = ci->id3->offset; 329 unsigned long strtoffset;
329 int skip = 0; 330 int skip = 0;
330 int64_t seek_target; 331 int64_t seek_target;
331 uint64_t granule_pos; 332 uint64_t granule_pos;
332 333
333 ogg_malloc_init(); 334 ogg_malloc_init();
334 335
336 action = CODEC_ACTION_NULL;
337 param = ci->id3->elapsed;
338 strtoffset = ci->id3->offset;
339
335 global_stack = 0; 340 global_stack = 0;
336 341
337#if defined(CPU_COLDFIRE) 342#if defined(CPU_COLDFIRE)
@@ -351,28 +356,40 @@ enum codec_status codec_run(void)
351 ci->seek_buffer(0); 356 ci->seek_buffer(0);
352 ci->set_elapsed(0); 357 ci->set_elapsed(0);
353 358
359 if (!strtoffset && param) {
360 action = CODEC_ACTION_SEEK_TIME;
361 }
362
363 goto next_page;
364
354 while (1) { 365 while (1) {
355 enum codec_command_action action = ci->get_command(&param); 366 if (action == CODEC_ACTION_NULL)
367 action = ci->get_command(&param);
356 368
357 if (action == CODEC_ACTION_HALT) 369 if (action != CODEC_ACTION_NULL) {
358 break; 370 if (action == CODEC_ACTION_HALT)
371 break;
372
373 if (action == CODEC_ACTION_SEEK_TIME) {
374 if (st != NULL) {
375 /* calculate granule to seek to (including seek rewind) */
376 seek_target = (48LL * param) + header.preskip;
377 skip = MIN(seek_target, SEEK_REWIND);
378 seek_target -= skip;
359 379
360 if (action == CODEC_ACTION_SEEK_TIME) { 380 LOGF("Opus seek page:%lld,%lld,%ld\n",
361 if (st != NULL) { 381 seek_target, page_granule, (long)param);
362 /* calculate granule to seek to (including seek rewind) */ 382 speex_seek_page_granule(seek_target, page_granule, &oy, &os);
363 seek_target = (48LL * param) + header.preskip; 383 }
364 skip = MIN(seek_target, SEEK_REWIND);
365 seek_target -= skip;
366 384
367 LOGF("Opus seek page:%lld,%lld,%ld\n", 385 ci->set_elapsed(param);
368 seek_target, page_granule, (long)param); 386 ci->seek_complete();
369 speex_seek_page_granule(seek_target, page_granule, &oy, &os);
370 } 387 }
371 388
372 ci->set_elapsed(param); 389 action = CODEC_ACTION_NULL;
373 ci->seek_complete();
374 } 390 }
375 391
392 next_page:
376 /*Get the ogg buffer for writing*/ 393 /*Get the ogg buffer for writing*/
377 if (get_more_data(&oy) < 1) { 394 if (get_more_data(&oy) < 1) {
378 goto done; 395 goto done;