aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Bouclet2018-07-21 07:57:23 +0200
committerBastien Bouclet2018-07-21 08:02:40 +0200
commitb8abe400850a23d12fe5cdc24d7106820d0f13fd (patch)
tree94efb61de59e68cb2cc137c79b5f8aa383e24134
parentaf6034efcdf9ff12e037f03626caf2c89c11a6ed (diff)
downloadscummvm-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.cpp32
-rw-r--r--video/qt_decoder.h1
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();
};
};