Browse Source

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.
Bart van Strien 9 years ago
parent
commit
2313f3091a
1 changed files with 17 additions and 10 deletions
  1. 17 10
      src/modules/video/theora/VideoStream.cpp

+ 17 - 10
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