From 5891ef4d89936917aaa7edf06f5d1fbc06a1271f Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Tue, 27 May 2014 00:09:11 -0400 Subject: 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. --- video/avi_decoder.cpp | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++ video/avi_decoder.h | 4 ++++ 2 files changed, 58 insertions(+) (limited to 'video') 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); -- cgit v1.2.3