diff options
author | Paul Gilbert | 2016-10-02 14:24:40 -0400 |
---|---|---|
committer | Paul Gilbert | 2016-10-02 14:24:40 -0400 |
commit | 3d25e260f783586c9a1a53dfa5bd0216d5277360 (patch) | |
tree | 1f4b1a27035d316aebb4ed66709b14400b03cb89 /video | |
parent | 28b2609b927a889b3e3b17da76ab99f642ac72f0 (diff) | |
download | scummvm-rg350-3d25e260f783586c9a1a53dfa5bd0216d5277360.tar.gz scummvm-rg350-3d25e260f783586c9a1a53dfa5bd0216d5277360.tar.bz2 scummvm-rg350-3d25e260f783586c9a1a53dfa5bd0216d5277360.zip |
TITANIC: Fix AVIDecoder to properly handle transparency video tracks
Diffstat (limited to 'video')
-rw-r--r-- | video/avi_decoder.cpp | 42 | ||||
-rw-r--r-- | video/avi_decoder.h | 1 |
2 files changed, 32 insertions, 11 deletions
diff --git a/video/avi_decoder.cpp b/video/avi_decoder.cpp index 30f87a126a..e2f5bbd465 100644 --- a/video/avi_decoder.cpp +++ b/video/avi_decoder.cpp @@ -111,6 +111,14 @@ bool AVIDecoder::isSeekable() const { return isVideoLoaded() && !_indexEntries.empty(); } +const Graphics::Surface *AVIDecoder::decodeNextTransparency() { + if (_videoTracks.size() != 2) + return nullptr; + + AVIVideoTrack *track = static_cast<AVIVideoTrack *>(_videoTracks[1].track); + return track->decodeNextFrame(); +} + bool AVIDecoder::parseNextChunk() { uint32 tag = _fileStream->readUint32BE(); uint32 size = _fileStream->readUint32LE(); @@ -362,15 +370,26 @@ bool AVIDecoder::loadStream(Common::SeekableReadStream *stream) { status.index = index; status.chunkSearchOffset = _movieListStart; - if ((*it)->getTrackType() == Track::kTrackTypeVideo) - _videoTracks.push_back(status); - else + if ((*it)->getTrackType() == Track::kTrackTypeAudio) { _audioTracks.push_back(status); - } + } else if (_videoTracks.empty()) { + _videoTracks.push_back(status); + } else { + // Secondary video track. Figure out the starting chunk offset, + // by iteratiing through the frames of the primary one + assert(_videoTracks.size() == 1); + stream->seek(_movieListStart); + + for (uint idx = 0; idx < _header.totalFrames; ++idx) { + _fileStream->readUint32BE(); + uint32 size = _fileStream->readUint32LE(); + _fileStream->seek(size, SEEK_CUR); + } - if (_videoTracks.size() != 1) { - close(); - return false; + status.chunkSearchOffset = _fileStream->pos(); + assert(status.chunkSearchOffset < _movieListEnd); + _videoTracks.push_back(status); + } } // Check if this is a special Duck Truemotion video @@ -401,12 +420,13 @@ void AVIDecoder::readNextPacket() { if (_videoTracks.empty()) return; - // Get the video frame first - handleNextPacket(_videoTracks[0]); + // Handle the video first + for (uint idx = 0; idx < _videoTracks.size(); ++idx) + handleNextPacket(_videoTracks[idx]); // Handle audio tracks next - for (uint32 i = 0; i < _audioTracks.size(); i++) - handleNextPacket(_audioTracks[i]); + for (uint idx = 0; idx < _audioTracks.size(); ++idx) + handleNextPacket(_audioTracks[idx]); } void AVIDecoder::handleNextPacket(TrackStatus &status) { diff --git a/video/avi_decoder.h b/video/avi_decoder.h index 7f4431f670..3448204429 100644 --- a/video/avi_decoder.h +++ b/video/avi_decoder.h @@ -75,6 +75,7 @@ public: bool isRewindable() const { return true; } bool isSeekable() const; + const Graphics::Surface *decodeNextTransparency(); protected: // VideoDecoder API void readNextPacket(); |