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.
This commit is contained in:
Bastien Bouclet 2018-07-21 07:57:23 +02:00
parent af6034efcd
commit b8abe40085
2 changed files with 33 additions and 0 deletions

View file

@ -285,6 +285,8 @@ Audio::SeekableAudioStream *QuickTimeDecoder::AudioTrackHandler::getSeekableAudi
} }
QuickTimeDecoder::VideoTrackHandler::VideoTrackHandler(QuickTimeDecoder *decoder, Common::QuickTimeParser::Track *parent) : _decoder(decoder), _parent(parent) { QuickTimeDecoder::VideoTrackHandler::VideoTrackHandler(QuickTimeDecoder *decoder, Common::QuickTimeParser::Track *parent) : _decoder(decoder), _parent(parent) {
checkEditListBounds();
_curEdit = 0; _curEdit = 0;
enterNewEditList(false); enterNewEditList(false);
@ -299,6 +301,36 @@ QuickTimeDecoder::VideoTrackHandler::VideoTrackHandler(QuickTimeDecoder *decoder
_ditherFrame = 0; _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() { QuickTimeDecoder::VideoTrackHandler::~VideoTrackHandler() {
if (_scaledSurface) { if (_scaledSurface) {
_scaledSurface->free(); _scaledSurface->free();

View file

@ -174,6 +174,7 @@ private:
uint32 getCurEditTrackDuration() const; uint32 getCurEditTrackDuration() const;
bool atLastEdit() const; bool atLastEdit() const;
bool endOfCurEdit() const; bool endOfCurEdit() const;
void checkEditListBounds();
}; };
}; };