diff options
author | Paul Gilbert | 2016-10-02 20:22:53 -0400 |
---|---|---|
committer | Paul Gilbert | 2016-10-02 20:22:53 -0400 |
commit | c676ecb258d9fca8a997055c5628e1cc786103de (patch) | |
tree | ef7a71fc9142bf1cb92a5f96c6f0de9e308cb95a /video | |
parent | 78a3ac6c5daf1b091813c6cebce4b1d7894cee86 (diff) | |
download | scummvm-rg350-c676ecb258d9fca8a997055c5628e1cc786103de.tar.gz scummvm-rg350-c676ecb258d9fca8a997055c5628e1cc786103de.tar.bz2 scummvm-rg350-c676ecb258d9fca8a997055c5628e1cc786103de.zip |
VIDEO: Implement seeking for AVI videos with a transparency video track
Diffstat (limited to 'video')
-rw-r--r-- | video/avi_decoder.cpp | 62 | ||||
-rw-r--r-- | video/avi_decoder.h | 8 | ||||
-rw-r--r-- | video/video_decoder.h | 2 |
3 files changed, 71 insertions, 1 deletions
diff --git a/video/avi_decoder.cpp b/video/avi_decoder.cpp index e2f5bbd465..7d88379007 100644 --- a/video/avi_decoder.cpp +++ b/video/avi_decoder.cpp @@ -94,6 +94,23 @@ AVIDecoder::AVIAudioTrack *AVIDecoder::createAudioTrack(AVIStreamHeader sHeader, return new AVIAudioTrack(sHeader, wvInfo, _soundType); } +bool AVIDecoder::seekToFrame(uint frame) { + if (!isSeekable()) + return false; + + // If we didn't find a video track, we can't seek by frame (of course) + if (_videoTracks.empty()) + return false; + + AVIVideoTrack *track = static_cast<AVIVideoTrack *>(_videoTracks.front().track); + Audio::Timestamp time = track->getFrameTime(frame); + + if (time < 0) + return false; + + return seek(time); +} + void AVIDecoder::initCommon() { _decodedHeader = false; _foundMovieList = false; @@ -386,9 +403,28 @@ bool AVIDecoder::loadStream(Common::SeekableReadStream *stream) { _fileStream->seek(size, SEEK_CUR); } + // Set the chunk offset, and force the stream num to 10, + // to avoid conflicting with any other audio track + status.index = 10; status.chunkSearchOffset = _fileStream->pos(); assert(status.chunkSearchOffset < _movieListEnd); _videoTracks.push_back(status); + + // Build up index entries for the secondary video track, so we + // can seek in at at the same time as the primary video track + for (uint idx = 0; idx < _header.totalFrames; ++idx) { + uint chunkPos = _fileStream->pos(); + _fileStream->seek(4, SEEK_CUR); + uint chunkSize = _fileStream->readUint32LE(); + _fileStream->seek(chunkSize, SEEK_CUR); + + OldIndex indexEntry; + indexEntry.flags = 0; + indexEntry.id = MKTAG('0', 'A', 'd', 'b'); + indexEntry.offset = chunkPos; + indexEntry.size = chunkSize; + _indexEntries.push_back(indexEntry); + } } } @@ -680,6 +716,32 @@ bool AVIDecoder::seekIntern(const Audio::Timestamp &time) { videoTrack->decodeFrame(chunk); } + // Update any secondary video track for transparencies + if (_videoTracks.size() == 2) { + AVIVideoTrack *videoTrack2 = static_cast<AVIVideoTrack *>(_videoTracks.back().track); + + // Set it's frame number + videoTrack2->setCurFrame((int)frame - 1); + + // Find the index entry for the frame and move to it + for (uint i = 0, frameNum = 0; i < _indexEntries.size(); ++i) { + if (_indexEntries[i].id != ID_REC && + getStreamIndex(_indexEntries[i].id) == _videoTracks.back().index) { + if (frameNum++ == frame) { + Common::SeekableReadStream *chunk = nullptr; + _fileStream->seek(_indexEntries[i].offset + 8); + _videoTracks.back().chunkSearchOffset = _indexEntries[i].offset; + + if (_indexEntries[i].size != 0) + chunk = _fileStream->readStream(_indexEntries[i].size); + + videoTrack2->decodeFrame(chunk); + break; + } + } + } + } + // Set the video track's frame videoTrack->setCurFrame((int)frame - 1); diff --git a/video/avi_decoder.h b/video/avi_decoder.h index 3448204429..3581b65409 100644 --- a/video/avi_decoder.h +++ b/video/avi_decoder.h @@ -304,6 +304,14 @@ protected: public: virtual AVIAudioTrack *createAudioTrack(AVIStreamHeader sHeader, PCMWaveFormat wvInfo); + + /** + * Seek to a given frame. + * + * This only works when the video track(s) supports getFrameTime(). + * This calls seek() internally. + */ + virtual bool seekToFrame(uint frame); }; } // End of namespace Video diff --git a/video/video_decoder.h b/video/video_decoder.h index eca15e7265..a415a70724 100644 --- a/video/video_decoder.h +++ b/video/video_decoder.h @@ -184,7 +184,7 @@ public: * This only works when one video track is present, and that track * supports getFrameTime(). This calls seek() internally. */ - bool seekToFrame(uint frame); + virtual bool seekToFrame(uint frame); /** * Pause or resume the video. This should stop/resume any audio playback |