mirror of
https://github.com/libretro/scummvm.git
synced 2025-04-02 23:01:42 +00:00
VIDEO: Fix QuickTime decoding of edits with mediaTime
QuickTimeDecoder has a bug which causes the mediaTime offset to be ignored when a track begins with an empty edit and is followed by an edit with a non-zero mediaTime. This causes the KQ6 Mac opening movie to start several tracks at unintended frames (they're never supposed to be displayed) and the intended frames at the end of the edit to never be displayed. (Bug #11085)
This commit is contained in:
parent
6e3403464b
commit
dcd537337b
@ -297,9 +297,9 @@ QuickTimeDecoder::VideoTrackHandler::VideoTrackHandler(QuickTimeDecoder *decoder
|
||||
}
|
||||
|
||||
_curEdit = 0;
|
||||
enterNewEditListEntry(false);
|
||||
|
||||
_curFrame = -1;
|
||||
enterNewEditListEntry(true); // might set _curFrame
|
||||
|
||||
_durationOverride = -1;
|
||||
_scaledSurface = 0;
|
||||
_curPalette = 0;
|
||||
@ -514,6 +514,9 @@ const Graphics::Surface *QuickTimeDecoder::VideoTrackHandler::decodeNextFrame()
|
||||
return 0;
|
||||
|
||||
enterNewEditListEntry(true);
|
||||
|
||||
if (isEmptyEdit())
|
||||
return 0;
|
||||
}
|
||||
|
||||
const Graphics::Surface *frame = bufferNextFrame();
|
||||
@ -697,14 +700,22 @@ uint32 QuickTimeDecoder::VideoTrackHandler::findKeyFrame(uint32 frame) const {
|
||||
return frame;
|
||||
}
|
||||
|
||||
void QuickTimeDecoder::VideoTrackHandler::enterNewEditListEntry(bool bufferFrames) {
|
||||
// Bypass all empty edit lists first
|
||||
while (!atLastEdit() && _parent->editList[_curEdit].mediaTime == -1)
|
||||
_curEdit++;
|
||||
bool QuickTimeDecoder::VideoTrackHandler::isEmptyEdit() const {
|
||||
return (_parent->editList[_curEdit].mediaTime == -1);
|
||||
}
|
||||
|
||||
void QuickTimeDecoder::VideoTrackHandler::enterNewEditListEntry(bool bufferFrames) {
|
||||
if (atLastEdit())
|
||||
return;
|
||||
|
||||
// if this is an empty edit then the only thing to do is set the
|
||||
// time for the next frame, which is the duration of this edit.
|
||||
if (isEmptyEdit()) {
|
||||
_curFrame = -1;
|
||||
_nextFrameStartTime = getCurEditTimeOffset() + getCurEditTrackDuration();
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 mediaTime = _parent->editList[_curEdit].mediaTime;
|
||||
uint32 frameNum = 0;
|
||||
uint32 totalDuration = 0;
|
||||
@ -792,8 +803,12 @@ const Graphics::Surface *QuickTimeDecoder::VideoTrackHandler::bufferNextFrame()
|
||||
}
|
||||
|
||||
uint32 QuickTimeDecoder::VideoTrackHandler::getRateAdjustedFrameTime() const {
|
||||
// Figure out what time the next frame is at taking the edit list rate into account
|
||||
Common::Rational offsetFromEdit = Common::Rational(_nextFrameStartTime - getCurEditTimeOffset()) / _parent->editList[_curEdit].mediaRate;
|
||||
// Figure out what time the next frame is at taking the edit list rate into account,
|
||||
// unless this is an empty edit, in which case the rate isn't applicable.
|
||||
Common::Rational offsetFromEdit = Common::Rational(_nextFrameStartTime - getCurEditTimeOffset());
|
||||
if (!isEmptyEdit()) {
|
||||
offsetFromEdit /= _parent->editList[_curEdit].mediaRate;
|
||||
}
|
||||
uint32 convertedTime = offsetFromEdit.toInt();
|
||||
|
||||
if ((offsetFromEdit.getNumerator() % offsetFromEdit.getDenominator()) > (offsetFromEdit.getDenominator() / 2))
|
||||
|
@ -171,6 +171,7 @@ private:
|
||||
Common::SeekableReadStream *getNextFramePacket(uint32 &descId);
|
||||
uint32 getCurFrameDuration(); // media time
|
||||
uint32 findKeyFrame(uint32 frame) const;
|
||||
bool isEmptyEdit() const;
|
||||
void enterNewEditListEntry(bool bufferFrames);
|
||||
const Graphics::Surface *bufferNextFrame();
|
||||
uint32 getRateAdjustedFrameTime() const; // media time
|
||||
|
Loading…
x
Reference in New Issue
Block a user