aboutsummaryrefslogtreecommitdiff
path: root/graphics/video
diff options
context:
space:
mode:
authorFilippos Karapetis2009-01-11 03:34:50 +0000
committerFilippos Karapetis2009-01-11 03:34:50 +0000
commit0b4dd7c4593587355c1965eb0d266040c83f0382 (patch)
treec9f6b62c14ba25ccbdf5e8773d5c4e0dc367b7ea /graphics/video
parent08c71e39490590125645215ce65fdcb71f11fae6 (diff)
downloadscummvm-rg350-0b4dd7c4593587355c1965eb0d266040c83f0382.tar.gz
scummvm-rg350-0b4dd7c4593587355c1965eb0d266040c83f0382.tar.bz2
scummvm-rg350-0b4dd7c4593587355c1965eb0d266040c83f0382.zip
Committed a modified version of wjp's patch for the video player:
- Split the video player from the video decoders. It's now possible to have one video player for multiple decoders - Added the palette weight calculation from the BS1 engine into VideoPlayer::setPalette. It's now possible to find the values of the white and black colors via getWhite() and getBlack() (useful for subtitle overlays) - Adapted FTA2's movie playing code to the new changes to video player - Fixed a slight bug in the DXA decoder (_videoinfo.startTime was not initialized) svn-id: r35816
Diffstat (limited to 'graphics/video')
-rw-r--r--graphics/video/dxa_player.cpp4
-rw-r--r--graphics/video/dxa_player.h2
-rw-r--r--graphics/video/smk_player.cpp1
-rw-r--r--graphics/video/smk_player.h2
-rw-r--r--graphics/video/video_player.cpp92
-rw-r--r--graphics/video/video_player.h68
6 files changed, 103 insertions, 66 deletions
diff --git a/graphics/video/dxa_player.cpp b/graphics/video/dxa_player.cpp
index e228510e6b..397d1232da 100644
--- a/graphics/video/dxa_player.cpp
+++ b/graphics/video/dxa_player.cpp
@@ -25,6 +25,7 @@
#include "common/endian.h"
#include "common/archive.h"
+#include "common/system.h"
#include "common/util.h"
#include "graphics/video/dxa_player.h"
@@ -476,6 +477,9 @@ void DXAPlayer::decode13(int size) {
bool DXAPlayer::decodeNextFrame() {
uint32 tag;
+ if (_videoInfo.currentFrame == 0)
+ _videoInfo.startTime = g_system->getMillis();
+
tag = _fileStream->readUint32BE();
if (tag == MKID_BE('CMAP')) {
byte rgb[768];
diff --git a/graphics/video/dxa_player.h b/graphics/video/dxa_player.h
index fb5645c089..78825dc6f1 100644
--- a/graphics/video/dxa_player.h
+++ b/graphics/video/dxa_player.h
@@ -30,7 +30,7 @@
namespace Graphics {
-class DXAPlayer : public VideoPlayer {
+class DXAPlayer : public VideoDecoder {
public:
DXAPlayer();
virtual ~DXAPlayer();
diff --git a/graphics/video/smk_player.cpp b/graphics/video/smk_player.cpp
index 81c18e94b4..143fa04621 100644
--- a/graphics/video/smk_player.cpp
+++ b/graphics/video/smk_player.cpp
@@ -321,6 +321,7 @@ SMKPlayer::SMKPlayer(Audio::Mixer *mixer)
}
SMKPlayer::~SMKPlayer() {
+ closeFile();
}
int SMKPlayer::getHeight() {
diff --git a/graphics/video/smk_player.h b/graphics/video/smk_player.h
index 512eb57c20..6e7e0e88a9 100644
--- a/graphics/video/smk_player.h
+++ b/graphics/video/smk_player.h
@@ -44,7 +44,7 @@ class BigHuffmanTree;
/**
* Implementation of a Smacker v2/v4 video decoder
*/
-class SMKPlayer : public Graphics::VideoPlayer {
+class SMKPlayer : public Graphics::VideoDecoder {
public:
SMKPlayer(Audio::Mixer *mixer);
virtual ~SMKPlayer();
diff --git a/graphics/video/video_player.cpp b/graphics/video/video_player.cpp
index 6bf7a5e39d..1f8fe78447 100644
--- a/graphics/video/video_player.cpp
+++ b/graphics/video/video_player.cpp
@@ -35,50 +35,51 @@
namespace Graphics {
-VideoPlayer::VideoPlayer() : _fileStream(0), _skipVideo(false) {
+VideoDecoder::VideoDecoder() : _fileStream(0) {
+ _black = 0;
+ _white = 255;
}
-VideoPlayer::~VideoPlayer() {
- closeFile();
+VideoDecoder::~VideoDecoder() {
}
-int VideoPlayer::getWidth() {
+int VideoDecoder::getWidth() {
if (!_fileStream)
return 0;
return _videoInfo.width;
}
-int VideoPlayer::getHeight() {
+int VideoDecoder::getHeight() {
if (!_fileStream)
return 0;
return _videoInfo.height;
}
-int32 VideoPlayer::getCurFrame() {
+int32 VideoDecoder::getCurFrame() {
if (!_fileStream)
return -1;
return _videoInfo.currentFrame;
}
-int32 VideoPlayer::getFrameCount() {
+int32 VideoDecoder::getFrameCount() {
if (!_fileStream)
return 0;
return _videoInfo.frameCount;
}
-int32 VideoPlayer::getFrameRate() {
+int32 VideoDecoder::getFrameRate() {
if (!_fileStream)
return 0;
return _videoInfo.frameRate;
}
-int32 VideoPlayer::getFrameDelay() {
+int32 VideoDecoder::getFrameDelay() {
if (!_fileStream)
return 0;
return _videoInfo.frameDelay;
}
-int32 VideoPlayer::getAudioLag() {
+int32 VideoDecoder::getAudioLag() {
if (!_fileStream)
return 0;
@@ -92,7 +93,7 @@ int32 VideoPlayer::getAudioLag() {
return videoTime - audioTime;
}
-uint32 VideoPlayer::getFrameWaitTime() {
+uint32 VideoDecoder::getFrameWaitTime() {
int32 waitTime = (getFrameDelay() + getAudioLag()) / 100;
if (waitTime < 0)
@@ -101,14 +102,7 @@ uint32 VideoPlayer::getFrameWaitTime() {
return waitTime;
}
-bool VideoPlayer::loadFile(const char *fileName) {
- return false;
-}
-
-void VideoPlayer::closeFile() {
-}
-
-void VideoPlayer::copyFrameToBuffer(byte *dst, uint x, uint y, uint pitch) {
+void VideoDecoder::copyFrameToBuffer(byte *dst, uint x, uint y, uint pitch) {
uint h = getHeight();
uint w = getWidth();
@@ -122,25 +116,45 @@ void VideoPlayer::copyFrameToBuffer(byte *dst, uint x, uint y, uint pitch) {
} while (--h);
}
-void VideoPlayer::setPalette(byte *pal) {
+void VideoDecoder::setPalette(byte *pal) {
byte videoPalette[256 * 4];
+ uint32 maxWeight = 0;
+ uint32 minWeight = 0xFFFFFFFF;
+ uint32 weight = 0;
+ byte r, g, b;
+
for (int i = 0; i < 256; i++) {
videoPalette[i * 4 + 0] = *pal++;
videoPalette[i * 4 + 1] = *pal++;
videoPalette[i * 4 + 2] = *pal++;
videoPalette[i * 4 + 3] = 0;
+
+ // Try and find the white and black colors for the current palette
+ r = videoPalette[i * 4 + 0];
+ g = videoPalette[i * 4 + 1];
+ b = videoPalette[i * 4 + 2];
+
+ weight = 3 * r * r + 6 * g * g + 2 * b * b;
+
+ if (weight >= maxWeight) {
+ _white = i;
+ maxWeight = weight;
+ }
+
+ if (weight <= minWeight) {
+ _black = i;
+ minWeight = i;
+ }
}
g_system->setPalette(videoPalette, 0, 256);
}
-bool VideoPlayer::decodeNextFrame() {
- return false;
-}
-void VideoPlayer::performPostProcessing(byte *screen) {
-}
+/*
+ * VideoPlayer
+ */
void VideoPlayer::processVideoEvents(Common::List<Common::Event> *stopEvents) {
Common::Event curEvent;
@@ -168,35 +182,30 @@ void VideoPlayer::processVideoEvents(Common::List<Common::Event> *stopEvents) {
}
}
-bool VideoPlayer::playVideo(const char *filename, Common::List<Common::Event> *stopEvents) {
+bool VideoPlayer::playVideo(Common::List<Common::Event> *stopEvents) {
_skipVideo = false;
- debug(0, "Playing video %s", filename);
-
- if (!loadFile(filename)) {
- warning("Failed to load video file %s", filename);
- return false;
- }
+ debug(0, "Playing video");
g_system->clearScreen();
- while (getCurFrame() < getFrameCount() && !_skipVideo) {
+ while (_decoder->getCurFrame() < _decoder->getFrameCount() && !_skipVideo) {
processVideoEvents(stopEvents);
uint32 startTime = 0;
- decodeNextFrame();
+ _decoder->decodeNextFrame();
Graphics::Surface *screen = g_system->lockScreen();
- copyFrameToBuffer((byte *)screen->pixels,
- (g_system->getWidth() - getWidth()) / 2,
- (g_system->getHeight() - getHeight()) / 2,
+ _decoder->copyFrameToBuffer((byte *)screen->pixels,
+ (g_system->getWidth() - _decoder->getWidth()) / 2,
+ (g_system->getHeight() - _decoder->getHeight()) / 2,
g_system->getWidth());
performPostProcessing((byte *)screen->pixels);
g_system->unlockScreen();
- uint32 waitTime = getFrameWaitTime();
+ uint32 waitTime = _decoder->getFrameWaitTime();
if (!waitTime) {
- warning("dropped frame %i", getCurFrame());
+ warning("dropped frame %i", _decoder->getCurFrame());
continue;
}
@@ -212,9 +221,10 @@ bool VideoPlayer::playVideo(const char *filename, Common::List<Common::Event> *s
}
}
- closeFile();
+ return !_skipVideo;
+}
- return true;
+void VideoPlayer::performPostProcessing(byte *screen) {
}
} // End of namespace Graphics
diff --git a/graphics/video/video_player.h b/graphics/video/video_player.h
index 4a44349552..a32996df75 100644
--- a/graphics/video/video_player.h
+++ b/graphics/video/video_player.h
@@ -39,10 +39,10 @@ namespace Graphics {
/**
* Implementation of a generic video decoder
*/
-class VideoPlayer {
+class VideoDecoder {
public:
- VideoPlayer();
- virtual ~VideoPlayer();
+ VideoDecoder();
+ virtual ~VideoDecoder();
/**
* Returns the width of the video
@@ -98,12 +98,12 @@ public:
* Load a video file
* @param filename the filename to load
*/
- virtual bool loadFile(const char *filename);
+ virtual bool loadFile(const char *filename) = 0;
/**
* Close a video file
*/
- virtual void closeFile();
+ virtual void closeFile()=0;
/**
* Returns if a video file is loaded or not
@@ -117,6 +117,16 @@ public:
virtual void setPalette(byte *pal);
/**
+ * Return the black palette color for the current frame
+ */
+ byte getBlack() { return _black; }
+
+ /**
+ * Return the white palette color for the current frame
+ */
+ byte getWhite() { return _white; }
+
+ /**
* Copy current frame into the specified position of the destination
* buffer.
* @param dst the buffer
@@ -127,24 +137,9 @@ public:
void copyFrameToBuffer(byte *dst, uint x, uint y, uint pitch);
/**
- * Decode the next frame
- */
- virtual bool decodeNextFrame();
-
- /**
- * A default implementation of a video player
- * Plays a non-interactive full screen video till it's stopped by a
- * specific event
- * @param filename the name of the file to play
- * @param stopEvents a list of events that can stop the video
+ * Decode the next frame to _videoFrameBuffer
*/
- bool playVideo(const char *filename, Common::List<Common::Event> *stopEvents);
-
- /**
- * Perform postprocessing once the frame data is copied to the screen,
- * right before the frame is drawn. Called from playVideo()
- */
- virtual void performPostProcessing(byte *screen);
+ virtual bool decodeNextFrame() = 0;
protected:
struct {
@@ -157,11 +152,38 @@ protected:
uint32 startTime;
} _videoInfo;
+ byte _black, _white;
+
Common::SeekableReadStream *_fileStream;
byte *_videoFrameBuffer;
+};
+
+class VideoPlayer {
+public:
+ VideoPlayer(VideoDecoder* decoder) : _skipVideo(false), _decoder(decoder)
+ { }
+ ~VideoPlayer() { }
+ /**
+ * A default implementation of a video player
+ * Plays a non-interactive full screen video till it's stopped by a
+ * specific event
+ * @param filename the name of the file to play
+ * @param stopEvents a list of events that can stop the video
+ *
+ * Returns true if the video was played to the end, false if skipped
+ */
+ bool playVideo(Common::List<Common::Event> *stopEvents);
+
+protected:
+ /**
+ * Perform postprocessing once the frame data is copied to the screen,
+ * right before the frame is drawn. Called by playVideo()
+ */
+ virtual void performPostProcessing(byte *screen);
+
bool _skipVideo;
+ VideoDecoder* _decoder;
-private:
void processVideoEvents(Common::List<Common::Event> *stopEvents);
};