diff options
author | Bastien Bouclet | 2018-07-21 07:57:23 +0200 |
---|---|---|
committer | Bastien Bouclet | 2018-07-21 08:02:40 +0200 |
commit | b8abe400850a23d12fe5cdc24d7106820d0f13fd (patch) | |
tree | 94efb61de59e68cb2cc137c79b5f8aa383e24134 | |
parent | af6034efcdf9ff12e037f03626caf2c89c11a6ed (diff) | |
download | scummvm-rg350-b8abe400850a23d12fe5cdc24d7106820d0f13fd.tar.gz scummvm-rg350-b8abe400850a23d12fe5cdc24d7106820d0f13fd.tar.bz2 scummvm-rg350-b8abe400850a23d12fe5cdc24d7106820d0f13fd.zip |
VIDEO: QT: Make sure all the edits are in the media bounds
In the Spanish version of Riven, the last edit of the video ogk.mov
ends one frame after the end of the media causing the playback to fail
without this check.
Fixes Trac#10633.
-rw-r--r-- | video/qt_decoder.cpp | 32 | ||||
-rw-r--r-- | video/qt_decoder.h | 1 |
2 files changed, 33 insertions, 0 deletions
diff --git a/video/qt_decoder.cpp b/video/qt_decoder.cpp index 4786e61227..bb9a92225b 100644 --- a/video/qt_decoder.cpp +++ b/video/qt_decoder.cpp @@ -285,6 +285,8 @@ Audio::SeekableAudioStream *QuickTimeDecoder::AudioTrackHandler::getSeekableAudi } QuickTimeDecoder::VideoTrackHandler::VideoTrackHandler(QuickTimeDecoder *decoder, Common::QuickTimeParser::Track *parent) : _decoder(decoder), _parent(parent) { + checkEditListBounds(); + _curEdit = 0; enterNewEditList(false); @@ -299,6 +301,36 @@ QuickTimeDecoder::VideoTrackHandler::VideoTrackHandler(QuickTimeDecoder *decoder _ditherFrame = 0; } +void QuickTimeDecoder::VideoTrackHandler::checkEditListBounds() { + // Check all the edit list entries are within the bounds of the media + // In the Spanish version of Riven, the last edit of the video ogk.mov + // ends one frame after the end of the media. + + uint32 offset = 0; + uint32 mediaDuration = _parent->mediaDuration * _decoder->_timeScale / _parent->timeScale; + + for (uint i = 0; i < _parent->editList.size(); i++) { + EditListEntry &edit = _parent->editList[i]; + + if (edit.mediaTime < 0) { + continue; // Ignore empty edits + } + + if ((uint32) edit.mediaTime > mediaDuration) { + // Check if the edit starts after the end of the media + // If so, mark it as empty so it is ignored + edit.mediaTime = -1; + } else if (edit.mediaTime + edit.trackDuration > mediaDuration) { + // Check if the edit ends after the end of the media + // If so, clip it so it fits in the media + edit.trackDuration = mediaDuration - edit.mediaTime; + } + + edit.timeOffset = offset; + offset += edit.trackDuration; + } +} + QuickTimeDecoder::VideoTrackHandler::~VideoTrackHandler() { if (_scaledSurface) { _scaledSurface->free(); diff --git a/video/qt_decoder.h b/video/qt_decoder.h index 5a6c5eebec..1ec8bd876d 100644 --- a/video/qt_decoder.h +++ b/video/qt_decoder.h @@ -174,6 +174,7 @@ private: uint32 getCurEditTrackDuration() const; bool atLastEdit() const; bool endOfCurEdit() const; + void checkEditListBounds(); }; }; |