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