diff options
author | Matthew Hoops | 2012-12-15 20:41:41 -0500 |
---|---|---|
committer | Matthew Hoops | 2012-12-15 20:41:41 -0500 |
commit | 9ae56146bbe1daab3f8919ec67dc458d864651cb (patch) | |
tree | fb8c48958ef305807e11fa7e37ddfd5dd8014137 /video | |
parent | 1214b7a7e4c38c7e676351512a4c6d7a2bb46610 (diff) | |
download | scummvm-rg350-9ae56146bbe1daab3f8919ec67dc458d864651cb.tar.gz scummvm-rg350-9ae56146bbe1daab3f8919ec67dc458d864651cb.tar.bz2 scummvm-rg350-9ae56146bbe1daab3f8919ec67dc458d864651cb.zip |
VIDEO: Add API changes to allow videos to be played backwards
Diffstat (limited to 'video')
-rw-r--r-- | video/video_decoder.cpp | 44 | ||||
-rw-r--r-- | video/video_decoder.h | 26 |
2 files changed, 63 insertions, 7 deletions
diff --git a/video/video_decoder.cpp b/video/video_decoder.cpp index ab12cfd971..ebe15c5fc1 100644 --- a/video/video_decoder.cpp +++ b/video/video_decoder.cpp @@ -188,6 +188,25 @@ const Graphics::Surface *VideoDecoder::decodeNextFrame() { return frame; } +bool VideoDecoder::setReverse(bool reverse) { + // Can only reverse video-only videos + if (reverse && hasAudio()) + return false; + + // Attempt to make sure all the tracks are in the requested direction + for (TrackList::iterator it = _tracks.begin(); it != _tracks.end(); it++) { + if ((*it)->getTrackType() == Track::kTrackTypeVideo && ((VideoTrack *)*it)->isReversed() != reverse) { + if (!((VideoTrack *)*it)->setReverse(reverse)) + return false; + + _needsUpdate = true; // force an update + } + } + + findNextVideoTrack(); + return true; +} + const byte *VideoDecoder::getPalette() { _dirtyPalette = false; return _palette; @@ -218,7 +237,7 @@ uint32 VideoDecoder::getTime() const { return _lastTimeChange.msecs(); if (isPaused()) - return (_playbackRate * (_pauseStartTime - _startTime)).toInt(); + return MAX<int>((_playbackRate * (_pauseStartTime - _startTime)).toInt(), 0); if (useAudioSync()) { for (TrackList::const_iterator it = _tracks.begin(); it != _tracks.end(); it++) { @@ -231,20 +250,29 @@ uint32 VideoDecoder::getTime() const { } } - return (_playbackRate * (g_system->getMillis() - _startTime)).toInt(); + return MAX<int>((_playbackRate * (g_system->getMillis() - _startTime)).toInt(), 0); } uint32 VideoDecoder::getTimeToNextFrame() const { if (endOfVideo() || _needsUpdate || !_nextVideoTrack) return 0; - uint32 elapsedTime = getTime(); + uint32 currentTime = getTime(); uint32 nextFrameStartTime = _nextVideoTrack->getNextFrameStartTime(); - if (nextFrameStartTime <= elapsedTime) + if (_nextVideoTrack->isReversed()) { + // For reversed videos, we need to handle the time difference the opposite way. + if (nextFrameStartTime >= currentTime) + return 0; + + return currentTime - nextFrameStartTime; + } + + // Otherwise, handle it normally. + if (nextFrameStartTime <= currentTime) return 0; - return nextFrameStartTime - elapsedTime; + return nextFrameStartTime - currentTime; } bool VideoDecoder::endOfVideo() const { @@ -402,9 +430,11 @@ void VideoDecoder::setRate(const Common::Rational &rate) { Common::Rational targetRate = rate; - if (rate < 0) { - // TODO: Implement support for this + // Attempt to set the reverse + if (!setReverse(rate < 0)) { + assert(rate < 0); // We shouldn't fail for forward. warning("Cannot set custom rate to backwards"); + setReverse(false); targetRate = 1; if (_playbackRate == targetRate) diff --git a/video/video_decoder.h b/video/video_decoder.h index 5fec52cf42..d0a6e08005 100644 --- a/video/video_decoder.h +++ b/video/video_decoder.h @@ -353,6 +353,17 @@ public: */ void setDefaultHighColorFormat(const Graphics::PixelFormat &format) { _defaultHighColorFormat = format; } + /** + * Set the video to decode frames in reverse. + * + * By default, VideoDecoder will decode forward. + * + * @note This is used by setRate() + * @note This will not work if an audio track is present + * @param reverse true for reverse, false for forward + * @return true on success, false otherwise + */ + bool setReverse(bool reverse); ///////////////////////////////////////// // Audio Control @@ -551,6 +562,21 @@ protected: * should only be used by VideoDecoder::seekToFrame(). */ virtual Audio::Timestamp getFrameTime(uint frame) const; + + /** + * Set the video track to play in reverse or forward. + * + * By default, a VideoTrack must decode forward. + * + * @param reverse true for reverse, false for forward + * @return true for success, false for failure + */ + virtual bool setReverse(bool reverse) { return !reverse; } + + /** + * Is the video track set to play in reverse? + */ + virtual bool isReversed() const { return false; } }; /** |