[Scummvm-cvs-logs] scummvm master -> cb25b7b5eea53769fc378dc8ae3d360eca685e74

clone2727 clone2727 at gmail.com
Wed Jan 21 02:34:51 CET 2015


This automated email contains information about 6 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
a59f5db505 VIDEO: Fix timing with frames going past the edit boundary
aaf4d38a56 VIDEO: Round the edit time offset instead of truncating it
8e2a438dd9 VIDEO: Fix edit frame calculation
1a0f104acf VIDEO: Fix potential off-by-one frame time after seek
7d1ee5563a VIDEO: Remove the "-1" edit hack
cb25b7b5ee VIDEO: Make the QuickTime code error out again if the frame data can't be found


Commit: a59f5db505ffce9567c3bc8adf30d2f843910d65
    https://github.com/scummvm/scummvm/commit/a59f5db505ffce9567c3bc8adf30d2f843910d65
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2015-01-20T20:10:58-05:00

Commit Message:
VIDEO: Fix timing with frames going past the edit boundary

Changed paths:
    video/qt_decoder.cpp
    video/qt_decoder.h



diff --git a/video/qt_decoder.cpp b/video/qt_decoder.cpp
index 0a29692..2012e36 100644
--- a/video/qt_decoder.cpp
+++ b/video/qt_decoder.cpp
@@ -397,8 +397,22 @@ uint32 QuickTimeDecoder::VideoTrackHandler::getNextFrameStartTime() const {
 	if (endOfTrack())
 		return 0;
 
-	// Convert to milliseconds so the tracks can be compared
-	return getRateAdjustedFrameTime() * 1000 / _parent->timeScale;
+	Audio::Timestamp frameTime(0, getRateAdjustedFrameTime(), _parent->timeScale);
+
+	// Check if the frame goes beyond the end of the edit. In that case, the next frame
+	// should really be when we cross the edit boundary.
+	if (_reversed) {
+		Audio::Timestamp editStartTime(0, _parent->editList[_curEdit].timeOffset, _decoder->_timeScale);
+		if (frameTime < editStartTime)
+			return editStartTime.msecs();
+	} else {
+		Audio::Timestamp nextEditStartTime(0, _parent->editList[_curEdit].timeOffset + _parent->editList[_curEdit].trackDuration, _decoder->_timeScale);
+		if (frameTime > nextEditStartTime)
+			return nextEditStartTime.msecs();
+	}
+
+	// Not past an edit boundary, so the frame time is what should be used
+	return frameTime.msecs();
 }
 
 const Graphics::Surface *QuickTimeDecoder::VideoTrackHandler::decodeNextFrame() {
@@ -422,6 +436,16 @@ const Graphics::Surface *QuickTimeDecoder::VideoTrackHandler::decodeNextFrame()
 			bufferNextFrame();
 	}
 
+	// Update the edit list, if applicable
+	if (endOfCurEdit()) {
+		_curEdit++;
+
+		if (atLastEdit())
+			return 0;
+
+		enterNewEditList(true);
+	}
+
 	const Graphics::Surface *frame = bufferNextFrame();
 
 	if (_reversed) {
@@ -443,16 +467,6 @@ const Graphics::Surface *QuickTimeDecoder::VideoTrackHandler::decodeNextFrame()
 		} else {
 			_nextFrameStartTime += getFrameDuration();
 		}
-
-		// Update the edit list, if applicable
-		// HACK: We're also accepting the time minus one because edit lists
-		// aren't as accurate as one would hope.
-		if (!atLastEdit() && getRateAdjustedFrameTime() >= getCurEditTimeOffset() + getCurEditTrackDuration() - 1) {
-			_curEdit++;
-
-			if (!atLastEdit())
-				enterNewEditList(true);
-		}
 	}
 
 	if (frame && (_parent->scaleFactorX != 1 || _parent->scaleFactorY != 1)) {
@@ -497,9 +511,7 @@ bool QuickTimeDecoder::VideoTrackHandler::setReverse(bool reverse) {
 		}
 	} else {
 		// Update the edit list, if applicable
-		// HACK: We're also accepting the time minus one because edit lists
-		// aren't as accurate as one would hope.
-		if (!atLastEdit() && getRateAdjustedFrameTime() >= getCurEditTimeOffset() + getCurEditTrackDuration() - 1) {
+		if (!atLastEdit() && endOfCurEdit()) {
 			_curEdit++;
 
 			if (atLastEdit())
@@ -739,4 +751,10 @@ bool QuickTimeDecoder::VideoTrackHandler::atLastEdit() const {
 	return _curEdit == _parent->editCount;
 }
 
+bool QuickTimeDecoder::VideoTrackHandler::endOfCurEdit() const {
+	// HACK: We're also accepting the time minus one because edit lists
+	// aren't as accurate as one would hope.
+	return getRateAdjustedFrameTime() >= getCurEditTimeOffset() + getCurEditTrackDuration() - 1;
+}
+
 } // End of namespace Video
diff --git a/video/qt_decoder.h b/video/qt_decoder.h
index 7e87d21..aa16ffc 100644
--- a/video/qt_decoder.h
+++ b/video/qt_decoder.h
@@ -166,6 +166,7 @@ private:
 		uint32 getCurEditTimeOffset() const;
 		uint32 getCurEditTrackDuration() const;
 		bool atLastEdit() const;
+		bool endOfCurEdit() const;
 	};
 };
 


Commit: aaf4d38a56219c63ee41638e93ef83f66f309b23
    https://github.com/scummvm/scummvm/commit/aaf4d38a56219c63ee41638e93ef83f66f309b23
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2015-01-20T20:10:58-05:00

Commit Message:
VIDEO: Round the edit time offset instead of truncating it

Allows for the KQ6 Mac intro to play without the edit "-1" hack

Changed paths:
    video/qt_decoder.cpp



diff --git a/video/qt_decoder.cpp b/video/qt_decoder.cpp
index 2012e36..1410279 100644
--- a/video/qt_decoder.cpp
+++ b/video/qt_decoder.cpp
@@ -721,7 +721,12 @@ const Graphics::Surface *QuickTimeDecoder::VideoTrackHandler::bufferNextFrame()
 
 uint32 QuickTimeDecoder::VideoTrackHandler::getRateAdjustedFrameTime() const {
 	// Figure out what time the next frame is at taking the edit list rate into account
-	uint32 convertedTime = (Common::Rational(_nextFrameStartTime - getCurEditTimeOffset()) / _parent->editList[_curEdit].mediaRate).toInt();
+	Common::Rational offsetFromEdit = Common::Rational(_nextFrameStartTime - getCurEditTimeOffset()) / _parent->editList[_curEdit].mediaRate;
+	uint32 convertedTime = offsetFromEdit.toInt();
+
+	if ((offsetFromEdit.getNumerator() % offsetFromEdit.getDenominator()) > (offsetFromEdit.getDenominator() / 2))
+		convertedTime++;
+
 	return convertedTime + getCurEditTimeOffset();
 }
 


Commit: 8e2a438dd9cf8d2c9b6413cfb4cd5e6b81a3c4d0
    https://github.com/scummvm/scummvm/commit/8e2a438dd9cf8d2c9b6413cfb4cd5e6b81a3c4d0
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2015-01-20T20:10:59-05:00

Commit Message:
VIDEO: Fix edit frame calculation

An edit that seeks to the last frame of the media would not show

Changed paths:
    video/qt_decoder.cpp



diff --git a/video/qt_decoder.cpp b/video/qt_decoder.cpp
index 1410279..ee2bd02 100644
--- a/video/qt_decoder.cpp
+++ b/video/qt_decoder.cpp
@@ -629,30 +629,32 @@ void QuickTimeDecoder::VideoTrackHandler::enterNewEditList(bool bufferFrames) {
 	if (atLastEdit())
 		return;
 
+	uint32 mediaTime = _parent->editList[_curEdit].mediaTime;
 	uint32 frameNum = 0;
-	bool done = false;
 	uint32 totalDuration = 0;
-	uint32 prevDuration = 0;
+	_durationOverride = -1;
 
 	// Track down where the mediaTime is in the media
 	// This is basically time -> frame mapping
 	// Note that this code uses first frame = 0
-	for (int32 i = 0; i < _parent->timeToSampleCount && !done; i++) {
-		for (int32 j = 0; j < _parent->timeToSample[i].count; j++) {
-			if (totalDuration == (uint32)_parent->editList[_curEdit].mediaTime) {
-				done = true;
-				prevDuration = totalDuration;
-				break;
-			} else if (totalDuration > (uint32)_parent->editList[_curEdit].mediaTime) {
-				done = true;
-				frameNum--;
-				break;
-			}
+	for (int32 i = 0; i < _parent->timeToSampleCount; i++) {
+		uint32 duration = _parent->timeToSample[i].count * _parent->timeToSample[i].duration;
+
+		if (totalDuration + duration >= mediaTime) {
+			uint32 frameInc = (mediaTime - totalDuration) / _parent->timeToSample[i].duration;
+			frameNum += frameInc;
+			totalDuration += frameInc * _parent->timeToSample[i].duration;
 
-			prevDuration = totalDuration;
-			totalDuration += _parent->timeToSample[i].duration;
-			frameNum++;
+			// If we didn't get to the exact media time, mark an override for
+			// the time.
+			if (totalDuration != mediaTime)
+				_durationOverride = totalDuration + _parent->timeToSample[i].duration - mediaTime;
+
+			break;
 		}
+
+		frameNum += _parent->timeToSample[i].count;
+		totalDuration += duration;
 	}
 
 	if (bufferFrames) {
@@ -668,12 +670,6 @@ void QuickTimeDecoder::VideoTrackHandler::enterNewEditList(bool bufferFrames) {
 	}
 
 	_nextFrameStartTime = getCurEditTimeOffset();
-
-	// Set an override for the duration since we came up in-between two frames
-	if (prevDuration != totalDuration)
-		_durationOverride = totalDuration - prevDuration;
-	else
-		_durationOverride = -1;
 }
 
 const Graphics::Surface *QuickTimeDecoder::VideoTrackHandler::bufferNextFrame() {


Commit: 1a0f104acfd465fa577dd14a43b368f92794a9d0
    https://github.com/scummvm/scummvm/commit/1a0f104acfd465fa577dd14a43b368f92794a9d0
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2015-01-20T20:10:59-05:00

Commit Message:
VIDEO: Fix potential off-by-one frame time after seek

If seeking to the final frame of an edit, _nextFrameStartTime wouldn't be adjust properly and would wrongly say that it's at the end of the edit. This never affected anything because of the edit "-1" hack.

Changed paths:
    video/qt_decoder.cpp
    video/qt_decoder.h



diff --git a/video/qt_decoder.cpp b/video/qt_decoder.cpp
index ee2bd02..8ce10d9 100644
--- a/video/qt_decoder.cpp
+++ b/video/qt_decoder.cpp
@@ -286,7 +286,6 @@ QuickTimeDecoder::VideoTrackHandler::VideoTrackHandler(QuickTimeDecoder *decoder
 	_curEdit = 0;
 	enterNewEditList(false);
 
-	_holdNextFrameStartTime = false;
 	_curFrame = -1;
 	_durationOverride = -1;
 	_scaledSurface = 0;
@@ -347,15 +346,12 @@ bool QuickTimeDecoder::VideoTrackHandler::seek(const Audio::Timestamp &requested
 		}
 	}
 
-	// All that's left is to figure out what our starting time is going to be
-	// Compare the starting point for the frame to where we need to be
-	_holdNextFrameStartTime = getRateAdjustedFrameTime() != (uint32)time.totalNumberOfFrames();
-
-	// If we went past the time, go back a frame. _curFrame before this point is at the frame
-	// that should be displayed. This adjustment ensures it is on the frame before the one that
-	// should be displayed.
-	if (_holdNextFrameStartTime)
+	// Check if we went past, then adjust the frame times
+	if (getRateAdjustedFrameTime() != (uint32)time.totalNumberOfFrames()) {
 		_curFrame--;
+		_durationOverride = getRateAdjustedFrameTime() - time.totalNumberOfFrames();
+		_nextFrameStartTime = time.totalNumberOfFrames();
+	}
 
 	if (_reversed) {
 		// Call setReverse again to update
@@ -449,20 +445,18 @@ const Graphics::Surface *QuickTimeDecoder::VideoTrackHandler::decodeNextFrame()
 	const Graphics::Surface *frame = bufferNextFrame();
 
 	if (_reversed) {
-		if (_holdNextFrameStartTime) {
-			// Don't set the next frame start time here; we just did a seek
-			_holdNextFrameStartTime = false;
+		if (_durationOverride >= 0) {
+			// Use our own duration overridden from a media seek
+			_nextFrameStartTime -= _durationOverride;
+			_durationOverride = -1;
 		} else {
 			// Just need to subtract the time
 			_nextFrameStartTime -= getFrameDuration();
 		}
 	} else {
-		if (_holdNextFrameStartTime) {
-			// Don't set the next frame start time here; we just did a seek
-			_holdNextFrameStartTime = false;
-		} else if (_durationOverride >= 0) {
-			// Use our own duration from the edit list calculation
-			_nextFrameStartTime += _durationOverride;
+		if (_durationOverride >= 0) {
+			// Use our own duration overridden from a media seek
+ 			_nextFrameStartTime += _durationOverride;
 			_durationOverride = -1;
 		} else {
 			_nextFrameStartTime += getFrameDuration();
@@ -499,11 +493,11 @@ bool QuickTimeDecoder::VideoTrackHandler::setReverse(bool reverse) {
 			_curEdit = _parent->editCount - 1;
 			_curFrame = _parent->frameCount;
 			_nextFrameStartTime = _parent->editList[_curEdit].trackDuration + _parent->editList[_curEdit].timeOffset;
-		} else if (_holdNextFrameStartTime) {
-			// We just seeked, so "pivot" around the frame that should be displayed
-			_curFrame++;
-			_nextFrameStartTime -= getFrameDuration();
-			_curFrame++;
+		} else if (_durationOverride >= 0) {
+			// We just had a media seek, so "pivot" around the frame that should
+			// be displayed.
+			_curFrame += 2;
+			_nextFrameStartTime += _durationOverride;
 		} else {
 			// We need to put _curFrame to be the one after the one that should be displayed.
 			// Since we're on the frame that should be displaying right now, add one.
@@ -518,11 +512,12 @@ bool QuickTimeDecoder::VideoTrackHandler::setReverse(bool reverse) {
 				return true;
 		}
 
-		if (_holdNextFrameStartTime) {
-			// We just seeked, so "pivot" around the frame that should be displayed
+		if (_durationOverride >= 0) {
+			// We just had a media seek, so "pivot" around the frame that should
+			// be displayed.
 			_curFrame--;
-			_nextFrameStartTime += getFrameDuration();
-		}
+			_nextFrameStartTime -= _durationOverride;
+ 		}
 
 		// We need to put _curFrame to be the one before the one that should be displayed.
 		// Since we're on the frame that should be displaying right now, subtract one.
diff --git a/video/qt_decoder.h b/video/qt_decoder.h
index aa16ffc..99ac9ff 100644
--- a/video/qt_decoder.h
+++ b/video/qt_decoder.h
@@ -151,7 +151,6 @@ private:
 		int32 _curFrame;
 		uint32 _nextFrameStartTime;
 		Graphics::Surface *_scaledSurface;
-		bool _holdNextFrameStartTime;
 		int32 _durationOverride;
 		const byte *_curPalette;
 		mutable bool _dirtyPalette;


Commit: 7d1ee5563a7168843b9f6400010ddd9983abebbc
    https://github.com/scummvm/scummvm/commit/7d1ee5563a7168843b9f6400010ddd9983abebbc
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2015-01-20T20:10:59-05:00

Commit Message:
VIDEO: Remove the "-1" edit hack

With the previous commits' fixes, it's no longer needed

Changed paths:
    video/qt_decoder.cpp



diff --git a/video/qt_decoder.cpp b/video/qt_decoder.cpp
index 8ce10d9..08d7620 100644
--- a/video/qt_decoder.cpp
+++ b/video/qt_decoder.cpp
@@ -748,9 +748,9 @@ bool QuickTimeDecoder::VideoTrackHandler::atLastEdit() const {
 }
 
 bool QuickTimeDecoder::VideoTrackHandler::endOfCurEdit() const {
-	// HACK: We're also accepting the time minus one because edit lists
-	// aren't as accurate as one would hope.
-	return getRateAdjustedFrameTime() >= getCurEditTimeOffset() + getCurEditTrackDuration() - 1;
+	// We're at the end of the edit once the next frame's time would
+	// bring us past the end of the edit.
+	return getRateAdjustedFrameTime() >= getCurEditTimeOffset() + getCurEditTrackDuration();
 }
 
 } // End of namespace Video


Commit: cb25b7b5eea53769fc378dc8ae3d360eca685e74
    https://github.com/scummvm/scummvm/commit/cb25b7b5eea53769fc378dc8ae3d360eca685e74
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2015-01-20T20:10:59-05:00

Commit Message:
VIDEO: Make the QuickTime code error out again if the frame data can't be found

The case shouldn't actually ever happen; the off-by-one bug when seeking to the last frame of the media (in an edit) caused this originally

Changed paths:
    video/qt_decoder.cpp



diff --git a/video/qt_decoder.cpp b/video/qt_decoder.cpp
index 08d7620..9b77ef7 100644
--- a/video/qt_decoder.cpp
+++ b/video/qt_decoder.cpp
@@ -566,10 +566,8 @@ Common::SeekableReadStream *QuickTimeDecoder::VideoTrackHandler::getNextFramePac
 		}
 	}
 
-	if (actualChunk < 0) {
-		warning("Could not find data for frame %d", _curFrame);
-		return 0;
-	}
+	if (actualChunk < 0)
+		error("Could not find data for frame %d", _curFrame);
 
 	// Next seek to that frame
 	Common::SeekableReadStream *stream = _decoder->_fd;






More information about the Scummvm-git-logs mailing list