VIDEO: Fix reverse playback in AVIDecoder

This commit is contained in:
Paul Gilbert 2017-09-03 17:29:09 -04:00
parent aba431ca9b
commit 22e24d7c0b
2 changed files with 37 additions and 5 deletions

View File

@ -129,6 +129,23 @@ bool AVIDecoder::isSeekable() const {
return isVideoLoaded() && !_indexEntries.empty();
}
const Graphics::Surface *AVIDecoder::decodeNextFrame() {
// When playing in reverse, we need to seek to the correct prior frame
AVIVideoTrack *track = nullptr;
bool isReversed = false;
for (int idx = _videoTracks.size() - 1; idx >= 0; --idx) {
track = static_cast<AVIVideoTrack *>(_videoTracks[idx].track);
isReversed |= track->isReversed();
}
if (isReversed) {
Audio::Timestamp time = track->getFrameTime(getCurFrame());
seekIntern(time);
}
return VideoDecoder::decodeNextFrame();
}
const Graphics::Surface *AVIDecoder::decodeNextTransparency() {
if (!_transparencyTrack.track)
return nullptr;
@ -544,11 +561,6 @@ void AVIDecoder::handleNextPacket(TrackStatus &status) {
if (!isReversed) {
// Start us off in this position next time
status.chunkSearchOffset = _fileStream->pos();
} else {
// Seek to the prior frame
assert(videoTrack);
Audio::Timestamp time = videoTrack->getFrameTime(getCurFrame());
seekIntern(time);
}
}

View File

@ -75,6 +75,26 @@ public:
bool isRewindable() const { return true; }
bool isSeekable() const;
/**
* Decode the next frame into a surface and return the latter.
*
* A subclass may override this, but must still call this function. As an
* example, a subclass may do this to apply some global video scale to
* individual track's frame.
*
* Note that this will call readNextPacket() internally first before calling
* the next video track's decodeNextFrame() function.
*
* @return a surface containing the decoded frame, or 0
* @note Ownership of the returned surface stays with the VideoDecoder,
* hence the caller must *not* free it.
* @note this may return 0, in which case the last frame should be kept on screen
*/
virtual const Graphics::Surface *decodeNextFrame();
/**
* Decodes the next transparency track frame
*/
const Graphics::Surface *decodeNextTransparency();
protected:
// VideoDecoder API