diff options
author | William Wilgus <me.theuser@yahoo.com> | 2018-12-31 03:04:31 -0600 |
---|---|---|
committer | William Wilgus <me.theuser@yahoo.com> | 2019-01-04 06:56:52 +0100 |
commit | 100f4338deea5239423a0b8974784939d520385c (patch) | |
tree | 95d63e56710b031fca6a8f26500cc2cacd964378 | |
parent | 976831e6674db98cc7992db1479afff9d2877c81 (diff) | |
download | rockbox-100f4338deea5239423a0b8974784939d520385c.tar.gz rockbox-100f4338deea5239423a0b8974784939d520385c.zip |
Fix Opus FS#13133 - Files with embedded artwork 45.8KiB+ skip near beginning
ogg_sync_reset() causes issues on the partial page boundary
due to the next page (already in buffer) being discarded
instead seek next page boundary past complete page
Change-Id: Ic05f188f489b015693d663f131e09cd92ad37ff7
-rw-r--r-- | lib/rbcodec/codecs/opus.c | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/lib/rbcodec/codecs/opus.c b/lib/rbcodec/codecs/opus.c index 1ce7f19dfd..6574d6c052 100644 --- a/lib/rbcodec/codecs/opus.c +++ b/lib/rbcodec/codecs/opus.c | |||
@@ -57,6 +57,27 @@ static int get_more_data(ogg_sync_state *oy) | |||
57 | 57 | ||
58 | return bytes; | 58 | return bytes; |
59 | } | 59 | } |
60 | |||
61 | /* seek to ogg page after given file position */ | ||
62 | static int seek_ogg_page(int64_t filepos) | ||
63 | { | ||
64 | const char synccode[] = "OggS\0"; /* Note: there are two nulls here */ | ||
65 | char buf[sizeof(synccode)]; | ||
66 | ci->seek_buffer(filepos); | ||
67 | while (ci->read_filebuf(buf, 1) == 1) { | ||
68 | if (buf[0] == synccode[0]) { | ||
69 | if (ci->read_filebuf(&buf[1], sizeof(buf) - 1) != sizeof(buf) - 1) | ||
70 | break; | ||
71 | if (memcmp(buf, synccode, sizeof(buf)) == 0) { | ||
72 | ci->seek_buffer(ci->curpos - sizeof(buf)); | ||
73 | LOGF("next page %ld", ci->curpos); | ||
74 | return 1; | ||
75 | } | ||
76 | } | ||
77 | } | ||
78 | return 0; | ||
79 | } | ||
80 | |||
60 | /* The read/seek functions track absolute position within the stream */ | 81 | /* The read/seek functions track absolute position within the stream */ |
61 | static int64_t get_next_page(ogg_sync_state *oy, ogg_page *og, | 82 | static int64_t get_next_page(ogg_sync_state *oy, ogg_page *og, |
62 | int64_t boundary) | 83 | int64_t boundary) |
@@ -408,8 +429,12 @@ enum codec_status codec_run(void) | |||
408 | 429 | ||
409 | /* Do this to avoid allocating space for huge comment packets | 430 | /* Do this to avoid allocating space for huge comment packets |
410 | (embedded Album Art) */ | 431 | (embedded Album Art) */ |
411 | if(os.packetno == 1 && ogg_stream_packetpeek(&os, &op) != 1){ | 432 | if (os.packetno == 1 && ogg_stream_packetpeek(&os, NULL) == 0){ |
412 | ogg_sync_reset(&oy); | 433 | LOGF("sync reset"); |
434 | /* seek buffer directly to the first audio packet */ | ||
435 | seek_ogg_page(ci->curpos - oy.returned); | ||
436 | ogg_sync_reset(&oy); | ||
437 | break; | ||
413 | } | 438 | } |
414 | 439 | ||
415 | while ((ogg_stream_packetout(&os, &op) == 1) && !op.e_o_s) { | 440 | while ((ogg_stream_packetout(&os, &op) == 1) && !op.e_o_s) { |