aboutsummaryrefslogtreecommitdiff
path: root/video
diff options
context:
space:
mode:
authorMatthew Hoops2015-01-16 01:51:31 -0500
committerMatthew Hoops2015-01-20 20:10:58 -0500
commita59f5db505ffce9567c3bc8adf30d2f843910d65 (patch)
treea27192eeca102970ab0e01f205b89f1b755bb80b /video
parentdfe04491c1d8ecb45f4952af96c9d73e9e654a32 (diff)
downloadscummvm-rg350-a59f5db505ffce9567c3bc8adf30d2f843910d65.tar.gz
scummvm-rg350-a59f5db505ffce9567c3bc8adf30d2f843910d65.tar.bz2
scummvm-rg350-a59f5db505ffce9567c3bc8adf30d2f843910d65.zip
VIDEO: Fix timing with frames going past the edit boundary
Diffstat (limited to 'video')
-rw-r--r--video/qt_decoder.cpp48
-rw-r--r--video/qt_decoder.h1
2 files changed, 34 insertions, 15 deletions
diff --git a/video/qt_decoder.cpp b/video/qt_decoder.cpp
index 0a29692948..2012e369e7 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 7e87d21ae7..aa16ffc4db 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;
};
};