aboutsummaryrefslogtreecommitdiff
path: root/video
diff options
context:
space:
mode:
Diffstat (limited to 'video')
-rw-r--r--video/avi_decoder.cpp56
-rw-r--r--video/avi_decoder.h4
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);