[Scummvm-git-logs] scummvm master -> a333f3c44ccde58438cb0deb9a6398b3008aeeec
dreammaster
dreammaster at scummvm.org
Thu Oct 13 02:09:44 CEST 2016
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
a333f3c44c VIDEO: Support rewind on AVI files with multiple video tracks
Commit: a333f3c44ccde58438cb0deb9a6398b3008aeeec
https://github.com/scummvm/scummvm/commit/a333f3c44ccde58438cb0deb9a6398b3008aeeec
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2016-10-12T20:09:36-04:00
Commit Message:
VIDEO: Support rewind on AVI files with multiple video tracks
Changed paths:
video/avi_decoder.cpp
video/avi_decoder.h
diff --git a/video/avi_decoder.cpp b/video/avi_decoder.cpp
index 2c8efc4..7041f42 100644
--- a/video/avi_decoder.cpp
+++ b/video/avi_decoder.cpp
@@ -392,19 +392,9 @@ bool AVIDecoder::loadStream(Common::SeekableReadStream *stream) {
} else if (_videoTracks.empty()) {
_videoTracks.push_back(status);
} else {
- // Secondary video track. Figure out the starting chunk offset,
- // by iteratiing through the index
+ // Secondary video track
assert(_videoTracks.size() == 1);
-
- // Find the index entry for the frame and move to it
- status.chunkSearchOffset = 0;
- for (uint idx = 0; idx < _indexEntries.size(); ++idx) {
- if (_indexEntries[idx].id != ID_REC &&
- getStreamIndex(_indexEntries[idx].id) == index) {
- status.chunkSearchOffset = _indexEntries[idx].offset;
- break;
- }
- }
+ status.chunkSearchOffset = getVideoTrackOffset(index);
assert(status.chunkSearchOffset != 0);
// Add the video track to the list
@@ -558,7 +548,7 @@ bool AVIDecoder::rewind() {
return false;
for (uint32 i = 0; i < _videoTracks.size(); i++)
- _videoTracks[i].chunkSearchOffset = _movieListStart;
+ _videoTracks[i].chunkSearchOffset = getVideoTrackOffset(_videoTracks[i].index);
for (uint32 i = 0; i < _audioTracks.size(); i++)
_audioTracks[i].chunkSearchOffset = _movieListStart;
@@ -566,6 +556,15 @@ bool AVIDecoder::rewind() {
return true;
}
+uint AVIDecoder::getVideoTrackOffset(uint trackIndex, uint frameNumber) {
+ if (trackIndex == _videoTracks.front().index && frameNumber == 0)
+ return _movieListStart;
+
+ OldIndex *entry = _indexEntries.find(trackIndex, frameNumber);
+ assert(entry);
+ return entry->offset;
+}
+
bool AVIDecoder::seekIntern(const Audio::Timestamp &time) {
// Can't seek beyond the end
if (time > getDuration())
@@ -702,28 +701,22 @@ bool AVIDecoder::seekIntern(const Audio::Timestamp &time) {
// Update any secondary video track for transparencies
if (_videoTracks.size() == 2) {
- AVIVideoTrack *videoTrack2 = static_cast<AVIVideoTrack *>(_videoTracks.back().track);
-
// Set it's frame number
+ AVIVideoTrack *videoTrack2 = static_cast<AVIVideoTrack *>(_videoTracks.back().track);
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;
+ // Find the index entry for the frame and read it in
+ OldIndex *entry = _indexEntries.find(_videoTracks.back().index, frame);
+ assert(entry);
- if (_indexEntries[i].size != 0)
- chunk = _fileStream->readStream(_indexEntries[i].size);
+ Common::SeekableReadStream *chunk = nullptr;
+ _fileStream->seek(entry->offset + 8);
+ _videoTracks.back().chunkSearchOffset = entry->offset;
- videoTrack2->decodeFrame(chunk);
- break;
- }
- }
- }
+ if (entry->size != 0)
+ chunk = _fileStream->readStream(entry->size);
+
+ videoTrack2->decodeFrame(chunk);
}
// Set the video track's frame
@@ -734,7 +727,7 @@ bool AVIDecoder::seekIntern(const Audio::Timestamp &time) {
return true;
}
-byte AVIDecoder::getStreamIndex(uint32 tag) const {
+byte AVIDecoder::getStreamIndex(uint32 tag) {
char string[3];
WRITE_BE_UINT16(string, tag >> 16);
string[2] = 0;
@@ -1035,4 +1028,16 @@ void AVIDecoder::AVIAudioTrack::createAudioStream() {
AVIDecoder::TrackStatus::TrackStatus() : track(0), chunkSearchOffset(0) {
}
+AVIDecoder::OldIndex *AVIDecoder::IndexEntries::find(uint index, uint frameNumber) {
+ for (uint idx = 0, frameCtr = 0; idx < size(); ++idx) {
+ if ((*this)[idx].id != ID_REC &&
+ AVIDecoder::getStreamIndex((*this)[idx].id) == index) {
+ if (frameCtr++ == frameNumber)
+ return &(*this)[idx];
+ }
+ }
+
+ return nullptr;
+}
+
} // End of namespace Video
diff --git a/video/avi_decoder.h b/video/avi_decoder.h
index db9928d..4bba07e 100644
--- a/video/avi_decoder.h
+++ b/video/avi_decoder.h
@@ -272,10 +272,15 @@ protected:
uint32 chunkSearchOffset;
};
+ class IndexEntries : public Common::Array<OldIndex> {
+ public:
+ OldIndex *find(uint index, uint frameNumber);
+ };
+
AVIHeader _header;
void readOldIndex(uint32 size);
- Common::Array<OldIndex> _indexEntries;
+ IndexEntries _indexEntries;
Common::SeekableReadStream *_fileStream;
bool _decodedHeader;
@@ -296,8 +301,9 @@ protected:
void handleStreamHeader(uint32 size);
void readStreamName(uint32 size);
uint16 getStreamType(uint32 tag) const { return tag & 0xFFFF; }
- byte getStreamIndex(uint32 tag) const;
+ static byte getStreamIndex(uint32 tag);
void checkTruemotion1();
+ uint getVideoTrackOffset(uint trackIndex, uint frameNumber = 0);
void handleNextPacket(TrackStatus& status);
bool shouldQueueAudio(TrackStatus& status);
More information about the Scummvm-git-logs
mailing list