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];
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
_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;
_file = 0;
_width = 0;
@ -68,7 +69,7 @@ SmushDecoder::SmushDecoder() {
_y = 0;
_blocky8 = new Blocky8();
_blocky16 = new Blocky16();
init();
_stream = NULL;
}
SmushDecoder::~SmushDecoder() {
@ -78,7 +79,6 @@ SmushDecoder::~SmushDecoder() {
void SmushDecoder::init() {
_IACTpos = 0;
_stream = NULL;
_curFrame = 0;
_videoPause = false;

View File

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

View File

@ -47,7 +47,7 @@ MoviePlayer::MoviePlayer() {
_x = 0;
_y = 0;
_videoDecoder = NULL;
_surface = new Graphics::Surface();
_internalSurface = NULL;
_externalSurface = new Graphics::Surface();
}
@ -89,15 +89,8 @@ bool MoviePlayer::prepareFrame() {
if (_videoDecoder->getTimeToNextFrame() > 0)
return false;
_surface->copyFrom(*_videoDecoder->decodeNextFrame());
// 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;
}
_internalSurface = _videoDecoder->decodeNextFrame();
_updateNeeded = true;
_movieTime = _videoDecoder->getElapsedTime();
_frame = _videoDecoder->getCurFrame();
@ -106,6 +99,12 @@ bool MoviePlayer::prepareFrame() {
}
Graphics::Surface *MoviePlayer::getDstSurface() {
_frameMutex.lock();
if (_updateNeeded && _internalSurface) {
_externalSurface->copyFrom(*_internalSurface);
}
_frameMutex.unlock();
return _externalSurface;
}
@ -114,15 +113,13 @@ void MoviePlayer::init() {
_movieTime = 0;
_updateNeeded = false;
_videoFinished = false;
g_system->getTimerManager()->installTimerProc(&timerCallback, _speed, NULL);
}
void MoviePlayer::deinit() {
_frameMutex.unlock();
g_system->getTimerManager()->removeTimerProc(&timerCallback);
_videoDecoder->close();
_surface->free();
_internalSurface = NULL;
_externalSurface->free();
_videoPause = false;
@ -144,6 +141,9 @@ bool MoviePlayer::play(Common::String filename, bool looping, int x, int y) {
init();
g_system->getTimerManager()->installTimerProc(&timerCallback, _speed, NULL);
_internalSurface = NULL;
return true;
}

View File

@ -37,7 +37,8 @@ protected:
Common::String _fname;
Common::Mutex _frameMutex;
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;
bool _updateNeeded;
int32 _speed;
@ -87,7 +88,7 @@ public:
*/
virtual void saveState(SaveGame *state);
virtual void restoreState(SaveGame *state);
protected:
static void timerCallback(void *ptr);
/**

View File

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