aboutsummaryrefslogtreecommitdiff
path: root/video
diff options
context:
space:
mode:
authorMatthew Hoops2014-05-27 00:09:11 -0400
committerMatthew Hoops2014-05-27 00:09:11 -0400
commit5891ef4d89936917aaa7edf06f5d1fbc06a1271f (patch)
tree1ae5fcd5c7cd3325c49ae50e13c6a602cade26aa /video
parent53332f8ab879b150883544fb8ea3987bdc190cdf (diff)
downloadscummvm-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.cpp54
-rw-r--r--video/avi_decoder.h4
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);