diff options
author | Matthew Hoops | 2015-01-16 01:51:31 -0500 |
---|---|---|
committer | Matthew Hoops | 2015-01-20 20:10:58 -0500 |
commit | a59f5db505ffce9567c3bc8adf30d2f843910d65 (patch) | |
tree | a27192eeca102970ab0e01f205b89f1b755bb80b /video | |
parent | dfe04491c1d8ecb45f4952af96c9d73e9e654a32 (diff) | |
download | scummvm-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.cpp | 48 | ||||
-rw-r--r-- | video/qt_decoder.h | 1 |
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; }; }; |