From 2313f3091a07736077bc40615590932acf0044d0 Mon Sep 17 00:00:00 2001 From: Bart van Strien Date: Tue, 5 Jan 2016 17:48:44 +0100 Subject: [PATCH] Improve seeking, hopefully fix hangs on shutdown Instead of returning the frame past our target, now return the frame for our target. Also defer to rewind implictly, rather than explicitly. Lastly, detect seeking past the end of the stream, and set EOS appropriately. --- src/modules/video/theora/VideoStream.cpp | 27 +++++++++++++++--------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/modules/video/theora/VideoStream.cpp b/src/modules/video/theora/VideoStream.cpp index c784d3f7f..326360aa8 100644 --- a/src/modules/video/theora/VideoStream.cpp +++ b/src/modules/video/theora/VideoStream.cpp @@ -266,13 +266,19 @@ void VideoStream::rewind() void VideoStream::seekDecoder(double target) { + if (target < 0.01) + { + rewind(); + return; + } + double low = 0; double high = file->getSize(); while (high-low > 0.0001) { // Determine our next binary search position - double pos = (high-low)/2+low; + double pos = (high+low)/2; file->seek(pos); // Break sync @@ -280,12 +286,18 @@ void VideoStream::seekDecoder(double target) ogg_sync_pageseek(&sync, &page); // Read a packet - readPacket(true); + readPacket(false); + if (eos) + return; // Determine if this is the right place double curTime = th_granule_time(decoder, packet.granulepos); - if (curTime > target && th_granule_time(decoder, packet.granulepos-1) < target) - break; + double nextTime = th_granule_time(decoder, packet.granulepos+1); + + if (curTime == -1) + continue; // Invalid granule position (magic?) + else if (curTime <= target && nextTime > target) + break; // the current frame should be displaying right now else if (curTime > target) high = pos; else @@ -306,12 +318,7 @@ void VideoStream::threadedFillBackBuffer(double dt) // Seeking backwards if (position < lastFrame) - { - if (position < 0.01) - rewind(); - else - seekDecoder(position); - } + seekDecoder(position); // If we're at the end of the stream, or if we're displaying the right frame // stop here