Added a decoded frame cache to PRSFile

Originally committed to SVN as r296.
This commit is contained in:
Rodrigo Braz Monteiro 2006-04-03 15:02:53 +00:00
parent 820af47c64
commit b973d58bee
4 changed files with 102 additions and 8 deletions

View file

@ -49,6 +49,9 @@
/////////////// ///////////////
// Constructor // Constructor
PRSFile::PRSFile () { PRSFile::PRSFile () {
// Cache data
cacheMemSize = 0;
maxCache = 8 << 20;
} }
@ -56,6 +59,7 @@ PRSFile::PRSFile () {
// Destructor // Destructor
PRSFile::~PRSFile() { PRSFile::~PRSFile() {
Reset(); Reset();
ClearCache();
} }
@ -71,6 +75,17 @@ void PRSFile::Reset() {
} }
///////////////////
// Clear the cache
void PRSFile::ClearCache() {
// Clear list of cached frames
frameCache.clear();
// Zero size
cacheMemSize = 0;
}
//////// ////////
// Save // Save
void PRSFile::Save(std::string path) { void PRSFile::Save(std::string path) {
@ -251,23 +266,61 @@ void PRSFile::DrawFrame(int n,PRSVideoFrame *frame) {
// Draw the blocks // Draw the blocks
int nblocks = (int) blocks.size(); int nblocks = (int) blocks.size();
for (int i=0;i<nblocks;i++) { for (int i=0;i<nblocks;i++) {
// Get display and image pair // Get display block and frame
PRSDisplay *display = blocks[i]; PRSDisplay *display = blocks[i];
PRSImage *image = GetImageByID(display->id); PRSVideoFrame *overFrame = CachedGetFrameByID(display->id);
if (!image) continue;
// Decode PNG
PRSVideoFrame *overFrame = image->GetDecodedFrame();
// Draw image on frame // Draw image on frame
if (overFrame) overFrame->Overlay(frame,display->x,display->y,display->alpha,display->blend); if (overFrame) overFrame->Overlay(frame,display->x,display->y,display->alpha,display->blend);
// Clean up // DON'T delete the frame!
delete overFrame; // The cache takes care of doing so.
} }
} }
///////////////////////////////////////////////////////////////////
// Gets a frame from cache, or load it there if it's not available
PRSVideoFrame* PRSFile::CachedGetFrameByID(int id) {
// Check if the image is already decoded on cache, fetch it if it is
PRSVideoFrame *frame = NULL;
std::list<PRSCachedFrame>::iterator cur;
for (cur=frameCache.begin();cur!=frameCache.end();cur++) {
if ((*cur).id == id) {
return (*cur).frame;
}
}
// It isn't; decode and add it to cache
// Get image
PRSImage *image = GetImageByID(id);
if (!image) return NULL;
// Get frame
frame = image->GetDecodedFrame();
// Add to cache
if (frame) {
// Add and raise size
PRSCachedFrame cached;
cached.frame = frame;
cached.id = id;
frameCache.push_front(cached);
cached.frame = NULL;
cacheMemSize += frame->GetSize();
// If memory has been exceeded, remove stuff from the back until it isn't anymore
while (cacheMemSize > maxCache && frameCache.size() > 1) {
cacheMemSize -= frameCache.back().frame->GetSize();
frameCache.pop_back();
}
}
// Return it
return frame;
}
//////////////////////////////////////////////// ////////////////////////////////////////////////
// Finds which display blocks are at a position // Finds which display blocks are at a position
void PRSFile::GetDisplayBlocksAtFrame(int n,std::vector<PRSDisplay*> &blocks) { void PRSFile::GetDisplayBlocksAtFrame(int n,std::vector<PRSDisplay*> &blocks) {

View file

@ -56,6 +56,9 @@ class PRSDisplay;
class PRSFile { class PRSFile {
private: private:
std::list<PRSEntry*> entryList; std::list<PRSEntry*> entryList;
std::list<PRSCachedFrame> frameCache;
int cacheMemSize;
int maxCache;
void Reset(); void Reset();
public: public:
@ -74,6 +77,8 @@ public:
bool HasDataAtFrame(int n); bool HasDataAtFrame(int n);
void DrawFrame(int n,PRSVideoFrame *frame); void DrawFrame(int n,PRSVideoFrame *frame);
PRSImage *GetImageByID(int id); PRSImage *GetImageByID(int id);
PRSVideoFrame *CachedGetFrameByID(int id);
void ClearCache();
PRSImage *FindDuplicateImage(PRSImage *img); PRSImage *FindDuplicateImage(PRSImage *img);
}; };

View file

@ -141,3 +141,26 @@ void PRSVideoFrame::Overlay(PRSVideoFrame *dstFrame,int x,int y,unsigned char al
} }
} }
} }
//////////////////
// Get frame size
int PRSVideoFrame::GetSize() {
return sizeof(PRSVideoFrame) + pitch * h;
}
//////////////////////
// Cached constructor
PRSCachedFrame::PRSCachedFrame () {
frame = 0;
id = -1;
}
/////////////////////
// Cached destructor
PRSCachedFrame::~PRSCachedFrame() {
delete frame;
frame = 0;
}

View file

@ -64,4 +64,17 @@ public:
~PRSVideoFrame(); ~PRSVideoFrame();
void Overlay(PRSVideoFrame *dst,int x,int y,unsigned char alpha=255,unsigned char blend=0); void Overlay(PRSVideoFrame *dst,int x,int y,unsigned char alpha=255,unsigned char blend=0);
int GetSize();
};
///////////////////////////
// Video frame cache class
class PRSCachedFrame {
public:
PRSCachedFrame();
~PRSCachedFrame();
PRSVideoFrame *frame;
int id;
}; };