[Scummvm-cvs-logs] scummvm master -> 285e1be1353dc098cff6c67d3e61535de2bbe41d

clone2727 clone2727 at gmail.com
Wed Dec 5 02:35:56 CET 2012


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:
285e1be135 VIDEO: Improve performance of the Cinepak decoder


Commit: 285e1be1353dc098cff6c67d3e61535de2bbe41d
    https://github.com/scummvm/scummvm/commit/285e1be1353dc098cff6c67d3e61535de2bbe41d
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2012-12-04T17:19:00-08:00

Commit Message:
VIDEO: Improve performance of the Cinepak decoder

Changed paths:
    video/codecs/cinepak.cpp
    video/codecs/cinepak.h



diff --git a/video/codecs/cinepak.cpp b/video/codecs/cinepak.cpp
index f457d83..bcf0cf1 100644
--- a/video/codecs/cinepak.cpp
+++ b/video/codecs/cinepak.cpp
@@ -34,16 +34,12 @@
 
 namespace Video {
 
-// Convert a color from YUV to RGB colorspace, Cinepak style.
-inline static void CPYUV2RGB(byte y, byte u, byte v, byte &r, byte &g, byte &b) {
-	r = CLIP<int>(y + 2 * (v - 128), 0, 255);
-	g = CLIP<int>(y - (u - 128) / 2 - (v - 128), 0, 255);
-	b = CLIP<int>(y + 2 * (u - 128), 0, 255);
-}
-
 #define PUT_PIXEL(offset, lum, u, v) \
 	if (_pixelFormat.bytesPerPixel != 1) { \
-		CPYUV2RGB(lum, u, v, r, g, b); \
+		byte r = _clipTable[lum + (v << 1)]; \
+		byte g = _clipTable[lum - (u >> 1) - v]; \
+		byte b = _clipTable[lum + (u << 1)]; \
+		\
 		if (_pixelFormat.bytesPerPixel == 2) \
 			*((uint16 *)_curFrame.surface->pixels + offset) = _pixelFormat.RGBToColor(r, g, b); \
 		else \
@@ -60,6 +56,21 @@ CinepakDecoder::CinepakDecoder(int bitsPerPixel) : Codec() {
 		_pixelFormat = Graphics::PixelFormat::createFormatCLUT8();
 	else
 		_pixelFormat = g_system->getScreenFormat();
+
+	// Create a lookup for the clip function
+	// This dramatically improves the performance of the color conversion
+	_clipTableBuf = new byte[1024];
+
+	for (uint i = 0; i < 1024; i++) {
+		if (i <= 512)
+			_clipTableBuf[i] = 0;
+		else if (i >= 768)
+			_clipTableBuf[i] = 255;
+		else
+			_clipTableBuf[i] = i - 512;
+	}
+
+	_clipTable = _clipTableBuf + 512;
 }
 
 CinepakDecoder::~CinepakDecoder() {
@@ -69,6 +80,7 @@ CinepakDecoder::~CinepakDecoder() {
 	}
 
 	delete[] _curFrame.strips;
+	delete[] _clipTableBuf;
 }
 
 const Graphics::Surface *CinepakDecoder::decodeImage(Common::SeekableReadStream *stream) {
@@ -82,7 +94,7 @@ const Graphics::Surface *CinepakDecoder::decodeImage(Common::SeekableReadStream
 	if (_curFrame.strips == NULL)
 		_curFrame.strips = new CinepakStrip[_curFrame.stripCount];
 
-	debug (4, "Cinepak Frame: Width = %d, Height = %d, Strip Count = %d", _curFrame.width, _curFrame.height, _curFrame.stripCount);
+	debug(4, "Cinepak Frame: Width = %d, Height = %d, Strip Count = %d", _curFrame.width, _curFrame.height, _curFrame.stripCount);
 
 	// Borrowed from FFMPEG. This should cut out the extra data Cinepak for Sega has (which is useless).
 	// The theory behind this is that this is here to confuse standard Cinepak decoders. But, we won't let that happen! ;)
@@ -190,14 +202,14 @@ void CinepakDecoder::loadCodebook(Common::SeekableReadStream *stream, uint16 str
 				codebook[i].y[j] = stream->readByte();
 
 			if (n == 6) {
-				codebook[i].u  = stream->readByte() + 128;
-				codebook[i].v  = stream->readByte() + 128;
+				codebook[i].u = stream->readSByte();
+				codebook[i].v = stream->readSByte();
 			} else {
 				// This codebook type indicates either greyscale or
 				// palettized video. For greyscale, default us to
-				// 128 for both u and v.
-				codebook[i].u  = 128;
-				codebook[i].v  = 128;
+				// 0 for both u and v.
+				codebook[i].u = 0;
+				codebook[i].v = 0;
 			}
 		}
 	}
@@ -207,7 +219,6 @@ void CinepakDecoder::decodeVectors(Common::SeekableReadStream *stream, uint16 st
 	uint32 flag = 0, mask = 0;
 	uint32 iy[4];
 	int32 startPos = stream->pos();
-	byte r = 0, g = 0, b = 0;
 
 	for (uint16 y = _curFrame.strips[strip].rect.top; y < _curFrame.strips[strip].rect.bottom; y += 4) {
 		iy[0] = _curFrame.strips[strip].rect.left + y * _curFrame.width;
diff --git a/video/codecs/cinepak.h b/video/codecs/cinepak.h
index ca4552f..7abda6f 100644
--- a/video/codecs/cinepak.h
+++ b/video/codecs/cinepak.h
@@ -36,8 +36,9 @@ class SeekableReadStream;
 namespace Video {
 
 struct CinepakCodebook {
-	byte y[4];
-	byte u, v;
+	// These are not in the normal YUV colorspace, but in the Cinepak YUV colorspace instead.
+	byte y[4]; // [0, 255]
+	int8 u, v; // [-128, 127]
 };
 
 struct CinepakStrip {
@@ -70,6 +71,7 @@ private:
 	CinepakFrame _curFrame;
 	int32 _y;
 	Graphics::PixelFormat _pixelFormat;
+	byte *_clipTable, *_clipTableBuf;
 
 	void loadCodebook(Common::SeekableReadStream *stream, uint16 strip, byte codebookType, byte chunkID, uint32 chunkSize);
 	void decodeVectors(Common::SeekableReadStream *stream, uint16 strip, byte chunkID, uint32 chunkSize);






More information about the Scummvm-git-logs mailing list