[Scummvm-cvs-logs] scummvm master -> 5891ef4d89936917aaa7edf06f5d1fbc06a1271f

clone2727 clone2727 at gmail.com
Tue May 27 06:11:00 CEST 2014


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
5891ef4d89 VIDEO: Handle Truemotion dimensions specially


Commit: 5891ef4d89936917aaa7edf06f5d1fbc06a1271f
    https://github.com/scummvm/scummvm/commit/5891ef4d89936917aaa7edf06f5d1fbc06a1271f
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2014-05-27T00:09:11-04:00

Commit Message:
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.

Changed paths:
    image/codecs/codec.cpp
    image/codecs/truemotion1.cpp
    image/codecs/truemotion1.h
    video/avi_decoder.cpp
    video/avi_decoder.h



diff --git a/image/codecs/codec.cpp b/image/codecs/codec.cpp
index 64acf3f..6b0c7eb 100644
--- a/image/codecs/codec.cpp
+++ b/image/codecs/codec.cpp
@@ -61,7 +61,7 @@ Codec *createBitmapCodec(uint32 tag, int width, int height, int bitsPerPixel) {
 #ifdef IMAGE_CODECS_TRUEMOTION1_H
 	case MKTAG('D','U','C','K'):
 	case MKTAG('d','u','c','k'):
-		return new TrueMotion1Decoder(width, height);
+		return new TrueMotion1Decoder();
 #endif
 #ifdef USE_MPEG2
 	case MKTAG('m','p','g','2'):
diff --git a/image/codecs/truemotion1.cpp b/image/codecs/truemotion1.cpp
index 741b9d5..e60ec6c 100644
--- a/image/codecs/truemotion1.cpp
+++ b/image/codecs/truemotion1.cpp
@@ -89,11 +89,8 @@ static const CompressionType compressionTypes[17] = {
 	{ ALGO_RGB24H, 2, 2, BLOCK_2x2 }
 };
 
-TrueMotion1Decoder::TrueMotion1Decoder(uint16 width, uint16 height) {
-	_surface = new Graphics::Surface();
-	_surface->create(width, height, getPixelFormat());
-	_surface->fillRect(Common::Rect(width, height), getPixelFormat().RGBToColor(0, 0, 0));
-
+TrueMotion1Decoder::TrueMotion1Decoder() {
+	_surface = 0;
 	_vertPred = 0;
 
 	_buf = _mbChangeBits = _indexStream = 0;
@@ -101,8 +98,11 @@ TrueMotion1Decoder::TrueMotion1Decoder(uint16 width, uint16 height) {
 }
 
 TrueMotion1Decoder::~TrueMotion1Decoder() {
-	_surface->free();
-	delete _surface;
+	if (_surface) {
+		_surface->free();
+		delete _surface;
+	}
+
 	delete[] _vertPred;
 }
 
@@ -194,6 +194,11 @@ void TrueMotion1Decoder::decodeHeader(Common::SeekableReadStream &stream) {
 		_vertPred = new uint32[_header.xsize];
 	}
 
+	if (!_surface) {
+		_surface = new Graphics::Surface();
+		_surface->create(_header.xsize, _header.ysize, getPixelFormat());
+	}
+
 	// There is 1 change bit per 4 pixels, so each change byte represents
 	// 32 pixels; divide width by 4 to obtain the number of change bits and
 	// then round up to the nearest byte.
diff --git a/image/codecs/truemotion1.h b/image/codecs/truemotion1.h
index bbbcd6d..51daf60 100644
--- a/image/codecs/truemotion1.h
+++ b/image/codecs/truemotion1.h
@@ -39,7 +39,7 @@ namespace Image {
  */
 class TrueMotion1Decoder : public Codec {
 public:
-	TrueMotion1Decoder(uint16 width, uint16 height);
+	TrueMotion1Decoder();
 	~TrueMotion1Decoder();
 
 	const Graphics::Surface *decodeFrame(Common::SeekableReadStream &stream);
diff --git a/video/avi_decoder.cpp b/video/avi_decoder.cpp
index 9b196fe..3c1c907 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 2f7b267..28d87bc 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);






More information about the Scummvm-git-logs mailing list