diff options
author | Paul Gilbert | 2017-09-03 17:29:09 -0400 |
---|---|---|
committer | Paul Gilbert | 2017-09-03 17:29:09 -0400 |
commit | 22e24d7c0b78801d813294718d6a320fd46fc8d9 (patch) | |
tree | 263977c4c813d1f460a7a9af03c91875d17ba0f2 /video | |
parent | aba431ca9b4f5a78ed2ee2a95e48def52257f391 (diff) | |
download | scummvm-rg350-22e24d7c0b78801d813294718d6a320fd46fc8d9.tar.gz scummvm-rg350-22e24d7c0b78801d813294718d6a320fd46fc8d9.tar.bz2 scummvm-rg350-22e24d7c0b78801d813294718d6a320fd46fc8d9.zip |
VIDEO: Fix reverse playback in AVIDecoder
Diffstat (limited to 'video')
-rw-r--r-- | video/avi_decoder.cpp | 22 | ||||
-rw-r--r-- | video/avi_decoder.h | 20 |
2 files changed, 37 insertions, 5 deletions
diff --git a/video/avi_decoder.cpp b/video/avi_decoder.cpp index 2f45a003f5..13b2c98994 100644 --- a/video/avi_decoder.cpp +++ b/video/avi_decoder.cpp @@ -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); } } diff --git a/video/avi_decoder.h b/video/avi_decoder.h index dd5773fb7f..5a6864f52e 100644 --- a/video/avi_decoder.h +++ b/video/avi_decoder.h @@ -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 |