diff options
author | Matthew Hoops | 2012-10-12 13:36:23 -0400 |
---|---|---|
committer | Matthew Hoops | 2012-10-12 13:36:23 -0400 |
commit | 075d0b4812f36781c690d8fe645ad2d802ea30d3 (patch) | |
tree | 4e3e9c2c6dd66d62a670bd1144fb173955da4585 /video/qt_decoder.cpp | |
parent | 2b55837650c4229dc3d75b660cecfc7a3292e5e0 (diff) | |
download | scummvm-rg350-075d0b4812f36781c690d8fe645ad2d802ea30d3.tar.gz scummvm-rg350-075d0b4812f36781c690d8fe645ad2d802ea30d3.tar.bz2 scummvm-rg350-075d0b4812f36781c690d8fe645ad2d802ea30d3.zip |
VIDEO: Fix choosing of the correct edit when seeking
Previously it could be off-by-one
Diffstat (limited to 'video/qt_decoder.cpp')
-rw-r--r-- | video/qt_decoder.cpp | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/video/qt_decoder.cpp b/video/qt_decoder.cpp index b4dab9ddfb..ca4d87f68f 100644 --- a/video/qt_decoder.cpp +++ b/video/qt_decoder.cpp @@ -348,18 +348,27 @@ bool QuickTimeDecoder::VideoTrackHandler::endOfTrack() const { } bool QuickTimeDecoder::VideoTrackHandler::seek(const Audio::Timestamp &requestedTime) { - // First, figure out what edit we're in - Audio::Timestamp time = requestedTime.convertToFramerate(_parent->timeScale); - - // Continue until we get to where we need to be + uint32 convertedFrames = requestedTime.convertToFramerate(_decoder->_timeScale).totalNumberOfFrames(); for (_curEdit = 0; !endOfTrack(); _curEdit++) - if ((uint32)time.totalNumberOfFrames() >= getCurEditTimeOffset() && (uint32)time.totalNumberOfFrames() < getCurEditTimeOffset() + getCurEditTrackDuration()) + if (convertedFrames >= _parent->editList[_curEdit].timeOffset && convertedFrames < _parent->editList[_curEdit].timeOffset + _parent->editList[_curEdit].trackDuration) break; - // This track is done + // If we did reach the end of the track, break out if (endOfTrack()) return true; + // If this track is in an empty edit, position us at the next non-empty + // edit. There's nothing else to do after this. + if (_parent->editList[_curEdit].mediaTime == -1) { + while (!endOfTrack() && _parent->editList[_curEdit].mediaTime == -1) + _curEdit++; + + if (!endOfTrack()) + enterNewEditList(true); + + return true; + } + enterNewEditList(false); // One extra check for the end of a track @@ -367,6 +376,7 @@ bool QuickTimeDecoder::VideoTrackHandler::seek(const Audio::Timestamp &requested return true; // Now we're in the edit and need to figure out what frame we need + Audio::Timestamp time = requestedTime.convertToFramerate(_parent->timeScale); while (getRateAdjustedFrameTime() < (uint32)time.totalNumberOfFrames()) { _curFrame++; if (_durationOverride >= 0) { @@ -557,6 +567,8 @@ void QuickTimeDecoder::VideoTrackHandler::enterNewEditList(bool bufferFrames) { uint32 prevDuration = 0; // 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) { @@ -577,10 +589,13 @@ void QuickTimeDecoder::VideoTrackHandler::enterNewEditList(bool bufferFrames) { if (bufferFrames) { // Track down the keyframe + // Then decode until the frame before target _curFrame = findKeyFrame(frameNum) - 1; while (_curFrame < (int32)frameNum - 1) bufferNextFrame(); } else { + // Since frameNum is the frame that needs to be displayed + // we'll set _curFrame to be the "last frame displayed" _curFrame = frameNum - 1; } @@ -589,6 +604,8 @@ void QuickTimeDecoder::VideoTrackHandler::enterNewEditList(bool bufferFrames) { // 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() { |