diff options
Diffstat (limited to 'video')
-rw-r--r-- | video/avi_decoder.cpp | 56 | ||||
-rw-r--r-- | video/avi_decoder.h | 4 |
2 files changed, 59 insertions, 1 deletions
diff --git a/video/avi_decoder.cpp b/video/avi_decoder.cpp index 9b196fefc9..68d6cb6cec 100644 --- a/video/avi_decoder.cpp +++ b/video/avi_decoder.cpp @@ -183,7 +183,7 @@ void AVIDecoder::handleList(uint32 listSize) { _decodedHeader = true; break; case ID_INFO: // Metadata - case ID_PRMI: // Unknown metadata, should be safe to ignore + case ID_PRMI: // Adobe Premiere metadata, safe to ignore // Ignore metadata _fileStream->skip(listSize); return; @@ -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); |