From b8abe400850a23d12fe5cdc24d7106820d0f13fd Mon Sep 17 00:00:00 2001 From: Bastien Bouclet Date: Sat, 21 Jul 2018 07:57:23 +0200 Subject: 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. --- video/qt_decoder.cpp | 32 ++++++++++++++++++++++++++++++++ video/qt_decoder.h | 1 + 2 files changed, 33 insertions(+) (limited to 'video') 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(); }; }; -- cgit v1.2.3