diff options
author | Bastien Bouclet | 2017-08-18 09:32:24 +0200 |
---|---|---|
committer | Bastien Bouclet | 2017-09-21 13:06:18 +0200 |
commit | 8547c89b86f0be02c4b3ef8e8adb4d5f96cf8432 (patch) | |
tree | dbe3fe398731a85a2d33440888613d87317397d8 | |
parent | 9127f5245fe10bc9de8efea5a9050d980f3ef241 (diff) | |
download | scummvm-rg350-8547c89b86f0be02c4b3ef8e8adb4d5f96cf8432.tar.gz scummvm-rg350-8547c89b86f0be02c4b3ef8e8adb4d5f96cf8432.tar.bz2 scummvm-rg350-8547c89b86f0be02c4b3ef8e8adb4d5f96cf8432.zip |
VIDEO: Change QT edit list to a Common::Array
And fix an out of bounds acces when seeking to the end of a video.
Skipping samples is needed even when seeking through silent edits
because a silent stream is queued for those.
Fixes #10219.
-rw-r--r-- | audio/decoders/quicktime.cpp | 9 | ||||
-rw-r--r-- | audio/midiparser_qt.cpp | 2 | ||||
-rw-r--r-- | common/quicktime.cpp | 16 | ||||
-rw-r--r-- | common/quicktime.h | 3 | ||||
-rw-r--r-- | video/qt_decoder.cpp | 6 |
5 files changed, 15 insertions, 21 deletions
diff --git a/audio/decoders/quicktime.cpp b/audio/decoders/quicktime.cpp index ff87e7a9f8..b8eccb664b 100644 --- a/audio/decoders/quicktime.cpp +++ b/audio/decoders/quicktime.cpp @@ -299,7 +299,7 @@ int QuickTimeAudioDecoder::QuickTimeAudioTrack::readBuffer(int16 *buffer, const } bool QuickTimeAudioDecoder::QuickTimeAudioTrack::allDataRead() const { - return _curEdit == _parentTrack->editCount; + return _curEdit == _parentTrack->editList.size(); } bool QuickTimeAudioDecoder::QuickTimeAudioTrack::endOfData() const { @@ -314,7 +314,7 @@ bool QuickTimeAudioDecoder::QuickTimeAudioTrack::seek(const Timestamp &where) { if (where >= getLength()) { // We're done - _curEdit = _parentTrack->editCount; + _curEdit = _parentTrack->editList.size(); return true; } @@ -324,8 +324,7 @@ bool QuickTimeAudioDecoder::QuickTimeAudioTrack::seek(const Timestamp &where) { // Now queue up some audio and skip whatever we need to skip Timestamp samplesToSkip = where.convertToFramerate(getRate()) - getCurrentTrackTime(); queueAudio(); - if (_parentTrack->editList[_curEdit].mediaTime != -1) - skipSamples(samplesToSkip, _queue); + skipSamples(samplesToSkip, _queue); return true; } @@ -427,7 +426,7 @@ void QuickTimeAudioDecoder::QuickTimeAudioTrack::findEdit(const Timestamp &posit // as the position is >= to the edit's start time, it is considered to be in that // edit. seek() already figured out if we reached the last edit, so we don't need // to handle that case here. - for (_curEdit = 0; _curEdit < _parentTrack->editCount - 1; _curEdit++) { + for (_curEdit = 0; _curEdit < _parentTrack->editList.size() - 1; _curEdit++) { Timestamp nextEditTime(0, _parentTrack->editList[_curEdit + 1].timeOffset, _decoder->_timeScale); if (position < nextEditTime) break; diff --git a/audio/midiparser_qt.cpp b/audio/midiparser_qt.cpp index b97ea56df5..3078be9186 100644 --- a/audio/midiparser_qt.cpp +++ b/audio/midiparser_qt.cpp @@ -423,7 +423,7 @@ void MidiParser_QT::initFromContainerTracks() { if (tracks[i]->codecType == CODEC_TYPE_MIDI) { assert(tracks[i]->sampleDescs.size() == 1); - if (tracks[i]->editCount != 1) + if (tracks[i]->editList.size() != 1) warning("Unhandled QuickTime MIDI edit lists, things may go awry"); MIDITrackInfo trackInfo; diff --git a/common/quicktime.cpp b/common/quicktime.cpp index 76880e1016..ecbf021e45 100644 --- a/common/quicktime.cpp +++ b/common/quicktime.cpp @@ -124,9 +124,8 @@ void QuickTimeParser::init() { // If this track doesn't have an edit list (like in MPEG-4 files), // fake an entry of one edit that takes up the entire sample - if (_tracks[i]->editCount == 0) { - _tracks[i]->editCount = 1; - _tracks[i]->editList = new EditListEntry[1]; + if (_tracks[i]->editList.size() == 0) { + _tracks[i]->editList.resize(1); _tracks[i]->editList[0].trackDuration = _tracks[i]->duration; _tracks[i]->editList[0].timeOffset = 0; _tracks[i]->editList[0].mediaTime = 0; @@ -434,14 +433,14 @@ int QuickTimeParser::readELST(Atom atom) { _fd->readByte(); // version _fd->readByte(); _fd->readByte(); _fd->readByte(); // flags - track->editCount = _fd->readUint32BE(); - track->editList = new EditListEntry[track->editCount]; + uint32 editCount = _fd->readUint32BE(); + track->editList.resize(editCount); - debug(2, "Track %d edit list count: %d", _tracks.size() - 1, track->editCount); + debug(2, "Track %d edit list count: %d", _tracks.size() - 1, editCount); uint32 offset = 0; - for (uint32 i = 0; i < track->editCount; i++) { + for (uint32 i = 0; i < editCount; i++) { track->editList[i].trackDuration = _fd->readUint32BE(); track->editList[i].mediaTime = _fd->readSint32BE(); track->editList[i].mediaRate = Rational(_fd->readUint32BE(), 0x10000); @@ -836,8 +835,6 @@ QuickTimeParser::Track::Track() { width = 0; height = 0; codecType = CODEC_TYPE_MOV_OTHER; - editCount = 0; - editList = 0; frameCount = 0; duration = 0; startTime = 0; @@ -850,7 +847,6 @@ QuickTimeParser::Track::~Track() { delete[] sampleToChunk; delete[] sampleSizes; delete[] keyframes; - delete[] editList; for (uint32 i = 0; i < sampleDescs.size(); i++) delete sampleDescs[i]; diff --git a/common/quicktime.h b/common/quicktime.h index f74d1ed0d9..3f82fc0431 100644 --- a/common/quicktime.h +++ b/common/quicktime.h @@ -150,8 +150,7 @@ protected: Array<SampleDesc *> sampleDescs; - uint32 editCount; - EditListEntry *editList; + Common::Array<EditListEntry> editList; uint32 frameCount; uint32 duration; diff --git a/video/qt_decoder.cpp b/video/qt_decoder.cpp index f2acbb1282..70f0ae43da 100644 --- a/video/qt_decoder.cpp +++ b/video/qt_decoder.cpp @@ -507,7 +507,7 @@ bool QuickTimeDecoder::VideoTrackHandler::setReverse(bool reverse) { _reversed = reverse; if (_reversed) { - if (_parent->editCount != 1) { + if (_parent->editList.size() != 1) { // TODO: Myst's holo.mov needs this :( warning("Can only set reverse without edits"); return false; @@ -517,7 +517,7 @@ bool QuickTimeDecoder::VideoTrackHandler::setReverse(bool reverse) { // If we're at the end of the video, go to the penultimate edit. // The current frame is set to one beyond the last frame here; // one "past" the currently displayed frame. - _curEdit = _parent->editCount - 1; + _curEdit = _parent->editList.size() - 1; _curFrame = _parent->frameCount; _nextFrameStartTime = _parent->editList[_curEdit].trackDuration + _parent->editList[_curEdit].timeOffset; } else if (_durationOverride >= 0) { @@ -769,7 +769,7 @@ uint32 QuickTimeDecoder::VideoTrackHandler::getCurEditTrackDuration() const { } bool QuickTimeDecoder::VideoTrackHandler::atLastEdit() const { - return _curEdit == _parent->editCount; + return _curEdit == _parent->editList.size(); } bool QuickTimeDecoder::VideoTrackHandler::endOfCurEdit() const { |