GRIM/Movie: Copy the surface when requested only.

This commit is contained in:
Giulio Camuffo 2011-10-07 22:36:10 +02:00
parent 150dadadd8
commit 8f451e1f11
5 changed files with 27 additions and 24 deletions

View File

@ -53,9 +53,10 @@ void decompressVima(const byte *src, int16 *dest, int destLen, uint16 *destTable
static uint16 smushDestTable[5786]; static uint16 smushDestTable[5786];
SmushDecoder::SmushDecoder() { SmushDecoder::SmushDecoder() {
// Set colour-format statically here for SMUSH (5650), to allow for differing PixelFormat in engine and renderer (and conversion from Surface there) // Set colour-format statically here for SMUSH (5650), to allow for differing
// PixelFormat in engine and renderer (and conversion from Surface there)
// Which means 16 bpp, 565, shift of 11, 5, 0, 0 for RGBA // Which means 16 bpp, 565, shift of 11, 5, 0, 0 for RGBA
_format = Graphics::PixelFormat(16, 5, 6, 5, 0, 11, 5, 0, 0); _format = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0);
_nbframes = 0; _nbframes = 0;
_file = 0; _file = 0;
_width = 0; _width = 0;
@ -68,7 +69,7 @@ SmushDecoder::SmushDecoder() {
_y = 0; _y = 0;
_blocky8 = new Blocky8(); _blocky8 = new Blocky8();
_blocky16 = new Blocky16(); _blocky16 = new Blocky16();
init(); _stream = NULL;
} }
SmushDecoder::~SmushDecoder() { SmushDecoder::~SmushDecoder() {
@ -78,7 +79,6 @@ SmushDecoder::~SmushDecoder() {
void SmushDecoder::init() { void SmushDecoder::init() {
_IACTpos = 0; _IACTpos = 0;
_stream = NULL;
_curFrame = 0; _curFrame = 0;
_videoPause = false; _videoPause = false;

View File

@ -68,6 +68,7 @@ private:
bool _videoPause; bool _videoPause;
bool _videoLooping; bool _videoLooping;
bool _demo; bool _demo;
public: public:
SmushDecoder(); SmushDecoder();
~SmushDecoder(); ~SmushDecoder();

View File

@ -47,7 +47,7 @@ MoviePlayer::MoviePlayer() {
_x = 0; _x = 0;
_y = 0; _y = 0;
_videoDecoder = NULL; _videoDecoder = NULL;
_surface = new Graphics::Surface(); _internalSurface = NULL;
_externalSurface = new Graphics::Surface(); _externalSurface = new Graphics::Surface();
} }
@ -89,15 +89,8 @@ bool MoviePlayer::prepareFrame() {
if (_videoDecoder->getTimeToNextFrame() > 0) if (_videoDecoder->getTimeToNextFrame() > 0)
return false; return false;
_surface->copyFrom(*_videoDecoder->decodeNextFrame()); _internalSurface = _videoDecoder->decodeNextFrame();
_updateNeeded = true;
// Avoid updating the _externalBuffer if it's flagged as updateNeeded
// since the draw-loop might access it then. This way, any late frames
// will be dropped, and the sound will continue, in synch.
if (!_updateNeeded) {
_externalSurface->copyFrom(*_surface);
_updateNeeded = true;
}
_movieTime = _videoDecoder->getElapsedTime(); _movieTime = _videoDecoder->getElapsedTime();
_frame = _videoDecoder->getCurFrame(); _frame = _videoDecoder->getCurFrame();
@ -106,6 +99,12 @@ bool MoviePlayer::prepareFrame() {
} }
Graphics::Surface *MoviePlayer::getDstSurface() { Graphics::Surface *MoviePlayer::getDstSurface() {
_frameMutex.lock();
if (_updateNeeded && _internalSurface) {
_externalSurface->copyFrom(*_internalSurface);
}
_frameMutex.unlock();
return _externalSurface; return _externalSurface;
} }
@ -114,15 +113,13 @@ void MoviePlayer::init() {
_movieTime = 0; _movieTime = 0;
_updateNeeded = false; _updateNeeded = false;
_videoFinished = false; _videoFinished = false;
g_system->getTimerManager()->installTimerProc(&timerCallback, _speed, NULL);
} }
void MoviePlayer::deinit() { void MoviePlayer::deinit() {
_frameMutex.unlock(); _frameMutex.unlock();
g_system->getTimerManager()->removeTimerProc(&timerCallback); g_system->getTimerManager()->removeTimerProc(&timerCallback);
_videoDecoder->close(); _videoDecoder->close();
_surface->free(); _internalSurface = NULL;
_externalSurface->free(); _externalSurface->free();
_videoPause = false; _videoPause = false;
@ -144,6 +141,9 @@ bool MoviePlayer::play(Common::String filename, bool looping, int x, int y) {
init(); init();
g_system->getTimerManager()->installTimerProc(&timerCallback, _speed, NULL);
_internalSurface = NULL;
return true; return true;
} }

View File

@ -37,7 +37,8 @@ protected:
Common::String _fname; Common::String _fname;
Common::Mutex _frameMutex; Common::Mutex _frameMutex;
Video::VideoDecoder *_videoDecoder; //< Initialize this to your needed subclass of VideoDecoder in the constructor Video::VideoDecoder *_videoDecoder; //< Initialize this to your needed subclass of VideoDecoder in the constructor
Graphics::Surface *_surface, *_externalSurface; const Graphics::Surface *_internalSurface;
Graphics::Surface *_externalSurface;
int32 _frame; int32 _frame;
bool _updateNeeded; bool _updateNeeded;
int32 _speed; int32 _speed;
@ -87,7 +88,7 @@ public:
*/ */
virtual void saveState(SaveGame *state); virtual void saveState(SaveGame *state);
virtual void restoreState(SaveGame *state); virtual void restoreState(SaveGame *state);
protected: protected:
static void timerCallback(void *ptr); static void timerCallback(void *ptr);
/** /**

View File

@ -48,16 +48,17 @@ bool SmushPlayer::loadFile(Common::String filename) {
return _videoDecoder->loadFile(filename); return _videoDecoder->loadFile(filename);
} }
SmushDecoder* SmushPlayer::getDecoder() { SmushDecoder *SmushPlayer::getDecoder() {
return dynamic_cast<SmushDecoder*>(_videoDecoder); return dynamic_cast<SmushDecoder *>(_videoDecoder);
} }
void SmushPlayer::init() { void SmushPlayer::init() {
SmushDecoder *decoder = getDecoder();
if (_demo) { if (_demo) {
_x = getDecoder()->getX(); _x = decoder->getX();
_y = getDecoder()->getY(); _y = decoder->getY();
} else { } else {
getDecoder()->setLooping(_videoLooping); decoder->setLooping(_videoLooping);
} }
MoviePlayer::init(); MoviePlayer::init();
} }