diff options
author | Matthew Hoops | 2014-05-27 00:09:11 -0400 |
---|---|---|
committer | Matthew Hoops | 2014-05-27 00:09:11 -0400 |
commit | 5891ef4d89936917aaa7edf06f5d1fbc06a1271f (patch) | |
tree | 1ae5fcd5c7cd3325c49ae50e13c6a602cade26aa /video | |
parent | 53332f8ab879b150883544fb8ea3987bdc190cdf (diff) | |
download | scummvm-rg350-5891ef4d89936917aaa7edf06f5d1fbc06a1271f.tar.gz scummvm-rg350-5891ef4d89936917aaa7edf06f5d1fbc06a1271f.tar.bz2 scummvm-rg350-5891ef4d89936917aaa7edf06f5d1fbc06a1271f.zip |
VIDEO: Handle Truemotion dimensions specially
Truemotion uses its own demuxer and seems to follow its own AVI rules. Work around it by coercing the video's dimensions to use the codec's internal dimensions.
Diffstat (limited to 'video')
-rw-r--r-- | video/avi_decoder.cpp | 54 | ||||
-rw-r--r-- | video/avi_decoder.h | 4 |
2 files changed, 58 insertions, 0 deletions
diff --git a/video/avi_decoder.cpp b/video/avi_decoder.cpp index 9b196fefc9..3c1c907097 100644 --- a/video/avi_decoder.cpp +++ b/video/avi_decoder.cpp @@ -322,6 +322,9 @@ bool AVIDecoder::loadStream(Common::SeekableReadStream *stream) { // Seek back to the start of the MOVI list _fileStream->seek(_movieListStart); + // Check if this is a special Duck Truemotion video + checkTruemotion1(); + return true; } @@ -658,6 +661,48 @@ void AVIDecoder::forceVideoEnd() { ((AVIVideoTrack *)*it)->forceTrackEnd(); } +void AVIDecoder::checkTruemotion1() { + AVIVideoTrack *track = 0; + + for (TrackListIterator it = getTrackListBegin(); it != getTrackListEnd(); it++) { + if ((*it)->getTrackType() == Track::kTrackTypeVideo) { + if (track) { + // Multiple tracks; isn't going to be truemotion 1 + return; + } + + track = (AVIVideoTrack *)*it; + } + } + + // No track found? + if (!track) + return; + + // Ignore non-truemotion tracks + if (!track->isTruemotion1()) + return; + + // Search for a non-empty frame + const Graphics::Surface *frame = 0; + for (int i = 0; i < 10 && !frame; i++) + frame = decodeNextFrame(); + + if (!frame) { + // Probably shouldn't happen + rewind(); + return; + } + + // Fill in the width/height based on the frame's width/height + _header.width = frame->w; + _header.height = frame->h; + track->forceDimensions(frame->w, frame->h); + + // Rewind us back to the beginning + rewind(); +} + VideoDecoder::AudioTrack *AVIDecoder::getAudioTrack(int index) { // AVI audio track indexes are relative to the first track Track *track = getTrack(index); @@ -732,6 +777,15 @@ void AVIDecoder::AVIVideoTrack::useInitialPalette() { } } +bool AVIDecoder::AVIVideoTrack::isTruemotion1() const { + return _bmInfo.compression == MKTAG('D', 'U', 'C', 'K') || _bmInfo.compression == MKTAG('d', 'u', 'c', 'k'); +} + +void AVIDecoder::AVIVideoTrack::forceDimensions(uint16 width, uint16 height) { + _bmInfo.width = width; + _bmInfo.height = height; +} + bool AVIDecoder::AVIVideoTrack::rewind() { _curFrame = -1; diff --git a/video/avi_decoder.h b/video/avi_decoder.h index 2f7b267d36..28d87bc3b7 100644 --- a/video/avi_decoder.h +++ b/video/avi_decoder.h @@ -185,6 +185,9 @@ protected: void loadPaletteFromChunk(Common::SeekableReadStream *chunk); void useInitialPalette(); + bool isTruemotion1() const; + void forceDimensions(uint16 width, uint16 height); + bool isRewindable() const { return true; } bool rewind(); @@ -257,6 +260,7 @@ protected: uint16 getStreamType(uint32 tag) const { return tag & 0xFFFF; } byte getStreamIndex(uint32 tag) const; void forceVideoEnd(); + void checkTruemotion1(); public: virtual AVIAudioTrack *createAudioTrack(AVIStreamHeader sHeader, PCMWaveFormat wvInfo); |