diff options
author | Eugene Sandulenko | 2016-08-01 00:27:28 +0300 |
---|---|---|
committer | GitHub | 2016-08-01 00:27:28 +0300 |
commit | 9d3a2c1c7f9365f65908f583e62047830f60693d (patch) | |
tree | d7ba49593a1e3d79f17b350e700b1fbcf71f5b22 /video | |
parent | 567054d8298a013f93dd9e0e332e2a08402b10a6 (diff) | |
parent | 19f8a0965be832a71a101054748cf000adf16add (diff) | |
download | scummvm-rg350-9d3a2c1c7f9365f65908f583e62047830f60693d.tar.gz scummvm-rg350-9d3a2c1c7f9365f65908f583e62047830f60693d.tar.bz2 scummvm-rg350-9d3a2c1c7f9365f65908f583e62047830f60693d.zip |
Merge pull request #786 from dreammaster/titanic
TITANIC: Starship Titanic engine
Diffstat (limited to 'video')
-rw-r--r-- | video/avi_decoder.cpp | 51 | ||||
-rw-r--r-- | video/avi_decoder.h | 26 |
2 files changed, 68 insertions, 9 deletions
diff --git a/video/avi_decoder.cpp b/video/avi_decoder.cpp index e07805f489..980ce3a3ea 100644 --- a/video/avi_decoder.cpp +++ b/video/avi_decoder.cpp @@ -76,12 +76,13 @@ enum { }; -AVIDecoder::AVIDecoder(Audio::Mixer::SoundType soundType) : _frameRateOverride(0), _soundType(soundType) { +AVIDecoder::AVIDecoder(Audio::Mixer::SoundType soundType, SelectTrackFn trackFn) : + _frameRateOverride(0), _soundType(soundType), _selectTrackFn(trackFn) { initCommon(); } -AVIDecoder::AVIDecoder(const Common::Rational &frameRateOverride, Audio::Mixer::SoundType soundType) - : _frameRateOverride(frameRateOverride), _soundType(soundType) { +AVIDecoder::AVIDecoder(const Common::Rational &frameRateOverride, Audio::Mixer::SoundType soundType, + SelectTrackFn trackFn) : _frameRateOverride(frameRateOverride), _soundType(soundType), _selectTrackFn(trackFn) { initCommon(); } @@ -99,6 +100,8 @@ void AVIDecoder::initCommon() { _movieListStart = 0; _movieListEnd = 0; _fileStream = 0; + _videoTrackCounter = _audioTrackCounter = 0; + _lastAddedTrack = nullptr; memset(&_header, 0, sizeof(_header)); } @@ -145,10 +148,12 @@ bool AVIDecoder::parseNextChunk() { case ID_JUNQ: // Same as JUNK, safe to ignore case ID_ISFT: // Metadata, safe to ignore case ID_DISP: // Metadata, should be safe to ignore - case ID_STRN: // Metadata, safe to ignore case ID_DMLH: // OpenDML extension, contains an extra total frames field, safe to ignore skipChunk(size); break; + case ID_STRN: // Metadata, safe to ignore + readStreamName(size); + break; case ID_IDX1: readOldIndex(size); break; @@ -287,6 +292,39 @@ void AVIDecoder::handleStreamHeader(uint32 size) { _fileStream->seek(startPos + strfSize); } +void AVIDecoder::addTrack(Track *track, bool isExternal) { + if (!_selectTrackFn || + (dynamic_cast<AVIVideoTrack *>(track) && _selectTrackFn(true, _videoTrackCounter++)) || + (dynamic_cast<AVIAudioTrack *>(track) && _selectTrackFn(false, _audioTrackCounter++))) { + VideoDecoder::addTrack(track, isExternal); + _lastAddedTrack = track; + } else { + _lastAddedTrack = nullptr; + } +} + +void AVIDecoder::readStreamName(uint32 size) { + if (!_lastAddedTrack) { + skipChunk(size); + } else { + // Get in the name + assert(size > 0 && size < 64); + char buffer[64]; + _fileStream->read(buffer, size); + if (size & 1) + _fileStream->skip(1); + + // Apply it to the most recently read stream + assert(_lastAddedTrack); + AVIVideoTrack *vidTrack = dynamic_cast<AVIVideoTrack *>(_lastAddedTrack); + AVIAudioTrack *audTrack = dynamic_cast<AVIAudioTrack *>(_lastAddedTrack); + if (vidTrack) + vidTrack->getName() = Common::String(buffer); + else if (audTrack) + audTrack->getName() = Common::String(buffer); + } +} + bool AVIDecoder::loadStream(Common::SeekableReadStream *stream) { close(); @@ -296,7 +334,7 @@ bool AVIDecoder::loadStream(Common::SeekableReadStream *stream) { return false; } - /* uint32 fileSize = */ stream->readUint32LE(); + int32 fileSize = stream->readUint32LE(); uint32 riffType = stream->readUint32BE(); if (riffType != ID_AVI) { @@ -307,7 +345,7 @@ bool AVIDecoder::loadStream(Common::SeekableReadStream *stream) { _fileStream = stream; // Go through all chunks in the file - while (parseNextChunk()) + while (_fileStream->pos() < fileSize && parseNextChunk()) ; if (!_decodedHeader) { @@ -337,7 +375,6 @@ bool AVIDecoder::loadStream(Common::SeekableReadStream *stream) { } if (_videoTracks.size() != 1) { - warning("Unhandled AVI video track count: %d", _videoTracks.size()); close(); return false; } diff --git a/video/avi_decoder.h b/video/avi_decoder.h index 96d9e821ff..a3733b579c 100644 --- a/video/avi_decoder.h +++ b/video/avi_decoder.h @@ -57,12 +57,15 @@ namespace Video { * - sci * - sword1 * - sword2 + * - titanic * - zvision */ class AVIDecoder : public VideoDecoder { public: - AVIDecoder(Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType); - AVIDecoder(const Common::Rational &frameRateOverride, Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType); + typedef bool(*SelectTrackFn)(bool isVideo, int trackNumber); + AVIDecoder(Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType, SelectTrackFn trackFn = nullptr); + AVIDecoder(const Common::Rational &frameRateOverride, Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType, + SelectTrackFn trackFn = nullptr); virtual ~AVIDecoder(); bool loadStream(Common::SeekableReadStream *stream); @@ -81,6 +84,16 @@ protected: bool supportsAudioTrackSwitching() const { return true; } AudioTrack *getAudioTrack(int index); + /** + * Define a track to be used by this class. + * + * The pointer is then owned by this base class. + * + * @param track The track to add + * @param isExternal Is this an external track not found by loadStream()? + */ + void addTrack(Track *track, bool isExternal = false); + struct BitmapInfoHeader { uint32 size; uint32 width; @@ -164,6 +177,7 @@ protected: uint32 quality; uint32 sampleSize; Common::Rect frame; + Common::String name; }; class AVIVideoTrack : public FixedRateVideoTrack { @@ -179,6 +193,7 @@ protected: Graphics::PixelFormat getPixelFormat() const; int getCurFrame() const { return _curFrame; } int getFrameCount() const { return _frameCount; } + Common::String &getName() { return _vidsHeader.name; } const Graphics::Surface *decodeNextFrame() { return _lastFrame; } const byte *getPalette() const; @@ -222,6 +237,7 @@ protected: void skipAudio(const Audio::Timestamp &time, const Audio::Timestamp &frameTime); virtual void resetStream(); uint32 getCurChunk() const { return _curChunk; } + Common::String &getName() { return _audsHeader.name; } void setCurChunk(uint32 chunk) { _curChunk = chunk; } bool isRewindable() const { return true; } @@ -268,12 +284,18 @@ protected: Audio::Mixer::SoundType _soundType; Common::Rational _frameRateOverride; + + int _videoTrackCounter, _audioTrackCounter; + Track *_lastAddedTrack; + SelectTrackFn _selectTrackFn; + void initCommon(); bool parseNextChunk(); void skipChunk(uint32 size); void handleList(uint32 listSize); void handleStreamHeader(uint32 size); + void readStreamName(uint32 size); uint16 getStreamType(uint32 tag) const { return tag & 0xFFFF; } byte getStreamIndex(uint32 tag) const; void checkTruemotion1(); |