diff options
-rw-r--r-- | lib/rbcodec/codecs/opus.c | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/lib/rbcodec/codecs/opus.c b/lib/rbcodec/codecs/opus.c index 89eb4fe3ad..acae1aaacc 100644 --- a/lib/rbcodec/codecs/opus.c +++ b/lib/rbcodec/codecs/opus.c @@ -78,6 +78,29 @@ static int seek_ogg_page(uint64_t filepos) return 0; } +/* seek to comment header */ +static int seek_opus_tags(void) +{ + int pos = 0; + const int64_t maxpos = sizeof(OpusHeader) + 1024; + const char synccode[] = "OpusTags"; + char buf[sizeof(synccode)]; + ci->seek_buffer(0); + while (ci->read_filebuf(buf, 1) == 1 && ci->curpos < maxpos) { + if (buf[0] == synccode[0]) { + if (ci->read_filebuf(&buf[1], sizeof(buf) - 2) != sizeof(buf) - 2) + break; + if (memcmp(buf, synccode, sizeof(buf)) == 0) { + ci->seek_buffer(ci->curpos - sizeof(buf)); + LOGF("OpusTags %ld", ci->curpos); + return 1; + } + } + } + /* comment header not found probably invalid file */ + return 0; +} + /* The read/seek functions track absolute position within the stream */ static int64_t get_next_page(ogg_sync_state *oy, ogg_page *og, int64_t boundary) @@ -455,7 +478,12 @@ enum codec_status codec_run(void) /* seek buffer directly to the first audio packet to avoid allocating space for huge comment packets (embedded Album Art) */ - seek_ogg_page(ci->curpos - oy.returned); + if (seek_opus_tags()) + seek_ogg_page(ci->curpos); + else { + LOGF("Could not find comment header"); + goto done; + } } LOGF("sync reset"); ogg_sync_reset(&oy); /* next page */ |