aboutsummaryrefslogtreecommitdiff
path: root/video
diff options
context:
space:
mode:
authorPaul Gilbert2016-10-02 20:22:53 -0400
committerPaul Gilbert2016-10-02 20:22:53 -0400
commitc676ecb258d9fca8a997055c5628e1cc786103de (patch)
treeef7a71fc9142bf1cb92a5f96c6f0de9e308cb95a /video
parent78a3ac6c5daf1b091813c6cebce4b1d7894cee86 (diff)
downloadscummvm-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.cpp62
-rw-r--r--video/avi_decoder.h8
-rw-r--r--video/video_decoder.h2
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