mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-20 19:21:46 +00:00
VIDEO: Fix reverse playback in AVIDecoder
This commit is contained in:
parent
aba431ca9b
commit
22e24d7c0b
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user