Skip to content

Commit

Permalink
changed: For memory file cache there's no point creating a bigger cac…
Browse files Browse the repository at this point in the history
…he than filesize
  • Loading branch information
arnova authored and popcornmix committed Jul 19, 2015
1 parent 38c5f66 commit 1e7489d
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 50 deletions.
4 changes: 4 additions & 0 deletions xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamFile.cpp
Expand Up @@ -53,6 +53,10 @@ bool CDVDInputStreamFile::Open(const char* strFile, const std::string& content,
return false;

unsigned int flags = READ_TRUNCATED | READ_BITRATE | READ_CHUNKED;

// If this file is audio and/or video (= not a subtitle) flag to caller
if (!CFileItem(strFile).IsSubtitle())
flags |= READ_AUDIO_VIDEO;

/*
* There are 4 buffer modes available (configurable in as.xml)
Expand Down
7 changes: 6 additions & 1 deletion xbmc/filesystem/CircularCache.cpp
Expand Up @@ -184,9 +184,14 @@ int CCircularCache::ReadFromCache(char *buf, size_t len)
int64_t CCircularCache::WaitForData(unsigned int minimum, unsigned int millis)
{
CSingleLock lock(m_sync);

// Caller requests current cache size
if (millis == 0)
return m_end - m_beg;

int64_t avail = m_end - m_cur;

if(millis == 0 || IsEndOfInput())
if (IsEndOfInput())
return avail;

if(minimum > m_size - m_size_back)
Expand Down
2 changes: 1 addition & 1 deletion xbmc/filesystem/File.cpp
Expand Up @@ -244,7 +244,7 @@ bool CFile::Open(const CURL& file, const unsigned int flags)
if (m_flags & READ_CACHED)
{
// for internet stream, if it contains multiple stream, file cache need handle it specially.
m_pFile = new CFileCache((m_flags & READ_MULTI_STREAM) == READ_MULTI_STREAM);
m_pFile = new CFileCache(m_flags);
return m_pFile->Open(url);
}
}
Expand Down
15 changes: 9 additions & 6 deletions xbmc/filesystem/File.h
Expand Up @@ -53,23 +53,26 @@ class IFileCallback
};

/* indicate that caller can handle truncated reads, where function returns before entire buffer has been filled */
#define READ_TRUNCATED 0x01
#define READ_TRUNCATED 0x01

/* indicate that that caller support read in the minimum defined chunk size, this disables internal cache then */
#define READ_CHUNKED 0x02
#define READ_CHUNKED 0x02

/* use cache to access this file */
#define READ_CACHED 0x04
#define READ_CACHED 0x04

/* open without caching. regardless to file type. */
#define READ_NO_CACHE 0x08
#define READ_NO_CACHE 0x08

/* calcuate bitrate for file while reading */
#define READ_BITRATE 0x10
#define READ_BITRATE 0x10

/* indicate the caller will seek between multiple streams in the file frequently */
/* indicate to the caller we will seek between multiple streams in the file frequently */
#define READ_MULTI_STREAM 0x20

/* indicate to the caller file is audio and/or video (and e.g. may grow) */
#define READ_AUDIO_VIDEO 0x40

class CFileStreamBuffer;

class CFile
Expand Down
97 changes: 58 additions & 39 deletions xbmc/filesystem/FileCache.cpp
Expand Up @@ -97,40 +97,25 @@ class CWriteRate
};


CFileCache::CFileCache(bool useDoubleCache)
CFileCache::CFileCache(const unsigned int flags)
: CThread("FileCache")
, m_pCache(NULL)
, m_bDeleteCache(true)
, m_seekPossible(0)
, m_nSeekResult(0)
, m_seekPos(0)
, m_readPos(0)
, m_writePos(0)
, m_chunkSize(0)
, m_writeRate(0)
, m_writeRateActual(0)
, m_cacheFull(false)
, m_fileSize(0)
, m_flags(flags)
{
m_bDeleteCache = true;
m_nSeekResult = 0;
m_seekPos = 0;
m_readPos = 0;
m_writePos = 0;
if (g_advancedSettings.m_cacheMemBufferSize == 0)
m_pCache = new CSimpleFileCache();
else
{
size_t front = g_advancedSettings.m_cacheMemBufferSize;
size_t back = std::max<size_t>( g_advancedSettings.m_cacheMemBufferSize / 4, 1024 * 1024);
if (useDoubleCache)
{
front = front / 2;
back = back / 2;
}
m_pCache = new CCircularCache(front, back);
}
if (useDoubleCache)
{
m_pCache = new CDoubleCache(m_pCache);
}
}

CFileCache::CFileCache(CCacheStrategy *pCache, bool bDeleteCache)
CFileCache::CFileCache(CCacheStrategy *pCache, bool bDeleteCache /* = true */)
: CThread("FileCacheStrategy")
, m_seekPossible(0)
, m_chunkSize(0)
Expand All @@ -156,7 +141,7 @@ CFileCache::~CFileCache()
m_pCache = NULL;
}

void CFileCache::SetCacheStrategy(CCacheStrategy *pCache, bool bDeleteCache)
void CFileCache::SetCacheStrategy(CCacheStrategy *pCache, bool bDeleteCache /* = true */)
{
if (m_bDeleteCache && m_pCache)
delete m_pCache;
Expand All @@ -178,22 +163,8 @@ bool CFileCache::Open(const CURL& url)

CLog::Log(LOGDEBUG,"CFileCache::Open - opening <%s> using cache", url.GetFileName().c_str());

if (!m_pCache)
{
CLog::Log(LOGERROR,"CFileCache::Open - no cache strategy defined");
return false;
}

m_sourcePath = url.Get();

// open cache strategy
if (m_pCache->Open() != CACHE_RC_OK)
{
CLog::Log(LOGERROR,"CFileCache::Open - failed to open cache");
Close();
return false;
}

// opening the source file.
if (!m_source.Open(m_sourcePath, READ_NO_CACHE | READ_TRUNCATED | READ_CHUNKED))
{
Expand All @@ -209,6 +180,54 @@ bool CFileCache::Open(const CURL& url)
m_chunkSize = CFile::GetChunkSize(m_source.GetChunkSize(), READ_CACHE_CHUNK_SIZE);
m_fileSize = m_source.GetLength();

if (!m_pCache)
{
if (g_advancedSettings.m_cacheMemBufferSize == 0)
{
// Use cache on disk
m_pCache = new CSimpleFileCache();
}
else
{
size_t cacheSize;
if (m_fileSize > 0 && m_fileSize < g_advancedSettings.m_cacheMemBufferSize && !(m_flags & READ_AUDIO_VIDEO))
{
// NOTE: We don't need to take into account READ_MULTI_STREAM here as it's only used for audio/video
cacheSize = m_fileSize;
}
else
{
cacheSize = g_advancedSettings.m_cacheMemBufferSize;
}

size_t back = cacheSize / 4;
size_t front = cacheSize - back;

if (m_flags & READ_MULTI_STREAM)
{
// READ_MULTI_STREAM requires double buffering, so use half the amount of memory for each buffer
front /= 2;
back /= 2;
}

m_pCache = new CCircularCache(front, back);
}

if (m_flags & READ_MULTI_STREAM)
{
// If READ_MULTI_STREAM flag is set: Double buffering is required
m_pCache = new CDoubleCache(m_pCache);
}
}

// open cache strategy
if (!m_pCache || m_pCache->Open() != CACHE_RC_OK)
{
CLog::Log(LOGERROR,"CFileCache::Open - failed to open cache");
Close();
return false;
}

m_readPos = 0;
m_writePos = 0;
m_writeRate = 1024 * 1024;
Expand Down
7 changes: 4 additions & 3 deletions xbmc/filesystem/FileCache.h
Expand Up @@ -32,11 +32,11 @@ namespace XFILE
class CFileCache : public IFile, public CThread
{
public:
CFileCache(bool useDoubleCache=false);
CFileCache(CCacheStrategy *pCache, bool bDeleteCache=true);
CFileCache(const unsigned int flags);
CFileCache(CCacheStrategy *pCache, bool bDeleteCache = true);
virtual ~CFileCache();

void SetCacheStrategy(CCacheStrategy *pCache, bool bDeleteCache=true);
void SetCacheStrategy(CCacheStrategy *pCache, bool bDeleteCache = true);

// CThread methods
virtual void Process();
Expand Down Expand Up @@ -79,6 +79,7 @@ namespace XFILE
unsigned m_writeRateActual;
bool m_cacheFull;
std::atomic<int64_t> m_fileSize;
unsigned int m_flags;
CCriticalSection m_sync;
};

Expand Down

0 comments on commit 1e7489d

Please sign in to comment.