mirror of https://github.com/odrling/Aegisub
Added a decoded frame cache to PRSFile
Originally committed to SVN as r296.
This commit is contained in:
parent
820af47c64
commit
b973d58bee
|
@ -49,6 +49,9 @@
|
|||
///////////////
|
||||
// Constructor
|
||||
PRSFile::PRSFile () {
|
||||
// Cache data
|
||||
cacheMemSize = 0;
|
||||
maxCache = 8 << 20;
|
||||
}
|
||||
|
||||
|
||||
|
@ -56,6 +59,7 @@ PRSFile::PRSFile () {
|
|||
// Destructor
|
||||
PRSFile::~PRSFile() {
|
||||
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
|
||||
void PRSFile::Save(std::string path) {
|
||||
|
@ -251,23 +266,61 @@ void PRSFile::DrawFrame(int n,PRSVideoFrame *frame) {
|
|||
// Draw the blocks
|
||||
int nblocks = (int) blocks.size();
|
||||
for (int i=0;i<nblocks;i++) {
|
||||
// Get display and image pair
|
||||
// Get display block and frame
|
||||
PRSDisplay *display = blocks[i];
|
||||
PRSImage *image = GetImageByID(display->id);
|
||||
if (!image) continue;
|
||||
|
||||
// Decode PNG
|
||||
PRSVideoFrame *overFrame = image->GetDecodedFrame();
|
||||
PRSVideoFrame *overFrame = CachedGetFrameByID(display->id);
|
||||
|
||||
// Draw image on frame
|
||||
if (overFrame) overFrame->Overlay(frame,display->x,display->y,display->alpha,display->blend);
|
||||
|
||||
// Clean up
|
||||
delete overFrame;
|
||||
// DON'T delete the frame!
|
||||
// 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
|
||||
void PRSFile::GetDisplayBlocksAtFrame(int n,std::vector<PRSDisplay*> &blocks) {
|
||||
|
|
|
@ -56,6 +56,9 @@ class PRSDisplay;
|
|||
class PRSFile {
|
||||
private:
|
||||
std::list<PRSEntry*> entryList;
|
||||
std::list<PRSCachedFrame> frameCache;
|
||||
int cacheMemSize;
|
||||
int maxCache;
|
||||
void Reset();
|
||||
|
||||
public:
|
||||
|
@ -74,6 +77,8 @@ public:
|
|||
bool HasDataAtFrame(int n);
|
||||
void DrawFrame(int n,PRSVideoFrame *frame);
|
||||
PRSImage *GetImageByID(int id);
|
||||
PRSVideoFrame *CachedGetFrameByID(int id);
|
||||
void ClearCache();
|
||||
|
||||
PRSImage *FindDuplicateImage(PRSImage *img);
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -64,4 +64,17 @@ public:
|
|||
~PRSVideoFrame();
|
||||
|
||||
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;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue