From 7bbf8af76100d4cc8eb3f9b71d498ce6392da5d7 Mon Sep 17 00:00:00 2001 From: shatty Date: Sun, 28 Dec 2003 11:48:38 +0000 Subject: [PATCH] clean ogg seeking. goes to next ogg page start. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5782 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../media/plugins/ogg/OggReaderPlugin.cpp | 47 +++++++++++++++++-- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/src/add-ons/media/plugins/ogg/OggReaderPlugin.cpp b/src/add-ons/media/plugins/ogg/OggReaderPlugin.cpp index 22a7713c96..14e497f387 100644 --- a/src/add-ons/media/plugins/ogg/OggReaderPlugin.cpp +++ b/src/add-ons/media/plugins/ogg/OggReaderPlugin.cpp @@ -282,9 +282,6 @@ oggReader::Seek(void *cookie, } else { return B_ERROR; } - *frame = filePositionToFrame(position); - *time = filePositionToTime(position); - // TODO: use B_MEDIA_SEEK_CLOSEST_BACKWARD, B_MEDIA_SEEK_CLOSEST_FORWARD to find key frame if (ogg_sync_reset(&fSync) != 0) { TRACE("oggReader::Seek: ogg_sync_reset failed?: error\n"); @@ -294,8 +291,48 @@ oggReader::Seek(void *cookie, TRACE("oggReader::Seek: ogg_stream_reset failed?: error\n"); return B_ERROR; } - fSeekable->Seek(position,SEEK_SET); - + if (fSeekable->Seek(position,SEEK_SET) < 0) { + TRACE("oggReader::Seek: Seek failed: error\n"); + return B_ERROR; + } + // align to page boundary + ogg_page page; + ogg_sync_state sync; + ogg_sync_init(&sync); + while (true) { + char * buffer = ogg_sync_buffer(&sync,4096); + ssize_t bytes = fSeekable->Read(buffer,4096); + if (bytes == 0) { + TRACE("oggReader::Seek: Read: no data\n"); + goto synced; + } + if (bytes < 0) { + TRACE("oggReader::Seek: Read: error\n"); + ogg_sync_clear(&sync); + return bytes; + } + if (ogg_sync_wrote(&sync,bytes) != 0) { + TRACE("oggReader::Seek: ogg_sync_wrote failed?: error\n"); + ogg_sync_clear(&sync); + return B_ERROR; + } + int offset; + while ((offset = ogg_sync_pageseek(&sync,&page)) != 0) { + if (offset > 0) { + goto synced; + } + position += -offset; + } + } +synced: + ogg_sync_clear(&sync); + if (fSeekable->Seek(position,SEEK_SET) < 0) { + TRACE("oggReader::Seek: Seek failed: error\n"); + return B_ERROR; + } + // output the values from where we regained sync + *frame = filePositionToFrame(position); + *time = filePositionToTime(position); return B_OK; }